]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Add support for test dictionaries in unit_test_attribute
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Tue, 5 Nov 2019 01:38:29 +0000 (19:38 -0600)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Tue, 5 Nov 2019 01:39:07 +0000 (19:39 -0600)
38 files changed:
src/bin/unit_test_attribute.c
src/lib/util/all.mk
src/tests/unit/condition/base.txt
src/tests/unit/condition/regex.txt
src/tests/unit/protocols/dhcpv4/base.txt
src/tests/unit/protocols/dhcpv6/addresses.txt
src/tests/unit/protocols/dhcpv6/bools.txt
src/tests/unit/protocols/dhcpv6/dates.txt
src/tests/unit/protocols/dhcpv6/dictionary [new file with mode: 0644]
src/tests/unit/protocols/dhcpv6/dns_wire_format.txt
src/tests/unit/protocols/dhcpv6/fixed_element_arrays.txt
src/tests/unit/protocols/dhcpv6/integers.txt
src/tests/unit/protocols/dhcpv6/microsoft.txt
src/tests/unit/protocols/dhcpv6/rfc3315.txt
src/tests/unit/protocols/dhcpv6/rfc3319.txt
src/tests/unit/protocols/dhcpv6/rfc3646.txt
src/tests/unit/protocols/dhcpv6/rfc6355.txt
src/tests/unit/protocols/dhcpv6/rfc8415.txt
src/tests/unit/protocols/dhcpv6/strings.txt
src/tests/unit/protocols/dhcpv6/tlvs.txt
src/tests/unit/protocols/dhcpv6/variable_element_arrays.txt
src/tests/unit/protocols/eap/aka/decode.txt
src/tests/unit/protocols/eap/aka/encode.txt
src/tests/unit/protocols/eap/aka/error.txt
src/tests/unit/protocols/eap/sim/decode.txt
src/tests/unit/protocols/eap/sim/encode.txt
src/tests/unit/protocols/eap/sim/error.txt
src/tests/unit/protocols/ethernet/base.txt
src/tests/unit/protocols/radius/errors.txt
src/tests/unit/protocols/radius/extended.txt
src/tests/unit/protocols/radius/lucent.txt
src/tests/unit/protocols/radius/rfc.txt
src/tests/unit/protocols/radius/struct.txt
src/tests/unit/protocols/radius/tunnel.txt
src/tests/unit/protocols/radius/unit.txt
src/tests/unit/protocols/radius/vendor.txt
src/tests/unit/protocols/radius/wimax.txt
src/tests/unit/xlat/base.txt

index 88f1407ccafedb88901758ddb04f530ec0033369..35c4485fc79d0c4e1e84a73f67d42f103bdbaffb 100644 (file)
@@ -50,8 +50,9 @@ typedef struct rad_request REQUEST;
 #  include <getopt.h>
 #endif
 
-#include <limits.h>
 #include <assert.h>
+#include <libgen.h>
+#include <limits.h>
 #include <sys/wait.h>
 
 #define EXIT_WITH_FAILURE \
@@ -166,13 +167,13 @@ typedef struct {
 typedef struct {
        TALLOC_CTX      *tmp_ctx;               //!< Talloc context for test points.
 
-       char const      *path;                  //!< Current path we're operating in.
+       char            *path;                  //!< Current path we're operating in.
        int             lineno;                 //!< Current line number.
        char const      *filename;              //!< Current file we're operating on.
        uint32_t        test_count;             //!< How many tests we've executed in this file.
 
        fr_dict_t       *dict;                  //!< Base dictionary.
-       fr_dict_t       *proto_dict;            //!< Protocol specific dictionary.
+       fr_dict_t       *active_dict;           //!< Protocol specific dictionary.
        CONF_SECTION    *features;              //!< Enabled features.
 } command_ctx_t;
 
@@ -204,6 +205,8 @@ static ssize_t xlat_test(UNUSED TALLOC_CTX *ctx, UNUSED char **out, UNUSED size_
 static char            proto_name_prev[128];
 static dl_t            *dl;
 static dl_loader_t     *dl_loader;
+static char const      *raddb_dir = RADDBDIR;
+static char const      *dict_dir = DICTDIR;
 
 size_t process_line(command_result_t *result, command_ctx_t *cc, char *data, size_t data_used, char *in, size_t inlen);
 static int process_file(bool *exit_now, TALLOC_CTX *ctx, CONF_SECTION *features,
@@ -783,6 +786,50 @@ static ssize_t load_test_point_by_command(void **symbol, char *command, char con
        return p - command;
 }
 
+/** Common dictionary load function
+ *
+ * Callers call fr_dict_dir_set to set the dictionary root to
+ * load dictionaries from, then provide a relative path to
+ * navigate through test subdirectories or protocols
+ */
+static int dictionary_load_common(command_result_t *result, command_ctx_t *cc, char *in, char *default_subdir)
+{
+       static  char *name, *dir, *tmp = NULL;
+       char *q;
+       int ret;
+
+       if (in[0] == '\0') {
+               fr_strerror_printf("Missing dictionary name");
+               RETURN_PARSE_ERROR(0);
+       }
+
+       /*
+        *      Decrease ref count if we're loading in a new dictionary
+        */
+       if (cc->active_dict) fr_dict_free(&cc->active_dict);
+
+       q = strchr(in, ' ');
+       if (q) {
+               name = tmp = talloc_bstrndup(NULL, in, q - in);
+               q++;
+               dir = q;
+       } else {
+               name = in;
+               dir = default_subdir;
+       }
+
+       ret = fr_dict_protocol_afrom_file(&cc->active_dict, name, dir);
+       talloc_free(tmp);
+       if (ret < 0) RETURN_COMMAND_ERROR();
+
+       /*
+        *      Dump the dictionary if we're in super debug mode
+        */
+       if (fr_debug_lvl > 5) fr_dict_dump(cc->active_dict);
+
+       RETURN_OK(0);
+}
+
 static fr_cmd_t *command_head = NULL;
 
 static int command_func(UNUSED FILE *fp, UNUSED FILE *fp_err, UNUSED void *ctx, UNUSED fr_cmd_info_t const *info)
@@ -867,7 +914,7 @@ static size_t command_normalise_attribute(command_result_t *result, command_ctx_
        VALUE_PAIR      *head = NULL;
        size_t          len;
 
-       if (fr_pair_list_afrom_str(NULL, cc->proto_dict ? cc->proto_dict : cc->dict, in, &head) != T_EOL) {
+       if (fr_pair_list_afrom_str(NULL, cc->active_dict ? cc->active_dict : cc->dict, in, &head) != T_EOL) {
                RETURN_OK_WITH_ERROR();
        }
 
@@ -882,6 +929,22 @@ static size_t command_normalise_attribute(command_result_t *result, command_ctx_
        RETURN_OK(len);
 }
 
+/** Change the working directory
+ *
+ */
+static size_t command_cd(command_result_t *result, command_ctx_t *cc,
+                        char *data, UNUSED size_t data_used, char *in, size_t inlen)
+{
+       TALLOC_FREE(cc->path);  /* Free old directories */
+
+       cc->path = fr_file_realpath(cc->tmp_ctx, in, inlen);
+       if (!cc->path) RETURN_COMMAND_ERROR();
+
+       strlcpy(data, cc->path, COMMAND_OUTPUT_MAX);
+
+       RETURN_OK(talloc_array_length(cc->path) - 1);
+}
+
 /*
  *     Clear the data buffer
  */
@@ -1020,7 +1083,7 @@ static size_t command_condition_normalise(command_result_t *result, command_ctx_
        cf_filename_set(cs, cc->filename);
        cf_lineno_set(cs, cc->lineno);
 
-       dec_len = fr_cond_tokenize(cs, &cond, &error, cc->proto_dict ? cc->proto_dict : cc->dict, in);
+       dec_len = fr_cond_tokenize(cs, &cond, &error, cc->active_dict ? cc->active_dict : cc->dict, in);
        if (dec_len <= 0) {
                fr_strerror_printf("ERROR offset %d %s", (int) -dec_len, error);
 
@@ -1096,7 +1159,10 @@ static size_t command_decode_pair(command_result_t *result, command_ctx_t *cc,
         *      Decode hex from input text
         */
        slen = hex_to_bin((uint8_t *)data, COMMAND_OUTPUT_MAX, p, inlen);
-       if (slen <= 0) RETURN_PARSE_ERROR(-(slen));
+       if (slen <= 0) {
+               CLEAR_TEST_POINT(cc);
+               RETURN_PARSE_ERROR(-(slen));
+       }
 
        to_dec = (uint8_t *)data;
        to_dec_end = to_dec + slen;
@@ -1107,14 +1173,16 @@ static size_t command_decode_pair(command_result_t *result, command_ctx_t *cc,
         */
        fr_cursor_init(&cursor, &head);
        while (to_dec < to_dec_end) {
-               slen = tp->func(cc->tmp_ctx, &cursor, cc->proto_dict ? cc->proto_dict : cc->dict,
+               slen = tp->func(cc->tmp_ctx, &cursor, cc->active_dict ? cc->active_dict : cc->dict,
                                (uint8_t *)to_dec, (to_dec_end - to_dec), decoder_ctx);
                if (slen < 0) {
                        fr_pair_list_free(&head);
+                       CLEAR_TEST_POINT(cc);
                        RETURN_OK_WITH_ERROR();
                }
                if ((size_t)slen > (size_t)(to_dec_end - to_dec)) {
                        fr_perror("Internal sanity check failed at %d", __LINE__);
+                       CLEAR_TEST_POINT(cc);
                        RETURN_COMMAND_ERROR();
                }
                to_dec += slen;
@@ -1140,6 +1208,7 @@ static size_t command_decode_pair(command_result_t *result, command_ctx_t *cc,
                        if (is_truncated(len, end - p)) {
                        oob:
                                fr_strerror_printf("Out of output buffer space");
+                               CLEAR_TEST_POINT(cc);
                                RETURN_COMMAND_ERROR();
                        }
                        p += len;
@@ -1154,8 +1223,8 @@ static size_t command_decode_pair(command_result_t *result, command_ctx_t *cc,
        } else { /* zero-length to_decibute */
                *p = '\0';
        }
-       CLEAR_TEST_POINT(cc);
 
+       CLEAR_TEST_POINT(cc);
        RETURN_OK(p - data);
 }
 
@@ -1190,7 +1259,7 @@ static size_t command_dictionary_attribute_parse(command_result_t *result, comma
 static size_t command_dictionary_dump(command_result_t *result, command_ctx_t *cc,
                                      UNUSED char *data, size_t data_used, UNUSED char *in, UNUSED size_t inlen)
 {
-       fr_dict_dump(cc->proto_dict ? cc->proto_dict : cc->dict);
+       fr_dict_dump(cc->active_dict ? cc->active_dict : cc->dict);
 
        /*
         *      Don't modify the contents of the data buffer
@@ -1198,49 +1267,6 @@ static size_t command_dictionary_dump(command_result_t *result, command_ctx_t *c
        RETURN_OK(data_used);
 }
 
-
-/** Dynamically load a protocol dictionary
- *
- */
-static size_t command_dictionary_load(command_result_t *result, command_ctx_t *cc,
-                                     UNUSED char *data, UNUSED size_t data_used, char *in, UNUSED size_t inlen)
-{
-       char *name, *dir, *tmp = NULL;
-       char *q;
-       int ret;
-
-       if (in[0] == '\0') {
-               fr_strerror_printf("Load-dictionary syntax is \"dictionary-load <proto_name> [<proto_dir>]\"");
-               RETURN_PARSE_ERROR(0);
-       }
-
-       /*
-        *      Decrease ref count if we're loading in a new dictionary
-        */
-       if (cc->proto_dict) fr_dict_free(&cc->proto_dict);
-
-       q = strchr(in, ' ');
-       if (q) {
-               name = tmp = talloc_bstrndup(NULL, in, q - in);
-               q++;
-               dir = q;
-       } else {
-               name = in;
-               dir = NULL;
-       }
-
-       ret = fr_dict_protocol_afrom_file(&cc->proto_dict, name, dir);
-       talloc_free(tmp);
-       if (ret < 0) RETURN_OK_WITH_ERROR();
-
-       /*
-        *      Dump the dictionary if we're in super debug mode
-        */
-       if (fr_debug_lvl > 5) fr_dict_dump(cc->proto_dict);
-
-       RETURN_OK(0);
-}
-
 static size_t command_encode_dns_label(command_result_t *result, UNUSED command_ctx_t *cc,
                                       char *data, UNUSED size_t data_used, char *in, UNUSED size_t inlen)
 {
@@ -1349,6 +1375,7 @@ static size_t command_encode_pair(command_result_t *result, command_ctx_t *cc,
        slen = load_test_point_by_command((void **)&tp, p, "tp_encode");
        if (!tp) {
                fr_strerror_printf_push("Failed locating encode testpoint");
+               CLEAR_TEST_POINT(cc);
                RETURN_COMMAND_ERROR();
        }
 
@@ -1356,10 +1383,12 @@ static size_t command_encode_pair(command_result_t *result, command_ctx_t *cc,
        fr_skip_whitespace(p);
        if (tp->test_ctx && (tp->test_ctx(&encoder_ctx, cc->tmp_ctx) < 0)) {
                fr_strerror_printf_push("Failed initialising encoder testpoint");
+               CLEAR_TEST_POINT(cc);
                RETURN_COMMAND_ERROR();
        }
 
-       if (fr_pair_list_afrom_str(cc->tmp_ctx, cc->proto_dict ? cc->proto_dict : cc->dict, p, &head) != T_EOL) {
+       if (fr_pair_list_afrom_str(cc->tmp_ctx, cc->active_dict ? cc->active_dict : cc->dict, p, &head) != T_EOL) {
+               CLEAR_TEST_POINT(cc);
                RETURN_OK_WITH_ERROR();
        }
 
@@ -1368,6 +1397,7 @@ static size_t command_encode_pair(command_result_t *result, command_ctx_t *cc,
                slen = tp->func(enc_p, enc_end - enc_p, &cursor, encoder_ctx);
                if (slen < 0) {
                        fr_pair_list_free(&head);
+                       CLEAR_TEST_POINT(cc);
                        RETURN_OK_WITH_ERROR();
                }
                enc_p += slen;
@@ -1381,6 +1411,26 @@ static size_t command_encode_pair(command_result_t *result, command_ctx_t *cc,
        RETURN_OK(hex_print(data, COMMAND_OUTPUT_MAX, encoded, enc_p - encoded));
 }
 
+/** Encode a RADIUS attribute writing the result to the data buffer as space separated hexits
+ *
+ */
+static size_t command_encode_raw(command_result_t *result, UNUSED command_ctx_t *cc,
+                                char *data, UNUSED size_t data_used, char *in, UNUSED size_t inlen)
+{
+       size_t  len;
+       uint8_t encoded[(COMMAND_OUTPUT_MAX / 2) - 1];
+
+       len = encode_rfc(in, encoded, sizeof(encoded));
+       if (len <= 0) RETURN_PARSE_ERROR(0);
+
+       if (len >= sizeof(encoded)) {
+               fr_strerror_printf("Encoder output would overflow output buffer");
+               RETURN_OK_WITH_ERROR();
+       }
+
+       RETURN_OK(hex_print(data, COMMAND_OUTPUT_MAX, encoded, len));
+}
+
 /** Incomplete - Will be used to encode packets
  *
  */
@@ -1418,25 +1468,6 @@ static size_t command_exit(command_result_t *result, UNUSED command_ctx_t *cc,
        RETURN_EXIT(atoi(in));
 }
 
-/** Dynamically load a protocol library
- *
- */
-static size_t command_proto_load(command_result_t *result, UNUSED command_ctx_t *cc,
-                                UNUSED char *data, UNUSED size_t data_used, char *in, UNUSED size_t inlen)
-{
-       ssize_t slen;
-
-       if (*in == '\0') {
-               fr_strerror_printf("Load syntax is \"load <lib_name>\"");
-               RETURN_PARSE_ERROR(0);
-       }
-
-       slen = load_proto_library(in);
-       if (slen <= 0) RETURN_PARSE_ERROR(-(slen));
-
-       RETURN_OK(0);
-}
-
 /** Compare the data buffer to an expected value
  *
  */
@@ -1541,24 +1572,32 @@ static size_t command_no(command_result_t *result, command_ctx_t *cc,
        return data_used;
 }
 
-/** Encode a RADIUS attribute writing the result to the data buffer as space separated hexits
+/** Dynamically load a protocol library
  *
  */
-static size_t command_encode_raw(command_result_t *result, UNUSED command_ctx_t *cc,
-                                char *data, UNUSED size_t data_used, char *in, UNUSED size_t inlen)
+static size_t command_proto(command_result_t *result, UNUSED command_ctx_t *cc,
+                                UNUSED char *data, UNUSED size_t data_used, char *in, UNUSED size_t inlen)
 {
-       size_t  len;
-       uint8_t encoded[(COMMAND_OUTPUT_MAX / 2) - 1];
-
-       len = encode_rfc(in, encoded, sizeof(encoded));
-       if (len <= 0) RETURN_PARSE_ERROR(0);
+       ssize_t slen;
 
-       if (len >= sizeof(encoded)) {
-               fr_strerror_printf("Encoder output would overflow output buffer");
-               RETURN_OK_WITH_ERROR();
+       if (*in == '\0') {
+               fr_strerror_printf("Load syntax is \"load <lib_name>\"");
+               RETURN_PARSE_ERROR(0);
        }
 
-       RETURN_OK(hex_print(data, COMMAND_OUTPUT_MAX, encoded, len));
+       fr_dict_dir_set(dict_dir);
+       slen = load_proto_library(in);
+       if (slen <= 0) RETURN_PARSE_ERROR(-(slen));
+
+       RETURN_OK(0);
+}
+
+static size_t command_proto_dictionary(command_result_t *result, command_ctx_t *cc,
+                                      UNUSED char *data, UNUSED size_t data_used, char *in, UNUSED size_t inlen)
+{
+       fr_dict_dir_set(dict_dir);
+
+       return dictionary_load_common(result, cc, in, NULL);
 }
 
 /** Touch a file to indicate a test completed
@@ -1573,6 +1612,14 @@ static size_t command_touch(command_result_t *result, UNUSED command_ctx_t *cc,
        RETURN_OK(0);
 }
 
+static size_t command_test_dictionary(command_result_t *result, command_ctx_t *cc,
+                                     UNUSED char *data, UNUSED size_t data_used, char *in, UNUSED size_t inlen)
+{
+       fr_dict_dir_set(cc->path);
+
+       return dictionary_load_common(result, cc, in, ".");
+}
+
 static size_t command_value_box_normalise(command_result_t *result, UNUSED command_ctx_t *cc,
                                          char *data, UNUSED size_t data_used, char *in, UNUSED size_t inlen)
 {
@@ -1684,7 +1731,7 @@ static size_t command_xlat_normalise(command_result_t *result, command_ctx_t *cc
        fmt[len] = '\0';
 
        dec_len = xlat_tokenize(fmt, &head, fmt,
-                               &(vp_tmpl_rules_t) { .dict_def = cc->proto_dict ? cc->proto_dict : cc->dict });
+                               &(vp_tmpl_rules_t) { .dict_def = cc->active_dict ? cc->active_dict : cc->dict });
        if (dec_len <= 0) {
                fr_strerror_printf("ERROR offset %d '%s'", (int) -dec_len, fr_strerror());
 
@@ -1721,6 +1768,11 @@ static fr_table_ptr_sorted_t     commands[] = {
                                        .usage = "attribute <attr> = <value>",
                                        .description = "Parse and reprint an attribute value pair, writing \"ok\" to the data buffer on success"
                                }},
+       { "cd ",                &(command_entry_t){
+                                       .func = command_cd,
+                                       .usage = "cd <path>",
+                                       .description = "Change the directory for loading dictionaries and $INCLUDEs, writing the full path into the data buffer on success"
+                               }},
        { "clear",              &(command_entry_t){
                                        .func = command_clear,
                                        .usage = "clear",
@@ -1771,11 +1823,6 @@ static fr_table_ptr_sorted_t     commands[] = {
                                        .usage = "dictionary-dump",
                                        .description = "Print the contents of the currently active protocol dictionary to stdout",
                                }},
-       { "dictionary-load ",   &(command_entry_t){
-                                       .func = command_dictionary_load,
-                                       .usage = "dictionary-load <proto_name> [<proto_dir>]",
-                                       .description = "Switch the active protocol dictionary",
-                               }},
        { "encode-dns-label ",  &(command_entry_t){
                                        .func = command_encode_dns_label,
                                        .usage = "encode-dns-label (-|string[,string])",
@@ -1801,11 +1848,6 @@ static fr_table_ptr_sorted_t     commands[] = {
                                        .usage = "exit[ <num>]",
                                        .description = "Exit with the specified error number.  If no <num> is provided, process will exit with 0"
                                }},
-       { "load ",              &(command_entry_t){
-                                       .func = command_proto_load,
-                                       .usage = "load <protocol>",
-                                       .description = "Switch the active protocol to the one specified, unloading the previous protocol",
-                               }},
        { "match",              &(command_entry_t){
                                        .func = command_match,
                                        .usage = "match <string>",
@@ -1826,11 +1868,26 @@ static fr_table_ptr_sorted_t    commands[] = {
                                        .usage = "no ...",
                                        .description = "Negate the result of a command returning 'ok'"
                                }},
+       { "proto ",             &(command_entry_t){
+                                       .func = command_proto,
+                                       .usage = "proto <protocol>",
+                                       .description = "Switch the active protocol to the one specified, unloading the previous protocol",
+                               }},
+       { "proto-dictionary ",  &(command_entry_t){
+                                       .func = command_proto_dictionary,
+                                       .usage = "proto-dictionary <proto_name> [<proto_dir>]",
+                                       .description = "Switch the active dictionary.  Root is set to the default dictionary path, or the one specified with -d.  <proto_dir> is relative to the root.",
+                               }},
        { "raw ",               &(command_entry_t){
                                        .func = command_encode_raw,
                                        .usage = "raw <string>",
                                        .description = "Create nested attributes from OID strings and values"
                                }},
+       { "test-dictionary ",   &(command_entry_t){
+                                       .func = command_test_dictionary,
+                                       .usage = "test-dictionary <proto_name> [<test_dir>]",
+                                       .description = "Switch the active dictionary.  Root is set to the path containing the current test file (override with cd <path>).  <test_dir> is relative to the root.",
+                               }},
        { "touch ",             &(command_entry_t){
                                        .func = command_touch,
                                        .usage = "touch <file>",
@@ -1917,15 +1974,19 @@ size_t process_line(command_result_t *result, command_ctx_t *cc, char *data, siz
        return data_used;
 }
 
-static void command_ctx_init(command_ctx_t *cc, TALLOC_CTX *ctx, char const *path, char const *filename,
-                            fr_dict_t *dict, CONF_SECTION *features)
+static command_ctx_t *command_ctx_alloc(TALLOC_CTX *ctx, char const *path, char const *filename,
+                                       fr_dict_t *dict, CONF_SECTION *features)
 {
-       memset(cc, 0, sizeof(*cc));
+       command_ctx_t *cc;
+
+       cc = talloc_zero(ctx, command_ctx_t);
        cc->tmp_ctx = talloc_named_const(ctx, 0, "tmp_ctx");
-       cc->path = path;
+       cc->path = talloc_strdup(cc, path);
        cc->dict = dict;
        cc->filename = filename;
        cc->features = features;
+
+       return cc;
 }
 
 static void command_ctx_reset(command_ctx_t *cc, TALLOC_CTX *ctx)
@@ -1945,9 +2006,9 @@ static int process_file(bool *exit_now, TALLOC_CTX *ctx, CONF_SECTION *features,
        ssize_t         data_used = 0;                  /* How much data the last command wrote */
        static char     path[PATH_MAX] = { '\0' };
 
-       command_ctx_t   cc;
+       command_ctx_t   *cc;
 
-       command_ctx_init(&cc, ctx, path, filename, dict, features);
+       cc = command_ctx_alloc(ctx, root_dir, filename, dict, features);
 
        /*
         *      Open the file, or stdin
@@ -1979,11 +2040,11 @@ static int process_file(bool *exit_now, TALLOC_CTX *ctx, CONF_SECTION *features,
                command_result_t        result = { .rcode = RESULT_OK };        /* Reset to OK */
                char                    *p = strchr(buffer, '\n');
 
-               cc.lineno++;
+               cc->lineno++;
 
                if (!p) {
                        if (!feof(fp)) {
-                               ERROR("Line %d too long in %s", cc.lineno, cc.path);
+                               ERROR("Line %d too long in %s", cc->lineno, cc->path);
                                ret = -1;
                                goto finish;
                        }
@@ -1991,13 +2052,13 @@ static int process_file(bool *exit_now, TALLOC_CTX *ctx, CONF_SECTION *features,
                        *p = '\0';
                }
 
-               data_used = process_line(&result, &cc, data, data_used, buffer, strlen(buffer));
+               data_used = process_line(&result, cc, data, data_used, buffer, strlen(buffer));
                switch (result.rcode) {
                /*
                 *      Command completed successfully
                 */
                case RESULT_OK:
-                       cc.test_count++;
+                       cc->test_count++;
                        continue;
 
                /*
@@ -2025,13 +2086,13 @@ static int process_file(bool *exit_now, TALLOC_CTX *ctx, CONF_SECTION *features,
 
                                command = fr_table_value_by_longest_prefix(&match_len, commands, buffer, -1, NULL);
                                if (!command) {
-                                       ERROR("%s[%d]: Unknown command: %s", cc.path, cc.lineno, p);
+                                       ERROR("%s[%d]: Unknown command: %s", cc->path, cc->lineno, p);
                                        ret = -1;
                                        goto finish;
                                }
 
                                if (command->func == command_eof) {
-                                       command_ctx_reset(&cc, ctx);
+                                       command_ctx_reset(cc, ctx);
                                        break;
                                }
                        }
@@ -2042,7 +2103,7 @@ static int process_file(bool *exit_now, TALLOC_CTX *ctx, CONF_SECTION *features,
                 */
                case RESULT_PARSE_ERROR:
                case RESULT_COMMAND_ERROR:
-                       PERROR("%s[%d]", filename, cc.lineno);
+                       PERROR("%s[%d]", filename, cc->lineno);
                        ret = -1;
                        goto finish;
 
@@ -2067,11 +2128,12 @@ finish:
        if (fp && (fp != stdin)) fclose(fp);
 
        /*
-        *      Free any residual resources re loaded.
+        *      Free any residual resources we loaded.
         */
-       TALLOC_FREE(cc.tmp_ctx);
-       fr_dict_free(&cc.proto_dict);
        unload_proto_library();
+       fr_dict_free(&cc->active_dict);
+       talloc_free(cc);
+
 
        return ret;
 }
@@ -2118,8 +2180,6 @@ static void commands_print(void)
 int main(int argc, char *argv[])
 {
        int                     c;
-       char const              *raddb_dir = RADDBDIR;
-       char const              *dict_dir = DICTDIR;
        char const              *receipt_file = NULL;
        int                     *inst = &c;
        CONF_SECTION            *cs, *features;
@@ -2258,7 +2318,7 @@ int main(int argc, char *argv[])
         *      Read tests from stdin
         */
        if (argc < 2) {
-               ret = process_file(&exit_now, autofree, features, dict, NULL, "-");
+               ret = process_file(&exit_now, autofree, features, dict, dirname(argv[0]), "-");
 
        /*
         *      ...or process each file in turn.
@@ -2267,7 +2327,7 @@ int main(int argc, char *argv[])
                int i;
 
                for (i = 1; i < argc; i++) {
-                       ret = process_file(&exit_now, autofree, features, dict, NULL, argv[i]);
+                       ret = process_file(&exit_now, autofree, features, dict, dirname(argv[i]), basename(argv[i]));
                        if ((ret != 0) || exit_now) break;
                }
        }
@@ -2293,5 +2353,11 @@ cleanup:
         */
        fr_strerror_free();
 
+       /*
+        *      Explicitly free children to make
+        *      memory errors on exit less confusing.
+        */
+       talloc_free_children(autofree);
+
        return ret;
 }
index 0f8bc19ffaad1622af1c89872f32aa2e1fa48bc5..5be813afa1eeb6ac78cdded8a018b89b779393f4 100644 (file)
@@ -20,6 +20,7 @@ SOURCES               := \
                   event.c \
                   fopencookie.c \
                   fifo.c \
+                  file.c \
                   fring.c \
                   getaddrinfo.c \
                   hash.c \
index 5cb5776088acc62226de6db68cdbc66f960dc3ae..68d5afe800880dd283daf90ab79a3cb5827cf822 100644 (file)
@@ -9,7 +9,7 @@
 #  A bunch of errors, in the order that the error strings
 #  appear in parser.c
 #
-dictionary-load radius
+proto-dictionary radius
 
 condition &request:User-Name == &reply:User-Name
 match &User-Name == &reply:User-Name
index dd545d659de108b626653362d706b29842e87216..289470c2d436da3f5e665cd56d125202f7145ecf 100644 (file)
@@ -1,4 +1,4 @@
-dictionary-load radius
+proto-dictionary radius
 
 condition &User-Name !~ /^foo\nbar$/
 match !&User-Name =~ /^foo\nbar$/
index b1040041f675057e993ce85ef689d69472a73549..dd6226a654e4223036268b5d94c88f5afc7f5b2a 100644 (file)
@@ -1,8 +1,8 @@
 #
 #  Test vectors for DHCP attributes
 #
-load dhcpv4
-dictionary-load dhcpv4
+proto dhcpv4
+proto-dictionary dhcpv4
 
 #
 #  DHCP TLV types
index f2ac6ab990625546cac23120a6fb4e9a99f79da0..0be098c143d0945ec8027f81b91bc3cccac70c98 100644 (file)
@@ -1,5 +1,5 @@
-load dhcpv6
-dictionary-load dhcpv6
+proto dhcpv6
+proto-dictionary dhcpv6
 
 #
 #  Encode ipv6address
index 3baaca05afcc9710a777fdf429ecc1f2856231ee..579c9b0658ef15c5265fa6a3be8c5b37cad65bad 100644 (file)
@@ -1,5 +1,5 @@
-load dhcpv6
-dictionary-load dhcpv6
+proto dhcpv6
+proto-dictionary dhcpv6
 
 #
 #  Bool
index 50ef350289aa1db4b06a745f7600b09609094db8..3a61d292f6a0049fc66038d78d624a12a452d300 100644 (file)
@@ -1,5 +1,5 @@
-load dhcpv6
-dictionary-load dhcpv6
+proto dhcpv6
+proto-dictionary dhcpv6
 
 #
 #  Date. Like a 32bit unix timestamp but starts from 1st Jan 2000 instead of 1st Jan 1970
diff --git a/src/tests/unit/protocols/dhcpv6/dictionary b/src/tests/unit/protocols/dhcpv6/dictionary
new file mode 100644 (file)
index 0000000..4421a8e
--- /dev/null
@@ -0,0 +1,51 @@
+PROTOCOL       DHCPv6          3
+BEGIN-PROTOCOL DHCPv6
+
+#
+#      Basic options needed by the DHCPv6 pair encoder and decoder
+#
+ATTRIBUTE      Packet-Type                             65536   uint32  internal
+ATTRIBUTE      Transaction-ID                          65537   uint32  internal
+
+ATTRIBUTE      Option-Request                          65535   uint16 array    # Magic option listing requested options
+
+#
+#      Test attributes
+#
+ATTRIBUTE      Test-string                             1       string
+ATTRIBUTE      Test-octets                             2       octets
+
+ATTRIBUTE      Test-ipaddr                             3       ipaddr
+ATTRIBUTE      Test-ipv4addr                           4       ipv4addr
+ATTRIBUTE      Test-ipv4prefix                         5       ipv4prefix
+ATTRIBUTE      Test-ipv6addr                           6       ipv6addr
+ATTRIBUTE      Test-ipv6prefix                         7       ipv6prefix
+ATTRIBUTE      Test-ifid                               8       ifid
+ATTRIBUTE      Test-ether                              11      ether
+
+ATTRIBUTE      Test-bool                               12      bool
+
+ATTRIBUTE      Test-uint8                              13      uint8
+ATTRIBUTE      Test-uint16                             14      uint16
+ATTRIBUTE      Test-uint32                             15      uint32
+ATTRIBUTE      Test-uint64                             16      uint64
+
+ATTRIBUTE      Test-int8                               17      int8
+ATTRIBUTE      Test-int16                              18      int16
+ATTRIBUTE      Test-int32                              19      int32
+ATTRIBUTE      Test-int64                              20      int64
+
+ATTRIBUTE      Test-float32                            21      float32
+
+ATTRIBUTE      Test-time-delta                         23      time_delta
+ATTRIBUTE      Test-date                               24      date
+
+ATTRIBUTE      Test-size                               26      size
+
+ATTRIBUTE      Test-tlv                                27      tlv
+ATTRIBUTE      Test-struct                             28      struct
+
+ATTRIBUTE      Test-vsa                                30      vsa
+ATTRIBUTE      Test-group                              32      group
+
+END-PROTOCOL   DHCPv6
index 646f03c518c024f4c6a9193867cf8f9555ece37b..72754602df6a3d16286dc5a7f24f94ddc25e4b12 100644 (file)
@@ -1,5 +1,5 @@
-load dhcpv6
-dictionary-load dhcpv6
+proto dhcpv6
+proto-dictionary dhcpv6
 
 encode-pair SIP-Server-Domain-Name-List = "foo.ca"
 match 00 15 00 08 03 66 6f 6f 02 63 61 00
index 68a8fce1d14952436e8b0d30c6f6945add319d04..640b4a0f18e2009f2b201964556e0ddba8a2eadc 100644 (file)
@@ -1,5 +1,5 @@
-load dhcpv6
-dictionary-load dhcpv6
+proto dhcpv6
+proto-dictionary dhcpv6
 
 #
 #  Array of 16bit integers
index d067716adc6e9a7434239fcc575490a5e59a07a2..003f2fd16eeaaa540709790d2b742110aab79487 100644 (file)
@@ -1,5 +1,5 @@
-load dhcpv6
-dictionary-load dhcpv6
+proto dhcpv6
+proto-dictionary dhcpv6
 
 #
 #  1 byte unsigned integer (uint8)
index c702e7db280faef82dbd4804b33081b89e2de677..26dc2dce2550d815d674929ff3bc2149920a6223 100644 (file)
@@ -1,5 +1,5 @@
-load dhcpv6
-dictionary-load dhcpv6
+proto dhcpv6
+proto-dictionary dhcpv6
 
 #
 #  Microsoft VSAs. We have no idea what the contents are, and the documentation doesn't say.
index 1a589cc5c7a33a041621bb8544fa8ef0bae4d161..da36c020a485c467db7fcb3651aa70ba41dedb0c 100644 (file)
@@ -1,5 +1,5 @@
-load dhcpv6
-dictionary-load dhcpv6
+proto dhcpv6
+proto-dictionary dhcpv6
 
 #
 #  Encoding an option header:
index 89776d885dacf87cd4da3d6705e6ba2b9faf94a3..797a9d547113a64c2b781145ee3b2945a0196255 100644 (file)
@@ -1,5 +1,5 @@
-load dhcpv6
-dictionary-load dhcpv6
+proto dhcpv6
+proto-dictionary dhcpv6
 
 #
 #  3.1  SIP Servers Domain Name List
index e807c0a0408026b0cecd20cba1d48f838b286321..a415b953c2c690edc1459c5dbfe074ba618e0de3 100644 (file)
@@ -1,5 +1,5 @@
-load dhcpv6
-dictionary-load dhcpv6
+proto dhcpv6
+proto-dictionary dhcpv6
 
 #
 #  Encoding an option header:
index 8ace778c5290a1af7344a157b886fdf3b4361354..94d43e69be61ab4730a80d75383c43db3da0cff6 100644 (file)
@@ -1,5 +1,5 @@
-load dhcpv6
-dictionary-load dhcpv6
+proto dhcpv6
+proto-dictionary dhcpv6
 
 #
 #  Encoding an option header:
index a37c627b7904f75b09e5633644c823159edf9af1..4d0d831d4fc51d1069cb00faca50f70371cd9b75 100644 (file)
@@ -5,8 +5,8 @@
 #
 #  Test vectors for DHCPv6 protocol
 #
-load dhcpv6
-dictionary-load dhcpv6
+proto dhcpv6
+proto-dictionary dhcpv6
 
 #
 #  8.  Client/Server Message Formats
index df1197bcbd4d8ff44e15c230ce97c2893bee36db..e9617b2daf1b0efbb3744bb414966c3c70c806d6 100644 (file)
@@ -1,5 +1,5 @@
-load dhcpv6
-dictionary-load dhcpv6
+proto dhcpv6
+proto-dictionary dhcpv6
 
 #
 #  Simple string type
index 35ba2410d7141df4344e3a52c556ea92d75bcbfa..184f3b8612663183e79eb6f1f30da14b62529540 100644 (file)
@@ -1,5 +1,5 @@
-load dhcpv6
-dictionary-load dhcpv6
+proto dhcpv6
+proto-dictionary dhcpv6
 
 #
 #  TLV with array type values
index 7d6a91b17517a07af78145f2c8462d8328ebc0a8..bda53e44c8b03a2d89a4f0e097c607f0a0d92b65 100644 (file)
@@ -1,5 +1,5 @@
-load dhcpv6
-dictionary-load dhcpv6
+proto dhcpv6
+proto-dictionary dhcpv6
 
 #
 #  Array of strings, each substring should have a 16bit length field containing its length
index 0c06e3c83e73e5660bb4904d622d51369b1db5e2..9b7dd3295f00111d1c563a0b092eb1471d3a7d06 100644 (file)
@@ -6,8 +6,8 @@
 need-feature tls
 
 # Load the EAP-SIM module
-load eap-aka-sim
-dictionary-load eap-aka-sim eap/aka-sim
+proto eap-aka-sim
+proto-dictionary eap-aka-sim eap/aka-sim
 
 #
 # Encode some AKA attributes with special formats
index e10cfd6a603562a5980bec910f57849ebb46602d..6c85d3a7310b43b4d93bf02d5eb7999d992b35de 100644 (file)
@@ -6,8 +6,8 @@
 need-feature tls
 
 # Load the EAP-AKA/SIM encoder/decoder
-load eap-aka-sim
-dictionary-load eap-aka-sim eap/aka-sim
+proto eap-aka-sim
+proto-dictionary eap-aka-sim eap/aka-sim
 
 #
 # Encode some AKA attributes with special formats
index bdb8fdb2870a8a0a9805d69cf087455f76587d08..b282ac0adabff51ae64618535e09f91b52cd3a95 100644 (file)
@@ -8,8 +8,8 @@
 need-feature tls
 
 # Load the EAP-AKA/SIM encoder/decoder
-load eap-aka-sim
-dictionary-load eap-aka-sim eap/aka-sim
+proto eap-aka-sim
+proto-dictionary eap-aka-sim eap/aka-sim
 
 # AKA_RES with invalid length (too small)
 decode-pair.aka_tp_decode 04 03 aa bb aa aa aa aa bb bb bb bb
index f5139ceb35d14889d5263c2aaef44081b7e102cd..f42c17b1b4f27c1ba88a1b6a64f5e8dfbc807eb1 100644 (file)
@@ -8,8 +8,8 @@
 need-feature tls
 
 # Load the EAP-AKA/SIM encoder/decoder
-load eap-aka-sim
-dictionary-load eap-aka-sim eap/aka-sim
+proto eap-aka-sim
+proto-dictionary eap-aka-sim eap/aka-sim
 
 # Boolean attribute
 decode-pair.sim_tp_decode 0d 01 00 00
index 715088203551760bc62b0ca48913ec595db8eda7..fdd17c6467ca4f66b1e557181bfc90ba2012947a 100644 (file)
@@ -6,8 +6,8 @@
 need-feature tls
 
 # Load the EAP-AKA/SIM encoder/decoder
-load eap-aka-sim
-dictionary-load eap-aka-sim eap/aka-sim
+proto eap-aka-sim
+proto-dictionary eap-aka-sim eap/aka-sim
 
 # Boolean attribute
 encode-pair.sim_tp_encode Any-ID-Req = yes
index 33b3c288b2aa3ca7e5414581bd3627236a9ec146..d9474969bd06105a384acbd9e9b64802319ac919 100644 (file)
@@ -8,8 +8,8 @@
 need-feature tls
 
 # Load the EAP-AKA/SIM encoder/decoder
-load eap-aka-sim
-dictionary-load eap-aka-sim eap/aka-sim
+proto eap-aka-sim
+proto-dictionary eap-aka-sim eap/aka-sim
 
 # Zero length attribute
 decode-pair.sim_tp_decode 0d 00
index ddc0caea51bc5cf1a27b01b7fcb790e20ff47cd2..c6f48b681e97553a1e601448e9a67655da11fac9 100644 (file)
@@ -1,7 +1,7 @@
 #
 #  Tests for the ethernet encoder/decoder
 #
-load ethernet
+proto ethernet
 
 encode-proto.libfreeradius_ethernet Ethernet-Src-Address = 0x010203040506, Ethernet-Dst-Address = 0x060504030201
 # data 06 04 05 04 03 02 01 01 02 03 04 05 06 00 00
index 6a44445c6863d15f2cd852a97d609434f4bf4c69..7c7fd507fde06e383fb7b3975f940e2a35309b7e 100644 (file)
@@ -1,8 +1,8 @@
 #
 #  Bad attributes
 #
-load radius
-dictionary-load radius
+proto radius
+proto-dictionary radius
 
 decode-pair 01 04 00
 match fr_radius_decode_pair: Insufficient data
index 106b867909a4d830a0924c5709d785741689d73a..1fdb6aa8f1b33b60ff4e3bc1168fb479cb4f1294 100644 (file)
@@ -1,6 +1,6 @@
 # Load libfreeradius-radius
-load radius
-dictionary-load radius
+proto radius
+proto-dictionary radius
 
 # Example attributes as used in RFC 6929
 raw 241.1 "bob"
index cd652caed1c5a388acbf8ef1eb5e716cb34a5f22..a1bcf159a5abf60b3964ce962b7790236fb6cbc9 100644 (file)
@@ -1,5 +1,5 @@
-load radius
-dictionary-load radius
+proto radius
+proto-dictionary radius
 
 encode-pair Lucent-Max-Shared-Users = 1
 match 1a 0d 00 00 12 ee 00 02 07 00 00 00 01
index 95d38b311f4c50f1ab3e27badc0301632875b617..c0058f98a746cdcc01a2d29f1d0287668fe88127 100644 (file)
@@ -74,8 +74,8 @@
 #  The output data is the hex version of the encode-paird attribute.
 #
 
-load radius
-dictionary-load radius
+proto radius
+proto-dictionary radius
 
 encode-pair User-Name = "bob"
 match 01 05 62 6f 62
index 4c05863b5b5dff4393d741ae8be28003b1f4debf..55ca04ff5156d61ea49768caeba5d85430c5c66f 100644 (file)
@@ -1,5 +1,5 @@
-load radius
-dictionary-load radius
+proto radius
+proto-dictionary radius
 
 #
 #  Structs in RADIUS
index 81c1b9fd97fdb1fe63ab2172d62004ddb37c87fc..c1649da3c004c6563e5b6303d3333cf8c5fdb9d3 100644 (file)
@@ -1,5 +1,5 @@
-load radius
-dictionary-load radius
+proto radius
+proto-dictionary radius
 
 #
 #  We can't look at the data here, because the encode-paird Tunnel-Password has a 2 byte
index 66cb5e4a0c4e817d0d7dcb5a63c657fc28f0e15c..9bc8537c4d0068145b2dae5b16b541faeb0fc432 100644 (file)
@@ -1,6 +1,6 @@
 # Load libfreeradius-radius
-load radius
-dictionary-load radius
+proto radius
+proto-dictionary radius
 
 #
 #  And using the dictionaries
index 849eb8c0cf02e94aec5acae6be1f205973398d9c..5f20277813fcdc95f4565ae712f276f5cbadfd98 100644 (file)
@@ -1,5 +1,5 @@
-load radius
-dictionary-load radius
+proto radius
+proto-dictionary radius
 
 encode-pair SN-VPN-Name = "foo"
 match 1a 0d 00 00 1f e4 00 02 00 07 66 6f 6f
index 5ea63e5b0a297785dfd93597ee53f4890b5482d9..e29c012e22b1a9b9f8149338c8970a02cf226e5b 100644 (file)
@@ -1,5 +1,5 @@
-load radius
-dictionary-load radius
+proto radius
+proto-dictionary radius
 
 #
 #  Test vectors for WiMAX attributes.
index 630f685c9ee5515bdfd856a2033a7f5f3cd8928a..4d3a28a1773bd8ebbee2d215a6c775356d8a2f58 100644 (file)
@@ -1,4 +1,4 @@
-dictionary-load radius
+proto-dictionary radius
 
 #
 #  Literals