#!/usr/bin/perl
##############################################################################
# Copyright (C) 1999, 2000 Jay Beale
# Copyright (C) 2001-2003 Hewlett Packard Company
# Licensed under the GNU General Public License
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
#############################################################################

##############################################################################
# This is the Back End to Bastille Linux, a hardening program for Linux.     #
# Its counterpart is found in the InteractiveBastille or AutomatedBastille   #
# program, which writes the configuration file used for this.                #
#                                                                            #
# The Bastille Front End and Back End were written by and are currently      #
# maintained by Bastille Linux's Lead Developer, Jay Beale.                  #
#                                                                            #
# The original content for Bastille was assembled by Jay Beale using many    #
# documents, including SANS' Securing Linux Step by Step, Kurt Seifried's    #
# Linux Administrators Security Guide, and many other pieces, including the  #
# Security HOWTO, the Unix Security Handbook, the Solaris Security FAQ and   #
# various magazine articles in LinuxWorld and SunWorld.                      #
#                                                                            #
##############################################################################


## Our use of modules is somewhat strange for Perl: we have a main routine
## in each module which runs on the "use" command.

use lib "/usr/lib";
push (@INC,"/usr/lib/perl5/site_perl/");
push (@INC,"/usr/lib/Bastille");

use Getopt::Long;
use File::Copy;

require Bastille::API;
import Bastille::API;    


# Process command-line arguments...
my $nodisclaim = 0;
my $verbose = 0;
my $force = 0;
my $log_only = 0;
my $debug = 0;

if( Getopt::Long::GetOptions( "n"     => \$nodisclaim,
                              "v"     => \$verbose,
                              "force" => \$force,
			      "log"   => \$log_only, 
			      "debug" => \$debug) ) {
    $error = 0; # no parse error

} else {
    $error = 1; # parse error
}

&setOptions($debug,$log_only,$verbose);
&ConfigureForDistro;

if ( $error ) { # GetOptions couldn't parse all of the args
    &ErrorLog(&getGlobal('ERROR',"usage") . "\n");
    exit(1);
}

print "NOTE:    Bastille is scanning the system configuration...\n\n";

require Bastille::IOLoader;
import Bastille::IOLoader;

&PrepareToRun;

&showDisclaimer($nodisclaim);

# Data Checking
# Loading Questions database for investigation and data validation
$Question{"Title_Screen"}{'proper_parent'}="Title_Screen";
$Question{"Title_Screen"}{'yes_child'}="End_Screen";

$Question{"End_Screen"}{'proper_parent'}="Title_Screen";
$Question{"End_Screen"}{'yes_child'}="End_Screen";


my $first_question = &Load_Questions('Y');

# Load in user's config file
unless (&ReadConfig) {
   &ErrorLog("ERROR:   Could not read config file: " . &getGlobal('BFILE', "config") . "\n");
   exit(1);
}

if($force) {
    &compareQandA($first_question,$force);
}
else {
    &compareQandA($first_question,$force);
    &validateAnswers;
}

unless ( $GLOBAL_LOGONLY ) {
# Since logonly should not make any changes (not even to configuration, mind you)
# lockfiles are not needed (jfs)
	if (-e &getGlobal('BFILE',"lockfile")){ # protect against simultaneous runs of Bastille
		&ErrorLog ("ERROR:  Another copy of bastille is currently making changes.\n".
				"        If you are sure yours is the only Bastille process running, \n".
				"        delete the file\n" . 
				"           " . &getGlobal('BFILE','lockfile')."\n".
				"        to reset lock.\n");
		exit 1;
	}else{
		system (&getGlobal('BIN',"touch")." ". &getGlobal('BFILE',"lockfile"));
	}
	print "Bastille is now locking down your system in accordance with your\n";
	print "answers in the \"config\" file.  Please be patient as some modules\n"; 
	print "may take a number of minutes, depending on the speed of your machine.\n\n";


} # of unless GLOBAL_LOGONLY
#######################################################################
##     Network Interface Protection/IPCHAINS/Personal Firewalling    ##
#######################################################################
if(exists $GLOBAL_CONFIG{Firewall}){
    print "Executing Firewall Specific Configuration\n";
    require Bastille::Firewall;
    import Bastille::Firewall;
}

#######################################################################
##                      Port Scan Attack Detection                   ##
#######################################################################

if(exists $GLOBAL_CONFIG{PSAD}){
    print "Executing PSAD Specific Configuration\n";
    require Bastille::PSAD;
    import Bastille::PSAD;
}

#######################################################################
##                            File Permissions                       ##
#######################################################################
if(exists $GLOBAL_CONFIG{FilePermissions}){
    print "Executing File Permissions Specific Configuration\n";
    require Bastille::FilePermissions;
    import Bastille::FilePermissions;
}

#######################################################################
##                     Account Creation/Security                     ##
#######################################################################
if(exists $GLOBAL_CONFIG{AccountSecurity}){
    print "Executing Account Security Specific Configuration\n";
    require Bastille::AccountSecurity;
    import Bastille::AccountSecurity; 
}

#######################################################################
##                Protecting LILO and single user mode               ##
#######################################################################
if(exists $GLOBAL_CONFIG{BootSecurity}){
    print "Executing Boot Security Specific Configuration\n";
    require Bastille::BootSecurity;
    import Bastille::BootSecurity;
}

#######################################################################
##                    inetd / TCP Wrappers Configuration             ##
#######################################################################

if(exists $GLOBAL_CONFIG{SecureInetd}){
    print "Executing Inetd Specific Configuration\n";
    require  Bastille::SecureInetd; 
    import Bastille::SecureInetd;
}

