📄 pgpgroupsutil.c
字号:
/*____________________________________________________________________________
Copyright (C) 2002 PGP Corporation
All rights reserved.
$Id: pgpGroupsUtil.c,v 1.8 2002/08/06 20:11:14 dallen Exp $
____________________________________________________________________________*/
#include <string.h>
#include "pgpMem.h"
#include "pgpSDKPriv.h"
#include "pgpContext.h"
#include "pgpGroups.h"
#include "pgpGroupsPriv.h"
#include "pgpKeys.h"
#include "pgpEncode.h"
#include "pgpPFLPriv.h"
#include "pgpStrings.h"
#include "pgpErrors.h"
#if PGP_MACINTOSH
#include "MacStrings.h"
#endif
/*____________________________________________________________________________
Caller must call PGPFreeKey() on resulting key
____________________________________________________________________________*/
static PGPError
sGroupItemToKey(
PGPGroupItem const * item,
PGPKeyDBRef keyDB,
PGPKeyDBObjRef * outKey )
{
PGPError err = kPGPError_NoErr;
PGPContextRef context;
PGPKeyDBObjRef key = kInvalidPGPKeyDBObjRef;
context = PGPPeekKeyDBContext( keyDB );
/* get the key ID into a PGPsdk form */
err = PGPFindKeyByKeyID( keyDB, &item->u.keyID, &key );
*outKey = key;
pgpAssert( ( IsntPGPError( err ) && IsntNull( *outKey ) ) ||
( IsPGPError( err ) && IsNull( *outKey ) ));
return( err );
}
static PGPValidity
sMinValidity(
PGPValidity validity1,
PGPValidity validity2 )
{
PGPValidity validity;
if ( validity1 == kPGPValidity_Unknown ||
validity2 == kPGPValidity_Unknown )
{
/* lowest we can get */
validity = kPGPValidity_Invalid;
return( validity );
}
/* asserts above guarantee we can use a simple MIN here */
pgpAssert( kPGPValidity_Invalid < kPGPValidity_Marginal );
pgpAssert( kPGPValidity_Marginal < kPGPValidity_Complete );
if ( validity1 < validity2 )
validity = validity1;
else
validity = validity2;
return( validity );
}
/*____________________________________________________________________________
Return the lowest validity of any item in the group
keydb should contain all keys available
It is not an error if keys can't be found; you may want to check
the not found count.
The lowest validity is kPGPValidity_Invalid and kPGPValidity_Unknown
is never returned.
____________________________________________________________________________*/
PGPError
PGPGetGroupLowestValidity(
PGPGroupSetRef set,
PGPGroupID id,
PGPKeyDBRef keyDB,
PGPValidity * lowestValidityOut,
PGPUInt32 * numKeysNotFound )
{
PGPError err = kPGPError_NoErr;
PGPGroupItemIterRef iter;
if ( IsntNull( lowestValidityOut ) )
*lowestValidityOut = kPGPValidity_Invalid;
if ( IsntNull( numKeysNotFound ) )
*numKeysNotFound = 0;
PGPValidatePtr( lowestValidityOut );
PGPValidatePtr( numKeysNotFound );
PGPValidateGroupSet( set );
PGPValidateParam( IsntNull( keyDB ) );
pgpEnterPGPErrorFunction();
err = PGPNewGroupItemIter( set, id,
kPGPGroupIterFlags_Recursive | kPGPGroupIterFlags_Keys,
&iter );
if ( IsntPGPError( err ) )
{
PGPGroupItem item;
PGPContextRef context;
PGPValidity lowestValidity = kPGPValidity_Complete;
PGPBoolean examinedAKey = FALSE;
context = PGPPeekKeyDBContext( keyDB );
/* 'lowestValidity' can only decrease while looping */
while( IsntPGPError( err = PGPGroupItemIterNext( iter, &item ) ) )
{
PGPKeyDBObjRef key;
pgpAssert( item.type == kPGPGroupItem_KeyID );
err = sGroupItemToKey( &item, keyDB, &key );
if ( IsntPGPError( err) )
{
PGPValidity validity;
examinedAKey = TRUE;
err = PGPGetPrimaryUserIDValidity( key, &validity );
lowestValidity = sMinValidity( validity, lowestValidity );
if ( lowestValidity == kPGPValidity_Invalid &&
IsNull( numKeysNotFound ))
{
/* it doesn't get any lower than kPGPValidity_Invalid and
the caller does not want the number of missing keys */
break;
}
}
else
{
if ( err == kPGPError_ItemNotFound )
{
/* just can't find the key; that's OK */
err = kPGPError_NoErr;
*numKeysNotFound += 1;
}
}
if ( IsPGPError( err ) )
break;
}
if ( err == kPGPError_EndOfIteration )
err = kPGPError_NoErr;
/* if we examined keys, use the validity we found, otherwise
consider it invalid */
if ( examinedAKey )
*lowestValidityOut = lowestValidity;
else
*lowestValidityOut = kPGPValidity_Invalid;
PGPFreeGroupItemIter( iter );
}
return( err );
}
/*____________________________________________________________________________
All all the keys in the group (and its subgroups) to the keyset
____________________________________________________________________________*/
PGPError
PGPNewKeySetFromGroup(
PGPGroupSetRef set,
PGPGroupID id,
PGPKeyDBRef keyDB, /* resolve key IDs using this db */
PGPKeySetRef * outKeys,
PGPUInt32 * numKeysNotFound
)
{
PGPError err = kPGPError_NoErr;
PGPGroupItemIterRef iter;
PGPKeySetRef workingSet = kInvalidPGPKeySetRef;
if ( IsntNull( numKeysNotFound ) )
*numKeysNotFound = 0;
if ( IsntNull( outKeys ) )
*outKeys = kInvalidPGPKeySetRef;
PGPValidatePtr( numKeysNotFound );
PGPValidatePtr( outKeys );
PGPValidateGroupSet( set );
PGPValidatePtr( keyDB );
pgpEnterPGPErrorFunction();
err = PGPNewEmptyKeySet( keyDB, &workingSet );
if ( IsntPGPError( err ) )
{
err = PGPNewGroupItemIter( set, id,
kPGPGroupIterFlags_Recursive | kPGPGroupIterFlags_Keys,
&iter );
}
if ( IsntPGPError( err ) )
{
PGPGroupItem item;
while( IsntPGPError( err = PGPGroupItemIterNext( iter, &item ) ) )
{
PGPKeyDBObjRef key;
pgpAssert( item.type == kPGPGroupItem_KeyID );
err = sGroupItemToKey( &item, keyDB, &key );
if ( IsntPGPError( err ) )
{
err = PGPAddKey( key, workingSet );
if ( IsPGPError( err ) )
break;
}
else if ( err == kPGPError_ItemNotFound )
{
*numKeysNotFound += 1;
}
else
{
break;
}
}
if ( err == kPGPError_EndOfIteration )
err = kPGPError_NoErr;
PGPFreeGroupItemIter( iter );
}
if ( IsPGPError( err ) && PGPKeySetRefIsValid( workingSet ) )
{
(void) PGPFreeKeySet( workingSet );
workingSet = kInvalidPGPKeySetRef;
}
*outKeys = workingSet;
return( err );
}
typedef struct
{
PGPKeyDBRef keyDB;
PGPGroupSetRef set;
} MySortInfo;
static PGPInt32
sCompareGroupItems(
PGPGroupItem * item1,
PGPGroupItem * item2,
void * userValue )
{
PGPKeyDBObjRef key1;
PGPKeyDBObjRef key2;
PGPError err1;
PGPError err2;
MySortInfo const * info = (MySortInfo const *)userValue;
PGPKeyDBRef keyDB = info->keyDB;
PGPInt32 result;
pgpAssert( IsntNull( info ) );
if ( item1->type == kPGPGroupItem_Group ||
item2->type == kPGPGroupItem_Group )
{
PGPGroupInfo groupInfo1;
PGPGroupInfo groupInfo2;
/* for now, always make groups come before keys */
if ( item1->type == kPGPGroupItem_Group &&
item2->type == kPGPGroupItem_KeyID )
{
return( -1 );
}
else if ( item1->type == kPGPGroupItem_KeyID &&
item2->type == kPGPGroupItem_Group )
{
return( 1 );
}
/* both are groups */
PGPGetGroupInfo( info->set, item1->u.groupID, &groupInfo1 );
PGPGetGroupInfo( info->set, item2->u.groupID, &groupInfo2 );
return( pgpCompareStringsIgnoreCase( groupInfo1.name,
groupInfo2.name ) );
}
err1 = sGroupItemToKey( item1, keyDB, &key1 );
err2 = sGroupItemToKey( item2, keyDB, &key2 );
/*
Rules:
errors on both: consider the same
error on one: it's always less than
*/
if ( IsPGPError( err1 ) && IsPGPError( err2 ) )
{
/* if we got errors on both, consider them the same */
result = 0;
}
else if ( IsPGPError( err1 ) )
{
result = -1;
}
else if ( IsPGPError( err2 ) )
{
result = 1;
}
else
{
result = PGPCompareKeys( key1, key2, kPGPKeyOrdering_UserID );
}
return( result );
}
PGPError
PGPSortGroupSetStd(
PGPGroupSetRef set,
PGPKeyDBRef keyDB )
{
PGPError err = kPGPError_NoErr;
MySortInfo info;
pgpEnterPGPErrorFunction();
info.set = set;
info.keyDB = keyDB;
err = PGPSortGroupSet( set, sCompareGroupItems, &info );
return( err );
}
PGPError
PGPNewFlattenedGroupFromGroup(
PGPGroupSetRef sourceSet,
PGPGroupID sourceID,
PGPGroupSetRef destSet,
PGPGroupID *destID)
{
PGPError err;
PGPValidatePtr( destID );
*destID = kPGPInvalidGroupID;
PGPValidateGroupSet( sourceSet );
PGPValidateGroupSet( destSet );
PGPValidateParam( sourceSet != destSet );
pgpEnterPGPErrorFunction();
err = PGPNewGroup( destSet, "", "", destID );
if( IsntPGPError( err ) )
{
PGPGroupItemIterRef iterator;
err = PGPNewGroupItemIter( sourceSet, sourceID,
kPGPGroupIterFlags_Recursive | kPGPGroupIterFlags_Keys,
&iterator );
if ( IsntPGPError( err ) )
{
PGPGroupItem item;
err = PGPGroupItemIterNext( iterator, &item );
while( IsntPGPError( err ) )
{
err = PGPAddItemToGroup( destSet, &item, *destID );
if( err == kPGPError_ItemAlreadyExists )
err = kPGPError_NoErr;
if( IsPGPError( err ) )
break;
err = PGPGroupItemIterNext( iterator, &item );
}
if ( err == kPGPError_EndOfIteration )
err = kPGPError_NoErr;
PGPFreeGroupItemIter( iterator );
}
if( IsPGPError( err ) )
{
(void) PGPDeleteGroup( destSet, *destID );
*destID = kPGPInvalidGroupID;
}
}
return( err );
}
/*__Editor_settings____
Local Variables:
tab-width: 4
End:
vi: ts=4 sw=4
vim: si
_____________________*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -