Piotr Caban : wininet: Cache non basic authorization data.
Alexandre Julliard
julliard at winehq.org
Mon Jul 19 11:05:32 CDT 2010
Module: wine
Branch: master
Commit: c398e6fc7718030c82215bd1ab10518b1b4b672c
URL: http://source.winehq.org/git/wine.git/?a=commit;h=c398e6fc7718030c82215bd1ab10518b1b4b672c
Author: Piotr Caban <piotr at codeweavers.com>
Date: Sat Jul 17 14:08:44 2010 +0200
wininet: Cache non basic authorization data.
---
dlls/wininet/http.c | 127 ++++++++++++++++++++++++++++++++++++++++++++--
dlls/wininet/internet.h | 21 ++++++++
2 files changed, 142 insertions(+), 6 deletions(-)
diff --git a/dlls/wininet/http.c b/dlls/wininet/http.c
index 57c4f75..c9bbde2 100644
--- a/dlls/wininet/http.c
+++ b/dlls/wininet/http.c
@@ -179,7 +179,7 @@ struct gzip_stream_t {
BOOL end_of_data;
};
-typedef struct _authorizationData
+typedef struct _basicAuthorizationData
{
struct list entry;
@@ -187,9 +187,24 @@ typedef struct _authorizationData
LPWSTR lpszwRealm;
LPSTR lpszAuthorization;
UINT AuthorizationLen;
+} basicAuthorizationData;
+
+typedef struct _authorizationData
+{
+ struct list entry;
+
+ LPWSTR host;
+ LPWSTR scheme;
+ LPWSTR domain;
+ UINT domain_len;
+ LPWSTR user;
+ UINT user_len;
+ LPWSTR password;
+ UINT password_len;
} authorizationData;
static struct list basicAuthorizationCache = LIST_INIT(basicAuthorizationCache);
+static struct list authorizationCache = LIST_INIT(authorizationCache);
static CRITICAL_SECTION authcache_cs;
static CRITICAL_SECTION_DEBUG critsect_debug =
@@ -570,13 +585,13 @@ static void destroy_authinfo( struct HttpAuthInfo *authinfo )
static UINT retrieve_cached_basic_authorization(LPWSTR host, LPWSTR realm, LPSTR *auth_data)
{
- authorizationData *ad;
+ basicAuthorizationData *ad;
UINT rc = 0;
TRACE("Looking for authorization for %s:%s\n",debugstr_w(host),debugstr_w(realm));
EnterCriticalSection(&authcache_cs);
- LIST_FOR_EACH_ENTRY(ad, &basicAuthorizationCache, authorizationData, entry)
+ LIST_FOR_EACH_ENTRY(ad, &basicAuthorizationCache, basicAuthorizationData, entry)
{
if (!strcmpiW(host,ad->lpszwHost) && !strcmpW(realm,ad->lpszwRealm))
{
@@ -594,14 +609,14 @@ static UINT retrieve_cached_basic_authorization(LPWSTR host, LPWSTR realm, LPSTR
static void cache_basic_authorization(LPWSTR host, LPWSTR realm, LPSTR auth_data, UINT auth_data_len)
{
struct list *cursor;
- authorizationData* ad = NULL;
+ basicAuthorizationData* ad = NULL;
TRACE("caching authorization for %s:%s = %s\n",debugstr_w(host),debugstr_w(realm),debugstr_an(auth_data,auth_data_len));
EnterCriticalSection(&authcache_cs);
LIST_FOR_EACH(cursor, &basicAuthorizationCache)
{
- authorizationData *check = LIST_ENTRY(cursor,authorizationData,entry);
+ basicAuthorizationData *check = LIST_ENTRY(cursor,basicAuthorizationData,entry);
if (!strcmpiW(host,check->lpszwHost) && !strcmpW(realm,check->lpszwRealm))
{
ad = check;
@@ -619,7 +634,7 @@ static void cache_basic_authorization(LPWSTR host, LPWSTR realm, LPSTR auth_data
}
else
{
- ad = HeapAlloc(GetProcessHeap(),0,sizeof(authorizationData));
+ ad = HeapAlloc(GetProcessHeap(),0,sizeof(basicAuthorizationData));
ad->lpszwHost = heap_strdupW(host);
ad->lpszwRealm = heap_strdupW(realm);
ad->lpszAuthorization = HeapAlloc(GetProcessHeap(),0,auth_data_len);
@@ -631,6 +646,95 @@ static void cache_basic_authorization(LPWSTR host, LPWSTR realm, LPSTR auth_data
LeaveCriticalSection(&authcache_cs);
}
+static BOOL retrieve_cached_authorization(LPWSTR host, LPWSTR scheme,
+ SEC_WINNT_AUTH_IDENTITY_W *nt_auth_identity)
+{
+ authorizationData *ad;
+
+ TRACE("Looking for authorization for %s:%s\n", debugstr_w(host), debugstr_w(scheme));
+
+ EnterCriticalSection(&authcache_cs);
+ LIST_FOR_EACH_ENTRY(ad, &authorizationCache, authorizationData, entry) {
+ if(!strcmpiW(host, ad->host) && !strcmpiW(scheme, ad->scheme)) {
+ TRACE("Authorization found in cache\n");
+
+ nt_auth_identity->User = heap_strdupW(ad->user);
+ nt_auth_identity->Password = heap_strdupW(ad->password);
+ nt_auth_identity->Domain = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*ad->domain_len);
+ if(!nt_auth_identity->User || !nt_auth_identity->Password ||
+ (!nt_auth_identity->Domain && ad->domain_len)) {
+ HeapFree(GetProcessHeap(), 0, nt_auth_identity->User);
+ HeapFree(GetProcessHeap(), 0, nt_auth_identity->Password);
+ HeapFree(GetProcessHeap(), 0, nt_auth_identity->Domain);
+ break;
+ }
+
+ nt_auth_identity->Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
+ nt_auth_identity->UserLength = ad->user_len;
+ nt_auth_identity->PasswordLength = ad->password_len;
+ memcpy(nt_auth_identity->Domain, ad->domain, sizeof(WCHAR)*ad->domain_len);
+ nt_auth_identity->DomainLength = ad->domain_len;
+ LeaveCriticalSection(&authcache_cs);
+ return TRUE;
+ }
+ }
+ LeaveCriticalSection(&authcache_cs);
+
+ return FALSE;
+}
+
+static void cache_authorization(LPWSTR host, LPWSTR scheme,
+ SEC_WINNT_AUTH_IDENTITY_W *nt_auth_identity)
+{
+ authorizationData *ad;
+ BOOL found = FALSE;
+
+ TRACE("Caching authorization for %s:%s\n", debugstr_w(host), debugstr_w(scheme));
+
+ EnterCriticalSection(&authcache_cs);
+ LIST_FOR_EACH_ENTRY(ad, &authorizationCache, authorizationData, entry)
+ if(!strcmpiW(host, ad->host) && !strcmpiW(scheme, ad->scheme)) {
+ found = TRUE;
+ break;
+ }
+
+ if(found) {
+ HeapFree(GetProcessHeap(), 0, ad->user);
+ HeapFree(GetProcessHeap(), 0, ad->password);
+ HeapFree(GetProcessHeap(), 0, ad->domain);
+ } else {
+ ad = HeapAlloc(GetProcessHeap(), 0, sizeof(authorizationData));
+ if(!ad) {
+ LeaveCriticalSection(&authcache_cs);
+ return;
+ }
+
+ ad->host = heap_strdupW(host);
+ ad->scheme = heap_strdupW(scheme);
+ list_add_head(&authorizationCache, &ad->entry);
+ }
+
+ ad->user = heap_strndupW(nt_auth_identity->User, nt_auth_identity->UserLength);
+ ad->password = heap_strndupW(nt_auth_identity->Password, nt_auth_identity->PasswordLength);
+ ad->domain = heap_strndupW(nt_auth_identity->Domain, nt_auth_identity->DomainLength);
+ ad->user_len = nt_auth_identity->UserLength;
+ ad->password_len = nt_auth_identity->PasswordLength;
+ ad->domain_len = nt_auth_identity->DomainLength;
+
+ if(!ad->host || !ad->scheme || !ad->user || !ad->password
+ || (nt_auth_identity->Domain && !ad->domain)) {
+ HeapFree(GetProcessHeap(), 0, ad->host);
+ HeapFree(GetProcessHeap(), 0, ad->scheme);
+ HeapFree(GetProcessHeap(), 0, ad->user);
+ HeapFree(GetProcessHeap(), 0, ad->password);
+ HeapFree(GetProcessHeap(), 0, ad->domain);
+ list_remove(&ad->entry);
+ HeapFree(GetProcessHeap(), 0, ad);
+ }
+
+ LeaveCriticalSection(&authcache_cs);
+}
+
static BOOL HTTP_DoAuthorization( http_request_t *lpwhr, LPCWSTR pszAuthValue,
struct HttpAuthInfo **ppAuthInfo,
LPWSTR domain_and_username, LPWSTR password,
@@ -705,7 +809,11 @@ static BOOL HTTP_DoAuthorization( http_request_t *lpwhr, LPCWSTR pszAuthValue,
nt_auth_identity.DomainLength = domain ? user - domain - 1 : 0;
nt_auth_identity.Password = password;
nt_auth_identity.PasswordLength = strlenW(nt_auth_identity.Password);
+
+ cache_authorization(host, pAuthInfo->scheme, &nt_auth_identity);
}
+ else if(retrieve_cached_authorization(host, pAuthInfo->scheme, &nt_auth_identity))
+ pAuthData = &nt_auth_identity;
else
/* use default credentials */
pAuthData = NULL;
@@ -715,6 +823,13 @@ static BOOL HTTP_DoAuthorization( http_request_t *lpwhr, LPCWSTR pszAuthValue,
pAuthData, NULL,
NULL, &pAuthInfo->cred,
&exp);
+
+ if(pAuthData && !domain_and_username) {
+ HeapFree(GetProcessHeap(), 0, nt_auth_identity.User);
+ HeapFree(GetProcessHeap(), 0, nt_auth_identity.Domain);
+ HeapFree(GetProcessHeap(), 0, nt_auth_identity.Password);
+ }
+
if (sec_status == SEC_E_OK)
{
PSecPkgInfoW sec_pkg_info;
diff --git a/dlls/wininet/internet.h b/dlls/wininet/internet.h
index 07b92d8..6e41f66 100644
--- a/dlls/wininet/internet.h
+++ b/dlls/wininet/internet.h
@@ -71,6 +71,27 @@ static inline LPWSTR heap_strdupW(LPCWSTR str)
return ret;
}
+static inline LPWSTR heap_strndupW(LPCWSTR str, UINT max_len)
+{
+ LPWSTR ret;
+ UINT len;
+
+ if(!str)
+ return NULL;
+
+ for(len=0; len<max_len; len++)
+ if(str[len] == '\0')
+ break;
+
+ ret = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*(len+1));
+ if(ret) {
+ memcpy(ret, str, sizeof(WCHAR)*len);
+ ret[len] = '\0';
+ }
+
+ return ret;
+}
+
static inline WCHAR *heap_strdupAtoW(const char *str)
{
LPWSTR ret = NULL;
More information about the wine-cvs
mailing list