This repository has been archived by the owner on Dec 27, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 298
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
15 changed files
with
321 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
/* | ||
* Copyright (C) 2015-2019 Jason A. Donenfeld <[email protected]>. All Rights Reserved. | ||
*/ | ||
|
||
#define __USE_MINGW_ANSI_STDIO 1 | ||
#include <stdio.h> | ||
#include <stdbool.h> | ||
#include <stdint.h> | ||
|
||
#include <winsock2.h> | ||
#include <ws2ipdef.h> | ||
#include <ws2tcpip.h> | ||
#include <in6addr.h> | ||
#include <windows.h> | ||
|
||
#undef interface | ||
#undef min | ||
#undef max | ||
|
||
#define WINCOMPAT | ||
|
||
#define IFNAMSIZ 64 | ||
#define EAI_SYSTEM -99 | ||
|
||
/* libc.c */ | ||
char *strsep(char **str, const char *sep); | ||
ssize_t getdelim(char **buf, size_t *bufsiz, int delimiter, FILE *fp); | ||
ssize_t getline(char **buf, size_t *bufsiz, FILE *fp); | ||
int inet_pton(int af, const char *src, void *dst); | ||
const char *inet_ntop(int af, const void *src, char *dst, socklen_t size); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
/* | ||
* Copyright (C) 2015-2019 Jason A. Donenfeld <[email protected]>. All Rights Reserved. | ||
*/ | ||
|
||
#include <stdbool.h> | ||
#include <ntsecapi.h> | ||
|
||
static inline bool __attribute__((__warn_unused_result__)) get_random_bytes(uint8_t *out, size_t len) | ||
{ | ||
return RtlGenRandom(out, len); | ||
} |
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
/* | ||
* Copyright (C) 2015-2019 Jason A. Donenfeld <[email protected]>. All Rights Reserved. | ||
*/ | ||
|
||
#include <winsock2.h> | ||
#include <windows.h> | ||
|
||
#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING | ||
#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x4 | ||
#endif | ||
|
||
__attribute__((constructor)) static void init(void) | ||
{ | ||
char *colormode; | ||
DWORD console_mode; | ||
HANDLE stdout_handle; | ||
WSADATA wsaData; | ||
WSAStartup(MAKEWORD(2, 2), &wsaData); | ||
|
||
stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE); // We don't close this. | ||
if (stdout_handle == INVALID_HANDLE_VALUE) | ||
goto no_color; | ||
if (!GetConsoleMode(stdout_handle, &console_mode)) | ||
goto no_color; | ||
if (!SetConsoleMode(stdout_handle, ENABLE_VIRTUAL_TERMINAL_PROCESSING | console_mode)) | ||
goto no_color; | ||
return; | ||
|
||
no_color: | ||
colormode = getenv("WG_COLOR_MODE"); | ||
if (!colormode) | ||
putenv("WG_COLOR_MODE=never"); | ||
} | ||
|
||
__attribute__((destructor)) static void deinit(void) | ||
{ | ||
WSACleanup(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
/* | ||
* Copyright (C) 2015-2019 Jason A. Donenfeld <[email protected]>. All Rights Reserved. | ||
*/ | ||
|
||
#include <windows.h> | ||
#include <tlhelp32.h> | ||
#include <stdio.h> | ||
#include <stdbool.h> | ||
#include <fcntl.h> | ||
|
||
static FILE *userspace_interface_file(const char *interface) | ||
{ | ||
char fname[MAX_PATH], error_message[1024 * 128] = { 0 }; | ||
HANDLE thread_token, process_snapshot, winlogon_process, winlogon_token, duplicated_token, pipe_handle = INVALID_HANDLE_VALUE; | ||
PROCESSENTRY32 entry = { .dwSize = sizeof(PROCESSENTRY32) }; | ||
BOOL ret; | ||
int fd; | ||
DWORD last_error = ERROR_SUCCESS; | ||
TOKEN_PRIVILEGES privileges = { | ||
.PrivilegeCount = 1, | ||
.Privileges = {{ .Attributes = SE_PRIVILEGE_ENABLED }} | ||
}; | ||
|
||
if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &privileges.Privileges[0].Luid)) | ||
goto err; | ||
|
||
process_snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); | ||
if (process_snapshot == INVALID_HANDLE_VALUE) | ||
goto err; | ||
for (ret = Process32First(process_snapshot, &entry); ret; last_error = GetLastError(), ret = Process32Next(process_snapshot, &entry)) { | ||
if (strcasecmp(entry.szExeFile, "winlogon.exe")) | ||
continue; | ||
|
||
RevertToSelf(); | ||
if (!ImpersonateSelf(SecurityImpersonation)) | ||
continue; | ||
if (!OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES, FALSE, &thread_token)) | ||
continue; | ||
if (!AdjustTokenPrivileges(thread_token, FALSE, &privileges, sizeof(privileges), NULL, NULL)) { | ||
last_error = GetLastError(); | ||
CloseHandle(thread_token); | ||
continue; | ||
} | ||
CloseHandle(thread_token); | ||
|
||
winlogon_process = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, entry.th32ProcessID); | ||
if (!winlogon_process) | ||
continue; | ||
if (!OpenProcessToken(winlogon_process, TOKEN_IMPERSONATE | TOKEN_DUPLICATE, &winlogon_token)) | ||
continue; | ||
CloseHandle(winlogon_process); | ||
if (!DuplicateToken(winlogon_token, SecurityImpersonation, &duplicated_token)) { | ||
last_error = GetLastError(); | ||
RevertToSelf(); | ||
continue; | ||
} | ||
CloseHandle(winlogon_token); | ||
if (!SetThreadToken(NULL, duplicated_token)) { | ||
last_error = GetLastError(); | ||
CloseHandle(duplicated_token); | ||
continue; | ||
} | ||
CloseHandle(duplicated_token); | ||
|
||
snprintf(fname, sizeof(fname), "\\\\.\\pipe\\WireGuard\\%s", interface); | ||
pipe_handle = CreateFile(fname, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); | ||
last_error = GetLastError(); | ||
if (pipe_handle != INVALID_HANDLE_VALUE) { | ||
last_error = ERROR_SUCCESS; | ||
break; | ||
} | ||
} | ||
RevertToSelf(); | ||
CloseHandle(process_snapshot); | ||
|
||
if (last_error != ERROR_SUCCESS || pipe_handle == INVALID_HANDLE_VALUE) | ||
goto err; | ||
fd = _open_osfhandle((intptr_t)pipe_handle, _O_RDWR); | ||
if (fd == -1) { | ||
last_error = GetLastError(); | ||
CloseHandle(pipe_handle); | ||
goto err; | ||
} | ||
return _fdopen(fd, "r+"); | ||
|
||
err: | ||
if (last_error == ERROR_SUCCESS) | ||
last_error = GetLastError(); | ||
if (last_error == ERROR_SUCCESS) | ||
last_error = ERROR_ACCESS_DENIED; | ||
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, last_error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), error_message, sizeof(error_message) - 1, NULL); | ||
fprintf(stderr, "Error: Unable to open IPC handle via SYSTEM impersonation: %ld: %s\n", last_error, error_message); | ||
errno = EACCES; | ||
return NULL; | ||
} | ||
|
||
static int userspace_get_wireguard_interfaces(struct inflatable_buffer *buffer) | ||
{ | ||
WIN32_FIND_DATA find_data; | ||
HANDLE find_handle; | ||
int ret = 0; | ||
|
||
find_handle = FindFirstFile("\\\\.\\pipe\\*", &find_data); | ||
if (find_handle == INVALID_HANDLE_VALUE) | ||
return -GetLastError(); | ||
do { | ||
if (strncmp("WireGuard\\", find_data.cFileName, 10)) | ||
continue; | ||
buffer->next = strdup(find_data.cFileName + 10); | ||
buffer->good = true; | ||
ret = add_next_to_inflatable_buffer(buffer); | ||
if (ret < 0) | ||
goto out; | ||
} while (FindNextFile(find_handle, &find_data)); | ||
|
||
out: | ||
FindClose(find_handle); | ||
return ret; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
/* | ||
* Copyright (C) 2015-2019 Jason A. Donenfeld <[email protected]>. All Rights Reserved. | ||
*/ | ||
|
||
#include <stdio.h> | ||
#include <stdbool.h> | ||
#include <stdint.h> | ||
#include <winsock2.h> | ||
#include <ws2tcpip.h> | ||
#include <windows.h> | ||
|
||
char *strsep(char **str, const char *sep) | ||
{ | ||
char *s = *str, *end; | ||
if (!s) | ||
return NULL; | ||
end = s + strcspn(s, sep); | ||
if (*end) | ||
*end++ = 0; | ||
else | ||
end = 0; | ||
*str = end; | ||
return s; | ||
} | ||
|
||
ssize_t getdelim(char **buf, size_t *bufsiz, int delimiter, FILE *fp) | ||
{ | ||
char *ptr, *eptr; | ||
|
||
if (!*buf || !*bufsiz) { | ||
*bufsiz = BUFSIZ; | ||
if (!(*buf = malloc(*bufsiz))) | ||
return -1; | ||
} | ||
|
||
for (ptr = *buf, eptr = *buf + *bufsiz;;) { | ||
int c = fgetc(fp); | ||
if (c == -1) { | ||
if (feof(fp)) { | ||
ssize_t diff = (ssize_t)(ptr - *buf); | ||
if (diff != 0) { | ||
*ptr = '\0'; | ||
return diff; | ||
} | ||
} | ||
return -1; | ||
} | ||
*ptr++ = c; | ||
if (c == delimiter) { | ||
*ptr = '\0'; | ||
return ptr - *buf; | ||
} | ||
if (ptr + 2 >= eptr) { | ||
char *nbuf; | ||
size_t nbufsiz = *bufsiz * 2; | ||
ssize_t d = ptr - *buf; | ||
if ((nbuf = realloc(*buf, nbufsiz)) == NULL) | ||
return -1; | ||
*buf = nbuf; | ||
*bufsiz = nbufsiz; | ||
eptr = nbuf + nbufsiz; | ||
ptr = nbuf + d; | ||
} | ||
} | ||
} | ||
|
||
ssize_t getline(char **buf, size_t *bufsiz, FILE *fp) | ||
{ | ||
return getdelim(buf, bufsiz, '\n', fp); | ||
} | ||
|
||
int inet_pton(int af, const char *src, void *dst) | ||
{ | ||
struct sockaddr_storage ss = { 0 }; | ||
int size = sizeof(ss); | ||
char s[INET6_ADDRSTRLEN + 1]; | ||
|
||
strncpy(s, src, INET6_ADDRSTRLEN + 1); | ||
s[INET6_ADDRSTRLEN] = '\0'; | ||
|
||
if (WSAStringToAddress(s, af, NULL, (struct sockaddr *)&ss, &size)) | ||
return 0; | ||
if (af == AF_INET) | ||
*(struct in_addr *)dst = ((struct sockaddr_in *)&ss)->sin_addr; | ||
else if (af == AF_INET6) | ||
*(struct in6_addr *)dst = ((struct sockaddr_in6 *)&ss)->sin6_addr; | ||
else | ||
return 0; | ||
return 1; | ||
} | ||
|
||
const char *inet_ntop(int af, const void *src, char *dst, socklen_t size) | ||
{ | ||
struct sockaddr_storage ss = { .ss_family = af }; | ||
unsigned long s = size; | ||
|
||
if (af == AF_INET) | ||
((struct sockaddr_in *)&ss)->sin_addr = *(struct in_addr *)src; | ||
else if (af == AF_INET6) | ||
((struct sockaddr_in6 *)&ss)->sin6_addr = *(struct in6_addr *)src; | ||
else | ||
return NULL; | ||
return WSAAddressToString((struct sockaddr *)&ss, sizeof(ss), NULL, dst, &s) ? NULL : dst; | ||
} |