예제 #1
1
        static void ExtractAttachments(TnefReader reader, BodyBuilder builder)
        {
            var      filter = new BestEncodingFilter();
            var      prop = reader.TnefPropertyReader;
            MimePart attachment = null;
            int      outIndex, outLength;

            byte[] attachData;
            string text;

            do
            {
                if (reader.AttributeLevel != TnefAttributeLevel.Attachment)
                {
                    break;
                }

                switch (reader.AttributeTag)
                {
                case TnefAttributeTag.AttachRenderData:
                    if (attachment != null)
                    {
                        builder.Attachments.Add(attachment);
                    }

                    attachment = new MimePart();
                    break;

                case TnefAttributeTag.Attachment:
                    if (attachment == null)
                    {
                        break;
                    }

                    while (prop.ReadNextProperty())
                    {
                        switch (prop.PropertyTag.Id)
                        {
                        case TnefPropertyId.AttachLongFilename:
                            attachment.FileName = prop.ReadValueAsString();
                            break;

                        case TnefPropertyId.AttachFilename:
                            if (attachment.FileName == null)
                            {
                                attachment.FileName = prop.ReadValueAsString();
                            }
                            break;

                        case TnefPropertyId.AttachContentLocation:
                            text = prop.ReadValueAsString();
                            if (Uri.IsWellFormedUriString(text, UriKind.Absolute))
                            {
                                attachment.ContentLocation = new Uri(text, UriKind.Absolute);
                            }
                            else if (Uri.IsWellFormedUriString(text, UriKind.Relative))
                            {
                                attachment.ContentLocation = new Uri(text, UriKind.Relative);
                            }
                            break;

                        case TnefPropertyId.AttachContentBase:
                            text = prop.ReadValueAsString();
                            attachment.ContentBase = new Uri(text, UriKind.Absolute);
                            break;

                        case TnefPropertyId.AttachContentId:
                            attachment.ContentId = prop.ReadValueAsString();
                            break;

                        case TnefPropertyId.AttachDisposition:
                            text = prop.ReadValueAsString();
                            if (attachment.ContentDisposition == null)
                            {
                                attachment.ContentDisposition = new ContentDisposition(text);
                            }
                            else
                            {
                                attachment.ContentDisposition.Disposition = text;
                            }
                            break;

                        case TnefPropertyId.AttachData:
                            // TODO: implement this...
                            break;
                        }
                    }
                    break;

                case TnefAttributeTag.AttachData:
                    if (attachment == null)
                    {
                        break;
                    }

                    attachData = prop.ReadValueAsBytes();
                    filter.Flush(attachData, 0, attachData.Length, out outIndex, out outLength);
                    attachment.ContentTransferEncoding = filter.GetBestEncoding(EncodingConstraint.EightBit);
                    attachment.ContentObject           = new ContentObject(new MemoryStream(attachData, false), ContentEncoding.Default);
                    filter.Reset();
                    break;
                }

                if (attachment != null)
                {
                    builder.Attachments.Add(attachment);
                }
            } while (reader.ReadNextAttribute());
        }
예제 #2
1
        static void ExtractAttachments(TnefReader reader, BodyBuilder builder)
        {
            var             attachMethod = TnefAttachMethod.ByValue;
            var             filter = new BestEncodingFilter();
            var             prop = reader.TnefPropertyReader;
            MimePart        attachment = null;
            int             outIndex, outLength;
            TnefAttachFlags flags;

            string[] mimeType;
            byte[]   attachData;
            string   text;

            do
            {
                if (reader.AttributeLevel != TnefAttributeLevel.Attachment)
                {
                    break;
                }

                switch (reader.AttributeTag)
                {
                case TnefAttributeTag.AttachRenderData:
                    attachMethod = TnefAttachMethod.ByValue;
                    attachment   = new MimePart();
                    break;

                case TnefAttributeTag.Attachment:
                    if (attachment == null)
                    {
                        break;
                    }

                    attachData = null;

                    while (prop.ReadNextProperty())
                    {
                        switch (prop.PropertyTag.Id)
                        {
                        case TnefPropertyId.AttachLongFilename:
                            attachment.FileName = prop.ReadValueAsString();
                            break;

                        case TnefPropertyId.AttachFilename:
                            if (attachment.FileName == null)
                            {
                                attachment.FileName = prop.ReadValueAsString();
                            }
                            break;

                        case TnefPropertyId.AttachContentLocation:
                            attachment.ContentLocation = prop.ReadValueAsUri();
                            break;

                        case TnefPropertyId.AttachContentBase:
                            attachment.ContentBase = prop.ReadValueAsUri();
                            break;

                        case TnefPropertyId.AttachContentId:
                            text = prop.ReadValueAsString();

                            var buffer = CharsetUtils.UTF8.GetBytes(text);
                            int index  = 0;

                            if (ParseUtils.TryParseMsgId(buffer, ref index, buffer.Length, false, false, out string msgid))
                            {
                                attachment.ContentId = msgid;
                            }
                            break;

                        case TnefPropertyId.AttachDisposition:
                            text = prop.ReadValueAsString();
                            if (ContentDisposition.TryParse(text, out ContentDisposition disposition))
                            {
                                attachment.ContentDisposition = disposition;
                            }
                            break;

                        case TnefPropertyId.AttachData:
                            attachData = prop.ReadValueAsBytes();
                            break;

                        case TnefPropertyId.AttachMethod:
                            attachMethod = (TnefAttachMethod)prop.ReadValueAsInt32();
                            break;

                        case TnefPropertyId.AttachMimeTag:
                            mimeType = prop.ReadValueAsString().Split('/');
                            if (mimeType.Length == 2)
                            {
                                attachment.ContentType.MediaType    = mimeType[0].Trim();
                                attachment.ContentType.MediaSubtype = mimeType[1].Trim();
                            }
                            break;

                        case TnefPropertyId.AttachFlags:
                            flags = (TnefAttachFlags)prop.ReadValueAsInt32();
                            if ((flags & TnefAttachFlags.RenderedInBody) != 0)
                            {
                                if (attachment.ContentDisposition == null)
                                {
                                    attachment.ContentDisposition = new ContentDisposition(ContentDisposition.Inline);
                                }
                                else
                                {
                                    attachment.ContentDisposition.Disposition = ContentDisposition.Inline;
                                }
                            }
                            break;

                        case TnefPropertyId.AttachSize:
                            if (attachment.ContentDisposition == null)
                            {
                                attachment.ContentDisposition = new ContentDisposition();
                            }

                            attachment.ContentDisposition.Size = prop.ReadValueAsInt64();
                            break;

                        case TnefPropertyId.DisplayName:
                            attachment.ContentType.Name = prop.ReadValueAsString();
                            break;
                        }
                    }

                    if (attachData != null)
                    {
                        int count = attachData.Length;
                        int index = 0;

                        if (attachMethod == TnefAttachMethod.EmbeddedMessage)
                        {
                            attachment.ContentTransferEncoding = ContentEncoding.Base64;
                            attachment = PromoteToTnefPart(attachment);
                            count     -= 16;
                            index      = 16;
                        }
                        else
                        {
                            filter.Flush(attachData, index, count, out outIndex, out outLength);
                            attachment.ContentTransferEncoding = filter.GetBestEncoding(EncodingConstraint.SevenBit);
                            filter.Reset();
                        }

                        attachment.Content = new MimeContent(new MemoryStream(attachData, index, count, false));
                        builder.Attachments.Add(attachment);
                    }
                    break;

                case TnefAttributeTag.AttachCreateDate:
                    if (attachment != null)
                    {
                        if (attachment.ContentDisposition == null)
                        {
                            attachment.ContentDisposition = new ContentDisposition();
                        }

                        attachment.ContentDisposition.CreationDate = prop.ReadValueAsDateTime();
                    }
                    break;

                case TnefAttributeTag.AttachModifyDate:
                    if (attachment != null)
                    {
                        if (attachment.ContentDisposition == null)
                        {
                            attachment.ContentDisposition = new ContentDisposition();
                        }

                        attachment.ContentDisposition.ModificationDate = prop.ReadValueAsDateTime();
                    }
                    break;

                case TnefAttributeTag.AttachTitle:
                    if (attachment != null && string.IsNullOrEmpty(attachment.FileName))
                    {
                        attachment.FileName = prop.ReadValueAsString();
                    }
                    break;

                case TnefAttributeTag.AttachMetaFile:
                    if (attachment == null)
                    {
                        break;
                    }

                    // TODO: what to do with the meta data?
                    break;

                case TnefAttributeTag.AttachData:
                    if (attachment == null || attachMethod != TnefAttachMethod.ByValue)
                    {
                        break;
                    }

                    attachData = prop.ReadValueAsBytes();
                    filter.Flush(attachData, 0, attachData.Length, out outIndex, out outLength);
                    attachment.ContentTransferEncoding = filter.GetBestEncoding(EncodingConstraint.SevenBit);
                    attachment.Content = new MimeContent(new MemoryStream(attachData, false));
                    filter.Reset();

                    builder.Attachments.Add(attachment);
                    break;
                }
            } while (reader.ReadNextAttribute());
        }
        public async Task<Message> OpenTnef(StorageFile datFile)
        {
            var message = new MimeMessage();
            var bodyFile = default(StorageFile);
            var targetFilesCollection = new List<FileInfo>();
            using (var stream = await datFile.OpenStreamForReadAsync())
            {
                using (var tnefReader = new TnefReader(stream))
                {
                    message = ExtractTnefMessage(tnefReader);
                    if (message.Sender == null)
                    {
                        message.Sender = new MailboxAddress(string.Empty, "Sender unknown");
                    }

                    foreach (MimePart mimePart in message.Attachments)
                    {
                        var isoFile = await LastExtractedFilesProvider.WriteFileToIsoStorage(mimePart.FileName, mimePart.ContentObject.Open());
                        var basicProperties = await isoFile.GetBasicPropertiesAsync();
                        var thumb = this.GetVectorThumbnailByType(isoFile.FileType);
                        var size = FileSizeString((double)basicProperties.Size);
                        targetFilesCollection.Add(new FileInfo(isoFile, thumb, size, datFile.DisplayName));
                    }

                    var body = Enumerable.FirstOrDefault<TextPart>(Enumerable.OfType<TextPart>(message.BodyParts));
                    if (body != null && !String.IsNullOrEmpty(body.Text))
                    {
                        string bodyFileName = "Message_Body.";
                        if (body.IsHtml)
                        {
                            bodyFileName += "html";
                        }
                        else if (body.IsPlain)
                        {
                            bodyFileName += "txt";
                        }
                        else if (body.IsRichText)
                        {
                            bodyFileName += "rtf";
                        }

                        bodyFile = await LastExtractedFilesProvider.WriteFileToIsoStorage(bodyFileName, body.Text);
                    }
                }
            }

            var targetMessage = new Message(message.Subject, message.Sender.ToString(), string.Empty, message.Date.ToString(), bodyFile, targetFilesCollection);

            return targetMessage;
        }
예제 #4
0
        internal TnefPropertyReader(TnefReader tnef)
        {
            propertyTag = TnefPropertyTag.Null;
            propertyName = new TnefNameId ();
            rawValueOffset = 0;
            rawValueLength = 0;
            propertyIndex = 0;
            propertyCount = 0;
            valueIndex = 0;
            valueCount = 0;
            rowIndex = 0;
            rowCount = 0;

            reader = tnef;
        }
예제 #5
0
        static MimeMessage ExtractTnefMessage(TnefReader reader)
        {
            var builder = new BodyBuilder();
            var message = new MimeMessage();

            while (reader.ReadNextAttribute())
            {
                if (reader.AttributeLevel == TnefAttributeLevel.Attachment)
                {
                    break;
                }

                var prop = reader.TnefPropertyReader;

                switch (reader.AttributeTag)
                {
                case TnefAttributeTag.RecipientTable:
                    ExtractRecipientTable(reader, message);
                    break;

                case TnefAttributeTag.MapiProperties:
                    ExtractMapiProperties(reader, message, builder);
                    break;

                case TnefAttributeTag.DateSent:
                    message.Date = prop.ReadValueAsDateTime();
                    break;

                case TnefAttributeTag.Body:
                    builder.TextBody = prop.ReadValueAsString();
                    break;
                }
            }

            if (reader.AttributeLevel == TnefAttributeLevel.Attachment)
            {
                ExtractAttachments(reader, builder);
            }

            message.Body = builder.ToMessageBody();

            return(message);
        }
예제 #6
0
		static void ExtractRecipientTable (TnefReader reader, MimeMessage message)
		{
			var prop = reader.TnefPropertyReader;

			// Note: The RecipientTable uses rows of properties...
			while (prop.ReadNextRow ()) {
				InternetAddressList list = null;
				string name = null, addr = null;

				while (prop.ReadNextProperty ()) {
					switch (prop.PropertyTag.Id) {
					case TnefPropertyId.RecipientType:
						int recipientType = prop.ReadValueAsInt32 ();
						switch (recipientType) {
						case 1: list = message.To; break;
						case 2: list = message.Cc; break;
						case 3: list = message.Bcc; break;
						}
						break;
					case TnefPropertyId.TransmitableDisplayName:
						if (string.IsNullOrEmpty (name))
							name = prop.ReadValueAsString ();
						break;
					case TnefPropertyId.DisplayName:
						name = prop.ReadValueAsString ();
						break;
					case TnefPropertyId.EmailAddress:
						if (string.IsNullOrEmpty (addr))
							addr = prop.ReadValueAsString ();
						break;
					case TnefPropertyId.SmtpAddress:
						// The SmtpAddress, if it exists, should take precedence over the EmailAddress
						// (since the SmtpAddress is meant to be used in the RCPT TO command).
						addr = prop.ReadValueAsString ();
						break;
					}
				}

				if (list != null && !string.IsNullOrEmpty (addr))
					list.Add (new MailboxAddress (name, addr));
			}
		}
예제 #7
0
        /// <summary>
        /// Converts the TNEF content into a <see cref="MimeKit.MimeMessage"/>.
        /// </summary>
        /// <remarks>
        /// TNEF data often contains properties that map to <see cref="MimeKit.MimeMessage"/>
        /// headers. TNEF data also often contains file attachments which will be
        /// mapped to MIME parts.
        /// </remarks>
        /// <returns>A message representing the TNEF data in MIME format.</returns>
        /// <exception cref="System.InvalidOperationException">
        /// The <see cref="MimeKit.MimePart.Content"/> property is <c>null</c>.
        /// </exception>
        public MimeMessage ConvertToMessage()
        {
            if (Content == null)
            {
                throw new InvalidOperationException("Cannot parse null TNEF data.");
            }

            int codepage = 0;

            if (!string.IsNullOrEmpty(ContentType.Charset))
            {
                if ((codepage = CharsetUtils.GetCodePage(ContentType.Charset)) == -1)
                {
                    codepage = 0;
                }
            }

            using (var reader = new TnefReader(Content.Open(), codepage, TnefComplianceMode.Loose)) {
                return(ExtractTnefMessage(reader));
            }
        }
예제 #8
0
 /// <summary>
 /// Initializes a new instance of the <see cref="MimeKit.Tnef.TnefReaderStream"/> class.
 /// </summary>
 /// <remarks>
 /// Creates a stream for reading a raw value from the <see cref="TnefReader"/>.
 /// </remarks>
 /// <param name="tnefReader">The <see cref="TnefReader"/>.</param>
 /// <param name="endOffset">The end offset.</param>
 public TnefReaderStream(TnefReader tnefReader, int endOffset)
 {
     valueEndOffset = endOffset;
     reader         = tnefReader;
 }
예제 #9
0
        static void ExtractMapiProperties(TnefReader reader, MimeMessage message, BodyBuilder builder)
        {
            var prop = reader.TnefPropertyReader;

            while (prop.ReadNextProperty())
            {
                switch (prop.PropertyTag.Id)
                {
                case TnefPropertyId.InternetMessageId:
                    if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode)
                    {
                        message.MessageId = prop.ReadValueAsString();
                    }
                    break;

                case TnefPropertyId.Subject:
                    if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode)
                    {
                        message.Subject = prop.ReadValueAsString();
                    }
                    break;

                case TnefPropertyId.RtfCompressed:
                    if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Binary)
                    {
                        var rtf = new TextPart("rtf");
                        rtf.ContentType.Name = "body.rtf";
                        rtf.Text             = prop.ReadValueAsString();

                        builder.Attachments.Add(rtf);
                    }
                    break;

                case TnefPropertyId.BodyHtml:
                    if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Binary)
                    {
                        var html = new TextPart("html");
                        html.ContentType.Name = "body.html";
                        html.Text             = prop.ReadValueAsString();

                        builder.Attachments.Add(html);
                    }
                    break;

                case TnefPropertyId.Body:
                    if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Binary)
                    {
                        var plain = new TextPart("plain");
                        plain.ContentType.Name = "body.txt";
                        plain.Text             = prop.ReadValueAsString();

                        builder.Attachments.Add(plain);
                    }
                    break;
                }
            }
        }
        private void ExtractAttachments(TnefReader reader, BodyBuilder builder)
        {
            var tnefAttachMethod = TnefAttachMethod.ByValue;
            var bestEncodingFilter = new BestEncodingFilter();
            var tnefPropertyReader = reader.TnefPropertyReader;
            MimePart mimePart = null;
            do
            {
                int outputIndex;
                int outputLength;
                switch (reader.AttributeTag)
                {
                    case TnefAttributeTag.AttachData:
                        if (mimePart != null && tnefAttachMethod == TnefAttachMethod.ByValue)
                        {
                            byte[] numArray = tnefPropertyReader.ReadValueAsBytes();
                            bestEncodingFilter.Flush(numArray, 0, numArray.Length, out outputIndex, out outputLength);
                            mimePart.ContentTransferEncoding = bestEncodingFilter.GetBestEncoding(EncodingConstraint.SevenBit, 78);
                            mimePart.ContentObject = new ContentObject(new MemoryStream(numArray, false), ContentEncoding.Default);
                            bestEncodingFilter.Reset();
                            builder.Attachments.Add(mimePart);
                            break;
                        }
                        break;
                    case TnefAttributeTag.AttachRenderData:
                        tnefAttachMethod = TnefAttachMethod.ByValue;
                        mimePart = new MimePart();
                        break;
                    case TnefAttributeTag.Attachment:
                        if (mimePart != null)
                        {
                            while (tnefPropertyReader.ReadNextProperty())
                            {
                                switch (tnefPropertyReader.PropertyTag.Id)
                                {
                                    case TnefPropertyId.AttachData:
                                        using (var rawValueReadStream = tnefPropertyReader.GetRawValueReadStream())
                                        {
                                            using (var memoryStream = new MemoryStream())
                                            {

                                                byte[] buffer = new byte[16];
                                                if (tnefAttachMethod == TnefAttachMethod.EmbeddedMessage)
                                                {
                                                    TnefPart tnefPart = new TnefPart();
                                                    foreach (Parameter parameter in mimePart.ContentType.Parameters)
                                                    {
                                                        tnefPart.ContentType.Parameters[parameter.Name] = parameter.Value;
                                                    }

                                                    if (mimePart.ContentDisposition != null)
                                                    {
                                                        tnefPart.ContentDisposition = mimePart.ContentDisposition;
                                                    }

                                                    mimePart = tnefPart;
                                                }
                                                rawValueReadStream.Read(buffer, 0, 16);
                                                rawValueReadStream.CopyTo(memoryStream, 4096);
                                                byte[] input = memoryStream.ToArray();
                                                bestEncodingFilter.Flush(input, 0, (int)memoryStream.Length, out outputIndex, out outputLength);
                                                mimePart.ContentTransferEncoding = bestEncodingFilter.GetBestEncoding(EncodingConstraint.SevenBit, 78);
                                                mimePart.ContentObject = new ContentObject(memoryStream, ContentEncoding.Default);
                                                bestEncodingFilter.Reset();
                                                builder.Attachments.Add(mimePart);
                                            }
                                        }

                                        continue;
                                    case TnefPropertyId.AttachFilename:
                                        if (String.IsNullOrEmpty(mimePart.FileName))
                                        {
                                            mimePart.FileName = tnefPropertyReader.ReadValueAsString();
                                            continue;
                                        }

                                        continue;
                                    case TnefPropertyId.AttachMethod:
                                        tnefAttachMethod = (TnefAttachMethod)tnefPropertyReader.ReadValueAsInt32();
                                        continue;
                                    case TnefPropertyId.AttachLongFilename:
                                        mimePart.FileName = tnefPropertyReader.ReadValueAsString();
                                        continue;
                                    case TnefPropertyId.AttachMimeTag:
                                        string[] strArray = tnefPropertyReader.ReadValueAsString().Split('/');
                                        if (strArray.Length == 2)
                                        {
                                            mimePart.ContentType.MediaType = strArray[0].Trim();
                                            mimePart.ContentType.MediaSubtype = strArray[1].Trim();
                                            continue;
                                        }

                                        continue;
                                    case TnefPropertyId.AttachContentBase:
                                        var uriString = tnefPropertyReader.ReadValueAsString();
                                        mimePart.ContentBase = new Uri(uriString, UriKind.Absolute);
                                        continue;
                                    case TnefPropertyId.AttachContentId:
                                        mimePart.ContentId = tnefPropertyReader.ReadValueAsString();
                                        continue;
                                    case TnefPropertyId.AttachContentLocation:
                                        var uriString2 = tnefPropertyReader.ReadValueAsString();
                                        if (Uri.IsWellFormedUriString(uriString2, UriKind.Absolute))
                                        {
                                            mimePart.ContentLocation = new Uri(uriString2, UriKind.Absolute);
                                            continue;
                                        }

                                        if (Uri.IsWellFormedUriString(uriString2, UriKind.Relative))
                                        {
                                            mimePart.ContentLocation = new Uri(uriString2, UriKind.Relative);
                                            continue;
                                        }

                                        continue;
                                    case TnefPropertyId.AttachFlags:
                                        if ((tnefPropertyReader.ReadValueAsInt32() & 4) != 0)
                                        {
                                            if (mimePart.ContentDisposition == null)
                                            {
                                                mimePart.ContentDisposition = new ContentDisposition("inline");
                                                continue;
                                            }

                                            mimePart.ContentDisposition.Disposition = "inline";
                                            continue;
                                        }

                                        continue;
                                    case TnefPropertyId.AttachDisposition:
                                        var disposition = tnefPropertyReader.ReadValueAsString();
                                        if (mimePart.ContentDisposition == null)
                                        {
                                            mimePart.ContentDisposition = new ContentDisposition(disposition);
                                            continue;
                                        }

                                        mimePart.ContentDisposition.Disposition = disposition;
                                        continue;
                                    case TnefPropertyId.AttachSize:
                                        if (mimePart.ContentDisposition == null)
                                        {
                                            mimePart.ContentDisposition = new ContentDisposition();
                                        }

                                        mimePart.ContentDisposition.Size = new long?(tnefPropertyReader.ReadValueAsInt64());
                                        continue;
                                    case TnefPropertyId.DisplayName:
                                        mimePart.ContentType.Name = tnefPropertyReader.ReadValueAsString();
                                        continue;
                                    default:
                                        continue;
                                }
                            }
                            break;
                        }
                        break;
                    case TnefAttributeTag.AttachTitle:
                        var name = tnefPropertyReader.ReadValueAsString();
                        if (mimePart != null && String.IsNullOrEmpty(mimePart.FileName))
                        {
                            mimePart.FileName = name;
                            break;
                        }

                        break;
                    case TnefAttributeTag.AttachCreateDate:
                        var creationDateTime = tnefPropertyReader.ReadValueAsDateTime();
                        if (mimePart != null)
                        {
                            if (mimePart.ContentDisposition == null)
                            {
                                mimePart.ContentDisposition = new ContentDisposition();
                            }

                            mimePart.ContentDisposition.CreationDate = new DateTimeOffset(creationDateTime);
                            break;
                        }

                        break;
                    case TnefAttributeTag.AttachModifyDate:
                        var modifyDateTime = tnefPropertyReader.ReadValueAsDateTime();
                        if (mimePart != null)
                        {
                            if (mimePart.ContentDisposition == null)
                            {
                                mimePart.ContentDisposition = new ContentDisposition();
                            }

                            mimePart.ContentDisposition.ModificationDate = new DateTimeOffset(modifyDateTime);
                            break;
                        }

                        break;
                }
            }

            while (reader.ReadNextAttribute());
        }
