diff options
Diffstat (limited to 'usr.sbin/ospf6d')
-rw-r--r-- | usr.sbin/ospf6d/ospf6d.c | 26 | ||||
-rw-r--r-- | usr.sbin/ospf6d/parse.y | 224 |
2 files changed, 149 insertions, 101 deletions
diff --git a/usr.sbin/ospf6d/ospf6d.c b/usr.sbin/ospf6d/ospf6d.c index fd128cbe3af..0a70a3f44ae 100644 --- a/usr.sbin/ospf6d/ospf6d.c +++ b/usr.sbin/ospf6d/ospf6d.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ospf6d.c,v 1.3 2007/10/11 21:25:37 claudio Exp $ */ +/* $OpenBSD: ospf6d.c,v 1.4 2007/10/13 16:35:22 deraadt Exp $ */ /* * Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org> @@ -55,7 +55,6 @@ int check_child(pid_t, const char *); void main_dispatch_ospfe(int, short, void *); void main_dispatch_rde(int, short, void *); -int check_file_secrecy(int, const char *); void ospf_redistribute_default(int); int ospf_reload(void); @@ -489,29 +488,6 @@ main_imsg_compose_rde(int type, pid_t pid, void *data, u_int16_t datalen) imsg_compose(ibuf_rde, type, 0, pid, data, datalen); } -int -check_file_secrecy(int fd, const char *fname) -{ - struct stat st; - - if (fstat(fd, &st)) { - warn("cannot stat %s", fname); - return (-1); - } - - if (st.st_uid != 0 && st.st_uid != getuid()) { - warnx("%s: owner not root or current user", fname); - return (-1); - } - - if (st.st_mode & (S_IRWXG | S_IRWXO)) { - warnx("%s: group/world readable/writeable", fname); - return (-1); - } - - return (0); -} - /* this needs to be added here so that ospfctl can be used without libevent */ void imsg_event_add(struct imsgbuf *ibuf) diff --git a/usr.sbin/ospf6d/parse.y b/usr.sbin/ospf6d/parse.y index 1a0b409dff0..eb3cf9830e6 100644 --- a/usr.sbin/ospf6d/parse.y +++ b/usr.sbin/ospf6d/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.5 2007/10/11 21:29:53 claudio Exp $ */ +/* $OpenBSD: parse.y,v 1.6 2007/10/13 16:35:22 deraadt Exp $ */ /* * Copyright (c) 2004, 2005 Esben Norby <norby@openbsd.org> @@ -24,11 +24,14 @@ %{ #include <sys/types.h> #include <sys/socket.h> +#include <sys/stat.h> #include <netinet/in.h> #include <arpa/inet.h> + #include <ctype.h> #include <err.h> #include <errno.h> +#include <unistd.h> #include <ifaddrs.h> #include <limits.h> #include <stdarg.h> @@ -40,28 +43,47 @@ #include "ospfe.h" #include "log.h" +TAILQ_HEAD(files, file) files = TAILQ_HEAD_INITIALIZER(files); +static struct file { + TAILQ_ENTRY(file) entry; + FILE *stream; + char *name; + int lineno; + int errors; +} *file; +struct file *pushfile(const char *, int); +int popfile(void); +int check_file_secrecy(int, const char *); +int yyparse(void); +int yylex(void); +int yyerror(const char *, ...); +int kw_cmp(const void *, const void *); +int lookup(char *); +int lgetc(int); +int lungetc(int); +int findeol(void); + +TAILQ_HEAD(symhead, sym) symhead = TAILQ_HEAD_INITIALIZER(symhead); +struct sym { + TAILQ_ENTRY(sym) entry; + int used; + int persist; + char *nam; + char *val; +}; +int symset(const char *, const char *, int); +char *symget(const char *); + +void clear_config(struct ospfd_conf *xconf); +u_int32_t get_rtr_id(void); +int host(const char *, struct in_addr *, struct in_addr *); + static struct ospfd_conf *conf; -static FILE *fin = NULL; -static int lineno = 1; static int errors = 0; -char *infile; struct area *area = NULL; struct iface *iface = NULL; -int yyerror(const char *, ...); -int yyparse(void); -int kw_cmp(const void *, const void *); -int lookup(char *); -int lgetc(int); -int lungetc(int); -int findeol(void); -int yylex(void); -void clear_config(struct ospfd_conf *xconf); -int check_file_secrecy(int fd, const char *fname); -u_int32_t get_rtr_id(void); -int host(const char *, struct in_addr *, struct in_addr *); - struct config_defaults { u_int16_t dead_interval; u_int16_t transmit_delay; @@ -76,19 +98,8 @@ struct config_defaults areadefs; struct config_defaults ifacedefs; struct config_defaults *defs; -TAILQ_HEAD(symhead, sym) symhead = TAILQ_HEAD_INITIALIZER(symhead); -struct sym { - TAILQ_ENTRY(sym) entries; - int used; - int persist; - char *nam; - char *val; -}; - -int symset(const char *, const char *, int); -char *symget(const char *); -struct area *conf_get_area(struct in_addr); -struct iface *conf_get_if(struct kif *, struct kif_addr *); +struct area *conf_get_area(struct in_addr); +struct iface *conf_get_if(struct kif *, struct kif_addr *); typedef struct { union { @@ -121,7 +132,7 @@ grammar : /* empty */ | grammar conf_main '\n' | grammar varset '\n' | grammar area '\n' - | grammar error '\n' { errors++; } + | grammar error '\n' { file->errors++; } ; string : string STRING { @@ -520,9 +531,9 @@ yyerror(const char *fmt, ...) { va_list ap; - errors = 1; + file->errors++; va_start(ap, fmt); - fprintf(stderr, "%s:%d: ", infile, yylval.lineno); + fprintf(stderr, "%s:%d: ", file->name, yylval.lineno); vfprintf(stderr, fmt, ap); fprintf(stderr, "\n"); va_end(ap); @@ -532,7 +543,6 @@ yyerror(const char *fmt, ...) int kw_cmp(const void *k, const void *e) { - return (strcmp(k, ((const struct keywords *)e)->k_name)); } @@ -584,10 +594,9 @@ char pushback_buffer[MAXPUSHBACK]; int pushback_index = 0; int -lgetc(int inquot) +lgetc(int quotec) { - int c, next; - FILE *f = fin; + int c, next; if (parsebuf) { /* Read character from the parsebuffer instead of input. */ @@ -603,29 +612,39 @@ lgetc(int inquot) if (pushback_index) return (pushback_buffer[--pushback_index]); - if (inquot) { - c = getc(f); + if (quotec) { + if ((c = getc(file->stream)) == EOF) { + yyerror("reached end of file while parsing quoted string"); + if (popfile() == EOF) + return (EOF); + return (quotec); + } return (c); } - while ((c = getc(f)) == '\\') { - next = getc(f); + while ((c = getc(file->stream)) == '\\') { + next = getc(file->stream); if (next != '\n') { c = next; break; } - yylval.lineno = lineno; - lineno++; + yylval.lineno = file->lineno; + file->lineno++; } if (c == '\t' || c == ' ') { /* Compress blanks to a single space. */ do { - c = getc(f); + c = getc(file->stream); } while (c == '\t' || c == ' '); - ungetc(c, f); + ungetc(c, file->stream); c = ' '; } + while (c == EOF) { + if (popfile() == EOF) + return (EOF); + c = getc(file->stream); + } return (c); } @@ -657,7 +676,7 @@ findeol(void) while (1) { c = lgetc(0); if (c == '\n') { - lineno++; + file->lineno++; break; } if (c == EOF) @@ -671,7 +690,7 @@ yylex(void) { char buf[8096]; char *p, *val; - int endc, next, c; + int quotec, next, c; int token; top: @@ -679,7 +698,7 @@ top: while ((c = lgetc(0)) == ' ') ; /* nothing */ - yylval.lineno = lineno; + yylval.lineno = file->lineno; if (c == '#') while ((c = lgetc(0)) != '\n' && c != EOF) ; /* nothing */ @@ -713,21 +732,21 @@ top: switch (c) { case '\'': case '"': - endc = c; + quotec = c; while (1) { - if ((c = lgetc(1)) == EOF) + if ((c = lgetc(quotec)) == EOF) return (0); if (c == '\n') { - lineno++; + file->lineno++; continue; } else if (c == '\\') { - if ((next = lgetc(1)) == EOF) + if ((next = lgetc(quotec)) == EOF) return (0); - if (next == endc) + if (next == quotec) c = next; else lungetc(next); - } else if (c == endc) { + } else if (c == quotec) { *p = '\0'; break; } @@ -801,14 +820,75 @@ nodigits: return (token); } if (c == '\n') { - yylval.lineno = lineno; - lineno++; + yylval.lineno = file->lineno; + file->lineno++; } if (c == EOF) return (0); return (c); } +int +check_file_secrecy(int fd, const char *fname) +{ + struct stat st; + + if (fstat(fd, &st)) { + log_warn("cannot stat %s", fname); + return (-1); + } + if (st.st_uid != 0 && st.st_uid != getuid()) { + log_warnx("%s: owner not root or current user", fname); + return (-1); + } + if (st.st_mode & (S_IRWXG | S_IRWXO)) { + log_warnx("%s: group/world readable/writeable", fname); + return (-1); + } + return (0); +} + +struct file * +pushfile(const char *name, int secret) +{ + struct file *nfile; + + if ((nfile = calloc(1, sizeof(struct file))) == NULL || + (nfile->name = strdup(name)) == NULL) + return (NULL); + if ((nfile->stream = fopen(nfile->name, "r")) == NULL) { + free(nfile->name); + free(nfile); + return (NULL); + } else if (secret && + check_file_secrecy(fileno(nfile->stream), nfile->name)) { + fclose(nfile->stream); + free(nfile->name); + free(nfile); + return (NULL); + } + nfile->lineno = 1; + TAILQ_INSERT_TAIL(&files, nfile, entry); + return (nfile); +} + +int +popfile(void) +{ + struct file *prev; + + if ((prev = TAILQ_PREV(file, files, entry)) != NULL) { + prev->errors += file->errors; + TAILQ_REMOVE(&files, file, entry); + fclose(file->stream); + free(file->name); + free(file); + file = prev; + return (0); + } + return (EOF); +} + struct ospfd_conf * parse_config(char *filename, int opts) { @@ -816,6 +896,9 @@ parse_config(char *filename, int opts) if ((conf = calloc(1, sizeof(struct ospfd_conf))) == NULL) fatal("parse_config"); + conf->opts = opts; + if (conf->opts & OSPFD_OPT_STUB_ROUTER) + conf->flags |= OSPFD_FLAG_STUB_ROUTER; bzero(&globaldefs, sizeof(globaldefs)); defs = &globaldefs; @@ -830,41 +913,30 @@ parse_config(char *filename, int opts) conf->spf_hold_time = DEFAULT_SPF_HOLDTIME; conf->spf_state = SPF_IDLE; - if ((fin = fopen(filename, "r")) == NULL) { + if ((file = pushfile(filename, !(conf->opts & OSPFD_OPT_NOACTION))) == NULL) { warn("%s", filename); free(conf); return (NULL); } - infile = filename; - conf->opts = opts; - if (conf->opts & OSPFD_OPT_STUB_ROUTER) - conf->flags |= OSPFD_FLAG_STUB_ROUTER; LIST_INIT(&conf->area_list); LIST_INIT(&conf->cand_list); SIMPLEQ_INIT(&conf->redist_list); - if (!(conf->opts & OSPFD_OPT_NOACTION)) - if (check_file_secrecy(fileno(fin), filename)) { - fclose(fin); - free(conf); - return (NULL); - } - yyparse(); - - fclose(fin); + errors = file->errors; + popfile(); /* Free macros and check which have not been used. */ for (sym = TAILQ_FIRST(&symhead); sym != NULL; sym = next) { - next = TAILQ_NEXT(sym, entries); + next = TAILQ_NEXT(sym, entry); if ((conf->opts & OSPFD_OPT_VERBOSE2) && !sym->used) fprintf(stderr, "warning: macro '%s' not " "used\n", sym->nam); if (!sym->persist) { free(sym->nam); free(sym->val); - TAILQ_REMOVE(&symhead, sym, entries); + TAILQ_REMOVE(&symhead, sym, entry); free(sym); } } @@ -887,7 +959,7 @@ symset(const char *nam, const char *val, int persist) struct sym *sym; for (sym = TAILQ_FIRST(&symhead); sym && strcmp(nam, sym->nam); - sym = TAILQ_NEXT(sym, entries)) + sym = TAILQ_NEXT(sym, entry)) ; /* nothing */ if (sym != NULL) { @@ -896,7 +968,7 @@ symset(const char *nam, const char *val, int persist) else { free(sym->nam); free(sym->val); - TAILQ_REMOVE(&symhead, sym, entries); + TAILQ_REMOVE(&symhead, sym, entry); free(sym); } } @@ -916,7 +988,7 @@ symset(const char *nam, const char *val, int persist) } sym->used = 0; sym->persist = persist; - TAILQ_INSERT_TAIL(&symhead, sym, entries); + TAILQ_INSERT_TAIL(&symhead, sym, entry); return (0); } @@ -947,7 +1019,7 @@ symget(const char *nam) { struct sym *sym; - TAILQ_FOREACH(sym, &symhead, entries) + TAILQ_FOREACH(sym, &symhead, entry) if (strcmp(nam, sym->nam) == 0) { sym->used = 1; return (sym->val); |