xref: /freebsd/crypto/krb5/src/tests/t_proxy.py (revision 7f2fe78b9dd5f51c821d771b63d2e096f6fd49e9)
1from k5test import *
2
3# Skip this test if we're missing proxy functionality or parts of the proxy.
4if runenv.tls_impl == 'no':
5    skip_rest('HTTP proxy tests', 'TLS build support not enabled')
6try:
7    import kdcproxy
8except:
9    skip_rest('HTTP proxy tests', 'Python kdcproxy module not found')
10
11# Construct a krb5.conf fragment configuring the client to use a local proxy
12# server.
13proxycerts = os.path.join(srctop, 'tests', 'proxy-certs')
14proxysubjectpem = os.path.join(proxycerts, 'proxy-subject.pem')
15proxysanpem = os.path.join(proxycerts, 'proxy-san.pem')
16proxyidealpem = os.path.join(proxycerts, 'proxy-ideal.pem')
17proxywrongpem = os.path.join(proxycerts, 'proxy-no-match.pem')
18proxybadpem = os.path.join(proxycerts, 'proxy-badsig.pem')
19proxyca = os.path.join(proxycerts, 'ca.pem')
20proxyurl = 'https://localhost:$port5/KdcProxy'
21proxyurlupcase = 'https://LocalHost:$port5/KdcProxy'
22proxyurl4 = 'https://127.0.0.1:$port5/KdcProxy'
23proxyurl6 = 'https://[::1]:$port5/KdcProxy'
24
25unanchored_krb5_conf = {'realms': {'$realm': {
26                        'kdc': proxyurl,
27                        'kpasswd_server': proxyurl}}}
28anchored_name_krb5_conf = {'realms': {'$realm': {
29                           'kdc': proxyurl,
30                           'kpasswd_server': proxyurl,
31                           'http_anchors': 'FILE:%s' % proxyca}}}
32anchored_upcasename_krb5_conf = {'realms': {'$realm': {
33                                 'kdc': proxyurlupcase,
34                                 'kpasswd_server': proxyurlupcase,
35                                 'http_anchors': 'FILE:%s' % proxyca}}}
36anchored_kadmin_krb5_conf = {'realms': {'$realm': {
37                             'kdc': proxyurl,
38                             'admin_server': proxyurl,
39                             'http_anchors': 'FILE:%s' % proxyca}}}
40anchored_ipv4_krb5_conf = {'realms': {'$realm': {
41                           'kdc': proxyurl4,
42                           'kpasswd_server': proxyurl4,
43                           'http_anchors': 'FILE:%s' % proxyca}}}
44kpasswd_input = (password('user') + '\n' + password('user') + '\n' +
45                 password('user') + '\n')
46
47def start_proxy(realm, keycertpem):
48    proxy_conf_path = os.path.join(realm.testdir, 'kdcproxy.conf')
49    proxy_exec_path = os.path.join(srctop, 'util', 'wsgiref-kdcproxy.py')
50    conf = open(proxy_conf_path, 'w')
51    conf.write('[%s]\n' % realm.realm)
52    conf.write('kerberos = kerberos://localhost:%d\n' % realm.portbase)
53    conf.write('kpasswd = kpasswd://localhost:%d\n' % (realm.portbase + 2))
54    conf.close()
55    realm.env['KDCPROXY_CONFIG'] = proxy_conf_path
56    cmd = [sys.executable, proxy_exec_path, str(realm.server_port()),
57           keycertpem]
58    return realm.start_server(cmd, sentinel='proxy server ready')
59
60# Fail: untrusted issuer and hostname doesn't match.
61mark('untrusted issuer, hostname mismatch')
62output("running pass 1: issuer not trusted and hostname doesn't match\n")
63realm = K5Realm(krb5_conf=unanchored_krb5_conf, get_creds=False,
64                create_host=False)
65proxy = start_proxy(realm, proxywrongpem)
66realm.kinit(realm.user_princ, password=password('user'), expected_code=1)
67stop_daemon(proxy)
68realm.stop()
69
70# Fail: untrusted issuer, host name matches subject.
71mark('untrusted issuer, hostname subject match')
72output("running pass 2: subject matches, issuer not trusted\n")
73realm = K5Realm(krb5_conf=unanchored_krb5_conf, get_creds=False,
74                create_host=False)
75proxy = start_proxy(realm, proxysubjectpem)
76realm.kinit(realm.user_princ, password=password('user'), expected_code=1)
77stop_daemon(proxy)
78realm.stop()
79
80# Fail: untrusted issuer, host name matches subjectAltName.
81mark('untrusted issuer, hostname SAN match')
82output("running pass 3: subjectAltName matches, issuer not trusted\n")
83realm = K5Realm(krb5_conf=unanchored_krb5_conf, get_creds=False,
84                create_host=False)
85proxy = start_proxy(realm, proxysanpem)
86realm.kinit(realm.user_princ, password=password('user'), expected_code=1)
87stop_daemon(proxy)
88realm.stop()
89
90# Fail: untrusted issuer, certificate signature is bad.
91mark('untrusted issuer, bad signature')
92output("running pass 4: subject matches, issuer not trusted\n")
93realm = K5Realm(krb5_conf=unanchored_krb5_conf, get_creds=False,
94                create_host=False)
95proxy = start_proxy(realm, proxybadpem)
96realm.kinit(realm.user_princ, password=password('user'), expected_code=1)
97stop_daemon(proxy)
98realm.stop()
99
100# Fail: trusted issuer but hostname doesn't match.
101mark('trusted issuer, hostname mismatch')
102output("running pass 5: issuer trusted but hostname doesn't match\n")
103realm = K5Realm(krb5_conf=anchored_name_krb5_conf, get_creds=False,
104                create_host=False)
105proxy = start_proxy(realm, proxywrongpem)
106realm.kinit(realm.user_princ, password=password('user'), expected_code=1)
107stop_daemon(proxy)
108realm.stop()
109
110# Succeed: trusted issuer and host name matches subject.
111mark('trusted issuer, hostname subject match')
112output("running pass 6: issuer trusted, subject matches\n")
113realm = K5Realm(krb5_conf=anchored_name_krb5_conf, start_kadmind=True,
114                get_creds=False)
115proxy = start_proxy(realm, proxysubjectpem)
116realm.kinit(realm.user_princ, password=password('user'))
117realm.run([kvno, realm.host_princ])
118realm.run([kpasswd, realm.user_princ], input=kpasswd_input)
119stop_daemon(proxy)
120realm.stop()
121
122# Succeed: trusted issuer and host name matches subjectAltName.
123mark('trusted issuer, hostname SAN match')
124output("running pass 7: issuer trusted, subjectAltName matches\n")
125realm = K5Realm(krb5_conf=anchored_name_krb5_conf, start_kadmind=True,
126                get_creds=False)
127proxy = start_proxy(realm, proxysanpem)
128realm.kinit(realm.user_princ, password=password('user'))
129realm.run([kvno, realm.host_princ])
130realm.run([kpasswd, realm.user_princ], input=kpasswd_input)
131stop_daemon(proxy)
132realm.stop()
133
134# Fail: certificate signature is bad.
135mark('bad signature')
136output("running pass 8: issuer trusted and subjectAltName matches, sig bad\n")
137realm = K5Realm(krb5_conf=anchored_name_krb5_conf,
138                get_creds=False,
139		                create_host=False)
140proxy = start_proxy(realm, proxybadpem)
141realm.kinit(realm.user_princ, password=password('user'), expected_code=1)
142stop_daemon(proxy)
143realm.stop()
144
145# Fail: trusted issuer but IP doesn't match.
146mark('trusted issuer, IP mismatch')
147output("running pass 9: issuer trusted but no name matches IP\n")
148realm = K5Realm(krb5_conf=anchored_ipv4_krb5_conf, get_creds=False,
149                create_host=False)
150proxy = start_proxy(realm, proxywrongpem)
151realm.kinit(realm.user_princ, password=password('user'), expected_code=1)
152stop_daemon(proxy)
153realm.stop()
154
155# Fail: trusted issuer, but subject does not match.
156mark('trusted issuer, IP mismatch (hostname in subject)')
157output("running pass 10: issuer trusted, but subject does not match IP\n")
158realm = K5Realm(krb5_conf=anchored_ipv4_krb5_conf, get_creds=False,
159                create_host=False)
160proxy = start_proxy(realm, proxysubjectpem)
161realm.kinit(realm.user_princ, password=password('user'), expected_code=1)
162stop_daemon(proxy)
163realm.stop()
164
165# Succeed: trusted issuer and host name matches subjectAltName.
166mark('trusted issuer, IP SAN match')
167output("running pass 11: issuer trusted, subjectAltName matches IP\n")
168realm = K5Realm(krb5_conf=anchored_ipv4_krb5_conf, start_kadmind=True,
169                get_creds=False)
170proxy = start_proxy(realm, proxysanpem)
171realm.kinit(realm.user_princ, password=password('user'))
172realm.run([kvno, realm.host_princ])
173realm.run([kpasswd, realm.user_princ], input=kpasswd_input)
174stop_daemon(proxy)
175realm.stop()
176
177# Fail: certificate signature is bad.
178mark('bad signature (IP hostname)')
179output("running pass 12: issuer trusted, names don't match, signature bad\n")
180realm = K5Realm(krb5_conf=anchored_ipv4_krb5_conf, get_creds=False,
181                create_host=False)
182proxy = start_proxy(realm, proxybadpem)
183realm.kinit(realm.user_princ, password=password('user'), expected_code=1)
184stop_daemon(proxy)
185realm.stop()
186
187# Succeed: trusted issuer and host name matches subject, using kadmin
188# configuration to find kpasswdd.
189mark('trusted issuer, hostname subject match (kadmin)')
190output("running pass 13: issuer trusted, subject matches\n")
191realm = K5Realm(krb5_conf=anchored_kadmin_krb5_conf, start_kadmind=True,
192                get_creds=False, create_host=False)
193proxy = start_proxy(realm, proxysubjectpem)
194realm.run([kpasswd, realm.user_princ], input=kpasswd_input)
195stop_daemon(proxy)
196realm.stop()
197
198# Succeed: trusted issuer and host name matches subjectAltName, using
199# kadmin configuration to find kpasswdd.
200mark('trusted issuer, hostname SAN match (kadmin)')
201output("running pass 14: issuer trusted, subjectAltName matches\n")
202realm = K5Realm(krb5_conf=anchored_kadmin_krb5_conf, start_kadmind=True,
203                get_creds=False, create_host=False)
204proxy = start_proxy(realm, proxysanpem)
205realm.run([kpasswd, realm.user_princ], input=kpasswd_input)
206stop_daemon(proxy)
207realm.stop()
208
209# Succeed: trusted issuer and host name matches subjectAltName (give or take
210# case).
211mark('trusted issuer, hostname SAN case-insensitive match')
212output("running pass 15: issuer trusted, subjectAltName case-insensitive\n")
213realm = K5Realm(krb5_conf=anchored_upcasename_krb5_conf, start_kadmind=True,
214                get_creds=False, create_host=False)
215proxy = start_proxy(realm, proxysanpem)
216realm.run([kpasswd, realm.user_princ], input=kpasswd_input)
217stop_daemon(proxy)
218realm.stop()
219
220success('MS-KKDCP proxy')
221