Skip to content
This repository was archived by the owner on Aug 12, 2019. It is now read-only.

Commit e420955

Browse files
committed
Mid-refactor for ignoring self-signed SSL certificates. Removed ability to load local WSDL as it causes issues with mismatched versions
1 parent 23850e9 commit e420955

File tree

3 files changed

+62
-25
lines changed

3 files changed

+62
-25
lines changed

Diff for: deepsecurity/deepsecurity.latest.wsdl.webarchive

3.73 MB
Binary file not shown.

Diff for: deepsecurity/manager.py

+32-25
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,15 @@
1818
import computer_group
1919
import ip_list
2020
import policy
21+
import soap_https_handler
2122

2223
class Manager(object):
2324
"""
2425
Class representing the Deep Security Manager and all of it's
2526
functionality. Well, at least the functionality available via the
2627
SOAP and REST APIs
2728
"""
28-
def __init__(self, username=None, password=None, tenant=None, dsm_hostname=None, start_session=True):
29+
def __init__(self, username=None, password=None, tenant='Primary', dsm_hostname=None, dsm_port=443, start_session=True, ignore_ssl_validation=False, debug=False):
2930
"""
3031
Create a new reference to a Deep Security Manager
3132
@@ -34,16 +35,18 @@ def __init__(self, username=None, password=None, tenant=None, dsm_hostname=None,
3435
tenant = In a multi-tenant deployment (like Deep Security as a Service) this is the tenant/account name.
3536
For non-multi tenant accounts this can be left blank or set to "primary"
3637
dsm_hostname = The hostname of the Deep Security Manager to access, defaults to Deep Security as a Service
38+
dsm_port = The port of the Deep Security Manager to access, defaults to Deep Security as a Service
3739
start_session = Whether or not to automatically start a session with the specified Deep Security Manager
3840
"""
3941
self.version = '9.6'
4042
self._hostname = 'app.deepsecurity.trendmicro.com' if not dsm_hostname else dsm_hostname # default to Deep Security as a Service
41-
self._port = 443 # on-premise defaults to 4119
43+
self._port = dsm_port # on-premise defaults to 4119
4244
self.rest_api_path = 'rest'
4345
self.soap_api_wsdl = 'webservice/Manager?WSDL'
4446
self.session_id_rest = None
4547
self.session_id_soap = None
4648
self.soap_client = None
49+
self.ignore_ssl_validation = ignore_ssl_validation
4750

