]> git.ipfire.org Git - people/stevee/ipfire-2.x.git/blame - html/cgi-bin/ids.cgi
ids.cgi: Use get_used_rulesfiles function from ids-functions.pl.
[people/stevee/ipfire-2.x.git] / html / cgi-bin / ids.cgi
CommitLineData
ac1cfefa 1#!/usr/bin/perl
70df8302
MT
2###############################################################################
3# #
4# IPFire.org - A linux based firewall #
e698090e 5# Copyright (C) 2007-2020 IPFire Team <info@ipfire.org> #
70df8302
MT
6# #
7# This program is free software: you can redistribute it and/or modify #
8# it under the terms of the GNU General Public License as published by #
9# the Free Software Foundation, either version 3 of the License, or #
10# (at your option) any later version. #
11# #
12# This program is distributed in the hope that it will be useful, #
13# but WITHOUT ANY WARRANTY; without even the implied warranty of #
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
15# GNU General Public License for more details. #
16# #
17# You should have received a copy of the GNU General Public License #
18# along with this program. If not, see <http://www.gnu.org/licenses/>. #
19# #
20###############################################################################
21
ac1cfefa
MT
22use strict;
23
24# enable only the following on debugging purpose
90c2e164
CS
25#use warnings;
26#use CGI::Carp 'fatalsToBrowser';
ac1cfefa 27
986e08d9 28require '/var/ipfire/general-functions.pl';
ac1cfefa
MT
29require "${General::swroot}/lang.pl";
30require "${General::swroot}/header.pl";
8dcebe53 31require "${General::swroot}/ids-functions.pl";
abffcc99 32require "${General::swroot}/network-functions.pl";
ac1cfefa 33
3e12c6e6
SS
34# Import ruleset providers file.
35require "$IDS::rulesetsourcesfile";
36
f2fdd0c1
CS
37my %color = ();
38my %mainsettings = ();
9d18656b 39my %idsrules = ();
1286e0d4 40my %idssettings=();
2f252efa 41my %used_providers=();
298723b9 42my %cgiparams=();
ac1cfefa 43my %checked=();
5a3e0dca 44my %selected=();
b7e29743 45my %ignored=();
0b89daee
SS
46
47# Read-in main settings, for language, theme and colors.
48&General::readhash("${General::swroot}/main/settings", \%mainsettings);
8186b372 49&General::readhash("/srv/web/ipfire/html/themes/ipfire/include/colors.txt", \%color);
0b89daee 50
1286e0d4
SS
51# Get the available network zones, based on the config type of the system and store
52# the list of zones in an array.
abffcc99 53my @network_zones = &Network::get_available_network_zones();
ac1cfefa 54
51b63b41
SS
55# Check if openvpn is started and add it to the array of network zones.
56if ( -e "/var/run/openvpn.pid") {
57 push(@network_zones, "ovpn");
58}
59
43263ea6
SS
60my $errormessage;
61
00512a5a 62# Create files if they does not exist yet.
b02e30fd 63&IDS::check_and_create_filelayout();
01ba4be4 64
99b372b5
SS
65# Hash which contains the colour code of a network zone.
66my %colourhash = (
67 'red' => $Header::colourred,
68 'green' => $Header::colourgreen,
69 'blue' => $Header::colourblue,
51b63b41
SS
70 'orange' => $Header::colourorange,
71 'ovpn' => $Header::colourovpn
99b372b5
SS
72);
73
ac1cfefa
MT
74&Header::showhttpheaders();
75
298723b9
SS
76#Get GUI values
77&Header::getcgihash(\%cgiparams);
ac1cfefa 78
b7e29743
SS
79## Add/edit an entry to the ignore file.
80#
81if (($cgiparams{'WHITELIST'} eq $Lang::tr{'add'}) || ($cgiparams{'WHITELIST'} eq $Lang::tr{'update'})) {
82
83 # Check if any input has been performed.
84 if ($cgiparams{'IGNORE_ENTRY_ADDRESS'} ne '') {
85
86 # Check if the given input is no valid IP-address or IP-address with subnet, display an error message.
87 if ((!&General::validip($cgiparams{'IGNORE_ENTRY_ADDRESS'})) && (!&General::validipandmask($cgiparams{'IGNORE_ENTRY_ADDRESS'}))) {
88 $errormessage = "$Lang::tr{'guardian invalid address or subnet'}";
89 }
90 } else {
91 $errormessage = "$Lang::tr{'guardian empty input'}";
92 }
93
94 # Go further if there was no error.
95 if ($errormessage eq '') {
96 my %ignored = ();
97 my $id;
98 my $status;
99
100 # Assign hash values.
101 my $new_entry_address = $cgiparams{'IGNORE_ENTRY_ADDRESS'};
102 my $new_entry_remark = $cgiparams{'IGNORE_ENTRY_REMARK'};
103
104 # Read-in ignoredfile.
b02e30fd 105 &General::readhasharray($IDS::ignored_file, \%ignored);
b7e29743
SS
106
107 # Check if we should edit an existing entry and got an ID.
108 if (($cgiparams{'WHITELIST'} eq $Lang::tr{'update'}) && ($cgiparams{'ID'})) {
109 # Assin the provided id.
110 $id = $cgiparams{'ID'};
111
112 # Undef the given ID.
113 undef($cgiparams{'ID'});
114
115 # Grab the configured status of the corresponding entry.
116 $status = $ignored{$id}[2];
117 } else {
118 # Each newly added entry automatically should be enabled.
119 $status = "enabled";
120
121 # Generate the ID for the new entry.
122 #
123 # Sort the keys by their ID and store them in an array.
124 my @keys = sort { $a <=> $b } keys %ignored;
125
126 # Reverse the key array.
127 my @reversed = reverse(@keys);
128
129 # Obtain the last used id.
130 my $last_id = @reversed[0];
131
132 # Increase the last id by one and use it as id for the new entry.
133 $id = ++$last_id;
134 }
135
136 # Add/Modify the entry to/in the ignored hash.
137 $ignored{$id} = ["$new_entry_address", "$new_entry_remark", "$status"];
138
139 # Write the changed ignored hash to the ignored file.
b02e30fd 140 &General::writehasharray($IDS::ignored_file, \%ignored);
b7e29743
SS
141
142 # Regenerate the ignore file.
9283e9b9 143 &IDS::generate_ignore_file();
b7e29743
SS
144 }
145
146 # Check if the IDS is running.
147 if(&IDS::ids_is_running()) {
148 # Call suricatactrl to perform a reload.
149 &IDS::call_suricatactrl("reload");
150 }
151
152## Toggle Enabled/Disabled for an existing entry on the ignore list.
153#
154
155} elsif ($cgiparams{'WHITELIST'} eq $Lang::tr{'toggle enable disable'}) {
156 my %ignored = ();
157
158 # Only go further, if an ID has been passed.
159 if ($cgiparams{'ID'}) {
160 # Assign the given ID.
161 my $id = $cgiparams{'ID'};
162
163 # Undef the given ID.
164 undef($cgiparams{'ID'});
165
166 # Read-in ignoredfile.
b02e30fd 167 &General::readhasharray($IDS::ignored_file, \%ignored);
b7e29743
SS
168
169 # Grab the configured status of the corresponding entry.
170 my $status = $ignored{$id}[2];
171
172 # Switch the status.
173 if ($status eq "disabled") {
174 $status = "enabled";
175 } else {
176 $status = "disabled";
177 }
178
179 # Modify the status of the existing entry.
180 $ignored{$id} = ["$ignored{$id}[0]", "$ignored{$id}[1]", "$status"];
181
182 # Write the changed ignored hash to the ignored file.
b02e30fd 183 &General::writehasharray($IDS::ignored_file, \%ignored);
b7e29743
SS
184
185 # Regenerate the ignore file.
9283e9b9 186 &IDS::generate_ignore_file();
b7e29743
SS
187
188 # Check if the IDS is running.
189 if(&IDS::ids_is_running()) {
190 # Call suricatactrl to perform a reload.
191 &IDS::call_suricatactrl("reload");
192 }
193 }
194
195## Remove entry from ignore list.
196#
197} elsif ($cgiparams{'WHITELIST'} eq $Lang::tr{'remove'}) {
198 my %ignored = ();
199
200 # Read-in ignoredfile.
b02e30fd 201 &General::readhasharray($IDS::ignored_file, \%ignored);
b7e29743
SS
202
203 # Drop entry from the hash.
204 delete($ignored{$cgiparams{'ID'}});
205
206 # Undef the given ID.
207 undef($cgiparams{'ID'});
208
209 # Write the changed ignored hash to the ignored file.
b02e30fd 210 &General::writehasharray($IDS::ignored_file, \%ignored);
b7e29743
SS
211
212 # Regenerate the ignore file.
9283e9b9 213 &IDS::generate_ignore_file();
b7e29743
SS
214
215 # Check if the IDS is running.
216 if(&IDS::ids_is_running()) {
217 # Call suricatactrl to perform a reload.
218 &IDS::call_suricatactrl("reload");
219 }
220}
221
9074e3d7
SS
222# Check if the page is locked, in this case, the ids_page_lock_file exists.
223if (-e $IDS::ids_page_lock_file) {
224 # Lock the webpage and print notice about autoupgrade of the ruleset
225 # is in progess.
226 &working_notice("$Lang::tr{'ids ruleset autoupdate in progress'}");
227
228 # Loop and check if the file still exists.
229 while(-e $IDS::ids_page_lock_file) {
230 # Sleep for a second and re-check.
231 sleep 1;
232 }
233
234 # Page has been unlocked, perform a reload.
235 &reload();
236}
237
3983aebd
SS
238# Check if any error has been stored.
239if (-e $IDS::storederrorfile) {
240 # Open file to read in the stored error message.
241 open(FILE, "<$IDS::storederrorfile") or die "Could not open $IDS::storederrorfile. $!\n";
242
243 # Read the stored error message.
244 $errormessage = <FILE>;
245
246 # Close file.
247 close (FILE);
248
249 # Delete the file, which is now not longer required.
250 unlink($IDS::storederrorfile);
251}
252
a468b62b
SS
253# Gather ruleset details.
254if ($cgiparams{'RULESET'}) {
255 ## Grab all available rules and store them in the idsrules hash.
256 #
257 # Open rules directory and do a directory listing.
258 opendir(DIR, $IDS::rulespath) or die $!;
259 # Loop through the direcory.
260 while (my $file = readdir(DIR)) {
422204ff 261
a468b62b
SS
262 # We only want files.
263 next unless (-f "$IDS::rulespath/$file");
422204ff 264
a468b62b
SS
265 # Ignore empty files.
266 next if (-z "$IDS::rulespath/$file");
422204ff 267
a468b62b
SS
268 # Use a regular expression to find files ending in .rules
269 next unless ($file =~ m/\.rules$/);
422204ff 270
a468b62b
SS
271 # Ignore files which are not read-able.
272 next unless (-R "$IDS::rulespath/$file");
395e3b90 273
a468b62b
SS
274 # Skip whitelist rules file.
275 next if( $file eq "whitelist.rules");
b7e29743 276
a468b62b
SS
277 # Call subfunction to read-in rulefile and add rules to
278 # the idsrules hash.
279 &readrulesfile("$file");
280 }
395e3b90 281
a468b62b 282 closedir(DIR);
395e3b90 283
a468b62b 284 # Gather used rulefiles.
3daa3000
SS
285 my @used_rulesfiles = &IDS::get_used_rulesfiles();
286
287 # Loop through the array of used rulesfiles.
288 foreach my $rulesfile (@used_rulesfiles) {
289 # Check if the current rulefile exists in the %idsrules hash.
290 # If not, the file probably does not exist anymore or contains
291 # no rules.
292 if($idsrules{$rulefile}) {
293 # Add the rulefile state to the %idsrules hash.
294 $idsrules{$rulefile}{'Rulefile'}{'State'} = "on";
e5738079
SS
295 }
296 }
297}
298
ea5c8eeb
SS
299# Save ruleset configuration.
300if ($cgiparams{'RULESET'} eq $Lang::tr{'save'}) {
301 my %oldsettings;
302
303 # Read-in current (old) IDS settings.
b02e30fd 304 &General::readhash("$IDS::rules_settings_file", \%oldsettings);
ea5c8eeb
SS
305
306 # Prevent form name from been stored in conf file.
307 delete $cgiparams{'RULESET'};
308
613f58fb 309 # Check if the choosen vendor (URL) requires an subscription/oinkcode.
3e12c6e6 310 if ($IDS::Ruleset::Providers{$cgiparams{'RULES'}}{'requires_subscription'} eq "True") {
613f58fb
SS
311 # Check if an subscription/oinkcode has been provided.
312 if ($cgiparams{'OINKCODE'}) {
313 # Check if the oinkcode contains unallowed chars.
314 unless ($cgiparams{'OINKCODE'} =~ /^[a-z0-9]+$/) {
315 $errormessage = $Lang::tr{'invalid input for oink code'};
316 }
317 } else {
318 # Print an error message, that an subsription/oinkcode is required for this
319 # vendor.
320 $errormessage = $Lang::tr{'ids oinkcode required'};
ea5c8eeb
SS
321 }
322 }
323
324 # Go on if there are no error messages.
325 if (!$errormessage) {
326 # Store settings into settings file.
b02e30fd 327 &General::writehash("$IDS::rules_settings_file", \%cgiparams);
ea5c8eeb 328
f644a167
SS
329 # Check if a ruleset is present - if not or the source has been changed download it.
330 if((! %idsrules) || ($oldsettings{'RULES'} ne $cgiparams{'RULES'})) {
331 # Check if the red device is active.
332 unless (-e "${General::swroot}/red/active") {
333 $errormessage = "$Lang::tr{'could not download latest updates'} - $Lang::tr{'system is offline'}";
5fd2e9d6
SS
334 }
335
a5ba473c 336 # Check if enough free disk space is availabe.
f644a167
SS
337 if(&IDS::checkdiskspace()) {
338 $errormessage = "$Lang::tr{'not enough disk space'}";
97870bf2
SS
339 }
340
f644a167
SS
341 # Check if any errors happend.
342 unless ($errormessage) {
343 # Lock the webpage and print notice about downloading
344 # a new ruleset.
5bd8940d 345 &working_notice("$Lang::tr{'ids working'}");
f644a167 346
a5ba473c 347 # Write the modify sid's file and pass the taken ruleaction.
81bae51f 348 &IDS::write_modify_sids_file();
a5ba473c 349
f644a167
SS
350 # Call subfunction to download the ruleset.
351 if(&IDS::downloadruleset()) {
352 $errormessage = $Lang::tr{'could not download latest updates'};
353
354 # Call function to store the errormessage.
355 &IDS::_store_error_message($errormessage);
356 } else {
357 # Call subfunction to launch oinkmaster.
358 &IDS::oinkmaster();
359 }
360
361 # Check if the IDS is running.
362 if(&IDS::ids_is_running()) {
363 # Call suricatactrl to stop the IDS - because of the changed
364 # ruleset - the use has to configure it before suricata can be
365 # used again.
366 &IDS::call_suricatactrl("stop");
367 }
368
369 # Perform a reload of the page.
370 &reload();
371 }
5fd2e9d6
SS
372 }
373 }
374
298723b9 375# Save ruleset.
ee7fe87e 376} elsif ($cgiparams{'RULESET'} eq $Lang::tr{'ids apply'}) {
d2212836 377 # Arrays to store which rulefiles have been enabled and will be used.
e5738079 378 my @enabled_rulefiles;
298723b9 379
d2212836
SS
380 # Hash to store the user-enabled and disabled sids.
381 my %enabled_disabled_sids;
382
af8e5145
SS
383 # Store if a restart of suricata is required.
384 my $suricata_restart_required;
385
9d18656b
SS
386 # Loop through the hash of idsrules.
387 foreach my $rulefile(keys %idsrules) {
1622e5c1
SS
388 # Check if the state of the rulefile has been changed.
389 unless ($cgiparams{$rulefile} eq $idsrules{$rulefile}{'Rulefile'}{'State'}) {
390 # A restart of suricata is required to apply the changes of the used rulefiles.
391 $suricata_restart_required = 1;
392 }
393
e5738079
SS
394 # Check if the rulefile is enabled.
395 if ($cgiparams{$rulefile} eq "on") {
396 # Add rulefile to the array of enabled rulefiles.
397 push(@enabled_rulefiles, $rulefile);
b65b5ef3
SS
398
399 # Drop item from cgiparams hash.
400 delete $cgiparams{$rulefile};
e5738079 401 }
466c6779 402 }
e5738079 403
d2212836
SS
404 # Read-in the files for enabled/disabled sids.
405 # This will be done by calling the read_enabled_disabled_sids_file function two times
406 # and merge the returned hashes together into the enabled_disabled_sids hash.
407 %enabled_disabled_sids = (
b02e30fd
SS
408 &read_enabled_disabled_sids_file($IDS::disabled_sids_file),
409 &read_enabled_disabled_sids_file($IDS::enabled_sids_file));
d2212836 410
9d18656b
SS
411 # Loop through the hash of idsrules.
412 foreach my $rulefile (keys %idsrules) {
298723b9 413 # Loop through the single rules of the rulefile.
9d18656b 414 foreach my $sid (keys %{$idsrules{$rulefile}}) {
c51a044a
SS
415 # Skip the current sid if it is not numeric.
416 next unless ($sid =~ /\d+/ );
417
298723b9
SS
418 # Check if there exists a key in the cgiparams hash for this sid.
419 if (exists($cgiparams{$sid})) {
420 # Look if the rule is disabled.
9d18656b 421 if ($idsrules{$rulefile}{$sid}{'State'} eq "off") {
298723b9
SS
422 # Check if the state has been set to 'on'.
423 if ($cgiparams{$sid} eq "on") {
d2212836
SS
424 # Add/Modify the sid to/in the enabled_disabled_sids hash.
425 $enabled_disabled_sids{$sid} = "enabled";
298723b9
SS
426
427 # Drop item from cgiparams hash.
60333473 428 delete $cgiparams{$rulefile}{$sid};
298723b9
SS
429 }
430 }
431 } else {
432 # Look if the rule is enabled.
9d18656b 433 if ($idsrules{$rulefile}{$sid}{'State'} eq "on") {
298723b9
SS
434 # Check if the state is 'on' and should be disabled.
435 # In this case there is no entry
436 # for the sid in the cgiparams hash.
d2212836
SS
437 # Add/Modify it to/in the enabled_disabled_sids hash.
438 $enabled_disabled_sids{$sid} = "disabled";
298723b9
SS
439
440 # Drop item from cgiparams hash.
60333473 441 delete $cgiparams{$rulefile}{$sid};
298723b9
SS
442 }
443 }
444 }
445 }
446
37659505 447 # Open enabled sid's file for writing.
b02e30fd 448 open(ENABLED_FILE, ">$IDS::enabled_sids_file") or die "Could not write to $IDS::enabled_sids_file. $!\n";
37659505
SS
449
450 # Open disabled sid's file for writing.
b02e30fd 451 open(DISABLED_FILE, ">$IDS::disabled_sids_file") or die "Could not write to $IDS::disabled_sids_file. $!\n";
d2212836
SS
452
453 # Write header to the files.
454 print ENABLED_FILE "#Autogenerated file. Any custom changes will be overwritten!\n";
455 print DISABLED_FILE "#Autogenerated file. Any custom changes will be overwritten!\n";
456
457 # Check if the hash for enabled/disabled files contains any entries.
458 if (%enabled_disabled_sids) {
459 # Loop through the hash.
460 foreach my $sid (keys %enabled_disabled_sids) {
461 # Check if the sid is enabled.
462 if ($enabled_disabled_sids{$sid} eq "enabled") {
463 # Print the sid to the enabled_sids file.
464 print ENABLED_FILE "enablesid $sid\n";
465 # Check if the sid is disabled.
466 } elsif ($enabled_disabled_sids{$sid} eq "disabled") {
467 # Print the sid to the disabled_sids file.
468 print DISABLED_FILE "disablesid $sid\n";
469 # Something strange happende - skip the current sid.
470 } else {
471 next;
472 }
37659505
SS
473 }
474 }
298723b9 475
d2212836
SS
476 # Close file for enabled_sids after writing.
477 close(ENABLED_FILE);
478
479 # Close file for disabled_sids after writing.
480 close(DISABLED_FILE);
e5738079 481
b02e30fd
SS
482 # Call function to generate and write the used rulefiles file.
483 &IDS::write_used_rulefiles_file(@enabled_rulefiles);
52599865 484
27760092 485 # Lock the webpage and print message.
5bd8940d 486 &working_notice("$Lang::tr{'ids apply ruleset changes'}");
27760092 487
52599865 488 # Call oinkmaster to alter the ruleset.
27760092
SS
489 &IDS::oinkmaster();
490
e2e7880d 491 # Check if the IDS is running.
5a28e721 492 if(&IDS::ids_is_running()) {
af8e5145
SS
493 # Check if a restart of suricata is required.
494 if ($suricata_restart_required) {
495 # Call suricatactrl to perform the restart.
496 &IDS::call_suricatactrl("restart");
497 } else {
498 # Call suricatactrl to perform a reload.
499 &IDS::call_suricatactrl("reload");
500 }
e2e7880d
SS
501 }
502
27760092
SS
503 # Reload page.
504 &reload();
52599865
SS
505
506# Download new ruleset.
5fd2e9d6 507} elsif ($cgiparams{'RULESET'} eq $Lang::tr{'update ruleset'}) {
43263ea6
SS
508 # Check if the red device is active.
509 unless (-e "${General::swroot}/red/active") {
013274d7 510 $errormessage = "$Lang::tr{'could not download latest updates'} - $Lang::tr{'system is offline'}";
43263ea6 511 }
52599865 512
3983aebd 513 # Check if enought free disk space is availabe.
434001d0
SS
514 if(&IDS::checkdiskspace()) {
515 $errormessage = "$Lang::tr{'not enough disk space'}";
516 }
52599865 517
43263ea6
SS
518 # Check if any errors happend.
519 unless ($errormessage) {
27760092
SS
520 # Lock the webpage and print notice about downloading
521 # a new ruleset.
5bd8940d 522 &working_notice("$Lang::tr{'ids download new ruleset'}");
3983aebd 523
43263ea6 524 # Call subfunction to download the ruleset.
434001d0
SS
525 if(&IDS::downloadruleset()) {
526 $errormessage = $Lang::tr{'could not download latest updates'};
8f22237b 527
3983aebd 528 # Call function to store the errormessage.
434001d0 529 &IDS::_store_error_message($errormessage);
52599865 530
3983aebd
SS
531 # Preform a reload of the page.
532 &reload();
533 } else {
534 # Call subfunction to launch oinkmaster.
535 &IDS::oinkmaster();
43263ea6 536
e2e7880d 537 # Check if the IDS is running.
5a28e721 538 if(&IDS::ids_is_running()) {
e2e7880d
SS
539 # Call suricatactrl to perform a reload.
540 &IDS::call_suricatactrl("reload");
541 }
542
3983aebd
SS
543 # Perform a reload of the page.
544 &reload();
545 }
52599865 546 }
5bd8940d 547# Save IDS settings.
e0bfd338 548} elsif ($cgiparams{'IDS'} eq $Lang::tr{'save'}) {
bbb6efae
SS
549 my %oldidssettings;
550 my $reload_page;
ebdd0f9a 551 my $monitored_zones = 0;
bbb6efae
SS
552
553 # Read-in current (old) IDS settings.
b02e30fd 554 &General::readhash("$IDS::ids_settings_file", \%oldidssettings);
bbb6efae 555
a232b58c 556 # Prevent form name from been stored in conf file.
e0bfd338 557 delete $cgiparams{'IDS'};
a232b58c 558
ebdd0f9a
SS
559 # Check if the IDS should be enabled.
560 if ($cgiparams{'ENABLE_IDS'} eq "on") {
561 # Check if any ruleset is available. Otherwise abort and display an error.
2f252efa 562 unless(%used_providers) {
ebdd0f9a
SS
563 $errormessage = $Lang::tr{'ids no ruleset available'};
564 }
565
566 # Loop through the array of available interfaces.
567 foreach my $zone (@network_zones) {
568 # Convert interface name into upper case.
569 my $zone_upper = uc($zone);
570
571 # Check if the IDS is enabled for this interaces.
572 if ($cgiparams{"ENABLE_IDS_$zone_upper"}) {
573 # Increase count.
574 $monitored_zones++;
575 }
576 }
577
578 # Check if at least one zone should be monitored, or show an error.
579 unless ($monitored_zones >= 1) {
580 $errormessage = $Lang::tr{'ids no network zone'};
581 }
582 }
583
a232b58c
SS
584 # Go on if there are no error messages.
585 if (!$errormessage) {
586 # Store settings into settings file.
b02e30fd 587 &General::writehash("$IDS::ids_settings_file", \%cgiparams);
a9a91e5f 588 }
8d2f6b0b 589
77351a6b
SS
590 # Check if the the automatic rule update hass been touched.
591 if($cgiparams{'AUTOUPDATE_INTERVAL'} ne $oldidssettings{'AUTOUPDATE_INTERVAL'}) {
592 # Call suricatactrl to set the new interval.
593 &IDS::call_suricatactrl("cron", $cgiparams{'AUTOUPDATE_INTERVAL'});
594 }
595
8d2f6b0b 596 # Generate file to store the home net.
b02e30fd 597 &IDS::generate_home_net_file();
e2e7880d 598
a40ee6b9
SS
599 # Generate file to the store the DNS servers.
600 &IDS::generate_dns_servers_file();
601
e698090e
SS
602 # Generate file to store the HTTP ports.
603 &IDS::generate_http_ports_file();
604
74cc8f5a 605 # Write the modify sid's file and pass the taken ruleaction.
81bae51f 606 &IDS::write_modify_sids_file();
bbb6efae 607
01d02eb6
SS
608 # Check if "MONITOR_TRAFFIC_ONLY" has been changed.
609 if($cgiparams{'MONITOR_TRAFFIC_ONLY'} ne $oldidssettings{'MONITOR_TRAFFIC_ONLY'}) {
bbb6efae 610 # Check if a ruleset exists.
2f252efa 611 if (%used_providers) {
bbb6efae 612 # Lock the webpage and print message.
5bd8940d 613 &working_notice("$Lang::tr{'ids working'}");
bbb6efae
SS
614
615 # Call oinkmaster to alter the ruleset.
616 &IDS::oinkmaster();
617
618 # Set reload_page to "True".
619 $reload_page="True";
620 }
621 }
622
e2e7880d
SS
623 # Check if the IDS currently is running.
624 if(&IDS::ids_is_running()) {
625 # Check if ENABLE_IDS is set to on.
626 if($cgiparams{'ENABLE_IDS'} eq "on") {
627 # Call suricatactrl to perform a reload of suricata.
628 &IDS::call_suricatactrl("reload");
629 } else {
630 # Call suricatactrl to stop suricata.
631 &IDS::call_suricatactrl("stop");
632 }
633 } else {
634 # Call suricatactrl to start suricata.
635 &IDS::call_suricatactrl("start");
636 }
bbb6efae
SS
637
638 # Check if the page should be reloaded.
639 if ($reload_page) {
640 # Perform a reload of the page.
641 &reload();
642 }
4c067847 643
9bf260de
SS
644# Toggle Enable/Disable autoupdate for a provider
645} elsif ($cgiparams{'AUTOUPDATE'} eq $Lang::tr{'toggle enable disable'}) {
646 my %used_providers = ();
647
648 # Only go further, if an ID has been passed.
649 if ($cgiparams{'ID'}) {
650 # Assign the given ID.
651 my $id = $cgiparams{'ID'};
652
653 # Undef the given ID.
654 undef($cgiparams{'ID'});
655
656 # Read-in providers settings file.
657 &General::readhasharray($IDS::providers_settings_file, \%used_providers);
658
659 # Grab the configured status of the corresponding entry.
660 my $status_autoupdate = $used_providers{$id}[2];
661
662 # Switch the status.
663 if ($status_autoupdate eq "disabled") {
664 $status_autoupdate = "enabled";
665 } else {
666 $status_autoupdate = "disabled";
667 }
668
669 # Modify the status of the existing entry.
670 $used_providers{$id} = ["$used_providers{$id}[0]", "$used_providers{$id}[1]", "$status_autoupdate", "$used_providers{$id}[3]"];
671
672 # Write the changed hash to the providers settings file.
673 &General::writehasharray($IDS::providers_settings_file, \%used_providers);
674 }
675
676# Add/Edit a provider to the list of used providers.
677#
4c067847 678} elsif (($cgiparams{'PROVIDERS'} eq "$Lang::tr{'add'}") || ($cgiparams{'PROVIDERS'} eq "$Lang::tr{'update'}")) {
aba3cbe5
SS
679 my %used_providers = ();
680
681 # Read-in providers settings file.
682 &General::readhasharray("$IDS::providers_settings_file", \%used_providers);
683
4c067847
SS
684 # Assign some nice human-readable values.
685 my $provider = $cgiparams{'PROVIDER'};
686 my $subscription_code = $cgiparams{'SUBSCRIPTION_CODE'};
bb4c30c6
SS
687 my $status_autoupdate;
688
689 # Handle autoupdate checkbox.
690 if ($cgiparams{'ENABLE_AUTOUPDATE'} eq "on") {
691 $status_autoupdate = "enabled";
692 } else {
693 $status_autoupdate = "disabled";
694 }
4c067847
SS
695
696 # Check if we are going to add a new provider.
697 if ($cgiparams{'PROVIDERS'} eq "$Lang::tr{'add'}") {
698 # Loop through the hash of used providers.
699 foreach my $id ( keys %used_providers) {
700 # Check if the choosen provider is already in use.
701 if ($used_providers{$id}[0] eq "$provider") {
702 # XXX - add to language file.
703 # Assign error message.
704 $errormessage = "The choosen provider is already in use.";
705 }
706 }
707 }
708
709 # Check if the provider requires a subscription code.
710 if ($IDS::Ruleset::Providers{$provider}{'requires_subscription'} eq "True") {
711 # Check if an subscription code has been provided.
712 if ($subscription_code) {
713 # Check if the code contains unallowed chars.
714 unless ($subscription_code =~ /^[a-z0-9]+$/) {
715 $errormessage = $Lang::tr{'invalid input for subscription code'};
716 }
717 } else {
718 # Print an error message, that an subsription code is required for this
719 # provider.
720 $errormessage = $Lang::tr{'ids subscription code required'};
721 }
722 }
723
724 # Go further if there was no error.
725 if ($errormessage eq '') {
726 my $id;
727 my $status;
728
729 # Check if we should edit an existing entry and got an ID.
730 if (($cgiparams{'PROVIDERS'} eq $Lang::tr{'update'}) && ($cgiparams{'ID'})) {
731 # Assin the provided id.
732 $id = $cgiparams{'ID'};
733
734 # Undef the given ID.
735 undef($cgiparams{'ID'});
736
737 # Grab the configured status of the corresponding entry.
738 $status = $used_providers{$id}[3];
739 } else {
740 # Each newly added entry automatically should be enabled.
741 $status = "enabled";
742
743 # Generate the ID for the new entry.
744 #
745 # Sort the keys by their ID and store them in an array.
746 my @keys = sort { $a <=> $b } keys %used_providers;
747
748 # Reverse the key array.
749 my @reversed = reverse(@keys);
750
751 # Obtain the last used id.
752 my $last_id = @reversed[0];
753
754 # Increase the last id by one and use it as id for the new entry.
755 $id = ++$last_id;
756 }
757
758 # Add/Modify the entry to/in the used providers hash..
759 $used_providers{$id} = ["$provider", "$subscription_code", "$status_autoupdate", "$status"];
760
761 # Write the changed hash to the providers settings file.
762 &General::writehasharray($IDS::providers_settings_file, \%used_providers);
763
764 # Undefine providers flag.
765 undef($cgiparams{'PROVIDERS'});
766 }
73eb03a3
SS
767
768## Toggle Enabled/Disabled for an existing provider.
769#
770} elsif ($cgiparams{'PROVIDERS'} eq $Lang::tr{'toggle enable disable'}) {
771 my %used_providers = ();
772
773 # Only go further, if an ID has been passed.
774 if ($cgiparams{'ID'}) {
775 # Assign the given ID.
776 my $id = $cgiparams{'ID'};
777
778 # Undef the given ID.
779 undef($cgiparams{'ID'});
780
781 # Read-in file which contains the provider settings.
782 &General::readhasharray($IDS::providers_settings_file, \%used_providers);
783
784 # Grab the configured status of the corresponding entry.
785 my $status = $used_providers{$id}[3];
786
787 # Switch the status.
788 if ($status eq "enabled") {
789 $status = "disabled";
790 } else {
791 $status = "enabled";
792 }
793
794 # Modify the status of the existing entry.
795 $used_providers{$id} = ["$used_providers{$id}[0]", "$used_providers{$id}[1]", "$used_providers{$id}[2]", "$status"];
796
797 # Write the changed hash to the providers settings file.
798 &General::writehasharray($IDS::providers_settings_file, \%used_providers);
799
800 # XXX - The ruleset needs to be regenerated
801 # XXX - Suricata requires a reload or if the last provider
802 # has been disabled suricata needs to be stopped.
803 # Check if the IDS is running.
804 #if(&IDS::ids_is_running()) {
805 # # Call suricatactrl to perform a reload.
806 # &IDS::call_suricatactrl("reload");
807 #}
808
809 # Undefine providers flag.
810 undef($cgiparams{'PROVIDERS'});
811 }
812
813## Remove provider from the list of used providers.
814#
815} elsif ($cgiparams{'PROVIDERS'} eq $Lang::tr{'remove'}) {
816 my %used_providers = ();
817
818 # Read-in provider settings file.
819 &General::readhasharray($IDS::providers_settings_file, \%used_providers);
820
821 # Drop entry from the hash.
822 delete($used_providers{$cgiparams{'ID'}});
823
824 # Undef the given ID.
825 undef($cgiparams{'ID'});
826
827 # Write the changed hash to the provide settings file.
828 &General::writehasharray($IDS::providers_settings_file, \%used_providers);
829
830 # XXX - The ruleset of the provider needs to be dropped.
831 # XXX - The remain rulest of suricata needs to be regenerated.
832 # XXX - Suricata requires a reload or if the last provider has
833 # been removed it has to be stopped.
834 # Check if the IDS is running.
835 #if(&IDS::ids_is_running()) {
836 # Call suricatactrl to perform a reload.
837 # &IDS::call_suricatactrl("reload");
838 #}
839
840 # Undefine providers flag.
841 undef($cgiparams{'PROVIDERS'});
ac1cfefa
MT
842}
843
ac1cfefa
MT
844&Header::openpage($Lang::tr{'intrusion detection system'}, 1, '');
845
2bbe6ede 846&Header::openbigbox('100%', 'left', '', $errormessage);
e0cec9fe 847
2bbe6ede 848&show_display_error_message();
0d34a479 849
2bbe6ede
SS
850if ($cgiparams{'RULESET'} eq "$Lang::tr{'ids customize ruleset'}" ) {
851 &show_customize_ruleset();
2f252efa
SS
852} elsif ($cgiparams{'PROVIDERS'} ne "") {
853 &show_add_provider();
2bbe6ede
SS
854} else {
855 &show_mainpage();
856}
029b8ed2 857
2bbe6ede
SS
858&Header::closebigbox();
859&Header::closepage();
e0cec9fe 860
2bbe6ede
SS
861#
862## Tiny function to show if a error message happened.
863#
864sub show_display_error_message() {
865 if ($errormessage) {
866 &Header::openbox('100%', 'left', $Lang::tr{'error messages'});
867 print "<class name='base'>$errormessage\n";
868 print "&nbsp;</class>\n";
869 &Header::closebox();
870 }
871}
e0cec9fe 872
2bbe6ede
SS
873#
874## Function to display the main IDS page.
875#
876sub show_mainpage() {
aba3cbe5 877 # Read-in idssettings and provider settings.
2bbe6ede 878 &General::readhash("$IDS::ids_settings_file", \%idssettings);
aba3cbe5 879 &General::readhasharray("$IDS::providers_settings_file", \%used_providers);
2bbe6ede
SS
880
881 # If no autoupdate intervall has been configured yet, set default value.
77351a6b 882 unless(exists($idssettings{'AUTOUPDATE_INTERVAL'})) {
2bbe6ede 883 # Set default to "weekly".
77351a6b 884 $idssettings{'AUTOUPDATE_INTERVAL'} = 'weekly';
17726644 885 }
2bbe6ede
SS
886
887 # Read-in ignored hosts.
888 &General::readhasharray("$IDS::settingsdir/ignored", \%ignored);
889
890 $checked{'ENABLE_IDS'}{'off'} = '';
891 $checked{'ENABLE_IDS'}{'on'} = '';
892 $checked{'ENABLE_IDS'}{$idssettings{'ENABLE_IDS'}} = "checked='checked'";
893 $checked{'MONITOR_TRAFFIC_ONLY'}{'off'} = '';
894 $checked{'MONITOR_TRAFFIC_ONLY'}{'on'} = '';
895 $checked{'MONITOR_TRAFFIC_ONLY'}{$idssettings{'MONITOR_TRAFFIC_ONLY'}} = "checked='checked'";
2bbe6ede
SS
896 $selected{'AUTOUPDATE_INTERVAL'}{'off'} = '';
897 $selected{'AUTOUPDATE_INTERVAL'}{'daily'} = '';
898 $selected{'AUTOUPDATE_INTERVAL'}{'weekly'} = '';
2f252efa 899 $selected{'AUTOUPDATE_INTERVAL'}{$idssettings{'AUTOUPDATE_INTERVAL'}} = "selected='selected'";
17726644 900
2bbe6ede
SS
901 # Draw current state of the IDS
902 &Header::openbox('100%', 'left', $Lang::tr{'intrusion detection system'});
1504a375 903
2bbe6ede
SS
904 # Check if the IDS is running and obtain the process-id.
905 my $pid = &IDS::ids_is_running();
87660964 906
2bbe6ede
SS
907 # Display some useful information, if suricata daemon is running.
908 if ($pid) {
909 # Gather used memory.
910 my $memory = &get_memory_usage($pid);
87660964 911
2bbe6ede
SS
912 print <<END;
913 <table width='95%' cellspacing='0' class='tbl'>
914 <tr>
915 <th bgcolor='$color{'color20'}' colspan='3' align='left'><strong>$Lang::tr{'intrusion detection'}</strong></th>
916 </tr>
87660964 917
2bbe6ede
SS
918 <tr>
919 <td class='base'>$Lang::tr{'guardian daemon'}</td>
920 <td align='center' colspan='2' width='75%' bgcolor='${Header::colourgreen}'><font color='white'><strong>$Lang::tr{'running'}</strong></font></td>
921 </tr>
87660964 922
2bbe6ede
SS
923 <tr>
924 <td class='base'></td>
925 <td bgcolor='$color{'color20'}' align='center'><strong>PID</strong></td>
926 <td bgcolor='$color{'color20'}' align='center'><strong>$Lang::tr{'memory'}</strong></td>
927 </tr>
87660964 928
2bbe6ede
SS
929 <tr>
930 <td class='base'></td>
931 <td bgcolor='$color{'color22'}' align='center'>$pid</td>
932 <td bgcolor='$color{'color22'}' align='center'>$memory KB</td>
933 </tr>
934 </table>
87660964 935END
2bbe6ede
SS
936 } else {
937 # Otherwise display a hint that the service is not launched.
938 print <<END;
939 <table width='95%' cellspacing='0' class='tbl'>
940 <tr>
941 <th bgcolor='$color{'color20'}' colspan='3' align='left'><strong>$Lang::tr{'intrusion detection'}</strong></th>
942 </tr>
87660964 943
2bbe6ede
SS
944 <tr>
945 <td class='base'>$Lang::tr{'guardian daemon'}</td>
946 <td align='center' width='75%' bgcolor='${Header::colourred}'><font color='white'><strong>$Lang::tr{'stopped'}</strong></font></td>
947 </tr>
948 </table>
87660964 949END
2bbe6ede 950 }
87660964 951
2f252efa
SS
952 # Only show this area, if at least one ruleset provider is configured.
953 if (%used_providers) {
674912fc 954
2bbe6ede 955print <<END
674912fc 956
2bbe6ede 957 <br><br><h2>$Lang::tr{'settings'}</h2>
1286e0d4 958
2bbe6ede
SS
959 <form method='post' action='$ENV{'SCRIPT_NAME'}'>
960 <table width='100%' border='0'>
961 <tr>
962 <td class='base' colspan='2'>
963 <input type='checkbox' name='ENABLE_IDS' $checked{'ENABLE_IDS'}{'on'}>&nbsp;$Lang::tr{'ids enable'}
964 </td>
cf02bf2f 965
2bbe6ede
SS
966 <td class='base' colspan='2'>
967 <input type='checkbox' name='MONITOR_TRAFFIC_ONLY' $checked{'MONITOR_TRAFFIC_ONLY'}{'on'}>&nbsp;$Lang::tr{'ids monitor traffic only'}
968 </td>
969 </tr>
1504a375 970
2bbe6ede
SS
971 <tr>
972 <td><br><br></td>
973 <td><br><br></td>
974 <td><br><br></td>
975 <td><br><br></td>
976 </tr>
a4ccfcbb 977
2bbe6ede
SS
978 <tr>
979 <td colspan='4'><b>$Lang::tr{'ids monitored interfaces'}</b><br></td>
980 </tr>
a4ccfcbb 981
2bbe6ede 982 <tr>
ac1cfefa
MT
983END
984;
1504a375 985
2bbe6ede
SS
986 # Loop through the array of available networks and print config options.
987 foreach my $zone (@network_zones) {
988 my $checked_input;
989 my $checked_forward;
1504a375 990
2bbe6ede
SS
991 # Convert current zone name to upper case.
992 my $zone_upper = uc($zone);
1504a375 993
2bbe6ede
SS
994 # Set zone name.
995 my $zone_name = $zone;
53817b89 996
2bbe6ede
SS
997 # Dirty hack to get the correct language string for the red zone.
998 if ($zone eq "red") {
999 $zone_name = "red1";
1000 }
53817b89 1001
2bbe6ede
SS
1002 # Grab checkbox status from settings hash.
1003 if ($idssettings{"ENABLE_IDS_$zone_upper"} eq "on") {
1004 $checked_input = "checked = 'checked'";
1005 }
1504a375 1006
2bbe6ede
SS
1007 print "<td class='base' width='20%'>\n";
1008 print "<input type='checkbox' name='ENABLE_IDS_$zone_upper' $checked_input>\n";
1009 print "&nbsp;$Lang::tr{'enabled on'}<font color='$colourhash{$zone}'> $Lang::tr{$zone_name}</font>\n";
1010 print "</td>\n";
1011 }
1b73b07e 1012
ac1cfefa 1013print <<END
2bbe6ede 1014 </tr>
77351a6b
SS
1015
1016 <tr>
1017 <td><br><br></td>
1018 <td><br><br></td>
1019 <td><br><br></td>
1020 <td><br><br></td>
1021 </tr>
1022
1023 <tr>
1024 <td colspan='4'><b>$Lang::tr{'ids automatic rules update'}</b></td>
1025 </tr>
1026
1027 <tr>
1028 <td>
1029 <select name='AUTOUPDATE_INTERVAL'>
1030 <option value='off' $selected{'AUTOUPDATE_INTERVAL'}{'off'} >- $Lang::tr{'Disabled'} -</option>
1031 <option value='daily' $selected{'AUTOUPDATE_INTERVAL'}{'daily'} >$Lang::tr{'Daily'}</option>
1032 <option value='weekly' $selected{'AUTOUPDATE_INTERVAL'}{'weekly'} >$Lang::tr{'Weekly'}</option>
1033 </select>
1034 </td>
1035 </tr>
2bbe6ede 1036 </table>
1504a375 1037
2bbe6ede 1038 <br><br>
ea5c8eeb 1039
2bbe6ede
SS
1040 <table width='100%'>
1041 <tr>
1042 <td align='right'><input type='submit' name='IDS' value='$Lang::tr{'save'}' /></td>
1043 </tr>
1044 </table>
1045 </form>
ea5c8eeb
SS
1046END
1047;
1048
2bbe6ede 1049 }
cf02bf2f 1050
2bbe6ede 1051 &Header::closebox();
ea5c8eeb 1052
2f252efa
SS
1053 #
1054 # Used Ruleset Providers section.
1055 #
2bbe6ede 1056 &Header::openbox('100%', 'center', $Lang::tr{'ids ruleset settings'});
ea5c8eeb 1057
2f252efa
SS
1058print <<END;
1059 <table width='100%' border='0'>
1060 <tr>
1061 <td class='base' bgcolor='$color{'color20'}'><b>$Lang::tr{'ids provider'}</b></td>
1062 <td class='base' bgcolor='$color{'color20'}'><b>$Lang::tr{'date'}</b></td>
1063 <td class='base' bgcolor='$color{'color20'}' align='center'><b>$Lang::tr{'ids autoupdates'}</b></td>
1064 <td class='base' bgcolor='$color{'color20'}'></td>
1065 <td class='base' colspan='3' bgcolor='$color{'color20'}'></td>
1066 </tr>
3e12c6e6 1067END
2f252efa
SS
1068 # Check if some providers has been configured.
1069 if (keys (%used_providers)) {
1070 my $col = "";
3e12c6e6 1071
2f252efa 1072 # Loop through all entries of the hash.
2f252efa
SS
1073 foreach my $id (sort keys(%used_providers)) {
1074 # Assign data array positions to some nice variable names.
1075 my $provider = $used_providers{$id}[0];
1076 my $provider_name = &get_provider_name($provider);
3e12c6e6 1077
2f252efa
SS
1078 #XXX my $rulesdate = &IDS::get_ruleset_date($provider);
1079 my $rulesdate;
1080
1081 my $subscription_code = $used_providers{$id}[1];
1082 my $autoupdate_status = $used_providers{$id}[2];
1083 my $status = $used_providers{$id}[3];
1084
1085 # Check if the item number is even or not.
1086 if ($id % 2) {
1087 $col="bgcolor='$color{'color22'}'";
1088 } else {
1089 $col="bgcolor='$color{'color20'}'";
2bbe6ede 1090 }
1504a375 1091
2f252efa
SS
1092 # Choose icons for the checkboxes.
1093 my $status_gif;
1094 my $status_gdesc;
1095 my $autoupdate_status_gif;
1096 my $autoupdate_status_gdesc;
1504a375 1097
2f252efa
SS
1098 # Check if the status is enabled and select the correct image and description.
1099 if ($status eq 'enabled' ) {
1100 $status_gif = 'on.gif';
1101 $status_gdesc = $Lang::tr{'click to disable'};
1102 } else {
1103 $status_gif = 'off.gif';
1104 $status_gdesc = $Lang::tr{'click to enable'};
1105 }
1504a375 1106
2f252efa
SS
1107 # Check if the autoupdate status is enabled and select the correct image and description.
1108 if ($autoupdate_status eq 'enabled') {
1109 $autoupdate_status_gif = 'on.gif';
1110 $autoupdate_status_gdesc = $Lang::tr{'click to disable'};
1111 } else {
1112 $autoupdate_status_gif = 'off.gif';
1113 $autoupdate_status_gdesc = $Lang::tr{'click to enable'};
1114 }
2bbe6ede 1115
2f252efa
SS
1116print <<END;
1117 <tr>
1118 <td width='33%' class='base' $col>$provider_name</td>
1119 <td width='30%' class='base' $col>$rulesdate</td>
1120
1121 <td align='center' $col>
1122 <form method='post' action='$ENV{'SCRIPT_NAME'}'>
1123 <input type='hidden' name='AUTOUPDATE' value='$Lang::tr{'toggle enable disable'}' />
1124 <input type='image' name='$Lang::tr{'toggle enable disable'}' src='/images/$autoupdate_status_gif' alt='$autoupdate_status_gdesc' title='$autoupdate_status_gdesc' />
1125 <input type='hidden' name='ID' value='$id' />
1126 </form>
1127 </td>
1128
1129 <td align='center' $col>
7323c72d 1130 <form method='post' action='$ENV{'SCRIPT_NAME'}'>
2f252efa
SS
1131 <input type='hidden' name='PROVIDERS' value='$Lang::tr{'toggle enable disable'}'>
1132 <input type='image' name='$Lang::tr{'toggle enable disable'}' src='/images/$status_gif' alt='$status_gdesc' title='$status_gdesc'>
1133 <input type='hidden' name='ID' value='$id'>
1134 </form>
1135 </td>
1136
1137 <td align='center' $col>
1138 <form method='post' action='$ENV{'SCRIPT_NAME'}'>
1139 <input type='hidden' name='PROVIDERS' value='$Lang::tr{'edit'}'>
1140 <input type='image' name='$Lang::tr{'edit'}' src='/images/edit.gif' alt='$Lang::tr{'edit'}' title='$Lang::tr{'edit'}'>
1141 <input type='hidden' name='ID' value='$id'>
1142 </form>
1143 </td>
1504a375 1144
2f252efa
SS
1145 <td align='center' $col>
1146 <form method='post' name='$provider' action='$ENV{'SCRIPT_NAME'}'>
1147 <input type='image' name='$Lang::tr{'remove'}' src='/images/delete.gif' title='$Lang::tr{'remove'}' alt='$Lang::tr{'remove'}'>
1148 <input type='hidden' name='ID' value='$id'>
1149 <input type='hidden' name='PROVIDERS' value='$Lang::tr{'remove'}'>
1150 </form>
1151 </td>
1152 </tr>
ea5c8eeb 1153END
2bbe6ede 1154 }
2f252efa
SS
1155
1156 } else {
1157 # Print notice that currently no hosts are ignored.
1158 print "<tr>\n";
1159 print "<td class='base' colspan='2'>$Lang::tr{'guardian no entries'}</td>\n";
1160 print "</tr>\n";
1161 }
1162
1163 print "</table>\n";
1164
1165 # Section to add new elements or edit existing ones.
ea5c8eeb 1166print <<END;
2f252efa
SS
1167 <br>
1168 <hr>
1169 <br>
1504a375 1170
2f252efa
SS
1171 <div align='right'>
1172 <table width='100%'>
1173 <form method='post' action='$ENV{'SCRIPT_NAME'}'>
1174 <tr>
1175END
1176
1177 # Only show this button if a ruleset provider is configured.
1178 if (%used_providers) {
1179 print "<input type='submit' name='RULESET' value='$Lang::tr{'ids customize ruleset'}'>\n";
1180 }
1181print <<END;
1182 <input type='submit' name='PROVIDERS' value='$Lang::tr{'ids add provider'}'>
1183 </tr>
1184 </form>
2bbe6ede 1185 </table>
2f252efa 1186 </div>
ac1cfefa 1187END
ac1cfefa 1188
2bbe6ede 1189 &Header::closebox();
fbfdb241 1190
2bbe6ede
SS
1191 #
1192 # Whitelist / Ignorelist
1193 #
1194 &Header::openbox('100%', 'center', $Lang::tr{'ids ignored hosts'});
b7e29743 1195
2bbe6ede 1196 print <<END;
b7e29743
SS
1197 <table width='100%'>
1198 <tr>
1199 <td class='base' bgcolor='$color{'color20'}'><b>$Lang::tr{'ip address'}</b></td>
1200 <td class='base' bgcolor='$color{'color20'}'><b>$Lang::tr{'remark'}</b></td>
1201 <td class='base' colspan='3' bgcolor='$color{'color20'}'></td>
1202 </tr>
1203END
1204 # Check if some hosts have been added to be ignored.
1205 if (keys (%ignored)) {
1206 my $col = "";
1207
1208 # Loop through all entries of the hash.
1209 while( (my $key) = each %ignored) {
1210 # Assign data array positions to some nice variable names.
1211 my $address = $ignored{$key}[0];
1212 my $remark = $ignored{$key}[1];
1213 my $status = $ignored{$key}[2];
1214
1215 # Check if the key (id) number is even or not.
1216 if ($cgiparams{'ID'} eq $key) {
1217 $col="bgcolor='${Header::colouryellow}'";
1218 } elsif ($key % 2) {
1219 $col="bgcolor='$color{'color22'}'";
1220 } else {
1221 $col="bgcolor='$color{'color20'}'";
1222 }
1223
1224 # Choose icon for the checkbox.
1225 my $gif;
1226 my $gdesc;
1227
1228 # Check if the status is enabled and select the correct image and description.
1229 if ($status eq 'enabled' ) {
1230 $gif = 'on.gif';
1231 $gdesc = $Lang::tr{'click to disable'};
1232 } else {
1233 $gif = 'off.gif';
1234 $gdesc = $Lang::tr{'click to enable'};
1235 }
1236
1237print <<END;
1238 <tr>
1239 <td width='20%' class='base' $col>$address</td>
1240 <td width='65%' class='base' $col>$remark</td>
1241
1242 <td align='center' $col>
1243 <form method='post' action='$ENV{'SCRIPT_NAME'}'>
2f252efa
SS
1244 <input type='hidden' name='WHITELIST' value='$Lang::tr{'toggle enable disable'}'>
1245 <input type='image' name='$Lang::tr{'toggle enable disable'}' src='/images/$gif' alt='$gdesc' title='$gdesc'>
1246 <input type='hidden' name='ID' value='$key'>
b7e29743
SS
1247 </form>
1248 </td>
1249
1250 <td align='center' $col>
1251 <form method='post' action='$ENV{'SCRIPT_NAME'}'>
2f252efa
SS
1252 <input type='hidden' name='WHITELIST' value='$Lang::tr{'edit'}'>
1253 <input type='image' name='$Lang::tr{'edit'}' src='/images/edit.gif' alt='$Lang::tr{'edit'}' title='$Lang::tr{'edit'}'>
1254 <input type='hidden' name='ID' value='$key'>
b7e29743
SS
1255 </form>
1256 </td>
1257
1258 <td align='center' $col>
1259 <form method='post' name='$key' action='$ENV{'SCRIPT_NAME'}'>
1260 <input type='image' name='$Lang::tr{'remove'}' src='/images/delete.gif' title='$Lang::tr{'remove'}' alt='$Lang::tr{'remove'}'>
1261 <input type='hidden' name='ID' value='$key'>
1262 <input type='hidden' name='WHITELIST' value='$Lang::tr{'remove'}'>
1263 </form>
2bbe6ede
SS
1264 </td>
1265 </tr>
b7e29743 1266END
2bbe6ede
SS
1267 }
1268 } else {
1269 # Print notice that currently no hosts are ignored.
1270 print "<tr>\n";
1271 print "<td class='base' colspan='2'>$Lang::tr{'guardian no entries'}</td>\n";
1272 print "</tr>\n";
b7e29743 1273 }
b7e29743 1274
2bbe6ede 1275 print "</table>\n";
b7e29743 1276
2bbe6ede 1277 # Section to add new elements or edit existing ones.
b7e29743 1278print <<END;
2bbe6ede
SS
1279 <br>
1280 <hr>
1281 <br>
1282
1283 <div align='center'>
1284 <table width='100%'>
b7e29743
SS
1285END
1286
2bbe6ede
SS
1287 # Assign correct headline and button text.
1288 my $buttontext;
1289 my $entry_address;
1290 my $entry_remark;
b7e29743 1291
2bbe6ede
SS
1292 # Check if an ID (key) has been given, in this case an existing entry should be edited.
1293 if ($cgiparams{'ID'} ne '') {
1294 $buttontext = $Lang::tr{'update'};
1295 print "<tr><td class='boldbase' colspan='3'><b>$Lang::tr{'update'}</b></td></tr>\n";
b7e29743 1296
2bbe6ede
SS
1297 # Grab address and remark for the given key.
1298 $entry_address = $ignored{$cgiparams{'ID'}}[0];
1299 $entry_remark = $ignored{$cgiparams{'ID'}}[1];
1300 } else {
1301 $buttontext = $Lang::tr{'add'};
1302 print "<tr><td class='boldbase' colspan='3'><b>$Lang::tr{'dnsforward add a new entry'}</b></td></tr>\n";
1303 }
b7e29743
SS
1304
1305print <<END;
2bbe6ede
SS
1306 <form method='post' action='$ENV{'SCRIPT_NAME'}'>
1307 <input type='hidden' name='ID' value='$cgiparams{'ID'}'>
1308 <tr>
1309 <td width='30%'>$Lang::tr{'ip address'}: </td>
1310 <td width='50%'><input type='text' name='IGNORE_ENTRY_ADDRESS' value='$entry_address' size='24' /></td>
b7e29743 1311
2bbe6ede
SS
1312 <td width='30%'>$Lang::tr{'remark'}: </td>
1313 <td wicth='50%'><input type='text' name=IGNORE_ENTRY_REMARK value='$entry_remark' size='24' /></td>
1314 <td align='center' width='20%'><input type='submit' name='WHITELIST' value='$buttontext' /></td>
1315 </tr>
1316 </form>
1317 </table>
1318 </div>
b7e29743
SS
1319END
1320
2bbe6ede 1321 &Header::closebox();
fed57fe7
SS
1322}
1323
fed57fe7
SS
1324#
1325## Function to show the customize ruleset section.
1326#
1327sub show_customize_ruleset() {
2bbe6ede
SS
1328 ### Java Script ###
1329 print"<script>\n";
1330
1331 # Java script variable declaration for show and hide.
1332 print"var show = \"$Lang::tr{'ids show'}\"\;\n";
1333 print"var hide = \"$Lang::tr{'ids hide'}\"\;\n";
1334
1335print <<END
1336 // Tiny java script function to show/hide the rules
1337 // of a given category.
1338 function showhide(tblname) {
1339 \$("#" + tblname).toggle();
1340
1341 // Get current content of the span element.
1342 var content = document.getElementById("span_" + tblname);
1343
1344 if (content.innerHTML === show) {
1345 content.innerHTML = hide;
1346 } else {
1347 content.innerHTML = show;
1348 }
1349 }
1350 </script>
1351END
1352;
87df37da 1353 &Header::openbox('100%', 'LEFT', "$Lang::tr{'intrusion detection system rules'}" );
80bcd4dd 1354 print"<form method='POST' action='$ENV{'SCRIPT_NAME'}'>\n";
ce0e83b3 1355
80bcd4dd
SS
1356 # Output display table for rule files
1357 print "<table width='100%'>\n";
f7fcd1c0 1358
80bcd4dd
SS
1359 # Loop over each rule file
1360 foreach my $rulefile (sort keys(%idsrules)) {
1361 my $rulechecked = '';
3ffee04b 1362
80bcd4dd
SS
1363 # Check if rule file is enabled
1364 if ($idsrules{$rulefile}{'Rulefile'}{'State'} eq 'on') {
1365 $rulechecked = 'CHECKED';
1366 }
1367
0a1bba1a
SS
1368 # Convert rulefile name into category name.
1369 my $categoryname = &_rulefile_to_category($rulefile);
1370
80bcd4dd
SS
1371 # Table and rows for the rule files.
1372 print"<tr>\n";
1373 print"<td class='base' width='5%'>\n";
1374 print"<input type='checkbox' name='$rulefile' $rulechecked>\n";
1375 print"</td>\n";
1376 print"<td class='base' width='90%'><b>$rulefile</b></td>\n";
1377 print"<td class='base' width='5%' align='right'>\n";
e0cec9fe 1378 print"<a href=\"javascript:showhide('$categoryname')\"><span id='span_$categoryname'>$Lang::tr{'ids show'}</span></a>\n";
80bcd4dd
SS
1379 print"</td>\n";
1380 print"</tr>\n";
1381
1382 # Rows which will be hidden per default and will contain the single rules.
0a1bba1a 1383 print"<tr style='display:none' id='$categoryname'>\n";
80bcd4dd 1384 print"<td colspan='3'>\n";
17726644 1385
f7fcd1c0 1386 # Local vars
80bcd4dd
SS
1387 my $lines;
1388 my $rows;
1389 my $col;
f9c2147d 1390
80bcd4dd
SS
1391 # New table for the single rules.
1392 print "<table width='100%'>\n";
e5738079 1393
80bcd4dd
SS
1394 # Loop over rule file rules
1395 foreach my $sid (sort {$a <=> $b} keys(%{$idsrules{$rulefile}})) {
1396 # Local vars
1397 my $ruledefchecked = '';
3ffee04b 1398
80bcd4dd
SS
1399 # Skip rulefile itself.
1400 next if ($sid eq "Rulefile");
f7fcd1c0 1401
80bcd4dd
SS
1402 # If 2 rules have been displayed, start a new row
1403 if (($lines % 2) == 0) {
1404 print "</tr><tr>\n";
1405
1406 # Increase rows by once.
1407 $rows++;
1408 }
1409
1410 # Colour lines.
1411 if ($rows % 2) {
1412 $col="bgcolor='$color{'color20'}'";
1413 } else {
1414 $col="bgcolor='$color{'color22'}'";
1415 }
f7fcd1c0 1416
80bcd4dd
SS
1417 # Set rule state
1418 if ($idsrules{$rulefile}{$sid}{'State'} eq 'on') {
1419 $ruledefchecked = 'CHECKED';
1420 }
1421
1422 # Create rule checkbox and display rule description
1423 print "<td class='base' width='5%' align='right' $col>\n";
1424 print "<input type='checkbox' NAME='$sid' $ruledefchecked>\n";
1425 print "</td>\n";
1426 print "<td class='base' width='45%' $col>$idsrules{$rulefile}{$sid}{'Description'}</td>";
1427
1428 # Increment rule count
1429 $lines++;
f7fcd1c0 1430 }
3ffee04b 1431
80bcd4dd
SS
1432 # If do not have a second rule for row, create empty cell
1433 if (($lines % 2) != 0) {
1434 print "<td class='base'></td>";
1435 }
17726644 1436
80bcd4dd
SS
1437 # Close display table
1438 print "</tr></table></td></tr>";
f7fcd1c0
SS
1439 }
1440
1441 # Close display table
80bcd4dd 1442 print "</table>";
17726644 1443
9268cddf 1444 print <<END
2999f1d2
CS
1445<table width='100%'>
1446<tr>
4efc8ccd
SS
1447 <td width='100%' align='right'>
1448 <input type='submit' value='$Lang::tr{'fwhost back'}'>
1449 <input type='submit' name='RULESET' value='$Lang::tr{'ids apply'}'>
1450 </td>
2999f1d2
CS
1451</tr>
1452</table>
298723b9 1453</form>
3ffee04b
CS
1454END
1455;
9268cddf
MT
1456 &Header::closebox();
1457 }
80bcd4dd
SS
1458}
1459
2f252efa
SS
1460#
1461## Function to show section for add/edit a provider.
1462#
1463sub show_add_provider() {
aba3cbe5 1464 my %used_providers = ();
2f252efa
SS
1465 my @subscription_providers;
1466
aba3cbe5
SS
1467 # Read -in providers settings file.
1468 &General::readhasharray("$IDS::providers_settings_file", \%used_providers);
1469
2f252efa
SS
1470 # Get all supported ruleset providers.
1471 my @ruleset_providers = &IDS::get_ruleset_providers();
1472
1473 ### Java Script ###
1474 print "<script>\n";
1475
1476 # Generate Java Script Object which contains the URL of the providers.
1477 print "\t// Object, which contains the webpages of the ruleset providers.\n";
1478 print "\tvar url = {\n";
1479
1480 # Loop through the array of supported providers.
1481 foreach my $provider (@ruleset_providers) {
1482 # Check if the provider requires a subscription.
1483 if ($IDS::Ruleset::Providers{$provider}{'requires_subscription'} eq "True") {
1484 # Add the provider to the array of subscription_providers.
1485 push(@subscription_providers, $provider);
1486 }
1487
1488 # Grab the URL for the provider.
1489 my $url = $IDS::Ruleset::Providers{$provider}{'website'};
1490
1491 # Print the URL to the Java Script Object.
1492 print "\t\t$provider: \"$url\"\,\n";
1493 }
1494
1495 # Close the Java Script Object declaration.
1496 print "\t}\;\n\n";
1497
1498 # Generate Java Script Array which contains the provider that requires a subscription.
1499 my $line = "";
1500 $line = join("', '", @subscription_providers);
1501
1502 print "\t// Array which contains the providers that requires a subscription.\n";
1503 print "\tsubscription_provider = ['$line']\;\n\n";
1504
1505print <<END
1506 // Java Script function to swap the text input field for
1507 // entering a subscription code.
1508 var update_provider = function() {
1509 if(inArray(\$('#PROVIDER').val(), subscription_provider)) {
1510 \$('.subscription_code').show();
1511 } else {
1512 \$('.subscription_code').hide();
1513 }
1514
1515 // Call function to change the website url.
1516 change_url(\$('#PROVIDER').val());
1517 };
1518
1519 // Java Script function to check if a given value is part of
1520 // an array.
1521 function inArray(value,array) {
1522 var count=array.length;
1523
1524 for(var i=0;i<count;i++) {
1525 if(array[i]===value){
1526 return true;
1527 }
1528 }
1529
1530 return false;
1531 }
1532
1533 // Tiny function to change the website url based on the selected element in the "PROVIDERS"
1534 // dropdown menu.
1535 function change_url(provider) {
1536 // Get and change the href to the corresponding url.
1537 document.getElementById("website").href = url[provider];
1538 }
1539
1540 // JQuery function to call corresponding function when
1541 // the ruleset provider is changed or the page is loaded for showing/hiding
1542 // the subscription_code area.
1543 \$(document).ready(function() {
1544 \$('#PROVIDER').change(update_provider);
1545 update_provider();
1546 });
1547
1548 </script>
1549END
1550;
1551
1552 &Header::openbox('100%', 'center', $Lang::tr{'ids provider settings'});
1553
1554 # Check if an existing provider should be edited.
1555 if($cgiparams{'PROVIDERS'} eq "$Lang::tr{'edit'}") {
1556 # Check if autoupdate is enabled for this provider.
bb4c30c6 1557 if ($used_providers{$cgiparams{'ID'}}[2] eq "enabled") {
2f252efa
SS
1558 # Set the checkbox to be checked.
1559 $checked{'ENABLE_AUTOUPDATE'} = "checked='checked'";
1560 }
1561 } elsif ($cgiparams{'PROVIDERS'} eq "$Lang::tr{'ids add provider'}") {
1562 # Set the autoupdate to true as default.
1563 $checked{'ENABLE_AUTOUPDATE'} = "checked='checked'";
1564 }
1565
1566print <<END
1567 <form method='post' action='$ENV{'SCRIPT_NAME'}'>
1568 <table width='100%' border='0'>
1569 <tr>
1570 <td colspan='2'><b>$Lang::tr{'ids provider'}</b></td>
1571 </tr>
1572
1573 <tr>
1574 <td width='40%'>
1575 <input type='hidden' name='ID' value='$cgiparams{'ID'}'>
1576 <select name='PROVIDER' id='PROVIDER'>
1577END
1578;
1579 # Loop through the array of ruleset providers.
1580 foreach my $provider (@ruleset_providers) {
1581 # Get the provider name.
1582 my $provider_name = &get_provider_name($provider);
1583
1584 # Pre-select the provider if one is given.
1585 if (($used_providers{$cgiparams{'ID'}}[0] eq "$provider") || ($cgiparams{'PROVIDER'} eq "$provider")) {
1586 $selected{$provider} = "selected='selected'";
1587 }
1588
1589 # Add the provider to the dropdown menu.
1590 print "<option value='$provider' $selected{$provider}>$provider_name</option>\n";
1591 }
1592print <<END
1593 </select>
1594 </td>
1595
1596 <td width='60%'>
1597 <b><a id="website" target="_blank" href="#">$Lang::tr{'ids visit provider website'}</a></b>
1598 </td>
1599 </tr>
1600
1601 <tr>
1602 <td colspan='2'><br><br></td>
1603 </tr>
1604
1605 <tr class='subscription_code' style='display:none' id='subscription_code'>
1606 <td colspan='2'>
1607 <table border='0'>
1608 <tr>
1609 <td>
1610 <b>$Lang::tr{'subscription code'}</b>
1611 </td>
1612 </tr>
1613
1614 <tr>
1615 <td>
1616 <input type='text' size='40' name='SUBSCRIPTION_CODE' value='$used_providers{$cgiparams{'ID'}}[1]'>
1617 </td>
1618 </tr>
1619
1620 <tr>
1621 <td><br><br></td>
1622 </tr>
1623 </table>
1624 </td>
1625 </tr>
1626
1627 <tr>
1628 <td colspan='2'>
1629 <input type='checkbox' name='ENABLE_AUTOUPDATE' $checked{'ENABLE_AUTOUPDATE'}>&nbsp;$Lang::tr{'ids enable automatic updates'}
1630 </td>
1631 </tr>
1632
1633 <tr>
1634 <td colspan='2' align='right'>
1635 <input type='submit' value='$Lang::tr{'back'}'>
1636END
1637;
1638 # Check if a provider should be added or edited.
1639 if ($cgiparams{'PROVIDERS'} eq "$Lang::tr{'edit'}") {
1640 # Display button for updating the existing provider.
1641 print "<input type='submit' name='PROVIDERS' value='$Lang::tr{'update'}'>\n";
1642 } else {
1643 # Display button to add the new provider.
1644 print "<input type='submit' name='PROVIDERS' value='$Lang::tr{'add'}'>\n";
1645 }
1646print <<END
1647 </td>
1648 </tr>
1649 </table>
1650 </form>
1651END
1652;
1653 &Header::closebox();
1654}
1655
27760092
SS
1656#
1657## A function to display a notice, to lock the webpage and
1658## tell the user which action currently will be performed.
1659#
1660sub working_notice ($) {
1661 my ($message) = @_;
1662
1663 &Header::openpage($Lang::tr{'intrusion detection system'}, 1, '');
1664 &Header::openbigbox('100%', 'left', '', $errormessage);
1665 &Header::openbox( 'Waiting', 1,);
1666 print <<END;
1667 <table>
1668 <tr>
1669 <td><img src='/images/indicator.gif' alt='$Lang::tr{'aktiv'}' /></td>
1670 <td>$message</td>
1671 </tr>
1672 </table>
1673END
1674 &Header::closebox();
1675 &Header::closebigbox();
1676 &Header::closepage();
1677}
1678
3983aebd
SS
1679#
1680## A tiny function to perform a reload of the webpage after one second.
1681#
1682sub reload () {
1683 print "<meta http-equiv='refresh' content='1'>\n";
1684
1685 # Stop the script.
1686 exit;
a70d269a
SS
1687}
1688
25f5cb0d
SS
1689#
1690## Private function to read-in and parse rules of a given rulefile.
1691#
1692## The given file will be read, parsed and all valid rules will be stored by ID,
9d18656b 1693## message/description and it's state in the idsrules hash.
25f5cb0d 1694#
3da6e01b
SS
1695sub readrulesfile ($) {
1696 my $rulefile = shift;
1697
1698 # Open rule file and read in contents
298ef5ba 1699 open(RULEFILE, "$IDS::rulespath/$rulefile") or die "Unable to read $rulefile!";
3da6e01b
SS
1700
1701 # Store file content in an array.
1702 my @lines = <RULEFILE>;
1703
1704 # Close file.
1705 close(RULEFILE);
1706
1707 # Loop over rule file contents
1708 foreach my $line (@lines) {
1709 # Remove whitespaces.
1710 chomp $line;
1711
1712 # Skip blank lines.
1713 next if ($line =~ /^\s*$/);
1714
1715 # Local vars.
1716 my $sid;
1717 my $msg;
1718
1719 # Gather rule sid and message from the ruleline.
1720 if ($line =~ m/.*msg:\"(.*?)\"\; .* sid:(.*?); /) {
1721 $msg = $1;
1722 $sid = $2;
1723
1724 # Check if a rule has been found.
1725 if ($sid && $msg) {
9d18656b
SS
1726 # Add rule to the idsrules hash.
1727 $idsrules{$rulefile}{$sid}{'Description'} = $msg;
3da6e01b
SS
1728
1729 # Grab status of the rule. Check if ruleline starts with a "dash".
1730 if ($line =~ /^\#/) {
1731 # If yes, the rule is disabled.
9d18656b 1732 $idsrules{$rulefile}{$sid}{'State'} = "off";
3da6e01b
SS
1733 } else {
1734 # Otherwise the rule is enabled.
9d18656b 1735 $idsrules{$rulefile}{$sid}{'State'} = "on";
3da6e01b
SS
1736 }
1737 }
1738 }
b7e29743 1739 }
3da6e01b 1740}
87660964 1741
8d2f6b0b
SS
1742#
1743## Function to get the used memory of a given process-id.
1744#
87660964 1745sub get_memory_usage($) {
004b13b7 1746 my ($pid) = @_;
87660964 1747
004b13b7 1748 my $memory = 0;
87660964 1749
004b13b7 1750 # Try to open the status file for the given process-id on the pseudo
87660964 1751 # file system proc.
004b13b7
SS
1752 if (open(FILE, "/proc/$pid/status")) {
1753 # Loop through the entire file.
1754 while (<FILE>) {
1755 # Splitt current line content and store them into variables.
1756 my ($key, $value) = split(":", $_, 2);
1757
1758 # Check if the current key is the one which contains the memory usage.
1759 # The wanted one is VmRSS which contains the Real-memory (resident set)
1760 # of the entire process.
1761 if ($key eq "VmRSS") {
1762 # Found the memory usage add it to the memory variable.
1763 $memory += $value;
1764
1765 # Break the loop.
1766 last;
1767 }
1768 }
87660964
SS
1769
1770 # Close file handle.
004b13b7 1771 close(FILE);
87660964
SS
1772
1773 # Return memory usage.
1774 return $memory;
004b13b7 1775 }
87660964
SS
1776
1777 # If the file could not be open, return nothing.
1778 return;
1779}
1780
a5d61752
SS
1781#
1782## Function to read-in the given enabled or disables sids file.
1783#
1784sub read_enabled_disabled_sids_file($) {
1785 my ($file) = @_;
1786
1787 # Temporary hash to store the sids and their state. It will be
1788 # returned at the end of this function.
1789 my %temphash;
1790
1791 # Open the given filename.
1792 open(FILE, "$file") or die "Could not open $file. $!\n";
1793
1794 # Loop through the file.
1795 while(<FILE>) {
1796 # Remove newlines.
1797 chomp $_;
1798
1799 # Skip blank lines.
1800 next if ($_ =~ /^\s*$/);
1801
1802 # Skip coments.
1803 next if ($_ =~ /^\#/);
1804
1805 # Splitt line into sid and state part.
1806 my ($state, $sid) = split(" ", $_);
1807
1808 # Skip line if the sid is not numeric.
1809 next unless ($sid =~ /\d+/ );
1810
1811 # Check if the sid was enabled.
1812 if ($state eq "enablesid") {
1813 # Add the sid and its state as enabled to the temporary hash.
1814 $temphash{$sid} = "enabled";
1815 # Check if the sid was disabled.
1816 } elsif ($state eq "disablesid") {
1817 # Add the sid and its state as disabled to the temporary hash.
1818 $temphash{$sid} = "disabled";
1819 # Invalid state - skip the current sid and state.
1820 } else {
1821 next;
1822 }
1823 }
1824
1825 # Close filehandle.
1826 close(FILE);
1827
1828 # Return the hash.
1829 return %temphash;
1830}
0a1bba1a 1831
019e5e9b
SS
1832#
1833## Function to get the provider name from the language file or providers file for a given handle.
1834#
1835sub get_provider_name($) {
1836 my ($handle) = @_;
1837 my $provider_name;
1838
1839 # Get the required translation string for the given provider handle.
1840 my $tr_string = $IDS::Ruleset::Providers{$handle}{'tr_string'};
1841
1842 # Check if the translation string is available in the language files.
1843 if ($Lang::tr{$tr_string}) {
1844 # Use the translated string from the language file.
1845 $provider_name = $Lang::tr{$tr_string};
1846 } else {
1847 # Fallback and use the provider summary from the providers file.
1848 $provider_name = $IDS::Ruleset::Providers{$handle}{'summary'};
1849 }
1850
1851 # Return the obtained provider name.
1852 return $provider_name;
1853}
1854
0a1bba1a
SS
1855#
1856## Private function to convert a given rulefile to a category name.
1857## ( No file extension anymore and if the name contained a dot, it
1858## would be replaced by a underline sign.)
1859#
1860sub _rulefile_to_category($) {
1861 my ($filename) = @_;
1862
1863 # Splitt the filename into single chunks and store them in a
1864 # temorary array.
1865 my @parts = split(/\./, $filename);
1866
1867 # Return / Remove last element of the temporary array.
1868 # This removes the file extension.
1869 pop @parts;
1870
1871 # Join together the single elements of the temporary array.
1872 # If these are more than one, use a "underline" for joining.
1873 my $category = join '_', @parts;
1874
1875 # Return the converted filename.
1876 return $category;
1877}