mirror of https://github.com/MISP/PyMISP
new: Properly implement the Email object creator
parent
003417a50e
commit
ab54c85509
|
@ -1 +1 @@
|
||||||
Subproject commit 196991c73fd35fef76822102424c2f65f95443f3
|
Subproject commit 956e6493158565426c228bf1dadb3c60a738288e
|
|
@ -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)"""
|
||||||
|
|
|
@ -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'])
|
||||||
|
|
Loading…
Reference in New Issue