### 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: allowlocalfirewall.template,v 1.3 1999-05-24 13:18:54-07 jhardin Exp $


proc allowlocalfirewall {} {
    # Local Host Access to Firewall

    Desc "Local Host Access to Firewall"

    ShortDesc "Local Host Access to Firewall"

    Header head1 -text "Per-Local-Host Services Allowed on Firewall"\
            -background gray\
            -help "These are services you wish local hosts to be able to access on the firewall itself."\
            "Likely candidates are DNS, NTP, and SSH (for administration)."

    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 label6 -text "A local network"\
            -textafter "been detected."\
            -default "has not"\
            -packFrame:anchor center \
            -help "You must have a local network to control access permissions for computers on the local network..."

    CheckBox allowall -text "Allow all local network traffic to firewall" \
           -default 1 \
           -help "If you wish to control local host access to the firewall system itself,"\
                 "uncheck this checkbox and enter your list of permitted hosts and services below."

    Line line1

    CheckBox allhosts -text "All hosts" \
           -default 0 \
           -help "All hosts on local network."

    Entry hostIP -text "Local Host"\
            -help "The name or unique IP address of a computer on the local network."\
            "\n\nIf you provide a file name here, the IP addresses and netmasks will be retrieved"\
            "from that file at the time the firewall script is run. This allows you to modify the"\
            "list of local hosts permitted to access the Internet without having to"\
            "regenerate the firewall script; simply edit the IP address file and re-run the"\
            "generated firewall script."

    global ServiceList
    ComboBox allowservice -text "Service to allow"\
            -count 10\
            -help "Select a service from the list, or enter one in the form port#(:port#)/\[tcp|udp\]."\
              "For example, to allow HTTP requests, enter \"80/tcp\". See the file"\
              "/etc/services (from which this list was generated) for a list of services with some comments,"\
              "or consult your ISP."\
            -entries $ServiceList

    Line line2

    Frame frame1 -entries {allhosts hostIP}
    Frame frame2 -entries {frame1 allowservice line2} -orient top

    ExtEntry allowedhosts -entries frame2 -count 5

    ShowPage {
      Enable allowedhosts
      global FirewallInKernel
      if {$FirewallInKernel == 0} {
        set label1 "is not"
        Disable allowedhosts
      } else {
        set label1 "is"
      }
      global LocalNetIP
      if {$LocalNetIP == ""} {
        set label6 "has not"
        Disable allowedhosts
      } else {
        set label6 "has"
      }
      if {$allowall} {
        Disable allowedhosts
      } else {
	forevery allowedhosts {
          if {$allhosts(index) == 0} {
            Enable hostIP
          } else {
            Disable hostIP
          }
        }
      }
    }

    Change {
      if {$allowall} {
        Disable allowedhosts
      } else {
        Enable allowedhosts
	forevery allowedhosts {
          if {$allhosts(index) == 0} {
            Enable hostIP
          } else {
            Disable hostIP
          }
        }
      }
    }

    Save {
      global IPFWADM
      global ISPPort
      global InetIPValid
      global LocalNetIP
      global LocalNetMask
      global PERL
      global ParseIP
      global MatchService
      global MatchPort
      if {$IPFWADM == "" || $ISPPort == ""} {
        # nothing
      } else {
        if {$LocalNetIP == ""} {
          print "# No local network has been detected."
        } else {
          if {$allowall} {
            print "# Local hosts are permitted full access to the firewall."
          } else {
            print "# Local host access to the firewall is restricted..."

            forevery allowedhosts {

              # If host IP is actually a filename, then parse the IP addresses from the file
              set fromfile 0
              if {$allhosts} {
                set host "\$LNET"
              } else {
                if {[file exists $hostIP]} {
                  if {$PERL != ""} {
                    set fromfile 1
                    set host "\$IP_TO_ALLOW"
                    print
                    print "# process local host permissions from file $hostIP"
                    print "if \[ -s $hostIP ]"
                    print "then"
                    print "  $PERL -n -e '$ParseIP' $hostIP | \\"
                    print "  while read IP_TO_ALLOW"
                    print "  do"
                  } else {
                    print
                    print "# perl not found - cannot set local host rules from $hostIP."
                    print "# Install perl, then regenerate the firewall file."
                    # generate do-nothing rules
                    set host "0.0.0.0/32"
                  }
                } else {
                  set host "$hostIP/32"
                }
              }

              set service $allowservice
              if {[regexp "$MatchPort" $service junk port junk prot]} {
                set ACK [pick {$prot == "tcp"} " \$ConnEstablished" ""]
                # if there's a description before or after the port spec, retrieve it.
                set descr ""
                if {![regexp "^(\[ A-Za-z0-9\\-_\]+)\[ \t\]+" $service junk descr]} {
                  # not before. try after.
                  regexp "\[ \t(\]+(\[ A-Za-z0-9\\-_\]+)" $service junk descr
                }
                if {$descr != ""} {
                  set descr " ($descr)"
                }

                # specified host is SOURCE
                if {$prot == "icmp"} {
                  print "# Allow the firewall to receive ICMP message $port$descr from local host $host"
                  print $IPFWADM "-I -a accept \$LETH -P $prot -S $host $port -D \$FWALL"
                } else {
                  # TCP or UDP
                  print "# Allow the firewall to receive $prot port $port$descr from local host $host"
                  print $IPFWADM "-I -a accept \$LETH -P $prot -S $host -D \$FWALL $port"
                  print $IPFWADM "-O -a accept \$LETH -P $prot$ACK -D $host -S \$FWALL $port"
                }

                if {$prot == "tcp" && $port == "21"} {
                  # ftp service...
                  # add special handling for ftp-data "reverse connection"
                  # with type-of-service adjustment for bulk data
                  print "#  The previous was an FTP control channel - permit the FTP data channel,"
                  print "#  with Type-of-Service set to bulk data"
                  print $IPFWADM "-O -a accept \$LETH -P $prot -S \$FWALL 20 -D $host 1025:65535"
                  print $IPFWADM "-I -a accept \$LETH -P $prot$ACK -D \$FWALL 20 -S $host 1025:65535 -t 0xE1 0x08"
                }

              } else {
                print "# Syntax error on host $host: service \"$service\" unparseable."
                tk_dialog .warning "Warning" "Syntax error on host $host: service \"$service\" unparseable." info 0 OK
              }

              if {$fromfile != 0} {
                # finish up the shell script loop
                print "  done"
                print "fi"
                print
              }
            }

            print $IPFWADM "-I -a reject -o \$LETH -D \$FWALL -S \$ANY"
	    if {$InetIPValid == 1} {
              print $IPFWADM "-I -a reject -o \$LETH -S \$ANY -D \$INET_IP"
            }
          }
        }
      }
    }
}  
