pwimport.cpp

来自「一款密码保险箱源码」· C++ 代码 · 共 786 行 · 第 1/2 页

CPP
786
字号
				pwTemplate.tCreation = tNow; CPwManager::GetNeverExpireTime(&pwTemplate.tExpire);
				pwTemplate.tLastAccess = tNow; pwTemplate.tLastMod = tNow;
				pwTemplate.uGroupId = dwLastGroupId;
				pwTemplate.uImageId = _GetPreferredIcon((LPCTSTR)strTitle);
				pwTemplate.uPasswordLen = strPassword.GetLength();

				pMgr->AddEntry(&pwTemplate);
			}

			strTitle.Empty(); strURL.Empty(); strUserName.Empty();
			strPassword.Empty(); strNotes.Empty();
			bInNotes = FALSE;
		}

		if(i >= uFileSize) break;

		if(bInNotes == TRUE)
		{
			if(strNotes.GetLength() != 0) strNotes += _T("\r\n");
			strNotes += str.Right(str.GetLength() - 14);
		}

		if((str.Left(12) == DEF_PV_CATEGORY) && (str.Right(12) == DEF_PV_CATEGORY))
		{
			strLastCategory = str.Right(str.GetLength() - 12);
			strLastCategory = strLastCategory.Left(strLastCategory.GetLength() - 12);
			strLastCategory.TrimLeft(); strLastCategory.TrimRight();

			if(strLastCategory.GetLength() == 0)
				strLastCategory = TRL("General");
			dwLastGroupId = pMgr->GetGroupId((LPCTSTR)strLastCategory);
			if(dwLastGroupId == DWORD_MAX)
			{
				PW_GROUP pwT;
				PW_TIME tNow;
				_GetCurrentPwTime(&tNow);
				memset(&pwT, 0, sizeof(PW_GROUP));
				pwT.pszGroupName = (TCHAR *)(LPCTSTR)strLastCategory;
				pwT.tCreation = tNow; CPwManager::GetNeverExpireTime(&pwT.tExpire);
				pwT.tLastAccess = tNow; pwT.tLastMod = tNow;
				pwT.uGroupId = 0; // 0 = create new group ID
				pwT.uImageId = _GetPreferredIcon((LPCTSTR)strLastCategory);
				pMgr->AddGroup(&pwT);
				dwLastGroupId = pMgr->GetGroupId((LPCTSTR)strLastCategory);
			}
			ASSERT(dwLastGroupId != DWORD_MAX);
		}

		if((str.Left(9) == _T("Comments:")) && (bInNotes == FALSE))
		{
			bInNotes = TRUE;
			str = str.Right(str.GetLength() - 9);
			if(str.GetLength() != 0) strNotes = str;
			continue;
		}

		if(str.Left(9) == _T("Account: ")) {strTitle = str.Right(str.GetLength() - 9); b=1;}

		b=0;
		if(str.Left(11) == _T("User Name: ")) {strUserName = str.Right(str.GetLength() - 11); b=1;}

		if(str.Left(11) == _T("Hyperlink: ")) {strURL = str.Right(str.GetLength() - 11); b=1;}

		if(str.Left(10) == _T("Password: ")) {strPassword = str.Right(str.GetLength() - 10); b=1;}

		if((b == 0) && (bInNotes == FALSE))
		{
			if(strNotes.GetLength() != 0) strNotes += _T("\r\n");
			strNotes += str;
		}
	}

	SAFE_DELETE_ARRAY(pData);

	return TRUE;
}

