ervu-sign-module/src/service_manager.c

287 lines
7.3 KiB
C
Raw Normal View History

#include "service_manager.h"
#include "utils/cryptopro.h"
#include <assert.h>
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;
}