📄 pksplit.c
字号:
// Compute name of share file
static PGPError
sCreateFilePathFromUserName (
LPSTR pszFolder,
LPSTR pszOldUserID,
UINT uUserNumber,
UINT uNumShares,
LPSTR pszModifier,
LPSTR pszPath,
INT iLen)
{
CHAR sz[kPGPMaxUserIDSize];
CHAR szDefName[16];
CHAR szDefExt[8];
CHAR szShares[16];
INT iMinRequiredLen;
INT i;
CHAR pszUserID[kPGPMaxUserIDSize];
INT userLen;
pgpUTF8StringToLocal (
0, 0, pszOldUserID, strlen(pszOldUserID),
pszUserID,
kPGPMaxUserIDSize, &userLen);
// 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));
wsprintf (sz, " #%i", uUserNumber);
lstrcat (szDefName, sz);
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,
UINT uUserNumber,
PGPShareRef sharesTotal,
PGPKeyDBRef keydb,
LPSTR pszFolder)
{
PFLFileSpecRef filespec = NULL;
PGPShareFileRef sharefile = NULL;
PGPShareRef sharesHolder = NULL;
PGPOptionListRef encodeOptions = NULL;
PGPError err = kPGPError_NoErr;
INT iModifier = 1;
CHAR szPath[MAX_PATH];
CHAR szModifier[16];
CHAR sz1[32];
CHAR sz2[kPGPMaxUserIDSize + 32];
PGPKeyDBObjRef key;
// create file name and filespec
err = sCreateFilePathFromUserName (pszFolder, pshs->szUserID,
uUserNumber, pshs->uShares, "", szPath, sizeof(szPath));
if (IsPGPError (err)) goto SaveFileCleanup;
// check for pre-existence of file
while (GetFileAttributes (szPath) != 0xFFFFFFFF)
{
iModifier++;
if (iModifier > MAX_MODIFIERS)
{
err = kPGPError_CantOpenFile;
goto SaveFileCleanup;
}
wsprintf (szModifier, " (%i)", iModifier);
err = sCreateFilePathFromUserName (pszFolder, pshs->szUserID,
uUserNumber, pshs->uShares,
szModifier, szPath, sizeof(szPath));
if (IsPGPError (err))
goto SaveFileCleanup;
}
err = PFLNewFileSpecFromFullPath (
PGPPeekContextMemoryMgr (g_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 = PGPFindKeyByKeyID (keydb, &(pshs->keyid), &key);
if (IsPGPError (err))
{
LoadString (g_hinst, IDS_CAPTIONALERT, sz1, sizeof(sz1));
LoadString (g_hinst, IDS_SHAREKEYGONE, sz2, sizeof(sz2));
lstrcat (sz2, pshs->szUserID);
PGPclMessageBoxUTF8 (NULL, sz2, sz1,
MB_OK|MB_ICONEXCLAMATION|MB_TOPMOST);
err = kPGPError_UserAbort;
goto SaveFileCleanup;
}
err = PGPBuildOptionList (g_context, &encodeOptions,
PGPOEncryptToKeyDBObj (g_context, key),
PGPOLastOption (g_context));
if (IsPGPError (err))
goto SaveFileCleanup;
}
// there is no public key for this shareholder
else
{
err = PGPBuildOptionList (g_context, &encodeOptions,
PGPOConventionalEncrypt (g_context,
PGPOPassphrase (g_context, pshs->pszPassphrase),
PGPOLastOption (g_context)),
PGPOLastOption (g_context));
if (IsPGPError (err))
goto SaveFileCleanup;
}
err = PGPCopySharesToFile (g_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 hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
SPLITKEYPROGRESSSTRUCT* pskps;
switch (uMsg) {
case WM_INITDIALOG :
// save address of struct
SetWindowLong (hwnd, GWL_USERDATA, lParam);
pskps = (SPLITKEYPROGRESSSTRUCT*)lParam;
UTF8EditInit (GetDlgItem (hwnd, IDC_PROGRESSTEXT));
SendDlgItemMessage (hwnd, IDC_PROGRESSBAR,
PBM_SETRANGE, 0, MAKELPARAM(0, pskps->iNumSteps));
SendDlgItemMessage (hwnd, IDC_PROGRESSBAR,
PBM_SETPOS, 0, 0);
return TRUE;
case WM_DESTROY :
UTF8EditDestroy (GetDlgItem (hwnd, IDC_PROGRESSTEXT));
return FALSE;
case WM_APP :
SendDlgItemMessage (hwnd, IDC_PROGRESSBAR,
PBM_SETPOS, wParam, 0);
UTF8EditSetText (GetDlgItem (hwnd, IDC_PROGRESSTEXT), (LPSTR)lParam);
break;
}
return FALSE;
}
// ___________________________________________________
//
// Change passphrase of key and all subkeys
static PGPError
sChangeKeyPhrase (
PGPKeyDBObjRef key,
LPSTR szOld,
PGPByte* pPasskeyOld,
PGPSize sizePasskeyOld,
PGPByte* pPasskey,
PGPSize sizePasskey)
{
PGPKeyIterRef keyiter;
PGPKeyDBObjRef subkey;
PGPError err;
if (szOld)
{
err = PGPChangePassphrase (key,
PGPOPassphrase (g_context, szOld),
PGPOPasskeyBuffer (g_context, pPasskey, sizePasskey),
PGPOLastOption (g_context));
}
else if (sizePasskeyOld > 0)
{
err = PGPChangePassphrase (key,
PGPOPasskeyBuffer (g_context, pPasskeyOld, sizePasskeyOld),
PGPOPasskeyBuffer (g_context, pPasskey, sizePasskey),
PGPOLastOption (g_context));
}
else
{
err = PGPChangePassphrase (key,
PGPOPassphrase (g_context, ""),
PGPOPasskeyBuffer (g_context, pPasskey, sizePasskey),
PGPOLastOption (g_context));
}
if (IsPGPError (err))
return err;
PGPNewKeyIterFromKeyDB (PGPPeekKeyDBObjKeyDB (key), &keyiter);
PGPKeyIterSeek (keyiter, key);
PGPKeyIterNextKeyDBObj (keyiter, kPGPKeyDBObjType_SubKey, &subkey);
while (subkey)
{
if (szOld)
{
err = PGPChangePassphrase (subkey,
PGPOPassphrase (g_context, szOld),
PGPOPasskeyBuffer (g_context, pPasskey, sizePasskey),
PGPOLastOption (g_context));
}
else if (sizePasskeyOld > 0)
{
err = PGPChangePassphrase (subkey,
PGPOPasskeyBuffer (g_context,
pPasskeyOld, sizePasskeyOld),
PGPOPasskeyBuffer (g_context, pPasskey, sizePasskey),
PGPOLastOption (g_context));
}
else
{
err = PGPChangePassphrase (subkey,
PGPOPassphrase (g_context, ""),
PGPOPasskeyBuffer (g_context, pPasskey, sizePasskey),
PGPOLastOption (g_context));
}
PGPKeyIterNextKeyDBObj (keyiter, kPGPKeyDBObjType_SubKey, &subkey);
}
PGPFreeKeyIter (keyiter);
return err;
}
// _______________________________________________
//
// browse folder callback function used to set initial folder location
static INT CALLBACK
sBrowseCallbackProc (
HWND hwnd,
UINT uMsg,
LPARAM lParam,
LPARAM lpData)
{
if (uMsg == BFFM_INITIALIZED)
{
CHAR sz[MAX_PATH];
UINT ulen;
PGPclGetPath (kPGPclDefaultSaveAsFolder, sz, sizeof(sz));
ulen = lstrlen (sz);
if (sz[ulen-1] == '\\')
sz[ulen-1] = '\0';
SendMessage (hwnd, BFFM_SETSELECTION, TRUE, (LPARAM)sz);
}
return 0;
}
// _______________________________________________
//
// 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;
PGPKeyDBObjRef 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 = PGPFindKeyByKeyID (psks->ppks->keydbMain,
&(psks->keyidToSplit), &keyToSplit);
if (IsPGPError (err))
{
PKMessageBox (psks->hwndDlg, IDS_CAPTIONALERT,
IDS_SPLITKEYGONE, MB_OK|MB_ICONEXCLAMATION);
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 = sBrowseCallbackProc;
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 = PGPclGetKeyPhrase (g_context, g_tlscontext,
psks->hwndDlg, sz, psks->ppks->keydbMain, keyToSplit,
&pszPhraseKeyToSplit, &pPasskeyToSplit, &sizePasskeyToSplit);
PGPclErrorBox (NULL, err);
if (IsPGPError (err))
{
bRetVal = FALSE;
goto SplitKeyCleanup;
}
// Pre-7.0 versions of PGP set the locking algorithm incorrectly
// at keygen time. The following hack of changing the passphrase to
// itself will relock the key with the correct algorithm, thus
// preventing problems when we actually split the key.
// If PGPclGetKeyPhrase returned a passkey then the key has already
// been split and the user may already be screwed -- nothing we
// can do about that now.
if (pszPhraseKeyToSplit)
{
err = PGPChangePassphrase (keyToSplit,
PGPOPassphrase (g_context, pszPhraseKeyToSplit),
PGPOPassphrase (g_context, pszPhraseKeyToSplit),
PGPOLastOption (g_context));
if (IsPGPError (err))
{
bRetVal = FALSE;
goto SplitKeyCleanup;
}
}
// make sure that this is what user wants to do
if (PKMessageBox (psks->hwndDlg, IDS_CAPTIONWARNING,
IDS_SPLITKEYCONFIRMATION, MB_YESNO|MB_ICONEXCLAMATION) == IDNO)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -