📄 cldapkeyserver.cpp
字号:
/*____________________________________________________________________________
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 + -