Esempio n. 1
0
def build_message(message):
    """ Build the AS2 mime message to be sent to partner. Encrypts, signs and compresses the message based on
    the partner profile. Returns the message final message content."""

    # Initialize the variables
    mic_content, mic_alg = None, None
    payload = email.Message.Message()

    # Build the As2 message headers as per specifications
    models.Log.objects.create(
        message=message,
        status='S',
        text=_(u'Build the AS2 message and header to send to the partner'))
    email_datetime = email.Utils.formatdate(localtime=True)
    as2_header = {
        'AS2-Version': '1.2',
        'ediint-features': 'CEM',
        'MIME-Version': '1.0',
        'Message-ID': '<%s>' % message.message_id,
        'AS2-From': as2utils.escape_as2name(message.organization.as2_name),
        'AS2-To': as2utils.escape_as2name(message.partner.as2_name),
        'Subject': message.partner.subject,
        'Date': email_datetime,
        'recipient-address': message.partner.target_url,
        'user-agent': 'PYAS2, A pythonic AS2 server'
    }

    # Create the payload message and add the data to be transferred as its contents
    with open(message.payload.file, 'rb') as fh:
        as2_content = fh.read()
    payload.set_payload(as2_content)
    payload.set_type(message.partner.content_type)
    payload.add_header('Content-Disposition',
                       'attachment',
                       filename=message.payload.name)
    del payload['MIME-Version']

    # Compress the message if requested in the profile
    if message.partner.compress:
        models.Log.objects.create(message=message,
                                  status='S',
                                  text=_(u'Compressing the payload.'))
        message.compressed = True
        compressed_message = email.Message.Message()
        compressed_message.set_type('application/pkcs7-mime')
        compressed_message.set_param('name', 'smime.p7z')
        compressed_message.set_param('smime-type', 'compressed-data')
        compressed_message.add_header('Content-Transfer-Encoding', 'base64')
        compressed_message.add_header('Content-Disposition',
                                      'attachment',
                                      filename='smime.p7z')
        compressed_message.set_payload(
            as2utils.compress_payload(
                as2utils.canonicalize(as2utils.mimetostring(payload, 0))))
        as2_content, payload = compressed_message.get_payload(
        ), compressed_message
        pyas2init.logger.debug('Compressed message %s payload as:\n%s' %
                               (message.message_id, payload.as_string()))

    # Sign the message if requested in the profile
    if message.partner.signature:
        models.Log.objects.create(
            message=message,
            status='S',
            text=_(u'Signing the message using organization key {0:s}'.format(
                message.organization.signature_key)))
        message.signed = True
        signed_message = MIMEMultipart('signed',
                                       protocol="application/pkcs7-signature")
        del signed_message['MIME-Version']
        mic_content = as2utils.canonicalize(as2utils.mimetostring(payload, 0))
        signed_message.attach(payload)
        mic_alg, signature = as2utils.sign_payload(
            mic_content,
            str(message.organization.signature_key.certificate.path),
            str(message.organization.signature_key.certificate_passphrase))
        signed_message.set_param('micalg', mic_alg)
        signed_message.attach(signature)
        signed_message.as_string()
        as2_content = as2utils.canonicalize(
            as2utils.extractpayload(signed_message))
        payload = signed_message
        pyas2init.logger.debug('Signed message %s payload as:\n%s' %
                               (message.message_id, payload.as_string()))

    # Encrypt the message if requested in the profile
    if message.partner.encryption:
        models.Log.objects.create(
            message=message,
            status='S',
            text=_(u'Encrypting the message using partner key {0:s}'.format(
                message.partner.encryption_key)))
        message.encrypted = True
        payload = as2utils.encrypt_payload(
            as2utils.canonicalize(as2utils.mimetostring(payload, 0)),
            message.partner.encryption_key.certificate.path,
            message.partner.encryption)
        payload.set_type('application/pkcs7-mime')
        as2_content = payload.get_payload().decode('base64')
        del payload['Content-Transfer-Encoding']
        pyas2init.logger.debug('Encrypted message %s payload as:\n%s' %
                               (message.message_id, payload.as_string()))

    # If MDN is to be requested from the partner, set the appropriate headers
    if message.partner.mdn:
        as2_header['disposition-notification-to'] = '*****@*****.**'
        if message.partner.mdn_sign:
            as2_header['disposition-notification-options'] = u'signed-receipt-protocol=required, ' \
                                                             u'pkcs7-signature; ' \
                                                             u'signed-receipt-micalg=optional, ' \
                                                             u'%s' % message.partner.mdn_sign
        message.mdn_mode = 'SYNC'
        if message.partner.mdn_mode == 'ASYNC':
            as2_header['receipt-delivery-option'] = pyas2init.gsettings[
                'mdn_url']
            message.mdn_mode = 'ASYNC'

    # If MIC content is set, i.e. message has been signed then calulcate the MIC
    if mic_content:
        pyas2init.logger.debug("Calculating MIC with alg %s for content:\n%s" %
                               (mic_alg, mic_content))
        calculate_mic = getattr(hashlib, mic_alg.replace('-', ''),
                                hashlib.sha1)
        message.mic = calculate_mic(mic_content).digest().encode(
            'base64').strip()

    # Extract the As2 headers as a string and save it to the message object
    as2_header.update(payload.items())
    message.headers = ''
    for key in as2_header:
        message.headers += '%s: %s\n' % (key, as2_header[key])
    message.save()

    models.Log.objects.create(
        message=message,
        status='S',
        text=
        _(u'AS2 message has been built successfully, sending it to the partner'
          ))
    return as2_content
