/// <summary>
        /// Parses body from the specified stream
        /// </summary>
        /// <param name="owner">Owner MIME entity.</param>
        /// <param name="defaultContentType">Default content-type for this body.</param>
        /// <param name="stream">Stream from where to read body.</param>
        /// <returns>Returns parsed body.</returns>
        /// <exception cref="ArgumentNullException">Is raised when <b>stream</b>, <b>defaultContentType</b> or <b>stream</b> is null reference.</exception>
        /// <exception cref="ParseException">Is raised when any parsing errors.</exception>
        protected static new MIME_b Parse(MIME_Entity owner,MIME_h_ContentType defaultContentType,SmartStream stream)
        {
            if(owner == null){
                throw new ArgumentNullException("owner");
            }
            if(defaultContentType == null){
                throw new ArgumentNullException("defaultContentType");
            }
            if(stream == null){
                throw new ArgumentNullException("stream");
            }

            // We need to buffer all body data, otherwise we don't know if we have readed all data 
            // from stream.
            MemoryStream msBuffer = new MemoryStream();
            Net_Utils.StreamCopy(stream,msBuffer,32000);
            msBuffer.Position = 0;

            SmartStream parseStream = new SmartStream(msBuffer,true);

            MIME_b_MessageDeliveryStatus retVal = new MIME_b_MessageDeliveryStatus();
            //Pare per-message fields.
            retVal.m_pMessageFields.Parse(parseStream);

            // Parse per-recipient fields.
            while(parseStream.Position - parseStream.BytesInReadBuffer < parseStream.Length){
                MIME_h_Collection recipientFields = new MIME_h_Collection(new MIME_h_Provider());
                recipientFields.Parse(parseStream);
                retVal.m_pRecipientBlocks.Add(recipientFields);                
            }                     

            return retVal;
        }
Example #2
0
        /// <summary>
        /// Parses body from the specified stream
        /// </summary>
        /// <param name="owner">Owner MIME entity.</param>
        /// <param name="defaultContentType">Default content-type for this body.</param>
        /// <param name="stream">Stream from where to read body.</param>
        /// <returns>Returns parsed body.</returns>
        /// <exception cref="ArgumentNullException">Is raised when <b>stream</b>, <b>defaultContentType</b> or <b>strean</b> is null reference.</exception>
        /// <exception cref="ParseException">Is raised when any parsing errors.</exception>
        protected static new MIME_b Parse(MIME_Entity owner,MIME_h_ContentType defaultContentType,SmartStream stream)
        {
            if(owner == null){
                throw new ArgumentNullException("owner");
            }
            if(defaultContentType == null){
                throw new ArgumentNullException("defaultContentType");
            }
            if(stream == null){
                throw new ArgumentNullException("stream");
            }

            string mediaType = null;
            try{
                mediaType = owner.ContentType.TypeWithSubtype;
            }
            catch{
                mediaType = "unparsable/unparsable";
            }

            MIME_b_Unknown retVal = new MIME_b_Unknown(mediaType);
            Net_Utils.StreamCopy(stream,retVal.EncodedStream,32000);

            return retVal;
        }
Example #3
0
        /// <summary>
        /// Parses body from the specified stream
        /// </summary>
        /// <param name="owner">Owner MIME entity.</param>
        /// <param name="defaultContentType">Default content-type for this body.</param>
        /// <param name="stream">Stream from where to read body.</param>
        /// <returns>Returns parsed body.</returns>
        /// <exception cref="ArgumentNullException">Is raised when <b>stream</b>, <b>mediaType</b> or <b>stream</b> is null reference.</exception>
        /// <exception cref="ParseException">Is raised when any parsing errors.</exception>
        protected static new MIME_b Parse(MIME_Entity owner,MIME_h_ContentType defaultContentType,SmartStream stream)
        {
            if(owner == null){
                throw new ArgumentNullException("owner");
            }
            if(defaultContentType == null){
                throw new ArgumentNullException("defaultContentType");
            }
            if(stream == null){
                throw new ArgumentNullException("stream");
            }

            MIME_b_Text retVal = null;
            if(owner.ContentType != null){
                retVal = new MIME_b_Text(owner.ContentType.TypeWithSubtype);
            }
            else{
                retVal = new MIME_b_Text(defaultContentType.TypeWithSubtype);
            }

            Net_Utils.StreamCopy(stream,retVal.EncodedStream,32000);
            retVal.SetModified(false);

            return retVal;
        }
Example #4
0
        /// <summary>
        /// Sets body parent.
        /// </summary>
        /// <param name="entity">Owner entity.</param>
        /// <param name="setContentType">If true sets entity.ContentType header value.</param>
        internal virtual void SetParent(MIME_Entity entity,bool setContentType)
        {
            m_pEntity = entity;

            // Owner entity has no content-type or has different content-type, just add/overwrite it.
            if(setContentType &&(entity.ContentType == null || !string.Equals(entity.ContentType.TypeWithSubtype,this.MediaType,StringComparison.InvariantCultureIgnoreCase))){
                entity.ContentType = m_pContentType;
            }
        }
        /// <summary>
        /// Sets body parent.
        /// </summary>
        /// <param name="entity">Owner entity.</param>
        /// <param name="setContentType">If true sets entity.ContentType header value.</param>
        internal override void SetParent(MIME_Entity entity,bool setContentType)
        {
            base.SetParent(entity,setContentType);

            // Owner entity has no content-type or has different content-type, just add/overwrite it.
            if(setContentType && (this.Entity.ContentType == null || !string.Equals(this.Entity.ContentType.TypeWithSubtype,this.MediaType,StringComparison.InvariantCultureIgnoreCase))){
                this.Entity.ContentType = new MIME_h_ContentType(MediaType);
            }
        }
        /// <summary>
        /// Adds specified MIME enity to the collection.
        /// </summary>
        /// <param name="entity">MIME entity.</param>
        /// <exception cref="ArgumentNullException">Is raised when <b>entity</b> is null reference.</exception>
        public void Add(MIME_Entity entity)
        {
            if(entity == null){
                throw new ArgumentNullException("entity");
            }

            m_pCollection.Add(entity);
            m_IsModified = true;
        }
        /// <summary>
        /// Inserts a new MIME entity into the collection at the specified location.
        /// </summary>
        /// <param name="index">The location in the collection where you want to add the MIME entity.</param>
        /// <param name="entity">MIME entity.</param>
        /// <exception cref="IndexOutOfRangeException">Is raised when <b>index</b> is out of range.</exception>
        /// <exception cref="ArgumentNullException">Is raised when <b>entity</b> is null reference.</exception>
        public void Insert(int index,MIME_Entity entity)
        {
            if(entity == null){
                throw new ArgumentNullException("entity");
            }

            m_pCollection.Insert(index,entity);
            m_IsModified = true;
        }
        /// <summary>
        /// Removes specified MIME entity from the collection.
        /// </summary>
        /// <param name="entity">MIME entity.</param>
        /// <exception cref="ArgumentNullException">Is raised when <b>field</b> is null reference.</exception>
        public void Remove(MIME_Entity entity)
        {
            if(entity == null){
                throw new ArgumentNullException("field");
            }

            m_pCollection.Remove(entity);
            m_IsModified = true;
        }
        /// <summary>
        /// Parses MIME entity body from specified stream.
        /// </summary>
        /// <param name="owner">Owner MIME entity.</param>
        /// <param name="stream">Stream from where to parse entity body.</param>
        /// <param name="defaultContentType">Default content type.</param>
        /// <returns>Returns parsed body.</returns>
        /// <exception cref="ArgumentNullException">Is raised when <b>owner</b>, <b>strean</b> or <b>defaultContentType</b> is null reference.</exception>
        /// <exception cref="ParseException">Is raised when header field parsing errors.</exception>
        public MIME_b Parse(MIME_Entity owner,SmartStream stream,MIME_h_ContentType defaultContentType)
        {
            if(owner == null){
                throw new ArgumentNullException("owner");
            }
            if(stream == null){
                throw new ArgumentNullException("stream");
            }
            if(defaultContentType == null){
                throw new ArgumentNullException("defaultContentType");
            }

            string mediaType = defaultContentType.TypeWithSubype;
            if(owner.ContentType != null){
                mediaType = owner.ContentType.TypeWithSubype;
            }

            Type bodyType = null;

            // We have exact body provider for specified mediaType.
            if(m_pBodyTypes.ContainsKey(mediaType)){
                bodyType = m_pBodyTypes[mediaType];
            }
            // Use default mediaType.
            else{
                // Registered list of mediaTypes are available: http://www.iana.org/assignments/media-types/.

                string mediaRootType = mediaType.Split('/')[0].ToLowerInvariant();
                if(mediaRootType == "application"){
                    bodyType = typeof(MIME_b_Application);
                }
                else if(mediaRootType == "audio"){
                    bodyType = typeof(MIME_b_Audio);
                }
                else if(mediaRootType == "image"){
                    bodyType = typeof(MIME_b_Image);
                }
                else if(mediaRootType == "message"){
                    bodyType = typeof(MIME_b_Message);
                }
                else if(mediaRootType == "multipart"){
                    bodyType = typeof(MIME_b_Multipart);
                }
                else if(mediaRootType == "text"){
                    bodyType = typeof(MIME_b_Text);
                }
                else if(mediaRootType == "video"){
                    bodyType = typeof(MIME_b_Video);
                }
                else{
                    throw new ParseException("Invalid media-type '" + mediaType + "'.");
                }
            }

            return (MIME_b)bodyType.GetMethod("Parse",System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.FlattenHierarchy).Invoke(null,new object[]{owner,mediaType,stream});
        }
        /// <summary>
        /// Sets body parent.
        /// </summary>
        /// <param name="entity">Owner entity.</param>
        /// <param name="setContentType">If true sets entity.ContentType header value.</param>
        internal override void SetParent(MIME_Entity entity, bool setContentType)
        {
            base.SetParent(entity, setContentType);

            // Owner entity has no content-type or has different content-type, just add/overwrite it.
            if (setContentType && (this.Entity.ContentType == null || !string.Equals(this.Entity.ContentType.TypeWithSubtype, this.MediaType, Helpers.GetDefaultIgnoreCaseComparison())))
            {
                this.Entity.ContentType = new MIME_h_ContentType(MediaType);
            }
        }
Example #11
0
        /// <summary>
        /// Sets body parent.
        /// </summary>
        /// <param name="entity">Owner entity.</param>
        /// <param name="setContentType">If true sets entity.ContentType header value.</param>
        internal override void SetParent(MIME_Entity entity, bool setContentType)
        {
            base.SetParent(entity, setContentType);

            // Owner entity has no content-type or has different content-type, just add/overwrite it.
            if (setContentType && (this.Entity.ContentType == null || !String2.Equals(this.Entity.ContentType.TypeWithSubtype, this.MediaType, StringComparison2.InvariantCultureIgnoreCase)))
            {
                this.Entity.ContentType = this.ContentType;
            }
        }
        /// <summary>
        /// Removes specified MIME entity from the collection.
        /// </summary>
        /// <param name="entity">MIME entity.</param>
        /// <exception cref="ArgumentNullException">Is raised when <b>field</b> is null reference.</exception>
        public void Remove(MIME_Entity entity)
        {
            if (entity == null)
            {
                throw new ArgumentNullException("field");
            }

            m_pCollection.Remove(entity);
            m_IsModified = true;
        }
        /// <summary>
        /// Inserts a new MIME entity into the collection at the specified location.
        /// </summary>
        /// <param name="index">The location in the collection where you want to add the MIME entity.</param>
        /// <param name="entity">MIME entity.</param>
        /// <exception cref="IndexOutOfRangeException">Is raised when <b>index</b> is out of range.</exception>
        /// <exception cref="ArgumentNullException">Is raised when <b>entity</b> is null reference.</exception>
        public void Insert(int index, MIME_Entity entity)
        {
            if (entity == null)
            {
                throw new ArgumentNullException("entity");
            }

            m_pCollection.Insert(index, entity);
            m_IsModified = true;
        }
        /// <summary>
        /// Adds specified MIME enity to the collection.
        /// </summary>
        /// <param name="entity">MIME entity.</param>
        /// <exception cref="ArgumentNullException">Is raised when <b>entity</b> is null reference.</exception>
        public void Add(MIME_Entity entity)
        {
            if (entity == null)
            {
                throw new ArgumentNullException("entity");
            }

            m_pCollection.Add(entity);
            m_IsModified = true;
        }
Example #15
0
        /// <summary>
        /// Sets body parent.
        /// </summary>
        /// <param name="entity">Owner entity.</param>
        /// <param name="setContentType">If true sets entity.ContentType header value.</param>
        internal virtual void SetParent(MIME_Entity entity, bool setContentType)
        {
            m_pEntity = entity;

            // Owner entity has no content-type or has different content-type, just add/overwrite it.
            if (setContentType && (entity.ContentType == null || !string.Equals(entity.ContentType.TypeWithSubtype, this.MediaType, StringComparison.InvariantCultureIgnoreCase)))
            {
                entity.ContentType = m_pContentType;
            }
        }
        /// <summary>
        /// Stores MIME entity body to the specified stream.
        /// </summary>
        /// <param name="stream">Stream where to store body data.</param>
        /// <param name="headerWordEncoder">Header 8-bit words ecnoder. Value null means that words are not encoded.</param>
        /// <param name="headerParmetersCharset">Charset to use to encode 8-bit header parameters. Value null means parameters not encoded.</param>
        /// <exception cref="ArgumentNullException">Is raised when <b>stream</b> is null reference.</exception>
        internal protected override void ToStream(Stream stream, MIME_Encoding_EncodedWord headerWordEncoder, Encoding headerParmetersCharset)
        {
            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }

            // Set "preamble" text if any.
            if (!string.IsNullOrEmpty(m_TextPreamble))
            {
                byte[] preableBytes = null;
                if (m_TextPreamble.EndsWith("\r\n"))
                {
                    preableBytes = Encoding.UTF8.GetBytes(m_TextPreamble);
                }
                else
                {
                    preableBytes = Encoding.UTF8.GetBytes(m_TextPreamble + "\r\n");
                }
                stream.Write(preableBytes, 0, preableBytes.Length);
            }

            for (int i = 0; i < m_pBodyParts.Count; i++)
            {
                MIME_Entity bodyPart = m_pBodyParts[i];
                // Start new body part.
                byte[] bStart = Encoding.UTF8.GetBytes("--" + this.ContentType.Param_Boundary + "\r\n");
                stream.Write(bStart, 0, bStart.Length);

                bodyPart.ToStream(stream, headerWordEncoder, headerParmetersCharset);

                // Last body part, close boundary.
                if (i == (m_pBodyParts.Count - 1))
                {
                    byte[] bEnd = Encoding.UTF8.GetBytes("--" + this.ContentType.Param_Boundary + "--\r\n");
                    stream.Write(bEnd, 0, bEnd.Length);
                }
            }

            // Set "epilogoue" text if any.
            if (!string.IsNullOrEmpty(m_TextEpilogue))
            {
                byte[] epilogoueBytes = null;
                if (m_TextEpilogue.EndsWith("\r\n"))
                {
                    epilogoueBytes = Encoding.UTF8.GetBytes(m_TextEpilogue);
                }
                else
                {
                    epilogoueBytes = Encoding.UTF8.GetBytes(m_TextEpilogue + "\r\n");
                }
                stream.Write(epilogoueBytes, 0, epilogoueBytes.Length);
            }
        }
        /// <summary>
        /// Parses MIME entity body from the specified reader.
        /// </summary>
        /// <param name="reader">Body reader from where to parse body.</param>
        /// <param name="owner">Specifies if body will be stream owner.</param>
        /// <returns>Returns true if this is last boundary in the message or in multipart "body parts".</returns>
        internal override void ParseFromReader(LineReader reader, bool owner)
        {
            // For multipart we need todo new limiting(limits to specified boundary) reader.
            _MIME_MultipartReader r = new _MIME_MultipartReader(reader, m_Boundary);

            while (r.Next())
            {
                MIME_Entity bodyPart = new MIME_Entity();
                bodyPart.Parse(r, owner);
                m_pParts.Add(bodyPart);
            }
        }
Example #18
0
        /// <summary>
        /// Cleans up any resources being used. This method is thread-safe.
        /// </summary>
        public void Dispose()
        {
            lock(this){
                if(m_IsDisposed){
                    return;
                }
                m_IsDisposed = true;

                m_pHeader = null;
                m_pParent = null;
            }
        }
Example #19
0
        /// <summary>
        /// Cleans up any resources being used. This method is thread-safe.
        /// </summary>
        public void Dispose()
        {
            lock (this){
                if (m_IsDisposed)
                {
                    return;
                }
                m_IsDisposed = true;

                m_pHeader = null;
                m_pParent = null;
            }
        }
Example #20
0
        /// <summary>
        /// Parses body from the specified stream
        /// </summary>
        /// <param name="owner">Owner MIME entity.</param>
        /// <param name="defaultContentType">Default content-type for this body.</param>
        /// <param name="stream">Stream from where to read body.</param>
        /// <returns>Returns parsed body.</returns>
        /// <exception cref="ArgumentNullException">Is raised when <b>stream</b>, <b>defaultContentType</b> or <b>stream</b> is null reference.</exception>
        /// <exception cref="ParseException">Is raised when any parsing errors.</exception>
        protected static MIME_b Parse(MIME_Entity owner,MIME_h_ContentType defaultContentType,SmartStream stream)
        {
            if(owner == null){
                throw new ArgumentNullException("owner");
            }
            if(defaultContentType == null){
                throw new ArgumentNullException("defaultContentType");
            }
            if(stream == null){
                throw new ArgumentNullException("stream");
            }

            throw new NotImplementedException("Body provider class does not implement required Parse method.");
        }
Example #21
0
        /// <summary>
        /// Parses body from the specified stream
        /// </summary>
        /// <param name="owner">Owner MIME entity.</param>
        /// <param name="defaultContentType">Default content-type for this body.</param>
        /// <param name="stream">Stream from where to read body.</param>
        /// <returns>Returns parsed body.</returns>
        /// <exception cref="ArgumentNullException">Is raised when <b>stream</b>, <b>defaultContentType</b> or <b>stream</b> is null reference.</exception>
        /// <exception cref="ParseException">Is raised when any parsing errors.</exception>
        protected static MIME_b Parse(MIME_Entity owner, MIME_h_ContentType defaultContentType, SmartStream stream)
        {
            if (owner == null)
            {
                throw new ArgumentNullException("owner");
            }
            if (defaultContentType == null)
            {
                throw new ArgumentNullException("defaultContentType");
            }
            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }

            throw new NotImplementedException("Body provider class does not implement required Parse method.");
        }
Example #22
0
        /// <summary>
        /// Gets certificates contained in pkcs 7.
        /// </summary>
        /// <returns>Returns certificates contained in pkcs 7. Returns null if no certificates.</returns>
        public X509Certificate2Collection GetCertificates()
        {
            // multipart/signed must always have only 2 entities, otherwise invalid data.
            if (this.BodyParts.Count != 2)
            {
                return(null);
            }

            // Get signature. It should be 2 entity.
            MIME_Entity signatureEntity = this.BodyParts[1];

            SignedCms signedCms = new SignedCms();

            signedCms.Decode(((MIME_b_SinglepartBase)signatureEntity.Body).Data);

            return(signedCms.Certificates);
        }
        /// <summary>
        /// Parses body from the specified stream
        /// </summary>
        /// <param name="owner">Owner MIME entity.</param>
        /// <param name="defaultContentType">Default content-type for this body.</param>
        /// <param name="stream">Stream from where to read body.</param>
        /// <returns>Returns parsed body.</returns>
        /// <exception cref="ArgumentNullException">Is raised when <b>stream</b>, <b>defaultContentType</b> or <b>strean</b> is null reference.</exception>
        /// <exception cref="ParseException">Is raised when any parsing errors.</exception>
        protected static new MIME_b Parse(MIME_Entity owner,MIME_h_ContentType defaultContentType,SmartStream stream)
        {
            if(owner == null){
                throw new ArgumentNullException("owner");
            }
            if(defaultContentType == null){
                throw new ArgumentNullException("defaultContentType");
            }
            if(stream == null){
                throw new ArgumentNullException("stream");
            }

            MIME_b_ApplicationPkcs7Mime retVal = new MIME_b_ApplicationPkcs7Mime();
            Net_Utils.StreamCopy(stream,retVal.EncodedStream,32000);

            return retVal;
        }
        /// <summary>
        /// Parses body from the specified stream
        /// </summary>
        /// <param name="owner">Owner MIME entity.</param>
        /// <param name="defaultContentType">Default content-type for this body.</param>
        /// <param name="stream">Stream from where to read body.</param>
        /// <returns>Returns parsed body.</returns>
        /// <exception cref="ArgumentNullException">Is raised when <b>stream</b>, <b>defaultContentType</b> or <b>stream</b> is null reference.</exception>
        /// <exception cref="ParseException">Is raised when any parsing errors.</exception>
        protected static new MIME_b Parse(MIME_Entity owner,MIME_h_ContentType defaultContentType,SmartStream stream)
        {
            if(owner == null){
                throw new ArgumentNullException("owner");
            }
            if(defaultContentType == null){
                throw new ArgumentNullException("defaultContentType");
            }
            if(stream == null){
                throw new ArgumentNullException("stream");
            }

            MIME_b_MessageRfc822 retVal = new MIME_b_MessageRfc822();
            retVal.m_pMessage = Mail_Message.ParseFromStream(stream);

            return retVal;
        }
