Jacek Caban : wininet: Added InternetGetSecurityInfoByURL[AW] implementation.

Alexandre Julliard julliard at winehq.org
Mon Jun 11 15:08:07 CDT 2012


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Mon Jun 11 10:22:38 2012 +0200

wininet: Added InternetGetSecurityInfoByURL[AW] implementation.

---

 dlls/wininet/http.c          |   16 +++++-----
 dlls/wininet/internet.c      |   59 ++++++++++++++++++++++++++++++++++++++---
 dlls/wininet/internet.h      |    5 +++
 dlls/wininet/netconnection.c |   13 +++++++--
 4 files changed, 77 insertions(+), 16 deletions(-)

diff --git a/dlls/wininet/http.c b/dlls/wininet/http.c
index 620fcf7..0cec4fb 100644
--- a/dlls/wininet/http.c
+++ b/dlls/wininet/http.c
@@ -244,11 +244,13 @@ void server_release(server_t *server)
 
     list_remove(&server->entry);
 
+    if(server->cert_chain)
+        CertFreeCertificateChain(server->cert_chain);
     heap_free(server->name);
     heap_free(server);
 }
 
-static server_t *get_server(const WCHAR *name, INTERNET_PORT port)
+server_t *get_server(const WCHAR *name, INTERNET_PORT port, BOOL do_create)
 {
     server_t *iter, *server = NULL;
 
@@ -262,13 +264,11 @@ static server_t *get_server(const WCHAR *name, INTERNET_PORT port)
         }
     }
 
