📄 pgppasscach.c
字号:
if (IsNull( passphrase )) {
err = sRetrieveCachedPassphraseInternal( context, keyID,
&passphrase, &passphraseLength );
if( IsPGPError( err ) ) {
PGPMutexUnlock(&gPassCacheMutex);
return err;
}
hashedPhrase = TRUE;
usedCache = TRUE;
}
err = (PGPError)pgpSecKeyUnlock (sec, (const char *)passphrase, passphraseLength,
hashedPhrase);
if (err != 1) {
if (err == 0)
err = kPGPError_BadPassphrase;
PGPMutexUnlock(&gPassCacheMutex);
return err;
}
err = kPGPError_NoErr;
checkedPhrase = TRUE;
} else {
PGPMutexUnlock(&gPassCacheMutex);
return IsntNull( passphrase ) ? kPGPError_BadPassphrase
: kPGPError_NoErr;
}
/* If we got here, we have successfully unlocked the key */
if( checkedPhrase && !usedCache && cacheTimeOut > 0 )
{
/* Add to cache */
if( !hashedPhrase )
{
err = pgpSecKeyLockingalgorithm( sec, NULL, &bufsize );
if( IsPGPError( err ) ) {
PGPMutexUnlock(&gPassCacheMutex);
return kPGPError_NoErr;
}
passBuffer = (PGPByte *)PGPNewSecureData(
PGPPeekContextMemoryMgr( context ), bufsize, 0 );
err = pgpSecKeyConvertPassphrase( sec, pgpEnv, (const char *)passphrase,
passphraseLength, passBuffer );
if( IsPGPError( err ) )
{
PGPFreeData( passBuffer );
PGPMutexUnlock(&gPassCacheMutex);
return kPGPError_NoErr;
}
passphrase = passBuffer;
passphraseLength = bufsize;
hashedPhrase = TRUE;
mustFree = TRUE;
}
pgpAssert( hashedPhrase );
err = sCachePassphraseInternal( context, keyID, passphrase,
passphraseLength, cacheTimeOut, cacheGlobal );
if( mustFree )
PGPFreeData( (PGPByte *)passphrase );
}
PGPMutexUnlock(&gPassCacheMutex);
return err;
}
/* Put the passphrase for the given key into the cache, if valid */
PGPError
pgpSecKeyCachePassphrase( PGPSecKey *sec, PGPByte const *passphrase,
PGPSize passphraseLength, PGPBoolean hashedPhrase, PGPUInt32 cacheTimeOut,
PGPBoolean cacheGlobal )
{
PGPContextRef context;
PGPEnv *pgpEnv;
PGPSize bufsize;
PGPByte *passBuffer;
PGPKeyID keyID;
PGPBoolean mustFree = FALSE;
PGPError err = kPGPError_NoErr;
context = sec->context;
pgpEnv = pgpContextGetEnvironment( context );
PGPMutexLock(&gPassCacheMutex);
if( passphraseLength == 0 )
passphrase = NULL;
if( IsNull( passphrase ) ) {
PGPMutexUnlock(&gPassCacheMutex);
return kPGPError_NoErr;
}
if( !hashedPhrase )
{
err = pgpSecKeyLockingalgorithm( sec, NULL, &bufsize );
if( IsPGPError( err ) )
return kPGPError_NoErr;
passBuffer = (PGPByte *)PGPNewSecureData(
PGPPeekContextMemoryMgr( context ), bufsize, 0 );
err = pgpSecKeyConvertPassphrase( sec, pgpEnv,
(const char *)passphrase,
passphraseLength, passBuffer );
if( IsPGPError( err ) )
{
PGPMutexUnlock(&gPassCacheMutex);
PGPFreeData( passBuffer );
return kPGPError_NoErr;
}
passphrase = passBuffer;
passphraseLength = bufsize;
hashedPhrase = TRUE;
mustFree = TRUE;
}
/* Add to cache */
pgpNewKeyIDFromRawData( sec->keyID, sec->pkAlg, 8, &keyID );
pgpAssert( hashedPhrase );
err = sCachePassphraseInternal( context, keyID, passphrase,
passphraseLength, cacheTimeOut, cacheGlobal );
if( mustFree )
PGPFreeData( (PGPByte *)passphrase );
PGPMutexUnlock(&gPassCacheMutex);
return err;
}
/* Call periodically to check for expiration of cached passphrases */
void
pgpExpirePassphraseCache( PGPContextRef context )
{
struct PGPCacheHeader * cacheHeader;
struct PGPPassCache ** cachePtr;
struct PGPPassCache * cache;
PGPTime now;
PGPBoolean someExpired = FALSE;
PGPMutexLock(&gPassCacheMutex);
cacheHeader = pgpContextGetPassphraseCache( context );
if( IsNull( cacheHeader ) ) {
PGPMutexUnlock(&gPassCacheMutex);
return;
}
now = PGPGetTime();
cachePtr = &cacheHeader->globalCache;
while( IsntNull(*cachePtr) )
{
cache = *cachePtr;
if( cache->timeoutTime < now ) {
sExpirePassCache( cachePtr );
cacheHeader->nCached--;
someExpired = TRUE;
} else
cachePtr = &cache->next;
}
cachePtr = &cacheHeader->localCaches;
while( IsntNull(*cachePtr) )
{
cache = *cachePtr;
if( cache->timeoutTime < now ) {
sExpirePassCache( cachePtr );
cacheHeader->nCached--;
someExpired = TRUE;
} else
cachePtr = &cache->next;
}
if( someExpired && IsntNull( pcClients ) )
PGPInOrderTraversal( pcClients, sNotifyProc, 0 );
PGPMutexUnlock(&gPassCacheMutex);
}
PGPBoolean
pgpIsPassphraseCached( PGPContextRef context )
{
struct PGPCacheHeader * cacheHeader;
struct PGPPassCache ** cachePtr;
PGPMutexLock(&gPassCacheMutex);
cacheHeader = pgpContextGetPassphraseCache( context );
if( IsNull( cacheHeader ) ) {
PGPMutexUnlock(&gPassCacheMutex);
return FALSE;
}
cachePtr = &cacheHeader->globalCache;
if( IsntNull( *cachePtr ) ) {
PGPMutexUnlock(&gPassCacheMutex);
return TRUE;
}
cachePtr = &cacheHeader->localCaches;
if( IsntNull( *cachePtr ) ) {
PGPMutexUnlock(&gPassCacheMutex);
return TRUE;
}
PGPMutexUnlock(&gPassCacheMutex);
return FALSE;
}
PGPError
pgpCountCachedPassphrases_internal( PGPContextRef context,
PGPUInt32 *pnLocal, PGPUInt32 *pnGlobal, PGPUInt32 *pnOtherLocal )
{
struct PGPCacheHeader * cacheHeader;
struct PGPPassCache * cache;
PGPUInt32 nLocal = 0;
PGPUInt32 nGlobal = 0;
PGPUInt32 nOtherLocal = 0;
PGPByte * userName = NULL;
PGPConnectRef clientID;
PGPMutexLock(&gPassCacheMutex);
if( IsntNull( pnLocal ) )
*pnLocal = 0;
if( IsntNull( pnGlobal ) )
*pnGlobal = 0;
if( IsntNull( pnOtherLocal ) )
*pnOtherLocal = 0;
clientID = pgpContextGetConnectRef( context );
#if ! PGP_OSX && (PGP_WIN32 || PGP_UNIX)
{
pgpRPCconnection *connectRef = (pgpRPCconnection *) clientID;
if( IsntNull( connectRef ) && IsntNull( connectRef->UserName ) )
{
userName = connectRef->UserName;
}
}
#endif
cacheHeader = pgpContextGetPassphraseCache( context );
if( IsntNull( cacheHeader ) )
{
cache = cacheHeader->globalCache;
while( IsntNull(cache) )
{
if( IsNull(userName) || 0 == strcmp((char *) userName,
(char *) cache->userName) )
++nGlobal;
cache = cache->next;
}
cache = cacheHeader->localCaches;
while( IsntNull(cache) )
{
if( pgpConnectRefEqual(cache->clientID, clientID) )
++nLocal;
else
++nOtherLocal;
cache = cache->next;
}
}
PGPMutexUnlock(&gPassCacheMutex);
if( IsntNull( pnLocal ) )
*pnLocal = nLocal;
if( IsntNull( pnGlobal ) )
*pnGlobal = nGlobal;
if( IsntNull( pnOtherLocal ) )
*pnOtherLocal = nOtherLocal;
return kPGPError_NoErr;
}
/* Maintain list of passphrase cache clients */
void
pgpPassphraseCacheAddClient( PGPContextRef context, PGPConnectRef id )
{
PGPUserValue uv;
PGPMutexLock(&gPassCacheMutex);
if( IsNull( pcClients ) )
PGPNewBinaryTree( PGPPeekContextMemoryMgr( context ),
&pcClients );
/* Make sure not already in the list */
if( IsntNull( pcClients ) )
{
if( IsPGPError( PGPFindNode( pcClients, (PGPInt32)id, &uv ) ) ) {
PGPAddNode( pcClients, (PGPInt32)id, 0 );
numClients++;
}
}
PGPMutexUnlock(&gPassCacheMutex);
}
void
pgpPassphraseCacheRemoveClient( PGPConnectRef id )
{
PGPUserValue uv;
PGPMutexLock(&gPassCacheMutex);
if( IsntNull( pcClients ) )
{
PGPDisposeNode( pcClients, (PGPInt32)id, &uv );
numClients--;
// id is zero when running SDK in "local mode".
if (( id == 0 ) || (numClients == 0)) {
PGPDisposeBinaryTree ( pcClients );
pcClients = NULL;
}
}
PGPMutexUnlock(&gPassCacheMutex);
}
/* Client call to clear all cached data */
PGPError
PGPPurgePassphraseCache( PGPContextRef context )
{
PGPValidateContext( context );
pgpEnterPGPErrorFunction();
if (pgpRPCEnabled())
return pgpPurgePassphraseCache_back(context);
return pgpPurgePassphraseCache_internal(context);
}
/* Client call to count cached passphrases */
PGPError
PGPCountCachedPassphrases( PGPContextRef context,
PGPUInt32 *pnLocal, PGPUInt32 *pnGlobal, PGPUInt32 *pnOtherLocal )
{
PGPValidateContext( context );
if( IsntNull( pnLocal ) )
PGPValidatePtr( pnLocal );
if( IsntNull( pnGlobal ) )
PGPValidatePtr( pnGlobal );
if( IsntNull( pnOtherLocal ) )
PGPValidatePtr( pnOtherLocal );
pgpEnterPGPErrorFunction();
if (pgpRPCEnabled()) {
PGPUInt32 nLocal, nGlobal, nOtherLocal;
PGPError err;
err = pgpCountCachedPassphrases_back( context, &nLocal, &nGlobal,
&nOtherLocal );
if( IsPGPError( err ) )
return err;
if( IsntNull( pnLocal ) )
*pnLocal = nLocal;
if( IsntNull( pnGlobal ) )
*pnGlobal = nGlobal;
if( IsntNull( pnOtherLocal ) )
*pnOtherLocal = nOtherLocal;
return kPGPError_NoErr;
}
if( IsntNull( pnLocal ) )
*pnLocal = 0;
if( IsntNull( pnGlobal ) )
*pnGlobal = 0;
if( IsntNull( pnOtherLocal ) )
*pnOtherLocal = 0;
return pgpCountCachedPassphrases_internal( context, pnLocal, pnGlobal,
pnOtherLocal );
}
/*__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 + -