Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
S
setuptools
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jérome Perrin
setuptools
Commits
38fcb3e3
Commit
38fcb3e3
authored
Oct 28, 2013
by
Toshio Kuratomi
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update ssl_match_hostname to match new stdlib code that fixes a security issue with IDNA domains.
parent
1e0a9fb4
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
54 additions
and
22 deletions
+54
-22
setuptools/ssl_support.py
setuptools/ssl_support.py
+54
-22
No files found.
setuptools/ssl_support.py
View file @
38fcb3e3
...
...
@@ -88,30 +88,62 @@ except ImportError:
class
CertificateError
(
ValueError
):
pass
def
_dnsname_to_pat
(
dn
,
max_wildcards
=
1
):
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
=
[]
for
frag
in
dn
.
split
(
r'.'
):
if
frag
.
count
(
'*'
)
>
max_wildcards
:
# Issue #17980: avoid denials of service by refusing more
# than one wildcard per fragment. A survery of established
# policy among SSL implementations showed it to be a
# reasonable choice.
raise
CertificateError
(
"too many wildcards in certificate DNS name: "
+
repr
(
dn
))
if
frag
==
'*'
:
# When '*' is a fragment by itself, it matches a non-empty dotless
# fragment.
pats
.
append
(
'[^.]+'
)
else
:
# Otherwise, '*' matches any dotless fragment.
frag
=
re
.
escape
(
frag
)
pats
.
append
(
frag
.
replace
(
r'\
*
', '
[
^
.]
*
'))
return re.compile(r'
\
A
' + r'
\
.
'.join(pats) + r'
\
Z
', re.IGNORECASE)
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 match_hostname(cert, hostname):
"""Verify that *cert* (in decoded format as returned by
SSLSocket.getpeercert()) matches the *hostname*. RFC 2818
rules
are mostly
followed, but IP addresses are not accepted for *hostname*.
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.
...
...
@@ -122,7 +154,7 @@ except ImportError:
san = cert.get('
subjectAltName
', ())
for key, value in san:
if key == '
DNS
':
if _dnsname_
to_pat(value).match(
hostname):
if _dnsname_
match(value,
hostname):
return
dnsnames.append(value)
if not dnsnames:
...
...
@@ -133,7 +165,7 @@ except ImportError:
# XXX according to RFC 2818, the most specific Common Name
# must be used.
if key == '
commonName
':
if _dnsname_
to_pat(value).match(
hostname):
if _dnsname_
match(value,
hostname):
return
dnsnames.append(value)
if len(dnsnames) > 1:
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment