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