b1d8faa7a26480c7311695506e438659721dd652
[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
39 struct sec_handle;
40
41 /*
42  * This is a sec connection to a host.  We should only have
43  * one connection per host.
44  */
45 struct tcp_conn {
46     const struct security_driver *driver;       /* MUST be first */
47     int                 read, write;            /* pipes to sec */
48     pid_t               pid;                    /* pid of sec process */
49     char *              pkt;                    /* last pkt read */
50     ssize_t             pktlen;                 /* len of above */
51     event_handle_t *    ev_read;                /* read (EV_READFD) handle */
52     int                 ev_read_refcnt;         /* number of readers */
53     char                hostname[MAX_HOSTNAME_LENGTH+1];
54                                                 /* host we're talking to */
55     char *              errmsg;                 /* error passed up */
56     int                 refcnt;                 /* number of handles using */
57     int                 handle;                 /* last proto handle read */
58     void                (*accept_fn)(security_handle_t *, pkt_t *);
59     struct sockaddr_in  peer;
60     TAILQ_ENTRY(tcp_conn) tq;                   /* queue handle */
61     int                 (*recv_security_ok)(struct sec_handle *, pkt_t *);
62     char *              (*prefix_packet)(void *, pkt_t *);
63     int                 toclose;
64     int                 donotclose;
65 };
66
67
68 struct sec_stream;
69
70 /*
71  * This is the private handle data.
72  */
73 struct sec_handle {
74     security_handle_t   sech;           /* MUST be first */
75     char *              hostname;       /* ptr to rc->hostname */
76     struct sec_stream * rs;             /* virtual stream we xmit over */
77     struct tcp_conn *   rc;             /* */
78     union {
79         void (*recvpkt)(void *, pkt_t *, security_status_t);
80                                         /* func to call when packet recvd */
81         void (*connect)(void *, security_handle_t *, security_status_t);
82                                         /* func to call when connected */
83     } fn;
84     void *              arg;            /* argument to pass function */
85     event_handle_t *    ev_timeout;     /* timeout handle for recv */
86     struct sockaddr_in  peer;
87     int                 sequence;
88     event_id_t          event_id;
89     char *              proto_handle;
90     event_handle_t *    ev_read;
91     struct sec_handle * prev;
92     struct sec_handle * next;
93     struct udp_handle * udp;
94     void                (*accept_fn)(security_handle_t *, pkt_t *);
95     int                 (*recv_security_ok)(struct sec_handle *, pkt_t *);
96 };
97
98 /*
99  * This is the internal security_stream data for sec.
100  */
101 struct sec_stream {
102     security_stream_t   secstr;         /* MUST be first */
103     struct tcp_conn *   rc;             /* physical connection */
104     int                 handle;         /* protocol handle */
105     event_handle_t *    ev_read;        /* read (EV_WAIT) event handle */
106     void                (*fn)(void *, void *, ssize_t); /* read event fn */
107     void *              arg;            /* arg for previous */
108     int                 fd;
109     char                databuf[NETWORK_BLOCK_BYTES];
110     ssize_t             len;
111     int                 socket;
112     in_port_t           port;
113     int                 closed_by_me;
114     int                 closed_by_network;
115 };
116
117 struct connq_s {
118     TAILQ_HEAD(, tcp_conn) tailq;
119     int qlength;
120 };
121 extern struct connq_s connq;
122
123 #define connq_first()           TAILQ_FIRST(&connq.tailq)
124 #define connq_next(rc)          TAILQ_NEXT(rc, tq)
125 #define connq_append(rc)        do {                                    \
126     TAILQ_INSERT_TAIL(&connq.tailq, rc, tq);                            \
127     connq.qlength++;                                                    \
128 } while (0)
129 #define connq_remove(rc)        do {                                    \
130     assert(connq.qlength > 0);                                          \
131     TAILQ_REMOVE(&connq.tailq, rc, tq);                                 \
132     connq.qlength--;                                                    \
133 } while (0)
134
135 /*
136  * This is data local to the datagram socket.  We have one datagram
137  * per process per auth.
138  */
139 typedef struct udp_handle {
140     const struct security_driver *driver;       /* MUST be first */
141     dgram_t dgram;              /* datagram to read/write from */
142     struct sockaddr_in peer;    /* who sent it to us */
143     pkt_t pkt;                  /* parsed form of dgram */
144     char *handle;               /* handle from recvd packet */
145     int sequence;               /* seq no of packet */
146     event_handle_t *ev_read;    /* read event handle from dgram */
147     int refcnt;                 /* number of handles blocked for reading */
148     struct sec_handle *bh_first, *bh_last;
149     void (*accept_fn)(security_handle_t *, pkt_t *);
150     int (*recv_security_ok)(struct sec_handle *, pkt_t *);
151     char *(*prefix_packet)(void *, pkt_t *);
152 } udp_handle_t;
153
154 /*
155  * We register one event handler for our network fd which takes
156  * care of all of our async requests.  When all async requests
157  * have either been satisfied or cancelled, we unregister our
158  * network event handler.
159  */
160 #define udp_addref(udp, netfd_read_callback) do {                       \
161     if ((udp)->refcnt++ == 0) {                                         \
162         assert((udp)->ev_read == NULL);                                 \
163         (udp)->ev_read = event_register((event_id_t)(udp)->dgram.socket,\
164             EV_READFD, netfd_read_callback, (udp));                     \
165     }                                                                   \
166     assert((udp)->refcnt > 0);                                          \
167 } while (0)
168
169 /*
170  * If this is the last request to be removed, then remove the
171  * reader event from the netfd.
172  */
173 #define udp_delref(udp) do {                                            \
174     assert((udp)->refcnt > 0);                                          \
175     if (--(udp)->refcnt == 0) {                                         \
176         assert((udp)->ev_read != NULL);                                 \
177         event_release((udp)->ev_read);                                  \
178         (udp)->ev_read = NULL;                                          \
179     }                                                                   \
180 } while (0)
181
182
183 int     sec_stream_auth(void *);
184 int     sec_stream_id(void *);
185 void    sec_accept(const security_driver_t *, int, int,
186                     void (*)(security_handle_t *, pkt_t *));
187 void    sec_close(void *);
188 void    sec_connect_callback(void *);
189 void    sec_connect_timeout(void *);
190 void    sec_close_connection_none(void *, char *);
191
192 ssize_t stream_sendpkt(void *, pkt_t *);
193 void    stream_recvpkt(void *,
194                         void (*)(void *, pkt_t *, security_status_t),
195                         void *, int);
196 void    stream_recvpkt_timeout(void *);
197 void    stream_recvpkt_cancel(void *);
198
199 int     tcpm_stream_write(void *, const void *, size_t);
200 void    tcpm_stream_read(void *, void (*)(void *, void *, ssize_t), void *);
201 ssize_t tcpm_stream_read_sync(void *, void **);
202 void    tcpm_stream_read_cancel(void *);
203 ssize_t tcpm_send_token(int, int, char **, const void *, size_t);
204 ssize_t tcpm_recv_token(int, int *, char **, char **, ssize_t *, int);
205 void    tcpm_close_connection(void *, char *);
206
207 int     tcpma_stream_accept(void *);
208 void *  tcpma_stream_client(void *, int);
209 void *  tcpma_stream_server(void *);
210 void    tcpma_stream_close(void *);
211
212 void *  tcp1_stream_server(void *);
213 int     tcp1_stream_accept(void *);
214 void *  tcp1_stream_client(void *, int);
215
216 int     tcp_stream_write(void *, const void *, size_t);
217
218 char *  bsd_prefix_packet(void *, pkt_t *);
219 int     bsd_recv_security_ok(struct sec_handle *, pkt_t *);
220
221 ssize_t udpbsd_sendpkt(void *, pkt_t *);
222 void    udp_close(void *);
223 void    udp_recvpkt(void *, void (*)(void *, pkt_t *, security_status_t),
224                      void *, int);
225 void    udp_recvpkt_cancel(void *);
226 void    udp_recvpkt_callback(void *);
227 void    udp_recvpkt_timeout(void *);
228 int     udp_inithandle(udp_handle_t *, struct sec_handle *, struct hostent *,
229                         in_port_t, char *, int);
230 void    udp_netfd_read_callback(void *);
231
232 struct tcp_conn *sec_tcp_conn_get(const char *, int);
233 void    sec_tcp_conn_put(struct tcp_conn *);
234 void    sec_tcp_conn_read(struct tcp_conn *);
235 void    parse_pkt(pkt_t *, const void *, size_t);
236 const char *pkthdr2str(const struct sec_handle *, const pkt_t *);
237 int     str2pkthdr(udp_handle_t *);
238 char *  check_user(struct sec_handle *, const char *, const char *);
239
240 char *  check_user_ruserok    (const char *host,
241                                 struct passwd *pwd,
242                                 const char *user);
243 char *  check_user_amandahosts(const char *host,
244                                 struct in_addr addr,
245                                 struct passwd *pwd,
246                                 const char *user,
247                                 const char *service);
248
249 ssize_t net_writev(int, struct iovec *, int);
250 ssize_t net_read(int, void *, size_t, int);
251 ssize_t net_read_fillbuf(int, int, void *, size_t);
252 void    show_stat_info(char *a, char *b);
253
254 #endif /* _SECURITY_INFO_H */