From: Philippe Wooding Date: Fri, 7 Dec 2018 13:50:40 +0000 (+0100) Subject: Replace base64tohex with base64decode using new async API X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8114ac2db1260aa75b1899bd3ffb902f8a3c4caf;p=thirdparty%2Ffreeradius-server.git Replace base64tohex with base64decode using new async API --- diff --git a/src/lib/server/xlat_func.c b/src/lib/server/xlat_func.c index 503d92a3a2d..6e8a70c0d25 100644 --- a/src/lib/server/xlat_func.c +++ b/src/lib/server/xlat_func.c @@ -1439,32 +1439,48 @@ static xlat_action_t base64_xlat(TALLOC_CTX *ctx, fr_cursor_t *out, return XLAT_ACTION_DONE; } -/** Convert base64 to hex +/** Decode base64 string * - * Example: "%{base64tohex:Zm9v}" == "666f6f" + * Example: "%{base64decode:Zm9v}" == "foo" */ -static ssize_t base64_to_hex_xlat(UNUSED TALLOC_CTX *ctx, char **out, size_t outlen, - UNUSED void const *mod_inst, UNUSED void const *xlat_inst, - REQUEST *request, char const *fmt) +static xlat_action_t xlat_base64_decode(TALLOC_CTX *ctx, fr_cursor_t *out, + REQUEST *request, UNUSED void const *xlat_inst, UNUSED void *xlat_thread_inst, + fr_value_box_t **in) { - uint8_t decbuf[1024]; + size_t alen; + ssize_t declen; + uint8_t *decbuf; + fr_value_box_t *vb; + + /* + * If there's no input, there's no output + */ + if (!in) return XLAT_ACTION_DONE; + + if (fr_value_box_list_concat(ctx, *in, in, FR_TYPE_OCTETS, true) < 0) { + RPEDEBUG("Failed concatenating input"); + return XLAT_ACTION_FAIL; + } + + alen = FR_BASE64_DEC_LENGTH((*in)->vb_length); - ssize_t declen; - ssize_t len = strlen(fmt); + MEM(decbuf = talloc_array(ctx, uint8_t, alen)); - declen = fr_base64_decode(decbuf, sizeof(decbuf), fmt, len); + declen = fr_base64_decode(decbuf, alen, (*in)->vb_strvalue, (*in)->vb_length); if (declen < 0) { + talloc_free(decbuf); REDEBUG("Base64 string invalid"); - return -1; + return XLAT_ACTION_FAIL; } - if ((size_t)((declen * 2) + 1) > outlen) { - REDEBUG("Base64 conversion failed, output buffer exhausted, needed %zd bytes, have %zd bytes", - (declen * 2) + 1, outlen); - return -1; - } + MEM(vb = fr_value_box_alloc_null(ctx)); + + fr_value_box_memdup(vb, vb, NULL, decbuf, declen, false); + talloc_free(decbuf); - return fr_bin2hex(*out, decbuf, declen); + fr_cursor_append(out, vb); + + return XLAT_ACTION_DONE; } /** Split an attribute into multiple new attributes based on a delimiter @@ -2523,7 +2539,6 @@ int xlat_init(void) xlat_register(NULL, "pairs", pairs_xlat, NULL, NULL, 0, XLAT_DEFAULT_BUF_LEN, true); - xlat_register(NULL, "base64tohex", base64_to_hex_xlat, NULL, NULL, 0, XLAT_DEFAULT_BUF_LEN, true); xlat_register(NULL, "explode", explode_xlat, NULL, NULL, 0, XLAT_DEFAULT_BUF_LEN, true); @@ -2537,6 +2552,7 @@ int xlat_init(void) c->internal = true; xlat_async_register(NULL, "base64", base64_xlat, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + xlat_async_register(NULL, "base64decode", xlat_base64_decode, NULL, NULL, NULL, NULL, NULL, NULL, NULL); xlat_async_register(NULL, "bin", bin_xlat, NULL, NULL, NULL, NULL, NULL, NULL, NULL); xlat_async_register(NULL, "concat", concat_xlat, NULL, NULL, NULL, NULL, NULL, NULL, NULL); xlat_async_register(NULL, "hex", hex_xlat, NULL, NULL, NULL, NULL, NULL, NULL, NULL); diff --git a/src/tests/keywords/base64 b/src/tests/keywords/base64 index 5ca090c28a1..8cb1284be07 100644 --- a/src/tests/keywords/base64 +++ b/src/tests/keywords/base64 @@ -108,4 +108,17 @@ if (&Tmp-String-3[0] != 'IDk4Nz4=') { test_fail } +update request { + &Tmp-Octets-0 := "%{base64decode:Zm9v}" + &Tmp-Octets-1 := "%{base64decode:AIAAAAAAAAAAAAAAAAA5ODc5}" +} + +if (&Tmp-Octets-0 != "foo") { + test_fail +} + +if (&Tmp-Octets-1 != 0x008000000000000000000000000039383739) { + test_fail +} + success