Example #25
0
        /// <summary>
        /// Parses body from the specified stream
        /// </summary>
        /// <param name="owner">Owner MIME entity.</param>
        /// <param name="mediaType">MIME media type. For example: text/plain.</param>
        /// <param name="stream">Stream from where to read body.</param>
        /// <returns>Returns parsed body.</returns>
        /// <exception cref="ArgumentNullException">Is raised when <b>stream</b>, <b>mediaType</b> or <b>strean</b> is null reference.</exception>
        /// <exception cref="ParseException">Is raised when any parsing errors.</exception>
        protected static new MIME_b Parse(MIME_Entity owner,string mediaType,SmartStream stream)
        {
            if(owner == null){
                throw new ArgumentNullException("owner");
            }
            if(mediaType == null){
                throw new ArgumentNullException("mediaType");
            }
            if(stream == null){
                throw new ArgumentNullException("stream");
            }

            MIME_b_Audio retVal = new MIME_b_Audio(mediaType);

            Net_Utils.StreamCopy(stream,retVal.EncodedStream,32000);

            return retVal;
        }
Example #26
0
        /// <summary>
        /// Stores MIME entity body to the specified stream.
        /// </summary>
        /// <param name="stream">Stream where to store body data.</param>
        /// <param name="headerWordEncoder">Header 8-bit words ecnoder. Value null means that words are not encoded.</param>
        /// <param name="headerParmetersCharset">Charset to use to encode 8-bit header parameters. Value null means parameters not encoded.</param>
        /// <param name="headerReencode">If true always specified encoding is used for header. If false and header field value not modified,
        /// original encoding is kept.</param>
        /// <exception cref="ArgumentNullException">Is raised when <b>stream</b> is null reference.</exception>
        internal protected override void ToStream(Stream stream, MIME_Encoding_EncodedWord headerWordEncoder, Encoding headerParmetersCharset, bool headerReencode)
        {
            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }

            /* RFC 2046 5.1.1.
             *  NOTE:  The CRLF preceding the boundary delimiter line is conceptually
             *  attached to the boundary so that it is possible to have a part that
             *  does not end with a CRLF (line  break).
             */

            // Set "preamble" text if any.
            if (!string.IsNullOrEmpty(m_TextPreamble))
            {
                byte[] preableBytes = Encoding.UTF8.GetBytes(m_TextPreamble);
                stream.Write(preableBytes, 0, preableBytes.Length);
            }

            for (int i = 0; i < m_pBodyParts.Count; i++)
            {
                MIME_Entity bodyPart = m_pBodyParts[i];
                // Start new body part.
                byte[] bStart = Encoding.UTF8.GetBytes("\r\n--" + this.Entity.ContentType.Param_Boundary + "\r\n");
                stream.Write(bStart, 0, bStart.Length);

                bodyPart.ToStream(stream, headerWordEncoder, headerParmetersCharset, headerReencode);

                // Last body part, close boundary.
                if (i == (m_pBodyParts.Count - 1))
                {
                    byte[] bEnd = Encoding.UTF8.GetBytes("\r\n--" + this.Entity.ContentType.Param_Boundary + "--\r\n");
                    stream.Write(bEnd, 0, bEnd.Length);
                }
            }

            // Set "epilogoue" text if any.
            if (!string.IsNullOrEmpty(m_TextEpilogue))
            {
                byte[] epilogoueBytes = Encoding.UTF8.GetBytes(m_TextEpilogue);
                stream.Write(epilogoueBytes, 0, epilogoueBytes.Length);
            }
        }
Example #27
0
        /// <summary>
        /// Creates text/plain MIME entity.
        /// </summary>
        /// <param name="transferEncoding">Content transfer encoding.</param>
        /// <param name="charset">Charset to use to encode text. If not sure, utf-8 is recommended.</param>
        /// <param name="text">Text.</param>
        /// <returns>Returns created entity.</returns>
        /// <exception cref="ArgumentNullException">Is raised when <b>transferEncoding</b>, <b>charset</b> or <b>text</b> is null reference.</exception>
        /// <exception cref="NotSupportedException">Is raised when body contains not supported Content-Transfer-Encoding.</exception>
        public static MIME_Entity CreateEntity_Text_Plain(string transferEncoding,Encoding charset,string text)
        {
            if(transferEncoding == null){
                throw new ArgumentNullException("transferEncoding");
            }
            if(charset == null){
                throw new ArgumentNullException("charset");
            }
            if(text == null){
                throw new ArgumentNullException("text");
            }

            MIME_Entity retVal = new MIME_Entity();
            MIME_b_Text body = new MIME_b_Text(MIME_MediaTypes.Text.plain);
            retVal.Body = body;
            body.SetText(transferEncoding,charset,text);

            return retVal;
        }
        /// <summary>
        /// Parses body from the specified stream
        /// </summary>
        /// <param name="owner">Owner MIME entity.</param>
        /// <param name="defaultContentType">Default content-type for this body.</param>
        /// <param name="stream">Stream from where to read body.</param>
        /// <returns>Returns parsed body.</returns>
        /// <exception cref="ArgumentNullException">Is raised when <b>stream</b>, <b>defaultContentType</b> or <b>stream</b> is null reference.</exception>
        /// <exception cref="ParseException">Is raised when any parsing errors.</exception>
        protected static new MIME_b Parse(MIME_Entity owner,MIME_h_ContentType defaultContentType,SmartStream stream)
        {
            if(owner == null){
                throw new ArgumentNullException("owner");
            }
            if(defaultContentType == null){
                throw new ArgumentNullException("defaultContentType");
            }
            if(stream == null){
                throw new ArgumentNullException("stream");
            }
            if(owner.ContentType == null || owner.ContentType.Param_Boundary == null){
                throw new ParseException("Multipart entity has not required 'boundary' paramter.");
            }
            
            MIME_b_MultipartParallel retVal = new MIME_b_MultipartParallel(owner.ContentType);
            ParseInternal(owner,owner.ContentType.TypeWithSubtype,stream,retVal);

            return retVal;
        }
        /// <summary>
        /// Parses body from the specified stream
        /// </summary>
        /// <param name="owner">Owner MIME entity.</param>
        /// <param name="mediaType">MIME media type. For example: text/plain.</param>
        /// <param name="stream">Stream from where to read body.</param>
        /// <returns>Returns parsed body.</returns>
        /// <exception cref="ArgumentNullException">Is raised when <b>stream</b>, <b>mediaType</b> or <b>stream</b> is null reference.</exception>
        /// <exception cref="ParseException">Is raised when any parsing errors.</exception>
        protected static new MIME_b Parse(MIME_Entity owner,string mediaType,SmartStream stream)
        {
            if(owner == null){
                throw new ArgumentNullException("owner");
            }
            if(mediaType == null){
                throw new ArgumentNullException("mediaType");
            }
            if(stream == null){
                throw new ArgumentNullException("stream");
            }
            if(owner.ContentType == null || owner.ContentType.Param_Boundary == null){
                throw new ParseException("Multipart entity has not required 'boundary' paramter.");
            }

            MIME_b_MultipartRelated retVal = new MIME_b_MultipartRelated(owner.ContentType);
            ParseInternal(owner,mediaType,stream,retVal);

            return retVal;
        }
        /// <summary>
        /// Gets all MIME entities as list.
        /// </summary>
        /// <param name="includeEmbbedMessage">If true, then embbed RFC822 message child entities are included.</param>
        /// <returns>Returns all MIME entities as list.</returns>
        /// <exception cref="ObjectDisposedException">Is raised when this class is disposed and this method is accessed.</exception>
        public MIME_Entity[] GetAllEntities(bool includeEmbbedMessage)
        {
            if (m_IsDisposed)
            {
                throw new ObjectDisposedException(this.GetType().Name);
            }

            List <MIME_Entity> retVal        = new List <MIME_Entity>();
            List <MIME_Entity> entitiesQueue = new List <MIME_Entity>();

            entitiesQueue.Add(this);

            while (entitiesQueue.Count > 0)
            {
                MIME_Entity currentEntity = entitiesQueue[0];
                entitiesQueue.RemoveAt(0);

                retVal.Add(currentEntity);

                // Current entity is multipart entity, add it's body-parts for processing.

                if (this.Body != null
                    &&
                    System.Reflection.IntrospectionExtensions.GetTypeInfo(currentEntity.Body.GetType())
                    .IsSubclassOf(typeof(MIME_b_Multipart)))
                {
                    MIME_EntityCollection bodyParts = ((MIME_b_Multipart)currentEntity.Body).BodyParts;
                    for (int i = 0; i < bodyParts.Count; i++)
                    {
                        entitiesQueue.Insert(i, bodyParts[i]);
                    }
                }
                // Add embbed message for processing (Embbed message entities will be included).
                else if (includeEmbbedMessage && this.Body != null && currentEntity.Body is MIME_b_MessageRfc822)
                {
                    entitiesQueue.Add(((MIME_b_MessageRfc822)currentEntity.Body).Message);
                }
            }

            return(retVal.ToArray());
        }
Example #31
0
        /// <summary>
        /// Parses body from the specified stream
        /// </summary>
        /// <param name="owner">Owner MIME entity.</param>
        /// <param name="mediaType">MIME media type. For example: text/plain.</param>
        /// <param name="stream">Stream from where to read body.</param>
        /// <returns>Returns parsed body.</returns>
        /// <exception cref="ArgumentNullException">Is raised when <b>stream</b>, <b>mediaType</b> or <b>strean</b> is null reference.</exception>
        /// <exception cref="ParseException">Is raised when any parsing errors.</exception>
        protected static new MIME_b Parse(MIME_Entity owner, string mediaType, SmartStream stream)
        {
            if (owner == null)
            {
                throw new ArgumentNullException("owner");
            }
            if (mediaType == null)
            {
                throw new ArgumentNullException("mediaType");
            }
            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }

            MIME_b_Audio retVal = new MIME_b_Audio(mediaType);

            Net_Utils.StreamCopy(stream, retVal.EncodedStream, 32000);

            return(retVal);
        }
        /// <summary>
        /// Parses body from the specified stream
        /// </summary>
        /// <param name="owner">Owner MIME entity.</param>
        /// <param name="mediaType">MIME media type. For example: text/plain.</param>
        /// <param name="stream">Stream from where to read body.</param>
        /// <returns>Returns parsed body.</returns>
        /// <exception cref="ArgumentNullException">Is raised when <b>stream</b>, <b>mediaType</b> or <b>stream</b> is null reference.</exception>
        /// <exception cref="ParseException">Is raised when any parsing errors.</exception>
        protected static new MIME_b Parse(MIME_Entity owner, string mediaType, SmartStream stream)
        {
            if (owner == null)
            {
                throw new ArgumentNullException("owner");
            }
            if (mediaType == null)
            {
                throw new ArgumentNullException("mediaType");
            }
            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }

            MIME_b_MessageRfc822 retVal = new MIME_b_MessageRfc822();

            retVal.m_pMessage = Mail_Message.ParseFromStream(stream);

            return(retVal);
        }
