xref: /freebsd/contrib/pam-krb5/tests/pam-util/logging-t.c (revision d0ff5773cefaf3fa41b1be3e44ca35bd9d5f68ee)
1 /*
2  * PAM logging test suite.
3  *
4  * The canonical version of this file is maintained in the rra-c-util package,
5  * which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
6  *
7  * Written by Russ Allbery <eagle@eyrie.org>
8  * Copyright 2020 Russ Allbery <eagle@eyrie.org>
9  * Copyright 2010-2013
10  *     The Board of Trustees of the Leland Stanford Junior University
11  *
12  * Permission is hereby granted, free of charge, to any person obtaining a
13  * copy of this software and associated documentation files (the "Software"),
14  * to deal in the Software without restriction, including without limitation
15  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
16  * and/or sell copies of the Software, and to permit persons to whom the
17  * Software is furnished to do so, subject to the following conditions:
18  *
19  * The above copyright notice and this permission notice shall be included in
20  * all copies or substantial portions of the Software.
21  *
22  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
25  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
28  * DEALINGS IN THE SOFTWARE.
29  *
30  * SPDX-License-Identifier: MIT
31  */
32 
33 #include <config.h>
34 #include <portable/pam.h>
35 #include <portable/system.h>
36 
37 #include <syslog.h>
38 
39 #include <pam-util/args.h>
40 #include <pam-util/logging.h>
41 #include <tests/fakepam/pam.h>
42 #include <tests/tap/basic.h>
43 #include <tests/tap/string.h>
44 
45 /* Test a normal PAM logging function. */
46 #define TEST(func, p, n)                                          \
47     do {                                                          \
48         (func)(args, "%s", "foo");                                \
49         seen = pam_output();                                      \
50         is_int((p), seen->lines[0].priority, "priority %d", (p)); \
51         is_string("foo", seen->lines[0].line, "line %s", (n));    \
52         pam_output_free(seen);                                    \
53     } while (0)
54 
55 /* Test a PAM error logging function. */
56 #define TEST_PAM(func, c, p, n)                                   \
57     do {                                                          \
58         (func)(args, (c), "%s", "bar");                           \
59         if ((c) == PAM_SUCCESS)                                   \
60             expected = strdup("bar");                             \
61         else                                                      \
62             basprintf(&expected, "%s: %s", "bar",                 \
63                       pam_strerror(args->pamh, c));               \
64         seen = pam_output();                                      \
65         is_int((p), seen->lines[0].priority, "priority %s", (n)); \
66         is_string(expected, seen->lines[0].line, "line %s", (n)); \
67         pam_output_free(seen);                                    \
68         free(expected);                                           \
69     } while (0)
70 
71 /* Test a PAM Kerberos error logging function .*/
72 #define TEST_KRB5(func, p, n)                                             \
73     do {                                                                  \
74         const char *msg;                                                  \
75                                                                           \
76         code = krb5_parse_name(args->ctx, "foo@bar@EXAMPLE.COM", &princ); \
77         (func)(args, code, "%s", "krb");                                  \
78         code = krb5_parse_name(args->ctx, "foo@bar@EXAMPLE.COM", &princ); \
79         msg = krb5_get_error_message(args->ctx, code);                    \
80         basprintf(&expected, "%s: %s", "krb", msg);                       \
81         seen = pam_output();                                              \
82         is_int((p), seen->lines[0].priority, "priority %s", (n));         \
83         is_string(expected, seen->lines[0].line, "line %s", (n));         \
84         pam_output_free(seen);                                            \
85         free(expected);                                                   \
86         krb5_free_error_message(args->ctx, msg);                          \
87     } while (0)
88 
89 
90 int
91 main(void)
92 {
93     pam_handle_t *pamh;
94     struct pam_args *args;
95     struct pam_conv conv = {NULL, NULL};
96     char *expected;
97     struct output *seen;
98 #ifdef HAVE_KRB5
99     krb5_error_code code;
100     krb5_principal princ;
101 #endif
102 
103     plan(27);
104 
105     if (pam_start("test", NULL, &conv, &pamh) != PAM_SUCCESS)
106         sysbail("Fake PAM initialization failed");
107     args = putil_args_new(pamh, 0);
108     if (args == NULL)
109         bail("cannot create PAM argument struct");
110     TEST(putil_crit, LOG_CRIT, "putil_crit");
111     TEST(putil_err, LOG_ERR, "putil_err");
112     putil_debug(args, "%s", "foo");
113     ok(pam_output() == NULL, "putil_debug without debug on");
114     args->debug = true;
115     TEST(putil_debug, LOG_DEBUG, "putil_debug");
116     args->debug = false;
117 
118     TEST_PAM(putil_crit_pam, PAM_SYSTEM_ERR, LOG_CRIT, "putil_crit_pam S");
119     TEST_PAM(putil_crit_pam, PAM_BUF_ERR, LOG_CRIT, "putil_crit_pam B");
120     TEST_PAM(putil_crit_pam, PAM_SUCCESS, LOG_CRIT, "putil_crit_pam ok");
121     TEST_PAM(putil_err_pam, PAM_SYSTEM_ERR, LOG_ERR, "putil_err_pam");
122     putil_debug_pam(args, PAM_SYSTEM_ERR, "%s", "bar");
123     ok(pam_output() == NULL, "putil_debug_pam without debug on");
124     args->debug = true;
125     TEST_PAM(putil_debug_pam, PAM_SYSTEM_ERR, LOG_DEBUG, "putil_debug_pam");
126     TEST_PAM(putil_debug_pam, PAM_SUCCESS, LOG_DEBUG, "putil_debug_pam ok");
127     args->debug = false;
128 
129 #ifdef HAVE_KRB5
130     TEST_KRB5(putil_crit_krb5, LOG_CRIT, "putil_crit_krb5");
131     TEST_KRB5(putil_err_krb5, LOG_ERR, "putil_err_krb5");
132     code = krb5_parse_name(args->ctx, "foo@bar@EXAMPLE.COM", &princ);
133     putil_debug_krb5(args, code, "%s", "krb");
134     ok(pam_output() == NULL, "putil_debug_krb5 without debug on");
135     args->debug = true;
136     TEST_KRB5(putil_debug_krb5, LOG_DEBUG, "putil_debug_krb5");
137     args->debug = false;
138 #else
139     skip_block(4, "not built with Kerberos support");
140 #endif
141 
142     putil_args_free(args);
143     pam_end(pamh, 0);
144 
145     return 0;
146 }
147