Table of contents Index

class FtpProxy - Wrapper class for the FTP proxy built in Zorp.

Declared in module Ftp

Inheritance hierarchy:

Ftp.FtpProxy
  Proxy.Proxy

Synopsis

class FtpProxy(Proxy):
    def Ftp.FtpProxy.__init__(self, session) # Initialize an FtpProxy instance
    def Ftp.FtpProxy.loadAnswers(self) # This function can be called by derived classes to initialize internal hashtables.
    def Ftp.FtpProxy.prepareData(self, side, mode) # Called by the low level proxy to prepare a given side according to mode.
    def Ftp.FtpProxy.resetData(self) # Called by the low level proxy to indicate that the data connection is to be shut down.
    def Ftp.FtpProxy.startData(self, side1, side2, way) # Called by the low level proxy to start the data connection as prepared by prepareData
    def Ftp.FtpProxy.stepData(self) # Called by the low level proxy to indicate that a processing step has been completed.

    # Inherited from Zorp.ZorpProxy
    def Zorp.ZorpProxy.__init__(self, name, session_id, client_stream) # Initialize a low level proxy instance.

    # Inherited from Proxy.Proxy
    def Proxy.Proxy.__init__(self, name, session) # Initializes a Proxy instance.
    def Proxy.Proxy.addPolicy(self, klass) # Adds a policy to the proxy.
    def Proxy.Proxy.connectServer(self, host, port) # Callback method called when a connection established

Description

By default deny everything, but data connection establishment. You should dervice your customized Ftp proxy classes in order to do something useful.

Usage

Default processing of commands:

All requests are denied in the low level proxy implementation by default. To enable different commands and answers you'll need to extend the low-level proxy in Python. To see how this is done, see the next two sections.

Setting policy for commands:

Changing the default behaviour of commands can be done using the hash named "command". This hash is indexed by the command name (e.g: USER or PWD), and each item in this hash is an action tuple, defining proxy behaviour for the given command. The first item in this tuple is an integer value, determining the action to take, and also the interpretation of the remaining items in the tuple.

Possible values for the first item:

FTP_CMD_ACCEPT
allow request without modification.
FTP_CMD_DENY
deny request. (default) Second parameter contains a string, which will be sent back to client.
FTP_CMD_POLICY
call a Python function to decide what to do. this value uses an additional tuple item, which must be a callable Python function. The function takes two parameters: self, command
FTP_CMD_ABORT
deny request, and drop conection.

Example:

      class AnonFtp(FtpProxy):
        def config(self):
          self.fw_server_data.ip_s="192.168.0.1"
          self.fw_client_data.ip_s="10.0.0.1"
          self.commands["USER"] = (Ftp.FTP_CMD_POLICY, self.pUser)
          self.commands["*"] = (Ftp.FTP_CMD_ACCEPT)
        def pUser(self,command):
          if self.request_parameter == "ftp" or self.request_parameter == "anonymous":
            return Z_ACCEPT
          return Z_DENY

Changing answer code or string:

