
      Chapter 25. AMANDA Security API
Prev  Part V. Technical Background  Next

-------------------------------------------------------------------------------

Chapter 25. AMANDA Security API


Mike Grupenhoff

Original text
AMANDA Core Team
<kashmir@munge.com>

Stefan G. Weichinger

XML-conversion;Updates
AMANDA Core Team
<sgw@amanda.org>
Table of Contents


  Introduction

  The_Problem

  The_API


        protocol_packet_transmission_functions

        stream_functions


  Data_Types


        security_driver_t

        security_handle_t

        security_stream_t

        security_status_t


  SECURITY_DRIVERS


        name

        connect

        accept

        close

        sendpkt

        recvpkt

        recvpkt_cancel

        stream_server

        stream_accept

        stream_client

        stream_close

        stream_auth

        stream_id

        stream_write

        stream_read

        stream_read_cancel



Note

Refer to http://www.amanda.org/docs/security-api.html for the current version
of this document.

 Introduction

This is a document of the API for defining and utilizing multiple security and
transport mechanisms for the AMANDA network protocol.
The goal of this API is to allow several different forms of communication and
authentication to exist between the AMANDA server and its clients.

 The Problem

There exist many potential ways that a user might wish to grant access to the
AMANDA daemon. The two currently supported are BSD (reserved port) and Kerberos
IV security. The current implementation of these two methods is not very
general, and adding additional methods requires a large amount of code to be
modified.
Additionally, the current methods require the protocol and dump transport to be
transmitted across the network using a pre-defined method. The AMANDA protocol
currently must be sent using udp datagrams to a well-known port, and the dumps
are transported using tcp connections between ports negotiated via the
protocol.

 The API

The security API was designed to be a layer in between the core logic of AMANDA
and the transport and authentication of the protocol and dumps.
The component server and client programs now deal with abstract concepts
instead of concrete udp and tcp handles.
The prefix "security_" is reserved for use as the namespace of this API.

 protocol packet transmission functions

These functions exist for transmitting pkt_t's between the client and server.
These functions operate on security_handle_t objects. These objects are
described later.

 security_getdriver

const security_driver_t *security_getdriver(const char *drivername);
Given a security type ("KRB4", "BSD", "SSH", etc), returns a pointer to that
type's security_driver_t (section 4.1), or NULL if no driver exists.

 security_connect

void security_connect(const security_driver_t *h, const char *hostname, char *
(*conf_fn)(char *arg, void *arg), void (*fn)(void *arg, security_handle_t *h,
security_status_t s), void *arg);
Given a security driver, and a hostname, calls back with a security_handle_t
(section 4.2) that can be used to communicate with that host. The status arg to
the callback is reflects the success of the request. Error messages can be had
via security_geterror().
This is expected to be the AMANDA server's interface for setting up connections
to clients.
conf_fn is used to determine configuration information. If NULL, no
configuration information is available.

 security_accept

void security_accept(const security_driver_t *h, int in, int out, void
(*callback)(security_handle_t *, pkt_t *));
Given a security driver, an input file descriptor, and an output file
descriptor, and a callback, when new connections are detected on the given file
descriptors, the function is called with a newly created security handle and
the initial packet received.
This is expected to be the AMANDA daemon's interface for setting up incoming
connections from the AMANDA server. The file descriptors are typically 0 and 1
(stdin/stdout).
This function uses the event interface, and only works properly when event_loop
() is called later in the program.

 security_close

void security_close(security_handle_t *h);
Closes a connection created by a security_connect() or security_accept().

 security_sendpkt

int security_sendpkt(security_handle_t *h, const pkt_t *pkt);
Transmits a pkt_t over a security handle. Returns 0 on success, or negative on
error. A descriptive error message can be obtained via security_geterror().

 security_recvpkt

