summaryrefslogtreecommitdiffstats
path: root/client/rulewin.c
blob: ff3d9c4a972f4e1391374a91736c41d515a03f26 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
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();
}