-    if(!server) {
-        server = heap_alloc(sizeof(*server));
+    if(!server && do_create) {
+        server = heap_alloc_zero(sizeof(*server));
         if(server) {
-            server->addr_len = 0;
             server->ref = 2; /* list reference and return */
             server->port = port;
-            server->security_flags = 0;
             list_init(&server->conn_pool);
             server->name = heap_strdupW(name);
             if(server->name) {
@@ -1724,7 +1724,7 @@ static BOOL HTTP_DealWithProxy(appinfo_t *hIC, http_session_t *session, http_req
     if(UrlComponents.nPort == INTERNET_INVALID_PORT_NUMBER)
         UrlComponents.nPort = INTERNET_DEFAULT_HTTP_PORT;
 
-    new_server = get_server(UrlComponents.lpszHostName, UrlComponents.nPort);
+    new_server = get_server(UrlComponents.lpszHostName, UrlComponents.nPort, TRUE);
     if(!new_server)
         return FALSE;
 
@@ -3103,7 +3103,7 @@ static DWORD HTTP_HttpOpenRequestW(http_session_t *session,
     if(port == INTERNET_INVALID_PORT_NUMBER)
         port = dwFlags & INTERNET_FLAG_SECURE ? INTERNET_DEFAULT_HTTPS_PORT : INTERNET_DEFAULT_HTTP_PORT;
 
-    request->server = get_server(session->hostName, port);
+    request->server = get_server(session->hostName, port, TRUE);
     if(!request->server) {
         WININET_Release(&request->hdr);
         return ERROR_OUTOFMEMORY;
@@ -3931,7 +3931,7 @@ static DWORD HTTP_HandleRedirect(http_request_t *request, LPCWSTR lpszUrl)
         if(!using_proxy && (strcmpiW(request->server->name, hostName) || request->server->port != urlComponents.nPort)) {
             server_t *new_server;
 
-            new_server = get_server(hostName, urlComponents.nPort);
+            new_server = get_server(hostName, urlComponents.nPort, TRUE);
             server_release(request->server);
             request->server = new_server;
         }
diff --git a/dlls/wininet/internet.c b/dlls/wininet/internet.c
index 118dcdd..2b659da 100644
--- a/dlls/wininet/internet.c
+++ b/dlls/wininet/internet.c
@@ -61,7 +61,6 @@
 #include "winreg.h"
 #include "winuser.h"
 #include "wininet.h"
-#include "winineti.h"
 #include "winnls.h"
 #include "wine/debug.h"
 #include "winerror.h"
@@ -4419,8 +4418,18 @@ DWORD WINAPI PrivacyGetZonePreferenceW( DWORD zone, DWORD type, LPDWORD template
  */
 BOOL WINAPI InternetGetSecurityInfoByURLA(LPSTR lpszURL, PCCERT_CHAIN_CONTEXT *ppCertChain, DWORD *pdwSecureFlags)
 {
-    FIXME("(%s %p %p)\n", debugstr_a(lpszURL), ppCertChain, pdwSecureFlags);
-    return FALSE;
+    WCHAR *url;
+    BOOL res;
+
+    TRACE("(%s %p %p)\n", debugstr_a(lpszURL), ppCertChain, pdwSecureFlags);
+
+    url = heap_strdupAtoW(lpszURL);
+    if(!url)
+        return FALSE;
+
+    res = InternetGetSecurityInfoByURLW(url, ppCertChain, pdwSecureFlags);
+    heap_free(url);
+    return res;
 }
 
 /***********************************************************************
@@ -4428,8 +4437,48 @@ BOOL WINAPI InternetGetSecurityInfoByURLA(LPSTR lpszURL, PCCERT_CHAIN_CONTEXT *p
  */
 BOOL WINAPI InternetGetSecurityInfoByURLW(LPCWSTR lpszURL, PCCERT_CHAIN_CONTEXT *ppCertChain, DWORD *pdwSecureFlags)
 {
-    FIXME("(%s %p %p)\n", debugstr_w(lpszURL), ppCertChain, pdwSecureFlags);
-    return FALSE;
+    WCHAR hostname[INTERNET_MAX_HOST_NAME_LENGTH];
+    URL_COMPONENTSW url = {sizeof(url)};
+    server_t *server;
+    BOOL res = FALSE;
+
+    TRACE("(%s %p %p)\n", debugstr_w(lpszURL), ppCertChain, pdwSecureFlags);
+
+    url.lpszHostName = hostname;
+    url.dwHostNameLength = sizeof(hostname)/sizeof(WCHAR);
+
+    res = InternetCrackUrlW(lpszURL, 0, 0, &url);
+    if(!res || url.nScheme != INTERNET_SCHEME_HTTPS) {
+        SetLastError(ERROR_INTERNET_ITEM_NOT_FOUND);
+        return FALSE;
+    }
+
+    if(url.nPort == INTERNET_INVALID_PORT_NUMBER)
+        url.nPort = INTERNET_DEFAULT_HTTPS_PORT;
+
+    server = get_server(hostname, url.nPort, FALSE);
+    if(!server) {
+        SetLastError(ERROR_INTERNET_ITEM_NOT_FOUND);
+        return FALSE;
+    }
+
+    if(server->cert_chain) {
+        const CERT_CHAIN_CONTEXT *chain_dup;
+
+        chain_dup = CertDuplicateCertificateChain(server->cert_chain);
+        if(chain_dup) {
+            *ppCertChain = chain_dup;
+            *pdwSecureFlags = server->security_flags & _SECURITY_ERROR_FLAGS_MASK;
+        }else {
+            res = FALSE;
+        }
+    }else {
+        SetLastError(ERROR_INTERNET_ITEM_NOT_FOUND);
+        res = FALSE;
+    }
+
+    server_release(server);
+    return res;
 }
 
 DWORD WINAPI InternetDialA( HWND hwndParent, LPSTR lpszConnectoid, DWORD dwFlags,
diff --git a/dlls/wininet/internet.h b/dlls/wininet/internet.h
index a25be32..e3fb530 100644
--- a/dlls/wininet/internet.h
+++ b/dlls/wininet/internet.h
@@ -47,6 +47,8 @@
 #define ioctlsocket ioctl
 #endif /* __MINGW32__ */
 
+#include "winineti.h"
+
 extern HMODULE WININET_hModule DECLSPEC_HIDDEN;
 
 #ifndef INET6_ADDRSTRLEN
@@ -63,6 +65,7 @@ typedef struct {
     LONG ref;
 
     DWORD security_flags;
+    const CERT_CHAIN_CONTEXT *cert_chain;
 
     struct list entry;
     struct list conn_pool;
@@ -546,6 +549,8 @@ int NETCON_GetCipherStrength(netconn_t*) DECLSPEC_HIDDEN;
 DWORD NETCON_set_timeout(netconn_t *connection, BOOL send, DWORD value) DECLSPEC_HIDDEN;
 int sock_get_error(int) DECLSPEC_HIDDEN;
 
+server_t *get_server(const WCHAR*,INTERNET_PORT,BOOL);
+
 extern void URLCacheContainers_CreateDefaults(void) DECLSPEC_HIDDEN;
 extern void URLCacheContainers_DeleteAll(void) DECLSPEC_HIDDEN;
 
diff --git a/dlls/wininet/netconnection.c b/dlls/wininet/netconnection.c
index 47b8453..a705cce 100644
--- a/dlls/wininet/netconnection.c
+++ b/dlls/wininet/netconnection.c
@@ -80,7 +80,6 @@
 #include "winbase.h"
 #include "wininet.h"
 #include "winerror.h"
-#include "wincrypt.h"
 
 #include "wine/debug.h"
 #include "internet.h"
@@ -358,15 +357,23 @@ static DWORD netconn_verify_cert(netconn_t *conn, PCCERT_CONTEXT cert, HCERTSTOR
         }
     }
 
-    CertFreeCertificateChain(chain);
-
     if(err) {
         WARN("failed %u\n", err);
+        CertFreeCertificateChain(chain);
+        if(conn->server->cert_chain) {
+            CertFreeCertificateChain(conn->server->cert_chain);
+            conn->server->cert_chain = NULL;
+        }
         if(conn->mask_errors)
             conn->server->security_flags |= conn->security_flags & _SECURITY_ERROR_FLAGS_MASK;
         return err;
     }
 
+    /* FIXME: Reuse cached chain */
+    if(conn->server->cert_chain)
+        CertFreeCertificateChain(chain);
+    else
+        conn->server->cert_chain = chain;
     return ERROR_SUCCESS;
 }
 




More information about the wine-cvs mailing list