Example #1
0
    def __init__(self, name, nat, cacheable=TRUE):
        """
        <method maturity="stable">
          <summary>
            Constructor to initialize a NAT policy.
          </summary>
          <description>
            <para>
              This contructor initializes a NAT policy.
            </para>
          </description>
          <metainfo>
            <arguments>
              <argument>
                <name>name</name>
                <type>
                  <string/>
                </type>
                <description>Name identifying the NAT policy.</description>
              </argument>
              <argument>
                <name>nat</name>
                <type>
                  <class filter="nat" instance="yes"/>
                </type>
                <description>NAT object which performs address translation.</description>
              </argument>
              <argument>
                <name>cacheable</name>
                <type>
                  <boolean/>
                </type>
                <default>TRUE</default>
                <description>Enable this parameter to cache the NAT decisions.</description>
              </argument>
            </arguments>
          </metainfo>
        </method>
        """

        self.name = name
        self.nat = nat
        self.cacheable = cacheable
        if self.cacheable:
            self.nat_cache = ShiftCache('nat(%s)' % name, 1000)
        if Globals.nat_policies.has_key(name):
            raise ValueError, "Duplicate NATPolicy name: %s" % name
        Globals.nat_policies[name] = self
Example #2
0
 def __init__(self, bindto=None, services=None, **kw):
     """
     <method maturity="stable">
       <summary>Constructor to initialize a CSZoneDispatcher instance.</summary>
       <description>
         <para>
           This constructor initializes a CSZoneDispatcher instance and sets
           its initial attributes based on arguments.
         </para>
       </description>
       <metainfo>
         <arguments>
           <argument maturity="stable">
             <name>bindto</name>
             <type>
               <sockaddr existing="yes"/>
             </type>
            <description>An existing <link linkend="python.SockAddr">socket address</link> containing the IP address and port number where the Dispatcher accepts connections.</description>
            </argument>
           <argument maturity="stable">
             <name>services</name>
             <type>
               <hash>
                 <key>
                   <tuple>
                     <zone/>
                     <zone/>
                   </tuple>
                 </key>
                 <value>
                     <service/>
                 </value>
               </hash>
             </type>
             <guitype>HASH;STRING_zone,STRING_zone;STRING_service</guitype>
             <description>Client zone - server zone - service name pairs
             using the <parameter>(("client_zone","server_zone"):"service")</parameter>
             format; specifying the service to start when the dispatcher
             accepts a connection from the given
             client zone that targets the server zone.</description>
           </argument>
           <argument maturity="stable">
             <name>follow_parent</name>
             <type>
               <boolean/>
             </type>
             <description>Set this parameter to <parameter>TRUE</parameter>
             if the dispatcher handles also the connections coming from
             the child zones of the selected client zones. Otherwise,
             the dispatcher accepts traffic only from the explicitly
             listed client zones.</description>
           </argument>
         </arguments>
       </metainfo>
     </method>
     """
     self.follow_parent = kw.pop('follow_parent', FALSE)
     super(CSZoneDispatcher, self).__init__(bindto, None, **kw)
     self.services = services
     self.cache = ShiftCache('csdispatch(%s)' % str(self.bindto), config.options.zone_dispatcher_shift_threshold)
Example #3
0
 def __init__(self, bindto=None, services=None, **kw):
     """
     <method maturity="stable">
       <summary>Constructor to initialize a ZoneDispatcher instance.</summary>
       <description>
         <para>
           This constructor initializes a ZoneDispatcher instance and sets
           its initial attributes based on arguments.
         </para>
       </description>
       <metainfo>
         <arguments>
           <argument maturity="stable">
             <name>bindto</name>
             <type></type>
             <description>bind to this address</description>
           </argument>
           <argument maturity="stable">
             <name>services</name>
             <type></type>
             <description>a mapping between zone names and services</description>
           </argument>
           <argument maturity="stable">
             <name>follow_parent</name>
             <type></type>
             <description>whether to follow the administrative hieararchy when finding the correct service</description>
           </argument>
         </arguments>
       </metainfo>
     </method>
     """
     self.follow_parent = kw.pop('follow_parent', FALSE)
     super(ZoneDispatcher, self).__init__(bindto, None, **kw)
     self.services = services
     self.cache = ShiftCache('sdispatch(%s)' % str(bindto), config.options.zone_dispatcher_shift_threshold)
Example #4
0
	def __init__(self, name):
		"""
                <method internal="yes">
                </method>
		"""
		AbstractZone.__init__(self, name)
		self.domains = []
		self.cache = ShiftCache('zone', config.options.zone_cache_shift_threshold)
Example #5
0
    def __init__(self, bindto=None, services=None, **kw):
        """
        <method maturity="stable">
          <summary>Constructor to initialize a ZoneDispatcher instance.</summary>
          <description>
            <para>
              This constructor initializes a ZoneDispatcher instance and sets
              its initial attributes based on arguments.
            </para>
          </description>
          <metainfo>
            <arguments>
              <argument maturity="stable">
                <name>bindto</name>
                <type></type>
                <description>bind to this address</description>
              </argument>
              <argument maturity="stable">
                <name>services</name>
                <type></type>
                <description>a mapping between zone names and services</description>
              </argument>
              <argument maturity="stable">
                <name>follow_parent</name>
                <type></type>
                <description>whether to follow the administrative hieararchy when finding the correct service</description>
              </argument>
            </arguments>
          </metainfo>
        </method>
        """
        if (ZoneDispatcher.deprecated_warning):

            ZoneDispatcher.deprecated_warning = False
            log(
                None, CORE_DEBUG, 3,
                "Use of ZoneDispatcher class is deprecated, Rule should be used instead."
            )

        self.follow_parent = kw.pop('follow_parent', FALSE)
        super(ZoneDispatcher, self).__init__(bindto, None, **kw)
        self.services = services
        self.cache = ShiftCache('sdispatch(%s)' % str(bindto),
                                config.options.zone_dispatcher_shift_threshold)
Example #6
0
	def __init__(self, name, nat, cacheable=TRUE):
                """
                <method maturity="stable">
                  <summary>
                    Constructor to initialize a NAT policy.
                  </summary>
                  <description>
                    <para>
                      This contructor initializes a NAT policy.
                    </para>
                  </description>
                  <metainfo>
                    <arguments>
                      <argument>
                        <name>name</name>
                        <type>
                          <string/>
                        </type>
                        <description>Name identifying the NAT policy.</description>
                      </argument>
                      <argument>
                        <name>nat</name>
                        <type>
                          <class filter="nat" instance="yes"/>
                        </type>
                        <description>NAT object which performs address translation.</description>
                      </argument>
                      <argument>
                        <name>cacheable</name>
                        <type>
                          <boolean/>
                        </type>
                        <default>TRUE</default>
                        <description>Enable this parameter to cache the NAT decisions.</description>
                      </argument>
                    </arguments>
                  </metainfo>
                </method>
                """

		self.name = name
		self.nat = nat
		self.cacheable = cacheable
		if self.cacheable:
			self.nat_cache = ShiftCache('nat(%s)' % name, 1000)
		if Globals.nat_policies.has_key(name):
			raise ValueError, "Duplicate NATPolicy name: %s" % name
		Globals.nat_policies[name] = self
Example #7
0
class NATPolicy(object):
        """
        <class maturity="stable" type="natpolicy">
          <summary>
            Class encapsulating named NAT instances.
          </summary>
          <description>
            <para>
              This class encapsulates a name and an associated NAT instance.
              NAT policies provide a way to re-use NAT instances whithout
              having to define NAT mappings for each service
              individually.
            </para>
            <example>
            <title>Using Natpolicies</title>
            <para>
            The following example defines a simple NAT policy, and uses this
            policy for SNAT in a service.</para>
            <synopsis>
NATPolicy(name="demo_natpolicy", nat=GeneralNAT(mapping=((InetDomain(addr="10.0.1.0/24"), InetDomain(addr="192.168.1.0/24")),)))

Service(name="office_http_inter", proxy_class=HttpProxy, snat_policy="demo_natpolicy")
            </synopsis>
            </example>
          </description>
        </class>


        """
	def __init__(self, name, nat, cacheable=TRUE):
                """
                <method maturity="stable">
                  <summary>
                    Constructor to initialize a NAT policy.
                  </summary>
                  <description>
                    <para>
                      This contructor initializes a NAT policy.
                    </para>
                  </description>
                  <metainfo>
                    <arguments>
                      <argument>
                        <name>name</name>
                        <type>
                          <string/>
                        </type>
                        <description>Name identifying the NAT policy.</description>
                      </argument>
                      <argument>
                        <name>nat</name>
                        <type>
                          <class filter="nat" instance="yes"/>
                        </type>
                        <description>NAT object which performs address translation.</description>
                      </argument>
                      <argument>
                        <name>cacheable</name>
                        <type>
                          <boolean/>
                        </type>
                        <default>TRUE</default>
                        <description>Enable this parameter to cache the NAT decisions.</description>
                      </argument>
                    </arguments>
                  </metainfo>
                </method>
                """

		self.name = name
		self.nat = nat
		self.cacheable = cacheable
		if self.cacheable:
			self.nat_cache = ShiftCache('nat(%s)' % name, 1000)
		if Globals.nat_policies.has_key(name):
			raise ValueError, "Duplicate NATPolicy name: %s" % name
		Globals.nat_policies[name] = self

	def performTranslation(self, session, addrs, nat_type):
                """
                <method internal="yes">
                </method>
                """
		if session:
			session_id = session.session_id
		else:
			session_id = None
		
		## LOG ##
		# This message reports that the NAT type and the old address before the NAT mapping occurs.
		##
		log(session_id, CORE_DEBUG, 4, "Before NAT mapping; nat_type='%d', src_addr='%s', dst_addr='%s'", (nat_type, str(addrs[NAT_SNAT]), str(addrs[NAT_DNAT])))
			
		if self.cacheable:
			if addrs[NAT_SNAT] and addrs[NAT_DNAT]:
				key = (addrs[NAT_SNAT].ip_s, addrs[NAT_DNAT].ip_s)
			elif addrs[NAT_SNAT]:
				key = (addrs[NAT_SNAT].ip_s, None)
			elif addrs[NAT_DNAT]:
				key = (None, addrs[NAT_DNAT].ip_s)
			else:
				raise ValueError, "NAT without any address set"
				
                        cached = self.nat_cache.lookup(key)
                        if cached:
                        	addr = addrs[nat_type].clone(FALSE)
				addr.ip_s = cached
                        else:
				addr = self.nat.performTranslation(session, addrs, nat_type)
				self.nat_cache.store(key, addr.ip_s)
		else:
			addr = self.nat.performTranslation(session, addrs, nat_type)

		## LOG ##
		# This message reports that the NAT type and the new address after the NAT mapping occurred.
		##
		log(session_id, CORE_DEBUG, 4, "After NAT mapping; nat_type='%d', src_addr='%s', dst_addr='%s', new_addr='%s'", (nat_type, str(addrs[NAT_SNAT]), str(addrs[NAT_DNAT]), str(addr)))
		return addr
		
	def getKZorpMapping(self):
		"""
		<method internal="yes">
		</method>
		"""	
		if hasattr(self.nat, 'getKZorpMapping'):
			return self.nat.getKZorpMapping()
		raise ValueError, "NAT class does not support KZorp representation"
