Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
# Make sure the MISP instance is working and the URL is valid
response = self.get_recommended_api_version()
if response.get('errors'):
logger.warning(response.get('errors')[0])
elif not response.get('version'):
logger.warning("Unable to check the recommended PyMISP version (MISP <2.4.60), please upgrade.")
else:
pymisp_version_tup = tuple(int(x) for x in __version__.split('.'))
recommended_version_tup = tuple(int(x) for x in response['version'].split('.'))
if recommended_version_tup < pymisp_version_tup[:3]:
logger.info("The version of PyMISP recommended by the MISP instance ({}) is older than the one you're using now ({}). If you have a problem, please upgrade the MISP instance or use an older PyMISP version.".format(response['version'], __version__))
elif pymisp_version_tup[:3] < recommended_version_tup:
logger.warning("The version of PyMISP recommended by the MISP instance ({}) is newer than the one you're using now ({}). Please upgrade PyMISP.".format(response['version'], __version__))
except Exception as e:
raise PyMISPError('Unable to connect to MISP ({}). Please make sure the API key and the URL are correct (http/https is required): {}'.format(self.root_url, e))
try:
self.describe_types = self.get_live_describe_types()
except Exception:
self.describe_types = self.get_local_describe_types()
self.categories = self.describe_types['categories']
self.types = self.describe_types['types']
self.category_type_mapping = self.describe_types['category_type_mappings']
self.sane_default = self.describe_types['sane_defaults']
def delete_attribute(self, attribute_id):
"""Delete an attribute, you can search by ID or UUID"""
found = False
for a in self.attributes:
if ((hasattr(a, 'id') and a.id == attribute_id)
or (hasattr(a, 'uuid') and a.uuid == attribute_id)):
a.delete()
found = True
break
if not found:
raise PyMISPError('No attribute with UUID/ID {} found.'.format(attribute_id))
def __init__(self, message):
super(PyMISPError, self).__init__(message)
self.message = message
def to_feed(self, valid_distributions=[0, 1, 2, 3, 4, 5], with_meta=False):
""" Generate a json output for MISP Feed.
Notes:
* valid_distributions only makes sense if the distribution key is set (i.e. the event is exported from a MISP instance)
"""
required = ['info', 'Orgc']
for r in required:
if not hasattr(self, r):
raise PyMISPError('The field {} is required to generate the event feed output.')
if (hasattr(self, 'distribution')
and self.distribution is not None
and int(self.distribution) not in valid_distributions):
return
to_return = super(MISPEvent, self)._to_feed()
if with_meta:
to_return['_hashes'] = []
to_return['_manifest'] = self.manifest
to_return['Orgc'] = self.Orgc._to_feed()
to_return['Tag'] = list(filter(None, [tag._to_feed() for tag in self.tags]))
if self.attributes:
to_return['Attribute'] = []
for attribute in self.attributes:
class UnknownMISPObjectTemplate(MISPObjectException):
"""Exception raised when the template is unknown"""
pass
class PyMISPInvalidFormat(PyMISPError):
pass
class MISPServerError(PyMISPError):
pass
class PyMISPNotImplementedYet(PyMISPError):
pass
class PyMISPUnexpectedResponse(PyMISPError):
pass
class PyMISPEmptyResponse(PyMISPError):
pass
pass
class SearchError(PyMISPError):
pass
class MissingDependency(PyMISPError):
pass
class NoURL(PyMISPError):
pass
class NoKey(PyMISPError):
pass
class MISPObjectException(PyMISPError):
pass
class InvalidMISPObject(MISPObjectException):
"""Exception raised when an object doesn't respect the contrains in the definition"""
pass
class UnknownMISPObjectTemplate(MISPObjectException):
"""Exception raised when the template is unknown"""
pass
def edited(self, val):
"""Set the edit flag"""
if isinstance(val, bool):
self.__edited = val
else:
raise PyMISPError('edited can only be True or False')
def attributes_statistics(self, context: str='type', percentage: bool=False):
"""Get attributes statistics from the MISP instance."""
# FIXME: https://github.com/MISP/MISP/issues/4874
if context not in ['type', 'category']:
raise PyMISPError('context can only be "type" or "category"')
if percentage:
path = f'attributes/attributeStatistics/{context}/true'
else:
path = f'attributes/attributeStatistics/{context}'
response = self._prepare_request('GET', path)
return self._check_response(response, expect_json=True)
def load(self, json_event, validate=False, metadata_only=False):
"""Load a JSON dump from a pseudo file or a JSON string"""
if hasattr(json_event, 'read'):
# python2 and python3 compatible to find if we have a file
json_event = json_event.read()
if isinstance(json_event, (basestring, bytes)):
if OLD_PY3 and isinstance(json_event, bytes):
json_event = json_event.decode()
json_event = json.loads(json_event)
if json_event.get('response'):
event = json_event.get('response')[0]
else:
event = json_event
if not event:
raise PyMISPError('Invalid event')
if metadata_only:
event.pop('Attribute', None)
event.pop('Object', None)
self.from_dict(**event)
if validate:
jsonschema.validate(json.loads(self.to_json()), self.__json_schema)
def attributes(self, attributes):
if all(isinstance(x, MISPAttribute) for x in attributes):
self.Attribute = attributes
else:
raise PyMISPError('All the attributes have to be of type MISPAttribute.')