14 struct keyvalue
*kv
= NULL
;
15 FILE *ifacefile
= NULL
;
17 char redif
[STRING_SIZE
];
18 char blueif
[STRING_SIZE
];
19 char orangeif
[STRING_SIZE
];
20 char enablered
[STRING_SIZE
] = "off";
21 char enableblue
[STRING_SIZE
] = "off";
22 char enableorange
[STRING_SIZE
] = "off";
25 char OVPNRED
[STRING_SIZE
] = "OVPN";
26 char OVPNBLUE
[STRING_SIZE
] = "OVPN_BLUE_";
27 char OVPNORANGE
[STRING_SIZE
] = "OVPN_ORANGE_";
28 char WRAPPERVERSION
[STRING_SIZE
] = "ipfire-2.2.0";
30 struct connection_struct
{
31 char name
[STRING_SIZE
];
32 char type
[STRING_SIZE
];
33 char proto
[STRING_SIZE
];
35 struct connection_struct
*next
;
38 typedef struct connection_struct connection
;
40 void exithandler(void)
51 printf("Wrapper for OpenVPN %s-debug\n", WRAPPERVERSION
);
53 printf("Wrapper for OpenVPN %s\n", WRAPPERVERSION
);
55 printf("openvpnctrl <option>\n");
56 printf(" Valid options are:\n");
57 printf(" -s --start\n");
58 printf(" starts OpenVPN (implicitly creates chains and firewall rules)\n");
59 printf(" -k --kill\n");
60 printf(" kills/stops OpenVPN\n");
61 printf(" -r --restart\n");
62 printf(" restarts OpenVPN (implicitly creates chains and firewall rules)\n");
63 printf(" -sn2n --start-net-2-net\n");
64 printf(" starts all net2net connections\n");
65 printf(" you may pass a connection name to the switch to only start a specific one\n");
66 printf(" -kn2n --kill-net-2-net\n");
67 printf(" kills all net2net connections\n");
68 printf(" you may pass a connection name to the switch to only start a specific one\n");
69 printf(" -d --display\n");
70 printf(" displays OpenVPN status to syslog\n");
71 printf(" -fwr --firewall-rules\n");
72 printf(" removes current OpenVPN chains and rules and resets them according to the config\n");
73 printf(" -sdo --start-daemon-only\n");
74 printf(" starts OpenVPN daemon only\n");
75 printf(" -ccr --create-chains-and-rules\n");
76 printf(" creates chains and rules for OpenVPN\n");
77 printf(" -dcr --delete-chains-and-rules\n");
78 printf(" removes all chains for OpenVPN\n");
82 connection
*getConnections() {
85 if (!(fp
= fopen(CONFIG_ROOT
"/ovpn/ovpnconfig", "r"))) {
86 fprintf(stderr
, "Could not open openvpn n2n configuration file.\n");
90 char line
[STRING_SIZE
] = "";
93 connection
*conn_first
= NULL
;
94 connection
*conn_last
= NULL
;
95 connection
*conn_curr
;
97 while ((fgets(line
, STRING_SIZE
, fp
) != NULL
)) {
98 if (line
[strlen(line
) - 1] == '\n')
99 line
[strlen(line
) - 1] = '\0';
101 conn_curr
= (connection
*)malloc(sizeof(connection
));
102 memset(conn_curr
, 0, sizeof(connection
));
104 if (conn_first
== NULL
) {
105 conn_first
= conn_curr
;
107 conn_last
->next
= conn_curr
;
109 conn_last
= conn_curr
;
112 result
= strtok(line
, ",");
115 strcpy(conn_curr
->name
, result
);
116 } else if (count
== 4) {
117 strcpy(conn_curr
->type
, result
);
118 } else if (count
== 12) {
119 strcpy(conn_curr
->proto
, result
);
120 } else if (count
== 13) {
121 conn_curr
->port
= atoi(result
);
124 result
= strtok(NULL
, ",");
134 int readPidFile(const char *pidfile
) {
135 FILE *fp
= fopen(pidfile
, "r");
137 fprintf(stderr
, "PID file not found: '%s'\n", pidfile
);
142 fscanf(fp
, "%d", &pid
);
148 void ovpnInit(void) {
150 // Read OpenVPN configuration
151 kv
= initkeyvalues();
152 if (!readkeyvalues(kv
, CONFIG_ROOT
"/ovpn/settings")) {
153 fprintf(stderr
, "Cannot read ovpn settings\n");
157 if (!findkey(kv
, "ENABLED", enablered
)) {
158 fprintf(stderr
, "Cannot read ENABLED\n");
162 if (!findkey(kv
, "ENABLED_BLUE", enableblue
)){
163 fprintf(stderr
, "Cannot read ENABLED_BLUE\n");
167 if (!findkey(kv
, "ENABLED_ORANGE", enableorange
)){
168 fprintf(stderr
, "Cannot read ENABLED_ORANGE\n");
173 // read interface settings
175 // details for the red int
176 memset(redif
, 0, STRING_SIZE
);
177 if ((ifacefile
= fopen(CONFIG_ROOT
"/red/iface", "r")))
179 if (fgets(redif
, STRING_SIZE
, ifacefile
))
181 if (redif
[strlen(redif
) - 1] == '\n')
182 redif
[strlen(redif
) - 1] = '\0';
187 if (!VALID_DEVICE(redif
))
189 memset(redif
, 0, STRING_SIZE
);
194 if (!readkeyvalues(kv
, CONFIG_ROOT
"/ethernet/settings"))
196 fprintf(stderr
, "Cannot read ethernet settings\n");
200 if (strcmp(enableblue
, "on")==0){
201 if (!findkey(kv
, "BLUE_DEV", blueif
)){
202 fprintf(stderr
, "Cannot read BLUE_DEV\n");
206 if (strcmp(enableorange
, "on")==0){
207 if (!findkey(kv
, "ORANGE_DEV", orangeif
)){
208 fprintf(stderr
, "Cannot read ORNAGE_DEV\n");
215 void executeCommand(char *command
) {
217 printf(strncat(command
, "\n", 2));
219 safe_system(strncat(command
, " >/dev/null 2>&1", 17));
222 void setChainRules(char *chain
, char *interface
, char *protocol
, char *port
)
224 char str
[STRING_SIZE
];
226 sprintf(str
, "/sbin/iptables -A %sINPUT -i %s -p %s --dport %s -j ACCEPT", chain
, interface
, protocol
, port
);
228 sprintf(str
, "/sbin/iptables -A %sINPUT -i tun+ -j ACCEPT", chain
);
230 sprintf(str
, "/sbin/iptables -A %sFORWARD -i tun+ -j ACCEPT", chain
);
234 void flushChain(char *chain
) {
235 char str
[STRING_SIZE
];
237 sprintf(str
, "/sbin/iptables -F %sINPUT", chain
);
239 sprintf(str
, "/sbin/iptables -F %sFORWARD", chain
);
244 void deleteChainReference(char *chain
) {
245 char str
[STRING_SIZE
];
247 sprintf(str
, "/sbin/iptables -D INPUT -j %sINPUT", chain
);
250 sprintf(str
, "/sbin/iptables -D FORWARD -j %sFORWARD", chain
);
255 void deleteChain(char *chain
) {
256 char str
[STRING_SIZE
];
258 sprintf(str
, "/sbin/iptables -X %sINPUT", chain
);
260 sprintf(str
, "/sbin/iptables -X %sFORWARD", chain
);
264 void deleteAllChains(void) {
265 // not an elegant solution, but to avoid timing problems with undeleted chain references
266 deleteChainReference(OVPNRED
);
267 deleteChainReference(OVPNBLUE
);
268 deleteChainReference(OVPNORANGE
);
270 flushChain(OVPNBLUE
);
271 flushChain(OVPNORANGE
);
272 deleteChain(OVPNRED
);
273 deleteChain(OVPNBLUE
);
274 deleteChain(OVPNORANGE
);
277 void createChainReference(char *chain
) {
278 char str
[STRING_SIZE
];
279 sprintf(str
, "/sbin/iptables -I INPUT %s -j %sINPUT", "14", chain
);
281 sprintf(str
, "/sbin/iptables -I FORWARD %s -j %sFORWARD", "12", chain
);
285 void createChain(char *chain
) {
286 char str
[STRING_SIZE
];
287 sprintf(str
, "/sbin/iptables -N %sINPUT", chain
);
289 sprintf(str
, "/sbin/iptables -N %sFORWARD", chain
);
293 void createAllChains(void) {
294 // create chain and chain references
295 if (!strcmp(enableorange
, "on")) {
296 if (strlen(orangeif
)) {
297 createChain(OVPNORANGE
);
298 createChainReference(OVPNORANGE
);
300 fprintf(stderr
, "OpenVPN enabled on orange but no orange interface found\n");
305 if (!strcmp(enableblue
, "on")) {
306 if (strlen(blueif
)) {
307 createChain(OVPNBLUE
);
308 createChainReference(OVPNBLUE
);
310 fprintf(stderr
, "OpenVPN enabled on blue but no blue interface found\n");
315 if (!strcmp(enablered
, "on")) {
317 createChain(OVPNRED
);
318 createChainReference(OVPNRED
);
320 fprintf(stderr
, "OpenVPN enabled on red but no red interface found\n");
326 void setFirewallRules(void) {
327 char protocol
[STRING_SIZE
] = "";
328 char dport
[STRING_SIZE
] = "";
329 char dovpnip
[STRING_SIZE
] = "";
331 kv
= initkeyvalues();
332 if (!readkeyvalues(kv
, CONFIG_ROOT
"/ovpn/settings"))
334 fprintf(stderr
, "Cannot read ovpn settings\n");
338 /* we got one device, so lets proceed further */
339 if (!findkey(kv
, "DDEST_PORT", dport
)){
340 fprintf(stderr
, "Cannot read DDEST_PORT\n");
344 if (!findkey(kv
, "DPROTOCOL", protocol
)){
345 fprintf(stderr
, "Cannot read DPROTOCOL\n");
349 if (!findkey(kv
, "VPN_IP", dovpnip
)){
350 fprintf(stderr
, "Cannot read VPN_IP\n");
351 // exit(1); step further as we don't need an ip
357 flushChain(OVPNBLUE
);
358 flushChain(OVPNORANGE
);
360 // set firewall rules
361 if (!strcmp(enablered
, "on") && strlen(redif
))
362 setChainRules(OVPNRED
, redif
, protocol
, dport
);
363 if (!strcmp(enableblue
, "on") && strlen(blueif
))
364 setChainRules(OVPNBLUE
, blueif
, protocol
, dport
);
365 if (!strcmp(enableorange
, "on") && strlen(orangeif
))
366 setChainRules(OVPNORANGE
, orangeif
, protocol
, dport
);
368 // read connection configuration
369 connection
*conn
= getConnections();
371 // set firewall rules for n2n connections
372 char command
[STRING_SIZE
];
373 while (conn
!= NULL
) {
374 if (strcmp(conn
->type
, "net") == 0) {
375 sprintf(command
, "/sbin/iptables -A %sINPUT -i %s -p %s --dport %d -j ACCEPT",
376 OVPNRED
, redif
, conn
->proto
, conn
->port
);
377 executeCommand(command
);
384 void stopDaemon(void) {
385 char command
[STRING_SIZE
];
387 int pid
= readPidFile("/var/run/openvpn.pid");
392 fprintf(stderr
, "Killing PID %d.\n", pid
);
395 snprintf(command
, STRING_SIZE
- 1, "/bin/rm -f /var/run/openvpn.pid");
396 executeCommand(command
);
399 void startDaemon(void) {
400 char command
[STRING_SIZE
];
402 if (!((strcmp(enablered
, "on")==0) || (strcmp(enableblue
, "on")==0) || (strcmp(enableorange
, "on")==0))){
403 fprintf(stderr
, "OpenVPN is not enabled on any interface\n");
406 snprintf(command
, STRING_SIZE
-1, "/sbin/modprobe tun");
407 executeCommand(command
);
408 snprintf(command
, STRING_SIZE
-1, "/usr/sbin/openvpn --config /var/ipfire/ovpn/server.conf");
409 executeCommand(command
);
413 void startNet2Net(char *name
) {
414 connection
*conn
= NULL
;
415 connection
*conn_iter
;
417 conn_iter
= getConnections();
420 if ((strcmp(conn_iter
->type
, "net") == 0) && (strcmp(conn_iter
->name
, name
) == 0)) {
424 conn_iter
= conn_iter
->next
;
428 fprintf(stderr
, "Connection not found.\n");
432 char configfile
[STRING_SIZE
];
433 snprintf(configfile
, STRING_SIZE
- 1, CONFIG_ROOT
"/ovpn/n2nconf/%s/%s.conf",
434 conn
->name
, conn
->name
);
436 FILE *fp
= fopen(configfile
, "r");
438 fprintf(stderr
, "Could not find configuration file for connection '%s' at '%s'.\n",
439 conn
->name
, configfile
);
444 // Make sure all firewall rules are up to date.
447 char command
[STRING_SIZE
];
448 snprintf(command
, STRING_SIZE
-1, "/sbin/modprobe tun");
449 executeCommand(command
);
450 snprintf(command
, STRING_SIZE
-1, "/usr/sbin/openvpn --config %s", configfile
);
451 executeCommand(command
);
454 void killNet2Net(char *name
) {
455 connection
*conn
= NULL
;
456 connection
*conn_iter
;
458 conn_iter
= getConnections();
461 if (strcmp(conn_iter
->name
, name
) == 0) {
465 conn_iter
= conn_iter
->next
;
469 fprintf(stderr
, "Connection not found.\n");
473 char pidfile
[STRING_SIZE
];
474 snprintf(pidfile
, STRING_SIZE
- 1, "/var/run/%sn2n.pid", conn
->name
);
476 int pid
= readPidFile(pidfile
);
481 fprintf(stderr
, "Killing PID %d.\n", pid
);
484 char command
[STRING_SIZE
];
485 snprintf(command
, STRING_SIZE
- 1, "/bin/rm -f %s", pidfile
);
486 executeCommand(command
);
491 void startAllNet2Net() {
492 connection
*conn
= getConnections();
495 startNet2Net(conn
->name
);
502 void killAllNet2Net() {
503 connection
*conn
= getConnections();
506 killNet2Net(conn
->name
);
513 void displayopenvpn(void) {
514 char command
[STRING_SIZE
];
516 snprintf(command
, STRING_SIZE
- 1, "/bin/killall -sSIGUSR2 openvpn");
517 executeCommand(command
);
520 int main(int argc
, char *argv
[]) {
529 if( (strcmp(argv
[1], "-sn2n") == 0) || (strcmp(argv
[1], "--start-net-2-net") == 0) ) {
530 startNet2Net(argv
[2]);
533 else if( (strcmp(argv
[1], "-kn2n") == 0) || (strcmp(argv
[1], "--kill-net-2-net") == 0) ) {
534 killNet2Net(argv
[2]);
542 if( (strcmp(argv
[1], "-k") == 0) || (strcmp(argv
[1], "--kill") == 0) ) {
546 else if( (strcmp(argv
[1], "-d") == 0) || (strcmp(argv
[1], "--display") == 0) ) {
550 else if( (strcmp(argv
[1], "-dcr") == 0) || (strcmp(argv
[1], "--delete-chains-and-rules") == 0) ) {
557 if( (strcmp(argv
[1], "-s") == 0) || (strcmp(argv
[1], "--start") == 0) ) {
564 else if( (strcmp(argv
[1], "-sn2n") == 0) || (strcmp(argv
[1], "--start-net-2-net") == 0) ) {
568 else if( (strcmp(argv
[1], "-kn2n") == 0) || (strcmp(argv
[1], "--kill-net-2-net") == 0) ) {
572 else if( (strcmp(argv
[1], "-sdo") == 0) || (strcmp(argv
[1], "--start-daemon-only") == 0) ) {
576 else if( (strcmp(argv
[1], "-r") == 0) || (strcmp(argv
[1], "--restart") == 0) ) {
584 else if( (strcmp(argv
[1], "-fwr") == 0) || (strcmp(argv
[1], "--firewall-rules") == 0) ) {
590 else if( (strcmp(argv
[1], "-ccr") == 0) || (strcmp(argv
[1], "--create-chains-and-rules") == 0) ) {