#!/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: mkconfig #TODO: # - Symlink support, see if symlinks are "new", put them in sentry.conf. # - Make script behavior vary depending on how it is called. # - sentry-save # - sentry-update # - Debugging code. # - More output options. # - Floppy(done). # - USB drive. # - Floppy image(done). # - tar.gz # - Support for files in - # - /var/chroot/snort/etc/snort # - /var/chroot/named/etc/namedb # - /var/chroot/named/etc/namedb/slave # - Prompt to format device. # - (DONE) Parsing/updating sentry.conf file # - And to only do this # - Find config # - Parse config # - Find updated files # - Copy updated files to temporary location # - Write out sentry.conf(no need to even change it - timestamp, maybe). # - Copy files and sentry.conf to new location(floppy/usb). # - Back up old sentry.conf on floppy/usb(just in case). MAIN: { require('/cdrom/SENTRY/scripts/MK-CONFIG/config_ops.pl'); require('/cdrom/SENTRY/scripts/MK-CONFIG/build_config.pl'); require('/cdrom/SENTRY/scripts/MK-CONFIG/floppy.pl'); $ENV{PATH} = "/bin:/sbin:/usr/bin:/usr/sbin"; umask 022; $SIG{INT} = \&ctrl_c; $SIG{HUP} = \&ctrl_c; $version = '0.3-BETA'; $rand_var = rand(50000); %prefs = (); @mounted = (); $output = ''; $output_file = '/tmp/tmpfile.' . "$rand_var"; my $status = ''; ## Dialog title $title = "Sentry Firewall CD: mkconfig v${version}"; if ($> != 0) { print "[-] Sorry, you must be root to use this utility.\n"; exit(0); } if (-e "/tmp/floppy.${rand_var}") { print "ERROR: /tmp directory unclean.\n"; exit(2); } system("which dialog 1>/dev/null 2>/dev/null"); if ($? > 0) { print "ERROR: dialog(1) utility not found.\n"; exit(2); } ## This avoids some silly errors. @etc_vars = (); @ssh_vars = (); @file_exceptions = (); @dir_exceptions = (); %prefs = (); %specdir = (); @etc_vars = ('rc.M', 'rc.6', 'rc.netdevice', 'rc.inet1', 'rc.inet1.conf', 'rc.inet2', 'rc.local', 'rc.modules', 'rc.firewall', 'rc.firewall.nat', 'rc.keymap', 'rc.snort', 'rc.sendmail', 'rc.ntpd', 'rc.firewall.save', 'passwd', 'shadow', 'group', 'fstab', 'hosts.equiv', 'hosts.allow', 'hosts.deny', 'profile', 'inetd.conf', 'snort.conf', 'proftpd.conf', 'shells', 'ftpusers', 'syslog.conf', 'named.conf', 'rndc.conf', 'newsyslog.conf', 'resolv.conf', 'hosts', 'hostname', 'squid.conf', 'smb.conf', 'pptpd.conf', 'gated.conf', 'syslog-ng.conf', 'pppoe.conf', 'httpd.conf', 'openssl.cnf', 'modules.conf', 'ntp.conf', 'ipsec.conf', 'ipsec.secrets', 'stunnel.conf', 'stunnel.pem', 'snmpd.conf', 'inittab', 'wlan.conf', 'miniserv.conf', 'miniserv.pem', 'miniserv.users', 'webmin_config', 'shorewall.conf', 'portsentry.conf', 'ulogd.conf', 'dnsmasq.conf', 'rinetd.conf', 'dhcpd.conf', 'sendmail.cf', 'zebra.conf', 'bgpd.conf', 'ospfd.conf', 'ripd.conf', 'lpd.conf', 'l2tpd.conf', 'ss5.conf'); @ssh_vars = ('shosts.equiv', 'ssh_config', 'sshd_config', 'ssh_host_dsa_key', 'ssh_host_dsa_key.pub', 'ssh_host_rsa_key', 'ssh_host_rsa_key.pub', 'ssh_host_key', 'ssh_host_key.pub', 'ssh_known_hosts', 'ssh_known_hosts2'); %specdir = ( 'squid.conf', '/etc/squid', 'smb.conf', '/etc/samba', 'httpd.conf', '/etc/apache', 'pppoe.conf', '/etc/ppp', 'syslog-ng.conf', '/etc/syslog-ng', 'openssl.cnf', '/etc/ssl', 'stunnel.conf', '/etc/stunnel', 'stunnel.pem', '/etc/stunnel', 'snmpd.conf', '/etc/ucd-snmp', 'wlan.conf', '/etc/wlan', 'miniserv.conf', '/etc/webmin', 'miniserv.pem', '/etc/webmin', 'miniserv.users', '/etc/webmin', 'webmin_config', '/etc/webmin', 'shorewall.conf', '/etc/shorewall', 'portsentry.conf', '/etc/portsentry', 'sendmail.cf', '/etc/mail', 'zebra.conf', '/etc/zebra', 'bgpd.conf', '/etc/zebra', 'ospfd.conf', '/etc/zebra', 'ripd.conf', '/etc/zebra', 'l2tpd.conf', '/etc/l2tp', 'ss5.conf', '/etc/ss5'); @dir_exceptions = ('X11'); @file_exceptions = ('^\/etc\/rc\.d\/rc\.K$', '^\/etc\/rc\.d\/rc\.[012345]{1}$', '^\/etc\/rc\.d\/rc\.S$', '^\/etc\/rc\.d\/rc\.inet1\.old$', '^\/etc\/rmt$', '^\/etc\/shadow\-$', '^\/etc\/passwd\-$', '\.*\-sample$', '\.*\-example$', '\.so$', '^\/etc\/ssh\/sshd_config\.local$', '^\/etc\/random\-seed$', '^\/etc\/xinetd.d.none$', '^\/etc\/mtab$', '^\/etc\/termcap$', '^\/etc\/gtk', '\.OLD$', '\.old$', '^\~.*$', '^.*\~$'); if ($0 eq 'update_config') { my ($mode, $ext_args) = (); foreach (@ARGV) { $_ = tolower($_); $_ =~ s/[\s\t]+//g; } if ($ARGV[0] eq 'usb') { print "Function not yet implemented.\n"; exit(1); } if (($ARGV[0] eq 'floppy') || ($ARGV[0] eq 'usb')) { $mode = "$ARGV[0]"; if (defined($ARGV[1])) { $ext_args = "$ARGV[1]"; } } else { print "Invalid mode: \"$ARGV[0]\"\n"; exit(1); } &update_config($mode,$ext_args); } &infobox("\\n${title}\\nCopyright (C) Stephen A. Zarkos, \\n\\n\\nOne moment please...", "10 50", 1); do { if (-e "${output_file}") { &infobox("ERROR: /tmp directory unclean! Exiting...\n", "0 0", 2); exit(2); } else { system("touch ${output_file}"); if ("$?" > "0") { &infobox("Unable to create ${output_file}, exiting...", "0 0", 2); exit(0); } chmod 0600, "/tmp/${output_file}"; } system("dialog --title \"$title\" --menu \"\nPlease select one of the following options:\n\" 0 0 0 \"SAVE\" \"Save Current Configuration \" \"EXIT\" \"Exit Program \" 2>${output_file}"); &get_output; if ("$?" > "0") { &ctrl_c; exit(0); } if ($output eq 'SAVE') { $status = &save_config; if ($status != 1) { &ctrl_c('noexit'); } else { system("dialog --title \"$title\" --menu \"\nConfiguration files have been copied.\n\nPlease select one of the following options:\n\" 0 0 0 \"FLOPPY\" \"Save configuration to a floppy disk \" \"FLOPPY IMAGE\" \"Save configuration to a floppy image \" \"CANCEL\" \"Return to main menu \" 2>${output_file}"); &get_output; if ($output eq 'FLOPPY') { $status = &create_floppy; ($output = 'EXIT') if ($status == 1); } elsif ($output eq 'FLOPPY IMAGE') { $status = &mk_image; ($output = 'EXIT') if ($status == 1); } &ctrl_c('noexit'); } } } until ($output eq 'EXIT'); &ctrl_c('noexit') if (-f "$output_file"); system('/usr/bin/clear') if (-x "/usr/bin/clear"); exit(0); } ## End Main ##------------------------------------------------------------------------------------## sub mount { $SIG{ALRM} = sub { die "TIMEOUT" }; my $command = "$_[0]"; my $dev = "$_[1]"; my $m_point = "$_[2]"; eval { alarm(10); ## Set timeout to 10 seconds. if ($command =~ /\/?umount/) { system("umount $dev 1>/dev/null 2>/dev/null"); } elsif ($command =~ /\/?mount/) { system("mount $dev $m_point 1>/dev/null 2>/dev/null"); } alarm(0); }; if ($@) { if ($@ =~ /TIMEOUT/) { ## Command timed out return 2; ## Timed Out } else { alarm(0); return 0; ## Return Error } } if (($?) && ($? gt "0")) { ## Something went wrong ## Do something productive return 0; ## Return Error } else { sleep(1); return 1; Return Success } } ## End sub mount ##------------------------------------------------------------------------------------## ##------------------------------------------------------------------------------------## sub infobox { my $text = "$_[0]"; my $sizevars = "$_[1]"; my $sleep = "$_[2]"; $sleep = defined($sleep) ? $sleep : 2; system("dialog --aspect 60 --colors --sleep ${sleep} --title \"${title}\" --infobox \"${text}\" ${sizevars}"); return 1; } ## End sub infobox() ##------------------------------------------------------------------------------------## ##------------------------------------------------------------------------------------## sub get_output { $output = ''; if (open(FH, "<${output_file}")) { flock(FH,2); $output = ; chomp($output) if (defined($output)); close(FH); } else { $output = 'NULL'; return 0; } if (!(defined($output))) { $output = 'NULL'; } return 1; } ## End sub get_output() ##------------------------------------------------------------------------------------## ##------------------------------------------------------------------------------------## sub ctrl_c { $SIG{INT} = \&ctrl_c; my $option = defined($_[0]) ? $_[0] : ''; my $status = ""; &infobox("Cleaning up, please wait...", "0 0", "1"); if (-d "/tmp/floppy.${rand_var}") { system("rm -rf /tmp/floppy.${rand_var} 1>/dev/null 2>/dev/null"); } if (-f "$output_file") { system("rm -f $output_file 1>/dev/null 2>/dev/null"); } ## unmount devices in @mounted. foreach (@mounted) { next if ($_ eq ''); &infobox("Unmounting ${_}...", "0 0", "1"); $status = &mount('umount', "$_", 'NULL'); if ($status != 1) { &infobox("ERROR: An error occurred while unmounting ${_}.\n\n", "0 0", "5"); } else { $_ = ''; } } return 1 if ($option eq 'noexit'); system('/usr/bin/clear') if (-x "/usr/bin/clear"); exit(0); } ## End sub ctrl_c() ##------------------------------------------------------------------------------------## return 1; ## _EOF_ ##