コード例 #1
0
ファイル: MimeEntityFacts.cs プロジェクト: DM-TOR/nhin-d
 public void ConstructorWithContentTypeShouldSetContentType()
 {
     MimeEntity e = new MimeEntity("Hello, world", "text/silly; charset=uk-monty");
     Assert.True(e.HasHeaders);
     Assert.True(e.HasHeader("content-type"));
     Assert.True(e.HasMediaType("text/silly"));
     Assert.Equal("text/silly; charset=uk-monty", e.ContentType);
 }
コード例 #2
0
ファイル: MimeEntityFacts.cs プロジェクト: DM-TOR/nhin-d
 public void DefaultConstructorShouldCreateEmptyEntity()
 {
     MimeEntity e = new MimeEntity();
     Assert.Empty(e.Headers);
     Assert.False(e.HasBody);
     Assert.False(e.HasHeaders);
     Assert.False(e.IsMultiPart);
 }
コード例 #3
0
ファイル: MimeEntityFacts.cs プロジェクト: DM-TOR/nhin-d
 public void MimeEntityShouldHaveHeaders()
 {
     MimeEntity e = new MimeEntity("Hello, world", "text/silly");
     e.ContentDisposition = "inline";
     e.ContentTransferEncoding = "base64";
     e.Headers.Add(new Header("foo", "bar"));
     
     Assert.True(e.HasHeader("FOO"));
     Assert.Equal(4, e.Headers.Count);
 }
コード例 #4
0
ファイル: SignedEntity.cs プロジェクト: DM-TOR/nhin-d
 /// <summary>
 /// Creates an entity consisting of the content and signature.
 /// </summary>
 /// <param name="algorithm">The digest algorithm used in the signature, used for the <c>micalg</c> parameter</param>
 /// <param name="content">The content entity that was signed.</param>
 /// <param name="signature">The signature entity</param>
 public SignedEntity(DigestAlgorithm algorithm, MimeEntity content, MimeEntity signature)
     : base(CreateContentType(algorithm))
 {
     if (content == null)
     {
         throw new ArgumentNullException("content");
     }
     
     Content = content;
     Signature = signature;
 }
コード例 #5
0
ファイル: DSN.cs プロジェクト: DM-TOR/nhin-d
        /// <summary>
        /// Initializes a new instance of the supplied DSN parts.
        /// </summary>
        public DSN(DSNPerMessage perMessage, IEnumerable<DSNPerRecipient> perRecipient)
            : base(DSNStandard.MediaType.DSNReport)
        {
            m_explanation = new MimeEntity();
            m_explanation.ContentType = MimeStandard.MediaType.TextPlain;

            m_notification = new MimeEntity();
            m_notification.ContentType = DSNStandard.MediaType.DSNDeliveryStatus;
            
            PerRecipient = perRecipient;
            PerMessage = perMessage;
        }
コード例 #6
0
ファイル: DSN.cs プロジェクト: DM-TOR/nhin-d
        internal DSN(MimeEntity explanation, HeaderCollection fields, IEnumerable<HeaderCollection> perRecipientCollection)
        {
            m_explanation = explanation;

            m_perMessage = new DSNPerMessage(fields);

            m_perRecipients = new List<DSNPerRecipient>();
            foreach (HeaderCollection perRecipientFields in perRecipientCollection)
            {
                m_perRecipients.Add(new DSNPerRecipient(perRecipientFields));
            }
        }
