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;
|
return FALSE;
|
||||||
auth_ptr = &request->authinfo;
|
auth_ptr = &request->authinfo;
|
||||||
auth_target = attr_authorization;
|
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;
|
username = request->connect->username;
|
||||||
password = request->connect->password;
|
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
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
auth_ptr = &request->proxy_authinfo;
|
auth_ptr = &request->proxy_authinfo;
|
||||||
auth_target = attr_proxy_authorization;
|
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;
|
username = request->connect->session->proxy_username;
|
||||||
password = request->connect->session->proxy_password;
|
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
|
|||||||
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
|
|||||||
{
|
{
|
||||||
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:
|
|||||||
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 )
|
|||||||
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)
|
|||||||
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)
|
|||||||
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
|
|||||||
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
|
|||||||
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
|
|||||||
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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user