Zorp is a component-based, object-oriented, event-driven and modular proxy firewall suite, which makes it possible to finetune proxy decisions (with its built in script language), to fully analyze complex protocols (like SSH with several forwarded TCP connections), and to utilize outband authentication techniques (unlike common practices where proxy authentication had to be hacked into the protocol).
Zorp is basically made up the following four cooperating building blocks:
decision logic
Implemented in Python and is primarily responsible to say A or B for questions. These questions are asked by the low level proxy modules to know how to treat their peers.
It is implemented as hooks an administrator can override, or whose result is defined through parameters the administrator can set, or change.
connecting proxy modules
Since Zorp is modular, modules must be connected in a way meaningful to the current application.
application level gateways, proxies
These are implemented in native programming language. They work closely with the decision logic, so the details of the protocol can be controlled by the administrator.
authentication modules
Zorp was designed to support user authentication from the ground up. Current practices of user authentication on firewalls require a special extension to the protocol, which is used to pass authentication credentials. Instead of this Zorp supports outband user authentication, where a channel other than the current protocol channel is used to pass this information.
Component based development has several advantages over traditional program development: reusability, smaller code size, higher level languages, language independence etc.
Zorp is also using components, but it doesn't depend on large component systems like OMG CORBA or Microsoft DCOM. Using those on a firewall would be questionable, because of security reasons.
A component in zorp is an interface, a set of functions and variables, which hides details in the implementation. Changing the implementation doesn't effect interoperability with other interfaces.
The four most important components in Zorp are:
ZorpListen
Implements a listener which accepts connections, and calls the given callback if a connection is accepted. A connection is represented by a ZorpStream interface.
ZorpConnect
Connects to the given address, and calls the given callback if the connection is established. The result connection can also be represented by a ZorpStream interface.
ZorpStream
This is a full-duplex stream with read and write operations, and are used by Proxies to transmit data.
ZorpProxy
A ZorpProxy receives two ZorpStreams representing the client and the server side. ZorpProxy is responsible to connect these with an appropriate protocol.
Proxy modules (application gateways) implement this interface, and are loaded dynamically.
Although building a system from components is also an OOP approach, the real power is the language where decisions can be specified. The language - Python - is an easy to learn, clean, and powerful object oriented language.
The administrator can either define his own reusable set of classes, or can use the ones provided by us.
Event driven in the context of zorp doesn't exactly mean the thing you are used to in connection with GUI programming. Event driven means that proxies send events to the decision layer, and the result controls the behaviour of the proxy.
For example the FTP proxy module sends an event whenever the transmission of a file is requested. The administrator then can hook into the processing of this event, and decide if the given file transfer is allowed, or not. (for instance by checking the current directory).
We are not however limited to yes/no answers. With the following means of communication we can create quite complex control mechanisms:
Events
Events are sent by the underlying Proxy to the event handler class implemented in Python. It may have one or more parameters, and returns a value modifying proxy behaviour. Handling an event means implementing an object method in Python.
Attributes
Attributes represent the internal state of the proxy which it decides to make available to the policy layer.
Callbacks
Callbacks are similar to events with the difference that they are called by the policy layer, and implemented by the proxy (contrary the event is called by the proxy and implemented in the policy)
Each proxy module can be an up-level proxy, where it is directly connected to the server and the client, or can be attached as a subprotocol proxy to a parent proxy. This is the case when a multiplexer protocol (like SSH), must be fully analyzed. This is called stacking a proxy into another.