summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvenaas <venaas>2008-05-29 11:02:26 +0000
committervenaas <venaas@e88ac4ed-0b26-0410-9574-a7f39faa03bf>2008-05-29 11:02:26 +0000
commit34b3d8a4025bc1c8ace4b1035597970ddf9d8a8d (patch)
treefcdf1d7e2b353bbc6f81b4246c128697a9941645
parente6793f425cac9a78f56f31cbe25f62c6b8fd350b (diff)
rewritten gconfig to not exit on errors
git-svn-id: https://svn.testnett.uninett.no/radsecproxy/trunk@263 e88ac4ed-0b26-0410-9574-a7f39faa03bf
-rw-r--r--gconfig.c218
-rw-r--r--gconfig.h4
-rw-r--r--radsecproxy.c68
3 files changed, 183 insertions, 107 deletions
diff --git a/gconfig.c b/gconfig.c
index 7a367e7..6f9da4e 100644
--- a/gconfig.c
+++ b/gconfig.c
@@ -18,14 +18,6 @@
#include "util.h"
#include "gconfig.h"
-char *mystringcopyx(const char *s) {
- char *t;
- t = stringcopy(s, 0);
- if (!t)
- debugx(1, DBG_ERR, "malloc failed");
- return t;
-}
-
/* returns NULL on error, where to continue parsing if token and ok. E.g. "" will return token with empty string */
char *strtokenquote(char *s, char **token, char *del, char *quote, char *comment) {
char *t = s, *q, *r;
@@ -60,6 +52,7 @@ char *strtokenquote(char *s, char **token, char *del, char *quote, char *comment
FILE *pushgconffile(struct gconffile **cf, const char *path) {
int i;
struct gconffile *newcf;
+ char *pathcopy;
FILE *f;
f = fopen(path, "r");
@@ -68,28 +61,39 @@ FILE *pushgconffile(struct gconffile **cf, const char *path) {
return NULL;
}
debug(DBG_DBG, "opened config file %s", path);
+
+ pathcopy = stringcopy(path, 0);
+ if (!pathcopy)
+ goto errmalloc;
+
if (!*cf) {
newcf = malloc(sizeof(struct gconffile) * 2);
if (!newcf)
- debugx(1, DBG_ERR, "malloc failed");
+ goto errmalloc;
newcf[1].file = NULL;
newcf[1].path = NULL;
} else {
for (i = 0; (*cf)[i].path; i++);
newcf = realloc(*cf, sizeof(struct gconffile) * (i + 2));
if (!newcf)
- debugx(1, DBG_ERR, "malloc failed");
+ goto errmalloc;
memmove(newcf + 1, newcf, sizeof(struct gconffile) * (i + 1));
}
newcf[0].file = f;
- newcf[0].path = mystringcopyx(path);
+ newcf[0].path = pathcopy;
*cf = newcf;
return f;
+
+ errmalloc:
+ free(pathcopy);
+ fclose(f);
+ debug(DBG_ERR, "malloc failed");
+ return NULL;
}
FILE *pushgconffiles(struct gconffile **cf, const char *cfgpath) {
int i;
- FILE *f;
+ FILE *f = NULL;
glob_t globbuf;
char *path, *curfile = NULL, *dir;
@@ -98,11 +102,17 @@ FILE *pushgconffiles(struct gconffile **cf, const char *cfgpath) {
path = (char *)cfgpath;
else {
/* dirname may modify its argument */
- curfile = mystringcopyx((*cf)->path);
+ curfile = stringcopy((*cf)->path, 0);
+ if (!curfile) {
+ debug(DBG_ERR, "malloc failed");
+ goto exit;
+ }
dir = dirname(curfile);
path = malloc(strlen(dir) + strlen(cfgpath) + 2);
- if (!path)
- debugx(1, DBG_ERR, "malloc failed");
+ if (!path) {
+ debug(DBG_ERR, "malloc failed");
+ goto exit;
+ }
strcpy(path, dir);
path[strlen(dir)] = '/';
strcpy(path + strlen(dir) + 1, cfgpath);
@@ -110,15 +120,17 @@ FILE *pushgconffiles(struct gconffile **cf, const char *cfgpath) {
memset(&globbuf, 0, sizeof(glob_t));
if (glob(path, 0, NULL, &globbuf)) {
debug(DBG_INFO, "could not glob %s", path);
- f = NULL;
- } else {
- for (i = globbuf.gl_pathc - 1; i >= 0; i--) {
- f = pushgconffile(cf, globbuf.gl_pathv[i]);
- if (!f)
- break;
- }
- globfree(&globbuf);
+ goto exit;
}
+
+ for (i = globbuf.gl_pathc - 1; i >= 0; i--) {
+ f = pushgconffile(cf, globbuf.gl_pathv[i]);
+ if (!f)
+ break;
+ }
+ globfree(&globbuf);
+
+ exit:
if (curfile) {
free(curfile);
free(path);
@@ -149,8 +161,10 @@ FILE *popgconffile(struct gconffile **cf) {
struct gconffile *openconfigfile(const char *file) {
struct gconffile *cf = NULL;
- if (!pushgconffile(&cf, file))
- debugx(1, DBG_ERR, "could not read config file %s\n%s", file, strerror(errno));
+ if (!pushgconffile(&cf, file)) {
+ debug(DBG_ERR, "could not read config file %s\n%s", file, strerror(errno));
+ return NULL;
+ }
debug(DBG_DBG, "reading config file %s", file);
return cf;
}
@@ -166,7 +180,7 @@ struct gconffile *openconfigfile(const char *file) {
* }
*/
-void getconfigline(struct gconffile **cf, char *block, char **opt, char **val, int *conftype) {
+int getconfigline(struct gconffile **cf, char *block, char **opt, char **val, int *conftype) {
char line[1024];
char *tokens[3], *s;
int tcount;
@@ -176,19 +190,21 @@ void getconfigline(struct gconffile **cf, char *block, char **opt, char **val, i
*conftype = 0;
if (!cf || !*cf || !(*cf)->file)
- return;
+ return 1;
for (;;) {
if (!fgets(line, 1024, (*cf)->file)) {
if (popgconffile(cf))
continue;
- return;
+ return 1;
}
s = line;
for (tcount = 0; tcount < 3; tcount++) {
s = strtokenquote(s, &tokens[tcount], " \t\r\n", "\"'", tcount ? NULL : "#");
- if (!s)
- debugx(1, DBG_ERR, "Syntax error in line starting with: %s", line);
+ if (!s) {
+ debug(DBG_ERR, "Syntax error in line starting with: %s", line);
+ return 0;
+ }
if (!tokens[tcount])
break;
}
@@ -197,59 +213,91 @@ void getconfigline(struct gconffile **cf, char *block, char **opt, char **val, i
if (**tokens == '}') {
if (block)
- return;
- debugx(1, DBG_ERR, "configuration error, found } with no matching {");
+ return 1;
+ debug(DBG_ERR, "configuration error, found } with no matching {");
+ return 0;
}
break;
}
switch (tcount) {
case 2:
- *opt = mystringcopyx(tokens[0]);
- *val = mystringcopyx(tokens[1]);
+ *opt = stringcopy(tokens[0], 0);
+ if (!*opt)
+ goto errmalloc;
+ *val = stringcopy(tokens[1], 0);
+ if (!*val)
+ goto errmalloc;
*conftype = CONF_STR;
break;
case 3:
if (tokens[1][0] == '=' && tokens[1][1] == '\0') {
- *opt = mystringcopyx(tokens[0]);
- *val = mystringcopyx(tokens[2]);
+ *opt = stringcopy(tokens[0], 0);
+ if (!*opt)
+ goto errmalloc;
+ *val = stringcopy(tokens[2], 0);
+ if (!*val)
+ goto errmalloc;
*conftype = CONF_STR;
break;
}
if (tokens[2][0] == '{' && tokens[2][1] == '\0') {
- *opt = mystringcopyx(tokens[0]);
- *val = mystringcopyx(tokens[1]);
+ *opt = stringcopy(tokens[0], 0);
+ if (!*opt)
+ goto errmalloc;
+ *val = stringcopy(tokens[1], 0);
+ if (!*val)
+ goto errmalloc;
*conftype = CONF_CBK;
break;
}
/* fall through */
default:
if (block)
- debugx(1, DBG_ERR, "configuration error in block %s, line starting with %s", block, tokens[0]);
- debugx(1, DBG_ERR, "configuration error, syntax error in line starting with %s", tokens[0]);
+ debug(DBG_ERR, "configuration error in block %s, line starting with %s", block, tokens[0]);
+ else
+ debug(DBG_ERR, "configuration error, syntax error in line starting with %s", tokens[0]);
+ return 0;
}
- if (!**val)
- debugx(1, DBG_ERR, "configuration error, option %s needs a non-empty value", *opt);
- return;
+ if (**val)
+ return 1;
+
+ debug(DBG_ERR, "configuration error, option %s needs a non-empty value", *opt);
+ goto errexit;
+
+ errmalloc:
+ debug(DBG_ERR, "malloc failed");
+ errexit:
+ free(*opt);
+ *opt = NULL;
+ free(*val);
+ *val = NULL;
+ return 0;
}
-void getgenericconfig(struct gconffile **cf, char *block, ...) {
+/* returns 1 if ok, 0 on error */
+/* caller must free returned values also on error */
+int getgenericconfig(struct gconffile **cf, char *block, ...) {
va_list ap;
- char *opt = NULL, *val, *word, *optval, **str = NULL, ***mstr = NULL;
+ char *opt = NULL, *val, *word, *optval, **str = NULL, ***mstr = NULL, **newmstr;
uint8_t *bln;
int type = 0, conftype = 0, n;
- void (*cbk)(struct gconffile **, char *, char *, char *) = NULL;
+ void (*cbk)(struct gconffile **, void *, char *, char *, char *) = NULL;
+ void *cbkarg = NULL;
for (;;) {
free(opt);
- getconfigline(cf, block, &opt, &val, &conftype);
+ if (!getconfigline(cf, block, &opt, &val, &conftype))
+ return 0;
if (!opt)
- return;
+ return 1;
if (conftype == CONF_STR && !strcasecmp(opt, "include")) {
- if (!pushgconffiles(cf, val))
- debugx(1, DBG_ERR, "failed to include config file %s", val);
+ if (!pushgconffiles(cf, val)) {
+ debug(DBG_ERR, "failed to include config file %s", val);
+ goto errexit;
+ }
free(val);
continue;
}
@@ -261,23 +309,26 @@ void getgenericconfig(struct gconffile **cf, char *block, ...) {
case CONF_STR:
str = va_arg(ap, char **);
if (!str)
- debugx(1, DBG_ERR, "getgenericconfig: internal parameter error");
+ goto errparam;
break;
case CONF_MSTR:
mstr = va_arg(ap, char ***);
if (!mstr)
- debugx(1, DBG_ERR, "getgenericconfig: internal parameter error");
+ goto errparam;
break;
case CONF_BLN:
bln = va_arg(ap, uint8_t *);
if (!bln)
- debugx(1, DBG_ERR, "getgenericconfig: internal parameter error");
+ goto errparam;
break;
case CONF_CBK:
- cbk = va_arg(ap, void (*)(struct gconffile **, char *, char *, char *));
+ cbk = va_arg(ap, void (*)(struct gconffile **, void *, char *, char *, char *));
+ if (!cbk)
+ goto errparam;
+ cbkarg = va_arg(ap, void *);
break;
default:
- debugx(1, DBG_ERR, "getgenericconfig: internal parameter error");
+ goto errparam;
}
if (!strcasecmp(opt, word))
break;
@@ -286,21 +337,25 @@ void getgenericconfig(struct gconffile **cf, char *block, ...) {
if (!word) {
if (block)
- debugx(1, DBG_ERR, "configuration error in block %s, unknown option %s", block, opt);
- debugx(1, DBG_ERR, "configuration error, unknown option %s", opt);
+ debug(DBG_ERR, "configuration error in block %s, unknown option %s", block, opt);
+ debug(DBG_ERR, "configuration error, unknown option %s", opt);
+ goto errexit;
}
if (((type == CONF_STR || type == CONF_MSTR || type == CONF_BLN) && conftype != CONF_STR) ||
(type == CONF_CBK && conftype != CONF_CBK)) {
if (block)
- debugx(1, DBG_ERR, "configuration error in block %s, wrong syntax for option %s", block, opt);
- debugx(1, DBG_ERR, "configuration error, wrong syntax for option %s", opt);
+ debug(DBG_ERR, "configuration error in block %s, wrong syntax for option %s", block, opt);
+ debug(DBG_ERR, "configuration error, wrong syntax for option %s", opt);
+ goto errexit;
}
switch (type) {
case CONF_STR:
- if (*str)
- debugx(1, DBG_ERR, "configuration error, option %s already set to %s", opt, *str);
+ if (*str) {
+ debug(DBG_ERR, "configuration error, option %s already set to %s", opt, *str);
+ goto errexit;
+ }
*str = val;
break;
case CONF_MSTR:
@@ -308,33 +363,41 @@ void getgenericconfig(struct gconffile **cf, char *block, ...) {
for (n = 0; (*mstr)[n]; n++);
else
n = 0;
- *mstr = realloc(*mstr, sizeof(char *) * (n + 2));
- if (!*mstr)
- debugx(1, DBG_ERR, "malloc failed");
- (*mstr)[n] = val;
- (*mstr)[n + 1] = NULL;
+ newmstr = realloc(*mstr, sizeof(char *) * (n + 2));
+ if (!newmstr) {
+ debug(DBG_ERR, "malloc failed");
+ goto errexit;
+ }
+ newmstr[n] = val;
+ newmstr[n + 1] = NULL;
+ *mstr = newmstr;
break;
case CONF_BLN:
if (!strcasecmp(val, "on"))
*bln = 1;
else if (!strcasecmp(val, "off"))
*bln = 0;
- else if (block)
- debugx(1, DBG_ERR, "configuration error in block %s, value for option %s must be on or off, not %s", block, opt, val);
- else
- debugx(1, DBG_ERR, "configuration error, value for option %s must be on or off, not %s", opt, val);
+ else {
+ if (block)
+ debug(DBG_ERR, "configuration error in block %s, value for option %s must be on or off, not %s", block, opt, val);
+ else
+ debug(DBG_ERR, "configuration error, value for option %s must be on or off, not %s", opt, val);
+ goto errexit;
+ }
break;
case CONF_CBK:
optval = malloc(strlen(opt) + strlen(val) + 2);
- if (!optval)
- debugx(1, DBG_ERR, "malloc failed");
+ if (!optval) {
+ debug(DBG_ERR, "malloc failed");
+ goto errexit;
+ }
sprintf(optval, "%s %s", opt, val);
- cbk(cf, optval, opt, val);
+ cbk(cf, cbkarg, optval, opt, val);
free(val);
free(optval);
continue;
default:
- debugx(1, DBG_ERR, "getgenericconfig: internal parameter error");
+ goto errparam;
}
if (block)
debug(DBG_DBG, "getgenericconfig: block %s: %s = %s", block, opt, val);
@@ -343,4 +406,11 @@ void getgenericconfig(struct gconffile **cf, char *block, ...) {
if (type == CONF_BLN)
free(val);
}
+
+ errparam:
+ debug(DBG_ERR, "getgenericconfig: internal parameter error");
+ errexit:
+ free(opt);
+ free(val);
+ return 0;
}
diff --git a/gconfig.h b/gconfig.h
index af44dac..55e8efe 100644
--- a/gconfig.h
+++ b/gconfig.h
@@ -8,8 +8,8 @@ struct gconffile {
FILE *file;
};
-void getconfigline(struct gconffile **cf, char *block, char **opt, char **val, int *conftype);
-void getgenericconfig(struct gconffile **cf, char *block, ...);
+int getconfigline(struct gconffile **cf, char *block, char **opt, char **val, int *conftype);
+int getgenericconfig(struct gconffile **cf, char *block, ...);
FILE *pushgconffile(struct gconffile **cf, const char *path);
FILE *pushgconffiles(struct gconffile **cf, const char *path);
FILE *popgconffile(struct gconffile **cf);
diff --git a/radsecproxy.c b/radsecproxy.c
index 5f18086..4833897 100644
--- a/radsecproxy.c
+++ b/radsecproxy.c
@@ -3159,7 +3159,7 @@ void addrewrite(char *value, char **attrs, char **vattrs) {
debug(DBG_DBG, "addrewrite: added rewrite block %s", value);
}
-void confclient_cb(struct gconffile **cf, char *block, char *opt, char *val) {
+void confclient_cb(struct gconffile **cf, void *arg, char *block, char *opt, char *val) {
char *type = NULL, *tls = NULL, *matchcertattr = NULL, *rewrite = NULL, *rewriteattr = NULL;
struct clsrvconf *conf;
@@ -3171,7 +3171,7 @@ void confclient_cb(struct gconffile **cf, char *block, char *opt, char *val) {
memset(conf, 0, sizeof(struct clsrvconf));
conf->certnamecheck = 1;
- getgenericconfig(cf, block,
+ if (!getgenericconfig(cf, block,
"type", CONF_STR, &type,
"host", CONF_STR, &conf->host,
"secret", CONF_STR, &conf->secret,
@@ -3181,8 +3181,9 @@ void confclient_cb(struct gconffile **cf, char *block, char *opt, char *val) {
"rewrite", CONF_STR, &rewrite,
"rewriteattribute", CONF_STR, &rewriteattr,
NULL
- );
-
+ ))
+ debugx(1, DBG_ERR, "configuration error");
+
conf->name = stringcopy(val, 0);
if (!conf->host)
conf->host = stringcopy(val, 0);
@@ -3224,7 +3225,7 @@ void confclient_cb(struct gconffile **cf, char *block, char *opt, char *val) {
}
}
-void confserver_cb(struct gconffile **cf, char *block, char *opt, char *val) {
+void confserver_cb(struct gconffile **cf, void *arg, char *block, char *opt, char *val) {
char *type = NULL, *tls = NULL, *matchcertattr = NULL, *rewrite = NULL;
struct clsrvconf *conf;
@@ -3236,7 +3237,7 @@ void confserver_cb(struct gconffile **cf, char *block, char *opt, char *val) {
memset(conf, 0, sizeof(struct clsrvconf));
conf->certnamecheck = 1;
- getgenericconfig(cf, block,
+ if (!getgenericconfig(cf, block,
"type", CONF_STR, &type,
"host", CONF_STR, &conf->host,
"port", CONF_STR, &conf->port,
@@ -3248,7 +3249,8 @@ void confserver_cb(struct gconffile **cf, char *block, char *opt, char *val) {
"CertificateNameCheck", CONF_BLN, &conf->certnamecheck,
"DynamicLookupCommand", CONF_STR, &conf->dynamiclookupcommand,
NULL
- );
+ ))
+ debugx(1, DBG_ERR, "configuration error");
conf->name = stringcopy(val, 0);
if (!conf->host)
@@ -3289,34 +3291,36 @@ void confserver_cb(struct gconffile **cf, char *block, char *opt, char *val) {
}
}
-void confrealm_cb(struct gconffile **cf, char *block, char *opt, char *val) {
+void confrealm_cb(struct gconffile **cf, void *arg, char *block, char *opt, char *val) {
char **servers = NULL, **accservers = NULL, *msg = NULL;
debug(DBG_DBG, "confrealm_cb called for %s", block);
- getgenericconfig(cf, block,
+ if (!getgenericconfig(cf, block,
"server", CONF_MSTR, &servers,
"accountingServer", CONF_MSTR, &accservers,
"ReplyMessage", CONF_STR, &msg,
NULL
- );
+ ))
+ debugx(1, DBG_ERR, "configuration error");
addrealm(realms, val, servers, accservers, msg);
}
-void conftls_cb(struct gconffile **cf, char *block, char *opt, char *val) {
+void conftls_cb(struct gconffile **cf, void *arg, char *block, char *opt, char *val) {
char *cacertfile = NULL, *cacertpath = NULL, *certfile = NULL, *certkeyfile = NULL, *certkeypwd = NULL;
debug(DBG_DBG, "conftls_cb called for %s", block);
- getgenericconfig(cf, block,
+ if (!getgenericconfig(cf, block,
"CACertificateFile", CONF_STR, &cacertfile,
"CACertificatePath", CONF_STR, &cacertpath,
"CertificateFile", CONF_STR, &certfile,
"CertificateKeyFile", CONF_STR, &certkeyfile,
"CertificateKeyPassword", CONF_STR, &certkeypwd,
NULL
- );
+ ))
+ debugx(1, DBG_ERR, "configuration error");
tlsadd(val, cacertfile, cacertpath, certfile, certkeyfile, certkeypwd);
free(cacertfile);
@@ -3326,16 +3330,17 @@ void conftls_cb(struct gconffile **cf, char *block, char *opt, char *val) {
free(certkeypwd);
}
-void confrewrite_cb(struct gconffile **cf, char *block, char *opt, char *val) {
+void confrewrite_cb(struct gconffile **cf, void *arg, char *block, char *opt, char *val) {
char **attrs = NULL, **vattrs = NULL;
debug(DBG_DBG, "confrewrite_cb called for %s", block);
- getgenericconfig(cf, block,
+ if (!getgenericconfig(cf, block,
"removeAttribute", CONF_MSTR, &attrs,
"removeVendorAttribute", CONF_MSTR, &vattrs,
NULL
- );
+ ))
+ debugx(1, DBG_ERR, "configuration error");
addrewrite(val, attrs, vattrs);
}
@@ -3366,21 +3371,22 @@ void getmainconfig(const char *configfile) {
if (!rewriteconfs)
debugx(1, DBG_ERR, "malloc failed");
- getgenericconfig(&cfs, NULL,
- "ListenUDP", CONF_STR, &options.listenudp,
- "ListenTCP", CONF_STR, &options.listentcp,
- "ListenAccountingUDP", CONF_STR, &options.listenaccudp,
- "SourceUDP", CONF_STR, &options.sourceudp,
- "SourceTCP", CONF_STR, &options.sourcetcp,
- "LogLevel", CONF_STR, &loglevel,
- "LogDestination", CONF_STR, &options.logdestination,
- "Client", CONF_CBK, confclient_cb,
- "Server", CONF_CBK, confserver_cb,
- "Realm", CONF_CBK, confrealm_cb,
- "TLS", CONF_CBK, conftls_cb,
- "Rewrite", CONF_CBK, confrewrite_cb,
- NULL
- );
+ if (!getgenericconfig(&cfs, NULL,
+ "ListenUDP", CONF_STR, &options.listenudp,
+ "ListenTCP", CONF_STR, &options.listentcp,
+ "ListenAccountingUDP", CONF_STR, &options.listenaccudp,
+ "SourceUDP", CONF_STR, &options.sourceudp,
+ "SourceTCP", CONF_STR, &options.sourcetcp,
+ "LogLevel", CONF_STR, &loglevel,
+ "LogDestination", CONF_STR, &options.logdestination,
+ "Client", CONF_CBK, confclient_cb, NULL,
+ "Server", CONF_CBK, confserver_cb, NULL,
+ "Realm", CONF_CBK, confrealm_cb, NULL,
+ "TLS", CONF_CBK, conftls_cb, NULL,
+ "Rewrite", CONF_CBK, confrewrite_cb, NULL,
+ NULL
+ ))
+ debugx(1, DBG_ERR, "configuration error");
tlsfree();
rewritefree();