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)
309 if (arg[0] ==
'<' && arg[
strlen(arg) - 1] ==
'>')
313 arg[
strlen(arg) - 1] =
'\0';
345 const int top_line,
const msglvl_t msglevel,
346 const uint64_t permission_mask, uint64_t *option_types_found,
349 const int max_recursive_levels = 10;
355 if (level <= max_recursive_levels)
357 if (
streq(file,
"stdin"))
368 while (fgets(line,
sizeof(line),
fp))
376 "In %s:%d: Maximum option line length (%d) exceeded, line starts with %s",
381 if (line_num == 1 && strncmp(line,
"\xEF\xBB\xBF", 3) == 0)
385 if (
parse_line(line + offset, p,
SIZE(p) - 1, file, line_num, msglevel,
391 permission_mask, option_types_found, es);
392 line_num += lines_inline;
402 msg(msglevel,
"In %s:%d: Error opening configuration file: %s", top_file, top_line,
409 "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.",
410 top_file, top_line, file);
418 const msglvl_t msglevel,
const uint64_t permission_mask,
419 uint64_t *option_types_found,
struct env_set *es)
437 option_types_found, es);
468 for (
int i = 1;
i < argc; ++
i)
476 "I'm trying to parse \"%s\" as an --option parameter but I don't see a leading '--'",
514 const char *file =
"[PUSH-OPTIONS]";
553 option_types_found, es);
558 option_types_found, es);
568 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)
Free the memory allocated for a buffer.
void buf_clear(struct buffer *buf)
Zeroise and reset a buffer.
bool buf_printf(struct buffer *buf, const char *format,...)
printf-style append to a buffer with overflow check.
void * gc_malloc(size_t size, bool clear, struct gc_arena *a)
Allocate memory and, optionally, zero it.
struct buffer alloc_buf(size_t size)
Allocate a buffer of the given size.
bool buf_parse(struct buffer *buf, const int delim, char *line, const int size)
Extract the next token from a buffer, delimited by a given character.
char * string_alloc(const char *str, struct gc_arena *gc)
Duplicate a string, allocating memory under garbage collection.
#define BSTR(buf)
Return the buffer content pointer cast to char *.
static bool buf_copy(struct buffer *dest, const struct buffer *src)
Copy the content of one buffer to the end of another.
#define streq(x, y)
helper to work around the semantics of the strcmp() return value
static bool buf_safe(const struct buffer *buf, size_t len)
Check whether len bytes can be appended to a buffer.
static void buf_set_read(struct buffer *buf, const uint8_t *data, size_t size)
Initialise a buffer with an externally provided read-only memory region.
static void secure_memzero(void *data, size_t len)
Securely zeroise memory.
size_t strlcat(char *dest, const char *src, size_t maxlen)
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 uint64_t permission_mask, uint64_t *option_types_found, struct env_set *es)
Resets options found in the PUSH_UPDATE message that are preceded by the - flag.
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 uint64_t permission_mask, uint64_t *option_types_found, struct env_set *es)
Processes an option to update.
void add_option(struct options *options, char *p[], bool is_inline, const char *file, int line, const int level, const msglvl_t msglevel, const uint64_t permission_mask, uint64_t *option_types_found, struct env_set *es)
static char * read_inline_file(const struct in_src *is, const char *close_tag, int *num_lines, struct gc_arena *gc)
static bool in_src_get(const struct in_src *is, char *line, const int size)
void options_server_import(struct options *o, const char *filename, msglvl_t msglevel, const uint64_t permission_mask, uint64_t *option_types_found, struct env_set *es)
static int check_inline_file_via_buf(struct buffer *multiline, char *p[], struct gc_arena *gc)
static bool space(char c)
static void bypass_doubledash(char **p)
static int check_inline_file(const struct in_src *is, char *p[], struct gc_arena *gc)
void parse_argv(struct options *options, const int argc, char *argv[], const msglvl_t msglevel, const uint64_t permission_mask, uint64_t *option_types_found, struct env_set *es)
void options_string_import(struct options *options, const char *config, const msglvl_t msglevel, const uint64_t permission_mask, uint64_t *option_types_found, struct env_set *es)
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 read_config_file(struct options *options, const char *file, int level, const char *top_file, const int top_line, const msglvl_t msglevel, const uint64_t permission_mask, uint64_t *option_types_found, struct env_set *es)
static int check_inline_file_via_fp(FILE *fp, char *p[], struct gc_arena *gc)
bool apply_push_options(struct context *c, struct options *options, struct buffer *buf, uint64_t permission_mask, uint64_t *option_types_found, struct env_set *es, bool is_update)
void read_config_string(const char *prefix, struct options *options, const char *config, const msglvl_t msglevel, const uint64_t permission_mask, uint64_t *option_types_found, struct env_set *es)
bool check_push_update_option_flags(char *line, int *i, uint64_t *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