OwlCyberSecurity - MANAGER
Edit File: logAnalysis.py
## # Copyright (c) 2012-2017 Apple Inc. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. ## # Adjust method names # PROPFINDs METHOD_PROPFIND_CALENDAR_HOME = "PROPFIND Calendar Home" METHOD_PROPFIND_CACHED_CALENDAR_HOME = "PROPFIND cached Calendar Home" METHOD_PROPFIND_CALENDAR = "PROPFIND Calendar" METHOD_PROPFIND_INBOX = "PROPFIND Inbox" METHOD_PROPFIND_ADDRESSBOOK_HOME = "PROPFIND Adbk Home" METHOD_PROPFIND_CACHED_ADDRESSBOOK_HOME = "PROPFIND cached Adbk Home" METHOD_PROPFIND_ADDRESSBOOK = "PROPFIND Adbk" METHOD_PROPFIND_DIRECTORY = "PROPFIND Directory" METHOD_PROPFIND_PRINCIPALS = "PROPFIND Principals" METHOD_PROPFIND_CACHED_PRINCIPALS = "PROPFIND cached Principals" # PROPPATCHs METHOD_PROPPATCH_CALENDAR = "PROPPATCH Calendar" METHOD_PROPPATCH_ADDRESSBOOK = "PROPPATCH Adbk Home" # REPORTs METHOD_REPORT_CALENDAR_MULTIGET = "REPORT cal-multi" METHOD_REPORT_CALENDAR_QUERY = "REPORT cal-query" METHOD_REPORT_CALENDAR_FREEBUSY = "REPORT freebusy" METHOD_REPORT_CALENDAR_HOME_SYNC = "REPORT cal-home-sync" METHOD_REPORT_CALENDAR_SYNC = "REPORT cal-sync" METHOD_REPORT_ADDRESSBOOK_MULTIGET = "REPORT adbk-multi" METHOD_REPORT_ADDRESSBOOK_QUERY = "REPORT adbk-query" METHOD_REPORT_DIRECTORY_QUERY = "REPORT dir-query" METHOD_REPORT_ADDRESSBOOK_HOME_SYNC = "REPORT adbk-home-sync" METHOD_REPORT_ADDRESSBOOK_SYNC = "REPORT adbk-sync" METHOD_REPORT_P_SEARCH_P_SET = "REPORT p-set" METHOD_REPORT_P_P_SEARCH = "REPORT p-search" METHOD_REPORT_EXPAND_P = "REPORT expand" # POSTs METHOD_POST_CALENDAR_HOME = "POST Calendar Home" METHOD_POST_CALENDAR = "POST Calendar" METHOD_POST_CALENDAR_ADD_MEMBER = "POST Calendar-add" METHOD_POST_CALENDAR_OBJECT = "POST ics" METHOD_POST_CALENDAR_OBJECT_SPLIT = "POST split" METHOD_POST_CALENDAR_OBJECT_ATTACHMENT_ADD = "POST att-add" METHOD_POST_CALENDAR_OBJECT_ATTACHMENT_UPDATE = "POST att-update" METHOD_POST_CALENDAR_OBJECT_ATTACHMENT_REMOVE = "POST att-remove" METHOD_POST_ADDRESSBOOK_HOME = "POST Adbk Home" METHOD_POST_ADDRESSBOOK = "POST Adbk" METHOD_POST_ADDRESSBOOK_ADD_MEMBER = "POST Adbk-add" METHOD_POST_ISCHEDULE_FREEBUSY = "POST Freebusy iSchedule" METHOD_POST_ISCHEDULE = "POST iSchedule" METHOD_POST_TIMEZONES = "POST Timezones" METHOD_POST_FREEBUSY = "POST Freebusy" METHOD_POST_ORGANIZER = "POST Organizer" METHOD_POST_ATTENDEE = "POST Attendee" METHOD_POST_OUTBOX = "POST Outbox" METHOD_POST_APNS = "POST apns" METHOD_POST_CONDUIT = "POST conduit" # PUTs METHOD_PUT_ICS = "PUT ics" METHOD_PUT_ORGANIZER = "PUT Organizer" METHOD_PUT_ATTENDEE = "PUT Attendee" METHOD_PUT_DROPBOX = "PUT dropbox" METHOD_PUT_VCF = "PUT VCF" # GETs METHOD_GET_CALENDAR_HOME = "GET Calendar Home" METHOD_GET_CALENDAR = "GET Calendar" METHOD_GET_ICS = "GET ics" METHOD_GET_INBOX_ICS = "GET inbox ics" METHOD_GET_DROPBOX = "GET dropbox" METHOD_GET_ADDRESSBOOK_HOME = "GET Adbk Home" METHOD_GET_ADDRESSBOOK = "GET Adbk" METHOD_GET_VCF = "GET VCF" METHOD_GET_TIMEZONES = "GET Timezones" # DELETEs METHOD_DELETE_CALENDAR_HOME = "DELETE Calendar Home" METHOD_DELETE_CALENDAR = "DELETE Calendar" METHOD_DELETE_ICS = "DELETE ics" METHOD_DELETE_INBOX_ICS = "DELETE inbox ics" METHOD_DELETE_DROPBOX = "DELETE dropbox" METHOD_DELETE_ADDRESSBOOK_HOME = "DELETE Adbk Home" METHOD_DELETE_ADDRESSBOOK = "DELETE Adbk" METHOD_DELETE_VCF = "DELETE vcf" def getAdjustedMethodName(stats, method=None, uri=None): if method is None: method = stats["method"] if uri is None: uri = stats["uri"] uribits = uri.rstrip("/").split('/')[1:] if len(uribits) == 0: uribits = [uri] calendar_specials = ("attachments", "dropbox", "notification", "freebusy", "outbox",) adbk_specials = ("notification",) def _PROPFIND(): cached = "cached" in stats if uribits[0] == "calendars": if len(uribits) == 3: return METHOD_PROPFIND_CACHED_CALENDAR_HOME if cached else METHOD_PROPFIND_CALENDAR_HOME elif len(uribits) > 3: if uribits[3] in calendar_specials: return "PROPFIND %s" % (uribits[3],) elif len(uribits) == 4: if uribits[3] == "inbox": return METHOD_PROPFIND_INBOX else: return METHOD_PROPFIND_CALENDAR elif uribits[0] == "addressbooks": if len(uribits) == 3: return METHOD_PROPFIND_CACHED_ADDRESSBOOK_HOME if cached else METHOD_PROPFIND_ADDRESSBOOK_HOME elif len(uribits) > 3: if uribits[3] in adbk_specials: return "PROPFIND %s" % (uribits[3],) elif len(uribits) == 4: return METHOD_PROPFIND_ADDRESSBOOK elif uribits[0] == "directory": return METHOD_PROPFIND_DIRECTORY elif uribits[0] == "principals": return METHOD_PROPFIND_CACHED_PRINCIPALS if cached else METHOD_PROPFIND_PRINCIPALS return method def _REPORT(): if "(" in method: report_type = method.split("}" if "}" in method else ":")[1][:-1] if report_type == "addressbook-query": if uribits[0] == "directory": report_type = "directory-query" if report_type == "sync-collection": if uribits[0] == "calendars": if len(uribits) == 3: report_type = "cal-home-sync" else: report_type = "cal-sync" elif uribits[0] == "addressbooks": if len(uribits) == 3: report_type = "adbk-home-sync" else: report_type = "adbk-sync" mappedNames = { "calendar-multiget": METHOD_REPORT_CALENDAR_MULTIGET, "calendar-query": METHOD_REPORT_CALENDAR_QUERY, "free-busy-query": METHOD_REPORT_CALENDAR_FREEBUSY, "cal-home-sync": METHOD_REPORT_CALENDAR_HOME_SYNC, "cal-sync": METHOD_REPORT_CALENDAR_SYNC, "addressbook-multiget": METHOD_REPORT_ADDRESSBOOK_MULTIGET, "addressbook-query": METHOD_REPORT_ADDRESSBOOK_QUERY, "directory-query": METHOD_REPORT_DIRECTORY_QUERY, "adbk-home-sync": METHOD_REPORT_ADDRESSBOOK_HOME_SYNC, "adbk-sync": METHOD_REPORT_ADDRESSBOOK_SYNC, "principal-search-property-set": METHOD_REPORT_P_SEARCH_P_SET, "principal-property-search": METHOD_REPORT_P_P_SEARCH, "expand-property": METHOD_REPORT_EXPAND_P, } return mappedNames.get(report_type, "REPORT %s" % (report_type,)) return method def _PROPPATCH(): if uribits[0] == "calendars": return METHOD_PROPPATCH_CALENDAR elif uribits[0] == "addressbooks": return METHOD_PROPPATCH_ADDRESSBOOK return method def _POST(): if uribits[0] == "calendars": if "(" in method: post_type = method.split("(")[1][:-1] mappedNames = { "add-member": METHOD_POST_CALENDAR_ADD_MEMBER, "split": METHOD_POST_CALENDAR_OBJECT_SPLIT, "attachment-add": METHOD_POST_CALENDAR_OBJECT_ATTACHMENT_ADD, "attachment-update": METHOD_POST_CALENDAR_OBJECT_ATTACHMENT_UPDATE, "attachment-remove": METHOD_POST_CALENDAR_OBJECT_ATTACHMENT_REMOVE, } return mappedNames.get(post_type, "POST %s" % (post_type,)) elif len(uribits) == 3: return METHOD_POST_CALENDAR_HOME elif len(uribits) == 4: if uribits[3] == "outbox": if "recipients" in stats: return METHOD_POST_FREEBUSY elif "freebusy" in stats: return METHOD_POST_FREEBUSY elif "itip.request" in stats or "itip.cancel" in stats: return METHOD_POST_ORGANIZER elif "itip.reply" in stats: return METHOD_POST_ATTENDEE else: return METHOD_POST_OUTBOX elif uribits[3] in calendar_specials: pass else: return METHOD_POST_CALENDAR elif len(uribits) == 5: return METHOD_POST_CALENDAR_OBJECT elif uribits[0] == "addressbooks": if len(uribits) == 3: return METHOD_POST_ADDRESSBOOK_HOME elif len(uribits) == 4: if uribits[3] in adbk_specials: pass else: return METHOD_POST_ADDRESSBOOK elif uribits[0] == "ischedule": if "fb-cached" in stats or "fb-uncached" in stats or "freebusy" in stats: return METHOD_POST_ISCHEDULE_FREEBUSY else: return METHOD_POST_ISCHEDULE elif uribits[0].startswith("timezones"): return METHOD_POST_TIMEZONES elif uribits[0].startswith("apns"): return METHOD_POST_APNS elif uribits[0].startswith("conduit"): return METHOD_POST_CONDUIT return method def _PUT(): if uribits[0] == "calendars": if len(uribits) > 3: if uribits[3] in calendar_specials: return "PUT %s" % (uribits[3],) elif len(uribits) == 4: pass else: if "itip.requests" in stats: return METHOD_PUT_ORGANIZER elif "itip.reply" in stats: return METHOD_PUT_ATTENDEE else: return METHOD_PUT_ICS elif uribits[0] == "addressbooks": if len(uribits) > 3: if uribits[3] in adbk_specials: return "PUT %s" % (uribits[3],) elif len(uribits) == 4: pass else: return METHOD_PUT_VCF return method def _GET(): if uribits[0] == "calendars": if len(uribits) == 3: return METHOD_GET_CALENDAR_HOME elif len(uribits) > 3: if uribits[3] in calendar_specials: return "GET %s" % (uribits[3],) elif len(uribits) == 4: return METHOD_GET_CALENDAR elif uribits[3] == "inbox": return METHOD_GET_INBOX_ICS else: return METHOD_GET_ICS elif uribits[0] == "addressbooks": if len(uribits) == 3: return METHOD_GET_ADDRESSBOOK_HOME elif len(uribits) > 3: if uribits[3] in adbk_specials: return "GET %s" % (uribits[3],) elif len(uribits) == 4: return METHOD_GET_ADDRESSBOOK else: return METHOD_GET_VCF elif uribits[0].startswith("timezones"): return METHOD_GET_TIMEZONES return method def _DELETE(): if uribits[0] == "calendars": if len(uribits) == 3: return METHOD_DELETE_CALENDAR_HOME elif len(uribits) > 3: if uribits[3] in calendar_specials: return "DELETE %s" % (uribits[3],) elif len(uribits) == 4: return METHOD_DELETE_CALENDAR elif uribits[3] == "inbox": return METHOD_DELETE_INBOX_ICS else: return METHOD_DELETE_ICS elif uribits[0] == "addressbooks": if len(uribits) == 3: return METHOD_DELETE_ADDRESSBOOK_HOME elif len(uribits) > 3: if uribits[3] in adbk_specials: return "DELETE %s" % (uribits[3],) elif len(uribits) == 4: return METHOD_DELETE_ADDRESSBOOK else: return METHOD_DELETE_VCF return method def _ANY(): return method return { "DELETE": _DELETE, "GET": _GET, "POST": _POST, "PROPFIND": _PROPFIND, "PROPPATCH": _PROPPATCH, "PUT": _PUT, "REPORT": _REPORT, }.get(method.split("(")[0], _ANY)() osClients = ( "Mac OS X/", "Mac+OS+X/", "Mac_OS_X/", "iOS/", ) versionClients = ( "iCal/", "iPhone/", "CalendarAgent/", "Calendar/", "CoreDAV/", "Safari/", "dataaccessd/", "Preferences/", "curl/", "DAVKit/", ) quickclients = ( ("InterMapper/", "InterMapper"), ("CardDAVPlugin/", "CardDAVPlugin"), ("Address%20Book/", "AddressBook"), ("AddressBook/", "AddressBook"), ("Mail/", "Mail"), ("iChat/", "iChat"), ) def getAdjustedClientName(stats): userAgent = stats["userAgent"] os = "" for client in osClients: index = userAgent.find(client) if index != -1: l = len(client) endex = userAgent.find(' ', index + l) os = (userAgent[index:] if endex == -1 else userAgent[index:endex]) + " " for client in versionClients: index = userAgent.find(client) if index != -1: if os: return os + client[:-1] else: l = len(client) endex = userAgent.find(' ', index + l) return os + (userAgent[index:] if endex == -1 else userAgent[index:endex]) for quick, result in quickclients: index = userAgent.find(quick) if index != -1: return os + result return userAgent[:20]