summaryrefslogtreecommitdiff
path: root/helper/bitmask_helper.nim
diff options
context:
space:
mode:
Diffstat (limited to 'helper/bitmask_helper.nim')
-rwxr-xr-xhelper/bitmask_helper.nim112
1 files changed, 112 insertions, 0 deletions
diff --git a/helper/bitmask_helper.nim b/helper/bitmask_helper.nim
new file mode 100755
index 0000000..64333ee
--- /dev/null
+++ b/helper/bitmask_helper.nim
@@ -0,0 +1,112 @@
+# Bitmask Helper
+# A privileged helper that should run as a service in windows.
+
+import asyncdispatch, asyncnet
+import strutils
+import protocol
+import osproc
+
+type
+ Client = ref object
+ socket: AsyncSocket
+ netAddr: string
+ id: int
+ connected: bool
+
+ Server = ref object
+ socket: AsyncSocket
+ clients: seq[Client]
+ openvpnProc: seq[Process]
+
+proc newServer(): Server = Server(socket: newAsyncSocket(), clients: @[])
+proc `$`(client: Client): string =
+ $client.id & "(" & client.netAddr & ")"
+
+#
+# OpenVPN commands
+#
+
+proc startOpenVPN(line: string, server: Server) =
+ let parsed = parseMessage(line)
+ echo(">>> start OpenVPN. \n args:", parsed.args)
+ if server.openvpnProc.len == 0:
+ server.openvpnProc = @[]
+ if server.openvpnProc.len > 0 and running(server.openvpnProc[0]):
+ echo(">>> need to stop process first (len: ", server.openvpnProc.len, ")")
+ return
+
+ try:
+ # TODO sanitize args
+ let p = startProcess("c:/Program Files/OpenVPN/bin/openvpn.exe", args=split(parsed.args))
+ echo "LEN: ", len(server.openvpnProc)
+ if server.openvpnProc.len == 0:
+ server.openvpnProc.add(p)
+ else:
+ server.openvpnProc[0] = p
+ except OsError:
+ echo("error while launching process!")
+
+
+proc stopOpenVPN(line: string, server: Server) =
+ echo(">>> stop OpenVPN, \n args:", parseMessage(line).args)
+ terminate(server.openvpnProc[0])
+
+
+proc doStatus(line: string, server: Server) =
+ if len(server.openvpnProc) == 1:
+ echo "running: ", running(server.openvpnProc[0])
+ else:
+ echo "no proc created"
+
+#
+# processing commands loop
+#
+
+proc processCommands(server: Server, client: Client) {.async.} =
+ while true:
+ let line = await client.socket.recvLine()
+ if line.len == 0:
+ echo(client, " disconnected!")
+ client.connected = false
+ client.socket.close()
+ return
+
+ echo("debug: ", client, " received: ", line)
+
+ try:
+ let parsed = parseMessage(line)
+ let cmd = parsed.cmd
+ case cmd
+ of "openvpn_start":
+ startOpenVPN(line, server)
+ of "openvpn_stop":
+ stopOpenVPN(line, server)
+ of "status":
+ doStatus(line, server)
+ of "ping":
+ ping(line, server)
+ else:
+ echo("Invalid command: ", cmd)
+
+ except MessageParsingError:
+ echo("Invalid message:", line)
+
+
+proc loop(server: Server, port = 7171) {.async.} =
+ server.socket.bindAddr(port.Port, address = "127.0.0.1")
+ server.socket.listen()
+
+ while true:
+ let (netAddr, clientSocket) = await server.socket.acceptAddr()
+ echo("Accepted connection from ", netAddr)
+ let client = Client(
+ socket: clientSocket,
+ netAddr: netAddr,
+ id: server.clients.len,
+ connected: true
+ )
+ server.clients.add(client)
+ asyncCheck processCommands(server, client)
+
+var server = newServer()
+waitFor loop(server)