BOOL CPwImport::ImportPwSafeToDb(const TCHAR *pszFile, CPwManager *pMgr)
{
	char *pData;
	unsigned long uFileSize, i;
	int nField, j;
	CString strGroup, strTitle, strUserName, strPassword, strNotes;
	DWORD dwGroupId;
	BOOL bInNotes = FALSE;
	CString str3, str4, str5, str6;

	ASSERT(pszFile != NULL); if(pszFile == NULL) return FALSE;
	ASSERT(pMgr != NULL); if(pMgr == NULL) return FALSE;

	pData = CPwImport::FileToMemory(pszFile, &uFileSize);
	if(pData == NULL) return FALSE;

	nField = 0;
	i = 0; j = 0;
	strGroup.Empty(); strTitle.Empty(); strUserName.Empty(); strPassword.Empty(); strNotes.Empty();

	if(uFileSize > 3)
		if((pData[0] == 0xEF) && (pData[1] == 0xBB) && (pData[2] == 0xBF))
			i += 3; // Skip UTF-8 initialization characters

	while(1)
	{
		if((pData[i] == '\t') && (bInNotes == FALSE))
		{
			nField++;

			if(nField == 1)
			{
				j = strGroup.ReverseFind(_T('.'));

				// Thanks to Andrew D. Bond for the following improvement
				// Slightly enhanced by D. Reichl to detect some more URLs

				// -- Andrew D. Bond
				// Introduction: The Password Safe export format is rather flawed,
				// since it uses the '.' character as the group / title separator.
				// However, '.' is not likely to appear in the context of titles
				// that include 'com', 'org', 'edu', etc, (domain names) or even
				// 'zip' (password protected zip files)

				// Slightly-smarter import: if the '.' we just found is followed
				// by 'com', 'org', 'edu', etc, (domain names) or even
				// 'zip' (password protected zip files) then figure this is part
				// of the title and try the group / title splitting again.
				// Example:
				//  strGroup = "websites.someSite.com" // j == 17 // <- INCORRECT
				//
				// Overall, these fixes do make things much better.
				// However, they will still not be able to handle entries where
				// the title has _other_ "."'s in it.
				// For example, when the title is:
				//  subdomain.domain.com
				//  mySoftware version 8.5
				//	domain.tv (replace .tv with any domain suffix not included below)

				if((strGroup.GetLength() >= 4) && (j != -1))
					str3 = strGroup.Right(3);
				else
					str3 = _T("   ");
				if((strGroup.GetLength() >= 5) && (j != -1))
					str4 = strGroup.Right(4);
				else
					str4 = _T("    ");
				if((strGroup.GetLength() >= 6) && (j != -1))
					str5 = strGroup.Right(5);
				else
					str5 = _T("     ");
				if((strGroup.GetLength() >= 7) && (j != -1))
					str6 = strGroup.Right(6);
				else
					str6 = _T("      ");

				str3.MakeLower(); str4.MakeLower(); str5.MakeLower(); str6.MakeLower();

				if((str4 == _T(".com")) || (str4 == _T(".org")) || (str4 == _T(".edu"))
					|| (str4 == _T(".net")) || (str4 == _T(".zip"))
					|| (str3 == _T(".uk")) || (str3 == _T(".de")) || (str3 == _T(".ch"))
					|| (str3 == _T(".at")) || (str3 == _T(".it")))
				{
					// Fix for double-point URLs like .co.uk
					if(str6 == _T(".co.uk")) j -= 3;

					strTitle = strGroup.Right(strGroup.GetLength() - j);
					strGroup = strGroup.Left(j);
					j = strGroup.ReverseFind(_T('.'));
				}

				if(j != -1)
				{
					strTitle = strGroup.Right(strGroup.GetLength() - j - 1) + strTitle;
					strGroup = strGroup.Left(j);
				}
				else
				{
					// No '.' was found, or it is part of a ".com" in the title.
					// Since Password Safe
					// **requires** a title but not a group name, this means
					// that a group name was not specified (a common
					// occurrence). We should assign a logical group name
					// and store the title we just identified. 
					strTitle = strGroup + strTitle;
					strGroup = TRL("Imported from Password Safe");
				}
			}
		}
		else if((pData[i] == '\"') && (bInNotes == FALSE) && (nField == 3))
		{
			bInNotes = TRUE;
		}
		else if((pData[i] == '\"') && (bInNotes == TRUE) && (nField == 3))
		{
			bInNotes = FALSE;

			if(strNotes.GetLength() != 0)
			{
				if(strNotes.GetAt(0) == _T('\"')) strNotes = strNotes.Right(strNotes.GetLength() - 1);
				if(strNotes.Right(1) == _T("\"")) strNotes = strNotes.Left(strNotes.GetLength() - 1);
			}
		}
		else if((pData[i] == '\r') && (bInNotes == FALSE))
		{
			// Ignore all \r
		}
		else if((pData[i] == '\n') && (bInNotes == FALSE))
		{
			dwGroupId = pMgr->GetGroupId((LPCTSTR)strGroup);
			if(dwGroupId == DWORD_MAX)
			{
				PW_GROUP pwT;
				PW_TIME tNow;
				_GetCurrentPwTime(&tNow);
				memset(&pwT, 0, sizeof(PW_GROUP));
				pwT.pszGroupName = (TCHAR *)(LPCTSTR)strGroup;
				pwT.tCreation = tNow; CPwManager::GetNeverExpireTime(&pwT.tExpire);
				pwT.tLastAccess = tNow; pwT.tLastMod = tNow;
				pwT.uGroupId = 0; // 0 = create new group ID
				pwT.uImageId = _GetPreferredIcon((LPCTSTR)strGroup);
				pMgr->AddGroup(&pwT);
				dwGroupId = pMgr->GetGroupId((LPCTSTR)strGroup);
			}
			ASSERT(dwGroupId != DWORD_MAX);

			PW_ENTRY pwTemplate;
			PW_TIME tNow;

			memset(&pwTemplate, 0, sizeof(PW_ENTRY));
			_GetCurrentPwTime(&tNow);
			pwTemplate.pszAdditional = (TCHAR *)(LPCTSTR)strNotes;
			pwTemplate.pszPassword = (TCHAR *)(LPCTSTR)strPassword;
			pwTemplate.pszTitle = (TCHAR *)(LPCTSTR)strTitle;
			pwTemplate.pszURL = g_pNullString;
			pwTemplate.pszUserName = (TCHAR *)(LPCTSTR)strUserName;
			pwTemplate.tCreation = tNow; CPwManager::GetNeverExpireTime(&pwTemplate.tExpire);
			pwTemplate.tLastAccess = tNow; pwTemplate.tLastMod = tNow;
			pwTemplate.uImageId = _GetPreferredIcon((LPCTSTR)strTitle);
			pwTemplate.uPasswordLen = strPassword.GetLength();
			pwTemplate.uGroupId = dwGroupId;
			// UUID is zero -> create new UUID

			pMgr->AddEntry(&pwTemplate);

			strGroup.Empty(); strTitle.Empty(); strUserName.Empty();
			strPassword.Empty(); strNotes.Empty();
			nField = 0;
		}
		else
		{
			if(nField == 0) strGroup += pData[i];
			else if(nField == 1) strUserName += pData[i];
			else if(nField == 2) strPassword += pData[i];
			else if(nField == 3) strNotes += pData[i];
		}

		i++;
		if(i >= uFileSize) break;
	}

	EraseCString(&strGroup); EraseCString(&strTitle); EraseCString(&strUserName);
	EraseCString(&strPassword); EraseCString(&strNotes);

	SAFE_DELETE_ARRAY(pData);
	return TRUE;
}