예제 #11
0
        static void ExtractAttachments(TnefReader reader, BodyBuilder builder)
        {
            var filter = new BestEncodingFilter ();
            var prop = reader.TnefPropertyReader;
            MimePart attachment = null;
            int outIndex, outLength;
            byte[] attachData;
            string text;

            Console.WriteLine ("Extracting attachments...");

            do {
                if (reader.AttributeLevel != TnefAttributeLevel.Attachment)
                    Assert.Fail ("Expected attachment attribute level: {0}", reader.AttributeLevel);

                switch (reader.AttributeTag) {
                case TnefAttributeTag.AttachRenderData:
                    attachment = new MimePart ();
                    builder.Attachments.Add (attachment);
                    break;
                case TnefAttributeTag.Attachment:
                    if (attachment == null)
                        break;

                    while (prop.ReadNextProperty ()) {
                        switch (prop.PropertyTag.Id) {
                        case TnefPropertyId.AttachLongFilename:
                            attachment.FileName = prop.ReadValueAsString ();

                            Console.WriteLine ("Attachment Property: {0} = {1}", prop.PropertyTag.Id, attachment.FileName);
                            break;
                        case TnefPropertyId.AttachFilename:
                            if (attachment.FileName == null) {
                                attachment.FileName = prop.ReadValueAsString ();
                                Console.WriteLine ("Attachment Property: {0} = {1}", prop.PropertyTag.Id, attachment.FileName);
                            } else {
                                Console.WriteLine ("Attachment Property: {0} = {1}", prop.PropertyTag.Id, prop.ReadValueAsString ());
                            }
                            break;
                        case TnefPropertyId.AttachContentLocation:
                            text = prop.ReadValueAsString ();
                            if (Uri.IsWellFormedUriString (text, UriKind.Absolute))
                                attachment.ContentLocation = new Uri (text, UriKind.Absolute);
                            else if (Uri.IsWellFormedUriString (text, UriKind.Relative))
                                attachment.ContentLocation = new Uri (text, UriKind.Relative);
                            Console.WriteLine ("Attachment Property: {0} = {1}", prop.PropertyTag.Id, text);
                            break;
                        case TnefPropertyId.AttachContentBase:
                            text = prop.ReadValueAsString ();
                            attachment.ContentBase = new Uri (text, UriKind.Absolute);
                            Console.WriteLine ("Attachment Property: {0} = {1}", prop.PropertyTag.Id, text);
                            break;
                        case TnefPropertyId.AttachContentId:
                            attachment.ContentId = prop.ReadValueAsString ();
                            Console.WriteLine ("Attachment Property: {0} = {1}", prop.PropertyTag.Id, attachment.ContentId);
                            break;
                        case TnefPropertyId.AttachDisposition:
                            text = prop.ReadValueAsString ();
                            if (attachment.ContentDisposition == null)
                                attachment.ContentDisposition = new ContentDisposition (text);
                            else
                                attachment.ContentDisposition.Disposition = text;
                            Console.WriteLine ("Attachment Property: {0} = {1}", prop.PropertyTag.Id, text);
                            break;
                        case TnefPropertyId.AttachData:
                            if (prop.IsEmbeddedMessage) {
                                Console.WriteLine ("Attachment Property: {0} is an EmbeddedMessage", prop.PropertyTag.Id);
                                var stream = prop.GetRawValueReadStream ();
                                using (var tnef = new TnefReader (stream, reader.MessageCodepage, reader.ComplianceMode)) {
                                    var embedded = ExtractTnefMessage (tnef);
                                    Console.WriteLine ("embedded attachments = {0}", embedded.BodyParts.Count ());
                                    foreach (var part in embedded.BodyParts)
                                        builder.Attachments.Add (part);
                                }
                            } else {
                                Console.WriteLine ("Attachment Property: {0} is not an EmbeddedMessage", prop.PropertyTag.Id);
                            }
                            break;
                        default:
                            Console.WriteLine ("Attachment Property (unhandled): {0} = {1}", prop.PropertyTag.Id, prop.ReadValue ());
                            break;
                        }
                    }
                    break;
                case TnefAttributeTag.AttachData:
                    if (attachment == null)
                        break;

                    attachData = prop.ReadValueAsBytes ();
                    filter.Flush (attachData, 0, attachData.Length, out outIndex, out outLength);
                    attachment.ContentTransferEncoding = filter.GetBestEncoding (EncodingConstraint.SevenBit);
                    attachment.ContentObject = new ContentObject (new MemoryStream (attachData, false));
                    filter.Reset ();
                    break;
                default:
                    Console.WriteLine ("Attachment Attribute (unhandled): {0} = {1}", reader.AttributeTag, prop.ReadValue ());
                    break;
                }
            } while (reader.ReadNextAttribute ());
        }
        private void ExtractMapiProperties(TnefReader reader, MimeMessage message, BodyBuilder builder)
        {
            var tnefPropertyReader = reader.TnefPropertyReader;
            while (tnefPropertyReader.ReadNextProperty())
            {
                switch (tnefPropertyReader.PropertyTag.Id)
                {
                    case TnefPropertyId.RtfCompressed:
                        var memoryStream = new MemoryStream();
                        if (tnefPropertyReader.PropertyTag.ValueTnefType == TnefPropertyType.String8 || tnefPropertyReader.PropertyTag.ValueTnefType == TnefPropertyType.Unicode || tnefPropertyReader.PropertyTag.ValueTnefType == TnefPropertyType.Binary)
                        {
                            var textPart = new TextPart("rtf");
                            textPart.ContentType.Name = "body.rtf";
                            RtfCompressedToRtf rtfCompressedToRtf = new RtfCompressedToRtf();
                            //var memoryStream = new MemoryStream();
                            using (var filteredStream = new FilteredStream(memoryStream))
                            {
                                filteredStream.Add(rtfCompressedToRtf);
                                using (Stream rawValueReadStream = tnefPropertyReader.GetRawValueReadStream())
                                {
                                    rawValueReadStream.CopyTo(filteredStream, 4096);
                                    filteredStream.Flush();
                                }
                            }

                            textPart.ContentObject = new ContentObject(memoryStream, ContentEncoding.Default);
                            memoryStream.Position = 0L;
                            builder.Attachments.Add(textPart);
                            continue;
                        }

                        memoryStream.Dispose();
                        continue;
                    case TnefPropertyId.BodyHtml:
                        if (tnefPropertyReader.PropertyTag.ValueTnefType == TnefPropertyType.String8 || tnefPropertyReader.PropertyTag.ValueTnefType == TnefPropertyType.Unicode || tnefPropertyReader.PropertyTag.ValueTnefType == TnefPropertyType.Binary)
                        {
                            var textPart = new TextPart("html");
                            textPart.ContentType.Name = "body.html";
                            textPart.Text = tnefPropertyReader.ReadValueAsString();
                            builder.Attachments.Add(textPart);
                            continue;
                        }

                        continue;
                    case TnefPropertyId.InternetMessageId:
                        if (tnefPropertyReader.PropertyTag.ValueTnefType == TnefPropertyType.String8 || tnefPropertyReader.PropertyTag.ValueTnefType == TnefPropertyType.Unicode)
                        {
                            message.MessageId = tnefPropertyReader.ReadValueAsString();
                            continue;
                        }

                        continue;
                    case TnefPropertyId.Subject:
                        if (tnefPropertyReader.PropertyTag.ValueTnefType == TnefPropertyType.String8 || tnefPropertyReader.PropertyTag.ValueTnefType == TnefPropertyType.Unicode)
                        {
                            message.Subject = tnefPropertyReader.ReadValueAsString();
                            continue;
                        }

                        continue;
                    case TnefPropertyId.Body:
                        if (tnefPropertyReader.PropertyTag.ValueTnefType == TnefPropertyType.String8 || tnefPropertyReader.PropertyTag.ValueTnefType == TnefPropertyType.Unicode || tnefPropertyReader.PropertyTag.ValueTnefType == TnefPropertyType.Binary)
                        {
                            var textPart = new TextPart("plain");
                            textPart.ContentType.Name = "body.txt";
                            textPart.Text = tnefPropertyReader.ReadValueAsString();
                            builder.Attachments.Add(textPart);
                            continue;
                        }

                        continue;
                    case TnefPropertyId.ConversationTopic:
                        if (tnefPropertyReader.PropertyTag.ValueTnefType == TnefPropertyType.String8 || tnefPropertyReader.PropertyTag.ValueTnefType == TnefPropertyType.Unicode)
                        {
                            message.Subject = tnefPropertyReader.ReadValueAsString();
                            continue;
                        }

                        continue;
                    case TnefPropertyId.SenderName:
                        if (tnefPropertyReader.PropertyTag.ValueTnefType == TnefPropertyType.String8 || tnefPropertyReader.PropertyTag.ValueTnefType == TnefPropertyType.Unicode)
                        {
                            var sender = new MailboxAddress(string.Empty, tnefPropertyReader.ReadValueAsString());
                            message.Sender = sender;
                        }

                        continue;
                    case (TnefPropertyId)Mapi.ID.PR_PRIMARY_SEND_ACCOUNT:
                        if (tnefPropertyReader.PropertyTag.ValueTnefType == TnefPropertyType.String8 || tnefPropertyReader.PropertyTag.ValueTnefType == TnefPropertyType.Unicode)
                        {
                            var senderEmail = new MailboxAddress(string.Empty, tnefPropertyReader.ReadValueAsString());
                            message.Sender = senderEmail;
                        }

                        continue;
                    default:
                        try
                        {
                            tnefPropertyReader.ReadValue();
                            continue;
                        }
                        catch
                        {
                            continue;
                        }
                }
            }
        }
		/// <summary>
		/// Initializes a new instance of the <see cref="MimeKit.Tnef.TnefReaderStream"/> class.
		/// </summary>
		/// <remarks>
		/// Creates a stream for reading a raw value from the <see cref="TnefReader"/>.
		/// </remarks>
		/// <param name="tnefReader">The <see cref="TnefReader"/>.</param>
		/// <param name="endOffset">The end offset.</param>
		public TnefReaderStream (TnefReader tnefReader, int endOffset)
		{
			valueEndOffset = endOffset;
			reader = tnefReader;
		}
예제 #14
0
        static void ExtractMapiProperties(TnefReader reader, MimeMessage message, BodyBuilder builder)
        {
            var            prop              = reader.TnefPropertyReader;
            var            recipient         = new EmailAddress();
            var            sender            = new EmailAddress();
            string         normalizedSubject = null;
            string         subjectPrefix     = null;
            MailboxAddress mailbox;
            var            msgid = false;

            while (prop.ReadNextProperty())
            {
                switch (prop.PropertyTag.Id)
                {
                case TnefPropertyId.InternetMessageId:
                    if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode)
                    {
                        message.MessageId = prop.ReadValueAsString();
                        msgid             = true;
                    }
                    break;

                case TnefPropertyId.TnefCorrelationKey:
                    // According to MSDN, PidTagTnefCorrelationKey is a unique key that is
                    // meant to be used to tie the TNEF attachment to the encapsulating
                    // message. It can be a string or a binary blob. It seems that most
                    // implementations use the Message-Id string, so if this property
                    // value looks like a Message-Id, then us it as one (unless we get a
                    // InternetMessageId property, in which case we use that instead.
                    if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Binary)
                    {
                        if (!msgid)
                        {
                            var value = prop.ReadValueAsString();

                            if (value.Length > 5 && value[0] == '<' && value[value.Length - 1] == '>' && value.IndexOf('@') != -1)
                            {
                                message.MessageId = value;
                            }
                        }
                    }
                    break;

                case TnefPropertyId.Subject:
                    if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode)
                    {
                        message.Subject = prop.ReadValueAsString();
                    }
                    break;

                case TnefPropertyId.SubjectPrefix:
                    if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode)
                    {
                        subjectPrefix = prop.ReadValueAsString();
                    }
                    break;

                case TnefPropertyId.NormalizedSubject:
                    if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode)
                    {
                        normalizedSubject = prop.ReadValueAsString();
                    }
                    break;

                case TnefPropertyId.SenderName:
                    if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode)
                    {
                        sender.Name = prop.ReadValueAsString();
                    }
                    break;

                case TnefPropertyId.SenderEmailAddress:
                    if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode)
                    {
                        sender.Addr = prop.ReadValueAsString();
                    }
                    break;

                case TnefPropertyId.SenderSearchKey:
                    if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Binary)
                    {
                        sender.SearchKey = prop.ReadValueAsString();
                    }
                    break;

                case TnefPropertyId.SenderAddrtype:
                    if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode)
                    {
                        sender.AddrType = prop.ReadValueAsString();
                    }
                    break;

                case TnefPropertyId.ReceivedByName:
                    if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode)
                    {
                        recipient.Name = prop.ReadValueAsString();
                    }
                    break;

                case TnefPropertyId.ReceivedByEmailAddress:
                    if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode)
                    {
                        recipient.Addr = prop.ReadValueAsString();
                    }
                    break;

                case TnefPropertyId.ReceivedBySearchKey:
                    if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Binary)
                    {
                        recipient.SearchKey = prop.ReadValueAsString();
                    }
                    break;

                case TnefPropertyId.ReceivedByAddrtype:
                    if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode)
                    {
                        recipient.AddrType = prop.ReadValueAsString();
                    }
                    break;

                case TnefPropertyId.RtfCompressed:
                    if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Binary)
                    {
                        var rtf = new TextPart("rtf");

                        var converter = new RtfCompressedToRtf();
                        var content   = new MemoryBlockStream();

                        using (var filtered = new FilteredStream(content)) {
                            filtered.Add(converter);

                            using (var compressed = prop.GetRawValueReadStream()) {
                                compressed.CopyTo(filtered, 4096);
                                filtered.Flush();
                            }
                        }

                        rtf.Content      = new MimeContent(content);
                        content.Position = 0;

                        builder.Attachments.Add(rtf);
                    }
                    break;

                case TnefPropertyId.BodyHtml:
                    if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Binary)
                    {
                        var      html = new TextPart("html");
                        Encoding encoding;

                        if (prop.PropertyTag.ValueTnefType != TnefPropertyType.Unicode)
                        {
                            encoding = Encoding.GetEncoding(reader.MessageCodepage);
                        }
                        else
                        {
                            encoding = CharsetUtils.UTF8;
                        }

                        html.SetText(encoding, prop.ReadValueAsString());

                        builder.Attachments.Add(html);
                    }
                    break;

                case TnefPropertyId.Body:
                    if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Binary)
                    {
                        var      plain = new TextPart("plain");
                        Encoding encoding;

                        if (prop.PropertyTag.ValueTnefType != TnefPropertyType.Unicode)
                        {
                            encoding = Encoding.GetEncoding(reader.MessageCodepage);
                        }
                        else
                        {
                            encoding = CharsetUtils.UTF8;
                        }

                        plain.SetText(encoding, prop.ReadValueAsString());

                        builder.Attachments.Add(plain);
                    }
                    break;

                case TnefPropertyId.Importance:
                    // https://msdn.microsoft.com/en-us/library/ee237166(v=exchg.80).aspx
                    switch (prop.ReadValueAsInt32())
                    {
                    case 2: message.Importance = MessageImportance.High; break;

                    case 1: message.Importance = MessageImportance.Normal; break;

                    case 0: message.Importance = MessageImportance.Low; break;
                    }
                    break;

                case TnefPropertyId.Priority:
                    // https://msdn.microsoft.com/en-us/library/ee159473(v=exchg.80).aspx
                    switch (prop.ReadValueAsInt32())
                    {
                    case  1: message.Priority = MessagePriority.Urgent; break;

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

                    case -1: message.Priority = MessagePriority.NonUrgent; break;
                    }
                    break;

                case TnefPropertyId.Sensitivity:
                    // https://msdn.microsoft.com/en-us/library/ee217353(v=exchg.80).aspx
                    // https://tools.ietf.org/html/rfc2156#section-5.3.4
                    switch (prop.ReadValueAsInt32())
                    {
                    case 1: message.Headers[HeaderId.Sensitivity] = "Personal"; break;

                    case 2: message.Headers[HeaderId.Sensitivity] = "Private"; break;

                    case 3: message.Headers[HeaderId.Sensitivity] = "Company-Confidential"; break;

                    case 0: message.Headers.Remove(HeaderId.Sensitivity); break;
                    }
                    break;
                }
            }

            if (string.IsNullOrEmpty(message.Subject) && !string.IsNullOrEmpty(normalizedSubject))
            {
                if (!string.IsNullOrEmpty(subjectPrefix))
                {
                    message.Subject = subjectPrefix + normalizedSubject;
                }
                else
                {
                    message.Subject = normalizedSubject;
                }
            }

            if (sender.TryGetMailboxAddress(out mailbox))
            {
                message.From.Add(mailbox);
            }

            if (recipient.TryGetMailboxAddress(out mailbox))
            {
                message.To.Add(mailbox);
            }
        }
예제 #15
0
        static void ExtractRecipientTable(TnefReader reader, MimeMessage message)
        {
            var prop = reader.TnefPropertyReader;

            // Note: The RecipientTable uses rows of properties...
            while (prop.ReadNextRow())
            {
                string transmitableDisplayName = null;
                string recipientDisplayName    = null;
                string displayName             = string.Empty;
                InternetAddressList list       = null;
                string addr = null;

                while (prop.ReadNextProperty())
                {
                    switch (prop.PropertyTag.Id)
                    {
                    case TnefPropertyId.RecipientType:
                        int recipientType = prop.ReadValueAsInt32();
                        switch (recipientType)
                        {
                        case 1: list = message.To; break;

                        case 2: list = message.Cc; break;

                        case 3: list = message.Bcc; break;
                        }
                        break;

                    case TnefPropertyId.TransmitableDisplayName:
                        transmitableDisplayName = prop.ReadValueAsString();
                        break;

                    case TnefPropertyId.RecipientDisplayName:
                        recipientDisplayName = prop.ReadValueAsString();
                        break;

                    case TnefPropertyId.DisplayName:
                        displayName = prop.ReadValueAsString();
                        break;

                    case TnefPropertyId.EmailAddress:
                        if (string.IsNullOrEmpty(addr))
                        {
                            addr = prop.ReadValueAsString();
                        }
                        break;

                    case TnefPropertyId.SmtpAddress:
                        // The SmtpAddress, if it exists, should take precedence over the EmailAddress
                        // (since the SmtpAddress is meant to be used in the RCPT TO command).
                        addr = prop.ReadValueAsString();
                        break;
                    }
                }

                if (list != null && !string.IsNullOrEmpty(addr))
                {
                    var name = recipientDisplayName ?? transmitableDisplayName ?? displayName;

                    list.Add(new MailboxAddress(name, addr));
                }
            }
        }
        private MimeMessage ExtractTnefMessage(TnefReader reader)
        {
            var tnefReader = reader.TnefPropertyReader;
            var builder = new BodyBuilder();
            var message = new MimeMessage();
            while (reader.ReadNextAttribute() && reader.AttributeLevel == TnefAttributeLevel.Message)
            {
                switch (reader.AttributeTag)
                {
                    case TnefAttributeTag.MapiProperties:
                        this.ExtractMapiProperties(reader, message, builder);
                        continue;
                    case TnefAttributeTag.DateReceived:
                        message.Date = tnefReader.ReadValueAsDateTime();
                        continue;
                    default:
                        continue;
                }
            }

            if (reader.AttributeLevel == TnefAttributeLevel.Attachment)
            {
                ExtractAttachments(reader, builder);
            }

            message.Body = builder.ToMessageBody();

            return message;
        }
예제 #17
0
        static MimeMessage ParseTnefMessage(string path, TnefComplianceStatus expected)
        {
            using (var reader = new TnefReader (File.OpenRead (path), 0, TnefComplianceMode.Loose)) {
                var message = ExtractTnefMessage (reader);

                Assert.AreEqual (expected, reader.ComplianceStatus, "Unexpected compliance status.");

                return message;
            }
        }
예제 #18
0
		static void ExtractMapiProperties (TnefReader reader, MimeMessage message, BodyBuilder builder)
		{
			var prop = reader.TnefPropertyReader;

			while (prop.ReadNextProperty ()) {
				switch (prop.PropertyTag.Id) {
				case TnefPropertyId.InternetMessageId:
					if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 ||
						prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode) {
						message.MessageId = prop.ReadValueAsString ();
					}
					break;
				case TnefPropertyId.Subject:
					if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 ||
						prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode) {
						message.Subject = prop.ReadValueAsString ();
					}
					break;
				case TnefPropertyId.RtfCompressed:
					if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 ||
						prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode ||
						prop.PropertyTag.ValueTnefType == TnefPropertyType.Binary) {
						var rtf = new TextPart ("rtf");
						rtf.ContentType.Name = "body.rtf";

						var converter = new RtfCompressedToRtf ();
						var content = new MemoryStream ();

						using (var filtered = new FilteredStream (content)) {
							filtered.Add (converter);

							using (var compressed = prop.GetRawValueReadStream ()) {
								compressed.CopyTo (filtered, 4096);
								filtered.Flush ();
							}
						}

						rtf.ContentObject = new ContentObject (content);
						content.Position = 0;

						builder.Attachments.Add (rtf);
					}
					break;
				case TnefPropertyId.BodyHtml:
					if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 ||
						prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode ||
						prop.PropertyTag.ValueTnefType == TnefPropertyType.Binary) {
						var html = new TextPart ("html");
						html.ContentType.Name = "body.html";
						html.Text = prop.ReadValueAsString ();

						builder.Attachments.Add (html);
					}
					break;
				case TnefPropertyId.Body:
					if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 ||
						prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode ||
						prop.PropertyTag.ValueTnefType == TnefPropertyType.Binary) {
						var plain = new TextPart ("plain");
						plain.ContentType.Name = "body.txt";
						plain.Text = prop.ReadValueAsString ();

						builder.Attachments.Add (plain);
					}
					break;
				}
			}
		}