Example #8
0
class RootZone(AbstractZone):
	"""
        <class maturity="stable" internal="yes">
          <summary>
            Class encapsulating all address-dependent hierarchies like IPv4 and IPv6.
          </summary>
          <description>
            <para>
              This class encapsulates the top of all address-dependent
              hierarchies. It is used to locate the address hierarchy for
              various address families like IPv4 and IPv6.
            </para>
            <para>
              An instance of this class is created at startup time in the
              global variable named 'root_zone' which is then used when
              looking up the zone of a specific address.
            </para>
          </description>
          <metainfo>
            <attributes/>
          </metainfo>
        </class>
	"""

	def __init__(self, name):
		"""
                <method internal="yes">
                </method>
		"""
		AbstractZone.__init__(self, name)
		self.domains = []
		self.cache = ShiftCache('zone', config.options.zone_cache_shift_threshold)

	def addDomain(self, domain_zone):
		"""
                <method internal="yes">
                </method>
		"""
		self.domains.append(domain_zone)
		
	def findDomain(self, address):
		"""
                <method internal="yes">
                  <summary>
                    Function to find the root Zone of the given address domain.
                  </summary>
                  <description>
                    <para>
                      This function finds the first child in self which uses
                      domain as address domain.
                    </para>
                  </description>
                  <metainfo>
                    <arguments>
                      <argument maturity="stable">
                        <name>domain</name>
                        <type>Domain instance</type>
                        <description>class implementing address range specifics (for example InetDomain for IPv4)</description>
                      </argument>
                    </arguments>
                  </metainfo>
                </method>
		"""
		
		for x in self.domains:
			if x.isMatchingAddress(address):
				return x
			
			
		# we never return self, because RootZone is not a real zone
		raise ZoneException, "No root Zone found for address domain %s" % (address, )

	def addZone(self, zone):
		"""
                <method internal="yes">
                </method>
		"""
		domain_root = self.findDomain(zone.domain)
		domain_root.addZone(zone)

	def findZone(self, address):
		"""
                <method internal="yes">
                  <summary>
                    Function to find the most specific Zone for address.
                  </summary>
                  <description>
                    <para>
                      This function searches the address hierarchy for the most
                      specific Zone containing 'address'.
                    </para>
                  </description>
                  <metainfo>
                    <arguments>                      
                      <argument maturity="stable">
                        <name>address</name>
                        <type>SockAddr instance</type>
                        <description>address we are trying to find</description>
                      </argument>
                    </arguments>
                  </metainfo>
                </method>
		"""

		# FIXME: this is address family specific, should be separated
		# to its own method
		hash = address.ip

                zone = None
                zone = self.cache.lookup(hash)
                if not zone:
        		domain_root = self.findDomain(address)
	        	if domain_root:
                		zone = domain_root.findZone(address)
	                	self.cache.store(hash, zone)
	        	
        	if not zone:
	                raise ZoneException, str(address)

		return zone
Example #9
0
 def __init__(self, bindto=None, services=None, **kw):
     """
     <method maturity="stable">
       <summary>Constructor to initialize a CSZoneDispatcher instance.</summary>
       <description>
         <para>
           This constructor initializes a CSZoneDispatcher instance and sets
           its initial attributes based on arguments.
         </para>
       </description>
       <metainfo>
         <arguments>
           <argument maturity="stable">
             <name>bindto</name>
             <type>
               <sockaddr existing="yes"/>
             </type>
            <description>An existing <link linkend="python.SockAddr">socket address</link> containing the IP address and port number where the Dispatcher accepts connections.</description>
            </argument>
           <argument maturity="stable">
             <name>services</name>
             <type>
               <hash>
                 <key>
                   <tuple>
                     <zone/>
                     <zone/>
                   </tuple>
                 </key>
                 <value>
                     <service/>
                 </value>
               </hash>
             </type>
             <guitype>HASH;STRING_zone,STRING_zone;STRING_service</guitype>
             <description>Client zone - server zone - service name pairs
             using the <parameter>(("client_zone","server_zone"):"service")</parameter>
             format; specifying the service to start when the dispatcher
             accepts a connection from the given
             client zone that targets the server zone.</description>
           </argument>
           <argument maturity="stable">
             <name>follow_parent</name>
             <type>
               <boolean/>
             </type>
             <description>Set this parameter to <parameter>TRUE</parameter>
             if the dispatcher handles also the connections coming from
             the child zones of the selected client zones. Otherwise,
             the dispatcher accepts traffic only from the explicitly
             listed client zones.</description>
           </argument>
         </arguments>
       </metainfo>
     </method>
     """
     self.follow_parent = kw.pop('follow_parent', FALSE)
     super(CSZoneDispatcher, self).__init__(bindto, None, **kw)
     self.services = services
     self.cache = ShiftCache('csdispatch(%s)' % str(self.bindto),
                             config.options.zone_dispatcher_shift_threshold)
