Add redirect-gateway options
[tomato.git] / release / src / router / rc / vpn.c
blobe83ad65c9c393a21afdfcfa89427afba099af30f
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];
43 vpnlog(VPN_LOG_INFO,"VPN GUI client backend starting...");
45 sprintf(&buffer[0], "vpnclient%d", clientNum);
46 if ( pidof(&buffer[0]) >= 0 )
48 vpnlog(VPN_LOG_NOTE, "VPN Client %d already running...", clientNum);
49 vpnlog(VPN_LOG_INFO,"PID: %d", pidof(&buffer[0]));
50 return;
53 // Determine interface
54 sprintf(&buffer[0], "vpn_client%d_if", clientNum);
55 if ( nvram_contains_word(&buffer[0], "tap") )
56 ifType = TAP;
57 else if ( nvram_contains_word(&buffer[0], "tun") )
58 ifType = TUN;
59 else
61 vpnlog(VPN_LOG_ERROR, "Invalid interface type, %.3s", nvram_safe_get(&buffer[0]));
62 return;
65 // Build interface name
66 snprintf(&iface[0], IF_SIZE, "%s%d", nvram_safe_get(&buffer[0]), clientNum+CLIENT_IF_START);
68 // Determine encryption mode
69 sprintf(&buffer[0], "vpn_client%d_crypt", clientNum);
70 if ( nvram_contains_word(&buffer[0], "tls") )
71 cryptMode = TLS;
72 else if ( nvram_contains_word(&buffer[0], "secret") )
73 cryptMode = SECRET;
74 else if ( nvram_contains_word(&buffer[0], "custom") )
75 cryptMode = CUSTOM;
76 else
78 vpnlog(VPN_LOG_ERROR,"Invalid encryption mode, %.6s", nvram_safe_get(&buffer[0]));
79 return;
82 // Determine if we should bridge the tunnel
83 sprintf(&buffer[0], "vpn_client%d_bridge", clientNum);
84 if ( ifType == TAP && nvram_get_int(&buffer[0]) == 1 )
85 routeMode = BRIDGE;
87 // Determine if we should NAT the tunnel
88 sprintf(&buffer[0], "vpn_client%d_nat", clientNum);
89 if ( (ifType == TUN || routeMode != BRIDGE) && nvram_get_int(&buffer[0]) == 1 )
90 routeMode = NAT;
92 // Make sure openvpn directory exists
93 mkdir("/etc/openvpn", 0700);
94 sprintf(&buffer[0], "/etc/openvpn/client%d", clientNum);
95 mkdir(&buffer[0], 0700);
97 // Make sure symbolic link exists
98 sprintf(&buffer[0], "/etc/openvpn/vpnclient%d", clientNum);
99 unlink(&buffer[0]);
100 if ( symlink("/usr/sbin/openvpn", &buffer[0]) )
102 vpnlog(VPN_LOG_ERROR,"Creating symlink failed...");
103 stop_vpnclient(clientNum);
104 return;
107 // Make sure module is loaded
108 modprobe("tun");
110 // Create tap/tun interface
111 sprintf(&buffer[0], "openvpn --mktun --dev %s", &iface[0]);
112 for (argv[argc=0] = strtok(&buffer[0], " "); argv[argc] != NULL; argv[++argc] = strtok(NULL, " "));
113 if ( _eval(argv, NULL, 0, NULL) )
115 vpnlog(VPN_LOG_ERROR,"Creating tunnel interface failed...");
116 stop_vpnclient(clientNum);
117 return;
120 // Bring interface up (TAP only)
121 if( ifType == TAP )
123 if ( routeMode == BRIDGE )
125 snprintf(&buffer[0], BUF_SIZE, "brctl addif %s %s", nvram_safe_get("lan_ifname"), &iface[0]);
126 for (argv[argc=0] = strtok(&buffer[0], " "); argv[argc] != NULL; argv[++argc] = strtok(NULL, " "));
127 if ( _eval(argv, NULL, 0, NULL) )
129 vpnlog(VPN_LOG_ERROR,"Adding tunnel interface to bridge failed...");
130 stop_vpnclient(clientNum);
131 return;
135 snprintf(&buffer[0], BUF_SIZE, "ifconfig %s promisc up", nvram_safe_get("lan_ifname"));
136 for (argv[argc=0] = strtok(&buffer[0], " "); argv[argc] != NULL; argv[++argc] = strtok(NULL, " "));
137 if ( _eval(argv, NULL, 0, NULL) )
139 vpnlog(VPN_LOG_ERROR,"Bringing interface up failed...");
140 stop_vpnclient(clientNum);
141 return;
145 // Build and write config file
146 vpnlog(VPN_LOG_EXTRA,"Writing config file");
147 sprintf(&buffer[0], "/etc/openvpn/client%d/config.ovpn", clientNum);
148 fp = fopen(&buffer[0], "w");
149 chmod(&buffer[0], S_IRUSR|S_IWUSR);
150 fprintf(fp, "# Automatically generated configuration\n");
151 fprintf(fp, "daemon\n");
152 if ( cryptMode == TLS )
153 fprintf(fp, "client\n");
154 fprintf(fp, "dev %s\n", &iface[0]);
155 sprintf(&buffer[0], "vpn_client%d_proto", clientNum);
156 fprintf(fp, "proto %s\n", nvram_safe_get(&buffer[0]));
157 sprintf(&buffer[0], "vpn_client%d_addr", clientNum);
158 fprintf(fp, "remote %s ", nvram_safe_get(&buffer[0]));
159 sprintf(&buffer[0], "vpn_client%d_port", clientNum);
160 fprintf(fp, "%d\n", nvram_get_int(&buffer[0]));
161 if ( cryptMode == SECRET )
163 if ( ifType == TUN )
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_remote", clientNum);
168 fprintf(fp, "%s\n", nvram_safe_get(&buffer[0]));
170 else if ( ifType == TAP )
172 sprintf(&buffer[0], "vpn_client%d_local", clientNum);
173 fprintf(fp, "ifconfig %s ", nvram_safe_get(&buffer[0]));
174 sprintf(&buffer[0], "vpn_client%d_nm", clientNum);
175 fprintf(fp, "%s\n", nvram_safe_get(&buffer[0]));
178 sprintf(&buffer[0], "vpn_client%d_retry", clientNum);
179 if ( (nvi = nvram_get_int(&buffer[0])) >= 0 )
180 fprintf(fp, "resolv-retry %d\n", nvi);
181 else
182 fprintf(fp, "resolv-retry infinite\n");
183 fprintf(fp, "nobind\n");
184 fprintf(fp, "persist-key\n");
185 fprintf(fp, "persist-tun\n");
186 sprintf(&buffer[0], "vpn_client%d_comp", clientNum);
187 fprintf(fp, "comp-lzo %s\n", nvram_safe_get(&buffer[0]));
188 sprintf(&buffer[0], "vpn_client%d_cipher", clientNum);
189 if ( !nvram_contains_word(&buffer[0], "default") )
190 fprintf(fp, "cipher %s\n", nvram_safe_get(&buffer[0]));
191 sprintf(&buffer[0], "vpn_client%d_rgw", clientNum);
192 if ( nvram_get_int(&buffer[0]) )
194 sprintf(&buffer[0], "vpn_client%d_gw", clientNum);
195 if ( ifType == TAP && nvram_safe_get(&buffer[0])[0] != '\0' )
196 fprintf(fp, "route-gateway %s\n", nvram_safe_get(&buffer[0]));
197 fprintf(fp, "redirect-gateway def1\n");
199 fprintf(fp, "verb 3\n");
200 if ( cryptMode == TLS )
202 sprintf(&buffer[0], "vpn_client%d_adns", clientNum);
203 if ( nvram_get_int(&buffer[0]) )
205 sprintf(&buffer[0], "/etc/openvpn/client%d/updown.sh", clientNum);
206 symlink("/rom/openvpn/updown.sh", &buffer[0]);
207 fprintf(fp, "script-security 2\n");
208 fprintf(fp, "up updown.sh\n");
209 fprintf(fp, "down updown.sh\n");
212 sprintf(&buffer[0], "vpn_client%d_hmac", clientNum);
213 nvi = nvram_get_int(&buffer[0]);
214 if ( nvi >= 0 )
216 fprintf(fp, "tls-auth static.key");
217 if ( nvi < 2 )
218 fprintf(fp, " %d", nvi);
219 fprintf(fp, "\n");
222 fprintf(fp, "ca ca.crt\n");
223 fprintf(fp, "cert client.crt\n");
224 fprintf(fp, "key client.key\n");
226 else if ( cryptMode == SECRET )
228 fprintf(fp, "secret static.key\n");
230 fprintf(fp, "status-version 2\n");
231 fprintf(fp, "status status\n");
232 fprintf(fp, "\n# Custom Configuration\n");
233 sprintf(&buffer[0], "vpn_client%d_custom", clientNum);
234 fprintf(fp, nvram_safe_get(&buffer[0]));
235 fclose(fp);
236 vpnlog(VPN_LOG_EXTRA,"Done writing config file");
238 // Write certification and key files
239 vpnlog(VPN_LOG_EXTRA,"Writing certs/keys");
240 if ( cryptMode == TLS )
242 sprintf(&buffer[0], "/etc/openvpn/client%d/ca.crt", clientNum);
243 fp = fopen(&buffer[0], "w");
244 chmod(&buffer[0], S_IRUSR|S_IWUSR);
245 sprintf(&buffer[0], "vpn_client%d_ca", clientNum);
246 fprintf(fp, nvram_safe_get(&buffer[0]));
247 fclose(fp);
249 sprintf(&buffer[0], "/etc/openvpn/client%d/client.key", clientNum);
250 fp = fopen(&buffer[0], "w");
251 chmod(&buffer[0], S_IRUSR|S_IWUSR);
252 sprintf(&buffer[0], "vpn_client%d_key", clientNum);
253 fprintf(fp, nvram_safe_get(&buffer[0]));
254 fclose(fp);
256 sprintf(&buffer[0], "/etc/openvpn/client%d/client.crt", clientNum);
257 fp = fopen(&buffer[0], "w");
258 chmod(&buffer[0], S_IRUSR|S_IWUSR);
259 sprintf(&buffer[0], "vpn_client%d_crt", clientNum);
260 fprintf(fp, nvram_safe_get(&buffer[0]));
261 fclose(fp);
263 sprintf(&buffer[0], "vpn_client%d_hmac", clientNum);
264 if ( cryptMode == SECRET || (cryptMode == TLS && nvram_get_int(&buffer[0]) >= 0) )
266 sprintf(&buffer[0], "/etc/openvpn/client%d/static.key", clientNum);
267 fp = fopen(&buffer[0], "w");
268 chmod(&buffer[0], S_IRUSR|S_IWUSR);
269 sprintf(&buffer[0], "vpn_client%d_static", clientNum);
270 fprintf(fp, nvram_safe_get(&buffer[0]));
271 fclose(fp);
273 vpnlog(VPN_LOG_EXTRA,"Done writing certs/keys");
275 // Start the VPN client
276 sprintf(&buffer[0], "/etc/openvpn/vpnclient%d --cd /etc/openvpn/client%d --config config.ovpn", clientNum, clientNum);
277 vpnlog(VPN_LOG_INFO,"Starting OpenVPN: %s",&buffer[0]);
278 for (argv[argc=0] = strtok(&buffer[0], " "); argv[argc] != NULL; argv[++argc] = strtok(NULL, " "));
279 if ( _eval(argv, NULL, 0, NULL) )
281 vpnlog(VPN_LOG_ERROR,"Starting OpenVPN failed...");
282 stop_vpnclient(clientNum);
283 return;
285 vpnlog(VPN_LOG_EXTRA,"Done starting openvpn");
287 // Handle firewall rules if appropriate
288 sprintf(&buffer[0], "vpn_client%d_firewall", clientNum);
289 if ( !nvram_contains_word(&buffer[0], "custom") )
291 // Create firewall rules
292 vpnlog(VPN_LOG_EXTRA,"Creating firewall rules");
293 mkdir("/etc/openvpn/fw", 0700);
294 sprintf(&buffer[0], "/etc/openvpn/fw/client%d-fw.sh", clientNum);
295 fp = fopen(&buffer[0], "w");
296 chmod(&buffer[0], S_IRUSR|S_IWUSR|S_IXUSR);
297 fprintf(fp, "#!/bin/sh\n");
298 fprintf(fp, "iptables -I INPUT -i %s -j ACCEPT\n", &iface[0]);
299 fprintf(fp, "iptables -I FORWARD -i %s -j ACCEPT\n", &iface[0]);
300 if ( routeMode == NAT )
302 sscanf(nvram_safe_get("lan_ipaddr"), "%d.%d.%d.%d", &ip[0], &ip[1], &ip[2], &ip[3]);
303 sscanf(nvram_safe_get("lan_netmask"), "%d.%d.%d.%d", &nm[0], &nm[1], &nm[2], &nm[3]);
304 fprintf(fp, "iptables -t nat -I POSTROUTING -s %d.%d.%d.%d/%s -o %s -j MASQUERADE\n",
305 ip[0]&nm[0], ip[1]&nm[1], ip[2]&nm[2], ip[3]&nm[3], nvram_safe_get("lan_netmask"), &iface[0]);
307 fclose(fp);
308 vpnlog(VPN_LOG_EXTRA,"Done creating firewall rules");
310 // Run the firewall rules
311 vpnlog(VPN_LOG_EXTRA,"Running firewall rules");
312 sprintf(&buffer[0], "/etc/openvpn/fw/client%d-fw.sh", clientNum);
313 argv[0] = &buffer[0];
314 argv[1] = NULL;
315 _eval(argv, NULL, 0, NULL);
316 vpnlog(VPN_LOG_EXTRA,"Done running firewall rules");
319 vpnlog(VPN_LOG_INFO,"VPN GUI server backend complete.");
322 void stop_vpnclient(int clientNum)
324 int argc;
325 char *argv[7];
326 char buffer[BUF_SIZE];
328 vpnlog(VPN_LOG_INFO,"Stopping VPN GUI client backend.");
330 // Remove firewall rules
331 vpnlog(VPN_LOG_EXTRA,"Removing firewall rules.");
332 sprintf(&buffer[0], "/etc/openvpn/fw/client%d-fw.sh", clientNum);
333 argv[0] = "sed";
334 argv[1] = "-i";
335 argv[2] = "s/-A/-D/g;s/-I/-D/g";
336 argv[3] = &buffer[0];
337 argv[4] = NULL;
338 if (!_eval(argv, NULL, 0, NULL))
340 argv[0] = &buffer[0];
341 argv[1] = NULL;
342 _eval(argv, NULL, 0, NULL);
344 vpnlog(VPN_LOG_EXTRA,"Done removing firewall rules.");
346 // Stop the VPN client
347 vpnlog(VPN_LOG_EXTRA,"Stopping OpenVPN client.");
348 sprintf(&buffer[0], "vpnclient%d", clientNum);
349 killall(&buffer[0], SIGTERM);
350 vpnlog(VPN_LOG_EXTRA,"OpenVPN client stopped.");
352 // NVRAM setting for device type could have changed, just try to remove both
353 vpnlog(VPN_LOG_EXTRA,"Removing VPN device.");
354 sprintf(&buffer[0], "openvpn --rmtun --dev tap%d", clientNum+CLIENT_IF_START);
355 for (argv[argc=0] = strtok(&buffer[0], " "); argv[argc] != NULL; argv[++argc] = strtok(NULL, " "));
356 _eval(argv, NULL, 0, NULL);
358 sprintf(&buffer[0], "openvpn --rmtun --dev tun%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);
361 vpnlog(VPN_LOG_EXTRA,"VPN device removed.");
363 modprobe_r("tun");
365 if ( nvram_get_int("vpn_debug") <= VPN_LOG_EXTRA )
367 vpnlog(VPN_LOG_EXTRA,"Removing generated files.");
368 // Delete all files for this client
369 sprintf(&buffer[0], "rm -rf /etc/openvpn/client%d /etc/openvpn/fw/client%d-fw.sh /etc/openvpn/vpnclient%d",clientNum,clientNum,clientNum);
370 for (argv[argc=0] = strtok(&buffer[0], " "); argv[argc] != NULL; argv[++argc] = strtok(NULL, " "));
371 _eval(argv, NULL, 0, NULL);
373 // Attempt to remove directories. Will fail if not empty
374 rmdir("/etc/openvpn/fw");
375 rmdir("/etc/openvpn");
376 vpnlog(VPN_LOG_EXTRA,"Done removing generated files.");
379 vpnlog(VPN_LOG_INFO,"VPN GUI client backend stopped.");
382 void start_vpnserver(int serverNum)
384 FILE *fp, *ccd;
385 char iface[IF_SIZE];
386 char buffer[BUF_SIZE];
387 char *argv[6], *chp, *route;
388 int argc = 0;
389 int c2c = 0;
390 enum { TAP, TUN } ifType = TUN;
391 enum { TLS, SECRET, CUSTOM } cryptMode = CUSTOM;
392 int nvi, ip[4], nm[4];
394 vpnlog(VPN_LOG_INFO,"VPN GUI server backend starting...");
396 sprintf(&buffer[0], "vpnserver%d", serverNum);
397 if ( pidof(&buffer[0]) >= 0 )
399 vpnlog(VPN_LOG_NOTE, "VPN Server %d already running...", serverNum);
400 vpnlog(VPN_LOG_INFO,"PID: %d", pidof(&buffer[0]));
401 return;
404 // Determine interface type
405 sprintf(&buffer[0], "vpn_server%d_if", serverNum);
406 if ( nvram_contains_word(&buffer[0], "tap") )
407 ifType = TAP;
408 else if ( nvram_contains_word(&buffer[0], "tun") )
409 ifType = TUN;
410 else
412 vpnlog(VPN_LOG_ERROR,"Invalid interface type, %.3s", nvram_safe_get(&buffer[0]));
413 return;
416 // Build interface name
417 snprintf(&iface[0], IF_SIZE, "%s%d", nvram_safe_get(&buffer[0]), serverNum+SERVER_IF_START);
419 // Determine encryption mode
420 sprintf(&buffer[0], "vpn_server%d_crypt", serverNum);
421 if ( nvram_contains_word(&buffer[0], "tls") )
422 cryptMode = TLS;
423 else if ( nvram_contains_word(&buffer[0], "secret") )
424 cryptMode = SECRET;
425 else if ( nvram_contains_word(&buffer[0], "custom") )
426 cryptMode = CUSTOM;
427 else
429 vpnlog(VPN_LOG_ERROR,"Invalid encryption mode, %.6s", nvram_safe_get(&buffer[0]));
430 return;
433 // Make sure openvpn directory exists
434 mkdir("/etc/openvpn", 0700);
435 sprintf(&buffer[0], "/etc/openvpn/server%d", serverNum);
436 mkdir(&buffer[0], 0700);
438 // Make sure symbolic link exists
439 sprintf(&buffer[0], "/etc/openvpn/vpnserver%d", serverNum);
440 unlink(&buffer[0]);
441 if ( symlink("/usr/sbin/openvpn", &buffer[0]) )
443 vpnlog(VPN_LOG_ERROR,"Creating symlink failed...");
444 stop_vpnserver(serverNum);
445 return;
448 // Make sure module is loaded
449 modprobe("tun");
451 // Create tap/tun interface
452 sprintf(&buffer[0], "openvpn --mktun --dev %s", &iface[0]);
453 for (argv[argc=0] = strtok(&buffer[0], " "); argv[argc] != NULL; argv[++argc] = strtok(NULL, " "));
454 if ( _eval(argv, NULL, 0, NULL) )
456 vpnlog(VPN_LOG_ERROR,"Creating tunnel interface failed...");
457 stop_vpnserver(serverNum);
458 return;
461 // Add interface to LAN bridge (TAP only)
462 if( ifType == TAP )
464 snprintf(&buffer[0], BUF_SIZE, "brctl addif %s %s", nvram_safe_get("lan_ifname"), &iface[0]);
465 for (argv[argc=0] = strtok(&buffer[0], " "); argv[argc] != NULL; argv[++argc] = strtok(NULL, " "));
466 if ( _eval(argv, NULL, 0, NULL) )
468 vpnlog(VPN_LOG_ERROR,"Adding tunnel interface to bridge failed...");
469 stop_vpnserver(serverNum);
470 return;
474 // Bring interface up
475 sprintf(&buffer[0], "ifconfig %s 0.0.0.0 promisc up", &iface[0]);
476 for (argv[argc=0] = strtok(&buffer[0], " "); argv[argc] != NULL; argv[++argc] = strtok(NULL, " "));
477 if ( _eval(argv, NULL, 0, NULL) )
479 vpnlog(VPN_LOG_ERROR,"Bringing up tunnel interface failed...");
480 stop_vpnserver(serverNum);
481 return;
484 // Build and write config files
485 vpnlog(VPN_LOG_EXTRA,"Writing config file");
486 sprintf(&buffer[0], "/etc/openvpn/server%d/config.ovpn", serverNum);
487 fp = fopen(&buffer[0], "w");
488 chmod(&buffer[0], S_IRUSR|S_IWUSR);
489 fprintf(fp, "# Automatically generated configuration\n");
490 fprintf(fp, "daemon\n");
491 if ( cryptMode == TLS )
493 if ( ifType == TUN )
495 sprintf(&buffer[0], "vpn_server%d_sn", serverNum);
496 fprintf(fp, "server %s ", nvram_safe_get(&buffer[0]));
497 sprintf(&buffer[0], "vpn_server%d_nm", serverNum);
498 fprintf(fp, "%s\n", nvram_safe_get(&buffer[0]));
500 else if ( ifType == TAP )
502 fprintf(fp, "server-bridge");
503 sprintf(&buffer[0], "vpn_server%d_dhcp", serverNum);
504 if ( nvram_get_int(&buffer[0]) == 0 )
506 fprintf(fp, " %s ", nvram_safe_get("lan_ipaddr"));
507 fprintf(fp, "%s ", nvram_safe_get("lan_netmask"));
508 sprintf(&buffer[0], "vpn_server%d_r1", serverNum);
509 fprintf(fp, "%s ", nvram_safe_get(&buffer[0]));
510 sprintf(&buffer[0], "vpn_server%d_r2", serverNum);
511 fprintf(fp, "%s", nvram_safe_get(&buffer[0]));
513 fprintf(fp, "\n");
516 else if ( cryptMode == SECRET )
518 if ( ifType == TUN )
520 sprintf(&buffer[0], "vpn_server%d_local", serverNum);
521 fprintf(fp, "ifconfig %s ", nvram_safe_get(&buffer[0]));
522 sprintf(&buffer[0], "vpn_server%d_remote", serverNum);
523 fprintf(fp, "%s\n", nvram_safe_get(&buffer[0]));
526 sprintf(&buffer[0], "vpn_server%d_proto", serverNum);
527 fprintf(fp, "proto %s\n", nvram_safe_get(&buffer[0]));
528 sprintf(&buffer[0], "vpn_server%d_port", serverNum);
529 fprintf(fp, "port %d\n", nvram_get_int(&buffer[0]));
530 fprintf(fp, "dev %s\n", &iface[0]);
531 sprintf(&buffer[0], "vpn_server%d_cipher", serverNum);
532 if ( !nvram_contains_word(&buffer[0], "default") )
533 fprintf(fp, "cipher %s\n", nvram_safe_get(&buffer[0]));
534 sprintf(&buffer[0], "vpn_server%d_comp", serverNum);
535 fprintf(fp, "comp-lzo %s\n", nvram_safe_get(&buffer[0]));
536 fprintf(fp, "keepalive 15 60\n");
537 fprintf(fp, "verb 3\n");
538 if ( cryptMode == TLS )
540 if ( ifType == TUN )
542 sscanf(nvram_safe_get("lan_ipaddr"), "%d.%d.%d.%d", &ip[0], &ip[1], &ip[2], &ip[3]);
543 sscanf(nvram_safe_get("lan_netmask"), "%d.%d.%d.%d", &nm[0], &nm[1], &nm[2], &nm[3]);
544 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],
545 nvram_safe_get("lan_netmask"));
548 sprintf(&buffer[0], "vpn_server%d_ccd", serverNum);
549 if ( nvram_get_int(&buffer[0]) )
551 fprintf(fp, "client-config-dir ccd\n");
553 sprintf(&buffer[0], "vpn_server%d_c2c", serverNum);
554 if ( (c2c = nvram_get_int(&buffer[0])) )
555 fprintf(fp, "client-to-client\n");
557 sprintf(&buffer[0], "vpn_server%d_ccd_excl", serverNum);
558 if ( nvram_get_int(&buffer[0]) )
559 fprintf(fp, "ccd-exclusive\n");
561 sprintf(&buffer[0], "/etc/openvpn/server%d/ccd", serverNum);
562 mkdir(&buffer[0], 0700);
563 chdir(&buffer[0]);
565 sprintf(&buffer[0], "vpn_server%d_ccd_val", serverNum);
566 strcpy(&buffer[0], nvram_safe_get(&buffer[0]));
567 chp = strtok(&buffer[0],">");
568 while ( chp != NULL )
570 nvi = strlen(chp);
572 chp[strcspn(chp,"<")] = '\0';
573 vpnlog(VPN_LOG_EXTRA,"CCD: enabled: %d", atoi(chp));
574 if ( atoi(chp) == 1 )
576 nvi -= strlen(chp)+1;
577 chp += strlen(chp)+1;
579 ccd = NULL;
580 route = NULL;
581 if ( nvi > 0 )
583 chp[strcspn(chp,"<")] = '\0';
584 vpnlog(VPN_LOG_EXTRA,"CCD: Common name: %s", chp);
585 ccd = fopen(chp, "w");
586 chmod(chp, S_IRUSR|S_IWUSR);
588 nvi -= strlen(chp)+1;
589 chp += strlen(chp)+1;
591 if ( nvi > 0 && ccd != NULL && strcspn(chp,"<") != strlen(chp) )
593 chp[strcspn(chp,"<")] = ' ';
594 chp[strcspn(chp,"<")] = '\0';
595 route = chp;
596 vpnlog(VPN_LOG_EXTRA,"CCD: Route: %s", chp);
597 if ( strlen(route) > 1 )
599 fprintf(ccd, "iroute %s\n", route);
600 fprintf(fp, "route %s\n", route);
603 nvi -= strlen(chp)+1;
604 chp += strlen(chp)+1;
606 if ( ccd != NULL )
607 fclose(ccd);
608 if ( nvi > 0 && route != NULL )
610 chp[strcspn(chp,"<")] = '\0';
611 vpnlog(VPN_LOG_EXTRA,"CCD: Push: %d", atoi(chp));
612 if ( c2c && atoi(chp) == 1 && strlen(route) > 1 )
613 fprintf(fp, "push \"route %s\"\n", route);
615 nvi -= strlen(chp)+1;
616 chp += strlen(chp)+1;
619 vpnlog(VPN_LOG_EXTRA,"CCD leftover: %d", nvi+1);
621 // Advance to next entry
622 chp = strtok(NULL, ">");
624 vpnlog(VPN_LOG_EXTRA,"CCD processing complete");
627 sprintf(&buffer[0], "vpn_server%d_pdns", serverNum);
628 if ( nvram_get_int(&buffer[0]) )
630 if ( nvram_safe_get("wan_domain")[0] != '\0' )
631 fprintf(fp, "push \"dhcp-option DOMAIN %s\"\n", nvram_safe_get("wan_domain"));
632 fprintf(fp, "push \"dhcp-option DNS %s\"\n", nvram_safe_get("lan_ipaddr"));
635 sprintf(&buffer[0], "vpn_server%d_rgw", serverNum);
636 if ( nvram_get_int(&buffer[0]) )
638 if ( ifType == TAP )
639 fprintf(fp, "push \"route-gateway %s\"\n", nvram_safe_get("lan_ipaddr"));
640 fprintf(fp, "push \"redirect-gateway def1\"\n");
643 sprintf(&buffer[0], "vpn_server%d_hmac", serverNum);
644 nvi = nvram_get_int(&buffer[0]);
645 if ( nvi >= 0 )
647 fprintf(fp, "tls-auth static.key");
648 if ( nvi < 2 )
649 fprintf(fp, " %d", nvi);
650 fprintf(fp, "\n");
653 fprintf(fp, "ca ca.crt\n");
654 fprintf(fp, "dh dh.pem\n");
655 fprintf(fp, "cert server.crt\n");
656 fprintf(fp, "key server.key\n");
658 else if ( cryptMode == SECRET )
660 fprintf(fp, "secret static.key\n");
662 fprintf(fp, "status-version 2\n");
663 fprintf(fp, "status status\n");
664 fprintf(fp, "\n# Custom Configuration\n");
665 sprintf(&buffer[0], "vpn_server%d_custom", serverNum);
666 fprintf(fp, nvram_safe_get(&buffer[0]));
667 fclose(fp);
668 vpnlog(VPN_LOG_EXTRA,"Done writing config file");
670 // Write certification and key files
671 vpnlog(VPN_LOG_EXTRA,"Writing certs/keys");
672 if ( cryptMode == TLS )
674 sprintf(&buffer[0], "/etc/openvpn/server%d/ca.crt", serverNum);
675 fp = fopen(&buffer[0], "w");
676 chmod(&buffer[0], S_IRUSR|S_IWUSR);
677 sprintf(&buffer[0], "vpn_server%d_ca", serverNum);
678 fprintf(fp, nvram_safe_get(&buffer[0]));
679 fclose(fp);
681 sprintf(&buffer[0], "/etc/openvpn/server%d/server.key", serverNum);
682 fp = fopen(&buffer[0], "w");
683 chmod(&buffer[0], S_IRUSR|S_IWUSR);
684 sprintf(&buffer[0], "vpn_server%d_key", serverNum);
685 fprintf(fp, nvram_safe_get(&buffer[0]));
686 fclose(fp);
688 sprintf(&buffer[0], "/etc/openvpn/server%d/server.crt", serverNum);
689 fp = fopen(&buffer[0], "w");
690 chmod(&buffer[0], S_IRUSR|S_IWUSR);
691 sprintf(&buffer[0], "vpn_server%d_crt", serverNum);
692 fprintf(fp, nvram_safe_get(&buffer[0]));
693 fclose(fp);
695 sprintf(&buffer[0], "/etc/openvpn/server%d/dh.pem", serverNum);
696 fp = fopen(&buffer[0], "w");
697 chmod(&buffer[0], S_IRUSR|S_IWUSR);
698 sprintf(&buffer[0], "vpn_server%d_dh", serverNum);
699 fprintf(fp, nvram_safe_get(&buffer[0]));
700 fclose(fp);
702 sprintf(&buffer[0], "vpn_server%d_hmac", serverNum);
703 if ( cryptMode == SECRET || (cryptMode == TLS && nvram_get_int(&buffer[0]) >= 0) )
705 sprintf(&buffer[0], "/etc/openvpn/server%d/static.key", serverNum);
706 fp = fopen(&buffer[0], "w");
707 chmod(&buffer[0], S_IRUSR|S_IWUSR);
708 sprintf(&buffer[0], "vpn_server%d_static", serverNum);
709 fprintf(fp, nvram_safe_get(&buffer[0]));
710 fclose(fp);
712 vpnlog(VPN_LOG_EXTRA,"Done writing certs/keys");
714 sprintf(&buffer[0], "/etc/openvpn/vpnserver%d --cd /etc/openvpn/server%d --config config.ovpn", serverNum, serverNum);
715 vpnlog(VPN_LOG_INFO,"Starting OpenVPN: %s",&buffer[0]);
716 for (argv[argc=0] = strtok(&buffer[0], " "); argv[argc] != NULL; argv[++argc] = strtok(NULL, " "));
717 if ( _eval(argv, NULL, 0, NULL) )
719 vpnlog(VPN_LOG_ERROR,"Starting VPN instance failed...");
720 stop_vpnserver(serverNum);
721 return;
723 vpnlog(VPN_LOG_EXTRA,"Done starting openvpn");
725 // Handle firewall rules if appropriate
726 sprintf(&buffer[0], "vpn_server%d_firewall", serverNum);
727 if ( !nvram_contains_word(&buffer[0], "custom") )
729 // Create firewall rules
730 vpnlog(VPN_LOG_EXTRA,"Creating firewall rules");
731 mkdir("/etc/openvpn/fw", 0700);
732 sprintf(&buffer[0], "/etc/openvpn/fw/server%d-fw.sh", serverNum);
733 fp = fopen(&buffer[0], "w");
734 chmod(&buffer[0], S_IRUSR|S_IWUSR|S_IXUSR);
735 fprintf(fp, "#!/bin/sh\n");
736 sprintf(&buffer[0], "vpn_server%d_proto", serverNum);
737 strncpy(&buffer[0], nvram_safe_get(&buffer[0]), BUF_SIZE);
738 fprintf(fp, "iptables -t nat -I PREROUTING -p %s ", strtok(&buffer[0], "-"));
739 sprintf(&buffer[0], "vpn_server%d_port", serverNum);
740 fprintf(fp, "--dport %d -j ACCEPT\n", nvram_get_int(&buffer[0]));
741 sprintf(&buffer[0], "vpn_server%d_proto", serverNum);
742 strncpy(&buffer[0], nvram_safe_get(&buffer[0]), BUF_SIZE);
743 fprintf(fp, "iptables -I INPUT -p %s ", strtok(&buffer[0], "-"));
744 sprintf(&buffer[0], "vpn_server%d_port", serverNum);
745 fprintf(fp, "--dport %d -j ACCEPT\n", nvram_get_int(&buffer[0]));
746 sprintf(&buffer[0], "vpn_server%d_firewall", serverNum);
747 if ( !nvram_contains_word(&buffer[0], "external") )
749 fprintf(fp, "iptables -I INPUT -i %s -j ACCEPT\n", &iface[0]);
750 fprintf(fp, "iptables -I FORWARD -i %s -j ACCEPT\n", &iface[0]);
752 fclose(fp);
753 vpnlog(VPN_LOG_EXTRA,"Done creating firewall rules");
755 // Run the firewall rules
756 vpnlog(VPN_LOG_EXTRA,"Running firewall rules");
757 sprintf(&buffer[0], "/etc/openvpn/fw/server%d-fw.sh", serverNum);
758 argv[0] = &buffer[0];
759 argv[1] = NULL;
760 _eval(argv, NULL, 0, NULL);
761 vpnlog(VPN_LOG_EXTRA,"Done running firewall rules");
764 vpnlog(VPN_LOG_INFO,"VPN GUI server backend complete.");
767 void stop_vpnserver(int serverNum)
769 int argc;
770 char *argv[9];
771 char buffer[BUF_SIZE];
773 vpnlog(VPN_LOG_INFO,"Stopping VPN GUI server backend.");
775 // Remove firewall rules
776 vpnlog(VPN_LOG_EXTRA,"Removing firewall rules.");
777 sprintf(&buffer[0], "/etc/openvpn/fw/server%d-fw.sh", serverNum);
778 argv[0] = "sed";
779 argv[1] = "-i";
780 argv[2] = "s/-A/-D/g;s/-I/-D/g";
781 argv[3] = &buffer[0];
782 argv[4] = NULL;
783 if (!_eval(argv, NULL, 0, NULL))
785 argv[0] = &buffer[0];
786 argv[1] = NULL;
787 _eval(argv, NULL, 0, NULL);
789 vpnlog(VPN_LOG_EXTRA,"Done removing firewall rules.");
791 // Stop the VPN server
792 vpnlog(VPN_LOG_EXTRA,"Stopping OpenVPN server.");
793 sprintf(&buffer[0], "vpnserver%d", serverNum);
794 killall(&buffer[0], SIGTERM);
795 vpnlog(VPN_LOG_EXTRA,"OpenVPN server stopped.");
797 // NVRAM setting for device type could have changed, just try to remove both
798 vpnlog(VPN_LOG_EXTRA,"Removing VPN device.");
799 sprintf(&buffer[0], "openvpn --rmtun --dev tap%d", serverNum+SERVER_IF_START);
800 for (argv[argc=0] = strtok(&buffer[0], " "); argv[argc] != NULL; argv[++argc] = strtok(NULL, " "));
801 _eval(argv, NULL, 0, NULL);
803 sprintf(&buffer[0], "openvpn --rmtun --dev tun%d", serverNum+SERVER_IF_START);
804 for (argv[argc=0] = strtok(&buffer[0], " "); argv[argc] != NULL; argv[++argc] = strtok(NULL, " "));
805 _eval(argv, NULL, 0, NULL);
806 vpnlog(VPN_LOG_EXTRA,"VPN device removed.");
808 modprobe_r("tun");
810 if ( nvram_get_int("vpn_debug") <= VPN_LOG_EXTRA )
812 vpnlog(VPN_LOG_EXTRA,"Removing generated files.");
813 // Delete all files for this server
814 sprintf(&buffer[0], "rm -rf /etc/openvpn/server%d /etc/openvpn/fw/server%d-fw.sh /etc/openvpn/vpnserver%d",serverNum,serverNum,serverNum);
815 for (argv[argc=0] = strtok(&buffer[0], " "); argv[argc] != NULL; argv[++argc] = strtok(NULL, " "));
816 _eval(argv, NULL, 0, NULL);
818 // Attempt to remove directories. Will fail if not empty
819 rmdir("/etc/openvpn/fw");
820 rmdir("/etc/openvpn");
821 vpnlog(VPN_LOG_EXTRA,"Done removing generated files.");
824 vpnlog(VPN_LOG_INFO,"VPN GUI server backend stopped.");
827 void start_vpn_eas()
829 char buffer[16], *cur;
830 int nums[4], i;
832 // Parse and start servers
833 strlcpy(&buffer[0], nvram_safe_get("vpn_server_eas"), sizeof(buffer));
834 if ( strlen(&buffer[0]) != 0 ) vpnlog(VPN_LOG_INFO, "Starting servers (eas): %s", &buffer[0]);
835 i = 0;
836 for( cur = strtok(&buffer[0],","); cur != NULL && i < 4; cur = strtok(NULL, ",")) { nums[i++] = atoi(cur); }
837 nums[i] = 0;
838 for( i = 0; nums[i] > 0; i++ ) { vpnlog(VPN_LOG_INFO, "Starting server %d (eas)", nums[i]); start_vpnserver(nums[i]); }
840 // Parse and start clients
841 strlcpy(&buffer[0], nvram_safe_get("vpn_client_eas"), sizeof(buffer));
842 if ( strlen(&buffer[0]) != 0 ) vpnlog(VPN_LOG_INFO, "Starting clients (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 client %d (eas)", nums[i]); start_vpnclient(nums[i]); }
849 void run_vpn_firewall_scripts()
851 DIR *dir;
852 struct dirent *file;
853 char *fn;
854 char *argv[3];
856 if ( chdir("/etc/openvpn/fw") )
857 return;
859 dir = opendir("/etc/openvpn/fw");
861 vpnlog(VPN_LOG_EXTRA,"Beginning all firewall scripts...");
862 while ( (file = readdir(dir)) != NULL )
864 fn = file->d_name;
865 if ( fn[0] == '.' )
866 continue;
867 vpnlog(VPN_LOG_INFO,"Running firewall script: %s", fn);
868 argv[0] = "/bin/sh";
869 argv[1] = fn;
870 argv[2] = NULL;
871 _eval(argv, NULL, 0, NULL);
873 vpnlog(VPN_LOG_EXTRA,"Done with all firewall scripts...");
875 closedir(dir);
878 void write_vpn_dnsmasq_config(FILE* f)
880 char nv[16];
881 char buf[16];
882 char *pos;
883 int cur;
885 strlcpy(&buf[0], nvram_safe_get("vpn_server_dns"), sizeof(buf));
886 for ( pos = strtok(&buf[0],","); pos != NULL; pos=strtok(NULL, ",") )
888 cur = atoi(pos);
889 if ( cur )
891 vpnlog(VPN_LOG_EXTRA, "Adding server %d interface to dns config", cur);
892 snprintf(&nv[0], 16, "vpn_server%d_if", cur);
893 fprintf(f, "interface=%s%d\n", nvram_safe_get(&nv[0]), SERVER_IF_START+cur);
898 void write_vpn_resolv(FILE* f)
900 DIR *dir;
901 struct dirent *file;
902 char *fn, ch;
903 FILE *dnsf;
905 if ( chdir("/etc/openvpn/dns") )
906 return;
908 dir = opendir("/etc/openvpn/dns");
910 vpnlog(VPN_LOG_EXTRA, "Adding DNS entries...");
911 while ( (file = readdir(dir)) != NULL )
913 fn = file->d_name;
915 if ( fn[0] == '.' )
916 continue;
918 if ( (dnsf = fopen(fn, "r")) == NULL )
919 continue;
921 vpnlog(VPN_LOG_INFO,"Adding DNS entries from %s", fn);
923 while( !feof(dnsf) )
925 ch = fgetc(dnsf);
926 fputc(ch==EOF?'\n':ch, f);
929 fclose(dnsf);
931 vpnlog(VPN_LOG_EXTRA, "Done with DNS entries...");
933 closedir(dir);