Skip to content

Commit

Permalink
feat: set permissions to the service
Browse files Browse the repository at this point in the history
  • Loading branch information
imLinguin committed May 7, 2024
1 parent 42768af commit 58a940a
Show file tree
Hide file tree
Showing 9 changed files with 184 additions and 5 deletions.
12 changes: 9 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,19 @@ jobs:
if: ${{ needs.check-changes.outputs.should_run != 'false' }}
steps:
- uses: actions/checkout@v4
- name: Build the dummy
- name: Setup
working-directory: dummy-service
run: gcc -o GalaxyCommunication.exe main.c -ladvapi32
run: meson setup build
- name: Build
working-directory: dummy-service
run: meson compile -C build
- name: Move files
working-directory: dummy-service
run: move build/*.exe .
- uses: actions/upload-artifact@v4
with:
name: dummy-GalaxyCommunication.exe
path: dummy-service/GalaxyCommunication.exe
path: dummy-service/*.exe
build:
strategy:
matrix:
Expand Down
Binary file added dummy-service/GalaxyCommunication.exe
Binary file not shown.
8 changes: 6 additions & 2 deletions dummy-service/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,11 @@ In case of Wine/Proton make sure to run the command above in the context of your

Use
```shell
gcc -o GalaxyCommunication.exe main.c -ladvapi32
meson setup builddir
```

For cross compilation on Linux use `x86_64-w64-mingw32-gcc`
For cross compilation on Linux/Mac make sure `mingw` is installed and add a `--cross-file meson/x86_64-w64-mingw32.ini` to the setup command

```shell
meson compile -C builddir
``
File renamed without changes.
1 change: 1 addition & 0 deletions dummy-service/install-dummy-service.bat
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ SET targetdir=C:\ProgramData\GOG.com\Galaxy\redists
sc create GalaxyCommunication binpath=%targetdir%\GalaxyCommunication.exe
if not exist "%targetdir%" mkdir %targetdir%
xcopy /y /q %currdir%GalaxyCommunication.exe %targetdir%
%currdir%update-permissions.exe
8 changes: 8 additions & 0 deletions dummy-service/meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
project('dummy-service', 'c',
version : '0.1',
default_options : ['warning_level=3'])

executable('GalaxyCommunication',
'communication.c')

executable('update-permissions', 'permissions.c')
18 changes: 18 additions & 0 deletions dummy-service/meson/x86_64-w64-mingw32.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[properties]
needs_exe_wrapper = true

[binaries]
c = 'x86_64-w64-mingw32-gcc'
cpp = 'x86_64-w64-mingw32-g++'
ar = 'x86_64-w64-mingw32-ar'
strip = 'x86_64-w64-mingw32-strip'
pkg-config = 'x86_64-w64-mingw32-pkg-config'
windres = 'x86_64-w64-mingw32-windres'

exe_wrapper = 'wine64'

[host_machine]
system = 'windows'
cpu_family = 'x86_64'
cpu = 'x86_64'
endian = 'little'
142 changes: 142 additions & 0 deletions dummy-service/permissions.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
#include <windows.h>
#include <stdio.h>
#include <aclapi.h>

// based on https://learn.microsoft.com/en-en/windows/win32/services/svccontrol-cpp

SC_HANDLE schSCManager;
SC_HANDLE schService;

EXPLICIT_ACCESS ea;
SECURITY_DESCRIPTOR sd;
PSECURITY_DESCRIPTOR psd = NULL;
PACL pacl = NULL;
PACL pNewAcl = NULL;
BOOL bDaclPresent = FALSE;
BOOL bDaclDefaulted = FALSE;
DWORD dwError = 0;
DWORD dwSize = 0;
DWORD dwBytesNeeded = 0;

int main(int argc, char** argv) {

schSCManager = OpenSCManager(
NULL, // local computer
NULL, // ServicesActive database
SC_MANAGER_ALL_ACCESS); // full access rights

if (NULL == schSCManager)
{
printf("OpenSCManager failed (%ld)\n", GetLastError());
return 1;
}

// Get a handle to the service

schService = OpenService(
schSCManager, // SCManager database
"GalaxyCommunication", // name of service
READ_CONTROL | WRITE_DAC); // access

if (schService == NULL)
{
printf("OpenService failed (%ld)\n", GetLastError());
CloseServiceHandle(schSCManager);
return 1;
}

// Get the current security descriptor.

if (!QueryServiceObjectSecurity(schService,
DACL_SECURITY_INFORMATION,
&psd, // using NULL does not work on all versions
0,
&dwBytesNeeded))
{
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{
dwSize = dwBytesNeeded;
psd = (PSECURITY_DESCRIPTOR)HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY, dwSize);
if (psd == NULL)
{
// Note: HeapAlloc does not support GetLastError.
printf("HeapAlloc failed\n");
goto dacl_cleanup;
}

if (!QueryServiceObjectSecurity(schService,
DACL_SECURITY_INFORMATION, psd, dwSize, &dwBytesNeeded))
{
printf("QueryServiceObjectSecurity failed (%ld)\n", GetLastError());
goto dacl_cleanup;
}
}
else
{
printf("QueryServiceObjectSecurity failed (%ld)\n", GetLastError());
goto dacl_cleanup;
}
}

// Get the DACL.

if (!GetSecurityDescriptorDacl(psd, &bDaclPresent, &pacl,
&bDaclDefaulted))
{
printf("GetSecurityDescriptorDacl failed(%ld)\n", GetLastError());
goto dacl_cleanup;
}

// Build the ACE.

BuildExplicitAccessWithName(&ea, TEXT("EVERYONE"),
SERVICE_START | SERVICE_STOP | READ_CONTROL,
SET_ACCESS, NO_INHERITANCE);

dwError = SetEntriesInAcl(1, &ea, pacl, &pNewAcl);
if (dwError != ERROR_SUCCESS)
{
printf("SetEntriesInAcl failed(%ld)\n", dwError);
goto dacl_cleanup;
}

// Initialize a new security descriptor.

if (!InitializeSecurityDescriptor(&sd,
SECURITY_DESCRIPTOR_REVISION))
{
printf("InitializeSecurityDescriptor failed(%ld)\n", GetLastError());
goto dacl_cleanup;
}

// Set the new DACL in the security descriptor.

if (!SetSecurityDescriptorDacl(&sd, TRUE, pNewAcl, FALSE))
{
printf("SetSecurityDescriptorDacl failed(%ld)\n", GetLastError());
goto dacl_cleanup;
}

// Set the new DACL for the service object.

if (!SetServiceObjectSecurity(schService,
DACL_SECURITY_INFORMATION, &sd))
{
printf("SetServiceObjectSecurity failed(%ld)\n", GetLastError());
goto dacl_cleanup;
}
else printf("Service DACL updated successfully\n");

dacl_cleanup:
CloseServiceHandle(schSCManager);
CloseServiceHandle(schService);

if(NULL != pNewAcl)
LocalFree((HLOCAL)pNewAcl);
if(NULL != psd)
HeapFree(GetProcessHeap(), 0, (LPVOID)psd);


return 0;
}
Binary file added dummy-service/update-permissions.exe
Binary file not shown.

0 comments on commit 58a940a

Please sign in to comment.