summaryrefslogtreecommitdiff
path: root/src/ne_auth.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ne_auth.c')
-rw-r--r--src/ne_auth.c50
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);
}
}