root/psad/tags/psad-2.0.2-pre7/kmsgsd.pl

Revision 1823, 6.4 kB (checked in by mbr, 2 years ago)

(Philip Lawrence) bugfix for perl module path not spliced correctly into @INC (some paths were being removed from @INC)

  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
Line 
1 #!/usr/bin/perl -w
2 #
3 ###########################################################################
4 #
5 # File: kmsgsd
6 #
7 # Purpose: kmsgsd separates iptables messages from all other
8 #          kernel messages.
9 #
10 # Strategy: read message from the /var/lib/psad/psadfifo named pipe and
11 #           print any firewall related dop/reject/deny messages to
12 #           the psad data file "/var/log/psad/fwdata".
13 #
14 # Author: Michael Rash (mbr@cipherdyne.org)
15 #
16 # Credits:  (see the CREDITS file)
17 #
18 # Copyright (C) 1999-2006 Michael Rash (mbr@cipherdyne.org)
19 #
20 # License (GNU Public License):
21 #
22 #    This program is distributed in the hope that it will be useful,
23 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
24 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25 #    GNU General Public License for more details.
26 #
27 #    You should have received a copy of the GNU General Public License
28 #    along with this program; if not, write to the Free Software
29 #    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
30 #    USA
31 #
32 ###########################################################################
33 #
34 # $Id$
35 #
36
37 use POSIX 'setsid';
38 use Getopt::Long 'GetOptions';
39 use strict;
40
41 ### establish the default path to the config file (can be
42 ### over-ridden with the -c <file> command line option.
43 my $CONFIG_FILE    = '/etc/psad/kmsgsd.conf';
44 my $fw_search_file = '/etc/psad/fw_search.conf';
45
46 ### path to default psad library directory for psad perl modules
47 my $psad_lib_dir = '/usr/lib/psad';
48
49 ### configuration hash
50 my %config;
51
52 ### commands hash
53 my %cmds;
54
55 ### specific fw msg search strings
56 my @fw_search = ();
57
58 ### flag used for HUP signal
59 my $hup_flag = 0;
60
61 ### handle command line arguments
62 die " ** Specify the path to the psad.conf file with " .
63     "\"-c <file>\".\n\n" unless (GetOptions (
64     'config=s' => \$CONFIG_FILE
65 ));
66
67 ### import psad perl modules
68 &import_psad_perl_modules();
69
70 ### import config
71 &import_config();
72
73 ### make sure there is not another kmsgsd already running
74 &Psad::unique_pid($config{'KMSGSD_PID_FILE'});
75
76 ### install HUP handler so config can be re-imported
77 $SIG{'HUP'}  = \&hup_sig;
78
79 my $pid = fork;
80 exit if $pid;
81 die " ** $0: Couldn't fork: $!" unless defined($pid);
82 POSIX::setsid() or die " ** $0: Can't start a new session: $!\n";
83
84 ### write the pid to the pid file
85 &Psad::writepid($config{'KMSGSD_PID_FILE'});
86
87 ### open the fwdata file
88 open LOG, ">> $config{'FW_DATA_FILE'}" or
89     die "Could not open $config{'FW_DATA_FILE'}: $!\n";
90
91 #===================== main =======================
92 ### main loop
93 for (;;) {
94     open FIFO, "< $config{'PSAD_FIFO'}" or die "Can't open file : $!\n";
95     my $service = <FIFO>;
96     if (defined $service
97         && ($service =~ /Packet\slog/ || $service =~ /IN.+?OUT/)
98         && ($service =~ /$config{'FW_MSG_SEARCH'}/
99         && (&found_fw_msg($service))
100         || $service =~ /$config{'SNORT_SID_STR'}/)) {
101         ### log to the fwdata file
102         my $old_fh = select LOG;
103         $| = 1;
104         print $service;
105         select $old_fh;
106     }
107     if ($hup_flag) {
108         ### clear the HUP flag and re-import the config
109         $hup_flag = 0;
110         &import_config();
111         close FIFO;
112         open FIFO, "< $config{'PSAD_FIFO'}" or
113             die "Can't open file : $!\n";
114         &Psad::psyslog('psad(kmsgsd)', 'received HUP signal, ' .
115             're-importing kmsgsd.conf');
116     }
117 }
118 ### These statements don't get executed, but for completeness...
119 close LOG;
120 close FIFO;
121 exit 0;
122 #==================== end main =====================
123
124 sub found_fw_msg() {
125     my $str = shift;
126     return 1 if $config{'FW_SEARCH_ALL'} eq 'Y';
127     for my $pattern (@fw_search) {
128         my $pat = qr|$pattern|;
129         return 1 if $str =~ m|$pat|;
130     }
131     return 0;
132 }
133
134 sub import_psad_perl_modules() {
135
136     my $mod_paths_ar = &get_psad_mod_paths();
137
138     push @$mod_paths_ar, @INC;
139     splice @INC, 0, $#$mod_paths_ar+1, @$mod_paths_ar;
140
141     require Psad;
142
143     return;
144 }
145
146 sub get_psad_mod_paths() {
147
148     my @paths = ();
149
150     unless (-d $psad_lib_dir) {
151         my $dir_tmp = $psad_lib_dir;
152         $dir_tmp =~ s|lib/|lib64/|;
153         if (-d $dir_tmp) {
154             $psad_lib_dir = $dir_tmp;
155         } else {
156             die "[*] psad lib directory: $psad_lib_dir does not exist, ",
157                 "use --Lib-dir <dir>";
158         }
159     }
160
161     opendir D, $psad_lib_dir or die "[*] Could not open $psad_lib_dir: $!";
162     my @dirs = readdir D;
163     closedir D;
164
165     push @paths, $psad_lib_dir;
166
167     for my $dir (@dirs) {
168         ### get directories like "/usr/lib/psad/x86_64-linux"
169         next unless -d "$psad_lib_dir/$dir";
170         push @paths, "$psad_lib_dir/$dir"
171             if $dir =~ m|linux| or $dir =~ m|thread|;
172     }
173     return \@paths;
174 }
175
176 sub import_config() {
177
178     ### read in the configuration file
179     &Psad::buildconf(\%config, \%cmds, $CONFIG_FILE);
180
181     ### import FW_MSG_SEARCH strings
182     &import_fw_search();
183
184     ### expand any embedded vars within config values
185     &Psad::expand_vars(\%config, \%cmds);
186
187     ### make sure the configuration is complete
188     &required_vars();
189
190     ### Check to make sure the commands specified in the config section
191     ### are in the right place, and attempt to correct automatically if not.
192     &Psad::check_commands(\%cmds, {});
193
194     return;
195 }
196
197 sub import_fw_search() {
198     open F, "< $fw_search_file" or die "[*] Could not open fw search ",
199         "string file $fw_search_file: $!";
200     my @lines = <F>;
201     close F;
202     my $found_fw_search = 0;
203     for my $line (@lines) {
204         next unless $line =~ /\S/;
205         next if $line =~ /^\s*#/;
206         if ($line =~ /^\s*FW_MSG_SEARCH\s+(.*?);/) {
207             push @fw_search, $1;
208             $found_fw_search = 1;
209         } elsif ($line =~ /^\s*FW_SEARCH_ALL\s+(\w+);/) {
210             my $strategy = $1;
211             if ($strategy eq 'Y' or $strategy eq 'N') {
212                 $config{'FW_SEARCH_ALL'} = $strategy;
213             }
214         }
215     }
216
217     $config{'FW_SEARCH_ALL'} = 'Y'
218         unless defined $config{'FW_SEARCH_ALL'};
219
220     unless ($config{'FW_SEARCH_ALL'} eq 'Y' or
221             $config{'FW_SEARCH_ALL'} eq 'N') {
222         $config{'FW_SEARCH_ALL'} = 'Y';
223     }
224
225     if ($config{'FW_SEARCH_ALL'} eq 'N' and not $found_fw_search) {
226         push @fw_search, 'DROP';
227     }
228     return;
229 }
230
231 sub required_vars() {
232     my @required_vars = qw(
233         KMSGSD_PID_FILE PSAD_FIFO FW_DATA_FILE
234         FW_MSG_SEARCH SNORT_SID_STR
235     );
236     &Psad::defined_vars($CONFIG_FILE, \@required_vars, \%config);
237     return;
238 }
239
240 sub hup_sig() {
241     $hup_flag = 1;
242     return;
243 }
Note: See TracBrowser for help on using the browser.