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