Juan Lang : crypt32: Only compare the hostname portion of a URL when checking against a name constraint .

Alexandre Julliard julliard at winehq.org
Tue Nov 17 09:28:16 CST 2009


Module: wine
Branch: master
Commit: e82005fe2dcd983769b09550e0f69f8bb36def05
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=e82005fe2dcd983769b09550e0f69f8bb36def05

Author: Juan Lang <juan.lang at gmail.com>
Date:   Fri Nov 13 17:44:42 2009 -0800

crypt32: Only compare the hostname portion of a URL when checking against a name constraint.

---

 dlls/crypt32/chain.c |   56 ++++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 50 insertions(+), 6 deletions(-)

diff --git a/dlls/crypt32/chain.c b/dlls/crypt32/chain.c
index 3badef1..0fd9df7 100644
--- a/dlls/crypt32/chain.c
+++ b/dlls/crypt32/chain.c
@@ -517,14 +517,58 @@ static BOOL url_matches(LPCWSTR constraint, LPCWSTR name,
         *trustErrorStatus |= CERT_TRUST_INVALID_NAME_CONSTRAINTS;
     else if (!name)
         ; /* no match */
-    else if (constraint[0] == '.')
+    else
     {
-        if (lstrlenW(name) > lstrlenW(constraint))
-            match = !lstrcmpiW(name + lstrlenW(name) - lstrlenW(constraint),
-             constraint);
+        LPCWSTR colon, authority_end, at, hostname = NULL;
+        /* The maximum length for a hostname is 254 in the DNS, see RFC 1034 */
+        WCHAR hostname_buf[255];
+
+        /* RFC 5280: only the hostname portion of the URL is compared.  From
+         * section 4.2.1.10:
+         * "For URIs, the constraint applies to the host part of the name.
+         *  The constraint MUST be specified as a fully qualified domain name
+         *  and MAY specify a host or a domain."
+         * The format for URIs is in RFC 2396.
+         *
+         * First, remove any scheme that's present. */
+        colon = strchrW(name, ':');
+        if (colon && *(colon + 1) == '/' && *(colon + 2) == '/')
+            name = colon + 3;
+        /* Next, find the end of the authority component.  (The authority is
+         * generally just the hostname, but it may contain a username or a port.
+         * Those are removed next.)
+         */
+        authority_end = strchrW(name, '/');
+        if (!authority_end)
+            authority_end = strchrW(name, '?');
+        if (!authority_end)
+            authority_end = name + strlenW(name);
+        /* Remove any port number from the authority */
+        for (colon = authority_end; colon >= name && *colon != ':'; colon--)
+            ;
+        if (*colon == ':')
+            authority_end = colon;
+        /* Remove any username from the authority */
+        if ((at = strchrW(name, '@')))
+            name = at;
+        /* Ignore any path or query portion of the URL. */
+        if (*authority_end)
+        {
+            if (authority_end - name < sizeof(hostname_buf) /
+             sizeof(hostname_buf[0]))
+            {
+                memcpy(hostname_buf, name,
+                 (authority_end - name) * sizeof(WCHAR));
+                hostname_buf[authority_end - name] = 0;
+                hostname = hostname_buf;
+            }
+            /* else: Hostname is too long, not a match */
+        }
+        else
+            hostname = name;
+        if (hostname)
+            match = !lstrcmpiW(constraint, hostname);
     }
-    else
-        match = !lstrcmpiW(constraint, name);
     return match;
 }
 




More information about the wine-cvs mailing list