⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pgppasscach.c

📁 可以实现对邮件的加密解密以及签名
💻 C
📖 第 1 页 / 共 2 页
字号:
		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 + -