blob: 431e22b44ab290a679e8f49f53869333ae5493ca [file] [log] [blame]
Willy Tarreaua84d3742007-05-07 00:36:48 +02001/*
2 include/types/acl.h
3 This file provides structures and types for ACLs.
4
Willy Tarreau11382812008-07-09 16:18:21 +02005 Copyright (C) 2000-2008 Willy Tarreau - w@1wt.eu
Willy Tarreaua84d3742007-05-07 00:36:48 +02006
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation, version 2.1
10 exclusively.
11
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public
18 License along with this library; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20*/
21
22#ifndef _TYPES_ACL_H
23#define _TYPES_ACL_H
24
25#include <common/compat.h>
26#include <common/config.h>
27#include <common/mini-clist.h>
28
29#include <types/proxy.h>
30#include <types/session.h>
31
32
Willy Tarreau11382812008-07-09 16:18:21 +020033/* Pattern matching function result.
34 *
35 * We're using a 3-state matching system :
36 * - PASS : at least one pattern already matches
37 * - MISS : some data is missing to decide if some rules may finally match.
38 * - FAIL : no mattern may ever match
39 *
40 * We assign values 0, 1 and 3 to FAIL, MISS and PASS respectively, so that we
41 * can make use of standard arithmetics for the truth tables below :
42 *
43 * x | !x x&y | F(0) | M(1) | P(3) x|y | F(0) | M(1) | P(3)
44 * ------+----- -----+------+------+----- -----+------+------+-----
45 * F(0) | P(3) F(0)| F(0) | F(0) | F(0) F(0)| F(0) | M(1) | P(3)
46 * M(1) | M(1) M(1)| F(0) | M(1) | M(1) M(1)| M(1) | M(1) | P(3)
47 * P(3) | F(0) P(3)| F(0) | M(1) | P(3) P(3)| P(3) | P(3) | P(3)
48 *
49 * neg(x) = (3 >> x) and(x,y) = (x & y) or(x,y) = (x | y)
50 *
51 */
52
Willy Tarreaua84d3742007-05-07 00:36:48 +020053enum {
54 ACL_PAT_FAIL = 0, /* test failed */
Willy Tarreau11382812008-07-09 16:18:21 +020055 ACL_PAT_MISS = 1, /* test may pass with more info */
56 ACL_PAT_PASS = 3, /* test passed */
Willy Tarreaua84d3742007-05-07 00:36:48 +020057};
58
59/* Condition polarity. It makes it easier for any option to choose between
60 * IF/UNLESS if it can store that information within the condition itself.
Willy Tarreau11382812008-07-09 16:18:21 +020061 * Those should be interpreted as "IF/UNLESS result == PASS".
Willy Tarreaua84d3742007-05-07 00:36:48 +020062 */
63enum {
64 ACL_COND_NONE, /* no polarity set yet */
65 ACL_COND_IF, /* positive condition (after 'if') */
66 ACL_COND_UNLESS, /* negative condition (after 'unless') */
67};
68
69/* possible flags for intermediate test values. The flags are maintained
70 * across consecutive fetches for a same entry (eg: parse all req lines).
71 */
72enum {
73 ACL_TEST_F_READ_ONLY = 1 << 0, /* test data are read-only */
74 ACL_TEST_F_MUST_FREE = 1 << 1, /* test data must be freed after end of evaluation */
75 ACL_TEST_F_VOL_TEST = 1 << 2, /* result must not survive longer than the test (eg: time) */
76 ACL_TEST_F_VOL_HDR = 1 << 3, /* result sensitive to changes in headers */
77 ACL_TEST_F_VOL_1ST = 1 << 4, /* result sensitive to changes in first line (eg: URI) */
78 ACL_TEST_F_VOL_TXN = 1 << 5, /* result sensitive to new transaction (eg: persist) */
79 ACL_TEST_F_VOL_SESS = 1 << 6, /* result sensitive to new session (eg: IP) */
80 ACL_TEST_F_VOLATILE = (1<<2)|(1<<3)|(1<<4)|(1<<5)|(1<<6),
Willy Tarreaub6866442008-07-14 23:54:42 +020081 ACL_TEST_F_FETCH_MORE = 1 << 7, /* if test does not match, retry with next entry (for multi-match) */
82 ACL_TEST_F_MAY_CHANGE = 1 << 8, /* if test does not match, retry later (eg: request size) */
Willy Tarreaua79534f2008-07-20 10:13:37 +020083 ACL_TEST_F_RES_SET = 1 << 9, /* for fetch() function to assign the result without calling match() */
84 ACL_TEST_F_RES_PASS = 1 << 10,/* with SET_RESULT, sets result to PASS (defaults to FAIL) */
85 ACL_TEST_F_SET_RES_PASS = (ACL_TEST_F_RES_SET|ACL_TEST_F_RES_PASS), /* sets result to PASS */
86 ACL_TEST_F_SET_RES_FAIL = (ACL_TEST_F_RES_SET), /* sets result to FAIL */
Willy Tarreaua84d3742007-05-07 00:36:48 +020087};
88
Willy Tarreaub6866442008-07-14 23:54:42 +020089/* ACLs can be evaluated on requests and on responses, and on partial or complete data */
Willy Tarreaud41f8d82007-06-10 10:06:18 +020090enum {
91 ACL_DIR_REQ = 0, /* ACL evaluated on request */
Willy Tarreaub6866442008-07-14 23:54:42 +020092 ACL_DIR_RTR = (1 << 0), /* ACL evaluated on response */
93 ACL_DIR_MASK = (ACL_DIR_REQ | ACL_DIR_RTR),
94 ACL_PARTIAL = (1 << 1), /* partial data, return MISS if data are missing */
Willy Tarreaud41f8d82007-06-10 10:06:18 +020095};
96
Willy Tarreauc8d7c962007-06-17 08:20:33 +020097/* possible flags for expressions or patterns */
98enum {
99 ACL_PAT_F_IGNORE_CASE = 1 << 0, /* ignore case */
100 ACL_PAT_F_FROM_FILE = 1 << 1, /* pattern comes from a file */
101};
102
Willy Tarreaua9802632008-07-25 19:13:19 +0200103/* what capabilities an ACL uses. These flags are set during parsing, which
104 * allows for flexible ACLs typed by their contents.
105 */
106enum {
Willy Tarreau0ceba5a2008-07-25 19:31:03 +0200107 ACL_USE_NOTHING = 0, /* no need for anything beyond internal information */
Willy Tarreaua9802632008-07-25 19:13:19 +0200108 ACL_USE_TCP4_PERMANENT = 1 << 0, /* unchanged TCPv4 data (eg: source IP) */
109 ACL_USE_TCP4_CACHEABLE = 1 << 1, /* cacheable TCPv4 data (eg: src conns) */
110 ACL_USE_TCP4_VOLATILE = 1 << 2, /* volatile TCPv4 data (eg: RTT) */
111 ACL_USE_TCP4_ANY = (ACL_USE_TCP4_PERMANENT | ACL_USE_TCP4_CACHEABLE | ACL_USE_TCP4_VOLATILE),
112
113 ACL_USE_TCP6_PERMANENT = 1 << 3, /* unchanged TCPv6 data (eg: source IP) */
114 ACL_USE_TCP6_CACHEABLE = 1 << 4, /* cacheable TCPv6 data (eg: src conns) */
115 ACL_USE_TCP6_VOLATILE = 1 << 5, /* volatile TCPv6 data (eg: RTT) */
116 ACL_USE_TCP6_ANY = (ACL_USE_TCP6_PERMANENT | ACL_USE_TCP6_CACHEABLE | ACL_USE_TCP6_VOLATILE),
117
118 ACL_USE_TCP_PERMANENT = 1 << 6, /* unchanged TCPv4/v6 data (eg: source IP) */
119 ACL_USE_TCP_CACHEABLE = 1 << 7, /* cacheable TCPv4/v6 data (eg: src conns) */
120 ACL_USE_TCP_VOLATILE = 1 << 8, /* volatile TCPv4/v6 data (eg: RTT) */
121 ACL_USE_TCP_ANY = (ACL_USE_TCP_PERMANENT | ACL_USE_TCP_CACHEABLE | ACL_USE_TCP_VOLATILE),
122
123 ACL_USE_L4REQ_PERMANENT = 1 << 9, /* unchanged layer4 request data */
124 ACL_USE_L4REQ_CACHEABLE = 1 << 10, /* cacheable layer4 request data (eg: length) */
125 ACL_USE_L4REQ_VOLATILE = 1 << 11, /* volatile layer4 request data (eg: contents) */
126 ACL_USE_L4REQ_ANY = (ACL_USE_L4REQ_PERMANENT | ACL_USE_L4REQ_CACHEABLE | ACL_USE_L4REQ_VOLATILE),
127
128 ACL_USE_L4RTR_PERMANENT = 1 << 12, /* unchanged layer4 response data */
129 ACL_USE_L4RTR_CACHEABLE = 1 << 13, /* cacheable layer4 response data (eg: length) */
130 ACL_USE_L4RTR_VOLATILE = 1 << 14, /* volatile layer4 response data (eg: contents) */
131 ACL_USE_L4RTR_ANY = (ACL_USE_L4RTR_PERMANENT | ACL_USE_L4RTR_CACHEABLE | ACL_USE_L4RTR_VOLATILE),
132
133 ACL_USE_L7REQ_PERMANENT = 1 << 15, /* unchanged layer7 request data (eg: method) */
134 ACL_USE_L7REQ_CACHEABLE = 1 << 16, /* cacheable layer7 request data (eg: content-length) */
135 ACL_USE_L7REQ_VOLATILE = 1 << 17, /* volatile layer7 request data (eg: cookie) */
136 ACL_USE_L7REQ_ANY = (ACL_USE_L7REQ_PERMANENT | ACL_USE_L7REQ_CACHEABLE | ACL_USE_L7REQ_VOLATILE),
137
138 ACL_USE_L7RTR_PERMANENT = 1 << 18, /* unchanged layer7 response data (eg: status) */
139 ACL_USE_L7RTR_CACHEABLE = 1 << 19, /* cacheable layer7 response data (eg: content-length) */
140 ACL_USE_L7RTR_VOLATILE = 1 << 20, /* volatile layer7 response data (eg: cookie) */
141 ACL_USE_L7RTR_ANY = (ACL_USE_L7RTR_PERMANENT | ACL_USE_L7RTR_CACHEABLE | ACL_USE_L7RTR_VOLATILE),
142
143 /* those ones are used for ambiguous "hdr_xxx" verbs */
144 ACL_USE_HDR_CACHEABLE = 1 << 21, /* cacheable request or response header (eg: content-length) */
145 ACL_USE_HDR_VOLATILE = 1 << 22, /* volatile request or response header (eg: cookie) */
146 ACL_USE_HDR_ANY = (ACL_USE_HDR_CACHEABLE | ACL_USE_HDR_VOLATILE),
147
148 /* information which remains during response */
149 ACL_USE_REQ_PERMANENT = (ACL_USE_TCP4_PERMANENT | ACL_USE_TCP6_PERMANENT | ACL_USE_TCP_PERMANENT |
150 ACL_USE_L4REQ_PERMANENT | ACL_USE_L7REQ_PERMANENT),
151 ACL_USE_REQ_CACHEABLE = (ACL_USE_TCP4_CACHEABLE | ACL_USE_TCP6_CACHEABLE | ACL_USE_TCP_CACHEABLE |
152 ACL_USE_L4REQ_CACHEABLE | ACL_USE_L7REQ_CACHEABLE | ACL_USE_HDR_CACHEABLE),
153
154 /* information which does not remain during response */
155 ACL_USE_REQ_VOLATILE = (ACL_USE_TCP4_VOLATILE | ACL_USE_TCP6_VOLATILE | ACL_USE_TCP_VOLATILE |
156 ACL_USE_L4REQ_VOLATILE | ACL_USE_L7REQ_VOLATILE),
157
158 /* any type of layer 4 contents information */
159 ACL_USE_L4_ANY = (ACL_USE_L4REQ_ANY | ACL_USE_L4RTR_ANY),
160
161 /* any type of layer 7 information */
162 ACL_USE_L7_ANY = (ACL_USE_L7REQ_ANY | ACL_USE_L7RTR_ANY | ACL_USE_HDR_ANY),
163
164 /* any type of response information */
165 ACL_USE_RTR_ANY = (ACL_USE_L4RTR_ANY | ACL_USE_L7RTR_ANY),
166};
167
168/* filtering hooks */
169enum {
170 /* hooks on the request path */
171 ACL_HOOK_REQ_FE_TCP = 0,
172 ACL_HOOK_REQ_FE_TCP_CONTENT,
173 ACL_HOOK_REQ_FE_HTTP_IN,
174 ACL_HOOK_REQ_FE_SWITCH,
175 ACL_HOOK_REQ_BE_TCP_CONTENT,
176 ACL_HOOK_REQ_BE_HTTP_IN,
177 ACL_HOOK_REQ_BE_SWITCH,
178 ACL_HOOK_REQ_FE_HTTP_OUT,
179 ACL_HOOK_REQ_BE_HTTP_OUT,
180 /* hooks on the response path */
181 ACL_HOOK_RTR_BE_TCP_CONTENT,
182 ACL_HOOK_RTR_BE_HTTP_IN,
183 ACL_HOOK_RTR_FE_TCP_CONTENT,
184 ACL_HOOK_RTR_FE_HTTP_IN,
185 ACL_HOOK_RTR_BE_HTTP_OUT,
186 ACL_HOOK_RTR_FE_HTTP_OUT,
187};
188
Willy Tarreaua84d3742007-05-07 00:36:48 +0200189/* How to store a time range and the valid days in 29 bits */
190struct acl_time {
191 int dow:7; /* 1 bit per day of week: 0-6 */
192 int h1:5, m1:6; /* 0..24:0..60. Use 0:0 for all day. */
193 int h2:5, m2:6; /* 0..24:0..60. Use 24:0 for all day. */
194};
195
196/* The acl will be linked to from the proxy where it is declared */
197struct acl_pattern {
198 struct list list; /* chaining */
199 union {
200 int i; /* integer value */
Willy Tarreauae8b7962007-06-09 23:10:04 +0200201 struct {
202 signed long long min, max;
203 int min_set :1;
204 int max_set :1;
205 } range; /* integer range */
Willy Tarreaua67fad92007-05-08 19:50:09 +0200206 struct {
207 struct in_addr addr;
208 struct in_addr mask;
209 } ipv4; /* IPv4 address */
Willy Tarreaua84d3742007-05-07 00:36:48 +0200210 struct acl_time time; /* valid hours and days */
211 } val; /* direct value */
212 union {
213 void *ptr; /* any data */
214 char *str; /* any string */
215 regex_t *reg; /* a compiled regex */
216 } ptr; /* indirect values, allocated */
Krzysztof Piotr Oledzki8001d612008-05-31 13:53:23 +0200217 void(*freeptrbuf)(void *ptr); /* a destructor able to free objects from the ptr */
Willy Tarreaua84d3742007-05-07 00:36:48 +0200218 int len; /* data length when required */
Willy Tarreauc8d7c962007-06-17 08:20:33 +0200219 int flags; /* expr or pattern flags. */
Willy Tarreaua84d3742007-05-07 00:36:48 +0200220};
221
222/* The structure exchanged between an acl_fetch_* function responsible for
223 * retrieving a value, and an acl_match_* function responsible for testing it.
224 */
225struct acl_test {
Willy Tarreau33a7e692007-06-10 19:45:56 +0200226 int i; /* integer value */
227 char *ptr; /* pointer to beginning of value */
228 int len; /* length of value at ptr, otherwise ignored */
229 int flags; /* ACL_TEST_F_* set to 0 on first call */
230 union { /* fetch_* functions context for any purpose */
231 void *p; /* any pointer */
232 int i; /* any integer */
233 long long ll; /* any long long or smaller */
234 double d; /* any float or double */
235 void *a[8]; /* any array of up to 8 pointers */
Willy Tarreaua84d3742007-05-07 00:36:48 +0200236 } ctx;
237};
238
239
240/*
241 * ACL keyword: Associates keywords with parsers, methods to retrieve the value and testers.
242 */
243
244/* some dummy declarations to silent the compiler */
245struct proxy;
246struct session;
247
Willy Tarreauae8b7962007-06-09 23:10:04 +0200248/*
249 * NOTE:
250 * The 'parse' function is called to parse words in the configuration. It must
251 * return the number of valid words read. 0 = error. The 'opaque' argument may
252 * be used by functions which need to maintain a context between consecutive
253 * values. It is initialized to zero before the first call, and passed along
254 * successive calls.
255 */
256
Willy Tarreau97be1452007-06-10 11:47:14 +0200257struct acl_expr;
Willy Tarreaua84d3742007-05-07 00:36:48 +0200258struct acl_keyword {
259 const char *kw;
Willy Tarreauae8b7962007-06-09 23:10:04 +0200260 int (*parse)(const char **text, struct acl_pattern *pattern, int *opaque);
Willy Tarreau97be1452007-06-10 11:47:14 +0200261 int (*fetch)(struct proxy *px, struct session *l4, void *l7, int dir,
262 struct acl_expr *expr, struct acl_test *test);
Willy Tarreaua84d3742007-05-07 00:36:48 +0200263 int (*match)(struct acl_test *test, struct acl_pattern *pattern);
Willy Tarreaua9802632008-07-25 19:13:19 +0200264 unsigned int requires; /* bit mask of all ACL_USE_* required to evaluate this keyword */
Willy Tarreaua84d3742007-05-07 00:36:48 +0200265 int use_cnt;
266};
267
268/*
269 * A keyword list. It is a NULL-terminated array of keywords. It embeds a
270 * struct list in order to be linked to other lists, allowing it to easily
271 * be declared where it is needed, and linked without duplicating data nor
272 * allocating memory.
273 */
274struct acl_kw_list {
275 struct list list;
276 struct acl_keyword kw[VAR_ARRAY];
277};
278
279/*
280 * Description of an ACL expression.
281 * It contains a subject and a set of patterns to test against it.
282 * - the function get() is called to retrieve the subject from the
283 * current session or transaction and build a test.
284 * - the function test() is called to evaluate the test based on the
285 * available patterns and return ACL_PAT_*
286 * Both of those functions are available through the keyword.
287 */
288struct acl_expr {
289 struct list list; /* chaining */
290 struct acl_keyword *kw; /* back-reference to the keyword */
291 union { /* optional argument of the subject (eg: header or cookie name) */
292 char *str;
293 } arg;
Willy Tarreaubb768912007-06-10 11:17:01 +0200294 int arg_len; /* optional argument length */
Willy Tarreaua84d3742007-05-07 00:36:48 +0200295 struct list patterns; /* list of acl_patterns */
296};
297
298struct acl {
299 struct list list; /* chaining */
300 char *name; /* acl name */
301 struct list expr; /* list of acl_exprs */
302 int cache_idx; /* ACL index in cache */
Willy Tarreaua9802632008-07-25 19:13:19 +0200303 unsigned int requires; /* or'ed bit mask of all acl_expr's ACL_USE_* */
Willy Tarreaua84d3742007-05-07 00:36:48 +0200304};
305
306/* the condition will be linked to from an action in a proxy */
307struct acl_term {
308 struct list list; /* chaining */
309 struct acl *acl; /* acl pointed to by this term */
310 int neg; /* 1 if the ACL result must be negated */
311};
312
313struct acl_term_suite {
314 struct list list; /* chaining of term suites */
315 struct list terms; /* list of acl_terms */
316};
317
318struct acl_cond {
319 struct list list; /* Some specific tests may use multiple conditions */
320 struct list suites; /* list of acl_term_suites */
321 int pol; /* polarity: ACL_COND_IF / ACL_COND_UNLESS */
Willy Tarreaua9802632008-07-25 19:13:19 +0200322 unsigned int requires; /* or'ed bit mask of all acl's ACL_USE_* */
323 int line; /* line in the config file where the condition is declared */
Willy Tarreaua84d3742007-05-07 00:36:48 +0200324};
325
326
327#endif /* _TYPES_ACL_H */
328
329/*
330 * Local variables:
331 * c-indent-level: 8
332 * c-basic-offset: 8
333 * End:
334 */