#!/usr/bin/perl -w ##=====================================================================## ## Copyright (c) 2001-2004 Stephen Zarkos. All rights reserved. ## Obsid@Sentry.net ## ## Please see file: COPYRIGHT for further copyright information and ## disclaimer. Or online at http://www.SentryFirewall.com/files/COPYRIGHT ##=====================================================================## ## File: build_config.pl ##------------------------------------------------------------------------------------## ## Sub recurse_dir(). ## Recurses through directory tree and fills @dirs with path/directory names. sub recurse_dir { my $path = "$_[0]"; my $dir = "$_[1]"; my ($slink,$filename,$status,$tmp) = ''; my $filehandle = rand(5000); (return 1) if ("${path}/${dir}" eq '/etc/default'); (return 1) if ("${path}/${dir}" eq '/etc/rc.d/SENTRY'); if (opendir($filehandle, "${path}/${dir}")) { while (defined($filename = readdir($filehandle))) { next if $filename =~ /^\.\.?$/; $status = ''; ## Recurse, fill @dirs with directory directory paths/names. if ((-d "${path}/${dir}/${filename}") && !(-l "${path}/${dir}/${filename}")) { foreach (@dir_exceptions) { if ($filename =~ /$_/) { $status = "0"; last; } } next if ($status eq "0"); next if ("${path}/${dir}/${filename}" eq '/etc/default/'); next if ("${path}/${dir}/${filename}" eq '/etc/rc.d/SENTRY/'); push(@dirs, "${path}/${dir}/${filename}"); &recurse_dir("$path/$dir", "$filename"); } # elsif (-l "${path}/${dir}/${filename}") { # if ($slink = readlink("${path}/${dir}/${filename}")) { # next if (!(-e "$slink")); # if (-d "$slink") { # $prefs{"${path}/${dir}/${filename}"} = "$slink"; # next; # } # next if ($slink =~ /^\/etc\/default\/?/); # if (("${path}/${dir}" eq '/etc') || ("${path}/${dir}" eq '/etc/rc.d')) { # foreach (@etc_vars) { # next if ("$filename" ne "$_"); # $status = "0"; # $prefs{"$_"} = "${path}/${dir}/${filename}"; # last; # } # if ($status ne "0") { # $prefs{"${path}/${dir}/${filename}"} = "${path}/${dir}/${filename}"; } # } # elsif ("${path}/${dir}" eq '/etc/ssh') { # foreach (@ssh_vars) { # next if ("$filename" ne "$_"); # $status = "0"; # $prefs{"$_"} = "${path}/${dir}/${filename}"; # last; # } # if ($status ne "0") { # $prefs{"${path}/${dir}/${filename}"} = "${path}/${dir}/${filename}"; } # } # else { # $prefs{"${path}/${dir}/${filename}"} = "${path}/${dir}/${filename}"; } # # } # next; # } # elsif (-f "${path}/${dir}/${filename}") { # next if (($filename =~ /\.gif$/) || ($filename =~ /\.jpg$/)); # if (("${path}/${dir}" eq '/etc') || ("${path}/${dir}" eq '/etc/rc.d')) { # foreach (@etc_vars) { # next if ("$filename" ne "$_"); # $status = "0"; # $prefs{"$_"} = "${path}/${dir}/${filename}"; # last; # } # if ($status ne "0") { # $prefs{"${path}/${dir}/${filename}"} = "${path}/${dir}/${filename}"; # next; # } # } # elsif ("${path}/${dir}" eq '/etc/ssh') { # foreach (@ssh_vars) { # next if ("$filename" ne "$_"); # $status = "0"; # $prefs{"$_"} = "${path}/${dir}/${filename}"; # last; # } # if ($status ne "0") { # $prefs{"${path}/${dir}/${filename}"} = "${path}/${dir}/${filename}"; # next; # } # } # else { # $prefs{"${path}/${dir}/${filename}"} = "${path}/${dir}/${filename}"; } # } } ## End while loop closedir($filehandle); return 1; } else { return 0; } ## Return Error. return 1; } ## End sub recurse_dir() ##------------------------------------------------------------------------------------## ##------------------------------------------------------------------------------------## ## Function prune_dirs() ## Remove directories from @dirs if the files within those directories don't ## differ from their counterparts in /etc/default/. sub prune_dirs { my $filename = ''; my $tmp = ''; my $status = 1; foreach (@dirs) { if ($_ eq '/etc/default') { ## Remove /etc/default from list. $_ = ''; next; } $tmp = "$_"; $tmp =~ s/^\/etc\/?//; if (opendir(DH, "/etc/${tmp}")) { while (defined($filename = readdir(DH))) { next if $filename =~ /^\.\.?$/; next if (!(-f "${_}/${filename}")); ## Must be a regular file. if (!(-f "/etc/default/${tmp}/${filename}")) { ## File is new(not in /etc/default/). Don't do anything. $status = 0; last; } if (`diff -b --brief /etc/default/${tmp}/${filename} /etc/${tmp}/${filename} 2>/dev/null`) { ## Files differ, so end the loop and don't do anything. $status = 0; last; } } closedir(DH); } if ($status != 0) { ## If no differences found, clear $_ to remove it from the list. $_ = ''; } $status = 1; } return 1; } ## End sub prune_dirs() ##------------------------------------------------------------------------------------## ##------------------------------------------------------------------------------------## ## Sub fill_prefs() ## Fill %prefs with info about changed or new files. sub fill_prefs { return 0 if !(defined($_[0])); my $parray = $_[0]; my ($filename,$tmp,$var,$last) = (); foreach (@$parray) { if (opendir(DH, "$_")) { while (defined($filename = readdir(DH))) { next if ($filename =~ /^\.\.?$/); next if (!(-f "${_}/${filename}")); # foreach $var (@file_exceptions) { # $tmp = "${_}/${filename}"; # if ($tmp =~ /$var/) { # $status = "0"; last; # } # } next if ($status eq "0"); $_ =~ s/\/+$//; $tmp = "$_"; $tmp =~ s/^\/etc\/?//; $tmp =~ s/\/{2,}/\//g; if (!(-f "/etc/default/${tmp}/${filename}")) { ## File not in /etc/default, must be new. $prefs{"$filename"}->{'conf'} = "/floppy/config/${filename}"; $prefs{"$filename"}->{'loc'} = "${_}/${filename}"; $prefs{"$filename"}->{'misc'} = "$_"; next; } if (`diff -b --brief /etc/default/${tmp}/${filename} /etc/${tmp}/${filename} 2>/dev/null`) { ## Files differ, shove them into %prefs. $last = 0; foreach $var (keys %specdir) { if ($specdir{"$var"} eq "$_") { if ($filename eq "$var") { ## $_ matches a directory in %specdir and $var also matches $filename. ## Shove element into %prefs. $prefs{"$filename"}->{'conf'} = "/floppy/config/${filename}"; $prefs{"$filename"}->{'loc'} = "${_}/${filename}"; $prefs{"$filename"}->{'misc'} = 'NULL'; $last = 1; last; } } } next if ($last == 1); if ($_ eq '/etc') { foreach $var (@etc_vars) { if ($var eq "$filename") { $prefs{"$filename"}->{'conf'} = "/floppy/config/${filename}"; $prefs{"$filename"}->{'loc'} = "${_}/${filename}"; $prefs{"$filename"}->{'misc'} = 'NULL'; last; } } ## File not in @etc_vars. $prefs{"$filename"}->{'conf'} = "/floppy/config/${filename}"; $prefs{"$filename"}->{'loc'} = "${_}/${filename}"; $prefs{"$filename"}->{'misc'} = "$_"; } elsif ($_ eq '/etc/ssh') { foreach $var (@ssh_vars) { if ($var eq "$filename") { $prefs{"$filename"}->{'conf'} = "/floppy/config/${filename}"; $prefs{"$filename"}->{'loc'} = "${_}/${filename}"; $prefs{"$filename"}->{'misc'} = 'NULL'; last; } } ## File not in @ssh_vars. $prefs{"$filename"}->{'conf'} = "/floppy/config/${filename}"; $prefs{"$filename"}->{'loc'} = "${_}/${filename}"; $prefs{"$filename"}->{'misc'} = "$_"; } else { $prefs{"$filename"}->{'conf'} = "/floppy/config/${filename}"; $prefs{"$filename"}->{'loc'} = "${_}/${filename}"; $prefs{"$filename"}->{'misc'} = "$_"; } } } closedir(DH); } else { ## Error, can't open directory. } } return 1; } ## End Sub fill_prefs(). ##------------------------------------------------------------------------------------## ##------------------------------------------------------------------------------------## ## Sub build_config() ## Create sentry.conf from info contained in %prefs. sub build_config { my $localtime = localtime; $localtime =~ s/\s+/ /g; my $tab = ''; &infobox("Building sentry.conf... ", "0 0", "1"); if (open(FH,">/tmp/floppy.${rand_var}/sentry.conf")) { flock(FH,2); print FH "\#\# Sentry Firewall CD 1.x Configuration File\n"; print FH "\#\# Generated by mkconfig v${version} on $localtime\n"; print FH "\n"; print FH "\#\# All configuration directives are case sensitive. Anything after a \'#\'\n"; print FH "\#\# sign is considered a comment.\n"; print FH "\n\n"; print FH "\#\#-----------------------------------------------------------------------\#\#\n"; print FH "\#\# /etc/rc.d Initialization Scripts.\n\n"; foreach (@etc_vars) { if (exists($prefs{$_})) { if ($_ =~ /^rc\./) { $tab = &fix_tab($_); print FH " $_" . "$tab" . "=\t$prefs{$_}->{'conf'}\n"; delete($prefs{$_}); } } } print FH "\n\n"; print FH "\#\#-----------------------------------------------------------------------\#\#\n"; print FH "\#\# Common System and Configuration Files.\n\n"; foreach (@etc_vars) { if (exists($prefs{$_})) { $tab = &fix_tab($_); print FH " $_" . "$tab" . "=\t$prefs{$_}->{'conf'}\n"; delete($prefs{$_}); } } print FH "\n\n"; print FH "\#\#-----------------------------------------------------------------------\#\#\n"; print FH "\#\# OpenSSH Configuration Directives and Host Keys.\n"; print FH "\#\# If no host keys are specified rc.sshd creates them at\n"; print FH "\#\# boot time. No default host keys are present on the rootdisk,\n"; print FH "\#\# for obvious reasons.\n\n"; foreach (@ssh_vars) { if (exists($prefs{$_})) { $tab = &fix_tab($_); print FH " $_" . "$tab" . "=\t$prefs{$_}->{'conf'}\n"; delete($prefs{$_}); } } print FH "\n\n"; print FH "\#\#-----------------------------------------------------------------------\#\#\n"; print FH "\#\# Other Configuration Directives.\n\n"; foreach (keys %prefs) { if (($_ ne '') && ($prefs{$_}->{'conf'} ne '')) { if (($prefs{$_}->{'misc'} ne 'NULL') && ($prefs{$_}->{'misc'} ne '')) { $tab = &fix_tab("$prefs{$_}->{'misc'}/${_}"); print FH " $prefs{$_}->{'misc'}/${_}" . "$tab" . "=\t$prefs{$_}->{'conf'}\n"; } else { $tab = &fix_tab($_); print FH " $_" . "$tab" . "=\t$prefs{$_}->{'conf'}\n"; } delete($prefs{$_}); } } print FH "\n\n"; print FH "\#\#-----------------------------------------------------------------------\#\#\n"; print FH "\#\# CDROM device where the Sentry Firewall CD is located. If not declared\n"; print FH "\#\# the configuration scripts will still try to probe for and mount the CD.\n"; print FH "\#\# But declaring this is much easier/faster/safer.\n\n"; print FH " \# cdrom = /dev/hdc\n"; print FH "\n\n"; close(FH); chmod 0600, "/tmp/floppy.${rand_var}/sentry.conf"; } else { return 0; } return 1; } ## End Sub build_config(). ##------------------------------------------------------------------------------------## ##------------------------------------------------------------------------------------## ## Sub fix_tab() ## Calculates the number of tabs needed to make output look pretty. sub fix_tab { my $tb = "$_[0]"; if ((length("$tb") + 1) < 8) { return "\t\t\t"; } elsif ((length("$tb") + 1) < 16) { return "\t\t"; } else { return "\t"; } return 1; } ## End Sub fix_tab(). ##------------------------------------------------------------------------------------## ## Avoid Errors. $version = $version; @dir_exceptions = @dir_exceptions; return 1; ## _EOF_ ##