From a54c8d2b826a363f7bf8f326a621fbd132b4c05f Mon Sep 17 00:00:00 2001 From: Joe Orton Date: Fri, 9 Sep 2022 20:27:14 +0100 Subject: Treat spaces as safe in Digest usernames. * src/mktable.c: Add safe_username generator. * src/ne_auth.c: Regenerate safe_username table. * test/auth.c (digest_username_star): Adjust test accordingly. --- src/mktable.c | 16 ++++++++++++++++ src/ne_auth.c | 49 ++++++++++++++++++++----------------------------- test/auth.c | 2 +- 3 files changed, 37 insertions(+), 30 deletions(-) diff --git a/src/mktable.c b/src/mktable.c index c51ee72..d194f1d 100644 --- a/src/mktable.c +++ b/src/mktable.c @@ -63,6 +63,21 @@ static unsigned char decode_b64(unsigned char ch) return DECODE_B64(ch); } +/* Username safety lookup table; "SF" for characters which are safe to + * include in 2617-style username parameter values, else "NS" for + * non-safe characters. Determined from RFC7230§3.2.6 - everything in + * qdtext EXCEPT obs-text (which is "non-ASCII") is treated as safe to + * include in a quoted username: + qdtext = HTAB / SP /%x21 / %x23-5B / %x5D-7E / obs-text + obs-text = %x80-FF +*/ +static unsigned char safe_username(unsigned char ch) +{ + return (ch == '\t' || ch == ' ' || ch == 0x21 + || (ch >= 0x23 && ch <= 0x7E && ch != 0x5C)) + ? 0 : 1; +} + #define QT 3 #define NQ 1 @@ -91,6 +106,7 @@ static const struct { { "decodeb64", decode_b64, 0 }, { "quote", gen_quote, FLAG_DECIMAL | FLAG_SHORT }, { "extparam", gen_extparam, FLAG_DECIMAL | FLAG_SHORT }, + { "safe_username", safe_username, FLAG_DECIMAL | FLAG_SHORT }, }; static void fail(const char *err, const char *arg) diff --git a/src/ne_auth.c b/src/ne_auth.c index 54b8fac..ee42641 100644 --- a/src/ne_auth.c +++ b/src/ne_auth.c @@ -865,34 +865,25 @@ static int ntlm_challenge(auth_session *sess, int attempt, } #endif /* HAVE_NTLM */ -/* Username safety lookup table; "SF" for characters which are safe to - * include in 2617-style username parameter values, else "NS" for - * non-safe characters. Determined from RFC7230§3.2.6 - everything in - * qdtext EXCEPT obs-text (which is "non-ASCII") is treated as safe to - * include in a quoted username. */ -#define SF 0 -#define NS 1 -static const signed char safe_username_table[256] = { -/* 0xXX x0 x2 x4 x6 x8 xA xC xE */ -/* 0x */ NS, NS, NS, NS, NS, NS, NS, NS, NS, NS, NS, NS, NS, NS, NS, NS, -/* 1x */ NS, NS, NS, NS, NS, NS, NS, NS, NS, NS, NS, NS, NS, NS, NS, NS, -/* 2x */ NS, SF, NS, SF, SF, SF, SF, SF, SF, SF, SF, SF, SF, SF, SF, SF, -/* 3x */ SF, SF, SF, SF, SF, SF, SF, SF, SF, SF, SF, SF, SF, SF, SF, SF, -/* 4x */ SF, SF, SF, SF, SF, SF, SF, SF, SF, SF, SF, SF, SF, SF, SF, SF, -/* 5x */ SF, SF, SF, SF, SF, SF, SF, SF, SF, SF, SF, SF, NS, SF, SF, SF, -/* 4x */ SF, SF, SF, SF, SF, SF, SF, SF, SF, SF, SF, SF, SF, SF, SF, SF, -/* 7x */ SF, SF, SF, SF, SF, SF, SF, SF, SF, SF, SF, SF, SF, SF, SF, NS, -/* 8x */ NS, NS, NS, NS, NS, NS, NS, NS, NS, NS, NS, NS, NS, NS, NS, NS, -/* 9x */ NS, NS, NS, NS, NS, NS, NS, NS, NS, NS, NS, NS, NS, NS, NS, NS, -/* Ax */ NS, NS, NS, NS, NS, NS, NS, NS, NS, NS, NS, NS, NS, NS, NS, NS, -/* Bx */ NS, NS, NS, NS, NS, NS, NS, NS, NS, NS, NS, NS, NS, NS, NS, NS, -/* Cx */ NS, NS, NS, NS, NS, NS, NS, NS, NS, NS, NS, NS, NS, NS, NS, NS, -/* Dx */ NS, NS, NS, NS, NS, NS, NS, NS, NS, NS, NS, NS, NS, NS, NS, NS, -/* Ex */ NS, NS, NS, NS, NS, NS, NS, NS, NS, NS, NS, NS, NS, NS, NS, NS, -/* Fx */ NS, NS, NS, NS, NS, NS, NS, NS, NS, NS, NS, NS, NS, NS, NS, NS -}; -#undef NS -#undef SF +/* Generated with 'mktable safe_username', do not alter here -- */ +static const unsigned char table_safe_username[256] = { +/* x00 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, +/* x10 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +/* x20 */ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/* x30 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/* x40 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/* x50 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, +/* x60 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/* x70 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, +/* x80 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +/* x90 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +/* xA0 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +/* xB0 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +/* xC0 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +/* xD0 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +/* xE0 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +/* xF0 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 +}; /* -- Generated code from 'mktable safe_username' ends. */ /* Returns non-zero if 'username' is unsafe to use without quoting. */ static int unsafe_username(const char *username) @@ -901,7 +892,7 @@ static int unsafe_username(const char *username) int rv = 0; for (p = username; *p; p++) - rv |= safe_username_table[(const unsigned char)*p]; + rv |= table_safe_username[(const unsigned char)*p]; return rv; } diff --git a/test/auth.c b/test/auth.c index 59b2ff8..90a5f58 100644 --- a/test/auth.c +++ b/test/auth.c @@ -1037,9 +1037,9 @@ static int digest_username_star(void) } ts[] = { { "Aladdin", NULL }, { "aladdin@cave.example.com", NULL }, + { "foo bar", NULL }, { "Ałâddín", "UTF-8''A%c5%82%c3%a2dd%c3%adn" }, { "Jäsøn Doe", "UTF-8''J%c3%a4s%c3%b8n%20Doe" }, - { "foo bar", "UTF-8''foo%20bar"}, { "foo\"bar", "UTF-8''foo%22bar" }, { NULL, NULL } }; -- cgit v1.2.1