Example #33
0
        /// <summary>
        /// Parses body from the specified stream
        /// </summary>
        /// <param name="owner">Owner MIME entity.</param>
        /// <param name="defaultContentType">Default content-type for this body.</param>
        /// <param name="stream">Stream from where to read body.</param>
        /// <returns>Returns parsed body.</returns>
        /// <exception cref="ArgumentNullException">Is raised when <b>stream</b>, <b>defaultContentType</b> or <b>strean</b> is null reference.</exception>
        /// <exception cref="ParseException">Is raised when any parsing errors.</exception>
        protected static new MIME_b Parse(MIME_Entity owner, MIME_h_ContentType defaultContentType, SmartStream stream)
        {
            if (owner == null)
            {
                throw new ArgumentNullException("owner");
            }
            if (defaultContentType == null)
            {
                throw new ArgumentNullException("defaultContentType");
            }
            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }

            MIME_b_ApplicationPkcs7Mime retVal = new MIME_b_ApplicationPkcs7Mime();

            Net_Utils.StreamCopy(stream, retVal.EncodedStream, stream.LineBufferSize);

            return(retVal);
        }
Example #34
0
        /// <summary>
        /// Parses body from the specified stream
        /// </summary>
        /// <param name="owner">Owner MIME entity.</param>
        /// <param name="defaultContentType">Default content-type for this body.</param>
        /// <param name="stream">Stream from where to read body.</param>
        /// <returns>Returns parsed body.</returns>
        /// <exception cref="ArgumentNullException">Is raised when <b>stream</b>, <b>defaultContentType</b> or <b>stream</b> is null reference.</exception>
        /// <exception cref="ParseException">Is raised when any parsing errors.</exception>
        protected static new MIME_b Parse(MIME_Entity owner, MIME_h_ContentType defaultContentType, SmartStream stream)
        {
            if (owner == null)
            {
                throw new ArgumentNullException("owner");
            }
            if (defaultContentType == null)
            {
                throw new ArgumentNullException("defaultContentType");
            }
            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }

            // We need to buffer all body data, otherwise we don't know if we have readed all data
            // from stream.
            MemoryStream msBuffer = new MemoryStream();

            Net_Utils.StreamCopy(stream, msBuffer, 32000);
            msBuffer.Position = 0;

            SmartStream parseStream = new SmartStream(msBuffer, true);

            MIME_b_MessageDeliveryStatus retVal = new MIME_b_MessageDeliveryStatus();

            //Pare per-message fields.
            retVal.m_pMessageFields.Parse(parseStream);

            // Parse per-recipient fields.
            while (parseStream.Position - parseStream.BytesInReadBuffer < parseStream.Length)
            {
                MIME_h_Collection recipientFields = new MIME_h_Collection(new MIME_h_Provider());
                recipientFields.Parse(parseStream);
                retVal.m_pRecipientBlocks.Add(recipientFields);
            }

            return(retVal);
        }
Example #35
0
        /// <summary>
        /// Internal body parsing.
        /// </summary>
        /// <param name="owner">Owner MIME entity.</param>
        /// <param name="mediaType">MIME media type. For example: text/plain.</param>
        /// <param name="stream">Stream from where to read body.</param>
        /// <param name="body">Multipart body instance.</param>
        /// <exception cref="ArgumentNullException">Is raised when <b>stream</b>, <b>mediaType</b>, <b>stream</b> or <b>body</b> is null reference.</exception>
        /// <exception cref="ParseException">Is raised when any parsing errors.</exception>
        protected static void ParseInternal(MIME_Entity owner, string mediaType, SmartStream stream, MIME_b_Multipart body)
        {
            if (owner == null)
            {
                throw new ArgumentNullException("owner");
            }
            if (mediaType == null)
            {
                throw new ArgumentNullException("mediaType");
            }
            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }
            if (owner.ContentType == null || owner.ContentType.Param_Boundary == null)
            {
                throw new ParseException("Multipart entity has not required 'boundary' parameter.");
            }
            if (body == null)
            {
                throw new ArgumentNullException("body");
            }

            _MultipartReader multipartReader = new _MultipartReader(stream, owner.ContentType.Param_Boundary);

            while (multipartReader.Next())
            {
                MIME_Entity entity = new MIME_Entity();
                entity.Parse(new SmartStream(multipartReader, false), Encoding.UTF8, body.DefaultBodyPartContentType);
                body.m_pBodyParts.Add(entity);
                entity.SetParent(owner);
            }

            body.m_TextPreamble = multipartReader.TextPreamble;
            body.m_TextEpilogue = multipartReader.TextEpilogue;

            body.BodyParts.SetModified(false);
        }
        /// <summary>
        /// Creates text/html MIME entity.
        /// </summary>
        /// <param name="transferEncoding">Content transfer encoding.</param>
        /// <param name="charset">Charset to use to encode text. If not sure, utf-8 is recommended.</param>
        /// <param name="text">Text.</param>
        /// <returns>Returns created entity.</returns>
        /// <exception cref="ArgumentNullException">Is raised when <b>transferEncoding</b>, <b>charset</b> or <b>text</b> is null reference.</exception>
        /// <exception cref="NotSupportedException">Is raised when body contains not supported Content-Transfer-Encoding.</exception>
        public static MIME_Entity CreateEntity_Text_Html(string transferEncoding, Encoding charset, string text)
        {
            if (transferEncoding == null)
            {
                throw new ArgumentNullException("transferEncoding");
            }
            if (charset == null)
            {
                throw new ArgumentNullException("charset");
            }
            if (text == null)
            {
                throw new ArgumentNullException("text");
            }

            MIME_Entity retVal = new MIME_Entity();
            MIME_b_Text body   = new MIME_b_Text(MIME_MediaTypes.Text.html);

            retVal.Body = body;
            body.SetText(transferEncoding, charset, text);

            return(retVal);
        }
Example #37
0
        /// <summary>
        /// Creates attachment entity.
        /// </summary>
        /// <param name="file">File name with optional path.</param>
        /// <returns>Returns created attachment entity.</returns>
        /// <exception cref="ArgumentNullException">Is raised when <b>file</b> is null reference.</exception>
        public static MIME_Entity CreateAttachment(string file)
        {
            if(file == null){
                throw new ArgumentNullException("file");
            }

            MIME_Entity retVal = new MIME_Entity();
            MIME_b_Application body = new MIME_b_Application(MIME_MediaTypes.Application.octet_stream);
            retVal.Body = body;
            body.SetBodyDataFromFile(file,MIME_TransferEncodings.Base64);
            retVal.ContentType.Param_Name = Path.GetFileName(file);

            FileInfo fileInfo = new FileInfo(file);
            MIME_h_ContentDisposition disposition = new MIME_h_ContentDisposition(MIME_DispositionTypes.Attachment);
            disposition.Param_FileName         = Path.GetFileName(file);
            disposition.Param_Size             = fileInfo.Length;
            disposition.Param_CreationDate     = fileInfo.CreationTime;
            disposition.Param_ModificationDate = fileInfo.LastWriteTime;
            disposition.Param_ReadDate         = fileInfo.LastAccessTime;
            retVal.ContentDisposition = disposition;

            return retVal;
        }
        // TODO:
        //public MIME_Entity GetEntityByPartsSpecifier(string partsSpecifier)


        /// <summary>
        /// Converts message to multipart/signed message.
        /// </summary>
        /// <param name="signerCert">>Signer certificate</param>
        /// <exception cref="ArgumentNullException">Is raised when <b>signerCert</b> is null reference.</exception>
        /// <exception cref="InvalidOperationException">Is raised when this method is called for already signed message.</exception>
        public void ConvertToMultipartSigned(X509Certificate2 signerCert)
        {
            if (signerCert == null)
            {
                throw new ArgumentNullException("signerCert");
            }
            if (this.IsSigned)
            {
                throw new InvalidOperationException("Message is already signed.");
            }

            MIME_Entity msgEntity = new MIME_Entity();

            msgEntity.Body = this.Body;
            msgEntity.ContentDisposition      = this.ContentDisposition;
            msgEntity.ContentTransferEncoding = this.ContentTransferEncoding;
            this.ContentTransferEncoding      = null;

            MIME_b_MultipartSigned multipartSigned = new MIME_b_MultipartSigned();

            this.Body = multipartSigned;
            multipartSigned.SetCertificate(signerCert);
            multipartSigned.BodyParts.Add(msgEntity);
        }
