Validate helper<->protocol

Signed-off-by: Tom Eastep <teastep@shorewall.net>
This commit is contained in:
Tom Eastep 2011-12-23 17:55:13 -08:00
parent 97354c8ce8
commit be4cb9d26a
4 changed files with 71 additions and 25 deletions

View File

@ -173,6 +173,7 @@ our %EXPORT_TAGS = (
do_tos do_tos
do_connbytes do_connbytes
do_helper do_helper
validate_helper
do_headers do_headers
do_condition do_condition
have_ipset_rules have_ipset_rules
@ -558,19 +559,19 @@ sub initialize( $$$ ) {
%ipset_exists = (); %ipset_exists = ();
%helpers = ( amanda => 1, %helpers = ( amanda => TCP,
ftp => 1, ftp => TCP,
h323 => 1, h323 => [UDP,TCP],
irc => 1, irc => TCP,
netbios_ns => 1, netbios_ns => [UDP,TCP],
netlink => 1, netlink => -1,
proto_gre => 1, proto_gre => GRE,
proto_sctp => 1, proto_sctp => SCTP,
pptp => 1, pptp => TCP,
proto_udplite => 1, proto_udplite => UDPLITE,
sane => 1, sane => TCP,
sip => 1, sip => UDP,
tftp => 1 ); tftp => UDP);
# #
# The chain table is initialized via a call to initialize_chain_table() after the configuration and capabilities have been determined. # The chain table is initialized via a call to initialize_chain_table() after the configuration and capabilities have been determined.
# #
@ -4004,22 +4005,56 @@ sub do_connbytes( $ ) {
} }
# #
# Create a soft "-m helper" match for the passed argument # Validate a helper/protocol pair
# #
sub do_helper( $ ) { sub validate_helper( $$ ) {
my $helper = shift; my ( $helper, $proto ) = @_;
my $helper_base = $helper;
$helper_base =~ s/-\d+$//;
my $protos = $helpers{$helper_base};
if ( $protos) {
#
# Recognized helper
#
my $protonum = resolve_proto( $proto );
#
# Caller should have called do_proto() before this function
#
assert( defined $protonum );
my $found;
if ( reftype $protos ) {
for ( @$protos ) {
$found |= ($_ == $protonum);
}
} elsif ( $protos == -1 ) {
$found = 1;
} else {
$found = ( $protos == $protonum );
}
fatal_error "Protocol $proto is not appropriate for helper $helper_base" unless $found;
} else {
warning_message "Unrecognized helper ($helper_base)";
}
}
#
# Create an "-m helper" match for the passed argument
#
sub do_helper( $$ ) {
my ( $helper, $proto ) = shift;
return '' if $helper eq '-'; return '' if $helper eq '-';
my $helper_base = $helper; validate_helper( $helper, $proto );
$helper_base =~ s/-\d+$//;
warning_message "Unrecognized helper ($helper)" unless $helpers{$helper_base};
qq(-m helper --helper "$helper" ) if defined wantarray; qq(-m helper --helper "$helper" ) if defined wantarray;
} }
# #
# Create a "-m length" match for the passed LENGTH # Create a "-m length" match for the passed LENGTH
# #

View File

@ -55,6 +55,7 @@ our @EXPORT = qw( ALLIPv4
DCCP DCCP
IPv6_ICMP IPv6_ICMP
SCTP SCTP
GRE
validate_address validate_address
validate_net validate_net
@ -117,6 +118,7 @@ use constant { ALLIPv4 => '0.0.0.0/0' ,
TCP => 6, TCP => 6,
UDP => 17, UDP => 17,
DCCP => 33, DCCP => 33,
GRE => 47,
IPv6_ICMP => 58, IPv6_ICMP => 58,
SCTP => 132, SCTP => 132,
UDPLITE => 136 }; UDPLITE => 136 };

View File

@ -59,6 +59,7 @@ sub process_notrack_rule( $$$$$$$ ) {
my $target = $action; my $target = $action;
my $exception_rule = ''; my $exception_rule = '';
my $rule = do_proto( $proto, $ports, $sports ) . do_user ( $user );
unless ( $action eq 'NOTRACK' ) { unless ( $action eq 'NOTRACK' ) {
( $target, my ( $option, $args, $junk ) ) = split ':', $action, 4; ( $target, my ( $option, $args, $junk ) ) = split ':', $action, 4;
@ -76,7 +77,7 @@ sub process_notrack_rule( $$$$$$$ ) {
if ( $option eq 'helper' ) { if ( $option eq 'helper' ) {
fatal_error "Invalid helper' ($args)" if $args =~ /,/; fatal_error "Invalid helper' ($args)" if $args =~ /,/;
fatal_error "A protocol protocol is required in CT:helper rules" if $proto eq '-'; fatal_error "A protocol protocol is required in CT:helper rules" if $proto eq '-';
do_helper( $args ); validate_helper( $args, $proto );
$action = "CT --helper $args"; $action = "CT --helper $args";
$exception_rule = do_proto( $proto, '-', '-' ); $exception_rule = do_proto( $proto, '-', '-' );
} elsif ( $option eq 'ctevents' ) { } elsif ( $option eq 'ctevents' ) {
@ -97,7 +98,7 @@ sub process_notrack_rule( $$$$$$$ ) {
expand_rule( $chainref , expand_rule( $chainref ,
$restriction , $restriction ,
do_proto( $proto, $ports, $sports ) . do_user ( $user ) , $rule,
$source , $source ,
$dest , $dest ,
'' , '' ,

View File

@ -488,7 +488,7 @@ sub process_tc_rule( ) {
do_length( $length ) . do_length( $length ) .
do_tos( $tos ) . do_tos( $tos ) .
do_connbytes( $connbytes ) . do_connbytes( $connbytes ) .
do_helper( $helper ) . do_helper( $helper, $proto ) .
do_headers( $headers ) , do_headers( $headers ) ,
$source , $source ,
$dest , $dest ,
@ -1451,7 +1451,15 @@ sub process_tc_priority() {
fatal_error "Invalid PRIORITY ($band)" unless $val && $val <= 3; fatal_error "Invalid PRIORITY ($band)" unless $val && $val <= 3;
my $rule = do_helper( $helper ) . "-j MARK --set-mark $band"; my $rule;
unless ( $helper eq '-' ) {
fatal_error( "A PROTO is required when a HELPER is specified" ) if $proto eq '-';
fatal_error( "Unknown protocol" ) unless defined resolve_protocol( $proto );
$rule = do_helper( $helper, $proto ) . "-j MARK --set-mark $band";
} else {
$rule = '';
}
$rule .= join('', '/', in_hex( $globals{TC_MASK} ) ) if have_capability( 'EXMARK' ); $rule .= join('', '/', in_hex( $globals{TC_MASK} ) ) if have_capability( 'EXMARK' );