Преглед на файлове

Official Neon fix for Bug 2095 (Cannot authenticate to WebDAV server with username containing some special characters)

https://github.com/notroj/neon/pull/79
(cherry picked from commit 0c65ce68d0bd4428ee3ddf5cd107793bfdbba1e7)

Source commit: 4e078153d750b1321f95bdf5465bf5dce3733d68
Martin Prikryl преди 3 години
родител
ревизия
31483aabb1
променени са 2 файла, в които са добавени 45 реда и са изтрити 6 реда
  1. 44 6
      libs/neon/src/ne_auth.c
  2. 1 0
      libs/neon/test/auth.c

+ 44 - 6
libs/neon/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);
         }
     }
 

+ 1 - 0
libs/neon/test/auth.c

@@ -1030,6 +1030,7 @@ static int digest_username_star(void)
         const char *username_raw, *username_star;
     } ts[] = {
         { "Aladdin", NULL },
+        { "[email protected]", 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"},