winhttp: Store credentials set with WinHttpSetCredentials separately from username and password set through options.
This commit is contained in:
parent
c5a969904f
commit
3b8a8d31dc
|
@ -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;
|
||||
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;
|
||||
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;
|
||||
|
|
Loading…
Reference in New Issue