From: Nick Porter Date: Mon, 26 Feb 2024 15:11:19 +0000 (+0000) Subject: Add value_box filename escape / make_safe functions X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8127c5dc3049560b5dff8499c9de47a6f15e10bc;p=thirdparty%2Ffreeradius-server.git Add value_box filename escape / make_safe functions --- diff --git a/src/lib/server/util.c b/src/lib/server/util.c index 12e72729fac..c5f7d57b936 100644 --- a/src/lib/server/util.c +++ b/src/lib/server/util.c @@ -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). diff --git a/src/lib/server/util.h b/src/lib/server/util.h index 565775a335c..e37c67bfebc 100644 --- a/src/lib/server/util.h +++ b/src/lib/server/util.h @@ -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);