Esempio n. 1
0
void 
engine_runloop(engine_type* engine, start_cb_t start, int single_run)
{
    /* run */
    while (engine->need_to_exit == 0) {
        
        if (engine->need_to_reload) {
            ods_log_info("[%s] enforcer reloading", engine_str);
            engine->need_to_reload = 0;
        } else {
            ods_log_info("[%s] enforcer started", engine_str);
            /* try to recover from backups */
            /* not for now:
             engine_recover_from_backups(engine);
             */
        }
        
        engine_run(engine, start, single_run);
    }
    
    /* shutdown */
    ods_log_info("[%s] enforcer shutdown", engine_str);
    hsm_close();
    if (engine->cmdhandler != NULL) {
        engine_stop_cmdhandler(engine);
    }
}
Esempio n. 2
0
/**
 * Reopen HSM.
 *
 */
int
lhsm_reopen(const char* filename)
{
    if (hsm_check_context(NULL) != HSM_OK) {
        ods_log_warning("[%s] idle libhsm connection, trying to reopen",
                        hsm_str);
        hsm_close();
        return lhsm_open(filename);
    }
    return HSM_OK;
}
Esempio n. 3
0
/**
 * Check the HSM connection, reload engine if necessary.
 *
 */
void
lhsm_check_connection(void* engine)
{
    engine_type* e = (engine_type*) engine;
    if (hsm_check_context(NULL) != HSM_OK) {
        ods_log_warning("[%s] idle libhsm connection, trying to reopen",
                        hsm_str);
        engine_stop_drudgers(e);
        hsm_close();
        (void)lhsm_open(e->config->cfg_filename);
        engine_start_drudgers((engine_type*) engine);
    } else {
        ods_log_debug("[%s] libhsm connection ok", hsm_str);
    }
    return;
}
int
main (int argc, char *argv[])
{
    int result;
    hsm_ctx_t *ctx;
    hsm_key_t **keys;
    hsm_key_t *key = NULL;
    char *id;
    size_t key_count = 0;
    size_t i;
    ldns_rr_list *rrset;
    ldns_rr *rr, *sig, *dnskey_rr;
    ldns_status status;
    hsm_sign_params_t *sign_params;

    int do_generate = 0;
    int do_sign = 0;
    int do_delete = 0;
    int do_random = 0;

    int res;
    uint32_t r32;
    uint64_t r64;

    char *config = NULL;
    const char *repository = "default";

    int ch;

    progname = argv[0];

    while ((ch = getopt(argc, argv, "hgsdrc:")) != -1) {
        switch (ch) {
        case 'c':
            config = strdup(optarg);
            break;
        case 'g':
            do_generate = 1;
            break;
        case 'h':
            usage();
            exit(0);
            break;
        case 's':
            do_sign = 1;
            break;
        case 'd':
            do_delete = 1;
            break;
        case 'r':
            do_random = 1;
            break;
        default:
            usage();
            exit(1);
        }
    }

    if (!config) {
        usage();
        exit(1);
    }

    /*
     * Open HSM library
     */
    fprintf(stdout, "Starting HSM lib test\n");
    result = hsm_open(config, hsm_prompt_pin);
    fprintf(stdout, "hsm_open result: %d\n", result);

    /*
     * Create HSM context
     */
    ctx = hsm_create_context();
    printf("global: ");
    hsm_print_ctx(NULL);
    printf("my: ");
    hsm_print_ctx(ctx);

    /*
     * Generate a new key OR find any key with an ID
     */
    if (do_generate) {
        key = hsm_generate_rsa_key(ctx, repository, 1024);

        if (key) {
            printf("\nCreated key!\n");
            hsm_print_key(key);
            printf("\n");
        } else {
            printf("Error creating key, bad token name?\n");
            hsm_print_error(ctx);
            exit(1);
        }
    } else if (do_sign || do_delete) {
        keys = hsm_list_keys(ctx, &key_count);
        printf("I have found %u keys\n", (unsigned int) key_count);

        /* let's just use the very first key we find and throw away the rest */
        for (i = 0; i < key_count && !key; i++) {
            printf("\nFound key!\n");
            hsm_print_key(keys[i]);

            id = hsm_get_key_id(ctx, keys[i]);

            if (id) {
                printf("Using key ID: %s\n", id);
                if (key) hsm_key_free(key);
                key = hsm_find_key_by_id(ctx, id);
                printf("ptr: 0x%p\n", (void *) key);
                free(id);
            } else {
                printf("Got no key ID (broken key?), skipped...\n");
            }

            hsm_key_free(keys[i]);
        }
        free(keys);

        if (!key) {
            printf("Failed to find useful key\n");
            exit(1);
        }
    }

    /*
     * Do some signing
     */
    if (do_sign) {
        printf("\nSigning with:\n");
        hsm_print_key(key);
        printf("\n");

        rrset = ldns_rr_list_new();

        status = ldns_rr_new_frm_str(&rr, "regress.opendnssec.se. IN A 123.123.123.123", 0, NULL, NULL);
        if (status == LDNS_STATUS_OK) ldns_rr_list_push_rr(rrset, rr);
        status = ldns_rr_new_frm_str(&rr, "regress.opendnssec.se. IN A 124.124.124.124", 0, NULL, NULL);
        if (status == LDNS_STATUS_OK) ldns_rr_list_push_rr(rrset, rr);

        sign_params = hsm_sign_params_new();
        sign_params->algorithm = LDNS_RSASHA1;
        sign_params->owner = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, "opendnssec.se.");
        dnskey_rr = hsm_get_dnskey(ctx, key, sign_params);
        sign_params->keytag = ldns_calc_keytag(dnskey_rr);

        sig = hsm_sign_rrset(ctx, rrset, key, sign_params);
        if (sig) {
            ldns_rr_list_print(stdout, rrset);
            ldns_rr_print(stdout, sig);
            ldns_rr_print(stdout, dnskey_rr);
            ldns_rr_free(sig);
        } else {
            hsm_print_error(ctx);
            exit(-1);
        }

        /* cleanup */
        ldns_rr_list_deep_free(rrset);
        hsm_sign_params_free(sign_params);
        ldns_rr_free(dnskey_rr);
    }

    /*
     * Delete key
     */
    if (do_delete) {
        printf("\nDelete key:\n");
        hsm_print_key(key);
        /* res = hsm_remove_key(ctx, key); */
        res = hsm_remove_key(ctx, key);
        printf("Deleted key. Result: %d\n", res);
        printf("\n");
    }

    if (key) hsm_key_free(key);

    /*
     * Test random{32,64} functions
     */
    if (do_random) {
        r32 = hsm_random32(ctx);
        printf("random 32: %u\n", r32);
        r64 = hsm_random64(ctx);
        printf("random 64: %llu\n", (long long unsigned int)r64);
    }

    /*
     * Destroy HSM context
     */
    if (ctx) {
        hsm_destroy_context(ctx);
    }

    /*
     * Close HSM library
     */
    result = hsm_close();
    fprintf(stdout, "all done! hsm_close result: %d\n", result);

    if (config) free(config);
    
    return 0;
}
/**
 * Start engine.
 *
 */
