⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 kmshare.c

📁 PGP—Pretty Good Privacy
💻 C
📖 第 1 页 / 共 3 页
字号:
	for (iIndex=0; iIndex<iNumItems; iIndex++) {
		lvI.mask = LVIF_PARAM;
		lvI.iItem = iIndex;
		lvI.iSubItem = 0;
		ListView_GetItem (psks->hwndList, &lvI);

		pshs = (PSHAREHOLDERSTRUCT)lvI.lParam;
		KMFreePhrase (pshs->pszPassphrase);

		KMFree (pshs);
	}
}


//	_______________________________________________
//
//  destroy dialog struct and remove from list

static VOID 
sDestroySplitKeyStruct (PSPLITKEYSTRUCT psksToDestroy)
{
	PSPLITKEYSTRUCT* ppsks;

	ppsks = psksToDestroy->pHeadOfList;

	while (*ppsks) {
		if (*ppsks == psksToDestroy) {
			*ppsks = psksToDestroy->next;
			KMFree (psksToDestroy);
			return;
		}
		ppsks = &((*ppsks)->next);
	}
}


//	_______________________________________________
//
//  Compute name of share file

static PGPError
sCreateFilePathFromUserName (
		LPSTR	pszFolder,
		LPSTR	pszUserID,
		UINT	uNumShares,
		LPSTR	pszModifier,
		LPSTR	pszPath, 
		INT		iLen) 
{
	CHAR		sz[kPGPMaxUserIDSize];
	CHAR		szDefName[16];
	CHAR		szDefExt[8];
	CHAR		szShares[16];
	INT			iMinRequiredLen;
	INT			i;

	// prepare number of shares substring
	if (uNumShares == 1) {
		LoadString (g_hInst, IDS_ONESHARE, szShares, sizeof(szShares));
	}
	else {
		LoadString (g_hInst, IDS_NUMSHARES, sz, sizeof(sz));
		wsprintf (szShares, sz, uNumShares);
	}

	// get default file name and extension
	LoadString (g_hInst, IDS_DEFSHARENAME, szDefName, sizeof(szDefName));
	lstrcat (szDefName, pszModifier);
	LoadString (g_hInst, IDS_DEFSHAREEXTENSION, szDefExt, sizeof(szDefExt));

	// check length of destination buffer
	iMinRequiredLen = 
		lstrlen (pszFolder) + lstrlen (szDefExt) + lstrlen (szDefName) +1;
	if (iMinRequiredLen >= iLen) 
		return kPGPError_CantOpenFile;

	// put folder into path
	lstrcpy (pszPath, pszFolder);
	iLen -= lstrlen (pszPath);
	if (pszPath[lstrlen(pszPath)-1] != '\\') {
		lstrcat (pszPath, "\\");
		iLen -= 1;
	}

	// look for invalid characters and truncate
	lstrcpy (sz, pszUserID);
	i = strcspn (sz, "\\/:*?""<>|");
	sz[i] = '\0';

	// remove trailing spaces
	while ((i > 0) && (sz[i-1] == ' ')) {
		i--;
		sz[i] = '\0';
	}

	// check if we've truncated too much
	if (lstrlen (sz) < 2) 
		lstrcpy (sz, szDefName);

	// check if name is too long
	iLen -= (lstrlen (szDefExt) +1);
	if ((lstrlen(sz) + lstrlen(szShares) + lstrlen(pszModifier)) >= iLen) {
		if ((lstrlen (sz) + lstrlen (pszModifier)) >= iLen) {
			if (lstrlen (sz) >= iLen) {
				sz[iLen-1] = '\0';
			}
			lstrcat (pszPath, sz);
			lstrcat (pszPath, ".");
			lstrcat (pszPath, szDefExt);

		}
		else {
			lstrcat (pszPath, sz);
			lstrcat (pszPath, pszModifier);
			lstrcat (pszPath, ".");
			lstrcat (pszPath, szDefExt);
		}
	}
	else {
		// construct full path
		lstrcat (pszPath, sz);
		lstrcat (pszPath, szShares);
		lstrcat (pszPath, pszModifier);
		lstrcat (pszPath, ".");
		lstrcat (pszPath, szDefExt);
	}

	return kPGPError_NoErr;
}


