This commit is contained in:
parent
d5e1142bce
commit
dd8970758a
@ -16,5 +16,10 @@
|
|||||||
<option name="name" value="MavenRepo" />
|
<option name="name" value="MavenRepo" />
|
||||||
<option name="url" value="https://repo.maven.apache.org/maven2/" />
|
<option name="url" value="https://repo.maven.apache.org/maven2/" />
|
||||||
</remote-repository>
|
</remote-repository>
|
||||||
|
<remote-repository>
|
||||||
|
<option name="id" value="Gitea" />
|
||||||
|
<option name="name" value="Gitea" />
|
||||||
|
<option name="url" value="https://git.nevets.tech/api/packages/Steven/maven" />
|
||||||
|
</remote-repository>
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
6
.idea/kotlinc.xml
Normal file
6
.idea/kotlinc.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="KotlinJpsPluginSettings">
|
||||||
|
<option name="version" value="1.9.21" />
|
||||||
|
</component>
|
||||||
|
</project>
|
8
.idea/modules.xml
Normal file
8
.idea/modules.xml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/modules/TVPN.main.iml" filepath="$PROJECT_DIR$/.idea/modules/TVPN.main.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
8
.idea/modules/TVPN.main.iml
Normal file
8
.idea/modules/TVPN.main.iml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module version="4">
|
||||||
|
<component name="AdditionalModuleElements">
|
||||||
|
<content url="file://$MODULE_DIR$/../../src/main" dumb="true">
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/../../src/main/kotlin" isTestSource="false" />
|
||||||
|
</content>
|
||||||
|
</component>
|
||||||
|
</module>
|
3
build-dll.bat
Normal file
3
build-dll.bat
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
@echo off
|
||||||
|
cmake -DCMAKE_BUILD_TYPE=Release -G "CodeBlocks - MinGW Makefiles" -S .\src\main\cpp -B .\src\main\cpp\build
|
||||||
|
cmake --build .\src\main\cpp\build --target wireguard_wrapper -- -j 14
|
55
build.gradle.kts
Normal file
55
build.gradle.kts
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
plugins {
|
||||||
|
java
|
||||||
|
kotlin("jvm") version "1.9.21"
|
||||||
|
id("com.github.johnrengelman.shadow") version "8.1.1"
|
||||||
|
id("edu.sc.seis.launch4j") version "3.0.6"
|
||||||
|
}
|
||||||
|
|
||||||
|
group = "tech.nevets"
|
||||||
|
version = "0.3.1"
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
maven {
|
||||||
|
url = uri("https://git.nevets.tech/api/packages/Steven/maven")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation("com.miglayout:miglayout-swing:11.4.2")
|
||||||
|
implementation("com.miglayout:miglayout-core:11.4.2")
|
||||||
|
implementation("com.formdev:flatlaf:3.5.1")
|
||||||
|
implementation("com.google.code.gson:gson:2.11.0")
|
||||||
|
implementation("tech.nevets:JConf:0.1.0:no-deps")
|
||||||
|
}
|
||||||
|
|
||||||
|
kotlin {
|
||||||
|
jvmToolchain(21)
|
||||||
|
}
|
||||||
|
|
||||||
|
//tasks.withType(JavaCompile).configureEach {
|
||||||
|
// options.encoding = "UTF-8"
|
||||||
|
//}
|
||||||
|
|
||||||
|
tasks.jar {
|
||||||
|
manifest {
|
||||||
|
attributes["Main-Class"] = "tech.nevets.tvpn.Main"
|
||||||
|
}
|
||||||
|
configurations["compileClasspath"].forEach { file: File ->
|
||||||
|
from(zipTree(file.absoluteFile))
|
||||||
|
}
|
||||||
|
duplicatesStrategy = DuplicatesStrategy.INCLUDE
|
||||||
|
}
|
||||||
|
|
||||||
|
launch4j {
|
||||||
|
mainClassName.set("tech.nevets.tvpn.Main")
|
||||||
|
outfile.set("TVPN.exe")
|
||||||
|
setJarTask(project.tasks["shadowJar"])
|
||||||
|
fileDescription.set("TVPN Client")
|
||||||
|
icon.set("$projectDir/src/main/resources/icon.ico")
|
||||||
|
productName.set("TVPN")
|
||||||
|
version.set("$this.version")
|
||||||
|
textVersion.set("$this.version")
|
||||||
|
bundledJrePath.set("./jre")
|
||||||
|
manifest.set("$projectDir/TVPN.exe.manifest")
|
||||||
|
}
|
@ -1,2 +1,2 @@
|
|||||||
org.gradle.jvmargs=-Xmx8192M
|
org.gradle.jvmargs=-Xmx8192M -Dfile.encoding=UTF-8
|
||||||
org.gradle.parallel=true
|
org.gradle.parallel=true
|
||||||
|
@ -1,2 +0,0 @@
|
|||||||
rootProject.name = 'TVPN'
|
|
||||||
|
|
1
settings.gradle.kts
Normal file
1
settings.gradle.kts
Normal file
@ -0,0 +1 @@
|
|||||||
|
rootProject.name = "TVPN"
|
@ -15,9 +15,11 @@ set(JNI_INCLUDE_DIR2 "${JAVA_HOME}/include/win32")
|
|||||||
include_directories(${JNI_INCLUDE_DIR} ${JNI_INCLUDE_DIR2})
|
include_directories(${JNI_INCLUDE_DIR} ${JNI_INCLUDE_DIR2})
|
||||||
|
|
||||||
# Add the source file that includes your JNI C wrapper code
|
# Add the source file that includes your JNI C wrapper code
|
||||||
add_library(wireguard_wrapper SHARED wireguard_wrapper.c)
|
add_library(wireguard_wrapper SHARED wireguard_wrapper.c
|
||||||
|
example.c)
|
||||||
|
|
||||||
target_link_libraries(wireguard_wrapper PRIVATE Rpcrt4)
|
#target_link_libraries(wireguard_wrapper PRIVATE Rpcrt4)
|
||||||
|
target_link_libraries(wireguard_wrapper ws2_32 rpcrt4)
|
||||||
|
|
||||||
# Optionally, you can specify output directory for the compiled library
|
# Optionally, you can specify output directory for the compiled library
|
||||||
set_target_properties(wireguard_wrapper PROPERTIES
|
set_target_properties(wireguard_wrapper PROPERTIES
|
||||||
|
4
src/main/cpp/build.ps1
Normal file
4
src/main/cpp/build.ps1
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
Get-ChildItem -Path build -Recurse | Remove-Item -force -recurse
|
||||||
|
if (Test-Path -Path .\build) { Remove-Item -Path .\build -Recurse -Force }
|
||||||
|
cmake -DCMAKE_BUILD_TYPE=Release -G "CodeBlocks - MinGW Makefiles" -S . -B .\build
|
||||||
|
cmake --build .\build --target wireguard_wrapper -- -j 14
|
@ -276,10 +276,19 @@ int __cdecl main(void)
|
|||||||
WIREGUARD_INTERFACE Interface;
|
WIREGUARD_INTERFACE Interface;
|
||||||
WIREGUARD_PEER DemoServer;
|
WIREGUARD_PEER DemoServer;
|
||||||
WIREGUARD_ALLOWED_IP AllV4;
|
WIREGUARD_ALLOWED_IP AllV4;
|
||||||
} Config = { .Interface = { .Flags = WIREGUARD_INTERFACE_HAS_PRIVATE_KEY, .PeersCount = 1 },
|
} Config = {
|
||||||
.DemoServer = { .Flags = WIREGUARD_PEER_HAS_PUBLIC_KEY | WIREGUARD_PEER_HAS_ENDPOINT,
|
.Interface = {
|
||||||
.AllowedIPsCount = 1 },
|
.Flags = WIREGUARD_INTERFACE_HAS_PRIVATE_KEY,
|
||||||
.AllV4 = { .AddressFamily = AF_INET } };
|
.PeersCount = 1
|
||||||
|
},
|
||||||
|
.DemoServer = {
|
||||||
|
.Flags = WIREGUARD_PEER_HAS_PUBLIC_KEY | WIREGUARD_PEER_HAS_ENDPOINT,
|
||||||
|
.AllowedIPsCount = 1
|
||||||
|
},
|
||||||
|
.AllV4 = {
|
||||||
|
.AddressFamily = AF_INET
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
Log(WIREGUARD_LOG_INFO, L"Generating keypair");
|
Log(WIREGUARD_LOG_INFO, L"Generating keypair");
|
||||||
BYTE PublicKey[WIREGUARD_KEY_LENGTH];
|
BYTE PublicKey[WIREGUARD_KEY_LENGTH];
|
||||||
|
@ -1,17 +1,23 @@
|
|||||||
#include <jni.h>
|
#include <jni.h>
|
||||||
#include <rpc.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
|
||||||
#include <wchar.h>
|
#include <wchar.h>
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include "wireguard.h"
|
#include "wireguard.h"
|
||||||
|
#include <string.h>
|
||||||
|
#include <ws2tcpip.h>
|
||||||
#include "tech_nevets_tvpn_wg_WireGuardJNI.h"
|
#include "tech_nevets_tvpn_wg_WireGuardJNI.h"
|
||||||
|
|
||||||
#pragma comment(lib, "Rpcrt4.lib")
|
#pragma comment(lib, "Rpcrt4.lib")
|
||||||
|
|
||||||
const wchar_t *APP_DIR = L"C:\\Program Files\\TVPN\\";
|
const wchar_t *APP_DIR = L"C:\\Program Files\\TVPN\\";
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
WIREGUARD_INTERFACE Interface;
|
||||||
|
WIREGUARD_PEER Peer;
|
||||||
|
WIREGUARD_ALLOWED_IP AllowedIP;
|
||||||
|
} Config;
|
||||||
|
|
||||||
static WIREGUARD_CREATE_ADAPTER_FUNC *WireGuardCreateAdapter;
|
static WIREGUARD_CREATE_ADAPTER_FUNC *WireGuardCreateAdapter;
|
||||||
static WIREGUARD_OPEN_ADAPTER_FUNC *WireGuardOpenAdapter;
|
static WIREGUARD_OPEN_ADAPTER_FUNC *WireGuardOpenAdapter;
|
||||||
static WIREGUARD_CLOSE_ADAPTER_FUNC *WireGuardCloseAdapter;
|
static WIREGUARD_CLOSE_ADAPTER_FUNC *WireGuardCloseAdapter;
|
||||||
@ -26,12 +32,12 @@ static WIREGUARD_GET_CONFIGURATION_FUNC *WireGuardGetConfiguration;
|
|||||||
static WIREGUARD_SET_CONFIGURATION_FUNC *WireGuardSetConfiguration;
|
static WIREGUARD_SET_CONFIGURATION_FUNC *WireGuardSetConfiguration;
|
||||||
|
|
||||||
static HMODULE InitializeWireGuardNT(void) {
|
static HMODULE InitializeWireGuardNT(void) {
|
||||||
HMODULE WireGuardDll = LoadLibraryExW(
|
printf("[C] Starting InitializeWireGuardNT!\n");
|
||||||
L"wireguard.dll",
|
HMODULE WireGuardDll = LoadLibraryW(L"wireguard.dll");
|
||||||
NULL,
|
if (!WireGuardDll) {
|
||||||
LOAD_LIBRARY_SEARCH_APPLICATION_DIR | LOAD_LIBRARY_SEARCH_SYSTEM32
|
printf("[C] Error loading wireguard.dll\n");
|
||||||
);
|
return NULL;
|
||||||
if (!WireGuardDll) return NULL;
|
}
|
||||||
#define X(Name) ((*(FARPROC *)&Name = GetProcAddress(WireGuardDll, #Name)) == NULL)
|
#define X(Name) ((*(FARPROC *)&Name = GetProcAddress(WireGuardDll, #Name)) == NULL)
|
||||||
if (X(WireGuardCreateAdapter) || X(WireGuardOpenAdapter) || X(WireGuardCloseAdapter) ||
|
if (X(WireGuardCreateAdapter) || X(WireGuardOpenAdapter) || X(WireGuardCloseAdapter) ||
|
||||||
X(WireGuardGetAdapterLUID) || X(WireGuardGetRunningDriverVersion) || X(WireGuardDeleteDriver) ||
|
X(WireGuardGetAdapterLUID) || X(WireGuardGetRunningDriverVersion) || X(WireGuardDeleteDriver) ||
|
||||||
@ -40,14 +46,16 @@ static HMODULE InitializeWireGuardNT(void) {
|
|||||||
#undef X
|
#undef X
|
||||||
{
|
{
|
||||||
DWORD LastError = GetLastError();
|
DWORD LastError = GetLastError();
|
||||||
|
fprintf(stderr, "[C] Failed to load wireguard.dll, error code: %lu\n", LastError);
|
||||||
FreeLibrary(WireGuardDll);
|
FreeLibrary(WireGuardDll);
|
||||||
SetLastError(LastError);
|
SetLastError(LastError);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
printf("[C] Finished Init WG.dll\n");
|
||||||
return WireGuardDll;
|
return WireGuardDll;
|
||||||
}
|
}
|
||||||
|
|
||||||
GUID generateGUID() {
|
static GUID generateGUID(void) {
|
||||||
UUID uuid;
|
UUID uuid;
|
||||||
RPC_STATUS status = UuidCreate(&uuid);
|
RPC_STATUS status = UuidCreate(&uuid);
|
||||||
|
|
||||||
@ -115,7 +123,7 @@ JNIEXPORT jint JNICALL Java_tech_nevets_tvpn_wg_WireGuardJNI_installTunnel(JNIEn
|
|||||||
const jchar *rawStr = (*env)->GetStringChars(env, tunnelName, 0); //TODO mem cleanup
|
const jchar *rawStr = (*env)->GetStringChars(env, tunnelName, 0); //TODO mem cleanup
|
||||||
LPWSTR tnlName = (LPWSTR) rawStr;
|
LPWSTR tnlName = (LPWSTR) rawStr;
|
||||||
|
|
||||||
wprintf(L"[C] Tunnel Name: %ls", tnlName);
|
wprintf(L"[C] Tunnel Name: %ls\n", tnlName);
|
||||||
|
|
||||||
wchar_t *servicePrefix = L"WireGuardTunnel$";
|
wchar_t *servicePrefix = L"WireGuardTunnel$";
|
||||||
wchar_t *serviceName = malloc(sizeof(wchar_t) * (wcslen(servicePrefix) + wcslen(tnlName) + 1)); //TODO mem cleanup
|
wchar_t *serviceName = malloc(sizeof(wchar_t) * (wcslen(servicePrefix) + wcslen(tnlName) + 1)); //TODO mem cleanup
|
||||||
@ -244,4 +252,115 @@ JNIEXPORT jint JNICALL Java_tech_nevets_tvpn_wg_WireGuardJNI_removeTunnel(JNIEnv
|
|||||||
free(tnlName);
|
free(tnlName);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jlong JNICALL Java_tech_nevets_tvpn_wg_WireGuardJNI_getWGVersion(JNIEnv *env, jobject obj) {
|
||||||
|
WSADATA WsaData;
|
||||||
|
if (WSAStartup(MAKEWORD(2, 2), &WsaData)) {
|
||||||
|
fprintf(stderr, "[C] Failed to initialize Winsock\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
HMODULE WireGuardDLL = InitializeWireGuardNT();
|
||||||
|
printf("[C] Post Init WGNT\n");
|
||||||
|
|
||||||
|
if (WireGuardDLL == NULL) {
|
||||||
|
fprintf(stderr, "[C] Failed to initialize WireGuardNT library\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD Version = WireGuardGetRunningDriverVersion();
|
||||||
|
printf("[C] Before Printed version\n");
|
||||||
|
|
||||||
|
|
||||||
|
//printf("[C] WG Ver: %lu\n", Version);
|
||||||
|
wprintf(L"WireGuardNT v%u.%u loaded", (Version >> 16) & 0xff, (Version >> 0) & 0xff);
|
||||||
|
|
||||||
|
FreeLibrary(WireGuardDLL);
|
||||||
|
return Version;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jlong JNICALL Java_tech_nevets_tvpn_wg_WireGuardJNI_parseConfig(JNIEnv *env, jobject obj, jobject conf) {
|
||||||
|
// Allocate memory for Config struct
|
||||||
|
Config *config = (Config *)malloc(sizeof(Config));
|
||||||
|
if (config == NULL) {
|
||||||
|
return 0; // Memory allocation failed
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get WGConf class and fields
|
||||||
|
jclass wgConfClass = (*env)->GetObjectClass(env, conf);
|
||||||
|
|
||||||
|
// Step 1: Fill Interface fields
|
||||||
|
jfieldID ifaceFieldID = (*env)->GetFieldID(env, wgConfClass, "iface", "Ltech/nevets/tvpn/wg/WGConf$Interface;");
|
||||||
|
jobject ifaceObj = (*env)->GetObjectField(env, conf, ifaceFieldID);
|
||||||
|
|
||||||
|
jclass ifaceClass = (*env)->GetObjectClass(env, ifaceObj);
|
||||||
|
config->Interface.Flags = (WIREGUARD_INTERFACE_FLAG)(*env)->GetIntField(env, ifaceObj, (*env)->GetFieldID(env, ifaceClass, "flags", "I"));
|
||||||
|
config->Interface.ListenPort = (WORD)(*env)->GetIntField(env, ifaceObj, (*env)->GetFieldID(env, ifaceClass, "port", "I"));
|
||||||
|
|
||||||
|
// Get and copy privateKey
|
||||||
|
jbyteArray privateKeyArray = (jbyteArray)(*env)->GetObjectField(env, ifaceObj, (*env)->GetFieldID(env, ifaceClass, "privateKey", "[B"));
|
||||||
|
(*env)->GetByteArrayRegion(env, privateKeyArray, 0, WIREGUARD_KEY_LENGTH, (jbyte *)config->Interface.PrivateKey);
|
||||||
|
|
||||||
|
// Get and copy publicKey
|
||||||
|
jbyteArray publicKeyArray = (jbyteArray)(*env)->GetObjectField(env, ifaceObj, (*env)->GetFieldID(env, ifaceClass, "publicKey", "[B"));
|
||||||
|
(*env)->GetByteArrayRegion(env, publicKeyArray, 0, WIREGUARD_KEY_LENGTH, (jbyte *)config->Interface.PublicKey);
|
||||||
|
|
||||||
|
config->Interface.PeersCount = (DWORD)(*env)->GetIntField(env, ifaceObj, (*env)->GetFieldID(env, ifaceClass, "peersCount", "I"));
|
||||||
|
|
||||||
|
// Step 2: Fill Peer fields
|
||||||
|
jfieldID peerFieldID = (*env)->GetFieldID(env, wgConfClass, "peer", "Ltech/nevets/tvpn/wg/WGConf$Peer;");
|
||||||
|
jobject peerObj = (*env)->GetObjectField(env, conf, peerFieldID);
|
||||||
|
|
||||||
|
jclass peerClass = (*env)->GetObjectClass(env, peerObj);
|
||||||
|
config->Peer.Flags = (WIREGUARD_PEER_FLAG)(*env)->GetIntField(env, peerObj, (*env)->GetFieldID(env, peerClass, "flags", "I"));
|
||||||
|
config->Peer.Reserved = (DWORD)(*env)->GetIntField(env, peerObj, (*env)->GetFieldID(env, peerClass, "reserved", "I"));
|
||||||
|
|
||||||
|
// Get and copy publicKey
|
||||||
|
jbyteArray peerPublicKeyArray = (jbyteArray)(*env)->GetObjectField(env, peerObj, (*env)->GetFieldID(env, peerClass, "publicKey", "[B"));
|
||||||
|
(*env)->GetByteArrayRegion(env, peerPublicKeyArray, 0, WIREGUARD_KEY_LENGTH, (jbyte *)config->Peer.PublicKey);
|
||||||
|
|
||||||
|
// Get and copy presharedKey
|
||||||
|
jbyteArray presharedKeyArray = (jbyteArray)(*env)->GetObjectField(env, peerObj, (*env)->GetFieldID(env, peerClass, "presharedKey", "[B"));
|
||||||
|
(*env)->GetByteArrayRegion(env, presharedKeyArray, 0, WIREGUARD_KEY_LENGTH, (jbyte *)config->Peer.PresharedKey);
|
||||||
|
|
||||||
|
config->Peer.PersistentKeepalive = (WORD)(*env)->GetIntField(env, peerObj, (*env)->GetFieldID(env, peerClass, "persistentKeepalive", "I"));
|
||||||
|
config->Peer.AllowedIPsCount = (DWORD)(*env)->GetIntField(env, peerObj, (*env)->GetFieldID(env, peerClass, "allowedIPsCount", "I"));
|
||||||
|
|
||||||
|
// Endpoint is more complex: requires parsing from byte array and setting `SOCKADDR_INET`
|
||||||
|
jbyteArray endpointArray = (jbyteArray)(*env)->GetObjectField(env, peerObj, (*env)->GetFieldID(env, peerClass, "endpoint", "[B"));
|
||||||
|
jsize endpointLen = (*env)->GetArrayLength(env, endpointArray);
|
||||||
|
jbyte *endpointBytes = (*env)->GetByteArrayElements(env, endpointArray, NULL);
|
||||||
|
|
||||||
|
if (endpointLen == sizeof(SOCKADDR_INET)) {
|
||||||
|
memcpy(&config->Peer.Endpoint, endpointBytes, sizeof(SOCKADDR_INET));
|
||||||
|
}
|
||||||
|
(*env)->ReleaseByteArrayElements(env, endpointArray, endpointBytes, 0);
|
||||||
|
|
||||||
|
// Step 3: Fill AllowedIP fields
|
||||||
|
jfieldID allowedIPFieldID = (*env)->GetFieldID(env, wgConfClass, "allowedIP", "Ltech/nevets/tvpn/wg/WGConf$AllowedIP;");
|
||||||
|
jobject allowedIPObj = (*env)->GetObjectField(env, conf, allowedIPFieldID);
|
||||||
|
|
||||||
|
jclass allowedIPClass = (*env)->GetObjectClass(env, allowedIPObj);
|
||||||
|
jstring addressStr = (jstring)(*env)->GetObjectField(env, allowedIPObj, (*env)->GetFieldID(env, allowedIPClass, "address", "Ljava/lang/String;"));
|
||||||
|
const char *addressChars = (*env)->GetStringUTFChars(env, addressStr, NULL);
|
||||||
|
|
||||||
|
// Assuming address parsing logic here, converting to either IN_ADDR or IN6_ADDR based on `addressFamily`
|
||||||
|
jstring familyStr = (jstring)(*env)->GetObjectField(env, allowedIPObj, (*env)->GetFieldID(env, allowedIPClass, "addressFamily", "Ljava/lang/String;"));
|
||||||
|
const char *familyChars = (*env)->GetStringUTFChars(env, familyStr, NULL);
|
||||||
|
|
||||||
|
if (strcmp(familyChars, "AF_INET") == 0) {
|
||||||
|
config->AllowedIP.AddressFamily = AF_INET;
|
||||||
|
inet_pton(AF_INET, addressChars, &config->AllowedIP.Address.V4);
|
||||||
|
} else if (strcmp(familyChars, "AF_INET6") == 0) {
|
||||||
|
config->AllowedIP.AddressFamily = AF_INET6;
|
||||||
|
inet_pton(AF_INET6, addressChars, &config->AllowedIP.Address.V6);
|
||||||
|
}
|
||||||
|
(*env)->ReleaseStringUTFChars(env, familyStr, familyChars);
|
||||||
|
(*env)->ReleaseStringUTFChars(env, addressStr, addressChars);
|
||||||
|
|
||||||
|
config->AllowedIP.Cidr = (BYTE)(*env)->GetByteField(env, allowedIPObj, (*env)->GetFieldID(env, allowedIPClass, "cidr", "B"));
|
||||||
|
|
||||||
|
// Return the pointer to Config struct as jlong
|
||||||
|
return (jlong)(uintptr_t)config;
|
||||||
|
|
||||||
}
|
}
|
@ -43,6 +43,8 @@ public class LogOutputStream extends OutputStream {
|
|||||||
for (int i = 0; i < pointer; i++) {
|
for (int i = 0; i < pointer; i++) {
|
||||||
sb.append(buf[i]);
|
sb.append(buf[i]);
|
||||||
}
|
}
|
||||||
textArea.append(sb.toString());
|
if (textArea != null) {
|
||||||
|
textArea.append(sb.toString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,20 +2,20 @@ package tech.nevets.tvpn;
|
|||||||
|
|
||||||
import com.formdev.flatlaf.FlatDarkLaf;
|
import com.formdev.flatlaf.FlatDarkLaf;
|
||||||
import tech.nevets.jconf.JsonConfig;
|
import tech.nevets.jconf.JsonConfig;
|
||||||
import tech.nevets.tvpn.cli.CommandBrigadier;
|
|
||||||
import tech.nevets.tvpn.ui.UIManager;
|
import tech.nevets.tvpn.ui.UIManager;
|
||||||
import tech.nevets.tvpn.wg.WireGuardJNI;
|
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
||||||
|
import tech.nevets.tvpn.cli.CommandBrigadier;
|
||||||
|
|
||||||
public class Main {
|
public class Main {
|
||||||
private static final Logger LOGGER = new Logger(Main.class);
|
private static final Logger LOGGER = new Logger(Main.class);
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
LogOutputStream logOut = new LogOutputStream();
|
LogOutputStream logOut = new LogOutputStream();
|
||||||
Logger.loadLogOutStream(logOut);
|
Logger.loadLogOutStream(logOut);
|
||||||
|
|
||||||
JsonConfig conf = new JsonConfig("");
|
JsonConfig conf = new JsonConfig("config.json");
|
||||||
|
|
||||||
if (args.length > 0) {
|
if (args.length > 0) {
|
||||||
new CommandBrigadier().execute(args);
|
new CommandBrigadier().execute(args);
|
||||||
|
@ -1,12 +0,0 @@
|
|||||||
package tech.nevets.tvpn.cli;
|
|
||||||
|
|
||||||
public interface Command {
|
|
||||||
|
|
||||||
void execute(String[] args);
|
|
||||||
|
|
||||||
String getName();
|
|
||||||
|
|
||||||
String getUsage();
|
|
||||||
|
|
||||||
String getDescription();
|
|
||||||
}
|
|
@ -1,49 +0,0 @@
|
|||||||
package tech.nevets.tvpn.cli;
|
|
||||||
|
|
||||||
import tech.nevets.tvpn.Logger;
|
|
||||||
import tech.nevets.tvpn.cli.commands.HelpCmd;
|
|
||||||
import tech.nevets.tvpn.cli.commands.InstallTunnelServiceCmd;
|
|
||||||
import tech.nevets.tvpn.cli.commands.UninstallTunnelServiceCmd;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class CommandBrigadier {
|
|
||||||
private static final Logger LOGGER = new Logger(CommandBrigadier.class);
|
|
||||||
|
|
||||||
private final List<Command> registeredCommands;
|
|
||||||
private final HelpCmd helpCmd;
|
|
||||||
|
|
||||||
public CommandBrigadier() {
|
|
||||||
this.registeredCommands = new ArrayList<>();
|
|
||||||
helpCmd = new HelpCmd(this);
|
|
||||||
|
|
||||||
registerCommand(helpCmd);
|
|
||||||
registerCommand(new InstallTunnelServiceCmd());
|
|
||||||
registerCommand(new UninstallTunnelServiceCmd());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void registerCommand(Command cmd) {
|
|
||||||
for (Command c : registeredCommands) {
|
|
||||||
if (c.getName().equals(cmd.getName())) {
|
|
||||||
LOGGER.warn("Command with name " + cmd.getName() + " already registered, skipping.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
registeredCommands.add(cmd);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void execute(String[] args) {
|
|
||||||
for (Command c : registeredCommands) {
|
|
||||||
if (c.getName().equals(args[0])) {
|
|
||||||
c.execute(args);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
helpCmd.execute(new String[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Command> getCommands() {
|
|
||||||
return registeredCommands;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,52 +0,0 @@
|
|||||||
package tech.nevets.tvpn.cli.commands;
|
|
||||||
|
|
||||||
import tech.nevets.tvpn.cli.Command;
|
|
||||||
import tech.nevets.tvpn.cli.CommandBrigadier;
|
|
||||||
|
|
||||||
public class HelpCmd implements Command {
|
|
||||||
private final CommandBrigadier cb;
|
|
||||||
|
|
||||||
public HelpCmd(CommandBrigadier cb) {
|
|
||||||
this.cb = cb;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void execute(String[] args) {
|
|
||||||
if (args.length > 0) {
|
|
||||||
for (Command c : cb.getCommands()) {
|
|
||||||
if (!(args.length == 1) && args[1].equals(c.getName())) {
|
|
||||||
System.out.println("TVPN - Usage Menu [" + c.getName() + "]");
|
|
||||||
System.out.println(c.getName() + " " + c.getUsage() + ": " + c.getDescription());
|
|
||||||
System.exit(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
sb.append("TVPN - Help Menu\n");
|
|
||||||
for (Command c : cb.getCommands()) {
|
|
||||||
sb.append(" - ").append(c.getName())
|
|
||||||
.append(" ").append(c.getUsage())
|
|
||||||
.append(": ").append(c.getDescription())
|
|
||||||
.append("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
System.out.println(sb);
|
|
||||||
System.exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return "help";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getUsage() {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getDescription() {
|
|
||||||
return "Displays the help menu";
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,71 +0,0 @@
|
|||||||
package tech.nevets.tvpn.cli.commands;
|
|
||||||
|
|
||||||
import tech.nevets.tvpn.Utils;
|
|
||||||
import tech.nevets.tvpn.cli.Command;
|
|
||||||
import tech.nevets.tvpn.wg.WireGuardJNI;
|
|
||||||
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
public class InstallTunnelServiceCmd implements Command {
|
|
||||||
@Override
|
|
||||||
public void execute(String[] args) {
|
|
||||||
|
|
||||||
|
|
||||||
System.out.println("Executing InstallTunnelServiceCmd");
|
|
||||||
String path = Utils.APP_DIR + "/configurations/" + args[1] + ".conf";
|
|
||||||
System.out.println(new WireGuardJNI().installTunnel(args[1], path));
|
|
||||||
System.exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return "/installtunnelservice";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getUsage() {
|
|
||||||
return "(/path/to/tunnel/config)";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getDescription() {
|
|
||||||
return "Creates and starts a WireGuard Tunnel Service";
|
|
||||||
}
|
|
||||||
|
|
||||||
String[] reservedNames = new String[]{
|
|
||||||
"CON", "PRN", "AUX", "NUL",
|
|
||||||
"COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9",
|
|
||||||
"LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9",
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
private boolean isReserved(String name) {
|
|
||||||
if (name.isEmpty()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
for (String s : reservedNames) {
|
|
||||||
if (name.contains(s)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final String[] SPECIAL_CHARS = new String[]{"$", "\\", "/", ":", "*", "?", "\"", "'", "<", ">", "|", "\t", "\00"};
|
|
||||||
private boolean hasSpecialChars(String name) {
|
|
||||||
for (String s : SPECIAL_CHARS) {
|
|
||||||
if (name.contains(s)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Pattern PATTERN = Pattern.compile("^[a-zA-Z0-9_=+.-]{1,32}$");
|
|
||||||
private boolean tunnelNameIsValid(String name) {
|
|
||||||
if (isReserved(name) || hasSpecialChars(name)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return PATTERN.matcher(name).hasMatch();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
package tech.nevets.tvpn.cli.commands;
|
|
||||||
|
|
||||||
import tech.nevets.tvpn.cli.Command;
|
|
||||||
import tech.nevets.tvpn.wg.WireGuardJNI;
|
|
||||||
|
|
||||||
public class UninstallTunnelServiceCmd implements Command {
|
|
||||||
@Override
|
|
||||||
public void execute(String[] args) {
|
|
||||||
System.out.println("Executing UnInstallTunnelServiceCmd");
|
|
||||||
System.out.println(new WireGuardJNI().removeTunnel(args[1]));
|
|
||||||
System.exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return "/uninstalltunnelservice";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getUsage() {
|
|
||||||
return "(tunnel name)";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getDescription() {
|
|
||||||
return "Stops and removes WireGuard Tunnel Service";
|
|
||||||
}
|
|
||||||
}
|
|
92
src/main/java/tech/nevets/tvpn/wg/WGConf.java
Normal file
92
src/main/java/tech/nevets/tvpn/wg/WGConf.java
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
package tech.nevets.tvpn.wg;
|
||||||
|
|
||||||
|
public class WGConf {
|
||||||
|
public Interface iface;
|
||||||
|
public Peer peer;
|
||||||
|
public AllowedIP allowedIP;
|
||||||
|
|
||||||
|
public WGConf(Interface iface, Peer peer, AllowedIP allowedIP) {
|
||||||
|
this.iface = iface;
|
||||||
|
this.peer = peer;
|
||||||
|
this.allowedIP = allowedIP;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
struct WIREGUARD_INTERFACE {
|
||||||
|
WIREGUARD_INTERFACE_FLAG Flags; < Bitwise combination of flags
|
||||||
|
WORD ListenPort; < Port for UDP listen socket, or 0 to choose randomly
|
||||||
|
BYTE PrivateKey[WIREGUARD_KEY_LENGTH]; < Private key of interface
|
||||||
|
BYTE PublicKey[WIREGUARD_KEY_LENGTH]; < Corresponding public key of private key
|
||||||
|
DWORD PeersCount; < Number of peer structs following this struct
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
WIREGUARD_INTERFACE_HAS_PUBLIC_KEY = (1 << 0), < The PublicKey field is set
|
||||||
|
WIREGUARD_INTERFACE_HAS_PRIVATE_KEY = (1 << 1), < The PrivateKey field is set
|
||||||
|
WIREGUARD_INTERFACE_HAS_LISTEN_PORT = (1 << 2), < The ListenPort field is set
|
||||||
|
WIREGUARD_INTERFACE_REPLACE_PEERS = (1 << 3) < Remove all peers before adding new ones
|
||||||
|
} WIREGUARD_INTERFACE_FLAG;
|
||||||
|
*/
|
||||||
|
public class Interface {
|
||||||
|
public int flags;
|
||||||
|
public int port; // Should be 0 for random
|
||||||
|
public byte[] privateKey;
|
||||||
|
public byte[] publicKey; // Should be unused, will be calculated by privateKey
|
||||||
|
public int peersCount; // Should be 1
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
struct WIREGUARD_PEER {
|
||||||
|
WIREGUARD_PEER_FLAG Flags; < Bitwise combination of flags
|
||||||
|
DWORD Reserved; < Reserved; must be zero
|
||||||
|
BYTE PublicKey[32]; < Public key, the peer's primary identifier
|
||||||
|
BYTE PresharedKey[32]; < Preshared key for additional layer of post-quantum resistance
|
||||||
|
WORD PersistentKeepalive; < Seconds interval, or 0 to disable
|
||||||
|
SOCKADDR_INET Endpoint; < Endpoint, with IP address and UDP port number
|
||||||
|
DWORD64 TxBytes; < Number of bytes transmitted
|
||||||
|
DWORD64 RxBytes; < Number of bytes received
|
||||||
|
DWORD64 LastHandshake; < Time of the last handshake, in 100ns intervals since 1601-01-01 UTC
|
||||||
|
DWORD AllowedIPsCount; < Number of allowed IP structs following this struct
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
WIREGUARD_PEER_HAS_PUBLIC_KEY = 1 << 0, < The PublicKey field is set
|
||||||
|
WIREGUARD_PEER_HAS_PRESHARED_KEY = 1 << 1, < The PresharedKey field is set
|
||||||
|
WIREGUARD_PEER_HAS_PERSISTENT_KEEPALIVE = 1 << 2, < The PersistentKeepAlive field is set
|
||||||
|
WIREGUARD_PEER_HAS_ENDPOINT = 1 << 3, < The Endpoint field is set
|
||||||
|
WIREGUARD_PEER_REPLACE_ALLOWED_IPS = 1 << 5, < Remove all allowed IPs before adding new ones
|
||||||
|
WIREGUARD_PEER_REMOVE = 1 << 6, < Remove specified peer
|
||||||
|
WIREGUARD_PEER_UPDATE = 1 << 7 < Do not add a new peer
|
||||||
|
} WIREGUARD_PEER_FLAG;
|
||||||
|
*/
|
||||||
|
public class Peer {
|
||||||
|
public int flags;
|
||||||
|
public int reserved = 0; // "Must be 0"
|
||||||
|
public byte[] publicKey;
|
||||||
|
public byte[] presharedKey;
|
||||||
|
public int persistentKeepalive; // In seconds, or 0 to disable
|
||||||
|
public byte[] endpoint; // Going to have to figure out how to parse this. IP + UDP Port
|
||||||
|
public int txBytes; // Unused, changed later
|
||||||
|
public int rxBytes; // Unused, changed later
|
||||||
|
public long lastHandshake; // Time of last handshake, in 100ns intervals since 1601-01-01 UTC. Unused, changed later
|
||||||
|
public int allowedIPsCount; // Number of allowed IP structures
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
struct WIREGUARD_ALLOWED_IP {
|
||||||
|
union
|
||||||
|
{
|
||||||
|
IN_ADDR V4;
|
||||||
|
IN6_ADDR V6;
|
||||||
|
} Address; < IP address
|
||||||
|
ADDRESS_FAMILY AddressFamily; < Address family, either AF_INET or AF_INET6
|
||||||
|
BYTE Cidr; < CIDR of allowed IPs
|
||||||
|
};
|
||||||
|
*/
|
||||||
|
public class AllowedIP {
|
||||||
|
public String address; // IP address; the V4 member is an IN_ADDR and the V6 member is an IN6_ADDR
|
||||||
|
public String addressFamily; // Address family, either AF_INET or AF_INET6
|
||||||
|
public byte cidr; // The CIDR of the address range
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,9 +1,14 @@
|
|||||||
package tech.nevets.tvpn.wg;
|
package tech.nevets.tvpn.wg;
|
||||||
|
|
||||||
|
import tech.nevets.tvpn.Logger;
|
||||||
|
|
||||||
public class WireGuardJNI {
|
public class WireGuardJNI {
|
||||||
|
private static final Logger LOGGER = new Logger(WireGuardJNI.class);
|
||||||
|
|
||||||
// Load the native library
|
// Load the native library
|
||||||
static {
|
static {
|
||||||
System.loadLibrary("libwireguard_wrapper"); // This will load wireguard_wrapper.dll (or .so on Linux)
|
System.loadLibrary("libwireguard_wrapper"); // This will load wireguard_wrapper.dll (or .so on Linux)
|
||||||
|
LOGGER.log("Loaded libwireguard_wrapper");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Native method declaration
|
// Native method declaration
|
||||||
@ -29,5 +34,8 @@ public class WireGuardJNI {
|
|||||||
public native int initializeWireGuard(String configFilePath);
|
public native int initializeWireGuard(String configFilePath);
|
||||||
public native void cleanup();
|
public native void cleanup();
|
||||||
|
|
||||||
|
public native String getWGVersion();
|
||||||
|
public native long parseConfig(WGConf conf);
|
||||||
|
|
||||||
// Other methods for WireGuard interaction can be added here if needed
|
// Other methods for WireGuard interaction can be added here if needed
|
||||||
}
|
}
|
||||||
|
11
src/main/kotlin/tech/nevets/tvpn/cli/Command.kt
Normal file
11
src/main/kotlin/tech/nevets/tvpn/cli/Command.kt
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
package tech.nevets.tvpn.cli
|
||||||
|
|
||||||
|
interface Command {
|
||||||
|
fun execute(args: Array<String>)
|
||||||
|
|
||||||
|
fun getName(): String
|
||||||
|
|
||||||
|
fun getUsage(): String
|
||||||
|
|
||||||
|
fun getDescription(): String
|
||||||
|
}
|
41
src/main/kotlin/tech/nevets/tvpn/cli/CommandBrigadier.kt
Normal file
41
src/main/kotlin/tech/nevets/tvpn/cli/CommandBrigadier.kt
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
package tech.nevets.tvpn.cli
|
||||||
|
|
||||||
|
import tech.nevets.tvpn.cli.commands.*
|
||||||
|
import tech.nevets.tvpn.Logger
|
||||||
|
|
||||||
|
class CommandBrigadier {
|
||||||
|
private val logger: Logger = Logger(CommandBrigadier::class.java)
|
||||||
|
private val registeredCmds: List<Command> = ArrayList()
|
||||||
|
private val helpCmd: HelpCmd = HelpCmd(this)
|
||||||
|
|
||||||
|
init {
|
||||||
|
registerCmd(helpCmd)
|
||||||
|
registerCmd(InstallTunnelServiceCmd())
|
||||||
|
registerCmd(UninstallTunnelServiceCmd())
|
||||||
|
registerCmd(VersionCmd())
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun registerCmd(cmd: Command) {
|
||||||
|
for (c in registeredCmds) {
|
||||||
|
if (c.getName() == cmd.getName()) {
|
||||||
|
logger.warn("Command with name " + cmd.getName() + " already registered, skipping.")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
registeredCmds.addLast(cmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun execute(args: Array<String>) {
|
||||||
|
for (c in registeredCmds) {
|
||||||
|
if (c.getName() == args[0]) {
|
||||||
|
c.execute(args)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
helpCmd.execute(arrayOf(""))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getCommands(): List<Command> {
|
||||||
|
return registeredCmds
|
||||||
|
}
|
||||||
|
}
|
45
src/main/kotlin/tech/nevets/tvpn/cli/commands/HelpCmd.kt
Normal file
45
src/main/kotlin/tech/nevets/tvpn/cli/commands/HelpCmd.kt
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
package tech.nevets.tvpn.cli.commands
|
||||||
|
|
||||||
|
import tech.nevets.tvpn.cli.Command
|
||||||
|
import tech.nevets.tvpn.cli.CommandBrigadier
|
||||||
|
import kotlin.system.exitProcess
|
||||||
|
|
||||||
|
class HelpCmd(private val cb: CommandBrigadier) : Command {
|
||||||
|
|
||||||
|
override fun execute(args: Array<String>) {
|
||||||
|
if (args.isNotEmpty()) {
|
||||||
|
for (c in cb.getCommands()) {
|
||||||
|
if (args.size != 1 && args[1] == c.getName()) {
|
||||||
|
println(("TVPN - Usage Menu [" + c.getName()) + "]")
|
||||||
|
println((c.getName() + " " + c.getUsage()) + ": " + c.getDescription())
|
||||||
|
exitProcess(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val sb = StringBuilder()
|
||||||
|
sb.append("TVPN - Help Menu\n")
|
||||||
|
for (c in cb.getCommands()) {
|
||||||
|
sb.append(" - ").append(c.getName())
|
||||||
|
.append(" ").append(c.getUsage())
|
||||||
|
.append(": ").append(c.getDescription())
|
||||||
|
.append("\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
println(sb)
|
||||||
|
exitProcess(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getName(): String {
|
||||||
|
return "help"
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getUsage(): String {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getDescription(): String {
|
||||||
|
return "Displays the help menu"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,65 @@
|
|||||||
|
package tech.nevets.tvpn.cli.commands
|
||||||
|
|
||||||
|
import tech.nevets.tvpn.Utils
|
||||||
|
import tech.nevets.tvpn.cli.Command
|
||||||
|
import tech.nevets.tvpn.wg.WireGuardJNI
|
||||||
|
import java.util.regex.Pattern
|
||||||
|
import kotlin.system.exitProcess
|
||||||
|
|
||||||
|
class InstallTunnelServiceCmd : Command {
|
||||||
|
override fun execute(args: Array<String>) {
|
||||||
|
println("Executing InstallTunnelServiceCmd")
|
||||||
|
val path = Utils.APP_DIR.toString() + "/configurations/" + args[1] + ".conf"
|
||||||
|
println(WireGuardJNI().installTunnel(args[1], path))
|
||||||
|
exitProcess(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getName(): String {
|
||||||
|
return "/installtunnelservice"
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getUsage(): String {
|
||||||
|
return "(/path/to/tunnel/config)"
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getDescription(): String {
|
||||||
|
return "Creates and starts a WireGuard Tunnel Service"
|
||||||
|
}
|
||||||
|
|
||||||
|
private var reservedNames: Array<String> = arrayOf(
|
||||||
|
"CON", "PRN", "AUX", "NUL",
|
||||||
|
"COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9",
|
||||||
|
"LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
private fun isReserved(name: String): Boolean {
|
||||||
|
if (name.isEmpty()) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for (s in reservedNames) {
|
||||||
|
if (name.contains(s)) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
private val specialChars = arrayOf("$", "\\", "/", ":", "*", "?", "\"", "'", "<", ">", "|", "\t", "\u0000")
|
||||||
|
private fun hasSpecialChars(name: String): Boolean {
|
||||||
|
for (s in specialChars) {
|
||||||
|
if (name.contains(s)) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
private val pattern: Pattern = Pattern.compile("^[a-zA-Z0-9_=+.-]{1,32}$")
|
||||||
|
private fun tunnelNameIsValid(name: String): Boolean {
|
||||||
|
if (isReserved(name) || hasSpecialChars(name)) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return pattern.matcher(name).hasMatch()
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
package tech.nevets.tvpn.cli.commands
|
||||||
|
|
||||||
|
import tech.nevets.tvpn.cli.Command
|
||||||
|
import tech.nevets.tvpn.wg.WireGuardJNI
|
||||||
|
import kotlin.system.exitProcess
|
||||||
|
|
||||||
|
class UninstallTunnelServiceCmd : Command {
|
||||||
|
override fun execute(args: Array<String>) {
|
||||||
|
println("Executing UnInstallTunnelServiceCmd")
|
||||||
|
println(WireGuardJNI().removeTunnel(args[1]))
|
||||||
|
exitProcess(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getName(): String {
|
||||||
|
return "/uninstalltunnelservice"
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getUsage(): String {
|
||||||
|
return "(tunnel name)"
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getDescription(): String {
|
||||||
|
return "Stops and removes WireGuard Tunnel Service"
|
||||||
|
}
|
||||||
|
}
|
26
src/main/kotlin/tech/nevets/tvpn/cli/commands/VersionCmd.kt
Normal file
26
src/main/kotlin/tech/nevets/tvpn/cli/commands/VersionCmd.kt
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
package tech.nevets.tvpn.cli.commands
|
||||||
|
|
||||||
|
import tech.nevets.tvpn.cli.Command
|
||||||
|
import tech.nevets.tvpn.wg.WireGuardJNI
|
||||||
|
import kotlin.system.exitProcess
|
||||||
|
|
||||||
|
class VersionCmd : Command {
|
||||||
|
override fun execute(args: Array<String>) {
|
||||||
|
println("Version: 0.3.1")
|
||||||
|
print("WireGuard Version: ")
|
||||||
|
WireGuardJNI().getWGVersion()
|
||||||
|
exitProcess(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getName(): String {
|
||||||
|
return "version"
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getUsage(): String {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getDescription(): String {
|
||||||
|
return "Shows the current running version."
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user