From: Arran Cudbard-Bell Date: Thu, 21 May 2020 14:47:38 +0000 (-0500) Subject: xlat: Make %{pack:} work on boxes not attribute references X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f5c6f003eb7332da12f652a7cbd2c5be388e1ee1;p=thirdparty%2Ffreeradius-server.git xlat: Make %{pack:} work on boxes not attribute references --- diff --git a/doc/antora/modules/unlang/pages/xlat/builtin.adoc b/doc/antora/modules/unlang/pages/xlat/builtin.adoc index 2c1f561bfeb..4d86133f56c 100644 --- a/doc/antora/modules/unlang/pages/xlat/builtin.adoc +++ b/doc/antora/modules/unlang/pages/xlat/builtin.adoc @@ -889,11 +889,12 @@ update reply { You should wait for 2520s ``` -=== +%{pack: &Attribute-Name &Attribute-Name ...}+ +=== +%{pack:%{Attribute-Name}%{Attribute-Name}...}+ -Pack multiple multiple attributes into a binary string. For best -results, each attribute passed to `pack` should be fixed size. That -is, not data type `octets` or `string`. +Pack multiple multiple attributes and/or literals into a binary string. +For best results, each attribute passed to `pack` should be fixed size. +That is, not data type `octets` or `string` as the length of those values +will not be encoded. See also the `unpack` module, which is the inverse to `pack`. @@ -904,7 +905,7 @@ See also the `unpack` module, which is the inverse to `pack`. [source,unlang] ---- update reply { - &Class := "%{pack:&reply:Framed-IP-Address &NAS-IP-Address}" + &Class := "%{pack:%{reply:Framed-IP-Address}%{NAS-IP-Address}}" } ---- diff --git a/src/lib/unlang/xlat_builtin.c b/src/lib/unlang/xlat_builtin.c index 9399446b5c6..6d4250069d1 100644 --- a/src/lib/unlang/xlat_builtin.c +++ b/src/lib/unlang/xlat_builtin.c @@ -2082,7 +2082,7 @@ static xlat_action_t xlat_func_md5(TALLOC_CTX *ctx, fr_cursor_t *out, /** Prints the name of the current module processing the request * - * For example will expand to "echo" (not "exec") in + * For example will expand to "echo" (not "exec") in @verbatim exec echo { ... @@ -2126,7 +2126,7 @@ static xlat_action_t xlat_func_module(TALLOC_CTX *ctx, fr_cursor_t *out, * * Example: @verbatim -"%{pack:&Attr-Foo &Attr-bar}" == packed hex values of the attributes +"%{pack:%{Attr-Foo}%{Attr-bar}" == packed hex values of the attributes @endverbatim * * @ingroup xlat_functions @@ -2135,81 +2135,51 @@ static xlat_action_t xlat_func_pack(TALLOC_CTX *ctx, fr_cursor_t *out, REQUEST *request, UNUSED void const *xlat_inst, UNUSED void *xlat_thread_inst, fr_value_box_t **in) { - fr_value_box_t *vb; - VALUE_PAIR *vp; - fr_cursor_t *cursor; - char *buffer, *p, *next; + fr_value_box_t *vb, *in_vb; + fr_cursor_t cursor; if (!*in) { - REDEBUG("Missing attribute reference"); + REDEBUG("Missing input boxes"); return XLAT_ACTION_FAIL; } - /* - * Concatenate all input into a list of attribute references. - */ - if (fr_value_box_list_concat(ctx, *in, in, FR_TYPE_STRING, true) < 0) { - RPEDEBUG("Failed concatenating input"); - return XLAT_ACTION_FAIL; - } - - buffer = talloc_strdup(ctx, (*in)->vb_strvalue); + MEM(vb = fr_value_box_alloc(ctx, FR_TYPE_OCTETS, NULL, false)); /* - * Allocate the initial box + * Loop over the input boxes, packing them together. */ - MEM(vb = fr_value_box_alloc(ctx, FR_TYPE_OCTETS, NULL, false)); - for (p = buffer; p != NULL; p = next) { - next = strchr(p, ' '); - if (next) { - while (isspace((int) *next)) { - *(next++) = '\0'; - } - } - - if (xlat_fmt_to_cursor(NULL, &cursor, NULL, request, p) < 0) { - fail: - talloc_free(buffer); - talloc_free(vb); - return XLAT_ACTION_FAIL; - } + for (in_vb = fr_cursor_init(&cursor, in); + in_vb; + in_vb = fr_cursor_next(&cursor)) { + fr_value_box_t *cast, box; - /* - * Loop over the input attributes, packing them together. - */ - for (vp = fr_cursor_head(cursor); - vp; - vp = fr_cursor_next(cursor)) { - fr_value_box_t *cast, box; - - if (vp->da->type != FR_TYPE_OCTETS) { - if (fr_value_box_cast(ctx, &box, FR_TYPE_OCTETS, NULL, &vp->data) < 0) goto fail2; - cast = &box; - } else { - cast = &vp->data; + if (in_vb->type != FR_TYPE_OCTETS) { + if (fr_value_box_cast(ctx, &box, FR_TYPE_OCTETS, NULL, in_vb) < 0) { + error: + talloc_free(vb); + RPEDEBUG("Failed packing value"); + return XLAT_ACTION_FAIL; } + cast = &box; + } else { + cast = in_vb; + } - if (vb->datum.length == 0) { - (void) fr_value_box_memcpy(vb, vb, NULL, cast->vb_octets, cast->datum.length, cast->tainted); + if (vb->vb_length == 0) { + (void) fr_value_box_memcpy(vb, vb, NULL, cast->vb_octets, cast->vb_length, cast->tainted); - } else if (fr_value_box_append_mem(vb, cast->vb_octets, cast->datum.length, cast->tainted) < 0) { - fail2: - talloc_free(cursor); - goto fail; - } - - fr_assert(vb->vb_octets != NULL); + } else if (fr_value_box_append_mem(vb, cast->vb_octets, cast->vb_length, cast->tainted) < 0) { + goto error; } - talloc_free(cursor); + + fr_assert(vb->vb_octets != NULL); } - talloc_free(buffer); fr_cursor_append(out, vb); return XLAT_ACTION_DONE; } - /** Encode attributes as a series of string attribute/value pairs * * This is intended to serialize one or more attributes as a comma