//	_______________________________________________
//
//  split the key 

static PGPError 
sSaveSharesToFile (
		PSHAREHOLDERSTRUCT	pshs, 
		PGPContextRef		context,
		PGPShareRef			sharesTotal,
		PGPKeySetRef		keyset,
		LPSTR				pszFolder)
{
	PFLFileSpecRef		filespec		= NULL;
	PGPShareFileRef		sharefile		= NULL;
	PGPShareRef			sharesHolder	= NULL;
	PGPOptionListRef	encodeOptions	= NULL;
	PGPError			err				= kPGPError_NoErr;
	INT					iModifier		= 0;

	CHAR				szPath[MAX_PATH];
	CHAR				szModifier[MAX_SHARES_LEN+1];
	CHAR				sz1[32];
	CHAR				sz2[kPGPMaxUserIDSize + 32];
	PGPKeyRef			key;

	// create file name and filespec
	err = sCreateFilePathFromUserName (pszFolder, pshs->szUserID, 
						pshs->uShares, NULL, szPath, sizeof(szPath));
	if (IsPGPError (err)) goto SaveFileCleanup;

	// check for pre-existence of file
	while (GetFileAttributes (szPath) != 0xFFFFFFFF) {
		iModifier++;
		if (iModifier > MAX_SHARES) {
			err = kPGPError_CantOpenFile;
			goto SaveFileCleanup;
		}
		wsprintf (szModifier, " %i", iModifier);
		err = sCreateFilePathFromUserName (pszFolder, pshs->szUserID,
						pshs->uShares, szModifier, szPath, sizeof(szPath));
		if (IsPGPError (err)) goto SaveFileCleanup;
	}	

	err = PFLNewFileSpecFromFullPath (PGPGetContextMemoryMgr (context), 
		szPath, &filespec);
	if (IsPGPError (err)) goto SaveFileCleanup;
	
	err = PFLFileSpecCreate (filespec);
	if (IsPGPError (err)) goto SaveFileCleanup;

	err = PGPNewShareFile (filespec, &sharefile);
	if (IsPGPError (err)) goto SaveFileCleanup;

	err = PGPSetShareFileUserID (sharefile, pshs->szUserID);
	if (IsPGPError (err)) goto SaveFileCleanup;

	err = PGPSplitShares (sharesTotal, pshs->uShares, &sharesHolder);
	if (IsPGPError (err)) goto SaveFileCleanup;

	// if this shareholder has public key, use it
	if (pshs->bPublicKey) {
		err = PGPSetShareFileOwnerKeyID (sharefile, pshs->keyid);
		if (IsPGPError (err)) goto SaveFileCleanup;

		err = PGPGetKeyByKeyID (keyset, &(pshs->keyid), pshs->keyalg, &key);
		if (IsPGPError (err)) {
			LoadString (g_hInst, IDS_CAPTIONERROR, sz1, sizeof(sz1));
			LoadString (g_hInst, IDS_SHAREKEYGONE, sz2, sizeof(sz2));
			lstrcat (sz2, pshs->szUserID);
			MessageBox (NULL, sz2, sz1, MB_OK|MB_ICONERROR);
			err = kPGPError_UserAbort;
			goto SaveFileCleanup;
		}

		err = PGPBuildOptionList (context, &encodeOptions,
			PGPOEncryptToKey (context, key),
			PGPOLastOption (context));
		if (IsPGPError (err)) goto SaveFileCleanup;
	}

	// there is no public key for this shareholder
	else {
		err = PGPBuildOptionList (context, &encodeOptions,
			PGPOConventionalEncrypt (context,
				PGPOPassphrase (context, pshs->pszPassphrase),
				PGPOLastOption (context)),
			PGPOLastOption (context));
		if (IsPGPError (err)) goto SaveFileCleanup;
	}

	err = PGPCopySharesToFile (context, sharefile, 
									encodeOptions, sharesHolder);
	if (IsPGPError (err)) goto SaveFileCleanup;

	err = PGPSaveShareFile (sharefile);

SaveFileCleanup:

	if (encodeOptions != NULL)
		PGPFreeOptionList (encodeOptions);

	if (sharesHolder != NULL)
		PGPFreeShares (sharesHolder);

	if (sharefile != NULL)
		PGPFreeShareFile (sharefile);

	if (filespec != NULL)
		PFLFreeFileSpec (filespec);

	return err;
}


