windows-nt/Source/XPSP1/NT/net/rras/cm/cmdial/userinfo.cpp
2020-09-26 16:20:57 +08:00

2784 lines
78 KiB
C++

//+----------------------------------------------------------------------------
//
// File: userinfo.cpp
//
// Module: CMDIAL32.DLL
//
// Synopsis: This module contains the code that handles getting/saving user info.
//
// Copyright (c) 1996-1999 Microsoft Corporation
//
// Author: henryt created 02/??/98
// quintinb created Header 08/16/99
//
//+----------------------------------------------------------------------------
#include "cmmaster.h"
#include "cmuufns.h"
#include "pwd_str.h"
#include "userinfo_str.h"
#include "conact_str.h"
///////////////////////////////////////////////////////////////////////////////////
// define's
///////////////////////////////////////////////////////////////////////////////////
//
// CM_MAX_PWD - Maximum possible size of password dataencrypted or otherwise.
// Includes inbound buffer size + room for encryption expansion.
//
const DWORD CM_MAX_PWD = PWLEN * 3; // 2.73 would be enough
//
// Define this if you want to test userinfo upgrade! You should also delete the key
// HKEY_CURRENT_USER\Software\Microsoft\Connection Manager\UserInfo\<Service Name>
//
//#define TEST_USERINFO_UPGRADE 1
#define CACHE_KEY_LEN 80 // Don't change unless you've read every comment regarding it
//
// Suffix for CacheEntry name used on Legacy and W9x. Note: the space is not a typo
const TCHAR* const c_pszCacheEntryNameSuffix = TEXT(" (Connection Manager)");
///////////////////////////////////////////////////////////////////////////////////
// typedef's
///////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
// func prototypes
///////////////////////////////////////////////////////////////////////////////////
////////////////
BOOL WriteDataToReg(
LPCTSTR pszKey,
UINT uiDataID,
DWORD dwType,
CONST BYTE *lpData,
DWORD cbData,
BOOL fAllUser);
BOOL ReadDataFromReg(
LPCTSTR pszKey,
UINT uiDataID,
LPDWORD lpdwType,
BYTE *lpData,
LPDWORD lpcbData,
BOOL fAllUser);
LPBYTE GetDataFromReg(
LPCTSTR pszKey,
UINT uiDataID,
DWORD dwType,
DWORD dwSize,
BOOL fAllUser);
BOOL DeleteDataFromReg(
LPCTSTR pszKey,
UINT uiDataID,
BOOL fAllUser);
BOOL DeleteUserInfoFromReg(
ArgsStruct *pArgs,
UINT uiEntry);
BOOL ReadPasswordFromCmp(
ArgsStruct *pArgs,
UINT uiEntry,
LPTSTR *ppszPassword);
LPCTSTR TranslateUserDataID(
UINT uiDataID);
BOOL ReadUserInfoFromCmp(
ArgsStruct *pArgs,
UINT uiEntry,
PVOID *ppvData);
BOOL DeleteUserInfoFromCmp(
ArgsStruct *pArgs,
UINT uiEntry);
DWORD RasSetCredsWrapper(
ArgsStruct *pArgs,
LPCTSTR pszPhoneBook,
DWORD dwMask,
LPCTSTR pszData);
int WriteUserInfoToRas(
ArgsStruct *pArgs,
UINT uiDataID,
PVOID pvData);
int DeleteUserInfoFromRas(
ArgsStruct *pArgs,
UINT uiEntry);
DWORD RasGetCredsWrapper(
ArgsStruct *pArgs,
LPCTSTR pszPhoneBook,
DWORD dwMask,
PVOID *ppvData);
BOOL ReadUserInfoFromRas(
ArgsStruct *pArgs,
UINT uiEntry,
PVOID *ppvData);
///////////////
BOOL ReadStringFromCache(
ArgsStruct *pArgs,
LPTSTR pszEntryName,
LPTSTR *ppszStr
);
BOOL DeleteStringFromCache(
ArgsStruct *pArgs,
LPTSTR pszEntryName
);
LPTSTR GetLegacyKeyName(ArgsStruct *pArgs);
LPTSTR EncryptPassword(
ArgsStruct *pArgs,
LPCTSTR pszPassword,
LPDWORD lpdwBufSize,
LPDWORD lpdwCryptType,
BOOL fReg,
LPSTR pszSubKey);
LPBYTE DecryptPassword(
ArgsStruct *pArgs,
LPBYTE pszEncryptedData,
DWORD dwEncryptionType,
DWORD dwEncryptedBytes,
BOOL /*fReg*/,
LPSTR pszSubKey);
LPTSTR BuildUserInfoSubKey(
LPCTSTR pszServiceKey,
BOOL fAllUser);
///////////////////////////////////////////////////////////////////////////////////
// Implementation
///////////////////////////////////////////////////////////////////////////////////
#ifdef TEST_USERINFO_UPGRADE
//+---------------------------------------------------------------------------
//
// Function: WriteStringToCache
//
// Synopsis: Write a null terminated password string to cache.
//
// Arguments: pArgs ptr to ArgsStruct
// pszEntryName name to identify the cache entry
// pszStr the string
//
// Returns: BOOL TRUE = success, FALSE = failure
//
//----------------------------------------------------------------------------
BOOL WriteStringToCache(
ArgsStruct *pArgs,
LPTSTR pszEntryName,
LPTSTR pszStr)
{
MYDBGASSERT(pArgs);
MYDBGASSERT(pszEntryName && *pszEntryName);
MYDBGASSERT(pszStr && *pszStr);
DWORD dwRes = ERROR_SUCCESS;
//
// In the legacy case, we use mpr.dll for caching user data on W9x.
// On NT we use the Local Security Authority (LSA)
//
if (OS_NT)
{
if (InitLsa(pArgs))
{
if (!(*ppszStr = (LPTSTR)CmMalloc(dwBufSize)))
{
return FALSE;
}
dwRes = LSA_WriteString(pArgs, pszEntryName, pszStr);
DeInitLsa(pArgs);
}
else
{
dwRes = GetLastError();
}
}
else
{
//
// for Windows95
//
HINSTANCE hInst = NULL;
WORD (WINAPI *pfnFunc)(LPSTR,WORD,LPSTR,WORD,BYTE,UINT) = NULL;
//
// Load MPR for system password cache support
//
MYVERIFY(hInst = LoadLibraryExA("mpr.dll", NULL, 0));
if (hInst)
{
//
// Get function ptr for WNetCachePassword API and cache the password
//
MYVERIFY(pfnFunc = (WORD (WINAPI *)(LPSTR,WORD,LPSTR,WORD,BYTE,UINT))
GetProcAddress(hInst, "WNetCachePassword"));
if (pfnFunc)
{
//
// Convert the EntryName and Password Strings to Ansi
//
LPSTR pszAnsiEntryName = WzToSzWithAlloc(pszEntryName);
LPSTR pszAnsiStr = WzToSzWithAlloc(pszStr);
if (pszAnsiStr && pszAnsiEntryName)
{
//
// Store the password
//
dwRes = pfnFunc(pszAnsiEntryName,
(WORD)lstrlenA(pszAnsiEntryName),
pszAnsiStr,
(WORD)lstrlenA(pszAnsiStr),
CACHE_KEY_LEN,
0);
}
else
{
dwRes = ERROR_NOT_ENOUGH_MEMORY;
}
CmFree(pszAnsiStr);
CmFree(pszAnsiEntryName);
}
else
{
dwRes = GetLastError();
}
FreeLibrary(hInst);
}
else
{
dwRes = GetLastError();
}
}
#ifdef DEBUG
if (dwRes)
{
CMTRACE1(TEXT("WriteStringToCache() failed, err=%u."), dwRes);
}
#endif
return (ERROR_SUCCESS == dwRes);
}
#endif //TEST_USERINFO_UPGRADE
//+----------------------------------------------------------------------------
//
// Function: BuildUserInfoSubKey
//
// Synopsis: Constructs the appropriate subkey for UserInfo based on the service
// name key and the user mode of the profile.
//
// Arguments: LPCTSTR pszServiceKey - The service name key
// BOOL fAllUser - Flag indicating that profile is All-User
//
// Returns: LPTSTR - Ptr to allocated buffer containing subkey or NULL on failure.
//
// History: nickball Created 8/14/98
//
//+----------------------------------------------------------------------------
LPTSTR BuildUserInfoSubKey(LPCTSTR pszServiceKey, BOOL fAllUser)
{
MYDBGASSERT(pszServiceKey);
if (NULL == pszServiceKey)
{
return NULL;
}
//
// Use the appropriate base key
//
LPTSTR pszSubKey = NULL;
if (fAllUser)
{
pszSubKey = CmStrCpyAlloc(c_pszRegCmUserInfo);
}
else
{
pszSubKey = CmStrCpyAlloc(c_pszRegCmSingleUserInfo);
}
MYDBGASSERT(pszSubKey);
//
// Append profile service name
//
if (pszSubKey && *pszSubKey)
{
pszSubKey = CmStrCatAlloc(&pszSubKey, pszServiceKey);
MYDBGASSERT(pszSubKey);
return pszSubKey;
}
CmFree(pszSubKey);
return NULL;
}
//+----------------------------------------------------------------------------
//
// Function: BuildICSDataInfoSubKey
//
// Synopsis: Constructs the appropriate subkey for ICS UserInfo based on the service
// name key.
//
// Arguments: LPCTSTR pszServiceKey - The service name key
//
// Returns: LPTSTR - Ptr to allocated buffer containing subkey or NULL on failure.
//
// History: 03/30/2001 tomkel Created
//
//+----------------------------------------------------------------------------
LPTSTR BuildICSDataInfoSubKey(LPCTSTR pszServiceKey)
{
MYDBGASSERT(pszServiceKey);
if (NULL == pszServiceKey)
{
return NULL;
}
//
// Use the appropriate base key
//
LPTSTR pszSubKey = NULL;
pszSubKey = CmStrCpyAlloc(c_pszRegCmRoot);
MYDBGASSERT(pszSubKey);
//
// Append profile service name
//
if (pszSubKey && *pszSubKey)
{
pszSubKey = CmStrCatAlloc(&pszSubKey, pszServiceKey);
MYDBGASSERT(pszSubKey);
if (pszSubKey)
{
CmStrCatAlloc(&pszSubKey, TEXT("\\"));
if (pszSubKey)
{
CmStrCatAlloc(&pszSubKey, c_pszCmRegKeyICSDataKey);
}
}
return pszSubKey;
}
CmFree(pszSubKey);
return NULL;
}
//+----------------------------------------------------------------------------
//
// Function: dwGetWNetCachedPassword
//
// Synopsis: Wrapper to encapsulate linking to MPR.DLL and calling GetWNetCac
// hedPassword.
//
// Arguments: LPSTR pszEntryName - The names of the key used to identify the password.
// LPSTR* ppszStr - The buffer to receive the retrieved password.
// WORD* pwSizeOfStr - The size of the input buffer. Also receives
// of the # of chars retrieved.
//
// Returns: DWORD - Windows error code.
//
// History: nickball Created Header 6/17/99
//
//+----------------------------------------------------------------------------
DWORD dwGetWNetCachedPassword(LPSTR pszEntryName, LPSTR* ppszStr, WORD* pwSizeOfStr)
{
MYDBGASSERT(OS_W9X);
DWORD dwRes = ERROR_SUCCESS;
WORD (WINAPI *pfnFunc)(LPSTR,WORD,LPSTR,LPWORD,BYTE) = NULL;
HINSTANCE hInst = NULL;
//
// Load MPR for system password cache support
//
MYVERIFY(hInst = LoadLibraryExA("mpr.dll", NULL, 0));
if (hInst)
{
//
// Get function ptr for WNetGetCachedPassword API and retrieve the string
//
MYVERIFY(pfnFunc = (WORD (WINAPI *)(LPSTR,WORD,LPSTR,LPWORD,BYTE))
GetProcAddress(hInst, "WNetGetCachedPassword"));
//
// Read the cache data
//
if (pfnFunc)
{
//
// NOTE: Final param must be CACHE_KEY_LEN (80), no docs to indicate
// exact usage of API but retrieval is tied to the value used when
// storing the pwd. Thus we hard code to CACHE_KEY_LEN because this
// is the value that was used by the original version that stored
// the password in the 9X cache. The receiving buffer size is
// retained at 256 to minimize delta from latest shipping version.
//
// NT# 355459 - nickball - 6/17/99
//
dwRes = pfnFunc(pszEntryName, (WORD)lstrlenA(pszEntryName),
*ppszStr, pwSizeOfStr, CACHE_KEY_LEN);
}
else
{
dwRes = GetLastError();
}
}
else
{
dwRes = GetLastError();
}
if (NULL != hInst)
{
FreeLibrary(hInst);
}
return (dwRes);
}
//+---------------------------------------------------------------------------
//
// Function: ReadStringFromCache
//
// Synopsis: Read a null terminated string from cache.
//
// Arguments: pArgs ptr to ArgsStruct
// pszEntryName name to identify the cache entry
// ppszStr ptr to the ptr of the buffer.
//
// Returns: BOOL TRUE = success, FALSE = failure
//
//----------------------------------------------------------------------------
BOOL ReadStringFromCache(
ArgsStruct *pArgs,
LPTSTR pszEntryName,
LPTSTR *ppszStr
)
{
DWORD dwRes = ERROR_SUCCESS;
//
// Alloc buffer - the buffer is uuencoded. See UserInfoToString().
//
WORD wBufSize = 256; // arbitrary, we used to use 80 on W95
//
// On NT, we use the Local Security Authority (LSA) services for reading
// the string in the legacy case. On Win9x, we uses mpr.dll.
// Note: wBufSize is used as an in\out param, can be modified below.
//
if (OS_NT)
{
if (InitLsa(pArgs))
{
if (!(*ppszStr = (LPTSTR)CmMalloc(wBufSize)))
{
return FALSE;
}
dwRes = LSA_ReadString(pArgs, pszEntryName, *ppszStr, wBufSize);
DeInitLsa(pArgs);
}
else
{
dwRes = GetLastError();
}
}
else
{
//
// for Windows95
//
LPSTR pszAnsiStr = (LPSTR)CmMalloc(wBufSize);
LPSTR pszAnsiEntryName = WzToSzWithAlloc(pszEntryName);
if (pszAnsiStr && pszAnsiEntryName)
{
dwRes = dwGetWNetCachedPassword(pszAnsiEntryName, &pszAnsiStr, &wBufSize);
if (ERROR_SUCCESS == dwRes)
{
*ppszStr = SzToWzWithAlloc(pszAnsiStr);
if (NULL == *ppszStr)
{
dwRes = ERROR_NOT_ENOUGH_MEMORY;
}
}
}
CmFree (pszAnsiStr);
CmFree (pszAnsiEntryName);
}
if (dwRes)
{
CmFree(*ppszStr);
*ppszStr = NULL;
CMTRACE1(TEXT("ReadStringFromCache() failed, err=%u."), dwRes);
}
return (ERROR_SUCCESS == dwRes);
}
//+---------------------------------------------------------------------------
//
// Function: DeleteStringFromCache
//
// Synopsis: Delete the string from cache.
//
// Arguments: pArgs ptr to ArgsStruct
// pszEntryName name to identify the cache entry
//
// Returns: BOOL TRUE = success, FALSE = failure
//
//----------------------------------------------------------------------------
BOOL DeleteStringFromCache(
ArgsStruct *pArgs,
LPTSTR pszEntryName
)
{
DWORD dwRes;
//
// on NT, we use the Local Security Authority (LSA) services for storing
// the string. On Win95, we use mpr.dll.
//
if (OS_NT)
{
if (InitLsa(pArgs))
{
dwRes = LSA_WriteString(pArgs, pszEntryName, NULL);
DeInitLsa(pArgs);
}
else
{
dwRes = GetLastError();
}
}
else
{
//
// for Windows95
//
HINSTANCE hInst = NULL;
WORD (WINAPI *pfnFunc)(LPSTR,WORD,BYTE) = NULL;
// Load MPR for system password cache support
MYVERIFY(hInst = LoadLibraryExA("mpr.dll", NULL, 0));
// Get function ptr for WNetRemoveCachedPassword API and remove the string
if (!hInst)
{
return FALSE;
}
MYVERIFY(pfnFunc = (WORD (WINAPI *)(LPSTR,WORD,BYTE))
GetProcAddress(hInst, "WNetRemoveCachedPassword"));
if (!pfnFunc)
{
FreeLibrary(hInst);
return FALSE;
}
LPSTR pszAnsiEntryName = WzToSzWithAlloc(pszEntryName);
if (pszAnsiEntryName)
{
dwRes = pfnFunc(pszAnsiEntryName, (WORD)lstrlenA(pszAnsiEntryName), CACHE_KEY_LEN);
}
else
{
dwRes = ERROR_NOT_ENOUGH_MEMORY;
}
CmFree (pszAnsiEntryName);
FreeLibrary(hInst);
}
#ifdef DEBUG
if (dwRes)
{
CMTRACE1(TEXT("DeleteStringFromCache() LSA_WriteString/WNetRemoveCachedPassword() failed, err=%u."), dwRes);
}
#endif
return (ERROR_SUCCESS == dwRes);
}
//+---------------------------------------------------------------------------
//
// Function: RasSetCredsWrapper
//
// Synopsis: Wrapper to call RasSetCredential. This function stores the
// given string in the appropriate field of a RASCREDENTIALS struct
// (based on the value in dwMask) and calls RasSetCredentials.
//
//
// Arguments: pArgs ptr to ArgsStruct
// pszPhoneBook Full path to the phonebook file, or NULL for
// the default all user pbk
// dwMask dwMask value to set in the RASCREDENTIALS
// struct. Currently must be one of RASCM_UserName,
// RASCM_Domain, or RASCM_Password.
// pszData string data to set
//
// Returns: DWORD ERROR_SUCCESS if successful, a windows error code otherwise
//
//----------------------------------------------------------------------------
DWORD RasSetCredsWrapper(
ArgsStruct *pArgs,
LPCTSTR pszPhoneBook,
DWORD dwMask,
LPCTSTR pszData
)
{
DWORD dwRet = ERROR_INVALID_PARAMETER;
BOOL fSavePassword = TRUE;
MYDBGASSERT(pArgs && pArgs->rlsRasLink.pfnSetCredentials);
MYDBGASSERT(pszData);
MYDBGASSERT((RASCM_UserName == dwMask) || (RASCM_Domain == dwMask) || (RASCM_Password == dwMask));
if (pArgs && pszData && pArgs->rlsRasLink.pfnSetCredentials)
{
LPTSTR pszConnectoid = GetRasConnectoidName(pArgs, pArgs->piniService, FALSE);
if (pszConnectoid)
{
RASCREDENTIALS RasCredentials = {0};
RasCredentials.dwSize = sizeof(RasCredentials);
if (CM_CREDS_GLOBAL == pArgs->dwCurrentCredentialType)
{
RasCredentials.dwMask = dwMask | RASCM_DefaultCreds;
}
else
{
RasCredentials.dwMask = dwMask;
}
BOOL bClearPassword = FALSE;
if (RASCM_UserName == dwMask)
{
lstrcpyU(RasCredentials.szUserName, pszData);
}
else if (RASCM_Domain == dwMask)
{
lstrcpyU(RasCredentials.szDomain, pszData);
}
else if (RASCM_Password == dwMask)
{
if (0 == lstrcmpU(c_pszSavedPasswordToken, pszData))
{
//
// We have 16 *'s. This password is from the RAS cred store,
// so we don't want to save the 16 *'s
//
fSavePassword = FALSE;
}
else
{
lstrcpyU(RasCredentials.szPassword, pszData);
bClearPassword = (TEXT('\0') == pszData[0]);
}
}
else
{
CmFree(pszConnectoid);
return ERROR_INVALID_PARAMETER;
}
if (fSavePassword)
{
dwRet = pArgs->rlsRasLink.pfnSetCredentials(pszPhoneBook, pszConnectoid, &RasCredentials, bClearPassword);
if (ERROR_CANNOT_FIND_PHONEBOOK_ENTRY == dwRet)
{
//
// Then the phonebook entry doesn't exist yet, lets create it.
//
LPRASENTRY pRasEntry = (LPRASENTRY)CmMalloc(sizeof(RASENTRY));
if (pRasEntry && pArgs->rlsRasLink.pfnSetEntryProperties)
{
pRasEntry->dwSize = sizeof(RASENTRY);
dwRet = pArgs->rlsRasLink.pfnSetEntryProperties(pszPhoneBook, pszConnectoid, pRasEntry, pRasEntry->dwSize, NULL, 0);
//
// Lets try to set the credentials one more time ...
//
if (ERROR_SUCCESS == dwRet)
{
dwRet = pArgs->rlsRasLink.pfnSetCredentials(pszPhoneBook, pszConnectoid, &RasCredentials, bClearPassword);
}
CmFree(pRasEntry);
}
}
}
CmWipePassword(RasCredentials.szPassword);
CmFree(pszConnectoid);
}
}
return dwRet;
}
//+---------------------------------------------------------------------------
//
// Function: WriteUserInfoToRas
//
// Synopsis: Write a userinfo data to ras credential storage
//
// Arguments: pArgs ptr to ArgsStruct
// uiDataID the resource ID associated with the data
// pvData userinfo data
//
// Returns: int TRUE = success, FALSE = failure, returns -1 if RAS
// doesn't cache this piece of data and it should be put
// in the registry instead.
//
//----------------------------------------------------------------------------
int WriteUserInfoToRas(
ArgsStruct *pArgs,
UINT uiDataID,
PVOID pvData)
{
int iReturn = -1;
if (OS_NT5 && pArgs && pArgs->bUseRasCredStore)
{
DWORD dwMask;
LPTSTR pszPhoneBook = NULL;
switch (uiDataID)
{
case UD_ID_USERNAME:
dwMask = RASCM_UserName;
iReturn = (ERROR_SUCCESS == RasSetCredsWrapper(pArgs, pArgs->pszRasPbk, dwMask, (LPCTSTR)pvData));
break;
case UD_ID_PASSWORD:
dwMask = RASCM_Password;
iReturn = (ERROR_SUCCESS == RasSetCredsWrapper(pArgs, pArgs->pszRasPbk, dwMask, (LPCTSTR)pvData));
MYDBGASSERT(iReturn);
//
// Note that if we are using the same username then we want to write the password to both the
// password and the InetPassword storage. This is because we don't actually have a password, just
// 16 *'s. This tells RAS to look in its internal store for the password. The trouble is that if
// we don't cache the real password when we hand RAS the 16 *'s, it looks and finds a NULL password.
// Thus we keep both passwords the same and this avoids that problem.
//
if (pArgs->piniService->GPPB(c_pszCmSection, c_pszCmEntryUseSameUserName))
{
pszPhoneBook = CreateRasPrivatePbk(pArgs);
if (pszPhoneBook)
{
iReturn = (ERROR_SUCCESS == RasSetCredsWrapper(pArgs, pszPhoneBook, dwMask, (LPCTSTR)pvData));
CmFree(pszPhoneBook);
}
}
break;
case UD_ID_DOMAIN:
dwMask = RASCM_Domain;
iReturn = (ERROR_SUCCESS == RasSetCredsWrapper(pArgs, pArgs->pszRasPbk, dwMask, (LPCTSTR)pvData));
break;
case UD_ID_INET_PASSWORD:
dwMask = RASCM_Password;
pszPhoneBook = CreateRasPrivatePbk(pArgs);
if (pszPhoneBook)
{
iReturn = (ERROR_SUCCESS == RasSetCredsWrapper(pArgs, pszPhoneBook, dwMask, (LPCTSTR)pvData));
CmFree(pszPhoneBook);
}
break;
case UD_ID_INET_USERNAME:
dwMask = RASCM_UserName;
pszPhoneBook = CreateRasPrivatePbk(pArgs);
if (pszPhoneBook)
{
iReturn = (ERROR_SUCCESS == RasSetCredsWrapper(pArgs, pszPhoneBook, dwMask, (LPCTSTR)pvData));
CmFree(pszPhoneBook);
}
break;
default:
break;
}
}
if ((0 != iReturn) && (-1 != iReturn))
{
if (CM_CREDS_GLOBAL == pArgs->dwCurrentCredentialType)
{
CMTRACE1(TEXT("WriteUserInfoToRas() - %s saved to the Global RAS Credential store"), TranslateUserDataID(uiDataID));
}
else
{
CMTRACE1(TEXT("WriteUserInfoToRas() - %s saved to the User RAS Credential store"), TranslateUserDataID(uiDataID));
}
}
return iReturn;
}
//+---------------------------------------------------------------------------
//
// Function: WriteUserInfoToReg
//
// Synopsis: Write a userinfo data to the registry.
//
// Arguments: pArgs ptr to ArgsStruct
// uiDataID the resource ID associated with the data
// pvData userinfo data
//
// Returns: BOOL TRUE = success, FALSE = failure
//
//----------------------------------------------------------------------------
BOOL WriteUserInfoToReg(
ArgsStruct *pArgs,
UINT uiDataID,
PVOID pvData)
{
MYDBGASSERT(pArgs);
MYDBGASSERT(pvData);
BOOL fRet = FALSE;
UINT uiID = uiDataID; // can be changed in switch
BYTE *lpData;
if (NULL == pArgs || NULL == pvData)
{
return FALSE;
}
//
// Determine Reg params based upon uiDataID
//
switch (uiID)
{
case UD_ID_USERNAME:
case UD_ID_INET_USERNAME:
case UD_ID_DOMAIN:
case UD_ID_CURRENTACCESSPOINT:
{
//
// Store as strings
//
DWORD dwSize = (lstrlenU((LPTSTR)pvData) + 1) * sizeof(TCHAR);
MYDBGASSERT(dwSize <= (UNLEN + sizeof(TCHAR))); // Make sure size is reasonable
lpData = (BYTE *) pvData;
fRet = WriteDataToReg(pArgs->szServiceName, uiID, REG_SZ, lpData, dwSize, pArgs->fAllUser);
break;
}
case UD_ID_PASSWORD:
case UD_ID_INET_PASSWORD:
{
DWORD dwBufLen = 0;
DWORD dwCrypt = 0;
LPTSTR pszSubKey = BuildUserInfoSubKey(pArgs->szServiceName, pArgs->fAllUser);
LPSTR pszAnsiSubKey = WzToSzWithAlloc(pszSubKey);
if (UD_ID_INET_PASSWORD == uiID)
{
dwCrypt |= CMSECURE_ET_USE_SECOND_RND_KEY;
}
//
// Encrypt
//
LPTSTR pszEncryptedData = EncryptPassword(pArgs, (LPTSTR) pvData, &dwBufLen, &dwCrypt, TRUE, pszAnsiSubKey);
//
// Free in case we return if the function failed
//
CmFree(pszSubKey);
CmFree(pszAnsiSubKey);
if (!pszEncryptedData)
{
return FALSE;
}
MYDBGASSERT(dwBufLen <= CM_MAX_PWD); // Can't read it out otherwise
//
// Write the password and the encryption type on success
//
if (WriteDataToReg(pArgs->szServiceName, uiID, REG_BINARY, (BYTE *) pszEncryptedData, dwBufLen, pArgs->fAllUser))
{
//
// A second write for the encryption type. Written as a DWORD.
//
uiID = UD_ID_PCS;
//
// Now that we're UNICODE enabled, we will always be encrypting
// a UNICODE string, so update the crypt type, so that it can be
// properly decrypted.
//
dwCrypt = AnsiToUnicodePcs(dwCrypt);
lpData = (BYTE *) &dwCrypt;
fRet = WriteDataToReg(pArgs->szServiceName, uiID, REG_DWORD, lpData, sizeof(DWORD), pArgs->fAllUser);
}
//
// Release the buffer before we go
//
CmFree(pszEncryptedData);
break;
}
case UD_ID_NOPROMPT:
case UD_ID_REMEMBER_PWD:
case UD_ID_REMEMBER_INET_PASSWORD:
case UD_ID_ACCESSPOINTENABLED:
{
//
// Store BOOL as DWORD
//
DWORD dwTmp = *(LPBOOL)pvData;
lpData = (BYTE *) &dwTmp;
fRet = WriteDataToReg(pArgs->szServiceName, uiID, REG_DWORD, lpData, sizeof(DWORD), pArgs->fAllUser);
break;
}
default:
break;
}
MYDBGASSERT(fRet);
return fRet;
}
//+----------------------------------------------------------------------------
//
// Function: WriteDataToReg
//
// Synopsis: Stores the specified data as the specifed value under the
// specified key under the userinfo root.
//
// Arguments: LPCTSTR pszKey - The key name (service name)
// UINT uiDataID - The resource ID, used to name the value
// DWORD dwType - The registry data type
// CONST BYTE *lpData - Ptr to the data to be stored
// DWORD cbData - The size of the data buffer
// BOOL fAllUser - Flag indicating that profile is All-User
//
// Returns: BOOL - TRUE on success, otherwise FALSE
//
// History: nickball Created 5/21/98
//
//+----------------------------------------------------------------------------
BOOL WriteDataToReg(
LPCTSTR pszKey,
UINT uiDataID,
DWORD dwType,
CONST BYTE *lpData,
DWORD cbData,
BOOL fAllUser)
{
MYDBGASSERT(pszKey && *pszKey);
MYDBGASSERT(lpData);
HKEY hKeyCm;
DWORD dwDisposition;
DWORD dwRes = 1;
LPTSTR pszSubKey;
if (NULL == pszKey || !*pszKey || NULL == lpData)
{
return FALSE;
}
//
// Per-user data is always stored under HKEY_CURRENT_USER
// Build the sub key to be opened.
//
pszSubKey = BuildUserInfoSubKey(pszKey, fAllUser);
if (NULL == pszSubKey)
{
return FALSE;
}
//
// Open the sub key under HKCU
//
dwRes = RegCreateKeyExU(HKEY_CURRENT_USER,
pszSubKey,
0,
TEXT(""),
REG_OPTION_NON_VOLATILE,
KEY_SET_VALUE,
NULL,
&hKeyCm,
&dwDisposition);
//
// If we opened the key successfully, write the value
//
if (ERROR_SUCCESS == dwRes)
{
dwRes = RegSetValueExU(hKeyCm,
TranslateUserDataID(uiDataID),
NULL,
dwType,
lpData,
cbData);
#ifdef DEBUG
if (ERROR_SUCCESS == dwRes)
{
CMTRACE1(TEXT("WriteDataToReg() - %s written to registry"), TranslateUserDataID(uiDataID));
}
#endif
RegCloseKey(hKeyCm);
}
CmFree(pszSubKey);
return (ERROR_SUCCESS == dwRes);
}
//+----------------------------------------------------------------------------
//
// Function: DeleteDataFromReg
//
// Synopsis: Deletes the specified value under the specified by uiDataID
//
// Arguments: LPCTSTR pszKey - The key name (service name)
// UINT uiDataID - The resource ID, used to name the value
// BOOL fAllUser - Flag indicating that profile is All-User
//
// Returns: BOOL - TRUE on success, otherwise FALSE
//
// History: nickball Created 5/21/98
//
//+----------------------------------------------------------------------------
BOOL DeleteDataFromReg(
LPCTSTR pszKey,
UINT uiDataID,
BOOL fAllUser)
{
MYDBGASSERT(pszKey && *pszKey);
HKEY hKeyCm;
DWORD dwRes = 1;
LPTSTR pszSubKey;
if (NULL == pszKey || !*pszKey)
{
return FALSE;
}
//
// Per-user data is always stored under HKEY_CURRENT_USER
// Build the sub key to be opened.
//
pszSubKey = BuildUserInfoSubKey(pszKey, fAllUser);
if (NULL == pszSubKey)
{
return FALSE;
}
//
// Open the sub key under HKCU
//
dwRes = RegOpenKeyExU(HKEY_CURRENT_USER,
pszSubKey,
0,
KEY_SET_VALUE,
&hKeyCm);
//
// If we opened the key successfully, delete the value
//
if (ERROR_SUCCESS == dwRes)
{
dwRes = RegDeleteValueU(hKeyCm, TranslateUserDataID(uiDataID));
//
// Delete the key used for encrypting the passwords
//
if (UD_ID_PASSWORD == uiDataID)
{
dwRes = RegDeleteValueU(hKeyCm, c_pszCmRegKeyEncryptedPasswordKey);
}
if (UD_ID_INET_PASSWORD == uiDataID)
{
dwRes = RegDeleteValueU(hKeyCm, c_pszCmRegKeyEncryptedInternetPasswordKey);
}
#ifdef DEBUG
if (ERROR_SUCCESS == dwRes)
{
CMTRACE1(TEXT("DeleteDataFromReg() - %s removed from registry"), TranslateUserDataID(uiDataID));
}
#endif
RegCloseKey(hKeyCm);
}
CmFree(pszSubKey);
return (ERROR_SUCCESS == dwRes);
}
//+----------------------------------------------------------------------------
//
// Function: GetDataFromReg
//
// Synopsis: Allocates a buffer for and retrieves the specifed data from the
// registry.
//
// Arguments: LPCTSTR pszKey - The key name (service name)
// UINT uiDataID - The resource ID, used to name the value
// DWORD dwType - The registry data type
// DWORD dwSize - Numbrt of bytes in the data buffer
// BOOL fAllUser - Flag indicating that profile is All-User
//
// Returns: LPBYTE - Ptr to retrieved data, NULL on error
//
// History: nickball Created 5/21/98
//
//+----------------------------------------------------------------------------
LPBYTE GetDataFromReg(
LPCTSTR pszKey,
UINT uiDataID,
DWORD dwType,
DWORD dwSize,
BOOL fAllUser)
{
MYDBGASSERT(pszKey);
DWORD dwSizeTmp = dwSize;
DWORD dwTypeTmp = dwType;
if (NULL == pszKey || !*pszKey)
{
return NULL;
}
//
// Allocate a buffer of the desired size
//
LPBYTE lpData = (BYTE *) CmMalloc(dwSize);
if (NULL == lpData)
{
return FALSE;
}
//
// Read the data from the registry
//
if (!ReadDataFromReg(pszKey, uiDataID, &dwTypeTmp, lpData, &dwSizeTmp, fAllUser))
{
CmFree(lpData);
lpData = NULL;
}
return lpData;
}
//+---------------------------------------------------------------------------
//
// Function: ReadUserInfoFromReg
//
// Synopsis: Read the specified userinfo data from the registry.
//
// Arguments: pArgs ptr to ArgsStruct
// uiDataID the resource ID associated with the data
// ppvData ptr to ptr to be allocated and filled
//
// Returns: BOOL TRUE = success, FALSE = failure
//
//----------------------------------------------------------------------------
BOOL ReadUserInfoFromReg(
ArgsStruct *pArgs,
UINT uiDataID,
PVOID *ppvData)
{
MYDBGASSERT(pArgs);
MYDBGASSERT(ppvData);
BYTE *lpData = NULL;
if (NULL == pArgs || NULL == ppvData)
{
return FALSE;
}
//
// Set size and type as appropriate
//
switch (uiDataID)
{
case UD_ID_USERNAME:
case UD_ID_INET_USERNAME:
case UD_ID_DOMAIN:
case UD_ID_CURRENTACCESSPOINT:
{
lpData = GetDataFromReg(pArgs->szServiceName, uiDataID, REG_SZ, (UNLEN + 1) * sizeof(TCHAR), pArgs->fAllUser);
if (lpData)
{
*ppvData = lpData;
}
break;
}
case UD_ID_PASSWORD:
case UD_ID_INET_PASSWORD:
{
BYTE *lpTmp = NULL;
//
// Get the encryption type
//
lpData = GetDataFromReg(pArgs->szServiceName, UD_ID_PCS, REG_DWORD, sizeof(DWORD), pArgs->fAllUser);
if (!lpData)
{
return FALSE;
}
//
// Since we know the return value in this case is a DWORD, then cast it to DWORD pointer
// and get the value
//
DWORD dwCrypt = *((DWORD*)lpData);
CmFree(lpData);
//
// Now retrieve the encrypted password
//
lpData = GetDataFromReg(pArgs->szServiceName, uiDataID, REG_BINARY, CM_MAX_PWD, pArgs->fAllUser);
if (!lpData)
{
return FALSE;
}
//
// Decrypt it
//
DWORD dwSize = lstrlenU((LPTSTR)lpData)*sizeof(TCHAR);
//
// Crypt routines only know about Ansi PCS values, so convert as necessary
//
LPTSTR pszSubKey = BuildUserInfoSubKey(pArgs->szServiceName, pArgs->fAllUser);
LPSTR pszAnsiSubKey = WzToSzWithAlloc(pszSubKey);
if (UD_ID_INET_PASSWORD == uiDataID)
{
dwCrypt |= CMSECURE_ET_USE_SECOND_RND_KEY;
}
lpTmp = DecryptPassword(pArgs, (LPBYTE)lpData, UnicodeToAnsiPcs(dwCrypt), dwSize, TRUE, pszAnsiSubKey);
//
// Free the buffer for the reg query
//
CmFree(lpData);
//
// We're Unicode now, so if the password was encrypted
// as an Ansi string convert the data to a UNICODE string.
// Otherwise, just update the supplied buffer.
//
if (IsAnsiPcs(dwCrypt) && lpTmp)
{
*ppvData = SzToWzWithAlloc((LPSTR)lpTmp);
CmFree(lpTmp);
}
else
{
*ppvData = lpTmp;
}
//
// Assign lpData for return purposes
//
lpData = (BYTE*) *ppvData; // NULL on failure
CmFree(pszSubKey);
CmFree(pszAnsiSubKey);
break;
}
case UD_ID_NOPROMPT:
case UD_ID_REMEMBER_PWD:
case UD_ID_REMEMBER_INET_PASSWORD:
case UD_ID_ACCESSPOINTENABLED:
{
lpData = GetDataFromReg(pArgs->szServiceName, uiDataID, REG_DWORD, sizeof(DWORD), pArgs->fAllUser);
if (lpData)
{
//
// Translate to DWORD pointer and check the value
//
if (*((DWORD*)lpData))
{
*(BOOL *)*ppvData = TRUE;
}
else
{
*(BOOL *)*ppvData = FALSE;
}
CmFree(lpData);
}
break;
}
default:
MYDBGASSERT(FALSE);
return FALSE;
}
return (NULL != lpData);
}
//+----------------------------------------------------------------------------
//
// Function: ReadDataFromReg
//
// Synopsis: Retrieves the data from the specifed value under the
// specified key under the userinfo root.
//
// Arguments: LPCTSTR pszKey - The key name (service name)
// UINT uiDataID - The resource ID, used to name the value
// LPDWORD lpdwType - The registry data type expected, and returned
// CONST BYTE *lpData - Ptr to buffer for data
// LPDWORD lpcbData - The size of the data buffer
// BOOL fAllUser - Flag indicating that profile is All-User
//
// Returns: BOOL - TRUE on success, otherwise FALSE
//
// History: nickball Created 5/21/98
//
//+----------------------------------------------------------------------------
BOOL ReadDataFromReg(
LPCTSTR pszKey,
UINT uiDataID,
LPDWORD lpdwType,
BYTE *lpData,
LPDWORD lpcbData,
BOOL fAllUser)
{
MYDBGASSERT(pszKey && *pszKey);
MYDBGASSERT(lpData);
MYDBGASSERT(lpcbData);
MYDBGASSERT(lpdwType);
HKEY hKeyCm;
DWORD dwRes = 1;
DWORD dwTypeTmp; // the value returned by query
LPTSTR pszSubKey;
if (NULL == pszKey || !*pszKey || NULL == lpData)
{
return FALSE;
}
//
// Per-user data is always stored under HKEY_CURRENT_USER
// Build the sub key to be opened.
//
pszSubKey = BuildUserInfoSubKey(pszKey, fAllUser);
if (NULL == pszSubKey)
{
return FALSE;
}
//
// Open the sub key under HKCU
//
dwRes = RegOpenKeyExU(HKEY_CURRENT_USER,
pszSubKey,
0,
KEY_QUERY_VALUE,
&hKeyCm);
//
// If we opened the key successfully, retrieve the value
//
if (ERROR_SUCCESS == dwRes)
{
dwRes = RegQueryValueExU(hKeyCm,
TranslateUserDataID(uiDataID),
NULL,
&dwTypeTmp,
lpData,
lpcbData);
if (ERROR_SUCCESS == dwRes)
{
CMTRACE1(TEXT("ReadDataFromReg() - %s read from registry"), TranslateUserDataID(uiDataID));
MYDBGASSERT(*lpdwType == dwTypeTmp);
if (*lpdwType == dwTypeTmp)
{
*lpdwType = dwTypeTmp;
}
}
RegCloseKey(hKeyCm);
}
CmFree(pszSubKey);
return (ERROR_SUCCESS == dwRes && (*lpdwType == dwTypeTmp)); // sanity check that type was expected
}
//+---------------------------------------------------------------------------
//
// Function: DeleteUserInfoFromReg
//
// Synopsis: Delete userinfo data from registry
//
// Arguments: pArgs ptr to ArgsStruct
// uiEntry cmp field entry id
//
// Returns: BOOL TRUE = success, FALSE = failure
//
//----------------------------------------------------------------------------
BOOL DeleteUserInfoFromReg(
ArgsStruct *pArgs,
UINT uiEntry
)
{
return DeleteDataFromReg(pArgs->szServiceName, uiEntry, pArgs->fAllUser);
}
//+---------------------------------------------------------------------------
//
// Function: DeleteUserInfoFromRas
//
// Synopsis: Delete userinfo data from the RAS credential cache
//
// Arguments: pArgs ptr to ArgsStruct
// uiEntry cmp field entry id
//
// Returns: int TRUE = success, FALSE = failure, -1 if RAS doesn't
// store this info
//
//----------------------------------------------------------------------------
int DeleteUserInfoFromRas(
ArgsStruct *pArgs,
UINT uiEntry
)
{
LPTSTR pszEmpty = TEXT("");
return WriteUserInfoToRas(pArgs, uiEntry, pszEmpty);
}
//+---------------------------------------------------------------------------
//
// Function: ReadPasswordFromCmp
//
// Synopsis: Read a null terminated password string from Cmp.
//
// Arguments: pArgs ptr to ArgsStruct
// uiEntry cmp entry name
// ppszPassword ptr to ptr of the password buffer.
//
// Returns: BOOL TRUE = success, FALSE = failure
//
//----------------------------------------------------------------------------
BOOL ReadPasswordFromCmp(
ArgsStruct *pArgs,
UINT uiEntry,
LPTSTR *ppszPassword
)
{
MYDBGASSERT(pArgs);
MYDBGASSERT(ppszPassword);
if (NULL == pArgs || NULL == ppszPassword)
{
return FALSE;
}
//
// Read in password from profile
//
BOOL fOk = FALSE;
LPTSTR pszEncryptedData = pArgs->piniProfile->GPPS(c_pszCmSection, TranslateUserDataID(uiEntry));
if (*pszEncryptedData)
{
//
// Trim away all the spaces at both ends
//
CmStrTrim(pszEncryptedData);
//
// Get the type and decrypt
//
DWORD dwEncryptionType = (DWORD)pArgs->piniProfile->GPPI(c_pszCmSection,
c_pszCmEntryPcs,
CMSECURE_ET_RC2); // default
//
// Since this was saved in the CMP in Ansi form, we need to convert the characters back to
// Ansi form so that we can decrypt them. We still may not be able to (if we cannot
// round trip the Unicode conversion for instance) but then we will fail and display a
// blank password. Not the end of the world but hopefully avoidable.
//
LPSTR pszAnsiEncryptedData;
LPSTR pszAnsiUnEncryptedData;
pszAnsiEncryptedData = WzToSzWithAlloc(pszEncryptedData);
if (NULL != pszAnsiEncryptedData)
{
DWORD dwSize = lstrlenA(pszAnsiEncryptedData)*sizeof(TCHAR);
//
// Here we don't need to differentiate between main password and internet password
// because we are reading this from a file and the mask is used when reading to/from
// registry.
//
pszAnsiUnEncryptedData = (LPSTR)DecryptPassword(pArgs,
(LPBYTE)pszAnsiEncryptedData,
dwEncryptionType,
dwSize,
FALSE,
NULL);
if (pszAnsiUnEncryptedData)
{
*ppszPassword = SzToWzWithAlloc(pszAnsiUnEncryptedData);
if (NULL != *ppszPassword)
{
fOk = ((BOOL)**ppszPassword);
}
CmWipePasswordA(pszAnsiUnEncryptedData);
CmFree(pszAnsiUnEncryptedData);
}
}
CmFree(pszAnsiEncryptedData);
}
CmFree(pszEncryptedData);
return fOk;
}
//+---------------------------------------------------------------------------
//
// Function: ReadUserInfoFromCmp
//
// Synopsis: Read a userinfo data from cmp.
//
// Arguments: pArgs ptr to ArgsStruct
// uiEntry the cmp file entry
// ppvData ptr to ptr to the data buffer. If the userinfo
// is multiple byte(e.g. password), the func allocs
// the buffer.
//
// Returns: BOOL TRUE = success, FALSE = failure
//
//----------------------------------------------------------------------------
BOOL ReadUserInfoFromCmp(
ArgsStruct *pArgs,
UINT uiEntry,
PVOID *ppvData
)
{
switch (uiEntry)
{
case UD_ID_USERNAME:
case UD_ID_INET_USERNAME:
case UD_ID_DOMAIN:
*ppvData = (PVOID)pArgs->piniProfile->GPPS(c_pszCmSection, TranslateUserDataID(uiEntry));
break;
case UD_ID_PASSWORD:
case UD_ID_INET_PASSWORD:
return ReadPasswordFromCmp(pArgs, uiEntry, (LPTSTR *)ppvData);
break;
case UD_ID_NOPROMPT:
case UD_ID_REMEMBER_PWD:
case UD_ID_REMEMBER_INET_PASSWORD:
*(BOOL *)(*ppvData) = pArgs->piniProfile->GPPB(c_pszCmSection, TranslateUserDataID(uiEntry));
break;
//
// None of these should be in the CMP by this point. Return a failure value.
//
case UD_ID_PCS:
case UD_ID_ACCESSPOINTENABLED:
case UD_ID_CURRENTACCESSPOINT: // if we are trying to read the access point
CMASSERTMSG(FALSE, TEXT("ReadUserInfoFromCmp -- trying to read a value that should never be in the cmp, why?"));
*ppvData = NULL;
return FALSE;
break;
default:
MYDBGASSERT(0);
break;
}
return TRUE;
}
//+---------------------------------------------------------------------------
//
// Function: DeleteUserInfoFromCmp
//
// Synopsis: Deletes userinfo data from cmp.
//
// Arguments: pArgs ptr to ArgsStruct
// uiEntry the cmp file entry
//
// Returns: BOOL TRUE = success, FALSE = failure
//
//----------------------------------------------------------------------------
BOOL DeleteUserInfoFromCmp(
ArgsStruct *pArgs,
UINT uiEntry
)
{
BOOL bReturn = FALSE;
UINT uiKeepDefCreds = 0;
const TCHAR* const c_pszKeepDefaultCredentials = TEXT("KeepDefaultCredentials");
if (NULL == pArgs)
{
return bReturn;
}
switch (uiEntry)
{
case UD_ID_USERNAME:
case UD_ID_DOMAIN:
case UD_ID_INET_USERNAME:
case UD_ID_NOPROMPT:
case UD_ID_REMEMBER_PWD:
case UD_ID_REMEMBER_INET_PASSWORD:
case UD_ID_PASSWORD:
case UD_ID_INET_PASSWORD:
//
// Get KeepDefaultCredentials value from CMP
//
uiKeepDefCreds = GetPrivateProfileIntU(c_pszCmSection, c_pszKeepDefaultCredentials, 0,
pArgs->piniProfile->GetFile());
if (0 == uiKeepDefCreds)
{
if (WritePrivateProfileStringU(c_pszCmSection, TranslateUserDataID(uiEntry),
NULL, pArgs->piniProfile->GetFile()))
{
bReturn = TRUE;
}
}
break;
default:
MYDBGASSERT(0);
break;
}
return bReturn;
}
//+---------------------------------------------------------------------------
//
// Function: RasGetCredsWrapper
//
// Synopsis: Wrapper function to call RasGetCredentials. The function
// calls RasGetCredentials and then copies the appropriate data
// from the RASCREDENTIALS struct into the buffer pointed to by
// *ppvData (allocated on the caller behalf). Note that the value
// set in dwMask determines which data item is retrieved from the
// credentials cache. Currently, dwMask must be one of RASCM_UserName,
// RASCM_Domain, or RASCM_Password.
//
// Arguments: pArgs ptr to ArgsStruct
// pszPhoneBook full path to the phonebook file to get the
// data from, or NULL to use the all user default pbk
// dwMask dwMask value for the RASCREDENTIALS struct
// ppvData ptr to ptr to the data buffer. If the userinfo
// is multiple byte(e.g. password), the func allocs
// the buffer.
//
// Returns: DWORD ERROR_SUCCESS on success, winerror on failure
//
//----------------------------------------------------------------------------
DWORD RasGetCredsWrapper(
ArgsStruct *pArgs,
LPCTSTR pszPhoneBook,
DWORD dwMask,
PVOID *ppvData
)
{
DWORD dwRet = ERROR_INVALID_PARAMETER;
MYDBGASSERT(pArgs && pArgs->rlsRasLink.pfnGetCredentials);
MYDBGASSERT(ppvData);
MYDBGASSERT((RASCM_UserName == dwMask) || (RASCM_Domain == dwMask) || (RASCM_Password == dwMask));
if (pArgs && ppvData && pArgs->rlsRasLink.pfnGetCredentials)
{
LPTSTR pszConnectoid = GetRasConnectoidName(pArgs, pArgs->piniService, FALSE);
if (pszConnectoid)
{
RASCREDENTIALS RasCredentials = {0};
RasCredentials.dwSize = sizeof(RasCredentials);
if (CM_CREDS_GLOBAL == pArgs->dwCurrentCredentialType)
{
RasCredentials.dwMask = dwMask | RASCM_DefaultCreds;
}
else
{
RasCredentials.dwMask = dwMask;
}
dwRet = pArgs->rlsRasLink.pfnGetCredentials(pszPhoneBook, pszConnectoid, &RasCredentials);
if (ERROR_SUCCESS == dwRet)
{
LPTSTR pszData = NULL;
if (RASCM_UserName == dwMask)
{
pszData = RasCredentials.szUserName;
}
else if (RASCM_Domain == dwMask)
{
pszData = RasCredentials.szDomain;
}
else if (RASCM_Password == dwMask)
{
pszData = RasCredentials.szPassword;
}
LPTSTR pszReturn = CmStrCpyAlloc(pszData);
if (NULL == pszReturn)
{
dwRet = ERROR_NOT_ENOUGH_MEMORY;
}
else
{
*ppvData = pszReturn;
}
}
CmWipePassword(RasCredentials.szPassword);
CmFree(pszConnectoid);
}
}
return dwRet;
}
//+---------------------------------------------------------------------------
//
// Function: ReadUserInfoFromRas
//
// Synopsis: Read userinfo data from the RAS credentials cache
//
// Arguments: pArgs ptr to ArgsStruct
// uiEntry the cmp file entry
// ppvData ptr to ptr to the data buffer. If the userinfo
// is multiple byte(e.g. password), the func allocs
// the buffer.
//
// Returns: BOOL TRUE = success, FALSE = failure
//
//----------------------------------------------------------------------------
BOOL ReadUserInfoFromRas(
ArgsStruct *pArgs,
UINT uiEntry,
PVOID *ppvData
)
{
BOOL bReturn = FALSE;
if (OS_NT5 && pArgs && pArgs->bUseRasCredStore)
{
DWORD dwMask;
LPTSTR pszPhoneBook = NULL;
switch (uiEntry)
{
case UD_ID_USERNAME:
dwMask = RASCM_UserName;
bReturn = (ERROR_SUCCESS == RasGetCredsWrapper(pArgs, pArgs->pszRasPbk, dwMask, ppvData));
break;
case UD_ID_PASSWORD:
dwMask = RASCM_Password;
bReturn = (ERROR_SUCCESS == RasGetCredsWrapper(pArgs, pArgs->pszRasPbk, dwMask, ppvData));
break;
case UD_ID_DOMAIN:
dwMask = RASCM_Domain;
bReturn = (ERROR_SUCCESS == RasGetCredsWrapper(pArgs, pArgs->pszRasPbk, dwMask, ppvData));
break;
case UD_ID_INET_PASSWORD:
dwMask = RASCM_Password;
pszPhoneBook = CreateRasPrivatePbk(pArgs);
if (pszPhoneBook)
{
bReturn = (ERROR_SUCCESS == RasGetCredsWrapper(pArgs, pszPhoneBook, dwMask, ppvData));
CmFree(pszPhoneBook);
}
break;
case UD_ID_INET_USERNAME:
dwMask = RASCM_UserName;
pszPhoneBook = CreateRasPrivatePbk(pArgs);
if (pszPhoneBook)
{
bReturn = (ERROR_SUCCESS == RasGetCredsWrapper(pArgs, pszPhoneBook, dwMask, ppvData));
CmFree(pszPhoneBook);
}
break;
}
}
if (bReturn)
{
if (CM_CREDS_GLOBAL == pArgs->dwCurrentCredentialType)
{
CMTRACE1(TEXT("ReadUserInfoFromRas() - %s retrieved from the Global RAS Credential store"), TranslateUserDataID(uiEntry));
}
else
{
CMTRACE1(TEXT("ReadUserInfoFromRas() - %s retrieved from the User RAS Credential store"), TranslateUserDataID(uiEntry));
}
}
return bReturn;
}
//+---------------------------------------------------------------------------
//
// Function: GetUserInfo
//
// Synopsis: Get an userinfo. The user info can reside in either the
// cache, cmp, or registry. This functions hides this from the
// user.
//
// We first try the cmp file. If that fails, we try the cache.
// We'll get the following user info:
// username,
// password,
// domain,
// remember main passwd,
// dial automatically,
// inet username,
// inet passwd
// remember inet password
// inet use same user name
//
// Arguments: pArgs ptr to ArgsStruct
// uiEntry the cmp file entry
// pvData ptr to ptr to the data buffer. If the userinfo
// is multiple byte(e.g. password), the func allocs
// the buffer.
//
// Returns: BOOL TRUE = success, FALSE = failure
//
//----------------------------------------------------------------------------
BOOL GetUserInfo(
ArgsStruct *pArgs,
UINT uiEntry,
PVOID *ppvData
)
{
BOOL bReturn = ReadUserInfoFromRas(pArgs, uiEntry, ppvData);
if (!bReturn)
{
bReturn = ReadUserInfoFromReg(pArgs, uiEntry, ppvData);
}
if (!bReturn)
{
bReturn = ReadUserInfoFromCmp(pArgs, uiEntry, ppvData);
}
return bReturn;
}
//+---------------------------------------------------------------------------
//
// Function: SaveUserInfo
//
// Synopsis: Save an userinfo. The user info can reside in either the
// RAS cred cache or the registry. This functions abstracts
// this from the user.
//
// We first try the RAS cred cache. If the RAS cred cache doesn't hold that
// piece of info we then save it in the registry.
// We'll save the following user info:
// username,
// password,
// domain,
// remember main passwd,
// dial automatically,
// inet username,
// inet passwd
// remember inet password
// inet use same user name
//
// Arguments: pArgs ptr to ArgsStruct
// uiEntry the cmp file entry
// pvData ptr to the data buffer. If the userinfo is
// multiple byte(e.g. password), the func allocs
// the buffer.
//
// Returns: BOOL TRUE = success, FALSE = failure
//
//----------------------------------------------------------------------------
BOOL SaveUserInfo(
ArgsStruct *pArgs,
UINT uiEntry,
PVOID pvData
)
{
//
// Try giving the Data to RAS first. If the function returns
// -1, then this is data that RAS doesn't hold for us and we will
// have to put it in the registry instead.
//
int iReturn = WriteUserInfoToRas(pArgs, uiEntry, pvData);
if (-1 == iReturn)
{
//
// Just write the data to the registry. Use CMP only as
// an upgrade reference for UserInfo data post CM 1.1
//
iReturn = WriteUserInfoToReg(pArgs, uiEntry, pvData);
}
return iReturn;
}
//+---------------------------------------------------------------------------
//
// Function: DeleteUserInfo
//
// Synopsis: Delete an userinfo. The user info can reside in either the
// RAS Cred cache or the registry. This functions abstracts
// this from the user.
//
// We first try the RAS cache first. If that piece of info isn't stored
// in the RAS cache then we try the registry.
//
// We'll delete the following user info:
// username,
// password,
// domain,
// remember main passwd,
// dial automatically,
// inet username,
// inet passwd
// remember inet password
// inet use same user name
//
// Arguments: pArgs ptr to ArgsStruct
// uiEntry the cmp file entry
//
// Returns: BOOL TRUE = success, FALSE = failure
//
//----------------------------------------------------------------------------
BOOL DeleteUserInfo(
ArgsStruct *pArgs,
UINT uiEntry
)
{
int iReturn = DeleteUserInfoFromRas(pArgs, uiEntry);
if (-1 == iReturn)
{
iReturn = DeleteUserInfoFromReg(pArgs, uiEntry);
}
return iReturn;
}
//+---------------------------------------------------------------------------
//
// Function: NeedToUpgradeUserInfo
//
// Synopsis: Do we need to upgrade the cm 1.0/1.1 userinfo to the cm 1.2 format?
//
// Arguments: pArgs - Ptr to global args struct
//
// Returns: BOOL TRUE = success, FALSE = failure
//
//----------------------------------------------------------------------------
int NeedToUpgradeUserInfo(
ArgsStruct *pArgs)
{
MYDBGASSERT(pArgs);
DWORD dwRes;
HKEY hKeyCm;
LPTSTR pszSubKey;
int iReturn = c_iNoUpgradeRequired;
if (pArgs)
{
//
// If this is NT5 or greater, we want to be storing our credentials with RAS
// instead of the registry.
//
// If this isn't NT5 we still want to upgrade the user to using the registry as
// storage instead of the cmp if they haven't already
// been upgraded. Thus the simple test is to open the service name key in HKCU.
// This key will exist, if the user has already run 1.2 bits.
//
pszSubKey = BuildUserInfoSubKey(pArgs->szServiceName, pArgs->fAllUser);
dwRes = RegOpenKeyExU(HKEY_CURRENT_USER,
pszSubKey,
0,
KEY_QUERY_VALUE,
&hKeyCm);
if (ERROR_SUCCESS == dwRes)
{
//
// Then we have the registry method, unless we are supposed to be using the RAS
// cred store we are done. If we are supposed to be using the RAS cred store
// we need to check to make sure that we are using it. Note we could have a problem
// here if the user has registry cred data and then their registry gets write protected.
// This would allow us to read from it but not delete the old data. Thus the user
// would never be able to save any changes because we would always think they needed
// to upgrade. An unlikely scenario but possible ...
//
if (pArgs->bUseRasCredStore)
{
LPTSTR pszUserName = NULL;
BOOL bRet = ReadUserInfoFromReg(pArgs, UD_ID_USERNAME, (PVOID*)&pszUserName);
if (bRet && (NULL != pszUserName) && (TEXT('\0') != pszUserName[0]))
{
//
// Then we have the username in the registry. Lets upgrade to the RAS
// credential store.
//
iReturn = c_iUpgradeFromRegToRas;
}
CmFree(pszUserName);
}
RegCloseKey(hKeyCm);
}
else
{
iReturn = c_iUpgradeFromCmp;
}
CmFree(pszSubKey);
}
else
{
CMASSERTMSG(FALSE, TEXT("NeedToUpgradeUserInfo -- NULL pArgs passed"));
}
//
// We don't want to upgrade if it's ICS. This prevents from adding info to the registry.
//
if (CM_LOGON_TYPE_ICS == pArgs->dwWinLogonType)
{
iReturn = c_iNoUpgradeRequired;
}
return iReturn;
}
//+---------------------------------------------------------------------------
//
// Function: UpgradeUserInfoFromRegToRasAndReg
//
// Synopsis: Upgrade the userinfo from CM 1.2 registry only format to the
// CM 1.3 format which uses both RAS credential storage and
// the registry.
//
// Arguments: pArgs ptr to ArgsStruct
//
// Returns: BOOL TRUE = success, FALSE = failure
//
//----------------------------------------------------------------------------
BOOL UpgradeUserInfoFromRegToRasAndReg(
ArgsStruct *pArgs
)
{
BOOL bReturn = FALSE;
if (OS_NT5)
{
LPTSTR pszTmp;
pszTmp = NULL;
//
// If we get an empty string "" from ReadUserInfoFromReg we don't want to
// save the empty string to the RAS Credstore because it might overwrite
// global credentials information. This can happen if User1 saves global
// credentials and User2 tries using the same profile. Since User2 is running
// this profile for the 1st time, he'll run through an upgrade path and if global
// creds exist we don't want to null them out.
//
if (ReadUserInfoFromReg(pArgs, UD_ID_INET_USERNAME, (PVOID*)&pszTmp))
{
DeleteUserInfoFromReg(pArgs, UD_ID_INET_USERNAME);
if (pszTmp && lstrlenU(pszTmp))
{
WriteUserInfoToRas(pArgs, UD_ID_INET_USERNAME, pszTmp);
}
CmFree(pszTmp);
}
pszTmp = NULL;
if (ReadUserInfoFromReg(pArgs, UD_ID_INET_PASSWORD, (PVOID*)&pszTmp))
{
DeleteUserInfoFromReg(pArgs, UD_ID_INET_PASSWORD);
if (pszTmp && lstrlenU(pszTmp))
{
WriteUserInfoToRas(pArgs, UD_ID_INET_PASSWORD, pszTmp);
}
CmFree(pszTmp);
}
pszTmp = NULL;
if (ReadUserInfoFromReg(pArgs, UD_ID_USERNAME, (PVOID*)&pszTmp))
{
DeleteUserInfoFromReg(pArgs, UD_ID_USERNAME);
if (pszTmp && lstrlenU(pszTmp))
{
WriteUserInfoToRas(pArgs, UD_ID_USERNAME, pszTmp);
}
CmFree(pszTmp);
}
pszTmp = NULL;
if (ReadUserInfoFromReg(pArgs, UD_ID_DOMAIN, (PVOID*)&pszTmp))
{
DeleteUserInfoFromReg(pArgs, UD_ID_DOMAIN);
if (pszTmp && lstrlenU(pszTmp))
{
WriteUserInfoToRas(pArgs, UD_ID_DOMAIN, pszTmp);
}
CmFree(pszTmp);
}
pszTmp = NULL;
if (ReadUserInfoFromReg(pArgs, UD_ID_PASSWORD, (PVOID*)&pszTmp))
{
DeleteUserInfoFromReg(pArgs, UD_ID_PASSWORD);
if (pszTmp && lstrlenU(pszTmp))
{
WriteUserInfoToRas(pArgs, UD_ID_PASSWORD, pszTmp);
}
CmFree(pszTmp);
}
//
// Now delete the PCS value as it is no longer meaningful
//
DeleteUserInfoFromReg(pArgs, UD_ID_PCS);
}
else
{
MYDBGASSERT(FALSE);
}
return bReturn;
}
//+---------------------------------------------------------------------------
//
// Function: UpgradeUserInfoFromCmp
//
// Synopsis: Upgrade the userinfo from cm1.0/1,1 format to 1.3 format.
//
// Arguments: pArgs ptr to ArgsStruct
//
// Returns: BOOL TRUE = success, FALSE = failure
//
//----------------------------------------------------------------------------
BOOL UpgradeUserInfoFromCmp(
ArgsStruct *pArgs
)
{
LPTSTR pszTmp;
BOOL fTmp;
PVOID pv;
//
// First retrieve each of the non-cached data items
// Then delete username, internetusername, domain, password,
// internetpassword, remember password, remember internet password
// and noprompt (dial automatically) from the CMP file.
// If the KeepDefaultCredentials is set to 1 in the .CMP file then the
// DeleteUserInfoFromCmp function does not actually delete the values from
// the file.
// If we get an empty string "" from ReadUserInfoFromCmp we don't want to
// save the empty string to the RAS Credstore because it might overwrite
// global credentials information. This can happen if User1 saves global
// credentials and User2 tries using the same profile. Since User2 is running
// this profile for the 1st time, he'll run through an upgrade path and if global
// creds exist we don't want to null them out.
//
pszTmp = NULL;
ReadUserInfoFromCmp(pArgs, UD_ID_USERNAME, (PVOID*)&pszTmp);
if (pszTmp && lstrlenU(pszTmp))
{
SaveUserInfo(pArgs, UD_ID_USERNAME, pszTmp);
}
DeleteUserInfoFromCmp(pArgs, UD_ID_USERNAME);
CmFree(pszTmp);
pszTmp = NULL;
ReadUserInfoFromCmp(pArgs, UD_ID_DOMAIN, (PVOID*)&pszTmp);
if (pszTmp && lstrlenU(pszTmp))
{
SaveUserInfo(pArgs, UD_ID_DOMAIN, pszTmp);
}
DeleteUserInfoFromCmp(pArgs, UD_ID_DOMAIN);
CmFree(pszTmp);
pszTmp = NULL;
ReadUserInfoFromCmp(pArgs, UD_ID_INET_USERNAME, (PVOID*)&pszTmp);
if (pszTmp && lstrlenU(pszTmp))
{
SaveUserInfo(pArgs, UD_ID_INET_USERNAME, pszTmp);
}
DeleteUserInfoFromCmp(pArgs, UD_ID_INET_USERNAME);
CmFree(pszTmp);
pv = &fTmp;
ReadUserInfoFromCmp(pArgs, UD_ID_NOPROMPT, &pv);
SaveUserInfo(pArgs, UD_ID_NOPROMPT, pv);
DeleteUserInfoFromCmp(pArgs, UD_ID_NOPROMPT);
pv = &fTmp;
ReadUserInfoFromCmp(pArgs, UD_ID_REMEMBER_PWD, &pv);
SaveUserInfo(pArgs, UD_ID_REMEMBER_PWD, pv);
DeleteUserInfoFromCmp(pArgs, UD_ID_REMEMBER_PWD);
pv = &fTmp;
ReadUserInfoFromCmp(pArgs, UD_ID_REMEMBER_INET_PASSWORD, &pv);
SaveUserInfo(pArgs, UD_ID_REMEMBER_INET_PASSWORD, pv);
DeleteUserInfoFromCmp(pArgs, UD_ID_REMEMBER_INET_PASSWORD);
//
// Construct old cache entry name
//
LPTSTR pszCacheEntryName = GetLegacyKeyName(pArgs);
//
// main passwd
//
pszTmp = NULL;
//
// To get the passwords, the cm 1.1 logic is that we first try the cmp, then the cache.
//
if (ReadUserInfoFromCmp(pArgs, UD_ID_PASSWORD, (PVOID*)&pszTmp))
{
if (pszTmp && lstrlenU(pszTmp))
{
SaveUserInfo(pArgs, UD_ID_PASSWORD, pszTmp);
}
}
else
{
CmFree(pszTmp);
pszTmp = NULL;
#ifdef TEST_USERINFO_UPGRADE
MYVERIFY(WriteStringToCache(pArgs, pszCacheEntryName, TEXT("CM 1.1 main password")));
#endif
//
// Try to read it from cache
//
if (ReadStringFromCache(pArgs, pszCacheEntryName, &pszTmp))
{
if (pszTmp && lstrlenU(pszTmp))
{
if (SaveUserInfo(pArgs, UD_ID_PASSWORD, pszTmp))
{
#ifdef TEST_USERINFO_UPGRADE
MYVERIFY(DeleteStringFromCache(pArgs, pszCacheEntryName));
#endif
}
}
}
}
DeleteUserInfoFromCmp(pArgs, UD_ID_PASSWORD);
CmFree(pszTmp);
//
// inet passwd
//
pszTmp = NULL;
if (ReadUserInfoFromCmp(pArgs, UD_ID_INET_PASSWORD, (PVOID*)&pszTmp))
{
if (pszTmp && lstrlenU(pszTmp))
{
SaveUserInfo(pArgs, UD_ID_INET_PASSWORD, pszTmp);
}
}
else
{
CmFree(pszTmp);
pszTmp = NULL;
//
// Build tunnel entry name and read string from cache
//
pszCacheEntryName = CmStrCatAlloc(&pszCacheEntryName, TEXT("-tunnel"));
#ifdef TEST_USERINFO_UPGRADE
MYVERIFY(WriteStringToCache(pArgs, pszCacheEntryName, TEXT("CM 1.1 internet password")));
#endif
if (ReadStringFromCache(pArgs, pszCacheEntryName, &pszTmp))
{
if (pszTmp && lstrlenU(pszTmp))
{
if (SaveUserInfo(pArgs, UD_ID_INET_PASSWORD, pszTmp))
{
#ifdef TEST_USERINFO_UPGRADE
MYVERIFY(DeleteStringFromCache(pArgs, pszCacheEntryName));
#endif
}
}
}
}
DeleteUserInfoFromCmp(pArgs, UD_ID_INET_PASSWORD);
CmFree(pszTmp);
CmFree(pszCacheEntryName);
return TRUE; // MarkUserInfoUpgraded(pArgs);
}
//+----------------------------------------------------------------------------
//
// Function: GetLegacyKeyName
//
// Synopsis: Builds the string fragment used to build cache entry name. The "
// sign-in" prefix is maintained for legacy compatibility
//
// Arguments: ArgsStruct *pArgs - Ptr to global args struct
//
// Returns: LPTSTR - Ptr to allocated string containing "<service name> - Sign-In"
//
// Note: Used exclusively for cache entry name construction
//
// History: nickball Created Header 4/16/98
//
//+----------------------------------------------------------------------------
LPTSTR GetLegacyKeyName(ArgsStruct *pArgs)
{
MYDBGASSERT(pArgs);
//
// Service name is the basis of the key name. We also include
// IDMSG_TITLESERVICE and append a suffix of " (Connection Manager)"
//
LPTSTR pszRes = CmFmtMsg(g_hInst, IDMSG_TITLESERVICE, pArgs->szServiceName);
MYDBGASSERT(pszRes && *pszRes);
if (pszRes)
{
pszRes = CmStrCatAlloc(&pszRes, c_pszCacheEntryNameSuffix);
}
return (pszRes);
}
//+----------------------------------------------------------------------------
//
// Function: EncryptPassword
//
// Synopsis: Wrapper for encrypting password
//
// Arguments: ArgsStruct *pArgs - Ptr to global args struct
// LPCTSTR pszPassword - The password to be encrypted
// LPDWORD lpdwBufSize - Buffer for size of the encrypted buffer - optional
// LPDWORD lpdwCryptType - Buffer for crypto type used
// BOOL fReg - Password is disguised for registry storage
//
// Returns: LPTSTR - Ptr to allocated buffer containing encrypted form of password
//
// History: nickball Created Header 5/22/98
//
//+----------------------------------------------------------------------------
LPTSTR EncryptPassword(
ArgsStruct *pArgs,
LPCTSTR pszPassword,
LPDWORD lpdwBufSize,
LPDWORD lpdwCryptType,
BOOL /*fReg*/,
LPSTR pszSubKey)
{
MYDBGASSERT(pArgs);
MYDBGASSERT(pszPassword);
MYDBGASSERT(lpdwCryptType);
DWORD dwEncryptedBufferLen;
DWORD dwSize = 0;
LPTSTR pszEncryptedData = NULL;
TCHAR szSourceData[PWLEN + 1];
if (NULL == pArgs || NULL == pszPassword || NULL == lpdwCryptType)
{
return NULL;
}
//
// Standard encryption, copy the password
//
lstrcpyU(szSourceData, pszPassword);
//
// It is not safe to call InitSecure more than once
//
if (!pArgs->fInitSecureCalled)
{
pArgs->fInitSecureCalled = TRUE;
InitSecure(FALSE); // don't use fast encryption anymore
}
//
// Encrypt the provided password
//
if (EncryptData(
(LPBYTE)szSourceData,
(lstrlenU(szSourceData)+1) * sizeof(TCHAR),
(LPBYTE*)&pszEncryptedData,
&dwEncryptedBufferLen,
lpdwCryptType,
#if defined(DEBUG) && defined(DEBUG_MEM)
(PFN_CMSECUREALLOC)AllocDebugMem, // Give the DEBUG_MEM version of alloc/free
(PFN_CMSECUREFREE)FreeDebugMem)) // Not quit right, AllocDebugMem takes 3 param
#else
(PFN_CMSECUREALLOC)CmMalloc,
(PFN_CMSECUREFREE)CmFree,
pszSubKey))
#endif
{
if (lpdwBufSize)
{
*lpdwBufSize = dwEncryptedBufferLen;
}
}
MYDBGASSERT(pszEncryptedData);
CmWipePassword(szSourceData);
return pszEncryptedData;
}
//+----------------------------------------------------------------------------
//
// Function: DecryptPassword
//
// Synopsis: Wrapper to decrypt password
//
// Arguments: ArgsStruct *pArgs - Ptr to global args struct
// LPCTSTR pszEncryptedData - The encrypted data
// DWORD dwEncryptionType - The encryption type of the data
// BOOL fReg - Password is disguised for registry storage
//
// Returns: LPTSTR - Ptr to a buffer containing the decrypted form of the password.
//
// History: nickball Created 5/22/98
//
//+----------------------------------------------------------------------------
LPBYTE DecryptPassword(
ArgsStruct *pArgs,
LPBYTE pszEncryptedData,
DWORD dwEncryptionType,
DWORD dwEncryptedBytes,
BOOL /*fReg*/,
LPSTR pszSubKey)
{
MYDBGASSERT(pArgs);
MYDBGASSERT(pszEncryptedData);
DWORD dwDecryptedBufferLen;
LPBYTE pszDecryptedData = NULL;
if (NULL == pArgs || NULL == pszEncryptedData)
{
return NULL;
}
//
// It is not safe to call InitSecure more than once
//
if (!pArgs->fInitSecureCalled)
{
pArgs->fInitSecureCalled = TRUE;
InitSecure(FALSE); // don't use fast encryption anymore
}
if (DecryptData(pszEncryptedData, dwEncryptedBytes, &pszDecryptedData, &dwDecryptedBufferLen,
dwEncryptionType,
#if defined(DEBUG) && defined(DEBUG_MEM)
(PFN_CMSECUREALLOC)AllocDebugMem, // Give the DEBUG_MEM version of alloc/free
(PFN_CMSECUREFREE)FreeDebugMem)) // Not quit right, AllocDebugMem takes 3 param
#else
(PFN_CMSECUREALLOC)CmMalloc,
(PFN_CMSECUREFREE)CmFree,
pszSubKey))
#endif
{
return pszDecryptedData;
}
return NULL;
}
//+----------------------------------------------------------------------------
//
// Function: TranslateUserDataID
//
// Synopsis: Wrapper to map user data ID to string name of .CMP entry
//
// Arguments: UINT uiDataID - UserInfo data ID to be translated
//
// Returns: LPCTSTR - Ptr to a constant containing the .CMP entry flag
//
// History: nickball Created 10/13/98
//
//+----------------------------------------------------------------------------
LPCTSTR TranslateUserDataID(UINT uiDataID)
{
switch(uiDataID)
{
case UD_ID_USERNAME:
return c_pszCmEntryUserName;
break;
case UD_ID_INET_USERNAME:
return c_pszCmEntryInetUserName;
break;
case UD_ID_DOMAIN:
return c_pszCmEntryDomain;
break;
case UD_ID_PASSWORD:
return c_pszCmEntryPassword;
break;
case UD_ID_INET_PASSWORD:
return c_pszCmEntryInetPassword;
break;
case UD_ID_NOPROMPT:
return c_pszCmEntryNoPrompt;
break;
case UD_ID_REMEMBER_PWD:
return c_pszCmEntryRememberPwd;
break;
case UD_ID_REMEMBER_INET_PASSWORD:
return c_pszCmEntryRememberInetPwd;
break;
case UD_ID_PCS:
return c_pszCmEntryPcs;
break;
case UD_ID_ACCESSPOINTENABLED:
return c_pszCmEntryAccessPointsEnabled;
break;
case UD_ID_CURRENTACCESSPOINT:
return c_pszCmEntryCurrentAccessPoint;
break;
default:
break;
}
MYDBGASSERT(FALSE);
return NULL;
}