xref: /freebsd/contrib/pam-krb5/tests/module/fast-anon-t.c (revision bf6873c5786e333d679a7838d28812febf479a8a)
1 /*
2  * Tests for anonymous FAST support in pam-krb5.
3  *
4  * Tests for anonymous Flexible Authentication Secure Tunneling, a mechanism
5  * for improving the preauthentication part of the Kerberos protocol and
6  * protecting it against various attacks.
7  *
8  * This is broken out from the other FAST tests because it uses PKINIT, and
9  * PKINIT code cannot be tested under valgrind with MIT Kerberos due to some
10  * bug in valgrind.
11  *
12  * Written by Russ Allbery <eagle@eyrie.org>
13  * Copyright 2017, 2020 Russ Allbery <eagle@eyrie.org>
14  * Copyright 2012
15  *     The Board of Trustees of the Leland Stanford Junior University
16  *
17  * SPDX-License-Identifier: BSD-3-clause or GPL-1+
18  */
19 
20 #include <config.h>
21 #include <portable/krb5.h>
22 #include <portable/system.h>
23 
24 #include <tests/fakepam/script.h>
25 #include <tests/tap/kerberos.h>
26 
27 
28 /*
29  * Test whether anonymous authentication works.  If this doesn't, we need to
30  * skip the tests of anonymous FAST.
31  */
32 static bool
anon_fast_works(void)33 anon_fast_works(void)
34 {
35     krb5_context ctx;
36     krb5_error_code retval;
37     krb5_principal princ = NULL;
38     char *realm;
39     krb5_creds creds;
40     krb5_get_init_creds_opt *opts = NULL;
41 
42     /* Construct the anonymous principal name. */
43     retval = krb5_init_context(&ctx);
44     if (retval != 0)
45         bail("cannot initialize Kerberos");
46     retval = krb5_get_default_realm(ctx, &realm);
47     if (retval != 0)
48         bail("cannot get default realm");
49     retval = krb5_build_principal_ext(
50         ctx, &princ, (unsigned int) strlen(realm), realm,
51         strlen(KRB5_WELLKNOWN_NAME), KRB5_WELLKNOWN_NAME,
52         strlen(KRB5_ANON_NAME), KRB5_ANON_NAME, NULL);
53     if (retval != 0)
54         bail("cannot construct anonymous principal");
55     krb5_free_default_realm(ctx, realm);
56 
57     /* Obtain the credentials. */
58     memset(&creds, 0, sizeof(creds));
59     retval = krb5_get_init_creds_opt_alloc(ctx, &opts);
60     if (retval != 0)
61         bail("cannot create credential options");
62     krb5_get_init_creds_opt_set_anonymous(opts, 1);
63     krb5_get_init_creds_opt_set_tkt_life(opts, 60);
64     retval = krb5_get_init_creds_password(ctx, &creds, princ, NULL, NULL, NULL,
65                                           0, NULL, opts);
66 
67     /* Clean up. */
68     if (princ != NULL)
69         krb5_free_principal(ctx, princ);
70     if (opts != NULL)
71         krb5_get_init_creds_opt_free(ctx, opts);
72     krb5_free_cred_contents(ctx, &creds);
73 
74     /* Return whether authentication succeeded. */
75     return (retval == 0);
76 }
77 
78 
79 int
main(void)80 main(void)
81 {
82     struct script_config config;
83     struct kerberos_config *krbconf;
84 
85     /* Skip the test if FAST is not available. */
86 #ifndef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_FAST_CCACHE_NAME
87     skip_all("FAST support not available");
88 #endif
89 
90     /* Initialize Kerberos configuration. */
91     krbconf = kerberos_setup(TAP_KRB_NEEDS_PASSWORD);
92     memset(&config, 0, sizeof(config));
93     config.user = krbconf->username;
94     config.authtok = krbconf->password;
95     config.extra[0] = krbconf->userprinc;
96     kerberos_generate_conf(krbconf->realm);
97 
98     /* Skip the test if anonymous PKINIT doesn't work. */
99     if (!anon_fast_works())
100         skip_all("anonymous PKINIT failed");
101 
102     /* Test anonymous FAST. */
103     plan_lazy();
104     run_script("data/scripts/fast/anonymous", &config);
105     run_script("data/scripts/fast/anonymous-debug", &config);
106 
107     return 0;
108 }
109