void CPwImport::_AddStringStreamToDb(const char *pStream, unsigned long uStreamSize, BOOL bUTF8)
{
	DWORD s;
	char *pTitle = NULL, *pUserName = NULL, *pPassword = NULL, *pURL = NULL, *pNotes = NULL;
	char *p = (char *)pStream;
	char *pEnd = (char *)pStream + uStreamSize;
	TCHAR *tszTitle = NULL, *tszUserName = NULL, *tszPassword = NULL, *tszURL = NULL, *tszNotes = NULL;

	ASSERT(pStream != NULL);

	while(1)
	{
		if(p >= pEnd) break;
		pTitle = p;
		s = szlen(p);
		p += s + 1;

		if(p >= pEnd) break;
		pUserName = p;
		s = szlen(p);
		p += s + 1;

		if(p >= pEnd) break;
		pPassword = p;
		s = szlen(p);
		p += s + 1;

		if(p >= pEnd) break;
		pURL = p;
		s = szlen(p);
		p += s + 1;

		if(p >= pEnd) break;
		pNotes = p;
		s = szlen(p);
		p += s + 1;

		if((strcmp(pTitle, "Account") != 0) && (strcmp(pPassword, "Password") != 0))
		{
			PW_ENTRY pwTemplate;
			PW_TIME tNow;

			if(bUTF8 == TRUE)
			{
				tszTitle = _UTF8ToString((UTF8_BYTE *)pTitle);
				tszUserName = _UTF8ToString((UTF8_BYTE *)pUserName);
				tszPassword = _UTF8ToString((UTF8_BYTE *)pPassword);
				tszURL = _UTF8ToString((UTF8_BYTE *)pURL);
				tszNotes = _UTF8ToString((UTF8_BYTE *)pNotes);
			}
			else
			{
				tszTitle = (TCHAR *)pTitle;
				tszUserName = (TCHAR *)pUserName;
				tszPassword = (TCHAR *)pPassword;
				tszURL = (TCHAR *)pURL;
				tszNotes = (TCHAR *)pNotes;
			}

			memset(&pwTemplate, 0, sizeof(PW_ENTRY));
			_GetCurrentPwTime(&tNow);
			pwTemplate.pszAdditional = tszNotes;
			pwTemplate.pszPassword = tszPassword;
			pwTemplate.pszTitle = tszTitle;
			pwTemplate.pszURL = tszURL;
			pwTemplate.pszUserName = tszUserName;
			pwTemplate.tCreation = tNow; CPwManager::GetNeverExpireTime(&pwTemplate.tExpire);
			pwTemplate.tLastAccess = tNow; pwTemplate.tLastMod = tNow;
			pwTemplate.uGroupId = m_dwLastGroupId;
			pwTemplate.uImageId = _GetPreferredIcon(tszTitle);
			pwTemplate.uPasswordLen = static_cast<DWORD>(_tcslen(tszPassword));
			// UUID is zero -> create new UUID

			m_pLastMgr->AddEntry(&pwTemplate);

			if(bUTF8 == TRUE)
			{
				SAFE_DELETE_ARRAY(tszTitle);
				SAFE_DELETE_ARRAY(tszUserName);
				SAFE_DELETE_ARRAY(tszPassword);
				SAFE_DELETE_ARRAY(tszURL);
				SAFE_DELETE_ARRAY(tszNotes);
			}
		}
	}
}

