diff --git a/Shorewall/compiler b/Shorewall/compiler index e97055370..437964eda 100755 --- a/Shorewall/compiler +++ b/Shorewall/compiler @@ -2300,18 +2300,14 @@ process_rule() # $1 = target validate_zone $clientzone || fatal_error "Undefined Client Zone in rule \"$rule\"" - # Parse and validate destination - source=$clientzone - if [ $source = $FW ]; then - source_hosts= - elif [ -n "$userspec" ]; then + if [ $source != $FW -a -n "$userspec" ]; then fatal_error "Invalid use of a user-qualification: rule \"$rule\"" - else - eval source_hosts=\"\$${source}_hosts\" fi + # Parse and validate destination + if [ "$servers" = "${servers%:*}" ] ; then serverzone="$servers" servers= @@ -3021,7 +3017,7 @@ process_tos_rule() { esac for dest in $dst; do - dest="$(dest_ip_range $dest)" + dest=$(match_dest $dest) case $srczone in $FW) @@ -3039,10 +3035,10 @@ process_tos_rule() { run_iptables2 -t mangle -A pretos $src \ $protocol $dest $dports $sports $tos else - eval interfaces=\$${srczone}_interfaces + eval hosts=\$${srczone}_hosts - for interface in $interfaces; do - run_iptables2 -t mangle -A pretos -i $interface \ + for host in $hosts; do + run_iptables2 -t mangle -A pretos $(match_source $host) \ $protocol $dest $dports $sports $tos done fi diff --git a/Shorewall/lib.config b/Shorewall/lib.config index cab5147b6..f83fca983 100644 --- a/Shorewall/lib.config +++ b/Shorewall/lib.config @@ -591,7 +591,7 @@ validate_hosts_file() { ;; *.*.*) ;; - *+|+*) + *+|+*|*!*) eval ${z}_is_complex=Yes ;; *) @@ -604,7 +604,7 @@ validate_hosts_file() { case $host in *.*.*) ;; - *+) + *+|*!*) eval ${z}_is_complex=Yes ;; *) @@ -827,6 +827,105 @@ physdev_echo() fi } +# +# Source IP range +# +source_ip_range() # $1 = Address or Address Range +{ + [ $# -gt 0 ] && case $1 in + *.*.*.*-*.*.*.*) + case $1 in + !*) + iprange_echo "! --src-range ${1#!}" + ;; + *) + iprange_echo "--src-range $1" + ;; + esac + ;; + !+*) + echo "-m set ! $(get_set_flags ${1#!} src)" + ;; + +*) + echo "-m set $(get_set_flags $1 src)" + ;; + *) + echo "-s $1" + ;; + esac +} + +# +# Destination IP range +# +dest_ip_range() # $1 = Address or Address Range +{ + [ $# -gt 0 ] && case $1 in + *.*.*.*-*.*.*.*) + case $1 in + !*) + iprange_echo "! --dst-range ${1#!}" + ;; + *) + iprange_echo "--dst-range $1" + ;; + esac + ;; + !+*) + echo "-m set ! $(get_set_flags ${1#!} dst)" + ;; + +*) + echo "-m set $(get_set_flags $1 dst)" + ;; + *) + echo "-d $1" + ;; + esac +} + +both_ip_ranges() # $1 = Source address or range, $2 = dest address or range +{ + local rangeprefix= setprefix= rangematch= setmatch= + + case $1 in + *.*.*.*-*.*.*.*) + rangeprefix="-m iprange" + rangematch="--src-range $1" + ;; + !+*) + setprefix="-m set" + setmatch="! $(get_set_flags ${1#!} src)" + ;; + +*) + setprefix="-m set" + setmatch="$(get_set_flags $1 src)" + ;; + *) + rangematch="-s $1" + ;; + esac + + case $2 in + *.*.*.*-*.*.*.*) + rangeprefix="-m iprange" + rangematch="$rangematch --dst-range $2" + ;; + !+*) + setprefix="-m set" + match="$setmatch ! $(get_set_flags ${2#!} dst)" + ;; + +*) + setprefix="-m set" + setmatch="$setmatch $(get_set_flags $2 dst)" + ;; + *) + rangematch="$rangematch -d $2" + ;; + esac + + echo "$rangeprefix $rangematch $setprefix $setmatch" +} + # # We allow hosts to be specified by IP address or by physdev. These two functions # are used to produce the proper match in a netfilter rule. @@ -868,6 +967,32 @@ match_dest_hosts() echo $(dest_ip_range $1) fi } +# +# Matches for either or :
+# +match_source() +{ + case "$1" in + *:*) + echo "-i ${1%%:*} $(match_source_hosts ${1#*:})" + ;; + *) + echo $(dest_ip_range $1) + ;; + esac +} + +match_dest() +{ + case "$1" in + *:*) + echo "-o ${1%%:*} $(match_dest_hosts ${1#*:})" + ;; + *) + echo $(dest_ip_range $1) + ;; + esac +} # # Similarly, the source or destination in a rule can be qualified by a device name. If @@ -1447,105 +1572,6 @@ strip_file_and_lib_load() # $1 = logical file name, $2 = library to load if the eval test -n \"\$LIB_${2}_LOADED\" } -# -# Source IP range -# -source_ip_range() # $1 = Address or Address Range -{ - [ $# -gt 0 ] && case $1 in - *.*.*.*-*.*.*.*) - case $1 in - !*) - iprange_echo "! --src-range ${1#!}" - ;; - *) - iprange_echo "--src-range $1" - ;; - esac - ;; - !+*) - echo "-m set ! $(get_set_flags ${1#!} src)" - ;; - +*) - echo "-m set $(get_set_flags $1 src)" - ;; - *) - echo "-s $1" - ;; - esac -} - -# -# Destination IP range -# -dest_ip_range() # $1 = Address or Address Range -{ - [ $# -gt 0 ] && case $1 in - *.*.*.*-*.*.*.*) - case $1 in - !*) - iprange_echo "! --dst-range ${1#!}" - ;; - *) - iprange_echo "--dst-range $1" - ;; - esac - ;; - !+*) - echo "-m set ! $(get_set_flags ${1#!} dst)" - ;; - +*) - echo "-m set $(get_set_flags $1 dst)" - ;; - *) - echo "-d $1" - ;; - esac -} - -both_ip_ranges() # $1 = Source address or range, $2 = dest address or range -{ - local rangeprefix= setprefix= rangematch= setmatch= - - case $1 in - *.*.*.*-*.*.*.*) - rangeprefix="-m iprange" - rangematch="--src-range $1" - ;; - !+*) - setprefix="-m set" - setmatch="! $(get_set_flags ${1#!} src)" - ;; - +*) - setprefix="-m set" - setmatch="$(get_set_flags $1 src)" - ;; - *) - rangematch="-s $1" - ;; - esac - - case $2 in - *.*.*.*-*.*.*.*) - rangeprefix="-m iprange" - rangematch="$rangematch --dst-range $2" - ;; - !+*) - setprefix="-m set" - match="$setmatch ! $(get_set_flags ${2#!} dst)" - ;; - +*) - setprefix="-m set" - setmatch="$setmatch $(get_set_flags $2 dst)" - ;; - *) - rangematch="$rangematch -d $2" - ;; - esac - - echo "$rangeprefix $rangematch $setprefix $setmatch" -} - # # Check that a mark value or mask is less that 256 or that it is less than 65536 and # that it's lower 8 bits are zero.