📄 ckeyserver.cpp
字号:
PGPBoolean
CKeyServer::Free()
{
PGPBoolean freedServer = FALSE;
mRefCount--;
if (mRefCount == 0) {
if (mIsOpen) {
ThrowPGPError_(kPGPError_ServerOpen);
}
delete this;
freedServer = TRUE;
}
return( freedServer );
}
CKeyServer::CKeyServer(
PGPContextRef inContext,
const char * inHostName,
PGPUInt32 inHostAddress,
PGPUInt16 inHostPort,
const char * inPath,
PGPKeyServerProtocol inType)
: mContext(inContext), mHostName(0), mHostPort(inHostPort),
mHostAddress(inHostAddress), mPath(0), mType(inType), mEventHandler(0),
mEventHandlerData(0), mTLSSession(kInvalidPGPtlsSessionRef),
mErrorString(0), mSecured(false), mIsBusy(false), mIsOpen(false),
mCanceled(false), mRefCount(1)
#if PGP_WIN32
, mAsyncHostEntryRef(kPGPInvalidAsyncHostEntryRef)
#endif
{
if (inHostName != 0) {
mHostName = new char[strlen(inHostName) + 1];
if (mHostName == 0) {
ThrowPGPError_(kPGPError_OutOfMemory);
}
strcpy(mHostName, inHostName);
}
if (inPath != 0) {
mPath = new char[strlen(inPath) + 2];
if (mPath == 0) {
ThrowPGPError_(kPGPError_OutOfMemory);
}
*mPath = '/';
strcpy(mPath + 1, inPath);
}
}
CKeyServer::~CKeyServer()
{
delete[] mHostName;
delete[] mErrorString;
delete[] mPath;
}
void
CKeyServer::SetIdleEventHandler(
PGPEventHandlerProcPtr inCallback,
PGPUserValue inUserData)
{
SetThreadIdleEventHandler(inCallback, inUserData);
}
void
CKeyServer::GetIdleEventHandler(
PGPEventHandlerProcPtr * outCallback,
PGPUserValue * outUserData)
{
GetThreadIdleEventHandler(outCallback, outUserData);
}
PGPError
CKeyServer::KeyServerIdleEventHandler(
PGPContextRef inContext,
PGPEvent * inEvent,
PGPUserValue callBackArg)
{
PGPEventHandlerProcPtr eventHandler;
PGPUserValue eventHandlerData;
PGPError result;
(void) inContext;
(void) inEvent;
GetThreadIdleEventHandler(&eventHandler, &eventHandlerData);
if (eventHandler != 0) {
PGPContextRef context = kInvalidPGPContextRef;
PGPEvent theEvent;
pgpClearMemory(&theEvent, sizeof(theEvent));
theEvent.type = kPGPEvent_KeyServerIdleEvent;
theEvent.job = 0;
theEvent.data.keyServerIdleData.keyServerRef =
(PGPKeyServerRef) callBackArg;
if (callBackArg != 0) {
context = ((CKeyServer *) callBackArg)->mContext;
}
result = eventHandler(context, &theEvent, eventHandlerData);
if (callBackArg != 0) {
if (result != kPGPError_NoErr) {
((CKeyServer *) callBackArg)->mCanceled = true;
} else if (((CKeyServer *) callBackArg)->mCanceled) {
result = kPGPError_UserAbort;
}
}
} else {
result = kPGPError_NoErr;
}
return result;
}
void
CKeyServer::Open(
PGPtlsSessionRef inTLSSession)
{
if (mIsOpen) {
ThrowPGPError_(kPGPError_ServerOpen);
}
mTLSSession = inTLSSession;
InitializeHostNameAndAddress(&mHostName, &mHostAddress);
mIsOpen = true;
}
void
CKeyServer::Close()
{
mTLSSession = kInvalidPGPtlsSessionRef;
mIsOpen = false;
mSecured = false;
mCanceled = false;
}
void
CKeyServer::Cancel()
{
StPreserveSocketsEventHandler preserve(this);
mCanceled = true;
#if PGP_WIN32
if (PGPAsyncHostEntryRefIsValid(mAsyncHostEntryRef)) {
PGPCancelAsyncHostEntryRef(mAsyncHostEntryRef);
mAsyncHostEntryRef = kPGPInvalidAsyncHostEntryRef;
}
#endif
}
void
CKeyServer::GetHostName(
char ** outHostName)
{
InitializeHostNameAndAddress(&mHostName, &mHostAddress);
*outHostName = (char *) PGPNewData( PGPGetContextMemoryMgr(mContext),
strlen(mHostName) + 1,
kPGPMemoryMgrFlags_None);
if (*outHostName == 0) {
ThrowPGPError_(kPGPError_OutOfMemory);
}
strcpy(*outHostName, mHostName);
}
void
CKeyServer::GetAddress(
PGPUInt32 & outAddress)
{
InitializeHostNameAndAddress(&mHostName, &mHostAddress);
outAddress = mHostAddress;
}
void
CKeyServer::GetPath(
char ** outPath)
{
*outPath = (char *) PGPNewData( PGPGetContextMemoryMgr(mContext),
strlen(mPath) + 1,
kPGPMemoryMgrFlags_None);
if (*outPath == 0) {
ThrowPGPError_(kPGPError_OutOfMemory);
}
strcpy(*outPath, mPath);
}
void
CKeyServer::GetErrorString(
char ** outErrorString)
{
if (mErrorString != 0) {
*outErrorString = (char *) PGPNewData(
PGPGetContextMemoryMgr(mContext),
strlen(mErrorString) + 1,
kPGPMemoryMgrFlags_None);
if (*outErrorString == 0) {
ThrowPGPError_(kPGPError_OutOfMemory);
}
strcpy(*outErrorString, mErrorString);
}
}
void
CKeyServer::SetErrorString(
const char * inErrorString)
{
delete[] mErrorString;
if (inErrorString == 0) {
mErrorString = 0;
} else {
mErrorString = new char[strlen(inErrorString) + 1];
if (mErrorString != 0) {
strcpy(mErrorString, inErrorString);
}
}
}
void
CKeyServer::InitOperation()
{
SetErrorString(0);
if (! mIsOpen) {
ThrowPGPError_(kPGPError_ServerNotOpen);
}
}
void
CKeyServer::InitializeHostNameAndAddress(
char ** inHostName,
PGPUInt32 * inHostAddress)
{
StPreserveSocketsEventHandler preserve(this);
PGPHostEntry * hostEntry = 0;
if (*inHostName != 0) {
PGPUInt32 tempAddress = PGPDottedToInternetAddress(*inHostName);
if ((PGPInt32) tempAddress != kPGPSockets_Error) {
*inHostAddress = PGPNetToHostLong(tempAddress);
delete *inHostName;
*inHostName = 0;
}
}
#if PGP_WIN32
PGPError err;
char h_name[256];
#endif
if (*inHostName == 0) {
PGPInternetAddress theAddress;
char * theHostName;
theAddress.s_addr = PGPHostToNetLong(*inHostAddress);
#if PGP_WIN32
err = PGPStartAsyncGetHostByAddress(theAddress.s_addr,
&mAsyncHostEntryRef);
ThrowIfPGPError_(err);
err = PGPWaitForGetHostByAddress(mAsyncHostEntryRef,
h_name, 256);
mAsyncHostEntryRef = kPGPInvalidAsyncHostEntryRef;
if (IsPGPError(err)) {
#else
hostEntry = PGPGetHostByAddress((const char *) &theAddress,
sizeof(PGPInternetAddress),
kPGPProtocolFamilyInternet);
if (hostEntry == 0) {
#endif
PGPInternetAddress address;
address.s_addr = PGPHostToNetLong(*inHostAddress);
theHostName = PGPInternetAddressToDottedString(address);
if (theHostName == 0) {
ThrowPGPError_(kPGPError_UnknownError);
}
} else {
#if PGP_WIN32
theHostName = h_name;
#else
theHostName = hostEntry->h_name;
#endif
}
*inHostName = new char[strlen(theHostName) + 1];
if (*inHostName == 0) {
ThrowPGPError_(kPGPError_OutOfMemory);
}
strcpy(*inHostName, theHostName);
} else if (*inHostAddress == 0) {
#if PGP_WIN32
err = PGPStartAsyncGetHostByName(*inHostName, &mAsyncHostEntryRef);
ThrowIfPGPError_(err);
err = PGPWaitForGetHostByName(mAsyncHostEntryRef, inHostAddress);
mAsyncHostEntryRef = kPGPInvalidAsyncHostEntryRef;
ThrowIfPGPError_(err);
*inHostAddress = PGPNetToHostLong(*inHostAddress);
#else
hostEntry = PGPGetHostByName(*inHostName);
if (hostEntry == 0) {
ThrowPGPError_(PGPGetLastSocketsError());
}
*inHostAddress = PGPNetToHostLong(
*((PGPUInt32 *)hostEntry->h_addr));
#endif
}
}
#if PGP_MACINTOSH
void
CKeyServer::CreateThreadStorage(
SThreadContext ** outContext)
{
OSStatus err;
ThreadID theThreadID;
map<ThreadID, SThreadContext>::iterator theIterator;
SThreadContext * theResult = nil;
try {
err = ::GetCurrentThread(&theThreadID);
if (err != noErr) {
ThrowPGPError_(err);
}
theIterator = sThreadContextMap.find(theThreadID);
if (theIterator != sThreadContextMap.end()) {
theResult = new SThreadContext;
if (theResult == 0) {
ThrowPGPError_(kPGPError_OutOfMemory);
}
*theResult = (*theIterator).second;
} else {
SThreadContext tempContext = {0, };
pgpLeaksSuspend();
sThreadContextMap[theThreadID] = tempContext;
pgpLeaksResume();
theIterator = sThreadContextMap.find(theThreadID);
if (theIterator == sThreadContextMap.end()) {
ThrowPGPError_(kPGPError_OutOfMemory);
}
}
(*theIterator).second.idleEventHandler = 0;
(*theIterator).second.idleEventHandlerData = 0;
}
catch (...) {
delete theResult;
throw;
}
*outContext = theResult;
}
void
CKeyServer::DisposeThreadStorage(
SThreadContext * inContext)
{
ThreadID theThreadID;
OSStatus err;
err = ::GetCurrentThread(&theThreadID);
if (err != noErr) {
ThrowPGPError_(err);
}
if (inContext != 0) {
sThreadContextMap[theThreadID] = *inContext;
delete inContext;
} else {
map<ThreadID, SThreadContext>::iterator theIterator;
theIterator = sThreadContextMap.find(theThreadID);
if (theIterator != sThreadContextMap.end()) {
sThreadContextMap.erase(theThreadID);
}
}
}
static SThreadContext *
GetThreadContext()
{
OSStatus err;
ThreadID theThreadID;
map<ThreadID, SThreadContext>::iterator theIterator;
SThreadContext * theResult = nil;
try {
err = ::GetCurrentThread(&theThreadID);
if (err != noErr) {
ThrowPGPError_(err);
}
theIterator = sThreadContextMap.find(theThreadID);
if (theIterator == sThreadContextMap.end()) {
ThrowPGPError_(kPGPError_SocketsNoStaticStorage);
}
theResult = &(*theIterator).second;
}
catch (...) {
}
return theResult;
}
void
CKeyServer::GetThreadIdleEventHandler(
PGPEventHandlerProcPtr * outCallback,
PGPUserValue * outUserData)
{
SThreadContext * theContext = GetThreadContext();
if (theContext != 0) {
*outCallback = theContext->idleEventHandler;
*outUserData = theContext->idleEventHandlerData;
} else {
*outCallback = 0;
*outUserData = 0;
}
}
void
CKeyServer::SetThreadIdleEventHandler(
PGPEventHandlerProcPtr inCallback,
PGPUserValue inUserData)
{
SThreadContext * theContext = GetThreadContext();
if (theContext != 0) {
theContext->idleEventHandler = inCallback;
theContext->idleEventHandlerData = inUserData;
}
}
#elif PGP_WIN32
void
CKeyServer::GetThreadIdleEventHandler(
PGPEventHandlerProcPtr * outCallback,
PGPUserValue * outUserData)
{
PGPRMWOLockStartReading(&sThreadLock);
*outCallback = (PGPEventHandlerProcPtr)
TlsGetValue(sIdleEventHandlerIndex);
*outUserData = (PGPUserValue) TlsGetValue(sIdleEventHandlerDataIndex);
PGPRMWOLockStopReading(&sThreadLock);
}
void
CKeyServer::SetThreadIdleEventHandler(
PGPEventHandlerProcPtr inCallback,
PGPUserValue inUserData)
{
PGPRMWOLockStartWriting(&sThreadLock);
if (TlsSetValue(sIdleEventHandlerIndex, inCallback)) {
if (! TlsSetValue(sIdleEventHandlerDataIndex, inUserData)) {
TlsSetValue(sIdleEventHandlerIndex, 0);
}
}
PGPRMWOLockStopWriting(&sThreadLock);
}
void
CKeyServer::CreateThreadStorage(
SThreadContext ** outContext)
{
*outContext = new SThreadContext;
if (*outContext == 0) {
ThrowPGPError_(kPGPError_OutOfMemory);
}
GetThreadIdleEventHandler( &(*outContext)->idleEventHandler,
&(*outContext)->idleEventHandlerData);
}
void
CKeyServer::DisposeThreadStorage(
SThreadContext * inContext)
{
if (inContext != 0) {
SetThreadIdleEventHandler( inContext->idleEventHandler,
inContext->idleEventHandlerData);
delete inContext;
}
}
#elif PGP_UNIX
void
CKeyServer::GetThreadIdleEventHandler(
PGPEventHandlerProcPtr * outCallback,
PGPUserValue * outUserData)
{
(void) outCallback;
(void) outUserData;
ThrowPGPError_(kPGPError_ServerOperationNotSupported);
}
void
CKeyServer::SetThreadIdleEventHandler(
PGPEventHandlerProcPtr inCallback,
PGPUserValue inUserData)
{
(void) inCallback;
(void) inUserData;
ThrowPGPError_(kPGPError_ServerOperationNotSupported);
}
void
CKeyServer::CreateThreadStorage(
SThreadContext ** outContext)
{
*outContext = 0;
}
void
CKeyServer::DisposeThreadStorage(
SThreadContext * inContext)
{
(void) inContext;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -