Source code for wer.schema

# -*- coding: utf8 -*-
from __future__ import unicode_literals

import hashlib
from os import path

from eulxml import xmlmap

from wer.helpers import DateField

REPORT_TYPES = (
    (0, 'Non Critical'),
    (1, 'Critical'),
    (2, 'Application Crash'),
    (3, 'Application Hang'),
    (4, 'Kernel Error')
)

FILE_TYPES = (
    (1, 'User Document'),
    (2, 'Other')
)


[docs]class DictMixin(object): """ Mixin class in order to export :class:`eulxml.xmlmap.XmlObject values to a Python dict"""
[docs] def to_dict(self): """ Recusively exports object values to a dict :return: `dict`of values """ if not hasattr(self, '_fields'): return self.__dict__ result = dict() for field_name, field in self._fields.items(): if isinstance(field, xmlmap.NodeField): obj = getattr(self, field_name) if obj is None: result[field_name] = None elif not hasattr(obj, 'to_dict'): result[field_name] = obj.__dict__ else: result[field_name] = obj.to_dict() elif isinstance(field, xmlmap.NodeListField): objs = getattr(self, field_name) result[field_name] = list() for obj in objs: if not hasattr(obj, 'to_dict'): result[field_name].append(obj.__dict__) else: result[field_name].append(obj.to_dict()) else: result[field_name] = getattr(self, field_name) return result
[docs]class LoaderMixin(object): """ Loading XML into object mixin """ @classmethod
[docs] def from_file(cls, file_path, validate=True): """ Creates a Python object from a XML file :param file_path: Path to the XML file :param validate: XML should be validated against the embedded XSD definition :type validate: Boolean :returns: the Python object """ return xmlmap.load_xmlobject_from_file(file_path, xmlclass=cls, validate=validate)
@classmethod
[docs] def from_string(cls, xml_string, validate=True): """ Creates a Python object from a XML string :param xml_string: XML string :param validate: XML should be validated against the embedded XSD definition :type validate: Boolean :returns: the Python object """ return xmlmap.load_xmlobject_from_string(xml_string, xmlclass=cls, validate=validate)
class XmlObject(DictMixin, xmlmap.XmlObject): pass
[docs]class MachineInfo(XmlObject): """ MachineInfo complex type """ ROOT_NAME = 'MACHINEINFO' name = xmlmap.StringField('@machinename') """ Machine name :type `string` """ os = xmlmap.StringField('@os') """ Machine operating system version :type `string` """ lcid = xmlmap.IntegerField('@lcid') """ Machine language identifier :type `int` """ oem = xmlmap.StringField('@oem', required=False) """ Optional machine OEM name :type `string` """
[docs]class ApplicationInfo(XmlObject): """ ApplicationInfo complex type """ ROOT_NAME = 'APPLICATIONINFO' name = xmlmap.StringField('@appname') """ Application name :type `string` """ path = xmlmap.StringField('@apppath') """ Application executable path :type `string` """ company = xmlmap.StringField('@appcompany', required=False) """ Optional application company :type `string` """
[docs]class EventInfo(XmlObject): """ EventInfo complex type """ ROOT_NAME = 'EVENTINFO' report_type = xmlmap.IntegerField('@reporttype') """ Report type :type `int` """ type = xmlmap.StringField('@eventtype') """ Event type :type `string` """ time = DateField('@eventtime') """ Event date :type :class:`datetime.datetime`""" name = xmlmap.StringField('@friendlyeventname', required=False) """ Friendly event name :type `string` """ description = xmlmap.StringField('@eventdescription', required=False) """ Event description :type `string` """
[docs]class Parameter(XmlObject): """ Parameter complex type """ ROOT_NAME = 'PARAMETER' id = xmlmap.IntegerField('@id') """ Parameter ID :type `int`""" name = xmlmap.StringField('@name', required=False) """ Optional paramneter name :type `string`""" value = xmlmap.StringField('@value') """ Paramneter value :type `string`"""
[docs]class SecondaryParameter(XmlObject): """ Secondary parameter complex type """ ROOT_NAME = 'SECONDARYPARAMETER' id = xmlmap.IntegerField('@id') """ Parameter ID :type `int` """ value = xmlmap.StringField('@value') """ Paramneter value :type `string` """
[docs]class File(XmlObject): """ File complex type """ ROOT_NAME = 'FILE' name = xmlmap.StringField('@filename') """ File name :type `string` """ type = xmlmap.IntegerField('@filetype') """ File type :type `int` """
[docs]class Report(LoaderMixin, XmlObject): """ Windows Error Report """ ROOT_NAME = 'WERREPORT' XSD_SCHEMA = path.join(path.dirname(__file__), 'ms-cer2.xsd') machine = xmlmap.NodeField('MACHINEINFO', MachineInfo) """ Machine informations :type :class:`wer.schema.MachineInfo` """ user = xmlmap.StringField('USERINFO/@username') """ User informations :type :class:`wer.schema.UserInfo` """ application = xmlmap.NodeField('APPLICATIONINFO', ApplicationInfo, required=False) """ Application informations :type :class:`wer.schema.ApplicationInfo` """ event = xmlmap.NodeField('EVENTINFO', EventInfo) """ Event informations :type :class:`wer.schema.EventInfo` """ parameters = xmlmap.NodeListField('SIGNATURE/PARAMETER', Parameter) """ Event parameters :type list of :class:`wer.schema.Parameter` """ secondary_parameters = xmlmap.NodeListField('SIGNATURE/SECONDARYPARAMETER', SecondaryParameter) """ Event secondary parameters :type list of :class:`wer.schema.SecondaryParameter` """ files = xmlmap.NodeListField('FILES/FILE', File) """ Event attached files :type list of :class:`wer.schema.File` """ @property def id(self): """ Computes the signature of the record, a SHA-512 of significant values :return: SHa-512 Hex string """ h = hashlib.new('sha512') for value in (self.machine.name, self.machine.os, self.user, self.application.name, self.application.path, self.event.report_type, self.event.type, self.event.time.isoformat()): h.update(str(value).encode('utf-8')) for parameter in sorted(self.parameters, key=lambda k: getattr(k, 'id')): h.update(parameter.value.encode('utf-8')) return h.hexdigest()
class ProcessVmInformation(XmlObject): ROOT_NAME = 'ProcessVmInformation' peak_virtual_size = xmlmap.IntegerField('PeakVirtualSize') virtual_size = xmlmap.IntegerField('VirtualSize') pagefault_count = xmlmap.IntegerField('PageFaultCount') peak_workingset_size = xmlmap.IntegerField('PeakWorkingSetSize') workingset_size = xmlmap.IntegerField('WorkingSetSize') quota_peak_paged_pool_usage = xmlmap.IntegerField('QuotaPeakPagedPoolUsage') quota_paged_pool_usage = xmlmap.IntegerField('QuotaPagedPoolUsage') quota_peak_nonpaged_pool_usage = xmlmap.IntegerField('QuotaPeakNonPagedPoolUsage') quota_nonpaged_pool_usage = xmlmap.IntegerField('QuotaPagedNonPoolUsage') pagefile_usage = xmlmap.IntegerField('PagefileUsage') peak_pagefile_usage = xmlmap.IntegerField('PeakPagefileUsage') private_usage = xmlmap.IntegerField('PrivateUsage') class ProcessInformation(XmlObject): ROOT_NAME = 'ProcessInformation' pid = xmlmap.IntegerField('Pid') image = xmlmap.StringField('ImageName') # Must generate more samples : bytes, string or integer ? cmd_line_signature = xmlmap.StringField('CmdLineSignature') uptime = xmlmap.IntegerField('Uptime') vm = xmlmap.NodeField('ProcessVmInformation', ProcessVmInformation) parent = xmlmap.NodeField('ParentProcess/ProcessInformation', 'self', required=False) class OSVersionInformation(XmlObject): ROOT_NAME = 'OSVersionInformation' version = xmlmap.StringField('WindowsNTVersion') build = xmlmap.IntegerField('Build') product = xmlmap.StringField('Product') edition = xmlmap.StringField('Edition') build_info = xmlmap.StringField('BuildString') revision = xmlmap.IntegerField('Revision') flavor = xmlmap.StringField('Flavor') architecture = xmlmap.StringField('Architecture') lcid = xmlmap.IntegerField('LCID') class SystemInformation(XmlObject): ROOT_NAME = 'SystemInformation' id = xmlmap.StringField('MID') manufacturer = xmlmap.StringField('SystemManufacturer') product = xmlmap.StringField('SystemProductName') bios_version = xmlmap.StringField('BIOSVersion') # TODO: Parse to date with timezone bias install_date = xmlmap.IntegerField('OSInstallDate') class SecureBootState(XmlObject): # TODO: generate more samples with secure boot enabled machines ROOT_NAME = 'SecureBootState' uefi_state = xmlmap.StringField('UEFISecureBootEnabled', required=False) class MetaParameter(XmlObject): id = xmlmap.IntegerField('substring(name(), 10)') value = xmlmap.StringField('text()') class ReportMetadata(LoaderMixin, XmlObject): ROOT_NAME = 'WERReportMetadata' XSD_SCHEMA = path.join(path.dirname(__file__), 'wer-metadata.xsd') os = xmlmap.NodeField('OSVersionInformation', OSVersionInformation) process = xmlmap.NodeField('ProcessInformation', ProcessInformation) system = xmlmap.NodeField('SystemInformation', SystemInformation) secure_boot = xmlmap.NodeField('SecureBootState', SecureBootState, required=False) parameters = xmlmap.NodeListField('ProblemSignatures/*[starts-with(name(), "Parameter")]', MetaParameter) dynamic_parameters = xmlmap.NodeListField('DynamicSignatures/*[starts-with(name(), "Parameter")]', MetaParameter) id = xmlmap.StringField('ReportInformation/Guid') created_on = xmlmap.StringField('ReportInformation/CreationTime')