]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Move the escape expansions into their own module
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Wed, 16 May 2018 05:20:37 +0000 (11:20 +0600)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Wed, 16 May 2018 05:20:37 +0000 (11:20 +0600)
raddb/all.mk
raddb/mods-available/escape [new file with mode: 0644]
src/modules/rlm_escape/README.md [new file with mode: 0644]
src/modules/rlm_escape/all.mk [new file with mode: 0644]
src/modules/rlm_escape/rlm_escape.c [new file with mode: 0644]
src/modules/rlm_expr/rlm_expr.c
src/tests/keywords/unit_test_module.conf

index 2c64245dfe9ed9a1a2239a24f0a7d69ad504c6c0..a1b79df2e68308e5818980048a206a89cf17a786 100644 (file)
@@ -9,7 +9,7 @@ LOCAL_SITES :=          $(addprefix raddb/sites-enabled/,$(DEFAULT_SITES))
 
 DEFAULT_MODULES :=     always attr_filter cache_eap chap client \
                        detail detail.log digest dhcpv4 eap \
-                       eap_inner echo exec expiration expr files linelog logintime \
+                       eap_inner echo escape exec expiration expr files linelog logintime \
                        mschap ntlm_auth pam pap passwd radius radutmp \
                        soh sradutmp stats unix unpack utf8
 
