diff --git a/README.md b/README.md index f4817a2..e03e19d 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ that are supported are the critical ones to integrating Deep Security into your ## Requirements -Python 2.7 or newer. The project only uses modules in the standard library. +Python 2.6 or newer. The project only uses modules in the standard library. ## Usage diff --git a/deepsecurity/computers.py b/deepsecurity/computers.py index 287b07d..cb37448 100644 --- a/deepsecurity/computers.py +++ b/deepsecurity/computers.py @@ -122,25 +122,25 @@ def get(self, detail_level='HIGH', computer_id=None, computer_group_id=None, pol computer_obj = Computer(self.manager, computer, self.log) if computer_obj: self[computer_obj.id] = computer_obj - self.log("Added Computer {}".format(computer_obj.id), level='debug') + self.log("Added Computer {0}".format(computer_obj.id), level='debug') try: # add this computer to any appropriate groups on the Manager() if 'computer_group_id' in dir(computer_obj) and computer_obj.computer_group_id: if self.manager.computer_groups and self.manager.computer_groups.has_key(computer_obj.computer_group_id): self.manager.computer_groups[computer_obj.computer_group_id].computers[computer_obj.id] = computer_obj - self.log("Added Computer {} to ComputerGroup {}".format(computer_obj.id, computer_obj.computer_group_id), level='debug') + self.log("Added Computer {0} to ComputerGroup {1}".format(computer_obj.id, computer_obj.computer_group_id), level='debug') except Exception, hostGroupid_err: - self.log("Could not add Computer {} to ComputerGroup".format(computer_obj.id), err=hostGroupid_err) + self.log("Could not add Computer {0} to ComputerGroup".format(computer_obj.id), err=hostGroupid_err) try: # add this computer to any appropriate policies on the Manager() if 'policy_id' in dir(computer_obj) and computer_obj.policy_id: if self.manager.policies and self.manager.policies.has_key(computer_obj.policy_id): self.manager.policies[computer_obj.policy_id].computers[computer_obj.id] = computer_obj - self.log("Added Computer {} to Policy {}".format(computer_obj.id, computer_obj.policy_id), level='debug') + self.log("Added Computer {0} to Policy {1}".format(computer_obj.id, computer_obj.policy_id), level='debug') except Exception, securityProfileid_err: - self.log("Could not add Computer {} to Policy".format(computer_obj.id), err=securityProfileid_err) + self.log("Could not add Computer {0} to Policy".format(computer_obj.id), err=securityProfileid_err) return len(self) @@ -172,7 +172,7 @@ def get(self, name=None, group_id=None): elif group_id: call = self.manager._get_request_format(call='hostGroupRetrieve') call['data'] = { - 'id': '{}'.format(group_id) + 'id': '{0}'.format(group_id) } else: call = self.manager._get_request_format(call='hostGroupRetrieveAll') @@ -185,7 +185,7 @@ def get(self, name=None, group_id=None): computer_group_obj = ComputerGroup(self.manager, group, self.log) if computer_group_obj: self[computer_group_obj.id] = computer_group_obj - self.log("Added ComputerGroup {}".format(computer_group_obj.id), level='debug') + self.log("Added ComputerGroup {0}".format(computer_group_obj.id), level='debug') return len(self) diff --git a/deepsecurity/core.py b/deepsecurity/core.py index 17d618b..fabbb31 100644 --- a/deepsecurity/core.py +++ b/deepsecurity/core.py @@ -6,6 +6,7 @@ import ssl import urllib import urllib2 +import requests # 3rd party libraries import libs.xmltodict as xmltodict @@ -47,7 +48,7 @@ def log_at_level(self, value): self._set_logging() else: if not self._log_at_level: - self._log_at_level = logging.WARNING + self._log_at_level = logging.DEBUG self._set_logging() # ******************************************************************* @@ -129,16 +130,16 @@ def _request(self, request, auth_required=True): 'call' ]: if not request.has_key(required_key) and request[required_key]: - self.log("All requests are required to have a key [{}] with a value".format(required_key), level='critical') + self.log("All requests are required to have a key [{0}] with a value".format(required_key), level='critical') return None url = None if request['api'] == self.API_TYPE_REST: - url = "{}/{}".format(self._rest_api_endpoint, request['call'].lstrip('/')) + url = "{0}/{1}".format(self._rest_api_endpoint, request['call'].lstrip('/')) else: url = self._soap_api_endpoint - self.log("Making a request to {}".format(url), level='debug') + self.log("Making a request to {0}".format(url), level='debug') # add the authentication parameters if auth_required: @@ -163,19 +164,10 @@ def _request(self, request, auth_required=True): if v: qs[k] = v url += '?%s' % urllib.urlencode(qs) - self.log("Added query string. Full URL is now {}".format(url), level='debug') + self.log("Added query string. Full URL is now {0}".format(url), level='debug') - self.log("URL to request is: {}".format(url)) + self.log("URL to request is: {0}".format(url)) - # Prep the SSL context - ssl_context = ssl.create_default_context() - if self.ignore_ssl_validation: - ssl_context.check_hostname = False - ssl_context.verify_mode = ssl.CERT_NONE - self.log("SSL certificate validation has been disabled for this call", level='warning') - - # Prep the URL opener - url_opener = urllib2.build_opener(urllib2.HTTPSHandler(context=ssl_context)) # Prep the request request_type = 'GET' @@ -189,7 +181,7 @@ def _request(self, request, auth_required=True): # some rest calls use a cookie to pass the sID if request['api'] == self.API_TYPE_REST and request['use_cookie_auth']: - headers['Cookie'] = 'sID="{}"'.format(self._sessions[self.API_TYPE_REST]) + headers['Cookie'] = 'sID="{0}"'.format(self._sessions[self.API_TYPE_REST]) if request['api'] == self.API_TYPE_REST and request['call'] in [ 'apiVersion', @@ -207,42 +199,54 @@ def _request(self, request, auth_required=True): 'content-type': 'application/soap+xml' } data = self._prep_data_for_soap(request['call'], request['data']) - url_request = urllib2.Request(url, data=data, headers=headers) + #url_request = urllib2.Request(url, data=data, headers=headers) request_type = 'POST' - self.log("Making a SOAP request with headers {}".format(headers), level='debug') - self.log(" and data {}".format(data), level='debug') + self.log("Making a SOAP request with headers {0}".format(headers), level='debug') + self.log(" and data {0}".format(data), level='debug') elif request['call'] == 'authentication/logout': - url_request = urllib2.Request(url, headers=headers) - setattr(url_request, 'get_method', lambda: 'DELETE') # make this request use the DELETE HTTP verb - request_type = 'DELETE' - self.log("Making a REST DELETE request with headers {}".format(headers), level='debug') + #url_request = urllib2.Request(url, headers=headers) + data = ""; + #setattr(url_request, 'get_method', lambda: 'DELETE') # make this request use the DELETE HTTP verb + #request_type = 'DELETE' + self.log("Making a REST DELETE request with headers {0}".format(headers), level='debug') elif request.has_key('data') and request['data']: # POST - url_request = urllib2.Request(url, data=json.dumps(request['data']), headers=headers) + data = json.dumps(request['data']); + #url_request = urllib2.Request(url, data=json.dumps(request['data']), headers=headers) request_type = 'POST' - self.log("Making a REST POST request with headers {}".format(headers), level='debug') - self.log(" and data {}".format(request['data']), level='debug') + self.log("Making a REST POST request with headers {0}".format(headers), level='debug') + self.log(" and data {0}".format(request['data']), level='debug') else: # GET - url_request = urllib2.Request(url, headers=headers) - self.log("Making a REST GET request with headers {}".format(headers), level='debug') + #url_request = urllib2.Request(url, headers=headers) + request_type = 'GET'; + self.log("Making a REST GET request with headers {0}".format(headers), level='debug') # Make the request response = None try: - response = url_opener.open(url_request) + if request_type == "POST": + response = requests.post(url, data = data, headers=headers, verify = False) + + if request_type == "DELETE": + response = requests.delete(url, data=data, headers= headers, verify=False) + + if request_type == "GET": + response = requests.get(url, data=data, headers = headers, verify = False) + + #response = url_opener.open(url_request) except Exception, url_err: - self.log("Failed to make {} {} call [{}]".format(request['api'].upper(), request_type, request['call'].lstrip('/')), err=url_err) + self.log("Failed to make {0} {1} call [{2}]".format(request['api'].upper(), request_type, request['call'].lstrip('/')), err=url_err) # Convert the request from JSON result = { - 'status': response.getcode() if response else None, - 'raw': response.read() if response else None, + 'status': response.status_code if response else None, + 'raw': response.text if response else None, 'headers': dict(response.headers) if response else dict(), 'data': None } bytes_of_data = len(result['raw']) if result['raw'] else 0 - self.log("Call returned HTTP status {} and {} bytes of data".format(result['status'], bytes_of_data), level='debug') + self.log("Call returned HTTP status {0} and {1} bytes of data".format(result['status'], bytes_of_data), level='debug') if response: if request['api'] == self.API_TYPE_SOAP: @@ -252,15 +256,15 @@ def _request(self, request, auth_required=True): full_data = xmltodict.parse(result['raw']) if full_data.has_key('soapenv:Envelope') and full_data['soapenv:Envelope'].has_key('soapenv:Body'): result['data'] = full_data['soapenv:Envelope']['soapenv:Body'] - if result['data'].has_key('{}Response'.format(request['call'])): - if result['data']['{}Response'.format(request['call'])].has_key('{}Return'.format(request['call'])): - result['data'] = result['data']['{}Response'.format(request['call'])]['{}Return'.format(request['call'])] + if result['data'].has_key('{0}Response'.format(request['call'])): + if result['data']['{0}Response'.format(request['call'])].has_key('{0}Return'.format(request['call'])): + result['data'] = result['data']['{0}Response'.format(request['call'])]['{0}Return'.format(request['call'])] else: - result['data'] = result['data']['{}Response'.format(request['call'])] + result['data'] = result['data']['{0}Response'.format(request['call'])] else: result['data'] = full_data except Exception, xmltodict_err: - self.log("Could not convert response from call {}".format(request['call']), err=xmltodict_err) + self.log("Could not convert response from call {0}".format(request['call']), err=xmltodict_err) else: # JSON response try: @@ -270,7 +274,7 @@ def _request(self, request, auth_required=True): except Exception, json_err: # report the exception as 'info' because it's not fatal and the data is # still captured in result['raw'] - self.log("Could not convert response from call {} to JSON. Threw exception:\n\t{}".format(request['call'], json_err), level='info') + self.log("Could not convert response from call {0} to JSON. Threw exception:\n\t{1}".format(request['call'], json_err), level='info') return result @@ -282,7 +286,7 @@ def _prefix_keys(self, prefix, d): if not type(d) == type({}): return d new_d = d.copy() for k,v in d.items(): - new_key = u"{}:{}".format(prefix, k) + new_key = u"{0}:{1}".format(prefix, k) new_v = v if type(v) == type({}): new_v = self._prefix_keys(prefix, v) new_d[new_key] = new_v @@ -300,7 +304,7 @@ def _prep_data_for_soap(self, call, details): - {} + {0} """.format(data).strip() @@ -325,13 +329,13 @@ def log(self, message='', err=None, level='info'): if err: level = 'error' - message += ' Threw exception:\n\t{}'.format(err) + message += ' Threw exception:\n\t{0}'.format(err) try: func = getattr(self.logger, level.lower()) func(message) except Exception, log_err: - self.logger.critical("Could not write to log. Threw exception:\n\t{}".format(log_err)) + self.logger.critical("Could not write to log. Threw exception:\n\t{0}".format(log_err)) class CoreDict(dict): def __init__(self): @@ -398,7 +402,7 @@ def find(self, **kwargs): for match_attr_val in match_attr_vals: if type(attr_to_check) in [type(''), type(u'')]: # string comparison - match = re.search(r'{}'.format(match_attr_val), attr_to_check) + match = re.search(r'{0}'.format(match_attr_val), attr_to_check) if match: item_matches = True break # and move on to the new kwarg @@ -438,7 +442,7 @@ def _set_properties(self, api_response, log_func): # make sure any integer IDs are stored as an int if new_key == 'id' and re.search('^\d+$', v.strip()): val = int(v) if new_key == 'policy_id': - if '@xsi:nil' in "{}".format(v): + if '@xsi:nil' in "{0}".format(v): val = None elif re.search('^\d+$', "".join(v.strip())): val = int(v) @@ -447,7 +451,7 @@ def _set_properties(self, api_response, log_func): setattr(self, new_key, val) except Exception, err: if log_func: - log_func("Could not set property {} to value {} for object {}".format(k, v, s)) + log_func("Could not set property {0} to value {1} for object {2}".format(k, v, s)) try: setattr(self, log, log_func) except: pass @@ -532,7 +536,7 @@ def find(self, **kwargs): for match_attr_val in match_attr_vals: if type(attr_to_check) in [type(''), type(u'')]: # string comparison - match = re.search(r'{}'.format(match_attr_val), attr_to_check) + match = re.search(r'{0}'.format(match_attr_val), attr_to_check) if match: item_matches = True break # and move on to the new kwarg diff --git a/deepsecurity/dsm.py b/deepsecurity/dsm.py index 081f06d..0734670 100644 --- a/deepsecurity/dsm.py +++ b/deepsecurity/dsm.py @@ -61,8 +61,8 @@ def __str__(self): """ Return a better string representation """ - dsm_port = ":{}".format(self.port) if self.port else "" - return "Manager <{}{}>".format(self.hostname, dsm_port) + dsm_port = ":{0}".format(self.port) if self.port else "" + return "Manager <{0}{1}>".format(self.hostname, dsm_port) # ******************************************************************* # properties @@ -124,9 +124,9 @@ def _set_endpoints(self): """ Set the API endpoints based on the current configuration """ - dsm_port = ":{}".format(self.port) if self.port else "" # allow for endpoints with no port specified - self._rest_api_endpoint = "https://{}{}/{}rest".format(self.hostname, dsm_port, self.prefix) - self._soap_api_endpoint = "https://{}{}/{}webservice/Manager".format(self.hostname, dsm_port, self.prefix) + dsm_port = ":{0}".format(self.port) if self.port else "" # allow for endpoints with no port specified + self._rest_api_endpoint = "https://{0}{1}/{2}rest".format(self.hostname, dsm_port, self.prefix) + self._soap_api_endpoint = "https://{0}{1}/{2}webservice/Manager".format(self.hostname, dsm_port, self.prefix) def _reset_session(self): """ @@ -153,7 +153,7 @@ def _get_local_config_file(self): """ user_credentials_path = os.path.expanduser('~/.deepsecurity/credentials') if os.path.exists(user_credentials_path): - self.log("Found local credentials file at [{}]".format(user_credentials_path)) + self.log("Found local credentials file at [{0}]".format(user_credentials_path)) credentials = { 'username': None, 'password': None, @@ -175,10 +175,10 @@ def _get_local_config_file(self): if v: if k in dir(self): try: - setattr(self, "_{}".format(k), v) - self.log("Loaded {} from local credentials file".format(k)) + setattr(self, "_{0}".format(k), v) + self.log("Loaded {0} from local credentials file".format(k)) except Exception, err: - self.log("Unable to load {} from local credentials file".format(k)) + self.log("Unable to load {0} from local credentials file".format(k)) def sign_in(self): """ diff --git a/deepsecurity/environments.py b/deepsecurity/environments.py index 982a00d..09f0ca6 100644 --- a/deepsecurity/environments.py +++ b/deepsecurity/environments.py @@ -62,7 +62,7 @@ def add_aws_account(self, name, aws_access_key=None, aws_secret_key=None, region 'accessKey': aws_access_key, 'secretKey': aws_secret_key, 'cloudType': 'AMAZON', - 'name': '{} / {}'.format(name, region_to_add), + 'name': '{0} / {1}'.format(name, region_to_add), 'cloudRegion': regions[region_to_add], }, } diff --git a/deepsecurity/policies.py b/deepsecurity/policies.py index 0632fa8..f08c311 100644 --- a/deepsecurity/policies.py +++ b/deepsecurity/policies.py @@ -27,9 +27,9 @@ def get(self): if policy_obj: try: self[policy_obj.id] = policy_obj - self.log("Added Policy {}".format(policy_obj.id), level='debug') + self.log("Added Policy {0}".format(policy_obj.id), level='debug') except Exception, err: - self.log("Could not add Policy {}".format(policy_obj), level='warning', err=err) + self.log("Could not add Policy {0}".format(policy_obj), level='warning', err=err) return len(self) @@ -134,7 +134,7 @@ def create(self, name, parent_profile_id=None, if new_policy: self[new_policy.id] = new_policy result = new_policy.id - self.log("Added new policy #{}".format(new_policy.id)) + self.log("Added new policy #{0}".format(new_policy.id)) except Exception, err: self.log("Could not create new policy from API response", err=err) else: @@ -168,7 +168,7 @@ def get(self, intrusion_prevention=True, firewall=True, integrity_monitoring=Tru if get: soap_call = self.manager._get_request_format(call=call) if call == 'DPIRuleRetrieveAll': - self.log("Calling {}. This may take 15-30 seconds as the call returns a substantial amount of data".format(call), level='warning') + self.log("Calling {0}. This may take 15-30 seconds as the call returns a substantial amount of data".format(call), level='warning') response = self.manager._request(soap_call) if response and response['status'] == 200: @@ -180,11 +180,13 @@ def get(self, intrusion_prevention=True, firewall=True, integrity_monitoring=Tru rule_obj.cve_numbers = rule_obj.cve_numbers.split(', ') if type(rule_obj.cve_numbers) in [type(''), type(u'')]: rule_obj.cve_numbers = [ rule_obj.cve_numbers ] - rule_id = '{}-{: >10}'.format(rule_key, i) + #TODO: find out what this is. + rule_id = '{0}-'.format(rule_key) + '{0:10d}'.format(i) + #rule_id = rule_id + ('%10s' % i); if 'id' in dir(rule_obj): rule_id = rule_obj.id elif 'tbuid' in dir(rule_obj): rule_id = rule_obj.tbuid self[rule_key][rule_id] = rule_obj - self.log("Added Rule {} from call {}".format(rule_id, call), level='debug') + self.log("Added Rule {0} from call {1}".format(rule_id, call), level='debug') return len(self) @@ -228,7 +230,7 @@ def _flatten_rules(self): rules = getattr(self, rule_type) if rules: for rule in rules['item']: - self.rules['{}-{}'.format(rule_type.replace('rule_ids', ''), rule)] = None + self.rules['{0}-{1}'.format(rule_type.replace('rule_ids', ''), rule)] = None def save(self): """ @@ -248,7 +250,7 @@ def save(self): else: result = False if 'log' in dir(self): - self.log("Could not save the policy. Returned: {}".format(response), level='error') + self.log("Could not save the policy. Returned: {0}".format(response), level='error') return result