392 lines
11 KiB
C++

//----------------------------------------------------------------------------
//
// Copyright (C) Intel Corporation, 2006 - 2007.
//
// File: main.cpp
//
// Contents: The main() function.
//
// Notes:
//----------------------------------------------------------------------------
//===================================================
// INCLUDES
//===================================================
#include <ace/OS_main.h>
#include <ace/Service_Config.h>
#if defined (ACE_HAS_WINCE)
# include "ace/ACE.h"
#endif /* ACE_HAS_WINCE */
// Configuration related includes
#include "Options.h"
#include "OptionsUtils.h"
#ifdef _SERVICE
#include <Psapi.h>
#include "MPSEventLogger.h"
#endif /* _SERVICE */
ACE_String_Base<ACE_TCHAR> absolutePath;
ACE_TString logFileNameFull;
// Not currently supported in Linux
#ifdef ACE_WIN32
ACE_DLL _SOCKS_AUTH_DLL;
ACE_DLL _AMT_AUTH_DLL;
SOAP_Authenticate _socks_auth_func;
SOAP_Authenticate _amt_auth_func;
enum Dll_to_be_loaded
{
SOCKS_DLL = 0,
AMT_DLL
};
#endif /* ACE_WIN32 */
#if defined (ACE_WIN32) && !defined (ACE_LACKS_WIN32_SERVICES) && defined (_SERVICE)
MPSEventLoggerWrapper m_pLogger;
#endif /* ACE_WIN32 && !(ACE_LACKS_WIN32_SERVICES) && (_SERVICE)*/
#if defined (ACE_WIN32) && !defined (ACE_LACKS_WIN32_SERVICES) && defined(_SERVICE)
#include "MPSService.h"
#define SLEEP_TIMEOUT 2
#define RUNNING_ITERATIONS 10
#include "tlhelp32.h"
typedef enum {NOANOTHERMPS, ANOTHERMPS, ANOTHERMPSERROR} ANOTHERMPSRC;
// Check if the another MPS.exe process is already running.
ANOTHERMPSRC IsAnotherMPSRunning()
{
HANDLE hProcessSnap = NULL;
ANOTHERMPSRC Ret = NOANOTHERMPS;
PROCESSENTRY32 pe32 = {0};
// Take a snapshot of all processes in the system.
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcessSnap == INVALID_HANDLE_VALUE) {
ACE_DEBUG((MY_ERROR
ACE_TEXT("CreateToolhelp32Snapshot failed err=%d\n"), GetLastError()));
return (ANOTHERMPSERROR);
}
// Fill in the size of the structure before using it.
pe32.dwSize = sizeof(PROCESSENTRY32);
// Walk the snapshot of the processes, and for each process,
// display information.
if (Process32First(hProcessSnap, &pe32))
{
do
{
if ((strcmp(pe32.szExeFile,"MPS.exe")==0) &&
(GetCurrentProcessId()!=pe32.th32ProcessID)) {
Ret = ANOTHERMPS;
OutputDebugString("AnotherMPSRunning\n");
break;
}
}
while (Process32Next(hProcessSnap, &pe32));
}
else {
Ret = ANOTHERMPSERROR; // could not walk the list of processes
ACE_DEBUG((MY_ERROR
ACE_TEXT("could not walk the list of processes \n") ));
}
// Do not forget to clean up the snapshot object.
CloseHandle (hProcessSnap);
return (Ret);
}
int runMPSService(int argc, ACE_TCHAR *argv[]) {
// CREATING THE main service
MPSService service(MPS_NAME);
// CALLING THE INITIALIZATION FUNTION
service.InitializeService(SERVICE_WIN32_OWN_PROCESS,SERVICE_ACCEPT_STOP|SERVICE_ACCEPT_SHUTDOWN,0);
// RUNNING THE DISPATCHER.
service.StartDispatcher();
return 0;
}
#endif /* ACE_WIN32 && !(ACE_LACKS_WIN32_SERVICES) && (_SERVICE)*/
//================================================
// Local Functions
//================================================
// Not currently supported in Linux
#ifdef ACE_WIN32
STATUS loadDllsAuthFunctions(Dll_to_be_loaded toLoad);
bool loadDllAuthFunc(ACE_DLL& dll, SOAP_Authenticate& func , const char* dll_name );
#endif /* ACE_WIN32 */
int run_main (int argc, ACE_TCHAR *argv[]);
//int mps_init (int argc, ACE_TCHAR *argv[]);
STATUS fillCommonElements();
//================================================
// main
//================================================
int
ACE_TMAIN (int argc, ACE_TCHAR *argv[])
{
#if defined(ACE_WIN32) && defined(_SERVICE)
// Check first that the MPS process isn't running already:
// give it RUNNING_ITERATIONS*SLEEP_TIMEOUT to finish run
bool isRunning=true;
ANOTHERMPSRC rc;
for (int i=0;i<=RUNNING_ITERATIONS;i++)
{
rc=IsAnotherMPSRunning();
if (rc==NOANOTHERMPS)
{
isRunning=false;
break;
}
else
{
if (rc==ANOTHERMPS)
{
Sleep(2000);
}
else
{
// general error, on last iteration set that no another MPS
if (i==RUNNING_ITERATIONS)
{
m_pLogger.LogErrorEvent(MPS_ERROR, MPS_TWO_RUNS_GENERAL_WINDOWS_ERROR);
isRunning=false;
break;
}
}
}
}
if (isRunning)
{
m_pLogger.LogErrorEvent(MPS_ERROR, MPS_TWO_RUNS_FAILURE);
return -1;
}
#endif
#if defined(ACE_WIN32) && defined(_SERVICE)
ACE_LOG_MSG->priority_mask(LM_ERROR, ACE_Log_Msg::PROCESS);
// Set up absolute path
TCHAR szPath[MAXPATHLEN];
const char * pszModuleName = NULL;
/*if pszModuleName is NULL, GetModuleHandle() will return the handle of the current process*/
if( GetModuleFileName(GetModuleHandle(pszModuleName), szPath, MAXPATHLEN-1 ) == 0 ) {
return -1;
}
absolutePath = szPath;
size_t index = absolutePath.rfind('\\');
absolutePath = absolutePath.substr(0, index+1);
#else
absolutePath = "";
#endif
ACE_TString staticConfigFile;
staticConfigFile += absolutePath;
staticConfigFile += STATIC_CONFIG_FILENAME;
ACE_TString dynamicConfigFile;
dynamicConfigFile += absolutePath;
dynamicConfigFile += DYNAMIC_CONFIG_FILENAME;
// Set up Options
if ( (Options::createInstance(
staticConfigFile.c_str(), dynamicConfigFile.c_str(),
ConfigFormats::instance() -> getFormat(STATIC_MANDATORY),
ConfigFormats::instance() -> getFormat(STATIC_OPTIONAL),
ConfigFormats::instance() -> getFormat(DYNAMIC_MANDATORY),
ConfigFormats::instance() -> getFormat(DYNAMIC_OPTIONAL)) != STATUS_SUCCESS) ||
(Options::instance() == NULL) ||
(!Options::instance()->isInit()))
{
ACE_ERROR ((MY_ERROR ACE_TEXT ("Error in initializing configuration file.\n")));
#if defined (ACE_WIN32) && !defined (ACE_LACKS_WIN32_SERVICES) && defined (_SERVICE)
m_pLogger.LogErrorEvent(MPS_ERROR, MPS_CONFIG_INIT_FAIL_MESSAGE);
#endif /* ACE_WIN32 && !(ACE_LACKS_WIN32_SERVICES) && (_SERVICE)*/
return -1;
}
// Already checked that Options::instance() is not null
if (Options::instance() -> read_static_file() == STATUS_FAILURE) {
ACE_ERROR ((MY_ERROR ACE_TEXT ("Error while reading static configuration file.\n")));
#if defined (ACE_WIN32) && !defined (ACE_LACKS_WIN32_SERVICES) && defined (_SERVICE)
m_pLogger.LogErrorEvent(MPS_ERROR, MPS_CONFIG_STATIC_FAIL_MESSAGE);
#endif /* ACE_WIN32 && !(ACE_LACKS_WIN32_SERVICES) && (_SERVICE)*/
return -1;
}
if(fillCommonElements() != STATUS_SUCCESS)
{
ACE_ERROR ((MY_ERROR ACE_TEXT ("Error while filling common elements.\n")));
return -1;
}
if (Options::instance() -> read_dynamic_file() == STATUS_FAILURE) {
#if defined (ACE_WIN32) && !defined (ACE_LACKS_WIN32_SERVICES) && defined (_SERVICE)
m_pLogger.LogErrorEvent(MPS_ERROR, MPS_CONFIG_DYNAMIC_FAIL_MESSAGE);
#endif /* ACE_WIN32 && !(ACE_LACKS_WIN32_SERVICES) && (_SERVICE)*/
ACE_ERROR_RETURN ((MY_ERROR ACE_TEXT ("Error while reading dynamic configuration file.\n")), -1);
}
// Not currently supported in Linux
#ifdef ACE_WIN32
// Load authentication dll - SOCKS
if (loadDllsAuthFunctions(SOCKS_DLL) != STATUS_SUCCESS)
{
#if defined (ACE_WIN32) && !defined (ACE_LACKS_WIN32_SERVICES) && defined (_SERVICE)
m_pLogger.LogErrorEvent(MPS_ERROR, MPS_READING_AUTHENTICATION_SOCKS_DLL_FAIL_MESSAGE);
#endif /* ACE_WIN32 && !(ACE_LACKS_WIN32_SERVICES) && (_SERVICE)*/
ACE_ERROR_RETURN((MY_ERROR
ACE_TEXT ("Failed loading Socks authentication dll - exit\n")),-1);
}
// Load authentication dll - AMT
if (loadDllsAuthFunctions(AMT_DLL) != STATUS_SUCCESS)
{
#if defined (ACE_WIN32) && !defined (ACE_LACKS_WIN32_SERVICES) && defined (_SERVICE)
m_pLogger.LogErrorEvent(MPS_ERROR, MPS_READING_AUTHENTICATION_AMT_DLL_FAIL_MESSAGE);
#endif /* ACE_WIN32 && !(ACE_LACKS_WIN32_SERVICES) && (_SERVICE)*/
ACE_ERROR_RETURN((MY_ERROR
ACE_TEXT ("Failed loading AMT authentication dll - exit\n")),-1);
}
#endif /* ACE_WIN32 */
int retValue;
#if defined (ACE_WIN32) && !defined (ACE_LACKS_WIN32_SERVICES) && defined (_SERVICE)
retValue = runMPSService(argc, argv);
#else
retValue = run_main (argc, argv);
#endif /* ACE_WIN32 && !(ACE_LACKS_WIN32_SERVICES) && (_SERVICE)*/
// Not currently supported in Linux
#ifdef ACE_WIN32
_SOCKS_AUTH_DLL.close();
_AMT_AUTH_DLL.close();
#endif /* ACE_WIN32 */
return retValue;
}
// Not currently supported in Linux
#ifdef ACE_WIN32
STATUS loadDllsAuthFunctions(Dll_to_be_loaded toLoad)
{
if (toLoad == SOCKS_DLL)
{
//loading SOCKS Authentication function:
const bool* needAuthenticationPtr = getSocksNeedAuthentication();
const ACE_TString* socksDllNamePtr = getSocksDllName();
const ACE_TString* socksDllParametersPtr = getSocksDllParameters();
if (needAuthenticationPtr == NULL || socksDllNamePtr == NULL || socksDllParametersPtr == NULL) {
ACE_DEBUG((MY_DEBUG
ACE_TEXT("Failed to get SOCKS Authentication details\n")));
return STATUS_FAILURE;
}
Authentication_Param socks_auth_params( *needAuthenticationPtr,
*socksDllNamePtr,
*socksDllParametersPtr);
if (socks_auth_params._authenticate)
{
if (loadDllAuthFunc(_SOCKS_AUTH_DLL, _socks_auth_func, socks_auth_params._dllName.c_str() ) == false)
{
ACE_DEBUG((MY_ERROR
ACE_TEXT("Failed loading SOCKS authentication dll = %s. \n"),
socks_auth_params._dllName.c_str()));
return STATUS_FAILURE;
}
}
else
{
ACE_DEBUG((MY_NOTICE
ACE_TEXT("NOT configures SOCKS authentication - going to accept all SOCKS connections\n")));
_socks_auth_func = NULL;
}
}
else
{
//loading AMT Authentication function:
const bool* needAuthenticationPtr = getAmtNeedAuthentication();
const ACE_TString* amtDllNamePtr = getAmtDllName();
const ACE_TString* amtDllParametersPtr = getAmtDllParameters();
if (needAuthenticationPtr == NULL || amtDllNamePtr == NULL || amtDllParametersPtr == NULL) {
ACE_DEBUG((MY_DEBUG
ACE_TEXT("Failed to get SOCKS Authentication details\n")));
return STATUS_FAILURE;
}
Authentication_Param amt_auth_params(*needAuthenticationPtr,
*amtDllNamePtr,
*amtDllParametersPtr);
if (amt_auth_params._authenticate)
{
if (loadDllAuthFunc(_AMT_AUTH_DLL, _amt_auth_func, amt_auth_params._dllName.c_str() ) == false)
{
ACE_DEBUG((MY_ERROR
ACE_TEXT("Failed loading AMT authentication dll = %s. \n"),
amt_auth_params._dllName.c_str()));
return STATUS_FAILURE;
}
}
else
{
ACE_DEBUG((MY_NOTICE
ACE_TEXT("APF authentication is not configured- going to accept all APF connections\n")));
_amt_auth_func = NULL;
}
}
return STATUS_SUCCESS;
}
bool loadDllAuthFunc(ACE_DLL& dll, SOAP_Authenticate& func, const char* dll_name )
{
int retval = dll.open (ACE_TEXT(dll_name));
if (retval != 0)
{
ACE_ERROR_RETURN ((MY_DEBUG,"%s.open", dll_name),false );
}
// Cast the void* to function* with a long as intermediate.
void *void_ptr = dll.symbol (AUTH_DLL_FUNC_NAME);
ptrdiff_t tmp = reinterpret_cast<ptrdiff_t> (void_ptr);
func = reinterpret_cast<SOAP_Authenticate> (tmp);
if (func == 0)
{
ACE_ERROR_RETURN ((MY_DEBUG
ACE_TEXT ("%p\n"),
dll.error ()), false);
}
return true;
}
#endif /* ACE_WIN32 */