Example #10
0
class CSZoneDispatcher(Dispatcher):
    """
    <class maturity="stable">
      <summary>Class encapsulating the Dispatcher which starts a service by the client and server zone.</summary>
      <description>
        <para>
          This class is similar to a simple Dispatcher, but instead of
          starting a fixed service, it chooses one based on the client
          and the destined server zone.
        </para>
        <para>
          It takes a mapping of services indexed by a client and the server
          zone name, with an exception of the '*' zone, which matches
          anything.
        </para>
        <para>
          NOTE: the server zone might change during proxy and NAT processing,
          therefore the server zone used here only matches the real
          destination if those phases leave the server address intact.
        </para>
        <example>
            <title>CSZoneDispatcher example</title>
            <para>The following example defines a CSZoneDispatcher that
            starts the service called <parameter>internet_HTTP_DMZ</parameter>
            for connections received on the <parameter>192.168.2.1</parameter>
             IP address, but only if the connection comes from the
             <parameter>internet</parameter> zone and the destination is
             in the <parameter>DMZ</parameter> zone.</para>
            <synopsis>CSZoneDispatcher(bindto=SockAddrInet('192.168.2.1', 50080), services={("internet", "DMZ"):"internet_HTTP_DMZ"}, transparent=TRUE, backlog=255, threaded=FALSE, follow_parent=FALSE)</synopsis>
        </example>
      </description>
      <metainfo>
        <attributes>
          <attribute maturity="stable">
            <name>services</name>
            <type></type>
            <description>services mapping indexed by zone names</description>
          </attribute>
        </attributes>
      </metainfo>
    </class>
    """
    def __init__(self, bindto=None, services=None, **kw):
        """
        <method maturity="stable">
          <summary>Constructor to initialize a CSZoneDispatcher instance.</summary>
          <description>
            <para>
              This constructor initializes a CSZoneDispatcher instance and sets
              its initial attributes based on arguments.
            </para>
          </description>
          <metainfo>
            <arguments>
              <argument maturity="stable">
                <name>bindto</name>
                <type>
                  <sockaddr existing="yes"/>
                </type>
               <description>An existing <link linkend="python.SockAddr">socket address</link> containing the IP address and port number where the Dispatcher accepts connections.</description>
               </argument>
              <argument maturity="stable">
                <name>services</name>
                <type>
                  <hash>
                    <key>
                      <tuple>
                        <zone/>
                        <zone/>
                      </tuple>
                    </key>
                    <value>
                        <service/>
                    </value>
                  </hash>
                </type>
                <guitype>HASH;STRING_zone,STRING_zone;STRING_service</guitype>
                <description>Client zone - server zone - service name pairs
                using the <parameter>(("client_zone","server_zone"):"service")</parameter>
                format; specifying the service to start when the dispatcher
                accepts a connection from the given
                client zone that targets the server zone.</description>
              </argument>
              <argument maturity="stable">
                <name>follow_parent</name>
                <type>
                  <boolean/>
                </type>
                <description>Set this parameter to <parameter>TRUE</parameter>
                if the dispatcher handles also the connections coming from
                the child zones of the selected client zones. Otherwise,
                the dispatcher accepts traffic only from the explicitly
                listed client zones.</description>
              </argument>
            </arguments>
          </metainfo>
        </method>
        """
        self.follow_parent = kw.pop('follow_parent', FALSE)
        super(CSZoneDispatcher, self).__init__(bindto, None, **kw)
        self.services = services
        self.cache = ShiftCache('csdispatch(%s)' % str(self.bindto),
                                config.options.zone_dispatcher_shift_threshold)

    def getService(self, session):
        """
        <method internal="yes">
          <summary>Virtual function which returns the service to be ran</summary>
          <description>
            <para>
              This function is called by our base class to find out the
              service to be used for the current session. It uses the
              client and the server zone name to decide which service to
              use.
            </para>
          </description>
          <metainfo>
            <arguments>
              <argument maturity="stable">
                <name>session</name>
                <type></type>
                <description>session we are starting</description>
              </argument>
            </arguments>
          </metainfo>
        </method>
        """
        dest_zone = Zone.lookup(session.client_local)

        cache_ndx = (session.client_zone.getName(), dest_zone.getName())

        cached = self.cache.lookup(cache_ndx)
        if cached == 0:
            ## LOG ##
            # This message indicates that no applicable service was found for this client zone in the services cache.
            # It is likely that there is no applicable service configured in this CSZoneListener/Receiver at all.
            # Check your CSZoneListener/Receiver service configuration.
            # @see: Listener.CSZoneListener
            # @see: Receiver.CSZoneReceiver
            ##
            log(
                None, CORE_POLICY, 2,
                "No applicable service found for this client & server zone (cached); bindto='%s', client_zone='%s', server_zone='%s'",
                (self.bindto, session.client_zone, dest_zone))
        elif cached:
            return cached

        src_hierarchy = {}
        dst_hierarchy = {}
        if self.follow_parent:
            z = session.client_zone
            level = 0
            while z:
                src_hierarchy[z.getName()] = level
                z = z.admin_parent
                level = level + 1
            src_hierarchy['*'] = level
            max_level = level + 1
            z = dest_zone
            level = 0
            while z:
                dst_hierarchy[z.getName()] = level
                z = z.admin_parent
                level = level + 1
            dst_hierarchy['*'] = level
            max_level = max(max_level, level + 1)
        else:
            src_hierarchy[session.client_zone.getName()] = 0
            src_hierarchy['*'] = 1
            dst_hierarchy[dest_zone.getName()] = 0
            dst_hierarchy['*'] = 1
            max_level = 10

        best = None
        for spec in self.services.keys():
            try:
                src_level = src_hierarchy[spec[0]]
                dst_level = dst_hierarchy[spec[1]]
            except KeyError:
                src_level = max_level
                dst_level = max_level

            if not best or                                                  \
               (best_src_level > src_level) or                              \
               (best_src_level == src_level and best_dst_level > dst_level):
                best = self.services[spec]
                best_src_level = src_level
                best_dst_level = dst_level

        s = None
        if best_src_level < max_level and best_dst_level < max_level:
            try:
                s = Globals.services[best]
            except KeyError:
                log(None, CORE_POLICY, 2, "No such service; service='%s'",
                    (best))
        else:
            ## LOG ##
            # This message indicates that no applicable service was found for this client zone.
            # Check your CSZoneListener/Receiver service configuration.
            # @see: Listener.CSZoneListener
            # @see: Receiver.CSZoneReceiver
            ##
            log(
                None, CORE_POLICY, 2,
                "No applicable service found for this client & server zone; bindto='%s', client_zone='%s', server_zone='%s'",
                (self.bindto, session.client_zone, dest_zone))
        self.cache.store(cache_ndx, s)
        return s