예제 #19
0
        static MimeMessage ExtractTnefMessage(TnefReader reader)
        {
            var builder = new BodyBuilder ();
            var message = new MimeMessage ();

            while (reader.ReadNextAttribute ()) {
                if (reader.AttributeLevel == TnefAttributeLevel.Attachment)
                    break;

                if (reader.AttributeLevel != TnefAttributeLevel.Message)
                    Assert.Fail ("Unknown attribute level.");

                var prop = reader.TnefPropertyReader;

                switch (reader.AttributeTag) {
                case TnefAttributeTag.RecipientTable:
                    ExtractRecipientTable (reader, message);
                    break;
                case TnefAttributeTag.MapiProperties:
                    ExtractMapiProperties (reader, message, builder);
                    break;
                case TnefAttributeTag.DateSent:
                    message.Date = prop.ReadValueAsDateTime ();
                    Console.WriteLine ("Message Attribute: {0} = {1}", reader.AttributeTag, message.Date);
                    break;
                case TnefAttributeTag.Body:
                    builder.TextBody = prop.ReadValueAsString ();
                    Console.WriteLine ("Message Attribute: {0} = {1}", reader.AttributeTag, builder.TextBody);
                    break;
                case TnefAttributeTag.TnefVersion:
                    Console.WriteLine ("Message Attribute: {0} = {1}", reader.AttributeTag, prop.ReadValueAsInt32 ());
                    break;
                case TnefAttributeTag.OemCodepage:
                    int codepage = prop.ReadValueAsInt32 ();
                    try {
                        var encoding = Encoding.GetEncoding (codepage);
                        Console.WriteLine ("Message Attribute: OemCodepage = {0}", encoding.HeaderName);
                    }
                    catch {
                        Console.WriteLine ("Message Attribute: OemCodepage = {0}", codepage);
                    }
                    break;
                default:
                    Console.WriteLine ("Message Attribute (unhandled): {0} = {1}", reader.AttributeTag, prop.ReadValue ());
                    break;
                }
            }

            if (reader.AttributeLevel == TnefAttributeLevel.Attachment) {
                ExtractAttachments (reader, builder);
            } else {
                Console.WriteLine ("no attachments");
            }

            message.Body = builder.ToMessageBody ();

            return message;
        }
예제 #20
0
        static void ExtractRecipientTable(TnefReader reader, MimeMessage message)
        {
            var prop = reader.TnefPropertyReader;

            // Note: The RecipientTable uses rows of properties...
            while (prop.ReadNextRow ()) {
                InternetAddressList list = null;
                string name = null, addr = null;

                while (prop.ReadNextProperty ()) {
                    switch (prop.PropertyTag.Id) {
                    case TnefPropertyId.RecipientType:
                        int recipientType = prop.ReadValueAsInt32 ();
                        switch (recipientType) {
                        case 1: list = message.To; break;
                        case 2: list = message.Cc; break;
                        case 3: list = message.Bcc; break;
                        default:
                            Assert.Fail ("Invalid recipient type.");
                            break;
                        }
                        Console.WriteLine ("RecipientTable Property: {0} = {1}", prop.PropertyTag.Id, recipientType);
                        break;
                    case TnefPropertyId.TransmitableDisplayName:
                        if (string.IsNullOrEmpty (name)) {
                            name = prop.ReadValueAsString ();
                            Console.WriteLine ("RecipientTable Property: {0} = {1}", prop.PropertyTag.Id, name);
                        } else {
                            Console.WriteLine ("RecipientTable Property: {0} = {1}", prop.PropertyTag.Id, prop.ReadValueAsString ());
                        }
                        break;
                    case TnefPropertyId.DisplayName:
                        name = prop.ReadValueAsString ();
                        Console.WriteLine ("RecipientTable Property: {0} = {1}", prop.PropertyTag.Id, name);
                        break;
                    case TnefPropertyId.EmailAddress:
                        if (string.IsNullOrEmpty (addr)) {
                            addr = prop.ReadValueAsString ();
                            Console.WriteLine ("RecipientTable Property: {0} = {1}", prop.PropertyTag.Id, addr);
                        } else {
                            Console.WriteLine ("RecipientTable Property: {0} = {1}", prop.PropertyTag.Id, prop.ReadValueAsString ());
                        }
                        break;
                    case TnefPropertyId.SmtpAddress:
                        // The SmtpAddress, if it exists, should take precedence over the EmailAddress
                        // (since the SmtpAddress is meant to be used in the RCPT TO command).
                        addr = prop.ReadValueAsString ();
                        Console.WriteLine ("RecipientTable Property: {0} = {1}", prop.PropertyTag.Id, addr);
                        break;
                    default:
                        Console.WriteLine ("RecipientTable Property (unhandled): {0} = {1}", prop.PropertyTag.Id, prop.ReadValue ());
                        break;
                    }
                }

                Assert.IsNotNull (list, "The recipient type was never specified.");
                Assert.IsNotNull (addr, "The address was never specified.");

                if (list != null)
                    list.Add (new MailboxAddress (name, addr));
            }
        }
예제 #21
0
        static void ExtractMapiProperties(TnefReader reader, MimeMessage message, BodyBuilder builder)
        {
            var prop = reader.TnefPropertyReader;

            while (prop.ReadNextProperty ()) {
                switch (prop.PropertyTag.Id) {
                case TnefPropertyId.InternetMessageId:
                    if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode) {
                        message.MessageId = prop.ReadValueAsString ();
                        Console.WriteLine ("Message Property: {0} = {1}", prop.PropertyTag.Id, message.MessageId);
                    } else {
                        Assert.Fail ("Unknown property type for Message-Id: {0}", prop.PropertyTag.ValueTnefType);
                    }
                    break;
                case TnefPropertyId.Subject:
                    if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode) {
                        message.Subject = prop.ReadValueAsString ();
                        Console.WriteLine ("Message Property: {0} = {1}", prop.PropertyTag.Id, message.Subject);
                    } else {
                        Assert.Fail ("Unknown property type for Subject: {0}", prop.PropertyTag.ValueTnefType);
                    }
                    break;
                case TnefPropertyId.RtfCompressed:
                    if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Binary) {
                        var rtf = new TextPart ("rtf");
                        rtf.ContentType.Name = "body.rtf";

                        var converter = new RtfCompressedToRtf ();
                        var content = new MemoryStream ();

                        using (var filtered = new FilteredStream (content)) {
                            filtered.Add (converter);

                            using (var compressed = prop.GetRawValueReadStream ()) {
                                compressed.CopyTo (filtered, 4096);
                                filtered.Flush ();
                            }
                        }

                        rtf.ContentObject = new ContentObject (content);
                        content.Position = 0;

                        builder.Attachments.Add (rtf);

                        Console.WriteLine ("Message Property: {0} = <compressed rtf data>", prop.PropertyTag.Id);
                    } else {
                        Assert.Fail ("Unknown property type for {0}: {1}", prop.PropertyTag.Id, prop.PropertyTag.ValueTnefType);
                    }
                    break;
                case TnefPropertyId.BodyHtml:
                    if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Binary) {
                        var html = new TextPart ("html");
                        html.ContentType.Name = "body.html";
                        html.Text = prop.ReadValueAsString ();

                        builder.Attachments.Add (html);

                        Console.WriteLine ("Message Property: {0} = {1}", prop.PropertyTag.Id, html.Text);
                    } else {
                        Assert.Fail ("Unknown property type for {0}: {1}", prop.PropertyTag.Id, prop.PropertyTag.ValueTnefType);
                    }
                    break;
                case TnefPropertyId.Body:
                    if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Binary) {
                        var plain = new TextPart ("plain");
                        plain.ContentType.Name = "body.txt";
                        plain.Text = prop.ReadValueAsString ();

                        builder.Attachments.Add (plain);

                        Console.WriteLine ("Message Property: {0} = {1}", prop.PropertyTag.Id, plain.Text);
                    } else {
                        Assert.Fail ("Unknown property type for {0}: {1}", prop.PropertyTag.Id, prop.PropertyTag.ValueTnefType);
                    }
                    break;
                default:
                    Console.WriteLine ("Message Property (unhandled): {0} = {1}", prop.PropertyTag.Id, prop.ReadValue ());
                    break;
                }
            }
        }
예제 #22
0
        static void ExtractMapiProperties(TnefReader reader, MimeMessage message, BodyBuilder builder)
        {
            var prop = reader.TnefPropertyReader;

            while (prop.ReadNextProperty())
            {
                switch (prop.PropertyTag.Id)
                {
                case TnefPropertyId.InternetMessageId:
                    if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode)
                    {
                        message.MessageId = prop.ReadValueAsString();
                    }
                    break;

                case TnefPropertyId.Subject:
                    if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode)
                    {
                        message.Subject = prop.ReadValueAsString();
                    }
                    break;

                case TnefPropertyId.RtfCompressed:
                    if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Binary)
                    {
                        var rtf = new TextPart("rtf");

                        var converter = new RtfCompressedToRtf();
                        var content   = new MemoryBlockStream();

                        using (var filtered = new FilteredStream(content)) {
                            filtered.Add(converter);

                            using (var compressed = prop.GetRawValueReadStream()) {
                                compressed.CopyTo(filtered, 4096);
                                filtered.Flush();
                            }
                        }

                        rtf.Content      = new MimeContent(content);
                        content.Position = 0;

                        builder.Attachments.Add(rtf);
                    }
                    break;

                case TnefPropertyId.BodyHtml:
                    if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Binary)
                    {
                        var      html = new TextPart("html");
                        Encoding encoding;

                        if (prop.PropertyTag.ValueTnefType != TnefPropertyType.Unicode)
                        {
                            encoding = Encoding.GetEncoding(reader.MessageCodepage);
                        }
                        else
                        {
                            encoding = CharsetUtils.UTF8;
                        }

                        html.SetText(encoding, prop.ReadValueAsString());

                        builder.Attachments.Add(html);
                    }
                    break;

                case TnefPropertyId.Body:
                    if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Binary)
                    {
                        var      plain = new TextPart("plain");
                        Encoding encoding;

                        if (prop.PropertyTag.ValueTnefType != TnefPropertyType.Unicode)
                        {
                            encoding = Encoding.GetEncoding(reader.MessageCodepage);
                        }
                        else
                        {
                            encoding = CharsetUtils.UTF8;
                        }

                        plain.SetText(encoding, prop.ReadValueAsString());

                        builder.Attachments.Add(plain);
                    }
                    break;

                case TnefPropertyId.Importance:
                    switch (prop.ReadValueAsInt32())
                    {
                    case 2: message.Importance = MessageImportance.High; break;

                    case 0: message.Importance = MessageImportance.Low; break;
                    }
                    break;

                case TnefPropertyId.Priority:
                    switch (prop.ReadValueAsInt32())
                    {
                    case 2: message.Priority = MessagePriority.Urgent; break;

                    case 0: message.Priority = MessagePriority.NonUrgent; break;
                    }
                    break;
                }
            }
        }
