diff options
-rw-r--r-- | sbin/dhclient/dhclient.c | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/sbin/dhclient/dhclient.c b/sbin/dhclient/dhclient.c index bcf09a7..5a62c3d 100644 --- a/sbin/dhclient/dhclient.c +++ b/sbin/dhclient/dhclient.c @@ -73,6 +73,7 @@ __FBSDID("$FreeBSD$"); #define alphachar(c) (((c) >= 0x41 && (c) <= 0x5a) || \ ((c) >= 0x61 && (c) <= 0x7a)) #define digitchar(c) ((c) >= 0x30 && (c) <= 0x39) +#define whitechar(c) ((c) == ' ' || (c) == '\t') #define borderchar(c) (alphachar(c) || digitchar(c)) #define middlechar(c) (borderchar(c) || hyphenchar(c)) @@ -116,6 +117,7 @@ void usage(void); int check_option(struct client_lease *l, int option); int ipv4addrs(char * buf); int res_hnok(const char *dn); +int check_search(const char *srch); char *option_as_string(unsigned int code, unsigned char *data, int len); int fork_privchld(int, int); @@ -2250,6 +2252,14 @@ check_option(struct client_lease *l, int option) } return (1); case DHO_DOMAIN_NAME: + if (!res_hnok(sbuf)) { + if (!check_search(sbuf)) { + warning("Bogus domain search list %d: %s (%s)", + option, sbuf, opbuf); + return (0); + } + } + return (1); case DHO_PAD: case DHO_TIME_OFFSET: case DHO_BOOT_SIZE: @@ -2325,6 +2335,52 @@ res_hnok(const char *dn) return (1); } +int +check_search(const char *srch) +{ + int pch = PERIOD, ch = *srch++; + int domains = 1; + + /* 256 char limit re resolv.conf(5) */ + if (strlen(srch) > 256) + return (0); + + while (whitechar(ch)) + ch = *srch++; + + while (ch != '\0') { + int nch = *srch++; + + if (periodchar(ch) || whitechar(ch)) { + ; + } else if (periodchar(pch)) { + if (!borderchar(ch)) + return (0); + } else if (periodchar(nch) || nch == '\0') { + if (!borderchar(ch)) + return (0); + } else { + if (!middlechar(ch)) + return (0); + } + if (!whitechar(ch)) { + pch = ch; + } else { + while (whitechar(nch)) { + nch = *srch++; + } + if (nch != '\0') + domains++; + pch = PERIOD; + } + ch = nch; + } + /* 6 domain limit re resolv.conf(5) */ + if (domains > 6) + return (0); + return (1); +} + /* Does buf consist only of dotted decimal ipv4 addrs? * return how many if so, * otherwise, return 0 |