def convert_encrypted_mime_message(crypto_message, ciphertext, from_user,
                                   to_user):
    '''
        Convert a MIME message that has been signed or encrypted, and creating a new
        plain text message with the payload the encrypted/signed original message. This reduces the
        metadata someone can collect, but it does require the receiving end decrypt the
        message and create a new readable message from the original message.
    '''
    def copy_item_from_original(msg, keyword):
        value = crypto_message.get_email_message().get_header(keyword)
        if value is not None:
            msg.__setitem__(keyword, value)

    if ciphertext is not None and len(ciphertext) > 0:
        # set up the body parts
        parts = []
        parts.append(
            MIMEApplication(mime_constants.PGP_MIME_VERSION_FIELD,
                            mime_constants.PGP_SUB_TYPE, encode_7or8bit))
        parts.append(
            MIMEApplication(ciphertext, mime_constants.OCTET_STREAM_SUB_TYPE,
                            encode_7or8bit))

        boundary = 'Part{}{}--'.format(random(), random())
        charset, __ = get_charset(
            crypto_message.get_email_message().get_message())
        params = {
            mime_constants.PROTOCOL_KEYWORD: mime_constants.PGP_TYPE,
            mime_constants.CHARSET_KEYWORD: charset,
        }
        msg = MIMEMultipart(mime_constants.ENCRYPTED_SUB_TYPE, boundary, parts,
                            **params)
        log_message("part's content type: {}".format(msg.get_content_type()))

        # configure the header
        msg.__setitem__(mime_constants.FROM_KEYWORD, from_user)
        msg.__setitem__(mime_constants.TO_KEYWORD, to_user)
        msg.__setitem__(constants.PGP_ENCRYPTED_CONTENT_TYPE,
                        mime_constants.MULTIPART_MIXED_TYPE)
        copy_item_from_original(msg, mime_constants.MESSAGE_ID_KEYWORD)
        copy_item_from_original(msg, mime_constants.SUBJECT_KEYWORD)
        copy_item_from_original(msg, mime_constants.DATE_KEYWORD)

        crypto_message.set_email_message(EmailMessage(msg))
        crypto_message.add_public_key_to_header(from_user)
        crypto_message.set_filtered(True)
        crypto_message.set_crypted(True)
def convert_encrypted_mime_message(crypto_message, ciphertext, from_user, to_user):
    '''
        Convert a MIME message that has been signed or encrypted, and creating a new
        plain text message with the payload the encrypted/signed original message. This reduces the
        metadata someone can collect, but it does require the receiving end decrypt the
        message and create a new readable message from the original message.
    '''

    def copy_item_from_original(msg, keyword):
        value = crypto_message.get_email_message().get_header(keyword)
        if value is not None:
            msg.__setitem__(keyword, value)

    if ciphertext is not None and len(ciphertext) > 0:
        # set up the body parts
        parts = []
        parts.append(
           MIMEApplication(
             mime_constants.PGP_MIME_VERSION_FIELD, mime_constants.PGP_SUB_TYPE, encode_7or8bit))
        parts.append(
           MIMEApplication(ciphertext, mime_constants.OCTET_STREAM_SUB_TYPE, encode_7or8bit))

        boundary = 'Part{}{}--'.format(random(), random())
        charset, __ = get_charset(crypto_message.get_email_message().get_message())
        params = {mime_constants.PROTOCOL_KEYWORD:mime_constants.PGP_TYPE,
                  mime_constants.CHARSET_KEYWORD:charset,}
        msg = MIMEMultipart(mime_constants.ENCRYPTED_SUB_TYPE, boundary, parts, **params)
        log_message("part's content type: {}".format(msg.get_content_type()))

        # configure the header
        msg.__setitem__(mime_constants.FROM_KEYWORD, from_user)
        msg.__setitem__(mime_constants.TO_KEYWORD, to_user)
        msg.__setitem__(constants.PGP_ENCRYPTED_CONTENT_TYPE, mime_constants.MULTIPART_MIXED_TYPE)
        copy_item_from_original(msg, mime_constants.MESSAGE_ID_KEYWORD)
        copy_item_from_original(msg, mime_constants.SUBJECT_KEYWORD)
        copy_item_from_original(msg, mime_constants.DATE_KEYWORD)

        crypto_message.set_email_message(EmailMessage(msg))
        crypto_message.add_public_key_to_header(from_user)
        crypto_message.set_filtered(True)
        crypto_message.set_crypted(True)