void
engine_start(const char* cfgfile, int cmdline_verbosity, int daemonize,
    int info, int single_run)
{
    engine_type* engine = NULL;
    int use_syslog = 0;
    ods_status zl_changed = ODS_STATUS_UNCHANGED;
    ods_status status = ODS_STATUS_OK;
    int close_hsm = 0;

    ods_log_assert(cfgfile);
    ods_log_init(NULL, use_syslog, cmdline_verbosity);
    ods_log_verbose("[%s] starting signer", engine_str);

    /* initialize */
    xmlInitGlobals();
    xmlInitParser();
    xmlInitThreads();
    engine = engine_create();
    if (!engine) {
        ods_fatal_exit("[%s] create failed", engine_str);
        return;
    }
    engine->daemonize = daemonize;

    /* config */
    engine->config = engine_config(engine->allocator, cfgfile,
        cmdline_verbosity);
    status = engine_config_check(engine->config);
    if (status != ODS_STATUS_OK) {
        ods_log_error("[%s] cfgfile %s has errors", engine_str, cfgfile);
        goto earlyexit;
    }
    if (info) {
        engine_config_print(stdout, engine->config); /* for debugging */
        goto earlyexit;
    }
    /* check pidfile */
    if (!util_check_pidfile(engine->config->pid_filename)) {
        exit(1);
    }
    /* open log */
    ods_log_init(engine->config->log_filename, engine->config->use_syslog,
       engine->config->verbosity);
    /* setup */
    tzset(); /* for portability */
    status = engine_setup(engine);
    if (status != ODS_STATUS_OK) {
        ods_log_error("[%s] setup failed: %s", engine_str,
            ods_status2str(status));
        engine->need_to_exit = 1;
        if (status != ODS_STATUS_WRITE_PIDFILE_ERR) {
            /* command handler had not yet been started */
            engine->cmdhandler_done = 1;
        }
    } else {
        /* setup ok, mark hsm open */
        close_hsm = 1;
    }

    /* run */
    while (engine->need_to_exit == 0) {
        /* update zone list */
        lock_basic_lock(&engine->zonelist->zl_lock);
        zl_changed = zonelist_update(engine->zonelist,
            engine->config->zonelist_filename);
        engine->zonelist->just_removed = 0;
        engine->zonelist->just_added = 0;
        engine->zonelist->just_updated = 0;
        lock_basic_unlock(&engine->zonelist->zl_lock);
        /* start/reload */
        if (engine->need_to_reload) {
            ods_log_info("[%s] signer reloading", engine_str);
            engine->need_to_reload = 0;
        } else {
            ods_log_info("[%s] signer started", engine_str);
            zl_changed = engine_recover(engine);
        }
        if (zl_changed == ODS_STATUS_OK ||
            zl_changed == ODS_STATUS_UNCHANGED) {
            engine_update_zones(engine, zl_changed);
        }
        engine_run(engine, single_run);
    }

    /* shutdown */
    ods_log_info("[%s] signer shutdown", engine_str);
    if (close_hsm) {
        ods_log_verbose("[%s] close hsm", engine_str);
        hsm_close();
    }
    if (!engine->cmdhandler_done) {
        engine_stop_xfrhandler(engine);
        engine_stop_dnshandler(engine);
        engine_stop_cmdhandler(engine);
    }

earlyexit:
    if (engine && engine->config) {
        if (engine->config->pid_filename) {
            (void)unlink(engine->config->pid_filename);
        }
        if (engine->config->clisock_filename) {
            (void)unlink(engine->config->clisock_filename);
        }
    }
    tsig_handler_cleanup();
    engine_cleanup(engine);
    engine = NULL;
    ods_log_close();
    xmlCleanupParser();
    xmlCleanupGlobals();
    xmlCleanupThreads();
    return;
}
/**
 * Set up engine.
 *
 */
