#include "service_manager.h" #include "utils/cryptopro.h" #include static void service_manager_handle_conf_free(service_handle_conf_t *handle_conf) { if (handle_conf != NULL) { str_t_clear(&handle_conf->location); handle_conf->conf_free(handle_conf->conf); free(handle_conf); } } static void* service_manager_handle_conf_load(const conf_file_context_t conf_file, service_handle_conf_t *handle_conf) { assert(conf_file != NULL); assert(handle_conf != NULL); void* cfg = handle_conf->conf_load(conf_file, &handle_conf->location); if (cfg == NULL) { LOG_ERROR("service_manager_handle_conf_load - conf_load failed"); } return cfg; } static int service_manager_handle_conf_merge(main_conf_t *main_cf, service_handle_conf_t *handle_conf) { assert(main_cf != NULL); assert(main_cf != NULL); int rc = handle_conf->conf_merge(main_cf, handle_conf->conf); if (rc) { LOG_ERROR("service_manager_handle_conf_merge - conf_merge failed"); } return rc; } int register_service(service_manager_t* services, const service_manager_conf_t* services_cf, handler_func handler, void* ctx, const str_t* location) { LOG_TRACE("register_service enter"); char *path = NULL; if (location == NULL) { LOG_ERROR("location is NULL"); goto error; } if (str_t_is_null(*location)) { LOG_ERROR("location is empty"); goto error; } LOG_DEBUG("location: %.*s", (int)location->len, location->data); fcgi_handler_t fcgi_handler = { .execute = handler, .ctx = ctx }; if (location->data[0] != '/') { LOG_ERROR("location must start with '/'"); goto error; } path = str_t_to_string(location); if (path == NULL) { LOG_ERROR("Could not copy location: %.*s", (int)location->len, location->data); goto error; } if (fcgi_register_handler(services->hfcgi, path, &fcgi_handler) != 0) { LOG_ERROR("Could not register handler by path: %s", path); goto error; } free(path); LOG_INFO("service registered, %.*s", (int) location->len, location->data); return 0; error: LOG_ERROR("register_service exit with error"); free(path); return -1; } service_handle_conf_t * service_manager_handle_conf_create(const conf_file_context_t conf_file, main_conf_t *main_cf, SERVICE_CONF_INIT_PROC handle_conf_init) { LOG_TRACE("service_manager_handle_conf_create enter"); service_handle_conf_t *hc = calloc(1, sizeof(service_handle_conf_t)); if (hc == NULL) { LOG_ERROR("calloc failed"); goto error; } handle_conf_init(hc); hc->conf = service_manager_handle_conf_load(conf_file, hc); if (hc->conf == NULL) { LOG_ERROR("could not load config"); goto error; } if (service_manager_handle_conf_merge(main_cf, hc)) { LOG_ERROR("could not merge config"); goto error; } LOG_TRACE("service_manager_handle_conf_create exit with success"); return hc; error: service_manager_handle_conf_free(hc); LOG_ERROR("service_manager_handle_conf_create exit with error"); return NULL; } int service_manager_load_conf(const char* config_file_name, service_manager_conf_t* services_cf) { conf_file_context_t conf_file = NULL; LOG_TRACE("service_manager_load_conf enter"); assert(config_file_name != NULL); assert(services_cf != NULL); memset(services_cf, 0, sizeof(service_manager_conf_t)); conf_file = conf_file_open_file(config_file_name); if (conf_file == NULL) { goto error; } if (main_conf_load(&services_cf->main_cf, config_file_name, conf_file)) { LOG_ERROR("main_conf_load failed"); goto error; } if (fcgi_load_conf(config_file_name, &services_cf->fcgi_cf)) { LOG_ERROR("FastCGI server configuraton loading failed"); goto error; } if (sign_conf_load(&services_cf->sign_cf, conf_file)) { LOG_ERROR("Sign service configuraton loading failed"); goto error; } if (verify_conf_load(&services_cf->verify_cf, conf_file)) { LOG_ERROR("Verify service configuraton loading failed"); goto error; } if (version_conf_load(&services_cf->version_cf)) { LOG_ERROR("Show version service configuraton loading failed"); goto error; } conf_file_close_file(conf_file); LOG_TRACE("service_manager_load_conf exit with success"); return 0; error: service_manager_clear_conf(services_cf); conf_file_close_file(conf_file); LOG_ERROR("service_manager_load_conf exit with error"); return -1; } void service_manager_clear_conf(service_manager_conf_t* services_cf) { assert(services_cf != NULL); version_conf_clear(&services_cf->version_cf); sign_conf_clear(&services_cf->sign_cf); verify_conf_clear(&services_cf->verify_cf); fcgi_clear_conf(&services_cf->fcgi_cf); main_conf_clear(&services_cf->main_cf); } int deinit_services(service_manager_t* services) { LOG_TRACE("deinit_services enter"); assert(services != NULL); fcgi_stop_server(services->hfcgi); fcgi_dispose_server(services->hfcgi); sign_service_free(services->hsign); verify_service_free(services->hverify); LOG_TRACE("deinit_services exit"); return 0; } int init_services(service_manager_t* services, const service_manager_conf_t* services_cf) { LOG_TRACE("init_services enter"); assert(services != NULL); assert(services_cf != NULL); /* create fcgi service */ services->hfcgi = fcgi_create_server(&services_cf->fcgi_cf); if (services->hfcgi == NULL) { LOG_ERROR("Could not create FastCGI server."); goto error; } if (!cryptopro_init(services_cf->main_cf.cp_file)) { LOG_ERROR("Could not init Cryptographic Provider"); goto error; } /* sign service */ services->hsign = sign_service_create(&services_cf->sign_cf, &services_cf->main_cf); if (services->hsign == NULL) { goto error; } if (register_service(services, services_cf, fcgi_sign_handler, services->hsign, &services_cf->sign_cf.location)) { LOG_ERROR("Could not register 'sign service'"); goto error; } /* verify service */ services->hverify = verify_service_create(&services_cf->verify_cf, &services_cf->main_cf); if (services->hverify == NULL) { goto error; } if (register_service(services, services_cf, fcgi_verify_handler, services->hverify, &services_cf->verify_cf.location)) { LOG_ERROR("Could not register 'verify service'"); goto error; } /* show version service */ if (register_service(services, services_cf, fcgi_version_handler, NULL, services_cf->version_cf.location)) { LOG_ERROR("Could not register 'show version service'"); goto error; } /* run fastcgi server */ if (fcgi_run_server(services->hfcgi) != 0) { LOG_ERROR("Could not run FastCGI server"); goto error; } LOG_TRACE("init_services exit with success"); return 0; error: deinit_services(services); LOG_ERROR("init_services exit with error"); return -1; }