unsigned long CPwImport::_GetPreferredIcon(LPCTSTR pszGroup)
{
	CString str = pszGroup;

	if(str.Find(_T("Windows")) != -1) return 38;
	if(str.Find(_T("System")) != -1) return 38;

	if(str.Find(_T("Network")) != -1) return 3;
	if(str.Find(_T("Connection")) != -1) return 3;
	if(str.Find(_T("VPN")) != -1) return 3;
	if(str.Find(_T("LAN")) != -1) return 3;

	if(str.Find(_T("Internet")) != -1) return 1;
	if(str.Find(_T("internet")) != -1) return 1;
	if(str.Find(_T("Web")) != -1) return 1;
	if(str.Find(_T("www")) != -1) return 1;
	if(str.Find(_T("WWW")) != -1) return 1;
	if(str.Find(_T("http")) != -1) return 1;
	if(str.Find(_T("HTTP")) != -1) return 1;
	if(str.Find(_T("ftp")) != -1) return 1;
	if(str.Find(_T("FTP")) != -1) return 1;

	if(str.Find(_T("eMail")) != -1) return 19;
	if(str.Find(_T("mail")) != -1) return 19;
	if(str.Find(_T("Post")) != -1) return 19;
	if(str.Find(_T("@")) != -1) return 19;

	if(str.Find(_T("Homebanking")) != -1) return 37;
	if(str.Find(_T("Banking")) != -1) return 37;
	if(str.Find(_T("Archive")) != -1) return 37;
	if(str.Find(_T("Collection")) != -1) return 37;
	if(str.Find(_T("Cash")) != -1) return 37;

	if(str.Find(_T("Explorer")) != -1) return 9;
	if(str.Find(_T("Netscape")) != -1) return 9;
	if(str.Find(_T("Mozilla")) != -1) return 9;
	if(str.Find(_T("Opera")) != -1) return 9;

	return 0;
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?