37 if (strlen(*p) >= 3 && !strncmp(*p,
"--", 2))
46 return c ==
'\0' || isspace(c);
50parse_line(
const char *line,
char *p[],
const int n,
const char *file,
const int line_num,
53 const int STATE_INITIAL = 0;
54 const int STATE_READING_QUOTED_PARM = 1;
55 const int STATE_READING_UNQUOTED_PARM = 2;
56 const int STATE_DONE = 3;
57 const int STATE_READING_SQUOTED_PARM = 4;
59 const char *error_prefix =
"";
63 int state = STATE_INITIAL;
64 bool backslash =
false;
68 unsigned int parm_len = 0;
70 msglevel &= ~M_OPTERR;
74 error_prefix =
"ERROR: ";
82 if (!backslash && in ==
'\\' && state != STATE_READING_SQUOTED_PARM)
88 if (state == STATE_INITIAL)
92 if (in ==
';' || in ==
'#')
96 if (!backslash && in ==
'\"')
98 state = STATE_READING_QUOTED_PARM;
100 else if (!backslash && in ==
'\'')
102 state = STATE_READING_SQUOTED_PARM;
107 state = STATE_READING_UNQUOTED_PARM;
111 else if (state == STATE_READING_UNQUOTED_PARM)
113 if (!backslash &&
space(in))
122 else if (state == STATE_READING_QUOTED_PARM)
124 if (!backslash && in ==
'\"')
133 else if (state == STATE_READING_SQUOTED_PARM)
144 if (state == STATE_DONE)
148 memcpy(p[ret], parm, parm_len);
149 p[ret][parm_len] =
'\0';
150 state = STATE_INITIAL;
155 if (backslash && out)
157 if (!(out ==
'\\' || out ==
'\"' ||
space(out)))
160 msg(msglevel,
"%sOptions warning: Bad backslash ('\\') usage in %s:%d",
161 error_prefix, file, line_num);
164 "%sOptions warning: Bad backslash ('\\') usage in %s:%d: remember that backslashes are treated as shell-escapes and if you need to pass backslash characters as part of a Windows filename, you should use double backslashes such as \"c:\\\\" PACKAGE
166 error_prefix, file, line_num);
177 if (parm_len >=
SIZE(parm))
179 parm[
SIZE(parm) - 1] = 0;
180 msg(msglevel,
"%sOptions error: Parameter at %s:%d is too long (%d chars max): %s",
181 error_prefix, file, line_num, (
int)
SIZE(parm), parm);
184 parm[parm_len++] = out;
193 }
while (*c++ !=
'\0');
195 if (state == STATE_READING_QUOTED_PARM)
197 msg(msglevel,
"%sOptions error: No closing quotation (\") in %s:%d", error_prefix, file,
201 if (state == STATE_READING_SQUOTED_PARM)
203 msg(msglevel,
"%sOptions error: No closing single quotation (\') in %s:%d", error_prefix,
207 if (state != STATE_INITIAL)
209 msg(msglevel,
"%sOptions error: Residual parse state (%d) in %s:%d", error_prefix, state,
216 for (
i = 0;
i < ret; ++
i)
312 if (arg[0] ==
'<' && arg[
strlen(arg) - 1] ==
'>')
316 arg[
strlen(arg) - 1] =
'\0';
348 const int top_line,
const msglvl_t msglevel,
349 const unsigned int permission_mask,
unsigned int *option_types_found,
352 const int max_recursive_levels = 10;
359 if (level <= max_recursive_levels)
361 if (
streq(file,
"stdin"))
372 while (fgets(line,
sizeof(line),
fp))
380 "In %s:%d: Maximum option line length (%d) exceeded, line starts with %s",
385 if (line_num == 1 && strncmp(line,
"\xEF\xBB\xBF", 3) == 0)
389 if (
parse_line(line + offset, p,
SIZE(p) - 1, file, line_num, msglevel,
395 permission_mask, option_types_found,
es);
396 line_num += lines_inline;
406 msg(msglevel,
"In %s:%d: Error opening configuration file: %s", top_file, top_line,
413 "In %s:%d: Maximum recursive include levels exceeded in include attempt of file %s -- probably you have a configuration file that tries to include itself.",
414 top_file, top_line, file);
422 const msglvl_t msglevel,
const unsigned int permission_mask,
423 unsigned int *option_types_found,
struct env_set *
es)
441 option_types_found,
es);
472 for (
int i = 1;
i < argc; ++
i)
480 "I'm trying to parse \"%s\" as an --option parameter but I don't see a leading '--'",
518 const char *file =
"[PUSH-OPTIONS]";
558 option_types_found,
es);
563 option_types_found,
es);
580 msg(
D_PUSH,
"OPTIONS IMPORT: reading client specific options from: %s", filename);
591 option_types_found,
es);
void free_buf(struct buffer *buf)
void buf_clear(struct buffer *buf)
bool buf_printf(struct buffer *buf, const char *format,...)
void * gc_malloc(size_t size, bool clear, struct gc_arena *a)
struct buffer alloc_buf(size_t size)
bool buf_parse(struct buffer *buf, const int delim, char *line, const int size)
char * string_alloc(const char *str, struct gc_arena *gc)
static bool buf_copy(struct buffer *dest, const struct buffer *src)
static bool buf_safe(const struct buffer *buf, size_t len)
static void buf_set_read(struct buffer *buf, const uint8_t *data, size_t size)
static void secure_memzero(void *data, size_t len)
Securely zeroise memory.
static SERVICE_STATUS status
void remove_option(struct context *c, struct options *options, char *p[], bool is_inline, const char *file, int line, const msglvl_t msglevel, const unsigned int permission_mask, unsigned int *option_types_found, struct env_set *es)
Resets options found in the PUSH_UPDATE message that are preceded by the - flag.
void add_option(struct options *options, char *p[], bool is_inline, const char *file, int line, const int level, const msglvl_t msglevel, const unsigned int permission_mask, unsigned int *option_types_found, struct env_set *es)
void update_option(struct context *c, struct options *options, char *p[], bool is_inline, const char *file, int line, const int level, const msglvl_t msglevel, const unsigned int permission_mask, unsigned int *option_types_found, struct env_set *es, unsigned int *update_options_found)
Processes an option to update.
void parse_argv(struct options *options, const int argc, char *argv[], const msglvl_t msglevel, const unsigned int permission_mask, unsigned int *option_types_found, struct env_set *es)
static bool in_src_get(const struct in_src *is, char *line, const int size)
void read_config_file(struct options *options, const char *file, int level, const char *top_file, const int top_line, const msglvl_t msglevel, const unsigned int permission_mask, unsigned int *option_types_found, struct env_set *es)
static int check_inline_file_via_buf(struct buffer *multiline, char *p[], struct gc_arena *gc)
static int check_inline_file(struct in_src *is, char *p[], struct gc_arena *gc)
static bool space(char c)
static void bypass_doubledash(char **p)
int parse_line(const char *line, char *p[], const int n, const char *file, const int line_num, msglvl_t msglevel, struct gc_arena *gc)
void options_string_import(struct options *options, const char *config, const msglvl_t msglevel, const unsigned int permission_mask, unsigned int *option_types_found, struct env_set *es)
void options_server_import(struct options *o, const char *filename, msglvl_t msglevel, unsigned int permission_mask, unsigned int *option_types_found, struct env_set *es)
bool apply_push_options(struct context *c, struct options *options, struct buffer *buf, unsigned int permission_mask, unsigned int *option_types_found, struct env_set *es, bool is_update)
static int check_inline_file_via_fp(FILE *fp, char *p[], struct gc_arena *gc)
void read_config_string(const char *prefix, struct options *options, const char *config, const msglvl_t msglevel, const unsigned int permission_mask, unsigned int *option_types_found, struct env_set *es)
static char * read_inline_file(struct in_src *is, const char *close_tag, int *num_lines, struct gc_arena *gc)
bool check_push_update_option_flags(char *line, int *i, unsigned int *flags)
Checks the formatting and validity of options inside push-update messages.
bool apply_pull_filter(const struct options *o, char *line)
Filter an option line by all pull filters.
#define PUSH_OPT_TO_REMOVE
#define PUSH_OPT_OPTIONAL
Wrapper structure for dynamically allocated memory.
int capacity
Size in bytes of memory allocated by malloc().
int len
Length in bytes of the actual content within the allocated memory.
Contains all state information for one tunnel.
Garbage collection arena used to keep track of dynamically allocated memory.
struct buffer * multiline