diff --git a/.gitignore b/.gitignore index a261d6f..630c966 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,5 @@ /urllib3-1.21.1.tar.gz /urllib3-1.22.tar.gz /urllib3-1.23.tar.gz +/urllib3-1.24.tar.gz +/urllib3-1.24.1.tar.gz diff --git a/Unbundle-ssl_match_hostname-backport.patch b/Unbundle-ssl_match_hostname-backport.patch new file mode 100644 index 0000000..5ad88ed --- /dev/null +++ b/Unbundle-ssl_match_hostname-backport.patch @@ -0,0 +1,207 @@ +From ee3425b5bfba3262c3485265c3aaaf99169e11d0 Mon Sep 17 00:00:00 2001 +From: Jeremy Cline +Date: Mon, 29 Oct 2018 16:07:52 -0400 +Subject: [PATCH] Unbundle ssl_match_hostname backport + +Fedora has shipped 3.5+ for a long time and we depend on backports of +Python 2. + +Signed-off-by: Jeremy Cline +--- + .../packages/ssl_match_hostname/__init__.py | 14 +- + .../ssl_match_hostname/_implementation.py | 156 ------------------ + 2 files changed, 3 insertions(+), 167 deletions(-) + delete mode 100644 src/urllib3/packages/ssl_match_hostname/_implementation.py + +diff --git a/src/urllib3/packages/ssl_match_hostname/__init__.py b/src/urllib3/packages/ssl_match_hostname/__init__.py +index d6594eb..6bd8fb9 100644 +--- a/src/urllib3/packages/ssl_match_hostname/__init__.py ++++ b/src/urllib3/packages/ssl_match_hostname/__init__.py +@@ -1,19 +1,11 @@ + import sys + + try: +- # Our match_hostname function is the same as 3.5's, so we only want to +- # import the match_hostname function if it's at least that good. +- if sys.version_info < (3, 5): +- raise ImportError("Fallback to vendored code") +- ++ # Python 3.5+ + from ssl import CertificateError, match_hostname + except ImportError: +- try: +- # Backport of the function from a pypi module +- from backports.ssl_match_hostname import CertificateError, match_hostname +- except ImportError: +- # Our vendored copy +- from ._implementation import CertificateError, match_hostname ++ # Python 2 ++ from backports.ssl_match_hostname import CertificateError, match_hostname + + # Not needed, but documenting what we provide. + __all__ = ('CertificateError', 'match_hostname') +diff --git a/src/urllib3/packages/ssl_match_hostname/_implementation.py b/src/urllib3/packages/ssl_match_hostname/_implementation.py +deleted file mode 100644 +index d6e66c0..0000000 +--- a/src/urllib3/packages/ssl_match_hostname/_implementation.py ++++ /dev/null +@@ -1,156 +0,0 @@ +-"""The match_hostname() function from Python 3.3.3, essential when using SSL.""" +- +-# Note: This file is under the PSF license as the code comes from the python +-# stdlib. http://docs.python.org/3/license.html +- +-import re +-import sys +- +-# ipaddress has been backported to 2.6+ in pypi. If it is installed on the +-# system, use it to handle IPAddress ServerAltnames (this was added in +-# python-3.5) otherwise only do DNS matching. This allows +-# backports.ssl_match_hostname to continue to be used in Python 2.7. +-try: +- import ipaddress +-except ImportError: +- ipaddress = None +- +-__version__ = '3.5.0.1' +- +- +-class CertificateError(ValueError): +- pass +- +- +-def _dnsname_match(dn, hostname, max_wildcards=1): +- """Matching according to RFC 6125, section 6.4.3 +- +- http://tools.ietf.org/html/rfc6125#section-6.4.3 +- """ +- pats = [] +- if not dn: +- return False +- +- # Ported from python3-syntax: +- # leftmost, *remainder = dn.split(r'.') +- parts = dn.split(r'.') +- leftmost = parts[0] +- remainder = parts[1:] +- +- wildcards = leftmost.count('*') +- if wildcards > max_wildcards: +- # Issue #17980: avoid denials of service by refusing more +- # than one wildcard per fragment. A survey of established +- # policy among SSL implementations showed it to be a +- # reasonable choice. +- raise CertificateError( +- "too many wildcards in certificate DNS name: " + repr(dn)) +- +- # speed up common case w/o wildcards +- if not wildcards: +- return dn.lower() == hostname.lower() +- +- # RFC 6125, section 6.4.3, subitem 1. +- # The client SHOULD NOT attempt to match a presented identifier in which +- # the wildcard character comprises a label other than the left-most label. +- if leftmost == '*': +- # When '*' is a fragment by itself, it matches a non-empty dotless +- # fragment. +- pats.append('[^.]+') +- elif leftmost.startswith('xn--') or hostname.startswith('xn--'): +- # RFC 6125, section 6.4.3, subitem 3. +- # The client SHOULD NOT attempt to match a presented identifier +- # where the wildcard character is embedded within an A-label or +- # U-label of an internationalized domain name. +- pats.append(re.escape(leftmost)) +- else: +- # Otherwise, '*' matches any dotless string, e.g. www* +- pats.append(re.escape(leftmost).replace(r'\*', '[^.]*')) +- +- # add the remaining fragments, ignore any wildcards +- for frag in remainder: +- pats.append(re.escape(frag)) +- +- pat = re.compile(r'\A' + r'\.'.join(pats) + r'\Z', re.IGNORECASE) +- return pat.match(hostname) +- +- +-def _to_unicode(obj): +- if isinstance(obj, str) and sys.version_info < (3,): +- obj = unicode(obj, encoding='ascii', errors='strict') +- return obj +- +-def _ipaddress_match(ipname, host_ip): +- """Exact matching of IP addresses. +- +- RFC 6125 explicitly doesn't define an algorithm for this +- (section 1.7.2 - "Out of Scope"). +- """ +- # OpenSSL may add a trailing newline to a subjectAltName's IP address +- # Divergence from upstream: ipaddress can't handle byte str +- ip = ipaddress.ip_address(_to_unicode(ipname).rstrip()) +- return ip == host_ip +- +- +-def match_hostname(cert, hostname): +- """Verify that *cert* (in decoded format as returned by +- SSLSocket.getpeercert()) matches the *hostname*. RFC 2818 and RFC 6125 +- rules are followed, but IP addresses are not accepted for *hostname*. +- +- CertificateError is raised on failure. On success, the function +- returns nothing. +- """ +- if not cert: +- raise ValueError("empty or no certificate, match_hostname needs a " +- "SSL socket or SSL context with either " +- "CERT_OPTIONAL or CERT_REQUIRED") +- try: +- # Divergence from upstream: ipaddress can't handle byte str +- host_ip = ipaddress.ip_address(_to_unicode(hostname)) +- except ValueError: +- # Not an IP address (common case) +- host_ip = None +- except UnicodeError: +- # Divergence from upstream: Have to deal with ipaddress not taking +- # byte strings. addresses should be all ascii, so we consider it not +- # an ipaddress in this case +- host_ip = None +- except AttributeError: +- # Divergence from upstream: Make ipaddress library optional +- if ipaddress is None: +- host_ip = None +- else: +- raise +- dnsnames = [] +- san = cert.get('subjectAltName', ()) +- for key, value in san: +- if key == 'DNS': +- if host_ip is None and _dnsname_match(value, hostname): +- return +- dnsnames.append(value) +- elif key == 'IP Address': +- if host_ip is not None and _ipaddress_match(value, host_ip): +- return +- dnsnames.append(value) +- if not dnsnames: +- # The subject is only checked when there is no dNSName entry +- # in subjectAltName +- for sub in cert.get('subject', ()): +- for key, value in sub: +- # XXX according to RFC 2818, the most specific Common Name +- # must be used. +- if key == 'commonName': +- if _dnsname_match(value, hostname): +- return +- dnsnames.append(value) +- if len(dnsnames) > 1: +- raise CertificateError("hostname %r " +- "doesn't match either of %s" +- % (hostname, ', '.join(map(repr, dnsnames)))) +- elif len(dnsnames) == 1: +- raise CertificateError("hostname %r " +- "doesn't match %r" +- % (hostname, dnsnames[0])) +- else: +- raise CertificateError("no appropriate commonName or " +- "subjectAltName fields were found") +-- +2.19.1 + diff --git a/python-urllib3.spec b/python-urllib3.spec index 4b876b2..4095d01 100644 --- a/python-urllib3.spec +++ b/python-urllib3.spec @@ -4,15 +4,15 @@ %bcond_without tests Name: python-%{srcname} -Version: 1.23 -Release: 4%{?dist} +Version: 1.24.1 +Release: 1%{?dist} Summary: Python HTTP library with thread-safe connection pooling and file post License: MIT -URL: https://github.com/shazow/urllib3 +URL: https://github.com/urllib3/urllib3 Source0: %{url}/archive/%{version}/%{srcname}-%{version}.tar.gz -# Used with Python 3.5+ -Source1: ssl_match_hostname_py3.py +# Unbundle ssl_match_hostname since we depend on it +Patch0: Unbundle-ssl_match_hostname-backport.patch BuildArch: noarch %description @@ -34,6 +34,7 @@ Requires: python2-pysocks BuildRequires: python2-devel %if %{with tests} +BuildRequires: python2-backports-ssl_match_hostname BuildRequires: python2-nose BuildRequires: python2-nose-exclude BuildRequires: python2-coverage @@ -70,7 +71,7 @@ Python3 HTTP module with connection pooling and file POST abilities. %prep -%setup -q -n %{srcname}-%{version} +%autosetup -p1 -n %{srcname}-%{version} # Drop the dummyserver tests in koji. They fail there in real builds, but not # in scratch builds (weird). rm -rf test/with_dummyserver/ @@ -80,6 +81,10 @@ rm -rf test/appengine/ # to do with Fedora in particular. They don't fail in upstream build infrastructure rm -rf test/contrib/ +# Tests for Python built without SSL, but Fedora builds with SSL. These tests +# fail when combined with the unbundling of backports-ssl_match_hostname +rm -f test/test_no_ssl.py + %build %py2_build %py3_build @@ -91,34 +96,30 @@ rm -rf test/contrib/ # Unbundle the Python 2 build rm -rf %{buildroot}/%{python2_sitelib}/urllib3/packages/six.py* -rm -rf %{buildroot}/%{python2_sitelib}/urllib3/packages/ssl_match_hostname/ mkdir -p %{buildroot}/%{python2_sitelib}/urllib3/packages/ -ln -s ../../six.py %{buildroot}/%{python2_sitelib}/urllib3/packages/six.py -ln -s ../../six.pyc %{buildroot}/%{python2_sitelib}/urllib3/packages/six.pyc -ln -s ../../six.pyo %{buildroot}/%{python2_sitelib}/urllib3/packages/six.pyo - -ln -s ../../backports/ssl_match_hostname %{buildroot}/%{python2_sitelib}/urllib3/packages/ssl_match_hostname +ln -s %{python2_sitelib}/six.py %{buildroot}/%{python2_sitelib}/urllib3/packages/six.py +ln -s %{python2_sitelib}/six.pyc %{buildroot}/%{python2_sitelib}/urllib3/packages/six.pyc +ln -s %{python2_sitelib}/six.pyo %{buildroot}/%{python2_sitelib}/urllib3/packages/six.pyo # Unbundle the Python 3 build rm -rf %{buildroot}/%{python3_sitelib}/urllib3/packages/six.py* rm -rf %{buildroot}/%{python3_sitelib}/urllib3/packages/__pycache__/six* -rm -rf %{buildroot}/%{python3_sitelib}/urllib3/packages/ssl_match_hostname/ mkdir -p %{buildroot}/%{python3_sitelib}/urllib3/packages/ -ln -s ../../six.py %{buildroot}/%{python3_sitelib}/urllib3/packages/six.py -ln -s ../../../__pycache__/six.cpython-%{python3_version_nodots}.opt-1.pyc %{buildroot}/%{python3_sitelib}/urllib3/packages/__pycache__/ -ln -s ../../../__pycache__/six.cpython-%{python3_version_nodots}.pyc %{buildroot}/%{python3_sitelib}/urllib3/packages/__pycache__/ -# urllib3 requires Python 3.5 to use the standard library's match_hostname, -# which we ship in Fedora 26, so we can safely replace the bundled version with -# this stub which imports the necessary objects. -cp %{SOURCE1} %{buildroot}/%{python3_sitelib}/urllib3/packages/ssl_match_hostname.py +ln -s %{python3_sitelib}/six.py %{buildroot}/%{python3_sitelib}/urllib3/packages/six.py +ln -s %{python3_sitelib}/__pycache__/six.cpython-%{python3_version_nodots}.opt-1.pyc \ + %{buildroot}/%{python3_sitelib}/urllib3/packages/__pycache__/ +ln -s %{python3_sitelib}/__pycache__/six.cpython-%{python3_version_nodots}.pyc \ + %{buildroot}/%{python3_sitelib}/urllib3/packages/__pycache__/ %if %{with tests} %check -py.test -py.test-3 +pushd test +PYTHONPATH=%{buildroot}%{python2_sitelib}:%{python2_sitelib} %{__python2} -m pytest -v +PYTHONPATH=%{buildroot}%{python3_sitelib}:%{python3_sitelib} %{__python3} -m pytest -v +popd %endif @@ -137,6 +138,9 @@ py.test-3 %changelog +* Mon Oct 29 2018 Jeremy Cline - 1.24.1-1 +- Update to v1.24.1 + * Wed Jun 20 2018 Lumír Balhar - 1.23-4 - Removed unneeded dependency python[23]-psutil diff --git a/sources b/sources index 392513e..d1287f7 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (urllib3-1.23.tar.gz) = 1d9eccdd2f939a1029fb6e49c45409b3a493f38b5880bba45a6e8a8088c0478190807b1fe7341b22abe363809ef41c5367de831de9618bcc62f34cb9f0cbc7af +SHA512 (urllib3-1.24.1.tar.gz) = 2f5453cf0ec1b65de9a9fca0fdb45664f7481507c875b7115c063cb177628b4b611377e588508ab8433e0797fc78b60fd3ea5cc5ac0a3f105d36bfff9a56f1f4