From 4f4b7f2bdcb7916edf64554a41185fc34660b2da Mon Sep 17 00:00:00 2001 From: Daniel Dayley Date: Tue, 26 May 2020 12:26:01 -0600 Subject: [PATCH] More code cleanup --- ifxlookup => ifxlookup.py | 28 +++++++++------------ plugins/aruba.py | 52 +++++++++++++++++++-------------------- plugins/bluecat.py | 38 ++++++++++++++-------------- plugins/dns.py | 6 ++--- plugins/f5.py | 38 ++++++++++++++-------------- plugins/guid_channels.py | 12 ++++----- plugins/openvpn.py | 50 ++++++++++++++++++++++++------------- plugins/shodan.py | 6 ++--- plugins/vmware.py | 10 +++----- servicebase.py | 14 +++++------ 10 files changed, 130 insertions(+), 124 deletions(-) rename ifxlookup => ifxlookup.py (92%) diff --git a/ifxlookup b/ifxlookup.py similarity index 92% rename from ifxlookup rename to ifxlookup.py index 27ca960..d57681d 100755 --- a/ifxlookup +++ b/ifxlookup.py @@ -107,8 +107,10 @@ class IFXLookup(): """Returns a map of plugins configured to use in the lookup.""" return self._delegate_map - def search_plugins(self,directory='/'.join(os.path.realpath(__file__).split('/')[:-1]) + '/' + 'plugins') : + def search_plugins(self,directory=None) : """Searches a given directory for compatible plugins and returns a map of available plugin names and classes""" + if not directory : + directory = '/'.join(os.path.realpath(__file__).split('/')[:-1]) + '/' + 'plugins' directory = os.path.normpath(os.path.expanduser(os.path.expandvars(directory))) name_map = {} candidates = {x.split('.')[0]:x for x in os.listdir(directory) if x.endswith('.py') and x != 'servicebase.py'} @@ -126,18 +128,6 @@ class IFXLookup(): raise TypeError('argument \'config\' should be of type dict') self._config.update(config) - def load_config_from_file(self,config=DEFAULT_CONFIG) : - """Loads a JSON or YAML file containing a configuration map for plugins. Used to configure several plugins at once.""" - if config : - file_descriptor = open(os.path.normpath(os.path.expanduser(os.path.expandvars(config)))) - try : - file_descriptor = open(os.path.normpath(os.path.expanduser(os.path.expandvars(config)))) - total_config = json.load(file_descriptor) - except json.decoder.JSONDecodeError as exception : - file_descriptor = open(os.path.normpath(os.path.expanduser(os.path.expandvars(config)))) - total_config = yaml.safe_load(file_descriptor) - self._config.update(total_config) - def dump_config(self) : """Returns the current configuration state. This likely contains sensitive information such as API keys.""" return self._config @@ -206,15 +196,19 @@ class IFXLookup(): report = {} for subject in subjects : report.update({subject:delegate.lookup(subject)}) - if delegate.error != [] : - error_info.update({delegatename:delegate.error}) - if delegate.warn != [] : - warn_info.update({delegatename:delegate.warn}) + if delegate._error != [] : + error_info.update({delegatename:delegate._error}) + if delegate._warn != [] : + warn_info.update({delegatename:delegate._warn}) report.update(error_info) report.update(warn_info) if report and report != {}: final_report.update({delegatename:report}) + if len(error_info) > 0 : + final_report.update({'error':error_info}) + if len(warn_info) > 0 : + final_report.update({'warning':warn_info}) # If caching is enabled prevent shutdown. Otherwise shutdown. if not self._caching : self.__shutdown_plugins() diff --git a/plugins/aruba.py b/plugins/aruba.py index 95e446c..e32917a 100644 --- a/plugins/aruba.py +++ b/plugins/aruba.py @@ -6,15 +6,15 @@ import xml.etree.ElementTree as ElementTree class ServiceDelegate(ServiceBase) : - host = None - api_session = requests.session() - session_key = None - query_page_size = 200 - clients_fields = ['sta_mac_address', 'client_ht_phy_type', 'openflow_state', 'client_ip_address', 'client_user_name', 'client_dev_type', 'client_ap_location', 'client_conn_port', 'client_conn_type', 'client_timestamp', 'client_role_name', 'client_active_uac', 'client_standby_uac', 'ap_cluster_name', 'client_health', 'total_moves', 'successful_moves', 'steer_capability', 'ssid', 'ap_name', 'channel', 'channel_str', 'channel_busy', 'tx_time', 'rx_time', 'channel_free', 'channel_interference', 'current_channel_utilization', 'radio_band', 'bssid', 'speed', 'max_negotiated_rate', 'noise_floor', 'radio_ht_phy_type', 'snr', 'total_data_frames', 'total_data_bytes', 'avg_data_rate', 'tx_avg_data_rate', 'rx_avg_data_rate', 'tx_frames_transmitted', 'tx_frames_dropped', 'tx_bytes_transmitted', 'tx_bytes_dropped', 'tx_time_transmitted', 'tx_time_dropped', 'tx_data_transmitted', 'tx_data_dropped', 'tx_data_retried', 'tx_data_transmitted_retried', 'tx_data_bytes_transmitted', 'tx_abs_data_bytes', 'tx_data_bytes_dropped', 'tx_time_data_transmitted', 'tx_time_data_dropped', 'tx_mgmt', 'rx_frames', 'rx_bytes', 'rx_data', 'rx_data_bytes', 'rx_abs_data_bytes', 'rx_data_retried', 'tx_data_frame_rate_dist', 'rx_data_frame_rate_dist', 'tx_data_bytes_rate_dist', 'rx_data_bytes_rate_dist', 'connection_type_classification', 'total_data_throughput', 'tx_data_throughput', 'rx_data_throughput', 'client_auth_type', 'client_auth_subtype', 'client_encrypt_type', 'client_fwd_mode'] - aps_fields = ['mon_ap', 'mon_bssid', 'mon_radio_phy_type', 'mon_ssid', 'mon_radio_band', 'mon_ap_current_channel', 'mon_ht_sec_channel', 'mon_sta_count', 'mon_ap_classification', 'mon_ap_match_conf_level', 'mon_ap_encr', 'mon_ap_encr_auth', 'mon_ap_encr_cipher', 'mon_ap_is_dos', 'mon_ap_type', 'mon_ap_status', 'mon_is_ibss', 'mon_ap_create_time', 'mon_ap_match_type', 'mon_ap_match_method', 'mon_ap_match_name', 'mon_ap_match_time', 'wms_event_count'] - justip_fields = ['client_ip_address'] - aruba_hosts = [] - aruba_basestations = [] + _host = None + _api_session = requests.session() + _session_key = None + _query_page_size = 200 + _clients_fields = ['sta_mac_address', 'client_ht_phy_type', 'openflow_state', 'client_ip_address', 'client_user_name', 'client_dev_type', 'client_ap_location', 'client_conn_port', 'client_conn_type', 'client_timestamp', 'client_role_name', 'client_active_uac', 'client_standby_uac', 'ap_cluster_name', 'client_health', 'total_moves', 'successful_moves', 'steer_capability', 'ssid', 'ap_name', 'channel', 'channel_str', 'channel_busy', 'tx_time', 'rx_time', 'channel_free', 'channel_interference', 'current_channel_utilization', 'radio_band', 'bssid', 'speed', 'max_negotiated_rate', 'noise_floor', 'radio_ht_phy_type', 'snr', 'total_data_frames', 'total_data_bytes', 'avg_data_rate', 'tx_avg_data_rate', 'rx_avg_data_rate', 'tx_frames_transmitted', 'tx_frames_dropped', 'tx_bytes_transmitted', 'tx_bytes_dropped', 'tx_time_transmitted', 'tx_time_dropped', 'tx_data_transmitted', 'tx_data_dropped', 'tx_data_retried', 'tx_data_transmitted_retried', 'tx_data_bytes_transmitted', 'tx_abs_data_bytes', 'tx_data_bytes_dropped', 'tx_time_data_transmitted', 'tx_time_data_dropped', 'tx_mgmt', 'rx_frames', 'rx_bytes', 'rx_data', 'rx_data_bytes', 'rx_abs_data_bytes', 'rx_data_retried', 'tx_data_frame_rate_dist', 'rx_data_frame_rate_dist', 'tx_data_bytes_rate_dist', 'rx_data_bytes_rate_dist', 'connection_type_classification', 'total_data_throughput', 'tx_data_throughput', 'rx_data_throughput', 'client_auth_type', 'client_auth_subtype', 'client_encrypt_type', 'client_fwd_mode'] + _aps_fields = ['mon_ap', 'mon_bssid', 'mon_radio_phy_type', 'mon_ssid', 'mon_radio_band', 'mon_ap_current_channel', 'mon_ht_sec_channel', 'mon_sta_count', 'mon_ap_classification', 'mon_ap_match_conf_level', 'mon_ap_encr', 'mon_ap_encr_auth', 'mon_ap_encr_cipher', 'mon_ap_is_dos', 'mon_ap_type', 'mon_ap_status', 'mon_is_ibss', 'mon_ap_create_time', 'mon_ap_match_type', 'mon_ap_match_method', 'mon_ap_match_name', 'mon_ap_match_time', 'wms_event_count'] + _justip_fields = ['client_ip_address'] + _aruba_hosts = [] + _aruba_basestations = [] def get_arguments(cls) : """Returns an array of information used to construct an argumentparser argument.""" @@ -22,11 +22,11 @@ class ServiceDelegate(ServiceBase) : def startup(self) : for requirement in ['host','username','key'] : - if requirement not in self.config or (requirement in self.config and (self.config[requirement] is '' or type(self.config[requirement]) is not str)): - self.error.append('Missing required config option ' + requirement) + if requirement not in self._config or (requirement in self._config and (self._config[requirement] is '' or type(self._config[requirement]) is not str)): + self._error.append('Missing required config option ' + requirement) return - self.host = self.config['host'] - self.start_session(self.config['host'],self.config['username'],self.config['key']) + self._host = self._config['host'] + self.start_session(self._config['host'],self._config['username'],self._config['key']) clientsquery = 'backend-observer-sta-19' clientssortfield = 'client_user_name' clientsfilter = 'client_conn_type not_equals 0' @@ -36,9 +36,9 @@ class ServiceDelegate(ServiceBase) : apsfilter = 'mon_ap_status equals 1' apsdevicetype = 'mon_bssid' self.debug('Retrieving list of Aruba\'s detected basestations...',1) - self.aruba_basestations = self.perform_list_query(apsquery,self.aps_fields,apssortfield,apsfilter,apsdevicetype) + self._aruba_basestations = self.perform_list_query(apsquery,self._aps_fields,apssortfield,apsfilter,apsdevicetype) self.debug('Retrieving list of Aruba connected clients...',1) - self.aruba_hosts = self.perform_list_query(clientsquery,self.clients_fields,clientssortfield,clientsfilter,clientsdevicetype) + self._aruba_hosts = self.perform_list_query(clientsquery,self._clients_fields,clientssortfield,clientsfilter,clientsdevicetype) self.debug('Searching Aruba information...',1) def lookup(self,subject) : @@ -50,11 +50,11 @@ class ServiceDelegate(ServiceBase) : # By IP if 'dns' in self.hints and subject in self.hints['dns'] and self.hints['dns'][subject]['addresses'] : for ip in self.hints['dns'][subject]['addresses'] : - for entry in self.aruba_basestations : + for entry in self._aruba_basestations : if ip in entry.values() : return entry # By value - for entry in self.aruba_basestations : + for entry in self._aruba_basestations : lowercase_values = [x.lower() for x in entry.values() if type(x) is str] all_values = lowercase_values + [x for x in entry.values() if type(x) is not str] for value in all_values : @@ -64,11 +64,11 @@ class ServiceDelegate(ServiceBase) : # By IP if 'dns' in self.hints and subject in self.hints['dns'] and self.hints['dns'][subject]['addresses'] : for ip in self.hints['dns'][subject]['addresses'] : - for entry in self.aruba_hosts : + for entry in self._aruba_hosts : if ip in entry.values() : return entry # By value - for entry in self.aruba_hosts : + for entry in self._aruba_hosts : lowercase_values = [x.lower() for x in entry.values() if type(x) is str] all_values = lowercase_values + [x for x in entry.values() if type(x) is not str] for value in all_values : @@ -80,9 +80,9 @@ class ServiceDelegate(ServiceBase) : def start_session(self,host,username,key) : headers = { 'Content-Type': 'application/x-www-form-urlencoded' } data = 'opcode=login&uid=' + username + '&passwd=' + key - self.api_session.post('https://' + host + '/screens/wms/wms.login',verify=False,headers=headers,data=data) - if 'SESSION' in self.api_session.cookies.get_dict() : - self.session_key = self.api_session.cookies.get_dict()['SESSION'] + self._api_session.post('https://' + host + '/screens/wms/wms.login',verify=False,headers=headers,data=data) + if 'SESSION' in self._api_session.cookies.get_dict() : + self._session_key = self._api_session.cookies.get_dict()['SESSION'] def perform_list_query(self,queryname,columnlist,sortfield,queryfilter,devicetype) : """"Performs a list-type XML query against the Aruba UI API""" @@ -128,9 +128,9 @@ class ServiceDelegate(ServiceBase) : allitems = [] while not finished : start_row.text = str(nextstart) - num_rows.text = str(self.query_page_size) - datapayload = ''.join(['query=',tostring(aruba_queries).decode(),'&UIDARUBA=',self.session_key]) - page = self.api_session.post('https://' + self.host + '/screens/cmnutil/execUiQuery.xml',verify=False,timeout=1,data=datapayload) + num_rows.text = str(self._query_page_size) + datapayload = ''.join(['query=',tostring(aruba_queries).decode(),'&UIDARUBA=',self._session_key]) + page = self._api_session.post('https://' + self._host + '/screens/cmnutil/execUiQuery.xml',verify=False,timeout=1,data=datapayload) self.debug('Got a page of results from Aruba host...',3) if page.status_code == 100 or page.status_code == 200 : pagecontents = ElementTree.fromstring(page.text) @@ -151,7 +151,7 @@ class ServiceDelegate(ServiceBase) : finished = True if page.status_code != 100 and page.status_code !=200 : finished = True - nextstart = nextstart + self.query_page_size + nextstart = nextstart + self._query_page_size else : finished = True self.debug('Retrieved ' + str((len(allitems))) + ' results from query',2) diff --git a/plugins/bluecat.py b/plugins/bluecat.py index 91580e3..75db6c0 100644 --- a/plugins/bluecat.py +++ b/plugins/bluecat.py @@ -6,42 +6,42 @@ import json class ServiceDelegate(ServiceBase) : current_auth_header = None - return_payload = {} - host = None + _return_payload = {} + _host = None def get_arguments(cls) : return ['-b', '--bluecat', 'store_true', 'Return network information about the subject (bluecat)'] def startup(self) : for requirement in ['host','username','key'] : - if requirement not in self.config or (requirement in self.config and (self.config[requirement] is '' or type(self.config[requirement]) is not str)): - self.error.append('Missing required config option ' + requirement) + if requirement not in self._config or (requirement in self._config and (self._config[requirement] is '' or type(self._config[requirement]) is not str)): + self._error.append('Missing required config option ' + requirement) return - self.host = self.config['host'] - self.current_auth_header = self.get_bc_auth_header(self.config['host'],self.config['username'],self.config['key']) + self._host = self._config['host'] + self._current_auth_header = self.get_bc_auth_header(self._config['host'],self._config['username'],self._config['key']) self.debug('Searching BlueCat for hosts...',1) def lookup(self,subject) : - self.return_payload = {} - if self.current_auth_header : + self._return_payload = {} + if self._current_auth_header : object = self.search_bc_object(subject) if object : - self.return_payload.update({'object':object}) + self._return_payload.update({'object':object}) parent = self.search_bc_parent_object(subject) if parent : - self.return_payload.update({'parent':parent}) - if len(self.return_payload) > 0 : - return self.return_payload + self._return_payload.update({'parent':parent}) + if len(self._return_payload) > 0 : + return self._return_payload else : return None else : return None def shutdown(self) : - if self.host and self.current_auth_header : - logout = requests.get('https://' + self.host + '/Services/REST/v1/logout',headers=self.current_auth_header) + if self._host and self._current_auth_header : + logout = requests.get('https://' + self._host + '/Services/REST/v1/logout',headers=self._current_auth_header) if not logout.text.endswith('successfully logged out.\"') : - self.error.append('Unable to log out of BlueCat API session') + self._error.append('Unable to log out of BlueCat API session') def get_bc_auth_header(self,host,username,password) : @@ -54,13 +54,13 @@ class ServiceDelegate(ServiceBase) : def search_bc_object(self,subject) : """Searches BC for the subject.""" # Search by IP - response = requests.get('https://' + self.host + '/Services/REST/v1/searchByObjectTypes?keyword=' + subject + '&types=IP4Address,IP6Address&start=0&count=10',headers=self.current_auth_header) + response = requests.get('https://' + self._host + '/Services/REST/v1/searchByObjectTypes?keyword=' + subject + '&types=IP4Address,IP6Address&start=0&count=10',headers=self._current_auth_header) return self.clean_response(response) def search_bc_parent_object(self,subject) : """Search for and return information about the objects parent, if any""" - if 'object' in self.return_payload and type(self.return_payload['object']) is dict and 'id' in self.return_payload['object'] : - response = requests.get('https://' + self.host + '/Services/REST/v1/getParent?entityId=' + str(self.return_payload['object']['id']), headers=self.current_auth_header) + if 'object' in self._return_payload and type(self._return_payload['object']) is dict and 'id' in self._return_payload['object'] : + response = requests.get('https://' + self._host + '/Services/REST/v1/getParent?entityId=' + str(self._return_payload['object']['id']), headers=self._current_auth_header) return self.clean_response(response) # Make a guess that it belongs to a static net that hasn't been put in bluecat elif subject != '' : @@ -68,7 +68,7 @@ class ServiceDelegate(ServiceBase) : try : ip = ipaddress.IPv4Network(subject + net,strict=False) network = str(ip.network_address) - response = requests.get('https://' + self.host + '/Services/REST/v1/searchByObjectTypes?keyword=' + network + '&types=IP4Network,IP4Block&start=0&count=10',headers=self.current_auth_header) + response = requests.get('https://' + self._host + '/Services/REST/v1/searchByObjectTypes?keyword=' + network + '&types=IP4Network,IP4Block&start=0&count=10',headers=self._current_auth_header) if not response.text.startswith('[]') : return self.clean_response(response) except: diff --git a/plugins/dns.py b/plugins/dns.py index 6de8e21..ec40672 100644 --- a/plugins/dns.py +++ b/plugins/dns.py @@ -12,8 +12,8 @@ class ServiceDelegate(ServiceBase) : def startup(self) : self.resolver = dns.resolver.Resolver() - if 'resolver' in self.config : - self.resolver.nameservers.append(self.config['resolver']) + if 'resolver' in self._config : + self.resolver.nameservers.append(self._config['resolver']) def lookup(self,subject) : @@ -29,7 +29,7 @@ class ServiceDelegate(ServiceBase) : subjecttuple = socket.gethostbyname_ex(subject) except socket.gaierror : # Not a valid host or IP - self.error.append('Unable to resolve ' + subject) + self._error.append('Unable to resolve ' + subject) subjecttuple = [subject,[],['']] # Can't make IPv4 out of it except socket.gaierror : diff --git a/plugins/f5.py b/plugins/f5.py index 9ba7b86..6b20694 100644 --- a/plugins/f5.py +++ b/plugins/f5.py @@ -8,8 +8,8 @@ urllib3.disable_warnings() class ServiceDelegate(ServiceBase) : - return_payload = {} - hosts = None + _return_payload = {} + _hosts = None _partition = 'Common' def get_arguments(cls) : @@ -17,28 +17,28 @@ class ServiceDelegate(ServiceBase) : def startup(self) : for requirement in ['hosts','username','key'] : - if requirement not in self.config or (requirement in self.config and self.config[requirement] is ''): - self.error.append('Missing required config option ' + requirement) + if requirement not in self._config or (requirement in self._config and self._config[requirement] is ''): + self._error.append('Missing required config option ' + requirement) return - self.hosts = self.config['hosts'] + self._hosts = self._config['hosts'] self.debug('Logging into F5\'s and searching for hosts, this make take some time.',1) def lookup(self,subject) : - self.return_payload = {} + self._return_payload = {} logincandidates = self.choose_host(subject) if logincandidates == {} : # Idk what to do here, do we give up or do we log in to all of them? - self.error.append('Unable to find an LB to log into to check host ' + str(subject)) + self._error.append('Unable to find an LB to log into to check host ' + str(subject)) return None for host in logincandidates.keys() : - auth_header = self.get_iq_auth_header(host,self.config['username'],self.config['key']) + auth_header = self.get_iq_auth_header(host,self._config['username'],self._config['key']) if not auth_header : - self.error.append('Unable to log in to ' + host) + self._error.append('Unable to log in to ' + host) continue # Get all VIPs - if 'vip' not in self.return_payload : + if 'vip' not in self._return_payload : vips = self.get_vip(host,auth_header); # If it's a VIP, return it and the host and let's be done if vips : @@ -47,11 +47,11 @@ class ServiceDelegate(ServiceBase) : all_vips = [ x['destination'] for x in vips ] if len(vip_match) > 0 : selected_vip = vip_match[0] - self.return_payload.update({'vip': selected_vip}) + self._return_payload.update({'vip': selected_vip}) pool_name = selected_vip['pool'].split('/' + self._partition + '/')[1] pool_info = self.get_pool(host,auth_header,pool_name) if pool_info : - self.return_payload.update(pool_info) + self._return_payload.update(pool_info) break else : self.debug('Unable to find VIP in VIPs from host ' + host,2) @@ -62,9 +62,9 @@ class ServiceDelegate(ServiceBase) : # Check if address is in the pool. If it is, return the node, pool, vip, and host. # Naw, I'll just give up. self.debug('Unable to get VIPs from ' + host,2) - if len(self.return_payload) is 0 : - self.return_payload = None - return self.return_payload + if len(self._return_payload) is 0 : + self._return_payload = None + return self._return_payload def shutdown(self) : return @@ -127,9 +127,9 @@ class ServiceDelegate(ServiceBase) : else : potentialdc = None if potentialdc : - for host in self.hosts.keys() : + for host in self._hosts.keys() : if potentialdc.lower() in host.lower() : - hosts.update({host:self.hosts[host]}) + hosts.update({host:self._hosts[host]}) if hosts != {} : return hosts self.debug('Unable to determine DC from subject name: ' + subject,3) @@ -139,9 +139,9 @@ class ServiceDelegate(ServiceBase) : potentialdc = self.hints['bluecat'][subject]['object']['locationCode'].split(' ')[-1] elif 'parent' in self.hints['bluecat'][subject] and 'name' in self.hints['bluecat'][subject]['parent'] : potentialdc = self.hints['bluecat'][subject]['parent']['name'].split(' ')[0] - for host in self.hosts.keys() : + for host in self._hosts.keys() : if potentialdc.lower() in host.lower() : - hosts.update({host:self.hosts[host]}) + hosts.update({host:self._hosts[host]}) self.debug('Got additional host info from the BlueCat plugin!',3) return hosts return hosts diff --git a/plugins/guid_channels.py b/plugins/guid_channels.py index a1902d5..3ea6577 100644 --- a/plugins/guid_channels.py +++ b/plugins/guid_channels.py @@ -13,10 +13,10 @@ class ServiceDelegate(ServiceBase) : # Load sub pack from options for requirement in ['sub_pack'] : - if requirement not in self.config or (requirement in self.config and self.config[requirement] is ''): - self.error.append('Missing required config option ' + requirement) + if requirement not in self._config or (requirement in self._config and self._config[requirement] is ''): + self._error.append('Missing required config option ' + requirement) return - self.sub_pack = self.config['sub_pack'] + self.sub_pack = self._config['sub_pack'] self.channels = json.loads(requests.get('https://cbd46b77.cdn.cms.movetv.com/cms/publish3/domain/channels/v4/-0700/770/' + self.sub_pack + '/1.json').text)['subscriptionpacks'][0]['channels'] self.channels_small = {x['channel_guid']:x['title'] for x in self.channels} self.debug('Beginning search for subscribed channels for GUID.',1) @@ -31,7 +31,7 @@ class ServiceDelegate(ServiceBase) : else : guid = None self.debug('Subject does not appear to be a valid GUID',1) - self.error.append('Subject does not appear to be a valid GUID') + self._error.append('Subject does not appear to be a valid GUID') return None for channel in self.channels_small : self.progress += 1 @@ -46,7 +46,7 @@ class ServiceDelegate(ServiceBase) : 'env': 'production', 'user_id': user_guid, 'channel_id': channel_guid, - 'message': self.sample_pssh + 'message': self._sample_pssh } drm_req = requests.post('http://p-drmwv.movetv.com/widevine/proxy', json=payload) if drm_req.status_code == 200 : @@ -56,4 +56,4 @@ class ServiceDelegate(ServiceBase) : self.debug('Got ' + str(drm_req.status_code) + ' for channel ' + str(channel_guid) + ' for user ' + str(user_guid) + ' (' + str(self.progress) + '/' + str(self.goal) + ')',verbosity) return drm_req.status_code - sample_pssh = [8,1,18,129,29,18,82,10,80,10,58,8,1,18,32,99,53,101,53,48,55,51,100,51,102,48,50,52,49,98,102,56,97,99,54,48,99,101,101,48,55,101,98,49,48,98,100,26,7,115,108,105,110,103,116,118,34,4,84,79,80,67,42,5,83,68,95,72,68,16,1,26,16,153,14,129,143,185,186,160,15,125,191,37,127,114,2,45,119,24,1,32,219,170,139,246,5,48,21,66,160,28,10,20,108,105,99,101,110,115,101,46,119,105,100,101,118,105,110,101,46,99,111,109,18,16,23,5,185,23,204,18,4,134,139,6,51,58,47,119,42,140,26,224,25,242,201,29,158,43,232,104,47,129,35,98,111,59,142,28,129,168,11,159,148,192,74,217,38,158,149,123,124,72,122,19,71,206,205,76,213,223,123,198,219,23,213,18,39,213,25,52,46,198,133,224,164,73,42,243,6,44,171,203,212,53,91,230,221,217,48,148,27,33,76,27,51,113,59,125,242,195,48,97,118,233,143,4,132,225,136,102,186,116,83,234,142,98,8,83,121,192,168,147,199,233,89,148,112,35,177,163,120,112,230,129,236,221,183,216,136,207,116,84,131,93,15,86,32,19,237,4,169,196,47,20,229,103,15,66,206,74,163,5,136,242,117,69,135,82,84,97,190,131,1,1,34,35,106,219,137,17,188,11,135,21,244,56,79,147,162,63,87,166,72,2,210,190,1,52,134,186,87,4,36,231,178,252,130,192,1,76,6,232,131,8,126,174,178,89,80,209,155,229,63,19,216,64,207,163,50,222,67,59,209,74,26,136,219,144,26,125,177,76,57,167,51,55,25,88,181,240,106,71,3,168,199,52,16,92,125,143,181,216,176,220,85,29,105,213,190,39,189,17,206,21,16,58,138,180,8,36,164,30,234,19,226,32,101,191,225,145,203,126,148,100,38,237,66,15,192,3,187,144,100,204,50,72,28,20,84,226,184,97,199,129,192,14,60,133,136,19,17,246,202,132,87,137,198,159,129,134,221,203,103,213,32,32,40,65,194,251,102,113,245,137,251,143,142,146,219,114,149,203,81,11,63,39,170,142,134,141,139,15,119,83,228,248,60,183,176,134,161,234,138,65,179,175,142,116,172,223,235,184,0,103,53,80,123,177,252,255,197,47,244,176,70,119,69,45,197,49,74,25,131,141,119,34,145,218,139,157,218,255,163,48,198,74,106,99,92,33,30,220,41,170,88,250,247,198,53,45,226,41,51,192,140,221,78,180,1,72,253,97,191,209,250,154,243,103,142,102,37,56,49,69,77,73,26,252,69,168,42,74,177,127,233,147,53,193,209,152,5,73,81,0,50,247,97,204,107,54,200,64,152,96,144,148,103,59,207,82,44,124,58,191,130,223,41,202,54,74,146,190,170,24,73,208,49,49,87,31,176,67,152,211,135,247,30,107,168,183,168,139,84,198,24,164,48,93,253,119,179,19,127,249,214,57,74,254,122,55,226,202,175,195,211,123,27,255,204,171,152,87,223,3,191,135,245,252,238,78,22,209,184,110,47,65,23,154,204,5,61,249,213,234,30,246,46,71,130,94,250,11,105,74,185,126,40,63,115,160,62,121,128,215,24,170,226,97,22,79,183,65,124,40,245,229,92,87,154,214,74,193,66,69,90,21,191,121,70,130,54,125,85,136,186,85,67,21,92,231,119,15,166,132,135,159,53,67,99,38,79,141,29,177,63,64,10,178,28,229,205,22,217,178,196,56,234,170,168,235,249,66,22,248,103,180,158,5,159,24,104,196,1,146,246,168,84,200,210,81,172,130,103,70,63,201,165,76,16,152,32,106,26,32,60,42,122,122,165,171,204,134,214,194,215,14,85,26,37,87,240,151,191,160,170,53,85,20,253,6,11,72,73,240,207,68,230,145,86,180,126,254,204,59,189,120,5,200,32,140,94,230,115,93,136,175,74,94,152,81,57,187,157,206,159,44,50,59,106,254,196,226,63,184,11,58,24,248,125,78,39,169,60,97,10,231,37,158,162,4,216,238,79,89,45,149,53,88,86,179,101,112,42,202,186,120,238,58,103,202,78,136,224,63,16,108,71,38,49,185,240,1,158,35,79,228,58,25,32,170,59,140,93,89,136,47,10,24,220,1,141,219,200,90,234,176,221,7,242,189,243,113,44,240,16,44,40,156,53,242,123,52,139,108,215,7,148,219,253,39,234,89,38,151,178,26,154,72,26,226,84,207,170,236,25,1,205,210,20,223,95,243,157,87,252,210,38,82,230,148,60,254,182,81,128,14,41,209,153,3,152,190,221,87,224,59,190,58,26,3,245,64,18,175,146,66,34,193,241,56,97,152,155,82,226,155,180,16,126,135,71,137,228,141,199,52,220,143,73,216,92,236,224,57,11,138,240,242,252,113,246,197,111,42,202,134,57,48,114,0,101,11,47,90,195,166,204,55,96,78,47,151,198,203,46,130,220,149,99,181,166,20,90,125,245,211,68,241,51,75,32,96,223,111,10,128,213,87,79,202,246,49,238,43,6,151,77,175,29,36,183,190,92,57,177,69,71,89,18,145,188,73,3,72,225,229,42,34,209,66,241,244,193,200,250,179,29,13,230,226,194,150,29,220,64,12,85,238,133,101,215,192,30,40,174,32,56,50,56,23,84,222,18,48,20,199,92,143,101,99,142,8,34,131,87,123,12,156,144,99,141,153,210,250,112,233,18,43,7,70,156,178,208,187,67,124,85,19,120,181,27,18,9,123,150,227,101,238,19,179,24,86,3,157,23,128,30,21,225,119,120,230,253,239,53,161,161,69,133,56,184,44,133,2,154,81,201,93,116,48,86,7,102,249,12,179,202,237,66,54,110,125,9,14,157,77,184,122,144,193,69,60,246,102,70,219,244,162,9,3,184,53,42,8,197,160,252,150,121,146,7,174,114,137,185,86,192,111,4,158,66,29,200,68,114,1,230,208,23,131,63,122,206,145,202,245,125,217,238,80,62,208,158,199,175,177,196,242,138,246,129,186,19,19,133,152,56,94,47,185,13,59,75,136,154,126,8,66,240,68,82,105,26,112,102,150,161,244,103,54,188,226,114,52,107,76,201,26,243,155,182,15,234,168,176,107,83,189,174,4,160,11,218,254,118,33,209,108,212,61,232,168,201,204,147,205,198,80,205,68,233,118,182,244,203,235,12,49,104,170,26,243,78,78,22,95,230,209,178,64,102,143,219,184,253,133,38,124,144,48,116,124,247,199,118,160,94,128,205,188,92,5,37,134,68,212,218,163,170,165,15,155,114,198,146,251,70,12,7,43,12,114,152,161,208,4,159,177,153,107,129,53,172,35,179,98,102,73,81,249,123,128,116,197,97,150,63,103,205,198,102,95,86,102,114,153,138,155,103,151,94,241,115,221,212,48,196,196,15,168,22,143,169,33,223,23,104,209,10,237,158,250,6,230,45,196,13,124,35,194,150,255,131,57,140,93,235,140,13,136,192,216,66,5,49,90,7,126,38,92,166,107,37,38,202,109,69,215,95,48,26,251,220,209,228,171,151,3,222,95,221,155,66,22,228,198,208,15,58,170,92,105,203,36,35,184,136,0,241,209,55,247,122,19,39,177,222,51,37,251,194,203,111,138,231,179,40,140,156,140,173,22,12,206,28,51,116,150,34,185,145,58,62,160,125,229,193,62,161,208,16,173,193,7,38,150,254,196,143,60,211,103,204,107,31,170,124,67,35,64,195,12,216,211,234,74,16,63,104,119,190,105,209,39,223,94,110,30,246,28,164,243,64,99,83,198,190,84,114,174,126,183,227,232,165,29,96,236,219,0,195,228,14,93,47,129,112,16,93,248,157,23,195,126,29,46,224,56,144,128,29,13,245,248,215,209,89,116,70,2,28,145,104,185,98,122,197,159,248,194,143,98,18,100,180,74,159,65,157,3,208,30,141,129,250,69,50,61,58,172,166,116,163,132,118,202,215,5,27,244,211,136,148,209,63,147,148,161,106,177,196,128,121,86,214,128,66,202,143,79,40,25,147,136,102,23,95,8,140,54,239,194,226,29,137,171,96,164,190,42,223,70,159,28,198,54,74,197,5,123,37,85,73,51,228,42,123,224,149,79,13,237,175,32,15,147,68,46,76,73,155,122,222,194,216,227,230,67,40,143,41,219,240,72,225,83,172,142,148,235,89,206,59,62,153,149,84,147,132,183,74,41,113,236,238,129,206,237,24,27,11,81,21,137,213,37,203,83,215,193,155,125,239,165,63,42,151,92,176,181,9,210,10,79,248,38,165,23,111,229,195,188,126,77,169,110,174,193,216,228,126,231,38,89,238,59,43,82,154,187,194,170,113,207,187,63,156,214,185,58,9,137,223,43,245,198,12,238,178,194,160,121,109,227,163,233,44,34,0,188,57,14,156,239,198,212,170,132,38,168,166,158,213,177,154,210,175,14,68,93,68,119,98,204,238,154,17,81,62,243,74,204,35,246,51,109,14,106,15,219,138,46,40,104,16,90,20,96,22,204,82,223,43,139,183,121,125,191,91,38,90,156,16,219,29,196,52,138,129,162,157,155,133,161,214,248,83,186,80,54,59,112,247,145,121,222,205,122,158,157,222,103,79,255,106,84,124,204,69,15,141,130,121,9,1,179,194,13,169,90,184,149,242,89,241,5,147,106,75,132,99,160,186,88,23,54,33,212,226,82,89,98,121,105,153,151,114,8,31,54,29,143,212,165,16,123,178,132,239,19,116,129,85,216,98,25,62,127,54,118,214,120,226,28,100,191,34,31,6,145,46,148,221,228,74,201,35,186,243,49,246,22,53,233,28,12,113,210,88,111,245,142,70,121,18,1,68,204,186,28,220,209,233,170,144,153,184,235,114,233,202,78,49,196,23,241,95,238,33,179,170,1,170,98,231,137,95,114,254,63,237,122,89,184,203,18,37,221,83,253,27,96,60,56,89,29,95,209,184,146,40,80,20,99,193,167,106,97,28,43,230,12,159,76,119,30,9,141,114,95,163,186,148,120,64,154,5,158,191,48,32,57,150,24,122,239,147,46,230,136,90,85,178,141,134,125,246,160,65,213,89,57,54,253,50,191,229,180,114,12,152,104,254,144,98,213,55,8,252,109,174,242,180,17,115,199,191,139,44,2,92,109,80,155,4,165,90,88,73,7,123,38,173,80,163,56,139,45,190,197,135,48,73,210,249,96,200,178,194,128,240,89,129,13,4,4,54,43,56,80,147,161,99,4,40,119,215,161,215,240,112,224,231,102,112,78,84,59,243,58,88,144,100,54,244,103,217,31,44,11,225,245,53,187,53,164,8,24,208,213,212,169,2,199,151,215,183,4,146,1,110,190,54,50,182,33,194,251,158,248,140,150,64,24,152,94,36,48,11,195,8,144,159,142,64,163,204,121,97,254,220,104,219,55,52,41,164,190,204,1,116,131,143,127,17,174,190,235,171,143,128,68,105,183,249,54,67,70,226,173,143,250,167,114,69,83,115,8,177,140,241,99,86,25,129,56,171,93,189,87,47,238,165,162,193,39,233,245,152,35,126,134,95,162,210,48,243,215,213,83,164,169,148,245,65,254,233,117,123,223,223,81,186,131,77,12,71,96,25,203,60,152,55,136,247,227,187,15,119,13,15,153,173,201,3,135,207,220,131,113,3,244,61,89,208,212,206,255,242,147,239,230,229,138,181,74,245,61,22,203,69,183,197,95,206,134,200,35,153,34,252,219,84,200,109,110,254,29,225,192,70,196,119,49,141,123,14,196,68,96,109,32,122,244,190,220,176,193,97,44,29,171,187,163,217,139,208,196,104,120,227,192,3,221,122,103,102,247,17,115,95,42,31,195,125,183,55,171,244,57,241,58,237,47,94,117,214,147,21,40,42,2,176,175,43,168,5,122,68,40,4,80,104,53,247,214,149,28,1,230,234,16,236,3,107,84,114,172,192,246,41,105,156,97,57,10,72,176,18,105,212,131,138,86,232,4,202,124,45,158,5,36,137,91,203,147,250,97,86,144,149,4,239,134,168,121,15,106,179,214,0,237,237,199,16,217,33,67,164,137,42,170,174,29,219,157,154,86,232,59,39,179,213,213,23,50,238,150,143,197,104,239,46,192,59,65,132,223,235,106,99,88,159,228,133,92,143,166,92,48,22,43,143,171,132,98,52,72,239,217,140,54,164,164,117,179,230,13,197,137,137,145,49,249,64,189,13,161,98,178,83,236,77,127,96,64,84,8,156,150,38,206,159,1,33,221,13,201,219,168,221,253,182,246,174,122,39,172,88,98,141,98,36,174,154,232,9,0,23,222,145,33,75,140,132,17,42,10,205,167,8,167,249,86,153,37,249,199,161,192,165,41,215,157,243,251,113,76,90,21,21,15,209,141,9,33,40,138,6,38,164,16,136,174,243,6,163,151,225,131,159,24,29,177,190,226,2,48,17,65,128,84,22,84,175,168,183,20,142,240,222,118,126,212,94,232,79,147,166,107,84,56,231,199,174,17,176,2,222,57,86,99,205,14,244,15,167,109,174,103,133,227,22,61,228,102,164,9,131,210,45,67,103,85,3,6,109,132,7,24,113,93,201,235,23,40,226,107,0,34,207,6,228,205,41,97,12,223,108,49,173,201,18,165,120,228,139,148,9,240,115,160,3,11,100,203,11,119,11,150,172,168,207,155,194,71,142,118,126,244,245,255,204,138,35,131,73,235,6,22,69,129,6,182,143,99,160,48,176,6,19,143,114,153,96,250,231,131,97,123,29,150,106,159,201,138,249,55,94,240,253,241,1,164,66,114,16,119,231,243,122,218,70,248,241,9,17,155,198,179,150,134,0,116,72,208,178,189,55,231,37,20,155,4,57,214,56,67,245,245,105,105,105,46,125,242,195,233,11,118,196,95,180,34,34,163,115,26,229,217,88,77,233,0,70,163,21,197,153,243,50,41,149,207,151,243,132,224,36,85,17,228,245,122,111,91,115,25,51,39,133,155,200,103,196,152,66,163,87,77,248,53,50,244,85,34,95,125,154,1,189,198,74,84,91,65,132,160,57,121,13,208,88,32,147,66,224,18,155,78,175,194,239,226,92,138,192,54,102,72,203,165,150,145,167,46,232,137,74,8,186,105,240,143,148,42,113,74,190,40,252,134,111,5,232,65,112,208,158,112,82,52,212,158,56,11,46,252,69,117,79,38,64,177,183,114,154,113,68,22,254,191,108,187,168,149,11,139,170,21,73,0,128,156,36,71,71,7,13,142,210,42,6,80,175,141,62,195,134,80,15,28,66,211,165,180,235,89,203,154,175,103,136,9,89,58,45,204,202,183,252,78,207,133,40,149,168,157,252,94,252,72,68,55,214,71,175,12,254,223,36,138,20,193,164,121,22,45,209,100,166,214,168,143,189,117,113,106,94,63,79,179,168,223,66,92,126,200,199,160,173,251,168,198,18,236,62,57,99,214,92,36,120,121,17,182,214,200,250,73,233,10,233,127,15,255,229,152,199,24,172,245,187,152,34,158,1,95,17,47,105,211,6,111,155,28,121,33,167,114,42,127,66,94,246,247,0,70,120,116,138,231,224,40,36,59,89,84,134,227,193,159,52,196,233,76,140,43,98,134,112,195,126,113,161,92,11,52,39,100,237,101,143,122,116,181,74,69,138,47,100,192,21,163,94,135,73,54,22,201,31,80,90,65,35,126,117,29,13,172,93,86,189,4,178,222,34,43,91,34,16,131,40,29,122,238,75,53,169,1,204,97,81,177,114,7,140,42,128,2,10,221,39,176,107,106,132,161,154,35,249,212,246,234,161,232,193,86,30,129,120,184,23,168,2,179,180,66,125,138,105,212,199,149,195,96,252,118,170,117,253,216,45,216,217,164,149,200,232,179,154,215,195,74,224,71,153,255,144,90,230,249,189,185,243,155,22,75,23,48,164,152,185,184,205,172,141,141,57,172,255,33,168,176,134,194,177,25,217,236,108,222,100,129,228,89,9,83,0,43,80,16,196,223,77,44,210,224,43,19,219,221,96,134,7,197,48,97,198,137,162,62,149,120,8,53,136,210,79,82,0,146,128,112,211,87,248,28,239,201,250,217,134,203,158,32,111,143,249,47,255,119,48,111,247,209,91,186,201,129,64,202,134,179,209,120,199,206,235,41,134,212,163,201,44,98,62,136,230,144,34,209,146,220,118,132,10,130,138,207,11,147,52,207,176,183,195,5,233,88,171,75,23,220,230,161,116,109,67,22,13,153,26,145,185,17,157,10,46,75,86,87,95,117,0,140,177,10,199,139,250,105,150,252,36,72,174,213,245,106,115,219,179,213,68,234,129,221,246,54,122,203,18,164,240,156,26,128,2,201,143,22,22,131,169,155,49,90,144,153,184,166,171,255,139,92,126,36,72,216,88,99,201,112,152,156,255,188,190,52,193,217,127,69,82,234,10,180,199,5,247,46,29,140,164,172,117,121,96,198,58,28,8,13,207,168,234,150,165,224,177,199,159,183,57,238,63,102,151,118,140,138,38,114,183,237,19,64,161,71,53,97,187,84,156,141,170,35,78,123,186,58,94,117,182,118,231,253,13,188,152,10,225,103,82,118,250,213,241,2,120,62,174,112,231,252,236,90,183,220,141,178,135,206,162,168,215,160,132,7,184,244,66,255,199,57,72,109,163,182,213,54,148,133,212,166,155,22,119,46,249,177,18,7,249,247,241,251,130,210,246,203,133,223,122,242,111,66,201,192,108,247,191,74,70,5,250,225,15,238,31,191,219,4,186,110,213,46,93,61,243,49,48,207,97,223,81,241,163,69,2,69,23,156,226,127,168,11,29,214,3,73,93,9,206,107,45,165,103,238,202,140,5,250,146,18,39,219,246,202,222,119,203,0,15,18,16,60,149,118,117,97,118,117,203,84,22,210,215,99,1,79,96,55,206] + _sample_pssh = [8,1,18,129,29,18,82,10,80,10,58,8,1,18,32,99,53,101,53,48,55,51,100,51,102,48,50,52,49,98,102,56,97,99,54,48,99,101,101,48,55,101,98,49,48,98,100,26,7,115,108,105,110,103,116,118,34,4,84,79,80,67,42,5,83,68,95,72,68,16,1,26,16,153,14,129,143,185,186,160,15,125,191,37,127,114,2,45,119,24,1,32,219,170,139,246,5,48,21,66,160,28,10,20,108,105,99,101,110,115,101,46,119,105,100,101,118,105,110,101,46,99,111,109,18,16,23,5,185,23,204,18,4,134,139,6,51,58,47,119,42,140,26,224,25,242,201,29,158,43,232,104,47,129,35,98,111,59,142,28,129,168,11,159,148,192,74,217,38,158,149,123,124,72,122,19,71,206,205,76,213,223,123,198,219,23,213,18,39,213,25,52,46,198,133,224,164,73,42,243,6,44,171,203,212,53,91,230,221,217,48,148,27,33,76,27,51,113,59,125,242,195,48,97,118,233,143,4,132,225,136,102,186,116,83,234,142,98,8,83,121,192,168,147,199,233,89,148,112,35,177,163,120,112,230,129,236,221,183,216,136,207,116,84,131,93,15,86,32,19,237,4,169,196,47,20,229,103,15,66,206,74,163,5,136,242,117,69,135,82,84,97,190,131,1,1,34,35,106,219,137,17,188,11,135,21,244,56,79,147,162,63,87,166,72,2,210,190,1,52,134,186,87,4,36,231,178,252,130,192,1,76,6,232,131,8,126,174,178,89,80,209,155,229,63,19,216,64,207,163,50,222,67,59,209,74,26,136,219,144,26,125,177,76,57,167,51,55,25,88,181,240,106,71,3,168,199,52,16,92,125,143,181,216,176,220,85,29,105,213,190,39,189,17,206,21,16,58,138,180,8,36,164,30,234,19,226,32,101,191,225,145,203,126,148,100,38,237,66,15,192,3,187,144,100,204,50,72,28,20,84,226,184,97,199,129,192,14,60,133,136,19,17,246,202,132,87,137,198,159,129,134,221,203,103,213,32,32,40,65,194,251,102,113,245,137,251,143,142,146,219,114,149,203,81,11,63,39,170,142,134,141,139,15,119,83,228,248,60,183,176,134,161,234,138,65,179,175,142,116,172,223,235,184,0,103,53,80,123,177,252,255,197,47,244,176,70,119,69,45,197,49,74,25,131,141,119,34,145,218,139,157,218,255,163,48,198,74,106,99,92,33,30,220,41,170,88,250,247,198,53,45,226,41,51,192,140,221,78,180,1,72,253,97,191,209,250,154,243,103,142,102,37,56,49,69,77,73,26,252,69,168,42,74,177,127,233,147,53,193,209,152,5,73,81,0,50,247,97,204,107,54,200,64,152,96,144,148,103,59,207,82,44,124,58,191,130,223,41,202,54,74,146,190,170,24,73,208,49,49,87,31,176,67,152,211,135,247,30,107,168,183,168,139,84,198,24,164,48,93,253,119,179,19,127,249,214,57,74,254,122,55,226,202,175,195,211,123,27,255,204,171,152,87,223,3,191,135,245,252,238,78,22,209,184,110,47,65,23,154,204,5,61,249,213,234,30,246,46,71,130,94,250,11,105,74,185,126,40,63,115,160,62,121,128,215,24,170,226,97,22,79,183,65,124,40,245,229,92,87,154,214,74,193,66,69,90,21,191,121,70,130,54,125,85,136,186,85,67,21,92,231,119,15,166,132,135,159,53,67,99,38,79,141,29,177,63,64,10,178,28,229,205,22,217,178,196,56,234,170,168,235,249,66,22,248,103,180,158,5,159,24,104,196,1,146,246,168,84,200,210,81,172,130,103,70,63,201,165,76,16,152,32,106,26,32,60,42,122,122,165,171,204,134,214,194,215,14,85,26,37,87,240,151,191,160,170,53,85,20,253,6,11,72,73,240,207,68,230,145,86,180,126,254,204,59,189,120,5,200,32,140,94,230,115,93,136,175,74,94,152,81,57,187,157,206,159,44,50,59,106,254,196,226,63,184,11,58,24,248,125,78,39,169,60,97,10,231,37,158,162,4,216,238,79,89,45,149,53,88,86,179,101,112,42,202,186,120,238,58,103,202,78,136,224,63,16,108,71,38,49,185,240,1,158,35,79,228,58,25,32,170,59,140,93,89,136,47,10,24,220,1,141,219,200,90,234,176,221,7,242,189,243,113,44,240,16,44,40,156,53,242,123,52,139,108,215,7,148,219,253,39,234,89,38,151,178,26,154,72,26,226,84,207,170,236,25,1,205,210,20,223,95,243,157,87,252,210,38,82,230,148,60,254,182,81,128,14,41,209,153,3,152,190,221,87,224,59,190,58,26,3,245,64,18,175,146,66,34,193,241,56,97,152,155,82,226,155,180,16,126,135,71,137,228,141,199,52,220,143,73,216,92,236,224,57,11,138,240,242,252,113,246,197,111,42,202,134,57,48,114,0,101,11,47,90,195,166,204,55,96,78,47,151,198,203,46,130,220,149,99,181,166,20,90,125,245,211,68,241,51,75,32,96,223,111,10,128,213,87,79,202,246,49,238,43,6,151,77,175,29,36,183,190,92,57,177,69,71,89,18,145,188,73,3,72,225,229,42,34,209,66,241,244,193,200,250,179,29,13,230,226,194,150,29,220,64,12,85,238,133,101,215,192,30,40,174,32,56,50,56,23,84,222,18,48,20,199,92,143,101,99,142,8,34,131,87,123,12,156,144,99,141,153,210,250,112,233,18,43,7,70,156,178,208,187,67,124,85,19,120,181,27,18,9,123,150,227,101,238,19,179,24,86,3,157,23,128,30,21,225,119,120,230,253,239,53,161,161,69,133,56,184,44,133,2,154,81,201,93,116,48,86,7,102,249,12,179,202,237,66,54,110,125,9,14,157,77,184,122,144,193,69,60,246,102,70,219,244,162,9,3,184,53,42,8,197,160,252,150,121,146,7,174,114,137,185,86,192,111,4,158,66,29,200,68,114,1,230,208,23,131,63,122,206,145,202,245,125,217,238,80,62,208,158,199,175,177,196,242,138,246,129,186,19,19,133,152,56,94,47,185,13,59,75,136,154,126,8,66,240,68,82,105,26,112,102,150,161,244,103,54,188,226,114,52,107,76,201,26,243,155,182,15,234,168,176,107,83,189,174,4,160,11,218,254,118,33,209,108,212,61,232,168,201,204,147,205,198,80,205,68,233,118,182,244,203,235,12,49,104,170,26,243,78,78,22,95,230,209,178,64,102,143,219,184,253,133,38,124,144,48,116,124,247,199,118,160,94,128,205,188,92,5,37,134,68,212,218,163,170,165,15,155,114,198,146,251,70,12,7,43,12,114,152,161,208,4,159,177,153,107,129,53,172,35,179,98,102,73,81,249,123,128,116,197,97,150,63,103,205,198,102,95,86,102,114,153,138,155,103,151,94,241,115,221,212,48,196,196,15,168,22,143,169,33,223,23,104,209,10,237,158,250,6,230,45,196,13,124,35,194,150,255,131,57,140,93,235,140,13,136,192,216,66,5,49,90,7,126,38,92,166,107,37,38,202,109,69,215,95,48,26,251,220,209,228,171,151,3,222,95,221,155,66,22,228,198,208,15,58,170,92,105,203,36,35,184,136,0,241,209,55,247,122,19,39,177,222,51,37,251,194,203,111,138,231,179,40,140,156,140,173,22,12,206,28,51,116,150,34,185,145,58,62,160,125,229,193,62,161,208,16,173,193,7,38,150,254,196,143,60,211,103,204,107,31,170,124,67,35,64,195,12,216,211,234,74,16,63,104,119,190,105,209,39,223,94,110,30,246,28,164,243,64,99,83,198,190,84,114,174,126,183,227,232,165,29,96,236,219,0,195,228,14,93,47,129,112,16,93,248,157,23,195,126,29,46,224,56,144,128,29,13,245,248,215,209,89,116,70,2,28,145,104,185,98,122,197,159,248,194,143,98,18,100,180,74,159,65,157,3,208,30,141,129,250,69,50,61,58,172,166,116,163,132,118,202,215,5,27,244,211,136,148,209,63,147,148,161,106,177,196,128,121,86,214,128,66,202,143,79,40,25,147,136,102,23,95,8,140,54,239,194,226,29,137,171,96,164,190,42,223,70,159,28,198,54,74,197,5,123,37,85,73,51,228,42,123,224,149,79,13,237,175,32,15,147,68,46,76,73,155,122,222,194,216,227,230,67,40,143,41,219,240,72,225,83,172,142,148,235,89,206,59,62,153,149,84,147,132,183,74,41,113,236,238,129,206,237,24,27,11,81,21,137,213,37,203,83,215,193,155,125,239,165,63,42,151,92,176,181,9,210,10,79,248,38,165,23,111,229,195,188,126,77,169,110,174,193,216,228,126,231,38,89,238,59,43,82,154,187,194,170,113,207,187,63,156,214,185,58,9,137,223,43,245,198,12,238,178,194,160,121,109,227,163,233,44,34,0,188,57,14,156,239,198,212,170,132,38,168,166,158,213,177,154,210,175,14,68,93,68,119,98,204,238,154,17,81,62,243,74,204,35,246,51,109,14,106,15,219,138,46,40,104,16,90,20,96,22,204,82,223,43,139,183,121,125,191,91,38,90,156,16,219,29,196,52,138,129,162,157,155,133,161,214,248,83,186,80,54,59,112,247,145,121,222,205,122,158,157,222,103,79,255,106,84,124,204,69,15,141,130,121,9,1,179,194,13,169,90,184,149,242,89,241,5,147,106,75,132,99,160,186,88,23,54,33,212,226,82,89,98,121,105,153,151,114,8,31,54,29,143,212,165,16,123,178,132,239,19,116,129,85,216,98,25,62,127,54,118,214,120,226,28,100,191,34,31,6,145,46,148,221,228,74,201,35,186,243,49,246,22,53,233,28,12,113,210,88,111,245,142,70,121,18,1,68,204,186,28,220,209,233,170,144,153,184,235,114,233,202,78,49,196,23,241,95,238,33,179,170,1,170,98,231,137,95,114,254,63,237,122,89,184,203,18,37,221,83,253,27,96,60,56,89,29,95,209,184,146,40,80,20,99,193,167,106,97,28,43,230,12,159,76,119,30,9,141,114,95,163,186,148,120,64,154,5,158,191,48,32,57,150,24,122,239,147,46,230,136,90,85,178,141,134,125,246,160,65,213,89,57,54,253,50,191,229,180,114,12,152,104,254,144,98,213,55,8,252,109,174,242,180,17,115,199,191,139,44,2,92,109,80,155,4,165,90,88,73,7,123,38,173,80,163,56,139,45,190,197,135,48,73,210,249,96,200,178,194,128,240,89,129,13,4,4,54,43,56,80,147,161,99,4,40,119,215,161,215,240,112,224,231,102,112,78,84,59,243,58,88,144,100,54,244,103,217,31,44,11,225,245,53,187,53,164,8,24,208,213,212,169,2,199,151,215,183,4,146,1,110,190,54,50,182,33,194,251,158,248,140,150,64,24,152,94,36,48,11,195,8,144,159,142,64,163,204,121,97,254,220,104,219,55,52,41,164,190,204,1,116,131,143,127,17,174,190,235,171,143,128,68,105,183,249,54,67,70,226,173,143,250,167,114,69,83,115,8,177,140,241,99,86,25,129,56,171,93,189,87,47,238,165,162,193,39,233,245,152,35,126,134,95,162,210,48,243,215,213,83,164,169,148,245,65,254,233,117,123,223,223,81,186,131,77,12,71,96,25,203,60,152,55,136,247,227,187,15,119,13,15,153,173,201,3,135,207,220,131,113,3,244,61,89,208,212,206,255,242,147,239,230,229,138,181,74,245,61,22,203,69,183,197,95,206,134,200,35,153,34,252,219,84,200,109,110,254,29,225,192,70,196,119,49,141,123,14,196,68,96,109,32,122,244,190,220,176,193,97,44,29,171,187,163,217,139,208,196,104,120,227,192,3,221,122,103,102,247,17,115,95,42,31,195,125,183,55,171,244,57,241,58,237,47,94,117,214,147,21,40,42,2,176,175,43,168,5,122,68,40,4,80,104,53,247,214,149,28,1,230,234,16,236,3,107,84,114,172,192,246,41,105,156,97,57,10,72,176,18,105,212,131,138,86,232,4,202,124,45,158,5,36,137,91,203,147,250,97,86,144,149,4,239,134,168,121,15,106,179,214,0,237,237,199,16,217,33,67,164,137,42,170,174,29,219,157,154,86,232,59,39,179,213,213,23,50,238,150,143,197,104,239,46,192,59,65,132,223,235,106,99,88,159,228,133,92,143,166,92,48,22,43,143,171,132,98,52,72,239,217,140,54,164,164,117,179,230,13,197,137,137,145,49,249,64,189,13,161,98,178,83,236,77,127,96,64,84,8,156,150,38,206,159,1,33,221,13,201,219,168,221,253,182,246,174,122,39,172,88,98,141,98,36,174,154,232,9,0,23,222,145,33,75,140,132,17,42,10,205,167,8,167,249,86,153,37,249,199,161,192,165,41,215,157,243,251,113,76,90,21,21,15,209,141,9,33,40,138,6,38,164,16,136,174,243,6,163,151,225,131,159,24,29,177,190,226,2,48,17,65,128,84,22,84,175,168,183,20,142,240,222,118,126,212,94,232,79,147,166,107,84,56,231,199,174,17,176,2,222,57,86,99,205,14,244,15,167,109,174,103,133,227,22,61,228,102,164,9,131,210,45,67,103,85,3,6,109,132,7,24,113,93,201,235,23,40,226,107,0,34,207,6,228,205,41,97,12,223,108,49,173,201,18,165,120,228,139,148,9,240,115,160,3,11,100,203,11,119,11,150,172,168,207,155,194,71,142,118,126,244,245,255,204,138,35,131,73,235,6,22,69,129,6,182,143,99,160,48,176,6,19,143,114,153,96,250,231,131,97,123,29,150,106,159,201,138,249,55,94,240,253,241,1,164,66,114,16,119,231,243,122,218,70,248,241,9,17,155,198,179,150,134,0,116,72,208,178,189,55,231,37,20,155,4,57,214,56,67,245,245,105,105,105,46,125,242,195,233,11,118,196,95,180,34,34,163,115,26,229,217,88,77,233,0,70,163,21,197,153,243,50,41,149,207,151,243,132,224,36,85,17,228,245,122,111,91,115,25,51,39,133,155,200,103,196,152,66,163,87,77,248,53,50,244,85,34,95,125,154,1,189,198,74,84,91,65,132,160,57,121,13,208,88,32,147,66,224,18,155,78,175,194,239,226,92,138,192,54,102,72,203,165,150,145,167,46,232,137,74,8,186,105,240,143,148,42,113,74,190,40,252,134,111,5,232,65,112,208,158,112,82,52,212,158,56,11,46,252,69,117,79,38,64,177,183,114,154,113,68,22,254,191,108,187,168,149,11,139,170,21,73,0,128,156,36,71,71,7,13,142,210,42,6,80,175,141,62,195,134,80,15,28,66,211,165,180,235,89,203,154,175,103,136,9,89,58,45,204,202,183,252,78,207,133,40,149,168,157,252,94,252,72,68,55,214,71,175,12,254,223,36,138,20,193,164,121,22,45,209,100,166,214,168,143,189,117,113,106,94,63,79,179,168,223,66,92,126,200,199,160,173,251,168,198,18,236,62,57,99,214,92,36,120,121,17,182,214,200,250,73,233,10,233,127,15,255,229,152,199,24,172,245,187,152,34,158,1,95,17,47,105,211,6,111,155,28,121,33,167,114,42,127,66,94,246,247,0,70,120,116,138,231,224,40,36,59,89,84,134,227,193,159,52,196,233,76,140,43,98,134,112,195,126,113,161,92,11,52,39,100,237,101,143,122,116,181,74,69,138,47,100,192,21,163,94,135,73,54,22,201,31,80,90,65,35,126,117,29,13,172,93,86,189,4,178,222,34,43,91,34,16,131,40,29,122,238,75,53,169,1,204,97,81,177,114,7,140,42,128,2,10,221,39,176,107,106,132,161,154,35,249,212,246,234,161,232,193,86,30,129,120,184,23,168,2,179,180,66,125,138,105,212,199,149,195,96,252,118,170,117,253,216,45,216,217,164,149,200,232,179,154,215,195,74,224,71,153,255,144,90,230,249,189,185,243,155,22,75,23,48,164,152,185,184,205,172,141,141,57,172,255,33,168,176,134,194,177,25,217,236,108,222,100,129,228,89,9,83,0,43,80,16,196,223,77,44,210,224,43,19,219,221,96,134,7,197,48,97,198,137,162,62,149,120,8,53,136,210,79,82,0,146,128,112,211,87,248,28,239,201,250,217,134,203,158,32,111,143,249,47,255,119,48,111,247,209,91,186,201,129,64,202,134,179,209,120,199,206,235,41,134,212,163,201,44,98,62,136,230,144,34,209,146,220,118,132,10,130,138,207,11,147,52,207,176,183,195,5,233,88,171,75,23,220,230,161,116,109,67,22,13,153,26,145,185,17,157,10,46,75,86,87,95,117,0,140,177,10,199,139,250,105,150,252,36,72,174,213,245,106,115,219,179,213,68,234,129,221,246,54,122,203,18,164,240,156,26,128,2,201,143,22,22,131,169,155,49,90,144,153,184,166,171,255,139,92,126,36,72,216,88,99,201,112,152,156,255,188,190,52,193,217,127,69,82,234,10,180,199,5,247,46,29,140,164,172,117,121,96,198,58,28,8,13,207,168,234,150,165,224,177,199,159,183,57,238,63,102,151,118,140,138,38,114,183,237,19,64,161,71,53,97,187,84,156,141,170,35,78,123,186,58,94,117,182,118,231,253,13,188,152,10,225,103,82,118,250,213,241,2,120,62,174,112,231,252,236,90,183,220,141,178,135,206,162,168,215,160,132,7,184,244,66,255,199,57,72,109,163,182,213,54,148,133,212,166,155,22,119,46,249,177,18,7,249,247,241,251,130,210,246,203,133,223,122,242,111,66,201,192,108,247,191,74,70,5,250,225,15,238,31,191,219,4,186,110,213,46,93,61,243,49,48,207,97,223,81,241,163,69,2,69,23,156,226,127,168,11,29,214,3,73,93,9,206,107,45,165,103,238,202,140,5,250,146,18,39,219,246,202,222,119,203,0,15,18,16,60,149,118,117,97,118,117,203,84,22,210,215,99,1,79,96,55,206] diff --git a/plugins/openvpn.py b/plugins/openvpn.py index 7d02ab2..be51307 100644 --- a/plugins/openvpn.py +++ b/plugins/openvpn.py @@ -1,10 +1,11 @@ from servicebase import ServiceBase import paramiko +import datetime import re class ServiceDelegate(ServiceBase) : - connections = None + _connections = None def get_arguments(cls) : """Returns an array of information used to construct an argumentparser argument.""" @@ -12,37 +13,38 @@ class ServiceDelegate(ServiceBase) : def startup(self) : for requirement in ['hosts','username','key'] : - if requirement not in self.config or (requirement in self.config and self.config[requirement] is ''): - self.error.append('Missing required config option ' + requirement) - return - self.hosts = self.config['hosts'] + if requirement not in self._config or (requirement in self._config and self._config[requirement] is ''): + self._error.append('Missing required config option ' + requirement) + rself._error + self.hosts = self._config['hosts'] self.debug('Logging into OpenVPN servers...',1) connections = {} - for host in self.config['hosts'] : + for host in self._config['hosts'] : try : sshclient = paramiko.SSHClient() sshclient.set_missing_host_key_policy(paramiko.AutoAddPolicy()) - sshclient.connect(host,22,username=self.config['username'],password=self.config['key']) + sshclient.connect(host,22,username=self._config['username'],password=self._config['key']) connections.update({host:sshclient}) except Exception as exception : - self.error.append('Unable to ssh into ' + host + ': ' + str(exception)) - self.connections = connections + self._error.append('Unable to ssh into ' + host + ': ' + str(exception)) + self._connections = connections def shutdown(self) : - for connection in self.connections.values() : + for connection in self._connections.values() : connection.close() def lookup(self,subject) : search_command = 'sudo -S cat /var/log/openvpn/openvpn.log | grep \'primary virtual IP for\' | grep \'' + subject + '\' | tail -n 1' - for host,connection in self.connections.items() : + final_dictionary = {} + for host,connection in self._connections.items() : try: stdin,stdout,stderr=connection.exec_command(search_command) - stdin.write(self.config['key'] + '\n') + stdin.write(self._config['key'] + '\n') stdin.flush() result = stdout.readlines() if len(result) > 0 : - self.debug('Retrieved line from ssh session: \n' + result[0],2) + self.debug('Retrieved line from ssh session: \n' + result[0].strip(),2) result = result[0] else : result = '' @@ -54,9 +56,23 @@ class ServiceDelegate(ServiceBase) : return_dictionary.update({item: matches[1]}) if len(return_dictionary) > 0 : return_dictionary.update({'host':host}) - return return_dictionary + + epoch = None + if 'timestamp' in final_dictionary.keys() and 'timestamp' in return_dictionary.keys() : + epoch = int(datetime.datetime.strptime(return_dictionary['timestamp'] + ' ' + str(datetime.datetime.now().year), '%b %d %H:%M:%S %Y').strftime('%s')) + if len(return_dictionary) > 0 : + if epoch : + if epoch > int(datetime.datetime.strptime(final_dictionary['timestamp'] + ' ' + str(datetime.datetime.now().year), '%b %d %H:%M:%S %Y').strftime('%s')) : + final_dictionary = {} + final_dictionary.update(return_dictionary) + else : + final_dictionary = return_dictionary else : - return None + self.debug('No results for ' + subject + ' on host ' + host,2) except Exception as exception : - self.error.append('Unable to get results from ssh: ' + str(exception)) - pass + raise exception + self._error.append('Unable to get results from ssh: ' + str(exception)) + if len(final_dictionary) > 0 : + return final_dictionary + else : + return None diff --git a/plugins/shodan.py b/plugins/shodan.py index febed10..e2cb23a 100644 --- a/plugins/shodan.py +++ b/plugins/shodan.py @@ -15,10 +15,10 @@ class ServiceDelegate(ServiceBase) : def startup(self) : for requirement in ['keys'] : - if requirement not in self.config or (requirement in self.config and self.config[requirement] is ''): - self.error.append('Missing required config option ' + requirement) + if requirement not in self._config or (requirement in self._config and self._config[requirement] is ''): + self._error.append('Missing required config option ' + requirement) return - keys = self.config['keys'] + keys = self._config['keys'] self._api_sessions = [shodan.Shodan(x) for x in keys] self.debug('Searching Shodan for hosts...',1) diff --git a/plugins/vmware.py b/plugins/vmware.py index 56ec5b4..915d03a 100644 --- a/plugins/vmware.py +++ b/plugins/vmware.py @@ -10,14 +10,12 @@ class ServiceDelegate(ServiceBase) : def startup(self) : self.resolver = dns.resolver.Resolver() - if 'resolver' in self.config : - self.resolver.nameservers.append(self.config['resolver']) + if 'resolver' in self._config : + self.resolver.nameservers.append(self._config['resolver']) def lookup(self,subject) : # Note : hostname lookups always use system resolver. - # TODO: Make host lookups use the config-sepcified resolver. - try : subjecttuple = socket.gethostbyname_ex(subject) # Can't make an IP of the subject @@ -27,11 +25,11 @@ class ServiceDelegate(ServiceBase) : subjecttuple = socket.gethostbyname_ex(subject) except socket.gaierror : # Not a valid host or IP - self.error.append("Unable to resolve " + subject) + self._error.append("Unable to resolve " + subject) subjecttuple = [subject,[],['']] # Can't make IPv4 out of it except socket.gaierror : - self.error.append("Unable to resolve " + subject) + self._error.append("Unable to resolve " + subject) subjecttuple = [subject,[],['']] # Get additional records return_dict = {} diff --git a/servicebase.py b/servicebase.py index e59a917..51c744b 100644 --- a/servicebase.py +++ b/servicebase.py @@ -1,22 +1,20 @@ import sys class ServiceBase : - config = {} - namespace = {} - data = {} + _config = {} error = [] warn = [] _status = "Ready" def __init__(self,hints={},config={}): - self.config = config - self.error = [] - self.warn = [] + self._config = config + self._error = [] + self._warn = [] self.hints = hints pass def _set_config(self,config) : """Allows for post-initialization configuration""" - self.config = config + self._config = config def _set_hints(self,hints) : """Allows for post-initialization configuration of hint data""" @@ -28,7 +26,7 @@ class ServiceBase : def debug(self,message,verbosity_level) : """Prints the submitted message if the environment's verbosity level matches or is surpassed by the submitted level.""" - if self.config['_namespace']['debug'] and self.config['_namespace']['debug'] >= verbosity_level : + if self._config['_namespace']['debug'] and self._config['_namespace']['debug'] >= verbosity_level : print(message,file=sys.stderr) @classmethod