Example #11
0
class ZoneDispatcher(Dispatcher):
    """
    <class maturity="stable" internal="yes">
      <summary>Class encapsulating the Dispatcher which starts a service by the client zone.</summary>
      <description>
        <para>
          This class is similar to a simple Dispatcher, but instead of
          starting a fixed service, it chooses one based on the client
          zone.
        </para>
        <para>
          It takes a mapping of services indexed by a zone name, with
          an exception of the '*' service, which matches anything.
        </para>
      </description>
      <metainfo>
        <attributes>
          <attribute maturity="stable">
            <name>services</name>
                <type>
                      <hash>
                        <key>
                            <zone/>
                        </key>
                        <value>
                            <service/>
                        </value>
                      </hash>
                    </type>
            <description>services mapping indexed by zone name</description>
          </attribute>
        </attributes>
      </metainfo>
    </class>
    """
    def __init__(self, bindto=None, services=None, **kw):
        """
        <method maturity="stable">
          <summary>Constructor to initialize a ZoneDispatcher instance.</summary>
          <description>
            <para>
              This constructor initializes a ZoneDispatcher instance and sets
              its initial attributes based on arguments.
            </para>
          </description>
          <metainfo>
            <arguments>
              <argument maturity="stable">
                <name>bindto</name>
                <type></type>
                <description>bind to this address</description>
              </argument>
              <argument maturity="stable">
                <name>services</name>
                <type></type>
                <description>a mapping between zone names and services</description>
              </argument>
              <argument maturity="stable">
                <name>follow_parent</name>
                <type></type>
                <description>whether to follow the administrative hieararchy when finding the correct service</description>
              </argument>
            </arguments>
          </metainfo>
        </method>
        """
        self.follow_parent = kw.pop('follow_parent', FALSE)
        super(ZoneDispatcher, self).__init__(bindto, None, **kw)
        self.services = services
        self.cache = ShiftCache('sdispatch(%s)' % str(bindto),
                                config.options.zone_dispatcher_shift_threshold)

    def getService(self, session):
        """
        <method internal="yes">
          <summary>Virtual function which returns the service to be ran</summary>
          <description>
            <para>
              This function is called by our base class to find out the
              service to be used for the current session. It uses the
              client zone name to decide which service to use.
            </para>
          </description>
          <metainfo>
            <arguments>
              <argument maturity="stable">
                <name>session</name>
                <type></type>
                <description>session we are starting</description>
              </argument>
            </arguments>
          </metainfo>
        </method>
        """

        cache_ndx = session.client_zone.getName()

        cached = self.cache.lookup(cache_ndx)
        if cached == 0:
            ## LOG ##
            # This message indicates that no applicable service was found for this client zone in the services cache.
            # It is likely that there is no applicable service configured in this ZoneListener/Receiver at all.
            # Check your ZoneListener/Receiver service configuration.
            # @see: Listener.ZoneListener
            # @see: Receiver.ZoneReceiver
            ##
            log(
                None, CORE_POLICY, 2,
                "No applicable service found for this client zone (cached); bindto='%s', client_zone='%s'",
                (self.bindto, session.client_zone))
        elif cached:
            return cached

        src_hierarchy = {}
        if self.follow_parent:
            z = session.client_zone
            level = 0
            while z:
                src_hierarchy[z.getName()] = level
                z = z.admin_parent
                level = level + 1
            src_hierarchy['*'] = level
            max_level = level + 1
        else:
            src_hierarchy[session.client_zone.getName()] = 0
            src_hierarchy['*'] = 1
            max_level = 10

        best = None
        for spec in self.services.keys():
            try:
                src_level = src_hierarchy[spec]
            except KeyError:
                src_level = max_level

            if not best or                                                  \
               (best_src_level > src_level):
                best = self.services[spec]
                best_src_level = src_level

        s = None
        if best_src_level < max_level:
            try:
                s = Globals.services[best]
            except KeyError:
                log(None, CORE_POLICY, 2, "No such service; service='%s'",
                    (best))

        else:
            ## LOG ##
            # This message indicates that no applicable service was found for this client zone.
            # Check your ZoneListener/Receiver service configuration.
            # @see: Listener.ZoneListener
            # @see: Receiver.ZoneReceiver
            ##
            log(
                None, CORE_POLICY, 2,
                "No applicable service found for this client zone; bindto='%s', client_zone='%s'",
                (self.bindto, session.client_zone))

        self.cache.store(cache_ndx, s)
        return s
