Example #1
0
/*
 * Internal helper function for remctld_start and remctld_start_fakeroot.
 *
 * Takes the Kerberos test configuration (the keytab principal is used as the
 * server principal), the configuration file to use (found via
 * test_file_path), and then any additional arguments to pass to remctld,
 * ending with a NULL.  Returns the PID of the running remctld process.  If
 * anything fails, calls bail.
 *
 * The path to remctld is obtained from the PATH_REMCTLD #define.  If this is
 * not set, remctld_start_internal calls skip_all.
 */
static struct process *
remctld_start_internal(struct kerberos_config *krbconf, const char *config,
                       va_list args, bool fakeroot)
{
    va_list args_copy;
    char *tmpdir, *pidfile, *confpath;
    size_t i, length;
    const char *arg, **argv;
    struct process *process;
    const char *path_remctld = PATH_REMCTLD;

    /* Check prerequisites. */
    if (path_remctld[0] == '\0')
        skip_all("remctld not found");

    /* Determine the location of the PID file and remove any old ones. */
    tmpdir = test_tmpdir();
    basprintf(&pidfile, "%s/remctld.pid", tmpdir);
    if (access(pidfile, F_OK) == 0)
        bail("remctld may already be running: %s exists", pidfile);

    /* Build the argv used to run remctld. */
    confpath = test_file_path(config);
    if (confpath == NULL)
        bail("cannot find remctld config %s", config);
    length = 11;
    va_copy(args_copy, args);
    while ((arg = va_arg(args_copy, const char *)) != NULL)
        length++;
    va_end(args_copy);
    argv = bmalloc(length * sizeof(const char *));
    i = 0;
    argv[i++] = path_remctld;
    argv[i++] = "-mdSF";
    argv[i++] = "-p";
    argv[i++] = "14373";
    argv[i++] = "-s";
    argv[i++] = krbconf->principal;
    argv[i++] = "-P";
    argv[i++] = pidfile;
    argv[i++] = "-f";
    argv[i++] = confpath;
    while ((arg = va_arg(args, const char *)) != NULL)
        argv[i++] = arg;
    argv[i] = NULL;

    /* Start remctld using process_start or process_start_fakeroot. */
    if (fakeroot)
        process = process_start_fakeroot(argv, pidfile);
    else
        process = process_start(argv, pidfile);

    /* Clean up and return. */
    test_file_path_free(confpath);
    free(pidfile);
    test_tmpdir_free(tmpdir);
    free(argv);
    return process;
}
Example #2
0
int
main(void)
{
    skip_all(NULL);
    assert(0);

    return 0;
}
Example #3
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;
}
Example #4
0
/*
  In some cases, an entire test file does not make sense because there
  some feature is missing.  In that case, the entire test case can be
  skipped in the following manner.
 */
