]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Convert hmacsha1 xlat to new async API
authorPhilippe Wooding <philippe.wooding@networkradius.com>
Tue, 4 Dec 2018 17:18:06 +0000 (18:18 +0100)
committerPhilippe Wooding <philippe.wooding@networkradius.com>
Tue, 4 Dec 2018 17:18:06 +0000 (18:18 +0100)
src/lib/server/xlat_func.c
src/tests/keywords/sha1

index dc22a0f69e63777b9fca144cafb010d913cea66c..e9efc89a5125912db0953aa9e3bff0bd7320d02c 100644 (file)
@@ -1118,84 +1118,6 @@ static xlat_action_t toupper_xlat(TALLOC_CTX *ctx, fr_cursor_t *out,
        return _xlat_change_case(true, ctx, out, request, in);
 }
 
-/** Decodes data or &Attr-Name to data
- *
- * This needs to die, and hopefully will die, when xlat functions accept
- * xlat node structures.
- *
- * @param ctx          Talloc ctx for temporary allocations.
- * @param out          fr_value_box_t containing a shallow copy of the attribute,
- *                     or the fmt string.
- * @param request      current request.
- * @param fmt          string.
- * @returns
- *     - The length of the data.
- *     - -1 on failure.
- */
-static int fr_value_box_from_fmt(TALLOC_CTX *ctx, fr_value_box_t *out, REQUEST *request, char const *fmt)
-{
-       VALUE_PAIR *vp;
-
-       while (isspace((int) *fmt)) fmt++;
-
-       /*
-        *      Not an attribute reference?  Just use the input format.
-        */
-       if (*fmt != '&') {
-               memset(out, 0, sizeof(*out));
-               out->vb_strvalue = fmt;
-               out->datum.length = talloc_array_length(fmt) - 1;
-               out->type = FR_TYPE_STRING;
-               return 0;
-       }
-
-       /*
-        *      If it's an attribute reference, get the underlying
-        *      attribute, and then store the data in network byte
-        *      order.
-        */
-       if ((xlat_fmt_get_vp(&vp, request, fmt) < 0) || !vp) return -1;
-
-       fr_value_box_copy(ctx, out, &vp->data);
-
-       return 0;
-}
-
-static int fr_value_box_to_bin(TALLOC_CTX *ctx, REQUEST *request, uint8_t **out, size_t *outlen, fr_value_box_t const *in)
-{
-       fr_value_box_t bin;
-
-       switch (in->type) {
-       case FR_TYPE_STRING:
-       case FR_TYPE_OCTETS:
-               memcpy(out, &in->datum.ptr, sizeof(in));
-               *outlen = in->datum.length;
-               return 0;
-
-       default:
-               if (fr_value_box_cast(ctx, &bin, FR_TYPE_OCTETS, NULL, in) < 0) {
-                       RPERROR("Failed casting xlat input to 'octets'");
-                       return -1;
-               }
-               memcpy(out, &bin.datum.ptr, sizeof(in));
-               *outlen = bin.datum.length;
-               return 0;
-       }
-}
-
-#define VALUE_FROM_FMT(_tmp_ctx, _p, _len, _request, _fmt) \
-       fr_value_box_t _value; \
-       if (!_tmp_ctx) MEM(_tmp_ctx = talloc_new(_request)); \
-       if (fr_value_box_from_fmt(_tmp_ctx, &_value, _request, _fmt) < 0) { \
-               talloc_free(_tmp_ctx); \
-               return -1; \
-       } \
-       if (fr_value_box_to_bin(_tmp_ctx, _request, &_p, &_len, &_value) < 0) { \
-               talloc_free(_tmp_ctx); \
-               return -1; \
-       }
-
-
 /** Calculate the MD5 hash of a string or attribute.
  *
  * Example: "%{md5:foo}" == "acbd18db4cc2f85cedef654fccc4a4d8"
@@ -1391,53 +1313,12 @@ static xlat_action_t hmac_md5_xlat(TALLOC_CTX *ctx, fr_cursor_t *out,
  *
  * Example: "%{hmacsha1:foo bar}" == "Zm9v"
  */
