mirror of https://github.com/MISP/PyMISP
parent
ac9b117f36
commit
b55370cdad
|
@ -9,6 +9,7 @@ addons:
|
||||||
packages:
|
packages:
|
||||||
- libfuzzy-dev
|
- libfuzzy-dev
|
||||||
- libemail-outlook-message-perl
|
- libemail-outlook-message-perl
|
||||||
|
- libemail-address-perl
|
||||||
|
|
||||||
python:
|
python:
|
||||||
- "3.6"
|
- "3.6"
|
||||||
|
|
|
@ -21,6 +21,10 @@ except ImportError:
|
||||||
logger = logging.getLogger('pymisp')
|
logger = logging.getLogger('pymisp')
|
||||||
|
|
||||||
|
|
||||||
|
class MISPMailObjectOutlookException(InvalidMISPObject):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class EMailObject(AbstractMISPObjectGenerator):
|
class EMailObject(AbstractMISPObjectGenerator):
|
||||||
def __init__(self, filepath: Union[Path, str] = None, pseudofile: BytesIO = None,
|
def __init__(self, filepath: Union[Path, str] = None, pseudofile: BytesIO = None,
|
||||||
attach_original_email: bool = True, **kwargs):
|
attach_original_email: bool = True, **kwargs):
|
||||||
|
@ -49,7 +53,6 @@ class EMailObject(AbstractMISPObjectGenerator):
|
||||||
pseudofile = self.__convert_outlook_msg_format(temp)
|
pseudofile = self.__convert_outlook_msg_format(temp)
|
||||||
os.unlink(temp) # remove temporary file necessary to convert formats
|
os.unlink(temp) # remove temporary file necessary to convert formats
|
||||||
converted = True
|
converted = True
|
||||||
|
|
||||||
else:
|
else:
|
||||||
raise InvalidMISPObject("File buffer (BytesIO) or a path is required.")
|
raise InvalidMISPObject("File buffer (BytesIO) or a path is required.")
|
||||||
|
|
||||||
|
@ -63,32 +66,43 @@ class EMailObject(AbstractMISPObjectGenerator):
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def __convert_outlook_msg_format(filepath: str) -> BytesIO:
|
def __convert_outlook_msg_format(filepath: str) -> BytesIO:
|
||||||
converted_file, _ = msgconvert(filepath)
|
try:
|
||||||
|
converted_file, stdout = msgconvert(filepath)
|
||||||
|
except mailparser.exceptions.MailParserOSError as e:
|
||||||
|
logger.critical(e)
|
||||||
|
raise MISPMailObjectOutlookException('In order to process parse emails in Outlook format (.msg) you need the package "libemail-outlook-message-perl" and "libemail-address-perl" (on a debian system)')
|
||||||
|
|
||||||
with open(converted_file, "rb") as f:
|
with open(converted_file, "rb") as f:
|
||||||
pseudofile = BytesIO(f.read())
|
pseudofile = BytesIO(f.read())
|
||||||
os.remove(converted_file) # delete temporary file
|
os.remove(converted_file) # delete temporary file
|
||||||
|
if pseudofile.getbuffer().nbytes == 0:
|
||||||
|
logger.critical('msgconvert created an empty file.')
|
||||||
|
if stdout:
|
||||||
|
# Probably empty, but in case it's not, let's show it
|
||||||
|
logger.critical(stdout)
|
||||||
|
raise MISPMailObjectOutlookException('You probably miss the package libemail-address-perl (on a debian system)')
|
||||||
return pseudofile
|
return pseudofile
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def attempt_decoding(bytes_io: BytesIO) -> EmailMessage:
|
def attempt_decoding(bytes_io: BytesIO) -> EmailMessage:
|
||||||
"""Attempt to decode different king of emails, for example non-ascii encoded emails."""
|
"""Attempt to decode different king of emails, for example non-ascii encoded emails."""
|
||||||
bytes = bytes_io.getvalue()
|
content_in_bytes = bytes_io.getvalue()
|
||||||
|
|
||||||
message: EmailMessage = email.message_from_bytes(bytes, policy=policy.default) # type: ignore
|
message: EmailMessage = email.message_from_bytes(content_in_bytes, policy=policy.default) # type: ignore
|
||||||
|
|
||||||
if len(message) != 0:
|
if len(message) != 0:
|
||||||
return message
|
return message
|
||||||
|
|
||||||
# Improperly encoded emails (utf-8-sig) fail silently. An empty email indicates this might be the case.
|
# Improperly encoded emails (utf-8-sig) fail silently. An empty email indicates this might be the case.
|
||||||
try:
|
try:
|
||||||
bytes.decode("ASCII")
|
content_in_bytes.decode("ASCII")
|
||||||
raise Exception("EmailObject failed to decode ASCII encoded email.")
|
raise Exception("EmailObject failed to decode ASCII encoded email.")
|
||||||
except UnicodeDecodeError:
|
except UnicodeDecodeError:
|
||||||
logger.debug("EmailObject was passed a non-ASCII encoded binary blob.")
|
logger.debug("EmailObject was passed a non-ASCII encoded binary blob.")
|
||||||
try:
|
try:
|
||||||
if bytes[:3] == b'\xef\xbb\xbf': # utf-8-sig byte-order mark (BOM)
|
if content_in_bytes[:3] == b'\xef\xbb\xbf': # utf-8-sig byte-order mark (BOM)
|
||||||
bytes = bytes.decode("utf_8_sig").encode("ASCII")
|
content_in_bytes = content_in_bytes.decode("utf_8_sig").encode("ASCII")
|
||||||
message = email.message_from_bytes(bytes, policy=policy.default) # type: ignore
|
message = email.message_from_bytes(content_in_bytes, policy=policy.default) # type: ignore
|
||||||
return message
|
return message
|
||||||
except UnicodeDecodeError:
|
except UnicodeDecodeError:
|
||||||
pass
|
pass
|
||||||
|
|
Loading…
Reference in New Issue