int main() {
  if (!has_feature())
    skip_all("Example of skipping an entire test");
  plan(4);
  ok(1, NULL);
  ok(1, NULL);
  ok(1, NULL);
  ok(1, NULL);
  return exit_status();
}
Example #5
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;
}
Example #6
0
int
main(void)
{
    pam_handle_t *pamh;
    struct pam_conv conv = { NULL, NULL };
    char **env;
    size_t i;

    /*
     * Skip this test if the native PAM library doesn't support a PAM
     * environment, since we "break" pam_putenv to mirror the native behavior
     * in that case.
     */
#ifndef HAVE_PAM_GETENV
    skip_all("system doesn't support PAM environment");
#endif

    plan(33);

    /* Basic environment manipulation. */
    if (pam_start("test", NULL, &conv, &pamh) != PAM_SUCCESS)
        sysbail("Fake PAM initialization failed");
    is_int(PAM_BAD_ITEM, pam_putenv(pamh, "TEST"), "delete when NULL");
    ok(pam_getenv(pamh, "TEST") == NULL, "getenv when NULL");
    env = pam_getenvlist(pamh);
    ok(env != NULL, "getenvlist when NULL returns non-NULL");
    is_string(NULL, env[0], "...but first element is NULL");
    for (i = 0; env[i] != NULL; i++)
        free(env[i]);
    free(env);

    /* putenv and getenv. */
    is_int(PAM_SUCCESS, pam_putenv(pamh, "TEST=foo"), "putenv TEST");
    is_string("foo", pam_getenv(pamh, "TEST"), "getenv TEST");
    is_int(PAM_SUCCESS, pam_putenv(pamh, "FOO=bar"), "putenv FOO");
    is_int(PAM_SUCCESS, pam_putenv(pamh, "BAR=baz"), "putenv BAR");
    is_string("foo", pam_getenv(pamh, "TEST"), "getenv TEST");
    is_string("bar", pam_getenv(pamh, "FOO"), "getenv FOO");
    is_string("baz", pam_getenv(pamh, "BAR"), "getenv BAR");
    ok(pam_getenv(pamh, "BAZ") == NULL, "getenv BAZ is NULL");

    /* Replacing and deleting environment variables. */
    is_int(PAM_BAD_ITEM, pam_putenv(pamh, "BAZ"), "putenv nonexistent delete");
    is_int(PAM_SUCCESS, pam_putenv(pamh, "FOO=foo"), "putenv replace");
    is_int(PAM_SUCCESS, pam_putenv(pamh, "FOON=bar=n"), "putenv prefix");
    is_string("foo", pam_getenv(pamh, "FOO"), "getenv FOO");
    is_string("bar=n", pam_getenv(pamh, "FOON"), "getenv FOON");
    is_int(PAM_BAD_ITEM, pam_putenv(pamh, "FO"), "putenv delete FO");
    is_int(PAM_SUCCESS, pam_putenv(pamh, "FOO"), "putenv delete FOO");
    ok(pam_getenv(pamh, "FOO") == NULL, "getenv FOO is NULL");
    is_string("bar=n", pam_getenv(pamh, "FOON"), "getenv FOON");
    is_string("baz", pam_getenv(pamh, "BAR"), "getenv BAR");

    /* pam_getenvlist. */
    env = pam_getenvlist(pamh);
    ok(env != NULL, "getenvlist not NULL");
    is_string("TEST=foo", env[0], "getenvlist TEST");
    is_string("BAR=baz", env[1], "getenvlist BAR");
    is_string("FOON=bar=n", env[2], "getenvlist FOON");
    ok(env[3] == NULL, "getenvlist length");
    for (i = 0; env[i] != NULL; i++)
        free(env[i]);
    free(env);
    is_int(PAM_SUCCESS, pam_putenv(pamh, "FOO=foo"), "putenv FOO");
    is_string("TEST=foo", pamh->environ[0], "pamh environ TEST");
    is_string("BAR=baz", pamh->environ[1], "pamh environ BAR");
    is_string("FOON=bar=n", pamh->environ[2], "pamh environ FOON");
    is_string("FOO=foo", pamh->environ[3], "pamh environ FOO");
    ok(pamh->environ[4] == NULL, "pamh environ length");

    pam_end(pamh, 0);

    return 0;
}
Example #7
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;
}
Example #8
0
void do_tests()
{
  DBUG_ENTER("do_tests");

  skip_all(": this module is not used in MySQL");

  plan(12);
  compile_time_assert(THREADS >= 4);

  DBUG_PRINT("wt", ("================= initialization ==================="));

  bad= my_atomic_initialize();
  ok(!bad, "my_atomic_initialize() returned %d", bad);

  mysql_cond_init(0, &thread_sync, 0);
  mysql_mutex_init(0, &lock, 0);
  wt_init();
  for (cnt=0; cnt < THREADS; cnt++)
    mysql_mutex_init(0, & thds[cnt].lock, 0);
  {
    WT_RESOURCE_ID resid[4];
    for (i=0; i < array_elements(resid); i++)
    {
      wt_thd_lazy_init(& thds[i].thd,
                       & wt_deadlock_search_depth_short, & wt_timeout_short,
                       & wt_deadlock_search_depth_long, & wt_timeout_long);
      resid[i].value= i+1;
      resid[i].type= &restype;
    }

    DBUG_PRINT("wt", ("================= manual test ==================="));

#define ok_wait(X,Y, R) \
    ok(wt_thd_will_wait_for(& thds[X].thd, & thds[Y].thd, &resid[R]) == 0, \
      "thd[" #X "] will wait for thd[" #Y "]")
#define ok_deadlock(X,Y,R) \
    ok(wt_thd_will_wait_for(& thds[X].thd, & thds[Y].thd, &resid[R]) == WT_DEADLOCK, \
      "thd[" #X "] will wait for thd[" #Y "] - deadlock")

    ok_wait(0,1,0);
    ok_wait(0,2,0);
    ok_wait(0,3,0);

    mysql_mutex_lock(&lock);
    bad= wt_thd_cond_timedwait(& thds[0].thd, &lock);
    mysql_mutex_unlock(&lock);
    ok(bad == WT_TIMEOUT, "timeout test returned %d", bad);

    ok_wait(0,1,0);
    ok_wait(1,2,1);
    ok_deadlock(2,0,2);

    mysql_mutex_lock(&lock);
    ok(wt_thd_cond_timedwait(& thds[0].thd, &lock) == WT_TIMEOUT, "as always");
    ok(wt_thd_cond_timedwait(& thds[1].thd, &lock) == WT_TIMEOUT, "as always");
    wt_thd_release_all(& thds[0].thd);
    wt_thd_release_all(& thds[1].thd);
    wt_thd_release_all(& thds[2].thd);
    wt_thd_release_all(& thds[3].thd);

    for (i=0; i < array_elements(resid); i++)
    {
      wt_thd_release_all(& thds[i].thd);
      wt_thd_destroy(& thds[i].thd);
    }
    mysql_mutex_unlock(&lock);
  }

  wt_deadlock_search_depth_short=6;
  wt_timeout_short=1000;
  wt_timeout_long= 100;
  wt_deadlock_search_depth_long=16;
  DBUG_PRINT("wt", ("================= stress test ==================="));

  diag("timeout_short=%lu us, deadlock_search_depth_short=%lu",
       wt_timeout_short, wt_deadlock_search_depth_short);
  diag("timeout_long=%lu us, deadlock_search_depth_long=%lu",
       wt_timeout_long, wt_deadlock_search_depth_long);

#define test_kill_strategy(X)                   \
  diag("kill strategy: " #X);                   \
  DBUG_EXECUTE("reset_file",                    \
               { rewind(DBUG_FILE); my_chsize(fileno(DBUG_FILE), 0, 0, MYF(0)); }); \
  DBUG_PRINT("info", ("kill strategy: " #X));   \
  kill_strategy=X;                              \
  do_one_test();

  test_kill_strategy(LATEST);
  test_kill_strategy(RANDOM);
  /*
    these two take looong time on sol10-amd64-a
    the server doesn't use this code now, so we disable these tests

    test_kill_strategy(YOUNGEST);
    test_kill_strategy(LOCKS);
  */

  DBUG_PRINT("wt", ("================= cleanup ==================="));
  for (cnt=0; cnt < THREADS; cnt++)
    mysql_mutex_destroy(& thds[cnt].lock);
  wt_end();
  mysql_mutex_destroy(&lock);
  mysql_cond_destroy(&thread_sync);
  DBUG_VOID_RETURN;
}
Example #9
0
/*
 * Obtain Kerberos tickets for the principal specified in config/principal
 * using the keytab specified in config/keytab, both of which are presumed to
 * be in tests in either the build or the source tree.  Also sets KRB5_KTNAME
 * and KRB5CCNAME.
 *
 * Returns the contents of config/principal in newly allocated memory or NULL
 * if Kerberos tests are apparently not configured.  If Kerberos tests are
 * configured but something else fails, calls bail.
 */
struct kerberos_config *
kerberos_setup(enum kerberos_needs needs)
{
    char *path;
    char buffer[BUFSIZ];
    FILE *file = NULL;

    /* If we were called before, clean up after the previous run. */
    if (config != NULL)
        kerberos_cleanup();
    config = bcalloc(1, sizeof(struct kerberos_config));

    /*
     * If we have a config/keytab file, set the KRB5CCNAME and KRB5_KTNAME
     * environment variables and obtain initial tickets.
     */
    config->keytab = test_file_path("config/keytab");
    if (config->keytab == NULL) {
        if (needs == TAP_KRB_NEEDS_KEYTAB || needs == TAP_KRB_NEEDS_BOTH)
            skip_all("Kerberos tests not configured");
    } else {
        tmpdir_ticket = test_tmpdir();
        basprintf(&config->cache, "%s/krb5cc_test", tmpdir_ticket);
        basprintf(&krb5ccname, "KRB5CCNAME=%s/krb5cc_test", tmpdir_ticket);
        basprintf(&krb5_ktname, "KRB5_KTNAME=%s", config->keytab);
        putenv(krb5ccname);
        putenv(krb5_ktname);
        kerberos_kinit();
    }

    /*
     * If we have a config/password file, read it and fill out the relevant
     * members of our config struct.
     */
    path = test_file_path("config/password");
    if (path != NULL)
        file = fopen(path, "r");
    if (file == NULL) {
        if (needs == TAP_KRB_NEEDS_PASSWORD || needs == TAP_KRB_NEEDS_BOTH)
            skip_all("Kerberos tests not configured");
    } else {
        if (fgets(buffer, sizeof(buffer), file) == NULL)
            bail("cannot read %s", path);
        if (buffer[strlen(buffer) - 1] != '\n')
            bail("no newline in %s", path);
        buffer[strlen(buffer) - 1] = '\0';
        config->userprinc = bstrdup(buffer);
        if (fgets(buffer, sizeof(buffer), file) == NULL)
            bail("cannot read password from %s", path);
        fclose(file);
        if (buffer[strlen(buffer) - 1] != '\n')
            bail("password too long in %s", path);
        buffer[strlen(buffer) - 1] = '\0';
        config->password = bstrdup(buffer);

        /*
         * Strip the realm from the principal and set realm and username.
         * This is not strictly correct; it doesn't cope with escaped @-signs
         * or enterprise names.
         */
        config->username = bstrdup(config->userprinc);
        config->realm = strchr(config->username, '@');
        if (config->realm == NULL)
            bail("test principal has no realm");
        *config->realm = '\0';
        config->realm++;
    }
    test_file_path_free(path);

    /*
     * If we have PKINIT configuration, read it and fill out the relevant
     * members of our config struct.
     */
    path = test_file_path("config/pkinit-principal");
    if (path != NULL)
        file = fopen(path, "r");
    if (file != NULL) {
        if (fgets(buffer, sizeof(buffer), file) == NULL)
            bail("cannot read %s", path);
        if (buffer[strlen(buffer) - 1] != '\n')
            bail("no newline in %s", path);
        buffer[strlen(buffer) - 1] = '\0';
        fclose(file);
        test_file_path_free(path);
        path = test_file_path("config/pkinit-cert");
        if (path != NULL) {
            config->pkinit_principal = bstrdup(buffer);
            config->pkinit_cert = bstrdup(path);
        }
    }
    test_file_path_free(path);
    if (config->pkinit_cert == NULL && (needs & TAP_KRB_NEEDS_PKINIT) != 0)
        skip_all("PKINIT tests not configured");

    /*
     * Register the cleanup function so that the caller doesn't have to do
     * explicit cleanup.
     */
    test_cleanup_register(kerberos_cleanup_handler);

    /* Return the configuration. */
    return config;
}
Example #10
0
int
main(void)
{
    int flag, status;
    socklen_t flaglen;
    struct addrinfo *ai4, *ai6;
    struct addrinfo hints;
    char addr[INET6_ADDRSTRLEN];
    char *p;
    socket_type fd;
    static const char *port = "119";
    static const char *ipv6_addr = "FEDC:BA98:7654:3210:FEDC:BA98:7654:3210";

#ifndef HAVE_INET6
    skip_all("IPv6 not supported");
#endif

    /* Set up the plan. */
    plan(34);

    /* Get IPv4 and IPv6 sockaddrs to use for subsequent tests. */
    memset(&hints, 0, sizeof(hints));
    hints.ai_flags = AI_NUMERICHOST;
    hints.ai_socktype = SOCK_STREAM;
    status = getaddrinfo("127.0.0.1", port, &hints, &ai4);
    if (status != 0)
        bail("getaddrinfo on 127.0.0.1 failed: %s", gai_strerror(status));
    status = getaddrinfo(ipv6_addr, port, &hints, &ai6);
    if (status != 0)
        bail("getaddr on %s failed: %s", ipv6_addr, gai_strerror(status));

    /* Test network_sockaddr_sprint. */
    ok(network_sockaddr_sprint(addr, sizeof(addr), ai6->ai_addr),
       "sprint of IPv6 address");
    for (p = addr; *p != '\0'; p++)
        if (islower((unsigned char) *p))
            *p = toupper((unsigned char) *p);
    is_string(ipv6_addr, addr, "...with right results");

    /* Test network_sockaddr_port. */
    is_int(119, network_sockaddr_port(ai6->ai_addr), "sockaddr_port IPv6");

    /* Test network_sockaddr_equal. */
    ok(network_sockaddr_equal(ai6->ai_addr, ai6->ai_addr),
       "sockaddr_equal IPv6");
    ok(!network_sockaddr_equal(ai4->ai_addr, ai6->ai_addr),
       "...and not equal to IPv4");
    ok(!network_sockaddr_equal(ai6->ai_addr, ai4->ai_addr),
       "...other way around");
    freeaddrinfo(ai6);

    /* Test IPv4 mapped addresses. */
    status = getaddrinfo("::ffff:7f00:1", NULL, &hints, &ai6);
    if (status != 0)
        bail("getaddr on ::ffff:7f00:1 failed: %s", gai_strerror(status));
    ok(network_sockaddr_sprint(addr, sizeof(addr), ai6->ai_addr),
       "sprint of IPv4-mapped address");
    is_string("127.0.0.1", addr, "...with right IPv4 result");
    ok(network_sockaddr_equal(ai4->ai_addr, ai6->ai_addr),
       "sockaddr_equal of IPv4-mapped address");
    ok(network_sockaddr_equal(ai6->ai_addr, ai4->ai_addr),
       "...and other way around");
    freeaddrinfo(ai4);
    status = getaddrinfo("127.0.0.2", NULL, &hints, &ai4);
    if (status != 0)
        bail("getaddrinfo on 127.0.0.2 failed: %s", gai_strerror(status));
    ok(!network_sockaddr_equal(ai4->ai_addr, ai6->ai_addr),
       "...but not some other address");
    ok(!network_sockaddr_equal(ai6->ai_addr, ai4->ai_addr),
       "...and the other way around");
    freeaddrinfo(ai6);
    freeaddrinfo(ai4);

    /* Tests for network_addr_compare. */
    is_addr_compare(1, ipv6_addr,   ipv6_addr,     NULL);
    is_addr_compare(1, ipv6_addr,   ipv6_addr,     "128");
    is_addr_compare(1, ipv6_addr,   ipv6_addr,     "60");
    is_addr_compare(1, "::127",     "0:0::127",    "128");
    is_addr_compare(1, "::127",     "0:0::128",    "120");
    is_addr_compare(0, "::127",     "0:0::128",    "128");
    is_addr_compare(0, "::7fff",    "0:0::8000",   "113");
    is_addr_compare(1, "::7fff",    "0:0::8000",   "112");
    is_addr_compare(0, "::3:ffff",  "::2:ffff",    "120");
    is_addr_compare(0, "::3:ffff",  "::2:ffff",    "119");
    is_addr_compare(0, "ffff::1",   "7fff::1",     "1");
    is_addr_compare(1, "ffff::1",   "7fff::1",     "0");
    is_addr_compare(0, "fffg::1",   "fffg::1",     NULL);
    is_addr_compare(0, "ffff::1",   "7fff::1",     "-1");
    is_addr_compare(0, "ffff::1",   "ffff::1",     "-1");
    is_addr_compare(0, "ffff::1",   "ffff::1",     "129");

    /* Test setting various socket options. */
    fd = socket(PF_INET6, SOCK_STREAM, IPPROTO_IP);
    if (fd == INVALID_SOCKET)
        sysbail("cannot create socket");
    network_set_reuseaddr(fd);
#ifdef SO_REUSEADDR
    flag = 0;
    flaglen = sizeof(flag);
    is_int(0, getsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &flag, &flaglen),
           "Getting SO_REUSEADDR works");
    ok(flag, "...and it is set");
#else
    skip_block(2, "SO_REUSEADDR not supported");
#endif
    network_set_v6only(fd);
#ifdef IPV6_V6ONLY
    flag = 0;
    flaglen = sizeof(flag);
    is_int(0, getsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &flag, &flaglen),
           "Getting IPV6_V6ONLY works");
    ok(flag, "...and it is set");
#else
    skip_block(2, "IPV6_V6ONLY not supported");
#endif
    network_set_freebind(fd);
#ifdef IP_FREEBIND
    flag = 0;
    flaglen = sizeof(flag);
    is_int(0, getsockopt(fd, IPPROTO_IP, IP_FREEBIND, &flag, &flaglen),
           "Getting IP_FREEBIND works");
    ok(flag, "...and it is set");
#else
    skip_block(2, "IP_FREEBIND not supported");
#endif
    close(fd);

    return 0;
}
Example #11
0
int
load_bin(FILE *file, int offset, int *core, int core_size) {
    int c0, c1;
    unsigned int checksum = 0;
    int count = 0;

    int addr = -1;

    if (fseek(file, offset, SEEK_SET) == -1) {
        lprintf(LOG_ERROR,
                "Can't set offset 0%.o: %s",
                offset, strerror(errno));
        return -1;
    }

    /* Seems like some of the dumps from Bitsavers are 0x00 padded,
     * skip that padding first and then skip the proper BIN format
     * padding. */
    if (!skip_all(file, 0xFF, 0x00) ||
	!skip_all(file, BIN_TYPE_MASK, BIN_TYPE_LEAD_TRAIL)) {
	lprintf(LOG_VERBOSE,
		"Reached EOF in file before finding useful data.\n");
	return 0;
    }

    while ((c0 = fgetc(file)) != EOF &&
	   (c1 = fgetc(file)) != EOF) {
        int word = ((c0 << 6) | c1) & 07777;
	count++;

	switch (c0 & BIN_TYPE_MASK) {
	case BIN_TYPE_ORIGIN:
	    if ((c1 & BIN_TYPE_MASK) != 0)
		lprintf(LOG_WARNING, "Potential error while decoding origin\n");
	    lprintf(LOG_DEBUG, "origin := %.4o\n", word);
	    addr = word;
	    break;

	case BIN_TYPE_INSTR: {
	    int c2 = fgetc(file);
	    if (c2 != EOF)
		ungetc(c2, file);

	    if ((c1 & BIN_TYPE_MASK) != 0)
		lprintf(LOG_WARNING, "Potential error while decoding instruction\n");

	    /* Now, this is either an instruction or a checksum, it
	     * all depends on the proceeding bytes */

	    /* If we reach EOF without trailer bytes, we assume
	     * it's still a checksum. */
	    if (c2 == EOF ||
		(c2 & BIN_TYPE_MASK) == BIN_TYPE_LEAD_TRAIL) {
		/* Checksum */
		checksum &= 07777;
		if (word != checksum) {
		    lprintf(LOG_ERROR,
			    "BIN loader cheksum error.\n"
			    "Calculated checksum: %.4o\n"
			    "Expected cheksum: %.4o\n",
			    checksum, word);
		    return -1;
		} else {
		    lprintf(LOG_DEBUG,
			    "BIN loader loaded %.4o words.\n",
			    count);
		    return count;
		}
	    } else {
		/* Actual instruction */
		if (addr == -1) {
		    lprintf(LOG_ERROR, "Got instruction, but origin not set.\n");
		    return -1;
		}

		lprintf(LOG_DEBUG, "%.4o: %.4o\n", addr, word);

		if (addr >= 0 && addr < core_size) {
		    core[addr++] = word;
		} else {
		    lprintf(LOG_ERROR,
			    "Address (%.4o) outside allocated core! Failing.\n",
			    addr);
		    return -1;
		}
	    }
	} break;

	case BIN_TYPE_LEAD_TRAIL:
	    lprintf(LOG_ERROR, "Unexpected trailer character.\n");
	    return -1;
	case BIN_TYPE_FIELD:
	    lprintf(LOG_WARNING, "Skipping unhandled field processing directive (%.4o)\n", c0);
            ungetc(c1, file);
	    break;
	}

        switch (c0 & BIN_TYPE_MASK) {
        case BIN_TYPE_ORIGIN:
        case BIN_TYPE_INSTR:
            checksum += (unsigned int)c0 + (unsigned int)c1;
            break;
        default:
            break;
        }
            
    };

    lprintf(LOG_ERROR, "Premature end of file.\n");
    return -1;
}
Example #12
0
int main(int argc, char *argv[])
{
	plan_lazy();

	dnssec_crypto_init();

	// PKCS #11 initialization

	dnssec_keystore_t *store = NULL;
	int r = dnssec_keystore_init_pkcs11(&store);
	if (r == DNSSEC_NOT_IMPLEMENTED_ERROR) {
		skip_all("not supported");
		goto done;
	}
	ok(r == DNSSEC_EOK && store, "dnssec_keystore_init_pkcs11()");

	char *dso_name = libsofthsm_dso();
	if (!dso_name) {
		skip_all("%s not found, set %s environment variable",
			 SOFTHSM_DSO, ENV_SOFTHSM_DSO);
		goto done;
	}
	ok(dso_name != NULL, "find token DSO");

	bool success = token_init();
	if (!success) {
		skip_all("failed to configure and initialize the token");
		goto done;
	}
	ok(success, "initialize the token");

	char config[4096] = { 0 };
	r = snprintf(config, sizeof(config), "pkcs11:token=%s;pin-value=%s %s",
	                                     TOKEN_LABEL, TOKEN_PIN, dso_name);
	free(dso_name);
	ok(r > 0 && r < sizeof(config), "build configuration");

	// key store access

	r = dnssec_keystore_init(store, config);
	ok(r == DNSSEC_NOT_IMPLEMENTED_ERROR, "dnssec_keystore_init(), not implemented");

	r = dnssec_keystore_open(store, config);
	ok(r == DNSSEC_EOK, "dnssec_keystore_open()");

	dnssec_list_t *keys = NULL;
	r = dnssec_keystore_list_keys(store, &keys);
	ok(r == DNSSEC_EOK && dnssec_list_size(keys) == 0, "dnssec_keystore_list_keys(), empty");
	dnssec_list_free_full(keys, NULL, NULL);

	// key manipulation

	static const int KEYS_COUNT = 3;
	static const key_parameters_t *KEYS[] = {
		&SAMPLE_RSA_KEY,
		&SAMPLE_ECDSA_KEY,
		&SAMPLE_DSA_KEY,
	};
	assert(KEYS_COUNT == sizeof(KEYS) / sizeof(*KEYS));

	for (int i = 0; i < KEYS_COUNT; i++) {
		test_algorithm(store, KEYS[i]);
	}

	test_key_listing(store, KEYS, KEYS_COUNT);

	r = dnssec_keystore_close(store);
	ok(r == DNSSEC_EOK, "dnssec_keystore_close()");
done:
	dnssec_keystore_deinit(store);
	dnssec_crypto_cleanup();
	token_cleanup();

	return 0;
}
Example #13
0
/*
 * Start a process and return its status information.  The status information
 * is also stored in the global processes linked list so that it can be
 * stopped automatically on program exit.
 *
 * The boolean argument says whether to start the process under fakeroot.  If
 * true, PATH_FAKEROOT must be defined, generally by Autoconf.  If it's not
 * found, call skip_all.
 *
 * This is a helper function for process_start and process_start_fakeroot.
 */
static struct process *
process_start_internal(const char *const argv[], const char *pidfile,
                       bool fakeroot)
{
    size_t i;
    int log_fd;
    const char *name;
    struct timeval tv;
    struct process *process;
    const char **fakeroot_argv = NULL;
    const char *path_fakeroot = PATH_FAKEROOT;

    /* Check prerequisites. */
    if (fakeroot && path_fakeroot[0] == '\0')
        skip_all("fakeroot not found");

    /* Create the process struct and log file. */
    process = bcalloc(1, sizeof(struct process));
    process->pidfile = bstrdup(pidfile);
    process->tmpdir = test_tmpdir();
    name = strrchr(argv[0], '/');
    if (name != NULL)
        name++;
    else
        name = argv[0];
    basprintf(&process->logfile, "%s/%s.log.XXXXXX", process->tmpdir, name);
    log_fd = mkstemp(process->logfile);
    if (log_fd < 0)
        sysbail("cannot create log file for %s", argv[0]);

    /* If using fakeroot, rewrite argv accordingly. */
    if (fakeroot) {
        for (i = 0; argv[i] != NULL; i++)
            ;
        fakeroot_argv = bcalloc(2 + i + 1, sizeof(const char *));
        fakeroot_argv[0] = path_fakeroot;
        fakeroot_argv[1] = "--";
        for (i = 0; argv[i] != NULL; i++)
            fakeroot_argv[i + 2] = argv[i];
        fakeroot_argv[i + 2] = NULL;
        argv = fakeroot_argv;
    }

    /*
     * Fork off the child process, redirect its standard output and standard
     * error to the log file, and then exec the program.
     */
    process->pid = fork();
    if (process->pid < 0)
        sysbail("fork failed");
    else if (process->pid == 0) {
        if (dup2(log_fd, STDOUT_FILENO) < 0)
            sysbail("cannot redirect standard output");
        if (dup2(log_fd, STDERR_FILENO) < 0)
            sysbail("cannot redirect standard error");
        close(log_fd);
        if (execv(argv[0], (char *const *) argv) < 0)
            sysbail("exec of %s failed", argv[0]);
    }
    close(log_fd);
    free(fakeroot_argv);

    /*
     * In the parent.  Wait for the child to start by watching for the PID
     * file to appear in 100ms intervals.
     */
    for (i = 0; i < PROCESS_WAIT * 10 && access(pidfile, F_OK) != 0; i++) {
        tv.tv_sec = 0;
        tv.tv_usec = 100000;
        select(0, NULL, NULL, NULL, &tv);
    }

    /*
     * If the PID file still hasn't appeared after ten seconds, attempt to
     * kill the process and then bail.
     */
    if (access(pidfile, F_OK) != 0) {
        kill(process->pid, SIGTERM);
        alarm(5);
        waitpid(process->pid, NULL, 0);
        alarm(0);
        bail("cannot start %s", argv[0]);
    }

    /*
     * Read the PID back from the PID file.  This usually isn't necessary for
     * non-forking daemons, but always doing this makes this function general,
     * and it's required when running under fakeroot.
     */
    if (fakeroot)
        process->pid = read_pidfile(pidfile);
    process->is_child = !fakeroot;

    /* Register the log file as a source of diag messages. */
    diag_file_add(process->logfile);

    /*
     * Add the process to our global list and set our cleanup handler if this
     * is the first process we started.
     */
    if (processes == NULL)
        test_cleanup_register(process_stop_all);
    process->next = processes;
    processes = process;

    /* All done. */
    return process;
}