예제 #1
0
void CDbxKyoto::ToggleEncryption()
{
	HANDLE hSave1 = hSettingChangeEvent;    hSettingChangeEvent = NULL;
	HANDLE hSave2 = hEventAddedEvent;       hEventAddedEvent = NULL;
	HANDLE hSave3 = hEventDeletedEvent;     hEventDeletedEvent = NULL;
	HANDLE hSave4 = hEventFilterAddedEvent; hEventFilterAddedEvent = NULL;

	mir_cslock lck(m_csDbAccess);
	ToggleSettingsEncryption(NULL);
	ToggleEventsEncryption(NULL);

	for (MCONTACT contactID = FindFirstContact(); contactID; contactID = FindNextContact(contactID)) {
		ToggleSettingsEncryption(contactID);
		ToggleEventsEncryption(contactID);
	}

	m_bEncrypted = !m_bEncrypted;

	DBCONTACTWRITESETTING dbcws = { "CryptoEngine", "DatabaseEncryption" };
	dbcws.value.type = DBVT_BYTE;
	dbcws.value.bVal = m_bEncrypted;
	WriteContactSetting(NULL, &dbcws);

	hSettingChangeEvent = hSave1;
	hEventAddedEvent = hSave2;
	hEventDeletedEvent = hSave3;
	hEventFilterAddedEvent = hSave4;
}
예제 #2
0
void CDbxKyoto::StoreKey()
{
	size_t iKeyLength = m_crypto->getKeyLength();
	BYTE *pKey = (BYTE*)_alloca(iKeyLength);
	m_crypto->getKey(pKey, iKeyLength);

	DBCONTACTWRITESETTING dbcws = { "CryptoEngine", "StoredKey" };
	dbcws.value.type = DBVT_BLOB;
	dbcws.value.cpbVal = (WORD)iKeyLength;
	dbcws.value.pbVal = pKey;
	WriteContactSetting(NULL, &dbcws);

	SecureZeroMemory(pKey, iKeyLength);
}
예제 #3
0
int CDbxKyoto::InitCrypt()
{
	CRYPTO_PROVIDER *pProvider;
	bool bMissingKey = false;

	DBVARIANT dbv = { 0 };
	dbv.type = DBVT_BLOB;
	if (GetContactSetting(NULL, "CryptoEngine", "Provider", &dbv)) {
	LBL_CreateProvider:
		CRYPTO_PROVIDER **ppProvs;
		int iNumProvs;
		Crypto_EnumProviders(&iNumProvs, &ppProvs);
		if (iNumProvs == 0)
			return 1;

		pProvider = ppProvs[0];  //!!!!!!!!!!!!!!!!!!

		DBCONTACTWRITESETTING dbcws = { "CryptoEngine", "Provider" };
		dbcws.value.type = DBVT_BLOB;
		dbcws.value.pbVal = (PBYTE)pProvider->pszName;
		dbcws.value.cpbVal = (int)strlen(pProvider->pszName) + 1;
		WriteContactSetting(NULL, &dbcws);
	}
	else {
		if (dbv.type != DBVT_BLOB) { // old version, clean it up
			bMissingKey = true;
			goto LBL_CreateProvider;
		}

		pProvider = Crypto_GetProvider(LPCSTR(dbv.pbVal));
		FreeVariant(&dbv);
		if (pProvider == NULL)
			goto LBL_CreateProvider;
	}

	if ((m_crypto = pProvider->pFactory()) == NULL)
		return 3;

	dbv.type = DBVT_BLOB;
	if (GetContactSetting(NULL, "CryptoEngine", "StoredKey", &dbv)) {
		bMissingKey = true;

	LBL_SetNewKey:
		m_crypto->generateKey(); // unencrypted key
		StoreKey();
	}
	else {
		size_t iKeyLength = m_crypto->getKeyLength();
		if (dbv.cpbVal != (WORD)iKeyLength)
			goto LBL_SetNewKey;

		if (!m_crypto->setKey(dbv.pbVal, iKeyLength))
			if (!EnterPassword(dbv.pbVal, iKeyLength))  // password protected?
				return 4;

		FreeVariant(&dbv);
	}

	if (bMissingKey)
		EnumModuleNames(sttModuleEnum, this);

	dbv.type = DBVT_BYTE;
	if (!GetContactSetting(NULL, "CryptoEngine", "DatabaseEncryption", &dbv))
		m_bEncrypted = dbv.bVal != 0;

	InitDialogs();
	return 0;
}
예제 #4
0
void CDb3Mmap::FillContacts()
{
	OBJLIST<COldMeta> arMetas(10, NumericKeySortT);

	for (DWORD dwOffset = m_dbHeader.ofsFirstContact; dwOffset != 0;) {
		DBContact *p = (DBContact*)DBRead(dwOffset, NULL);
		if (p->signature != DBCONTACT_SIGNATURE)
			break;

		DWORD dwContactID;
		if (m_dbHeader.version >= DB_095_VERSION) {
			dwContactID = p->dwContactID;
			if (dwContactID > m_dwMaxContactId)
				m_dwMaxContactId = dwContactID + 1;
		}
		else dwContactID = m_dwMaxContactId++;

		DBCachedContact *cc = m_cache->AddContactToCache(dwContactID);
		cc->dwDriverData = dwOffset;
		CheckProto(cc, "");

		DBVARIANT dbv; dbv.type = DBVT_DWORD;
		cc->nSubs = (0 != GetContactSetting(dwContactID, META_PROTO, "NumContacts", &dbv)) ? -1 : dbv.dVal;
		if (cc->nSubs != -1) {
			cc->pSubs = (MCONTACT*)mir_alloc(cc->nSubs*sizeof(MCONTACT));
			for (int i = 0; i < cc->nSubs; i++) {
				char setting[100];
				mir_snprintf(setting, SIZEOF(setting), "Handle%d", i);
				cc->pSubs[i] = (0 != GetContactSetting(dwContactID, META_PROTO, setting, &dbv)) ? NULL : dbv.dVal;
			}
		}
		cc->nDefault = (0 != GetContactSetting(dwContactID, META_PROTO, "Default", &dbv)) ? -1 : dbv.dVal;
		cc->parentID = (0 != GetContactSetting(dwContactID, META_PROTO, "ParentMeta", &dbv)) ? NULL : dbv.dVal;

		// whether we need conversion or not
		if (!GetContactSetting(dwContactID, META_PROTO, "MetaID", &dbv))
			arMetas.insert(new COldMeta(dbv.dVal, cc));

		dwOffset = p->ofsNext;
	}

	// no need in conversion? quit then
	if (m_bReadOnly || arMetas.getCount() == 0)
		return;

	DBVARIANT dbv; dbv.type = DBVT_DWORD;
	for (MCONTACT hh = FindFirstContact(); hh; hh = FindNextContact(hh)) {
		if (GetContactSetting(hh, META_PROTO, "MetaLink", &dbv))
			continue;

		COldMeta *p = arMetas.find((COldMeta*)&dbv.dVal);
		if (p == NULL)
			continue;

		if (GetContactSetting(hh, META_PROTO, "ContactNumber", &dbv))
			continue;

		DBCONTACTWRITESETTING dbws = { META_PROTO };
		dbws.value.type = DBVT_DWORD;

		DBCachedContact *ccMeta = p->cc;
		if (int(dbv.dVal) < ccMeta->nSubs) {
			ccMeta->pSubs[dbv.dVal] = hh;

			char setting[100];
			mir_snprintf(setting, SIZEOF(setting), "Handle%d", dbv.dVal);
			dbws.szSetting = setting;
			dbws.value.dVal = hh;
			WriteContactSetting(ccMeta->contactID, &dbws);
		}

		// store contact id instead of the old mc number
		dbws.szSetting = "ParentMeta";
		dbws.value.dVal = ccMeta->contactID;
		WriteContactSetting(hh, &dbws);

		// wipe out old data from subcontacts
		DeleteContactSetting(hh, META_PROTO, "ContactNumber");
		DeleteContactSetting(hh, META_PROTO, "MetaLink");
	}

	for (int i = 0; i < arMetas.getCount(); i++) {
		COldMeta &p = arMetas[i];
		DBCachedContact *ccMeta = p.cc;
		MCONTACT hContact = ccMeta->contactID;

		// we don't need it anymore
		if (!GetContactSetting(hContact, META_PROTO, "MetaID", &dbv)) {
			DeleteContactSetting(hContact, META_PROTO, "MetaID");
			WipeContactHistory((DBContact*)DBRead(ccMeta->dwDriverData, NULL));
		}

		for (int k = 0; k < ccMeta->nSubs; k++) {
			DBCachedContact *ccSub = m_cache->GetCachedContact(ccMeta->pSubs[k]);
			if (ccSub) {
				ccSub->parentID = hContact;
				MetaMergeHistory(ccMeta, ccSub);
			}
		}
	}
}
예제 #5
0
void CDb3Mmap::ToggleSettingsEncryption(MCONTACT contactID)
{
	DWORD ofsContact = GetContactOffset(contactID);
	if (ofsContact == 0)
		return;

	DBContact *contact = (DBContact*)DBRead(ofsContact, NULL);
	if (contact->ofsFirstSettings == 0)
		return;

	// fast cycle through all settings
	DBContactSettings *setting = (DBContactSettings*)DBRead(contact->ofsFirstSettings, NULL);
	DWORD offset = contact->ofsFirstSettings;
	char *szModule = GetModuleNameByOfs(setting->ofsModuleName);
	if (szModule == NULL)
		return;

	while (true) {
		OBJLIST<VarDescr> arSettings(10);
		char szSetting[256];
		int bytesRemaining, len;
		DWORD ofsBlobPtr = offset + offsetof(DBContactSettings, blob), ofsNext = setting->ofsNext;
		PBYTE pBlob = (PBYTE)DBRead(ofsBlobPtr, &bytesRemaining);
		while (pBlob[0]) {
			NeedBytes(1);
			len = pBlob[0];
			memcpy(szSetting, pBlob + 1, len); szSetting[len] = 0;
			NeedBytes(1 + pBlob[0]);
			MoveAlong(1 + pBlob[0]);
			NeedBytes(5);

			switch (pBlob[0]) {
			case DBVT_ASCIIZ:
				len = *(PWORD)(pBlob + 1);
				// we need to convert a string into utf8 and encrypt it
				if (!m_bEncrypted) {
					BYTE bSave = pBlob[len + 3]; pBlob[len + 3] = 0;
					arSettings.insert(new VarDescr(szSetting, mir_utf8encode((LPCSTR)pBlob + 3)));
					pBlob[len + 3] = bSave;
				}
				NeedBytes(3 + len);
				break;

			case DBVT_UTF8:
				len = *(PWORD)(pBlob + 1);
				// we need to encrypt these strings
				if (!m_bEncrypted) {
					BYTE bSave = pBlob[len + 3]; pBlob[len + 3] = 0;
					arSettings.insert(new VarDescr(szSetting, (LPCSTR)pBlob + 3));
					pBlob[len + 3] = bSave;
				}
				NeedBytes(3 + len);
				break;

			case DBVT_ENCRYPTED:
				len = *(PWORD)(pBlob + 1);
				// we need to decrypt these strings
				if (m_bEncrypted && !IsSettingEncrypted(szModule, szSetting))
					arSettings.insert(new VarDescr(szSetting, pBlob + 3, len));
				NeedBytes(3 + len);
				break;

			case DBVT_BLOB:
				NeedBytes(3 + *(PWORD)(pBlob + 1));
				break;
			}
			NeedBytes(3);
			MoveAlong(1 + GetSettingValueLength(pBlob));
			NeedBytes(1);
		}

		for (int i = 0; i < arSettings.getCount(); i++) {
			VarDescr &p = arSettings[i];
			if (!m_bEncrypted) {
				size_t encodedLen;
				BYTE *pResult = m_crypto->encodeString(p.szValue, &encodedLen);
				if (pResult != NULL) {
					DBCONTACTWRITESETTING dbcws = { szModule, p.szVar };
					dbcws.value.type = DBVT_ENCRYPTED;
					dbcws.value.pbVal = pResult;
					dbcws.value.cpbVal = (WORD)encodedLen;
					WriteContactSetting(contactID, &dbcws);

					mir_free(pResult);
				}
			}
			else {
				size_t realLen;
				ptrA decoded(m_crypto->decodeString((PBYTE)(char*)p.szValue, p.iLen, &realLen));
				if (decoded != NULL) {
					DBCONTACTWRITESETTING dbcws = { szModule, p.szVar };
					dbcws.value.type = DBVT_UNENCRYPTED;
					dbcws.value.pszVal = decoded;
					dbcws.value.cchVal = (WORD)realLen;
					WriteContactSetting(contactID, &dbcws);
				}
			}
		}

		if (!ofsNext)
			break;

		setting = (DBContactSettings*)DBRead(offset = ofsNext, NULL);
		if ((szModule = GetModuleNameByOfs(setting->ofsModuleName)) == NULL)
			break;
	}
}
예제 #6
0
int CDb3Mmap::InitCrypt()
{
	if (m_dbHeader.version == DB_OLD_VERSION)
		return 0;

	CRYPTO_PROVIDER *pProvider;
	bool bMissingKey = false;

	DBVARIANT dbv = { 0 };
	dbv.type = DBVT_BLOB;
	if (GetContactSetting(NULL, "CryptoEngine", "Provider", &dbv)) {
	LBL_CreateProvider:
		CRYPTO_PROVIDER **ppProvs;
		int iNumProvs;
		Crypto_EnumProviders(&iNumProvs, &ppProvs);
		if (iNumProvs == 0)
			return 1;

		if (iNumProvs > 1)
		{
			CSelectCryptoDialog dlg(ppProvs, iNumProvs);
			dlg.DoModal();
			pProvider = dlg.GetSelected();
		}
		else pProvider = ppProvs[0];

		DBCONTACTWRITESETTING dbcws = { "CryptoEngine", "Provider" };
		dbcws.value.type = DBVT_BLOB;
		dbcws.value.pbVal = (PBYTE)pProvider->pszName;
		dbcws.value.cpbVal = (int)mir_strlen(pProvider->pszName) + 1;
		WriteContactSetting(NULL, &dbcws);
	}
	else {
		if (dbv.type != DBVT_BLOB) { // old version, clean it up
			bMissingKey = true;
			goto LBL_CreateProvider;
		}

		pProvider = Crypto_GetProvider(LPCSTR(dbv.pbVal));
		FreeVariant(&dbv);
		if (pProvider == NULL)
			goto LBL_CreateProvider;
	}

	if ((m_crypto = pProvider->pFactory()) == NULL)
		return 3;

	dbv.type = DBVT_BLOB;
	if (GetContactSetting(NULL, "CryptoEngine", "StoredKey", &dbv)) {
		bMissingKey = true;

	LBL_SetNewKey:
		m_crypto->generateKey(); // unencrypted key
		StoreKey();
	}
	else {
		size_t iKeyLength = m_crypto->getKeyLength();
		if (dbv.cpbVal != (WORD)iKeyLength)
			goto LBL_SetNewKey;

		if (!m_crypto->setKey(dbv.pbVal, iKeyLength)) {
			if (memcmp(m_dbHeader.signature, &dbSignatureE, sizeof(m_dbHeader.signature)))
				goto LBL_SetNewKey;

			if (!EnterPassword(dbv.pbVal, iKeyLength)) { // password protected?
				if (m_dbHeader.version >= DB_094_VERSION)
					return 4;

				// one of the early used version of mmap was replaced then by mmap_sa
				// simply remove old badly generated key
				bMissingKey = true;
				goto LBL_SetNewKey;
			}
		}

		FreeVariant(&dbv);
	}

	if (bMissingKey)
		EnumModuleNames(sttModuleEnum, this);

	dbv.type = DBVT_BYTE;
	if (!GetContactSetting(NULL, "CryptoEngine", "DatabaseEncryption", &dbv))
		m_bEncrypted = dbv.bVal != 0;

	InitDialogs();
	return 0;
}