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.
 
 
 
 
 
 

483 lines
13 KiB

//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1995 - 1999
//
// File: ceformat.cpp
//
// Contents: helper functions
//
//--------------------------------------------------------------------------
#include "pch.cpp"
#pragma hdrstop
#include "celib.h"
#include <assert.h>
#include <wininet.h>
HRESULT
ceDupString(
IN WCHAR const *pwszIn,
IN WCHAR **ppwszOut)
{
DWORD cb;
HRESULT hr;
cb = (wcslen(pwszIn) + 1) * sizeof(WCHAR);
*ppwszOut = (WCHAR *) LocalAlloc(LMEM_FIXED, cb);
if (NULL == *ppwszOut)
{
hr = E_OUTOFMEMORY;
_JumpError(hr, error, "LocalAlloc");
}
CopyMemory(*ppwszOut, pwszIn, cb);
hr = S_OK;
error:
return(hr);
}
#define cwcCNMAX 64 // 64 chars max for CN
#define cwcCHOPHASHMAX (1 + 5) // "-%05hu" decimal USHORT hash digits
#define cwcCHOPBASE (cwcCNMAX - (cwcCHOPHASHMAX + cwcSUFFIXMAX))
HRESULT
ceSanitizedNameToDSName(
IN WCHAR const *pwszSanitizedName,
OUT WCHAR **ppwszNameOut)
{
HRESULT hr;
DWORD cwc;
DWORD cwcCopy;
WCHAR wszDSName[cwcCHOPBASE + cwcCHOPHASHMAX + 1];
*ppwszNameOut = NULL;
cwc = wcslen(pwszSanitizedName);
cwcCopy = cwc;
if (cwcCHOPBASE < cwcCopy)
{
cwcCopy = cwcCHOPBASE;
}
CopyMemory(wszDSName, pwszSanitizedName, cwcCopy * sizeof(WCHAR));
wszDSName[cwcCopy] = L'\0';
if (cwcCHOPBASE < cwc)
{
// Hash the rest of the name into a USHORT
USHORT usHash = 0;
DWORD i;
WCHAR *pwsz;
// Truncate an incomplete sanitized Unicode character
pwsz = wcsrchr(wszDSName, L'!');
if (NULL != pwsz && wcslen(pwsz) < 5)
{
cwcCopy -= wcslen(pwsz);
*pwsz = L'\0';
}
for (i = cwcCopy; i < cwc; i++)
{
USHORT usLowBit = (0x8000 & usHash)? 1 : 0;
usHash = ((usHash << 1) | usLowBit) + pwszSanitizedName[i];
}
wsprintf(&wszDSName[cwcCopy], L"-%05hu", usHash);
assert(wcslen(wszDSName) < ARRAYSIZE(wszDSName));
}
hr = ceDupString(wszDSName, ppwszNameOut);
_JumpIfError(hr, error, "ceDupString");
error:
return(hr);
}
HRESULT
ceInternetCanonicalizeUrl(
IN WCHAR const *pwszIn,
OUT WCHAR **ppwszOut)
{
HRESULT hr;
WCHAR *pwsz = NULL;
assert(NULL != pwszIn);
if (0 == _wcsnicmp(L"file:", pwszIn, 5))
{
hr = ceDupString(pwszIn, &pwsz);
_JumpIfError(hr, error, "ceDupString");
}
else
{
// Calculate required buffer size by passing a very small buffer
// The call will fail, and tell us how big the buffer should be.
WCHAR wszPlaceHolder[1];
DWORD cwc = ARRAYSIZE(wszPlaceHolder);
BOOL bResult;
bResult = InternetCanonicalizeUrl(
pwszIn, // lpszUrl
wszPlaceHolder, // lpszBuffer
&cwc, // lpdwBufferLength
0); // dwFlags
assert(!bResult); // This will always fail
hr = ceHLastError();
if (HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER) != hr)
{
// unexpected error
_JumpError(hr, error, "InternetCanonicalizeUrl");
}
// NOTE: InternetCanonicalizeUrl counts characters, not bytes as doc'd
// cwc includes trailing L'0'
pwsz = (WCHAR *) LocalAlloc(LMEM_FIXED, cwc * sizeof(WCHAR));
if (NULL == pwsz)
{
hr = E_OUTOFMEMORY;
_JumpError(hr, error, "LocalAlloc");
}
// canonicalize
if (!InternetCanonicalizeUrl(
pwszIn, // lpszUrl
pwsz, // lpszBuffer
&cwc, // lpdwBufferLength
0)) // dwFlags
{
hr = ceHLastError();
_JumpError(hr, error, "InternetCanonicalizeUrl");
}
}
*ppwszOut = pwsz;
pwsz = NULL;
hr = S_OK;
error:
if (NULL != pwsz)
{
LocalFree(pwsz);
}
return(hr);
}
// ceFormatCertsrvStringArray FormatMessage arguments:
//
// %1 -- Machine full DNS name: pwszServerName_p1_2;
//
// %2 -- Machine short name: first DNS component of pwszServerName_p1_2
//
// %3 -- Sanitized CA name: pwszSanitizedName_p3_7
//
// %4 -- Cert Filename Suffix:
// if 0 == iCert_p4 && MAXDWORD == iCertTarget_p4: L""
// else if MAXDWORD != iCertTarget_p4 L"(%u-%u)"
// else L"(%u)"
//
// %5 -- DS DN path to Domain root: pwszDomainDN_p5
//
// %6 -- DS DN path to Configuration container: pwszConfigDN_p6
//
// %7 -- Sanitized CA name, truncated and hash suffix added if too long:
// pwszSanitizedName_p3_7
//
// %8 -- CRL Filename/Key Name Suffix: L"" if 0 == iCRL_p8; else L"(%u)"
//
// %9 -- CRL Filename Suffix: L"" if !fDeltaCRL_p9; else L"+"
//
// %10 -- DS CRL attribute: L"" if !fDSAttrib_p10_11; depends on fDeltaCRL_p9
//
// %11 -- DS CA Cert attribute: L"" if !fDSAttrib_p10_11
//
// %12 -- DS user cert attribute
//
// %13 -- DS KRA cert attribute
//
// %14 -- DS cross cert pair attribute
#ifndef wszDSSEARCHBASECRLATTRIBUTE
#define wszDSSEARCHBASECRLATTRIBUTE L"?certificateRevocationList?base?objectclass=cRLDistributionPoint"
#endif
#ifndef wszDSSEARCHDELTACRLATTRIBUTE
#define wszDSSEARCHDELTACRLATTRIBUTE L"?deltaRevocationList?base?objectclass=cRLDistributionPoint"
#endif
#ifndef wszDSSEARCHCACERTATTRIBUTE
#define wszDSSEARCHCACERTATTRIBUTE L"?cACertificate?base?objectclass=certificationAuthority"
#endif
#ifndef wszDSSEARCHUSERCERTATTRIBUTE
#define wszDSSEARCHUSERCERTATTRIBUTE L"?userCertificate?base?objectClass=*"
#endif
#ifndef wszDSSEARCHKRACERTATTRIBUTE
#define wszDSSEARCHKRACERTATTRIBUTE L"?userCertificate?one?objectClass=msPKI-PrivateKeyRecoveryAgent"
#endif
#ifndef wszDSSEARCHCROSSCERTPAIRATTRIBUTE
#define wszDSSEARCHCROSSCERTPAIRATTRIBUTE L"?crossCertificatePair?one?objectClass=certificationAuthority"
#endif
HRESULT
ceFormatCertsrvStringArray(
IN BOOL fURL,
IN LPCWSTR pwszServerName_p1_2,
IN LPCWSTR pwszSanitizedName_p3_7,
IN DWORD iCert_p4,
IN DWORD iCertTarget_p4,
IN LPCWSTR pwszDomainDN_p5,
IN LPCWSTR pwszConfigDN_p6,
IN DWORD iCRL_p8,
IN BOOL fDeltaCRL_p9,
IN BOOL fDSAttrib_p10_11,
IN DWORD cStrings,
IN LPCWSTR *apwszStringsIn,
OUT LPWSTR *apwszStringsOut)
{
HRESULT hr = S_OK;
LPCWSTR apwszInsertionArray[100]; // 100 'cause this is the max number of insertion numbers allowed by FormatMessage
LPWSTR pwszCurrent = NULL;
BSTR strShortMachineName = NULL;
DWORD i;
WCHAR *pwszSanitizedDSName = NULL;
WCHAR wszCertSuffix[2 * cwcFILENAMESUFFIXMAX];
WCHAR wszCRLSuffix[cwcFILENAMESUFFIXMAX];
WCHAR wszDeltaCRLSuffix[cwcFILENAMESUFFIXMAX];
WCHAR const *pwszT;
ZeroMemory(apwszStringsOut, cStrings * sizeof(apwszStringsOut[0]));
ZeroMemory(apwszInsertionArray, sizeof(apwszInsertionArray));
// Format the template into a real name
// Initialize the insertion string array.
//+================================================
// Machine DNS name (%1)
assert(L'1' == wszFCSAPARM_SERVERDNSNAME[1]);
apwszInsertionArray[1 - 1] = pwszServerName_p1_2;
//+================================================
// Short Machine Name (%2)
assert(L'2' == wszFCSAPARM_SERVERSHORTNAME[1]);
strShortMachineName = SysAllocString(pwszServerName_p1_2);
if (strShortMachineName == NULL)
{
hr = E_OUTOFMEMORY;
_JumpIfError(hr, error, "SysAllocString");
}
pwszCurrent = wcschr(strShortMachineName, L'.');
if (NULL != pwszCurrent)
{
*pwszCurrent = 0;
}
apwszInsertionArray[2 - 1] = strShortMachineName;
//+================================================
// sanitized name (%3)
assert(L'3' == wszFCSAPARM_SANITIZEDCANAME[1]);
apwszInsertionArray[3 - 1] = pwszSanitizedName_p3_7;
//+================================================
// Cert filename suffix (%4) | (%4-%4)
assert(L'4' == wszFCSAPARM_CERTFILENAMESUFFIX[1]);
wszCertSuffix[0] = L'\0';
if (0 != iCert_p4 || MAXDWORD != iCertTarget_p4)
{
wsprintf(
wszCertSuffix,
MAXDWORD != iCertTarget_p4? L"(%u-%u)" : L"(%u)",
iCert_p4,
iCertTarget_p4);
}
apwszInsertionArray[4 - 1] = wszCertSuffix;
//+================================================
// Domain DN (%5)
if (NULL == pwszDomainDN_p5 || L'\0' == *pwszDomainDN_p5)
{
pwszDomainDN_p5 = L"DC=UnavailableDomainDN";
}
assert(L'5' == wszFCSAPARM_DOMAINDN[1]);
apwszInsertionArray[5 - 1] = pwszDomainDN_p5;
//+================================================
// Config DN (%6)
if (NULL == pwszConfigDN_p6 || L'\0' == *pwszConfigDN_p6)
{
pwszConfigDN_p6 = L"DC=UnavailableConfigDN";
}
assert(L'6' == wszFCSAPARM_CONFIGDN[1]);
apwszInsertionArray[6 - 1] = pwszConfigDN_p6;
// Don't pass pwszSanitizedName_p3_7 to SysAllocStringLen with the extended
// length to avoid faulting past end of pwszSanitizedName_p3_7.
//+================================================
// Sanitized Short Name (%7)
assert(L'7' == wszFCSAPARM_SANITIZEDCANAMEHASH[1]);
hr = ceSanitizedNameToDSName(pwszSanitizedName_p3_7, &pwszSanitizedDSName);
_JumpIfError(hr, error, "ceSanitizedNameToDSName");
apwszInsertionArray[7 - 1] = pwszSanitizedDSName;
//+================================================
// CRL filename suffix (%8)
assert(L'8' == wszFCSAPARM_CRLFILENAMESUFFIX[1]);
wszCRLSuffix[0] = L'\0';
if (0 != iCRL_p8)
{
wsprintf(wszCRLSuffix, L"(%u)", iCRL_p8);
}
apwszInsertionArray[8 - 1] = wszCRLSuffix;
//+================================================
// Delta CRL filename suffix (%9)
assert(L'9' == wszFCSAPARM_CRLDELTAFILENAMESUFFIX[1]);
wszDeltaCRLSuffix[0] = L'\0';
if (fDeltaCRL_p9)
{
wcscpy(wszDeltaCRLSuffix, L"+");
}
apwszInsertionArray[9 - 1] = wszDeltaCRLSuffix;
//+================================================
// CRL attribute (%10)
assert(L'1' == wszFCSAPARM_DSCRLATTRIBUTE[1]);
assert(L'0' == wszFCSAPARM_DSCRLATTRIBUTE[2]);
pwszT = L"";
if (fDSAttrib_p10_11)
{
pwszT = fDeltaCRL_p9?
wszDSSEARCHDELTACRLATTRIBUTE :
wszDSSEARCHBASECRLATTRIBUTE;
}
apwszInsertionArray[10 - 1] = pwszT;
//+================================================
// CA cert attribute (%11)
assert(L'1' == wszFCSAPARM_DSCACERTATTRIBUTE[1]);
assert(L'1' == wszFCSAPARM_DSCACERTATTRIBUTE[2]);
pwszT = L"";
if (fDSAttrib_p10_11)
{
pwszT = wszDSSEARCHCACERTATTRIBUTE;
}
apwszInsertionArray[11 - 1] = pwszT;
//+================================================
// User cert attribute (%12)
assert(L'1' == wszFCSAPARM_DSUSERCERTATTRIBUTE[1]);
assert(L'2' == wszFCSAPARM_DSUSERCERTATTRIBUTE[2]);
pwszT = L"";
if (fDSAttrib_p10_11)
{
pwszT = wszDSSEARCHUSERCERTATTRIBUTE;
}
apwszInsertionArray[12 - 1] = pwszT;
//+================================================
// KRA cert attribute (%13)
assert(L'1' == wszFCSAPARM_DSKRACERTATTRIBUTE[1]);
assert(L'3' == wszFCSAPARM_DSKRACERTATTRIBUTE[2]);
pwszT = L"";
if (fDSAttrib_p10_11)
{
pwszT = wszDSSEARCHKRACERTATTRIBUTE;
}
apwszInsertionArray[13 - 1] = pwszT;
//+================================================
// Cross cert pair attribute (%14)
assert(L'1' == wszFCSAPARM_DSCROSSCERTPAIRATTRIBUTE[1]);
assert(L'4' == wszFCSAPARM_DSCROSSCERTPAIRATTRIBUTE[2]);
pwszT = L"";
if (fDSAttrib_p10_11)
{
pwszT = wszDSSEARCHCROSSCERTPAIRATTRIBUTE;
}
apwszInsertionArray[14 - 1] = pwszT;
//+================================================
// Now format the strings...
for (i = 0; i < cStrings; i++)
{
if (0 == FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_STRING |
FORMAT_MESSAGE_ARGUMENT_ARRAY,
(VOID *) apwszStringsIn[i],
0, // dwMessageID
0, // dwLanguageID
(LPWSTR) &apwszStringsOut[i],
wcslen(apwszStringsIn[i]),
(va_list *) apwszInsertionArray))
{
hr = ceHLastError();
_JumpError(hr, error, "FormatMessage");
}
if (fURL)
{
WCHAR *pwsz;
hr = ceInternetCanonicalizeUrl(apwszStringsOut[i], &pwsz);
_JumpIfError(hr, error, "ceInternetCanonicalizeUrl");
LocalFree(apwszStringsOut[i]);
apwszStringsOut[i] = pwsz;
}
}
error:
if (S_OK != hr)
{
for (i = 0; i < cStrings; i++)
{
if (NULL != apwszStringsOut[i])
{
LocalFree(apwszStringsOut[i]);
apwszStringsOut[i] = NULL;
}
}
}
if (NULL != strShortMachineName)
{
SysFreeString(strShortMachineName);
}
if (NULL != pwszSanitizedDSName)
{
LocalFree(pwszSanitizedDSName);
}
return (hr);
}