#!/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: config_ops.pl ##------------------------------------------------------------------------------------## ## Function: save_config() ## Take current configuration and create floppy config disk and sentry.conf. sub save_config { my ($key,$status,$tags) = (); my @newdirs = (); %prefs = (); local (@dirs) = ('/etc'); &infobox("\\nProcessing current configuration in /etc,\\nplease wait...\\n\\n NOTE: Symlinks to files in /etc/default/ will not be processed.", "0 0", "0"); ## Create /tmp/floppy.${rand_var}/config if (!(mkdir("/tmp/floppy.${rand_var}", 0700))) { &infobox("Unable to mkdir /tmp/floppy.${rand_var}.", "0 0", "2"); return 0; } if (!(mkdir("/tmp/floppy.${rand_var}/config", 0700))) { &infobox("Unable to mkdir /tmp/floppy.${rand_var}/config.", "0 0", "2"); rmdir("/tmp/floppy.${rand_var}"); return 0; } ## Populate @dirs and %prefs with stuff in /etc. &recurse_dir('', 'etc'); ## Call prune_dirs() to remove those directories from @dirs if the ## contents do not differ from their counterparts in /etc/default/. &prune_dirs; ## Iterate through @dirs, build command tag list for dialog(1). foreach (@dirs) { next if ($_ eq ''); $tags .= " $_ \"\" on"; } system("dialog --title \"$title\" --checklist \"\\nPlease select which directories you would like processed:\\n\\nNOTE: The directories listed here only represent those whose contents differ from their counterparts in /etc/default/.\\n\\n\" 0 0 0 $tags 2>${output_file}"); &get_output; if (("$?" > "0") || ($output eq 'NULL')) { ## Cancel button was pressed or nothing was selected. %prefs = (); return 2; } ## $tags will now hold the directories user would like to process. ## Strip " and shove the rest into @newdirs. $tags = $output; $tags =~ s/\"//g; @newdirs = split(/ /, $tags); &infobox("Copying files, please wait...", "0 0", "1"); ## Call fill_prefs() to parse directories in @newdirs and fill %prefs() with info about ## changed files. $status = &fill_prefs(\@newdirs); return 0 if ($status == 0); foreach (keys %prefs) { system("cp -p $prefs{$_}->{'loc'} /tmp/floppy.${rand_var}/config/${_} 1>/dev/null 2>/dev/null"); if ($? > "0") { delete($prefs{"$_"}); return 0; ## FIXME: Error. } } $status = &build_config; return 0 if ($status != 1); ## Make sure collected files will even fit on floppy... $output = `du -sh /tmp/floppy.${rand_var}`; chomp($output); $output =~ s/[\s\t]+.+//; if ($output =~ /M$/) { $output =~ s/M$//; if ($output > 1.4) { &infobox("ERROR: Not enough space on floppy disk to copy selected files! \nPlease select fewer directories to process...\n\nSelected Files: ${output}M\nAvailable Space: 1.44M\n", "0 0", "5"); return 0; } } return 1; } ## End sub save_config() ##------------------------------------------------------------------------------------## ##------------------------------------------------------------------------------------## ## Sub cp_config(). ## Copies files from tmp configuration location to other mounted media or image. sub cp_config { my $mnt_point = "$_[0]"; ## Backup/copy sentry.conf file. Copy files to floppy. &infobox("Copying files to ${mnt_point}.", "0 0", "1"); $status = 0; if (-f "${mnt_point}/sentry.conf") { system("cp -p ${mnt_point}/sentry.conf ${mnt_point}/sentry.conf.bak 1>/dev/null 2>/dev/null"); } system("cp -p /tmp/floppy.${rand_var}/sentry.conf ${mnt_point}/ 1>/dev/null 2>/dev/null"); if ($? > 0) { $status = &cp_error("/tmp/floppy.${rand_var}/sentry.conf", "${mnt_point}/sentry.conf", "$?", "$!"); return 0 if ($status != 1); } mkdir("${mnt_point}/config", 0755); if (opendir(DH, "/tmp/floppy.${rand_var}/config")) { while (defined($filename = readdir(DH))) { next if ($filename =~ /^\.\.?$/); system("cp -p /tmp/floppy.${rand_var}/config/${filename} ${mnt_point}/config/${filename} 1>/dev/null 2>/dev/null"); if ($? > 0) { $status = &cp_error("/tmp/floppy.${rand_var}/config/${filename}", "${mnt_point}/config/${filename}", "$?", "$!"); return 0 if ($status != 1); } if (($filename eq 'shadow') || ($filename =~ /^ssh_host(_rsa|_dsa)?_key$/)) { chmod(0600, "${mnt_point}/config/${filename}"); } } closedir(DH); } else { system("dialog --title \"$title\" --menu \"Unable to open directory: \"/tmp/floppy.${rand_var}/config\", exiting.\\n\\n\" 0 0 0 \"OK\" 2>${output_file}"); return 0; } system('sync'); return 1; } ## End cp_config(). ##------------------------------------------------------------------------------------## ##------------------------------------------------------------------------------------## ## Sub cp_error(). ## Warns user if an error occurs during a file copy operation. sub cp_error { my ($src, $dst, $err_num, $err_msg) = @_; system("dialog --aspect 80 --title \"$title\" --menu \"ERROR: An error occurred while copying \"$src\" to \"$dst\":\\n\\n$err_num, $err_msg\\n\\n\" 0 0 0 \"Continue\" \"Cancel\" 2>${output_file}"); &get_output; (return 0) if ($output eq 'Cancel'); return 1; } ## End sub cp_error(). ##------------------------------------------------------------------------------------## ##------------------------------------------------------------------------------------## ## sub update_config() ## Locates/parses current configuration and updates files on floppy. sub update_config { ## TODO: # Add USB thumbdrive functionality. # Add another arg to tell this script where to mount the device... my @config = (); my $mode = "$_[0]"; ## Floppy/USB. my $ext_args = "$_[1]"; ($mode = '/floppy') if ($mode eq 'floppy'); ($mode = '/mnt') if ($mode eq 'usb'); if (-f "${mode}/sentry.conf") { if (open(FH,"<${mode}/sentry.conf")) { flock(FH,1); @config = ; close(FH); } else { ## FIXME: Error. } } else { print "ERROR: Unable to locate sentry.conf file.\n"; return 0; } my ($src,$dst,$var,$value) = ''; my %prefs = (); foreach (@conf) { next if ("$_" eq ''); next if ($_ =~ /=>/); chomp($_); $_ =~ s/#.*//; $_ =~ s/\"+//g; $_ =~ s/\'+//g; $_ =~ s/\`+//g; $_ =~ s/\*+//g; $_ =~ s/[\s\t]+//g; if ($_ =~ /\|=/) { ($src,$dst) = split(/\|=/, $_, 2); if (($src ne '') && ($dst ne '')) { $_ = "$dst" . '=' . "$src"; } else { next; } } ## Throw the rest into %prefs(). elsif ($_ =~ /=/) { ($var,$value) = split(/=/, $_, 2); next if (($value =~ /^[hH]{1}[tT]{2}[pP]{1}[sS]?:\/\//) || ($value =~ /^[sS]?[fF]{1}[tT]{1}[pP]{1}:\/\//) || ($value =~ /^[sS]{1}[cC]{1}[pP]{1}:\/\//)); next if ($var =~ /^device\d$/); next if ($var =~ /^(http|ftp)_proxy$/); next if ($var =~ /^proxy\-(user|passwd)$/); next if ($var eq 'start_webmin'); if (($var ne '') && ($value ne '')) { $prefs{$var} = "$value"; } } } ## End foreach loop foreach (@etc_vars) { if (exists($prefs{"$_"})) { next if (!(-f "$prefs${_}")); if (exists($specdir{"$_"})) { if (`diff -b --brief $prefs${_} $specdir{$_}/${_} 2>/dev/null`) { ## Files differ. if (-w "$prefs{$_}") { if ($ext_args ne 'nobackup') { system("cp -p $prefs{$_} ${prefs{$_}}.bak 1>/dev/null 2>/dev/null"); } system("cp -p $specdir{$_}/${_} $prefs{$_}"); } else { ## FIXME: error } } } else { if (`diff -b --brief $prefs${_} /etc/${_} 2>/dev/null`) { ## Files differ. if (-w "$prefs{$_}") { if ($ext_args ne 'nobackup') { system("cp -p $prefs{$_} ${prefs{$_}}.bak 1>/dev/null 2>/dev/null"); } system("cp -p /etc/${_} $prefs{$_}"); } else { ## FIXME: error } } } } } foreach (@ssh_vars) { if (exists($prefs{"$_"})) { if (`diff -b --brief $prefs${_} /etc/ssh/${_} 2>/dev/null`) { ## Files differ. if (-w "$prefs{$_}") { if ($ext_args ne 'nobackup') { system("cp -p $prefs{$_} ${prefs{$_}}.bak 1>/dev/null 2>/dev/null"); } system("cp -p /etc/ssh/${_} $prefs{$_}"); } else { ## FIXME: Error. } } } } foreach (keys %prefs) { if ((-f "$_") && (-f "$prefs{$_}")) { if (`diff -b --brief $prefs{$_} $_ 2>/dev/null`) { ## Files differ. if (-w "$prefs{$_}") { if ($ext_args ne 'nobackup') { system("cp -p $prefs{$_} ${prefs{$_}}.bak 1>/dev/null 2>/dev/null"); } system("cp -p $_ $prefs{$_} 1>/dev/null 2>/dev/null"); } else { ## FIXME: Error. } } } } %prefs = (); @conf = (); system ("touch ${mode}/sentry.conf 1>/dev/null 2>/dev/null"); return 1; } ## End sub update_config() ##------------------------------------------------------------------------------------## ## Avoid Errors. @etc_vars = @etc_vars; @ssh_vars = @ssh_vars; return 1; ## _EOF_ ##