diff --git a/tests/util_test.c b/tests/util_test.c index 8863e33..0df972b 100644 --- a/tests/util_test.c +++ b/tests/util_test.c @@ -279,8 +279,29 @@ static void test_filter_printf(void) { printf("test_filter_printf OK\n"); } +static void test_rfc4515_replace(void) { + assert(rfc4515_length("", NULL) == 1); + assert(rfc4515_length(" ", NULL) == 2); + assert(rfc4515_length("test1234567890_.", NULL) == 17); + assert(rfc4515_length("\\test\\test\\", NULL) == 18); + assert(rfc4515_length("*test*test*", NULL) == 18); + assert(rfc4515_length("(test(test(", NULL) == 18); + assert(rfc4515_length(")test)test)", NULL) == 18); + assert(rfc4515_length("\\\\**(())", NULL) == 25); + + assert(!strcmp(rfc4515_replace(""), "")); + assert(!strcmp(rfc4515_replace(" "), " ")); + assert(!strcmp(rfc4515_replace("test1234567890_."), "test1234567890_.")); + assert(!strcmp(rfc4515_replace("\\test\\test\\"), "\\5Ctest\\5Ctest\\5C")); + assert(!strcmp(rfc4515_replace("*test*test*"), "\\2Atest\\2Atest\\2A")); + assert(!strcmp(rfc4515_replace("(test(test("), "\\28test\\28test\\28")); + assert(!strcmp(rfc4515_replace(")test)test)"), "\\29test\\29test\\29")); + assert(!strcmp(rfc4515_replace("\\\\**(())"), "\\5C\\5C\\2A\\2A\\28\\28\\29\\29")); + printf("test_rfc4515_replace OK\n"); +} int main (void) { test_filter_printf(); + test_rfc4515_replace(); test_get_user_cfgfile_path(); test_check_user_token(); #if HAVE_CR diff --git a/util.c b/util.c index d157678..588374f 100644 --- a/util.c +++ b/util.c @@ -783,7 +783,66 @@ size_t filter_result_len(const char *filter, const char *user, char *output) { } char *filter_printf(const char *filter, const char *user) { - char *result = malloc(filter_result_len(filter, user, NULL)); - filter_result_len(filter, user, result); + char *user_rfc4515 = rfc4515_replace(user); + char *result = malloc(filter_result_len(filter, user_rfc4515, NULL)); + filter_result_len(filter, user_rfc4515, result); + free(user_rfc4515); return result; } + +size_t rfc4515_length (const char* in, char* out) +{ + const char* pos = NULL; + size_t result = 0; + const char specials[] = "\\*()"; + + do + { + pos = strpbrk(in, specials); + + size_t len = 0; + if(pos != NULL) + { + len = pos - in; + } + else + { + len = strlen(in); + } + + if(out != NULL) + { + strncpy(out, in, len); + out += len; + } + + result += len; + in += len; + + if(pos != NULL) + { + if(out != NULL) + { + snprintf(out, 4, "%c%02X", 0x5c, *pos); + out += 3; + } + + in += sizeof(char); + result += 3; + } + } while (pos != NULL); + + if(out != NULL) + { + *out = '\0'; + } + + return (result + sizeof(char)); +} + +char* rfc4515_replace(const char* in) +{ + char* result = (char*)malloc(rfc4515_length(in, NULL)); + rfc4515_length (in, result); + return result; +} diff --git a/util.h b/util.h index 3a36978..1d1b2eb 100644 --- a/util.h +++ b/util.h @@ -103,4 +103,7 @@ int challenge_response(YK_KEY *yk, int slot, size_t filter_result_len(const char *filter, const char *user, char *output); char *filter_printf(const char *filter, const char *user); +size_t rfc4515_length ( const char* in, char* out ); +char* rfc4515_replace ( const char* in ); + #endif /* __PAM_YUBICO_UTIL_H_INCLUDED__ */