Example #12
0
class NATPolicy(object):
    """
    <class maturity="stable" type="natpolicy">
      <summary>
        Class encapsulating named NAT instances.
      </summary>
      <description>
        <para>
          This class encapsulates a name and an associated NAT instance.
          NAT policies provide a way to re-use NAT instances whithout
          having to define NAT mappings for each service
          individually.
        </para>
        <example>
        <title>Using Natpolicies</title>
        <para>
        The following example defines a simple NAT policy, and uses this
        policy for SNAT in a service.</para>
        <synopsis>NATPolicy(name="demo_natpolicy", nat=GeneralNAT(mapping=((InetSubnet(addr="10.0.1.0/24"), InetSubnet(addr="192.168.1.0/24")),)))

Service(name="office_http_inter", proxy_class=HttpProxy, snat_policy="demo_natpolicy")</synopsis>
        </example>
      </description>
      <metainfo>
        <attributes/>
      </metainfo>
    </class>


    """
    def __init__(self, name, nat, cacheable=TRUE):
        """
        <method maturity="stable">
          <summary>
            Constructor to initialize a NAT policy.
          </summary>
          <description>
            <para>
              This contructor initializes a NAT policy.
            </para>
          </description>
          <metainfo>
            <arguments>
              <argument>
                <name>name</name>
                <type>
                  <string/>
                </type>
                <description>Name identifying the NAT policy.</description>
              </argument>
              <argument>
                <name>nat</name>
                <type>
                  <class filter="nat" instance="yes"/>
                </type>
                <description>NAT object which performs address translation.</description>
              </argument>
              <argument>
                <name>cacheable</name>
                <type>
                  <boolean/>
                </type>
                <default>TRUE</default>
                <description>Enable this parameter to cache the NAT decisions.</description>
              </argument>
            </arguments>
          </metainfo>
        </method>
        """

        self.name = name
        self.nat = nat
        self.cacheable = cacheable
        if self.cacheable:
            self.nat_cache = ShiftCache('nat(%s)' % name, 1000)
        if Globals.nat_policies.has_key(name):
            raise ValueError, "Duplicate NATPolicy name: %s" % name
        Globals.nat_policies[name] = self

    def performTranslation(self, session, addrs, nat_type):
        """
        <method internal="yes">
        </method>
        """
        if session:
            session_id = session.session_id
        else:
            session_id = None

        ## LOG ##
        # This message reports that the NAT type and the old address before the NAT mapping occurs.
        ##
        log(session_id, CORE_DEBUG, 4,
            "Before NAT mapping; nat_type='%d', src_addr='%s', dst_addr='%s'",
            (nat_type, str(addrs[NAT_SNAT]), str(addrs[NAT_DNAT])))

        if self.cacheable:
            if addrs[NAT_SNAT] and addrs[NAT_DNAT]:
                key = (addrs[NAT_SNAT].ip_s, addrs[NAT_DNAT].ip_s)
            elif addrs[NAT_SNAT]:
                key = (addrs[NAT_SNAT].ip_s, None)
            elif addrs[NAT_DNAT]:
                key = (None, addrs[NAT_DNAT].ip_s)
            else:
                raise ValueError, "NAT without any address set"

            cached = self.nat_cache.lookup(key)
            if cached:
                addr = cached.clone(FALSE)
                addr.port = addrs[nat_type].port
            else:
                addr = self.nat.performTranslation(session, addrs, nat_type)
                self.nat_cache.store(key, addr.clone(FALSE) if addr else None)
        else:
            addr = self.nat.performTranslation(session, addrs, nat_type)

        ## LOG ##
        # This message reports that the NAT type and the new address after the NAT mapping occurred.
        ##
        log(
            session_id, CORE_DEBUG, 4,
            "After NAT mapping; nat_type='%d', src_addr='%s', dst_addr='%s', new_addr='%s'",
            (nat_type, str(addrs[NAT_SNAT]), str(addrs[NAT_DNAT]), str(addr)))
        return addr

    def getKZorpMapping(self):
        """
        <method internal="yes">
        </method>
        """
        if hasattr(self.nat, 'getKZorpMapping'):
            return self.nat.getKZorpMapping()
        raise ValueError, "NAT class does not support KZorp representation"