#######################################################################
##                      Disabling of User Space Tools                ##
#######################################################################
if(exists $GLOBAL_CONFIG{DisableUserTools}){
    print "Executing User Tool Specific Configuration\n";
    require Bastille::DisableUserTools;   
    import Bastille::DisableUserTools;
}

#######################################################################
##    Misc. Pluggable Authentication Modules (PAM) Configuration     ##
#######################################################################

if(exists $GLOBAL_CONFIG{ConfigureMiscPAM}){
    print "Executing PAM Specific Configuration\n";
    require Bastille::ConfigureMiscPAM; 
    import Bastille::ConfigureMiscPAM;
}

#######################################################################
##                               Logging                             ##
#######################################################################
if(exists $GLOBAL_CONFIG{Logging}){
    print "Executing Logging Specific Configuration\n";
    require  Bastille::Logging; 
    import Bastille::Logging;
}

#######################################################################
#######################################################################
####                            System Daemons                     ####
#######################################################################
#######################################################################

#######################################################################
##                          Miscellaneous Daemons                    ##
#######################################################################
if(exists $GLOBAL_CONFIG{MiscellaneousDaemons}){
    print "Executing Daemon Specific Configuration\n";
    require  Bastille::MiscellaneousDaemons;  
    import Bastille::MiscellaneousDaemons;
}

#######################################################################
##                               Sendmail                            ##
#######################################################################
if(exists $GLOBAL_CONFIG{Sendmail}){
    print "Executing Sendmail Specific Configuration\n";
    require Bastille::Sendmail; 
    import Bastille::Sendmail;
}

#######################################################################
##                            Remote Access                          ##
#######################################################################

# version 1.2.0 -- removed this module temporarily from run -- let's
# 		   make this smarter
#
#use Bastille::RemoteAccess;

#######################################################################
##                             DNS/BIND/NAMED                        ##
#######################################################################
if(exists $GLOBAL_CONFIG{DNS}){
    print "Executing DNS Specific Configuration\n";
    require Bastille::DNS;  
    import Bastille::DNS;
}

#######################################################################
##                              HTTP/APACHE                          ##
#######################################################################
if(exists $GLOBAL_CONFIG{Apache}){
    print "Executing Apache Specific Configuration\n";
    require  Bastille::Apache; 
    import Bastille::Apache; 
}

#######################################################################
##                                lpr/lpd                            ##
#######################################################################
if(exists $GLOBAL_CONFIG{Printing}){
    print "Executing Printing Specific Configuration\n";
    require  Bastille::Printing;
    import Bastille::Printing;
}

#######################################################################
##                                  FTP                              ##
#######################################################################

if(exists $GLOBAL_CONFIG{FTP}){
    print "Executing FTP Specific Configuration\n";
    require Bastille::FTP;
    import Bastille::FTP; 
}

#######################################################################
##                                 TMPDIR			    ## 
#######################################################################
if(exists $GLOBAL_CONFIG{TMPDIR}){
    print "Executing Temporary Directory Specific Configuration\n";
    require Bastille::TMPDIR;
    import Bastille::TMPDIR; 
}

#######################################################################
##            HP-UX Security Patch Check Configuration               ##
#######################################################################
if(exists $GLOBAL_CONFIG{Patches}){
    print "Executing HP-UX's Security Patch Check Configuration\n";
    require Bastille::Patches;
    import Bastille::Patches;
}

#######################################################################
##                       IPFilter Configuration                      ##
#######################################################################
if(exists $GLOBAL_CONFIG{IPFilter}){
    print "Executing IPFilter Configuration\n";
    use Bastille::IPFilter;
    &Bastille::IPFilter::run;
}

#######################################################################
##                            HP-UX OS Specific                      ##
#######################################################################
if(exists $GLOBAL_CONFIG{HP_UX}){
    print "Executing HP-UX Specific Configuration\n";
    require Bastille::HP_UX;
    import Bastille::HP_UX; 
}


#######################################################################
##                            Patch Download                         ##
#######################################################################
# Note: currently comented since both RedHat and Debian implementations
# do not work ok.

#use Bastille::PatchDownload;

#######################################################################
##          Setting all file sums recorded to a post bastille state  ##
#######################################################################
for my $file (sort keys %GLOBAL_SUM) {
    &B_set_sum($file);
}

#######################################################################
##              Point user at TODO list, if it exists                ##
#######################################################################
if ( -e &getGlobal('BFILE','TODO') ) {
   print("\nPlease check\n" . 
         &getGlobal('BFILE','TODO') . 
         "\nfor further instructions on how to secure your system.\n\n");
}

unless (unlink &getGlobal('BFILE',"lockfile")){  # Remove lockfile
    &ErrorLog ("ERROR:   Unable to delete Bastille lock file: ".
	       &getGlobal('BFILE','lockfile')."\n");
}

#######################################################################
##              Copying current config to last.config for            ##
##              logging purposes                                     ##
#######################################################################
copy(&getGlobal('BFILE',"config") , &getGlobal('BFILE',"last.config"));

#######################################################################
##              Point user at the ErrorLog, if it was used           ##
#######################################################################
if( defined $errorFlag ) {
    print STDERR "########################################################\n" . 
	         "Errors have occurred in the configuration.\n" . 
		 "Please view the following file for more details:\n\t" .
		 &getGlobal('BFILE',"error-log") . "\n" .
		 "########################################################\n\n"; 

    # Exiting with a warning flag as non fatal errors have occured.
    exit(2);
}

# Execution went without warning or fatal error.
exit(0);