示例#3
0
 def __setitem__(self, name, val):
     name, val = forbid_multi_line_headers(name, val)
     MIMEMultipart.__setitem__(self, name, val)
示例#4
0
 def __setitem__(self, name, val):
     name, val = forbid_multi_line_headers(name, val, self.encoding)
     MIMEMultipart.__setitem__(self, name, val)
示例#5
0
class Message(object):
    """
        Wrapper around email.Message class simplifying creation of simple email
        message objects.

        Allows most basic email messages types (including text, html &
        attachments) to be created simply from constructor. More complex
        messages should be created using the email.mime classes directly

        Class wraps the email.Message class and delegates item/attr lookups
        to the wrapped class (allows the object to be treated as a MIMEBase
        instance even though it doesnt inherit from this)

        Basic usage:

        >>> msg = Message('Test Message',to='*****@*****.**',text="Hello",html="<b>Hello</b>",attachments=['img.jpg'])

    """
    def __init__(self,
                 subject,
                 to,
                 cc=None,
                 bcc=None,
                 text=None,
                 html=None,
                 attachments=None,
                 sender=None,
                 reply_to=None):
        """
            Create message object

            subject         : Subject field
            to              : To recipients (as string - eg. "A <*****@*****.**>, B <*****@*****.**>")
            cc              : Cc recipients (same format as to)
            bcc             : Bcc recipients (same format as to)
            text            : Plain text body
            html            : HTML body ('text' will be included as alternative)
            attachments     : List of attachments - if the item is a subclass of MIMEBase
                              this is inserted directly, otherwise it is assumed to be
                              a filename and a MIME attachment craeted guessing the
                              content-type (for detailed control of the attachment
                              parameters create these separately)
            sender          : Value for the 'From' header (e.g. Foo Barr <*****@*****.**>).
                              If specified, 'Reply-To' header is also set to this address.
            reply_to        : Value for the 'Reply-To' header.

        """
        if not html and not attachments:
            # Simple plain text email
            self.root = MIMEText(text, 'plain', self._charset(text))
        else:
            # Multipart message
            self.root = MIMEMultipart()
            if html:
                # Add html & plain text alernative parts
                alt = MIMEMultipart('alternative')
                alt.attach(MIMEText(text, 'plain', self._charset(text)))
                alt.attach(MIMEText(html, 'html', self._charset(html)))
                self.root.attach(alt)
            else:
                # Just add plain text part
                txt = MIMEText(text, 'plain', self._charset(text))
                self.root.attach(txt)
            # Add attachments
            for a in attachments or []:
                self.root.attach(self._attachment(a))
        # Set headers
        self.root['To'] = to
        if cc: self.root['Cc'] = cc
        if bcc: self.root['Bcc'] = bcc

        if sender:
            self.root['From'] = sender

            if not reply_to:
                # If 'Reply-To' is not provided, set it to the 'From' value
                self.root['Reply-To'] = sender

        if reply_to:
            self.root['Reply-To'] = reply_to

        self.root['Subject'] = subject

    def _charset(self, s):
        """
            Guess charset - assume ascii for text and force utf-8 for unicode
            (email.mime classes take care of encoding)
        """
        return 'utf-8' if isinstance(s, unicode_type) else 'us-ascii'

    def _attachment(self, a):
        """
            Create MIME attachment
        """
        if isinstance(a, MIMEBase):
            # Already MIME object - return
            return a
        else:
            # Assume filename - guess mime-type from extension and return MIME object
            main, sub = (guess_type(a)[0]
                         or 'application/octet-stream').split('/', 1)
            attachment = MIMEBase(main, sub)
            with open(a, 'rb') as f:
                attachment.set_payload(f.read())
            if sys.version_info[0] == 2:
                # Try to handle non-ascii filenames
                attachment.add_header('Content-Disposition',
                                      'attachment',
                                      filename=unicode(
                                          os.path.basename(a),
                                          sys.getfilesystemencoding()))
            else:
                attachment.add_header('Content-Disposition',
                                      'attachment',
                                      filename=os.path.basename(a))
            encode_base64(attachment)
            return attachment

    # Delegate to root MIME object (allows object to be treated as MIMEBase)

    def __getitem__(self, key):
        return self.root.__getitem__(key)

    def __setitem__(self, key, value):
        self.root.__setitem__(key, value)

    def __delitem__(self, key):
        return self.root.__delitem__(key)

    def __getattr__(self, attr):
        if attr != 'root':
            return getattr(self.root, attr)
