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

📄 cldapkeyserver.cpp

📁 PGP8.0源码 请认真阅读您的文件包然后写出其具体功能
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/*____________________________________________________________________________
        Copyright (C) 2002 PGP Corporation
        All rights reserved.

        $Id: CLDAPKeyServer.cpp,v 1.23 2002/11/05 00:10:44 dallen Exp $
____________________________________________________________________________*/

#include <string.h>
#include <ctype.h>
/* <stdlib.h> includs <sys/time.h> which aCC barfs on if <sys/sigevent.h>
   in not included. */
#if PGP_COMPILER_HPUX
#include <sys/sigevent.h>
#endif /* PGP_COMPILER_HPUX */
#include <stdlib.h>

#include "pgpStrings.h"
#include "pgpOptionList.h"
#include "pgpEventPriv.h"
#include "pgpKeys.h"
#include "pgpFeatures.h"
#include "pgpSockets.h"
#include "pgpMem.h"
#include "pgpMemoryMgr.h"
#include "pgpDebug.h"

#include "CLDAPKeyServer.h"
#include "CLDAPPGPKeyServer.h"



#define ThrowIfLDAPCanceled_()	if (mCanceled) \
									ThrowPGPError_(kPGPError_UserAbort);
#define ThrowIfPGPErrorOrLDAPCanceled_(x)	{	ThrowIfPGPError_(x); \
												ThrowIfLDAPCanceled_(); }

static const char *	kBaseKeyspaceDN = "baseKeyspaceDN";
static const char *	kBasePendingDN = "basePendingDN";
static const char *	kVersionDN = "version";
static const char *	kPGPServerInfoCN = "cn=PGPServerInfo";
static const char *	kMonitorCN = "cn=monitor";
static const char *	kObjectClassAny = "(objectclass=*)";
static const char *	kPGPKeyAttribute = "pgpKey";
static const char *	kPGPKeyV2Attribute = "pgpKeyV2";
static const char *	kRequestPGPRequest = "PGPrequest";
static const char *	kDefaultPGPGroupspace = "ou=default,o=pgp groupspace,c=us";
//static const char *	kPGPSrvGroupFile = "pgpSrvGroupFile";
static const char *	kPGPSrvGroupFileV2 = "pgpSrvGroupFileV2";
static const char *	kRequestRequest = "Request: ";
static const char * kRequestLocation = "Location: ";
static const char * kRequestPending = "pending";
static const char *	kRequestActive = "active";
static const char *	kAddAndRequestDNPrefix = "pgpcertid=virtual, ";
static const char *	kAdd = "add";
static const char *	kDelete = "delete";
static const char *	kDisable = "disable";
static const char *	kObjectClass = "objectclass";
static const char * kPGPSrvGroupFileClass = "pgpsrvgroupfile";



CLDAPKeyServer::CLDAPKeyServer(
	PGPContextRef			inContext,
	const char *			inHostName,
	PGPUInt32				inHostAddress,
	PGPUInt16				inHostPort,
	PGPKeyServerProtocol	inType,
	PGPKeyServerClass		inClass,
	PGPKeyServerAccessType	inAccessType,
	PGPKeyServerKeySpace	inKeySpace,
	const char *			inKeyStoreDN)
	: CKeyServer(inContext, inHostName, inHostAddress, inHostPort, 0, inType, inClass),
	  mContext(inContext),
	  mAccessType(inAccessType), mKeySpace(inKeySpace), mLDAP(0),
	  mBaseKeySpaceDN(0), mBasePendingDN(0),
	  mExportFormat(kPGPExportFormat_Basic),
	  mUseLDAPPGP(false)
{
	mLDAPPGPKeyServer = new CLDAPPGPKeyServer(inContext,
											 inHostName,
											 0,
											 inHostPort,
											 inType,
											 inClass,
											 inAccessType,
											 inKeyStoreDN);
}



CLDAPKeyServer::~CLDAPKeyServer()
{
	delete mLDAPPGPKeyServer;
}

	void
CLDAPKeyServer::Open(
	PGPtlsSessionRef	inTLSSession)
{
	StPreserveSocketsEventHandler	preserve(this);
	PGPldapMessageRef				message = kInvalidPGPldapMessageRef;
	PGPldapResult					result;
	char **							value = 0;
	char *							szError = NULL;
	PGPError						pgpError	= kPGPError_NoErr;

	SetErrorString(0);

	try
	{
		mLDAPPGPKeyServer->Open(inTLSSession);
		mUseLDAPPGP = true;
		return;
	}
	catch(PGPError exception)
	{
		// If we get a SocketsNotConnected error, we couldn't contact the server,
		// so lets save time and not try connecting again
		if( exception == kPGPError_SocketsNotConnected )
		{
			// Free mLDAPPGPKeyServer's LDAP context
			((CLDAPPGPKeyServer *)mLDAPPGPKeyServer)->GetLDAP( mLDAP, mSecured );
			
			if( PGPldapContextRefIsValid( mLDAP ) )
			{
				(void) PGPFreeLDAPContext( mLDAP );
				mLDAP = kInvalidPGPldapContextRef;
				mSecured = false;
				((CLDAPPGPKeyServer *)mLDAPPGPKeyServer)->SetLDAP( mLDAP, mSecured );
			}

			ThrowPGPError_( kPGPError_ServerOpenFailed );
		}
	}

	try
	{
		PGPldapMessageRef	nextMessage		= kInvalidPGPldapMessageRef;
		char *				attribute		= NULL;
		PGPberElementRef	iterAttribute	= kInvalidPGPberElementRef;
		static const char *	attr[4] = { kBaseKeyspaceDN,
									kBasePendingDN, kVersionDN, 0 };

		CKeyServer::Open(inTLSSession);
		
		// Open ldap connection
		pgpError = pgpEventKeyServer(	mContext,
										mEventHandler,
										mEventHandlerData,
										(PGPKeyServerRef) this,
										kPGPKeyServerState_Opening);
		ThrowIfPGPErrorOrLDAPCanceled_(pgpError);

		// We already created the PGPldapContextRef in CLDAPPGPKeyServer::Open,
		// so let's just grab that and re-use it.  We need to do this in order to 
		// avoid trying to do a TLS negotiation twice.
		((CLDAPPGPKeyServer *)mLDAPPGPKeyServer)->GetLDAP( mLDAP, mSecured );
		
		// Retrieve key space distinguished names

		pgpError = PGPNewLDAPMessage( mLDAP, &message );
		if( IsPGPError( pgpError ) )
			ThrowPGPError_( kPGPError_ServerOpenFailed );

		pgpError = PGPldapSearchSync( mLDAP,
									  (char *) kPGPServerInfoCN,
									  kPGPldapScope_Base,
									  (char *) kObjectClassAny,
									  (char **) attr,
									  FALSE,
									  message );
		ThrowIfLDAPCanceled_();
		if( IsPGPError( pgpError ) )
			ThrowPGPError_(kPGPError_ServerOpenFailed);

		pgpError = PGPldapFirstEntry( mLDAP, message, &nextMessage );
		if( IsPGPError( pgpError ) )
			ThrowPGPError_( kPGPError_ServerOpenFailed );

		while (nextMessage != NULL)
		{
			pgpError = PGPldapFirstAttribute( mLDAP,
								   nextMessage,
								   &iterAttribute,
								   &attribute );
			if( IsPGPError( pgpError ) )
				ThrowPGPError_( kPGPError_ServerOpenFailed );

			while (attribute != NULL)
			{
				pgpError = PGPldapGetValues( mLDAP,
								  nextMessage,
								  attribute,
								  &value );
				if( IsPGPError( pgpError ) )
					ThrowPGPError_( kPGPError_ServerOpenFailed );

				if ((value != 0) && (*value != 0))
				{
					if (pgpCompareStringsIgnoreCase(attribute,
							attr[0]) == 0) 
					{
						mBaseKeySpaceDN = new char[strlen(*value) + 1];
						if (mBaseKeySpaceDN == 0)
							ThrowPGPError_(kPGPError_OutOfMemory);

						strcpy(mBaseKeySpaceDN, *value);
					} 
					else if (pgpCompareStringsIgnoreCase(attribute,
								attr[1]) == 0)
					{
						mBasePendingDN = new char[strlen(*value) + 1];
						if (mBasePendingDN == 0)
							ThrowPGPError_(kPGPError_OutOfMemory);

						strcpy(mBasePendingDN, *value);
					}
					else if (pgpCompareStringsIgnoreCase(attribute,
								attr[2]) == 0)
					{
						if (atol(*value) > 1)
							mExportFormat = kPGPExportFormat_Complete;

					}
					(void) PGPFreeLDAPValues( value );
					value = 0;
				}
				else 
				{
					pgpError = PGPldapGetErrno( mLDAP, NULL, NULL, &result );
					if( IsPGPError( pgpError ) )
						ThrowPGPError_( kPGPError_ServerOpenFailed );

					if (( value == 0 ) && ( result != kPGPldapResult_Success ))
					{
						if( result == kPGPldapResult_InsufficientAccess )
							ThrowPGPError_(kPGPError_ServerAuthorizationFailed);
						else
							ThrowPGPError_(kPGPError_ServerOpenFailed);
					}
				}
				(void) PGPFreeData( attribute );
				attribute = NULL;

				pgpError = PGPldapNextAttribute( mLDAP,
									  nextMessage,
									  iterAttribute,
									  &attribute );
				if( IsPGPError( pgpError ) )
					ThrowPGPError_( kPGPError_ServerOpenFailed );
			}

			pgpError = PGPldapGetErrno( mLDAP, NULL, NULL, &result );
			if( IsPGPError( pgpError ) || ( result != kPGPldapResult_Success ) )
				ThrowPGPError_(kPGPError_ServerOpenFailed);

			pgpError = PGPldapNextEntry( mLDAP,
							  nextMessage,
							  &nextMessage );
			if( IsPGPError( pgpError ) )
				ThrowPGPError_( kPGPError_ServerOpenFailed );
		}
		if ( (mBaseKeySpaceDN == 0) || (mBasePendingDN == 0) )
			ThrowPGPError_(kPGPError_ServerOpenFailed);

		PGPFreeLDAPMessage( message );
		message = kInvalidPGPldapMessageRef;
	}
	
	catch (...) {
		delete[] mBaseKeySpaceDN;
		mBaseKeySpaceDN = 0;
		delete[] mBasePendingDN;
		mBasePendingDN = 0;
		
		if( IsntNull( value ) )
			PGPFreeLDAPValues( value );

		if( PGPldapMessageRefIsValid( message ) )
			PGPFreeLDAPMessage( message );

		mTLSSession = kInvalidPGPtlsSessionRef;
		mIsOpen = false;
		mSecured = false;
		if( PGPldapContextRefIsValid( mLDAP ) )
		{
			if (!mCanceled)
			{
				(void) PGPldapGetErrno( mLDAP, NULL, &szError, &result );
				SetErrorString( szError );
			}
		}

		if (mCanceled)
		{
			mCanceled = false;
			ThrowPGPError_(kPGPError_UserAbort);
		} 
		else 
			throw;
	}
}



	void
CLDAPKeyServer::Close()
{
	StPreserveSocketsEventHandler	preserve(this);

	(void) pgpEventKeyServer( mContext,
				mEventHandler,
				mEventHandlerData,
				(PGPKeyServerRef) this,
				kPGPKeyServerState_Closing);

	// This will also unbind and free our PGPldapContextRef
	mLDAPPGPKeyServer->Close();
	mSecured = false;
	mLDAP = kInvalidPGPldapContextRef;
					
	delete[] mBaseKeySpaceDN;
	mBaseKeySpaceDN = 0;
	delete[] mBasePendingDN;
	mBasePendingDN = 0;


	CKeyServer::Close();
}



	void
CLDAPKeyServer::Cancel()
{
	mLDAPPGPKeyServer->Cancel();

	CKeyServer::Cancel();

	if( PGPldapContextRefIsValid( mLDAP ) )
	{
		PGPError		err			= kPGPError_NoErr;
		PGPSocketRef	sock		= kInvalidPGPSocketRef;

		err = PGPldapGetOption( mLDAP, kPGPldapOpt_Desc, &sock );
		if( IsntPGPError( err ) )
			(void) PGPCloseSocket( sock );
	}
	else
		return;

	mSecured = false;
}



	void
CLDAPKeyServer::Query(
	PGPFilterRef	inFilterRef,
	PGPKeyDBRef *	outFoundKeys)
{
	StPreserveSocketsEventHandler	preserve(this);
	char *							query = 0;
	PGPldapMessageRef				message = kInvalidPGPldapMessageRef;
	char **							value = 0;
	PGPKeyDBRef						foundKeys = kInvalidPGPKeyDBRef;
	PGPKeyDBRef						singleKeyDB = kInvalidPGPKeyDBRef;
	PGPKeySetRef					singleKeySet = kInvalidPGPKeySetRef;
	PGPBoolean						partialResults = false;
	PGPBoolean						receivedBadKeys = false;
	PGPldapResult					ldapResult 	= kPGPldapResult_Success;
	PGPError						pgpError 	= kPGPError_NoErr;
	PGPldapMessageRef				nextMessage = kInvalidPGPldapMessageRef;
	char *							szError		= NULL;
	
	SetErrorString( NULL );

	if( mUseLDAPPGP )
	{
		mLDAPPGPKeyServer->Query(inFilterRef, outFoundKeys);
		return;
	}
		
	if (! mIsOpen)
		ThrowPGPError_(kPGPError_ServerNotOpen);
	
	try {
		char *				attribute;
		PGPberElementRef	iterAttribute;
		const char *		attr[2] =
								{ (mExportFormat == kPGPExportFormat_Basic) ?
									kPGPKeyAttribute : kPGPKeyV2Attribute,
										0 };

		pgpError = PGPLDAPQueryFromFilter(inFilterRef, &query);
		ThrowIfPGPErrorOrLDAPCanceled_(pgpError);

		pgpError = pgpEventKeyServer(	mContext,
										mEventHandler,
										mEventHandlerData,
										(PGPKeyServerRef) this,
										kPGPKeyServerState_Querying);
		ThrowIfPGPErrorOrLDAPCanceled_(pgpError);
		
		// Send the query
		
		pgpError = PGPNewLDAPMessage( mLDAP, &message );
		if( IsPGPError( pgpError ) )
			ThrowPGPError_( kPGPError_ServerSearchFailed );

		pgpError = PGPldapSearchSync(	mLDAP,
							( mKeySpace == kPGPKeyServerKeySpace_Pending ) ?
								mBasePendingDN : 
								mBaseKeySpaceDN,
							kPGPldapScope_Subtree,
							query,
							(char **) attr,
							FALSE,
							message );

		ThrowIfLDAPCanceled_();

		switch( pgpError )
		{
			case kPGPError_NoErr:
				break;
			
			case kPGPError_LDAPInsufficientAccess:
				ThrowPGPError_( kPGPError_ServerAuthorizationFailed );
				break;
			
			case kPGPError_LDAPSizelimitExceeded:
			case kPGPError_LDAPTimelimitExceeded:
				partialResults = true;
				break;
			
			default:
				ThrowPGPError_(kPGPError_ServerSearchFailed);
				break;
		}
		PGPFreeData(query);
		query = NULL;
		
		// Get the results
		pgpError = pgpEventKeyServer(	mContext,
										mEventHandler,
										mEventHandlerData,
										(PGPKeyServerRef) this,
										kPGPKeyServerState_ProcessingResults);
		ThrowIfPGPErrorOrLDAPCanceled_(pgpError);
		pgpError = PGPNewKeyDB(mContext, &foundKeys);
		ThrowIfPGPErrorOrLDAPCanceled_(pgpError);

		pgpError = PGPldapFirstEntry( mLDAP, message, &nextMessage );
		if( IsPGPError( pgpError ) )
			ThrowPGPError_( kPGPError_ServerSearchFailed );

		while( PGPldapMessageRefIsValid( nextMessage ) )
		{
			pgpError = PGPldapFirstAttribute( mLDAP, nextMessage, &iterAttribute, 
				&attribute );
			if( IsPGPError( pgpError ) )
				ThrowPGPError_( kPGPError_ServerSearchFailed );

			while( IsntNull( attribute ) )
			{
				pgpError = PGPldapGetValues( mLDAP, nextMessage, 
					attribute,
					&value );
				if( IsPGPError( pgpError ) )
					ThrowPGPError_( kPGPError_ServerSearchFailed );

				if ((value != 0) && (*value != 0))
				{
					if (pgpCompareStringsIgnoreCase(attribute, attr[0]) == 0)
					{
						pgpError = PGPImport(
										mContext,
										&singleKeyDB,
										PGPOInputBuffer(	mContext,
															*value,
															strlen( *value ) ),
										PGPOLastOption( mContext ) );
						if( IsPGPError( pgpError ) )
							receivedBadKeys = true;
						else 
						{
							pgpError = PGPNewKeySet( singleKeyDB, &singleKeySet );
							ThrowIfPGPError_( pgpError );
							
							pgpError = PGPCopyKeys( singleKeySet, foundKeys, NULL );
							ThrowIfPGPError_( pgpError );
							
							PGPFreeKeySet( singleKeySet );
							singleKeySet = kInvalidPGPKeySetRef;
							
							PGPFreeKeyDB( singleKeyDB );
							singleKeyDB = kInvalidPGPKeyDBRef;
						}
					}
					(void) PGPFreeLDAPValues( value );
					value = NULL;
				}
				else
				{
					pgpError = PGPldapGetErrno( mLDAP, NULL, NULL, &ldapResult );
					if( IsPGPError( pgpError ) )
						ThrowPGPError_( kPGPError_ServerSearchFailed );

					if ( ( IsNull( value ) ) && ( ldapResult != kPGPldapResult_Success ) )
						ThrowPGPError_( kPGPError_ServerSearchFailed );
				}

				PGPFreeData( attribute );
				attribute = NULL;

				pgpError = PGPldapNextAttribute( mLDAP, nextMessage, iterAttribute, 
					&attribute );
				if( IsPGPError( pgpError ) )
					ThrowPGPError_( kPGPError_ServerSearchFailed );
			}

			pgpError = PGPldapNextEntry( mLDAP, nextMessage, &nextMessage );
			if( IsPGPError( pgpError ) )
				ThrowPGPError_( kPGPError_ServerSearchFailed );
		}

		PGPFreeLDAPMessage( message );
		message = kInvalidPGPldapMessageRef;

		*outFoundKeys = foundKeys;
	}
	
	catch (...) {
		if( singleKeySet != kInvalidPGPKeySetRef )
			PGPFreeKeySet( singleKeySet );

		if( singleKeyDB != kInvalidPGPKeyDBRef )
			PGPFreeKeyDB( singleKeyDB );

		if( foundKeys != kInvalidPGPKeyDBRef )
			PGPFreeKeyDB(foundKeys);

		if( value != 0 )
			PGPFreeLDAPValues( value );

		if( PGPldapMessageRefIsValid( message ) )
			PGPFreeLDAPMessage( message );

⌨️ 快捷键说明

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