static ods_status
engine_setup(engine_type* engine)
{
    ods_status status = ODS_STATUS_OK;
    struct sigaction action;
    int result = 0;
    int sockets[2] = {0,0};

    ods_log_debug("[%s] setup signer engine", engine_str);
    if (!engine || !engine->config) {
        return ODS_STATUS_ASSERT_ERR;
    }
    /* set edns */
    edns_init(&engine->edns, EDNS_MAX_MESSAGE_LEN);

    /* create command handler (before chowning socket file) */
    engine->cmdhandler = cmdhandler_create(engine->allocator,
        engine->config->clisock_filename);
    if (!engine->cmdhandler) {
        return ODS_STATUS_CMDHANDLER_ERR;
    }
    engine->dnshandler = dnshandler_create(engine->allocator,
        engine->config->interfaces);
    engine->xfrhandler = xfrhandler_create(engine->allocator);
    if (!engine->xfrhandler) {
        return ODS_STATUS_XFRHANDLER_ERR;
    }
    if (engine->dnshandler) {
        if (socketpair(AF_UNIX, SOCK_DGRAM, 0, sockets) == -1) {
            return ODS_STATUS_XFRHANDLER_ERR;
        }
        engine->xfrhandler->dnshandler.fd = sockets[0];
        engine->dnshandler->xfrhandler.fd = sockets[1];
        status = dnshandler_listen(engine->dnshandler);
        if (status != ODS_STATUS_OK) {
            ods_log_error("[%s] setup: unable to listen to sockets (%s)",
                engine_str, ods_status2str(status));
        }
    }
    /* privdrop */
    engine->uid = privuid(engine->config->username);
    engine->gid = privgid(engine->config->group);
    /* TODO: does piddir exists? */
    /* remove the chown stuff: piddir? */
    ods_chown(engine->config->pid_filename, engine->uid, engine->gid, 1);
    ods_chown(engine->config->clisock_filename, engine->uid, engine->gid, 0);
    ods_chown(engine->config->working_dir, engine->uid, engine->gid, 0);
    if (engine->config->log_filename && !engine->config->use_syslog) {
        ods_chown(engine->config->log_filename, engine->uid, engine->gid, 0);
    }
    if (engine->config->working_dir &&
        chdir(engine->config->working_dir) != 0) {
        ods_log_error("[%s] setup: unable to chdir to %s (%s)", engine_str,
            engine->config->working_dir, strerror(errno));
        return ODS_STATUS_CHDIR_ERR;
    }
    if (engine_privdrop(engine) != ODS_STATUS_OK) {
        return ODS_STATUS_PRIVDROP_ERR;
    }
    /* daemonize */
    if (engine->daemonize) {
        switch ((engine->pid = fork())) {
            case -1: /* error */
                ods_log_error("[%s] setup: unable to fork daemon (%s)",
                    engine_str, strerror(errno));
                return ODS_STATUS_FORK_ERR;
            case 0: /* child */
                break;
            default: /* parent */
                engine_cleanup(engine);
                engine = NULL;
                xmlCleanupParser();
                xmlCleanupGlobals();
                xmlCleanupThreads();
                exit(0);
        }
        if (setsid() == -1) {
            ods_log_error("[%s] setup: unable to setsid daemon (%s)",
                engine_str, strerror(errno));
            return ODS_STATUS_SETSID_ERR;
        }
    }
    engine->pid = getpid();
    ods_log_verbose("[%s] running as pid %lu", engine_str,
        (unsigned long) engine->pid);
    /* catch signals */
    signal_set_engine(engine);
    action.sa_handler = signal_handler;
    sigfillset(&action.sa_mask);
    action.sa_flags = 0;
    sigaction(SIGTERM, &action, NULL);
    sigaction(SIGHUP, &action, NULL);
    sigaction(SIGINT, &action, NULL);
    sigaction(SIGILL, &action, NULL);
    sigaction(SIGUSR1, &action, NULL);
    sigaction(SIGALRM, &action, NULL);
    sigaction(SIGCHLD, &action, NULL);
    action.sa_handler = SIG_IGN;
    sigaction(SIGPIPE, &action, NULL);
    /* set up hsm */ /* LEAK */
    result = lhsm_open(engine->config->cfg_filename);
    if (result != HSM_OK) {
        return ODS_STATUS_HSM_ERR;
    }
    /* create workers/drudgers */
    engine_create_workers(engine);
    engine_create_drudgers(engine);
    /* start cmd/dns/xfr handlers */
    engine_start_cmdhandler(engine);
    engine_start_dnshandler(engine);
    engine_start_xfrhandler(engine);
    tsig_handler_init(engine->allocator);
    /* write pidfile */
    if (util_write_pidfile(engine->config->pid_filename, engine->pid) == -1) {
        hsm_close();
        return ODS_STATUS_WRITE_PIDFILE_ERR;
    }
    /* setup done */
    return ODS_STATUS_OK;
}
Esempio n. 7
0
int
main(int argc, char* argv[])
{
    ods_status status;
    engineconfig_type* cfg;
    int c;
    int options_index = 0;
    const char* cfgfile = ODS_SE_CFGFILE;
    static struct option long_options[] = {
        {"config", required_argument, 0, 'c'},
        {"help", no_argument, 0, 'h'},
        {"verbose", no_argument, 0, 'v'},
        { 0, 0, 0, 0}
    };

    argv0 = argv[0];

    /* parse the commandline */
    while ((c=getopt_long(argc, argv, "c:hv", long_options, &options_index)) != -1) {
        switch (c) {
            case 'c':
                cfgfile = optarg;
                break;
            case 'h':
                usage();
                exit(0);
            case 'v':
                ++verbosity;
                break;
            default:
                usage();
                exit(1);
        }
    }
    argc -= optind;
    argv += optind;
    if (argc != 0) {
        usage();
        exit(1);
    }

    ods_log_init("ods-migrate", 0, NULL, verbosity);

    xmlInitGlobals();
    xmlInitParser();
    xmlInitThreads();

    tzset(); /* for portability */

    /* Parse config file */
    cfg = engine_config(cfgfile, verbosity, NULL);
    cfg->verbosity = verbosity;
    /* does it make sense? */
    if (engine_config_check(cfg) != ODS_STATUS_OK) {
        abort(); /* TODO give some error, abort */
    }

    status = hsm_open2(parse_conf_repositories(cfgfile), hsm_prompt_pin);
    if (status != HSM_OK) {
        char* errorstr =  hsm_get_error(NULL);
        if (errorstr != NULL) {
            fprintf(stderr, "%s", errorstr);
            free(errorstr);
            abort(); /* FIXME */
        } else {
            fprintf(stderr,"error opening libhsm (errno %i)\n", status);
        }
        return 1;
    }
    dblayer_initialize();

    switch (cfg->db_type) {
        case ENFORCER_DATABASE_TYPE_SQLITE:
#ifdef HAVE_SQLITE3
            dblayer_sqlite3_open(cfg->datastore);
#else
            fprintf(stderr, "Database SQLite3 not available during compile-time.\n");
#endif
            break;
        case ENFORCER_DATABASE_TYPE_MYSQL:
#ifdef HAVE_MYSQL
            dblayer_mysql_open(cfg->db_host, cfg->db_username, cfg->db_password, cfg->datastore, cfg->db_port, NULL);
#else
    fprintf(stderr, "Database MySQL not available during compile-time.\n");
#endif
            break;
        case ENFORCER_DATABASE_TYPE_NONE:
        default:
            fprintf(stderr, "No database defined\n");
    }

    dblayer_foreach(listQueryStr, updateQueryStr, &compute);
    
    hsm_close();

    engine_config_cleanup(cfg);
    /* dblayer_foreach for each frees something dblayer_close uses
     * We better just let it leak. */
    /* dblayer_close(); */
    dblayer_finalize();
    ods_log_close();

    xmlCleanupParser();
    xmlCleanupGlobals();

    return 0;
}
Esempio n. 8
0
/**
 * Start engine.
 *
 */
