diff options
Diffstat (limited to 'recipes-security/bastille/files/FileContent.pm')
-rw-r--r-- | recipes-security/bastille/files/FileContent.pm | 1153 |
1 files changed, 0 insertions, 1153 deletions
diff --git a/recipes-security/bastille/files/FileContent.pm b/recipes-security/bastille/files/FileContent.pm deleted file mode 100644 index 0a5d609..0000000 --- a/recipes-security/bastille/files/FileContent.pm +++ /dev/null @@ -1,1153 +0,0 @@ -package Bastille::API::FileContent; -use strict; - -use Bastille::API; - -require Exporter; -our @ISA = qw(Exporter); -our @EXPORT_OK = qw( -B_blank_file -B_insert_line_after -B_insert_line_before -B_insert_line -B_append_line -B_prepend_line -B_replace_line -B_replace_lines -B_replace_pattern -B_match_line -B_match_line_only -B_match_chunk -B_return_matched_lines -B_hash_comment_line -B_hash_uncomment_line -B_delete_line -B_chunk_replace -B_print -B_getValueFromFile -B_getValueFromString - -B_TODO -B_TODOFlags -); -our @EXPORT = @EXPORT_OK; - - - -########################################################################### -# &B_blank_file ($filename,$pattern) blanks the file $filename, unless the -# pattern $pattern is present in the file. This lets us completely redo -# a file, if it isn't the one we put in place on a previous run... -# -# B_blank_file respects $GLOBAL_LOGONLY and uses B_open_plus and B_close_plus -# so that it makes backups and only modifies files when we're not in "-v" -# mode... -# -# If the file does not exist, the function does nothing, and gives an error -# to the Error Log -# -########################################################################### - -sub B_blank_file($$) { - - my ($filename,$pattern) = @_; - my $retval; - - # If this variable is true, we won't blank the file... - - my $found_pattern=0; - - if ($retval=&B_open_plus (*BLANK_NEW,*BLANK_OLD,$filename) ) { - - my @lines; - - while (my $line = <BLANK_OLD>) { - - push @lines,$line; - if ($line =~ $pattern) { - $found_pattern=1; - } - } - - # Only copy the old file if the new one didn't match. - if ($found_pattern) { - while ( my $line = shift @lines ) { - &B_print(*BLANK_NEW,$line); - } - } - else { - &B_log("ACTION","Blanked file $filename\n"); - } - &B_close_plus(*BLANK_NEW,*BLANK_OLD,$filename); - } - else { - &B_log("ERROR","Couldn't blank file $filename since we couldn't open it or its replacement\n"); - } - - return $retval; - -} - -########################################################################### -# &B_insert_line_after ($filename,$pattern,$line_to_insert,$line_to_follow) -# modifies $filename, inserting $line_to_insert unless one or more lines -# in the file matches $pattern. The $line_to_insert will be placed -# immediately after $line_to_follow, if it exists. If said line does not -# exist, the line will not be inserted and this routine will return 0. -# -# B_insert_line uses B_open_plus and B_close_plus, so that the file -# modified is backed up... -# -# Here's examples of where you might use this: -# -# You'd like to insert a line in Apache's configuration file, in a -# particular section. -# -########################################################################### - -sub B_insert_line_after($$$$) { - - my ($filename,$pattern,$line_to_insert,$line_to_follow) = @_; - - my @lines; - my $found_pattern=0; - my $found_line_to_follow=0; - - my $retval=1; - - if ( &B_open_plus (*INSERT_NEW,*INSERT_OLD,$filename) ) { - - # Read through the file looking for a match both on the $pattern - # and the line we are supposed to be inserting after... - - my $ctr=1; - while (my $line=<INSERT_OLD>) { - push (@lines,$line); - if ($line =~ $pattern) { - $found_pattern=1; - } - if ( ($found_line_to_follow < 1) and ($line =~ $line_to_follow)) { - $found_line_to_follow=$ctr; - } - $ctr++; - } - - # Log an error if we never found the line we were to insert after - unless ($found_line_to_follow ) { - $retval=0; - &B_log("ERROR","Never found the line that we were supposed to insert after in $filename\n"); - } - - # Now print the file back out, inserting our line if we should... - - $ctr=1; - while (my $line = shift @lines) { - &B_print(*INSERT_NEW,$line); - if ( ($ctr == $found_line_to_follow) and ($found_pattern == 0) ) { - &B_print(*INSERT_NEW,$line_to_insert); - &B_log("ACTION","Inserted the following line in $filename:\n"); - &B_log("ACTION","$line_to_insert"); - } - $ctr++; - } - - &B_close_plus (*INSERT_NEW,*INSERT_OLD,$filename); - - } - else { - $retval=0; - &B_log("ERROR","Couldn't insert line to $filename, since open failed."); - } - - return $retval; - -} -########################################################################### -# &B_insert_line_before ($filename,$pattern,$line_to_insert,$line_to_preceed) -# modifies $filename, inserting $line_to_insert unless one or more lines -# in the file matches $pattern. The $line_to_insert will be placed -# immediately before $line_to_preceed, if it exists. If said line does not -# exist, the line will not be inserted and this routine will return 0. -# -# B_insert_line uses B_open_plus and B_close_plus, so that the file -# modified is backed up... -# -# Here's examples of where you might use this: -# -# You'd like to insert a line in Apache's configuration file, in a -# particular section. -# -########################################################################### - -sub B_insert_line_before($$$$) { - - my ($filename,$pattern,$line_to_insert,$line_to_preceed) = @_; - - my @lines; - my $found_pattern=0; - my $found_line_to_preceed=0; - - my $retval=1; - - if ( &B_open_plus (*INSERT_NEW,*INSERT_OLD,$filename) ) { - - # Read through the file looking for a match both on the $pattern - # and the line we are supposed to be inserting after... - - my $ctr=1; - while (my $line=<INSERT_OLD>) { - push (@lines,$line); - if ($line =~ $pattern) { - $found_pattern=1; - } - if ( ($found_line_to_preceed < 1) and ($line =~ $line_to_preceed)) { - $found_line_to_preceed=$ctr; - } - $ctr++; - } - - # Log an error if we never found the line we were to preceed - unless ($found_line_to_preceed ) { - $retval=0; - &B_log("ERROR","Never found the line that we were supposed to insert before in $filename\n"); - } - - # Now print the file back out, inserting our line if we should... - - $ctr=1; - while (my $line = shift @lines) { - if ( ($ctr == $found_line_to_preceed) and ($found_pattern == 0) ) { - &B_print(*INSERT_NEW,$line_to_insert); - &B_log("ACTION","Inserted the following line in $filename:\n"); - &B_log("ACTION","$line_to_insert"); - } - &B_print(*INSERT_NEW,$line); - $ctr++; - } - - &B_close_plus (*INSERT_NEW,*INSERT_OLD,$filename); - - } - else { - $retval=0; - &B_log("ERROR","Couldn't insert line to $filename, since open failed."); - } - - return $retval; - -} - -########################################################################### -# &B_insert_line ($filename,$pattern,$line_to_insert,$line_to_follow) -# -# has been renamed to B_insert_line_after() -# -# This name will continue to work, as a shim for code that has not been -# transitioned. -########################################################################### - -sub B_insert_line($$$$) { - - my $rtn_value = &B_insert_line_after(@_); - - return ($rtn_value); -} - - -########################################################################### -# &B_append_line ($filename,$pattern,$line_to_append) modifies $filename, -# appending $line_to_append unless one or more lines in the file matches -# $pattern. This is an enhancement to the append_line_if_no_such_line_exists -# idea. -# -# Additionally, if $pattern is set equal to "", the line is always appended. -# -# B_append_line uses B_open_plus and B_close_plus, so that the file -# modified is backed up... -# -# Here's examples of where you might use this: -# -# You'd like to add a root line to /etc/ftpusers if none exists. -# You'd like to add a Options Indexes line to Apache's config. file, -# after you delete all Options lines from said config file. -# -########################################################################### - -sub B_append_line($$$) { - - my ($filename,$pattern,$line_to_append) = @_; - - my $found_pattern=0; - my $retval=1; - - if ( &B_open_plus (*APPEND_NEW,*APPEND_OLD,$filename) ) { - while (my $line=<APPEND_OLD>) { - &B_print(*APPEND_NEW,$line); - if ($line =~ $pattern) { - $found_pattern=1; - } - } - # Changed != 0 to $pattern so that "" works instead of 0 and perl - # does not give the annoying - # Argument "XX" isn't numeric in ne at ... - if ( $pattern eq "" or ! $found_pattern ) { - &B_print(*APPEND_NEW,$line_to_append); - &B_log("ACTION","Appended the following line to $filename:\n"); - &B_log("ACTION","$line_to_append"); - } - &B_close_plus (*APPEND_NEW,*APPEND_OLD,$filename); - } - else { - $retval=0; - &B_log("ERROR","# Couldn't append line to $filename, since open failed."); - } - - return $retval; - -} - -########################################################################### -# &B_prepend_line ($filename,$pattern,$line_to_prepend) modifies $filename, -# pre-pending $line_to_prepend unless one or more lines in the file matches -# $pattern. This is an enhancement to the prepend_line_if_no_such_line_exists -# idea. -# -# B_prepend_line uses B_open_plus and B_close_plus, so that the file -# modified is backed up... -# -# Here's examples of where you might use this: -# -# You'd like to insert the line "auth required pam_deny.so" to the top -# of the PAM stack file /etc/pam.d/rsh to totally deactivate rsh. -# -########################################################################### - -sub B_prepend_line($$$) { - - my ($filename,$pattern,$line_to_prepend) = @_; - - my @lines; - my $found_pattern=0; - my $retval=1; - - if ( &B_open_plus (*PREPEND_NEW,*PREPEND_OLD,$filename) ) { - while (my $line=<PREPEND_OLD>) { - push (@lines,$line); - if ($line =~ $pattern) { - $found_pattern=1; - } - } - unless ($found_pattern) { - &B_print(*PREPEND_NEW,$line_to_prepend); - } - while (my $line = shift @lines) { - &B_print(*PREPEND_NEW,$line); - } - - &B_close_plus (*PREPEND_NEW,*PREPEND_OLD,$filename); - - # Log the action - &B_log("ACTION","Pre-pended the following line to $filename:\n"); - &B_log("ACTION","$line_to_prepend"); - } - else { - $retval=0; - &B_log("ERROR","Couldn't prepend line to $filename, since open failed.\n"); - } - - return $retval; - -} - - -########################################################################### -# &B_replace_line ($filename,$pattern,$line_to_switch_in) modifies $filename, -# replacing any lines matching $pattern with $line_to_switch_in. -# -# It returns the number of lines it replaced (or would have replaced, if -# LOGONLY mode wasn't on...) -# -# B_replace_line uses B_open_plus and B_close_plus, so that the file -# modified is backed up... -# -# Here an example of where you might use this: -# -# You'd like to replace any Options lines in Apache's config file with: -# Options Indexes FollowSymLinks -# -########################################################################### - -sub B_replace_line($$$) { - - my ($filename,$pattern,$line_to_switch_in) = @_; - my $retval=0; - - if ( &B_open_plus (*REPLACE_NEW,*REPLACE_OLD,$filename) ) { - while (my $line=<REPLACE_OLD>) { - unless ($line =~ $pattern) { - &B_print(*REPLACE_NEW,$line); - } - else { - # Don't replace the line if it's already there. - unless ($line eq $line_to_switch_in) { - &B_print(*REPLACE_NEW,$line_to_switch_in); - - $retval++; - &B_log("ACTION","File modification in $filename -- replaced line\n" . - "$line\n" . - "with:\n" . - "$line_to_switch_in"); - } - # But if it is there, make sure it stays there! (by Paul Allen) - else { - &B_print(*REPLACE_NEW,$line); - } - } - } - &B_close_plus (*REPLACE_NEW,*REPLACE_OLD,$filename); - } - else { - $retval=0; - &B_log("ERROR","Couldn't replace line(s) in $filename because open failed.\n"); - } - - return $retval; -} - -########################################################################### -# &B_replace_lines ($filename,$patterns_and_substitutes) modifies $filename, -# replacing the line matching the nth $pattern specified in $patterns_and_substitutes->[n]->[0] -# with the corresponding substitutes in $patterns_and_substitutes->[n]->-[1] -# -# It returns the number of lines it replaced (or would have replaced, if -# LOGONLY mode wasn't on...) -# -# B_replace_lines uses B_open_plus and B_close_plus, so that the file -# modified is backed up... -# -# Here an example of where you might use this: -# -# You'd like to replace /etc/opt/ssh/sshd_config file -# (^#|^)Protocol\s+(.*)\s*$ ==> Protocol 2 -# (^#|^)X11Forwarding\s+(.*)\s*$ ==> X11Forwarding yes -# (^#|^)IgnoreRhosts\s+(.*)\s*$ ==> gnoreRhosts yes -# (^#|^)RhostsAuthentication\s+(.*)\s*$ ==> RhostsAuthentication no -# (^#|^)RhostsRSAAuthentication\s+(.*)\s*$ ==> RhostsRSAAuthentication no -# (^#|^)PermitRootLogin\s+(.*)\s*$ ==> PermitRootLogin no -# (^#|^)PermitEmptyPasswords\s+(.*)\s*$ ==> PermitEmptyPasswords no -# my $patterns_and_substitutes = [ -# [ '(^#|^)Protocol\s+(.*)\s*$' => 'Protocol 2'], -# ['(^#|^)X11Forwarding\s+(.*)\s*$' => 'X11Forwarding yes'], -# ['(^#|^)IgnoreRhosts\s+(.*)\s*$' => 'gnoreRhosts yes'], -# ['(^#|^)RhostsAuthentication\s+(.*)\s*$' => 'RhostsAuthentication no'], -# ['(^#|^)RhostsRSAAuthentication\s+(.*)\s*$' => 'RhostsRSAAuthentication no'], -# ['(^#|^)PermitRootLogin\s+(.*)\s*$' => 'PermitRootLogin no'], -# ['(^#|^)PermitEmptyPasswords\s+(.*)\s*$' => 'PermitEmptyPasswords no'] -#] -# B_replaces_lines($sshd_config,$patterns_and_substitutes); -########################################################################### - -sub B_replace_lines($$){ - my ($filename, $pairs) = @_; - my $retval = 0; - if ( &B_open_plus (*REPLACE_NEW,*REPLACE_OLD,$filename) ) { - while (my $line = <REPLACE_OLD>) { - my $switch; - my $switch_before = $line; - chomp($line); - foreach my $pair (@$pairs) { - $switch = 0; - - my $pattern = $pair->[0] ; - my $replace = $pair->[1]; - my $evalstr = '$line' . "=~ s/$pattern/$replace/"; - eval $evalstr; - if ($@) { - &B_log("ERROR", "eval $evalstr failed.\n"); - } - #if ( $line =~ s/$pair->[0]/$pair->[1]/) { - # $switch = 1; - # last; - #} - } - &B_print(*REPLACE_NEW,"$line\n"); - if ($switch) { - $retval++; - B_log("ACTION","File modification in $filename -- replaced line\n" . - "$switch_before\n" . - "with:\n" . - "$line\n"); - } - } - &B_close_plus (*REPLACE_NEW,*REPLACE_OLD,$filename); - return 1; - } - else { - $retval=0; - &B_log("ERROR","Couldn't replace line(s) in $filename because open failed.\n"); - } -} - -################################################################################################ -# &B_replace_pattern ($filename,$pattern,$pattern_to_remove,$text_to_switch_in) -# modifies $filename, acting on only lines that match $pattern, replacing a -# string that matches $pattern_to_remove with $text_to_switch_in. -# -# Ex: -# B_replace_pattern('/etc/httpd.conf','^\s*Options.*\bIncludes\b','Includes','IncludesNoExec') -# -# replaces all "Includes" with "IncludesNoExec" on Apache Options lines. -# -# It returns the number of lines it altered (or would have replaced, if -# LOGONLY mode wasn't on...) -# -# B_replace_pattern uses B_open_plus and B_close_plus, so that the file -# modified is backed up... -# -################################################################################################# - -sub B_replace_pattern($$$$) { - - my ($filename,$pattern,$pattern_to_remove,$text_to_switch_in) = @_; - my $retval=0; - - if ( &B_open_plus (*REPLACE_NEW,*REPLACE_OLD,$filename) ) { - while (my $line=<REPLACE_OLD>) { - unless ($line =~ $pattern) { - &B_print(*REPLACE_NEW,$line); - } - else { - my $orig_line =$line; - $line =~ s/$pattern_to_remove/$text_to_switch_in/; - - &B_print(*REPLACE_NEW,$line); - - $retval++; - &B_log("ACTION","File modification in $filename -- replaced line\n" . - "$orig_line\n" . - "via pattern with:\n" . - "$line\n\n"); - } - } - &B_close_plus (*REPLACE_NEW,*REPLACE_OLD,$filename); - } - else { - $retval=0; - &B_log("ERROR","Couldn't pattern-replace line(s) in $filename because open failed.\n"); - } - - return $retval; -} - - -########################################################################### -# &B_match_line($file,$pattern); -# -# This subroutine will return a 1 if the pattern specified can be matched -# against the file specified. It will return a 0 otherwise. -# -# return values: -# 0: pattern not in file or the file is not readable -# 1: pattern is in file -########################################################################### -sub B_match_line($$) { - # file to be checked and pattern to check for. - my ($file,$pattern) = @_; - # if the file is readable then - if(-r $file) { - # if the file can be opened then - if(open FILE,"<$file") { - # look at each line in the file - while (my $line = <FILE>) { - # if a line matches the pattern provided then - if($line =~ $pattern) { - # return the pattern was found - B_log('DEBUG','Pattern: ' . $pattern . ' matched in file: ' . - $file . "\n"); - return 1; - } - } - } - # if the file cann't be opened then - else { - # send a note to that affect to the errorlog - &B_log("ERROR","Unable to open file for read.\n$file\n$!\n"); - } - } - B_log('DEBUG','Pattern: ' . $pattern . ' not matched in file: ' . - $file . "\n"); - # the provided pattern was not matched against a line in the file - return 0; -} - -########################################################################### -# &B_match_line_only($file,$pattern); -# -# This subroutine checks if the specified pattern can be matched and if -# it's the only content in the file. The only content means it's only but -# may have several copies in the file. -# -# return values: -# 0: pattern not in file or pattern is not the only content -# or the file is not readable -# 1: pattern is in file and it's the only content -############################################################################ -sub B_match_line_only($$) { - my ($file,$pattern) = @_; - - # if matched, set to 1 later - my $retval = 0; - - # if the file is readable then - if(-r $file) { - # if the file can be opened then - if(&B_open(*FILED, $file)) { - # pattern should be matched at least once - # pattern can not be mismatched - while (my $line = <FILED>) { - if ($line =~ $pattern) { - $retval = 1; - } - else { - &B_close(*FILED); - return 0; - } - } - } - &B_close(*FILED); - } - - return $retval; -} - -########################################################################### -# &B_return_matched_lines($file,$pattern); -# -# This subroutine returns lines in a file matching a given regular -# expression, when called in the default list mode. When called in scalar -# mode, returns the number of elements found. -########################################################################### -sub B_return_matched_lines($$) -{ - my ($filename,$pattern) = @_; - my @lines = (); - - open(READFILE, $filename); - while (<READFILE>) { - chomp; - next unless /$pattern/; - push(@lines, $_); - } - if (wantarray) - { - return @lines; - } - else - { - return scalar (@lines); - } -} - -########################################################################### -# &B_match_chunk($file,$pattern); -# -# This subroutine will return a 1 if the pattern specified can be matched -# against the file specified on a line-agnostic form. This allows for -# patterns which by necessity must match against a multi-line pattern. -# This is the natural analogue to B_replace_chunk, which was created to -# provide multi-line capability not provided by B_replace_line. -# -# return values: -# 0: pattern not in file or the file is not readable -# 1: pattern is in file -########################################################################### - -sub B_match_chunk($$) { - - my ($file,$pattern) = @_; - my @lines; - my $big_long_line; - my $retval=1; - - open CHUNK_FILE,$file; - - # Read all lines into one scalar. - @lines = <CHUNK_FILE>; - close CHUNK_FILE; - - foreach my $line ( @lines ) { - $big_long_line .= $line; - } - - # Substitution routines get weird unless last line is terminated with \n - chomp $big_long_line; - $big_long_line .= "\n"; - - # Exit if we don't find a match - unless ($big_long_line =~ $pattern) { - $retval = 0; - } - - return $retval; -} - -########################################################################### -# &B_hash_comment_line ($filename,$pattern) modifies $filename, replacing -# any lines matching $pattern with a "hash-commented" version, like this: -# -# -# finger stream tcp nowait nobody /usr/sbin/tcpd in.fingerd -# becomes: -# #finger stream tcp nowait nobody /usr/sbin/tcpd in.fingerd -# -# Also: -# tftp dgram udp wait root /usr/lbin/tftpd tftpd\ -# /opt/ignite\ -# /var/opt/ignite -# becomes: -# #tftp dgram udp wait root /usr/lbin/tftpd tftpd\ -# # /opt/ignite\ -# # /var/opt/ignite -# -# -# B_hash_comment_line uses B_open_plus and B_close_plus, so that the file -# modified is backed up... -# -########################################################################### - -sub B_hash_comment_line($$) { - - my ($filename,$pattern) = @_; - my $retval=1; - - if ( &B_open_plus (*HASH_NEW,*HASH_OLD,$filename) ) { - my $line; - while ($line=<HASH_OLD>) { - unless ( ($line =~ $pattern) and ($line !~ /^\s*\#/) ) { - &B_print(*HASH_NEW,$line); - } - else { - &B_print(*HASH_NEW,"#$line"); - &B_log("ACTION","File modification in $filename -- hash commented line\n" . - "$line\n" . - "like this:\n" . - "#$line\n\n"); - # while the line has a trailing \ then we should also comment out the line below - while($line =~ m/\\\n$/) { - if($line=<HASH_OLD>) { - &B_print(*HASH_NEW,"#$line"); - &B_log("ACTION","File modification in $filename -- hash commented line\n" . - "$line\n" . - "like this:\n" . - "#$line\n\n"); - } - else { - $line = ""; - } - } - - } - } - &B_close_plus (*HASH_NEW,*HASH_OLD,$filename); - } - else { - $retval=0; - &B_log("ERROR","Couldn't hash-comment line(s) in $filename because open failed.\n"); - } - - return $retval; -} - - -########################################################################### -# &B_hash_uncomment_line ($filename,$pattern) modifies $filename, -# removing any commenting from lines that match $pattern. -# -# #finger stream tcp nowait nobody /usr/sbin/tcpd in.fingerd -# becomes: -# finger stream tcp nowait nobody /usr/sbin/tcpd in.fingerd -# -# -# B_hash_uncomment_line uses B_open_plus and B_close_plus, so that the file -# modified is backed up... -# -########################################################################### - -sub B_hash_uncomment_line($$) { - - my ($filename,$pattern) = @_; - my $retval=1; - - if ( &B_open_plus (*HASH_NEW,*HASH_OLD,$filename) ) { - my $line; - while ($line=<HASH_OLD>) { - unless ( ($line =~ $pattern) and ($line =~ /^\s*\#/) ) { - &B_print(*HASH_NEW,$line); - } - else { - $line =~ /^\s*\#+(.*)$/; - $line = "$1\n"; - - &B_print(*HASH_NEW,"$line"); - &B_log("ACTION","File modification in $filename -- hash uncommented line\n"); - &B_log("ACTION",$line); - # while the line has a trailing \ then we should also uncomment out the line below - while($line =~ m/\\\n$/) { - if($line=<HASH_OLD>) { - $line =~ /^\s*\#+(.*)$/; - $line = "$1\n"; - &B_print(*HASH_NEW,"$line"); - &B_log("ACTION","File modification in $filename -- hash uncommented line\n"); - &B_log("ACTION","#$line"); - &B_log("ACTION","like this:\n"); - &B_log("ACTION","$line"); - } - else { - $line = ""; - } - } - } - } - &B_close_plus (*HASH_NEW,*HASH_OLD,$filename); - } - else { - $retval=0; - &B_log("ERROR","Couldn't hash-uncomment line(s) in $filename because open failed.\n"); - } - - return $retval; -} - - - -########################################################################### -# &B_delete_line ($filename,$pattern) modifies $filename, deleting any -# lines matching $pattern. It uses B_replace_line to do this. -# -# B_replace_line uses B_open_plus and B_close_plus, so that the file -# modified is backed up... -# -# Here an example of where you might use this: -# -# You'd like to remove any timeout= lines in /etc/lilo.conf, so that your -# delay=1 modification will work. - -# -########################################################################### - - -sub B_delete_line($$) { - - my ($filename,$pattern)=@_; - my $retval=&B_replace_line($filename,$pattern,""); - - return $retval; -} - - -########################################################################### -# &B_chunk_replace ($file,$pattern,$replacement) reads $file replacing the -# first occurrence of $pattern with $replacement. -# -########################################################################### - -sub B_chunk_replace($$$) { - - my ($file,$pattern,$replacement) = @_; - - my @lines; - my $big_long_line; - my $retval=1; - - &B_open (*OLDFILE,$file); - - # Read all lines into one scalar. - @lines = <OLDFILE>; - &B_close (*OLDFILE); - foreach my $line ( @lines ) { - $big_long_line .= $line; - } - - # Substitution routines get weird unless last line is terminated with \n - chomp $big_long_line; - $big_long_line .= "\n"; - - # Exit if we don't find a match - unless ($big_long_line =~ $pattern) { - return 0; - } - - $big_long_line =~ s/$pattern/$replacement/s; - - $retval=&B_open_plus (*NEWFILE,*OLDFILE,$file); - if ($retval) { - &B_print (*NEWFILE,$big_long_line); - &B_close_plus (*NEWFILE,*OLDFILE,$file); - } - - return $retval; -} - -########################################################################### -# &B_print ($handle,@list) prints the items of @list to the file handle -# $handle. It logs the action and respects the $GLOBAL_LOGONLY variable. -# -########################################################################### - -sub B_print { - my $handle=shift @_; - - my $result=1; - - unless ($GLOBAL_LOGONLY) { - $result=print $handle @_; - } - - ($handle) = "$handle" =~ /[^:]+::[^:]+::([^:]+)/; - - $result; -} - - -########################################################################## -# &B_getValueFromFile($regex,$file); -# Takes a regex with a single group "()" and returns the unique value -# on any non-commented lines -# This (and B_return_matched_lines are only used in this file, though are -# probably more generally useful. For now, leaving these here serve the following -#functions: -# a) still gets exported/associated as part of the Test_API package, and -# is still availble for a couple operations that can't be deferred to the -# main test loop, as they save values so that individual tests don't have to -# recreate (copy / paste) the logic to get them. -# -# It also avoids the circular "use" if we incldued "use Test API" at the top -# of this file (Test API "uses" this file. -# Returns the uncommented, unique values of a param=value pair. -# -# Return values: -# 'Not Defined' if the value is not present or not uniquely defined. -# $value if the value is present and unique -# -########################################################################### -sub B_getValueFromFile ($$){ - my $inputRegex=$_[0]; - my $file=$_[1]; - my ($lastvalue,$value)=''; - - my @lines=&B_return_matched_lines($file, $inputRegex); - - return &B_getValueFromString($inputRegex,join('/n',@lines)); -} - -########################################################################## -# &B_getValueFromString($param,$string); -# Takes a regex with a single group "()" and returns the unique value -# on any non-commented lines -# This (and B_return_matched_lines are only used in this file, though are -# probably more generally useful. For now, leaving these here serve the following -#functions: -# a) still gets exported/associated as part of the Test_API package, and -# is still availble for a couple operations that can't be deferred to the -# main test loop, as they save values so that individual tests don't have to -# recreate (copy / paste) the logic to get them. -# -# It also avoids the circular "use" if we incldued "use Test API" at the top -# of this file (Test API "uses" this file. -# Returns the uncommented, unique values of a param=value pair. -# -# Return values: -# 'Not Unique' if the value is not uniquely defined. -# undef if the value isn't defined at all -# $value if the value is present and unique -# -########################################################################### -sub B_getValueFromString ($$){ - my $inputRegex=$_[0]; - my $inputString=$_[1]; - my $lastValue=''; - my $value=''; - - my @lines=split(/\n/,$inputString); - - &B_log("DEBUG","B_getvaluefromstring called with regex: $inputRegex and input: " . - $inputString); - foreach my $line (grep(/$inputRegex/,@lines)) { - $line =~ /$inputRegex/; - $value=$1; - if (($lastValue eq '') and ($value ne '')) { - $lastValue = $value; - } elsif (($lastValue ne $value) and ($value ne '')) { - B_log("DEBUG","getvaluefromstring returned Not Unique"); - return 'Not Unique'; - } - } - if ((not(defined($value))) or ($value eq '')) { - &B_log("DEBUG","Could not find regex match in string"); - return undef; - } else { - &B_log("DEBUG","B_getValueFromString Found: $value ; using: $inputRegex"); - return $value; - } -} - -############################################################### -# This function adds something to the To Do List. -# Arguments: -# 1) The string you want to add to the To Do List. -# 2) Optional: Question whose TODOFlag should be set to indicate -# A pending manual action in subsequent reports. Only skip this -# If there's no security-audit relevant action you need the user to -# accomplish -# Ex: -# &B_TODO("------\nInstalling IPFilter\n----\nGo get Ipfilter","IPFilter.install_ipfilter"); -# -# -# Returns: -# 0 - If error condition -# True, if sucess, specifically: -# "appended" if the append operation was successful -# "exists" if no change was made since the entry was already present -############################################################### -sub B_TODO ($;$) { - my $text = $_[0]; - my $FlaggedQuestion = $_[1]; - my $multilineString = ""; - - # trim off any leading and trailing new lines, regexes separated for "clarity" - $text =~ s/^\n+(.*)/$1/; - $text =~ s/(.*)\n+$/$1/; - - if ( ! -e &getGlobal('BFILE',"TODO") ) { - # Make the TODO list file for HP-UX Distro - &B_create_file(&getGlobal('BFILE', "TODO")); - &B_append_line(&getGlobal('BFILE', "TODO"),'a$b', - "Please take the steps below to make your system more secure,\n". - "then delete the item from this file and record what you did along\n". - "with the date and time in your system administration log. You\n". - "will need that information in case you ever need to revert your\n". - "changes.\n\n"); - } - - - if (open(TODO,"<" . &getGlobal('BFILE', "TODO"))) { - while (my $line = <TODO>) { - # getting rid of all meta characters. - $line =~ s/(\\|\||\(|\)|\[|\]|\{|\}|\^|\$|\*|\+|\?|\.)//g; - $multilineString .= $line; - } - chomp $multilineString; - $multilineString .= "\n"; - - close(TODO); - } - else { - &B_log("ERROR","Unable to read TODO.txt file.\n" . - "The following text could not be appended to the TODO list:\n" . - $text . - "End of TODO text\n"); - return 0; #False - } - - my $textPattern = $text; - - # getting rid of all meta characters. - $textPattern =~ s/(\\|\||\(|\)|\[|\]|\{|\}|\^|\$|\*|\+|\?|\.)//g; - - if( $multilineString !~ "$textPattern") { - my $datestamp = "{" . localtime() . "}"; - unless ( &B_append_line(&getGlobal('BFILE', "TODO"), "", $datestamp . "\n" . $text . "\n\n\n") ) { - &B_log("ERROR","TODO Failed for text: " . $text ); - } - #Note that we only set the flag on the *initial* entry in the TODO File - #Not on subsequent detection. This is to avoid the case where Bastille - #complains on a subsequent Bastille run of an already-performed manual - #action that the user neglected to delete from the TODO file. - # It does, however lead to a report of "nonsecure" when the user - #asked for the TODO item, performed it, Bastille detected that and cleared the - # Item, and then the user unperformed the action. I think this is proper behavior. - # rwf 06/06 - - if (defined($FlaggedQuestion)) { - &B_TODOFlags("set",$FlaggedQuestion); - } - return "appended"; #evals to true, and also notes what happened - } else { - return "exists"; #evals to true, and also - } - -} - - -##################################################################### -# &B_TODOFlags() -# -# This is the interface to the TODO flags. Test functions set these when they -# require a TODO item to be completed to get to a "secure" state. -# The prune/reporting function checks these to ensure no flags are set before -# reporting an item "secure" -# "Methods" are load | save | isSet <Question> | set <Question> | unset <Question> -# -###################################################################### - -sub B_TODOFlags($;$) { - my $action = $_[0]; - my $module = $_[1]; - - use File::Spec; - - my $todo_flag = &getGlobal("BFILE","TODOFlag"); - - &B_log("DEBUG","B_TODOFlags action: $action , module: $module"); - - if ($action eq "load") { - if (-e $todo_flag ) { - &B_open(*TODO_FLAGS, $todo_flag); - my @lines = <TODO_FLAGS>; - foreach my $line (@lines) { - chomp($line); - $GLOBAL_CONFIG{"$line"}{"TODOFlag"}="yes"; - } - return (&B_close(*TODO_FLAGS)); #return success of final close - } else { - return 1; #No-op is okay - } - } elsif ($action eq "save") { - # Make sure the file exists, else create - #Note we use open_plus and and create file, so if Bastille is - #reverted, all the flags will self-clear (file deleted) - my $flagNumber = 0; - my $flagData = ''; - foreach my $key (keys %GLOBAL_CONFIG) { - if ($GLOBAL_CONFIG{$key}{"TODOFlag"} eq "yes") { - ++$flagNumber; - $flagData .= "$key\n"; - } - } - if (not( -e $todo_flag)) { - &B_log("DEBUG","Initializing TODO Flag file: $todo_flag"); - &B_create_file($todo_flag); # Make sure it exists - } - &B_blank_file($todo_flag, - "This will not appear in the file; ensures blanking"); - return &B_append_line($todo_flag, "", "$flagData"); #return success of save - } elsif (($action eq "isSet") and ($module ne "")) { - if ($GLOBAL_CONFIG{"$module"}{"TODOFlag"} eq "yes") { - return 1; #TRUE - } else { - return 0; #FALSE - } - } elsif (($action eq "set") and ($module ne "")) { - $GLOBAL_CONFIG{"$module"}{"TODOFlag"} = "yes"; - } elsif (($action eq "clear") and ($module ne "")) { - $GLOBAL_CONFIG{"$module"}{"TODOFlag"} = ""; - } else { - &B_log("ERROR","TODO_Flag Called with invalid parameters: $action , $module". - "audit report may be incorrect."); - return 0; #FALSE - } -} - -1; - - |