Skip to content

Commit f134eef

Browse files
authored
Merge pull request #28 from edarevsky/add-option-to-disable-host-check
Add option to disable host check when sending requests
2 parents 07b4959 + 70132de commit f134eef

1 file changed

Lines changed: 35 additions & 23 deletions

File tree

GSSDK.py

Lines changed: 35 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
from urllib.request import ProxyHandler
1818
from urllib.request import install_opener
1919
from urllib.request import urlopen
20-
from http.client import HTTPConnection
20+
from http.client import HTTPSConnection
2121
from http.client import HTTPS_PORT
2222
from urllib.request import HTTPSHandler
2323
from urllib.parse import quote_plus
@@ -29,7 +29,7 @@
2929
from urllib2 import ProxyHandler
3030
from urllib2 import install_opener
3131
from urllib2 import urlopen
32-
from httplib import HTTPConnection
32+
from httplib import HTTPSConnection
3333
from httplib import HTTPS_PORT
3434
from urllib2 import HTTPSHandler
3535
from urllib import quote_plus
@@ -41,7 +41,7 @@
4141
import socket
4242
import os
4343
import ssl
44-
import copy
44+
import copy
4545

4646
from hashlib import sha1
4747
from base64 import b64decode, b64encode
@@ -68,7 +68,7 @@ def __str__(self):
6868

6969
class GSRequest():
7070
DEFAULT_API_DOMAIN = "us1.gigya.com"
71-
VERSION = "3.5.0"
71+
VERSION = "3.5.1"
7272
caCertsPath = os.path.join(os.path.dirname(__file__), "cacert.pem")
7373

7474
_domain = ""
@@ -85,7 +85,7 @@ class GSRequest():
8585
_useHTTPS = False
8686
_apiDomain = DEFAULT_API_DOMAIN
8787

88-
def __init__(self, apiKey=None, secretKey=None, apiMethod=None, params=None, useHTTPS=False, userKey=None):
88+
def __init__(self, apiKey=None, secretKey=None, apiMethod=None, params=None, useHTTPS=False, userKey=None, enable_host_check=True):
8989
"""
9090
Constructs a request using the apiKey and secretKey.
9191
@param apiKey
@@ -95,6 +95,7 @@ def __init__(self, apiKey=None, secretKey=None, apiMethod=None, params=None, use
9595
@param params the request parameters
9696
@param useHTTPS useHTTPS set this to true if you want to use HTTPS.
9797
@param userKey A key of an admin user with extra permissions.
98+
@param enable_host_check Hostcheck can be disabled by passing enable_host_check=false when using HTTPS. Can be necessary when using proxy. Default is True
9899
If this parameter is provided, then the secretKey parameter is assumed to be the admin user's secret key and not the site's secret key.
99100
"""
100101

