pwexport.cpp

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

CPP
818
字号
/*
  KeePass Password Safe - The Open-Source Password Manager
  Copyright (C) 2003-2007 Dominik Reichl <dominik.reichl@t-online.de>

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

#include "StdAfx.h"
#include "PwExport.h"
#include <vector>

#include "../Util/MemUtil.h"
#include "../Util/StrUtil.h"
#include "../Util/Base64.h"
#include "../Util/TranslateEx.h"

CPwExport::CPwExport()
{
	m_pMgr = NULL;
	m_nFormat = 0;
	m_fp = NULL;

	SetNewLineSeq(FALSE);

	ZeroMemory(&m_aDefaults[PWEXP_TXT], sizeof(PWEXPORT_OPTIONS));
	m_aDefaults[PWEXP_TXT].bGroup = TRUE;
	m_aDefaults[PWEXP_TXT].bTitle = TRUE;
	m_aDefaults[PWEXP_TXT].bUserName = TRUE;
	m_aDefaults[PWEXP_TXT].bURL = TRUE;
	m_aDefaults[PWEXP_TXT].bPassword = TRUE;
	m_aDefaults[PWEXP_TXT].bNotes = TRUE;

	ZeroMemory(&m_aDefaults[PWEXP_HTML], sizeof(PWEXPORT_OPTIONS));
	m_aDefaults[PWEXP_HTML].bGroup = TRUE;
	m_aDefaults[PWEXP_HTML].bTitle = TRUE;
	m_aDefaults[PWEXP_HTML].bUserName = TRUE;
	m_aDefaults[PWEXP_HTML].bURL = TRUE;
	m_aDefaults[PWEXP_HTML].bPassword = TRUE;
	m_aDefaults[PWEXP_HTML].bNotes = TRUE;

	ZeroMemory(&m_aDefaults[PWEXP_XML], sizeof(PWEXPORT_OPTIONS));
	m_aDefaults[PWEXP_XML].bGroup = TRUE;
	m_aDefaults[PWEXP_XML].bGroupTree = TRUE;
	m_aDefaults[PWEXP_XML].bTitle = TRUE;
	m_aDefaults[PWEXP_XML].bUserName = TRUE;
	m_aDefaults[PWEXP_XML].bURL = TRUE;
	m_aDefaults[PWEXP_XML].bPassword = TRUE;
	m_aDefaults[PWEXP_XML].bNotes = TRUE;
	m_aDefaults[PWEXP_XML].bUUID = TRUE;
	m_aDefaults[PWEXP_XML].bImage = TRUE;
	m_aDefaults[PWEXP_XML].bCreationTime = TRUE;
	m_aDefaults[PWEXP_XML].bLastAccTime = TRUE;
	m_aDefaults[PWEXP_XML].bLastModTime = TRUE;
	m_aDefaults[PWEXP_XML].bExpireTime = TRUE;
	m_aDefaults[PWEXP_XML].bAttachment = TRUE;

	ZeroMemory(&m_aDefaults[PWEXP_CSV], sizeof(PWEXPORT_OPTIONS));
	m_aDefaults[PWEXP_CSV].bTitle = TRUE;
	m_aDefaults[PWEXP_CSV].bUserName = TRUE;
	m_aDefaults[PWEXP_CSV].bURL = TRUE;
	m_aDefaults[PWEXP_CSV].bPassword = TRUE;
	m_aDefaults[PWEXP_CSV].bNotes = TRUE;

	ZeroMemory(&m_aDefaults[PWEXP_KEEPASS], sizeof(PWEXPORT_OPTIONS));
	m_aDefaults[PWEXP_KEEPASS].bGroup = TRUE;
	m_aDefaults[PWEXP_KEEPASS].bGroupTree = TRUE;
	m_aDefaults[PWEXP_KEEPASS].bTitle = TRUE;
	m_aDefaults[PWEXP_KEEPASS].bUserName = TRUE;
	m_aDefaults[PWEXP_KEEPASS].bURL = TRUE;
	m_aDefaults[PWEXP_KEEPASS].bPassword = TRUE;
	m_aDefaults[PWEXP_KEEPASS].bNotes = TRUE;
	m_aDefaults[PWEXP_KEEPASS].bUUID = TRUE;
	m_aDefaults[PWEXP_KEEPASS].bImage = TRUE;
	m_aDefaults[PWEXP_KEEPASS].bCreationTime = TRUE;
	m_aDefaults[PWEXP_KEEPASS].bLastAccTime = TRUE;
	m_aDefaults[PWEXP_KEEPASS].bLastModTime = TRUE;
	m_aDefaults[PWEXP_KEEPASS].bExpireTime = TRUE;
	m_aDefaults[PWEXP_KEEPASS].bAttachment = TRUE;
	m_aDefaults[PWEXP_KEEPASS].bExportBackups = TRUE;
}

CPwExport::~CPwExport()
{
	m_pMgr = NULL;
	m_nFormat = 0;
	m_fp = NULL;
}

void CPwExport::SetManager(CPwManager *pMgr)
{
	ASSERT(pMgr != NULL);
	m_pMgr = pMgr;
}

void CPwExport::SetFormat(int nFormat)
{
	ASSERT((nFormat > PWEXP_NULL) && (nFormat < PWEXP_LAST));
	if((nFormat > PWEXP_NULL) && (nFormat < PWEXP_LAST))
		m_nFormat = nFormat;
}

void CPwExport::SetNewLineSeq(BOOL bWindows)
{
	if(bWindows == TRUE) m_pszNewLine = _T("\r\n");
	else m_pszNewLine = _T("\n");
}

void CPwExport::_ExpStr(LPCTSTR lpString)
{
	if(_tcslen(lpString) != 0)
	{
		UTF8_BYTE *pUtf8String = _StringToUTF8(lpString);

		ASSERT(pUtf8String != NULL);
		if(pUtf8String != NULL)
		{
			fwrite(pUtf8String, 1, strlen((char *)pUtf8String), m_fp);
			SAFE_DELETE_ARRAY(pUtf8String);
		}
	}
}

void CPwExport::_ExpXmlStr(LPCTSTR lpString)
{
	if(_tcslen(lpString) > 0)
	{
		TCHAR *pXmlString = MakeSafeXmlString(lpString);
		
		ASSERT(pXmlString != NULL);
		if(pXmlString != NULL)
		{
			UTF8_BYTE *pUtf8String = _StringToUTF8(pXmlString);
			fwrite(pUtf8String, 1, strlen((char *)pUtf8String), m_fp);
			SAFE_DELETE_ARRAY(pUtf8String);
			SAFE_DELETE_ARRAY(pXmlString);
		}
	}
}

void CPwExport::_ExpHtmlStr(LPCTSTR lpString)
{
	if(lpString[0] == 0) _ExpStr(_T("&nbsp;"));
	else _ExpXmlStr(lpString);
}

void CPwExport::_ExpStrIf(BOOL bCondition, LPCTSTR lpString)
{
	if(bCondition == TRUE)
	{
		if(m_bOneSkipped == TRUE) _ExpStr(m_lpSep);
		else m_bOneSkipped = TRUE;

		if(m_pOptions->bEncodeNewlines == TRUE)
		{
			CString str = lpString;
			str.Replace(_T("\r"), _T("\\r"));
			str.Replace(_T("\n"), _T("\\n"));
			_ExpStr(str);
		}
		else _ExpStr(lpString);
	}
}

void CPwExport::_ExpXmlStrIf(BOOL bCondition, LPCTSTR lpString)
{
	if(bCondition == TRUE)
	{
		if(m_bOneSkipped == TRUE) _ExpStr(m_lpSep);
		else m_bOneSkipped = TRUE;

		if(m_pOptions->bEncodeNewlines == TRUE)
		{
			CString str = lpString;
			str.Replace(_T("\r"), _T("\\r"));
			str.Replace(_T("\n"), _T("\\n"));
			_ExpXmlStr(str);
		}
		else _ExpXmlStr(lpString);
	}
}

void CPwExport::_ExpHtmlStrIf(BOOL bCondition, LPCTSTR lpString)
{
	if(bCondition == TRUE)
	{
		if(m_bOneSkipped == TRUE) _ExpStr(m_lpSep);
		else m_bOneSkipped = TRUE;

		if(m_pOptions->bEncodeNewlines == TRUE)
		{
			CString str = lpString;
			str.Replace(_T("\r"), _T("\\r"));
			str.Replace(_T("\n"), _T("\\n"));
			_ExpHtmlStr(str);
		}
		else _ExpHtmlStr(lpString);
	}
}

void CPwExport::_ExpCsvStrIf(BOOL bCondition, LPCTSTR lpString)
{
	if(bCondition == TRUE)
	{
		if(m_bOneSkipped == TRUE) _ExpStr(m_lpSep);
		else m_bOneSkipped = TRUE;

		CString str = lpString;
		str.Replace(_T("\\"), _T("\\\\"));
		str.Replace(_T("\""), _T("\\\""));

		if(m_pOptions->bEncodeNewlines == TRUE)
		{
			str.Replace(_T("\r"), _T("\\r"));
			str.Replace(_T("\n"), _T("\\n"));
			_ExpStr(str);
		}
		else _ExpStr(str);
	}
}

void CPwExport::_ExpResetSkip()
{
	m_bOneSkipped = FALSE;
}

void CPwExport::_ExpSetSep(LPCTSTR lpSep)
{
	if(lpSep == NULL) m_lpSep = _T("");
	else m_lpSep = lpSep;
}

BOOL CPwExport::ExportAll(const TCHAR *pszFile, const PWEXPORT_OPTIONS *pOptions, CPwManager *pStoreMgr)
{
	ASSERT(pszFile != NULL);
	return ExportGroup(pszFile, DWORD_MAX, pOptions, pStoreMgr);
}

CString CPwExport::MakeGroupTreeString(DWORD dwGroupId) const
{
	PW_GROUP *pg;
	CString str;

	pg = m_pMgr->GetGroupById(dwGroupId);
	ASSERT(pg != NULL); if(pg == NULL) return str;

	const USHORT usLevel = pg->usLevel;
	ASSERT(usLevel != 0xFFFF); if(usLevel == 0xFFFF) return str;
	if(usLevel == 0) return str;
	DWORD *pdwIndices = new DWORD[usLevel + 2];
	ASSERT(pdwIndices != NULL); if(pdwIndices == NULL) return str;

	if(m_pMgr->GetGroupTree(dwGroupId, pdwIndices) == TRUE)
	{
		for(DWORD i = 0; i < (DWORD)usLevel; i++)
		{
			pg = m_pMgr->GetGroup(pdwIndices[i]);

			if(pg != NULL)
			{
				if(i > 0) str += _T("\\");

				CString strTemp = pg->pszGroupName;
				strTemp.Replace(_T("\\"), _T("/"));
				str += strTemp;
			}
		}
	}

	SAFE_DELETE_ARRAY(pdwIndices);
	return str;
}

BOOL CPwExport::ExportGroup(const TCHAR *pszFile, DWORD dwGroupId, const PWEXPORT_OPTIONS *pOptions, CPwManager *pStoreMgr)
{
	FILE *fp = NULL;
	DWORD i, j, dwThisId, dwNumberOfGroups, dwInvalidId1, dwInvalidId2;
	PW_ENTRY *p;
	PW_GROUP *pg;
	BYTE aInitUTF8[3] = { 0xEF, 0xBB, 0xBF };
	CString str, strUUID, strImage, strCreationTime, strLastAccTime, strLastModTime;
	CString strExpireTime, strGroupTree;
	BYTE *pbEncodedAttachment = NULL;
	PW_TIME tNever;
	std::vector<DWORD> aGroupIds;
	USHORT usLevel = 0;
	BOOL bReturn = TRUE;

	ASSERT(m_pMgr != NULL); if(m_pMgr == NULL) return FALSE;
	m_pMgr->GetNeverExpireTime(&tNever);

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

	if(m_nFormat == PWEXP_KEEPASS) { ASSERT(pStoreMgr != NULL); if(pStoreMgr == NULL) return FALSE; }

	if(pOptions == NULL)
	{
		if(m_nFormat == PWEXP_TXT) pOptions = &m_aDefaults[PWEXP_TXT];
		else if(m_nFormat == PWEXP_HTML) pOptions = &m_aDefaults[PWEXP_HTML];
		else if(m_nFormat == PWEXP_XML) pOptions = &m_aDefaults[PWEXP_XML];
		else if(m_nFormat == PWEXP_CSV) pOptions = &m_aDefaults[PWEXP_CSV];
		else if(m_nFormat == PWEXP_KEEPASS) pOptions = &m_aDefaults[PWEXP_KEEPASS];
		else { ASSERT(FALSE); return FALSE; }
	}
	m_pOptions = pOptions;

	dwNumberOfGroups = m_pMgr->GetNumberOfGroups();
	dwInvalidId1 = m_pMgr->GetGroupId(PWS_BACKUPGROUP_SRC);
	dwInvalidId2 = m_pMgr->GetGroupId(PWS_BACKUPGROUP);

	if(dwGroupId != DWORD_MAX)
	{
		i = m_pMgr->GetGroupByIdN(dwGroupId);
		ASSERT(i != DWORD_MAX); if(i == DWORD_MAX) return FALSE;

		usLevel = m_pMgr->GetGroup(i)->usLevel;

		while(1)
		{
			pg = m_pMgr->GetGroup(i);
			ASSERT(pg != NULL); if(pg == NULL) break;

			if((pg->uGroupId != dwGroupId) && (pg->usLevel <= usLevel)) break;

			aGroupIds.push_back(pg->uGroupId);

			i++;
			if(i == dwNumberOfGroups) break;
		}
	}
	else
	{
		for(i = 0; i < dwNumberOfGroups; i++)
		{
			pg = m_pMgr->GetGroup(i);
			ASSERT(pg != NULL); if(pg == NULL) continue;
			aGroupIds.push_back(pg->uGroupId);
		}
	}

	if(m_nFormat != PWEXP_KEEPASS)
	{
		fp = NULL;
		_tfopen_s(&fp, pszFile, _T("wb"));
		if(fp == NULL) { aGroupIds.clear(); return FALSE; }
		m_fp = fp;

		fwrite(aInitUTF8, 1, 3, fp);
	}

	if(m_nFormat == PWEXP_TXT)
	{
	}
	else if(m_nFormat == PWEXP_HTML)
	{
		_ExpStr(_T("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">"));
		_ExpStr(m_pszNewLine);
		_ExpStr(_T("<html><head>"));
		_ExpStr(_T("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">"));
		_ExpStr(_T("<title>"));
		_ExpStr(TRL("Password List"));
		_ExpStr(_T("</title></head><body>"));
		_ExpStr(m_pszNewLine);
		_ExpStr(_T("<h1>"));
		_ExpStr(TRL("Password List"));
		_ExpStr(_T("</h1>"));
		_ExpStr(m_pszNewLine);
		_ExpStr(_T("<table width=\"100%\" border=\"1px\" cellspacing=\"0\" cellpadding=\"1\"><tr><th>"));

		_ExpSetSep(_T("</th><th>"));
		_ExpResetSkip();
		_ExpStrIf(pOptions->bGroup, TRL("Password Groups"));
		_ExpStrIf(pOptions->bGroupTree, TRL("Group Tree"));
		_ExpStrIf(pOptions->bTitle, TRL("Title"));
		_ExpStrIf(pOptions->bUserName, TRL("UserName"));
		_ExpStrIf(pOptions->bURL, TRL("URL"));
		_ExpStrIf(pOptions->bPassword, TRL("Password"));
		_ExpStrIf(pOptions->bNotes, TRL("Notes"));
		_ExpStrIf(pOptions->bUUID, TRL("UUID"));
		_ExpStrIf(pOptions->bImage, TRL("Icon"));
		_ExpStrIf(pOptions->bCreationTime, TRL("Creation Time"));
		_ExpStrIf(pOptions->bLastAccTime, TRL("Last Access"));
		_ExpStrIf(pOptions->bLastModTime, TRL("Last Modification"));
		_ExpStrIf(pOptions->bExpireTime, TRL("Expires"));
		_ExpStrIf(pOptions->bAttachment, TRL("Attachment Description"));
		_ExpStrIf(pOptions->bAttachment, TRL("Attachment"));

		_ExpStr(_T("</th></tr>"));
		_ExpStr(m_pszNewLine);
	}
	else if(m_nFormat == PWEXP_XML)
	{
		_ExpStr(_T("<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>"));
		_ExpStr(m_pszNewLine);
		_ExpStr(_T("<pwlist>"));
		_ExpStr(m_pszNewLine);
	}
	else if(m_nFormat == PWEXP_CSV)

⌨️ 快捷键说明

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