コード例 #7
0
ファイル: Message.cs プロジェクト: DM-TOR/nhin-d
 /// <summary>Extracts the body and associated MIME <c>Content-*</c> headers as a <see cref="MimeEntity"/></summary>
 /// <remarks>
 /// The source message has MIME and non-MIME headers, and the body is not a complete MIME entity for signing and encryption.
 /// Takes the source and creates new Message that contains only items relevant to Mime
 /// </remarks>
 /// <returns>The extacted MIME headers and body as a <see cref="MimeEntity"/></returns>
 public MimeEntity ExtractMimeEntity()
 {
     MimeEntity entity = new MimeEntity();
     
     if (this.HasHeaders)
     {
         entity.Headers = this.Headers.SelectMimeHeaders();
         if (!entity.HasHeaders)
         {
             throw new MimeException(MimeError.InvalidMimeEntity);
         }
     }
     
     if (this.HasBody)
     {
         entity.Body = new Body(this.Body);
     }
     
     return entity;
 }
コード例 #8
0
ファイル: SignedEntity.cs プロジェクト: DM-TOR/nhin-d
        /// <summary>
        /// Creates a signed entity from a <see cref="MimeEntity"/>, which must be multipart and have a content and signed part.
        /// </summary>
        /// <param name="source">The source entity.</param>
        /// <returns>The newly initialized signed entity.</returns>
        public static SignedEntity Load(MimeEntity source)
        {
            if (source == null)
            {
                throw new ArgumentNullException("source");
            }

            if (!source.IsMultiPart)
            {
                throw new SignatureException(SignatureError.InvalidMultipartSigned);
            }
            
            return new SignedEntity(source.ParsedContentType, source.GetParts());
        }
コード例 #9
0
ファイル: DSNParser.cs プロジェクト: DM-TOR/nhin-d
        /// <summary>
        /// Extract DSN fields 
        /// Fields are formatted just like MIME headers, but embedded within the Body of MimeEntity instead
        /// </summary>
        /// <param name="fieldEntity">Source entity</param>
        /// <returns>Collection of fields</returns>
        public static HeaderCollection ParseDSNFields(MimeEntity fieldEntity)
        {
            if (fieldEntity == null)
            {
                throw new ArgumentNullException("fieldEntity");
            }
            Body DSNBody = fieldEntity.Body;
            if (DSNBody == null)
            {
                throw new DSNException(DSNError.InvalidDSNBody);
            }
            HeaderCollection DSNFields = null;
            try
            {
                DSNFields = new HeaderCollection(MimeSerializer.Default.DeserializeHeaders(DSNBody.TrimEmptyLines()));
            }
            catch (Exception ex)
            {
                throw new DSNException(DSNError.InvalidDSNFields, ex);
            }

            if (DSNFields.IsNullOrEmpty())
            {
                throw new DSNException(DSNError.InvalidDSNFields);
            }

            return DSNFields;
        }
コード例 #10
0
 bool DecryptSignedContent(IncomingMessage message, DirectAddress recipient, out SignedCms signatures, out MimeEntity payload)
 {
     signatures = null;
     payload = null;
     foreach (X509Certificate2 cert in recipient.Certificates)
     {
         try
         {
             if (this.DecryptSignatures(message, cert, out signatures, out payload))
             {
                 // Decrypted and extracted signatures successfully
                 return true;
             }
         }
         catch(Exception ex)
         {
             this.Notify(message, ex);
         }
     }
     
     return false;
 }
コード例 #11
0
ファイル: DSNStandard.cs プロジェクト: DM-TOR/nhin-d
        /// <summary>
        /// Tests the <paramref name="entity"/> to see if it is an DSN
        /// </summary>
        /// <remarks>
        /// DSN status is indicated by the appropriate main body <c>Content-Type</c>. The multipart body
        /// will contain the approprieate report-type />
        /// </remarks>
        /// <param name="entity">The entity to test</param>
        /// <returns><c>true</c> if the entity is an DSN, <c>false</c> otherwise</returns>
        public static bool IsReport(MimeEntity entity)
        {
            if (entity == null)
            {
                return false;
            }

            ContentType contentType = entity.ParsedContentType;
            return (contentType.IsMediaType(MediaType.ReportMessage) && contentType.HasParameter(MediaType.ReportType, MediaType.ReportTypeValueDelivery));
        }
