*
* Example: "%{md5:foo}" == "acbd18db4cc2f85cedef654fccc4a4d8"
*/
-static ssize_t md5_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_md5(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 digest[16];
- size_t i, len, inlen;
- uint8_t *p;
+ uint8_t digest[MD5_DIGEST_LENGTH];
FR_MD5_CTX md5_ctx;
- TALLOC_CTX *tmp_ctx = NULL;
+ fr_value_box_t *vb;
- VALUE_FROM_FMT(tmp_ctx, p, inlen, request, fmt);
+ /*
+ * Concatenate all input if there is some
+ */
+ if (*in && fr_value_box_list_concat(ctx, *in, in, FR_TYPE_OCTETS, true) < 0) {
+ RPEDEBUG("Failed concatenating input");
+ return XLAT_ACTION_FAIL;
+ }
fr_md5_init(&md5_ctx);
- fr_md5_update(&md5_ctx, p, inlen);
+ if (*in) {
+ fr_md5_update(&md5_ctx, (*in)->vb_octets, (*in)->vb_length);
+ } else {
+ /* MD5 of empty string */
+ fr_md5_update(&md5_ctx, NULL, 0);
+ }
fr_md5_final(digest, &md5_ctx);
- /*
- * Each digest octet takes two hex digits, plus one for
- * the terminating NUL.
- */
- len = (outlen / 2) - 1;
- if (len > 16) len = 16;
-
- for (i = 0; i < len; i++) snprintf((*out) + (i * 2), 3, "%02x", digest[i]);
+ MEM(vb = fr_value_box_alloc_null(ctx));
+ fr_value_box_memdup(vb, vb, NULL, digest, sizeof(digest), false);
- talloc_free(tmp_ctx);
+ fr_cursor_append(out, vb);
- return strlen(*out);
+ return XLAT_ACTION_DONE;
}
/** Calculate the SHA1 hash of a string or attribute.
xlat_register(NULL, "urlunquote", urlunquote_xlat, NULL, NULL, 0, XLAT_DEFAULT_BUF_LEN, true);
xlat_register(NULL, "tolower", tolower_xlat, NULL, NULL, 0, XLAT_DEFAULT_BUF_LEN, true);
xlat_register(NULL, "toupper", toupper_xlat, NULL, NULL, 0, XLAT_DEFAULT_BUF_LEN, true);
- xlat_register(NULL, "md5", md5_xlat, NULL, NULL, 0, XLAT_DEFAULT_BUF_LEN, true);
xlat_register(NULL, "sha1", sha1_xlat, NULL, NULL, 0, XLAT_DEFAULT_BUF_LEN, true);
#ifdef HAVE_OPENSSL_EVP_H
xlat_register(NULL, "sha224", sha224_xlat, NULL, NULL, 0, XLAT_DEFAULT_BUF_LEN, true);
xlat_async_register(NULL, "base64", xlat_base64, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
xlat_async_register(NULL, "concat", xlat_concat, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
xlat_async_register(NULL, "bin", xlat_bin, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+ xlat_async_register(NULL, "md5", xlat_md5, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
return 0;
}
request:Tmp-String-2 := "Jefe"
}
+
+update request {
+ &Tmp-Octets-3 := "%{md5:This is a string\n}"
+ &Tmp-Octets-4 := "%{md5:%{Tmp-String-0}}"
+ &Tmp-Octets-5 := "%{md5:%{request:Tmp-String-0}}"
+ &Tmp-Octets-6 := "%{md5:%{request:Tmp-Octets-0}}"
+ &Tmp-Octets-7 := "%{md5:%{Tmp-String-9}}"
+}
+
#
# Put "This is a string" into a file and call "md5sum" on it.
# You should get this string.
#
-if ("%{md5:This is a string\n}" != '9ac4dbbc3c0ad2429e61d0df5dc28add') {
+if (&Tmp-Octets-3 != 0x9ac4dbbc3c0ad2429e61d0df5dc28add) {
test_fail
}
-if ("%{md5:&Tmp-String-0}" != '9ac4dbbc3c0ad2429e61d0df5dc28add') {
+if (&Tmp-Octets-4 != 0x9ac4dbbc3c0ad2429e61d0df5dc28add) {
test_fail
}
-if ("%{md5:&request:Tmp-String-0}" != '9ac4dbbc3c0ad2429e61d0df5dc28add') {
+if (&Tmp-Octets-5 != 0x9ac4dbbc3c0ad2429e61d0df5dc28add) {
test_fail
}
-if ("%{md5:%{request:Tmp-String-0}}" != '9ac4dbbc3c0ad2429e61d0df5dc28add') {
+#
+# MD5 should also be able to cope with references to octet attributes
+#
+if (&Tmp-Octets-6 != 0xc1e7fa505b2fc1fd0da6cac3db6f6f44) {
test_fail
}
#
-# MD5 should also be able to cope with references to octet attributes
+# MD5 of null string is d41d8cd98f00b204e9800998ecf8427e
#
-if ("%{md5:&request:Tmp-Octets-0}" != 'c1e7fa505b2fc1fd0da6cac3db6f6f44') {
+if (&Tmp-Octets-7 != 0xd41d8cd98f00b204e9800998ecf8427e) {
test_fail
}