summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Orton <jorton@redhat.com>2022-07-04 10:18:28 +0100
committerJoe Orton <jorton@apache.org>2022-07-11 08:10:31 +0100
commit93faea82fe49bfcf22d99c0e9f954ae714315de5 (patch)
treeeef64605fd048097864ae81b251126f8fe949af9
parent9924d4d31525f8b61e37076b18004c603fd01761 (diff)
downloadneon-git-93faea82fe49bfcf22d99c0e9f954ae714315de5.tar.gz
Relax strictness of usernames allowed with Digest without requiring
userhash/ext-param quoting (closes #78): * src/ne_auth.c (unsafe_username): New function. (get_digest_h_urp): Use it, rather than ne_strparam() to determine whether the passed username is safe to use quoted. * test/auth.c (digest_username_star): Test for @ in usernames.
-rw-r--r--src/ne_auth.c50
-rw-r--r--test/auth.c1
2 files changed, 45 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);
}
}
diff --git a/test/auth.c b/test/auth.c
index c9b3c63..e985703 100644
--- a/test/auth.c
+++ b/test/auth.c
@@ -1030,6 +1030,7 @@ static int digest_username_star(void)
const char *username_raw, *username_star;
} ts[] = {
{ "Aladdin", NULL },
+ { "aladdin@cave.example.com", 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"},