Windows2003-3790/inetcore/outlookexpress/msoert/protstor.cpp
2020-09-30 16:53:55 +02:00

352 lines
9.7 KiB
C++

/*
** p r o t s t o r . c p p
**
** Purpose:
** Functions to provide blob-level access to the pstore
**
** Note:
** LocalAlloc/Free are used for memory allocation
**
** History
** 2/12/97: (t-erikne) created
**
** Copyright (C) Microsoft Corp. 1997.
*/
///////////////////////////////////////////////////////////////////////////
//
// Depends on
//
#include "pch.hxx"
#include <pstore.h>
#include "wstrings.h"
#include <error.h>
#ifdef MAC
#include <mapinls.h>
#endif // !MAC
#include <BadStrFunctions.h>
///////////////////////////////////////////////////////////////////////////
//
// Static Things
//
static void _PST_GenerateTagName(LPWSTR pwsz, DWORD cch, DWORD offset);
#ifdef DEBUG
#define test3sub_string L"Test 3 SUBType"
// {220D5CC2-853A-11d0-84BC-00C04FD43F8F}
static GUID test3sub =
{ 0x220d5cc2, 0x853a, 0x11d0, { 0x84, 0xbc, 0x0, 0xc0, 0x4f, 0xd4, 0x3f, 0x8f } };
// {4E741310-850D-11d0-84BB-00C04FD43F8F}
static GUID NOT_EXIST =
{ 0x4e741310, 0x850d, 0x11d0, { 0x84, 0xbb, 0x0, 0xc0, 0x4f, 0xd4, 0x3f, 0x8f } };
// {FFAC62F0-8533-11d0-84BC-00C04FD43F8F}
#define NoRuleSubType_string L"Foobar bang with no rules"
static GUID NoRuleSubType =
{ 0xffac62f0, 0x8533, 0x11d0, { 0x84, 0xbc, 0x0, 0xc0, 0x4f, 0xd4, 0x3f, 0x8f } };
#endif
///////////////////////////////////////////////////////////////////////////
//
// Functions
//
OESTDAPI_(HRESULT) PSTSetNewData(
IN IPStore *const pISecProv,
IN const GUID *const guidType,
IN const GUID *const guidSubt,
IN LPCWSTR wszAccountName,
IN const BLOB *const pclear,
OUT BLOB *const phandle)
{
HRESULT hr = S_OK;
const int cchLookup = 80;
WCHAR wszLookup[cchLookup];
PST_PROMPTINFO PromptInfo = { sizeof(PST_PROMPTINFO), 0, NULL, L""};
DWORD count = 0;
BYTE *pb = NULL;
if (!(pISecProv &&
guidType && guidSubt &&
wszAccountName &&
pclear && pclear->pBlobData && pclear->cbSize))
return E_INVALIDARG;
if (phandle)
phandle->pBlobData = NULL;
StrCpyNW(wszLookup, wszAccountName, cchLookup);
do
{
// if they didn't give us an out param for the lookup, then it is
// dumb to make one. Just try the AccountName
if (phandle)
_PST_GenerateTagName(wszLookup, cchLookup, count++);
hr = pISecProv->WriteItem(
PST_KEY_CURRENT_USER,
guidType,
guidSubt,
wszLookup,
pclear->cbSize,
pclear->pBlobData,
&PromptInfo,
PST_CF_NONE,
PST_NO_OVERWRITE);
if (!phandle)
{
// if we didn't get an out param, we are done regardless
break;
}
}
while (PST_E_ITEM_EXISTS == hr);
if (SUCCEEDED(hr))
{
// we created it
if (phandle)
{
phandle->cbSize = (lstrlenW(wszLookup) + 1) * sizeof(WCHAR);
//NOTE: LocalAlloc is our memory allocator
phandle->pBlobData = (BYTE *)LocalAlloc(LMEM_ZEROINIT, phandle->cbSize);
if (!phandle->pBlobData)
{
hr = E_OUTOFMEMORY;
goto exit;
}
StrCpyNW((LPWSTR)phandle->pBlobData, wszLookup, (phandle->cbSize / sizeof(wszLookup[0])));
}
}
exit:
return hr;
}
OESTDAPI_(HRESULT) PSTGetData(
IN IPStore *const pISecProv,
IN const GUID *const guidType,
IN const GUID *const guidSubt,
IN LPCWSTR wszLookupName,
OUT BLOB *const pclear)
{
HRESULT hr;
PST_PROMPTINFO PromptInfo = { sizeof(PST_PROMPTINFO), 0, NULL, L""};
pclear->pBlobData = NULL;
pclear->cbSize = 0;
if (!(pISecProv && wszLookupName && pclear))
return E_INVALIDARG;
if (SUCCEEDED(hr = pISecProv->OpenItem(
PST_KEY_CURRENT_USER,
guidType,
guidSubt,
wszLookupName,
PST_READ,
&PromptInfo,
0)))
{
hr = pISecProv->ReadItem(
PST_KEY_CURRENT_USER,
guidType,
guidSubt,
wszLookupName,
&pclear->cbSize,
&pclear->pBlobData, // ppbData
&PromptInfo, // pPromptInfo
0); // dwFlags
// don't care if this fails
pISecProv->CloseItem(
PST_KEY_CURRENT_USER,
guidType,
guidSubt,
wszLookupName,
0);
}
if (FAILED(TrapError(hr)))
hr = hrPasswordNotFound;
return hr;
}
OESTDAPI_(LPWSTR) WszGenerateNameFromBlob(IN BLOB blob)
{
LPWSTR szW = NULL;
TCHAR szT[100];
DWORD *pdw;
TCHAR *pt;
int i, max;
DWORD cch;
if (blob.cbSize > ARRAYSIZE(szT) ||
blob.cbSize % sizeof(DWORD))
return NULL;
cch = (blob.cbSize*2)+1;
szW = (LPWSTR)LocalAlloc(LMEM_ZEROINIT, cch*sizeof(WCHAR));
if (!szW)
return NULL;
pt = szT;
szT[0] = '\000';
pdw = (DWORD *)blob.pBlobData;
max = blob.cbSize / sizeof(DWORD);
for (i = 0; i < max; i++, pdw++)
{
DWORD cchLeft = (ARRAYSIZE(szT) - (DWORD)(pt - szT) - 1); // Good old typing will convert the pointer math to # of chars instead of # of bytes.
if (cchLeft)
{
pt += wnsprintf(pt, cchLeft, "%X", *pdw);
}
}
*pt = '\000';
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szT, cch, szW, cch);
szW[cch-1] = 0;
return szW;
}
OESTDAPI_(void) PSTFreeHandle(LPBYTE pb)
{
if (pb)
LocalFree((HLOCAL)pb);
}
OESTDAPI_(HRESULT) PSTCreateTypeSubType_NoUI(
IN IPStore *const pISecProv,
IN const GUID *const guidType,
IN LPCWSTR szType,
IN const GUID *const guidSubt,
IN LPCWSTR szSubt)
{
#ifdef ENABLE_RULES
PST_ACCESSRULESET RuleSet;
PST_ACCESSRULE rgRules[2];
#endif
PST_TYPEINFO Info;
HRESULT hr;
if (!pISecProv)
return E_INVALIDARG;
Info.cbSize = sizeof(PST_TYPEINFO);
// if type is not available the create it
Info.szDisplayName = (LPWSTR)szType;
if (S_OK != (hr = pISecProv->CreateType(PST_KEY_CURRENT_USER,
guidType,
&Info,
0)))
{
if (PST_E_TYPE_EXISTS != hr)
goto exit;
}
// make rules for read, write access
#ifdef ATH_RELEASE_BUILD
#error Need to enable access rules for protected store passwords? (t-erikne)
#endif
#ifdef ENABLE_RULES
// Do Rule Stuff
RuleSet.cbSize = sizeof(PST_ACCESSRULESET);
RuleSet.cRules = 2;
RuleSet.rgRules = rgRules;
//PST_BINARYCHECKDATA bindata;
PST_ACCESSCLAUSE rgClauses[1];
//N need to or on on the authenticode stuff
// derive the calling exe (me) and only allow access to me
rgClauses[0].ClaTYPE_GUID = PST_CURRENT_EXE;
rgClauses[0].cbClauseData = 0;
rgClauses[0].pbClauseData = NULL;
rgRules[0].AccessModeFlags = PST_READ; // READ: just exe
rgRules[0].cClauses = 1;
rgRules[0].rgClauses = rgClauses;
rgRules[1].AccessModeFlags = PST_WRITE; // WRITE: just exe
rgRules[1].cClauses = 1;
rgRules[1].rgClauses = rgClauses;
#endif
// create the server password subtype
Info.szDisplayName = (LPWSTR)szSubt;
if (S_OK !=
(hr = pISecProv->CreateSubtype(
PST_KEY_CURRENT_USER,
guidType,
guidSubt,
&Info,
#ifdef ENABLE_RULES
&Rules,
#else
NULL,
#endif
0)))
{
if (PST_E_TYPE_EXISTS != hr)
goto exit;
}
hr = S_OK; // cool if we made it here
exit:
return hr;
}
///////////////////////////////////////////////////////////////////////////
//
// Static utility functions
//
void _PST_GenerateTagName(LPWSTR pwsz, DWORD cch, DWORD offset)
{
SYSTEMTIME stNow;
FILETIME ftNow;
const int cchArrLen = 32;
WCHAR wszTime[cchArrLen];
TCHAR szT[cchArrLen];
UINT ich=0;
UINT cchLen=lstrlenW(pwsz);
GetLocalTime(&stNow);
ZeroMemory(&ftNow, sizeof(ftNow));
SystemTimeToFileTime(&stNow, &ftNow);
// Raid 48394 - 2 backslashes in account friendly name causes the account to not be fully created
while (ich < cchLen)
{
if (L'\\' == pwsz[ich])
{
MoveMemory((LPBYTE)pwsz + (sizeof(WCHAR) * ich), (LPBYTE)pwsz + ((ich + 1) * sizeof(WCHAR)), (cchLen - ich) * sizeof(WCHAR));
cchLen--;
}
else
ich++;
}
wnsprintf(szT, ARRAYSIZE(szT), TEXT("%08.8lX"), ftNow.dwLowDateTime+offset);
if (MultiByteToWideChar(CP_ACP, 0, szT, -1, wszTime, cchArrLen))
{
const int cchTime = lstrlenW(wszTime);
if (long(cch) > lstrlenW(pwsz)+cchTime)
StrCatBuffW(pwsz, wszTime, cch);
else
StrCpyNW(&pwsz[cch-cchTime-1], wszTime, (cchTime + 1));
}
return;
}