Example #13
0
class CSZoneDispatcher(Dispatcher):
    """
    <class maturity="stable">
      <summary>Class encapsulating the Dispatcher which starts a service by the client and server zone.</summary>
      <description>
        <para>
          This class is similar to a simple Dispatcher, but instead of
          starting a fixed service, it chooses one based on the client
          and the destined server zone.
        </para>
        <para>
          It takes a mapping of services indexed by a client and the server
          zone name, with an exception of the '*' zone, which matches
          anything.
        </para>
        <para>
          NOTE: the server zone might change during proxy and NAT processing,
          therefore the server zone used here only matches the real
          destination if those phases leave the server address intact.
        </para>
        <example>
            <title>CSZoneDispatcher example</title>
            <para>The following example defines a CSZoneDispatcher that
            starts the service called <parameter>internet_HTTP_DMZ</parameter>
            for connections received on the <parameter>192.168.2.1</parameter>
             IP address, but only if the connection comes from the
             <parameter>internet</parameter> zone and the destination is
             in the <parameter>DMZ</parameter> zone.</para>
            <synopsis>CSZoneDispatcher(bindto=SockAddrInet('192.168.2.1', 50080), services={("internet", "DMZ"):"internet_HTTP_DMZ"}, transparent=TRUE, backlog=255, threaded=FALSE, follow_parent=FALSE)</synopsis>
        </example>
      </description>
      <metainfo>
        <attributes>
          <attribute maturity="stable">
            <name>services</name>
            <type></type>
            <description>services mapping indexed by zone names</description>
          </attribute>
        </attributes>
      </metainfo>
    </class>
    """

    deprecated_warning = True
    def __init__(self, bindto=None, services=None, **kw):
        """
        <method maturity="stable">
          <summary>Constructor to initialize a CSZoneDispatcher instance.</summary>
          <description>
            <para>
              This constructor initializes a CSZoneDispatcher instance and sets
              its initial attributes based on arguments.
            </para>
          </description>
          <metainfo>
            <arguments>
              <argument maturity="stable">
                <name>bindto</name>
                <type>
                  <sockaddr existing="yes"/>
                </type>
               <description>An existing <link linkend="python.SockAddr">socket address</link> containing the IP address and port number where the Dispatcher accepts connections.</description>
               </argument>
              <argument maturity="stable">
                <name>services</name>
                <type>
                  <hash>
                    <key>
                      <tuple>
                        <zone/>
                        <zone/>
                      </tuple>
                    </key>
                    <value>
                        <service/>
                    </value>
                  </hash>
                </type>
                <guitype>HASH;STRING_zone,STRING_zone;STRING_service</guitype>
                <description>Client zone - server zone - service name pairs
                using the <parameter>(("client_zone","server_zone"):"service")</parameter>
                format; specifying the service to start when the dispatcher
                accepts a connection from the given
                client zone that targets the server zone.</description>
              </argument>
              <argument maturity="stable">
                <name>follow_parent</name>
                <type>
                  <boolean/>
                </type>
                <description>Set this parameter to <parameter>TRUE</parameter>
                if the dispatcher handles also the connections coming from
                the child zones of the selected client zones. Otherwise,
                the dispatcher accepts traffic only from the explicitly
                listed client zones.</description>
              </argument>
            </arguments>
          </metainfo>
        </method>
        """
        if (CSZoneDispatcher.deprecated_warning):

            CSZoneDispatcher.deprecated_warning = False
            log(None, CORE_DEBUG, 3, "Use of CSZoneDispatcher class is deprecated, Rule should be used instead.")

        self.follow_parent = kw.pop('follow_parent', FALSE)
        super(CSZoneDispatcher, self).__init__(bindto, None, **kw)
        self.services = services
        self.cache = ShiftCache('csdispatch(%s)' % str(self.bindto), config.options.zone_dispatcher_shift_threshold)

    def _getSession(self, client_stream, client_local, client_listen, client_address):
        """
        <method internal="yes">
          <summary>Virtual function which returns the service to be ran</summary>
          <description>
            <para>
              This function is called by our base class to find out the
              service to be used for the current client_info. It uses the
              client and the server zone name to decide which service to
              use.
            </para>
          </description>
          <metainfo>
            <arguments>
              <argument maturity="stable">
                <name>client_info</name>
                <type></type>
                <description>Session information</description>
              </argument>
            </arguments>
          </metainfo>
        </method>
        """
        dest_zone = Zone.lookup(client_local)
        client_zone = Zone.lookup(client_address)
        cache_ndx = (client_zone.getName(), dest_zone.getName())

        cached = self.cache.lookup(cache_ndx)
        if cached == 0:
            ## LOG ##
            # This message indicates that no applicable service was found for this client zone in the services cache.
            # It is likely that there is no applicable service configured in this CSZoneListener/Receiver at all.
            # Check your CSZoneListener/Receiver service configuration.
            # @see: Listener.CSZoneListener
            # @see: Receiver.CSZoneReceiver
            ##
            log(None, CORE_POLICY, 2, "No applicable service found for this client & server zone (cached); bindto='%s', client_zone='%s', server_zone='%s'", (self.bindto, client_zone, dest_zone))
        elif cached:
            return MasterSession(cached, client_stream, client_local, client_listen, client_address, client_zone = client_zone, instance_id=getInstanceId(cached.name))

        src_hierarchy = {}
        dst_hierarchy = {}
        if self.follow_parent:
            z = client_zone
            level = 0
            while z:
                src_hierarchy[z.getName()] = level
                z = z.admin_parent
                level = level + 1
            src_hierarchy['*'] = level
            max_level = level + 1
            z = dest_zone
            level = 0
            while z:
                dst_hierarchy[z.getName()] = level
                z = z.admin_parent
                level = level + 1
            dst_hierarchy['*'] = level
            max_level = max(max_level, level + 1)
        else:
            src_hierarchy[client_zone.getName()] = 0
            src_hierarchy['*'] = 1
            dst_hierarchy[dest_zone.getName()] = 0
            dst_hierarchy['*'] = 1
            max_level = 10

        best = None
        for spec in self.services.keys():
            try:
                src_level = src_hierarchy[spec[0]]
                dst_level = dst_hierarchy[spec[1]]
            except KeyError:
                src_level = max_level
                dst_level = max_level

            if not best or                                                  \
               (best_src_level > src_level) or                              \
               (best_src_level == src_level and best_dst_level > dst_level):
                best = self.services[spec]
                best_src_level = src_level
                best_dst_level = dst_level

        service = None
        if best is not None and best_src_level < max_level and best_dst_level < max_level:
            try:
                service = Globals.services[best]
            except KeyError:
                log(None, CORE_POLICY, 2, "No such service; service='%s'", (best))
        else:
            ## LOG ##
            # This message indicates that no applicable service was found for this client zone.
            # Check your CSZoneListener/Receiver service configuration.
            # @see: Listener.CSZoneListener
            # @see: Receiver.CSZoneReceiver
            ##
            log(None, CORE_POLICY, 2, "No applicable service found for this client & server zone; bindto='%s', client_zone='%s', server_zone='%s'", (self.bindto, client_zone, dest_zone))

        if service is None:
            return None

        self.cache.store(cache_ndx, service)
        return MasterSession(service, client_stream, client_local, client_listen, client_address, client_zone = client_zone, instance_id=getInstanceId(service.name))
Example #14
0
class ZoneDispatcher(Dispatcher):
    """
    <class maturity="stable" internal="yes">
      <summary>Class encapsulating the Dispatcher which starts a service by the client zone.</summary>
      <description>
        <para>
          This class is similar to a simple Dispatcher, but instead of
          starting a fixed service, it chooses one based on the client
          zone.
        </para>
        <para>
          It takes a mapping of services indexed by a zone name, with
          an exception of the '*' service, which matches anything.
        </para>
      </description>
      <metainfo>
        <attributes>
          <attribute maturity="stable">
            <name>services</name>
                <type>
                      <hash>
                        <key>
                            <zone/>
                        </key>
                        <value>
                            <service/>
                        </value>
                      </hash>
                    </type>
            <description>services mapping indexed by zone name</description>
          </attribute>
        </attributes>
      </metainfo>
    </class>
    """

    deprecated_warning = True
    def __init__(self, bindto=None, services=None, **kw):
        """
        <method maturity="stable">
          <summary>Constructor to initialize a ZoneDispatcher instance.</summary>
          <description>
            <para>
              This constructor initializes a ZoneDispatcher instance and sets
              its initial attributes based on arguments.
            </para>
          </description>
          <metainfo>
            <arguments>
              <argument maturity="stable">
                <name>bindto</name>
                <type></type>
                <description>bind to this address</description>
              </argument>
              <argument maturity="stable">
                <name>services</name>
                <type></type>
                <description>a mapping between zone names and services</description>
              </argument>
              <argument maturity="stable">
                <name>follow_parent</name>
                <type></type>
                <description>whether to follow the administrative hieararchy when finding the correct service</description>
              </argument>
            </arguments>
          </metainfo>
        </method>
        """
        if (ZoneDispatcher.deprecated_warning):

            ZoneDispatcher.deprecated_warning = False
            log(None, CORE_DEBUG, 3, "Use of ZoneDispatcher class is deprecated, Rule should be used instead.")

        self.follow_parent = kw.pop('follow_parent', FALSE)
        super(ZoneDispatcher, self).__init__(bindto, None, **kw)
        self.services = services
        self.cache = ShiftCache('sdispatch(%s)' % str(bindto), config.options.zone_dispatcher_shift_threshold)

    def _getSession(self, client_stream, client_local, client_listen, client_address):
        """
        <method internal="yes">
          <summary>Virtual function which returns the service to be ran</summary>
          <description>
            <para>
              This function is called by our base class to find out the
              service to be used. It uses the client zone name to decide
              which service to use.
            </para>
          </description>
          <metainfo>
            <arguments>
              <argument maturity="stable">
                <name>client_info</name>
                <type></type>
                <description>Session information</description>
              </argument>
            </arguments>
          </metainfo>
        </method>
        """

        client_zone = Zone.lookup(client_address)
        cache_ndx = client_zone.getName()

        cached = self.cache.lookup(cache_ndx)
        if cached == 0:
            ## LOG ##
            # This message indicates that no applicable service was found for this client zone in the services cache.
            # It is likely that there is no applicable service configured in this ZoneListener/Receiver at all.
            # Check your ZoneListener/Receiver service configuration.
            # @see: Listener.ZoneListener
            # @see: Receiver.ZoneReceiver
            ##
            log(None, CORE_POLICY, 2, "No applicable service found for this client zone (cached); bindto='%s', client_zone='%s'", (self.bindto, client_zone))
        elif cached:
            return MasterSession(cached, client_stream, client_local, client_listen, client_address, client_zone = client_zone, instance_id=getInstanceId(cached.name))

        src_hierarchy = {}
        if self.follow_parent:
            z = client_zone
            level = 0
            while z:
                src_hierarchy[z.getName()] = level
                z = z.admin_parent
                level = level + 1
            src_hierarchy['*'] = level
            max_level = level + 1
        else:
            src_hierarchy[client_zone.getName()] = 0
            src_hierarchy['*'] = 1
            max_level = 10

        best = None
        for spec in self.services.keys():
            try:
                src_level = src_hierarchy[spec]
            except KeyError:
                src_level = max_level

            if not best or                                                  \
               (best_src_level > src_level):
                best = self.services[spec]
                best_src_level = src_level

        service = None
        if best is not None and best_src_level < max_level:
            try:
                service = Globals.services[best]
            except KeyError:
                log(None, CORE_POLICY, 2, "No such service; service='%s'", (best))

        else:
            ## LOG ##
            # This message indicates that no applicable service was found for this client zone.
            # Check your ZoneListener/Receiver service configuration.
            # @see: Listener.ZoneListener
            # @see: Receiver.ZoneReceiver
            ##
            log(None, CORE_POLICY, 2, "No applicable service found for this client zone; bindto='%s', client_zone='%s'", (self.bindto, client_zone))

        if service is None:
            return None

        self.cache.store(cache_ndx, service)
        return MasterSession(service, client_stream, client_local, client_listen, client_address, client_zone = client_zone, instance_id=getInstanceId(service.name))
Example #15
0
         (for example, the IP addresses and zone of the server and the client, 
        and the username and group memberships of the user when authentication is used). 
        Other components of Zorp refer to this data
          when making various policy-based decisions.
    </para>
  </description>
  <metainfo/>
</module>
"""

import Zorp
from Zorp import *
from Zone import root_zone
from Cache import ShiftCache

inbound_cache = ShiftCache('inbound_cache', config.options.inbound_service_cache_threshold)
outbound_cache = ShiftCache('outbound_cache', config.options.outbound_service_cache_threshold)

class AbstractSession:
        """
        <class maturity="stable" abstract="yes" internal="yes">
          <summary>
            Class encapsulating an abstract session for different types (master, or stacked).
          </summary>
          <description>
            <para>
              Abstract base class for different session types (master, or stacked),
              both MasterSession and StackedSession are derived from this class.
            </para>
          </description>
          <metainfo>