X-Git-Url: https://tinc-vpn.org/git/browse?a=blobdiff_plain;f=src%2Fconf.c;h=87e2ec5426692acca12d4e4e3c5397e5a811422c;hb=f02d3ed3e135b5326003e7f69f8331ff6a3cc219;hp=e927abdbdfa9bb2ca9f9898caabd963ab8d5680a;hpb=7e74e00d167da659ba6c3db3e8822008d27c081b;p=tinc diff --git a/src/conf.c b/src/conf.c index e927abdb..87e2ec54 100644 --- a/src/conf.c +++ b/src/conf.c @@ -1,9 +1,9 @@ /* conf.c -- configuration code Copyright (C) 1998 Robert van der Meulen - 1998-2003 Ivo Timmermans - 2000-2003 Guus Sliepen - 2000 Cris van Pelt + 1998-2005 Ivo Timmermans + 2000-2006 Guus Sliepen + 2000 Cris van Pelt 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 @@ -19,7 +19,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id: conf.c,v 1.9.4.74 2003/08/08 14:59:27 guus Exp $ + $Id$ */ #include "system.h" @@ -33,12 +33,12 @@ avl_tree_t *config_tree; -int pingtimeout = 0; /* seconds before timeout */ +int pinginterval = 0; /* seconds between pings */ +int pingtimeout = 0; /* seconds to wait for response */ char *confbase = NULL; /* directory in which all config files are */ char *netname = NULL; /* name of the vpn network */ -static int config_compare(const config_t *a, const config_t *b) -{ +static int config_compare(const config_t *a, const config_t *b) { int result; result = strcasecmp(a->variable, b->variable); @@ -54,30 +54,26 @@ static int config_compare(const config_t *a, const config_t *b) return strcmp(a->file, b->file); } -void init_configuration(avl_tree_t ** config_tree) -{ +void init_configuration(avl_tree_t ** config_tree) { cp(); *config_tree = avl_alloc_tree((avl_compare_t) config_compare, (avl_action_t) free_config); } -void exit_configuration(avl_tree_t ** config_tree) -{ +void exit_configuration(avl_tree_t ** config_tree) { cp(); avl_delete_tree(*config_tree); *config_tree = NULL; } -config_t *new_config(void) -{ +config_t *new_config(void) { cp(); - return (config_t *) xmalloc_and_zero(sizeof(config_t)); + return xmalloc_and_zero(sizeof(config_t)); } -void free_config(config_t *cfg) -{ +void free_config(config_t *cfg) { cp(); if(cfg->variable) @@ -92,15 +88,13 @@ void free_config(config_t *cfg) free(cfg); } -void config_add(avl_tree_t *config_tree, config_t *cfg) -{ +void config_add(avl_tree_t *config_tree, config_t *cfg) { cp(); avl_insert(config_tree, cfg); } -config_t *lookup_config(const avl_tree_t *config_tree, char *variable) -{ +config_t *lookup_config(avl_tree_t *config_tree, char *variable) { config_t cfg, *found; cp(); @@ -120,8 +114,7 @@ config_t *lookup_config(const avl_tree_t *config_tree, char *variable) return found; } -config_t *lookup_config_next(const avl_tree_t *config_tree, const config_t *cfg) -{ +config_t *lookup_config_next(avl_tree_t *config_tree, const config_t *cfg) { avl_node_t *node; config_t *found; @@ -131,7 +124,7 @@ config_t *lookup_config_next(const avl_tree_t *config_tree, const config_t *cfg) if(node) { if(node->next) { - found = (config_t *) node->next->data; + found = node->next->data; if(!strcasecmp(found->variable, cfg->variable)) return found; @@ -141,8 +134,7 @@ config_t *lookup_config_next(const avl_tree_t *config_tree, const config_t *cfg) return NULL; } -bool get_config_bool(const config_t *cfg, bool *result) -{ +bool get_config_bool(const config_t *cfg, bool *result) { cp(); if(!cfg) @@ -162,8 +154,7 @@ bool get_config_bool(const config_t *cfg, bool *result) return false; } -bool get_config_int(const config_t *cfg, int *result) -{ +bool get_config_int(const config_t *cfg, int *result) { cp(); if(!cfg) @@ -178,8 +169,7 @@ bool get_config_int(const config_t *cfg, int *result) return false; } -bool get_config_string(const config_t *cfg, char **result) -{ +bool get_config_string(const config_t *cfg, char **result) { cp(); if(!cfg) @@ -190,8 +180,7 @@ bool get_config_string(const config_t *cfg, char **result) return true; } -bool get_config_address(const config_t *cfg, struct addrinfo **result) -{ +bool get_config_address(const config_t *cfg, struct addrinfo **result) { struct addrinfo *ai; cp(); @@ -212,18 +201,15 @@ bool get_config_address(const config_t *cfg, struct addrinfo **result) return false; } -bool get_config_subnet(const config_t *cfg, subnet_t ** result) -{ - subnet_t *subnet; +bool get_config_subnet(const config_t *cfg, subnet_t ** result) { + subnet_t subnet = {0}; cp(); if(!cfg) return false; - subnet = str2net(cfg->value); - - if(!subnet) { + if(!str2net(&subnet, cfg->value)) { logger(LOG_ERR, _("Subnet expected for configuration variable %s in %s line %d"), cfg->variable, cfg->file, cfg->line); return false; @@ -231,17 +217,16 @@ bool get_config_subnet(const config_t *cfg, subnet_t ** result) /* Teach newbies what subnets are... */ - if(((subnet->type == SUBNET_IPV4) - && !maskcheck(&subnet->net.ipv4.address, subnet->net.ipv4.prefixlength, sizeof(ipv4_t))) - || ((subnet->type == SUBNET_IPV6) - && !maskcheck(&subnet->net.ipv6.address, subnet->net.ipv6.prefixlength, sizeof(ipv6_t)))) { + if(((subnet.type == SUBNET_IPV4) + && !maskcheck(&subnet.net.ipv4.address, subnet.net.ipv4.prefixlength, sizeof(ipv4_t))) + || ((subnet.type == SUBNET_IPV6) + && !maskcheck(&subnet.net.ipv6.address, subnet.net.ipv6.prefixlength, sizeof(ipv6_t)))) { logger(LOG_ERR, _ ("Network address and prefix length do not match for configuration variable %s in %s line %d"), cfg->variable, cfg->file, cfg->line); - free(subnet); return false; } - *result = subnet; + *(*result = new_subnet()) = subnet; return true; } @@ -256,8 +241,7 @@ bool get_config_subnet(const config_t *cfg, subnet_t ** result) given, and buf needs to be expanded, the var pointed to by buflen will be increased. */ -static char *readline(FILE * fp, char **buf, size_t *buflen) -{ +static char *readline(FILE * fp, char **buf, size_t *buflen) { char *newline = NULL; char *p; char *line; /* The array that contains everything that has been read so far */ @@ -319,12 +303,11 @@ static char *readline(FILE * fp, char **buf, size_t *buflen) Parse a configuration file and put the results in the configuration tree starting at *base. */ -int read_config_file(avl_tree_t *config_tree, const char *fname) -{ +int read_config_file(avl_tree_t *config_tree, const char *fname) { int err = -2; /* Parse error */ FILE *fp; char *buffer, *line; - char *variable, *value; + char *variable, *value, *eol; int lineno = 0; int len; bool ignore = false; @@ -375,6 +358,10 @@ int read_config_file(avl_tree_t *config_tree, const char *fname) variable = value = line; + eol = line + strlen(line); + while(strchr("\t ", *--eol)) + *eol = '\0'; + len = strcspn(value, "\t ="); value += len; value += strspn(value, "\t "); @@ -384,6 +371,7 @@ int read_config_file(avl_tree_t *config_tree, const char *fname) } variable[len] = '\0'; + if(!*value) { logger(LOG_ERR, _("No value for variable `%s' on line %d while reading config file %s"), variable, lineno, fname); @@ -405,8 +393,7 @@ int read_config_file(avl_tree_t *config_tree, const char *fname) return err; } -bool read_server_config() -{ +bool read_server_config() { char *fname; int x; @@ -424,98 +411,7 @@ bool read_server_config() return x == 0; } -bool is_safe_path(const char *file) -{ -#if !(defined(HAVE_CYGWIN) || defined(HAVE_MINGW)) - char *p; - const char *f; - char x; - struct stat s; - char l[MAXBUFSIZE]; - - if(*file != '/') { - logger(LOG_ERR, _("`%s' is not an absolute path"), file); - return false; - } - - p = strrchr(file, '/'); - - if(p == file) /* It's in the root */ - p++; - - x = *p; - *p = '\0'; - - f = file; - -check1: - if(lstat(f, &s) < 0) { - logger(LOG_ERR, _("Couldn't stat `%s': %s"), f, strerror(errno)); - return false; - } - - if(s.st_uid != geteuid()) { - logger(LOG_ERR, _("`%s' is owned by UID %d instead of %d"), - f, s.st_uid, geteuid()); - return false; - } - - if(S_ISLNK(s.st_mode)) { - logger(LOG_WARNING, _("Warning: `%s' is a symlink"), f); - - if(readlink(f, l, MAXBUFSIZE) < 0) { - logger(LOG_ERR, _("Unable to read symbolic link `%s': %s"), f, - strerror(errno)); - return false; - } - - f = l; - goto check1; - } - - *p = x; - f = file; - -check2: - if(lstat(f, &s) < 0 && errno != ENOENT) { - logger(LOG_ERR, _("Couldn't stat `%s': %s"), f, strerror(errno)); - return false; - } - - if(errno == ENOENT) - return true; - - if(s.st_uid != geteuid()) { - logger(LOG_ERR, _("`%s' is owned by UID %d instead of %d"), - f, s.st_uid, geteuid()); - return false; - } - - if(S_ISLNK(s.st_mode)) { - logger(LOG_WARNING, _("Warning: `%s' is a symlink"), f); - - if(readlink(f, l, MAXBUFSIZE) < 0) { - logger(LOG_ERR, _("Unable to read symbolic link `%s': %s"), f, - strerror(errno)); - return false; - } - - f = l; - goto check2; - } - - if(s.st_mode & 0007) { - /* Accessible by others */ - logger(LOG_ERR, _("`%s' has unsecure permissions"), f); - return false; - } -#endif - - return true; -} - -FILE *ask_and_safe_open(const char *filename, const char *what, bool safe, const char *mode) -{ +FILE *ask_and_open(const char *filename, const char *what, const char *mode) { FILE *r; char *directory; char *fn; @@ -573,17 +469,6 @@ FILE *ask_and_safe_open(const char *filename, const char *what, bool safe, const return NULL; } - /* Then check the file for nasty attacks */ - if(safe) { - if(!is_safe_path(fn)) { /* Do not permit any directories that are readable or writeable by other users. */ - fprintf(stderr, _("The file `%s' (or any of the leading directories) has unsafe permissions.\n" - "I will not create or overwrite this file.\n"), fn); - fclose(r); - free(fn); - return NULL; - } - } - free(fn); return r;