warn about unknown settings in the configuration file

This commit is contained in:
yrutschle 2020-08-29 18:22:42 +02:00
parent 8b6e06e6c7
commit 9f99f296b1
4 changed files with 130 additions and 7 deletions

View File

@ -2,6 +2,9 @@ vNEXT:
Added symbol to support libconfig 1.4.9, still in Added symbol to support libconfig 1.4.9, still in
use in CentOS7. use in CentOS7.
Warn about unknown settings in the configuration
file.
v1.21: 11JUL2020 v1.21: 11JUL2020
WARNING: WARNING:
Moved configuration and command-line management to Moved configuration and command-line management to

View File

@ -1,5 +1,5 @@
/* Generated by conf2struct (https://www.rutschle.net/tech/conf2struct/README) /* Generated by conf2struct (https://www.rutschle.net/tech/conf2struct/README)
* on Tue Aug 11 17:35:54 2020. * on Sat Aug 29 18:12:55 2020.
# conf2struct: generate libconf parsers that read to structs # conf2struct: generate libconf parsers that read to structs
# Copyright (C) 2018-2019 Yves Rutschle # Copyright (C) 2018-2019 Yves Rutschle
@ -171,13 +171,30 @@ char* config_error_text(config_t* c) {
} }
#endif #endif
/* This is the same as config_setting_lookup_string() except
it allocates a new string which belongs to the caller */
static int myconfig_setting_lookup_stringcpy(
const config_setting_t* setting,
const char* name,
char** value)
{
const char* str;
*value = NULL;
if (config_setting_lookup_string(setting, name, &str) == CONFIG_TRUE) {
asprintf(value, "%s", str);
return CONFIG_TRUE;
} else {
return CONFIG_FALSE;
}
}
typedef int (*lookup_fn)(const config_setting_t*, const char*, void*); typedef int (*lookup_fn)(const config_setting_t*, const char*, void*);
lookup_fn lookup_fns[] = { lookup_fn lookup_fns[] = {
(lookup_fn)config_setting_lookup_bool, (lookup_fn)config_setting_lookup_bool,
(lookup_fn)config_setting_lookup_int, (lookup_fn)config_setting_lookup_int,
(lookup_fn)config_setting_lookup_int64, (lookup_fn)config_setting_lookup_int64,
(lookup_fn)config_setting_lookup_float, (lookup_fn)config_setting_lookup_float,
(lookup_fn)config_setting_lookup_string, (lookup_fn)myconfig_setting_lookup_stringcpy,
NULL, /* CFG_GROUP */ NULL, /* CFG_GROUP */
NULL, /* CFG_ARRAY */ NULL, /* CFG_ARRAY */
NULL, /* CFG_LIST */ NULL, /* CFG_LIST */
@ -1120,7 +1137,7 @@ static void print_setting(config_type type, void* val)
/* Changes all dashes to underscores in a string of /* Changes all dashes to underscores in a string of
* vice-versa */ * vice-versa */
void strswap_ud(const char target, char* str) static void strswap_ud(const char target, char* str)
{ {
char* c; char* c;
for (c = str; *c; c++) for (c = str; *c; c++)
@ -1130,7 +1147,7 @@ void strswap_ud(const char target, char* str)
/* Same as config_setting_lookup() but looks up with dash or /* Same as config_setting_lookup() but looks up with dash or
* underscore so `my_setting` and `my-setting` match the same */ * underscore so `my_setting` and `my-setting` match the same */
config_setting_t* config_setting_lookup_ud(config_setting_t* cfg, struct config_desc* desc) static config_setting_t* config_setting_lookup_ud(config_setting_t* cfg, struct config_desc* desc)
{ {
config_setting_t* setting; config_setting_t* setting;
char name[strlen(desc->name)+1];; char name[strlen(desc->name)+1];;
@ -1146,7 +1163,7 @@ config_setting_t* config_setting_lookup_ud(config_setting_t* cfg, struct config_
return setting; return setting;
} }
int lookup_typed_ud(config_setting_t* cfg, void* target, struct config_desc *desc) static int lookup_typed_ud(config_setting_t* cfg, void* target, struct config_desc *desc)
{ {
lookup_fn lookup_fn = lookup_fns[desc->type]; lookup_fn lookup_fn = lookup_fns[desc->type];
char name[strlen(desc->name)+1];; char name[strlen(desc->name)+1];;
@ -1160,6 +1177,22 @@ int lookup_typed_ud(config_setting_t* cfg, void* target, struct config_desc *des
return lookup_fn(cfg, name, ((char*)target) + desc->offset); return lookup_fn(cfg, name, ((char*)target) + desc->offset);
} }
/* Removes a setting, trying both underscores and dashes as
* name (so deleting 'my-setting' deletes both 'my_setting'
* and 'my-setting') */
static int setting_delete_ud(config_setting_t* cfg, struct config_desc *desc)
{
char name[strlen(desc->name)+1];;
strcpy(name, desc->name);
strswap_ud('_', name);
if (config_setting_remove(cfg, name) == CONFIG_TRUE)
return CONFIG_TRUE;
strswap_ud('-', name);
return config_setting_remove(cfg, name);
}
/* When traversing configuration, allocate memory for plural /* When traversing configuration, allocate memory for plural
* types, init for scalars */ * types, init for scalars */
static void read_block_init(void* target, config_setting_t* cfg, struct config_desc* desc) static void read_block_init(void* target, config_setting_t* cfg, struct config_desc* desc)
@ -1244,6 +1277,7 @@ static int read_block_setval(void* target,
TRACE_READ(("[%d] = ", i)); TRACE_READ(("[%d] = ", i));
print_setting(desc->array_type, (char*)block + desc->size *i); TRACE_READ(("\n")); print_setting(desc->array_type, (char*)block + desc->size *i); TRACE_READ(("\n"));
} }
setting_delete_ud(cfg, desc);
} }
break; break;
@ -1265,6 +1299,7 @@ static int read_block_setval(void* target,
return 0; return 0;
} }
print_setting(desc->type, (((char*)target) + desc->offset)); print_setting(desc->type, (((char*)target) + desc->offset));
setting_delete_ud(cfg, desc);
in_cfg = 1; in_cfg = 1;
} else { } else {
TRACE_READ((" not in config file")); TRACE_READ((" not in config file"));
@ -1556,6 +1591,86 @@ static int c2s_parse_file(const char* filename, config_t* c, char**errmsg)
return 1; return 1;
} }
/* Allocates a new string that represents the setting value, which must be a scalar */
static void scalar_to_string(char** strp, config_setting_t* s)
{
switch(config_setting_type(s)) {
case CONFIG_TYPE_INT:
asprintf(strp, "%d\n", config_setting_get_int(s));
break;
case CONFIG_TYPE_BOOL:
asprintf(strp, "%s\n", config_setting_get_bool(s) ? "[true]" : "[false]" );
break;
case CONFIG_TYPE_INT64:
asprintf(strp, "%lld\n", config_setting_get_int64(s));
break;
case CONFIG_TYPE_FLOAT:
asprintf(strp, "%lf\n", config_setting_get_float(s));
break;
case CONFIG_TYPE_STRING:
asprintf(strp, "%s\n", config_setting_get_string(s));
break;
default: /* This means a bug */
fprintf(stderr, "Unexpected type %d\n", config_setting_type(s));
exit(1);
}
}
/* Typesets all the settings in a configuration as a
* newly-allocated string. The string management is caller's
* responsability.
* Returns the number of scalars in the configuration */
static int cfg_as_string(config_setting_t* parent, const char* path, char** strp)
{
int i, len, res = 0;
config_setting_t* child;
char* subpath, *value, *old;
const char* name;
len = config_setting_length(parent);
for (i = 0; i < len; i++) {
child = config_setting_get_elem(parent, i);
name = config_setting_name(child);
if (!name) name = "";
if(config_setting_is_list(parent) ||
config_setting_is_array(parent)) {
asprintf(&subpath, "%s[%d]%s", path, config_setting_index(child), name);
} else {
asprintf(&subpath, "%s/%s", path, name);
}
if (config_setting_is_scalar(child)) {
scalar_to_string(&value, child);
/* Add value to the output string */
if (*strp) {
asprintf(&old, "%s", *strp);
free(*strp);
} else {
asprintf(&old, "%s", "");
}
asprintf(strp, "%s%s:%s", old, subpath, value);
free(value);
free(old);
res++; /* At least one scalar was found */
} else {
/* It's an aggregate -- descend into it */
res += cfg_as_string(child, subpath, strp);
}
free(subpath);
}
return res;
}
/* 0: success /* 0: success
<0: error */ <0: error */
int sslhcfg_cl_parse(int argc, char* argv[], struct sslhcfg_item* cfg) int sslhcfg_cl_parse(int argc, char* argv[], struct sslhcfg_item* cfg)
@ -1625,6 +1740,11 @@ int sslhcfg_cl_parse(int argc, char* argv[], struct sslhcfg_item* cfg)
return -1; return -1;
} }
errmsg = NULL;
res = cfg_as_string(s, "", &errmsg);
if (res)
fprintf(stderr, "Unknown settings:\n%s\n", errmsg);
return 0; return 0;
} }

View File

@ -1,5 +1,5 @@
/* Generated by conf2struct (https://www.rutschle.net/tech/conf2struct/README) /* Generated by conf2struct (https://www.rutschle.net/tech/conf2struct/README)
* on Tue Aug 11 17:35:54 2020. * on Sat Aug 29 18:12:55 2020.
# conf2struct: generate libconf parsers that read to structs # conf2struct: generate libconf parsers that read to structs
# Copyright (C) 2018-2019 Yves Rutschle # Copyright (C) 2018-2019 Yves Rutschle

View File

@ -33,7 +33,7 @@ protocols:
{ name: "regex"; host: "localhost"; port: "9011"; { name: "regex"; host: "localhost"; port: "9011";
regex_patterns: [ "^foo", "^bar" ]; regex_patterns: [ "^foo", "^bar" ];
minlength: 4; minlength: 4;
test_patterns: ( test_patterns: ( # this is used by the test script, not by sslh
{ pattern: "foo"; result: "ssh"; }, # After timeout { pattern: "foo"; result: "ssh"; }, # After timeout
{ pattern: "fooo"; result: "regex"; }, { pattern: "fooo"; result: "regex"; },
{ pattern: "bar"; result: "ssh"; }, { pattern: "bar"; result: "ssh"; },