Esempio n. 2
0
def build_message(message):
    """ Build the AS2 mime message to be sent to partner. Encrypts, signs and compresses the message based on
    the partner profile. Returns the message final message content."""

    # Initialize the variables
    mic_content, mic_alg = None, None
    payload = email.Message.Message()

    # Build the As2 message headers as per specifications
    models.Log.objects.create(message=message,
                              status='S',
                              text=_(u'Build the AS2 message and header to send to the partner'))
    email_datetime = email.Utils.formatdate(localtime=True)
    as2_header = {
        'AS2-Version': '1.2',
        'ediint-features': 'CEM',
        'MIME-Version': '1.0',
        'Message-ID': '<%s>' % message.message_id,
        'AS2-From': as2utils.escape_as2name(message.organization.as2_name),
        'AS2-To': as2utils.escape_as2name(message.partner.as2_name),
        'Subject': message.partner.subject,
        'Date': email_datetime,
        'recipient-address': message.partner.target_url,
        'user-agent': 'PYAS2, A pythonic AS2 server'
    }

    # Create the payload message and add the data to be transferred as its contents
    with open(message.payload.file, 'rb') as fh:
        as2_content = fh.read()
    payload.set_payload(as2_content)
    payload.set_type(message.partner.content_type)
    payload.add_header('Content-Disposition', 'attachment', filename=message.payload.name)
    del payload['MIME-Version']

    # Compress the message if requested in the profile
    if message.partner.compress:
        models.Log.objects.create(message=message, status='S', text=_(u'Compressing the payload.'))
        message.compressed = True
        compressed_message = email.Message.Message()
        compressed_message.set_type('application/pkcs7-mime')
        compressed_message.set_param('name', 'smime.p7z')
        compressed_message.set_param('smime-type', 'compressed-data')
        compressed_message.add_header('Content-Transfer-Encoding', 'base64')
        compressed_message.add_header('Content-Disposition', 'attachment', filename='smime.p7z')
        compressed_message.set_payload(
            as2utils.compress_payload(as2utils.canonicalize(as2utils.mimetostring(payload, 0))))
        as2_content, payload = compressed_message.get_payload(), compressed_message
        pyas2init.logger.debug('Compressed message %s payload as:\n%s' % (message.message_id, payload.as_string()))

    # Sign the message if requested in the profile
    if message.partner.signature:
        models.Log.objects.create(message=message,
                                  status='S',
                                  text=_(u'Signing the message using organization key {0:s}'.format(
                                      message.organization.signature_key)))
        message.signed = True
        signed_message = MIMEMultipart('signed', protocol="application/pkcs7-signature")
        del signed_message['MIME-Version']
        mic_content = as2utils.canonicalize(as2utils.mimetostring(payload, 0))
        signed_message.attach(payload)
        mic_alg, signature = as2utils.sign_payload(mic_content,
                                                   str(message.organization.signature_key.certificate.path),
                                                   str(message.organization.signature_key.certificate_passphrase))
        signed_message.set_param('micalg', mic_alg)
        signed_message.attach(signature)
        signed_message.as_string()
        as2_content = as2utils.canonicalize(as2utils.extractpayload(signed_message))
        payload = signed_message
        pyas2init.logger.debug('Signed message %s payload as:\n%s' % (message.message_id, payload.as_string()))

    # Encrypt the message if requested in the profile
    if message.partner.encryption:
        models.Log.objects.create(message=message,
                                  status='S',
                                  text=_(u'Encrypting the message using partner key {0:s}'.format(
                                      message.partner.encryption_key)))
        message.encrypted = True
        payload = as2utils.encrypt_payload(as2utils.canonicalize(as2utils.mimetostring(payload, 0)),
                                           message.partner.encryption_key.certificate.path,
                                           message.partner.encryption)
        payload.set_type('application/pkcs7-mime')
        as2_content = payload.get_payload()
        pyas2init.logger.debug('Encrypted message %s payload as:\n%s' % (message.message_id, payload.as_string()))

    # If MDN is to be requested from the partner, set the appropriate headers
    if message.partner.mdn:
        as2_header['disposition-notification-to'] = '*****@*****.**'
        if message.partner.mdn_sign:
            as2_header['disposition-notification-options'] = u'signed-receipt-protocol=required, ' \
                                                             u'pkcs7-signature; ' \
                                                             u'signed-receipt-micalg=optional, ' \
                                                             u'%s' % message.partner.mdn_sign
        message.mdn_mode = 'SYNC'
        if message.partner.mdn_mode == 'ASYNC':
            as2_header['receipt-delivery-option'] = pyas2init.gsettings['mdn_url']
            message.mdn_mode = 'ASYNC'

    # If MIC content is set, i.e. message has been signed then calulcate the MIC
    if mic_content:
        pyas2init.logger.debug("Calculating MIC with alg %s for content:\n%s" % (mic_alg, mic_content))
        calculate_mic = getattr(hashlib, mic_alg.replace('-', ''), hashlib.sha1)
        message.mic = calculate_mic(mic_content).digest().encode('base64').strip()

    # Extract the As2 headers as a string and save it to the message object
    as2_header.update(payload.items())
    message.headers = ''
    for key in as2_header:
        message.headers += '%s: %s\n' % (key, as2_header[key])
    message.save()

    models.Log.objects.create(message=message,
                              status='S',
                              text=_(u'AS2 message has been built successfully, sending it to the partner'))
    return as2_content