diff --git a/raddb/mods-available/escape b/raddb/mods-available/escape
new file mode 100644 (file)
index 0000000..e78d0b5
--- /dev/null
@@ -0,0 +1,12 @@
+# -*- text -*-
+#
+#  $Id$
+
+#
+#  This module registers two xlat functions
+#  - <module inst>     Replaces characters not in the safe_characters list with escaped versions
+#  - un<module inst>   Replaces escape sequences with the original character.
+#
+escape {
+       safe_characters = "@abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-_: /äéöüàâæçèéêëîïôœùûüaÿÄÉÖÜßÀÂÆÇÈÉÊËÎÏÔŒÙÛÜŸ"
+}
diff --git a/src/modules/rlm_escape/README.md b/src/modules/rlm_escape/README.md
new file mode 100644 (file)
index 0000000..5b3ee82
--- /dev/null
@@ -0,0 +1,8 @@
+# rlm_escape
+## Metadata
+<dl>
+  <dt>category</dt><dd>policy</dd>
+</dl>
+
+## Summary
+Escapes and unescapes strings using the MIME escape format
diff --git a/src/modules/rlm_escape/all.mk b/src/modules/rlm_escape/all.mk
new file mode 100644 (file)
index 0000000..9cb0ce3
--- /dev/null
@@ -0,0 +1,2 @@
+TARGET         := rlm_escape.a
+SOURCES                := rlm_escape.c
diff --git a/src/modules/rlm_escape/rlm_escape.c b/src/modules/rlm_escape/rlm_escape.c
new file mode 100644 (file)
index 0000000..8684240
--- /dev/null
@@ -0,0 +1,199 @@
+/*
+ *   This program is is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or (at
+ *   your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * $Id$
+ * @file rlm_escape.c
+ * @brief Register escape/unescape xlat functions.
+ *
+ * @copyright 2018 Arran Cudbard-Bell <a.cudbardb@freeradius.org>
+ */
+RCSID("$Id$")
+USES_APPLE_DEPRECATED_API
+
+#include <freeradius-devel/radiusd.h>
+
+#include <freeradius-devel/modules.h>
+#include <freeradius-devel/rad_assert.h>
+
+#include <ctype.h>
+
+/*
+ *     Define a structure for our module configuration.
+ */
+typedef struct {
+       char const *xlat_name;
+       char const *allowed_chars;
+} rlm_escape_t;
+
+static const CONF_PARSER module_config[] = {
+       { FR_CONF_OFFSET("safe_characters", FR_TYPE_STRING, rlm_escape_t, allowed_chars), .dflt = "@abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-_: /" },
+       CONF_PARSER_TERMINATOR
+};
+
+static char const hextab[] = "0123456789abcdef";
+
+/** Equivalent to the old safe_characters functionality in rlm_sql but with utf8 support
+ *
+ * @verbatim Example: "%{escape:<img>foo.jpg</img>}" == "=60img=62foo.jpg=60/img=62" @endverbatim
+ */
+static ssize_t escape_xlat(UNUSED TALLOC_CTX *ctx, char **out, size_t outlen,
+                          void const *mod_inst, UNUSED void const *xlat_inst,
+                          UNUSED REQUEST *request, char const *fmt)
+{
+       rlm_escape_t const      *inst = mod_inst;
+       char const              *p = fmt;
+       char                    *out_p = *out;
+       size_t                  freespace = outlen;
+
+       while (p[0]) {
+               int chr_len = 1;
+               int ret = 1;    /* -Werror=uninitialized */
+
+               if (fr_utf8_strchr(&chr_len, inst->allowed_chars, p) == NULL) {
+                       /*
+                        *      '=' 1 + ([hex]{2}) * chr_len)
+                        */
+                       if (freespace <= (size_t)(1 + (chr_len * 3))) break;
+
+                       switch (chr_len) {
+                       case 4:
+                               ret = snprintf(out_p, freespace, "=%02X=%02X=%02X=%02X",
+                                              (uint8_t)p[0], (uint8_t)p[1], (uint8_t)p[2], (uint8_t)p[3]);
+                               break;
+
+                       case 3:
+                               ret = snprintf(out_p, freespace, "=%02X=%02X=%02X",
+                                              (uint8_t)p[0], (uint8_t)p[1], (uint8_t)p[2]);
+                               break;
+
+                       case 2:
+                               ret = snprintf(out_p, freespace, "=%02X=%02X", (uint8_t)p[0], (uint8_t)p[1]);
+                               break;
+
+                       case 1:
+                               ret = snprintf(out_p, freespace, "=%02X", (uint8_t)p[0]);
+                               break;
+                       }
+
+                       p += chr_len;
+                       out_p += ret;
+                       freespace -= ret;
+                       continue;
+               }
+
+               /*
+                *      Only one byte left.
+                */
+               if (freespace <= 1) break;
+
+               /*
+                *      Allowed character (copy whole mb chars at once)
+                */
+               memcpy(out_p, p, chr_len);
+               out_p += chr_len;
+               p += chr_len;
+               freespace -= chr_len;
+       }
+       *out_p = '\0';
+
+       return outlen - freespace;
+}
+
+/** Equivalent to the old safe_characters functionality in rlm_sql
+ *
+ * @verbatim Example: "%{unescape:=60img=62foo.jpg=60/img=62}" == "<img>foo.jpg</img>" @endverbatim
+ */
+static ssize_t unescape_xlat(UNUSED TALLOC_CTX *ctx, char **out, size_t outlen,
+                            UNUSED void const *mod_inst, UNUSED void const *xlat_inst,
+                            UNUSED REQUEST *request, char const *fmt)
+{
+       char const *p;
+       char *out_p = *out;
+       char *c1, *c2, c3;
+       size_t  freespace = outlen;
+
+       if (outlen <= 1) return 0;
+
+       p = fmt;
+       while (*p && (--freespace > 0)) {
+               if (*p != '=') {
+               next:
+
+                       *out_p++ = *p++;
+                       continue;
+               }
+
+               /* Is a = char */
+
+               if (!(c1 = memchr(hextab, tolower(*(p + 1)), 16)) ||
+                   !(c2 = memchr(hextab, tolower(*(p + 2)), 16))) goto next;
+               c3 = ((c1 - hextab) << 4) + (c2 - hextab);
+
+               *out_p++ = c3;
+               p += 3;
+       }
+
+       *out_p = '\0';
+
+       return outlen - freespace;
+}
+
+/*
+ *     Do any per-module initialization that is separate to each
+ *     configured instance of the module.  e.g. set up connections
+ *     to external databases, read configuration files, set up
+ *     dictionary entries, etc.
+ *
+ *     If configuration information is given in the config section
+ *     that must be referenced in later calls, store a handle to it
+ *     in *instance otherwise put a null pointer there.
+ */
+static int mod_bootstrap(void *instance, CONF_SECTION *conf)
+{
+       rlm_escape_t    *inst = instance;
+       char            *unescape;
+
+       inst->xlat_name = cf_section_name2(conf);
+       if (!inst->xlat_name) {
+               inst->xlat_name = cf_section_name1(conf);
+       }
+
+       MEM(unescape = talloc_asprintf(NULL, "un%s", inst->xlat_name));
+       xlat_register(inst, inst->xlat_name, escape_xlat, NULL, NULL, 0, XLAT_DEFAULT_BUF_LEN, true);
+       xlat_register(inst, unescape, unescape_xlat, NULL, NULL, 0, XLAT_DEFAULT_BUF_LEN, true);
+       talloc_free(unescape);
+
+       return 0;
+}
+
+/*
+ *     The module name should be the only globally exported symbol.
+ *     That is, everything else should be 'static'.
+ *
+ *     If the module needs to temporarily modify it's instantiation
+ *     data, the type should be changed to RLM_TYPE_THREAD_UNSAFE.
+ *     The server will then take care of ensuring that the module
+ *     is single-threaded.
+ */
+extern rad_module_t rlm_escape;
+rad_module_t rlm_escape = {
+       .magic          = RLM_MODULE_INIT,
+       .name           = "escape",
+       .inst_size      = sizeof(rlm_escape_t),
+       .config         = module_config,
+       .bootstrap      = mod_bootstrap,
+};
index 051e59a9f155317026ef2f09e175a918e9e60579..fc8f4238babdc0d9cb1c6b7e1b1d3c6227f74dab 100644 (file)
@@ -17,7 +17,7 @@
 /**
  * $Id$
  * @file rlm_expr.c
- * @brief Register many xlat expansions including the expr expansion.
+ * @brief Register an xlat expansion to perform basic mathematical operations.
  *
  * @copyright 2001,2006  The FreeRADIUS server project
  * @copyright 2002  Alan DeKok <aland@ox.org>
@@ -39,16 +39,8 @@ USES_APPLE_DEPRECATED_API
  */
 typedef struct rlm_expr_t {
        char const *xlat_name;
-       char const *allowed_chars;
 } rlm_expr_t;
 
