You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
SSLproxy/src/filter.h

342 lines
10 KiB
C

/*-
* SSLproxy
*
* Copyright (c) 2017-2024, Soner Tari <sonertari@gmail.com>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef FILTER_H
#define FILTER_H
#include "opts.h"
#include "kbtree.h"
#include "aho_corasick_template_impl.h"
#define FILTER_ACTION_NONE 0x00000000U
#define FILTER_ACTION_MATCH 0x00000200U
#define FILTER_ACTION_DIVERT 0x00000400U
#define FILTER_ACTION_SPLIT 0x00000800U
#define FILTER_ACTION_PASS 0x00001000U
#define FILTER_ACTION_BLOCK 0x00002000U
#define FILTER_LOG_CONNECT 0x00004000U
#define FILTER_LOG_MASTER 0x00008000U
#define FILTER_LOG_CERT 0x00010000U
#define FILTER_LOG_CONTENT 0x00020000U
#define FILTER_LOG_PCAP 0x00040000U
#define FILTER_LOG_MIRROR 0x00080000U
#define FILTER_LOG_NOCONNECT 0x00100000U
#define FILTER_LOG_NOMASTER 0x00200000U
#define FILTER_LOG_NOCERT 0x00400000U
#define FILTER_LOG_NOCONTENT 0x00800000U
#define FILTER_LOG_NOPCAP 0x01000000U
#define FILTER_LOG_NOMIRROR 0x02000000U
#define FILTER_PRECEDENCE 0x000000FFU
ACM_DECLARE (char);
typedef struct filter_parse_state {
unsigned int action : 1;
unsigned int user : 1;
unsigned int desc : 1;
unsigned int srcip : 1;
unsigned int sni : 1;
unsigned int cn : 1;
unsigned int host : 1;
unsigned int uri : 1;
unsigned int dstip : 1;
unsigned int dstport : 1;
unsigned int conn_opts : 1;
unsigned int reconnect_ssl : 1;
} filter_parse_state_t;
typedef struct name_value_lines {
char *name;
char *value;
unsigned int line_num;
} name_value_lines_t;
typedef struct value {
char *value;
struct value *next;
} value_t;
typedef struct macro {
char *name;
struct value *value;
struct macro *next;
} macro_t;
typedef struct filter_action {
// Filter action
unsigned int divert : 1;
unsigned int split : 1;
unsigned int pass : 1;
unsigned int block : 1;
unsigned int match : 1;
// Log action, two bits
// 0: don't change, 1: disable, 2: enable
unsigned int log_connect : 2;
unsigned int log_master : 2;
unsigned int log_cert : 2;
unsigned int log_content : 2;
unsigned int log_pcap : 2;
#ifndef WITHOUT_MIRROR
unsigned int log_mirror : 2;
#endif /* !WITHOUT_MIRROR */
// Only used with struct filter rules
conn_opts_t *conn_opts;
// Precedence is used in rule application
// More specific rules have higher precedence
unsigned int precedence;
#ifdef DEBUG_PROXY
unsigned int line_num;
#endif /* DEBUG_PROXY */
} filter_action_t;
typedef struct filter_rule {
// from: source filter
unsigned int all_conns : 1; /* 1 to apply to all src ips and users */
#ifndef WITHOUT_USERAUTH
unsigned int all_users : 1; /* 1 to apply to all users */
char *user;
unsigned int exact_user : 1; /* 1 for exact, 0 for substring match */
char *desc;
unsigned int exact_desc : 1; /* 1 for exact, 0 for substring match */
#endif /* !WITHOUT_USERAUTH */
char *ip;
unsigned int exact_ip : 1; /* 1 for exact, 0 for substring match */
// to: target filter
char *dstip;
char *sni;
char *cn;
char *host;
char *uri;
unsigned int exact_dstip : 1; /* 1 for exact, 0 for substring match */
unsigned int exact_sni : 1; /* 1 for exact, 0 for substring match */
unsigned int exact_cn : 1; /* 1 for exact, 0 for substring match */
unsigned int exact_host : 1; /* 1 for exact, 0 for substring match */
unsigned int exact_uri : 1; /* 1 for exact, 0 for substring match */
unsigned int all_dstips : 1; /* 1 to match all sites == '*' */
unsigned int all_snis : 1; /* 1 to match all sites == '*' */
unsigned int all_cns : 1; /* 1 to match all sites == '*' */
unsigned int all_hosts : 1; /* 1 to match all sites == '*' */
unsigned int all_uris : 1; /* 1 to match all sites == '*' */
// This is not for the src ip in the 'from' part of rules
char *port;
unsigned int all_ports : 1; /* 1 to match all ports == '*' */
unsigned int exact_port : 1; /* 1 for exact, 0 for substring match */
struct filter_action action;
struct filter_rule *next;
} filter_rule_t;
typedef struct filter_port {
char *port;
unsigned int all_ports : 1;
unsigned int exact : 1; /* used in debug logging only */
struct filter_action action;
} filter_port_t;
typedef const char *str_t;
#define getk_port(a) (a)->port
typedef filter_port_t *filter_port_p_t;
KBTREE_INIT(port, filter_port_p_t, kb_str_cmp, str_t, getk_port)
typedef struct filter_port_list {
struct filter_port *port;
struct filter_port_list *next;
} filter_port_list_t;
typedef struct filter_site {
char *site;
unsigned int all_sites : 1;
unsigned int exact : 1; /* used in debug logging only */
kbtree_t(port) *port_btree;
ACMachine(char) *port_acm;
struct filter_port *port_all;
struct filter_action action;
} filter_site_t;
#define getk_site(a) (a)->site
typedef filter_site_t *filter_site_p_t;
KBTREE_INIT(site, filter_site_p_t, kb_str_cmp, str_t, getk_site)
typedef struct filter_site_list {
struct filter_site *site;
struct filter_site_list *next;
} filter_site_list_t;
typedef struct filter_list {
kbtree_t(site) *ip_btree;
ACMachine(char) *ip_acm;
struct filter_site *ip_all;
kbtree_t(site) *sni_btree;
ACMachine(char) *sni_acm;
struct filter_site *sni_all;
kbtree_t(site) *cn_btree;
ACMachine(char) *cn_acm;
struct filter_site *cn_all;
kbtree_t(site) *host_btree;
ACMachine(char) *host_acm;
struct filter_site *host_all;
kbtree_t(site) *uri_btree;
ACMachine(char) *uri_acm;
struct filter_site *uri_all;
} filter_list_t;
typedef struct filter_ip {
char *ip;
unsigned int exact : 1; /* used in debug logging only */
struct filter_list *list;
} filter_ip_t;
typedef struct filter_ip_list {
struct filter_ip *ip;
struct filter_ip_list *next;
} filter_ip_list_t;
#ifndef WITHOUT_USERAUTH
typedef struct filter_desc {
char *desc;
unsigned int exact : 1; /* used in debug logging only */
struct filter_list *list;
} filter_desc_t;
#define getk_desc(a) (a)->desc
typedef filter_desc_t *filter_desc_p_t;
KBTREE_INIT(desc, filter_desc_p_t, kb_str_cmp, str_t, getk_desc)
typedef struct filter_desc_list {
struct filter_desc *desc;
struct filter_desc_list *next;
} filter_desc_list_t;
typedef struct filter_user {
char *user;
unsigned int exact : 1; /* used in debug logging only */
struct filter_list *list;
kbtree_t(desc) *desc_btree;
ACMachine(char) *desc_acm;
} filter_user_t;
#define getk_user(a) (a)->user
typedef filter_user_t *filter_user_p_t;
KBTREE_INIT(user, filter_user_p_t, kb_str_cmp, str_t, getk_user)
typedef struct filter_user_list {
struct filter_user *user;
struct filter_user_list *next;
} filter_user_list_t;
#endif /* !WITHOUT_USERAUTH */
#define getk_ip(a) (a)->ip
typedef filter_ip_t *filter_ip_p_t;
KBTREE_INIT(ip, filter_ip_p_t, kb_str_cmp, str_t, getk_ip)
typedef struct filter {
#ifndef WITHOUT_USERAUTH
kbtree_t(user) *user_btree; /* exact */
ACMachine(char) *user_acm; /* substring */
kbtree_t(desc) *desc_btree; /* exact */
ACMachine(char) *desc_acm; /* substring */
struct filter_list *all_user;
#endif /* !WITHOUT_USERAUTH */
kbtree_t(ip) *ip_btree; /* exact */
ACMachine(char) *ip_acm; /* substring */
struct filter_list *all;
} filter_t;
#ifndef WITHOUT_USERAUTH
void filter_userlist_free(userlist_t *);
int filter_userlist_copy(userlist_t *, const char *, userlist_t **) NONNULL(2) WUNRES;
char *filter_userlist_str(userlist_t *);
int filter_userlist_set(char *, unsigned int, userlist_t **, const char *) NONNULL(1,4) WUNRES;
#endif /* !WITHOUT_USERAUTH */
void filter_macro_free(opts_t *) NONNULL(1);
void filter_rules_free(opts_t *) NONNULL(1);
void filter_free(opts_t *) NONNULL(1);
int filter_macro_copy(macro_t *, const char *, opts_t *) NONNULL(2,3) WUNRES;
int filter_rule_copy(filter_rule_t *, const char *, opts_t *, tmp_opts_t *) NONNULL(2,3) WUNRES;
char *filter_macro_str(macro_t *);
char *filter_rule_str(filter_rule_t *);
char *filter_str(filter_t *);
int filter_passsite_set(opts_t *, conn_opts_t *, char *, unsigned int) NONNULL(1,3) WUNRES;
int filter_macro_set(opts_t *, char *, unsigned int) NONNULL(1,2) WUNRES;
int load_filterrule_struct(opts_t *, conn_opts_t *, const char *, unsigned int *, FILE *, tmp_opts_t *) WUNRES;
filter_port_t *filter_port_find(filter_site_t *, char *) NONNULL(1,2);
filter_site_t *filter_site_exact_match(kbtree_t(site) *, char *) NONNULL(2) WUNRES;
filter_site_t *filter_site_substring_match(ACMachine(char) *, char *) NONNULL(2) WUNRES;
filter_site_t *filter_site_find(kbtree_t(site) *, ACMachine(char) *, filter_site_t *, char *) NONNULL(4) WUNRES;
filter_ip_t *filter_ip_exact_match(kbtree_t(ip) *, char *) NONNULL(2);
filter_ip_t *filter_ip_substring_match(ACMachine(char) *, char *) NONNULL(2);
#ifndef WITHOUT_USERAUTH
filter_desc_t *filter_desc_exact_match(kbtree_t(desc) *, char *) NONNULL(2) WUNRES;
filter_desc_t *filter_desc_substring_match(ACMachine(char) *, char *) NONNULL(2) WUNRES;
filter_user_t *filter_user_exact_match(kbtree_t(user) *, char *) NONNULL(2) WUNRES;
filter_user_t *filter_user_substring_match(ACMachine(char) *, char *) NONNULL(2) WUNRES;
#endif /* !WITHOUT_USERAUTH */
int filter_rule_set(opts_t *, conn_opts_t *conn_opts, const char *, char *, unsigned int) NONNULL(1,3,4) WUNRES;
filter_t *filter_set(filter_rule_t *, const char *, tmp_opts_t *) WUNRES;
#endif /* !FILTER_H */
/* vim: set noet ft=c: */