Like with commands, we have a hash for answers as well. This hash indexed by command concatenated with answer, and contains an action tuple in each item. A special wildcard character `*' matches every command. Another feature is that you don't need to write the full answer code, it's possible to write only the first, or the first two digits.

For example, all three index below is valid:

PWD200
Match exactly the answer 200 coming in reply to a PWD command.
PWD2
Match every answer starting with 2 in reply to a PWD command.
*20
Match every answer between 200 and 209 in reply to any command.
All answers are "denied" default. It's changed to "500 Error parsing answer", because dropping an answer is not permitted by RFC959. You may enable all answers with "*".

The precedence in processing hashtable entries is the following:

  1. Exact match. (PWD200)
  2. Exact command match, partial answer matches (PWD20, PWD2, PWD)
  3. Wildcard command, with answer codes repeated as above. (*200, *20, *2, *)

Possible values for the first item in the action tuple:

FTP_ANS_ACCEPT
allow answer without modification.
FTP_ANS_CHANGE
change answer code and message. (default) Second parameter contains a string, which will be sent back to client.
FTP_ANS_POLICY
call a Python function to decide what to do. this value uses an additional parameter, which must be a callable Python function. The function takes three parameters: self, command, answer
FTP_ANS_ABORT
deny request, and drop conection.

Attributes:

data_connect
Object for the data connection
data_proxy
proxy to use for data connections
data_port_min
ports should be allocated above this variable
data_port_max
ports should be allocated below this variable
data_mode
FTP_DATA_KEEP, FTP_DATA_PASSIVE or FTP_DATA_ACTIVE can be used to force a connection type in server side. (default: FTP_DATA_KEEP)
transparent_mode
(logical) TRUE for transparent proxy, FALSE otherwise (default: TRUE)
fw_server_data
(ZorpSocket) Firewall address in server side. By default it contains the IP address of the interface `towards' the server.
fw_client_data
(ZorpSocket) Firewall address in client side. By default it contains the IP address of the interface `towards' the client.
permit_unknown_command
(boolean) Enable commands not understood (and not handled) by proxy. (Default: FALSE)
permit_empty_command
(boolean) Enable lines without commands. (Default: FALSE)
max_line_length
(integer) Maximum line lenght, what a proxy may transfer. (Default: 255)
max_username_length
(integer) Maximum length of usernames. (Default: 32)
max_password_length
(integer) Maximum length of passwords. (Default: 64)
commands
(hash) normative policy hash, directing the proxy to do something with requests, without the need to call Python. indexed by the command (e.g. "USER", "PWD" etc) (default: empty)
answers
(hash) normative policy hash directing the proxy to do something with answers. Indexed by the command, and the answer (e.g. "USER331", "PWD200" etc) (default: empty)
request_command
(string) When a command goes up to policy level, you may change it with this. FIXME: Not yet used.
request_parameter
(string) When a command goes up to policy level, this variable contains command parameters.
answer_code
(string) When an answer goes up to policy level, this variable contains answer code.
answer_parameter
(string) When an answer go up to policy level, this variable contain answer parameters.
restrict_client_connect
(boolean) Restricting data connection in client side. Accept data connection only if it's coming from IP number equal with command channel endpoint. (Default: TRUE)
restrict_server_connect
(boolean) Restricting data connection in server side. Accept data connection only if it's coming from IP number equal with command channel endpoint. (Default: FALSE)


Ftp.FtpProxy.__init__(self, session)

Initialize an FtpProxy instance

self
this instance
session
The session object


Ftp.FtpProxy.loadAnswers(self)

This function can be called by derived classes to initialize internal hashtables.

self
this instance
This function fills in the self.answers hash so that commonly used request/answer combinations are enabled.

Ftp.FtpProxy.prepareData(self, side, mode)

Called by the low level proxy to prepare a given side according to mode.

self
this instance
side
FTP_SIDE_CLIENT or FTP_SIDE_SERVER
mode
'L' for Listen, or 'C' for connect
This function simply calls self.data_connect.prepare with the same parameters it receives from the proxy.

Ftp.FtpProxy.resetData(self)

Called by the low level proxy to indicate that the data connection is to be shut down.

self
this instance
This function simply calls self.data_connect.resetState() to shut down the currently half, or fully established data connection.

Ftp.FtpProxy.startData(self, side1, side2, way)

Called by the low level proxy to start the data connection as prepared by prepareData

self
this instance
side1
start processing on this side
side2
continue processing here
way
data direction
This function simply calls self.data_connect.start with the same parameters it receives from the proxy.

Ftp.FtpProxy.stepData(self)

Called by the low level proxy to indicate that a processing step has been completed.

self
this instance
This function simply calls self.data_connect.processState().
Copyright © 2000 BalaBit IT Ltd.
Written by: Balázs Scheidler