273 lines
5.1 KiB
Plaintext
273 lines
5.1 KiB
Plaintext
%{
|
|
/* strongSwan config file parser (parser.y)
|
|
* Copyright (C) 2001 Mathieu Lafon - Arkoon Network Security
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License as published by the
|
|
* Free Software Foundation; either version 2 of the License, or (at your
|
|
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
* for more details.
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include <library.h>
|
|
#include <utils/debug.h>
|
|
|
|
#include "ipsec-parser.h"
|
|
|
|
#define YYERROR_VERBOSE
|
|
#define ERRSTRING_LEN 256
|
|
|
|
/**
|
|
* Bison
|
|
*/
|
|
static char parser_errstring[ERRSTRING_LEN+1];
|
|
|
|
extern void yyerror(const char *s);
|
|
extern int yylex (void);
|
|
extern void _parser_y_error(char *b, int size, const char *s);
|
|
|
|
/**
|
|
* Static Globals
|
|
*/
|
|
static int _save_errors_;
|
|
static config_parsed_t *_parser_cfg;
|
|
static kw_list_t **_parser_kw, *_parser_kw_last;
|
|
static char errbuf[ERRSTRING_LEN+1];
|
|
|
|
/**
|
|
* Gperf
|
|
*/
|
|
extern kw_entry_t *in_word_set (char *str, unsigned int len);
|
|
|
|
%}
|
|
|
|
%union { char *s; };
|
|
%token EQUAL FIRST_SPACES EOL CONFIG SETUP CONN CA INCLUDE FILE_VERSION
|
|
%token <s> STRING
|
|
|
|
%%
|
|
|
|
/*
|
|
* Config file
|
|
*/
|
|
|
|
config_file:
|
|
config_file section_or_include
|
|
| /* NULL */
|
|
;
|
|
|
|
section_or_include:
|
|
FILE_VERSION STRING EOL
|
|
{
|
|
free($2);
|
|
}
|
|
| CONFIG SETUP EOL
|
|
{
|
|
_parser_kw = &(_parser_cfg->config_setup);
|
|
_parser_kw_last = NULL;
|
|
} kw_section
|
|
| CONN STRING EOL
|
|
{
|
|
section_list_t *section = malloc_thing(section_list_t);
|
|
|
|
section->name = strdupnull($2);
|
|
section->kw = NULL;
|
|
section->next = NULL;
|
|
_parser_kw = &(section->kw);
|
|
if (!_parser_cfg->conn_first)
|
|
_parser_cfg->conn_first = section;
|
|
if (_parser_cfg->conn_last)
|
|
_parser_cfg->conn_last->next = section;
|
|
_parser_cfg->conn_last = section;
|
|
_parser_kw_last = NULL;
|
|
free($2);
|
|
} kw_section
|
|
| CA STRING EOL
|
|
{
|
|
section_list_t *section = malloc_thing(section_list_t);
|
|
section->name = strdupnull($2);
|
|
section->kw = NULL;
|
|
section->next = NULL;
|
|
_parser_kw = &(section->kw);
|
|
if (!_parser_cfg->ca_first)
|
|
_parser_cfg->ca_first = section;
|
|
if (_parser_cfg->ca_last)
|
|
_parser_cfg->ca_last->next = section;
|
|
_parser_cfg->ca_last = section;
|
|
_parser_kw_last = NULL;
|
|
free($2);
|
|
} kw_section
|
|
| INCLUDE STRING
|
|
{
|
|
extern void _parser_y_include (const char *f);
|
|
_parser_y_include($2);
|
|
free($2);
|
|
} EOL
|
|
| EOL
|
|
;
|
|
|
|
kw_section:
|
|
FIRST_SPACES statement_kw EOL kw_section
|
|
|
|
|
;
|
|
|
|
statement_kw:
|
|
STRING EQUAL STRING
|
|
{
|
|
kw_list_t *new;
|
|
kw_entry_t *entry = in_word_set($1, strlen($1));
|
|
|
|
if (entry == NULL)
|
|
{
|
|
snprintf(errbuf, ERRSTRING_LEN, "unknown keyword '%s'", $1);
|
|
yyerror(errbuf);
|
|
}
|
|
else if (_parser_kw)
|
|
{
|
|
new = (kw_list_t *)malloc_thing(kw_list_t);
|
|
new->entry = entry;
|
|
new->value = strdupnull($3);
|
|
new->next = NULL;
|
|
if (_parser_kw_last)
|
|
_parser_kw_last->next = new;
|
|
_parser_kw_last = new;
|
|
if (!*_parser_kw)
|
|
*_parser_kw = new;
|
|
}
|
|
free($1);
|
|
free($3);
|
|
}
|
|
| STRING EQUAL
|
|
{
|
|
free($1);
|
|
}
|
|
|
|
|
;
|
|
|
|
%%
|
|
|
|
void yyerror(const char *s)
|
|
{
|
|
if (_save_errors_)
|
|
_parser_y_error(parser_errstring, ERRSTRING_LEN, s);
|
|
}
|
|
|
|
config_parsed_t *parser_load_conf(const char *file)
|
|
{
|
|
config_parsed_t *cfg = NULL;
|
|
int err = 0;
|
|
FILE *f;
|
|
|
|
extern void _parser_y_init(const char *f);
|
|
extern void _parser_y_fini(void);
|
|
extern FILE *yyin;
|
|
|
|
memset(parser_errstring, 0, ERRSTRING_LEN+1);
|
|
|
|
cfg = (config_parsed_t *)malloc_thing(config_parsed_t);
|
|
if (cfg)
|
|
{
|
|
memset(cfg, 0, sizeof(config_parsed_t));
|
|
f = fopen(file, "r");
|
|
if (f)
|
|
{
|
|
yyin = f;
|
|
_parser_y_init(file);
|
|
_save_errors_ = 1;
|
|
_parser_cfg = cfg;
|
|
|
|
if (yyparse() !=0 )
|
|
{
|
|
if (parser_errstring[0] == '\0')
|
|
{
|
|
snprintf(parser_errstring, ERRSTRING_LEN, "Unknown error...");
|
|
}
|
|
_save_errors_ = 0;
|
|
while (yyparse() != 0);
|
|
err++;
|
|
}
|
|
else if (parser_errstring[0] != '\0')
|
|
{
|
|
err++;
|
|
}
|
|
else
|
|
{
|
|
/**
|
|
* Config valid
|
|
*/
|
|
}
|
|
|
|
fclose(f);
|
|
}
|
|
else
|
|
{
|
|
snprintf(parser_errstring, ERRSTRING_LEN, "can't load file '%s'", file);
|
|
err++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
snprintf(parser_errstring, ERRSTRING_LEN, "can't allocate memory");
|
|
err++;
|
|
}
|
|
|
|
if (err)
|
|
{
|
|
DBG1(DBG_APP, "%s", parser_errstring);
|
|
|
|
if (cfg)
|
|
parser_free_conf(cfg);
|
|
cfg = NULL;
|
|
}
|
|
|
|
_parser_y_fini();
|
|
return cfg;
|
|
}
|
|
|
|
static void parser_free_kwlist(kw_list_t *list)
|
|
{
|
|
kw_list_t *elt;
|
|
|
|
while (list)
|
|
{
|
|
elt = list;
|
|
list = list->next;
|
|
free(elt->value);
|
|
free(elt);
|
|
}
|
|
}
|
|
|
|
void parser_free_conf(config_parsed_t *cfg)
|
|
{
|
|
section_list_t *sec;
|
|
if (cfg)
|
|
{
|
|
parser_free_kwlist(cfg->config_setup);
|
|
while (cfg->conn_first)
|
|
{
|
|
sec = cfg->conn_first;
|
|
cfg->conn_first = cfg->conn_first->next;
|
|
free(sec->name);
|
|
parser_free_kwlist(sec->kw);
|
|
free(sec);
|
|
}
|
|
while (cfg->ca_first)
|
|
{
|
|
sec = cfg->ca_first;
|
|
cfg->ca_first = cfg->ca_first->next;
|
|
free(sec->name);
|
|
parser_free_kwlist(sec->kw);
|
|
free(sec);
|
|
}
|
|
free(cfg);
|
|
}
|
|
}
|