Example #39
0
        /// <summary>
        /// Parses body from the specified stream
        /// </summary>
        /// <param name="owner">Owner MIME entity.</param>
        /// <param name="defaultContentType">Default content-type for this body.</param>
        /// <param name="stream">Stream from where to read body.</param>
        /// <returns>Returns parsed body.</returns>
        /// <exception cref="ArgumentNullException">Is raised when <b>stream</b>, <b>defaultContentType</b> or <b>strean</b> is null reference.</exception>
        /// <exception cref="ParseException">Is raised when any parsing errors.</exception>
        protected static new MIME_b Parse(MIME_Entity owner,MIME_h_ContentType defaultContentType,SmartStream stream)
        {
            if(owner == null){
                throw new ArgumentNullException("owner");
            }
            if(defaultContentType == null){
                throw new ArgumentNullException("defaultContentType");
            }
            if(stream == null){
                throw new ArgumentNullException("stream");
            }

            MIME_b_Unknown retVal = null;
            if(owner.ContentType != null){
                retVal = new MIME_b_Unknown(owner.ContentType.TypeWithSubype);
            }
            else{
                retVal = new MIME_b_Unknown(defaultContentType.TypeWithSubype);
            }

            Net_Utils.StreamCopy(stream,retVal.EncodedStream,32000);

            return retVal;
        }
        /// <summary>
        /// Parses body from the specified stream
        /// </summary>
        /// <param name="owner">Owner MIME entity.</param>
        /// <param name="defaultContentType">Default content-type for this body.</param>
        /// <param name="stream">Stream from where to read body.</param>
        /// <returns>Returns parsed body.</returns>
        /// <exception cref="ArgumentNullException">Is raised when <b>stream</b>, <b>defaultContentType</b> or <b>strean</b> is null reference.</exception>
        /// <exception cref="ParseException">Is raised when any parsing errors.</exception>
        protected static new MIME_b Parse(MIME_Entity owner,MIME_h_ContentType defaultContentType,SmartStream stream)
        {
            if(owner == null){
                throw new ArgumentNullException("owner");
            }
            if(defaultContentType == null){
                throw new ArgumentNullException("defaultContentType");
            }
            if(stream == null){
                throw new ArgumentNullException("stream");
            }

            MIME_b_Application retVal = null;
            if(owner.ContentType != null){
                retVal = new MIME_b_Application(owner.ContentType.TypeWithSubtype);
            }
            else{
                retVal = new MIME_b_Application(defaultContentType.TypeWithSubtype);
            }

            Net_Utils.StreamCopy(stream,retVal.EncodedStream,stream.LineBufferSize);

            return retVal;
        }
        /// <summary>
        /// Parses body from the specified stream
        /// </summary>
        /// <param name="owner">Owner MIME entity.</param>
        /// <param name="defaultContentType">Default content-type for this body.</param>
        /// <param name="stream">Stream from where to read body.</param>
        /// <returns>Returns parsed body.</returns>
        /// <exception cref="ArgumentNullException">Is raised when <b>stream</b>, <b>defaultContentType</b> or <b>stream</b> is null reference.</exception>
        /// <exception cref="ParseException">Is raised when any parsing errors.</exception>
        protected static new MIME_b Parse(MIME_Entity owner, MIME_h_ContentType defaultContentType, SmartStream stream)
        {
            if (owner == null)
            {
                throw new ArgumentNullException("owner");
            }
            if (defaultContentType == null)
            {
                throw new ArgumentNullException("defaultContentType");
            }
            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }

            MIME_b_MessageDeliveryStatus retVal = new MIME_b_MessageDeliveryStatus();

            //Pare per-message fields.
            retVal.m_pMessageFields.Parse(stream);
            // Parse per-recipient fields.
            while (true)
            {
                MIME_h_Collection recipientFields = new MIME_h_Collection(new MIME_h_Provider());
                recipientFields.Parse(stream);
                if (recipientFields.Count == 0)
                {
                    break;
                }
                else
                {
                    retVal.m_pRecipientBlocks.Add(recipientFields);
                }
            }

            return(retVal);
        }
        /// <summary>
        /// Gets if the collection contains specified MIME entity.
        /// </summary>
        /// <param name="entity">MIME entity.</param>
        /// <returns>Returns true if the specified MIME entity exists in the collection, otherwise false.</returns>
        /// <exception cref="ArgumentNullException">Is raised when <b>entity</b> is null.</exception>
        public bool Contains(MIME_Entity entity)
        {
            if(entity == null){
                throw new ArgumentNullException("entity");
            }

            return m_pCollection.Contains(entity);
        }
        /// <summary>
        /// Default constructor.
        /// </summary>
        /// <param name="owner">Owner MIME entity.</param>
        /// <exception cref="ArgumentNullException">Is raised when <b>owner</b> is null.</exception>
        internal MIME_MultipartBody(MIME_Entity owner) : base(owner)
        {
            m_Boundary = owner.ContentType.Param_Boundary;

            m_pParts = new MIME_EntityCollection();
        }
 /// <summary>
 /// Parses MIME entity body from the specified reader.
 /// </summary>
 /// <param name="reader">Body reader from where to parse body.</param>
 /// <param name="owner">Specifies if body will be stream owner.</param>
 /// <returns>Returns true if this is last boundary in the message or in multipart "body parts".</returns>
 internal override void ParseFromReader(LineReader reader,bool owner)
 {
     // For multipart we need todo new limiting(limits to specified boundary) reader.
     _MIME_MultipartReader r = new _MIME_MultipartReader(reader,m_Boundary);
     while(r.Next()){
         MIME_Entity bodyPart = new MIME_Entity();                
         bodyPart.Parse(r,owner);
         m_pParts.Add(bodyPart);                
     }
 }
