Client-specific server configuration
[tomato.git] / release / src / router / rc / vpn.c
blob99459dcf81f8f16ed080af385e61d180c733d79c
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 #ifdef _dprintf
20 #undef _dprintf
21 #endif
22 #define _dprintf(x...) if(nvram_get_int("vpn_debug")!=0) syslog(LOG_INFO, "VPN DEBUG: " __LINE_T__ ": " x)
24 #define CLIENT_IF_START 10
25 #define SERVER_IF_START 20
27 #define BUF_SIZE 96
28 #define IF_SIZE 8
30 void start_vpnclient(int clientNum)
32 FILE *fp;
33 char buffer[BUF_SIZE];
34 char iface[IF_SIZE];
35 char *argv[5];
36 int argc = 0;
37 enum { TLS, SECRET, CUSTOM } cryptMode = CUSTOM;
38 enum { TAP, TUN } ifType = TUN;
39 enum { BRIDGE, NAT, NONE } routeMode = NONE;
40 int nvi, ip[4], nm[4];
42 sprintf(&buffer[0], "vpnclient%d", clientNum);
43 if ( pidof(&buffer[0]) >= 0 )
45 syslog(LOG_INFO, "VPN Client %d already running...", clientNum);
46 return;
49 // Determine interface
50 sprintf(&buffer[0], "vpn_client%d_if", clientNum);
51 if ( nvram_contains_word(&buffer[0], "tap") )
52 ifType = TAP;
53 else if ( nvram_contains_word(&buffer[0], "tun") )
54 ifType = TUN;
55 else
57 _dprintf("Invalid interface type, %.3s", nvram_safe_get(&buffer[0]));
58 return;
61 // Build interface name
62 snprintf(&iface[0], IF_SIZE, "%s%d", nvram_safe_get(&buffer[0]), clientNum+CLIENT_IF_START);
64 // Determine encryption mode
65 sprintf(&buffer[0], "vpn_client%d_crypt", clientNum);
66 if ( nvram_contains_word(&buffer[0], "tls") )
67 cryptMode = TLS;
68 else if ( nvram_contains_word(&buffer[0], "secret") )
69 cryptMode = SECRET;
70 else if ( nvram_contains_word(&buffer[0], "custom") )
71 cryptMode = CUSTOM;
72 else
74 _dprintf("Invalid encryption mode, %.6s", nvram_safe_get(&buffer[0]));
75 return;
78 // Determine if we should bridge the tunnel
79 sprintf(&buffer[0], "vpn_client%d_bridge", clientNum);
80 if ( ifType == TAP && nvram_get_int(&buffer[0]) == 1 )
81 routeMode = BRIDGE;
83 // Determine if we should NAT the tunnel
84 sprintf(&buffer[0], "vpn_client%d_nat", clientNum);
85 if ( (ifType == TUN || routeMode != BRIDGE) && nvram_get_int(&buffer[0]) == 1 )
86 routeMode = NAT;
88 // Make sure openvpn directory exists
89 mkdir("/etc/openvpn", 0700);
91 // Make sure symbolic link exists
92 sprintf(&buffer[0], "/etc/openvpn/vpnclient%d", clientNum);
93 unlink(&buffer[0]);
94 if ( symlink("/usr/sbin/openvpn", &buffer[0]) )
96 _dprintf("Creating symlink failed...");
97 stop_vpnclient(clientNum);
98 return;
101 // Make sure module is loaded
102 modprobe("tun");
104 // Create tap/tun interface
105 sprintf(&buffer[0], "openvpn --mktun --dev %s", &iface[0]);
106 for (argv[argc=0] = strtok(&buffer[0], " "); argv[argc] != NULL; argv[++argc] = strtok(NULL, " "));
107 if ( _eval(argv, NULL, 0, NULL) )
109 _dprintf("Creating tunnel interface failed...");
110 stop_vpnclient(clientNum);
111 return;
114 // Bring interface up (TAP only)
115 if( ifType == TAP )
117 if ( routeMode == BRIDGE )
119 snprintf(&buffer[0], BUF_SIZE, "brctl addif %s %s", nvram_safe_get("lan_ifname"), &iface[0]);
120 for (argv[argc=0] = strtok(&buffer[0], " "); argv[argc] != NULL; argv[++argc] = strtok(NULL, " "));
121 if ( _eval(argv, NULL, 0, NULL) )
123 _dprintf("Adding tunnel interface to bridge failed...");
124 stop_vpnclient(clientNum);
125 return;
129 snprintf(&buffer[0], BUF_SIZE, "ifconfig %s promisc up", nvram_safe_get("lan_ifname"));
130 for (argv[argc=0] = strtok(&buffer[0], " "); argv[argc] != NULL; argv[++argc] = strtok(NULL, " "));
131 if ( _eval(argv, NULL, 0, NULL) )
133 _dprintf("Bringing interface up failed...");
134 stop_vpnclient(clientNum);
135 return;
139 // Build and write config file
140 sprintf(&buffer[0], "/etc/openvpn/client%d.ovpn", clientNum);
141 fp = fopen(&buffer[0], "w");
142 chmod(&buffer[0], S_IRUSR|S_IWUSR);
143 fprintf(fp, "# Automatically generated configuration\n");
144 fprintf(fp, "daemon\n");
145 if ( cryptMode == TLS )
146 fprintf(fp, "client\n");
147 fprintf(fp, "dev %s\n", &iface[0]);
148 sprintf(&buffer[0], "vpn_client%d_proto", clientNum);
149 fprintf(fp, "proto %s\n", nvram_safe_get(&buffer[0]));
150 sprintf(&buffer[0], "vpn_client%d_addr", clientNum);
151 fprintf(fp, "remote %s ", nvram_safe_get(&buffer[0]));
152 sprintf(&buffer[0], "vpn_client%d_port", clientNum);
153 fprintf(fp, "%d\n", nvram_get_int(&buffer[0]));
154 if ( cryptMode == SECRET )
156 if ( ifType == TUN )
158 sprintf(&buffer[0], "vpn_client%d_local", clientNum);
159 fprintf(fp, "ifconfig %s ", nvram_safe_get(&buffer[0]));
160 sprintf(&buffer[0], "vpn_client%d_remote", clientNum);
161 fprintf(fp, "%s\n", nvram_safe_get(&buffer[0]));
163 else if ( ifType == TAP )
165 sprintf(&buffer[0], "vpn_client%d_local", clientNum);
166 fprintf(fp, "ifconfig %s ", nvram_safe_get(&buffer[0]));
167 sprintf(&buffer[0], "vpn_client%d_nm", clientNum);
168 fprintf(fp, "%s\n", nvram_safe_get(&buffer[0]));
171 sprintf(&buffer[0], "vpn_client%d_retry", clientNum);
172 if ( (nvi = nvram_get_int(&buffer[0])) >= 0 )
173 fprintf(fp, "resolv-retry %d\n", nvi);
174 else
175 fprintf(fp, "resolv-retry infinite\n");
176 fprintf(fp, "nobind\n");
177 fprintf(fp, "persist-key\n");
178 fprintf(fp, "persist-tun\n");
179 sprintf(&buffer[0], "vpn_client%d_comp", clientNum);
180 fprintf(fp, "comp-lzo %s\n", nvram_safe_get(&buffer[0]));
181 sprintf(&buffer[0], "vpn_client%d_cipher", clientNum);
182 if ( !nvram_contains_word(&buffer[0], "default") )
183 fprintf(fp, "cipher %s\n", nvram_safe_get(&buffer[0]));
184 fprintf(fp, "verb 3\n");
185 if ( cryptMode == TLS )
187 sprintf(&buffer[0], "vpn_client%d_hmac", clientNum);
188 nvi = nvram_get_int(&buffer[0]);
189 if ( nvi >= 0 )
191 fprintf(fp, "tls-auth client%d-static.key", clientNum);
192 if ( nvi < 2 )
193 fprintf(fp, " %d", nvi);
194 fprintf(fp, "\n");
197 fprintf(fp, "ca client%d-ca.crt\n", clientNum);
198 fprintf(fp, "cert client%d.crt\n", clientNum);
199 fprintf(fp, "key client%d.key\n", clientNum);
201 else if ( cryptMode == SECRET )
203 fprintf(fp, "secret client%d-static.key\n", clientNum);
205 fprintf(fp, "\n# Custom Configuration\n");
206 sprintf(&buffer[0], "vpn_client%d_custom", clientNum);
207 fprintf(fp, nvram_safe_get(&buffer[0]));
208 fclose(fp);
210 // Write certification and key files
211 if ( cryptMode == TLS )
213 sprintf(&buffer[0], "/etc/openvpn/client%d-ca.crt", clientNum);
214 fp = fopen(&buffer[0], "w");
215 chmod(&buffer[0], S_IRUSR|S_IWUSR);
216 sprintf(&buffer[0], "vpn_client%d_ca", clientNum);
217 fprintf(fp, nvram_safe_get(&buffer[0]));
218 fclose(fp);
220 sprintf(&buffer[0], "/etc/openvpn/client%d.key", clientNum);
221 fp = fopen(&buffer[0], "w");
222 chmod(&buffer[0], S_IRUSR|S_IWUSR);
223 sprintf(&buffer[0], "vpn_client%d_key", clientNum);
224 fprintf(fp, nvram_safe_get(&buffer[0]));
225 fclose(fp);
227 sprintf(&buffer[0], "/etc/openvpn/client%d.crt", clientNum);
228 fp = fopen(&buffer[0], "w");
229 chmod(&buffer[0], S_IRUSR|S_IWUSR);
230 sprintf(&buffer[0], "vpn_client%d_crt", clientNum);
231 fprintf(fp, nvram_safe_get(&buffer[0]));
232 fclose(fp);
234 sprintf(&buffer[0], "vpn_client%d_hmac", clientNum);
235 if ( cryptMode == SECRET || (cryptMode == TLS && nvram_get_int(&buffer[0]) >= 0) )
237 sprintf(&buffer[0], "/etc/openvpn/client%d-static.key", clientNum);
238 fp = fopen(&buffer[0], "w");
239 chmod(&buffer[0], S_IRUSR|S_IWUSR);
240 sprintf(&buffer[0], "vpn_client%d_static", clientNum);
241 fprintf(fp, nvram_safe_get(&buffer[0]));
242 fclose(fp);
245 // Start the VPN client
246 sprintf(&buffer[0], "/etc/openvpn/vpnclient%d --cd /etc/openvpn --config client%d.ovpn", clientNum, clientNum);
247 for (argv[argc=0] = strtok(&buffer[0], " "); argv[argc] != NULL; argv[++argc] = strtok(NULL, " "));
248 if ( _eval(argv, NULL, 0, NULL) )
250 _dprintf("Starting OpenVPN failed...");
251 stop_vpnclient(clientNum);
252 return;
255 // Handle firewall rules if appropriate
256 sprintf(&buffer[0], "vpn_client%d_firewall", clientNum);
257 if ( !nvram_contains_word(&buffer[0], "custom") )
259 // Create firewall rules
260 sprintf(&buffer[0], "/etc/openvpn/client%d-fw.sh", clientNum);
261 fp = fopen(&buffer[0], "w");
262 chmod(&buffer[0], S_IRUSR|S_IWUSR|S_IXUSR);
263 fprintf(fp, "#!/bin/sh\n");
264 fprintf(fp, "iptables -A INPUT -i %s -j ACCEPT\n", &iface[0]);
265 fprintf(fp, "iptables -A FORWARD -i %s -j ACCEPT\n", &iface[0]);
266 if ( routeMode == NAT )
268 sscanf(nvram_safe_get("lan_ipaddr"), "%d.%d.%d.%d", &ip[0], &ip[1], &ip[2], &ip[3]);
269 sscanf(nvram_safe_get("lan_netmask"), "%d.%d.%d.%d", &nm[0], &nm[1], &nm[2], &nm[3]);
270 fprintf(fp, "iptables -t nat -A POSTROUTING -s %d.%d.%d.%d/%s -o %s -j MASQUERADE\n",
271 ip[0]&nm[0], ip[1]&nm[1], ip[2]&nm[2], ip[3]&nm[3], nvram_safe_get("lan_netmask"), &iface[0]);
273 fclose(fp);
275 // Run the firewall rules
276 sprintf(&buffer[0], "/etc/openvpn/client%d-fw.sh", clientNum);
277 argv[0] = &buffer[0];
278 argv[1] = NULL;
279 if ( _eval(argv, NULL, 0, NULL) )
281 _dprintf("Adding firewall rules failed...");
282 stop_vpnclient(clientNum);
283 return;
288 void stop_vpnclient(int clientNum)
290 DIR *dir;
291 struct dirent *file;
292 char *fn;
293 int argc;
294 char *argv[7];
295 char buffer[32];
297 // Remove firewall rules
298 sprintf(&buffer[0], "/etc/openvpn/client%d-fw.sh", clientNum);
299 argv[0] = "sed";
300 argv[1] = "-i";
301 argv[2] = "s/-A/-D/g;s/-I/-D/g";
302 argv[3] = &buffer[0];
303 argv[4] = NULL;
304 if (!_eval(argv, NULL, 0, NULL))
306 argv[0] = &buffer[0];
307 argv[1] = NULL;
308 _eval(argv, NULL, 0, NULL);
311 // Stop the VPN client
312 sprintf(&buffer[0], "vpnclient%d", clientNum);
313 killall(&buffer[0], SIGTERM);
315 // NVRAM setting for device type could have changed, just try to remove both
316 sprintf(&buffer[0], "openvpn --rmtun --dev tap%d", clientNum+CLIENT_IF_START);
317 for (argv[argc=0] = strtok(&buffer[0], " "); argv[argc] != NULL; argv[++argc] = strtok(NULL, " "));
318 _eval(argv, NULL, 0, NULL);
320 sprintf(&buffer[0], "openvpn --rmtun --dev tun%d", clientNum+CLIENT_IF_START);
321 for (argv[argc=0] = strtok(&buffer[0], " "); argv[argc] != NULL; argv[++argc] = strtok(NULL, " "));
322 _eval(argv, NULL, 0, NULL);
324 modprobe_r("tun");
326 if ( nvram_get_int("vpn_debug") != 1 )
328 // Delete all files in /etc/openvpn that match client#
329 sprintf(&buffer[0], "client%d", clientNum);
330 dir = opendir("/etc/openvpn");
331 chdir("/etc/openvpn");
332 while ( (file = readdir(dir)) != NULL )
334 fn = file->d_name;
335 if ( strstr(fn, &buffer[0]) )
336 unlink(fn);
341 void start_vpnserver(int serverNum)
343 FILE *fp, *ccd;
344 char buffer[BUF_SIZE];
345 char iface[IF_SIZE];
346 char *argv[6], *chp, *route;
347 int argc = 0;
348 int c2c = 0;
349 enum { TAP, TUN } ifType = TUN;
350 enum { TLS, SECRET, CUSTOM } cryptMode = CUSTOM;
351 int nvi, ip[4], nm[4];
353 sprintf(&buffer[0], "vpnserver%d", serverNum);
354 if ( pidof(&buffer[0]) >= 0 )
356 syslog(LOG_INFO, "VPN Server %d already running...", serverNum);
357 return;
360 // Determine interface type
361 sprintf(&buffer[0], "vpn_server%d_if", serverNum);
362 if ( nvram_contains_word(&buffer[0], "tap") )
363 ifType = TAP;
364 else if ( nvram_contains_word(&buffer[0], "tun") )
365 ifType = TUN;
366 else
368 _dprintf("Invalid interface type, %.3s", nvram_safe_get(&buffer[0]));
369 return;
372 // Build interface name
373 snprintf(&iface[0], IF_SIZE, "%s%d", nvram_safe_get(&buffer[0]), serverNum+SERVER_IF_START);
375 // Determine encryption mode
376 sprintf(&buffer[0], "vpn_server%d_crypt", serverNum);
377 if ( nvram_contains_word(&buffer[0], "tls") )
378 cryptMode = TLS;
379 else if ( nvram_contains_word(&buffer[0], "secret") )
380 cryptMode = SECRET;
381 else if ( nvram_contains_word(&buffer[0], "custom") )
382 cryptMode = CUSTOM;
383 else
385 _dprintf("Invalid encryption mode, %.6s", nvram_safe_get(&buffer[0]));
386 return;
389 // Make sure openvpn directory exists
390 mkdir("/etc/openvpn", 0700);
392 // Make sure symbolic link exists
393 sprintf(&buffer[0], "/etc/openvpn/vpnserver%d", serverNum);
394 unlink(&buffer[0]);
395 if ( symlink("/usr/sbin/openvpn", &buffer[0]) )
397 _dprintf("Creating symlink failed...");
398 stop_vpnserver(serverNum);
399 return;
402 // Make sure module is loaded
403 modprobe("tun");
405 // Create tap/tun interface
406 sprintf(&buffer[0], "openvpn --mktun --dev %s", &iface[0]);
407 for (argv[argc=0] = strtok(&buffer[0], " "); argv[argc] != NULL; argv[++argc] = strtok(NULL, " "));
408 if ( _eval(argv, NULL, 0, NULL) )
410 _dprintf("Creating tunnel interface failed...");
411 stop_vpnserver(serverNum);
412 return;
415 // Add interface to LAN bridge (TAP only)
416 if( ifType == TAP )
418 snprintf(&buffer[0], BUF_SIZE, "brctl addif %s %s", nvram_safe_get("lan_ifname"), &iface[0]);
419 for (argv[argc=0] = strtok(&buffer[0], " "); argv[argc] != NULL; argv[++argc] = strtok(NULL, " "));
420 if ( _eval(argv, NULL, 0, NULL) )
422 _dprintf("Adding tunnel interface to bridge failed...");
423 stop_vpnserver(serverNum);
424 return;
428 // Bring interface up
429 sprintf(&buffer[0], "ifconfig %s 0.0.0.0 promisc up", &iface[0]);
430 for (argv[argc=0] = strtok(&buffer[0], " "); argv[argc] != NULL; argv[++argc] = strtok(NULL, " "));
431 if ( _eval(argv, NULL, 0, NULL) )
433 _dprintf("Bringing up tunnel interface failed...");
434 stop_vpnserver(serverNum);
435 return;
438 // Build and write config files
439 sprintf(&buffer[0], "/etc/openvpn/server%d.ovpn", serverNum);
440 fp = fopen(&buffer[0], "w");
441 chmod(&buffer[0], S_IRUSR|S_IWUSR);
442 fprintf(fp, "# Automatically generated configuration\n");
443 fprintf(fp, "daemon\n");
444 if ( cryptMode == TLS )
446 if ( ifType == TUN )
448 sprintf(&buffer[0], "vpn_server%d_sn", serverNum);
449 fprintf(fp, "server %s ", nvram_safe_get(&buffer[0]));
450 sprintf(&buffer[0], "vpn_server%d_nm", serverNum);
451 fprintf(fp, "%s\n", nvram_safe_get(&buffer[0]));
453 else if ( ifType == TAP )
455 fprintf(fp, "server-bridge");
456 sprintf(&buffer[0], "vpn_server%d_dhcp", serverNum);
457 if ( nvram_get_int(&buffer[0]) == 0 )
459 fprintf(fp, " %s ", nvram_safe_get("lan_ipaddr"));
460 fprintf(fp, "%s ", nvram_safe_get("lan_netmask"));
461 sprintf(&buffer[0], "vpn_server%d_r1", serverNum);
462 fprintf(fp, "%s ", nvram_safe_get(&buffer[0]));
463 sprintf(&buffer[0], "vpn_server%d_r2", serverNum);
464 fprintf(fp, "%s", nvram_safe_get(&buffer[0]));
466 fprintf(fp, "\n");
469 else if ( cryptMode == SECRET )
471 if ( ifType == TUN )
473 sprintf(&buffer[0], "vpn_server%d_local", serverNum);
474 fprintf(fp, "ifconfig %s ", nvram_safe_get(&buffer[0]));
475 sprintf(&buffer[0], "vpn_server%d_remote", serverNum);
476 fprintf(fp, "%s\n", nvram_safe_get(&buffer[0]));
479 sprintf(&buffer[0], "vpn_server%d_proto", serverNum);
480 fprintf(fp, "proto %s\n", nvram_safe_get(&buffer[0]));
481 sprintf(&buffer[0], "vpn_server%d_port", serverNum);
482 fprintf(fp, "port %d\n", nvram_get_int(&buffer[0]));
483 fprintf(fp, "dev %s\n", &iface[0]);
484 sprintf(&buffer[0], "vpn_server%d_cipher", serverNum);
485 if ( !nvram_contains_word(&buffer[0], "default") )
486 fprintf(fp, "cipher %s\n", nvram_safe_get(&buffer[0]));
487 sprintf(&buffer[0], "vpn_server%d_comp", serverNum);
488 fprintf(fp, "comp-lzo %s\n", nvram_safe_get(&buffer[0]));
489 fprintf(fp, "keepalive 15 60\n");
490 fprintf(fp, "verb 3\n");
491 if ( cryptMode == TLS )
493 if ( ifType == TUN )
495 sscanf(nvram_safe_get("lan_ipaddr"), "%d.%d.%d.%d", &ip[0], &ip[1], &ip[2], &ip[3]);
496 sscanf(nvram_safe_get("lan_netmask"), "%d.%d.%d.%d", &nm[0], &nm[1], &nm[2], &nm[3]);
497 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],
498 nvram_safe_get("lan_netmask"));
501 sprintf(&buffer[0], "vpn_server%d_ccd", serverNum);
502 if ( nvram_get_int(&buffer[0]) )
504 fprintf(fp, "client-config-dir server%d-ccd\n", serverNum);
506 sprintf(&buffer[0], "vpn_server%d_c2c", serverNum);
507 if ( (c2c = nvram_get_int(&buffer[0])) )
508 fprintf(fp, "client-to-client\n");
510 sprintf(&buffer[0], "vpn_server%d_ccd_excl", serverNum);
511 if ( nvram_get_int(&buffer[0]) )
512 fprintf(fp, "ccd-exclusive\n");
514 sprintf(&buffer[0], "/etc/openvpn/server%d-ccd", serverNum);
515 mkdir(&buffer[0], 0700);
516 chdir(&buffer[0]);
518 sprintf(&buffer[0], "vpn_server%d_ccd_val", serverNum);
519 strcpy(&buffer[0], nvram_safe_get(&buffer[0]));
520 chp = strtok(&buffer[0],">");
521 while ( chp != NULL )
523 nvi = strlen(chp);
525 chp[strcspn(chp,"<")] = '\0';
526 _dprintf("CCD: enabled: %d", atoi(chp));
527 if ( atoi(chp) == 1 )
529 nvi -= strlen(chp)+1;
530 chp += strlen(chp)+1;
532 ccd = NULL;
533 route = NULL;
534 if ( nvi > 0 )
536 chp[strcspn(chp,"<")] = '\0';
537 _dprintf("CCD: Common name: %s", chp);
538 ccd = fopen(chp, "w");
539 chmod(chp, S_IRUSR|S_IWUSR);
541 nvi -= strlen(chp)+1;
542 chp += strlen(chp)+1;
544 if ( nvi > 0 && ccd != NULL && strcspn(chp,"<") != strlen(chp) )
546 chp[strcspn(chp,"<")] = ' ';
547 chp[strcspn(chp,"<")] = '\0';
548 route = chp;
549 _dprintf("CCD: Route: %s", chp);
550 if ( strlen(route) > 1 )
552 fprintf(ccd, "iroute %s\n", route);
553 fprintf(fp, "route %s\n", route);
556 nvi -= strlen(chp)+1;
557 chp += strlen(chp)+1;
559 if ( ccd != NULL )
560 fclose(ccd);
561 if ( nvi > 0 && route != NULL )
563 chp[strcspn(chp,"<")] = '\0';
564 _dprintf("CCD: Push: %d", atoi(chp));
565 if ( c2c && atoi(chp) == 1 && strlen(route) > 1 )
566 fprintf(fp, "push \"route %s\"\n", route);
568 nvi -= strlen(chp)+1;
569 chp += strlen(chp)+1;
572 _dprintf("CCD processing: %d", nvi);
574 // Advance to next entry
575 chp = strtok(NULL, ">");
579 sprintf(&buffer[0], "vpn_server%d_hmac", serverNum);
580 nvi = nvram_get_int(&buffer[0]);
581 if ( nvi >= 0 )
583 fprintf(fp, "tls-auth server%d-static.key", serverNum);
584 if ( nvi < 2 )
585 fprintf(fp, " %d", nvi);
586 fprintf(fp, "\n");
589 fprintf(fp, "ca server%d-ca.crt\n", serverNum);
590 fprintf(fp, "dh server%d-dh.pem\n", serverNum);
591 fprintf(fp, "cert server%d.crt\n", serverNum);
592 fprintf(fp, "key server%d.key\n", serverNum);
594 else if ( cryptMode == SECRET )
596 fprintf(fp, "secret server%d-static.key\n", serverNum);
598 fprintf(fp, "status-version 2\n");
599 fprintf(fp, "status server%d.status\n", serverNum);
600 fprintf(fp, "\n# Custom Configuration\n");
601 sprintf(&buffer[0], "vpn_server%d_custom", serverNum);
602 fprintf(fp, nvram_safe_get(&buffer[0]));
603 fclose(fp);
605 // Write certification and key files
606 if ( cryptMode == TLS )
608 sprintf(&buffer[0], "/etc/openvpn/server%d-ca.crt", serverNum);
609 fp = fopen(&buffer[0], "w");
610 chmod(&buffer[0], S_IRUSR|S_IWUSR);
611 sprintf(&buffer[0], "vpn_server%d_ca", serverNum);
612 fprintf(fp, nvram_safe_get(&buffer[0]));
613 fclose(fp);
615 sprintf(&buffer[0], "/etc/openvpn/server%d.key", serverNum);
616 fp = fopen(&buffer[0], "w");
617 chmod(&buffer[0], S_IRUSR|S_IWUSR);
618 sprintf(&buffer[0], "vpn_server%d_key", serverNum);
619 fprintf(fp, nvram_safe_get(&buffer[0]));
620 fclose(fp);
622 sprintf(&buffer[0], "/etc/openvpn/server%d.crt", serverNum);
623 fp = fopen(&buffer[0], "w");
624 chmod(&buffer[0], S_IRUSR|S_IWUSR);
625 sprintf(&buffer[0], "vpn_server%d_crt", serverNum);
626 fprintf(fp, nvram_safe_get(&buffer[0]));
627 fclose(fp);
629 sprintf(&buffer[0], "/etc/openvpn/server%d-dh.pem", serverNum);
630 fp = fopen(&buffer[0], "w");
631 chmod(&buffer[0], S_IRUSR|S_IWUSR);
632 sprintf(&buffer[0], "vpn_server%d_dh", serverNum);
633 fprintf(fp, nvram_safe_get(&buffer[0]));
634 fclose(fp);
636 sprintf(&buffer[0], "vpn_server%d_hmac", serverNum);
637 if ( cryptMode == SECRET || (cryptMode == TLS && nvram_get_int(&buffer[0]) >= 0) )
639 sprintf(&buffer[0], "/etc/openvpn/server%d-static.key", serverNum);
640 fp = fopen(&buffer[0], "w");
641 chmod(&buffer[0], S_IRUSR|S_IWUSR);
642 sprintf(&buffer[0], "vpn_server%d_static", serverNum);
643 fprintf(fp, nvram_safe_get(&buffer[0]));
644 fclose(fp);
647 sprintf(&buffer[0], "/etc/openvpn/vpnserver%d --cd /etc/openvpn --config server%d.ovpn", serverNum, serverNum);
648 for (argv[argc=0] = strtok(&buffer[0], " "); argv[argc] != NULL; argv[++argc] = strtok(NULL, " "));
649 if ( _eval(argv, NULL, 0, NULL) )
651 _dprintf("Starting VPN instance failed...");
652 stop_vpnserver(serverNum);
653 return;
656 // Handle firewall rules if appropriate
657 sprintf(&buffer[0], "vpn_server%d_firewall", serverNum);
658 if ( !nvram_contains_word(&buffer[0], "custom") )
660 // Create firewall rules
661 sprintf(&buffer[0], "/etc/openvpn/server%d-fw.sh", serverNum);
662 fp = fopen(&buffer[0], "w");
663 chmod(&buffer[0], S_IRUSR|S_IWUSR|S_IXUSR);
664 fprintf(fp, "#!/bin/sh\n");
665 sprintf(&buffer[0], "vpn_server%d_proto", serverNum);
666 strncpy(&buffer[0], nvram_safe_get(&buffer[0]), BUF_SIZE);
667 fprintf(fp, "iptables -I INPUT -p %s ", strtok(&buffer[0], "-"));
668 sprintf(&buffer[0], "vpn_server%d_port", serverNum);
669 fprintf(fp, "--dport %d -j ACCEPT\n", nvram_get_int(&buffer[0]));
670 sprintf(&buffer[0], "vpn_server%d_firewall", serverNum);
671 if ( !nvram_contains_word(&buffer[0], "external") )
673 fprintf(fp, "iptables -A INPUT -i %s -j ACCEPT\n", &iface[0]);
674 fprintf(fp, "iptables -A FORWARD -i %s -j ACCEPT\n", &iface[0]);
676 fclose(fp);
678 // Run the firewall rules
679 sprintf(&buffer[0], "/etc/openvpn/server%d-fw.sh", serverNum);
680 argv[0] = &buffer[0];
681 argv[1] = NULL;
682 if ( _eval(argv, NULL, 0, NULL) )
684 _dprintf("Adding firewall rules failed...");
685 stop_vpnserver(serverNum);
686 return;
691 void stop_vpnserver(int serverNum)
693 DIR *dir;
694 struct dirent *file;
695 char *fn;
696 int argc;
697 char *argv[9];
698 char buffer[32];
700 // Remove firewall rules
701 sprintf(&buffer[0], "/etc/openvpn/server%d-fw.sh", serverNum);
702 argv[0] = "sed";
703 argv[1] = "-i";
704 argv[2] = "s/-A/-D/g;s/-I/-D/g";
705 argv[3] = &buffer[0];
706 argv[4] = NULL;
707 if (!_eval(argv, NULL, 0, NULL))
709 argv[0] = &buffer[0];
710 argv[1] = NULL;
711 _eval(argv, NULL, 0, NULL);
714 // Stop the VPN server
715 sprintf(&buffer[0], "vpnserver%d", serverNum);
716 killall(&buffer[0], SIGTERM);
718 // NVRAM setting for device type could have changed, just try to remove both
719 sprintf(&buffer[0], "openvpn --rmtun --dev tap%d", serverNum+SERVER_IF_START);
720 for (argv[argc=0] = strtok(&buffer[0], " "); argv[argc] != NULL; argv[++argc] = strtok(NULL, " "));
721 _eval(argv, NULL, 0, NULL);
723 sprintf(&buffer[0], "openvpn --rmtun --dev tun%d", serverNum+SERVER_IF_START);
724 for (argv[argc=0] = strtok(&buffer[0], " "); argv[argc] != NULL; argv[++argc] = strtok(NULL, " "));
725 _eval(argv, NULL, 0, NULL);
727 modprobe_r("tun");
729 if ( nvram_get_int("vpn_debug") != 1 )
731 // Delete all files in /etc/openvpn that match server#
732 sprintf(&buffer[0], "server%d", serverNum);
733 dir = opendir("/etc/openvpn");
734 chdir("/etc/openvpn");
735 while ( (file = readdir(dir)) != NULL )
737 fn = file->d_name;
738 if ( strstr(fn, &buffer[0]) )
739 unlink(fn);
741 closedir(dir);
745 void run_vpn_firewall_scripts()
747 DIR *dir;
748 struct dirent *file;
749 char *fn;
750 char *match = "-fw.sh";
751 char *argv[3];
753 if ( chdir("/etc/openvpn") )
754 return;
756 dir = opendir("/etc/openvpn");
758 while ( (file = readdir(dir)) != NULL )
760 fn = file->d_name;
761 if ( strlen(fn) >= strlen(match) && !strcmp(&fn[strlen(fn)-strlen(match)],match) )
763 _dprintf("Running firewall script: %s", fn);
764 argv[0] = "/bin/sh";
765 argv[1] = fn;
766 argv[2] = NULL;
767 _eval(argv, NULL, 0, NULL);
771 closedir(dir);