コード例 #12
0
ファイル: TestMDN.cs プロジェクト: JoshuaJeong/nhin-d.net35
 HeaderCollection GetNotificationFields(MimeEntity notificationEntity)
 {
     return MDNParser.ParseMDNFields(notificationEntity);
 }
コード例 #13
0
ファイル: TestDSN.cs プロジェクト: DM-TOR/nhin-d
        /// <summary>
        /// Verify Disposition-Type MDN notification 
        /// </summary>
        void VerifyDSNHeaders(MimeEntity notificationEntity, DSN notification)
        {
            HeaderCollection fields = DSNParser.ParseDSNFields(notificationEntity);
            Assert.NotEmpty(fields);
            //
            // perMessage
            //
            Assert.True(fields.HasHeader(DSNStandard.Fields.ReportingMTA, "dns;" + ReportingMtaName));
            Assert.True(fields.HasHeader(DSNStandard.Fields.OriginalMessageID, OriginalID));

            //
            // perRecipient
            //
            Assert.True(fields.HasHeader(DSNStandard.Fields.FinalRecipient, 
                                         "rfc822;" + notification.PerRecipient.First().FinalRecipient.Address));
            Assert.True(fields.HasHeader(DSNStandard.Fields.Action, "failed"));
            Assert.True(fields.HasHeader(DSNStandard.Fields.Status, "5.0.0"));
            
        }
コード例 #14
0
ファイル: TestMDN.cs プロジェクト: JoshuaJeong/nhin-d.net35
 void Verify(MimeEntity[] mdnEntities)
 {
     Assert.True(mdnEntities.Length == 2);
     Assert.True(mdnEntities[1].ParsedContentType.IsMediaType(MDNStandard.MediaType.DispositionNotification));
 }
コード例 #15
0
ファイル: MimeEntityFacts.cs プロジェクト: DM-TOR/nhin-d
 public void EntityShouldHaveParsedContentType(string mediaType)
 {
     MimeEntity e = new MimeEntity("Hello, world", mediaType);
     Assert.Equal(mediaType, e.ParsedContentType.MediaType);
 }
コード例 #16
0
ファイル: MimeEntityFacts.cs プロジェクト: DM-TOR/nhin-d
 public void TextPlainShouldNotBeMultipart()
 {
     MimeEntity e = new MimeEntity("Hello, world");
     Assert.False(e.IsMultiPart);
 }
コード例 #17
0
ファイル: MimeEntityFacts.cs プロジェクト: DM-TOR/nhin-d
 public void BodyTextShouldBeAccessible()
 {
     MimeEntity e = new MimeEntity("Hello, world");
     Assert.Equal("Hello, world", e.Body.Text);
 }
コード例 #18
0
ファイル: MimeEntityFacts.cs プロジェクト: DM-TOR/nhin-d
 public void BodySourceTextShouldBeAccessible()
 {
     MimeEntity e = new MimeEntity("Hello, world");
     Assert.Equal("Hello, world", e.Body.SourceText.ToString());
 }
コード例 #19
0
ファイル: TestMDN.cs プロジェクト: JoshuaJeong/nhin-d.net35
        /// <summary>
        /// Verify Disposition-Type MDN notification 
        /// </summary>
        void VerifyDispositionTypeNotification(MimeEntity notificationEntity, Notification notification)
        {
            HeaderCollection fields = this.GetNotificationFields(notificationEntity);
            Assert.NotEmpty(fields);

            Assert.True(fields.HasHeader(MDNStandard.Fields.Disposition, notification.Disposition.ToString()), 
                string.Format("Expected a contained Disposition-Type of {0}", notification.Disposition));
            Assert.True(fields.HasHeader(MDNStandard.Fields.Gateway, "smtp;gateway.example.com"));
            Assert.True(fields.HasHeader(MDNStandard.Fields.OriginalMessageID, OriginalID));
            if (fields[MDNStandard.Fields.Error] != null)
            {
                Assert.True(fields.HasHeader(MDNStandard.Fields.Error, ErrorMessage));
            }
        }
