A part of an e-mail body.
More or less an embedded e-mail for its own.
Inheritance: AbstractEMail
Beispiel #1
0
        /// <summary>
        /// Add an attachment to this e-mail.
        /// </summary>
        /// <param name="EMailBodypart">An attachment.</param>
        public T AddAttachment <T>(EMailBodypart EMailBodypart)
            where T : AbstractEMailBuilder
        {
            _Attachments.Add(EMailBodypart);

            return((T)this);
        }
Beispiel #2
0
        /// <summary>
        /// Parse an e-mail from the given enumeration of strings.
        /// </summary>
        /// <param name="MailText">An enumeration of strings.</param>
        private EMail(IEnumerable <String> MailText)

            : this(MailText.TakeWhile(line => line.IsNotNullOrEmpty()).
                   AggregateIndentedLines().
                   ToKeyValuePairs(':'))

        {
            Body = new EMailBodypart(MailText);
        }
Beispiel #3
0
        /// <summary>
        /// Create a new e-mail based on the given e-mail builder.
        /// </summary>
        /// <param name="MailBuilder">An e-mail builder.</param>
        public EMail(AbstractEMailBuilder MailBuilder)

            : this(MailBuilder.
                   EncodeBodyparts().
                   // Copy only everything which is not related to the e-mail body!
                   MailHeaders.Where(header => !header.Key.ToLower().StartsWith("content")).
                   Concat(MailBuilder.Body.MailHeaders))

        {
            //ToDo: Do a real deep-copy here!
            Body = MailBuilder.Body;

            //ToDo: Work-aroung for PGP/GPG!
            this.From = MailBuilder.From;
            this.To   = MailBuilder.To;
            this.Cc   = MailBuilder.Cc;
        }
Beispiel #4
0
        /// <summary>
        /// Encode this and all nested e-mail body parts.
        /// </summary>
        internal AbstractEMailBuilder EncodeBodyparts()
        {
            var SignTheMail    = false;
            var EncryptTheMail = false;

            EMailBodypart BodypartToBeSecured = null;

            #region Add attachments, if available...

            if (_Attachments == null ||
                _Attachments.Count == 0)
            {
                BodypartToBeSecured = _EncodeBodyparts();
            }

            else
            {
                BodypartToBeSecured = new EMailBodypart(ContentTypeBuilder:       AEMail => new MailContentType(AEMail, MailContentTypes.multipart_mixed)
                {
                    CharSet = "utf-8"
                }.GenerateMIMEBoundary(),
                                                        ContentTransferEncoding:  "8bit",
                                                        Content:                  new String[] { "This is a multi-part message in MIME format." },
                                                        NestedBodyparts:          new EMailBodypart[] { _EncodeBodyparts() }.
                                                        Concat(_Attachments));
            }

            #endregion


            #region Check security settings

            switch (SecurityLevel)
            {
            case EMailSecurity.autosign:

                if (From.SecretKeyRing != null &&
                    From.SecretKeyRing.Any() &&
                    Passphrase.IsNotNullOrEmpty())
                {
                    SignTheMail = true;
                }

                break;


            case EMailSecurity.sign:

                if (From.SecretKeyRing == null ||
                    !From.SecretKeyRing.Any() ||
                    Passphrase.IsNullOrEmpty())
                {
                    throw new ApplicationException("Can not sign the e-mail!");
                }

                SignTheMail = true;

                break;


            case EMailSecurity.auto:

                if (From.SecretKeyRing != null &&
                    From.SecretKeyRing.Any() &&
                    Passphrase.IsNotNullOrEmpty())
                {
                    SignTheMail = true;
                }

                if (SignTheMail &&
                    (!To.Any() | To.Any(v => v.PublicKeyRing != null && v.PublicKeyRing.Any())) &&
                    (!Cc.Any() | Cc.Any(v => v.PublicKeyRing != null && v.PublicKeyRing.Any())))
                {
                    EncryptTheMail = true;
                }

                break;


            case EMailSecurity.encrypt:

                if (From.SecretKeyRing == null ||
                    !From.SecretKeyRing.Any() ||
                    Passphrase.IsNullOrEmpty() ||
                    To.Any(v => v.PublicKeyRing == null || !v.PublicKeyRing.Any()) ||
                    Cc.Any(v => v.PublicKeyRing == null || !v.PublicKeyRing.Any()))
                {
                    throw new ApplicationException("Can not sign and encrypt the e-mail!");
                }

                EncryptTheMail = true;

                break;
            }

            #endregion

            #region Sign the e-mail

            if (SignTheMail & !EncryptTheMail)
            {
                var DataToBeSigned = BodypartToBeSecured.

                                     // Include headers of this MIME body
                                     // https://tools.ietf.org/html/rfc1847 Security Multiparts for MIME:
                                     ToText().

                                     // Any trailing whitespace MUST then be removed from the signed material
                                     Select(line => line.TrimEnd()).

                                     // Canonical text format with <CR><LF> line endings
                                     // https://tools.ietf.org/html/rfc3156 5. OpenPGP signed data
                                     Aggregate((a, b) => a + "\r\n" + b)

                                     //ToDo: Apply Content-Transfer-Encoding
                ;

                // MIME Security with OpenPGP (rfc3156, https://tools.ietf.org/html/rfc3156)
                // OpenPGP Message Format     (rfc4880, https://tools.ietf.org/html/rfc4880)
                _Body = new EMailBodypart(ContentTypeBuilder:          AMail => new MailContentType(AMail, MailContentTypes.multipart_signed)
                {
                    MicAlg   = "pgp-sha512",
                    Protocol = "application/pgp-signature",
                    CharSet  = "utf-8",
                },
                                          ContentTransferEncoding:     "8bit",
                                          NestedBodyparts:             new EMailBodypart[] {
                    BodypartToBeSecured,

                    new EMailBodypart(ContentTypeBuilder:       AMail => new MailContentType(AMail, MailContentTypes.application_pgp__signature)
                    {
                        CharSet = "utf-8"
                    },
                                      //    ContentTransferEncoding:  "8bit",
                                      ContentDescription:       "OpenPGP digital signature",
                                      ContentDisposition:       ContentDispositions.attachment.ToString() + "; filename=\"signature.asc\"",
                                      Content:                  new String[] {
                        OpenPGP.CreateSignature(new MemoryStream(DataToBeSigned.ToUTF8Bytes()),
                                                From.SecretKeyRing.First(),
                                                Passphrase,
                                                HashAlgorithm: HashAlgorithm).

                        WriteTo(new MemoryStream(), CloseOutputStream: false).
                        ToUTF8String()
                    })
                }
                                          );
            }

            #endregion

            #region Encrypt the e-mail

            else if (SignTheMail & EncryptTheMail)
            {
                var Plaintext  = BodypartToBeSecured.ToText().Aggregate((a, b) => a + "\r\n" + b).ToUTF8Bytes();
                var Ciphertext = new MemoryStream();

                OpenPGP.EncryptSignAndZip(InputStream:            new MemoryStream(Plaintext),
                                          Length:                 (UInt64)Plaintext.Length,
                                          SecretKey:              From.SecretKeyRing.First(),
                                          Passphrase:             Passphrase,
                                          PublicKey:              To.First().PublicKeyRing.First(),
                                          OutputStream:           Ciphertext,
                                          SymmetricKeyAlgorithm:  SymmetricKeyAlgorithm,
                                          HashAlgorithm:          HashAlgorithm,
                                          CompressionAlgorithm:   CompressionAlgorithm,
                                          ArmoredOutput:          true,
                                          Filename:               "encrypted.asc",
                                          LastModificationTime:   DateTime.UtcNow);

                // MIME Security with OpenPGP (rfc3156, https://tools.ietf.org/html/rfc3156)
                // OpenPGP Message Format     (rfc4880, https://tools.ietf.org/html/rfc4880)
                _Body = new EMailBodypart(ContentTypeBuilder:          AMail => new MailContentType(AMail, MailContentTypes.multipart_encrypted)
                {
                    Protocol = "application/pgp-encrypted",
                    CharSet  = "utf-8",
                },
                                          ContentTransferEncoding:     "8bit",
                                          NestedBodyparts:             new EMailBodypart[] {
                    new EMailBodypart(ContentTypeBuilder:   AMail => new MailContentType(AMail, MailContentTypes.application_pgp__encrypted)
                    {
                        CharSet = "utf-8"
                    },
                                      ContentDescription:   "PGP/MIME version identification",
                                      ContentDisposition:   ContentDispositions.attachment.ToString() + "; filename=\"signature.asc\"",
                                      Content:              new String[] { "Version: 1" }),

                    new EMailBodypart(ContentTypeBuilder:   AMail => new MailContentType(AMail, MailContentTypes.application_octet__stream)
                    {
                        CharSet = "utf-8"
                    },
                                      ContentDescription:   "OpenPGP encrypted message",
                                      ContentDisposition:   ContentDispositions.inline.ToString() + "; filename=\"encrypted.asc\"",
                                      Content:              new String[] { Ciphertext.ToArray().ToUTF8String() }),
                }
                                          );
            }

            #endregion


            else
            {
                this._Body = BodypartToBeSecured;
            }

            return(this);
        }
Beispiel #5
0
 /// <summary>
 /// Parse the e-mail from the given text lines.
 /// </summary>
 /// <param name="MailText">The E-Mail as an enumeration of strings.</param>
 public AbstractEMailBuilder(IEnumerable <String> MailText)
     : base(MailText)
 {
     this._Body = new EMailBodypart(MailText);
 }
Beispiel #6
0
 /// <summary>
 /// Parse the e-mail from the given e-mail.
 /// </summary>
 /// <param name="EMail">An e-mail.</param>
 public AbstractEMailBuilder(EMail EMail)
     : base(EMail)
 {
     this._Body = new EMailBodypart(EMail.ToText);
 }
Beispiel #7
0
        /// <summary>
        /// Create a new e-mail based on the given e-mail builder.
        /// </summary>
        /// <param name="MailBuilder">An e-mail builder.</param>
        public EMail(AbstractEMailBuilder MailBuilder)
            : this(MailBuilder.
                       EncodeBodyparts().
                       // Copy only everything which is not related to the e-mail body!
                       MailHeaders.Where(header => !header.Key.ToLower().StartsWith("content")).
                       Concat(MailBuilder.Body.MailHeaders))
        {
            //ToDo: Do a real deep-copy here!
            Body  = MailBuilder.Body;

            //ToDo: Work-aroung for PGP/GPG!
            this.From = MailBuilder.From;
            this.To   = MailBuilder.To;
            this.Cc   = MailBuilder.Cc;
        }
Beispiel #8
0
 /// <summary>
 /// Parse an e-mail from the given enumeration of strings.
 /// </summary>
 /// <param name="MailText">An enumeration of strings.</param>
 private EMail(IEnumerable<String> MailText)
     : this(MailText.TakeWhile(line => line.IsNotNullOrEmpty()).
                     AggregateIndentedLines().
                     ToKeyValuePairs(':'))
 {
     Body  = new EMailBodypart(MailText);
 }