Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fixing SSL certificate error in exe compiled with py2exe (or PyInstaller)

I've just finished testing a Python programme which involves logging into a site and requires a CSRF cookie to be set. I've tried packaging it as an exe using py2exe and got a socket error. I have the same problem when I try with PyInstaller. Googling the Errno I found a few other people with the same problem and so I know the problem is to do with the location of SLL certificates.

This is my site_agent class including the logging calls.

    class site_agent:
        self.get_params()
        URL = root_url + '/accounts/login/'        
        # Retrieve the CSRF token first
        self.agent = requests.session()
        self.agent.get(URL)  # retrieves the cookie # This line throws the error
        self.csrftoken = self.agent.cookies['csrftoken']    
        # Set up login data including the CSRF cookie
        login_data = {'username': self.username,
                      'password': self.password,
                      'csrfmiddlewaretoken' : self.csrftoken}
        # Log in
        logging.info('Logging in')
        response = self.agent.post(URL, data=login_data, headers=hdr)

The error comes at the self.agent.get(URL) line and the Traceback shows:

Traceback (most recent call last):
  File "<string>", line 223, in <module>
  File "<string>", line 198, in main
  File "<string>", line 49, in __init__
  File "C:\pyinstaller-2.0\pyinstaller-2.0\autoresponder\b
uild\pyi.win32\autoresponder\out00-PYZ.pyz\requests.sessions", line 350, in get
  File "C:\pyinstaller-2.0\pyinstaller-2.0\autoresponder\b
uild\pyi.win32\autoresponder\out00-PYZ.pyz\requests.sessions", line 338, in requ
est
  File "C:\pyinstaller-2.0\pyinstaller-2.0\autoresponder\b
uild\pyi.win32\autoresponder\out00-PYZ.pyz\requests.sessions", line 441, in send

  File "C:\pyinstaller-2.0\pyinstaller-2.0\autoresponder\b
uild\pyi.win32\autoresponder\out00-PYZ.pyz\requests.adapters", line 331, in send

requests.exceptions.SSLError: [Errno 185090050] _ssl.c:336: error:0B084002:x509
certificate routines:X509_load_cert_crl_file:system lib

Does this mean that the problem is in requests.adapters?

If so, can I just edit it in my installed Python packages to look for cacert.pem somewhere else, rebuild my exe with py2exe or PyInstaller, then change it back in my installed version of Python?

EDIT

I now have the programme running after compiling with PyInstaller and setting verify=False in all requests.get() and requests.post() calls. But SSL is there for a a reason and I'd really like to be able to fix this error before letting anyone use the tool.

like image 943
Jamie Bull Avatar asked Jun 17 '13 23:06

Jamie Bull


2 Answers

This can be solved easily if you are using "requests" module.

1) Place the below code in your main python file where "requests" module is used

os.environ['REQUESTS_CA_BUNDLE'] = "certifi/cacert.pem"

2) Within your distributable folder where exe is present, create a folder called "certifi" and place the "cacert.pem" file within it.

3) You can find the "cacert.pem" file by

pip install certifi

import certifi
certifi.where()

Awesome.. now your distributable includes the necessary certificates to validate ssl calls.

like image 199
HVS Avatar answered Oct 13 '22 21:10

HVS


If using pyinstaller... create a hook-requests.py file in PyInstaller\hooks\ for the requests lib containing

from hookutils import collect_data_files

# Get the cacert.pem
datas = collect_data_files('requests') 
like image 38
frmdstryr Avatar answered Oct 13 '22 20:10

frmdstryr