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 WRAP_PROXY_PORT = '8080'
29 def setup_wrappers(base):
31 pkgcfg = subprocess.Popen(['pkg-config', '--exists', 'socket_wrapper'])
33 if pkgcfg.returncode != 0:
34 raise ValueError('Socket Wrappers not available')
36 pkgcfg = subprocess.Popen(['pkg-config', '--exists', 'nss_wrapper'])
38 if pkgcfg.returncode != 0:
39 raise ValueError('Socket Wrappers not available')
41 wrapdir = os.path.join(base, 'wrapdir')
42 if not os.path.exists(wrapdir):
45 hosts_file = os.path.join(testdir, 'hosts')
46 with open(hosts_file, 'w+') as f:
47 f.write('%s %s' % (WRAP_IPADDR, WRAP_HOSTNAME))
49 wenv = {'LD_PRELOAD': 'libsocket_wrapper.so libnss_wrapper.so',
50 'SOCKET_WRAPPER_DIR': wrapdir,
51 'SOCKET_WRAPPER_DEFAULT_IFACE': '9',
52 'WRAP_PROXY_PORT': WRAP_PROXY_PORT,
53 'NSS_WRAPPER_HOSTNAME': WRAP_HOSTNAME,
54 'NSS_WRAPPER_HOSTS': hosts_file}
60 KDC_DBNAME = 'db.file'
61 KDC_STASH = 'stash.file'
62 KDC_PASSWORD = 'modauthgssapi'
63 KRB5_CONF_TEMPLATE = '''
65 default_realm = ${TESTREALM}
66 dns_lookup_realm = false
67 dns_lookup_kdc = false
71 default_ccache_name = FILE://${TESTDIR}/ccaches/krb5_ccache_XXXXXX
79 .mag.dev = ${TESTREALM}
80 mag.dev = ${TESTREALM}
84 database_name = ${KDCDIR}/${KDC_DBNAME}
87 KDC_CONF_TEMPLATE = '''
91 restrict_anonymous_to_tgt = true
95 master_key_type = aes256-cts
97 max_renewable_life = 14d
98 acl_file = ${KDCDIR}/kadm5.acl
99 dict_file = /usr/share/dict/words
100 default_principal_flags = +preauth
101 admin_keytab = ${TESTREALM}/kadm5.keytab
102 key_stash_file = ${KDCDIR}/${KDC_STASH}
109 def setup_kdc(testdir, wrapenv):
111 # setup kerberos environment
112 testlog = os.path.join(testdir, 'kerb.log')
113 krb5conf = os.path.join(testdir, 'krb5.conf')
114 kdcconf = os.path.join(testdir, 'kdc.conf')
115 kdcdir = os.path.join(testdir, 'kdc')
116 kdcstash = os.path.join(kdcdir, KDC_STASH)
117 kdcdb = os.path.join(kdcdir, KDC_DBNAME)
118 if os.path.exists(kdcdir):
119 shutil.rmtree(kdcdir)
122 t = Template(KRB5_CONF_TEMPLATE)
123 text = t.substitute({'TESTREALM': TESTREALM,
126 'KDC_DBNAME': KDC_DBNAME,
127 'WRAP_HOSTNAME': WRAP_HOSTNAME})
128 with open(krb5conf, 'w+') as f:
131 t = Template(KDC_CONF_TEMPLATE)
132 text = t.substitute({'TESTREALM': TESTREALM,
135 'KDC_STASH': KDC_STASH})
136 with open(kdcconf, 'w+') as f:
139 kdcenv = {'PATH': '/sbin:/bin:/usr/sbin:/usr/bin',
140 'KRB5_CONFIG': krb5conf,
141 'KRB5_KDC_PROFILE': kdcconf,
142 'KRB5_TRACE': os.path.join(testdir, 'krbtrace.log')}
143 kdcenv.update(wrapenv)
145 with (open(testlog, 'a')) as logfile:
146 ksetup = subprocess.Popen(["kdb5_util", "create", "-s",
147 "-r", TESTREALM, "-P", KDC_PASSWORD],
148 stdout=logfile, stderr=logfile,
149 env=kdcenv, preexec_fn=os.setsid)
151 if ksetup.returncode != 0:
152 raise ValueError('KDC Setup failed')
154 with (open(testlog, 'a')) as logfile:
155 kdcproc = subprocess.Popen(['krb5kdc', '-n'],
156 stdout=logfile, stderr=logfile,
157 env=kdcenv, preexec_fn=os.setsid)
159 return kdcproc, kdcenv
162 def kadmin_local(cmd, env, logfile):
163 ksetup = subprocess.Popen(["kadmin.local", "-q", cmd],
164 stdout=logfile, stderr=logfile,
165 env=env, preexec_fn=os.setsid)
167 if ksetup.returncode != 0:
168 raise ValueError('Kadmin local [%s] failed' % cmd)
173 USR_NAME_2 = "maguser2"
174 USR_PWD_2 = "magpwd2"
175 SVC_KTNAME = "httpd/http.keytab"
176 KEY_TYPE = "aes256-cts-hmac-sha1-96:normal"
179 def setup_keys(tesdir, env):
181 testlog = os.path.join(testdir, 'kerb.log')
183 svc_name = "HTTP/%s" % WRAP_HOSTNAME
184 svc_keytab = os.path.join(testdir, SVC_KTNAME)
185 cmd = "addprinc -randkey -e %s %s" % (KEY_TYPE, svc_name)
186 with (open(testlog, 'a')) as logfile:
187 kadmin_local(cmd, env, logfile)
188 cmd = "ktadd -k %s -e %s %s" % (svc_keytab, KEY_TYPE, svc_name)
189 with (open(testlog, 'a')) as logfile:
190 kadmin_local(cmd, env, logfile)
192 cmd = "addprinc -pw %s -e %s %s" % (USR_PWD, KEY_TYPE, USR_NAME)
193 with (open(testlog, 'a')) as logfile:
194 kadmin_local(cmd, env, logfile)
196 cmd = "addprinc -pw %s -e %s %s" % (USR_PWD_2, KEY_TYPE, USR_NAME_2)
197 with (open(testlog, 'a')) as logfile:
198 kadmin_local(cmd, env, logfile)
200 keys_env = { "KRB5_KTNAME": svc_keytab }
206 def setup_http(testdir, wrapenv):
208 httpdir = os.path.join(testdir, 'httpd')
209 if os.path.exists(httpdir):
210 shutil.rmtree(httpdir)
212 os.mkdir(os.path.join(httpdir, 'conf.d'))
213 os.mkdir(os.path.join(httpdir, 'html'))
214 os.mkdir(os.path.join(httpdir, 'logs'))
215 os.symlink('/etc/httpd/modules', os.path.join(httpdir, 'modules'))
217 shutil.copy('src/.libs/mod_auth_gssapi.so', httpdir)
219 with open('tests/httpd.conf') as f:
220 t = Template(f.read())
221 text = t.substitute({'HTTPROOT': httpdir,
222 'HTTPNAME': WRAP_HOSTNAME,
223 'HTTPADDR': WRAP_IPADDR,
224 'PROXYPORT': WRAP_PROXY_PORT,
225 'HTTPPORT': WRAP_HTTP_PORT})
226 config = os.path.join(httpdir, 'httpd.conf')
227 with open(config, 'w+') as f:
230 httpenv = {'PATH': '/sbin:/bin:/usr/sbin:/usr/bin',
231 'MALLOC_CHECK_': '3',
232 'MALLOC_PERTURB_': str(random.randint(0, 32767) % 255 + 1)}
233 httpenv.update(wrapenv)
235 httpproc = subprocess.Popen(['httpd', '-DFOREGROUND', '-f', config],
236 env=httpenv, preexec_fn=os.setsid)
241 def kinit_user(testdir, kdcenv):
242 testlog = os.path.join(testdir, 'kinit.log')
243 ccache = os.path.join(testdir, 'k5ccache')
244 testenv = {'KRB5CCNAME': ccache}
245 testenv.update(kdcenv)
247 with (open(testlog, 'a')) as logfile:
248 kinit = subprocess.Popen(["kinit", USR_NAME],
249 stdin=subprocess.PIPE,
250 stdout=logfile, stderr=logfile,
251 env=testenv, preexec_fn=os.setsid)
252 kinit.communicate('%s\n' % USR_PWD)
254 if kinit.returncode != 0:
255 raise ValueError('kinit failed')
260 def test_spnego_auth(testdir, testenv, testlog):
262 spnegodir = os.path.join(testdir, 'httpd', 'html', 'spnego')
264 shutil.copy('tests/index.html', spnegodir)
266 with (open(testlog, 'a')) as logfile:
267 spnego = subprocess.Popen(["tests/t_spnego.py"],
268 stdout=logfile, stderr=logfile,
269 env=testenv, preexec_fn=os.setsid)
271 if spnego.returncode != 0:
272 sys.stderr.write('SPNEGO: FAILED\n')
274 sys.stderr.write('SPNEGO: SUCCESS\n')
277 def test_basic_auth_krb5(testdir, testenv, testlog):
279 basicdir = os.path.join(testdir, 'httpd', 'html', 'basic_auth_krb5')
281 shutil.copy('tests/index.html', basicdir)
283 with (open(testlog, 'a')) as logfile:
284 basick5 = subprocess.Popen(["tests/t_basic_k5.py"],
285 stdout=logfile, stderr=logfile,
286 env=testenv, preexec_fn=os.setsid)
288 if basick5.returncode != 0:
289 sys.stderr.write('BASIC-AUTH: FAILED\n')
291 sys.stderr.write('BASIC-AUTH: SUCCESS\n')
293 with (open(testlog, 'a')) as logfile:
294 basick5 = subprocess.Popen(["tests/t_basic_k5_two_users.py"],
295 stdout=logfile, stderr=logfile,
296 env=testenv, preexec_fn=os.setsid)
298 if basick5.returncode != 0:
299 sys.stderr.write('BASIC-AUTH Two Users: FAILED\n')
301 sys.stderr.write('BASIC-AUTH Two Users: SUCCESS\n')
303 with (open(testlog, 'a')) as logfile:
304 basick5 = subprocess.Popen(["tests/t_basic_proxy.py"],
305 stdout=logfile, stderr=logfile,
306 env=testenv, preexec_fn=os.setsid)
308 if basick5.returncode != 0:
309 sys.stderr.write('BASIC Proxy Auth: FAILED\n')
311 sys.stderr.write('BASIC Proxy Auth: SUCCESS\n')
314 if __name__ == '__main__':
318 testdir = args['path']
319 if os.path.exists(testdir):
320 shutil.rmtree(testdir)
325 testlog = os.path.join(testdir, 'tests.log')
328 wrapenv = setup_wrappers(testdir)
330 kdcproc, kdcenv = setup_kdc(testdir, wrapenv)
331 processes['KDC(%d)' % kdcproc.pid] = kdcproc
333 httpproc = setup_http(testdir, kdcenv)
334 processes['HTTPD(%d)' % httpproc.pid] = httpproc
336 keysenv = setup_keys(testdir, kdcenv)
337 testenv = kinit_user(testdir, kdcenv)
339 test_spnego_auth(testdir, testenv, testlog)
342 testenv = {'MAG_USER_NAME': USR_NAME,
343 'MAG_USER_PASSWORD': USR_PWD,
344 'MAG_USER_NAME_2': USR_NAME_2,
345 'MAG_USER_PASSWORD_2': USR_PWD_2}
346 testenv.update(kdcenv)
347 test_basic_auth_krb5(testdir, testenv, testlog)
350 with (open(testlog, 'a')) as logfile:
351 for name in processes:
352 logfile.write("Killing %s\n" % name)
353 os.killpg(processes[name].pid, signal.SIGTERM)