summaryrefslogtreecommitdiffstats
path: root/src/plugins/ifw/plugin.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/ifw/plugin.c')
-rw-r--r--src/plugins/ifw/plugin.c224
1 files changed, 224 insertions, 0 deletions
diff --git a/src/plugins/ifw/plugin.c b/src/plugins/ifw/plugin.c
new file mode 100644
index 0000000..0e6ac69
--- /dev/null
+++ b/src/plugins/ifw/plugin.c
@@ -0,0 +1,224 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sys/socket.h>
+
+#include "ifw.h"
+#include "ifw_dbus.h"
+#include "ipset.h"
+
+static int init(plugin_t *plugin, DBusConnection *connection);
+static void deinit(plugin_t *plugin, DBusConnection *connection);
+static void process_attack(plugin_t *plugin, DBusConnection *connection, int seq, msg_usr_t *attack);
+static DBusHandlerResult handle_message(DBusConnection *connection, DBusMessage *message, plugin_t *plugin);
+#ifdef IFW_FAKE
+static int generate_fake_attack(msg_usr_t *attack);
+static void handle_fake(plugin_t *plugin, DBusConnection *connection);
+#else
+static void handle_incoming(plugin_t *plugin, DBusConnection *connection);
+#endif
+
+static int init(plugin_t *plugin, DBusConnection *connection) {
+ ifw_t *ifw;
+
+ ifw = malloc(sizeof(ifw_t));
+ if (!ifw) {
+ fprintf(stderr, "unable to malloc ifw\n");
+ return -1;
+ }
+
+ report_list_init(&ifw->reports);
+ black_list_init(&ifw->blacklist);
+ white_list_init(&ifw->whitelist);
+ white_list_load(&ifw->whitelist, IFW_WHITELIST_FILENAME);
+
+ ifw->mode = IFW_MODE_INTERACTIVE;
+
+#ifdef IFW_FAKE
+ plugin->fd = 0;
+#else
+ plugin->fd = nl_ifw_create_socket();
+ if (plugin->fd < 0) {
+ fprintf(stderr, "unable to init netlink\n");
+ return -1;
+ }
+#endif
+
+ ifw_dbus_notify_clear(connection);
+ ifw_dbus_notify_init(connection);
+
+ plugin->priv = (void *) ifw;
+
+ return 0;
+}
+
+static void deinit(plugin_t *plugin, DBusConnection *connection) {
+ ifw_t *ifw = (ifw_t *) plugin->priv;
+
+ ifw_dbus_notify_clear(connection);
+ close(plugin->fd);
+}
+
+#ifdef IFW_FAKE
+#include <time.h>
+
+static int generate_fake_attack(msg_usr_t *attack) {
+ static int seq = 0;
+ uint32_t addr = 0xC0A86401;
+
+ time(&attack->timestamp_sec);
+ strcpy(attack->indev_name, "ppp0");
+ attack->sensor = 0;
+ attack->protocol = 0;
+ attack->icmp_type = 0;
+ attack->d_port = 0;
+ attack->s_addr = htonl(addr);
+
+ switch(seq%3) {
+ case 0:
+ strcpy(attack->prefix, "SCAN");
+ break;
+ case 1:
+ strcpy(attack->prefix, "SERV");
+ attack->d_port = 22;
+ break;
+ case 2:
+ strcpy(attack->prefix, "PASS");
+ break;
+ }
+
+ addr++;
+ seq++;
+
+ return seq;
+}
+
+static void handle_fake(plugin_t *plugin, DBusConnection *connection) {
+ msg_usr_t fake_attack;
+ int seq;
+
+ read(0, NULL, 1);
+
+ seq = generate_fake_attack(&fake_attack);
+ printf("seq : %d\n", seq);
+
+ process_attack(plugin, connection, seq, &fake_attack);
+}
+
+#else
+
+static void handle_incoming(plugin_t *plugin, DBusConnection *connection) {
+ struct nl_msg msg;
+ static int seq = 0;
+ msg_usr_t attack;
+
+ if (nl_ifw_read_msg(plugin->fd, NULL, &msg) <= 0) {
+ fprintf(stderr, "unable to read packet from netlink\n");
+ return;
+ }
+
+ attack.timestamp_sec = msg.timestamp_sec;
+ strncpy(attack.indev_name, msg.indev_name, IFNAMSIZ);
+ strncpy(attack.prefix, (char *) msg.prefix, PREFSIZ);
+ attack.sensor = 0;
+ attack.protocol = msg.ip.protocol;
+ attack.s_addr = msg.ip.saddr;
+ switch (msg.ip.protocol) {
+ case IPPROTO_TCP:
+ attack.d_port = msg.h.th.dest;
+ break;
+ case IPPROTO_UDP:
+ attack.d_port = msg.h.uh.dest;
+ break;
+ default:
+ attack.d_port = 0;
+ break;
+ }
+ attack.icmp_type = 0;
+
+ process_attack(plugin, connection, seq++, &attack);
+}
+
+#endif
+
+static void process_attack(plugin_t *plugin, DBusConnection *connection, int seq, msg_usr_t *attack) {
+ ifw_t *ifw = (ifw_t *) plugin->priv;
+ report_list_cell_t *report;
+
+ if (black_list_find(&ifw->blacklist, attack->s_addr) ||
+ white_list_find(&ifw->whitelist, attack->s_addr) ||
+ report_list_find(&ifw->reports, attack->s_addr, 0)) {
+ struct in_addr addr;
+ addr.s_addr = attack->s_addr;
+ fprintf(stderr, "skipping known address: %s\n", inet_ntoa(addr));
+ return;
+ }
+
+ if (!strcmp(attack->indev_name, "lo")) {
+ fprintf(stderr, "skipping loopback interface\n");
+ return;
+ }
+
+ report = report_list_add(&ifw->reports, seq, attack);
+ if (report) {
+ if (ifw->mode == IFW_MODE_AUTO) {
+ /* add ip address in ipset blacklist */
+ ifw_dbus_apply_report_verdict(connection, ifw, report, 1);
+ }
+
+ /* notify the attack to frontends */
+ ifw_dbus_notify_attack(connection, report);
+ }
+
+ black_list_print(&ifw->blacklist);
+ white_list_print(&ifw->whitelist);
+ report_list_print(&ifw->reports);
+}
+
+static DBusHandlerResult handle_message(DBusConnection *connection, DBusMessage *message, plugin_t *plugin) {
+ ifw_t *ifw = (ifw_t *) plugin->priv;
+ if (dbus_message_is_method_call(message, IFW_DBUS_INTERFACE, "GetMode")) {
+ return ifw_dbus_get_mode(connection, message, ifw);
+ } else if (dbus_message_is_method_call(message, IFW_DBUS_INTERFACE, "SetMode")) {
+ return ifw_dbus_set_mode(connection, message, ifw);
+ } else if (dbus_message_is_method_call(message, IFW_DBUS_INTERFACE, "GetReports")) {
+ return ifw_dbus_get_reports(connection, message, ifw);
+ } else if (dbus_message_is_method_call(message, IFW_DBUS_INTERFACE, "GetBlacklist")) {
+ return ifw_dbus_get_blacklist(connection, message, ifw);
+ } else if (dbus_message_is_method_call(message, IFW_DBUS_INTERFACE, "SetBlacklistVerdict")) {
+ return ifw_dbus_set_blacklist_verdict(connection, message, ifw);
+ } else if (dbus_message_is_method_call(message, IFW_DBUS_INTERFACE, "UnBlacklist")) {
+ return ifw_dbus_unblacklist(connection, message, ifw);
+ } else if (dbus_message_is_method_call(message, IFW_DBUS_INTERFACE, "GetWhitelist")) {
+ return ifw_dbus_get_whitelist(connection, message, ifw);
+ } else if (dbus_message_is_method_call(message, IFW_DBUS_INTERFACE, "Whitelist")) {
+ return ifw_dbus_whitelist(connection, message, ifw);
+ } else if (dbus_message_is_method_call(message, IFW_DBUS_INTERFACE, "UnWhitelist")) {
+ return ifw_dbus_unwhitelist(connection, message, ifw);
+ } else if (dbus_message_is_method_call(message, IFW_DBUS_INTERFACE, "ClearProcessedReports")) {
+ return ifw_dbus_clear_processed_reports(connection, message, ifw);
+ } else if (dbus_message_is_method_call(message, IFW_DBUS_INTERFACE, "SendAlertAck")) {
+ return ifw_dbus_send_alert_ack(connection, message, ifw);
+ } else if (dbus_message_is_method_call(message, IFW_DBUS_INTERFACE, "SendManageRequest")) {
+ return ifw_dbus_send_manage_request(connection, message, ifw);
+ }
+
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
+plugin_t ifw_plugin = {
+ .name = "Interactive Firewall",
+ .path = IFW_DBUS_PATH,
+ .init = init,
+#ifdef IFW_FAKE
+ .handle_incoming = handle_fake,
+#else
+ .handle_incoming = handle_incoming,
+#endif
+ .handle_message = handle_message,
+ .deinit = deinit,
+};