📄 pgprecipientdialogcommon.cpp
字号:
/*____________________________________________________________________________
Copyright (C) 2002 PGP Corporation
All rights reserved.
$Id: pgpRecipientDialogCommon.cpp,v 1.29 2002/11/13 20:59:44 pbj Exp $
____________________________________________________________________________*/
#include <ctype.h>
#include <string.h>
#include "pgpErrors.h"
#include "pgpKeys.h"
#include "pgpKeyServer.h"
#include "pgpMem.h"
#include "pgpPFLPriv.h"
#include "pgpStrings.h"
#include "pgpUtilities.h"
#if PGP_WIN32
#include "pgpUnicode.h"
#include "pgpUnicodeWin32.h"
#endif
#include "pgpDialogs.h"
#include "pgpRecipientDialogCommon.h"
#define UserIsVisible(user) \
( IsntNull( user ) && \
( user->location == kPGPRecipientUserLocation_UserList ) || \
( user->location == kPGPRecipientUserLocation_RecipientList ) )
#define kMandatoryARRMask 0x80
#define IsMandatoryARRClass(x) (((x) & kMandatoryARRMask) != 0)
PGPError
PGPMoveRecipientsARRPrefetch(
void *hwndParent,
PGPRecipientsList *recipients,
PGPUInt32 numUsers,
PGPRecipientUser **userList);
static PGPUInt32
GetNextMarkValue(void)
{
static PGPUInt32 sMarkValue = 0;
return( ++sMarkValue );
}
static const char *
FindSubstring(
const char * inBuffer,
const char * inSearchStr)
{
const char * currBuffPointer = inBuffer;
while (*currBuffPointer != 0)
{
const char * compareOne = currBuffPointer;
const char * compareTwo = inSearchStr;
while ( tolower(*compareOne) == tolower(*compareTwo) )
{
compareOne++;
compareTwo++;
if (*compareTwo == 0)
{
return (char *) currBuffPointer;
}
}
currBuffPointer++;
}
return NULL;
}
static PGPError
AllocateNewUsers(PGPRecipientsList *recipients)
{
PGPError err = kPGPError_NoErr;
PGPRecipientUserList *userList;
userList = (PGPRecipientUserList *) PGPNewData( recipients->memoryMgr,
sizeof( *userList ), 0 );
if( IsntNull( userList ) )
{
PGPUInt32 userIndex;
// Add user list to recipients.
userList->nextUserList = recipients->userLists;
recipients->userLists = userList;
// Thread new users into recipients free list
for( userIndex = 0; userIndex < kPGPNumUserListUsers; userIndex++ )
{
userList->users[userIndex].nextUser = recipients->freeUsers;
recipients->freeUsers = &userList->users[userIndex];
}
}
else
{
err = kPGPError_OutOfMemory;
}
return( err );
}
static PGPError
NewUser(
PGPRecipientsList *recipients,
PGPRecipientUser **newUser)
{
PGPError err = kPGPError_NoErr;
*newUser = NULL;
if( IsNull( recipients->freeUsers ) )
{
err = AllocateNewUsers( recipients );
}
if( IsntPGPError( err ) )
{
pgpAssert( IsntNull( recipients->freeUsers ) );
*newUser = recipients->freeUsers;
recipients->freeUsers = recipients->freeUsers->nextUser;
pgpClearMemory( *newUser, sizeof( **newUser ) );
(**newUser).recipients = recipients;
}
return( err );
}
static PGPError
AllocateNewKeys(PGPRecipientsList *recipients)
{
PGPError err = kPGPError_NoErr;
PGPRecipientKeyList *keyList;
keyList = (PGPRecipientKeyList *) PGPNewData( recipients->memoryMgr,
sizeof( *keyList ), 0 );
if( IsntNull( keyList ) )
{
PGPUInt32 keyIndex;
// Add key list to recipients.
keyList->nextKeyList = recipients->keyLists;
recipients->keyLists = keyList;
// Thread new keys into recipients free list
for( keyIndex = 0; keyIndex < kPGPNumKeyListKeys; keyIndex++ )
{
keyList->keys[keyIndex].nextKey = recipients->freeKeys;
recipients->freeKeys = &keyList->keys[keyIndex];
}
}
else
{
err = kPGPError_OutOfMemory;
}
return( err );
}
static PGPError
NewKey(
PGPRecipientsList *recipients,
PGPRecipientKey **newKey)
{
PGPError err = kPGPError_NoErr;
*newKey = NULL;
if( IsNull( recipients->freeKeys ) )
{
err = AllocateNewKeys( recipients );
}
if( IsntPGPError( err ) )
{
pgpAssert( IsntNull( recipients->freeKeys ) );
*newKey = recipients->freeKeys;
recipients->freeKeys = recipients->freeKeys->nextKey;
pgpClearMemory( *newKey, sizeof( **newKey ) );
}
return( err );
}
static void
FreeKey(PGPRecipientKey *key)
{
pgpAssert( IsntNull( key ) );
if( IsntNull( key->arrKeys ) )
{
PGPFreeData( key->arrKeys );
key->arrKeys = NULL;
}
/* The key is not individually allocated, so no disposal is necessary */
}
static PGPError
RememberName(
PGPRecipientsList *recipients,
const char *name,
PGPUInt32 *nameOffset)
{
PGPError err = kPGPError_NoErr;
PGPUInt32 nameLength;
pgpAssert( IsntNull( recipients) );
pgpAssert( IsntNull( name) );
pgpAssert( IsntNull( nameOffset) );
pgpAssert( recipients->nextNameOffset <= recipients->nameListSize );
*nameOffset = 0;
nameLength = strlen( name ) + 1; /* Account for trailing '\0' */
/* Limit the names to kPGPMaxUserIDSize characters in case
name is corrupted */
if( nameLength > kPGPMaxUserIDSize )
{
nameLength = kPGPMaxUserIDSize;
}
if( nameLength > recipients->nameListSize -
recipients->nextNameOffset )
{
PGPUInt32 newNameListSize;
char *newNameList;
// Need to grow/allocate the names list.
#define kNameListGrowSize 1024L
newNameListSize = recipients->nameListSize + kNameListGrowSize;
newNameList = (char *) PGPNewData( recipients->memoryMgr,
newNameListSize, 0 );
if( IsntNull( newNameList ) )
{
if( IsntNull( recipients->nameList ) )
{
pgpCopyMemory( recipients->nameList, newNameList,
recipients->nameListSize );
PGPFreeData( recipients->nameList );
}
else
{
// Special case. Offset zero is invalid and is an empty string
// Start at offset 1
pgpAssert( recipients->nextNameOffset == 0 );
recipients->nextNameOffset = 1;
newNameList[0] = 0;
}
recipients->nameList = newNameList;
recipients->nameListSize = newNameListSize;
}
else
{
err = kPGPError_OutOfMemory;
}
}
if( IsntPGPError( err ) )
{
pgpAssert( nameLength <= recipients->nameListSize -
recipients->nextNameOffset );
// Copy all but trailing NULL (in case of overflow)
pgpCopyMemory( name, &recipients->nameList[recipients->nextNameOffset],
nameLength-1 );
// Now NULL terminate it
recipients->nameList[recipients->nextNameOffset+nameLength-1]=0;
*nameOffset = recipients->nextNameOffset;
recipients->nextNameOffset += nameLength;
}
return( err );
}
static PGPError
FindARRKeys(
PGPRecipientsList *recipients,
PGPRecipientKey *theKey)
{
PGPError err = kPGPError_NoErr;
if( IsntNull( theKey->arrKeys ) )
{
PGPFreeData( theKey->arrKeys );
theKey->arrKeys = NULL;
theKey->numARRKeys = 0;
theKey->haveMissingARRs = FALSE;
}
if( recipients->arrEnforcement != kPGPARREnforcement_None )
{
PGPUInt32 numARRKeys;
err = PGPCountAdditionalRecipientRequests( theKey->keyRef,
&numARRKeys );
if( IsntPGPError( err ) && numARRKeys != 0)
{
theKey->numARRKeys = (PGPUInt16) numARRKeys;
theKey->arrKeys = (PGPRecipientKeyARRInfo *) PGPNewData(
recipients->memoryMgr,
theKey->numARRKeys *
sizeof( theKey->arrKeys[0] ),
kPGPMemoryMgrFlags_Clear );
if( IsntNull( theKey->arrKeys ) )
{
PGPUInt32 arrIndex;
for( arrIndex = 0; arrIndex < theKey->numARRKeys;
++arrIndex )
{
PGPRecipientKeyARRInfo *arrInfo;
PGPKeyDBObjRef arrKeyRef = kInvalidPGPKeyDBObjRef;
arrInfo = &theKey->arrKeys[arrIndex];
err = PGPGetIndexedAdditionalRecipientRequestKey(
theKey->keyRef, arrIndex,
&arrKeyRef, &arrInfo->keyID,
&arrInfo->arrClass );
if( IsntPGPError( err ) )
{
if( PGPKeyDBObjRefIsValid( arrKeyRef ) )
{
err = PGPGetKeyDBObjUserValue( arrKeyRef,
(PGPUserValue *) &arrInfo->key );
}
if( IsNull( arrInfo->key ) )
{
arrInfo->keyMissing = TRUE;
}
else if( ! arrInfo->key->isVisible )
{
arrInfo->key = NULL;
}
if( IsMandatoryARRClass( arrInfo->arrClass ) &&
IsNull( arrInfo->key ) )
{
theKey->haveMissingARRs = TRUE;
}
}
if( IsPGPError( err ) )
break;
}
}
else
{
err = kPGPError_OutOfMemory;
}
}
}
return( err );
}
static PGPError
UpdateKeyUserIDs(
PGPRecipientsList *recipients,
PGPRecipientKey *theKey,
PGPKeyIterRef iterator,
PGPUInt32 *numAddedUserIDs)
{
PGPKeyDBObjRef curUserID;
PGPError err = kPGPError_NoErr;
PGPBoolean haveExistingUserIDs = IsntNull( theKey->users );
PGPKeyDBObjRef primaryUserID = kInvalidPGPKeyDBObjRef;
PGPUInt32 newNewUserIDs = 0;
(void) PGPKeyIterRewind( iterator, kPGPKeyDBObjType_UserID );
(void) PGPGetPrimaryUserID( theKey->keyRef, &primaryUserID );
err = PGPKeyIterNextKeyDBObj( iterator, kPGPKeyDBObjType_UserID, &curUserID );
while( IsntPGPError( err ) )
{
PGPRecipientUser *user = NULL;
if( haveExistingUserIDs )
{
/* See if we already have the user */
user = theKey->users;
while( IsntNull( user ) )
{
if( user->userInfo.userID == curUserID )
break;
user = user->nextUser;
}
}
if( IsNull( user ) )
{
err = NewUser( recipients, &user );
if( IsntPGPError( err ) )
{
PGPSize bufferSize;
char tempName[ 256 ];
PGPBoolean isAttribute;
user->kind = kPGPRecipientUserKind_Key;
user->userInfo.key = theKey;
user->userInfo.userID = curUserID;
++newNewUserIDs;
if( theKey->canEncrypt )
{
user->location =
kPGPRecipientUserLocation_UserList;
}
else
{
user->location =
kPGPRecipientUserLocation_Hidden;
}
if( curUserID == primaryUserID )
user->userInfo.isPrimaryUser = TRUE;
tempName[0] = 0;
err = PGPGetKeyDBObjBooleanProperty( curUserID,
kPGPUserIDProperty_IsAttribute, &isAttribute );
if( IsntPGPError( err ) )
{
if( isAttribute )
{
user->location = kPGPRecipientUserLocation_Hidden;
}
else
{
err = PGPGetKeyDBObjDataProperty( curUserID,
kPGPUserIDProperty_Name, tempName,
sizeof( tempName ), &bufferSize );
#if PGP_WIN32
/* if userid is pre-8.0, it may contain high-ASCII
chars instead of being UTF8. Here we convert
if necessary */
if( IsntPGPError( err ) )
{
if (pgpIsntUTF8String (tempName, bufferSize))
{
CHAR sz[kPGPMaxUserIDSize];
PGPUInt32 u;
u = bufferSize;
lstrcpyn (sz, tempName, u+1);
err = pgpLocalStringToUTF8 (0,
GetACP(), sz, u, tempName,
sizeof(tempName), &bufferSize);
}
}
#endif PGP_WIN32
if( IsntPGPError( err ) )
{
tempName[bufferSize] = 0;
err = RememberName( recipients, tempName,
&user->nameOffset );
}
}
}
if( IsntPGPError( err ) )
{
// Link the user to the key
user->nextUser = theKey->users;
theKey->users = user;
if( UserIsVisible( user ) )
{
theKey->isVisible = TRUE;
if( user->userInfo.isPrimaryUser )
{
theKey->primaryUser = user;
}
else if( IsNull( theKey->primaryUser ))
{
theKey->primaryUser = user;
}
}
}
}
}
if( IsntPGPError( err ) )
err = PGPKeyIterNextKeyDBObj( iterator, kPGPKeyDBObjType_UserID, &curUserID );
}
if( err == kPGPError_EndOfIteration )
err = kPGPError_NoErr;
if( IsntNull( numAddedUserIDs ) )
*numAddedUserIDs = newNewUserIDs;
return( err );
}
static PGPError
AddKey(
PGPRecipientsList *recipients,
PGPKeyIterRef iterator,
PGPKeyDBObjRef keyRef,
PGPBoolean isDefaultKey,
PGPBoolean markAsNew,
PGPRecipientKey **recipientKey)
{
PGPError err = kPGPError_NoErr;
PGPRecipientKey *theKey;
err = NewKey( recipients, &theKey );
if( IsntPGPError( err ) )
{
theKey->keyRef = keyRef;
theKey->isDefaultKey = isDefaultKey;
theKey->isNewOrChangedKey = markAsNew;
theKey->isVisible = FALSE; /* Assume not visible */
if( recipients->arrEnforcement != kPGPARREnforcement_None )
{
err = FindARRKeys( recipients, theKey );
}
if( IsntPGPError( err ) )
{
PGPInt32 algorithm;
err = PGPGetKeyDBObjNumericProperty( keyRef, kPGPKeyProperty_AlgorithmID, &algorithm );
theKey->algorithm = (PGPPublicKeyAlgorithm)algorithm;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -