### 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: denylocalhost.template,v 2.10 1998-09-14 17:06:18-07 jhardin Exp $


proc denylocalhosts {} {
    # Deny / Services (Per-Host, Local Hosts)

    Desc "Per-Local-Host Service Blocking"

    ShortDesc "Per-Local-Host Service Blocking"

    Header head1 -text "Per-Local-Host Service Blocking"\
	    -background gray\
	    -help "Services are things like Telnet for logins, SMTP for email, FTP for file transfer,"\
	    "HTTP for Webs, and so forth. Certain services you may want to provide even if your default"\
	    "policy is \"deny\", for example, HTTP to serve web pages."\

    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 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."

    Label label5 -text "Masquerading"\
            -textafter "been enabled."\
	    -default "has not"\
	    -packFrame:anchor center \
	    -help "If IP Masquerade is in use, then all local-net host controls must be configured in the"\
	    "Masquerade screen."

    Entry hostIP -text "Local Host"\
            -help "The name or unique IP address of a computer on the local network."

    global ServiceList
    ComboBox denyservice -text "Service to deny"\
	    -count 10\
	    -help "Select a service from the list, or enter one in the form port#(:port#)/\[tcp|udp\]."\
	      "For example, to deny 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

    Radio direction -defaultIndex 0\
	    -entryhelp {\
	    "Inbound" "Service requests coming in from host(s) on the Intenet."\
	    "Outbound" "Service requests going out to host(s) on the Internet."\
	    }

    Line line1

    Frame frame1 -entries {hostIP}
    Frame frame2 -entries {denyservice direction}
    Frame frame3 -entries {frame1 frame2 line1} -orient top

    ExtEntry deniedhosts -entries frame3 -count 5

    ShowPage {
      Enable deniedhosts
      global FirewallInKernel
      if {$FirewallInKernel == 0} {
	set label1 "is not"
	Disable deniedhosts
      } else {
	set label1 "is"
      }
      global ForwardInKernel
      if {$ForwardInKernel == 0} {
	set label4 "is not"
	Disable deniedhosts
      } else {
        set label4 "is"
      }
      if {${masq@masquerade} && ${isp@on_internet}} {
        set label5 "has"
	Disable deniedhosts
      } else {
        set label5 "has not"
      }
    }

    Save {
      global IPFWADM
      global ISPPort
      global LocalNetIP
      global LocalNetMask
      global PERL
      global ParseIP
      global MatchService
      global MatchPort
      if {$IPFWADM == "" || $ISPPort == ""} {
        # nothing
      } else {

	if {${masq@masquerade} && ${isp@on_internet}} {
	  print "# Masquerading is in use. Hosts on the local net will be controlled through"
	  print "# the masquerade options."
	} else {
	  if {$LocalNetIP == ""} {
	    print "# No local network has been detected."
	  } else {

            forevery deniedhosts {

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

              set service $denyservice
              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)"
                }

	        if {$direction(index) == 0} {		# inbound (specified host is DEST)
                  if {$prot == "icmp"} {
                    print "# Block ICMP message $port$descr to local host $host"
                    print $IPFWADM "-I -a deny -o \$INET -P $prot -S \$ANY $port -D $host"
                  } else {
	            if {$prot == "tcp" } {
                      print "# Allow established $prot port $port$descr traffic to local host $host"
                      print $IPFWADM "-I -a accept \$INET -P $prot \$ConnEstablished -S \$ANY -D $host $port"
		    }
                    print "# Block new $prot port $port$descr traffic to local host $host"
                    print $IPFWADM "-I -a deny -o \$INET -P $prot -S \$ANY -D $host $port"
                  }
	        } else {				# outbound (specified host is SOURCE)
                  if {$prot == "icmp"} {
                    print "# Block ICMP message $port$descr from local host $host"
                    print $IPFWADM "-O -a reject \$INET -P $prot -S $host $port -D \$ANY"
                  } else {
	            if {$prot == "tcp" } {
                      print "# Allow established $prot port $port$descr traffic from local host $host"
                      print $IPFWADM "-O -a accept \$INET -P $prot \$ConnEstablished -S $host -D \$ANY $port"
		    }
                    print "# Block new $prot port $port$descr traffic from local host $host"
                    print $IPFWADM "-O -a reject \$INET -P $prot -S $host -D \$ANY $port"
	          }
	        }

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

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