Windows NT 4.0 source code leak
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

/*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