Example #45
0
        /// <summary>
        /// Stores MIME entity body to the specified stream.
        /// </summary>
        /// <param name="stream">Stream where to store body data.</param>
        /// <param name="headerWordEncoder">Header 8-bit words ecnoder. Value null means that words are not encoded.</param>
        /// <param name="headerParmetersCharset">Charset to use to encode 8-bit header parameters. Value null means parameters not encoded.</param>
        /// <param name="headerReencode">If true always specified encoding is used for header. If false and header field value not modified,
        /// original encoding is kept.</param>
        /// <exception cref="ArgumentNullException">Is raised when <b>stream</b> is null reference.</exception>
        internal protected override void ToStream(Stream stream, MIME_Encoding_EncodedWord headerWordEncoder, Encoding headerParmetersCharset, bool headerReencode)
        {
            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }

            /* RFC 2046 5.1.1.
             *  NOTE:  The CRLF preceding the boundary delimiter line is conceptually
             *  attached to the boundary so that it is possible to have a part that
             *  does not end with a CRLF (line  break).
             *
             *  dash-boundary := "--" boundary
             *
             *  multipart-body := [preamble CRLF]
             *                    dash-boundary transport-padding CRLF
             *                    body-part *encapsulation
             *                    close-delimiter transport-padding
             *                    [CRLF epilogue]
             *
             *  encapsulation := delimiter transport-padding
             *                   CRLF body-part
             *
             *  delimiter := CRLF dash-boundary
             *
             *  close-delimiter := delimiter "--"
             */

            // Set "preamble" text if any.
            if (!string.IsNullOrEmpty(m_TextPreamble))
            {
                if (m_TextPreamble.EndsWith("\r\n"))
                {
                    byte[] preableBytes = Encoding.UTF8.GetBytes(m_TextPreamble);
                    stream.Write(preableBytes, 0, preableBytes.Length);
                }
                else
                {
                    byte[] preableBytes = Encoding.UTF8.GetBytes(m_TextPreamble + "\r\n");
                    stream.Write(preableBytes, 0, preableBytes.Length);
                }
            }

            for (int i = 0; i < m_pBodyParts.Count; i++)
            {
                MIME_Entity bodyPart = m_pBodyParts[i];

                // First boundary has no preceeding CRLF.
                if (i == 0)
                {
                    byte[] bStart = Encoding.UTF8.GetBytes("--" + this.Entity.ContentType.Param_Boundary + "\r\n");
                    stream.Write(bStart, 0, bStart.Length);
                }
                // Boundaries > 1.
                else
                {
                    byte[] bStart = Encoding.UTF8.GetBytes("\r\n--" + this.Entity.ContentType.Param_Boundary + "\r\n");
                    stream.Write(bStart, 0, bStart.Length);
                }

                bodyPart.ToStream(stream, headerWordEncoder, headerParmetersCharset, headerReencode);

                // Last body part, close boundary.
                if (i == (m_pBodyParts.Count - 1))
                {
                    byte[] bEnd = Encoding.UTF8.GetBytes("\r\n--" + this.Entity.ContentType.Param_Boundary + "--");
                    stream.Write(bEnd, 0, bEnd.Length);
                }
            }

            // Set "epilogoue" text if any.
            if (!string.IsNullOrEmpty(m_TextEpilogue))
            {
                if (m_TextEpilogue.StartsWith("\r\n"))
                {
                    byte[] epilogoueBytes = Encoding.UTF8.GetBytes(m_TextEpilogue);
                    stream.Write(epilogoueBytes, 0, epilogoueBytes.Length);
                }
                else
                {
                    byte[] epilogoueBytes = Encoding.UTF8.GetBytes("\r\n" + m_TextEpilogue);
                    stream.Write(epilogoueBytes, 0, epilogoueBytes.Length);
                }
            }
        }
        /// <summary>
        /// Parses MIME entity body from specified stream.
        /// </summary>
        /// <param name="owner">Owner MIME entity.</param>
        /// <param name="stream">Stream from where to parse entity body.</param>
        /// <param name="defaultContentType">Default content type.</param>
        /// <returns>Returns parsed body.</returns>
        /// <exception cref="ArgumentNullException">Is raised when <b>owner</b>, <b>strean</b> or <b>defaultContentType</b> is null reference.</exception>
        /// <exception cref="ParseException">Is raised when header field parsing errors.</exception>
        public MIME_b Parse(MIME_Entity owner, SmartStream stream, MIME_h_ContentType defaultContentType)
        {
            if (owner == null)
            {
                throw new ArgumentNullException("owner");
            }
            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }
            if (defaultContentType == null)
            {
                throw new ArgumentNullException("defaultContentType");
            }

            string mediaType = defaultContentType.TypeWithSubtype;

            try
            {
                if (owner.ContentType != null)
                {
                    mediaType = owner.ContentType.TypeWithSubtype;
                }
            }
            catch
            {
                // Do nothing, content will be MIME_b_Unknown.
                mediaType = "unknown/unknown";
            }

            Type bodyType = null;

            // We have exact body provider for specified mediaType.
            if (m_pBodyTypes.ContainsKey(mediaType))
            {
                bodyType = m_pBodyTypes[mediaType];
            }
            // Use default mediaType.
            else
            {
                // Registered list of mediaTypes are available: http://www.iana.org/assignments/media-types/.

                string mediaRootType = mediaType.Split('/')[0].ToLowerInvariant();
                if (mediaRootType == "application")
                {
                    bodyType = typeof(MIME_b_Application);
                }
                else if (mediaRootType == "audio")
                {
                    bodyType = typeof(MIME_b_Audio);
                }
                else if (mediaRootType == "image")
                {
                    bodyType = typeof(MIME_b_Image);
                }
                else if (mediaRootType == "message")
                {
                    bodyType = typeof(MIME_b_Message);
                }
                else if (mediaRootType == "multipart")
                {
                    bodyType = typeof(MIME_b_Multipart);
                }
                else if (mediaRootType == "text")
                {
                    bodyType = typeof(MIME_b_Text);
                }
                else if (mediaRootType == "video")
                {
                    bodyType = typeof(MIME_b_Video);
                }
                else
                {
                    bodyType = typeof(MIME_b_Unknown);
                }
            }

            return((MIME_b)System.Reflection.IntrospectionExtensions.GetTypeInfo(bodyType)
                   .GetMethod("Parse", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.FlattenHierarchy).Invoke(null, new object[] { owner, defaultContentType, stream }));
        }
		/// <summary>
		/// Constructs specified entity and it's childentities bodystructure string.
		/// </summary>
		/// <param name="entity">Mime entity.</param>
		/// <param name="bodystructure">Specifies if to construct BODY or BODYSTRUCTURE.</param>
		/// <returns></returns>
		private string ConstructParts(MIME_Entity entity,bool bodystructure)
		{
			/* RFC 3501 7.4.2 BODYSTRUCTURE
							  BODY A form of BODYSTRUCTURE without extension data.
			  
				A parenthesized list that describes the [MIME-IMB] body
				structure of a message.  This is computed by the server by
				parsing the [MIME-IMB] header fields, defaulting various fields
				as necessary.

				For example, a simple text message of 48 lines and 2279 octets
				can have a body structure of: ("TEXT" "PLAIN" ("CHARSET"
				"US-ASCII") NIL NIL "7BIT" 2279 48)

				Multiple parts are indicated by parenthesis nesting.  Instead
				of a body type as the first element of the parenthesized list,
				there is a sequence of one or more nested body structures.  The
				second element of the parenthesized list is the multipart
				subtype (mixed, digest, parallel, alternative, etc.).
					
				For example, a two part message consisting of a text and a
				BASE64-encoded text attachment can have a body structure of:
				(("TEXT" "PLAIN" ("CHARSET" "US-ASCII") NIL NIL "7BIT" 1152
				23)("TEXT" "PLAIN" ("CHARSET" "US-ASCII" "NAME" "cc.diff")
				"<*****@*****.**>" "Compiler diff"
				"BASE64" 4554 73) "MIXED")

				Extension data follows the multipart subtype.  Extension data
				is never returned with the BODY fetch, but can be returned with
				a BODYSTRUCTURE fetch.  Extension data, if present, MUST be in
				the defined order.  The extension data of a multipart body part
				are in the following order:

				body parameter parenthesized list
					A parenthesized list of attribute/value pairs [e.g., ("foo"
					"bar" "baz" "rag") where "bar" is the value of "foo", and
					"rag" is the value of "baz"] as defined in [MIME-IMB].

				body disposition
					A parenthesized list, consisting of a disposition type
					string, followed by a parenthesized list of disposition
					attribute/value pairs as defined in [DISPOSITION].

				body language
					A string or parenthesized list giving the body language
					value as defined in [LANGUAGE-TAGS].

				body location
					A string list giving the body content URI as defined in [LOCATION].

				Any following extension data are not yet defined in this
				version of the protocol.  Such extension data can consist of
				zero or more NILs, strings, numbers, or potentially nested
				parenthesized lists of such data.  Client implementations that
				do a BODYSTRUCTURE fetch MUST be prepared to accept such
				extension data.  Server implementations MUST NOT send such
				extension data until it has been defined by a revision of this
				protocol.

				The basic fields of a non-multipart body part are in the
				following order:

				body type
					A string giving the content media type name as defined in [MIME-IMB].
				
				body subtype
					 A string giving the content subtype name as defined in [MIME-IMB].

				body parameter parenthesized list
					A parenthesized list of attribute/value pairs [e.g., ("foo"
					"bar" "baz" "rag") where "bar" is the value of "foo" and
					"rag" is the value of "baz"] as defined in [MIME-IMB].

				body id
					A string giving the content id as defined in [MIME-IMB].

				body description
					A string giving the content description as defined in [MIME-IMB].

				body encoding
					A string giving the content transfer encoding as defined in	[MIME-IMB].

				body size
					A number giving the size of the body in octets.  Note that
					this size is the size in its transfer encoding and not the
					resulting size after any decoding.

				A body type of type MESSAGE and subtype RFC822 contains,
				immediately after the basic fields, the envelope structure,
				body structure, and size in text lines of the encapsulated
				message.

				A body type of type TEXT contains, immediately after the basic
				fields, the size of the body in text lines.  Note that this
				size is the size in its content transfer encoding and not the
				resulting size after any decoding.

				Extension data follows the basic fields and the type-specific
				fields listed above.  Extension data is never returned with the
				BODY fetch, but can be returned with a BODYSTRUCTURE fetch.
				Extension data, if present, MUST be in the defined order.

				The extension data of a non-multipart body part are in the
				following order:

				body MD5
					A string giving the body MD5 value as defined in [MD5].
					
				body disposition
					A parenthesized list with the same content and function as
					the body disposition for a multipart body part.

				body language
					A string or parenthesized list giving the body language
					value as defined in [LANGUAGE-TAGS].

				body location
					A string list giving the body content URI as defined in [LOCATION].

				Any following extension data are not yet defined in this
				version of the protocol, and would be as described above under
				multipart extension data.
			
			
				// We don't construct extention fields like rfc says:
					Server implementations MUST NOT send such
					extension data until it has been defined by a revision of this
					protocol.
			
										
				contentTypeMainMediaType - Example: 'TEXT'
				contentTypeSubMediaType  - Example: 'PLAIN'
				conentTypeParameters     - Example: '("CHARSET" "iso-8859-1" ...)'
				contentID                - Content-ID: header field value.
				contentDescription       - Content-Description: header field value.
				contentEncoding          - Content-Transfer-Encoding: header field value.
				contentSize              - mimeEntity ENCODED data size
				[envelope]               - NOTE: included only if contentType = "message" !!!
				[contentLines]           - number of ENCODED data lines. NOTE: included only if contentType = "text" !!!
									   			
				// Basic fields for multipart
				(nestedMimeEntries) contentTypeSubMediaType
												
				// Basic fields for non-multipart
				contentTypeMainMediaType contentTypeSubMediaType (conentTypeParameters) contentID contentDescription contentEncoding contentSize [envelope] [contentLine]

			*/

            MIME_Encoding_EncodedWord wordEncoder = new MIME_Encoding_EncodedWord(MIME_EncodedWordEncoding.B,Encoding.UTF8);
            wordEncoder.Split = false;

			StringBuilder retVal = new StringBuilder();
			// Multipart message
			if(entity.Body is MIME_b_Multipart){
				retVal.Append("(");

				// Construct child entities.
				foreach(MIME_Entity childEntity in ((MIME_b_Multipart)entity.Body).BodyParts){
					// Construct child entity. This can be multipart or non multipart.
					retVal.Append(ConstructParts(childEntity,bodystructure));
				}
			
				// Add contentTypeSubMediaType
                if(entity.ContentType != null && entity.ContentType.SubType != null){
                    retVal.Append(" \"" + entity.ContentType.SubType + "\"");
                }
                else{
                    retVal.Append(" NIL");
                }

				retVal.Append(")");
			}
			// Single part message
			else{
				retVal.Append("(");

				// NOTE: all header fields and parameters must in ENCODED form !!!

				// Add contentTypeMainMediaType
				if(entity.ContentType != null && entity.ContentType.Type != null){
					retVal.Append("\"" + entity.ContentType.Type + "\"");
				}
				else{
					retVal.Append("NIL");
				}

                // Add contentTypeSubMediaType
                if(entity.ContentType != null && entity.ContentType.SubType != null){
                    retVal.Append(" \"" + entity.ContentType.SubType + "\"");
                }
                else{
                    retVal.Append(" NIL");
                }

				// conentTypeParameters - Syntax: {("name" SP "value" *(SP "name" SP "value"))}
				if(entity.ContentType != null){
                    if(entity.ContentType.Parameters.Count > 0){
                        retVal.Append(" (");
                        bool first = true;
                        foreach(MIME_h_Parameter parameter in entity.ContentType.Parameters){
                            // For the first item, don't add SP.
                            if(first){
                                first = false;
                            }
                            else{
                                retVal.Append(" ");
                            }

                            retVal.Append("\"" + parameter.Name + "\" \"" + wordEncoder.Encode(parameter.Value) + "\"");
                        }
                        retVal.Append(")");
                    }
                    else{
                        retVal.Append(" NIL");
                    }
				}
				else{
					retVal.Append(" NIL");
				}

				// contentID
				string contentID = entity.ContentID;
				if(contentID != null){
					retVal.Append(" \"" + wordEncoder.Encode(contentID) + "\""); 
				}
				else{
					retVal.Append(" NIL");
				}

				// contentDescription
				string contentDescription = entity.ContentDescription;
				if(contentDescription != null){
					retVal.Append(" \"" + wordEncoder.Encode(contentDescription) + "\""); 
				}
				else{
					retVal.Append(" NIL");
				}

				// contentEncoding
				if(entity.ContentTransferEncoding != null){
					retVal.Append(" \"" + wordEncoder.Encode(entity.ContentTransferEncoding) + "\""); 
				}
				else{
					// If not specified, then must be 7bit.
					retVal.Append(" \"7bit\"");
				}

				// contentSize
				if(entity.Body is MIME_b_SinglepartBase){                    
					retVal.Append(" " + ((MIME_b_SinglepartBase)entity.Body).EncodedData.Length.ToString());
				}
				else{
					retVal.Append(" 0");
				}

				// envelope ---> FOR ContentType: message/rfc822 ONLY ###
				if(entity.Body is MIME_b_MessageRfc822){                    
					retVal.Append(" " + IMAP_t_Fetch_r_i_Envelope.ConstructEnvelope(((MIME_b_MessageRfc822)entity.Body).Message));

                    // TODO: BODYSTRUCTURE,LINES
				}

				// contentLines ---> FOR ContentType: text/xxx ONLY ###
				if(entity.Body is MIME_b_Text){                    
				    long lineCount = 0;
					StreamLineReader r = new StreamLineReader(new MemoryStream(((MIME_b_SinglepartBase)entity.Body).EncodedData));
					byte[] line = r.ReadLine();
					while(line != null){
						lineCount++;

						line = r.ReadLine();
					}
						
					retVal.Append(" " + lineCount.ToString());
				}

				retVal.Append(")");
			}

			return retVal.ToString();
		}
        /// <summary>
        /// Creates attachment entity.
        /// </summary>
        /// <param name="stream">Attachment data stream. Data is read from stream current position.</param>
        /// <param name="fileName">File name.</param>
        /// <returns>Returns created attachment entity.</returns>
        /// <exception cref="ArgumentNullException">Is raised when <b>stream</b> or <b>fileName</b> is null reference.</exception>
        public static MIME_Entity CreateAttachment(Stream stream,string fileName)
        {
            if(stream == null){
                throw new ArgumentNullException("stream");
            }
            if(fileName == null){
                throw new ArgumentNullException("fileName");
            }

            long fileSize = stream.CanSeek ? (stream.Length - stream.Position) : -1;

            MIME_Entity retVal = new MIME_Entity();
            MIME_b_Application body = new MIME_b_Application(MIME_MediaTypes.Application.octet_stream);
            retVal.Body = body;
            body.SetData(stream,MIME_TransferEncodings.Base64);
            retVal.ContentType.Param_Name = Path.GetFileName(fileName);

            MIME_h_ContentDisposition disposition = new MIME_h_ContentDisposition(MIME_DispositionTypes.Attachment);
            disposition.Param_FileName         = Path.GetFileName(fileName);
            disposition.Param_Size             = fileSize;
            //disposition.Param_CreationDate     = fileInfo.CreationTime;
            //disposition.Param_ModificationDate = fileInfo.LastWriteTime;
            //disposition.Param_ReadDate         = fileInfo.LastAccessTime;
            retVal.ContentDisposition = disposition;

            return retVal;
        }