int
engine_start(const char* cfgfile, int cmdline_verbosity, int daemonize,
    int info, int single_run)
{
    engine_type* engine = NULL;
    ods_status zl_changed = ODS_STATUS_UNCHANGED;
    ods_status status = ODS_STATUS_OK;

    engine = engine_create();
    if (!engine) {
        ods_fatal_exit("[%s] create failed", engine_str);
        return 1;
    }
    engine->daemonize = daemonize;

    /* config */
    engine->config = engine_config(cfgfile, cmdline_verbosity);
    status = engine_config_check(engine->config);
    if (status != ODS_STATUS_OK) {
        ods_log_error("[%s] cfgfile %s has errors", engine_str, cfgfile);
        goto earlyexit;
    }
    if (info) {
        engine_config_print(stdout, engine->config); /* for debugging */
        goto earlyexit;
    }
    /* check pidfile */
    if (!util_check_pidfile(engine->config->pid_filename)) {
        exit(1);
    }
    /* open log */
    ods_log_init("ods-signerd", engine->config->use_syslog,
        engine->config->log_filename, engine->config->verbosity);
    /* setup */
    status = engine_setup(engine);
    if (status != ODS_STATUS_OK) {
        ods_log_error("[%s] setup failed: %s", engine_str,
            ods_status2str(status));
        if (status != ODS_STATUS_WRITE_PIDFILE_ERR) {
            /* command handler had not yet been started */
            engine->cmdhandler_done = 1;
        }
        goto earlyexit;
    }

    /* run */
    while (engine->need_to_exit == 0) {
        /* update zone list */
        lock_basic_lock(&engine->zonelist->zl_lock);
        zl_changed = zonelist_update(engine->zonelist,
            engine->config->zonelist_filename);
        engine->zonelist->just_removed = 0;
        engine->zonelist->just_added = 0;
        engine->zonelist->just_updated = 0;
        lock_basic_unlock(&engine->zonelist->zl_lock);
        /* start/reload */
        if (engine->need_to_reload) {
            ods_log_info("[%s] signer reloading", engine_str);
            fifoq_wipe(engine->signq);
            engine->need_to_reload = 0;
        } else {
            ods_log_info("[%s] signer started (version %s), pid %u",
                engine_str, PACKAGE_VERSION, engine->pid);
            if (hsm_open2(engine->config->repositories, hsm_check_pin) != HSM_OK) {
                char* error =  hsm_get_error(NULL);
                if (error != NULL) {
                    ods_log_error("[%s] %s", "hsm", error);
                    free(error);
                }
                ods_log_error("[%s] opening hsm failed (for engine recover)", engine_str);
                break;
            }
            zl_changed = engine_recover(engine);
            hsm_close();
        }
        if (zl_changed == ODS_STATUS_OK ||
            zl_changed == ODS_STATUS_UNCHANGED) {
            engine_update_zones(engine, zl_changed);
        }
        if (hsm_open2(engine->config->repositories, hsm_check_pin) != HSM_OK) {
            char* error =  hsm_get_error(NULL);
            if (error != NULL) {
                ods_log_error("[%s] %s", "hsm", error);
                free(error);
            }
            ods_log_error("[%s] opening hsm failed (for engine run)", engine_str);
            break;
        }
        engine_run(engine, single_run);
        hsm_close();
    }

    /* shutdown */
    ods_log_info("[%s] signer shutdown", engine_str);
    engine_stop_cmdhandler(engine);
    engine_stop_xfrhandler(engine);
    engine_stop_dnshandler(engine);

earlyexit:
    if (engine && engine->config) {
        if (engine->config->pid_filename) {
            (void)unlink(engine->config->pid_filename);
        }
        if (engine->config->clisock_filename) {
            (void)unlink(engine->config->clisock_filename);
        }
    }
    tsig_handler_cleanup();
    engine_cleanup(engine);
    engine = NULL;

    return 1;
}
Esempio n. 9
0
int
main (int argc, char *argv[])
{
    int result;

    char *config = NULL;

    int ch;
    progname = argv[0];

    while ((ch = getopt(argc, argv, "c:vVh")) != -1) {
        switch (ch) {
        case 'c':
            config = strdup(optarg);
            break;
        case 'v':
            verbose++;
            break;
        case 'V':
            version();
            exit(0);
            break;
        case 'h':
            usage();
            exit(0);
            break;
        default:
            usage();
            exit(1);
        }
    }
    argc -= optind;
    argv += optind;

    if (!argc) {
        usage();
        exit(1);
    }


    if (!strcasecmp(argv[0], "logout")) {
        if (config) free(config);
        exit(cmd_logout());
    }

    result = hsm_open(config, hsm_prompt_pin);
    if (result) {
        hsm_print_error(NULL);
        exit(-1);
    }

    openlog("hsmutil", LOG_PID, LOG_USER);

    if (!strcasecmp(argv[0], "login")) {
        argc --;
        argv ++;
        result = cmd_login();
    } else if (!strcasecmp(argv[0], "list")) {
        argc --;
        argv ++;
        result = cmd_list(argc, argv);
    } else if (!strcasecmp(argv[0], "generate")) {
        argc --;
        argv ++;
        result = cmd_generate(argc, argv);
    } else if (!strcasecmp(argv[0], "remove")) {
        argc --;
        argv ++;
        result = cmd_remove(argc, argv);
    } else if (!strcasecmp(argv[0], "purge")) {
        argc --;
        argv ++;
        result = cmd_purge(argc, argv);
    } else if (!strcasecmp(argv[0], "dnskey")) {
        argc --;
        argv ++;
        result = cmd_dnskey(argc, argv);
    } else if (!strcasecmp(argv[0], "test")) {
        argc --;
        argv ++;
        result = cmd_test(argc, argv);
    } else if (!strcasecmp(argv[0], "info")) {
        argc --;
        argv ++;
        result = cmd_info();
    } else if (!strcasecmp(argv[0], "debug")) {
        argc --;
        argv ++;
        result = cmd_debug();
    } else {
        usage();
        result = -1;
    }

    (void) hsm_close();
    if (config) free(config);

    closelog();

    exit(result);
}
Esempio n. 10
0
/**
 * Set up engine and return the setup status.
 *
 */
static ods_status
engine_setup_and_return_status(engine_type* engine)
{
    struct sigaction action;
    int result = 0;
    int fd;

    ods_log_debug("[%s] enforcer setup", engine_str);
    if (!engine || !engine->config) {
        return ODS_STATUS_ASSERT_ERR;
    }

    /* create command handler (before chowning socket file) */
    engine->cmdhandler = cmdhandler_create(engine->allocator,
        engine->config->clisock_filename);
    if (!engine->cmdhandler) {
        ods_log_error("[%s] create command handler to %s failed",
            engine_str, engine->config->clisock_filename);
        return ODS_STATUS_CMDHANDLER_ERR;
    }

    /* privdrop */
    engine->uid = privuid(engine->config->username);
    engine->gid = privgid(engine->config->group);
    /* TODO: does piddir exists? */
    /* remove the chown stuff: piddir? */
    ods_chown(engine->config->pid_filename, engine->uid, engine->gid, 1);
    ods_chown(engine->config->clisock_filename, engine->uid, engine->gid, 0);
    ods_chown(engine->config->working_dir, engine->uid, engine->gid, 0);
    if (engine->config->log_filename && !engine->config->use_syslog) {
        ods_chown(engine->config->log_filename, engine->uid, engine->gid, 0);
    }
    if (engine->config->working_dir &&
        chdir(engine->config->working_dir) != 0) {
        ods_log_error("[%s] chdir to %s failed: %s", engine_str,
            engine->config->working_dir, strerror(errno));
        return ODS_STATUS_CHDIR_ERR;
    }
    if (engine_privdrop(engine) != ODS_STATUS_OK) {
        ods_log_error("[%s] unable to drop privileges", engine_str);
        return ODS_STATUS_PRIVDROP_ERR;
    }

    /* daemonize */
    if (engine->daemonize) {
        switch ((engine->pid = fork())) {
            case -1: /* error */
                ods_log_error("[%s] unable to fork daemon: %s",
                    engine_str, strerror(errno));
                return ODS_STATUS_FORK_ERR;
            case 0: /* child */
                if ((fd = open("/dev/null", O_RDWR, 0)) != -1) {
                    (void)dup2(fd, STDIN_FILENO);
                    (void)dup2(fd, STDOUT_FILENO);
                    (void)dup2(fd, STDERR_FILENO);
                    if (fd > 2) (void)close(fd);
                }
                break;
            default: /* parent */
                engine_cleanup(engine);
                engine = NULL;
                xmlCleanupParser();
                xmlCleanupGlobals();
                xmlCleanupThreads();
                exit(0);
        }
        if (setsid() == -1) {
            ods_log_error("[%s] unable to setsid daemon (%s)",
                engine_str, strerror(errno));
            return ODS_STATUS_SETSID_ERR;
        }
    }
    engine->pid = getpid();
    ods_log_verbose("[%s] running as pid %lu", engine_str,
        (unsigned long) engine->pid);

    /* catch signals */
    signal_set_engine(engine);
    action.sa_handler = signal_handler;
    sigfillset(&action.sa_mask);
    action.sa_flags = 0;
    sigaction(SIGHUP, &action, NULL);
    sigaction(SIGTERM, &action, NULL);

    /* set up hsm */ /* LEAK */
    result = hsm_open(engine->config->cfg_filename, hsm_prompt_pin, NULL);
    if (result != HSM_OK) {
        ods_log_error("[%s] error initializing libhsm (errno %i)",
            engine_str, result);
        return ODS_STATUS_HSM_ERR;
    }

    /* create workers */
    engine_create_workers(engine);
    engine_create_drudgers(engine);

    /* start command handler */
    engine_start_cmdhandler(engine);

    /* write pidfile */
    if (util_write_pidfile(engine->config->pid_filename, engine->pid) == -1) {
        hsm_close();
        ods_log_error("[%s] unable to write pid file", engine_str);
        return ODS_STATUS_WRITE_PIDFILE_ERR;
    }

    return ODS_STATUS_OK;
}
Esempio n. 11
0
int
main (int argc, char *argv[])
{
    int result;

    hsm_ctx_t *ctx = NULL;
    hsm_key_t *key = NULL;
    unsigned int keysize = 1024;
    unsigned int iterations = 1;
    unsigned int threads = 1;

    static struct timeval start,end;

    char *config = NULL;
    const char *repository = NULL;

    sign_arg_t sign_arg_array[PTHREAD_THREADS_MAX];

    pthread_t      thread_array[PTHREAD_THREADS_MAX];
    pthread_attr_t thread_attr;
    void          *thread_status;

    int ch;
    unsigned int n;
    double elapsed, speed;

    progname = argv[0];

    while ((ch = getopt(argc, argv, "c:i:r:s:t:")) != -1) {
        switch (ch) {
        case 'c':
            config = strdup(optarg);
            break;
        case 'i':
            iterations = atoi(optarg);
            break;
        case 'r':
            repository = strdup(optarg);
            break;
        case 's':
            keysize = atoi(optarg);
            break;
        case 't':
            threads = atoi(optarg);
            break;
        default:
            usage();
            exit(1);
        }
    }

    if (!repository) {
        usage();
        exit(1);
    }

#if 0
    if (!config) {
        usage();
        exit(1);
    }
#endif

    /* Open HSM library */
    fprintf(stderr, "Opening HSM Library...\n");
    result = hsm_open(config, hsm_prompt_pin, NULL);
    if (result) {
        fprintf(stderr, "hsm_open() returned %d\n", result);
        exit(-1);
    }

    /* Create HSM context */
    ctx = hsm_create_context();
    if (! ctx) {
        fprintf(stderr, "hsm_create_context() returned error\n");
        exit(-1);
    }

    /* Generate a temporary key */
    fprintf(stderr, "Generating temporary key...\n");
    key = hsm_generate_rsa_key(ctx, repository, keysize);
    if (key) {
        char *id = hsm_get_key_id(ctx, key);
        fprintf(stderr, "Temporary key created: %s\n", id);
        free(id);
    } else {
        fprintf(stderr, "Could not generate a key pair in repository \"%s\"\n", repository);
        exit(-1);
    }

    /* Prepare threads */
    pthread_attr_init(&thread_attr);
    pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_JOINABLE);

    for (n=0; n<threads; n++) {
        sign_arg_array[n].id = n;
        sign_arg_array[n].ctx = hsm_create_context();
        if (! sign_arg_array[n].ctx) {
            fprintf(stderr, "hsm_create_context() returned error\n");
            exit(-1);
        }
        sign_arg_array[n].key = key;
        sign_arg_array[n].iterations = iterations;
    }

    fprintf(stderr, "Signing %d RRsets with %s using %d %s...\n",
        iterations, algoname, threads, (threads > 1 ? "threads" : "thread"));
    gettimeofday(&start, NULL);

    /* Create threads for signing */
    for (n=0; n<threads; n++) {
        result = pthread_create(&thread_array[n], &thread_attr,
            sign, (void *) &sign_arg_array[n]);
        if (result) {
            fprintf(stderr, "pthread_create() returned %d\n", result);
            exit(EXIT_FAILURE);
        }
    }

    /* Wait for threads to finish */
    for (n=0; n<threads; n++) {
        result = pthread_join(thread_array[n], &thread_status);
        if (result) {
            fprintf(stderr, "pthread_join() returned %d\n", result);
            exit(EXIT_FAILURE);
        }
    }

    gettimeofday(&end, NULL);
    fprintf(stderr, "Signing done.\n");

    /* Report results */
    end.tv_sec -= start.tv_sec;
    end.tv_usec-= start.tv_usec;
    elapsed =(double)(end.tv_sec)+(double)(end.tv_usec)*.000001;
    speed = iterations / elapsed * threads;
    printf("%d %s, %d signatures per thread, %.2f sig/s (RSA %d bits)\n",
        threads, (threads > 1 ? "threads" : "thread"), iterations,
        speed, keysize);

    /* Delete temporary key */
    fprintf(stderr, "Deleting temporary key...\n");
    result = hsm_remove_key(ctx, key);
    if (result) {
        fprintf(stderr, "hsm_remove_key() returned %d\n", result);
        exit(-1);
    }

    /* Clean up */
    hsm_destroy_context(ctx);
    (void) hsm_close();
    if (config) free(config);

    return 0;
}