예제 #23
0
		/// <summary>
		/// Converts the TNEF content into a <see cref="MimeKit.MimeMessage"/>.
		/// </summary>
		/// <remarks>
		/// TNEF data often contains properties that map to <see cref="MimeKit.MimeMessage"/>
		/// headers. TNEF data also often contains file attachments which will be
		/// mapped to MIME parts.
		/// </remarks>
		/// <returns>A message representing the TNEF data in MIME format.</returns>
		/// <exception cref="System.InvalidOperationException">
		/// The <see cref="MimeKit.MimePart.ContentObject"/> property is <c>null</c>.
		/// </exception>
		public MimeMessage ConvertToMessage ()
		{
			if (ContentObject == null)
				throw new InvalidOperationException ("Cannot parse TNEF data without a ContentObject.");

			int codepage = 0;

			if (!string.IsNullOrEmpty (ContentType.Charset)) {
				if ((codepage = CharsetUtils.GetCodePage (ContentType.Charset)) == -1)
					codepage = 0;
			}

			using (var reader = new TnefReader (ContentObject.Open (), codepage, TnefComplianceMode.Loose)) {
				return ExtractTnefMessage (reader);
			}
		}
예제 #24
0
        static void ExtractAttachments(TnefReader reader, BodyBuilder builder)
        {
            var             attachMethod = TnefAttachMethod.ByValue;
            var             filter = new BestEncodingFilter();
            var             prop = reader.TnefPropertyReader;
            MimePart        attachment = null;
            int             outIndex, outLength;
            TnefAttachFlags flags;

            string[] mimeType;
            byte[]   attachData;
            string   text;

            do
            {
                if (reader.AttributeLevel != TnefAttributeLevel.Attachment)
                {
                    break;
                }

                switch (reader.AttributeTag)
                {
                case TnefAttributeTag.AttachRenderData:
                    attachMethod = TnefAttachMethod.ByValue;
                    attachment   = new MimePart();
                    break;

                case TnefAttributeTag.Attachment:
                    if (attachment == null)
                    {
                        break;
                    }

                    while (prop.ReadNextProperty())
                    {
                        switch (prop.PropertyTag.Id)
                        {
                        case TnefPropertyId.AttachLongFilename:
                            attachment.FileName = prop.ReadValueAsString();
                            break;

                        case TnefPropertyId.AttachFilename:
                            if (attachment.FileName == null)
                            {
                                attachment.FileName = prop.ReadValueAsString();
                            }
                            break;

                        case TnefPropertyId.AttachContentLocation:
                            text = prop.ReadValueAsString();
                            if (Uri.IsWellFormedUriString(text, UriKind.Absolute))
                            {
                                attachment.ContentLocation = new Uri(text, UriKind.Absolute);
                            }
                            else if (Uri.IsWellFormedUriString(text, UriKind.Relative))
                            {
                                attachment.ContentLocation = new Uri(text, UriKind.Relative);
                            }
                            break;

                        case TnefPropertyId.AttachContentBase:
                            text = prop.ReadValueAsString();
                            attachment.ContentBase = new Uri(text, UriKind.Absolute);
                            break;

                        case TnefPropertyId.AttachContentId:
                            attachment.ContentId = prop.ReadValueAsString();
                            break;

                        case TnefPropertyId.AttachDisposition:
                            text = prop.ReadValueAsString();
                            if (attachment.ContentDisposition == null)
                            {
                                attachment.ContentDisposition = new ContentDisposition(text);
                            }
                            else
                            {
                                attachment.ContentDisposition.Disposition = text;
                            }
                            break;

                        case TnefPropertyId.AttachData:
                            var stream  = prop.GetRawValueReadStream();
                            var content = new MemoryStream();
                            var guid    = new byte[16];

                            if (attachMethod == TnefAttachMethod.EmbeddedMessage)
                            {
                                var tnef = new TnefPart();

                                foreach (var param in attachment.ContentType.Parameters)
                                {
                                    tnef.ContentType.Parameters[param.Name] = param.Value;
                                }

                                if (attachment.ContentDisposition != null)
                                {
                                    tnef.ContentDisposition = attachment.ContentDisposition;
                                }

                                attachment = tnef;
                            }

                            // read the GUID
                            stream.Read(guid, 0, 16);

                            // the rest is content
                            using (var filtered = new FilteredStream(content)) {
                                filtered.Add(filter);
                                stream.CopyTo(filtered, 4096);
                                filtered.Flush();
                            }

                            content.Position = 0;

                            attachment.ContentTransferEncoding = filter.GetBestEncoding(EncodingConstraint.SevenBit);
                            attachment.Content = new MimeContent(content);
                            filter.Reset();

                            builder.Attachments.Add(attachment);
                            break;

                        case TnefPropertyId.AttachMethod:
                            attachMethod = (TnefAttachMethod)prop.ReadValueAsInt32();
                            break;

                        case TnefPropertyId.AttachMimeTag:
                            mimeType = prop.ReadValueAsString().Split('/');
                            if (mimeType.Length == 2)
                            {
                                attachment.ContentType.MediaType    = mimeType[0].Trim();
                                attachment.ContentType.MediaSubtype = mimeType[1].Trim();
                            }
                            break;

                        case TnefPropertyId.AttachFlags:
                            flags = (TnefAttachFlags)prop.ReadValueAsInt32();
                            if ((flags & TnefAttachFlags.RenderedInBody) != 0)
                            {
                                if (attachment.ContentDisposition == null)
                                {
                                    attachment.ContentDisposition = new ContentDisposition(ContentDisposition.Inline);
                                }
                                else
                                {
                                    attachment.ContentDisposition.Disposition = ContentDisposition.Inline;
                                }
                            }
                            break;

                        case TnefPropertyId.AttachSize:
                            if (attachment.ContentDisposition == null)
                            {
                                attachment.ContentDisposition = new ContentDisposition();
                            }

                            attachment.ContentDisposition.Size = prop.ReadValueAsInt64();
                            break;

                        case TnefPropertyId.DisplayName:
                            attachment.ContentType.Name = prop.ReadValueAsString();
                            break;
                        }
                    }
                    break;

                case TnefAttributeTag.AttachCreateDate:
                    if (attachment != null)
                    {
                        if (attachment.ContentDisposition == null)
                        {
                            attachment.ContentDisposition = new ContentDisposition();
                        }

                        attachment.ContentDisposition.CreationDate = prop.ReadValueAsDateTime();
                    }
                    break;

                case TnefAttributeTag.AttachModifyDate:
                    if (attachment != null)
                    {
                        if (attachment.ContentDisposition == null)
                        {
                            attachment.ContentDisposition = new ContentDisposition();
                        }

                        attachment.ContentDisposition.ModificationDate = prop.ReadValueAsDateTime();
                    }
                    break;

                case TnefAttributeTag.AttachTitle:
                    if (attachment != null && string.IsNullOrEmpty(attachment.FileName))
                    {
                        attachment.FileName = prop.ReadValueAsString();
                    }
                    break;

                case TnefAttributeTag.AttachMetaFile:
                    if (attachment == null)
                    {
                        break;
                    }

                    // TODO: what to do with the meta data?
                    break;

                case TnefAttributeTag.AttachData:
                    if (attachment == null || attachMethod != TnefAttachMethod.ByValue)
                    {
                        break;
                    }

                    attachData = prop.ReadValueAsBytes();
                    filter.Flush(attachData, 0, attachData.Length, out outIndex, out outLength);
                    attachment.ContentTransferEncoding = filter.GetBestEncoding(EncodingConstraint.EightBit);
                    attachment.Content = new MimeContent(new MemoryStream(attachData, false));
                    filter.Reset();

                    builder.Attachments.Add(attachment);
                    break;
                }
            } while (reader.ReadNextAttribute());
        }
예제 #25
0
		static void ExtractAttachments (TnefReader reader, BodyBuilder builder)
		{
			var attachMethod = TnefAttachMethod.ByValue;
			var filter = new BestEncodingFilter ();
			var prop = reader.TnefPropertyReader;
			MimePart attachment = null;
			int outIndex, outLength;
			TnefAttachFlags flags;
			string[] mimeType;
			byte[] attachData;
			string text;

			do {
				if (reader.AttributeLevel != TnefAttributeLevel.Attachment)
					break;

				switch (reader.AttributeTag) {
				case TnefAttributeTag.AttachRenderData:
					attachMethod = TnefAttachMethod.ByValue;
					attachment = new MimePart ();
					break;
				case TnefAttributeTag.Attachment:
					if (attachment == null)
						break;

					while (prop.ReadNextProperty ()) {
						switch (prop.PropertyTag.Id) {
						case TnefPropertyId.AttachLongFilename:
							attachment.FileName = prop.ReadValueAsString ();
							break;
						case TnefPropertyId.AttachFilename:
							if (attachment.FileName == null)
								attachment.FileName = prop.ReadValueAsString ();
							break;
						case TnefPropertyId.AttachContentLocation:
							text = prop.ReadValueAsString ();
							if (Uri.IsWellFormedUriString (text, UriKind.Absolute))
								attachment.ContentLocation = new Uri (text, UriKind.Absolute);
							else if (Uri.IsWellFormedUriString (text, UriKind.Relative))
								attachment.ContentLocation = new Uri (text, UriKind.Relative);
							break;
						case TnefPropertyId.AttachContentBase:
							text = prop.ReadValueAsString ();
							attachment.ContentBase = new Uri (text, UriKind.Absolute);
							break;
						case TnefPropertyId.AttachContentId:
							attachment.ContentId = prop.ReadValueAsString ();
							break;
						case TnefPropertyId.AttachDisposition:
							text = prop.ReadValueAsString ();
							if (attachment.ContentDisposition == null)
								attachment.ContentDisposition = new ContentDisposition (text);
							else
								attachment.ContentDisposition.Disposition = text;
							break;
						case TnefPropertyId.AttachData:
							var stream = prop.GetRawValueReadStream ();
							var content = new MemoryStream ();
							var guid = new byte[16];

							if (attachMethod == TnefAttachMethod.EmbeddedMessage) {
								var tnef = new TnefPart ();

								foreach (var param in attachment.ContentType.Parameters)
									tnef.ContentType.Parameters[param.Name] = param.Value;

								if (attachment.ContentDisposition != null)
									tnef.ContentDisposition = attachment.ContentDisposition;

								attachment = tnef;
							}

							// read the GUID
							stream.Read (guid, 0, 16);

							// the rest is content
							using (var filtered = new FilteredStream (content)) {
								filtered.Add (filter);
								stream.CopyTo (filtered, 4096);
								filtered.Flush ();
							}

							content.Position = 0;

							attachment.ContentTransferEncoding = filter.GetBestEncoding (EncodingConstraint.SevenBit);
							attachment.ContentObject = new ContentObject (content);
							filter.Reset ();

							builder.Attachments.Add (attachment);
							break;
						case TnefPropertyId.AttachMethod:
							attachMethod = (TnefAttachMethod) prop.ReadValueAsInt32 ();
							break;
						case TnefPropertyId.AttachMimeTag:
							mimeType = prop.ReadValueAsString ().Split ('/');
							if (mimeType.Length == 2) {
								attachment.ContentType.MediaType = mimeType[0].Trim ();
								attachment.ContentType.MediaSubtype = mimeType[1].Trim ();
							}
							break;
						case TnefPropertyId.AttachFlags:
							flags = (TnefAttachFlags) prop.ReadValueAsInt32 ();
							if ((flags & TnefAttachFlags.RenderedInBody) != 0) {
								if (attachment.ContentDisposition == null)
									attachment.ContentDisposition = new ContentDisposition (ContentDisposition.Inline);
								else
									attachment.ContentDisposition.Disposition = ContentDisposition.Inline;
							}
							break;
						case TnefPropertyId.AttachSize:
							if (attachment.ContentDisposition == null)
								attachment.ContentDisposition = new ContentDisposition ();

							attachment.ContentDisposition.Size = prop.ReadValueAsInt64 ();
							break;
						case TnefPropertyId.DisplayName:
							attachment.ContentType.Name = prop.ReadValueAsString ();
							break;
						}
					}
					break;
				case TnefAttributeTag.AttachCreateDate:
					if (attachment != null) {
						if (attachment.ContentDisposition == null)
							attachment.ContentDisposition = new ContentDisposition ();

						attachment.ContentDisposition.CreationDate = prop.ReadValueAsDateTime ();
					}
					break;
				case TnefAttributeTag.AttachModifyDate:
					if (attachment != null) {
						if (attachment.ContentDisposition == null)
							attachment.ContentDisposition = new ContentDisposition ();

						attachment.ContentDisposition.ModificationDate = prop.ReadValueAsDateTime ();
					}
					break;
				case TnefAttributeTag.AttachTitle:
					if (attachment != null && string.IsNullOrEmpty (attachment.FileName))
						attachment.FileName = prop.ReadValueAsString ();
					break;
				case TnefAttributeTag.AttachMetaFile:
					if (attachment == null)
						break;

					// TODO: what to do with the meta data?
					break;
				case TnefAttributeTag.AttachData:
					if (attachment == null || attachMethod != TnefAttachMethod.ByValue)
						break;

					attachData = prop.ReadValueAsBytes ();
					filter.Flush (attachData, 0, attachData.Length, out outIndex, out outLength);
					attachment.ContentTransferEncoding = filter.GetBestEncoding (EncodingConstraint.EightBit);
					attachment.ContentObject = new ContentObject (new MemoryStream (attachData, false));
					filter.Reset ();

					builder.Attachments.Add (attachment);
					break;
				}
			} while (reader.ReadNextAttribute ());
		}