コード例 #20
0
ファイル: Message.cs プロジェクト: DM-TOR/nhin-d
 /// <summary>
 /// Extracts the MIME entity for signing and encryption purposes.
 /// </summary>
 /// <remarks>The MIME entity for signing and encrytion consists of the <c>Content-*</c>
 /// MIME headers and the body as a complete MIME entity. Some clients omit the epilogue of a
 /// multipart message.</remarks>
 /// <param name="includeEpilogue">Should the epilogue be included if this the body of this message
 /// is multipart?</param>
 /// <returns>The complete MIME entity from this message for signing and encrytion.</returns>
 public MimeEntity ExtractEntityForSignature(bool includeEpilogue)
 {
     if (includeEpilogue || !this.IsMultiPart)
     {
         return this.ExtractMimeEntity();
     }
     
     MimeEntity signableEntity = new MimeEntity();
     signableEntity.Headers = this.Headers.SelectMimeHeaders();
     
     StringSegment content = StringSegment.Null;
     foreach(MimePart part in this.GetAllParts())
     {
         if (part.Type == MimePartType.BodyEpilogue)
         {
             content = new StringSegment(content.Source, content.StartIndex, part.SourceText.StartIndex - 1);
         }
         else
         {                
             content.Union(part.SourceText);
         }
     }            
     signableEntity.Body = new Body(content);
     
     return signableEntity;
 }                        
コード例 #21
0
ファイル: MimeEntity.cs プロジェクト: DM-TOR/nhin-d
 /// <summary>
 /// Updates this entity with a new entity, updating headers and body as appropriate.
 /// </summary>
 /// <param name="entity">The entity to update.</param>
 public virtual void UpdateBody(MimeEntity entity)
 {
     if (entity == null)
     {
         throw new ArgumentNullException("entity");
     }
     
     this.ClearParsedHeaders();
     this.Headers.AddUpdate(entity.Headers);
     this.Body = entity.Body;            
 }
コード例 #22
0
ファイル: MDNParser.cs プロジェクト: DM-TOR/nhin-d
        /// <summary>
        /// Retrieve MDN entites from the multiple parts of a message body
        /// <param name="parts">message body parts</param>
        /// <param name="explanation">(out) the explanation entity, if any</param>
        /// <param name="mdn">(out) the entity containing the MDN notification fields</param>
        /// </summary>
        public static void GetMDNEntities(IEnumerable<MimeEntity> parts, out MimeEntity explanation, out MimeEntity mdn)
        {
            if (parts == null)
            {
                throw new ArgumentNullException("parts");
            }
            
            explanation = null;
            mdn = null;
            foreach (MimeEntity entity in parts)
            {
                ContentType contentType = entity.ParsedContentType;
                if (contentType.IsMediaType(MDNStandard.MediaType.DispositionNotification))
                {
                    if (mdn != null)
                    {
                        throw new MDNException(MDNError.InvalidMDNBody);
                    }
                    mdn = entity;
                }
                else if (contentType.IsMediaType(MimeStandard.MediaType.TextPlain))
                {
                    if (explanation != null)
                    {
                        throw new MDNException(MDNError.InvalidMDNBody);
                    }
                    explanation = entity;
                }
            }

            if (explanation == null || mdn == null)
            {
                throw new MDNException(MDNError.InvalidMDNBody);
            }
        }
コード例 #23
0
ファイル: TestDSN.cs プロジェクト: DM-TOR/nhin-d
 void Verify(MimeEntity[] dsnEntities)
 {
     Assert.True(dsnEntities.Length == 2);
     //text/plain
     //future work to support text/html via a provider model.
     Assert.True(dsnEntities[0].ParsedContentType.IsMediaType(DSNStandard.MediaType.TextPlain));
     Assert.True(dsnEntities[1].ParsedContentType.IsMediaType(DSNStandard.MediaType.DSNDeliveryStatus));
 }
