Leaked source code of windows server 2003
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.
 
 
 
 
 
 

565 lines
18 KiB

/*
** s e c h t m l . c p p
**
** Purpose:
** Defines an inline script for the preview pane that will show general
** security UI. An ActiveX control sits on top of this and passes
** the results to our command target
**
** History
** 4/02/97: (t-erikne) Created.
** 7/15/97: (t-erikne) Removed ActiveX control
** 7/16/97: (t-erikne) updated to HTML 4.0
**
** Copyright (C) Microsoft Corp. 1997.
*/
///////////////////////////////////////////////////////////////////////////
//
// Depends on
//
#include <pch.hxx>
#include <resource.h>
#include <docobj.h>
#include "oleutil.h"
#include "ourguid.h"
#include <error.h>
#include <mimeole.h>
#include "secutil.h"
#include <shlwapi.h>
#include "demand.h"
///////////////////////////////////////////////////////////////////////////
//
// Macros
//
#define THIS_AS_UNK ((IUnknown *)(IObjectWithSite *)this)
///////////////////////////////////////////////////////////////////////////
//
// Statics
//
static const TCHAR s_szHTMLRow[] =
"<TR>"
"<TD WIDTH=5%%>"
"<IMG SRC=\"res://msoeres.dll/%s\">"
"</TD>"
"<TD CLASS=%s>"
"%s"
"</TD>"
"</TR>\r\n";
static const TCHAR s_szHTMLRowForRec[] =
"<TR>"
"<TD CLASS=GOOD>"
"%s %s"
"</TD>"
"</TR>\r\n";
// WARNING: If you change the order here, make sure to change it in the order of
// sprintf parameters where it is used in HrOutputSecurityScript.
static const TCHAR s_szHTMLmain[] =
"document.all.hightext.className=\"%s\";"
"document.all.btnCert.disabled=%d;"
"document.all.chkShowAgain.readonly=%d;"
"document.all.chkShowAgain.disabled=%d;"
"document.all.btnTrust.disabled=%d;"
"}\r\n";
static const TCHAR s_szHTMLCloseAll[] =
"</SCRIPT>"
"</BODY></HTML>";
static const TCHAR s_szHTMLgifUNK[] =
"quest.gif";
static const TCHAR s_szHTMLgifGOOD[] =
"check.gif";
static const TCHAR s_szHTMLgifBAD[] =
"eks.gif";
static const TCHAR s_szHTMLclassGOOD[] =
"GOOD";
static const TCHAR s_szHTMLclassBAD[] =
"BAD";
static const TCHAR s_szHTMLclassUNK[] =
"UNK";
static const TCHAR s_szHTMLRowNoIcon[] =
"<TR>"
"<TD WIDTH=5%%>"
"</TD>"
"<TD CLASS=%s>" // "BAD", "GOOD", "UNK"
"%s%s" // label, email address
"</TD>"
"</TR>\r\n";
static const TCHAR s_szHMTLEndTable[] =
"</TABLE>\r\n<p>\r\n<p>" ;
static const TCHAR s_szHTMLEnd[] =
"</BODY></HTML>";
///////////////////////////////////////////////////////////////////////////
//
// Code
//
HRESULT HrOutputSecurityScript(LPSTREAM *ppstm, SECSTATE *pSecState, BOOL fDisableCheckbox)
{
HRESULT hr;
TCHAR szRes[CCHMAX_STRINGRES];
TCHAR szBuf[CCHMAX_STRINGRES];
UINT ids;
ULONG ul;
int i;
BOOL fBadThingsHappened = FALSE;
const WORD wTrusted = LOWORD(pSecState->user_validity);
hr = LoadResourceToHTMLStream("secwarn1.htm", ppstm);
if (FAILED(hr))
goto exit;
ul = ULONG(HIWORD(pSecState->user_validity));
// Top level Messages
//N8 one of the places that we need to pay attention
// to cryptdlg's flags, see wTrusted. I assume that
// we get ATHSEC_NOTRUSTUNKNOWN in a certain set
// of cases. see the chain code in secutil.cpp
// 1. Tamper
if (AthLoadString(
(pSecState->ro_msg_validity & MSV_SIGNATURE_MASK)
? (pSecState->ro_msg_validity & MSV_BADSIGNATURE)
? idsWrnSecurityMsgTamper
: idsUnkSecurityMsgTamper
: (pSecState->fHaveCert ? idsOkSecurityMsgTamper : idsUnkSecurityMsgTamper),
szRes, ARRAYSIZE(szRes)))
{
wnsprintf(szBuf, ARRAYSIZE(szBuf), s_szHTMLRow,
(pSecState->ro_msg_validity & MSV_SIGNATURE_MASK)
? ((pSecState->ro_msg_validity & MSV_BADSIGNATURE)
? s_szHTMLgifBAD
: s_szHTMLgifUNK)
: (pSecState->fHaveCert ? s_szHTMLgifGOOD : s_szHTMLgifUNK),
(pSecState->ro_msg_validity & MSV_SIGNATURE_MASK)
? ((pSecState->ro_msg_validity & MSV_BADSIGNATURE)
? s_szHTMLclassBAD
: s_szHTMLclassUNK)
: (pSecState->fHaveCert ? s_szHTMLclassGOOD : s_szHTMLclassUNK),
szRes);
(*ppstm)->Write(szBuf, lstrlen(szBuf)*sizeof(TCHAR), NULL);
}
// 2. Trust
if (AthLoadString(
(wTrusted)
? (wTrusted & ATHSEC_NOTRUSTUNKNOWN)
? idsUnkSecurityTrust
: idsWrnSecurityTrustNotTrusted
: idsOkSecurityTrustNotTrusted,
szRes, ARRAYSIZE(szRes)))
{
wnsprintf(szBuf, ARRAYSIZE(szBuf), s_szHTMLRow,
(wTrusted)
? (wTrusted & ATHSEC_NOTRUSTUNKNOWN)
? s_szHTMLgifUNK
: s_szHTMLgifBAD
: s_szHTMLgifGOOD,
(wTrusted)
? (wTrusted & ATHSEC_NOTRUSTUNKNOWN)
? s_szHTMLclassUNK
: s_szHTMLclassBAD
: s_szHTMLclassGOOD,
szRes);
(*ppstm)->Write(szBuf, lstrlen(szBuf)*sizeof(TCHAR), NULL);
}
// 3. Expire
if (AthLoadString(
(pSecState->ro_msg_validity & MSV_EXPIRED_SIGNINGCERT)
? idsWrnSecurityTrustExpired
: idsOkSecurityTrustExpired,
szRes, ARRAYSIZE(szRes)))
{
wnsprintf(szBuf, ARRAYSIZE(szBuf), s_szHTMLRow,
(pSecState->ro_msg_validity & MSV_EXPIRED_SIGNINGCERT)
? s_szHTMLgifBAD
: s_szHTMLgifGOOD,
(pSecState->ro_msg_validity & MSV_EXPIRED_SIGNINGCERT)
? s_szHTMLclassBAD
: s_szHTMLclassGOOD,
szRes);
(*ppstm)->Write(szBuf, lstrlen(szBuf)*sizeof(TCHAR), NULL);
}
// Validity Messages
ids = idsWrnSecurityTrustAddress; //base
for (i=ATHSEC_NUMVALIDITYBITS; i; i--)
{
if (!AthLoadString(
(ul & 0x1)
? ids
: ids+OFFSET_SMIMEOK,
szRes, ARRAYSIZE(szRes)))
{
continue;
}
wnsprintf(szBuf, ARRAYSIZE(szBuf), s_szHTMLRow,
(ul & 0x1) ? s_szHTMLgifBAD : s_szHTMLgifGOOD,
(ul & 0x1) ? s_szHTMLclassBAD : s_szHTMLclassGOOD,
szRes);
if (ul & 0x1)
{
fBadThingsHappened = TRUE;
}
(*ppstm)->Write(szBuf, lstrlen(szBuf)*sizeof(TCHAR), NULL);
if (ul & 0x1 && ids == idsWrnSecurityTrustAddress)
{
// Output the email addresses
// Certificate first
if (AthLoadString(idsWrnSecurityTrustAddressSigner, szRes, ARRAYSIZE(szRes))) {
wnsprintf(szBuf, ARRAYSIZE(szBuf), s_szHTMLRowNoIcon,
s_szHTMLclassBAD,
szRes,
pSecState->szSignerEmail ? pSecState->szSignerEmail : "");
(*ppstm)->Write(szBuf, lstrlen(szBuf)*sizeof(TCHAR), NULL);
}
// Then the Sender
if (AthLoadString(idsWrnSecurityTrustAddressSender , szRes, ARRAYSIZE(szRes))) {
wnsprintf(szBuf, ARRAYSIZE(szBuf), s_szHTMLRowNoIcon,
s_szHTMLclassBAD,
szRes,
pSecState->szSenderEmail ? pSecState->szSenderEmail : "");
(*ppstm)->Write(szBuf, lstrlen(szBuf)*sizeof(TCHAR), NULL);
}
}
ul >>= 1;
ids++;
}
Assert(0==ul);
// Response script
CHECKHR(hr = HrLoadStreamFileFromResource("secwarn2.htm", ppstm));
// main() function
if ((pSecState->ro_msg_validity & MSV_BADSIGNATURE) ||
(pSecState->ro_msg_validity & MSV_EXPIRED_SIGNINGCERT) ||
(wTrusted & ATHSEC_NOTRUSTNOTTRUSTED))
fBadThingsHappened = TRUE;
wnsprintf(szBuf, ARRAYSIZE(szBuf), s_szHTMLmain,
fBadThingsHappened ? s_szHTMLclassBAD : s_szHTMLclassUNK,
!pSecState->fHaveCert, // fDisableCheckbox,
fDisableCheckbox,
fDisableCheckbox, // !pSecState->fHaveCert,
!pSecState->fHaveCert);
CHECKHR(hr = (*ppstm)->Write(szBuf, lstrlen(szBuf)*sizeof(TCHAR), NULL));
// Finish
CHECKHR(hr = (*ppstm)->Write(s_szHTMLCloseAll, sizeof(s_szHTMLCloseAll)-sizeof(TCHAR), NULL));
#ifdef DEBUG
WriteStreamToFile(*ppstm, "c:\\oesecstm.htm", CREATE_ALWAYS, GENERIC_WRITE);
#endif
exit:
return hr;
}
HRESULT HrDumpLineToStream(LPSTREAM *ppstm, UINT *ids, TCHAR *szPar)
{
TCHAR szRes[CCHMAX_STRINGRES];
TCHAR szBuf[CCHMAX_STRINGRES];
if(*ids)
{
AthLoadString(*ids, szRes, ARRAYSIZE(szRes));
wnsprintf(szBuf, ARRAYSIZE(szBuf), s_szHTMLRowForRec, szRes, szPar);
(*ppstm)->Write(szBuf, lstrlen(szBuf)*sizeof(TCHAR), NULL);
*ids = 0;
}
return(S_OK);
}
HRESULT HrOutputRecHasProblems(LPSTREAM *ppstm, SECSTATE *pSecState)
{
HRESULT hr = S_OK;
const WORD wTrusted = LOWORD(pSecState->user_validity);
UINT ids = 0;
UINT ids1 = 0;
TCHAR szBuf[CCHMAX_STRINGRES];
ULONG ul = ULONG(HIWORD(pSecState->user_validity));
int i;
if(AthLoadString(idsRecHasProblems, szBuf, ARRAYSIZE(szBuf)))
(*ppstm)->Write(szBuf, lstrlen(szBuf)*sizeof(TCHAR), NULL);
// 1. Tamper
if(pSecState->ro_msg_validity & MSV_SIGNATURE_MASK)
ids = (pSecState->ro_msg_validity & MSV_BADSIGNATURE) ? idsWrnSecurityMsgTamper : idsUnkSecurityMsgTamper;
else if(!pSecState->fHaveCert)
ids = idsUnkSecurityMsgTamper;
HrDumpLineToStream(ppstm, &ids, NULL);
// 2. Trust
if(wTrusted)
{
ids = (wTrusted & ATHSEC_NOTRUSTUNKNOWN) ? idsUnkSecurityTrust : idsWrnSecurityTrustNotTrusted;
HrDumpLineToStream(ppstm, &ids, NULL);
}
// 3. Expire
if(pSecState->ro_msg_validity & MSV_EXPIRED_SIGNINGCERT)
{
ids = idsWrnSecurityTrustExpired;
HrDumpLineToStream(ppstm, &ids, NULL);
}
// Validity Messages
ids = idsWrnSecurityTrustAddress; //base
for (i=ATHSEC_NUMVALIDITYBITS; i; i--)
{
if (ul & 0x1)
{
if(ids == idsWrnSecurityTrustAddress)
{
ids1 = idsWrnSecurityTrustAddress;
HrDumpLineToStream(ppstm, &ids1, NULL);
ids1 = idsWrnSecurityTrustAddressSigner;
HrDumpLineToStream(ppstm, &ids1, pSecState->szSignerEmail);
ids1 = idsWrnSecurityTrustAddressSender;
HrDumpLineToStream(ppstm, &ids1, pSecState->szSenderEmail);
}
else
{
ids1 = ids;
HrDumpLineToStream(ppstm, &ids1, NULL);
}
}
ul >>= 1;
ids++;
}
return(S_OK);
}
HRESULT HrOutputSecureReceipt(LPSTREAM *ppstm, TCHAR * pszSubject, TCHAR * pszFrom, FILETIME * pftSentTime, FILETIME * pftSigningTime, SECSTATE *pSecState)
{
HRESULT hr = S_OK;
TCHAR szRes[CCHMAX_STRINGRES];
CHAR szTmp[CCHMAX_STRINGRES];
TCHAR szBuf[CCHMAX_STRINGRES*2];
SYSTEMTIME SysTime;
int size = 0;
IF_FAILEXIT(hr = LoadResourceToHTMLStream("secrec.htm", ppstm));
// Add To line
if(AthLoadString(idsToField, szRes, ARRAYSIZE(szRes)))
{
size = lstrlen(pszFrom);
if(size == 0)
{
if(!AthLoadString(idsRecUnknown, szTmp, ARRAYSIZE(szTmp)))
szTmp[0] = _T('\0');
wnsprintf(szBuf, ARRAYSIZE(szBuf), s_szHTMLRowForRec, szRes, szTmp);
}
else
{
if(size >= (CCHMAX_STRINGRES - lstrlen(s_szHTMLRowForRec) - lstrlen(szRes) - 2))
pszFrom[CCHMAX_STRINGRES - lstrlen(s_szHTMLRowForRec) - lstrlen(szRes) - 3] = _T('\0');
wnsprintf(szBuf, ARRAYSIZE(szBuf), s_szHTMLRowForRec, szRes, pszFrom);
}
(*ppstm)->Write(szBuf, lstrlen(szBuf)*sizeof(TCHAR), NULL);
}
// Add Subject line
if(AthLoadString(idsSubjectField, szRes, ARRAYSIZE(szRes)))
{
if(lstrlen(pszSubject) >= (CCHMAX_STRINGRES - lstrlen(s_szHTMLRowForRec) - lstrlen(szRes) - 2))
pszSubject[CCHMAX_STRINGRES - lstrlen(s_szHTMLRowForRec) - lstrlen(szRes) - 3] = _T('\0');
wnsprintf(szBuf, ARRAYSIZE(szBuf), s_szHTMLRowForRec, szRes, pszSubject);
(*ppstm)->Write(szBuf, lstrlen(szBuf)*sizeof(TCHAR), NULL);
}
// Add Sent line
if(AthLoadString(idsSentField, szRes, ARRAYSIZE(szRes)))
{
CchFileTimeToDateTimeSz(pftSentTime, szTmp, CCHMAX_STRINGRES - lstrlen(szRes) - 2, DTM_NOSECONDS);
wnsprintf(szBuf, ARRAYSIZE(szBuf), s_szHTMLRowForRec, szRes, szTmp);
(*ppstm)->Write(szBuf, lstrlen(szBuf)*sizeof(TCHAR), NULL);
}
// End of table
CHECKHR(hr = (*ppstm)->Write(s_szHMTLEndTable, sizeof(s_szHMTLEndTable)-sizeof(TCHAR), NULL));
// Final message
if(AthLoadString(idsReceiptField, szRes, ARRAYSIZE(szRes)))
{
CchFileTimeToDateTimeSz(pftSigningTime, szTmp, CCHMAX_STRINGRES - lstrlen(szRes) - 2, DTM_NOSECONDS);
wnsprintf(szBuf, ARRAYSIZE(szBuf), szRes, szTmp);
(*ppstm)->Write(szBuf, lstrlen(szBuf)*sizeof(TCHAR), NULL);
}
if(!IsSignTrusted(pSecState))
{
HrOutputRecHasProblems(ppstm, pSecState) ;
// End of table again
CHECKHR(hr = (*ppstm)->Write(s_szHMTLEndTable, sizeof(s_szHMTLEndTable)-sizeof(TCHAR), NULL));
}
// End of HTML file
CHECKHR(hr = (*ppstm)->Write(s_szHTMLEnd, sizeof(s_szHTMLEnd)-sizeof(TCHAR), NULL));
exit:
return(hr);
}
// user's itself secure receipt
HRESULT HrOutputUserSecureReceipt(LPSTREAM *ppstm, IMimeMessage *pMsg)
{
HRESULT hr = S_OK;
LPSTR lpszSubj = NULL;
LPSTR lpszTo = NULL;
CHAR szTmp[CCHMAX_STRINGRES];
TCHAR szRes[CCHMAX_STRINGRES];
TCHAR szBuf[CCHMAX_STRINGRES*2];
PROPVARIANT Var;
int size;
IF_FAILEXIT(hr = LoadResourceToHTMLStream("srsentit.htm", ppstm));
MimeOleGetBodyPropA(pMsg, HBODY_ROOT, PIDTOSTR(PID_HDR_SUBJECT), NOFLAGS, &lpszSubj);
MimeOleGetBodyPropA(pMsg, HBODY_ROOT, PIDTOSTR(PID_HDR_TO), NOFLAGS, &lpszTo);
// Add To line
if(AthLoadString(idsToField, szRes, ARRAYSIZE(szRes)))
{
// we have a name in <[email protected]>",
// need remove '<' and '>' for HTML
size = lstrlen(lpszTo);
if(lpszTo[size - 1] == _T('>'))
lpszTo[size - 1] = _T('\0');
if(lpszTo[0] == _T('<'))
lpszTo[0] = _T(' ');
if(size >= ((int) (CCHMAX_STRINGRES - sizeof(s_szHTMLRowForRec) - lstrlen(szRes) - 2)))
lpszTo[CCHMAX_STRINGRES - sizeof(s_szHTMLRowForRec) - lstrlen(szRes) - 3] = _T('\0');
wnsprintf(szBuf, ARRAYSIZE(szBuf), s_szHTMLRowForRec, szRes, lpszTo);
(*ppstm)->Write(szBuf, lstrlen(szBuf)*sizeof(TCHAR), NULL);
}
// Add Subject line
if(AthLoadString(idsSubjectField, szRes, ARRAYSIZE(szRes)))
{
size = lstrlen(szRes);
if(lstrlen(lpszSubj) >= ((int) (CCHMAX_STRINGRES - sizeof(s_szHTMLRowForRec) - size - 2)))
lpszSubj[CCHMAX_STRINGRES - sizeof(s_szHTMLRowForRec) - size - 3] = _T('\0');
wnsprintf(szBuf, ARRAYSIZE(szBuf), s_szHTMLRowForRec, szRes, lpszSubj);
(*ppstm)->Write(szBuf, lstrlen(szBuf)*sizeof(TCHAR), NULL);
}
// End of table
CHECKHR(hr = (*ppstm)->Write(s_szHMTLEndTable, sizeof(s_szHMTLEndTable)-sizeof(TCHAR), NULL));
// Final message
if(AthLoadString(idsFinalSelfReceipt, szRes, ARRAYSIZE(szRes)))
{
FILETIME ftSigningTime;
PCCERT_CONTEXT pcSigningCert = NULL;
THUMBBLOB tbSigner = {0};
BLOB blSymCaps = {0};
GetSigningCert(pMsg, &pcSigningCert, &tbSigner, &blSymCaps, &ftSigningTime);
CchFileTimeToDateTimeSz(&ftSigningTime, szTmp, ARRAYSIZE(szTmp),
DTM_NOSECONDS);
wnsprintf(szBuf, ARRAYSIZE(szBuf), szRes, szTmp);
(*ppstm)->Write(szBuf, lstrlen(szBuf)*sizeof(TCHAR), NULL);
if(pcSigningCert)
CertFreeCertificateContext(pcSigningCert);
SafeMemFree(tbSigner.pBlobData);
SafeMemFree(blSymCaps.pBlobData);
}
// End of HTML file
CHECKHR(hr = (*ppstm)->Write(s_szHTMLEnd, sizeof(s_szHTMLEnd)-sizeof(TCHAR), NULL));
exit:
SafeMemFree(lpszSubj);
SafeMemFree(lpszTo);
return(hr);
}
// secure receipt error screen
HRESULT HrOutputErrSecReceipt(LPSTREAM *ppstm, HRESULT hrError, SECSTATE *pSecState)
{
HRESULT hr = S_OK;
TCHAR szRes[CCHMAX_STRINGRES];
TCHAR szTmp[CCHMAX_STRINGRES];
TCHAR szBuf[CCHMAX_STRINGRES*2];
UINT ids = 0;
switch(hrError)
{
case MIME_E_SECURITY_RECEIPT_CANTFINDSENTITEM:
case MIME_E_SECURITY_RECEIPT_CANTFINDORGMSG:
hr = LoadResourceToHTMLStream("srecerr.htm", ppstm);
break;
case MIME_E_SECURITY_RECEIPT_NOMATCHINGRECEIPTBODY:
case MIME_E_SECURITY_RECEIPT_MSGHASHMISMATCH:
hr = LoadResourceToHTMLStream("recerr2.htm", ppstm);
break;
default:
hr = LoadResourceToHTMLStream("recerr3.htm", ppstm);
break;
}
if(FAILED(hr))
goto exit;
if(!IsSignTrusted(pSecState))
{
HrOutputRecHasProblems(ppstm, pSecState);
// End of table again
CHECKHR(hr = (*ppstm)->Write(s_szHMTLEndTable, sizeof(s_szHMTLEndTable)-sizeof(TCHAR), NULL));
}
// End of HTML file
if(AthLoadString(idsOESignature, szRes, ARRAYSIZE(szRes)))
(*ppstm)->Write(szRes, lstrlen(szRes)*sizeof(TCHAR), NULL);
CHECKHR(hr = (*ppstm)->Write(s_szHTMLEnd, sizeof(s_szHTMLEnd)-sizeof(TCHAR), NULL));
exit:
return(hr);
}