Esempio n. 3
0
def build_message(message):
    ''' Build the AS2 mime message to be sent to partner'''
    models.Log.objects.create(message=message, status='S', text=_(u'Build the AS2 message and header to send to the partner'))
    reference = '<%s>'%message.message_id
    micContent = None
    email_datetime = email.Utils.formatdate(localtime=True)
    as2Header = {
        'AS2-Version'         : '1.2',
        'ediint-features'     : 'CEM',
        'MIME-Version'        : '1.0',  
        'Message-ID'          : reference,
        'AS2-From'            : as2utils.escape_as2name(message.organization.as2_name),
        'AS2-To'              : as2utils.escape_as2name(message.partner.as2_name),
        'Subject'             : message.partner.subject,
        'Date'                : email_datetime,
        'recipient-address'   : message.partner.target_url,
        'user-agent'          : 'PYAS2, A pythonic AS2 server'
    }
    payload = email.Message.Message()
    with open(message.payload.file, 'rb') as fh:
        payload.set_payload(fh.read())
        fh.close()
    payload.set_type(message.partner.content_type)
    payload.add_header('Content-Disposition', 'attachment', filename=message.payload.name)
    del payload['MIME-Version']
    #micContent,cmicContent,content = payload.get_payload(),None,payload.get_payload()
    content = payload.get_payload()
    if message.partner.compress:
        models.Log.objects.create(message=message, status='S', text=_(u'Compressing the payload.'))
        message.compressed = True
        #micContent = as2utils.canonicalize(as2utils.mimetostring(payload, 0))
        cmessage = email.Message.Message()
        cmessage.set_type('application/pkcs7-mime')
        cmessage.set_param('name', 'smime.p7z')
        cmessage.set_param('smime-type', 'compressed-data') 
        cmessage.add_header('Content-Transfer-Encoding', 'base64')
        cmessage.add_header('Content-Disposition', 'attachment', filename='smime.p7z')
        cmessage.set_payload(as2utils.compress_payload(as2utils.canonicalize(as2utils.mimetostring(payload, 0))))
        content,payload = cmessage.get_payload(),cmessage
        pyas2init.logger.debug('Compressed message %s payload as:\n%s'%(message.message_id,payload.as_string()))
    if message.partner.signature: 
        models.Log.objects.create(message=message, status='S', text=_(u'Signing the message using organzation key %s'%message.organization.signature_key))
        message.signed = True
        multipart = MIMEMultipart('signed',protocol="application/pkcs7-signature")
        del multipart['MIME-Version']
        #micContent = as2utils.canonicalize2(payload)
        micContent = as2utils.canonicalize(as2utils.mimetostring(payload, 0))
        multipart.attach(payload)
        micalg, signature = as2utils.sign_payload(micContent, str(message.organization.signature_key.certificate.path), str(message.organization.signature_key.certificate_passphrase))
        multipart.set_param('micalg',micalg)
        multipart.attach(signature)
        multipart.as_string()
        content = as2utils.canonicalize(as2utils.extractpayload(multipart))
        payload = multipart
        pyas2init.logger.debug('Signed message %s payload as:\n%s'%(message.message_id,payload.as_string()))
    if message.partner.encryption: 
        #if not message.compressed and not message.signed:
            #micContent = as2utils.canonicalize(as2utils.mimetostring(payload, 0))
        models.Log.objects.create(message=message, status='S', text=_(u'Encrypting the message using partner key %s'%message.partner.encryption_key))
        message.encrypted = True
        payload = as2utils.encrypt_payload(as2utils.canonicalize(as2utils.mimetostring(payload, 0)), message.partner.encryption_key.certificate.path , message.partner.encryption)
        payload.set_type('application/pkcs7-mime')
        content = payload.get_payload()
        pyas2init.logger.debug('Encrypted message %s payload as:\n%s'%(message.message_id,payload.as_string()))
    if message.partner.mdn:
        as2Header['disposition-notification-to'] = '*****@*****.**' 
        if message.partner.mdn_sign:			
            as2Header['disposition-notification-options'] = 'signed-receipt-protocol=required, pkcs7-signature; signed-receipt-micalg=optional, %s'%message.partner.mdn_sign
        message.mdn_mode = 'SYNC'
        if message.partner.mdn_mode == 'ASYNC':
            as2Header['receipt-delivery-option'] = pyas2init.gsettings['mdn_url']
            message.mdn_mode = 'ASYNC'
    if micContent:
        pyas2init.logger.debug("Calcualting MIC with alg %s for content:\n%s"%(micalg,micContent))
        calcMIC = getattr(hashlib, micalg.replace('-',''), hashlib.sha1)
        message.mic = calcMIC(micContent).digest().encode('base64').strip()
    as2Header.update(payload.items())
    message.headers = ''
    for key in as2Header:
        message.headers = message.headers + '%s: %s\n'%(key, as2Header[key])
    message.save()
    models.Log.objects.create(message=message, status='S', text=_(u'AS2 message has been built successfully, sending it to the partner'))
    return content 
