############################################################################
##
## Copyright (c) 2000 BalaBit IT Ltd, Budapest, Hungary
##
## 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: Plug.py,v 1.8.6.2 2001/09/04 10:13:07 bazsi Exp $
##
## Author  : Bazsi
## Auditor : kisza
## Last version: 1.10
## Notes:
##   - comments in English
##
############################################################################

"""Module defining an interface to the Plug proxy module.

This module defines an interface to the Plug proxy. Plug is a simple TCP
circuit, which means that transmission takes place without protocol
verification.
"""

from Zorp import *
from Proxy import Proxy
from Conntrack import AbstractTracker

PLUG_DEBUG = "plug.debug"

class PlugTracker(AbstractTracker):
	"""Class encapsulating a plug specific connection tracker.

	This class encapsulates a plug specific connection tracker. It
	basically uses a timeout to track associated packets. For more
	information check out the CTracker class.
	"""
	def __init__(self, service):
		"""Constructor to initialize a PlugTracker instance

		This constructor initializes a PlugTracker instance
		by setting attributes based on arguments and calling
		inherited constructors.

		Arguments

		  self -- this instance

		  service -- service to instantiate when a session starts
		"""
		AbstractTracker.__init__(self, "plug", service)

	def config(self):
		"""Function to set up default configuration for PlugTracker.

		This function sets up default configuration for PlugTracker
		by setting the timeout value to 30 seconds.

		Arguments

		  self -- this instance
		"""
		self.timeout = 30

class PlugProxy(Proxy):
	"""Class encapsulating the Plug proxy implemented in Zorp.
	
	This class implements a general plug proxy, with optionally
	disabling data transfer in either direction.

	By default plug copies all data in both directions. To change
	this set the 'copy_to_client' or 'copy_to_server' attributes
	to FALSE.

	  Note 
	
	    Copying out of band data is not supported.

	Attributes

	  copy_to_server -- Copy data in client->server direction
	  
	  copy_to_client -- Copy data in server->client direction
	  
	  bandwidth_to_client -- Readonly variable containing the utilized
                                 bandwidth in server->client direction.
				 
	  bandwidth_to_server -- Readonly variable containing the utilized
	                         bandwidth in client->server direction.
				 
	  packet_stats_interval -- The number of milliseconds between
	                           two successive packetStats() events.
				   By default: 0.
				   NOTE: this is currently implemented as the
				   number of passing packages, not as
				   milliseconds.
				   
	  stack_proxy -- the proxy class to stack into the connection
	"""

	def __init__(self, session, type):
		"""Constructor initializing a PlugProxy instance.

		This constructor creates and sets up a PlugProxy instance.

		Arguments

		  self -- this instance
		  
		  session -- session this instance belongs to
		
		"""
		self.stack_proxy = None
		Proxy.__init__(self, "plug", session, type)

	def dgramstart(self, ctracker):
		Proxy.startdgramproxy(self, ctracker)

	def requestStack(self):
		"""Function returning the stacked proxy class.
		
		This callback is called by the underlying C proxy to query
		if something is to be stacked into it. It should return
		the proxy class to be used.

		Arguments
		
		  self -- this instance
		  
		Returns
		
		  the class of the proxy to stack in
		"""
		return self.stack_proxy

	def packetStats(self, client_bytes, client_pkts, server_bytes, server_pkts):
		"""Function called when the packet_stats_interval is elapsed.

		This function is called whenever the time interval elapses
	        (or as currently implemented the given number of
	        packets were transmitted). this event receives packet
	        statistics as parameters.

	        It's useful for terminating connections with excessive
	        bandwidth requirements (for instance to limit the impact of
	        the covert channel opened when using plug instead of a
	        protocol specific proxy).
	        
	        Arguments
	        
	          self -- this instance
	          
	          client_bytes -- the number of bytes transmitted to the client
	          
	          client_pkts  -- the number of packets transmitted to the client
	          
	          server_bytes -- the number of bytes transmitted to the server
	          
	          server_pkts  -- the number of packets transmitted to the server
		"""
		raise NotImplementedError

	# This statement registers the default tracker class to use for
	# datagram oriented sessions. To change this assign a different
	# value to the conntrack attribute.
	conntrack = PlugTracker
