From: Arran Cudbard-Bell Date: Thu, 20 Sep 2012 12:55:08 +0000 (+0100) Subject: Move string manipulation functions from xlat.c to rlm_expr X-Git-Tag: release_3_0_0_beta1~1694 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=89b127940b425e5e3d16d0104885a50abf3dc344;p=thirdparty%2Ffreeradius-server.git Move string manipulation functions from xlat.c to rlm_expr --- diff --git a/src/main/xlat.c b/src/main/xlat.c index 1c8c9a5ec58..1df05dd1f10 100644 --- a/src/main/xlat.c +++ b/src/main/xlat.c @@ -26,7 +26,6 @@ RCSID("$Id$") #include -#include #include #include @@ -690,155 +689,6 @@ static size_t xlat_debug(UNUSED void *instance, REQUEST *request, return strlen(out); } - -/** - * @brief Calculate the MD5 hash of a string. - * - * Example: "%{md5:foo}" == "acbd18db4cc2f85cedef654fccc4a4d8" - */ -static size_t xlat_md5(UNUSED void *instance, REQUEST *request, - const char *fmt, char *out, size_t outlen, - UNUSED RADIUS_ESCAPE_STRING func) -{ - int i; - uint8_t digest[16]; - FR_MD5_CTX ctx; - char buffer[1024]; - - if (!radius_xlat(buffer, sizeof(buffer), fmt, request, func)) { - *out = '\0'; - return 0; - } - - fr_MD5Init(&ctx); - fr_MD5Update(&ctx, (void *) buffer, strlen(buffer)); - fr_MD5Final(digest, &ctx); - - if (outlen < 33) { - snprintf(out, outlen, "md5_overflow"); - return strlen(out); - } - - for (i = 0; i < 16; i++) { - snprintf(out + i * 2, 3, "%02x", digest[i]); - } - - return strlen(out); -} - - -/** - * @brief Convert a string to lowercase - * - * Example "%{lc:Bar}" == "bar" - * - * Probably only works for ASCII - */ -static size_t xlat_lc(UNUSED void *instance, REQUEST *request, - const char *fmt, char *out, size_t outlen, - UNUSED RADIUS_ESCAPE_STRING func) -{ - char *p, *q; - char buffer[1024]; - - if (outlen <= 1) return 0; - - if (!radius_xlat(buffer, sizeof(buffer), fmt, request, func)) { - *out = '\0'; - return 0; - } - - for (p = buffer, q = out; *p != '\0'; p++, outlen--) { - if (outlen <= 1) break; - - *(q++) = tolower((int) *p); - } - - *q = '\0'; - - return strlen(out); -} - -static size_t xlat_urlquote(UNUSED void *instance, REQUEST *request, - const char *fmt, char *out, size_t outlen, - UNUSED RADIUS_ESCAPE_STRING func) -{ - char *in, *o; - char buffer[1024]; - - if (outlen <= 1) return 0; - - if (!radius_xlat(buffer, sizeof(buffer), fmt, request, func)) { - *out = '\0'; - return 0; - } - - in = buffer; - o = out; - - while (*in && outlen > 1) { - if (isalnum(*in)) { - *o++ = *in++; - outlen--; - continue; - } - - switch (*in) { - case '-': - case '_': - case '.': - case '~': - *o++ = *in++; - outlen--; - break; - default: - if (outlen <= 3) - break; - snprintf(o, 4, "%%%02x", *in++); - outlen -= 3; - o += 3; - } - } - - *o = '\0'; - - return strlen(out); -} - - -/** - * @brief Convert a string to uppercase - * - * Example: "%{uc:Foo}" == "FOO" - * - * Probably only works for ASCII - */ -static size_t xlat_uc(UNUSED void *instance, REQUEST *request, - const char *fmt, char *out, size_t outlen, - UNUSED RADIUS_ESCAPE_STRING func) -{ - char *p, *q; - char buffer[1024]; - - if (outlen <= 1) return 0; - - if (!radius_xlat(buffer, sizeof(buffer), fmt, request, func)) { - *out = '\0'; - return 0; - } - - for (p = buffer, q = out; *p != '\0'; p++, outlen--) { - if (outlen <= 1) break; - - *(q++) = toupper((int) *p); - } - - *q = '\0'; - - return strlen(out); -} - - /* * Compare two xlat_t structs, based ONLY on the module name. */ @@ -939,7 +789,6 @@ int xlat_register(const char *module, RAD_XLAT_FUNC func, void *instance) XLAT_REGISTER(hex); XLAT_REGISTER(string); XLAT_REGISTER(module); - XLAT_REGISTER(urlquote); #ifdef HAVE_REGEX_H /* @@ -960,21 +809,6 @@ int xlat_register(const char *module, RAD_XLAT_FUNC func, void *instance) c = xlat_find("debug"); rad_assert(c != NULL); c->internal = TRUE; - - xlat_register("md5", xlat_md5, &xlat_inst[0]); - c = xlat_find("md5"); - rad_assert(c != NULL); - c->internal = TRUE; - - xlat_register("tolower", xlat_lc, &xlat_inst[0]); - c = xlat_find("tolower"); - rad_assert(c != NULL); - c->internal = TRUE; - - xlat_register("toupper", xlat_uc, &xlat_inst[0]); - c = xlat_find("toupper"); - rad_assert(c != NULL); - c->internal = TRUE; } /* diff --git a/src/modules/rlm_expr/rlm_expr.c b/src/modules/rlm_expr/rlm_expr.c index 599f63b5120..27f0add8c6d 100644 --- a/src/modules/rlm_expr/rlm_expr.c +++ b/src/modules/rlm_expr/rlm_expr.c @@ -25,7 +25,11 @@ RCSID("$Id$") #include +#include #include + +#include + #include "rlm_expr.h" /* @@ -408,6 +412,159 @@ static size_t randstr_xlat(UNUSED void *instance, REQUEST *request, return outlen - freespace; } +/** + * @brief URLencode special characters + * + * Example: "%{urlquote:http://example.org/}" == "http%3A%47%47example.org%47" + */ +static size_t urlquote_xlat(UNUSED void *instance, REQUEST *request, + const char *fmt, char *out, size_t outlen, + UNUSED RADIUS_ESCAPE_STRING func) +{ + char *p; + char buffer[1024]; + size_t freespace = outlen; + size_t len; + + if (outlen <= 1) return 0; + + len = radius_xlat(buffer, sizeof(buffer), fmt, request, func); + if (!len) { + radlog(L_ERR, "rlm_expr: xlat failed."); + *out = '\0'; + return 0; + } + + p = buffer; + while ((len-- > 0) && (--freespace > 0)) { + if (isalnum(*p)) { + *out++ = *p++; + continue; + } + + switch (*p) { + case '-': + case '_': + case '.': + case '~': + *out++ = *p++; + break; + default: + if (freespace < 3) + break; + + snprintf(out, 4, "%%%02x", *p++); /* %xx */ + + /* Already decremented */ + freespace -= 2; + out += 3; + } + } + + *out = '\0'; + + return outlen - freespace; +} + +/** + * @brief Convert a string to lowercase + * + * Example "%{lc:Bar}" == "bar" + * + * Probably only works for ASCII + */ +static size_t lc_xlat(UNUSED void *instance, REQUEST *request, + const char *fmt, char *out, size_t outlen, + UNUSED RADIUS_ESCAPE_STRING func) +{ + char *p, *q; + char buffer[1024]; + + if (outlen <= 1) return 0; + + if (!radius_xlat(buffer, sizeof(buffer), fmt, request, func)) { + *out = '\0'; + return 0; + } + + for (p = buffer, q = out; *p != '\0'; p++, outlen--) { + if (outlen <= 1) break; + + *(q++) = tolower((int) *p); + } + + *q = '\0'; + + return strlen(out); +} + +/** + * @brief Convert a string to uppercase + * + * Example: "%{uc:Foo}" == "FOO" + * + * Probably only works for ASCII + */ +static size_t uc_xlat(UNUSED void *instance, REQUEST *request, + const char *fmt, char *out, size_t outlen, + UNUSED RADIUS_ESCAPE_STRING func) +{ + char *p, *q; + char buffer[1024]; + + if (outlen <= 1) return 0; + + if (!radius_xlat(buffer, sizeof(buffer), fmt, request, func)) { + *out = '\0'; + return 0; + } + + for (p = buffer, q = out; *p != '\0'; p++, outlen--) { + if (outlen <= 1) break; + + *(q++) = toupper((int) *p); + } + + *q = '\0'; + + return strlen(out); +} + +/** + * @brief Calculate the MD5 hash of a string. + * + * Example: "%{md5:foo}" == "acbd18db4cc2f85cedef654fccc4a4d8" + */ +static size_t md5_xlat(UNUSED void *instance, REQUEST *request, + const char *fmt, char *out, size_t outlen, + UNUSED RADIUS_ESCAPE_STRING func) +{ + char buffer[1024]; + uint8_t digest[16]; + int i; + FR_MD5_CTX ctx; + + if (!radius_xlat(buffer, sizeof(buffer), fmt, request, func)) { + *out = '\0'; + return 0; + } + + fr_MD5Init(&ctx); + fr_MD5Update(&ctx, (void *) buffer, strlen(buffer)); + fr_MD5Final(digest, &ctx); + + if (outlen < 33) { + snprintf(out, outlen, "md5_overflow"); + return strlen(out); + } + + for (i = 0; i < 16; i++) { + snprintf(out + i * 2, 3, "%02x", digest[i]); + } + + return strlen(out); +} + /* * Do any per-module initialization that is separate to each * configured instance of the module. e.g. set up connections @@ -442,6 +599,10 @@ static int expr_instantiate(CONF_SECTION *conf, void **instance) xlat_register("rand", rand_xlat, inst); xlat_register("randstr", randstr_xlat, inst); + xlat_register("urlquote", urlquote_xlat, inst); + xlat_register("tolower", lc_xlat, inst); + xlat_register("toupper", uc_xlat, inst); + xlat_register("md5", md5_xlat, inst); /* * Initialize various paircompare functions