1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
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)
|