/** * Open HSM. * */ int lhsm_open(const char* filename) { int result = hsm_open(filename, hsm_check_pin); if (result != HSM_OK) { char* error = hsm_get_error(NULL); if (error != NULL) { ods_log_error("[%s] %s", hsm_str, error); free(error); } else { ods_log_crit("[%s] error opening libhsm (errno %i)", hsm_str, result); } /* exit? */ } else { ods_log_info("[%s] libhsm connection opened succesfully", hsm_str); } return result; }
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; }
/** * 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; }
/** * Get RRSIG from one of the HSMs, given a RRset and a key. * */ ldns_rr* lhsm_sign(hsm_ctx_t* ctx, ldns_rr_list* rrset, key_type* key_id, ldns_rdf* owner, time_t inception, time_t expiration) { ods_status status = ODS_STATUS_OK; char* error = NULL; ldns_rr* result = NULL; hsm_sign_params_t* params = NULL; int retries = 0; if (!owner || !key_id || !rrset || !inception || !expiration) { ods_log_error("[%s] unable to sign: missing required elements", hsm_str); return NULL; } lhsm_sign_start: /* get dnskey */ if (!key_id->dnskey) { status = lhsm_get_key(ctx, owner, key_id); if (status != ODS_STATUS_OK) { error = hsm_get_error(ctx); if (error) { ods_log_error("[%s] %s", hsm_str, error); free((void*)error); } else if (!retries) { lhsm_clear_key_cache(key_id); retries++; goto lhsm_sign_start; } ods_log_error("[%s] unable to sign: get key failed", hsm_str); return NULL; } } ods_log_assert(key_id->dnskey); ods_log_assert(key_id->hsmkey); ods_log_assert(key_id->params); /* adjust parameters */ params = hsm_sign_params_new(); params->owner = ldns_rdf_clone(key_id->params->owner); params->algorithm = key_id->algorithm; params->flags = key_id->flags; params->inception = inception; params->expiration = expiration; params->keytag = ldns_calc_keytag(key_id->dnskey); ods_log_deeebug("[%s] sign RRset[%i] with key %s tag %u", hsm_str, ldns_rr_get_type(ldns_rr_list_rr(rrset, 0)), key_id->locator?key_id->locator:"(null)", params->keytag); result = hsm_sign_rrset(ctx, rrset, key_id->hsmkey, params); hsm_sign_params_free(params); if (!result) { error = hsm_get_error(ctx); if (error) { ods_log_error("[%s] %s", hsm_str, error); free((void*)error); } else if (!retries) { lhsm_clear_key_cache(key_id); retries++; goto lhsm_sign_start; } ods_log_crit("[%s] error signing rrset with libhsm", hsm_str); } return result; }
/** * Get key from one of the HSMs. * */ ods_status lhsm_get_key(hsm_ctx_t* ctx, ldns_rdf* owner, key_type* key_id) { char *error = NULL; int retries = 0; if (!owner || !key_id) { ods_log_error("[%s] unable to get key: missing required elements", hsm_str); return ODS_STATUS_ASSERT_ERR; } lhsm_key_start: /* set parameters */ if (!key_id->params) { key_id->params = hsm_sign_params_new(); if (key_id->params) { key_id->params->owner = ldns_rdf_clone(owner); key_id->params->algorithm = key_id->algorithm; key_id->params->flags = key_id->flags; } else { /* could not create params */ error = hsm_get_error(ctx); if (error) { ods_log_error("[%s] %s", hsm_str, error); free((void*)error); } else if (!retries) { lhsm_clear_key_cache(key_id); retries++; goto lhsm_key_start; } ods_log_error("[%s] unable to get key: create params for key %s " "failed", hsm_str, key_id->locator?key_id->locator:"(null)"); return ODS_STATUS_ERR; } } /* lookup key */ if (!key_id->hsmkey) { key_id->hsmkey = hsm_find_key_by_id(ctx, key_id->locator); } if (!key_id->hsmkey) { error = hsm_get_error(ctx); if (error) { ods_log_error("[%s] %s", hsm_str, error); free((void*)error); } else if (!retries) { lhsm_clear_key_cache(key_id); retries++; goto lhsm_key_start; } /* could not find key */ ods_log_error("[%s] unable to get key: key %s not found", hsm_str, key_id->locator?key_id->locator:"(null)"); return ODS_STATUS_ERR; } /* get dnskey */ if (!key_id->dnskey) { key_id->dnskey = hsm_get_dnskey(ctx, key_id->hsmkey, key_id->params); } if (!key_id->dnskey) { error = hsm_get_error(ctx); if (error) { ods_log_error("[%s] %s", hsm_str, error); free((void*)error); } else if (!retries) { lhsm_clear_key_cache(key_id); retries++; goto lhsm_key_start; } ods_log_error("[%s] unable to get key: hsm failed to create dnskey", hsm_str); return ODS_STATUS_ERR; } key_id->params->keytag = ldns_calc_keytag(key_id->dnskey); return ODS_STATUS_OK; }