diff options
Diffstat (limited to 'client')
| -rw-r--r-- | client/Makefile.am | 26 | ||||
| -rw-r--r-- | client/advancedwin.c | 59 | ||||
| -rw-r--r-- | client/advancedwin.h | 10 | ||||
| -rw-r--r-- | client/callbacks.c | 298 | ||||
| -rw-r--r-- | client/callbacks.h | 197 | ||||
| -rw-r--r-- | client/connection.c | 292 | ||||
| -rw-r--r-- | client/connection.h | 41 | ||||
| -rw-r--r-- | client/daemon.c | 198 | ||||
| -rw-r--r-- | client/daemon.h | 13 | ||||
| -rw-r--r-- | client/format.c | 216 | ||||
| -rw-r--r-- | client/format.h | 34 | ||||
| -rw-r--r-- | client/interface.c | 2173 | ||||
| -rw-r--r-- | client/interface.h | 9 | ||||
| -rw-r--r-- | client/log.c | 71 | ||||
| -rw-r--r-- | client/log.h | 12 | ||||
| -rw-r--r-- | client/main.c | 55 | ||||
| -rw-r--r-- | client/main.h | 7 | ||||
| -rw-r--r-- | client/mainwin.c | 52 | ||||
| -rw-r--r-- | client/mainwin.h | 12 | ||||
| -rw-r--r-- | client/rule.c | 318 | ||||
| -rw-r--r-- | client/rule.h | 52 | ||||
| -rw-r--r-- | client/ruleset.c | 534 | ||||
| -rw-r--r-- | client/ruleset.h | 49 | ||||
| -rw-r--r-- | client/rulewin.c | 249 | ||||
| -rw-r--r-- | client/rulewin.h | 14 | ||||
| -rw-r--r-- | client/support.c | 144 | ||||
| -rw-r--r-- | client/support.h | 67 | ||||
| -rw-r--r-- | client/test.fwx | 141 | 
28 files changed, 5343 insertions, 0 deletions
diff --git a/client/Makefile.am b/client/Makefile.am new file mode 100644 index 0000000..8b6f709 --- /dev/null +++ b/client/Makefile.am @@ -0,0 +1,26 @@ +## Process this file with automake to produce Makefile.in + +INCLUDES = \ +	-I/usr/include/libipq -Wall \ +	-DPACKAGE_DATA_DIR=\""$(datadir)"\" \ +	-DPACKAGE_LOCALE_DIR=\""$(prefix)/$(DATADIRNAME)/locale"\" \ +	@PACKAGE_CFLAGS@ + +bin_PROGRAMS = fieryfilter + +fieryfilter_SOURCES = \ +	ruleset.c ruleset.h \ +	main.c main.h \ +	support.c support.h \ +	interface.c interface.h \ +	callbacks.c callbacks.h \ +	connection.c connection.h \ +	daemon.c daemon.h \ +	mainwin.c mainwin.h \ +	rulewin.c rulewin.h \ +	log.c log.h \ +	format.c format.h \ +	rule.c rule.h \ +	advancedwin.c advancedwin.h + +fieryfilter_LDADD = @PACKAGE_LIBS@ $(INTLLIBS) -lmcheck diff --git a/client/advancedwin.c b/client/advancedwin.c new file mode 100644 index 0000000..4cbac57 --- /dev/null +++ b/client/advancedwin.c @@ -0,0 +1,59 @@ +#include <gtk/gtk.h> + +#include "advancedwin.h" +#include "interface.h" +#include "format.h" +#include "support.h" +#include "connection.h" +#include "ruleset.h" + +static gboolean ignore_apply = TRUE; + +static GtkWidget* get_window(void) { +    static GtkWidget *aw = NULL; + +    if (!aw) { +        aw = create_advanced_window(); +        fill_icmp_menu(GTK_OPTION_MENU(lookup_widget(aw, "icmp_option_menu")), TRUE, 0); +    } +    return aw; +} + + +void advancedwin_show(gboolean b) { +    if (b) { +        advancedwin_fill(); +        gtk_widget_show_all(get_window()); +        ignore_apply = FALSE; +    } else { +        ignore_apply = TRUE; +        gtk_widget_hide(get_window()); +    } +} + +void advancedwin_fill() { +    GtkWidget *aw = get_window(); + +    set_icmp_menu_entry(GTK_OPTION_MENU(lookup_widget(aw, "icmp_option_menu")), TRUE, ruleset.icmp_reject_code); +    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(aw, "tcp_rst_check_button")), ruleset.use_tcp_rst); +} + +void advancedwin_apply() { +   GtkWidget *w, *aw; +   GtkOptionMenu *om; +    +   if (ignore_apply) +        return; +     +   aw = get_window(); +   om = GTK_OPTION_MENU(lookup_widget(aw, "icmp_option_menu")); +    +   w = GTK_WIDGET(g_list_nth_data(gtk_container_get_children(GTK_CONTAINER(gtk_option_menu_get_menu(om))), +                                                             gtk_option_menu_get_history(om))); +   ruleset.icmp_reject_code = GPOINTER_TO_UINT(g_object_get_data(G_OBJECT(w), "icmp_value")); +    +   ruleset.use_tcp_rst = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(aw, "tcp_rst_check_button"))); + +   ruleset.modified = TRUE; +   ruleset_update_ui(); +} diff --git a/client/advancedwin.h b/client/advancedwin.h new file mode 100644 index 0000000..c0c5f74 --- /dev/null +++ b/client/advancedwin.h @@ -0,0 +1,10 @@ +#ifndef fooadvancedwinhfoo +#define fooadvancedwinhfoo + +#include <glib.h> + +void advancedwin_show(gboolean b); +void advancedwin_fill(); +void advancedwin_apply(); + +#endif diff --git a/client/callbacks.c b/client/callbacks.c new file mode 100644 index 0000000..ac0cb4b --- /dev/null +++ b/client/callbacks.c @@ -0,0 +1,298 @@ +#ifdef HAVE_CONFIG_H +#  include <config.h> +#endif + +#include <gtk/gtk.h> +#include <stdio.h> +#include <netinet/in.h> +#include <netdb.h> + +#include "callbacks.h" +#include "interface.h" +#include "support.h" + +#include "connection.h" +#include "mainwin.h" +#include "rulewin.h" +#include "log.h" +#include "rulewin.h" +#include "advancedwin.h" + +gboolean on_connection_window_delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_data) { +    conn_verdict(VERDICT_DROP); +    return TRUE; +} +                                                                                                                                                                                 +                                                                                                                                                                                 +void on_drop_button_clicked(GtkButton *button, gpointer user_data) { +    conn_verdict(VERDICT_DROP); +} +                                                                                                                                                                                 +                                                                                                                                                                                 +void on_reject_button_clicked(GtkButton *button, gpointer user_data) { +    conn_verdict(VERDICT_REJECT); +} +                                                                                                                                                                                 +                                                                                                                                                                                 +void on_accept_button_clicked(GtkButton *button, gpointer user_data) { +    conn_verdict(VERDICT_ACCEPT); +} + +void on_quit_activate(GtkMenuItem *menuitem, gpointer user_data) { +    gtk_main_quit(); +} + +void on_clear_log_activate(GtkMenuItem *menuitem, gpointer user_data) { +    log_widget_clear(); +} + +void on_sticky_button_toggled(GtkToggleButton *togglebutton, gpointer user_data) { +    conn_set_sticky(); +} + +gboolean on_main_window_delete_event (GtkWidget *widget, GdkEvent *event, gpointer user_data) { +    gtk_main_quit(); +    return FALSE; +} + +void on_icmp_option_menu_changed(GtkOptionMenu *optionmenu, gpointer user_data) { +    advancedwin_apply(); +} + +void on_direction_optionmenu_changed(GtkOptionMenu *optionmenu, gpointer user_data) { +    rulewin_set_sensitive(GTK_WIDGET(optionmenu)); +} + +void on_match_direction_checkbutton_toggled(GtkToggleButton *togglebutton, gpointer user_data) { +    rulewin_set_sensitive(GTK_WIDGET(togglebutton)); +} + + +void on_match_interfaces_checkbutton_toggled(GtkToggleButton *togglebutton, gpointer user_data) { +    rulewin_set_sensitive(GTK_WIDGET(togglebutton)); +} + + +void on_protocol_optionmenu_changed(GtkOptionMenu *optionmenu, gpointer user_data) { +    rulewin_set_sensitive(GTK_WIDGET(optionmenu)); +} + + +void on_port_spinbutton_value_changed(GtkSpinButton *spinbutton, gpointer user_data) { +    GtkWidget *w = GTK_WIDGET(spinbutton); +    struct servent *se; +    guint16 port; +    gchar *p; +    static gchar txt[256]; + +    port = (guint16) gtk_spin_button_get_value(GTK_SPIN_BUTTON(lookup_widget(w, "port_spinbutton"))); + +    if ((se = getservbyport(htons(port), NULL))) +        snprintf(p = txt, sizeof(txt), "<b>%s</b>", se->s_name); +    else +        p = "<i>Unknown</i>"; + +    gtk_label_set_label(GTK_LABEL(lookup_widget(w, "type_label")), p); +} + + +void on_match_type_checkbutton_toggled(GtkToggleButton *togglebutton, gpointer user_data) { +    rulewin_set_sensitive(GTK_WIDGET(togglebutton)); +} + + +void on_src_netmask_checkbutton_toggled(GtkToggleButton *togglebutton, gpointer user_data) { +    rulewin_set_sensitive(GTK_WIDGET(togglebutton)); +} + +void on_dst_netmask_checkbutton_toggled(GtkToggleButton *togglebutton, gpointer user_data) { +    rulewin_set_sensitive(GTK_WIDGET(togglebutton)); +} + + +void on_src_netmask_spinbutton_value_changed(GtkSpinButton *spinbutton, gpointer user_data) { +    rulewin_update_host_ranges(GTK_WIDGET(spinbutton)); +} + + +void on_src_ip_entry_changed(GtkEditable *editable, gpointer user_data) { +    rulewin_update_host_ranges(GTK_WIDGET(editable)); +} + + +void on_match_source_checkbutton_toggled(GtkToggleButton *togglebutton, gpointer user_data) { +    rulewin_set_sensitive(GTK_WIDGET(togglebutton)); +} + + +void on_ok_button_clicked(GtkButton *button, gpointer user_data) { +    GtkWidget *rw = GTK_WIDGET(button); +    rulewin_ok(rw); +    gtk_widget_destroy(rw); +} + + +void on_cancel_button_clicked(GtkButton *button, gpointer user_data) { +    rulewin_cancel(GTK_WIDGET(button)); +} + + +void on_add_button_clicked(GtkButton *button, gpointer user_data) { +    rulewin_show(NULL); +} + + +void on_desc_entry_changed(GtkEditable *editable, gpointer user_data) { +    GtkWidget *rw = GTK_WIDGET(editable); +    static gchar desc[256]; +    const gchar *p; +    // Yes, the user may insert <> charachters here, but is this tragic? + +    p = gtk_entry_get_text(GTK_ENTRY(lookup_widget(rw, "desc_entry"))); + +    if (!*p) +        p = "<span color=\"white\" size=\"xx-large\"><b><i>New rule</i></b></span>"; +     +    snprintf(desc, sizeof(desc), "<span color=\"white\" size=\"xx-large\"><b>%s</b></span>", p); +    gtk_label_set_label(GTK_LABEL(lookup_widget(rw, "desc_label")), desc); +    rulewin_set_sensitive(GTK_WIDGET(editable)); +} + + +void on_bc_radiobutton_toggled(GtkToggleButton *togglebutton, gpointer user_data) { +    rulewin_set_sensitive(GTK_WIDGET(togglebutton)); +} + + + +void on_dst_netmask_spinbutton_value_changed(GtkSpinButton *spinbutton, gpointer user_data) { +    rulewin_update_host_ranges(GTK_WIDGET(spinbutton)); +} + + +void on_dst_ip_entry_changed(GtkEditable *editable, gpointer user_data) { +    rulewin_update_host_ranges(GTK_WIDGET(editable)); +} + + +void on_match_destination_checkbutton_toggled(GtkToggleButton *togglebutton, gpointer user_data) { +    rulewin_set_sensitive(GTK_WIDGET(togglebutton)); +} + + + +void on_properties_button_clicked(GtkButton *button, gpointer user_data) { +    rule_t* rule; +     +    if ((rule = ruleset_get_current_rule())) +        rulewin_show(rule); +} + + +void on_up_button_clicked(GtkButton *button, gpointer user_data) { +    rule_t* rule; +     +    if ((rule = ruleset_get_current_rule())) +        ruleset_move_rule(rule, -1); +} + + +void on_down_button_clicked(GtkButton *button, gpointer user_data) { +    rule_t* rule; +     +    if ((rule = ruleset_get_current_rule())) +        ruleset_move_rule(rule, +1); +} + + +void on_remove_button_clicked(GtkButton *button, gpointer user_data) { +    rule_t* rule; +     +    if ((rule = ruleset_get_current_rule())) +        ruleset_remove_rule(rule); +} + + +void on_clear_button_clicked(GtkButton *button, gpointer user_data) { +    ruleset_clear(); +} + + +void on_ruleset_view_cursor_changed(GtkTreeView *treeview, gpointer user_data) { +    ruleset_update_ui(); +} + + +gboolean on_rule_window_delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_data) { +    rulewin_cancel(GTK_WIDGET(widget)); +    return TRUE; +} + + +void on_commit_button_clicked(GtkButton *button, gpointer user_data) { +    ruleset_commit(); +} + + +void +on_save_ruleset_activate               (GtkMenuItem     *menuitem, +                                        gpointer         user_data) +{ + +} + + +void +on_open_ruleset_activate               (GtkMenuItem     *menuitem, +                                        gpointer         user_data) +{ + +} + + +void on_advanced_button_clicked(GtkButton *button, gpointer user_data){ +    advancedwin_show(TRUE); +} + + +gboolean on_advanced_window_delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_data) { +    advancedwin_show(FALSE); +    return TRUE; +} + + +void on_tcp_rst_check_button_toggled(GtkToggleButton *togglebutton, gpointer user_data) { +    advancedwin_apply(); +} + + +void on_close_button_clicked(GtkButton *button, gpointer user_data) { +    advancedwin_show(FALSE); +} + + +void on_ruleset_check_button_toggled(GtkToggleButton *togglebutton, gpointer user_data) { +    ruleset.ignore_rules = !gtk_toggle_button_get_active(togglebutton); +    ruleset.modified = TRUE; +    ruleset_update_ui(); +} + + +void on_unmatch_optionmenu_changed(GtkOptionMenu *optionmenu, gpointer user_data) { +    ruleset.unmatch_verdict = gtk_option_menu_get_history(optionmenu); +    ruleset.modified = TRUE; +    ruleset_update_ui(); +} + +void on_new_ruleset_activate(GtkMenuItem *menuitem, gpointer user_data) { +    ruleset_new(NULL); +} + +void on_about_activate(GtkMenuItem *menuitem, gpointer user_data) { +     +} + +void on_log_spinbutton_value_changed(GtkSpinButton *spinbutton, gpointer user_data) { +    log_widget_cut(); +} + diff --git a/client/callbacks.h b/client/callbacks.h new file mode 100644 index 0000000..21b8f02 --- /dev/null +++ b/client/callbacks.h @@ -0,0 +1,197 @@ +#include <gtk/gtk.h> + + +gboolean +on_connection_window_delete_event      (GtkWidget       *widget, +                                        GdkEvent        *event, +                                        gpointer         user_data); + +void +on_drop_button_clicked                 (GtkButton       *button, +                                        gpointer         user_data); + +void +on_reject_button_clicked               (GtkButton       *button, +                                        gpointer         user_data); + +void +on_accept_button_clicked               (GtkButton       *button, +                                        gpointer         user_data); + +void +on_quit_activate                       (GtkMenuItem     *menuitem, +                                        gpointer         user_data); + +void +on_clear_log_activate                  (GtkMenuItem     *menuitem, +                                        gpointer         user_data); + +void +on_about_activate                      (GtkMenuItem     *menuitem, +                                        gpointer         user_data); + +void +on_sticky_button_toggled               (GtkToggleButton *togglebutton, +                                        gpointer         user_data); + +gboolean +on_main_window_delete_event            (GtkWidget       *widget, +                                        GdkEvent        *event, +                                        gpointer         user_data); + +void +on_icmp_option_menu_changed            (GtkOptionMenu   *optionmenu, +                                        gpointer         user_data); + +void +on_direction_optionmenu_changed        (GtkOptionMenu   *optionmenu, +                                        gpointer         user_data); + +void +on_match_direction_checkbutton_toggled (GtkToggleButton *togglebutton, +                                        gpointer         user_data); + +void +on_match_interfaces_checkbutton_toggled +                                        (GtkToggleButton *togglebutton, +                                        gpointer         user_data); + +void +on_protocol_optionmenu_changed         (GtkOptionMenu   *optionmenu, +                                        gpointer         user_data); + +void +on_port_spinbutton_value_changed       (GtkSpinButton   *spinbutton, +                                        gpointer         user_data); + +void +on_match_type_checkbutton_toggled      (GtkToggleButton *togglebutton, +                                        gpointer         user_data); + +void +on_src_netmask_checkbutton_toggled     (GtkToggleButton *togglebutton, +                                        gpointer         user_data); + +void +on_src_netmask_spinbutton_value_changed +                                        (GtkSpinButton   *spinbutton, +                                        gpointer         user_data); + +void +on_src_ip_entry_changed                (GtkEditable     *editable, +                                        gpointer         user_data); + +void +on_match_source_checkbutton_toggled    (GtkToggleButton *togglebutton, +                                        gpointer         user_data); + +void +on_cancel_button_clicked               (GtkButton       *button, +                                        gpointer         user_data); + +void +on_ok_button_clicked                   (GtkButton       *button, +                                        gpointer         user_data); + +void +on_add_button_clicked                  (GtkButton       *button, +                                        gpointer         user_data); + +void +on_desc_entry_changed                  (GtkEditable     *editable, +                                        gpointer         user_data); + +void +on_bc_radiobutton_toggled              (GtkToggleButton *togglebutton, +                                        gpointer         user_data); +void +on_dst_netmask_spinbutton_value_changed +                                        (GtkSpinButton   *spinbutton, +                                        gpointer         user_data); + +void +on_dst_ip_entry_changed                (GtkEditable     *editable, +                                        gpointer         user_data); + +void +on_match_destination_checkbutton_toggled +                                        (GtkToggleButton *togglebutton, +                                        gpointer         user_data); + +void +on_dst_netmask_checkbutton_toggled     (GtkToggleButton *togglebutton, +                                        gpointer         user_data); + +void +on_properties_button_clicked           (GtkButton       *button, +                                        gpointer         user_data); + +void +on_up_button_clicked                   (GtkButton       *button, +                                        gpointer         user_data); + +void +on_down_button_clicked                 (GtkButton       *button, +                                        gpointer         user_data); + +void +on_remove_button_clicked               (GtkButton       *button, +                                        gpointer         user_data); + +void +on_clear_button_clicked                (GtkButton       *button, +                                        gpointer         user_data); + +void +on_ruleset_view_cursor_changed         (GtkTreeView     *treeview, +                                        gpointer         user_data); + +gboolean +on_rule_window_delete_event            (GtkWidget       *widget, +                                        GdkEvent        *event, +                                        gpointer         user_data); + +void +on_commit_button_clicked               (GtkButton       *button, +                                        gpointer         user_data); + +void +on_save_ruleset_activate               (GtkMenuItem     *menuitem, +                                        gpointer         user_data); + +void +on_open_ruleset_activate               (GtkMenuItem     *menuitem, +                                        gpointer         user_data); + +void +on_advanced_button_clicked             (GtkButton       *button, +                                        gpointer         user_data); + +gboolean +on_advanced_window_delete_event        (GtkWidget       *widget, +                                        GdkEvent        *event, +                                        gpointer         user_data); + +void +on_tcp_rst_check_button_toggled        (GtkToggleButton *togglebutton, +                                        gpointer         user_data); + +void +on_close_button_clicked                (GtkButton       *button, +                                        gpointer         user_data); + +void +on_ruleset_check_button_toggled        (GtkToggleButton *togglebutton, +                                        gpointer         user_data); + +void +on_unmatch_optionmenu_changed          (GtkOptionMenu   *optionmenu, +                                        gpointer         user_data); + +void +on_new_ruleset_activate                (GtkMenuItem     *menuitem, +                                        gpointer         user_data); + +void +on_log_spinbutton_value_changed        (GtkSpinButton   *spinbutton, +                                        gpointer         user_data); diff --git a/client/connection.c b/client/connection.c new file mode 100644 index 0000000..fb04e41 --- /dev/null +++ b/client/connection.c @@ -0,0 +1,292 @@ +#include <gtk/gtk.h> +#include <netdb.h> +#include <time.h> +#include <linux/ip.h> +#include <sys/ioctl.h> +#include <net/if.h> +#include <string.h> +#include <stdio.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> + +#include "connection.h" +#include "interface.h" +#include "support.h" +#include "daemon.h" +#include "mainwin.h" +#include "log.h" +#include "rulewin.h" +#include "ruleset.h" + +#include "format.h" + +GSList *queued_conn_list = NULL; +guint queued_conn_count = 0; + +conn_info_t *conn_current = NULL; + +guint total_conn_count = 0; + +static GtkWidget* get_window(void) { +    static GtkWidget *cw = NULL; + +    if (!cw) { +        GdkColor color; +        cw = create_connection_window(); +        gdk_color_parse ("black", &color); +        gtk_widget_modify_bg(lookup_widget(cw, "title_eventbox"), GTK_STATE_NORMAL, &color); +    } + +    return cw; +} + +void conn_fill_info(conn_info_t *c) { +    struct protoent *pe = NULL; +    struct servent *se = NULL; +    static gchar txt[256]; +    char *t; + +    c->from_string = g_strdup(format_hostname(c->src_ip_address)); +    c->to_string = g_strdup(format_hostname(c->dst_ip_address)); + +    c->port_string = NULL; +     +    if (c->protocol == IPPROTO_ICMP) +        snprintf(t = txt, sizeof(txt), "ICMP %s", icmp_type_str(c->icmp_type)); +    else if (c->protocol == IPPROTO_TCP || c->protocol == IPPROTO_UDP) { +        gchar *pp = c->protocol == IPPROTO_TCP ? "TCP" : "UDP"; + +        if ((se = getservbyport(htons(c->port), NULL))) +            snprintf(t = txt, sizeof(txt), "%s Port#%u (%s)", pp, c->port, c->port_string = g_strdup(se->s_name)); +        else +            snprintf(t = txt, sizeof(txt), "%s Port#%u", pp, c->port); +    } else if ((pe = getprotobynumber(c->protocol))) +        t = pe->p_name; +    else +        t = "Unknown"; + +    c->type_string = g_strdup(t); + +    strncpy(txt, ctime(&c->timestamp), sizeof(txt)); +    if (txt[0]) // remove trailing \n +        txt[strlen(txt)-1] = 0; +    c->timestamp_string = g_strdup(txt); +} + +void conn_free(conn_info_t*c) { +    g_free(c->from_string); +    g_free(c->to_string); +    g_free(c->type_string); +    g_free(c->port_string); +    g_free(c->timestamp_string); +    g_free(c); +} + +void conn_set_sticky() { +    if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(get_main_window(), "sticky_button")))) +        gtk_window_stick(GTK_WINDOW(get_window())); +    else +        gtk_window_unstick(GTK_WINDOW(get_window())); +} + +void conn_show_info(conn_info_t *c) { +    GtkWidget* window; +    GtkTooltips *tooltips; +    static gchar txt[256]; +    static gchar fn[PATH_MAX]; +    char *d; +    GdkPixbuf *pixbuf; + +    window = get_window(); + +    snprintf(txt, sizeof(txt), "<span size=\"xx-large\" color=\"white\"><b>%s Connection</b></span>", c->direction == DIR_INCOMING ? "Incoming" : (c->direction == DIR_OUTGOING ? "Outgoing" : "Passing")); +    gtk_label_set_label(GTK_LABEL(lookup_widget(window, "title_label")), txt); + +    gtk_image_set_from_stock(GTK_IMAGE(lookup_widget(window, "title_image")), c->direction == DIR_INCOMING ? GTK_STOCK_GO_FORWARD : (c->direction == DIR_OUTGOING ? GTK_STOCK_GO_BACK : GTK_STOCK_NEW), GTK_ICON_SIZE_DND); + +    if (c->direction == DIR_INCOMING) +        d = c->device_in; +    else if (c->direction == DIR_OUTGOING) +        d = c->device_out; +    else +        snprintf(d = txt, sizeof(txt), "%s => %s", c->device_in, c->device_out); +     +    gtk_label_set_label(GTK_LABEL(lookup_widget(window, "interface_label")), d); +    gtk_label_set_label(GTK_LABEL(lookup_widget(window, "from_label")), c->from_string); +    gtk_label_set_label(GTK_LABEL(lookup_widget(window, "to_label")), c->to_string); +    gtk_label_set_label(GTK_LABEL(lookup_widget(window, "type_label")), c->type_string); + +    tooltips = GTK_TOOLTIPS(lookup_widget(window, "tooltips")); +    gtk_tooltips_set_tip(tooltips, lookup_widget(window, "from_eventbox"), format_ip_address(c->src_ip_address), NULL); +    gtk_tooltips_set_tip(tooltips, lookup_widget(window, "to_eventbox"), format_ip_address(c->dst_ip_address), NULL); +    gtk_tooltips_set_delay(tooltips, 0); +     +    snprintf(txt, sizeof(txt), "%lu", c->id); +    gtk_label_set_label(GTK_LABEL(lookup_widget(window, "id_label")), txt); + +    gtk_label_set_label(GTK_LABEL(lookup_widget(window, "time_label")), c->timestamp_string); + +    gtk_widget_set_sensitive(lookup_widget(window, "reject_button"), !c->broadcast); + +    gtk_label_set_label(GTK_LABEL(lookup_widget(window, "broadcast_label")), c->broadcast ? "Yes" : "No"); + +    gtk_image_set_from_stock(GTK_IMAGE(lookup_widget(window, "type_image")), GTK_STOCK_MISSING_IMAGE, GTK_ICON_SIZE_DND); +    if (c->port_string) { +        snprintf(fn, sizeof(fn), "%s/pixmaps/%s.png", "..", c->port_string); +         +        if ((pixbuf = gdk_pixbuf_new_from_file(fn, NULL))) { +            gtk_image_set_from_pixbuf(GTK_IMAGE(lookup_widget(window, "type_image")), pixbuf); +            g_object_unref(pixbuf); +        } +    } +         +    gtk_widget_show_all(window); +    conn_set_sticky(); + +    gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); +    gtk_window_present(GTK_WINDOW(window)); +} + + +void conn_show_count() { +    static gchar txt[256]; +    gchar *p; + +    if (queued_conn_count) +        snprintf(p = txt, sizeof(txt), "Connection (%i in queue)", queued_conn_count); +    else +        p = "Connection"; + +    gtk_window_set_title(GTK_WINDOW(get_window()), p); +} + +void conn_pop() { +    g_assert(!conn_current && queued_conn_list); + +    conn_current = (conn_info_t*) queued_conn_list->data; +    queued_conn_list = g_slist_remove(queued_conn_list, conn_current); +    queued_conn_count--; +    conn_show_count(); +    conn_show_info(conn_current); +} + +static conn_info_t* ipq2ci(ipq_packet_msg_t* m) { +    conn_info_t* ci = g_new0(conn_info_t, 1); +    struct iphdr *ip = (struct iphdr*) m->payload; + +    ci->id = m->packet_id; +    ci->direction = (m->indev_name[0] && m->outdev_name[0]) ? DIR_PASSING : (m->indev_name[0] ? DIR_INCOMING : DIR_OUTGOING); +    strncpy(ci->device_in, m->indev_name, IFNAMSIZ); ci->device_in[IFNAMSIZ] = 0; +    strncpy(ci->device_out, m->outdev_name, IFNAMSIZ); ci->device_out[IFNAMSIZ] = 0; + +    if (m->data_len < sizeof(struct iphdr)) { +        g_message("Packet too small for complete IP header"); +        g_free(ci); +        return NULL; +    } +     +    ci->src_ip_address = ip->saddr; +    ci->dst_ip_address = ip->daddr; +    ci->protocol = ip->protocol; + +    ci->broadcast = is_broadcast(ci->dst_ip_address); + +    ci->port = 0; +    ci->icmp_type = 0; +     +    if (ci->protocol == IPPROTO_TCP || ci->protocol == IPPROTO_UDP) +        ci->port = ntohs(*((guint16*) (m->payload + sizeof(struct iphdr) + 2))); +    else if (ci->protocol == IPPROTO_ICMP) +        ci->icmp_type = *((guint8*) (m->payload + sizeof(struct iphdr))); +     +    ci->timestamp = m->timestamp_sec; +     +    return ci; +} + +guint verdict2nr(verdict_t v) { +    switch (v) { +        case VERDICT_REJECT : return ruleset.icmp_reject_code+2; +        case VERDICT_QUERY :  +        case VERDICT_DROP : return 0;  +        case VERDICT_ACCEPT : return 1; +    } + +    return 0; +} + +void conn_new(ipq_packet_msg_t *m) { +    conn_info_t *ci; + +    if ((ci = ipq2ci(m))) { +        queued_conn_list = g_slist_append(queued_conn_list, ci); +        queued_conn_count++; +        total_conn_count++; +        conn_fill_info(ci); +        log_widget_append(ci); +         +        conn_show_count(); +         +        if (!conn_current) +            conn_pop(); +         +        mainwin_update_status_bar(); +    } +} + +void conn_verdict(verdict_t v) { +    if (!conn_current) +        return; + +    if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(get_window(), "queue_check_button")))) { +        for (;;) { +            verdict_t _v; + +            if (v == VERDICT_REJECT && conn_current->broadcast) +                _v = VERDICT_DROP; +            else +                _v = v; + +            daemon_verdict(conn_current->id, verdict2nr(_v)); +            log_widget_verdict(conn_current, _v); +            conn_free(conn_current); + +            if (!queued_conn_list) +                break; + +            conn_current = (conn_info_t*) queued_conn_list->data; +            queued_conn_list = g_slist_remove(queued_conn_list, conn_current); +            queued_conn_count--; +        } + +         +        conn_current = NULL; +        g_assert(queued_conn_count == 0); + +        gtk_widget_hide(get_window()); +         +    } else { + +        if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(get_window(), "rule_check_button")))) { +            rule_t *rule; + +            rule = rule_new_from_conn_info(conn_current); +            rule->verdict = v; +            rulewin_show(rule); +            gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(get_window(), "rule_check_button")), FALSE); +        } +     +        daemon_verdict(conn_current->id, verdict2nr(v)); +        log_widget_verdict(conn_current, v); +        conn_free(conn_current); +        conn_current = NULL; +         +        if (!queued_conn_list) +            gtk_widget_hide(get_window()); +        else +            conn_pop(); +    } + +    mainwin_update_status_bar(); +} diff --git a/client/connection.h b/client/connection.h new file mode 100644 index 0000000..fe4fdf5 --- /dev/null +++ b/client/connection.h @@ -0,0 +1,41 @@ +#ifndef fooconnectionhfoo +#define fooconnectionhfoo + +#include <glib.h> +#include <linux/netfilter.h> +#include <libipq/libipq.h> +#include <gtk/gtk.h> + +#include "../daemon/common.h" +#include "main.h" + +typedef struct conn_info { +    unsigned long id; +    conn_direction_t direction; +    gchar device_in[IFNAMSIZ+1]; +    gchar device_out[IFNAMSIZ+1]; +    guint32 src_ip_address, dst_ip_address; +    guint protocol; +    guint16 port; +    guint8 icmp_type; +    long timestamp; +    gboolean broadcast; +     +    gchar* from_string; +    gchar* to_string; +    gchar* type_string; +    gchar* timestamp_string; +    gchar* port_string; + +    GtkTreeIter iter; +} conn_info_t; + +void conn_new(ipq_packet_msg_t *ci); +void conn_verdict(verdict_t v); +void conn_set_sticky(); + +extern guint total_conn_count; +extern guint queued_conn_count; +extern conn_info_t *conn_current; + +#endif diff --git a/client/daemon.c b/client/daemon.c new file mode 100644 index 0000000..fd69ef5 --- /dev/null +++ b/client/daemon.c @@ -0,0 +1,198 @@ +#include <sys/socket.h> +#include <sys/un.h> +#include <stdio.h> +#include <gtk/gtk.h> + +#include "daemon.h" +#include "../daemon/common.h" +#include "connection.h" + +int sock = -1; +GIOChannel *channel = NULL; +GSList *send_message_queue = NULL; + +static void dispatch(message_t *m) { +    switch (m->code) { +        case MSG_PACKET : +            conn_new((ipq_packet_msg_t*) (m+1)); +            break; +        default: +            break; +    } +    g_free(m); +} + +static gboolean recv_work() { +    static guint8 temp[sizeof(message_t)]; +    static message_t *m = NULL; +    static guint index = 0; + +    guint8 *p; +    size_t l; +    ssize_t r; + +    if (index < sizeof(message_t)) { +        p = temp + index; +        l = sizeof(message_t); +    } else { +        p = ((guint8*) m) + index; +        l = m->length+sizeof(message_t); +    } + +    if ((r = read(sock, p, l-index)) < 0) { +        g_message("read() failed, exiting."); +        gtk_main_quit(); +        return FALSE; +    } + +    index += r; + +    if (index == sizeof(message_t)) { +        m = g_malloc(((message_t*) temp)->length + sizeof(message_t)); +        memcpy(m, temp, sizeof(message_t)); +    } + +    if (index >= sizeof(message_t)) +        if (index == sizeof(message_t) + m->length) { +            dispatch(m); +            m = NULL; +            index = 0; +        } + +    return TRUE; +} + +static gboolean send_work() { +    static message_t *m = NULL; +    static int index = 0; +    guint l, r; +    guint8* p; + +    if (!m) { +        if (!send_message_queue) +            return FALSE; +         +        m = (message_t*) send_message_queue->data; +        send_message_queue = g_slist_remove(send_message_queue, m); +         +        index = 0; +    } + +    p = ((guint8*) m) + index; +    l = m->length + sizeof(message_t); + +    if ((r = write(sock, p, l - index)) < 0) { +        g_message("write() failed, exiting"); +        gtk_main_quit(); +        return FALSE; +    } + +    index += r; + + +    if (index >= l) { +        g_free(m); +        m = NULL; +        index = 0; +    } + + +    return m || send_message_queue; +} + + +static gboolean callback(GIOChannel *source, GIOCondition condition, gpointer data) { +     +    if (condition & G_IO_HUP) { +        gtk_main_quit(); +        return FALSE; +    } +     +    if (condition & G_IO_IN) +        return recv_work(); + +    if (condition & G_IO_OUT) +        return send_work(); + +    g_error("Huch?"); +    return FALSE; +} + +static int enqueue_message(message_t *m) { + +    send_message_queue = g_slist_append(send_message_queue, m); + +    if (!send_message_queue->next) +        g_io_add_watch(channel, G_IO_OUT, callback, NULL);     + +    return 0; +} + +static message_t* new_message(message_code_t code, guint8* p, guint s) { +    message_t* m; + +    if (!p) +        s = 0; +     +    m = g_malloc(sizeof(message_t) + s); + +    m->code = code; +    m->pid = getpid(); +    m->length = s; + +    if (p) +        memcpy(m+1, p, s); +     +    return m; +} + +static int unix_socket(gchar *p) { +    struct sockaddr_un addr; +    int sock; +                                                                                                                                                 +    if ((sock = socket(PF_LOCAL, SOCK_STREAM, 0)) < 0) { +        perror("socket(PF_LOCAL, SOCK_STREAM, 0)"); +        return -1; +    } + +    addr.sun_family = AF_LOCAL; +    strncpy(addr.sun_path, p, sizeof(addr.sun_path)); +    addr.sun_path[sizeof(addr.sun_path)-1] = 0; + +    if (connect(sock, (struct sockaddr *) &addr, SUN_LEN(&addr)) < 0) { +        perror("connect()"); +        return -1; +    } + +    return sock; +} + +int daemon_init() { + +    if ((sock = unix_socket(SOCKET_PATH)) < 0) +        return -1; + +    channel = g_io_channel_unix_new(sock); +    g_io_add_watch(channel, G_IO_IN|G_IO_HUP, callback, NULL); +     +    return 0; +} + + +void daemon_done() { +    if (sock >= 0) +        close(sock); + +    if (channel) +        g_io_channel_unref(channel); +} + + +void daemon_verdict(unsigned long id, guint r) { +    static guint8 buf[sizeof(unsigned long) + sizeof(guint32)]; + +    *((unsigned long*) &buf[0]) = id; +    *((guint32*) &buf[sizeof(unsigned long)]) = r; + +    enqueue_message(new_message(MSG_VERDICT, buf, sizeof(buf))); +} diff --git a/client/daemon.h b/client/daemon.h new file mode 100644 index 0000000..cf8be3e --- /dev/null +++ b/client/daemon.h @@ -0,0 +1,13 @@ +#ifndef foodaemonhfoo +#define foodaemonhfoo + +#include <glib.h> +#include <linux/netfilter.h> +#include <libipq/libipq.h> + +int daemon_init(); +void daemon_done(); + +void daemon_verdict(unsigned long id, guint r); + +#endif diff --git a/client/format.c b/client/format.c new file mode 100644 index 0000000..6cc6057 --- /dev/null +++ b/client/format.c @@ -0,0 +1,216 @@ +#include <netinet/in.h> +#include <stdio.h> +#include <netdb.h> +#include <sys/ioctl.h> +#include <net/if.h> +#include <unistd.h> +#include <sys/socket.h> +#include <arpa/inet.h> + + +#include "format.h" + +icmp_entry_t icmp_type_table[] = { +    { "Echo reply (PONG)", 0 }, +    { "Destination unreachable", 3 }, +    { "Source quench", 4 }, +    { "Redirect", 5 }, +    { "Echo request (PING)", 8 }, +    { "Router advertisement", 9 }, +    { "Timestamp request", 13 }, +    { "Information request", 15 }, +    { "Address mask reqeust", 17 }, +    { "Traceroute", 30 }, +    { "Domain name request", 37 }, +    { NULL, 0 } +     +}; + +icmp_entry_t icmp_code_table[] = { +    { "Packet filtered", 13 }, +    { "Network unreachable", 0 }, +    { "Host unreachable", 1 }, +    { "Protocol unreachable", 2 }, +    { "Port unreachable", 3 }, +    { "Network unknown", 6 }, +    { "Host unknown", 7 }, +    { "Network prohibited", 9 }, +    { "Host prohibited", 10 }, +    { NULL, 0 } +}; + +gchar* icmp_type_str(guint8 t) { +    gint i; +    for (i = 0; icmp_type_table[i].name; i++) +        if (icmp_type_table[i].value == t) +            return icmp_type_table[i].name; + +    return NULL; +} + +gchar* icmp_code_str(guint8 c) { +    gint i; +    for (i = 0; icmp_code_table[i].name; i++) +        if (icmp_code_table[i].value == c) +            return icmp_code_table[i].name; + +    return NULL; +} + +void fill_icmp_menu(GtkOptionMenu *om, gboolean w, guint8 def) { +    guint i, r = 0; +    GtkMenu *m; +    icmp_entry_t *table = w ? icmp_code_table : icmp_type_table; +     +    m = GTK_MENU(gtk_menu_new()); +    for (i = 0; table[i].name; i++) { +        GtkMenuItem *mi = GTK_MENU_ITEM(gtk_menu_item_new_with_label(table[i].name)); +        g_object_set_data(G_OBJECT(mi), "icmp_value", GUINT_TO_POINTER((guint) table[i].value)); +        gtk_menu_shell_append(GTK_MENU_SHELL(m), GTK_WIDGET(mi)); + +        if (table[i].value == def) +            r = i; +    } + +    gtk_option_menu_set_menu(om, GTK_WIDGET(m)); +    gtk_option_menu_set_history(om, r); +} + +void set_icmp_menu_entry(GtkOptionMenu *om, gboolean w, guint8 def) { +    guint r = 0, i; +    icmp_entry_t *table = w ? icmp_code_table : icmp_type_table; + +    for (i = 0; table[i].name; i++) +        if (table[i].value == def) { +            r = i; +            break; +        } +         +    gtk_option_menu_set_history(om, r); +} + + +gchar* format_ip_address(guint32 a) { +    static gchar txt[256]; + +    snprintf(txt, sizeof(txt), "%u.%u.%u.%u", a & 0xFF, (a >> 8) & 0xFF, (a >> 16) & 0xFF, a >> 24); +    return txt; +} + + +gchar* format_hostname(guint32 a) { +    static gchar txt[256]; +    struct hostent *he; + +    if ((he = gethostbyaddr(&a, 4, AF_INET))) { +        g_strlcpy(txt, he->h_name, sizeof(txt)); +        return txt; +    } else +        return format_ip_address(a);     +} + +GList *fill_interface_list() { +    GList *items = NULL; +    int sock, n; +    struct ifreq ifr[10]; +    struct ifconf ifc; +     +    if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) +        return NULL; + +    ifc.ifc_req = ifr; +    ifc.ifc_len = sizeof(ifr); + +    if (ioctl(sock, SIOCGIFCONF, &ifc) < 0) +        goto finish; + +    for (n = 0 ; n < ifc.ifc_len/sizeof(struct ifreq); n++) +        if (strcmp(ifr[n].ifr_name, "lo") != 0) +            items = g_list_prepend(items, g_strdup(ifr[n].ifr_name)); + +finish: +    close(sock); +    return items; +} + +void free_interface_list(GList *l) { +    while (l) { +        gchar *s = (gchar*) l->data; +        l = g_list_remove(l, s); +        g_free(s); +    }     +} + + +gboolean is_broadcast(guint32 ip) { +    int sock, n; +    struct ifreq ifr[10]; +    struct ifconf ifc; +    gboolean b = FALSE; +     +    if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) +        return FALSE; + +    ifc.ifc_req = ifr; +    ifc.ifc_len = sizeof(ifr); + +    if (ioctl(sock, SIOCGIFCONF, &ifc) < 0) { +        b = FALSE; +        goto finish; +    } +     +    for (n = 0 ; n < ifc.ifc_len/sizeof(struct ifreq); n++) { +        if (ioctl(sock, SIOCGIFBRDADDR, &ifc.ifc_req[n]) >= 0) { +            if (ip == ((struct sockaddr_in*) &ifc.ifc_req[n].ifr_broadaddr)->sin_addr.s_addr) { +                b = TRUE; +                break; +            } +        } +    } + +finish: +    close(sock); +    return b; +} + +gchar* format_host_range(const gchar *ip, gint bits) { +    struct in_addr a; +    guint32 i, f, t, m; +    static char txt[256]; +     +    if (!inet_aton(ip, &a)) +        return "<i>Invalid IP Address</i>"; + +    if (bits > 32) bits = 32; +    if (bits < 0) bits = 0; + +    if (bits == 32) { +        snprintf(txt, sizeof(txt), "Single host %s", ip); +        return txt; +    } else if (bits == 0) +        return "<i>Entire Internet</i>"; + +    i = a.s_addr; +     +    m = 0xFFFFFFFF << (32-bits); +     +    f = i & htonl(m); +    t = i | htonl(~m); + +    g_strlcpy(txt, inet_ntoa(*((struct in_addr*) &f)), sizeof(txt)); +    g_strlcat(txt, " - ", sizeof(txt)); +    g_strlcat(txt, inet_ntoa(*((struct in_addr*) &t)), sizeof(txt)); + +    return txt; +} + +gchar* format_verdict(verdict_t v, verdict_format_t t) { +    switch (v) { +        case VERDICT_QUERY: return t == FORMAT_USER ? "Query User" : "query"; +        case VERDICT_ACCEPT: return t == FORMAT_USER ? "Accept" : "accept"; +        case VERDICT_REJECT: return t == FORMAT_USER ? "Reject" : "reject"; +        case VERDICT_DROP: return t == FORMAT_USER ? "Drop" : "drop"; +    } + +    return "???"; +} diff --git a/client/format.h b/client/format.h new file mode 100644 index 0000000..a4453b3 --- /dev/null +++ b/client/format.h @@ -0,0 +1,34 @@ +#ifndef fooformathfoo +#define fooformathfoo + +#include <glib.h> +#include <gtk/gtk.h> + +#include "main.h" + +typedef struct icmp_entry { +    gchar *name; +    guint8 value; +} icmp_entry_t; + +typedef enum verdict_format { +    FORMAT_USER, +    FORMAT_XML +} verdict_format_t; + +extern icmp_entry_t icmp_type_table[]; +extern icmp_entry_t icmp_code_table[]; + +gchar* icmp_type_str(guint8 t); +gchar* icmp_code_str(guint8 c); +void fill_icmp_menu(GtkOptionMenu *om, gboolean w, guint8 def); +void set_icmp_menu_entry(GtkOptionMenu *om, gboolean w, guint8 def); +gchar* format_hostname(guint32 a); +gchar* format_ip_address(guint32 a); +GList *fill_interface_list(); +void free_interface_list(GList *l); +gboolean is_broadcast(guint32 ip); +gchar* format_host_range(const gchar *ip, gint bits); +gchar* format_verdict(verdict_t v, verdict_format_t t); + +#endif diff --git a/client/interface.c b/client/interface.c new file mode 100644 index 0000000..dd764e1 --- /dev/null +++ b/client/interface.c @@ -0,0 +1,2173 @@ +/* + * DO NOT EDIT THIS FILE - it is generated by Glade. + */ + +#ifdef HAVE_CONFIG_H +#  include <config.h> +#endif + +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <string.h> +#include <stdio.h> + +#include <gdk/gdkkeysyms.h> +#include <gtk/gtk.h> + +#include "callbacks.h" +#include "interface.h" +#include "support.h" + +#define GLADE_HOOKUP_OBJECT(component,widget,name) \ +  g_object_set_data_full (G_OBJECT (component), name, \ +    gtk_widget_ref (widget), (GDestroyNotify) gtk_widget_unref) + +#define GLADE_HOOKUP_OBJECT_NO_REF(component,widget,name) \ +  g_object_set_data (G_OBJECT (component), name, widget) + +GtkWidget* +create_connection_window (void) +{ +  GtkWidget *connection_window; +  GtkWidget *vbox2; +  GtkWidget *title_eventbox; +  GtkWidget *hbox27; +  GtkWidget *title_image; +  GtkWidget *title_label; +  GtkWidget *hseparator11; +  GtkWidget *hbox1; +  GtkWidget *table2; +  GtkWidget *interface_label; +  GtkWidget *type_label; +  GtkWidget *time_label; +  GtkWidget *id_label; +  GtkWidget *broadcast_label; +  GtkWidget *to_eventbox; +  GtkWidget *to_label; +  GtkWidget *from_eventbox; +  GtkWidget *from_label; +  GtkWidget *_label2; +  GtkWidget *_label3; +  GtkWidget *_label4; +  GtkWidget *_label5; +  GtkWidget *label15; +  GtkWidget *label16; +  GtkWidget *label20; +  GtkWidget *type_image; +  GtkWidget *hseparator12; +  GtkWidget *vbox23; +  GtkWidget *queue_check_button; +  GtkWidget *rule_check_button; +  GtkWidget *hseparator13; +  GtkWidget *hbuttonbox7; +  GtkWidget *accept_button; +  GtkWidget *alignment11; +  GtkWidget *hbox12; +  GtkWidget *image14; +  GtkWidget *label29; +  GtkWidget *reject_button; +  GtkWidget *alignment13; +  GtkWidget *hbox17; +  GtkWidget *image24; +  GtkWidget *label35; +  GtkWidget *drop_button; +  GtkWidget *alignment9; +  GtkWidget *hbox10; +  GtkWidget *image12; +  GtkWidget *label27; +  GtkTooltips *tooltips; + +  tooltips = gtk_tooltips_new (); + +  connection_window = gtk_window_new (GTK_WINDOW_TOPLEVEL); +  gtk_window_set_title (GTK_WINDOW (connection_window), _("FieryFilter Connection")); +  gtk_window_set_position (GTK_WINDOW (connection_window), GTK_WIN_POS_CENTER); +  gtk_window_set_resizable (GTK_WINDOW (connection_window), FALSE); + +  vbox2 = gtk_vbox_new (FALSE, 0); +  gtk_widget_show (vbox2); +  gtk_container_add (GTK_CONTAINER (connection_window), vbox2); + +  title_eventbox = gtk_event_box_new (); +  gtk_widget_show (title_eventbox); +  gtk_box_pack_start (GTK_BOX (vbox2), title_eventbox, FALSE, FALSE, 0); + +  hbox27 = gtk_hbox_new (FALSE, 5); +  gtk_widget_show (hbox27); +  gtk_container_add (GTK_CONTAINER (title_eventbox), hbox27); +  gtk_container_set_border_width (GTK_CONTAINER (hbox27), 5); + +  title_image = gtk_image_new_from_stock ("gtk-go-forward", GTK_ICON_SIZE_DND); +  gtk_widget_show (title_image); +  gtk_box_pack_start (GTK_BOX (hbox27), title_image, FALSE, FALSE, 0); + +  title_label = gtk_label_new (_("<span size=\"xx-large\" color=\"white\"><b>Outgoing Connection</b></span>")); +  gtk_widget_show (title_label); +  gtk_box_pack_start (GTK_BOX (hbox27), title_label, FALSE, FALSE, 0); +  gtk_label_set_use_markup (GTK_LABEL (title_label), TRUE); +  gtk_label_set_justify (GTK_LABEL (title_label), GTK_JUSTIFY_LEFT); +  gtk_misc_set_alignment (GTK_MISC (title_label), 0, 0.5); + +  hseparator11 = gtk_hseparator_new (); +  gtk_widget_show (hseparator11); +  gtk_box_pack_start (GTK_BOX (vbox2), hseparator11, FALSE, TRUE, 0); + +  hbox1 = gtk_hbox_new (FALSE, 10); +  gtk_widget_show (hbox1); +  gtk_box_pack_start (GTK_BOX (vbox2), hbox1, TRUE, TRUE, 0); +  gtk_container_set_border_width (GTK_CONTAINER (hbox1), 10); + +  table2 = gtk_table_new (7, 2, FALSE); +  gtk_widget_show (table2); +  gtk_box_pack_start (GTK_BOX (hbox1), table2, TRUE, TRUE, 0); +  gtk_table_set_row_spacings (GTK_TABLE (table2), 3); +  gtk_table_set_col_spacings (GTK_TABLE (table2), 5); + +  interface_label = gtk_label_new (_("eth0")); +  gtk_widget_show (interface_label); +  gtk_table_attach (GTK_TABLE (table2), interface_label, 1, 2, 1, 2, +                    (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), +                    (GtkAttachOptions) (GTK_EXPAND), 0, 0); +  GTK_WIDGET_SET_FLAGS (interface_label, GTK_CAN_FOCUS); +  gtk_label_set_justify (GTK_LABEL (interface_label), GTK_JUSTIFY_LEFT); +  gtk_label_set_selectable (GTK_LABEL (interface_label), TRUE); +  gtk_misc_set_alignment (GTK_MISC (interface_label), 0, 0.5); + +  type_label = gtk_label_new (_("tcp-80-http")); +  gtk_widget_show (type_label); +  gtk_table_attach (GTK_TABLE (table2), type_label, 1, 2, 0, 1, +                    (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), +                    (GtkAttachOptions) (GTK_EXPAND), 0, 0); +  GTK_WIDGET_SET_FLAGS (type_label, GTK_CAN_FOCUS); +  gtk_label_set_justify (GTK_LABEL (type_label), GTK_JUSTIFY_LEFT); +  gtk_label_set_selectable (GTK_LABEL (type_label), TRUE); +  gtk_misc_set_alignment (GTK_MISC (type_label), 0, 0.5); + +  time_label = gtk_label_new (_("label17")); +  gtk_widget_show (time_label); +  gtk_table_attach (GTK_TABLE (table2), time_label, 1, 2, 4, 5, +                    (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), +                    (GtkAttachOptions) (GTK_EXPAND), 0, 0); +  GTK_WIDGET_SET_FLAGS (time_label, GTK_CAN_FOCUS); +  gtk_label_set_justify (GTK_LABEL (time_label), GTK_JUSTIFY_LEFT); +  gtk_label_set_selectable (GTK_LABEL (time_label), TRUE); +  gtk_misc_set_alignment (GTK_MISC (time_label), 0, 0.5); + +  id_label = gtk_label_new (_("label18")); +  gtk_widget_show (id_label); +  gtk_table_attach (GTK_TABLE (table2), id_label, 1, 2, 5, 6, +                    (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), +                    (GtkAttachOptions) (GTK_EXPAND), 0, 0); +  GTK_WIDGET_SET_FLAGS (id_label, GTK_CAN_FOCUS); +  gtk_label_set_justify (GTK_LABEL (id_label), GTK_JUSTIFY_LEFT); +  gtk_label_set_selectable (GTK_LABEL (id_label), TRUE); +  gtk_misc_set_alignment (GTK_MISC (id_label), 0, 0.5); + +  broadcast_label = gtk_label_new (_("Yes")); +  gtk_widget_show (broadcast_label); +  gtk_table_attach (GTK_TABLE (table2), broadcast_label, 1, 2, 6, 7, +                    (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), +                    (GtkAttachOptions) (GTK_EXPAND), 0, 0); +  gtk_label_set_justify (GTK_LABEL (broadcast_label), GTK_JUSTIFY_LEFT); +  gtk_misc_set_alignment (GTK_MISC (broadcast_label), 0, 0.5); + +  to_eventbox = gtk_event_box_new (); +  gtk_widget_show (to_eventbox); +  gtk_table_attach (GTK_TABLE (table2), to_eventbox, 1, 2, 3, 4, +                    (GtkAttachOptions) (GTK_FILL), +                    (GtkAttachOptions) (GTK_FILL), 0, 0); +  gtk_tooltips_set_tip (tooltips, to_eventbox, _("addr"), NULL); + +  to_label = gtk_label_new (_("www.heise.de")); +  gtk_widget_show (to_label); +  gtk_container_add (GTK_CONTAINER (to_eventbox), to_label); +  GTK_WIDGET_SET_FLAGS (to_label, GTK_CAN_FOCUS); +  gtk_label_set_justify (GTK_LABEL (to_label), GTK_JUSTIFY_LEFT); +  gtk_label_set_selectable (GTK_LABEL (to_label), TRUE); +  gtk_misc_set_alignment (GTK_MISC (to_label), 0, 0.5); + +  from_eventbox = gtk_event_box_new (); +  gtk_widget_show (from_eventbox); +  gtk_table_attach (GTK_TABLE (table2), from_eventbox, 1, 2, 2, 3, +                    (GtkAttachOptions) (GTK_FILL), +                    (GtkAttachOptions) (GTK_FILL), 0, 0); +  gtk_tooltips_set_tip (tooltips, from_eventbox, _("addr"), NULL); + +  from_label = gtk_label_new (_("localhost")); +  gtk_widget_show (from_label); +  gtk_container_add (GTK_CONTAINER (from_eventbox), from_label); +  GTK_WIDGET_SET_FLAGS (from_label, GTK_CAN_FOCUS); +  gtk_label_set_justify (GTK_LABEL (from_label), GTK_JUSTIFY_LEFT); +  gtk_label_set_selectable (GTK_LABEL (from_label), TRUE); +  gtk_misc_set_alignment (GTK_MISC (from_label), 0, 0.5); + +  _label2 = gtk_label_new (_("<b>Type:</b>")); +  gtk_widget_show (_label2); +  gtk_table_attach (GTK_TABLE (table2), _label2, 0, 1, 0, 1, +                    (GtkAttachOptions) (GTK_FILL), +                    (GtkAttachOptions) (GTK_EXPAND), 0, 0); +  gtk_label_set_use_markup (GTK_LABEL (_label2), TRUE); +  gtk_label_set_justify (GTK_LABEL (_label2), GTK_JUSTIFY_LEFT); +  gtk_misc_set_alignment (GTK_MISC (_label2), 1, 0.5); + +  _label3 = gtk_label_new (_("<b>Device:</b>")); +  gtk_widget_show (_label3); +  gtk_table_attach (GTK_TABLE (table2), _label3, 0, 1, 1, 2, +                    (GtkAttachOptions) (GTK_FILL), +                    (GtkAttachOptions) (GTK_EXPAND), 0, 0); +  gtk_label_set_use_markup (GTK_LABEL (_label3), TRUE); +  gtk_label_set_justify (GTK_LABEL (_label3), GTK_JUSTIFY_LEFT); +  gtk_misc_set_alignment (GTK_MISC (_label3), 1, 0.5); + +  _label4 = gtk_label_new (_("<b>From:</b>")); +  gtk_widget_show (_label4); +  gtk_table_attach (GTK_TABLE (table2), _label4, 0, 1, 2, 3, +                    (GtkAttachOptions) (GTK_FILL), +                    (GtkAttachOptions) (GTK_EXPAND), 0, 0); +  gtk_label_set_use_markup (GTK_LABEL (_label4), TRUE); +  gtk_label_set_justify (GTK_LABEL (_label4), GTK_JUSTIFY_LEFT); +  gtk_misc_set_alignment (GTK_MISC (_label4), 1, 0.5); + +  _label5 = gtk_label_new (_("<b>To:</b>")); +  gtk_widget_show (_label5); +  gtk_table_attach (GTK_TABLE (table2), _label5, 0, 1, 3, 4, +                    (GtkAttachOptions) (GTK_FILL), +                    (GtkAttachOptions) (GTK_EXPAND), 0, 0); +  gtk_label_set_use_markup (GTK_LABEL (_label5), TRUE); +  gtk_label_set_justify (GTK_LABEL (_label5), GTK_JUSTIFY_LEFT); +  gtk_misc_set_alignment (GTK_MISC (_label5), 1, 0.5); + +  label15 = gtk_label_new (_("<b>Time:</b>")); +  gtk_widget_show (label15); +  gtk_table_attach (GTK_TABLE (table2), label15, 0, 1, 4, 5, +                    (GtkAttachOptions) (GTK_FILL), +                    (GtkAttachOptions) (GTK_EXPAND), 0, 0); +  gtk_label_set_use_markup (GTK_LABEL (label15), TRUE); +  gtk_label_set_justify (GTK_LABEL (label15), GTK_JUSTIFY_LEFT); +  gtk_misc_set_alignment (GTK_MISC (label15), 1, 0.5); + +  label16 = gtk_label_new (_("<b>ID#:</b>")); +  gtk_widget_show (label16); +  gtk_table_attach (GTK_TABLE (table2), label16, 0, 1, 5, 6, +                    (GtkAttachOptions) (GTK_FILL), +                    (GtkAttachOptions) (GTK_EXPAND), 0, 0); +  gtk_label_set_use_markup (GTK_LABEL (label16), TRUE); +  gtk_label_set_justify (GTK_LABEL (label16), GTK_JUSTIFY_LEFT); +  gtk_misc_set_alignment (GTK_MISC (label16), 1, 0.5); + +  label20 = gtk_label_new (_("<b>Broadcast:</b>")); +  gtk_widget_show (label20); +  gtk_table_attach (GTK_TABLE (table2), label20, 0, 1, 6, 7, +                    (GtkAttachOptions) (GTK_FILL), +                    (GtkAttachOptions) (GTK_EXPAND), 0, 0); +  gtk_label_set_use_markup (GTK_LABEL (label20), TRUE); +  gtk_label_set_justify (GTK_LABEL (label20), GTK_JUSTIFY_LEFT); +  gtk_misc_set_alignment (GTK_MISC (label20), 1, 0.5); + +  type_image = gtk_image_new_from_stock ("gtk-missing-image", GTK_ICON_SIZE_DND); +  gtk_widget_show (type_image); +  gtk_box_pack_end (GTK_BOX (hbox1), type_image, FALSE, FALSE, 0); +  gtk_misc_set_alignment (GTK_MISC (type_image), 0.5, 0); + +  hseparator12 = gtk_hseparator_new (); +  gtk_widget_show (hseparator12); +  gtk_box_pack_start (GTK_BOX (vbox2), hseparator12, FALSE, FALSE, 0); + +  vbox23 = gtk_vbox_new (FALSE, 0); +  gtk_widget_show (vbox23); +  gtk_box_pack_start (GTK_BOX (vbox2), vbox23, FALSE, FALSE, 0); +  gtk_container_set_border_width (GTK_CONTAINER (vbox23), 5); + +  queue_check_button = gtk_check_button_new_with_mnemonic (_("Apply decision to all _queued connections")); +  gtk_widget_show (queue_check_button); +  gtk_box_pack_start (GTK_BOX (vbox23), queue_check_button, FALSE, FALSE, 0); + +  rule_check_button = gtk_check_button_new_with_mnemonic (_("_Create a rule from this decision")); +  gtk_widget_show (rule_check_button); +  gtk_box_pack_start (GTK_BOX (vbox23), rule_check_button, FALSE, FALSE, 0); + +  hseparator13 = gtk_hseparator_new (); +  gtk_widget_show (hseparator13); +  gtk_box_pack_start (GTK_BOX (vbox2), hseparator13, FALSE, FALSE, 0); + +  hbuttonbox7 = gtk_hbutton_box_new (); +  gtk_widget_show (hbuttonbox7); +  gtk_box_pack_start (GTK_BOX (vbox2), hbuttonbox7, FALSE, FALSE, 0); +  gtk_container_set_border_width (GTK_CONTAINER (hbuttonbox7), 5); +  gtk_button_box_set_layout (GTK_BUTTON_BOX (hbuttonbox7), GTK_BUTTONBOX_END); +  gtk_box_set_spacing (GTK_BOX (hbuttonbox7), 5); + +  accept_button = gtk_button_new (); +  gtk_widget_show (accept_button); +  gtk_container_add (GTK_CONTAINER (hbuttonbox7), accept_button); +  GTK_WIDGET_SET_FLAGS (accept_button, GTK_CAN_DEFAULT); + +  alignment11 = gtk_alignment_new (0.5, 0.5, 0, 0); +  gtk_widget_show (alignment11); +  gtk_container_add (GTK_CONTAINER (accept_button), alignment11); + +  hbox12 = gtk_hbox_new (FALSE, 2); +  gtk_widget_show (hbox12); +  gtk_container_add (GTK_CONTAINER (alignment11), hbox12); + +  image14 = gtk_image_new_from_stock ("gtk-yes", GTK_ICON_SIZE_BUTTON); +  gtk_widget_show (image14); +  gtk_box_pack_start (GTK_BOX (hbox12), image14, FALSE, FALSE, 0); + +  label29 = gtk_label_new_with_mnemonic (_("_Accept")); +  gtk_widget_show (label29); +  gtk_box_pack_start (GTK_BOX (hbox12), label29, FALSE, FALSE, 0); +  gtk_label_set_justify (GTK_LABEL (label29), GTK_JUSTIFY_LEFT); + +  reject_button = gtk_button_new (); +  gtk_widget_show (reject_button); +  gtk_container_add (GTK_CONTAINER (hbuttonbox7), reject_button); +  GTK_WIDGET_SET_FLAGS (reject_button, GTK_CAN_DEFAULT); + +  alignment13 = gtk_alignment_new (0.5, 0.5, 0, 0); +  gtk_widget_show (alignment13); +  gtk_container_add (GTK_CONTAINER (reject_button), alignment13); + +  hbox17 = gtk_hbox_new (FALSE, 2); +  gtk_widget_show (hbox17); +  gtk_container_add (GTK_CONTAINER (alignment13), hbox17); + +  image24 = gtk_image_new_from_stock ("gtk-dialog-error", GTK_ICON_SIZE_BUTTON); +  gtk_widget_show (image24); +  gtk_box_pack_start (GTK_BOX (hbox17), image24, FALSE, FALSE, 0); + +  label35 = gtk_label_new_with_mnemonic (_("_Reject")); +  gtk_widget_show (label35); +  gtk_box_pack_start (GTK_BOX (hbox17), label35, FALSE, FALSE, 0); +  gtk_label_set_justify (GTK_LABEL (label35), GTK_JUSTIFY_LEFT); + +  drop_button = gtk_button_new (); +  gtk_widget_show (drop_button); +  gtk_container_add (GTK_CONTAINER (hbuttonbox7), drop_button); +  GTK_WIDGET_SET_FLAGS (drop_button, GTK_CAN_DEFAULT); + +  alignment9 = gtk_alignment_new (0.5, 0.5, 0, 0); +  gtk_widget_show (alignment9); +  gtk_container_add (GTK_CONTAINER (drop_button), alignment9); + +  hbox10 = gtk_hbox_new (FALSE, 2); +  gtk_widget_show (hbox10); +  gtk_container_add (GTK_CONTAINER (alignment9), hbox10); + +  image12 = gtk_image_new_from_stock ("gtk-delete", GTK_ICON_SIZE_BUTTON); +  gtk_widget_show (image12); +  gtk_box_pack_start (GTK_BOX (hbox10), image12, FALSE, FALSE, 0); + +  label27 = gtk_label_new_with_mnemonic (_("_Drop")); +  gtk_widget_show (label27); +  gtk_box_pack_start (GTK_BOX (hbox10), label27, FALSE, FALSE, 0); +  gtk_label_set_justify (GTK_LABEL (label27), GTK_JUSTIFY_LEFT); + +  g_signal_connect ((gpointer) connection_window, "delete_event", +                    G_CALLBACK (on_connection_window_delete_event), +                    NULL); +  g_signal_connect ((gpointer) accept_button, "clicked", +                    G_CALLBACK (on_accept_button_clicked), +                    NULL); +  g_signal_connect ((gpointer) reject_button, "clicked", +                    G_CALLBACK (on_reject_button_clicked), +                    NULL); +  g_signal_connect ((gpointer) drop_button, "clicked", +                    G_CALLBACK (on_drop_button_clicked), +                    NULL); + +  /* Store pointers to all widgets, for use by lookup_widget(). */ +  GLADE_HOOKUP_OBJECT_NO_REF (connection_window, connection_window, "connection_window"); +  GLADE_HOOKUP_OBJECT (connection_window, vbox2, "vbox2"); +  GLADE_HOOKUP_OBJECT (connection_window, title_eventbox, "title_eventbox"); +  GLADE_HOOKUP_OBJECT (connection_window, hbox27, "hbox27"); +  GLADE_HOOKUP_OBJECT (connection_window, title_image, "title_image"); +  GLADE_HOOKUP_OBJECT (connection_window, title_label, "title_label"); +  GLADE_HOOKUP_OBJECT (connection_window, hseparator11, "hseparator11"); +  GLADE_HOOKUP_OBJECT (connection_window, hbox1, "hbox1"); +  GLADE_HOOKUP_OBJECT (connection_window, table2, "table2"); +  GLADE_HOOKUP_OBJECT (connection_window, interface_label, "interface_label"); +  GLADE_HOOKUP_OBJECT (connection_window, type_label, "type_label"); +  GLADE_HOOKUP_OBJECT (connection_window, time_label, "time_label"); +  GLADE_HOOKUP_OBJECT (connection_window, id_label, "id_label"); +  GLADE_HOOKUP_OBJECT (connection_window, broadcast_label, "broadcast_label"); +  GLADE_HOOKUP_OBJECT (connection_window, to_eventbox, "to_eventbox"); +  GLADE_HOOKUP_OBJECT (connection_window, to_label, "to_label"); +  GLADE_HOOKUP_OBJECT (connection_window, from_eventbox, "from_eventbox"); +  GLADE_HOOKUP_OBJECT (connection_window, from_label, "from_label"); +  GLADE_HOOKUP_OBJECT (connection_window, _label2, "_label2"); +  GLADE_HOOKUP_OBJECT (connection_window, _label3, "_label3"); +  GLADE_HOOKUP_OBJECT (connection_window, _label4, "_label4"); +  GLADE_HOOKUP_OBJECT (connection_window, _label5, "_label5"); +  GLADE_HOOKUP_OBJECT (connection_window, label15, "label15"); +  GLADE_HOOKUP_OBJECT (connection_window, label16, "label16"); +  GLADE_HOOKUP_OBJECT (connection_window, label20, "label20"); +  GLADE_HOOKUP_OBJECT (connection_window, type_image, "type_image"); +  GLADE_HOOKUP_OBJECT (connection_window, hseparator12, "hseparator12"); +  GLADE_HOOKUP_OBJECT (connection_window, vbox23, "vbox23"); +  GLADE_HOOKUP_OBJECT (connection_window, queue_check_button, "queue_check_button"); +  GLADE_HOOKUP_OBJECT (connection_window, rule_check_button, "rule_check_button"); +  GLADE_HOOKUP_OBJECT (connection_window, hseparator13, "hseparator13"); +  GLADE_HOOKUP_OBJECT (connection_window, hbuttonbox7, "hbuttonbox7"); +  GLADE_HOOKUP_OBJECT (connection_window, accept_button, "accept_button"); +  GLADE_HOOKUP_OBJECT (connection_window, alignment11, "alignment11"); +  GLADE_HOOKUP_OBJECT (connection_window, hbox12, "hbox12"); +  GLADE_HOOKUP_OBJECT (connection_window, image14, "image14"); +  GLADE_HOOKUP_OBJECT (connection_window, label29, "label29"); +  GLADE_HOOKUP_OBJECT (connection_window, reject_button, "reject_button"); +  GLADE_HOOKUP_OBJECT (connection_window, alignment13, "alignment13"); +  GLADE_HOOKUP_OBJECT (connection_window, hbox17, "hbox17"); +  GLADE_HOOKUP_OBJECT (connection_window, image24, "image24"); +  GLADE_HOOKUP_OBJECT (connection_window, label35, "label35"); +  GLADE_HOOKUP_OBJECT (connection_window, drop_button, "drop_button"); +  GLADE_HOOKUP_OBJECT (connection_window, alignment9, "alignment9"); +  GLADE_HOOKUP_OBJECT (connection_window, hbox10, "hbox10"); +  GLADE_HOOKUP_OBJECT (connection_window, image12, "image12"); +  GLADE_HOOKUP_OBJECT (connection_window, label27, "label27"); +  GLADE_HOOKUP_OBJECT_NO_REF (connection_window, tooltips, "tooltips"); + +  gtk_widget_grab_focus (accept_button); +  gtk_widget_grab_default (accept_button); +  return connection_window; +} + +GtkWidget* +create_main_window (void) +{ +  GtkWidget *main_window; +  GtkWidget *vbox5; +  GtkWidget *menubar1; +  GtkWidget *menuitem4; +  GtkWidget *menuitem4_menu; +  GtkWidget *new_ruleset1; +  GtkWidget *image96; +  GtkWidget *open_ruleset; +  GtkWidget *image97; +  GtkWidget *save_ruleset; +  GtkWidget *image98; +  GtkWidget *separatormenuitem1; +  GtkWidget *quit; +  GtkWidget *menuitem5; +  GtkWidget *menuitem5_menu; +  GtkWidget *clear_log; +  GtkWidget *image99; +  GtkWidget *menuitem7; +  GtkWidget *menuitem7_menu; +  GtkWidget *about; +  GtkWidget *title_eventbox; +  GtkWidget *hbox28; +  GtkWidget *label76; +  GtkWidget *version_label; +  GtkWidget *hseparator7; +  GtkWidget *notebook1; +  GtkWidget *scrolledwindow2; +  GtkWidget *log_view; +  GtkWidget *label21; +  GtkWidget *vbox6; +  GtkWidget *frame1; +  GtkWidget *vbox7; +  GtkWidget *ruleset_check_button; +  GtkWidget *hbox13; +  GtkWidget *label30; +  GtkWidget *unmatch_optionmenu; +  GtkWidget *menu1; +  GtkWidget *default_query; +  GtkWidget *image114; +  GtkWidget *default_accept; +  GtkWidget *image115; +  GtkWidget *default_reject; +  GtkWidget *image116; +  GtkWidget *default_drop; +  GtkWidget *image117; +  GtkWidget *label23; +  GtkWidget *hbox21; +  GtkWidget *vbox18; +  GtkWidget *scrolledwindow3; +  GtkWidget *ruleset_view; +  GtkWidget *frame10; +  GtkWidget *table7; +  GtkWidget *label70; +  GtkWidget *label64; +  GtkWidget *label63; +  GtkWidget *rule_verdict_label; +  GtkWidget *rule_match_label; +  GtkWidget *rule_name_label; +  GtkWidget *rule_enabled_label; +  GtkWidget *label82; +  GtkWidget *label62; +  GtkWidget *vbox19; +  GtkWidget *properties_button; +  GtkWidget *hseparator4; +  GtkWidget *up_button; +  GtkWidget *down_button; +  GtkWidget *hseparator3; +  GtkWidget *add_button; +  GtkWidget *alignment6; +  GtkWidget *hbox7; +  GtkWidget *image9; +  GtkWidget *label24; +  GtkWidget *remove_button; +  GtkWidget *alignment7; +  GtkWidget *hbox8; +  GtkWidget *image10; +  GtkWidget *label25; +  GtkWidget *clear_button; +  GtkWidget *hseparator10; +  GtkWidget *advanced_button; +  GtkWidget *alignment16; +  GtkWidget *hbox25; +  GtkWidget *image59; +  GtkWidget *label79; +  GtkWidget *hseparator9; +  GtkWidget *commit_button; +  GtkWidget *alignment14; +  GtkWidget *hbox23; +  GtkWidget *image57; +  GtkWidget *label77; +  GtkWidget *label22; +  GtkWidget *vbox8; +  GtkWidget *frame2; +  GtkWidget *vbox9; +  GtkWidget *autoscroll_button; +  GtkWidget *sticky_button; +  GtkWidget *hbox22; +  GtkWidget *label66; +  GtkObject *log_spinbutton_adj; +  GtkWidget *log_spinbutton; +  GtkWidget *label36; +  GtkWidget *label32; +  GtkWidget *statusbar; +  GtkAccelGroup *accel_group; + +  accel_group = gtk_accel_group_new (); + +  main_window = gtk_window_new (GTK_WINDOW_TOPLEVEL); +  gtk_window_set_title (GTK_WINDOW (main_window), _("FieryFilter")); +  gtk_window_set_default_size (GTK_WINDOW (main_window), 620, 520); + +  vbox5 = gtk_vbox_new (FALSE, 0); +  gtk_widget_show (vbox5); +  gtk_container_add (GTK_CONTAINER (main_window), vbox5); + +  menubar1 = gtk_menu_bar_new (); +  gtk_widget_show (menubar1); +  gtk_box_pack_start (GTK_BOX (vbox5), menubar1, FALSE, FALSE, 0); + +  menuitem4 = gtk_menu_item_new_with_mnemonic (_("_File")); +  gtk_widget_show (menuitem4); +  gtk_container_add (GTK_CONTAINER (menubar1), menuitem4); + +  menuitem4_menu = gtk_menu_new (); +  gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem4), menuitem4_menu); + +  new_ruleset1 = gtk_image_menu_item_new_with_mnemonic (_("_New ruleset")); +  gtk_widget_show (new_ruleset1); +  gtk_container_add (GTK_CONTAINER (menuitem4_menu), new_ruleset1); + +  image96 = gtk_image_new_from_stock ("gtk-new", GTK_ICON_SIZE_MENU); +  gtk_widget_show (image96); +  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (new_ruleset1), image96); + +  open_ruleset = gtk_image_menu_item_new_with_mnemonic (_("_Open ruleset...")); +  gtk_widget_show (open_ruleset); +  gtk_container_add (GTK_CONTAINER (menuitem4_menu), open_ruleset); + +  image97 = gtk_image_new_from_stock ("gtk-open", GTK_ICON_SIZE_MENU); +  gtk_widget_show (image97); +  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (open_ruleset), image97); + +  save_ruleset = gtk_image_menu_item_new_with_mnemonic (_("_Save ruleset as...")); +  gtk_widget_show (save_ruleset); +  gtk_container_add (GTK_CONTAINER (menuitem4_menu), save_ruleset); + +  image98 = gtk_image_new_from_stock ("gtk-save-as", GTK_ICON_SIZE_MENU); +  gtk_widget_show (image98); +  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (save_ruleset), image98); + +  separatormenuitem1 = gtk_menu_item_new (); +  gtk_widget_show (separatormenuitem1); +  gtk_container_add (GTK_CONTAINER (menuitem4_menu), separatormenuitem1); +  gtk_widget_set_sensitive (separatormenuitem1, FALSE); + +  quit = gtk_image_menu_item_new_from_stock ("gtk-quit", accel_group); +  gtk_widget_show (quit); +  gtk_container_add (GTK_CONTAINER (menuitem4_menu), quit); + +  menuitem5 = gtk_menu_item_new_with_mnemonic (_("_Edit")); +  gtk_widget_show (menuitem5); +  gtk_container_add (GTK_CONTAINER (menubar1), menuitem5); + +  menuitem5_menu = gtk_menu_new (); +  gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem5), menuitem5_menu); + +  clear_log = gtk_image_menu_item_new_with_mnemonic (_("_Clear Log")); +  gtk_widget_show (clear_log); +  gtk_container_add (GTK_CONTAINER (menuitem5_menu), clear_log); + +  image99 = gtk_image_new_from_stock ("gtk-clear", GTK_ICON_SIZE_MENU); +  gtk_widget_show (image99); +  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (clear_log), image99); + +  menuitem7 = gtk_menu_item_new_with_mnemonic (_("_Help")); +  gtk_widget_show (menuitem7); +  gtk_container_add (GTK_CONTAINER (menubar1), menuitem7); + +  menuitem7_menu = gtk_menu_new (); +  gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem7), menuitem7_menu); + +  about = gtk_menu_item_new_with_mnemonic (_("_About")); +  gtk_widget_show (about); +  gtk_container_add (GTK_CONTAINER (menuitem7_menu), about); + +  title_eventbox = gtk_event_box_new (); +  gtk_widget_show (title_eventbox); +  gtk_box_pack_start (GTK_BOX (vbox5), title_eventbox, FALSE, FALSE, 0); + +  hbox28 = gtk_hbox_new (FALSE, 0); +  gtk_widget_show (hbox28); +  gtk_container_add (GTK_CONTAINER (title_eventbox), hbox28); + +  label76 = gtk_label_new (_("<b><span size=\"xx-large\" color=\"white\">FieryFilter Interactive Personal Firewall</span></b>")); +  gtk_widget_show (label76); +  gtk_box_pack_start (GTK_BOX (hbox28), label76, TRUE, TRUE, 0); +  gtk_label_set_use_markup (GTK_LABEL (label76), TRUE); +  gtk_label_set_justify (GTK_LABEL (label76), GTK_JUSTIFY_LEFT); +  gtk_misc_set_alignment (GTK_MISC (label76), 0, 0.5); +  gtk_misc_set_padding (GTK_MISC (label76), 10, 5); + +  version_label = gtk_label_new (_("<span color=\"white\"><i>Version 4711</i></span>")); +  gtk_widget_show (version_label); +  gtk_box_pack_start (GTK_BOX (hbox28), version_label, FALSE, FALSE, 0); +  gtk_label_set_use_markup (GTK_LABEL (version_label), TRUE); +  gtk_label_set_justify (GTK_LABEL (version_label), GTK_JUSTIFY_LEFT); +  gtk_misc_set_alignment (GTK_MISC (version_label), 0.5, 1); +  gtk_misc_set_padding (GTK_MISC (version_label), 10, 5); + +  hseparator7 = gtk_hseparator_new (); +  gtk_widget_show (hseparator7); +  gtk_box_pack_start (GTK_BOX (vbox5), hseparator7, FALSE, TRUE, 0); + +  notebook1 = gtk_notebook_new (); +  gtk_widget_show (notebook1); +  gtk_box_pack_start (GTK_BOX (vbox5), notebook1, TRUE, TRUE, 3); + +  scrolledwindow2 = gtk_scrolled_window_new (NULL, NULL); +  gtk_widget_show (scrolledwindow2); +  gtk_container_add (GTK_CONTAINER (notebook1), scrolledwindow2); +  gtk_container_set_border_width (GTK_CONTAINER (scrolledwindow2), 5); +  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow2), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); +  gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow2), GTK_SHADOW_IN); + +  log_view = gtk_tree_view_new (); +  gtk_widget_show (log_view); +  gtk_container_add (GTK_CONTAINER (scrolledwindow2), log_view); + +  label21 = gtk_label_new_with_mnemonic (_("Connection _Log")); +  gtk_widget_show (label21); +  gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook1), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook1), 0), label21); +  GTK_WIDGET_SET_FLAGS (label21, GTK_CAN_FOCUS); +  gtk_label_set_use_markup (GTK_LABEL (label21), TRUE); +  gtk_label_set_justify (GTK_LABEL (label21), GTK_JUSTIFY_LEFT); + +  vbox6 = gtk_vbox_new (FALSE, 10); +  gtk_widget_show (vbox6); +  gtk_container_add (GTK_CONTAINER (notebook1), vbox6); +  gtk_container_set_border_width (GTK_CONTAINER (vbox6), 5); + +  frame1 = gtk_frame_new (NULL); +  gtk_widget_show (frame1); +  gtk_box_pack_start (GTK_BOX (vbox6), frame1, FALSE, TRUE, 0); + +  vbox7 = gtk_vbox_new (FALSE, 5); +  gtk_widget_show (vbox7); +  gtk_container_add (GTK_CONTAINER (frame1), vbox7); +  gtk_container_set_border_width (GTK_CONTAINER (vbox7), 5); + +  ruleset_check_button = gtk_check_button_new_with_mnemonic (_("Respect r_uleset")); +  gtk_widget_show (ruleset_check_button); +  gtk_box_pack_start (GTK_BOX (vbox7), ruleset_check_button, FALSE, FALSE, 0); +  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ruleset_check_button), TRUE); + +  hbox13 = gtk_hbox_new (FALSE, 5); +  gtk_widget_show (hbox13); +  gtk_box_pack_start (GTK_BOX (vbox7), hbox13, FALSE, FALSE, 0); + +  label30 = gtk_label_new_with_mnemonic (_("Un_matched connections:")); +  gtk_widget_show (label30); +  gtk_box_pack_start (GTK_BOX (hbox13), label30, FALSE, FALSE, 0); +  gtk_label_set_justify (GTK_LABEL (label30), GTK_JUSTIFY_LEFT); + +  unmatch_optionmenu = gtk_option_menu_new (); +  gtk_widget_show (unmatch_optionmenu); +  gtk_box_pack_start (GTK_BOX (hbox13), unmatch_optionmenu, TRUE, TRUE, 0); +  gtk_option_menu_set_history (GTK_OPTION_MENU (unmatch_optionmenu), 1); + +  menu1 = gtk_menu_new (); + +  default_query = gtk_image_menu_item_new_with_mnemonic (_("Query User")); +  gtk_widget_show (default_query); +  gtk_container_add (GTK_CONTAINER (menu1), default_query); + +  image114 = gtk_image_new_from_stock ("gtk-dialog-question", GTK_ICON_SIZE_MENU); +  gtk_widget_show (image114); +  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (default_query), image114); + +  default_accept = gtk_image_menu_item_new_with_mnemonic (_("Accept")); +  gtk_widget_show (default_accept); +  gtk_container_add (GTK_CONTAINER (menu1), default_accept); + +  image115 = gtk_image_new_from_stock ("gtk-yes", GTK_ICON_SIZE_MENU); +  gtk_widget_show (image115); +  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (default_accept), image115); + +  default_reject = gtk_image_menu_item_new_with_mnemonic (_("Reject")); +  gtk_widget_show (default_reject); +  gtk_container_add (GTK_CONTAINER (menu1), default_reject); + +  image116 = gtk_image_new_from_stock ("gtk-dialog-error", GTK_ICON_SIZE_MENU); +  gtk_widget_show (image116); +  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (default_reject), image116); + +  default_drop = gtk_image_menu_item_new_with_mnemonic (_("Drop")); +  gtk_widget_show (default_drop); +  gtk_container_add (GTK_CONTAINER (menu1), default_drop); + +  image117 = gtk_image_new_from_stock ("gtk-delete", GTK_ICON_SIZE_MENU); +  gtk_widget_show (image117); +  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (default_drop), image117); + +  gtk_option_menu_set_menu (GTK_OPTION_MENU (unmatch_optionmenu), menu1); + +  label23 = gtk_label_new (_("<b>Firewall mode</b>")); +  gtk_widget_show (label23); +  gtk_frame_set_label_widget (GTK_FRAME (frame1), label23); +  gtk_label_set_use_markup (GTK_LABEL (label23), TRUE); +  gtk_label_set_justify (GTK_LABEL (label23), GTK_JUSTIFY_LEFT); + +  hbox21 = gtk_hbox_new (FALSE, 10); +  gtk_widget_show (hbox21); +  gtk_box_pack_start (GTK_BOX (vbox6), hbox21, TRUE, TRUE, 0); + +  vbox18 = gtk_vbox_new (FALSE, 5); +  gtk_widget_show (vbox18); +  gtk_box_pack_start (GTK_BOX (hbox21), vbox18, TRUE, TRUE, 0); + +  scrolledwindow3 = gtk_scrolled_window_new (NULL, NULL); +  gtk_widget_show (scrolledwindow3); +  gtk_box_pack_start (GTK_BOX (vbox18), scrolledwindow3, TRUE, TRUE, 0); +  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow3), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); +  gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow3), GTK_SHADOW_IN); + +  ruleset_view = gtk_tree_view_new (); +  gtk_widget_show (ruleset_view); +  gtk_container_add (GTK_CONTAINER (scrolledwindow3), ruleset_view); + +  frame10 = gtk_frame_new (NULL); +  gtk_widget_show (frame10); +  gtk_box_pack_start (GTK_BOX (vbox18), frame10, FALSE, FALSE, 0); + +  table7 = gtk_table_new (4, 2, FALSE); +  gtk_widget_show (table7); +  gtk_container_add (GTK_CONTAINER (frame10), table7); +  gtk_container_set_border_width (GTK_CONTAINER (table7), 5); +  gtk_table_set_row_spacings (GTK_TABLE (table7), 5); +  gtk_table_set_col_spacings (GTK_TABLE (table7), 5); + +  label70 = gtk_label_new (_("<b>Verdict:</b>")); +  gtk_widget_show (label70); +  gtk_table_attach (GTK_TABLE (table7), label70, 0, 1, 3, 4, +                    (GtkAttachOptions) (GTK_FILL), +                    (GtkAttachOptions) (0), 0, 0); +  gtk_label_set_use_markup (GTK_LABEL (label70), TRUE); +  gtk_label_set_justify (GTK_LABEL (label70), GTK_JUSTIFY_LEFT); +  gtk_misc_set_alignment (GTK_MISC (label70), 1, 0.5); + +  label64 = gtk_label_new (_("<b>Match:</b>")); +  gtk_widget_show (label64); +  gtk_table_attach (GTK_TABLE (table7), label64, 0, 1, 2, 3, +                    (GtkAttachOptions) (GTK_FILL), +                    (GtkAttachOptions) (0), 0, 0); +  gtk_label_set_use_markup (GTK_LABEL (label64), TRUE); +  gtk_label_set_justify (GTK_LABEL (label64), GTK_JUSTIFY_LEFT); +  gtk_misc_set_alignment (GTK_MISC (label64), 1, 0.5); + +  label63 = gtk_label_new (_("<b>Description:</b>")); +  gtk_widget_show (label63); +  gtk_table_attach (GTK_TABLE (table7), label63, 0, 1, 1, 2, +                    (GtkAttachOptions) (GTK_FILL), +                    (GtkAttachOptions) (0), 0, 0); +  gtk_label_set_use_markup (GTK_LABEL (label63), TRUE); +  gtk_label_set_justify (GTK_LABEL (label63), GTK_JUSTIFY_LEFT); +  gtk_misc_set_alignment (GTK_MISC (label63), 1, 0.5); + +  rule_verdict_label = gtk_label_new (_("label69")); +  gtk_widget_show (rule_verdict_label); +  gtk_table_attach (GTK_TABLE (table7), rule_verdict_label, 1, 2, 3, 4, +                    (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), +                    (GtkAttachOptions) (0), 0, 0); +  gtk_label_set_use_markup (GTK_LABEL (rule_verdict_label), TRUE); +  gtk_label_set_justify (GTK_LABEL (rule_verdict_label), GTK_JUSTIFY_LEFT); +  gtk_misc_set_alignment (GTK_MISC (rule_verdict_label), 0, 0.5); + +  rule_match_label = gtk_label_new (_("label68")); +  gtk_widget_show (rule_match_label); +  gtk_table_attach (GTK_TABLE (table7), rule_match_label, 1, 2, 2, 3, +                    (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), +                    (GtkAttachOptions) (0), 0, 0); +  gtk_label_set_use_markup (GTK_LABEL (rule_match_label), TRUE); +  gtk_label_set_justify (GTK_LABEL (rule_match_label), GTK_JUSTIFY_LEFT); +  gtk_misc_set_alignment (GTK_MISC (rule_match_label), 0, 0.5); + +  rule_name_label = gtk_label_new (_("label67")); +  gtk_widget_show (rule_name_label); +  gtk_table_attach (GTK_TABLE (table7), rule_name_label, 1, 2, 1, 2, +                    (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), +                    (GtkAttachOptions) (0), 0, 0); +  gtk_label_set_use_markup (GTK_LABEL (rule_name_label), TRUE); +  gtk_label_set_justify (GTK_LABEL (rule_name_label), GTK_JUSTIFY_LEFT); +  gtk_misc_set_alignment (GTK_MISC (rule_name_label), 0, 0.5); + +  rule_enabled_label = gtk_label_new (_("label80")); +  gtk_widget_show (rule_enabled_label); +  gtk_table_attach (GTK_TABLE (table7), rule_enabled_label, 1, 2, 0, 1, +                    (GtkAttachOptions) (GTK_FILL), +                    (GtkAttachOptions) (0), 0, 0); +  gtk_label_set_use_markup (GTK_LABEL (rule_enabled_label), TRUE); +  gtk_label_set_justify (GTK_LABEL (rule_enabled_label), GTK_JUSTIFY_LEFT); +  gtk_misc_set_alignment (GTK_MISC (rule_enabled_label), 0, 0.5); + +  label82 = gtk_label_new (_("<b>Enabled:</b>")); +  gtk_widget_show (label82); +  gtk_table_attach (GTK_TABLE (table7), label82, 0, 1, 0, 1, +                    (GtkAttachOptions) (GTK_FILL), +                    (GtkAttachOptions) (0), 0, 0); +  gtk_label_set_use_markup (GTK_LABEL (label82), TRUE); +  gtk_label_set_justify (GTK_LABEL (label82), GTK_JUSTIFY_LEFT); +  gtk_misc_set_alignment (GTK_MISC (label82), 1, 0.5); + +  label62 = gtk_label_new (_("<b>Rule</b>")); +  gtk_widget_show (label62); +  gtk_frame_set_label_widget (GTK_FRAME (frame10), label62); +  gtk_label_set_use_markup (GTK_LABEL (label62), TRUE); +  gtk_label_set_justify (GTK_LABEL (label62), GTK_JUSTIFY_LEFT); + +  vbox19 = gtk_vbox_new (FALSE, 5); +  gtk_widget_show (vbox19); +  gtk_box_pack_start (GTK_BOX (hbox21), vbox19, FALSE, FALSE, 0); + +  properties_button = gtk_button_new_from_stock ("gtk-properties"); +  gtk_widget_show (properties_button); +  gtk_box_pack_start (GTK_BOX (vbox19), properties_button, FALSE, FALSE, 0); +  GTK_WIDGET_SET_FLAGS (properties_button, GTK_CAN_DEFAULT); + +  hseparator4 = gtk_hseparator_new (); +  gtk_widget_show (hseparator4); +  gtk_box_pack_start (GTK_BOX (vbox19), hseparator4, FALSE, TRUE, 5); + +  up_button = gtk_button_new_from_stock ("gtk-go-up"); +  gtk_widget_show (up_button); +  gtk_box_pack_start (GTK_BOX (vbox19), up_button, FALSE, FALSE, 0); +  GTK_WIDGET_SET_FLAGS (up_button, GTK_CAN_DEFAULT); + +  down_button = gtk_button_new_from_stock ("gtk-go-down"); +  gtk_widget_show (down_button); +  gtk_box_pack_start (GTK_BOX (vbox19), down_button, FALSE, FALSE, 0); +  GTK_WIDGET_SET_FLAGS (down_button, GTK_CAN_DEFAULT); + +  hseparator3 = gtk_hseparator_new (); +  gtk_widget_show (hseparator3); +  gtk_box_pack_start (GTK_BOX (vbox19), hseparator3, FALSE, TRUE, 5); + +  add_button = gtk_button_new (); +  gtk_widget_show (add_button); +  gtk_box_pack_start (GTK_BOX (vbox19), add_button, FALSE, FALSE, 0); +  GTK_WIDGET_SET_FLAGS (add_button, GTK_CAN_DEFAULT); + +  alignment6 = gtk_alignment_new (0.5, 0.5, 0, 0); +  gtk_widget_show (alignment6); +  gtk_container_add (GTK_CONTAINER (add_button), alignment6); + +  hbox7 = gtk_hbox_new (FALSE, 2); +  gtk_widget_show (hbox7); +  gtk_container_add (GTK_CONTAINER (alignment6), hbox7); + +  image9 = gtk_image_new_from_stock ("gtk-add", GTK_ICON_SIZE_BUTTON); +  gtk_widget_show (image9); +  gtk_box_pack_start (GTK_BOX (hbox7), image9, FALSE, FALSE, 0); + +  label24 = gtk_label_new_with_mnemonic (_("_Add new rule")); +  gtk_widget_show (label24); +  gtk_box_pack_start (GTK_BOX (hbox7), label24, FALSE, FALSE, 0); +  gtk_label_set_justify (GTK_LABEL (label24), GTK_JUSTIFY_LEFT); + +  remove_button = gtk_button_new (); +  gtk_widget_show (remove_button); +  gtk_box_pack_start (GTK_BOX (vbox19), remove_button, FALSE, FALSE, 0); +  GTK_WIDGET_SET_FLAGS (remove_button, GTK_CAN_DEFAULT); + +  alignment7 = gtk_alignment_new (0.5, 0.5, 0, 0); +  gtk_widget_show (alignment7); +  gtk_container_add (GTK_CONTAINER (remove_button), alignment7); + +  hbox8 = gtk_hbox_new (FALSE, 2); +  gtk_widget_show (hbox8); +  gtk_container_add (GTK_CONTAINER (alignment7), hbox8); + +  image10 = gtk_image_new_from_stock ("gtk-remove", GTK_ICON_SIZE_BUTTON); +  gtk_widget_show (image10); +  gtk_box_pack_start (GTK_BOX (hbox8), image10, FALSE, FALSE, 0); + +  label25 = gtk_label_new_with_mnemonic (_("_Remove rule")); +  gtk_widget_show (label25); +  gtk_box_pack_start (GTK_BOX (hbox8), label25, FALSE, FALSE, 0); +  gtk_label_set_justify (GTK_LABEL (label25), GTK_JUSTIFY_LEFT); + +  clear_button = gtk_button_new_from_stock ("gtk-clear"); +  gtk_widget_show (clear_button); +  gtk_box_pack_start (GTK_BOX (vbox19), clear_button, FALSE, FALSE, 0); +  GTK_WIDGET_SET_FLAGS (clear_button, GTK_CAN_DEFAULT); + +  hseparator10 = gtk_hseparator_new (); +  gtk_widget_show (hseparator10); +  gtk_box_pack_start (GTK_BOX (vbox19), hseparator10, FALSE, FALSE, 5); + +  advanced_button = gtk_button_new (); +  gtk_widget_show (advanced_button); +  gtk_box_pack_start (GTK_BOX (vbox19), advanced_button, FALSE, FALSE, 0); + +  alignment16 = gtk_alignment_new (0.5, 0.5, 0, 0); +  gtk_widget_show (alignment16); +  gtk_container_add (GTK_CONTAINER (advanced_button), alignment16); + +  hbox25 = gtk_hbox_new (FALSE, 2); +  gtk_widget_show (hbox25); +  gtk_container_add (GTK_CONTAINER (alignment16), hbox25); + +  image59 = gtk_image_new_from_stock ("gtk-preferences", GTK_ICON_SIZE_BUTTON); +  gtk_widget_show (image59); +  gtk_box_pack_start (GTK_BOX (hbox25), image59, FALSE, FALSE, 0); + +  label79 = gtk_label_new_with_mnemonic (_("_Advanced")); +  gtk_widget_show (label79); +  gtk_box_pack_start (GTK_BOX (hbox25), label79, FALSE, FALSE, 0); +  gtk_label_set_justify (GTK_LABEL (label79), GTK_JUSTIFY_LEFT); + +  hseparator9 = gtk_hseparator_new (); +  gtk_widget_show (hseparator9); +  gtk_box_pack_start (GTK_BOX (vbox19), hseparator9, FALSE, FALSE, 5); + +  commit_button = gtk_button_new (); +  gtk_widget_show (commit_button); +  gtk_box_pack_start (GTK_BOX (vbox19), commit_button, FALSE, FALSE, 0); +  GTK_WIDGET_SET_FLAGS (commit_button, GTK_CAN_DEFAULT); + +  alignment14 = gtk_alignment_new (0.5, 0.5, 0, 0); +  gtk_widget_show (alignment14); +  gtk_container_add (GTK_CONTAINER (commit_button), alignment14); + +  hbox23 = gtk_hbox_new (FALSE, 2); +  gtk_widget_show (hbox23); +  gtk_container_add (GTK_CONTAINER (alignment14), hbox23); + +  image57 = gtk_image_new_from_stock ("gtk-execute", GTK_ICON_SIZE_BUTTON); +  gtk_widget_show (image57); +  gtk_box_pack_start (GTK_BOX (hbox23), image57, FALSE, FALSE, 0); + +  label77 = gtk_label_new_with_mnemonic (_("Co_mmit")); +  gtk_widget_show (label77); +  gtk_box_pack_start (GTK_BOX (hbox23), label77, FALSE, FALSE, 0); +  gtk_label_set_justify (GTK_LABEL (label77), GTK_JUSTIFY_LEFT); + +  label22 = gtk_label_new_with_mnemonic (_("Firewall _Rules")); +  gtk_widget_show (label22); +  gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook1), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook1), 1), label22); +  gtk_label_set_use_markup (GTK_LABEL (label22), TRUE); +  gtk_label_set_justify (GTK_LABEL (label22), GTK_JUSTIFY_LEFT); + +  vbox8 = gtk_vbox_new (FALSE, 10); +  gtk_widget_show (vbox8); +  gtk_container_add (GTK_CONTAINER (notebook1), vbox8); +  gtk_container_set_border_width (GTK_CONTAINER (vbox8), 5); + +  frame2 = gtk_frame_new (NULL); +  gtk_widget_show (frame2); +  gtk_box_pack_start (GTK_BOX (vbox8), frame2, FALSE, FALSE, 0); + +  vbox9 = gtk_vbox_new (FALSE, 5); +  gtk_widget_show (vbox9); +  gtk_container_add (GTK_CONTAINER (frame2), vbox9); +  gtk_container_set_border_width (GTK_CONTAINER (vbox9), 5); + +  autoscroll_button = gtk_check_button_new_with_mnemonic (_("_Automatic scrolling to newly added log entries")); +  gtk_widget_show (autoscroll_button); +  gtk_box_pack_start (GTK_BOX (vbox9), autoscroll_button, FALSE, FALSE, 0); +  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (autoscroll_button), TRUE); + +  sticky_button = gtk_check_button_new_with_mnemonic (_("Popup window is _sticky (visible on all desktops)")); +  gtk_widget_show (sticky_button); +  gtk_box_pack_start (GTK_BOX (vbox9), sticky_button, FALSE, FALSE, 0); +  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sticky_button), TRUE); + +  hbox22 = gtk_hbox_new (FALSE, 5); +  gtk_widget_show (hbox22); +  gtk_box_pack_start (GTK_BOX (vbox9), hbox22, TRUE, TRUE, 0); + +  label66 = gtk_label_new (_("Maximum number of Log entries:")); +  gtk_widget_show (label66); +  gtk_box_pack_start (GTK_BOX (hbox22), label66, FALSE, FALSE, 0); +  gtk_label_set_justify (GTK_LABEL (label66), GTK_JUSTIFY_LEFT); + +  log_spinbutton_adj = gtk_adjustment_new (100, 10, 999, 1, 10, 10); +  log_spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (log_spinbutton_adj), 1, 0); +  gtk_widget_show (log_spinbutton); +  gtk_box_pack_start (GTK_BOX (hbox22), log_spinbutton, FALSE, TRUE, 0); + +  label36 = gtk_label_new (_("<b>User Interface</b>")); +  gtk_widget_show (label36); +  gtk_frame_set_label_widget (GTK_FRAME (frame2), label36); +  gtk_label_set_use_markup (GTK_LABEL (label36), TRUE); +  gtk_label_set_justify (GTK_LABEL (label36), GTK_JUSTIFY_LEFT); + +  label32 = gtk_label_new_with_mnemonic (_("_Options")); +  gtk_widget_show (label32); +  gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook1), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook1), 2), label32); +  gtk_label_set_justify (GTK_LABEL (label32), GTK_JUSTIFY_LEFT); + +  statusbar = gtk_statusbar_new (); +  gtk_widget_show (statusbar); +  gtk_box_pack_start (GTK_BOX (vbox5), statusbar, FALSE, FALSE, 0); + +  g_signal_connect ((gpointer) main_window, "delete_event", +                    G_CALLBACK (on_main_window_delete_event), +                    NULL); +  g_signal_connect ((gpointer) new_ruleset1, "activate", +                    G_CALLBACK (on_new_ruleset_activate), +                    NULL); +  g_signal_connect ((gpointer) open_ruleset, "activate", +                    G_CALLBACK (on_open_ruleset_activate), +                    NULL); +  g_signal_connect ((gpointer) save_ruleset, "activate", +                    G_CALLBACK (on_save_ruleset_activate), +                    NULL); +  g_signal_connect ((gpointer) quit, "activate", +                    G_CALLBACK (on_quit_activate), +                    NULL); +  g_signal_connect ((gpointer) clear_log, "activate", +                    G_CALLBACK (on_clear_log_activate), +                    NULL); +  g_signal_connect ((gpointer) about, "activate", +                    G_CALLBACK (on_about_activate), +                    NULL); +  g_signal_connect ((gpointer) ruleset_check_button, "toggled", +                    G_CALLBACK (on_ruleset_check_button_toggled), +                    NULL); +  g_signal_connect ((gpointer) unmatch_optionmenu, "changed", +                    G_CALLBACK (on_unmatch_optionmenu_changed), +                    NULL); +  g_signal_connect ((gpointer) ruleset_view, "cursor_changed", +                    G_CALLBACK (on_ruleset_view_cursor_changed), +                    NULL); +  g_signal_connect ((gpointer) properties_button, "clicked", +                    G_CALLBACK (on_properties_button_clicked), +                    NULL); +  g_signal_connect ((gpointer) up_button, "clicked", +                    G_CALLBACK (on_up_button_clicked), +                    NULL); +  g_signal_connect ((gpointer) down_button, "clicked", +                    G_CALLBACK (on_down_button_clicked), +                    NULL); +  g_signal_connect ((gpointer) add_button, "clicked", +                    G_CALLBACK (on_add_button_clicked), +                    NULL); +  g_signal_connect ((gpointer) remove_button, "clicked", +                    G_CALLBACK (on_remove_button_clicked), +                    NULL); +  g_signal_connect ((gpointer) clear_button, "clicked", +                    G_CALLBACK (on_clear_button_clicked), +                    NULL); +  g_signal_connect ((gpointer) advanced_button, "clicked", +                    G_CALLBACK (on_advanced_button_clicked), +                    NULL); +  g_signal_connect ((gpointer) commit_button, "clicked", +                    G_CALLBACK (on_commit_button_clicked), +                    NULL); +  g_signal_connect ((gpointer) sticky_button, "toggled", +                    G_CALLBACK (on_sticky_button_toggled), +                    NULL); +  g_signal_connect ((gpointer) log_spinbutton, "value_changed", +                    G_CALLBACK (on_log_spinbutton_value_changed), +                    NULL); + +  gtk_label_set_mnemonic_widget (GTK_LABEL (label30), unmatch_optionmenu); + +  /* Store pointers to all widgets, for use by lookup_widget(). */ +  GLADE_HOOKUP_OBJECT_NO_REF (main_window, main_window, "main_window"); +  GLADE_HOOKUP_OBJECT (main_window, vbox5, "vbox5"); +  GLADE_HOOKUP_OBJECT (main_window, menubar1, "menubar1"); +  GLADE_HOOKUP_OBJECT (main_window, menuitem4, "menuitem4"); +  GLADE_HOOKUP_OBJECT (main_window, menuitem4_menu, "menuitem4_menu"); +  GLADE_HOOKUP_OBJECT (main_window, new_ruleset1, "new_ruleset1"); +  GLADE_HOOKUP_OBJECT (main_window, image96, "image96"); +  GLADE_HOOKUP_OBJECT (main_window, open_ruleset, "open_ruleset"); +  GLADE_HOOKUP_OBJECT (main_window, image97, "image97"); +  GLADE_HOOKUP_OBJECT (main_window, save_ruleset, "save_ruleset"); +  GLADE_HOOKUP_OBJECT (main_window, image98, "image98"); +  GLADE_HOOKUP_OBJECT (main_window, separatormenuitem1, "separatormenuitem1"); +  GLADE_HOOKUP_OBJECT (main_window, quit, "quit"); +  GLADE_HOOKUP_OBJECT (main_window, menuitem5, "menuitem5"); +  GLADE_HOOKUP_OBJECT (main_window, menuitem5_menu, "menuitem5_menu"); +  GLADE_HOOKUP_OBJECT (main_window, clear_log, "clear_log"); +  GLADE_HOOKUP_OBJECT (main_window, image99, "image99"); +  GLADE_HOOKUP_OBJECT (main_window, menuitem7, "menuitem7"); +  GLADE_HOOKUP_OBJECT (main_window, menuitem7_menu, "menuitem7_menu"); +  GLADE_HOOKUP_OBJECT (main_window, about, "about"); +  GLADE_HOOKUP_OBJECT (main_window, title_eventbox, "title_eventbox"); +  GLADE_HOOKUP_OBJECT (main_window, hbox28, "hbox28"); +  GLADE_HOOKUP_OBJECT (main_window, label76, "label76"); +  GLADE_HOOKUP_OBJECT (main_window, version_label, "version_label"); +  GLADE_HOOKUP_OBJECT (main_window, hseparator7, "hseparator7"); +  GLADE_HOOKUP_OBJECT (main_window, notebook1, "notebook1"); +  GLADE_HOOKUP_OBJECT (main_window, scrolledwindow2, "scrolledwindow2"); +  GLADE_HOOKUP_OBJECT (main_window, log_view, "log_view"); +  GLADE_HOOKUP_OBJECT (main_window, label21, "label21"); +  GLADE_HOOKUP_OBJECT (main_window, vbox6, "vbox6"); +  GLADE_HOOKUP_OBJECT (main_window, frame1, "frame1"); +  GLADE_HOOKUP_OBJECT (main_window, vbox7, "vbox7"); +  GLADE_HOOKUP_OBJECT (main_window, ruleset_check_button, "ruleset_check_button"); +  GLADE_HOOKUP_OBJECT (main_window, hbox13, "hbox13"); +  GLADE_HOOKUP_OBJECT (main_window, label30, "label30"); +  GLADE_HOOKUP_OBJECT (main_window, unmatch_optionmenu, "unmatch_optionmenu"); +  GLADE_HOOKUP_OBJECT (main_window, menu1, "menu1"); +  GLADE_HOOKUP_OBJECT (main_window, default_query, "default_query"); +  GLADE_HOOKUP_OBJECT (main_window, image114, "image114"); +  GLADE_HOOKUP_OBJECT (main_window, default_accept, "default_accept"); +  GLADE_HOOKUP_OBJECT (main_window, image115, "image115"); +  GLADE_HOOKUP_OBJECT (main_window, default_reject, "default_reject"); +  GLADE_HOOKUP_OBJECT (main_window, image116, "image116"); +  GLADE_HOOKUP_OBJECT (main_window, default_drop, "default_drop"); +  GLADE_HOOKUP_OBJECT (main_window, image117, "image117"); +  GLADE_HOOKUP_OBJECT (main_window, label23, "label23"); +  GLADE_HOOKUP_OBJECT (main_window, hbox21, "hbox21"); +  GLADE_HOOKUP_OBJECT (main_window, vbox18, "vbox18"); +  GLADE_HOOKUP_OBJECT (main_window, scrolledwindow3, "scrolledwindow3"); +  GLADE_HOOKUP_OBJECT (main_window, ruleset_view, "ruleset_view"); +  GLADE_HOOKUP_OBJECT (main_window, frame10, "frame10"); +  GLADE_HOOKUP_OBJECT (main_window, table7, "table7"); +  GLADE_HOOKUP_OBJECT (main_window, label70, "label70"); +  GLADE_HOOKUP_OBJECT (main_window, label64, "label64"); +  GLADE_HOOKUP_OBJECT (main_window, label63, "label63"); +  GLADE_HOOKUP_OBJECT (main_window, rule_verdict_label, "rule_verdict_label"); +  GLADE_HOOKUP_OBJECT (main_window, rule_match_label, "rule_match_label"); +  GLADE_HOOKUP_OBJECT (main_window, rule_name_label, "rule_name_label"); +  GLADE_HOOKUP_OBJECT (main_window, rule_enabled_label, "rule_enabled_label"); +  GLADE_HOOKUP_OBJECT (main_window, label82, "label82"); +  GLADE_HOOKUP_OBJECT (main_window, label62, "label62"); +  GLADE_HOOKUP_OBJECT (main_window, vbox19, "vbox19"); +  GLADE_HOOKUP_OBJECT (main_window, properties_button, "properties_button"); +  GLADE_HOOKUP_OBJECT (main_window, hseparator4, "hseparator4"); +  GLADE_HOOKUP_OBJECT (main_window, up_button, "up_button"); +  GLADE_HOOKUP_OBJECT (main_window, down_button, "down_button"); +  GLADE_HOOKUP_OBJECT (main_window, hseparator3, "hseparator3"); +  GLADE_HOOKUP_OBJECT (main_window, add_button, "add_button"); +  GLADE_HOOKUP_OBJECT (main_window, alignment6, "alignment6"); +  GLADE_HOOKUP_OBJECT (main_window, hbox7, "hbox7"); +  GLADE_HOOKUP_OBJECT (main_window, image9, "image9"); +  GLADE_HOOKUP_OBJECT (main_window, label24, "label24"); +  GLADE_HOOKUP_OBJECT (main_window, remove_button, "remove_button"); +  GLADE_HOOKUP_OBJECT (main_window, alignment7, "alignment7"); +  GLADE_HOOKUP_OBJECT (main_window, hbox8, "hbox8"); +  GLADE_HOOKUP_OBJECT (main_window, image10, "image10"); +  GLADE_HOOKUP_OBJECT (main_window, label25, "label25"); +  GLADE_HOOKUP_OBJECT (main_window, clear_button, "clear_button"); +  GLADE_HOOKUP_OBJECT (main_window, hseparator10, "hseparator10"); +  GLADE_HOOKUP_OBJECT (main_window, advanced_button, "advanced_button"); +  GLADE_HOOKUP_OBJECT (main_window, alignment16, "alignment16"); +  GLADE_HOOKUP_OBJECT (main_window, hbox25, "hbox25"); +  GLADE_HOOKUP_OBJECT (main_window, image59, "image59"); +  GLADE_HOOKUP_OBJECT (main_window, label79, "label79"); +  GLADE_HOOKUP_OBJECT (main_window, hseparator9, "hseparator9"); +  GLADE_HOOKUP_OBJECT (main_window, commit_button, "commit_button"); +  GLADE_HOOKUP_OBJECT (main_window, alignment14, "alignment14"); +  GLADE_HOOKUP_OBJECT (main_window, hbox23, "hbox23"); +  GLADE_HOOKUP_OBJECT (main_window, image57, "image57"); +  GLADE_HOOKUP_OBJECT (main_window, label77, "label77"); +  GLADE_HOOKUP_OBJECT (main_window, label22, "label22"); +  GLADE_HOOKUP_OBJECT (main_window, vbox8, "vbox8"); +  GLADE_HOOKUP_OBJECT (main_window, frame2, "frame2"); +  GLADE_HOOKUP_OBJECT (main_window, vbox9, "vbox9"); +  GLADE_HOOKUP_OBJECT (main_window, autoscroll_button, "autoscroll_button"); +  GLADE_HOOKUP_OBJECT (main_window, sticky_button, "sticky_button"); +  GLADE_HOOKUP_OBJECT (main_window, hbox22, "hbox22"); +  GLADE_HOOKUP_OBJECT (main_window, label66, "label66"); +  GLADE_HOOKUP_OBJECT (main_window, log_spinbutton, "log_spinbutton"); +  GLADE_HOOKUP_OBJECT (main_window, label36, "label36"); +  GLADE_HOOKUP_OBJECT (main_window, label32, "label32"); +  GLADE_HOOKUP_OBJECT (main_window, statusbar, "statusbar"); + +  gtk_widget_grab_default (commit_button); +  gtk_window_add_accel_group (GTK_WINDOW (main_window), accel_group); + +  return main_window; +} + +GtkWidget* +create_rule_window (void) +{ +  GtkWidget *rule_window; +  GtkWidget *vbox11; +  GtkWidget *desc_eventbox; +  GtkWidget *desc_label; +  GtkWidget *hseparator2; +  GtkWidget *notebook2; +  GtkWidget *vbox12; +  GtkWidget *label60; +  GtkWidget *desc_entry; +  GtkWidget *label72; +  GtkWidget *rule_optionmenu; +  GtkWidget *menu5; +  GtkWidget *imagemenuitem1; +  GtkWidget *image110; +  GtkWidget *imagemenuitem2; +  GtkWidget *image111; +  GtkWidget *imagemenuitem3; +  GtkWidget *image112; +  GtkWidget *imagemenuitem4; +  GtkWidget *image113; +  GtkWidget *label56; +  GtkWidget *vbox16; +  GtkWidget *frame4; +  GtkWidget *hbox18; +  GtkWidget *direction_label; +  GtkWidget *direction_optionmenu; +  GtkWidget *menu4; +  GtkWidget *incoming_menu_item; +  GtkWidget *image37; +  GtkWidget *outgoing_menu_item; +  GtkWidget *image38; +  GtkWidget *passing_menu_item; +  GtkWidget *match_direction_checkbutton; +  GtkWidget *frame5; +  GtkWidget *table3; +  GtkWidget *incoming_label; +  GtkWidget *outgoing_label; +  GtkWidget *outgoing_combo; +  GtkWidget *combo_entry2; +  GtkWidget *incoming_combo; +  GtkWidget *combo_entry3; +  GtkWidget *match_interfaces_checkbutton; +  GtkWidget *label57; +  GtkWidget *vbox17; +  GtkWidget *frame6; +  GtkWidget *table4; +  GtkWidget *protocol_label; +  GtkWidget *port_label; +  GtkWidget *protocol_optionmenu; +  GtkWidget *menu3; +  GtkWidget *udp_menu_item; +  GtkWidget *tcp_menu_item; +  GtkWidget *icmp_menu_item; +  GtkWidget *icmp_label; +  GtkWidget *icmp_optionmenu; +  GtkWidget *hbox19; +  GtkObject *port_spinbutton_adj; +  GtkWidget *port_spinbutton; +  GtkWidget *type_label; +  GtkWidget *match_type_checkbutton; +  GtkWidget *label58; +  GtkWidget *vbox13; +  GtkWidget *frame7; +  GtkWidget *table5; +  GtkWidget *src_ip_label; +  GtkWidget *src_ip_entry; +  GtkWidget *src_host_range_value_label; +  GtkObject *src_netmask_spinbutton_adj; +  GtkWidget *src_netmask_spinbutton; +  GtkWidget *src_netmask_label_bits; +  GtkWidget *src_host_range_label; +  GtkWidget *src_netmask_checkbutton; +  GtkWidget *src_netmask_label; +  GtkWidget *label74; +  GtkWidget *match_source_checkbutton; +  GtkWidget *frame8; +  GtkWidget *table6; +  GtkWidget *dst_ip_label; +  GtkWidget *dst_ip_entry; +  GtkWidget *dst_host_range_label; +  GtkObject *dst_netmask_spinbutton_adj; +  GtkWidget *dst_netmask_spinbutton; +  GtkWidget *dst_netmask_label_bits; +  GtkWidget *dst_host_range_value_label; +  GtkWidget *dst_netmask_checkbutton; +  GtkWidget *label75; +  GtkWidget *dst_netmask_label; +  GtkWidget *match_destination_checkbutton; +  GtkWidget *frame9; +  GtkWidget *vbox14; +  GtkWidget *bc_dont_match_radiobutton; +  GSList *bc_dont_match_radiobutton_group = NULL; +  GtkWidget *bc_match_broadcast_radiobutton; +  GtkWidget *bc_match_unicast_radiobutton; +  GtkWidget *label41; +  GtkWidget *label59; +  GtkWidget *hbuttonbox3; +  GtkWidget *ok_button; +  GtkWidget *cancel_button; + +  rule_window = gtk_window_new (GTK_WINDOW_TOPLEVEL); +  gtk_window_set_title (GTK_WINDOW (rule_window), _("FieryFilter Rule")); +  gtk_window_set_resizable (GTK_WINDOW (rule_window), FALSE); + +  vbox11 = gtk_vbox_new (FALSE, 0); +  gtk_widget_show (vbox11); +  gtk_container_add (GTK_CONTAINER (rule_window), vbox11); + +  desc_eventbox = gtk_event_box_new (); +  gtk_widget_show (desc_eventbox); +  gtk_box_pack_start (GTK_BOX (vbox11), desc_eventbox, FALSE, FALSE, 0); + +  desc_label = gtk_label_new (_("desc_label")); +  gtk_widget_show (desc_label); +  gtk_container_add (GTK_CONTAINER (desc_eventbox), desc_label); +  GTK_WIDGET_SET_FLAGS (desc_label, GTK_CAN_FOCUS); +  gtk_label_set_use_markup (GTK_LABEL (desc_label), TRUE); +  gtk_label_set_justify (GTK_LABEL (desc_label), GTK_JUSTIFY_LEFT); +  gtk_label_set_selectable (GTK_LABEL (desc_label), TRUE); +  gtk_misc_set_alignment (GTK_MISC (desc_label), 0, 0.5); +  gtk_misc_set_padding (GTK_MISC (desc_label), 10, 10); + +  hseparator2 = gtk_hseparator_new (); +  gtk_widget_show (hseparator2); +  gtk_box_pack_start (GTK_BOX (vbox11), hseparator2, FALSE, FALSE, 0); + +  notebook2 = gtk_notebook_new (); +  gtk_widget_show (notebook2); +  gtk_box_pack_start (GTK_BOX (vbox11), notebook2, TRUE, TRUE, 0); +  gtk_container_set_border_width (GTK_CONTAINER (notebook2), 5); + +  vbox12 = gtk_vbox_new (FALSE, 5); +  gtk_widget_show (vbox12); +  gtk_container_add (GTK_CONTAINER (notebook2), vbox12); +  gtk_container_set_border_width (GTK_CONTAINER (vbox12), 5); + +  label60 = gtk_label_new (_("Description:")); +  gtk_widget_show (label60); +  gtk_box_pack_start (GTK_BOX (vbox12), label60, FALSE, FALSE, 0); +  gtk_label_set_use_markup (GTK_LABEL (label60), TRUE); +  gtk_label_set_justify (GTK_LABEL (label60), GTK_JUSTIFY_LEFT); +  gtk_misc_set_alignment (GTK_MISC (label60), 0, 0.5); + +  desc_entry = gtk_entry_new (); +  gtk_widget_show (desc_entry); +  gtk_box_pack_start (GTK_BOX (vbox12), desc_entry, FALSE, FALSE, 0); +  gtk_entry_set_max_length (GTK_ENTRY (desc_entry), 64); +  gtk_entry_set_text (GTK_ENTRY (desc_entry), _("A new rule")); + +  label72 = gtk_label_new (_("Action:")); +  gtk_widget_show (label72); +  gtk_box_pack_start (GTK_BOX (vbox12), label72, FALSE, FALSE, 0); +  gtk_label_set_justify (GTK_LABEL (label72), GTK_JUSTIFY_LEFT); +  gtk_misc_set_alignment (GTK_MISC (label72), 0, 0.5); + +  rule_optionmenu = gtk_option_menu_new (); +  gtk_widget_show (rule_optionmenu); +  gtk_box_pack_start (GTK_BOX (vbox12), rule_optionmenu, FALSE, FALSE, 0); + +  menu5 = gtk_menu_new (); + +  imagemenuitem1 = gtk_image_menu_item_new_with_mnemonic (_("Query User")); +  gtk_widget_show (imagemenuitem1); +  gtk_container_add (GTK_CONTAINER (menu5), imagemenuitem1); + +  image110 = gtk_image_new_from_stock ("gtk-dialog-question", GTK_ICON_SIZE_MENU); +  gtk_widget_show (image110); +  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (imagemenuitem1), image110); + +  imagemenuitem2 = gtk_image_menu_item_new_with_mnemonic (_("Accept")); +  gtk_widget_show (imagemenuitem2); +  gtk_container_add (GTK_CONTAINER (menu5), imagemenuitem2); + +  image111 = gtk_image_new_from_stock ("gtk-yes", GTK_ICON_SIZE_MENU); +  gtk_widget_show (image111); +  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (imagemenuitem2), image111); + +  imagemenuitem3 = gtk_image_menu_item_new_with_mnemonic (_("Reject")); +  gtk_widget_show (imagemenuitem3); +  gtk_container_add (GTK_CONTAINER (menu5), imagemenuitem3); + +  image112 = gtk_image_new_from_stock ("gtk-dialog-error", GTK_ICON_SIZE_MENU); +  gtk_widget_show (image112); +  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (imagemenuitem3), image112); + +  imagemenuitem4 = gtk_image_menu_item_new_with_mnemonic (_("Drop")); +  gtk_widget_show (imagemenuitem4); +  gtk_container_add (GTK_CONTAINER (menu5), imagemenuitem4); + +  image113 = gtk_image_new_from_stock ("gtk-delete", GTK_ICON_SIZE_MENU); +  gtk_widget_show (image113); +  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (imagemenuitem4), image113); + +  gtk_option_menu_set_menu (GTK_OPTION_MENU (rule_optionmenu), menu5); + +  label56 = gtk_label_new (_("General")); +  gtk_widget_show (label56); +  gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook2), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook2), 0), label56); +  gtk_label_set_justify (GTK_LABEL (label56), GTK_JUSTIFY_LEFT); + +  vbox16 = gtk_vbox_new (FALSE, 5); +  gtk_widget_show (vbox16); +  gtk_container_add (GTK_CONTAINER (notebook2), vbox16); +  gtk_container_set_border_width (GTK_CONTAINER (vbox16), 5); + +  frame4 = gtk_frame_new (NULL); +  gtk_widget_show (frame4); +  gtk_box_pack_start (GTK_BOX (vbox16), frame4, FALSE, FALSE, 0); + +  hbox18 = gtk_hbox_new (FALSE, 5); +  gtk_widget_show (hbox18); +  gtk_container_add (GTK_CONTAINER (frame4), hbox18); +  gtk_container_set_border_width (GTK_CONTAINER (hbox18), 5); + +  direction_label = gtk_label_new (_("Direction:")); +  gtk_widget_show (direction_label); +  gtk_box_pack_start (GTK_BOX (hbox18), direction_label, FALSE, FALSE, 0); +  gtk_label_set_justify (GTK_LABEL (direction_label), GTK_JUSTIFY_LEFT); +  gtk_misc_set_alignment (GTK_MISC (direction_label), 1, 0.5); + +  direction_optionmenu = gtk_option_menu_new (); +  gtk_widget_show (direction_optionmenu); +  gtk_box_pack_start (GTK_BOX (hbox18), direction_optionmenu, TRUE, TRUE, 0); + +  menu4 = gtk_menu_new (); + +  incoming_menu_item = gtk_image_menu_item_new_with_mnemonic (_("Incoming")); +  gtk_widget_show (incoming_menu_item); +  gtk_container_add (GTK_CONTAINER (menu4), incoming_menu_item); + +  image37 = gtk_image_new_from_stock ("gtk-go-forward", GTK_ICON_SIZE_MENU); +  gtk_widget_show (image37); +  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (incoming_menu_item), image37); + +  outgoing_menu_item = gtk_image_menu_item_new_with_mnemonic (_("Outgoing")); +  gtk_widget_show (outgoing_menu_item); +  gtk_container_add (GTK_CONTAINER (menu4), outgoing_menu_item); + +  image38 = gtk_image_new_from_stock ("gtk-go-back", GTK_ICON_SIZE_MENU); +  gtk_widget_show (image38); +  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (outgoing_menu_item), image38); + +  passing_menu_item = gtk_menu_item_new_with_mnemonic (_("Passing")); +  gtk_widget_show (passing_menu_item); +  gtk_container_add (GTK_CONTAINER (menu4), passing_menu_item); + +  gtk_option_menu_set_menu (GTK_OPTION_MENU (direction_optionmenu), menu4); + +  match_direction_checkbutton = gtk_check_button_new_with_mnemonic (_("Match _direction:")); +  gtk_widget_show (match_direction_checkbutton); +  gtk_frame_set_label_widget (GTK_FRAME (frame4), match_direction_checkbutton); +  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (match_direction_checkbutton), TRUE); + +  frame5 = gtk_frame_new (NULL); +  gtk_widget_show (frame5); +  gtk_box_pack_start (GTK_BOX (vbox16), frame5, FALSE, FALSE, 0); + +  table3 = gtk_table_new (2, 2, FALSE); +  gtk_widget_show (table3); +  gtk_container_add (GTK_CONTAINER (frame5), table3); +  gtk_container_set_border_width (GTK_CONTAINER (table3), 5); +  gtk_table_set_row_spacings (GTK_TABLE (table3), 5); +  gtk_table_set_col_spacings (GTK_TABLE (table3), 5); + +  incoming_label = gtk_label_new_with_mnemonic (_("In_coming:")); +  gtk_widget_show (incoming_label); +  gtk_table_attach (GTK_TABLE (table3), incoming_label, 0, 1, 0, 1, +                    (GtkAttachOptions) (GTK_FILL), +                    (GtkAttachOptions) (0), 0, 0); +  gtk_label_set_justify (GTK_LABEL (incoming_label), GTK_JUSTIFY_LEFT); +  gtk_misc_set_alignment (GTK_MISC (incoming_label), 1, 0.5); + +  outgoing_label = gtk_label_new_with_mnemonic (_("_Outgoing:")); +  gtk_widget_show (outgoing_label); +  gtk_table_attach (GTK_TABLE (table3), outgoing_label, 0, 1, 1, 2, +                    (GtkAttachOptions) (GTK_FILL), +                    (GtkAttachOptions) (0), 0, 0); +  gtk_label_set_justify (GTK_LABEL (outgoing_label), GTK_JUSTIFY_LEFT); +  gtk_misc_set_alignment (GTK_MISC (outgoing_label), 1, 0.5); + +  outgoing_combo = gtk_combo_new (); +  g_object_set_data (G_OBJECT (GTK_COMBO (outgoing_combo)->popwin), +                     "GladeParentKey", outgoing_combo); +  gtk_widget_show (outgoing_combo); +  gtk_table_attach (GTK_TABLE (table3), outgoing_combo, 1, 2, 1, 2, +                    (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), +                    (GtkAttachOptions) (0), 0, 0); + +  combo_entry2 = GTK_COMBO (outgoing_combo)->entry; +  gtk_widget_show (combo_entry2); + +  incoming_combo = gtk_combo_new (); +  g_object_set_data (G_OBJECT (GTK_COMBO (incoming_combo)->popwin), +                     "GladeParentKey", incoming_combo); +  gtk_widget_show (incoming_combo); +  gtk_table_attach (GTK_TABLE (table3), incoming_combo, 1, 2, 0, 1, +                    (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), +                    (GtkAttachOptions) (0), 0, 0); + +  combo_entry3 = GTK_COMBO (incoming_combo)->entry; +  gtk_widget_show (combo_entry3); + +  match_interfaces_checkbutton = gtk_check_button_new_with_mnemonic (_("Match _interfaces:")); +  gtk_widget_show (match_interfaces_checkbutton); +  gtk_frame_set_label_widget (GTK_FRAME (frame5), match_interfaces_checkbutton); +  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (match_interfaces_checkbutton), TRUE); + +  label57 = gtk_label_new (_("Interface")); +  gtk_widget_show (label57); +  gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook2), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook2), 1), label57); +  gtk_label_set_justify (GTK_LABEL (label57), GTK_JUSTIFY_LEFT); + +  vbox17 = gtk_vbox_new (FALSE, 5); +  gtk_widget_show (vbox17); +  gtk_container_add (GTK_CONTAINER (notebook2), vbox17); +  gtk_container_set_border_width (GTK_CONTAINER (vbox17), 5); + +  frame6 = gtk_frame_new (NULL); +  gtk_widget_show (frame6); +  gtk_box_pack_start (GTK_BOX (vbox17), frame6, FALSE, FALSE, 0); + +  table4 = gtk_table_new (3, 2, FALSE); +  gtk_widget_show (table4); +  gtk_container_add (GTK_CONTAINER (frame6), table4); +  gtk_container_set_border_width (GTK_CONTAINER (table4), 5); +  gtk_table_set_row_spacings (GTK_TABLE (table4), 5); +  gtk_table_set_col_spacings (GTK_TABLE (table4), 5); + +  protocol_label = gtk_label_new_with_mnemonic (_("_Protocol:")); +  gtk_widget_show (protocol_label); +  gtk_table_attach (GTK_TABLE (table4), protocol_label, 0, 1, 0, 1, +                    (GtkAttachOptions) (GTK_FILL), +                    (GtkAttachOptions) (0), 0, 0); +  gtk_label_set_justify (GTK_LABEL (protocol_label), GTK_JUSTIFY_LEFT); +  gtk_misc_set_alignment (GTK_MISC (protocol_label), 1, 0.5); + +  port_label = gtk_label_new_with_mnemonic (_("_Port number:")); +  gtk_widget_show (port_label); +  gtk_table_attach (GTK_TABLE (table4), port_label, 0, 1, 1, 2, +                    (GtkAttachOptions) (GTK_FILL), +                    (GtkAttachOptions) (0), 0, 0); +  gtk_label_set_justify (GTK_LABEL (port_label), GTK_JUSTIFY_LEFT); +  gtk_misc_set_alignment (GTK_MISC (port_label), 1, 0.5); + +  protocol_optionmenu = gtk_option_menu_new (); +  gtk_widget_show (protocol_optionmenu); +  gtk_table_attach (GTK_TABLE (table4), protocol_optionmenu, 1, 2, 0, 1, +                    (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), +                    (GtkAttachOptions) (0), 0, 0); + +  menu3 = gtk_menu_new (); + +  udp_menu_item = gtk_menu_item_new_with_mnemonic (_("UDP - User Datagram Protocol")); +  gtk_widget_show (udp_menu_item); +  gtk_container_add (GTK_CONTAINER (menu3), udp_menu_item); + +  tcp_menu_item = gtk_menu_item_new_with_mnemonic (_("TCP - Transmission Control Protocol")); +  gtk_widget_show (tcp_menu_item); +  gtk_container_add (GTK_CONTAINER (menu3), tcp_menu_item); + +  icmp_menu_item = gtk_menu_item_new_with_mnemonic (_("ICMP - Internet Control Message Protocol")); +  gtk_widget_show (icmp_menu_item); +  gtk_container_add (GTK_CONTAINER (menu3), icmp_menu_item); + +  gtk_option_menu_set_menu (GTK_OPTION_MENU (protocol_optionmenu), menu3); + +  icmp_label = gtk_label_new_with_mnemonic (_("I_CMP-Type:")); +  gtk_widget_show (icmp_label); +  gtk_table_attach (GTK_TABLE (table4), icmp_label, 0, 1, 2, 3, +                    (GtkAttachOptions) (GTK_FILL), +                    (GtkAttachOptions) (0), 0, 0); +  gtk_label_set_justify (GTK_LABEL (icmp_label), GTK_JUSTIFY_LEFT); +  gtk_misc_set_alignment (GTK_MISC (icmp_label), 1, 0.5); + +  icmp_optionmenu = gtk_option_menu_new (); +  gtk_widget_show (icmp_optionmenu); +  gtk_table_attach (GTK_TABLE (table4), icmp_optionmenu, 1, 2, 2, 3, +                    (GtkAttachOptions) (GTK_FILL), +                    (GtkAttachOptions) (0), 0, 0); + +  hbox19 = gtk_hbox_new (TRUE, 5); +  gtk_widget_show (hbox19); +  gtk_table_attach (GTK_TABLE (table4), hbox19, 1, 2, 1, 2, +                    (GtkAttachOptions) (GTK_FILL), +                    (GtkAttachOptions) (GTK_FILL), 0, 0); + +  port_spinbutton_adj = gtk_adjustment_new (65535, 1, 65535, 1, 100, 10); +  port_spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (port_spinbutton_adj), 5, 0); +  gtk_widget_show (port_spinbutton); +  gtk_box_pack_start (GTK_BOX (hbox19), port_spinbutton, TRUE, TRUE, 0); +  gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (port_spinbutton), TRUE); + +  type_label = gtk_label_new (_("www")); +  gtk_widget_show (type_label); +  gtk_box_pack_end (GTK_BOX (hbox19), type_label, FALSE, TRUE, 0); +  gtk_label_set_use_markup (GTK_LABEL (type_label), TRUE); +  gtk_label_set_justify (GTK_LABEL (type_label), GTK_JUSTIFY_LEFT); + +  match_type_checkbutton = gtk_check_button_new_with_mnemonic (_("Match _type:")); +  gtk_widget_show (match_type_checkbutton); +  gtk_frame_set_label_widget (GTK_FRAME (frame6), match_type_checkbutton); +  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (match_type_checkbutton), TRUE); + +  label58 = gtk_label_new (_("Type")); +  gtk_widget_show (label58); +  gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook2), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook2), 2), label58); +  gtk_label_set_justify (GTK_LABEL (label58), GTK_JUSTIFY_LEFT); + +  vbox13 = gtk_vbox_new (FALSE, 5); +  gtk_widget_show (vbox13); +  gtk_container_add (GTK_CONTAINER (notebook2), vbox13); +  gtk_container_set_border_width (GTK_CONTAINER (vbox13), 5); + +  frame7 = gtk_frame_new (NULL); +  gtk_widget_show (frame7); +  gtk_box_pack_start (GTK_BOX (vbox13), frame7, FALSE, FALSE, 0); + +  table5 = gtk_table_new (4, 3, FALSE); +  gtk_widget_show (table5); +  gtk_container_add (GTK_CONTAINER (frame7), table5); +  gtk_container_set_border_width (GTK_CONTAINER (table5), 5); +  gtk_table_set_row_spacings (GTK_TABLE (table5), 5); +  gtk_table_set_col_spacings (GTK_TABLE (table5), 5); + +  src_ip_label = gtk_label_new (_("IP-Address:")); +  gtk_widget_show (src_ip_label); +  gtk_table_attach (GTK_TABLE (table5), src_ip_label, 0, 1, 0, 1, +                    (GtkAttachOptions) (GTK_FILL), +                    (GtkAttachOptions) (0), 0, 0); +  gtk_label_set_justify (GTK_LABEL (src_ip_label), GTK_JUSTIFY_LEFT); +  gtk_misc_set_alignment (GTK_MISC (src_ip_label), 1, 0.5); + +  src_ip_entry = gtk_entry_new (); +  gtk_widget_show (src_ip_entry); +  gtk_table_attach (GTK_TABLE (table5), src_ip_entry, 1, 3, 0, 1, +                    (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), +                    (GtkAttachOptions) (0), 0, 0); +  gtk_entry_set_max_length (GTK_ENTRY (src_ip_entry), 15); +  gtk_entry_set_text (GTK_ENTRY (src_ip_entry), _("192.168.0.1")); + +  src_host_range_value_label = gtk_label_new (_("label48")); +  gtk_widget_show (src_host_range_value_label); +  gtk_table_attach (GTK_TABLE (table5), src_host_range_value_label, 1, 3, 3, 4, +                    (GtkAttachOptions) (GTK_FILL), +                    (GtkAttachOptions) (0), 0, 0); +  gtk_widget_set_sensitive (src_host_range_value_label, FALSE); +  gtk_label_set_use_markup (GTK_LABEL (src_host_range_value_label), TRUE); +  gtk_label_set_justify (GTK_LABEL (src_host_range_value_label), GTK_JUSTIFY_LEFT); +  gtk_misc_set_alignment (GTK_MISC (src_host_range_value_label), 0, 0.5); + +  src_netmask_spinbutton_adj = gtk_adjustment_new (24, 0, 32, 1, 8, 10); +  src_netmask_spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (src_netmask_spinbutton_adj), 1, 0); +  gtk_widget_show (src_netmask_spinbutton); +  gtk_table_attach (GTK_TABLE (table5), src_netmask_spinbutton, 1, 2, 2, 3, +                    (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), +                    (GtkAttachOptions) (0), 0, 0); +  gtk_widget_set_sensitive (src_netmask_spinbutton, FALSE); +  gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (src_netmask_spinbutton), TRUE); + +  src_netmask_label_bits = gtk_label_new (_("bits")); +  gtk_widget_show (src_netmask_label_bits); +  gtk_table_attach (GTK_TABLE (table5), src_netmask_label_bits, 2, 3, 2, 3, +                    (GtkAttachOptions) (GTK_FILL), +                    (GtkAttachOptions) (0), 0, 0); +  gtk_widget_set_sensitive (src_netmask_label_bits, FALSE); +  gtk_label_set_justify (GTK_LABEL (src_netmask_label_bits), GTK_JUSTIFY_LEFT); +  gtk_misc_set_alignment (GTK_MISC (src_netmask_label_bits), 0, 0.5); + +  src_host_range_label = gtk_label_new (_("Host range:")); +  gtk_widget_show (src_host_range_label); +  gtk_table_attach (GTK_TABLE (table5), src_host_range_label, 0, 1, 3, 4, +                    (GtkAttachOptions) (GTK_FILL), +                    (GtkAttachOptions) (0), 0, 0); +  gtk_widget_set_sensitive (src_host_range_label, FALSE); +  gtk_label_set_justify (GTK_LABEL (src_host_range_label), GTK_JUSTIFY_LEFT); +  gtk_misc_set_alignment (GTK_MISC (src_host_range_label), 1, 0.5); + +  src_netmask_checkbutton = gtk_check_button_new_with_mnemonic (_("Specify netmask")); +  gtk_widget_show (src_netmask_checkbutton); +  gtk_table_attach (GTK_TABLE (table5), src_netmask_checkbutton, 1, 3, 1, 2, +                    (GtkAttachOptions) (GTK_FILL), +                    (GtkAttachOptions) (0), 0, 0); + +  src_netmask_label = gtk_label_new (_("Netmask:")); +  gtk_widget_show (src_netmask_label); +  gtk_table_attach (GTK_TABLE (table5), src_netmask_label, 0, 1, 2, 3, +                    (GtkAttachOptions) (GTK_FILL), +                    (GtkAttachOptions) (0), 0, 0); +  gtk_label_set_justify (GTK_LABEL (src_netmask_label), GTK_JUSTIFY_LEFT); +  gtk_misc_set_alignment (GTK_MISC (src_netmask_label), 1, 0.5); + +  label74 = gtk_label_new (""); +  gtk_widget_show (label74); +  gtk_table_attach (GTK_TABLE (table5), label74, 0, 1, 1, 2, +                    (GtkAttachOptions) (GTK_FILL), +                    (GtkAttachOptions) (0), 0, 0); +  gtk_label_set_justify (GTK_LABEL (label74), GTK_JUSTIFY_LEFT); +  gtk_misc_set_alignment (GTK_MISC (label74), 0, 0.5); + +  match_source_checkbutton = gtk_check_button_new_with_mnemonic (_("Match source:")); +  gtk_widget_show (match_source_checkbutton); +  gtk_frame_set_label_widget (GTK_FRAME (frame7), match_source_checkbutton); +  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (match_source_checkbutton), TRUE); + +  frame8 = gtk_frame_new (NULL); +  gtk_widget_show (frame8); +  gtk_box_pack_start (GTK_BOX (vbox13), frame8, FALSE, FALSE, 0); + +  table6 = gtk_table_new (4, 3, FALSE); +  gtk_widget_show (table6); +  gtk_container_add (GTK_CONTAINER (frame8), table6); +  gtk_container_set_border_width (GTK_CONTAINER (table6), 5); +  gtk_table_set_row_spacings (GTK_TABLE (table6), 5); +  gtk_table_set_col_spacings (GTK_TABLE (table6), 5); + +  dst_ip_label = gtk_label_new (_("IP-Address:")); +  gtk_widget_show (dst_ip_label); +  gtk_table_attach (GTK_TABLE (table6), dst_ip_label, 0, 1, 0, 1, +                    (GtkAttachOptions) (GTK_FILL), +                    (GtkAttachOptions) (0), 0, 0); +  gtk_label_set_justify (GTK_LABEL (dst_ip_label), GTK_JUSTIFY_LEFT); +  gtk_misc_set_alignment (GTK_MISC (dst_ip_label), 1, 0.5); + +  dst_ip_entry = gtk_entry_new (); +  gtk_widget_show (dst_ip_entry); +  gtk_table_attach (GTK_TABLE (table6), dst_ip_entry, 1, 3, 0, 1, +                    (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), +                    (GtkAttachOptions) (0), 0, 0); +  gtk_entry_set_max_length (GTK_ENTRY (dst_ip_entry), 15); +  gtk_entry_set_text (GTK_ENTRY (dst_ip_entry), _("192.168.0.1")); + +  dst_host_range_label = gtk_label_new (_("Host range:")); +  gtk_widget_show (dst_host_range_label); +  gtk_table_attach (GTK_TABLE (table6), dst_host_range_label, 0, 1, 3, 4, +                    (GtkAttachOptions) (GTK_FILL), +                    (GtkAttachOptions) (0), 0, 0); +  gtk_label_set_justify (GTK_LABEL (dst_host_range_label), GTK_JUSTIFY_LEFT); +  gtk_misc_set_alignment (GTK_MISC (dst_host_range_label), 1, 0.5); + +  dst_netmask_spinbutton_adj = gtk_adjustment_new (24, 0, 32, 1, 10, 10); +  dst_netmask_spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (dst_netmask_spinbutton_adj), 1, 0); +  gtk_widget_show (dst_netmask_spinbutton); +  gtk_table_attach (GTK_TABLE (table6), dst_netmask_spinbutton, 1, 2, 2, 3, +                    (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), +                    (GtkAttachOptions) (0), 0, 0); + +  dst_netmask_label_bits = gtk_label_new (_("bits")); +  gtk_widget_show (dst_netmask_label_bits); +  gtk_table_attach (GTK_TABLE (table6), dst_netmask_label_bits, 2, 3, 2, 3, +                    (GtkAttachOptions) (GTK_FILL), +                    (GtkAttachOptions) (0), 0, 0); +  gtk_label_set_justify (GTK_LABEL (dst_netmask_label_bits), GTK_JUSTIFY_LEFT); +  gtk_misc_set_alignment (GTK_MISC (dst_netmask_label_bits), 0, 0.5); + +  dst_host_range_value_label = gtk_label_new (_("label50")); +  gtk_widget_show (dst_host_range_value_label); +  gtk_table_attach (GTK_TABLE (table6), dst_host_range_value_label, 1, 3, 3, 4, +                    (GtkAttachOptions) (GTK_FILL), +                    (GtkAttachOptions) (0), 0, 0); +  gtk_label_set_use_markup (GTK_LABEL (dst_host_range_value_label), TRUE); +  gtk_label_set_justify (GTK_LABEL (dst_host_range_value_label), GTK_JUSTIFY_LEFT); +  gtk_misc_set_alignment (GTK_MISC (dst_host_range_value_label), 0, 0.5); + +  dst_netmask_checkbutton = gtk_check_button_new_with_mnemonic (_("Specify netmask")); +  gtk_widget_show (dst_netmask_checkbutton); +  gtk_table_attach (GTK_TABLE (table6), dst_netmask_checkbutton, 1, 3, 1, 2, +                    (GtkAttachOptions) (GTK_FILL), +                    (GtkAttachOptions) (0), 0, 0); + +  label75 = gtk_label_new (""); +  gtk_widget_show (label75); +  gtk_table_attach (GTK_TABLE (table6), label75, 0, 1, 1, 2, +                    (GtkAttachOptions) (GTK_FILL), +                    (GtkAttachOptions) (0), 0, 0); +  gtk_label_set_justify (GTK_LABEL (label75), GTK_JUSTIFY_LEFT); +  gtk_misc_set_alignment (GTK_MISC (label75), 0, 0.5); + +  dst_netmask_label = gtk_label_new (_("Netmask:")); +  gtk_widget_show (dst_netmask_label); +  gtk_table_attach (GTK_TABLE (table6), dst_netmask_label, 0, 1, 2, 3, +                    (GtkAttachOptions) (GTK_FILL), +                    (GtkAttachOptions) (0), 0, 0); +  gtk_label_set_justify (GTK_LABEL (dst_netmask_label), GTK_JUSTIFY_LEFT); +  gtk_misc_set_alignment (GTK_MISC (dst_netmask_label), 1, 0.5); + +  match_destination_checkbutton = gtk_check_button_new_with_mnemonic (_("Match destination:")); +  gtk_widget_show (match_destination_checkbutton); +  gtk_frame_set_label_widget (GTK_FRAME (frame8), match_destination_checkbutton); +  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (match_destination_checkbutton), TRUE); + +  frame9 = gtk_frame_new (NULL); +  gtk_widget_show (frame9); +  gtk_box_pack_start (GTK_BOX (vbox13), frame9, FALSE, FALSE, 0); + +  vbox14 = gtk_vbox_new (FALSE, 0); +  gtk_widget_show (vbox14); +  gtk_container_add (GTK_CONTAINER (frame9), vbox14); +  gtk_container_set_border_width (GTK_CONTAINER (vbox14), 5); + +  bc_dont_match_radiobutton = gtk_radio_button_new_with_mnemonic (NULL, _("Don't match")); +  gtk_widget_show (bc_dont_match_radiobutton); +  gtk_box_pack_start (GTK_BOX (vbox14), bc_dont_match_radiobutton, FALSE, FALSE, 0); +  gtk_radio_button_set_group (GTK_RADIO_BUTTON (bc_dont_match_radiobutton), bc_dont_match_radiobutton_group); +  bc_dont_match_radiobutton_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (bc_dont_match_radiobutton)); + +  bc_match_broadcast_radiobutton = gtk_radio_button_new_with_mnemonic (NULL, _("Match broadcast")); +  gtk_widget_show (bc_match_broadcast_radiobutton); +  gtk_box_pack_start (GTK_BOX (vbox14), bc_match_broadcast_radiobutton, FALSE, FALSE, 0); +  gtk_radio_button_set_group (GTK_RADIO_BUTTON (bc_match_broadcast_radiobutton), bc_dont_match_radiobutton_group); +  bc_dont_match_radiobutton_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (bc_match_broadcast_radiobutton)); + +  bc_match_unicast_radiobutton = gtk_radio_button_new_with_mnemonic (NULL, _("Match unicast")); +  gtk_widget_show (bc_match_unicast_radiobutton); +  gtk_box_pack_start (GTK_BOX (vbox14), bc_match_unicast_radiobutton, FALSE, FALSE, 0); +  gtk_radio_button_set_group (GTK_RADIO_BUTTON (bc_match_unicast_radiobutton), bc_dont_match_radiobutton_group); +  bc_dont_match_radiobutton_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (bc_match_unicast_radiobutton)); + +  label41 = gtk_label_new (_("Broadcast:")); +  gtk_widget_show (label41); +  gtk_frame_set_label_widget (GTK_FRAME (frame9), label41); +  gtk_label_set_justify (GTK_LABEL (label41), GTK_JUSTIFY_LEFT); + +  label59 = gtk_label_new (_("Addresses")); +  gtk_widget_show (label59); +  gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook2), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook2), 3), label59); +  gtk_label_set_justify (GTK_LABEL (label59), GTK_JUSTIFY_LEFT); + +  hbuttonbox3 = gtk_hbutton_box_new (); +  gtk_widget_show (hbuttonbox3); +  gtk_box_pack_start (GTK_BOX (vbox11), hbuttonbox3, FALSE, FALSE, 0); +  gtk_container_set_border_width (GTK_CONTAINER (hbuttonbox3), 5); +  gtk_button_box_set_layout (GTK_BUTTON_BOX (hbuttonbox3), GTK_BUTTONBOX_END); +  gtk_box_set_spacing (GTK_BOX (hbuttonbox3), 5); + +  ok_button = gtk_button_new_from_stock ("gtk-ok"); +  gtk_widget_show (ok_button); +  gtk_container_add (GTK_CONTAINER (hbuttonbox3), ok_button); +  GTK_WIDGET_SET_FLAGS (ok_button, GTK_CAN_DEFAULT); + +  cancel_button = gtk_button_new_from_stock ("gtk-cancel"); +  gtk_widget_show (cancel_button); +  gtk_container_add (GTK_CONTAINER (hbuttonbox3), cancel_button); +  GTK_WIDGET_SET_FLAGS (cancel_button, GTK_CAN_DEFAULT); + +  g_signal_connect_swapped ((gpointer) rule_window, "delete_event", +                            G_CALLBACK (on_rule_window_delete_event), +                            GTK_OBJECT (rule_window)); +  g_signal_connect_swapped ((gpointer) desc_entry, "changed", +                            G_CALLBACK (on_desc_entry_changed), +                            GTK_OBJECT (rule_window)); +  g_signal_connect_swapped ((gpointer) direction_optionmenu, "changed", +                            G_CALLBACK (on_direction_optionmenu_changed), +                            GTK_OBJECT (rule_window)); +  g_signal_connect_swapped ((gpointer) match_direction_checkbutton, "toggled", +                            G_CALLBACK (on_match_direction_checkbutton_toggled), +                            GTK_OBJECT (rule_window)); +  g_signal_connect_swapped ((gpointer) match_interfaces_checkbutton, "toggled", +                            G_CALLBACK (on_match_interfaces_checkbutton_toggled), +                            GTK_OBJECT (rule_window)); +  g_signal_connect_swapped ((gpointer) protocol_optionmenu, "changed", +                            G_CALLBACK (on_protocol_optionmenu_changed), +                            GTK_OBJECT (rule_window)); +  g_signal_connect_swapped ((gpointer) port_spinbutton, "value_changed", +                            G_CALLBACK (on_port_spinbutton_value_changed), +                            GTK_OBJECT (rule_window)); +  g_signal_connect_swapped ((gpointer) match_type_checkbutton, "toggled", +                            G_CALLBACK (on_match_type_checkbutton_toggled), +                            GTK_OBJECT (rule_window)); +  g_signal_connect_swapped ((gpointer) src_ip_entry, "changed", +                            G_CALLBACK (on_src_ip_entry_changed), +                            GTK_OBJECT (rule_window)); +  g_signal_connect_swapped ((gpointer) src_netmask_spinbutton, "value_changed", +                            G_CALLBACK (on_src_netmask_spinbutton_value_changed), +                            GTK_OBJECT (rule_window)); +  g_signal_connect ((gpointer) src_netmask_checkbutton, "toggled", +                    G_CALLBACK (on_src_netmask_checkbutton_toggled), +                    NULL); +  g_signal_connect_swapped ((gpointer) match_source_checkbutton, "toggled", +                            G_CALLBACK (on_match_source_checkbutton_toggled), +                            GTK_OBJECT (rule_window)); +  g_signal_connect_swapped ((gpointer) dst_ip_entry, "changed", +                            G_CALLBACK (on_dst_ip_entry_changed), +                            GTK_OBJECT (rule_window)); +  g_signal_connect_swapped ((gpointer) dst_netmask_spinbutton, "value_changed", +                            G_CALLBACK (on_dst_netmask_spinbutton_value_changed), +                            GTK_OBJECT (rule_window)); +  g_signal_connect_swapped ((gpointer) dst_netmask_checkbutton, "toggled", +                            G_CALLBACK (on_dst_netmask_checkbutton_toggled), +                            GTK_OBJECT (rule_window)); +  g_signal_connect_swapped ((gpointer) match_destination_checkbutton, "toggled", +                            G_CALLBACK (on_match_destination_checkbutton_toggled), +                            GTK_OBJECT (rule_window)); +  g_signal_connect_swapped ((gpointer) bc_dont_match_radiobutton, "toggled", +                            G_CALLBACK (on_bc_radiobutton_toggled), +                            GTK_OBJECT (rule_window)); +  g_signal_connect_swapped ((gpointer) bc_match_broadcast_radiobutton, "toggled", +                            G_CALLBACK (on_bc_radiobutton_toggled), +                            GTK_OBJECT (rule_window)); +  g_signal_connect_swapped ((gpointer) bc_match_unicast_radiobutton, "toggled", +                            G_CALLBACK (on_bc_radiobutton_toggled), +                            GTK_OBJECT (rule_window)); +  g_signal_connect_swapped ((gpointer) ok_button, "clicked", +                            G_CALLBACK (on_ok_button_clicked), +                            GTK_OBJECT (rule_window)); +  g_signal_connect_swapped ((gpointer) cancel_button, "clicked", +                            G_CALLBACK (on_cancel_button_clicked), +                            GTK_OBJECT (rule_window)); + +  gtk_label_set_mnemonic_widget (GTK_LABEL (incoming_label), combo_entry3); +  gtk_label_set_mnemonic_widget (GTK_LABEL (outgoing_label), combo_entry2); +  gtk_label_set_mnemonic_widget (GTK_LABEL (protocol_label), protocol_optionmenu); +  gtk_label_set_mnemonic_widget (GTK_LABEL (icmp_label), icmp_optionmenu); + +  /* Store pointers to all widgets, for use by lookup_widget(). */ +  GLADE_HOOKUP_OBJECT_NO_REF (rule_window, rule_window, "rule_window"); +  GLADE_HOOKUP_OBJECT (rule_window, vbox11, "vbox11"); +  GLADE_HOOKUP_OBJECT (rule_window, desc_eventbox, "desc_eventbox"); +  GLADE_HOOKUP_OBJECT (rule_window, desc_label, "desc_label"); +  GLADE_HOOKUP_OBJECT (rule_window, hseparator2, "hseparator2"); +  GLADE_HOOKUP_OBJECT (rule_window, notebook2, "notebook2"); +  GLADE_HOOKUP_OBJECT (rule_window, vbox12, "vbox12"); +  GLADE_HOOKUP_OBJECT (rule_window, label60, "label60"); +  GLADE_HOOKUP_OBJECT (rule_window, desc_entry, "desc_entry"); +  GLADE_HOOKUP_OBJECT (rule_window, label72, "label72"); +  GLADE_HOOKUP_OBJECT (rule_window, rule_optionmenu, "rule_optionmenu"); +  GLADE_HOOKUP_OBJECT (rule_window, menu5, "menu5"); +  GLADE_HOOKUP_OBJECT (rule_window, imagemenuitem1, "imagemenuitem1"); +  GLADE_HOOKUP_OBJECT (rule_window, image110, "image110"); +  GLADE_HOOKUP_OBJECT (rule_window, imagemenuitem2, "imagemenuitem2"); +  GLADE_HOOKUP_OBJECT (rule_window, image111, "image111"); +  GLADE_HOOKUP_OBJECT (rule_window, imagemenuitem3, "imagemenuitem3"); +  GLADE_HOOKUP_OBJECT (rule_window, image112, "image112"); +  GLADE_HOOKUP_OBJECT (rule_window, imagemenuitem4, "imagemenuitem4"); +  GLADE_HOOKUP_OBJECT (rule_window, image113, "image113"); +  GLADE_HOOKUP_OBJECT (rule_window, label56, "label56"); +  GLADE_HOOKUP_OBJECT (rule_window, vbox16, "vbox16"); +  GLADE_HOOKUP_OBJECT (rule_window, frame4, "frame4"); +  GLADE_HOOKUP_OBJECT (rule_window, hbox18, "hbox18"); +  GLADE_HOOKUP_OBJECT (rule_window, direction_label, "direction_label"); +  GLADE_HOOKUP_OBJECT (rule_window, direction_optionmenu, "direction_optionmenu"); +  GLADE_HOOKUP_OBJECT (rule_window, menu4, "menu4"); +  GLADE_HOOKUP_OBJECT (rule_window, incoming_menu_item, "incoming_menu_item"); +  GLADE_HOOKUP_OBJECT (rule_window, image37, "image37"); +  GLADE_HOOKUP_OBJECT (rule_window, outgoing_menu_item, "outgoing_menu_item"); +  GLADE_HOOKUP_OBJECT (rule_window, image38, "image38"); +  GLADE_HOOKUP_OBJECT (rule_window, passing_menu_item, "passing_menu_item"); +  GLADE_HOOKUP_OBJECT (rule_window, match_direction_checkbutton, "match_direction_checkbutton"); +  GLADE_HOOKUP_OBJECT (rule_window, frame5, "frame5"); +  GLADE_HOOKUP_OBJECT (rule_window, table3, "table3"); +  GLADE_HOOKUP_OBJECT (rule_window, incoming_label, "incoming_label"); +  GLADE_HOOKUP_OBJECT (rule_window, outgoing_label, "outgoing_label"); +  GLADE_HOOKUP_OBJECT (rule_window, outgoing_combo, "outgoing_combo"); +  GLADE_HOOKUP_OBJECT (rule_window, combo_entry2, "combo_entry2"); +  GLADE_HOOKUP_OBJECT (rule_window, incoming_combo, "incoming_combo"); +  GLADE_HOOKUP_OBJECT (rule_window, combo_entry3, "combo_entry3"); +  GLADE_HOOKUP_OBJECT (rule_window, match_interfaces_checkbutton, "match_interfaces_checkbutton"); +  GLADE_HOOKUP_OBJECT (rule_window, label57, "label57"); +  GLADE_HOOKUP_OBJECT (rule_window, vbox17, "vbox17"); +  GLADE_HOOKUP_OBJECT (rule_window, frame6, "frame6"); +  GLADE_HOOKUP_OBJECT (rule_window, table4, "table4"); +  GLADE_HOOKUP_OBJECT (rule_window, protocol_label, "protocol_label"); +  GLADE_HOOKUP_OBJECT (rule_window, port_label, "port_label"); +  GLADE_HOOKUP_OBJECT (rule_window, protocol_optionmenu, "protocol_optionmenu"); +  GLADE_HOOKUP_OBJECT (rule_window, menu3, "menu3"); +  GLADE_HOOKUP_OBJECT (rule_window, udp_menu_item, "udp_menu_item"); +  GLADE_HOOKUP_OBJECT (rule_window, tcp_menu_item, "tcp_menu_item"); +  GLADE_HOOKUP_OBJECT (rule_window, icmp_menu_item, "icmp_menu_item"); +  GLADE_HOOKUP_OBJECT (rule_window, icmp_label, "icmp_label"); +  GLADE_HOOKUP_OBJECT (rule_window, icmp_optionmenu, "icmp_optionmenu"); +  GLADE_HOOKUP_OBJECT (rule_window, hbox19, "hbox19"); +  GLADE_HOOKUP_OBJECT (rule_window, port_spinbutton, "port_spinbutton"); +  GLADE_HOOKUP_OBJECT (rule_window, type_label, "type_label"); +  GLADE_HOOKUP_OBJECT (rule_window, match_type_checkbutton, "match_type_checkbutton"); +  GLADE_HOOKUP_OBJECT (rule_window, label58, "label58"); +  GLADE_HOOKUP_OBJECT (rule_window, vbox13, "vbox13"); +  GLADE_HOOKUP_OBJECT (rule_window, frame7, "frame7"); +  GLADE_HOOKUP_OBJECT (rule_window, table5, "table5"); +  GLADE_HOOKUP_OBJECT (rule_window, src_ip_label, "src_ip_label"); +  GLADE_HOOKUP_OBJECT (rule_window, src_ip_entry, "src_ip_entry"); +  GLADE_HOOKUP_OBJECT (rule_window, src_host_range_value_label, "src_host_range_value_label"); +  GLADE_HOOKUP_OBJECT (rule_window, src_netmask_spinbutton, "src_netmask_spinbutton"); +  GLADE_HOOKUP_OBJECT (rule_window, src_netmask_label_bits, "src_netmask_label_bits"); +  GLADE_HOOKUP_OBJECT (rule_window, src_host_range_label, "src_host_range_label"); +  GLADE_HOOKUP_OBJECT (rule_window, src_netmask_checkbutton, "src_netmask_checkbutton"); +  GLADE_HOOKUP_OBJECT (rule_window, src_netmask_label, "src_netmask_label"); +  GLADE_HOOKUP_OBJECT (rule_window, label74, "label74"); +  GLADE_HOOKUP_OBJECT (rule_window, match_source_checkbutton, "match_source_checkbutton"); +  GLADE_HOOKUP_OBJECT (rule_window, frame8, "frame8"); +  GLADE_HOOKUP_OBJECT (rule_window, table6, "table6"); +  GLADE_HOOKUP_OBJECT (rule_window, dst_ip_label, "dst_ip_label"); +  GLADE_HOOKUP_OBJECT (rule_window, dst_ip_entry, "dst_ip_entry"); +  GLADE_HOOKUP_OBJECT (rule_window, dst_host_range_label, "dst_host_range_label"); +  GLADE_HOOKUP_OBJECT (rule_window, dst_netmask_spinbutton, "dst_netmask_spinbutton"); +  GLADE_HOOKUP_OBJECT (rule_window, dst_netmask_label_bits, "dst_netmask_label_bits"); +  GLADE_HOOKUP_OBJECT (rule_window, dst_host_range_value_label, "dst_host_range_value_label"); +  GLADE_HOOKUP_OBJECT (rule_window, dst_netmask_checkbutton, "dst_netmask_checkbutton"); +  GLADE_HOOKUP_OBJECT (rule_window, label75, "label75"); +  GLADE_HOOKUP_OBJECT (rule_window, dst_netmask_label, "dst_netmask_label"); +  GLADE_HOOKUP_OBJECT (rule_window, match_destination_checkbutton, "match_destination_checkbutton"); +  GLADE_HOOKUP_OBJECT (rule_window, frame9, "frame9"); +  GLADE_HOOKUP_OBJECT (rule_window, vbox14, "vbox14"); +  GLADE_HOOKUP_OBJECT (rule_window, bc_dont_match_radiobutton, "bc_dont_match_radiobutton"); +  GLADE_HOOKUP_OBJECT (rule_window, bc_match_broadcast_radiobutton, "bc_match_broadcast_radiobutton"); +  GLADE_HOOKUP_OBJECT (rule_window, bc_match_unicast_radiobutton, "bc_match_unicast_radiobutton"); +  GLADE_HOOKUP_OBJECT (rule_window, label41, "label41"); +  GLADE_HOOKUP_OBJECT (rule_window, label59, "label59"); +  GLADE_HOOKUP_OBJECT (rule_window, hbuttonbox3, "hbuttonbox3"); +  GLADE_HOOKUP_OBJECT (rule_window, ok_button, "ok_button"); +  GLADE_HOOKUP_OBJECT (rule_window, cancel_button, "cancel_button"); + +  gtk_widget_grab_focus (ok_button); +  gtk_widget_grab_default (ok_button); +  return rule_window; +} + +GtkWidget* +create_wait_window (void) +{ +  GtkWidget *wait_window; +  GtkWidget *hbox20; +  GtkWidget *image39; +  GtkWidget *label61; + +  wait_window = gtk_window_new (GTK_WINDOW_TOPLEVEL); +  gtk_window_set_title (GTK_WINDOW (wait_window), _("Firewall Update")); +  gtk_window_set_position (GTK_WINDOW (wait_window), GTK_WIN_POS_CENTER); +  gtk_window_set_modal (GTK_WINDOW (wait_window), TRUE); +  gtk_window_set_resizable (GTK_WINDOW (wait_window), FALSE); + +  hbox20 = gtk_hbox_new (FALSE, 10); +  gtk_widget_show (hbox20); +  gtk_container_add (GTK_CONTAINER (wait_window), hbox20); +  gtk_container_set_border_width (GTK_CONTAINER (hbox20), 10); + +  image39 = gtk_image_new_from_stock ("gtk-dialog-info", GTK_ICON_SIZE_DIALOG); +  gtk_widget_show (image39); +  gtk_box_pack_start (GTK_BOX (hbox20), image39, FALSE, FALSE, 0); + +  label61 = gtk_label_new (_("Please be patient while the firewall is installed...\nThank you!")); +  gtk_widget_show (label61); +  gtk_box_pack_start (GTK_BOX (hbox20), label61, TRUE, TRUE, 0); +  GTK_WIDGET_SET_FLAGS (label61, GTK_CAN_FOCUS); +  gtk_label_set_use_markup (GTK_LABEL (label61), TRUE); +  gtk_label_set_selectable (GTK_LABEL (label61), TRUE); + +  /* Store pointers to all widgets, for use by lookup_widget(). */ +  GLADE_HOOKUP_OBJECT_NO_REF (wait_window, wait_window, "wait_window"); +  GLADE_HOOKUP_OBJECT (wait_window, hbox20, "hbox20"); +  GLADE_HOOKUP_OBJECT (wait_window, image39, "image39"); +  GLADE_HOOKUP_OBJECT (wait_window, label61, "label61"); + +  return wait_window; +} + +GtkWidget* +create_advanced_window (void) +{ +  GtkWidget *advanced_window; +  GtkWidget *vbox20; +  GtkWidget *frame3; +  GtkWidget *vbox22; +  GtkWidget *hbox16; +  GtkWidget *label34; +  GtkWidget *icmp_option_menu; +  GtkWidget *menu2; +  GtkWidget *tcp_rst_check_button; +  GtkWidget *label37; +  GtkWidget *hbuttonbox5; +  GtkWidget *close_button; + +  advanced_window = gtk_window_new (GTK_WINDOW_TOPLEVEL); +  gtk_window_set_title (GTK_WINDOW (advanced_window), _("Advanced")); +  gtk_window_set_resizable (GTK_WINDOW (advanced_window), FALSE); + +  vbox20 = gtk_vbox_new (FALSE, 5); +  gtk_widget_show (vbox20); +  gtk_container_add (GTK_CONTAINER (advanced_window), vbox20); +  gtk_container_set_border_width (GTK_CONTAINER (vbox20), 5); + +  frame3 = gtk_frame_new (NULL); +  gtk_widget_show (frame3); +  gtk_box_pack_start (GTK_BOX (vbox20), frame3, FALSE, TRUE, 0); + +  vbox22 = gtk_vbox_new (FALSE, 5); +  gtk_widget_show (vbox22); +  gtk_container_add (GTK_CONTAINER (frame3), vbox22); +  gtk_container_set_border_width (GTK_CONTAINER (vbox22), 5); + +  hbox16 = gtk_hbox_new (FALSE, 5); +  gtk_widget_show (hbox16); +  gtk_box_pack_start (GTK_BOX (vbox22), hbox16, TRUE, TRUE, 0); + +  label34 = gtk_label_new_with_mnemonic (_("Reject with _ICMP-Code:")); +  gtk_widget_show (label34); +  gtk_box_pack_start (GTK_BOX (hbox16), label34, FALSE, TRUE, 0); +  gtk_label_set_justify (GTK_LABEL (label34), GTK_JUSTIFY_LEFT); + +  icmp_option_menu = gtk_option_menu_new (); +  gtk_widget_show (icmp_option_menu); +  gtk_box_pack_start (GTK_BOX (hbox16), icmp_option_menu, TRUE, TRUE, 0); + +  menu2 = gtk_menu_new (); + +  gtk_option_menu_set_menu (GTK_OPTION_MENU (icmp_option_menu), menu2); + +  tcp_rst_check_button = gtk_check_button_new_with_mnemonic (_("Reject TCP connections with RST-Flag")); +  gtk_widget_show (tcp_rst_check_button); +  gtk_box_pack_start (GTK_BOX (vbox22), tcp_rst_check_button, FALSE, FALSE, 0); + +  label37 = gtk_label_new (_("<b>Rejected connections</b>")); +  gtk_widget_show (label37); +  gtk_frame_set_label_widget (GTK_FRAME (frame3), label37); +  gtk_label_set_use_markup (GTK_LABEL (label37), TRUE); +  gtk_label_set_justify (GTK_LABEL (label37), GTK_JUSTIFY_LEFT); + +  hbuttonbox5 = gtk_hbutton_box_new (); +  gtk_widget_show (hbuttonbox5); +  gtk_box_pack_start (GTK_BOX (vbox20), hbuttonbox5, TRUE, TRUE, 0); +  gtk_button_box_set_layout (GTK_BUTTON_BOX (hbuttonbox5), GTK_BUTTONBOX_END); + +  close_button = gtk_button_new_from_stock ("gtk-close"); +  gtk_widget_show (close_button); +  gtk_container_add (GTK_CONTAINER (hbuttonbox5), close_button); +  GTK_WIDGET_SET_FLAGS (close_button, GTK_CAN_DEFAULT); + +  g_signal_connect ((gpointer) advanced_window, "delete_event", +                    G_CALLBACK (on_advanced_window_delete_event), +                    NULL); +  g_signal_connect ((gpointer) icmp_option_menu, "changed", +                    G_CALLBACK (on_icmp_option_menu_changed), +                    NULL); +  g_signal_connect ((gpointer) tcp_rst_check_button, "toggled", +                    G_CALLBACK (on_tcp_rst_check_button_toggled), +                    NULL); +  g_signal_connect ((gpointer) close_button, "clicked", +                    G_CALLBACK (on_close_button_clicked), +                    NULL); + +  gtk_label_set_mnemonic_widget (GTK_LABEL (label34), icmp_option_menu); + +  /* Store pointers to all widgets, for use by lookup_widget(). */ +  GLADE_HOOKUP_OBJECT_NO_REF (advanced_window, advanced_window, "advanced_window"); +  GLADE_HOOKUP_OBJECT (advanced_window, vbox20, "vbox20"); +  GLADE_HOOKUP_OBJECT (advanced_window, frame3, "frame3"); +  GLADE_HOOKUP_OBJECT (advanced_window, vbox22, "vbox22"); +  GLADE_HOOKUP_OBJECT (advanced_window, hbox16, "hbox16"); +  GLADE_HOOKUP_OBJECT (advanced_window, label34, "label34"); +  GLADE_HOOKUP_OBJECT (advanced_window, icmp_option_menu, "icmp_option_menu"); +  GLADE_HOOKUP_OBJECT (advanced_window, menu2, "menu2"); +  GLADE_HOOKUP_OBJECT (advanced_window, tcp_rst_check_button, "tcp_rst_check_button"); +  GLADE_HOOKUP_OBJECT (advanced_window, label37, "label37"); +  GLADE_HOOKUP_OBJECT (advanced_window, hbuttonbox5, "hbuttonbox5"); +  GLADE_HOOKUP_OBJECT (advanced_window, close_button, "close_button"); + +  return advanced_window; +} + diff --git a/client/interface.h b/client/interface.h new file mode 100644 index 0000000..8acfac5 --- /dev/null +++ b/client/interface.h @@ -0,0 +1,9 @@ +/* + * DO NOT EDIT THIS FILE - it is generated by Glade. + */ + +GtkWidget* create_connection_window (void); +GtkWidget* create_main_window (void); +GtkWidget* create_rule_window (void); +GtkWidget* create_wait_window (void); +GtkWidget* create_advanced_window (void); diff --git a/client/log.c b/client/log.c new file mode 100644 index 0000000..86b6e4a --- /dev/null +++ b/client/log.c @@ -0,0 +1,71 @@ +#include "mainwin.h" +#include "support.h" + +#include "log.h" + +static GtkListStore *log_list_store = NULL; +enum { COLUMN_TIME, COLUMN_TYPE, COLUMN_SOURCE, COLUMN_DESTINATION, COLUMN_DECISION, N_COLUMNS }; + +void log_widget_init() { +    GtkTreeView *tv = GTK_TREE_VIEW(lookup_widget(get_main_window(), "log_view")); + +    log_list_store = gtk_list_store_new(N_COLUMNS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); +    gtk_tree_view_set_model(tv, GTK_TREE_MODEL(log_list_store)); + +    gtk_tree_view_append_column(tv, gtk_tree_view_column_new_with_attributes("Time", gtk_cell_renderer_text_new(), "text", COLUMN_TIME, NULL)); +    gtk_tree_view_append_column(tv, gtk_tree_view_column_new_with_attributes("Type", gtk_cell_renderer_text_new(), "text", COLUMN_TYPE, NULL)); +    gtk_tree_view_append_column(tv, gtk_tree_view_column_new_with_attributes("Source", gtk_cell_renderer_text_new(), "text", COLUMN_SOURCE, NULL)); +    gtk_tree_view_append_column(tv, gtk_tree_view_column_new_with_attributes("Destination", gtk_cell_renderer_text_new(), "text", COLUMN_DESTINATION, NULL)); +    gtk_tree_view_append_column(tv, gtk_tree_view_column_new_with_attributes("Decision", gtk_cell_renderer_text_new(), "text", COLUMN_DECISION, NULL)); +} + + +void log_widget_append(conn_info_t *ci) { +    gtk_list_store_append(log_list_store, &ci->iter); +    gtk_list_store_set(log_list_store, &ci->iter, +                       COLUMN_TIME, ci->timestamp_string, +                       COLUMN_TYPE, ci->type_string,  +                       COLUMN_SOURCE, ci->from_string, +                       COLUMN_DESTINATION, ci->to_string, +                       COLUMN_DECISION, "outstanding...", +                       -1); + +    log_widget_cut(); +     +    if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(get_main_window(), "autoscroll_button")))) { +        GtkTreeView *tv = GTK_TREE_VIEW(lookup_widget(get_main_window(), "log_view")); +        GtkTreePath *path; + +        path = gtk_tree_model_get_path(gtk_tree_view_get_model(tv), &ci->iter); +        gtk_tree_view_set_cursor(tv, path, NULL, FALSE); +        gtk_tree_view_scroll_to_cell(tv, path, NULL, TRUE, .5, 0); +        gtk_tree_path_free(path); +    } +} + +void log_widget_verdict(conn_info_t *ci, verdict_t v) { +    gtk_list_store_set(log_list_store, &ci->iter, +                       COLUMN_DECISION, v == VERDICT_REJECT ? "REJECTED" : (v == VERDICT_DROP ? "DROPPPED" : "ACCEPTED"), +                       -1); +} + +void log_widget_clear() { +    gtk_list_store_clear(log_list_store); +} + + +void log_widget_cut() { +    gfloat m = gtk_spin_button_get_value(GTK_SPIN_BUTTON(lookup_widget(get_main_window(), "log_spinbutton"))); + +    if (m < 10) +        m = 10; + +    while (gtk_tree_model_iter_n_children(GTK_TREE_MODEL(log_list_store), NULL) > m) { +        GtkTreeIter iter; +        if (!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(log_list_store), &iter)) +            return; +         +        gtk_list_store_remove(log_list_store, &iter); +    } +     +} diff --git a/client/log.h b/client/log.h new file mode 100644 index 0000000..3b34bcd --- /dev/null +++ b/client/log.h @@ -0,0 +1,12 @@ +#ifndef foologhfoo +#define foologhfoo + +#include "connection.h" + +void log_widget_init(); +void log_widget_append(conn_info_t *ci); +void log_widget_verdict(conn_info_t *ci, verdict_t v); +void log_widget_clear(); +void log_widget_cut(); + +#endif diff --git a/client/main.c b/client/main.c new file mode 100644 index 0000000..da8ce1a --- /dev/null +++ b/client/main.c @@ -0,0 +1,55 @@ +#include <sys/syscall.h> +#include <mcheck.h> + +#ifdef HAVE_CONFIG_H +#  include <config.h> +#endif + +#include <gtk/gtk.h> + +#include "interface.h" +#include "support.h" +#include "connection.h" +#include "daemon.h" +#include "mainwin.h" +#include "ruleset.h" + +int main (int argc, char *argv[]) { +    mtrace(); +     +#ifdef ENABLE_NLS +    bindtextdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR); +    bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); +    textdomain (GETTEXT_PACKAGE); +#endif +     +    gtk_set_locale(); +    gtk_init(&argc, &argv); +     +    add_pixmap_directory (PACKAGE_DATA_DIR "/" PACKAGE "/pixmaps"); +     +    if (daemon_init() < 0) +        goto finish; + +    if (ruleset_init() < 0) +        goto finish; + +    if (ruleset_initial_load() < 0) +        goto finish; + +    if (ruleset_commit() < 0) +        goto finish; + +    mainwin_show(); +    gtk_main (); +     +finish: +    ruleset_done(); +    daemon_done(); + +    //syscall(SYS_exit, 0); +     +    return 0; +} + + diff --git a/client/main.h b/client/main.h new file mode 100644 index 0000000..4b0e011 --- /dev/null +++ b/client/main.h @@ -0,0 +1,7 @@ +#ifndef foomainhfoo +#define foomainhfoo + +typedef enum verdict { VERDICT_QUERY, VERDICT_ACCEPT, VERDICT_REJECT, VERDICT_DROP } verdict_t; +typedef enum conn_direction { DIR_INCOMING, DIR_OUTGOING, DIR_PASSING } conn_direction_t; + +#endif diff --git a/client/mainwin.c b/client/mainwin.c new file mode 100644 index 0000000..e8189ef --- /dev/null +++ b/client/mainwin.c @@ -0,0 +1,52 @@ +#include <time.h> +#include <stdio.h> + +#include "mainwin.h" +#include "interface.h" +#include "support.h" +#include "connection.h" +#include "log.h" +#include "ruleset.h" +#include "format.h" +#include "advancedwin.h" + +GtkWidget* get_main_window(void) { +    static GtkWidget *mw = NULL; + +    if (!mw) { +        GdkColor color; +        mw = create_main_window(); +        gdk_color_parse ("black", &color); +        gtk_widget_modify_bg(lookup_widget(mw, "title_eventbox"), GTK_STATE_NORMAL, &color); +        log_widget_init(); +        ruleset_widget_init(); + +        gtk_label_set_label(GTK_LABEL(lookup_widget(mw, "version_label")), "<i><span color=\"white\">Version "VERSION"</span></i>"); +    } + +    return mw; +} + +void mainwin_show() { +    gtk_widget_show_all(get_main_window()); +} + +void mainwin_update_status_bar() { +    GtkStatusbar *s; +    static guint ctx = (guint) -1; +    static gchar txt[256]; + +    s = GTK_STATUSBAR(lookup_widget(get_main_window(), "statusbar")); +     +    if (ctx == (guint) -1)  +        ctx = gtk_statusbar_get_context_id(s, "Recieved packets"); +    else +        gtk_statusbar_pop(s, ctx); + +    if (queued_conn_count || conn_current) +        snprintf(txt, sizeof(txt), "Recieved %u packets, %u oustanding", total_conn_count, queued_conn_count + (conn_current ? 1 : 0)); +    else +        snprintf(txt, sizeof(txt), "Recieved %u packets", total_conn_count); +     +    gtk_statusbar_push(s, ctx, txt); +} diff --git a/client/mainwin.h b/client/mainwin.h new file mode 100644 index 0000000..dc49fe8 --- /dev/null +++ b/client/mainwin.h @@ -0,0 +1,12 @@ +#ifndef foomainwinhfoo +#define foomainwinhfoo + +#include <gtk/gtk.h> + +#include "connection.h" + +GtkWidget* get_main_window(void); +void mainwin_show(); +void mainwin_update_status_bar(); + +#endif diff --git a/client/rule.c b/client/rule.c new file mode 100644 index 0000000..60c7081 --- /dev/null +++ b/client/rule.c @@ -0,0 +1,318 @@ +#include <string.h> +#include <stdio.h> +#include <netinet/in.h> +#include <arpa/inet.h> + +#include "rule.h" +#include "format.h" + +static int id = 0; + +rule_t* rule_new() { +    rule_t* rule = g_new0(rule_t, 1); + +    rule->enabled = TRUE; +    rule->realized = FALSE; +    rule->match = 0; +     +    rule->direction = DIR_OUTGOING; +    rule->src_netmask_bits = 32; +    rule->dst_netmask_bits = 32; + +    rule->id = id++; + +    //g_message("allocated rule %u", rule->id); +     +    return rule; +} + +void rule_free(rule_t *rule) { +    //g_message("freed rule %u", rule->id); + +    if (rule->being_edited) +        g_message("WARNING! Rule being currently edited is freed!"); +    g_free(rule); +} + +rule_t* rule_new_from_conn_info(conn_info_t *ci) { +    rule_t *rule = rule_new(); +    g_assert(ci); + +    rule->enabled = TRUE; +    rule->realized = FALSE; +    rule->match = MATCH_DIRECTION | MATCH_TYPE; + +    strncpy(rule->description, ci->type_string, sizeof(rule->description)); +    strncpy(rule->device_in, ci->device_in, IFNAMSIZ); +    strncpy(rule->device_out, ci->device_out, IFNAMSIZ); + +    rule->protocol = ci->protocol; +    rule->port = ci->port; +    rule->icmp_type = ci->icmp_type; +    rule->direction = ci->direction; + +    rule->src_ip_address = ci->src_ip_address; +    rule->dst_ip_address = ci->dst_ip_address; +     +    rule->src_netmask_bits = 32; +    rule->dst_netmask_bits = 32; + +    if (ci->broadcast) +        rule->match |= MATCH_BROADCAST; + +    if (ci->direction == DIR_INCOMING) +        rule->match |= MATCH_SOURCE; + +    if (ci->direction == DIR_OUTGOING) +        rule->match |= MATCH_DESTINATION; + +    if (ci->direction == DIR_PASSING) +        rule->match |= MATCH_DESTINATION|MATCH_SOURCE; +     +    return rule; +} + +rule_t* rule_new_from_xml(xmlDocPtr doc, xmlNodePtr node) { +    rule_t *rule = rule_new(); +    xmlChar *text = NULL; + +    rule->match = 0; +    rule->enabled = TRUE; +    rule->realized = TRUE; +     +    for (node = node->xmlChildrenNode; node; node = node->next) { + +        if (node->type == XML_TEXT_NODE) +            continue; + +        if (node->type != XML_ELEMENT_NODE) +            goto finish; +         +        text = xmlNodeListGetString(doc, node->xmlChildrenNode, 1); +         +        if (!xmlStrcmp(node->name, "description")) +            g_strlcpy(rule->description, text, sizeof(rule->description)); +        else if (!xmlStrcmp(node->name, "direction")) { +            rule->match |= MATCH_DIRECTION; +             +            if (!xmlStrcmp(text, "incoming")) +                rule->direction = DIR_INCOMING; +            else if (!xmlStrcmp(text, "outgoing")) +                rule->direction = DIR_OUTGOING; +            else if (!xmlStrcmp(text, "passing")) +                rule->direction = DIR_PASSING; +            else +                goto finish; +             +        } else if (!xmlStrcmp(node->name, "protocol")) { +            rule->match |= MATCH_TYPE; + +            if (!xmlStrcmp(text, "udp")) +                rule->protocol = IPPROTO_UDP; +            else if (!xmlStrcmp(text, "tcp")) +                rule->protocol = IPPROTO_TCP; +            else if (!xmlStrcmp(text, "tcp")) +                rule->protocol = IPPROTO_ICMP; +            else +                goto finish; +             +        } else if (!xmlStrcmp(node->name, "destination-port")) { +            rule->match |= MATCH_TYPE; +            rule->port = atoi(text); +        } else if (!xmlStrcmp(node->name, "icmp-type")) { +            rule->match |= MATCH_TYPE; +            rule->icmp_type = atoi(text); +        } else if (!xmlStrcmp(node->name, "source")) { +            rule->match |= MATCH_SOURCE; +            if (!inet_aton(text, (struct in_addr*) &rule->src_ip_address)) +                goto finish; +        } else if (!xmlStrcmp(node->name, "destination")) { +            rule->match |= MATCH_DESTINATION; +            if (!inet_aton(text, (struct in_addr*) &rule->dst_ip_address)) +                goto finish; +        } else if (!xmlStrcmp(node->name, "input-device")) { +            rule->match |= MATCH_INTERFACES; +            g_strlcpy(rule->device_in, text, sizeof(rule->device_in)); +        } else if (!xmlStrcmp(node->name, "output-device")) { +            rule->match |= MATCH_INTERFACES; +            g_strlcpy(rule->device_out, text, sizeof(rule->device_out)); +        } else if (!xmlStrcmp(node->name, "source-netmask-bits")) { +            rule->src_netmask_bits = atoi(text); +        } else if (!xmlStrcmp(node->name, "destination-netmask-bits")) { +            rule->dst_netmask_bits = atoi(text); +        } else if (!xmlStrcmp(node->name, "broadcast")) { +            rule->match |= MATCH_BROADCAST; +            rule->match &= ~MATCH_UNICAST; +        } else if (!xmlStrcmp(node->name, "unicast")) { +            rule->match |= MATCH_UNICAST; +            rule->match &= ~MATCH_BROADCAST; +        } else if (!xmlStrcmp(node->name, "target")) { + +            if (!xmlStrcmp(text, "drop")) +                rule->verdict = VERDICT_DROP; +            else if (!xmlStrcmp(text, "reject")) +                rule->verdict = VERDICT_REJECT; +            else if (!xmlStrcmp(text, "accept")) +                rule->verdict = VERDICT_ACCEPT; +            else if (!xmlStrcmp(text, "query") || !xmlStrcmp(text, "ask")) +                rule->verdict = VERDICT_QUERY; +            else +                goto finish; +        } else if (!xmlStrcmp(node->name, "disabled")) { +            rule->enabled = FALSE; +        } else +            goto finish; + +        if (text) +            xmlFree(text); +        text = NULL; +    } + +    return rule; +     +finish: +    if (text) +        xmlFree(text); +     +    rule_free(rule); +    return NULL; +} + + +gchar* rule_match_string(rule_t* rule) { +    static char txt[256], txt2[256]; +    guint l; +    g_assert(rule); + +    txt[0] = 0; +     +    if (rule->match & MATCH_DIRECTION) { +        switch (rule->direction) { +            case DIR_INCOMING: g_strlcat(txt, "incoming; ", sizeof(txt)); break; +            case DIR_OUTGOING: g_strlcat(txt, "outgoing; ", sizeof(txt)); break; +            case DIR_PASSING: g_strlcat(txt, "passing; ", sizeof(txt)); break; +        } + +        if (rule->match & MATCH_INTERFACES) { +            if (rule->direction == DIR_INCOMING) +                snprintf(txt2, sizeof(txt2), "device %s; ", rule->device_in); +            else if (rule->direction == DIR_OUTGOING) +                snprintf(txt2, sizeof(txt2), "device %s; ", rule->device_out); +            else +                snprintf(txt2, sizeof(txt2), "devices %s to %s; ", rule->device_in, rule->device_out); + +            g_strlcat(txt, txt2, sizeof(txt)); +        } +    } + +    if (rule->match & MATCH_TYPE) { +        if (rule->protocol == IPPROTO_ICMP) +            snprintf(txt2, sizeof(txt2), "protocol ICMP; type %s; ", icmp_type_str(rule->icmp_type)); +        else +            snprintf(txt2, sizeof(txt2), "protocol %s; port %u; ", rule->protocol == IPPROTO_TCP ? "TCP" : "UDP", rule->port); + +        g_strlcat(txt, txt2, sizeof(txt)); +    } + +    if (rule->match & MATCH_SOURCE) { +        if (rule->src_netmask_bits < 32) +            snprintf(txt2, sizeof(txt2), "from %s/%i; ", format_ip_address(rule->src_ip_address), rule->src_netmask_bits); +        else +            snprintf(txt2, sizeof(txt2), "from %s; ", format_ip_address(rule->src_ip_address)); +         +        g_strlcat(txt, txt2, sizeof(txt)); +    } + +    if (rule->match & MATCH_DESTINATION) { +        if (rule->dst_netmask_bits < 32) +            snprintf(txt2, sizeof(txt2), "to %s/%i; ", format_ip_address(rule->dst_ip_address), rule->dst_netmask_bits); +        else +            snprintf(txt2, sizeof(txt2), "to %s; ", format_ip_address(rule->dst_ip_address)); +        g_strlcat(txt, txt2, sizeof(txt)); +    } + +    if (rule->match & MATCH_BROADCAST) +        g_strlcat(txt, "broadcast; ", sizeof(txt)); + +    if (rule->match & MATCH_UNICAST) +        g_strlcat(txt, "unicast; ", sizeof(txt)); + +     +    if ((l = strlen(txt)) > 2) { +        txt[l-2] = 0; +        return txt; +    } else +        return "all"; +} + +int rule_to_xml(rule_t*rule, xmlDocPtr doc, xmlNodePtr parent) { +    static char txt[256]; +     +    xmlNodePtr node = NULL; +     +    if (!(node = xmlNewDocNode(doc, NULL, "rule", NULL))) +        goto finish; + +    snprintf(txt, sizeof(txt), "%u", rule->id); +    xmlNewProp(node, "id", txt); +     +    xmlNewTextChild(node, NULL, "description", rule->description); + +    if (!rule->enabled) +        xmlNewTextChild(node, NULL, "disabled", NULL); + +    xmlNewTextChild(node, NULL, "target", format_verdict(rule->verdict, FORMAT_XML)); + +    if (rule->match & MATCH_DIRECTION) { + +        xmlNewTextChild(node, NULL, "direction", rule->direction == DIR_INCOMING ? "incoming" : (rule->direction == DIR_OUTGOING ? "outgoing" : "passing")); +         +        if (rule->match & MATCH_INTERFACES) { +            if ((rule->direction == DIR_INCOMING || rule->direction == DIR_PASSING) && rule->device_in[0]) +                xmlNewTextChild(node, NULL, "input-device", rule->device_in); +            else if ((rule->direction == DIR_OUTGOING || rule->direction == DIR_PASSING) && rule->device_out[0]) +                xmlNewTextChild(node, NULL, "output-device", rule->device_out); +        } +    } + +    if (rule->match & MATCH_TYPE) { +        xmlNewTextChild(node, NULL, "protocol", rule->protocol == IPPROTO_UDP ? "udp" : (rule->protocol == IPPROTO_ICMP ? "icmp" : "tcp")); + +        if (rule->protocol == IPPROTO_ICMP) { +            snprintf(txt, sizeof(txt), "%u", rule->icmp_type); +            xmlNewTextChild(node, NULL, "icmp-type", txt); +        } else { +            snprintf(txt, sizeof(txt), "%u", rule->port); +            xmlNewTextChild(node, NULL, "destination-port", txt); +        } +    } + +    if (rule->match & MATCH_SOURCE) { +        xmlNewTextChild(node, NULL, "source", format_ip_address(rule->src_ip_address)); +        if (rule->src_netmask_bits < 32) { +            snprintf(txt, sizeof(txt), "%u", rule->src_netmask_bits); +            xmlNewTextChild(node, NULL, "source-netmask-bits", txt); +        } +    } + +    if (rule->match & MATCH_DESTINATION) { +        xmlNewTextChild(node, NULL, "destination", format_ip_address(rule->dst_ip_address)); +        if (rule->dst_netmask_bits < 32) { +            snprintf(txt, sizeof(txt), "%u", rule->dst_netmask_bits); +            xmlNewTextChild(node, NULL, "destination-netmask-bits", txt); +        } +    } else if (rule->match & MATCH_BROADCAST) +        xmlNewTextChild(node, NULL, "broadcast", NULL); +    else if (rule->match & MATCH_UNICAST) +        xmlNewTextChild(node, NULL, "unicast", NULL); + +         +    xmlAddChild(parent, node); +    return 0; + +finish: +    if (node) +        xmlFreeNode(node); + +    return -1; +} diff --git a/client/rule.h b/client/rule.h new file mode 100644 index 0000000..bb50d12 --- /dev/null +++ b/client/rule.h @@ -0,0 +1,52 @@ +#ifndef foorulehfoo +#define foorulehfoo + +#include <net/if.h> +#include <glib.h> +#include <gtk/gtk.h> +#include <libxml/tree.h> + +#include "connection.h" +#include "main.h" + +typedef enum match { +    MATCH_INTERFACES = 1, +    MATCH_DIRECTION = 4, +    MATCH_TYPE = 8, +    MATCH_SOURCE = 16, +    MATCH_DESTINATION = 32, +    MATCH_BROADCAST = 64, +    MATCH_UNICAST = 128 +} match_t; + +typedef struct rule { +    gboolean realized; +    gboolean enabled; +    gboolean being_edited; +    verdict_t verdict; +    char description[64]; +    guint32 id; +    GtkTreeIter iter; +     +    match_t match; +    char device_in[IFNAMSIZ+1]; +    char device_out[IFNAMSIZ+1]; +    conn_direction_t direction; +    guint protocol; +    guint port; +    guint icmp_type; +    guint32 src_ip_address; +    guint src_netmask_bits; +    guint32 dst_ip_address; +    guint dst_netmask_bits; +} rule_t; + +rule_t* rule_new(); +rule_t* rule_new_from_conn_info(conn_info_t *ci); +rule_t* rule_new_from_xml(xmlDocPtr doc, xmlNodePtr node); +void rule_free(rule_t *rule); +gchar* rule_match_string(rule_t* rule); + +int rule_to_xml(rule_t*rule, xmlDocPtr doc, xmlNodePtr node); + +#endif diff --git a/client/ruleset.c b/client/ruleset.c new file mode 100644 index 0000000..5c1095a --- /dev/null +++ b/client/ruleset.c @@ -0,0 +1,534 @@ +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <signal.h> +#include <libxml/tree.h> +#include <sys/stat.h> +#include <sys/types.h> + +#include "ruleset.h" +#include "mainwin.h" +#include "support.h" +#include "format.h" +#include "interface.h" +#include "advancedwin.h" + +ruleset_t ruleset = { +    modified : FALSE, +    filename : NULL, +    icmp_reject_code : 13, +    use_tcp_rst : FALSE, +    ignore_rules : FALSE, +    unmatch_verdict : VERDICT_QUERY, +    rules : NULL +}; +     +static pid_t child_pid = (pid_t) -1; + +static GtkListStore *ruleset_list_store = NULL; +enum { COLUMN_ENABLED, COLUMN_DESCRIPTION, COLUMN_VERDICT, COLUMN_RULE, N_COLUMNS }; + +static int commit_pipe[2] = {-1, -1}; +volatile static gboolean commit_running = FALSE; +GtkWidget *commit_window = NULL; + +static void _free_list() { +    while (ruleset.rules) { +        rule_free(ruleset.rules->data); +        ruleset.rules = g_list_remove(ruleset.rules, ruleset.rules->data); +    } +} + +void _set_data(rule_t *rule) { +    g_assert(ruleset_list_store && rule); +     +    gtk_list_store_set(ruleset_list_store, &rule->iter, +                       COLUMN_ENABLED, rule->enabled, +                       COLUMN_DESCRIPTION, rule->description, +                       COLUMN_VERDICT, format_verdict(rule->verdict, FORMAT_USER), +                       COLUMN_RULE, rule, +                       -1); +} + +void ruleset_reset() { + +    g_free(ruleset.filename); +    ruleset.filename = NULL; + +    _free_list(); +     +    ruleset.modified = FALSE; +    ruleset.icmp_reject_code = 13; +    ruleset.use_tcp_rst = FALSE; +    ruleset.ignore_rules = FALSE; +    ruleset.unmatch_verdict = VERDICT_QUERY; +    ruleset.rules = NULL; +} + +void ruleset_fill_ui() { +    GList *l; +    GtkWidget *mw = get_main_window(); +     +    g_assert(ruleset_list_store); +     +    gtk_list_store_clear(ruleset_list_store); + +    for (l = ruleset.rules; l; l = l->next) { +        rule_t *rule = (rule_t*) l->data; +        gtk_list_store_append(ruleset_list_store, &rule->iter); +        _set_data(rule); +        rule->realized = TRUE; +    } + +    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(mw, "ruleset_check_button")), !ruleset.ignore_rules); +    gtk_option_menu_set_history(GTK_OPTION_MENU(lookup_widget(mw, "unmatch_optionmenu")), ruleset.unmatch_verdict); + +    ruleset_update_ui(); +} + +int ruleset_load(gchar *fn) { +    xmlDocPtr doc = NULL; +    xmlNodePtr node; +     +    ruleset_reset(); + +    if (!(doc = xmlParseFile(fn))) +        goto finish; + +    if (!(node = xmlDocGetRootElement(doc))) +        goto finish; + +    if (xmlStrcmp(node->name, "ruleset")) +        goto finish; + +    for (node = node->xmlChildrenNode; node; node = node->next) { +        rule_t *rule; + +        if (node->type == XML_TEXT_NODE) +            continue; + +        if (node->type != XML_ELEMENT_NODE) +            goto finish; + +        if (!xmlStrcmp(node->name, "use-tcp-rst")) { +            ruleset.use_tcp_rst = TRUE; +            continue; +        } + +        if (!xmlStrcmp(node->name, "ignore-rules")) { +            ruleset.ignore_rules = TRUE; +            continue; +        } + +        if (!xmlStrcmp(node->name, "unmatch-verdict")) { +            xmlChar *text; +            text = xmlNodeListGetString(doc, node->xmlChildrenNode, 1); + +            if (!xmlStrcmp(text, "drop")) +                ruleset.unmatch_verdict = VERDICT_DROP; +            else if (!xmlStrcmp(text, "reject")) +                ruleset.unmatch_verdict = VERDICT_REJECT; +            else if (!xmlStrcmp(text, "accept")) +                ruleset.unmatch_verdict = VERDICT_ACCEPT; +            else if (!xmlStrcmp(text, "query") || !xmlStrcmp(text, "ask")) +                ruleset.unmatch_verdict = VERDICT_QUERY; +            else { +                xmlFree(text); +                goto finish; +            } +             +            xmlFree(text); +            continue; +        } + +        if (!xmlStrcmp(node->name, "icmp-reject-code")) { +            xmlChar *text; +            text = xmlNodeListGetString(doc, node->xmlChildrenNode, 1); +            ruleset.icmp_reject_code = atoi(text); +            xmlFree(text); +            continue; +        } +         +        if (xmlStrcmp(node->name, "rule")) +            goto finish; + +        if (!(rule = rule_new_from_xml(doc, node))) +            goto finish; + +        ruleset.rules = g_list_append(ruleset.rules, rule); +    } + +    xmlFreeDoc(doc); +     +    ruleset.filename = g_strdup(fn); +    ruleset.modified = FALSE; +    ruleset_fill_ui(); +     +    return 0; + +finish: +    fprintf(stderr, "Broken XML file.\n"); + +    if (doc) +        xmlFreeDoc(doc); + +    _free_list(); +     +    return -1; +} + +int ruleset_save(gchar *fn) { +    GList *l; +    xmlDocPtr doc = NULL; +    xmlNodePtr node; +    int r = -1; +    char txt[256]; +     +    if (!fn) +        fn = ruleset.filename; +     +    g_assert(fn); + +    if (!(doc = xmlNewDoc("1.0"))) +        goto finish; + +    if (!(node = xmlNewNode(NULL, "ruleset"))) +        goto finish; +     +    xmlDocSetRootElement(doc, node); +     +    if (ruleset.use_tcp_rst) +        xmlNewTextChild(node, NULL, "use-tcp-rst", NULL); + +    if (ruleset.ignore_rules) +        xmlNewTextChild(node, NULL, "ignore-rules", NULL); + +    xmlNewTextChild(node, NULL, "unmatch-verdict", format_verdict(ruleset.unmatch_verdict, FORMAT_XML)); +     +    snprintf(txt, sizeof(txt), "%u", ruleset.icmp_reject_code); +    xmlNewTextChild(node, NULL, "icmp-reject-code", txt); + +    for (l = ruleset.rules; l; l = l->next) { +        if (rule_to_xml((rule_t*) l->data, doc, node) < 0) +            goto finish; +    } + +    if (xmlSaveFormatFile(fn, doc, 1) < 0) +        goto finish; + +    xmlFreeDoc(doc); + +    ruleset.modified = FALSE; +    ruleset_update_ui(); +         +    return 0; + +finish: +    fprintf(stderr, "Could not write XML file.\n"); +     +    if (doc) +        xmlFreeDoc(doc); +     +    return r; +} + +rule_t* ruleset_get_current_rule() { +    GtkTreePath *path; +    GtkTreeIter iter; +    GtkTreeView *tv = GTK_TREE_VIEW(lookup_widget(get_main_window(), "ruleset_view")); +    rule_t *rule; +     +    gtk_tree_view_get_cursor(tv, &path, NULL); + +    if (!path) +        return NULL; +     +    gtk_tree_model_get_iter(GTK_TREE_MODEL(ruleset_list_store), &iter, path); +    gtk_tree_model_get(GTK_TREE_MODEL(ruleset_list_store), &iter, COLUMN_RULE, &rule, -1); +     +    return rule; +     +} + +int ruleset_install() { +    char *argv[3]; +    GError *e; + +    g_assert(ruleset.filename); +     +    argv[0] = "install-firewall"; +    argv[1] = ruleset.filename; +    argv[2] = NULL; + +    if (!g_spawn_async_with_pipes(NULL, argv, NULL, G_SPAWN_DO_NOT_REAP_CHILD|G_SPAWN_SEARCH_PATH, NULL, NULL, &child_pid, NULL, NULL, NULL, &e)) { +        fprintf(stderr, "Could not run install-firewall: %s\n", e->message); +        g_error_free(e); +        return -1; +    } + +    return 0; +} + +static void _sigchld(int sig) { +    gchar c = 'X'; +    write(commit_pipe[1], &c, 1); +    signal(SIGCHLD, SIG_DFL); +} + + +static gboolean _commit_finish(GIOChannel *source, GIOCondition condition, gpointer data) { +    gchar c; +    read(commit_pipe[0], &c, 1); +    gtk_widget_hide(commit_window); +    commit_running = FALSE; +    return TRUE; +} + +int ruleset_commit() { +    g_assert(ruleset.filename); + +    if (commit_running) +        return 0; +     +    commit_running = TRUE; + +    if (!commit_window) +        commit_window = create_wait_window(); +     +    gtk_widget_show_all(commit_window); + +    signal(SIGCHLD, _sigchld); +     +    if (ruleset.modified) +        ruleset_save(ruleset.filename); +     +    return ruleset_install(); +} + +void ruleset_update_ui() { +    GList *l; +    rule_t *rule = ruleset_get_current_rule(); + +    gtk_widget_set_sensitive(GTK_WIDGET(lookup_widget(get_main_window(), "properties_button")), rule && !rule->being_edited); +    gtk_widget_set_sensitive(GTK_WIDGET(lookup_widget(get_main_window(), "remove_button")), rule ? TRUE : FALSE); +    gtk_widget_set_sensitive(GTK_WIDGET(lookup_widget(get_main_window(), "clear_button")), ruleset.rules ? TRUE : FALSE); + +    l = g_list_first(ruleset.rules); +    gtk_widget_set_sensitive(GTK_WIDGET(lookup_widget(get_main_window(), "up_button")), !rule || !l || l->data == rule ? FALSE : TRUE); +    l = g_list_last(ruleset.rules); +    gtk_widget_set_sensitive(GTK_WIDGET(lookup_widget(get_main_window(), "down_button")), !rule || !l || l->data == rule ? FALSE : TRUE); + + +    gtk_widget_set_sensitive(GTK_WIDGET(lookup_widget(get_main_window(), "commit_button")), ruleset.modified); +     +    if (rule) { +        gtk_label_set_label(GTK_LABEL(lookup_widget(get_main_window(), "rule_enabled_label")), rule->enabled ? "Yes" : "No"); +        gtk_label_set_label(GTK_LABEL(lookup_widget(get_main_window(), "rule_name_label")), rule->description); +        gtk_label_set_label(GTK_LABEL(lookup_widget(get_main_window(), "rule_match_label")), rule_match_string(rule)); +        gtk_label_set_label(GTK_LABEL(lookup_widget(get_main_window(), "rule_verdict_label")), format_verdict(rule->verdict, FORMAT_USER)); +    } else { +        gchar *p = "<i>n/a</i>"; +        gtk_label_set_label(GTK_LABEL(lookup_widget(get_main_window(), "rule_enabled_label")), p); +        gtk_label_set_label(GTK_LABEL(lookup_widget(get_main_window(), "rule_name_label")), p); +        gtk_label_set_label(GTK_LABEL(lookup_widget(get_main_window(), "rule_match_label")), p); +        gtk_label_set_label(GTK_LABEL(lookup_widget(get_main_window(), "rule_verdict_label")), p); +    } + +} + +int ruleset_append_rule(rule_t *rule) { +    g_assert(rule); +     +    if (g_list_find(ruleset.rules, rule)) +        return -1; +     +    ruleset.rules = g_list_append(ruleset.rules, rule); +    gtk_list_store_append(ruleset_list_store, &rule->iter); +    _set_data(rule); + +    rule->realized = TRUE; + +    ruleset.modified = TRUE; +    ruleset_update_ui(); +    return 0; +} + +int ruleset_update_rule(rule_t *rule) { +    g_assert(rule && rule->realized); + +    _set_data(rule); +     +    ruleset.modified = TRUE; +    ruleset_update_ui(); +    return 0; +} + + +int ruleset_remove_rule(rule_t *rule) { +    g_assert(rule); + +    if (rule->being_edited) +        return -1; +     +    if (!g_list_find(ruleset.rules, rule)) +        return -1; + +    gtk_list_store_remove(ruleset_list_store, &rule->iter); +    ruleset.rules = g_list_remove(ruleset.rules, rule); +    rule_free(rule); +     +    ruleset.modified = TRUE; +    ruleset_update_ui(); +    return 0; +} + + +int ruleset_move_rule(rule_t *rule, int i) { +    GtkTreeIter *iter = NULL; +    GList *a = NULL, *l; +     +    if (i == 0) +        return -1; + +    l = g_list_find(ruleset.rules, rule); +    g_assert(l); + +     +    if (i > 0) { +        if (!l->next) +            return -1; + +        iter = &(((rule_t*) l->next->data)->iter); + +        a = l->next->next; +    } + +    if (i < 0) { +        if (!l->prev) +            return -1; + +        iter = &(((rule_t*) l->prev->data)->iter); +         +        a = l->prev; +    } + +    ruleset.rules = g_list_remove(ruleset.rules, rule); +    ruleset.rules = g_list_insert_before(ruleset.rules, a, rule); + +    gtk_list_store_swap(ruleset_list_store, &rule->iter, iter); + +    ruleset.modified = TRUE; +    ruleset_update_ui();     +    return 0; +} + +void ruleset_clear() { +    _free_list(); +    if (ruleset_list_store) +        gtk_list_store_clear(ruleset_list_store); +    ruleset_update_ui(); +} + +static void _ruleset_toggled(GtkCellRendererToggle *cell, gchar *path_str, gpointer d) { +    rule_t *rule; +    GtkTreeIter iter; +    GtkTreePath *path = gtk_tree_path_new_from_string(path_str); +     +    gtk_tree_model_get_iter(GTK_TREE_MODEL(ruleset_list_store), &iter, path); +    gtk_tree_model_get(GTK_TREE_MODEL(ruleset_list_store), &iter, COLUMN_RULE, &rule, -1); + +    rule->enabled = !rule->enabled; +    _set_data(rule); +     +    gtk_tree_path_free (path); + +    ruleset.modified = TRUE; +    ruleset_update_ui(); +} + +void ruleset_widget_init() { +    GtkTreeView *tv = GTK_TREE_VIEW(lookup_widget(get_main_window(), "ruleset_view")); +    GtkTreeViewColumn *c; +    GtkCellRenderer *r; + +    gtk_tree_view_set_model(tv, GTK_TREE_MODEL(ruleset_list_store)); + +    r = gtk_cell_renderer_toggle_new(); +    g_signal_connect(r, "toggled", G_CALLBACK(_ruleset_toggled), NULL); +     +    c = gtk_tree_view_column_new_with_attributes("", r, "active", COLUMN_ENABLED, NULL); +    gtk_tree_view_append_column(tv, c); + +    c = gtk_tree_view_column_new_with_attributes("Verdict", gtk_cell_renderer_text_new(), "text", COLUMN_VERDICT, NULL); +    gtk_tree_view_column_set_resizable(c, TRUE); +    gtk_tree_view_append_column(tv, c); + +    c = gtk_tree_view_column_new_with_attributes("Description", gtk_cell_renderer_text_new(), "text", COLUMN_DESCRIPTION, NULL); +    gtk_tree_view_column_set_resizable(c, TRUE); +    gtk_tree_view_append_column(tv, c); + +    ruleset_update_ui(); +} + + +int ruleset_init() { +    GIOChannel *c; +    if (pipe(commit_pipe) < 0) +        return -1; + +    if (!(c = g_io_channel_unix_new(commit_pipe[0]))) { +        ruleset_done(); +        return -1; +    } +     +    g_io_add_watch(c, G_IO_IN, _commit_finish, NULL); +    g_io_channel_unref(c); + +    g_assert(!ruleset_list_store); +    ruleset_list_store = gtk_list_store_new(N_COLUMNS, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER); + +    return 0; +} + +void ruleset_done() { +    g_free(ruleset.filename); +    ruleset.filename = NULL; +     +    _free_list(); +     +    if (commit_pipe[0] >= 0) +        close(commit_pipe[0]); +    if (commit_pipe[1] >= 0) +        close(commit_pipe[1]); +     +    commit_pipe[0] = commit_pipe[1] = -1; + +    g_object_unref(ruleset_list_store); + +} + +int ruleset_new(gchar *fn) { +    ruleset_reset(); +    ruleset.filename = g_strdup(fn); +    ruleset.modified = TRUE; + +    ruleset_fill_ui(); + +    return 0; +} + +int ruleset_initial_load() { +    char fn[PATH_MAX]; + +    snprintf(fn, sizeof(fn), "%s/.fieryfilter/", getenv("HOME")); +    if (mkdir(fn, 0700) && errno != EEXIST) +        return -1; + +    snprintf(fn, sizeof(fn), "%s/.fieryfilter/default.fwx", getenv("HOME")); +    if (ruleset_load(fn) < 0) +        if (ruleset_new(fn) < 0) +            return -1; + +    return 0; +} + diff --git a/client/ruleset.h b/client/ruleset.h new file mode 100644 index 0000000..6ba2b67 --- /dev/null +++ b/client/ruleset.h @@ -0,0 +1,49 @@ +#ifndef foorulesethfoo +#define foorulesethfoo + +#include <glib.h> +#include <gtk/gtk.h> + +#include "../daemon/common.h" +#include "main.h" +#include "connection.h" +#include "rule.h" + +typedef struct ruleset { +    gboolean modified; +    gchar *filename; + +    guint icmp_reject_code; +    gboolean use_tcp_rst; +    gboolean ignore_rules; +    verdict_t unmatch_verdict; + +    GList *rules; +} ruleset_t; + +extern ruleset_t ruleset; + +int ruleset_new(gchar *fn); +int ruleset_load(gchar *fn); +int ruleset_save(gchar *fn); +int ruleset_initial_load(); +int ruleset_commit(); +int ruleset_append_rule(rule_t *rule); +int ruleset_update_rule(rule_t *rule); +int ruleset_remove_rule(rule_t *rule); +int ruleset_move_rule(rule_t *rule, int i); +void ruleset_clear(); + +void ruleset_widget_init(); +void ruleset_update_ui(); +void ruleset_show_rule_info(); +rule_t* ruleset_get_current_rule(); + +int ruleset_install(); + +int ruleset_init(); +void ruleset_done(); + + + +#endif diff --git a/client/rulewin.c b/client/rulewin.c new file mode 100644 index 0000000..ff3d9c4 --- /dev/null +++ b/client/rulewin.c @@ -0,0 +1,249 @@ +#include <gtk/gtk.h> +#include <string.h> +#include <netinet/in.h> +#include <arpa/inet.h> + +#include "rulewin.h" +#include "interface.h" +#include "support.h" +#include "ruleset.h" +#include "format.h" + +void rulewin_fill(GtkWidget *rw, rule_t *r) { +    GList *l; +    GtkWidget *bc = NULL; +     +    if (r->description[0]) { +        gtk_label_set_label(GTK_LABEL(lookup_widget(rw, "desc_label")), r->description); +        gtk_entry_set_text(GTK_ENTRY(lookup_widget(rw, "desc_entry")), r->description); +    } else { +        gtk_label_set_label(GTK_LABEL(lookup_widget(rw, "desc_label")), "<span color=\"white\" size=\"xx-large\"><b><i>New rule</i></b></span>"); +        gtk_entry_set_text(GTK_ENTRY(lookup_widget(rw, "desc_entry")), ""); +    } + +    gtk_option_menu_set_history(GTK_OPTION_MENU(lookup_widget(rw, "rule_optionmenu")), r->verdict); + +    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(rw, "match_direction_checkbutton")), r->match & MATCH_DIRECTION); +    gtk_option_menu_set_history(GTK_OPTION_MENU(lookup_widget(rw, "direction_optionmenu")), r->direction); + +    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(rw, "match_interfaces_checkbutton")), r->match & MATCH_INTERFACES); +    gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(lookup_widget(rw, "incoming_combo"))->entry), r->device_in); +    gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(lookup_widget(rw, "outgoing_combo"))->entry), r->device_out); +     +    l = fill_interface_list(); +    gtk_combo_set_popdown_strings(GTK_COMBO(lookup_widget(rw, "incoming_combo")), l); +    gtk_combo_set_popdown_strings(GTK_COMBO(lookup_widget(rw, "outgoing_combo")), l); +    free_interface_list(l); + +    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(rw, "match_type_checkbutton")), r->match & MATCH_TYPE); +     +    gtk_option_menu_set_history(GTK_OPTION_MENU(lookup_widget(rw, "protocol_optionmenu")), r->protocol == IPPROTO_UDP ? 0 : (r->protocol == IPPROTO_TCP ? 1 : 2)); +    gtk_spin_button_set_value(GTK_SPIN_BUTTON(lookup_widget(rw, "port_spinbutton")), r->port); +    fill_icmp_menu(GTK_OPTION_MENU(lookup_widget(rw, "icmp_optionmenu")), FALSE, r->icmp_type); + +    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(rw, "match_source_checkbutton")), r->match & MATCH_SOURCE); +    gtk_entry_set_text(GTK_ENTRY(lookup_widget(rw, "src_ip_entry")), format_ip_address(r->src_ip_address)); +    gtk_spin_button_set_value(GTK_SPIN_BUTTON(lookup_widget(rw, "src_netmask_spinbutton")), r->src_netmask_bits); +    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(rw, "src_netmask_checkbutton")), r->src_netmask_bits < 32); + +    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(rw, "match_destination_checkbutton")), r->match & MATCH_DESTINATION); +    gtk_entry_set_text(GTK_ENTRY(lookup_widget(rw, "dst_ip_entry")), format_ip_address(r->dst_ip_address)); +    gtk_spin_button_set_value(GTK_SPIN_BUTTON(lookup_widget(rw, "dst_netmask_spinbutton")), r->dst_netmask_bits); +    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(rw, "dst_netmask_checkbutton")), r->dst_netmask_bits < 32); + +    if (r->match & MATCH_BROADCAST) +        bc = lookup_widget(rw, "bc_match_broadcast_radiobutton"); +    else if (r->match & MATCH_UNICAST) +        bc = lookup_widget(rw, "bc_match_unicast_radiobutton");  +    else +        bc = lookup_widget(rw, "bc_dont_match_radiobutton");  + +    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(bc), TRUE); +} + + +void rulewin_update_host_ranges(GtkWidget *rw) { +    const gchar *ip; +    gint bits; + +    ip = gtk_entry_get_text(GTK_ENTRY(lookup_widget(rw, "src_ip_entry"))); +    bits = (gint) gtk_spin_button_get_value(GTK_SPIN_BUTTON(lookup_widget(rw, "src_netmask_spinbutton"))); +    gtk_label_set_label(GTK_LABEL(lookup_widget(rw, "src_host_range_value_label")), format_host_range(ip, bits)); + +    ip = gtk_entry_get_text(GTK_ENTRY(lookup_widget(rw, "dst_ip_entry"))); +    bits = (gint) gtk_spin_button_get_value(GTK_SPIN_BUTTON(lookup_widget(rw, "dst_netmask_spinbutton"))); +    gtk_label_set_label(GTK_LABEL(lookup_widget(rw, "dst_host_range_value_label")), format_host_range(ip, bits)); +} + +void rulewin_set_sensitive(GtkWidget *rw) { +    gboolean b; +    guint i; +    gtk_widget_set_sensitive(lookup_widget(rw, "ok_button"), *gtk_entry_get_text(GTK_ENTRY(lookup_widget(rw, "desc_entry"))) ? TRUE : FALSE); + +    b = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(rw, "match_direction_checkbutton"))); + +    gtk_widget_set_sensitive(lookup_widget(rw, "direction_label"), b); +    gtk_widget_set_sensitive(lookup_widget(rw, "direction_optionmenu"), b); + +    gtk_widget_set_sensitive(lookup_widget(rw, "match_interfaces_checkbutton"), b); +    b = b && gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(rw, "match_interfaces_checkbutton"))); +    i = gtk_option_menu_get_history(GTK_OPTION_MENU(lookup_widget(rw, "direction_optionmenu"))); +    gtk_widget_set_sensitive(lookup_widget(rw, "incoming_label"), b && i != 1); +    gtk_widget_set_sensitive(lookup_widget(rw, "incoming_combo"), b && i != 1); +    gtk_widget_set_sensitive(lookup_widget(rw, "outgoing_label"), b && i != 0); +    gtk_widget_set_sensitive(lookup_widget(rw, "outgoing_combo"), b && i != 0); + + +    b = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(rw, "match_type_checkbutton"))); +    gtk_widget_set_sensitive(lookup_widget(rw, "protocol_label"), b); +    gtk_widget_set_sensitive(lookup_widget(rw, "protocol_optionmenu"), b); + +    i = gtk_option_menu_get_history(GTK_OPTION_MENU(lookup_widget(rw, "protocol_optionmenu"))); +     +    gtk_widget_set_sensitive(lookup_widget(rw, "port_label"), b && i != 2); +    gtk_widget_set_sensitive(lookup_widget(rw, "port_spinbutton"), b && i != 2); +    gtk_widget_set_sensitive(lookup_widget(rw, "type_label"), b && i != 2); + +    gtk_widget_set_sensitive(lookup_widget(rw, "icmp_label"), b && i == 2); +    gtk_widget_set_sensitive(lookup_widget(rw, "icmp_optionmenu"), b && i == 2); + +    b = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(rw, "match_source_checkbutton"))); +    gtk_widget_set_sensitive(lookup_widget(rw, "src_ip_label"), b); +    gtk_widget_set_sensitive(lookup_widget(rw, "src_ip_entry"), b); + +    gtk_widget_set_sensitive(lookup_widget(rw, "src_netmask_checkbutton"), b); +    b = b && gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(rw, "src_netmask_checkbutton"))); +    gtk_widget_set_sensitive(lookup_widget(rw, "src_netmask_spinbutton"), b); +    gtk_widget_set_sensitive(lookup_widget(rw, "src_netmask_label"), b); +    gtk_widget_set_sensitive(lookup_widget(rw, "src_netmask_label_bits"), b); +    gtk_widget_set_sensitive(lookup_widget(rw, "src_host_range_label"), b); +    gtk_widget_set_sensitive(lookup_widget(rw, "src_host_range_value_label"), b); + +    b = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(rw, "bc_dont_match_radiobutton"))); +    gtk_widget_set_sensitive(lookup_widget(rw, "match_destination_checkbutton"), b); +    b = b && gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(rw, "match_destination_checkbutton"))); +    gtk_widget_set_sensitive(lookup_widget(rw, "dst_ip_label"), b); +    gtk_widget_set_sensitive(lookup_widget(rw, "dst_ip_entry"), b); +    gtk_widget_set_sensitive(lookup_widget(rw, "dst_netmask_checkbutton"), b); +     +    b = b && gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(rw, "dst_netmask_checkbutton"))); +    gtk_widget_set_sensitive(lookup_widget(rw, "dst_netmask_spinbutton"), b); +    gtk_widget_set_sensitive(lookup_widget(rw, "dst_netmask_label"), b); +    gtk_widget_set_sensitive(lookup_widget(rw, "dst_netmask_label_bits"), b); +    gtk_widget_set_sensitive(lookup_widget(rw, "dst_host_range_label"), b); +    gtk_widget_set_sensitive(lookup_widget(rw, "dst_host_range_value_label"), b); +} + +int rulewin_show(rule_t *rule) { +    GtkWidget *rw; +    GdkColor color; + +    if (!rule) +        rule = rule_new(); + +    if (rule->being_edited) +        return -1; +     +    rule->being_edited = TRUE; +     +    rw = create_rule_window(); +    g_object_set_data(G_OBJECT(rw), "rule", rule); + +    gdk_color_parse ("black", &color); +    gtk_widget_modify_bg(lookup_widget(rw, "desc_eventbox"), GTK_STATE_NORMAL, &color); +     +    rulewin_fill(rw, rule); +    rulewin_set_sensitive(rw); +    gtk_widget_show_all(rw); + + +    ruleset_update_ui(); +     +    return 0; +} + +void rulewin_ok(GtkWidget *rw) { +    rule_t *rule; + +    rule = (rule_t*) g_object_get_data(G_OBJECT(rw), "rule"); +    g_assert(rule); + +    g_object_set_data(G_OBJECT(rw), "rule", NULL); + +    rule->verdict = gtk_option_menu_get_history(GTK_OPTION_MENU(lookup_widget(rw, "rule_optionmenu"))); +    strncpy(rule->description, gtk_entry_get_text(GTK_ENTRY(lookup_widget(rw, "desc_entry"))), sizeof(rule->description)); + +    rule->match = 0; + +    if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(rw, "match_direction_checkbutton")))) +        rule->match |= MATCH_DIRECTION; +         +    rule->direction = gtk_option_menu_get_history(GTK_OPTION_MENU(lookup_widget(rw, "direction_optionmenu"))); + +    if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(rw, "match_interfaces_checkbutton")))) +        rule->match |= MATCH_INTERFACES; + +    g_strlcpy(rule->device_in, gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(lookup_widget(rw, "incoming_combo"))->entry)), sizeof(rule->device_in)); +    g_strlcpy(rule->device_out, gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(lookup_widget(rw, "outgoing_combo"))->entry)), sizeof(rule->device_out)); +     +    if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(rw, "match_type_checkbutton")))) +        rule->match |= MATCH_TYPE; +     +    switch (gtk_option_menu_get_history(GTK_OPTION_MENU(lookup_widget(rw, "protocol_optionmenu")))) { +        case 0: rule->protocol = IPPROTO_UDP; break; +        case 1: rule->protocol = IPPROTO_TCP; break; +        default: rule->protocol = IPPROTO_UDP; +    } + +    rule->port = CLAMP(1, (guint16) gtk_spin_button_get_value(GTK_SPIN_BUTTON(lookup_widget(rw, "port_spinbutton"))), 0xFFFF); + +    // ICMP fehlt +     +    if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(rw, "match_source_checkbutton")))) +        rule->match |= MATCH_SOURCE; + +    inet_aton(gtk_entry_get_text(GTK_ENTRY(lookup_widget(rw, "src_ip_entry"))), (struct in_addr*) &rule->src_ip_address); +    rule->src_ip_address = rule->src_ip_address; +     +    if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(rw, "src_netmask_checkbutton")))) +        rule->src_netmask_bits = gtk_spin_button_get_value(GTK_SPIN_BUTTON(lookup_widget(rw, "src_netmask_spinbutton"))); +    else +        rule->src_netmask_bits = 32; +     +    if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(rw, "match_destination_checkbutton")))) +        rule->match |= MATCH_DESTINATION; + +    inet_aton(gtk_entry_get_text(GTK_ENTRY(lookup_widget(rw, "dst_ip_entry"))), (struct in_addr*) &rule->dst_ip_address); +    rule->dst_ip_address = rule->dst_ip_address; + +    if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(rw, "dst_netmask_checkbutton")))) +        rule->dst_netmask_bits = gtk_spin_button_get_value(GTK_SPIN_BUTTON(lookup_widget(rw, "dst_netmask_spinbutton"))); +    else +        rule->dst_netmask_bits = 32; +     +    if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(rw, "bc_match_broadcast_radiobutton")))) +        rule->match |= MATCH_BROADCAST; +    else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(rw, "bc_match_unicast_radiobutton")))) +        rule->match |= MATCH_UNICAST; +     +    rule->being_edited = FALSE; +     +    if (rule->realized) +        ruleset_update_rule(rule); +    else +        ruleset_append_rule(rule); +} + +void rulewin_cancel(GtkWidget *rw) { +    rule_t *rule; +     +    rule = (rule_t*) g_object_get_data(G_OBJECT(rw), "rule"); +    rule->being_edited = FALSE; + +    if (!rule->realized) +        rule_free(rule); + +    gtk_widget_destroy(rw); + +    ruleset_update_ui(); +} diff --git a/client/rulewin.h b/client/rulewin.h new file mode 100644 index 0000000..698153f --- /dev/null +++ b/client/rulewin.h @@ -0,0 +1,14 @@ +#ifndef foorulewinhfoo +#define foorulewinhfoo + +#include <gtk/gtk.h> + +#include "ruleset.h" + +int rulewin_show(rule_t *rule); +void rulewin_set_sensitive(GtkWidget *rw); +void rulewin_ok(GtkWidget *rw); +void rulewin_cancel(GtkWidget *rw); +void rulewin_update_host_ranges(GtkWidget *rw); + +#endif diff --git a/client/support.c b/client/support.c new file mode 100644 index 0000000..3f5998d --- /dev/null +++ b/client/support.c @@ -0,0 +1,144 @@ +/* + * DO NOT EDIT THIS FILE - it is generated by Glade. + */ + +#ifdef HAVE_CONFIG_H +#  include <config.h> +#endif + +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <string.h> +#include <stdio.h> + +#include <gtk/gtk.h> + +#include "support.h" + +GtkWidget* +lookup_widget                          (GtkWidget       *widget, +                                        const gchar     *widget_name) +{ +  GtkWidget *parent, *found_widget; + +  for (;;) +    { +      if (GTK_IS_MENU (widget)) +        parent = gtk_menu_get_attach_widget (GTK_MENU (widget)); +      else +        parent = widget->parent; +      if (!parent) +        parent = g_object_get_data (G_OBJECT (widget), "GladeParentKey"); +      if (parent == NULL) +        break; +      widget = parent; +    } + +  found_widget = (GtkWidget*) g_object_get_data (G_OBJECT (widget), +                                                 widget_name); +  if (!found_widget) +    g_warning ("Widget not found: %s", widget_name); +  return found_widget; +} + +static GList *pixmaps_directories = NULL; + +/* Use this function to set the directory containing installed pixmaps. */ +void +add_pixmap_directory                   (const gchar     *directory) +{ +  pixmaps_directories = g_list_prepend (pixmaps_directories, +                                        g_strdup (directory)); +} + +/* This is an internally used function to find pixmap files. */ +static gchar* +find_pixmap_file                       (const gchar     *filename) +{ +  GList *elem; + +  /* We step through each of the pixmaps directory to find it. */ +  elem = pixmaps_directories; +  while (elem) +    { +      gchar *pathname = g_strdup_printf ("%s%s%s", (gchar*)elem->data, +                                         G_DIR_SEPARATOR_S, filename); +      if (g_file_test (pathname, G_FILE_TEST_EXISTS)) +        return pathname; +      g_free (pathname); +      elem = elem->next; +    } +  return NULL; +} + +/* This is an internally used function to create pixmaps. */ +GtkWidget* +create_pixmap                          (GtkWidget       *widget, +                                        const gchar     *filename) +{ +  gchar *pathname = NULL; +  GtkWidget *pixmap; + +  if (!filename || !filename[0]) +      return gtk_image_new (); + +  pathname = find_pixmap_file (filename); + +  if (!pathname) +    { +      g_warning (_("Couldn't find pixmap file: %s"), filename); +      return gtk_image_new (); +    } + +  pixmap = gtk_image_new_from_file (pathname); +  g_free (pathname); +  return pixmap; +} + +/* This is an internally used function to create pixmaps. */ +GdkPixbuf* +create_pixbuf                          (const gchar     *filename) +{ +  gchar *pathname = NULL; +  GdkPixbuf *pixbuf; +  GError *error = NULL; + +  if (!filename || !filename[0]) +      return NULL; + +  pathname = find_pixmap_file (filename); + +  if (!pathname) +    { +      g_warning (_("Couldn't find pixmap file: %s"), filename); +      return NULL; +    } + +  pixbuf = gdk_pixbuf_new_from_file (pathname, &error); +  if (!pixbuf) +    { +      fprintf (stderr, "Failed to load pixbuf file: %s: %s\n", +               pathname, error->message); +      g_error_free (error); +    } +  g_free (pathname); +  return pixbuf; +} + +/* This is used to set ATK action descriptions. */ +void +glade_set_atk_action_description       (AtkAction       *action, +                                        const gchar     *action_name, +                                        const gchar     *description) +{ +  gint n_actions, i; + +  n_actions = atk_action_get_n_actions (action); +  for (i = 0; i < n_actions; i++) +    { +      if (!strcmp (atk_action_get_name (action, i), action_name)) +        atk_action_set_description (action, i, description); +    } +} + diff --git a/client/support.h b/client/support.h new file mode 100644 index 0000000..92201b9 --- /dev/null +++ b/client/support.h @@ -0,0 +1,67 @@ +/* + * DO NOT EDIT THIS FILE - it is generated by Glade. + */ + +#ifdef HAVE_CONFIG_H +#  include <config.h> +#endif + +#include <gtk/gtk.h> + +/* + * Standard gettext macros. + */ +#ifdef ENABLE_NLS +#  include <libintl.h> +#  undef _ +#  define _(String) dgettext (PACKAGE, String) +#  ifdef gettext_noop +#    define N_(String) gettext_noop (String) +#  else +#    define N_(String) (String) +#  endif +#else +#  define textdomain(String) (String) +#  define gettext(String) (String) +#  define dgettext(Domain,Message) (Message) +#  define dcgettext(Domain,Message,Type) (Message) +#  define bindtextdomain(Domain,Directory) (Domain) +#  define _(String) (String) +#  define N_(String) (String) +#endif + + +/* + * Public Functions. + */ + +/* + * This function returns a widget in a component created by Glade. + * Call it with the toplevel widget in the component (i.e. a window/dialog), + * or alternatively any widget in the component, and the name of the widget + * you want returned. + */ +GtkWidget*  lookup_widget              (GtkWidget       *widget, +                                        const gchar     *widget_name); + + +/* Use this function to set the directory containing installed pixmaps. */ +void        add_pixmap_directory       (const gchar     *directory); + + +/* + * Private Functions. + */ + +/* This is used to create the pixmaps used in the interface. */ +GtkWidget*  create_pixmap              (GtkWidget       *widget, +                                        const gchar     *filename); + +/* This is used to create the pixbufs used in the interface. */ +GdkPixbuf*  create_pixbuf              (const gchar     *filename); + +/* This is used to set ATK action descriptions. */ +void        glade_set_atk_action_description (AtkAction       *action, +                                              const gchar     *action_name, +                                              const gchar     *description); + diff --git a/client/test.fwx b/client/test.fwx new file mode 100644 index 0000000..f5ac861 --- /dev/null +++ b/client/test.fwx @@ -0,0 +1,141 @@ +<?xml version="1.0"?> +<ruleset> +  <rule id="0"> +    <description>SPOP3/Cocaine</description> +    <target>accept</target> +    <direction>outgoing</direction> +    <protocol>tcp</protocol> +    <destination-port>995</destination-port> +    <destination>192.168.50.1</destination> +  </rule> +  <rule id="1"> +    <description>POP3/hamburg.de</description> +    <target>accept</target> +    <direction>outgoing</direction> +    <protocol>tcp</protocol> +    <destination-port>110</destination-port> +    <destination>62.181.130.2</destination> +  </rule> +  <rule id="2"> +    <description>POP3/Hansenet</description> +    <target>accept</target> +    <direction>outgoing</direction> +    <protocol>tcp</protocol> +    <destination-port>110</destination-port> +    <destination>213.191.73.2</destination> +  </rule> +  <rule id="3"> +    <description>POP3/Strato</description> +    <target>accept</target> +    <direction>outgoing</direction> +    <protocol>tcp</protocol> +    <destination-port>110</destination-port> +    <destination>192.67.198.2</destination> +  </rule> +  <rule id="4"> +    <description>POP3/Strato</description> +    <target>accept</target> +    <direction>outgoing</direction> +    <protocol>tcp</protocol> +    <destination-port>110</destination-port> +    <destination>192.67.198.79</destination> +  </rule> +  <rule id="5"> +    <description>POP3/Strato</description> +    <target>accept</target> +    <direction>outgoing</direction> +    <protocol>tcp</protocol> +    <destination-port>110</destination-port> +    <destination>192.67.198.62</destination> +  </rule> +  <rule id="6"> +    <description>HTTP</description> +    <target>accept</target> +    <direction>outgoing</direction> +    <protocol>tcp</protocol> +    <destination-port>80</destination-port> +  </rule> +  <rule id="7"> +    <description>DHCP</description> +    <target>accept</target> +    <direction>outgoing</direction> +    <protocol>udp</protocol> +    <destination-port>67</destination-port> +    <destination>192.168.50.1</destination> +  </rule> +  <rule id="8"> +    <description>CUPS Broadcast</description> +    <target>accept</target> +    <direction>incoming</direction> +    <protocol>udp</protocol> +    <destination-port>631</destination-port> +    <source>192.168.50.1</source> +    <broadcast/> +  </rule> +  <rule id="9"> +    <description>Samba Broadcast Port 138 (cocaine)</description> +    <target>accept</target> +    <direction>incoming</direction> +    <protocol>udp</protocol> +    <destination-port>138</destination-port> +    <source>192.168.50.1</source> +    <broadcast/> +  </rule> +  <rule id="10"> +    <description>Samba Broadcast Port 137 (cocaine)</description> +    <target>accept</target> +    <direction>incoming</direction> +    <protocol>udp</protocol> +    <destination-port>137</destination-port> +    <source>192.168.50.1</source> +    <broadcast/> +  </rule> +  <rule id="11"> +    <description>FTP - stud</description> +    <target>accept</target> +    <direction>outgoing</direction> +    <protocol>tcp</protocol> +    <destination-port>21</destination-port> +    <destination>134.100.7.11</destination> +  </rule> +  <rule id="16"> +    <description>NTP/PTB</description> +    <target>accept</target> +    <direction>outgoing</direction> +    <protocol>udp</protocol> +    <destination-port>123</destination-port> +    <destination>192.53.103.104</destination> +  </rule> +  <rule id="14"> +    <description>NTP/campari</description> +    <target>accept</target> +    <direction>outgoing</direction> +    <protocol>udp</protocol> +    <destination-port>123</destination-port> +    <destination>192.168.100.1</destination> +  </rule> +  <rule id="12"> +    <description>NTP</description> +    <target>accept</target> +    <direction>outgoing</direction> +    <protocol>udp</protocol> +    <destination-port>123</destination-port> +    <destination>130.149.17.21</destination> +  </rule> +  <rule id="15"> +    <description>NTP</description> +    <target>accept</target> +    <direction>outgoing</direction> +    <protocol>udp</protocol> +    <destination-port>123</destination-port> +    <destination>131.188.3.222</destination> +  </rule> +  <rule id="13"> +    <description>NTP</description> +    <target>accept</target> +    <direction>outgoing</direction> +    <protocol>udp</protocol> +    <destination-port>123</destination-port> +    <destination>131.188.1.40</destination> +  </rule> +</ruleset>  | 
