Bring trunk up to date with 4.0

git-svn-id: https://shorewall.svn.sourceforge.net/svnroot/shorewall/trunk@7228 fbd18981-670d-0410-9b5c-8dc0c1a9a2bb
This commit is contained in:
teastep 2007-08-26 15:12:04 +00:00
parent e110c3de6e
commit 5f6596a728
15 changed files with 302 additions and 216 deletions

View File

@ -198,29 +198,16 @@ sub setup_accounting() {
if ( $filter_table->{accounting} ) { if ( $filter_table->{accounting} ) {
for my $chain ( qw/INPUT FORWARD/ ) { for my $chain ( qw/INPUT FORWARD/ ) {
insert_rule $filter_table->{$chain}, 1, '-j accounting'; insert_rule $filter_table->{$chain}, 1, '-j accounting';
insert_rule $filter_table->{$chain}, 2, '-m state --state ESTABLISHED,RELATED -j ACCEPT' if $config{FASTACCEPT};
}
} elsif ( $config{FASTACCEPT} ) {
for my $chain ( qw/INPUT FORWARD/ ) {
insert_rule $filter_table->{$chain}, 1, '-m state --state ESTABLISHED,RELATED -j ACCEPT';
} }
} }
if ( $filter_table->{accountout} ) { if ( $filter_table->{accountout} ) {
insert_rule $filter_table->{OUTPUT}, 1, '-j accountout'; insert_rule $filter_table->{OUTPUT}, 1, '-j accountout';
insert_rule $filter_table->{OUTPUT}, 2, '-m state --state ESTABLISHED,RELATED -j ACCEPT' if $config{FASTACCEPT};
} elsif ( $config{FASTACCEPT} ) {
insert_rule $filter_table->{OUTPUT}, 1, '-m state --state ESTABLISHED,RELATED -j ACCEPT';
} }
} else { } else {
if ( $filter_table->{accounting} ) { if ( $filter_table->{accounting} ) {
for my $chain ( qw/INPUT FORWARD OUTPUT/ ) { for my $chain ( qw/INPUT FORWARD OUTPUT/ ) {
insert_rule $filter_table->{$chain}, 1, '-j accounting'; insert_rule $filter_table->{$chain}, 1, '-j accounting';
insert_rule $filter_table->{$chain}, 2, '-m state --state ESTABLISHED,RELATED -j ACCEPT' if $config{FASTACCEPT};
}
} elsif ( $config{FASTACCEPT} ) {
for my $chain ( qw/INPUT FORWARD OUTPUT/ ) {
insert_rule $filter_table->{$chain}, 1, '-m state --state ESTABLISHED,RELATED -j ACCEPT';
} }
} }
} }

View File

