From: Dmitry Timoshkov Subject: [PATCH] urlmon: Handle failure using HTTP Basic authentication scheme by asking user/password. Message-Id: <20210607193959.8adb4a83abf0bfc70b244302@baikal.ru> Date: Mon, 7 Jun 2021 19:39:59 +0300 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=34964 Signed-off-by: Dmitry Timoshkov --- dlls/urlmon/http.c | 10 ++++++++++ dlls/urlmon/protocol.c | 38 ++++++++++++++++++++++++++++++++++++++ dlls/urlmon/urlmon_main.h | 1 + 3 files changed, 49 insertions(+) diff --git a/dlls/urlmon/http.c b/dlls/urlmon/http.c index bee226bd474..241e630c338 100644 --- a/dlls/urlmon/http.c +++ b/dlls/urlmon/http.c @@ -231,6 +231,9 @@ static HRESULT handle_http_error(HttpProtocol *This, DWORD error) if(This->base.bindf & BINDF_NO_UI) dlg_flags |= FLAGS_ERROR_UI_FLAGS_NO_UI; + if(!error) + dlg_flags |= FLAGS_ERROR_UI_FILTER_FOR_ERRORS; + res = InternetErrorDlg(hwnd, This->base.request, error, dlg_flags, NULL); hres = res == ERROR_INTERNET_FORCE_RETRY || res == ERROR_SUCCESS ? RPC_E_RETRY : internet_error_to_hres(error); } @@ -989,3 +992,10 @@ HRESULT HttpSProtocol_Construct(IUnknown *outer, void **ppv) return create_http_protocol(TRUE, outer, ppv); } + +void handle_basic_auth_error(Protocol *prot) +{ + HttpProtocol *This = impl_from_Protocol(prot); + + handle_http_error(This, ERROR_SUCCESS); +} diff --git a/dlls/urlmon/protocol.c b/dlls/urlmon/protocol.c index 2acffdc1ffe..4600a6ccb75 100644 --- a/dlls/urlmon/protocol.c +++ b/dlls/urlmon/protocol.c @@ -220,6 +220,44 @@ static void WINAPI internet_status_callback(HINTERNET internet, DWORD_PTR contex IInternetProtocol_Release(protocol->protocol); break; + case INTERNET_STATUS_RESPONSE_RECEIVED: + { + DWORD status, size; + + TRACE("%p INTERNET_STATUS_RESPONSE_RECEIVED (%u bytes)\n", protocol, *(const DWORD *)status_info); + + size = sizeof(status); + if (HttpQueryInfoW(protocol->request, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &status, &size, 0)) + { + TRACE("request status: %u\n", status); + if (status == HTTP_STATUS_DENIED) + { + WCHAR auth[2048]; + DWORD idx; + BOOL is_basic = FALSE; + + TRACE("=> HTTP_STATUS_DENIED\n"); + + size = ARRAY_SIZE(auth); + idx = 0; + while (HttpQueryInfoW(protocol->request, HTTP_QUERY_WWW_AUTHENTICATE, auth, &size, &idx)) + { + static const WCHAR basicW[] = {'B','a','s','i','c'}; /* Note: not nul-terminated */ + + TRACE("WWW_AUTHENTICATE: %s\n", debugstr_w(auth)); + + is_basic = !wcsnicmp(auth, basicW, ARRAY_SIZE(basicW)); + + size = ARRAY_SIZE(auth); + } + + if (is_basic) + handle_basic_auth_error(protocol); + } + } + break; + } + default: WARN("Unhandled Internet status callback %d\n", internet_status); } diff --git a/dlls/urlmon/urlmon_main.h b/dlls/urlmon/urlmon_main.h index 691c63e3b42..77c506db66d 100644 --- a/dlls/urlmon/urlmon_main.h +++ b/dlls/urlmon/urlmon_main.h @@ -228,6 +228,7 @@ tls_data_t *get_tls_data(void) DECLSPEC_HIDDEN; void unregister_notif_wnd_class(void) DECLSPEC_HIDDEN; HWND get_notif_hwnd(void) DECLSPEC_HIDDEN; void release_notif_hwnd(HWND) DECLSPEC_HIDDEN; +void handle_basic_auth_error(Protocol*) DECLSPEC_HIDDEN; const char *debugstr_bindstatus(ULONG) DECLSPEC_HIDDEN; -- 2.31.1