#include #include "ifw_dbus.h" static void ifw_dbus_notify_simple_signal(DBusConnection *bus, char *signal) { DBusMessage *message; message = dbus_message_new_signal(IFW_DBUS_PATH, IFW_DBUS_INTERFACE, signal); dbus_connection_send(bus, message, NULL); dbus_connection_flush(bus); dbus_message_unref(message); } void ifw_dbus_apply_report_verdict(DBusConnection *connection, ifw_t *ifw, report_list_cell_t *report, int do_blacklist) { if (do_blacklist) { if (!black_list_find(&ifw->blacklist, report->info.s_addr)) { printf("blacklisting seq %d\n", report->seq); black_list_add(&ifw->blacklist, &report->info); ifw_dbus_notify_blacklist(connection, &report->info); } else { printf("(seq %d) addr %u already in blacklist\n", report->seq, report->info.s_addr); } } else { printf("ignoring seq %d\n", report->seq); } report->processed = 1; } /* notify frontends of a new attack with a DBus signal */ void ifw_dbus_notify_attack(DBusConnection *bus, report_list_cell_t *report) { DBusMessage *message; message = dbus_message_new_signal(IFW_DBUS_PATH, IFW_DBUS_INTERFACE, "Attack"); /* DBus wants a char** for strings, and &char[] == char*, so use temporary variables */ char *dev = report->info.indev_name; char *prefix = report->info.prefix; dbus_message_append_args(message, DBUS_TYPE_UINT32, &report->info.timestamp_sec, DBUS_TYPE_STRING, &dev, DBUS_TYPE_STRING, &prefix, DBUS_TYPE_UINT32, &report->info.sensor, DBUS_TYPE_UINT32, &report->info.protocol, DBUS_TYPE_UINT32, &report->info.s_addr, DBUS_TYPE_UINT32, &report->info.d_port, DBUS_TYPE_UINT32, &report->info.icmp_type, DBUS_TYPE_UINT32, &report->seq, DBUS_TYPE_UINT32, &report->processed, DBUS_TYPE_INVALID); dbus_connection_send(bus, message, NULL); dbus_connection_flush(bus); dbus_message_unref(message); } /* notify frontends of a new blacklist with a DBus signal */ void ifw_dbus_notify_blacklist(DBusConnection *bus, msg_usr_t *attack) { DBusMessage *message; /* DBus wants a char** for strings, and &char[] == char*, so use temporary variables */ char *dev = attack->indev_name; char *prefix = attack->prefix; message = dbus_message_new_signal(IFW_DBUS_PATH, IFW_DBUS_INTERFACE, "Blacklist"); dbus_message_append_args(message, DBUS_TYPE_UINT32, &attack->timestamp_sec, DBUS_TYPE_STRING, &dev, DBUS_TYPE_STRING, &prefix, DBUS_TYPE_UINT32, &attack->sensor, DBUS_TYPE_UINT32, &attack->protocol, DBUS_TYPE_UINT32, &attack->s_addr, DBUS_TYPE_UINT32, &attack->d_port, DBUS_TYPE_UINT32, &attack->icmp_type, DBUS_TYPE_INVALID); dbus_connection_send(bus, message, NULL); dbus_connection_flush(bus); dbus_message_unref(message); } /* notify frontends of a new whitelist with a DBus signal */ void ifw_dbus_notify_whitelist(DBusConnection *bus, u_int32_t addr) { DBusMessage *message; message = dbus_message_new_signal(IFW_DBUS_PATH, IFW_DBUS_INTERFACE, "Whitelist"); dbus_message_append_args(message, DBUS_TYPE_UINT32, &addr, DBUS_TYPE_INVALID); dbus_connection_send(bus, message, NULL); dbus_connection_flush(bus); dbus_message_unref(message); } /* notify frontends that ifw data isn't usable with a DBus signal */ void ifw_dbus_notify_clear(DBusConnection *bus) { ifw_dbus_notify_simple_signal(bus, "Clear"); } /* notify frontends that ifw has just been started */ void ifw_dbus_notify_init(DBusConnection *bus) { ifw_dbus_notify_simple_signal(bus, "Init"); } /* notify frontends that a user is aware of the attacks */ void ifw_dbus_notify_alert_ack(DBusConnection *bus) { ifw_dbus_notify_simple_signal(bus, "AlertAck"); } /* notify frontends that a user is wants to review the attacks */ void ifw_dbus_notify_manage_request(DBusConnection *bus) { ifw_dbus_notify_simple_signal(bus, "ManageRequest"); } DBusHandlerResult ifw_dbus_get_mode(DBusConnection *connection, DBusMessage *message, ifw_t *ifw) { DBusMessage *reply; reply = dbus_message_new_method_return(message); dbus_message_append_args(reply, DBUS_TYPE_UINT32, &ifw->mode, DBUS_TYPE_INVALID); dbus_connection_send(connection, reply, NULL); dbus_connection_flush(connection); dbus_message_unref(reply); return DBUS_HANDLER_RESULT_HANDLED; } DBusHandlerResult ifw_dbus_set_mode(DBusConnection *connection, DBusMessage *message, ifw_t *ifw) { DBusError error; DBusMessage *reply; ifw_mode_t mode; dbus_error_init (&error); if (!dbus_message_get_args (message, &error, DBUS_TYPE_UINT32, &mode, DBUS_TYPE_INVALID)) { fprintf(stderr, "ifw_dbus_set_mode(): failed to read D-BUS message args: %s\n", error.message); dbus_error_free (&error); return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } dbus_error_free (&error); printf("setting new ifw mode : %s\n", mode == IFW_MODE_AUTO ? "auto" : mode == IFW_MODE_INTERACTIVE ? "interactive" : "unknown"); ifw->mode = mode; reply = dbus_message_new_method_return(message); dbus_message_append_args(reply, DBUS_TYPE_UINT32, &ifw->mode, DBUS_TYPE_INVALID); dbus_connection_send(connection, reply, NULL); dbus_connection_flush(connection); dbus_message_unref(reply); return DBUS_HANDLER_RESULT_HANDLED; } DBusHandlerResult ifw_dbus_get_reports(DBusConnection *connection, DBusMessage *message, ifw_t *ifw) { DBusError error; struct list_head *entry; DBusMessage *reply; char include_processed; dbus_error_init (&error); if (!dbus_message_get_args (message, &error, DBUS_TYPE_UINT32, &include_processed, DBUS_TYPE_INVALID)) { fprintf(stderr, "ifw_dbus_get_reports(): failed to read D-BUS message args: %s\n", error.message); dbus_error_free (&error); return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } dbus_error_free (&error); reply = dbus_message_new_method_return(message); __list_for_each(entry, &ifw->reports) { report_list_cell_t *cell; /* DBus wants a char** for strings, and &char[] == char*, so use temporary variables */ char *dev, *prefix; cell = list_entry(entry, report_list_cell_t, list); if (cell->processed && !include_processed) { continue; } dev = cell->info.indev_name; prefix = cell->info.prefix; dbus_message_append_args(reply, DBUS_TYPE_UINT32, &cell->info.timestamp_sec, DBUS_TYPE_STRING, &dev, DBUS_TYPE_STRING, &prefix, DBUS_TYPE_UINT32, &cell->info.sensor, DBUS_TYPE_UINT32, &cell->info.protocol, DBUS_TYPE_UINT32, &cell->info.s_addr, DBUS_TYPE_UINT32, &cell->info.d_port, DBUS_TYPE_UINT32, &cell->info.icmp_type, DBUS_TYPE_UINT32, &cell->seq, DBUS_TYPE_UINT32, &cell->processed, DBUS_TYPE_INVALID); } dbus_connection_send(connection, reply, NULL); dbus_connection_flush(connection); dbus_message_unref(reply); return DBUS_HANDLER_RESULT_HANDLED; } DBusHandlerResult ifw_dbus_get_blacklist(DBusConnection *connection, DBusMessage *message, ifw_t *ifw) { struct list_head *entry; DBusMessage *reply; reply = dbus_message_new_method_return(message); __list_for_each(entry, &ifw->blacklist) { black_list_cell_t *cell; /* DBus wants a char** for strings, and &char[] == char*, so use temporary variables */ char *dev, *prefix; cell = list_entry(entry, black_list_cell_t, list); dev = cell->info.indev_name; prefix = cell->info.prefix; dbus_message_append_args(reply, DBUS_TYPE_UINT32, &cell->info.timestamp_sec, DBUS_TYPE_STRING, &dev, DBUS_TYPE_STRING, &prefix, DBUS_TYPE_UINT32, &cell->info.sensor, DBUS_TYPE_UINT32, &cell->info.protocol, DBUS_TYPE_UINT32, &cell->info.s_addr, DBUS_TYPE_UINT32, &cell->info.d_port, DBUS_TYPE_UINT32, &cell->info.icmp_type, DBUS_TYPE_INVALID); } dbus_connection_send(connection, reply, NULL); dbus_connection_flush(connection); dbus_message_unref(reply); return DBUS_HANDLER_RESULT_HANDLED; } DBusHandlerResult ifw_dbus_set_blacklist_verdict(DBusConnection *connection, DBusMessage *message, ifw_t *ifw) { DBusError error; DBusMessage *reply; int seq, do_blacklist; report_list_cell_t *report; dbus_error_init (&error); if (!dbus_message_get_args (message, &error, DBUS_TYPE_UINT32, &seq, DBUS_TYPE_UINT32, &do_blacklist, DBUS_TYPE_INVALID)) { fprintf(stderr, "ifw_dbus_blacklist(): failed to read D-BUS message args: %s\n", error.message); dbus_error_free (&error); return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } dbus_error_free (&error); reply = dbus_message_new_method_return(message); dbus_connection_send(connection, reply, NULL); dbus_connection_flush(connection); dbus_message_unref(reply); report = report_list_find_seq(&ifw->reports, seq); if (report) { ifw_dbus_apply_report_verdict(connection, ifw, report, do_blacklist); } else { fprintf(stderr, "unable find sequence number in report list, skipping\n"); } black_list_print(&ifw->blacklist); report_list_print(&ifw->reports); return DBUS_HANDLER_RESULT_HANDLED; } DBusHandlerResult ifw_dbus_unblacklist(DBusConnection *connection, DBusMessage *message, ifw_t *ifw) { DBusError error; DBusMessage *reply; u_int32_t addr; dbus_error_init (&error); if (!dbus_message_get_args (message, &error, DBUS_TYPE_UINT32, &addr, DBUS_TYPE_INVALID)) { fprintf(stderr, "ifw_dbus_blacklist(): failed to read D-BUS message args: %s\n", error.message); dbus_error_free (&error); return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } dbus_error_free (&error); black_list_remove(&ifw->blacklist, addr); reply = dbus_message_new_method_return(message); dbus_connection_send(connection, reply, NULL); dbus_connection_flush(connection); dbus_message_unref(reply); return DBUS_HANDLER_RESULT_HANDLED; } DBusHandlerResult ifw_dbus_get_whitelist(DBusConnection *connection, DBusMessage *message, ifw_t *ifw) { struct list_head *entry; DBusMessage *reply; reply = dbus_message_new_method_return(message); __list_for_each(entry, &ifw->whitelist) { white_list_cell_t *cell; cell = list_entry(entry, white_list_cell_t, list); dbus_message_append_args(reply, DBUS_TYPE_UINT32, &cell->addr, DBUS_TYPE_INVALID); } dbus_connection_send(connection, reply, NULL); dbus_connection_flush(connection); dbus_message_unref(reply); return DBUS_HANDLER_RESULT_HANDLED; } DBusHandlerResult ifw_dbus_whitelist(DBusConnection *connection, DBusMessage *message, ifw_t *ifw) { DBusError error; DBusMessage *reply; u_int32_t addr; dbus_error_init (&error); if (!dbus_message_get_args (message, &error, DBUS_TYPE_UINT32, &addr, DBUS_TYPE_INVALID)) { fprintf(stderr, "ifw_dbus_whitelist(): failed to read D-BUS message args: %s\n", error.message); dbus_error_free (&error); return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } dbus_error_free (&error); if (!white_list_find(&ifw->whitelist, addr)) { printf("whitelisting addr %u\n", addr); white_list_add(&ifw->whitelist, addr); } else { printf("addr %u already in whitelist\n", addr); } white_list_print(&ifw->whitelist); reply = dbus_message_new_method_return(message); dbus_connection_send(connection, reply, NULL); dbus_connection_flush(connection); dbus_message_unref(reply); ifw_dbus_notify_whitelist(connection, addr); return DBUS_HANDLER_RESULT_HANDLED; } DBusHandlerResult ifw_dbus_unwhitelist(DBusConnection *connection, DBusMessage *message, ifw_t *ifw) { DBusError error; DBusMessage *reply; u_int32_t addr; dbus_error_init (&error); if (!dbus_message_get_args (message, &error, DBUS_TYPE_UINT32, &addr, DBUS_TYPE_INVALID)) { fprintf(stderr, "ifw_dbus_whitelist(): failed to read D-BUS message args: %s\n", error.message); dbus_error_free (&error); return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } dbus_error_free (&error); printf("remove addr from whitelist %u\n", addr); white_list_remove(&ifw->whitelist, addr); white_list_print(&ifw->whitelist); reply = dbus_message_new_method_return(message); dbus_connection_send(connection, reply, NULL); dbus_connection_flush(connection); dbus_message_unref(reply); return DBUS_HANDLER_RESULT_HANDLED; } DBusHandlerResult ifw_dbus_clear_processed_reports(DBusConnection *connection, DBusMessage *message, ifw_t *ifw) { DBusMessage *reply; report_list_clear_processed(&ifw->reports); reply = dbus_message_new_method_return(message); dbus_connection_send(connection, reply, NULL); dbus_connection_flush(connection); dbus_message_unref(reply); return DBUS_HANDLER_RESULT_HANDLED; } DBusHandlerResult ifw_dbus_send_alert_ack(DBusConnection *connection, DBusMessage *message, ifw_t *ifw) { DBusMessage *reply; ifw_dbus_notify_alert_ack(connection); reply = dbus_message_new_method_return(message); dbus_connection_send(connection, reply, NULL); dbus_connection_flush(connection); dbus_message_unref(reply); return DBUS_HANDLER_RESULT_HANDLED; } DBusHandlerResult ifw_dbus_send_manage_request(DBusConnection *connection, DBusMessage *message, ifw_t *ifw) { DBusMessage *reply; ifw_dbus_notify_manage_request(connection); reply = dbus_message_new_method_return(message); dbus_connection_send(connection, reply, NULL); dbus_connection_flush(connection); dbus_message_unref(reply); return DBUS_HANDLER_RESULT_HANDLED; }