pwmanager.cpp
来自「一款密码保险箱源码」· C++ 代码 · 共 2,201 行 · 第 1/5 页
CPP
2,201 行
pos = sizeof(PW_DBHEADER);
BYTE *pb;
// Store all groups to memory file
for(i = 0; i < m_dwNumGroups; i++)
{
usFieldType = 0x0001; dwFieldSize = 4;
memcpy(&pVirtualFile[pos], &usFieldType, 2); pos += 2;
memcpy(&pVirtualFile[pos], &dwFieldSize, 4); pos += 4;
memcpy(&pVirtualFile[pos], &m_pGroups[i].uGroupId, 4); pos += 4;
pb = _StringToUTF8(m_pGroups[i].pszGroupName);
usFieldType = 0x0002; dwFieldSize = szlen((char *)pb) + 1;
memcpy(&pVirtualFile[pos], &usFieldType, 2); pos += 2;
memcpy(&pVirtualFile[pos], &dwFieldSize, 4); pos += 4;
ASSERT((pb != NULL) && (szlen((char *)pb) == (dwFieldSize - 1)) && ((pos + dwFieldSize) <= uAllocated));
szcpy(&pVirtualFile[pos], (char *)pb); pos += dwFieldSize;
SAFE_DELETE_ARRAY(pb);
usFieldType = 0x0003; dwFieldSize = 5;
memcpy(&pVirtualFile[pos], &usFieldType, 2); pos += 2;
memcpy(&pVirtualFile[pos], &dwFieldSize, 4); pos += 4;
PwTimeToTime(&m_pGroups[i].tCreation, aCompressedTime);
memcpy(&pVirtualFile[pos], aCompressedTime, 5); pos += 5;
usFieldType = 0x0004; dwFieldSize = 5;
memcpy(&pVirtualFile[pos], &usFieldType, 2); pos += 2;
memcpy(&pVirtualFile[pos], &dwFieldSize, 4); pos += 4;
PwTimeToTime(&m_pGroups[i].tLastMod, aCompressedTime);
memcpy(&pVirtualFile[pos], aCompressedTime, 5); pos += 5;
usFieldType = 0x0005; dwFieldSize = 5;
memcpy(&pVirtualFile[pos], &usFieldType, 2); pos += 2;
memcpy(&pVirtualFile[pos], &dwFieldSize, 4); pos += 4;
PwTimeToTime(&m_pGroups[i].tLastAccess, aCompressedTime);
memcpy(&pVirtualFile[pos], aCompressedTime, 5); pos += 5;
usFieldType = 0x0006; dwFieldSize = 5;
memcpy(&pVirtualFile[pos], &usFieldType, 2); pos += 2;
memcpy(&pVirtualFile[pos], &dwFieldSize, 4); pos += 4;
PwTimeToTime(&m_pGroups[i].tExpire, aCompressedTime);
memcpy(&pVirtualFile[pos], aCompressedTime, 5); pos += 5;
usFieldType = 0x0007; dwFieldSize = 4;
memcpy(&pVirtualFile[pos], &usFieldType, 2); pos += 2;
memcpy(&pVirtualFile[pos], &dwFieldSize, 4); pos += 4;
memcpy(&pVirtualFile[pos], &m_pGroups[i].uImageId, 4); pos += 4;
usFieldType = 0x0008; dwFieldSize = 2;
memcpy(&pVirtualFile[pos], &usFieldType, 2); pos += 2;
memcpy(&pVirtualFile[pos], &dwFieldSize, 4); pos += 4;
memcpy(&pVirtualFile[pos], &m_pGroups[i].usLevel, 2); pos += 2;
usFieldType = 0x0009; dwFieldSize = 4;
memcpy(&pVirtualFile[pos], &usFieldType, 2); pos += 2;
memcpy(&pVirtualFile[pos], &dwFieldSize, 4); pos += 4;
memcpy(&pVirtualFile[pos], &m_pGroups[i].dwFlags, 4); pos += 4;
usFieldType = 0xFFFF; dwFieldSize = 0;
memcpy(&pVirtualFile[pos], &usFieldType, 2); pos += 2;
memcpy(&pVirtualFile[pos], &dwFieldSize, 4); pos += 4;
}
// Store all entries to memory file
for(i = 0; i < m_dwNumEntries; i++)
{
UnlockEntryPassword(&m_pEntries[i]);
usFieldType = 0x0001; dwFieldSize = 16;
memcpy(&pVirtualFile[pos], &usFieldType, 2); pos += 2;
memcpy(&pVirtualFile[pos], &dwFieldSize, 4); pos += 4;
memcpy(&pVirtualFile[pos], &m_pEntries[i].uuid, 16); pos += 16;
usFieldType = 0x0002; dwFieldSize = 4;
memcpy(&pVirtualFile[pos], &usFieldType, 2); pos += 2;
memcpy(&pVirtualFile[pos], &dwFieldSize, 4); pos += 4;
memcpy(&pVirtualFile[pos], &m_pEntries[i].uGroupId, 4); pos += 4;
usFieldType = 0x0003; dwFieldSize = 4;
memcpy(&pVirtualFile[pos], &usFieldType, 2); pos += 2;
memcpy(&pVirtualFile[pos], &dwFieldSize, 4); pos += 4;
memcpy(&pVirtualFile[pos], &m_pEntries[i].uImageId, 4); pos += 4;
pb = _StringToUTF8(m_pEntries[i].pszTitle);
usFieldType = 0x0004;
dwFieldSize = szlen((char *)pb) + 1; // Add terminating NULL character space
memcpy(&pVirtualFile[pos], &usFieldType, 2); pos += 2;
memcpy(&pVirtualFile[pos], &dwFieldSize, 4); pos += 4;
ASSERT((pb != NULL) && (szlen((char *)pb) == (dwFieldSize - 1)) && ((pos + dwFieldSize) <= uAllocated));
szcpy(&pVirtualFile[pos], (char *)pb); pos += dwFieldSize;
SAFE_DELETE_ARRAY(pb);
pb = _StringToUTF8(m_pEntries[i].pszURL);
usFieldType = 0x0005;
dwFieldSize = szlen((char *)pb) + 1; // Add terminating NULL character space
memcpy(&pVirtualFile[pos], &usFieldType, 2); pos += 2;
memcpy(&pVirtualFile[pos], &dwFieldSize, 4); pos += 4;
ASSERT((pb != NULL) && (szlen((char *)pb) == (dwFieldSize - 1)) && ((pos + dwFieldSize) <= uAllocated));
szcpy(&pVirtualFile[pos], (char *)pb); pos += dwFieldSize;
SAFE_DELETE_ARRAY(pb);
pb = _StringToUTF8(m_pEntries[i].pszUserName);
usFieldType = 0x0006;
dwFieldSize = szlen((char *)pb) + 1; // Add terminating NULL character space
memcpy(&pVirtualFile[pos], &usFieldType, 2); pos += 2;
memcpy(&pVirtualFile[pos], &dwFieldSize, 4); pos += 4;
ASSERT((pb != NULL) && (szlen((char *)pb) == (dwFieldSize - 1)) && ((pos + dwFieldSize) <= uAllocated));
szcpy(&pVirtualFile[pos], (char *)pb); pos += dwFieldSize;
SAFE_DELETE_ARRAY(pb);
pb = _StringToUTF8(m_pEntries[i].pszPassword);
usFieldType = 0x0007;
dwFieldSize = szlen((char *)pb) + 1; // Add terminating NULL character space
memcpy(&pVirtualFile[pos], &usFieldType, 2); pos += 2;
memcpy(&pVirtualFile[pos], &dwFieldSize, 4); pos += 4;
ASSERT((pb != NULL) && (szlen((char *)pb) == (dwFieldSize - 1)) && ((pos + dwFieldSize) <= uAllocated));
szcpy(&pVirtualFile[pos], (char *)pb); pos += dwFieldSize;
if(pb != NULL) mem_erase((unsigned char *)pb, szlen((char *)pb));
SAFE_DELETE_ARRAY(pb);
pb = _StringToUTF8(m_pEntries[i].pszAdditional);
usFieldType = 0x0008;
dwFieldSize = szlen((char *)pb) + 1; // Add terminating NULL character space
memcpy(&pVirtualFile[pos], &usFieldType, 2); pos += 2;
memcpy(&pVirtualFile[pos], &dwFieldSize, 4); pos += 4;
ASSERT((pb != NULL) && (szlen((char *)pb) == (dwFieldSize - 1)) && ((pos + dwFieldSize) <= uAllocated));
szcpy(&pVirtualFile[pos], (char *)pb); pos += dwFieldSize;
SAFE_DELETE_ARRAY(pb);
usFieldType = 0x0009; dwFieldSize = 5;
memcpy(&pVirtualFile[pos], &usFieldType, 2); pos += 2;
memcpy(&pVirtualFile[pos], &dwFieldSize, 4); pos += 4;
PwTimeToTime(&m_pEntries[i].tCreation, aCompressedTime);
memcpy(&pVirtualFile[pos], aCompressedTime, 5); pos += 5;
usFieldType = 0x000A; dwFieldSize = 5;
memcpy(&pVirtualFile[pos], &usFieldType, 2); pos += 2;
memcpy(&pVirtualFile[pos], &dwFieldSize, 4); pos += 4;
PwTimeToTime(&m_pEntries[i].tLastMod, aCompressedTime);
memcpy(&pVirtualFile[pos], aCompressedTime, 5); pos += 5;
usFieldType = 0x000B; dwFieldSize = 5;
memcpy(&pVirtualFile[pos], &usFieldType, 2); pos += 2;
memcpy(&pVirtualFile[pos], &dwFieldSize, 4); pos += 4;
PwTimeToTime(&m_pEntries[i].tLastAccess, aCompressedTime);
memcpy(&pVirtualFile[pos], aCompressedTime, 5); pos += 5;
usFieldType = 0x000C; dwFieldSize = 5;
memcpy(&pVirtualFile[pos], &usFieldType, 2); pos += 2;
memcpy(&pVirtualFile[pos], &dwFieldSize, 4); pos += 4;
PwTimeToTime(&m_pEntries[i].tExpire, aCompressedTime);
memcpy(&pVirtualFile[pos], aCompressedTime, 5); pos += 5;
pb = _StringToUTF8(m_pEntries[i].pszBinaryDesc);
usFieldType = 0x000D;
dwFieldSize = szlen((char *)pb) + 1;
memcpy(&pVirtualFile[pos], &usFieldType, 2); pos += 2;
memcpy(&pVirtualFile[pos], &dwFieldSize, 4); pos += 4;
ASSERT((pb != NULL) && (szlen((char *)pb) == (dwFieldSize - 1)) && ((pos + dwFieldSize) <= uAllocated));
szcpy(&pVirtualFile[pos], (char *)pb); pos += dwFieldSize;
SAFE_DELETE_ARRAY(pb);
usFieldType = 0x000E; dwFieldSize = m_pEntries[i].uBinaryDataLen;
memcpy(&pVirtualFile[pos], &usFieldType, 2); pos += 2;
memcpy(&pVirtualFile[pos], &dwFieldSize, 4); pos += 4;
if((m_pEntries[i].pBinaryData != NULL) && (dwFieldSize != 0))
memcpy(&pVirtualFile[pos], m_pEntries[i].pBinaryData, dwFieldSize);
pos += dwFieldSize;
usFieldType = 0xFFFF; dwFieldSize = 0;
memcpy(&pVirtualFile[pos], &usFieldType, 2); pos += 2;
memcpy(&pVirtualFile[pos], &dwFieldSize, 4); pos += 4;
LockEntryPassword(&m_pEntries[i]);
}
ASSERT((pos <= uFileSize) && ((pos + 33) > uAllocated));
sha256_begin(&sha32);
sha256_hash((unsigned char *)pVirtualFile + sizeof(PW_DBHEADER), pos - sizeof(PW_DBHEADER), &sha32);
sha256_end((unsigned char *)hdr.aContentsHash, &sha32);
// Now we have everything required to build up the header
memcpy(pVirtualFile, &hdr, sizeof(PW_DBHEADER));
// Generate m_pTransformedMasterKey from m_pMasterKey
if(_TransformMasterKey(hdr.aMasterSeed2) == FALSE)
{ ASSERT(FALSE); SAFE_DELETE_ARRAY(pVirtualFile); _LoadAndRemoveAllMetaStreams(false); return PWE_CRYPT_ERROR; }
// Hash the master password with the generated hash salt
sha256_begin(&sha32);
sha256_hash(hdr.aMasterSeed, 16, &sha32);
sha256_hash(m_pTransformedMasterKey, 32, &sha32);
sha256_end((unsigned char *)uFinalKey, &sha32);
#if 0
// For debugging purposes, a file containing the plain text is created.
// This code of course must not be compiled into the final binary.
#pragma message("PLAIN TEXT OUTPUT IS ENABLED!")
#pragma message("DO NOT DISTRIBUTE THIS BINARY!")
// std::basic_string<TCHAR> tstrClear = pszFile;
// tstrClear += _T(".plaintext.bin");
// FILE *fpClear = NULL;
// _tfopen_s(&fpClear, tstrClear.c_str(), _T("wb"));
// fwrite(pVirtualFile, 1, uFileSize, fpClear);
// fclose(fpClear); fpClear = NULL;
#endif
if(m_nAlgorithm == ALGO_AES)
{
CRijndael aes;
// Initialize Rijndael/AES
if(aes.Init(CRijndael::CBC, CRijndael::EncryptDir, uFinalKey,
CRijndael::Key32Bytes, hdr.aEncryptionIV) != RIJNDAEL_SUCCESS)
{
SAFE_DELETE_ARRAY(pVirtualFile);
return PWE_CRYPT_ERROR;
}
uEncryptedPartSize = (unsigned long)aes.PadEncrypt((UINT8 *)pVirtualFile +
sizeof(PW_DBHEADER), pos - sizeof(PW_DBHEADER), (UINT8 *)pVirtualFile +
sizeof(PW_DBHEADER));
}
else if(m_nAlgorithm == ALGO_TWOFISH)
{
CTwofish twofish;
if(twofish.Init(uFinalKey, 32, hdr.aEncryptionIV) == false)
{
SAFE_DELETE_ARRAY(pVirtualFile);
_LoadAndRemoveAllMetaStreams(false);
return PWE_CRYPT_ERROR;
}
uEncryptedPartSize = (unsigned long)twofish.PadEncrypt(
(UINT8 *)pVirtualFile + sizeof(PW_DBHEADER),
pos - sizeof(PW_DBHEADER), (UINT8 *)pVirtualFile + sizeof(PW_DBHEADER));
}
else
{
ASSERT(FALSE);
_OPENDB_FAIL_LIGHT;
_LoadAndRemoveAllMetaStreams(false);
return PWE_INVALID_PARAM;
}
// Check if all went correct
ASSERT((uEncryptedPartSize % 16) == 0);
if((uEncryptedPartSize > 2147483446) || ((uEncryptedPartSize == 0) &&
(GetNumberOfGroups() != 0)))
{
ASSERT(FALSE);
SAFE_DELETE_ARRAY(pVirtualFile);
_LoadAndRemoveAllMetaStreams(false);
return PWE_CRYPT_ERROR;
}
fp = NULL;
_tfopen_s(&fp, pszFile, _T("wb"));
if(fp == NULL)
{
mem_erase((unsigned char *)pVirtualFile, uAllocated);
SAFE_DELETE_ARRAY(pVirtualFile);
_LoadAndRemoveAllMetaStreams(false);
return PWE_NOFILEACCESS_WRITE;
}
// Write memory file to disk
if(fwrite(pVirtualFile, 1, uEncryptedPartSize + sizeof(PW_DBHEADER), fp) !=
uEncryptedPartSize + sizeof(PW_DBHEADER))
{
mem_erase((unsigned char *)pVirtualFile, uAllocated);
SAFE_DELETE_ARRAY(pVirtualFile);
_LoadAndRemoveAllMetaStreams(false);
return PWE_FILEERROR_WRITE;
}
// Close file, erase and delete memory
fclose(fp); fp = NULL;
memcpy(&m_dbLastHeader, &hdr, sizeof(PW_DBHEADER));
mem_erase((unsigned char *)pVirtualFile, uAllocated);
SAFE_DELETE_ARRAY(pVirtualFile);
_LoadAndRemoveAllMetaStreams(false);
return PWE_SUCCESS;
}
DWORD CPwManager::Find(const TCHAR *pszFindString, BOOL bCaseSensitive, DWORD fieldFlags, DWORD nStart)
{
DWORD i;
CString strFind;
CString strEntry;
if(nStart >= (int)m_dwNumEntries) return DWORD_MAX;
ASSERT(pszFindString != NULL); if(pszFindString == NULL) return DWORD_MAX;
strFind = pszFindString;
if(bCaseSensitive == FALSE) strFind.MakeLower();
if((strFind.GetLength() == 0) || (strFind == _T("*"))) return nStart;
for(i = nStart; i < (int)m_dwNumEntries; i++)
{
if(fieldFlags & PWMF_TITLE)
{
strEntry = m_pEntries[i].pszTitle;
if(bCaseSensitive == FALSE) strEntry.MakeLower();
if(strEntry.Find(strFind) != -1) return i;
}
if(fieldFlags & PWMF_USER)
{
strEntry = m_pEntries[i].pszUserName;
if(bCaseSensitive == FALSE) strEntry.MakeLower();
if(strEntry.Find(strFind) != -1) return i;
}
if(fieldFlags & PWMF_URL)
{
strEntry = m_pEntries[i].pszURL;
if(bCaseSensitive == FALSE) strEntry.MakeLower();
if(strEntry.Find(strFind) != -1) return i;
}
if(fieldFlags & PWMF_PASSWORD)
{
UnlockEntryPassword(&m_pEntries[i]);
strEntry = m_pEntries[i].pszPassword;
LockEntryPassword(&m_pEntries[i]);
if(bCaseSensitive == FALSE) strEntry.MakeLower();
if(strEntry.Find(strFind) != -1) return i;
}
if(fieldFlags & PWMF_ADDITIONAL)
{
strEntry = m_pEntries[i].pszAdditional;
if(bCaseSensitive == FALSE) strEntry.MakeLower();
if(strEntry.Find(strFind) != -1) return i;
}
if(fieldFlags & PWMF_GROUPNAME)
{
DWORD dwGroupIndex = GetGroupByIdN(m_pEntries[i].uGroupId);
ASSERT(dwGroupIndex != DWORD_MAX);
strEntry = GetGroup(dwGroupIndex)->pszGroupName;
if(bCaseSensitive == FALSE) strEntry.MakeLower();
if(strEntry.Find(strFind) != -1) return i;
}
}
return DWORD_MAX;
}
void CPwManager::MoveInternal(DWORD dwFrom, DWORD dwTo)
{
LONG i, dir;
PW_ENTRY pe;
if(dwFrom == dwTo) return; // Nothing to do
if(dwFrom >= m_dwNumEntries) return; // Invalid index
if(dwTo >= m_dwNumEntries) return; // Invalid index
// Set moving direction
if(dwFrom < dwTo) dir = 1;
else dir = -1;
i = (LONG)dwFrom;
while(1)
{
if(i == (LONG)dwTo) break;
pe = m_pEntries[i];
m_pEntries[i] = m_pEntries[i+dir];
m_pEntries[i+dir] = pe;
i += dir;
}
}
BOOL CPwManager::MoveGroup(DWORD dwFrom, DWORD dwTo)
{
LONG i, dir;
PW_GROUP pg;
ASSERT((dwFrom != DWORD_MAX) && (dwTo != DWORD_MAX));
if(dwFrom == dwTo) return TRUE;
if(dwFrom >= m_dwNumGroups) return FALSE;
if(dwTo >= m_dwNumGroups) return FALSE;
// Set moving direction
if(dwFrom < dwTo) dir = 1;
else dir = -1;
i = (LONG)dwFrom;
while(1)
{
if(i == (LONG)dwTo) break;
pg = m_pGroups[i];
m_pGroups[i] = m_pGroups[i+dir];
m_pGroups[i+dir] = pg;
i += dir;
}
FixGroupTree();
return TRUE;
}
void CPwManager::MoveInGroup(DWORD idGroup, DWORD dwFrom, DWORD dwTo)
{
if((dwFrom >= m_dwNumEntries) || (dwFrom == DWORD_MAX)) return;
if((dwTo >= m_dwNumEntries) || (dwTo == DWORD_MAX)) return;
if(dwFrom == dwTo) return;
DWORD dwFromEx = GetEntryByGroupN(idGroup, dwFrom);
DWORD dwToEx = GetEntryByGroupN(idGroup, dwTo);
if((dwFromEx == DWORD_MAX) || (dwToEx == DWORD_MAX)) return;
MoveInternal(dwFromEx, dwToEx);
}
BOOL CPwManager::GetGroupTree(DWORD idGroup, DWORD *pGroupIndexes) const
{
DWORD i, dwGroupPos;
USHORT usLevel;
ASSERT(pGroupIndexes != NULL); if(pGroupIndexes == NULL) return FALSE;
dwGroupPos = GetGroupByIdN(idGroup);
ASSERT(dwGroupPos != DWORD_MAX); if(dwGroupPos == DWORD_MAX) return FALSE;
i = dwGroupPos;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?