📄 kmshare.c
字号:
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 + -