xref: /freebsd/contrib/pam-krb5/tests/fakepam/README (revision bf6873c5786e333d679a7838d28812febf479a8a)
1*bf6873c5SCy Schubert                          PAM Testing Framework
2*bf6873c5SCy Schubert
3*bf6873c5SCy SchubertOverview
4*bf6873c5SCy Schubert
5*bf6873c5SCy Schubert    The files in this directory provide a shim PAM library that's used for
6*bf6873c5SCy Schubert    testing and a test framework used to exercise a PAM module.
7*bf6873c5SCy Schubert
8*bf6873c5SCy Schubert    This library and its include files define the minimum amount
9*bf6873c5SCy Schubert    of the PAM module interface so that PAM modules can be tested without
10*bf6873c5SCy Schubert    such problems as needing configuration files in /etc/pam.d or needing
11*bf6873c5SCy Schubert    changes to the system configuration to run a testing PAM module
12*bf6873c5SCy Schubert    instead of the normal system PAM modules.
13*bf6873c5SCy Schubert
14*bf6873c5SCy Schubert    The goal of this library is that all PAM code should be able to be
15*bf6873c5SCy Schubert    left unchanged and the code just linked with the fakepam library
16*bf6873c5SCy Schubert    rather than the regular PAM library.  The testing code can then call
17*bf6873c5SCy Schubert    pam_start and pam_end as defined in the fakepam/pam.h header file and
18*bf6873c5SCy Schubert    inspect internal PAM state as needed.
19*bf6873c5SCy Schubert
20*bf6873c5SCy Schubert    The library also provides an interface to exercise a PAM module via an
21*bf6873c5SCy Schubert    interaction script, so that as much of the testing process as possible
22*bf6873c5SCy Schubert    is moved into simple text files instead of C code.  That test script
23*bf6873c5SCy Schubert    format supports specifying the PAM configuration, the PAM interfaces
24*bf6873c5SCy Schubert    to run, the expected prompts and replies, and the expected log
25*bf6873c5SCy Schubert    messages.  That interface is defined in fakepam/script.h.
26*bf6873c5SCy Schubert
27*bf6873c5SCy SchubertFake PAM Library
28*bf6873c5SCy Schubert
29*bf6873c5SCy Schubert    Unfortunately, the standard PAM library for most operating systems
30*bf6873c5SCy Schubert    does not provide a reasonable testing framework.  The primary problem
31*bf6873c5SCy Schubert    is configuration: the PAM library usually hard-codes a configuration
32*bf6873c5SCy Schubert    location such as /etc/pam.conf or /etc/pam.d/<application>.  But there
33*bf6873c5SCy Schubert    are other problems as well, such as capturing logging rather than
34*bf6873c5SCy Schubert    having it go to syslog and inspecting PAM internal state to make sure
35*bf6873c5SCy Schubert    that it's updated properly by the module.
36*bf6873c5SCy Schubert
37*bf6873c5SCy Schubert    This library implements some of the same API as the system PAM library
38*bf6873c5SCy Schubert    and uses the system PAM library headers, but the underlying
39*bf6873c5SCy Schubert    implementation does not call the system PAM library or dynamically
40*bf6873c5SCy Schubert    load modules.  Instead, it's meant to be linked into a single
41*bf6873c5SCy Schubert    executable along with the implementation of a PAM module.  It does not
42*bf6873c5SCy Schubert    provide most of the application-level PAM interfaces (so one cannot
43*bf6873c5SCy Schubert    link a PAM-using application against it), just the interfaces called
44*bf6873c5SCy Schubert    by a module.  The caller of the library can then call the module API
45*bf6873c5SCy Schubert    (such as pam_sm_authenticate) directly.
46*bf6873c5SCy Schubert
47*bf6873c5SCy Schubert    All of the internal state maintained by the PAM library is made
48*bf6873c5SCy Schubert    available to the test program linked with this library.  See
49*bf6873c5SCy Schubert    fakepam/pam.h for the data structures.  This allows verification that
50*bf6873c5SCy Schubert    the PAM module is setting the internal PAM state properly.
51*bf6873c5SCy Schubert
52*bf6873c5SCy Schubert  User Handling
53*bf6873c5SCy Schubert
54*bf6873c5SCy Schubert    In order to write good test suites, one often has to be able to
55*bf6873c5SCy Schubert    authenticate as a variety of users, but PAM modules may expect the
56*bf6873c5SCy Schubert    authenticating user to exist on the system.  The fakepam library
57*bf6873c5SCy Schubert    provides a pam_modutil_getpwnam (if available) or a getpwnam
58*bf6873c5SCy Schubert    implementation that returns information for a single user (and user
59*bf6873c5SCy Schubert    unknown for everyone else).  To set the information for the one valid
60*bf6873c5SCy Schubert    user, call the pam_set_pwd function and provide a struct passwd that
61*bf6873c5SCy Schubert    will be returned by pam_modutil_getpwnam.
62*bf6873c5SCy Schubert
63*bf6873c5SCy Schubert    The fakepam library also provides a replacement krb5_kuserok function
64*bf6873c5SCy Schubert    for testing PAM modules that use Kerberos.  This source file should
65*bf6873c5SCy Schubert    only be included in packages that are building with Kerberos.  It
66*bf6873c5SCy Schubert    implements the same functionality as the default krb5_kuserok
67*bf6873c5SCy Schubert    function, but looks for .k5login in the home directory configured by
68*bf6873c5SCy Schubert    the test framework instead of using getpwnam.
69*bf6873c5SCy Schubert
70*bf6873c5SCy Schubert    Only those two functions are intercepted, so if the module looks up
71*bf6873c5SCy Schubert    users in other ways, it may still bypass the fakepam library and look
72*bf6873c5SCy Schubert    at system users.
73*bf6873c5SCy Schubert
74*bf6873c5SCy Schubert  Output Handling
75*bf6873c5SCy Schubert
76*bf6873c5SCy Schubert    The fakepam library intercepts the PAM functions that would normally
77*bf6873c5SCy Schubert    log to syslog and instead accumulates the output in a static string
78*bf6873c5SCy Schubert    variable.  To retrieve the logging output so far, call pam_output,
79*bf6873c5SCy Schubert    which returns a struct of all the output strings up to that point and
80*bf6873c5SCy Schubert    resets the accumulated output.
81*bf6873c5SCy Schubert
82*bf6873c5SCy SchubertScripted PAM Testing
83*bf6873c5SCy Schubert
84*bf6873c5SCy Schubert    Also provided as part of the fakepam library is a test framework for
85*bf6873c5SCy Schubert    testing PAM modules.  This test framework allows most of the testing
86*bf6873c5SCy Schubert    process to be encapsulated in a text configuration file per test,
87*bf6873c5SCy Schubert    rather than in a tedious set of checks and calls written in C.
88*bf6873c5SCy Schubert
89*bf6873c5SCy Schubert  Test API
90*bf6873c5SCy Schubert
91*bf6873c5SCy Schubert    The basic test API is to call either run_script (to run a single test
92*bf6873c5SCy Schubert    script) or run_script_dir (to run all scripts in a particular
93*bf6873c5SCy Schubert    directory).  Both take a configuration struct that controls how the
94*bf6873c5SCy Schubert    PAM library is set up and called.
95*bf6873c5SCy Schubert
96*bf6873c5SCy Schubert    That configuration struct takes the following elements:
97*bf6873c5SCy Schubert
98*bf6873c5SCy Schubert    user
99*bf6873c5SCy Schubert        The user as which to authenticate, passed into pam_start and also
100*bf6873c5SCy Schubert        substituted for the %u escape.  This should match the user whose
101*bf6873c5SCy Schubert        home directory information is configured using pam_set_pwd if that
102*bf6873c5SCy Schubert        function is in use.
103*bf6873c5SCy Schubert
104*bf6873c5SCy Schubert    password
105*bf6873c5SCy Schubert        Only used for the %p escape.  This is not used to set the
106*bf6873c5SCy Schubert        authentication token in the PAM library (see authtok below).
107*bf6873c5SCy Schubert
108*bf6873c5SCy Schubert    newpass
109*bf6873c5SCy Schubert        Only used for the %n escape.
110*bf6873c5SCy Schubert
111*bf6873c5SCy Schubert    extra
112*bf6873c5SCy Schubert        An array of up to 10 additional strings used by the %0 through %9
113*bf6873c5SCy Schubert        escapes when parsing the configuration file, as discussed below.
114*bf6873c5SCy Schubert
115*bf6873c5SCy Schubert    authtok
116*bf6873c5SCy Schubert        Sets the default value of the PAM_AUTHTOK data item.  This will be
117*bf6873c5SCy Schubert        set immediately after initializing the PAM library and before
118*bf6873c5SCy Schubert        calling any PAM module functions.
119*bf6873c5SCy Schubert
120*bf6873c5SCy Schubert    authtok
121*bf6873c5SCy Schubert        Like authtok, but for the PAM_OLDAUTHTOK data item.
122*bf6873c5SCy Schubert
123*bf6873c5SCy Schubert    callback
124*bf6873c5SCy Schubert        This, and the associated data element, specifies a callback that's
125*bf6873c5SCy Schubert        called at the end of processing of the script before calling
126*bf6873c5SCy Schubert        pam_end.  This can be used to inspect and verify the internal
127*bf6873c5SCy Schubert        state of PAM.  The data element is an opaque pointer passed into
128*bf6873c5SCy Schubert        the callback.
129*bf6873c5SCy Schubert
130*bf6873c5SCy Schubert  Test Script Basic Format
131*bf6873c5SCy Schubert
132*bf6873c5SCy Schubert    Test scripts are composed of one or more sections.  Each section
133*bf6873c5SCy Schubert    begins with:
134*bf6873c5SCy Schubert
135*bf6873c5SCy Schubert        [<section>]
136*bf6873c5SCy Schubert
137*bf6873c5SCy Schubert    starting in column 1, where <section> is the name of the section.  The
138*bf6873c5SCy Schubert    valid section types and the format of their contents are described
139*bf6873c5SCy Schubert    below.
140*bf6873c5SCy Schubert
141*bf6873c5SCy Schubert    Blank lines and lines starting with # are ignored.
142*bf6873c5SCy Schubert
143*bf6873c5SCy Schubert    Several strings undergo %-escape expansion as mentioned below.  For
144*bf6873c5SCy Schubert    any such string, the following escapes are supported:
145*bf6873c5SCy Schubert
146*bf6873c5SCy Schubert        %i      Current UID (not the UID of the target user)
147*bf6873c5SCy Schubert        %n      New password
148*bf6873c5SCy Schubert        %p      Password
149*bf6873c5SCy Schubert        %u      Username
150*bf6873c5SCy Schubert        %0      extra[0]
151*bf6873c5SCy Schubert        ...
152*bf6873c5SCy Schubert        %9      extra[9]
153*bf6873c5SCy Schubert
154*bf6873c5SCy Schubert    All of these are set in the script_config struct.
155*bf6873c5SCy Schubert
156*bf6873c5SCy Schubert    Regular expression matching is supported for output lines and for
157*bf6873c5SCy Schubert    prompts.  To mark an expected prompt or output line as a regular
158*bf6873c5SCy Schubert    expression, it must begin and end with a slash (/).  Slashes inside
159*bf6873c5SCy Schubert    the regular expression do not need to be escaped.  If regular
160*bf6873c5SCy Schubert    expression support is not available in the C library, those matching
161*bf6873c5SCy Schubert    tests will be skipped.
162*bf6873c5SCy Schubert
163*bf6873c5SCy Schubert  The [options] Section
164*bf6873c5SCy Schubert
165*bf6873c5SCy Schubert    The [options] section contains the PAM configuration that will be
166*bf6873c5SCy Schubert    passed to the module.  These are the options that are normally listed
167*bf6873c5SCy Schubert    in the PAM configuration file after the name of the module.  The
168*bf6873c5SCy Schubert    syntax of this section is one or more lines of the form:
169*bf6873c5SCy Schubert
170*bf6873c5SCy Schubert        <group> = <options>
171*bf6873c5SCy Schubert
172*bf6873c5SCy Schubert    where <group> is one of "account", "auth", "password", or "session".
173*bf6873c5SCy Schubert    The options are space-delimited and may be either option names or
174*bf6873c5SCy Schubert    option=value pairs.
175*bf6873c5SCy Schubert
176*bf6873c5SCy Schubert  The [run] Section
177*bf6873c5SCy Schubert
178*bf6873c5SCy Schubert    The [run] section specifies what PAM interfaces to call.  It consists
179*bf6873c5SCy Schubert    of one or more lines in the format:
180*bf6873c5SCy Schubert
181*bf6873c5SCy Schubert        <call> = <status>
182*bf6873c5SCy Schubert
183*bf6873c5SCy Schubert    where <call> is the PAM call to make and <status> is the status code
184*bf6873c5SCy Schubert    that it should return.  <call> is one of the PAM module interface
185*bf6873c5SCy Schubert    functions without the leading "pam_sm_", so one of "acct_mgmt",
186*bf6873c5SCy Schubert    "authenticate", "setcred", "chauthtok", "open_session", or
187*bf6873c5SCy Schubert    "close_session".  The return status is one of the PAM constants
188*bf6873c5SCy Schubert    defined for return status, such as PAM_IGNORE or PAM_SUCCESS.  The
189*bf6873c5SCy Schubert    test framework will ensure that the PAM call returns the appropriate
190*bf6873c5SCy Schubert    status.
191*bf6873c5SCy Schubert
192*bf6873c5SCy Schubert    The <call> may be optionally followed by an open parentheses and then
193*bf6873c5SCy Schubert    a list of flags separated by |, or syntactically:
194*bf6873c5SCy Schubert
195*bf6873c5SCy Schubert        <call>(<flag>|<flag>|...) = <status>
196*bf6873c5SCy Schubert
197*bf6873c5SCy Schubert    In this form, rather than passing a flags value of 0 to the PAM call,
198*bf6873c5SCy Schubert    the test framework will pass the combination of the provided flags.
199*bf6873c5SCy Schubert    The flags are PAM constants without the leading PAM_, so (for example)
200*bf6873c5SCy Schubert    DELETE_CRED, ESTABLISH_CRED, REFRESH_CRED, or REINITIALIZE_CRED for
201*bf6873c5SCy Schubert    the "setcred" call.
202*bf6873c5SCy Schubert
203*bf6873c5SCy Schubert    As a special case, <call> may be "end" to specify flags to pass to the
204*bf6873c5SCy Schubert    pam_end call (such as PAM_DATA_SILENT).
205*bf6873c5SCy Schubert
206*bf6873c5SCy Schubert  The [end] Section
207*bf6873c5SCy Schubert
208*bf6873c5SCy Schubert    The [end] section defines how to call pam_end.  It currently takes
209*bf6873c5SCy Schubert    only one setting, flags, the syntax of which is:
210*bf6873c5SCy Schubert
211*bf6873c5SCy Schubert        flags = <flag>|<flag>
212*bf6873c5SCy Schubert
213*bf6873c5SCy Schubert    This allows PAM_DATA_SILENT or other flags to be passed to pam_end
214*bf6873c5SCy Schubert    when running the test script.
215*bf6873c5SCy Schubert
216*bf6873c5SCy Schubert  The [output] Section
217*bf6873c5SCy Schubert
218*bf6873c5SCy Schubert    The [output] section defines the logging output expected from the
219*bf6873c5SCy Schubert    module.  It consists of zero or more lines in the format:
220*bf6873c5SCy Schubert
221*bf6873c5SCy Schubert        <priority> <output>
222*bf6873c5SCy Schubert        <priority> /<regex>/
223*bf6873c5SCy Schubert
224*bf6873c5SCy Schubert    where <priority> is a syslog priority and <output> is the remaining
225*bf6873c5SCy Schubert    output or a regular expression to match against the output.  Valid
226*bf6873c5SCy Schubert    values for <priority> are DEBUG, INFO, NOTICE, ERR, and CRIT.
227*bf6873c5SCy Schubert    <output> and <regex> may contain spaces and undergoes %-escape
228*bf6873c5SCy Schubert    expansion.
229*bf6873c5SCy Schubert
230*bf6873c5SCy Schubert    The replacement values are taken from the script_config struct passed
231*bf6873c5SCy Schubert    as a parameter to run_script or run_script_dir.
232*bf6873c5SCy Schubert
233*bf6873c5SCy Schubert    If the [output] section is missing entirely, the test framework will
234*bf6873c5SCy Schubert    expect there to be no logging output from the PAM module.
235*bf6873c5SCy Schubert
236*bf6873c5SCy Schubert    This defines the logging output, not the prompts returned through the
237*bf6873c5SCy Schubert    conversation function.  For that, see the next section.
238*bf6873c5SCy Schubert
239*bf6873c5SCy Schubert  The [prompts] Section
240*bf6873c5SCy Schubert
241*bf6873c5SCy Schubert    The [prompts] section defines the prompts that the PAM module is
242*bf6873c5SCy Schubert    expected to send via the conversation function, and the responses that
243*bf6873c5SCy Schubert    the test harness will send back (if any).  This consists of zero or
244*bf6873c5SCy Schubert    more lines in one of the following formats:
245*bf6873c5SCy Schubert
246*bf6873c5SCy Schubert        <type> = <prompt>
247*bf6873c5SCy Schubert        <type> = /<prompt>/
248*bf6873c5SCy Schubert        <type> = <prompt>|<response>
249*bf6873c5SCy Schubert        <type> = /<prompt>/|<response>
250*bf6873c5SCy Schubert
251*bf6873c5SCy Schubert    The <type> is the style of prompt, chosen from "echo_off", "echo_on",
252*bf6873c5SCy Schubert    "error_msg", and "info".  The <prompt> is the actual prompt sent and
253*bf6873c5SCy Schubert    undergoes %-escape expansion.  It may be enclosed in slashes (/) to
254*bf6873c5SCy Schubert    indicate that it's a regular expression instead of literal text.  The
255*bf6873c5SCy Schubert    <response> if present (and its presence is signaled by the |
256*bf6873c5SCy Schubert    character) contains the response sent back by the test framework and
257*bf6873c5SCy Schubert    also undergoes %-escape expansion.  The response starts with the final
258*bf6873c5SCy Schubert    | character on the line, so <prompt> regular expressions may freely
259*bf6873c5SCy Schubert    use | inside the regular expression.
260*bf6873c5SCy Schubert
261*bf6873c5SCy Schubert    If the [prompts] section is present and empty, the test harness will
262*bf6873c5SCy Schubert    check that the PAM module does not send any prompts.  If the [prompts]
263*bf6873c5SCy Schubert    section is absent entirely, the conversation function passed to the
264*bf6873c5SCy Schubert    PAM module will be NULL.
265*bf6873c5SCy Schubert
266*bf6873c5SCy SchubertLicense
267*bf6873c5SCy Schubert
268*bf6873c5SCy Schubert    This file is part of the documentation of rra-c-util, which can be
269*bf6873c5SCy Schubert    found at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
270*bf6873c5SCy Schubert
271*bf6873c5SCy Schubert    Copyright 2011-2012, 2020-2021 Russ Allbery <eagle@eyrie.org>
272*bf6873c5SCy Schubert
273*bf6873c5SCy Schubert    Copying and distribution of this file, with or without modification,
274*bf6873c5SCy Schubert    are permitted in any medium without royalty provided the copyright
275*bf6873c5SCy Schubert    notice and this notice are preserved.  This file is offered as-is,
276*bf6873c5SCy Schubert    without any warranty.
277