Need help for embedding Wireguard into a Windows service in C++

41 Views Asked by At

I am a beginner in C/C++, and I need to embed Wireguard in a service for an app. I followed the docs of Wireguard and used embeddable-dll-service to build a little program as a test:

#include <iostream>
#include <Windows.h>
#include <winsvc.h>

bool checkAdmin()
{
    BOOL isAdmin = FALSE;
    SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
    PSID AdministratorsGroup;
    if (!AllocateAndInitializeSid(&NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &AdministratorsGroup))
    {
        std::cout << "Failed to allocate and initialize SID\n";
        return false;
    }

    if (!CheckTokenMembership(NULL, AdministratorsGroup, &isAdmin))
    {
        std::cout << "Failed to check token membership\n";
        FreeSid(AdministratorsGroup);
        return false;
    }

    FreeSid(AdministratorsGroup);

    return isAdmin == TRUE;
}

bool checkService()
{
    SC_HANDLE hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
    if (hSCManager == NULL)
    {
        std::cout << "Failed to open service control manager\n";
        return false;
    }

    SC_HANDLE hService = OpenServiceW(hSCManager, L"MooncloudTunnelService", SERVICE_ALL_ACCESS);
    if (hService == NULL)
    {
        CloseServiceHandle(hSCManager);
        return false;
    }

    CloseServiceHandle(hService);
    CloseServiceHandle(hSCManager);

    return true;
}

int createService()
{
    std::cout << "Creating service\n";

    SC_HANDLE hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
    if (hSCManager == NULL)
    {
        std::cout << "Failed to open service control manager\n";
        return 1;
    }

    wchar_t szPath[MAX_PATH];
    GetModuleFileNameW(NULL, szPath, MAX_PATH);

    SC_HANDLE hService = CreateServiceW(
        hSCManager,
        L"MooncloudTunnelService",
        L"Mooncloud Tunnel Service",
        SERVICE_ALL_ACCESS,
        SERVICE_WIN32_OWN_PROCESS,
        SERVICE_AUTO_START,
        SERVICE_ERROR_NORMAL,
        szPath,
        NULL,
        NULL,
        L"Nsi\0TcpIp",
        NULL,
        NULL
    );

    if (hService == NULL)
    {
        std::cout << "Failed to create service\n";
        CloseServiceHandle(hSCManager);
        return 1;
    }

    SERVICE_SID_INFO sidInfo;
    sidInfo.dwServiceSidType = SERVICE_SID_TYPE_UNRESTRICTED;

    if (!ChangeServiceConfig2(hService, SERVICE_CONFIG_SERVICE_SID_INFO, &sidInfo))
    {
        std::cout << "Failed to change service SID type\n";
        CloseServiceHandle(hService);
        CloseServiceHandle(hSCManager);
        return 1;
    }

    std::cout << "Service created successfully\n";

    CloseServiceHandle(hService);
    CloseServiceHandle(hSCManager);

    return 0;

}

int destroyService()
{
    // Supprimer le service
    SC_HANDLE hSCManagerDelete = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
    if (hSCManagerDelete == NULL)
    {
        std::cout << "Failed to open service control manager for deletion\n";
        return 1;
    }

    SC_HANDLE hServiceDelete = OpenServiceW(hSCManagerDelete, L"MooncloudTunnelService", SERVICE_ALL_ACCESS);
    if (hServiceDelete == NULL)
    {
        std::cout << "Failed to open service for deletion\n";
        CloseServiceHandle(hSCManagerDelete);
        return 1;
    }

    if (!DeleteService(hServiceDelete))
    {
        std::cout << "Failed to delete service\n";
        CloseServiceHandle(hServiceDelete);
        CloseServiceHandle(hSCManagerDelete);
        return 1;
    }

    std::cout << "Service deleted successfully\n";

    CloseServiceHandle(hServiceDelete);
    CloseServiceHandle(hSCManagerDelete);

    return 0;
}

int main(int argc, char* argv[])
{
    std::cout << "Hello World!\n";

    if (checkAdmin() == false)
    {
        std::cout << "This program requires administrator privileges\n";
        return 1;
    }

    if (argc == 3 && !strcmp(argv[1], "/service"))
    {
        if (checkService() == false) {
            createService();
        }
        else {
            std::cout << "Service already exists\n";
            destroyService();
            std::cout << "Old service destroyed\n";
            createService();
        }

        HMODULE tunnel_lib = LoadLibrary(L"tunnel.dll");
        if (!tunnel_lib)
            abort();
        BOOL(_cdecl * tunnel_proc)(_In_ LPCSTR conf_file);
        *(FARPROC*)&tunnel_proc = GetProcAddress(tunnel_lib, "WireGuardTunnelService");
        if (!tunnel_proc)
            abort();
        return tunnel_proc(argv[2]);
    }
    else if (argc == 2 && !strcmp(argv[1], "/unistall"))
    {
        if (checkService() == false) {
            std::cout << "Service does not exist\n";
            return 1;
        }
        else {
            destroyService();
        }
        return 0;
    }
    else
    {
        std::cout << "Bad Arguments\n";
        return 1;
    }

    return 0;
}

The service runs well, the /unistall command works fine too. But I get this message in the prompt everytime I run the program with the /service command and a wireguard config file : Service run error: Path must end in either .conf.dpapi or .conf

I debugged the app and the argv[2] value is the good path to my config file, this one is correct and ends with a .conf extension. I tried to put the whole path, quoted or non-quoted, double or single \\ in the path but I still get the same thing.

0

There are 0 best solutions below