rigid 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (229) hide show
  1. checksums.yaml +4 -4
  2. data/vendor/click/__init__.pyc +0 -0
  3. data/vendor/click/_bashcomplete.pyc +0 -0
  4. data/vendor/click/_compat.pyc +0 -0
  5. data/vendor/click/_termui_impl.pyc +0 -0
  6. data/vendor/click/_textwrap.pyc +0 -0
  7. data/vendor/click/_unicodefun.pyc +0 -0
  8. data/vendor/click/_winconsole.pyc +0 -0
  9. data/vendor/click/core.pyc +0 -0
  10. data/vendor/click/decorators.pyc +0 -0
  11. data/vendor/click/exceptions.pyc +0 -0
  12. data/vendor/click/formatting.pyc +0 -0
  13. data/vendor/click/globals.pyc +0 -0
  14. data/vendor/click/parser.pyc +0 -0
  15. data/vendor/click/termui.pyc +0 -0
  16. data/vendor/click/testing.pyc +0 -0
  17. data/vendor/click/types.pyc +0 -0
  18. data/vendor/click/utils.pyc +0 -0
  19. data/vendor/easy_install.pyc +0 -0
  20. data/vendor/pkg_resources/__init__.pyc +0 -0
  21. data/vendor/pkg_resources/_vendor/__init__.pyc +0 -0
  22. data/vendor/pkg_resources/_vendor/appdirs.pyc +0 -0
  23. data/vendor/pkg_resources/_vendor/packaging/__about__.pyc +0 -0
  24. data/vendor/pkg_resources/_vendor/packaging/__init__.pyc +0 -0
  25. data/vendor/pkg_resources/_vendor/packaging/_compat.pyc +0 -0
  26. data/vendor/pkg_resources/_vendor/packaging/_structures.pyc +0 -0
  27. data/vendor/pkg_resources/_vendor/packaging/markers.pyc +0 -0
  28. data/vendor/pkg_resources/_vendor/packaging/requirements.pyc +0 -0
  29. data/vendor/pkg_resources/_vendor/packaging/specifiers.pyc +0 -0
  30. data/vendor/pkg_resources/_vendor/packaging/utils.pyc +0 -0
  31. data/vendor/pkg_resources/_vendor/packaging/version.pyc +0 -0
  32. data/vendor/pkg_resources/_vendor/pyparsing.pyc +0 -0
  33. data/vendor/pkg_resources/_vendor/six.pyc +0 -0
  34. data/vendor/pkg_resources/extern/__init__.pyc +0 -0
  35. data/vendor/{requests-2.11.1.dist-info/METADATA → requests-2.12.1.dist-info/DESCRIPTION.rst} +51 -30
  36. data/vendor/{requests-2.11.1.dist-info → requests-2.12.1.dist-info}/INSTALLER +0 -0
  37. data/vendor/{requests-2.11.1.dist-info/DESCRIPTION.rst → requests-2.12.1.dist-info/METADATA} +80 -1
  38. data/vendor/{requests-2.11.1.dist-info → requests-2.12.1.dist-info}/RECORD +61 -41
  39. data/vendor/{requests-2.11.1.dist-info → requests-2.12.1.dist-info}/WHEEL +1 -1
  40. data/vendor/requests-2.12.1.dist-info/metadata.json +1 -0
  41. data/vendor/{requests-2.11.1.dist-info → requests-2.12.1.dist-info}/top_level.txt +0 -0
  42. data/vendor/requests/__init__.py +2 -2
  43. data/vendor/requests/__init__.pyc +0 -0
  44. data/vendor/requests/_internal_utils.py +27 -0
  45. data/vendor/requests/_internal_utils.pyc +0 -0
  46. data/vendor/requests/adapters.py +1 -1
  47. data/vendor/requests/adapters.pyc +0 -0
  48. data/vendor/requests/api.py +3 -1
  49. data/vendor/requests/api.pyc +0 -0
  50. data/vendor/requests/auth.py +2 -1
  51. data/vendor/requests/auth.pyc +0 -0
  52. data/vendor/requests/cacert.pem +448 -375
  53. data/vendor/requests/certs.pyc +0 -0
  54. data/vendor/requests/compat.py +2 -0
  55. data/vendor/requests/compat.pyc +0 -0
  56. data/vendor/requests/cookies.py +3 -1
  57. data/vendor/requests/cookies.pyc +0 -0
  58. data/vendor/requests/exceptions.py +2 -0
  59. data/vendor/requests/exceptions.pyc +0 -0
  60. data/vendor/requests/hooks.pyc +0 -0
  61. data/vendor/requests/models.py +53 -29
  62. data/vendor/requests/models.pyc +0 -0
  63. data/vendor/requests/packages/__init__.py +6 -0
  64. data/vendor/requests/packages/__init__.pyc +0 -0
  65. data/vendor/requests/packages/chardet/__init__.pyc +0 -0
  66. data/vendor/requests/packages/chardet/big5freq.pyc +0 -0
  67. data/vendor/requests/packages/chardet/big5prober.pyc +0 -0
  68. data/vendor/requests/packages/chardet/chardetect.pyc +0 -0
  69. data/vendor/requests/packages/chardet/chardistribution.pyc +0 -0
  70. data/vendor/requests/packages/chardet/charsetgroupprober.pyc +0 -0
  71. data/vendor/requests/packages/chardet/charsetprober.pyc +0 -0
  72. data/vendor/requests/packages/chardet/codingstatemachine.pyc +0 -0
  73. data/vendor/requests/packages/chardet/compat.pyc +0 -0
  74. data/vendor/requests/packages/chardet/constants.pyc +0 -0
  75. data/vendor/requests/packages/chardet/cp949prober.pyc +0 -0
  76. data/vendor/requests/packages/chardet/escprober.pyc +0 -0
  77. data/vendor/requests/packages/chardet/escsm.pyc +0 -0
  78. data/vendor/requests/packages/chardet/eucjpprober.pyc +0 -0
  79. data/vendor/requests/packages/chardet/euckrfreq.pyc +0 -0
  80. data/vendor/requests/packages/chardet/euckrprober.pyc +0 -0
  81. data/vendor/requests/packages/chardet/euctwfreq.pyc +0 -0
  82. data/vendor/requests/packages/chardet/euctwprober.pyc +0 -0
  83. data/vendor/requests/packages/chardet/gb2312freq.pyc +0 -0
  84. data/vendor/requests/packages/chardet/gb2312prober.pyc +0 -0
  85. data/vendor/requests/packages/chardet/hebrewprober.pyc +0 -0
  86. data/vendor/requests/packages/chardet/jisfreq.pyc +0 -0
  87. data/vendor/requests/packages/chardet/jpcntx.pyc +0 -0
  88. data/vendor/requests/packages/chardet/langbulgarianmodel.pyc +0 -0
  89. data/vendor/requests/packages/chardet/langcyrillicmodel.pyc +0 -0
  90. data/vendor/requests/packages/chardet/langgreekmodel.pyc +0 -0
  91. data/vendor/requests/packages/chardet/langhebrewmodel.pyc +0 -0
  92. data/vendor/requests/packages/chardet/langhungarianmodel.pyc +0 -0
  93. data/vendor/requests/packages/chardet/langthaimodel.pyc +0 -0
  94. data/vendor/requests/packages/chardet/latin1prober.pyc +0 -0
  95. data/vendor/requests/packages/chardet/mbcharsetprober.pyc +0 -0
  96. data/vendor/requests/packages/chardet/mbcsgroupprober.pyc +0 -0
  97. data/vendor/requests/packages/chardet/mbcssm.pyc +0 -0
  98. data/vendor/requests/packages/chardet/sbcharsetprober.pyc +0 -0
  99. data/vendor/requests/packages/chardet/sbcsgroupprober.pyc +0 -0
  100. data/vendor/requests/packages/chardet/sjisprober.pyc +0 -0
  101. data/vendor/requests/packages/chardet/universaldetector.pyc +0 -0
  102. data/vendor/requests/packages/chardet/utf8prober.pyc +0 -0
  103. data/vendor/requests/packages/idna/__init__.py +1 -0
  104. data/vendor/requests/packages/idna/__init__.pyc +0 -0
  105. data/vendor/requests/packages/idna/codec.py +118 -0
  106. data/vendor/requests/packages/idna/codec.pyc +0 -0
  107. data/vendor/requests/packages/idna/compat.py +12 -0
  108. data/vendor/requests/packages/idna/compat.pyc +0 -0
  109. data/vendor/requests/packages/idna/core.py +387 -0
  110. data/vendor/requests/packages/idna/core.pyc +0 -0
  111. data/vendor/requests/packages/idna/idnadata.py +1584 -0
  112. data/vendor/requests/packages/idna/idnadata.pyc +0 -0
  113. data/vendor/requests/packages/idna/intranges.py +46 -0
  114. data/vendor/requests/packages/idna/intranges.pyc +0 -0
  115. data/vendor/requests/packages/idna/uts46data.py +7267 -0
  116. data/vendor/requests/packages/idna/uts46data.pyc +0 -0
  117. data/vendor/requests/packages/urllib3/__init__.py +2 -1
  118. data/vendor/requests/packages/urllib3/__init__.pyc +0 -0
  119. data/vendor/requests/packages/urllib3/_collections.pyc +0 -0
  120. data/vendor/requests/packages/urllib3/connection.py +62 -26
  121. data/vendor/requests/packages/urllib3/connection.pyc +0 -0
  122. data/vendor/requests/packages/urllib3/connectionpool.py +25 -20
  123. data/vendor/requests/packages/urllib3/connectionpool.pyc +0 -0
  124. data/vendor/requests/packages/urllib3/contrib/__init__.pyc +0 -0
  125. data/vendor/requests/packages/urllib3/contrib/appengine.py +87 -22
  126. data/vendor/requests/packages/urllib3/contrib/appengine.pyc +0 -0
  127. data/vendor/requests/packages/urllib3/contrib/ntlmpool.py +2 -5
  128. data/vendor/requests/packages/urllib3/contrib/ntlmpool.pyc +0 -0
  129. data/vendor/requests/packages/urllib3/contrib/pyopenssl.py +191 -118
  130. data/vendor/requests/packages/urllib3/contrib/pyopenssl.pyc +0 -0
  131. data/vendor/requests/packages/urllib3/contrib/socks.py +11 -5
  132. data/vendor/requests/packages/urllib3/contrib/socks.pyc +0 -0
  133. data/vendor/requests/packages/urllib3/exceptions.py +32 -0
  134. data/vendor/requests/packages/urllib3/exceptions.pyc +0 -0
  135. data/vendor/requests/packages/urllib3/fields.py +1 -1
  136. data/vendor/requests/packages/urllib3/fields.pyc +0 -0
  137. data/vendor/requests/packages/urllib3/filepost.py +1 -1
  138. data/vendor/requests/packages/urllib3/filepost.pyc +0 -0
  139. data/vendor/requests/packages/urllib3/packages/__init__.pyc +0 -0
  140. data/vendor/requests/packages/urllib3/packages/backports/__init__.py +0 -0
  141. data/vendor/requests/packages/urllib3/packages/backports/__init__.pyc +0 -0
  142. data/vendor/requests/packages/urllib3/packages/backports/makefile.py +53 -0
  143. data/vendor/requests/packages/urllib3/packages/backports/makefile.pyc +0 -0
  144. data/vendor/requests/packages/urllib3/packages/ordered_dict.pyc +0 -0
  145. data/vendor/requests/packages/urllib3/packages/six.pyc +0 -0
  146. data/vendor/requests/packages/urllib3/packages/ssl_match_hostname/__init__.py +7 -1
  147. data/vendor/requests/packages/urllib3/packages/ssl_match_hostname/__init__.pyc +0 -0
  148. data/vendor/requests/packages/urllib3/packages/ssl_match_hostname/_implementation.py +55 -3
  149. data/vendor/requests/packages/urllib3/packages/ssl_match_hostname/_implementation.pyc +0 -0
  150. data/vendor/requests/packages/urllib3/poolmanager.py +2 -6
  151. data/vendor/requests/packages/urllib3/poolmanager.pyc +0 -0
  152. data/vendor/requests/packages/urllib3/request.py +1 -4
  153. data/vendor/requests/packages/urllib3/request.pyc +0 -0
  154. data/vendor/requests/packages/urllib3/response.py +94 -6
  155. data/vendor/requests/packages/urllib3/response.pyc +0 -0
  156. data/vendor/requests/packages/urllib3/util/__init__.pyc +0 -0
  157. data/vendor/requests/packages/urllib3/util/connection.py +1 -0
  158. data/vendor/requests/packages/urllib3/util/connection.pyc +0 -0
  159. data/vendor/requests/packages/urllib3/util/request.pyc +0 -0
  160. data/vendor/requests/packages/urllib3/util/response.py +7 -0
  161. data/vendor/requests/packages/urllib3/util/response.pyc +0 -0
  162. data/vendor/requests/packages/urllib3/util/retry.py +93 -17
  163. data/vendor/requests/packages/urllib3/util/retry.pyc +0 -0
  164. data/vendor/requests/packages/urllib3/util/ssl_.py +28 -12
  165. data/vendor/requests/packages/urllib3/util/ssl_.pyc +0 -0
  166. data/vendor/requests/packages/urllib3/util/timeout.py +9 -6
  167. data/vendor/requests/packages/urllib3/util/timeout.pyc +0 -0
  168. data/vendor/requests/packages/urllib3/util/url.py +14 -5
  169. data/vendor/requests/packages/urllib3/util/url.pyc +0 -0
  170. data/vendor/requests/sessions.py +18 -5
  171. data/vendor/requests/sessions.pyc +0 -0
  172. data/vendor/requests/status_codes.pyc +0 -0
  173. data/vendor/requests/structures.pyc +0 -0
  174. data/vendor/requests/utils.py +42 -32
  175. data/vendor/requests/utils.pyc +0 -0
  176. data/vendor/{rigid-0.2.0.dist-info → rigid-0.2.1.dist-info}/DESCRIPTION.rst +0 -0
  177. data/vendor/{rigid-0.2.0.dist-info → rigid-0.2.1.dist-info}/INSTALLER +0 -0
  178. data/vendor/{rigid-0.2.0.dist-info → rigid-0.2.1.dist-info}/METADATA +2 -2
  179. data/vendor/{rigid-0.2.0.dist-info → rigid-0.2.1.dist-info}/RECORD +18 -18
  180. data/vendor/{rigid-0.2.0.dist-info → rigid-0.2.1.dist-info}/WHEEL +0 -0
  181. data/vendor/{rigid-0.2.0.dist-info → rigid-0.2.1.dist-info}/entry_points.txt +0 -0
  182. data/vendor/{rigid-0.2.0.dist-info → rigid-0.2.1.dist-info}/metadata.json +1 -1
  183. data/vendor/{rigid-0.2.0.dist-info → rigid-0.2.1.dist-info}/top_level.txt +0 -0
  184. data/vendor/rigid/__init__.pyc +0 -0
  185. data/vendor/rigid/api.py +39 -2
  186. data/vendor/rigid/api.pyc +0 -0
  187. data/vendor/rigid/commands/__init__.py +71 -11
  188. data/vendor/rigid/commands/__init__.pyc +0 -0
  189. data/vendor/rigid/commands/deploy.pyc +0 -0
  190. data/vendor/rigid/deploy.py +1 -1
  191. data/vendor/rigid/deploy.pyc +0 -0
  192. data/vendor/rigid/file_scanner.py +1 -1
  193. data/vendor/rigid/file_scanner.pyc +0 -0
  194. data/vendor/rigid/utils.pyc +0 -0
  195. data/vendor/tests/__init__.pyc +0 -0
  196. data/vendor/tests/integration/__init__.pyc +0 -0
  197. data/vendor/tests/integration/test_app.py +12 -0
  198. data/vendor/tests/integration/test_app.pyc +0 -0
  199. data/vendor/tests/integration/test_apps.pyc +0 -0
  200. data/vendor/tests/integration/test_deploy.pyc +0 -0
  201. data/vendor/tests/integration/test_domains.pyc +0 -0
  202. data/vendor/tests/integration/test_login.pyc +0 -0
  203. data/vendor/tests/integration/test_promote.py +2 -2
  204. data/vendor/tests/integration/test_promote.pyc +0 -0
  205. data/vendor/tests/integration/test_token.pyc +0 -0
  206. data/vendor/tests/integration/test_whoami.pyc +0 -0
  207. data/vendor/tests/test_deploy.pyc +0 -0
  208. data/vendor/tests/test_file_scanner.pyc +0 -0
  209. data/vendor/tests/utils.py +5 -2
  210. data/vendor/tests/utils.pyc +0 -0
  211. data/vendor/yaml/__init__.pyc +0 -0
  212. data/vendor/yaml/composer.pyc +0 -0
  213. data/vendor/yaml/constructor.pyc +0 -0
  214. data/vendor/yaml/cyaml.pyc +0 -0
  215. data/vendor/yaml/dumper.pyc +0 -0
  216. data/vendor/yaml/emitter.pyc +0 -0
  217. data/vendor/yaml/error.pyc +0 -0
  218. data/vendor/yaml/events.pyc +0 -0
  219. data/vendor/yaml/loader.pyc +0 -0
  220. data/vendor/yaml/nodes.pyc +0 -0
  221. data/vendor/yaml/parser.pyc +0 -0
  222. data/vendor/yaml/reader.pyc +0 -0
  223. data/vendor/yaml/representer.pyc +0 -0
  224. data/vendor/yaml/resolver.pyc +0 -0
  225. data/vendor/yaml/scanner.pyc +0 -0
  226. data/vendor/yaml/serializer.pyc +0 -0
  227. data/vendor/yaml/tokens.pyc +0 -0
  228. metadata +37 -17
  229. data/vendor/requests-2.11.1.dist-info/metadata.json +0 -1
