Skip to content

Commit cead38e

Browse files
committed
add proxy support to OCSP
1 parent 2f8e306 commit cead38e

File tree

4 files changed

+71
-40
lines changed

4 files changed

+71
-40
lines changed

chunk_downloader.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from .errorcode import (ER_NO_ADDITIONAL_CHUNK, ER_CHUNK_DOWNLOAD_FAILED)
1313
from .errors import (Error, OperationalError)
1414
from .network import (SnowflakeRestful, NO_TOKEN, MAX_CONNECTION_POOL)
15+
from .ssl_wrap_socket import (set_proxies)
1516

1617
DEFAULT_REQUEST_TIMEOUT = 3600
1718
DEFAULT_CLIENT_RESULT_PREFETCH_SLOTS = 2
@@ -262,7 +263,7 @@ def _get_request(
262263
GET request for Large Result set chunkloader
263264
"""
264265
# sharing the proxy and certificate
265-
proxies = SnowflakeRestful.set_proxies(
266+
proxies = set_proxies(
266267
self._connection.rest._proxy_host,
267268
self._connection.rest._proxy_port,
268269
self._connection.rest._proxy_user,

network.py

Lines changed: 12 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
from .sqlstate import (SQLSTATE_CONNECTION_NOT_EXISTS,
4343
SQLSTATE_CONNECTION_WAS_NOT_ESTABLISHED,
4444
SQLSTATE_CONNECTION_REJECTED)
45+
from .ssl_wrap_socket import (set_proxies)
4546
from .util_text import split_rows_from_stream
4647
from .version import VERSION
4748

@@ -151,10 +152,18 @@ def __init__(self, host=u'127.0.0.1', port=8080,
151152
self._max_connection_pool = max_connection_pool
152153
self._connection = connection
153154
self.logger = getLogger(__name__)
155+
156+
# insecure mode (disabled by default)
154157
ssl_wrap_socket.FEATURE_INSECURE_MODE = \
155158
self._connection and self._connection._insecure_mode
159+
# cache file name (enabled by default)
156160
ssl_wrap_socket.FEATURE_OCSP_RESPONSE_CACHE_FILE_NAME = \
157161
self._connection and self._connection._ocsp_response_cache_filename
162+
#
163+
ssl_wrap_socket.PROXY_HOST = self._proxy_host
164+
ssl_wrap_socket.PROXY_PORT = self._proxy_port
165+
ssl_wrap_socket.PROXY_USER = self._proxy_user
166+
ssl_wrap_socket.PROXY_PASSWORD = self._proxy_password
158167

159168
# This is to address the issue where requests hangs
160169
_ = 'dummy'.encode('idna').decode('utf-8')
@@ -168,35 +177,6 @@ def token(self):
168177
def master_token(self):
169178
return self._master_token if hasattr(self, u'_master_token') else None
170179

171-
@staticmethod
172-
def set_proxies(proxy_host,
173-
proxy_port,
174-
proxy_user=None,
175-
proxy_password=None):
176-
proxies = None
177-
if proxy_host and proxy_port:
178-
if proxy_user or proxy_password:
179-
proxy_auth = u'{proxy_user}:{proxy_password}@'.format(
180-
proxy_user=proxy_user if proxy_user is not None else '',
181-
proxy_password=proxy_password if proxy_password is not
182-
None else ''
183-
)
184-
else:
185-
proxy_auth = u''
186-
proxies = {
187-
u'http': u'http://{proxy_auth}{proxy_host}:{proxy_port}'.format(
188-
proxy_host=proxy_host,
189-
proxy_port=TO_UNICODE(proxy_port),
190-
proxy_auth=proxy_auth,
191-
),
192-
u'https': u'http://{proxy_auth}{proxy_host}:{proxy_port}'.format(
193-
proxy_host=proxy_host,
194-
proxy_port=TO_UNICODE(proxy_port),
195-
proxy_auth=proxy_auth,
196-
),
197-
}
198-
return proxies
199-
200180
def close(self):
201181
if hasattr(self, u'_token'):
202182
del self._token
@@ -509,7 +489,7 @@ def _get_request(self, url, headers, token=None, timeout=None):
509489
port=self._port,
510490
url=url,
511491
)
512-
proxies = SnowflakeRestful.set_proxies(
492+
proxies = set_proxies(
513493
self._proxy_host, self._proxy_port, self._proxy_user,
514494
self._proxy_password
515495
)
@@ -544,7 +524,7 @@ def _post_request(self, url, headers, body, token=None,
544524
port=self._port,
545525
url=url,
546526
)
547-
proxies = SnowflakeRestful.set_proxies(
527+
proxies = set_proxies(
548528
self._proxy_host, self._proxy_port, self._proxy_user,
549529
self._proxy_password)
550530

@@ -883,7 +863,7 @@ def authenticate_by_saml(self, authenticator, account, user, password):
883863
token_url = data[u'tokenUrl']
884864
sso_url = data[u'ssoUrl']
885865

886-
proxies = SnowflakeRestful.set_proxies(
866+
proxies = set_proxies(
887867
self._proxy_host, self._proxy_port, self._proxy_user,
888868
self._proxy_password)
889869
self.logger.debug(u'token_url=%s, proxies=%s', token_url, proxies)

ocsp_pyopenssl.py

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -513,7 +513,7 @@ def process_ocsp_response(response, ocsp_issuer):
513513
return single_response_map
514514

515515

516-
def execute_ocsp_request(ocsp_uri, cert_id, do_retry=True):
516+
def execute_ocsp_request(ocsp_uri, cert_id, proxies=None, do_retry=True):
517517
"""
518518
Executes OCSP request for the given cert id
519519
"""
@@ -558,6 +558,7 @@ def execute_ocsp_request(ocsp_uri, cert_id, do_retry=True):
558558
'Host': parsed_url.hostname.encode(
559559
'utf-8'),
560560
},
561+
proxies=proxies,
561562
data=data)
562563
if response.status_code == OK:
563564
logger.debug("OCSP response was successfully returned")
@@ -1014,13 +1015,15 @@ class SnowflakeOCSP(object):
10141015
OCSP validator using PyOpenSSL.
10151016
"""
10161017

1017-
def __init__(self, must_use_cache=False, ocsp_response_cache_url=None):
1018+
def __init__(self, must_use_cache=False,
1019+
proxies=None, ocsp_response_cache_url=None):
10181020
"""
10191021
:param must_use_cache: Test purpose. must use cache or raises an error
10201022
:param ocsp_response_cache_url: the location of cache file
10211023
"""
10221024
self.logger = getLogger(__name__)
10231025
self._must_use_cache = must_use_cache
1026+
self._proxies = proxies
10241027
if ocsp_response_cache_url is None and CACHE_DIR is not None:
10251028
self._ocsp_response_cache_url = 'file://' + path.join(
10261029
CACHE_DIR, 'ocsp_response_cache')
@@ -1148,8 +1151,10 @@ def validate_by_direct_connection(
11481151
if not cache_status:
11491152
# not cached or invalid
11501153
self.logger.info('getting OCSP response from remote')
1151-
ocsp_response = execute_ocsp_request(ocsp_uri, cert_id,
1152-
do_retry=do_retry)
1154+
ocsp_response = execute_ocsp_request(
1155+
ocsp_uri, cert_id,
1156+
proxies=self._proxies,
1157+
do_retry=do_retry)
11531158
else:
11541159
self.logger.info('using OCSP response cache')
11551160
single_response_map = process_ocsp_response(
@@ -1175,7 +1180,8 @@ def validate_by_direct_connection(
11751180

11761181
return True, cert_id, ocsp_response
11771182

1178-
def generate_cert_id_response(self, hostname, connection, do_retry=True):
1183+
def generate_cert_id_response(
1184+
self, hostname, connection, proxies=None, do_retry=True):
11791185
current_time = int(time.time())
11801186
cert_data = _extract_certificate_chain(connection)
11811187
results = {}
@@ -1188,7 +1194,8 @@ def generate_cert_id_response(self, hostname, connection, do_retry=True):
11881194
if ocsp_uri:
11891195
ret, cert_id, ocsp_response = \
11901196
self.validate_by_direct_connection(
1191-
ocsp_uri, ocsp_issuer, ocsp_subject, do_retry)
1197+
ocsp_uri, ocsp_issuer, ocsp_subject,
1198+
do_retry=do_retry)
11921199
if ret and cert_id and ocsp_response:
11931200
cert_id_der = der_encoder.encode(cert_id)
11941201
results[cert_id_der] = (
@@ -1242,7 +1249,7 @@ def _openssl_connect(hostname, port=443):
12421249

12431250
ocsp = SnowflakeOCSP()
12441251
connection = _openssl_connect(url, port)
1245-
results = ocsp.generate_cert_id_response(url, connection)
1252+
results = ocsp.generate_cert_id_response(url, connection, proxies=None)
12461253
current_Time = int(time.time())
12471254
print("Target URL: https://{0}:{1}/".format(url, port))
12481255
print("Current Time: {0}".format(

ssl_wrap_socket.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,14 @@
1818
"""
1919
FEATURE_OCSP_RESPONSE_CACHE_FILE_NAME = None
2020

21+
"""
22+
Proxy, shared across all connections
23+
"""
24+
PROXY_HOST = None
25+
PROXY_PORT = None
26+
PROXY_USER = None
27+
PROXY_PASSWORD = None
28+
2129
# imports
2230
import select
2331
import socket
@@ -36,6 +44,7 @@
3644
from cryptography.hazmat.backends.openssl import backend as openssl_backend
3745
from cryptography.hazmat.backends.openssl.x509 import _Certificate
3846

47+
from .compat import (TO_UNICODE)
3948
from .errorcode import (ER_SERVER_CERTIFICATE_REVOKED)
4049
from .errors import (OperationalError)
4150
from .ocsp_pyopenssl import SnowflakeOCSP
@@ -414,6 +423,8 @@ def ssl_wrap_socket_with_ocsp(
414423
FEATURE_OCSP_RESPONSE_CACHE_FILE_NAME)
415424
if not FEATURE_INSECURE_MODE:
416425
v = SnowflakeOCSP(
426+
proxies=set_proxies(PROXY_HOST, PROXY_PORT, PROXY_USER,
427+
PROXY_PASSWORD),
417428
ocsp_response_cache_url=FEATURE_OCSP_RESPONSE_CACHE_FILE_NAME
418429
).validate(server_hostname, ret.connection)
419430
if not v:
@@ -432,6 +443,38 @@ def ssl_wrap_socket_with_ocsp(
432443
return ret
433444

434445

446+
def set_proxies(proxy_host,
447+
proxy_port,
448+
proxy_user=None,
449+
proxy_password=None):
450+
"""
451+
Set proxy dict for requests
452+
"""
453+
proxies = None
454+
if proxy_host and proxy_port:
455+
if proxy_user or proxy_password:
456+
proxy_auth = u'{proxy_user}:{proxy_password}@'.format(
457+
proxy_user=proxy_user if proxy_user is not None else '',
458+
proxy_password=proxy_password if proxy_password is not
459+
None else ''
460+
)
461+
else:
462+
proxy_auth = u''
463+
proxies = {
464+
u'http': u'http://{proxy_auth}{proxy_host}:{proxy_port}'.format(
465+
proxy_host=proxy_host,
466+
proxy_port=TO_UNICODE(proxy_port),
467+
proxy_auth=proxy_auth,
468+
),
469+
u'https': u'http://{proxy_auth}{proxy_host}:{proxy_port}'.format(
470+
proxy_host=proxy_host,
471+
proxy_port=TO_UNICODE(proxy_port),
472+
proxy_auth=proxy_auth,
473+
),
474+
}
475+
return proxies
476+
477+
435478
def inject_into_urllib3():
436479
"""
437480
Monkey-patch urllib3 with PyOpenSSL-backed SSL-support and OCSP

0 commit comments

Comments
 (0)