]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blob - src/misc-progs/openvpnctrl.c
Fix vnstat directory creation
[people/pmueller/ipfire-2.x.git] / src / misc-progs / openvpnctrl.c
1 #include <stdio.h>
2 #include <string.h>
3 #include <unistd.h>
4 #include <stdlib.h>
5 #include <sys/types.h>
6 #include <fcntl.h>
7 #include "setuid.h"
8 #include "libsmooth.h"
9
10 #define noovpndebug
11
12 // global vars
13 struct keyvalue *kv = NULL;
14 FILE *ifacefile = NULL;
15
16 char redif[STRING_SIZE];
17 char blueif[STRING_SIZE];
18 char orangeif[STRING_SIZE];
19 char enablered[STRING_SIZE] = "off";
20 char enableblue[STRING_SIZE] = "off";
21 char enableorange[STRING_SIZE] = "off";
22
23 // consts
24 char OVPNRED[STRING_SIZE] = "OVPN";
25 char OVPNBLUE[STRING_SIZE] = "OVPN_BLUE_";
26 char OVPNORANGE[STRING_SIZE] = "OVPN_ORANGE_";
27 char WRAPPERVERSION[STRING_SIZE] = "2.0.1.6";
28
29 void exithandler(void)
30 {
31 if(kv)
32 freekeyvalues(kv);
33 if (ifacefile)
34 fclose(ifacefile);
35 }
36
37 void usage(void)
38 {
39 #ifdef ovpndebug
40 printf("Wrapper for OpenVPN v%s-debug\n", WRAPPERVERSION);
41 #else
42 printf("Wrapper for OpenVPN v%s\n", WRAPPERVERSION);
43 #endif
44 printf("openvpnctrl <option>\n");
45 printf(" Valid options are:\n");
46 printf(" -s --start\n");
47 printf(" starts OpenVPN (implicitly creates chains and firewall rules)\n");
48 printf(" -k --kill\n");
49 printf(" kills/stops OpenVPN\n");
50 printf(" -r --restart\n");
51 printf(" restarts OpenVPN (implicitly creates chains and firewall rules)\n");
52 printf(" -d --display\n");
53 printf(" displays OpenVPN status to syslog\n");
54 printf(" -fwr --firewall-rules\n");
55 printf(" removes current OpenVPN chains and rules and resets them according to the config\n");
56 printf(" -sdo --start-daemon-only\n");
57 printf(" starts OpenVPN daemon only\n");
58 printf(" -ccr --create-chains-and-rules\n");
59 printf(" creates chains and rules for OpenVPN\n");
60 printf(" -dcr --delete-chains-and-rules\n");
61 printf(" removes all chains for OpenVPN\n");
62 exit(1);
63 }
64
65 void ovpnInit(void) {
66
67 // Read OpenVPN configuration
68 kv = initkeyvalues();
69 if (!readkeyvalues(kv, CONFIG_ROOT "/ovpn/settings")) {
70 fprintf(stderr, "Cannot read ovpn settings\n");
71 exit(1);
72 }
73
74 if (!findkey(kv, "ENABLED", enablered)) {
75 fprintf(stderr, "Cannot read ENABLED\n");
76 exit(1);
77 }
78
79 if (!findkey(kv, "ENABLED_BLUE", enableblue)){
80 fprintf(stderr, "Cannot read ENABLED_BLUE\n");
81 exit(1);
82 }
83
84 if (!findkey(kv, "ENABLED_ORANGE", enableorange)){
85 fprintf(stderr, "Cannot read ENABLED_ORANGE\n");
86 exit(1);
87 }
88 freekeyvalues(kv);
89
90 // read interface settings
91
92 // details for the red int
93 memset(redif, 0, STRING_SIZE);
94 if ((ifacefile = fopen(CONFIG_ROOT "/red/iface", "r")))
95 {
96 if (fgets(redif, STRING_SIZE, ifacefile))
97 {
98 if (redif[strlen(redif) - 1] == '\n')
99 redif[strlen(redif) - 1] = '\0';
100 }
101 fclose (ifacefile);
102 ifacefile = NULL;
103
104 if (!VALID_DEVICE(redif))
105 {
106 memset(redif, 0, STRING_SIZE);
107 }
108 }
109
110 kv=initkeyvalues();
111 if (!readkeyvalues(kv, CONFIG_ROOT "/ethernet/settings"))
112 {
113 fprintf(stderr, "Cannot read ethernet settings\n");
114 exit(1);
115 }
116
117 if (strcmp(enableblue, "on")==0){
118 if (!findkey(kv, "BLUE_DEV", blueif)){
119 fprintf(stderr, "Cannot read BLUE_DEV\n");
120 exit(1);
121 }
122 }
123 if (strcmp(enableorange, "on")==0){
124 if (!findkey(kv, "ORANGE_DEV", orangeif)){
125 fprintf(stderr, "Cannot read ORNAGE_DEV\n");
126 exit(1);
127 }
128 }
129 freekeyvalues(kv);
130 }
131
132 void executeCommand(char *command) {
133 #ifdef ovpndebug
134 printf(strncat(command, "\n", 2));
135 #endif
136 safe_system(strncat(command, " >/dev/null 2>&1", 17));
137 }
138
139 void setChainRules(char *chain, char *interface, char *protocol, char *port)
140 {
141 char str[STRING_SIZE];
142
143 sprintf(str, "/sbin/iptables -A %sINPUT -i %s -p %s --dport %s -j ACCEPT", chain, interface, protocol, port);
144 executeCommand(str);
145 sprintf(str, "/sbin/iptables -A %sINPUT -i tun+ -j ACCEPT", chain);
146 executeCommand(str);
147 sprintf(str, "/sbin/iptables -A %sFORWARD -i tun+ -j ACCEPT", chain);
148 executeCommand(str);
149 }
150
151 void flushChain(char *chain) {
152 char str[STRING_SIZE];
153
154 sprintf(str, "/sbin/iptables -F %sINPUT", chain);
155 executeCommand(str);
156 sprintf(str, "/sbin/iptables -F %sFORWARD", chain);
157 executeCommand(str);
158 safe_system(str);
159 }
160
161 void deleteChainReference(char *chain) {
162 char str[STRING_SIZE];
163
164 sprintf(str, "/sbin/iptables -D INPUT -j %sINPUT", chain);
165 executeCommand(str);
166 safe_system(str);
167 sprintf(str, "/sbin/iptables -D FORWARD -j %sFORWARD", chain);
168 executeCommand(str);
169 safe_system(str);
170 }
171
172 void deleteChain(char *chain) {
173 char str[STRING_SIZE];
174
175 sprintf(str, "/sbin/iptables -X %sINPUT", chain);
176 executeCommand(str);
177 sprintf(str, "/sbin/iptables -X %sFORWARD", chain);
178 executeCommand(str);
179 }
180
181 void deleteAllChains(void) {
182 // not an elegant solution, but to avoid timing problems with undeleted chain references
183 deleteChainReference(OVPNRED);
184 deleteChainReference(OVPNBLUE);
185 deleteChainReference(OVPNORANGE);
186 flushChain(OVPNRED);
187 flushChain(OVPNBLUE);
188 flushChain(OVPNORANGE);
189 deleteChain(OVPNRED);
190 deleteChain(OVPNBLUE);
191 deleteChain(OVPNORANGE);
192 }
193
194 void createChainReference(char *chain) {
195 char str[STRING_SIZE];
196 sprintf(str, "/sbin/iptables -I INPUT %s -j %sINPUT", "14", chain);
197 executeCommand(str);
198 sprintf(str, "/sbin/iptables -I FORWARD %s -j %sFORWARD", "12", chain);
199 executeCommand(str);
200 }
201
202 void createChain(char *chain) {
203 char str[STRING_SIZE];
204 sprintf(str, "/sbin/iptables -N %sINPUT", chain);
205 executeCommand(str);
206 sprintf(str, "/sbin/iptables -N %sFORWARD", chain);
207 executeCommand(str);
208 }
209
210 void createAllChains(void) {
211 if (!((strcmp(enablered, "on")==0) || (strcmp(enableblue, "on")==0) || (strcmp(enableorange, "on")==0))){
212 fprintf(stderr, "OpenVPN is not enabled on any interface\n");
213 exit(1);
214 } else {
215 // create chain and chain references
216 if (!strcmp(enableorange, "on")) {
217 if (strlen(orangeif)) {
218 createChain(OVPNORANGE);
219 createChainReference(OVPNORANGE);
220 } else {
221 fprintf(stderr, "OpenVPN enabled on orange but no orange interface found\n");
222 //exit(1);
223 }
224 }
225
226 if (!strcmp(enableblue, "on")) {
227 if (strlen(blueif)) {
228 createChain(OVPNBLUE);
229 createChainReference(OVPNBLUE);
230 } else {
231 fprintf(stderr, "OpenVPN enabled on blue but no blue interface found\n");
232 //exit(1);
233 }
234 }
235
236 if (!strcmp(enablered, "on")) {
237 if (strlen(redif)) {
238 createChain(OVPNRED);
239 createChainReference(OVPNRED);
240 } else {
241 fprintf(stderr, "OpenVPN enabled on red but no red interface found\n");
242 //exit(1);
243 }
244 }
245 }
246 }
247
248 void setFirewallRules(void) {
249 char protocol[STRING_SIZE] = "";
250 char dport[STRING_SIZE] = "";
251 char dovpnip[STRING_SIZE] = "";
252
253 /* check if it makes sence to proceed further */
254 if (!((strcmp(enablered, "on")==0) || (strcmp(enableblue, "on")==0) || (strcmp(enableorange, "on")==0))){
255 fprintf(stderr, "Config error, at least one device must be enabled\n");
256 exit(1);
257 }
258
259 kv = initkeyvalues();
260 if (!readkeyvalues(kv, CONFIG_ROOT "/ovpn/settings"))
261 {
262 fprintf(stderr, "Cannot read ovpn settings\n");
263 exit(1);
264 }
265
266 /* we got one device, so lets proceed further */
267 if (!findkey(kv, "DDEST_PORT", dport)){
268 fprintf(stderr, "Cannot read DDEST_PORT\n");
269 exit(1);
270 }
271
272 if (!findkey(kv, "DPROTOCOL", protocol)){
273 fprintf(stderr, "Cannot read DPROTOCOL\n");
274 exit(1);
275 }
276
277 if (!findkey(kv, "VPN_IP", dovpnip)){
278 fprintf(stderr, "Cannot read VPN_IP\n");
279 // exit(1); step further as we don't need an ip
280 }
281 freekeyvalues(kv);
282
283 // set firewall rules
284 if (!strcmp(enablered, "on") && strlen(redif))
285 setChainRules(OVPNRED, redif, protocol, dport);
286 if (!strcmp(enableblue, "on") && strlen(blueif))
287 setChainRules(OVPNBLUE, blueif, protocol, dport);
288 if (!strcmp(enableorange, "on") && strlen(orangeif))
289 setChainRules(OVPNORANGE, orangeif, protocol, dport);
290 }
291
292 void stopDaemon(void) {
293 char command[STRING_SIZE];
294
295 snprintf(command, STRING_SIZE - 1, "/bin/killall openvpn");
296 executeCommand(command);
297 snprintf(command, STRING_SIZE - 1, "/bin/rm -f /var/run/openvpn.pid");
298 executeCommand(command);
299 snprintf(command, STRING_SIZE-1, "/sbin/modprobe -r tun");
300 executeCommand(command);
301 }
302
303 void startDaemon(void) {
304 char command[STRING_SIZE];
305
306 if (!((strcmp(enablered, "on")==0) || (strcmp(enableblue, "on")==0) || (strcmp(enableorange, "on")==0))){
307 fprintf(stderr, "OpenVPN is not enabled on any interface\n");
308 exit(1);
309 } else {
310 snprintf(command, STRING_SIZE-1, "/sbin/modprobe tun");
311 executeCommand(command);
312 snprintf(command, STRING_SIZE-1, "/usr/sbin/openvpn --config /var/ipfire/ovpn/server.conf");
313 executeCommand(command);
314 }
315 }
316
317 void displayopenvpn(void) {
318 char command[STRING_SIZE];
319
320 snprintf(command, STRING_SIZE - 1, "/bin/killall -sSIGUSR2 openvpn");
321 executeCommand(command);
322 }
323
324 int main(int argc, char *argv[]) {
325 if (!(initsetuid()))
326 exit(1);
327 if(argc < 2)
328 usage();
329
330 if(argc == 2) {
331 if( (strcmp(argv[1], "-k") == 0) || (strcmp(argv[1], "--kill") == 0) ) {
332 stopDaemon();
333 return 0;
334 }
335 else if( (strcmp(argv[1], "-d") == 0) || (strcmp(argv[1], "--display") == 0) ) {
336 displayopenvpn();
337 return 0;
338 }
339 else if( (strcmp(argv[1], "-dcr") == 0) || (strcmp(argv[1], "--delete-chains-and-rules") == 0) ) {
340 deleteAllChains();
341 return 0;
342 }
343 else {
344 ovpnInit();
345
346 if( (strcmp(argv[1], "-s") == 0) || (strcmp(argv[1], "--start") == 0) ) {
347 deleteAllChains();
348 createAllChains();
349 setFirewallRules();
350 startDaemon();
351 return 0;
352 }
353 else if( (strcmp(argv[1], "-sdo") == 0) || (strcmp(argv[1], "--start-daemon-only") == 0) ) {
354 startDaemon();
355 return 0;
356 }
357 else if( (strcmp(argv[1], "-r") == 0) || (strcmp(argv[1], "--restart") == 0) ) {
358 stopDaemon();
359 deleteAllChains();
360 createAllChains();
361 setFirewallRules();
362 startDaemon();
363 return 0;
364 }
365 else if( (strcmp(argv[1], "-fwr") == 0) || (strcmp(argv[1], "--firewall-rules") == 0) ) {
366 deleteAllChains();
367 createAllChains();
368 setFirewallRules();
369 return 0;
370 }
371 else if( (strcmp(argv[1], "-ccr") == 0) || (strcmp(argv[1], "--create-chains-and-rules") == 0) ) {
372 createAllChains();
373 setFirewallRules();
374 return 0;
375 }
376 else {
377 usage();
378 return 0;
379 }
380 }
381 }
382 else {
383 usage();
384 return 0;
385 }
386 return 0;
387 }
388