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
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
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
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