### Copyright (C) 1997 John D. Hardin
### This program is free software; you can redistribute it and/or modify
### it under the terms of the GNU General Public License as published by
### the Free Software Foundation; either version 2 of the License, or
### (at your option) any later version.
###
### 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.

### $Id: general.template,v 2.30 1999-05-24 12:33:28-07 jhardin Exp $


proc general {} {
    # General Settings

    Desc "General firewall settings"

    ShortDesc "General settings"

    Header head1 -text "          General firewall settings          "\
	    -background gray\
	    -help "Settings that determine the general character of the firewall configuration."

    Label label1 -text "Firewall support"\
            -textafter "compiled into the kernel."\
	    -default "is"\
	    -packFrame:anchor center \
	    -help "Firewall support must be compiled into the kernel. If it is not,"\
	    "then you must configure and build a new kernel; see the Kernel HOWTO for"\
	    "instructions."

    Label label2 -default "" -packFrame:anchor center

    Line line1

    Radio defaultpolicy -text "What is the default firewall policy?"\
	    -defaultIndex 0\
	    -entryhelp {"Deny" "Unless explicitly accepted, packets will be discarded."\
	    "Accept" "Unless explicitly blocked, packets will be accepted. (see below)"\
	    }\
	    -help "The preferred policy from a security standpoint is to discard packets"\
	    "unless they are explicitly accepted."\
	    "This allows you to tightly control the access others have to your network, but"\
	    "requires more administration and a greater understanding of the services being used.\n"\
	    "If you are running on a computer with little or no critical information and only dialup"\
	    "access to the Internet, you can probably safely set your default policy to \"allow\".\n"\
	    "This default policy will apply to packets originating on your local network as well as"\
	    "those originating from the Internet."\
	    -packFrame:fill x

    CheckBox blockinettcp -text "Default deny TCP traffic on the Internet interface?"\
            -default 1\
	    -help "The default policy is Accept. If you wish to increase security by making \"Deny\" the default"\
	    "policy for TCP packets on the Internet interface *only*, check this box. You will then have to"\
	    "explicitly list the TCP traffic to allow over the Internet interface."

    CheckBox blockinetudp -text "Default deny UDP traffic on the Internet interface?"\
            -default 1\
	    -help "The default policy is Accept. If you wish to increase security by making \"Deny\" the default"\
	    "policy for UDP packets on the Internet interface *only*, check this box. You will then have to"\
	    "explicitly list the UDP traffic to allow over the Internet interface."

    CheckBox outboundtraceroute -text "Allow outbound traceroute packets?"\
            -default 1\
	    -help "Traceroute sends UDP packets to (hopefully) unused UDP ports. If you're blocking UDP traffic"\
	    "then traceroute won't work.\n\nThis option allows outbound UDP packets to the port range traceroute"\
	    "defaults to using (33434-33523)."\
	    "\n\nIf traceroute on your system uses a different UDP port range, you'll have to manually edit the"\
	    "generated file."

    CheckBox inboundtraceroute -text "Allow inbound traceroute packets?"\
            -default 0\
	    -help "Traceroute sends UDP packets to (hopefully) unused UDP ports. If you're blocking UDP traffic"\
	    "then traceroute won't work.\n\nThis option allows inbound UDP packets to the port range traceroute"\
	    "defaults to using (33434-33523)."\
	    "\n\nYou probably shouldn't allow this unless you are trying to troubleshoot a problem, and then only"\
	    "for as long as you're troubleshooting - then turn it back off."

    Line line2

    Label label3 -text "Local network" -default "" -packFrame:anchor center 

    Label label3a -text "Internet" -default "" -packFrame:anchor center 

    Label label4 -text "IP Forwarding support"\
            -textafter "compiled into the kernel."\
	    -default "is"\
	    -packFrame:anchor center \
	    -help "Forwarding support must be compiled into the kernel if you wish to transfer"\
	    "packets between the local network and the Internet. If it is not,"\
	    "then you must configure and build a new kernel; see the Kernel HOWTO for"\
	    "instructions."


    CheckBox classmask -text "Use default class mask for local network" -default 0 \
	-packFrame:anchor center \
        -help \
	    "Your local network is a Private-Address network, and you have subnetted it."\
	    "This means that rules are being generated only for the subnet that your firewall"\
	    "is directly attached to. This can lead to incomplete support of hosts on other"\
            "subnets of your local network."\
	    "\n\nIf you check this checkbox, the rules will for be the entire Private-Address space."\
            "\n\nFor example, if your local network is 10.1.0.0/255.255.0.0, hosts on the 10.2.0.0 subnet"\
            "may have problems getting through the firewall. Checking this checkbox will make the local"\
            "network rules test 10.0.0.0/255.0.0.0 instead of 10.1.0.0/255.255.0.0"

    CheckBox antispoof -text "Enable anti-spoofing" -default 1 \
	-packFrame:anchor center \
        -help \
	    "\"Spoofing\" is when someone alters a packet they are sending over the Internet to your network"\
	    "so that it appears to have come from your local network rather than from the Internet."\
	    "This can make them appear to be on your local network even though they aren't."\
	    "\n\nIf you enable anti-spoofing, the firewall will discard any packet that comes in from the Internet"\
            "with its source address set to an address on your local net."\
	    "\n\nYou do not need to set this option if your local network uses one of the networks reserved"\
	    "for private use by RFC1597, as rules to block those addresses from the Internet are always generated."

    CheckBox blockXall -text "Block all traffic to X server" -default 1 \
	-packFrame:anchor center \
        -help \
	    "This will block all traffic from the Internet to X servers on your local network."\
            "It may occasionally cause other services (such as FTP and WWW requests) to fail"\
            "if the client happens to open an unused port in the range normally used by the X server."

    CheckBox blockXftp -text "Block FTP to X server traffic" -default 1 \
	-packFrame:anchor center \
        -help \
	    "If you allow FTP traffic through your firewall, it is possible for a poorly-administered system"\
	    "to send traffic from their FTP-data port (port 20) to your X Window server (port 6000:6005)"\
	    "and crash your X server."\
	    "\n\nThis will block traffic from the ftp-data port on Internet hosts to X servers on your local network."\
            "It may occasionally cause FTP transfers to fail if the FTP client happens to open an unused port"\
            "in the range normally used by the X server."


    ShowPage {
        global LocalEth
    	global LocalNetIP
	global LocalNetMask
        global InetEth
	if {$LocalNetIP == "" || $LocalNetMask == "" || $LocalNetIP == "Unknown" || $LocalNetMask == "Unknown"} {
	  if {$label3 == ""} {
	    set label3 "not detected."
	    Help label3 "A local network on $LocalEth could not be detected. IP Masquerade configuration will"\
	      "not be offered.\n"\
	      "This version of the ipfwadm dotfile module does not support SLIP- or PPP-based local networks." 
	  }
	  Disable classmask
          set classmask 0
	  Disable antispoof
	  set antispoof 0
	} else {
	  set label3 "detected on $LocalEth: $LocalNetIP/$LocalNetMask"
          if { [IsAddressPrivate "$LocalNetIP/$LocalNetMask"] } {
            # this is more complex than it needs to be - I still don't have the hang
            # of expression quoting in Tcl... Bleah.
            if { [MaskNetwork "$LocalNetIP/8"] == "10.0.0.0" && [LookUpMaskBits $LocalNetMask] > 8 } {
              Enable classmask
            } elseif { [MaskNetwork "$LocalNetIP/12"] == "172.16.0.0" && [LookUpMaskBits $LocalNetMask] > 12 } {
              Enable classmask
            } elseif { [MaskNetwork "$LocalNetIP/16"] == "192.168.0.0" && [LookUpMaskBits $LocalNetMask] > 16 } {
              Enable classmask
            } else {
              Disable classmask
              set classmask 0
            }
          } else {
            Disable classmask
            set classmask 0
          }
          if {${isp@on_internet}} {
	    Enable antispoof
            Enable blockXall
            if {$blockXall} {
              set blockXftp 0
              Disable blockXftp
            } else {
              Enable blockXftp
            }
          } else {
	    Disable antispoof
            Disable blockXftp
            Disable blockXall
          }
        }

    	global InternetIP
	global InternetMask
	    set label3a "$InternetIP/$InternetMask"
	if { $InternetIP == "" || $InternetMask == "" || $InternetIP == "Unknown" || $InternetMask == "Unknown" } {
	  set label3a "not detected."
	} else {
	  set label3a "possibly detected on $InetEth: $InternetIP/$InternetMask"
	}

        global FirewallInKernel
        if {$FirewallInKernel == 0} {
	  # Firewall support not compiled into kernel
	  # can we pop a warning box?
	  set label1 "is not"
          Disable defaultpolicy
	  Disable blockinettcp
	  Disable blockinetudp
	  Disable outboundtraceroute
	  Disable inboundtraceroute
        } else {
          if {$defaultpolicy(index) == 1} {
	    Enable blockinettcp
	    Enable blockinetudp
	    Enable outboundtraceroute
	    Enable inboundtraceroute
	  } else {
	    Disable blockinettcp
	    Disable blockinetudp
	    Disable outboundtraceroute
	    Disable inboundtraceroute
	  }
	}

    	global IPFWADM
	if {$IPFWADM == ""} {
	  if {$label2 == ""} {
	    set label2 "ipfwadm could not be found.\nThe firewall configuration file cannot be generated."
	    Help label2 "For security purposes, this module needs to know the complete path to the ipfwadm command."\
	  	"It couldn't be found, so it's either not installed or not on your PATH."\
		"\nIf ipfwadm is installed, then either run this dotfile module as root (not recommended)"\
		"or temporarily add the directory ipfwadm is in to your PATH."
	  }
	} else {
	  if {$label2 == ""} {
	    set label2 "ipfwadm found in $IPFWADM"
	    Help label2 "For security purposes, this module needs to know the complete path to the ipfwadm command."
	  }
	}

        global ForwardInKernel
        if {$ForwardInKernel == 0} {
	  # Firewall support not compiled into kernel
	  # can we pop a warning box?
	  set label4 "is not"
        }
    }

    Change {
      if {$defaultpolicy(index) == 1} {
	Enable blockinettcp
	Enable blockinetudp
	Enable outboundtraceroute
	Enable inboundtraceroute
      } else {
	Disable blockinettcp
	Disable blockinetudp
	Disable outboundtraceroute
	Disable inboundtraceroute
      }
      if {${isp@on_internet}} {
        if {$blockXall} {
          set blockXftp 0
          Disable blockXftp
        } else {
          Enable blockXftp
        }
      }
    }

    Save {
    	global IPFWADM
	if {$IPFWADM == ""} {
	  print "echo 'ipfwadm not found. Ensure it is installed and that it is on your PATH.'"
	  print "exit 1"
	} else {
          global LocalEth
    	  global LocalNetIP
	  global LocalNetMask
          global InetEth
	  global ISPPort
          set ISPPort ""
	  global DialdPort
	  set DialdPort ""
	  global UseIPUP
	  set UseIPUP 0
	  global InetIP
	  global InetIPValid
	  set InetIP ""
	  set InetIPValid 0
          if {${isp@on_internet}} {
	    set ISPTypeID [set isp@connection_type(index)]
          } else {
	    set ISPTypeID -1
	    print "# Standalone (not directly connected to the Internet)"
	    set ISPPort "-V $LocalNetIP -W $LocalEth"
	    set InetIP "$LocalNetIP/32"
            set InetIPValid 1
          }
          if {$ISPTypeID == 0} {
	    print "# dialup ISP via PPP, dynamic IP address"
	    print "# You may wish to add"
            print "#   \"echo 7 > /proc/sys/net/ipv4/ip_dynaddr\""
            print "# to your /etc/rc.d/rc.local - see"
	    print "# /usr/src/linux/Documentation/networking/ip_dynaddr.txt for details"
	    set ISPPort "-W ppp0"
	    # no way to know or determine at runtime - loose
	    set InetIP "\$ANY"
            set InetIPValid 0
          }
          if {$ISPTypeID == 1} {
	    print "# dialup ISP via PPP, dynamic IP address, diald"
	    print "# You may wish to add"
            print "#   \"echo 7 > /proc/sys/net/ipv4/ip_dynaddr\""
            print "# to your /etc/rc.d/rc.local - see"
	    print "# /usr/src/linux/Documentation/networking/ip_dynaddr.txt for details"
	    set ISPPort "-W ppp0"
	    # we should figure this out dynamically rather than hard coding it...
	    set DialdPort "-W sl0"
	    # no way to know or determine at runtime - loose
	    set InetIP "\$ANY"
            set InetIPValid 0
          }
          if {$ISPTypeID == 2} {
	    print "# dialup ISP via PPP, dynamic IP address"
	    print "# You may wish to add"
            print "#   \"echo 7 > /proc/sys/net/ipv4/ip_dynaddr\""
            print "# to your /etc/rc.d/rc.local - see"
	    print "# /usr/src/linux/Documentation/networking/ip_dynaddr.txt for details"
	    # fourth arg to ip-up is our Internet IP address, first is network device
	    set ISPPort "-V \$\{4\} -W \$\{1\}"
	    set UseIPUP 1
	    set InetIP "\$\{4\}/32"
            set InetIPValid 1
          }
          if {$ISPTypeID == 3} {
	    print "# dialup ISP via PPP, dynamic IP address, diald"
	    print "# You may wish to add"
            print "#   \"echo 7 > /proc/sys/net/ipv4/ip_dynaddr\""
            print "# to your /etc/rc.d/rc.local - see"
	    print "# /usr/src/linux/Documentation/networking/ip_dynaddr.txt for details"
	    # fourth arg to ip-up is our Internet IP address, first is network device
	    set ISPPort "-V \$\{4\} -W \$\{1\}"
	    set UseIPUP 1
	    # we should figure this out dynamically rather than hard coding it...
	    set DialdPort "-W sl0"
	    set UseIPUP 1
	    set InetIP "\$\{4\}/32"
            set InetIPValid 1
          }
          if {$ISPTypeID == 4} {
	    set ISPIP [set isp@ISPIP]
	    print "# dialup ISP via PPP, static IP address ($ISPIP)"
	    set ISPPort "-V $ISPIP"
	    set InetIP "$ISPIP/32"
            set InetIPValid 1
          }
          if {$ISPTypeID == 5} {
	    set ISPIP [set isp@ISPIP]
	    print "# dialup ISP via PPP, static IP address ($ISPIP)"
	    set ISPPort "-V $ISPIP"
	    # we should figure this out dynamically rather than hard coding it...
	    set DialdPort "-W sl0"
	    set InetIP "$ISPIP/32"
            set InetIPValid 1
          }
          if {$ISPTypeID == 6} {
	    set ISPPort "-W $InetEth"
	    if {${isp@ISPisDHCP}} {
	      print "# Multihomed (Internet on $InetEth, DHCP)"
	      print "# This firewall script must also be called from dhcpcd to reflect"
	      print "# possible changes in the IP address when the DHCP lease expires."
	      print "# Add \"-c /path/to/this-script\" to the dhcpcd command line, or"
	      print "# edit /etc/sysconfig/network-scripts/ifdhcpc-done and add a call"
	      print "# to this script if you're running RedHat."
	      print
	      print "# This code will extract the current IP address and net mask"
	      set dhcpinfo "/etc/dhcpc/hostinfo-$InetEth"
	      print "# from the dhcpc status file $dhcpinfo"
	      print
	      print "DHCP_IP=`grep -i '^IPADDR=' $dhcpinfo | tr -dc '.0-9'`"
	      print "DHCP_MASK=`grep -i '^NETMASK=' $dhcpinfo | tr -dc '.0-9'`"
	      print "export INET_NET=\"\$DHCP_IP/\$DHCP_MASK\""
	      set InetIP "\$DHCP_IP/32"
              set InetIPValid 1
	      # This may be wrong. We'll see...
	      print
	      print "# This code checks for a router specified by the DCHP server"
	      print "# and sets the default route to point at that router"
	      print
	      print "DHCP_GW=`grep -i '^ROUTER=' $dhcpinfo | tr -dc '.0-9'`"
	      print "\[ -n \"\$DHCP_GW\" ] && route add default gw \$DHCP_GW"
	      print
	    } else {
	      print "# Multihomed (Internet on $InetEth)"
	      # figure out the network address of $InetEth interface
              set inetethconfig ""
              catch {
                set inetethconfig [exec /sbin/ifconfig $InetEth]
              }
              if {[regexp {[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+} $inetethconfig]} {
                # the following will break, of course, should the output of ifconfig change radically
                # this script is based on the ifconfig in net-tools-1.32.alpha-2
	        set inetethIP ""
                regexp {inet addr:([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)} $inetethconfig junk inetethIP
	        set InetIP "$inetethIP/32"
                set InetIPValid 1
              } else {
	        print "# Unable to determine $InetEth IP address. Check hardware configuration."
	        print "# Firewall configuration will be loose."
	        set InetIP "\$ANY"
                set InetIPValid 0
              }
            }
          }
          if {$ISPTypeID == 7} {
	    print "# ISDN ISP via PPP, dynamic IP address"
	    set ISPPort "-W ippp0"
	    # no way to know or determine at runtime - loose
	    set InetIP "\$ANY"
            set InetIPValid 0
          }
          if {$ISPTypeID == 8} {
	    print "# ISDN ISP via PPP, dynamic IP address, diald"
	    set ISPPort "-W ippp0"
	    # we should figure this out dynamically rather than hard coding it...
	    set DialdPort "-W sl0"
	    # no way to know or determine at runtime - loose
	    set InetIP "\$ANY"
            set InetIPValid 0
          }
          if {$ISPTypeID == 9} {
	    set ISPIP [set isp@ISPIP]
	    print "# ISDN ISP via PPP, static IP address ($ISPIP)"
	    set ISPPort "-V $ISPIP"
	    set InetIP "$ISPIP/32"
            set InetIPValid 1
          }
          if {$ISPTypeID == 10} {
	    set ISPIP [set isp@ISPIP]
	    print "# ISDN ISP via PPP, static IP address ($ISPIP)"
	    set ISPPort "-V $ISPIP"
	    # we should figure this out dynamically rather than hard coding it...
	    set DialdPort "-W sl0"
	    set InetIP "$ISPIP/32"
            set InetIPValid 1
          }
          if {$ISPTypeID == 11} {
	    set ISPIP [set isp@ISPIP]
	    print "# ISP via SLIP, static IP address ($ISPIP)"
	    set ISPPort "-W sl0 -V $ISPIP"
	    set InetIP "$ISPIP/32"
            set InetIPValid 1
          }
          if {$ISPTypeID == 12} {
	    set ISPIP [set isp@ISPIP]
	    print "# ISP via SLIP, static IP address ($ISPIP)"
	    set ISPPort "-W sl1 -V $ISPIP"
	    # we should figure this out dynamically rather than hard coding it...
	    set DialdPort "-W sl0"
	    set InetIP "$ISPIP/32"
            set InetIPValid 1
          }
	  if {$ISPPort == ""} {
	    print "echo 'WARNING! Internal error in ipfwadm module for dotfile.' >&2"
	    print "echo 'Please contact the author with the following information:' >&2"
	    print "echo '\$connection_type(index) of" $ISPTypeID "is not supported.' >&2"
	    print "exit 1"
	  } else {
	    if {$UseIPUP} {
	      print "# NOTICE: This file must be placed in or called by /etc/ppp/ip-up."
              print "#"
              print "# It is suggested that you put this script in /etc/ppp/firewall to make"
              print "# maintenance easier, and call it from within /etc/ppp/ip-up:"
	      print "#"
	      print "#     . /etc/ppp/firewall"
	      print "#"
	      print "# If you are supporting inbound PPP users you may want to use the \"ipparam\""
	      print "# option on the pppd command line you use to connect to your ISP, then put"
	      print "# the firewall call inside an if-then like:"
	      print "#     if \[ \"\$6\" = \"whatever-flag-you-choose\" ]"
	      print "#     then"
              print "#       . /etc/ppp/firewall"
	      print "#     fi"
	      print "# so that user dialins don't mess with the firewall setup."
              print "#"
              print "# see http://www.wolfenet.com/~jhardin/ipfwadm/invocation.html for details"
	      print "#"
	      print
	    }

	    print "# Initialization"
	    print
	    print "# Define some variables to make things a bit clearer below"
	    print "# Any system anywhere"
	    print "export ANY=\"0.0.0.0/0\""
	    print "# The Internet connection"
	    print "export INET=\"$ISPPort\""
	    if { $LocalNetIP != "" } {
	      print "# The local network port"
	      print "export LETH=\"-V $LocalNetIP -W $LocalEth\""
	      print "# The local network"
              if { [IsAddressPrivate "$LocalNetIP/$LocalNetMask"] && $classmask } {
                if { [MaskNetwork "$LocalNetIP/8"] == "10.0.0.0" } {
	          print "export LNET=\"10.0.0.0/8\""
                } elseif { [MaskNetwork "$LocalNetIP/12"] == "172.16.0.0" } {
	          print "export LNET=\"172.16.0.0/12\""
                } elseif { [MaskNetwork "$LocalNetIP/16"] == "192.168.0.0" } {
	          print "export LNET=\"192.168.0.0/16\""
                }
              } else {
	        print "export LNET=\"[MaskNetwork "$LocalNetIP/$LocalNetMask"]/$LocalNetMask\""
              }
	      print "# The firewall (this system on the local network)"
	      print "export FWALL=\"$LocalNetIP/32\""
              print "# The local network broadcast address"
              print "export LBC=\"[BroadcastAddress "$LocalNetIP/$LocalNetMask"]/32\""
	    }
	    if { $InetIP != "" } {
	      print "# The firewall's Internet address (if known or determinable)"
	      print "export INET_IP=\"$InetIP\""
	    }
	    print "# Some ipfwadm flags for the TCP protocol"
	    print "export OpenNewConn=\"-y\""
	    print "export ConnEstablished=\"-k\""
	    print
            print "# Set default policy"
	    if {$defaultpolicy(index) == 1} {
              # default policy: ALLOW
	      if {$blockinettcp} {
	        print "# NOTE: default for Internet TCP traffic is DENY (see below)"
	      }
	      if {$blockinetudp} {
	        print "# NOTE: default for Internet UDP traffic is DENY (see below)"
	      }
              print "# default deny until firewall setup is completed..."
	      print $IPFWADM "-I -p deny"
	      print $IPFWADM "-O -p deny"
	      if {${masq@masquerade} && ${isp@on_internet}} {
	        print
	        print "# Default forwarding policy set to DENY due to masquerading."
	        print "# It is strongly recommended you not change this,"
	        print "# because if you masquerade and forward by default,"
	        print "# then you can also masquerade traffic coming FROM the"
	        print "# Internet and thus contribute to cracking attempts"
	        print "# against both your site and others."
	        print "# If this masquerading firewall also needs to forward"
	        print "# traffic without masquerading, you'll need to hand-enter"
	        print "# the forwarding rules (for now)."
              }
	      print $IPFWADM "-F -p deny"
	    } else {
              # default policy: DENY
	      print $IPFWADM "-I -p deny"
	      print $IPFWADM "-O -p deny"
	      print $IPFWADM "-F -p deny"
	    }
	    print
	    print "# Reset to known state"
	    print $IPFWADM "-I -f           # flush existing input rules"
	    print $IPFWADM "-O -f           # flush existing output rules"
	    print $IPFWADM "-F -f           # flush existing forwarding rules"

          }
        }
    }
}
