[PATCH 2/2] wininet: Add a simple certificate dialog to InternetErrorDlg.
David Hedberg
dhedberg at codeweavers.com
Sun Dec 19 14:34:28 CST 2010
---
dlls/wininet/dialogs.c | 125 ++++++++++++++++++++++++++++++++-
dlls/wininet/resource.h | 6 ++
dlls/wininet/tests/Makefile.in | 2 +-
dlls/wininet/tests/internet.c | 148 ++++++++++++++++++++++++++++++++++++++++
dlls/wininet/wininet_En.rc | 16 ++++
dlls/wininet/wininet_Sv.rc | 16 ++++
6 files changed, 308 insertions(+), 5 deletions(-)
diff --git a/dlls/wininet/dialogs.c b/dlls/wininet/dialogs.c
index b3713a5..4fd3d3f 100644
--- a/dlls/wininet/dialogs.c
+++ b/dlls/wininet/dialogs.c
@@ -44,6 +44,8 @@
#include "resource.h"
+#define MAX_STRING_LEN 1024
+
WINE_DEFAULT_DEBUG_CHANNEL(wininet);
struct WININET_ErrorDlgParams
@@ -461,6 +463,109 @@ static INT_PTR WINAPI WININET_PasswordDialog(
}
/***********************************************************************
+ * WININET_InvalidCertificateDialog
+ */
+static INT_PTR WINAPI WININET_InvalidCertificateDialog(
+ HWND hdlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
+{
+ struct WININET_ErrorDlgParams *params;
+ HWND hitem;
+ WCHAR buf[1024];
+
+ if( uMsg == WM_INITDIALOG )
+ {
+ TRACE("WM_INITDIALOG (%08lx)\n", lParam);
+
+ /* save the parameter list */
+ params = (struct WININET_ErrorDlgParams*) lParam;
+ SetWindowLongPtrW( hdlg, GWLP_USERDATA, lParam );
+
+ switch( params->dwError )
+ {
+ case ERROR_INTERNET_INVALID_CA:
+ LoadStringW( WININET_hModule, IDS_CERT_CA_INVALID, buf, 1024 );
+ break;
+ case ERROR_INTERNET_SEC_CERT_DATE_INVALID:
+ LoadStringW( WININET_hModule, IDS_CERT_DATE_INVALID, buf, 1024 );
+ break;
+ case ERROR_INTERNET_SEC_CERT_CN_INVALID:
+ LoadStringW( WININET_hModule, IDS_CERT_CN_INVALID, buf, 1024 );
+ break;
+ case ERROR_INTERNET_SEC_CERT_ERRORS:
+ /* FIXME: We should fetch information about the
+ * certificate here and show all the relevant errors.
+ */
+ LoadStringW( WININET_hModule, IDS_CERT_ERRORS, buf, 1024 );
+ break;
+ default:
+ FIXME( "No message for error %d\n", params->dwError );
+ buf[0] = '\0';
+ }
+
+ hitem = GetDlgItem( hdlg, IDC_CERT_ERROR );
+ SetWindowTextW( hitem, buf );
+
+ return TRUE;
+ }
+
+ params = (struct WININET_ErrorDlgParams*)
+ GetWindowLongPtrW( hdlg, GWLP_USERDATA );
+
+ switch( uMsg )
+ {
+ case WM_COMMAND:
+ if( wParam == IDOK )
+ {
+ BOOL res = TRUE;
+
+ if( params->dwFlags & FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS )
+ {
+ DWORD flags, size = sizeof(flags);
+
+ InternetQueryOptionW( params->hRequest, INTERNET_OPTION_SECURITY_FLAGS, &flags, &size );
+ switch( params->dwError )
+ {
+ case ERROR_INTERNET_INVALID_CA:
+ flags |= SECURITY_FLAG_IGNORE_UNKNOWN_CA;
+ break;
+ case ERROR_INTERNET_SEC_CERT_DATE_INVALID:
+ flags |= SECURITY_FLAG_IGNORE_CERT_DATE_INVALID;
+ break;
+ case ERROR_INTERNET_SEC_CERT_CN_INVALID:
+ flags |= SECURITY_FLAG_IGNORE_CERT_CN_INVALID;
+ break;
+ case ERROR_INTERNET_SEC_CERT_ERRORS:
+ FIXME("Should only add ignore flags as needed.\n");
+ flags |= SECURITY_FLAG_IGNORE_CERT_CN_INVALID |
+ SECURITY_FLAG_IGNORE_CERT_DATE_INVALID |
+ SECURITY_FLAG_IGNORE_UNKNOWN_CA;
+ /* FIXME: ERROR_INTERNET_SEC_CERT_ERRORS also
+ * seems to set the corresponding DLG_* flags.
+ */
+ break;
+ }
+ res = InternetSetOptionW( params->hRequest, INTERNET_OPTION_SECURITY_FLAGS, &flags, size );
+ if(!res)
+ WARN("InternetSetOption(INTERNET_OPTION_SECURITY_FLAGS) failed.\n");
+ }
+
+ EndDialog( hdlg, res ? ERROR_SUCCESS : ERROR_NOT_SUPPORTED );
+ return TRUE;
+ }
+ if( wParam == IDCANCEL )
+ {
+ TRACE("Pressed cancel.\n");
+
+ EndDialog( hdlg, ERROR_CANCELLED );
+ return TRUE;
+ }
+ break;
+ }
+
+ return FALSE;
+}
+
+/***********************************************************************
* WININET_GetConnectionStatus
*/
static INT WININET_GetConnectionStatus( HINTERNET hRequest )
@@ -494,6 +599,9 @@ DWORD WINAPI InternetErrorDlg(HWND hWnd, HINTERNET hRequest,
TRACE("%p %p %d %08x %p\n", hWnd, hRequest, dwError, dwFlags, lppvData);
+ if( !hWnd && !(dwFlags & FLAGS_ERROR_UI_FLAGS_NO_UI) )
+ return ERROR_INVALID_HANDLE;
+
params.hWnd = hWnd;
params.hRequest = hRequest;
params.dwError = dwError;
@@ -520,14 +628,23 @@ DWORD WINAPI InternetErrorDlg(HWND hWnd, HINTERNET hRequest,
WARN("unhandled status %u\n", dwStatus);
return 0;
}
+ case ERROR_INTERNET_SEC_CERT_ERRORS:
+ case ERROR_INTERNET_SEC_CERT_CN_INVALID:
+ case ERROR_INTERNET_SEC_CERT_DATE_INVALID:
+ case ERROR_INTERNET_INVALID_CA:
+ if( dwFlags & FLAGS_ERROR_UI_FLAGS_NO_UI )
+ return ERROR_CANCELLED;
+ if( dwFlags & ~FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS )
+ FIXME("%08x contains unsupported flags.\n", dwFlags);
+
+ return DialogBoxParamW( WININET_hModule, MAKEINTRESOURCEW( IDD_INVCERTDLG ),
+ hWnd, WININET_InvalidCertificateDialog, (LPARAM) ¶ms );
case ERROR_INTERNET_HTTP_TO_HTTPS_ON_REDIR:
- case ERROR_INTERNET_INVALID_CA:
case ERROR_INTERNET_POST_IS_NON_SECURE:
- case ERROR_INTERNET_SEC_CERT_CN_INVALID:
- case ERROR_INTERNET_SEC_CERT_DATE_INVALID:
FIXME("Need to display dialog for error %d\n", dwError);
return ERROR_SUCCESS;
}
- return ERROR_INVALID_PARAMETER;
+
+ return ERROR_NOT_SUPPORTED;
}
diff --git a/dlls/wininet/resource.h b/dlls/wininet/resource.h
index 279c112..256a374 100644
--- a/dlls/wininet/resource.h
+++ b/dlls/wininet/resource.h
@@ -21,6 +21,7 @@
#include <windef.h>
#include <winuser.h>
+#define IDD_INVCERTDLG 0x398
#define IDD_AUTHDLG 0x399
#define IDD_PROXYDLG 0x400
@@ -30,5 +31,10 @@
#define IDC_PASSWORD 0x404
#define IDC_SAVEPASSWORD 0x405
#define IDC_SERVER 0x406
+#define IDC_CERT_ERROR 0x407
#define IDS_LANCONNECTION 0x500
+#define IDS_CERT_CA_INVALID 0x501
+#define IDS_CERT_DATE_INVALID 0x502
+#define IDS_CERT_CN_INVALID 0x503
+#define IDS_CERT_ERRORS 0x504
diff --git a/dlls/wininet/tests/Makefile.in b/dlls/wininet/tests/Makefile.in
index 942267a..2f58593 100644
--- a/dlls/wininet/tests/Makefile.in
+++ b/dlls/wininet/tests/Makefile.in
@@ -1,5 +1,5 @@
TESTDLL = wininet.dll
-IMPORTS = wininet ws2_32 advapi32
+IMPORTS = wininet ws2_32 user32 advapi32
C_SRCS = \
ftp.c \
diff --git a/dlls/wininet/tests/internet.c b/dlls/wininet/tests/internet.c
index a38e196..df0a882 100644
--- a/dlls/wininet/tests/internet.c
+++ b/dlls/wininet/tests/internet.c
@@ -22,6 +22,7 @@
#include <string.h>
#include "windef.h"
#include "winbase.h"
+#include "winuser.h"
#include "wininet.h"
#include "winerror.h"
#include "winreg.h"
@@ -1123,6 +1124,152 @@ static void test_Option_PerConnectionOptionA(void)
HeapFree(GetProcessHeap(), 0, list.pOptions);
}
+#define FLAG_TODO 0x1
+#define FLAG_NEEDREQ 0x2
+#define FLAG_UNIMPL 0x4
+
+void test_InternetErrorDlg(void)
+{
+ HINTERNET ses, con, req;
+ DWORD res, flags;
+ HWND hwnd;
+ ULONG i;
+ static const struct {
+ DWORD error;
+ DWORD res;
+ DWORD test_flags;
+ } no_ui_res[] = {
+ { ERROR_INTERNET_INCORRECT_PASSWORD , ERROR_SUCCESS, FLAG_NEEDREQ },
+ { ERROR_INTERNET_SEC_CERT_DATE_INVALID , ERROR_CANCELLED, 0 },
+ { ERROR_INTERNET_SEC_CERT_CN_INVALID , ERROR_CANCELLED, 0 },
+ { ERROR_INTERNET_HTTP_TO_HTTPS_ON_REDIR , ERROR_SUCCESS, 0 },
+ { ERROR_INTERNET_HTTPS_TO_HTTP_ON_REDIR , ERROR_SUCCESS, FLAG_TODO },
+ { ERROR_INTERNET_MIXED_SECURITY , ERROR_CANCELLED, FLAG_TODO },
+ { ERROR_INTERNET_CHG_POST_IS_NON_SECURE , ERROR_CANCELLED, FLAG_TODO },
+ { ERROR_INTERNET_POST_IS_NON_SECURE , ERROR_SUCCESS, 0 },
+ { ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED, ERROR_CANCELLED, FLAG_NEEDREQ|FLAG_TODO },
+ { ERROR_INTERNET_INVALID_CA , ERROR_CANCELLED, 0 },
+ { ERROR_INTERNET_HTTPS_HTTP_SUBMIT_REDIR, ERROR_CANCELLED, FLAG_TODO },
+ { ERROR_INTERNET_INSERT_CDROM , ERROR_CANCELLED, FLAG_TODO|FLAG_NEEDREQ|FLAG_UNIMPL },
+ { ERROR_INTERNET_SEC_CERT_ERRORS , ERROR_CANCELLED, 0 },
+ { ERROR_INTERNET_SEC_CERT_REV_FAILED , ERROR_CANCELLED, FLAG_TODO },
+ { ERROR_HTTP_COOKIE_NEEDS_CONFIRMATION , ERROR_HTTP_COOKIE_DECLINED, FLAG_TODO },
+ { ERROR_INTERNET_BAD_AUTO_PROXY_SCRIPT , ERROR_CANCELLED, FLAG_TODO },
+ { ERROR_INTERNET_UNABLE_TO_DOWNLOAD_SCRIPT, ERROR_CANCELLED, FLAG_TODO },
+ { ERROR_HTTP_REDIRECT_NEEDS_CONFIRMATION, ERROR_CANCELLED, FLAG_TODO },
+ { ERROR_INTERNET_SEC_CERT_REVOKED , ERROR_CANCELLED, 0 },
+ { 0, ERROR_NOT_SUPPORTED }
+ };
+
+ flags = 0;
+
+ res = InternetErrorDlg(NULL, NULL, 12055, flags, NULL);
+ ok(res == ERROR_INVALID_HANDLE, "Got %d\n", res);
+
+ ses = InternetOpen(NULL, INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
+ ok(ses != 0, "InternetOpen failed: 0x%08x\n", GetLastError());
+ con = InternetConnect(ses, "www.winehq.org", 80, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
+ ok(con != 0, "InternetConnect failed: 0x%08x\n", GetLastError());
+ req = HttpOpenRequest(con, "GET", "/", NULL, NULL, NULL, 0, 0);
+ ok(req != 0, "HttpOpenRequest failed: 0x%08x\n", GetLastError());
+
+ /* NULL hwnd and FLAGS_ERROR_UI_FLAGS_NO_UI not set */
+ for(i = INTERNET_ERROR_BASE; i < INTERNET_ERROR_LAST; i++)
+ {
+ res = InternetErrorDlg(NULL, req, i, flags, NULL);
+ ok(res == ERROR_INVALID_HANDLE, "Got %d (%d)\n", res, i);
+ }
+
+ hwnd = GetDesktopWindow();
+ ok(hwnd != NULL, "GetDesktopWindow failed (%d)\n", GetLastError());
+
+ flags = FLAGS_ERROR_UI_FLAGS_NO_UI;
+ for(i = INTERNET_ERROR_BASE; i < INTERNET_ERROR_LAST; i++)
+ {
+ DWORD expected, test_flags, j;
+
+ for(j = 0; no_ui_res[j].error != 0; ++j)
+ if(no_ui_res[j].error == i)
+ break;
+
+ test_flags = no_ui_res[j].test_flags;
+ expected = no_ui_res[j].res;
+
+ /* Try an invalid request handle */
+ res = InternetErrorDlg(hwnd, (HANDLE)0xdeadbeef, i, flags, NULL);
+ if(res == ERROR_CALL_NOT_IMPLEMENTED)
+ {
+ todo_wine ok(test_flags & FLAG_UNIMPL, "%i is unexpectedly unimplemented.\n", i);
+ continue;
+ }
+ else
+ todo_wine ok(res == ERROR_INVALID_HANDLE, "Got %d (%d)\n", res, i);
+
+ /* With a valid req */
+ if(i == ERROR_INTERNET_NEED_UI)
+ continue; /* Crashes on windows XP */
+
+ if(i == ERROR_INTERNET_SEC_CERT_REVOKED)
+ continue; /* Interactive (XP, Win7) */
+
+ res = InternetErrorDlg(hwnd, req, i, flags, NULL);
+
+ /* Handle some special cases */
+ switch(i)
+ {
+ case ERROR_INTERNET_HTTP_TO_HTTPS_ON_REDIR:
+ case ERROR_INTERNET_HTTPS_TO_HTTP_ON_REDIR:
+ if(res == ERROR_CANCELLED)
+ {
+ /* Some windows XP, w2k3 x64, W2K8 */
+ win_skip("Skipping some tests for %d\n", i);
+ continue;
+ }
+ break;
+ case 12054: /* ERROR_INTERNET_FORTEZZA_LOGIN_NEEDED */
+ if(res != expected)
+ {
+ /* Windows XP, W2K3 */
+ ok(res == NTE_PROV_TYPE_NOT_DEF, "Got %d\n", res);
+ win_skip("Skipping some tests for %d\n", i);
+ continue;
+ }
+ break;
+ default: break;
+ }
+
+ if(test_flags & FLAG_TODO)
+ todo_wine ok(res == expected, "Got %d, expected %d (%d)\n", res, expected, i);
+ else
+ ok(res == expected, "Got %d, expected %d (%d)\n", res, expected, i);
+
+ /* Same thing with NULL hwnd */
+ res = InternetErrorDlg(NULL, req, i, flags, NULL);
+ if(test_flags & FLAG_TODO)
+ todo_wine ok(res == expected, "Got %d, expected %d (%d)\n", res, expected, i);
+ else
+ ok(res == expected, "Got %d, expected %d (%d)\n", res, expected, i);
+
+
+ /* With a null req */
+ if(test_flags & FLAG_NEEDREQ)
+ expected = ERROR_INVALID_PARAMETER;
+
+ res = InternetErrorDlg(hwnd, NULL, i, flags, NULL);
+ if( test_flags & FLAG_TODO || i == ERROR_INTERNET_INCORRECT_PASSWORD)
+ todo_wine ok(res == expected, "Got %d, expected %d (%d)\n", res, expected, i);
+ else
+ ok(res == expected, "Got %d, expected %d (%d)\n", res, expected, i);
+ }
+
+ res = InternetCloseHandle(req);
+ ok(res == TRUE, "InternetCloseHandle failed: 0x%08x\n", GetLastError());
+ res = InternetCloseHandle(con);
+ ok(res == TRUE, "InternetCloseHandle failed: 0x%08x\n", GetLastError());
+ res = InternetCloseHandle(ses);
+ ok(res == TRUE, "InternetCloseHandle failed: 0x%08x\n", GetLastError());
+}
+
/* ############################### */
START_TEST(internet)
@@ -1153,6 +1300,7 @@ START_TEST(internet)
test_null();
test_Option_PerConnectionOption();
test_Option_PerConnectionOptionA();
+ test_InternetErrorDlg();
if (!pInternetTimeFromSystemTimeA)
win_skip("skipping the InternetTime tests\n");
diff --git a/dlls/wininet/wininet_En.rc b/dlls/wininet/wininet_En.rc
index d4ad275..5566859 100644
--- a/dlls/wininet/wininet_En.rc
+++ b/dlls/wininet/wininet_En.rc
@@ -60,7 +60,23 @@ FONT 8, "MS Shell Dlg"
PUSHBUTTON "Cancel", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP
}
+IDD_INVCERTDLG DIALOG 3, 24, 250, 86
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Security Warning"
+FONT 8, "MS Shell Dlg"
+{
+ LTEXT "There is a problem with the certificate for this site.", -1, 40, 6, 200, 20
+ LTEXT "", IDC_CERT_ERROR, 40, 26, 200, 20
+ LTEXT "Do you want to continue anyway?", -1, 40, 46, 200, 20
+ PUSHBUTTON "Yes", IDOK, 40, 66, 56, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON
+ PUSHBUTTON "No", IDCANCEL, 100, 66, 56, 14, WS_GROUP | WS_TABSTOP
+}
+
STRINGTABLE
{
IDS_LANCONNECTION "LAN Connection"
+ IDS_CERT_CA_INVALID "The certificate is issued by an unknown or untrusted publisher."
+ IDS_CERT_DATE_INVALID "The date on the certificate is invalid."
+ IDS_CERT_CN_INVALID "The name on the certificate does not match the site."
+ IDS_CERT_ERRORS "There is at least one unspecified security problem with this certificate."
}
diff --git a/dlls/wininet/wininet_Sv.rc b/dlls/wininet/wininet_Sv.rc
index 520cdcb..cc97d6e 100644
--- a/dlls/wininet/wininet_Sv.rc
+++ b/dlls/wininet/wininet_Sv.rc
@@ -60,7 +60,23 @@ FONT 8, "MS Shell Dlg"
PUSHBUTTON "Avbryt", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP
}
+IDD_INVCERTDLG DIALOG 3, 24, 250, 86
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Säkerhetsvarning"
+FONT 8, "MS Shell Dlg"
+{
+ LTEXT "Ett problem upptäcktes med certifikatet för denna site.", -1, 40, 6, 200, 20
+ LTEXT "", IDC_CERT_ERROR, 40, 26, 200, 20
+ LTEXT "Vill du fortsätta ändå?", -1, 40, 46, 200, 20
+ PUSHBUTTON "Ja", IDOK, 40, 66, 56, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON
+ PUSHBUTTON "Nej", IDCANCEL, 100, 66, 56, 14, WS_GROUP | WS_TABSTOP
+}
+
STRINGTABLE
{
IDS_LANCONNECTION "LAN-anslutning"
+ IDS_CERT_CA_INVALID "Certifikatet är utfärdat av en okänd eller ej betrodd utgivare."
+ IDS_CERT_DATE_INVALID "Certifikatets datum är ogiltigt."
+ IDS_CERT_CN_INVALID "Namnet på certifikatet matchar inte sitens namn."
+ IDS_CERT_ERRORS "Certifikatet har minst ett ospecificerat säkerhetsproblem."
}
--
1.7.3.3
More information about the wine-patches
mailing list