Centralize handling of MACs in the Chains module

This commit is contained in:
Tom Eastep 2011-02-14 15:34:11 -08:00
parent 0fa027802f
commit 4ad9a83996
2 changed files with 29 additions and 25 deletions

View File

@ -108,7 +108,6 @@ sub process_accounting_rule( ) {
our $jumpchainref = 0; our $jumpchainref = 0;
our %accountingjumps; our %accountingjumps;
my $hasmac;
my ($action, $chain, $source, $dest, $proto, $ports, $sports, $user, $mark, $ipsec, $headers ) = split_line1 1, 11, 'Accounting File', $accounting_commands; my ($action, $chain, $source, $dest, $proto, $ports, $sports, $user, $mark, $ipsec, $headers ) = split_line1 1, 11, 'Accounting File', $accounting_commands;
@ -210,8 +209,6 @@ sub process_accounting_rule( ) {
if ( $source eq 'any' || $source eq 'all' ) { if ( $source eq 'any' || $source eq 'all' ) {
$source = ALLIP; $source = ALLIP;
} else {
fatal_error "MAC addresses not are not allowed in the OUTPUT section" if $hasmac = ( $source =~ /~/ ) && $asection == OUTPUT;
} }
if ( have_bridges && ! $asection ) { if ( have_bridges && ! $asection ) {
@ -220,7 +217,6 @@ sub process_accounting_rule( ) {
if ( $source =~ /^$fw:?(.*)$/ ) { if ( $source =~ /^$fw:?(.*)$/ ) {
$source = $1 ? $1 : ALLIP; $source = $1 ? $1 : ALLIP;
$restriction = OUTPUT_RESTRICT; $restriction = OUTPUT_RESTRICT;
fatal_error "MAC addresses are not allowed in an unsectioned accounting file" if $restriction & OUTPUT || $source =~ /~/;
$chain = 'accountout' unless $chain and $chain ne '-'; $chain = 'accountout' unless $chain and $chain ne '-';
$dest = ALLIP if $dest eq 'any' || $dest eq 'all'; $dest = ALLIP if $dest eq 'any' || $dest eq 'all';
} else { } else {
@ -270,15 +266,17 @@ sub process_accounting_rule( ) {
warning_message "Adding rule to unreferenced accounting chain $chain" unless reserved_chain_name( $chain ); warning_message "Adding rule to unreferenced accounting chain $chain" unless reserved_chain_name( $chain );
$chainref->{ipsec} = $dir; $chainref->{ipsec} = $dir;
} }
} elsif ( $ipsec ne '-' ) { } else {
fatal_error "$chain is not an accounting chain" unless $chainref->{accounting};
if ( $ipsec ne '-' ) {
$dir = $chainref->{ipsec}; $dir = $chainref->{ipsec};
fatal_error "Adding an IPSEC rule into a non-IPSEC chain is not allowed" unless $dir; fatal_error "Adding an IPSEC rule into a non-IPSEC chain is not allowed" unless $dir;
$rule .= do_ipsec( $dir , $ipsec ); $rule .= do_ipsec( $dir , $ipsec );
} elsif ( $asection ) { } elsif ( $asection ) {
$restriction |= $chainref->{restriction}; $restriction |= $chainref->{restriction};
} }
}
$chainref->{restricted} |= INPUT_RESTRICT if $hasmac;
if ( $jumpchainref ) { if ( $jumpchainref ) {
if ( $asection ) { if ( $asection ) {

View File

@ -2802,8 +2802,8 @@ sub mysplit( $ );
# #
# Match a Source. # Match a Source.
# #
sub match_source_net( $;$ ) { sub match_source_net( $;$\$ ) {
my ( $net, $restriction) = @_; my ( $net, $restriction, $macref ) = @_;
$restriction |= NO_RESTRICT; $restriction |= NO_RESTRICT;
@ -2814,7 +2814,8 @@ sub match_source_net( $;$ ) {
validate_range $addr1, $addr2; validate_range $addr1, $addr2;
iprange_match . "${invert}--src-range $net "; iprange_match . "${invert}--src-range $net ";
} elsif ( $net =~ /^!?~/ ) { } elsif ( $net =~ /^!?~/ ) {
fatal_error "MAC address cannot be used in this context" if $restriction >= OUTPUT_RESTRICT; fatal_error "A MAC address($net) cannot be used in this context" if $restriction >= OUTPUT_RESTRICT;
$$macref = 1 if $macref;
mac_match $net; mac_match $net;
} elsif ( $net =~ /^(!?)\+[a-zA-Z][-\w]*(\[.*\])?/ ) { } elsif ( $net =~ /^(!?)\+[a-zA-Z][-\w]*(\[.*\])?/ ) {
require_capability( 'IPSET_MATCH' , 'ipset names in Shorewall configuration files' , '' ); require_capability( 'IPSET_MATCH' , 'ipset names in Shorewall configuration files' , '' );
@ -3589,6 +3590,7 @@ sub expand_rule( $$$$$$$$$$;$ )
my $chain = $chainref->{name}; my $chain = $chainref->{name};
my $table = $chainref->{table}; my $table = $chainref->{table};
my $jump = $target ? '-j ' . $target : ''; my $jump = $target ? '-j ' . $target : '';
my $mac;
our @ends = (); our @ends = ();
# #
@ -3639,7 +3641,9 @@ sub expand_rule( $$$$$$$$$$;$ )
if ( $source eq '-' ) { if ( $source eq '-' ) {
$source = ''; $source = '';
} elsif ( $family == F_IPV4 ) { } elsif ( $family == F_IPV4 ) {
if ( $source =~ /^(.+?):(.+)$/ ) { if ( $source =~ /^~/ ) {
$inets = $source;
} elsif ( $source =~ /^(.+?):(.+)$/ ) {
$iiface = $1; $iiface = $1;
$inets = $2; $inets = $2;
} elsif ( $source =~ /\+|&|~|\..*\./ ) { } elsif ( $source =~ /\+|&|~|\..*\./ ) {
@ -3904,7 +3908,7 @@ sub expand_rule( $$$$$$$$$$;$ )
fatal_error "SOURCE interface may not be specified with a source IP address in the POSTROUTING chain" if $restriction == POSTROUTE_RESTRICT && $iiface && ( $inets ne ALLIP || $iexcl || $trivialiexcl); fatal_error "SOURCE interface may not be specified with a source IP address in the POSTROUTING chain" if $restriction == POSTROUTE_RESTRICT && $iiface && ( $inets ne ALLIP || $iexcl || $trivialiexcl);
fatal_error "DEST interface may not be specified with a destination IP address in the PREROUTING chain" if $restriction == PREROUTE_RESTRICT && $diface && ( $dnets ne ALLIP || $dexcl || $trivialdexcl); fatal_error "DEST interface may not be specified with a destination IP address in the PREROUTING chain" if $restriction == PREROUTE_RESTRICT && $diface && ( $dnets ne ALLIP || $dexcl || $trivialdexcl);
my ( $fromref, $done ); my ( $fromref, $mac, $done );
if ( $iexcl || $dexcl || $oexcl ) { if ( $iexcl || $dexcl || $oexcl ) {
# #
@ -3927,7 +3931,7 @@ sub expand_rule( $$$$$$$$$$;$ )
for ( mysplit $iexcl ) { for ( mysplit $iexcl ) {
my $cond = conditional_rule( $chainref, $_ ); my $cond = conditional_rule( $chainref, $_ );
add_rule $chainref, ( match_source_net $_ , $restriction ) . $exclude; add_rule $chainref, ( match_source_net $_ , $restriction, $mac ) . $exclude;
conditional_rule_end( $chainref ) if $cond; conditional_rule_end( $chainref ) if $cond;
} }
@ -3966,10 +3970,10 @@ sub expand_rule( $$$$$$$$$$;$ )
my $cond = conditional_rule( $chainref, $inet ); my $cond = conditional_rule( $chainref, $inet );
my $source_match = match_source_net( $inet, $restriction ) if have_capability( 'KLUDGEFREE' ); my $source_match = match_source_net( $inet, $restriction, $mac ) if have_capability( 'KLUDGEFREE' );
for my $dnet ( mysplit $dnets ) { for my $dnet ( mysplit $dnets ) {
$source_match = match_source_net( $inet, $restriction ) unless have_capability( 'KLUDGEFREE' ); $source_match = match_source_net( $inet, $restriction, $mac ) unless have_capability( 'KLUDGEFREE' );
add_jump( $chainref, $echainref, 0, join( '', $rule, $source_match, match_dest_net( $dnet ), $onet ), 1 ); add_jump( $chainref, $echainref, 0, join( '', $rule, $source_match, match_dest_net( $dnet ), $onet ), 1 );
} }
@ -3983,7 +3987,7 @@ sub expand_rule( $$$$$$$$$$;$ )
# #
for ( mysplit $iexcl ) { for ( mysplit $iexcl ) {
my $cond = conditional_rule( $echainref, $_ ); my $cond = conditional_rule( $echainref, $_ );
add_rule $echainref, ( match_source_net $_ , $restriction ) . '-j RETURN'; add_rule $echainref, ( match_source_net $_ , $restriction, $mac ) . '-j RETURN';
conditional_rule_end( $echainref ) if $cond; conditional_rule_end( $echainref ) if $cond;
} }
@ -4033,10 +4037,10 @@ sub expand_rule( $$$$$$$$$$;$ )
my $cond = conditional_rule( $chainref, $inet ); my $cond = conditional_rule( $chainref, $inet );
$source_match = match_source_net( $inet, $restriction ) if have_capability( 'KLUDGEFREE' ); $source_match = match_source_net( $inet, $restriction, $mac ) if have_capability( 'KLUDGEFREE' );
for my $dnet ( mysplit $dnets ) { for my $dnet ( mysplit $dnets ) {
$source_match = match_source_net( $inet, $restriction ) unless have_capability( 'KLUDGEFREE' ); $source_match = match_source_net( $inet, $restriction, $mac ) unless have_capability( 'KLUDGEFREE' );
my $dest_match = match_dest_net( $dnet ); my $dest_match = match_dest_net( $dnet );
my $matches = join( '', $rule, $source_match, $dest_match, $onet ); my $matches = join( '', $rule, $source_match, $dest_match, $onet );
@ -4094,6 +4098,8 @@ sub expand_rule( $$$$$$$$$$;$ )
conditional_rule_end( $chainref ) if $cond; conditional_rule_end( $chainref ) if $cond;
} }
} }
$chainref->{restricted} |= INPUT_RESTRICT if $mac;
# #
# Mark Target as referenced, if it's a chain # Mark Target as referenced, if it's a chain
# #