[PATCH] urlmon: Handle failure using HTTP Basic authentication scheme by asking user/password.

Dmitry Timoshkov dmitry at baikal.ru
Mon Jun 7 11:39:59 CDT 2021


Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=34964
Signed-off-by: Dmitry Timoshkov <dmitry at baikal.ru>
---
 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




More information about the wine-devel mailing list