+#define _XOPEN_SOURCE 500
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <fcntl.h>
+#include <ftw.h>
#include "setuid.h"
#include "netutil.h"
#include "libsmooth.h"
typedef struct connection_struct connection;
+static int recursive_remove_callback(const char* fpath, const struct stat* sb, int typeflag, struct FTW* ftwbuf) {
+ int rv = remove(fpath);
+ if (rv)
+ perror(fpath);
+
+ return rv;
+}
+
+static int recursive_remove(const char* path) {
+ return nftw(path, recursive_remove_callback, 64, FTW_DEPTH | FTW_PHYS);
+}
+
void exithandler(void)
{
if(kv)
printf(" -kn2n --kill-net-2-net\n");
printf(" kills all net2net connections\n");
printf(" you may pass a connection name to the switch to only start a specific one\n");
+ printf(" -drrd --delete-rrd\n");
+ printf(" Deletes the RRD data for a specific client\n");
+ printf(" you need to pass a connection name (RW) to the switch to delete the directory (case sensitive)\n");
printf(" -d --display\n");
printf(" displays OpenVPN status to syslog\n");
printf(" -fwr --firewall-rules\n");
return pid;
}
+int readExternalAddress(char* address) {
+ FILE *fp = fopen("/var/ipfire/red/local-ipaddress", "r");
+ if (!fp)
+ goto ERROR;
+
+ int r = fscanf(fp, "%s", address);
+ fclose(fp);
+
+ if (r < 0)
+ goto ERROR;
+
+ /* In case the read IP address is not valid, we empty
+ * the content of address and return non-zero. */
+ if (!VALID_IP(address))
+ goto ERROR;
+
+ return 0;
+
+ERROR:
+ address = NULL;
+ return 1;
+}
+
void ovpnInit(void) {
// Read OpenVPN configuration
kv = initkeyvalues();
fprintf(stderr, "Cannot read ethernet settings\n");
exit(1);
}
-
+
if (strcmp(enableblue, "on") == 0) {
if (!findkey(kv, "BLUE_DEV", blueif)) {
exit(1);
}
void setFirewallRules(void) {
+ char command[STRING_SIZE];
char protocol[STRING_SIZE] = "";
char dport[STRING_SIZE] = "";
char dovpnip[STRING_SIZE] = "";
exit(1);
}
- /* we got one device, so lets proceed further */
+ /* we got one device, so lets proceed further */
if (!findkey(kv, "DDEST_PORT", dport)){
fprintf(stderr, "Cannot read DDEST_PORT\n");
exit(1);
if (!strcmp(enableorange, "on") && strlen(orangeif))
addRule(OVPNINPUT, orangeif, protocol, dport);
+ /* Allow ICMP error messages to pass. */
+ snprintf(command, STRING_SIZE - 1, "/sbin/iptables -A %s -p icmp"
+ " -m conntrack --ctstate RELATED -j RETURN", OVPNBLOCK);
+ executeCommand(command);
+
// read connection configuration
connection *conn = getConnections();
// set firewall rules for n2n connections
- char command[STRING_SIZE];
char *local_subnet_address = NULL;
char *transfer_subnet_address = NULL;
while (conn != NULL) {
void startDaemon(void) {
char command[STRING_SIZE];
-
+
if (!((strcmp(enablered, "on") == 0) || (strcmp(enableblue, "on") == 0) || (strcmp(enableorange, "on") == 0))) {
fprintf(stderr, "OpenVPN is not enabled on any interface\n");
exit(1);
executeCommand(command);
snprintf(command, STRING_SIZE-1, "/usr/sbin/openvpn --config /var/ipfire/ovpn/server.conf");
executeCommand(command);
+ snprintf(command, STRING_SIZE-1, "/bin/chown root.nobody /var/run/ovpnserver.log");
+ executeCommand(command);
+ snprintf(command, STRING_SIZE-1, "/bin/chmod 644 /var/run/ovpnserver.log");
+ executeCommand(command);
}
}
// Make sure all firewall rules are up to date.
setFirewallRules();
+ // Get the external IP address.
+ char address[STRING_SIZE] = "";
+ int r = readExternalAddress(address);
+ if (r) {
+ fprintf(stderr, "Could not read the external address\n");
+ exit(1);
+ }
+
char command[STRING_SIZE];
snprintf(command, STRING_SIZE-1, "/sbin/modprobe tun");
executeCommand(command);
- snprintf(command, STRING_SIZE-1, "/usr/sbin/openvpn --config %s", configfile);
+ snprintf(command, STRING_SIZE-1, "/usr/sbin/openvpn --local %s --config %s", address, configfile);
executeCommand(command);
return 0;
int killNet2Net(char *name) {
connection *conn = NULL;
connection *conn_iter;
+ int rc = 0;
conn_iter = getConnections();
snprintf(command, STRING_SIZE - 1, "/bin/rm -f %s", pidfile);
executeCommand(command);
+ char runfile[STRING_SIZE];
+ snprintf(runfile, STRING_SIZE - 1, "/var/run/openvpn/%s-n2n", conn->name);
+ rc = recursive_remove(runfile);
+ if (rc)
+ perror(runfile);
+
return 0;
}
+int deleterrd(char *name) {
+ char rrd_dir[STRING_SIZE];
+
+ connection *conn = getConnections();
+ while(conn) {
+ if (strcmp(conn->name, name) != 0) {
+ conn = conn->next;
+ continue;
+ }
+
+ // Handle RW connections
+ if (strcmp(conn->type, "host") == 0) {
+ snprintf(rrd_dir, STRING_SIZE - 1, "/var/log/rrd/collectd/localhost/openvpn-%s/", name);
+
+ // Handle N2N connections
+ } else if (strcmp(conn->type, "net") == 0) {
+ snprintf(rrd_dir, STRING_SIZE - 1, "/var/log/rrd/collectd/localhost/openvpn-%s-n2n/", name);
+
+ // Unhandled connection type
+ } else {
+ conn = conn->next;
+ continue;
+ }
+
+ return recursive_remove(rrd_dir);
+ }
+
+ return 1;
+}
+
void startAllNet2Net() {
int exitcode = 0, _exitcode = 0;
else if( (strcmp(argv[1], "-kn2n") == 0) || (strcmp(argv[1], "--kill-net-2-net") == 0) ) {
killNet2Net(argv[2]);
return 0;
+ }
+ else if( (strcmp(argv[1], "-drrd") == 0) || (strcmp(argv[1], "--delete-rrd") == 0) ) {
+ deleterrd(argv[2]);
+ return 0;
} else {
usage();
return 1;
}
else {
ovpnInit();
-
+
if( (strcmp(argv[1], "-s") == 0) || (strcmp(argv[1], "--start") == 0) ) {
setFirewallRules();
startDaemon();