diff options
Diffstat (limited to 'lib/dns/rdata/in_1/naptr_35.c')
-rw-r--r-- | lib/dns/rdata/in_1/naptr_35.c | 136 |
1 files changed, 134 insertions, 2 deletions
diff --git a/lib/dns/rdata/in_1/naptr_35.c b/lib/dns/rdata/in_1/naptr_35.c index 51aadf7..3d09757 100644 --- a/lib/dns/rdata/in_1/naptr_35.c +++ b/lib/dns/rdata/in_1/naptr_35.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007-2009 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: naptr_35.c,v 1.53 2008-02-15 23:46:51 tbox Exp $ */ +/* $Id: naptr_35.c,v 1.56 2009-12-04 21:09:34 marka Exp $ */ /* Reviewed: Thu Mar 16 16:52:50 PST 2000 by bwelling */ @@ -25,12 +25,134 @@ #define RDATA_IN_1_NAPTR_35_C #define RRTYPE_NAPTR_ATTRIBUTES (0) +#ifdef HAVE_REGEX_H +#include <regex.h> +#endif + +/* + * Check the wire format of the Regexp field. + * Don't allow embeded NUL's. + */ +static inline isc_result_t +txt_valid_regex(const unsigned char *txt) { +#ifdef HAVE_REGEX_H + regex_t preg; + unsigned int regflags = REG_EXTENDED; + unsigned int nsub = 0; + char regex[256]; + char *cp; +#endif + isc_boolean_t flags = ISC_FALSE; + isc_boolean_t replace = ISC_FALSE; + unsigned char c; + unsigned char delim; + unsigned int len; + + len = *txt++; + if (len == 0U) + return (ISC_R_SUCCESS); + + delim = *txt++; + len--; + + /* + * Digits, backslash and flags can't be delimiters. + */ + switch (delim) { + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + case '\\': case 'i': case 0: + return (DNS_R_SYNTAX); + } + +#ifdef HAVE_REGEX_H + memset(&preg, 0, sizeof(preg)); + cp = regex; +#endif + + while (len-- > 0) { + c = *txt++; + if (c == 0) + return (DNS_R_SYNTAX); + if (c == delim && !replace) { + replace = ISC_TRUE; + continue; + } else if (c == delim && !flags) { + flags = ISC_TRUE; + continue; + } else if (c == delim) + return (DNS_R_SYNTAX); + /* + * Flags are not escaped. + */ + if (flags) { + switch (c) { + case 'i': +#ifdef HAVE_REGEX_H + regflags |= REG_ICASE; +#endif + continue; + default: + return (DNS_R_SYNTAX); + } + } +#ifdef HAVE_REGEX_H + if (!replace) + *cp++ = c; +#endif + if (c == '\\') { + if (len == 0) + return (DNS_R_SYNTAX); + c = *txt++; + if (c == 0) + return (DNS_R_SYNTAX); + len--; + if (replace) + switch (c) { + case '0': return (DNS_R_SYNTAX); +#ifdef HAVE_REGEX_H + case '1': if (nsub < 1) nsub = 1; break; + case '2': if (nsub < 2) nsub = 2; break; + case '3': if (nsub < 3) nsub = 3; break; + case '4': if (nsub < 4) nsub = 4; break; + case '5': if (nsub < 5) nsub = 5; break; + case '6': if (nsub < 6) nsub = 6; break; + case '7': if (nsub < 7) nsub = 7; break; + case '8': if (nsub < 8) nsub = 8; break; + case '9': if (nsub < 9) nsub = 9; break; +#endif + } +#ifdef HAVE_REGEX_H + if (!replace) + *cp++ = c; +#endif + } + } + if (!flags) + return (DNS_R_SYNTAX); +#ifdef HAVE_REGEX_H + *cp = '\0'; + if (regcomp(&preg, regex, regflags)) + return (DNS_R_SYNTAX); + /* + * Check that substitutions in the replacement string are consistant + * with the regular expression. + */ + if (preg.re_nsub < nsub) { + regfree(&preg); + return (DNS_R_SYNTAX); + } + regfree(&preg); +#endif + return (ISC_R_SUCCESS); +} static inline isc_result_t fromtext_in_naptr(ARGS_FROMTEXT) { isc_token_t token; dns_name_t name; isc_buffer_t buffer; + unsigned char *regex; REQUIRE(type == 35); REQUIRE(rdclass == 1); @@ -74,9 +196,11 @@ fromtext_in_naptr(ARGS_FROMTEXT) { /* * Regexp. */ + regex = isc_buffer_used(target); RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_qstring, ISC_FALSE)); RETTOK(txt_fromtext(&token.value.as_textregion, target)); + RETTOK(txt_valid_regex(regex)); /* * Replacement. @@ -156,6 +280,7 @@ static inline isc_result_t fromwire_in_naptr(ARGS_FROMWIRE) { dns_name_t name; isc_region_t sr; + unsigned char *regex; REQUIRE(type == 35); REQUIRE(rdclass == 1); @@ -189,7 +314,9 @@ fromwire_in_naptr(ARGS_FROMWIRE) { /* * Regexp. */ + regex = isc_buffer_used(target); RETERR(txt_fromwire(source, target)); + RETERR(txt_valid_regex(regex)); /* * Replacement. @@ -575,4 +702,9 @@ checknames_in_naptr(ARGS_CHECKNAMES) { return (ISC_TRUE); } +static inline int +casecompare_in_naptr(ARGS_COMPARE) { + return (compare_in_naptr(rdata1, rdata2)); +} + #endif /* RDATA_IN_1_NAPTR_35_C */ |