From 24e1fcc7a0bc34ce45231b34b310369e4cddb197 Mon Sep 17 00:00:00 2001 From: Hans Leidekker Date: Thu, 22 Apr 2010 16:34:48 +0200 Subject: [PATCH] winhttp: Support setting and querying credentials on request handles. --- dlls/winhttp/session.c | 78 ++++++++++++++++++++++++++- dlls/winhttp/tests/winhttp.c | 123 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 199 insertions(+), 2 deletions(-) diff --git a/dlls/winhttp/session.c b/dlls/winhttp/session.c index cd5ebed65e9..82da7211070 100644 --- a/dlls/winhttp/session.c +++ b/dlls/winhttp/session.c @@ -547,6 +547,18 @@ static void request_destroy( object_header_t *hdr ) heap_free( request ); } +static void str_to_buffer( WCHAR *buffer, const WCHAR *str, LPDWORD buflen ) +{ + int len = 0; + if (str) len = strlenW( str ); + if (buffer && *buflen > len) + { + memcpy( buffer, str, len * sizeof(WCHAR) ); + buffer[len] = 0; + } + *buflen = len * sizeof(WCHAR); +} + static BOOL request_query_option( object_header_t *hdr, DWORD option, LPVOID buffer, LPDWORD buflen ) { request_t *request = (request_t *)hdr; @@ -615,6 +627,23 @@ static BOOL request_query_option( object_header_t *hdr, DWORD option, LPVOID buf *(DWORD *)buffer = request->recv_timeout; *buflen = sizeof(DWORD); return TRUE; + + case WINHTTP_OPTION_USERNAME: + str_to_buffer( buffer, request->connect->username, buflen ); + return TRUE; + + case WINHTTP_OPTION_PASSWORD: + str_to_buffer( buffer, request->connect->password, buflen ); + return TRUE; + + case WINHTTP_OPTION_PROXY_USERNAME: + str_to_buffer( buffer, request->connect->session->proxy_username, buflen ); + return TRUE; + + case WINHTTP_OPTION_PROXY_PASSWORD: + str_to_buffer( buffer, request->connect->session->proxy_password, buflen ); + return TRUE; + default: FIXME("unimplemented option %u\n", option); set_last_error( ERROR_INVALID_PARAMETER ); @@ -622,6 +651,19 @@ static BOOL request_query_option( object_header_t *hdr, DWORD option, LPVOID buf } } +static WCHAR *buffer_to_str( WCHAR *buffer, DWORD buflen ) +{ + WCHAR *ret; + if ((ret = heap_alloc( (buflen + 1) * sizeof(WCHAR)))) + { + memcpy( ret, buffer, buflen * sizeof(WCHAR) ); + ret[buflen] = 0; + return ret; + } + set_last_error( ERROR_OUTOFMEMORY ); + return NULL; +} + static BOOL request_set_option( object_header_t *hdr, DWORD option, LPVOID buffer, DWORD buflen ) { request_t *request = (request_t *)hdr; @@ -681,8 +723,7 @@ static BOOL request_set_option( object_header_t *hdr, DWORD option, LPVOID buffe return TRUE; } case WINHTTP_OPTION_SECURITY_FLAGS: - FIXME("WINHTTP_OPTION_SECURITY_FLAGS unimplemented (%08x)\n", - *(DWORD *)buffer); + FIXME("WINHTTP_OPTION_SECURITY_FLAGS unimplemented (%08x)\n", *(DWORD *)buffer); return TRUE; case WINHTTP_OPTION_RESOLVE_TIMEOUT: request->resolve_timeout = *(DWORD *)buffer; @@ -696,6 +737,39 @@ static BOOL request_set_option( object_header_t *hdr, DWORD option, LPVOID buffe case WINHTTP_OPTION_RECEIVE_TIMEOUT: request->recv_timeout = *(DWORD *)buffer; return TRUE; + + case WINHTTP_OPTION_USERNAME: + { + connect_t *connect = request->connect; + + heap_free( connect->username ); + if (!(connect->username = buffer_to_str( buffer, buflen ))) return FALSE; + return TRUE; + } + case WINHTTP_OPTION_PASSWORD: + { + connect_t *connect = request->connect; + + heap_free( connect->password ); + if (!(connect->password = buffer_to_str( buffer, buflen ))) return FALSE; + return TRUE; + } + case WINHTTP_OPTION_PROXY_USERNAME: + { + session_t *session = request->connect->session; + + heap_free( session->proxy_username ); + if (!(session->proxy_username = buffer_to_str( buffer, buflen ))) return FALSE; + return TRUE; + } + case WINHTTP_OPTION_PROXY_PASSWORD: + { + session_t *session = request->connect->session; + + heap_free( session->proxy_password ); + if (!(session->proxy_password = buffer_to_str( buffer, buflen ))) return FALSE; + return TRUE; + } default: FIXME("unimplemented option %u\n", option); set_last_error( ERROR_INVALID_PARAMETER ); diff --git a/dlls/winhttp/tests/winhttp.c b/dlls/winhttp/tests/winhttp.c index 94346e258ec..9d3a47380f7 100644 --- a/dlls/winhttp/tests/winhttp.c +++ b/dlls/winhttp/tests/winhttp.c @@ -1677,6 +1677,128 @@ static void test_resolve_timeout(void) WinHttpCloseHandle(ses); } +static void test_credentials(void) +{ + static const WCHAR hostnameW[] = {'l','o','c','a','l','h','o','s','t',0}; + static WCHAR userW[] = {'u','s','e','r',0}; + static WCHAR passW[] = {'p','a','s','s',0}; + static WCHAR proxy_userW[] = {'p','r','o','x','y','u','s','e','r',0}; + static WCHAR proxy_passW[] = {'p','r','o','x','y','p','a','s','s',0}; + HANDLE ses, con, req; + DWORD size, error; + WCHAR buffer[32]; + BOOL ret; + + ses = WinHttpOpen(test_useragent, 0, proxy_userW, proxy_passW, 0); + ok(ses != NULL, "failed to open session %u\n", GetLastError()); + + con = WinHttpConnect(ses, hostnameW, 0, 0); + ok(con != NULL, "failed to open a connection %u\n", GetLastError()); + + req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0); + ok(req != NULL, "failed to open a request %u\n", GetLastError()); + + size = sizeof(buffer)/sizeof(WCHAR); + ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_USERNAME, &buffer, &size); + ok(ret, "failed to query proxy username %u\n", GetLastError()); + ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer)); + ok(!size, "expected 0, got %u\n", size); + + size = sizeof(buffer)/sizeof(WCHAR); + ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_PASSWORD, &buffer, &size); + ok(ret, "failed to query proxy password %u\n", GetLastError()); + ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer)); + ok(!size, "expected 0, got %u\n", size); + + ret = WinHttpSetOption(req, WINHTTP_OPTION_PROXY_USERNAME, proxy_userW, lstrlenW(proxy_userW)); + ok(ret, "failed to set username %u\n", GetLastError()); + + size = sizeof(buffer)/sizeof(WCHAR); + ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_USERNAME, &buffer, &size); + ok(ret, "failed to query proxy username %u\n", GetLastError()); + ok(!winetest_strcmpW(buffer, proxy_userW), "unexpected result %s\n", wine_dbgstr_w(buffer)); + ok(size == lstrlenW(proxy_userW) * sizeof(WCHAR), "unexpected result %u\n", size); + + size = sizeof(buffer)/sizeof(WCHAR); + ret = WinHttpQueryOption(req, WINHTTP_OPTION_USERNAME, &buffer, &size); + ok(ret, "failed to query username %u\n", GetLastError()); + ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer)); + ok(!size, "expected 0, got %u\n", size); + + size = sizeof(buffer)/sizeof(WCHAR); + ret = WinHttpQueryOption(req, WINHTTP_OPTION_PASSWORD, &buffer, &size); + ok(ret, "failed to query password %u\n", GetLastError()); + ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer)); + ok(!size, "expected 0, got %u\n", size); + + ret = WinHttpSetOption(req, WINHTTP_OPTION_PROXY_PASSWORD, proxy_passW, lstrlenW(proxy_passW)); + ok(ret, "failed to set proxy password %u\n", GetLastError()); + + size = sizeof(buffer)/sizeof(WCHAR); + ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_PASSWORD, &buffer, &size); + ok(ret, "failed to query proxy password %u\n", GetLastError()); + ok(!winetest_strcmpW(buffer, proxy_passW), "unexpected result %s\n", wine_dbgstr_w(buffer)); + ok(size == lstrlenW(proxy_passW) * sizeof(WCHAR), "unexpected result %u\n", size); + + ret = WinHttpSetOption(req, WINHTTP_OPTION_USERNAME, userW, lstrlenW(userW)); + ok(ret, "failed to set username %u\n", GetLastError()); + + size = sizeof(buffer)/sizeof(WCHAR); + ret = WinHttpQueryOption(req, WINHTTP_OPTION_USERNAME, &buffer, &size); + ok(ret, "failed to query username %u\n", GetLastError()); + ok(!winetest_strcmpW(buffer, userW), "unexpected result %s\n", wine_dbgstr_w(buffer)); + ok(size == lstrlenW(userW) * sizeof(WCHAR), "unexpected result %u\n", size); + + ret = WinHttpSetOption(req, WINHTTP_OPTION_PASSWORD, passW, lstrlenW(passW)); + ok(ret, "failed to set password %u\n", GetLastError()); + + size = sizeof(buffer)/sizeof(WCHAR); + ret = WinHttpQueryOption(req, WINHTTP_OPTION_PASSWORD, &buffer, &size); + ok(ret, "failed to query password %u\n", GetLastError()); + ok(!winetest_strcmpW(buffer, passW), "unexpected result %s\n", wine_dbgstr_w(buffer)); + ok(size == lstrlenW(passW) * sizeof(WCHAR), "unexpected result %u\n", size); + + WinHttpCloseHandle(req); + + req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0); + ok(req != NULL, "failed to open a request %u\n", GetLastError()); + + SetLastError(0xdeadbeef); + ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, NULL, NULL); + error = GetLastError(); + ok(!ret, "expected failure\n"); + ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error); + + SetLastError(0xdeadbeef); + ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, NULL, passW, NULL); + error = GetLastError(); + ok(!ret, "expected failure\n"); + ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error); + + ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, passW, NULL); + ok(ret, "failed to set credentials %u\n", GetLastError()); + + size = sizeof(buffer)/sizeof(WCHAR); + ret = WinHttpQueryOption(req, WINHTTP_OPTION_USERNAME, &buffer, &size); + ok(ret, "failed to query username %u\n", GetLastError()); + todo_wine { + ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer)); + ok(!size, "expected 0, got %u\n", size); + } + + size = sizeof(buffer)/sizeof(WCHAR); + ret = WinHttpQueryOption(req, WINHTTP_OPTION_PASSWORD, &buffer, &size); + ok(ret, "failed to query password %u\n", GetLastError()); + todo_wine { + ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer)); + ok(!size, "expected 0, got %u\n", size); + } + + WinHttpCloseHandle(req); + WinHttpCloseHandle(con); + WinHttpCloseHandle(ses); +} + START_TEST (winhttp) { test_OpenRequest(); @@ -1691,4 +1813,5 @@ START_TEST (winhttp) test_empty_headers_param(); test_Timeouts(); test_resolve_timeout(); + test_credentials(); } -- 2.11.4.GIT