@@ -5,14 +5,11 @@ Issue #10, see: http://code.google.com/p/urllib3/issues/detail?id=10
5
5
  """
6
6
  from __future__ import absolute_import
7
7
 
8
- try:
9
- from http.client import HTTPSConnection
10
- except ImportError:
11
- from httplib import HTTPSConnection
12
8
  from logging import getLogger
13
9
  from ntlm import ntlm
14
10
 
15
- from urllib3 import HTTPSConnectionPool
11
+ from .. import HTTPSConnectionPool
12
+ from ..packages.six.moves.http_client import HTTPSConnection
16
13
 
17
14
 
18
15
  log = getLogger(__name__)
@@ -1,17 +1,21 @@
1
- '''SSL with SNI_-support for Python 2. Follow these instructions if you would
1
+ """
2
+ SSL with SNI_-support for Python 2. Follow these instructions if you would
2
3
  like to verify SSL certificates in Python 2. Note, the default libraries do
3
4
  *not* do certificate checking; you need to do additional work to validate
4
5
  certificates yourself.
5
6
 
6
7
  This needs the following packages installed:
7
8
 
8
- * pyOpenSSL (tested with 0.13)
9
- * ndg-httpsclient (tested with 0.3.2)
10
- * pyasn1 (tested with 0.1.6)
9
+ * pyOpenSSL (tested with 16.0.0)
10
+ * cryptography (minimum 1.3.4, from pyopenssl)
11
+ * idna (minimum 2.0, from cryptography)
12
+
13
+ However, pyopenssl depends on cryptography, which depends on idna, so while we
14
+ use all three directly here we end up having relatively few packages required.
11
15
 
12
16
  You can install them with the following command:
13
17
 
14
- pip install pyopenssl ndg-httpsclient pyasn1
18
+ pip install pyopenssl cryptography idna
15
19
 
16
20
  To activate certificate checking, call
17
21
  :func:`~urllib3.contrib.pyopenssl.inject_into_urllib3` from your Python code
@@ -34,45 +38,38 @@ compression in Python 2 (see `CRIME attack`_).
34
38
  If you want to configure the default list of supported cipher suites, you can
35
39
  set the ``urllib3.contrib.pyopenssl.DEFAULT_SSL_CIPHER_LIST`` variable.
36
40
 
37
- Module Variables
38
- ----------------
39
-
40
- :var DEFAULT_SSL_CIPHER_LIST: The list of supported SSL/TLS cipher suites.
41
-
42
41
  .. _sni: https://en.wikipedia.org/wiki/Server_Name_Indication
43
42
  .. _crime attack: https://en.wikipedia.org/wiki/CRIME_(security_exploit)
44
-
45
- '''
43
+ """
46
44
  from __future__ import absolute_import
47
45
 
48
- try:
49
- from ndg.httpsclient.ssl_peer_verification import SUBJ_ALT_NAME_SUPPORT
50
- from ndg.httpsclient.subj_alt_name import SubjectAltName as BaseSubjectAltName
51
- except SyntaxError as e:
52
- raise ImportError(e)
53
-
46
+ import idna
54
47
  import OpenSSL.SSL
55
- from pyasn1.codec.der import decoder as der_decoder
56
- from pyasn1.type import univ, constraint
48
+ from cryptography import x509
49
+ from cryptography.hazmat.backends.openssl import backend as openssl_backend
50
+ from cryptography.hazmat.backends.openssl.x509 import _Certificate
51
+
57
52
  from socket import timeout, error as SocketError
53
+ from io import BytesIO
58
54
 
59
55
  try: # Platform-specific: Python 2
60
56
  from socket import _fileobject
61
57
  except ImportError: # Platform-specific: Python 3
62
58
  _fileobject = None
63
- from urllib3.packages.backports.makefile import backport_makefile
59
+ from ..packages.backports.makefile import backport_makefile
64
60
 
61
+ import logging
65
62
  import ssl
66
63
  import select
67
64
  import six
65
+ import sys
68
66
 
69
- from .. import connection
70
67
  from .. import util
71
68
 
72
69
  __all__ = ['inject_into_urllib3', 'extract_from_urllib3']
73
70
 
74
- # SNI only *really* works if we can read the subjectAltName of certificates.
75
- HAS_SNI = SUBJ_ALT_NAME_SUPPORT
71
+ # SNI always works.
72
+ HAS_SNI = True
76
73
 
77
74
  # Map from urllib3 to PyOpenSSL compatible parameter-values.
78
75
  _openssl_versions = {
@@ -91,78 +88,120 @@ try:
91
88
  except AttributeError:
92
89
  pass
93
90
 
94
- _openssl_verify = {
91
+ _stdlib_to_openssl_verify = {
95
92
  ssl.CERT_NONE: OpenSSL.SSL.VERIFY_NONE,
96
93
  ssl.CERT_OPTIONAL: OpenSSL.SSL.VERIFY_PEER,
97
94
  ssl.CERT_REQUIRED:
98
95
  OpenSSL.SSL.VERIFY_PEER + OpenSSL.SSL.VERIFY_FAIL_IF_NO_PEER_CERT,
99
96
  }
100
-
101
- DEFAULT_SSL_CIPHER_LIST = util.ssl_.DEFAULT_CIPHERS.encode('ascii')
97
+ _openssl_to_stdlib_verify = dict(
98
+ (v, k) for k, v in _stdlib_to_openssl_verify.items()
99
+ )
102
100
 
103
101
  # OpenSSL will only write 16K at a time
104
102
  SSL_WRITE_BLOCKSIZE = 16384
105
103
 
106
104
  orig_util_HAS_SNI = util.HAS_SNI
107
- orig_connection_ssl_wrap_socket = connection.ssl_wrap_socket
105
+ orig_util_SSLContext = util.ssl_.SSLContext
106
+
107
+
108
+ log = logging.getLogger(__name__)
108
109
 
109
110
 
110
111
  def inject_into_urllib3():
111
112
  'Monkey-patch urllib3 with PyOpenSSL-backed SSL-support.'
112
113
 
113
- connection.ssl_wrap_socket = ssl_wrap_socket
114
+ util.ssl_.SSLContext = PyOpenSSLContext
114
115
  util.HAS_SNI = HAS_SNI
116
+ util.ssl_.HAS_SNI = HAS_SNI
115
117
  util.IS_PYOPENSSL = True
118
+ util.ssl_.IS_PYOPENSSL = True
116
119
 
117
120
 
118
121
  def extract_from_urllib3():
119
122
  'Undo monkey-patching by :func:`inject_into_urllib3`.'
120
123
 
121
- connection.ssl_wrap_socket = orig_connection_ssl_wrap_socket
124
+ util.ssl_.SSLContext = orig_util_SSLContext
122
125
  util.HAS_SNI = orig_util_HAS_SNI
126
+ util.ssl_.HAS_SNI = orig_util_HAS_SNI
123
127
  util.IS_PYOPENSSL = False
128
+ util.ssl_.IS_PYOPENSSL = False
129
+
130
+
131
+ def _dnsname_to_stdlib(name):
132
+ """
133
+ Converts a dNSName SubjectAlternativeName field to the form used by the
134
+ standard library on the given Python version.
135
+
136
+ Cryptography produces a dNSName as a unicode string that was idna-decoded
137
+ from ASCII bytes. We need to idna-encode that string to get it back, and
138
+ then on Python 3 we also need to convert to unicode via UTF-8 (the stdlib
139
+ uses PyUnicode_FromStringAndSize on it, which decodes via UTF-8).
140
+ """
141
+ def idna_encode(name):
142
+ """
143
+ Borrowed wholesale from the Python Cryptography Project. It turns out
144
+ that we can't just safely call `idna.encode`: it can explode for
145
+ wildcard names. This avoids that problem.
146
+ """
147
+ for prefix in [u'*.', u'.']:
148
+ if name.startswith(prefix):
149
+ name = name[len(prefix):]
150
+ return prefix.encode('ascii') + idna.encode(name)
151
+ return idna.encode(name)
152
+
153
+ name = idna_encode(name)
154
+ if sys.version_info >= (3, 0):
155
+ name = name.decode('utf-8')
156
+ return name
124
157
 
125
158
 
126
- # Note: This is a slightly bug-fixed version of same from ndg-httpsclient.
127
- class SubjectAltName(BaseSubjectAltName):
128
- '''ASN.1 implementation for subjectAltNames support'''
129
-
130
- # There is no limit to how many SAN certificates a certificate may have,
131
- # however this needs to have some limit so we'll set an arbitrarily high
132
- # limit.
133
- sizeSpec = univ.SequenceOf.sizeSpec + \
134
- constraint.ValueSizeConstraint(1, 1024)
135
-
136
-
137
- # Note: This is a slightly bug-fixed version of same from ndg-httpsclient.
138
159
  def get_subj_alt_name(peer_cert):
139
- # Search through extensions
140
- dns_name = []
141
- if not SUBJ_ALT_NAME_SUPPORT:
142
- return dns_name
143
-
144
- general_names = SubjectAltName()
145
- for i in range(peer_cert.get_extension_count()):
146
- ext = peer_cert.get_extension(i)
147
- ext_name = ext.get_short_name()
148
- if ext_name != b'subjectAltName':
149
- continue
150
-
151
- # PyOpenSSL returns extension data in ASN.1 encoded form
152
- ext_dat = ext.get_data()
153
- decoded_dat = der_decoder.decode(ext_dat,
154
- asn1Spec=general_names)
155
-
156
- for name in decoded_dat:
157
- if not isinstance(name, SubjectAltName):
158
- continue
159
- for entry in range(len(name)):
160
- component = name.getComponentByPosition(entry)
161
- if component.getName() != 'dNSName':
162
- continue
163
- dns_name.append(str(component.getComponent()))
164
-
165
- return dns_name
160
+ """
161
+ Given an PyOpenSSL certificate, provides all the subject alternative names.
162
+ """
163
+ # Pass the cert to cryptography, which has much better APIs for this.
164
+ # This is technically using private APIs, but should work across all
165
+ # relevant versions until PyOpenSSL gets something proper for this.
166
+ cert = _Certificate(openssl_backend, peer_cert._x509)
167
+
168
+ # We want to find the SAN extension. Ask Cryptography to locate it (it's
169
+ # faster than looping in Python)
170
+ try:
171
+ ext = cert.extensions.get_extension_for_class(
172
+ x509.SubjectAlternativeName
173
+ ).value
174
+ except x509.ExtensionNotFound:
175
+ # No such extension, return the empty list.
176
+ return []
177
+ except (x509.DuplicateExtension, x509.UnsupportedExtension,
178
+ x509.UnsupportedGeneralNameType, UnicodeError) as e:
179
+ # A problem has been found with the quality of the certificate. Assume
180
+ # no SAN field is present.
181
+ log.warning(
182
+ "A problem was encountered with the certificate that prevented "
183
+ "urllib3 from finding the SubjectAlternativeName field. This can "
184
+ "affect certificate validation. The error was %s",
185
+ e,
186
+ )
187
+ return []
188
+
189
+ # We want to return dNSName and iPAddress fields. We need to cast the IPs
190
+ # back to strings because the match_hostname function wants them as
191
+ # strings.
192
+ # Sadly the DNS names need to be idna encoded and then, on Python 3, UTF-8
193
+ # decoded. This is pretty frustrating, but that's what the standard library
194
+ # does with certificates, and so we need to attempt to do the same.
195
+ names = [
196
+ ('DNS', _dnsname_to_stdlib(name))
197
+ for name in ext.get_values_for_type(x509.DNSName)
198
+ ]
199
+ names.extend(
200
+ ('IP Address', str(name))
201
+ for name in ext.get_values_for_type(x509.IPAddress)
202
+ )
203
+
204
+ return names
166
205
 
167
206
 
168
207
  class WrappedSocket(object):
@@ -282,10 +321,7 @@ class WrappedSocket(object):
282
321
  'subject': (
283
322
  (('commonName', x509.get_subject().CN),),
284
323
  ),
285
- 'subjectAltName': [
286
- ('DNS', value)
287
- for value in get_subj_alt_name(x509)
288
- ]
324
+ 'subjectAltName': get_subj_alt_name(x509)
289
325
  }
290
326
 
291
327
  def _reuse(self):
@@ -308,51 +344,88 @@ else: # Platform-specific: Python 3
308
344
  WrappedSocket.makefile = makefile
309
345
 
310
346
 
311
- def _verify_callback(cnx, x509, err_no, err_depth, return_code):
312
- return err_no == 0
347
+ class PyOpenSSLContext(object):
348
+ """
349
+ I am a wrapper class for the PyOpenSSL ``Context`` object. I am responsible
350
+ for translating the interface of the standard library ``SSLContext`` object
351
+ to calls into PyOpenSSL.
352
+ """
353
+ def __init__(self, protocol):
354
+ self.protocol = _openssl_versions[protocol]
355
+ self._ctx = OpenSSL.SSL.Context(self.protocol)
356
+ self._options = 0
357
+ self.check_hostname = False
358
+
359
+ @property
360
+ def options(self):
361
+ return self._options
362
+
363
+ @options.setter
364
+ def options(self, value):
365
+ self._options = value
366
+ self._ctx.set_options(value)
367
+
368
+ @property
369
+ def verify_mode(self):
370
+ return _openssl_to_stdlib_verify[self._ctx.get_verify_mode()]
371
+
372
+ @verify_mode.setter
373
+ def verify_mode(self, value):
374
+ self._ctx.set_verify(
375
+ _stdlib_to_openssl_verify[value],
376
+ _verify_callback
377
+ )
378
+
379
+ def set_default_verify_paths(self):
380
+ self._ctx.set_default_verify_paths()
381
+
382
+ def set_ciphers(self, ciphers):
383
+ if isinstance(ciphers, six.text_type):
384
+ ciphers = ciphers.encode('utf-8')
385
+ self._ctx.set_cipher_list(ciphers)
386
+
387
+ def load_verify_locations(self, cafile=None, capath=None, cadata=None):
388
+ if cafile is not None:
389
+ cafile = cafile.encode('utf-8')
390
+ if capath is not None:
391
+ capath = capath.encode('utf-8')
392
+ self._ctx.load_verify_locations(cafile, capath)
393
+ if cadata is not None:
394
+ self._ctx.load_verify_locations(BytesIO(cadata))
395
+
396
+ def load_cert_chain(self, certfile, keyfile=None, password=None):
397
+ self._ctx.use_certificate_file(certfile)
398
+ if password is not None:
399
+ self._ctx.set_passwd_cb(lambda max_length, prompt_twice, userdata: password)
400
+ self._ctx.use_privatekey_file(keyfile or certfile)
401
+
402
+ def wrap_socket(self, sock, server_side=False,
403
+ do_handshake_on_connect=True, suppress_ragged_eofs=True,
404
+ server_hostname=None):
405
+ cnx = OpenSSL.SSL.Connection(self._ctx, sock)
406
+
407
+ if isinstance(server_hostname, six.text_type): # Platform-specific: Python 3
408
+ server_hostname = server_hostname.encode('utf-8')
409
+
410
+ if server_hostname is not None:
411
+ cnx.set_tlsext_host_name(server_hostname)
412
+
413
+ cnx.set_connect_state()
414
+
415
+ while True:
416
+ try:
417
+ cnx.do_handshake()
418
+ except OpenSSL.SSL.WantReadError:
419
+ rd, _, _ = select.select([sock], [], [], sock.gettimeout())
420
+ if not rd:
421
+ raise timeout('select timed out')
422
+ continue
423
+ except OpenSSL.SSL.Error as e:
424
+ raise ssl.SSLError('bad handshake: %r' % e)
425
+ break
313
426
 
427
+ return WrappedSocket(cnx, sock)
314
428
 
315
- def ssl_wrap_socket(sock, keyfile=None, certfile=None, cert_reqs=None,
316
- ca_certs=None, server_hostname=None,
317
- ssl_version=None, ca_cert_dir=None):
318
- ctx = OpenSSL.SSL.Context(_openssl_versions[ssl_version])
319
- if certfile:
320
- keyfile = keyfile or certfile # Match behaviour of the normal python ssl library
321
- ctx.use_certificate_file(certfile)
322
- if keyfile:
323
- ctx.use_privatekey_file(keyfile)
324
- if cert_reqs != ssl.CERT_NONE:
325
- ctx.set_verify(_openssl_verify[cert_reqs], _verify_callback)
326
- if ca_certs or ca_cert_dir:
327
- try:
328
- ctx.load_verify_locations(ca_certs, ca_cert_dir)
329
- except OpenSSL.SSL.Error as e:
330
- raise ssl.SSLError('bad ca_certs: %r' % ca_certs, e)
331
- else:
332
- ctx.set_default_verify_paths()
333
-
334
- # Disable TLS compression to mitigate CRIME attack (issue #309)
335
- OP_NO_COMPRESSION = 0x20000
336
- ctx.set_options(OP_NO_COMPRESSION)
337
-
338
- # Set list of supported ciphersuites.
339
- ctx.set_cipher_list(DEFAULT_SSL_CIPHER_LIST)
340
-
341
- cnx = OpenSSL.SSL.Connection(ctx, sock)
342
- if isinstance(server_hostname, six.text_type): # Platform-specific: Python 3
343
- server_hostname = server_hostname.encode('utf-8')
344
- cnx.set_tlsext_host_name(server_hostname)
345
- cnx.set_connect_state()
346
- while True:
347
- try:
348
- cnx.do_handshake()
349
- except OpenSSL.SSL.WantReadError:
350
- rd, _, _ = select.select([sock], [], [], sock.gettimeout())
351
- if not rd:
352
- raise timeout('select timed out')
353
- continue
354
- except OpenSSL.SSL.Error as e:
355
- raise ssl.SSLError('bad handshake: %r' % e)
356
- break
357
429
 
358
- return WrappedSocket(cnx, sock)
430
+ def _verify_callback(cnx, x509, err_no, err_depth, return_code):
431
+ return err_no == 0
@@ -1,17 +1,23 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  """
3
- SOCKS support for urllib3
4
- ~~~~~~~~~~~~~~~~~~~~~~~~~
5
-
6
- This contrib module contains provisional support for SOCKS proxies from within
3
+ This module contains provisional support for SOCKS proxies from within
7
4
  urllib3. This module supports SOCKS4 (specifically the SOCKS4A variant) and
8
5
  SOCKS5. To enable its functionality, either install PySocks or install this
9
6
  module with the ``socks`` extra.
10
7
 
8
+ The SOCKS implementation supports the full range of urllib3 features. It also
9
+ supports the following SOCKS features:
10
+
11
+ - SOCKS4
12
+ - SOCKS4a
13
+ - SOCKS5
14
+ - Usernames and passwords for the SOCKS proxy
15
+
11
16
  Known Limitations:
12
17
 
13
18
  - Currently PySocks does not support contacting remote websites via literal
14
- IPv6 addresses. Any such connection attempt will fail.
19
+ IPv6 addresses. Any such connection attempt will fail. You must use a domain
20
+ name.
15
21
  - Currently PySocks does not support IPv6 connections to the SOCKS proxy. Any
16
22
  such connection attempt will fail.
17
23
  """
@@ -1,4 +1,7 @@
1
1
  from __future__ import absolute_import
2
+ from .packages.six.moves.http_client import (
3
+ IncompleteRead as httplib_IncompleteRead
4
+ )
2
5
  # Base Exceptions
3
6
 
4
7
 
@@ -193,6 +196,35 @@ class ResponseNotChunked(ProtocolError, ValueError):
193
196
  pass
194
197
 
195
198
 
199
+ class BodyNotHttplibCompatible(HTTPError):
200
+ """
201
+ Body should be httplib.HTTPResponse like (have an fp attribute which
202
+ returns raw chunks) for read_chunked().
203
+ """
204
+ pass
205
+
206
+
207
+ class IncompleteRead(HTTPError, httplib_IncompleteRead):
208
+ """
209
+ Response length doesn't match expected Content-Length
210
+
211
+ Subclass of http_client.IncompleteRead to allow int value
212
+ for `partial` to avoid creating large objects on streamed
213
+ reads.
214
+ """
215
+ def __init__(self, partial, expected):
216
+ super(IncompleteRead, self).__init__(partial, expected)
217
+
218
+ def __repr__(self):
219
+ return ('IncompleteRead(%i bytes read, '
220
+ '%i more expected)' % (self.partial, self.expected))
221
+
222
+
223
+ class InvalidHeader(HTTPError):
224
+ "The header provided was somehow invalid."
225
+ pass
226
+
227
+
196
228
  class ProxySchemeUnknown(AssertionError, ValueError):
197
229
  "ProxyManager does not support the supplied scheme"
198
230
  # TODO(t-8ch): Stop inheriting from AssertionError in v2.0.