winhttp: Send basic authorization credentials with the first request if they've been set.

Signed-off-by: Huw Davies <huw@codeweavers.com>
Signed-off-by: Hans Leidekker <hans@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Huw Davies 2017-10-02 09:47:27 +01:00 committed by Alexandre Julliard
parent 9c2cce0923
commit 6ce8624760
2 changed files with 57 additions and 3 deletions

View file

@ -1142,24 +1142,25 @@ static BOOL do_authorization( request_t *request, DWORD target, DWORD scheme_fla
const WCHAR *auth_target, *username, *password;
WCHAR auth_value[2048], *auth_reply;
DWORD len = sizeof(auth_value), len_scheme, flags;
BOOL ret;
BOOL ret, has_auth_value;
if (scheme == SCHEME_INVALID) return FALSE;
switch (target)
{
case WINHTTP_AUTH_TARGET_SERVER:
if (!get_authvalue( request, WINHTTP_QUERY_WWW_AUTHENTICATE, scheme_flag, auth_value, len ))
return FALSE;
has_auth_value = get_authvalue( request, WINHTTP_QUERY_WWW_AUTHENTICATE, scheme_flag, auth_value, len );
auth_ptr = &request->authinfo;
auth_target = attr_authorization;
if (request->creds[TARGET_SERVER][scheme].username)
{
if (scheme != SCHEME_BASIC && !has_auth_value) return FALSE;
username = request->creds[TARGET_SERVER][scheme].username;
password = request->creds[TARGET_SERVER][scheme].password;
}
else
{
if (!has_auth_value) return FALSE;
username = request->connect->username;
password = request->connect->password;
}
@ -2086,6 +2087,9 @@ static BOOL send_request( request_t *request, LPCWSTR headers, DWORD headers_len
if (connect->hostname)
add_host_header( request, WINHTTP_ADDREQ_FLAG_ADD_IF_NEW );
if (request->creds[TARGET_SERVER][SCHEME_BASIC].username)
do_authorization( request, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC );
if (total_len || (request->verb && !strcmpW( request->verb, postW )))
{
WCHAR length[21]; /* decimal long int + null */

View file

@ -2075,6 +2075,7 @@ static const char largeauth[] =
static const char unauthorized[] = "Unauthorized";
static const char hello_world[] = "Hello World";
static const char auth_unseen[] = "Auth Unseen";
struct server_info
{
@ -2134,6 +2135,15 @@ static DWORD CALLBACK server_thread(LPVOID param)
send(c, okmsg, sizeof okmsg - 1, 0);
send(c, page1, sizeof page1 - 1, 0);
}
if (strstr(buffer, "/auth_with_creds"))
{
send(c, okauthmsg, sizeof okauthmsg - 1, 0);
if (strstr(buffer, "Authorization: Basic dXNlcjpwd2Q="))
send(c, hello_world, sizeof hello_world - 1, 0);
else
send(c, auth_unseen, sizeof auth_unseen - 1, 0);
continue;
}
if (strstr(buffer, "/auth"))
{
if (strstr(buffer, "Authorization: Basic dXNlcjpwd2Q="))
@ -2309,6 +2319,7 @@ static void test_basic_request(int port, const WCHAR *verb, const WCHAR *path)
static void test_basic_authentication(int port)
{
static const WCHAR authW[] = {'/','a','u','t','h',0};
static const WCHAR auth_with_credsW[] = {'/','a','u','t','h','_','w','i','t','h','_','c','r','e','d','s',0};
static WCHAR userW[] = {'u','s','e','r',0};
static WCHAR passW[] = {'p','w','d',0};
static WCHAR pass2W[] = {'p','w','d','2',0};
@ -2472,6 +2483,45 @@ static void test_basic_authentication(int port)
WinHttpCloseHandle(con);
WinHttpCloseHandle(ses);
/* now set the credentials first to show that they get sent with the first request */
ses = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0);
ok(ses != NULL, "failed to open session %u\n", GetLastError());
con = WinHttpConnect(ses, localhostW, port, 0);
ok(con != NULL, "failed to open a connection %u\n", GetLastError());
req = WinHttpOpenRequest(con, NULL, auth_with_credsW, NULL, NULL, NULL, 0);
ok(req != NULL, "failed to open a request %u\n", GetLastError());
ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, passW, NULL);
ok(ret, "failed to set credentials %u\n", GetLastError());
ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
ok(ret, "failed to send request %u\n", GetLastError());
ret = WinHttpReceiveResponse(req, NULL);
ok(ret, "failed to receive response %u\n", GetLastError());
status = 0xdeadbeef;
size = sizeof(status);
ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
ok(ret, "failed to query status code %u\n", GetLastError());
ok(status == HTTP_STATUS_OK, "request failed unexpectedly %u\n", status);
size = 0;
ret = WinHttpReadData(req, buffer, sizeof(buffer), &size);
error = GetLastError();
ok(ret || broken(error == ERROR_WINHTTP_SHUTDOWN || error == ERROR_WINHTTP_TIMEOUT) /* XP */, "failed to read data %u\n", GetLastError());
if (ret)
{
ok(size == 11, "expected 11, got %u\n", size);
ok(!memcmp(buffer, hello_world, 11), "got %s\n", buffer);
}
WinHttpCloseHandle(req);
WinHttpCloseHandle(con);
WinHttpCloseHandle(ses);
/* credentials set with WinHttpSetCredentials take precedence over those set through options */
ses = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0);