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 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 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