#include #include #include #include #include #include #include #include #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 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, };