Read configuration file

This commit is contained in:
Nikos Mavrogiannopoulos
2013-01-30 17:33:17 +01:00
parent e54667b71c
commit 0b6fc4c696
6 changed files with 162 additions and 13 deletions
+1 -1
View File
@@ -1,5 +1,5 @@
AM_CPPFLAGS = -I$(srcdir)../gl/ -I$(builddir)../gl/ \
-I$(srcdir)/ -I$(builddir)/../
-I$(srcdir)/ -I$(builddir)/../ -I$(srcdir)/../libopts
EXTRA_DIST = ocserv.1
+141 -1
View File
@@ -23,10 +23,146 @@
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <pwd.h>
#include <grp.h>
#include <fcntl.h>
#include <ocserv-args.h>
#include <autoopts/options.h>
#include <vpn.h>
#define MAX_ENTRIES 64
#define READ_MULTI_LINE(name, s_name, num, mand) \
val = optionGetValue(pov, name); \
if (val != NULL && val->valType == OPARG_TYPE_STRING) { \
if (s_name == NULL) { \
num = 0; \
s_name = malloc(sizeof(char*)*MAX_ENTRIES); \
do { \
if (val && !strcmp(val->pzName, name)==0) \
continue; \
s_name[num] = strdup(val->v.strVal); \
num++; \
if (num>=MAX_ENTRIES) \
break; \
} while((val = optionNextValue(pov, val)) != NULL); \
s_name[num] = NULL; \
} \
} else if (mand != 0) { \
fprintf(stderr, "Configuration option %s is mandatory.\n", name); \
}
#define READ_BOOLEAN(name, s_name, mand) \
val = optionGetValue(pov, name); \
if (val != NULL) { \
s_name = 1; \
} else if (mand != 0) { \
fprintf(stderr, "Configuration option %s is mandatory.\n", name); \
}
#define READ_STRING(name, s_name, mand) \
val = optionGetValue(pov, name); \
if (val != NULL && val->valType == OPARG_TYPE_STRING) \
s_name = strdup(val->v.strVal); \
else if (mand != 0) { \
fprintf(stderr, "Configuration option %s is mandatory.\n", name); \
}
#define READ_NUMERIC(name, s_name, mand) \
val = optionGetValue(pov, name); \
if (val != NULL) { \
if (val->valType == OPARG_TYPE_NUMERIC) \
s_name = val->v.longVal; \
else if (val->valType == OPARG_TYPE_STRING) \
s_name = atoi(val->v.strVal); \
} else if (mand != 0) { \
fprintf(stderr, "Configuration option %s is mandatory.\n", name); \
}
static void parse_cfg_file(const char* file, struct cfg_st *config)
{
tOptionValue const * pov;
const tOptionValue* val;
char tmpstr[256];
char** auth;
unsigned auth_size;
unsigned j;
pov = configFileLoad(file);
if (pov == NULL) {
fprintf(stderr, "Error loading config file %s\n", file);
exit(1);
}
READ_MULTI_LINE("auth", auth, auth_size, 1);
for (j=0;j<auth_size;j++) {
if (strcasecmp(auth[j], "pam") == 0) {
config->auth_types |= AUTH_TYPE_PAM;
} else if (strcasecmp(auth[j], "certificate") == 0) {
config->auth_types |= AUTH_TYPE_CERTIFICATE;
config->cert_req = GNUTLS_CERT_REQUIRE;
} else {
fprintf(stderr, "Unknown auth method: %s\n", auth[j]);
exit(1);
}
free(auth[j]);
}
free(auth);
READ_STRING("listen-host", config->name, 0);
READ_NUMERIC("tcp-port", config->port, 1);
READ_NUMERIC("udp-port", config->udp_port, 1);
READ_STRING("server-cert", config->cert, 1);
READ_STRING("server-key", config->key, 1);
READ_STRING("ca-cert", config->ca, 0);
READ_STRING("crl", config->crl, 0);
READ_STRING("cert-user-oid", config->cert_user_oid, 0);
READ_STRING("tls-priorities", config->priorities, 0);
READ_STRING("chroot-dir", config->chroot_dir, 0);
READ_NUMERIC("cookie-validity", config->cookie_validity, 1);
READ_STRING("cookie-db", config->db_file, 1);
val = optionGetValue(pov, "run-as-user"); \
if (val != NULL && val->valType == OPARG_TYPE_STRING) {
const struct passwd* pwd = getpwnam(val->v.strVal);
if (pwd == NULL) {
fprintf(stderr, "Unknown user: %s\n", val->v.strVal);
exit(1);
}
config->uid = pwd->pw_uid;
}
val = optionGetValue(pov, "run-as-group"); \
if (val != NULL && val->valType == OPARG_TYPE_STRING) {
const struct group *grp = getgrnam(val->v.strVal);
if (grp == NULL) {
fprintf(stderr, "Unknown group: %s\n", val->v.strVal);
exit(1);
}
config->gid = grp->gr_gid;
}
READ_STRING("device", config->network.name, 1);
READ_STRING("ipv4-network", config->network.ipv4, 0);
READ_STRING("ipv4-netmask", config->network.ipv4_netmask, 0);
READ_STRING("ipv4-dns", config->network.ipv4_dns, 0);
READ_STRING("ipv6-network", config->network.ipv6, 0);
READ_STRING("ipv6-netmask", config->network.ipv6_netmask, 0);
READ_STRING("ipv6-dns", config->network.ipv6_dns, 0);
READ_MULTI_LINE("route", config->network.routes, config->network.routes_size, 0);
}
int cmd_parser (int argc, char **argv, struct cfg_st* config)
{
@@ -42,8 +178,12 @@ int cmd_parser (int argc, char **argv, struct cfg_st* config)
if (HAVE_OPT(CONFIG)) {
cfg_file = OPT_ARG(CONFIG);
} else {
fprintf(stderr, "Please use the -c option to specify a configuration file, or --help for more information.\n");
fprintf(stderr, "%s -c [config]\nUse %s --help for more information.\n", argv[0], argv[0]);
exit(1);
}
parse_cfg_file(cfg_file, config);
return 0;
}
+1 -1
View File
@@ -2,7 +2,7 @@
*
* DO NOT EDIT THIS FILE (ocserv-args.c)
*
* It has been AutoGen-ed January 30, 2013 at 01:39:04 AM by AutoGen 5.16
* It has been AutoGen-ed January 30, 2013 at 05:20:00 PM by AutoGen 5.16
* From the definitions ocserv-args.def
* and the template file options
*
+10 -3
View File
@@ -53,6 +53,9 @@ An example configuration file follows.
#auth = "pam,certificate"
auth = "pam"
# Use listen-host to limit to specific IPs or to the IPs of a provided hostname.
# listen-host = [IP|HOSTNAME]
# TCP port number
tcp-port = 3333
@@ -68,6 +71,10 @@ server-key = /path/to/key.pem
# is set.
#ca-cert = /path/to/ca.pem
# The object identifier that will be used to read the user ID in the client certificate.
# The object identifier should be part of the certificate's DN
#cert-user-oid = 0.9.2342.19200300.100.1.1
# A revocation list of ca-cert is set
#crl = /path/to/crl.pem
@@ -93,10 +100,10 @@ run-as-group = nogroup
device = vpns
ipv4-address = 192.168.1.0
ipv4-mask = 255.255.255.0
ipv4-network = 192.168.1.0
ipv4-netmask = 255.255.255.0
# Use the keywork local to advertize the local P-t-P address as DNS server
# network-ipv4-dns = 192.168.2.1
# ipv4-dns = 192.168.2.1
ipv4-dns = local
#ipv6-address =
+1 -1
View File
@@ -2,7 +2,7 @@
*
* DO NOT EDIT THIS FILE (ocserv-args.h)
*
* It has been AutoGen-ed January 30, 2013 at 01:39:04 AM by AutoGen 5.16
* It has been AutoGen-ed January 30, 2013 at 05:20:00 PM by AutoGen 5.16
* From the definitions ocserv-args.def
* and the template file options
*
+8 -6
View File
@@ -22,37 +22,39 @@ extern int syslog_open;
#define MAX(x,y) ((x)>(y)?(x):(y))
/* the first is generic, for the methods that require a username password */
#define AUTH_TYPE_USERNAME_PASS (1<<0)
#define AUTH_TYPE_CERTIFICATE (1<<1)
#define MAX_NETWORKS 24
#define MAX_ROUTES 64
#define AUTH_TYPE_PAM (1<<1 | AUTH_TYPE_USERNAME_PASS)
#define AUTH_TYPE_CERTIFICATE (1<<2)
struct vpn_st {
const char *name; /* device name */
const char *ipv4_netmask;
const char *ipv4;
const char *ipv4_local; /* local IPv4 address */
const char *ipv6_netmask;
const char *ipv6;
const char *ipv6_local; /* local IPv6 address */
const char *ipv4_dns;
const char *ipv6_dns;
unsigned int mtu;
const char *routes[MAX_ROUTES];
const char **routes;
unsigned int routes_size;
};
struct cfg_st {
const char *name;
unsigned int port;
unsigned int udp_port;
const char *cert;
const char *key;
const char *ca;
const char *crl;
const char *cert_user_oid; /* The OID that will be used to extract the username */
unsigned int auth_types; /* or'ed sequence of AUTH_TYPE */
gnutls_certificate_request_t cert_req;
const char *priorities;
const char *chroot_dir; /* where the xml files are served from */
unsigned int auth_types; /* or'ed sequence of AUTH_TYPE */
time_t cookie_validity; /* in seconds */
const char *db_file;
unsigned foreground;