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 ...@@ -1572,8 +1572,16 @@ static BOOL do_authorization( request_t *request, DWORD target, DWORD scheme_fla
return FALSE; return FALSE;
auth_ptr = &request->authinfo; auth_ptr = &request->authinfo;
auth_target = attr_authorization; auth_target = attr_authorization;
username = request->connect->username; if (request->creds[TARGET_SERVER][scheme].username)
password = request->connect->password; {
username = request->creds[TARGET_SERVER][scheme].username;
password = request->creds[TARGET_SERVER][scheme].password;
}
else
{
username = request->connect->username;
password = request->connect->password;
}
break; break;
case WINHTTP_AUTH_TARGET_PROXY: case WINHTTP_AUTH_TARGET_PROXY:
...@@ -1581,8 +1589,16 @@ static BOOL do_authorization( request_t *request, DWORD target, DWORD scheme_fla ...@@ -1581,8 +1589,16 @@ static BOOL do_authorization( request_t *request, DWORD target, DWORD scheme_fla
return FALSE; return FALSE;
auth_ptr = &request->proxy_authinfo; auth_ptr = &request->proxy_authinfo;
auth_target = attr_proxy_authorization; auth_target = attr_proxy_authorization;
username = request->connect->session->proxy_username; if (request->creds[TARGET_PROXY][scheme].username)
password = request->connect->session->proxy_password; {
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; break;
default: default:
...@@ -1766,11 +1782,12 @@ static BOOL do_authorization( request_t *request, DWORD target, DWORD scheme_fla ...@@ -1766,11 +1782,12 @@ static BOOL do_authorization( request_t *request, DWORD target, DWORD scheme_fla
return ret; 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 ) const WCHAR *password )
{ {
if ((scheme == WINHTTP_AUTH_SCHEME_BASIC || scheme == WINHTTP_AUTH_SCHEME_DIGEST) && enum auth_scheme scheme = scheme_from_flag( scheme_flag );
(!username || !password))
if (scheme == SCHEME_INVALID || ((scheme == SCHEME_BASIC || scheme == SCHEME_DIGEST) && (!username || !password)))
{ {
set_last_error( ERROR_INVALID_PARAMETER ); set_last_error( ERROR_INVALID_PARAMETER );
return FALSE; return FALSE;
...@@ -1779,24 +1796,24 @@ static BOOL set_credentials( request_t *request, DWORD target, DWORD scheme, con ...@@ -1779,24 +1796,24 @@ static BOOL set_credentials( request_t *request, DWORD target, DWORD scheme, con
{ {
case WINHTTP_AUTH_TARGET_SERVER: case WINHTTP_AUTH_TARGET_SERVER:
{ {
heap_free( request->connect->username ); heap_free( request->creds[TARGET_SERVER][scheme].username );
if (!username) request->connect->username = NULL; if (!username) request->creds[TARGET_SERVER][scheme].username = NULL;
else if (!(request->connect->username = strdupW( username ))) return FALSE; else if (!(request->creds[TARGET_SERVER][scheme].username = strdupW( username ))) return FALSE;
heap_free( request->connect->password ); heap_free( request->creds[TARGET_SERVER][scheme].password );
if (!password) request->connect->password = NULL; if (!password) request->creds[TARGET_SERVER][scheme].password = NULL;
else if (!(request->connect->password = strdupW( password ))) return FALSE; else if (!(request->creds[TARGET_SERVER][scheme].password = strdupW( password ))) return FALSE;
break; break;
} }
case WINHTTP_AUTH_TARGET_PROXY: case WINHTTP_AUTH_TARGET_PROXY:
{ {
heap_free( request->connect->session->proxy_username ); heap_free( request->creds[TARGET_PROXY][scheme].username );
if (!username) request->connect->session->proxy_username = NULL; if (!username) request->creds[TARGET_PROXY][scheme].username = NULL;
else if (!(request->connect->session->proxy_username = strdupW( username ))) return FALSE; else if (!(request->creds[TARGET_PROXY][scheme].username = strdupW( username ))) return FALSE;
heap_free( request->connect->session->proxy_password ); heap_free( request->creds[TARGET_PROXY][scheme].password );
if (!password) request->connect->session->proxy_password = NULL; if (!password) request->creds[TARGET_PROXY][scheme].password = NULL;
else if (!(request->connect->session->proxy_password = strdupW( password ))) return FALSE; else if (!(request->creds[TARGET_PROXY][scheme].password = strdupW( password ))) return FALSE;
break; break;
} }
default: default:
......
...@@ -555,7 +555,7 @@ end: ...@@ -555,7 +555,7 @@ end:
static void request_destroy( object_header_t *hdr ) static void request_destroy( object_header_t *hdr )
{ {
request_t *request = (request_t *)hdr; request_t *request = (request_t *)hdr;
unsigned int i; unsigned int i, j;
TRACE("%p\n", request); TRACE("%p\n", request);
...@@ -587,6 +587,14 @@ static void request_destroy( object_header_t *hdr ) ...@@ -587,6 +587,14 @@ static void request_destroy( object_header_t *hdr )
heap_free( request->headers ); heap_free( request->headers );
for (i = 0; i < request->num_accept_types; i++) heap_free( request->accept_types[i] ); for (i = 0; i < request->num_accept_types; i++) heap_free( request->accept_types[i] );
heap_free( request->accept_types ); 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 ); heap_free( request );
} }
......
...@@ -1986,8 +1986,9 @@ static void test_basic_request(int port, const WCHAR *verb, const WCHAR *path) ...@@ -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 void test_basic_authentication(int port)
{ {
static const WCHAR authW[] = {'/','a','u','t','h',0}; static const WCHAR authW[] = {'/','a','u','t','h',0};
static const WCHAR userW[] = {'u','s','e','r',0}; static WCHAR userW[] = {'u','s','e','r',0};
static const WCHAR passW[] = {'p','w','d',0}; static WCHAR passW[] = {'p','w','d',0};
static WCHAR pass2W[] = {'p','w','d','2',0};
HINTERNET ses, con, req; HINTERNET ses, con, req;
DWORD status, size, error, supported, first, target; DWORD status, size, error, supported, first, target;
BOOL ret; BOOL ret;
...@@ -2120,6 +2121,76 @@ static void test_basic_authentication(int port) ...@@ -2120,6 +2121,76 @@ static void test_basic_authentication(int port)
WinHttpCloseHandle(req); WinHttpCloseHandle(req);
WinHttpCloseHandle(con); WinHttpCloseHandle(con);
WinHttpCloseHandle(ses); 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) static void test_no_headers(int port)
......
...@@ -148,6 +148,14 @@ typedef struct ...@@ -148,6 +148,14 @@ typedef struct
BOOL is_request; /* part of request headers? */ BOOL is_request; /* part of request headers? */
} header_t; } header_t;
enum auth_target
{
TARGET_INVALID = -1,
TARGET_SERVER,
TARGET_PROXY,
TARGET_MAX
};
enum auth_scheme enum auth_scheme
{ {
SCHEME_INVALID = -1, SCHEME_INVALID = -1,
...@@ -155,7 +163,8 @@ enum auth_scheme ...@@ -155,7 +163,8 @@ enum auth_scheme
SCHEME_NTLM, SCHEME_NTLM,
SCHEME_PASSPORT, SCHEME_PASSPORT,
SCHEME_DIGEST, SCHEME_DIGEST,
SCHEME_NEGOTIATE SCHEME_NEGOTIATE,
SCHEME_MAX
}; };
struct authinfo struct authinfo
...@@ -206,6 +215,11 @@ typedef struct ...@@ -206,6 +215,11 @@ typedef struct
HANDLE task_thread; HANDLE task_thread;
struct list task_queue; struct list task_queue;
CRITICAL_SECTION task_cs; CRITICAL_SECTION task_cs;
struct
{
WCHAR *username;
WCHAR *password;
} creds[TARGET_MAX][SCHEME_MAX];
} request_t; } request_t;
typedef struct _task_header_t task_header_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