Eat trailing whitespace in config files.
[tinc] / src / conf.c
index e57eb8b..369a5fb 100644 (file)
@@ -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.70 2003/08/02 15:27:24 guus Exp $
+    $Id: conf.c,v 1.9.4.77 2003/12/12 19:52:24 guus Exp $
 */
 
 #include "system.h"
@@ -73,7 +73,7 @@ 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)
@@ -131,7 +131,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;
@@ -214,16 +214,14 @@ bool get_config_address(const config_t *cfg, struct addrinfo **result)
 
 bool get_config_subnet(const config_t *cfg, subnet_t ** result)
 {
-       subnet_t *subnet;
+       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 +229,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;
 }
@@ -324,7 +321,7 @@ 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;
@@ -359,11 +356,11 @@ int read_config_file(avl_tree_t *config_tree, const char *fname)
 
                lineno++;
 
-               if(*line == '#')
+               if(!*line || *line == '#')
                        continue;
 
                if(ignore) {
-                       if(!strncmp(variable, "-----END", 8))
+                       if(!strncmp(line, "-----END", 8))
                                ignore = false;
                        continue;
                }
@@ -375,6 +372,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,13 +385,13 @@ 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);
                        break;
                }
 
-               logger(LOG_DEBUG, "%s=%s", variable, value);
                cfg = new_config();
                cfg->variable = xstrdup(variable);
                cfg->value = xstrdup(value);
@@ -425,97 +426,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;
@@ -546,7 +457,11 @@ FILE *ask_and_safe_open(const char *filename, const char *what, bool safe, const
                        fn = xstrdup(filename);
        }
 
-       if(!strchr(fn, '/') || fn[0] != '/') {
+#ifdef HAVE_MINGW
+       if(fn[0] != '\\' && fn[0] != '/' && !strchr(fn, ':')) {
+#else
+       if(fn[0] != '/') {
+#endif
                /* The directory is a relative path or a filename. */
                char *p;
 
@@ -570,17 +485,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;