diff options
Diffstat (limited to 'src/ne_auth.c')
| -rw-r--r-- | src/ne_auth.c | 50 |
1 files changed, 44 insertions, 6 deletions
diff --git a/src/ne_auth.c b/src/ne_auth.c index 2a31084..9284fa4 100644 --- a/src/ne_auth.c +++ b/src/ne_auth.c @@ -885,6 +885,47 @@ 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 + +/* Returns non-zero if 'username' is unsafe to use without quoting. */ +static int unsafe_username(const char *username) +{ + const char *p; + int rv = 0; + + for (p = username; *p; p++) + rv |= safe_username_table[(const unsigned char)*p]; + + return rv; +} + /* Returns the H(username:realm:password) used in the Digest H(A1) * calculation. */ static char *get_digest_h_urp(auth_session *sess, ne_buffer **errmsg, @@ -911,19 +952,16 @@ static char *get_digest_h_urp(auth_session *sess, ne_buffer **errmsg, * caller has indicated the username really is UTF-8; or * else b) the challenge is an error since the username * cannot be sent safely. */ - char *esc = ne_strparam("UTF-8", NULL, (unsigned char *)sess->username); - - if (esc) { + if (unsafe_username(sess->username)) { if (parms->userhash == userhash_none || parms->handler->new_creds == NULL) { - ne_free(esc); challenge_error(errmsg, _("could not handle non-ASCII " "username in Digest challenge")); ne__strzero(password, sizeof password); return NULL; } - sess->username_star = esc; - NE_DEBUG(NE_DBG_HTTPAUTH, "auth: Using username* => %s\n", esc); + sess->username_star = ne_strparam("UTF-8", NULL, (unsigned char *)sess->username); + NE_DEBUG(NE_DBG_HTTPAUTH, "auth: Using username* => %s\n", sess->username_star); } } |
