settings: Don't allow dots in section/key names anymore
authorTobias Brunner <tobias@strongswan.org>
Thu, 31 May 2018 09:46:29 +0000 (11:46 +0200)
committerTobias Brunner <tobias@strongswan.org>
Tue, 11 Sep 2018 16:30:18 +0000 (18:30 +0200)
This requires config changes if filelog is used with a path that
contains dots. This path must now be defined in the `path` setting of an
arbitrarily named subsection of `filelog`.  Without that change the
whole strongswan.conf file will fail to load, which some users might
not notice immediately.

conf/strongswan.conf.5.head.in
scripts/settings-test.c
src/libstrongswan/settings/settings_lexer.l
src/libstrongswan/settings/settings_parser.y
src/libstrongswan/tests/suites/test_settings.c

index c9db453..9337c19 100644 (file)
@@ -40,12 +40,6 @@ Section names and keys may contain any printable character except:
        . , : { } = " # \\n \\t space
 .EE
 .PP
-In rare circumstances \fB.\fP characters may be used in section names (e.g. for
-log file names in a filelog section), but should generally be avoided.
-To use \fB:\fP characters in section names (e.g. for Windows log file paths)
-they may be written as \fB::\fP, which the parser replaces with a single
-\fB:\fP.
-
 An example file in this format might look like this:
 .PP
 .EX
index 336da09..5811d70 100644 (file)
@@ -81,7 +81,6 @@ static void print_section(section_t *section, int level)
 
 /**
  * Recursively print a given section and all subsections/settings
- * FIXME: Doesn't work properly if any of the keys contain dots
  */
 static void print_settings_section(settings_t *settings, char *section,
                                                                   int level)
index 9cde119..c21ebbb 100644 (file)
@@ -49,8 +49,8 @@ static void include_files(parser_helper_t *ctx);
 /* type of our extra data */
 %option extra-type="parser_helper_t*"
 
-/* state used to scan names */
-%x nam
+/* state used to scan references */
+%x ref
 /* state used to scan values */
 %x val
 /* state used to scan include file patterns */
@@ -59,7 +59,7 @@ static void include_files(parser_helper_t *ctx);
 %x str
 
 /* pattern for section/key names */
-NAME [^#{}:,="\r\n\t ]
+NAME [^#{}:.,="\r\n\t ]
 
 %%
 
@@ -68,10 +68,15 @@ NAME [^#{}:,="\r\n\t ]
 \n|#.*\n                               /* eat newlines and comments at the end of a line */
 
 "{"                                            |
-"}"                                            |
-","                                            return yytext[0];
+"}"                                            return yytext[0];
 
-":"                                            return REFS;
+"."                                            return DOT;
+","                                            return COMMA;
+
+":"                                            {
+       yy_push_state(ref, yyscanner);
+       return COLON;
+}
 
 "="                                            {
        yy_push_state(val, yyscanner);
@@ -88,41 +93,26 @@ NAME [^#{}:,="\r\n\t ]
        return STRING_ERROR;
 }
 
-{NAME} {
-       yyextra->string_init(yyextra);
-       yyextra->string_add(yyextra, yytext);
-       yy_push_state(nam, yyscanner);
+{NAME}+                                {
+       yylval->s = strdup(yytext);
+       return NAME;
 }
 
-<nam>{
-       "::"                            {
-               yyextra->string_add(yyextra, yytext+1);
-       }
+<ref>{
+       [\t ]*#[^\r\n]*                 /* eat comments */
+       [\t\r ]+                                /* eat whitespace */
+       \n|#.*\n                                /* eat newlines and comments at the end of a line */
 
-       {NAME}+                         {
-               yyextra->string_add(yyextra, yytext);
+       ","                                             return COMMA;
+
+       {NAME}+(\.{NAME}+)* {
+               yylval->s = strdup(yytext);
+               return NAME;
        }
 
-       <<EOF>>                         |
-       .|[\r\n]                        {
-               if (*yytext)
-               {
-                       switch (yytext[0])
-                       {
-                               case '\n':
-                                       /* put the newline back to fix the line numbers */
-                                       unput('\n');
-                                       yy_set_bol(0);
-                                       break;
-                               default:
-                                       /* these are parsed outside of this start condition */
-                                       unput(yytext[0]);
-                                       break;
-                       }
-               }
+       .                                       {
+               unput(yytext[0]);
                yy_pop_state(yyscanner);
-               yylval->s = yyextra->string_get(yyextra);
-               return NAME;
        }
 }
 
index 7e72a90..cc1c917 100644 (file)
@@ -82,7 +82,9 @@ static int yylex(YYSTYPE *lvalp, parser_helper_t *ctx)
        array_t *refs;
 }
 %token <s> NAME STRING
-%token REFS ":"
+%token DOT "."
+%token COMMA ","
+%token COLON ":"
 %token NEWLINE STRING_ERROR
 
 /* ...and other symbols */
@@ -152,7 +154,7 @@ references:
                $$ = array_create(0, 0);
                array_insert($$, ARRAY_TAIL, $1);
        }
-       | references ',' NAME
+       | references "," NAME
        {
                array_insert($1, ARRAY_TAIL, $3);
                $$ = $1;
index 6259c9e..e060960 100644 (file)
@@ -1480,18 +1480,6 @@ START_TEST(test_valid)
        ck_assert(settings->load_files(settings, path, FALSE));
        verify_string("value", "valid.key");
        verify_string("value1", "valid.key1");
-
-       contents = chunk_from_str(
-               "c::\\Logfiles\\charon.log { dmn = 1 }");
-       ck_assert(chunk_write(contents, path, 0022, TRUE));
-       ck_assert(settings->load_files(settings, path, FALSE));
-       verify_string("1", "%s.dmn", "c:\\Logfiles\\charon.log");
-
-       contents = chunk_from_str(
-               "section { c::\\Logfiles\\charon.log = 1 }");
-       ck_assert(chunk_write(contents, path, 0022, TRUE));
-       ck_assert(settings->load_files(settings, path, FALSE));
-       verify_string("1", "section.%s", "c:\\Logfiles\\charon.log");
 }
 END_TEST
 
@@ -1539,6 +1527,16 @@ START_TEST(test_invalid)
                "incorrect :: ref {}");
        ck_assert(chunk_write(contents, path, 0022, TRUE));
        ck_assert(!settings->load_files(settings, path, FALSE));
+
+       contents = chunk_from_str(
+               "/var/log/daemon.log { dmn = 1 }");
+       ck_assert(chunk_write(contents, path, 0022, TRUE));
+       ck_assert(!settings->load_files(settings, path, FALSE));
+
+       contents = chunk_from_str(
+               "filelog { /var/log/daemon.log = 1 }");
+       ck_assert(chunk_write(contents, path, 0022, TRUE));
+       ck_assert(!settings->load_files(settings, path, FALSE));
 }
 END_TEST