Much progress on object generation

git-svn-id: https://shorewall.svn.sourceforge.net/svnroot/shorewall/trunk@5502 fbd18981-670d-0410-9b5c-8dc0c1a9a2bb
This commit is contained in:
teastep 2007-03-12 01:04:21 +00:00
parent d2db1d04a9
commit 892244d316
3 changed files with 265 additions and 74 deletions

View File

@ -107,7 +107,7 @@ my %config = ( STARTUP_ENABLED => undef,
#
# Config options and global settings that are to be copied to object
#
my @propagateconfig = qw/ CLEAR_TC DISABLE_IPV6 ADMINISABSENTMINDED IP_FORWARDING MODULESDIR MODULE_SUFFIX LOGFORMAT /;
my @propagateconfig = qw/ CLEAR_TC DISABLE_IPV6 ADMINISABSENTMINDED IP_FORWARDING MODULESDIR MODULE_SUFFIX LOGFORMAT SUBSYSLOCK/;
my @propagateenv = qw/ LOGLIMIT LOGTAGONLY LOGRULENUMBERS /;
#
# From parsing the capabilities file
@ -142,13 +142,40 @@ my %capabilities =
ADDRTYPE => undef,
);
my %capdesc = ( NAT_ENABLED => 'NAT',
MANGLE_ENABLED => 'Packet Mangling',
MULTIPORT => 'Multi-port Match' ,
XMULTIPORT => 'Extended Multi-port Match',
CONNTRACK_MATCH => 'Connection Tracking Match',
USEPKTTYPE => 'Packet Type Match',
POLICY_MATCH => 'Policy Match',
PHYSDEV_MATCH => 'Physdev Match',
LENGTH_MATCH => 'Packet length Match',
IPRANGE_MATCH => 'IP Range Match',
RECENT_MATCH => 'Recent Match',
OWNER_MATCH => 'Owner Match',
IPSET_MATCH => 'Ipset Match',
CONNMARK => 'CONNMARK Target',
XCONNMARK => 'Extended CONNMARK Target',
CONNMARK_MATCH => 'Connmark Match',
XCONNMARK_MATCH => 'Extended Connmark Match',
RAW_TABLE => 'Raw Table',
IPP2P_MATCH => 'IPP2P Match',
CLASSIFY_TARGET => 'CLASSIFY Target',
ENHANCED_REJECT => 'Extended Reject',
KLUDGEFREE => 'Repeat match',
MARK => 'MARK Target',
XMARK => 'Extended Mark Target',
MANGLE_FORWARD => 'Mangle FORWARD Chain',
COMMENTS => 'Comments',
ADDRTYPE => 'Address Type Match',
);
my ( $command, $doing, $done ) = qw/ compile Compiling Compiled/; #describe the current command, it's present progressive, and it's completion.
my $line; # Current config file line
my $object; # Object file Handle Reference
my $tempfile; # Temporary object file name
my $line = ''; # Current config file line
my $object = 0; # Object file Handle Reference
my $tempfile = ''; # Temporary object file name
#
@ -385,7 +412,7 @@ sub fatal_error
print STDERR " ERROR: @_\n";
close $object, if $object;
system "rm -rf $ENV{TMP_DIR}" if $ENV{TMP_DIR};
exit 2;
die;
}
sub progress_message {
@ -450,7 +477,7 @@ sub emit ( $ ) {
#
sub emit_unindented( $ ) {
print $object $_[0];
print $object "$_[0]\n";
}
#
@ -5400,10 +5427,6 @@ sub do_initialize() {
$env{MAXZONENAMELENGTH} = 5;
}
fatal_error "Shorewall $env{VERSION} requires Conntrack Match Support" unless $capabilities{CONNTRACK_MATCH};
fatal_error "Shorewall $env{VERSION} requires Extended Multi-port Match Support" unless $capabilities{XMULTIPORT};
fatal_error "Shorewall $env{VERSION} requires Address Type Match Support" unless $capabilities{ADDRTYPE};
if ( $ENV{DEBUG} ) {
print "\n";
print "Configuration:\n";
@ -5427,6 +5450,205 @@ sub do_initialize() {
initialize_chain_table;
}
sub setup_forwarding() {
if ( "\L$config{IP_FORWARDING}" eq 'on' ) {
emit 'echo 1 > /proc/sys/net/ipv4/ip_forward';
emit 'progress_message2 IP Forwarding Enabled';
} elsif ( "\L$config{IP_FORWARDING}" eq 'off' ) {
emit 'echo 0 > /proc/sys/net/ipv4/ip_forward';
emit 'progress_message2 IP Forwarding Disabled!';
}
}
sub generate_object () {
copy find_file 'prog.header';
my $date = localtime;
emit "#\n# Compiled firewall script generated by Shorewall $ENV{VERSION} - $date\n#";
if ( $ENV{EXPORT} ) {
emit 'SHAREDIR=/usr/share/shorewall-lite';
emit 'CONFDIR=/etc/shorewall-lite';
emit 'VARDIR=/var/lib/shorewall-lite';
emit 'PRODUCT="Shorewall Lite"';
copy "$env{SHAREDIR}/lib.base";
emit '################################################################################';
emit '# End of /usr/share/shorewall/lib.base';
emit '################################################################################';
} else {
emit 'SHAREDIR=/usr/share/shorewall';
emit 'CONFDIR=/etc/shorewall';
emit 'VARDIR=/var/lib/shorewall\n';
emit 'PRODUCT=\'Shorewall\'';
emit '. /usr/share/shoreall-lite/lib.base';
}
emit '';
for my $exit qw/init start started stop stopped/ {
emit "run_${exit}_exit() {";
$indent = ' ';
append_file $exit;
$indent = '';
emit "}\n";
}
emit 'initialize()';
emit '{';
$indent = ' ';
if ( $ENV{EXPORT} ) {
emit '#';
emit '# These variables are required by the library functions called in this script';
emit '#';
emit 'CONFIG_PATH="/etc/shorewall-lite:/usr/share/shorewall-lite"';
} else {
emit 'if [ ! -f ${SHAREDIR}/version ]; then';
emit ' fatal_error "This script requires Shorewall which do not appear to be installed on this system (did you forget \"-e\" when you compiled?)"';
emit 'fi';
emit '';
emit 'local version=\$(cat \${SHAREDIR}/version)';
emit '';
emit 'if [ ${SHOREWALL_LIBVERSION:-0} -lt 30203 ]; then';
emit ' fatal_error "This script requires Shorewall version 3.3.3 or later; current version is $version"';
emit 'fi';
emit '#';
emit '# These variables are required by the library functions called in this script';
emit '#';
emit "CONFIG_PATH=\"$config{CONFIG_PATH}\"";
}
for my $option ( @propagateconfig ) {
my $value = $config{$option} || '';
emit "${option}=\"${value}\"";
}
for my $option ( @propagateenv ) {
my $value = $env{$option} || '';
emit "${option}=\"${value}\"";
}
emit '[ -n "${COMMAND:=restart}" ]';
emit '[ -n "${VERBOSE:=0}" ]';
emit '[ -n "${RESTOREFILE:=$RESTOREFILE}" ]';
emit '[ -n "$LOGFORMAT" ] || LOGFORMAT="Shorewall:%s:%s:"';
emit "VERSION=\"$ENV{VERSION}\"";
emit "PATH=\"$config{PATH}\"";
emit 'TERMINATOR=fatal_error';
if ( $config{IPTABLES} ) {
emit "IPTABLES=\"$config{IPTABLES}\"\n";
emit "[ -x \"$config{IPTABLES}\" ] || startup_error \"IPTABLES=$config{IPTABLES} does not exist or is not executable\"";
} else {
emit '[ -z "$IPTABLES" ] && IPTABLES=$(mywhich iptables 2> /dev/null)';
emit '';
emit '[ -n "$IPTABLES" -a -x "$IPTABLES" ] || startup_error "Can\'t find iptables executable"';
}
emit '';
emit "STOPPING=";
emit "COMMENT=\n"; # Fixme -- eventually this goes but it's ok now to maintain compability with lib.base
emit '#';
emit '# The library requires that ${VARDIR} exist';
emit '#';
emit '[ -d ${VARDIR} ] || mkdir -p ${VARDIR}';
$indent = '';
emit "}\n";
copy find_file 'prog.functions';
progress_message2 "Creating iptables-restore input..."; create_iptables_restore_file;
emit '#';
emit '# Start/Restart/Reload the firewall';
emit '#';
emit 'define_firewall() {';
$indent = ' ';
emit 'local restore_file=$1';
save_progress_message 'Initializing...';
if ( $ENV{EXPORT} ) {
my $mf = find_file 'modules';
if ( $mf ne "$env{SHAREDIR}/module" && -f $mf ) {
emit 'echo MODULESDIR="$MODULESDIR" > ${VARDIR}/.modulesdir';
emit 'cat > ${VARDIR}/.modules << EOF';
open MF, $mf or fatal_error "Unable to open $mf: $!";
while ( $line = <MF> ) { print $object $line if $line =~ /^\s*loadmodule\b/; }
close MF;
emit_unindented "EOF\n";
emit 'reload_kernel_modules < ${VARDIR}/.modules';
} else {
emit 'load_kernel_modules Yes';
}
} else {
emit 'load_kernel_modules Yes';
}
emit '';
for my $interface ( @{find_interfaces_by_option 'norfc1918'} ) {
emit "addr=\$(ip -f inet addr show $interface 2> /dev/null | grep 'inet\ ' | head -n1)";
emit 'if [ -n "$addr" ]; then';
emit " addr=\$(echo \$addr | sed 's/inet //;s/\/.*//;s/ peer.*//')";
emit ' for network in 10.0.0.0/8 176.16.0.0/12 192.168.0.0/16; do';
emit ' if in_network $addr $network; then';
emit " startup_error \"The 'norfc1918' option has been specified on an interface with an RFC 1918 address. Interface:$interface\"";
emit ' fi';
emit ' done';
emit 'fi';
}
emit "run_init_exit\n";
emit "delete_proxyarp\n";
emit '[ -n "$CLEAR_TC" ] && delete_tc1';
emit '';
emit '[ -n "$DISABLE_IPV6" ] && disable_ipv6';
emit '';
emit "undo_routing\n";
emit "restore_default_route\n";
emit "f=\$(find_file ipsets)\n";
emit 'if [ -f $f ]; then';
emit ' progress_message2 "Restoring IPSETS...';
emit ' ipset -U :all: :all:';
emit ' ipset -F';
emit ' ipset -X';
emit ' ipset -R < $f';
emit "fi\n";
emit "disable_ipv6\n" if $config{DISABLE_IPV6};
setup_forwarding;
$indent = '';
emit '}';
copy find_file 'prog.footer';
}
sub report_capability( $ ) {
my $cap = $_[0];
print " $capdesc{$cap}: ";
print $capabilities{$cap} ? "Available\n" : "Not Available\n";
}
sub compile_firewall( $ ) {
my $objectfile = $_[0];
@ -5442,71 +5664,28 @@ sub compile_firewall( $ ) {
fatal_error "$objectfile is a Directory" if -d $objectfile;
fatal_error "$dir is a Symbolic Link" if -l $objectfile;
fatal_error "$objectfile exists and is not a compiled script" if -e _ && ! -x _;
( $object, $tempfile ) = tempfile ( 'tempfileXXXX' , DIR => $dir );
$file = "$file.$suffix" if $suffix;
};
fatal_error "$@" if $@;
copy find_file 'prog.header';
my $date = localtime;
emit "#\n# Compiled firewall script generated by Shorewall $env{VERSION} - $date\n#";
if ( $ENV{EXPORT} ) {
emit 'SHAREDIR=/usr/share/shorewall-lite';
emit 'CONFDIR=/etc/shorewall-lite';
emit 'VARDIR=/var/lib/shorewall-lite';
emit 'PRODUCT="Shorewall Lite"';
copy "$env{SHAREDIR}/lib.base";
emit '################################################################################';
emit '# End of /usr/share/shorewall/lib.base';
emit '################################################################################';
} else {
emit 'SHAREDIR=/usr/share/shorewall';
emit 'CONFDIR=/etc/shorewall';
emit 'VARDIR=/var/lib/shorewall\n';
emit 'PRODUCT=\'Shorewall\'';
emit '. /usr/share/shoreall-lite/lib.base';
}
emit '';
for my $exit qw/init initdone start started stop stopped/ {
emit "run_${exit}_exit() {";
$indent = ' ';
append_file $exit;
$indent = '';
emit "}\n";
}
emit 'initialize()';
emit '{';
$indent = ' ';
for my $option ( @propagateconfig ) {
my $value = $config{$option} || '';
emit "${option}=\"${value}\"";
}
for my $option ( @propagateenv ) {
my $value = $env{$option} || '';
emit "${option}=\"${value}\"";
}
emit '}';
$indent = '';
copy find_file 'prog.functions';
}
if ( $ENV{VERBOSE} > 1 ) {
print "Shorewall has detected the following capabilities:\n";
for my $cap ( sort { $capdesc{$a} cmp $capdesc{$b} } keys %capabilities ) {
report_capability $cap;
}
}
fatal_error "Shorewall $ENV{VERSION} requires Conntrack Match Support" unless $capabilities{CONNTRACK_MATCH};
fatal_error "Shorewall $ENV{VERSION} requires Extended Multi-port Match Support" unless $capabilities{XMULTIPORT};
fatal_error "Shorewall $ENV{VERSION} requires Address Type Match Support" unless $capabilities{ADDRTYPE};
fatal_error 'BRIDGING=Yes requires Physdev Match support in your Kernel and iptables' if $config{BRIDGING} && ! $capabilities{PHYSDEV_MATCH};
fatal_error 'MACLIST_TTL requires the Recent Match capability which is not present in your Kernel and/or iptables' if $config{MACLIST_TTL} && ! $capabilities{RECENT_MATCH};
fatal_error 'RFC1918_STRICT=Yes requires Connection Tracking match' if $config{RFC1918_STRICT} && ! $capabilities{CONNTRACK_MATCH};
#
# Process the zones file.
#
@ -5522,7 +5701,7 @@ sub compile_firewall( $ ) {
if ( $ENV{DEBUG} ) {
dump_zone_info;
} else {
} elsif ( $ENV{VERBOSE} > 1 ) {
progress_message "Determining Hosts in Zones..."; zone_report;
}
#
@ -5586,8 +5765,14 @@ sub compile_firewall( $ ) {
# Create the script.
#
unless ( $command eq 'check' ) {
progress_message2 "Creating iptables-restore input..."; create_iptables_restore_file;
copy find_file 'prog.footer';
eval {
( $object, $tempfile ) = tempfile ( 'tempfileXXXX' , DIR => $dir );
};
fatal_error "$@" if $@;
generate_object;
$file = "$dir/$file";
rename $tempfile, $file;
chmod 0700, $file;

View File

@ -339,6 +339,11 @@ lib_load() # $1 = Name of the Library, $2 = Error Message heading if the library
eval loaded=\$LIB_${1}_LOADED
if [ -z "$loaded" ]; then
if [ -n "$EXPERIMENTAL" ]; then
eval LIB_${1}_LOADED=Yes
return
fi
if [ -f $lib ]; then
progress_message "Loading library $lib..."
. $lib

View File

@ -2181,6 +2181,7 @@ do_initialize() {
report_capabilities1 > $TMP_DIR/capabilities
export TMP_DIR
export CONFIG_PATH
export VERSION
fi
#
# Clear $FW