#!/bin/sh # # Shorewall 3.2 -- /usr/share/shorewall/clib.macros # # This program is under GPL [http://www.gnu.org/copyleft/gpl.htm] # # (c) 2005,2006 - Tom Eastep (teastep@shorewall.net) # # Complete documentation is available at http://shorewall.net # # This program is free software; you can redistribute it and/or modify # it under the terms of Version 2 of the GNU General Public License # as published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA # # This function maps old action names into their new macro equivalents # map_old_action() # $1 = Potential Old Action { local macro= aktion if [ -n "$MAPOLDACTIONS" ]; then case $1 in */*) echo $1 return ;; *) if [ -f $(find_file $1) ]; then echo $1 return fi case $1 in Allow*) macro=${1#*w} aktion=ACCEPT ;; Drop*) macro=${1#*p} aktion=DROP ;; Reject*) macro=${1#*t} aktion=REJECT ;; *) echo $1 return ;; esac esac if [ -f $(find_file macro.$macro) ]; then echo $macro/$aktion return fi fi echo $1 } # # Combine a source/dest from the macro body with one from the macro invocation # merge_macro_source_dest() # $1 = source/dest from macro body, $2 = source/dest from invocation { case $2 in -) echo ${1} ;; *.*.*|+*|~*|!~*) # # Value in the invocation is an address -- put it behind the value from the macro # echo ${1}:${2} ;; *) echo ${2}:${1} ;; esac } verify_macro_from_action() { temp=$(map_old_action $temp) case $temp in */*) param=${temp#*/} case $param in ACCEPT|DROP|REJECT|LOG|QUEUE|CONTINUE) ;; *) rule="$xtarget $xclients $xservers $xprotocol $xports $xcports $xratelimit $xuserspec" fatal_error "Invalid Macro Parameter in rule \"$rule\"" ;; esac temp=${temp%%/*} ;; esac f1=macro.${temp} fn=$(find_file $f1) if [ ! -f $TMP_DIR/$f1 ]; then # # We must only verify macros once to ensure that they don't invoke any non-standard actions # if [ -f $fn ]; then strip_file $f1 $fn progress_message " ..Expanding Macro $fn..." while read mtarget mclients mservers mprotocol mports mcports mratelimit muserspec; do expandv mtarget temp="${mtarget%%:*}" case "$temp" in ACCEPT|DROP|REJECT|LOG|QUEUE|CONTINUE|PARAM) ;; *) rule="$mtarget $mclients $mservers $mprotocol $mports $mcports $mratelimit $muserspec" fatal_error "Invalid TARGET in rule \"$rule\"" esac done < $TMP_DIR/$f1 progress_message " ..End Macro" else rule="$xtarget $xclients $xservers $xprotocol $xports $xcports $xratelimit $xuserspec" fatal_error "Invalid TARGET in rule \"$rule\"" fi fi } expand_macro_in_action() { xtarget1=$(map_old_action $xtarget1) case $xtarget1 in */*) param=${xtarget1#*/} xtarget1=${xtarget1%%/*} ;; esac progress_message "..Expanding Macro $(find_file macro.$xtarget1)..." while read mtarget mclients mservers mprotocol mports mcports mratelimit muserspec; do expandv mtarget mclients mservers mprotocol mports mcports mratelimit muserspec mtarget=$(merge_levels $xaction2 $mtarget) case $mtarget in PARAM|PARAM:*) [ -n "$param" ] && mtarget=$(substitute_action $param $mtarget) || fatal_error "PARAM requires that a parameter be supplied in macro invocation" ;; esac if [ -n "$mclients" ]; then case $mclients in -|SOURCE) mclients=${xclients} ;; DEST) mclients=${xservers} ;; *) mclients=$(merge_macro_source_dest $mclients $xclients) ;; esac else mclients=${xclients} fi if [ -n "$mservers" ]; then case $mservers in -|DEST) mservers=${xservers} ;; SOURCE) mservers=${xclients} ;; *) mservers=$(merge_macro_source_dest $mservers $xservers) ;; esac else mservers=${xserverss} fi [ -n "$xprotocol" ] && [ "x${xprotocol}" != x- ] && mprotocol=$xprotocol [ -n "$xports" ] && [ "x${xports}" != x- ] && mports=$xports [ -n "$xcports" ] && [ "x${xcports}" != x- ] && mcports=$xcports [ -n "$xratelimit" ] && [ "x${xratelimit}" != x- ] && mratelimit=$xratelimit [ -n "$xuserspec" ] && [ "x${xuserspec}" != x- ] && muserspec=$xuserspec rule="$mtarget ${mclients:=-} ${mservers:=-} ${mprotocol:=-} ${mports:=-} ${mcports:=-} ${mratelimit:-} ${muserspec:=-}" process_action $xchain $xaction1 $mtarget $mclients $mservers $mprotocol $mports $mcports $mratelimit $muserspec done < $TMP_DIR/macro.$xtarget1 progress_message "..End Macro" } # # Process a macro invocation in the rules file # process_macro() # $1 = target # $2 = param # $2 = clients # $3 = servers # $4 = protocol # $5 = ports # $6 = cports # $7 = address # $8 = ratelimit # $9 = userspec { local itarget="$1" local param="$2" local iclients="$3" local iservers="$4" local iprotocol="$5" local iports="$6" local icports="$7" local iaddress="$8" local iratelimit="$9" local iuserspec="${10}" progress_message "..Expanding Macro $(find_file macro.${itarget%%:*})..." while read mtarget mclients mservers mprotocol mports mcports mratelimit muserspec; do expandv mtarget mclients mservers mprotocol mports mcports mratelimit muserspec mtarget=$(merge_levels $itarget $mtarget) case $mtarget in PARAM|PARAM:*) [ -n "$param" ] && mtarget=$(substitute_action $param $mtarget) || fatal_error "PARAM requires that a parameter be supplied in macro invocation" ;; esac case ${mtarget%%:*} in ACCEPT|ACCEPT+|NONAT|DROP|REJECT|DNAT|DNAT-|REDIRECT|REDIRECT-|LOG|CONTINUE|QUEUE|SAME|SAME-) ;; *) if list_search ${mtarget%%:*} $ACTIONS; then if ! list_search $mtarget $USEDACTIONS; then createactionchain $mtarget USEDACTIONS="$USEDACTIONS $mtarget" fi mtarget=$(find_logactionchain $mtarget) else fatal_error "Invalid Action in rule \"$mtarget ${mclients:--} ${mservers:--} ${mprotocol:--} ${mports:--} ${mcports:--} ${xaddress:--} ${mratelimit:--} ${muserspec:--}\"" fi ;; esac if [ -n "$mclients" ]; then case $mclients in -|SOURCE) mclients=${iclients} ;; DEST) mclients=${iservers} ;; *) mclients=$(merge_macro_source_dest $mclients $iclients) ;; esac else mclients=${iclients} fi if [ -n "$mservers" ]; then case $mservers in -|DEST) mservers=${iservers} ;; SOURCE) mservers=${iclients} ;; *) mservers=$(merge_macro_source_dest $mservers $iservers) ;; esac else mservers=${iservers} fi [ -n "$iprotocol" ] && [ "x${iprotocol}" != x- ] && mprotocol=$iprotocol [ -n "$iports" ] && [ "x${iports}" != x- ] && mports=$iports [ -n "$icports" ] && [ "x${icports}" != x- ] && mcports=$icports [ -n "$iratelimit" ] && [ "x${iratelimit}" != x- ] && mratelimit=$iratelimit [ -n "$iuserspec" ] && [ "x${iuserspec}" != x- ] && muserspec=$iuserspec rule="$mtarget ${mclients=-} ${mservers:=-} ${mprotocol:=-} ${mports:=-} ${mcports:=-} ${xaddress:=-} ${mratelimit:=-} ${muserspec:=-}" process_rule $mtarget $mclients $mservers $mprotocol $mports $mcports ${iaddress:=-} $mratelimit $muserspec done < $TMP_DIR/macro.${itarget%%:*} progress_message "..End Macro" } CLIB_MACROS_LOADED=Yes