[PATCH] wininet: Option INTERNET_OPTION_END_BROWSER_SESSION clears cached credentials
Alistair Leslie-Hughes
leslie_alistair at hotmail.com
Wed Sep 18 19:47:44 CDT 2019
Signed-off-by: Alistair Leslie-Hughes <leslie_alistair at hotmail.com>
---
dlls/wininet/http.c | 31 ++++++++++++++
dlls/wininet/internet.c | 1 +
dlls/wininet/internet.h | 1 +
dlls/wininet/tests/http.c | 87 +++++++++++++++++++++++++++++++++++++++
4 files changed, 120 insertions(+)
diff --git a/dlls/wininet/http.c b/dlls/wininet/http.c
index 5844a7c7d6..60dab62441 100644
--- a/dlls/wininet/http.c
+++ b/dlls/wininet/http.c
@@ -1019,6 +1019,37 @@ static void cache_authorization(LPWSTR host, LPWSTR scheme,
LeaveCriticalSection(&authcache_cs);
}
+void free_authorization_cache(void)
+{
+ authorizationData *ad, *sa_safe;
+ basicAuthorizationData *basic, *basic_safe;
+
+ EnterCriticalSection(&authcache_cs);
+
+ LIST_FOR_EACH_ENTRY_SAFE(basic, basic_safe, &basicAuthorizationCache, basicAuthorizationData, entry)
+ {
+ heap_free(basic->host);
+ heap_free(basic->realm);
+ heap_free(basic->authorization);
+
+ list_remove(&basic->entry);
+ heap_free(basic);
+ }
+
+ LIST_FOR_EACH_ENTRY_SAFE(ad, sa_safe, &authorizationCache, authorizationData, entry)
+ {
+ heap_free(ad->host);
+ heap_free(ad->scheme);
+ heap_free(ad->user);
+ heap_free(ad->password);
+ heap_free(ad->domain);
+ list_remove(&ad->entry);
+ heap_free(ad);
+ }
+
+ LeaveCriticalSection(&authcache_cs);
+}
+
static BOOL HTTP_DoAuthorization( http_request_t *request, LPCWSTR pszAuthValue,
struct HttpAuthInfo **ppAuthInfo,
LPWSTR domain_and_username, LPWSTR password,
diff --git a/dlls/wininet/internet.c b/dlls/wininet/internet.c
index b7aa5fe330..266100861d 100644
--- a/dlls/wininet/internet.c
+++ b/dlls/wininet/internet.c
@@ -2821,6 +2821,7 @@ BOOL WINAPI InternetSetOptionW(HINTERNET hInternet, DWORD dwOption,
case INTERNET_OPTION_END_BROWSER_SESSION:
FIXME("Option INTERNET_OPTION_END_BROWSER_SESSION: semi-stub\n");
free_cookie();
+ free_authorization_cache();
break;
case INTERNET_OPTION_CONNECTED_STATE:
FIXME("Option INTERNET_OPTION_CONNECTED_STATE: STUB\n");
diff --git a/dlls/wininet/internet.h b/dlls/wininet/internet.h
index 40e51bec32..8954d071f9 100644
--- a/dlls/wininet/internet.h
+++ b/dlls/wininet/internet.h
@@ -456,6 +456,7 @@ static inline req_file_t *req_file_addref(req_file_t *req_file)
BOOL init_urlcache(void) DECLSPEC_HIDDEN;
void free_urlcache(void) DECLSPEC_HIDDEN;
void free_cookie(void) DECLSPEC_HIDDEN;
+void free_authorization_cache(void) DECLSPEC_HIDDEN;
void init_winsock(void) DECLSPEC_HIDDEN;
diff --git a/dlls/wininet/tests/http.c b/dlls/wininet/tests/http.c
index b61d5c7030..f1a647346e 100644
--- a/dlls/wininet/tests/http.c
+++ b/dlls/wininet/tests/http.c
@@ -4502,6 +4502,92 @@ static void test_basic_auth_credentials_reuse(int port)
InternetCloseHandle( ses );
}
+static void test_basic_auth_credentials_end_session(int port)
+{
+ HINTERNET ses, con, req;
+ DWORD status, size;
+ BOOL ret;
+ char buffer[0x40];
+
+ ses = InternetOpenA( "winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0 );
+ ok( ses != NULL, "InternetOpenA failed\n" );
+
+ con = InternetConnectA( ses, "localhost", port, "user", "pwd",
+ INTERNET_SERVICE_HTTP, 0, 0 );
+ ok( con != NULL, "InternetConnectA failed %u\n", GetLastError() );
+
+ req = HttpOpenRequestA( con, "HEAD", "/upload.txt", NULL, NULL, NULL, 0, 0 );
+ ok( req != NULL, "HttpOpenRequestA failed %u\n", GetLastError() );
+
+ ret = HttpSendRequestA( req, NULL, 0, NULL, 0 );
+ ok( ret, "HttpSendRequestA failed %u\n", GetLastError() );
+
+ size = sizeof(buffer);
+ SetLastError(0xdeadbeef);
+ ret = InternetQueryOptionA(req, INTERNET_OPTION_USERNAME, buffer, &size);
+ ok(ret, "unexpected failure %u\n", GetLastError());
+ ok(!strcmp(buffer, "user"), "got %s\n", buffer);
+ ok(size == 4, "got %u\n", size);
+
+ size = sizeof(buffer);
+ SetLastError(0xdeadbeef);
+ ret = InternetQueryOptionA(req, INTERNET_OPTION_PASSWORD, buffer, &size);
+ ok(ret, "unexpected failure %u\n", GetLastError());
+ ok(!strcmp(buffer, "pwd"), "got %s\n", buffer);
+ ok(size == 3, "got %u\n", size);
+
+ status = 0xdeadbeef;
+ size = sizeof(status);
+ ret = HttpQueryInfoA( req, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, &status, &size, NULL );
+ ok( ret, "HttpQueryInfoA failed %u\n", GetLastError() );
+ ok( status == HTTP_STATUS_OK, "got %u\n", status );
+
+ InternetCloseHandle( req );
+ InternetCloseHandle( con );
+ InternetCloseHandle( ses );
+
+ ses = InternetOpenA( "winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0 );
+ ok( ses != NULL, "InternetOpenA failed\n" );
+
+ /* Clear the cached credentials */
+ ret = InternetSetOptionA(ses, INTERNET_OPTION_END_BROWSER_SESSION, NULL, 0);
+ ok(ret, "unexpected failure %u\n", GetLastError());
+
+ con = InternetConnectA( ses, "localhost", port, NULL, NULL,
+ INTERNET_SERVICE_HTTP, 0, 0 );
+ ok( con != NULL, "InternetConnectA failed %u\n", GetLastError() );
+
+ req = HttpOpenRequestA( con, "PUT", "/upload2.txt", NULL, NULL, NULL, 0, 0 );
+ ok( req != NULL, "HttpOpenRequestA failed %u\n", GetLastError() );
+
+ ret = HttpSendRequestA( req, NULL, 0, NULL, 0 );
+ ok( ret, "HttpSendRequestA failed %u\n", GetLastError() );
+
+ size = sizeof(buffer);
+ SetLastError(0xdeadbeef);
+ ret = InternetQueryOptionA(req, INTERNET_OPTION_USERNAME, buffer, &size);
+ ok(ret, "unexpected failure %u\n", GetLastError());
+ ok(!strcmp(buffer, ""), "got %s\n", buffer);
+ ok(size == 0, "got %u\n", size);
+
+ size = sizeof(buffer);
+ SetLastError(0xdeadbeef);
+ ret = InternetQueryOptionA(req, INTERNET_OPTION_PASSWORD, buffer, &size);
+ ok(ret, "unexpected failure %u\n", GetLastError());
+ ok(!strcmp(buffer, ""), "got %s\n", buffer);
+ ok(size == 0, "got %u\n", size);
+
+ status = 0xdeadbeef;
+ size = sizeof(status);
+ ret = HttpQueryInfoA( req, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, &status, &size, NULL );
+ ok( ret, "HttpQueryInfoA failed %u\n", GetLastError() );
+ ok( status == HTTP_STATUS_BAD_REQUEST, "got %u\n", status );
+
+ InternetCloseHandle( req );
+ InternetCloseHandle( con );
+ InternetCloseHandle( ses );
+}
+
static void test_async_read(int port)
{
HINTERNET ses, con, req;
@@ -5696,6 +5782,7 @@ static void test_http_connection(void)
test_request_content_length(si.port);
test_accept_encoding(si.port);
test_basic_auth_credentials_reuse(si.port);
+ test_basic_auth_credentials_end_session(si.port);
test_async_read(si.port);
test_http_read(si.port);
test_connection_break(si.port);
--
2.17.1
More information about the wine-devel
mailing list