1 /*
2  * PKINIT authentication tests for the pam-krb5 module.
3  *
4  * This test case includes tests that require a PKINIT certificate, but which
5  * don't write a Kerberos ticket cache.
6  *
7  * Written by Russ Allbery <eagle@eyrie.org>
8  * Copyright 2020 Russ Allbery <eagle@eyrie.org>
9  * Copyright 2012
10  *     The Board of Trustees of the Leland Stanford Junior University
11  *
12  * SPDX-License-Identifier: BSD-3-clause or GPL-1+
13  */
14 
15 #include <config.h>
16 #include <portable/system.h>
17 
18 #include <tests/fakepam/script.h>
19 #include <tests/tap/kerberos.h>
20 #include <tests/tap/process.h>
21 #include <tests/tap/string.h>
22 
23 
24 int
25 main(void)
26 {
27     struct script_config config;
28     struct kerberos_config *krbconf;
29 #if defined(HAVE_KRB5_MIT) && defined(PATH_OPENSSL)
30     const char **generate_pkcs12;
31     char *tmpdir, *pkcs12_path;
32 #endif
33 
34     /* Load the Kerberos principal and certificate path. */
35     krbconf = kerberos_setup(TAP_KRB_NEEDS_PKINIT);
36     memset(&config, 0, sizeof(config));
37     config.user = krbconf->pkinit_principal;
38     config.extra[0] = krbconf->pkinit_cert;
39 
40     /*
41      * Generate a testing krb5.conf file with a nonexistent default realm so
42      * that we can be sure that our principals will stay fully-qualified in
43      * the logs.
44      */
45     kerberos_generate_conf("bogus.example.com");
46 
47     /* Check things that are the same with both Kerberos implementations. */
48     plan_lazy();
49     run_script("data/scripts/pkinit/basic", &config);
50     run_script("data/scripts/pkinit/basic-debug", &config);
51     run_script("data/scripts/pkinit/prompt-use", &config);
52     run_script("data/scripts/pkinit/prompt-try", &config);
53     run_script("data/scripts/pkinit/try-pkinit", &config);
54 
55     /* Debugging output is a little different between the implementations. */
56 #ifdef HAVE_KRB5_HEIMDAL
57     run_script("data/scripts/pkinit/try-pkinit-debug", &config);
58 #else
59     run_script("data/scripts/pkinit/try-pkinit-debug-mit", &config);
60 #endif
61 
62     /* Only MIT Kerberos supports setting preauth options. */
63 #ifdef HAVE_KRB5_MIT
64     run_script("data/scripts/pkinit/preauth-opt-mit", &config);
65 #endif
66 
67     /*
68      * If OpenSSL is available, test prompting with MIT Kerberos since we have
69      * to implement the prompting for the use_pkinit case ourselves.  To do
70      * this, convert the input PKINIT certificate to a PKCS12 file with a
71      * password.
72      */
73 #if defined(HAVE_KRB5_MIT) && defined(PATH_OPENSSL)
74     tmpdir = test_tmpdir();
75     basprintf(&pkcs12_path, "%s/%s", tmpdir, "pkinit-pkcs12");
76     generate_pkcs12 = bcalloc_type(10, const char *);
77     generate_pkcs12[0] = PATH_OPENSSL;
78     generate_pkcs12[1] = "pkcs12";
79     generate_pkcs12[2] = "-export";
80     generate_pkcs12[3] = "-in";
81     generate_pkcs12[4] = krbconf->pkinit_cert;
82     generate_pkcs12[5] = "-password";
83     generate_pkcs12[6] = "pass:some-password";
84     generate_pkcs12[7] = "-out";
85     generate_pkcs12[8] = pkcs12_path;
86     generate_pkcs12[9] = NULL;
87     run_setup(generate_pkcs12);
88     free(generate_pkcs12);
89     config.extra[0] = pkcs12_path;
90     config.extra[1] = "some-password";
91     run_script("data/scripts/pkinit/pin-mit", &config);
92     unlink(pkcs12_path);
93     free(pkcs12_path);
94     test_tmpdir_free(tmpdir);
95 #endif /* HAVE_KRB5_MIT && PATH_OPENSSL */
96 
97     return 0;
98 }
99