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;
 }


-- 
_____________________________________________________________________
-- Bandwidth and Colocation Provided by http://www.api-digital.com --

svn-commits mailing list
To UNSUBSCRIBE or update options visit:
   http://lists.digium.com/mailman/listinfo/svn-commits

Reply via email to