예제 #26
0
 /// <summary>
 /// Initialize a new instance of the <see cref="TnefReaderStream"/> class.
 /// </summary>
 /// <remarks>
 /// Creates a stream for reading a raw value from the <see cref="TnefReader"/>.
 /// </remarks>
 /// <param name="tnefReader">The <see cref="TnefReader"/>.</param>
 /// <param name="dataEndOffset">The end offset of the data.</param>
 /// <param name="valueEndOffset">The end offset of the container value.</param>
 public TnefReaderStream(TnefReader tnefReader, int dataEndOffset, int valueEndOffset)
 {
     this.valueEndOffset = valueEndOffset;
     this.dataEndOffset  = dataEndOffset;
     reader = tnefReader;
 }
예제 #27
0
        static void ExtractMapiProperties(TnefReader reader, MimeMessage message, BodyBuilder builder)
        {
            var prop = reader.TnefPropertyReader;

            while (prop.ReadNextProperty())
            {
                switch (prop.PropertyTag.Id)
                {
                case TnefPropertyId.InternetMessageId:
                    if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode)
                    {
                        message.MessageId = prop.ReadValueAsString();
                    }
                    break;

                case TnefPropertyId.Subject:
                    if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode)
                    {
                        message.Subject = prop.ReadValueAsString();
                    }
                    break;

                case TnefPropertyId.RtfCompressed:
                    if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Binary)
                    {
                        var rtf = new TextPart("rtf");
                        rtf.ContentType.Name = "body.rtf";

                        var converter = new RtfCompressedToRtf();
                        var content   = new MemoryBlockStream();

                        using (var filtered = new FilteredStream(content)) {
                            filtered.Add(converter);

                            using (var compressed = prop.GetRawValueReadStream()) {
                                compressed.CopyTo(filtered, 4096);
                                filtered.Flush();
                            }
                        }

                        rtf.ContentObject = new ContentObject(content);
                        content.Position  = 0;

                        builder.Attachments.Add(rtf);
                    }
                    break;

                case TnefPropertyId.BodyHtml:
                    if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Binary)
                    {
                        var html = new TextPart("html");
                        html.ContentType.Name = "body.html";
                        html.Text             = prop.ReadValueAsString();

                        builder.Attachments.Add(html);
                    }
                    break;

                case TnefPropertyId.Body:
                    if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Binary)
                    {
                        var plain = new TextPart("plain");
                        plain.ContentType.Name = "body.txt";
                        plain.Text             = prop.ReadValueAsString();

                        builder.Attachments.Add(plain);
                    }
                    break;
                }
            }
        }
예제 #28
0
		static void ExtractAttachments (TnefReader reader, BodyBuilder builder)
		{
			var filter = new BestEncodingFilter ();
			var prop = reader.TnefPropertyReader;
			MimePart attachment = null;
			int outIndex, outLength;
			byte[] attachData;
			string text;

			do {
				if (reader.AttributeLevel != TnefAttributeLevel.Attachment)
					break;

				switch (reader.AttributeTag) {
				case TnefAttributeTag.AttachRenderData:
					attachment = new MimePart ();
					builder.Attachments.Add (attachment);
					break;
				case TnefAttributeTag.Attachment:
					if (attachment == null)
						break;

					while (prop.ReadNextProperty ()) {
						switch (prop.PropertyTag.Id) {
						case TnefPropertyId.AttachLongFilename:
							attachment.FileName = prop.ReadValueAsString ();
							break;
						case TnefPropertyId.AttachFilename:
							if (attachment.FileName == null)
								attachment.FileName = prop.ReadValueAsString ();
							break;
						case TnefPropertyId.AttachContentLocation:
							text = prop.ReadValueAsString ();
							if (Uri.IsWellFormedUriString (text, UriKind.Absolute))
								attachment.ContentLocation = new Uri (text, UriKind.Absolute);
							else if (Uri.IsWellFormedUriString (text, UriKind.Relative))
								attachment.ContentLocation = new Uri (text, UriKind.Relative);
							break;
						case TnefPropertyId.AttachContentBase:
							text = prop.ReadValueAsString ();
							attachment.ContentBase = new Uri (text, UriKind.Absolute);
							break;
						case TnefPropertyId.AttachContentId:
							attachment.ContentId = prop.ReadValueAsString ();
							break;
						case TnefPropertyId.AttachDisposition:
							text = prop.ReadValueAsString ();
							if (attachment.ContentDisposition == null)
								attachment.ContentDisposition = new ContentDisposition (text);
							else
								attachment.ContentDisposition.Disposition = text;
							break;
						case TnefPropertyId.AttachData:
							// TODO: implement this...
							break;
						}
					}
					break;
				case TnefAttributeTag.AttachData:
					if (attachment == null)
						break;

					attachData = prop.ReadValueAsBytes ();
					filter.Flush (attachData, 0, attachData.Length, out outIndex, out outLength);
					attachment.ContentTransferEncoding = filter.GetBestEncoding (EncodingConstraint.EightBit);
					attachment.ContentObject = new ContentObject (new MemoryStream (attachData, false));
					filter.Reset ();
					break;
				}
			} while (reader.ReadNextAttribute ());
		}
