2020-07-03 16:49:47 +02:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0
|
|
|
|
*
|
2021-01-30 16:45:26 +01:00
|
|
|
* Copyright (C) 2018-2021 WireGuard LLC. All Rights Reserved.
|
2020-07-03 16:49:47 +02:00
|
|
|
*/
|
|
|
|
|
2020-10-31 11:55:26 +01:00
|
|
|
#include "logger.h"
|
2021-07-28 13:50:40 +02:00
|
|
|
#include "main.h"
|
2020-10-31 11:55:26 +01:00
|
|
|
#include "namespace.h"
|
|
|
|
|
|
|
|
#include <Windows.h>
|
2020-11-04 01:08:41 +01:00
|
|
|
#include <winternl.h>
|
2021-07-23 18:19:00 +02:00
|
|
|
#include <winefs.h>
|
2020-10-31 13:03:14 +01:00
|
|
|
#include <wchar.h>
|
2021-07-23 18:19:00 +02:00
|
|
|
#include <stdlib.h>
|
2020-07-03 16:49:47 +02:00
|
|
|
|
2020-12-17 19:00:25 +01:00
|
|
|
static HANDLE PrivateNamespace = NULL;
|
|
|
|
static HANDLE BoundaryDescriptor = NULL;
|
2020-07-03 16:49:47 +02:00
|
|
|
static CRITICAL_SECTION Initializing;
|
|
|
|
|
2021-07-28 20:20:09 +02:00
|
|
|
static _Return_type_success_(return != FALSE)
|
|
|
|
BOOL NamespaceRuntimeInit(VOID)
|
2020-07-03 16:49:47 +02:00
|
|
|
{
|
2020-11-03 12:29:34 +01:00
|
|
|
DWORD LastError;
|
2020-07-03 16:49:47 +02:00
|
|
|
|
|
|
|
EnterCriticalSection(&Initializing);
|
2020-12-17 19:00:25 +01:00
|
|
|
if (PrivateNamespace)
|
2020-07-03 16:49:47 +02:00
|
|
|
{
|
|
|
|
LeaveCriticalSection(&Initializing);
|
2020-11-03 12:29:34 +01:00
|
|
|
return TRUE;
|
2020-07-03 16:49:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
BYTE Sid[MAX_SID_SIZE];
|
2021-06-24 12:12:13 +02:00
|
|
|
DWORD SidSize = sizeof(Sid);
|
|
|
|
if (!CreateWellKnownSid(IsLocalSystem ? WinLocalSystemSid : WinBuiltinAdministratorsSid, NULL, Sid, &SidSize))
|
2020-07-03 16:49:47 +02:00
|
|
|
{
|
2020-11-03 12:29:34 +01:00
|
|
|
LastError = LOG_LAST_ERROR(L"Failed to create SID");
|
2021-10-12 07:21:31 +02:00
|
|
|
goto cleanupLeaveCriticalSection;
|
2020-07-03 16:49:47 +02:00
|
|
|
}
|
|
|
|
|
2020-12-17 19:00:25 +01:00
|
|
|
BoundaryDescriptor = CreateBoundaryDescriptorW(L"Wintun", 0);
|
|
|
|
if (!BoundaryDescriptor)
|
2020-07-03 16:49:47 +02:00
|
|
|
{
|
2020-11-03 12:29:34 +01:00
|
|
|
LastError = LOG_LAST_ERROR(L"Failed to create boundary descriptor");
|
2021-10-12 07:21:31 +02:00
|
|
|
goto cleanupLeaveCriticalSection;
|
2020-07-03 16:49:47 +02:00
|
|
|
}
|
2020-12-17 19:00:25 +01:00
|
|
|
if (!AddSIDToBoundaryDescriptor(&BoundaryDescriptor, Sid))
|
2020-07-03 16:49:47 +02:00
|
|
|
{
|
2020-11-03 12:29:34 +01:00
|
|
|
LastError = LOG_LAST_ERROR(L"Failed to add SID to boundary descriptor");
|
2020-12-17 19:00:25 +01:00
|
|
|
goto cleanupBoundaryDescriptor;
|
2020-07-03 16:49:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
for (;;)
|
|
|
|
{
|
2020-12-17 19:00:25 +01:00
|
|
|
if ((PrivateNamespace = CreatePrivateNamespaceW(&SecurityAttributes, BoundaryDescriptor, L"Wintun")) != NULL)
|
2020-07-03 16:49:47 +02:00
|
|
|
break;
|
2020-11-03 12:29:34 +01:00
|
|
|
if ((LastError = GetLastError()) == ERROR_ALREADY_EXISTS)
|
2020-07-03 16:49:47 +02:00
|
|
|
{
|
2020-12-17 19:00:25 +01:00
|
|
|
if ((PrivateNamespace = OpenPrivateNamespaceW(BoundaryDescriptor, L"Wintun")) != NULL)
|
2020-07-03 16:49:47 +02:00
|
|
|
break;
|
2020-11-03 12:29:34 +01:00
|
|
|
if ((LastError = GetLastError()) == ERROR_PATH_NOT_FOUND)
|
2020-07-03 16:49:47 +02:00
|
|
|
continue;
|
2021-02-02 13:12:45 +01:00
|
|
|
LOG_ERROR(LastError, L"Failed to open private namespace");
|
2020-07-03 16:49:47 +02:00
|
|
|
}
|
2020-11-03 12:29:34 +01:00
|
|
|
else
|
2021-02-02 13:12:45 +01:00
|
|
|
LOG_ERROR(LastError, L"Failed to create private namespace");
|
2020-12-17 19:00:25 +01:00
|
|
|
goto cleanupBoundaryDescriptor;
|
2020-07-03 16:49:47 +02:00
|
|
|
}
|
|
|
|
|
2020-11-03 12:29:34 +01:00
|
|
|
LeaveCriticalSection(&Initializing);
|
|
|
|
return TRUE;
|
2020-07-03 16:49:47 +02:00
|
|
|
|
2020-12-17 19:00:25 +01:00
|
|
|
cleanupBoundaryDescriptor:
|
|
|
|
DeleteBoundaryDescriptor(BoundaryDescriptor);
|
2020-07-03 16:49:47 +02:00
|
|
|
cleanupLeaveCriticalSection:
|
|
|
|
LeaveCriticalSection(&Initializing);
|
2020-11-03 12:29:34 +01:00
|
|
|
SetLastError(LastError);
|
|
|
|
return FALSE;
|
2020-07-03 16:49:47 +02:00
|
|
|
}
|
|
|
|
|
2021-07-28 20:20:09 +02:00
|
|
|
_Use_decl_annotations_
|
|
|
|
HANDLE
|
2021-10-12 07:21:31 +02:00
|
|
|
NamespaceTakeDriverInstallationMutex(VOID)
|
2020-07-03 16:49:47 +02:00
|
|
|
{
|
2020-11-03 12:29:34 +01:00
|
|
|
if (!NamespaceRuntimeInit())
|
2020-07-03 16:49:47 +02:00
|
|
|
return NULL;
|
2021-10-12 07:21:31 +02:00
|
|
|
HANDLE Mutex = CreateMutexW(&SecurityAttributes, FALSE, L"Wintun\\Wintun-Driver-Installation-Mutex");
|
2020-07-03 16:49:47 +02:00
|
|
|
if (!Mutex)
|
2020-11-03 12:29:34 +01:00
|
|
|
{
|
2021-10-12 07:21:31 +02:00
|
|
|
LOG_LAST_ERROR(L"Failed to create mutex");
|
|
|
|
return NULL;
|
2020-11-03 12:29:34 +01:00
|
|
|
}
|
2021-02-02 13:12:45 +01:00
|
|
|
DWORD Result = WaitForSingleObject(Mutex, INFINITE);
|
|
|
|
switch (Result)
|
2020-07-03 16:49:47 +02:00
|
|
|
{
|
|
|
|
case WAIT_OBJECT_0:
|
|
|
|
case WAIT_ABANDONED:
|
2020-11-03 12:29:34 +01:00
|
|
|
return Mutex;
|
2020-07-03 16:49:47 +02:00
|
|
|
}
|
2021-10-12 07:21:31 +02:00
|
|
|
LOG(WINTUN_LOG_ERR, L"Failed to get mutex (status: 0x%x)", Result);
|
2020-07-03 16:49:47 +02:00
|
|
|
CloseHandle(Mutex);
|
2021-10-12 07:21:31 +02:00
|
|
|
SetLastError(ERROR_GEN_FAILURE);
|
2020-11-03 12:29:34 +01:00
|
|
|
return NULL;
|
2020-07-03 16:49:47 +02:00
|
|
|
}
|
|
|
|
|
2021-07-28 20:20:09 +02:00
|
|
|
_Use_decl_annotations_
|
|
|
|
HANDLE
|
2021-10-12 07:21:31 +02:00
|
|
|
NamespaceTakeDeviceInstallationMutex(VOID)
|
2020-11-02 12:07:05 +01:00
|
|
|
{
|
2020-11-03 12:29:34 +01:00
|
|
|
if (!NamespaceRuntimeInit())
|
2020-11-02 12:07:05 +01:00
|
|
|
return NULL;
|
2021-10-12 07:21:31 +02:00
|
|
|
HANDLE Mutex = CreateMutexW(&SecurityAttributes, FALSE, L"Wintun\\Wintun-Device-Installation-Mutex");
|
2020-11-02 12:07:05 +01:00
|
|
|
if (!Mutex)
|
2020-11-03 12:29:34 +01:00
|
|
|
{
|
|
|
|
LOG_LAST_ERROR(L"Failed to create mutex");
|
2020-11-02 12:07:05 +01:00
|
|
|
return NULL;
|
2020-11-03 12:29:34 +01:00
|
|
|
}
|
2021-02-02 13:12:45 +01:00
|
|
|
DWORD Result = WaitForSingleObject(Mutex, INFINITE);
|
|
|
|
switch (Result)
|
2020-11-02 12:07:05 +01:00
|
|
|
{
|
|
|
|
case WAIT_OBJECT_0:
|
|
|
|
case WAIT_ABANDONED:
|
2020-11-03 12:29:34 +01:00
|
|
|
return Mutex;
|
2020-11-02 12:07:05 +01:00
|
|
|
}
|
2021-02-02 13:12:45 +01:00
|
|
|
LOG(WINTUN_LOG_ERR, L"Failed to get mutex (status: 0x%x)", Result);
|
2020-11-02 12:07:05 +01:00
|
|
|
CloseHandle(Mutex);
|
2020-11-03 12:29:34 +01:00
|
|
|
SetLastError(ERROR_GEN_FAILURE);
|
|
|
|
return NULL;
|
2020-11-02 12:07:05 +01:00
|
|
|
}
|
|
|
|
|
2021-07-28 20:20:09 +02:00
|
|
|
_Use_decl_annotations_
|
|
|
|
VOID
|
|
|
|
NamespaceReleaseMutex(HANDLE Mutex)
|
2020-07-03 16:49:47 +02:00
|
|
|
{
|
|
|
|
ReleaseMutex(Mutex);
|
|
|
|
CloseHandle(Mutex);
|
|
|
|
}
|
|
|
|
|
2021-07-28 20:20:09 +02:00
|
|
|
VOID NamespaceInit(VOID)
|
2020-07-03 16:49:47 +02:00
|
|
|
{
|
|
|
|
InitializeCriticalSection(&Initializing);
|
|
|
|
}
|
|
|
|
|
2021-07-28 20:20:09 +02:00
|
|
|
VOID NamespaceDone(VOID)
|
2020-07-03 16:49:47 +02:00
|
|
|
{
|
|
|
|
EnterCriticalSection(&Initializing);
|
2020-12-17 19:00:25 +01:00
|
|
|
if (PrivateNamespace)
|
2020-07-03 16:49:47 +02:00
|
|
|
{
|
2020-12-17 19:00:25 +01:00
|
|
|
ClosePrivateNamespace(PrivateNamespace, 0);
|
|
|
|
DeleteBoundaryDescriptor(BoundaryDescriptor);
|
|
|
|
PrivateNamespace = NULL;
|
2020-07-03 16:49:47 +02:00
|
|
|
}
|
|
|
|
LeaveCriticalSection(&Initializing);
|
|
|
|
DeleteCriticalSection(&Initializing);
|
|
|
|
}
|