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.2";
30 struct connection_struct
{
31 char name
[STRING_SIZE
];
32 char type
[STRING_SIZE
];
33 char proto
[STRING_SIZE
];
34 char status
[STRING_SIZE
];
36 struct connection_struct
*next
;
39 typedef struct connection_struct connection
;
41 void exithandler(void)
52 printf("Wrapper for OpenVPN %s-debug\n", WRAPPERVERSION
);
54 printf("Wrapper for OpenVPN %s\n", WRAPPERVERSION
);
56 printf("openvpnctrl <option>\n");
57 printf(" Valid options are:\n");
58 printf(" -s --start\n");
59 printf(" starts OpenVPN (implicitly creates chains and firewall rules)\n");
60 printf(" -k --kill\n");
61 printf(" kills/stops OpenVPN\n");
62 printf(" -r --restart\n");
63 printf(" restarts OpenVPN (implicitly creates chains and firewall rules)\n");
64 printf(" -sn2n --start-net-2-net\n");
65 printf(" starts all net2net connections\n");
66 printf(" you may pass a connection name to the switch to only start a specific one\n");
67 printf(" -kn2n --kill-net-2-net\n");
68 printf(" kills all net2net connections\n");
69 printf(" you may pass a connection name to the switch to only start a specific one\n");
70 printf(" -d --display\n");
71 printf(" displays OpenVPN status to syslog\n");
72 printf(" -fwr --firewall-rules\n");
73 printf(" removes current OpenVPN chains and rules and resets them according to the config\n");
74 printf(" -sdo --start-daemon-only\n");
75 printf(" starts OpenVPN daemon only\n");
76 printf(" -ccr --create-chains-and-rules\n");
77 printf(" creates chains and rules for OpenVPN\n");
78 printf(" -dcr --delete-chains-and-rules\n");
79 printf(" removes all chains for OpenVPN\n");
83 connection
*getConnections() {
86 if (!(fp
= fopen(CONFIG_ROOT
"/ovpn/ovpnconfig", "r"))) {
87 fprintf(stderr
, "Could not open openvpn n2n configuration file.\n");
91 char line
[STRING_SIZE
] = "";
92 char result
[STRING_SIZE
] = "";
95 connection
*conn_first
= NULL
;
96 connection
*conn_last
= NULL
;
97 connection
*conn_curr
;
99 while ((fgets(line
, STRING_SIZE
, fp
) != NULL
)) {
100 if (line
[strlen(line
) - 1] == '\n')
101 line
[strlen(line
) - 1] = '\0';
103 conn_curr
= (connection
*)malloc(sizeof(connection
));
104 memset(conn_curr
, 0, sizeof(connection
));
106 if (conn_first
== NULL
) {
107 conn_first
= conn_curr
;
109 conn_last
->next
= conn_curr
;
111 conn_last
= conn_curr
;
114 char *lineptr
= &line
;
116 if (*lineptr
== NULL
)
120 while (*lineptr
!= NULL
) {
121 if (*lineptr
== ',') {
125 *resultptr
++ = *lineptr
++;
130 strcpy(conn_curr
->status
, result
);
131 } else if (count
== 2) {
132 strcpy(conn_curr
->name
, result
);
133 } else if (count
== 4) {
134 strcpy(conn_curr
->type
, result
);
135 } else if (count
== 29) {
136 strcpy(conn_curr
->proto
, result
);
137 } else if (count
== 30) {
138 conn_curr
->port
= atoi(result
);
150 int readPidFile(const char *pidfile
) {
151 FILE *fp
= fopen(pidfile
, "r");
153 fprintf(stderr
, "PID file not found: '%s'\n", pidfile
);
158 fscanf(fp
, "%d", &pid
);
164 void ovpnInit(void) {
166 // Read OpenVPN configuration
167 kv
= initkeyvalues();
168 if (!readkeyvalues(kv
, CONFIG_ROOT
"/ovpn/settings")) {
169 fprintf(stderr
, "Cannot read ovpn settings\n");
173 if (!findkey(kv
, "ENABLED", enablered
)) {
174 fprintf(stderr
, "Cannot read ENABLED\n");
178 if (!findkey(kv
, "ENABLED_BLUE", enableblue
)){
179 fprintf(stderr
, "Cannot read ENABLED_BLUE\n");
183 if (!findkey(kv
, "ENABLED_ORANGE", enableorange
)){
184 fprintf(stderr
, "Cannot read ENABLED_ORANGE\n");
189 // read interface settings
191 // details for the red int
192 memset(redif
, 0, STRING_SIZE
);
193 if ((ifacefile
= fopen(CONFIG_ROOT
"/red/iface", "r")))
195 if (fgets(redif
, STRING_SIZE
, ifacefile
))
197 if (redif
[strlen(redif
) - 1] == '\n')
198 redif
[strlen(redif
) - 1] = '\0';
203 if (!VALID_DEVICE(redif
))
205 memset(redif
, 0, STRING_SIZE
);
210 if (!readkeyvalues(kv
, CONFIG_ROOT
"/ethernet/settings"))
212 fprintf(stderr
, "Cannot read ethernet settings\n");
216 if (strcmp(enableblue
, "on")==0){
217 if (!findkey(kv
, "BLUE_DEV", blueif
)){
218 fprintf(stderr
, "Cannot read BLUE_DEV\n");
222 if (strcmp(enableorange
, "on")==0){
223 if (!findkey(kv
, "ORANGE_DEV", orangeif
)){
224 fprintf(stderr
, "Cannot read ORNAGE_DEV\n");
231 void executeCommand(char *command
) {
233 printf(strncat(command
, "\n", 2));
235 safe_system(strncat(command
, " >/dev/null 2>&1", 17));
238 void setChainRules(char *chain
, char *interface
, char *protocol
, char *port
)
240 char str
[STRING_SIZE
];
242 sprintf(str
, "/sbin/iptables -A %sINPUT -i %s -p %s --dport %s -j ACCEPT", chain
, interface
, protocol
, port
);
244 sprintf(str
, "/sbin/iptables -A %sINPUT -i tun+ -j ACCEPT", chain
);
246 sprintf(str
, "/sbin/iptables -A %sFORWARD -i tun+ -j ACCEPT", chain
);
250 void flushChain(char *chain
) {
251 char str
[STRING_SIZE
];
253 sprintf(str
, "/sbin/iptables -F %sINPUT", chain
);
255 sprintf(str
, "/sbin/iptables -F %sFORWARD", chain
);
260 void deleteChainReference(char *chain
) {
261 char str
[STRING_SIZE
];
263 sprintf(str
, "/sbin/iptables -D INPUT -j %sINPUT", chain
);
266 sprintf(str
, "/sbin/iptables -D FORWARD -j %sFORWARD", chain
);
271 void deleteChain(char *chain
) {
272 char str
[STRING_SIZE
];
274 sprintf(str
, "/sbin/iptables -X %sINPUT", chain
);
276 sprintf(str
, "/sbin/iptables -X %sFORWARD", chain
);
280 void deleteAllChains(void) {
281 // not an elegant solution, but to avoid timing problems with undeleted chain references
282 deleteChainReference(OVPNRED
);
283 deleteChainReference(OVPNBLUE
);
284 deleteChainReference(OVPNORANGE
);
286 flushChain(OVPNBLUE
);
287 flushChain(OVPNORANGE
);
288 deleteChain(OVPNRED
);
289 deleteChain(OVPNBLUE
);
290 deleteChain(OVPNORANGE
);
293 void createChainReference(char *chain
) {
294 char str
[STRING_SIZE
];
295 sprintf(str
, "/sbin/iptables -I INPUT %s -j %sINPUT", "14", chain
);
297 sprintf(str
, "/sbin/iptables -I FORWARD %s -j %sFORWARD", "12", chain
);
301 void createChain(char *chain
) {
302 char str
[STRING_SIZE
];
303 sprintf(str
, "/sbin/iptables -N %sINPUT", chain
);
305 sprintf(str
, "/sbin/iptables -N %sFORWARD", chain
);
309 void createAllChains(void) {
310 // create chain and chain references
311 if (!strcmp(enableorange
, "on")) {
312 if (strlen(orangeif
)) {
313 createChain(OVPNORANGE
);
314 createChainReference(OVPNORANGE
);
316 fprintf(stderr
, "OpenVPN enabled on orange but no orange interface found\n");
321 if (!strcmp(enableblue
, "on")) {
322 if (strlen(blueif
)) {
323 createChain(OVPNBLUE
);
324 createChainReference(OVPNBLUE
);
326 fprintf(stderr
, "OpenVPN enabled on blue but no blue interface found\n");
331 if (!strcmp(enablered
, "on")) {
333 createChain(OVPNRED
);
334 createChainReference(OVPNRED
);
336 fprintf(stderr
, "OpenVPN enabled on red but no red interface found\n");
342 void setFirewallRules(void) {
343 char protocol
[STRING_SIZE
] = "";
344 char dport
[STRING_SIZE
] = "";
345 char dovpnip
[STRING_SIZE
] = "";
347 kv
= initkeyvalues();
348 if (!readkeyvalues(kv
, CONFIG_ROOT
"/ovpn/settings"))
350 fprintf(stderr
, "Cannot read ovpn settings\n");
354 /* we got one device, so lets proceed further */
355 if (!findkey(kv
, "DDEST_PORT", dport
)){
356 fprintf(stderr
, "Cannot read DDEST_PORT\n");
360 if (!findkey(kv
, "DPROTOCOL", protocol
)){
361 fprintf(stderr
, "Cannot read DPROTOCOL\n");
365 if (!findkey(kv
, "VPN_IP", dovpnip
)){
366 fprintf(stderr
, "Cannot read VPN_IP\n");
367 // exit(1); step further as we don't need an ip
373 flushChain(OVPNBLUE
);
374 flushChain(OVPNORANGE
);
376 // set firewall rules
377 if (!strcmp(enablered
, "on") && strlen(redif
))
378 setChainRules(OVPNRED
, redif
, protocol
, dport
);
379 if (!strcmp(enableblue
, "on") && strlen(blueif
))
380 setChainRules(OVPNBLUE
, blueif
, protocol
, dport
);
381 if (!strcmp(enableorange
, "on") && strlen(orangeif
))
382 setChainRules(OVPNORANGE
, orangeif
, protocol
, dport
);
384 // read connection configuration
385 connection
*conn
= getConnections();
387 // set firewall rules for n2n connections
388 char command
[STRING_SIZE
];
389 while (conn
!= NULL
) {
390 if (strcmp(conn
->type
, "net") == 0) {
391 sprintf(command
, "/sbin/iptables -A %sINPUT -i %s -p %s --dport %d -j ACCEPT",
392 OVPNRED
, redif
, conn
->proto
, conn
->port
);
393 executeCommand(command
);
400 void stopDaemon(void) {
401 char command
[STRING_SIZE
];
403 int pid
= readPidFile("/var/run/openvpn.pid");
408 fprintf(stderr
, "Killing PID %d.\n", pid
);
411 snprintf(command
, STRING_SIZE
- 1, "/bin/rm -f /var/run/openvpn.pid");
412 executeCommand(command
);
415 void startDaemon(void) {
416 char command
[STRING_SIZE
];
418 if (!((strcmp(enablered
, "on")==0) || (strcmp(enableblue
, "on")==0) || (strcmp(enableorange
, "on")==0))){
419 fprintf(stderr
, "OpenVPN is not enabled on any interface\n");
422 snprintf(command
, STRING_SIZE
-1, "/sbin/modprobe tun");
423 executeCommand(command
);
424 snprintf(command
, STRING_SIZE
-1, "/usr/sbin/openvpn --config /var/ipfire/ovpn/server.conf");
425 executeCommand(command
);
429 int startNet2Net(char *name
) {
430 connection
*conn
= NULL
;
431 connection
*conn_iter
;
433 conn_iter
= getConnections();
436 if ((strcmp(conn_iter
->type
, "net") == 0) && (strcmp(conn_iter
->name
, name
) == 0)) {
440 conn_iter
= conn_iter
->next
;
444 fprintf(stderr
, "Connection not found.\n");
448 if (strcmp(conn
->status
, "on") != 0) {
449 fprintf(stderr
, "Connection '%s' is not enabled.\n", conn
->name
);
453 fprintf(stderr
, "Starting connection %s...\n", conn
->name
);
455 char configfile
[STRING_SIZE
];
456 snprintf(configfile
, STRING_SIZE
- 1, CONFIG_ROOT
"/ovpn/n2nconf/%s/%s.conf",
457 conn
->name
, conn
->name
);
459 FILE *fp
= fopen(configfile
, "r");
461 fprintf(stderr
, "Could not find configuration file for connection '%s' at '%s'.\n",
462 conn
->name
, configfile
);
467 // Make sure all firewall rules are up to date.
470 char command
[STRING_SIZE
];
471 snprintf(command
, STRING_SIZE
-1, "/sbin/modprobe tun");
472 executeCommand(command
);
473 snprintf(command
, STRING_SIZE
-1, "/usr/sbin/openvpn --config %s", configfile
);
474 executeCommand(command
);
479 int killNet2Net(char *name
) {
480 connection
*conn
= NULL
;
481 connection
*conn_iter
;
483 conn_iter
= getConnections();
486 if (strcmp(conn_iter
->name
, name
) == 0) {
490 conn_iter
= conn_iter
->next
;
494 fprintf(stderr
, "Connection not found.\n");
498 char pidfile
[STRING_SIZE
];
499 snprintf(pidfile
, STRING_SIZE
- 1, "/var/run/%sn2n.pid", conn
->name
);
501 int pid
= readPidFile(pidfile
);
503 fprintf(stderr
, "Could not read pid file of connection %s.", conn
->name
);
507 fprintf(stderr
, "Killing connection %s (PID %d)...\n", conn
->name
, pid
);
510 char command
[STRING_SIZE
];
511 snprintf(command
, STRING_SIZE
- 1, "/bin/rm -f %s", pidfile
);
512 executeCommand(command
);
517 void startAllNet2Net() {
518 int exitcode
= 0, _exitcode
= 0;
520 connection
*conn
= getConnections();
523 /* Skip all connections that are not of type "net" or disabled. */
524 if ((strcmp(conn
->type
, "net") != 0) || (strcmp(conn
->status
, "on") != 0)) {
529 _exitcode
= startNet2Net(conn
->name
);
532 if (_exitcode
> exitcode
) {
533 exitcode
= _exitcode
;
540 void killAllNet2Net() {
541 int exitcode
= 0, _exitcode
= 0;
543 connection
*conn
= getConnections();
546 /* Skip all connections that are not of type "net". */
547 if (strcmp(conn
->type
, "net") != 0) {
552 _exitcode
= killNet2Net(conn
->name
);
555 if (_exitcode
> exitcode
) {
556 exitcode
= _exitcode
;
563 void displayopenvpn(void) {
564 char command
[STRING_SIZE
];
566 snprintf(command
, STRING_SIZE
- 1, "/bin/killall -sSIGUSR2 openvpn");
567 executeCommand(command
);
570 int main(int argc
, char *argv
[]) {
579 if( (strcmp(argv
[1], "-sn2n") == 0) || (strcmp(argv
[1], "--start-net-2-net") == 0) ) {
580 startNet2Net(argv
[2]);
583 else if( (strcmp(argv
[1], "-kn2n") == 0) || (strcmp(argv
[1], "--kill-net-2-net") == 0) ) {
584 killNet2Net(argv
[2]);
592 if( (strcmp(argv
[1], "-k") == 0) || (strcmp(argv
[1], "--kill") == 0) ) {
596 else if( (strcmp(argv
[1], "-d") == 0) || (strcmp(argv
[1], "--display") == 0) ) {
600 else if( (strcmp(argv
[1], "-dcr") == 0) || (strcmp(argv
[1], "--delete-chains-and-rules") == 0) ) {
607 if( (strcmp(argv
[1], "-s") == 0) || (strcmp(argv
[1], "--start") == 0) ) {
614 else if( (strcmp(argv
[1], "-sn2n") == 0) || (strcmp(argv
[1], "--start-net-2-net") == 0) ) {
618 else if( (strcmp(argv
[1], "-kn2n") == 0) || (strcmp(argv
[1], "--kill-net-2-net") == 0) ) {
622 else if( (strcmp(argv
[1], "-sdo") == 0) || (strcmp(argv
[1], "--start-daemon-only") == 0) ) {
626 else if( (strcmp(argv
[1], "-r") == 0) || (strcmp(argv
[1], "--restart") == 0) ) {
634 else if( (strcmp(argv
[1], "-fwr") == 0) || (strcmp(argv
[1], "--firewall-rules") == 0) ) {
640 else if( (strcmp(argv
[1], "-ccr") == 0) || (strcmp(argv
[1], "--create-chains-and-rules") == 0) ) {