@@ -118,6 +119,7 @@ def __init__(self, apiKey=None, secretKey=None, apiMethod=None, params=None, use
118119
self._secretKey = secretKey
119120
self._userKey = userKey
120121
self._traceLog = list()
122+
self._enableHostCheck = enable_host_check
121123
self.traceField("apiMethod", apiMethod)
122124
self.traceField("apiKey", apiKey)
123125

@@ -188,7 +190,7 @@ def send(self, timeout=None):
188190

189191
return GSResponse(self._method, None, self._params, errCode, errMsg, self._traceLog)
190192

191-
def sendRequest(self, httpMethod, domain, path, params, token, secret=None, useHTTPS=False, timeout=None, userKey=None):
193+
def sendRequest(self, httpMethod, domain, path, params, token, secret=None, useHTTPS=False, timeout=None, userKey=None, enable_host_check=True):
192194

193195
params["sdk"] = "python_" + self.VERSION
194196
# prepare query params
@@ -216,16 +218,15 @@ def sendRequest(self, httpMethod, domain, path, params, token, secret=None, useH
216218
params["oauth_token"] = token
217219

218220
# get rest response.
219-
res = self.curl(resourceURI, params, timeout)
221+
res = self.curl(resourceURI, params, timeout, enable_host_check)
220222

221223
return res
222224

223225

224-
def curl(self, url, params=None, timeout=None):
226+
def curl(self, url, params=None, timeout=None, enable_host_check=True):
225227

226228
queryString = self.buildQS(params)
227229

228-
229230
self.traceField("URL", url)
230231
self.traceField("postData", queryString)
231232

@@ -234,12 +235,12 @@ def curl(self, url, params=None, timeout=None):
234235
if self._proxy:
235236
opener = build_opener(
236237
HTTPHandler(),
237-
ValidHTTPSHandler(),
238+
ValidHTTPSHandler(enable_host_check), # maybe always send False???
238239
ProxyHandler({proto: self._proxy}))
239240
else:
240241
opener = build_opener(
241242
HTTPHandler(),
242-
ValidHTTPSHandler())
243+
ValidHTTPSHandler(enable_host_check))
243244

244245
queryString = queryString.encode('utf-8')
245246

@@ -440,11 +441,12 @@ def __str__(self):
440441
return sb
441442

442443

443-
class ValidHTTPSConnection(HTTPConnection):
444+
class ValidHTTPSConnection(HTTPSConnection):
444445
default_port = HTTPS_PORT
445446

446447
def __init__(self, *args, **kwargs):
447-
HTTPConnection.__init__(self, *args, **kwargs)
448+
HTTPSConnection.__init__(self, *args, **kwargs)
449+
self._context = kwargs.get('context')
448450

449451
def connect(self):
450452
sock = socket.create_connection((self.host, self.port), self.timeout, self.source_address)
@@ -453,18 +455,28 @@ def connect(self):
453455
self.sock = sock
454456
self._tunnel()
455457

456-
context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
457-
context.minumum_version = ssl.TLSVersion.TLSv1_2
458-
context.load_verify_locations(GSRequest.caCertsPath)
459-
context.verify_mode = ssl.CERT_REQUIRED
460-
context.check_hostname = True
461-
462-
self.sock = context.wrap_socket(sock, server_hostname=self.host)
458+
self.sock = self._context.wrap_socket(sock, server_hostname=self.host)
463459

464460

465461
class ValidHTTPSHandler(HTTPSHandler):
462+
def __init__(self, enable_host_check=True):
463+
super().__init__()
464+
self._enableHostCheck = enable_host_check
465+
466466
def https_open(self, req):
467-
return self.do_open(ValidHTTPSConnection, req)
467+
return self.do_open(self.get_connection, req)
468+
469+
def get_connection(self, host, timeout):
470+
return ValidHTTPSConnection(host, timeout = timeout, context = self.create_context())
471+
472+
def create_context(self):
473+
context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
474+
context.minimum_version = ssl.TLSVersion.TLSv1_2
475+
context.load_verify_locations(GSRequest.caCertsPath)
476+
context.verify_mode = ssl.CERT_REQUIRED
477+
context.check_hostname = self._enableHostCheck
478+
479+
return context
468480

469481

470482
class SigUtils():
@@ -483,7 +495,7 @@ def validateUserSignature(UID, timestamp, secret, signature, expiration=None):
483495
def validateUserSignatureWithExpiration(UID, timestamp, secret, signature, expiration):
484496
expired = SigUtils.signatureTimestampExpired(timestamp, expiration)
485497
signatureValidated = SigUtils.validateUserSignature(UID, timestamp, secret, signature)
486-
return not expired and signatureValidated
498+
return not expired and signatureValidated
487499

488500
@staticmethod
489501
def validateFriendSignature(UID, timestamp, friendUID, secret, signature, expiration=None):
@@ -493,7 +505,7 @@ def validateFriendSignature(UID, timestamp, friendUID, secret, signature, expira
493505
return expectedSig == signature
494506
else:
495507
expired = SigUtils.signatureTimestampExpired(timestamp, expiration)
496-
return not expired and expectedSig == signature
508+
return not expired and expectedSig == signature
497509

498510
@staticmethod
499511
def validateFriendSignatureWithExpiration(UID, timestamp, friendUID, secret, signature, expiration):

0 commit comments

Comments
 (0)