J
John Adams
To learn Perl, I have written a bit of code that needs to do the following:
1) Load a configuration file with various line formats (i.e. starting
with }, or ), or SEC_CRIT, etc)
2) Load a second file with a list of file names in the form of
"/usr/sbin/someprog", "/usr/etc/somefile" etc
3) Write each line (keeping the same format in terms of leading spaces and
blank lines) unless it matches
an entry in the second file list where it will add a "# " to the line to
comment it out.
The configuration file is called "list.txt" while the configuration file is
"policy.txt". The code below works, but it could probably be done more
efficiently. Some ideas on how this script can be made leaner would be
greatly appreciated. Below is the code and then some sample data for the
two files:
__CODE__ match.pl
#!/usr/bin/perl
use strict;
use warnings;
open(SEARCH, "list.txt") || die "Can't open file list.txt";
my (@search_string) = <SEARCH>;
close(SEARCH);
open(POLICY, "policy.txt") || die "Can't open file policy.txt";
my (@policy_lines) = <POLICY>;
close(POLICY);
# Declare Variables #
my $first_part;
my $first_part2;
my $i;
my $search_string;
my $policy_line;
my $policy_line2;
foreach $policy_line(@policy_lines) { #1
for ($i=0;$i<scalar(@search_string);$i++ ) { #2
if ($policy_line =~ /^(\s)*$/) {next;} #
Ignore Blank Lines
$policy_line2 = $policy_line;
$policy_line2 =~ s/^\s*//; #
Remove leading whitespace
($first_part) = split(/\s+/,$policy_line2); #
Avoid collisions with text after search string
$first_part2 = quotemeta($first_part); #
Quote Meta Characters
if ($search_string[$i] =~ /$first_part2$/) { #3 #
Match strings with first and last anchors
print "# ",$policy_line; last; #
Print commented line if matched
}
else {next;}
} #4
{
if ($i>=scalar(@search_string)) { print $policy_line; next;} #
Just print line if not matched
}
}
__END__
__FILE__ list.txt
/usr/sbin/a
/usr/sbin/11
/sbin/busybox
/usr/sbin/3
/usr/sbin/22
/sbin/accton
__END__
__FILE__ policy.txt
############################################################################
##
#
##
############################################################################
## #
#
# #
# Policy file
# #
#
##
############################################################################
##
############################################################################
##
/usr/sbin
/usr/sbin/a
/usr/sbin/b
/usr/sbin/c
/usr/sbin/d
/usr/sbin/e
/usr/sbin/f
/usr/sbin/1
/usr/sbin/2
/usr/sbin/3
/usr/sbin/4
/usr/sbin/11
/usr/sbin/22
/usr/sbin/33
/usr/sbin/44
/usr/sbin/55
@@section GLOBAL
TWROOT=/usr/sbin;
TWBIN=/usr/sbin;
@@section FS
SEC_CRIT = $(IgnoreNone)-SHa ; # Critical files that cannot change
SEC_SUID = $(IgnoreNone)-SHa ; # Binaries with the SUID or SGID flags
set
SEC_BIN = $(ReadOnly) ; # Binaries that should not change
SEC_CONFIG = $(Dynamic) ; # Config files that are changed
infrequently but accessed often
SEC_LOG = $(Growing) ; # Files that grow, but that should
never change ownership
SEC_INVARIANT = +tpug ; # Directories that should never change
permission or ownership
SIG_LOW = 33 ; # Non-critical files that are of
minimal security impact
SIG_MED = 66 ; # Non-critical files that are of
significant security impact
SIG_HI = 100 ; # Critical files that are significant
points of vulnerability
# Binaries
(
)
{
{
/sbin/accton -> $(SEC_CRIT) ;
/sbin/badblocks -> $(SEC_CRIT) ;
/sbin/busybox -> $(SEC_CRIT) ;
/sbin/busybox.anaconda -> $(SEC_CRIT) ;
/sbin/convertquota -> $(SEC_CRIT) ;
/sbin/dosfsck -> $(SEC_CRIT) ;
/sbin/debugfs -> $(SEC_CRIT) ;
/sbin/debugreiserfs -> $(SEC_CRIT) ;
__END__
1) Load a configuration file with various line formats (i.e. starting
with }, or ), or SEC_CRIT, etc)
2) Load a second file with a list of file names in the form of
"/usr/sbin/someprog", "/usr/etc/somefile" etc
3) Write each line (keeping the same format in terms of leading spaces and
blank lines) unless it matches
an entry in the second file list where it will add a "# " to the line to
comment it out.
The configuration file is called "list.txt" while the configuration file is
"policy.txt". The code below works, but it could probably be done more
efficiently. Some ideas on how this script can be made leaner would be
greatly appreciated. Below is the code and then some sample data for the
two files:
__CODE__ match.pl
#!/usr/bin/perl
use strict;
use warnings;
open(SEARCH, "list.txt") || die "Can't open file list.txt";
my (@search_string) = <SEARCH>;
close(SEARCH);
open(POLICY, "policy.txt") || die "Can't open file policy.txt";
my (@policy_lines) = <POLICY>;
close(POLICY);
# Declare Variables #
my $first_part;
my $first_part2;
my $i;
my $search_string;
my $policy_line;
my $policy_line2;
foreach $policy_line(@policy_lines) { #1
for ($i=0;$i<scalar(@search_string);$i++ ) { #2
if ($policy_line =~ /^(\s)*$/) {next;} #
Ignore Blank Lines
$policy_line2 = $policy_line;
$policy_line2 =~ s/^\s*//; #
Remove leading whitespace
($first_part) = split(/\s+/,$policy_line2); #
Avoid collisions with text after search string
$first_part2 = quotemeta($first_part); #
Quote Meta Characters
if ($search_string[$i] =~ /$first_part2$/) { #3 #
Match strings with first and last anchors
print "# ",$policy_line; last; #
Print commented line if matched
}
else {next;}
} #4
{
if ($i>=scalar(@search_string)) { print $policy_line; next;} #
Just print line if not matched
}
}
__END__
__FILE__ list.txt
/usr/sbin/a
/usr/sbin/11
/sbin/busybox
/usr/sbin/3
/usr/sbin/22
/sbin/accton
__END__
__FILE__ policy.txt
############################################################################
##
#
##
############################################################################
## #
#
# #
# Policy file
# #
#
##
############################################################################
##
############################################################################
##
/usr/sbin
/usr/sbin/a
/usr/sbin/b
/usr/sbin/c
/usr/sbin/d
/usr/sbin/e
/usr/sbin/f
/usr/sbin/1
/usr/sbin/2
/usr/sbin/3
/usr/sbin/4
/usr/sbin/11
/usr/sbin/22
/usr/sbin/33
/usr/sbin/44
/usr/sbin/55
@@section GLOBAL
TWROOT=/usr/sbin;
TWBIN=/usr/sbin;
@@section FS
SEC_CRIT = $(IgnoreNone)-SHa ; # Critical files that cannot change
SEC_SUID = $(IgnoreNone)-SHa ; # Binaries with the SUID or SGID flags
set
SEC_BIN = $(ReadOnly) ; # Binaries that should not change
SEC_CONFIG = $(Dynamic) ; # Config files that are changed
infrequently but accessed often
SEC_LOG = $(Growing) ; # Files that grow, but that should
never change ownership
SEC_INVARIANT = +tpug ; # Directories that should never change
permission or ownership
SIG_LOW = 33 ; # Non-critical files that are of
minimal security impact
SIG_MED = 66 ; # Non-critical files that are of
significant security impact
SIG_HI = 100 ; # Critical files that are significant
points of vulnerability
# Binaries
(
)
{
{
/sbin/accton -> $(SEC_CRIT) ;
/sbin/badblocks -> $(SEC_CRIT) ;
/sbin/busybox -> $(SEC_CRIT) ;
/sbin/busybox.anaconda -> $(SEC_CRIT) ;
/sbin/convertquota -> $(SEC_CRIT) ;
/sbin/dosfsck -> $(SEC_CRIT) ;
/sbin/debugfs -> $(SEC_CRIT) ;
/sbin/debugreiserfs -> $(SEC_CRIT) ;
__END__