📄 pgpkeyfilter.c
字号:
value = (PGPByte *)pgpContextMemAlloc( context, len, 0);
if( IsntNull( value ) )
{
pgpCopyMemory (val, value, len);
newFilter->value.propbuffer.prop = prop;
newFilter->value.propbuffer.val = value;
newFilter->value.propbuffer.len = len;
}
else
{
PGPFreeFilter( newFilter );
newFilter = NULL;
err = kPGPError_OutOfMemory;
}
}
*outFilter = newFilter;
pgpAssertErrWithPtr( err, *outFilter );
return err;
}
#if NOT_YET /* [ */
/*
* Create a filtered KeySet based on the same KeyDB as the specified
* original. The original must be unfiltered. The filtering type
* is chosen automatically based on the string.
*
* Currently, a "0x" prefix looks up by keyID, otherwise
* by userid name substring matching.
*/
PGPError
PGPNewKeyFilterFromStringQuery(
PGPContextRef context,
char const * query,
PGPFilterRef * outFilter)
{
PGPError err = kPGPError_NoErr;
PGPFilterRef filter = kInvalidPGPKeySetRef;
PGPValidatePtr( outFilter );
PGPValidatePtr( query );
*outFilter = NULL;
PGPValidateContext( context );
not yet
if (query[0] == '0' && query[1] == 'x')
{
PGPKeyIDRef keyID;
err = PGPNewKeyIDFromString( context, query, &keyID );
if ( IsntPGPError( err ) )
{
err = PGPNewKeyIDFilter( context, keyID, &filter );
PGPFreeKeyID( keyID );
}
}
else
{
err = PGPNewUserIDStringFilter( context, query,
kPGPMatchCriterion_SubString,
&filter );
}
*outFilter = filter;
pgpAssertErrWithPtr( err, *outFilter );
return err;
}
#endif /* ] NOT_YET */
static PGPBoolean
sComparisonMatchesCriterion(
long comparison,
PGPMatchCriterion criterion )
{
switch (criterion)
{
case kPGPMatchCriterion_LessOrEqual:
return comparison <= 0;
case kPGPMatchCriterion_GreaterOrEqual:
return comparison >= 0;
case kPGPMatchCriterion_Equal:
return comparison == 0;
default:
pgpAssert(0);
break;
}
return FALSE;
}
static PGPBoolean
sFilterUserID(
PGPFilterRef filter,
PGPKeyDBObj *userid,
char const * string,
PGPSize stringLength)
{
PGPBoolean result = FALSE;
char const * nameStr;
PGPSize nameLength;
char const * p;
nameStr = pgpUserIDName(userid, &nameLength);
switch (filter->filterType)
{
case kPGPFilterTypeUserIDEmail:
p = (char *)memchr(nameStr, '<', nameLength);
if (p == NULL)
{
nameLength = 0;
break;
}
p++;
nameLength -= (p - nameStr);
nameStr = p;
p = (char *)memchr(nameStr, '>', nameLength);
if (p != NULL)
nameLength = p - nameStr;
break;
case kPGPFilterTypeUserIDName:
p = (char *)memchr(nameStr, '<', nameLength);
if (p == NULL)
break;
while (p > nameStr && p[-1] == ' ')
p--;
nameLength = p - nameStr;
break;
case kPGPFilterTypeUserIDString:
break;
default:
/* This should never happen */
pgpAssert(0);
break;
}
if (filter->match == kPGPMatchCriterion_Equal)
{
if (nameLength == stringLength &&
xmemimem(nameStr, nameLength,
string, stringLength) != NULL)
{
result = TRUE;
}
}
else if (filter->match == kPGPMatchCriterion_SubString)
{
if (xmemimem(nameStr, nameLength,
string, stringLength))
{
result = TRUE;
}
}
return result;
}
/* Find the object or a parent of the specified type, or return NULL */
static PGPKeyDBObj *
sFindParent( PGPKeyDBObj *obj, PGPUInt32 type )
{
PGPUInt32 objtype;
pgpAssert( type != RINGTYPE_KEY );
while( (objtype = pgpObjectType( obj )) != type )
{
if( objtype == RINGTYPE_KEY )
return NULL;
obj = obj->up;
}
return obj;
}
/* Compare the time from the key object to the time from the filter */
static PGPBoolean
sCompareTime(
PGPFilterRef filter,
PGPTime keyTime)
{
PGPBoolean result = FALSE;
PGPTime filterTime = filter->value.proptime.val;
if (keyTime == filterTime)
result = TRUE; /* All match criteria include equality */
else if (filter->match == kPGPMatchCriterion_Equal)
result = FALSE;
else
{
/*
* Now we know that the two times are unequal,
* and the match criterion is either <= or >=.
* So we'll just evaluate <=, and then invert
* the result if the criterion was >=.
*/
result = (keyTime <= filterTime);
if( filter->filterType == kPGPFilterTypeKeyTime &&
(filter->value.proptime.prop == kPGPKeyProperty_Expiration ||
filter->value.proptime.prop == kPGPSubKeyProperty_Expiration ) )
{
if (filterTime == kPGPExpirationTime_Never)
result = TRUE;
else if (keyTime == kPGPExpirationTime_Never)
result = FALSE;
}
if (filter->match == kPGPMatchCriterion_GreaterOrEqual)
{
result = !result;
}
else
{
pgpAssert(filter->match == kPGPMatchCriterion_LessOrEqual);
}
}
return result;
}
/* Comparison structure for string buffers - must be equal or substring */
static PGPBoolean
sCompareString(
PGPFilterRef filter,
void *bufval,
PGPSize buflen)
{
PGPBoolean result;
if( filter->value.propbuffer.prop == kPGPKeyProperty_KeyID ||
filter->value.propbuffer.prop == kPGPSubKeyProperty_KeyID ||
filter->value.propbuffer.prop == kPGPSigProperty_KeyID )
{
pgpAssert( filter->match == kPGPMatchCriterion_Equal );
result = pgpKeyIDsEqual( filter->value.propbuffer.val, bufval );
}
else
{
if (filter->match == kPGPMatchCriterion_Equal)
{
result = (buflen == filter->value.propbuffer.len) &&
pgpMemoryEqual( bufval, filter->value.propbuffer.val,
buflen );
}
else
{
pgpAssert (filter->match == kPGPMatchCriterion_SubString);
result = (NULL != xmemimem( bufval, buflen,
filter->value.propbuffer.val,
filter->value.propbuffer.len ) );
}
}
return result;
}
PGPBoolean
pgpKeyDBObjMatchesFilter(
PGPFilterRef filter,
PGPKeyDBObjRef obj)
{
PGPBoolean boolval;
PGPUInt32 numval;
PGPTime timeval;
PGPByte *bufval;
PGPSize buflen;
PGPBoolean result = FALSE;
PGPKeyDBObj *userid;
PGPKeyDBObj *sig;
PGPKeyDBObj *subkey;
PGPKeyDBObj *key;
PGPByte pkAlg;
PGPKeyID keyID;
PGPInt32 comparison;
PGPError err = kPGPError_NoErr;
if ( ! PGPFilterIsValid( filter ) )
return( FALSE );
/* key object will be top level key (possibly same as obj) */
for( key = obj; pgpObjectType(key) != RINGTYPE_KEY; key = key->up )
;
/* Shortcut to detect child validity if we've checked parent key */
if( pgpObjectType( obj ) != RINGTYPE_KEY
&& IsntNull( filter->cachedKeyQuery ) )
{
if( key == filter->cachedKeyQuery )
{
if( !filter->filterChildren )
return filter->cachedResult;
if( !filter->cachedResult )
return FALSE;
/* Continue on if we're filtering children and parent key was OK */
}
}
switch(filter->filterType)
{
/* Key property filters */
case kPGPFilterTypeKeyBoolean:
err = pgpGetKeyBoolean (key,
(PGPKeyDBObjProperty)filter->value.propbool.prop,
&boolval);
if( IsntPGPError( err ) )
result = sCompareBoolean( filter, boolval );
break;
case kPGPFilterTypeKeyNumber:
err = pgpGetKeyNumber (key,
(PGPKeyDBObjProperty)filter->value.propnum.prop,
(PGPInt32 *)&numval);
if( IsntPGPError( err ) )
result = sCompareNumber( filter, numval );
break;
case kPGPFilterTypeKeyTime:
err = pgpGetKeyTime (key,
(PGPKeyDBObjProperty)filter->value.proptime.prop,
&timeval);
if( IsntPGPError( err ) )
result = sCompareTime( filter, timeval );
break;
case kPGPFilterTypeKeyBuffer:
err = pgpGetKeyAllocatedPropertyBuffer( key,
(PGPKeyDBObjProperty)filter->value.propbuffer.prop,
&bufval, &buflen );
if( IsPGPError( err ) )
break;
result = sCompareString( filter, bufval, buflen );
PGPFreeData( bufval );
break;
case kPGPFilterTypeSubKeyBoolean:
if( filter->filterChildren
&& IsntNull( subkey = sFindParent( obj, RINGTYPE_SUBKEY ) ) )
{
err = pgpGetSubKeyBoolean (subkey,
(PGPKeyDBObjProperty)filter->value.propbool.prop,
&boolval);
if( IsntPGPError( err ) )
result = sCompareBoolean( filter, boolval );
} else for (subkey = key->down; !result && IsntNull( subkey );
subkey = subkey->next)
{
if (!pgpKeyDBObjIsReal( subkey ) )
continue;
if( pgpObjectType( subkey ) != RINGTYPE_SUBKEY )
continue;
err = pgpGetSubKeyBoolean (subkey,
(PGPKeyDBObjProperty)filter->value.propbool.prop,
&boolval);
if( IsntPGPError( err ) )
result = sCompareBoolean( filter, boolval );
}
break;
case kPGPFilterTypeSubKeyNumber:
if( filter->filterChildren
&& IsntNull( subkey = sFindParent( obj, RINGTYPE_SUBKEY ) ) )
{
err = pgpGetSubKeyNumber (subkey,
(PGPKeyDBObjProperty)filter->value.propnum.prop,
(PGPInt32 *)&numval);
if( IsntPGPError( err ) )
result = sCompareNumber( filter, numval );
} else for (subkey = key->down; !result && IsntNull(subkey);
subkey = subkey->next)
{
if (!pgpKeyDBObjIsReal( subkey ) )
continue;
if( pgpObjectType( subkey ) != RINGTYPE_SUBKEY )
continue;
err = pgpGetSubKeyNumber (subkey,
(PGPKeyDBObjProperty)filter->value.propnum.prop,
(PGPInt32 *)&numval);
if( IsntPGPError( err ) )
result = sCompareNumber( filter, numval );
}
break;
case kPGPFilterTypeSubKeyTime:
if( filter->filterChildren
&& IsntNull( subkey = sFindParent( obj, RINGTYPE_SUBKEY ) ) )
{
err = pgpGetSubKeyTime (subkey,
(PGPKeyDBObjProperty)filter->value.proptime.prop,
&timeval);
if( IsntPGPError( err ) )
result = sCompareTime( filter, timeval );
} else for (subkey = key->down; !result && IsntNull(subkey);
subkey = subkey->next)
{
if (!pgpKeyDBObjIsReal( subkey ) )
continue;
if( pgpObjectType( subkey ) != RINGTYPE_SUBKEY )
continue;
err = pgpGetSubKeyTime (subkey,
(PGPKeyDBObjProperty)filter->value.proptime.prop,
&timeval);
if( IsntPGPError( err ) )
result = sCompareTime( filter, timeval );
}
break;
case kPGPFilterTypeSubKeyBuffer:
if( filter->filterChildren
&& IsntNull( subkey = sFindParent( obj, RINGTYPE_SUBKEY ) ) )
{
err = pgpGetSubKeyAllocatedPropertyBuffer( subkey,
(PGPKeyDBObjProperty)filter->value.propbuffer.prop,
&bufval, &buflen );
if( IsPGPError( err ) )
return FALSE;
result = sCompareString( filter, bufval, buflen );
PGPFreeData( bufval );
} else for (subkey = key->down; !result && IsntNull(subkey);
subkey = subkey->next)
{
if (!pgpKeyDBObjIsReal( subkey ) )
continue;
if( pgpObjectType( subkey ) != RINGTYPE_SUBKEY )
continue;
err = pgpGetSubKeyAllocatedPropertyBuffer( subkey,
(PGPKeyDBObjProperty)filter->value.propbuffer.prop,
&bufval, &buflen );
if( IsPGPError( err ) )
continue;
result = sCompareString( filter, bufval, buflen );
PGPFreeData( bufval );
}
break;
case kPGPFilterTypeUserIDBoolean:
if( filter->filterChildren
&& IsntNull( userid = sFindParent( obj, RINGTYPE_USERID ) ) )
{
err = pgpGetUserIDBoolean (userid,
(PGPKeyDBObjProperty)filter->value.propbool.prop,
&boolval);
if( IsntPGPError( err ) )
result = sCompareBoolean( filter, boolval );
} else for (userid = key->down; !result && IsntNull(userid);
userid = userid->next)
{
if (!pgpKeyDBObjIsReal( userid) )
continue;
if( pgpObjectType( userid ) != RINGTYPE_USERID )
continue;
err = pgpGetUserIDBoolean (userid,
(PGPKeyDBObjProperty)filter->value.propbool.prop,
&boolval);
if( IsntPGPError( err ) )
result = sCompareBoolean( filter, boolval );
}
break;
case kPGPFilterTypeUserIDNumber:
if( filter->filterChildren
&& IsntNull( userid = sFindParent( obj, RINGTYPE_USERID ) ) )
{
err = pgpGetUserIDNumber (userid,
(PGPKeyDBObjProperty)filter->value.propnum.prop,
(PGPInt32 *)&numval);
if( IsntPGPError( err ) )
result = sCompareNumber( filter, numval );
} else for (userid = key->down; !result && IsntNull(userid);
userid = userid->next)
{
if (!pgpKeyDBObjIsReal( userid) )
continue;
if( pgpObjectType( userid ) != RINGTYPE_USERID )
continue;
err = pgpGetUserIDNumber (userid,
(PGPKeyDBObjProperty)filter->value.propnum.prop,
(PGPInt32 *)&numval);
if( IsntPGPError( err ) )
result = sCompareNumber( filter, numval );
}
break;
#if 0
/* Support this when we add a userid time prop function */
case kPGPFilterTypeUserIDTime:
if( filter->filterChildren
&& IsntNull( userid = sFindParent( obj, RINGTYPE_USERID ) ) )
{
err = PGPGetUserIDTime (userid, filter->value.proptime.prop,
&timeval);
if( IsntPGPError( err ) )
result = sCompareTime( filter, timeval );
} else for (userid = key->down; !result && IsntNull(userid);
userid = userid->next)
{
if (!pgpKeyDBObjIsReal( userid) )
continue;
if( pgpObjectType( userid ) != RINGTYPE_USERID )
continue;
err = PGPGetUserIDTime (userid, filter->value.proptime.prop,
&timeval);
if( IsntPGPError( err ) )
result = sCompareTime( filter, timeval );
}
break;
#endif
case kPGPFilterTypeUserIDBuffer:
if( filter->filterChildren
&& IsntNull( userid = sFindParent( obj, RINGTYPE_USERID ) ) )
{
err = pgpGetUserIDAllocatedStringBuffer( userid,
(PGPKeyDBObjProperty)filter->value.propbuffer.prop,
&bufval, &buflen );
if( IsPGPError( err ) )
break;
result = sCompareString( filter, bufval, buflen );
PGPFreeData( bufval );
} else for (userid = key->down; !result && IsntNull(userid);
userid = userid->next)
{
if (!pgpKeyDBObjIsReal( userid) )
continue;
if( pgpObjectType( userid ) != RINGTYPE_USERID )
continue;
err = pgpGetUserIDAllocatedStringBuffer( userid,
(PGPKeyDBObjProperty)filter->value.propbuffer.prop,
&bufval, &buflen );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -