-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add ssl_context to TCPConnector #211
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -223,10 +223,17 @@ class TCPConnector(BaseConnector): | |
""" | ||
|
||
def __init__(self, *args, verify_ssl=True, | ||
resolve=False, family=socket.AF_INET, **kwargs): | ||
resolve=False, family=socket.AF_INET, ssl_context=None, | ||
**kwargs): | ||
if not verify_ssl and ssl_context is not None: | ||
raise ValueError( | ||
"Either disable ssl certificate validation by " | ||
"verify_ssl=False or specify ssl_context, not both.") | ||
|
||
super().__init__(*args, **kwargs) | ||
|
||
self._verify_ssl = verify_ssl | ||
self._ssl_context = ssl_context | ||
self._family = family | ||
self._resolve = resolve | ||
self._resolved_hosts = {} | ||
|
@@ -236,6 +243,33 @@ def verify_ssl(self): | |
"""Do check for ssl certifications?""" | ||
return self._verify_ssl | ||
|
||
@property | ||
def ssl_context(self): | ||
"""SSLContext instance for https requests. | ||
|
||
Lazy property, creates context on demand. | ||
""" | ||
if self._ssl_context is None: | ||
if not self._verify_ssl: | ||
sslcontext = ssl.SSLContext(ssl.PROTOCOL_SSLv23) | ||
sslcontext.options |= ssl.OP_NO_SSLv2 | ||
sslcontext.options |= ssl.OP_NO_SSLv3 | ||
sslcontext.options |= getattr(ssl, "OP_NO_COMPRESSION", 0) | ||
sslcontext.set_default_verify_paths() | ||
elif hasattr(ssl, 'create_default_context'): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i think it should be module global variable |
||
# Python 3.4+ | ||
sslcontext = ssl.create_default_context() | ||
else: # pragma: no cover | ||
# Fallback for Python 3.3. | ||
sslcontext = ssl.SSLContext(ssl.PROTOCOL_SSLv23) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ssl.create_default_context() does a little bit more than his fallback version, like compression disable and check hostnames. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I just borrowed the fallback code from There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hm..while it sounds good I wonder it also good if aiohttp will uncanny make client/server affected to CRIME attack depending on under which Python version it runs. I think it's wise to synchronize behaviour for 3.3 with 3.4. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Python 3.3 has no There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well, all the need is to sync the behavior. Currently it's different from the fallback case by lines 413, 418 and 437 which gives us next additional code:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sounds good, except I like to try use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I didn't found ssl.Purpose for 3.3 quickly, so just picked raw enum value instead. Might worth to add some comment about where it comes from. |
||
sslcontext.options |= ssl.OP_NO_SSLv2 | ||
sslcontext.options |= ssl.OP_NO_SSLv3 | ||
sslcontext.options |= getattr(ssl, "OP_NO_COMPRESSION", 0) | ||
sslcontext.set_default_verify_paths() | ||
sslcontext.verify_mode = ssl.CERT_REQUIRED | ||
self._ssl_context = sslcontext | ||
return self._ssl_context | ||
|
||
@property | ||
def family(self): | ||
"""Socket family like AF_INET.""" | ||
|
@@ -288,11 +322,10 @@ def _create_connection(self, req, **kwargs): | |
|
||
Has same keyword arguments as BaseEventLoop.create_connection. | ||
""" | ||
sslcontext = req.ssl | ||
if req.ssl and not self._verify_ssl: | ||
sslcontext = ssl.SSLContext(ssl.PROTOCOL_SSLv23) | ||
sslcontext.options |= ssl.OP_NO_SSLv2 | ||
sslcontext.set_default_verify_paths() | ||
if req.ssl: | ||
sslcontext = self.ssl_context | ||
else: | ||
sslcontext = None | ||
|
||
hosts = yield from self._resolve_host(req.host, req.port) | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why only SSLv2?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's behavior of current aiohttp.TCPConnector, I didn't modified this code :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, miss it below. May be worth to touch it then since it cause the way to allow SSLv3 while others forbids that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree, SSLv3 has vulnerability issues IIRC.