Imported Upstream version 2.5.2p1
[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,x) do {            \
43         if ((i) <= debug_auth) {        \
44             dbprintf(x);                \
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     void                (*accept_fn)(security_handle_t *, pkt_t *);
79     struct sockaddr_storage     peer;
80     TAILQ_ENTRY(tcp_conn) tq;                   /* queue handle */
81     int                 (*recv_security_ok)(struct sec_handle *, pkt_t *);
82     char *              (*prefix_packet)(void *, pkt_t *);
83     int                 toclose;
84     int                 donotclose;
85     int                 auth;
86 #ifdef KRB5_SECURITY
87     gss_ctx_id_t        gss_context;
88 #endif
89 };
90
91
92 struct sec_stream;
93
94 /*
95  * This is the private handle data.
96  */
97 struct sec_handle {
98     security_handle_t   sech;           /* MUST be first */
99     char *              hostname;       /* ptr to rc->hostname */
100     struct sec_stream * rs;             /* virtual stream we xmit over */
101     struct tcp_conn *   rc;             /* */
102     union {
103         void (*recvpkt)(void *, pkt_t *, security_status_t);
104                                         /* func to call when packet recvd */
105         void (*connect)(void *, security_handle_t *, security_status_t);
106                                         /* func to call when connected */
107     } fn;
108     void *              arg;            /* argument to pass function */
109     event_handle_t *    ev_timeout;     /* timeout handle for recv */
110     struct sockaddr_storage     peer;
111     int                 sequence;
112     event_id_t          event_id;
113     char *              proto_handle;
114     event_handle_t *    ev_read;
115     struct sec_handle * prev;
116     struct sec_handle * next;
117     struct udp_handle * udp;
118     void                (*accept_fn)(security_handle_t *, pkt_t *);
119     int                 (*recv_security_ok)(struct sec_handle *, pkt_t *);
120 };
121
122 /*
123  * This is the internal security_stream data for sec.
124  */
125 struct sec_stream {
126     security_stream_t   secstr;         /* MUST be first */
127     struct tcp_conn *   rc;             /* physical connection */
128     int                 handle;         /* protocol handle */
129     event_handle_t *    ev_read;        /* read (EV_WAIT) event handle */
130     void                (*fn)(void *, void *, ssize_t); /* read event fn */
131     void *              arg;            /* arg for previous */
132     int                 fd;
133     char                databuf[NETWORK_BLOCK_BYTES];
134     ssize_t             len;
135     int                 socket;
136     in_port_t           port;
137     int                 closed_by_me;
138     int                 closed_by_network;
139 };
140
141 struct connq_s {
142     TAILQ_HEAD(, tcp_conn) tailq;
143     int qlength;
144 };
145 extern struct connq_s connq;
146
147 #define connq_first()           TAILQ_FIRST(&connq.tailq)
148 #define connq_next(rc)          TAILQ_NEXT(rc, tq)
149 #define connq_append(rc)        do {                                    \
150     TAILQ_INSERT_TAIL(&connq.tailq, rc, tq);                            \
151     connq.qlength++;                                                    \
152 } while (0)
153 #define connq_remove(rc)        do {                                    \
154     assert(connq.qlength > 0);                                          \
155     TAILQ_REMOVE(&connq.tailq, rc, tq);                                 \
156     connq.qlength--;                                                    \
157 } while (0)
158
159 /*
160  * This is data local to the datagram socket.  We have one datagram
161  * per process per auth.
162  */
163 typedef struct udp_handle {
164     const struct security_driver *driver;       /* MUST be first */
165     dgram_t dgram;              /* datagram to read/write from */
166     struct sockaddr_storage peer;       /* who sent it to us */
167     pkt_t pkt;                  /* parsed form of dgram */
168     char *handle;               /* handle from recvd packet */
169     int sequence;               /* seq no of packet */
170     event_handle_t *ev_read;    /* read event handle from dgram */
171     int refcnt;                 /* number of handles blocked for reading */
172     struct sec_handle *bh_first, *bh_last;
173     void (*accept_fn)(security_handle_t *, pkt_t *);
174     int (*recv_security_ok)(struct sec_handle *, pkt_t *);
175     char *(*prefix_packet)(void *, pkt_t *);
176 } udp_handle_t;
177
178 /*
179  * We register one event handler for our network fd which takes
180  * care of all of our async requests.  When all async requests
181  * have either been satisfied or cancelled, we unregister our
182  * network event handler.
183  */
184 #define udp_addref(udp, netfd_read_callback) do {                       \
185     if ((udp)->refcnt++ == 0) {                                         \
186         assert((udp)->ev_read == NULL);                                 \
187         (udp)->ev_read = event_register((event_id_t)(udp)->dgram.socket,\
188             EV_READFD, netfd_read_callback, (udp));                     \
189     }                                                                   \
190     assert((udp)->refcnt > 0);                                          \
191 } while (0)
192
193 /*
194  * If this is the last request to be removed, then remove the
195  * reader event from the netfd.
196  */
197 #define udp_delref(udp) do {                                            \
198     assert((udp)->refcnt > 0);                                          \
199     if (--(udp)->refcnt == 0) {                                         \
200         assert((udp)->ev_read != NULL);                                 \
201         event_release((udp)->ev_read);                                  \
202         (udp)->ev_read = NULL;                                          \
203     }                                                                   \
204 } while (0)
205
206
207 int     sec_stream_auth(void *);
208 int     sec_stream_id(void *);
209 void    sec_accept(const security_driver_t *, int, int,
210                     void (*)(security_handle_t *, pkt_t *));
211 void    sec_close(void *);
212 void    sec_connect_callback(void *);
213 void    sec_connect_timeout(void *);
214 void    sec_close_connection_none(void *, char *);
215
216 ssize_t stream_sendpkt(void *, pkt_t *);
217 void    stream_recvpkt(void *,
218                         void (*)(void *, pkt_t *, security_status_t),
219                         void *, int);
220 void    stream_recvpkt_timeout(void *);
221 void    stream_recvpkt_cancel(void *);
222
223 int     tcpm_stream_write(void *, const void *, size_t);
224 void    tcpm_stream_read(void *, void (*)(void *, void *, ssize_t), void *);
225 ssize_t tcpm_stream_read_sync(void *, void **);
226 void    tcpm_stream_read_cancel(void *);
227 ssize_t tcpm_send_token(struct tcp_conn *, int, int, char **, const void *, size_t);
228 ssize_t tcpm_recv_token(struct tcp_conn *, int, int *, char **, char **, ssize_t *, int);
229 void    tcpm_close_connection(void *, char *);
230
231 int     tcpma_stream_accept(void *);
232 void *  tcpma_stream_client(void *, int);
233 void *  tcpma_stream_server(void *);
234 void    tcpma_stream_close(void *);
235
236 void *  tcp1_stream_server(void *);
237 int     tcp1_stream_accept(void *);
238 void *  tcp1_stream_client(void *, int);
239
240 int     tcp_stream_write(void *, const void *, size_t);
241
242 char *  bsd_prefix_packet(void *, pkt_t *);
243 int     bsd_recv_security_ok(struct sec_handle *, pkt_t *);
244
245 ssize_t udpbsd_sendpkt(void *, pkt_t *);
246 void    udp_close(void *);
247 void    udp_recvpkt(void *, void (*)(void *, pkt_t *, security_status_t),
248                      void *, int);
249 void    udp_recvpkt_cancel(void *);
250 void    udp_recvpkt_callback(void *);
251 void    udp_recvpkt_timeout(void *);
252 int     udp_inithandle(udp_handle_t *, struct sec_handle *, char *hostname,
253                        struct sockaddr_storage *, in_port_t, char *, int);
254 void    udp_netfd_read_callback(void *);
255
256 struct tcp_conn *sec_tcp_conn_get(const char *, int);
257 void    sec_tcp_conn_put(struct tcp_conn *);
258 void    sec_tcp_conn_read(struct tcp_conn *);
259 void    parse_pkt(pkt_t *, const void *, size_t);
260 const char *pkthdr2str(const struct sec_handle *, const pkt_t *);
261 int     str2pkthdr(udp_handle_t *);
262 char *  check_user(struct sec_handle *, const char *, const char *);
263
264 char *  check_user_ruserok    (const char *host,
265                                 struct passwd *pwd,
266                                 const char *user);
267 char *  check_user_amandahosts(const char *host,
268                                 struct sockaddr_storage *addr,
269                                 struct passwd *pwd,
270                                 const char *user,
271                                 const char *service);
272
273 ssize_t net_writev(int, struct iovec *, int);
274 ssize_t net_read(int, void *, size_t, int);
275 ssize_t net_read_fillbuf(int, int, void *, size_t);
276 void    show_stat_info(char *a, char *b);
277 int     check_name_give_sockaddr(const char *hostname, struct sockaddr *addr,
278                                  char **errstr);
279 int     check_addrinfo_give_name(struct addrinfo *res, const char *hostname,
280                                  char **errstr);
281 int     try_resolving_hostname(const char *hostname,
282                                char **cannonname);
283
284 #endif /* _SECURITY_INFO_H */