@ -54,7 +54,7 @@ our @EXPORT = qw( merge_levels
%macros %macros
); );
our @EXPORT_OK = qw( initialize ); our @EXPORT_OK = qw( initialize );
our $VERSION = 4.01; our $VERSION = 4.03;
# #
# Used Actions. Each action that is actually used has an entry with value 1. # Used Actions. Each action that is actually used has an entry with value 1.
@ -389,12 +389,14 @@ sub process_macro1 ( $$ ) {
$mtarget =~ s/:.*$//; $mtarget =~ s/:.*$//;
$mtarget = (split '/' , $mtarget)[0];
my $targettype = $targets{$mtarget}; my $targettype = $targets{$mtarget};
$targettype = 0 unless defined $targettype; $targettype = 0 unless defined $targettype;
fatal_error "Invalid target ($mtarget)" fatal_error "Invalid target ($mtarget)"
unless ( $targettype == STANDARD ) || ( $mtarget eq 'PARAM' ) || ( $mtarget eq 'LOG' ); unless ( $targettype == STANDARD ) || ( $mtarget eq 'PARAM' ) || ( $targettype & ( LOGRULE | NFQ ) );
} }
progress_message " ..End Macro $macrofile"; progress_message " ..End Macro $macrofile";
@ -412,7 +414,7 @@ sub process_action1 ( $$ ) {
my $targettype = $targets{$target}; my $targettype = $targets{$target};
if ( defined $targettype ) { if ( defined $targettype ) {
return if ( $targettype == STANDARD ) || ( $targettype == MACRO ) || ( $targettype & LOGRULE ); return if ( $targettype == STANDARD ) || ( $targettype == MACRO ) || ( $targettype & ( LOGRULE | NFQ ) );
fatal_error "Invalid TARGET ($target)" if $targettype & STANDARD; fatal_error "Invalid TARGET ($target)" if $targettype & STANDARD;
@ -424,6 +426,8 @@ sub process_action1 ( $$ ) {
} else { } else {
( $target, my $param ) = split '/', $target; ( $target, my $param ) = split '/', $target;
return if $target eq 'NFQUEUE';
if ( defined $param ) { if ( defined $param ) {
my $paramtype = $targets{$param} || 0; my $paramtype = $targets{$param} || 0;
@ -462,8 +466,8 @@ sub process_actions1() {
next unless $action; next unless $action;
if ( $targets{$action} ) { if ( $targets{$action} ) {
next if $targets{$action} & ACTION; warning_message "Duplicate Action Name ($action) Ignored" unless $targets{$action} & ACTION;
fatal_error "Invalid Action Name ($action)"; next;
} }
$targets{$action} = ACTION; $targets{$action} = ACTION;
@ -632,7 +636,7 @@ sub process_action3( $$$$$ ) {
if ( $action2type & ACTION ) { if ( $action2type & ACTION ) {
$target2 = (find_logactionchain ( $target = $target2 ))->{name}; $target2 = (find_logactionchain ( $target = $target2 ))->{name};
} else { } else {
die "Internal Error" unless $action2type == MACRO || $action2type & LOGRULE; fatal_error "Internal Error" unless $action2type == MACRO || $action2type & ( LOGRULE | NFQ );
} }
} }
@ -666,10 +670,10 @@ sub process_actions3 () {
add_rule $chainref, '-m addrtype --dst-type BROADCAST -j DROP'; add_rule $chainref, '-m addrtype --dst-type BROADCAST -j DROP';
} else { } else {
add_command $chainref, 'for address in $ALL_BCASTS; do'; add_command $chainref, 'for address in $ALL_BCASTS; do';
push_cmd_mode $chainref; incr_cmd_level $chainref;
log_rule_limit $level, $chainref, 'dropBcast' , 'DROP', '', $tag, 'add', ' -d $address ' if $level ne ''; log_rule_limit $level, $chainref, 'dropBcast' , 'DROP', '', $tag, 'add', ' -d $address ' if $level ne '';
add_rule $chainref, '-d $address -j DROP'; add_rule $chainref, '-d $address -j DROP';
pop_cmd_mode $chainref; decr_cmd_level $chainref;
add_command $chainref, 'done'; add_command $chainref, 'done';
log_rule_limit $level, $chainref, 'dropBcast' , 'DROP', '', $tag, 'add', ' -d 224.0.0.0/4 ' if $level ne ''; log_rule_limit $level, $chainref, 'dropBcast' , 'DROP', '', $tag, 'add', ' -d 224.0.0.0/4 ' if $level ne '';
@ -690,10 +694,10 @@ sub process_actions3 () {
add_rule $chainref, '-m addrtype --dst-type BROADCAST -j ACCEPT'; add_rule $chainref, '-m addrtype --dst-type BROADCAST -j ACCEPT';
} else { } else {
add_command $chainref, 'for address in $ALL_BCASTS; do'; add_command $chainref, 'for address in $ALL_BCASTS; do';
push_cmd_mode $chainref; incr_cmd_level $chainref;
log_rule_limit $level, $chainref, 'allowBcast' , 'ACCEPT', '', $tag, 'add', ' -d $address ' if $level ne ''; log_rule_limit $level, $chainref, 'allowBcast' , 'ACCEPT', '', $tag, 'add', ' -d $address ' if $level ne '';
add_rule $chainref, '-d $address -j ACCEPT'; add_rule $chainref, '-d $address -j ACCEPT';
pop_cmd_mode $chainref; decr_cmd_level $chainref;
add_command $chainref, 'done'; add_command $chainref, 'done';
log_rule_limit $level, $chainref, 'allowBcast' , 'ACCEPT', '', $tag, 'add', ' -d 224.0.0.0/4 ' if $level ne ''; log_rule_limit $level, $chainref, 'allowBcast' , 'ACCEPT', '', $tag, 'add', ' -d 224.0.0.0/4 ' if $level ne '';

View File

@ -44,6 +44,7 @@ our @EXPORT = qw( STANDARD
ACTION ACTION
MACRO MACRO
LOGRULE LOGRULE
NFQ
NO_RESTRICT NO_RESTRICT
PREROUTE_RESTRICT PREROUTE_RESTRICT
INPUT_RESTRICT INPUT_RESTRICT
@ -52,14 +53,15 @@ our @EXPORT = qw( STANDARD
ALL_RESTRICT ALL_RESTRICT
process_comment process_comment
push_cmd_mode incr_cmd_level
pop_cmd_mode decr_cmd_level
add_command add_command
add_commands add_commands
mark_referenced mark_referenced
add_file add_file
add_rule add_rule
insert_rule insert_rule
insert_rule_nice
chain_base chain_base
forward_chain forward_chain
input_chain input_chain
@ -89,7 +91,6 @@ our @EXPORT = qw( STANDARD
clearrule clearrule
do_proto do_proto
mac_match mac_match
numeric_value
verify_mark verify_mark
verify_small_mark verify_small_mark
validate_mark validate_mark
@ -128,7 +129,7 @@ our @EXPORT = qw( STANDARD
%targets %targets
); );
our @EXPORT_OK = qw( initialize ); our @EXPORT_OK = qw( initialize );
our $VERSION = 4.02; our $VERSION = 4.03;
# #
# Chain Table # Chain Table
@ -138,16 +139,17 @@ our $VERSION = 4.02;
# %chain_table { <table> => { <chain1> => { name => <chain name> # %chain_table { <table> => { <chain1> => { name => <chain name>
# table => <table name> # table => <table name>
# is_policy => 0|1 # is_policy => 0|1
# is_optionsl => 0|1 # is_optional => 0|1
# referenced => 0|1 # referenced => 0|1
# log => <logging rule number for use when LOGRULENUMBERS> # log => <logging rule number for use when LOGRULENUMBERS>
# policy => <policy> # policy => <policy>
# policychain => <name of policy chain> -- self-reference if this is a policy chain
# policypair => [ <policy source>, <policy dest> ] -- Used for reporting duplicated policies
# loglevel => <level> # loglevel => <level>
# synparams => <burst/limit> # synparams => <burst/limit>
# synchain => <name of synparam chain> # synchain => <name of synparam chain>
# default => <default action> # default => <default action>
# policy_chain => <ref to policy chain -- self-reference if this is a policy chain> # cmdlevel => <number of open loops or blocks in runtime commands>
# cmdmode => <number of open loops or blocks in runtime commands>
# rules => [ <rule1> # rules => [ <rule1>
# <rule2> # <rule2>
# ... # ...
@ -188,6 +190,7 @@ use constant { STANDARD => 1, #defined by Netfilter
ACTION => 64, #An action (may be built-in) ACTION => 64, #An action (may be built-in)
MACRO => 128, #A Macro MACRO => 128, #A Macro
LOGRULE => 256, #'LOG' LOGRULE => 256, #'LOG'
NFQ => 512, #'NFQUEUE'
}; };
our %targets; our %targets;
@ -276,6 +279,8 @@ sub initialize() {
'CONTINUE!' => STANDARD, 'CONTINUE!' => STANDARD,
'QUEUE' => STANDARD, 'QUEUE' => STANDARD,
'QUEUE!' => STANDARD, 'QUEUE!' => STANDARD,
'NFQUEUE' => STANDARD + NFQ,
'NFQUEUE!' => STANDARD + NFQ,
'SAME' => NATRULE, 'SAME' => NATRULE,
'SAME-' => NATRULE + NATONLY, 'SAME-' => NATRULE + NATONLY,
'dropBcast' => BUILTIN + ACTION, 'dropBcast' => BUILTIN + ACTION,
@ -331,21 +336,21 @@ sub process_comment() {
} }
} }
# #
# Functions to manipulate cmdmode # Functions to manipulate cmdlevel
# #
sub push_cmd_mode( $ ) { sub incr_cmd_level( $ ) {
$_[0]->{cmdmode}++; $_[0]->{cmdlevel}++;
} }
sub pop_cmd_mode( $ ) { sub decr_cmd_level( $ ) {
fatal_error "Internal error in pop_cmd_mode()" if --$_[0]->{cmdmode} < 0; fatal_error "Internal error in decr_cmd_level()" if --$_[0]->{cmdlevel} < 0;
} }
sub add_command($$) sub add_command($$)
{ {
my ($chainref, $command) = @_; my ($chainref, $command) = @_;
push @{$chainref->{rules}}, join ('', ' ' x $chainref->{cmdmode} , $command ); push @{$chainref->{rules}}, join ('', ' ' x $chainref->{cmdlevel} , $command );
$chainref->{referenced} = 1; $chainref->{referenced} = 1;
} }
@ -354,7 +359,7 @@ sub add_commands {
my $chainref = shift @_; my $chainref = shift @_;
for my $command ( @_ ) { for my $command ( @_ ) {
push @{$chainref->{rules}}, join ('', ' ' x $chainref->{cmdmode} , $command ); push @{$chainref->{rules}}, join ('', ' ' x $chainref->{cmdlevel} , $command );
} }
$chainref->{referenced} = 1; $chainref->{referenced} = 1;
@ -403,7 +408,7 @@ sub add_rule($$)
$rule .= qq( -m comment --comment "$comment") if $comment; $rule .= qq( -m comment --comment "$comment") if $comment;
if ( $chainref->{cmdmode} ) { if ( $chainref->{cmdlevel} ) {
$rule =~ s/"/\\"/g; #Must preserve quotes in the rule $rule =~ s/"/\\"/g; #Must preserve quotes in the rule
add_command $chainref , qq(echo "-A $chainref->{name} $rule" >&3); add_command $chainref , qq(echo "-A $chainref->{name} $rule" >&3);
} else { } else {
@ -421,7 +426,7 @@ sub insert_rule($$$)
{ {
my ($chainref, $number, $rule) = @_; my ($chainref, $number, $rule) = @_;
fatal_error 'Internal Error in insert_rule()' if $chainref->{cmdmode}; fatal_error 'Internal Error in insert_rule()' if $chainref->{cmdlevel};
$rule .= "-m comment --comment \"$comment\"" if $comment; $rule .= "-m comment --comment \"$comment\"" if $comment;
@ -445,12 +450,16 @@ sub chain_base($) {
$chain; $chain;
} }
sub chain_base_cond($) {
$config{DYNAMIC_ZONES} ? chain_base($_[0]) : $_[0];
}
# #
# Forward Chain for an interface # Forward Chain for an interface
# #
sub forward_chain($) sub forward_chain($)
{ {
$_[0] . '_fwd'; chain_base_cond($_[0]) . '_fwd';
} }
# #
@ -458,7 +467,7 @@ sub forward_chain($)
# #
sub input_chain($) sub input_chain($)
{ {
$_[0] . '_in'; chain_base_cond($_[0]) . '_in';
} }
# #
@ -466,7 +475,7 @@ sub input_chain($)
# #
sub output_chain($) sub output_chain($)
{ {
$_[0] . '_out'; chain_base_cond($_[0]) . '_out';
} }
# #
@ -474,7 +483,7 @@ sub output_chain($)
# #
sub masq_chain($) sub masq_chain($)
{ {
$_[0] . '_masq'; chain_base_cond($_[0]) . '_masq';
} }
# #
@ -489,12 +498,12 @@ sub syn_flood_chain ( $ ) {
# #
sub mac_chain( $ ) sub mac_chain( $ )
{ {
$_[0] . '_mac'; chain_base_cond($_[0]) . '_mac';
} }
sub macrecent_target($) sub macrecent_target($)
{ {
$config{MACLIST_TTL} ? $_[0] . '_rec' : 'RETURN'; $config{MACLIST_TTL} ? chain_base_cond($_[0]) . '_rec' : 'RETURN';
} }
# #
@ -502,22 +511,22 @@ sub macrecent_target($)
# #
sub dynamic_fwd( $ ) sub dynamic_fwd( $ )
{ {
$_[0] . '_dynf'; chain_base_cond($_[0]) . '_dynf';
} }
sub dynamic_in( $ ) sub dynamic_in( $ )
{ {
$_[0] . '_dyni'; chain_base_cond($_[0]) . '_dyni';
} }
sub dynamic_out( $ ) # $1 = interface sub dynamic_out( $ ) # $1 = interface
{ {
$_[0] . '_dyno'; chain_base_cond($_[0]) . '_dyno';
} }
sub dynamic_chains( $ ) #$1 = interface sub dynamic_chains( $ ) #$1 = interface
{ {
my $c = $_[0]; my $c = chain_base_cond($_[0]);
[ $c . '_dyni' , $c . '_dynf' , $c . '_dyno' ]; [ $c . '_dyni' , $c . '_dynf' , $c . '_dyno' ];
} }
@ -527,7 +536,7 @@ sub dynamic_chains( $ ) #$1 = interface
# #
sub dnat_chain( $ ) sub dnat_chain( $ )
{ {
$_[0] . '_dnat'; chain_base_cond($_[0]) . '_dnat';
} }
# #
@ -535,7 +544,7 @@ sub dnat_chain( $ )
# #
sub snat_chain( $ ) sub snat_chain( $ )
{ {
$_[0] . '_snat'; chain_base_cond($_[0]) . '_snat';
} }
# #
@ -543,7 +552,7 @@ sub snat_chain( $ )
# #
sub ecn_chain( $ ) sub ecn_chain( $ )
{ {
$_[0] . '_ecn'; chain_base_cond($_[0]) . '_ecn';
} }
# #
@ -551,7 +560,7 @@ sub ecn_chain( $ )
# #
sub first_chains( $ ) #$1 = interface sub first_chains( $ ) #$1 = interface
{ {
my $c = $_[0]; my $c = chain_base_cond($_[0]);
[ $c . '_fwd', $c . '_in' ]; [ $c . '_fwd', $c . '_in' ];
} }
@ -563,12 +572,14 @@ sub new_chain($$)
{ {
my ($table, $chain) = @_; my ($table, $chain) = @_;
warning_message "Internal error in new_chain()" if $chain_table{$table}{$chain};
$chain_table{$table}{$chain} = { name => $chain, $chain_table{$table}{$chain} = { name => $chain,
rules => [], rules => [],
table => $table, table => $table,
loglevel => '', loglevel => '',
log => 1, log => 1,
cmdmode => 0 }; cmdlevel => 0 };
} }
# #
@ -668,7 +679,7 @@ sub initialize_chain_table()
new_builtin_chain 'nat', $chain, 'ACCEPT'; new_builtin_chain 'nat', $chain, 'ACCEPT';
} }
for my $chain qw(PREROUTING INPUT FORWARD OUTPUT POSTROUTING) { for my $chain qw(PREROUTING INPUT OUTPUT ) {
new_builtin_chain 'mangle', $chain, 'ACCEPT'; new_builtin_chain 'mangle', $chain, 'ACCEPT';
} }
@ -693,7 +704,7 @@ sub finish_chain_section ($$) {
if ( $chainref->{synparams} ) { if ( $chainref->{synparams} ) {
my $synchainref = ensure_chain 'filter', syn_flood_chain $chainref; my $synchainref = ensure_chain 'filter', syn_flood_chain $chainref;
if ( $section eq 'DONE' ) { if ( $section eq 'DONE' ) {
if ( $chainref->{policy} =~ /^(ACCEPT|CONTINUE|QUEUE)$/ ) { if ( $chainref->{policy} =~ /^(ACCEPT|CONTINUE|QUEUE|NFQUEUE)/ ) {
add_rule $chainref, "-p tcp --syn -j $synchainref->{name}"; add_rule $chainref, "-p tcp --syn -j $synchainref->{name}";
} }
} else { } else {
@ -762,7 +773,7 @@ sub set_mss( $$$ ) {
} }
# #
# Interate over non-firewall zones adding TCPMSS rules as appropriate # Interate over non-firewall zones and interfaces with 'mss=' setting adding TCPMSS rules as appropriate.
# #
sub setup_zone_mss() { sub setup_zone_mss() {
for my $zone ( @zones ) { for my $zone ( @zones ) {
@ -984,15 +995,6 @@ sub mac_match( $ ) {
"--match mac --mac-source ${invert}$mac "; "--match mac --mac-source ${invert}$mac ";
} }
#
# Convert value to decimal number
#
sub numeric_value ( $ ) {
my $mark = $_[0];
fatal_error "Invalid Numeric Value ($mark)" unless "\L$mark" =~ /^(0x[a-f0-9]+|0[0-7]*|[1-9]\d*)$/;
$mark =~ /^0x/ ? hex $mark : $mark =~ /^0/ ? oct $mark : $mark;
}
# #
# Mark validatation functions # Mark validatation functions
# #
@ -1224,8 +1226,10 @@ sub match_orig_dest ( $ ) {
if ( $net =~ /^!/ ) { if ( $net =~ /^!/ ) {
$net =~ s/!//; $net =~ s/!//;
validate_net $net;
"-m conntrack --ctorigdst ! $net "; "-m conntrack --ctorigdst ! $net ";
} else { } else {
validate_net $net;
$net eq ALLIPv4 ? '' : "-m conntrack --ctorigdst $net "; $net eq ALLIPv4 ? '' : "-m conntrack --ctorigdst $net ";
} }
} }
@ -1301,7 +1305,7 @@ sub log_rule_limit( $$$$$$$$ ) {
} }
if ( length $prefix > 29 ) { if ( length $prefix > 29 ) {
$prefix = substr $prefix, 0, 29; $prefix = substr( $prefix, 0, 28 ) . ' ';
warning_message "Log Prefix shortened to \"$prefix\""; warning_message "Log Prefix shortened to \"$prefix\"";
} }
@ -1473,7 +1477,7 @@ sub expand_rule( $$$$$$$$$$ )
my ($iiface, $diface, $inets, $dnets, $iexcl, $dexcl, $onets , $oexcl ); my ($iiface, $diface, $inets, $dnets, $iexcl, $dexcl, $onets , $oexcl );
my $chain = $chainref->{name}; my $chain = $chainref->{name};
my $initialcmdmode = $chainref->{cmdmode}; my $initialcmdlevel = $chainref->{cmdlevel};
# #
# Handle Log Level # Handle Log Level
@ -1531,7 +1535,7 @@ sub expand_rule( $$$$$$$$$$ )
$rule .= '-s $source '; $rule .= '-s $source ';
push_cmd_mode $chainref; incr_cmd_level $chainref;
} else { } else {
fatal_error "Source Interface ($iiface) not allowed when the source zone is $firewall_zone" if $restriction & OUTPUT_RESTRICT; fatal_error "Source Interface ($iiface) not allowed when the source zone is $firewall_zone" if $restriction & OUTPUT_RESTRICT;
$rule .= match_source_dev( $iiface ); $rule .= match_source_dev( $iiface );
@ -1560,7 +1564,7 @@ sub expand_rule( $$$$$$$$$$ )
add_command( $chainref , "for address in $list; do" ); add_command( $chainref , "for address in $list; do" );
$rule .= '-d $address '; $rule .= '-d $address ';
push_cmd_mode $chainref; incr_cmd_level $chainref;
} else { } else {
$rule .= join ( '', '-d ', get_interface_address( $interfaces[0] ), ' ' ); $rule .= join ( '', '-d ', get_interface_address( $interfaces[0] ), ' ' );
} }
@ -1591,7 +1595,7 @@ sub expand_rule( $$$$$$$$$$ )
fatal_error "Bridge port ($diface) not allowed" if port_to_bridge( $diface ); fatal_error "Bridge port ($diface) not allowed" if port_to_bridge( $diface );
add_command( $chainref , 'for dest in ' . get_interface_addresses( $diface) . '; do' ); add_command( $chainref , 'for dest in ' . get_interface_addresses( $diface) . '; do' );
$rule .= '-d $dest '; $rule .= '-d $dest ';
push_cmd_mode $chainref; incr_cmd_level $chainref;
} else { } else {
fatal_error "Bridge Port ($diface) not allowed in OUTPUT or POSTROUTING rules" if ( $restriction & ( POSTROUTE_RESTRICT + OUTPUT_RESTRICT ) ) && port_to_bridge( $diface ); fatal_error "Bridge Port ($diface) not allowed in OUTPUT or POSTROUTING rules" if ( $restriction & ( POSTROUTE_RESTRICT + OUTPUT_RESTRICT ) ) && port_to_bridge( $diface );
fatal_error "Destination Interface ($diface) not allowed when the destination zone is $firewall_zone" if $restriction & INPUT_RESTRICT; fatal_error "Destination Interface ($diface) not allowed when the destination zone is $firewall_zone" if $restriction & INPUT_RESTRICT;
@ -1625,7 +1629,7 @@ sub expand_rule( $$$$$$$$$$ )
add_command( $chainref , "for address in $list; do" ); add_command( $chainref , "for address in $list; do" );
$rule .= '-m conntrack --ctorigdst $address '; $rule .= '-m conntrack --ctorigdst $address ';
push_cmd_mode $chainref; incr_cmd_level $chainref;
} else { } else {
get_interface_address $interfaces[0]; get_interface_address $interfaces[0];
$rule .= join( '', '-m conntrack --ctorigdst $', interface_address ( $interfaces[0] ), ' ' ); $rule .= join( '', '-m conntrack --ctorigdst $', interface_address ( $interfaces[0] ), ' ' );
@ -1649,7 +1653,7 @@ sub expand_rule( $$$$$$$$$$ )
unless ( $onets ) { unless ( $onets ) {
my @oexcl = mysplit $oexcl; my @oexcl = mysplit $oexcl;
if ( @oexcl == 1 ) { if ( @oexcl == 1 ) {
$rule .= "-m conntrack --ctorigdst ! $oexcl "; $rule .= match_orig_dest( "!$oexcl" );
$oexcl = ''; $oexcl = '';
} }
} }
@ -1727,19 +1731,13 @@ sub expand_rule( $$$$$$$$$$ )
for my $inet ( mysplit $inets ) { for my $inet ( mysplit $inets ) {
for my $dnet ( mysplit $dnets ) { for my $dnet ( mysplit $dnets ) {
# #
# We defer evaluating the source net match to accomodate system without $capabilities{KLUDGEFREE} # We evaluate the source net match in the inner loop to accomodate systems without $capabilities{KLUDGEFREE}
# #
add_rule $chainref, join( '', $rule, match_source_net( $inet), match_dest_net( $dnet ), $onet, "-j $echain" ); add_rule $chainref, join( '', $rule, match_source_net( $inet), match_dest_net( $dnet ), $onet, "-j $echain" );
} }
} }
} }
#
# The final rule in the exclusion chain will not qualify the source or destination
#
$inets = ALLIPv4;
$dnets = ALLIPv4;
# #
# Create the Exclusion Chain # Create the Exclusion Chain
# #
@ -1748,17 +1746,9 @@ sub expand_rule( $$$$$$$$$$ )
# #
# Generate RETURNs for each exclusion # Generate RETURNs for each exclusion
# #
for my $net ( mysplit $iexcl ) { add_rule $echainref, ( match_source_net $_ ) . '-j RETURN' for ( mysplit $iexcl );
add_rule $echainref, ( match_source_net $net ) . '-j RETURN'; add_rule $echainref, ( match_dest_net $_ ) . '-j RETURN' for ( mysplit $dexcl );
} add_rule $echainref, ( match_orig_dest $_ ) . '-j RETURN' for ( mysplit $oexcl );
for my $net ( mysplit $dexcl ) {
add_rule $echainref, ( match_dest_net $net ) . '-j RETURN';
}
for my $net ( mysplit $oexcl ) {
add_rule $echainref, ( match_orig_dest $net ) . '-j RETURN';
}
# #
# Log rule # Log rule
# #
@ -1800,8 +1790,8 @@ sub expand_rule( $$$$$$$$$$ )
} }
} }
while ( $chainref->{cmdmode} > $initialcmdmode ) { while ( $chainref->{cmdlevel} > $initialcmdlevel ) {
pop_cmd_mode $chainref; decr_cmd_level $chainref;
add_command $chainref, 'done'; add_command $chainref, 'done';
} }
@ -1974,7 +1964,7 @@ sub create_netfilter_load() {
for my $chain ( @builtins ) { for my $chain ( @builtins ) {
my $chainref = $chain_table{$table}{$chain}; my $chainref = $chain_table{$table}{$chain};
if ( $chainref ) { if ( $chainref ) {
fatal_error "Internal error in create_netfilter_load()" if $chainref->{cmdmode}; fatal_error "Internal error in create_netfilter_load()" if $chainref->{cmdlevel};
emit_unindented ":$chain $chainref->{policy} [0:0]"; emit_unindented ":$chain $chainref->{policy} [0:0]";
push @chains, $chainref; push @chains, $chainref;
} }
@ -1985,7 +1975,7 @@ sub create_netfilter_load() {
for my $chain ( grep $chain_table{$table}{$_}->{referenced} , ( sort keys %{$chain_table{$table}} ) ) { for my $chain ( grep $chain_table{$table}{$_}->{referenced} , ( sort keys %{$chain_table{$table}} ) ) {
my $chainref = $chain_table{$table}{$chain}; my $chainref = $chain_table{$table}{$chain};
unless ( $chainref->{builtin} ) { unless ( $chainref->{builtin} ) {
fatal_error "Internal error in create_netfilter_load()" if $chainref->{cmdmode}; fatal_error "Internal error in create_netfilter_load()" if $chainref->{cmdlevel};
emit_unindented ":$chainref->{name} - [0:0]"; emit_unindented ":$chainref->{name} - [0:0]";
push @chains, $chainref; push @chains, $chainref;
} }

View File

@ -41,7 +41,7 @@ use Shorewall::Proxyarp;
our @ISA = qw(Exporter); our @ISA = qw(Exporter);
our @EXPORT = qw( compiler EXPORT TIMESTAMP DEBUG ); our @EXPORT = qw( compiler EXPORT TIMESTAMP DEBUG );
our @EXPORT_OK = qw( $export ); our @EXPORT_OK = qw( $export );
our $VERSION = 4.02; our $VERSION = 4.03;
our $export; our $export;
@ -85,7 +85,7 @@ sub generate_script_1() {
copy $globals{SHAREDIRPL} . 'prog.header'; copy $globals{SHAREDIRPL} . 'prog.header';
for my $exit qw/init start tcclear started stop stopped clear refresh refreshed/ { for my $exit qw/init isusable start tcclear started stop stopped clear refresh refreshed/ {
emit "\nrun_${exit}_exit() {"; emit "\nrun_${exit}_exit() {";
push_indent; push_indent;
append_file $exit or emit 'true'; append_file $exit or emit 'true';
@ -581,8 +581,6 @@ sub generate_script_2 () {
push_indent; push_indent;
setup_mss( $config{CLAMPMSS} ) if $config{CLAMPMSS};
} }
# #
@ -775,6 +773,10 @@ sub compiler( $$$$ ) {
# #
generate_script_2 unless $command eq 'check'; generate_script_2 unless $command eq 'check';
# #
# Set up MSS rules
#
setup_mss;
#
# Do all of the zone-independent stuff # Do all of the zone-independent stuff
# #
add_common_rules; add_common_rules;

View File

@ -93,7 +93,7 @@ our @EXPORT = qw(
%capabilities ); %capabilities );
our @EXPORT_OK = qw( $shorewall_dir initialize read_a_line1 set_config_path ); our @EXPORT_OK = qw( $shorewall_dir initialize read_a_line1 set_config_path );
our $VERSION = 4.02; our $VERSION = 4.03;
# #
# describe the current command, it's present progressive, and it's completion. # describe the current command, it's present progressive, and it's completion.
@ -198,8 +198,8 @@ sub initialize() {
ORIGINAL_POLICY_MATCH => '', ORIGINAL_POLICY_MATCH => '',
LOGPARMS => '', LOGPARMS => '',
TC_SCRIPT => '', TC_SCRIPT => '',
VERSION => '4.0.2', VERSION => '4.0.3',
CAPVERSION => 30405 , CAPVERSION => 40003 ,
); );
# #
# From shorewall.conf file # From shorewall.conf file
@ -247,6 +247,7 @@ sub initialize() {
REJECT_DEFAULT => undef, REJECT_DEFAULT => undef,
ACCEPT_DEFAULT => undef, ACCEPT_DEFAULT => undef,
QUEUE_DEFAULT => undef, QUEUE_DEFAULT => undef,
NFQUEUE_DEFAULT => undef,
# #
# RSH/RCP Commands # RSH/RCP Commands
# #
@ -328,6 +329,9 @@ sub initialize() {
MANGLE_FORWARD => undef, MANGLE_FORWARD => undef,
COMMENTS => undef, COMMENTS => undef,
ADDRTYPE => undef, ADDRTYPE => undef,
TCPMSS_MATCH => undef,
HASHLIMIT_MATCH => undef,
NFQUEUE_TARGET => undef,
CAPVERSION => undef, CAPVERSION => undef,
); );
# #
@ -360,7 +364,9 @@ sub initialize() {
MANGLE_FORWARD => 'Mangle FORWARD Chain', MANGLE_FORWARD => 'Mangle FORWARD Chain',
COMMENTS => 'Comments', COMMENTS => 'Comments',
ADDRTYPE => 'Address Type Match', ADDRTYPE => 'Address Type Match',
TCPMSS_MATCH => 'TCP MSS', TCPMSS_MATCH => 'TCPMSS Match',
HASHLIMIT_MATCH => 'Hashlimit Match',
NFQUEUE_TARGET => 'NFQUEUE Target',
CAPVERSION => 'Capability Version', CAPVERSION => 'Capability Version',
); );
# #
@ -1183,6 +1189,8 @@ sub determine_capabilities() {
$capabilities{USEPKTTYPE} = qt( "$iptables -A $sillyname -m pkttype --pkt-type broadcast -j ACCEPT" ); $capabilities{USEPKTTYPE} = qt( "$iptables -A $sillyname -m pkttype --pkt-type broadcast -j ACCEPT" );
$capabilities{ADDRTYPE} = qt( "$iptables -A $sillyname -m addrtype --src-type BROADCAST -j ACCEPT" ); $capabilities{ADDRTYPE} = qt( "$iptables -A $sillyname -m addrtype --src-type BROADCAST -j ACCEPT" );
$capabilities{TCPMSS_MATCH} = qt( "$iptables -A $sillyname -p tcp --tcp-flags SYN,RST SYN -m tcpmss --mss 1000:1500 -j ACCEPT" ); $capabilities{TCPMSS_MATCH} = qt( "$iptables -A $sillyname -p tcp --tcp-flags SYN,RST SYN -m tcpmss --mss 1000:1500 -j ACCEPT" );
$capabilities{HASHLIMIT_MATCH} = qt( "$iptables -A $sillyname -m hashlimit --hashlimit 4 --hashlimit-burst 5 --hashlimit-name fooX1234 --hashlimit-mode dstip -j ACCEPT" );
$capabilities{NFQUEUE_TARGET} = qt( "$iptables -A $sillyname -j NFQUEUE --queue-num 4" );
qt( "$iptables -F $sillyname" ); qt( "$iptables -F $sillyname" );
qt( "$iptables -X $sillyname" ); qt( "$iptables -X $sillyname" );
@ -1418,7 +1426,7 @@ sub get_configuration( $ ) {
default_yes_no 'EXPORTPARAMS' , ''; default_yes_no 'EXPORTPARAMS' , '';
default_yes_no 'EXPAND_POLICIES' , ''; default_yes_no 'EXPAND_POLICIES' , '';
default_yes_no 'ACCOUNTING_EXPERT' , ''; default_yes_no 'KEEP_RT_TABLES' , '';
default_yes_no 'MARK_IN_FORWARD_CHAIN' , ''; default_yes_no 'MARK_IN_FORWARD_CHAIN' , '';
$capabilities{XCONNMARK} = '' unless $capabilities{XCONNMARK_MATCH} and $capabilities{XMARK}; $capabilities{XCONNMARK} = '' unless $capabilities{XCONNMARK_MATCH} and $capabilities{XMARK};
@ -1480,16 +1488,17 @@ sub get_configuration( $ ) {
} }
default 'RESTOREFILE' , 'restore'; default 'RESTOREFILE' , 'restore';
default 'IPSECFILE' , 'zones';
default 'DROP_DEFAULT' , 'Drop'; default 'DROP_DEFAULT' , 'Drop';
default 'REJECT_DEFAULT' , 'Reject'; default 'REJECT_DEFAULT' , 'Reject';
default 'QUEUE_DEFAULT' , 'none'; default 'QUEUE_DEFAULT' , 'none';
default 'NFQUEUE_DEFAULT' , 'none';
default 'ACCEPT_DEFAULT' , 'none'; default 'ACCEPT_DEFAULT' , 'none';
default 'OPTIMIZE' , 0; default 'OPTIMIZE' , 0;
default 'IPSECFILE' , 'zones';
fatal_error 'IPSECFILE=ipsec is not supported by Shorewall-perl ' . $globals{VERSION} unless $config{IPSECFILE} eq 'zones'; fatal_error 'IPSECFILE=ipsec is not supported by Shorewall-perl ' . $globals{VERSION} unless $config{IPSECFILE} eq 'zones';
for my $default qw/DROP_DEFAULT REJECT_DEFAULT QUEUE_DEFAULT ACCEPT_DEFAULT/ { for my $default qw/DROP_DEFAULT REJECT_DEFAULT QUEUE_DEFAULT NFQUEUE_DEFAULT ACCEPT_DEFAULT/ {
$config{$default} = 'none' if "\L$config{$default}" eq 'none'; $config{$default} = 'none' if "\L$config{$default}" eq 'none';
} }

View File

@ -41,7 +41,7 @@ our @EXPORT = qw( ALLIPv4
@rfc1918_networks @rfc1918_networks
); );
our @EXPORT_OK = qw( ); our @EXPORT_OK = qw( );
our $VERSION = 4.00; our $VERSION = 4.03;
# #
# Some IPv4 useful stuff # Some IPv4 useful stuff
@ -75,6 +75,8 @@ sub validate_address( $ ) {
sub validate_net( $ ) { sub validate_net( $ ) {
my ($net, $vlsm, $rest) = split( '/', $_[0], 3 ); my ($net, $vlsm, $rest) = split( '/', $_[0], 3 );
fatal_error "An ipset name ($net) is not allowed in this context" if substr( $net, 0, 1 ) eq '+';
if ( defined $vlsm ) { if ( defined $vlsm ) {
fatal_error "Invalid VLSM ($vlsm)" unless $vlsm =~ /^\d+$/ && $vlsm <= 32; fatal_error "Invalid VLSM ($vlsm)" unless $vlsm =~ /^\d+$/ && $vlsm <= 32;
fatal_error "Invalid Network address ($_[0])" if defined $rest; fatal_error "Invalid Network address ($_[0])" if defined $rest;

View File

@ -36,7 +36,7 @@ use strict;
our @ISA = qw(Exporter); our @ISA = qw(Exporter);
our @EXPORT = qw( setup_masq setup_nat setup_netmap add_addresses ); our @EXPORT = qw( setup_masq setup_nat setup_netmap add_addresses );
our @EXPORT_OK = (); our @EXPORT_OK = ();
our $VERSION = 4.00; our $VERSION = 4.03;
our @addresses_to_add; our @addresses_to_add;
our %addresses_to_add; our %addresses_to_add;
@ -212,7 +212,7 @@ sub setup_one_masq($$$$$$$)
add_commands( $chainref, add_commands( $chainref,
'', '',
"if [ \"$variable\" != 0.0.0.0 ]; then" ); "if [ \"$variable\" != 0.0.0.0 ]; then" );
push_cmd_mode( $chainref ); incr_cmd_level( $chainref );
$detectaddress = 1; $detectaddress = 1;
} }
} else { } else {
@ -249,7 +249,7 @@ sub setup_one_masq($$$$$$$)
$exceptionrule ); $exceptionrule );
if ( $detectaddress ) { if ( $detectaddress ) {
pop_cmd_mode( $chainref ); decr_cmd_level( $chainref );
add_command( $chainref , 'fi' ); add_command( $chainref , 'fi' );
} }

View File

@ -34,21 +34,32 @@ use strict;
our @ISA = qw(Exporter); our @ISA = qw(Exporter);
our @EXPORT = qw( validate_policy apply_policy_rules complete_standard_chain sub setup_syn_flood_chains ); our @EXPORT = qw( validate_policy apply_policy_rules complete_standard_chain sub setup_syn_flood_chains );
our @EXPORT_OK = qw( ); our @EXPORT_OK = qw( );
our $VERSION = 4.02; our $VERSION = 4.03;
# #
# Create a new policy chain and return a reference to it. # Convert a chain into a policy chain.
# #
sub new_policy_chain($$$) sub convert_to_policy_chain($$$$$)
{ {
my ($chain, $policy, $optional) = @_; my ($chainref, $source, $dest, $policy, $optional ) = @_;
my $chainref = new_chain 'filter', $chain;
$chainref->{is_policy} = 1; $chainref->{is_policy} = 1;
$chainref->{policy} = $policy; $chainref->{policy} = $policy;
$chainref->{is_optional} = $optional; $chainref->{is_optional} = $optional;
$chainref->{policychain} = $chain; $chainref->{policychain} = $chainref->{name};
$chainref->{policypair} = [ $source, $dest ];
}
#
# Create a new policy chain and return a reference to it.
#
sub new_policy_chain($$$$)
{
my ($source, $dest, $policy, $optional) = @_;
my $chainref = new_chain( 'filter', "${source}2${dest}" );
convert_to_policy_chain( $chainref, $source, $dest, $policy, $optional );
$chainref; $chainref;
} }
@ -56,9 +67,9 @@ sub new_policy_chain($$$)
# #
# Set the passed chain's policychain and policy to the passed values. # Set the passed chain's policychain and policy to the passed values.
# #
sub set_policy_chain($$$) sub set_policy_chain($$$$$)
{ {
my ($chain1, $chainref, $policy) = @_; my ($source, $dest, $chain1, $chainref, $policy ) = @_;
my $chainref1 = $filter_table->{$chain1}; my $chainref1 = $filter_table->{$chain1};
@ -86,6 +97,7 @@ sub set_policy_chain($$$)
} }
$chainref1->{policy} = $policy; $chainref1->{policy} = $policy;
$chainref1->{policypair} = [ $source, $dest ];
} }
} }
@ -97,8 +109,13 @@ sub validate_policy()
sub print_policy($$$$) sub print_policy($$$$)
{ {
my ( $source, $dest, $policy , $chain ) = @_; my ( $source, $dest, $policy , $chain ) = @_;
progress_message " Policy for $source to $dest is $policy using chain $chain" unless ( ( $source eq 'all' ) || ( $dest eq 'all' ) ) {
unless ( $source eq $dest ) || ( $source eq 'all' ) || ( $dest eq 'all' ); if ( $policy eq 'CONTINUE' ) {
my ( $sourceref, $destref ) = @zones{$source,$dest};
warning_message "CONTINUE policy between two un-nested zones ($source, $dest)" if ! ( @{$sourceref->{parents}} || @{$destref->{parents}} );
}
progress_message " Policy for $source to $dest is $policy using chain $chain" unless $source eq $dest;
}
} }
my %validpolicies = ( my %validpolicies = (
@ -107,19 +124,21 @@ sub validate_policy()
DROP => undef, DROP => undef,
CONTINUE => undef, CONTINUE => undef,
QUEUE => undef, QUEUE => undef,
NFQUEUE => undef,
NONE => undef NONE => undef
); );
my %map = ( DROP_DEFAULT => 'DROP' , my %map = ( DROP_DEFAULT => 'DROP' ,
REJECT_DEFAULT => 'REJECT' , REJECT_DEFAULT => 'REJECT' ,
ACCEPT_DEFAULT => 'ACCEPT' , ACCEPT_DEFAULT => 'ACCEPT' ,
QUEUE_DEFAULT => 'QUEUE' ); QUEUE_DEFAULT => 'QUEUE' ,
NFQUEUE_DEFAULT => 'NFQUEUE' );
my $zone; my $zone;
use constant { OPTIONAL => 1 }; use constant { OPTIONAL => 1 };
for my $option qw/DROP_DEFAULT REJECT_DEFAULT ACCEPT_DEFAULT QUEUE_DEFAULT/ { for my $option qw/DROP_DEFAULT REJECT_DEFAULT ACCEPT_DEFAULT QUEUE_DEFAULT NFQUEUE_DEFAULT/ {
my $action = $config{$option}; my $action = $config{$option};
next if $action eq 'none'; next if $action eq 'none';
my $actiontype = $targets{$action}; my $actiontype = $targets{$action};
@ -139,13 +158,13 @@ sub validate_policy()
} }
for $zone ( @zones ) { for $zone ( @zones ) {
push @policy_chains, ( new_policy_chain "${zone}2${zone}", 'ACCEPT', OPTIONAL ); push @policy_chains, ( new_policy_chain $zone, $zone, 'ACCEPT', OPTIONAL );
if ( $config{IMPLICIT_CONTINUE} && ( @{$zones{$zone}{parents}} ) ) { if ( $config{IMPLICIT_CONTINUE} && ( @{$zones{$zone}{parents}} ) ) {
for my $zone1 ( @zones ) { for my $zone1 ( @zones ) {
next if $zone eq $zone1; next if $zone eq $zone1;
push @policy_chains, ( new_policy_chain "${zone}2${zone1}", 'CONTINUE', OPTIONAL ); push @policy_chains, ( new_policy_chain $zone, $zone1, 'CONTINUE', OPTIONAL );
push @policy_chains, ( new_policy_chain "${zone1}2${zone}", 'CONTINUE', OPTIONAL ); push @policy_chains, ( new_policy_chain $zone1, $zone, 'CONTINUE', OPTIONAL );
} }
} }
} }
@ -178,6 +197,8 @@ sub validate_policy()
fatal_error "Invalid default action ($default:$remainder)" if defined $remainder; fatal_error "Invalid default action ($default:$remainder)" if defined $remainder;
( $policy , my $queue ) = split( '/' , $policy );
if ( $default ) { if ( $default ) {
if ( "\L$default" eq 'none' ) { if ( "\L$default" eq 'none' ) {
$default = 'none'; $default = 'none';
@ -199,7 +220,13 @@ sub validate_policy()
fatal_error "Invalid policy $policy" unless exists $validpolicies{$policy}; fatal_error "Invalid policy $policy" unless exists $validpolicies{$policy};
if ( $policy eq 'NONE' ) { if ( defined $queue ) {
fatal_error "Invalid policy ($policy/$queue)" unless $policy eq 'NFQUEUE';
require_capability( 'NFQUEUE_TARGET', 'An NFQUEUE Policy', 's' );
$queue = numeric_value( $queue );
fatal_error "Invalid NFQUEUE queue number ($queue)" if $queue > 65535;
$policy = "$policy/$queue";
} elsif ( $policy eq 'NONE' ) {
fatal_error "NONE policy not allowed with \"all\"" fatal_error "NONE policy not allowed with \"all\""
if $clientwild || $serverwild; if $clientwild || $serverwild;
fatal_error "NONE policy not allowed to/from firewall zone" fatal_error "NONE policy not allowed to/from firewall zone"
@ -224,18 +251,16 @@ sub validate_policy()
$chainref->{is_optional} = 0; $chainref->{is_optional} = 0;
$chainref->{policy} = $policy; $chainref->{policy} = $policy;
} else { } else {
fatal_error "Duplicate policy: $client $server $policy"; fatal_error qq(Policy "$client $server $policy" duplicates earlier policy "@{$chainref->{policypair}} $chainref->{policy}");
} }
} elsif ( $chainref->{policy} ) { } elsif ( $chainref->{policy} ) {
fatal_error "Duplicate policy: $client $server $policy"; fatal_error qq(Policy "$client $server $policy" duplicates earlier policy "@{$chainref->{policypair}} $chainref->{policy}");
} else { } else {
$chainref->{is_policy} = 1; convert_to_policy_chain( $chainref, $client, $server, $policy, 0 );
$chainref->{policy} = $policy;
$chainref->{policychain} = $chain;
push @policy_chains, ( $chainref ) unless $config{EXPAND_POLICIES} && ( $clientwild || $serverwild ); push @policy_chains, ( $chainref ) unless $config{EXPAND_POLICIES} && ( $clientwild || $serverwild );
} }
} else { } else {
$chainref = new_policy_chain $chain, $policy, 0; $chainref = new_policy_chain $client, $server, $policy, 0;
push @policy_chains, ( $chainref ) unless $config{EXPAND_POLICIES} && ( $clientwild || $serverwild ); push @policy_chains, ( $chainref ) unless $config{EXPAND_POLICIES} && ( $clientwild || $serverwild );
} }
@ -252,19 +277,19 @@ sub validate_policy()
if ( $serverwild ) { if ( $serverwild ) {
for my $zone ( @zones , 'all' ) { for my $zone ( @zones , 'all' ) {
for my $zone1 ( @zones , 'all' ) { for my $zone1 ( @zones , 'all' ) {
set_policy_chain "${zone}2${zone1}", $chainref, $policy; set_policy_chain $client, $server, "${zone}2${zone1}", $chainref, $policy;
print_policy $zone, $zone1, $policy, $chain; print_policy $zone, $zone1, $policy, $chain;
} }
} }
} else { } else {
for my $zone ( @zones ) { for my $zone ( @zones ) {
set_policy_chain "${zone}2${server}", $chainref, $policy; set_policy_chain $client, $server, "${zone}2${server}", $chainref, $policy;
print_policy $zone, $server, $policy, $chain; print_policy $zone, $server, $policy, $chain;
} }
} }
} elsif ( $serverwild ) { } elsif ( $serverwild ) {
for my $zone ( @zones , 'all' ) { for my $zone ( @zones , 'all' ) {
set_policy_chain "${client}2${zone}", $chainref, $policy; set_policy_chain $client, $server, "${client}2${zone}", $chainref, $policy;
print_policy $client, $zone, $policy, $chain; print_policy $client, $zone, $policy, $chain;
} }
@ -284,7 +309,14 @@ sub policy_rules( $$$$ ) {
add_rule $chainref, "-j $default" if $default && $default ne 'none'; add_rule $chainref, "-j $default" if $default && $default ne 'none';
log_rule $loglevel , $chainref , $target , '' if $loglevel ne ''; log_rule $loglevel , $chainref , $target , '' if $loglevel ne '';
fatal_error "Null target in policy_rules()" unless $target; fatal_error "Null target in policy_rules()" unless $target;
add_rule $chainref , ( '-j ' . ( $target eq 'REJECT' ? 'reject' : $target ) ) unless $target eq 'CONTINUE'; if ( $target eq 'REJECT' ) {
$target = 'reject';
} elsif ( $target =~ /^NFQUEUE/ ) {
my $queue = ( split( '/', $target) )[1] || 0;
$target = "NFQUEUE --queue-num $queue";
}
add_rule( $chainref , "-j $target" ) unless $target eq 'CONTINUE';
} }
} }
@ -305,7 +337,7 @@ sub default_policy( $$$ ) {
if ( $chainref eq $policyref ) { if ( $chainref eq $policyref ) {
policy_rules $chainref , $policy, $loglevel , $default; policy_rules $chainref , $policy, $loglevel , $default;
} else { } else {
if ( $policy eq 'ACCEPT' || $policy eq 'QUEUE' ) { if ( $policy eq 'ACCEPT' || $policy eq 'QUEUE' || $policy =~ /^NFQUEUE/ ) {
if ( $synparams ) { if ( $synparams ) {
report_syn_flood_protection; report_syn_flood_protection;
policy_rules $chainref , $policy , $loglevel , $default; policy_rules $chainref , $policy , $loglevel , $default;
@ -374,6 +406,8 @@ sub apply_policy_rules() {
sub complete_standard_chain ( $$$ ) { sub complete_standard_chain ( $$$ ) {
my ( $stdchainref, $zone, $zone2 ) = @_; my ( $stdchainref, $zone, $zone2 ) = @_;
add_rule $stdchainref, '-m state --state ESTABLISHED,RELATED -j ACCEPT' unless $config{FASTACCEPT};
run_user_exit $stdchainref; run_user_exit $stdchainref;
my $ruleschainref = $filter_table->{"${zone}2${zone2}"}; my $ruleschainref = $filter_table->{"${zone}2${zone2}"};

View File

@ -316,8 +316,9 @@ sub add_an_rtrule( $$$$ ) {
if ( "\L$provider" =~ /^(0x[a-f0-9]+|0[0-7]*|[0-9]*)$/ ) { if ( "\L$provider" =~ /^(0x[a-f0-9]+|0[0-7]*|[0-9]*)$/ ) {
my $provider_number = numeric_value $provider; my $provider_number = numeric_value $provider;
for my $provider ( keys %providers ) { for ( keys %providers ) {
if ( $providers{$provider}{number} == $provider_number ) { if ( $providers{$_}{number} == $provider_number ) {
$provider = $_;
$found = 1; $found = 1;
last; last;
} }

View File

@ -47,7 +47,7 @@ our @EXPORT = qw( process_tos
dump_rule_chains dump_rule_chains
); );
our @EXPORT_OK = qw( process_rule process_rule1 initialize ); our @EXPORT_OK = qw( process_rule process_rule1 initialize );
our $VERSION = 4.02; our $VERSION = 4.03;
# #
# Keep track of chains for the /var/lib/shorewall[-lite]/chains file # Keep track of chains for the /var/lib/shorewall[-lite]/chains file
@ -109,7 +109,7 @@ sub process_tos() {
my ($src, $dst, $proto, $sports, $ports , $tos, $mark ) = split_line 6, 7, 'tos file entry'; my ($src, $dst, $proto, $sports, $ports , $tos, $mark ) = split_line 6, 7, 'tos file entry';
fatal_error "TOS field required" unless $tos ne '-'; fatal_error "A value must be supplied in the TOS column" if $tos eq '-';
if ( defined ( my $tosval = $tosoptions{"\L$tos"} ) ) { if ( defined ( my $tosval = $tosoptions{"\L$tos"} ) ) {
$tos = $tosval; $tos = $tosval;
@ -501,6 +501,13 @@ sub add_common_rules() {
my $list; my $list;
my $chain; my $chain;
if ( $config{FASTACCEPT} ) {
for $chain qw( INPUT FORWARD OUTPUT ) {
$chainref = $filter_table->{$chain};
add_rule( $chainref , "-m state --state ESTABLISHED,RELATED -j ACCEPT" );
}
}
my $rejectref = new_standard_chain 'reject'; my $rejectref = new_standard_chain 'reject';
$level = $config{BLACKLIST_LOGLEVEL}; $level = $config{BLACKLIST_LOGLEVEL};
@ -533,10 +540,10 @@ sub add_common_rules() {
add_rule_pair $chainref, '-m addrtype --src-type BROADCAST ', 'DROP', $config{SMURF_LOG_LEVEL} ; add_rule_pair $chainref, '-m addrtype --src-type BROADCAST ', 'DROP', $config{SMURF_LOG_LEVEL} ;
} else { } else {
add_command $chainref, 'for address in $ALL_BCASTS; do'; add_command $chainref, 'for address in $ALL_BCASTS; do';
push_cmd_mode $chainref; incr_cmd_level $chainref;
log_rule( $config{SMURF_LOG_LEVEL} , $chainref, 'DROP', '-s $address ' ); log_rule( $config{SMURF_LOG_LEVEL} , $chainref, 'DROP', '-s $address ' );
add_rule $chainref, '-s $address -j DROP'; add_rule $chainref, '-s $address -j DROP';
pop_cmd_mode $chainref; decr_cmd_level $chainref;
add_command $chainref, 'done'; add_command $chainref, 'done';
} }
@ -546,9 +553,9 @@ sub add_common_rules() {
add_rule $rejectref , '-m addrtype --src-type BROADCAST -j DROP'; add_rule $rejectref , '-m addrtype --src-type BROADCAST -j DROP';
} else { } else {
add_command $rejectref, 'for address in $ALL_BCASTS; do'; add_command $rejectref, 'for address in $ALL_BCASTS; do';
push_cmd_mode $rejectref; incr_cmd_level $rejectref;
add_rule $rejectref, '-d $address -j DROP'; add_rule $rejectref, '-d $address -j DROP';
pop_cmd_mode $rejectref; decr_cmd_level $rejectref;
add_command $rejectref, 'done'; add_command $rejectref, 'done';
} }
@ -967,6 +974,14 @@ sub process_rule1 ( $$$$$$$$$$$ ) {
$current_param = pop @param_stack if $param ne ''; $current_param = pop @param_stack if $param ne '';
return; return;
} elsif ( $actiontype & NFQ ) {
require_capability( 'NFQUEUE_TARGET', 'NFQUEUE Rules', '' );
$param = $param eq '' ? 0 : numeric_value( $param );
fatal_error "Invalid value ($param) for NFQUEUE queue number" if $param > 65535;
$action = "NFQUEUE/$param";
} else {
fatal_error "The $basictarget TARGET does not accept a parameter" unless $param eq '';
} }
# #
# We can now dispense with the postfix characters # We can now dispense with the postfix characters
@ -1110,7 +1125,6 @@ sub process_rule1 ( $$$$$$$$$$$ ) {
my $servport = $serverport ne '' ? $serverport : $ports; my $servport = $serverport ne '' ? $serverport : $ports;
fatal_error "A server must be specified in the DEST column in $action rules" unless ( $actiontype & REDIRECT ) || $server ne ALLIPv4; fatal_error "A server must be specified in the DEST column in $action rules" unless ( $actiontype & REDIRECT ) || $server ne ALLIPv4;
fatal_error "Invalid server ($server)" if $server =~ /:/;
# #
# Generate the target # Generate the target
# #
@ -1118,6 +1132,17 @@ sub process_rule1 ( $$$$$$$$$$$ ) {
if ( $actiontype & REDIRECT ) { if ( $actiontype & REDIRECT ) {
$target = '-j REDIRECT --to-port ' . ( $serverport ne '' ? $serverport : $ports ); $target = '-j REDIRECT --to-port ' . ( $serverport ne '' ? $serverport : $ports );
if ( $origdest eq '' || $origdest eq '-' ) {
$origdest = ALLIPv4;
} elsif ( $origdest eq 'detect' ) {
if ( $config{DETECT_DNAT_IPADDRS} && $sourcezone ne $firewall_zone ) {
my $interfacesref = $zones{$sourcezone}{interfaces};
my @interfaces = keys %$interfacesref;
$origdest = @interfaces ? "detect:@interfaces" : ALLIPv4;
} else {
$origdest = ALLIPv4;
}
}
} else { } else {
if ( $action eq 'SAME' ) { if ( $action eq 'SAME' ) {
fatal_error 'Port mapping not allowed in SAME rules' if $serverport; fatal_error 'Port mapping not allowed in SAME rules' if $serverport;
@ -1135,7 +1160,7 @@ sub process_rule1 ( $$$$$$$$$$$ ) {
} }
unless ( $origdest && $origdest ne '-' && $origdest ne 'detect' ) { unless ( $origdest && $origdest ne '-' && $origdest ne 'detect' ) {
if ( $config{DETECT_DNAT_IPADDRS} ) { if ( $config{DETECT_DNAT_IPADDRS} && $sourcezone ne $firewall_zone ) {
my $interfacesref = $zones{$sourcezone}{interfaces}; my $interfacesref = $zones{$sourcezone}{interfaces};
my @interfaces = keys %$interfacesref; my @interfaces = keys %$interfacesref;
$origdest = @interfaces ? "detect:@interfaces" : ALLIPv4; $origdest = @interfaces ? "detect:@interfaces" : ALLIPv4;
@ -1144,6 +1169,7 @@ sub process_rule1 ( $$$$$$$$$$$ ) {
} }
} }
} }
# #
# And generate the nat table rule(s) # And generate the nat table rule(s)
# #
@ -1217,7 +1243,7 @@ sub process_rule1 ( $$$$$$$$$$$ ) {
$source , $source ,
$dest , $dest ,
$origdest , $origdest ,
"-j $action " , $actiontype & NFQ ? "-j NFQUEUE --queue-num $param " : "-j $action " ,
$loglevel , $loglevel ,
$action , $action ,
'' ); '' );
@ -1849,11 +1875,13 @@ sub generate_matrix() {
} }
} }
sub setup_mss( $ ) { sub setup_mss( ) {
my $clampmss = $_[0]; my $clampmss = $config{CLAMPMSS};
my $option; my $option;
my $match = ''; my $match = '';
my $chainref = $filter_table->{FORWARD};
if ( $clampmss ) {
if ( "\L$clampmss" eq 'yes' ) { if ( "\L$clampmss" eq 'yes' ) {
$option = '--clamp-mss-to-pmtu'; $option = '--clamp-mss-to-pmtu';
} else { } else {
@ -1861,13 +1889,44 @@ sub setup_mss( $ ) {
$option = "--set-mss $clampmss"; $option = "--set-mss $clampmss";
} }
add_rule $filter_table->{FORWARD} , "-p tcp --tcp-flags SYN,RST SYN ${match}-j TCPMSS $option"; $match .= '-m policy --pol none --dir out ' if $capabilities{POLICY_MATCH};
}
my $interfaces = find_interfaces_by_option( 'mss' );
if ( @$interfaces ) {
#
# Since we will need multiple rules, we create a separate chain
#
$chainref = new_chain 'filter', 'settcpmss';
#
# Send all forwarded SYN packets to the 'settcpmss' chain
#
add_rule $filter_table->{FORWARD} , "-p tcp --tcp-flags SYN,RST SYN -j settcpmss";
my $in_match = '';
my $out_match = '';
if ( $capabilities{POLICY_MATCH} ) {
$in_match = '-m policy --pol none --dir in ';
$out_match = '-m policy --pol none --dir out ';
}
for ( @$interfaces ) {
my $mss = $interfaces{$_}{options}{mss};
my $mssmatch = $capabilities{TCPMSS_MATCH} ? "-m tcpmss --mss $mss: " : '';
add_rule $chainref, "-o $_ -p tcp --tcp-flags SYN,RST SYN ${mssmatch}${out_match}-j TCPMSS --set-mss $mss";
add_rule $chainref, "-o $_ -j RETURN" if $clampmss;
add_rule $chainref, "-i $_ -p tcp --tcp-flags SYN,RST SYN ${mssmatch}${in_match}-j TCPMSS --set-mss $mss";
add_rule $chainref, "-i $_ -j RETURN" if $clampmss;
}
}
add_rule $chainref , "-p tcp --tcp-flags SYN,RST SYN ${match}-j TCPMSS $option" if $clampmss;
} }
sub dump_rule_chains() { sub dump_rule_chains() {
for my $arrayref ( @rule_chains ) { emit_unindented "@$_" for ( @rule_chains );
emit_unindented "@$arrayref";
}
} }
1; 1;

View File

@ -39,7 +39,7 @@ use strict;
our @ISA = qw(Exporter); our @ISA = qw(Exporter);
our @EXPORT = qw( setup_tc ); our @EXPORT = qw( setup_tc );
our @EXPORT_OK = qw( process_tc_rule initialize ); our @EXPORT_OK = qw( process_tc_rule initialize );
our $VERSION = 4.02; our $VERSION = 4.03;
our %tcs = ( T => { chain => 'tcpost', our %tcs = ( T => { chain => 'tcpost',
connmark => 0, connmark => 0,
@ -184,7 +184,7 @@ sub process_tc_rule( $$$$$$$$$$ ) {
my $tcsref; my $tcsref;
my $connmark = 0; my $connmark = 0;
my $classid = 0; my $classid = 0;
my $device; my $device = '';
if ( $source ) { if ( $source ) {
if ( $source eq $firewall_zone ) { if ( $source eq $firewall_zone ) {
@ -268,7 +268,7 @@ sub process_tc_rule( $$$$$$$$$$ ) {
} }
} }
if ( my $result = expand_rule( if ( ( my $result = expand_rule(
ensure_chain( 'mangle' , $chain ) , ensure_chain( 'mangle' , $chain ) ,
NO_RESTRICT , NO_RESTRICT ,
do_proto( $proto, $ports, $sports) . do_test( $testval, $mask ) . do_tos( $tos ) , do_proto( $proto, $ports, $sports) . do_test( $testval, $mask ) . do_tos( $tos ) ,
@ -278,11 +278,12 @@ sub process_tc_rule( $$$$$$$$$$ ) {
"-j $target $mark" , "-j $target $mark" ,
'' , '' ,
'' , '' ,
'' ) ) { '' ) )
&& $device ) {
# #
# expand_rule() returns destination device if any # expand_rule() returns destination device if any
# #
fatal_error "Class Id $original_mark is not associated with device $result" if $config{TC_ENABLED} eq 'internal' && $classid && $device ne $result; fatal_error "Class Id $original_mark is not associated with device $result" if $device ne $result;
} }
progress_message " TC Rule \"$currentline\" $done"; progress_message " TC Rule \"$currentline\" $done";

View File

@ -37,6 +37,7 @@ our @EXPORT = qw( NOTHING
IPSECPROTO IPSECPROTO
IPSECMODE IPSECMODE
numeric_value
determine_zones determine_zones
zone_report zone_report
dump_zone_contents dump_zone_contents
@ -59,7 +60,7 @@ our @EXPORT = qw( NOTHING
@bridges ); @bridges );
our @EXPORT_OK = qw( initialize ); our @EXPORT_OK = qw( initialize );
our $VERSION = 4.01; our $VERSION = 4.03;
# #
# IPSEC Option types # IPSEC Option types
@ -76,7 +77,7 @@ use constant { NOTHING => 'NOTHING',
# #
# @zones contains the ordered list of zones with sub-zones appearing before their parents. # @zones contains the ordered list of zones with sub-zones appearing before their parents.
# #
# %zones{<zone1> => {type = > <zone type> # %zones{<zone1> => {type = > <zone type> 'firewall', 'ipv4', 'ipsec4', 'bport4';
# options => { complex => 0|1 # options => { complex => 0|1
# in_out => < policy match string > # in_out => < policy match string >
# in => < policy match string > # in => < policy match string >
@ -110,16 +111,6 @@ our %reservedName = ( all => 1,
SOURCE => 1, SOURCE => 1,
DEST => 1 ); DEST => 1 );
se constant ( ZT_IPV4 => 1,
ZT_IPSEC => 2,
ZT_BPORT => 4,
ZT_IPV6 => 8,
ZT_FIREWALL => 16,
ZT_IPSEC4 => ZT_IPV4 | ZT_IPSEC
ZT_IPSEC6 => ZT_IPV6 | ZT_IPSEC
ZT_BPORT4 => ZT_IPV4 | ZT_BPORT
ZT_BPORT6 => ZT_IPV6 | ZT_BPORT
);
# #
# Interface Table. # Interface Table.
# #
@ -162,6 +153,15 @@ INIT {
initialize; initialize;
} }
#
# Convert value to decimal number
#
sub numeric_value ( $ ) {
my $mark = $_[0];
fatal_error "Invalid Numeric Value ($mark)" unless "\L$mark" =~ /^(0x[a-f0-9]+|0[0-7]*|[1-9]\d*)$/;
$mark =~ /^0/ ? oct $mark : $mark;
}
# #
# Parse the passed option list and return a reference to a hash as follows: # Parse the passed option list and return a reference to a hash as follows:
# #
@ -219,7 +219,7 @@ sub parse_zone_option_list($$)
if ( $key{$e} ) { if ( $key{$e} ) {
$h{$e} = $val; $h{$e} = $val;
} else { } else {
fatal_error "The \"$e\" option may only be specified for ipsec zones" unless $zonetype & ZT_IPSEC; fatal_error "The \"$e\" option may only be specified for ipsec zones" unless $zonetype eq 'ipsec4';
$options .= $invert; $options .= $invert;
$options .= "--$e "; $options .= "--$e ";
$options .= "$val "if defined $val; $options .= "$val "if defined $val;
@ -261,7 +261,7 @@ sub determine_zones()
for my $p ( @parents ) { for my $p ( @parents ) {
fatal_error "Invalid Parent List ($2)" unless $p; fatal_error "Invalid Parent List ($2)" unless $p;
fatal_error "Unknown parent zone ($p)" unless $zones{$p}; fatal_error "Unknown parent zone ($p)" unless $zones{$p};
fatal_error 'Subzones of firewall zone not allowed' if $zones{$p}{type} & ZT_FIREWALL; fatal_error 'Subzones of firewall zone not allowed' if $zones{$p}{type} eq 'firewall';
push @{$zones{$p}{children}}, $zone; push @{$zones{$p}{children}}, $zone;
} }
} }
@ -273,20 +273,20 @@ sub determine_zones()
$type = "ipv4" unless $type; $type = "ipv4" unless $type;
if ( $type =~ /ipv4/i ) { if ( $type =~ /ipv4/i ) {
$type = ZT_IPV4; $type = 'ipv4';
} elsif ( $type =~ /^ipsec4?$/i ) { } elsif ( $type =~ /^ipsec4?$/i ) {
$type = ZT_IPSEC4; $type = 'ipsec4';
} elsif ( $type =~ /^bport4?$/i ) { } elsif ( $type =~ /^bport4?$/i ) {
warning_message "Bridge Port zones should have a parent zone" unless @parents; warning_message "Bridge Port zones should have a parent zone" unless @parents;
$type = ZT_BPORT4; $type = 'bport4';
} elsif ( $type eq 'firewall' ) { } elsif ( $type eq 'firewall' ) {
fatal_error 'Firewall zone may not be nested' if @parents; fatal_error 'Firewall zone may not be nested' if @parents;
fatal_error "Only one firewall zone may be defined ($zone)" if $firewall_zone; fatal_error "Only one firewall zone may be defined ($zone)" if $firewall_zone;
$firewall_zone = $zone; $firewall_zone = $zone;
$ENV{FW} = $zone; $ENV{FW} = $zone;
$type = ZT_FIREWALL; $type = "firewall";
} elsif ( $type eq '-' ) { } elsif ( $type eq '-' ) {
$type = ZT_IPV4; $type = 'ipv4';
} else { } else {
fatal_error "Invalid zone type ($type)" ; fatal_error "Invalid zone type ($type)" ;
} }
@ -302,7 +302,7 @@ sub determine_zones()
options => { in_out => parse_zone_option_list( $options || '', $type ) , options => { in_out => parse_zone_option_list( $options || '', $type ) ,
in => parse_zone_option_list( $in_options || '', $type ) , in => parse_zone_option_list( $in_options || '', $type ) ,
out => parse_zone_option_list( $out_options || '', $type ) , out => parse_zone_option_list( $out_options || '', $type ) ,
complex => ($type & ZT_IPSEC || $options || $in_options || $out_options ? 1 : 0) } , complex => ($type eq 'ipsec4' || $options || $in_options || $out_options ? 1 : 0) } ,
interfaces => {} , interfaces => {} ,
children => [] , children => [] ,
hosts => {} hosts => {}
@ -337,22 +337,12 @@ sub determine_zones()
# #
sub haveipseczones() { sub haveipseczones() {
for my $zoneref ( values %zones ) { for my $zoneref ( values %zones ) {
return 1 if $zoneref->{type} & ZT_IPSEC; return 1 if $zoneref->{type} eq 'ipsec4';
} }
0; 0;
} }
my @typenames = ( Untyped, #0
firewall, #1
ipv4, #2
Invalid, #3
Invalid, #4
Invalid, #5
ipsec4, #6
Invalid, #7
Invalid, #8
# #
# Report about zones. # Report about zones.
# #
@ -551,9 +541,10 @@ sub validate_interfaces_file( $ )
use constant { SIMPLE_IF_OPTION => 1, use constant { SIMPLE_IF_OPTION => 1,
BINARY_IF_OPTION => 2, BINARY_IF_OPTION => 2,
ENUM_IF_OPTION => 3, ENUM_IF_OPTION => 3,
MASK_IF_OPTION => 3, NUMERIC_IF_OPTION => 4,
MASK_IF_OPTION => 7,
IF_OPTION_ZONEONLY => 4 }; IF_OPTION_ZONEONLY => 8 };
my %validoptions = (arp_filter => BINARY_IF_OPTION, my %validoptions = (arp_filter => BINARY_IF_OPTION,
arp_ignore => ENUM_IF_OPTION, arp_ignore => ENUM_IF_OPTION,
@ -572,6 +563,7 @@ sub validate_interfaces_file( $ )
sourceroute => BINARY_IF_OPTION, sourceroute => BINARY_IF_OPTION,
tcpflags => SIMPLE_IF_OPTION, tcpflags => SIMPLE_IF_OPTION,
upnp => SIMPLE_IF_OPTION, upnp => SIMPLE_IF_OPTION,
mss => NUMERIC_IF_OPTION,
); );
my $fn = open_file 'interfaces'; my $fn = open_file 'interfaces';
@ -701,6 +693,9 @@ sub validate_interfaces_file( $ )
} else { } else {
fatal_error "Internal Error in validate_interfaces_file"; fatal_error "Internal Error in validate_interfaces_file";
} }
} elsif ( $type == NUMERIC_IF_OPTION ) {
fatal_error "The $option option requires a value" unless defined $value;
$options{$option} = numeric_value $value;
} }
} }

View File

@ -22,7 +22,7 @@
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
# #
VERSION=4.0.2 VERSION=4.0.3
usage() # $1 = exit status usage() # $1 = exit status
{ {

View File

@ -540,7 +540,7 @@ find_first_interface_address_if_any() # $1 = interface
# #
interface_is_usable() # $1 = interface interface_is_usable() # $1 = interface
{ {
interface_is_up $1 && [ "$(find_first_interface_address_if_any $1)" != 0.0.0.0 ] interface_is_up $1 && [ "$(find_first_interface_address_if_any $1)" != 0.0.0.0 ] && run_isusable_exit $1
} }
# #

View File

@ -1,5 +1,5 @@
%define name shorewall-perl %define name shorewall-perl
%define version 4.0.2 %define version 4.0.3
%define release 1 %define release 1
Summary: Shoreline Firewall Perl-based compiler. Summary: Shoreline Firewall Perl-based compiler.
@ -72,6 +72,8 @@ fi
%doc COPYING releasenotes.txt %doc COPYING releasenotes.txt
%changelog %changelog
* Mon Aug 13 2007 Tom Eastep tom@shorewall.net
- Updated to 4.0.3-1
* Thu Aug 09 2007 Tom Eastep tom@shorewall.net * Thu Aug 09 2007 Tom Eastep tom@shorewall.net
- Updated to 4.0.2-1 - Updated to 4.0.2-1
* Sat Jul 21 2007 Tom Eastep tom@shorewall.net * Sat Jul 21 2007 Tom Eastep tom@shorewall.net