Imported Upstream version 3.2.0
[debian/amanda] / common-src / security.h
1 /*
2  * Amanda, The Advanced Maryland Automatic Network Disk Archiver
3  * Copyright (c) 1999 University of Maryland at College Park
4  * All Rights Reserved.
5  *
6  * Permission to use, copy, modify, distribute, and sell this software and its
7  * documentation for any purpose is hereby granted without fee, provided that
8  * the above copyright notice appear in all copies and that both that
9  * copyright notice and this permission notice appear in supporting
10  * documentation, and that the name of U.M. not be used in advertising or
11  * publicity pertaining to distribution of the software without specific,
12  * written prior permission.  U.M. makes no representations about the
13  * suitability of this software for any purpose.  It is provided "as is"
14  * without express or implied warranty.
15  *
16  * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
18  * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
20  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
21  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22  *
23  * Authors: the Amanda Development Team.  Its members are listed in a
24  * file named AUTHORS, in the root directory of this distribution.
25  */
26 /*
27  * $Id: security.h,v 1.17 2006/05/26 14:00:58 martinea Exp $
28  *
29  * security api
30  */
31 #ifndef SECURITY_H
32 #define SECURITY_H
33
34 #include "packet.h"
35
36 struct security_handle;
37
38 /*
39  * Overview
40  *
41  * The Security API consists of handles (also called connections), each of
42  * which represents a connection to a particular host.  A handle is implemented
43  * by a driver.  Each handle supports a packet-based communication protocol, as
44  * well as an arbitrary number of bidirectional tcp-like streams.
45  */
46
47 /*
48  * This is a type that gets passed to the security_recvpkt() and
49  * security_connect() callbacks. It details what the status of this callback
50  * is.
51  */
52 typedef enum {
53     S_OK,       /* the pkt_t was received fine */
54     S_TIMEOUT,  /* no pkt_t was received within the time specified in the
55                  * timeout argument to security_recvpkt() */
56     S_ERROR,    /* an error occurred during reception. Call security_geterror()
57                  * for more information */
58 } security_status_t;
59
60 /*
61  * Drivers
62  */
63
64 /*
65  * This structure defines a security driver.  This driver abstracts
66  * common security actions behind a set of function pointers.  Macros
67  * mask this.
68  */
69 typedef struct security_driver {
70
71     /*
72      * The name of this driver, eg, "BSD", "BSDTCP", "KRB5", etc...  This is
73      * used by security_getdriver() to associate a name with a driver type.
74      */
75     const char *name;
76
77     /*
78      * This is the implementation of security_connect(). It actually sets up
79      * the connection, and then returns a structure describing the connection.
80      * The first element of this structure MUST be a security_handle_t, because
81      * it will be cast to that after it is passed up to the caller.
82      *
83      * The first argument is the host to connect to. The second argument is a
84      * function to call when a connection is made. The third argument is passed
85      * to the callback.
86      *
87      * The callback takes three arguments. The first is the caller supplied
88      * void pointer. The second is a newly allocated security handle. The third
89      * is a security_status_t flag indicating the success or failure of the
90      * operation.
91      */
92     void (*connect)(const char *, char *(*)(char *, void *),
93             void (*)(void *, struct security_handle *, security_status_t),
94             void *, void *);
95
96     /*
97      * This form sets up a callback that returns new handles as they are
98      * received.  It is passed the input and output file descriptors and a
99      * callback. The callback takes a security handle argument and also an
100      * initial packet received for that handle.
101      */
102     void (*accept)(const struct security_driver *, char *(*)(char *, void *),
103             int, int, void (*)(struct security_handle *, pkt_t *), void *);
104
105     /* get the remote hostname */
106     char *(*get_authenticated_peer_name)(struct security_handle *handle);
107
108     /*
109      * Frees up handles allocated by the previous methods
110      */
111     void (*close)(void *);
112
113     /*
114      * This transmits a packet after adding the security information
115      * Returns 0 on success, negative on error.
116      */
117     ssize_t (*sendpkt)(void *, pkt_t *);
118
119     /*
120      * This creates an event in the event handler for receiving pkt_t's on a
121      * security_handle.  The given callback will be called with the given arg
122      * when the driver determines that it has data for that handle.  The last
123      * argument is a timeout, in seconds.  This may be -1 to indicate no
124      * timeout.  This method should assume that the caller will invoke
125      * event_loop
126      *
127      * If there was an error or timeout, this will be indicated in the status
128      * argument.
129      *
130      * Only one recvpkt request can exist per handle.
131      */
132     void (*recvpkt)(void *, void (*)(void *, pkt_t *, security_status_t), void
133             *, int);
134
135     /*
136      * Cancel an outstanding recvpkt request on a handle. Drivers should allow
137      * this to be run even if no recvpkt was scheduled, or if one was
138      * previously cancelled.
139      */
140     void (*recvpkt_cancel)(void *);
141
142     /*
143      * Get a stream given a security handle. This function returns a object
144      * describing the stream. The first member of this object MUST be a
145      * security_stream_t, because it will be cast to that.
146      */
147     void *(*stream_server)(void *);
148
149     /*
150      * Accept a stream created by stream_server
151      */
152     int (*stream_accept)(void *);
153
154     /*
155      * Get a stream and connect it to a remote given a security handle and a
156      * stream id.  This function returns a object describing the stream. The
157      * first member of this object MUST be a security_stream_t, because it will
158      * be cast to that.
159      */
160     void *(*stream_client)(void *, int);
161
162     /*
163      * Close a stream opened with stream_server or stream_client
164      */
165     void (*stream_close)(void *);
166
167     /*
168      * Authenticate a stream.
169      */
170     int (*stream_auth)(void *);
171
172     /*
173      * Return a numeric id for a stream.  This is to be used by stream_client
174      * on the other end of the connection to connect to this stream.
175      */
176     int (*stream_id)(void *);
177
178     /*
179      * Write to a stream.
180      */
181     int (*stream_write)(void *, const void *, size_t);
182
183     /*
184      * Read asyncronously from a stream.  Only one request can exist
185      * per stream.
186      */
187     void (*stream_read)(void *, void (*)(void *, void *, ssize_t), void *);
188
189     /*
190      * Read syncronously from a stream.
191      */
192     ssize_t (*stream_read_sync)(void *, void **);
193
194     /*
195      * Cancel a stream read request
196      */
197     void (*stream_read_cancel)(void *);
198
199     void (*close_connection)(void *, char *);
200
201     int (*data_encrypt)(void *, void *, ssize_t, void **, ssize_t *);
202     int (*data_decrypt)(void *, void *, ssize_t, void **, ssize_t *);
203 } security_driver_t;
204
205 /* Given a security type ("KRB4", "BSD", "SSH", etc), returns a pointer to that
206  * type's security_driver_t, or NULL if no driver exists.  */
207 const security_driver_t *security_getdriver(const char *);
208
209 /*
210  * Handles
211  */
212
213 /*
214  * This structure is a handle to a connection to a host for transmission
215  * of protocol packets (pkt_t's).  The underlying security type defines
216  * the actual protocol and transport.
217  *
218  * This handle is reference counted so that it can be used inside of
219  * security streams after it has been closed by our callers.
220  */
221 typedef struct security_handle {
222     const security_driver_t *driver;
223     char *error;
224 } security_handle_t;
225
226 /* void security_connect(
227  *  const security_driver_t *driver,
228  *  const char *hostname,
229  *  char *(*conf_fn)(char *, void *),
230  *  void (*fn)(void *, security_handle_t *, security_status_t),
231  *  void *arg,
232  *  void *datap);
233  *
234  * Given a security driver, and a hostname, calls back with a security_handle_t
235  * that can be used to communicate with that host. The status arg to the
236  * callback is reflects the success of the request. Error messages can be had
237  * via security_geterror().  The conf_fn is used to determine configuration
238  * information, with its second argument being the datap. If conf_fn is NULL,
239  * no configuration information is available.
240  */
241 #define security_connect(driver, hostname, conf_fn, fn, arg, datap)     \
242     (*(driver)->connect)(hostname, conf_fn, fn, arg, datap)
243
244 /* void security_accept(
245  *  const security_driver_t *driver,
246  *  char *(*conf_fn)(char *, void *),
247  *  int in,
248  *  int out,
249  *  void (*fn)(security_handle_t *, pkt_t *),
250  *  void *datap);
251  *
252  * Given a security driver, an input file descriptor, and an output file
253  * descriptor, and a callback, when new connections are detected on the given
254  * file descriptors, the function is called with a newly created security
255  * handle and the initial packet received.  This is amandad's interface for
256  * accepting incoming connections from the Amanda server. The file descriptors
257  * are typically 0 and 1 (stdin/stdout).  This function uses the event
258  * interface, and only works properly when event_loop() is called later in the
259  * program.
260  */
261 #define security_accept(driver, conf_fn, in, out, fn, datap)    \
262     (*(driver)->accept)(driver, conf_fn, in, out, fn, datap)
263
264 /* char *security_get_authenticated_peer_name(
265  *  security_handle_t *handle);
266  *
267  * Returns the fully qualified, authenticated hostname of the peer, or
268  * "localhost" for a local system.  The string is statically allocated and need
269  * not be freed.  The string will never be NULL, but may be an empty string if
270  * the remote identity is not known, not defined, or could not be
271  * authenticated.
272  */
273 #define security_get_authenticated_peer_name(handle) \
274     (*(handle)->driver->get_authenticated_peer_name)(handle)
275
276 /* Closes a security stream created by a security_connect() or
277  * security_accept() and frees up resources associated with it. */
278 void security_close(security_handle_t *);
279
280 /* ssize_t security_sendpkt(security_handle_t *, const pkt_t *);
281  *
282  * Transmits a pkt_t over a security handle. Returns 0 on success, or negative
283  * on error. A descriptive error message can be obtained via
284  * security_geterror(). */
285 #define security_sendpkt(handle, pkt)           \
286     (*(handle)->driver->sendpkt)(handle, pkt)
287
288 /* void security_recvpkt(
289  *  security_handle_t *handle,
290  *  void (*fn)(void *, pkt_t *, security_status_t),
291  *  void *arg,
292  *  int timeout);
293  *
294  * Requests that when incoming packets arrive for this handle, the given
295  * function is called with the given argument, the received packet, and the
296  * status of the reception.  If a packet does not arrive within the number of
297  * seconds specified in the 'timeout' argument, RECV_TIMEOUT is passed in the
298  * status argument of the timeout.  On receive error, the callback's status
299  * argument will be set to RECV_ERROR. An error message can be retrieved via
300  * security_geterror().  On successful reception, RECV_OK will be passed in the
301  * status argument, and the pkt argument will point to a valid packet.  This
302  * function uses the event interface. Callbacks will only be generated when
303  * event_loop() is called. */
304 #define security_recvpkt(handle, fn, arg, timeout)      \
305     (*(handle)->driver->recvpkt)(handle, fn, arg, timeout)
306
307 /* void security_recvpkt_cancel(security_handle_t *);
308  *
309  * Cancels a previous recvpkt request for this handle. */
310 #define security_recvpkt_cancel(handle)         \
311     (*(handle)->driver->recvpkt_cancel)(handle)
312
313 /* const char *security_geterror(security_handle_t *);
314  *
315  * Returns a descriptive error message for the last error condition on this
316  * handle. */
317 #define security_geterror(handle)       ((handle)->error)
318
319 /* Sets the string that security_geterror() returns.  For use by security
320  * drivers. */
321 void security_seterror(security_handle_t *, const char *, ...)
322      G_GNUC_PRINTF(2,3);
323
324 /* Initializes a security_handle_t. This is meant to be called only by security
325  * drivers to initialize the common part of a newly allocated
326  * security_handle_t.  */
327 void security_handleinit(security_handle_t *, const security_driver_t *);
328
329 /*
330  * Streams
331  */
332
333 /*
334  * This structure is a handle to a stream connection to a host for
335  * transmission of random data such as dumps or index data.
336  */
337 typedef struct security_stream {
338     const security_driver_t *driver;
339     char *error;
340 } security_stream_t;
341
342 /* Initializes a security_stream_t. This is meant to be called only by security
343  * drivers to initialize the common part of a newly allocated
344  * security_stream_t. */
345 void security_streaminit(security_stream_t *, const security_driver_t *);
346
347 /* const char *security_stream_geterror(security_stream_t *);
348  *
349  * Returns a descriptive error message for the last error condition on this
350  * stream. */
351 #define security_stream_geterror(stream)        ((stream)->error)
352
353 /* Sets the string that security_stream_geterror() returns. */
354 void security_stream_seterror(security_stream_t *, const char *, ...)
355      G_GNUC_PRINTF(2,3);
356
357 /* security_stream_t *security_stream_server(security_handle_t *);
358  *
359  * Creates the server end of a security stream, and will prepare to receive a
360  * connection from the host on the other end of the security handle passed.
361  * Returns a security_stream_t on success, and NULL on error. Error messages
362  * can be obtained by calling security_geterror() on the security handle
363  * associated with this stream. */
364 #define security_stream_server(handle)  \
365     (*(handle)->driver->stream_server)(handle)
366
367 /* int security_stream_accept(security_stream_t *);
368  *
369  * Given a security stream created by security_stream_server, blocks until a
370  * connection is made from the remote end.  After calling stream_server,
371  * stream_accept must be called on the stream before it is fully connected.
372  * Returns 0 on success, and -1 on error. Error messages can be obtained by
373  * calling security_stream_geterror().
374  */
375 #define security_stream_accept(stream)          \
376     (*(stream)->driver->stream_accept)(stream)
377
378 /* security_stream_t *security_stream_client(security_handle_t *, int);
379  *
380  * Creates the client end of a security stream, and connects it to the machine
381  * on the other end of the security handle. The 'id' argument identifies which
382  * stream on the other end to connect to, and should have come from
383  * security_stream_id on the other end of the connection.  Returns a
384  * security_stream_t on success, and NULL on error. Error messages can be
385  * obtained by calling security_geterror() on the security handle associated
386  * with this stream. */
387 #define security_stream_client(handle, id)      \
388     (*(handle)->driver->stream_client)(handle, id)
389
390 /* Closes a security stream and frees up resources associated with it. */
391 void security_stream_close(security_stream_t *);
392
393 /* int security_stream_auth(security_stream_t *);
394  *
395  * Authenticate a connected security stream.  This should be called by the
396  * target after security_stream_accept returns successfully, and by the client
397  * after security_stream_connect returns successfullly. Returns 0 on success,
398  * and -1 on error. Error messages can be obtained by calling
399  * security_stream_geterror().
400  */
401 #define security_stream_auth(stream)            \
402     (*(stream)->driver->stream_auth)(stream)
403
404 /* int security_stream_id(security_stream_t *);
405  *
406  * Returns an identifier which can be used to connect to this security stream
407  * with security_stream_client().  Typical usage is for one end of a connection
408  * to create a stream with security_stream_server(), and then transmit the id
409  * for that stream to the other side. The other side will then connect to that
410  * id with security_stream_client(). */
411 #define security_stream_id(stream)              \
412     (*(stream)->driver->stream_id)(stream)
413
414 /* int security_stream_write(security_stream_t *, const void *, size_t);
415  *
416  * Writes a chunk of data to the security stream. Returns 0 on success, or
417  * negative on error. Error messages can be obtained by calling
418  * security_stream_geterror().
419  */
420 #define security_stream_write(stream, buf, size)        \
421     (*(stream)->driver->stream_write)(stream, buf, size)
422
423 /* void security_stream_read(
424  *  security_stream_t *stream,
425  *  void (*fn)(void *, void *, size_t),
426  *  void *arg);
427
428  * Requests that when data is ready to be read on this stream, the given
429  * function is called with the given arg, a buffer full of data, and the size
430  * of that buffer. On error, the bufsize will be negative. An error message can
431  * be retrieved by calling security_stream_geterror().  This function uses the
432  * event interface. Callbacks will only be generated while in event_loop(). */
433 #define security_stream_read(stream, fn, arg)           \
434     (*(stream)->driver->stream_read)(stream, fn, arg)
435
436 /* void security_stream_read_sync(security_stream_t *, void **);
437  *
438  * Return a buffer of data read from the stream. This function will block until
439  * something can be read, but other event will be fired. A pointer to the data
440  * is returned in *buf and the size of the buffer is returned.  On error, the
441  * size will be negative. An error message can be retrieved by calling
442  * security_stream_geterror(). This function uses the event interface.  */
443 #define security_stream_read_sync(stream, buf)          \
444     (*(stream)->driver->stream_read_sync)(stream, buf)
445
446 /* void security_stream_read_cancel(security_stream_t *);
447  *
448  * Cancels a previous read request. */
449 #define security_stream_read_cancel(stream)             \
450     (*(stream)->driver->stream_read_cancel)(stream)
451
452 /* void security_close_connection(security_handle_t *, hostname *);
453  *
454  * Close a security handle, freeing associated resources.  The hostname
455  * argument is ignored. */
456 #define security_close_connection(handle, hostname) \
457     (*(handle)->driver->close_connection)(handle, hostname)
458
459 #endif  /* SECURITY_H */