2024-08-21 12:47:16 +03:00
|
|
|
#include "service_manager.h"
|
|
|
|
|
|
2024-11-14 12:16:55 +03:00
|
|
|
#include "utils/cryptopro.h"
|
|
|
|
|
|
2024-08-21 12:47:16 +03:00
|
|
|
#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;
|
|
|
|
|
}
|
2024-11-14 12:16:55 +03:00
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
2024-08-21 12:47:16 +03:00
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
2024-11-14 12:16:55 +03:00
|
|
|
version_conf_clear(&services_cf->version_cf);
|
2024-08-21 12:47:16 +03:00
|
|
|
sign_conf_clear(&services_cf->sign_cf);
|
2024-11-14 12:16:55 +03:00
|
|
|
verify_conf_clear(&services_cf->verify_cf);
|
2024-08-21 12:47:16 +03:00
|
|
|
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);
|
|
|
|
|
|
2024-11-14 12:16:55 +03:00
|
|
|
verify_service_free(services->hverify);
|
|
|
|
|
|
2024-08-21 12:47:16 +03:00
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2024-11-14 12:16:55 +03:00
|
|
|
if (!cryptopro_init(services_cf->main_cf.cp_file)) {
|
|
|
|
|
LOG_ERROR("Could not init Cryptographic Provider");
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* sign service */
|
2025-02-24 15:43:55 +03:00
|
|
|
services->hsign = sign_service_create(&services_cf->sign_cf, &services_cf->main_cf);
|
2024-08-21 12:47:16 +03:00
|
|
|
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;
|
|
|
|
|
}
|
2024-11-14 12:16:55 +03:00
|
|
|
|
|
|
|
|
/* verify service */
|
2025-02-24 16:17:45 +03:00
|
|
|
services->hverify = verify_service_create(&services_cf->verify_cf, &services_cf->main_cf);
|
2024-11-14 12:16:55 +03:00
|
|
|
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;
|
|
|
|
|
}
|
2024-08-21 12:47:16 +03:00
|
|
|
|
|
|
|
|
/* 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;
|
|
|
|
|
}
|