Example #49
0
        /// <summary>
        /// Generates message parsing failed message.
        /// </summary>
        /// <param name="message">Message stream.</param>
        /// <returns>Returns message parsing failed message.</returns>
        /// <exception cref="ArgumentNullException">Is raised when <b>message</b> is null reference.</exception>
        public static Mail_Message GenerateBadMessage(Stream message)
        {
            if(message == null){
                throw new ArgumentNullException("message");
            }

            Mail_Message msg = new Mail_Message();
            msg.MimeVersion = "1.0";
            msg.MessageID = MIME_Utils.CreateMessageID();
            msg.Date = DateTime.Now;
            msg.From = new Mail_t_MailboxList();
            msg.From.Add(new Mail_t_Mailbox("system","system"));
            msg.To = new Mail_t_AddressList();
            msg.To.Add(new Mail_t_Mailbox("system","system"));
            msg.Subject = "[BAD MESSAGE] Bad message, message parsing failed !";

            //--- multipart/mixed -------------------------------------------------------------------------------------------------
            MIME_h_ContentType contentType_multipartMixed = new MIME_h_ContentType(MIME_MediaTypes.Multipart.mixed);
            contentType_multipartMixed.Param_Boundary = Guid.NewGuid().ToString().Replace('-','.');
            MIME_b_MultipartMixed multipartMixed = new MIME_b_MultipartMixed(contentType_multipartMixed);
            msg.Body = multipartMixed;

                //--- text/plain ---------------------------------------------------------------------------------------------------
                MIME_Entity entity_text_plain = new MIME_Entity();
                MIME_b_Text text_plain = new MIME_b_Text(MIME_MediaTypes.Text.plain);
                entity_text_plain.Body = text_plain;
                text_plain.SetText(MIME_TransferEncodings.QuotedPrintable,Encoding.UTF8,"NOTE: Bad message, message parsing failed.\r\n\r\nOriginal message attached as 'data.eml'\r\n");
                multipartMixed.BodyParts.Add(entity_text_plain);

                //--- application/octet-stream --------------------------------------------------------------------------------------
                MIME_Entity entity_application_octet_stream = new MIME_Entity();
                entity_application_octet_stream.ContentDisposition = new MIME_h_ContentDisposition("attachment");
                entity_application_octet_stream.ContentDisposition.Param_FileName = "data.eml";
                MIME_b_Application application_octet_stream = new MIME_b_Application(MIME_MediaTypes.Application.octet_stream);
                entity_application_octet_stream.Body = application_octet_stream;
                application_octet_stream.SetData(message,"base64");
                multipartMixed.BodyParts.Add(entity_application_octet_stream);

            return msg;
        }
        /// <summary>
        /// Default constructor.
        /// </summary>
        /// <param name="owner">Owner MIME entity.</param>
        /// <exception cref="ArgumentNullException">Is raised when <b>owner</b> is null.</exception>
        internal MIME_MultipartBody(MIME_Entity owner) : base(owner)
        {
            m_Boundary = owner.ContentType.Param_Boundary;

            m_pParts = new MIME_EntityCollection();
        }
Example #51
0
		/// <summary>
		/// Stores message to specified folder.
		/// </summary>
        /// <param name="accessingUser">User who accesses this method. 
        /// User needs r permission to call this method or Exception is thrown. 
        /// There is special user 'system' for which permission check is skipped.</param>
        /// <param name="folderOwnerUser">User who's folder it is.</param>
        /// <param name="folder">Folder where to store message. For example: Inbox,Public Folders/Documnets .</param>
		/// <param name="msgStream">Stream where message has stored. Stream position must be at the beginning of the message.</param>
		/// <param name="date">Recieve date.</param>
		/// <param name="flags">Message flags.</param>
		public void StoreMessage(string accessingUser,string folderOwnerUser,string folder,Stream msgStream,DateTime date,IMAP_MessageFlags flags)
		{
            /* Implementation notes:
                *) Validate values. Throw ArgumnetExcetion if invalid values.
                *) Ensure that user exists.
                *) Normalize folder. Remove '/' from folder start and end, ... .
                *) Do Shared Folders mapping.
                *) Ensure that folder exists. Throw Exception if don't.
                *) See if user has sufficient permissions. User requires 'p' or 'i' permission.
                    There is builtin user system, skip ACL for it.
                *) Store message.
            */

            //--- Validate values -------------------//
            ArgsValidator.ValidateUserName(folderOwnerUser);
            ArgsValidator.ValidateFolder(folder);
            ArgsValidator.ValidateNotNull(msgStream);
            //---------------------------------------//

            // Ensure that user exists.
            if(!UserExists(folderOwnerUser)){
                throw new Exception("User '" + folderOwnerUser + "' doesn't exist !");
            }

            // Normalize folder. Remove '/' from folder start and end.
            folder = API_Utlis.NormalizeFolder(folder);

            // Do Shared Folders mapping.
            string originalFolder = folder;
            SharedFolderMapInfo mappedFolder = MapSharedFolder(originalFolder);
            if(mappedFolder.IsSharedFolder){
                folderOwnerUser = mappedFolder.FolderOnwer;
                folder = mappedFolder.Folder;

                if(folderOwnerUser == "" || folder == ""){
                    throw new ArgumentException("Specified root folder '" + originalFolder + "' isn't accessible !");
                }
            }

            // Ensure that folder exists. Throw Exception if don't.
            if(!FolderExists(folderOwnerUser + "/" + folder)){
                throw new Exception("Folder '" + folder + "' doesn't exist !");
            }

            // See if user has sufficient permissions. User requires 'p' or 'i' permission.
            //  There is builtin user system, skip ACL for it.
            if(accessingUser.ToLower() != "system"){
                IMAP_ACL_Flags acl = GetUserACL(folderOwnerUser,folder,accessingUser);
                if((acl & IMAP_ACL_Flags.p) == 0 && (acl & IMAP_ACL_Flags.i) == 0){
                    throw new InsufficientPermissionsException("Insufficient permissions for folder '" + accessingUser + "/" + folder + "' !");
                }
            }

            //--- Store message
            MemoryStream msgMemStream = new MemoryStream();
            Net_Utils.StreamCopy(msgStream,msgMemStream,32000);
	        byte[] messageData = msgMemStream.ToArray();
            byte[] topLines = GetTopLines(new MemoryStream(messageData),50);
            Mail_Message message = null;
            try{
                msgStream.Position = 0;
                message = Mail_Message.ParseFromByte(messageData);
            }
            catch(Exception x){
                message = new Mail_Message();
                message.MimeVersion = "1.0";
                message.MessageID = MIME_Utils.CreateMessageID();
                message.Date = DateTime.Now;
                message.From = new Mail_t_MailboxList();
                message.From.Add(new Mail_t_Mailbox("system","system"));
                message.To = new Mail_t_AddressList();
                message.To.Add(new Mail_t_Mailbox("system","system"));
                message.Subject = "[BAD MESSAGE] Bad message, message parsing failed !";

                //--- multipart/mixed -------------------------------------------------------------------------------------------------
                MIME_h_ContentType contentType_multipartMixed = new MIME_h_ContentType(MIME_MediaTypes.Multipart.mixed);
                contentType_multipartMixed.Param_Boundary = Guid.NewGuid().ToString().Replace('-','.');
                MIME_b_MultipartMixed multipartMixed = new MIME_b_MultipartMixed(contentType_multipartMixed);
                message.Body = multipartMixed;

                    //--- text/plain ---------------------------------------------------------------------------------------------------
                    MIME_Entity entity_text_plain = new MIME_Entity();
                    MIME_b_Text text_plain = new MIME_b_Text(MIME_MediaTypes.Text.plain);
                    entity_text_plain.Body = text_plain;
                    text_plain.SetText(MIME_TransferEncodings.QuotedPrintable,Encoding.UTF8,"NOTE: Bad message, message parsing failed.\r\n\r\n");
                    multipartMixed.BodyParts.Add(entity_text_plain);
            }
            byte[] envelope = System.Text.Encoding.Default.GetBytes(IMAP_Envelope.ConstructEnvelope(message));
            byte[] body     = System.Text.Encoding.Default.GetBytes(IMAP_BODY.ConstructBodyStructure(message,false));

			using(WSqlCommand sqlCmd = new WSqlCommand(m_ConStr,"lspr_StoreMessage")){
				sqlCmd.AddParameter("_userName"     ,NpgsqlDbType.Varchar   ,folderOwnerUser);
				sqlCmd.AddParameter("_folder"       ,NpgsqlDbType.Varchar   ,folder);
				sqlCmd.AddParameter("_messageID"    ,NpgsqlDbType.Varchar   ,Guid.NewGuid().ToString());
				sqlCmd.AddParameter("_size"         ,NpgsqlDbType.Integer   ,messageData.Length);
				sqlCmd.AddParameter("_messageFlags" ,NpgsqlDbType.Integer   ,(int)flags);
				sqlCmd.AddParameter("_date"         ,NpgsqlDbType.Timestamp ,date);
				sqlCmd.AddParameter("_topLines"     ,NpgsqlDbType.Bytea     ,topLines);
				sqlCmd.AddParameter("_data"         ,NpgsqlDbType.Bytea     ,messageData);
                sqlCmd.AddParameter("_imapEnvelope" ,NpgsqlDbType.Bytea     ,envelope);
                sqlCmd.AddParameter("_imapBody"     ,NpgsqlDbType.Bytea     ,body);

				DataSet ds = sqlCmd.Execute();
			}
		}
        /// <summary>
        /// Internal body parsing.
        /// </summary>
        /// <param name="owner">Owner MIME entity.</param>
        /// <param name="mediaType">MIME media type. For example: text/plain.</param>
        /// <param name="stream">Stream from where to read body.</param>
        /// <param name="body">Multipart body instance.</param>
        /// <exception cref="ArgumentNullException">Is raised when <b>stream</b>, <b>mediaType</b>, <b>stream</b> or <b>body</b> is null reference.</exception>
        /// <exception cref="ParseException">Is raised when any parsing errors.</exception>
        protected static void ParseInternal(MIME_Entity owner,string mediaType,SmartStream stream,MIME_b_Multipart body)
        {
            if(owner == null){
                throw new ArgumentNullException("owner");
            }
            if(mediaType == null){
                throw new ArgumentNullException("mediaType");
            }
            if(stream == null){
                throw new ArgumentNullException("stream");
            }
            if(owner.ContentType == null || owner.ContentType.Param_Boundary == null){
                throw new ParseException("Multipart entity has not required 'boundary' parameter.");
            }
            if(body == null){
                throw new ArgumentNullException("body");
            }

            _MultipartReader multipartReader = new _MultipartReader(stream,owner.ContentType.Param_Boundary);       
            while(multipartReader.Next()){
                MIME_Entity entity = new MIME_Entity();
                entity.Parse(new SmartStream(multipartReader,false),Encoding.UTF8,body.DefaultBodyPartContentType);
                body.m_pBodyParts.Add(entity);
                entity.SetParent(owner);
            }

            body.m_TextPreamble = multipartReader.TextPreamble;
            body.m_TextEpilogue = multipartReader.TextEpilogue;

            body.BodyParts.SetModified(false);
        }