Esempio n. 4
0
def build_message(message):
    """ Build the AS2 mime message to be sent to partner"""
    models.Log.objects.create(
        message=message, status="S", text=_(u"Build the AS2 message and header to send to the partner")
    )
    reference = "<%s>" % message.message_id
    micContent = None
    email_datetime = email.Utils.formatdate(localtime=True)
    as2Header = {
        "AS2-Version": "1.2",
        "ediint-features": "CEM",
        "MIME-Version": "1.0",
        "Message-ID": reference,
        "AS2-From": as2utils.escape_as2name(message.organization.as2_name),
        "AS2-To": as2utils.escape_as2name(message.partner.as2_name),
        "Subject": message.partner.subject,
        "Date": email_datetime,
        "recipient-address": message.partner.target_url,
        "user-agent": "PYAS2, A pythonic AS2 server",
    }
    payload = email.Message.Message()
    with open(message.payload.file, "rb") as fh:
        payload.set_payload(fh.read())
        fh.close()
    payload.set_type(message.partner.content_type)
    payload.add_header("Content-Disposition", "attachment", filename=message.payload.name)
    del payload["MIME-Version"]
    # micContent,cmicContent,content = payload.get_payload(),None,payload.get_payload()
    content = payload.get_payload()
    if message.partner.compress:
        models.Log.objects.create(message=message, status="S", text=_(u"Compressing the payload."))
        message.compressed = True
        # micContent = as2utils.canonicalize(as2utils.mimetostring(payload, 0))
        cmessage = email.Message.Message()
        cmessage.set_type("application/pkcs7-mime")
        cmessage.set_param("name", "smime.p7z")
        cmessage.set_param("smime-type", "compressed-data")
        cmessage.add_header("Content-Transfer-Encoding", "base64")
        cmessage.add_header("Content-Disposition", "attachment", filename="smime.p7z")
        cmessage.set_payload(as2utils.compress_payload(as2utils.canonicalize(as2utils.mimetostring(payload, 0))))
        content, payload = cmessage.get_payload(), cmessage
        pyas2init.logger.debug("Compressed message %s payload as:\n%s" % (message.message_id, payload.as_string()))
    if message.partner.signature:
        models.Log.objects.create(
            message=message,
            status="S",
            text=_(u"Signing the message using organzation key %s" % message.organization.signature_key),
        )
        message.signed = True
        multipart = MIMEMultipart("signed", protocol="application/pkcs7-signature")
        del multipart["MIME-Version"]
        # micContent = as2utils.canonicalize2(payload)
        micContent = as2utils.canonicalize(as2utils.mimetostring(payload, 0))
        multipart.attach(payload)
        micalg, signature = as2utils.sign_payload(
            micContent,
            str(message.organization.signature_key.certificate.path),
            str(message.organization.signature_key.certificate_passphrase),
        )
        multipart.set_param("micalg", micalg)
        multipart.attach(signature)
        multipart.as_string()
        content = as2utils.canonicalize(as2utils.extractpayload(multipart))
        payload = multipart
        pyas2init.logger.debug("Signed message %s payload as:\n%s" % (message.message_id, payload.as_string()))
    if message.partner.encryption:
        # if not message.compressed and not message.signed:
        # micContent = as2utils.canonicalize(as2utils.mimetostring(payload, 0))
        models.Log.objects.create(
            message=message,
            status="S",
            text=_(u"Encrypting the message using partner key %s" % message.partner.encryption_key),
        )
        message.encrypted = True
        payload = as2utils.encrypt_payload(
            as2utils.canonicalize(as2utils.mimetostring(payload, 0)),
            message.partner.encryption_key.certificate.path,
            message.partner.encryption,
        )
        payload.set_type("application/pkcs7-mime")
        content = payload.get_payload()
        pyas2init.logger.debug("Encrypted message %s payload as:\n%s" % (message.message_id, payload.as_string()))
    if message.partner.mdn:
        as2Header["disposition-notification-to"] = "*****@*****.**"
        if message.partner.mdn_sign:
            as2Header["disposition-notification-options"] = (
                "signed-receipt-protocol=required, pkcs7-signature; signed-receipt-micalg=optional, %s"
                % message.partner.mdn_sign
            )
        message.mdn_mode = "SYNC"
        if message.partner.mdn_mode == "ASYNC":
            as2Header["receipt-delivery-option"] = pyas2init.gsettings["mdn_url"]
            message.mdn_mode = "ASYNC"
    if micContent:
        pyas2init.logger.debug("Calcualting MIC with alg %s for content:\n%s" % (micalg, micContent))
        calcMIC = getattr(hashlib, micalg.replace("-", ""), hashlib.sha1)
        message.mic = calcMIC(micContent).digest().encode("base64").strip()
    as2Header.update(payload.items())
    message.headers = ""
    for key in as2Header:
        message.headers = message.headers + "%s: %s\n" % (key, as2Header[key])
    message.save()
    models.Log.objects.create(
        message=message, status="S", text=_(u"AS2 message has been built successfully, sending it to the partner")
    )
    return content