瀏覽代碼

Merge branch 'thirdparty'

# Conflicts:
#	libs/neon/src/ne_auth.c

Source commit: d1ab7c77b7da35670cd80660355d6dfc90f0d97b
Martin Prikryl 3 年之前
父節點
當前提交
6339542e70
共有 1 個文件被更改,包括 44 次插入24 次删除
  1. 44 24
      libs/neon/src/ne_auth.c

+ 44 - 24
libs/neon/src/ne_auth.c

@@ -933,6 +933,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,
@@ -959,37 +1000,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);
-
-        #ifdef WINSCP
-        if (esc && (parms->userhash == userhash_none || parms->handler->new_creds == NULL)) {
-            const char *p;
-            int ascii = 1;
-            for (p = sess->username; *p; p++) {
-                if (((*p & ~0x7f) != 0) || (!isprint(*p) && !isspace(*p))) {
-                    ascii = 0;
-                    break;
-                }
-            }
-
-            if (ascii) {
-                ne_free(esc);
-                esc = NULL;
-            }
-        }
-        #endif
-
-        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);
         }
     }