int security_recvpkt(security_handle_t *h, void (*callback)(void *arg, pkt_t
*pkt, security_status_t), void *arg, int timeout);
Requests that when incoming packets arrive for this handle, the given function
is called with the given argument, the received packet, and the status of the
reception.
If a packet does not arrive within the number of seconds specified in the
'timeout' argument, RECV_TIMEOUT is passed in the status argument of the
timeout.
On receive error, the callback's status argument will be set to RECV_ERROR. An
error message can be retrieved via security_geterror().
On successful reception, RECV_OK will be passed in the status argument, and the
pkt argument will point to a valid packet.
This function uses the event interface. Callbacks will only be generated when
event_loop() is called.

 security_recvpkt_cancel

int security_recvpkt_cancel(security_handle_t *h);
Cancels a previous recvpkt request for this handle.

 security_geterror

const char *security_geterror(security_handle_t *h);
Returns a descriptive error message for the last error condition on this
handle.

 security_seterror

void security_seterror(security_handle_t *h, const char *msg, ...);
Sets the string that security_geterror() returns.

 security_handleinit

void security_handleinit(security_handle_t *, const security_driver_t *);
Initializes a security_handle_t. This is meant to be called only by security
drivers to initialize the common part of a newly allocated security_handle_t.

 stream functions

These functions exist for transmitting random data over a stream-like
connection.
These functions operate on security_stream_t objects, which are described
later.

 security_stream_server

security_stream_t *security_stream_server(security_handle_t *h);
Creates the server end of a security stream, and will receive a connection from
the host on the other end of the security handle passed.
Returns a security_stream_t on success, and NULL on error. Error messages can
be obtained by calling security_geterror() on the security handle associated
with this stream.

 security_stream_accept

int security_stream_accept(security_stream_t *);
Given a security stream created by security_stream_server, blocks until a
connection is made from the remote end.
Returns 0 on success, and -1 on error. Error messages can be obtained by
calling security_stream_geterror().

 security_stream_client

security_stream_t *security_stream_client(security_handle_t *h, int id);
Creates the client end of a security stream, and connects it to the machine on
the other end of the security handle. The 'id' argument identifies which stream
on the other end to connect to.
Returns a security_stream_t on success, and NULL on error. Error messages can
be obtained by calling security_geterror() on the security handle associated
with this stream.

 security_stream_close

void security_stream_close(security_stream_t *s);
Closes a security stream and frees up resources associated with it.

 security_stream_auth

int security_stream_auth(security_stream_t *s);
Authenticate a connected security stream.
Returns 0 on success, and -1 on error. Error messages can be obtained by
calling security_stream_geterror().

 security_stream_id

int security_stream_id(security_stream_t *s);
Returns an identifier which can be used to connect to this security stream with
security_stream_client().
Typical usage would be for one end of a connection to create a stream with
security_stream_server(), and then transmit the id for that stream to the other
side. The other side will then connect to that id with security_stream_client
().

 security_stream_write

int security_stream_write(security_stream_t *s, const void *buf, size_t
bufsize);
Writes a chunk of data to the security stream. Returns 0 on success, or
negative on error. Error messages can be obtained by calling
security_stream_geterror().

 security_stream_read

void security_stream_read(security_stream_t *s, void (*callback)(void *arg,
void *buf, int bufsize), void *arg);
Requests that when data is ready to be read on this stream, the given function
is called with the given arg, a buffer full of data, and the size of that
buffer.
On error, the bufsize will be negative. An error message can be retrieved by
calling security_stream_geterror().
This function uses the event interface. Callbacks will only be generated while
in event_loop().

 security_stream_read_cancel

void security_stream_read_cancel(security_stream_t *s);
Cancels a previous read request.

 security_stream_geterror

const char *security_stream_geterror(security_stream_t *h);
Returns a descriptive error message for the last error condition on this
stream.

 security_stream_seterror

void security_stream_seterror(security_stream_t *h, const char *msg, ...);
Sets the string that security_stream_geterror() returns.

 Data Types

All visible data types are meant to be opaque to the caller. At no time should
a caller have to access a member of any data type directly. The API should
always be used instead.

 security_driver_t

