summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGraham Leggett <minfrin@apache.org>2014-04-21 17:45:58 +0000
committerGraham Leggett <minfrin@apache.org>2014-04-21 17:45:58 +0000
commit882e7b8852fd4af3decd4c93fd895155a5c25c95 (patch)
tree636100248ba3547f2661b93ef9487d4aca12e476
parentd81ecb2730b3545f544016f1d9411cc4568b7bef (diff)
downloadapr-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.c15
-rw-r--r--include/apr_escape.h25
-rw-r--r--test/testescape.c30
-rw-r--r--tools/gen_test_char.c20
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) ? ',' : ' ');