wininet: Add a simple certificate dialog to InternetErrorDlg.

This commit is contained in:
David Hedberg 2010-12-19 21:34:28 +01:00 committed by Alexandre Julliard
parent 46be41271c
commit 08fe24de06
6 changed files with 309 additions and 6 deletions

View File

@ -44,6 +44,8 @@
#include "resource.h" #include "resource.h"
#define MAX_STRING_LEN 1024
WINE_DEFAULT_DEBUG_CHANNEL(wininet); WINE_DEFAULT_DEBUG_CHANNEL(wininet);
struct WININET_ErrorDlgParams struct WININET_ErrorDlgParams
@ -460,6 +462,109 @@ static INT_PTR WINAPI WININET_PasswordDialog(
return FALSE; return FALSE;
} }
/***********************************************************************
* 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 * WININET_GetConnectionStatus
*/ */
@ -494,6 +599,9 @@ DWORD WINAPI InternetErrorDlg(HWND hWnd, HINTERNET hRequest,
TRACE("%p %p %d %08x %p\n", hWnd, hRequest, dwError, dwFlags, lppvData); 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.hWnd = hWnd;
params.hRequest = hRequest; params.hRequest = hRequest;
params.dwError = dwError; params.dwError = dwError;
@ -520,14 +628,23 @@ DWORD WINAPI InternetErrorDlg(HWND hWnd, HINTERNET hRequest,
WARN("unhandled status %u\n", dwStatus); WARN("unhandled status %u\n", dwStatus);
return 0; return 0;
} }
case ERROR_INTERNET_SEC_CERT_ERRORS:
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_CN_INVALID:
case ERROR_INTERNET_SEC_CERT_DATE_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) &params );
case ERROR_INTERNET_HTTP_TO_HTTPS_ON_REDIR:
case ERROR_INTERNET_POST_IS_NON_SECURE:
FIXME("Need to display dialog for error %d\n", dwError); FIXME("Need to display dialog for error %d\n", dwError);
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
return ERROR_INVALID_PARAMETER;
return ERROR_NOT_SUPPORTED;
} }

View File

@ -21,6 +21,7 @@
#include <windef.h> #include <windef.h>
#include <winuser.h> #include <winuser.h>
#define IDD_INVCERTDLG 0x398
#define IDD_AUTHDLG 0x399 #define IDD_AUTHDLG 0x399
#define IDD_PROXYDLG 0x400 #define IDD_PROXYDLG 0x400
@ -30,5 +31,10 @@
#define IDC_PASSWORD 0x404 #define IDC_PASSWORD 0x404
#define IDC_SAVEPASSWORD 0x405 #define IDC_SAVEPASSWORD 0x405
#define IDC_SERVER 0x406 #define IDC_SERVER 0x406
#define IDC_CERT_ERROR 0x407
#define IDS_LANCONNECTION 0x500 #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

View File

@ -1,5 +1,5 @@
TESTDLL = wininet.dll TESTDLL = wininet.dll
IMPORTS = wininet ws2_32 advapi32 IMPORTS = wininet ws2_32 user32 advapi32
C_SRCS = \ C_SRCS = \
ftp.c \ ftp.c \

View File

@ -22,6 +22,7 @@
#include <string.h> #include <string.h>
#include "windef.h" #include "windef.h"
#include "winbase.h" #include "winbase.h"
#include "winuser.h"
#include "wininet.h" #include "wininet.h"
#include "winerror.h" #include "winerror.h"
#include "winreg.h" #include "winreg.h"
@ -1123,6 +1124,152 @@ static void test_Option_PerConnectionOptionA(void)
HeapFree(GetProcessHeap(), 0, list.pOptions); 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) START_TEST(internet)
@ -1153,6 +1300,7 @@ START_TEST(internet)
test_null(); test_null();
test_Option_PerConnectionOption(); test_Option_PerConnectionOption();
test_Option_PerConnectionOptionA(); test_Option_PerConnectionOptionA();
test_InternetErrorDlg();
if (!pInternetTimeFromSystemTimeA) if (!pInternetTimeFromSystemTimeA)
win_skip("skipping the InternetTime tests\n"); win_skip("skipping the InternetTime tests\n");

View File

@ -60,7 +60,23 @@ FONT 8, "MS Shell Dlg"
PUSHBUTTON "Cancel", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP 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 STRINGTABLE
{ {
IDS_LANCONNECTION "LAN Connection" 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."
} }

View File

@ -60,7 +60,23 @@ FONT 8, "MS Shell Dlg"
PUSHBUTTON "Avbryt", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP 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 STRINGTABLE
{ {
IDS_LANCONNECTION "LAN-anslutning" 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."
} }