]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Add value_box filename escape / make_safe functions
authorNick Porter <nick@portercomputing.co.uk>
Mon, 26 Feb 2024 15:11:19 +0000 (15:11 +0000)
committerNick Porter <nick@portercomputing.co.uk>
Tue, 5 Mar 2024 20:27:02 +0000 (20:27 +0000)
src/lib/server/util.c
src/lib/server/util.h

index 12e72729fac793a30084633d4e44df3bb8f14206..c5f7d57b9361e30985d4caedf30cf0cb7a098c93 100644 (file)
@@ -162,6 +162,31 @@ size_t rad_filename_make_safe(UNUSED request_t *request, char *out, size_t outle
        return (p - out);
 }
 
+int rad_filename_box_make_safe(fr_value_box_t *vb, UNUSED void *uxtc)
+{
+       char                    *escaped;
+       size_t                  len;
+       fr_value_box_entry_t    entry;
+
+       if (vb->vb_length == 0) return 0;
+       if (vb->safe_for == (fr_value_box_safe_for_t)rad_filename_box_make_safe) return 0;
+
+       /*
+        *      Allocate an output buffer, only ever the same or shorter than the input
+        */
+       MEM(escaped = talloc_array(vb, char, vb->vb_length + 1));
+
+       len = rad_filename_make_safe(NULL, escaped, (vb->vb_length + 1), vb->vb_strvalue, NULL);
+
+       entry = vb->entry;
+       fr_value_box_clear_value(vb);
+       fr_value_box_bstrndup(vb, vb, NULL, escaped, len, false);
+       vb->entry = entry;
+       talloc_free(escaped);
+
+       return 0;
+}
+
 /** Escapes the raw string such that it should be safe to use as part of a file path
  *
  * This function is designed to produce a string that's still readable but portable
@@ -262,6 +287,40 @@ size_t rad_filename_escape(UNUSED request_t *request, char *out, size_t outlen,
        return outlen - freespace;
 }
 
+int rad_filename_box_escape(fr_value_box_t *vb, UNUSED void *uxtc)
+{
+       char                    *escaped;
+       size_t                  len;
+       fr_value_box_entry_t    entry;
+
+       if (vb->vb_length == 0) return 0;
+       if (vb->safe_for == (fr_value_box_safe_for_t)rad_filename_box_escape) return 0;
+
+       /*
+        *      Allocate an output buffer, if every character is escaped,
+        *      it will be 3 times the input
+        */
+       MEM(escaped = talloc_array(vb, char, vb->vb_length * 3 + 1));
+
+       len = rad_filename_escape(NULL, escaped, (vb->vb_length * 3 + 1), vb->vb_strvalue, NULL);
+
+       /*
+        *      If the escaped length == input length, no changes were done.
+        */
+       if (len == vb->vb_length) {
+               talloc_free(escaped);
+               return 0;
+       }
+
+       entry = vb->entry;
+       fr_value_box_clear_value(vb);
+       fr_value_box_bstrndup(vb, vb, NULL, escaped, len, false);
+       vb->entry = entry;
+       talloc_free(escaped);
+
+       return 0;
+}
+
 /** Converts data stored in a file name back to its original form
  *
  * @param out Where to write the unescaped string (may be the same as in).
index 565775a335cff52c6da40f4738df80f2d382f78b..e37c67bfebc3f67e1ebfc253d23de447762e71d0 100644 (file)
@@ -36,8 +36,10 @@ extern "C" {
 void (*reset_signal(int signo, void (*func)(int)))(int);
 size_t         rad_filename_make_safe(UNUSED request_t *request, char *out, size_t outlen,
                                       char const *in, UNUSED void *arg);
+int            rad_filename_box_make_safe(fr_value_box_t *vb, UNUSED void *uxtc);
 size_t         rad_filename_escape(UNUSED request_t *request, char *out, size_t outlen,
                                    char const *in, UNUSED void *arg);
+int            rad_filename_box_escape(fr_value_box_t *vb, UNUSED void *uxtc);
 ssize_t                rad_filename_unescape(char *out, size_t outlen, char const *in, size_t inlen);
 char           *rad_ajoin(TALLOC_CTX *ctx, char const **argv, int argc, char c);