1 /*-
2  * SSLproxy
3  *
4  * Copyright (c) 2017-2021, Soner Tari <sonertari@gmail.com>.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are met:
9  * 1. Redistributions of source code must retain the above copyright notice,
10  *    this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright notice,
12  *    this list of conditions and the following disclaimer in the documentation
13  *    and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS''
16  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
19  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25  * POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 #ifndef FILTER_H
29 #define FILTER_H
30 
31 #include "opts.h"
32 #include "kbtree.h"
33 #include "aho_corasick_template_impl.h"
34 
35 #define FILTER_ACTION_NONE   0x00000000U
36 #define FILTER_ACTION_MATCH  0x00000200U
37 #define FILTER_ACTION_DIVERT 0x00000400U
38 #define FILTER_ACTION_SPLIT  0x00000800U
39 #define FILTER_ACTION_PASS   0x00001000U
40 #define FILTER_ACTION_BLOCK  0x00002000U
41 
42 #define FILTER_LOG_CONNECT   0x00004000U
43 #define FILTER_LOG_MASTER    0x00008000U
44 #define FILTER_LOG_CERT      0x00010000U
45 #define FILTER_LOG_CONTENT   0x00020000U
46 #define FILTER_LOG_PCAP      0x00040000U
47 #define FILTER_LOG_MIRROR    0x00080000U
48 
49 #define FILTER_LOG_NOCONNECT 0x00100000U
50 #define FILTER_LOG_NOMASTER  0x00200000U
51 #define FILTER_LOG_NOCERT    0x00400000U
52 #define FILTER_LOG_NOCONTENT 0x00800000U
53 #define FILTER_LOG_NOPCAP    0x01000000U
54 #define FILTER_LOG_NOMIRROR  0x02000000U
55 
56 #define FILTER_PRECEDENCE    0x000000FFU
57 
58 ACM_DECLARE (char);
59 
60 typedef struct filter_parse_state {
61 	unsigned int action : 1;
62 	unsigned int user : 1;
63 	unsigned int desc : 1;
64 	unsigned int srcip : 1;
65 	unsigned int sni : 1;
66 	unsigned int cn : 1;
67 	unsigned int host : 1;
68 	unsigned int uri : 1;
69 	unsigned int dstip : 1;
70 	unsigned int dstport : 1;
71 	unsigned int conn_opts : 1;
72 	unsigned int reconnect_ssl : 1;
73 } filter_parse_state_t;
74 
75 typedef struct name_value_lines {
76 	char *name;
77 	char *value;
78 	unsigned int line_num;
79 } name_value_lines_t;
80 
81 typedef struct value {
82 	char *value;
83 	struct value *next;
84 } value_t;
85 
86 typedef struct macro {
87 	char *name;
88 	struct value *value;
89 	struct macro *next;
90 } macro_t;
91 
92 typedef struct filter_action {
93 	// Filter action
94 	unsigned int divert : 1;
95 	unsigned int split : 1;
96 	unsigned int pass : 1;
97 	unsigned int block : 1;
98 	unsigned int match : 1;
99 
100 	// Log action, two bits
101 	// 0: don't change, 1: disable, 2: enable
102 	unsigned int log_connect : 2;
103 	unsigned int log_master : 2;
104 	unsigned int log_cert : 2;
105 	unsigned int log_content : 2;
106 	unsigned int log_pcap : 2;
107 #ifndef WITHOUT_MIRROR
108 	unsigned int log_mirror : 2;
109 #endif /* !WITHOUT_MIRROR */
110 
111 	// Only used with struct filter rules
112 	conn_opts_t *conn_opts;
113 
114 	// Precedence is used in rule application
115 	// More specific rules have higher precedence
116 	unsigned int precedence;
117 
118 #ifdef DEBUG_PROXY
119 	unsigned int line_num;
120 #endif /* DEBUG_PROXY */
121 } filter_action_t;
122 
123 typedef struct filter_rule {
124 	// from: source filter
125 	unsigned int all_conns : 1;   /* 1 to apply to all src ips and users */
126 
127 #ifndef WITHOUT_USERAUTH
128 	unsigned int all_users : 1;   /* 1 to apply to all users */
129 
130 	char *user;
131 	unsigned int exact_user : 1;  /* 1 for exact, 0 for substring match */
132 
133 	char *desc;
134 	unsigned int exact_desc : 1;  /* 1 for exact, 0 for substring match */
135 #endif /* !WITHOUT_USERAUTH */
136 
137 	char *ip;
138 	unsigned int exact_ip : 1;    /* 1 for exact, 0 for substring match */
139 
140 	// to: target filter
141 	char *dstip;
142 	char *sni;
143 	char *cn;
144 	char *host;
145 	char *uri;
146 
147 	unsigned int exact_dstip : 1; /* 1 for exact, 0 for substring match */
148 	unsigned int exact_sni : 1;   /* 1 for exact, 0 for substring match */
149 	unsigned int exact_cn : 1;    /* 1 for exact, 0 for substring match */
150 	unsigned int exact_host : 1;  /* 1 for exact, 0 for substring match */
151 	unsigned int exact_uri : 1;   /* 1 for exact, 0 for substring match */
152 
153 	unsigned int all_dstips : 1;  /* 1 to match all sites == '*' */
154 	unsigned int all_snis : 1;    /* 1 to match all sites == '*' */
155 	unsigned int all_cns : 1;     /* 1 to match all sites == '*' */
156 	unsigned int all_hosts : 1;   /* 1 to match all sites == '*' */
157 	unsigned int all_uris : 1;    /* 1 to match all sites == '*' */
158 
159 	// This is not for the src ip in the 'from' part of rules
160 	char *port;
161 	unsigned int all_ports : 1;   /* 1 to match all ports == '*' */
162 	unsigned int exact_port : 1;  /* 1 for exact, 0 for substring match */
163 
164 	struct filter_action action;
165 
166 	struct filter_rule *next;
167 } filter_rule_t;
168 
169 typedef struct filter_port {
170 	char *port;
171 	unsigned int all_ports : 1;
172 	unsigned int exact : 1;       /* used in debug logging only */
173 
174 	struct filter_action action;
175 } filter_port_t;
176 
177 typedef const char *str_t;
178 
179 #define getk_port(a) (a)->port
180 typedef filter_port_t *filter_port_p_t;
181 KBTREE_INIT(port, filter_port_p_t, kb_str_cmp, str_t, getk_port)
182 
183 typedef struct filter_port_list {
184 	struct filter_port *port;
185 	struct filter_port_list *next;
186 } filter_port_list_t;
187 
188 typedef struct filter_site {
189 	char *site;
190 	unsigned int all_sites : 1;
191 	unsigned int exact : 1;       /* used in debug logging only */
192 
193 	kbtree_t(port) *port_btree;
194 	ACMachine(char) *port_acm;
195 	struct filter_port *port_all;
196 
197 	struct filter_action action;
198 } filter_site_t;
199 
200 #define getk_site(a) (a)->site
201 typedef filter_site_t *filter_site_p_t;
202 KBTREE_INIT(site, filter_site_p_t, kb_str_cmp, str_t, getk_site)
203 
204 typedef struct filter_site_list {
205 	struct filter_site *site;
206 	struct filter_site_list *next;
207 } filter_site_list_t;
208 
209 typedef struct filter_list {
210 	kbtree_t(site) *ip_btree;
211 	ACMachine(char) *ip_acm;
212 	struct filter_site *ip_all;
213 
214 	kbtree_t(site) *sni_btree;
215 	ACMachine(char) *sni_acm;
216 	struct filter_site *sni_all;
217 
218 	kbtree_t(site) *cn_btree;
219 	ACMachine(char) *cn_acm;
220 	struct filter_site *cn_all;
221 
222 	kbtree_t(site) *host_btree;
223 	ACMachine(char) *host_acm;
224 	struct filter_site *host_all;
225 
226 	kbtree_t(site) *uri_btree;
227 	ACMachine(char) *uri_acm;
228 	struct filter_site *uri_all;
229 } filter_list_t;
230 
231 typedef struct filter_ip {
232 	char *ip;
233 	unsigned int exact : 1;       /* used in debug logging only */
234 	struct filter_list *list;
235 } filter_ip_t;
236 
237 typedef struct filter_ip_list {
238 	struct filter_ip *ip;
239 	struct filter_ip_list *next;
240 } filter_ip_list_t;
241 
242 #ifndef WITHOUT_USERAUTH
243 typedef struct filter_desc {
244 	char *desc;
245 	unsigned int exact : 1;       /* used in debug logging only */
246 	struct filter_list *list;
247 } filter_desc_t;
248 
249 #define getk_desc(a) (a)->desc
250 typedef filter_desc_t *filter_desc_p_t;
251 KBTREE_INIT(desc, filter_desc_p_t, kb_str_cmp, str_t, getk_desc)
252 
253 typedef struct filter_desc_list {
254 	struct filter_desc *desc;
255 	struct filter_desc_list *next;
256 } filter_desc_list_t;
257 
258 typedef struct filter_user {
259 	char *user;
260 	unsigned int exact : 1;       /* used in debug logging only */
261 	struct filter_list *list;
262 	kbtree_t(desc) *desc_btree;
263 	ACMachine(char) *desc_acm;
264 } filter_user_t;
265 
266 #define getk_user(a) (a)->user
267 typedef filter_user_t *filter_user_p_t;
268 KBTREE_INIT(user, filter_user_p_t, kb_str_cmp, str_t, getk_user)
269 
270 typedef struct filter_user_list {
271 	struct filter_user *user;
272 	struct filter_user_list *next;
273 } filter_user_list_t;
274 #endif /* !WITHOUT_USERAUTH */
275 
276 #define getk_ip(a) (a)->ip
277 typedef filter_ip_t *filter_ip_p_t;
278 KBTREE_INIT(ip, filter_ip_p_t, kb_str_cmp, str_t, getk_ip)
279 
280 typedef struct filter {
281 #ifndef WITHOUT_USERAUTH
282 	kbtree_t(user) *user_btree;   /* exact */
283 	ACMachine(char) *user_acm;    /* substring */
284 
285 	kbtree_t(desc) *desc_btree;   /* exact */
286 	ACMachine(char) *desc_acm;    /* substring */
287 
288 	struct filter_list *all_user;
289 #endif /* !WITHOUT_USERAUTH */
290 
291 	kbtree_t(ip) *ip_btree;       /* exact */
292 	ACMachine(char) *ip_acm;      /* substring */
293 
294 	struct filter_list *all;
295 } filter_t;
296 
297 #ifndef WITHOUT_USERAUTH
298 void filter_userlist_free(userlist_t *);
299 int filter_userlist_copy(userlist_t *, const char *, userlist_t **) NONNULL(2) WUNRES;
300 char *filter_userlist_str(userlist_t *);
301 int filter_userlist_set(char *, unsigned int, userlist_t **, const char *) NONNULL(1,4) WUNRES;
302 #endif /* !WITHOUT_USERAUTH */
303 
304 void filter_macro_free(opts_t *) NONNULL(1);
305 void filter_rules_free(opts_t *) NONNULL(1);
306 void filter_free(opts_t *) NONNULL(1);
307 
308 int filter_macro_copy(macro_t *, const char *, opts_t *) NONNULL(2,3) WUNRES;
309 int filter_rule_copy(filter_rule_t *, const char *, opts_t *, tmp_opts_t *) NONNULL(2,3) WUNRES;
310 
311 char *filter_macro_str(macro_t *);
312 char *filter_rule_str(filter_rule_t *);
313 char *filter_str(filter_t *);
314 
315 int filter_passsite_set(opts_t *, conn_opts_t *, char *, unsigned int) NONNULL(1,3) WUNRES;
316 int filter_macro_set(opts_t *, char *, unsigned int) NONNULL(1,2) WUNRES;
317 
318 int load_filterrule_struct(opts_t *, conn_opts_t *, const char *, unsigned int *, FILE *, tmp_opts_t *) WUNRES;
319 
320 filter_port_t *filter_port_find(filter_site_t *, char *) NONNULL(1,2);
321 
322 filter_site_t *filter_site_exact_match(kbtree_t(site) *, char *) NONNULL(2) WUNRES;
323 filter_site_t *filter_site_substring_match(ACMachine(char) *, char *) NONNULL(2) WUNRES;
324 filter_site_t *filter_site_find(kbtree_t(site) *, ACMachine(char) *, filter_site_t *, char *) NONNULL(4) WUNRES;
325 
326 filter_ip_t *filter_ip_exact_match(kbtree_t(ip) *, char *) NONNULL(2);
327 filter_ip_t *filter_ip_substring_match(ACMachine(char) *, char *) NONNULL(2);
328 
329 #ifndef WITHOUT_USERAUTH
330 filter_desc_t *filter_desc_exact_match(kbtree_t(desc) *, char *) NONNULL(2) WUNRES;
331 filter_desc_t *filter_desc_substring_match(ACMachine(char) *, char *) NONNULL(2) WUNRES;
332 
333 filter_user_t *filter_user_exact_match(kbtree_t(user) *, char *) NONNULL(2) WUNRES;
334 filter_user_t *filter_user_substring_match(ACMachine(char) *, char *) NONNULL(2) WUNRES;
335 #endif /* !WITHOUT_USERAUTH */
336 int filter_rule_set(opts_t *, conn_opts_t *conn_opts, const char *, char *, unsigned int) NONNULL(1,3,4) WUNRES;
337 filter_t *filter_set(filter_rule_t *, const char *, tmp_opts_t *) WUNRES;
338 
339 #endif /* !FILTER_H */
340 
341 /* vim: set noet ft=c: */
342