diff options
author | Graham Leggett <minfrin@apache.org> | 2014-04-21 17:45:58 +0000 |
---|---|---|
committer | Graham Leggett <minfrin@apache.org> | 2014-04-21 17:45:58 +0000 |
commit | 882e7b8852fd4af3decd4c93fd895155a5c25c95 (patch) | |
tree | 636100248ba3547f2661b93ef9487d4aca12e476 | |
parent | d81ecb2730b3545f544016f1d9411cc4568b7bef (diff) | |
download | apr-882e7b8852fd4af3decd4c93fd895155a5c25c95.tar.gz |
Split the ability to filter LDAP escape sequences into DN escaping or filter
escaping, allowing the option to escape both at the same time.
git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1588937 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r-- | encoding/apr_escape.c | 15 | ||||
-rw-r--r-- | include/apr_escape.h | 25 | ||||
-rw-r--r-- | test/testescape.c | 30 | ||||
-rw-r--r-- | tools/gen_test_char.c | 20 |
4 files changed, 72 insertions, 18 deletions
diff --git a/encoding/apr_escape.c b/encoding/apr_escape.c index 33705c739..eda467593 100644 --- a/encoding/apr_escape.c +++ b/encoding/apr_escape.c @@ -1181,7 +1181,7 @@ APR_DECLARE(const void *) apr_punescape_hex(apr_pool_t *p, const char *str, } APR_DECLARE(apr_status_t) apr_escape_ldap(char *escaped, const void *str, - apr_ssize_t slen, apr_size_t *len) + apr_ssize_t slen, int flags, apr_size_t *len) { apr_size_t size = 1; int found = 0; @@ -1192,7 +1192,8 @@ APR_DECLARE(apr_status_t) apr_escape_ldap(char *escaped, const void *str, if (s) { if (d) { while (((c = *s) && slen) || (slen > 0)) { - if (TEST_CHAR(c, T_ESCAPE_LDAP)) { + if (((flags & APR_ESCAPE_LDAP_DN) && TEST_CHAR(c, T_ESCAPE_LDAP_DN)) + || ((flags & APR_ESCAPE_LDAP_FILTER) && TEST_CHAR(c, T_ESCAPE_LDAP_FILTER))) { d = c2x(c, '\\', d); size += 2; found = 1; @@ -1208,7 +1209,8 @@ APR_DECLARE(apr_status_t) apr_escape_ldap(char *escaped, const void *str, } else { while (((c = *s) && slen) || (slen > 0)) { - if (TEST_CHAR(c, T_ESCAPE_LDAP)) { + if (((flags & APR_ESCAPE_LDAP_DN) && TEST_CHAR(c, T_ESCAPE_LDAP_DN)) + || ((flags & APR_ESCAPE_LDAP_FILTER) && TEST_CHAR(c, T_ESCAPE_LDAP_FILTER))) { size += 2; found = 1; } @@ -1229,14 +1231,15 @@ APR_DECLARE(apr_status_t) apr_escape_ldap(char *escaped, const void *str, return APR_SUCCESS; } -APR_DECLARE(const char *) apr_pescape_ldap(apr_pool_t *p, const void *src, apr_ssize_t srclen) +APR_DECLARE(const char *) apr_pescape_ldap(apr_pool_t *p, const void *src, + apr_ssize_t srclen, int flags) { apr_size_t len; - switch (apr_escape_ldap(NULL, src, srclen, &len)) { + switch (apr_escape_ldap(NULL, src, srclen, flags, &len)) { case APR_SUCCESS: { char *encoded = apr_palloc(p, len); - apr_escape_ldap(encoded, src, srclen, NULL); + apr_escape_ldap(encoded, src, srclen, flags, NULL); return encoded; } case APR_NOTFOUND: { diff --git a/include/apr_escape.h b/include/apr_escape.h index f1968be0c..6d4e08be0 100644 --- a/include/apr_escape.h +++ b/include/apr_escape.h @@ -40,7 +40,22 @@ extern "C" { * passed to indicate a string-valued key, and have the length computed * automatically. */ -#define APR_ESCAPE_STRING (-1) +#define APR_ESCAPE_STRING (-1) + +/** + * Apply LDAP distinguished name escaping as per RFC4514. + */ +#define APR_ESCAPE_LDAP_DN (0x01) + +/** + * Apply LDAP filter escaping as per RFC4515. + */ +#define APR_ESCAPE_LDAP_FILTER (0x02) + +/** + * Apply both RFC4514 and RFC4515 LDAP escaping. + */ +#define APR_ESCAPE_LDAP_ALL (0x03) /** * Perform shell escaping on the provided string. @@ -372,11 +387,13 @@ APR_DECLARE(const void *) apr_punescape_hex(apr_pool_t *p, const char *str, * @param dest The destination buffer, can be NULL * @param src The original buffer * @param srclen The length of the original buffer + * @param flags APR_ESCAPE_LDAP_DN for RFC4514, APR_ESCAPE_LDAP_FILTER for + * RFC4515, APR_ESCAPE_LDAP_ALL for both * @param len If present, returns the length of the string * @return APR_SUCCESS, or APR_NOTFOUND if the string was NULL */ APR_DECLARE(apr_status_t) apr_escape_ldap(char *dest, const void *src, - apr_ssize_t srclen, apr_size_t *len); + apr_ssize_t srclen, int flags, apr_size_t *len); /** * Apply LDAP escaping to binary data, and return the results from a @@ -385,11 +402,13 @@ APR_DECLARE(apr_status_t) apr_escape_ldap(char *dest, const void *src, * @param p Pool to allocate from * @param src The original buffer * @param slen The length of the original buffer + * @param flags APR_ESCAPE_LDAP_DN for RFC4514, APR_ESCAPE_LDAP_FILTER for + * RFC4515, APR_ESCAPE_LDAP_ALL for both * @return A zero padded buffer allocated from the pool on success, or * NULL if src was NULL. */ APR_DECLARE(const char *) apr_pescape_ldap(apr_pool_t *p, const void *src, - apr_ssize_t slen) __attribute__((nonnull(1))); + apr_ssize_t slen, int flags) __attribute__((nonnull(1))); /** @} */ #ifdef __cplusplus diff --git a/test/testescape.c b/test/testescape.c index 8d537de0e..66452274d 100644 --- a/test/testescape.c +++ b/test/testescape.c @@ -263,13 +263,37 @@ static void test_escape(abts_case *tc, void *data) (len == 4)); src = "Parens R Us (for all your parenthetical needs) plus asterisk* \"+,;<>\\"; + target = "Parens R Us (for all your parenthetical needs) plus asterisk* \\22\\2b\\2c\\3b\\3c\\3e\\5c"; + dest = apr_pescape_ldap(pool, src, APR_ESCAPE_STRING, APR_ESCAPE_LDAP_DN); + ABTS_ASSERT(tc, + apr_psprintf(pool, "ldap escaped (%s) does not match expected output (%s)", + dest, target), + (strcmp(dest, target) == 0)); + apr_escape_ldap(NULL, src, APR_ESCAPE_STRING, APR_ESCAPE_LDAP_DN, &len); + ABTS_ASSERT(tc, + apr_psprintf(pool, "size mismatch (%" APR_SIZE_T_FMT "!=%" APR_SIZE_T_FMT ")", len, strlen(dest) + 1), + (len == strlen(dest) + 1)); + + src = "Parens R Us (for all your parenthetical needs) plus asterisk* \"+,;<>\\"; + target = "Parens R Us \\28for all your parenthetical needs\\29 plus asterisk\\2a \"+,;<>\\5c"; + dest = apr_pescape_ldap(pool, src, APR_ESCAPE_STRING, APR_ESCAPE_LDAP_FILTER); + ABTS_ASSERT(tc, + apr_psprintf(pool, "ldap escaped (%s) does not match expected output (%s)", + dest, target), + (strcmp(dest, target) == 0)); + apr_escape_ldap(NULL, src, APR_ESCAPE_STRING, APR_ESCAPE_LDAP_FILTER, &len); + ABTS_ASSERT(tc, + apr_psprintf(pool, "size mismatch (%" APR_SIZE_T_FMT "!=%" APR_SIZE_T_FMT ")", len, strlen(dest) + 1), + (len == strlen(dest) + 1)); + + src = "Parens R Us (for all your parenthetical needs) plus asterisk* \"+,;<>\\"; target = "Parens R Us \\28for all your parenthetical needs\\29 plus asterisk\\2a \\22\\2b\\2c\\3b\\3c\\3e\\5c"; - dest = apr_pescape_ldap(pool, src, APR_ESCAPE_STRING); + dest = apr_pescape_ldap(pool, src, APR_ESCAPE_STRING, APR_ESCAPE_LDAP_ALL); ABTS_ASSERT(tc, - apr_psprintf(pool, "shell escaped (%s) does not match expected output (%s)", + apr_psprintf(pool, "ldap escaped (%s) does not match expected output (%s)", dest, target), (strcmp(dest, target) == 0)); - apr_escape_ldap(NULL, src, APR_ESCAPE_STRING, &len); + apr_escape_ldap(NULL, src, APR_ESCAPE_STRING, APR_ESCAPE_LDAP_ALL, &len); ABTS_ASSERT(tc, apr_psprintf(pool, "size mismatch (%" APR_SIZE_T_FMT "!=%" APR_SIZE_T_FMT ")", len, strlen(dest) + 1), (len == strlen(dest) + 1)); diff --git a/tools/gen_test_char.c b/tools/gen_test_char.c index 156b33145..c48d2cbe7 100644 --- a/tools/gen_test_char.c +++ b/tools/gen_test_char.c @@ -32,7 +32,8 @@ #define T_ESCAPE_ECHO (0x08) #define T_ESCAPE_URLENCODED (0x10) #define T_ESCAPE_XML (0x20) -#define T_ESCAPE_LDAP (0x40) +#define T_ESCAPE_LDAP_DN (0x40) +#define T_ESCAPE_LDAP_FILTER (0x80) int main(int argc, char *argv[]) { @@ -47,7 +48,8 @@ int main(int argc, char *argv[]) "#define T_ESCAPE_ECHO (%u)\n" "#define T_ESCAPE_URLENCODED (%u)\n" "#define T_ESCAPE_XML (%u)\n" - "#define T_ESCAPE_LDAP (%u)\n" + "#define T_ESCAPE_LDAP_DN (%u)\n" + "#define T_ESCAPE_LDAP_FILTER (%u)\n" "\n" "static const unsigned char test_char_table[256] = {", T_ESCAPE_SHELL_CMD, @@ -56,7 +58,8 @@ int main(int argc, char *argv[]) T_ESCAPE_ECHO, T_ESCAPE_URLENCODED, T_ESCAPE_XML, - T_ESCAPE_LDAP); + T_ESCAPE_LDAP_DN, + T_ESCAPE_LDAP_FILTER); for (c = 0; c < 256; ++c) { flags = 0; @@ -109,9 +112,14 @@ int main(int argc, char *argv[]) flags |= T_ESCAPE_XML; } - /* LDAP DN escaping (RFC4514) and LDAP filter escaping (RFC4515) */ - if (!isprint(c) || strchr("\"+,;<>\\", c) || strchr("*()\\", c)) { - flags |= T_ESCAPE_LDAP; + /* LDAP DN escaping (RFC4514) */ + if (!isprint(c) || strchr("\"+,;<>\\", c)) { + flags |= T_ESCAPE_LDAP_DN; + } + + /* LDAP filter escaping (RFC4515) */ + if (!isprint(c) || strchr("*()\\", c)) { + flags |= T_ESCAPE_LDAP_FILTER; } printf("%u%c", flags, (c < 255) ? ',' : ' '); |