[PATCH v3] wininet: Clear cached credentials after the first failed attempt.

Alistair Leslie-Hughes leslie_alistair at hotmail.com
Thu Oct 14 03:45:58 CDT 2021


Windows when using cached credentials will use them on the first challenge,
if then a second 403 (ACCESS_DENIED) is received, the user is prompted again
but this time with the password and save checkbox cleared.

v2:
Use a BOOL flag variable.

v3:
Reset flags on success.

Signed-off-by: Alistair Leslie-Hughes <leslie_alistair at hotmail.com>
---
 dlls/wininet/dialogs.c  | 24 +++++++++++++++++++++++-
 dlls/wininet/internet.h |  1 +
 2 files changed, 24 insertions(+), 1 deletion(-)

diff --git a/dlls/wininet/dialogs.c b/dlls/wininet/dialogs.c
index a48c75865ac..5837b9f95d3 100644
--- a/dlls/wininet/dialogs.c
+++ b/dlls/wininet/dialogs.c
@@ -152,9 +152,25 @@ static BOOL WININET_GetSetPassword( HWND hdlg, LPCWSTR szServer,
     p = wcschr( szUserPass, ':' );
     if( p )
     {
+        struct WININET_ErrorDlgParams *params;
+        HWND hwnd;
+
+        params = (struct WININET_ErrorDlgParams*)
+                 GetWindowLongPtrW( hdlg, GWLP_USERDATA );
+
         *p = 0;
         SetWindowTextW( hUserItem, szUserPass );
-        SetWindowTextW( hPassItem, p+1 );
+
+        if (!params->req->clear_auth)
+        {
+            SetWindowTextW( hPassItem, p+1 );
+
+            hwnd = GetDlgItem( hdlg, IDC_SAVEPASSWORD );
+            if (hwnd)
+                SendMessageW(hwnd, BM_SETCHECK, BST_CHECKED, 0);
+        }
+        else
+            WININET_GetSetPassword( hdlg, szServer, szRealm, TRUE );
     }
 
     return TRUE;
@@ -264,6 +280,8 @@ static INT_PTR WINAPI WININET_ProxyPasswordDialog(
                 WININET_GetSetPassword( hdlg, params->req->session->appInfo->proxy, szRealm, TRUE );
             WININET_SetAuthorization( params->req, username, password, TRUE );
 
+            params->req->clear_auth = TRUE;
+
             EndDialog( hdlg, ERROR_INTERNET_FORCE_RETRY );
             return TRUE;
         }
@@ -340,6 +358,7 @@ static INT_PTR WINAPI WININET_PasswordDialog(
                 WININET_GetSetPassword( hdlg, params->req->session->hostName, szRealm, TRUE );
             }
             WININET_SetAuthorization( params->req, username, password, FALSE );
+            params->req->clear_auth = TRUE;
 
             EndDialog( hdlg, ERROR_INTERNET_FORCE_RETRY );
             return TRUE;
@@ -509,6 +528,9 @@ DWORD WINAPI InternetErrorDlg(HWND hWnd, HINTERNET hRequest,
             res = DialogBoxParamW( WININET_hModule, MAKEINTRESOURCEW( IDD_AUTHDLG ),
                                     hWnd, WININET_PasswordDialog, (LPARAM) &params );
             break;
+        case HTTP_STATUS_OK:
+            req->clear_auth = FALSE;
+            break;
         default:
             WARN("unhandled status %u\n", req->status_code);
         }
diff --git a/dlls/wininet/internet.h b/dlls/wininet/internet.h
index b361c0d1b4d..141613dd120 100644
--- a/dlls/wininet/internet.h
+++ b/dlls/wininet/internet.h
@@ -361,6 +361,7 @@ typedef struct
     LPWSTR statusText;
     DWORD bytesToWrite;
     DWORD bytesWritten;
+    BOOL clear_auth; /* Flag to clear the password field on the authorization dialog */
 
     CRITICAL_SECTION headers_section;  /* section to protect the headers array */
     HTTPHEADERW *custHeaders;
-- 
2.33.0




More information about the wine-devel mailing list