[asterisk-commits] mmichelson: branch group/dns_naptr r433336 - in /team/group/dns_naptr: main/ ...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Mar 24 14:19:25 CDT 2015


Author: mmichelson
Date: Tue Mar 24 14:19:23 2015
New Revision: 433336

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=433336
Log:
Add off-nominal NAPTR flags test.

This test ensures that NAPTR records with invalid flags are
not added to the result set.


Modified:
    team/group/dns_naptr/main/dns_naptr.c
    team/group/dns_naptr/tests/test_dns_naptr.c

Modified: team/group/dns_naptr/main/dns_naptr.c
URL: http://svnview.digium.com/svn/asterisk/team/group/dns_naptr/main/dns_naptr.c?view=diff&rev=433336&r1=433335&r2=433336
==============================================================================
--- team/group/dns_naptr/main/dns_naptr.c (original)
+++ team/group/dns_naptr/main/dns_naptr.c Tue Mar 24 14:19:23 2015
@@ -39,6 +39,80 @@
 #include "asterisk/linkedlists.h"
 #include "asterisk/dns_internal.h"
 #include "asterisk/utils.h"
+
+/*!
+ * \brief Result of analyzing NAPTR flags on a record
+ */
+enum flags_result {
+	/*! Terminal record, meaning the DDDS algorithm can be stopped */
+	FLAGS_TERMINAL,
+	/*! No flags provided, likely meaning another NAPTR lookup */
+	FLAGS_EMPTY,
+	/*! Unrecognized but valid flags. We cannot conclude what they mean */
+	FLAGS_UNKNOWN,
+	/*! Non-alphanumeric or invalid combination of flags */
+	FLAGS_INVALID,
+};
+
+/*!
+ * \brief Analyze and interpret NAPTR flags as per RFC 3404
+ *
+ * \note The flags string passed into this function is NOT NULL-terminated
+ *
+ * \param flags The flags string from a NAPTR record
+ * \flags_size The size of the flags string in bytes
+ * \return flag result
+ */
+static enum flags_result interpret_flags(const char *flags, uint8_t flags_size)
+{
+	int i;
+	char known_flag_found = 0;
+
+	if (flags_size == 0) {
+		return FLAGS_EMPTY;
+	}
+
+	/* Take care of the most common (and easy) case, one character */
+	if (flags_size == 1) {
+		if (*flags == 's' || *flags == 'S' ||
+				*flags == 'a' || *flags == 'A' ||
+				*flags == 'u' || *flags == 'U') {
+			return FLAGS_TERMINAL;
+		} else if (!isalnum(*flags)) {
+			return FLAGS_INVALID;
+		} else {
+			return FLAGS_UNKNOWN;
+		}
+	}
+
+	for (i = 0; i < flags_size; ++i) {
+		if (!isalnum(flags[i])) {
+			return FLAGS_INVALID;
+		} else if (flags[i] == 's' || flags[i] == 'S') {
+			if (known_flag_found && known_flag_found != 's') {
+				return FLAGS_INVALID;
+			}
+			known_flag_found = 's';
+		} else if (flags[i] == 'u' || flags[i] == 'U') {
+			if (known_flag_found && known_flag_found != 'u') {
+				return FLAGS_INVALID;
+			}
+			known_flag_found = 'u';
+		} else if (flags[i] == 'a' || flags[i] == 'A') {
+			if (known_flag_found && known_flag_found != 'a') {
+				return FLAGS_INVALID;
+			}
+			known_flag_found = 'a';
+		} else if (flags[i] == 'p' || flags[i] == 'P') {
+			if (known_flag_found && known_flag_found != 'p') {
+				return FLAGS_INVALID;
+			}
+			known_flag_found = 'p';
+		}
+	}
+
+	return (!known_flag_found || known_flag_found == 'p') ? FLAGS_UNKNOWN : FLAGS_TERMINAL;
+}
 
 struct ast_dns_record *ast_dns_naptr_alloc(struct ast_dns_query *query, const char *data, const size_t size)
 {
@@ -58,6 +132,7 @@
 	char *naptr_search_base = (char *)query->result->answer;
 	size_t remaining_size = query->result->answer_size;
 	char *end_of_record;
+	enum flags_result flags_res;
 
 	/* 
 	 * This is bordering on the hackiest thing I've ever written.
@@ -162,6 +237,15 @@
 		return NULL;
 	}
 
+	/* We've validated the size of the NAPTR record. Now we can validate
+	 * the individual parts
+	 */
+	flags_res = interpret_flags(flags, flags_size);
+	if (flags_res == FLAGS_INVALID) {
+		ast_log(LOG_ERROR, "NAPTR Record contained invalid flags %.*s\n", flags_size, flags);
+		return NULL;
+	}
+
 	naptr = ast_calloc(1, sizeof(*naptr) + size + flags_size + 1 + services_size + 1 + regexp_size + 1 + replacement_size + 1);
 	if (!naptr) {
 		return NULL;

Modified: team/group/dns_naptr/tests/test_dns_naptr.c
URL: http://svnview.digium.com/svn/asterisk/team/group/dns_naptr/tests/test_dns_naptr.c?view=diff&rev=433336&r1=433335&r2=433336
==============================================================================
--- team/group/dns_naptr/tests/test_dns_naptr.c (original)
+++ team/group/dns_naptr/tests/test_dns_naptr.c Tue Mar 24 14:19:23 2015
@@ -397,10 +397,87 @@
 
 	return res;
 }
+
+AST_TEST_DEFINE(naptr_resolve_off_nominal_flags)
+{
+	RAII_VAR(struct ast_dns_result *, result, NULL, ast_dns_result_free);
+	struct naptr_record records[] = {
+		/* Non-alphanumeric flag */
+		{ 100, 100, {1, "\x0a"}, {4, "BLAH"}, {15, "!.*!horse.mane!"}, ""},
+		/* Mix of valid and non-alphanumeric */
+		{ 100, 100, {2, "A\x0a"}, {4, "BLAH"}, {15, "!.*!horse.mane!"}, ""},
+		/* Invalid combinations of flags */
+		{ 100, 100, {2, "sa"}, {4, "BLAH"}, {15, "!.*!horse.mane!"}, ""},
+		{ 100, 100, {2, "su"}, {4, "BLAH"}, {15, "!.*!horse.mane!"}, ""},
+		{ 100, 100, {2, "sp"}, {4, "BLAH"}, {15, "!.*!horse.mane!"}, ""},
+		{ 100, 100, {2, "as"}, {4, "BLAH"}, {15, "!.*!horse.mane!"}, ""},
+		{ 100, 100, {2, "au"}, {4, "BLAH"}, {15, "!.*!horse.mane!"}, ""},
+		{ 100, 100, {2, "ap"}, {4, "BLAH"}, {15, "!.*!horse.mane!"}, ""},
+		{ 100, 100, {2, "ua"}, {4, "BLAH"}, {15, "!.*!horse.mane!"}, ""},
+		{ 100, 100, {2, "us"}, {4, "BLAH"}, {15, "!.*!horse.mane!"}, ""},
+		{ 100, 100, {2, "up"}, {4, "BLAH"}, {15, "!.*!horse.mane!"}, ""},
+		{ 100, 100, {2, "pa"}, {4, "BLAH"}, {15, "!.*!horse.mane!"}, ""},
+		{ 100, 100, {2, "ps"}, {4, "BLAH"}, {15, "!.*!horse.mane!"}, ""},
+		{ 100, 100, {2, "pu"}, {4, "BLAH"}, {15, "!.*!horse.mane!"}, ""},
+	};
+	enum ast_test_result_state res = AST_TEST_PASS;
+	const struct ast_dns_record *record;
+
+	switch (cmd) {
+	case TEST_INIT:
+		info->name = "naptr_resolve_off_nominal_flags";
+		info->category = "/main/dns/naptr/";
+		info->summary = "Ensure that NAPTR records with invalid flags are not presented in results";
+		info->description = "This test defines a set of records where the flags provided are\n"
+			"invalid in some way. This may be due to providing non-alphanumeric characters or\n"
+			"by providing clashing flags. The result should be that none of the defined records\n"
+			"are returned by the resolver\n";
+		return AST_TEST_NOT_RUN;
+	case TEST_EXECUTE:
+		break;
+	}
+
+	test_records = records;
+	num_test_records = ARRAY_LEN(records);
+	memset(ans_buffer, 0, sizeof(ans_buffer));
+
+	ast_dns_resolver_register(&naptr_resolver);
+
+	if (ast_dns_resolve("goose.feathers", ns_t_naptr, ns_c_in, &result)) {
+		ast_test_status_update(test, "Failed to perform DNS resolution, despite using valid inputs\n");
+		res = AST_TEST_FAIL;
+		goto cleanup;
+	}
+
+	if (!result) {
+		ast_test_status_update(test, "Synchronous DNS resolution failed to set a result\n");
+		res = AST_TEST_FAIL;
+		goto cleanup;
+	}
+
+	record = ast_dns_result_get_records(result);
+	if (record) {
+		ast_test_status_update(test, "DNS resolution returned records when it was not expected to\n");
+		res = AST_TEST_FAIL;
+		goto cleanup;
+	}
+
+cleanup:
+
+	ast_dns_resolver_unregister(&naptr_resolver);
+
+	test_records = NULL;
+	num_test_records = 0;
+	memset(ans_buffer, 0, sizeof(ans_buffer));
+
+	return res;
+}
+
 static int unload_module(void)
 {
 	AST_TEST_UNREGISTER(naptr_resolve_nominal);
 	AST_TEST_UNREGISTER(naptr_resolve_off_nominal_length);
+	AST_TEST_UNREGISTER(naptr_resolve_off_nominal_flags);
 
 	return 0;
 }
@@ -409,6 +486,7 @@
 {
 	AST_TEST_REGISTER(naptr_resolve_nominal);
 	AST_TEST_REGISTER(naptr_resolve_off_nominal_length);
+	AST_TEST_REGISTER(naptr_resolve_off_nominal_flags);
 
 	return AST_MODULE_LOAD_SUCCESS;
 }




More information about the asterisk-commits mailing list