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