This is a static object containing function vectors that implement the API for
a particular security type.

 security_handle_t

This is an object that describes a protocol connection to a remote server.
There is one security_handle_t per request, and there can be many to the same
remote host.

 security_stream_t

This is an object that describes a data connection to a remote host. It is
always associated and derived from a security_handle_t. Arbitrary data can be
passed over a security stream.

 security_status_t

This is an enumerated type that is passed to the callback of security_recvpkt
and security_connect. The possible values it can have are:
S_OK - the pkt_t was received fine S_TIMEOUT - no pkt_t was received within the
time specified in the timeout argument to security_recvpkt(). S_ERROR - an
error occurred during reception. Call security_geterror() for more information.

 SECURITY DRIVERS

Each security type is defined by a struct of function vectors. These methods
implement the details of this security type.
This section will document each element of security_driver_t.

 name

const char *name;
This is the name of the driver. This is used by security_getdriver() to
associate a name with a driver type.

 connect

void (*connect)(const char *hostname, void (*fn)(void *, security_handle_t *,
security_status_t), void *);
This is the implementation of security_connect(). It actually sets up the
connection, and then returns a structure describing the connection. The first
element of this structure MUST be a security_handle_t, because it will be cast
to that after it is passed up to the caller.
The first argument is the host to connect to. The second argument is a function
to call when a connection is made. The third argument is passed to the
callback.
The callback takes three arguments. The first is the caller supplied void
pointer. The second is a newly allocated security handle. The third is a
security_status_t flag indicating the success or failure of the operation.

 accept

void (*accept)(int in, int out, void (*callback)(security_handle_t *handle,
pkt_t *pkt));
This is the implementation of security_accept(). It is passed the input and
output file descriptors and a callback. The callback takes a security handle
argument and also an initial packet received for that handle.

 close

void (*close)(void *handle);
The implementation of security_close().

 sendpkt

int (*sendpkt)(void *handle, pkt_t *pkt);
The implementation of security_sendpkt(). Security information is usually added
by the driver before transmission.

 recvpkt

void (*recvpkt)(void *handle, void (*callback)(void *arg, pkt_t *pkt,
security_status_t), void *arg);
The implementation of security_recvpkt(). It will typically be layered onto the
event interface somehow. It can assume that a caller will eventually call
event_loop().

 recvpkt_cancel

void (*recvpkt_cancel)(void *handle);
The implementation of security_recvpkt_cancel(). Drivers should allow this to
be run even if no recvpkt was scheduled, or if one was previously cancelled.

 stream_server

void *(*stream_server)(void *handle);
Implementation of security_stream_server(). This function returns a object
describing the stream. The first member of this object MUST be a
security_stream_t, because it will be cast to that.

 stream_accept

int (*stream_accept)(void *stream);
After calling stream_server, stream_accept must be called on the stream before
it is fully connected.

 stream_client

void *(*stream_client)(void *handle, int id);
Implementation of security_stream_client(). The id argument is something
returned by security_stream_id(). Again, the handle is referenced counted.
This function returns a object describing the stream. The first member of this
object MUST be a security_stream_t, because it will be cast to that.

 stream_close

void (*stream_close)(void *stream);
Close and free up resources for an open stream.

 stream_auth

int (*stream_auth)(void *stream);
Authenticate a connected stream.

 stream_id

int (*stream_id)(void *stream);
Return a unique id for this stream. This is to be used by stream_client() to
connect to this stream.

 stream_write

int (*stream_write)(void *stream, const void *buf, size_t bufsize);
Implementation of security_stream_write.

 stream_read

void (*stream_read)(void *stream, void (*callback)(void *arg, void *buf, int
bufsize), void *arg);
Implementation of security_stream_read.

 stream_read_cancel

void (*stream_read_cancel)(void *stream);
Implementation of security_stream_read_cancel.
-------------------------------------------------------------------------------

Prev                           Up                           Next
Chapter 24. AMANDA Event API  Home  Chapter 26. Virtual Tape API