예제 #29
0
		static void ExtractAttachments (TnefReader reader, BodyBuilder builder)
		{
			var attachMethod = TnefAttachMethod.ByValue;
			var filter = new BestEncodingFilter ();
			var prop = reader.TnefPropertyReader;
			MimePart attachment = null;
			int outIndex, outLength;
			TnefAttachFlags flags;
			string[] mimeType;
			byte[] attachData;
			DateTime time;
			string text;

			Console.WriteLine ("Extracting attachments...");

			do {
				if (reader.AttributeLevel != TnefAttributeLevel.Attachment)
					Assert.Fail ("Expected attachment attribute level: {0}", reader.AttributeLevel);

				switch (reader.AttributeTag) {
				case TnefAttributeTag.AttachRenderData:
					Console.WriteLine ("Attachment Attribute: {0}", reader.AttributeTag);
					attachMethod = TnefAttachMethod.ByValue;
					attachment = new MimePart ();
					break;
				case TnefAttributeTag.Attachment:
					Console.WriteLine ("Attachment Attribute: {0}", reader.AttributeTag);
					if (attachment == null)
						break;

					while (prop.ReadNextProperty ()) {
						switch (prop.PropertyTag.Id) {
						case TnefPropertyId.AttachLongFilename:
							attachment.FileName = prop.ReadValueAsString ();

							Console.WriteLine ("Attachment Property: {0} = {1}", prop.PropertyTag.Id, attachment.FileName);
							break;
						case TnefPropertyId.AttachFilename:
							if (attachment.FileName == null) {
								attachment.FileName = prop.ReadValueAsString ();
								Console.WriteLine ("Attachment Property: {0} = {1}", prop.PropertyTag.Id, attachment.FileName);
							} else {
								Console.WriteLine ("Attachment Property: {0} = {1}", prop.PropertyTag.Id, prop.ReadValueAsString ());
							}
							break;
						case TnefPropertyId.AttachContentLocation:
							text = prop.ReadValueAsString ();
							if (Uri.IsWellFormedUriString (text, UriKind.Absolute))
								attachment.ContentLocation = new Uri (text, UriKind.Absolute);
							else if (Uri.IsWellFormedUriString (text, UriKind.Relative))
								attachment.ContentLocation = new Uri (text, UriKind.Relative);
							Console.WriteLine ("Attachment Property: {0} = {1}", prop.PropertyTag.Id, text);
							break;
						case TnefPropertyId.AttachContentBase:
							text = prop.ReadValueAsString ();
							attachment.ContentBase = new Uri (text, UriKind.Absolute);
							Console.WriteLine ("Attachment Property: {0} = {1}", prop.PropertyTag.Id, text);
							break;
						case TnefPropertyId.AttachContentId:
							attachment.ContentId = prop.ReadValueAsString ();
							Console.WriteLine ("Attachment Property: {0} = {1}", prop.PropertyTag.Id, attachment.ContentId);
							break;
						case TnefPropertyId.AttachDisposition:
							text = prop.ReadValueAsString ();
							if (attachment.ContentDisposition == null)
								attachment.ContentDisposition = new ContentDisposition (text);
							else
								attachment.ContentDisposition.Disposition = text;
							Console.WriteLine ("Attachment Property: {0} = {1}", prop.PropertyTag.Id, text);
							break;
						case TnefPropertyId.AttachMethod:
							attachMethod = (TnefAttachMethod) prop.ReadValueAsInt32 ();
							Console.WriteLine ("Attachment Property: {0} = {1}", prop.PropertyTag.Id, attachMethod);
							break;
						case TnefPropertyId.AttachMimeTag:
							text = prop.ReadValueAsString ();
							mimeType = text.Split ('/');
							if (mimeType.Length == 2) {
								attachment.ContentType.MediaType = mimeType[0].Trim ();
								attachment.ContentType.MediaSubtype = mimeType[1].Trim ();
							}
							Console.WriteLine ("Attachment Property: {0} = {1}", prop.PropertyTag.Id, text);
							break;
						case TnefPropertyId.AttachFlags:
							flags = (TnefAttachFlags) prop.ReadValueAsInt32 ();
							if ((flags & TnefAttachFlags.RenderedInBody) != 0) {
								if (attachment.ContentDisposition == null)
									attachment.ContentDisposition = new ContentDisposition (ContentDisposition.Inline);
								else
									attachment.ContentDisposition.Disposition = ContentDisposition.Inline;
							}
							Console.WriteLine ("Attachment Property: {0} = {1}", prop.PropertyTag.Id, flags);
							break;
						case TnefPropertyId.AttachData:
							var stream = prop.GetRawValueReadStream ();
							var content = new MemoryStream ();
							var guid = new byte[16];

							if (attachMethod == TnefAttachMethod.EmbeddedMessage) {
								var tnef = new TnefPart ();

								foreach (var param in attachment.ContentType.Parameters)
									tnef.ContentType.Parameters[param.Name] = param.Value;

								if (attachment.ContentDisposition != null)
									tnef.ContentDisposition = attachment.ContentDisposition;

								attachment = tnef;
							}

							stream.Read (guid, 0, 16);

							stream.CopyTo (content, 4096);

							var buffer = content.GetBuffer ();
							filter.Flush (buffer, 0, (int) content.Length, out outIndex, out outLength);
							attachment.ContentTransferEncoding = filter.GetBestEncoding (EncodingConstraint.SevenBit);
							attachment.ContentObject = new ContentObject (content);
							filter.Reset ();

							Console.WriteLine ("Attachment Property: {0} has GUID {1}", prop.PropertyTag.Id, new Guid (guid));

							builder.Attachments.Add (attachment);
							break;
						case TnefPropertyId.DisplayName:
							attachment.ContentType.Name = prop.ReadValueAsString ();
							Console.WriteLine ("Attachment Property: {0} = {1}", prop.PropertyTag.Id, attachment.ContentType.Name);
							break;
						case TnefPropertyId.AttachSize:
							if (attachment.ContentDisposition == null)
								attachment.ContentDisposition = new ContentDisposition ();

							attachment.ContentDisposition.Size = prop.ReadValueAsInt64 ();
							Console.WriteLine ("Attachment Property: {0} = {1}", prop.PropertyTag.Id, attachment.ContentDisposition.Size.Value);
							break;
						default:
							Console.WriteLine ("Attachment Property (unhandled): {0} = {1}", prop.PropertyTag.Id, prop.ReadValue ());
							break;
						}
					}
					break;
				case TnefAttributeTag.AttachData:
					Console.WriteLine ("Attachment Attribute: {0}", reader.AttributeTag);
					if (attachment == null || attachMethod != TnefAttachMethod.ByValue)
						break;

					attachData = prop.ReadValueAsBytes ();
					filter.Flush (attachData, 0, attachData.Length, out outIndex, out outLength);
					attachment.ContentTransferEncoding = filter.GetBestEncoding (EncodingConstraint.SevenBit);
					attachment.ContentObject = new ContentObject (new MemoryStream (attachData, false));
					filter.Reset ();

					builder.Attachments.Add (attachment);
					break;
				case TnefAttributeTag.AttachCreateDate:
					time = prop.ReadValueAsDateTime ();

					if (attachment != null) {
						if (attachment.ContentDisposition == null)
							attachment.ContentDisposition = new ContentDisposition ();

						attachment.ContentDisposition.CreationDate = time;
					}

					Console.WriteLine ("Attachment Attribute: {0} = {1}", reader.AttributeTag, time);
					break;
				case TnefAttributeTag.AttachModifyDate:
					time = prop.ReadValueAsDateTime ();

					if (attachment != null) {
						if (attachment.ContentDisposition == null)
							attachment.ContentDisposition = new ContentDisposition ();

						attachment.ContentDisposition.ModificationDate = time;
					}

					Console.WriteLine ("Attachment Attribute: {0} = {1}", reader.AttributeTag, time);
					break;
				case TnefAttributeTag.AttachTitle:
					text = prop.ReadValueAsString ();

					if (attachment != null && string.IsNullOrEmpty (attachment.FileName))
						attachment.FileName = text;

					Console.WriteLine ("Attachment Attribute: {0} = {1}", reader.AttributeTag, text);
					break;
				default:
					Console.WriteLine ("Attachment Attribute (unhandled): {0} = {1}", reader.AttributeTag, prop.ReadValue ());
					break;
				}
			} while (reader.ReadNextAttribute ());
		}
예제 #30
0
		static MimeMessage ExtractTnefMessage (TnefReader reader)
		{
			var builder = new BodyBuilder ();
			var message = new MimeMessage ();

			while (reader.ReadNextAttribute ()) {
				if (reader.AttributeLevel == TnefAttributeLevel.Attachment)
					break;

				var prop = reader.TnefPropertyReader;

				switch (reader.AttributeTag) {
				case TnefAttributeTag.RecipientTable:
					ExtractRecipientTable (reader, message);
					break;
				case TnefAttributeTag.MapiProperties:
					ExtractMapiProperties (reader, message, builder);
					break;
				case TnefAttributeTag.DateSent:
					message.Date = prop.ReadValueAsDateTime ();
					break;
				case TnefAttributeTag.Body:
					builder.TextBody = prop.ReadValueAsString ();
					break;
				}
			}

			if (reader.AttributeLevel == TnefAttributeLevel.Attachment)
				ExtractAttachments (reader, builder);

			message.Body = builder.ToMessageBody ();

			return message;
		}
예제 #31
0
        static void ExtractAttachments(TnefReader reader, BodyBuilder builder)
        {
            var      attachMethod = TnefAttachMethod.ByValue;
            var      filter = new BestEncodingFilter();
            var      prop = reader.TnefPropertyReader;
            MimePart attachment = null;
            int      outIndex, outLength;

            byte[] attachData;
            string text;

            do
            {
                if (reader.AttributeLevel != TnefAttributeLevel.Attachment)
                {
                    break;
                }

                switch (reader.AttributeTag)
                {
                case TnefAttributeTag.AttachRenderData:
                    attachMethod = TnefAttachMethod.ByValue;
                    attachment   = new MimePart();
                    break;

                case TnefAttributeTag.Attachment:
                    if (attachment == null)
                    {
                        break;
                    }

                    while (prop.ReadNextProperty())
                    {
                        switch (prop.PropertyTag.Id)
                        {
                        case TnefPropertyId.AttachLongFilename:
                            attachment.FileName = prop.ReadValueAsString();
                            break;

                        case TnefPropertyId.AttachFilename:
                            if (attachment.FileName == null)
                            {
                                attachment.FileName = prop.ReadValueAsString();
                            }
                            break;

                        case TnefPropertyId.AttachContentLocation:
                            text = prop.ReadValueAsString();
                            if (Uri.IsWellFormedUriString(text, UriKind.Absolute))
                            {
                                attachment.ContentLocation = new Uri(text, UriKind.Absolute);
                            }
                            else if (Uri.IsWellFormedUriString(text, UriKind.Relative))
                            {
                                attachment.ContentLocation = new Uri(text, UriKind.Relative);
                            }
                            break;

                        case TnefPropertyId.AttachContentBase:
                            text = prop.ReadValueAsString();
                            attachment.ContentBase = new Uri(text, UriKind.Absolute);
                            break;

                        case TnefPropertyId.AttachContentId:
                            attachment.ContentId = prop.ReadValueAsString();
                            break;

                        case TnefPropertyId.AttachDisposition:
                            text = prop.ReadValueAsString();
                            if (attachment.ContentDisposition == null)
                            {
                                attachment.ContentDisposition = new ContentDisposition(text);
                            }
                            else
                            {
                                attachment.ContentDisposition.Disposition = text;
                            }
                            break;

                        case TnefPropertyId.AttachData:
                            var stream  = prop.GetRawValueReadStream();
                            var content = new MemoryStream();
                            var guid    = new byte[16];

                            if (attachMethod == TnefAttachMethod.EmbeddedMessage)
                            {
                                var tnef = new TnefPart();

                                foreach (var param in attachment.ContentType.Parameters)
                                {
                                    tnef.ContentType.Parameters.Add(param.Name, param.Value);
                                }

                                if (attachment.ContentDisposition != null)
                                {
                                    tnef.ContentDisposition = attachment.ContentDisposition;
                                }

                                attachment = tnef;
                            }

                            // read the GUID
                            stream.Read(guid, 0, 16);

                            // the rest is content
                            stream.CopyTo(content, 4096);

#if !PORTABLE
                            var buffer = content.GetBuffer();
#else
                            var buffer = content.ToArray();
#endif
                            filter.Flush(buffer, 0, (int)content.Length, out outIndex, out outLength);
                            attachment.ContentTransferEncoding = filter.GetBestEncoding(EncodingConstraint.SevenBit);
                            attachment.ContentObject           = new ContentObject(content);
                            filter.Reset();

                            builder.Attachments.Add(attachment);
                            break;

                        case TnefPropertyId.AttachMethod:
                            attachMethod = (TnefAttachMethod)prop.ReadValueAsInt32();
                            break;

                        case TnefPropertyId.AttachSize:
                            if (attachment.ContentDisposition == null)
                            {
                                attachment.ContentDisposition = new ContentDisposition();
                            }

                            attachment.ContentDisposition.Size = prop.ReadValueAsInt64();
                            break;

                        case TnefPropertyId.DisplayName:
                            attachment.ContentType.Name = prop.ReadValueAsString();
                            break;
                        }
                    }
                    break;

                case TnefAttributeTag.AttachCreateDate:
                    if (attachment != null)
                    {
                        if (attachment.ContentDisposition == null)
                        {
                            attachment.ContentDisposition = new ContentDisposition();
                        }

                        attachment.ContentDisposition.CreationDate = prop.ReadValueAsDateTime();
                    }
                    break;

                case TnefAttributeTag.AttachModifyDate:
                    if (attachment != null)
                    {
                        if (attachment.ContentDisposition == null)
                        {
                            attachment.ContentDisposition = new ContentDisposition();
                        }

                        attachment.ContentDisposition.ModificationDate = prop.ReadValueAsDateTime();
                    }
                    break;

                case TnefAttributeTag.AttachTitle:
                    if (attachment != null && string.IsNullOrEmpty(attachment.FileName))
                    {
                        attachment.FileName = prop.ReadValueAsString();
                    }
                    break;

                case TnefAttributeTag.AttachMetaFile:
                    if (attachment == null)
                    {
                        break;
                    }

                    // TODO: what to do with the meta data?
                    break;

                case TnefAttributeTag.AttachData:
                    if (attachment == null || attachMethod != TnefAttachMethod.ByValue)
                    {
                        break;
                    }

                    attachData = prop.ReadValueAsBytes();
                    filter.Flush(attachData, 0, attachData.Length, out outIndex, out outLength);
                    attachment.ContentTransferEncoding = filter.GetBestEncoding(EncodingConstraint.EightBit);
                    attachment.ContentObject           = new ContentObject(new MemoryStream(attachData, false));
                    filter.Reset();

                    builder.Attachments.Add(attachment);
                    break;
                }
            } while (reader.ReadNextAttribute());
        }