4851
# Deep Security data
4952
self.computer_groups = {}
@@ -54,12 +57,13 @@ def __init__(self, username=None, password=None, tenant=None, dsm_hostname=None,
5457
self.ip_lists = {}
5558

5659
# Setup functions
57-
self.debug = False
60+
self._debug = debug
5861
self.logger = self._setup_logging()
5962
self._set_url()
6063

6164
# Try to start a session if possible
6265
if username and password and start_session:
66+
self.log("Attempting to start a session")
6367
self.start_session(username=username, password=password, tenant=tenant)
6468

6569
def __del__(self):
@@ -105,6 +109,17 @@ def port(self, val):
105109
self._port = val
106110
self._set_url()
107111

112+
# Any change to debug requires that logging be reset
113+
@property
114+
def debug(self): return self._debug
115+
116+
@debug.setter
117+
def debug(self, val):
118+
"""
119+
Reset the logging configuration on change
120+
"""
121+
self._setup_logging()
122+
108123
# *****************************************************************
109124
# 'Private' methods
110125
# *****************************************************************
@@ -115,16 +130,18 @@ def _setup_logging(self):
115130

116131
# Based on tips from http://www.blog.pythonlibrary.org/2012/08/02/python-101-an-intro-to-logging/
117132
logging.basicConfig(level=logging.ERROR)
133+
if self._debug:
134+
logging.basicConfig(level=logging.DEBUG)
118135

119136
# turn down suds logging
120137
logging.getLogger('suds.client').setLevel(logging.ERROR)
121-
if self.debug:
138+
if self._debug:
122139
logging.getLogger('suds.client').setLevel(logging.DEBUG)
123140

124141
# setup module logging
125142
logger = logging.getLogger("DeepSecurity.API")
126143
logger.setLevel(logging.WARNING)
127-
if self.debug:
144+
if self._debug:
128145
logger.setLevel(logging.DEBUG)
129146

130147
formatter = logging.Formatter('[%(asctime)s]\t%(message)s', '%Y-%m-%d %H:%M:%S')
@@ -159,25 +176,12 @@ def _get_soap_client(self, force_load_from_url=False):
159176
"""
160177
soap_client = None
161178

162-
# First, try to use a local WSDL
163-
wsdl_path = None
164-
current_path = os.path.realpath(os.path.dirname(inspect.getfile(inspect.currentframe())))
165-
found_wsdl = []
166-
for fn in os.listdir(current_path):
167-
if fn.endswith('.wsdl.xml'): found_wsdl.append(os.path.join(current_path, fn))
168-
169-
found_wsdl.sort()
170-
171-
if len(found_wsdl) > 0:
172-
if 'deepsecurity.latest.wsdl.xml' in found_wsdl:
173-
wsdl_path = 'file://deepsecurity.latest.wsdl.xml'
174-
else:
175-
wsdl_path = 'file://{}'.format(found_wsdl[0])
176-
177-
if not wsdl_path or force_load_from_url: wsdl_path = self.base_url_for_soap
178-
179179
try:
180-
soap_client = suds.client.Client(wsdl_path)
180+
if self.ignore_ssl_validation:
181+
self.log("Ignoring SSL validation for SOAP API access")
182+
soap_client = suds.client.Client(self.base_url_for_soap, transport=soap_https_handler.HTTPSIgnoreValidation())
183+
else:
184+
soap_client = suds.client.Client(self.base_url_for_soap)
181185
except Exception, soap_err:
182186
self.log("Could not create a SOAP client. Threw exception: %s" % soap_err)
183187
soap_client = None
@@ -362,7 +366,7 @@ def start_session(self, username=None, password=None, tenant=None, force_new_ses
362366
# We need to make different calls for tenants and the primary
363367
soap_call = None
364368
rest_call = None
365-
if not tenant:
369+
if not tenant or tenant.lower() == "primary":
366370
soap_call = self._get_call_structure()
367371
soap_call['auth'] = False
368372
soap_call['method'] = 'authenticate'
@@ -414,7 +418,10 @@ def start_session(self, username=None, password=None, tenant=None, force_new_ses
414418

415419
# Do we have an existing REST session?
416420
if not self.session_id_rest or force_new_session:
417-
if rest_call: self.session_id_rest = (self._make_call(rest_call)).text
421+
if rest_call:
422+
response = self._make_call(rest_call)
423+
if response:
424+
self.session_id_rest = response.text
418425

419426
if self.session_id_rest:
420427
self.log("Authenticated successfully, starting REST session [%s]" % self.session_id_rest)

Diff for: deepsecurity/soap_https_handler.py

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import ssl
2+
import urllib2
3+
from suds.transport.http import HttpTransport, Reply, TransportError
4+
5+
class HTTPSIgnoreValidation(HttpTransport):
6+
"""
7+
An HTTPS Handler set to ignore SSL certificate validation
8+
9+
The software and AWS Marketplace installations of Deep Security default to using
10+
a self-signed certificate and require this handler for SOAP API access
11+
12+
With help from;
13+
@nitwit via http://stackoverflow.com/questions/6277027/suds-over-https-with-cert
14+
@enno groper via http://stackoverflow.com/questions/19268548/python-ignore-certicate-validation-urllib2
15+
"""
16+
def __init__(self, *args, **kwargs): HttpTransport.__init__(self, *args, **kwargs)
17+
18+
def u2open(self, u2request):
19+
"""
20+
Open a connection.
21+
@param u2request: A urllib2 request.
22+
@type u2request: urllib2.Requet.
23+
@return: The opened file-like urllib2 object.
24+
@rtype: fp
25+
"""
26+
tm = self.options.timeout
27+
ctx = ssl.create_default_context()
28+
ctx.check_hostname = False
29+
ctx.verify_mode = ssl.CERT_NONE
30+
return urllib2.urlopen(u2request, context=ctx)

0 commit comments

Comments
 (0)