1 |
|
import cStringIO
|
2 |
|
import urllib2
|
3 |
1 |
|
4 |
|
pycurl = None
|
5 |
|
try:
|
6 |
|
import pycurl
|
7 |
|
except ImportError:
|
8 |
|
pass
|
9 |
|
M2Crypto = None
|
10 |
|
try:
|
11 |
|
import M2Crypto
|
12 |
|
except ImportError:
|
13 |
|
pass
|
|
2 |
import requests
|
14 |
3 |
|
15 |
4 |
from authentic2 import app_settings
|
16 |
5 |
|
17 |
|
def get_url_pycurl(url):
|
18 |
|
'''Use pycurl to retrieve an HTTPS URL, preferred to M2Crypto as it also
|
19 |
|
handles Server Name Indication (SNI).
|
20 |
|
'''
|
21 |
|
try:
|
22 |
|
buf = cStringIO.StringIO()
|
23 |
|
c = pycurl.Curl()
|
24 |
|
c.setopt(c.URL, str(url))
|
25 |
|
c.setopt(c.WRITEFUNCTION, buf.write)
|
26 |
|
c.setopt(pycurl.CAINFO, app_settings.CAFILE)
|
27 |
|
c.setopt(pycurl.CAPATH, app_settings.CAPATH)
|
28 |
|
if app_settings.A2_VERIFY_SSL:
|
29 |
|
c.setopt(pycurl.SSL_VERIFYHOST, 2)
|
30 |
|
c.setopt(pycurl.SSL_VERIFYPEER, 1)
|
31 |
|
else:
|
32 |
|
c.setopt(pycurl.SSL_VERIFYHOST, 0)
|
33 |
|
c.setopt(pycurl.SSL_VERIFYPEER, 0)
|
34 |
|
c.perform()
|
35 |
|
r = buf.getvalue()
|
36 |
|
buf.close()
|
37 |
|
http_code = c.getinfo(pycurl.HTTP_CODE)
|
38 |
|
if http_code != 200:
|
39 |
|
raise urllib2.HTTPError(url, http_code, None, None, None)
|
40 |
|
return r
|
41 |
|
except pycurl.error, e:
|
42 |
|
# Wrap error
|
43 |
|
raise urllib2.URLError('SSL access error %s' % e)
|
44 |
|
|
45 |
|
__M2CRYPTO_SSL_CONTEXT = None
|
46 |
|
|
47 |
|
def get_m2crypto_ssl_context():
|
48 |
|
'''Create an SSL Context and cache it in global __M2CRYPTO_SSL_CONTEXT'''
|
49 |
|
global __M2CRYPTO_SSL_CONTEXT
|
50 |
|
|
51 |
|
if __M2CRYPTO_SSL_CONTEXT is None:
|
52 |
|
__M2CRYPTO_SSL_CONTEXT = M2Crypto.SSL.Context()
|
53 |
|
__M2CRYPTO_SSL_CONTEXT.load_verify_locations(cafile=app_settings.CAFILE,
|
54 |
|
capath=app_settings.CAPATH)
|
55 |
|
return __M2CRYPTO_SSL_CONTEXT
|
56 |
|
|
57 |
|
def get_url_m2crypto(url):
|
58 |
|
'''Use M2Crypto to retrieve an HTTPs URL'''
|
59 |
|
try:
|
60 |
|
return M2Crypto.m2urllib2.build_opener(get_m2crypto_ssl_context()).open(url).read()
|
61 |
|
except M2Crypto.SSL.Checker.SSLVerificationError, e:
|
62 |
|
# Wrap error
|
63 |
|
raise urllib2.URLError('SSL Verification error %s' % e)
|
64 |
|
|
65 |
6 |
def get_url(url):
|
66 |
|
'''Does a simple GET on an URL, if the URL uses TLS, M2Crypto is used to
|
67 |
|
check the certificate'''
|
68 |
|
|
69 |
|
if url.startswith('https'):
|
70 |
|
if pycurl:
|
71 |
|
return get_url_pycurl(url)
|
72 |
|
if M2Crypto:
|
73 |
|
return get_url_m2crypto(url)
|
74 |
|
raise urllib2.URLError('https is unsupported without either pyCurl or M2Crypto')
|
75 |
|
return urllib2.urlopen(url).read()
|
|
7 |
'''Does a simple GET on an URL, check the certificate'''
|
|
8 |
verify = app_settings.A2_VERIFY_SSL
|
|
9 |
if verify and app_settings.CAFILE:
|
|
10 |
verify = app_settings.CAFILE
|
|
11 |
return requests.get(url, verify=verify).text
|
76 |
|
-
|