cliexplorer.cpp
来自「PGP8.0源码 请认真阅读您的文件包然后写出其具体功能」· C++ 代码 · 共 909 行 · 第 1/2 页
CPP
909 行
//////////////// START OF INTERPROCESS COMMUNICATION //////////
static char sEnvCSP[] = "CSP";
static char sEnvDataName[] = "KEY_CONTS_OUT_NAME";
static char sGetKeyConts[] = "-getIEKeyContainers";
#define CL_IE_TIMEOUT 45 /* In seconds */
/* Remove command options, if any */
static void sGetCurrArgv0( char *out, int size ) {
LPCSTR s = GetCommandLine();
char *firstQ=NULL, *secondQ=NULL;
*out = '\0';
/* remove leading spaces */
while( *s == ' ' || *s == '\t' )
s ++;
strncpy( out, s, size-1 );
out[size-1] = '\0';
/* Make sure we get the first qoute for the executable,
not its argument */
firstQ = ( *out == '"' ? out : NULL );
if( firstQ ) {
secondQ = strchr( firstQ+1, '"' );
pgpAssert( secondQ ); /* How Windows allowed unterminated quotes? */
}
if( firstQ && secondQ ) { /* Quotes were used */
/* Remove quotes */
secondQ[0] = '\0';
memmove(out, firstQ+1, strlen(firstQ)/* including '\0' */ );
}
else if( firstQ == NULL ) { /* No qoutes used */
secondQ = strchr( out, ' ' );
if( secondQ )
*secondQ = '\0';
}
#if PGP_DEBUG && defined(PGP_IE_TRACE_CONT_REMOTE)
{
char s[MAX_PATH+32];
sprintf( s, "sGetCurrArgv0 returns %s\n", out );
OutputDebugString( s );
}
#endif
}
HANDLE static sGetRemoteProcess( const char *CSP, const char *dataName )
{
STARTUPINFO startupInfo;
PROCESS_INFORMATION processInformation = {0};
char path[MAX_PATH + sizeof(sGetKeyConts)];
char cmdline[MAX_PATH + sizeof(sGetKeyConts)];
char *env;
BOOL r;
int i=0;
int CSP_len =
strlen(CSP) + sizeof(sEnvCSP)-1 + 1/*for'='*/ + 1/*for\0*/ +
strlen(dataName) + sizeof(sEnvDataName)-1 + 1/*for'='*/ + 1/*for\0*/ +
1 /*for\0*/;
/* estimate the size of present environment block */
env = GetEnvironmentStrings();
for( i=0; env[i] != '\0'; i+=strlen(env+i)+1 ) {}
CSP_len += i+1/*for\0*/;
env = (char *)calloc( 1, CSP_len );
if( !env )
return NULL;
memcpy( env, GetEnvironmentStrings(), i );
sprintf( env+i, "%s=%s", sEnvCSP, CSP );
i += strlen( env+i )+1;
sprintf( env+i, "%s=%s", sEnvDataName, dataName );
i += strlen( env+i ) +1;
env[i] = '\0';
memset( &startupInfo, 0, sizeof(startupInfo) );
startupInfo.cb = sizeof(startupInfo);
/* Determine the process to run */
sGetCurrArgv0( path, sizeof(path) );
/* Quote unquoted path and add option */
strcpy( cmdline, "\"" );
strcat( cmdline, path );
strcat( cmdline, "\" " );
strcat( cmdline, sGetKeyConts );
#if PGP_DEBUG
{
char u[MAX_PATH];
strcpy( u, path );
strupr( u );
pgpAssert( strstr( u, "PGPKEYS" ) ); /* So far it is the case */
}
#endif
r = CreateProcess(
path, // name of executable module
cmdline, // command line string
NULL, // SD
NULL, // SD
FALSE, // handle inheritance option
0, // creation flags
env, // new environment block
NULL, // current directory name
&startupInfo, // startup information
&processInformation // process information
);
#if PGP_DEBUG
DWORD err = GetLastError();
#endif
free(env);
return processInformation.hProcess;
}
HANDLE static sCreateTempFile() {
char s[MAX_PATH] = "";
HANDLE h;
GetTempPath (sizeof(s), s);
GetTempFileName (s, "PGP", 0, s);
h = CreateFile(
s, // file name
GENERIC_READ|GENERIC_WRITE, // access mode
FILE_SHARE_WRITE, // share mode
NULL, // SD
CREATE_ALWAYS, // how to create
FILE_FLAG_DELETE_ON_CLOSE|FILE_ATTRIBUTE_TEMPORARY, // file attributes
NULL // handle to template file
);
return h;
}
static int sCreateNamedData( HANDLE *hFile, HANDLE *hMapFile, const char *mapName,
const void *p, int size )
{
HANDLE hf, hm;
DWORD n;
*hFile = NULL;
*hMapFile = NULL;
hf = sCreateTempFile();
if( hf == NULL ) {
return -1;
}
WriteFile( hf, &size, sizeof(size), &n, NULL );
if( p )
WriteFile( hf, p, size, &n, NULL );
hm = CreateFileMapping(
hf, // Current file handle.
NULL, // Default security.
PAGE_READWRITE, // Read/write permission.
0, // Max. object size.
0, // Size of hFile.
mapName); // Name of mapping object.
if (hm == NULL)
{
pgpDebugMsg("Could not create file-mapping object.");
CloseHandle(hf);
return -1;
}
*hFile = hf;
*hMapFile = hm;
return 0;
}
static sReadNamedData( const char *dataName, char **out ) {
HANDLE hMapFileOut = NULL;
void *lpMapAddress=NULL;
int ret;
int retries = CL_IE_TIMEOUT;
*out = NULL;
/* Now read reply */
while( retries-- > 0 && hMapFileOut == NULL ) {
Sleep(1000);
hMapFileOut = OpenFileMapping(
FILE_MAP_ALL_ACCESS, // Read/write permission.
FALSE, // Do not inherit the name
dataName);
#if PGP_DEBUG
if( retries < CL_IE_TIMEOUT - 10 )
OutputDebugString( "sReadNamedData: host process is not ready within 10 sec!\n" );
#endif
}
if( hMapFileOut == NULL ) {
ret = -1;
goto error;
}
lpMapAddress = MapViewOfFile(
hMapFileOut, // Handle to mapping object.
FILE_MAP_ALL_ACCESS, // Read/write permission.
0, // Max. object size.
0, // Size of hFile.
0); // Map entire file.
if (lpMapAddress == NULL) {
ret = -1;
goto error;
}
{
DWORD l;
char *c;
l = *(DWORD*)lpMapAddress;
if( l == 0 || l == -1 )
goto error;
c = (char *)malloc(l);
if( c == NULL ) {
ret = -1;
goto error;
}
memcpy( c, (BYTE*)lpMapAddress + sizeof(l), l );
*out = c;
}
error:
if( lpMapAddress )
UnmapViewOfFile( lpMapAddress );
CloseHandle(hMapFileOut);
return ret;
}
/* This runs in another process */
extern "C" int PGPclExport
PGPclIEInit(const char *cmdLine)
{
const char *CSP;
const char *mapFileNameOut;
HANDLE hFile, hMapFile;
char *conts = NULL;
int conts_n = 0;
int l=0;
if( cmdLine == NULL )
cmdLine = GetCommandLine();
/* Check for the magic */
if( strstr( cmdLine, sGetKeyConts ) == NULL )
return 0;
CSP = getenv( sEnvCSP );
mapFileNameOut = getenv( sEnvDataName );
if( !CSP )
return -1;
sGetExistingKeyContainers( CSP, &conts, &conts_n );
if( conts_n ) {
char *c = conts;
while( conts_n > 0 ) {
const size1 = strlen( c ) + 1;
l += size1;
c += size1;
conts_n--;
}
l++; /* For the last terminating symbol */
pgpAssert( *c == '\0' );
}
/* Always create "reply" data, so the caller will not wait */
sCreateNamedData( &hFile,
&hMapFile, mapFileNameOut, conts, l );
free( conts );
Sleep( CL_IE_TIMEOUT * 1000 );
CloseHandle( hFile );
CloseHandle( hMapFile );
pgpAssert(0 /* Why this process wasn't killed? */);
ExitProcess(-1);
return 0;
}
/* Query for key containers using invocation of new process with
the same name as this one.
Remote process must call PGPclIEInit at the beginning.
*/
extern "C" int PGPclExport
PGPclIEGetExistingKeyContainersRemote( const char *CSP, char **conts, int *n )
{
HANDLE hProc;
int retries = 10;
int ret = -1;
char *dataNameValue=NULL;
*conts = NULL;
*n = 0;
if( *CSP == '\0' )
return 0;
/* Generate data name to make it robust.
(There is no much need to make this name random)
*/
if( CLIEGenerateNewUUID( &dataNameValue ) != 0 )
return -1;
#if PGP_DEBUG
/* make it easy-identifiable */
{
const char suffix[] = "dataNameValue";
dataNameValue = (char*)realloc( dataNameValue, strlen(dataNameValue)+sizeof(suffix) );
strcat( dataNameValue, suffix );
}
#endif
hProc = sGetRemoteProcess(CSP, dataNameValue);
if( hProc == NULL )
goto error;
{
char *c, *p;
int i=0;
sReadNamedData( dataNameValue, &c );
if( c == NULL )
goto error;
for( p=c; p && *p; p+=strlen(p)+1 ) {
i++;
}
if( i ) {
*n = i;
*conts = c;
}
}
ret = 0; // OK
error:
free(dataNameValue);
if( hProc != NULL ) {
BOOL r = TerminateProcess( hProc, 0 );
pgpAssert( r == TRUE );
CloseHandle(hProc);
}
return ret;
}
extern "C" void PGPclExport PGPclIEFreeMem( void *cont ) {
if( cont )
free(cont);
}
/*
This class allows us to call PGPclIEInit implicitly; otherwize it needs to be called
somewhere close to WinMain
*/
static class A {
public:
A() {
PGPclIEInit(NULL);
}
} theInst;
//////////////// END OF INTERPROCESS COMMUNICATION //////////
#ifdef TEST
void main() {
char *cont;
int n=0;
char *p;
char *diff;
/* test container diff function */
CLIEDiffKeyContainers( "3\0" "2\0" "1\0" "\0", "1\0" "2\0" "3\0" "4\0" "\0", &diff );
printf( "diff=%s\n", diff );
free(diff);
printf( "Aladdin >>>\n" );
sGetExistingKeyContainers( "eToken Base Cryptographic Provider", &cont, &n );
p = cont;
while( p && *p ) {
printf( "Aladdin: %s\n", p );
p += strlen( p ) + 1;
}
free( cont );
cont = NULL;
printf( "Schlumberger >>>\n" );
sGetExistingKeyContainers( "Schlumberger Cryptographic Service Provider", &cont, &n );
p = cont;
while( p && *p ) {
printf( "Schlumberger: %s\n", p );
p += strlen( p ) + 1;
}
free( cont );
cont = NULL;
printf( "iKey >>>\n" );
sGetExistingKeyContainers( "Datakey RSA CSP", &cont, &n );
p = cont;
while( p && *p ) {
printf( "Rainbow: %s\n", p );
p += strlen( p ) + 1;
}
free( cont );
cont = NULL;
printf( "Gemsafe >>>\n" );
sGetExistingKeyContainers( "Gemplus GemSAFE Card CSP", &cont, &n );
p = cont;
while( p && *p ) {
printf( "GemSafe: %s\n", p );
p += strlen( p ) + 1;
}
free( cont );
cont = NULL;
}
#endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?