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

📄 cldapkeyserver.cpp

📁 可以实现对邮件的加密解密以及签名
💻 CPP
📖 第 1 页 / 共 3 页
字号:

		if( query != 0 )
			PGPFreeData( query );

		if( mCanceled )
			ThrowPGPError_( kPGPError_UserAbort );
		else
		{
			(void) PGPldapGetErrno( mLDAP, NULL, &szError, &ldapResult );
			SetErrorString( szError );
			throw;
		}
	}
	
	if( receivedBadKeys )
		ThrowPGPError_( kPGPError_ServerBadKeysInSearchResults );

	if( partialResults )
		ThrowPGPError_( kPGPError_ServerPartialSearchResults );

}



	void
CLDAPKeyServer::Upload(
	PGPKeyUploadPreference inSendPrivateKeys,
	PGPKeySetRef	inKeysToUpload,
	PGPKeySetRef *	outKeysThatFailed)
{
	StPreserveSocketsEventHandler	preserve(this);
	
	char *			keySpace				= NULL;
	char *			exportedKey				= NULL;
	PGPKeySetRef	errorKeySet				= kInvalidPGPKeySetRef;
	PGPKeyListRef	keyList					= kInvalidPGPKeyListRef;
	PGPKeyIterRef	keyIter					= kInvalidPGPKeyIterRef;
	PGPKeySetRef	singleKeySet			= kInvalidPGPKeySetRef;
	PGPBoolean		sendRequest				= false;
	PGPBoolean		authorizationFailed		= false;
	PGPBoolean		partialFailure			= false;
	PGPBoolean		keyAlreadyExists		= false;
	PGPBoolean		failedPolicy			= false;
	PGPError		pgpError				= kPGPError_NoErr;
	char *			keySpaceSuffix			= NULL;
	PGPBoolean		exportPrivateKeys		= false;
	char *			szError					= NULL;
	PGPldapResult	ldapResult				= kPGPldapResult_Success;
	
	if( mKeySpace == kPGPKeyServerKeySpace_Pending )
		keySpaceSuffix = mBasePendingDN;
	else
		keySpaceSuffix = mBaseKeySpaceDN;
	
	SetErrorString( NULL );

	if( mUseLDAPPGP )
	{
		mLDAPPGPKeyServer->Upload(inSendPrivateKeys, inKeysToUpload, outKeysThatFailed);
		return;
	}

	if( !mIsOpen )
		ThrowPGPError_(kPGPError_ServerNotOpen);

	if( inSendPrivateKeys == kPGPPrivateKeyAllowed )
	{
		if( mType != kPGPKeyServerProtocol_LDAPS )
			ThrowPGPError_( kPGPError_ServerOperationRequiresTLS );

		exportPrivateKeys = true;
	}

	try
	{
		PGPKeyDBObjRef		key;
		PGPSize				bufSize;
		char *				strVals[2] = { 0, 0 };
		PGPldapMod			mod = { kPGPldapModOp_Add,
									( ( mExportFormat == kPGPExportFormat_Basic ) ?
										(char *) kPGPKeyAttribute : 
										(char *) kPGPKeyV2Attribute ),
									strVals,
									(PGPberValue **) NULL };
		PGPldapMod *		attrs[2] = { &mod, NULL };

		
		pgpError = pgpEventKeyServer(	mContext,
										mEventHandler,
										mEventHandlerData,
										(PGPKeyServerRef) this,
										kPGPKeyServerState_Uploading);
		ThrowIfPGPErrorOrLDAPCanceled_( pgpError );
			
		// Create error set
		pgpError = PGPNewEmptyKeySet( PGPPeekKeySetKeyDB( inKeysToUpload ), &errorKeySet );
		ThrowIfPGPError_( pgpError );
		
		// Create keyspace
		keySpace = new char[strlen( kAddAndRequestDNPrefix ) + 
							strlen(	keySpaceSuffix ) + 1];
		if( IsNull( keySpace ) )
			ThrowPGPError_( kPGPError_OutOfMemory );

		sprintf( keySpace, "%s%s", kAddAndRequestDNPrefix, keySpaceSuffix );
		
		// Iterate through keys uploading them one at a time
		pgpError = PGPOrderKeySet(	inKeysToUpload,
									kPGPKeyOrdering_Any,
									FALSE,
									&keyList );
		ThrowIfPGPError_( pgpError );
		pgpError = PGPNewKeyIter( keyList, &keyIter );
		ThrowIfPGPError_( pgpError);
		while( ( pgpError = PGPKeyIterNextKeyDBObj( keyIter, 
								kPGPKeyDBObjType_Key,
								&key ) ) == kPGPError_NoErr )
		{
			// Send to server
			if( !sendRequest )
			{
				pgpError = PGPExport( mContext,
								PGPOExportKeyDBObj( mContext, key ),
								PGPOExportPrivateKeys(mContext,
													exportPrivateKeys),
								PGPOAllocatedOutputBuffer(
													mContext,
													(void **) &exportedKey,
													MAX_PGPSize,
													&bufSize),
								PGPOExportFormat(mContext,
												mExportFormat),
								PGPOLastOption(mContext));

				ThrowIfPGPError_( pgpError );
				strVals[0] = exportedKey;
				
				pgpError = PGPldapAddSync( mLDAP, keySpace, attrs );
				if( IsPGPError( pgpError ) )
				{
					partialFailure = true;
	
					switch ( pgpError )
					{
						case kPGPError_LDAPAlreadyExists:
							keyAlreadyExists = true;
							break;
						
						case kPGPError_LDAPInsufficientAccess:
							sendRequest = true;
							break;
						
						case kPGPError_LDAPInvalidCredentials:
							failedPolicy = true;
							break;

						default:
							ThrowIfPGPError_( pgpError );
							break;
					}
				}

				pgpError = PGPAddKey(key, errorKeySet);
				ThrowIfPGPError_( pgpError );

				PGPFreeData( exportedKey);
				exportedKey = 0;
			}
			
			// Need to send a signed request
			if( sendRequest && ( !mSecured ) )
			{
				pgpError = PGPNewOneKeySet( key, &singleKeySet );
				ThrowIfPGPError_( pgpError );

				pgpError = SendRequest( kAdd, singleKeySet, 0 );
				if( IsPGPError( pgpError ) ) {
					partialFailure = true;
					(void) PGPAddKeys( singleKeySet, errorKeySet );

					switch( pgpError )
					{
						case kPGPError_ServerKeyAlreadyExists:
							keyAlreadyExists = true;
							break;
						
						case kPGPError_ServerAuthorizationFailed:
							authorizationFailed = true;
							break;
						
						case kPGPError_ServerKeyFailedPolicy:
							failedPolicy = true;
							break;
					}
				}

				PGPFreeKeySet(singleKeySet);
				singleKeySet = kInvalidPGPKeySetRef;
			}
		}

		delete[] keySpace;
		keySpace = 0;

		PGPFreeKeyIter( keyIter );
		keyIter = kInvalidPGPKeyIterRef;

		PGPFreeKeyList( keyList );
		keyList = kInvalidPGPKeyListRef;

		if( partialFailure )
		{
			*outKeysThatFailed = errorKeySet;
			errorKeySet = kInvalidPGPKeySetRef;

			if (failedPolicy)
				ThrowPGPError_(kPGPError_ServerKeyFailedPolicy);
			else if (authorizationFailed)
				ThrowPGPError_(kPGPError_ServerAuthorizationFailed);
			else if (keyAlreadyExists)
				ThrowPGPError_(kPGPError_ServerKeyAlreadyExists);
			else
				ThrowPGPError_(kPGPError_ServerPartialAddFailure);
		}
		else
		{
			PGPFreeKeySet(errorKeySet);
			errorKeySet = kInvalidPGPKeySetRef;
		}
	}
	
	catch (...)
	{
		delete[] keySpace;
		if (exportedKey != 0)
			PGPFreeData(exportedKey);

		if (singleKeySet != kInvalidPGPKeySetRef)
			PGPFreeKeySet(singleKeySet);

		if (keyIter != kInvalidPGPKeyIterRef)
			PGPFreeKeyIter(keyIter);

		if (keyList != kInvalidPGPKeyListRef)
			PGPFreeKeyList(keyList);

		if (errorKeySet != kInvalidPGPKeySetRef)
			PGPFreeKeySet(errorKeySet);

		if (mCanceled)
			ThrowPGPError_(kPGPError_UserAbort);
		else 
		{
			(void) PGPldapGetErrno( mLDAP, NULL, &szError, &ldapResult );
			SetErrorString( szError );
			throw;
		}
	}
}



	void
CLDAPKeyServer::Delete(
	PGPKeySetRef	inKeysToDelete,
	PGPKeySetRef *	outKeysThatFailed)
{
	if( mUseLDAPPGP )
	{
		mLDAPPGPKeyServer->Delete(inKeysToDelete, outKeysThatFailed);
		return;
	}

	DeleteOrDisable(true, inKeysToDelete, outKeysThatFailed);
}



	void
CLDAPKeyServer::Disable(
	PGPKeySetRef	inKeysToDisable,
	PGPKeySetRef *	outKeysThatFailed)
{
	if( mUseLDAPPGP )
	{
		mLDAPPGPKeyServer->Disable(inKeysToDisable, outKeysThatFailed);
		return;
	}

	DeleteOrDisable(false, inKeysToDisable, outKeysThatFailed);
}



	void
CLDAPKeyServer::DeleteOrDisable(
	PGPBoolean		inDelete,
	PGPKeySetRef	inKeySet,
	PGPKeySetRef *	outKeysThatFailed)
{
	StPreserveSocketsEventHandler	preserve(this);
	const char *	action		= 0;
	char *			szError		= NULL;
	PGPldapResult	result		= kPGPldapResult_Success;
	PGPError		pgpError	= kPGPError_NoErr;

	SetErrorString( NULL );
	if( !mIsOpen )
		ThrowPGPError_( kPGPError_ServerNotOpen );

	try 
	{
		PGPKeyServerState	state;
		
		if( mAccessType != kPGPKeyServerAccessType_Administrator )
			ThrowPGPError_( kPGPError_ServerAuthorizationRequired );

		if( inDelete )
		{
			action = kDelete;
			state = kPGPKeyServerState_Deleting;
		} 
		else
		{
			action = kDisable;
			state = kPGPKeyServerState_Disabling;
		}
		pgpError = pgpEventKeyServer(	mContext,
										mEventHandler,
										mEventHandlerData,
										(PGPKeyServerRef) this, 
										state );
		ThrowIfPGPErrorOrLDAPCanceled_( pgpError );
		pgpError = SendRequest(	action,
								inKeySet,
								outKeysThatFailed );
		ThrowIfPGPErrorOrLDAPCanceled_( pgpError );
	}
	
	catch (...)
	{
		if( mCanceled )
			ThrowPGPError_( kPGPError_UserAbort );
		else 
		{
			(void) PGPldapGetErrno( mLDAP, NULL, &szError, &result );
			SetErrorString( szError );
			throw;
		}
	}
}



	PGPError
CLDAPKeyServer::SendRequest(
	const char *	inAction,
	PGPKeySetRef	inKeySetRef,
	PGPKeySetRef *	outKeysThatFailed)
{
	PGPError		result			= kPGPError_NoErr;
	char *			request			= NULL;
	char *			signedRequest	= NULL;
	PGPKeyListRef	keyList			= kInvalidPGPKeyListRef;
	PGPKeyIterRef	keyIter			= kInvalidPGPKeyIterRef;
	char *			keySpace		= NULL;
	char *			error			= NULL;
	char *			szError			= NULL;
	
	try
	{
		PGPUInt32			requestSize		= 0;
		PGPKeyID			keyID;
		char				keyIDString[kPGPMaxKeyIDStringSize];
		const char *		location		= NULL;
		PGPUInt32			total;
		PGPError			pgpError		= kPGPError_NoErr;
		PGPOptionListRef	options;
		PGPKeyDBObjRef		key;
		PGPSize				dummy;
		char *				strVals[2] = { 0, 0 };
		PGPldapMod			mod = { kPGPldapModOp_Add,
									(char *) kRequestPGPRequest,
									strVals,
									(PGPberValue **) NULL };
		PGPldapMod *		attrs[2] = { &mod, 0 };
		PGPldapResult		ldapResult		= kPGPldapResult_Success;
		char *				nextItem		= NULL;
		
		if( mKeySpace == kPGPKeyServerKeySpace_Pending )
			location = kRequestPending;
		else
			location = kRequestActive;
		
		// Allocate request buffer and add prefix
		pgpError = PGPCountKeys( inKeySetRef, &total );
		ThrowIfPGPError_( pgpError );
		request = new char[strlen( kRequestRequest ) + strlen( inAction )
							+ strlen( kRequestLocation ) + strlen( location )
							+ ( ( kPGPMaxKeyIDStringSize + 2 ) * total ) + 7];
		if( request == 0 )
			ThrowPGPError_(kPGPError_OutOfMemory);

		requestSize = sprintf(	request,
								"%s%s\r\n%s%s\r\n\r\n",
								kRequestRequest,
								inAction,
								kRequestLocation,
								location );
		
		// Iterate through keys creating the request
		pgpError = PGPOrderKeySet( inKeySetRef, kPGPKeyOrdering_Any, FALSE, &keyList );
		ThrowIfPGPError_( pgpError );

		pgpError = PGPNewKeyIter( keyList, &keyIter );
		ThrowIfPGPError_(pgpError);

		while( ( pgpError = PGPKeyIterNextKeyDBObj( keyIter, kPGPKeyDBObjType_Key, &key) )
					== kPGPError_NoErr)
		{
			pgpError = PGPGetKeyID( key, &keyID );
			ThrowIfPGPError_( pgpError );

			pgpError = PGPGetKeyIDString(	&keyID,
											kPGPKeyIDString_Full,
											keyIDString );
			ThrowIfPGPError_( pgpError );

			requestSize += sprintf(	request + requestSize,
									"%s\r\n",
									keyIDString );
		}
		PGPFreeKeyIter( keyIter );
		keyIter = kInvalidPGPKeyIterRef;

		PGPFreeKeyList( keyList );
		keyList = kInvalidPGPKeyListRef;

		if( pgpError != kPGPError_EndOfIteration )
			ThrowIfPGPError_( pgpError );

		// Now sign the request if we do not have a secure connection
		if( ! mSecured )
		{
			do
			{
				pgpError = pgpEventKeyServerSign(	mContext,
													&options,
													mEventHandler,
													mEventHandlerData,
													(PGPKeyServerRef) this );
				ThrowIfPGPErrorOrLDAPCanceled_( pgpError );

				pgpError = PGPEncode(	mContext,
										PGPOInputBuffer( mContext,
													request,
													requestSize ),
										PGPOAllocatedOutputBuffer(
													mContext,
													(void**) &signedRequest,
													MAX_PGPSize,
													&dummy ),
										options,
										PGPOLastOption( mContext ) );
			} while (pgpError == kPGPError_BadPassphrase);

			ThrowIfPGPError_(pgpError);

			delete[] request;
			request = NULL;
		}
		
		// Send the request
		mod.value[0] = ( mSecured ? request : signedRequest );

		keySpace = new char[strlen( kAddAndRequestDNPrefix )
							+ strlen( mBaseKeySpaceDN ) + 1];
		if( keySpace == 0 )
			ThrowPGPError_( kPGPError_OutOfMemory );

		sprintf( keySpace, "%s%s", kAddAndRequestDNPrefix, mBaseKeySpaceDN );

		pgpError = PGPldapAddSync( mLDAP, keySpace, attrs );

		switch( pgpError )
		{
			case kPGPError_NoErr:
			case kPGPError_LDAPAlreadyExists:
			case kPGPError_LDAPInsufficientAccess:
			case kPGPError_LDAPInvalidCredentials:
				/* Ignore these errors for now.  We'll handle them later. */
				break;
			
			default:
				ThrowPGPError_( kPGPError_ServerRequestFailed );
				break;
		}

		ThrowIfLDAPCanceled_();

		delete[] keySpace;
		keySpace = NULL;

		if( mSecured )
		{
			delete[] request;
			request = 0;
		}
		else
		{
			PGPFreeData(signedRequest);
			signedRequest = 0;
		}
	
		// Scan for error keys
		if( ( outKeysThatFailed != 0 ) && ( IsntNull( szError ) ) &&
			( *szError != '\0' ) )
		{
			char *	currentItem = NULL;
		
			error = new char[strlen( szError ) + 1];

			if( IsNull( error ) )
				ThrowPGPError_(kPGPError_OutOfMemory);

			strcpy( error, szError );
			currentItem = strchr( error, ':' );

			if( currentItem != 0 )
			{
				currentItem++;
				while( ( *currentItem != '\0' ) && isspace( *currentItem ) )
					currentItem++;

				while( *currentItem != '\0' )
				{
					nextItem = currentItem;
					while( ( *nextItem != '\0' ) && ( !isspace( *nextItem ) ) )
						nextItem++;

					if( *nextItem != '\0' )
						*nextItem++ = '\0';

					pgpError = PGPNewKeyIDFromString( currentItem,
									kPGPPublicKeyAlgorithm_Invalid,
									&keyID);
					ThrowIfPGPError_(pgpError);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -