📄 pgpkeyfilter.c
字号:
{
RingIterator * ringIter;
RingObject * nameObj;
char const * nameStr;
PGPSize nameLength;
char * string;
PGPSize stringLength;
char const * p;
case kPGPFilterTypeUserIDEmail:
string = filter->value.userIDEmail;
stringLength = strlen(string);
goto stringFilter;
case kPGPFilterTypeUserIDName:
string = filter->value.userIDName;
stringLength = strlen(string);
goto stringFilter;
case kPGPFilterTypeUserIDString:
string = filter->value.userIDString;
stringLength = strlen(string);
/* FALL THROUGH */
stringFilter:
ringIter = ringIterCreate(ringSet);
if (ringIter != NULL)
{
ringIterSeekTo(ringIter, keyObj);
while (ringIterNextObject(ringIter, 2) == 2)
{
nameObj = ringIterCurrentObject(ringIter, 2);
if (ringObjectType(nameObj) == RINGTYPE_NAME &&
!ringNameIsAttribute(ringSet, nameObj))
{
nameStr = ringNameName(ringSet, nameObj, &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 == kPGPMatchEqual)
{
if (nameLength == stringLength &&
xmemimem(nameStr, nameLength,
string, stringLength) != NULL)
{
result = TRUE;
break;
}
}
else if (filter->match == kPGPMatchSubString)
{
if (xmemimem(nameStr, nameLength,
string, stringLength))
{
result = TRUE;
break;
}
}
}
}
ringIterDestroy(ringIter);
}
break;
}
default:
pgpAssertMsg(FALSE, "Unimplemented filter type");
break;
}
return result;
}
/* 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 == kPGPMatchEqual)
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 >=.
*/
if (filter->filterType == kPGPFilterTypeKeyTime
&& filter->value.proptime.prop == kPGPKeyPropExpiration)
{
if (filterTime == kPGPExpirationTime_Never)
result = TRUE;
else if (keyTime == kPGPExpirationTime_Never)
result = FALSE;
}
else
{
result = (keyTime <= filterTime);
}
if (filter->match == kPGPMatchGreaterOrEqual)
{
result = !result;
}
else
{
pgpAssert(filter->match == kPGPMatchLessOrEqual);
}
}
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->match == kPGPMatchEqual)
{
result = (buflen == filter->value.propbuffer.len) &&
pgpMemoryEqual( bufval, filter->value.propbuffer.val,
buflen );
}
else
{
pgpAssert (filter->match == kPGPMatchSubString);
result = (NULL != xmemimem( bufval, buflen,
filter->value.propbuffer.val,
filter->value.propbuffer.len ) );
}
return result;
}
PGPBoolean
pgpKeyMatchesFilter(
PGPFilterRef filter,
PGPKeyRef key)
{
PGPContextRef context;
RingSet const *rset;
RingObject *keyobj;
PGPBoolean boolval;
PGPUInt32 numval;
PGPTime timeval;
PGPByte *bufval;
PGPSize buflen;
PGPBoolean result = FALSE;
PGPUserID *userid;
PGPSig *sig;
PGPSubKey *subkey;
PGPError err = kPGPError_NoErr;
if ( ! PGPFilterIsValid( filter ) )
return( FALSE );
/* Handle some filters in this function, some using ringobjects */
switch(filter->filterType)
{
/* Key property filters */
case kPGPFilterTypeKeyBoolean:
err = PGPGetKeyBoolean (key,
(PGPKeyPropName)filter->value.propbool.prop,
&boolval);
if( IsntPGPError( err ) )
result = sCompareBoolean( filter, boolval );
break;
case kPGPFilterTypeKeyNumber:
err = PGPGetKeyNumber (key,
(PGPKeyPropName)filter->value.propnum.prop,
(PGPInt32 *)&numval);
if( IsntPGPError( err ) )
result = sCompareNumber( filter, numval );
break;
case kPGPFilterTypeKeyTime:
err = PGPGetKeyTime (key,
(PGPKeyPropName)filter->value.proptime.prop,
&timeval);
if( IsntPGPError( err ) )
result = sCompareTime( filter, timeval );
break;
case kPGPFilterTypeKeyBuffer:
err = PGPGetKeyPropertyBuffer( key,
(PGPKeyPropName)filter->value.propbuffer.prop,
0, NULL, &buflen );
if( IsPGPError( err ) )
break;
bufval = PGPNewData( PGPGetContextMemoryMgr( filter->context ),
buflen, 0);
if( IsNull( bufval ) )
break;
err = PGPGetKeyPropertyBuffer( key,
(PGPKeyPropName)filter->value.propbuffer.prop,
buflen, bufval, &buflen );
if( IsntPGPError( err ) )
result = sCompareString( filter, bufval, buflen );
PGPFreeData( bufval );
break;
case kPGPFilterTypeSubKeyBoolean:
for (subkey = (PGPSubKeyRef)key->subKeys.next;
!result && subkey != (PGPSubKeyRef)&key->subKeys;
subkey = subkey->next)
{
if (subkey->removed)
continue;
err = PGPGetSubKeyBoolean (subkey,
(PGPKeyPropName)filter->value.propbool.prop,
&boolval);
if( IsntPGPError( err ) )
result = sCompareBoolean( filter, boolval );
}
break;
case kPGPFilterTypeSubKeyNumber:
for (subkey = (PGPSubKeyRef)key->subKeys.next;
!result && subkey != (PGPSubKeyRef)&key->subKeys;
subkey = subkey->next)
{
if (subkey->removed)
continue;
err = PGPGetSubKeyNumber (subkey,
(PGPKeyPropName)filter->value.propnum.prop,
(PGPInt32 *)&numval);
if( IsntPGPError( err ) )
result = sCompareNumber( filter, numval );
}
break;
case kPGPFilterTypeSubKeyTime:
for (subkey = (PGPSubKeyRef)key->subKeys.next;
!result && subkey != (PGPSubKeyRef)&key->subKeys;
subkey = subkey->next)
{
if (subkey->removed)
continue;
err = PGPGetSubKeyTime (subkey,
(PGPKeyPropName)filter->value.proptime.prop,
&timeval);
if( IsntPGPError( err ) )
result = sCompareTime( filter, timeval );
}
break;
case kPGPFilterTypeSubKeyBuffer:
for (subkey = (PGPSubKeyRef)key->subKeys.next;
!result && subkey != (PGPSubKeyRef)&key->subKeys;
subkey = subkey->next)
{
if (subkey->removed)
continue;
err = PGPGetSubKeyPropertyBuffer( subkey,
(PGPKeyPropName)filter->value.propbuffer.prop,
0, NULL, &buflen );
if( IsPGPError( err ) )
continue;
bufval = PGPNewData( PGPGetContextMemoryMgr( filter->context ),
buflen, 0);
if( IsNull( bufval ) )
continue;
err = PGPGetSubKeyPropertyBuffer( subkey,
(PGPKeyPropName)filter->value.propbuffer.prop,
buflen, bufval, &buflen );
if( IsntPGPError( err ) )
result = sCompareString( filter, bufval, buflen );
PGPFreeData( bufval );
}
break;
case kPGPFilterTypeUserIDBoolean:
for (userid = (PGPUserIDRef)key->userIDs.next;
!result && userid != (PGPUserIDRef)&key->userIDs;
userid = userid->next)
{
if (userid->removed)
continue;
err = PGPGetUserIDBoolean (userid,
(PGPUserIDPropName)filter->value.propbool.prop,
&boolval);
if( IsntPGPError( err ) )
result = sCompareBoolean( filter, boolval );
}
break;
case kPGPFilterTypeUserIDNumber:
for (userid = (PGPUserIDRef)key->userIDs.next;
!result && userid != (PGPUserIDRef)&key->userIDs;
userid = userid->next)
{
if (userid->removed)
continue;
err = PGPGetUserIDNumber (userid,
(PGPUserIDPropName)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:
for (userid = (PGPUserIDRef)key->userIDs.next;
!result && userid != (PGPUserIDRef)&key->userIDs;
userid = userid->next)
{
if (userid->removed)
continue;
err = PGPGetUserIDTime (userid, filter->value.proptime.prop,
&timeval);
if( IsntPGPError( err ) )
result = sCompareTime( filter, timeval );
}
break;
#endif
case kPGPFilterTypeUserIDBuffer:
for (userid = (PGPUserIDRef)key->userIDs.next;
!result && userid != (PGPUserIDRef)&key->userIDs;
userid = userid->next)
{
if (userid->removed)
continue;
err = PGPGetUserIDStringBuffer( userid,
(PGPUserIDPropName)filter->value.propbuffer.prop,
0, NULL, &buflen );
if( IsPGPError( err ) )
continue;
bufval = PGPNewData( PGPGetContextMemoryMgr( filter->context ),
buflen, 0);
if( IsNull( bufval ) )
continue;
err = PGPGetUserIDStringBuffer( userid,
(PGPUserIDPropName)filter->value.propbuffer.prop,
buflen, (char *)bufval, &buflen );
if( IsntPGPError( err ) )
result = sCompareString( filter, bufval, buflen );
PGPFreeData( bufval );
}
break;
case kPGPFilterTypeSigBoolean:
for (userid = (PGPUserIDRef)key->userIDs.next;
!result && userid != (PGPUserIDRef)&key->userIDs;
userid = userid->next)
{
if (userid->removed)
continue;
for (sig = (PGPSigRef) userid->certs.next;
!result && sig != (PGPSigRef)&userid->certs;
sig = sig->next)
{
if (sig->removed)
continue;
err = PGPGetSigBoolean (sig,
(PGPSigPropName)filter->value.propbool.prop,
&boolval);
if( IsntPGPError( err ) )
result = sCompareBoolean( filter, boolval );
}
}
break;
case kPGPFilterTypeSigNumber:
for (userid = (PGPUserIDRef)key->userIDs.next;
!result && userid != (PGPUserIDRef)&key->userIDs;
userid = userid->next)
{
if (userid->removed)
continue;
for (sig = (PGPSigRef) userid->certs.next;
!result && sig != (PGPSigRef)&userid->certs;
sig = sig->next)
{
if (sig->removed)
continue;
err = PGPGetSigNumber (sig,
(PGPSigPropName)filter->value.propnum.prop,
(PGPInt32 *)&numval);
if( IsntPGPError( err ) )
result = sCompareNumber( filter, numval );
}
}
break;
case kPGPFilterTypeSigTime:
for (userid = (PGPUserIDRef)key->userIDs.next;
!result && userid != (PGPUserIDRef)&key->userIDs;
userid = userid->next)
{
if (userid->removed)
continue;
for (sig = (PGPSigRef) userid->certs.next;
!result && sig != (PGPSigRef)&userid->certs;
sig = sig->next)
{
if (sig->removed)
continue;
err = PGPGetSigTime (sig,
(PGPSigPropName)filter->value.proptime.prop,
&timeval);
if( IsntPGPError( err ) )
result = sCompareTime( filter, timeval );
}
}
break;
case kPGPFilterTypeSigBuffer:
for (userid = (PGPUserIDRef)key->userIDs.next;
!result && userid != (PGPUserIDRef)&key->userIDs;
userid = userid->next)
{
if (userid->removed)
continue;
for (sig = (PGPSigRef) userid->certs.next;
!result && sig != (PGPSigRef)&userid->certs;
sig = sig->next)
{
if (sig->removed)
continue;
err = PGPGetSigPropertyBuffer( sig,
(PGPSigPropName)filter->value.propbuffer.prop,
0, NULL, &buflen );
if( IsPGPError( err ) )
continue;
bufval = PGPNewData(
PGPGetContextMemoryMgr( filter->context ),
buflen, 0);
if( IsNull( bufval ) )
continue;
err = PGPGetSigPropertyBuffer( sig,
(PGPSigPropName)filter->value.propbuffer.prop,
buflen, bufval, &buflen );
if( IsntPGPError( err ) )
result = sCompareString( filter, bufval, buflen );
PGPFreeData( bufval );
}
}
break;
/* Compound filters */
case kPGPFilterTypeNot:
result = !pgpKeyMatchesFilter(filter->value.notFilter, key);
break;
case kPGPFilterTypeAnd:
result = pgpKeyMatchesFilter(filter->value.andFilter.andFilter1,
key)
&& pgpKeyMatchesFilter(filter->value.andFilter.andFilter2,
key);
break;
case kPGPFilterTypeOr:
result = pgpKeyMatchesFilter(filter->value.orFilter.orFilter1,
key)
|| pgpKeyMatchesFilter(filter->value.orFilter.orFilter2,
key);
break;
default:
/* Fall through to the ringobject based filtering */
context = filter->context;
if ( ! pgpContextIsValid( context ) )
return( FALSE );
rset = pgpKeyDBRingSet(key->keyDB);
keyobj = key->key;
result = sKeyObjMatchesFilter(context, filter, rset, keyobj);
}
return result;
}
static PGPError
pgpEncodeSearchTerms( PGPContextRef context,
char *var,
PGPSize varlen,
char **newString )
{
static char const badChars[] = "*()";
char *ptrBad;
char *ptrGood;
PGPInt16 i;
*newString = (char*) pgpContextMemAlloc( context,
2*varlen+1,
kPGPMemoryMgrFlags_Clear );
if ( *newString == NULL )
{
return kPGPError_OutOfMemory;
}
ptrBad = var;
ptrGood = *newString;
while ( *ptrBad != '\0' )
{
for (i=0; badChars[i] != '\0'; i++ )
{
if ( *ptrBad == badChars[i] )
{
*ptrGood++ = '\\';
*ptrGood++ = *ptrBad++;
break;
}
}
if (badChars[i] == '\0')
{
*ptrGood++ = *ptrBad++;
}
}
*ptrGood = '\0';
return kPGPError_NoErr;
}
static PGPError
pgpGrowQueryString(PGPContextRef context,
char **query, PGPUInt16 *maxsize, PGPUInt16 growthfactor)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -