📄 cldapkeyserver.cpp
字号:
/*____________________________________________________________________________
Copyright (C) 1997 Network Associates Inc. and affiliated companies.
All rights reserved.
$Id: CLDAPKeyServer.cpp,v 1.32.6.1 1999/06/13 21:12:31 heller 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 "pgpDebug.h"
#include "CLDAPKeyServer.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 * 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,
PGPKeyServerAccessType inAccessType,
PGPKeyServerKeySpace inKeySpace)
: CKeyServer(inContext, inHostName, inHostAddress, inHostPort, 0, inType),
mAccessType(inAccessType), mKeySpace(inKeySpace), mLDAP(0),
mBaseKeySpaceDN(0), mBasePendingDN(0),
mExportFormat(kPGPExportFormat_Basic)
{
}
CLDAPKeyServer::~CLDAPKeyServer()
{
}
void
CLDAPKeyServer::Open(
PGPtlsSessionRef inTLSSession)
{
StPreserveSocketsEventHandler preserve(this);
LDAPMessage * message = 0;
char ** value = 0;
SetErrorString(0);
try {
PGPError pgpError = kPGPError_NoErr;
int ldapResult = 0;
LDAPMessage * nextMessage = 0;
char * attribute;
BerElement * iterAttribute;
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);
mLDAP = ldap_open(mHostName, mHostPort);
if (mLDAP == 0) {
ThrowPGPError_(kPGPError_ServerOpenFailed);
}
ThrowIfLDAPCanceled_();
// Secure connection for HTTPS
if (mType == kPGPKeyServerProtocol_LDAPS) {
if ((mTLSSession == kInvalidPGPtlsSessionRef)
|| (PGPSocketsEstablishTLSSession(
(PGPSocketRef) mLDAP->ld_sb.sb_sd,
mTLSSession) != kPGPError_NoErr)) {
pgpError = pgpEventKeyServerTLS(
mContext,
mEventHandler,
mEventHandlerData,
(PGPKeyServerRef) this,
kPGPKeyServerState_TLSUnableToSecureConnection,
mTLSSession);
} else {
pgpError = pgpEventKeyServerTLS(
mContext,
mEventHandler,
mEventHandlerData,
(PGPKeyServerRef) this,
kPGPKeyServerState_TLSConnectionSecured,
mTLSSession);
mSecured = true;
mLDAP->tlsSession = mTLSSession;
}
ThrowIfPGPErrorOrLDAPCanceled_(pgpError);
}
// Retrieve key space distinguished names
ldapResult = ldap_search_s( mLDAP,
(char *) kPGPServerInfoCN,
LDAP_SCOPE_BASE,
(char *) kObjectClassAny,
(char **) attr,
0,
&message);
ThrowIfLDAPCanceled_();
if (ldapResult != LDAP_SUCCESS) {
ThrowPGPError_(kPGPError_ServerOpenFailed);
}
nextMessage = ldap_first_entry(mLDAP, message);
while (nextMessage != 0) {
attribute = ldap_first_attribute( mLDAP,
nextMessage,
&iterAttribute);
while (attribute != 0) {
value = ldap_get_values( mLDAP,
nextMessage,
attribute);
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;
}
}
ldap_value_free(value);
value = 0;
} else if ((value == 0)
&& (mLDAP->ld_errno != LDAP_SUCCESS)) {
if (mLDAP->ld_errno == LDAP_INSUFFICIENT_ACCESS) {
ThrowPGPError_(kPGPError_ServerAuthorizationFailed);
} else {
ThrowPGPError_(kPGPError_ServerOpenFailed);
}
}
attribute = ldap_next_attribute( mLDAP,
nextMessage,
iterAttribute);
}
pgpFixBeforeShip(am getting errors here)
/*
if (mLDAP->ld_errno != LDAP_SUCCESS) {
ThrowPGPError_(kPGPError_ServerOpenFailed);
}
*/ nextMessage = ldap_next_entry( mLDAP,
nextMessage);
}
if (/*(mLDAP->ld_errno != LDAP_SUCCESS) ||*/ (mBaseKeySpaceDN == 0)
|| (mBasePendingDN == 0)) {
ThrowPGPError_(kPGPError_ServerOpenFailed);
}
ldap_msgfree(message);
}
catch (...) {
delete[] mBaseKeySpaceDN;
mBaseKeySpaceDN = 0;
delete[] mBasePendingDN;
mBasePendingDN = 0;
if (value != 0) {
ldap_value_free(value);
}
if (message != 0) {
ldap_msgfree(message);
}
mTLSSession = kInvalidPGPtlsSessionRef;
mIsOpen = false;
mSecured = false;
if (mLDAP != 0) {
if (!mCanceled) {
SetErrorString(mLDAP->ld_error);
}
ldap_unbind(mLDAP);
mLDAP = 0;
}
if (mCanceled) {
mCanceled = false;
ThrowPGPError_(kPGPError_UserAbort);
} else {
throw;
}
}
}
void
CLDAPKeyServer::Close()
{
StPreserveSocketsEventHandler preserve(this);
pgpEventKeyServer( mContext,
mEventHandler,
mEventHandlerData,
(PGPKeyServerRef) this,
kPGPKeyServerState_Closing);
delete[] mBaseKeySpaceDN;
mBaseKeySpaceDN = 0;
delete[] mBasePendingDN;
mBasePendingDN = 0;
if (mLDAP != 0) {
// Both the TLS close and the socket close are done in the LDAP unbind
ldap_unbind(mLDAP);
mSecured = false;
mLDAP = 0;
}
CKeyServer::Close();
}
void
CLDAPKeyServer::Cancel()
{
CKeyServer::Cancel();
if (mIsBusy && (mLDAP != 0)
&& PGPSocketRefIsValid( (PGPSocketRef) mLDAP->ld_sb.sb_sd)) {
PGPCloseSocket((PGPSocketRef) mLDAP->ld_sb.sb_sd);
mLDAP->ld_sb.sb_sd = 0;
#if PGP_WIN32
if (PGPAsyncHostEntryRefIsValid(mLDAP->ld_sb.ref)) {
PGPCancelAsyncHostEntryRef(mLDAP->ld_sb.ref);
mLDAP->ld_sb.ref = kPGPInvalidAsyncHostEntryRef;
}
#endif
}
}
void
CLDAPKeyServer::Query(
PGPFilterRef inFilterRef,
PGPKeySetRef * outFoundKeys)
{
StPreserveSocketsEventHandler preserve(this);
char * query = 0;
LDAPMessage * message = 0;
char ** value = 0;
PGPKeySetRef foundKeys = kInvalidPGPKeySetRef;
PGPKeySetRef singleKeySet = kInvalidPGPKeySetRef;
PGPBoolean partialResults = false;
PGPBoolean receivedBadKeys = false;
int ldapResult = 0;
PGPError pgpError = kPGPError_NoErr;
LDAPMessage * nextMessage = 0;
SetErrorString(0);
if (! mIsOpen) {
ThrowPGPError_(kPGPError_ServerNotOpen);
}
try {
char * attribute;
BerElement * 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
ldapResult = ldap_search_s( mLDAP,
(mKeySpace ==
kPGPKeyServerKeySpace_Pending) ?
mBasePendingDN : mBaseKeySpaceDN,
LDAP_SCOPE_SUBTREE,
query,
(char **) attr,
0,
&message);
ThrowIfLDAPCanceled_();
switch (ldapResult) {
case LDAP_SUCCESS:
{
}
break;
case LDAP_INSUFFICIENT_ACCESS:
{
ThrowPGPError_(kPGPError_ServerAuthorizationFailed);
}
break;
case LDAP_SIZELIMIT_EXCEEDED:
case LDAP_TIMELIMIT_EXCEEDED:
{
partialResults = true;
}
break;
default:
{
ThrowPGPError_(kPGPError_ServerSearchFailed);
}
break;
}
PGPFreeData(query);
query = 0;
// Get the results
pgpError = pgpEventKeyServer( mContext,
mEventHandler,
mEventHandlerData,
(PGPKeyServerRef) this,
kPGPKeyServerState_ProcessingResults);
ThrowIfPGPErrorOrLDAPCanceled_(pgpError);
pgpError = PGPNewKeySet(mContext, &foundKeys);
ThrowIfPGPErrorOrLDAPCanceled_(pgpError);
nextMessage = ldap_first_entry(mLDAP, message);
while (nextMessage != 0) {
attribute = ldap_first_attribute( mLDAP,
nextMessage,
&iterAttribute);
while (attribute != 0) {
value = ldap_get_values( mLDAP,
nextMessage,
attribute);
if ((value != 0) && (*value != 0)) {
if (pgpCompareStringsIgnoreCase(attribute,
attr[0]) == 0) {
pgpError = PGPImportKeySet(
mContext,
&singleKeySet,
PGPOInputBuffer( mContext,
*value,
strlen(*value)),
PGPOLastOption(mContext));
if (IsPGPError(pgpError)) {
receivedBadKeys = true;
} else {
pgpError = PGPAddKeys(singleKeySet, foundKeys);
ThrowIfPGPError_(pgpError);
pgpError = PGPCommitKeyRingChanges(foundKeys);
ThrowIfPGPError_(pgpError);
PGPFreeKeySet(singleKeySet);
singleKeySet = kInvalidPGPKeySetRef;
}
}
ldap_value_free(value);
value = 0;
} else if ((value == 0)
&& (mLDAP->ld_errno != LDAP_SUCCESS)) {
ThrowPGPError_(kPGPError_ServerSearchFailed);
}
attribute = ldap_next_attribute( mLDAP,
nextMessage,
iterAttribute);
}
pgpFixBeforeShip(am getting errors here)
/*
if (mLDAP->ld_errno != LDAP_SUCCESS) {
ThrowPGPError_(kPGPError_ServerSearchFailed);
}
*/
nextMessage = ldap_next_entry( mLDAP,
nextMessage);
}
/* if (mLDAP->ld_errno != LDAP_SUCCESS) {
ThrowPGPError_(kPGPError_ServerSearchFailed);
}
*/ ldap_msgfree(message);
*outFoundKeys = foundKeys;
}
catch (...) {
if (singleKeySet != kInvalidPGPKeySetRef) {
PGPFreeKeySet(singleKeySet);
}
if (foundKeys != kInvalidPGPKeySetRef) {
PGPFreeKeySet(foundKeys);
}
if (value != 0) {
ldap_value_free(value);
}
if (message != 0) {
ldap_msgfree(message);
}
if (query != 0) {
PGPFreeData(query);
}
if (mCanceled) {
ThrowPGPError_(kPGPError_UserAbort);
} else {
SetErrorString(mLDAP->ld_error);
throw;
}
}
if (receivedBadKeys) {
ThrowPGPError_(kPGPError_ServerBadKeysInSearchResults);
}
if (partialResults) {
ThrowPGPError_(kPGPError_ServerPartialSearchResults);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -