Add TLS renegotiation time to GUI
[tomato.git] / release / src / router / rc / vpn.c
blobc394d21adc9da017e4e03f8235d9df3814015d0e
1 /*
3 Copyright (C) 2008-2009 Keith Moyer, tomatovpn@keithmoyer.com
5 No part of this file may be used without permission.
7 */
9 #include "rc.h"
10 #include <sys/types.h>
11 #include <dirent.h>
12 #include <string.h>
14 // Line number as text string
15 #define __LINE_T__ __LINE_T_(__LINE__)
16 #define __LINE_T_(x) __LINE_T(x)
17 #define __LINE_T(x) # x
19 #define VPN_LOG_ERROR -1
20 #define VPN_LOG_NOTE 0
21 #define VPN_LOG_INFO 1
22 #define VPN_LOG_EXTRA 2
23 #define vpnlog(level,x...) if(nvram_get_int("vpn_debug")>=level) syslog(LOG_INFO, #level ": " __LINE_T__ ": " x)
25 #define CLIENT_IF_START 10
26 #define SERVER_IF_START 20
28 #define BUF_SIZE 128
29 #define IF_SIZE 8
31 void start_vpnclient(int clientNum)
33 FILE *fp;
34 char iface[IF_SIZE];
35 char buffer[BUF_SIZE];
36 char *argv[5];
37 int argc = 0;
38 enum { TLS, SECRET, CUSTOM } cryptMode = CUSTOM;
39 enum { TAP, TUN } ifType = TUN;
40 enum { BRIDGE, NAT, NONE } routeMode = NONE;
41 int nvi, ip[4], nm[4];
42 long int nvl;
44 vpnlog(VPN_LOG_INFO,"VPN GUI client backend starting...");
46 sprintf(&buffer[0], "vpnclient%d", clientNum);
47 if ( pidof(&buffer[0]) >= 0 )
49 vpnlog(VPN_LOG_NOTE, "VPN Client %d already running...", clientNum);
50 vpnlog(VPN_LOG_INFO,"PID: %d", pidof(&buffer[0]));
51 return;
54 // Determine interface
55 sprintf(&buffer[0], "vpn_client%d_if", clientNum);
56 if ( nvram_contains_word(&buffer[0], "tap") )
57 ifType = TAP;
58 else if ( nvram_contains_word(&buffer[0], "tun") )
59 ifType = TUN;
60 else
62 vpnlog(VPN_LOG_ERROR, "Invalid interface type, %.3s", nvram_safe_get(&buffer[0]));
63 return;
66 // Build interface name
67 snprintf(&iface[0], IF_SIZE, "%s%d", nvram_safe_get(&buffer[0]), clientNum+CLIENT_IF_START);
69 // Determine encryption mode
70 sprintf(&buffer[0], "vpn_client%d_crypt", clientNum);
71 if ( nvram_contains_word(&buffer[0], "tls") )
72 cryptMode = TLS;
73 else if ( nvram_contains_word(&buffer[0], "secret") )
74 cryptMode = SECRET;
75 else if ( nvram_contains_word(&buffer[0], "custom") )
76 cryptMode = CUSTOM;
77 else
79 vpnlog(VPN_LOG_ERROR,"Invalid encryption mode, %.6s", nvram_safe_get(&buffer[0]));
80 return;
83 // Determine if we should bridge the tunnel
84 sprintf(&buffer[0], "vpn_client%d_bridge", clientNum);
85 if ( ifType == TAP && nvram_get_int(&buffer[0]) == 1 )
86 routeMode = BRIDGE;
88 // Determine if we should NAT the tunnel
89 sprintf(&buffer[0], "vpn_client%d_nat", clientNum);
90 if ( (ifType == TUN || routeMode != BRIDGE) && nvram_get_int(&buffer[0]) == 1 )
91 routeMode = NAT;
93 // Make sure openvpn directory exists
94 mkdir("/etc/openvpn", 0700);
95 sprintf(&buffer[0], "/etc/openvpn/client%d", clientNum);
96 mkdir(&buffer[0], 0700);
98 // Make sure symbolic link exists
99 sprintf(&buffer[0], "/etc/openvpn/vpnclient%d", clientNum);
100 unlink(&buffer[0]);
101 if ( symlink("/usr/sbin/openvpn", &buffer[0]) )
103 vpnlog(VPN_LOG_ERROR,"Creating symlink failed...");
104 stop_vpnclient(clientNum);
105 return;
108 // Make sure module is loaded
109 modprobe("tun");
111 // Create tap/tun interface
112 sprintf(&buffer[0], "openvpn --mktun --dev %s", &iface[0]);
113 for (argv[argc=0] = strtok(&buffer[0], " "); argv[argc] != NULL; argv[++argc] = strtok(NULL, " "));
114 if ( _eval(argv, NULL, 0, NULL) )
116 vpnlog(VPN_LOG_ERROR,"Creating tunnel interface failed...");
117 stop_vpnclient(clientNum);
118 return;
121 // Bring interface up (TAP only)
122 if( ifType == TAP )
124 if ( routeMode == BRIDGE )
126 snprintf(&buffer[0], BUF_SIZE, "brctl addif %s %s", nvram_safe_get("lan_ifname"), &iface[0]);
127 for (argv[argc=0] = strtok(&buffer[0], " "); argv[argc] != NULL; argv[++argc] = strtok(NULL, " "));
128 if ( _eval(argv, NULL, 0, NULL) )
130 vpnlog(VPN_LOG_ERROR,"Adding tunnel interface to bridge failed...");
131 stop_vpnclient(clientNum);
132 return;
136 snprintf(&buffer[0], BUF_SIZE, "ifconfig %s promisc up", nvram_safe_get("lan_ifname"));
137 for (argv[argc=0] = strtok(&buffer[0], " "); argv[argc] != NULL; argv[++argc] = strtok(NULL, " "));
138 if ( _eval(argv, NULL, 0, NULL) )
140 vpnlog(VPN_LOG_ERROR,"Bringing interface up failed...");
141 stop_vpnclient(clientNum);
142 return;
146 // Build and write config file
147 vpnlog(VPN_LOG_EXTRA,"Writing config file");
148 sprintf(&buffer[0], "/etc/openvpn/client%d/config.ovpn", clientNum);
149 fp = fopen(&buffer[0], "w");
150 chmod(&buffer[0], S_IRUSR|S_IWUSR);
151 fprintf(fp, "# Automatically generated configuration\n");
152 fprintf(fp, "daemon\n");
153 if ( cryptMode == TLS )
154 fprintf(fp, "client\n");
155 fprintf(fp, "dev %s\n", &iface[0]);
156 sprintf(&buffer[0], "vpn_client%d_proto", clientNum);
157 fprintf(fp, "proto %s\n", nvram_safe_get(&buffer[0]));
158 sprintf(&buffer[0], "vpn_client%d_addr", clientNum);
159 fprintf(fp, "remote %s ", nvram_safe_get(&buffer[0]));
160 sprintf(&buffer[0], "vpn_client%d_port", clientNum);
161 fprintf(fp, "%d\n", nvram_get_int(&buffer[0]));
162 if ( cryptMode == SECRET )
164 if ( ifType == TUN )
166 sprintf(&buffer[0], "vpn_client%d_local", clientNum);
167 fprintf(fp, "ifconfig %s ", nvram_safe_get(&buffer[0]));
168 sprintf(&buffer[0], "vpn_client%d_remote", clientNum);
169 fprintf(fp, "%s\n", nvram_safe_get(&buffer[0]));
171 else if ( ifType == TAP )
173 sprintf(&buffer[0], "vpn_client%d_local", clientNum);
174 fprintf(fp, "ifconfig %s ", nvram_safe_get(&buffer[0]));
175 sprintf(&buffer[0], "vpn_client%d_nm", clientNum);
176 fprintf(fp, "%s\n", nvram_safe_get(&buffer[0]));
179 sprintf(&buffer[0], "vpn_client%d_retry", clientNum);
180 if ( (nvi = nvram_get_int(&buffer[0])) >= 0 )
181 fprintf(fp, "resolv-retry %d\n", nvi);
182 else
183 fprintf(fp, "resolv-retry infinite\n");
184 sprintf(&buffer[0], "vpn_client%d_reneg", clientNum);
185 if ( (nvl = atol(nvram_safe_get(&buffer[0]))) >= 0 )
186 fprintf(fp, "reneg-sec %ld\n", nvl);
187 fprintf(fp, "nobind\n");
188 fprintf(fp, "persist-key\n");
189 fprintf(fp, "persist-tun\n");
190 sprintf(&buffer[0], "vpn_client%d_comp", clientNum);
191 fprintf(fp, "comp-lzo %s\n", nvram_safe_get(&buffer[0]));
192 sprintf(&buffer[0], "vpn_client%d_cipher", clientNum);
193 if ( !nvram_contains_word(&buffer[0], "default") )
194 fprintf(fp, "cipher %s\n", nvram_safe_get(&buffer[0]));
195 sprintf(&buffer[0], "vpn_client%d_rgw", clientNum);
196 if ( nvram_get_int(&buffer[0]) )
198 sprintf(&buffer[0], "vpn_client%d_gw", clientNum);
199 if ( ifType == TAP && nvram_safe_get(&buffer[0])[0] != '\0' )
200 fprintf(fp, "route-gateway %s\n", nvram_safe_get(&buffer[0]));
201 fprintf(fp, "redirect-gateway def1\n");
203 fprintf(fp, "verb 3\n");
204 if ( cryptMode == TLS )
206 sprintf(&buffer[0], "vpn_client%d_adns", clientNum);
207 if ( nvram_get_int(&buffer[0]) > 0 )
209 sprintf(&buffer[0], "/etc/openvpn/client%d/updown.sh", clientNum);
210 symlink("/rom/openvpn/updown.sh", &buffer[0]);
211 fprintf(fp, "script-security 2\n");
212 fprintf(fp, "up updown.sh\n");
213 fprintf(fp, "down updown.sh\n");
216 sprintf(&buffer[0], "vpn_client%d_hmac", clientNum);
217 nvi = nvram_get_int(&buffer[0]);
218 if ( nvi >= 0 )
220 fprintf(fp, "tls-auth static.key");
221 if ( nvi < 2 )
222 fprintf(fp, " %d", nvi);
223 fprintf(fp, "\n");
226 fprintf(fp, "ca ca.crt\n");
227 fprintf(fp, "cert client.crt\n");
228 fprintf(fp, "key client.key\n");
230 else if ( cryptMode == SECRET )
232 fprintf(fp, "secret static.key\n");
234 fprintf(fp, "status-version 2\n");
235 fprintf(fp, "status status\n");
236 fprintf(fp, "\n# Custom Configuration\n");
237 sprintf(&buffer[0], "vpn_client%d_custom", clientNum);
238 fprintf(fp, nvram_safe_get(&buffer[0]));
239 fclose(fp);
240 vpnlog(VPN_LOG_EXTRA,"Done writing config file");
242 // Write certification and key files
243 vpnlog(VPN_LOG_EXTRA,"Writing certs/keys");
244 if ( cryptMode == TLS )
246 sprintf(&buffer[0], "/etc/openvpn/client%d/ca.crt", clientNum);
247 fp = fopen(&buffer[0], "w");
248 chmod(&buffer[0], S_IRUSR|S_IWUSR);
249 sprintf(&buffer[0], "vpn_client%d_ca", clientNum);
250 fprintf(fp, nvram_safe_get(&buffer[0]));
251 fclose(fp);
253 sprintf(&buffer[0], "/etc/openvpn/client%d/client.key", clientNum);
254 fp = fopen(&buffer[0], "w");
255 chmod(&buffer[0], S_IRUSR|S_IWUSR);
256 sprintf(&buffer[0], "vpn_client%d_key", clientNum);
257 fprintf(fp, nvram_safe_get(&buffer[0]));
258 fclose(fp);
260 sprintf(&buffer[0], "/etc/openvpn/client%d/client.crt", clientNum);
261 fp = fopen(&buffer[0], "w");
262 chmod(&buffer[0], S_IRUSR|S_IWUSR);
263 sprintf(&buffer[0], "vpn_client%d_crt", clientNum);
264 fprintf(fp, nvram_safe_get(&buffer[0]));
265 fclose(fp);
267 sprintf(&buffer[0], "vpn_client%d_hmac", clientNum);
268 if ( cryptMode == SECRET || (cryptMode == TLS && nvram_get_int(&buffer[0]) >= 0) )
270 sprintf(&buffer[0], "/etc/openvpn/client%d/static.key", clientNum);
271 fp = fopen(&buffer[0], "w");
272 chmod(&buffer[0], S_IRUSR|S_IWUSR);
273 sprintf(&buffer[0], "vpn_client%d_static", clientNum);
274 fprintf(fp, nvram_safe_get(&buffer[0]));
275 fclose(fp);
277 vpnlog(VPN_LOG_EXTRA,"Done writing certs/keys");
279 // Start the VPN client
280 sprintf(&buffer[0], "/etc/openvpn/vpnclient%d --cd /etc/openvpn/client%d --config config.ovpn", clientNum, clientNum);
281 vpnlog(VPN_LOG_INFO,"Starting OpenVPN: %s",&buffer[0]);
282 for (argv[argc=0] = strtok(&buffer[0], " "); argv[argc] != NULL; argv[++argc] = strtok(NULL, " "));
283 if ( _eval(argv, NULL, 0, NULL) )
285 vpnlog(VPN_LOG_ERROR,"Starting OpenVPN failed...");
286 stop_vpnclient(clientNum);
287 return;
289 vpnlog(VPN_LOG_EXTRA,"Done starting openvpn");
291 // Handle firewall rules if appropriate
292 sprintf(&buffer[0], "vpn_client%d_firewall", clientNum);
293 if ( !nvram_contains_word(&buffer[0], "custom") )
295 // Create firewall rules
296 vpnlog(VPN_LOG_EXTRA,"Creating firewall rules");
297 mkdir("/etc/openvpn/fw", 0700);
298 sprintf(&buffer[0], "/etc/openvpn/fw/client%d-fw.sh", clientNum);
299 fp = fopen(&buffer[0], "w");
300 chmod(&buffer[0], S_IRUSR|S_IWUSR|S_IXUSR);
301 fprintf(fp, "#!/bin/sh\n");
302 fprintf(fp, "iptables -I INPUT -i %s -j ACCEPT\n", &iface[0]);
303 fprintf(fp, "iptables -I FORWARD -i %s -j ACCEPT\n", &iface[0]);
304 if ( routeMode == NAT )
306 sscanf(nvram_safe_get("lan_ipaddr"), "%d.%d.%d.%d", &ip[0], &ip[1], &ip[2], &ip[3]);
307 sscanf(nvram_safe_get("lan_netmask"), "%d.%d.%d.%d", &nm[0], &nm[1], &nm[2], &nm[3]);
308 fprintf(fp, "iptables -t nat -I POSTROUTING -s %d.%d.%d.%d/%s -o %s -j MASQUERADE\n",
309 ip[0]&nm[0], ip[1]&nm[1], ip[2]&nm[2], ip[3]&nm[3], nvram_safe_get("lan_netmask"), &iface[0]);
311 fclose(fp);
312 vpnlog(VPN_LOG_EXTRA,"Done creating firewall rules");
314 // Run the firewall rules
315 vpnlog(VPN_LOG_EXTRA,"Running firewall rules");
316 sprintf(&buffer[0], "/etc/openvpn/fw/client%d-fw.sh", clientNum);
317 argv[0] = &buffer[0];
318 argv[1] = NULL;
319 _eval(argv, NULL, 0, NULL);
320 vpnlog(VPN_LOG_EXTRA,"Done running firewall rules");
323 vpnlog(VPN_LOG_INFO,"VPN GUI server backend complete.");
326 void stop_vpnclient(int clientNum)
328 int argc;
329 char *argv[7];
330 char buffer[BUF_SIZE];
332 vpnlog(VPN_LOG_INFO,"Stopping VPN GUI client backend.");
334 // Remove firewall rules
335 vpnlog(VPN_LOG_EXTRA,"Removing firewall rules.");
336 sprintf(&buffer[0], "/etc/openvpn/fw/client%d-fw.sh", clientNum);
337 argv[0] = "sed";
338 argv[1] = "-i";
339 argv[2] = "s/-A/-D/g;s/-I/-D/g";
340 argv[3] = &buffer[0];
341 argv[4] = NULL;
342 if (!_eval(argv, NULL, 0, NULL))
344 argv[0] = &buffer[0];
345 argv[1] = NULL;
346 _eval(argv, NULL, 0, NULL);
348 vpnlog(VPN_LOG_EXTRA,"Done removing firewall rules.");
350 // Stop the VPN client
351 vpnlog(VPN_LOG_EXTRA,"Stopping OpenVPN client.");
352 sprintf(&buffer[0], "vpnclient%d", clientNum);
353 killall(&buffer[0], SIGTERM);
354 vpnlog(VPN_LOG_EXTRA,"OpenVPN client stopped.");
356 // NVRAM setting for device type could have changed, just try to remove both
357 vpnlog(VPN_LOG_EXTRA,"Removing VPN device.");
358 sprintf(&buffer[0], "openvpn --rmtun --dev tap%d", clientNum+CLIENT_IF_START);
359 for (argv[argc=0] = strtok(&buffer[0], " "); argv[argc] != NULL; argv[++argc] = strtok(NULL, " "));
360 _eval(argv, NULL, 0, NULL);
362 sprintf(&buffer[0], "openvpn --rmtun --dev tun%d", clientNum+CLIENT_IF_START);
363 for (argv[argc=0] = strtok(&buffer[0], " "); argv[argc] != NULL; argv[++argc] = strtok(NULL, " "));
364 _eval(argv, NULL, 0, NULL);
365 vpnlog(VPN_LOG_EXTRA,"VPN device removed.");
367 modprobe_r("tun");
369 if ( nvram_get_int("vpn_debug") <= VPN_LOG_EXTRA )
371 vpnlog(VPN_LOG_EXTRA,"Removing generated files.");
372 // Delete all files for this client
373 sprintf(&buffer[0], "rm -rf /etc/openvpn/client%d /etc/openvpn/fw/client%d-fw.sh /etc/openvpn/vpnclient%d",clientNum,clientNum,clientNum);
374 for (argv[argc=0] = strtok(&buffer[0], " "); argv[argc] != NULL; argv[++argc] = strtok(NULL, " "));
375 _eval(argv, NULL, 0, NULL);
377 // Attempt to remove directories. Will fail if not empty
378 rmdir("/etc/openvpn/fw");
379 rmdir("/etc/openvpn");
380 vpnlog(VPN_LOG_EXTRA,"Done removing generated files.");
383 vpnlog(VPN_LOG_INFO,"VPN GUI client backend stopped.");
386 void start_vpnserver(int serverNum)
388 FILE *fp, *ccd;
389 char iface[IF_SIZE];
390 char buffer[BUF_SIZE];
391 char *argv[6], *chp, *route;
392 int argc = 0;
393 int c2c = 0;
394 enum { TAP, TUN } ifType = TUN;
395 enum { TLS, SECRET, CUSTOM } cryptMode = CUSTOM;
396 int nvi, ip[4], nm[4];
397 long int nvl;
399 vpnlog(VPN_LOG_INFO,"VPN GUI server backend starting...");
401 sprintf(&buffer[0], "vpnserver%d", serverNum);
402 if ( pidof(&buffer[0]) >= 0 )
404 vpnlog(VPN_LOG_NOTE, "VPN Server %d already running...", serverNum);
405 vpnlog(VPN_LOG_INFO,"PID: %d", pidof(&buffer[0]));
406 return;
409 // Determine interface type
410 sprintf(&buffer[0], "vpn_server%d_if", serverNum);
411 if ( nvram_contains_word(&buffer[0], "tap") )
412 ifType = TAP;
413 else if ( nvram_contains_word(&buffer[0], "tun") )
414 ifType = TUN;
415 else
417 vpnlog(VPN_LOG_ERROR,"Invalid interface type, %.3s", nvram_safe_get(&buffer[0]));
418 return;
421 // Build interface name
422 snprintf(&iface[0], IF_SIZE, "%s%d", nvram_safe_get(&buffer[0]), serverNum+SERVER_IF_START);
424 // Determine encryption mode
425 sprintf(&buffer[0], "vpn_server%d_crypt", serverNum);
426 if ( nvram_contains_word(&buffer[0], "tls") )
427 cryptMode = TLS;
428 else if ( nvram_contains_word(&buffer[0], "secret") )
429 cryptMode = SECRET;
430 else if ( nvram_contains_word(&buffer[0], "custom") )
431 cryptMode = CUSTOM;
432 else
434 vpnlog(VPN_LOG_ERROR,"Invalid encryption mode, %.6s", nvram_safe_get(&buffer[0]));
435 return;
438 // Make sure openvpn directory exists
439 mkdir("/etc/openvpn", 0700);
440 sprintf(&buffer[0], "/etc/openvpn/server%d", serverNum);
441 mkdir(&buffer[0], 0700);
443 // Make sure symbolic link exists
444 sprintf(&buffer[0], "/etc/openvpn/vpnserver%d", serverNum);
445 unlink(&buffer[0]);
446 if ( symlink("/usr/sbin/openvpn", &buffer[0]) )
448 vpnlog(VPN_LOG_ERROR,"Creating symlink failed...");
449 stop_vpnserver(serverNum);
450 return;
453 // Make sure module is loaded
454 modprobe("tun");
456 // Create tap/tun interface
457 sprintf(&buffer[0], "openvpn --mktun --dev %s", &iface[0]);
458 for (argv[argc=0] = strtok(&buffer[0], " "); argv[argc] != NULL; argv[++argc] = strtok(NULL, " "));
459 if ( _eval(argv, NULL, 0, NULL) )
461 vpnlog(VPN_LOG_ERROR,"Creating tunnel interface failed...");
462 stop_vpnserver(serverNum);
463 return;
466 // Add interface to LAN bridge (TAP only)
467 if( ifType == TAP )
469 snprintf(&buffer[0], BUF_SIZE, "brctl addif %s %s", nvram_safe_get("lan_ifname"), &iface[0]);
470 for (argv[argc=0] = strtok(&buffer[0], " "); argv[argc] != NULL; argv[++argc] = strtok(NULL, " "));
471 if ( _eval(argv, NULL, 0, NULL) )
473 vpnlog(VPN_LOG_ERROR,"Adding tunnel interface to bridge failed...");
474 stop_vpnserver(serverNum);
475 return;
479 // Bring interface up
480 sprintf(&buffer[0], "ifconfig %s 0.0.0.0 promisc up", &iface[0]);
481 for (argv[argc=0] = strtok(&buffer[0], " "); argv[argc] != NULL; argv[++argc] = strtok(NULL, " "));
482 if ( _eval(argv, NULL, 0, NULL) )
484 vpnlog(VPN_LOG_ERROR,"Bringing up tunnel interface failed...");
485 stop_vpnserver(serverNum);
486 return;
489 // Build and write config files
490 vpnlog(VPN_LOG_EXTRA,"Writing config file");
491 sprintf(&buffer[0], "/etc/openvpn/server%d/config.ovpn", serverNum);
492 fp = fopen(&buffer[0], "w");
493 chmod(&buffer[0], S_IRUSR|S_IWUSR);
494 fprintf(fp, "# Automatically generated configuration\n");
495 fprintf(fp, "daemon\n");
496 if ( cryptMode == TLS )
498 if ( ifType == TUN )
500 sprintf(&buffer[0], "vpn_server%d_sn", serverNum);
501 fprintf(fp, "server %s ", nvram_safe_get(&buffer[0]));
502 sprintf(&buffer[0], "vpn_server%d_nm", serverNum);
503 fprintf(fp, "%s\n", nvram_safe_get(&buffer[0]));
505 else if ( ifType == TAP )
507 fprintf(fp, "server-bridge");
508 sprintf(&buffer[0], "vpn_server%d_dhcp", serverNum);
509 if ( nvram_get_int(&buffer[0]) == 0 )
511 fprintf(fp, " %s ", nvram_safe_get("lan_ipaddr"));
512 fprintf(fp, "%s ", nvram_safe_get("lan_netmask"));
513 sprintf(&buffer[0], "vpn_server%d_r1", serverNum);
514 fprintf(fp, "%s ", nvram_safe_get(&buffer[0]));
515 sprintf(&buffer[0], "vpn_server%d_r2", serverNum);
516 fprintf(fp, "%s", nvram_safe_get(&buffer[0]));
518 fprintf(fp, "\n");
521 else if ( cryptMode == SECRET )
523 if ( ifType == TUN )
525 sprintf(&buffer[0], "vpn_server%d_local", serverNum);
526 fprintf(fp, "ifconfig %s ", nvram_safe_get(&buffer[0]));
527 sprintf(&buffer[0], "vpn_server%d_remote", serverNum);
528 fprintf(fp, "%s\n", nvram_safe_get(&buffer[0]));
531 sprintf(&buffer[0], "vpn_server%d_proto", serverNum);
532 fprintf(fp, "proto %s\n", nvram_safe_get(&buffer[0]));
533 sprintf(&buffer[0], "vpn_server%d_port", serverNum);
534 fprintf(fp, "port %d\n", nvram_get_int(&buffer[0]));
535 fprintf(fp, "dev %s\n", &iface[0]);
536 sprintf(&buffer[0], "vpn_server%d_cipher", serverNum);
537 if ( !nvram_contains_word(&buffer[0], "default") )
538 fprintf(fp, "cipher %s\n", nvram_safe_get(&buffer[0]));
539 sprintf(&buffer[0], "vpn_server%d_comp", serverNum);
540 fprintf(fp, "comp-lzo %s\n", nvram_safe_get(&buffer[0]));
541 sprintf(&buffer[0], "vpn_server%d_reneg", serverNum);
542 if ( (nvl = atol(nvram_safe_get(&buffer[0]))) >= 0 )
543 fprintf(fp, "reneg-sec %ld\n", nvl);
544 fprintf(fp, "keepalive 15 60\n");
545 fprintf(fp, "verb 3\n");
546 if ( cryptMode == TLS )
548 if ( ifType == TUN )
550 sscanf(nvram_safe_get("lan_ipaddr"), "%d.%d.%d.%d", &ip[0], &ip[1], &ip[2], &ip[3]);
551 sscanf(nvram_safe_get("lan_netmask"), "%d.%d.%d.%d", &nm[0], &nm[1], &nm[2], &nm[3]);
552 fprintf(fp, "push \"route %d.%d.%d.%d %s\"\n", ip[0]&nm[0], ip[1]&nm[1], ip[2]&nm[2], ip[3]&nm[3],
553 nvram_safe_get("lan_netmask"));
556 sprintf(&buffer[0], "vpn_server%d_ccd", serverNum);
557 if ( nvram_get_int(&buffer[0]) )
559 fprintf(fp, "client-config-dir ccd\n");
561 sprintf(&buffer[0], "vpn_server%d_c2c", serverNum);
562 if ( (c2c = nvram_get_int(&buffer[0])) )
563 fprintf(fp, "client-to-client\n");
565 sprintf(&buffer[0], "vpn_server%d_ccd_excl", serverNum);
566 if ( nvram_get_int(&buffer[0]) )
567 fprintf(fp, "ccd-exclusive\n");
569 sprintf(&buffer[0], "/etc/openvpn/server%d/ccd", serverNum);
570 mkdir(&buffer[0], 0700);
571 chdir(&buffer[0]);
573 sprintf(&buffer[0], "vpn_server%d_ccd_val", serverNum);
574 strcpy(&buffer[0], nvram_safe_get(&buffer[0]));
575 chp = strtok(&buffer[0],">");
576 while ( chp != NULL )
578 nvi = strlen(chp);
580 chp[strcspn(chp,"<")] = '\0';
581 vpnlog(VPN_LOG_EXTRA,"CCD: enabled: %d", atoi(chp));
582 if ( atoi(chp) == 1 )
584 nvi -= strlen(chp)+1;
585 chp += strlen(chp)+1;
587 ccd = NULL;
588 route = NULL;
589 if ( nvi > 0 )
591 chp[strcspn(chp,"<")] = '\0';
592 vpnlog(VPN_LOG_EXTRA,"CCD: Common name: %s", chp);
593 ccd = fopen(chp, "w");
594 chmod(chp, S_IRUSR|S_IWUSR);
596 nvi -= strlen(chp)+1;
597 chp += strlen(chp)+1;
599 if ( nvi > 0 && ccd != NULL && strcspn(chp,"<") != strlen(chp) )
601 chp[strcspn(chp,"<")] = ' ';
602 chp[strcspn(chp,"<")] = '\0';
603 route = chp;
604 vpnlog(VPN_LOG_EXTRA,"CCD: Route: %s", chp);
605 if ( strlen(route) > 1 )
607 fprintf(ccd, "iroute %s\n", route);
608 fprintf(fp, "route %s\n", route);
611 nvi -= strlen(chp)+1;
612 chp += strlen(chp)+1;
614 if ( ccd != NULL )
615 fclose(ccd);
616 if ( nvi > 0 && route != NULL )
618 chp[strcspn(chp,"<")] = '\0';
619 vpnlog(VPN_LOG_EXTRA,"CCD: Push: %d", atoi(chp));
620 if ( c2c && atoi(chp) == 1 && strlen(route) > 1 )
621 fprintf(fp, "push \"route %s\"\n", route);
623 nvi -= strlen(chp)+1;
624 chp += strlen(chp)+1;
627 vpnlog(VPN_LOG_EXTRA,"CCD leftover: %d", nvi+1);
629 // Advance to next entry
630 chp = strtok(NULL, ">");
632 vpnlog(VPN_LOG_EXTRA,"CCD processing complete");
635 sprintf(&buffer[0], "vpn_server%d_pdns", serverNum);
636 if ( nvram_get_int(&buffer[0]) )
638 if ( nvram_safe_get("wan_domain")[0] != '\0' )
639 fprintf(fp, "push \"dhcp-option DOMAIN %s\"\n", nvram_safe_get("wan_domain"));
640 fprintf(fp, "push \"dhcp-option DNS %s\"\n", nvram_safe_get("lan_ipaddr"));
643 sprintf(&buffer[0], "vpn_server%d_rgw", serverNum);
644 if ( nvram_get_int(&buffer[0]) )
646 if ( ifType == TAP )
647 fprintf(fp, "push \"route-gateway %s\"\n", nvram_safe_get("lan_ipaddr"));
648 fprintf(fp, "push \"redirect-gateway def1\"\n");
651 sprintf(&buffer[0], "vpn_server%d_hmac", serverNum);
652 nvi = nvram_get_int(&buffer[0]);
653 if ( nvi >= 0 )
655 fprintf(fp, "tls-auth static.key");
656 if ( nvi < 2 )
657 fprintf(fp, " %d", nvi);
658 fprintf(fp, "\n");
661 fprintf(fp, "ca ca.crt\n");
662 fprintf(fp, "dh dh.pem\n");
663 fprintf(fp, "cert server.crt\n");
664 fprintf(fp, "key server.key\n");
666 else if ( cryptMode == SECRET )
668 fprintf(fp, "secret static.key\n");
670 fprintf(fp, "status-version 2\n");
671 fprintf(fp, "status status\n");
672 fprintf(fp, "\n# Custom Configuration\n");
673 sprintf(&buffer[0], "vpn_server%d_custom", serverNum);
674 fprintf(fp, nvram_safe_get(&buffer[0]));
675 fclose(fp);
676 vpnlog(VPN_LOG_EXTRA,"Done writing config file");
678 // Write certification and key files
679 vpnlog(VPN_LOG_EXTRA,"Writing certs/keys");
680 if ( cryptMode == TLS )
682 sprintf(&buffer[0], "/etc/openvpn/server%d/ca.crt", serverNum);
683 fp = fopen(&buffer[0], "w");
684 chmod(&buffer[0], S_IRUSR|S_IWUSR);
685 sprintf(&buffer[0], "vpn_server%d_ca", serverNum);
686 fprintf(fp, nvram_safe_get(&buffer[0]));
687 fclose(fp);
689 sprintf(&buffer[0], "/etc/openvpn/server%d/server.key", serverNum);
690 fp = fopen(&buffer[0], "w");
691 chmod(&buffer[0], S_IRUSR|S_IWUSR);
692 sprintf(&buffer[0], "vpn_server%d_key", serverNum);
693 fprintf(fp, nvram_safe_get(&buffer[0]));
694 fclose(fp);
696 sprintf(&buffer[0], "/etc/openvpn/server%d/server.crt", serverNum);
697 fp = fopen(&buffer[0], "w");
698 chmod(&buffer[0], S_IRUSR|S_IWUSR);
699 sprintf(&buffer[0], "vpn_server%d_crt", serverNum);
700 fprintf(fp, nvram_safe_get(&buffer[0]));
701 fclose(fp);
703 sprintf(&buffer[0], "/etc/openvpn/server%d/dh.pem", serverNum);
704 fp = fopen(&buffer[0], "w");
705 chmod(&buffer[0], S_IRUSR|S_IWUSR);
706 sprintf(&buffer[0], "vpn_server%d_dh", serverNum);
707 fprintf(fp, nvram_safe_get(&buffer[0]));
708 fclose(fp);
710 sprintf(&buffer[0], "vpn_server%d_hmac", serverNum);
711 if ( cryptMode == SECRET || (cryptMode == TLS && nvram_get_int(&buffer[0]) >= 0) )
713 sprintf(&buffer[0], "/etc/openvpn/server%d/static.key", serverNum);
714 fp = fopen(&buffer[0], "w");
715 chmod(&buffer[0], S_IRUSR|S_IWUSR);
716 sprintf(&buffer[0], "vpn_server%d_static", serverNum);
717 fprintf(fp, nvram_safe_get(&buffer[0]));
718 fclose(fp);
720 vpnlog(VPN_LOG_EXTRA,"Done writing certs/keys");
722 sprintf(&buffer[0], "/etc/openvpn/vpnserver%d --cd /etc/openvpn/server%d --config config.ovpn", serverNum, serverNum);
723 vpnlog(VPN_LOG_INFO,"Starting OpenVPN: %s",&buffer[0]);
724 for (argv[argc=0] = strtok(&buffer[0], " "); argv[argc] != NULL; argv[++argc] = strtok(NULL, " "));
725 if ( _eval(argv, NULL, 0, NULL) )
727 vpnlog(VPN_LOG_ERROR,"Starting VPN instance failed...");
728 stop_vpnserver(serverNum);
729 return;
731 vpnlog(VPN_LOG_EXTRA,"Done starting openvpn");
733 // Handle firewall rules if appropriate
734 sprintf(&buffer[0], "vpn_server%d_firewall", serverNum);
735 if ( !nvram_contains_word(&buffer[0], "custom") )
737 // Create firewall rules
738 vpnlog(VPN_LOG_EXTRA,"Creating firewall rules");
739 mkdir("/etc/openvpn/fw", 0700);
740 sprintf(&buffer[0], "/etc/openvpn/fw/server%d-fw.sh", serverNum);
741 fp = fopen(&buffer[0], "w");
742 chmod(&buffer[0], S_IRUSR|S_IWUSR|S_IXUSR);
743 fprintf(fp, "#!/bin/sh\n");
744 sprintf(&buffer[0], "vpn_server%d_proto", serverNum);
745 strncpy(&buffer[0], nvram_safe_get(&buffer[0]), BUF_SIZE);
746 fprintf(fp, "iptables -t nat -I PREROUTING -p %s ", strtok(&buffer[0], "-"));
747 sprintf(&buffer[0], "vpn_server%d_port", serverNum);
748 fprintf(fp, "--dport %d -j ACCEPT\n", nvram_get_int(&buffer[0]));
749 sprintf(&buffer[0], "vpn_server%d_proto", serverNum);
750 strncpy(&buffer[0], nvram_safe_get(&buffer[0]), BUF_SIZE);
751 fprintf(fp, "iptables -I INPUT -p %s ", strtok(&buffer[0], "-"));
752 sprintf(&buffer[0], "vpn_server%d_port", serverNum);
753 fprintf(fp, "--dport %d -j ACCEPT\n", nvram_get_int(&buffer[0]));
754 sprintf(&buffer[0], "vpn_server%d_firewall", serverNum);
755 if ( !nvram_contains_word(&buffer[0], "external") )
757 fprintf(fp, "iptables -I INPUT -i %s -j ACCEPT\n", &iface[0]);
758 fprintf(fp, "iptables -I FORWARD -i %s -j ACCEPT\n", &iface[0]);
760 fclose(fp);
761 vpnlog(VPN_LOG_EXTRA,"Done creating firewall rules");
763 // Run the firewall rules
764 vpnlog(VPN_LOG_EXTRA,"Running firewall rules");
765 sprintf(&buffer[0], "/etc/openvpn/fw/server%d-fw.sh", serverNum);
766 argv[0] = &buffer[0];
767 argv[1] = NULL;
768 _eval(argv, NULL, 0, NULL);
769 vpnlog(VPN_LOG_EXTRA,"Done running firewall rules");
772 vpnlog(VPN_LOG_INFO,"VPN GUI server backend complete.");
775 void stop_vpnserver(int serverNum)
777 int argc;
778 char *argv[9];
779 char buffer[BUF_SIZE];
781 vpnlog(VPN_LOG_INFO,"Stopping VPN GUI server backend.");
783 // Remove firewall rules
784 vpnlog(VPN_LOG_EXTRA,"Removing firewall rules.");
785 sprintf(&buffer[0], "/etc/openvpn/fw/server%d-fw.sh", serverNum);
786 argv[0] = "sed";
787 argv[1] = "-i";
788 argv[2] = "s/-A/-D/g;s/-I/-D/g";
789 argv[3] = &buffer[0];
790 argv[4] = NULL;
791 if (!_eval(argv, NULL, 0, NULL))
793 argv[0] = &buffer[0];
794 argv[1] = NULL;
795 _eval(argv, NULL, 0, NULL);
797 vpnlog(VPN_LOG_EXTRA,"Done removing firewall rules.");
799 // Stop the VPN server
800 vpnlog(VPN_LOG_EXTRA,"Stopping OpenVPN server.");
801 sprintf(&buffer[0], "vpnserver%d", serverNum);
802 killall(&buffer[0], SIGTERM);
803 vpnlog(VPN_LOG_EXTRA,"OpenVPN server stopped.");
805 // NVRAM setting for device type could have changed, just try to remove both
806 vpnlog(VPN_LOG_EXTRA,"Removing VPN device.");
807 sprintf(&buffer[0], "openvpn --rmtun --dev tap%d", serverNum+SERVER_IF_START);
808 for (argv[argc=0] = strtok(&buffer[0], " "); argv[argc] != NULL; argv[++argc] = strtok(NULL, " "));
809 _eval(argv, NULL, 0, NULL);
811 sprintf(&buffer[0], "openvpn --rmtun --dev tun%d", serverNum+SERVER_IF_START);
812 for (argv[argc=0] = strtok(&buffer[0], " "); argv[argc] != NULL; argv[++argc] = strtok(NULL, " "));
813 _eval(argv, NULL, 0, NULL);
814 vpnlog(VPN_LOG_EXTRA,"VPN device removed.");
816 modprobe_r("tun");
818 if ( nvram_get_int("vpn_debug") <= VPN_LOG_EXTRA )
820 vpnlog(VPN_LOG_EXTRA,"Removing generated files.");
821 // Delete all files for this server
822 sprintf(&buffer[0], "rm -rf /etc/openvpn/server%d /etc/openvpn/fw/server%d-fw.sh /etc/openvpn/vpnserver%d",serverNum,serverNum,serverNum);
823 for (argv[argc=0] = strtok(&buffer[0], " "); argv[argc] != NULL; argv[++argc] = strtok(NULL, " "));
824 _eval(argv, NULL, 0, NULL);
826 // Attempt to remove directories. Will fail if not empty
827 rmdir("/etc/openvpn/fw");
828 rmdir("/etc/openvpn");
829 vpnlog(VPN_LOG_EXTRA,"Done removing generated files.");
832 vpnlog(VPN_LOG_INFO,"VPN GUI server backend stopped.");
835 void start_vpn_eas()
837 char buffer[16], *cur;
838 int nums[4], i;
840 // Parse and start servers
841 strlcpy(&buffer[0], nvram_safe_get("vpn_server_eas"), sizeof(buffer));
842 if ( strlen(&buffer[0]) != 0 ) vpnlog(VPN_LOG_INFO, "Starting servers (eas): %s", &buffer[0]);
843 i = 0;
844 for( cur = strtok(&buffer[0],","); cur != NULL && i < 4; cur = strtok(NULL, ",")) { nums[i++] = atoi(cur); }
845 nums[i] = 0;
846 for( i = 0; nums[i] > 0; i++ ) { vpnlog(VPN_LOG_INFO, "Starting server %d (eas)", nums[i]); start_vpnserver(nums[i]); }
848 // Parse and start clients
849 strlcpy(&buffer[0], nvram_safe_get("vpn_client_eas"), sizeof(buffer));
850 if ( strlen(&buffer[0]) != 0 ) vpnlog(VPN_LOG_INFO, "Starting clients (eas): %s", &buffer[0]);
851 i = 0;
852 for( cur = strtok(&buffer[0],","); cur != NULL && i < 4; cur = strtok(NULL, ",")) { nums[i++] = atoi(cur); }
853 nums[i] = 0;
854 for( i = 0; nums[i] > 0; i++ ) { vpnlog(VPN_LOG_INFO, "Starting client %d (eas)", nums[i]); start_vpnclient(nums[i]); }
857 void run_vpn_firewall_scripts()
859 DIR *dir;
860 struct dirent *file;
861 char *fn;
862 char *argv[3];
864 if ( chdir("/etc/openvpn/fw") )
865 return;
867 dir = opendir("/etc/openvpn/fw");
869 vpnlog(VPN_LOG_EXTRA,"Beginning all firewall scripts...");
870 while ( (file = readdir(dir)) != NULL )
872 fn = file->d_name;
873 if ( fn[0] == '.' )
874 continue;
875 vpnlog(VPN_LOG_INFO,"Running firewall script: %s", fn);
876 argv[0] = "/bin/sh";
877 argv[1] = fn;
878 argv[2] = NULL;
879 _eval(argv, NULL, 0, NULL);
881 vpnlog(VPN_LOG_EXTRA,"Done with all firewall scripts...");
883 closedir(dir);
886 void write_vpn_dnsmasq_config(FILE* f)
888 char nv[16];
889 char buf[24];
890 char *pos;
891 int cur;
892 DIR *dir;
893 struct dirent *file;
895 strlcpy(&buf[0], nvram_safe_get("vpn_server_dns"), sizeof(buf));
896 for ( pos = strtok(&buf[0],","); pos != NULL; pos=strtok(NULL, ",") )
898 cur = atoi(pos);
899 if ( cur )
901 vpnlog(VPN_LOG_EXTRA, "Adding server %d interface to dns config", cur);
902 snprintf(&nv[0], sizeof(nv), "vpn_server%d_if", cur);
903 fprintf(f, "interface=%s%d\n", nvram_safe_get(&nv[0]), SERVER_IF_START+cur);
907 if ( (dir = opendir("/etc/openvpn/dns")) != NULL )
909 while ( (file = readdir(dir)) != NULL )
911 if ( file->d_name[0] == '.' )
912 continue;
914 if ( sscanf(file->d_name, "client%d.resolv", &cur) == 1 )
916 vpnlog(VPN_LOG_EXTRA, "Checking ADNS settings for client %d", cur);
917 snprintf(&buf[0], sizeof(buf), "vpn_client%d_adns", cur);
918 if ( nvram_get_int(&buf[0]) == 2 )
920 vpnlog(VPN_LOG_INFO, "Adding strict-order to dnsmasq config for client %d", cur);
921 fprintf(f, "strict-order\n");
922 break;
929 int write_vpn_resolv(FILE* f)
931 DIR *dir;
932 struct dirent *file;
933 char *fn, ch, buf[24];
934 FILE *dnsf;
935 int exclusive = 0;
937 if ( chdir("/etc/openvpn/dns") )
938 return 0;
940 dir = opendir("/etc/openvpn/dns");
942 vpnlog(VPN_LOG_EXTRA, "Adding DNS entries...");
943 while ( (file = readdir(dir)) != NULL )
945 fn = file->d_name;
947 if ( fn[0] == '.' )
948 continue;
950 if ( (dnsf = fopen(fn, "r")) == NULL )
951 continue;
953 vpnlog(VPN_LOG_INFO,"Adding DNS entries from %s", fn);
955 while( !feof(dnsf) )
957 ch = fgetc(dnsf);
958 fputc(ch==EOF?'\n':ch, f);
961 fclose(dnsf);
963 if ( sscanf(fn, "client%c.resolv", &ch) == 1 )
965 snprintf(&buf[0], sizeof(buf), "vpn_client%c_adns", ch);
966 if ( nvram_get_int(&buf[0]) == 3 )
967 exclusive = 1;
971 vpnlog(VPN_LOG_EXTRA, "Done with DNS entries...");
973 closedir(dir);
975 return exclusive;