コード例 #24
0
ファイル: MDNParser.cs プロジェクト: DM-TOR/nhin-d
        /// <summary>
        /// Extract MDN fields (RFC 3798 Section 3.1.*). 
        /// Fields are formatted just like MIME headers, but embedded within the Body of MimeEntity instead
        /// </summary>
        /// <param name="fieldEntity">Source entity</param>
        /// <returns>Collection of fields</returns>
        public static HeaderCollection ParseMDNFields(MimeEntity fieldEntity)
        {
            if (fieldEntity == null)
            {
                throw new ArgumentNullException("fieldEntity");
            }
            Body mdnBody = fieldEntity.Body;
            if (mdnBody == null)
            {
                throw new MDNException(MDNError.InvalidMDNBody);
            }
            HeaderCollection mdnFields = null;
            try
            {
                mdnFields = new HeaderCollection(MimeSerializer.Default.DeserializeHeaders(mdnBody.Text));
            }
            catch(Exception ex)
            {
                throw new MDNException(MDNError.InvalidMDNFields, ex);
            }

            if (mdnFields.IsNullOrEmpty())
            {
                throw new MDNException(MDNError.InvalidMDNFields);
            }

            return mdnFields;
        }
コード例 #25
0
        /// <summary>
        /// Decrypt (optionally) the given message and try to extract signatures
        /// </summary>
        bool DecryptSignatures(IncomingMessage message, X509Certificate2 certificate, out SignedCms signatures, out MimeEntity payload)
        {
            MimeEntity decryptedEntity = null;
            signatures = null;
            payload = null;
            
            if (certificate != null)
            {
                decryptedEntity = m_cryptographer.DecryptEntity(message.GetEncryptedBytes(m_cryptographer), certificate);
            }
            else
            {
                decryptedEntity = message.Message;
            }
            if (decryptedEntity == null)
            {
                return false;
            }

            if (SMIMEStandard.IsContentEnvelopedSignature(decryptedEntity.ParsedContentType))
            {
                signatures = m_cryptographer.DeserializeEnvelopedSignature(decryptedEntity);
                payload = MimeSerializer.Default.Deserialize<MimeEntity>(signatures.ContentInfo.Content);
            }
            else if (SMIMEStandard.IsContentMultipartSignature(decryptedEntity.ParsedContentType))
            {
                SignedEntity signedEntity = SignedEntity.Load(decryptedEntity);
                signatures = m_cryptographer.DeserializeDetachedSignature(signedEntity);
                payload = signedEntity.Content;
            }
            else
            {
                throw new AgentException(AgentError.UnsignedMessage);
            }
            
            return true;
        }
コード例 #26
0
ファイル: MDNStandard.cs プロジェクト: DM-TOR/nhin-d
 /// <summary>
 /// Tests the <paramref name="entity"/> to see if it contains an MDN request.
 /// </summary>
 /// <param name="entity">The entity to test</param>
 /// <returns><c>true</c> if the entity contains an MDN request, <c>false</c> otherwise</returns>
 public static bool HasMDNRequest(MimeEntity entity)
 {
     if (entity == null)
     {
         return false;
     }
     
     return entity.HasHeader(Headers.DispositionNotificationTo);
 }
