mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
270 lines
7.9 KiB
270 lines
7.9 KiB
/*Included Files------------------------------------------------------------*/
|
|
#include "all.h"
|
|
#include "statesec.h"
|
|
|
|
/*External Functions--------------------------------------------------------*/
|
|
/*
|
|
this state checks to see if we need warning messages.
|
|
ie, zone crossings, sending over insecure channels
|
|
*/
|
|
extern int SecurityCheck(struct Mwin *tw, HTRequest *pRequest, BOOL fSending, BOOL fUseSsl, int nState){
|
|
#ifdef HTTPS_ACCESS_TYPE
|
|
/*just because someone is a schmuck*/
|
|
if (!tw) return nState;
|
|
|
|
/*
|
|
if this was a special page, remove the special page designation, and make
|
|
last warning = this warning so we don't get a warning
|
|
*/
|
|
if (tw->dwSslPageFlagsWorking & SSL_PAGE_LAST_SPECIAL_PAGE){
|
|
tw->dwSslPageFlagsWorking &= ~SSL_PAGE_LAST_SPECIAL_PAGE;
|
|
if (tw->dwSslPageFlagsWorking & SSL_PAGE_CURRENT_SECURE_PROTOCOL){
|
|
tw->dwSslPageFlagsWorking |= SSL_PAGE_LAST_SECURE_PROTOCOL;
|
|
}
|
|
}
|
|
|
|
/*Zone Crossing Violation?*/
|
|
if (!fSending){
|
|
/*one way zone cross. this page insecure, last one secure*/
|
|
if (
|
|
(((tw->dwSslPageFlagsWorking&SSL_PAGE_LAST_SECURE_PROTOCOL))==SSL_PAGE_LAST_SECURE_PROTOCOL ?TRUE:FALSE)
|
|
!=
|
|
(((tw->dwSslPageFlagsWorking&SSL_PAGE_CURRENT_SECURE_PROTOCOL))==SSL_PAGE_CURRENT_SECURE_PROTOCOL?TRUE:FALSE)
|
|
){
|
|
/*insecure receive possible, check to see if warning already given for page*/
|
|
if (SSL_PAGE_VIEWING_WARNING_GIVEN & tw->dwSslPageFlagsWorking){
|
|
if (SSL_PAGE_VIEWING_DUP & tw->dwSslPageFlagsWorking){
|
|
/*
|
|
another thread on this page snuck in while the original thread that triggered
|
|
the dialog is still blocked. fake blocking on this thread too.
|
|
*/
|
|
nState = STATE_SECURITY_CHECK;
|
|
}
|
|
else if (SSL_PAGE_VIEWING_ABORT & tw->dwSslPageFlagsWorking){
|
|
/*user cancelled*/
|
|
pRequest->iFlags = HTREQ_USERCANCEL;
|
|
nState = STATE_ABORT;
|
|
}
|
|
else{
|
|
/*user oked this, this is latest zone crossing notice*/
|
|
tw->dwSslPageFlagsWorking &= ~SSL_PAGE_LAST_SECURE_PROTOCOL;
|
|
if (tw->dwSslPageFlagsWorking & SSL_PAGE_CURRENT_SECURE_PROTOCOL){
|
|
tw->dwSslPageFlagsWorking |= SSL_PAGE_LAST_SECURE_PROTOCOL;
|
|
}
|
|
}
|
|
}
|
|
else{
|
|
if (FALSE == SslDialogViewing(tw->win, &tw->dwSslPageFlagsWorking)){
|
|
/*problem when creating dialog, block*/
|
|
nState = STATE_ABORT;
|
|
}
|
|
else{
|
|
/*return to msg loop so this thread blocks*/
|
|
nState = STATE_SECURITY_CHECK;
|
|
}
|
|
}
|
|
}
|
|
/*see if we requested a secure and got insecure objects*/
|
|
else if (!fUseSsl && (tw->dwSslPageFlagsWorking&SSL_PAGE_CURRENT_SECURE_PROTOCOL)){
|
|
/*insecure receive from a secure base page possible*/
|
|
if (SSL_PAGE_MIXED_WARNING_GIVEN & tw->dwSslPageFlagsWorking){
|
|
/*
|
|
we warn one time per page, so leave this flag on
|
|
this flag is reset on each call to Image_LoadAll_Async
|
|
so we can click and choose to load each one later
|
|
*/
|
|
if (SSL_PAGE_MIXED_DUP & tw->dwSslPageFlagsWorking){
|
|
/*
|
|
another thread on this page snuck in while the original thread that triggered
|
|
the dialog is still blocked. fake blocking on this thread too.
|
|
*/
|
|
nState = STATE_SECURITY_CHECK;
|
|
}
|
|
else if (SSL_PAGE_MIXED_ABORT & tw->dwSslPageFlagsWorking){
|
|
/*user cancelled*/
|
|
pRequest->iFlags = HTREQ_USERCANCEL;
|
|
nState = STATE_ABORT;
|
|
}
|
|
}
|
|
else{
|
|
if (FALSE == SslDialogMixed(tw->win, &tw->dwSslPageFlagsWorking)){
|
|
/*problem when creating dialog, block*/
|
|
nState = STATE_ABORT;
|
|
}
|
|
else{
|
|
/*return to msg loop so this thread blocks*/
|
|
nState = STATE_SECURITY_CHECK;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
/*see if socket is not using SSL and we are sending*/
|
|
else if (!fUseSsl){
|
|
/*insecure send possible*/
|
|
if (SSL_PAGE_SENDING_WARNING_GIVEN & tw->dwSslPageFlagsWorking){
|
|
/*make sure we bug user for each insecure send from this page*/
|
|
tw->dwSslPageFlagsWorking &= ~SSL_PAGE_SENDING_WARNING_GIVEN;
|
|
if (SSL_PAGE_SENDING_ABORT & tw->dwSslPageFlagsWorking){
|
|
/*user cancelled*/
|
|
pRequest->iFlags = HTREQ_USERCANCEL;
|
|
nState = STATE_ABORT;
|
|
}
|
|
}
|
|
else{
|
|
/*Time to do the security dialog, if we got here, he have a violation*/
|
|
if (gPrefs.nSendingSecurity != SECURITY_LOW){
|
|
if (FALSE == SslDialogSending(tw->win, &tw->dwSslPageFlagsWorking)){
|
|
/*problem when creating dialog, block*/
|
|
nState = STATE_ABORT;
|
|
}
|
|
else{
|
|
/*return to msg loop so this thread blocks*/
|
|
nState = STATE_SECURITY_CHECK;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
return nState;
|
|
}
|
|
|
|
#ifdef HTTPS_ACCESS_TYPE
|
|
|
|
// can either loop back and continue or wait
|
|
int CertAndCNSecurityCheck(struct Mwin *tw, DWORD *pdwSSLFlags, DWORD *pdwSendFlags, int socket)
|
|
{
|
|
//UINT ui_w3docFlags = 0;
|
|
HWND hWnd;
|
|
int iReturn = STATE_SEND_CANCEL_CERTTEST;
|
|
char *pCert;
|
|
int nCert = 0;
|
|
|
|
|
|
ASSERT(pdwSSLFlags);
|
|
ASSERT(pdwSendFlags);
|
|
ASSERT(*pdwSSLFlags & SO_SSL_ERROR); // theres an error in SSL
|
|
ASSERT(*pdwSendFlags & FLAGS_NET_SEND_IS_SSL); // we're in SSL
|
|
|
|
//if (tw && tw->w3doc)
|
|
// ui_w3docFlags = tw->w3doc->flags;
|
|
|
|
// this is neeeded to handle the case where tw is not valid yet
|
|
// for example, we're loading a SSL page on startup.
|
|
if ( tw && tw->win )
|
|
hWnd = tw->win;
|
|
else
|
|
hWnd = GetDesktopWindow();
|
|
|
|
|
|
// get the current Cert and compare it, perhaps this may a Cert thats
|
|
// already errored out, and therefore we don't need to complain on it
|
|
WS_GETSOCKOPT(socket, SO_SSL_LEVEL, SO_SSL_CERTIFICATE, NULL, &nCert);
|
|
if (nCert)
|
|
{
|
|
pCert = malloc(nCert);
|
|
WS_GETSOCKOPT(socket, SO_SSL_LEVEL, SO_SSL_CERTIFICATE, pCert, &nCert);
|
|
}
|
|
|
|
// pLastCertOk is the last Cert that we failed on.
|
|
if (SSLGlobals.pLastCertOk && pCert)
|
|
{
|
|
// If we're returning we could be skipping a check on
|
|
// a send so before we do, we check to make sure that
|
|
// that the Last Cert was stored for the same reason
|
|
// we're about to skip informing the User about
|
|
if (
|
|
(SSLGlobals.dwCertGlobalSettings == SECURITY_BAD_CN_SENDING &&
|
|
(*pdwSendFlags & FLAGS_NET_SEND_DOING_SEND)) ||
|
|
(SSLGlobals.dwCertGlobalSettings == SECURITY_BAD_CN_RECVING &&
|
|
!(*pdwSendFlags & FLAGS_NET_SEND_DOING_SEND)) ||
|
|
(SSLGlobals.dwCertGlobalSettings == SECURITY_BAD_DATETIME &&
|
|
(*pdwSSLFlags & SO_SSL_CERT_EXPIRED))
|
|
)
|
|
{
|
|
if ( memcmp( pCert, SSLGlobals.pLastCertOk, min(nCert, SSLGlobals.nLastCertOk)) == 0 )
|
|
{
|
|
|
|
// we ignore this error since we already complained about
|
|
// the cert, and the user has said he doesn't care about it.
|
|
*pdwSSLFlags &= (~SO_SSL_ERROR);
|
|
free(pCert);
|
|
return STATE_SEND_CANCEL_CERTTEST; // keep going
|
|
}
|
|
}
|
|
}
|
|
|
|
// something bad happening while trying to get our Cert,
|
|
// lets bail out of here before we GPF
|
|
if ( pCert == NULL )
|
|
{
|
|
*pdwSSLFlags &= (~SO_SSL_ERROR);
|
|
return STATE_ABORT;
|
|
}
|
|
|
|
|
|
if ( *pdwSSLFlags & SO_SSL_CERT_EXPIRED )
|
|
{
|
|
// we have an expired Cert, we need to ask the user
|
|
// whether we can continue loading
|
|
|
|
if ( SslDialogBadCertDateTime(hWnd, pdwSendFlags, pCert, nCert) == FALSE )
|
|
{
|
|
iReturn = STATE_ABORT;
|
|
}
|
|
else
|
|
{
|
|
iReturn = STATE_SEND_SSL_UI_RETRY;
|
|
}
|
|
|
|
}
|
|
else if ( *pdwSSLFlags & SO_SSL_BAD_COMMON_NAME )
|
|
{
|
|
if ( *pdwSendFlags & FLAGS_NET_SEND_DOING_SEND )
|
|
{
|
|
// if'we sending ie posting data to a SSL server
|
|
// then the use wants to knowe about it, then
|
|
// stop the net, and wait for the UI to come
|
|
// so we know if its ok to go on
|
|
if ( gPrefs.bChkCNOnSend )
|
|
{
|
|
|
|
if ( SslDialogCNBadSending(hWnd, pdwSendFlags, pCert, nCert) == FALSE )
|
|
{
|
|
iReturn = STATE_ABORT;
|
|
}
|
|
else
|
|
{
|
|
iReturn = STATE_SEND_SSL_UI_RETRY;
|
|
}
|
|
// otherwise we fall through and continue
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
if ( gPrefs.bChkCNOnRecv )
|
|
{
|
|
if ( SslDialogCNBadRecving(hWnd, pdwSendFlags, pCert, nCert) == FALSE )
|
|
{
|
|
iReturn = STATE_ABORT;
|
|
}
|
|
else
|
|
{
|
|
iReturn = STATE_SEND_SSL_UI_RETRY;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// if we failed to even call SslDialog... we never freed
|
|
// the pCert, so we need to do it now
|
|
if ( iReturn == STATE_SEND_CANCEL_CERTTEST )
|
|
free(pCert);
|
|
|
|
*pdwSSLFlags &= (~SO_SSL_ERROR);
|
|
return iReturn;
|
|
}
|
|
|
|
#endif
|
|
|