1 /*- 2 * SSLsplit - transparent SSL/TLS interception 3 * https://www.roe.ch/SSLsplit 4 * 5 * Copyright (c) 2009-2019, Daniel Roethlisberger <daniel@roe.ch>. 6 * Copyright (c) 2017-2021, Soner Tari <sonertari@gmail.com>. 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions are met: 11 * 1. Redistributions of source code must retain the above copyright notice, 12 * this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright notice, 14 * this list of conditions and the following disclaimer in the documentation 15 * and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' 18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 21 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 * POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 #ifndef OPTS_H 31 #define OPTS_H 32 33 #include "proc.h" 34 #include "nat.h" 35 #include "ssl.h" 36 #include "cert.h" 37 #include "attrib.h" 38 39 #ifndef WITHOUT_USERAUTH 40 #include <sys/types.h> 41 #include <sys/socket.h> 42 #include <sqlite3.h> 43 #endif /* !WITHOUT_USERAUTH */ 44 45 /* 46 * Print helper for logging code. 47 */ 48 #define STRORDASH(x) (((x)&&*(x))?(x):"-") 49 #define STRORNONE(x) (((x)&&*(x))?(x):"") 50 #define NLORNONE(x) (((x)&&*(x))?"\n":"") 51 52 #define FILTER_ACTION_NONE 0x00000000U 53 #define FILTER_ACTION_MATCH 0x00000200U 54 #define FILTER_ACTION_DIVERT 0x00000400U 55 #define FILTER_ACTION_SPLIT 0x00000800U 56 #define FILTER_ACTION_PASS 0x00001000U 57 #define FILTER_ACTION_BLOCK 0x00002000U 58 59 #define FILTER_LOG_CONNECT 0x00004000U 60 #define FILTER_LOG_MASTER 0x00008000U 61 #define FILTER_LOG_CERT 0x00010000U 62 #define FILTER_LOG_CONTENT 0x00020000U 63 #define FILTER_LOG_PCAP 0x00040000U 64 #define FILTER_LOG_MIRROR 0x00080000U 65 66 #define FILTER_LOG_NOCONNECT 0x00100000U 67 #define FILTER_LOG_NOMASTER 0x00200000U 68 #define FILTER_LOG_NOCERT 0x00400000U 69 #define FILTER_LOG_NOCONTENT 0x00800000U 70 #define FILTER_LOG_NOPCAP 0x01000000U 71 #define FILTER_LOG_NOMIRROR 0x02000000U 72 73 #define FILTER_PRECEDENCE 0x000000FFU 74 75 #ifndef WITHOUT_USERAUTH 76 typedef struct userlist { 77 char *user; 78 struct userlist *next; 79 } userlist_t; 80 #endif /* !WITHOUT_USERAUTH */ 81 82 typedef struct global global_t; 83 84 typedef struct conn_opts { 85 unsigned int sslcomp : 1; 86 #ifdef HAVE_SSLV2 87 unsigned int no_ssl2 : 1; 88 #endif /* HAVE_SSLV2 */ 89 #ifdef HAVE_SSLV3 90 unsigned int no_ssl3 : 1; 91 #endif /* HAVE_SSLV3 */ 92 #ifdef HAVE_TLSV10 93 unsigned int no_tls10 : 1; 94 #endif /* HAVE_TLSV10 */ 95 #ifdef HAVE_TLSV11 96 unsigned int no_tls11 : 1; 97 #endif /* HAVE_TLSV11 */ 98 #ifdef HAVE_TLSV12 99 unsigned int no_tls12 : 1; 100 #endif /* HAVE_TLSV12 */ 101 #ifdef HAVE_TLSV13 102 unsigned int no_tls13 : 1; 103 #endif /* HAVE_TLSV13 */ 104 unsigned int passthrough : 1; 105 unsigned int deny_ocsp : 1; 106 char *ciphers; 107 char *ciphersuites; 108 CONST_SSL_METHOD *(*sslmethod)(void); 109 #if (OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)) || (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x20702000L) 110 int sslversion; 111 int minsslversion; 112 int maxsslversion; 113 #endif /* OPENSSL_VERSION_NUMBER >= 0x10100000L */ 114 X509 *cacrt; 115 EVP_PKEY *cakey; 116 STACK_OF(X509) *chain; 117 X509 *clientcrt; 118 EVP_PKEY *clientkey; 119 #ifndef OPENSSL_NO_DH 120 DH *dh; 121 #endif /* !OPENSSL_NO_DH */ 122 #ifndef OPENSSL_NO_ECDH 123 char *ecdhcurve; 124 #endif /* !OPENSSL_NO_ECDH */ 125 char *leafcrlurl; 126 unsigned int remove_http_accept_encoding: 1; 127 unsigned int remove_http_referer: 1; 128 unsigned int verify_peer: 1; 129 unsigned int allow_wrong_host: 1; 130 #ifndef WITHOUT_USERAUTH 131 unsigned int user_auth: 1; 132 char *user_auth_url; 133 unsigned int user_timeout; 134 #endif /* !WITHOUT_USERAUTH */ 135 unsigned int validate_proto : 1; 136 // Used with struct filtering rules only 137 unsigned int reconnect_ssl : 1; 138 unsigned int max_http_header_size; 139 } conn_opts_t; 140 141 typedef struct opts { 142 // Set to 1 to divert to lp, set to 0 for split mode 143 // Defaults to 1 144 unsigned int divert : 1; 145 146 #ifndef WITHOUT_USERAUTH 147 userlist_t *divertusers; 148 userlist_t *passusers; 149 #endif /* !WITHOUT_USERAUTH */ 150 151 // Used to store macros and filter rules and to create the filter 152 // Freed during startup after the filter is created and debug printed 153 struct macro *macro; 154 struct filter_rule *filter_rules; 155 156 struct filter *filter; 157 global_t *global; 158 } opts_t; 159 160 typedef struct proxyspec { 161 unsigned int ssl : 1; 162 unsigned int http : 1; 163 unsigned int upgrade: 1; 164 unsigned int pop3 : 1; 165 unsigned int smtp : 1; 166 unsigned int dns : 1; /* set if spec needs DNS lookups */ 167 struct sockaddr_storage listen_addr; 168 socklen_t listen_addrlen; 169 /* connect_addr and connect_addrlen are set: static mode; 170 * natlookup is set: NAT mode; natsocket /may/ be set too; 171 * sni_port is set, in which case we use SNI lookups */ 172 struct sockaddr_storage connect_addr; 173 socklen_t connect_addrlen; 174 unsigned short sni_port; 175 char *natengine; 176 nat_lookup_cb_t natlookup; 177 nat_socket_cb_t natsocket; 178 struct proxyspec *next; 179 180 struct sockaddr_storage divert_addr; 181 socklen_t divert_addrlen; 182 183 struct sockaddr_storage return_addr; 184 socklen_t return_addrlen; 185 186 // Each proxyspec has its own opts 187 opts_t *opts; 188 conn_opts_t *conn_opts; 189 } proxyspec_t; 190 191 // Temporary options 192 // conn_opts strings used while cloning into proxyspec or struct filter rule opts 193 typedef struct tmp_opts { 194 char *cacrt_str; 195 char *cakey_str; 196 char *chain_str; 197 char *clientcrt_str; 198 char *clientkey_str; 199 char *leafcrlurl_str; 200 char *dh_str; 201 // Global split mode set by the -n option 202 // Overrides the divert options of all proxyspecs 203 // Not equivalent to the conf file Divert option 204 unsigned int split : 1; 205 // Prevents Include option in include files 206 unsigned int include : 1; 207 #ifdef DEBUG_PROXY 208 unsigned int line_num; 209 #endif /* DEBUG_PROXY */ 210 } tmp_opts_t; 211 212 struct global { 213 unsigned int debug : 1; 214 unsigned int detach : 1; 215 unsigned int contentlog_isdir : 1; 216 unsigned int contentlog_isspec : 1; 217 unsigned int pcaplog_isdir : 1; 218 unsigned int pcaplog_isspec : 1; 219 #ifdef HAVE_LOCAL_PROCINFO 220 unsigned int lprocinfo : 1; 221 #endif /* HAVE_LOCAL_PROCINFO */ 222 unsigned int certgen_writeall : 1; 223 char *certgendir; 224 char *leafcertdir; 225 char *dropuser; 226 char *dropgroup; 227 char *jaildir; 228 char *pidfile; 229 char *conffile; 230 char *connectlog; 231 char *contentlog; 232 char *contentlog_basedir; /* static part of logspec for privsep srv */ 233 char *masterkeylog; 234 char *pcaplog; 235 char *pcaplog_basedir; /* static part of pcap logspec for privsep srv */ 236 #ifndef WITHOUT_MIRROR 237 char *mirrorif; 238 char *mirrortarget; 239 #endif /* !WITHOUT_MIRROR */ 240 unsigned int conn_idle_timeout; 241 unsigned int expired_conn_check_period; 242 unsigned int stats_period; 243 unsigned int statslog: 1; 244 unsigned int log_stats: 1; 245 #ifndef WITHOUT_USERAUTH 246 char *userdb_path; 247 sqlite3 *userdb; 248 struct sqlite3_stmt *update_user_atime; 249 #endif /* !WITHOUT_USERAUTH */ 250 251 conn_opts_t *conn_opts; 252 proxyspec_t *spec; 253 opts_t *opts; 254 255 // @todo Modify cert cache to move the key field to opts struct 256 // Otherwise, cache HIT fetches certs forged using different leaf cert keys, 257 // which fails loading src server keys 258 // We must use the same key while forging and reusing certs 259 EVP_PKEY *leafkey; 260 cert_t *defaultleafcert; 261 int leafkey_rsabits; 262 263 #ifndef OPENSSL_NO_ENGINE 264 // @todo Use different openssl engines for each proxyspec, so move to opts? 265 char *openssl_engine; 266 #endif /* !OPENSSL_NO_ENGINE */ 267 }; 268 269 #ifndef WITHOUT_USERAUTH 270 typedef struct userdbkeys { 271 char ip[46]; 272 char user[32]; 273 char ether[18]; 274 } userdbkeys_t; 275 #endif /* !WITHOUT_USERAUTH */ 276 277 int oom_return(const char *) WUNRES; 278 void *oom_return_null(const char *) WUNRES; 279 int oom_return_na() WUNRES; 280 void *oom_return_na_null() WUNRES; 281 282 cert_t *opts_load_cert_chain_key(const char *) NONNULL(1); 283 284 void opts_unset_divert(opts_t *) NONNULL(1); 285 286 void proxyspec_free(proxyspec_t *); 287 proxyspec_t *proxyspec_new(global_t *, const char *, tmp_opts_t *) MALLOC; 288 int proxyspec_set_proto(proxyspec_t *, const char *) NONNULL(1,2) WUNRES; 289 int proxyspec_parse(int *, char **[], const char *, global_t *, const char *, tmp_opts_t *) WUNRES; 290 291 char *conn_opts_str(conn_opts_t *); 292 char *proxyspec_str(proxyspec_t *) NONNULL(1) MALLOC; 293 294 conn_opts_t *conn_opts_new(void) MALLOC; 295 opts_t *opts_new(void) MALLOC; 296 void opts_free(opts_t *) NONNULL(1); 297 void conn_opts_free(conn_opts_t *); 298 tmp_opts_t *tmp_opts_copy(tmp_opts_t *) NONNULL(1) MALLOC; 299 conn_opts_t *conn_opts_copy(conn_opts_t *, const char *, tmp_opts_t *) WUNRES; 300 int opts_set_cacrt(conn_opts_t *, const char *, const char *, tmp_opts_t *) NONNULL(1,2,3) WUNRES; 301 int opts_set_cakey(conn_opts_t *, const char *, const char *, tmp_opts_t *) NONNULL(1,2,3) WUNRES; 302 int opts_set_chain(conn_opts_t *, const char *, const char *, tmp_opts_t *) NONNULL(1,2,3) WUNRES; 303 int opts_set_leafcrlurl(conn_opts_t *, const char *, const char *, tmp_opts_t *) NONNULL(1,2,3) WUNRES; 304 void opts_set_deny_ocsp(conn_opts_t *) NONNULL(1); 305 void opts_set_passthrough(conn_opts_t *) NONNULL(1); 306 int opts_set_clientcrt(conn_opts_t *, const char *, const char *, tmp_opts_t *) NONNULL(1,2,3) WUNRES; 307 int opts_set_clientkey(conn_opts_t *, const char *, const char *, tmp_opts_t *) NONNULL(1,2,3) WUNRES; 308 #ifndef OPENSSL_NO_DH 309 int opts_set_dh(conn_opts_t *, const char *, const char *, tmp_opts_t *) NONNULL(1,2,3) WUNRES; 310 #endif /* !OPENSSL_NO_DH */ 311 #ifndef OPENSSL_NO_ECDH 312 int opts_set_ecdhcurve(conn_opts_t *, const char *, const char *) NONNULL(1,2,3) WUNRES; 313 #endif /* !OPENSSL_NO_ECDH */ 314 void opts_unset_sslcomp(conn_opts_t *) NONNULL(1); 315 int opts_force_proto(conn_opts_t *, const char *, const char *) NONNULL(1,2,3) WUNRES; 316 int opts_disable_enable_proto(conn_opts_t *, const char *, const char *, int) NONNULL(1,2,3) WUNRES; 317 int opts_set_ciphers(conn_opts_t *, const char *, const char *) NONNULL(1,2,3) WUNRES; 318 int opts_set_ciphersuites(conn_opts_t *, const char *, const char *) NONNULL(1,2,3) WUNRES; 319 320 int set_conn_opts_option(conn_opts_t *, const char *, const char *, char *, unsigned int, tmp_opts_t *); 321 int load_proxyspec_struct(global_t *, const char *, char **, unsigned int *, FILE *, tmp_opts_t *) WUNRES; 322 323 #define OPTS_DEBUG(global) unlikely((global)->debug) 324 325 global_t * global_new(void) MALLOC; 326 void tmp_opts_free(tmp_opts_t *) NONNULL(1); 327 void global_free(global_t *) NONNULL(1); 328 int global_has_ssl_spec(global_t *) NONNULL(1) WUNRES; 329 int global_has_dns_spec(global_t *) NONNULL(1) WUNRES; 330 int global_has_userauth_spec(global_t *) NONNULL(1) WUNRES; 331 int global_has_cakey_spec(global_t *) NONNULL(1) WUNRES; 332 int global_set_user(global_t *, const char *, const char *) NONNULL(1,2,3) WUNRES; 333 int global_set_group(global_t *, const char *, const char *) NONNULL(1,2,3) WUNRES; 334 int global_set_jaildir(global_t *, const char *, const char *) NONNULL(1,2,3) WUNRES; 335 int global_set_pidfile(global_t *, const char *, const char *) NONNULL(1,2,3) WUNRES; 336 int global_set_connectlog(global_t *, const char *, const char *) NONNULL(1,2,3) WUNRES; 337 int global_set_contentlog(global_t *, const char *, const char *) NONNULL(1,2,3) WUNRES; 338 int global_set_contentlogdir(global_t *, const char *, const char *) NONNULL(1,2,3) WUNRES; 339 int global_set_contentlogpathspec(global_t *, const char *, const char *) NONNULL(1,2,3) WUNRES; 340 #ifdef HAVE_LOCAL_PROCINFO 341 void global_set_lprocinfo(global_t *) NONNULL(1); 342 #endif /* HAVE_LOCAL_PROCINFO */ 343 int global_set_masterkeylog(global_t *, const char *, const char *) NONNULL(1,2,3) WUNRES; 344 int global_set_pcaplog(global_t *, const char *, const char *) NONNULL(1,2,3) WUNRES; 345 int global_set_pcaplogdir(global_t *, const char *, const char *) NONNULL(1,2,3) WUNRES; 346 int global_set_pcaplogpathspec(global_t *, const char *, const char *) NONNULL(1,2,3) WUNRES; 347 #ifndef WITHOUT_MIRROR 348 int global_set_mirrorif(global_t *, const char *, const char *) NONNULL(1,2,3) WUNRES; 349 int global_set_mirrortarget(global_t *, const char *, const char *) NONNULL(1,2,3) WUNRES; 350 #endif /* !WITHOUT_MIRROR */ 351 void global_set_daemon(global_t *) NONNULL(1); 352 void global_set_debug(global_t *) NONNULL(1); 353 int global_set_debug_level(const char *) NONNULL(1) WUNRES; 354 void global_set_statslog(global_t *) NONNULL(1); 355 356 int is_yesno(const char *) WUNRES; 357 int check_value_yesno(const char *, const char *, unsigned int) WUNRES; 358 int get_name_value(char *, char **, const char, unsigned int) WUNRES; 359 int global_set_option(global_t *, const char *, const char *, char **, tmp_opts_t *) NONNULL(1,2,3,5) WUNRES; 360 int global_set_leafkey(global_t *, const char *, const char *) NONNULL(1,2,3) WUNRES; 361 int global_set_leafcertdir(global_t *, const char *, const char *) NONNULL(1,2,3) WUNRES; 362 int global_set_defaultleafcert(global_t *, const char *, const char *) NONNULL(1,2,3) WUNRES; 363 int global_set_certgendir_writeall(global_t *, const char *, const char *) NONNULL(1,2,3) WUNRES; 364 int global_set_certgendir_writegencerts(global_t *, const char *, const char *) NONNULL(1,2,3) WUNRES; 365 int global_set_openssl_engine(global_t *, const char *, const char *) NONNULL(1,2,3) WUNRES; 366 int global_load_conffile(global_t *, const char *, const char *, char **, tmp_opts_t *) NONNULL(1,2,4) WUNRES; 367 #endif /* !OPTS_H */ 368 369 /* vim: set noet ft=c: */ 370