/** * Add a string to a list of strings. Taken from ods-enforcer. * */ void ods_str_list_add(char*** list, char* str) { char** old = NULL; size_t count = 0; if (*list) { for (count=0; (*list)[count]; ++count) { ; } old = *list; *list = (char**) calloc(sizeof(char*), count+2); if (!*list) { ods_fatal_exit("[%s] fatal ods_str_list_add(): calloc() failed", file_str); } if (old) { memcpy(*list, old, count * sizeof(char*)); } free(old); (*list)[count] = str; (*list)[count+1] = NULL; } else { /** List is NULL, allocate new */ *list = calloc(sizeof(char*), 2); if (!*list) { ods_fatal_exit("[%s] fatal ods_str_list_add(): calloc() failed", file_str); } (*list)[0] = str; } }
static void ods_protobuf_loghandler(::google::protobuf::LogLevel level, const char *filename, int line, const std::string &message) { const char * const fmt = "[%s] %s %s:%d] %s"; switch (level) { case ::google::protobuf::LOGLEVEL_INFO: ods_log_info(fmt,module_str,"INFO",filename,line,message.c_str()); break; case ::google::protobuf::LOGLEVEL_WARNING: ods_log_warning(fmt,module_str,"WARNING",filename,line,message.c_str()); break; case ::google::protobuf::LOGLEVEL_ERROR: ods_log_crit(fmt,module_str,"ERROR",filename,line,message.c_str()); break; case ::google::protobuf::LOGLEVEL_FATAL: ods_fatal_exit(fmt,module_str,"FATAL",filename,line,message.c_str()); break; default: ods_log_assert(false); break; } }
/** * Push a key to the key list. * */ key_type* keylist_push(keylist_type* kl, const char* locator, const char* resourcerecord, uint8_t algorithm, uint32_t flags, int publish, int ksk, int zsk) { key_type* keys_old = NULL; ods_log_assert(kl); keys_old = kl->keys; CHECKALLOC(kl->keys = (key_type*) malloc((kl->count + 1) * sizeof(key_type))); if (!kl->keys) { ods_fatal_exit("[%s] unable to add key: allocator_alloc() failed", key_str); } if (keys_old) { memcpy(kl->keys, keys_old, (kl->count) * sizeof(key_type)); } free(keys_old); kl->count++; kl->keys[kl->count -1].locator = locator; kl->keys[kl->count -1].resourcerecord = resourcerecord; kl->keys[kl->count -1].algorithm = algorithm; kl->keys[kl->count -1].flags = flags; kl->keys[kl->count -1].publish = publish; kl->keys[kl->count -1].ksk = ksk; kl->keys[kl->count -1].zsk = zsk; kl->keys[kl->count -1].dnskey = NULL; kl->keys[kl->count -1].params = NULL; return &kl->keys[kl->count -1]; }
/** * Start engine. * */ engine_type * engine_start(const char* cfgfile, int cmdline_verbosity, int daemonize, int info) { engine_type* engine = NULL; int use_syslog = 0; ods_status status = ODS_STATUS_OK; ods_log_assert(cfgfile); ods_log_init(NULL, use_syslog, cmdline_verbosity); ods_log_verbose("[%s] starting enforcer", engine_str); /* initialize */ xmlInitGlobals(); xmlInitParser(); xmlInitThreads(); engine = engine_create(); if (!engine) { ods_fatal_exit("[%s] create failed", engine_str); return NULL; } 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); engine_stop(engine); return NULL; } if (info) { engine_config_print(stdout, engine->config); /* for debugging */ engine_stop(engine); return NULL; } /* open log */ ods_log_init(engine->config->log_filename, engine->config->use_syslog, engine->config->verbosity); /* setup */ tzset(); /* for portability */ /* initialize protobuf and protobuf-orm */ ods_protobuf_initialize(); ods_orm_initialize(); return engine; }
/** * Allocate memory. * */ void* allocator_alloc(allocator_type* allocator, size_t size) { void* result; ods_log_assert(allocator); /* align size */ if (size == 0) { size = 1; } result = allocator->allocator(size); if (!result) { ods_fatal_exit("[%s] allocator failed: out of memory", allocator_str); return NULL; } return result; }
int flush_enforce_task(engine_type *engine, bool enforce_all) { int status; task_id what_id; /* flush (force to run) the enforcer task when it is waiting in the task list. */ if (!task_id_from_long_name(module_str, &what_id)) { /* no such task */ return 1; } enforcer_context.enforce_all = enforce_all; if (!schedule_flush_type(engine->taskq, what_id)) { status = schedule_task(engine->taskq, enforce_task(engine, enforce_all)); if (status != ODS_STATUS_OK) { ods_fatal_exit("[%s] failed to create enforce task", module_str); return 0; } } return 1; }
/** * 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; }
/** * 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; }