//	_______________________________________________
//
//	Split key progress dialog message procedure

static BOOL CALLBACK 
sSplitKeyProgressDlgProc (HWND hDlg, 
					   UINT uMsg, 
					   WPARAM wParam, 
					   LPARAM lParam) 
{
	SPLITKEYPROGRESSSTRUCT*	pskps;

	switch (uMsg) {

	case WM_INITDIALOG :
		// save address of struct
		SetWindowLong (hDlg, GWL_USERDATA, lParam);
		pskps = (SPLITKEYPROGRESSSTRUCT*)lParam;
		SendDlgItemMessage (hDlg, IDC_PROGRESSBAR, PBM_SETRANGE,
							0, MAKELPARAM(0, pskps->iNumSteps));
		SendDlgItemMessage (hDlg, IDC_PROGRESSBAR, PBM_SETPOS,
							0, 0);
		return TRUE;

	case WM_APP :
		SendDlgItemMessage (hDlg, IDC_PROGRESSBAR, PBM_SETPOS,
							wParam, 0);
		SetDlgItemText (hDlg, IDC_PROGRESSTEXT, (LPSTR)lParam);
		break;

	}
	return FALSE;
}


//	___________________________________________________
//
//  Change passphrase of key and all subkeys

static PGPError 
sChangeKeyPhrase (
		PGPContextRef	context,
		PGPKeySetRef	keyset,
		PGPKeyRef		key, 
		LPSTR			szOld, 
		PGPByte*		pPasskeyOld,
		PGPSize			sizePasskeyOld,
		PGPByte*		pPasskey,
		PGPSize			sizePasskey) 
{
	UINT			u;
	PGPKeyListRef	keylist;
	PGPKeyIterRef	keyiter;
	PGPSubKeyRef	subkey;
	PGPError		err;

	if (szOld) {
		err = PGPChangePassphrase (key, 
				PGPOPassphrase (context, szOld), 
				PGPOPasskeyBuffer (context, pPasskey, sizePasskey),
				PGPOLastOption (context));
	}
	else if (sizePasskeyOld > 0) {
		err = PGPChangePassphrase (key, 
				PGPOPasskeyBuffer (context, pPasskeyOld, sizePasskeyOld), 
				PGPOPasskeyBuffer (context, pPasskey, sizePasskey),
				PGPOLastOption (context));
	}
	else {
		err = PGPChangePassphrase (key, 
				PGPOPassphrase (context, ""), 
				PGPOPasskeyBuffer (context, pPasskey, sizePasskey),
				PGPOLastOption (context));
	}
	if (IsPGPError (err)) return err;

	PGPGetKeyNumber (key, kPGPKeyPropAlgID, &u);
	switch (u) {
	case kPGPPublicKeyAlgorithm_RSA :
		break;

	case kPGPPublicKeyAlgorithm_DSA :
		PGPOrderKeySet (keyset, kPGPAnyOrdering, &keylist);
		PGPNewKeyIter (keylist, &keyiter);
		PGPKeyIterSeek (keyiter, key);
		PGPKeyIterNextSubKey (keyiter, &subkey);
		while (subkey) {
			if (szOld) {
				err = PGPChangeSubKeyPassphrase (subkey, 
						PGPOPassphrase (context, szOld),
						PGPOPasskeyBuffer (context, pPasskey, sizePasskey),
						PGPOLastOption (context));
			}
			else if (sizePasskeyOld > 0) {
				err = PGPChangeSubKeyPassphrase (subkey, 
						PGPOPasskeyBuffer (context, 
											pPasskeyOld, sizePasskeyOld),
						PGPOPasskeyBuffer (context, pPasskey, sizePasskey),
						PGPOLastOption (context));
			}
			else {
				err = PGPChangeSubKeyPassphrase (subkey, 
						PGPOPassphrase (context, ""),
						PGPOPasskeyBuffer (context, pPasskey, sizePasskey),
						PGPOLastOption (context));
			}
			PGPKeyIterNextSubKey (keyiter, &subkey);
		}
		PGPFreeKeyIter (keyiter);
		PGPFreeKeyList (keylist);
		break;

	default :
		break;
	}

	return err;
}

//	_______________________________________________
//
//  split the key 

static BOOL 
sSplitKey (PSPLITKEYSTRUCT psks)
{
	PGPShareRef			shares				= NULL;
	PGPSize				sizePasskey			= 0;
	PGPByte*			pPasskey			= NULL;
	LPSTR				pszPhraseKeyToSplit	= NULL;
	PGPByte*			pPasskeyToSplit		= NULL;
	PGPSize				sizePasskeyToSplit	= 0;
	CHAR				szEmptyString[]		= {""};
	HWND				hwndProgress		= NULL;
	BOOL				bRetVal				= TRUE;

	PGPError				err;
	PGPKeyRef				keyToSplit;
	BROWSEINFO				bi;
	LPITEMIDLIST			pidl;
	LPMALLOC				pMalloc;
	CHAR					szFolder[MAX_PATH];
	CHAR					sz[kPGPMaxUserIDSize + 32];
	INT						iItem;
	INT						iNumItems;
	LV_ITEM					lvI;
	PSHAREHOLDERSTRUCT		pshs;
	HCURSOR					hcursorOld;
	SPLITKEYPROGRESSSTRUCT	skps;

	// get keyref from keyring
	err = PGPGetKeyByKeyID (psks->pKM->KeySetMain, &(psks->keyidToSplit),
							psks->keyalgToSplit, &keyToSplit);
	if (IsPGPError (err)) {
		KMMessageBox (psks->hwndDlg, IDS_CAPTIONERROR, IDS_SPLITKEYGONE, 
						MB_OK|MB_ICONERROR);
		bRetVal = FALSE;
		goto SplitKeyCleanup;
	}

	// get task allocator
	if (SHGetMalloc(&pMalloc) != NOERROR) return FALSE;

	// get prompt string
	LoadString (g_hInst, IDS_SAVESHARES, sz, sizeof(sz));

	// initialize structure
	bi.hwndOwner = psks->hwndDlg;
	bi.pidlRoot = NULL;
	bi.pszDisplayName = szFolder;
	bi.lpszTitle = sz;
	bi.ulFlags = BIF_RETURNONLYFSDIRS;
	bi.lpfn = NULL;
	bi.lParam = 0;

	// allow user to browse
	pidl = SHBrowseForFolder (&bi);
	if (pidl == NULL) return FALSE;
	SHGetPathFromIDList (pidl, szFolder);
	pMalloc->lpVtbl->Free(pMalloc, pidl);

	// get passphrase of key to split
	LoadString (g_hInst, IDS_SPLITKEYPHRASEPROMPT, sz, sizeof(sz));
	err = KMGetKeyPhrase (psks->pKM->Context, psks->pKM->tlsContext,
			psks->hwndDlg, sz, 
			psks->pKM->KeySetMain, keyToSplit,
			&pszPhraseKeyToSplit, &pPasskeyToSplit, 
			&sizePasskeyToSplit);
	PGPclErrorBox (NULL, err);

	if (IsPGPError (err)) {
		bRetVal = FALSE;
		goto SplitKeyCleanup;
	}

	// make sure that this is what user wants to do
	if (KMMessageBox (psks->hwndDlg, IDS_CAPTION, IDS_SPLITKEYCONFIRMATION,
						MB_YESNO|MB_ICONEXCLAMATION) == IDNO) {
		bRetVal = FALSE;
		goto SplitKeyCleanup;
	}

	// post progress dialog
	iNumItems = ListView_GetItemCount (psks->hwndList);
	skps.iNumSteps = iNumItems +2;

⌨️ 快捷键说明

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