-static ssize_t hmac_sha1_xlat(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 hmac_sha1_xlat(TALLOC_CTX *ctx, fr_cursor_t *out,
+                                   REQUEST *request, void const *xlat_inst, void *xlat_thread_inst,
+                                   fr_value_box_t **in)
 {
-       char const      *p, *q;
        uint8_t         digest[SHA1_DIGEST_LENGTH];
-
-       char            *data_fmt;
-
-       uint8_t         *data_p, *key_p;
-       size_t          data_len, key_len;
-       TALLOC_CTX      *tmp_ctx = NULL;
-
-       if (outlen <= (sizeof(digest) * 2)) {
-               REDEBUG("Insufficient space to write digest, needed %zu bytes, have %zu bytes",
-                       (sizeof(digest) * 2) + 1, outlen);
-               return -1;
-       }
-
-       p = fmt;
-       while (isspace(*p)) p++;
-
-       /*
-        *      Find the delimiting char
-        */
-       q = strchr(p, ' ');
-       if (!q) {
-               REDEBUG("HMAC requires exactly two arguments (&data &key)");
-               return -1;
-       }
-
-       tmp_ctx = talloc_new(ctx);
-       data_fmt = talloc_bstrndup(tmp_ctx, p, q - p);
-       p = q + 1;
-
-       {
-               VALUE_FROM_FMT(tmp_ctx, data_p, data_len, request, data_fmt);
-       }
-       {
-               VALUE_FROM_FMT(tmp_ctx, key_p, key_len, request, p);
-       }
-
-       fr_hmac_sha1(digest, data_p, data_len, key_p, key_len);
-
-       talloc_free(tmp_ctx);
-
-       return fr_bin2hex(*out, digest, sizeof(digest));
+       return _xlat_hmac(ctx, out, request, xlat_inst, xlat_thread_inst, in, digest, SHA1_DIGEST_LENGTH, HMAC_SHA1);
 }
 
 /** Encode attributes as a series of string attribute/value pairs
@@ -2627,7 +2508,6 @@ int xlat_init(void)
        XLAT_REGISTER(module);
        XLAT_REGISTER(debug_attr);
 
-       xlat_register(NULL, "hmacsha1", hmac_sha1_xlat, NULL, NULL, 0, XLAT_DEFAULT_BUF_LEN, true);
        xlat_register(NULL, "pairs", pairs_xlat, NULL, NULL, 0, XLAT_DEFAULT_BUF_LEN, true);
 
 
@@ -2649,6 +2529,7 @@ int xlat_init(void)
        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);
        xlat_async_register(NULL, "hmacmd5", hmac_md5_xlat, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+       xlat_async_register(NULL, "hmacsha1", hmac_sha1_xlat, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
        xlat_async_register(NULL, "md5", md5_xlat, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
        xlat_async_register(NULL, "rand", rand_xlat, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
        xlat_async_register(NULL, "randstr", randstr_xlat, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
index 3c711b853393d8ffbf961105b337fcd565b4983d..eea61d7d3962fc32b312381c35e67fc49d887eea 100644 (file)
@@ -7,14 +7,17 @@ update {
        request:Tmp-Octets-0 := 0x000504030201
        request:Tmp-String-1 := "what do ya want for nothing?"
        request:Tmp-String-2 := "Jefe"
+       request:Tmp-String-3 := ""
 }
 
 update {
        request:Tmp-Octets-2 := "%{sha1:This is a string\n}"
        request:Tmp-Octets-3 := "%{sha1:%{Tmp-String-0}}"
        request:Tmp-Octets-4 := "%{sha1:%{request:Tmp-String-0}}"
-       request:Tmp-Octets-5 := "%{sha1:%{request:Tmp-Octets-0}}"
-       request:Tmp-Octets-6 := "%{sha1:%{request:Tmp-Octets-9}}"
+       request:Tmp-Octets-5 := "%{sha1:%{request:Tmp-Octets-9}}"
+       request:Tmp-Octets-6 := "%{hmacsha1:%{&Tmp-String-1} %{&Tmp-String-2}}"
+       request:Tmp-Octets-7 := "%{hmacsha1:%{&Tmp-String-3} %{&Tmp-String-3}}"
+       request:Tmp-Octets-8 := "%{hmacsha1:%{&Tmp-String-1} }"
 }
 
 #
@@ -34,23 +37,30 @@ if (&request:Tmp-Octets-4 != 0xcc7edf1ccc4bdf1e0ec8f72b95388b65218ecf0c) {
 }
 
 #
-#  SHA1 should also be able to cope with references to octet attributes
+# SHA1 of empty string
 #
-if (&request:Tmp-Octets-5 != 0x365b244645fe7294dff062174996572319d5a82c) {
+if (&request:Tmp-Octets-5 != 0xda39a3ee5e6b4b0d3255bfef95601890afd80709) {
        test_fail
 }
 
 #
-# SHA1 of empty string
+#  SHA1 HMAC with attribute references
 #
-if (&request:Tmp-Octets-6 != 0xda39a3ee5e6b4b0d3255bfef95601890afd80709) {
+if (&request:Tmp-Octets-6 != 0xeffcdf6ae5eb2fa2d27416d5f184df9c259a7c79) {
        test_fail
 }
 
 #
-#  SHA1 HMAC with attribute references
+#  MD5 HMAC with empty key and data
+#
+if (&Tmp-Octets-7 != 0xfbdb1d1b18aa6c08324b7d64b71fb76370690e1d) {
+       test_fail
+}
+
+#
+#  MD5 HMAC with missing key should fail
 #
-if ("%{hmacsha1:&Tmp-String-1 &Tmp-String-2}" != 'effcdf6ae5eb2fa2d27416d5f184df9c259a7c79') {
+if (&Tmp-Octets-8 != "") {
        test_fail
 }