|
Packit |
fd8b60 |
# Copyright (C) 2010 by the Massachusetts Institute of Technology.
|
|
Packit |
fd8b60 |
# All rights reserved.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
# Export of this software from the United States of America may
|
|
Packit |
fd8b60 |
# require a specific license from the United States Government.
|
|
Packit |
fd8b60 |
# It is the responsibility of any person or organization contemplating
|
|
Packit |
fd8b60 |
# export to obtain such a license before exporting.
|
|
Packit |
fd8b60 |
#
|
|
Packit |
fd8b60 |
# WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
|
|
Packit |
fd8b60 |
# distribute this software and its documentation for any purpose and
|
|
Packit |
fd8b60 |
# without fee is hereby granted, provided that the above copyright
|
|
Packit |
fd8b60 |
# notice appear in all copies and that both that copyright notice and
|
|
Packit |
fd8b60 |
# this permission notice appear in supporting documentation, and that
|
|
Packit |
fd8b60 |
# the name of M.I.T. not be used in advertising or publicity pertaining
|
|
Packit |
fd8b60 |
# to distribution of the software without specific, written prior
|
|
Packit |
fd8b60 |
# permission. Furthermore if you modify this software you must label
|
|
Packit |
fd8b60 |
# your software as modified software and not distribute it in such a
|
|
Packit |
fd8b60 |
# fashion that it might be confused with the original M.I.T. software.
|
|
Packit |
fd8b60 |
# M.I.T. makes no representations about the suitability of
|
|
Packit |
fd8b60 |
# this software for any purpose. It is provided "as is" without express
|
|
Packit |
fd8b60 |
# or implied warranty.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
"""A module for krb5 test scripts
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
To run test scripts during "make check" (if Python 2.5 or later is
|
|
Packit |
fd8b60 |
available), add rules like the following to Makefile.in:
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
check-pytests::
|
|
Packit |
fd8b60 |
$(RUNPYTEST) $(srcdir)/t_testname.py $(PYTESTFLAGS)
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
A sample test script:
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
from k5test import *
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
# Run a test program under a variety of configurations:
|
|
Packit |
fd8b60 |
for realm in multipass_realms():
|
|
Packit |
fd8b60 |
realm.run(['./testprog', 'arg'])
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
# Run a test server and client under just the default configuration:
|
|
Packit |
fd8b60 |
realm = K5Realm()
|
|
Packit |
fd8b60 |
realm.start_server(['./serverprog'], 'starting...')
|
|
Packit |
fd8b60 |
realm.run(['./clientprog', realm.host_princ])
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
# Inform framework that tests completed successfully.
|
|
Packit |
fd8b60 |
success('World peace and cure for cancer')
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
By default, the realm will have:
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* The name KRBTEST.COM
|
|
Packit |
fd8b60 |
* Listener ports starting at 61000
|
|
Packit |
fd8b60 |
* krb5.conf and kdc.conf files
|
|
Packit |
fd8b60 |
* A fresh DB2 KDB
|
|
Packit |
fd8b60 |
* Running krb5kdc (but not kadmind)
|
|
Packit |
fd8b60 |
* Principals named realm.user_princ and realm.admin_princ; call
|
|
Packit |
fd8b60 |
password('user') and password('admin') to get the password
|
|
Packit |
fd8b60 |
* Credentials for realm.user_princ in realm.ccache
|
|
Packit |
fd8b60 |
* Admin rights for realm.admin_princ in the kadmind acl file
|
|
Packit |
fd8b60 |
* A host principal named realm.host_princ with a random key
|
|
Packit |
fd8b60 |
* A keytab for the host principal in realm.keytab
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
The realm's behaviour can be modified with the following constructor
|
|
Packit |
fd8b60 |
keyword arguments:
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* realm='realmname': Override the realm name
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* portbase=NNN: Override the listener port base; currently three ports are
|
|
Packit |
fd8b60 |
used
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* testdir='dirname': Override the storage area for the realm's files
|
|
Packit |
fd8b60 |
(path may be specified relative to the current working dir)
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* krb5_conf={ ... }: krb5.conf options, expressed as a nested
|
|
Packit |
fd8b60 |
dictionary, to be merged with the default krb5.conf settings. A key
|
|
Packit |
fd8b60 |
may be mapped to None to delete a setting from the defaults. A key
|
|
Packit |
fd8b60 |
may be mapped to a list in order to create multiple settings for the
|
|
Packit |
fd8b60 |
same variable name. Keys and values undergo the following template
|
|
Packit |
fd8b60 |
substitutions:
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
- $realm: The realm name
|
|
Packit |
fd8b60 |
- $testdir: The realm storage directory (absolute path)
|
|
Packit |
fd8b60 |
- $buildtop: The root of the build directory
|
|
Packit |
fd8b60 |
- $srctop: The root of the source directory
|
|
Packit |
fd8b60 |
- $plugins: The plugin directory in the build tree
|
|
Packit |
fd8b60 |
- $hostname: The FQDN of the host
|
|
Packit |
fd8b60 |
- $port0: The first listener port (portbase)
|
|
Packit |
fd8b60 |
- ...
|
|
Packit |
fd8b60 |
- $port9: The tenth listener port (portbase + 9)
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
When choosing ports, note the following:
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
- port0 is used in the default krb5.conf for the KDC
|
|
Packit |
fd8b60 |
- port1 is used in the default krb5.conf for kadmind
|
|
Packit |
fd8b60 |
- port2 is used in the default krb5.conf for kpasswd
|
|
Packit |
fd8b60 |
- port3 is used in the default krb5.conf for kpropd
|
|
Packit |
fd8b60 |
- port4 is used in the default krb5.conf for iprop (in kadmind)
|
|
Packit |
fd8b60 |
- port5 is the return value of realm.server_port()
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* kdc_conf={...}: kdc.conf options, expressed as a nested dictionary,
|
|
Packit |
fd8b60 |
to be merged with the default kdc.conf settings. The same
|
|
Packit |
fd8b60 |
conventions and substitutions for krb5_conf apply.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* create_kdb=False: Don't create a KDB. Implicitly disables all of
|
|
Packit |
fd8b60 |
the other options since they all require a KDB.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* krbtgt_keysalt='enctype:salttype': After creating the KDB,
|
|
Packit |
fd8b60 |
regenerate the krbtgt key using the specified key/salt combination,
|
|
Packit |
fd8b60 |
using a kadmin.local cpw query.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* create_user=False: Don't create the user principal. Implies
|
|
Packit |
fd8b60 |
get_creds=False.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* create_host=False: Don't create the host principal or the associated
|
|
Packit |
fd8b60 |
keytab.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* start_kdc=False: Don't start the KDC. Implies get_creds=False.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* start_kadmind=True: Start kadmind.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* get_creds=False: Don't get user credentials.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* bdb_only=True: Use the DB2 KDB module even if K5TEST_LMDB is set in
|
|
Packit |
fd8b60 |
the environment.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
Scripts may use the following functions and variables:
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* fail(message): Display message (plus leading marker and trailing
|
|
Packit |
fd8b60 |
newline) and explanatory messages about debugging.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* success(message): Indicate that the test script has completed
|
|
Packit |
fd8b60 |
successfully. Suppresses the display of explanatory debugging
|
|
Packit |
fd8b60 |
messages in the on-exit handler. message should briefly summarize
|
|
Packit |
fd8b60 |
the operations tested; it will only be displayed (with leading
|
|
Packit |
fd8b60 |
marker and trailing newline) if the script is running verbosely.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* skipped(whatmsg, whymsg): Indicate that some tests were skipped.
|
|
Packit |
fd8b60 |
whatmsg should concisely say what was skipped (e.g. "LDAP KDB
|
|
Packit |
fd8b60 |
tests") and whymsg should give the reason (e.g. "because LDAP module
|
|
Packit |
fd8b60 |
not built").
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* skip_rest(message): Indicate that some tests were skipped, then exit
|
|
Packit |
fd8b60 |
the current script.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* output(message, force_verbose=False): Place message (without any
|
|
Packit |
fd8b60 |
added newline) in testlog, and write it to stdout if running
|
|
Packit |
fd8b60 |
verbosely.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* mark(message): Place a divider message in the test output, to make
|
|
Packit |
fd8b60 |
it easier to determine what part of the test script a command
|
|
Packit |
fd8b60 |
invocation belongs to. The last mark message will also be displayed
|
|
Packit |
fd8b60 |
if a command invocation fails. Do not include a newline in message.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* which(progname): Return the location of progname in the executable
|
|
Packit |
fd8b60 |
path, or None if it is not found.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* password(name): Return a weakly random password based on name. The
|
|
Packit |
fd8b60 |
password will be consistent across calls with the same name.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* stop_daemon(proc): Stop a daemon process started with
|
|
Packit |
fd8b60 |
realm.start_server() or realm.start_in_inetd(). Only necessary if
|
|
Packit |
fd8b60 |
the port needs to be reused; daemon processes will be stopped
|
|
Packit |
fd8b60 |
automatically when the script exits.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* multipass_realms(**keywords): This is an iterator function. Yields
|
|
Packit |
fd8b60 |
a realm for each of the standard test passes, each of which alters
|
|
Packit |
fd8b60 |
the default configuration in some way to exercise different parts of
|
|
Packit |
fd8b60 |
the krb5 code base. keywords may contain any K5Realm initializer
|
|
Packit |
fd8b60 |
keyword with the exception of krbtgt_keysalt, which will not be
|
|
Packit |
fd8b60 |
honored. If keywords contains krb5_conf and/or kdc_conf fragments,
|
|
Packit |
fd8b60 |
they will be merged with the default and per-pass specifications.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* multidb_realms(**keywords): Yields a realm for multiple DB modules.
|
|
Packit |
fd8b60 |
Currently DB2 and LMDB are included. Ideally LDAP would be
|
|
Packit |
fd8b60 |
included, but setting up a test LDAP server currently requires a
|
|
Packit |
fd8b60 |
one-second delay, so all LDAP tests are currently confined to
|
|
Packit |
fd8b60 |
t_kdb.py. keywords may contain any K5Realm initializer.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* cross_realms(num, xtgts=None, args=None, **keywords): This function
|
|
Packit |
fd8b60 |
returns a list of num realms, where each realm's configuration knows
|
|
Packit |
fd8b60 |
how to contact all of the realms. By default, each realm will
|
|
Packit |
fd8b60 |
contain cross TGTs in both directions for all other realms; this
|
|
Packit |
fd8b60 |
default may be overridden by specifying a collection of tuples in
|
|
Packit |
fd8b60 |
the xtgts parameter, where each tuple is a pair of zero-based realm
|
|
Packit |
fd8b60 |
indexes, indicating that the first realm can authenticate to the
|
|
Packit |
fd8b60 |
second (i.e. krbtgt/secondrealm@firstrealm exists in both realm's
|
|
Packit |
fd8b60 |
databases). If args is given, it should be a list of keyword
|
|
Packit |
fd8b60 |
arguments specific to each realm; these will be merged with the
|
|
Packit |
fd8b60 |
global keyword arguments passed to cross_realms, with specific
|
|
Packit |
fd8b60 |
arguments taking priority.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* buildtop: The top of the build directory (absolute path).
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* srctop: The top of the source directory (absolute path).
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* plugins: The plugin directory in the build tree (absolute path).
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* hostname: This machine's fully-qualified domain name.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* null_input: A file opened to read /dev/null.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* args: Positional arguments left over after flags are processed.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* runenv: The contents of $srctop/runenv.py, containing a dictionary
|
|
Packit |
fd8b60 |
'env' which specifies additional variables to be added to the realm
|
|
Packit |
fd8b60 |
environment, and a variable 'tls_impl', which indicates which TLS
|
|
Packit |
fd8b60 |
implementation (if any) is being used by libkrb5's support for
|
|
Packit |
fd8b60 |
contacting KDCs and kpasswd servers over HTTPS.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* verbose: Whether the script is running verbosely.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* testpass: The command-line test pass argument. The script does not
|
|
Packit |
fd8b60 |
need to examine this argument in most cases; it will be honored in
|
|
Packit |
fd8b60 |
multipass_realms().
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* Pathname variables for programs within the build directory:
|
|
Packit |
fd8b60 |
- krb5kdc
|
|
Packit |
fd8b60 |
- kadmind
|
|
Packit |
fd8b60 |
- kadmin
|
|
Packit |
fd8b60 |
- kadminl (kadmin.local)
|
|
Packit |
fd8b60 |
- kdb5_ldap_util
|
|
Packit |
fd8b60 |
- kdb5_util
|
|
Packit |
fd8b60 |
- ktutil
|
|
Packit |
fd8b60 |
- kinit
|
|
Packit |
fd8b60 |
- klist
|
|
Packit |
fd8b60 |
- kswitch
|
|
Packit |
fd8b60 |
- kvno
|
|
Packit |
fd8b60 |
- kdestroy
|
|
Packit |
fd8b60 |
- kpasswd
|
|
Packit |
fd8b60 |
- t_inetd
|
|
Packit |
fd8b60 |
- kproplog
|
|
Packit |
fd8b60 |
- kpropd
|
|
Packit |
fd8b60 |
- kprop
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
Scripts may use the following realm methods and attributes:
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* realm.run(args, env=None, **keywords): Run a command in a specified
|
|
Packit |
fd8b60 |
environment (or the realm's environment by default), obeying the
|
|
Packit |
fd8b60 |
command-line debugging options. Fail if the command does not return
|
|
Packit |
fd8b60 |
0. Log the command output appropriately, and return it as a single
|
|
Packit |
fd8b60 |
multi-line string. Keyword arguments can contain input='string' to
|
|
Packit |
fd8b60 |
send an input string to the command, expected_code=N to expect a
|
|
Packit |
fd8b60 |
return code other than 0, expected_msg=MSG to expect a substring in
|
|
Packit |
fd8b60 |
the command output, and expected_trace=('a', 'b', ...) to expect an
|
|
Packit |
fd8b60 |
ordered series of line substrings in the command's KRB5_TRACE
|
|
Packit |
fd8b60 |
output, or return_trace=True to return a tuple of the command output
|
|
Packit |
fd8b60 |
and the trace output.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* realm.kprop_port(): Returns a port number based on realm.portbase
|
|
Packit |
fd8b60 |
intended for use by kprop and kpropd.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* realm.server_port(): Returns a port number based on realm.portbase
|
|
Packit |
fd8b60 |
intended for use by server processes.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* realm.start_server(args, sentinel, env=None): Start a daemon
|
|
Packit |
fd8b60 |
process. Wait until sentinel appears as a substring of a line in
|
|
Packit |
fd8b60 |
the server process's stdout or stderr (which are folded together).
|
|
Packit |
fd8b60 |
Returns a subprocess.Popen object which can be passed to
|
|
Packit |
fd8b60 |
stop_daemon() to stop the server, or used to read from the server's
|
|
Packit |
fd8b60 |
output.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* realm.start_in_inetd(args, port=None, env=None): Begin a t_inetd
|
|
Packit |
fd8b60 |
process which will spawn a server process after accepting a client
|
|
Packit |
fd8b60 |
connection. If port is not specified, realm.server_port() will be
|
|
Packit |
fd8b60 |
used. Returns a process object which can be passed to stop_daemon()
|
|
Packit |
fd8b60 |
to stop the server.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* realm.create_kdb(): Create a new KDB.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* realm.start_kdc(args=[], env=None): Start a krb5kdc process. Errors
|
|
Packit |
fd8b60 |
if a KDC is already running. If args is given, it contains a list
|
|
Packit |
fd8b60 |
of additional krb5kdc arguments.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* realm.stop_kdc(): Stop the krb5kdc process. Errors if no KDC is
|
|
Packit |
fd8b60 |
running.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* realm.start_kadmind(env=None): Start a kadmind process. Errors if a
|
|
Packit |
fd8b60 |
kadmind is already running.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* realm.stop_kadmind(): Stop the kadmind process. Errors if no
|
|
Packit |
fd8b60 |
kadmind is running.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* realm.stop(): Stop any daemon processes running on behalf of the
|
|
Packit |
fd8b60 |
realm.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* realm.addprinc(princname, password=None): Using kadmin.local, create
|
|
Packit |
fd8b60 |
a principal in the KDB named princname, with either a random or
|
|
Packit |
fd8b60 |
specified key.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* realm.extract_keytab(princname, keytab): Using kadmin.local, create
|
|
Packit |
fd8b60 |
a keytab for princname in the filename keytab. Uses the -norandkey
|
|
Packit |
fd8b60 |
option to avoid re-randomizing princname's key.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* realm.kinit(princname, password=None, flags=[]): Acquire credentials
|
|
Packit |
fd8b60 |
for princname using kinit, with additional flags []. If password is
|
|
Packit |
fd8b60 |
specified, it will be used as input to the kinit process; otherwise
|
|
Packit |
fd8b60 |
flags must cause kinit not to need a password (e.g. by specifying a
|
|
Packit |
fd8b60 |
keytab).
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* realm.klist(client_princ, service_princ=None, ccache=None): Using
|
|
Packit |
fd8b60 |
klist, list the credentials cache ccache (must be a filename;
|
|
Packit |
fd8b60 |
self.ccache if not specified) and verify that the output shows
|
|
Packit |
fd8b60 |
credentials for client_princ and service_princ (self.krbtgt_princ if
|
|
Packit |
fd8b60 |
not specified).
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* realm.klist_keytab(princ, keytab=None): Using klist, list keytab
|
|
Packit |
fd8b60 |
(must be a filename; self.keytab if not specified) and verify that
|
|
Packit |
fd8b60 |
the output shows the keytab name and principal name.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* realm.prep_kadmin(princname=None, password=None, flags=[]): Populate
|
|
Packit |
fd8b60 |
realm.kadmin_ccache with a ticket which can be used to run kadmin.
|
|
Packit |
fd8b60 |
If princname is not specified, realm.admin_princ and its default
|
|
Packit |
fd8b60 |
password will be used.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* realm.run_kadmin(args, **keywords): Run the specified query in
|
|
Packit |
fd8b60 |
kadmin, using realm.kadmin_ccache to authenticate. Accepts the same
|
|
Packit |
fd8b60 |
keyword arguments as run.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* realm.special_env(name, has_kdc_conf, krb5_conf=None,
|
|
Packit |
fd8b60 |
kdc_conf=None): Create an environment with a modified krb5.conf
|
|
Packit |
fd8b60 |
and/or kdc.conf. The specified krb5_conf and kdc_conf fragments, if
|
|
Packit |
fd8b60 |
any, will be merged with the realm's existing configuration. If
|
|
Packit |
fd8b60 |
has_kdc_conf is false, the new environment will have no kdc.conf.
|
|
Packit |
fd8b60 |
The environment returned by this method can be used with realm.run()
|
|
Packit |
fd8b60 |
or similar methods.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* realm.start_kpropd(env, args=[]): Start a kpropd process. Pass an
|
|
Packit |
fd8b60 |
environment created with realm.special_env() for the replica. If
|
|
Packit |
fd8b60 |
args is given, it contains a list of additional kpropd arguments.
|
|
Packit |
fd8b60 |
Returns a handle to the kpropd process.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* realm.run_kpropd_once(env, args=[]): Run kpropd once, using the -t
|
|
Packit |
fd8b60 |
flag. Pass an environment created with realm.special_env() for the
|
|
Packit |
fd8b60 |
replica. If args is given, it contains a list of additional kpropd
|
|
Packit |
fd8b60 |
arguments. Returns the kpropd output.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* realm.realm: The realm's name.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* realm.testdir: The realm's storage directory (absolute path).
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* realm.portbase: The realm's first listener port.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* realm.user_princ: The principal name user@<realmname>.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* realm.admin_princ: The principal name user/admin@<realmname>.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* realm.host_princ: The name of the host principal for this machine,
|
|
Packit |
fd8b60 |
with realm.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* realm.nfs_princ: The name of the nfs principal for this machine,
|
|
Packit |
fd8b60 |
with realm.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* realm.krbtgt_princ: The name of the krbtgt principal for the realm.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* realm.keytab: A keytab file in realm.testdir. Initially contains a
|
|
Packit |
fd8b60 |
host keytab unless disabled by the realm construction options.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* realm.client_keytab: A keytab file in realm.testdir. Initially
|
|
Packit |
fd8b60 |
nonexistent.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* realm.ccache: A ccache file in realm.testdir. Initially contains
|
|
Packit |
fd8b60 |
credentials for user unless disabled by the realm construction
|
|
Packit |
fd8b60 |
options.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* realm.kadmin_ccache: The ccache file initialized by prep_kadmin and
|
|
Packit |
fd8b60 |
used by run_kadmin.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* env: The realm's environment, extended from os.environ to point at
|
|
Packit |
fd8b60 |
the realm's config files and the build tree's shared libraries.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
When the test script is run, its behavior can be modified with
|
|
Packit |
fd8b60 |
command-line flags. These are documented in the --help output.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
"""
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
import atexit
|
|
Packit |
fd8b60 |
import fcntl
|
|
Packit |
fd8b60 |
import optparse
|
|
Packit |
fd8b60 |
import os
|
|
Packit |
fd8b60 |
import shlex
|
|
Packit |
fd8b60 |
import shutil
|
|
Packit |
fd8b60 |
import signal
|
|
Packit |
fd8b60 |
import socket
|
|
Packit |
fd8b60 |
import string
|
|
Packit |
fd8b60 |
import subprocess
|
|
Packit |
fd8b60 |
import sys
|
|
Packit |
fd8b60 |
import imp
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
# Used when most things go wrong (other than programming errors) so
|
|
Packit |
fd8b60 |
# that the user sees an error message rather than a Python traceback,
|
|
Packit |
fd8b60 |
# without help from the test script. The on-exit handler will display
|
|
Packit |
fd8b60 |
# additional explanatory text.
|
|
Packit |
fd8b60 |
def fail(msg):
|
|
Packit |
fd8b60 |
"""Print a message and exit with failure."""
|
|
Packit |
fd8b60 |
global _current_pass
|
|
Packit |
fd8b60 |
print("*** Failure:", msg)
|
|
Packit |
fd8b60 |
if _last_mark:
|
|
Packit |
fd8b60 |
print("*** Last mark: %s" % _last_mark)
|
|
Packit |
fd8b60 |
if _last_cmd:
|
|
Packit |
fd8b60 |
print("*** Last command (#%d): %s" % (_cmd_index - 1, _last_cmd))
|
|
Packit |
fd8b60 |
if _last_cmd_output:
|
|
Packit |
fd8b60 |
print("*** Output of last command:")
|
|
Packit |
fd8b60 |
sys.stdout.write(_last_cmd_output)
|
|
Packit |
fd8b60 |
if _current_pass:
|
|
Packit |
fd8b60 |
print("*** Failed in test pass:", _current_pass)
|
|
Packit |
fd8b60 |
if _current_db:
|
|
Packit |
fd8b60 |
print("*** Failed with db:", _current_db)
|
|
Packit |
fd8b60 |
sys.exit(1)
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
def success(msg):
|
|
Packit |
fd8b60 |
global _success
|
|
Packit |
fd8b60 |
_check_daemons()
|
|
Packit |
fd8b60 |
output('*** Success: %s\n' % msg)
|
|
Packit |
fd8b60 |
_success = True
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
def mark(msg):
|
|
Packit |
fd8b60 |
global _last_mark
|
|
Packit |
fd8b60 |
output('\n====== %s ======\n' % msg)
|
|
Packit |
fd8b60 |
_last_mark = msg
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
def skipped(whatmsg, whymsg):
|
|
Packit |
fd8b60 |
output('*** Skipping: %s: %s\n' % (whatmsg, whymsg), force_verbose=True)
|
|
Packit |
fd8b60 |
f = open(os.path.join(buildtop, 'skiptests'), 'a')
|
|
Packit |
fd8b60 |
f.write('Skipped %s: %s\n' % (whatmsg, whymsg))
|
|
Packit |
fd8b60 |
f.close()
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
def skip_rest(whatmsg, whymsg):
|
|
Packit |
fd8b60 |
global _success
|
|
Packit |
fd8b60 |
skipped(whatmsg, whymsg)
|
|
Packit |
fd8b60 |
_check_daemons()
|
|
Packit |
fd8b60 |
_success = True
|
|
Packit |
fd8b60 |
sys.exit(0)
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
def output(msg, force_verbose=False):
|
|
Packit |
fd8b60 |
"""Output a message to testlog, and to stdout if running verbosely."""
|
|
Packit |
fd8b60 |
_outfile.write(msg)
|
|
Packit |
fd8b60 |
if verbose or force_verbose:
|
|
Packit |
fd8b60 |
sys.stdout.write(msg)
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
# Return the location of progname in the executable path, or None if
|
|
Packit |
fd8b60 |
# it is not found.
|
|
Packit |
fd8b60 |
def which(progname):
|
|
Packit |
fd8b60 |
for dir in os.environ["PATH"].split(os.pathsep):
|
|
Packit |
fd8b60 |
path = os.path.join(dir, progname)
|
|
Packit |
fd8b60 |
if os.access(path, os.X_OK):
|
|
Packit |
fd8b60 |
return path
|
|
Packit |
fd8b60 |
return None
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
def password(name):
|
|
Packit |
fd8b60 |
"""Choose a weakly random password from name, consistent across calls."""
|
|
Packit |
fd8b60 |
return name + str(os.getpid())
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
# Exit handler which ensures processes are cleaned up and, on failure,
|
|
Packit |
fd8b60 |
# prints messages to help developers debug the problem.
|
|
Packit |
fd8b60 |
def _onexit():
|
|
Packit |
fd8b60 |
global _daemons, _success, srctop, verbose
|
|
Packit |
fd8b60 |
global _debug, _stop_before, _stop_after, _shell_before, _shell_after
|
|
Packit |
fd8b60 |
if _debug or _stop_before or _stop_after or _shell_before or _shell_after:
|
|
Packit |
fd8b60 |
# Wait before killing daemons in case one is being debugged.
|
|
Packit |
fd8b60 |
sys.stdout.write('*** Press return to kill daemons and exit script: ')
|
|
Packit |
fd8b60 |
sys.stdout.flush()
|
|
Packit |
fd8b60 |
sys.stdin.readline()
|
|
Packit |
fd8b60 |
for proc in _daemons:
|
|
Packit |
fd8b60 |
if _check_daemon(proc) is None:
|
|
Packit |
fd8b60 |
os.kill(proc.pid, signal.SIGTERM)
|
|
Packit |
fd8b60 |
if not _success:
|
|
Packit |
fd8b60 |
print
|
|
Packit |
fd8b60 |
if not verbose:
|
|
Packit |
fd8b60 |
testlogfile = os.path.join(os.getcwd(), 'testlog')
|
|
Packit |
fd8b60 |
utildir = os.path.join(srctop, 'util')
|
|
Packit |
fd8b60 |
print('For details, see: %s' % testlogfile)
|
|
Packit |
fd8b60 |
print('Or re-run this test script with the -v flag:')
|
|
Packit |
fd8b60 |
print(' cd %s' % os.getcwd())
|
|
Packit |
fd8b60 |
print(' PYTHONPATH=%s %s %s -v' %
|
|
Packit |
fd8b60 |
(utildir, sys.executable, sys.argv[0]))
|
|
Packit |
fd8b60 |
print()
|
|
Packit |
fd8b60 |
print('Use --debug=NUM to run a command under a debugger. Use')
|
|
Packit |
fd8b60 |
print('--stop-after=NUM to stop after a daemon is started in order to')
|
|
Packit |
fd8b60 |
print('attach to it with a debugger. Use --help to see other')
|
|
Packit |
fd8b60 |
print('options.')
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
def _onsigint(signum, frame):
|
|
Packit |
fd8b60 |
# Exit without displaying a stack trace. Suppress messages from _onexit.
|
|
Packit |
fd8b60 |
global _success
|
|
Packit |
fd8b60 |
_success = True
|
|
Packit |
fd8b60 |
sys.exit(1)
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
# Find the parent of dir which is at the root of a build or source directory.
|
|
Packit |
fd8b60 |
def _find_root(dir):
|
|
Packit |
fd8b60 |
while True:
|
|
Packit |
fd8b60 |
if os.path.exists(os.path.join(dir, 'lib', 'krb5', 'krb')):
|
|
Packit |
fd8b60 |
break
|
|
Packit |
fd8b60 |
parent = os.path.dirname(dir)
|
|
Packit |
fd8b60 |
if (parent == dir):
|
|
Packit |
fd8b60 |
return None
|
|
Packit |
fd8b60 |
dir = parent
|
|
Packit |
fd8b60 |
return dir
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
def _find_buildtop():
|
|
Packit |
fd8b60 |
root = _find_root(os.getcwd())
|
|
Packit |
fd8b60 |
if root is None:
|
|
Packit |
fd8b60 |
fail('Cannot find root of krb5 build directory.')
|
|
Packit |
fd8b60 |
if not os.path.exists(os.path.join(root, 'config.status')):
|
|
Packit |
fd8b60 |
# Looks like an unbuilt source directory.
|
|
Packit |
fd8b60 |
fail('This script must be run inside a krb5 build directory.')
|
|
Packit |
fd8b60 |
return root
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
def _find_srctop():
|
|
Packit |
fd8b60 |
scriptdir = os.path.abspath(os.path.dirname(sys.argv[0]))
|
|
Packit |
fd8b60 |
if not scriptdir:
|
|
Packit |
fd8b60 |
scriptdir = os.getcwd()
|
|
Packit |
fd8b60 |
root = _find_root(scriptdir)
|
|
Packit |
fd8b60 |
if root is None:
|
|
Packit |
fd8b60 |
fail('Cannot find root of krb5 source directory.')
|
|
Packit |
fd8b60 |
return os.path.abspath(root)
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
# Return the local hostname as it will be canonicalized by
|
|
Packit |
fd8b60 |
# krb5_sname_to_principal. We can't simply use socket.getfqdn()
|
|
Packit |
fd8b60 |
# because it explicitly prefers results containing periods and
|
|
Packit |
fd8b60 |
# krb5_sname_to_principal doesn't care.
|
|
Packit |
fd8b60 |
def _get_hostname():
|
|
Packit |
fd8b60 |
hostname = socket.gethostname()
|
|
Packit |
fd8b60 |
try:
|
|
Packit |
fd8b60 |
ai = socket.getaddrinfo(hostname, None, 0, 0, 0, socket.AI_CANONNAME)
|
|
Packit |
fd8b60 |
except socket.gaierror as e:
|
|
Packit |
fd8b60 |
fail('Local hostname "%s" does not resolve: %s.' % (hostname, e[1]))
|
|
Packit |
fd8b60 |
(family, socktype, proto, canonname, sockaddr) = ai[0]
|
|
Packit |
fd8b60 |
try:
|
|
Packit |
fd8b60 |
name = socket.getnameinfo(sockaddr, socket.NI_NAMEREQD)
|
|
Packit |
fd8b60 |
except socket.gaierror:
|
|
Packit |
fd8b60 |
return canonname.lower()
|
|
Packit |
fd8b60 |
return name[0].lower()
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
# Parse command line arguments, setting global option variables. Also
|
|
Packit |
fd8b60 |
# sets the global variable args to the positional arguments, which may
|
|
Packit |
fd8b60 |
# be used by the test script.
|
|
Packit |
fd8b60 |
def _parse_args():
|
|
Packit |
fd8b60 |
global args, verbose, testpass, _debug, _debugger_command
|
|
Packit |
fd8b60 |
global _stop_before, _stop_after, _shell_before, _shell_after
|
|
Packit |
fd8b60 |
parser = optparse.OptionParser()
|
|
Packit |
fd8b60 |
parser.add_option('-v', '--verbose', action='store_true', dest='verbose',
|
|
Packit |
fd8b60 |
default=False, help='Display verbose output')
|
|
Packit |
fd8b60 |
parser.add_option('-p', '--pass', dest='testpass', metavar='PASS',
|
|
Packit |
fd8b60 |
help='If a multi-pass test, run only PASS')
|
|
Packit |
fd8b60 |
parser.add_option('--debug', dest='debug', metavar='NUM',
|
|
Packit |
fd8b60 |
help='Debug numbered command (or "all")')
|
|
Packit |
fd8b60 |
parser.add_option('--debugger', dest='debugger', metavar='COMMAND',
|
|
Packit |
fd8b60 |
help='Debugger command (default is gdb --args)',
|
|
Packit |
fd8b60 |
default='gdb --args')
|
|
Packit |
fd8b60 |
parser.add_option('--stop-before', dest='stopb', metavar='NUM',
|
|
Packit |
fd8b60 |
help='Stop before numbered command (or "all")')
|
|
Packit |
fd8b60 |
parser.add_option('--stop-after', dest='stopa', metavar='NUM',
|
|
Packit |
fd8b60 |
help='Stop after numbered command (or "all")')
|
|
Packit |
fd8b60 |
parser.add_option('--shell-before', dest='shellb', metavar='NUM',
|
|
Packit |
fd8b60 |
help='Spawn shell before numbered command (or "all")')
|
|
Packit |
fd8b60 |
parser.add_option('--shell-after', dest='shella', metavar='NUM',
|
|
Packit |
fd8b60 |
help='Spawn shell after numbered command (or "all")')
|
|
Packit |
fd8b60 |
(options, args) = parser.parse_args()
|
|
Packit |
fd8b60 |
verbose = options.verbose
|
|
Packit |
fd8b60 |
testpass = options.testpass
|
|
Packit |
fd8b60 |
_debug = _parse_cmdnum('--debug', options.debug)
|
|
Packit |
fd8b60 |
_debugger_command = shlex.split(options.debugger)
|
|
Packit |
fd8b60 |
_stop_before = _parse_cmdnum('--stop-before', options.stopb)
|
|
Packit |
fd8b60 |
_stop_after = _parse_cmdnum('--stop-after', options.stopa)
|
|
Packit |
fd8b60 |
_shell_before = _parse_cmdnum('--shell-before', options.shellb)
|
|
Packit |
fd8b60 |
_shell_after = _parse_cmdnum('--shell-after', options.shella)
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
# Translate a command number spec. -1 means all, None means none.
|
|
Packit |
fd8b60 |
def _parse_cmdnum(optname, str):
|
|
Packit |
fd8b60 |
if not str:
|
|
Packit |
fd8b60 |
return None
|
|
Packit |
fd8b60 |
if str == 'all':
|
|
Packit |
fd8b60 |
return -1
|
|
Packit |
fd8b60 |
try:
|
|
Packit |
fd8b60 |
return int(str)
|
|
Packit |
fd8b60 |
except ValueError:
|
|
Packit |
fd8b60 |
fail('%s value must be "all" or a number' % optname)
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
# Test if a command index matches a translated command number spec.
|
|
Packit |
fd8b60 |
def _match_cmdnum(cmdnum, ind):
|
|
Packit |
fd8b60 |
if cmdnum is None:
|
|
Packit |
fd8b60 |
return False
|
|
Packit |
fd8b60 |
elif cmdnum == -1:
|
|
Packit |
fd8b60 |
return True
|
|
Packit |
fd8b60 |
else:
|
|
Packit |
fd8b60 |
return cmdnum == ind
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
# Return an environment suitable for running programs in the build
|
|
Packit |
fd8b60 |
# tree. It is safe to modify the result.
|
|
Packit |
fd8b60 |
def _build_env():
|
|
Packit |
fd8b60 |
global buildtop, runenv
|
|
Packit |
fd8b60 |
env = os.environ.copy()
|
|
Packit |
fd8b60 |
for (k, v) in runenv.env.items():
|
|
Packit |
fd8b60 |
if v.find('./') == 0:
|
|
Packit |
fd8b60 |
env[k] = os.path.join(buildtop, v)
|
|
Packit |
fd8b60 |
else:
|
|
Packit |
fd8b60 |
env[k] = v
|
|
Packit |
fd8b60 |
# Make sure we don't get confused by translated messages
|
|
Packit |
fd8b60 |
# or localized times.
|
|
Packit |
fd8b60 |
env['LC_ALL'] = 'C'
|
|
Packit |
fd8b60 |
return env
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
def _import_runenv():
|
|
Packit |
fd8b60 |
global buildtop
|
|
Packit |
fd8b60 |
runenv_py = os.path.join(buildtop, 'runenv.py')
|
|
Packit |
fd8b60 |
if not os.path.exists(runenv_py):
|
|
Packit |
fd8b60 |
fail('You must run "make runenv.py" in %s first.' % buildtop)
|
|
Packit |
fd8b60 |
return imp.load_source('runenv', runenv_py)
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
# Merge the nested dictionaries cfg1 and cfg2 into a new dictionary.
|
|
Packit |
fd8b60 |
# cfg1 or cfg2 may be None, in which case the other is returned. If
|
|
Packit |
fd8b60 |
# cfg2 contains keys mapped to None, the corresponding keys will be
|
|
Packit |
fd8b60 |
# mapped to None in the result. The result may contain references to
|
|
Packit |
fd8b60 |
# parts of cfg1 or cfg2, so is not safe to modify.
|
|
Packit |
fd8b60 |
def _cfg_merge(cfg1, cfg2):
|
|
Packit |
fd8b60 |
if not cfg2:
|
|
Packit |
fd8b60 |
return cfg1
|
|
Packit |
fd8b60 |
if not cfg1:
|
|
Packit |
fd8b60 |
return cfg2
|
|
Packit |
fd8b60 |
result = cfg1.copy()
|
|
Packit |
fd8b60 |
for key, value2 in cfg2.items():
|
|
Packit |
fd8b60 |
if value2 is None:
|
|
Packit |
fd8b60 |
result.pop(key, None)
|
|
Packit |
fd8b60 |
elif key not in result:
|
|
Packit |
fd8b60 |
result[key] = value2
|
|
Packit |
fd8b60 |
else:
|
|
Packit |
fd8b60 |
value1 = result[key]
|
|
Packit |
fd8b60 |
if isinstance(value1, dict):
|
|
Packit |
fd8b60 |
if not isinstance(value2, dict):
|
|
Packit |
fd8b60 |
raise TypeError()
|
|
Packit |
fd8b60 |
result[key] = _cfg_merge(value1, value2)
|
|
Packit |
fd8b60 |
else:
|
|
Packit |
fd8b60 |
result[key] = value2
|
|
Packit |
fd8b60 |
return result
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
# Python gives us shlex.split() to turn a shell command into a list of
|
|
Packit |
fd8b60 |
# arguments, but oddly enough, not the easier reverse operation. For
|
|
Packit |
fd8b60 |
# now, do a bad job of faking it.
|
|
Packit |
fd8b60 |
def _shell_equiv(args):
|
|
Packit |
fd8b60 |
return " ".join(args)
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
# Add a valgrind prefix to the front of args if specified in the
|
|
Packit |
fd8b60 |
# environment. Under normal circumstances this just returns args.
|
|
Packit |
fd8b60 |
def _valgrind(args):
|
|
Packit |
fd8b60 |
valgrind = os.getenv('VALGRIND')
|
|
Packit |
fd8b60 |
if valgrind:
|
|
Packit |
fd8b60 |
args = shlex.split(valgrind) + args
|
|
Packit |
fd8b60 |
return args
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
def _stop_or_shell(stop, shell, env, ind):
|
|
Packit |
fd8b60 |
if (_match_cmdnum(stop, ind)):
|
|
Packit |
fd8b60 |
sys.stdout.write('*** [%d] Waiting for return: ' % ind)
|
|
Packit |
fd8b60 |
sys.stdout.flush()
|
|
Packit |
fd8b60 |
sys.stdin.readline()
|
|
Packit |
fd8b60 |
if (_match_cmdnum(shell, ind)):
|
|
Packit |
fd8b60 |
output('*** [%d] Spawning shell\n' % ind, True)
|
|
Packit |
fd8b60 |
subprocess.call(os.getenv('SHELL'), env=env)
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
# Look for the expected strings in successive lines of trace.
|
|
Packit |
fd8b60 |
def _check_trace(trace, expected):
|
|
Packit |
fd8b60 |
i = 0
|
|
Packit |
fd8b60 |
for line in trace.splitlines():
|
|
Packit |
fd8b60 |
if i < len(expected) and expected[i] in line:
|
|
Packit |
fd8b60 |
i += 1
|
|
Packit |
fd8b60 |
if i < len(expected):
|
|
Packit |
fd8b60 |
fail('Expected string not found in trace output: ' + expected[i])
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
def _run_cmd(args, env, input=None, expected_code=0, expected_msg=None,
|
|
Packit |
fd8b60 |
expected_trace=None, return_trace=False):
|
|
Packit |
fd8b60 |
global null_input, _cmd_index, _last_cmd, _last_cmd_output, _debug
|
|
Packit |
fd8b60 |
global _stop_before, _stop_after, _shell_before, _shell_after
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
tracefile = None
|
|
Packit |
fd8b60 |
if expected_trace is not None or return_trace:
|
|
Packit |
fd8b60 |
tracefile = 'testtrace'
|
|
Packit |
fd8b60 |
if os.path.exists(tracefile):
|
|
Packit |
fd8b60 |
os.remove(tracefile)
|
|
Packit |
fd8b60 |
env = env.copy()
|
|
Packit |
fd8b60 |
env['KRB5_TRACE'] = tracefile
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
if (_match_cmdnum(_debug, _cmd_index)):
|
|
Packit |
fd8b60 |
return _debug_cmd(args, env, input)
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
args = _valgrind(args)
|
|
Packit |
fd8b60 |
_last_cmd = _shell_equiv(args)
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
output('*** [%d] Executing: %s\n' % (_cmd_index, _last_cmd))
|
|
Packit |
fd8b60 |
_stop_or_shell(_stop_before, _shell_before, env, _cmd_index)
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
if input:
|
|
Packit |
fd8b60 |
infile = subprocess.PIPE
|
|
Packit |
fd8b60 |
else:
|
|
Packit |
fd8b60 |
infile = null_input
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
# Run the command and log the result, folding stderr into stdout.
|
|
Packit |
fd8b60 |
proc = subprocess.Popen(args, stdin=infile, stdout=subprocess.PIPE,
|
|
Packit |
fd8b60 |
stderr=subprocess.STDOUT, env=env,
|
|
Packit |
fd8b60 |
universal_newlines=True)
|
|
Packit |
fd8b60 |
(outdata, dummy_errdata) = proc.communicate(input)
|
|
Packit |
fd8b60 |
_last_cmd_output = outdata
|
|
Packit |
fd8b60 |
code = proc.returncode
|
|
Packit |
fd8b60 |
output(outdata)
|
|
Packit |
fd8b60 |
output('*** [%d] Completed with return code %d\n' % (_cmd_index, code))
|
|
Packit |
fd8b60 |
_stop_or_shell(_stop_after, _shell_after, env, _cmd_index)
|
|
Packit |
fd8b60 |
_cmd_index += 1
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
# Check the return code and return the output.
|
|
Packit |
fd8b60 |
if code != expected_code:
|
|
Packit |
fd8b60 |
fail('%s failed with code %d.' % (args[0], code))
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
if expected_msg is not None and expected_msg not in outdata:
|
|
Packit |
fd8b60 |
fail('Expected string not found in command output: ' + expected_msg)
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
if tracefile is not None:
|
|
Packit |
fd8b60 |
with open(tracefile, 'r') as f:
|
|
Packit |
fd8b60 |
trace = f.read()
|
|
Packit |
fd8b60 |
output('*** Trace output for previous command:\n')
|
|
Packit |
fd8b60 |
output(trace)
|
|
Packit |
fd8b60 |
if expected_trace is not None:
|
|
Packit |
fd8b60 |
_check_trace(trace, expected_trace)
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
return (outdata, trace) if return_trace else outdata
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
def _debug_cmd(args, env, input):
|
|
Packit |
fd8b60 |
global _cmd_index, _debugger_command
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
args = _debugger_command + list(args)
|
|
Packit |
fd8b60 |
output('*** [%d] Executing in debugger: %s\n' %
|
|
Packit |
fd8b60 |
(_cmd_index, _shell_equiv(args)), True)
|
|
Packit |
fd8b60 |
if input:
|
|
Packit |
fd8b60 |
print
|
|
Packit |
fd8b60 |
print('*** Enter the following input when appropriate:')
|
|
Packit |
fd8b60 |
print()
|
|
Packit |
fd8b60 |
print(input)
|
|
Packit |
fd8b60 |
print()
|
|
Packit |
fd8b60 |
code = subprocess.call(args, env=env)
|
|
Packit |
fd8b60 |
output('*** [%d] Completed in debugger with return code %d\n' %
|
|
Packit |
fd8b60 |
(_cmd_index, code))
|
|
Packit |
fd8b60 |
_cmd_index += 1
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
# Start a daemon process with the specified args and env. Wait until
|
|
Packit |
fd8b60 |
# we see sentinel as a substring of a line on either stdout or stderr.
|
|
Packit |
fd8b60 |
# Clean up the daemon process on exit.
|
|
Packit |
fd8b60 |
def _start_daemon(args, env, sentinel):
|
|
Packit |
fd8b60 |
global null_input, _cmd_index, _last_cmd, _last_cmd_output, _debug
|
|
Packit |
fd8b60 |
global _stop_before, _stop_after, _shell_before, _shell_after
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
if (_match_cmdnum(_debug, _cmd_index)):
|
|
Packit |
fd8b60 |
output('*** [%d] Warning: ' % _cmd_index, True)
|
|
Packit |
fd8b60 |
output( 'test script cannot proceed after debugging a daemon\n', True)
|
|
Packit |
fd8b60 |
_debug_cmd(args, env, None)
|
|
Packit |
fd8b60 |
output('*** Exiting after debugging daemon\n', True)
|
|
Packit |
fd8b60 |
sys.exit(1)
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
args = _valgrind(args)
|
|
Packit |
fd8b60 |
_last_cmd = _shell_equiv(args)
|
|
Packit |
fd8b60 |
output('*** [%d] Starting: %s\n' % (_cmd_index, _last_cmd))
|
|
Packit |
fd8b60 |
_stop_or_shell(_stop_before, _shell_before, env, _cmd_index)
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
# Start the daemon and look for the sentinel in stdout or stderr.
|
|
Packit |
fd8b60 |
proc = subprocess.Popen(args, stdin=null_input, stdout=subprocess.PIPE,
|
|
Packit |
fd8b60 |
stderr=subprocess.STDOUT, env=env,
|
|
Packit |
fd8b60 |
universal_newlines=True)
|
|
Packit |
fd8b60 |
_last_cmd_output = ''
|
|
Packit |
fd8b60 |
while True:
|
|
Packit |
fd8b60 |
line = proc.stdout.readline()
|
|
Packit |
fd8b60 |
_last_cmd_output += line
|
|
Packit |
fd8b60 |
if line == "":
|
|
Packit |
fd8b60 |
code = proc.wait()
|
|
Packit |
fd8b60 |
fail('%s failed to start with code %d.' % (args[0], code))
|
|
Packit |
fd8b60 |
output(line)
|
|
Packit |
fd8b60 |
if sentinel in line:
|
|
Packit |
fd8b60 |
break
|
|
Packit |
fd8b60 |
output('*** [%d] Started with pid %d\n' % (_cmd_index, proc.pid))
|
|
Packit |
fd8b60 |
_stop_or_shell(_stop_after, _shell_after, env, _cmd_index)
|
|
Packit |
fd8b60 |
_cmd_index += 1
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
# Save the daemon in a list for cleanup. Note that we won't read
|
|
Packit |
fd8b60 |
# any more of the daemon's output after the sentinel, which will
|
|
Packit |
fd8b60 |
# cause the daemon to block if it generates enough. For now we
|
|
Packit |
fd8b60 |
# assume all daemon processes are quiet enough to avoid this
|
|
Packit |
fd8b60 |
# problem. If it causes an issue, some alternatives are:
|
|
Packit |
fd8b60 |
# - Output to a file and poll the file for the sentinel
|
|
Packit |
fd8b60 |
# (undesirable because it slows down the test suite by the
|
|
Packit |
fd8b60 |
# polling interval times the number of daemons started)
|
|
Packit |
fd8b60 |
# - Create an intermediate subprocess which discards output
|
|
Packit |
fd8b60 |
# after the sentinel.
|
|
Packit |
fd8b60 |
_daemons.append(proc)
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
# Return the process; the caller can stop it with stop_daemon.
|
|
Packit |
fd8b60 |
return proc
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
# Check a daemon's status prior to terminating it. Display its return
|
|
Packit |
fd8b60 |
# code if it already exited, and display any output it has generated.
|
|
Packit |
fd8b60 |
# Return the daemon's exit status or None if it is still running.
|
|
Packit |
fd8b60 |
def _check_daemon(proc):
|
|
Packit |
fd8b60 |
exited = False
|
|
Packit |
fd8b60 |
code = proc.poll()
|
|
Packit |
fd8b60 |
if code is not None:
|
|
Packit |
fd8b60 |
output('*** Daemon pid %d exited with code %d\n' % (proc.pid, code))
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
flags = fcntl.fcntl(proc.stdout, fcntl.F_GETFL)
|
|
Packit |
fd8b60 |
fcntl.fcntl(proc.stdout, fcntl.F_SETFL, flags | os.O_NONBLOCK)
|
|
Packit |
fd8b60 |
try:
|
|
Packit |
fd8b60 |
out = proc.stdout.read()
|
|
Packit |
fd8b60 |
except:
|
|
Packit |
fd8b60 |
return
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
output('*** Daemon pid %d output:\n' % proc.pid)
|
|
Packit |
fd8b60 |
output(out)
|
|
Packit |
fd8b60 |
return code
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
# Check all tracked daemon processes. If any daemons already exited,
|
|
Packit |
fd8b60 |
# remove them from the list (so we don't try to terminate them again).
|
|
Packit |
fd8b60 |
# If any daemons exited with an error, fail out.
|
|
Packit |
fd8b60 |
def _check_daemons():
|
|
Packit |
fd8b60 |
exited = []
|
|
Packit |
fd8b60 |
daemon_error = False
|
|
Packit |
fd8b60 |
for proc in _daemons:
|
|
Packit |
fd8b60 |
code = _check_daemon(proc)
|
|
Packit |
fd8b60 |
if code is not None:
|
|
Packit |
fd8b60 |
exited.append(proc)
|
|
Packit |
fd8b60 |
if code != 0:
|
|
Packit |
fd8b60 |
daemon_error = True
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
for proc in exited:
|
|
Packit |
fd8b60 |
_daemons.remove(proc)
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
if daemon_error:
|
|
Packit |
fd8b60 |
fail('One or more daemon processes exited with an error')
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
def stop_daemon(proc):
|
|
Packit |
fd8b60 |
code = _check_daemon(proc)
|
|
Packit |
fd8b60 |
if code is not None:
|
|
Packit |
fd8b60 |
_daemons.remove(proc)
|
|
Packit |
fd8b60 |
if code != 0:
|
|
Packit |
fd8b60 |
fail('Daemon process %d exited early' % proc.pid)
|
|
Packit |
fd8b60 |
else:
|
|
Packit |
fd8b60 |
output('*** Terminating process %d\n' % proc.pid)
|
|
Packit |
fd8b60 |
os.kill(proc.pid, signal.SIGTERM)
|
|
Packit |
fd8b60 |
proc.wait()
|
|
Packit |
fd8b60 |
_daemons.remove(proc)
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
class K5Realm(object):
|
|
Packit |
fd8b60 |
"""An object representing a functional krb5 test realm."""
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
def __init__(self, realm='KRBTEST.COM', portbase=61000, testdir='testdir',
|
|
Packit |
fd8b60 |
krb5_conf=None, kdc_conf=None, create_kdb=True,
|
|
Packit |
fd8b60 |
krbtgt_keysalt=None, create_user=True, get_creds=True,
|
|
Packit |
fd8b60 |
create_host=True, start_kdc=True, start_kadmind=False,
|
|
Packit |
fd8b60 |
start_kpropd=False, bdb_only=False):
|
|
Packit |
fd8b60 |
global hostname, _default_krb5_conf, _default_kdc_conf
|
|
Packit |
fd8b60 |
global _lmdb_kdc_conf, _current_db
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
self.realm = realm
|
|
Packit |
fd8b60 |
self.testdir = os.path.join(os.getcwd(), testdir)
|
|
Packit |
fd8b60 |
self.portbase = portbase
|
|
Packit |
fd8b60 |
self.user_princ = 'user@' + self.realm
|
|
Packit |
fd8b60 |
self.admin_princ = 'user/admin@' + self.realm
|
|
Packit |
fd8b60 |
self.host_princ = 'host/%s@%s' % (hostname, self.realm)
|
|
Packit |
fd8b60 |
self.nfs_princ = 'nfs/%s@%s' % (hostname, self.realm)
|
|
Packit |
fd8b60 |
self.krbtgt_princ = 'krbtgt/%s@%s' % (self.realm, self.realm)
|
|
Packit |
fd8b60 |
self.keytab = os.path.join(self.testdir, 'keytab')
|
|
Packit |
fd8b60 |
self.client_keytab = os.path.join(self.testdir, 'client_keytab')
|
|
Packit |
fd8b60 |
self.ccache = os.path.join(self.testdir, 'ccache')
|
|
Packit |
fd8b60 |
self.gss_mech_config = os.path.join(self.testdir, 'mech.conf')
|
|
Packit |
fd8b60 |
self.kadmin_ccache = os.path.join(self.testdir, 'kadmin_ccache')
|
|
Packit |
fd8b60 |
self._krb5_conf = _cfg_merge(_default_krb5_conf, krb5_conf)
|
|
Packit |
fd8b60 |
base_kdc_conf = _default_kdc_conf
|
|
Packit |
fd8b60 |
if (os.getenv('K5TEST_LMDB') is not None and
|
|
Packit |
fd8b60 |
not bdb_only and not _current_db):
|
|
Packit |
fd8b60 |
base_kdc_conf = _cfg_merge(base_kdc_conf, _lmdb_kdc_conf)
|
|
Packit |
fd8b60 |
self._kdc_conf = _cfg_merge(base_kdc_conf, kdc_conf)
|
|
Packit |
fd8b60 |
self._kdc_proc = None
|
|
Packit |
fd8b60 |
self._kadmind_proc = None
|
|
Packit |
fd8b60 |
self._kpropd_procs = []
|
|
Packit |
fd8b60 |
krb5_conf_path = os.path.join(self.testdir, 'krb5.conf')
|
|
Packit |
fd8b60 |
kdc_conf_path = os.path.join(self.testdir, 'kdc.conf')
|
|
Packit |
fd8b60 |
self.env = self._make_env(krb5_conf_path, kdc_conf_path)
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
self._create_empty_dir()
|
|
Packit |
fd8b60 |
self._create_conf(self._krb5_conf, krb5_conf_path)
|
|
Packit |
fd8b60 |
self._create_conf(self._kdc_conf, kdc_conf_path)
|
|
Packit |
fd8b60 |
self._create_acl()
|
|
Packit |
fd8b60 |
self._create_dictfile()
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
if create_kdb:
|
|
Packit |
fd8b60 |
self.create_kdb()
|
|
Packit |
fd8b60 |
if krbtgt_keysalt and create_kdb:
|
|
Packit |
fd8b60 |
self.run([kadminl, 'cpw', '-randkey', '-e', krbtgt_keysalt,
|
|
Packit |
fd8b60 |
self.krbtgt_princ])
|
|
Packit |
fd8b60 |
if create_user and create_kdb:
|
|
Packit |
fd8b60 |
self.addprinc(self.user_princ, password('user'))
|
|
Packit |
fd8b60 |
self.addprinc(self.admin_princ, password('admin'))
|
|
Packit |
fd8b60 |
if create_host and create_kdb:
|
|
Packit |
fd8b60 |
self.addprinc(self.host_princ)
|
|
Packit |
fd8b60 |
self.extract_keytab(self.host_princ, self.keytab)
|
|
Packit |
fd8b60 |
if start_kdc and create_kdb:
|
|
Packit |
fd8b60 |
self.start_kdc()
|
|
Packit |
fd8b60 |
if start_kadmind and create_kdb:
|
|
Packit |
fd8b60 |
self.start_kadmind()
|
|
Packit |
fd8b60 |
if get_creds and create_kdb and create_user and start_kdc:
|
|
Packit |
fd8b60 |
self.kinit(self.user_princ, password('user'))
|
|
Packit |
fd8b60 |
self.klist(self.user_princ)
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
def _create_empty_dir(self):
|
|
Packit |
fd8b60 |
dir = self.testdir
|
|
Packit |
fd8b60 |
shutil.rmtree(dir, True)
|
|
Packit |
fd8b60 |
if (os.path.exists(dir)):
|
|
Packit |
fd8b60 |
fail('Cannot remove %s to create test realm.' % dir)
|
|
Packit |
fd8b60 |
os.mkdir(dir)
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
def _create_conf(self, profile, filename):
|
|
Packit |
fd8b60 |
file = open(filename, 'w')
|
|
Packit |
fd8b60 |
for section, contents in profile.items():
|
|
Packit |
fd8b60 |
file.write('[%s]\n' % section)
|
|
Packit |
fd8b60 |
self._write_cfg_section(file, contents, 1)
|
|
Packit |
fd8b60 |
file.close()
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
def _write_cfg_section(self, file, contents, indent_level):
|
|
Packit |
fd8b60 |
indent = '\t' * indent_level
|
|
Packit |
fd8b60 |
for name, value in contents.items():
|
|
Packit |
fd8b60 |
name = self._subst_cfg_value(name)
|
|
Packit |
fd8b60 |
if isinstance(value, dict):
|
|
Packit |
fd8b60 |
# A dictionary value yields a list subsection.
|
|
Packit |
fd8b60 |
file.write('%s%s = {\n' % (indent, name))
|
|
Packit |
fd8b60 |
self._write_cfg_section(file, value, indent_level + 1)
|
|
Packit |
fd8b60 |
file.write('%s}\n' % indent)
|
|
Packit |
fd8b60 |
elif isinstance(value, list):
|
|
Packit |
fd8b60 |
# A list value yields multiple values for the same name.
|
|
Packit |
fd8b60 |
for item in value:
|
|
Packit |
fd8b60 |
item = self._subst_cfg_value(item)
|
|
Packit |
fd8b60 |
file.write('%s%s = %s\n' % (indent, name, item))
|
|
Packit |
fd8b60 |
elif isinstance(value, str):
|
|
Packit |
fd8b60 |
# A string value yields a straightforward variable setting.
|
|
Packit |
fd8b60 |
value = self._subst_cfg_value(value)
|
|
Packit |
fd8b60 |
file.write('%s%s = %s\n' % (indent, name, value))
|
|
Packit |
fd8b60 |
else:
|
|
Packit |
fd8b60 |
raise TypeError()
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
def _subst_cfg_value(self, value):
|
|
Packit |
fd8b60 |
global buildtop, srctop, hostname
|
|
Packit |
fd8b60 |
template = string.Template(value)
|
|
Packit |
fd8b60 |
subst = template.substitute(realm=self.realm,
|
|
Packit |
fd8b60 |
testdir=self.testdir,
|
|
Packit |
fd8b60 |
buildtop=buildtop,
|
|
Packit |
fd8b60 |
srctop=srctop,
|
|
Packit |
fd8b60 |
plugins=plugins,
|
|
Packit |
fd8b60 |
hostname=hostname,
|
|
Packit |
fd8b60 |
port0=self.portbase,
|
|
Packit |
fd8b60 |
port1=self.portbase + 1,
|
|
Packit |
fd8b60 |
port2=self.portbase + 2,
|
|
Packit |
fd8b60 |
port3=self.portbase + 3,
|
|
Packit |
fd8b60 |
port4=self.portbase + 4,
|
|
Packit |
fd8b60 |
port5=self.portbase + 5,
|
|
Packit |
fd8b60 |
port6=self.portbase + 6,
|
|
Packit |
fd8b60 |
port7=self.portbase + 7,
|
|
Packit |
fd8b60 |
port8=self.portbase + 8,
|
|
Packit |
fd8b60 |
port9=self.portbase + 9)
|
|
Packit |
fd8b60 |
# Empty values must be quoted to avoid a syntax error.
|
|
Packit |
fd8b60 |
return subst if subst else '""'
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
def _create_acl(self):
|
|
Packit |
fd8b60 |
global hostname
|
|
Packit |
fd8b60 |
filename = os.path.join(self.testdir, 'acl')
|
|
Packit |
fd8b60 |
file = open(filename, 'w')
|
|
Packit |
fd8b60 |
file.write('%s *e\n' % self.admin_princ)
|
|
Packit |
fd8b60 |
file.write('kiprop/%s@%s p\n' % (hostname, self.realm))
|
|
Packit |
fd8b60 |
file.close()
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
def _create_dictfile(self):
|
|
Packit |
fd8b60 |
filename = os.path.join(self.testdir, 'dictfile')
|
|
Packit |
fd8b60 |
file = open(filename, 'w')
|
|
Packit |
fd8b60 |
file.write('weak_password\n')
|
|
Packit |
fd8b60 |
file.close()
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
def _make_env(self, krb5_conf_path, kdc_conf_path):
|
|
Packit |
fd8b60 |
env = _build_env()
|
|
Packit |
fd8b60 |
env['KRB5_CONFIG'] = krb5_conf_path
|
|
Packit |
fd8b60 |
env['KRB5_KDC_PROFILE'] = kdc_conf_path or os.devnull
|
|
Packit |
fd8b60 |
env['KRB5CCNAME'] = self.ccache
|
|
Packit |
fd8b60 |
env['KRB5_KTNAME'] = self.keytab
|
|
Packit |
fd8b60 |
env['KRB5_CLIENT_KTNAME'] = self.client_keytab
|
|
Packit |
fd8b60 |
env['KRB5RCACHEDIR'] = self.testdir
|
|
Packit |
fd8b60 |
env['KPROPD_PORT'] = str(self.kprop_port())
|
|
Packit |
fd8b60 |
env['KPROP_PORT'] = str(self.kprop_port())
|
|
Packit |
fd8b60 |
env['GSS_MECH_CONFIG'] = self.gss_mech_config
|
|
Packit |
fd8b60 |
return env
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
def run(self, args, env=None, **keywords):
|
|
Packit |
fd8b60 |
if env is None:
|
|
Packit |
fd8b60 |
env = self.env
|
|
Packit |
fd8b60 |
return _run_cmd(args, env, **keywords)
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
def kprop_port(self):
|
|
Packit |
fd8b60 |
return self.portbase + 3
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
def server_port(self):
|
|
Packit |
fd8b60 |
return self.portbase + 5
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
def start_server(self, args, sentinel, env=None):
|
|
Packit |
fd8b60 |
if env is None:
|
|
Packit |
fd8b60 |
env = self.env
|
|
Packit |
fd8b60 |
return _start_daemon(args, env, sentinel)
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
def start_in_inetd(self, args, port=None, env=None):
|
|
Packit |
fd8b60 |
if not port:
|
|
Packit |
fd8b60 |
port = self.server_port()
|
|
Packit |
fd8b60 |
if env is None:
|
|
Packit |
fd8b60 |
env = self.env
|
|
Packit |
fd8b60 |
inetd_args = [t_inetd, str(port)] + args
|
|
Packit |
fd8b60 |
return _start_daemon(inetd_args, env, 'Ready!')
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
def create_kdb(self):
|
|
Packit |
fd8b60 |
global kdb5_util
|
|
Packit |
fd8b60 |
self.run([kdb5_util, 'create', '-W', '-s', '-P', 'master'])
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
def start_kdc(self, args=[], env=None):
|
|
Packit |
fd8b60 |
global krb5kdc
|
|
Packit |
fd8b60 |
if env is None:
|
|
Packit |
fd8b60 |
env = self.env
|
|
Packit |
fd8b60 |
assert(self._kdc_proc is None)
|
|
Packit |
fd8b60 |
self._kdc_proc = _start_daemon([krb5kdc, '-n'] + args, env,
|
|
Packit |
fd8b60 |
'starting...')
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
def stop_kdc(self):
|
|
Packit |
fd8b60 |
assert(self._kdc_proc is not None)
|
|
Packit |
fd8b60 |
stop_daemon(self._kdc_proc)
|
|
Packit |
fd8b60 |
self._kdc_proc = None
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
def start_kadmind(self, env=None):
|
|
Packit |
fd8b60 |
global krb5kdc
|
|
Packit |
fd8b60 |
if env is None:
|
|
Packit |
fd8b60 |
env = self.env
|
|
Packit |
fd8b60 |
assert(self._kadmind_proc is None)
|
|
Packit |
fd8b60 |
dump_path = os.path.join(self.testdir, 'dump')
|
|
Packit |
fd8b60 |
self._kadmind_proc = _start_daemon([kadmind, '-nofork', '-W',
|
|
Packit |
fd8b60 |
'-p', kdb5_util, '-K', kprop,
|
|
Packit |
fd8b60 |
'-F', dump_path], env,
|
|
Packit |
fd8b60 |
'starting...')
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
def stop_kadmind(self):
|
|
Packit |
fd8b60 |
assert(self._kadmind_proc is not None)
|
|
Packit |
fd8b60 |
stop_daemon(self._kadmind_proc)
|
|
Packit |
fd8b60 |
self._kadmind_proc = None
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
def _kpropd_args(self):
|
|
Packit |
fd8b60 |
datatrans_path = os.path.join(self.testdir, 'incoming-datatrans')
|
|
Packit |
fd8b60 |
kpropdacl_path = os.path.join(self.testdir, 'kpropd-acl')
|
|
Packit |
fd8b60 |
return [kpropd, '-D', '-P', str(self.kprop_port()),
|
|
Packit |
fd8b60 |
'-f', datatrans_path, '-p', kdb5_util, '-a', kpropdacl_path]
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
def start_kpropd(self, env, args=[]):
|
|
Packit |
fd8b60 |
proc = _start_daemon(self._kpropd_args() + args, env, 'ready')
|
|
Packit |
fd8b60 |
self._kpropd_procs.append(proc)
|
|
Packit |
fd8b60 |
return proc
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
def stop_kpropd(self, proc):
|
|
Packit |
fd8b60 |
stop_daemon(proc)
|
|
Packit |
fd8b60 |
self._kpropd_procs.remove(proc)
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
def run_kpropd_once(self, env, args=[]):
|
|
Packit |
fd8b60 |
return self.run(self._kpropd_args() + ['-t'] + args, env=env)
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
def stop(self):
|
|
Packit |
fd8b60 |
if self._kdc_proc:
|
|
Packit |
fd8b60 |
self.stop_kdc()
|
|
Packit |
fd8b60 |
if self._kadmind_proc:
|
|
Packit |
fd8b60 |
self.stop_kadmind()
|
|
Packit |
fd8b60 |
for p in self._kpropd_procs:
|
|
Packit |
fd8b60 |
stop_daemon(p)
|
|
Packit |
fd8b60 |
self._kpropd_procs = []
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
def addprinc(self, princname, password=None):
|
|
Packit |
fd8b60 |
if password:
|
|
Packit |
fd8b60 |
self.run([kadminl, 'addprinc', '-pw', password, princname])
|
|
Packit |
fd8b60 |
else:
|
|
Packit |
fd8b60 |
self.run([kadminl, 'addprinc', '-randkey', princname])
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
def extract_keytab(self, princname, keytab):
|
|
Packit |
fd8b60 |
self.run([kadminl, 'ktadd', '-k', keytab, '-norandkey', princname])
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
def kinit(self, princname, password=None, flags=[], **keywords):
|
|
Packit |
fd8b60 |
if password:
|
|
Packit |
fd8b60 |
input = password + "\n"
|
|
Packit |
fd8b60 |
else:
|
|
Packit |
fd8b60 |
input = None
|
|
Packit |
fd8b60 |
return self.run([kinit] + flags + [princname], input=input, **keywords)
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
def klist(self, client_princ, service_princ=None, ccache=None, **keywords):
|
|
Packit |
fd8b60 |
if service_princ is None:
|
|
Packit |
fd8b60 |
service_princ = self.krbtgt_princ
|
|
Packit |
fd8b60 |
if ccache is None:
|
|
Packit |
fd8b60 |
ccache = self.ccache
|
|
Packit |
fd8b60 |
ccachestr = ccache
|
|
Packit |
fd8b60 |
if len(ccachestr) < 2 or ':' not in ccachestr[2:]:
|
|
Packit |
fd8b60 |
ccachestr = 'FILE:' + ccachestr
|
|
Packit |
fd8b60 |
output = self.run([klist, ccache], **keywords)
|
|
Packit |
fd8b60 |
if (('Ticket cache: %s\n' % ccachestr) not in output or
|
|
Packit |
fd8b60 |
('Default principal: %s\n' % client_princ) not in output or
|
|
Packit |
fd8b60 |
service_princ not in output):
|
|
Packit |
fd8b60 |
fail('Unexpected klist output.')
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
def klist_keytab(self, princ, keytab=None, **keywords):
|
|
Packit |
fd8b60 |
if keytab is None:
|
|
Packit |
fd8b60 |
keytab = self.keytab
|
|
Packit |
fd8b60 |
output = self.run([klist, '-k', keytab], **keywords)
|
|
Packit |
fd8b60 |
if (('Keytab name: FILE:%s\n' % keytab) not in output or
|
|
Packit |
fd8b60 |
'KVNO Principal\n----' not in output or
|
|
Packit |
fd8b60 |
princ not in output):
|
|
Packit |
fd8b60 |
fail('Unexpected klist output.')
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
def prep_kadmin(self, princname=None, pw=None, flags=[]):
|
|
Packit |
fd8b60 |
if princname is None:
|
|
Packit |
fd8b60 |
princname = self.admin_princ
|
|
Packit |
fd8b60 |
pw = password('admin')
|
|
Packit |
fd8b60 |
return self.kinit(princname, pw,
|
|
Packit |
fd8b60 |
flags=['-S', 'kadmin/admin',
|
|
Packit |
fd8b60 |
'-c', self.kadmin_ccache] + flags)
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
def run_kadmin(self, args, **keywords):
|
|
Packit |
fd8b60 |
return self.run([kadmin, '-c', self.kadmin_ccache] + args, **keywords)
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
def special_env(self, name, has_kdc_conf, krb5_conf=None, kdc_conf=None):
|
|
Packit |
fd8b60 |
krb5_conf_path = os.path.join(self.testdir, 'krb5.conf.%s' % name)
|
|
Packit |
fd8b60 |
krb5_conf = _cfg_merge(self._krb5_conf, krb5_conf)
|
|
Packit |
fd8b60 |
self._create_conf(krb5_conf, krb5_conf_path)
|
|
Packit |
fd8b60 |
if has_kdc_conf:
|
|
Packit |
fd8b60 |
kdc_conf_path = os.path.join(self.testdir, 'kdc.conf.%s' % name)
|
|
Packit |
fd8b60 |
kdc_conf = _cfg_merge(self._kdc_conf, kdc_conf)
|
|
Packit |
fd8b60 |
self._create_conf(kdc_conf, kdc_conf_path)
|
|
Packit |
fd8b60 |
else:
|
|
Packit |
fd8b60 |
kdc_conf_path = None
|
|
Packit |
fd8b60 |
return self._make_env(krb5_conf_path, kdc_conf_path)
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
def multipass_realms(**keywords):
|
|
Packit |
fd8b60 |
global _current_pass, _passes, testpass
|
|
Packit |
fd8b60 |
caller_krb5_conf = keywords.get('krb5_conf')
|
|
Packit |
fd8b60 |
caller_kdc_conf = keywords.get('kdc_conf')
|
|
Packit |
fd8b60 |
for p in _passes:
|
|
Packit |
fd8b60 |
(name, krbtgt_keysalt, krb5_conf, kdc_conf) = p
|
|
Packit |
fd8b60 |
if testpass and name != testpass:
|
|
Packit |
fd8b60 |
continue
|
|
Packit |
fd8b60 |
output('*** Beginning pass %s\n' % name)
|
|
Packit |
fd8b60 |
keywords['krb5_conf'] = _cfg_merge(krb5_conf, caller_krb5_conf)
|
|
Packit |
fd8b60 |
keywords['kdc_conf'] = _cfg_merge(kdc_conf, caller_kdc_conf)
|
|
Packit |
fd8b60 |
keywords['krbtgt_keysalt'] = krbtgt_keysalt
|
|
Packit |
fd8b60 |
_current_pass = name
|
|
Packit |
fd8b60 |
realm = K5Realm(**keywords)
|
|
Packit |
fd8b60 |
yield realm
|
|
Packit |
fd8b60 |
realm.stop()
|
|
Packit |
fd8b60 |
_current_pass = None
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
def multidb_realms(**keywords):
|
|
Packit |
fd8b60 |
global _current_db, _dbpasses
|
|
Packit |
fd8b60 |
caller_kdc_conf = keywords.get('kdc_conf')
|
|
Packit |
fd8b60 |
for p in _dbpasses:
|
|
Packit |
fd8b60 |
(name, kdc_conf) = p
|
|
Packit |
fd8b60 |
output('*** Using DB type %s\n' % name)
|
|
Packit |
fd8b60 |
keywords['kdc_conf'] = _cfg_merge(kdc_conf, caller_kdc_conf)
|
|
Packit |
fd8b60 |
_current_db = name
|
|
Packit |
fd8b60 |
realm = K5Realm(**keywords)
|
|
Packit |
fd8b60 |
yield realm
|
|
Packit |
fd8b60 |
realm.stop()
|
|
Packit |
fd8b60 |
_current_db = None
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
def cross_realms(num, xtgts=None, args=None, **keywords):
|
|
Packit |
fd8b60 |
# Build keyword args for each realm.
|
|
Packit |
fd8b60 |
realm_args = []
|
|
Packit |
fd8b60 |
for i in range(num):
|
|
Packit |
fd8b60 |
realmnumber = i + 1
|
|
Packit |
fd8b60 |
# Start with any global keyword arguments to this function.
|
|
Packit |
fd8b60 |
a = keywords.copy()
|
|
Packit |
fd8b60 |
if args and args[i]:
|
|
Packit |
fd8b60 |
# Merge in specific arguments for this realm. Use
|
|
Packit |
fd8b60 |
# _cfg_merge for config fragments.
|
|
Packit |
fd8b60 |
a.update(args[i])
|
|
Packit |
fd8b60 |
for cf in ('krb5_conf', 'kdc_conf'):
|
|
Packit |
fd8b60 |
if cf in keywords and cf in args[i]:
|
|
Packit |
fd8b60 |
a[cf] = _cfg_merge(keywords[cf], args[i][cf])
|
|
Packit |
fd8b60 |
# Set defaults for the realm name, testdir, and portbase.
|
|
Packit |
fd8b60 |
if not 'realm' in a:
|
|
Packit |
fd8b60 |
a['realm'] = 'KRBTEST%d.COM' % realmnumber
|
|
Packit |
fd8b60 |
if not 'testdir' in a:
|
|
Packit |
fd8b60 |
a['testdir'] = os.path.join('testdir', str(realmnumber))
|
|
Packit |
fd8b60 |
if not 'portbase' in a:
|
|
Packit |
fd8b60 |
a['portbase'] = 61000 + 10 * realmnumber
|
|
Packit |
fd8b60 |
realm_args.append(a)
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
# Build a [realms] config fragment containing all of the realms.
|
|
Packit |
fd8b60 |
realmsection = { '$realm' : None }
|
|
Packit |
fd8b60 |
for a in realm_args:
|
|
Packit |
fd8b60 |
name = a['realm']
|
|
Packit |
fd8b60 |
portbase = a['portbase']
|
|
Packit |
fd8b60 |
realmsection[name] = {
|
|
Packit |
fd8b60 |
'kdc' : '$hostname:%d' % portbase,
|
|
Packit |
fd8b60 |
'admin_server' : '$hostname:%d' % (portbase + 1),
|
|
Packit |
fd8b60 |
'kpasswd_server' : '$hostname:%d' % (portbase + 2)
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
realmscfg = {'realms': realmsection}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
# Set realmsection in each realm's krb5_conf keyword argument.
|
|
Packit |
fd8b60 |
for a in realm_args:
|
|
Packit |
fd8b60 |
a['krb5_conf'] = _cfg_merge(realmscfg, a.get('krb5_conf'))
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
if xtgts is None:
|
|
Packit |
fd8b60 |
# Default to cross tgts for every pair of realms.
|
|
Packit |
fd8b60 |
# (itertools.permutations would work here but is new in 2.6.)
|
|
Packit |
fd8b60 |
xtgts = [(x,y) for x in range(num) for y in range(num) if x != y]
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
# Create the realms.
|
|
Packit |
fd8b60 |
realms = []
|
|
Packit |
fd8b60 |
for i in range(num):
|
|
Packit |
fd8b60 |
r = K5Realm(**realm_args[i])
|
|
Packit |
fd8b60 |
# Create specified cross TGTs in this realm's db.
|
|
Packit |
fd8b60 |
for j in range(num):
|
|
Packit |
fd8b60 |
if j == i:
|
|
Packit |
fd8b60 |
continue
|
|
Packit |
fd8b60 |
iname = r.realm
|
|
Packit |
fd8b60 |
jname = realm_args[j]['realm']
|
|
Packit |
fd8b60 |
if (i, j) in xtgts:
|
|
Packit |
fd8b60 |
# This realm can authenticate to realm j.
|
|
Packit |
fd8b60 |
r.addprinc('krbtgt/%s' % jname, password('cr-%d-%d-' % (i, j)))
|
|
Packit |
fd8b60 |
if (j, i) in xtgts:
|
|
Packit |
fd8b60 |
# Realm j can authenticate to this realm.
|
|
Packit |
fd8b60 |
r.addprinc('krbtgt/%s@%s' % (iname, jname),
|
|
Packit |
fd8b60 |
password('cr-%d-%d-' % (j, i)))
|
|
Packit |
fd8b60 |
realms.append(r)
|
|
Packit |
fd8b60 |
return realms
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
_default_krb5_conf = {
|
|
Packit |
fd8b60 |
'libdefaults': {
|
|
Packit |
fd8b60 |
'default_realm': '$realm',
|
|
Packit |
fd8b60 |
'dns_lookup_kdc': 'false',
|
|
Packit |
fd8b60 |
'plugin_base_dir': '$plugins'},
|
|
Packit |
fd8b60 |
'realms': {'$realm': {
|
|
Packit |
fd8b60 |
'kdc': '$hostname:$port0',
|
|
Packit |
fd8b60 |
'admin_server': '$hostname:$port1',
|
|
Packit |
fd8b60 |
'kpasswd_server': '$hostname:$port2'}}}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
_default_kdc_conf = {
|
|
Packit |
fd8b60 |
'realms': {'$realm': {
|
|
Packit |
fd8b60 |
'database_module': 'db',
|
|
Packit |
fd8b60 |
'iprop_port': '$port4',
|
|
Packit |
fd8b60 |
'key_stash_file': '$testdir/stash',
|
|
Packit |
fd8b60 |
'acl_file': '$testdir/acl',
|
|
Packit |
fd8b60 |
'dictfile': '$testdir/dictfile',
|
|
Packit |
fd8b60 |
'kadmind_port': '$port1',
|
|
Packit |
fd8b60 |
'kpasswd_port': '$port2',
|
|
Packit |
fd8b60 |
'kdc_listen': '$port0',
|
|
Packit |
fd8b60 |
'kdc_tcp_listen': '$port0'}},
|
|
Packit |
fd8b60 |
'dbmodules': {
|
|
Packit |
fd8b60 |
'db_module_dir': '$plugins/kdb',
|
|
Packit |
fd8b60 |
'db': {'db_library': 'db2', 'database_name' : '$testdir/db'}},
|
|
Packit |
fd8b60 |
'logging': {
|
|
Packit |
fd8b60 |
'admin_server': 'FILE:$testdir/kadmind5.log',
|
|
Packit |
fd8b60 |
'kdc': 'FILE:$testdir/kdc.log',
|
|
Packit |
fd8b60 |
'default': 'FILE:$testdir/others.log'}}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
_lmdb_kdc_conf = {'dbmodules': {'db': {'db_library': 'klmdb',
|
|
Packit |
fd8b60 |
'nosync': 'true'}}}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
# A pass is a tuple of: name, krbtgt_keysalt, krb5_conf, kdc_conf.
|
|
Packit |
fd8b60 |
_passes = [
|
|
Packit |
fd8b60 |
# No special settings; exercises AES256.
|
|
Packit |
fd8b60 |
('default', None, None, None),
|
|
Packit |
fd8b60 |
|
|
Packit Service |
a81408 |
# Exercise the DES3 enctype.
|
|
Packit Service |
a81408 |
('des3', None,
|
|
Packit Service |
a81408 |
{'libdefaults': {'permitted_enctypes': 'des3'}},
|
|
Packit Service |
a81408 |
{'realms': {'$realm': {
|
|
Packit Service |
a81408 |
'supported_enctypes': 'des3-cbc-sha1:normal',
|
|
Packit Service |
a81408 |
'master_key_type': 'des3-cbc-sha1'}}}),
|
|
Packit Service |
a81408 |
|
|
Packit |
fd8b60 |
# Exercise the arcfour enctype.
|
|
Packit |
fd8b60 |
('arcfour', None,
|
|
Packit |
fd8b60 |
{'libdefaults': {'permitted_enctypes': 'rc4'}},
|
|
Packit |
fd8b60 |
{'realms': {'$realm': {
|
|
Packit |
fd8b60 |
'supported_enctypes': 'arcfour-hmac:normal',
|
|
Packit |
fd8b60 |
'master_key_type': 'arcfour-hmac'}}}),
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
# Exercise the AES128 enctype.
|
|
Packit |
fd8b60 |
('aes128', None,
|
|
Packit |
fd8b60 |
{'libdefaults': {'permitted_enctypes': 'aes128-cts'}},
|
|
Packit |
fd8b60 |
{'realms': {'$realm': {
|
|
Packit |
fd8b60 |
'supported_enctypes': 'aes128-cts:normal',
|
|
Packit |
fd8b60 |
'master_key_type': 'aes128-cts'}}}),
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
# Exercise the camellia256-cts enctype.
|
|
Packit |
fd8b60 |
('camellia256', None,
|
|
Packit |
fd8b60 |
{'libdefaults': {'permitted_enctypes': 'camellia256-cts'}},
|
|
Packit |
fd8b60 |
{'realms': {'$realm': {
|
|
Packit |
fd8b60 |
'supported_enctypes': 'camellia256-cts:normal',
|
|
Packit |
fd8b60 |
'master_key_type': 'camellia256-cts'}}}),
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
# Exercise the aes128-sha2 enctype.
|
|
Packit |
fd8b60 |
('aes128-sha2', None,
|
|
Packit |
fd8b60 |
{'libdefaults': {'permitted_enctypes': 'aes128-sha2'}},
|
|
Packit |
fd8b60 |
{'realms': {'$realm': {
|
|
Packit |
fd8b60 |
'supported_enctypes': 'aes128-sha2:normal',
|
|
Packit |
fd8b60 |
'master_key_type': 'aes128-sha2'}}}),
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
# Exercise the aes256-sha2 enctype.
|
|
Packit |
fd8b60 |
('aes256-sha2', None,
|
|
Packit |
fd8b60 |
{'libdefaults': {'permitted_enctypes': 'aes256-sha2'}},
|
|
Packit |
fd8b60 |
{'realms': {'$realm': {
|
|
Packit |
fd8b60 |
'supported_enctypes': 'aes256-sha2:normal',
|
|
Packit |
fd8b60 |
'master_key_type': 'aes256-sha2'}}}),
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
# Test a setup with modern principal keys but an old TGT key.
|
|
Packit |
fd8b60 |
('aes256.destgt', 'arcfour-hmac:normal',
|
|
Packit |
fd8b60 |
{'libdefaults': {'allow_weak_crypto': 'true'}},
|
|
Packit |
fd8b60 |
None)
|
|
Packit |
fd8b60 |
]
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
_success = False
|
|
Packit |
fd8b60 |
_current_pass = None
|
|
Packit |
fd8b60 |
_current_db = None
|
|
Packit |
fd8b60 |
_daemons = []
|
|
Packit |
fd8b60 |
_parse_args()
|
|
Packit |
fd8b60 |
atexit.register(_onexit)
|
|
Packit |
fd8b60 |
signal.signal(signal.SIGINT, _onsigint)
|
|
Packit |
fd8b60 |
_outfile = open('testlog', 'w')
|
|
Packit |
fd8b60 |
_cmd_index = 1
|
|
Packit |
fd8b60 |
_last_mark = None
|
|
Packit |
fd8b60 |
_last_cmd = None
|
|
Packit |
fd8b60 |
_last_cmd_output = None
|
|
Packit |
fd8b60 |
buildtop = _find_buildtop()
|
|
Packit |
fd8b60 |
srctop = _find_srctop()
|
|
Packit |
fd8b60 |
plugins = os.path.join(buildtop, 'plugins')
|
|
Packit |
fd8b60 |
runenv = _import_runenv()
|
|
Packit |
fd8b60 |
hostname = _get_hostname()
|
|
Packit |
fd8b60 |
null_input = open(os.devnull, 'r')
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
# A DB pass is a tuple of: name, kdc_conf.
|
|
Packit |
fd8b60 |
_dbpasses = [('db2', None)]
|
|
Packit |
fd8b60 |
if runenv.have_lmdb == 'yes':
|
|
Packit |
fd8b60 |
_dbpasses.append(('lmdb', _lmdb_kdc_conf))
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
krb5kdc = os.path.join(buildtop, 'kdc', 'krb5kdc')
|
|
Packit |
fd8b60 |
kadmind = os.path.join(buildtop, 'kadmin', 'server', 'kadmind')
|
|
Packit |
fd8b60 |
kadmin = os.path.join(buildtop, 'kadmin', 'cli', 'kadmin')
|
|
Packit |
fd8b60 |
kadminl = os.path.join(buildtop, 'kadmin', 'cli', 'kadmin.local')
|
|
Packit |
fd8b60 |
kdb5_ldap_util = os.path.join(buildtop, 'plugins', 'kdb', 'ldap', 'ldap_util',
|
|
Packit |
fd8b60 |
'kdb5_ldap_util')
|
|
Packit |
fd8b60 |
kdb5_util = os.path.join(buildtop, 'kadmin', 'dbutil', 'kdb5_util')
|
|
Packit |
fd8b60 |
ktutil = os.path.join(buildtop, 'kadmin', 'ktutil', 'ktutil')
|
|
Packit |
fd8b60 |
kinit = os.path.join(buildtop, 'clients', 'kinit', 'kinit')
|
|
Packit |
fd8b60 |
klist = os.path.join(buildtop, 'clients', 'klist', 'klist')
|
|
Packit |
fd8b60 |
kswitch = os.path.join(buildtop, 'clients', 'kswitch', 'kswitch')
|
|
Packit |
fd8b60 |
kvno = os.path.join(buildtop, 'clients', 'kvno', 'kvno')
|
|
Packit |
fd8b60 |
kdestroy = os.path.join(buildtop, 'clients', 'kdestroy', 'kdestroy')
|
|
Packit |
fd8b60 |
kpasswd = os.path.join(buildtop, 'clients', 'kpasswd', 'kpasswd')
|
|
Packit |
fd8b60 |
t_inetd = os.path.join(buildtop, 'tests', 'dejagnu', 't_inetd')
|
|
Packit |
fd8b60 |
kproplog = os.path.join(buildtop, 'kprop', 'kproplog')
|
|
Packit |
fd8b60 |
kpropd = os.path.join(buildtop, 'kprop', 'kpropd')
|
|
Packit |
fd8b60 |
kprop = os.path.join(buildtop, 'kprop', 'kprop')
|