-static const CONF_PARSER module_config[] = {
-       { FR_CONF_OFFSET("safe_characters", FR_TYPE_STRING, rlm_expr_t, allowed_chars), .dflt = "@abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-_: /" },
-       CONF_PARSER_TERMINATOR
-};
-
-static char const hextab[] = "0123456789abcdef";
-
 /** Calculate powers
  *
  * @author Orson Peters
@@ -531,112 +523,6 @@ static ssize_t expr_xlat(UNUSED TALLOC_CTX *ctx, char **out, size_t outlen,
        return strlen(*out);
 }
 
-/** Equivalent to the old safe_characters functionality in rlm_sql but with utf8 support
- *
- * @verbatim Example: "%{escape:<img>foo.jpg</img>}" == "=60img=62foo.jpg=60/img=62" @endverbatim
- */
-static ssize_t escape_xlat(UNUSED TALLOC_CTX *ctx, char **out, size_t outlen,
-                          void const *mod_inst, UNUSED void const *xlat_inst,
-                          UNUSED REQUEST *request, char const *fmt)
-{
-       rlm_expr_t const *inst = mod_inst;
-       char const *p = fmt;
-       char *out_p = *out;
-       size_t freespace = outlen;
-
-       while (p[0]) {
-               int chr_len = 1;
-               int ret = 1;    /* -Werror=uninitialized */
-
-               if (fr_utf8_strchr(&chr_len, inst->allowed_chars, p) == NULL) {
-                       /*
-                        *      '=' 1 + ([hex]{2}) * chr_len)
-                        */
-                       if (freespace <= (size_t)(1 + (chr_len * 3))) break;
-
-                       switch (chr_len) {
-                       case 4:
-                               ret = snprintf(out_p, freespace, "=%02X=%02X=%02X=%02X",
-                                              (uint8_t)p[0], (uint8_t)p[1], (uint8_t)p[2], (uint8_t)p[3]);
-                               break;
-
-                       case 3:
-                               ret = snprintf(out_p, freespace, "=%02X=%02X=%02X",
-                                              (uint8_t)p[0], (uint8_t)p[1], (uint8_t)p[2]);
-                               break;
-
-                       case 2:
-                               ret = snprintf(out_p, freespace, "=%02X=%02X", (uint8_t)p[0], (uint8_t)p[1]);
-                               break;
-
-                       case 1:
-                               ret = snprintf(out_p, freespace, "=%02X", (uint8_t)p[0]);
-                               break;
-                       }
-
-                       p += chr_len;
-                       out_p += ret;
-                       freespace -= ret;
-                       continue;
-               }
-
-               /*
-                *      Only one byte left.
-                */
-               if (freespace <= 1) break;
-
-               /*
-                *      Allowed character (copy whole mb chars at once)
-                */
-               memcpy(out_p, p, chr_len);
-               out_p += chr_len;
-               p += chr_len;
-               freespace -= chr_len;
-       }
-       *out_p = '\0';
-
-       return outlen - freespace;
-}
-
-/** Equivalent to the old safe_characters functionality in rlm_sql
- *
- * @verbatim Example: "%{unescape:=60img=62foo.jpg=60/img=62}" == "<img>foo.jpg</img>" @endverbatim
- */
-static ssize_t unescape_xlat(UNUSED TALLOC_CTX *ctx, char **out, size_t outlen,
-                            UNUSED void const *mod_inst, UNUSED void const *xlat_inst,
-                            UNUSED REQUEST *request, char const *fmt)
-{
-       char const *p;
-       char *out_p = *out;
-       char *c1, *c2, c3;
-       size_t  freespace = outlen;
-
-       if (outlen <= 1) return 0;
-
-       p = fmt;
-       while (*p && (--freespace > 0)) {
-               if (*p != '=') {
-               next:
-
-                       *out_p++ = *p++;
-                       continue;
-               }
-
-               /* Is a = char */
-
-               if (!(c1 = memchr(hextab, tolower(*(p + 1)), 16)) ||
-                   !(c2 = memchr(hextab, tolower(*(p + 2)), 16))) goto next;
-               c3 = ((c1 - hextab) << 4) + (c2 - hextab);
-
-               *out_p++ = c3;
-               p += 3;
-       }
-
-       *out_p = '\0';
-
-       return outlen - freespace;
-}
-
 /*
  *     Do any per-module initialization that is separate to each
  *     configured instance of the module.  e.g. set up connections
@@ -657,8 +543,6 @@ static int mod_bootstrap(void *instance, CONF_SECTION *conf)
        }
 
        xlat_register(inst, inst->xlat_name, expr_xlat, NULL, NULL, 0, XLAT_DEFAULT_BUF_LEN, true);
-       xlat_register(inst, "escape", escape_xlat, NULL, NULL, 0, XLAT_DEFAULT_BUF_LEN, true);
-       xlat_register(inst, "unescape", unescape_xlat, NULL, NULL, 0, XLAT_DEFAULT_BUF_LEN, true);
 
        /*
         *      Initialize various paircompare functions
@@ -681,6 +565,5 @@ rad_module_t rlm_expr = {
        .magic          = RLM_MODULE_INIT,
        .name           = "expr",
        .inst_size      = sizeof(rlm_expr_t),
-       .config         = module_config,
        .bootstrap      = mod_bootstrap,
 };
index 33a420ff09011f7a88d8b9c4c5a423c6fc5463cd..5fdb0859305431d3db0d273b8ec481ea97bce368 100644 (file)
@@ -19,6 +19,8 @@ modules {
        $INCLUDE ${raddb}/mods-enabled/pap
 
        $INCLUDE ${raddb}/mods-enabled/expr
+       
+       $INCLUDE ${raddb}/mods-enabled/escape
 
        delay reschedule {
                force_reschedule = yes