Added configurable path to extra configuration file.
[openvpnui.git] / src / vpncontrol.cpp
1 #include "vpncontrol.h"
2 #include "stdio.h"
3 #include <QSettings>
4
5
6 VPNControl::VPNControl(QObject *parent) :
7 QObject(parent),
8 vpnProcess(NULL),
9 vpnStatus(VPNSTATUS_INVALID),
10 server(""),
11 port(1194),
12 compressed(true),
13 useTLS(true),
14 tlsDirection(1)
15 {
16 // Read in the settings
17 QSettings settings;
18 settings.setValue("showAll", false);
19
20 // Read configuration settings
21 server = settings.value("server", "127.0.0.1").toString();
22 port = settings.value("port", 1194).toInt();
23 compressed = settings.value("compressed", true).toBool();
24 useTLS = settings.value("useTLS", true).toBool();
25 tlsDirection = settings.value("tlsDirection", 1).toInt();
26 caCertFile = settings.value("caCertFile", "").toString();
27 clientCertFile = settings.value("clientCertFile", "").toString();
28 clientKeyFile = settings.value("clientKeyFile", "").toString();
29 tlsKeyFile = settings.value("tlsKeyFile", "").toString();
30 configFile = settings.value("configFile", "").toString();
31 }
32
33 void VPNControl::initialise()
34 {
35 setStatus(VPNSTATUS_UNINITIALISED);
36 }
37
38 void VPNControl::setStatus(VPNSTATUS newStatus)
39 {
40 if (vpnStatus != newStatus) {
41 vpnStatus = newStatus;
42 emit statusChanged(newStatus);
43 }
44 }
45 int VPNControl::getTlsDirection() const
46 {
47 return tlsDirection;
48 }
49
50 void VPNControl::setTlsDirection(int value)
51 {
52 if (value != tlsDirection) {
53 tlsDirection = value;
54 settingsSetValue("tlsDirection", value);
55 emit tlsDirectionChanged (value);
56 }
57 }
58
59 bool VPNControl::getUseTLS() const
60 {
61 return useTLS;
62 }
63
64 void VPNControl::setUseTLS(bool value)
65 {
66 if (value != useTLS) {
67 useTLS = value;
68 settingsSetValue("useTLS", value);
69 emit useTLSChanged(useTLS);
70 }
71 }
72
73 bool VPNControl::getCompressed() const
74 {
75 return compressed;
76 }
77
78 void VPNControl::setCompressed(bool value)
79 {
80 if (value != compressed) {
81 compressed = value;
82 settingsSetValue("compressed", value);
83 emit compressedChanged(compressed);
84 }
85 }
86
87 unsigned int VPNControl::getPort() const
88 {
89 return port;
90 }
91
92 void VPNControl::setPort(unsigned int value)
93 {
94 if (value != port) {
95 port = value;
96 settingsSetValue("port", value);
97 emit portChanged(port);
98 }
99 }
100
101 QString VPNControl::getServer() const
102 {
103 return server;
104 }
105
106 void VPNControl::setServer(const QString &value)
107 {
108 if (value != server) {
109 server = value;
110 settingsSetValue("server", value);
111 emit serverChanged(server);
112 }
113 }
114
115 QString VPNControl::getCaCertFile () const
116 {
117 return caCertFile;
118 }
119
120 void VPNControl::setCaCertFile(const QString &value)
121 {
122 if (value != caCertFile) {
123 caCertFile = value;
124 settingsSetValue("caCertFile", value);
125 emit caCertFileChanged(caCertFile);
126 }
127 }
128
129 void VPNControl::setClientCertFile(const QString &value)
130 {
131 if (value != clientCertFile) {
132 clientCertFile = value;
133 settingsSetValue("clientCertFile", value);
134 emit clientCertFileChanged(clientCertFile);
135 }
136 }
137
138 void VPNControl::setClientKeyFile(const QString &value)
139 {
140 if (value != clientKeyFile) {
141 clientKeyFile = value;
142 settingsSetValue("clientKeyFile", value);
143 emit clientKeyFileChanged(clientKeyFile);
144 }
145 }
146
147 void VPNControl::setTlsKeyFile(const QString &value)
148 {
149 if (value != tlsKeyFile) {
150 tlsKeyFile = value;
151 settingsSetValue("tlsKeyFile", value);
152 emit tlsKeyFileChanged(tlsKeyFile);
153 }
154 }
155
156 void VPNControl::setConfigFile(const QString &value)
157 {
158 if (value != configFile) {
159 configFile = value;
160 settingsSetValue("configFile", value);
161 emit tlsKeyFileChanged(configFile);
162 }
163 }
164
165 QString VPNControl::getClientCertFile () const
166 {
167 return clientCertFile;
168 }
169
170 QString VPNControl::getClientKeyFile () const
171 {
172 return clientKeyFile;
173 }
174
175 QString VPNControl::getTlsKeyFile () const
176 {
177 return tlsKeyFile;
178 }
179
180 QString VPNControl::getConfigFile () const
181 {
182 return configFile;
183 }
184
185 QString VPNControl::getLogText() const
186 {
187 return logText;
188 }
189
190 void VPNControl::setLogText(const QString &value)
191 {
192 logText = value;
193 emit logTextChanged(logText);
194 }
195
196 void VPNControl::settingsSetValue (QString key, QString value) {
197 QSettings settings;
198
199 settings.setValue(key, value);
200 }
201
202 void VPNControl::settingsSetValue (QString key, int value) {
203 QSettings settings;
204
205 settings.setValue(key, value);
206 }
207
208 void VPNControl::vpnConnect() {
209 if (vpnProcess != NULL) {
210 printf ("Process already running.\n");
211 }
212 else {
213 vpnProcess = new QProcess();
214 QString program = "openvpn";
215 collectArguments ();
216 vpnProcess->setReadChannel(QProcess::StandardOutput);
217 connect(vpnProcess, SIGNAL(error(QProcess::ProcessError)), this, SLOT(readError(QProcess::ProcessError)));
218 connect(vpnProcess, SIGNAL(readyRead()), this, SLOT(readData()));
219 connect(vpnProcess, SIGNAL(started()), this, SLOT(started()));
220 connect(vpnProcess, SIGNAL(finished(int)), this, SLOT(finished(int)));
221
222 vpnProcess->start(program, arguments);
223 vpnProcess->closeWriteChannel();
224 setStatus(VPNSTATUS_INITIALISING);
225 arguments.clear();
226 }
227 }
228
229 void VPNControl::collectArguments () {
230 arguments.clear();
231
232 addArgumentNonempty("config", configFile);
233 addArgumentNonempty("remote", server);
234 addArgumentNonempty("port", QString::number(port));
235 addOption("comp-lzo", compressed);
236 if ((useTLS) && (!tlsKeyFile.isEmpty())) {
237 addArgument("tls-auth", tlsKeyFile);
238 addValue(QString::number(tlsDirection));
239 }
240 addArgumentNonempty("ca", caCertFile);
241 addArgumentNonempty("cert", clientCertFile);
242 addArgumentNonempty("key", clientKeyFile);
243 }
244
245 void VPNControl::addArgument (QString key, QString value) {
246 QString argument;
247
248 argument = "--" + key;
249 arguments.append(argument);
250 if (!value.isEmpty()) {
251 arguments.append(value);
252 }
253 }
254
255 void VPNControl::addArgumentNonempty (QString key, QString value) {
256 QString argument;
257
258 if (!value.isEmpty()) {
259 argument = "--" + key;
260 arguments.append(argument);
261 arguments.append(value);
262 }
263 }
264
265 void VPNControl::addArgument (QString key) {
266 QString argument;
267
268 argument = "--" + key;
269 arguments.append(argument);
270 }
271
272 void VPNControl::addOption (QString key, bool add) {
273 if (add) {
274 addArgument (key);
275 }
276 }
277
278 void VPNControl::addValue (QString key) {
279 arguments.append(key);
280 }
281
282 void VPNControl::vpnDisconnect() {
283 if (vpnProcess != NULL) {
284
285 vpnProcess->terminate();
286 setStatus(VPNSTATUS_DISCONNECTING);
287 }
288 }
289
290 void VPNControl::readData() {
291 while (vpnProcess->canReadLine()) {
292 QByteArray read = vpnProcess->readLine();
293 //printf ("Output: %s", read.data());
294
295 logAppend(read);
296
297 if (read.endsWith("Initialization Sequence Completed\n")) {
298 setStatus(VPNSTATUS_CONNECTED);
299 }
300 }
301 }
302
303 void VPNControl::started() {
304 setStatus(VPNSTATUS_CONNECTING);
305 }
306
307 void VPNControl::finished(int code) {
308 if (vpnProcess != NULL) {
309 //delete vpnProcess;
310 vpnProcess = NULL;
311 }
312 setStatus(VPNSTATUS_UNINITIALISED);
313 }
314
315 void VPNControl::readError(QProcess::ProcessError error)
316 {
317 printf ("Error: %d\n", error);
318 if (vpnProcess != NULL) {
319 QByteArray dataOut = vpnProcess->readAllStandardOutput();
320 QByteArray errorOut = vpnProcess->readAllStandardError();
321
322 printf ("Output text: %s\n", dataOut.data());
323 printf ("Error text: %s\n", errorOut.data());
324 }
325
326 // Disconnect
327 vpnDisconnect();
328 }
329
330 void VPNControl::updateConfiguration()
331 {
332 printf ("Update configuration\n");
333 }
334
335 void VPNControl::logAppend(const QString &text)
336 {
337 if (!text.isEmpty()) {
338 // How many lines to add
339 int newLines = text.count('\n');
340 int currentLines = logText.count('\n');
341 int removeLines = currentLines + newLines - 18;
342
343 // Remove excess lines
344 // while (removeLines > 0) {
345 // int nextLine = logText.indexOf('\n');
346 // if (nextLine > 0) {
347 // logText = logText.right(nextLine);
348 // }
349 // removeLines--;
350 // }
351
352 // Add new lines
353 logText.append(text);
354 emit logTextChanged(logText);
355 }
356 }
357