From 080d729f31b01a99bd3694cdde511b86d1a32e4c Mon Sep 17 00:00:00 2001
From: Lorenz Stechauner <lorenz.stechauner@necronda.net>
Date: Wed, 6 Jan 2021 15:49:52 +0100
Subject: [PATCH] Add config file

---
 src/cache.c           |   6 +-
 src/client.c          |  47 ++++++------
 src/config.c          | 171 +++++++++++++++++++++++++++++++++++++++++-
 src/config.h          |  19 ++++-
 src/necronda-server.c |  81 +++++++++-----------
 src/necronda-server.h |   6 +-
 6 files changed, 249 insertions(+), 81 deletions(-)

diff --git a/src/cache.c b/src/cache.c
index 70c569a..1748803 100644
--- a/src/cache.c
+++ b/src/cache.c
@@ -204,9 +204,13 @@ int cache_init() {
 int cache_unload() {
     int shm_id = shmget(SHM_KEY_CACHE, 0, 0);
     if (shm_id < 0) {
-        fprintf(stderr, ERR_STR "Unable to create shared memory: %s" CLR_STR "\n", strerror(errno));
+        fprintf(stderr, ERR_STR "Unable to get shared memory id: %s" CLR_STR "\n", strerror(errno));
+        shmdt(cache);
+        return -1;
     } else if (shmctl(shm_id, IPC_RMID, NULL) < 0) {
         fprintf(stderr, ERR_STR "Unable to configure shared memory: %s" CLR_STR "\n", strerror(errno));
+        shmdt(cache);
+        return -1;
     }
     shmdt(cache);
     return 0;
diff --git a/src/client.c b/src/client.c
index c7420dd..aef55ae 100644
--- a/src/client.c
+++ b/src/client.c
@@ -19,23 +19,13 @@ char *client_addr_str, *client_addr_str_ptr, *server_addr_str, *server_addr_str_
 
 struct timeval client_timeout = {.tv_sec = CLIENT_TIMEOUT, .tv_usec = 0};
 
-char *get_webroot(const char *http_host) {
-    char *webroot = malloc(strlen(webroot_base) + strlen(http_host) + 1);
-    unsigned long len = strlen(webroot_base);
-    while (webroot_base[len - 1] == '/') len--;
-    long pos = strchr(http_host, ':') - http_host;
-    sprintf(webroot, "%.*s/%.*s", (int) len, webroot_base, (int) (pos < 0 ? strlen(http_host) : pos), http_host);
-    return path_is_directory(webroot) ? webroot : NULL;
-}
-
-int get_dir_mode(const char *webroot) {
-    char buf[256];
-    struct stat statbuf;
-    sprintf(buf, "%s/.necronda-server/dir_mode_info", webroot);
-    if (stat(buf, &statbuf) == 0) return URI_DIR_MODE_INFO;
-    sprintf(buf, "%s/.necronda-server/dir_mode_list", webroot);
-    if (stat(buf, &statbuf) == 0) return URI_DIR_MODE_LIST;
-    return URI_DIR_MODE_FORBIDDEN;
+host_config *get_host_config(const char *host) {
+    for (int i = 0; i < MAX_HOST_CONFIG; i++) {
+        host_config *hc = &config[i];
+        if (hc->type == CONFIG_TYPE_UNSET) break;
+        if (strcmp(hc->name, host) == 0) return hc;
+    }
+    return NULL;
 }
 
 void client_terminate() {
@@ -49,12 +39,13 @@ int client_websocket_handler() {
 
 int client_request_handler(sock *client, unsigned long client_num, unsigned int req_num) {
     struct timespec begin, end;
-    int ret, client_keep_alive, dir_mode;
+    int ret, client_keep_alive;
     char buf0[1024], buf1[1024];
     char msg_buf[4096], msg_pre_buf[4096], err_msg[256];
     char buffer[CHUNK_SIZE];
     err_msg[0] = 0;
-    char host[256], *host_ptr, *hdr_connection, *webroot;
+    char host[256], *host_ptr, *hdr_connection;
+    host_config *conf;
     long content_length = 0;
     FILE *file = NULL;
     msg_buf[0] = 0;
@@ -133,18 +124,22 @@ int client_request_handler(sock *client, unsigned long client_num, unsigned int
     log_prefix = log_req_prefix;
     print(BLD_STR "%s %s" CLR_STR, req.method, req.uri);
 
-    // TODO Reverse Proxy
-    webroot = get_webroot(host);
-    if (webroot == NULL) {
+    conf = get_host_config(host);
+    if (conf == NULL) {
         res.status = http_get_status(307);
         sprintf(buf0, "https://%s%s", DEFAULT_HOST, req.uri);
         http_add_header_field(&res.hdr, "Location", buf0);
         goto respond;
     }
 
-    dir_mode = get_dir_mode(webroot);
+    if (conf->type != CONFIG_TYPE_LOCAL) {
+        // TODO Reverse Proxy
+        res.status = http_get_status(501);
+        goto respond;
+    }
+
     http_uri uri;
-    ret = uri_init(&uri, webroot, req.uri, dir_mode);
+    ret = uri_init(&uri, conf->local.webroot, req.uri, conf->local.dir_mode);
     if (ret != 0) {
         if (ret == 1) {
             sprintf(err_msg, "Invalid URI: has to start with slash.");
@@ -183,7 +178,7 @@ int client_request_handler(sock *client, unsigned long client_num, unsigned int
     } else if (uri.filename == NULL || (strlen(uri.pathinfo) > 0 && (int) uri.is_static)) {
         res.status = http_get_status(404);
         goto respond;
-    } else if (strlen(uri.pathinfo) != 0 && dir_mode != URI_DIR_MODE_INFO) {
+    } else if (strlen(uri.pathinfo) != 0 && conf->local.dir_mode != URI_DIR_MODE_INFO) {
         res.status = http_get_status(404);
         goto respond;
     }
@@ -460,7 +455,7 @@ int client_connection_handler(sock *client, unsigned long client_num) {
 
     clock_gettime(CLOCK_MONOTONIC, &begin);
 
-    if (dns_server != NULL) {
+    if (dns_server[0] != 0) {
         sprintf(buf, "dig @%s +short +time=1 -x %s", dns_server, client_addr_str);
         FILE *dig = popen(buf, "r");
         if (dig == NULL) {
diff --git a/src/config.c b/src/config.c
index 95cbe4f..1118b05 100644
--- a/src/config.c
+++ b/src/config.c
@@ -6,12 +6,179 @@
  */
 
 #include "config.h"
-
+#include "uri.h"
+#include <sys/ipc.h>
+#include <sys/shm.h>
 
 int config_init() {
+    int shm_id = shmget(SHM_KEY_CONFIG, MAX_HOST_CONFIG * sizeof(host_config), IPC_CREAT | IPC_EXCL | 0640);
+    if (shm_id < 0) {
+        fprintf(stderr, ERR_STR "Unable to create shared memory: %s" CLR_STR "\n", strerror(errno));
+        return -1;
+    }
+
+    void *shm = shmat(shm_id, NULL, SHM_RDONLY);
+    if (shm == (void *) -1) {
+        fprintf(stderr, ERR_STR "Unable to attach shared memory (ro): %s" CLR_STR "\n", strerror(errno));
+        return -2;
+    }
+    config = shm;
+
+    void *shm_rw = shmat(shm_id, NULL, 0);
+    if (shm_rw == (void *) -1) {
+        fprintf(stderr, ERR_STR "Unable to attach shared memory (rw): %s" CLR_STR "\n", strerror(errno));
+        return -3;
+    }
+    config = shm_rw;
+    memset(config, 0, MAX_HOST_CONFIG * sizeof(host_config));
+    shmdt(shm_rw);
+    config = shm;
     return 0;
 }
 
-int config_load() {
+int config_unload() {
+    int shm_id = shmget(SHM_KEY_CONFIG, 0, 0);
+    if (shm_id < 0) {
+        fprintf(stderr, ERR_STR "Unable to get shared memory id: %s" CLR_STR "\n", strerror(errno));
+        shmdt(config);
+        return -1;
+    } else if (shmctl(shm_id, IPC_RMID, NULL) < 0) {
+        fprintf(stderr, ERR_STR "Unable to configure shared memory: %s" CLR_STR "\n", strerror(errno));
+        shmdt(config);
+        return -1;
+    }
+    shmdt(config);
+    return 0;
+}
+
+int config_load(const char *filename) {
+    FILE *file = fopen(filename, "r");
+    if (file == NULL) {
+        fprintf(stderr, ERR_STR "Unable to open config file: %s" CLR_STR "\n", strerror(errno));
+        return -1;
+    }
+
+    fseek(file, 0, SEEK_END);
+    unsigned long len = ftell(file);
+    fseek(file, 0, SEEK_SET);
+    char *conf = malloc(len);
+    fread(conf, 1, len, file);
+    fclose(file);
+
+    host_config *tmp_config = malloc(MAX_HOST_CONFIG * sizeof(host_config));
+    memset(tmp_config, 0, MAX_HOST_CONFIG * sizeof(host_config));
+
+    int i = 0;
+    int mode = 0;
+    char *ptr = NULL;
+    char host[256], *source, *target;
+    host[0] = 0;
+    while ((ptr = strtok(ptr == NULL ? conf :  NULL, "\n")) != NULL) {
+        char *comment = strchr(ptr, '#');
+        if (comment != NULL) comment[0] = 0;
+        len = strlen(ptr);
+        if (ptr[0] == '[') {
+            if (ptr[len - 1] != ']') goto err;
+            strncpy(tmp_config[i].name, ptr + 1, len - 2);
+            i++;
+            continue;
+        } else if (i == 0) {
+            if (len > 12 && strncmp(ptr, "certificate", 11) == 0 && (ptr[11] == ' ' || ptr[11] == '\t')) {
+                source = ptr + 11;
+                target = cert_file;
+            } else if (len > 12 && strncmp(ptr, "private_key", 11) == 0 && (ptr[11] == ' ' || ptr[11] == '\t')) {
+                source = ptr + 11;
+                target = key_file;
+            } else if (len > 10 && strncmp(ptr, "geoip_dir", 9) == 0 && (ptr[9] == ' ' || ptr[9] == '\t')) {
+                source = ptr + 9;
+                target = geoip_dir;
+            } else if (len > 11 && strncmp(ptr, "dns_server", 10) == 0 && (ptr[10] == ' ' || ptr[10] == '\t')) {
+                source = ptr + 10;
+                target = dns_server;
+            }
+        } else {
+            host_config *hc = &tmp_config[i - 1];
+            if (len > 8 && strncmp(ptr, "webroot", 7) == 0 && (ptr[7] == ' ' || ptr[7] == '\t')) {
+                source = ptr + 7;
+                target = hc->local.webroot;
+                if (hc->type != 0 && hc->type != CONFIG_TYPE_LOCAL) {
+                    goto err;
+                } else {
+                    hc->type = CONFIG_TYPE_LOCAL;
+                }
+            } else if (len > 9 && strncmp(ptr, "dir_mode", 8) == 0 && (ptr[8] == ' ' || ptr[8] == '\t')) {
+                source = ptr + 8;
+                target = NULL;
+                mode = 1;
+                if (hc->type != 0 && hc->type != CONFIG_TYPE_LOCAL) {
+                    goto err;
+                } else {
+                    hc->type = CONFIG_TYPE_LOCAL;
+                }
+            } else if (len > 9 && strncmp(ptr, "hostname", 8) == 0 && (ptr[8] == ' ' || ptr[8] == '\t')) {
+                source = ptr + 8;
+                target = hc->rev_proxy.hostname;
+                if (hc->type != 0 && hc->type != CONFIG_TYPE_REVERSE_PROXY) {
+                    goto err;
+                } else {
+                    hc->type = CONFIG_TYPE_REVERSE_PROXY;
+                }
+            } else if (len > 5 && strncmp(ptr, "port", 4) == 0 && (ptr[4] == ' ' || ptr[4] == '\t')) {
+                source = ptr + 4;
+                target = NULL;
+                mode = 2;
+                if (hc->type != 0 && hc->type != CONFIG_TYPE_REVERSE_PROXY) {
+                    goto err;
+                } else {
+                    hc->type = CONFIG_TYPE_REVERSE_PROXY;
+                }
+            }
+        }
+        char *end_ptr = source + strlen(source) - 1;
+        while (source[0] == ' ' || source[0] == '\t') source++;
+        while (end_ptr[0] == ' ' || end_ptr[0] == '\t') end_ptr--;
+        if (end_ptr <= source) {
+            err:
+            free(conf);
+            free(tmp_config);
+            fprintf(stderr, ERR_STR "Unable to parse config file" CLR_STR "\n");
+            return -2;
+        }
+        end_ptr[1] = 0;
+        if (target != NULL) {
+            strcpy(target, source);
+        } else if (mode == 1) {
+            if (strcmp(source, "forbidden") == 0) {
+                tmp_config[i - 1].local.dir_mode = URI_DIR_MODE_FORBIDDEN;
+            } else if (strcmp(source, "info") == 0) {
+                tmp_config[i - 1].local.dir_mode = URI_DIR_MODE_INFO;
+            } else if (strcmp(source, "list") == 0) {
+                tmp_config[i - 1].local.dir_mode = URI_DIR_MODE_LIST;
+            } else {
+                goto err;
+            }
+        } else if (mode == 2) {
+            tmp_config[i - 1].rev_proxy.port = (unsigned short) strtoul(source, NULL, 10);
+        }
+    }
+
+    free(conf);
+
+    int shm_id = shmget(SHM_KEY_CONFIG, 0, 0);
+    if (shm_id < 0) {
+        fprintf(stderr, ERR_STR "Unable to get shared memory id: %s" CLR_STR "\n", strerror(errno));
+        shmdt(config);
+        return -3;
+    }
+
+    void *shm_rw = shmat(shm_id, NULL, 0);
+    if (shm_rw == (void *) -1) {
+        free(tmp_config);
+        fprintf(stderr, ERR_STR "Unable to attach shared memory (rw): %s" CLR_STR "\n", strerror(errno));
+        return -4;
+    }
+    memcpy(shm_rw, tmp_config, MAX_HOST_CONFIG * sizeof(host_config));
+    free(tmp_config);
+    shmdt(shm_rw);
     return 0;
 }
diff --git a/src/config.h b/src/config.h
index 5dda945..fc7b144 100644
--- a/src/config.h
+++ b/src/config.h
@@ -9,24 +9,35 @@
 #ifndef NECRONDA_SERVER_CONFIG_H
 #define NECRONDA_SERVER_CONFIG_H
 
+#define CONFIG_TYPE_UNSET 0
+#define CONFIG_TYPE_LOCAL 1
+#define CONFIG_TYPE_REVERSE_PROXY 2
+
+
 typedef struct {
     int type;
     char name[256];
     union {
         struct {
-            char address[256];
+            char hostname[256];
             unsigned short port;
-        };
+        } rev_proxy;
         struct {
             char webroot[256];
             unsigned char dir_mode;
-        };
+        } local;
     };
 } host_config;
 
 
+host_config *config;
+char cert_file[256], key_file[256], geoip_dir[256], dns_server[256];
+
+
 int config_init();
 
-int config_load();
+int config_load(const char *filename);
+
+int config_unload();
 
 #endif //NECRONDA_SERVER_CONFIG_H
diff --git a/src/necronda-server.c b/src/necronda-server.c
index 8524966..539f07d 100644
--- a/src/necronda-server.c
+++ b/src/necronda-server.c
@@ -19,6 +19,7 @@
 
 
 int active = 1;
+const char *config_file;
 
 
 void openssl_init() {
@@ -88,6 +89,7 @@ void destroy() {
         fprintf(stderr, ERR_STR "Killed %i child process(es)" CLR_STR "\n", kills);
     }
     cache_unload();
+    config_unload();
     exit(2);
 }
 
@@ -156,6 +158,7 @@ void terminate() {
         fprintf(stderr, "Goodbye\n");
     }
     cache_unload();
+    config_unload();
     exit(0);
 }
 
@@ -190,68 +193,42 @@ int main(int argc, const char *argv[]) {
     }
     printf("Necronda Web Server\n");
 
+    ret = config_init();
+    if (ret != 0) {
+        return 1;
+    }
+
+    config_file = NULL;
     for (int i = 1; i < argc; i++) {
         const char *arg = argv[i];
-        unsigned long len = strlen(arg);
         if (strcmp(arg, "-h") == 0 || strcmp(arg, "--help") == 0) {
-            printf("Usage: necronda-server [-h] -w <PATH> -c <CERT-FILE> -p <KEY-FILE> [-g <DB-DIR>] [-d <DNS-SERVER>]\n"
+            printf("Usage: necronda-server [-h] [-c <CONFIG-FILE>]\n"
                    "\n"
                    "Options:\n"
-                   "  -c, --cert <CERT-FILE>    path to the full chain certificate file\n"
-                   "  -d, --dns <DNS-SERVER>    ip address or hostname of a DNS server for dig\n"
-                   "  -g, --geoip <DB-DIR>      path to a Maxmind GeoIP Database file\n"
-                   "  -h, --help                print this dialogue\n"
-                   "  -p, --privkey <KEY-FILE>  path to the private key file\n"
-                   "  -w, --webroot <PATH>      path to the web root directory\n");
+                   "  -c, --config <CONFIG-FILE>  path to the config file. If not provided, default will be used\n"
+                   "  -h, --help                  print this dialogue\n");
+            config_unload();
             return 0;
-        } else if (strcmp(arg, "-w") == 0 || strcmp(arg, "--webroot") == 0) {
+        } else if (strcmp(arg, "-c") == 0 || strcmp(arg, "--config") == 0) {
             if (i == argc - 1) {
-                fprintf(stderr, ERR_STR "Unable to parse argument %s, usage: --webroot <WEBROOT>" CLR_STR "\n", arg);
+                fprintf(stderr, ERR_STR "Unable to parse argument %s, usage: --config <CONFIG-FILE>" CLR_STR "\n", arg);
+                config_unload();
                 return 1;
             }
-            webroot_base = argv[++i];
-        } else if (strcmp(arg, "-c") == 0 || strcmp(arg, "--cert") == 0) {
-            if (i == argc - 1) {
-                fprintf(stderr, ERR_STR "Unable to parse argument %s, usage: --cert <CERT-FILE>" CLR_STR "\n", arg);
-                return 1;
-            }
-            cert_file = argv[++i];
-        } else if (strcmp(arg, "-p") == 0 || strcmp(arg, "--privkey") == 0) {
-            if (i == argc - 1) {
-                fprintf(stderr, ERR_STR "Unable to parse argument %s, usage: --privkey <KEY-FILE>" CLR_STR "\n", arg);
-                return 1;
-            }
-            key_file = argv[++i];
-        } else if (strcmp(arg, "-g") == 0 || strcmp(arg, "--geoip") == 0) {
-            if (i == argc - 1) {
-                fprintf(stderr, ERR_STR "Unable to parse argument %s, usage: --geoip <DB-DIR>" CLR_STR "\n", arg);
-                return 1;
-            }
-            geoip_dir = argv[++i];
-        } else if (strcmp(arg, "-d") == 0 || strcmp(arg, "--dns") == 0) {
-            if (i == argc - 1) {
-                fprintf(stderr, ERR_STR "Unable to parse argument %s, usage: --dns <DNS-SERVER>" CLR_STR "\n", arg);
-                return 1;
-            }
-            dns_server = argv[++i];
+            config_file = argv[++i];
         } else {
             fprintf(stderr, ERR_STR "Unable to parse argument '%s'" CLR_STR "\n", arg);
+            config_unload();
             return 1;
         }
     }
 
-    if (webroot_base == NULL) {
-        fprintf(stderr, ERR_STR "Error: --webroot is missing" CLR_STR "\n");
-        return 1;
-    }
-    if (cert_file == NULL) {
-        fprintf(stderr, ERR_STR "Error: --cert is missing" CLR_STR "\n");
-        return 1;
-    }
-    if (key_file == NULL) {
-        fprintf(stderr, ERR_STR "Error: --privkey is missing" CLR_STR "\n");
+    ret = config_load(config_file == NULL ? DEFAULT_CONFIG_FILE : config_file);
+    if (ret != 0) {
+        config_unload();
         return 1;
     }
+    printf("%s %s\n", cert_file, key_file);
 
     sockets[0] = socket(AF_INET6, SOCK_STREAM, 0);
     if (sockets[0] < 0) goto socket_err;
@@ -259,12 +236,14 @@ int main(int argc, const char *argv[]) {
     if (sockets[1] < 0) {
         socket_err:
         fprintf(stderr, ERR_STR "Unable to create socket: %s" CLR_STR "\n", strerror(errno));
+        config_unload();
         return 1;
     }
 
     for (int i = 0; i < NUM_SOCKETS; i++) {
         if (setsockopt(sockets[i], SOL_SOCKET, SO_REUSEADDR, &YES, sizeof(YES)) < 0) {
             fprintf(stderr, ERR_STR "Unable to set options for socket %i: %s" CLR_STR "\n", i, strerror(errno));
+            config_unload();
             return 1;
         }
     }
@@ -273,16 +252,18 @@ int main(int argc, const char *argv[]) {
     if (bind(sockets[1], (struct sockaddr *) &addresses[1], sizeof(addresses[1])) < 0) {
         bind_err:
         fprintf(stderr, ERR_STR "Unable to bind socket to address: %s" CLR_STR "\n", strerror(errno));
+        config_unload();
         return 1;
     }
 
     signal(SIGINT, terminate);
     signal(SIGTERM, terminate);
 
-    if (geoip_dir != NULL) {
+    if (geoip_dir[0] != 0) {
         DIR *geoip = opendir(geoip_dir);
         if (geoip == NULL) {
             fprintf(stderr, ERR_STR "Unable to open GeoIP dir: %s" CLR_STR "\n", strerror(errno));
+            config_unload();
             return 1;
         }
         struct dirent *dir;
@@ -291,18 +272,21 @@ int main(int argc, const char *argv[]) {
             if (strcmp(dir->d_name + strlen(dir->d_name) - 5, ".mmdb") != 0) continue;
             if (i >= MAX_MMDB) {
                 fprintf(stderr, ERR_STR "Too many .mmdb files" CLR_STR "\n");
+                config_unload();
                 return 1;
             }
             sprintf(buf, "%s/%s", geoip_dir, dir->d_name);
             ret = MMDB_open(buf, 0, &mmdbs[i]);
             if (ret != MMDB_SUCCESS) {
                 fprintf(stderr, ERR_STR "Unable to open .mmdb file: %s" CLR_STR "\n", MMDB_strerror(ret));
+                config_unload();
                 return 1;
             }
             i++;
         }
         if (i == 0) {
             fprintf(stderr, ERR_STR "No .mmdb files found in %s" CLR_STR "\n", geoip_dir);
+            config_unload();
             return 1;
         }
         closedir(geoip);
@@ -324,17 +308,20 @@ int main(int argc, const char *argv[]) {
     if (SSL_CTX_use_certificate_chain_file(client.ctx, cert_file) != 1) {
         fprintf(stderr, ERR_STR "Unable to load certificate chain file: %s: %s" CLR_STR "\n",
                 ERR_reason_error_string(ERR_get_error()), cert_file);
+        config_unload();
         return 1;
     }
     if (SSL_CTX_use_PrivateKey_file(client.ctx, key_file, SSL_FILETYPE_PEM) != 1) {
         fprintf(stderr, ERR_STR "Unable to load private key file: %s: %s" CLR_STR "\n",
                 ERR_reason_error_string(ERR_get_error()), key_file);
+        config_unload();
         return 1;
     }
 
     for (int i = 0; i < NUM_SOCKETS; i++) {
         if (listen(sockets[i], LISTEN_BACKLOG) < 0) {
             fprintf(stderr, ERR_STR "Unable to listen on socket %i: %s" CLR_STR "\n", i, strerror(errno));
+            config_unload();
             return 1;
         }
     }
@@ -349,6 +336,7 @@ int main(int argc, const char *argv[]) {
 
     ret = cache_init();
     if (ret < 0) {
+        config_unload();
         return 1;
     } else if (ret != 0) {
         return 0;
@@ -363,6 +351,7 @@ int main(int argc, const char *argv[]) {
         ready_sockets_num = select(max_socket_fd + 1, &read_socket_fds, NULL, NULL, &timeout);
         if (ready_sockets_num < 0) {
             fprintf(stderr, ERR_STR "Unable to select sockets: %s" CLR_STR "\n", strerror(errno));
+            terminate();
             return 1;
         }
 
diff --git a/src/necronda-server.h b/src/necronda-server.h
index 0a586c4..3415433 100644
--- a/src/necronda-server.h
+++ b/src/necronda-server.h
@@ -32,6 +32,7 @@
 #define NUM_SOCKETS 2
 #define MAX_CHILDREN 1024
 #define MAX_MMDB 3
+#define MAX_HOST_CONFIG 64
 #define LISTEN_BACKLOG 16
 #define REQ_PER_CONNECTION 100
 #define CLIENT_TIMEOUT 3600
@@ -70,13 +71,14 @@
 #ifndef PHP_FPM_SOCKET
 #define PHP_FPM_SOCKET "/var/run/php-fpm/php-fpm.sock"
 #endif
+#ifndef DEFAULT_CONFIG_FILE
+#define DEFAULT_CONFIG_FILE "/etc/necronda-server/necronda-server.conf"
+#endif
 
 int sockets[NUM_SOCKETS];
 pid_t children[MAX_CHILDREN];
 MMDB_s mmdbs[MAX_MMDB];
 
-const char *cert_file, *key_file, *webroot_base, *geoip_dir, *dns_server;
-
 typedef struct {
     unsigned int enc:1;
     int socket;