############################################################################
##
## 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: Pssl.py,v 1.2.2.1.2.2 2001/09/04 10:13:21 bazsi Exp $
##
## Author  : Bazsi
## Auditor : 
## Last audited version: 
## Notes:
##
############################################################################

"""Module defining an interface to the Pssl proxy.

This module defines an interface to the Pssl proxy implemented in Zorp. Pssl
is a plug with the additional possibility of using SSL encryption/decryption
on either of its sides.
"""

from Zorp import *
from Proxy import Proxy

SSL_VERIFY_NONE               = 0
SSL_VERIFY_OPTIONAL           = 1
SSL_VERIFY_REQUIRED_UNTRUSTED = 2
SSL_VERIFY_REQUIRED_TRUSTED   = 3


class PsslProxy(Proxy):
	"""Encapsulates an SSL enabled plug proxy.

	This class encapsulates a plug proxy which implements SSL on either
	of its sides making it possible for any protocol proxy to be
	wrapped into SSL.
	
	Verification
	
	  PSSL can optionally perform X509 certificate based authentication
	  on its SSL enabled sides. This can be controlled by the
	  'client_verify_type' and the 'server_verify_type' attributes
	  both of which can be one of the following values:
	  
	    SSL_VERIFY_NONE -- do not perform certificate verification
	    
	    SSL_VERIFY_OPTIONAL -- the peer can optionally send a certificate
	    
	    SSL_VERIFY_REQUIRED_UNTRUSTED -- the peer is required to provide a 
	                                     certificate but it doesn't need to 
	                                     be trusted
	    
	    SSL_VERIFY_REQUIRED_TRUSTED -- the peer is required to provide a
	                                   certificate and it must be trusted
	    
	  A certificate is trusted if:
	  
	    * the current time is within its validity periods
	    
	    * the issuer of the certificate is trusted (e.g. its issuer CA
	      is listed in the trusted ca directory)
	    
	    * none of the affected certificates are listed in revocation
	      lists
	      
	    * none of the affected revocation lists are expired

	Attributes
	
	  stack_proxy    -- the proxy to stack into Pssl once the SSL 
	                    connection is established
	  
	  copy_to_client -- Copy data in server->client direction
	  
	  copy_to_server -- Copy data in client->server 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.
				   
	  client_need_ssl	-- Enable SSL on the client side of the proxy. This
	                           requires setting client_key and client_cert.
				   
	  client_cert		-- Filename of the client side
	                           authentication certificate in PEM format. 
	                           This must be a server certificate, since
	                           for clients the proxy behaves as it were
	                           an SSL server.

	  client_key		-- Client side authentication private key 
	                           corresponding to 'client_cert'.
	  
	  client_ca_directory    -- Directory containing trusted CAs in PEM format.

	  client_crl_directory  -- Direcory containing CRLs for CAs.

	  client_verify_type    -- Verification for the peer on the client side.
	  
	  client_verify_depth   -- The maximum allowable certificate chain depth during client verification.

	  server_need_ssl	-- Enable SSL on the server side of the proxy. 
	                           Optionally you can set the server_key and 
	                           server_cert attributes if you want to
	                           perform authentication on the server.
	                           Since this mode of the proxy means
	                           behaving like a client, this certificate
	                           must be a client certificate.
				   
	  server_cert		-- Server side authentication certificate (requires a client certificate).
	  
	  server_key		-- Server side authentication private key.

	  server_ca_direcory    -- Directory containing trusted CAs in PEM format.

	  server_crl_directory  -- Direcory containing CRLs for CAs.

	  server_verify_type    -- Server verification type.

	  server_verify_depth -- The maximum allowable certificate chain depth during server verification.
	"""

	def __init__(self, session, type):
		"""Constructor to initialize a PsslProxy instance.

		Sets attributes based on arguments, and calls the inherited
		constructor.

		Arguments

		  self    -- this instance
		  
		  session -- the reference of the owning session  

		  type -- type of this session, must indicate STREAM session, since SSL is supported only on TCP streams
		"""
		self.stack_proxy = None
		Proxy.__init__(self, "pssl", session, type)

	def requestStack(self):
		"""Function used to query whether to stack anything to Pssl.

		Callback called by the underlying C proxy to query if
		something is to be stacked.

		Arguments
		
		  self -- this instance
		  
		"""
		return self.stack_proxy