Example #53
0
 /// <summary>
 /// Sets MIME entity parent entity.
 /// </summary>
 /// <param name="parent">Parent entity.</param>
 internal void SetParent(MIME_Entity parent)
 {
     m_pParent = parent;
 }
Example #54
0
 /// <summary>
 /// Sets body parent.
 /// </summary>
 /// <param name="entity">Owner entity.</param>
 internal void SetParent(MIME_Entity entity)
 {
     m_pEntity = entity;
 }
        public void Send(ChannelMessage message)
        {
            var creds = CredentialsProvider.GetCredentials().ToNetworkCredential();

            Mail_Message msg = new Mail_Message();

            msg.MimeVersion = "1.0";
            msg.MessageID = MIME_Utils.CreateMessageID();
            msg.Subject = message.Context;
            msg.From = message.From.ToMailBoxList();
            msg.ReplyTo = message.ReturnTo == null ?
                message.From.ToAddressList() : message.ReturnTo.ToAddressList();

            if (String.IsNullOrEmpty(message.InReplyTo) == false)
                msg.InReplyTo = message.InReplyTo;

            msg.To = new Mail_t_AddressList();
            foreach (var address in message.To)
                msg.To.Add(address.ToMailBox());

            msg.Cc = new Mail_t_AddressList();
            foreach (var address in message.CC)
                msg.Cc.Add(address.ToMailBox());

            //--- multipart/mixed -------------------------------------------------------------------------------------------------
            MIME_h_ContentType contentType_multipartMixed = new MIME_h_ContentType(MIME_MediaTypes.Multipart.mixed);
            contentType_multipartMixed.Param_Boundary = Guid.NewGuid().ToString().Replace('-', '.');
            MIME_b_MultipartMixed multipartMixed = new MIME_b_MultipartMixed(contentType_multipartMixed);
            msg.Body = multipartMixed;

            //--- multipart/alternative -----------------------------------------------------------------------------------------
            MIME_Entity entity_multipartAlternative = new MIME_Entity();
            MIME_h_ContentType contentType_multipartAlternative = new MIME_h_ContentType(MIME_MediaTypes.Multipart.alternative);
            contentType_multipartAlternative.Param_Boundary = Guid.NewGuid().ToString().Replace('-', '.');
            MIME_b_MultipartAlternative multipartAlternative = new MIME_b_MultipartAlternative(contentType_multipartAlternative);
            entity_multipartAlternative.Body = multipartAlternative;
            multipartMixed.BodyParts.Add(entity_multipartAlternative);

            //--- text/plain ----------------------------------------------------------------------------------------------------
            MIME_Entity entity_text_plain = new MIME_Entity();
            MIME_b_Text text_plain = new MIME_b_Text(MIME_MediaTypes.Text.plain);
            entity_text_plain.Body = text_plain;
            // Add text body if there is any
            if (message.BodyText != null && message.BodyText.Length > 0)
            {
                var bodyText = message.BodyText.ReadString();

                // Make sure there is a newline at the end of our text, otherwise it will screw up
                // our multipart data format
                if (!bodyText.EndsWith(Environment.NewLine))
                    bodyText = bodyText + Environment.NewLine;

                text_plain.SetText(MIME_TransferEncodings.SevenBit, Encoding.UTF8, bodyText);
            }

            multipartAlternative.BodyParts.Add(entity_text_plain);

            //--- text/html ------------------------------------------------------------------------------------------------------
            MIME_Entity entity_text_html = new MIME_Entity();
            MIME_b_Text text_html = new MIME_b_Text(MIME_MediaTypes.Text.html);
            entity_text_html.Body = text_html;
            if (message.BodyHtml != null && message.BodyHtml.Length > 0)
            {
                var bodyHtml = message.BodyHtml.ReadString();

                // Make sure there is a newline at the end of our text, otherwise it will screw up
                // our multipart data format
                if (!bodyHtml.EndsWith(Environment.NewLine))
                    bodyHtml = bodyHtml + Environment.NewLine;

                text_html.SetText(MIME_TransferEncodings.SevenBit, Encoding.UTF8, bodyHtml);
            }

            multipartAlternative.BodyParts.Add(entity_text_html);

            foreach (var channelAttachment in message.Attachments)
            {
                MIME_b_Application attachmentBody = new MIME_b_Application(MIME_MediaTypes.Application.octet_stream);
                MIME_Entity attachment = new MIME_Entity();
                attachment.Body = attachmentBody;

                // Has to happen before the following lines of code
                multipartMixed.BodyParts.Add(attachment);

                attachment.ContentType = new MIME_h_ContentType(MimeHelper.GetMimeType(channelAttachment.Filename));
                attachment.ContentType.Param_Name = channelAttachment.Filename;

                MIME_h_ContentDisposition contentDisposition = new MIME_h_ContentDisposition(DispositionTypeNames.Attachment);
                contentDisposition.Param_FileName = channelAttachment.Filename;

                attachment.ContentDisposition = contentDisposition;
                attachment.ContentTransferEncoding = TransferEncoding.Base64.ToString();

                attachmentBody.SetData(channelAttachment.ContentStream, MIME_TransferEncodings.Base64);
            }

            // Inject headers
            if (!String.IsNullOrEmpty(message.MessageIdentifier))
                msg.Header.Add(new MIME_h_Unstructured("x-i2mp-messageid", message.MessageIdentifier));

            //if (!String.IsNullOrEmpty(message.Metadata.i2mpFlow))
            //    msg.Header.Add(new MIME_h_Unstructured("x-i2mp-flow", message.Metadata.i2mpFlow));

            //if (!String.IsNullOrEmpty(message.Metadata.i2mpReference))
            //    mailMessage.Headers.Add("X-i2mp-ref", message.Metadata.i2mpReference);

            //if (!String.IsNullOrEmpty(message.Metadata.i2mpSequence))
            //    mailMessage.Headers.Add("X-i2mp-seq", message.Metadata.i2mpSequence);

            //if (!String.IsNullOrEmpty(message.Metadata.i2mpRelation))
            //    mailMessage.Headers.Add("X-i2mp-rel", message.Metadata.i2mpRelation);

            //if (!String.IsNullOrEmpty(message.Metadata.i2mpRelationId))
            //    mailMessage.Headers.Add("X-i2mp-rel-id", message.Metadata.i2mpRelationId);

            // Send message
            try
            {
                SMTP_Client client = new SMTP_Client();

                if ("/Settings/Channels/LoggerEnabled".AsKey(false))
                    client.Logger = new LumiSoft.Net.Log.Logger();

                // todo push this logic into the smtp client implementation itself
                if (Hostname == "smtp.live.com")
                {
                    // Hack for hotmail, first do a connect with no secured channel,
                    // then a STARTTLS
                    client.Connect(Hostname, Port, false);
                    client.StartTLS();
                }
                else
                {
                    client.Connect(Hostname, Port, IsSecured);
                }

                client.Authenticate(creds.UserName, creds.Password);

                using (MemoryStream ms = new MemoryStream())
                {
                    client.MailFrom(msg.From[0].Address, -1);

                    msg.ToStream(ms,
                        new MIME_Encoding_EncodedWord(MIME_EncodedWordEncoding.Q, Encoding.UTF8), Encoding.UTF8);

                    // Reset stream
                    ms.Seek(0, SeekOrigin.Begin);

                    foreach (var address in message.To)
                        client.RcptTo(address.Address);

                    foreach (var address in message.CC)
                        client.RcptTo(address.Address);

                    foreach (var address in message.BCC)
                        client.RcptTo(address.Address);

                    try
                    {
                        client.SendMessage(ms);
                    }
                    finally
                    {
                        client.Dispose();
                    }
                }
            }
            catch(SmtpFailedRecipientsException e)
            {
                throw new ChannelFunctionalException(e.Message, e) { DoNotRetry = true };
            }
            catch (SmtpException e)
            {
                throw new ChannelFunctionalException(e.Message, e);
            }
            catch (Exception e)
            {
                throw new ChannelFunctionalException(e.Message, e);
            }
        }
        /// <summary>
        /// Stores MIME entity body to the specified stream.
        /// </summary>
        /// <param name="stream">Stream where to store body data.</param>
        /// <param name="headerWordEncoder">Header 8-bit words ecnoder. Value null means that words are not encoded.</param>
        /// <param name="headerParmetersCharset">Charset to use to encode 8-bit header parameters. Value null means parameters not encoded.</param>
        /// <param name="headerReencode">If true always specified encoding is used for header. If false and header field value not modified, 
        /// original encoding is kept.</param>
        /// <exception cref="ArgumentNullException">Is raised when <b>stream</b> is null reference.</exception>
        internal protected override void ToStream(Stream stream,MIME_Encoding_EncodedWord headerWordEncoder,Encoding headerParmetersCharset,bool headerReencode)
        {
            // We have signer certificate, sign this entity.
            if(this.BodyParts.Count > 0 && m_pSignerCert != null){
                // Remove old signature if there is any.
                if(this.BodyParts.Count > 1){
                    this.BodyParts.Remove(1);
                }

                // Store entity to tmp stream.
                MemoryStream tmpDataEntityStream = new MemoryStream();
                this.BodyParts[0].ToStream(tmpDataEntityStream,null,null,false);
        
                // Compute PKCS #7 message.
                SignedCms signedCms = new SignedCms(new ContentInfo(tmpDataEntityStream.ToArray()),true);
                signedCms.ComputeSignature(new CmsSigner(m_pSignerCert));
                byte[] pkcs7 = signedCms.Encode();
   
                // Create PKCS 7 entity.
                MIME_Entity entity_application_pkcs7 = new MIME_Entity();
                MIME_b_Application application_pkcs7 = new MIME_b_Application(MIME_MediaTypes.Application.x_pkcs7_signature);
                entity_application_pkcs7.Body = application_pkcs7;
                application_pkcs7.SetData(new MemoryStream(pkcs7),MIME_TransferEncodings.Base64);
                entity_application_pkcs7.ContentType.Param_Name = "smime.p7s";
                entity_application_pkcs7.ContentDescription = "S/MIME Cryptographic Signature";
                this.BodyParts.Add(entity_application_pkcs7);

                signedCms.Decode(application_pkcs7.Data);
                signedCms.CheckSignature(true);
            }

            base.ToStream(stream,headerWordEncoder,headerParmetersCharset,headerReencode);
        }
Example #57
0
 /// <summary>
 /// Sets MIME entity parent entity.
 /// </summary>
 /// <param name="parent">Parent entity.</param>
 internal void SetParent(MIME_Entity parent)
 {
     m_pParent = parent;
 }