📄 cldapkeyserver.cpp
字号:
void
CLDAPKeyServer::Upload(
PGPKeyUploadPreference inSendPrivateKeys,
PGPKeySetRef inKeysToUpload,
PGPKeySetRef * outKeysThatFailed)
{
StPreserveSocketsEventHandler preserve(this);
char * keySpace = 0;
char * exportedKey = 0;
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 = 0;
PGPBoolean exportPrivateKeys = false;
if( mKeySpace == kPGPKeyServerKeySpace_Pending )
{
keySpaceSuffix = mBasePendingDN;
}
else
{
keySpaceSuffix = mBaseKeySpaceDN;
}
SetErrorString(0);
if (! mIsOpen) {
ThrowPGPError_(kPGPError_ServerNotOpen);
}
if (inSendPrivateKeys == kPGPPrivateKeyAllowed) {
if (mType != kPGPKeyServerProtocol_LDAPS) {
ThrowPGPError_(kPGPError_ServerOperationRequiresTLS);
}
exportPrivateKeys = true;
}
try {
PGPKeyRef key;
PGPSize bufSize;
int ldapResult;
char * strVals[2] = { 0, 0 };
LDAPMod mod = { 0,
(char *) ((mExportFormat ==
kPGPExportFormat_Basic) ?
kPGPKeyAttribute : kPGPKeyV2Attribute),
{strVals},
0 };
LDAPMod * attrs[2] = { &mod, 0 };
pgpError = pgpEventKeyServer( mContext,
mEventHandler,
mEventHandlerData,
(PGPKeyServerRef) this,
kPGPKeyServerState_Uploading);
ThrowIfPGPErrorOrLDAPCanceled_(pgpError);
// Create error set
pgpError = PGPNewKeySet(mContext, &errorKeySet);
ThrowIfPGPError_(pgpError);
// Create keyspace
keySpace = new char[strlen(kAddAndRequestDNPrefix) + strlen(
keySpaceSuffix) + 1];
if (keySpace == 0) {
ThrowPGPError_(kPGPError_OutOfMemory);
}
sprintf(keySpace, "%s%s", kAddAndRequestDNPrefix, keySpaceSuffix);
// Iterate through keys uploading them one at a time
pgpError = PGPOrderKeySet( inKeysToUpload,
kPGPAnyOrdering,
&keyList);
ThrowIfPGPError_(pgpError);
pgpError = PGPNewKeyIter(keyList, &keyIter);
ThrowIfPGPError_(pgpError);
while ((pgpError = PGPKeyIterNext(keyIter, &key)) == kPGPError_NoErr) {
// Send to server
pgpError = PGPNewSingletonKeySet(key, &singleKeySet);
ThrowIfPGPError_(pgpError);
if (! sendRequest) {
pgpError = PGPExportKeySet(
singleKeySet,
PGPOExportPrivateKeys(mContext,
exportPrivateKeys),
PGPOAllocatedOutputBuffer(
mContext,
(void **) &exportedKey,
MAX_PGPSize,
&bufSize),
PGPOExportFormat(mContext,
mExportFormat),
PGPOLastOption(mContext));
ThrowIfPGPError_(pgpError);
strVals[0] = exportedKey;
ldapResult = ldap_add_s( mLDAP,
keySpace,
attrs);
PGPFreeData(exportedKey);
exportedKey = 0;
if (ldapResult != LDAP_SUCCESS) {
partialFailure = true;
PGPAddKeys(singleKeySet, errorKeySet);
switch (ldapResult) {
case LDAP_ALREADY_EXISTS:
{
keyAlreadyExists = true;
}
break;
case LDAP_INSUFFICIENT_ACCESS:
{
sendRequest = true;
}
break;
case LDAP_INVALID_CREDENTIALS:
{
failedPolicy = true;
}
break;
}
}
}
// Need to send a signed request
if (sendRequest && (! mSecured)) {
pgpError = SendRequest(kAdd, singleKeySet, 0);
if (IsPGPError(pgpError)) {
partialFailure = true;
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);
}
}
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 {
SetErrorString(mLDAP->ld_error);
throw;
}
}
}
void
CLDAPKeyServer::Delete(
PGPKeySetRef inKeysToDelete,
PGPKeySetRef * outKeysThatFailed)
{
DeleteOrDisable(true, inKeysToDelete, outKeysThatFailed);
}
void
CLDAPKeyServer::Disable(
PGPKeySetRef inKeysToDisable,
PGPKeySetRef * outKeysThatFailed)
{
DeleteOrDisable(false, inKeysToDisable, outKeysThatFailed);
}
void
CLDAPKeyServer::DeleteOrDisable(
PGPBoolean inDelete,
PGPKeySetRef inKeySet,
PGPKeySetRef * outKeysThatFailed)
{
StPreserveSocketsEventHandler preserve(this);
const char *action = 0;
PGPError pgpError = kPGPError_NoErr;
SetErrorString(0);
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 {
SetErrorString(mLDAP->ld_error);
throw;
}
}
}
PGPError
CLDAPKeyServer::SendRequest(
const char * inAction,
PGPKeySetRef inKeySetRef,
PGPKeySetRef * outKeysThatFailed)
{
PGPError result = kPGPError_NoErr;
char * request = 0;
char * signedRequest = 0;
PGPKeyListRef keyList = kInvalidPGPKeyListRef;
PGPKeyIterRef keyIter = kInvalidPGPKeyIterRef;
char * keySpace = 0;
char * error = 0;
PGPKeySetRef singleKeySet = kInvalidPGPKeySetRef;
try {
PGPUInt32 requestSize = 0;
PGPKeyID keyID;
char keyIDString[kPGPMaxKeyIDStringSize];
const char * location = 0;
PGPUInt32 total;
PGPError pgpError = kPGPError_NoErr;
PGPOptionListRef options;
PGPKeyRef key;
PGPSize dummy;
char * strVals[2] = { 0, 0 };
LDAPMod mod = { 0, (char *) kRequestPGPRequest,
{strVals}, 0 };
LDAPMod * attrs[2] = { &mod, 0 };
int ldapResult = 0;
PGPUInt32 numAlgorithms;
char * nextItem = 0;
PGPUInt32 i = 0;
PGPPublicKeyAlgorithmInfo algorithmInfo;
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, kPGPAnyOrdering, &keyList);
ThrowIfPGPError_(pgpError);
pgpError = PGPNewKeyIter(keyList, &keyIter);
ThrowIfPGPError_(pgpError);
while ((pgpError = PGPKeyIterNext(keyIter, &key)) == kPGPError_NoErr) {
pgpError = PGPGetKeyIDFromKey(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 = 0;
}
// Send the request
mod.mod_values[0] = (mSecured) ? request : signedRequest;
keySpace = new char[strlen(kAddAndRequestDNPrefix)
+ strlen(mBaseKeySpaceDN) + 1];
if (keySpace == 0) {
ThrowPGPError_(kPGPError_OutOfMemory);
}
sprintf(keySpace, "%s%s", kAddAndRequestDNPrefix, mBaseKeySpaceDN);
ldapResult = ldap_add_s( mLDAP,
keySpace,
attrs);
ThrowIfLDAPCanceled_();
delete[] keySpace;
keySpace = 0;
if (mSecured) {
delete[] request;
request = 0;
} else {
PGPFreeData(signedRequest);
signedRequest = 0;
}
// Scan for error keys
if ((outKeysThatFailed != 0) && (mLDAP->ld_error != 0)
&& (*mLDAP->ld_error != '\0')) {
char * currentItem = 0;
error = new char[strlen(mLDAP->ld_error) + 1];
if (error == 0) {
ThrowPGPError_(kPGPError_OutOfMemory);
}
strcpy(error, mLDAP->ld_error);
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 = PGPGetKeyIDFromString(currentItem, &keyID);
ThrowIfPGPError_(pgpError);
pgpError = PGPCountPublicKeyAlgorithms(&numAlgorithms);
ThrowIfPGPError_(pgpError);
for (i = 0; i < numAlgorithms; i++) {
pgpError = PGPGetIndexedPublicKeyAlgorithmInfo( i,
&algorithmInfo);
ThrowIfPGPError_(pgpError);
pgpError = PGPGetKeyByKeyID(
inKeySetRef,
&keyID,
algorithmInfo.algID,
&key);
if (IsntPGPError(pgpError)
&& (key != kInvalidPGPKeyRef)) {
break;
}
}
if (*outKeysThatFailed == kInvalidPGPKeySetRef) {
pgpError = PGPNewKeySet(mContext, outKeysThatFailed);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -