2 # Copyright (C) 2015 - mod_auth_gssapi contributors, see COPYING for license.
10 from string import Template
17 parser = argparse.ArgumentParser(description='Mod Auth GSSAPI Tests Environment')
18 parser.add_argument('--path', default='%s/scratchdir' % os.getcwd(),
19 help="Directory in which tests are run")
21 return vars(parser.parse_args())
24 WRAP_HOSTNAME = "kdc.mag.dev"
25 WRAP_IPADDR = '127.0.0.9'
27 def setup_wrappers(base):
29 pkgcfg = subprocess.Popen(['pkg-config', '--exists', 'socket_wrapper'])
31 if pkgcfg.returncode != 0:
32 raise ValueError('Socket Wrappers not available')
34 pkgcfg = subprocess.Popen(['pkg-config', '--exists', 'nss_wrapper'])
36 if pkgcfg.returncode != 0:
37 raise ValueError('Socket Wrappers not available')
39 wrapdir = os.path.join(base, 'wrapdir')
40 if not os.path.exists(wrapdir):
43 hosts_file = os.path.join(testdir, 'hosts')
44 with open(hosts_file, 'w+') as f:
45 f.write('%s %s' % (WRAP_IPADDR, WRAP_HOSTNAME))
47 wenv = {'LD_PRELOAD': 'libsocket_wrapper.so libnss_wrapper.so',
48 'SOCKET_WRAPPER_DIR': wrapdir,
49 'SOCKET_WRAPPER_DEFAULT_IFACE': '9',
50 'NSS_WRAPPER_HOSTNAME': WRAP_HOSTNAME,
51 'NSS_WRAPPER_HOSTS': hosts_file}
57 KDC_DBNAME = 'db.file'
58 KDC_STASH = 'stash.file'
59 KDC_PASSWORD = 'modauthgssapi'
60 KRB5_CONF_TEMPLATE = '''
62 default_realm = ${TESTREALM}
63 dns_lookup_realm = false
64 dns_lookup_kdc = false
68 default_ccache_name = FILE://${TESTDIR}/ccaches/krb5_ccache_XXXXXX
76 .mag.dev = ${TESTREALM}
77 mag.dev = ${TESTREALM}
81 database_name = ${KDCDIR}/${KDC_DBNAME}
84 KDC_CONF_TEMPLATE = '''
88 restrict_anonymous_to_tgt = true
92 master_key_type = aes256-cts
94 max_renewable_life = 14d
95 acl_file = ${KDCDIR}/kadm5.acl
96 dict_file = /usr/share/dict/words
97 default_principal_flags = +preauth
98 admin_keytab = ${TESTREALM}/kadm5.keytab
99 key_stash_file = ${KDCDIR}/${KDC_STASH}
106 def setup_kdc(testdir, wrapenv):
108 # setup kerberos environment
109 testlog = os.path.join(testdir, 'kerb.log')
110 krb5conf = os.path.join(testdir, 'krb5.conf')
111 kdcconf = os.path.join(testdir, 'kdc.conf')
112 kdcdir = os.path.join(testdir, 'kdc')
113 kdcstash = os.path.join(kdcdir, KDC_STASH)
114 kdcdb = os.path.join(kdcdir, KDC_DBNAME)
115 if os.path.exists(kdcdir):
116 shutil.rmtree(kdcdir)
119 t = Template(KRB5_CONF_TEMPLATE)
120 text = t.substitute({'TESTREALM': TESTREALM,
123 'KDC_DBNAME': KDC_DBNAME,
124 'WRAP_HOSTNAME': WRAP_HOSTNAME})
125 with open(krb5conf, 'w+') as f:
128 t = Template(KDC_CONF_TEMPLATE)
129 text = t.substitute({'TESTREALM': TESTREALM,
132 'KDC_STASH': KDC_STASH})
133 with open(kdcconf, 'w+') as f:
136 kdcenv = {'PATH': '/sbin:/bin:/usr/sbin:/usr/bin',
137 'KRB5_CONFIG': krb5conf,
138 'KRB5_KDC_PROFILE': kdcconf,
139 'KRB5_TRACE': os.path.join(testdir, 'krbtrace.log')}
140 kdcenv.update(wrapenv)
142 with (open(testlog, 'a')) as logfile:
143 ksetup = subprocess.Popen(["kdb5_util", "create", "-s",
144 "-r", TESTREALM, "-P", KDC_PASSWORD],
145 stdout=logfile, stderr=logfile,
146 env=kdcenv, preexec_fn=os.setsid)
148 if ksetup.returncode != 0:
149 raise ValueError('KDC Setup failed')
151 with (open(testlog, 'a')) as logfile:
152 kdcproc = subprocess.Popen(['krb5kdc', '-n'],
153 stdout=logfile, stderr=logfile,
154 env=kdcenv, preexec_fn=os.setsid)
156 return kdcproc, kdcenv
159 def kadmin_local(cmd, env, logfile):
160 ksetup = subprocess.Popen(["kadmin.local", "-q", cmd],
161 stdout=logfile, stderr=logfile,
162 env=env, preexec_fn=os.setsid)
164 if ksetup.returncode != 0:
165 raise ValueError('Kadmin local [%s] failed' % cmd)
170 USR_NAME_2 = "maguser2"
171 USR_PWD_2 = "magpwd2"
172 SVC_KTNAME = "httpd/http.keytab"
173 KEY_TYPE = "aes256-cts-hmac-sha1-96:normal"
176 def setup_keys(tesdir, env):
178 testlog = os.path.join(testdir, 'kerb.log')
180 svc_name = "HTTP/%s" % WRAP_HOSTNAME
181 svc_keytab = os.path.join(testdir, SVC_KTNAME)
182 cmd = "addprinc -randkey -e %s %s" % (KEY_TYPE, svc_name)
183 with (open(testlog, 'a')) as logfile:
184 kadmin_local(cmd, env, logfile)
185 cmd = "ktadd -k %s -e %s %s" % (svc_keytab, KEY_TYPE, svc_name)
186 with (open(testlog, 'a')) as logfile:
187 kadmin_local(cmd, env, logfile)
189 cmd = "addprinc -pw %s -e %s %s" % (USR_PWD, KEY_TYPE, USR_NAME)
190 with (open(testlog, 'a')) as logfile:
191 kadmin_local(cmd, env, logfile)
193 cmd = "addprinc -pw %s -e %s %s" % (USR_PWD_2, KEY_TYPE, USR_NAME_2)
194 with (open(testlog, 'a')) as logfile:
195 kadmin_local(cmd, env, logfile)
197 keys_env = { "KRB5_KTNAME": svc_keytab }
203 def setup_http(testdir, wrapenv):
205 httpdir = os.path.join(testdir, 'httpd')
206 if os.path.exists(httpdir):
207 shutil.rmtree(httpdir)
209 os.mkdir(os.path.join(httpdir, 'conf.d'))
210 os.mkdir(os.path.join(httpdir, 'html'))
211 os.mkdir(os.path.join(httpdir, 'logs'))
212 os.symlink('/etc/httpd/modules', os.path.join(httpdir, 'modules'))
214 shutil.copy('src/.libs/mod_auth_gssapi.so', httpdir)
216 with open('tests/httpd.conf') as f:
217 t = Template(f.read())
218 text = t.substitute({'HTTPROOT': httpdir,
219 'HTTPNAME': WRAP_HOSTNAME,
220 'HTTPADDR': WRAP_IPADDR,
222 config = os.path.join(httpdir, 'httpd.conf')
223 with open(config, 'w+') as f:
226 httpenv = {'PATH': '/sbin:/bin:/usr/sbin:/usr/bin',
227 'MALLOC_CHECK_': '3',
228 'MALLOC_PERTURB_': str(random.randint(0, 32767) % 255 + 1)}
229 httpenv.update(wrapenv)
231 httpproc = subprocess.Popen(['httpd', '-DFOREGROUND', '-f', config],
232 env=httpenv, preexec_fn=os.setsid)
237 def kinit_user(testdir, kdcenv):
238 testlog = os.path.join(testdir, 'kinit.log')
239 ccache = os.path.join(testdir, 'k5ccache')
240 testenv = {'KRB5CCNAME': ccache}
241 testenv.update(kdcenv)
243 with (open(testlog, 'a')) as logfile:
244 kinit = subprocess.Popen(["kinit", USR_NAME],
245 stdin=subprocess.PIPE,
246 stdout=logfile, stderr=logfile,
247 env=testenv, preexec_fn=os.setsid)
248 kinit.communicate('%s\n' % USR_PWD)
250 if kinit.returncode != 0:
251 raise ValueError('kinit failed')
256 def test_spnego_auth(testdir, testenv, testlog):
258 spnegodir = os.path.join(testdir, 'httpd', 'html', 'spnego')
260 shutil.copy('tests/index.html', spnegodir)
262 with (open(testlog, 'a')) as logfile:
263 spnego = subprocess.Popen(["tests/t_spnego.py"],
264 stdout=logfile, stderr=logfile,
265 env=testenv, preexec_fn=os.setsid)
267 if spnego.returncode != 0:
268 sys.stderr.write('SPNEGO: FAILED\n')
270 sys.stderr.write('SPNEGO: SUCCESS\n')
273 def test_basic_auth_krb5(testdir, testenv, testlog):
275 basicdir = os.path.join(testdir, 'httpd', 'html', 'basic_auth_krb5')
277 shutil.copy('tests/index.html', basicdir)
279 with (open(testlog, 'a')) as logfile:
280 basick5 = subprocess.Popen(["tests/t_basic_k5.py"],
281 stdout=logfile, stderr=logfile,
282 env=testenv, preexec_fn=os.setsid)
284 if basick5.returncode != 0:
285 sys.stderr.write('BASIC-AUTH: FAILED\n')
287 sys.stderr.write('BASIC-AUTH: SUCCESS\n')
289 with (open(testlog, 'a')) as logfile:
290 basick5 = subprocess.Popen(["tests/t_basic_k5_two_users.py"],
291 stdout=logfile, stderr=logfile,
292 env=testenv, preexec_fn=os.setsid)
294 if basick5.returncode != 0:
295 sys.stderr.write('BASIC-AUTH Two Users: FAILED\n')
297 sys.stderr.write('BASIC-AUTH Two Users: SUCCESS\n')
300 if __name__ == '__main__':
304 testdir = args['path']
305 if os.path.exists(testdir):
306 shutil.rmtree(testdir)
311 testlog = os.path.join(testdir, 'tests.log')
314 wrapenv = setup_wrappers(testdir)
316 kdcproc, kdcenv = setup_kdc(testdir, wrapenv)
317 processes['KDC(%d)' % kdcproc.pid] = kdcproc
319 httpproc = setup_http(testdir, kdcenv)
320 processes['HTTPD(%d)' % httpproc.pid] = httpproc
322 keysenv = setup_keys(testdir, kdcenv)
323 testenv = kinit_user(testdir, kdcenv)
325 test_spnego_auth(testdir, testenv, testlog)
328 testenv = {'MAG_USER_NAME': USR_NAME,
329 'MAG_USER_PASSWORD': USR_PWD,
330 'MAG_USER_NAME_2': USR_NAME_2,
331 'MAG_USER_PASSWORD_2': USR_PWD_2}
332 testenv.update(kdcenv)
333 test_basic_auth_krb5(testdir, testenv, testlog)
336 with (open(testlog, 'a')) as logfile:
337 for name in processes:
338 logfile.write("Killing %s\n" % name)
339 os.killpg(processes[name].pid, signal.SIGTERM)