示例#6
0
 def __setitem__(self, name, value):
     StdlibMIMEMultipart.__setitem__(self, name, encode_header(name, value))
示例#7
0
文件: mail.py 项目: boothead/karl
 def __setitem__(self, name, value):
     StdlibMIMEMultipart.__setitem__(self, name, encode_header(name, value))
示例#8
0
class Message(object):
    """
        Wrapper around email.Message class simplifying creation of simple email
        message objects.

        Allows most basic email messages types (including text, html &
        attachments) to be created simply from constructor. More complex
        messages should be created using the email.mime classes directly

        Class wraps the email.Message class and delegates item/attr lookups
        to the wrapped class (allows the object to be treated as a MIMEBase
        instance even though it doesnt inherit from this)

        Basic usage:

        >>> msg = Message('Test Message',to='*****@*****.**',text="Hello",html="<b>Hello</b>",attachments=['img.jpg'])

    """

    def __init__(self,subject,to,cc=None,bcc=None,text=None,html=None,
                 attachments=None, sender=None, reply_to=None):
        """
            Create message object

            subject         : Subject field
            to              : To recipients (as string - eg. "A <*****@*****.**>, B <*****@*****.**>")
            cc              : Cc recipients (same format as to)
            bcc             : Bcc recipients (same format as to)
            text            : Plain text body
            html            : HTML body ('text' will be included as alternative)
            attachments     : List of attachments - if the item is a subclass of MIMEBase
                              this is inserted directly, otherwise it is assumed to be
                              a filename and a MIME attachment craeted guessing the
                              content-type (for detailed control of the attachment
                              parameters create these separately)
            sender          : Value for the 'From' header (e.g. Foo Barr <*****@*****.**>).
                              If specified, 'Reply-To' header is also set to this address.
            reply_to        : Value for the 'Reply-To' header.

        """
        if not html and not attachments:
            # Simple plain text email
            self.root = MIMEText(text,'plain',self._charset(text))
        else:
            # Multipart message
            self.root = MIMEMultipart()
            if html:
                # Add html & plain text alernative parts
                alt = MIMEMultipart('alternative')
                alt.attach(MIMEText(text,'plain',self._charset(text)))
                alt.attach(MIMEText(html,'html',self._charset(html)))
                self.root.attach(alt)
            else:
                # Just add plain text part
                txt = MIMEText(text,'plain',self._charset(text))
                self.root.attach(txt)
            # Add attachments
            for a in attachments or []:
                self.root.attach(self._attachment(a))
        # Set headers
        self.root['To'] = to
        if cc: self.root['Cc'] = cc
        if bcc: self.root['Bcc'] = bcc

        if sender:
            self.root['From'] = sender

            if not reply_to:
                # If 'Reply-To' is not provided, set it to the 'From' value
                self.root['Reply-To'] = sender

        if reply_to:
            self.root['Reply-To'] = reply_to

        self.root['Subject'] = subject

    def _charset(self,s):
        """
            Guess charset - assume ascii for text and force utf-8 for unicode
            (email.mime classes take care of encoding)
        """
        return 'utf-8' if isinstance(s,unicode_type) else 'us-ascii'

    def _attachment(self,a):
        """
            Create MIME attachment
        """
        if isinstance(a,MIMEBase):
            # Already MIME object - return
            return a
        else:
            # Assume filename - guess mime-type from extension and return MIME object
            main,sub = (guess_type(a)[0] or 'application/octet-stream').split('/',1)
            attachment = MIMEBase(main,sub)
            with open(a,'rb') as f:
                attachment.set_payload(f.read())
            attachment.add_header('Content-Disposition','attachment',filename=os.path.basename(a))
            encode_base64(attachment)
            return attachment

    # Delegate to root MIME object (allows object to be treated as MIMEBase)

    def __getitem__(self,key):
        return self.root.__getitem__(key)

    def __setitem__(self,key,value):
        self.root.__setitem__(key,value)

    def __delitem__(self,key):
        return self.root.__delitem__(key)

    def __getattr__(self,attr):
        if attr != 'root':
            return getattr(self.root,attr)
示例#9
0
 def __setitem__(self, name, val):
     MIMEMultipart.__setitem__(self, name, val)
示例#10
0
from __future__ import unicode_literals