summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/nsd/compat/b64_pton.c220
-rw-r--r--usr.sbin/nsd/compat/inet_aton.c10
-rw-r--r--usr.sbin/nsd/compat/strptime.c10
-rw-r--r--usr.sbin/nsd/dns.c4
-rw-r--r--usr.sbin/nsd/nsd.c4
-rw-r--r--usr.sbin/nsd/rdata.c12
-rw-r--r--usr.sbin/nsd/remote.c4
-rw-r--r--usr.sbin/nsd/tsig.c106
-rw-r--r--usr.sbin/nsd/util.c8
-rw-r--r--usr.sbin/nsd/zlexer.lex64
-rw-r--r--usr.sbin/nsd/zonec.c44
11 files changed, 331 insertions, 155 deletions
diff --git a/usr.sbin/nsd/compat/b64_pton.c b/usr.sbin/nsd/compat/b64_pton.c
index b69bb21bfe3..0e4aafceb35 100644
--- a/usr.sbin/nsd/compat/b64_pton.c
+++ b/usr.sbin/nsd/compat/b64_pton.c
@@ -107,9 +107,9 @@ static const char Pad64 = '=';
end of the data is performed using the '=' character.
Since all base64 input is an integral number of octets, only the
- -------------------------------------------------
+ -------------------------------------------------
following cases can arise:
-
+
(1) the final quantum of encoding input is an integral
multiple of 24 bits; here, the final unit of encoded
output will be an integral multiple of 4 characters
@@ -128,65 +128,99 @@ static const char Pad64 = '=';
it returns the number of data bytes stored at the target, or -1 on error.
*/
-int
-b64_pton(char const *src, uint8_t *target, size_t targsize)
+static int b64rmap_initialized = 0;
+static uint8_t b64rmap[256];
+
+static const uint8_t b64rmap_special = 0xf0;
+static const uint8_t b64rmap_end = 0xfd;
+static const uint8_t b64rmap_space = 0xfe;
+static const uint8_t b64rmap_invalid = 0xff;
+
+/**
+ * Initializing the reverse map is not thread safe.
+ * Which is fine for NSD. For now...
+ **/
+static void
+b64_initialize_rmap ()
+{
+ int i;
+
+ /* Null: end of string, stop parsing */
+ b64rmap[0] = b64rmap_end;
+
+ for (i = 1; i < 256; ++i) {
+ /* Whitespaces */
+ if (isspace(i))
+ b64rmap[i] = b64rmap_space;
+ /* Padding: stop parsing */
+ else if (i == Pad64)
+ b64rmap[i] = b64rmap_end;
+ /* Non-base64 char */
+ else
+ b64rmap[i] = b64rmap_invalid;
+ }
+
+ /* Fill reverse mapping for base64 chars */
+ for (i = 0; Base64[i] != '\0'; ++i)
+ b64rmap[(uint8_t)Base64[i]] = i;
+
+ b64rmap_initialized = 1;
+}
+
+static int
+b64_pton_do(char const *src, uint8_t *target, size_t targsize)
{
int tarindex, state, ch;
- char *pos;
+ uint8_t ofs;
state = 0;
tarindex = 0;
- while ((ch = *src++) != '\0') {
- if (isspace((unsigned char)ch)) /* Skip whitespace anywhere. */
- continue;
+ while (1)
+ {
+ ch = *src++;
+ ofs = b64rmap[ch];
- if (ch == Pad64)
- break;
-
- pos = strchr(Base64, ch);
- if (pos == 0) {
+ if (ofs >= b64rmap_special) {
+ /* Ignore whitespaces */
+ if (ofs == b64rmap_space)
+ continue;
+ /* End of base64 characters */
+ if (ofs == b64rmap_end)
+ break;
/* A non-base64 character. */
return (-1);
}
switch (state) {
case 0:
- if (target) {
- if ((size_t)tarindex >= targsize)
- return (-1);
- target[tarindex] = (pos - Base64) << 2;
- }
+ if ((size_t)tarindex >= targsize)
+ return (-1);
+ target[tarindex] = ofs << 2;
state = 1;
break;
case 1:
- if (target) {
- if ((size_t)tarindex + 1 >= targsize)
- return (-1);
- target[tarindex] |= (pos - Base64) >> 4;
- target[tarindex+1] = ((pos - Base64) & 0x0f)
- << 4 ;
- }
+ if ((size_t)tarindex + 1 >= targsize)
+ return (-1);
+ target[tarindex] |= ofs >> 4;
+ target[tarindex+1] = (ofs & 0x0f)
+ << 4 ;
tarindex++;
state = 2;
break;
case 2:
- if (target) {
- if ((size_t)tarindex + 1 >= targsize)
- return (-1);
- target[tarindex] |= (pos - Base64) >> 2;
- target[tarindex+1] = ((pos - Base64) & 0x03)
- << 6;
- }
+ if ((size_t)tarindex + 1 >= targsize)
+ return (-1);
+ target[tarindex] |= ofs >> 2;
+ target[tarindex+1] = (ofs & 0x03)
+ << 6;
tarindex++;
state = 3;
break;
case 3:
- if (target) {
- if ((size_t)tarindex >= targsize)
- return (-1);
- target[tarindex] |= (pos - Base64);
- }
+ if ((size_t)tarindex >= targsize)
+ return (-1);
+ target[tarindex] |= ofs;
tarindex++;
state = 0;
break;
@@ -210,7 +244,7 @@ b64_pton(char const *src, uint8_t *target, size_t targsize)
case 2: /* Valid, means one byte of info */
/* Skip any number of spaces. */
for ((void)NULL; ch != '\0'; ch = *src++)
- if (!isspace((unsigned char)ch))
+ if (b64rmap[ch] != b64rmap_space)
break;
/* Make sure there is another trailing = sign. */
if (ch != Pad64)
@@ -225,7 +259,7 @@ b64_pton(char const *src, uint8_t *target, size_t targsize)
* whitespace after it?
*/
for ((void)NULL; ch != '\0'; ch = *src++)
- if (!isspace((unsigned char)ch))
+ if (b64rmap[ch] != b64rmap_space)
return (-1);
/*
@@ -234,7 +268,7 @@ b64_pton(char const *src, uint8_t *target, size_t targsize)
* zeros. If we don't check them, they become a
* subliminal channel.
*/
- if (target && target[tarindex] != 0)
+ if (target[tarindex] != 0)
return (-1);
}
} else {
@@ -248,3 +282,109 @@ b64_pton(char const *src, uint8_t *target, size_t targsize)
return (tarindex);
}
+
+
+static int
+b64_pton_len(char const *src)
+{
+ int tarindex, state, ch;
+ uint8_t ofs;
+
+ state = 0;
+ tarindex = 0;
+
+ while (1)
+ {
+ ch = *src++;
+ ofs = b64rmap[ch];
+
+ if (ofs >= b64rmap_special) {
+ /* Ignore whitespaces */
+ if (ofs == b64rmap_space)
+ continue;
+ /* End of base64 characters */
+ if (ofs == b64rmap_end)
+ break;
+ /* A non-base64 character. */
+ return (-1);
+ }
+
+ switch (state) {
+ case 0:
+ state = 1;
+ break;
+ case 1:
+ tarindex++;
+ state = 2;
+ break;
+ case 2:
+ tarindex++;
+ state = 3;
+ break;
+ case 3:
+ tarindex++;
+ state = 0;
+ break;
+ default:
+ abort();
+ }
+ }
+
+ /*
+ * We are done decoding Base-64 chars. Let's see if we ended
+ * on a byte boundary, and/or with erroneous trailing characters.
+ */
+
+ if (ch == Pad64) { /* We got a pad char. */
+ ch = *src++; /* Skip it, get next. */
+ switch (state) {
+ case 0: /* Invalid = in first position */
+ case 1: /* Invalid = in second position */
+ return (-1);
+
+ case 2: /* Valid, means one byte of info */
+ /* Skip any number of spaces. */
+ for ((void)NULL; ch != '\0'; ch = *src++)
+ if (b64rmap[ch] != b64rmap_space)
+ break;
+ /* Make sure there is another trailing = sign. */
+ if (ch != Pad64)
+ return (-1);
+ ch = *src++; /* Skip the = */
+ /* Fall through to "single trailing =" case. */
+ /* FALLTHROUGH */
+
+ case 3: /* Valid, means two bytes of info */
+ /*
+ * We know this char is an =. Is there anything but
+ * whitespace after it?
+ */
+ for ((void)NULL; ch != '\0'; ch = *src++)
+ if (b64rmap[ch] != b64rmap_space)
+ return (-1);
+
+ }
+ } else {
+ /*
+ * We ended by seeing the end of the string. Make sure we
+ * have no partial bytes lying around.
+ */
+ if (state != 0)
+ return (-1);
+ }
+
+ return (tarindex);
+}
+
+
+int
+b64_pton(char const *src, uint8_t *target, size_t targsize)
+{
+ if (!b64rmap_initialized)
+ b64_initialize_rmap ();
+
+ if (target)
+ return b64_pton_do (src, target, targsize);
+ else
+ return b64_pton_len (src);
+}
diff --git a/usr.sbin/nsd/compat/inet_aton.c b/usr.sbin/nsd/compat/inet_aton.c
index 7eb8e623d95..430f9b03d4f 100644
--- a/usr.sbin/nsd/compat/inet_aton.c
+++ b/usr.sbin/nsd/compat/inet_aton.c
@@ -99,7 +99,7 @@ inet_aton(const char *cp, struct in_addr *addr)
* Values are specified as for C:
* 0x=hex, 0=octal, isdigit=decimal.
*/
- if (!isdigit((int)c))
+ if (!isdigit((unsigned char)c))
return (0);
val = 0; base = 10;
if (c == '0') {
@@ -110,12 +110,12 @@ inet_aton(const char *cp, struct in_addr *addr)
base = 8;
}
for (;;) {
- if (isascii((int)c) && isdigit((int)c)) {
+ if (isascii((unsigned char)c) && isdigit((unsigned char)c)) {
val = (val * base) + (c - '0');
c = *++cp;
- } else if (base == 16 && isascii((int)c) && isxdigit((int)c)) {
+ } else if (base == 16 && isascii((unsigned char)c) && isxdigit((unsigned char)c)) {
val = (val << 4) |
- (c + 10 - (islower((int)c) ? 'a' : 'A'));
+ (c + 10 - (islower((unsigned char)c) ? 'a' : 'A'));
c = *++cp;
} else
break;
@@ -137,7 +137,7 @@ inet_aton(const char *cp, struct in_addr *addr)
/*
* Check for trailing characters.
*/
- if (c != '\0' && (!isascii((int)c) || !isspace((int)c)))
+ if (c != '\0' && (!isascii((unsigned char)c) || !isspace((unsigned char)c)))
return (0);
/*
* Concoct the address according to
diff --git a/usr.sbin/nsd/compat/strptime.c b/usr.sbin/nsd/compat/strptime.c
index 0c61cc9008a..e6eb375918f 100644
--- a/usr.sbin/nsd/compat/strptime.c
+++ b/usr.sbin/nsd/compat/strptime.c
@@ -10,7 +10,7 @@
* - Does not properly processes year day
*
* LICENSE
- * Copyright (c) 2008, NLnet Labs, Matthijs Mekking
+ * Copyright (c) 2008, NLnet Labs, Matthijs Mekking.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -91,7 +91,7 @@ str2int(const char **buf, int max)
{
int ret=0, count=0;
- while (*buf[0] != '\0' && isdigit(*buf[0]) && count<max) {
+ while (*buf[0] != '\0' && isdigit((unsigned char)*buf[0]) && count<max) {
ret = ret*10 + (*buf[0] - '0');
(*buf)++;
count++;
@@ -111,7 +111,7 @@ nsd_strptime(const char *s, const char *format, struct tm *tm)
int c, alt_format, ret;
int split_year = 0;
- while ((c = *format) != '\0') {
+ while ((c = (unsigned char)*format) != '\0') {
alt_format = 0;
/* whitespace, literal or format */
@@ -119,7 +119,7 @@ nsd_strptime(const char *s, const char *format, struct tm *tm)
/** whitespace matches zero or more whitespace characters in the
* input string.
**/
- while (isspace(*s))
+ while (isspace((unsigned char)*s))
s++;
}
else if (c == '%') { /* format */
@@ -225,7 +225,7 @@ nsd_strptime(const char *s, const char *format, struct tm *tm)
break;
case 'n': /* arbitrary whitespace */
case 't':
- while (isspace(*s))
+ while (isspace((unsigned char)*s))
s++;
break;
case 'p': /* am pm */
diff --git a/usr.sbin/nsd/dns.c b/usr.sbin/nsd/dns.c
index 5d80f8a11ba..b10a53810e5 100644
--- a/usr.sbin/nsd/dns.c
+++ b/usr.sbin/nsd/dns.c
@@ -891,7 +891,7 @@ rrtype_from_string(const char *name)
if (strncasecmp(name, "TYPE", 4) != 0)
return 0;
- if (!isdigit((int)name[4]))
+ if (!isdigit((unsigned char)name[4]))
return 0;
/* The rest from the string must be a number. */
@@ -936,7 +936,7 @@ rrclass_from_string(const char *name)
if (strncasecmp(name, "CLASS", 5) != 0)
return 0;
- if (!isdigit((int)name[5]))
+ if (!isdigit((unsigned char)name[5]))
return 0;
/* The rest from the string must be a number. */
diff --git a/usr.sbin/nsd/nsd.c b/usr.sbin/nsd/nsd.c
index b8cfd3e3d59..dc37b31a3cd 100644
--- a/usr.sbin/nsd/nsd.c
+++ b/usr.sbin/nsd/nsd.c
@@ -829,11 +829,11 @@ main(int argc, char *argv[])
#ifdef HAVE_GETPWNAM
/* Parse the username into uid and gid */
if (*nsd.username) {
- if (isdigit((int)*nsd.username)) {
+ if (isdigit((unsigned char)*nsd.username)) {
char *t;
nsd.uid = strtol(nsd.username, &t, 10);
if (*t != 0) {
- if (*t != '.' || !isdigit((int)*++t)) {
+ if (*t != '.' || !isdigit((unsigned char)*++t)) {
error("-u user or -u uid or -u uid.gid");
}
nsd.gid = strtol(t, &t, 10);
diff --git a/usr.sbin/nsd/rdata.c b/usr.sbin/nsd/rdata.c
index 9d01c6c28dd..ec5d6ff4be0 100644
--- a/usr.sbin/nsd/rdata.c
+++ b/usr.sbin/nsd/rdata.c
@@ -98,9 +98,9 @@ rdata_dns_name_to_string(buffer_type *output, rdata_atom_type rdata,
if (ch=='.' || ch==';' || ch=='(' || ch==')' || ch=='\\') {
buffer_printf(output, "\\%c", (char) ch);
- } else if (!isgraph((int)(unsigned char) ch)) {
+ } else if (!isgraph((unsigned char) ch)) {
buffer_printf(output, "\\%03u", (unsigned int) ch);
- } else if (isprint((int)(unsigned char) ch)) {
+ } else if (isprint((unsigned char) ch)) {
buffer_printf(output, "%c", (char) ch);
} else {
buffer_printf(output, "\\%03u", (unsigned int) ch);
@@ -127,7 +127,7 @@ rdata_text_to_string(buffer_type *output, rdata_atom_type rdata,
buffer_printf(output, "\"");
for (i = 1; i <= length; ++i) {
char ch = (char) data[i];
- if (isprint((int)(unsigned char)ch)) {
+ if (isprint((unsigned char)ch)) {
if (ch == '"' || ch == '\\') {
buffer_printf(output, "\\");
}
@@ -153,7 +153,7 @@ rdata_texts_to_string(buffer_type *output, rdata_atom_type rdata,
buffer_printf(output, "\"");
for (i = 1; i <= data[pos]; ++i) {
char ch = (char) data[pos + i];
- if (isprint((int)(unsigned char)ch)) {
+ if (isprint((unsigned char)ch)) {
if (ch == '"' || ch == '\\') {
buffer_printf(output, "\\");
}
@@ -179,7 +179,7 @@ rdata_long_text_to_string(buffer_type *output, rdata_atom_type rdata,
buffer_printf(output, "\"");
for (i = 0; i < length; ++i) {
char ch = (char) data[i];
- if (isprint((int)(unsigned char)ch)) {
+ if (isprint((unsigned char)ch)) {
if (ch == '"' || ch == '\\') {
buffer_printf(output, "\\");
}
@@ -201,7 +201,7 @@ rdata_tag_to_string(buffer_type *output, rdata_atom_type rdata,
size_t i;
for (i = 1; i <= length; ++i) {
char ch = (char) data[i];
- if (isdigit((int)ch) || islower((int)ch))
+ if (isdigit((unsigned char)ch) || islower((unsigned char)ch))
buffer_printf(output, "%c", ch);
else return 0;
}
diff --git a/usr.sbin/nsd/remote.c b/usr.sbin/nsd/remote.c
index 82b49990216..18ca7a64b88 100644
--- a/usr.sbin/nsd/remote.c
+++ b/usr.sbin/nsd/remote.c
@@ -731,7 +731,7 @@ static char*
skipwhite(char* str)
{
/* EOS \0 is not a space */
- while( isspace(*str) )
+ while( isspace((unsigned char)*str) )
str++;
return str;
}
@@ -1036,7 +1036,7 @@ find_arg2(SSL* ssl, char* arg, char** arg2)
if(as) {
as[0]=0;
*arg2 = as+1;
- while(isspace(*as) && as > arg)
+ while(isspace((unsigned char)*as) && as > arg)
as--;
as[0]=0;
return 1;
diff --git a/usr.sbin/nsd/tsig.c b/usr.sbin/nsd/tsig.c
index 8b4f3249470..316f477894d 100644
--- a/usr.sbin/nsd/tsig.c
+++ b/usr.sbin/nsd/tsig.c
@@ -1,5 +1,5 @@
/*
- * tsig.h -- TSIG definitions (RFC 2845).
+ * tsig.c -- TSIG implementation (RFC 2845).
*
* Copyright (c) 2001-2006, NLnet Labs. All rights reserved.
*
@@ -8,7 +8,7 @@
*/
-#include <config.h>
+#include "config.h"
#include <stdlib.h>
#include <ctype.h>
@@ -17,16 +17,17 @@
#include "dns.h"
#include "packet.h"
#include "query.h"
+#include "rbtree.h"
static region_type *tsig_region;
struct tsig_key_table
{
- struct tsig_key_table *next;
+ rbnode_t node; /* by dname */
tsig_key_type *key;
};
typedef struct tsig_key_table tsig_key_table_type;
-static tsig_key_table_type *tsig_key_table;
+static rbtree_t *tsig_key_table;
struct tsig_algorithm_table
{
@@ -37,18 +38,6 @@ typedef struct tsig_algorithm_table tsig_algorithm_table_type;
static tsig_algorithm_table_type *tsig_algorithm_table;
static size_t max_algo_digest_size = 0;
-tsig_lookup_algorithm_table tsig_supported_algorithms[] = {
- { TSIG_HMAC_MD5, "hmac-md5" },
-#ifdef HAVE_EVP_SHA1
- { TSIG_HMAC_SHA1, "hmac-sha1" },
-#endif /* HAVE_EVP_SHA1 */
-
-#ifdef HAVE_EVP_SHA256
- { TSIG_HMAC_SHA256, "hmac-sha256" },
-#endif /* HAVE_EVP_SHA256 */
- { 0, NULL }
-};
-
static void
tsig_digest_variables(tsig_record_type *tsig, int tsig_timers_only)
{
@@ -96,27 +85,53 @@ tsig_digest_variables(tsig_record_type *tsig, int tsig_timers_only)
}
}
+static int
+tree_dname_compare(const void* a, const void* b)
+{
+ return dname_compare((const dname_type*)a, (const dname_type*)b);
+}
+
int
tsig_init(region_type *region)
{
tsig_region = region;
- tsig_key_table = NULL;
+ tsig_key_table = rbtree_create(region, &tree_dname_compare);
tsig_algorithm_table = NULL;
-#if defined(TSIG) && defined(HAVE_SSL)
+#if defined(HAVE_SSL)
return tsig_openssl_init(region);
-#endif
+#endif /* defined(HAVE_SSL) */
return 1;
}
void
tsig_add_key(tsig_key_type *key)
{
- tsig_key_table_type *entry = (tsig_key_table_type *) region_alloc(
+ tsig_key_table_type *entry = (tsig_key_table_type *) region_alloc_zero(
tsig_region, sizeof(tsig_key_table_type));
entry->key = key;
- entry->next = tsig_key_table;
- tsig_key_table = entry;
+ entry->node.key = entry->key->name;
+ (void)rbtree_insert(tsig_key_table, &entry->node);
+}
+
+void
+tsig_del_key(tsig_key_type *key)
+{
+ tsig_key_table_type *entry;
+ if(!key) return;
+ entry = (tsig_key_table_type*)rbtree_delete(tsig_key_table, key->name);
+ if(!entry) return;
+ region_recycle(tsig_region, entry, sizeof(tsig_key_table_type));
+}
+
+tsig_key_type*
+tsig_find_key(const dname_type* name)
+{
+ tsig_key_table_type* entry;
+ entry = (tsig_key_table_type*)rbtree_search(tsig_key_table, name);
+ if(entry)
+ return entry->key;
+ return NULL;
}
void
@@ -139,8 +154,8 @@ int
tsig_strlowercmp(const char* str1, const char* str2)
{
while (str1 && str2 && *str1 != '\0' && *str2 != '\0') {
- if(tolower((int)*str1) != tolower((int)*str2)) {
- if(tolower((int)*str1) < tolower((int)*str2))
+ if(tolower((unsigned char)*str1) != tolower((unsigned char)*str2)) {
+ if(tolower((unsigned char)*str1) < tolower((unsigned char)*str2))
return -1;
return 1;
}
@@ -182,19 +197,6 @@ tsig_get_algorithm_by_name(const char *name)
return NULL;
}
-/*
- * Find an HMAC algorithm based on its id.
- */
-tsig_algorithm_type *
-tsig_get_algorithm_by_id(uint8_t alg)
-{
- int i=0;
- for (/*empty*/; tsig_supported_algorithms[i].id > 0; i++) {
- if (tsig_supported_algorithms[i].id == alg)
- return tsig_get_algorithm_by_name(tsig_supported_algorithms[i].short_name);
- }
- return NULL;
-}
const char *
tsig_error(int error_code)
@@ -248,11 +250,21 @@ tsig_create_record_custom(tsig_record_type *tsig, region_type *region,
large_object_size, initial_cleanup_size, 0);
tsig->context_region = region_create_custom(xalloc, free, chunk_size,
large_object_size, initial_cleanup_size, 0);
- region_add_cleanup(region, tsig_cleanup, tsig);
+ if(region)
+ region_add_cleanup(region, tsig_cleanup, tsig);
tsig_init_record(tsig, NULL, NULL);
}
void
+tsig_delete_record(tsig_record_type* tsig, region_type* region)
+{
+ if(region)
+ region_remove_cleanup(region, tsig_cleanup, tsig);
+ region_destroy(tsig->rr_region);
+ region_destroy(tsig->context_region);
+}
+
+void
tsig_init_record(tsig_record_type *tsig,
tsig_algorithm_type *algorithm,
tsig_key_type *key)
@@ -272,7 +284,6 @@ tsig_init_record(tsig_record_type *tsig,
int
tsig_from_query(tsig_record_type *tsig)
{
- tsig_key_table_type *key_entry;
tsig_key_type *key = NULL;
tsig_algorithm_table_type *algorithm_entry;
tsig_algorithm_type *algorithm = NULL;
@@ -283,16 +294,7 @@ tsig_from_query(tsig_record_type *tsig)
assert(!tsig->algorithm);
assert(!tsig->key);
- /* XXX: TODO: slow linear check for keyname */
- for (key_entry = tsig_key_table;
- key_entry;
- key_entry = key_entry->next)
- {
- if (dname_compare(tsig->key_name, key_entry->key->name) == 0) {
- key = key_entry->key;
- break;
- }
- }
+ key = (tsig_key_type*)tsig_find_key(tsig->key_name);
for (algorithm_entry = tsig_algorithm_table;
algorithm_entry;
@@ -594,8 +596,6 @@ tsig_parse_rr(tsig_record_type *tsig, buffer_type *packet)
tsig->rr_region, buffer_current(packet), tsig->other_size);
buffer_skip(packet, tsig->other_size);
tsig->status = TSIG_OK;
- tsig->error_code = TSIG_ERROR_NOERROR;
-
return 1;
}
@@ -668,7 +668,7 @@ tsig_error_reply(tsig_record_type *tsig)
void
tsig_finalize()
{
-#if defined(TSIG) && defined(HAVE_SSL)
+#if defined(HAVE_SSL)
tsig_openssl_finalize();
-#endif
+#endif /* defined(HAVE_SSL) */
}
diff --git a/usr.sbin/nsd/util.c b/usr.sbin/nsd/util.c
index 7d93f54b55b..7af07d0c65e 100644
--- a/usr.sbin/nsd/util.c
+++ b/usr.sbin/nsd/util.c
@@ -553,7 +553,7 @@ hex_pton(const char* src, uint8_t* target, size_t targsize)
return -1;
}
while(*src) {
- if(!isxdigit((int)src[0]) || !isxdigit((int)src[1]))
+ if(!isxdigit((unsigned char)src[0]) || !isxdigit((unsigned char)src[1]))
return -1;
*t++ = hexdigit_to_int(src[0]) * 16 +
hexdigit_to_int(src[1]) ;
@@ -658,7 +658,7 @@ b32_pton(const char *src, uint8_t *target, size_t tsize)
if(p+5 >= tsize*8)
return -1;
- if(isspace(ch))
+ if(isspace((unsigned char)ch))
continue;
if(ch >= '0' && ch <= '9')
@@ -690,13 +690,13 @@ strip_string(char *str)
char *start = str;
char *end = str + strlen(str) - 1;
- while (isspace(*start))
+ while (isspace((unsigned char)*start))
++start;
if (start > end) {
/* Completely blank. */
str[0] = '\0';
} else {
- while (isspace(*end))
+ while (isspace((unsigned char)*end))
--end;
*++end = '\0';
diff --git a/usr.sbin/nsd/zlexer.lex b/usr.sbin/nsd/zlexer.lex
index 0d5ac7e0c9e..90a1df3741c 100644
--- a/usr.sbin/nsd/zlexer.lex
+++ b/usr.sbin/nsd/zlexer.lex
@@ -8,7 +8,7 @@
*
*/
-#include <config.h>
+#include "config.h"
#include <ctype.h>
#include <errno.h>
@@ -19,8 +19,6 @@
#include "dname.h"
#include "zparser.h"
-#define YY_NO_UNPUT
-
#if 0
#define LEXOUT(s) printf s /* used ONLY when debugging */
#else
@@ -68,6 +66,23 @@ pop_parser_state(void)
yy_switch_to_buffer(include_stack[include_stack_ptr]);
}
+static YY_BUFFER_STATE oldstate;
+/* Start string scan */
+void
+parser_push_stringbuf(char* str)
+{
+ oldstate = YY_CURRENT_BUFFER;
+ yy_switch_to_buffer(yy_scan_string(str));
+}
+
+void
+parser_pop_stringbuf(void)
+{
+ yy_delete_buffer(YY_CURRENT_BUFFER);
+ yy_switch_to_buffer(oldstate);
+ oldstate = NULL;
+}
+
#ifndef yy_set_bol /* compat definition, for flex 2.4.6 */
#define yy_set_bol(at_bol) \
{ \
@@ -78,11 +93,23 @@ pop_parser_state(void)
#endif
%}
+%option noinput
+%option nounput
+%{
+#ifndef YY_NO_UNPUT
+#define YY_NO_UNPUT 1
+#endif
+#ifndef YY_NO_INPUT
+#define YY_NO_INPUT 1
+#endif
+%}
SPACE [ \t]
LETTER [a-zA-Z]
NEWLINE [\n\r]
-ZONESTR [^ \t\n\r();.\"\$]
+ZONESTR [^ \t\n\r();.\"\$]|\\.|\\\n
+CHARSTR [^ \t\n\r();.]|\\.|\\\n
+QUOTE \"
DOLLAR \$
COMMENT ;
DOT \.
@@ -144,11 +171,13 @@ ANY [^\"\n\\]|\\.
/* split the original yytext */
*tmp = '\0';
strip_string(yytext);
-
+
dname = dname_parse(parser->region, tmp + 1);
if (!dname) {
zc_error("incorrect include origin '%s'",
tmp + 1);
+ } else if (*(tmp + strlen(tmp + 1)) != '.') {
+ zc_error("$INCLUDE directive requires absolute domain name");
} else {
origin = domain_table_insert(
parser->db->domains, dname);
@@ -242,6 +271,8 @@ ANY [^\"\n\\]|\\.
<bitlabel><<EOF>> {
zc_error("EOF inside bitlabel");
BEGIN(INITIAL);
+ yyrestart(yyin); /* this is so that lex does not give an internal err */
+ yyterminate();
}
<bitlabel>{BIT}* { yymore(); }
<bitlabel>\n { ++parser->line; yymore(); }
@@ -252,21 +283,23 @@ ANY [^\"\n\\]|\\.
}
/* Quoted strings. Strip leading and ending quotes. */
-\" { BEGIN(quotedstring); LEXOUT(("\" ")); }
+{QUOTE} { BEGIN(quotedstring); LEXOUT(("\" ")); }
<quotedstring><<EOF>> {
zc_error("EOF inside quoted string");
BEGIN(INITIAL);
+ yyrestart(yyin); /* this is so that lex does not give an internal err */
+ yyterminate();
}
<quotedstring>{ANY}* { LEXOUT(("STR ")); yymore(); }
<quotedstring>\n { ++parser->line; yymore(); }
-<quotedstring>\" {
+<quotedstring>{QUOTE} {
LEXOUT(("\" "));
BEGIN(INITIAL);
yytext[yyleng - 1] = '\0';
return parse_token(STR, yytext, &lexer_state);
}
-({ZONESTR}|\\.|\\\n)+ {
+{ZONESTR}({CHARSTR})* {
/* Any allowed word. */
return parse_token(STR, yytext, &lexer_state);
}
@@ -313,7 +346,7 @@ zoctet(char *text)
if (s[0] != '\\') {
/* Ordinary character. */
*p = *s;
- } else if (isdigit((int)s[1]) && isdigit((int)s[2]) && isdigit((int)s[3])) {
+ } else if (isdigit((unsigned char)s[1]) && isdigit((unsigned char)s[2]) && isdigit((unsigned char)s[3])) {
/* \DDD escape. */
int val = (hexdigit_to_int(s[1]) * 100 +
hexdigit_to_int(s[2]) * 10 +
@@ -341,8 +374,8 @@ zoctet(char *text)
static int
parse_token(int token, char *yytext, enum lexer_state *lexer_state)
{
- char *str = region_strdup(parser->rr_region, yytext);
- size_t len = zoctet(str);
+ size_t len;
+ char *str;
if (*lexer_state == EXPECT_OWNER) {
*lexer_state = PARSING_OWNER;
@@ -352,7 +385,7 @@ parse_token(int token, char *yytext, enum lexer_state *lexer_state)
uint16_t rrclass;
/* type */
- token = rrtype_to_token(str, &yylval.type);
+ token = rrtype_to_token(yytext, &yylval.type);
if (token != 0) {
*lexer_state = PARSING_RDATA;
LEXOUT(("%d[%s] ", token, yytext));
@@ -360,7 +393,7 @@ parse_token(int token, char *yytext, enum lexer_state *lexer_state)
}
/* class */
- rrclass = rrclass_from_string(str);
+ rrclass = rrclass_from_string(yytext);
if (rrclass != 0) {
yylval.klass = rrclass;
LEXOUT(("CLASS "));
@@ -368,13 +401,16 @@ parse_token(int token, char *yytext, enum lexer_state *lexer_state)
}
/* ttl */
- yylval.ttl = strtottl(str, &t);
+ yylval.ttl = strtottl(yytext, &t);
if (*t == '\0') {
LEXOUT(("TTL "));
return T_TTL;
}
}
+ str = region_strdup(parser->rr_region, yytext);
+ len = zoctet(str);
+
yylval.data.str = str;
yylval.data.len = len;
diff --git a/usr.sbin/nsd/zonec.c b/usr.sbin/nsd/zonec.c
index 34391328ede..3a85ed48a7f 100644
--- a/usr.sbin/nsd/zonec.c
+++ b/usr.sbin/nsd/zonec.c
@@ -103,12 +103,12 @@ zparser_conv_hex(region_type *region, const char *hex, size_t len)
while (*hex) {
*t = 0;
for (i = 16; i >= 1; i -= 15) {
- if (isxdigit((int)*hex)) {
+ if (isxdigit((unsigned char)*hex)) {
*t += hexdigit_to_int(*hex) * i;
} else {
zc_error_prev_line(
"illegal hex character '%c'",
- (int) *hex);
+ (int)(unsigned char) *hex);
return NULL;
}
++hex;
@@ -144,12 +144,12 @@ zparser_conv_hex_length(region_type *region, const char *hex, size_t len)
while (*hex) {
*t = 0;
for (i = 16; i >= 1; i -= 15) {
- if (isxdigit((int)*hex)) {
+ if (isxdigit((unsigned char)*hex)) {
*t += hexdigit_to_int(*hex) * i;
} else {
zc_error_prev_line(
"illegal hex character '%c'",
- (int) *hex);
+ (int)(unsigned char) *hex);
return NULL;
}
++hex;
@@ -415,7 +415,7 @@ zparser_conv_ilnp64(region_type *region, const char *text)
} else {
/* Our grammar is stricter than the one accepted by
* strtol. */
- c = (int) *ch;
+ c = (unsigned char) *ch;
if (!isxdigit(c)) {
zc_error_prev_line("ilnp64: invalid "
"(non-hexadecimal) character %c", c);
@@ -510,7 +510,7 @@ zparser_conv_eui(region_type *region, const char *text, size_t len)
nnum = len/8;
num = 1;
for (ch = text; *ch != '\0'; ch++) {
- int c = (int) *ch;
+ int c = (unsigned char) *ch;
if (*ch == '-') {
num++;
} else if (!isxdigit(c)) {
@@ -590,7 +590,7 @@ zparser_conv_tag(region_type *region, const char *text, size_t len)
return NULL;
}
for (ptr = text; *ptr; ptr++) {
- if (!isdigit(*ptr) && !islower(*ptr)) {
+ if (!isdigit((unsigned char)*ptr) && !islower((unsigned char)*ptr)) {
zc_error_prev_line("invalid tag %s: contains invalid char %c",
text, *ptr);
return NULL;
@@ -786,14 +786,14 @@ precsize_aton (char *cp, char **endptr)
int exponent;
int mantissa;
- while (isdigit((int)*cp))
+ while (isdigit((unsigned char)*cp))
mval = mval * 10 + hexdigit_to_int(*cp++);
if (*cp == '.') { /* centimeters */
cp++;
- if (isdigit((int)*cp)) {
+ if (isdigit((unsigned char)*cp)) {
cmval = hexdigit_to_int(*cp++) * 10;
- if (isdigit((int)*cp)) {
+ if (isdigit((unsigned char)*cp)) {
cmval += hexdigit_to_int(*cp++);
}
}
@@ -858,17 +858,17 @@ zparser_conv_loc(region_type *region, char *str)
if (!parse_int(str, &str, &deg, "degrees", 0, 180))
return NULL;
- if (!isspace((int)*str)) {
+ if (!isspace((unsigned char)*str)) {
zc_error_prev_line("space expected after degrees");
return NULL;
}
++str;
/* Minutes? */
- if (isdigit((int)*str)) {
+ if (isdigit((unsigned char)*str)) {
if (!parse_int(str, &str, &min, "minutes", 0, 60))
return NULL;
- if (!isspace((int)*str)) {
+ if (!isspace((unsigned char)*str)) {
zc_error_prev_line("space expected after minutes");
return NULL;
}
@@ -876,7 +876,7 @@ zparser_conv_loc(region_type *region, char *str)
}
/* Seconds? */
- if (isdigit((int)*str)) {
+ if (isdigit((unsigned char)*str)) {
start = str;
if (!parse_int(str, &str, &i, "seconds", 0, 60)) {
return NULL;
@@ -886,7 +886,7 @@ zparser_conv_loc(region_type *region, char *str)
return NULL;
}
- if (!isspace((int)*str)) {
+ if (!isspace((unsigned char)*str)) {
zc_error_prev_line("space expected after seconds");
return NULL;
}
@@ -929,7 +929,7 @@ zparser_conv_loc(region_type *region, char *str)
if (lat != 0 && lon != 0)
break;
- if (!isspace((int)*str)) {
+ if (!isspace((unsigned char)*str)) {
zc_error_prev_line("space expected after latitude/longitude");
return NULL;
}
@@ -942,7 +942,7 @@ zparser_conv_loc(region_type *region, char *str)
return NULL;
}
- if (!isspace((int)*str)) {
+ if (!isspace((unsigned char)*str)) {
zc_error_prev_line("space expected before altitude");
return NULL;
}
@@ -966,7 +966,7 @@ zparser_conv_loc(region_type *region, char *str)
if (!parse_int(str + 1, &str, &i, "altitude fraction", 0, 99)) {
return NULL;
}
- if (!isspace((int)*str) && *str != '\0' && *str != 'm') {
+ if (!isspace((unsigned char)*str) && *str != '\0' && *str != 'm') {
zc_error_prev_line("altitude fraction must be a number");
return NULL;
}
@@ -975,7 +975,7 @@ zparser_conv_loc(region_type *region, char *str)
zc_error_prev_line("altitude must be expressed in meters");
return NULL;
}
- if (!isspace((int)*str) && *str != '\0')
+ if (!isspace((unsigned char)*str) && *str != '\0')
++str;
if (sscanf(start, "%lf", &d) != 1) {
@@ -984,16 +984,16 @@ zparser_conv_loc(region_type *region, char *str)
alt = (uint32_t) (10000000.0 + d * 100 + 0.5);
- if (!isspace((int)*str) && *str != '\0') {
+ if (!isspace((unsigned char)*str) && *str != '\0') {
zc_error_prev_line("unexpected character after altitude");
return NULL;
}
/* Now parse size, horizontal precision and vertical precision if any */
- for(i = 1; isspace((int)*str) && i <= 3; i++) {
+ for(i = 1; isspace((unsigned char)*str) && i <= 3; i++) {
vszhpvp[i] = precsize_aton(str + 1, &str);
- if (!isspace((int)*str) && *str != '\0') {
+ if (!isspace((unsigned char)*str) && *str != '\0') {
zc_error_prev_line("invalid size or precision");
return NULL;
}