93b234f6f4fdb526fba1d964658a96b0fe48e84c
[debian/amanda] / common-src / security-util.h
1 #ifndef _SECURITY_UTIL_H
2 #define _SECURITY_UTIL_H
3
4 /*
5  * Amanda, The Advanced Maryland Automatic Network Disk Archiver
6  * Copyright (c) 1999 University of Maryland
7  * All Rights Reserved.
8  *
9  * Permission to use, copy, modify, distribute, and sell this software and its
10  * documentation for any purpose is hereby granted without fee, provided that
11  * the above copyright notice appear in all copies and that both that
12  * copyright notice and this permission notice appear in supporting
13  * documentation, and that the name of U.M. not be used in advertising or
14  * publicity pertaining to distribution of the software without specific,
15  * written prior permission.  U.M. makes no representations about the
16  * suitability of this software for any purpose.  It is provided "as is"
17  * without express or implied warranty.
18  *
19  * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
21  * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
22  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
23  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
24  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
25  *
26  * Authors: the Amanda Development Team.  Its members are listed in a
27  * file named AUTHORS, in the root directory of this distribution.
28  */
29
30 /*
31  * $Id: security-util.h,v 1.5 2006/07/01 00:10:38 paddy_s Exp $
32  *
33  */
34
35 #include "stream.h"
36 #include "dgram.h"
37 #include "queue.h"
38 #include "conffile.h"
39 #include "security.h"
40 #include "event.h"
41
42 #define auth_debug(i, ...) do {         \
43         if ((i) <= debug_auth) {        \
44             dbprintf(__VA_ARGS__);      \
45         }                               \
46 } while (0)
47
48
49 #ifdef KRB5_SECURITY
50 #  define KRB5_DEPRECATED 1
51 #  ifndef KRB5_HEIMDAL_INCLUDES
52 #    include <gssapi/gssapi_generic.h>
53 #  else
54 #    include <gssapi/gssapi.h>
55 #  endif
56 #  include <krb5.h>
57 #endif
58
59 struct sec_handle;
60
61 /*
62  * This is a sec connection to a host.  We should only have
63  * one connection per host.
64  */
65 struct tcp_conn {
66     const struct security_driver *driver;       /* MUST be first */
67     int                 read, write;            /* pipes to sec */
68     pid_t               pid;                    /* pid of sec process */
69     char *              pkt;                    /* last pkt read */
70     ssize_t             pktlen;                 /* len of above */
71     event_handle_t *    ev_read;                /* read (EV_READFD) handle */
72     int                 ev_read_refcnt;         /* number of readers */
73     char                hostname[MAX_HOSTNAME_LENGTH+1];
74                                                 /* host we're talking to */
75     char *              errmsg;                 /* error passed up */
76     int                 refcnt;                 /* number of handles using */
77     int                 handle;                 /* last proto handle read */
78     int                 event_id;               /* event ID fired when token read */
79     void                (*accept_fn)(security_handle_t *, pkt_t *);
80     sockaddr_union      peer;
81     TAILQ_ENTRY(tcp_conn) tq;                   /* queue handle */
82     int                 (*recv_security_ok)(struct sec_handle *, pkt_t *);
83     char *              (*prefix_packet)(void *, pkt_t *);
84     int                 toclose;
85     int                 donotclose;
86     int                 auth;
87     char *              (*conf_fn)(char *, void *);
88     void *              datap;
89 #ifdef KRB5_SECURITY
90     gss_ctx_id_t        gss_context;
91 #endif
92 };
93
94
95 struct sec_stream;
96
97 /*
98  * This is the private handle data.
99  */
100 struct sec_handle {
101     security_handle_t   sech;           /* MUST be first */
102     char *              hostname;       /* ptr to rc->hostname */
103     struct sec_stream * rs;             /* virtual stream we xmit over */
104     struct tcp_conn *   rc;             /* */
105     union {
106         void (*recvpkt)(void *, pkt_t *, security_status_t);
107                                         /* func to call when packet recvd */
108         void (*connect)(void *, security_handle_t *, security_status_t);
109                                         /* func to call when connected */
110     } fn;
111     void *              arg;            /* argument to pass function */
112     event_handle_t *    ev_timeout;     /* timeout handle for recv */
113     sockaddr_union      peer;
114     int                 sequence;
115     event_id_t          event_id;
116     char *              proto_handle;
117     event_handle_t *    ev_read;
118     struct sec_handle * prev;
119     struct sec_handle * next;
120     struct udp_handle * udp;
121     void                (*accept_fn)(security_handle_t *, pkt_t *);
122     int                 (*recv_security_ok)(struct sec_handle *, pkt_t *);
123 };
124
125 /*
126  * This is the internal security_stream data for sec.
127  */
128 struct sec_stream {
129     security_stream_t   secstr;         /* MUST be first */
130     struct tcp_conn *   rc;             /* physical connection */
131     int                 handle;         /* protocol handle */
132     event_handle_t *    ev_read;        /* read (EV_WAIT) event handle */
133     void                (*fn)(void *, void *, ssize_t); /* read event fn */
134     void *              arg;            /* arg for previous */
135     int                 fd;
136     char                databuf[NETWORK_BLOCK_BYTES];
137     ssize_t             len;
138     int                 socket;
139     in_port_t           port;
140     int                 closed_by_me;
141     int                 closed_by_network;
142 };
143
144 struct connq_s {
145     TAILQ_HEAD(, tcp_conn) tailq;
146     int qlength;
147 };
148 extern struct connq_s connq;
149
150 #define connq_first()           TAILQ_FIRST(&connq.tailq)
151 #define connq_next(rc)          TAILQ_NEXT(rc, tq)
152 #define connq_append(rc)        do {                                    \
153     TAILQ_INSERT_TAIL(&connq.tailq, rc, tq);                            \
154     connq.qlength++;                                                    \
155 } while (0)
156 #define connq_remove(rc)        do {                                    \
157     assert(connq.qlength > 0);                                          \
158     TAILQ_REMOVE(&connq.tailq, rc, tq);                                 \
159     connq.qlength--;                                                    \
160 } while (0)
161
162 /*
163  * This is data local to the datagram socket.  We have one datagram
164  * per process per auth.
165  */
166 typedef struct udp_handle {
167     const struct security_driver *driver;       /* MUST be first */
168     dgram_t dgram;              /* datagram to read/write from */
169     sockaddr_union peer;        /* who sent it to us */
170     pkt_t pkt;                  /* parsed form of dgram */
171     char *handle;               /* handle from recvd packet */
172     int sequence;               /* seq no of packet */
173     event_handle_t *ev_read;    /* read event handle from dgram */
174     int refcnt;                 /* number of handles blocked for reading */
175     struct sec_handle *bh_first, *bh_last;
176     void (*accept_fn)(security_handle_t *, pkt_t *);
177     int (*recv_security_ok)(struct sec_handle *, pkt_t *);
178     char *(*prefix_packet)(void *, pkt_t *);
179 } udp_handle_t;
180
181 /*
182  * We register one event handler for our network fd which takes
183  * care of all of our async requests.  When all async requests
184  * have either been satisfied or cancelled, we unregister our
185  * network event handler.
186  */
187 #define udp_addref(udp, netfd_read_callback) do {                       \
188     if ((udp)->refcnt++ == 0) {                                         \
189         assert((udp)->ev_read == NULL);                                 \
190         (udp)->ev_read = event_register((event_id_t)(udp)->dgram.socket,\
191             EV_READFD, netfd_read_callback, (udp));                     \
192     }                                                                   \
193     assert((udp)->refcnt > 0);                                          \
194 } while (0)
195
196 /*
197  * If this is the last request to be removed, then remove the
198  * reader event from the netfd.
199  */
200 #define udp_delref(udp) do {                                            \
201     assert((udp)->refcnt > 0);                                          \
202     if (--(udp)->refcnt == 0) {                                         \
203         assert((udp)->ev_read != NULL);                                 \
204         event_release((udp)->ev_read);                                  \
205         (udp)->ev_read = NULL;                                          \
206     }                                                                   \
207 } while (0)
208
209
210 int     sec_stream_auth(void *);
211 int     sec_stream_id(void *);
212 void    sec_accept(const security_driver_t *,
213                    char *(*)(char *, void *),
214                    int, int,
215                    void (*)(security_handle_t *, pkt_t *),
216                    void *);
217 void    sec_close(void *);
218 void    sec_connect_callback(void *);
219 void    sec_connect_timeout(void *);
220 void    sec_close_connection_none(void *, char *);
221
222 ssize_t stream_sendpkt(void *, pkt_t *);
223 void    stream_recvpkt(void *,
224                         void (*)(void *, pkt_t *, security_status_t),
225                         void *, int);
226 void    stream_recvpkt_timeout(void *);
227 void    stream_recvpkt_cancel(void *);
228
229 int     tcpm_stream_write(void *, const void *, size_t);
230 void    tcpm_stream_read(void *, void (*)(void *, void *, ssize_t), void *);
231 ssize_t tcpm_stream_read_sync(void *, void **);
232 void    tcpm_stream_read_cancel(void *);
233 ssize_t tcpm_send_token(struct tcp_conn *, int, int, char **, const void *, size_t);
234 ssize_t tcpm_recv_token(struct tcp_conn *, int, int *, char **, char **, ssize_t *, int);
235 void    tcpm_close_connection(void *, char *);
236
237 int     tcpma_stream_accept(void *);
238 void *  tcpma_stream_client(void *, int);
239 void *  tcpma_stream_server(void *);
240 void    tcpma_stream_close(void *);
241
242 void *  tcp1_stream_server(void *);
243 int     tcp1_stream_accept(void *);
244 void *  tcp1_stream_client(void *, int);
245
246 int     tcp_stream_write(void *, const void *, size_t);
247
248 char *  bsd_prefix_packet(void *, pkt_t *);
249 int     bsd_recv_security_ok(struct sec_handle *, pkt_t *);
250
251 ssize_t udpbsd_sendpkt(void *, pkt_t *);
252 void    udp_close(void *);
253 void    udp_recvpkt(void *, void (*)(void *, pkt_t *, security_status_t),
254                      void *, int);
255 void    udp_recvpkt_cancel(void *);
256 void    udp_recvpkt_callback(void *);
257 void    udp_recvpkt_timeout(void *);
258 int     udp_inithandle(udp_handle_t *, struct sec_handle *, char *hostname,
259                        sockaddr_union *, in_port_t, char *, int);
260 void    udp_netfd_read_callback(void *);
261
262 struct tcp_conn *sec_tcp_conn_get(const char *, int);
263 void    sec_tcp_conn_put(struct tcp_conn *);
264 void    sec_tcp_conn_read(struct tcp_conn *);
265 void    parse_pkt(pkt_t *, const void *, size_t);
266 const char *pkthdr2str(const struct sec_handle *, const pkt_t *);
267 int     str2pkthdr(udp_handle_t *);
268 char *  check_user(struct sec_handle *, const char *, const char *);
269
270 char *  check_user_ruserok    (const char *host,
271                                 struct passwd *pwd,
272                                 const char *user);
273 char *  check_user_amandahosts(const char *host,
274                                 sockaddr_union *addr,
275                                 struct passwd *pwd,
276                                 const char *user,
277                                 const char *service);
278
279 ssize_t net_read(int, void *, size_t, int);
280 ssize_t net_read_fillbuf(int, int, void *, size_t);
281 void    show_stat_info(char *a, char *b);
282 int     check_name_give_sockaddr(const char *hostname, struct sockaddr *addr,
283                                  char **errstr);
284
285 #endif /* _SECURITY_INFO_H */