author | Matt Mackall <mpm@selenic.com> |
Mon, 06 Jun 2011 15:17:40 -0500 | |
changeset 14536 | 52cbeb5a651b |
parent 14313 | a389dd285282 |
child 14666 | 27b080aa880a |
permissions | -rw-r--r-- |
12737
7adb1274a4f9
test-url: skip test when ssl module is unavailable
Augie Fackler <durin42@gmail.com>
parents:
12592
diff
changeset
|
1 |
import sys |
12592
f2937d6492c5
url: verify correctness of https server certificates (issue2407)
Mads Kiilerich <mads@kiilerich.com>
parents:
diff
changeset
|
2 |
|
f2937d6492c5
url: verify correctness of https server certificates (issue2407)
Mads Kiilerich <mads@kiilerich.com>
parents:
diff
changeset
|
3 |
def check(a, b): |
f2937d6492c5
url: verify correctness of https server certificates (issue2407)
Mads Kiilerich <mads@kiilerich.com>
parents:
diff
changeset
|
4 |
if a != b: |
f2937d6492c5
url: verify correctness of https server certificates (issue2407)
Mads Kiilerich <mads@kiilerich.com>
parents:
diff
changeset
|
5 |
print (a, b) |
f2937d6492c5
url: verify correctness of https server certificates (issue2407)
Mads Kiilerich <mads@kiilerich.com>
parents:
diff
changeset
|
6 |
|
12606
5c8353692123
test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents:
12592
diff
changeset
|
7 |
def cert(cn): |
5c8353692123
test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents:
12592
diff
changeset
|
8 |
return dict(subject=((('commonName', cn),),)) |
5c8353692123
test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents:
12592
diff
changeset
|
9 |
|
14204
5fa21960b2f4
sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents:
14076
diff
changeset
|
10 |
from mercurial.sslutil import _verifycert |
12592
f2937d6492c5
url: verify correctness of https server certificates (issue2407)
Mads Kiilerich <mads@kiilerich.com>
parents:
diff
changeset
|
11 |
|
12724
66e7ba85585b
test-url: remove trailing whitespace
Augie Fackler <durin42@gmail.com>
parents:
12606
diff
changeset
|
12 |
# Test non-wildcard certificates |
12606
5c8353692123
test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents:
12592
diff
changeset
|
13 |
check(_verifycert(cert('example.com'), 'example.com'), |
5c8353692123
test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents:
12592
diff
changeset
|
14 |
None) |
5c8353692123
test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents:
12592
diff
changeset
|
15 |
check(_verifycert(cert('example.com'), 'www.example.com'), |
5c8353692123
test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents:
12592
diff
changeset
|
16 |
'certificate is for example.com') |
5c8353692123
test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents:
12592
diff
changeset
|
17 |
check(_verifycert(cert('www.example.com'), 'example.com'), |
5c8353692123
test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents:
12592
diff
changeset
|
18 |
'certificate is for www.example.com') |
12592
f2937d6492c5
url: verify correctness of https server certificates (issue2407)
Mads Kiilerich <mads@kiilerich.com>
parents:
diff
changeset
|
19 |
|
f2937d6492c5
url: verify correctness of https server certificates (issue2407)
Mads Kiilerich <mads@kiilerich.com>
parents:
diff
changeset
|
20 |
# Test wildcard certificates |
12606
5c8353692123
test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents:
12592
diff
changeset
|
21 |
check(_verifycert(cert('*.example.com'), 'www.example.com'), |
5c8353692123
test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents:
12592
diff
changeset
|
22 |
None) |
5c8353692123
test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents:
12592
diff
changeset
|
23 |
check(_verifycert(cert('*.example.com'), 'example.com'), |
5c8353692123
test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents:
12592
diff
changeset
|
24 |
'certificate is for *.example.com') |
5c8353692123
test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents:
12592
diff
changeset
|
25 |
check(_verifycert(cert('*.example.com'), 'w.w.example.com'), |
5c8353692123
test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents:
12592
diff
changeset
|
26 |
'certificate is for *.example.com') |
12592
f2937d6492c5
url: verify correctness of https server certificates (issue2407)
Mads Kiilerich <mads@kiilerich.com>
parents:
diff
changeset
|
27 |
|
13249
75d0c38a0bca
url: check subjectAltName when verifying ssl certificate
Yuya Nishihara <yuya@tcha.org>
parents:
13248
diff
changeset
|
28 |
# Test subjectAltName |
75d0c38a0bca
url: check subjectAltName when verifying ssl certificate
Yuya Nishihara <yuya@tcha.org>
parents:
13248
diff
changeset
|
29 |
san_cert = {'subject': ((('commonName', 'example.com'),),), |
75d0c38a0bca
url: check subjectAltName when verifying ssl certificate
Yuya Nishihara <yuya@tcha.org>
parents:
13248
diff
changeset
|
30 |
'subjectAltName': (('DNS', '*.example.net'), |
75d0c38a0bca
url: check subjectAltName when verifying ssl certificate
Yuya Nishihara <yuya@tcha.org>
parents:
13248
diff
changeset
|
31 |
('DNS', 'example.net'))} |
75d0c38a0bca
url: check subjectAltName when verifying ssl certificate
Yuya Nishihara <yuya@tcha.org>
parents:
13248
diff
changeset
|
32 |
check(_verifycert(san_cert, 'example.net'), |
75d0c38a0bca
url: check subjectAltName when verifying ssl certificate
Yuya Nishihara <yuya@tcha.org>
parents:
13248
diff
changeset
|
33 |
None) |
75d0c38a0bca
url: check subjectAltName when verifying ssl certificate
Yuya Nishihara <yuya@tcha.org>
parents:
13248
diff
changeset
|
34 |
check(_verifycert(san_cert, 'foo.example.net'), |
75d0c38a0bca
url: check subjectAltName when verifying ssl certificate
Yuya Nishihara <yuya@tcha.org>
parents:
13248
diff
changeset
|
35 |
None) |
75d0c38a0bca
url: check subjectAltName when verifying ssl certificate
Yuya Nishihara <yuya@tcha.org>
parents:
13248
diff
changeset
|
36 |
# subject is only checked when subjectAltName is empty |
75d0c38a0bca
url: check subjectAltName when verifying ssl certificate
Yuya Nishihara <yuya@tcha.org>
parents:
13248
diff
changeset
|
37 |
check(_verifycert(san_cert, 'example.com'), |
75d0c38a0bca
url: check subjectAltName when verifying ssl certificate
Yuya Nishihara <yuya@tcha.org>
parents:
13248
diff
changeset
|
38 |
'certificate is for *.example.net, example.net') |
75d0c38a0bca
url: check subjectAltName when verifying ssl certificate
Yuya Nishihara <yuya@tcha.org>
parents:
13248
diff
changeset
|
39 |
|
12592
f2937d6492c5
url: verify correctness of https server certificates (issue2407)
Mads Kiilerich <mads@kiilerich.com>
parents:
diff
changeset
|
40 |
# Avoid some pitfalls |
12606
5c8353692123
test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents:
12592
diff
changeset
|
41 |
check(_verifycert(cert('*.foo'), 'foo'), |
5c8353692123
test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents:
12592
diff
changeset
|
42 |
'certificate is for *.foo') |
5c8353692123
test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents:
12592
diff
changeset
|
43 |
check(_verifycert(cert('*o'), 'foo'), |
5c8353692123
test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents:
12592
diff
changeset
|
44 |
'certificate is for *o') |
12592
f2937d6492c5
url: verify correctness of https server certificates (issue2407)
Mads Kiilerich <mads@kiilerich.com>
parents:
diff
changeset
|
45 |
|
12742
6ab4a7d3c179
url: validity (notBefore/notAfter) is checked by OpenSSL (issue2407)
Mads Kiilerich <mads@kiilerich.com>
parents:
12738
diff
changeset
|
46 |
check(_verifycert({'subject': ()}, |
12606
5c8353692123
test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents:
12592
diff
changeset
|
47 |
'example.com'), |
13249
75d0c38a0bca
url: check subjectAltName when verifying ssl certificate
Yuya Nishihara <yuya@tcha.org>
parents:
13248
diff
changeset
|
48 |
'no commonName or subjectAltName found in certificate') |
12592
f2937d6492c5
url: verify correctness of https server certificates (issue2407)
Mads Kiilerich <mads@kiilerich.com>
parents:
diff
changeset
|
49 |
check(_verifycert(None, 'example.com'), |
12606
5c8353692123
test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents:
12592
diff
changeset
|
50 |
'no certificate received') |
13248
00411a4fa1bb
url: fix UnicodeDecodeError on certificate verification error
Yuya Nishihara <yuya@tcha.org>
parents:
12865
diff
changeset
|
51 |
|
13770 | 52 |
import doctest |
53 |
||
54 |
def test_url(): |
|
55 |
""" |
|
14076
924c82157d46
url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents:
13848
diff
changeset
|
56 |
>>> from mercurial.util import url |
13770 | 57 |
|
58 |
This tests for edge cases in url.URL's parsing algorithm. Most of |
|
59 |
these aren't useful for documentation purposes, so they aren't |
|
60 |
part of the class's doc tests. |
|
61 |
||
62 |
Query strings and fragments: |
|
63 |
||
64 |
>>> url('http://host/a?b#c') |
|
65 |
<url scheme: 'http', host: 'host', path: 'a', query: 'b', fragment: 'c'> |
|
66 |
>>> url('http://host/a?') |
|
67 |
<url scheme: 'http', host: 'host', path: 'a'> |
|
68 |
>>> url('http://host/a#b#c') |
|
69 |
<url scheme: 'http', host: 'host', path: 'a', fragment: 'b#c'> |
|
70 |
>>> url('http://host/a#b?c') |
|
71 |
<url scheme: 'http', host: 'host', path: 'a', fragment: 'b?c'> |
|
72 |
>>> url('http://host/?a#b') |
|
73 |
<url scheme: 'http', host: 'host', path: '', query: 'a', fragment: 'b'> |
|
13827
f1823b9f073b
url: nuke some newly-introduced underbars in identifiers
Matt Mackall <mpm@selenic.com>
parents:
13817
diff
changeset
|
74 |
>>> url('http://host/?a#b', parsequery=False) |
13770 | 75 |
<url scheme: 'http', host: 'host', path: '?a', fragment: 'b'> |
13827
f1823b9f073b
url: nuke some newly-introduced underbars in identifiers
Matt Mackall <mpm@selenic.com>
parents:
13817
diff
changeset
|
76 |
>>> url('http://host/?a#b', parsefragment=False) |
13770 | 77 |
<url scheme: 'http', host: 'host', path: '', query: 'a#b'> |
13827
f1823b9f073b
url: nuke some newly-introduced underbars in identifiers
Matt Mackall <mpm@selenic.com>
parents:
13817
diff
changeset
|
78 |
>>> url('http://host/?a#b', parsequery=False, parsefragment=False) |
13770 | 79 |
<url scheme: 'http', host: 'host', path: '?a#b'> |
80 |
||
81 |
IPv6 addresses: |
|
82 |
||
83 |
>>> url('ldap://[2001:db8::7]/c=GB?objectClass?one') |
|
84 |
<url scheme: 'ldap', host: '[2001:db8::7]', path: 'c=GB', |
|
85 |
query: 'objectClass?one'> |
|
86 |
>>> url('ldap://joe:xxx@[2001:db8::7]:80/c=GB?objectClass?one') |
|
87 |
<url scheme: 'ldap', user: 'joe', passwd: 'xxx', host: '[2001:db8::7]', |
|
88 |
port: '80', path: 'c=GB', query: 'objectClass?one'> |
|
89 |
||
90 |
Missing scheme, host, etc.: |
|
91 |
||
92 |
>>> url('://192.0.2.16:80/') |
|
93 |
<url path: '://192.0.2.16:80/'> |
|
94 |
>>> url('http://mercurial.selenic.com') |
|
95 |
<url scheme: 'http', host: 'mercurial.selenic.com'> |
|
96 |
>>> url('/foo') |
|
97 |
<url path: '/foo'> |
|
98 |
>>> url('bundle:/foo') |
|
99 |
<url scheme: 'bundle', path: '/foo'> |
|
100 |
>>> url('a?b#c') |
|
101 |
<url path: 'a?b', fragment: 'c'> |
|
102 |
>>> url('http://x.com?arg=/foo') |
|
103 |
<url scheme: 'http', host: 'x.com', query: 'arg=/foo'> |
|
104 |
>>> url('http://joe:xxx@/foo') |
|
105 |
<url scheme: 'http', user: 'joe', passwd: 'xxx', path: 'foo'> |
|
106 |
||
107 |
Just a scheme and a path: |
|
108 |
||
109 |
>>> url('mailto:John.Doe@example.com') |
|
110 |
<url scheme: 'mailto', path: 'John.Doe@example.com'> |
|
111 |
>>> url('a:b:c:d') |
|
13808 | 112 |
<url path: 'a:b:c:d'> |
113 |
>>> url('aa:bb:cc:dd') |
|
114 |
<url scheme: 'aa', path: 'bb:cc:dd'> |
|
13770 | 115 |
|
116 |
SSH examples: |
|
117 |
||
118 |
>>> url('ssh://joe@host//home/joe') |
|
119 |
<url scheme: 'ssh', user: 'joe', host: 'host', path: '/home/joe'> |
|
120 |
>>> url('ssh://joe:xxx@host/src') |
|
121 |
<url scheme: 'ssh', user: 'joe', passwd: 'xxx', host: 'host', path: 'src'> |
|
122 |
>>> url('ssh://joe:xxx@host') |
|
123 |
<url scheme: 'ssh', user: 'joe', passwd: 'xxx', host: 'host'> |
|
124 |
>>> url('ssh://joe@host') |
|
125 |
<url scheme: 'ssh', user: 'joe', host: 'host'> |
|
126 |
>>> url('ssh://host') |
|
127 |
<url scheme: 'ssh', host: 'host'> |
|
128 |
>>> url('ssh://') |
|
129 |
<url scheme: 'ssh'> |
|
130 |
>>> url('ssh:') |
|
131 |
<url scheme: 'ssh'> |
|
132 |
||
133 |
Non-numeric port: |
|
134 |
||
135 |
>>> url('http://example.com:dd') |
|
136 |
<url scheme: 'http', host: 'example.com', port: 'dd'> |
|
137 |
>>> url('ssh://joe:xxx@host:ssh/foo') |
|
138 |
<url scheme: 'ssh', user: 'joe', passwd: 'xxx', host: 'host', port: 'ssh', |
|
139 |
path: 'foo'> |
|
140 |
||
141 |
Bad authentication credentials: |
|
142 |
||
143 |
>>> url('http://joe@joeville:123@4:@host/a?b#c') |
|
144 |
<url scheme: 'http', user: 'joe@joeville', passwd: '123@4:', |
|
145 |
host: 'host', path: 'a', query: 'b', fragment: 'c'> |
|
146 |
>>> url('http://!*#?/@!*#?/:@host/a?b#c') |
|
147 |
<url scheme: 'http', host: '!*', fragment: '?/@!*#?/:@host/a?b#c'> |
|
148 |
>>> url('http://!*#?@!*#?:@host/a?b#c') |
|
149 |
<url scheme: 'http', host: '!*', fragment: '?@!*#?:@host/a?b#c'> |
|
150 |
>>> url('http://!*@:!*@@host/a?b#c') |
|
151 |
<url scheme: 'http', user: '!*@', passwd: '!*@', host: 'host', |
|
152 |
path: 'a', query: 'b', fragment: 'c'> |
|
153 |
||
154 |
File paths: |
|
155 |
||
156 |
>>> url('a/b/c/d.g.f') |
|
157 |
<url path: 'a/b/c/d.g.f'> |
|
158 |
>>> url('/x///z/y/') |
|
159 |
<url path: '/x///z/y/'> |
|
13848
b2798c1defff
url: be stricter about detecting schemes
Brodie Rao <brodie@bitheap.org>
parents:
13827
diff
changeset
|
160 |
>>> url('/foo:bar') |
b2798c1defff
url: be stricter about detecting schemes
Brodie Rao <brodie@bitheap.org>
parents:
13827
diff
changeset
|
161 |
<url path: '/foo:bar'> |
b2798c1defff
url: be stricter about detecting schemes
Brodie Rao <brodie@bitheap.org>
parents:
13827
diff
changeset
|
162 |
>>> url('\\\\foo:bar') |
b2798c1defff
url: be stricter about detecting schemes
Brodie Rao <brodie@bitheap.org>
parents:
13827
diff
changeset
|
163 |
<url path: '\\\\foo:bar'> |
b2798c1defff
url: be stricter about detecting schemes
Brodie Rao <brodie@bitheap.org>
parents:
13827
diff
changeset
|
164 |
>>> url('./foo:bar') |
b2798c1defff
url: be stricter about detecting schemes
Brodie Rao <brodie@bitheap.org>
parents:
13827
diff
changeset
|
165 |
<url path: './foo:bar'> |
13770 | 166 |
|
13817
7f18bab2c0b0
url: abort on file:// URLs with non-localhost hosts
Brodie Rao <brodie@bitheap.org>
parents:
13808
diff
changeset
|
167 |
Non-localhost file URL: |
7f18bab2c0b0
url: abort on file:// URLs with non-localhost hosts
Brodie Rao <brodie@bitheap.org>
parents:
13808
diff
changeset
|
168 |
|
7f18bab2c0b0
url: abort on file:// URLs with non-localhost hosts
Brodie Rao <brodie@bitheap.org>
parents:
13808
diff
changeset
|
169 |
>>> u = url('file://mercurial.selenic.com/foo') |
7f18bab2c0b0
url: abort on file:// URLs with non-localhost hosts
Brodie Rao <brodie@bitheap.org>
parents:
13808
diff
changeset
|
170 |
Traceback (most recent call last): |
7f18bab2c0b0
url: abort on file:// URLs with non-localhost hosts
Brodie Rao <brodie@bitheap.org>
parents:
13808
diff
changeset
|
171 |
File "<stdin>", line 1, in ? |
7f18bab2c0b0
url: abort on file:// URLs with non-localhost hosts
Brodie Rao <brodie@bitheap.org>
parents:
13808
diff
changeset
|
172 |
Abort: file:// URLs can only refer to localhost |
7f18bab2c0b0
url: abort on file:// URLs with non-localhost hosts
Brodie Rao <brodie@bitheap.org>
parents:
13808
diff
changeset
|
173 |
|
13770 | 174 |
Empty URL: |
175 |
||
176 |
>>> u = url('') |
|
177 |
>>> u |
|
178 |
<url path: ''> |
|
179 |
>>> str(u) |
|
180 |
'' |
|
181 |
||
182 |
Empty path with query string: |
|
183 |
||
184 |
>>> str(url('http://foo/?bar')) |
|
185 |
'http://foo/?bar' |
|
186 |
||
187 |
Invalid path: |
|
188 |
||
189 |
>>> u = url('http://foo/bar') |
|
190 |
>>> u.path = 'bar' |
|
191 |
>>> str(u) |
|
192 |
'http://foo/bar' |
|
193 |
||
14313
a389dd285282
util: make str(url) return file:/// for abs paths again
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
14204
diff
changeset
|
194 |
>>> u = url('file:/foo/bar/baz') |
a389dd285282
util: make str(url) return file:/// for abs paths again
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
14204
diff
changeset
|
195 |
>>> u |
a389dd285282
util: make str(url) return file:/// for abs paths again
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
14204
diff
changeset
|
196 |
<url scheme: 'file', path: '/foo/bar/baz'> |
a389dd285282
util: make str(url) return file:/// for abs paths again
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
14204
diff
changeset
|
197 |
>>> str(u) |
a389dd285282
util: make str(url) return file:/// for abs paths again
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
14204
diff
changeset
|
198 |
'file:///foo/bar/baz' |
a389dd285282
util: make str(url) return file:/// for abs paths again
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
14204
diff
changeset
|
199 |
|
13770 | 200 |
>>> u = url('file:///foo/bar/baz') |
201 |
>>> u |
|
202 |
<url scheme: 'file', path: '/foo/bar/baz'> |
|
203 |
>>> str(u) |
|
14313
a389dd285282
util: make str(url) return file:/// for abs paths again
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
14204
diff
changeset
|
204 |
'file:///foo/bar/baz' |
a389dd285282
util: make str(url) return file:/// for abs paths again
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
14204
diff
changeset
|
205 |
|
a389dd285282
util: make str(url) return file:/// for abs paths again
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
14204
diff
changeset
|
206 |
>>> u = url('file:foo/bar/baz') |
a389dd285282
util: make str(url) return file:/// for abs paths again
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
14204
diff
changeset
|
207 |
>>> u |
a389dd285282
util: make str(url) return file:/// for abs paths again
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
14204
diff
changeset
|
208 |
<url scheme: 'file', path: 'foo/bar/baz'> |
a389dd285282
util: make str(url) return file:/// for abs paths again
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
14204
diff
changeset
|
209 |
>>> str(u) |
a389dd285282
util: make str(url) return file:/// for abs paths again
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
14204
diff
changeset
|
210 |
'file:foo/bar/baz' |
13770 | 211 |
""" |
212 |
||
213 |
doctest.testmod(optionflags=doctest.NORMALIZE_WHITESPACE) |
|
214 |
||
13248
00411a4fa1bb
url: fix UnicodeDecodeError on certificate verification error
Yuya Nishihara <yuya@tcha.org>
parents:
12865
diff
changeset
|
215 |
# Unicode (IDN) certname isn't supported |
00411a4fa1bb
url: fix UnicodeDecodeError on certificate verification error
Yuya Nishihara <yuya@tcha.org>
parents:
12865
diff
changeset
|
216 |
check(_verifycert(cert(u'\u4f8b.jp'), 'example.jp'), |
00411a4fa1bb
url: fix UnicodeDecodeError on certificate verification error
Yuya Nishihara <yuya@tcha.org>
parents:
12865
diff
changeset
|
217 |
'IDN in certificate not supported') |