From 14c8d417c9c9135bcbd61ffb1569e6c486186c27 Mon Sep 17 00:00:00 2001 From: Soner Tari Date: Tue, 26 Oct 2021 19:08:00 +0300 Subject: [PATCH] Move connection oriented options to a new conn_opts struct --- src/filter.c | 34 +- src/filter.h | 4 +- src/main.c | 90 ++--- src/opts.c | 683 ++++++++++++++++--------------- src/opts.h | 55 +-- src/protohttp.c | 18 +- src/protosmtp.c | 2 +- src/protossl.c | 88 ++-- src/prototcp.c | 10 +- src/proxy.c | 1 + src/pxyconn.c | 10 +- src/pxyconn.h | 1 + src/pxythrmgr.c | 2 +- tests/check/filter.t.c | 882 ++++++++++++++++++++--------------------- tests/check/opts.t.c | 23 +- 15 files changed, 972 insertions(+), 931 deletions(-) diff --git a/src/filter.c b/src/filter.c index 59efcd3..2e0cbe1 100644 --- a/src/filter.c +++ b/src/filter.c @@ -1397,7 +1397,7 @@ filter_rule_dbg_print(filter_rule_t *rule) #define MAX_SITE_LEN 200 int -filter_passsite_set(opts_t *opts, char *value, int line_num) +filter_passsite_set(opts_t *opts, unsigned int user_auth, char *value, int line_num) { #define MAX_PASSSITE_TOKENS 3 @@ -1467,7 +1467,7 @@ filter_passsite_set(opts_t *opts, char *value, int line_num) rule->action.precedence++; rule->all_users = 1; } else if (sys_isuser(argv[1])) { - if (!opts->user_auth) { + if (!user_auth) { fprintf(stderr, "User filter requires user auth on line %d\n", line_num); return -1; } @@ -1501,7 +1501,7 @@ filter_passsite_set(opts_t *opts, char *value, int line_num) return -1; } #ifndef WITHOUT_USERAUTH - if (!opts->user_auth) { + if (!user_auth) { fprintf(stderr, "Keyword filter requires user auth on line %d\n", line_num); return -1; } @@ -1975,12 +1975,12 @@ filter_rule_translate(opts_t *opts, const char *name, int argc, char **argv, int } static int WUNRES -filter_rule_parse(opts_t *opts, const char *name, int argc, char **argv, int line_num); +filter_rule_parse(opts_t *opts, unsigned int user_auth, const char *name, int argc, char **argv, int line_num); #define MAX_FILTER_RULE_TOKENS 17 static int WUNRES -filter_rule_macro_expand(opts_t *opts, const char *name, int argc, char **argv, int i, int line_num) +filter_rule_macro_expand(opts_t *opts, unsigned int user_auth, const char *name, int argc, char **argv, int i, int line_num) { if (argv[i][0] == '$') { macro_t *macro; @@ -1998,7 +1998,7 @@ filter_rule_macro_expand(opts_t *opts, const char *name, int argc, char **argv, expanded_argv[i] = value->value; - if (filter_rule_parse(opts, name, argc, expanded_argv, line_num) == -1) + if (filter_rule_parse(opts, user_auth, name, argc, expanded_argv, line_num) == -1) return -1; value = value->next; @@ -2015,7 +2015,7 @@ filter_rule_macro_expand(opts_t *opts, const char *name, int argc, char **argv, } static int WUNRES -filter_rule_parse(opts_t *opts, const char *name, int argc, char **argv, int line_num) +filter_rule_parse(opts_t *opts, unsigned int user_auth, const char *name, int argc, char **argv, int line_num) { int done_all = 0; int done_from = 0; @@ -2046,7 +2046,7 @@ filter_rule_parse(opts_t *opts, const char *name, int argc, char **argv, int lin #ifndef WITHOUT_USERAUTH if (equal(argv[i], "user") || equal(argv[i], "desc")) { if (equal(argv[i], "user")) { - if (!opts->user_auth) { + if (!user_auth) { fprintf(stderr, "User filter requires user auth on line %d\n", line_num); return -1; } @@ -2057,7 +2057,7 @@ filter_rule_parse(opts_t *opts, const char *name, int argc, char **argv, int lin if (argv[i][strlen(argv[i]) - 1] == '*') { // Nothing to do for '*' or substring search for 'user*' } - else if ((rv = filter_rule_macro_expand(opts, name, argc, argv, i, line_num)) != 0) { + else if ((rv = filter_rule_macro_expand(opts, user_auth, name, argc, argv, i, line_num)) != 0) { return rv; } else if (!sys_isuser(argv[i])) { @@ -2069,7 +2069,7 @@ filter_rule_parse(opts_t *opts, const char *name, int argc, char **argv, int lin // It is possible to define desc without user (i.e. * or all_users), hence no 'else' here if (i < argc && equal(argv[i], "desc")) { - if (!opts->user_auth) { + if (!user_auth) { fprintf(stderr, "Desc filter requires user auth on line %d\n", line_num); return -1; } @@ -2080,7 +2080,7 @@ filter_rule_parse(opts_t *opts, const char *name, int argc, char **argv, int lin if (argv[i][strlen(argv[i]) - 1] == '*') { // Nothing to do for '*' or substring search for 'desc*' } - else if ((rv = filter_rule_macro_expand(opts, name, argc, argv, i, line_num)) != 0) { + else if ((rv = filter_rule_macro_expand(opts, user_auth, name, argc, argv, i, line_num)) != 0) { return rv; } i++; @@ -2097,7 +2097,7 @@ filter_rule_parse(opts_t *opts, const char *name, int argc, char **argv, int lin if (argv[i][strlen(argv[i]) - 1] == '*') { // Nothing to do for '*' or substring search for 'ip*' } - else if ((rv = filter_rule_macro_expand(opts, name, argc, argv, i, line_num)) != 0) { + else if ((rv = filter_rule_macro_expand(opts, user_auth, name, argc, argv, i, line_num)) != 0) { return rv; } i++; @@ -2126,7 +2126,7 @@ filter_rule_parse(opts_t *opts, const char *name, int argc, char **argv, int lin if ((i = filter_arg_index_inc(i, argc, argv[i], line_num)) == -1) return -1; - if ((rv = filter_rule_macro_expand(opts, name, argc, argv, i, line_num)) != 0) { + if ((rv = filter_rule_macro_expand(opts, user_auth, name, argc, argv, i, line_num)) != 0) { return rv; } i++; @@ -2137,7 +2137,7 @@ filter_rule_parse(opts_t *opts, const char *name, int argc, char **argv, int lin if ((i = filter_arg_index_inc(i, argc, argv[i], line_num)) == -1) return -1; - if ((rv = filter_rule_macro_expand(opts, name, argc, argv, i, line_num)) != 0) { + if ((rv = filter_rule_macro_expand(opts, user_auth, name, argc, argv, i, line_num)) != 0) { return rv; } i++; @@ -2168,7 +2168,7 @@ filter_rule_parse(opts_t *opts, const char *name, int argc, char **argv, int lin #endif /* !WITHOUT_MIRROR */ || argv[i][0] == '$') { do { - if ((rv = filter_rule_macro_expand(opts, name, argc, argv, i, line_num)) != 0) { + if ((rv = filter_rule_macro_expand(opts, user_auth, name, argc, argv, i, line_num)) != 0) { return rv; } if (++i == argc) @@ -2206,7 +2206,7 @@ filter_rule_parse(opts_t *opts, const char *name, int argc, char **argv, int lin } int -filter_rule_set(opts_t *opts, const char *name, char *value, int line_num) +filter_rule_set(opts_t *opts, unsigned int user_auth, const char *name, char *value, int line_num) { char *argv[sizeof(char *) * MAX_FILTER_RULE_TOKENS]; int argc = 0; @@ -2223,7 +2223,7 @@ filter_rule_set(opts_t *opts, const char *name, char *value, int line_num) } } - return filter_rule_parse(opts, name, argc, argv, line_num); + return filter_rule_parse(opts, user_auth, name, argc, argv, line_num); } static filter_port_t * diff --git a/src/filter.h b/src/filter.h index 7243295..7a782e8 100644 --- a/src/filter.h +++ b/src/filter.h @@ -277,7 +277,7 @@ char *filter_macro_str(macro_t *); char *filter_rule_str(filter_rule_t *); char *filter_str(filter_t *); -int filter_passsite_set(opts_t *, char *, int) NONNULL(1,2) WUNRES; +int filter_passsite_set(opts_t *, unsigned int, char *, int) NONNULL(1,3) WUNRES; int filter_macro_set(opts_t *, char *, int) NONNULL(1,2) WUNRES; filter_port_t *filter_port_find(filter_site_t *, char *) NONNULL(1,2); @@ -296,7 +296,7 @@ filter_desc_t *filter_desc_substring_match(ACMachine(char) *, char *) NONNULL(2) 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 *, const char *, char *, int) NONNULL(1,2,3) WUNRES; +int filter_rule_set(opts_t *, unsigned int, const char *, char *, int) NONNULL(1,3,4) WUNRES; filter_t *filter_set(filter_rule_t *) WUNRES; #endif /* !FILTER_H */ diff --git a/src/main.c b/src/main.c index 734632d..f1e2a9c 100644 --- a/src/main.c +++ b/src/main.c @@ -328,26 +328,26 @@ main_load_leafcert(const char *filename, void *arg) } static void -main_check_opts(opts_t *opts, const char *argv0) +main_check_opts(opts_t *opts, conn_opts_t *conn_opts, const char *argv0) { - if (opts->cacrt && !opts->cakey) { + if (conn_opts->cacrt && !conn_opts->cakey) { fprintf(stderr, "%s: no CA key specified (-k).\n", argv0); exit(EXIT_FAILURE); } - if (opts->cakey && !opts->cacrt) { + if (conn_opts->cakey && !conn_opts->cacrt) { fprintf(stderr, "%s: no CA cert specified (-c).\n", argv0); exit(EXIT_FAILURE); } - if (opts->cakey && opts->cacrt && - (X509_check_private_key(opts->cacrt, opts->cakey) != 1)) { + if (conn_opts->cakey && conn_opts->cacrt && + (X509_check_private_key(conn_opts->cacrt, conn_opts->cakey) != 1)) { fprintf(stderr, "%s: CA cert does not match key.\n", argv0); ERR_print_errors_fp(stderr); exit(EXIT_FAILURE); } - if (!opts->cakey && + if (!conn_opts->cakey && !opts->global->leafcertdir && !opts->global->defaultleafcert) { fprintf(stderr, "%s: at least one of -c/-k, -t or -A " @@ -410,15 +410,15 @@ main(int argc, char *argv[]) exit(EXIT_FAILURE); break; case 'c': - if (opts_set_cacrt(global->opts, argv0, optarg, global_tmp_opts) == -1) + if (opts_set_cacrt(global->conn_opts, argv0, optarg, global_tmp_opts) == -1) exit(EXIT_FAILURE); break; case 'k': - if (opts_set_cakey(global->opts, argv0, optarg, global_tmp_opts) == -1) + if (opts_set_cakey(global->conn_opts, argv0, optarg, global_tmp_opts) == -1) exit(EXIT_FAILURE); break; case 'C': - if (opts_set_chain(global->opts, argv0, optarg, global_tmp_opts) == -1) + if (opts_set_chain(global->conn_opts, argv0, optarg, global_tmp_opts) == -1) exit(EXIT_FAILURE); break; case 'K': @@ -434,54 +434,54 @@ main(int argc, char *argv[]) exit(EXIT_FAILURE); break; case 'q': - if (opts_set_leafcrlurl(global->opts, argv0, optarg, global_tmp_opts) == -1) + if (opts_set_leafcrlurl(global->conn_opts, argv0, optarg, global_tmp_opts) == -1) exit(EXIT_FAILURE); break; case 'O': - opts_set_deny_ocsp(global->opts); + opts_set_deny_ocsp(global->conn_opts); break; case 'P': - opts_set_passthrough(global->opts); + opts_set_passthrough(global->conn_opts); break; case 'a': - if (opts_set_clientcrt(global->opts, argv0, optarg, global_tmp_opts) == -1) + if (opts_set_clientcrt(global->conn_opts, argv0, optarg, global_tmp_opts) == -1) exit(EXIT_FAILURE); break; case 'b': - if (opts_set_clientkey(global->opts, argv0, optarg, global_tmp_opts) == -1) + if (opts_set_clientkey(global->conn_opts, argv0, optarg, global_tmp_opts) == -1) exit(EXIT_FAILURE); break; #ifndef OPENSSL_NO_DH case 'g': - if (opts_set_dh(global->opts, argv0, optarg, global_tmp_opts) == -1) + if (opts_set_dh(global->conn_opts, argv0, optarg, global_tmp_opts) == -1) exit(EXIT_FAILURE); break; #endif /* !OPENSSL_NO_DH */ #ifndef OPENSSL_NO_ECDH case 'G': - if (opts_set_ecdhcurve(global->opts, argv0, optarg) == -1) + if (opts_set_ecdhcurve(global->conn_opts, argv0, optarg) == -1) exit(EXIT_FAILURE); break; #endif /* !OPENSSL_NO_ECDH */ #ifdef SSL_OP_NO_COMPRESSION case 'Z': - opts_unset_sslcomp(global->opts); + opts_unset_sslcomp(global->conn_opts); break; #endif /* SSL_OP_NO_COMPRESSION */ case 's': - if (opts_set_ciphers(global->opts, argv0, optarg) == -1) + if (opts_set_ciphers(global->conn_opts, argv0, optarg) == -1) exit(EXIT_FAILURE); break; case 'U': - if (opts_set_ciphersuites(global->opts, argv0, optarg) == -1) + if (opts_set_ciphersuites(global->conn_opts, argv0, optarg) == -1) exit(EXIT_FAILURE); break; case 'r': - if (opts_force_proto(global->opts, argv0, optarg) == -1) + if (opts_force_proto(global->conn_opts, argv0, optarg) == -1) exit(EXIT_FAILURE); break; case 'R': - if (opts_disable_proto(global->opts, argv0, optarg) == -1) + if (opts_disable_proto(global->conn_opts, argv0, optarg) == -1) exit(EXIT_FAILURE); break; #ifndef OPENSSL_NO_ENGINE @@ -671,10 +671,10 @@ main(int argc, char *argv[]) exit(EXIT_FAILURE); } #endif /* !OPENSSL_NO_ENGINE */ - main_check_opts(global->opts, argv0); + main_check_opts(global->opts, global->conn_opts, argv0); for (proxyspec_t *spec = global->spec; spec; spec = spec->next) { if (spec->ssl || spec->upgrade) - main_check_opts(spec->opts, argv0); + main_check_opts(spec->opts, spec->conn_opts, argv0); } } #ifdef __APPLE__ @@ -698,7 +698,7 @@ main(int argc, char *argv[]) } #ifndef WITHOUT_USERAUTH - if (global->opts->user_auth || global_has_userauth_spec(global)) { + if (global->conn_opts->user_auth || global_has_userauth_spec(global)) { if (!global->userdb_path) { fprintf(stderr, "User auth requires a userdb path\n"); exit(EXIT_FAILURE); @@ -720,25 +720,25 @@ main(int argc, char *argv[]) #endif /* !WITHOUT_USERAUTH */ /* dynamic defaults */ - if (!global->opts->ciphers) { - global->opts->ciphers = strdup(DFLT_CIPHERS); - if (!global->opts->ciphers) + if (!global->conn_opts->ciphers) { + global->conn_opts->ciphers = strdup(DFLT_CIPHERS); + if (!global->conn_opts->ciphers) oom_die(argv0); } - if (!global->opts->ciphersuites) { - global->opts->ciphersuites = strdup(DFLT_CIPHERSUITES); - if (!global->opts->ciphersuites) + if (!global->conn_opts->ciphersuites) { + global->conn_opts->ciphersuites = strdup(DFLT_CIPHERSUITES); + if (!global->conn_opts->ciphersuites) oom_die(argv0); } for (proxyspec_t *spec = global->spec; spec; spec = spec->next) { - if (!spec->opts->ciphers) { - spec->opts->ciphers = strdup(DFLT_CIPHERS); - if (!spec->opts->ciphers) + if (!spec->conn_opts->ciphers) { + spec->conn_opts->ciphers = strdup(DFLT_CIPHERS); + if (!spec->conn_opts->ciphers) oom_die(argv0); } - if (!spec->opts->ciphersuites) { - spec->opts->ciphersuites = strdup(DFLT_CIPHERSUITES); - if (!spec->opts->ciphersuites) + if (!spec->conn_opts->ciphersuites) { + spec->conn_opts->ciphersuites = strdup(DFLT_CIPHERSUITES); + if (!spec->conn_opts->ciphersuites) oom_die(argv0); } } @@ -867,7 +867,7 @@ main(int argc, char *argv[]) /* debug log, part 2 */ if (OPTS_DEBUG(global)) { - char *s = opts_proto_dbg_dump(global->opts); + char *s = opts_proto_dbg_dump(global->conn_opts); if (!s) oom_die(argv0); @@ -889,20 +889,20 @@ main(int argc, char *argv[]) global->openssl_engine); } #endif /* !OPENSSL_NO_ENGINE */ - if (global->opts->cacrt) { - char *subj = ssl_x509_subject(global->opts->cacrt); + if (global->conn_opts->cacrt) { + char *subj = ssl_x509_subject(global->conn_opts->cacrt); log_dbg_printf("Loaded CA: '%s'\n", subj); free(subj); #ifdef DEBUG_CERTIFICATE - log_dbg_print_free(ssl_x509_to_str(global->opts->cacrt)); - log_dbg_print_free(ssl_x509_to_pem(global->opts->cacrt)); + log_dbg_print_free(ssl_x509_to_str(global->conn_opts->cacrt)); + log_dbg_print_free(ssl_x509_to_pem(global->conn_opts->cacrt)); #endif /* DEBUG_CERTIFICATE */ } else { log_dbg_printf("No CA loaded.\n"); } for (proxyspec_t *spec = global->spec; spec; spec = spec->next) { - if (spec->opts->cacrt) { - char *subj = ssl_x509_subject(spec->opts->cacrt); + if (spec->conn_opts->cacrt) { + char *subj = ssl_x509_subject(spec->conn_opts->cacrt); log_dbg_printf("Loaded ProxySpec CA: '%s'\n", subj); free(subj); #ifdef DEBUG_CERTIFICATE @@ -921,9 +921,9 @@ main(int argc, char *argv[]) if (global->defaultleafcert) { log_dbg_printf("- Default leaf key\n"); // @todo Debug print the cakey and passthrough opts for proxspecs too? - } else if (global->opts->cakey) { + } else if (global->conn_opts->cakey) { log_dbg_printf("- Global generated on the fly\n"); - } else if (global->opts->passthrough) { + } else if (global->conn_opts->passthrough) { log_dbg_printf("- Global passthrough without decryption\n"); } else { log_dbg_printf("- Global connection drop\n"); diff --git a/src/opts.c b/src/opts.c index 72994f0..ba8735d 100644 --- a/src/opts.c +++ b/src/opts.c @@ -120,34 +120,47 @@ opts_load_cert_chain_key(const char *filename) return cert; } -opts_t * -opts_new(void) +static conn_opts_t * MALLOC WUNRES +conn_opts_new(void) { - opts_t *opts; + conn_opts_t *conn_opts; - opts = malloc(sizeof(opts_t)); - if (!opts) + conn_opts = malloc(sizeof(conn_opts_t)); + if (!conn_opts) return oom_return_na_null(); - memset(opts, 0, sizeof(opts_t)); + memset(conn_opts, 0, sizeof(conn_opts_t)); - opts->divert = 1; - opts->sslcomp = 1; - opts->chain = sk_X509_new_null(); - opts->sslmethod = SSLv23_method; + conn_opts->sslcomp = 1; + conn_opts->chain = sk_X509_new_null(); + conn_opts->sslmethod = SSLv23_method; #if (OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)) || (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x20702000L) - opts->minsslversion = TLS1_VERSION; + conn_opts->minsslversion = TLS1_VERSION; #ifdef HAVE_TLSV13 - opts->maxsslversion = TLS1_3_VERSION; + conn_opts->maxsslversion = TLS1_3_VERSION; #else /* !HAVE_TLSV13 */ - opts->maxsslversion = TLS1_2_VERSION; + conn_opts->maxsslversion = TLS1_2_VERSION; #endif /* !HAVE_TLSV13 */ #endif /* OPENSSL_VERSION_NUMBER >= 0x10100000L */ - opts->remove_http_referer = 1; - opts->verify_peer = 1; + conn_opts->remove_http_referer = 1; + conn_opts->verify_peer = 1; #ifndef WITHOUT_USERAUTH - opts->user_timeout = 300; + conn_opts->user_timeout = 300; #endif /* !WITHOUT_USERAUTH */ - opts->max_http_header_size = 8192; + conn_opts->max_http_header_size = 8192; + return conn_opts; +} + +opts_t * +opts_new(void) +{ + opts_t *opts; + + opts = malloc(sizeof(opts_t)); + if (!opts) + return oom_return_na_null(); + memset(opts, 0, sizeof(opts_t)); + + opts->divert = 1; return opts; } @@ -166,6 +179,9 @@ global_new(void) global->expired_conn_check_period = 10; global->stats_period = 1; + global->conn_opts = conn_opts_new(); + if (!global->conn_opts) + return NULL; global->opts = opts_new(); if (!global->opts) return NULL; @@ -173,44 +189,54 @@ global_new(void) return global; } -void -opts_free(opts_t *opts) +static void NONNULL(1) +conn_opts_free(conn_opts_t *conn_opts) { - if (opts->chain) { - sk_X509_pop_free(opts->chain, X509_free); + if (conn_opts->chain) { + sk_X509_pop_free(conn_opts->chain, X509_free); } - if (opts->clientcrt) { - X509_free(opts->clientcrt); + if (conn_opts->clientcrt) { + X509_free(conn_opts->clientcrt); } - if (opts->clientkey) { - EVP_PKEY_free(opts->clientkey); + if (conn_opts->clientkey) { + EVP_PKEY_free(conn_opts->clientkey); } - if (opts->cacrt) { - X509_free(opts->cacrt); + if (conn_opts->cacrt) { + X509_free(conn_opts->cacrt); } - if (opts->cakey) { - EVP_PKEY_free(opts->cakey); + if (conn_opts->cakey) { + EVP_PKEY_free(conn_opts->cakey); } #ifndef OPENSSL_NO_DH - if (opts->dh) { - DH_free(opts->dh); + if (conn_opts->dh) { + DH_free(conn_opts->dh); } #endif /* !OPENSSL_NO_DH */ #ifndef OPENSSL_NO_ECDH - if (opts->ecdhcurve) { - free(opts->ecdhcurve); + if (conn_opts->ecdhcurve) { + free(conn_opts->ecdhcurve); } #endif /* !OPENSSL_NO_ECDH */ - if (opts->ciphers) { - free(opts->ciphers); + if (conn_opts->ciphers) { + free(conn_opts->ciphers); } - if (opts->ciphersuites) { - free(opts->ciphersuites); + if (conn_opts->ciphersuites) { + free(conn_opts->ciphersuites); } #ifndef WITHOUT_USERAUTH - if (opts->user_auth_url) { - free(opts->user_auth_url); + if (conn_opts->user_auth_url) { + free(conn_opts->user_auth_url); } +#endif /* !WITHOUT_USERAUTH */ + + memset(conn_opts, 0, sizeof(opts_t)); + free(conn_opts); +} + +void +opts_free(opts_t *opts) +{ +#ifndef WITHOUT_USERAUTH filter_userlist_free(opts->divertusers); filter_userlist_free(opts->passusers); #endif /* !WITHOUT_USERAUTH */ @@ -244,6 +270,8 @@ spec_addrs_free(spec_addrs_t *spec_addrs) void proxyspec_free(proxyspec_t *spec) { + if (spec->conn_opts) + conn_opts_free(spec->conn_opts); if (spec->opts) opts_free(spec->opts); if (spec->natengine) @@ -365,6 +393,9 @@ global_free(global_t *global) sqlite3_close(global->userdb); } #endif /* !WITHOUT_USERAUTH */ + if (global->conn_opts) { + conn_opts_free(global->conn_opts); + } if (global->opts) { opts_free(global->opts); } @@ -422,7 +453,7 @@ global_has_userauth_spec(global_t *global) { proxyspec_t *p = global->spec; while (p) { - if (p->opts->user_auth) + if (p->conn_opts->user_auth) return 1; p = p->next; } @@ -438,7 +469,7 @@ global_has_cakey_spec(global_t *global) { proxyspec_t *p = global->spec; while (p) { - if (p->opts->cakey) + if (p->conn_opts->cakey) return 1; p = p->next; } @@ -449,101 +480,101 @@ global_has_cakey_spec(global_t *global) * Dump the SSL/TLS protocol related configuration. */ char * -opts_proto_dbg_dump(opts_t *opts) +opts_proto_dbg_dump(conn_opts_t *conn_opts) { char *s; if (asprintf(&s, "SSL/TLS protocol: %s%s%s%s%s%s%s%s%s", #if (OPENSSL_VERSION_NUMBER < 0x10100000L) || (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20702000L) #ifdef HAVE_SSLV2 - (opts->sslmethod == SSLv2_method) ? "ssl2" : + (conn_opts->sslmethod == SSLv2_method) ? "ssl2" : #endif /* HAVE_SSLV2 */ #ifdef HAVE_SSLV3 - (opts->sslmethod == SSLv3_method) ? "ssl3" : + (conn_opts->sslmethod == SSLv3_method) ? "ssl3" : #endif /* HAVE_SSLV3 */ #ifdef HAVE_TLSV10 - (opts->sslmethod == TLSv1_method) ? "tls10" : + (conn_opts->sslmethod == TLSv1_method) ? "tls10" : #endif /* HAVE_TLSV10 */ #ifdef HAVE_TLSV11 - (opts->sslmethod == TLSv1_1_method) ? "tls11" : + (conn_opts->sslmethod == TLSv1_1_method) ? "tls11" : #endif /* HAVE_TLSV11 */ #ifdef HAVE_TLSV12 - (opts->sslmethod == TLSv1_2_method) ? "tls12" : + (conn_opts->sslmethod == TLSv1_2_method) ? "tls12" : #endif /* HAVE_TLSV12 */ /* There is no TLSv1_3_method defined, * since no ssl version < 0x10100000L supports it. */ #else /* OPENSSL_VERSION_NUMBER >= 0x10100000L */ #ifdef HAVE_SSLV3 - (opts->sslversion == SSL3_VERSION) ? "ssl3" : + (conn_opts->sslversion == SSL3_VERSION) ? "ssl3" : #endif /* HAVE_SSLV3 */ #ifdef HAVE_TLSV10 - (opts->sslversion == TLS1_VERSION) ? "tls10" : + (conn_opts->sslversion == TLS1_VERSION) ? "tls10" : #endif /* HAVE_TLSV10 */ #ifdef HAVE_TLSV11 - (opts->sslversion == TLS1_1_VERSION) ? "tls11" : + (conn_opts->sslversion == TLS1_1_VERSION) ? "tls11" : #endif /* HAVE_TLSV11 */ #ifdef HAVE_TLSV12 - (opts->sslversion == TLS1_2_VERSION) ? "tls12" : + (conn_opts->sslversion == TLS1_2_VERSION) ? "tls12" : #endif /* HAVE_TLSV12 */ #ifdef HAVE_TLSV13 - (opts->sslversion == TLS1_3_VERSION) ? "tls13" : + (conn_opts->sslversion == TLS1_3_VERSION) ? "tls13" : #endif /* HAVE_TLSV13 */ #endif /* OPENSSL_VERSION_NUMBER >= 0x10100000L */ "negotiate", #ifdef HAVE_SSLV2 - opts->no_ssl2 ? " -ssl2" : + conn_opts->no_ssl2 ? " -ssl2" : #endif /* HAVE_SSLV2 */ "", #ifdef HAVE_SSLV3 - opts->no_ssl3 ? " -ssl3" : + conn_opts->no_ssl3 ? " -ssl3" : #endif /* HAVE_SSLV3 */ "", #ifdef HAVE_TLSV10 - opts->no_tls10 ? " -tls10" : + conn_opts->no_tls10 ? " -tls10" : #endif /* HAVE_TLSV10 */ "", #ifdef HAVE_TLSV11 - opts->no_tls11 ? " -tls11" : + conn_opts->no_tls11 ? " -tls11" : #endif /* HAVE_TLSV11 */ "", #ifdef HAVE_TLSV12 - opts->no_tls12 ? " -tls12" : + conn_opts->no_tls12 ? " -tls12" : #endif /* HAVE_TLSV12 */ "", #ifdef HAVE_TLSV13 - opts->no_tls13 ? " -tls13" : + conn_opts->no_tls13 ? " -tls13" : #endif /* HAVE_TLSV13 */ "", #if (OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)) || (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x20702000L) #ifdef HAVE_SSLV3 - (opts->minsslversion == SSL3_VERSION) ? ">=ssl3" : + (conn_opts->minsslversion == SSL3_VERSION) ? ">=ssl3" : #endif /* HAVE_SSLV3 */ #ifdef HAVE_TLSV10 - (opts->minsslversion == TLS1_VERSION) ? ">=tls10" : + (conn_opts->minsslversion == TLS1_VERSION) ? ">=tls10" : #endif /* HAVE_TLSV10 */ #ifdef HAVE_TLSV11 - (opts->minsslversion == TLS1_1_VERSION) ? ">=tls11" : + (conn_opts->minsslversion == TLS1_1_VERSION) ? ">=tls11" : #endif /* HAVE_TLSV11 */ #ifdef HAVE_TLSV12 - (opts->minsslversion == TLS1_2_VERSION) ? ">=tls12" : + (conn_opts->minsslversion == TLS1_2_VERSION) ? ">=tls12" : #endif /* HAVE_TLSV12 */ #ifdef HAVE_TLSV13 - (opts->minsslversion == TLS1_3_VERSION) ? ">=tls13" : + (conn_opts->minsslversion == TLS1_3_VERSION) ? ">=tls13" : #endif /* HAVE_TLSV13 */ "", #ifdef HAVE_SSLV3 - (opts->maxsslversion == SSL3_VERSION) ? "<=ssl3" : + (conn_opts->maxsslversion == SSL3_VERSION) ? "<=ssl3" : #endif /* HAVE_SSLV3 */ #ifdef HAVE_TLSV10 - (opts->maxsslversion == TLS1_VERSION) ? "<=tls10" : + (conn_opts->maxsslversion == TLS1_VERSION) ? "<=tls10" : #endif /* HAVE_TLSV10 */ #ifdef HAVE_TLSV11 - (opts->maxsslversion == TLS1_1_VERSION) ? "<=tls11" : + (conn_opts->maxsslversion == TLS1_1_VERSION) ? "<=tls11" : #endif /* HAVE_TLSV11 */ #ifdef HAVE_TLSV12 - (opts->maxsslversion == TLS1_2_VERSION) ? "<=tls12" : + (conn_opts->maxsslversion == TLS1_2_VERSION) ? "<=tls12" : #endif /* HAVE_TLSV12 */ #ifdef HAVE_TLSV13 - (opts->maxsslversion == TLS1_3_VERSION) ? "<=tls13" : + (conn_opts->maxsslversion == TLS1_3_VERSION) ? "<=tls13" : #endif /* HAVE_TLSV13 */ "" #else /* OPENSSL_VERSION_NUMBER < 0x10100000L */ @@ -557,123 +588,138 @@ opts_proto_dbg_dump(opts_t *opts) #ifndef WITHOUT_USERAUTH static int WUNRES -opts_set_user_auth_url(opts_t *opts, const char * argv0, const char *optarg) +opts_set_user_auth_url(conn_opts_t *conn_opts, const char * argv0, const char *optarg) { - if (opts->user_auth_url) - free(opts->user_auth_url); - opts->user_auth_url = strdup(optarg); - if (!opts->user_auth_url) + if (conn_opts->user_auth_url) + free(conn_opts->user_auth_url); + conn_opts->user_auth_url = strdup(optarg); + if (!conn_opts->user_auth_url) return oom_return(argv0); #ifdef DEBUG_OPTS - log_dbg_printf("UserAuthURL: %s\n", opts->user_auth_url); + log_dbg_printf("UserAuthURL: %s\n", conn_opts->user_auth_url); #endif /* DEBUG_OPTS */ return 0; } #endif /* !WITHOUT_USERAUTH */ -static opts_t * WUNRES -global_opts_copy(global_t *global, const char *argv0, global_tmp_opts_t *global_tmp_opts) +static conn_opts_t * WUNRES +global_conn_opts_copy(global_t *global, const char *argv0, global_tmp_opts_t *global_tmp_opts) { #ifdef DEBUG_OPTS - log_dbg_printf("Copy global opts\n"); + log_dbg_printf("Copy global conn_opts\n"); #endif /* DEBUG_OPTS */ - opts_t *opts = opts_new(); - if (!opts) + conn_opts_t *conn_opts = conn_opts_new(); + if (!conn_opts) return NULL; - opts->global = global; - opts->divert = global->opts->divert; - opts->sslcomp = global->opts->sslcomp; + conn_opts->sslcomp = global->conn_opts->sslcomp; #ifdef HAVE_SSLV2 - opts->no_ssl2 = global->opts->no_ssl2; + conn_opts->no_ssl2 = global->conn_opts->no_ssl2; #endif /* HAVE_SSLV2 */ #ifdef HAVE_SSLV3 - opts->no_ssl3 = global->opts->no_ssl3; + conn_opts->no_ssl3 = global->conn_opts->no_ssl3; #endif /* HAVE_SSLV3 */ #ifdef HAVE_TLSV10 - opts->no_tls10 = global->opts->no_tls10; + conn_opts->no_tls10 = global->conn_opts->no_tls10; #endif /* HAVE_TLSV10 */ #ifdef HAVE_TLSV11 - opts->no_tls11 = global->opts->no_tls11; + conn_opts->no_tls11 = global->conn_opts->no_tls11; #endif /* HAVE_TLSV11 */ #ifdef HAVE_TLSV12 - opts->no_tls12 = global->opts->no_tls12; + conn_opts->no_tls12 = global->conn_opts->no_tls12; #endif /* HAVE_TLSV12 */ #ifdef HAVE_TLSV13 - opts->no_tls13 = global->opts->no_tls13; + conn_opts->no_tls13 = global->conn_opts->no_tls13; #endif /* HAVE_TLSV13 */ - opts->passthrough = global->opts->passthrough; - opts->deny_ocsp = global->opts->deny_ocsp; - opts->sslmethod = global->opts->sslmethod; + conn_opts->passthrough = global->conn_opts->passthrough; + conn_opts->deny_ocsp = global->conn_opts->deny_ocsp; + conn_opts->sslmethod = global->conn_opts->sslmethod; #if (OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)) || (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x20702000L) - opts->sslversion = global->opts->sslversion; - opts->minsslversion = global->opts->minsslversion; - opts->maxsslversion = global->opts->maxsslversion; + conn_opts->sslversion = global->conn_opts->sslversion; + conn_opts->minsslversion = global->conn_opts->minsslversion; + conn_opts->maxsslversion = global->conn_opts->maxsslversion; #endif /* OPENSSL_VERSION_NUMBER >= 0x10100000L */ - opts->remove_http_accept_encoding = global->opts->remove_http_accept_encoding; - opts->remove_http_referer = global->opts->remove_http_referer; - opts->verify_peer = global->opts->verify_peer; - opts->allow_wrong_host = global->opts->allow_wrong_host; + conn_opts->remove_http_accept_encoding = global->conn_opts->remove_http_accept_encoding; + conn_opts->remove_http_referer = global->conn_opts->remove_http_referer; + conn_opts->verify_peer = global->conn_opts->verify_peer; + conn_opts->allow_wrong_host = global->conn_opts->allow_wrong_host; #ifndef WITHOUT_USERAUTH - opts->user_auth = global->opts->user_auth; - opts->user_timeout = global->opts->user_timeout; + conn_opts->user_auth = global->conn_opts->user_auth; + conn_opts->user_timeout = global->conn_opts->user_timeout; #endif /* !WITHOUT_USERAUTH */ - opts->validate_proto = global->opts->validate_proto; - opts->max_http_header_size = global->opts->max_http_header_size; + conn_opts->validate_proto = global->conn_opts->validate_proto; + conn_opts->max_http_header_size = global->conn_opts->max_http_header_size; // Pass NULL as global_tmp_opts param, so we don't reassign the var to itself // That would be harmless but incorrect if (global_tmp_opts && global_tmp_opts->chain_str) { - if (opts_set_chain(opts, argv0, global_tmp_opts->chain_str, NULL) == -1) + if (opts_set_chain(conn_opts, argv0, global_tmp_opts->chain_str, NULL) == -1) return NULL; } if (global_tmp_opts && global_tmp_opts->leafcrlurl_str) { - if (opts_set_leafcrlurl(opts, argv0, global_tmp_opts->leafcrlurl_str, NULL) == -1) + if (opts_set_leafcrlurl(conn_opts, argv0, global_tmp_opts->leafcrlurl_str, NULL) == -1) return NULL; } if (global_tmp_opts && global_tmp_opts->cacrt_str) { - if (opts_set_cacrt(opts, argv0, global_tmp_opts->cacrt_str, NULL) == -1) + if (opts_set_cacrt(conn_opts, argv0, global_tmp_opts->cacrt_str, NULL) == -1) return NULL; } if (global_tmp_opts && global_tmp_opts->cakey_str) { - if (opts_set_cakey(opts, argv0, global_tmp_opts->cakey_str, NULL) == -1) + if (opts_set_cakey(conn_opts, argv0, global_tmp_opts->cakey_str, NULL) == -1) return NULL; } if (global_tmp_opts && global_tmp_opts->clientcrt_str) { - if (opts_set_clientcrt(opts, argv0, global_tmp_opts->clientcrt_str, NULL) == -1) + if (opts_set_clientcrt(conn_opts, argv0, global_tmp_opts->clientcrt_str, NULL) == -1) return NULL; } if (global_tmp_opts && global_tmp_opts->clientkey_str) { - if (opts_set_clientkey(opts, argv0, global_tmp_opts->clientkey_str, NULL) == -1) + if (opts_set_clientkey(conn_opts, argv0, global_tmp_opts->clientkey_str, NULL) == -1) return NULL; } #ifndef OPENSSL_NO_DH if (global_tmp_opts && global_tmp_opts->dh_str) { - if (opts_set_dh(opts, argv0, global_tmp_opts->dh_str, NULL) == -1) + if (opts_set_dh(conn_opts, argv0, global_tmp_opts->dh_str, NULL) == -1) return NULL; } #endif /* !OPENSSL_NO_DH */ #ifndef OPENSSL_NO_ECDH - if (global->opts->ecdhcurve) { - if (opts_set_ecdhcurve(opts, argv0, global->opts->ecdhcurve) == -1) + if (global->conn_opts->ecdhcurve) { + if (opts_set_ecdhcurve(conn_opts, argv0, global->conn_opts->ecdhcurve) == -1) return NULL; } #endif /* !OPENSSL_NO_ECDH */ - if (global->opts->ciphers) { - if (opts_set_ciphers(opts, argv0, global->opts->ciphers) == -1) + if (global->conn_opts->ciphers) { + if (opts_set_ciphers(conn_opts, argv0, global->conn_opts->ciphers) == -1) return NULL; } - if (global->opts->ciphersuites) { - if (opts_set_ciphersuites(opts, argv0, global->opts->ciphersuites) == -1) + if (global->conn_opts->ciphersuites) { + if (opts_set_ciphersuites(conn_opts, argv0, global->conn_opts->ciphersuites) == -1) return NULL; } #ifndef WITHOUT_USERAUTH - if (global->opts->user_auth_url) { - if (opts_set_user_auth_url(opts, argv0, global->opts->user_auth_url) == -1) + if (global->conn_opts->user_auth_url) { + if (opts_set_user_auth_url(conn_opts, argv0, global->conn_opts->user_auth_url) == -1) return NULL; } + return conn_opts; +} + +static opts_t * WUNRES +global_opts_copy(global_t *global, const char *argv0) +{ +#ifdef DEBUG_OPTS + log_dbg_printf("Copy global opts\n"); +#endif /* DEBUG_OPTS */ + + opts_t *opts = opts_new(); + if (!opts) + return NULL; + opts->global = global; + + opts->divert = global->opts->divert; + if (filter_userlist_copy(global->opts->divertusers, argv0, &opts->divertusers) == -1) return oom_return_null(argv0); @@ -697,7 +743,10 @@ proxyspec_new(global_t *global, const char *argv0, global_tmp_opts_t *global_tmp if (!spec) return oom_return_null(argv0); memset(spec, 0, sizeof(proxyspec_t)); - spec->opts = global_opts_copy(global, argv0, global_tmp_opts); + spec->conn_opts = global_conn_opts_copy(global, argv0, global_tmp_opts); + if (!spec->conn_opts) + return NULL; + spec->opts = global_opts_copy(global, argv0); if (!spec->opts) return NULL; return spec; @@ -1021,7 +1070,7 @@ proxyspec_parse(int *argc, char **argv[], const char *natengine, global_t *globa } static char * -opts_str(opts_t *opts) +opts_str(opts_t *opts, conn_opts_t *conn_opts) { char *s = NULL; char *proto_dump = NULL; @@ -1054,7 +1103,7 @@ opts_str(opts_t *opts) if (!fs) goto out; - proto_dump = opts_proto_dbg_dump(opts); + proto_dump = opts_proto_dbg_dump(conn_opts); if (!proto_dump) goto out; @@ -1087,46 +1136,46 @@ opts_str(opts_t *opts) #endif /* !WITHOUT_USERAUTH */ "%s|%d\n%s%s%s%s%s%s%s", (opts->divert ? "divert" : "split"), - (!opts->sslcomp ? "|no sslcomp" : ""), + (!conn_opts->sslcomp ? "|no sslcomp" : ""), #ifdef HAVE_SSLV2 - (opts->no_ssl2 ? "|no_ssl2" : ""), + (conn_opts->no_ssl2 ? "|no_ssl2" : ""), #endif /* HAVE_SSLV2 */ #ifdef HAVE_SSLV3 - (opts->no_ssl3 ? "|no_ssl3" : ""), + (conn_opts->no_ssl3 ? "|no_ssl3" : ""), #endif /* HAVE_SSLV3 */ #ifdef HAVE_TLSV10 - (opts->no_tls10 ? "|no_tls10" : ""), + (conn_opts->no_tls10 ? "|no_tls10" : ""), #endif /* HAVE_TLSV10 */ #ifdef HAVE_TLSV11 - (opts->no_tls11 ? "|no_tls11" : ""), + (conn_opts->no_tls11 ? "|no_tls11" : ""), #endif /* HAVE_TLSV11 */ #ifdef HAVE_TLSV12 - (opts->no_tls12 ? "|no_tls12" : ""), + (conn_opts->no_tls12 ? "|no_tls12" : ""), #endif /* HAVE_TLSV12 */ #ifdef HAVE_TLSV13 - (opts->no_tls13 ? "|no_tls13" : ""), + (conn_opts->no_tls13 ? "|no_tls13" : ""), #endif /* HAVE_TLSV13 */ - (opts->passthrough ? "|passthrough" : ""), - (opts->deny_ocsp ? "|deny_ocsp" : ""), - (opts->ciphers ? opts->ciphers : "no ciphers"), - (opts->ciphersuites ? opts->ciphersuites : "no ciphersuites"), + (conn_opts->passthrough ? "|passthrough" : ""), + (conn_opts->deny_ocsp ? "|deny_ocsp" : ""), + (conn_opts->ciphers ? conn_opts->ciphers : "no ciphers"), + (conn_opts->ciphersuites ? conn_opts->ciphersuites : "no ciphersuites"), #ifndef OPENSSL_NO_ECDH - (opts->ecdhcurve ? opts->ecdhcurve : "no ecdhcurve"), + (conn_opts->ecdhcurve ? conn_opts->ecdhcurve : "no ecdhcurve"), #endif /* !OPENSSL_NO_ECDH */ - (opts->leafcrlurl ? opts->leafcrlurl : "no leafcrlurl"), - (opts->remove_http_accept_encoding ? "|remove_http_accept_encoding" : ""), - (opts->remove_http_referer ? "|remove_http_referer" : ""), - (opts->verify_peer ? "|verify_peer" : ""), - (opts->allow_wrong_host ? "|allow_wrong_host" : ""), + (conn_opts->leafcrlurl ? conn_opts->leafcrlurl : "no leafcrlurl"), + (conn_opts->remove_http_accept_encoding ? "|remove_http_accept_encoding" : ""), + (conn_opts->remove_http_referer ? "|remove_http_referer" : ""), + (conn_opts->verify_peer ? "|verify_peer" : ""), + (conn_opts->allow_wrong_host ? "|allow_wrong_host" : ""), #ifndef WITHOUT_USERAUTH - (opts->user_auth ? "|user_auth" : ""), - (opts->user_auth_url ? opts->user_auth_url : "no user_auth_url"), - opts->user_timeout, + (conn_opts->user_auth ? "|user_auth" : ""), + (conn_opts->user_auth_url ? conn_opts->user_auth_url : "no user_auth_url"), + conn_opts->user_timeout, du, pu, #endif /* !WITHOUT_USERAUTH */ - (opts->validate_proto ? "|validate_proto" : ""), - opts->max_http_header_size, + (conn_opts->validate_proto ? "|validate_proto" : ""), + conn_opts->max_http_header_size, proto_dump, strlen(ms) ? "\n" : "", ms, strlen(frs) ? "\n" : "", frs, @@ -1214,7 +1263,7 @@ proxyspec_str(proxyspec_t *spec) goto out; } } - optsstr = opts_str(spec->opts); + optsstr = opts_str(spec->opts, spec->conn_opts); if (!optsstr) { goto out; } @@ -1248,7 +1297,7 @@ out: } int -opts_set_cacrt(opts_t *opts, const char *argv0, const char *optarg, global_tmp_opts_t *global_tmp_opts) +opts_set_cacrt(conn_opts_t *conn_opts, const char *argv0, const char *optarg, global_tmp_opts_t *global_tmp_opts) { if (global_tmp_opts) { if (global_tmp_opts->cacrt_str) @@ -1258,10 +1307,10 @@ opts_set_cacrt(opts_t *opts, const char *argv0, const char *optarg, global_tmp_o return oom_return(argv0); } - if (opts->cacrt) - X509_free(opts->cacrt); - opts->cacrt = ssl_x509_load(optarg); - if (!opts->cacrt) { + if (conn_opts->cacrt) + X509_free(conn_opts->cacrt); + conn_opts->cacrt = ssl_x509_load(optarg); + if (!conn_opts->cacrt) { fprintf(stderr, "%s: error loading CA cert from '%s':\n", argv0, optarg); if (errno) { @@ -1271,14 +1320,14 @@ opts_set_cacrt(opts_t *opts, const char *argv0, const char *optarg, global_tmp_o } return -1; } - ssl_x509_refcount_inc(opts->cacrt); - sk_X509_insert(opts->chain, opts->cacrt, 0); - if (!opts->cakey) { - opts->cakey = ssl_key_load(optarg); + ssl_x509_refcount_inc(conn_opts->cacrt); + sk_X509_insert(conn_opts->chain, conn_opts->cacrt, 0); + if (!conn_opts->cakey) { + conn_opts->cakey = ssl_key_load(optarg); } #ifndef OPENSSL_NO_DH - if (!opts->dh) { - opts->dh = ssl_dh_load(optarg); + if (!conn_opts->dh) { + conn_opts->dh = ssl_dh_load(optarg); } #endif /* !OPENSSL_NO_DH */ #ifdef DEBUG_OPTS @@ -1288,7 +1337,7 @@ opts_set_cacrt(opts_t *opts, const char *argv0, const char *optarg, global_tmp_o } int -opts_set_cakey(opts_t *opts, const char *argv0, const char *optarg, global_tmp_opts_t *global_tmp_opts) +opts_set_cakey(conn_opts_t *conn_opts, const char *argv0, const char *optarg, global_tmp_opts_t *global_tmp_opts) { if (global_tmp_opts) { if (global_tmp_opts->cakey_str) @@ -1298,10 +1347,10 @@ opts_set_cakey(opts_t *opts, const char *argv0, const char *optarg, global_tmp_o return oom_return(argv0); } - if (opts->cakey) - EVP_PKEY_free(opts->cakey); - opts->cakey = ssl_key_load(optarg); - if (!opts->cakey) { + if (conn_opts->cakey) + EVP_PKEY_free(conn_opts->cakey); + conn_opts->cakey = ssl_key_load(optarg); + if (!conn_opts->cakey) { fprintf(stderr, "%s: error loading CA key from '%s':\n", argv0, optarg); if (errno) { @@ -1311,16 +1360,16 @@ opts_set_cakey(opts_t *opts, const char *argv0, const char *optarg, global_tmp_o } return -1; } - if (!opts->cacrt) { - opts->cacrt = ssl_x509_load(optarg); - if (opts->cacrt) { - ssl_x509_refcount_inc(opts->cacrt); - sk_X509_insert(opts->chain, opts->cacrt, 0); + if (!conn_opts->cacrt) { + conn_opts->cacrt = ssl_x509_load(optarg); + if (conn_opts->cacrt) { + ssl_x509_refcount_inc(conn_opts->cacrt); + sk_X509_insert(conn_opts->chain, conn_opts->cacrt, 0); } } #ifndef OPENSSL_NO_DH - if (!opts->dh) { - opts->dh = ssl_dh_load(optarg); + if (!conn_opts->dh) { + conn_opts->dh = ssl_dh_load(optarg); } #endif /* !OPENSSL_NO_DH */ #ifdef DEBUG_OPTS @@ -1330,7 +1379,7 @@ opts_set_cakey(opts_t *opts, const char *argv0, const char *optarg, global_tmp_o } int -opts_set_chain(opts_t *opts, const char *argv0, const char *optarg, global_tmp_opts_t *global_tmp_opts) +opts_set_chain(conn_opts_t *opts, const char *argv0, const char *optarg, global_tmp_opts_t *global_tmp_opts) { if (global_tmp_opts) { if (global_tmp_opts->chain_str) @@ -1357,7 +1406,7 @@ opts_set_chain(opts_t *opts, const char *argv0, const char *optarg, global_tmp_o } int -opts_set_leafcrlurl(opts_t *opts, const char *argv0, const char *optarg, global_tmp_opts_t *global_tmp_opts) +opts_set_leafcrlurl(conn_opts_t *conn_opts, const char *argv0, const char *optarg, global_tmp_opts_t *global_tmp_opts) { if (global_tmp_opts) { if (global_tmp_opts->leafcrlurl_str) @@ -1367,13 +1416,13 @@ opts_set_leafcrlurl(opts_t *opts, const char *argv0, const char *optarg, global_ return oom_return(argv0); } - if (opts->leafcrlurl) - free(opts->leafcrlurl); - opts->leafcrlurl = strdup(optarg); - if (!opts->leafcrlurl) + if (conn_opts->leafcrlurl) + free(conn_opts->leafcrlurl); + conn_opts->leafcrlurl = strdup(optarg); + if (!conn_opts->leafcrlurl) return oom_return(argv0); #ifdef DEBUG_OPTS - log_dbg_printf("LeafCRLURL: %s\n", opts->leafcrlurl); + log_dbg_printf("LeafCRLURL: %s\n", conn_opts->leafcrlurl); #endif /* DEBUG_OPTS */ return 0; } @@ -1390,31 +1439,31 @@ set_certgendir(global_t *global, const char *argv0, const char *optarg) } void -opts_set_deny_ocsp(opts_t *opts) +opts_set_deny_ocsp(conn_opts_t *conn_opts) { - opts->deny_ocsp = 1; + conn_opts->deny_ocsp = 1; } -void -opts_unset_deny_ocsp(opts_t *opts) +static void +opts_unset_deny_ocsp(conn_opts_t *conn_opts) { - opts->deny_ocsp = 0; + conn_opts->deny_ocsp = 0; } void -opts_set_passthrough(opts_t *opts) +opts_set_passthrough(conn_opts_t *conn_opts) { - opts->passthrough = 1; + conn_opts->passthrough = 1; } void -opts_unset_passthrough(opts_t *opts) +opts_unset_passthrough(conn_opts_t *conn_opts) { - opts->passthrough = 0; + conn_opts->passthrough = 0; } int -opts_set_clientcrt(opts_t *opts, const char *argv0, const char *optarg, global_tmp_opts_t *global_tmp_opts) +opts_set_clientcrt(conn_opts_t *conn_opts, const char *argv0, const char *optarg, global_tmp_opts_t *global_tmp_opts) { if (global_tmp_opts) { if (global_tmp_opts->clientcrt_str) @@ -1424,10 +1473,10 @@ opts_set_clientcrt(opts_t *opts, const char *argv0, const char *optarg, global_t return oom_return(argv0); } - if (opts->clientcrt) - X509_free(opts->clientcrt); - opts->clientcrt = ssl_x509_load(optarg); - if (!opts->clientcrt) { + if (conn_opts->clientcrt) + X509_free(conn_opts->clientcrt); + conn_opts->clientcrt = ssl_x509_load(optarg); + if (!conn_opts->clientcrt) { fprintf(stderr, "%s: error loading client cert from '%s':\n", argv0, optarg); if (errno) { @@ -1444,7 +1493,7 @@ opts_set_clientcrt(opts_t *opts, const char *argv0, const char *optarg, global_t } int -opts_set_clientkey(opts_t *opts, const char *argv0, const char *optarg, global_tmp_opts_t *global_tmp_opts) +opts_set_clientkey(conn_opts_t *opts, const char *argv0, const char *optarg, global_tmp_opts_t *global_tmp_opts) { if (global_tmp_opts) { if (global_tmp_opts->clientkey_str) @@ -1475,7 +1524,7 @@ opts_set_clientkey(opts_t *opts, const char *argv0, const char *optarg, global_t #ifndef OPENSSL_NO_DH int -opts_set_dh(opts_t *opts, const char *argv0, const char *optarg, global_tmp_opts_t *global_tmp_opts) +opts_set_dh(conn_opts_t *conn_opts, const char *argv0, const char *optarg, global_tmp_opts_t *global_tmp_opts) { if (global_tmp_opts) { if (global_tmp_opts->dh_str) @@ -1485,10 +1534,10 @@ opts_set_dh(opts_t *opts, const char *argv0, const char *optarg, global_tmp_opts return oom_return(argv0); } - if (opts->dh) - DH_free(opts->dh); - opts->dh = ssl_dh_load(optarg); - if (!opts->dh) { + if (conn_opts->dh) + DH_free(conn_opts->dh); + conn_opts->dh = ssl_dh_load(optarg); + if (!conn_opts->dh) { fprintf(stderr, "%s: error loading DH params from '%s':\n", argv0, optarg); if (errno) { @@ -1507,62 +1556,62 @@ opts_set_dh(opts_t *opts, const char *argv0, const char *optarg, global_tmp_opts #ifndef OPENSSL_NO_ECDH int -opts_set_ecdhcurve(opts_t *opts, const char *argv0, const char *optarg) +opts_set_ecdhcurve(conn_opts_t *conn_opts, const char *argv0, const char *optarg) { EC_KEY *ec; - if (opts->ecdhcurve) - free(opts->ecdhcurve); + if (conn_opts->ecdhcurve) + free(conn_opts->ecdhcurve); if (!(ec = ssl_ec_by_name(optarg))) { fprintf(stderr, "%s: unknown curve '%s'\n", argv0, optarg); return -1; } EC_KEY_free(ec); - opts->ecdhcurve = strdup(optarg); - if (!opts->ecdhcurve) + conn_opts->ecdhcurve = strdup(optarg); + if (!conn_opts->ecdhcurve) return oom_return(argv0); #ifdef DEBUG_OPTS - log_dbg_printf("ECDHCurve: %s\n", opts->ecdhcurve); + log_dbg_printf("ECDHCurve: %s\n", conn_opts->ecdhcurve); #endif /* DEBUG_OPTS */ return 0; } #endif /* !OPENSSL_NO_ECDH */ -void -opts_set_sslcomp(opts_t *opts) +static void +opts_set_sslcomp(conn_opts_t *conn_opts) { - opts->sslcomp = 1; + conn_opts->sslcomp = 1; } void -opts_unset_sslcomp(opts_t *opts) +opts_unset_sslcomp(conn_opts_t *conn_opts) { - opts->sslcomp = 0; + conn_opts->sslcomp = 0; } int -opts_set_ciphers(opts_t *opts, const char *argv0, const char *optarg) +opts_set_ciphers(conn_opts_t *conn_opts, const char *argv0, const char *optarg) { - if (opts->ciphers) - free(opts->ciphers); - opts->ciphers = strdup(optarg); - if (!opts->ciphers) + if (conn_opts->ciphers) + free(conn_opts->ciphers); + conn_opts->ciphers = strdup(optarg); + if (!conn_opts->ciphers) return oom_return(argv0); #ifdef DEBUG_OPTS - log_dbg_printf("Ciphers: %s\n", opts->ciphers); + log_dbg_printf("Ciphers: %s\n", conn_opts->ciphers); #endif /* DEBUG_OPTS */ return 0; } int -opts_set_ciphersuites(opts_t *opts, const char *argv0, const char *optarg) +opts_set_ciphersuites(conn_opts_t *conn_opts, const char *argv0, const char *optarg) { - if (opts->ciphersuites) - free(opts->ciphersuites); - opts->ciphersuites = strdup(optarg); - if (!opts->ciphersuites) + if (conn_opts->ciphersuites) + free(conn_opts->ciphersuites); + conn_opts->ciphersuites = strdup(optarg); + if (!conn_opts->ciphersuites) return oom_return(argv0); #ifdef DEBUG_OPTS - log_dbg_printf("CipherSuites: %s\n", opts->ciphersuites); + log_dbg_printf("CipherSuites: %s\n", conn_opts->ciphersuites); #endif /* DEBUG_OPTS */ return 0; } @@ -1571,12 +1620,12 @@ opts_set_ciphersuites(opts_t *opts, const char *argv0, const char *optarg) * Parse SSL proto string in optarg and look up the corresponding SSL method. */ int -opts_force_proto(opts_t *opts, const char *argv0, const char *optarg) +opts_force_proto(conn_opts_t *conn_opts, const char *argv0, const char *optarg) { #if (OPENSSL_VERSION_NUMBER < 0x10100000L) || (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20702000L) - if (opts->sslmethod != SSLv23_method) { + if (conn_opts->sslmethod != SSLv23_method) { #else /* OPENSSL_VERSION_NUMBER >= 0x10100000L */ - if (opts->sslversion) { + if (conn_opts->sslversion) { #endif /* OPENSSL_VERSION_NUMBER >= 0x10100000L */ fprintf(stderr, "%s: cannot use -r multiple times\n", argv0); return -1; @@ -1585,27 +1634,27 @@ opts_force_proto(opts_t *opts, const char *argv0, const char *optarg) #if (OPENSSL_VERSION_NUMBER < 0x10100000L) || (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20702000L) #ifdef HAVE_SSLV2 if (!strcmp(optarg, "ssl2")) { - opts->sslmethod = SSLv2_method; + conn_opts->sslmethod = SSLv2_method; } else #endif /* HAVE_SSLV2 */ #ifdef HAVE_SSLV3 if (!strcmp(optarg, "ssl3")) { - opts->sslmethod = SSLv3_method; + conn_opts->sslmethod = SSLv3_method; } else #endif /* HAVE_SSLV3 */ #ifdef HAVE_TLSV10 if (!strcmp(optarg, "tls10") || !strcmp(optarg, "tls1")) { - opts->sslmethod = TLSv1_method; + conn_opts->sslmethod = TLSv1_method; } else #endif /* HAVE_TLSV10 */ #ifdef HAVE_TLSV11 if (!strcmp(optarg, "tls11")) { - opts->sslmethod = TLSv1_1_method; + conn_opts->sslmethod = TLSv1_1_method; } else #endif /* HAVE_TLSV11 */ #ifdef HAVE_TLSV12 if (!strcmp(optarg, "tls12")) { - opts->sslmethod = TLSv1_2_method; + conn_opts->sslmethod = TLSv1_2_method; } else #endif /* HAVE_TLSV12 */ /* There is no TLSv1_3_method defined, @@ -1618,27 +1667,27 @@ opts_force_proto(opts_t *opts, const char *argv0, const char *optarg) */ #ifdef HAVE_SSLV3 if (!strcmp(optarg, "ssl3")) { - opts->sslversion = SSL3_VERSION; + conn_opts->sslversion = SSL3_VERSION; } else #endif /* HAVE_SSLV3 */ #ifdef HAVE_TLSV10 if (!strcmp(optarg, "tls10") || !strcmp(optarg, "tls1")) { - opts->sslversion = TLS1_VERSION; + conn_opts->sslversion = TLS1_VERSION; } else #endif /* HAVE_TLSV10 */ #ifdef HAVE_TLSV11 if (!strcmp(optarg, "tls11")) { - opts->sslversion = TLS1_1_VERSION; + conn_opts->sslversion = TLS1_1_VERSION; } else #endif /* HAVE_TLSV11 */ #ifdef HAVE_TLSV12 if (!strcmp(optarg, "tls12")) { - opts->sslversion = TLS1_2_VERSION; + conn_opts->sslversion = TLS1_2_VERSION; } else #endif /* HAVE_TLSV12 */ #ifdef HAVE_TLSV13 if (!strcmp(optarg, "tls13")) { - opts->sslversion = TLS1_3_VERSION; + conn_opts->sslversion = TLS1_3_VERSION; } else #endif /* HAVE_TLSV13 */ #endif /* OPENSSL_VERSION_NUMBER >= 0x10100000L */ @@ -1657,36 +1706,36 @@ opts_force_proto(opts_t *opts, const char *argv0, const char *optarg) * Parse SSL proto string in optarg and set the corresponding no_foo bit. */ int -opts_disable_proto(opts_t *opts, const char *argv0, const char *optarg) +opts_disable_proto(conn_opts_t *conn_opts, const char *argv0, const char *optarg) { #ifdef HAVE_SSLV2 if (!strcmp(optarg, "ssl2")) { - opts->no_ssl2 = 1; + conn_opts->no_ssl2 = 1; } else #endif /* HAVE_SSLV2 */ #ifdef HAVE_SSLV3 if (!strcmp(optarg, "ssl3")) { - opts->no_ssl3 = 1; + conn_opts->no_ssl3 = 1; } else #endif /* HAVE_SSLV3 */ #ifdef HAVE_TLSV10 if (!strcmp(optarg, "tls10") || !strcmp(optarg, "tls1")) { - opts->no_tls10 = 1; + conn_opts->no_tls10 = 1; } else #endif /* HAVE_TLSV10 */ #ifdef HAVE_TLSV11 if (!strcmp(optarg, "tls11")) { - opts->no_tls11 = 1; + conn_opts->no_tls11 = 1; } else #endif /* HAVE_TLSV11 */ #ifdef HAVE_TLSV12 if (!strcmp(optarg, "tls12")) { - opts->no_tls12 = 1; + conn_opts->no_tls12 = 1; } else #endif /* HAVE_TLSV12 */ #ifdef HAVE_TLSV13 if (!strcmp(optarg, "tls13")) { - opts->no_tls13 = 1; + conn_opts->no_tls13 = 1; } else #endif /* HAVE_TLSV13 */ { @@ -1701,32 +1750,32 @@ opts_disable_proto(opts_t *opts, const char *argv0, const char *optarg) } static int WUNRES -opts_set_min_proto(UNUSED opts_t *opts, const char *argv0, const char *optarg) +opts_set_min_proto(UNUSED conn_opts_t *conn_opts, const char *argv0, const char *optarg) { #if (OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)) || (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x20702000L) #ifdef HAVE_SSLV3 if (!strcmp(optarg, "ssl3")) { - opts->minsslversion = SSL3_VERSION; + conn_opts->minsslversion = SSL3_VERSION; } else #endif /* HAVE_SSLV3 */ #ifdef HAVE_TLSV10 if (!strcmp(optarg, "tls10") || !strcmp(optarg, "tls1")) { - opts->minsslversion = TLS1_VERSION; + conn_opts->minsslversion = TLS1_VERSION; } else #endif /* HAVE_TLSV10 */ #ifdef HAVE_TLSV11 if (!strcmp(optarg, "tls11")) { - opts->minsslversion = TLS1_1_VERSION; + conn_opts->minsslversion = TLS1_1_VERSION; } else #endif /* HAVE_TLSV11 */ #ifdef HAVE_TLSV12 if (!strcmp(optarg, "tls12")) { - opts->minsslversion = TLS1_2_VERSION; + conn_opts->minsslversion = TLS1_2_VERSION; } else #endif /* HAVE_TLSV12 */ #ifdef HAVE_TLSV13 if (!strcmp(optarg, "tls13")) { - opts->minsslversion = TLS1_3_VERSION; + conn_opts->minsslversion = TLS1_3_VERSION; } else #endif /* HAVE_TLSV13 */ #endif /* OPENSSL_VERSION_NUMBER >= 0x10100000L */ @@ -1742,32 +1791,32 @@ opts_set_min_proto(UNUSED opts_t *opts, const char *argv0, const char *optarg) } static int WUNRES -opts_set_max_proto(UNUSED opts_t *opts, const char *argv0, const char *optarg) +opts_set_max_proto(UNUSED conn_opts_t *conn_opts, const char *argv0, const char *optarg) { #if (OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)) || (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x20702000L) #ifdef HAVE_SSLV3 if (!strcmp(optarg, "ssl3")) { - opts->maxsslversion = SSL3_VERSION; + conn_opts->maxsslversion = SSL3_VERSION; } else #endif /* HAVE_SSLV3 */ #ifdef HAVE_TLSV10 if (!strcmp(optarg, "tls10") || !strcmp(optarg, "tls1")) { - opts->maxsslversion = TLS1_VERSION; + conn_opts->maxsslversion = TLS1_VERSION; } else #endif /* HAVE_TLSV10 */ #ifdef HAVE_TLSV11 if (!strcmp(optarg, "tls11")) { - opts->maxsslversion = TLS1_1_VERSION; + conn_opts->maxsslversion = TLS1_1_VERSION; } else #endif /* HAVE_TLSV11 */ #ifdef HAVE_TLSV12 if (!strcmp(optarg, "tls12")) { - opts->maxsslversion = TLS1_2_VERSION; + conn_opts->maxsslversion = TLS1_2_VERSION; } else #endif /* HAVE_TLSV12 */ #ifdef HAVE_TLSV13 if (!strcmp(optarg, "tls13")) { - opts->maxsslversion = TLS1_3_VERSION; + conn_opts->maxsslversion = TLS1_3_VERSION; } else #endif /* HAVE_TLSV13 */ #endif /* OPENSSL_VERSION_NUMBER >= 0x10100000L */ @@ -1783,80 +1832,80 @@ opts_set_max_proto(UNUSED opts_t *opts, const char *argv0, const char *optarg) } static void -opts_set_remove_http_accept_encoding(opts_t *opts) +opts_set_remove_http_accept_encoding(conn_opts_t *conn_opts) { - opts->remove_http_accept_encoding = 1; + conn_opts->remove_http_accept_encoding = 1; } static void -opts_unset_remove_http_accept_encoding(opts_t *opts) +opts_unset_remove_http_accept_encoding(conn_opts_t *conn_opts) { - opts->remove_http_accept_encoding = 0; + conn_opts->remove_http_accept_encoding = 0; } static void -opts_set_remove_http_referer(opts_t *opts) +opts_set_remove_http_referer(conn_opts_t *conn_opts) { - opts->remove_http_referer = 1; + conn_opts->remove_http_referer = 1; } static void -opts_unset_remove_http_referer(opts_t *opts) +opts_unset_remove_http_referer(conn_opts_t *conn_opts) { - opts->remove_http_referer = 0; + conn_opts->remove_http_referer = 0; } static void -opts_set_verify_peer(opts_t *opts) +opts_set_verify_peer(conn_opts_t *conn_opts) { - opts->verify_peer = 1; + conn_opts->verify_peer = 1; } static void -opts_unset_verify_peer(opts_t *opts) +opts_unset_verify_peer(conn_opts_t *conn_opts) { - opts->verify_peer = 0; + conn_opts->verify_peer = 0; } static void -opts_set_allow_wrong_host(opts_t *opts) +opts_set_allow_wrong_host(conn_opts_t *conn_opts) { - opts->allow_wrong_host = 1; + conn_opts->allow_wrong_host = 1; } static void -opts_unset_allow_wrong_host(opts_t *opts) +opts_unset_allow_wrong_host(conn_opts_t *conn_opts) { - opts->allow_wrong_host = 0; + conn_opts->allow_wrong_host = 0; } #ifndef WITHOUT_USERAUTH static void -opts_set_user_auth(UNUSED opts_t *opts) +opts_set_user_auth(UNUSED conn_opts_t *conn_opts) { #if defined(__OpenBSD__) || defined(__linux__) // Enable user auth on OpenBSD and Linux only - opts->user_auth = 1; + conn_opts->user_auth = 1; #endif /* __OpenBSD__ || __linux__ */ } static void -opts_unset_user_auth(opts_t *opts) +opts_unset_user_auth(conn_opts_t *conn_opts) { - opts->user_auth = 0; + conn_opts->user_auth = 0; } #endif /* !WITHOUT_USERAUTH */ static void -opts_set_validate_proto(opts_t *opts) +opts_set_validate_proto(conn_opts_t *conn_opts) { - opts->validate_proto = 1; + conn_opts->validate_proto = 1; } static void -opts_unset_validate_proto(opts_t *opts) +opts_unset_validate_proto(conn_opts_t *conn_opts) { - opts->validate_proto = 0; + conn_opts->validate_proto = 0; } int @@ -1876,8 +1925,8 @@ global_set_leafkey(global_t *global, const char *argv0, const char *optarg) return -1; } #ifndef OPENSSL_NO_DH - if (!global->opts->dh) { - global->opts->dh = ssl_dh_load(optarg); + if (!global->conn_opts->dh) { + global->conn_opts->dh = ssl_dh_load(optarg); } #endif /* !OPENSSL_NO_DH */ #ifdef DEBUG_OPTS @@ -2415,7 +2464,7 @@ check_value_yesno(const char *value, const char *name, int line_num) * them cloning global opts while creating proxyspecs */ static int -set_option(opts_t *opts, const char *argv0, +set_option(opts_t *opts, conn_opts_t *conn_opts, const char *argv0, const char *name, char *value, char **natengine, int line_num, global_tmp_opts_t *global_tmp_opts) { int yes; @@ -2426,63 +2475,63 @@ set_option(opts_t *opts, const char *argv0, } if (equal(name, "CACert")) { - return opts_set_cacrt(opts, argv0, value, global_tmp_opts); + return opts_set_cacrt(conn_opts, argv0, value, global_tmp_opts); } else if (equal(name, "CAKey")) { - return opts_set_cakey(opts, argv0, value, global_tmp_opts); + return opts_set_cakey(conn_opts, argv0, value, global_tmp_opts); } else if (equal(name, "ClientCert")) { - return opts_set_clientcrt(opts, argv0, value, global_tmp_opts); + return opts_set_clientcrt(conn_opts, argv0, value, global_tmp_opts); } else if (equal(name, "ClientKey")) { - return opts_set_clientkey(opts, argv0, value, global_tmp_opts); + return opts_set_clientkey(conn_opts, argv0, value, global_tmp_opts); } else if (equal(name, "CAChain")) { - return opts_set_chain(opts, argv0, value, global_tmp_opts); + return opts_set_chain(conn_opts, argv0, value, global_tmp_opts); } else if (equal(name, "LeafCRLURL")) { - return opts_set_leafcrlurl(opts, argv0, value, global_tmp_opts); + return opts_set_leafcrlurl(conn_opts, argv0, value, global_tmp_opts); } else if (equal(name, "DenyOCSP")) { yes = check_value_yesno(value, "DenyOCSP", line_num); if (yes == -1) return -1; - yes ? opts_set_deny_ocsp(opts) : opts_unset_deny_ocsp(opts); + yes ? opts_set_deny_ocsp(conn_opts) : opts_unset_deny_ocsp(conn_opts); #ifdef DEBUG_OPTS - log_dbg_printf("DenyOCSP: %u\n", opts->deny_ocsp); + log_dbg_printf("DenyOCSP: %u\n", conn_opts->deny_ocsp); #endif /* DEBUG_OPTS */ } else if (equal(name, "Passthrough")) { yes = check_value_yesno(value, "Passthrough", line_num); if (yes == -1) return -1; - yes ? opts_set_passthrough(opts) : opts_unset_passthrough(opts); + yes ? opts_set_passthrough(conn_opts) : opts_unset_passthrough(conn_opts); #ifdef DEBUG_OPTS - log_dbg_printf("Passthrough: %u\n", opts->passthrough); + log_dbg_printf("Passthrough: %u\n", conn_opts->passthrough); #endif /* DEBUG_OPTS */ #ifndef OPENSSL_NO_DH } else if (equal(name, "DHGroupParams")) { - return opts_set_dh(opts, argv0, value, global_tmp_opts); + return opts_set_dh(conn_opts, argv0, value, global_tmp_opts); #endif /* !OPENSSL_NO_DH */ #ifndef OPENSSL_NO_ECDH } else if (equal(name, "ECDHCurve")) { - return opts_set_ecdhcurve(opts, argv0, value); + return opts_set_ecdhcurve(conn_opts, argv0, value); #endif /* !OPENSSL_NO_ECDH */ #ifdef SSL_OP_NO_COMPRESSION } else if (equal(name, "SSLCompression")) { yes = check_value_yesno(value, "SSLCompression", line_num); if (yes == -1) return -1; - yes ? opts_set_sslcomp(opts) : opts_unset_sslcomp(opts); + yes ? opts_set_sslcomp(conn_opts) : opts_unset_sslcomp(conn_opts); #ifdef DEBUG_OPTS - log_dbg_printf("SSLCompression: %u\n", opts->sslcomp); + log_dbg_printf("SSLCompression: %u\n", conn_opts->sslcomp); #endif /* DEBUG_OPTS */ #endif /* SSL_OP_NO_COMPRESSION */ } else if (equal(name, "ForceSSLProto")) { - return opts_force_proto(opts, argv0, value); + return opts_force_proto(conn_opts, argv0, value); } else if (equal(name, "DisableSSLProto")) { - return opts_disable_proto(opts, argv0, value); + return opts_disable_proto(conn_opts, argv0, value); } else if (equal(name, "MinSSLProto")) { - return opts_set_min_proto(opts, argv0, value); + return opts_set_min_proto(conn_opts, argv0, value); } else if (equal(name, "MaxSSLProto")) { - return opts_set_max_proto(opts, argv0, value); + return opts_set_max_proto(conn_opts, argv0, value); } else if (equal(name, "Ciphers")) { - return opts_set_ciphers(opts, argv0, value); + return opts_set_ciphers(conn_opts, argv0, value); } else if (equal(name, "CipherSuites")) { - return opts_set_ciphersuites(opts, argv0, value); + return opts_set_ciphersuites(conn_opts, argv0, value); } else if (equal(name, "NATEngine")) { if (*natengine) free(*natengine); @@ -2497,22 +2546,22 @@ set_option(opts_t *opts, const char *argv0, yes = check_value_yesno(value, "UserAuth", line_num); if (yes == -1) return -1; - yes ? opts_set_user_auth(opts) : opts_unset_user_auth(opts); + yes ? opts_set_user_auth(conn_opts) : opts_unset_user_auth(conn_opts); #ifdef DEBUG_OPTS - log_dbg_printf("UserAuth: %u\n", opts->user_auth); + log_dbg_printf("UserAuth: %u\n", conn_opts->user_auth); #endif /* DEBUG_OPTS */ } else if (equal(name, "UserAuthURL")) { - return opts_set_user_auth_url(opts, argv0, value); + return opts_set_user_auth_url(conn_opts, argv0, value); } else if (equal(name, "UserTimeout")) { unsigned int i = atoi(value); if (i <= 86400) { - opts->user_timeout = i; + conn_opts->user_timeout = i; } else { fprintf(stderr, "Invalid UserTimeout %s on line %d, use 0-86400\n", value, line_num); return -1; } #ifdef DEBUG_OPTS - log_dbg_printf("UserTimeout: %u\n", opts->user_timeout); + log_dbg_printf("UserTimeout: %u\n", conn_opts->user_timeout); #endif /* DEBUG_OPTS */ } else if (equal(name, "DivertUsers")) { return filter_userlist_set(value, line_num, &opts->divertusers, "DivertUsers"); @@ -2523,63 +2572,63 @@ set_option(opts_t *opts, const char *argv0, yes = check_value_yesno(value, "ValidateProto", line_num); if (yes == -1) return -1; - yes ? opts_set_validate_proto(opts) : opts_unset_validate_proto(opts); + yes ? opts_set_validate_proto(conn_opts) : opts_unset_validate_proto(conn_opts); #ifdef DEBUG_OPTS - log_dbg_printf("ValidateProto: %u\n", opts->validate_proto); + log_dbg_printf("ValidateProto: %u\n", conn_opts->validate_proto); #endif /* DEBUG_OPTS */ } else if (equal(name, "MaxHTTPHeaderSize")) { unsigned int i = atoi(value); if (i >= 1024 && i <= 65536) { - opts->max_http_header_size = i; + conn_opts->max_http_header_size = i; } else { fprintf(stderr, "Invalid MaxHTTPHeaderSize %s on line %d, use 1024-65536\n", value, line_num); return -1; } #ifdef DEBUG_OPTS - log_dbg_printf("MaxHTTPHeaderSize: %u\n", opts->max_http_header_size); + log_dbg_printf("MaxHTTPHeaderSize: %u\n", conn_opts->max_http_header_size); #endif /* DEBUG_OPTS */ } else if (equal(name, "VerifyPeer")) { yes = check_value_yesno(value, "VerifyPeer", line_num); if (yes == -1) return -1; - yes ? opts_set_verify_peer(opts) : opts_unset_verify_peer(opts); + yes ? opts_set_verify_peer(conn_opts) : opts_unset_verify_peer(conn_opts); #ifdef DEBUG_OPTS - log_dbg_printf("VerifyPeer: %u\n", opts->verify_peer); + log_dbg_printf("VerifyPeer: %u\n", conn_opts->verify_peer); #endif /* DEBUG_OPTS */ } else if (equal(name, "AllowWrongHost")) { yes = check_value_yesno(value, "AllowWrongHost", line_num); if (yes == -1) return -1; - yes ? opts_set_allow_wrong_host(opts) : opts_unset_allow_wrong_host(opts); + yes ? opts_set_allow_wrong_host(conn_opts) : opts_unset_allow_wrong_host(conn_opts); #ifdef DEBUG_OPTS - log_dbg_printf("AllowWrongHost: %u\n", opts->allow_wrong_host); + log_dbg_printf("AllowWrongHost: %u\n", conn_opts->allow_wrong_host); #endif /* DEBUG_OPTS */ } else if (equal(name, "RemoveHTTPAcceptEncoding")) { yes = check_value_yesno(value, "RemoveHTTPAcceptEncoding", line_num); if (yes == -1) return -1; - yes ? opts_set_remove_http_accept_encoding(opts) : opts_unset_remove_http_accept_encoding(opts); + yes ? opts_set_remove_http_accept_encoding(conn_opts) : opts_unset_remove_http_accept_encoding(conn_opts); #ifdef DEBUG_OPTS - log_dbg_printf("RemoveHTTPAcceptEncoding: %u\n", opts->remove_http_accept_encoding); + log_dbg_printf("RemoveHTTPAcceptEncoding: %u\n", conn_opts->remove_http_accept_encoding); #endif /* DEBUG_OPTS */ } else if (equal(name, "RemoveHTTPReferer")) { yes = check_value_yesno(value, "RemoveHTTPReferer", line_num); if (yes == -1) return -1; - yes ? opts_set_remove_http_referer(opts) : opts_unset_remove_http_referer(opts); + yes ? opts_set_remove_http_referer(conn_opts) : opts_unset_remove_http_referer(conn_opts); #ifdef DEBUG_OPTS - log_dbg_printf("RemoveHTTPReferer: %u\n", opts->remove_http_referer); + log_dbg_printf("RemoveHTTPReferer: %u\n", conn_opts->remove_http_referer); #endif /* DEBUG_OPTS */ } else if (equal(name, "PassSite")) { - return filter_passsite_set(opts, value, line_num); + return filter_passsite_set(opts, conn_opts->user_auth, value, line_num); } else if (equal(name, "Define")) { return filter_macro_set(opts, value, line_num); } else if (equal(name, "Split") || equal(name, "Pass") || equal(name, "Block") || equal(name, "Match")) { - return filter_rule_set(opts, name, value, line_num); + return filter_rule_set(opts, conn_opts->user_auth, name, value, line_num); } else if (equal(name, "Divert")) { yes = is_yesno(value); if (yes == -1) - return filter_rule_set(opts, name, value, line_num); + return filter_rule_set(opts, conn_opts->user_auth, name, value, line_num); else yes ? opts_set_divert(opts) : opts_unset_divert(opts); } else { @@ -2670,7 +2719,7 @@ set_proxyspec_option(proxyspec_t *spec, const char *argv0, return 2; } else { - return set_option(spec->opts, argv0, name, value, natengine, line_num, NULL); + return set_option(spec->opts, spec->conn_opts, argv0, name, value, natengine, line_num, NULL); } return 0; } @@ -3048,7 +3097,7 @@ set_global_option(global_t *global, const char *argv0, } return retval; } else { - return set_option(global->opts, argv0, name, value, natengine, *line_num, global_tmp_opts); + return set_option(global->opts, global->conn_opts, argv0, name, value, natengine, *line_num, global_tmp_opts); } return 0; } diff --git a/src/opts.h b/src/opts.h index 3388e58..95f80a2 100644 --- a/src/opts.h +++ b/src/opts.h @@ -81,11 +81,7 @@ typedef struct userlist { typedef struct global global_t; -typedef struct opts { - // Set to 1 to divert to lp, set to 0 for split mode - // Defaults to 1 - unsigned int divert : 1; - +typedef struct conn_opts { unsigned int sslcomp : 1; #ifdef HAVE_SSLV2 unsigned int no_ssl2 : 1; @@ -135,11 +131,21 @@ typedef struct opts { unsigned int user_auth: 1; char *user_auth_url; unsigned int user_timeout; - userlist_t *divertusers; - userlist_t *passusers; #endif /* !WITHOUT_USERAUTH */ unsigned int validate_proto : 1; unsigned int max_http_header_size; +} conn_opts_t; + +typedef struct opts { + // Set to 1 to divert to lp, set to 0 for split mode + // Defaults to 1 + unsigned int divert : 1; + +#ifndef WITHOUT_USERAUTH + userlist_t *divertusers; + userlist_t *passusers; +#endif /* !WITHOUT_USERAUTH */ + // Used to store filter rules and to create filter // Freed during startup after filter is created and debug printed struct filter_rule *filter_rules; @@ -176,6 +182,7 @@ typedef struct proxyspec { // Each proxyspec has its own opts opts_t *opts; + conn_opts_t *conn_opts; } proxyspec_t; // Temporary global options @@ -237,6 +244,8 @@ struct global { sqlite3 *userdb; struct sqlite3_stmt *update_user_atime; #endif /* !WITHOUT_USERAUTH */ + + conn_opts_t *conn_opts; proxyspec_t *spec; opts_t *opts; @@ -279,26 +288,26 @@ char *proxyspec_str(proxyspec_t *) NONNULL(1) MALLOC WUNRES; opts_t *opts_new(void) MALLOC WUNRES; void opts_free(opts_t *) NONNULL(1); -char *opts_proto_dbg_dump(opts_t *) NONNULL(1); -int opts_set_cacrt(opts_t *, const char *, const char *, global_tmp_opts_t *) NONNULL(1,2,3) WUNRES; -int opts_set_cakey(opts_t *, const char *, const char *, global_tmp_opts_t *) NONNULL(1,2,3) WUNRES; -int opts_set_chain(opts_t *, const char *, const char *, global_tmp_opts_t *) NONNULL(1,2,3) WUNRES; -int opts_set_leafcrlurl(opts_t *, const char *, const char *, global_tmp_opts_t *) NONNULL(1,2,3) WUNRES; -void opts_set_deny_ocsp(opts_t *) NONNULL(1); -void opts_set_passthrough(opts_t *) NONNULL(1); -int opts_set_clientcrt(opts_t *, const char *, const char *, global_tmp_opts_t *) NONNULL(1,2,3) WUNRES; -int opts_set_clientkey(opts_t *, const char *, const char *, global_tmp_opts_t *) NONNULL(1,2,3) WUNRES; +char *opts_proto_dbg_dump(conn_opts_t *) NONNULL(1); +int opts_set_cacrt(conn_opts_t *, const char *, const char *, global_tmp_opts_t *) NONNULL(1,2,3) WUNRES; +int opts_set_cakey(conn_opts_t *, const char *, const char *, global_tmp_opts_t *) NONNULL(1,2,3) WUNRES; +int opts_set_chain(conn_opts_t *, const char *, const char *, global_tmp_opts_t *) NONNULL(1,2,3) WUNRES; +int opts_set_leafcrlurl(conn_opts_t *, const char *, const char *, global_tmp_opts_t *) NONNULL(1,2,3) WUNRES; +void opts_set_deny_ocsp(conn_opts_t *) NONNULL(1); +void opts_set_passthrough(conn_opts_t *) NONNULL(1); +int opts_set_clientcrt(conn_opts_t *, const char *, const char *, global_tmp_opts_t *) NONNULL(1,2,3) WUNRES; +int opts_set_clientkey(conn_opts_t *, const char *, const char *, global_tmp_opts_t *) NONNULL(1,2,3) WUNRES; #ifndef OPENSSL_NO_DH -int opts_set_dh(opts_t *, const char *, const char *, global_tmp_opts_t *) NONNULL(1,2,3) WUNRES; +int opts_set_dh(conn_opts_t *, const char *, const char *, global_tmp_opts_t *) NONNULL(1,2,3) WUNRES; #endif /* !OPENSSL_NO_DH */ #ifndef OPENSSL_NO_ECDH -int opts_set_ecdhcurve(opts_t *, const char *, const char *) NONNULL(1,2,3) WUNRES; +int opts_set_ecdhcurve(conn_opts_t *, const char *, const char *) NONNULL(1,2,3) WUNRES; #endif /* !OPENSSL_NO_ECDH */ -void opts_unset_sslcomp(opts_t *) NONNULL(1); -int opts_force_proto(opts_t *, const char *, const char *) NONNULL(1,2,3) WUNRES; -int opts_disable_proto(opts_t *, const char *, const char *) NONNULL(1,2,3) WUNRES; -int opts_set_ciphers(opts_t *, const char *, const char *) NONNULL(1,2,3) WUNRES; -int opts_set_ciphersuites(opts_t *, const char *, const char *) NONNULL(1,2,3) WUNRES; +void opts_unset_sslcomp(conn_opts_t *) NONNULL(1); +int opts_force_proto(conn_opts_t *, const char *, const char *) NONNULL(1,2,3) WUNRES; +int opts_disable_proto(conn_opts_t *, const char *, const char *) NONNULL(1,2,3) WUNRES; +int opts_set_ciphers(conn_opts_t *, const char *, const char *) NONNULL(1,2,3) WUNRES; +int opts_set_ciphersuites(conn_opts_t *, const char *, const char *) NONNULL(1,2,3) WUNRES; #define OPTS_DEBUG(global) unlikely((global)->debug) diff --git a/src/protohttp.c b/src/protohttp.c index 40ae9ad..82a1b71 100644 --- a/src/protohttp.c +++ b/src/protohttp.c @@ -349,10 +349,10 @@ protohttp_filter_request_header_line(const char *line, protohttp_ctx_t *http_ctx http_ctx->seen_keyword_count++; return newhdr; // @attention Always use conn ctx for opts, child ctx does not have opts, see the comments in pxy_conn_child_ctx - } else if (ctx->spec->opts->remove_http_accept_encoding && !strncasecmp(line, "Accept-Encoding:", 16)) { + } else if (ctx->conn_opts->remove_http_accept_encoding && !strncasecmp(line, "Accept-Encoding:", 16)) { http_ctx->seen_keyword_count++; return NULL; - } else if (ctx->spec->opts->remove_http_referer && !strncasecmp(line, "Referer:", 8)) { + } else if (ctx->conn_opts->remove_http_referer && !strncasecmp(line, "Referer:", 8)) { http_ctx->seen_keyword_count++; return NULL; /* Suppress upgrading to SSL/TLS, WebSockets or HTTP/2 and keep-alive */ @@ -630,7 +630,7 @@ protohttp_filter_request_header(struct evbuffer *inbuf, struct evbuffer *outbuf, } /* request header complete */ - if (ctx->spec->opts->deny_ocsp) { + if (ctx->conn_opts->deny_ocsp) { protohttp_ocsp_deny(ctx, http_ctx); } } @@ -764,7 +764,7 @@ protohttp_validate(pxy_conn_ctx_t *ctx) log_finest("Passed validation"); return 0; } - if (http_ctx->seen_bytes > ctx->spec->opts->max_http_header_size) { + if (http_ctx->seen_bytes > ctx->conn_opts->max_http_header_size) { // Fail validation if still cannot pass as http after reaching max header size http_ctx->not_valid = 1; log_finest_va("Reached max header size, size=%llu", http_ctx->seen_bytes); @@ -805,22 +805,22 @@ protohttp_bev_readcb_src(struct bufferevent *bev, pxy_conn_ctx_t *ctx) struct evbuffer *outbuf = bufferevent_get_output(ctx->dst.bev); #ifndef WITHOUT_USERAUTH - if (ctx->spec->opts->user_auth && !ctx->user) { + if (ctx->conn_opts->user_auth && !ctx->user) { log_finest("Redirecting conn"); char *url = protohttp_get_url(inbuf, ctx); pxy_discard_inbuf(bev); if (url) { - evbuffer_add_printf(bufferevent_get_output(bev), redirect_url, ctx->spec->opts->user_auth_url, url); + evbuffer_add_printf(bufferevent_get_output(bev), redirect_url, ctx->conn_opts->user_auth_url, url); free(url); } else { - evbuffer_add_printf(bufferevent_get_output(bev), redirect, ctx->spec->opts->user_auth_url); + evbuffer_add_printf(bufferevent_get_output(bev), redirect, ctx->conn_opts->user_auth_url); } ctx->sent_userauth_msg = 1; return; } #endif /* !WITHOUT_USERAUTH */ - if (ctx->spec->opts->validate_proto && !ctx->protoctx->is_valid) { + if (ctx->conn_opts->validate_proto && !ctx->protoctx->is_valid) { http_ctx->seen_bytes += evbuffer_get_length(inbuf); } @@ -843,7 +843,7 @@ protohttp_bev_readcb_src(struct bufferevent *bev, pxy_conn_ctx_t *ctx) evbuffer_add_buffer(outbuf, inbuf); } - if (ctx->spec->opts->validate_proto && !ctx->protoctx->is_valid) { + if (ctx->conn_opts->validate_proto && !ctx->protoctx->is_valid) { if (protohttp_validate(ctx) == -1) { evbuffer_add(bufferevent_get_output(bev), proto_error, strlen(proto_error)); ctx->sent_protoerror_msg = 1; diff --git a/src/protosmtp.c b/src/protosmtp.c index 0b85ecc..a4068f5 100644 --- a/src/protosmtp.c +++ b/src/protosmtp.c @@ -118,7 +118,7 @@ protosmtp_validate_response(pxy_conn_ctx_t *ctx, char *packet, size_t packet_siz static int NONNULL(1,2,3,4) protosmtp_try_validate_response(struct bufferevent *bev, pxy_conn_ctx_t *ctx, struct evbuffer *inbuf, struct evbuffer *outbuf) { - if (ctx->spec->opts->validate_proto) { + if (ctx->conn_opts->validate_proto) { size_t packet_size = evbuffer_get_length(inbuf); char *packet = (char *)pxy_malloc_packet(packet_size, ctx); if (!packet) { diff --git a/src/protossl.c b/src/protossl.c index 5c724b6..16c1074 100644 --- a/src/protossl.c +++ b/src/protossl.c @@ -287,7 +287,7 @@ protossl_sslctx_setoptions(SSL_CTX *sslctx, pxy_conn_ctx_t *ctx) #ifdef SSL_OP_NO_SSLv2 #ifdef HAVE_SSLV2 - if (ctx->spec->opts->no_ssl2) { + if (ctx->conn_opts->no_ssl2) { #endif /* HAVE_SSLV2 */ SSL_CTX_set_options(sslctx, SSL_OP_NO_SSLv2); #ifdef HAVE_SSLV2 @@ -295,40 +295,40 @@ protossl_sslctx_setoptions(SSL_CTX *sslctx, pxy_conn_ctx_t *ctx) #endif /* HAVE_SSLV2 */ #endif /* !SSL_OP_NO_SSLv2 */ #ifdef HAVE_SSLV3 - if (ctx->spec->opts->no_ssl3) { + if (ctx->conn_opts->no_ssl3) { SSL_CTX_set_options(sslctx, SSL_OP_NO_SSLv3); } #endif /* HAVE_SSLV3 */ #ifdef HAVE_TLSV10 - if (ctx->spec->opts->no_tls10) { + if (ctx->conn_opts->no_tls10) { SSL_CTX_set_options(sslctx, SSL_OP_NO_TLSv1); } #endif /* HAVE_TLSV10 */ #ifdef HAVE_TLSV11 - if (ctx->spec->opts->no_tls11) { + if (ctx->conn_opts->no_tls11) { SSL_CTX_set_options(sslctx, SSL_OP_NO_TLSv1_1); } #endif /* HAVE_TLSV11 */ #ifdef HAVE_TLSV12 - if (ctx->spec->opts->no_tls12) { + if (ctx->conn_opts->no_tls12) { SSL_CTX_set_options(sslctx, SSL_OP_NO_TLSv1_2); } #endif /* HAVE_TLSV12 */ #ifdef HAVE_TLSV13 - if (ctx->spec->opts->no_tls13) { + if (ctx->conn_opts->no_tls13) { SSL_CTX_set_options(sslctx, SSL_OP_NO_TLSv1_3); } #endif /* HAVE_TLSV13 */ #ifdef SSL_OP_NO_COMPRESSION - if (!ctx->spec->opts->sslcomp) { + if (!ctx->conn_opts->sslcomp) { SSL_CTX_set_options(sslctx, SSL_OP_NO_COMPRESSION); } #endif /* SSL_OP_NO_COMPRESSION */ - SSL_CTX_set_cipher_list(sslctx, ctx->spec->opts->ciphers); + SSL_CTX_set_cipher_list(sslctx, ctx->conn_opts->ciphers); #ifdef HAVE_TLSV13 - SSL_CTX_set_ciphersuites(sslctx, ctx->spec->opts->ciphersuites); + SSL_CTX_set_ciphersuites(sslctx, ctx->conn_opts->ciphersuites); #endif /* HAVE_TLSV13 */ #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER) @@ -346,7 +346,7 @@ static SSL_CTX * protossl_srcsslctx_create(pxy_conn_ctx_t *ctx, X509 *crt, STACK_OF(X509) *chain, EVP_PKEY *key) { - SSL_CTX *sslctx = SSL_CTX_new(ctx->spec->opts->sslmethod()); + SSL_CTX *sslctx = SSL_CTX_new(ctx->conn_opts->sslmethod()); if (!sslctx) { ctx->enomem = 1; return NULL; @@ -355,22 +355,22 @@ protossl_srcsslctx_create(pxy_conn_ctx_t *ctx, X509 *crt, STACK_OF(X509) *chain, protossl_sslctx_setoptions(sslctx, ctx); #if (OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)) || (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x20702000L) - if (ctx->spec->opts->minsslversion) { - if (SSL_CTX_set_min_proto_version(sslctx, ctx->spec->opts->minsslversion) == 0) { + if (ctx->conn_opts->minsslversion) { + if (SSL_CTX_set_min_proto_version(sslctx, ctx->conn_opts->minsslversion) == 0) { SSL_CTX_free(sslctx); return NULL; } } - if (ctx->spec->opts->maxsslversion) { - if (SSL_CTX_set_max_proto_version(sslctx, ctx->spec->opts->maxsslversion) == 0) { + if (ctx->conn_opts->maxsslversion) { + if (SSL_CTX_set_max_proto_version(sslctx, ctx->conn_opts->maxsslversion) == 0) { SSL_CTX_free(sslctx); return NULL; } } // ForceSSLproto has precedence - if (ctx->spec->opts->sslversion) { - if (SSL_CTX_set_min_proto_version(sslctx, ctx->spec->opts->sslversion) == 0 || - SSL_CTX_set_max_proto_version(sslctx, ctx->spec->opts->sslversion) == 0) { + if (ctx->conn_opts->sslversion) { + if (SSL_CTX_set_min_proto_version(sslctx, ctx->conn_opts->sslversion) == 0 || + SSL_CTX_set_max_proto_version(sslctx, ctx->conn_opts->sslversion) == 0) { SSL_CTX_free(sslctx); return NULL; } @@ -391,15 +391,15 @@ protossl_srcsslctx_create(pxy_conn_ctx_t *ctx, X509 *crt, STACK_OF(X509) *chain, SSL_CTX_set_tlsext_servername_arg(sslctx, ctx); #endif /* !OPENSSL_NO_TLSEXT */ #ifndef OPENSSL_NO_DH - if (ctx->spec->opts->dh) { - SSL_CTX_set_tmp_dh(sslctx, ctx->spec->opts->dh); + if (ctx->conn_opts->dh) { + SSL_CTX_set_tmp_dh(sslctx, ctx->conn_opts->dh); } else { SSL_CTX_set_tmp_dh_callback(sslctx, ssl_tmp_dh_callback); } #endif /* !OPENSSL_NO_DH */ #ifndef OPENSSL_NO_ECDH - if (ctx->spec->opts->ecdhcurve) { - EC_KEY *ecdh = ssl_ec_by_name(ctx->spec->opts->ecdhcurve); + if (ctx->conn_opts->ecdhcurve) { + EC_KEY *ecdh = ssl_ec_by_name(ctx->conn_opts->ecdhcurve); SSL_CTX_set_tmp_ecdh(sslctx, ecdh); EC_KEY_free(ecdh); } else { @@ -562,16 +562,16 @@ protossl_srccert_create(pxy_conn_ctx_t *ctx) } else { if (OPTS_DEBUG(ctx->global)) log_dbg_printf("Certificate cache: MISS\n"); - cert->crt = ssl_x509_forge(ctx->spec->opts->cacrt, - ctx->spec->opts->cakey, + cert->crt = ssl_x509_forge(ctx->conn_opts->cacrt, + ctx->conn_opts->cakey, ctx->sslctx->origcrt, ctx->global->leafkey, NULL, - ctx->spec->opts->leafcrlurl); + ctx->conn_opts->leafcrlurl); cachemgr_fkcrt_set(ctx->sslctx->origcrt, cert->crt); } cert_set_key(cert, ctx->global->leafkey); - cert_set_chain(cert, ctx->spec->opts->chain); + cert_set_chain(cert, ctx->conn_opts->chain); ctx->sslctx->generated_cert = 1; } @@ -940,7 +940,7 @@ protossl_ossl_servername_cb(SSL *ssl, UNUSED int *al, void *arg) /* generate a new certificate with sn as additional altSubjectName * and replace it both in the current SSL ctx and in the cert cache */ - if (ctx->spec->opts->allow_wrong_host && !ctx->sslctx->immutable_cert && + if (ctx->conn_opts->allow_wrong_host && !ctx->sslctx->immutable_cert && !ssl_x509_names_match((sslcrt = SSL_get_certificate(ssl)), sn)) { X509 *newcrt; SSL_CTX *newsslctx; @@ -949,9 +949,9 @@ protossl_ossl_servername_cb(SSL *ssl, UNUSED int *al, void *arg) log_dbg_printf("Certificate cache: UPDATE " "(SNI mismatch)\n"); } - newcrt = ssl_x509_forge(ctx->spec->opts->cacrt, ctx->spec->opts->cakey, + newcrt = ssl_x509_forge(ctx->conn_opts->cacrt, ctx->conn_opts->cakey, sslcrt, ctx->global->leafkey, - sn, ctx->spec->opts->leafcrlurl); + sn, ctx->conn_opts->leafcrlurl); if (!newcrt) { ctx->enomem = 1; return SSL_TLSEXT_ERR_NOACK; @@ -982,7 +982,7 @@ protossl_ossl_servername_cb(SSL *ssl, UNUSED int *al, void *arg) } } - newsslctx = protossl_srcsslctx_create(ctx, newcrt, ctx->spec->opts->chain, + newsslctx = protossl_srcsslctx_create(ctx, newcrt, ctx->conn_opts->chain, ctx->global->leafkey); if (!newsslctx) { X509_free(newcrt); @@ -1011,7 +1011,7 @@ protossl_dstssl_create(pxy_conn_ctx_t *ctx) SSL *ssl; SSL_SESSION *sess; - sslctx = SSL_CTX_new(ctx->spec->opts->sslmethod()); + sslctx = SSL_CTX_new(ctx->conn_opts->sslmethod()); if (!sslctx) { ctx->enomem = 1; return NULL; @@ -1020,43 +1020,43 @@ protossl_dstssl_create(pxy_conn_ctx_t *ctx) protossl_sslctx_setoptions(sslctx, ctx); #if (OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)) || (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x20702000L) - if (ctx->spec->opts->minsslversion) { - if (SSL_CTX_set_min_proto_version(sslctx, ctx->spec->opts->minsslversion) == 0) { + if (ctx->conn_opts->minsslversion) { + if (SSL_CTX_set_min_proto_version(sslctx, ctx->conn_opts->minsslversion) == 0) { SSL_CTX_free(sslctx); return NULL; } } - if (ctx->spec->opts->maxsslversion) { - if (SSL_CTX_set_max_proto_version(sslctx, ctx->spec->opts->maxsslversion) == 0) { + if (ctx->conn_opts->maxsslversion) { + if (SSL_CTX_set_max_proto_version(sslctx, ctx->conn_opts->maxsslversion) == 0) { SSL_CTX_free(sslctx); return NULL; } } // ForceSSLproto has precedence - if (ctx->spec->opts->sslversion) { - if (SSL_CTX_set_min_proto_version(sslctx, ctx->spec->opts->sslversion) == 0 || - SSL_CTX_set_max_proto_version(sslctx, ctx->spec->opts->sslversion) == 0) { + if (ctx->conn_opts->sslversion) { + if (SSL_CTX_set_min_proto_version(sslctx, ctx->conn_opts->sslversion) == 0 || + SSL_CTX_set_max_proto_version(sslctx, ctx->conn_opts->sslversion) == 0) { SSL_CTX_free(sslctx); return NULL; } } #endif /* OPENSSL_VERSION_NUMBER >= 0x10100000L */ - if (ctx->spec->opts->verify_peer) { + if (ctx->conn_opts->verify_peer) { SSL_CTX_set_verify(sslctx, SSL_VERIFY_PEER, NULL); SSL_CTX_set_default_verify_paths(sslctx); } else { SSL_CTX_set_verify(sslctx, SSL_VERIFY_NONE, NULL); } - if (ctx->spec->opts->clientcrt && - (SSL_CTX_use_certificate(sslctx, ctx->spec->opts->clientcrt) != 1)) { + if (ctx->conn_opts->clientcrt && + (SSL_CTX_use_certificate(sslctx, ctx->conn_opts->clientcrt) != 1)) { log_dbg_printf("loading dst client certificate failed\n"); SSL_CTX_free(sslctx); return NULL; } - if (ctx->spec->opts->clientkey && - (SSL_CTX_use_PrivateKey(sslctx, ctx->spec->opts->clientkey) != 1)) { + if (ctx->conn_opts->clientkey && + (SSL_CTX_use_PrivateKey(sslctx, ctx->conn_opts->clientkey) != 1)) { log_dbg_printf("loading dst client key failed\n"); SSL_CTX_free(sslctx); return NULL; @@ -1527,7 +1527,7 @@ protossl_setup_src_ssl(pxy_conn_ctx_t *ctx) else if (ctx->term) { return -1; } - else if (!ctx->enomem && (ctx->pass || ctx->spec->opts->passthrough)) { + else if (!ctx->enomem && (ctx->pass || ctx->conn_opts->passthrough)) { log_err_level_printf(LOG_WARNING, "Falling back to passthrough\n"); protopassthrough_engage(ctx); // report protocol change by returning 1 @@ -1719,7 +1719,7 @@ protossl_bev_eventcb_error_srvdst(UNUSED struct bufferevent *bev, pxy_conn_ctx_t /* the callout to the original destination failed, * e.g. because it asked for client cert auth, so * close the accepted socket and clean up */ - if (((ctx->spec->opts->passthrough && ctx->sslctx->have_sslerr) || (ctx->pass && !ctx->sslctx->have_sslerr))) { + if (((ctx->conn_opts->passthrough && ctx->sslctx->have_sslerr) || (ctx->pass && !ctx->sslctx->have_sslerr))) { /* ssl callout failed, fall back to plain TCP passthrough of SSL connection */ log_err_level_printf(LOG_WARNING, "SSL srvdst connection failed; falling back to passthrough\n"); ctx->sslctx->have_sslerr = 0; diff --git a/src/prototcp.c b/src/prototcp.c index 4416187..f9eed1d 100644 --- a/src/prototcp.c +++ b/src/prototcp.c @@ -226,10 +226,10 @@ prototcp_init_conn(UNUSED evutil_socket_t fd, UNUSED short what, void *arg) int prototcp_try_send_userauth_msg(struct bufferevent *bev, pxy_conn_ctx_t *ctx) { - if (ctx->spec->opts->user_auth && !ctx->user) { + if (ctx->conn_opts->user_auth && !ctx->user) { log_finest("Sending userauth message"); pxy_discard_inbuf(bev); - evbuffer_add_printf(bufferevent_get_output(bev), USERAUTH_MSG, ctx->spec->opts->user_auth_url); + evbuffer_add_printf(bufferevent_get_output(bev), USERAUTH_MSG, ctx->conn_opts->user_auth_url); ctx->sent_userauth_msg = 1; return 1; } @@ -240,7 +240,7 @@ prototcp_try_send_userauth_msg(struct bufferevent *bev, pxy_conn_ctx_t *ctx) static int NONNULL(1,2,3,4) prototcp_try_validate_proto(struct bufferevent *bev, pxy_conn_ctx_t *ctx, struct evbuffer *inbuf, struct evbuffer *outbuf) { - if (ctx->spec->opts->validate_proto && ctx->protoctx->validatecb && !ctx->protoctx->is_valid) { + if (ctx->conn_opts->validate_proto && ctx->protoctx->validatecb && !ctx->protoctx->is_valid) { size_t packet_size = evbuffer_get_length(inbuf); char *packet = (char *)pxy_malloc_packet(packet_size, ctx); if (!packet) { @@ -371,7 +371,7 @@ prototcp_bev_readcb_dst_child(struct bufferevent *bev, pxy_conn_child_ctx_t *ctx int prototcp_try_close_unauth_conn(struct bufferevent *bev, pxy_conn_ctx_t *ctx) { - if (ctx->spec->opts->user_auth && !ctx->user) { + if (ctx->conn_opts->user_auth && !ctx->user) { size_t outbuflen = evbuffer_get_length(bufferevent_get_output(bev)); if (outbuflen > 0) { log_finest_va("Not closing unauth conn, outbuflen=%zu", outbuflen); @@ -390,7 +390,7 @@ prototcp_try_close_unauth_conn(struct bufferevent *bev, pxy_conn_ctx_t *ctx) int prototcp_try_close_protoerror_conn(struct bufferevent *bev, pxy_conn_ctx_t *ctx) { - if (ctx->spec->opts->validate_proto && ctx->sent_protoerror_msg) { + if (ctx->conn_opts->validate_proto && ctx->sent_protoerror_msg) { size_t outbuflen = evbuffer_get_length(bufferevent_get_output(bev)); if (outbuflen > 0) { log_finest_va("Not closing protoerror conn, outbuflen=%zu", outbuflen); diff --git a/src/proxy.c b/src/proxy.c index 690a059..e3e4dcd 100644 --- a/src/proxy.c +++ b/src/proxy.c @@ -170,6 +170,7 @@ proxy_conn_ctx_new(evutil_socket_t fd, ctx->fd = fd; ctx->thrmgr = thrmgr; ctx->spec = spec; + ctx->conn_opts = spec->conn_opts; ctx->divert = spec->opts->divert; // Enable all logging for conn if proxyspec does not have any filter diff --git a/src/pxyconn.c b/src/pxyconn.c index 90b8058..8ca57b0 100644 --- a/src/pxyconn.c +++ b/src/pxyconn.c @@ -328,10 +328,10 @@ pxy_conn_ctx_free(pxy_conn_ctx_t *ctx, int by_requestor) } #ifndef WITHOUT_USERAUTH - if (ctx->spec->opts->user_auth && ctx->srchost_str && ctx->user && ctx->ether) { + if (ctx->conn_opts->user_auth && ctx->srchost_str && ctx->user && ctx->ether) { // Update userdb atime if idle time is more than 50% of user timeout, which is expected to reduce update frequency unsigned int idletime = ctx->idletime + (time(NULL) - ctx->ctime); - if (idletime > (ctx->spec->opts->user_timeout / 2)) { + if (idletime > (ctx->conn_opts->user_timeout / 2)) { userdbkeys_t keys; // Zero out for NULL termination memset(&keys, 0, sizeof(userdbkeys_t)); @@ -1270,7 +1270,7 @@ pxy_setup_child_listener(pxy_conn_ctx_t *ctx) #ifndef WITHOUT_USERAUTH int user_len = 0; - if (ctx->spec->opts->user_auth && ctx->user) { + if (ctx->conn_opts->user_auth && ctx->user) { // +1 for comma user_len = strlen(ctx->user) + 1; } @@ -1773,7 +1773,7 @@ identify_user(UNUSED evutil_socket_t fd, UNUSED short what, void *arg) log_finest_va("Passed ethernet address test, %s", ether); ctx->idletime = time(NULL) - sqlite3_column_int(ctx->thr->get_user, 2); - if (ctx->idletime > ctx->spec->opts->user_timeout) { + if (ctx->idletime > ctx->conn_opts->user_timeout) { log_finest_va("User entry timed out, idletime=%u", ctx->idletime); goto redirect; } @@ -1969,7 +1969,7 @@ out: void pxy_userauth(pxy_conn_ctx_t *ctx) { - if (ctx->spec->opts->user_auth && !ctx->user) { + if (ctx->conn_opts->user_auth && !ctx->user) { #if defined(__OpenBSD__) || defined(__linux__) int ec = get_client_ether( #if defined(__OpenBSD__) diff --git a/src/pxyconn.h b/src/pxyconn.h index 3d9e9e2..a080643 100644 --- a/src/pxyconn.h +++ b/src/pxyconn.h @@ -255,6 +255,7 @@ struct pxy_conn_ctx { pxy_thr_ctx_t *thr; pxy_thrmgr_ctx_t *thrmgr; + conn_opts_t *conn_opts; proxyspec_t *spec; global_t *global; diff --git a/src/pxythrmgr.c b/src/pxythrmgr.c index ee52d48..65b0a74 100644 --- a/src/pxythrmgr.c +++ b/src/pxythrmgr.c @@ -107,7 +107,7 @@ pxy_thrmgr_run(pxy_thrmgr_ctx_t *ctx) ctx->thr[i]->thrmgr = ctx; #ifndef WITHOUT_USERAUTH - if ((ctx->global->opts->user_auth || global_has_userauth_spec(ctx->global)) && + if ((ctx->global->conn_opts->user_auth || global_has_userauth_spec(ctx->global)) && sqlite3_prepare_v2(ctx->global->userdb, "SELECT user,ether,atime,desc FROM users WHERE ip = ?1", 100, &ctx->thr[i]->get_user, NULL)) { log_err_level_printf(LOG_CRIT, "Error preparing get_user sql stmt: %s\n", sqlite3_errmsg(ctx->global->userdb)); goto leave; diff --git a/tests/check/filter.t.c b/tests/check/filter.t.c index 5439850..6b86991 100644 --- a/tests/check/filter.t.c +++ b/tests/check/filter.t.c @@ -39,78 +39,78 @@ START_TEST(set_filter_rule_01) opts_t *opts = opts_new(); s = strdup("*"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 0, "Divert", s, 0); fail_unless(rv == 0, "failed to parse rule"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 0, "Split", s, 0); fail_unless(rv == 0, "failed to parse rule"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 0, "Pass", s, 0); fail_unless(rv == 0, "failed to parse rule"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 0, "Block", s, 0); fail_unless(rv == 0, "failed to parse rule"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("from *"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 0, "Divert", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("from *"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 0, "Split", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("from *"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 0, "Pass", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("from *"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 0, "Block", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("from *"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to *"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 0, "Divert", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to *"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 0, "Split", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to *"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 0, "Pass", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to *"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 0, "Block", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to *"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log *"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 0, "Divert", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log *"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 0, "Split", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log *"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 0, "Pass", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log *"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 0, "Block", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log *"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); @@ -125,65 +125,65 @@ START_TEST(set_filter_rule_02) opts_t *opts = opts_new(); s = strdup("from ip *"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 0, "Divert", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("from ip *"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 0, "Split", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("from ip *"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 0, "Pass", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("from ip *"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 0, "Block", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("from ip *"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("from ip 192.168.0.1"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 0, "Divert", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("from ip 192.168.0.1"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 0, "Split", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("from ip 192.168.0.1"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 0, "Pass", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("from ip 192.168.0.1"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 0, "Block", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("from ip 192.168.0.1"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("from ip 192.168.0.1*"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 0, "Divert", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("from ip 192.168.0.1*"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 0, "Split", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("from ip 192.168.0.1*"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 0, "Pass", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("from ip 192.168.0.1*"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 0, "Block", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("from ip 192.168.0.1*"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); @@ -194,23 +194,23 @@ START_TEST(set_filter_rule_02) // macro expansion returns 1, not 0 s = strdup("from ip $macro"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 0, "Divert", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("from ip $macro"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 0, "Split", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("from ip $macro"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 0, "Pass", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("from ip $macro"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 0, "Block", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("from ip $macro"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); @@ -233,214 +233,212 @@ START_TEST(set_filter_rule_03) close(2); s = strdup("from user *"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 0, "Divert", s, 0); fail_unless(rv == -1, "failed to parse rule"); free(s); s = strdup("from user *"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 0, "Split", s, 0); fail_unless(rv == -1, "failed to parse rule"); free(s); s = strdup("from user *"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 0, "Pass", s, 0); fail_unless(rv == -1, "failed to parse rule"); free(s); s = strdup("from user *"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 0, "Block", s, 0); fail_unless(rv == -1, "failed to parse rule"); free(s); s = strdup("from user *"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == -1, "failed to parse rule"); free(s); s = strdup("from user * desc desc"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 0, "Divert", s, 0); fail_unless(rv == -1, "failed to parse rule"); free(s); s = strdup("from user * desc desc"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 0, "Split", s, 0); fail_unless(rv == -1, "failed to parse rule"); free(s); s = strdup("from user * desc desc"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 0, "Pass", s, 0); fail_unless(rv == -1, "failed to parse rule"); free(s); s = strdup("from user * desc desc"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 0, "Block", s, 0); fail_unless(rv == -1, "failed to parse rule"); free(s); s = strdup("from user * desc desc"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == -1, "failed to parse rule"); free(s); s = strdup("from user $macro"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 0, "Divert", s, 0); fail_unless(rv == -1, "failed to parse rule"); free(s); s = strdup("from user $macro"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 0, "Split", s, 0); fail_unless(rv == -1, "failed to parse rule"); free(s); s = strdup("from user $macro"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 0, "Pass", s, 0); fail_unless(rv == -1, "failed to parse rule"); free(s); s = strdup("from user $macro"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 0, "Block", s, 0); fail_unless(rv == -1, "failed to parse rule"); free(s); s = strdup("from user $macro"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == -1, "failed to parse rule"); free(s); s = strdup("from user $macro desc desc"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 0, "Divert", s, 0); fail_unless(rv == -1, "failed to parse rule"); free(s); s = strdup("from user $macro desc desc"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 0, "Split", s, 0); fail_unless(rv == -1, "failed to parse rule"); free(s); s = strdup("from user $macro desc desc"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 0, "Pass", s, 0); fail_unless(rv == -1, "failed to parse rule"); free(s); s = strdup("from user $macro desc desc"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 0, "Block", s, 0); fail_unless(rv == -1, "failed to parse rule"); free(s); s = strdup("from user $macro desc desc"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == -1, "failed to parse rule"); free(s); s = strdup("from user $macro desc $macro"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 0, "Divert", s, 0); fail_unless(rv == -1, "failed to parse rule"); free(s); s = strdup("from user $macro desc $macro"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 0, "Split", s, 0); fail_unless(rv == -1, "failed to parse rule"); free(s); s = strdup("from user $macro desc $macro"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 0, "Pass", s, 0); fail_unless(rv == -1, "failed to parse rule"); free(s); s = strdup("from user $macro desc $macro"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 0, "Block", s, 0); fail_unless(rv == -1, "failed to parse rule"); free(s); s = strdup("from user $macro desc $macro"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == -1, "failed to parse rule"); free(s); - opts->user_auth = 1; - s = strdup("from user *"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 1, "Divert", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("from user *"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 1, "Split", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("from user *"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 1, "Pass", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("from user *"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 1, "Block", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("from user *"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 1, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("from user * desc desc"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 1, "Divert", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("from user * desc desc"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 1, "Split", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("from user * desc desc"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 1, "Pass", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("from user * desc desc"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 1, "Block", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("from user * desc desc"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 1, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("from user $macro"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 1, "Divert", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("from user $macro"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 1, "Split", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("from user $macro"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 1, "Pass", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("from user $macro"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 1, "Block", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("from user $macro"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 1, "Match", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("from user $macro desc desc"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 1, "Divert", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("from user $macro desc desc"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 1, "Split", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("from user $macro desc desc"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 1, "Pass", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("from user $macro desc desc"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 1, "Block", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("from user $macro desc desc"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 1, "Match", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("from user $macro desc $macro"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 1, "Divert", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("from user $macro desc $macro"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 1, "Split", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("from user $macro desc $macro"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 1, "Pass", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("from user $macro desc $macro"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 1, "Block", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("from user $macro desc $macro"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 1, "Match", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); @@ -456,128 +454,128 @@ START_TEST(set_filter_rule_04) opts_t *opts = opts_new(); s = strdup("to ip *"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 0, "Divert", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to ip *"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 0, "Split", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to ip *"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 0, "Pass", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to ip *"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 0, "Block", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to ip *"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to ip * port *"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 0, "Divert", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to ip * port *"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 0, "Split", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to ip * port *"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 0, "Pass", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to ip * port *"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 0, "Block", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to ip * port *"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to ip 192.168.0.1"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 0, "Divert", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to ip 192.168.0.1"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 0, "Split", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to ip 192.168.0.1"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 0, "Pass", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to ip 192.168.0.1"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 0, "Block", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to ip 192.168.0.1"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to ip 192.168.0.1 port *"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 0, "Divert", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to ip 192.168.0.1 port *"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 0, "Split", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to ip 192.168.0.1 port *"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 0, "Pass", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to ip 192.168.0.1 port *"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 0, "Block", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to ip 192.168.0.1 port *"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to ip * port 443"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 0, "Divert", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to ip * port 443"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 0, "Split", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to ip * port 443"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 0, "Pass", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to ip * port 443"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 0, "Block", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to ip * port 443"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to ip 192.168.0.1 port 443"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 0, "Divert", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to ip 192.168.0.1 port 443"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 0, "Split", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to ip 192.168.0.1 port 443"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 0, "Pass", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to ip 192.168.0.1 port 443"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 0, "Block", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to ip 192.168.0.1 port 443"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); @@ -592,23 +590,23 @@ START_TEST(set_filter_rule_04) free(s); s = strdup("to ip $macro1 port $macro2"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 0, "Divert", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("to ip $macro1 port $macro2"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 0, "Split", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("to ip $macro1 port $macro2"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 0, "Pass", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("to ip $macro1 port $macro2"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 0, "Block", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("to ip $macro1 port $macro2"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); @@ -633,548 +631,548 @@ START_TEST(set_filter_rule_05) free(s); s = strdup("to sni *"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 0, "Divert", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to sni *"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 0, "Split", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to sni *"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 0, "Pass", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to sni *"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 0, "Block", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to sni *"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to sni example.com"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 0, "Divert", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to sni example.com"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 0, "Split", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to sni example.com"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 0, "Pass", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to sni example.com"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 0, "Block", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to sni example.com"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to sni example.com port 443"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 0, "Divert", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to sni example.com port 443"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 0, "Split", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to sni example.com port 443"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 0, "Pass", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to sni example.com port 443"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 0, "Block", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to sni example.com port 443"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to sni $macro"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 0, "Divert", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("to sni $macro"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 0, "Split", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("to sni $macro"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 0, "Pass", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("to sni $macro"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 0, "Block", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("to sni $macro"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("to sni example.com port $macro2"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 0, "Divert", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("to sni example.com port $macro2"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 0, "Split", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("to sni example.com port $macro2"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 0, "Pass", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("to sni example.com port $macro2"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 0, "Block", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("to sni example.com port $macro2"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("to sni $macro port $macro2"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 0, "Divert", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("to sni $macro port $macro2"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 0, "Split", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("to sni $macro port $macro2"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 0, "Pass", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("to sni $macro port $macro2"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 0, "Block", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("to sni $macro port $macro2"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("to cn *"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 0, "Divert", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to cn *"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 0, "Split", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to cn *"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 0, "Pass", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to cn *"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 0, "Block", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to cn *"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to cn example.com"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 0, "Divert", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to cn example.com"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 0, "Split", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to cn example.com"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 0, "Pass", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to cn example.com"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 0, "Block", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to cn example.com"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to cn example.com port 443"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 0, "Divert", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to cn example.com port 443"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 0, "Split", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to cn example.com port 443"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 0, "Pass", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to cn example.com port 443"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 0, "Block", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to cn example.com port 443"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to cn $macro"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 0, "Divert", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("to cn $macro"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 0, "Split", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("to cn $macro"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 0, "Pass", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("to cn $macro"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 0, "Block", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("to cn $macro"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("to cn example.com port $macro2"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 0, "Divert", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("to cn example.com port $macro2"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 0, "Split", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("to cn example.com port $macro2"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 0, "Pass", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("to cn example.com port $macro2"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 0, "Block", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("to cn example.com port $macro2"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("to cn $macro port $macro2"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 0, "Divert", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("to cn $macro port $macro2"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 0, "Split", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("to cn $macro port $macro2"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 0, "Pass", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("to cn $macro port $macro2"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 0, "Block", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("to cn $macro port $macro2"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("to host *"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 0, "Divert", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to host *"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 0, "Split", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to host *"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 0, "Pass", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to host *"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 0, "Block", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to host *"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to host example.com"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 0, "Divert", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to host example.com"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 0, "Split", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to host example.com"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 0, "Pass", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to host example.com"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 0, "Block", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to host example.com"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to host example.com port 443"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 0, "Divert", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to host example.com port 443"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 0, "Split", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to host example.com port 443"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 0, "Pass", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to host example.com port 443"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 0, "Block", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to host example.com port 443"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to host $macro"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 0, "Divert", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("to host $macro"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 0, "Split", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("to host $macro"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 0, "Pass", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("to host $macro"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 0, "Block", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("to host $macro"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("to host example.com port $macro2"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 0, "Divert", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("to host example.com port $macro2"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 0, "Split", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("to host example.com port $macro2"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 0, "Pass", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("to host example.com port $macro2"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 0, "Block", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("to host example.com port $macro2"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("to host $macro port $macro2"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 0, "Divert", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("to host $macro port $macro2"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 0, "Split", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("to host $macro port $macro2"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 0, "Pass", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("to host $macro port $macro2"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 0, "Block", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("to host $macro port $macro2"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("to uri *"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 0, "Divert", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to uri *"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 0, "Split", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to uri *"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 0, "Pass", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to uri *"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 0, "Block", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to uri *"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to uri example.com"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 0, "Divert", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to uri example.com"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 0, "Split", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to uri example.com"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 0, "Pass", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to uri example.com"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 0, "Block", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to uri example.com"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to uri example.com port 443"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 0, "Divert", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to uri example.com port 443"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 0, "Split", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to uri example.com port 443"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 0, "Pass", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to uri example.com port 443"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 0, "Block", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to uri example.com port 443"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to uri $macro"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 0, "Divert", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("to uri $macro"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 0, "Split", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("to uri $macro"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 0, "Pass", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("to uri $macro"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 0, "Block", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("to uri $macro"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("to uri example.com port $macro2"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 0, "Divert", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("to uri example.com port $macro2"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 0, "Split", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("to uri example.com port $macro2"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 0, "Pass", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("to uri example.com port $macro2"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 0, "Block", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("to uri example.com port $macro2"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("to uri $macro port $macro2"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 0, "Divert", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("to uri $macro port $macro2"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 0, "Split", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("to uri $macro port $macro2"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 0, "Pass", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("to uri $macro port $macro2"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 0, "Block", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("to uri $macro port $macro2"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("to port 443"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 0, "Divert", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to port 443"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 0, "Split", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to port 443"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 0, "Pass", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to port 443"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 0, "Block", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to port 443"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("to port $macro2"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 0, "Divert", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("to port $macro2"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 0, "Split", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("to port $macro2"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 0, "Pass", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("to port $macro2"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 0, "Block", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("to port $macro2"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); @@ -1189,296 +1187,296 @@ START_TEST(set_filter_rule_06) opts_t *opts = opts_new(); s = strdup("log *"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 0, "Divert", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log *"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 0, "Split", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log *"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 0, "Pass", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log *"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 0, "Block", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log *"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log connect"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 0, "Divert", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log connect"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 0, "Split", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log connect"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 0, "Pass", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log connect"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 0, "Block", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log connect"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log master"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 0, "Divert", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log master"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 0, "Split", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log master"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 0, "Pass", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log master"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 0, "Block", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log master"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log cert"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 0, "Divert", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log cert"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 0, "Split", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log cert"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 0, "Pass", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log cert"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 0, "Block", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log cert"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log content"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 0, "Divert", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log content"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 0, "Split", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log content"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 0, "Pass", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log content"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 0, "Block", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log content"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log pcap"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 0, "Divert", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log pcap"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 0, "Split", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log pcap"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 0, "Pass", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log pcap"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 0, "Block", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log pcap"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log mirror"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 0, "Divert", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log mirror"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 0, "Split", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log mirror"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 0, "Pass", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log mirror"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 0, "Block", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log mirror"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log !*"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 0, "Divert", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log !*"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 0, "Split", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log !*"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 0, "Pass", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log !*"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 0, "Block", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log !*"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log !connect"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 0, "Divert", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log !connect"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 0, "Split", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log !connect"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 0, "Pass", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log !connect"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 0, "Block", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log !connect"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log !master"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 0, "Divert", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log !master"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 0, "Split", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log !master"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 0, "Pass", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log !master"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 0, "Block", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log !master"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log !cert"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 0, "Divert", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log !cert"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 0, "Split", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log !cert"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 0, "Pass", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log !cert"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 0, "Block", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log !cert"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log !content"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 0, "Divert", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log !content"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 0, "Split", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log !content"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 0, "Pass", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log !content"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 0, "Block", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log !content"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log !pcap"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 0, "Divert", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log !pcap"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 0, "Split", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log !pcap"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 0, "Pass", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log !pcap"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 0, "Block", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log !pcap"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log !mirror"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 0, "Divert", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log !mirror"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 0, "Split", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log !mirror"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 0, "Pass", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log !mirror"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 0, "Block", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("log !mirror"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); @@ -1488,23 +1486,23 @@ START_TEST(set_filter_rule_06) free(s); s = strdup("log $macro"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 0, "Divert", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("log $macro"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 0, "Split", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("log $macro"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 0, "Pass", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("log $macro"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 0, "Block", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("log $macro"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); @@ -1514,23 +1512,23 @@ START_TEST(set_filter_rule_06) free(s); s = strdup("log $macro2"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 0, "Divert", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("log $macro2"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 0, "Split", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("log $macro2"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 0, "Pass", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("log $macro2"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 0, "Block", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("log $macro2"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); @@ -1540,23 +1538,23 @@ START_TEST(set_filter_rule_06) free(s); s = strdup("log $macro3"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 0, "Divert", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("log $macro3"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 0, "Split", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("log $macro3"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 0, "Pass", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("log $macro3"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 0, "Block", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("log $macro3"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); @@ -1566,23 +1564,23 @@ START_TEST(set_filter_rule_06) free(s); s = strdup("log $macro4"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 0, "Divert", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("log $macro4"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 0, "Split", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("log $macro4"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 0, "Pass", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("log $macro4"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 0, "Block", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("log $macro4"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); @@ -1592,23 +1590,23 @@ START_TEST(set_filter_rule_06) free(s); s = strdup("log $macro5"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 0, "Divert", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("log $macro5"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 0, "Split", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("log $macro5"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 0, "Pass", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("log $macro5"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 0, "Block", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("log $macro5"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); @@ -1618,23 +1616,23 @@ START_TEST(set_filter_rule_06) free(s); s = strdup("log $macro6"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 0, "Divert", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("log $macro6"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 0, "Split", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("log $macro6"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 0, "Pass", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("log $macro6"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 0, "Block", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); s = strdup("log $macro6"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); @@ -1650,54 +1648,52 @@ START_TEST(set_filter_rule_07) opts_t *opts = opts_new(); s = strdup("*"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 0, "Divert", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("from *"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 0, "Split", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("from ip *"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 0, "Pass", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("from ip * to ip 192.168.0.1"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 0, "Block", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); - opts->user_auth = 1; - s = strdup("from user *"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 1, "Block", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("from desc *"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 1, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("from user * desc desc"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 1, "Split", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("from user root desc *"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 1, "Pass", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("from user * desc *"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 1, "Divert", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("from * to * log *"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 1, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); @@ -1789,64 +1785,64 @@ START_TEST(set_filter_rule_08) opts_t *opts = opts_new(); s = strdup("from ip 192.168.0.1 to ip 192.168.0.2"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 0, "Divert", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("from ip 192.168.0.1 to ip 192.168.0.2 log connect master cert content pcap mirror"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 0, "Split", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("from ip 192.168.0.1 to ip 192.168.0.2 log !connect !cert !pcap"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 0, "Pass", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); // Block action at precedence 1 is not applied to a site of the same rule at precedence 2 now s = strdup("from ip 192.168.0.1 to ip 192.168.0.2"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 0, "Block", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); // Add another target s = strdup("from ip 192.168.0.1 to ip 192.168.0.3"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); // Add another source s = strdup("from ip 192.168.0.2 to ip 192.168.0.1"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("from ip 192.168.0.2 to ip *"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); // Search substring (subnet?) s = strdup("from ip 192.168.0.2 to ip 192.168.0.*"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); // Add another target s = strdup("from ip 192.168.0.2 to ip 192.168.0.3"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); // Add substring src s = strdup("from ip 192.168.1.* to ip 192.168.0.1"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); // Add substring src and target s = strdup("from ip 192.168.2.* to ip 192.168.3.*"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); @@ -1953,76 +1949,76 @@ START_TEST(set_filter_rule_09) opts_t *opts = opts_new(); s = strdup("from ip 192.168.0.1 to ip 192.168.0.2 port 443"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 0, "Divert", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("from ip 192.168.0.1 to ip 192.168.0.2 port 443 log connect master cert content pcap mirror"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 0, "Split", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("from ip 192.168.0.1 to ip 192.168.0.2 port 443 log !connect !cert !pcap"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 0, "Pass", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); // Block action at precedence 2 is not applied to a port of the same rule at precedence 3 now s = strdup("from ip 192.168.0.1 to ip 192.168.0.2 port 443"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 0, "Block", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); // Add another target, the following port rules should not change this site rule s = strdup("from ip 192.168.0.1 to ip 192.168.0.3 log !mirror"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); // Add another target port s = strdup("from ip 192.168.0.1 to ip 192.168.0.3 port 443"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); // Add another target port s = strdup("from ip 192.168.0.1 to ip 192.168.0.3 port 80"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); // Add another source s = strdup("from ip 192.168.0.2 to ip 192.168.0.1 port 443"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); // Add substring source s = strdup("from ip 192.168.1.* to ip 192.168.0.1 port 443"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); // Add substring source and target s = strdup("from ip 192.168.2.* to ip 192.168.3.* port 443"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("from ip 192.168.0.2 to ip 192.168.0.1 port *"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); // Search substring s = strdup("from ip 192.168.0.2 to ip 192.168.0.1 port 80*"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); // Add substring source, target, and port s = strdup("from ip 192.168.4.* to ip 192.168.5.* port 80*"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); @@ -2163,66 +2159,64 @@ START_TEST(set_filter_rule_10) int rv; opts_t *opts = opts_new(); - opts->user_auth = 1; - s = strdup("from user root to sni example.com"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 1, "Divert", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("from user root to sni example.com log connect master cert content pcap mirror"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 1, "Split", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("from user root to sni example.com log !connect !cert !pcap"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 1, "Pass", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); // Block action at precedence 2 is not applied to a site of the same rule at precedence 4 now s = strdup("from user root to sni example.com"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 1, "Block", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); // Add another target s = strdup("from user root to sni example2.com"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 1, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); // Add another source s = strdup("from user daemon to sni example.com"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 1, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("from user daemon to sni *"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 1, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); // Search substring (subdomain?) s = strdup("from user daemon to sni .example.com*"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 1, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); // Add another target s = strdup("from user daemon to sni example3.com"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 1, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); // Add substring source s = strdup("from user admin1* to sni example4.com"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 1, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("from user admin2* to sni example5.com"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 1, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); @@ -2287,81 +2281,79 @@ START_TEST(set_filter_rule_11) int rv; opts_t *opts = opts_new(); - opts->user_auth = 1; - s = strdup("from user root to cn example.com port 443"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 1, "Divert", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("from user root to cn example.com port 443 log connect master cert content pcap mirror"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 1, "Split", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("from user root to cn example.com port 443 log !connect !cert !pcap"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 1, "Pass", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); // Block action at precedence 3 is not applied to a site of the same rule at precedence 5 now s = strdup("from user root to cn example.com port 443"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 1, "Block", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); // Add another target s = strdup("from user root to cn example2.com port 443"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 1, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); // Add another source s = strdup("from user daemon to cn example.com port 443"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 1, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("from user daemon to cn * port 443"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 1, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("from user daemon to cn example.com port *"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 1, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("from user daemon to cn * port *"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 1, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); // Search substring (subdomain?) s = strdup("from user daemon to cn .example.com* port 443"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 1, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("from user daemon to cn .example.com* port 443*"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 1, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); // Add another target s = strdup("from user daemon to cn example3.com port 443"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 1, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); // Add substring source s = strdup("from user admin1* to cn example4.com port 443"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 1, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("from user admin2* to cn example5.com port 443"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 1, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); @@ -2451,100 +2443,98 @@ START_TEST(set_filter_rule_12) int rv; opts_t *opts = opts_new(); - opts->user_auth = 1; - s = strdup("from user root desc desc to host example.com"); - rv = filter_rule_set(opts, "Divert", s, 0); + rv = filter_rule_set(opts, 1, "Divert", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("from user root desc desc to host example.com port 443 log connect master cert content pcap mirror"); - rv = filter_rule_set(opts, "Split", s, 0); + rv = filter_rule_set(opts, 1, "Split", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("from user root desc desc to host example.com log !connect !cert !pcap"); - rv = filter_rule_set(opts, "Pass", s, 0); + rv = filter_rule_set(opts, 1, "Pass", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); // Block action at precedence 2 is not applied to a site of the same rule at precedence 5 now s = strdup("from user root desc desc to host example.com"); - rv = filter_rule_set(opts, "Block", s, 0); + rv = filter_rule_set(opts, 1, "Block", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); // Add another target s = strdup("from user root desc desc to host example2.com port 443"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 1, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); // Add another source s = strdup("from user daemon desc desc to host example.com"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 1, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("from user daemon desc desc to host * port 443"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 1, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); // Search substring (subdomain?) s = strdup("from user daemon desc desc to host .example.com*"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 1, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); // Add another target s = strdup("from user daemon desc desc to host example3.com"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 1, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); // Add substring source s = strdup("from user admin1* desc desc1* to host example4.com"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 1, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("from user admin2* desc desc2* to host example5.com"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 1, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); // Add another desc s = strdup("from user daemon desc desc2 to host example6.com"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 1, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); // Add all users s = strdup("from user * desc desc to host example7.com"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 1, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); // Add all users all sni sites s = strdup("from user * desc desc to sni *"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 1, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); // Add another desc s = strdup("from desc desc3 to uri example8.com"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 1, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("from user * desc desc4* to host example9.com"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 1, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); s = strdup("from user admin* desc desc5* to host example10.com* port 443*"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 1, "Match", s, 0); fail_unless(rv == 0, "failed to parse rule"); free(s); @@ -2672,7 +2662,7 @@ START_TEST(set_filter_rule_13) free(s); s = strdup("from ip $ips to ip $dstips port $ports log $logs"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 0, "Match", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); @@ -2830,10 +2820,8 @@ START_TEST(set_filter_rule_14) fail_unless(rv == 0, "failed to set macro"); free(s); - opts->user_auth = 1; - s = strdup("from user $users desc $descs to sni $sites log $logs"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 1, "Match", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); @@ -2942,10 +2930,8 @@ START_TEST(set_filter_rule_15) fail_unless(rv == 0, "failed to set macro"); free(s); - opts->user_auth = 1; - s = strdup("from user $users desc $descs to cn $sites port $ports log $logs"); - rv = filter_rule_set(opts, "Match", s, 0); + rv = filter_rule_set(opts, 1, "Match", s, 0); fail_unless(rv == 1, "failed to parse rule"); free(s); diff --git a/tests/check/opts.t.c b/tests/check/opts.t.c index b9a1a84..4415c6b 100644 --- a/tests/check/opts.t.c +++ b/tests/check/opts.t.c @@ -636,7 +636,7 @@ START_TEST(opts_set_passsite_01) opts_t *opts = opts_new(); char *s = strdup("example.com"); - UNUSED int rv = filter_passsite_set(opts, s, 0); + UNUSED int rv = filter_passsite_set(opts, 0, s, 0); free(s); fail_unless(!strcmp(opts->filter_rules->site, "example.com"), "site not example.com"); @@ -666,7 +666,7 @@ START_TEST(opts_set_passsite_02) opts_t *opts = opts_new(); char *s = strdup("example.com 192.168.0.1"); - UNUSED int rv = filter_passsite_set(opts, s, 0); + UNUSED int rv = filter_passsite_set(opts, 0, s, 0); free(s); fail_unless(!strcmp(opts->filter_rules->site, "example.com"), "site not example.com"); @@ -696,10 +696,8 @@ START_TEST(opts_set_passsite_03) char *ps; opts_t *opts = opts_new(); - opts->user_auth = 1; - char *s = strdup("example.com root"); - UNUSED int rv = filter_passsite_set(opts, s, 0); + UNUSED int rv = filter_passsite_set(opts, 1, s, 0); free(s); fail_unless(!strcmp(opts->filter_rules->site, "example.com"), "site not example.com"); @@ -722,10 +720,8 @@ START_TEST(opts_set_passsite_04) char *ps; opts_t *opts = opts_new(); - opts->user_auth = 1; - char *s = strdup("*.google.com * android"); - UNUSED int rv = filter_passsite_set(opts, s, 0); + UNUSED int rv = filter_passsite_set(opts, 1, s, 0); free(s); fail_unless(!strcmp(opts->filter_rules->site, "*.google.com"), "site not *.google.com"); @@ -753,28 +749,27 @@ START_TEST(opts_set_passsite_05) // Dup string using strdup(), otherwise strtok_r() in opts_set_passsite() will cause segmentation fault s = strdup("example.com"); - UNUSED int rv = filter_passsite_set(opts, s, 0); + UNUSED int rv = filter_passsite_set(opts, 0, s, 0); free(s); fail_unless(!opts->filter_rules->next, "next set"); s = strdup("example.com *"); - rv = filter_passsite_set(opts, s, 1); + rv = filter_passsite_set(opts, 0, s, 1); free(s); fail_unless(opts->filter_rules->next, "next not set"); fail_unless(!opts->filter_rules->next->next, "next->next set"); s = strdup("example.com 192.168.0.1"); - rv = filter_passsite_set(opts, s, 2); + rv = filter_passsite_set(opts, 0, s, 2); free(s); fail_unless(opts->filter_rules->next, "next not set"); fail_unless(opts->filter_rules->next->next, "next->next not set"); fail_unless(!opts->filter_rules->next->next->next, "next->next->next set"); #ifndef WITHOUT_USERAUTH - opts->user_auth = 1; // Use root user, opts_set_passsite() calls sys_isuser() to validate the user s = strdup("example.com root"); - rv = filter_passsite_set(opts, s, 3); + rv = filter_passsite_set(opts, 1, s, 3); free(s); fail_unless(opts->filter_rules->next, "next not set"); fail_unless(opts->filter_rules->next->next, "next->next not set"); @@ -782,7 +777,7 @@ START_TEST(opts_set_passsite_05) fail_unless(!opts->filter_rules->next->next->next->next, "next->next->next->next set"); s = strdup("*.google.com * android"); - rv = filter_passsite_set(opts, s, 4); + rv = filter_passsite_set(opts, 1, s, 4); free(s); #endif /* !WITHOUT_USERAUTH */ ps = filter_rule_str(opts->filter_rules);