diff options
-rw-r--r-- | CMakeLists.txt | 5 | ||||
-rw-r--r-- | config.h.in | 2 | ||||
-rw-r--r-- | src/config.c | 19 | ||||
-rw-r--r-- | src/config.l | 1 | ||||
-rw-r--r-- | src/config.y | 11 | ||||
-rw-r--r-- | src/fastd.h | 2 |
6 files changed, 29 insertions, 11 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 40bdb3c..9625deb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,6 +15,11 @@ endif(UECC_FOUND AND NACL_FOUND) set(WITH_PROTOCOL_ECFXP ${CRYPTO_FOUND} CACHE BOOL "Include ec25519-fhmqvc-xsalsa20-poly1305 protocol") +set(MAX_CONFIG_DEPTH 10 CACHE STRING "Maximum config include depth") + +# Ensure the value is numeric +math(EXPR MAX_CONFIG_DEPTH_NUM ${MAX_CONFIG_DEPTH}) + if(WITH_PROTOCOL_ECFXP AND NOT CRYPTO_FOUND) MESSAGE(FATAL_ERROR "libuecc and NaCl are required for the ec25519-fhmqvc-xsalsa20-poly1305 protocol") endif(WITH_PROTOCOL_ECFXP AND NOT CRYPTO_FOUND) diff --git a/config.h.in b/config.h.in index c1a1bd8..2a58ff1 100644 --- a/config.h.in +++ b/config.h.in @@ -30,4 +30,6 @@ #cmakedefine WITH_PROTOCOL_ECFXP +#define MAX_CONFIG_DEPTH @MAX_CONFIG_DEPTH_NUM@ + #endif /* _FASTD_CONFIG_H_ */ diff --git a/src/config.c b/src/config.c index d584264..db178df 100644 --- a/src/config.c +++ b/src/config.c @@ -88,31 +88,32 @@ static bool config_match(const char *opt, ...) { return match; } -static void fastd_read_config(fastd_context *ctx, fastd_config *conf, const char *filename) { - yyscan_t scanner; - fastd_config_pstate *ps; - int token; - YYSTYPE token_val; +void fastd_read_config(fastd_context *ctx, fastd_config *conf, const char *filename, int depth) { + if (depth >= MAX_CONFIG_DEPTH) + exit_error(ctx, "maximum config include depth exceeded"); - FILE *file; bool use_stdin = !strcmp(filename, "-"); + FILE *file; if (use_stdin) file = stdin; else file = fopen(filename, "r"); + yyscan_t scanner; fastd_config_yylex_init(&scanner); fastd_config_yyset_in(file, scanner); - ps = fastd_config_pstate_new(); + fastd_config_pstate *ps = fastd_config_pstate_new(); + int token; + YYSTYPE token_val; do { token = fastd_config_yylex(&token_val, scanner); if (token < 0) exit_error(ctx, "config error: %s", token_val.str); - } while(fastd_config_push_parse(ps, token, &token_val, ctx, conf) == YYPUSH_MORE); + } while(fastd_config_push_parse(ps, token, &token_val, ctx, conf, depth+1) == YYPUSH_MORE); fastd_config_pstate_delete(ps); fastd_config_yylex_destroy(scanner); @@ -145,7 +146,7 @@ void fastd_configure(fastd_context *ctx, fastd_config *conf, int argc, char *con while (i < argc) { IF_OPTION_ARG("-c", "--config") { - fastd_read_config(ctx, conf, arg); + fastd_read_config(ctx, conf, arg, 0); continue; } diff --git a/src/config.l b/src/config.l index 54d3447..231f228 100644 --- a/src/config.l +++ b/src/config.l @@ -23,6 +23,7 @@ peer { yylval->str = yytext; return TOK_PEER; } address { yylval->str = yytext; return TOK_ADDRESS; } secret { yylval->str = yytext; return TOK_SECRET; } key { yylval->str = yytext; return TOK_KEY; } +include { yylval->str = yytext; return TOK_INCLUDE; } [0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3} { if (!inet_pton(AF_INET, yytext, &yylval->addr)) { diff --git a/src/config.y b/src/config.y index 9868d57..2bc4fed 100644 --- a/src/config.y +++ b/src/config.y @@ -3,6 +3,7 @@ %name-prefix "fastd_config_" %parse-param {fastd_context *ctx} %parse-param {fastd_config *conf} +%parse-param {int depth} %code requires { #include <fastd.h> @@ -29,6 +30,7 @@ %token <str> TOK_ADDRESS %token <str> TOK_SECRET %token <str> TOK_KEY +%token <str> TOK_INCLUDE %token <addr> TOK_ADDR %token <addr6> TOK_ADDR6 @@ -42,7 +44,7 @@ #include <stdint.h> #include <peer.h> - void fastd_config_error(fastd_context *ctx, fastd_config *conf, char *s); + void fastd_config_error(fastd_context *ctx, fastd_config *conf, int depth, char *s); extern fastd_protocol fastd_protocol_null; @@ -70,6 +72,7 @@ statement: TOK_INTERFACE interface ';' | TOK_PROTOCOL protocol ';' | TOK_SECRET secret ';' | TOK_PEER peer '{' peer_conf '}' + | TOK_INCLUDE include ';' ; interface: TOK_STRING { free(conf->ifname); conf->ifname = strdup($1); } @@ -150,6 +153,10 @@ peer_key: TOK_STRING { free(conf->peers->key); conf->peers->key = strdup($1); } ; +include: TOK_STRING { fastd_read_config(ctx, conf, $1, depth); } + ; + + maybe_string: TOK_STRING | { $$ = ""; } ; @@ -169,6 +176,6 @@ port: TOK_INTEGER { } ; %% -void fastd_config_error(fastd_context *ctx, fastd_config *conf, char *s) { +void fastd_config_error(fastd_context *ctx, fastd_config *conf, int depth, char *s) { exit_error(ctx, "config error: %s", s); } diff --git a/src/fastd.h b/src/fastd.h index a8346c1..8aed925 100644 --- a/src/fastd.h +++ b/src/fastd.h @@ -122,6 +122,8 @@ struct _fastd_context { void fastd_printf(const fastd_context *ctx, const char *format, ...); + +void fastd_read_config(fastd_context *ctx, fastd_config *conf, const char *filename, int depth); void fastd_configure(fastd_context *ctx, fastd_config *conf, int argc, char *const argv[]); #define pr_log(ctx, level, prefix, args...) if ((ctx)->conf == NULL || (level) <= (ctx)->conf->loglevel) \ |