Skip to content
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

Macos certif #447

Merged
merged 17 commits into from
Oct 10, 2020
Merged

Macos certif #447

merged 17 commits into from
Oct 10, 2020

Conversation

Czaki
Copy link
Contributor

@Czaki Czaki commented Oct 8, 2020

This PR is for fix #443
Because try of using /Applications/Python 2.7/Install Certificates.command fail I decide to vendor in script base on one present on my machine.

I'm not sure what to do with python 3.5 so I skip this step on this version. @mayeut any suggestion?

The test for this case could be hard. We could download something from github.com, but any break in this functionality may produce error long time after change happen.

@henryiii
Copy link
Contributor

henryiii commented Oct 8, 2020

Another solution I've seen mentioned that might include Python 3.5 is:

pip install certifi
CERT_PATH=$(python -m certifi)
export SSL_CERT_FILE=${CERT_PATH}
export REQUESTS_CA_BUNDLE=${CERT_PATH}

But I think the problem is that Python 3.6+ have their own copy of OpenSSL, while 3.5 does not and uses the system copy, so does this even show up at all for 3.5?

@joerick
Copy link
Contributor

joerick commented Oct 9, 2020

Thanks for looking at this @Czaki. But due to the existing test_ssl I'm still unsure exactly what we're fixing here. As I noted in #443, I'd like to see a failing test that recreates the SSL error before we attempt any fixes using Install Certificates.command or similar.

cibuildwheel/macos.py Outdated Show resolved Hide resolved
@mayeut
Copy link
Member

mayeut commented Oct 9, 2020

But I think the problem is that Python 3.6+ have their own copy of OpenSSL, while 3.5 does not and uses the system copy, so does this even show up at all for 3.5?

The system copy was so old on python 3.5 that it did not support TLS 1.2 which caused some issue. Its openssl version has been patched in #71 not to use the system one.

I'm not sure what to do with python 3.5 so I skip this step on this version. @mayeut any suggestion?

It shall be patched like the other versions.

@djhoese
Copy link

djhoese commented Oct 9, 2020

I just tried forcing the TLS protocol version in my branch for vispy and it worked! I made sure not to use the dev version of cibuildwheel and I don't think I was skipping the test or anything. I think this is the main cause. Can someone summarize all of the issues related to why cibuildwheel started doing that and why it works?

@mayeut
Copy link
Member

mayeut commented Oct 9, 2020

@Czaki
Copy link
Contributor Author

Czaki commented Oct 9, 2020

my test run does not finish yet, but basic on @mayeut I expand the test set.

But I think that we should test more ssl context cases.

EDIT also got error

https://dev.azure.com/PartSeg/Open%20Source%20contrib/_build/results?buildId=1764&view=results

@Czaki
Copy link
Contributor Author

Czaki commented Oct 9, 2020

@mayeut I got this for python 3.5

FileNotFoundError: [Errno 2] No such file or directory: '/Library/Frameworks/Python.framework/Versions/3.5/etc/openssl'

Did you have any idea? Or omit python 3.5 as there is plan to drop its support?

@mayeut
Copy link
Member

mayeut commented Oct 9, 2020

@mayeut I got this for python 3.5
FileNotFoundError: [Errno 2] No such file or directory: '/Library/Frameworks/Python.framework/Versions/3.5/etc/openssl'
Did you have any idea? Or omit python 3.5 as there is plan to drop its support?

That's because the folder /Library/Frameworks/Python.framework/Versions/3.5/etc/openssl does not exist yet. It should be created before symlink is created (it does not exist because neither the official installer nor the patch create this folder)

@Czaki
Copy link
Contributor Author

Czaki commented Oct 10, 2020

@mayeut When omit test_ssl for python 3.5 then everything pass. But for python 3.5 its fail. Could You review my changes? Have You any idea why python 3.5 does not use certificates from certifi?

@mayeut
Copy link
Member

mayeut commented Oct 10, 2020

@mayeut When omit test_ssl for python 3.5 then everything pass. But for python 3.5 its fail. Could You review my changes? Have You any idea why python 3.5 does not use certificates from certifi?

I just tested "manually" the patch on my machine (i.e., just following the logic):
before:

Matt$ /Library/Frameworks/Python.framework/Versions/3.5/bin/python3
Python 3.5.4 (v3.5.4:3f56838976, Aug  7 2017, 12:56:33) 
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import ssl
>>> ssl.OPENSSL_VERSION
'OpenSSL 1.0.2u  20 Dec 2019'
>>> ssl.get_default_verify_paths()
DefaultVerifyPaths(cafile=None, capath=None, openssl_cafile_env='SSL_CERT_FILE', openssl_cafile='/Library/Frameworks/Python.framework/Versions/3.5/etc/openssl/cert.pem', openssl_capath_env='SSL_CERT_DIR', openssl_capath='/Library/Frameworks/Python.framework/Versions/3.5/etc/openssl/certs')
>>> from urllib.request import urlopen
>>> data = urlopen("https://raw.githubusercontent.com/joerick/cibuildwheel/master/README.md")
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/urllib/request.py", line 1254, in do_open
    h.request(req.get_method(), req.selector, req.data, headers)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/http/client.py", line 1107, in request
    self._send_request(method, url, body, headers)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/http/client.py", line 1152, in _send_request
    self.endheaders(body)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/http/client.py", line 1103, in endheaders
    self._send_output(message_body)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/http/client.py", line 934, in _send_output
    self.send(msg)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/http/client.py", line 877, in send
    self.connect()
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/http/client.py", line 1261, in connect
    server_hostname=server_hostname)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/ssl.py", line 385, in wrap_socket
    _context=self)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/ssl.py", line 760, in __init__
    self.do_handshake()
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/ssl.py", line 996, in do_handshake
    self._sslobj.do_handshake()
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/ssl.py", line 641, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:719)

patch logic:

Matt$ mkdir -p /Library/Frameworks/Python.framework/Versions/3.5/etc/openssl/
Matt$ cp /Library/Frameworks/Python.framework/Versions/3.6/etc/openssl/cert.pem /Library/Frameworks/Python.framework/Versions/3.5/etc/openssl/

after:

Matt$ /Library/Frameworks/Python.framework/Versions/3.5/bin/python3
Python 3.5.4 (v3.5.4:3f56838976, Aug  7 2017, 12:56:33) 
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import ssl
>>> ssl.get_default_verify_paths()
DefaultVerifyPaths(cafile='/Library/Frameworks/Python.framework/Versions/3.5/etc/openssl/cert.pem', capath=None, openssl_cafile_env='SSL_CERT_FILE', openssl_cafile='/Library/Frameworks/Python.framework/Versions/3.5/etc/openssl/cert.pem', openssl_capath_env='SSL_CERT_DIR', openssl_capath='/Library/Frameworks/Python.framework/Versions/3.5/etc/openssl/certs')
>>> from urllib.request import urlopen
>>> data = urlopen("https://raw.githubusercontent.com/joerick/cibuildwheel/master/README.md")
>>> data.read()
b'cibuildwheel\n============\n\n[![PyPI](https://img.shie................

So it should be working. Now investigating why it's failing in CI.

@mayeut
Copy link
Member

mayeut commented Oct 10, 2020

With an updated test case to print ssl.get_default_verify_paths(), I'm still getting the following

DefaultVerifyPaths(cafile=None, capath=None, openssl_cafile_env='SSL_CERT_FILE', openssl_cafile='/Library/Frameworks/Python.framework/Versions/3.5/etc/openssl/cert.pem', openssl_capath_env='SSL_CERT_DIR', openssl_capath='/Library/Frameworks/Python.framework/Versions/3.5/etc/openssl/certs')

cafile should not be None here.

Copy link
Member

@mayeut mayeut left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With mode changed with octal 0o775, tests are passing as expected. c.f. https://github.com/mayeut/cibuildwheel/runs/1235348121?check_suite_focus=true

Co-authored-by: Matthieu Darbois <mayeut@users.noreply.github.com>
@YannickJadoul
Copy link
Member

With mode changed with octal 0o775, tests are passing as expected.

Great! Thanks you so much for checking and finding that, @mayeut! :-)

@Czaki, I've taken the liberty to apply @mayeut's suggestion, and (hopefully) get a green build.

Copy link
Member

@YannickJadoul YannickJadoul left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't really followed the whole discussion or problem, so these are mostly minor style-related comments.

Apart from those, it seems like @djhoese, @Czaki, and @mayeut together figured out what went wrong and how to best fix this, so not a lot of comments there.

cibuildwheel/resources/install_certifi.py Show resolved Hide resolved
import stat
import subprocess
import sys
STAT_0o775 = ( stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New line, before?

cibuildwheel/resources/install_certifi.py Show resolved Hide resolved
cibuildwheel/resources/install_certifi.py Show resolved Hide resolved
cibuildwheel/resources/install_certifi.py Show resolved Hide resolved
test/test_1_ssl.py Outdated Show resolved Hide resolved
data = urlopen("https://www.nist.gov", context=context)
context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
data = urlopen("https://www.nist.gov", context=context)
data = urlopen("https://raw.githubusercontent.com/joerick/cibuildwheel/master/CI.md", context=context)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to assert something for the received data? E.g. just that it's not empty, or so?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe we should, but then we should have some file with some fixed content.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not per se. You could just test if something non-empty was downloaded? Or take away the data =, maybe? It just feels weird, all these useless assignments.

cibuildwheel/macos.py Show resolved Hide resolved
mayeut
mayeut previously approved these changes Oct 10, 2020
@mayeut mayeut dismissed their stale review October 10, 2020 14:42

change for python 3.5 now ok, letting @YannickJadoul follow-up with his review

@Czaki
Copy link
Contributor Author

Czaki commented Oct 10, 2020

Before merge I have one question.
If we should test multiple SSL version ssl.PROTOCOL_* or only this two tests which we already have.

@mayeut
Copy link
Member

mayeut commented Oct 10, 2020

The test with ssl.PROTOCOL_TLSv1_2 was only there to check support was indeed there for this protocol a couple years back. I don't think we should have any specific tests other than that until web servers start to heavily shift to newer protocols and disable TLS v1.2 (that was the case for PyPI where the minimum supported protocol shifted to TLS v1.2, hence this test).

c.f. https://www.ssllabs.com/ssl-pulse/ for an idea of currently deployed protocols.

Copy link
Member

@YannickJadoul YannickJadoul left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, @Czaki! Looks good to me, now!

@mayeut mayeut merged commit 8094b3f into pypa:master Oct 10, 2020
@mayeut
Copy link
Member

mayeut commented Oct 10, 2020

Thanks @Czaki !

@Czaki
Copy link
Contributor Author

Czaki commented Oct 10, 2020

@joerick 1.6.3?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

SSL issues with OSX on Azure
6 participants