コード例 #27
0
ファイル: DSNParser.cs プロジェクト: DM-TOR/nhin-d
        /// <summary>
        /// Retrieve DSN entites from the multiple parts of a message body
        /// <param name="parts">message body parts</param>
        /// <param name="explanation">(out) the explanation entity, if any</param>
        /// <param name="deliveryStatus">(out) the entity containing the DSN fields</param>
        /// </summary>
        public static void GetDSNEntities(IEnumerable<MimeEntity> parts, out MimeEntity explanation, out MimeEntity deliveryStatus)
        {
            if (parts == null)
            {
                throw new ArgumentNullException("parts");
            }

            explanation = null;
            deliveryStatus = null;
            foreach (MimeEntity entity in parts)
            {
                ContentType contentType = entity.ParsedContentType;
                if (contentType.IsMediaType(DSNStandard.MediaType.DSNDeliveryStatus))
                {
                    if (deliveryStatus != null)
                    {
                        throw new DSNException(DSNError.InvalidDSNBody);
                    }
                    deliveryStatus = entity;
                }
                else if (contentType.IsMediaType(MimeStandard.MediaType.TextPlain))
                {
                    if (explanation != null)
                    {
                        throw new DSNException(DSNError.InvalidDSNBody);
                    }
                    explanation = entity;
                }
            }

            if (explanation == null || deliveryStatus == null)
            {
                throw new DSNException(DSNError.InvalidDSNBody);
            }
        }
コード例 #28
0
ファイル: MDNStandard.cs プロジェクト: DM-TOR/nhin-d
 /// <summary>
 /// Tests the <paramref name="entity"/> to see if it is an MDN
 /// </summary>
 /// <remarks>
 /// MDN status is indicated by the appropriate main body <c>Content-Type</c>. The multipart body
 /// will contain the actual disposition notification (see <see cref="MDNStandard.IsNotification"/>
 /// </remarks>
 /// <param name="entity">The entity to test</param>
 /// <returns><c>true</c> if the entity is an MDN, <c>false</c> otherwise</returns>
 public static bool IsReport(MimeEntity entity)
 {
     if (entity == null)
     {
         return false;
     }
     
     ContentType contentType = entity.ParsedContentType;
     return (contentType.IsMediaType(MDNStandard.MediaType.ReportMessage) && contentType.HasParameter(MDNStandard.ReportType, MDNStandard.ReportTypeValueNotification));
 }
コード例 #29
0
ファイル: DSNParser.cs プロジェクト: DM-TOR/nhin-d
        /// <summary>
        /// Extract per-recipient dsn headers as a collection
        /// Fields are formatted just like MIME headers, but embedded within the Body of MimeEntity instead
        /// </summary>
        /// <param name="fieldEntity">Source entity</param>
        /// <returns>Collection of <see cref="HeaderCollection"/></returns>
        public static List<HeaderCollection> ParsePerRecientFields(MimeEntity fieldEntity)
        {
            if (fieldEntity == null)
            {
                throw new ArgumentNullException("fieldEntity");
            }
            Body dsnBody = fieldEntity.Body;
            if (dsnBody == null)
            {
                throw new DSNException(DSNError.InvalidDSNBody);
            }
            HeaderCollection dsnFields = new HeaderCollection();
            try
            {
                dsnFields.Add(new HeaderCollection(MimeSerializer.Default.DeserializeHeaders(dsnBody.PerRecipientSeperator()))
                    , PerRecipientFieldList());
            }
            catch (Exception ex)
            {
                throw new DSNException(DSNError.InvalidDSNFields, ex);
            }

            if (dsnFields.IsNullOrEmpty())
            {
                throw new DSNException(DSNError.InvalidDSNFields);
            }

            return PerRecipientList(dsnFields);
        }
コード例 #30
0
ファイル: MDNStandard.cs プロジェクト: DM-TOR/nhin-d
        /// <summary>
        /// Tests the entity to determine if it is a disposition notification body part
        /// </summary>
        /// <remarks>
        /// Notification status is indicated by the appropriate <c>Content-Type</c>. The notification
        /// section will be a body part of the appropriate MDN report multipart body.
        /// </remarks>
        /// <param name="entity">The entity to test</param>
        /// <returns><c>true</c> if this body part is an MDN notification, <c>false</c> otherwise</returns>
        public static bool IsNotification(MimeEntity entity)
        {
            if (entity == null)
            {
                return false;
            }

            return entity.HasMediaType(MDNStandard.MediaType.DispositionNotification);
        }