]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
v4: Convert eap-aka-sim xlats to new api (#4030)
authorNick Porter <nick@portercomputing.co.uk>
Thu, 25 Mar 2021 19:32:27 +0000 (19:32 +0000)
committerGitHub <noreply@github.com>
Thu, 25 Mar 2021 19:32:27 +0000 (19:32 +0000)
* Convert %{aka_sim_id_method: } to new xlat api

* Update docs for new %(aka_sim_id_method: ) syntax

* Update tests for new %(aka_sim_id_method: ) syntax

* Convert %{aka_sim_id_type: } to new xlat api

* Update docs for new %(aka_sim_id_type: ) syntax

* Update tests for new %(aka_sim_id_type: ) syntax

* Convert %{3gpp_pseudonym_key_index: } xlat to new api

* Update docs for new %(3gpp_pseudonym_key_index: ) syntax

* Convert %(3gpp_pseudonym_decrypt: ) to new xlat api

* Amend documentation for new syntax of %(3gpp_pseudonym_decrypt: ) xlat

* Auto load eap_aka_sim enums for xlats

* Convert %(3gpp_pseudonym_encrypt: ) to new xlat api

* Update documentation to new %(3gpp_pseudonym_encrypt: ) syntax

* Update tests to use new %(3gpp_pseudonym_encrypt: ) syntax

* Move eap_aka_sim tests to eap_sim to match module name so they run.

* Tidy eap_sim test files

17 files changed:
doc/antora/modules/raddb/pages/mods-available/eap.adoc
doc/antora/modules/raddb/pages/sites-available/eap-aka-sim.adoc
raddb/mods-available/eap
raddb/sites-available/eap-aka-sim
scripts/build/missing-xlat-doc.txt
src/lib/eap_aka_sim/base.c
src/lib/eap_aka_sim/xlat.c
src/tests/modules/eap_aka_sim/sim_xlat_id_sim.unlang [deleted file]
src/tests/modules/eap_sim/.gitignore [moved from src/tests/modules/eap_aka_sim/.gitignore with 100% similarity]
src/tests/modules/eap_sim/all.mk [moved from src/tests/modules/eap_aka_sim/all.mk with 100% similarity]
src/tests/modules/eap_sim/module.conf [moved from src/tests/modules/eap_aka_sim/module.conf with 100% similarity]
src/tests/modules/eap_sim/sim_xlat_id_aka.attrs [moved from src/tests/modules/eap_aka_sim/sim_xlat_id_aka.attrs with 100% similarity]
src/tests/modules/eap_sim/sim_xlat_id_aka.unlang [moved from src/tests/modules/eap_aka_sim/sim_xlat_id_aka.unlang with 52% similarity]
src/tests/modules/eap_sim/sim_xlat_id_error.attrs [moved from src/tests/modules/eap_aka_sim/sim_xlat_id_error.attrs with 100% similarity]
src/tests/modules/eap_sim/sim_xlat_id_error.unlang [moved from src/tests/modules/eap_aka_sim/sim_xlat_id_error.unlang with 56% similarity]
src/tests/modules/eap_sim/sim_xlat_id_sim.attrs [moved from src/tests/modules/eap_aka_sim/sim_xlat_id_sim.attrs with 100% similarity]
src/tests/modules/eap_sim/sim_xlat_id_sim.unlang [new file with mode: 0644]

index 7ec0944ecd377cd3b2f0c8b6e559e3d2e6ab7b55..d7751f098374907db3c099193a59f7cba77fd5ee 100644 (file)
@@ -1484,7 +1484,7 @@ require user configuration.
 
 The rlm_eap module provides the below functions to interact with the `3GPP` and `SIM` protocols.
 
-### %{3gpp_pseudonym_decrypt:...}
+### %(3gpp_pseudonym_decrypt:...)
 
 TODO
 
@@ -1503,7 +1503,7 @@ TODO
 TODO
 ```
 
-### %{3gpp_pseudonym_encrypt:...}
+### %(3gpp_pseudonym_encrypt:...)
 
 TODO
 
@@ -1522,7 +1522,7 @@ TODO
 TODO
 ```
 
-### %{3gpp_pseudonym_key_index:...}
+### %(3gpp_pseudonym_key_index:...)
 
 TODO
 
index 0d2a81d4f1129cf616ea046eab2a4a9c0b516688..61938048bdb8618ce8736d4ddaa0f9360133b220 100644 (file)
@@ -137,7 +137,7 @@ modules.  Usually this is not an issue because EAP Negotiation
 allows the supplicant and server to negotiate a mutually acceptable
 EAP type. If, however, you want to avoid the additional round trips
 involved in that negotiation, you can use
-`%{aka_sim_id_method:User-Name}` in the top level virtual server,
+`%(aka_sim_id_method:%{User-Name})` in the top level virtual server,
 which will return the EAP method hinted by the identity, and then
 set `&control.EAP-Type` to an appropriate value before calling the
 EAP module.
@@ -300,7 +300,7 @@ The following facilitates may be useful when generating pseudonym
 values:
 
 - The encrypt expansions of the `rlm_cipher` module.
-- The `%{3gpp_pseudonym_encrypt:}` expansion.
+- The `%(3gpp_pseudonym_encrypt:)` expansion.
 - The `%{rand:}` expansion.
 
 NOTE: Add a `&reply.Next-Pseudonym-Id` attribute in this section to
index 088c0f32d20f3bcf515057e1c2f8a8f1fc86ef5e..b1cd2d7b736cabb2d25fde3c8d4e14af68fffcae 100644 (file)
@@ -1638,7 +1638,7 @@ eap {
 #
 #  The rlm_eap module provides the below functions to interact with the `3GPP` and `SIM` protocols.
 #
-#  ### %{3gpp_pseudonym_decrypt:...}
+#  ### %(3gpp_pseudonym_decrypt:...)
 #
 #  TODO
 #
@@ -1657,7 +1657,7 @@ eap {
 #  TODO
 #  ```
 #
-#  ### %{3gpp_pseudonym_encrypt:...}
+#  ### %(3gpp_pseudonym_encrypt:...)
 #
 #  TODO
 #
@@ -1676,7 +1676,7 @@ eap {
 #  TODO
 #  ```
 #
-#  ### %{3gpp_pseudonym_key_index:...}
+#  ### %(3gpp_pseudonym_key_index:...)
 #
 #  TODO
 #
@@ -1695,7 +1695,7 @@ eap {
 #  TODO
 #  ```
 #
-#  ### %{sim_id_method:...}
+#  ### %(aka_sim_id_method:...)
 #
 #  TODO
 #
@@ -1714,7 +1714,7 @@ eap {
 #  TODO
 #  ```
 #
-#  ### %{sim_id_type:...}
+#  ### %(aka_sim_id_type:...)
 #
 #  TODO
 #
index 0a6d1ef48c8f80aca928f98719a5b26db21f3d24..14f4e29cbaf2602172c4a3eb4d9aaf8532521978 100644 (file)
@@ -148,7 +148,7 @@ server eap-aka-sim {
        #  allows the supplicant and server to negotiate a mutually acceptable
        #  EAP type. If, however, you want to avoid the additional round trips
        #  involved in that negotiation, you can use
-       #  `%{aka_sim_id_method:User-Name}` in the top level virtual server,
+       #  `%(aka_sim_id_method:%{User-Name})` in the top level virtual server,
        #  which will return the EAP method hinted by the identity, and then
        #  set `&control.EAP-Type` to an appropriate value before calling the
        #  EAP module.
@@ -326,7 +326,7 @@ server eap-aka-sim {
        #  values:
        #
        #  - The encrypt expansions of the `rlm_cipher` module.
-       #  - The `%{3gpp_pseudonym_encrypt:}` expansion.
+       #  - The `%(3gpp_pseudonym_encrypt:)` expansion.
        #  - The `%{rand:}` expansion.
        #
        #  NOTE: Add a `&reply.Next-Pseudonym-Id` attribute in this section to
index f98b83e81999a0c211c9c0cc6ce29f32415fc2b2..43b65538ef6126fc87b11faa4ae062b13e9c8efb 100644 (file)
@@ -1,4 +1,4 @@
-%{aka_sim_id_type:...}
+%(aka_sim_id_type:...)
 %{attr:...}
 %{attr_by_num:...}
 %{attr_by_oid:...}
index 0846bfbc3791f839e31b346670c851a279edc01c..0008f02aa42fa408053674751c15f0c7a374cafb 100644 (file)
@@ -257,6 +257,10 @@ int fr_aka_sim_init(void)
                fr_dict_autofree(libfreeradius_aka_sim_dict);
                return -1;
        }
+       if (fr_dict_enum_autoload(libfreeradius_aka_sim_dict_enum) < 0) {
+               PERROR("Failed loading libfreeradius-eap-aka-sim enumerations");
+               return -1;
+       }
        instance_count++;
 
        return 0;
index 455abafbd3e3314c4e1d7f3ecfb40abb303b5eb2..ec668baf27fac3dcd06dc3efe7282d7210349fe3 100644 (file)
 static int aka_sim_xlat_refs = 0;
 
 
+static xlat_arg_parser_t const aka_sim_xlat_id_method_xlat_args[] = {
+       { .required = true, .single = true, .type = FR_TYPE_STRING },
+       XLAT_ARG_PARSER_TERMINATOR
+};
+
 /** Returns the SIM method EAP-SIM or EAP-AKA hinted at by the user identifier
  *
 @verbatim
-%{aka_sim_id_method:&id_attr}
+%(aka_sim_id_method:%{id_attr})
 @endverbatim
  *
  * @ingroup xlat_functions
  */
-static ssize_t aka_sim_xlat_id_method_xlat(TALLOC_CTX *ctx, char **out, UNUSED size_t outlen,
-                                          UNUSED void const *mod_inst, UNUSED void const *xlat_inst,
-                                          request_t *request, char const *fmt)
+static xlat_action_t aka_sim_xlat_id_method_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, request_t *request,
+                                                UNUSED void const *xlat_inst, UNUSED void *xlat_thread_inst,
+                                                fr_value_box_list_t *in)
 {
-       tmpl_t                          *vpt;
-       TALLOC_CTX                      *our_ctx = talloc_init_const("aka_sim_xlat");
-       ssize_t                         slen, id_len;
-       char const                      *p = fmt, *id, *method;
+       char const                      *method;
        fr_aka_sim_id_type_t            type_hint;
        fr_aka_sim_method_hint_t        method_hint;
+       fr_value_box_t                  *id = fr_dlist_head(in);
+       fr_value_box_t                  *vb;
 
-       /*
-        *  Trim whitespace
-        */
-       fr_skip_whitespace(p);
-
-       slen = tmpl_afrom_attr_substr(our_ctx, NULL, &vpt, &FR_SBUFF_IN(p, strlen(p)),
-                                     NULL,
-                                     &(tmpl_rules_t){
-                                               .dict_def = request->dict,
-                                               .prefix = TMPL_ATTR_REF_PREFIX_AUTO
-                                     });
-       if (slen <= 0) {
-               RPEDEBUG("Invalid attribute reference");
-       error:
-               talloc_free(our_ctx);
-               return -1;
-       }
-
-       if (tmpl_aexpand(our_ctx, &id, request, vpt, NULL, NULL) < 0) {
-               RPEDEBUG2("Failing expanding ID attribute");
-               goto error;
-       }
-
-       id_len = talloc_array_length(id) - 1;
-       if (fr_aka_sim_id_type(&type_hint, &method_hint, id, id_len) < 0) {
-               RPEDEBUG2("AKA/SIM Id \"%pV\" has unrecognised format", fr_box_strvalue_len(id, id_len));
-               goto error;
+       if (fr_aka_sim_id_type(&type_hint, &method_hint, id->vb_strvalue, id->vb_length) < 0) {
+               RPEDEBUG2("AKA/SIM Id \"%pV\" has unrecognised format", id);
+               return XLAT_ACTION_FAIL;
        }
 
        switch (method_hint) {
        default:
        case AKA_SIM_METHOD_HINT_UNKNOWN:
-               *out = NULL;
-               return 0;
+               return XLAT_ACTION_DONE;
 
        case AKA_SIM_METHOD_HINT_SIM:
                method = fr_dict_enum_name_by_value(attr_eap_aka_sim_method_hint,
@@ -98,65 +77,45 @@ static ssize_t aka_sim_xlat_id_method_xlat(TALLOC_CTX *ctx, char **out, UNUSED s
                break;
        }
 
-       *out = talloc_typed_strdup(ctx, method);
-       talloc_free(our_ctx);
+       MEM(vb = fr_value_box_alloc(ctx, FR_TYPE_STRING, NULL, false));
+       fr_value_box_bstrndup(ctx, vb, NULL, method, strlen(method), false);
+       fr_dcursor_append(out, vb);
 
-       return talloc_array_length(*out) - 1;
+       return XLAT_ACTION_DONE;
 }
 
+static xlat_arg_parser_t const aka_sim_xlat_id_type_xlat_args[] = {
+       { .required = true, .single = true, .type = FR_TYPE_STRING },
+       XLAT_ARG_PARSER_TERMINATOR
+};
+
 /** Returns the type of identity used
  *
 @verbatim
-%{aka_sim_id_type:&id_attr}
+%(aka_sim_id_type:%{id_attr})
 @endverbatim
  *
  * @ingroup xlat_functions
  */
-static ssize_t aka_sim_xlat_id_type_xlat(TALLOC_CTX *ctx, char **out, UNUSED size_t outlen,
-                               UNUSED void const *mod_inst, UNUSED void const *xlat_inst,
-                               request_t *request, char const *fmt)
+static xlat_action_t aka_sim_xlat_id_type_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, request_t *request,
+                                              UNUSED void const *xlat_inst, UNUSED void *xlat_thread_inst,
+                                              fr_value_box_list_t *in)
 {
-       tmpl_t                  *vpt;
-       TALLOC_CTX                      *our_ctx = talloc_init_const("aka_sim_xlat");
-       ssize_t                         slen, id_len;
-       char const                      *p = fmt, *id, *type;
+       char const                      *type;
        fr_aka_sim_id_type_t            type_hint;
        fr_aka_sim_method_hint_t        method_hint;
+       fr_value_box_t                  *id = fr_dlist_head(in);
+       fr_value_box_t                  *vb;
 
-       /*
-        *  Trim whitespace
-        */
-       fr_skip_whitespace(p);
-
-       slen = tmpl_afrom_attr_substr(our_ctx, NULL, &vpt, &FR_SBUFF_IN(p, strlen(p)),
-                                     NULL,
-                                     &(tmpl_rules_t){
-                                               .dict_def = request->dict,
-                                               .prefix = TMPL_ATTR_REF_PREFIX_AUTO
-                                     });
-       if (slen <= 0) {
-               RPEDEBUG("Invalid attribute reference");
-       error:
-               talloc_free(our_ctx);
-               return -1;
-       }
-
-       if (tmpl_aexpand(our_ctx, &id, request, vpt, NULL, NULL) < 0) {
-               RPEDEBUG2("Failing expanding ID attribute");
-               goto error;
-       }
-
-       id_len = talloc_array_length(id) - 1;
-       if (fr_aka_sim_id_type(&type_hint, &method_hint, id, id_len) < 0) {
-               RPEDEBUG2("AKA/AKA/SIM Id \"%pV\" has unrecognised format", fr_box_strvalue_len(id, id_len));
-               goto error;
+       if (fr_aka_sim_id_type(&type_hint, &method_hint, id->vb_strvalue, id->vb_length) < 0) {
+               RPEDEBUG2("AKA/AKA/SIM Id \"%pV\" has unrecognised format", id);
+               return XLAT_ACTION_FAIL;
        }
 
        switch (type_hint) {
        default:
        case AKA_SIM_ID_TYPE_UNKNOWN:
-               *out = NULL;
-               return 0;
+               return XLAT_ACTION_DONE;
 
        case AKA_SIM_ID_TYPE_PERMANENT:
                type = fr_dict_enum_name_by_value(attr_eap_aka_sim_identity_type,
@@ -174,92 +133,71 @@ static ssize_t aka_sim_xlat_id_type_xlat(TALLOC_CTX *ctx, char **out, UNUSED siz
                break;
        }
 
-       *out = talloc_typed_strdup(ctx, type);
-       talloc_free(our_ctx);
+       MEM(vb = fr_value_box_alloc(ctx, FR_TYPE_STRING, NULL, false));
+       fr_value_box_bstrndup(ctx, vb, NULL, type, strlen(type), false);
+       fr_dcursor_append(out, vb);
 
-       return talloc_array_length(*out) - 1;
+       return XLAT_ACTION_DONE;
 }
 
+static xlat_arg_parser_t const aka_sim_id_3gpp_pseudonym_key_index_xlat_args[] = {
+       { .required = true, .single = true, .type = FR_TYPE_STRING },
+       XLAT_ARG_PARSER_TERMINATOR
+};
+
 /** Returns the key index from a 3gpp pseudonym
  *
 @verbatim
-%{3gpp_pseudonym_key_index:&id_attr}
+%(3gpp_pseudonym_key_index:%{id_attr})
 @endverbatim
  *
  * @ingroup xlat_functions
  */
-static ssize_t aka_sim_3gpp_pseudonym_key_index_xlat(TALLOC_CTX *ctx, char **out, UNUSED size_t outlen,
-                                                UNUSED void const *mod_inst, UNUSED void const *xlat_inst,
-                                                request_t *request, char const *fmt)
+static xlat_action_t aka_sim_id_3gpp_pseudonym_key_index_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, request_t *request,
+                                                             UNUSED void const *xlat_inst,
+                                                             UNUSED void *xlat_thread_inst, fr_value_box_list_t *in)
 {
-       tmpl_t  *vpt;
-       TALLOC_CTX      *our_ctx = talloc_init_const("aka_sim_xlat");
-       ssize_t         slen, id_len;
-       char const      *p = fmt, *id;
-
-       /*
-        *  Trim whitespace
-        */
-       fr_skip_whitespace(p);
-
-       slen = tmpl_afrom_attr_substr(our_ctx, NULL, &vpt, &FR_SBUFF_IN(p, strlen(p)),
-                                     NULL,
-                                     &(tmpl_rules_t){
-                                               .dict_def = request->dict,
-                                               .prefix = TMPL_ATTR_REF_PREFIX_AUTO
-                                     });
-       if (slen <= 0) {
-               RPEDEBUG("Invalid attribute reference");
-       error:
-               talloc_free(our_ctx);
-               return -1;
-       }
-
-       if (tmpl_aexpand(our_ctx, &id, request, vpt, NULL, NULL) < 0) {
-               RPEDEBUG2("Failing expanding ID attribute");
-               goto error;
-       }
+       fr_value_box_t  *id = fr_dlist_head(in);
+       fr_value_box_t  *vb;
 
-       id_len = talloc_array_length(id) - 1;
-       if (id_len != AKA_SIM_3GPP_PSEUDONYM_LEN) {
+       if (id->vb_length != AKA_SIM_3GPP_PSEUDONYM_LEN) {
                REDEBUG2("3gpp pseudonym incorrect length, expected %i bytes, got %zu bytes",
-                        AKA_SIM_3GPP_PSEUDONYM_LEN, id_len);
-               goto error;
+                        AKA_SIM_3GPP_PSEUDONYM_LEN, id->vb_length);
+               return XLAT_ACTION_FAIL;
        }
 
-       MEM(*out = talloc_typed_asprintf(ctx, "%i", fr_aka_sim_id_3gpp_pseudonym_tag(id)));
-       talloc_free(our_ctx);
+       MEM(vb = fr_value_box_alloc(ctx, FR_TYPE_UINT8, NULL, false));
+       vb->vb_uint8 = fr_aka_sim_id_3gpp_pseudonym_tag(id->vb_strvalue);
+       fr_dcursor_append(out, vb);
 
-       return talloc_array_length(*out) - 1;
+       return XLAT_ACTION_DONE;
 }
 
 /** Decrypt a 3gpp pseudonym
  *
 @verbatim
-%{3gpp_pseudonym_decrypt:&id_attr &key_attr}
+%(3gpp_pseudonym_decrypt:&id_attr &key_attr)
 @endverbatim
  *
  * @ingroup xlat_functions
  */
-static ssize_t aka_sim_3gpp_pseudonym_decrypt_xlat(TALLOC_CTX *ctx, char **out, UNUSED size_t outlen,
-                                              UNUSED void const *mod_inst, UNUSED void const *xlat_inst,
-                                              request_t *request, char const *fmt)
+static xlat_action_t aka_sim_3gpp_pseudonym_decrypt_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, request_t *request,
+                                                        UNUSED void const *xlat_inst,
+                                                        UNUSED void *xlat_thread_inst, fr_value_box_list_t *in)
 {
        tmpl_t  *id_vpt, *key_vpt;
        TALLOC_CTX      *our_ctx = talloc_init_const("aka_sim_xlat");
        ssize_t         slen, id_len, key_len;
        uint8_t         tag;
-       char            out_tag;
+       char            out_tag, *buff;
        uint8_t         *key;
        char            decrypted[AKA_SIM_IMSI_MAX_LEN + 1];
-       char const      *p = fmt, *id;
-
-       /*
-        *  Trim whitespace
-        */
-       fr_skip_whitespace(p);
+       char const      *id;
+       fr_value_box_t  *id_vb = fr_dlist_head(in);
+       fr_value_box_t  *key_vb = fr_dlist_next(in, id_vb);
+       fr_value_box_t  *vb;
 
-       slen = tmpl_afrom_attr_substr(our_ctx, NULL, &id_vpt, &FR_SBUFF_IN(p, strlen(p)),
+       slen = tmpl_afrom_attr_substr(our_ctx, NULL, &id_vpt, &FR_SBUFF_IN(id_vb->vb_strvalue, id_vb->vb_length),
                                      NULL,
                                      &(tmpl_rules_t){
                                                .dict_def = request->dict,
@@ -269,17 +207,10 @@ static ssize_t aka_sim_3gpp_pseudonym_decrypt_xlat(TALLOC_CTX *ctx, char **out,
                RPEDEBUG("Invalid ID attribute reference");
        error:
                talloc_free(our_ctx);
-               return -1;
+               return XLAT_ACTION_FAIL;
        }
 
-       p += slen;
-       if (*p != ' ') {
-               REDEBUG2("Missing key argument");
-               goto error;
-       }
-       p++;
-
-       slen = tmpl_afrom_attr_substr(our_ctx, NULL, &key_vpt, &FR_SBUFF_IN(p, strlen(p)),
+       slen = tmpl_afrom_attr_substr(our_ctx, NULL, &key_vpt, &FR_SBUFF_IN(key_vb->vb_strvalue, key_vb->vb_length),
                                      NULL,
                                      &(tmpl_rules_t){
                                                .dict_def = request->dict,
@@ -342,41 +273,53 @@ static ssize_t aka_sim_3gpp_pseudonym_decrypt_xlat(TALLOC_CTX *ctx, char **out,
        /*
         *      Recombine unencrypted IMSI with tag
         */
-       MEM(*out = talloc_typed_asprintf(ctx, "%c%s", out_tag, decrypted));
+       MEM(vb = fr_value_box_alloc_null(ctx));
+       fr_value_box_bstr_alloc(ctx, &buff, vb, NULL, AKA_SIM_IMSI_MAX_LEN + 1, false);
+       *buff = out_tag;
+       strncpy(buff+1, decrypted, AKA_SIM_IMSI_MAX_LEN + 1);
+       fr_dcursor_append(out, vb);
        talloc_free(our_ctx);
 
-       return talloc_array_length(*out) - 1;
+       return XLAT_ACTION_DONE;
 }
 
+extern xlat_arg_parser_t aka_sim_3gpp_pseudonym_decrypt_xlat_args[];
+xlat_arg_parser_t aka_sim_3gpp_pseudonym_decrypt_xlat_args[] = {
+       { .required = true, .concat = true, .single = false, .variadic = false, .type = FR_TYPE_STRING,
+         .func = NULL, .uctx = NULL },
+       { .required = true, .concat = true, .single = false, .variadic = false, .type = FR_TYPE_STRING,
+         .func = NULL, .uctx = NULL },
+       XLAT_ARG_PARSER_TERMINATOR
+};
+
 /** Encrypts a 3gpp pseudonym
  *
 @verbatim
-%{3gpp_pseudonym_encrypt:&id_attr &key_attr key_index}
+%(3gpp_pseudonym_encrypt:&id_attr &key_attr key_index)
 @endverbatim
  *
  * @ingroup xlat_functions
  */
-static ssize_t aka_sim_3gpp_pseudonym_encrypt_xlat(TALLOC_CTX *ctx, char **out, UNUSED size_t outlen,
-                                              UNUSED void const *mod_inst, UNUSED void const *xlat_inst,
-                                              request_t *request, char const *fmt)
+static xlat_action_t aka_sim_3gpp_pseudonym_encrypt_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, request_t *request,
+                                                        UNUSED void const *xlat_inst,
+                                                        UNUSED void *xlat_thread_inst, fr_value_box_list_t *in)
 {
-       tmpl_t                  *id_vpt, *key_vpt;
+       tmpl_t                          *id_vpt, *key_vpt;
        TALLOC_CTX                      *our_ctx = talloc_init_const("aka_sim_xlat");
        ssize_t                         slen, id_len, key_len;
        uint8_t                         *key, tag = 0;
        unsigned long                   key_index;
        char                            encrypted[AKA_SIM_3GPP_PSEUDONYM_LEN + 1];
-       char const                      *p = fmt, *id;
-       char const              *id_p, *id_end;
+       char const                      *id;
+       char const                      *id_p, *id_end;
        fr_aka_sim_id_type_t            type_hint;
        fr_aka_sim_method_hint_t        method_hint;
+       fr_value_box_t                  *id_vb = fr_dlist_head(in);
+       fr_value_box_t                  *attr_vb = fr_dlist_next(in, id_vb);
+       fr_value_box_t                  *index_vb = fr_dlist_next(in, attr_vb);
+       fr_value_box_t                  *vb;
 
-       /*
-        *  Trim whitespace
-        */
-       fr_skip_whitespace(p);
-
-       slen = tmpl_afrom_attr_substr(our_ctx, NULL, &id_vpt, &FR_SBUFF_IN(p, strlen(p)),
+       slen = tmpl_afrom_attr_substr(our_ctx, NULL, &id_vpt, &FR_SBUFF_IN(id_vb->vb_strvalue, id_vb->vb_length),
                                      NULL,
                                      &(tmpl_rules_t){
                                                .dict_def = request->dict,
@@ -386,17 +329,10 @@ static ssize_t aka_sim_3gpp_pseudonym_encrypt_xlat(TALLOC_CTX *ctx, char **out,
                RPEDEBUG("Invalid ID attribute reference");
        error:
                talloc_free(our_ctx);
-               return -1;
-       }
-
-       p += slen;
-       if (*p != ' ') {
-               REDEBUG2("Missing key argument");
-               goto error;
+               return XLAT_ACTION_FAIL;
        }
-       p++;
 
-       slen = tmpl_afrom_attr_substr(our_ctx, NULL, &key_vpt, &FR_SBUFF_IN(p, strlen(p)),
+       slen = tmpl_afrom_attr_substr(our_ctx, NULL, &key_vpt, &FR_SBUFF_IN(attr_vb->vb_strvalue, attr_vb->vb_length),
                                      NULL,
                                      &(tmpl_rules_t){
                                                .dict_def = request->dict,
@@ -406,18 +342,11 @@ static ssize_t aka_sim_3gpp_pseudonym_encrypt_xlat(TALLOC_CTX *ctx, char **out,
                RPEDEBUG("Invalid key attribute reference");
                goto error;
        }
-       p += slen;
-
-       if (*p != ' ') {
-               REDEBUG2("Missing key index");
-               goto error;
-       }
-       p++;
 
        /*
         *      Get the key index
         */
-       key_index = strtoul(p, NULL, 10);
+       key_index = index_vb->vb_uint8;
        if (key_index > 15) {
                REDEBUG2("Key index must be between 0-15");
                goto error;
@@ -487,7 +416,7 @@ static ssize_t aka_sim_3gpp_pseudonym_encrypt_xlat(TALLOC_CTX *ctx, char **out,
        } else if ((id_len >= AKA_SIM_IMSI_MIN_LEN) && (id_len <= AKA_SIM_IMSI_MAX_LEN)) {
                fr_pair_t *eap_type;
 
-               eap_type = fr_pair_find_by_da(&request->request_pairs, attr_eap_type);
+               eap_type = fr_pair_find_by_da(&request->control_pairs, attr_eap_type);
                if (!eap_type) {
                        REDEBUG("SIM ID does not contain method hint, and no &control.EAP-Type found.  "
                                "Don't know what tag to prepend to encrypted identity");
@@ -520,30 +449,47 @@ static ssize_t aka_sim_3gpp_pseudonym_encrypt_xlat(TALLOC_CTX *ctx, char **out,
         */
        if (fr_aka_sim_id_3gpp_pseudonym_encrypt(encrypted, id_p, id_end - id_p, tag, (uint8_t)key_index, key) < 0) {
                RPEDEBUG2("Failed encrypting SIM ID \"%pV\"", fr_box_strvalue_len(id, id_len));
-               return -1;
+               return XLAT_ACTION_FAIL;
        }
 
-       MEM(*out = talloc_typed_asprintf(ctx, "%s", encrypted));
+       MEM(vb = fr_value_box_alloc(ctx, FR_TYPE_STRING, NULL, false));
+       fr_value_box_bstrndup(ctx, vb, NULL, encrypted, strlen(encrypted), false);
+       fr_dcursor_append(out, vb);
        talloc_free(our_ctx);
 
-       return talloc_array_length(*out) - 1;
+       return XLAT_ACTION_DONE;
 }
 
+extern xlat_arg_parser_t aka_sim_3gpp_pseudonym_encrypt_xlat_args[];
+xlat_arg_parser_t aka_sim_3gpp_pseudonym_encrypt_xlat_args[] = {
+       { .required = true, .concat = true, .single = false, .variadic = false, .type = FR_TYPE_STRING,
+         .func = NULL, .uctx = NULL },
+       { .required = true, .concat = true, .single = false, .variadic = false, .type = FR_TYPE_STRING,
+         .func = NULL, .uctx = NULL },
+       { .required = true, .concat = false, .single = true, .variadic = false, .type = FR_TYPE_UINT8,
+         .func = NULL, .uctx = NULL },
+       XLAT_ARG_PARSER_TERMINATOR
+};
+
 void fr_aka_sim_xlat_register(void)
 {
+       xlat_t  *xlat;
+
        if (aka_sim_xlat_refs) {
                aka_sim_xlat_refs++;
                return;
        }
 
-       xlat_register_legacy(NULL, "aka_sim_id_method", aka_sim_xlat_id_method_xlat, NULL, NULL, 0, 0);
-       xlat_register_legacy(NULL, "aka_sim_id_type", aka_sim_xlat_id_type_xlat, NULL, NULL, 0, 0);
-       xlat_register_legacy(NULL, "3gpp_pseudonym_key_index",
-                     aka_sim_3gpp_pseudonym_key_index_xlat, NULL, NULL, 0, 0);
-       xlat_register_legacy(NULL, "3gpp_pseudonym_decrypt",
-                     aka_sim_3gpp_pseudonym_decrypt_xlat, NULL, NULL, 0, 0);
-       xlat_register_legacy(NULL, "3gpp_pseudonym_encrypt",
-                     aka_sim_3gpp_pseudonym_encrypt_xlat, NULL, NULL, 0, 0);
+       xlat = xlat_register(NULL, "aka_sim_id_method", aka_sim_xlat_id_method_xlat, false);
+       xlat_func_args(xlat, aka_sim_xlat_id_method_xlat_args);
+       xlat = xlat_register(NULL, "aka_sim_id_type", aka_sim_xlat_id_type_xlat, false);
+       xlat_func_args(xlat, aka_sim_xlat_id_type_xlat_args);
+       xlat = xlat_register(NULL, "3gpp_pseudonym_key_index", aka_sim_id_3gpp_pseudonym_key_index_xlat, false);
+       xlat_func_args(xlat, aka_sim_id_3gpp_pseudonym_key_index_xlat_args);
+       xlat = xlat_register(NULL, "3gpp_pseudonym_decrypt", aka_sim_3gpp_pseudonym_decrypt_xlat, false);
+       xlat_func_args(xlat, aka_sim_3gpp_pseudonym_decrypt_xlat_args);
+       xlat = xlat_register(NULL, "3gpp_pseudonym_encrypt", aka_sim_3gpp_pseudonym_encrypt_xlat, false);
+       xlat_func_args(xlat, aka_sim_3gpp_pseudonym_encrypt_xlat_args);
        aka_sim_xlat_refs = 1;
 }
 
diff --git a/src/tests/modules/eap_aka_sim/sim_xlat_id_sim.unlang b/src/tests/modules/eap_aka_sim/sim_xlat_id_sim.unlang
deleted file mode 100644 (file)
index 384a432..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-if ("%{aka_sim_id_method:User-Name}" != 'SIM') {
-       test_fail
-} else {
-       test_pass
-}
-
-if ("%{aka_sim_id_type:User-Name}" != 'Permanent') {
-       test_fail
-} else {
-       test_pass
-}
-
-#
-#  Encrypt the permanent ID
-#
-update control {
-       &Tmp-String-0 := '1234567812345678'
-}
-update control {
-       &User-Name := "%{3gpp_pseudonym_encrypt:User-Name control.Tmp-String-0 6}"
-}
-
-#
-#  Can we get the EAP method from the encrypted blob correctly?
-#
-if ("%{aka_sim_id_method:control.User-Name}" != 'SIM') {
-       test_fail
-} else {
-       test_pass
-}
-
-#
-#  Can we identify the encrypted blob correctly?
-#
-if ("%{aka_sim_id_type:control.User-Name}" != 'Pseudonym') {
-       test_fail
-} else {
-       test_pass
-}
-
-#
-#  We should refuse to re-encrypt an encrypted NAI
-#
-if ("%{3gpp_pseudonym_encrypt:control.User-Name &control.Tmp-String-0 6}" != '') {
-       test_fail
-} else {
-       test_pass
-}
similarity index 52%
rename from src/tests/modules/eap_aka_sim/sim_xlat_id_aka.unlang
rename to src/tests/modules/eap_sim/sim_xlat_id_aka.unlang
index de5ffcd14c27b98bdec1093f2f79cdd066222998..fdd0a1c00c003f09ebc317d26142af27006ab14a 100644 (file)
@@ -1,13 +1,9 @@
-if ("%{aka_sim_id_method:User-Name}" != 'AKA') {
+if ("%(aka_sim_id_method:%{User-Name})" != 'AKA') {
        test_fail
-} else {
-       test_pass
 }
 
-if ("%{aka_sim_id_type:User-Name}" != 'Permanent') {
+if ("%(aka_sim_id_type:%{User-Name})" != 'Permanent') {
        test_fail
-} else {
-       test_pass
 }
 
 #
@@ -17,47 +13,39 @@ update control {
        &Tmp-String-0 := '1420032219455258'
 }
 update control {
-       &User-Name := "%{3gpp_pseudonym_encrypt:&User-Name &control.Tmp-String-0 6}"
+       &User-Name := "%(3gpp_pseudonym_encrypt:&User-Name &control.Tmp-String-0 6)"
 }
 
 #
 #  0.2 - Can we get the EAP method from the encrypted blob correctly?
 #
-if ("%{aka_sim_id_method:control.User-Name}" != 'AKA') {
+if ("%(aka_sim_id_method:%{control.User-Name})" != 'AKA') {
        test_fail
-} else {
-       test_pass
 }
 
 #
 #  0.3 - Can we identify the encrypted blob correctly?
 #
-if ("%{aka_sim_id_type:control.User-Name}" != 'Pseudonym') {
+if ("%(aka_sim_id_type:%{control.User-Name})" != 'Pseudonym') {
        test_fail
-} else {
-       test_pass
 }
 
 #
 #  0.4 - We should refuse to re-encrypt an encrypted NAI
 #
-if ("%{3gpp_pseudonym_encrypt:&control.User-Name &control.Tmp-String-0 6}" != '') {
+if ("%(3gpp_pseudonym_encrypt:&control.User-Name &control.Tmp-String-0 6)" != '') {
        test_fail
-} else {
-       test_pass
 }
 
 #
 #  0.5 - Get the original IMSI back again
 #
 update control {
-       &Tmp-String-1 := "%{3gpp_pseudonym_decrypt:&control.User-Name &control.Tmp-String-0}"
+       &Tmp-String-1 := "%(3gpp_pseudonym_decrypt:&control.User-Name &control.Tmp-String-0)"
 }
 
 if (&control.Tmp-String-1 != &User-Name) {
        test_fail
-} else {
-       test_pass
 }
 
 #
@@ -79,36 +67,32 @@ update control {
        &Tmp-String-0 := '1420032219455259'
 }
 update control {
-       &User-Name[1] := "%{3gpp_pseudonym_encrypt:&User-Name[1] &control.Tmp-String-0 6}"
+       &User-Name[1] := "%(3gpp_pseudonym_encrypt:&User-Name[1] &control.Tmp-String-0 6)"
 }
 
 #
 #  1.2 - Can we identify the encrypted blob correctly?
 #
-if ("%{aka_sim_id_type:&control.User-Name[1]}" != 'Pseudonym') {
+if ("%(aka_sim_id_type:%{control.User-Name[1]})" != 'Pseudonym') {
        test_fail
-} else {
-       test_pass
 }
 
 #
 #  1.3 - We should refuse to re-encrypt an encrypted NAI
 #
-if ("%{3gpp_pseudonym_encrypt:&control.User-Name[1] &control.Tmp-String-0 6}" != '') {
+if ("%(3gpp_pseudonym_encrypt:&control.User-Name[1] &control.Tmp-String-0 6)" != '') {
        test_fail
-} else {
-       test_pass
 }
 
 #
 #  1.4 - Get the original IMSI back again
 #
 update control {
-       &Tmp-String-1 := "%{3gpp_pseudonym_decrypt:&control.User-Name[1] &control.Tmp-String-0}"
+       &Tmp-String-1 := "%(3gpp_pseudonym_decrypt:&control.User-Name[1] &control.Tmp-String-0)"
 }
 
 if (&control.Tmp-String-1 != "0%{User-Name[1]}") {
        test_fail
-} else {
-       test_pass
 }
+
+test_pass
similarity index 56%
rename from src/tests/modules/eap_aka_sim/sim_xlat_id_error.unlang
rename to src/tests/modules/eap_sim/sim_xlat_id_error.unlang
index 45caa5e3db64787da0c991a15dfc8e13e6fcc944..e010ae90bab47c6d3cfaebb8ea109b7b1a4a46e3 100644 (file)
@@ -5,10 +5,8 @@ update request {
        &User-Name := '14200322194552581'
 }
 
-if ("%{aka_sim_id_method:User-Name}" != '') {
+if ("%(aka_sim_id_method:%{User-Name})" != '') {
        test_fail
-} else {
-       test_pass
 }
 
 #
@@ -18,8 +16,8 @@ update request {
        &User-Name := ''
 }
 
-if ("%{aka_sim_id_method:User-Name}" != '') {
+if ("%(aka_sim_id_method:%{User-Name})" != '') {
        test_fail
-} else {
-       test_pass
 }
+
+test_pass
diff --git a/src/tests/modules/eap_sim/sim_xlat_id_sim.unlang b/src/tests/modules/eap_sim/sim_xlat_id_sim.unlang
new file mode 100644 (file)
index 0000000..d875d9a
--- /dev/null
@@ -0,0 +1,40 @@
+if ("%(aka_sim_id_method:%{User-Name})" != 'SIM') {
+       test_fail
+}
+
+if ("%(aka_sim_id_type:%{User-Name})" != 'Permanent') {
+       test_fail
+}
+
+#
+#  Encrypt the permanent ID
+#
+update control {
+       &Tmp-String-0 := '1234567812345678'
+}
+update control {
+       &User-Name := "%(3gpp_pseudonym_encrypt:User-Name control.Tmp-String-0 6)"
+}
+
+#
+#  Can we get the EAP method from the encrypted blob correctly?
+#
+if ("%(aka_sim_id_method:%{control.User-Name})" != 'SIM') {
+       test_fail
+}
+
+#
+#  Can we identify the encrypted blob correctly?
+#
+if ("%(aka_sim_id_type:%{control.User-Name})" != 'Pseudonym') {
+       test_fail
+}
+
+#
+#  We should refuse to re-encrypt an encrypted NAI
+#
+if ("%(3gpp_pseudonym_encrypt:control.User-Name &control.Tmp-String-0 6)" != '') {
+       test_fail
+}
+
+test_pass