new: Properly implement the Email object creator

pull/232/head
Raphaël Vinot 2018-05-03 20:51:04 +02:00
parent 003417a50e
commit ab54c85509
3 changed files with 33 additions and 9 deletions

@ -1 +1 @@
Subproject commit 196991c73fd35fef76822102424c2f65f95443f3 Subproject commit 956e6493158565426c228bf1dadb3c60a738288e

View File

@ -101,6 +101,7 @@ class MISPAttribute(AbstractMISP):
self.__category_type_mapping = describe_types['category_type_mappings'] self.__category_type_mapping = describe_types['category_type_mappings']
self.__sane_default = describe_types['sane_defaults'] self.__sane_default = describe_types['sane_defaults']
self.__strict = strict self.__strict = strict
self.uuid = str(uuid.uuid4())
self.ShadowAttribute = [] self.ShadowAttribute = []
@property @property
@ -605,14 +606,18 @@ class MISPEvent(AbstractMISP):
def add_attribute(self, type, value, **kwargs): def add_attribute(self, type, value, **kwargs):
"""Add an attribute. type and value are required but you can pass all """Add an attribute. type and value are required but you can pass all
other parameters supported by MISPAttribute""" other parameters supported by MISPAttribute"""
attr_list = []
if isinstance(value, list): if isinstance(value, list):
for a in value: attr_list = [self.add_attribute(type=type, value=a, **kwargs) for a in value]
self.add_attribute(type=type, value=a, **kwargs)
else: else:
attribute = MISPAttribute() attribute = MISPAttribute()
attribute.from_dict(type=type, value=value, **kwargs) attribute.from_dict(type=type, value=value, **kwargs)
self.attributes.append(attribute) self.attributes.append(attribute)
self.edited = True self.edited = True
if attr_list:
return attr_list
else:
return attribute
def get_object_by_id(self, object_id): def get_object_by_id(self, object_id):
"""Get an object by ID (the ID is the one set by the server when creating the new object)""" """Get an object by ID (the ID is the one set by the server when creating the new object)"""

View File

@ -5,28 +5,46 @@ from ..exceptions import InvalidMISPObject
from .abstractgenerator import AbstractMISPObjectGenerator from .abstractgenerator import AbstractMISPObjectGenerator
from io import BytesIO from io import BytesIO
import logging import logging
from email import message_from_bytes from email import message_from_bytes, policy
logger = logging.getLogger('pymisp') logger = logging.getLogger('pymisp')
class EMailObject(AbstractMISPObjectGenerator): class EMailObject(AbstractMISPObjectGenerator):
def __init__(self, filepath=None, pseudofile=None, standalone=True, **kwargs): def __init__(self, filepath=None, pseudofile=None, attach_original_email=True, standalone=True, **kwargs):
if filepath: if filepath:
with open(filepath, 'rb') as f: with open(filepath, 'rb') as f:
pseudofile = BytesIO(f.read()) self.__pseudofile = BytesIO(f.read())
elif pseudofile and isinstance(pseudofile, BytesIO): elif pseudofile and isinstance(pseudofile, BytesIO):
pseudofile = pseudofile self.__pseudofile = pseudofile
else: else:
raise InvalidMISPObject('File buffer (BytesIO) or a path is required.') raise InvalidMISPObject('File buffer (BytesIO) or a path is required.')
# PY3 way: # PY3 way:
# super().__init__('file') # super().__init__('file')
super(EMailObject, self).__init__('email', standalone=standalone, **kwargs) super(EMailObject, self).__init__('email', standalone=standalone, **kwargs)
self.__email = message_from_bytes(pseudofile.getvalue()) self.__email = message_from_bytes(self.__pseudofile.getvalue(), policy=policy.default)
if attach_original_email:
self.add_attribute('eml', value='Full email', data=self.__pseudofile)
self.generate_attributes() self.generate_attributes()
@property
def email(self):
return self.__email
def force_eml(self, pseudofile):
self.eml.data = pseudofile
@property
def attachments(self):
to_return = []
for attachment in self.__email.iter_attachments():
to_return.append((attachment.get_filename(), BytesIO(attachment.get_content().as_bytes())))
return to_return
def generate_attributes(self): def generate_attributes(self):
if self.__email.get_body():
self.add_attribute('email-body', value=self.__email.get_body().as_string())
if 'Reply-To' in self.__email: if 'Reply-To' in self.__email:
self.add_attribute('reply-to', value=self.__email['Reply-To']) self.add_attribute('reply-to', value=self.__email['Reply-To'])
if 'Message-ID' in self.__email: if 'Message-ID' in self.__email:
@ -44,4 +62,5 @@ class EMailObject(AbstractMISPObjectGenerator):
self.add_attribute('from', value=e_from.strip()) self.add_attribute('from', value=e_from.strip())
if 'Return-Path' in self.__email: if 'Return-Path' in self.__email:
self.add_attribute('return-path', value=self.__email['Return-Path']) self.add_attribute('return-path', value=self.__email['Return-Path'])
# TODO: self.add_attribute('attachment', value=) if 'User-Agent' in self.__email:
self.add_attribute('user-agent', value=self.__email['User-Agent'])