📄 pgprpcserver.c
字号:
/*____________________________________________________________________________
Copyright (C) 2002 PGP Corporation
All rights reserved.
$Id: pgpRPCServer.c,v 1.97 2002/08/06 20:11:13 dallen Exp $
____________________________________________________________________________*/
#if PGP_WIN32
#include <windows.h>
#elif PGP_UNIX
#include <sys/types.h>
#include <unistd.h>
#include <pwd.h>
#endif
#include "pgpPubTypes.h"
#include "pgpErrors.h"
#include "pgpFileSpec.h"
#include "pgpUtilities.h"
#include "pgpKeys.h"
#include "pgpPublicKey.h"
#include "pgpContext.h"
#include "pgpRPCMsg.h"
#include "pgpKeyPriv.h"
#include "pgpRandomPoolPriv.h"
#include "pgpRndSeed.h"
#include "pgpPassCach.h"
/* Global context used by backend */
PGPContextRef gCtx = NULL;
/* Linked list of all connection refs */
static pgpRPCconnection *sConnectRefs;
#if PGP_DEBUG
#if PGP_WIN32
void DbgPrintf(char *mesg, ...);
#else
#define DbgPrintf printf
#endif
#else
#define DbgPrintf(x)
#endif
void
pgpRPCCreateBEContext()
{
PGPError err;
// Make sure we DONT use RPC.
// Make sure we DONT start the FrontEndThread.
err = PGPsdkInit(kPGPFlags_ForceLocalExecution);
if ( IsPGPError( err ) ) {
return;
}
err = PGPNewContext( kPGPsdkAPIVersion, &gCtx );
if ( IsPGPError( err ) ) {
return;
}
}
void
pgpRPCCleanupBEContext()
{
if (gCtx != kInvalidPGPContextRef)
PGPFreeContext(gCtx);
PGPsdkCleanup();
return;
}
/*
* Messages received by this service.
* Each of the sRecv_XXX functions must construct the
* PGPPackMsg to be returned to the client.
*/
static void
sRecv_Connect(PGPPackMsg *pkt, PGPPackMsg *rpkt)
{
PGPInt32 client_ver;
PGPUInt32 conn_ref, ID, EventHandle[3];
client_ver = unpack_int32(pkt);
/*
* Check for clients talking the wrong version. PGPMSG_PROTOCOL_REV
* needs to get updated when the protocol changes.
*/
if (client_ver != PGPMSG_PROTOCOL_REV) {
rpkt->status = kPGPError_RPCGarbledMsg;
return;
}
ID = unpack_uint32(pkt);
EventHandle[0] = unpack_uint32(pkt);
EventHandle[1] = unpack_uint32(pkt);
EventHandle[2] = unpack_uint32(pkt);
conn_ref = pgpRPCAllocConnection();
#if PGP_WIN32
// convert the handle to one we can use from the backend process
{
HANDLE hProcess;
PGPUInt32 i;
hProcess = OpenProcess (PROCESS_DUP_HANDLE, FALSE, ID);
for( i=0; i<sizeof(EventHandle)/sizeof(EventHandle[0]); i++ )
{
DuplicateHandle (hProcess, (HANDLE)EventHandle[i],
GetCurrentProcess (), (HANDLE*)&EventHandle[i],
0, FALSE, DUPLICATE_SAME_ACCESS);
((pgpRPCconnection *)conn_ref)->EventHandle[i] = EventHandle[i];
}
CloseHandle (hProcess);
}
/*
* Fill-in UserName in connection.
*/
{
char namebuf[256];
DWORD namebuflen = sizeof(namebuf);
if (GetUserName(namebuf, &namebuflen) != 0) {
PGPByte *cp;
cp = PGPNewData(PGPGetDefaultMemoryMgr(), namebuflen, 0);
if (cp == NULL) {
rpkt->status = kPGPError_UnknownError;
return;
}
pgpCopyMemory(namebuf, cp, namebuflen);
((pgpRPCconnection *)conn_ref)->UserName = cp;
}
}
#else /* if PGP_UNIX */
{
PGPByte *cp;
struct passwd *pw;
((pgpRPCconnection *)conn_ref)->ThreadID = ID;
/*
* Fill-in UserName in connection.
* On UNIX/LINUX, use ASCII representation of UID.
*/
pw = getpwuid(getuid());
cp = PGPNewData(PGPGetDefaultMemoryMgr(), strlen(pw->pw_name)+1, 0);
if (cp == NULL) {
rpkt->status = kPGPError_UnknownError;
return;
}
strcpy(cp, pw->pw_name);
((pgpRPCconnection *)conn_ref)->UserName = cp;
((pgpRPCconnection *)conn_ref)->uid = getuid();
((pgpRPCconnection *)conn_ref)->gid = getgid();
((pgpRPCconnection *)conn_ref)->pid = getpid();
}
#endif
/* Maintain linked list of connectrefs */
((pgpRPCconnection *)conn_ref)->next = sConnectRefs;
sConnectRefs = (pgpRPCconnection *)conn_ref;
pgpPassphraseCacheAddClient( gCtx, (PGPConnectRef) conn_ref );
pack_int32(rpkt, (PGPUInt32)conn_ref);
rpkt->status = 0;
}
/* Called when we free context in front end */
static void
sRecv_Disconnect(PGPPackMsg *pkt, PGPPackMsg *rpkt)
{
pgpRPCconnection *conn_ref;
conn_ref = (pgpRPCconnection *)pkt->connect_ref;
/* Remove conn_ref from linked list */
pgpPassphraseCacheRemoveClient( (PGPConnectRef) conn_ref );
if( sConnectRefs == conn_ref )
{
sConnectRefs = conn_ref->next;
} else {
pgpRPCconnection *sc;
for( sc = sConnectRefs; IsntNull( sc->next ); sc=sc->next )
{
if( sc->next == conn_ref )
{
sc->next = conn_ref->next;
break;
}
}
}
if( IsntNull( conn_ref->UserName ) )
PGPFreeData( conn_ref->UserName );
#if PGP_WIN32
if( conn_ref->EventHandle[0] )
CloseHandle ( (HANDLE)(conn_ref->EventHandle[0]) );
if( conn_ref->EventHandle[1] )
CloseHandle ( (HANDLE)(conn_ref->EventHandle[1]) );
if( conn_ref->EventHandle[2] )
CloseHandle ( (HANDLE)(conn_ref->EventHandle[2]) );
#endif
pgpClearMemory( conn_ref, sizeof(*conn_ref) );
PGPFreeData( conn_ref );
/* Refresh random seed file on disk when we close a frontend context */
pgpSaveGlobalRandomPool( );
rpkt->status = 0;
}
static void
sRecv_Reconnect(PGPPackMsg *pkt, PGPPackMsg *rpkt)
{
pgpRPCconnection *conn_ref;
conn_ref = (pgpRPCconnection *)pkt->connect_ref;
if( IsntNull( conn_ref->UserName ) )
PGPFreeData( conn_ref->UserName );
#if PGP_WIN32
/*
* Fill-in UserName in connection.
*/
{
char namebuf[256];
DWORD namebuflen = sizeof(namebuf);
if (GetUserName(namebuf, &namebuflen) != 0) {
PGPByte *cp;
cp = PGPNewData(PGPGetDefaultMemoryMgr(), namebuflen, 0);
if (cp == NULL) {
rpkt->status = kPGPError_UnknownError;
return;
}
pgpCopyMemory(namebuf, cp, namebuflen);
((pgpRPCconnection *)conn_ref)->UserName = cp;
}
}
#else /* if PGP_UNIX */
{
PGPByte *cp;
struct passwd *pw;
/*
* Fill-in UserName in connection.
* On UNIX/LINUX, use ASCII representation of UID.
*/
pw = getpwuid(getuid());
cp = PGPNewData(PGPGetDefaultMemoryMgr(), strlen(pw->pw_name)+1, 0);
if (cp == NULL) {
rpkt->status = kPGPError_UnknownError;
return;
}
strcpy(cp, pw->pw_name);
((pgpRPCconnection *)conn_ref)->UserName = cp;
((pgpRPCconnection *)conn_ref)->uid = getuid();
((pgpRPCconnection *)conn_ref)->gid = getgid();
((pgpRPCconnection *)conn_ref)->pid = getpid();
}
#endif
rpkt->status = 0;
}
static void
sRecv_FetchObjectData(PGPPackMsg *pkt, PGPPackMsg *rpkt)
{
PGPError err;
PGPInt32 id;
PGPByte *bufPtr;
PGPSize bufSize;
id = unpack_int32(pkt);
err = pgpFetchObjectData_back(
gCtx,
id,
&bufPtr,
&bufSize);
rpkt->status = err;
if (IsPGPError(err)) return;
pack_opaque(rpkt, bufPtr, bufSize);
if( IsntNull( bufPtr ) )
PGPFreeData( bufPtr );
}
static void
sRecv_GetKeyByKeyID(PGPPackMsg *pkt, PGPPackMsg *rpkt)
{
PGPUInt32 dbid;
PGPKeyID *keyIDIn;
PGPBoolean dummyOK, deletedOK;
PGPError err;
PGPUInt32 outID;
PGPSize keyIDSize;
dbid = unpack_uint32(pkt);
unpack_opaque(pkt, (void **) &keyIDIn, &keyIDSize);
dummyOK = unpack_bool(pkt);
deletedOK = unpack_bool(pkt);
err = pgpGetKeyByKeyID_back(
gCtx,
dbid,
keyIDIn,
dummyOK,
deletedOK,
&outID);
rpkt->status = err;
if (IsPGPError(err)) return;
pack_uint32(rpkt, outID);
}
static void
sRecv_KeyEncrypt(PGPPackMsg *pkt, PGPPackMsg *rpkt)
{
PGPError err;
PGPUInt32 id;
PGPByte *inbuf;
PGPSize inbuflen;
PGPPublicKeyMessageFormat format;
PGPByte *outbuf;
PGPSize outbuflen;
id = unpack_uint32(pkt);
unpack_opaque(pkt, (void **) &inbuf, &inbuflen);
format = (PGPPublicKeyMessageFormat)unpack_uint32(pkt);
err = pgpKeyEncrypt_back(
gCtx,
id,
inbuf,
inbuflen,
format,
&outbuf,
&outbuflen);
rpkt->status = err;
if (IsPGPError(err)) return;
pack_opaque(rpkt, outbuf, outbuflen);
if( IsntNull( outbuf ) )
PGPFreeData( outbuf );
}
static void
sRecv_KeyDecrypt(PGPPackMsg *pkt, PGPPackMsg *rpkt)
{
PGPError err;
PGPUInt32 id;
PGPByte *passphrase;
PGPSize pplen;
PGPBoolean hashedPhrase;
PGPUInt32 cacheTimeOut;
PGPBoolean cacheGlobal;
PGPByte *inbuf;
PGPSize inbuflen;
PGPPublicKeyMessageFormat format;
PGPByte *outbuf;
PGPSize outbuflen;
id = unpack_uint32(pkt);
unpack_opaque(pkt, (void **) &passphrase, &pplen);
hashedPhrase = unpack_bool(pkt);
cacheTimeOut = unpack_uint32(pkt);
cacheGlobal = unpack_bool(pkt);
unpack_opaque(pkt, (void **) &inbuf, &inbuflen);
format = (PGPPublicKeyMessageFormat)unpack_uint32(pkt);
err = pgpKeyDecrypt_back(
gCtx,
id,
passphrase,
pplen,
hashedPhrase,
cacheTimeOut,
cacheGlobal,
inbuf,
inbuflen,
format,
&outbuf,
&outbuflen);
rpkt->status = err;
if (IsPGPError(err)) return;
pack_opaque(rpkt, outbuf, outbuflen);
if( IsntNull( outbuf ) )
PGPFreeData( outbuf );
}
static void
sRecv_KeyVerify(PGPPackMsg *pkt, PGPPackMsg *rpkt)
{
PGPByte *inbuf;
PGPSize inbuflen;
PGPHashAlgorithm hashalg;
PGPByte *hash;
PGPSize hashlen;
PGPPublicKeyMessageFormat format;
PGPInt32 n;
PGPUInt32 id;
id = unpack_uint32(pkt);
unpack_opaque(pkt, (void **) &inbuf, &inbuflen);
hashalg = (PGPHashAlgorithm) unpack_uint32(pkt);
unpack_opaque(pkt, (void **) &hash, &hashlen);
format = (PGPPublicKeyMessageFormat)unpack_uint32(pkt);
n = pgpKeyVerify_back(
gCtx,
id,
inbuf,
inbuflen,
hashalg,
hash,
hashlen,
format);
pack_int32(rpkt, n);
rpkt->status = kPGPError_NoErr;
}
static void
sRecv_KeySign(PGPPackMsg *pkt, PGPPackMsg *rpkt)
{
PGPError err;
PGPUInt32 id;
PGPByte *passphrase;
PGPSize pplen;
PGPBoolean hashedPhrase;
PGPUInt32 cacheTimeOut;
PGPBoolean cacheGlobal;
PGPHashAlgorithm hashalg;
PGPByte *hash;
PGPSize hashlen;
PGPPublicKeyMessageFormat format;
PGPByte *outbuf;
PGPSize outbuflen;
id = unpack_uint32(pkt);
unpack_opaque(pkt, (void **) &passphrase, &pplen);
hashedPhrase = unpack_bool(pkt);
cacheTimeOut = unpack_uint32(pkt);
cacheGlobal = unpack_bool(pkt);
hashalg = (PGPHashAlgorithm)unpack_int32(pkt);
unpack_opaque(pkt, (void **) &hash, &hashlen);
format = (PGPPublicKeyMessageFormat)unpack_uint32(pkt);
err = pgpKeySign_back(
gCtx,
id,
passphrase,
pplen,
hashedPhrase,
cacheTimeOut,
cacheGlobal,
hashalg,
hash,
hashlen,
format,
&outbuf,
&outbuflen);
rpkt->status = err;
if (IsPGPError(err)) return;
pack_opaque(rpkt, (PGPByte *)outbuf, outbuflen);
if( IsntNull( outbuf ) )
PGPFreeData( outbuf );
}
static void
sRecv_SecPassphraseOK(PGPPackMsg *pkt, PGPPackMsg *rpkt)
{
PGPUInt32 id;
PGPByte *passphrase;
PGPSize pplen;
PGPBoolean hashedPhrase, b;
PGPUInt32 cacheTimeOut;
PGPBoolean cacheGlobal;
id = unpack_uint32(pkt);
unpack_opaque(pkt, (void **) &passphrase, &pplen);
hashedPhrase = unpack_bool(pkt);
cacheTimeOut = unpack_uint32(pkt);
cacheGlobal = unpack_bool(pkt);
b = pgpSecPassphraseOK_back(
gCtx,
id,
passphrase,
pplen,
hashedPhrase,
cacheTimeOut,
cacheGlobal);
pack_bool(rpkt, b);
rpkt->status = kPGPError_NoErr;
}
static void
sRecv_PurgePassphraseCache(PGPPackMsg *pkt, PGPPackMsg *rpkt)
{
PGPError err;
pkt;
err = pgpPurgePassphraseCache_back(gCtx);
rpkt->status = err;
}
static void
sRecv_CountCachedPassphrases(PGPPackMsg *pkt, PGPPackMsg *rpkt)
{
PGPError err;
PGPUInt32 nLocal, nGlobal, nOtherLocal;
err = pgpCountCachedPassphrases_back(gCtx,
&nLocal, &nGlobal, &nOtherLocal);
rpkt->status = err;
if (IsPGPError(err)) return;
pack_uint32(rpkt, nLocal);
pack_uint32(rpkt, nGlobal);
pack_uint32(rpkt, nOtherLocal);
}
static void
sRecv_KeyMaxSizes(PGPPackMsg *pkt, PGPPackMsg *rpkt)
{
PGPError err;
PGPUInt32 id;
PGPUInt32 maxEncryption=0, maxDecryption=0, maxSignature=0;
PGPBoolean needMaxEncryption, needMaxDecryption, needMaxSignature;
PGPPublicKeyMessageFormat format;
id = unpack_uint32(pkt);
needMaxEncryption = unpack_bool(pkt);
needMaxDecryption = unpack_bool(pkt);
needMaxSignature = unpack_bool(pkt);
format = (PGPPublicKeyMessageFormat)unpack_uint32(pkt);
err = pgpKeyMaxSizes_back(
gCtx,
id,
(needMaxEncryption ? &maxEncryption : NULL),
(needMaxDecryption ? &maxDecryption : NULL),
(needMaxSignature ? &maxSignature : NULL),
format);
rpkt->status = err;
if (IsPGPError(err)) return;
pack_uint32(rpkt, maxEncryption);
pack_uint32(rpkt, maxDecryption);
pack_uint32(rpkt, maxSignature);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -