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.
832 lines
23 KiB
832 lines
23 KiB
/*++
|
|
|
|
Copyright (c) 1998 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
cred.cxx
|
|
|
|
Abstract:
|
|
|
|
Shared memory data structures for digest sspi package.
|
|
|
|
|
|
Author:
|
|
|
|
Adriaan Canter (adriaanc) 01-Aug-1998
|
|
|
|
--*/
|
|
|
|
#include "include.hxx"
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CEntry Functions
|
|
//
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
// CEntry::Free
|
|
// BUGBUG - inline this.
|
|
//--------------------------------------------------------------------
|
|
DWORD CEntry::Free(CMMFile *pMMFile, CEntry *pEntry)
|
|
{
|
|
BOOL bFree = pMMFile->FreeEntry(pEntry);
|
|
return (bFree ? ERROR_SUCCESS : ERROR_INTERNAL_ERROR);
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
// CEntry::GetNext
|
|
//--------------------------------------------------------------------
|
|
CEntry* CEntry::GetNext(CEntry *pEntry)
|
|
{
|
|
if (pEntry->dwNext)
|
|
return (CEntry*) OFFSET_TO_POINTER(g_pHeap, pEntry->dwNext);
|
|
return NULL;
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
// CEntry::GetPrev
|
|
//--------------------------------------------------------------------
|
|
CEntry* CEntry::GetPrev(CEntry *pEntry)
|
|
{
|
|
if (pEntry->dwPrev)
|
|
return (CEntry*) OFFSET_TO_POINTER(g_pHeap, pEntry->dwPrev);
|
|
return NULL;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CSess Functions
|
|
//
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
// CSess::Create
|
|
//--------------------------------------------------------------------
|
|
CSess* CSess::Create(CMMFile *pMMFile,
|
|
LPSTR szAppCtx, LPSTR szUserCtx, BOOL fHTTP)
|
|
{
|
|
DIGEST_ASSERT(pMMFile);
|
|
|
|
// Unaligned Sess lengths.
|
|
DWORD cbAppCtx = szAppCtx ? strlen(szAppCtx) + 1 : 0;
|
|
DWORD cbUserCtx = szUserCtx ? strlen(szUserCtx) + 1 : 0;
|
|
|
|
// Aligned Sess lengths.
|
|
DWORD cbStructAligned = ROUNDUPDWORD(sizeof(CSess));
|
|
DWORD cbAppCtxAligned = ROUNDUPDWORD(cbAppCtx);
|
|
DWORD cbUserCtxAligned = ROUNDUPDWORD(cbUserCtx);
|
|
|
|
// Total number of required bytes (aligned).
|
|
DWORD cbEntryAligned = cbStructAligned
|
|
+ cbAppCtxAligned + cbUserCtxAligned;
|
|
|
|
// Allocate from mem map.
|
|
CSess *pSess = (CSess*) pMMFile->AllocateEntry(cbEntryAligned);
|
|
|
|
if (!pSess)
|
|
{
|
|
DIGEST_ASSERT(FALSE);
|
|
goto exit;
|
|
}
|
|
|
|
DWORD cbCurrentOffset;
|
|
cbCurrentOffset = cbStructAligned;
|
|
|
|
pSess->dwAppCtx = pSess->dwUserCtx = 0;
|
|
|
|
// AppCtx
|
|
if (szAppCtx)
|
|
{
|
|
memcpy(OFFSET_TO_POINTER(pSess, cbCurrentOffset), szAppCtx, cbAppCtx);
|
|
pSess->dwAppCtx = cbCurrentOffset;
|
|
cbCurrentOffset += cbAppCtxAligned;
|
|
}
|
|
|
|
// UserCtx
|
|
if (szUserCtx)
|
|
{
|
|
memcpy(OFFSET_TO_POINTER(pSess, cbCurrentOffset), szUserCtx, cbUserCtx);
|
|
pSess->dwUserCtx = cbCurrentOffset;
|
|
}
|
|
|
|
// No need to advance cbCurrentOffset.
|
|
|
|
pSess->cbSess = cbEntryAligned;
|
|
pSess->dwCred = 0;
|
|
pSess->dwSig = SIG_SESS;
|
|
pSess->fHTTP = fHTTP;
|
|
pSess->dwPrev = 0;
|
|
pSess->dwNext = 0;
|
|
|
|
exit:
|
|
|
|
return pSess;
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
// CSess::GetAppCtx
|
|
//--------------------------------------------------------------------
|
|
LPSTR CSess::GetAppCtx(CSess *pSess)
|
|
{
|
|
if (pSess->dwAppCtx)
|
|
return (LPSTR) OFFSET_TO_POINTER(pSess, pSess->dwAppCtx);
|
|
else
|
|
return NULL;
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
// CSess::GetUserCtx
|
|
//--------------------------------------------------------------------
|
|
LPSTR CSess::GetUserCtx(CSess *pSess)
|
|
{
|
|
if (pSess->dwUserCtx)
|
|
return (LPSTR) OFFSET_TO_POINTER(pSess, pSess->dwUserCtx);
|
|
else
|
|
return NULL;
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
// CSess::GetCtx
|
|
// Allocates a context string in local heap.
|
|
//--------------------------------------------------------------------
|
|
LPSTR CSess::GetCtx(CSess *pSess)
|
|
{
|
|
DIGEST_ASSERT(pSess);
|
|
|
|
LPSTR szAppCtx, szUserCtx, szCtx;
|
|
DWORD cbAppCtx, cbUserCtx, cbCtx;
|
|
|
|
szAppCtx = GetAppCtx(pSess);
|
|
szUserCtx = GetUserCtx(pSess);
|
|
|
|
cbAppCtx = szAppCtx ? strlen(szAppCtx) : 0;
|
|
cbUserCtx = szUserCtx ? strlen(szUserCtx) : 0;
|
|
|
|
cbCtx = cbAppCtx + sizeof(':') + cbUserCtx + sizeof('\0');
|
|
|
|
szCtx = new CHAR[cbCtx];
|
|
if (!szCtx)
|
|
{
|
|
DIGEST_ASSERT(FALSE);
|
|
return NULL;
|
|
}
|
|
|
|
// "appctx:userctx\0"
|
|
// bugbug - macro for sizeof -1
|
|
memcpy(szCtx, szAppCtx, cbAppCtx);
|
|
memcpy(szCtx + cbAppCtx, ":", sizeof(":") - 1);
|
|
memcpy(szCtx + cbAppCtx + sizeof(":") - 1, szUserCtx, cbUserCtx);
|
|
memcpy(szCtx + cbAppCtx + sizeof(":") - 1 + cbUserCtx, "\0", sizeof("\0") - 1);
|
|
|
|
return szCtx;
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
// CSess::CtxMatch
|
|
//--------------------------------------------------------------------
|
|
BOOL CSess::CtxMatch(CSess *pSess1, CSess *pSess2)
|
|
{
|
|
DIGEST_ASSERT(pSess1 && pSess2);
|
|
|
|
LPSTR szAppCtx1, szAppCtx2, szUserCtx1, szUserCtx2;
|
|
|
|
szAppCtx1 = CSess::GetAppCtx(pSess1);
|
|
szAppCtx2 = CSess::GetAppCtx(pSess2);
|
|
szUserCtx1 = CSess::GetUserCtx(pSess1);
|
|
szUserCtx2 = CSess::GetUserCtx(pSess2);
|
|
|
|
// If both AppCtx values are NULL or
|
|
// are equal to same string.
|
|
if ((!szAppCtx1 && !szAppCtx2)
|
|
|| ((szAppCtx1 && szAppCtx2)
|
|
&& !strcmp(szAppCtx1, szAppCtx2)))
|
|
{
|
|
// And both UserCtx values are NULL or
|
|
// are equal to same string.
|
|
if ((!szUserCtx1 && !szUserCtx2)
|
|
|| ((szUserCtx1 && szUserCtx2)
|
|
&& !strcmp(szUserCtx1, szUserCtx2)))
|
|
|
|
{
|
|
// Credentials are shareable.
|
|
return TRUE;
|
|
}
|
|
}
|
|
// Otherwise creds are not shareable.
|
|
return FALSE;
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
// CSess::GetCred
|
|
//--------------------------------------------------------------------
|
|
CCred *CSess::GetCred(CSess* pSess)
|
|
{
|
|
if (!pSess->dwCred)
|
|
return NULL;
|
|
return (CCred*) OFFSET_TO_POINTER(g_pHeap, pSess->dwCred);
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
// CSess::SetCred
|
|
//--------------------------------------------------------------------
|
|
CCred *CSess::SetCred(CSess* pSess, CCred* pCred)
|
|
{
|
|
if (!pCred)
|
|
pSess->dwCred = 0;
|
|
else
|
|
pSess->dwCred = POINTER_TO_OFFSET(g_pHeap, pCred);
|
|
|
|
return pCred;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CList Functions
|
|
//
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
// CList::CList
|
|
//--------------------------------------------------------------------
|
|
CList::CList()
|
|
{
|
|
_pHead = NULL;
|
|
_pCur = NULL;
|
|
_pdwOffset = NULL;
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
// CList::Init
|
|
//--------------------------------------------------------------------
|
|
CEntry* CList::Init(LPDWORD pdwOffset)
|
|
{
|
|
DIGEST_ASSERT(pdwOffset)
|
|
|
|
_pdwOffset = pdwOffset;
|
|
|
|
if (*pdwOffset)
|
|
{
|
|
_pHead = (CEntry*) OFFSET_TO_POINTER(g_pHeap, *pdwOffset);
|
|
_pCur = _pHead;
|
|
}
|
|
return _pHead;
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
// CList::Seek
|
|
//--------------------------------------------------------------------
|
|
CEntry* CList::Seek()
|
|
{
|
|
// DIGEST_ASSERT(_pHead);
|
|
_pHead = (CEntry*) OFFSET_TO_POINTER(g_pHeap, *_pdwOffset);
|
|
_pCur = _pHead;
|
|
return _pCur;
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
// CList::GetNext
|
|
//--------------------------------------------------------------------
|
|
CEntry* CList::GetNext()
|
|
{
|
|
if (! *_pdwOffset)
|
|
return NULL;
|
|
|
|
CEntry *pEntry = _pCur;
|
|
|
|
if (_pCur)
|
|
_pCur = _pCur->dwNext ?
|
|
(CEntry*) OFFSET_TO_POINTER(g_pHeap, _pCur->dwNext) : NULL;
|
|
|
|
return pEntry;
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
// CList::GetPrev
|
|
//--------------------------------------------------------------------
|
|
CEntry* CList::GetPrev()
|
|
{
|
|
if (! *_pdwOffset)
|
|
return NULL;
|
|
|
|
CEntry *pEntry = _pCur;
|
|
|
|
if (_pCur)
|
|
_pCur = _pCur->dwPrev ?
|
|
(CEntry*) OFFSET_TO_POINTER(g_pHeap, _pCur->dwPrev) : NULL;
|
|
|
|
return pEntry;
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
// CList::Insert
|
|
//--------------------------------------------------------------------
|
|
CEntry* CList::Insert(CEntry *pEntry)
|
|
{
|
|
// BUGBUG - assert pnext pprev are null
|
|
DIGEST_ASSERT(pEntry
|
|
&& (pEntry->dwPrev == pEntry->dwNext == 0));
|
|
|
|
if (!_pHead)
|
|
{
|
|
_pHead = pEntry;
|
|
}
|
|
else
|
|
{
|
|
pEntry->dwNext = POINTER_TO_OFFSET(g_pHeap, _pHead);
|
|
_pHead->dwPrev = POINTER_TO_OFFSET(g_pHeap, pEntry);
|
|
_pHead = pEntry;
|
|
}
|
|
|
|
*_pdwOffset = POINTER_TO_OFFSET(g_pHeap, pEntry);
|
|
|
|
return pEntry;
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
// CList::DeLink
|
|
//--------------------------------------------------------------------
|
|
CEntry* CList::DeLink(CEntry *pEntry)
|
|
{
|
|
DIGEST_ASSERT(pEntry);
|
|
|
|
if (pEntry == _pHead)
|
|
{
|
|
_pHead = (CEntry*) OFFSET_TO_POINTER(g_pHeap, pEntry->dwNext);
|
|
*_pdwOffset = POINTER_TO_OFFSET(g_pHeap, _pHead);
|
|
}
|
|
else
|
|
{
|
|
CEntry *pPrev;
|
|
pPrev = (CEntry*) OFFSET_TO_POINTER(g_pHeap, pEntry->dwPrev);
|
|
pPrev->dwNext = pEntry->dwNext;
|
|
}
|
|
|
|
if (pEntry->dwNext)
|
|
{
|
|
CEntry *pNext;
|
|
pNext = (CEntry*) OFFSET_TO_POINTER(g_pHeap, pEntry->dwNext);
|
|
pNext->dwPrev = pEntry->dwPrev;
|
|
}
|
|
|
|
if (_pCur == pEntry)
|
|
{
|
|
_pCur = (CEntry*) OFFSET_TO_POINTER(g_pHeap, pEntry->dwNext);
|
|
}
|
|
|
|
|
|
return pEntry;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CCred Functions
|
|
//
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
// CCred::Create
|
|
//--------------------------------------------------------------------
|
|
CCred* CCred::Create(CMMFile *pMMFile,
|
|
LPSTR szHost, LPSTR szRealm, LPSTR szUser,
|
|
LPSTR szPass, LPSTR szNonce, LPSTR szCNonce)
|
|
{
|
|
// BUGBUG - assert strings non-null. Nonce can be NULL.
|
|
DIGEST_ASSERT(pMMFile && szRealm && szUser && szPass);
|
|
|
|
CSecureStr EncryptedPassword;
|
|
|
|
if (szPass && !EncryptedPassword.SetData(szPass))
|
|
return NULL;
|
|
|
|
// Unaligned string sizes.
|
|
DWORD cbRealm = szRealm ? strlen(szRealm) + 1 : 0;
|
|
DWORD cbUser = szUser ? strlen(szUser) + 1 : 0;
|
|
DWORD cbPass = szPass ? EncryptedPassword.GetStrLen() : 0;
|
|
|
|
|
|
// Aligned string sizes.
|
|
DWORD cbStructAligned = ROUNDUPDWORD(sizeof(CCred));
|
|
DWORD cbRealmAligned = ROUNDUPDWORD(cbRealm);
|
|
DWORD cbUserAligned = ROUNDUPDWORD(cbUser);
|
|
DWORD cbPassAligned = ROUNDUPDWORD(cbPass);
|
|
|
|
// Total number of required bytes (aligned).
|
|
DWORD cbEntryAligned = cbStructAligned
|
|
+ cbRealmAligned
|
|
+ cbUserAligned
|
|
+ cbPassAligned;
|
|
|
|
// Allocate cred and nonce from memmap
|
|
// BUGBUG - MASKING PNONCE
|
|
// BUGBUG - no, I'm not.
|
|
CCred *pCred;
|
|
CNonce *pNonce, *pCNonce;
|
|
pNonce = pCNonce = NULL;
|
|
|
|
// Allocate a credential.
|
|
pCred = (CCred*) pMMFile->AllocateEntry(cbEntryAligned);
|
|
if (!pCred)
|
|
{
|
|
DIGEST_ASSERT(FALSE);
|
|
goto exit;
|
|
}
|
|
|
|
|
|
DWORD cbCurrentOffset;
|
|
cbCurrentOffset = cbStructAligned;
|
|
|
|
// Realm.
|
|
memcpy(OFFSET_TO_POINTER(pCred, cbCurrentOffset), szRealm, cbRealm);
|
|
pCred->dwRealm = cbCurrentOffset;
|
|
cbCurrentOffset += cbRealmAligned;
|
|
|
|
// User
|
|
memcpy(OFFSET_TO_POINTER(pCred, cbCurrentOffset), szUser, cbUser);
|
|
pCred->dwUser = cbCurrentOffset;
|
|
cbCurrentOffset += cbUserAligned;
|
|
|
|
// Pass
|
|
memcpy(OFFSET_TO_POINTER(pCred, cbCurrentOffset), EncryptedPassword.GetPtr(), cbPass);
|
|
pCred->dwPass = cbCurrentOffset;
|
|
pCred->cbPass = cbPass;
|
|
|
|
pCred->cbCred = cbEntryAligned;
|
|
pCred->tStamp = GetTickCount();
|
|
pCred->dwSig = SIG_CRED;
|
|
pCred->dwPrev = NULL;
|
|
pCred->dwNext = NULL;
|
|
|
|
pCred->dwNonce = 0;
|
|
pCred->dwCNonce = 0;
|
|
|
|
// Allocate nonce and client nonce if specified.
|
|
if (szNonce)
|
|
CCred::SetNonce(pMMFile, pCred, szHost, szNonce, SERVER_NONCE);
|
|
|
|
if (szCNonce)
|
|
CCred::SetNonce(pMMFile, pCred, szHost, szCNonce, CLIENT_NONCE);
|
|
exit:
|
|
|
|
return pCred;
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
// CCred::GetRealm
|
|
//--------------------------------------------------------------------
|
|
LPSTR CCred::GetRealm(CCred* pCred)
|
|
{
|
|
DIGEST_ASSERT(pCred);
|
|
if (pCred->dwRealm)
|
|
return (LPSTR) OFFSET_TO_POINTER(pCred, pCred->dwRealm);
|
|
else
|
|
return NULL;
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
// CCred::GetUser
|
|
//--------------------------------------------------------------------
|
|
LPSTR CCred::GetUser(CCred* pCred)
|
|
{
|
|
DIGEST_ASSERT(pCred);
|
|
if (pCred->dwUser)
|
|
return (LPSTR) OFFSET_TO_POINTER(pCred, pCred->dwUser);
|
|
else
|
|
return NULL;
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
// CCred::GetPass
|
|
//--------------------------------------------------------------------
|
|
LPSTR CCred::GetPass(CCred* pCred)
|
|
{
|
|
DIGEST_ASSERT(pCred);
|
|
if (pCred->dwPass)
|
|
{
|
|
CSecureStr EncryptedPassword(
|
|
(LPSTR) OFFSET_TO_POINTER(pCred, pCred->dwPass),
|
|
pCred->cbPass,
|
|
false);
|
|
return EncryptedPassword.GetUnencryptedString();
|
|
}
|
|
else
|
|
return NULL;
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
// CCred::SetNonce
|
|
//--------------------------------------------------------------------
|
|
VOID CCred::SetNonce(CMMFile *pMMFile, CCred* pCred,
|
|
LPSTR szHost, LPSTR szNonce, DWORD dwType)
|
|
{
|
|
DIGEST_ASSERT(pCred && szNonce);
|
|
|
|
// First determine if a nonce for the specified host
|
|
// already exists and delete it if it does.
|
|
CList NonceList;
|
|
NonceList.Init(dwType == SERVER_NONCE ?
|
|
&pCred->dwNonce : &pCred->dwCNonce);
|
|
|
|
CNonce *pNonce;
|
|
while (pNonce = (CNonce*) NonceList.GetNext())
|
|
{
|
|
if (CNonce::IsHostMatch(pNonce, szHost))
|
|
{
|
|
NonceList.DeLink(pNonce);
|
|
CEntry::Free(pMMFile, pNonce);
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Create a CNonce object and insert it into the list.
|
|
pNonce = CNonce::Create(pMMFile, szHost, szNonce);
|
|
if (pNonce)
|
|
{
|
|
NonceList.Seek();
|
|
NonceList.Insert(pNonce);
|
|
}
|
|
else
|
|
{
|
|
DIGEST_ASSERT(FALSE);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
// CCred::GetNonce
|
|
//--------------------------------------------------------------------
|
|
CNonce *CCred::GetNonce(CCred* pCred, LPSTR szHost, DWORD dwType)
|
|
{
|
|
CNonce *pNonce;
|
|
CList NonceList;
|
|
NonceList.Init(dwType == SERVER_NONCE ?
|
|
&pCred->dwNonce : &pCred->dwCNonce);
|
|
|
|
while (pNonce = (CNonce*) NonceList.GetNext())
|
|
{
|
|
if (CNonce::IsHostMatch(pNonce, szHost))
|
|
break;
|
|
}
|
|
return pNonce;
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
// CCred::Free
|
|
//--------------------------------------------------------------------
|
|
VOID CCred::Free(CMMFile *pMMFile, CSess *pSess, CCred *pCred)
|
|
{
|
|
CNonce *pNonce;
|
|
CList NonceList;
|
|
|
|
// Free up server nonce.
|
|
NonceList.Init(&pCred->dwNonce);
|
|
while (pNonce = (CNonce*) NonceList.GetNext())
|
|
{
|
|
NonceList.DeLink(pNonce);
|
|
CEntry::Free(pMMFile, pNonce);
|
|
}
|
|
|
|
// Free up client nonce.
|
|
NonceList.Init(&pCred->dwCNonce);
|
|
while (pNonce = (CNonce*) NonceList.GetNext())
|
|
{
|
|
NonceList.DeLink(pNonce);
|
|
CEntry::Free(pMMFile, pNonce);
|
|
}
|
|
|
|
// Remove credential from session's list.
|
|
CList CredList;
|
|
CredList.Init(&pSess->dwCred);
|
|
CredList.DeLink(pCred);
|
|
CEntry::Free(pMMFile, pCred);
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CNonce Functions
|
|
//
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
// CNonce::Create
|
|
//--------------------------------------------------------------------
|
|
CNonce* CNonce::Create(CMMFile *pMMFile, LPSTR szHost, LPSTR szNonce)
|
|
{
|
|
DIGEST_ASSERT(pMMFile && szNonce);
|
|
|
|
// Unaligned string sizes.
|
|
DWORD cbNonce = szNonce ? strlen(szNonce) + 1 : 0;
|
|
DWORD cbHost = szHost ? strlen(szHost) + 1 : 0;
|
|
|
|
// Aligned string sizes.
|
|
DWORD cbStructAligned = ROUNDUPDWORD(sizeof(CNonce));
|
|
DWORD cbNonceAligned = ROUNDUPDWORD(cbNonce);
|
|
DWORD cbHostAligned = ROUNDUPDWORD(cbHost);
|
|
|
|
// Total number of required bytes (aligned).
|
|
DWORD cbEntryAligned = cbStructAligned
|
|
+ cbHostAligned
|
|
+ cbNonceAligned;
|
|
|
|
// Allocate from mem map.
|
|
CNonce *pNonce = (CNonce*) pMMFile->AllocateEntry(cbEntryAligned);
|
|
|
|
// Failed to allocate.
|
|
if (!pNonce)
|
|
{
|
|
DIGEST_ASSERT(FALSE);
|
|
goto exit;
|
|
}
|
|
|
|
DWORD cbCurrentOffset;
|
|
cbCurrentOffset = cbStructAligned;
|
|
|
|
// Host.
|
|
if (szHost)
|
|
{
|
|
memcpy(OFFSET_TO_POINTER(pNonce, cbCurrentOffset), szHost, cbHost);
|
|
pNonce->dwHost = cbCurrentOffset;
|
|
cbCurrentOffset += cbHostAligned;
|
|
}
|
|
else
|
|
{
|
|
pNonce->dwHost = 0;
|
|
}
|
|
|
|
// Nonce.
|
|
memcpy(OFFSET_TO_POINTER(pNonce, cbCurrentOffset), szNonce, cbNonce);
|
|
pNonce->dwNonce = cbCurrentOffset;
|
|
cbCurrentOffset += cbNonceAligned;
|
|
|
|
pNonce->cbNonce = cbEntryAligned;
|
|
pNonce->cCount = 0;
|
|
|
|
pNonce->dwSig = SIG_NONC;
|
|
pNonce->dwPrev = 0;
|
|
pNonce->dwNext = 0;
|
|
|
|
exit:
|
|
|
|
return pNonce;
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
// CNonce::GetNonce
|
|
//--------------------------------------------------------------------
|
|
LPSTR CNonce::GetNonce(CNonce* pNonce)
|
|
{
|
|
if (pNonce && pNonce->dwNonce)
|
|
return (LPSTR) OFFSET_TO_POINTER(pNonce, pNonce->dwNonce);
|
|
else
|
|
return NULL;
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
// CNonce::GetCount
|
|
// bugbug - what if no nonce?
|
|
//--------------------------------------------------------------------
|
|
DWORD CNonce::GetCount(CNonce* pNonce)
|
|
{
|
|
DIGEST_ASSERT(pNonce);
|
|
return pNonce->cCount;
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
// CNonce::IsHostMatch
|
|
//--------------------------------------------------------------------
|
|
BOOL CNonce::IsHostMatch(CNonce *pNonce, LPSTR szHost)
|
|
{
|
|
if (szHost)
|
|
{
|
|
if (pNonce->dwHost
|
|
&& !strcmp(szHost, (LPSTR) OFFSET_TO_POINTER(pNonce, pNonce->dwHost)))
|
|
return TRUE;
|
|
return FALSE;
|
|
}
|
|
|
|
if (!pNonce->dwHost)
|
|
return TRUE;
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CCredInfo Functions
|
|
//
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
// CCredInfo::CCredInfo
|
|
//--------------------------------------------------------------------
|
|
CCredInfo::CCredInfo(CCred* pCred, LPSTR szHost)
|
|
{
|
|
DIGEST_ASSERT(pCred
|
|
&& (pCred->dwPass > pCred->dwUser)
|
|
&& (pCred->dwUser > pCred->dwRealm));
|
|
|
|
CCredInfo::szHost = NewString(szHost);
|
|
szRealm = NewString(CCred::GetRealm(pCred));
|
|
szUser = NewString(CCred::GetUser(pCred));
|
|
|
|
LPSTR szPass = CCred::GetPass(pCred);
|
|
|
|
if (szPass)
|
|
{
|
|
BOOL fSetDataSuccess = Password.SetData(szPass);
|
|
|
|
SecureZeroMemory(szPass, strlen(szPass));
|
|
delete [] szPass;
|
|
|
|
if (!fSetDataSuccess)
|
|
{
|
|
dwStatus = ERROR_NOT_ENOUGH_MEMORY;
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Get server nonce. This is always required.
|
|
// BUGBUG - what about pre-loading?
|
|
CNonce *pNonce;
|
|
pNonce = CCred::GetNonce(pCred, szHost, SERVER_NONCE);
|
|
if (!pNonce)
|
|
{
|
|
dwStatus = ERROR_INVALID_PARAMETER;
|
|
return;
|
|
}
|
|
szNonce = NewString(CNonce::GetNonce(pNonce));
|
|
cCount = pNonce->cCount;
|
|
|
|
pNonce = CCred::GetNonce(pCred, szHost, CLIENT_NONCE);
|
|
if (pNonce)
|
|
szCNonce = NewString(CNonce::GetNonce(pNonce));
|
|
else
|
|
szCNonce = NULL;
|
|
|
|
tStamp = pCred->tStamp;
|
|
pPrev = NULL;
|
|
pNext = NULL;
|
|
dwStatus = ERROR_SUCCESS;
|
|
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
// CCredInfo::CCredInfo
|
|
// BUGBUG - special casing for NULLs, especially szNonce.
|
|
//--------------------------------------------------------------------
|
|
CCredInfo::CCredInfo(LPSTR szHost, LPSTR szRealm, LPSTR szUser,
|
|
LPSTR szPass, LPSTR szNonce, LPSTR szCNonce)
|
|
{
|
|
CCredInfo::szHost = NewString(szHost);
|
|
CCredInfo::szRealm = NewString(szRealm);
|
|
CCredInfo::szUser = NewString(szUser);
|
|
CCredInfo::Password.SetData(szPass);
|
|
CCredInfo::szNonce = NewString(szNonce);
|
|
CCredInfo::szCNonce = NewString(szCNonce);
|
|
|
|
cCount = 0;
|
|
tStamp = 0;
|
|
pPrev = NULL;
|
|
pNext = NULL;
|
|
|
|
dwStatus = ERROR_SUCCESS;
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
// CCredInfo::~CCredInfo
|
|
//--------------------------------------------------------------------
|
|
CCredInfo::~CCredInfo()
|
|
{
|
|
if (szHost)
|
|
delete [] szHost;
|
|
if (szRealm)
|
|
delete [] szRealm;
|
|
if (szUser)
|
|
delete [] szUser;
|
|
Password.Free();
|
|
if (szNonce)
|
|
delete [] szNonce;
|
|
if (szCNonce)
|
|
delete [] szCNonce;
|
|
|
|
}
|
|
|
|
|