📄 msrc4plugin.cpp
字号:
m_pREGISTRY->ReadItem(sLogit, 2,INDEXVAL_LOG, sLogItDef); //debuglog
m_pREGISTRY->ReadItem(keyFile, KEYFILENAME_SIZE,INDEXVAL_KEYGEN, defaultGenFile); //GenKey
delete m_pREGISTRY;
//HKCU/Server
m_pREGISTRY = new REGISTRY(HKEY_CURRENT_USER, MSRC4_KEY_NAME_SERVER, true);
m_pREGISTRY->ReadItem(keyFile, KEYFILENAME_SIZE,INDEXVAL_KEYFILE, defaultKeyFile); //key file
strcpy(strPlugin.szHKCUServer,keyFile);
m_pREGISTRY->ReadItem(sLogit, 2,INDEXVAL_LOG, sLogItDef); //debuglog
m_pREGISTRY->ReadItem(keyFile, KEYFILENAME_SIZE,INDEXVAL_KEYGEN, defaultGenFile); //GenKey
delete m_pREGISTRY;
//HKCU/Viewer
m_pREGISTRY = new REGISTRY(HKEY_CURRENT_USER, MSRC4_KEY_NAME_VIEWER, true);
m_pREGISTRY->ReadItem(keyFile, KEYFILENAME_SIZE,INDEXVAL_KEYFILE, defaultKeyFile); //key file
strcpy(strPlugin.szHKCUViewer,keyFile);
m_pREGISTRY->ReadItem(sLogit, 2,INDEXVAL_LOG, sLogItDef); //debuglog
m_pREGISTRY->ReadItem(keyFile, KEYFILENAME_SIZE,INDEXVAL_KEYGEN, defaultGenFile); //GenKey
strcpy(strPlugin.szHKCUGenKey,keyFile);
delete m_pREGISTRY;
#else
strcpy(strPlugin.szHKLMServer,sDefaultKeyName);
strcpy(strPlugin.szHKCUViewer,sDefaultKeyName);
strcpy(strPlugin.szHKCUServer,sDefaultKeyName);
strcpy(strPlugin.szHKCUGenKey,sDefaultGenKey);
strcpy(sLogit, sLogItDef);
#endif
pPlugin = &strPlugin;
// Display the Plugin Config dialog box
DoDialog();
}
else
{
// ***CASE 2: - INITIALIZE PLUGIN***
PrintLog((DEST,"SetParams - StartUp."));
//#ifdef _WITH_REGISTRY
// Use szParams to setup the Plugin.
// (it corresponds to the VNC password as we require it in the GetParams() function below)
MyStrToken(szExternalKey, szParams, 1, ',');
// Use szParams to setup the Plugin.
MyStrToken(szExternalKey, szParams, 1, ',');
// The second parameter is the type of application that has loaded the plugin
// "viewer" : for vncviewer
// "server-svc" : for WinVNC run as a service
// "server-app" : for WINVNC run as an application
// this info can be used for application/environnement dependent operations (config saving...)
MyStrToken(szLoaderType, szParams, 2, ',');
//#endif
// Odditional params may be added later if necessary
if (strlen(szLoaderType) > 0)
{
#ifdef _WITH_REGISTRY
//szLoaderType determines key hive to open...
if (strcmp(szLoaderType, "server-svc") == 0) {
m_pREGISTRY = new REGISTRY(HKEY_LOCAL_MACHINE, MSRC4_KEY_NAME_SERVER, false);
PrintLog((DEST,"***** SERVER -> SERVICE *****"));
}else
if (strcmp(szLoaderType, "server-app") == 0) {
m_pREGISTRY = new REGISTRY(HKEY_CURRENT_USER, MSRC4_KEY_NAME_SERVER, false);
PrintLog((DEST,"***** SERVER -> Application *****"));
}else
if (strcmp(szLoaderType, "viewer") == 0) {
m_pREGISTRY = new REGISTRY(HKEY_CURRENT_USER, MSRC4_KEY_NAME_VIEWER, false);
PrintLog((DEST,"***** VIEWER Application *****"));
}
else {
PrintLog((DEST,"***** Bad LoaderType: %s *****", szLoaderType));
}
#else
if (strcmp(szLoaderType, "server-svc") == 0) {
PrintLog((DEST,"***** SERVER -> SERVICE *****")); }
else {
if (strcmp(szLoaderType, "server-app") == 0) {
PrintLog((DEST,"***** SERVER -> Application *****"));}
else {
if (strcmp(szLoaderType, "viewer") == 0) {
PrintLog((DEST,"***** VIEWER Application *****")); }
else {
PrintLog((DEST,"***** Bad LoaderType: %s *****", szLoaderType)); }
}
}
#endif
}
#ifdef _WITH_REGISTRY
PrintLog((DEST,"Trying to find the key file"));
PrintLog((DEST,"Looking at the registry"));
m_pREGISTRY->ReadItem(keyFile, KEYFILENAME_SIZE,INDEXVAL_KEYFILE, NULL);
delete m_pREGISTRY;
PrintLog((DEST,"Looking for %s", keyFile));
//open the key file
hKeyFile = CreateFile(keyFile, GENERIC_READ, FILE_SHARE_READ,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
#else
PrintLog((DEST,"Trying to find the key file"));
//default to "didn't work"
hKeyFile = INVALID_HANDLE_VALUE;
FindKey(PLUGIN_FILE, sDefaultKeyName, sVariable, &hKeyFile, output);
#endif
rc = PrepContext(iWinVer, &hProvider);
rc = PrepContext(iWinVer, &hProvider2);
if (hKeyFile == INVALID_HANDLE_VALUE) {
//PrintLog((DEST,"Key Not Found at %s",keyFile));
PrintLog((DEST,"No key Found, using password."));
rc = CreateDerivedCryptKey(hProvider, &hKey, szExternalKey);
rc = CreateDerivedCryptKey(hProvider, &hKey2, szExternalKey);
}
else
{
//PrintLog((DEST,"Found key at %s",keyFile));
ImportCryptKey(hProvider, &hKey, hKeyFile);
rc = SetFilePointer(hKeyFile, 0, NULL, FILE_BEGIN);
ImportCryptKey(hProvider2, &hKey2, hKeyFile);
CloseHandle(hKeyFile);
PrintLog((DEST,"Key File Read."));
}
CleanupCryptoKey(hExchangeKey);
CleanupCryptoKey(hExchangeKey2);
hExchangeKey = 0;
hExchangeKey2 = 0;
//reset the salt flag so the password gets re-salted for the new session
bSaltD = true;
bSaltE = true;
}
return 1;
}
//
// Return the current plugin params
// As the plugin is basically a blackbox, VNC doesn't need to know
// the Plugin parameters. Should not often be used...
//
PLUGIN_API char* GetParams(void)
{
PrintLog((DEST,"GetParams. %s",getParams ));
if (strlen(szExternalKey) > 0)
return szExternalKey; // Return the already stored externalkey params
else
return getParams;
}
//
// TransformBuffer function
//
// Transform the data given in pDataBuffer then return the pointer on the allocated
// buffer containing the resulting data.
// The length of the resulting data is given by pnTransformedDataLen
//
PLUGIN_API BYTE* TransformBuffer(BYTE* pDataBuffer, int nDataLen, int* pnTransformedDataLen)
{
DWORD dwByteCount;
unsigned char * salt = 0;
unsigned char * iv = 0;
int headerLen = 0;
bTransHeader = bSaltE;
BYTE* pTransBuffer = CheckLocalTransBufferSize(GiveTransDataLen(nDataLen));
if (pTransBuffer == NULL)
{
*pnTransformedDataLen = -1;
return NULL;
}
if (bSaltE)
{
//If the SALT/IV for the session hasn't been setup yet, set it up.
PrintLog((DEST,"Salting E key"));
__try
{
//create the session key using the salt
salt = new unsigned char[SALT_SIZE+1];
iv = new unsigned char[IV_SIZE+1];
memset(salt,0,SALT_SIZE);
memset(iv,0,IV_SIZE);
//generate some random data for the SALT
CryptGenRandom(hProvider, SALT_SIZE, salt);
CryptGenRandom(hProvider, IV_SIZE, iv);
// memset(salt,1,SALT_SIZE);
// memset(iv,1,IV_SIZE);
//SALT the key
//if(!CryptSetKeyParam(hKey, KP_SALT, salt, 0)) {
// PrintLog((DEST,"Error %x during CryptSetKeyParam!\n", GetLastError()));
// //return NULL;
//}
if(!CryptSetKeyParam(hKey2, KP_IV, iv, 0)) {
PrintLog((DEST,"Error %x during CryptSetKeyParam!\n", GetLastError()));
//return NULL;
}
//copy the salt into the beginning of the buffer
memcpy(pTransBuffer, salt, SALT_SIZE);
memcpy(pTransBuffer+SALT_SIZE, iv, IV_SIZE);
//PrintLog((DEST,"Password: %16.16s",szExternalKey));
PrintLog((DEST,"SALTE:%*.*s",SALT_SIZE,SALT_SIZE,salt));
}
__finally{
delete[] salt;
delete[] iv;
}
headerLen = HeaderLen; //add header length
}
memcpy(pTransBuffer+headerLen, pDataBuffer, nDataLen);
dwByteCount = nDataLen;
//Call CryptEncrypt with the key and the buffer, it transforms the buffer inplace
//Since I'm using a STREAM encryption, the size does not change.
if (! CryptEncrypt(hKey, 0, false, 0, pTransBuffer+headerLen, &dwByteCount, nDataLen)) {
PrintLog((DEST,"CryptEncrypt failed."));
return NULL;
}
//It SHOULD not change...
if (dwByteCount != (DWORD)nDataLen) {
PrintLog((DEST,"TransformBuffer Assertion failed."));
return NULL;
}
// return the transformed data length
*pnTransformedDataLen = GiveTransDataLen(nDataLen);
//don't need additional salt, turn it off.
bSaltE = bTransHeader = false;
return pTransBuffer; // Actually, pTransBuffer = pLocalTransBuffer
}
//
// RestoreBuffer function
//
// This function has a 2 mandatory behaviors:
//
// 1. If pRestoredDataBuffer is NULL, the function must return the pointer to current
// LocalRestBuffer that is going to receive the Transformed data to restore
// from VNC viewer/server's socket.
// This buffer must be of the size of transformed data, calculated from nDataLen
// and this size must be given back in pnRestoredDataLen.
//
// 2. If pRestoredDataBuffer != NULL, it is the destination buffer that is going to receive
// the restored data. So the function must restore the data that is currently in the
// local pLocalRestBuffer (nDataLen long) and put the result in pRestoredDataBuffer.
// The length of the resulting data is given back in pnTransformedDataLen
//
// Explanation: Actually, when VNC viewer/server wants to restore some data, it does the following:
// - Calls RestoreBuffer with NULL to get the buffer (and its length) to store incoming transformed data
// - Reads incoming transformed data from socket directly into the buffer given (and of given length)
// - Calls RestoreBuffer again to actually restore data into the given destination buffer.
// This way the copies of data buffers are reduced to the minimum.
//
PLUGIN_API BYTE* RestoreBuffer(BYTE* pRestoredDataBuffer, int nDataLen, int* pnRestoredDataLen)
{
DWORD dwByteCount;
unsigned char * salt = 0;
unsigned char * iv = 0;
int headerLen = 0;
// If given buffer is NULL, allocate necessary space here and return the pointer.
// Additinaly, calculate the resulting length based on nDataLen and return it at the same time.
if (pRestoredDataBuffer == NULL)
{
bTransHeader = bSaltD;
// Give the size of the transformed data buffer, based on the original data length
*pnRestoredDataLen = GiveTransDataLen(nDataLen);
// Ensure the pLocalRestBuffer that receive transformed data is big enough
BYTE* pBuffer = CheckLocalRestBufferSize(*pnRestoredDataLen);
return pBuffer; // Actually pBuffer = pLocalRestBuffer
}
if (bSaltD)
{
__try
{
//If we haven't setup the key with the Salt, then get the salt off the buffer and setup the key
salt = new unsigned char[SALT_SIZE+1];
iv = new unsigned char[IV_SIZE+1];
PrintLog((DEST,"Salting D key"));
//Get the salt off the beginning of the buffer
memcpy(salt,pLocalRestBuffer,SALT_SIZE);
//Get the IV off the buffer
memcpy(iv,pLocalRestBuffer+SALT_SIZE,IV_SIZE);
//PrintLog((DEST,"Password: %16.16s",szExternalKey));
PrintLog((DEST,"SALTD:%*.*s",SALT_SIZE,SALT_SIZE,salt));
// memset(salt,1,SALT_SIZE);
// memset(iv,1,IV_SIZE);
//SALT the key
//if(!CryptSetKeyParam(hKey2, KP_SALT, salt, 0)) {
// PrintLog((DEST,"Error %x during CryptSetKeyParam!\n", GetLastError()));
// //return NULL;
//}
//set the IV
if(!CryptSetKeyParam(hKey2, KP_IV, iv, 0)) {
PrintLog((DEST,"Error %x during CryptSetKeyParam!\n", GetLastError()));
return NULL;
}
}
__finally
{
delete[] salt;
delete[] iv;
}
headerLen = HeaderLen; //add header length
}
// If we reach this point, pLocalTransBuffer must contain the transformed data to restore
// Do the actual data restoration/unpadding etc...
// Copy data into the destination buffer, without modifiying it.
memcpy(pRestoredDataBuffer, pLocalRestBuffer+headerLen, nDataLen-headerLen);
dwByteCount = nDataLen-headerLen;
//Call CryptDecrypt with the key and the buffer. The buffer will be transformed in place
if (! CryptDecrypt(hKey2, 0, false, 0, pRestoredDataBuffer, &dwByteCount)) {
PrintLog((DEST,"CryptDecrypt failed."));
return NULL;
}
//The size should not change
if (dwByteCount != (DWORD)(nDataLen-headerLen)) {
PrintLog((DEST,"RestoreBuffer Assertion failed."));
return NULL;
}
if (bTransHeader)
PrintLog((DEST,"%16.16s",pRestoredDataBuffer));
// return the resulting data length
*pnRestoredDataLen = GiveRestDataLen(nDataLen);
//turn off salt, we should have it already
bSaltD = bTransHeader = false;
return pLocalRestBuffer;
//return pRestoredDataBuffer;
}
//
// Free the DataBuffer and TransBuffer than have been allocated
// in TransformBuffer and RestoreBuffer, using the method adapted
// to the used allocation method.
//
PLUGIN_API void FreeBuffer(BYTE* pBuffer)
{
//PrintLog((DEST,"FreeBuffer."));
if (pBuffer != NULL)
free(pBuffer);
return;
}
// -----------------------------------------------------------------
// End of functions that must be exported
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -