1 /*
2  *  Copyright (C) 2004-2009 Christos Tsantilas
3  *
4  *  This program is free software; you can redistribute it and/or
5  *  modify it under the terms of the GNU Lesser General Public
6  *  License as published by the Free Software Foundation; either
7  *  version 2.1 of the License, or (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  *  Lesser General Public License for more details.
13  *
14  *  You should have received a copy of the GNU Lesser General Public
15  *  License along with this library; if not, write to the Free Software
16  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17  *  MA  02110-1301  USA.
18  */
19 
20 #ifndef __ACL_H
21 #define __ACL_H
22 
23 #include "c-icap.h"
24 #include "net_io.h"
25 #include "types_ops.h"
26 
27 #ifdef __cplusplus
28 extern "C"
29 {
30 #endif
31 
32 /**
33  \defgroup ACL Access lists API
34  \ingroup API
35  * Access control lists related API. Structures, functions and macros used
36  * to define custom acl types, and use access control lists in services
37  * and modules.
38  */
39 
40 #define MAX_NAME_LEN 31
41 
42 /*ACL type structures and functions */
43 struct ci_request;
44 /**
45  \ingroup ACL
46  * This is the struct used to implement an acl type object.
47  */
48 typedef struct ci_acl_type {
49 
50     /**
51        \brief The acl type name
52      */
53     char name[MAX_NAME_LEN+1];
54 
55     /**
56      \brief Pointer to the functions which retrieves the test data for
57      *      this acl type
58      *
59      * This method extract the test data from request object for this acl
60      * object. For example for the "src" acl type this function will extract
61      * the icap client ip address
62      \param req Pointer to the related ci_request_t object
63      \param param Some acl types supports one parameter passed by the c-icap
64      *            administrator
65      \return A pointer to the test data
66     */
67     void *(*get_test_data)(struct ci_request *req, char *param);
68 
69     /**
70      \brief Pointer to the function which release the acl test data
71      *      (if required)
72      *
73      * This method releases the acl test data,which  allocated using the
74      * get_test_data method
75      \param req Pointer to the related ci_request_t object
76      \param data Pointer to allocated test data
77      */
78     void (*free_test_data)(struct ci_request *req, void *data);
79 
80     /**
81      \brief Pointer to the ci_types_ops_t struct which implements basic
82      *      operations for the acl test data
83      */
84     const ci_type_ops_t *type;
85 } ci_acl_type_t;
86 
87 struct ci_acl_type_list {
88     ci_acl_type_t *acl_type_list;
89     int acl_type_list_size;
90     int acl_type_list_num;
91 };
92 
93 int ci_acl_typelist_init(struct ci_acl_type_list *list);
94 int ci_acl_typelist_add(struct ci_acl_type_list *list, const ci_acl_type_t *type);
95 int ci_acl_typelist_release(struct ci_acl_type_list *list);
96 int ci_acl_typelist_reset(struct ci_acl_type_list *list);
97 const ci_acl_type_t *ci_acl_typelist_search(struct ci_acl_type_list *list, const char *name);
98 
99 
100 /*ACL specs structures and functions */
101 
102 typedef struct ci_acl_data ci_acl_data_t;
103 struct ci_acl_data {
104     void *data;
105     ci_acl_data_t *next;
106 };
107 
108 /**
109    \brief This struct holds an access control list (acl).
110    \ingroup ACL
111    *
112    * Imagine the following access control list defined in the c-icap config
113    * file:\n
114    * \code acl LOCALNET 127.0.0.1/255.255.255.255 192.168.1.0/255.255.255.0
115    * \endcode
116    * This struct represents access control lists like the above
117  */
118 typedef struct ci_acl_spec ci_acl_spec_t;
119 struct ci_acl_spec {
120     char name[MAX_NAME_LEN + 1];
121     const ci_acl_type_t *type;
122     char *parameter;
123     ci_acl_data_t *data;
124     ci_acl_spec_t *next;
125 };
126 
127 /*Specs lists and access entries structures and functions */
128 typedef struct ci_specs_list ci_specs_list_t;
129 struct ci_specs_list {
130     const ci_acl_spec_t *spec;
131     int negate;
132     ci_specs_list_t *next;
133 };
134 
135 /**
136  \brief An access entry object holds an access control list, and can be
137  *      connected to linked lists of access entries.
138  \ingroup ACL
139  *
140  * This struct used to implement lists of access control lists.
141  * Each access entry can hold an "allow" or "deny" access control list.
142  * An access entries list represents the following c-icap config lines:
143  * \code
144  *  icap_access allow LOCALNET LOCALHOST
145  *  icap_access deny ALL
146  * \endcode
147  * each of the above lines represented by an ci_access_entry object.
148  * The ci_access_entry objects can be connected to a simple linked list.
149  *
150  */
151 typedef struct ci_access_entry ci_access_entry_t;
152 struct ci_access_entry {
153     int type;   /*CI_ACCESS_DENY or CI_ACCESS_ALLOW*/
154     ci_specs_list_t *spec_list;
155     ci_access_entry_t *next;
156 };
157 
158 /**
159  \brief Append a new access entry object to an access entries list
160  \ingroup ACL
161  *
162  \param list Pointer to the access entry list
163  \param type CI_ACCESS_ALLOW if CI_ACCESS_DENY to specify if this access entry holds an "allow" or "deny" access control list
164  \return A pointer to the newly created access entry object
165  */
166 CI_DECLARE_FUNC(ci_access_entry_t *) ci_access_entry_new(ci_access_entry_t **list, int type);
167 
168 /**
169  \brief Destroy an access entries list
170  \ingroup ACL
171  *
172  \param list Pointer to the access entries list
173 */
174 CI_DECLARE_FUNC(void) ci_access_entry_release(ci_access_entry_t *list);
175 
176 CI_DECLARE_FUNC(const ci_acl_spec_t *) ci_access_entry_add_acl(ci_access_entry_t *access_entry, const ci_acl_spec_t *acl, int negate);
177 
178 /**
179  \brief Add an acl to an access entry object
180  \ingroup ACL
181  *
182  \param access_entry Pointer to the access entry  object
183  \param aclname The name of the acl to be added.
184  \return non zero on success, zero otherwise
185  */
186 CI_DECLARE_FUNC(int) ci_access_entry_add_acl_by_name(ci_access_entry_t *access_entry, const char *aclname);
187 
188 /**
189  \brief Check if an access entries list matches a request object
190  \ingroup ACL
191  *
192  \param access_entry Pointer to the access entries list (a linked list of
193  *                   ci_access_entry_t objects)
194  \param req pointer to the request object (ci_request_t object)
195  \return CI_ACCESS_ALLOW if request matches the access list, CI_ACCESS_DENY
196  *       otherwise
197  */
198 CI_DECLARE_FUNC(int) ci_access_entry_match_request(ci_access_entry_t *access_entry, ci_request_t *req);
199 
200 
201 /*Inititalizing, reseting and tools acl library functions */
202 
203 /**
204  \brief Initializes the c-icap acl subsystem. It is not thread safe
205  \ingroup ACL
206  */
207 CI_DECLARE_FUNC(void) ci_acl_init();
208 
209 /**
210  \brief Resets the c-icap acl subsystem. It is not thread safe
211  \ingroup ACL
212  */
213 CI_DECLARE_FUNC(void) ci_acl_reset();
214 
215 /**
216  \brief Destroys the c-icap acl subsystem.
217  \ingroup ACL
218  */
219 CI_DECLARE_FUNC(void) ci_acl_destroy();
220 
221 CI_DECLARE_FUNC(const ci_acl_spec_t *) ci_acl_search(const char *name);
222 CI_DECLARE_FUNC(int) ci_acl_add_data(const char *name, const char *type, const char *data);
223 
224 /**
225  \brief Search for an acl type
226  \ingroup ACL
227  *
228  \param name The name of the acl type
229  \return Pointer to the ci_acl_type_t structure which implements the acl type,
230  *       or NULL
231  */
232 CI_DECLARE_FUNC(const ci_acl_type_t *) ci_acl_type_search(const char *name);
233 
234 /**
235  \brief Add a custom acl type to the c-icap acl subsystem
236  \ingroup ACL
237  *
238  \param type Pointer to the c-acl_type_t struct which implements the acl type
239  \return non zero on success, zero otherwise
240  */
241 CI_DECLARE_FUNC(int) ci_acl_type_add(const ci_acl_type_t *type);
242 
243 #ifdef __cplusplus
244 }
245 #endif
246 
247 #endif/* __ACL_H*/
248