Commit 3b8a8d31 authored by Hans Leidekker's avatar Hans Leidekker Committed by Alexandre Julliard

winhttp: Store credentials set with WinHttpSetCredentials separately from…

winhttp: Store credentials set with WinHttpSetCredentials separately from username and password set through options.
parent c5a96990
......@@ -1572,8 +1572,16 @@ static BOOL do_authorization( request_t *request, DWORD target, DWORD scheme_fla
return FALSE;
auth_ptr = &request->authinfo;
auth_target = attr_authorization;
username = request->connect->username;
password = request->connect->password;
if (request->creds[TARGET_SERVER][scheme].username)
{
username = request->creds[TARGET_SERVER][scheme].username;
password = request->creds[TARGET_SERVER][scheme].password;
}
else
{
username = request->connect->username;
password = request->connect->password;
}
break;
case WINHTTP_AUTH_TARGET_PROXY:
......@@ -1581,8 +1589,16 @@ static BOOL do_authorization( request_t *request, DWORD target, DWORD scheme_fla
return FALSE;
auth_ptr = &request->proxy_authinfo;
auth_target = attr_proxy_authorization;
username = request->connect->session->proxy_username;
password = request->connect->session->proxy_password;
if (request->creds[TARGET_PROXY][scheme].username)
{
username = request->creds[TARGET_PROXY][scheme].username;
password = request->creds[TARGET_PROXY][scheme].password;
}
else
{
username = request->connect->session->proxy_username;
password = request->connect->session->proxy_password;
}
break;
default:
......@@ -1766,11 +1782,12 @@ static BOOL do_authorization( request_t *request, DWORD target, DWORD scheme_fla
return ret;
}
static BOOL set_credentials( request_t *request, DWORD target, DWORD scheme, const WCHAR *username,
static BOOL set_credentials( request_t *request, DWORD target, DWORD scheme_flag, const WCHAR *username,
const WCHAR *password )
{
if ((scheme == WINHTTP_AUTH_SCHEME_BASIC || scheme == WINHTTP_AUTH_SCHEME_DIGEST) &&
(!username || !password))
enum auth_scheme scheme = scheme_from_flag( scheme_flag );
if (scheme == SCHEME_INVALID || ((scheme == SCHEME_BASIC || scheme == SCHEME_DIGEST) && (!username || !password)))
{
set_last_error( ERROR_INVALID_PARAMETER );
return FALSE;
......@@ -1779,24 +1796,24 @@ static BOOL set_credentials( request_t *request, DWORD target, DWORD scheme, con
{
case WINHTTP_AUTH_TARGET_SERVER:
{
heap_free( request->connect->username );
if (!username) request->connect->username = NULL;
else if (!(request->connect->username = strdupW( username ))) return FALSE;
heap_free( request->creds[TARGET_SERVER][scheme].username );
if (!username) request->creds[TARGET_SERVER][scheme].username = NULL;
else if (!(request->creds[TARGET_SERVER][scheme].username = strdupW( username ))) return FALSE;
heap_free( request->connect->password );
if (!password) request->connect->password = NULL;
else if (!(request->connect->password = strdupW( password ))) return FALSE;
heap_free( request->creds[TARGET_SERVER][scheme].password );
if (!password) request->creds[TARGET_SERVER][scheme].password = NULL;
else if (!(request->creds[TARGET_SERVER][scheme].password = strdupW( password ))) return FALSE;
break;
}
case WINHTTP_AUTH_TARGET_PROXY:
{
heap_free( request->connect->session->proxy_username );
if (!username) request->connect->session->proxy_username = NULL;
else if (!(request->connect->session->proxy_username = strdupW( username ))) return FALSE;
heap_free( request->creds[TARGET_PROXY][scheme].username );
if (!username) request->creds[TARGET_PROXY][scheme].username = NULL;
else if (!(request->creds[TARGET_PROXY][scheme].username = strdupW( username ))) return FALSE;
heap_free( request->connect->session->proxy_password );
if (!password) request->connect->session->proxy_password = NULL;
else if (!(request->connect->session->proxy_password = strdupW( password ))) return FALSE;
heap_free( request->creds[TARGET_PROXY][scheme].password );
if (!password) request->creds[TARGET_PROXY][scheme].password = NULL;
else if (!(request->creds[TARGET_PROXY][scheme].password = strdupW( password ))) return FALSE;
break;
}
default:
......
......@@ -555,7 +555,7 @@ end:
static void request_destroy( object_header_t *hdr )
{
request_t *request = (request_t *)hdr;
unsigned int i;
unsigned int i, j;
TRACE("%p\n", request);
......@@ -587,6 +587,14 @@ static void request_destroy( object_header_t *hdr )
heap_free( request->headers );
for (i = 0; i < request->num_accept_types; i++) heap_free( request->accept_types[i] );
heap_free( request->accept_types );
for (i = 0; i < TARGET_MAX; i++)
{
for (j = 0; j < SCHEME_MAX; j++)
{
heap_free( request->creds[i][j].username );
heap_free( request->creds[i][j].password );
}
}
heap_free( request );
}
......
......@@ -1986,8 +1986,9 @@ 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 userW[] = {'u','s','e','r',0};
static const WCHAR passW[] = {'p','w','d',0};
static WCHAR userW[] = {'u','s','e','r',0};
static WCHAR passW[] = {'p','w','d',0};
static WCHAR pass2W[] = {'p','w','d','2',0};
HINTERNET ses, con, req;
DWORD status, size, error, supported, first, target;
BOOL ret;
......@@ -2120,6 +2121,76 @@ static void test_basic_authentication(int port)
WinHttpCloseHandle(req);
WinHttpCloseHandle(con);
WinHttpCloseHandle(ses);
/* credentials set with WinHttpSetCredentials take precedence over those set through options */
ses = WinHttpOpen(test_useragent, 0, 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, authW, 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 = WinHttpSetOption(req, WINHTTP_OPTION_USERNAME, userW, lstrlenW(userW));
ok(ret, "failed to set username %u\n", GetLastError());
ret = WinHttpSetOption(req, WINHTTP_OPTION_PASSWORD, pass2W, lstrlenW(pass2W));
ok(ret, "failed to set password %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 == 200, "request failed unexpectedly %u\n", status);
WinHttpCloseHandle(req);
WinHttpCloseHandle(con);
WinHttpCloseHandle(ses);
ses = WinHttpOpen(test_useragent, 0, 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, authW, NULL, NULL, NULL, 0);
ok(req != NULL, "failed to open a request %u\n", GetLastError());
ret = WinHttpSetOption(req, WINHTTP_OPTION_USERNAME, userW, lstrlenW(userW));
ok(ret, "failed to set username %u\n", GetLastError());
ret = WinHttpSetOption(req, WINHTTP_OPTION_PASSWORD, pass2W, lstrlenW(passW));
ok(ret, "failed to set password %u\n", GetLastError());
ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, pass2W, 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 == 401, "request failed unexpectedly %u\n", status);
WinHttpCloseHandle(req);
WinHttpCloseHandle(con);
WinHttpCloseHandle(ses);
}
static void test_no_headers(int port)
......
......@@ -148,6 +148,14 @@ typedef struct
BOOL is_request; /* part of request headers? */
} header_t;
enum auth_target
{
TARGET_INVALID = -1,
TARGET_SERVER,
TARGET_PROXY,
TARGET_MAX
};
enum auth_scheme
{
SCHEME_INVALID = -1,
......@@ -155,7 +163,8 @@ enum auth_scheme
SCHEME_NTLM,
SCHEME_PASSPORT,
SCHEME_DIGEST,
SCHEME_NEGOTIATE
SCHEME_NEGOTIATE,
SCHEME_MAX
};
struct authinfo
......@@ -206,6 +215,11 @@ typedef struct
HANDLE task_thread;
struct list task_queue;
CRITICAL_SECTION task_cs;
struct
{
WCHAR *username;
WCHAR *password;
} creds[TARGET_MAX][SCHEME_MAX];
} request_t;
typedef struct _task_header_t task_header_t;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment