Beispiel #1
0
int
main(void)
{
    struct script_config config;
    struct kerberos_config *krbconf;

    /* Skip the test if FAST is not available. */
#ifndef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_FAST_CCACHE_NAME
    skip_all("FAST support not available");
#endif

    /*
     * To test FAST with an existing ticket cache, we also need a keytab, but
     * we can test anonymous FAST without that.  So only say that we require a
     * password.
     */
    krbconf = kerberos_setup(TAP_KRB_NEEDS_PASSWORD);
    memset(&config, 0, sizeof(config));
    config.user = krbconf->userprinc;
    config.authtok = krbconf->password;

    /*
     * Generate a testing krb5.conf file with a nonexistent default realm so
     * that we can be sure that our principals will stay fully-qualified in
     * the logs.
     */
    kerberos_generate_conf("bogus.example.com");

    plan_lazy();

    /* If we have a keytab and ticket cache available, test fast_ccache. */
    if (krbconf->keytab == NULL)
        skip_block(4, "Kerberos keytab required to test fast_ccache");
    else {
        config.extra[0] = krbconf->cache;
        run_script("data/scripts/fast/ccache", &config);
        run_script("data/scripts/fast/ccache-debug", &config);
        run_script("data/scripts/fast/no-ccache", &config);
        run_script("data/scripts/fast/no-ccache-debug", &config);
    }

    /*
     * Test anonymous FAST.  This will require some pre-testing later.  For
     * this, we need to use our real local realm.
     */
    kerberos_generate_conf(krbconf->realm);
    config.user = krbconf->username;
    config.extra[0] = krbconf->userprinc;
    if (anon_fast_works()) {
        run_script("data/scripts/fast/anonymous", &config);
        run_script("data/scripts/fast/anonymous-debug", &config);
    } else {
        skip_block(2, "Anonymous authentication required to test anon_fast");
    }

    return 0;
}
Beispiel #2
0
int
main(void)
{
    struct script_config config;
    struct kerberos_config *krbconf;

    /* Load the Kerberos principal and certificate path. */
    krbconf = kerberos_setup(TAP_KRB_NEEDS_PKINIT);
    memset(&config, 0, sizeof(config));
    config.user = krbconf->pkinit_principal;
    config.extra[0] = krbconf->pkinit_cert;

    /*
     * Generate a testing krb5.conf file with a nonexistent default realm so
     * that we can be sure that our principals will stay fully-qualified in
     * the logs.
     */
    kerberos_generate_conf("bogus.example.com");

    /*
     * Currently, what we can test and how to test varies a lot by Kerberos
     * implementation.  This will improve later.
     */
    plan_lazy();
#ifdef HAVE_KRB5_HEIMDAL
    run_script("data/scripts/pkinit/basic", &config);
    run_script("data/scripts/pkinit/basic-debug", &config);
    run_script("data/scripts/pkinit/prompt-use", &config);
#else
    run_script("data/scripts/pkinit/no-use-pkinit", &config);
#endif
    run_script("data/scripts/pkinit/try-pkinit", &config);
#ifdef HAVE_KRB5_HEIMDAL
    run_script("data/scripts/pkinit/try-pkinit-debug", &config);
    run_script("data/scripts/pkinit/prompt-try", &config);
#else
    run_script("data/scripts/pkinit/try-pkinit-debug-mit", &config);
    run_script("data/scripts/pkinit/preauth-opt-mit", &config);
#endif

    return 0;
}
Beispiel #3
0
int
main(void)
{
    struct script_config config;
    struct kerberos_password *password;
    DIR *tmpdir;
    struct dirent *file;
    char *tmppath, *path;

    /* Load the Kerberos principal and password from a file. */
    password = kerberos_config_password();
    if (password == NULL)
        skip_all("Kerberos tests not configured");
    memset(&config, 0, sizeof(config));
    config.user = password->username;
    config.password = password->password;
    config.extra[0] = password->principal;

    /* Generate a testing krb5.conf file. */
    kerberos_generate_conf(password->realm);

    /* Get the temporary directory and store that as the %1 substitution. */
    tmppath = test_tmpdir();
    config.extra[1] = tmppath;

    plan_lazy();

    /*
     * We need to ensure that the only thing in the test temporary directory
     * is the krb5.conf file that we generated, since we're going to check for
     * cleanup by looking for any out-of-place files.
     */
    tmpdir = opendir(tmppath);
    if (tmpdir == NULL)
        sysbail("cannot open directory %s", tmppath);
    while ((file = readdir(tmpdir)) != NULL) {
        if (strcmp(file->d_name, ".") == 0 || strcmp(file->d_name, "..") == 0)
            continue;
        if (strcmp(file->d_name, "krb5.conf") == 0)
            continue;
        basprintf(&path, "%s/%s", tmppath, file->d_name);
        if (unlink(path) < 0)
            sysbail("cannot delete temporary file %s", path);
        free(path);
    }
    closedir(tmpdir);

    /*
     * Authenticate only, call pam_end, and be sure the ticket cache is
     * gone.  The auth-only script sets ccache_dir to the temporary directory,
     * so the module will create a temporary ticket cache there and then
     * should clean it up.
     */
    run_script("data/scripts/cache-cleanup/auth-only", &config);
    path = NULL;
    tmpdir = opendir(tmppath);
    if (tmpdir == NULL)
        sysbail("cannot open directory %s", tmppath);
    while ((file = readdir(tmpdir)) != NULL) {
        if (strcmp(file->d_name, ".") == 0 || strcmp(file->d_name, "..") == 0)
            continue;
        if (strcmp(file->d_name, "krb5.conf") == 0)
            continue;
        if (path == NULL)
            basprintf(&path, "%s/%s", tmppath, file->d_name);
    }
    closedir(tmpdir);
    if (path != NULL)
        diag("found stray temporary file %s", path);
    ok(path == NULL, "ticket cache cleaned up");
    if (path != NULL)
        free(path);

    test_tmpdir_free(tmppath);
    kerberos_config_password_free(password);
    return 0;
}
Beispiel #4
0
int
main(void)
{
    struct script_config config;
    struct kerberos_config *krbconf;
    char *newpass, *date;
    struct passwd pwd;
    time_t now;

    /* Load the Kerberos principal and password from a file. */
    krbconf = kerberos_setup(TAP_KRB_NEEDS_PASSWORD);
    memset(&config, 0, sizeof(config));
    config.user = krbconf->username;
    config.password = krbconf->password;
    config.extra[0] = krbconf->userprinc;

    /*
     * Ensure we can expire the password.  Heimdal has a prompt for the
     * expiration time, so save that to use as a substitution in the script.
     */
    now = time(NULL) - 1;
    if (!kerberos_expire_password(krbconf->userprinc, now))
        skip_all("kadmin not configured or kadmin mismatch");
    date = bstrdup(ctime(&now));
    date[strlen(date) - 1] = '\0';
    config.extra[1] = date;

    /* Generate a testing krb5.conf file. */
    kerberos_generate_conf(krbconf->realm);

    /* Create a fake passwd struct for our user. */
    memset(&pwd, 0, sizeof(pwd));
    pwd.pw_name = krbconf->username;
    pwd.pw_uid = getuid();
    pwd.pw_gid = getgid();
    basprintf(&pwd.pw_dir, "%s/tmp", getenv("BUILD"));
    pam_set_pwd(&pwd);

    /*
     * We'll be changing the password to something new.  This needs to be
     * sufficiently random that it's unlikely to fall afoul of password
     * strength checking.
     */
    basprintf(&newpass, "ngh1,a%lu nn9af6", (unsigned long) getpid());
    config.newpass = newpass;

    plan_lazy();

    /* Default behavior. */
#ifdef HAVE_KRB5_HEIMDAL
    run_script("data/scripts/expired/basic-heimdal", &config);
    config.newpass = krbconf->password;
    config.password = newpass;
    kerberos_expire_password(krbconf->userprinc, now);
    run_script("data/scripts/expired/basic-heimdal-debug", &config);
#else
    run_script("data/scripts/expired/basic-mit", &config);
    config.newpass = krbconf->password;
    config.password = newpass;
    kerberos_expire_password(krbconf->userprinc, now);
    run_script("data/scripts/expired/basic-mit-debug", &config);
#endif

    /* Test again with PAM_SILENT, specified two ways. */
#ifdef HAVE_KRB5_HEIMDAL
    config.newpass = newpass;
    config.password = krbconf->password;
    kerberos_expire_password(krbconf->userprinc, now);
    run_script("data/scripts/expired/basic-heimdal-silent", &config);
    config.newpass = krbconf->password;
    config.password = newpass;
    kerberos_expire_password(krbconf->userprinc, now);
    run_script("data/scripts/expired/basic-heimdal-flag-silent", &config);
#else
    config.newpass = newpass;
    config.password = krbconf->password;
    kerberos_expire_password(krbconf->userprinc, now);
    run_script("data/scripts/expired/basic-mit-silent", &config);
    config.newpass = krbconf->password;
    config.password = newpass;
    kerberos_expire_password(krbconf->userprinc, now);
    run_script("data/scripts/expired/basic-mit-flag-silent", &config);
#endif

    /*
     * We can only run the remaining checks if we can suppress the Kerberos
     * library behavior of prompting for a new password when the password has
     * expired.
     */
#ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_CHANGE_PASSWORD_PROMPT

    /* Check the forced failure behavior. */
    run_script("data/scripts/expired/fail", &config);
    run_script("data/scripts/expired/fail-debug", &config);

    /* Defer the error to the account management check. */
    config.newpass = newpass;
    config.password = krbconf->password;
    config.authtok = krbconf->password;
    kerberos_expire_password(krbconf->userprinc, now);
    run_script("data/scripts/expired/defer", &config);
    config.newpass = krbconf->password;
    config.password = newpass;
    config.authtok = newpass;
    kerberos_expire_password(krbconf->userprinc, now);
    run_script("data/scripts/expired/defer-debug", &config);

#else /* !HAVE_KRB5_GET_INIT_CREDS_OPT_SET_CHANGE_PASSWORD_PROMPT */

    /* Mention that we skipped something for the record. */
    skip_block(4, "cannot disable library password prompting");

#endif /* HAVE_KRB5_GET_INIT_CREDS_OPT_SET_CHANGE_PASSWORD_PROMPT */

    /* In case we ran into some error, try to unexpire the password. */
    kerberos_expire_password(krbconf->userprinc, 0);

    free(date);
    free(newpass);
    free(pwd.pw_dir);
    return 0;
}
Beispiel #5
0
int
main(void)
{
    struct script_config config;
    struct kerberos_config *krbconf;
    char *user;

    /*
     * Load the Kerberos principal and password from a file, but set the
     * principal as extra[0] and use something else bogus as the user.  We
     * want to test that alt_auth_map works when there's no relationship
     * between the mapped principal and the user.
     */
    krbconf = kerberos_setup(TAP_KRB_NEEDS_PASSWORD);
    memset(&config, 0, sizeof(config));
    config.user = "******";
    config.authtok = krbconf->password;
    config.extra[0] = krbconf->username;
    config.extra[1] = krbconf->userprinc;

    /*
     * Generate a testing krb5.conf file with a nonexistent default realm so
     * that we can be sure that our principals will stay fully-qualified in
     * the logs.
     */
    kerberos_generate_conf("bogus.example.com");
    config.extra[2] = "bogus.example.com";

    /* Test without password prompting. */
    plan_lazy();
    run_script("data/scripts/alt-auth/basic", &config);
    run_script("data/scripts/alt-auth/basic-debug", &config);
    run_script("data/scripts/alt-auth/fail", &config);
    run_script("data/scripts/alt-auth/fail-debug", &config);
    run_script("data/scripts/alt-auth/force", &config);
    run_script("data/scripts/alt-auth/only", &config);

    /*
     * If the alternate account exists but the password is incorrect, we
     * should not fall back to the regular account.  Test with debug so that
     * we don't need two principals configured.
     */
    config.authtok = "bogus incorrect password";
    run_script("data/scripts/alt-auth/force-fail-debug", &config);

    /*
     * Switch to our correct user (but wrong realm) realm to test username
     * mapping to a different realm.
     */
    config.authtok = krbconf->password;
    config.user = krbconf->username;
    config.extra[2] = krbconf->realm;
    run_script("data/scripts/alt-auth/username-map", &config);

    /*
     * Split the username into two parts, one in the PAM configuration and one
     * in the real username, so that we can test interpolation of the username
     * when %s isn't the first token.
     */
    config.user = &krbconf->username[1];
    user = bstrndup(krbconf->username, 1);
    config.extra[3] = user;
    run_script("data/scripts/alt-auth/username-map-prefix", &config);
    free(user);
    config.extra[3] = NULL;

    /*
     * Ensure that we don't add the realm of the authentication username when
     * the alt_auth_map already includes a realm.
     */
    basprintf(&user, "*****@*****.**", krbconf->username);
    config.user = user;
    diag("re-running username-map with fully-qualified PAM user");
    run_script("data/scripts/alt-auth/username-map", &config);
    free(user);
    config.user = krbconf->username;

    /*
     * Add the password and make the user match our authentication principal,
     * and then test fallback to normal authentication when alternative
     * authentication fails.
     */
    config.user = krbconf->userprinc;
    config.password = krbconf->password;
    config.extra[2] = krbconf->realm;
    run_script("data/scripts/alt-auth/fallback", &config);
    run_script("data/scripts/alt-auth/fallback-debug", &config);
    run_script("data/scripts/alt-auth/fallback-realm", &config);
    run_script("data/scripts/alt-auth/force-fallback", &config);
    run_script("data/scripts/alt-auth/only-fail", &config);

    return 0;
}
Beispiel #6
0
int
main(void)
{
    krb5_context ctx;
    const char *message;
    char *expected;
    char long_principal[VERY_LONG_PRINCIPAL];
    const char *acls[5];
    const struct rule rule = {
        (char *) "TEST", 0, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, 0, 0,
        NULL, NULL, (char **) acls
    };

    plan(16);

    /* Use a krb5.conf with a default realm of EXAMPLE.ORG. */
    kerberos_generate_conf("EXAMPLE.ORG");

    /* Check behavior with empty groups. */
    fake_queue_group(&empty, 0);
    set_passwd("someone", 0);
    acls[0] = "localgroup:empty";
    acls[1] = NULL;
    ok(!acl_permit(&rule, "*****@*****.**"), "Empty");

    /* Check behavior when user is expected to be in supplied group. */
    fake_queue_group(&goodguys, 0);
    set_passwd("remi", 0);
    acls[0] = "localgroup:goodguys";
    acls[1] = NULL;
    ok(acl_permit(&rule, "*****@*****.**"), "User in group");

    /* And when the user is not in the supplied group. */
    fake_queue_group(&goodguys, 0);
    set_passwd("someoneelse", 0);
    ok(!acl_permit(&rule, "*****@*****.**"), "User not in group");

    /* Check that the user's primary group also counts. */
    fake_queue_group(&goodguys, 0);
    set_passwd("otheruser", 42);
    ok(acl_permit(&rule, "*****@*****.**"),
       "User has group as primary group");

    /* And when the user does not convert to a local user or is complex. */
    fake_queue_group(&goodguys, 0);
    set_passwd("remi", 0);
    errors_capture();
    ok(!acl_permit(&rule, "remi/[email protected]"),
       "User with instance with base user in group");
    is_string(NULL, errors, "...with no error");

    /* Principal name is too long. */
    fake_queue_group(&goodguys, 0);
    memset(long_principal, 'A', sizeof(long_principal));
    long_principal[sizeof(long_principal) - 1] = '\0';
    errors_capture();
    ok(!acl_permit(&rule, long_principal), "Long principal");

    /* Determine the expected error message and check it. */
    if (krb5_init_context(&ctx) != 0)
        bail("cannot create Kerberos context");
    message = krb5_get_error_message(ctx, KRB5_CONFIG_NOTENUFSPACE);
    basprintf(&expected, "conversion of %s to local name failed: %s\n",
              long_principal, message);
    krb5_free_context(ctx);
    is_string(expected, errors, "...with correct error message");
    krb5_free_error_message(ctx, message);
    free(expected);

    /* Unsupported realm. */
    fake_queue_group(&goodguys, 0);
    set_passwd("eagle", 0);
    ok(!acl_permit(&rule, "*****@*****.**"), "Non-local realm");

    /* Check behavior when syscall fails */
    fake_queue_group(&goodguys, EPERM);
    set_passwd("remi", 0);
    errors_capture();
    ok(!acl_permit(&rule, "*****@*****.**"), "Failing getgrnam_r");
    is_string("TEST:0: retrieving membership of localgroup goodguys failed\n",
              errors, "...with correct error message");

    /* Check that deny group works as expected */
    fake_queue_group(&badguys, 0);
    set_passwd("boba-fett", 0);
    acls[0] = "deny:localgroup:badguys";
    acls[1] = NULL;
    ok(!acl_permit(&rule, "*****@*****.**"), "Denied user");
    fake_queue_group(&badguys, 0);
    set_passwd("remi", 0);
    ok(!acl_permit(&rule, "*****@*****.**"),
       "User not in denied group but also not allowed");

    /* Check that both deny and "allow" pragma work together */
    fake_queue_group(&goodguys, 0);
    fake_queue_group(&badguys, 0);
    set_passwd("eagle", 0);
    acls[0] = "localgroup:goodguys";
    acls[1] = "deny:localgroup:badguys";
    acls[2] = NULL;
    ok(acl_permit(&rule, "*****@*****.**"),
       "User in allowed group plus a denied group");
    fake_queue_group(&goodguys, 0);
    fake_queue_group(&badguys, 0);
    set_passwd("darth-maul", 0);
    ok(!acl_permit(&rule, "*****@*****.**"),
       "User in a denied group plus an allowed group");
    fake_queue_group(&goodguys, 0);
    fake_queue_group(&badguys, 0);
    set_passwd("anyoneelse", 0);
    ok(!acl_permit(&rule, "*****@*****.**"),
       "User in neither denied nor allowed group");

    /* Clean up. */
    free(errors);
    return 0;
}
Beispiel #7
0
int
main(void)
{
    struct script_config config;
    struct kerberos_config *krbconf;
    char *k5login;
    struct extra extra;
    struct passwd pwd;
    FILE *file;

    /* Load the Kerberos principal and password from a file. */
    krbconf = kerberos_setup(TAP_KRB_NEEDS_PASSWORD);
    memset(&config, 0, sizeof(config));
    config.user = krbconf->username;
    extra.realm = krbconf->realm;
    config.authtok = krbconf->password;
    config.extra[0] = krbconf->userprinc;

    /* Generate a testing krb5.conf file. */
    kerberos_generate_conf(krbconf->realm);

    /* Create a fake passwd struct for our user. */
    memset(&pwd, 0, sizeof(pwd));
    pwd.pw_name = krbconf->username;
    pwd.pw_uid = getuid();
    pwd.pw_gid = getgid();
    basprintf(&pwd.pw_dir, "%s/tmp", getenv("BUILD"));
    pam_set_pwd(&pwd);

    plan_lazy();

    /* Basic test. */
    run_script("data/scripts/cache/basic", &config);

    /* Check the cache status before the session is closed. */
    config.callback = check_cache;
    config.data = &extra;
    run_script("data/scripts/cache/open-session", &config);

    /* Change the authenticating user and test search_k5login. */
    pwd.pw_name = (char *) "testuser";
    config.user = "******";
    basprintf(&k5login, "%s/.k5login", pwd.pw_dir);
    file = fopen(k5login, "w");
    if (file == NULL)
        sysbail("cannot create %s", k5login);
    if (fprintf(file, "%s\n", krbconf->userprinc) < 0)
        sysbail("cannot write to %s", k5login);
    if (fclose(file) < 0)
        sysbail("cannot flush %s", k5login);
    run_script("data/scripts/cache/search-k5login", &config);
    config.callback = NULL;
    run_script("data/scripts/cache/search-k5login-debug", &config);
    unlink(k5login);
    free(k5login);

    /* Test search_k5login when no .k5login file exists. */
    pwd.pw_name = krbconf->username;
    config.user = krbconf->username;
    diag("testing search_k5login with no .k5login file");
    run_script("data/scripts/cache/search-k5login", &config);

    free(pwd.pw_dir);
    return 0;
}