]> git.ipfire.org Git - ipfire-2.x.git/blame - html/cgi-bin/ids.cgi
ids.cgi: Drop loading of File::Copy module.
[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 #
b6f571fa 5# Copyright (C) 2007-2015 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";
31
f2fdd0c1
CS
32my %color = ();
33my %mainsettings = ();
0b89daee 34my %netsettings = ();
a232b58c 35my %snortrules = ();
ac1cfefa 36my %snortsettings=();
43263ea6 37my %rulesetsources = ();
298723b9 38my %cgiparams=();
ac1cfefa 39my %checked=();
5a3e0dca 40my %selected=();
0b89daee
SS
41
42# Read-in main settings, for language, theme and colors.
43&General::readhash("${General::swroot}/main/settings", \%mainsettings);
44&General::readhash("/srv/web/ipfire/html/themes/".$mainsettings{'THEME'}."/include/colors.txt", \%color);
45
46# Get netsettings.
ac1cfefa
MT
47&General::readhash("${General::swroot}/ethernet/settings", \%netsettings);
48
43263ea6
SS
49# Get all available ruleset locations.
50&General::readhash("${General::swroot}/snort/ruleset-sources.list", \%rulesetsources);
51
52my $rulestarball = "/var/tmp/snortrules.tar.gz";
53my $snortrulepath = "/etc/snort/rules";
54my $snortusedrulefilesfile = "${General::swroot}/snort/snort-used-rulefiles.conf";
55my $errormessage;
56
57# Hook used to download and update the ruleset,
58# if the cgi got called from command line.
59if ($ENV{"REMOTE_ADDR"} eq "") {
60 # Read snortsettings.
61 &General::readhash("${General::swroot}/snort/settings", \%snortsettings);
62
63 # Download rules tarball.
64 $errormessage = &downloadruleset();
65
66 # Sleep for one second.
67 sleep(1);
68
69 # Check if there was an error message.
70 unless ($errormessage) {
71 # Call oinkmaster.
72 &oinkmaster();
73 } else {
74 # Call logger and log the errormessage.
75 system("logger -t oinkmaster $errormessage");
76 }
77
78exit(0);
79}
80
ac1cfefa
MT
81&Header::showhttpheaders();
82
0b89daee 83# Default settings for snort.
ac1cfefa
MT
84$snortsettings{'ENABLE_SNORT'} = 'off';
85$snortsettings{'ENABLE_SNORT_GREEN'} = 'off';
86$snortsettings{'ENABLE_SNORT_BLUE'} = 'off';
87$snortsettings{'ENABLE_SNORT_ORANGE'} = 'off';
5a3e0dca 88$snortsettings{'RULES'} = '';
ac1cfefa 89$snortsettings{'OINKCODE'} = '';
ac1cfefa 90
298723b9
SS
91#Get GUI values
92&Header::getcgihash(\%cgiparams);
ac1cfefa 93
500c5c55
SS
94# Try to determine if oinkmaster is running.
95my $oinkmaster_pid = `pidof oinkmaster.pl -x`;
96
97# If oinkmaster is running display output.
98if ($oinkmaster_pid) {
99 &working("$Lang::tr{'snort working'}");
100}
101
3da6e01b
SS
102## Grab all available snort rules and store them in the snortrules hash.
103#
422204ff
SS
104# Open snort rules directory and do a directory listing.
105opendir(DIR, $snortrulepath) or die $!;
106 # Loop through the direcory.
107 while (my $file = readdir(DIR)) {
108
109 # We only want files.
110 next unless (-f "$snortrulepath/$file");
111
112 # Ignore empty files.
113 next if (-z "$snortrulepath/$file");
114
3da6e01b 115 # Use a regular expression to find files ending in .rules
422204ff
SS
116 next unless ($file =~ m/\.rules$/);
117
3da6e01b
SS
118 # Ignore files which are not read-able.
119 next unless (-R "$snortrulepath/$file");
395e3b90 120
3da6e01b
SS
121 # Call subfunction to read-in rulefile and add rules to
122 # the snortrules hash.
123 &readrulesfile("$file");
395e3b90 124 }
395e3b90 125
3da6e01b 126closedir(DIR);
395e3b90 127
e5738079
SS
128# Gather used rulefiles.
129#
130# Check if the file for activated rulefiles is not empty.
131if(-f $snortusedrulefilesfile) {
132 # Open the file for used rulefile and read-in content.
133 open(FILE, $snortusedrulefilesfile) or die "Could not open $snortusedrulefilesfile. $!\n";
134
135 # Read-in content.
136 my @lines = <FILE>;
137
138 # Close file.
139 close(FILE);
140
141 # Loop through the array.
142 foreach my $line (@lines) {
143 # Remove newlines.
144 chomp($line);
145
146 # Skip comments.
147 next if ($line =~ /\#/);
148
149 # Skip blank lines.
150 next if ($line =~ /^\s*$/);
151
152 # Gather rule sid and message from the ruleline.
153 if ($line =~ /.*include \$RULE_PATH\/(.*)/) {
154 my $rulefile = $1;
155
156 # Add the rulefile to the %snortrules hash.
157 $snortrules{$rulefile}{'Rulefile'}{'State'} = "on";
158 }
159 }
160}
161
298723b9
SS
162# Save ruleset.
163if ($cgiparams{'RULESET'} eq $Lang::tr{'update'}) {
164 my $enabled_sids_file = "${General::swroot}/snort/oinkmaster-enabled-sids.conf";
165 my $disabled_sids_file = "${General::swroot}/snort/oinkmaster-disabled-sids.conf";
166
167 # Arrays to store sid which should be added to the corresponding files.
168 my @enabled_sids;
169 my @disabled_sids;
e5738079 170 my @enabled_rulefiles;
298723b9
SS
171
172 # Loop through the hash of snortrules.
173 foreach my $rulefile(keys %snortrules) {
e5738079
SS
174 # Check if the rulefile is enabled.
175 if ($cgiparams{$rulefile} eq "on") {
176 # Add rulefile to the array of enabled rulefiles.
177 push(@enabled_rulefiles, $rulefile);
b65b5ef3
SS
178
179 # Drop item from cgiparams hash.
180 delete $cgiparams{$rulefile};
e5738079 181 }
466c6779 182 }
e5738079 183
466c6779
SS
184 # Loop through the hash of snortrules.
185 foreach my $rulefile (keys %snortrules) {
298723b9
SS
186 # Loop through the single rules of the rulefile.
187 foreach my $sid (keys %{$snortrules{$rulefile}}) {
c51a044a
SS
188 # Skip the current sid if it is not numeric.
189 next unless ($sid =~ /\d+/ );
190
298723b9
SS
191 # Check if there exists a key in the cgiparams hash for this sid.
192 if (exists($cgiparams{$sid})) {
193 # Look if the rule is disabled.
194 if ($snortrules{$rulefile}{$sid}{'State'} eq "off") {
195 # Check if the state has been set to 'on'.
196 if ($cgiparams{$sid} eq "on") {
197 # Add the sid to the enabled_sids array.
198 push(@enabled_sids, $sid);
199
200 # Drop item from cgiparams hash.
60333473 201 delete $cgiparams{$rulefile}{$sid};
298723b9
SS
202 }
203 }
204 } else {
205 # Look if the rule is enabled.
206 if ($snortrules{$rulefile}{$sid}{'State'} eq "on") {
207 # Check if the state is 'on' and should be disabled.
208 # In this case there is no entry
209 # for the sid in the cgiparams hash.
210 # Add it to the disabled_sids array.
211 push(@disabled_sids, $sid);
212
213 # Drop item from cgiparams hash.
60333473 214 delete $cgiparams{$rulefile}{$sid};
298723b9
SS
215 }
216 }
217 }
218 }
219
37659505
SS
220 # Open enabled sid's file for writing.
221 open(FILE, ">$enabled_sids_file") or die "Could not write to $enabled_sids_file. $!\n";
298723b9 222
37659505
SS
223 # Write header to file.
224 print FILE "#Autogenerated file. Any custom changes will be overwritten!\n";
298723b9 225
37659505
SS
226 # Check if the enabled_sids array contains any sid's.
227 if (@enabled_sids) {
298723b9
SS
228 # Loop through the array of enabled sids and write them to the file.
229 foreach my $sid (@enabled_sids) {
37659505 230 print FILE "enablesid $sid\n";
298723b9 231 }
298723b9
SS
232 }
233
37659505
SS
234 # Close file after writing.
235 close(FILE);
236
237 # Open disabled sid's file for writing.
238 open(FILE, ">$disabled_sids_file") or die "Could not write to $disabled_sids_file. $!\n";
298723b9 239
37659505
SS
240 # Write header to file.
241 print FILE "#Autogenerated file. Any custom changes will be overwritten!\n";
298723b9 242
37659505
SS
243 # Check if the enabled_sids array contains any sid's.
244 if (@disabled_sids) {
245 # Loop through the array of disabled sids and write them to the file.
246 foreach my $sid (@disabled_sids) {
247 print FILE "disablesid $sid\n";
248 }
249 }
298723b9 250
37659505
SS
251 # Close file after writing.
252 close(FILE);
e5738079
SS
253
254 # Open file for used rulefiles.
37659505 255 open (FILE, ">$snortusedrulefilesfile") or die "Could not write to $snortusedrulefilesfile. $!\n";
e5738079
SS
256
257 # Write header to file.
258 print FILE "#Autogenerated file. Any custom changes will be overwritten!\n";
259
260 # Check if the enabled_rulefiles array contains any entries.
261 if (@enabled_rulefiles) {
262 # Loop through the array of rulefiles which should be loaded and write the to the file.
263 foreach my $file (@enabled_rulefiles) {
264 print FILE "include \$RULE_PATH/$file\n";
265 }
266 }
267
268 # Close file after writing.
269 close(FILE);
52599865
SS
270
271 # Call oinkmaster to alter the ruleset.
272 &oinkmaster();
273
274# Download new ruleset.
275} elsif ($cgiparams{'RULESET'} eq $Lang::tr{'download new ruleset'}) {
43263ea6
SS
276 # Check if the red device is active.
277 unless (-e "${General::swroot}/red/active") {
278 $errormessage = $Lang::tr{'could not download latest updates'};
279 }
52599865
SS
280
281 # Call diskfree to gather the free disk space of /var.
282 my @df = `/bin/df -B M /var`;
283
284 # Loop through the output.
285 foreach my $line (@df) {
286 # Ignore header line.
287 next if $line =~ m/^Filesystem/;
288
289 # Search for a line with the device information.
290 if ($line =~ m/dev/ ) {
291 # Split the line into single pieces.
292 my @values = split(' ', $line);
293 my ($filesystem, $blocks, $used, $available, $used_perenctage, $mounted_on) = @values;
294
295 # Check if the available disk space is more than 300MB.
296 if ($available < 300) {
297 # If there is not enough space, print out an error message.
298 $errormessage = "$Lang::tr{'not enough disk space'} < 300MB, /var $1MB";
52599865 299
43263ea6
SS
300 # Break loop.
301 last;
52599865 302 }
43263ea6
SS
303 }
304 }
52599865 305
43263ea6
SS
306 # Check if any errors happend.
307 unless ($errormessage) {
308 # Call subfunction to download the ruleset.
309 $errormessage = &downloadruleset();
310 }
8f22237b 311
43263ea6
SS
312 # Sleep for 1 second
313 sleep(1);
52599865 314
43263ea6
SS
315 # Check if the downloader returend any error message.
316 unless ($errormessage) {
317 # Call subfunction to launch oinkmaster.
318 &oinkmaster();
319
320 # Sleep for 1 seconds.
321 sleep(1);
52599865 322 }
a232b58c
SS
323# Save snort settings.
324} elsif ($cgiparams{'SNORT'} eq $Lang::tr{'save'}) {
325 # Prevent form name from been stored in conf file.
326 delete $cgiparams{'SNORT'};
327
328 # Check if an oinkcode has been provided.
329 if ($cgiparams{'OINKCODE'}) {
330 # Check if the oinkcode contains unallowed chars.
331 unless ($cgiparams{'OINKCODE'} =~ /^[a-z0-9]+$/) {
332 $errormessage = $Lang::tr{'invalid input for oink code'};
333 }
f9c2147d 334 }
ac1cfefa 335
a232b58c
SS
336 # Go on if there are no error messages.
337 if (!$errormessage) {
338 # Store settings into settings file.
339 &General::writehash("${General::swroot}/snort/settings", \%cgiparams);
340
a232b58c 341 # Call snortctrl to restart snort
a9a91e5f
MT
342 system('/usr/local/bin/snortctrl restart >/dev/null');
343 }
ac1cfefa
MT
344}
345
52599865
SS
346# Read-in snortsettings
347&General::readhash("${General::swroot}/snort/settings", \%snortsettings);
348
ac1cfefa
MT
349$checked{'ENABLE_SNORT'}{'off'} = '';
350$checked{'ENABLE_SNORT'}{'on'} = '';
351$checked{'ENABLE_SNORT'}{$snortsettings{'ENABLE_SNORT'}} = "checked='checked'";
352$checked{'ENABLE_SNORT_GREEN'}{'off'} = '';
353$checked{'ENABLE_SNORT_GREEN'}{'on'} = '';
354$checked{'ENABLE_SNORT_GREEN'}{$snortsettings{'ENABLE_SNORT_GREEN'}} = "checked='checked'";
355$checked{'ENABLE_SNORT_BLUE'}{'off'} = '';
356$checked{'ENABLE_SNORT_BLUE'}{'on'} = '';
357$checked{'ENABLE_SNORT_BLUE'}{$snortsettings{'ENABLE_SNORT_BLUE'}} = "checked='checked'";
358$checked{'ENABLE_SNORT_ORANGE'}{'off'} = '';
359$checked{'ENABLE_SNORT_ORANGE'}{'on'} = '';
360$checked{'ENABLE_SNORT_ORANGE'}{$snortsettings{'ENABLE_SNORT_ORANGE'}} = "checked='checked'";
5a3e0dca 361$selected{'RULES'}{'nothing'} = '';
5a3e0dca 362$selected{'RULES'}{'community'} = '';
a0fa489f 363$selected{'RULES'}{'emerging'} = '';
5a3e0dca
MT
364$selected{'RULES'}{'registered'} = '';
365$selected{'RULES'}{'subscripted'} = '';
366$selected{'RULES'}{$snortsettings{'RULES'}} = "selected='selected'";
ac1cfefa
MT
367
368&Header::openpage($Lang::tr{'intrusion detection system'}, 1, '');
369
17726644
SS
370### Java Script ###
371print <<END
372<script>
373 // Tiny java script function to show/hide the rules
374 // of a given category.
375 function showhide(tblname) {
376 \$("#" + tblname).toggle();
377 }
378</script>
379END
380;
381
ac1cfefa
MT
382&Header::openbigbox('100%', 'left', '', $errormessage);
383
384if ($errormessage) {
385 &Header::openbox('100%', 'left', $Lang::tr{'error messages'});
386 print "<class name='base'>$errormessage\n";
387 print "&nbsp;</class>\n";
388 &Header::closebox();
389}
390
7cc8a0e5 391&Header::openbox('100%', 'left', $Lang::tr{'intrusion detection system'});
1504a375
SS
392
393my $rulesdate;
394
395# Check if a ruleset allready has been downloaded.
396if ( -f "$rulestarball"){
397 # Call stat on the filename to obtain detailed information.
398 my @Info = stat("$rulestarball");
399
400 # Grab details about the creation time.
401 $rulesdate = localtime($Info[9]);
402}
403
ac1cfefa 404print <<END
1504a375
SS
405<form method='post' action='$ENV{'SCRIPT_NAME'}'>
406 <table width='100%' border='0'>
407 <tr>
408 <td class='base' width='25%'>
409 <input type='checkbox' name='ENABLE_SNORT' $checked{'ENABLE_SNORT'}{'on'}>RED Snort
410 </td>
411
412 <td class='base' width='25%'>
413 <input type='checkbox' name='ENABLE_SNORT_GREEN' $checked{'ENABLE_SNORT_GREEN'}{'on'}>GREEN Snort
414 </td>
415
416 <td class='base' width='25%'>
ac1cfefa
MT
417END
418;
1504a375
SS
419
420# Check if a blue device is configured.
421if ($netsettings{'BLUE_DEV'}) {
422 print "<input type='checkbox' name='ENABLE_SNORT_BLUE' $checked{'ENABLE_SNORT_BLUE'}{'on'} />BLUE Snort\n";
ac1cfefa 423}
1504a375
SS
424
425print "</td>\n";
426
427print "<td width='25%'>\n";
428
429# Check if an orange device is configured.
430if ($netsettings{'ORANGE_DEV'}) {
431 print "<input type='checkbox' name='ENABLE_SNORT_ORANGE' $checked{'ENABLE_SNORT_ORANGE'}{'on'} />ORANGE Snort\n";
ac1cfefa 432}
1b73b07e 433
ac1cfefa 434print <<END
1504a375
SS
435 </td>
436 </tr>
437
438 <tr>
439 <td colspan='4'><br><br></td>
440 </tr>
441
442 <tr>
443 <td colspan='4'><b>$Lang::tr{'ids rules update'}</b></td>
444 </tr>
445
446 <tr>
447 <td colspan='4'><select name='RULES'>
5a3e0dca 448 <option value='nothing' $selected{'RULES'}{'nothing'} >$Lang::tr{'no'}</option>
a0fa489f 449 <option value='emerging' $selected{'RULES'}{'emerging'} >$Lang::tr{'emerging rules'}</option>
5a3e0dca
MT
450 <option value='community' $selected{'RULES'}{'community'} >$Lang::tr{'community rules'}</option>
451 <option value='registered' $selected{'RULES'}{'registered'} >$Lang::tr{'registered user rules'}</option>
452 <option value='subscripted' $selected{'RULES'}{'subscripted'} >$Lang::tr{'subscripted user rules'}</option>
453 </select>
1504a375
SS
454 </td>
455 </tr>
456
457 <tr>
458 <td colspan='4'>
459 <br>$Lang::tr{'ids rules license'} <a href='https://www.snort.org/subscribe' target='_blank'>www.snort.org</a>$Lang::tr{'ids rules license1'}</br>
460 <br>$Lang::tr{'ids rules license2'} <a href='https://www.snort.org/account/oinkcode' target='_blank'>Get an Oinkcode</a>, $Lang::tr{'ids rules license3'}</br>
461 </td>
462 </tr>
463
464 <tr>
465 <td colspan='4' nowrap='nowrap'>Oinkcode:&nbsp;<input type='text' size='40' name='OINKCODE' value='$snortsettings{'OINKCODE'}'></td>
466 </tr>
467
468 <tr>
469 <td colspan='4' align='left'><br>
470 <input type='submit' name='RULESET' value='$Lang::tr{'download new ruleset'}'>&nbsp;$Lang::tr{'updates installed'}: $rulesdate
471 </td>
472
473 </tr>
474 </table>
475
476 <br><br>
477
478 <table width='100%'>
479 <tr>
480 <td align='right'><input type='submit' name='SNORT' value='$Lang::tr{'save'}' /></td>
481 </tr>
482 </table>
ac1cfefa
MT
483</form>
484END
485;
486
ac1cfefa 487&Header::closebox();
fbfdb241 488
f7fcd1c0 489&Header::openbox('100%', 'LEFT', $Lang::tr{'intrusion detection system rules'});
298723b9
SS
490 print"<form method='POST' action='$ENV{'SCRIPT_NAME'}'>\n";
491
f7fcd1c0 492 # Output display table for rule files
17726644 493 print "<table width='100%'>\n";
ce0e83b3 494
17726644
SS
495 # Local variable required for java script to show/hide
496 # rules of a rulefile.
497 my $rulesetcount = 1;
f7fcd1c0
SS
498
499 # Loop over each rule file
500 foreach my $rulefile (sort keys(%snortrules)) {
501 my $rulechecked = '';
502
f7fcd1c0 503 # Check if rule file is enabled
e5738079 504 if ($snortrules{$rulefile}{'Rulefile'}{'State'} eq 'on') {
f7fcd1c0
SS
505 $rulechecked = 'CHECKED';
506 }
3ffee04b 507
17726644
SS
508 # Table and rows for the rule files.
509 print"<tr>\n";
510 print"<td class='base' width='5%'>\n";
e5738079 511 print"<input type='checkbox' name='$rulefile' $rulechecked>\n";
17726644
SS
512 print"</td>\n";
513 print"<td class='base' width='90%'><b>$rulefile</b></td>\n";
514 print"<td class='base' width='5%' align='right'>\n";
515 print"<a href=\"javascript:showhide('ruleset$rulesetcount')\">SHOW</a>\n";
516 print"</td>\n";
517 print"</tr>\n";
518
519 # Rows which will be hidden per default and will contain the single rules.
520 print"<tr style='display:none' id='ruleset$rulesetcount'>\n";
521 print"<td colspan='3'>\n";
522
523 # Local vars
524 my $lines;
525 my $rows;
526 my $col;
527
528 # New table for the single rules.
529 print "<table width='100%'>\n";
530
531 # Loop over rule file rules
532 foreach my $sid (sort {$a <=> $b} keys(%{$snortrules{$rulefile}})) {
f7fcd1c0 533 # Local vars
17726644 534 my $ruledefchecked = '';
f9c2147d 535
e5738079
SS
536 # Skip rulefile itself.
537 next if ($sid eq "Rulefile");
538
17726644
SS
539 # If 2 rules have been displayed, start a new row
540 if (($lines % 2) == 0) {
541 print "</tr><tr>\n";
3ffee04b 542
17726644
SS
543 # Increase rows by once.
544 $rows++;
545 }
f7fcd1c0 546
17726644
SS
547 # Colour lines.
548 if ($rows % 2) {
549 $col="bgcolor='$color{'color20'}'";
550 } else {
551 $col="bgcolor='$color{'color22'}'";
f7fcd1c0
SS
552 }
553
17726644 554 # Set rule state
298723b9 555 if ($snortrules{$rulefile}{$sid}{'State'} eq 'on') {
17726644 556 $ruledefchecked = 'CHECKED';
f7fcd1c0 557 }
3ffee04b 558
17726644
SS
559 # Create rule checkbox and display rule description
560 print "<td class='base' width='5%' align='right' $col>\n";
561 print "<input type='checkbox' NAME='$sid' $ruledefchecked>\n";
562 print "</td>\n";
563 print "<td class='base' width='45%' $col>$snortrules{$rulefile}{$sid}{'Description'}</td>";
564
565 # Increment rule count
566 $lines++;
567 }
568
569 # If do not have a second rule for row, create empty cell
570 if (($lines % 2) != 0) {
571 print "<td class='base'></td>";
f7fcd1c0
SS
572 }
573
574 # Close display table
17726644 575 print "</tr></table></td></tr>";
3ffee04b 576
17726644
SS
577 # Finished whith the rule file, increase count.
578 $rulesetcount++;
f7fcd1c0 579 }
17726644
SS
580
581 # Close display table
582 print "</table>";
583
f7fcd1c0 584print <<END
2999f1d2
CS
585<table width='100%'>
586<tr>
298723b9 587 <td width='100%' align='right'><input type='submit' name='RULESET' value='$Lang::tr{'update'}'>
3ffee04b
CS
588 &nbsp; <!-- space for future online help link -->
589 </td>
2999f1d2
CS
590</tr>
591</table>
298723b9 592</form>
3ffee04b
CS
593END
594;
f7fcd1c0 595&Header::closebox();
ac1cfefa
MT
596&Header::closebigbox();
597&Header::closepage();
598
500c5c55
SS
599sub working ($) {
600 my $message = $_[0];
601
602 &Header::openpage($Lang::tr{'intrusion detection system'}, 1, '');
603 &Header::openbigbox('100%', 'left', '', $errormessage);
604 &Header::openbox( 'Waiting', 1, "<meta http-equiv='refresh' content='1'>" );
605 print <<END;
606 <table>
607 <tr>
608 <td><img src='/images/indicator.gif' alt='$Lang::tr{'aktiv'}' /></td>
609 <td>$message</td>
610 </tr>
611 <tr>
612 <td colspan='2' align='center'>
613 <form method='post' action='$ENV{'SCRIPT_NAME'}'>
614 <input type='image' alt='$Lang::tr{'reload'}' title='$Lang::tr{'reload'}' src='/images/view-refresh.png' />
615 </form>
616 </tr>
617 </table>
618END
619 &Header::closebox();
620 &Header::closebigbox();
621 &Header::closepage();
622 exit;
a70d269a
SS
623}
624
43263ea6
SS
625sub downloadruleset {
626 # Read proxysettings.
627 my %proxysettings=();
628 &General::readhash("${General::swroot}/proxy/settings", \%proxysettings);
629
630 # Load required perl module to handle the download.
631 use LWP::UserAgent;
ac1cfefa 632
43263ea6
SS
633 # Init the download module.
634 my $downloader = LWP::UserAgent->new;
ac1cfefa 635
43263ea6
SS
636 # Set timeout to 10 seconds.
637 $downloader->timeout(10);
ac1cfefa 638
43263ea6
SS
639 # Check if an upstream proxy is configured.
640 if ($proxysettings{'UPSTREAM_PROXY'}) {
641 my ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
642 my $proxy_url;
afe26a05 643
43263ea6
SS
644 # Check if we got a peer.
645 if ($peer) {
646 $proxy_url = "http://";
647
648 # Check if the proxy requires authentication.
649 if (($proxysettings{'UPSTREAM_USER'}) && ($proxysettings{'UPSTREAM_PASSWORD'})) {
650 $proxy_url .= "$proxysettings{'UPSTREAM_USER'}\:$proxysettings{'UPSTREAM_PASSWORD'}\@";
651 }
652
653 # Add proxy server address and port.
654 $proxy_url .= "$peer\:$peerport";
655 } else {
656 # Break and return error message.
657 return "$Lang::tr{'could not download latest updates'}";
658 }
659
660 # Setup proxy settings.
661 $downloader->proxy('http', $proxy_url);
662 }
afe26a05
SS
663
664 # Grab the right url based on the configured vendor.
43263ea6 665 my $url = $rulesetsources{$snortsettings{'RULES'}};
afe26a05 666
43263ea6
SS
667 # Check if the vendor requires an oinkcode and add it if needed.
668 $url =~ s/\<oinkcode\>/$snortsettings{'OINKCODE'}/g;
afe26a05
SS
669
670 # Abort if no url could be determined for the vendor.
43263ea6
SS
671 unless ($url) {
672 # Abort and return errormessage.
673 return "$Lang::tr{'could not download latest updates'}";
afe26a05
SS
674 }
675
43263ea6
SS
676 # Pass the requested url to the downloader.
677 my $request = HTTP::Request->new(GET => $url);
ac1cfefa 678
43263ea6
SS
679 # Perform the request and save the output into the "$rulestarball" file.
680 my $response = $downloader->request($request, $rulestarball);
ac1cfefa 681
43263ea6
SS
682 # Check if there was any error.
683 unless ($response->is_success) {
684 return "$response->status_line";
ac1cfefa 685 }
43263ea6
SS
686
687 # If we got here, everything worked fine. Return nothing.
688 return;
ac1cfefa 689}
3da6e01b 690
56dacb58
SS
691sub oinkmaster () {
692 # Call oinkmaster to generate ruleset.
a6edfcbd 693 system("/usr/local/bin/oinkmaster.pl -v -s -u file://$rulestarball -C /var/ipfire/snort/oinkmaster.conf -o /etc/snort/rules 2>&1 |logger -t oinkmaster");
56dacb58
SS
694}
695
3da6e01b
SS
696sub readrulesfile ($) {
697 my $rulefile = shift;
698
699 # Open rule file and read in contents
700 open(RULEFILE, "$snortrulepath/$rulefile") or die "Unable to read $rulefile!";
701
702 # Store file content in an array.
703 my @lines = <RULEFILE>;
704
705 # Close file.
706 close(RULEFILE);
707
708 # Loop over rule file contents
709 foreach my $line (@lines) {
710 # Remove whitespaces.
711 chomp $line;
712
713 # Skip blank lines.
714 next if ($line =~ /^\s*$/);
715
716 # Local vars.
717 my $sid;
718 my $msg;
719
720 # Gather rule sid and message from the ruleline.
721 if ($line =~ m/.*msg:\"(.*?)\"\; .* sid:(.*?); /) {
722 $msg = $1;
723 $sid = $2;
724
725 # Check if a rule has been found.
726 if ($sid && $msg) {
727 # Add rule to the snortrules hash.
728 $snortrules{$rulefile}{$sid}{'Description'} = $msg;
729
730 # Grab status of the rule. Check if ruleline starts with a "dash".
731 if ($line =~ /^\#/) {
732 # If yes, the rule is disabled.
298723b9 733 $snortrules{$rulefile}{$sid}{'State'} = "off";
3da6e01b
SS
734 } else {
735 # Otherwise the rule is enabled.
298723b9 736 $snortrules{$rulefile}{$sid}{'State'} = "on";
3da6e01b
SS
737 }
738 }
739 }
740 }
741}