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 #include "protossl.h"
31 #include "prototcp.h"
32 #include "protopassthrough.h"
33
34 #include "cachemgr.h"
35
36 #include <string.h>
37 #include <sys/param.h>
38 #include <event2/bufferevent_ssl.h>
39
40 /*
41 * Context used for all server sessions.
42 */
43 #ifdef USE_SSL_SESSION_ID_CONTEXT
44 static unsigned long ssl_session_context = 0x31415926;
45 #endif /* USE_SSL_SESSION_ID_CONTEXT */
46
47 void
protossl_log_ssl_error(struct bufferevent * bev,pxy_conn_ctx_t * ctx)48 protossl_log_ssl_error(struct bufferevent *bev, pxy_conn_ctx_t *ctx)
49 {
50 unsigned long sslerr;
51
52 /* Can happen for socket errs, ssl errs;
53 * may happen for unclean ssl socket shutdowns. */
54 sslerr = bufferevent_get_openssl_error(bev);
55 if (sslerr)
56 ctx->sslctx->have_sslerr = 1;
57 if (!errno && !sslerr) {
58 #if LIBEVENT_VERSION_NUMBER >= 0x02010000
59 /* We have disabled notification for unclean shutdowns
60 * so this should not happen; log a warning. */
61 log_err_level_printf(LOG_WARNING, "Spurious error from bufferevent (errno=0,sslerr=0)\n");
62 #else /* LIBEVENT_VERSION_NUMBER < 0x02010000 */
63 /* Older versions of libevent will report these. */
64 if (OPTS_DEBUG(ctx->global)) {
65 log_dbg_printf("Unclean SSL shutdown, fd=%d\n", ctx->fd);
66 }
67 #endif /* LIBEVENT_VERSION_NUMBER < 0x02010000 */
68 } else if (ERR_GET_REASON(sslerr) == SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE) {
69 /* these can happen due to client cert auth,
70 * only log error if debugging is activated */
71 log_dbg_printf("Error from bufferevent: %i:%s %lu:%i:%s:%i:%s:%i:%s\n",
72 errno, errno ? strerror(errno) : "-", sslerr,
73 ERR_GET_REASON(sslerr), STRORDASH(ERR_reason_error_string(sslerr)),
74 ERR_GET_LIB(sslerr), STRORDASH(ERR_lib_error_string(sslerr)),
75 ERR_GET_FUNC(sslerr), STRORDASH(ERR_func_error_string(sslerr)));
76 while ((sslerr = bufferevent_get_openssl_error(bev))) {
77 log_dbg_printf("Additional SSL error: %lu:%i:%s:%i:%s:%i:%s\n",
78 sslerr,
79 ERR_GET_REASON(sslerr), STRORDASH(ERR_reason_error_string(sslerr)),
80 ERR_GET_LIB(sslerr), STRORDASH(ERR_lib_error_string(sslerr)),
81 ERR_GET_FUNC(sslerr), STRORDASH(ERR_func_error_string(sslerr)));
82 }
83 } else {
84 /* real errors */
85 log_err_printf("Error from bufferevent: %i:%s %lu:%i:%s:%i:%s:%i:%s\n",
86 errno, errno ? strerror(errno) : "-",
87 sslerr,
88 ERR_GET_REASON(sslerr), STRORDASH(ERR_reason_error_string(sslerr)),
89 ERR_GET_LIB(sslerr), STRORDASH(ERR_lib_error_string(sslerr)),
90 ERR_GET_FUNC(sslerr), STRORDASH(ERR_func_error_string(sslerr)));
91 while ((sslerr = bufferevent_get_openssl_error(bev))) {
92 log_err_printf("Additional SSL error: %lu:%i:%s:%i:%s:%i:%s\n",
93 sslerr,
94 ERR_GET_REASON(sslerr), STRORDASH(ERR_reason_error_string(sslerr)),
95 ERR_GET_LIB(sslerr), STRORDASH(ERR_lib_error_string(sslerr)),
96 ERR_GET_FUNC(sslerr), STRORDASH(ERR_func_error_string(sslerr)));
97 }
98 }
99 if (ctx->spec->opts->filter && !ctx->pass) {
100 log_err_level_printf(LOG_WARNING, "Closing on ssl error without filter match: %s:%s, %s:%s, "
101 #ifndef WITHOUT_USERAUTH
102 "%s, %s, "
103 #endif /* !WITHOUT_USERAUTH */
104 "%s, %s\n",
105 STRORDASH(ctx->srchost_str), STRORDASH(ctx->srcport_str), STRORDASH(ctx->dsthost_str), STRORDASH(ctx->dstport_str),
106 #ifndef WITHOUT_USERAUTH
107 STRORDASH(ctx->user), STRORDASH(ctx->desc),
108 #endif /* !WITHOUT_USERAUTH */
109 STRORDASH(ctx->sslctx->sni), STRORDASH(ctx->sslctx->ssl_names));
110 }
111 }
112
113 int
protossl_log_masterkey(pxy_conn_ctx_t * ctx,pxy_conn_desc_t * this)114 protossl_log_masterkey(pxy_conn_ctx_t *ctx, pxy_conn_desc_t *this)
115 {
116 // XXX: Remove ssl check? But the caller function is called by non-ssl protos.
117 if (this->ssl) {
118 /* log master key */
119 if (ctx->log_master && ctx->global->masterkeylog) {
120 char *keystr;
121 keystr = ssl_ssl_masterkey_to_str(this->ssl);
122 if ((keystr == NULL) ||
123 (log_masterkey_print_free(keystr) == -1)) {
124 if (errno == ENOMEM)
125 ctx->enomem = 1;
126 pxy_conn_term(ctx, 1);
127 return -1;
128 }
129 }
130 }
131 return 0;
132 }
133
134 /* forward declaration of OpenSSL callbacks */
135 #ifndef OPENSSL_NO_TLSEXT
136 static int protossl_ossl_servername_cb(SSL *ssl, int *al, void *arg);
137 #endif /* !OPENSSL_NO_TLSEXT */
138 static int protossl_ossl_sessnew_cb(SSL *, SSL_SESSION *);
139 static void protossl_ossl_sessremove_cb(SSL_CTX *, SSL_SESSION *);
140 #if (OPENSSL_VERSION_NUMBER < 0x10100000L) || (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20800000L)
141 static SSL_SESSION * protossl_ossl_sessget_cb(SSL *, unsigned char *, int, int *);
142 #else /* OPENSSL_VERSION_NUMBER >= 0x10100000L */
143 static SSL_SESSION * protossl_ossl_sessget_cb(SSL *, const unsigned char *, int, int *);
144 #endif /* OPENSSL_VERSION_NUMBER >= 0x10100000L */
145
146 /*
147 * Dump information on a certificate to the debug log.
148 */
149 static void
protossl_debug_crt(X509 * crt)150 protossl_debug_crt(X509 *crt)
151 {
152 char *sj = ssl_x509_subject(crt);
153 if (sj) {
154 log_dbg_printf("Subject DN: %s\n", sj);
155 free(sj);
156 }
157
158 char *names = ssl_x509_names_to_str(crt);
159 if (names) {
160 log_dbg_printf("Common Names: %s\n", names);
161 free(names);
162 }
163
164 char *fpr;
165 if (!(fpr = ssl_x509_fingerprint(crt, 1))) {
166 log_err_level_printf(LOG_WARNING, "Error generating X509 fingerprint\n");
167 } else {
168 log_dbg_printf("Fingerprint: %s\n", fpr);
169 free(fpr);
170 }
171
172 #ifdef DEBUG_CERTIFICATE
173 /* dump certificate */
174 log_dbg_print_free(ssl_x509_to_str(crt));
175 log_dbg_print_free(ssl_x509_to_pem(crt));
176 #endif /* DEBUG_CERTIFICATE */
177 }
178
179 /*
180 * Called by OpenSSL when a new src SSL session is created.
181 * OpenSSL increments the refcount before calling the callback and will
182 * decrement it again if we return 0. Returning 1 will make OpenSSL skip
183 * the refcount decrementing. In other words, return 0 if we did not
184 * keep a pointer to the object (which we never do here).
185 */
186 #ifdef HAVE_SSLV2
187 #define MAYBE_UNUSED
188 #else /* !HAVE_SSLV2 */
189 #define MAYBE_UNUSED UNUSED
190 #endif /* !HAVE_SSLV2 */
191 static int
protossl_ossl_sessnew_cb(MAYBE_UNUSED SSL * ssl,SSL_SESSION * sess)192 protossl_ossl_sessnew_cb(MAYBE_UNUSED SSL *ssl, SSL_SESSION *sess)
193 #undef MAYBE_UNUSED
194 {
195 #ifdef DEBUG_SESSION_CACHE
196 log_dbg_printf("===> OpenSSL new session callback:\n");
197 if (sess) {
198 log_dbg_print_free(ssl_session_to_str(sess));
199 } else {
200 log_dbg_printf("(null)\n");
201 }
202 #endif /* DEBUG_SESSION_CACHE */
203 #ifdef HAVE_SSLV2
204 /* Session resumption seems to fail for SSLv2 with protocol
205 * parsing errors, so we disable caching for SSLv2. */
206 if (SSL_version(ssl) == SSL2_VERSION) {
207 log_err_level_printf(LOG_WARNING, "Session resumption denied to SSLv2"
208 "client.\n");
209 return 0;
210 }
211 #endif /* HAVE_SSLV2 */
212 if (sess) {
213 cachemgr_ssess_set(sess);
214 }
215 return 0;
216 }
217
218 /*
219 * Called by OpenSSL when a src SSL session should be removed.
220 * OpenSSL calls SSL_SESSION_free() after calling the callback;
221 * we do not need to free the reference here.
222 */
223 static void
protossl_ossl_sessremove_cb(UNUSED SSL_CTX * sslctx,SSL_SESSION * sess)224 protossl_ossl_sessremove_cb(UNUSED SSL_CTX *sslctx, SSL_SESSION *sess)
225 {
226 #ifdef DEBUG_SESSION_CACHE
227 log_dbg_printf("===> OpenSSL remove session callback:\n");
228 if (sess) {
229 log_dbg_print_free(ssl_session_to_str(sess));
230 } else {
231 log_dbg_printf("(null)\n");
232 }
233 #endif /* DEBUG_SESSION_CACHE */
234 if (sess) {
235 cachemgr_ssess_del(sess);
236 }
237 }
238
239 /*
240 * Called by OpenSSL when a src SSL session is requested by the client.
241 */
242 static SSL_SESSION *
243 #if (OPENSSL_VERSION_NUMBER < 0x10100000L) || (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20800000L)
protossl_ossl_sessget_cb(UNUSED SSL * ssl,unsigned char * id,int idlen,int * copy)244 protossl_ossl_sessget_cb(UNUSED SSL *ssl, unsigned char *id, int idlen, int *copy)
245 #else /* OPENSSL_VERSION_NUMBER >= 0x10100000L */
246 protossl_ossl_sessget_cb(UNUSED SSL *ssl, const unsigned char *id, int idlen, int *copy)
247 #endif /* OPENSSL_VERSION_NUMBER >= 0x10100000L */
248 {
249 SSL_SESSION *sess;
250
251 #ifdef DEBUG_SESSION_CACHE
252 log_dbg_printf("===> OpenSSL get session callback:\n");
253 #endif /* DEBUG_SESSION_CACHE */
254
255 *copy = 0; /* SSL should not increment reference count of session */
256 sess = cachemgr_ssess_get(id, idlen);
257
258 #ifdef DEBUG_SESSION_CACHE
259 if (sess) {
260 log_dbg_print_free(ssl_session_to_str(sess));
261 }
262 #endif /* DEBUG_SESSION_CACHE */
263
264 log_dbg_printf("SSL session cache: %s\n", sess ? "HIT" : "MISS");
265 return sess;
266 }
267
268 /*
269 * Set SSL_CTX options that are the same for incoming and outgoing SSL_CTX.
270 */
271 static void
protossl_sslctx_setoptions(SSL_CTX * sslctx,pxy_conn_ctx_t * ctx)272 protossl_sslctx_setoptions(SSL_CTX *sslctx, pxy_conn_ctx_t *ctx)
273 {
274 SSL_CTX_set_options(sslctx, SSL_OP_ALL);
275 #ifdef SSL_OP_TLS_ROLLBACK_BUG
276 SSL_CTX_set_options(sslctx, SSL_OP_TLS_ROLLBACK_BUG);
277 #endif /* SSL_OP_TLS_ROLLBACK_BUG */
278 #ifdef SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION
279 SSL_CTX_set_options(sslctx, SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION);
280 #endif /* SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION */
281 #ifdef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
282 SSL_CTX_set_options(sslctx, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS);
283 #endif /* SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS */
284 #ifdef SSL_OP_NO_TICKET
285 SSL_CTX_set_options(sslctx, SSL_OP_NO_TICKET);
286 #endif /* SSL_OP_NO_TICKET */
287
288 #ifdef SSL_OP_NO_SSLv2
289 #ifdef HAVE_SSLV2
290 if (ctx->conn_opts->no_ssl2) {
291 #endif /* HAVE_SSLV2 */
292 SSL_CTX_set_options(sslctx, SSL_OP_NO_SSLv2);
293 #ifdef HAVE_SSLV2
294 }
295 #endif /* HAVE_SSLV2 */
296 #endif /* !SSL_OP_NO_SSLv2 */
297 #ifdef HAVE_SSLV3
298 if (ctx->conn_opts->no_ssl3) {
299 SSL_CTX_set_options(sslctx, SSL_OP_NO_SSLv3);
300 }
301 #endif /* HAVE_SSLV3 */
302 #ifdef HAVE_TLSV10
303 if (ctx->conn_opts->no_tls10) {
304 SSL_CTX_set_options(sslctx, SSL_OP_NO_TLSv1);
305 }
306 #endif /* HAVE_TLSV10 */
307 #ifdef HAVE_TLSV11
308 if (ctx->conn_opts->no_tls11) {
309 SSL_CTX_set_options(sslctx, SSL_OP_NO_TLSv1_1);
310 }
311 #endif /* HAVE_TLSV11 */
312 #ifdef HAVE_TLSV12
313 if (ctx->conn_opts->no_tls12) {
314 SSL_CTX_set_options(sslctx, SSL_OP_NO_TLSv1_2);
315 }
316 #endif /* HAVE_TLSV12 */
317 #ifdef HAVE_TLSV13
318 if (ctx->conn_opts->no_tls13) {
319 SSL_CTX_set_options(sslctx, SSL_OP_NO_TLSv1_3);
320 }
321 #endif /* HAVE_TLSV13 */
322
323 #ifdef SSL_OP_NO_COMPRESSION
324 if (!ctx->conn_opts->sslcomp) {
325 SSL_CTX_set_options(sslctx, SSL_OP_NO_COMPRESSION);
326 }
327 #endif /* SSL_OP_NO_COMPRESSION */
328
329 SSL_CTX_set_cipher_list(sslctx, ctx->conn_opts->ciphers);
330 #ifdef HAVE_TLSV13
331 SSL_CTX_set_ciphersuites(sslctx, ctx->conn_opts->ciphersuites);
332 #endif /* HAVE_TLSV13 */
333
334 #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER)
335 /* If the security level of OpenSSL is set to 2+ in system configuration,
336 * our forged certificates with 1024-bit RSA key size will be rejected */
337 SSL_CTX_set_security_level(sslctx, 1);
338 #endif /* OPENSSL_VERSION_NUMBER >= 0x10100000L */
339 }
340
341 /*
342 * Create and set up a new SSL_CTX instance for terminating SSL.
343 * Set up all the necessary callbacks, the certificate, the cert chain and key.
344 */
345 static SSL_CTX *
protossl_srcsslctx_create(pxy_conn_ctx_t * ctx,X509 * crt,STACK_OF (X509)* chain,EVP_PKEY * key)346 protossl_srcsslctx_create(pxy_conn_ctx_t *ctx, X509 *crt, STACK_OF(X509) *chain,
347 EVP_PKEY *key)
348 {
349 SSL_CTX *sslctx = SSL_CTX_new(ctx->conn_opts->sslmethod());
350 if (!sslctx) {
351 ctx->enomem = 1;
352 return NULL;
353 }
354
355 protossl_sslctx_setoptions(sslctx, ctx);
356
357 #if (OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)) || (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x20702000L)
358 if (ctx->conn_opts->minsslversion) {
359 if (SSL_CTX_set_min_proto_version(sslctx, ctx->conn_opts->minsslversion) == 0) {
360 SSL_CTX_free(sslctx);
361 return NULL;
362 }
363 }
364 if (ctx->conn_opts->maxsslversion) {
365 if (SSL_CTX_set_max_proto_version(sslctx, ctx->conn_opts->maxsslversion) == 0) {
366 SSL_CTX_free(sslctx);
367 return NULL;
368 }
369 }
370 // ForceSSLproto has precedence
371 if (ctx->conn_opts->sslversion) {
372 if (SSL_CTX_set_min_proto_version(sslctx, ctx->conn_opts->sslversion) == 0 ||
373 SSL_CTX_set_max_proto_version(sslctx, ctx->conn_opts->sslversion) == 0) {
374 SSL_CTX_free(sslctx);
375 return NULL;
376 }
377 }
378 #endif /* OPENSSL_VERSION_NUMBER >= 0x10100000L */
379
380 SSL_CTX_sess_set_new_cb(sslctx, protossl_ossl_sessnew_cb);
381 SSL_CTX_sess_set_remove_cb(sslctx, protossl_ossl_sessremove_cb);
382 SSL_CTX_sess_set_get_cb(sslctx, protossl_ossl_sessget_cb);
383 SSL_CTX_set_session_cache_mode(sslctx, SSL_SESS_CACHE_SERVER |
384 SSL_SESS_CACHE_NO_INTERNAL);
385 #ifdef USE_SSL_SESSION_ID_CONTEXT
386 SSL_CTX_set_session_id_context(sslctx, (void *)(&ssl_session_context),
387 sizeof(ssl_session_context));
388 #endif /* USE_SSL_SESSION_ID_CONTEXT */
389 #ifndef OPENSSL_NO_TLSEXT
390 SSL_CTX_set_tlsext_servername_callback(sslctx, protossl_ossl_servername_cb);
391 SSL_CTX_set_tlsext_servername_arg(sslctx, ctx);
392 #endif /* !OPENSSL_NO_TLSEXT */
393 #ifndef OPENSSL_NO_DH
394 if (ctx->conn_opts->dh) {
395 SSL_CTX_set_tmp_dh(sslctx, ctx->conn_opts->dh);
396 } else {
397 SSL_CTX_set_tmp_dh_callback(sslctx, ssl_tmp_dh_callback);
398 }
399 #endif /* !OPENSSL_NO_DH */
400 #ifndef OPENSSL_NO_ECDH
401 if (ctx->conn_opts->ecdhcurve) {
402 EC_KEY *ecdh = ssl_ec_by_name(ctx->conn_opts->ecdhcurve);
403 SSL_CTX_set_tmp_ecdh(sslctx, ecdh);
404 EC_KEY_free(ecdh);
405 } else {
406 EC_KEY *ecdh = ssl_ec_by_name(NULL);
407 SSL_CTX_set_tmp_ecdh(sslctx, ecdh);
408 EC_KEY_free(ecdh);
409 }
410 #endif /* !OPENSSL_NO_ECDH */
411 if (SSL_CTX_use_certificate(sslctx, crt) != 1) {
412 log_dbg_printf("loading src server certificate failed\n");
413 SSL_CTX_free(sslctx);
414 return NULL;
415 }
416 if (SSL_CTX_use_PrivateKey(sslctx, key) != 1) {
417 log_dbg_printf("loading src server key failed\n");
418 SSL_CTX_free(sslctx);
419 return NULL;
420 }
421 for (int i = 0; i < sk_X509_num(chain); i++) {
422 X509 *c = sk_X509_value(chain, i);
423 ssl_x509_refcount_inc(c); /* next call consumes a reference */
424 SSL_CTX_add_extra_chain_cert(sslctx, c);
425 }
426
427 #ifdef DEBUG_SESSION_CACHE
428 if (OPTS_DEBUG(ctx->global)) {
429 int mode = SSL_CTX_get_session_cache_mode(sslctx);
430 log_dbg_printf("SSL session cache mode: %08x\n", mode);
431 if (mode == SSL_SESS_CACHE_OFF)
432 log_dbg_printf("SSL_SESS_CACHE_OFF\n");
433 if (mode & SSL_SESS_CACHE_CLIENT)
434 log_dbg_printf("SSL_SESS_CACHE_CLIENT\n");
435 if (mode & SSL_SESS_CACHE_SERVER)
436 log_dbg_printf("SSL_SESS_CACHE_SERVER\n");
437 if (mode & SSL_SESS_CACHE_NO_AUTO_CLEAR)
438 log_dbg_printf("SSL_SESS_CACHE_NO_AUTO_CLEAR\n");
439 if (mode & SSL_SESS_CACHE_NO_INTERNAL_LOOKUP)
440 log_dbg_printf("SSL_SESS_CACHE_NO_INTERNAL_LOOKUP\n");
441 if (mode & SSL_SESS_CACHE_NO_INTERNAL_STORE)
442 log_dbg_printf("SSL_SESS_CACHE_NO_INTERNAL_STORE\n");
443 }
444 #endif /* DEBUG_SESSION_CACHE */
445
446 return sslctx;
447 }
448
449 static int
protossl_srccert_write_to_gendir(pxy_conn_ctx_t * ctx,X509 * crt,int is_orig)450 protossl_srccert_write_to_gendir(pxy_conn_ctx_t *ctx, X509 *crt, int is_orig)
451 {
452 char *fn;
453 int rv;
454
455 if (!ctx->sslctx->origcrtfpr)
456 return -1;
457 if (is_orig) {
458 rv = asprintf(&fn, "%s/%s.crt", ctx->global->certgendir,
459 ctx->sslctx->origcrtfpr);
460 } else {
461 if (!ctx->sslctx->usedcrtfpr)
462 return -1;
463 rv = asprintf(&fn, "%s/%s-%s.crt", ctx->global->certgendir,
464 ctx->sslctx->origcrtfpr, ctx->sslctx->usedcrtfpr);
465 }
466 if (rv == -1) {
467 ctx->enomem = 1;
468 return -1;
469 }
470 rv = log_cert_submit(fn, crt);
471 free(fn);
472 return rv;
473 }
474
475 void
protossl_srccert_write(pxy_conn_ctx_t * ctx)476 protossl_srccert_write(pxy_conn_ctx_t *ctx)
477 {
478 if (ctx->global->certgen_writeall || ctx->sslctx->generated_cert) {
479 if (protossl_srccert_write_to_gendir(ctx,
480 SSL_get_certificate(ctx->src.ssl), 0) == -1) {
481 log_err_level_printf(LOG_CRIT, "Failed to write used certificate\n");
482 }
483 }
484 if (ctx->global->certgen_writeall) {
485 if (protossl_srccert_write_to_gendir(ctx, ctx->sslctx->origcrt, 1) == -1) {
486 log_err_level_printf(LOG_CRIT, "Failed to write orig certificate\n");
487 }
488 }
489 }
490
491 static cert_t *
protossl_srccert_create(pxy_conn_ctx_t * ctx)492 protossl_srccert_create(pxy_conn_ctx_t *ctx)
493 {
494 cert_t *cert = NULL;
495
496 if (ctx->global->leafcertdir) {
497 if (ctx->sslctx->sni) {
498 cert = cachemgr_tgcrt_get(ctx->sslctx->sni);
499 if (!cert) {
500 char *wildcarded;
501 wildcarded = ssl_wildcardify(ctx->sslctx->sni);
502 if (!wildcarded) {
503 ctx->enomem = 1;
504 return NULL;
505 }
506 cert = cachemgr_tgcrt_get(wildcarded);
507 free(wildcarded);
508 }
509 if (cert && OPTS_DEBUG(ctx->global)) {
510 log_dbg_printf("Target cert by SNI\n");
511 }
512 } else if (ctx->sslctx->origcrt) {
513 char **names = ssl_x509_names(ctx->sslctx->origcrt);
514 for (char **p = names; *p; p++) {
515 if (!cert) {
516 cert = cachemgr_tgcrt_get(*p);
517 }
518 if (!cert) {
519 char *wildcarded;
520 wildcarded = ssl_wildcardify(*p);
521 if (!wildcarded) {
522 ctx->enomem = 1;
523 } else {
524 /* increases ref count */
525 cert = cachemgr_tgcrt_get(
526 wildcarded);
527 free(wildcarded);
528 }
529 }
530 free(*p);
531 }
532 free(names);
533 if (ctx->enomem) {
534 return NULL;
535 }
536 if (cert && OPTS_DEBUG(ctx->global)) {
537 log_dbg_printf("Target cert by origcrt\n");
538 }
539 }
540
541 if (cert) {
542 ctx->sslctx->immutable_cert = 1;
543 }
544 }
545
546 if (!cert && ctx->global->defaultleafcert) {
547 cert = ctx->global->defaultleafcert;
548 cert_refcount_inc(cert);
549 ctx->sslctx->immutable_cert = 1;
550 if (OPTS_DEBUG(ctx->global)) {
551 log_dbg_printf("Using default leaf certificate\n");
552 }
553 }
554
555 if (!cert && ctx->sslctx->origcrt && ctx->global->leafkey) {
556 cert = cert_new();
557
558 cert->crt = cachemgr_fkcrt_get(ctx->sslctx->origcrt);
559 if (cert->crt) {
560 if (OPTS_DEBUG(ctx->global))
561 log_dbg_printf("Certificate cache: HIT\n");
562 } else {
563 if (OPTS_DEBUG(ctx->global))
564 log_dbg_printf("Certificate cache: MISS\n");
565 cert->crt = ssl_x509_forge(ctx->conn_opts->cacrt,
566 ctx->conn_opts->cakey,
567 ctx->sslctx->origcrt,
568 ctx->global->leafkey,
569 NULL,
570 ctx->conn_opts->leafcrlurl);
571 cachemgr_fkcrt_set(ctx->sslctx->origcrt, cert->crt);
572 }
573 cert_set_key(cert, ctx->global->leafkey);
574 cert_set_chain(cert, ctx->conn_opts->chain);
575 ctx->sslctx->generated_cert = 1;
576 }
577
578 if ((WANT_CONNECT_LOG(ctx) || ctx->global->certgendir) && ctx->sslctx->origcrt) {
579 ctx->sslctx->origcrtfpr = ssl_x509_fingerprint(ctx->sslctx->origcrt, 0);
580 if (!ctx->sslctx->origcrtfpr)
581 ctx->enomem = 1;
582 }
583 if ((WANT_CONNECT_LOG(ctx) || ctx->global->certgen_writeall) &&
584 cert && cert->crt) {
585 ctx->sslctx->usedcrtfpr = ssl_x509_fingerprint(cert->crt, 0);
586 if (!ctx->sslctx->usedcrtfpr)
587 ctx->enomem = 1;
588 }
589
590 return cert;
591 }
592
593 static filter_action_t * NONNULL(1,2)
protossl_filter_match_sni(pxy_conn_ctx_t * ctx,filter_list_t * list)594 protossl_filter_match_sni(pxy_conn_ctx_t *ctx, filter_list_t *list)
595 {
596 filter_site_t *site = filter_site_find(list->sni_btree, list->sni_acm, list->sni_all, ctx->sslctx->sni);
597 if (!site)
598 return NULL;
599
600 #ifndef WITHOUT_USERAUTH
601 log_fine_va("Found site (line=%d): %s for %s:%s, %s:%s, %s, %s, %s", site->action.line_num, site->site,
602 STRORDASH(ctx->srchost_str), STRORDASH(ctx->srcport_str), STRORDASH(ctx->dsthost_str), STRORDASH(ctx->dstport_str),
603 STRORDASH(ctx->user), STRORDASH(ctx->desc), STRORDASH(ctx->sslctx->sni));
604 #else /* WITHOUT_USERAUTH */
605 log_fine_va("Found site (line=%d): %s for %s:%s, %s:%s, %s", site->action.line_num, site->site,
606 STRORDASH(ctx->srchost_str), STRORDASH(ctx->srcport_str), STRORDASH(ctx->dsthost_str), STRORDASH(ctx->dstport_str),
607 STRORDASH(ctx->sslctx->sni));
608 #endif /* WITHOUT_USERAUTH */
609
610 if (!site->port_btree && !site->port_acm && (site->action.precedence < ctx->filter_precedence)) {
611 log_finest_va("Rule precedence lower than conn filter precedence %d < %d (line=%d): %s, %s", site->action.precedence, ctx->filter_precedence, site->action.line_num, site->site, ctx->sslctx->sni);
612 return NULL;
613 }
614
615 #ifdef DEBUG_PROXY
616 if (site->all_sites)
617 log_finest_va("Match all sni (line=%d): %s, %s", site->action.line_num, site->site, ctx->sslctx->sni);
618 else if (site->exact)
619 log_finest_va("Match exact with sni (line=%d): %s, %s", site->action.line_num, site->site, ctx->sslctx->sni);
620 else
621 log_finest_va("Match substring in sni (line=%d): %s, %s", site->action.line_num, site->site, ctx->sslctx->sni);
622 #endif /* DEBUG_PROXY */
623
624 filter_action_t *port_action = pxy_conn_filter_port(ctx, site);
625 if (port_action)
626 return port_action;
627
628 return &site->action;
629 }
630
631 static filter_action_t * NONNULL(1,2)
protossl_filter_match_cn(pxy_conn_ctx_t * ctx,filter_list_t * list)632 protossl_filter_match_cn(pxy_conn_ctx_t *ctx, filter_list_t *list)
633 {
634 filter_site_t *site = NULL;
635
636 // ballpark figures
637 #define MAX_CN_LEN 4096
638 #define MAX_CN_TOKENS 100
639
640 int argc = 0;
641 char *p, *last = NULL;
642
643 size_t len = strlen(ctx->sslctx->ssl_names);
644
645 if (len > MAX_CN_LEN) {
646 log_err_level_printf(LOG_WARNING, "Skip too long common names, max len %d: %s\n", MAX_CN_LEN, ctx->sslctx->ssl_names);
647 return NULL;
648 }
649
650 // Do not tokenize ssl_names if there is no rule to match exact common names
651 if (list->cn_btree) {
652 // strtok_r() modifies the string param, so copy ssl_names to a local var and pass it to strtok_r()
653 char _cn[len + 1];
654 memcpy(_cn, ctx->sslctx->ssl_names, len);
655 _cn[len] = '\0';
656
657 for ((p = strtok_r(_cn, "/", &last));
658 p;
659 (p = strtok_r(NULL, "/", &last))) {
660 if (argc++ < MAX_CN_TOKENS) {
661 site = filter_site_exact_match(list->cn_btree, p);
662 if (site) {
663 log_finest_va("Match exact with common name (%d) (line=%d): %s, %s", argc, site->action.line_num, p, ctx->sslctx->ssl_names);
664 break;
665 }
666 }
667 else {
668 log_err_level_printf(LOG_WARNING, "Too many tokens in common names, max tokens %d: %s\n", MAX_CN_TOKENS, ctx->sslctx->ssl_names);
669 break;
670 }
671 }
672 }
673
674 if (!site) {
675 site = filter_site_substring_match(list->cn_acm, ctx->sslctx->ssl_names);
676 if (site)
677 log_finest_va("Match substring in common names (line=%d): %s, %s", site->action.line_num, site->site, ctx->sslctx->ssl_names);
678 }
679
680 if (!site)
681 return NULL;
682
683 #ifndef WITHOUT_USERAUTH
684 log_fine_va("Found site (line=%d): %s for %s:%s, %s:%s, %s, %s, %s", site->action.line_num, site->site,
685 STRORDASH(ctx->srchost_str), STRORDASH(ctx->srcport_str), STRORDASH(ctx->dsthost_str), STRORDASH(ctx->dstport_str),
686 STRORDASH(ctx->user), STRORDASH(ctx->desc), STRORDASH(ctx->sslctx->ssl_names));
687 #else /* WITHOUT_USERAUTH */
688 log_fine_va("Found site (line=%d): %s for %s:%s, %s:%s, %s", site->action.line_num, site->site,
689 STRORDASH(ctx->srchost_str), STRORDASH(ctx->srcport_str), STRORDASH(ctx->dsthost_str), STRORDASH(ctx->dstport_str),
690 STRORDASH(ctx->sslctx->ssl_names));
691 #endif /* WITHOUT_USERAUTH */
692
693 if (!site->port_btree && !site->port_acm && (site->action.precedence < ctx->filter_precedence)) {
694 log_finest_va("Rule precedence lower than conn filter precedence %d < %d (line=%d): %s, %s", site->action.precedence, ctx->filter_precedence, site->action.line_num, site->site, ctx->sslctx->ssl_names);
695 return NULL;
696 }
697
698 if (site->all_sites)
699 log_finest_va("Match all common names (line=%d): %s, %s", site->action.line_num, site->site, ctx->sslctx->ssl_names);
700
701 filter_action_t *port_action = pxy_conn_filter_port(ctx, site);
702 if (port_action)
703 return port_action;
704
705 return &site->action;
706 }
707
708 static filter_action_t * NONNULL(1,2)
protossl_filter(pxy_conn_ctx_t * ctx,filter_list_t * list)709 protossl_filter(pxy_conn_ctx_t *ctx, filter_list_t *list)
710 {
711 filter_action_t *action_sni = NULL;
712 filter_action_t *action_cn = NULL;
713
714 if (ctx->sslctx->sni) {
715 if (!(action_sni = protossl_filter_match_sni(ctx, list))) {
716 #ifndef WITHOUT_USERAUTH
717 log_finest_va("No filter match with sni: %s:%s, %s:%s, %s, %s, %s, %s",
718 STRORDASH(ctx->srchost_str), STRORDASH(ctx->srcport_str), STRORDASH(ctx->dsthost_str), STRORDASH(ctx->dstport_str),
719 STRORDASH(ctx->user), STRORDASH(ctx->desc), STRORDASH(ctx->sslctx->sni), STRORDASH(ctx->sslctx->ssl_names));
720 #else /* WITHOUT_USERAUTH */
721 log_finest_va("No filter match with sni: %s:%s, %s:%s, %s, %s",
722 STRORDASH(ctx->srchost_str), STRORDASH(ctx->srcport_str), STRORDASH(ctx->dsthost_str), STRORDASH(ctx->dstport_str),
723 STRORDASH(ctx->sslctx->sni), STRORDASH(ctx->sslctx->ssl_names));
724 #endif /* !WITHOUT_USERAUTH */
725 }
726 }
727
728 if (ctx->sslctx->ssl_names) {
729 if (!(action_cn = protossl_filter_match_cn(ctx, list))) {
730 #ifndef WITHOUT_USERAUTH
731 log_finest_va("No filter match with common names: %s:%s, %s:%s, %s, %s, %s, %s",
732 STRORDASH(ctx->srchost_str), STRORDASH(ctx->srcport_str), STRORDASH(ctx->dsthost_str), STRORDASH(ctx->dstport_str),
733 STRORDASH(ctx->user), STRORDASH(ctx->desc), STRORDASH(ctx->sslctx->sni), STRORDASH(ctx->sslctx->ssl_names));
734 #else /* WITHOUT_USERAUTH */
735 log_finest_va("No filter match with common names: %s:%s, %s:%s, %s, %s",
736 STRORDASH(ctx->srchost_str), STRORDASH(ctx->srcport_str), STRORDASH(ctx->dsthost_str), STRORDASH(ctx->dstport_str),
737 STRORDASH(ctx->sslctx->sni), STRORDASH(ctx->sslctx->ssl_names));
738 #endif /* !WITHOUT_USERAUTH */
739 }
740 }
741
742 if (action_sni || action_cn)
743 return pxy_conn_set_filter_action(action_sni, action_cn
744 #ifdef DEBUG_PROXY
745 , ctx, ctx->sslctx->sni, ctx->sslctx->ssl_names
746 #endif /* DEBUG_PROXY */
747 );
748
749 return NULL;
750 }
751
752 static void
protossl_reconnect_srvdst(pxy_conn_ctx_t * ctx)753 protossl_reconnect_srvdst(pxy_conn_ctx_t *ctx)
754 {
755 log_fine("ENTER");
756
757 // Reconnect only once
758 ctx->sslctx->reconnected = 1;
759
760 ctx->srvdst.free(ctx->srvdst.bev, ctx);
761 ctx->srvdst.bev = NULL;
762 ctx->srvdst.ssl = NULL;
763 ctx->connected = 0;
764
765 if (protossl_conn_connect(ctx) == -1) {
766 return;
767 }
768
769 if (bufferevent_socket_connect(ctx->srvdst.bev, (struct sockaddr *)&ctx->dstaddr, ctx->dstaddrlen) == -1) {
770 log_err_level(LOG_CRIT, "bufferevent_socket_connect for srvdst failed");
771 pxy_conn_term(ctx, 1);
772 }
773 }
774
775 static int
protossl_apply_filter(pxy_conn_ctx_t * ctx)776 protossl_apply_filter(pxy_conn_ctx_t *ctx)
777 {
778 int rv = 0;
779 filter_action_t *a;
780 if ((a = pxy_conn_filter(ctx, protossl_filter))) {
781 unsigned int action = pxy_conn_translate_filter_action(ctx, a);
782
783 ctx->filter_precedence = action & FILTER_PRECEDENCE;
784
785 if (action & FILTER_ACTION_DIVERT) {
786 ctx->deferred_action = FILTER_ACTION_NONE;
787 ctx->divert = 1;
788 }
789 else if (action & FILTER_ACTION_SPLIT) {
790 ctx->deferred_action = FILTER_ACTION_NONE;
791 ctx->divert = 0;
792 }
793 else if (action & FILTER_ACTION_PASS) {
794 ctx->deferred_action = FILTER_ACTION_NONE;
795 ctx->pass = 1;
796 rv = 1;
797 }
798 else if (action & FILTER_ACTION_BLOCK) {
799 // Always defer block action, the only action we can defer from this point on
800 // This block action should override any deferred pass action,
801 // because the current rule must have a higher precedence
802 log_fine("Deferring block action");
803 ctx->deferred_action = FILTER_ACTION_BLOCK;
804 }
805 //else { /* FILTER_ACTION_MATCH */ }
806
807 // Filtering rules at higher precedence can enable/disable logging
808 if (action & FILTER_LOG_CONNECT)
809 ctx->log_connect = 1;
810 else if (action & FILTER_LOG_NOCONNECT)
811 ctx->log_connect = 0;
812 if (action & FILTER_LOG_MASTER)
813 ctx->log_master = 1;
814 else if (action & FILTER_LOG_NOMASTER)
815 ctx->log_master = 0;
816 if (action & FILTER_LOG_CERT)
817 ctx->log_cert = 1;
818 else if (action & FILTER_LOG_NOCERT)
819 ctx->log_cert = 0;
820 if (action & FILTER_LOG_CONTENT)
821 ctx->log_content = 1;
822 else if (action & FILTER_LOG_NOCONTENT)
823 ctx->log_content = 0;
824 if (action & FILTER_LOG_PCAP)
825 ctx->log_pcap = 1;
826 else if (action & FILTER_LOG_NOPCAP)
827 ctx->log_pcap = 0;
828 #ifndef WITHOUT_MIRROR
829 if (action & FILTER_LOG_MIRROR)
830 ctx->log_mirror = 1;
831 else if (action & FILTER_LOG_NOMIRROR)
832 ctx->log_mirror = 0;
833 #endif /* !WITHOUT_MIRROR */
834
835 if (a->conn_opts) {
836 ctx->conn_opts = a->conn_opts;
837
838 if (ctx->conn_opts->reconnect_ssl) {
839 // Reconnect srvdst only once, if ReconnectSSL set in the rule
840 if (!ctx->sslctx->reconnected) {
841 protossl_reconnect_srvdst(ctx);
842 // Return immediately to avoid applying deferred pass action
843 return 1;
844 } else {
845 log_finest("Already reconnected once, will not reconnect again");
846 }
847 }
848 }
849 }
850
851 // Cannot defer pass action any longer
852 // Match action should not override pass action, hence no 'else if'
853 if (ctx->deferred_action & FILTER_ACTION_PASS) {
854 log_fine("Applying deferred pass action");
855 ctx->deferred_action = FILTER_ACTION_NONE;
856 ctx->pass = 1;
857 rv = 1;
858 }
859
860 return rv;
861 }
862
863 /*
864 * Create new SSL context for the incoming connection, based on the original
865 * destination SSL certificate.
866 * Returns NULL if no suitable certificate could be found or the site should
867 * be passed through.
868 */
869 static SSL *
protossl_srcssl_create(pxy_conn_ctx_t * ctx,SSL * origssl)870 protossl_srcssl_create(pxy_conn_ctx_t *ctx, SSL *origssl)
871 {
872 cert_t *cert;
873
874 cachemgr_dsess_set((struct sockaddr*)&ctx->dstaddr,
875 ctx->dstaddrlen, ctx->sslctx->sni,
876 SSL_get0_session(origssl));
877
878 ctx->sslctx->origcrt = SSL_get_peer_certificate(origssl);
879
880 if (OPTS_DEBUG(ctx->global)) {
881 if (ctx->sslctx->origcrt) {
882 log_dbg_printf("===> Original server certificate:\n");
883 protossl_debug_crt(ctx->sslctx->origcrt);
884 } else {
885 log_dbg_printf("===> Original server has no cert!\n");
886 }
887 }
888
889 cert = protossl_srccert_create(ctx);
890 if (!cert)
891 return NULL;
892
893 if (OPTS_DEBUG(ctx->global)) {
894 log_dbg_printf("===> Forged server certificate:\n");
895 protossl_debug_crt(cert->crt);
896 }
897
898 if (WANT_CONNECT_LOG(ctx) || ctx->spec->opts->filter) {
899 ctx->sslctx->ssl_names = ssl_x509_names_to_str(ctx->sslctx->origcrt ?
900 ctx->sslctx->origcrt :
901 cert->crt);
902 if (!ctx->sslctx->ssl_names)
903 ctx->enomem = 1;
904 }
905
906 // Defers any block action until HTTP filter application
907 // or until the first src readcb of non-http protos
908 if (protossl_apply_filter(ctx)) {
909 cert_free(cert);
910 return NULL;
911 }
912
913 SSL_CTX *sslctx = protossl_srcsslctx_create(ctx, cert->crt, cert->chain,
914 cert->key);
915 cert_free(cert);
916 if (!sslctx)
917 return NULL;
918 SSL *ssl = SSL_new(sslctx);
919 SSL_CTX_free(sslctx); /* SSL_new() increments refcount */
920 if (!ssl) {
921 ctx->enomem = 1;
922 return NULL;
923 }
924 #ifdef SSL_MODE_RELEASE_BUFFERS
925 /* lower memory footprint for idle connections */
926 SSL_set_mode(ssl, SSL_get_mode(ssl) | SSL_MODE_RELEASE_BUFFERS);
927 #endif /* SSL_MODE_RELEASE_BUFFERS */
928 return ssl;
929 }
930
931 #ifndef OPENSSL_NO_TLSEXT
932 /*
933 * OpenSSL servername callback, called when OpenSSL receives a servername
934 * TLS extension in the clientHello. Must switch to a new SSL_CTX with
935 * a different certificate if we want to replace the server cert here.
936 * We generate a new certificate if the current one does not match the
937 * supplied servername. This should only happen if the original destination
938 * server supplies a certificate which does not match the server name we
939 * indicate to it.
940 */
941 static int
protossl_ossl_servername_cb(SSL * ssl,UNUSED int * al,void * arg)942 protossl_ossl_servername_cb(SSL *ssl, UNUSED int *al, void *arg)
943 {
944 pxy_conn_ctx_t *ctx = arg;
945 const char *sn;
946 X509 *sslcrt;
947
948 if (!(sn = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name)))
949 return SSL_TLSEXT_ERR_NOACK;
950
951 if (!ctx->sslctx->sni) {
952 if (OPTS_DEBUG(ctx->global)) {
953 log_dbg_printf("Warning: SNI parser yielded no "
954 "hostname, copying OpenSSL one: "
955 "[NULL] != [%s]\n", sn);
956 }
957 ctx->sslctx->sni = strdup(sn);
958 if (!ctx->sslctx->sni) {
959 ctx->enomem = 1;
960 return SSL_TLSEXT_ERR_NOACK;
961 }
962 }
963 if (OPTS_DEBUG(ctx->global)) {
964 if (!!strcmp(sn, ctx->sslctx->sni)) {
965 /*
966 * This may happen if the client resumes a session, but
967 * uses a different SNI hostname when resuming than it
968 * used when the session was created. OpenSSL
969 * correctly ignores the SNI in the ClientHello in this
970 * case, but since we have already sent the SNI onwards
971 * to the original destination, there is no way back.
972 * We log an error and hope this never happens.
973 */
974 log_dbg_printf("Warning: SNI parser yielded different "
975 "hostname than OpenSSL callback for "
976 "the same ClientHello message: "
977 "[%s] != [%s]\n", ctx->sslctx->sni, sn);
978 }
979 }
980
981 /* generate a new certificate with sn as additional altSubjectName
982 * and replace it both in the current SSL ctx and in the cert cache */
983 if (ctx->conn_opts->allow_wrong_host && !ctx->sslctx->immutable_cert &&
984 !ssl_x509_names_match((sslcrt = SSL_get_certificate(ssl)), sn)) {
985 X509 *newcrt;
986 SSL_CTX *newsslctx;
987
988 if (OPTS_DEBUG(ctx->global)) {
989 log_dbg_printf("Certificate cache: UPDATE "
990 "(SNI mismatch)\n");
991 }
992 newcrt = ssl_x509_forge(ctx->conn_opts->cacrt, ctx->conn_opts->cakey,
993 sslcrt, ctx->global->leafkey,
994 sn, ctx->conn_opts->leafcrlurl);
995 if (!newcrt) {
996 ctx->enomem = 1;
997 return SSL_TLSEXT_ERR_NOACK;
998 }
999 cachemgr_fkcrt_set(ctx->sslctx->origcrt, newcrt);
1000 ctx->sslctx->generated_cert = 1;
1001 if (OPTS_DEBUG(ctx->global)) {
1002 log_dbg_printf("===> Updated forged server "
1003 "certificate:\n");
1004 protossl_debug_crt(newcrt);
1005 }
1006 if (WANT_CONNECT_LOG(ctx) || ctx->spec->opts->filter) {
1007 if (ctx->sslctx->ssl_names) {
1008 free(ctx->sslctx->ssl_names);
1009 }
1010 ctx->sslctx->ssl_names = ssl_x509_names_to_str(newcrt);
1011 if (!ctx->sslctx->ssl_names) {
1012 ctx->enomem = 1;
1013 }
1014 }
1015 if (WANT_CONNECT_LOG(ctx) || ctx->global->certgendir) {
1016 if (ctx->sslctx->usedcrtfpr) {
1017 free(ctx->sslctx->usedcrtfpr);
1018 }
1019 ctx->sslctx->usedcrtfpr = ssl_x509_fingerprint(newcrt, 0);
1020 if (!ctx->sslctx->usedcrtfpr) {
1021 ctx->enomem = 1;
1022 }
1023 }
1024
1025 newsslctx = protossl_srcsslctx_create(ctx, newcrt, ctx->conn_opts->chain,
1026 ctx->global->leafkey);
1027 if (!newsslctx) {
1028 X509_free(newcrt);
1029 return SSL_TLSEXT_ERR_NOACK;
1030 }
1031 SSL_set_SSL_CTX(ssl, newsslctx); /* decr's old incr new refc */
1032 SSL_CTX_free(newsslctx);
1033 X509_free(newcrt);
1034 } else if (OPTS_DEBUG(ctx->global)) {
1035 log_dbg_printf("Certificate cache: KEEP (SNI match or "
1036 "target mode)\n");
1037 }
1038
1039 return SSL_TLSEXT_ERR_OK;
1040 }
1041 #endif /* !OPENSSL_NO_TLSEXT */
1042
1043 /*
1044 * Create new SSL context for outgoing connections to the original destination.
1045 * If hostname sni is provided, use it for Server Name Indication.
1046 */
1047 SSL *
protossl_dstssl_create(pxy_conn_ctx_t * ctx)1048 protossl_dstssl_create(pxy_conn_ctx_t *ctx)
1049 {
1050 SSL_CTX *sslctx;
1051 SSL *ssl;
1052 SSL_SESSION *sess;
1053
1054 sslctx = SSL_CTX_new(ctx->conn_opts->sslmethod());
1055 if (!sslctx) {
1056 ctx->enomem = 1;
1057 return NULL;
1058 }
1059
1060 protossl_sslctx_setoptions(sslctx, ctx);
1061
1062 #if (OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)) || (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x20702000L)
1063 if (ctx->conn_opts->minsslversion) {
1064 if (SSL_CTX_set_min_proto_version(sslctx, ctx->conn_opts->minsslversion) == 0) {
1065 SSL_CTX_free(sslctx);
1066 return NULL;
1067 }
1068 }
1069 if (ctx->conn_opts->maxsslversion) {
1070 if (SSL_CTX_set_max_proto_version(sslctx, ctx->conn_opts->maxsslversion) == 0) {
1071 SSL_CTX_free(sslctx);
1072 return NULL;
1073 }
1074 }
1075 // ForceSSLproto has precedence
1076 if (ctx->conn_opts->sslversion) {
1077 if (SSL_CTX_set_min_proto_version(sslctx, ctx->conn_opts->sslversion) == 0 ||
1078 SSL_CTX_set_max_proto_version(sslctx, ctx->conn_opts->sslversion) == 0) {
1079 SSL_CTX_free(sslctx);
1080 return NULL;
1081 }
1082 }
1083 #endif /* OPENSSL_VERSION_NUMBER >= 0x10100000L */
1084
1085 if (ctx->conn_opts->verify_peer) {
1086 SSL_CTX_set_verify(sslctx, SSL_VERIFY_PEER, NULL);
1087 SSL_CTX_set_default_verify_paths(sslctx);
1088 } else {
1089 SSL_CTX_set_verify(sslctx, SSL_VERIFY_NONE, NULL);
1090 }
1091
1092 if (ctx->conn_opts->clientcrt &&
1093 (SSL_CTX_use_certificate(sslctx, ctx->conn_opts->clientcrt) != 1)) {
1094 log_dbg_printf("loading dst client certificate failed\n");
1095 SSL_CTX_free(sslctx);
1096 return NULL;
1097 }
1098 if (ctx->conn_opts->clientkey &&
1099 (SSL_CTX_use_PrivateKey(sslctx, ctx->conn_opts->clientkey) != 1)) {
1100 log_dbg_printf("loading dst client key failed\n");
1101 SSL_CTX_free(sslctx);
1102 return NULL;
1103 }
1104
1105 ssl = SSL_new(sslctx);
1106 SSL_CTX_free(sslctx); /* SSL_new() increments refcount */
1107 if (!ssl) {
1108 ctx->enomem = 1;
1109 return NULL;
1110 }
1111 #ifndef OPENSSL_NO_TLSEXT
1112 if (ctx->sslctx->sni) {
1113 SSL_set_tlsext_host_name(ssl, ctx->sslctx->sni);
1114 }
1115 #endif /* !OPENSSL_NO_TLSEXT */
1116
1117 #ifdef SSL_MODE_RELEASE_BUFFERS
1118 /* lower memory footprint for idle connections */
1119 SSL_set_mode(ssl, SSL_get_mode(ssl) | SSL_MODE_RELEASE_BUFFERS);
1120 #endif /* SSL_MODE_RELEASE_BUFFERS */
1121
1122 /* session resuming based on remote endpoint address and port */
1123 sess = cachemgr_dsess_get((struct sockaddr *)&ctx->dstaddr,
1124 ctx->dstaddrlen, ctx->sslctx->sni); /* new sess inst */
1125 if (sess) {
1126 if (OPTS_DEBUG(ctx->global)) {
1127 log_dbg_printf("Attempt reuse dst SSL session\n");
1128 }
1129 SSL_set_session(ssl, sess); /* increments sess refcount */
1130 SSL_SESSION_free(sess);
1131 }
1132
1133 return ssl;
1134 }
1135
1136 /*
1137 * Set up a bufferevent structure for either a dst or src connection,
1138 * optionally with or without SSL. Sets all callbacks, enables read
1139 * and write events, but does not call bufferevent_socket_connect().
1140 *
1141 * For dst connections, pass -1 as fd. Pass a pointer to an initialized
1142 * SSL struct as ssl if the connection should use SSL.
1143 *
1144 * Returns pointer to initialized bufferevent structure, as returned
1145 * by bufferevent_socket_new() or bufferevent_openssl_socket_new().
1146 */
1147 static struct bufferevent * NONNULL(1,3)
protossl_bufferevent_setup(pxy_conn_ctx_t * ctx,evutil_socket_t fd,SSL * ssl)1148 protossl_bufferevent_setup(pxy_conn_ctx_t *ctx, evutil_socket_t fd, SSL *ssl)
1149 {
1150 log_finest_va("ENTER, fd=%d", fd);
1151
1152 struct bufferevent *bev = bufferevent_openssl_socket_new(ctx->thr->evbase, fd, ssl,
1153 ((fd == -1) ? BUFFEREVENT_SSL_CONNECTING : BUFFEREVENT_SSL_ACCEPTING), BEV_OPT_DEFER_CALLBACKS);
1154 if (!bev) {
1155 log_err_level_printf(LOG_CRIT, "Error creating bufferevent socket\n");
1156 return NULL;
1157 }
1158 #if LIBEVENT_VERSION_NUMBER >= 0x02010000
1159 log_finest_va("bufferevent_openssl_set_allow_dirty_shutdown, fd=%d", fd);
1160
1161 /* Prevent unclean (dirty) shutdowns to cause error
1162 * events on the SSL socket bufferevent. */
1163 bufferevent_openssl_set_allow_dirty_shutdown(bev, 1);
1164 #endif /* LIBEVENT_VERSION_NUMBER >= 0x02010000 */
1165
1166 // @attention Do not set callbacks here, we do not set r cb for tcp/ssl srvdst
1167 //bufferevent_setcb(bev, pxy_bev_readcb, pxy_bev_writecb, pxy_bev_eventcb, ctx);
1168 // @attention Do not enable r/w events here, we do not set r cb for tcp/ssl srvdst
1169 // Also, to avoid r/w cb before connected, we should enable r/w events after the conn is connected
1170 //bufferevent_enable(bev, EV_READ|EV_WRITE);
1171 return bev;
1172 }
1173
1174 static struct bufferevent * NONNULL(1,3)
protossl_bufferevent_setup_child(pxy_conn_child_ctx_t * ctx,evutil_socket_t fd,SSL * ssl)1175 protossl_bufferevent_setup_child(pxy_conn_child_ctx_t *ctx, evutil_socket_t fd, SSL *ssl)
1176 {
1177 log_finest_va("ENTER, fd=%d", fd);
1178
1179 struct bufferevent *bev = bufferevent_openssl_socket_new(ctx->conn->thr->evbase, fd, ssl,
1180 ((fd == -1) ? BUFFEREVENT_SSL_CONNECTING : BUFFEREVENT_SSL_ACCEPTING), BEV_OPT_DEFER_CALLBACKS);
1181 if (!bev) {
1182 log_err_level_printf(LOG_CRIT, "Error creating bufferevent socket\n");
1183 return NULL;
1184 }
1185
1186 #if LIBEVENT_VERSION_NUMBER >= 0x02010000
1187 log_finest_va("bufferevent_openssl_set_allow_dirty_shutdown, fd=%d", fd);
1188
1189 /* Prevent unclean (dirty) shutdowns to cause error
1190 * events on the SSL socket bufferevent. */
1191 bufferevent_openssl_set_allow_dirty_shutdown(bev, 1);
1192 #endif /* LIBEVENT_VERSION_NUMBER >= 0x02010000 */
1193
1194 bufferevent_setcb(bev, pxy_bev_readcb_child, pxy_bev_writecb_child, pxy_bev_eventcb_child, ctx);
1195
1196 // @attention We cannot enable events here, because src events will be deferred until after dst is connected
1197 // Also, to avoid r/w cb before connected, we should enable r/w events after the conn is connected
1198 //bufferevent_enable(bev, EV_READ|EV_WRITE);
1199 return bev;
1200 }
1201
1202 /*
1203 * Free bufferenvent and close underlying socket properly.
1204 * For OpenSSL bufferevents, this will shutdown the SSL connection.
1205 */
1206 static void
protossl_bufferevent_free_and_close_fd(struct bufferevent * bev,pxy_conn_ctx_t * ctx)1207 protossl_bufferevent_free_and_close_fd(struct bufferevent *bev, pxy_conn_ctx_t *ctx)
1208 {
1209 SSL *ssl = bufferevent_openssl_get_ssl(bev); /* does not inc refc */
1210 struct bufferevent *ubev = bufferevent_get_underlying(bev);
1211 evutil_socket_t fd;
1212
1213 if (ubev) {
1214 fd = bufferevent_getfd(ubev);
1215 } else {
1216 fd = bufferevent_getfd(bev);
1217 }
1218
1219 log_finer_va("in=%zu, out=%zu, fd=%d", evbuffer_get_length(bufferevent_get_input(bev)), evbuffer_get_length(bufferevent_get_output(bev)), fd);
1220
1221 // @see https://stackoverflow.com/questions/31688709/knowing-all-callbacks-have-run-with-libevent-and-bufferevent-free
1222 bufferevent_setcb(bev, NULL, NULL, NULL, NULL);
1223
1224 /*
1225 * From the libevent book: SSL_RECEIVED_SHUTDOWN tells
1226 * SSL_shutdown to act as if we had already received a close
1227 * notify from the other end. SSL_shutdown will then send the
1228 * final close notify in reply. The other end will receive the
1229 * close notify and send theirs. By this time, we will have
1230 * already closed the socket and the other end's real close
1231 * notify will never be received. In effect, both sides will
1232 * think that they have completed a clean shutdown and keep
1233 * their sessions valid. This strategy will fail if the socket
1234 * is not ready for writing, in which case this hack will lead
1235 * to an unclean shutdown and lost session on the other end.
1236 *
1237 * Note that in the case of autossl, the SSL object operates on
1238 * a BIO wrapper around the underlying bufferevent.
1239 */
1240 SSL_set_shutdown(ssl, SSL_RECEIVED_SHUTDOWN);
1241 SSL_shutdown(ssl);
1242
1243 bufferevent_disable(bev, EV_READ|EV_WRITE);
1244 if (ubev) {
1245 bufferevent_disable(ubev, EV_READ|EV_WRITE);
1246 bufferevent_setfd(ubev, -1);
1247 bufferevent_setcb(ubev, NULL, NULL, NULL, NULL);
1248 bufferevent_free(ubev);
1249 }
1250 bufferevent_free(bev);
1251
1252 if (OPTS_DEBUG(ctx->global)) {
1253 char *str = ssl_ssl_state_to_str(ssl, "SSL_free() in state ", 1);
1254 if (str)
1255 log_dbg_print_free(str);
1256 }
1257 #ifdef DEBUG_PROXY
1258 char *str = ssl_ssl_state_to_str(ssl, "SSL_free() in state ", 0);
1259 if (str) {
1260 log_finer_va("fd=%d, %s", fd, str);
1261 free(str);
1262 }
1263 #endif /* DEBUG_PROXY */
1264
1265 SSL_free(ssl);
1266 /* bufferevent_getfd() returns -1 if no file descriptor is associated
1267 * with the bufferevent */
1268 if (fd >= 0)
1269 evutil_closesocket(fd);
1270 }
1271
1272 void
protossl_free(pxy_conn_ctx_t * ctx)1273 protossl_free(pxy_conn_ctx_t *ctx)
1274 {
1275 if (ctx->sslctx->ssl_names) {
1276 free(ctx->sslctx->ssl_names);
1277 }
1278 if (ctx->sslctx->origcrtfpr) {
1279 free(ctx->sslctx->origcrtfpr);
1280 }
1281 if (ctx->sslctx->usedcrtfpr) {
1282 free(ctx->sslctx->usedcrtfpr);
1283 }
1284 if (ctx->sslctx->origcrt) {
1285 X509_free(ctx->sslctx->origcrt);
1286 }
1287 if (ctx->sslctx->sni) {
1288 free(ctx->sslctx->sni);
1289 }
1290 if (ctx->sslctx->srvdst_ssl_version) {
1291 free(ctx->sslctx->srvdst_ssl_version);
1292 }
1293 if (ctx->sslctx->srvdst_ssl_cipher) {
1294 free(ctx->sslctx->srvdst_ssl_cipher);
1295 }
1296 free(ctx->sslctx);
1297 // It is necessary to NULL the sslctx to prevent passthrough mode trying to access it (signal 11 crash)
1298 ctx->sslctx = NULL;
1299 }
1300
1301 #ifndef OPENSSL_NO_TLSEXT
1302 /*
1303 * The SNI hostname has been resolved. Fill the first resolved address into
1304 * the context and continue connecting.
1305 */
1306 static void
protossl_sni_resolve_cb(int errcode,struct evutil_addrinfo * ai,void * arg)1307 protossl_sni_resolve_cb(int errcode, struct evutil_addrinfo *ai, void *arg)
1308 {
1309 pxy_conn_ctx_t *ctx = arg;
1310
1311 log_finest("ENTER");
1312
1313 if (errcode) {
1314 log_err_printf("Cannot resolve SNI hostname '%s': %s\n", ctx->sslctx->sni, evutil_gai_strerror(errcode));
1315 evutil_closesocket(ctx->fd);
1316 pxy_conn_ctx_free(ctx, 1);
1317 return;
1318 }
1319
1320 memcpy(&ctx->dstaddr, ai->ai_addr, ai->ai_addrlen);
1321 ctx->dstaddrlen = ai->ai_addrlen;
1322 evutil_freeaddrinfo(ai);
1323 pxy_conn_connect(ctx);
1324 }
1325 #endif /* !OPENSSL_NO_TLSEXT */
1326
1327 /*
1328 * The src fd is readable. This is used to sneak-preview the SNI on SSL
1329 * connections. If ctx->ev is NULL, it was called manually for a non-SSL
1330 * connection. If ctx->opts->passthrough is set, it was called a second time
1331 * after the first ssl callout failed because of client cert auth.
1332 */
1333 static void
protossl_fd_readcb(evutil_socket_t fd,UNUSED short what,void * arg)1334 protossl_fd_readcb(evutil_socket_t fd, UNUSED short what, void *arg)
1335 {
1336 pxy_conn_ctx_t *ctx = arg;
1337
1338 log_finest("ENTER");
1339
1340 event_free(ctx->ev);
1341 ctx->ev = NULL;
1342
1343 // Child connections will use the sni info obtained by the parent conn
1344 /* for SSL, peek ClientHello and parse SNI from it */
1345
1346 unsigned char buf[1024];
1347 ssize_t n;
1348 const unsigned char *chello;
1349 int rv;
1350
1351 n = recv(fd, buf, sizeof(buf), MSG_PEEK);
1352 if (n == -1) {
1353 log_err_printf("Error peeking on fd, aborting connection\n");
1354 log_fine("Error peeking on fd, aborting connection");
1355 goto out;
1356 }
1357 if (n == 0) {
1358 /* socket got closed while we were waiting */
1359 log_err_printf("Socket got closed while waiting\n");
1360 log_fine("Socket got closed while waiting");
1361 goto out;
1362 }
1363
1364 rv = ssl_tls_clienthello_parse(buf, n, 0, &chello, &ctx->sslctx->sni);
1365 if ((rv == 1) && !chello) {
1366 log_err_printf("Peeking did not yield a (truncated) ClientHello message, aborting connection\n");
1367 log_fine("Peeking did not yield a (truncated) ClientHello message, aborting connection");
1368 goto out;
1369 }
1370 if (OPTS_DEBUG(ctx->global)) {
1371 log_dbg_printf("SNI peek: [%s] [%s], fd=%d\n", ctx->sslctx->sni ? ctx->sslctx->sni : "n/a",
1372 ((rv == 1) && chello) ? "incomplete" : "complete", ctx->fd);
1373 }
1374 if ((rv == 1) && chello && (ctx->sslctx->sni_peek_retries++ < 50)) {
1375 /* ssl_tls_clienthello_parse indicates that we
1376 * should retry later when we have more data, and we
1377 * haven't reached the maximum retry count yet.
1378 * Reschedule this event as timeout-only event in
1379 * order to prevent busy looping over the read event.
1380 * Because we only peeked at the pending bytes and
1381 * never actually read them, fd is still ready for
1382 * reading now. We use 25 * 0.2 s = 5 s timeout. */
1383 struct timeval retry_delay = {0, 100};
1384
1385 ctx->ev = event_new(ctx->thr->evbase, fd, 0, protossl_fd_readcb, ctx);
1386 if (!ctx->ev) {
1387 log_err_level(LOG_CRIT, "Error creating retry event, aborting connection");
1388 goto out;
1389 }
1390 if (event_add(ctx->ev, &retry_delay) == -1)
1391 goto out;
1392 return;
1393 }
1394
1395 if (ctx->sslctx->sni && !ctx->dstaddrlen && ctx->spec->sni_port) {
1396 char sniport[6];
1397 struct evutil_addrinfo hints;
1398
1399 memset(&hints, 0, sizeof(hints));
1400 hints.ai_family = ctx->af;
1401 hints.ai_flags = EVUTIL_AI_ADDRCONFIG;
1402 hints.ai_socktype = SOCK_STREAM;
1403 hints.ai_protocol = IPPROTO_TCP;
1404
1405 snprintf(sniport, sizeof(sniport), "%i", ctx->spec->sni_port);
1406 evdns_getaddrinfo(ctx->thr->dnsbase, ctx->sslctx->sni, sniport, &hints, protossl_sni_resolve_cb, ctx);
1407 return;
1408 }
1409
1410 pxy_conn_connect(ctx);
1411 return;
1412 out:
1413 evutil_closesocket(fd);
1414 pxy_conn_ctx_free(ctx, 1);
1415 }
1416
1417 void
protossl_init_conn(evutil_socket_t fd,UNUSED short what,void * arg)1418 protossl_init_conn(evutil_socket_t fd, UNUSED short what, void *arg)
1419 {
1420 pxy_conn_ctx_t *ctx = arg;
1421
1422 log_finest("ENTER");
1423
1424 event_free(ctx->ev);
1425 ctx->ev = NULL;
1426
1427 if (pxy_conn_init(ctx) == -1)
1428 return;
1429
1430 #ifdef OPENSSL_NO_TLSEXT
1431 pxy_conn_connect(ctx);
1432 return;
1433 #endif /* !OPENSSL_NO_TLSEXT */
1434
1435 /* for SSL, defer dst connection setup to initial_readcb */
1436 ctx->ev = event_new(ctx->thr->evbase, ctx->fd, EV_READ, protossl_fd_readcb, ctx);
1437 if (!ctx->ev)
1438 goto out;
1439
1440 if (event_add(ctx->ev, NULL) == -1) {
1441 log_finest("event_add failed");
1442 // Note that the timercb of the connection handling thread may try to access the ctx
1443 goto out;
1444 }
1445 return;
1446 out:
1447 evutil_closesocket(fd);
1448 pxy_conn_ctx_free(ctx, 1);
1449 }
1450
1451 int
protossl_setup_dst_ssl(pxy_conn_ctx_t * ctx)1452 protossl_setup_dst_ssl(pxy_conn_ctx_t *ctx)
1453 {
1454 ctx->dst.ssl = protossl_dstssl_create(ctx);
1455 if (!ctx->dst.ssl) {
1456 log_err_level_printf(LOG_CRIT, "Error creating SSL for dst\n");
1457 pxy_conn_term(ctx, 1);
1458 return -1;
1459 }
1460 return 0;
1461 }
1462
1463 static int NONNULL(1)
protossl_setup_srvdst_ssl(pxy_conn_ctx_t * ctx)1464 protossl_setup_srvdst_ssl(pxy_conn_ctx_t *ctx)
1465 {
1466 ctx->srvdst.ssl = protossl_dstssl_create(ctx);
1467 if (!ctx->srvdst.ssl) {
1468 log_err_level_printf(LOG_CRIT, "Error creating SSL for srvdst\n");
1469 pxy_conn_term(ctx, 1);
1470 return -1;
1471 }
1472 return 0;
1473 }
1474
1475 int
protossl_setup_srvdst(pxy_conn_ctx_t * ctx)1476 protossl_setup_srvdst(pxy_conn_ctx_t *ctx)
1477 {
1478 if (protossl_setup_srvdst_ssl(ctx) == -1) {
1479 return -1;
1480 }
1481
1482 ctx->srvdst.bev = protossl_bufferevent_setup(ctx, -1, ctx->srvdst.ssl);
1483 if (!ctx->srvdst.bev) {
1484 log_err_level_printf(LOG_CRIT, "Error creating srvdst\n");
1485 SSL_free(ctx->srvdst.ssl);
1486 ctx->srvdst.ssl = NULL;
1487 pxy_conn_term(ctx, 1);
1488 return -1;
1489 }
1490 ctx->srvdst.free = protossl_bufferevent_free_and_close_fd;
1491 return 0;
1492 }
1493
1494 int
protossl_conn_connect(pxy_conn_ctx_t * ctx)1495 protossl_conn_connect(pxy_conn_ctx_t *ctx)
1496 {
1497 log_finest("ENTER");
1498
1499 /* create server-side socket and eventbuffer */
1500 if (protossl_setup_srvdst(ctx) == -1) {
1501 return -1;
1502 }
1503
1504 // Disable and NULL r/w cbs, we do nothing for srvdst in r/w cbs
1505 bufferevent_setcb(ctx->srvdst.bev, NULL, NULL, pxy_bev_eventcb, ctx);
1506 return 0;
1507 }
1508
1509 int
protossl_setup_dst_ssl_child(pxy_conn_child_ctx_t * ctx)1510 protossl_setup_dst_ssl_child(pxy_conn_child_ctx_t *ctx)
1511 {
1512 // Children rely on the findings of parent
1513 ctx->dst.ssl = protossl_dstssl_create(ctx->conn);
1514 if (!ctx->dst.ssl) {
1515 log_err_level_printf(LOG_CRIT, "Error creating SSL\n");
1516 // pxy_conn_free()>pxy_conn_free_child() will close the fd, since we have a non-NULL src.bev now
1517 pxy_conn_term(ctx->conn, 1);
1518 return -1;
1519 }
1520 return 0;
1521 }
1522
1523 int
protossl_setup_dst_child(pxy_conn_child_ctx_t * ctx)1524 protossl_setup_dst_child(pxy_conn_child_ctx_t *ctx)
1525 {
1526 if (!ctx->conn->srvdst_xferred) {
1527 // Reuse srvdst of parent in the first child conn
1528 ctx->conn->srvdst_xferred = 1;
1529 ctx->srvdst_xferred = 1;
1530 ctx->dst = ctx->conn->srvdst;
1531 bufferevent_setcb(ctx->dst.bev, pxy_bev_readcb_child, pxy_bev_writecb_child, pxy_bev_eventcb_child, ctx);
1532 ctx->protoctx->bev_eventcb(ctx->dst.bev, BEV_EVENT_CONNECTED, ctx);
1533 } else {
1534 if (protossl_setup_dst_ssl_child(ctx) == -1) {
1535 return -1;
1536 }
1537
1538 ctx->dst.bev = protossl_bufferevent_setup_child(ctx, -1, ctx->dst.ssl);
1539 if (!ctx->dst.bev) {
1540 log_err_level_printf(LOG_CRIT, "Error creating dst bufferevent\n");
1541 SSL_free(ctx->dst.ssl);
1542 ctx->dst.ssl = NULL;
1543 pxy_conn_term(ctx->conn, 1);
1544 return -1;
1545 }
1546 ctx->dst.free = protossl_bufferevent_free_and_close_fd;
1547 }
1548 return 0;
1549 }
1550
1551 void
protossl_connect_child(pxy_conn_child_ctx_t * ctx)1552 protossl_connect_child(pxy_conn_child_ctx_t *ctx)
1553 {
1554 log_finest("ENTER");
1555
1556 /* create server-side socket and eventbuffer */
1557 protossl_setup_dst_child(ctx);
1558 }
1559
1560 static int NONNULL(1)
protossl_setup_src_ssl(pxy_conn_ctx_t * ctx)1561 protossl_setup_src_ssl(pxy_conn_ctx_t *ctx)
1562 {
1563 // @todo Make srvdst.ssl the origssl param
1564 if (ctx->src.ssl || (ctx->src.ssl = protossl_srcssl_create(ctx, ctx->srvdst.ssl))) {
1565 return 0;
1566 }
1567 else if (ctx->term) {
1568 return -1;
1569 }
1570 else if (!ctx->enomem && (ctx->pass || ctx->conn_opts->passthrough)) {
1571 log_err_level_printf(LOG_WARNING, "Falling back to passthrough\n");
1572 protopassthrough_engage(ctx);
1573 // report protocol change by returning 1
1574 return 1;
1575 }
1576 else if (ctx->sslctx->reconnected) {
1577 return -1;
1578 }
1579 pxy_conn_term(ctx, 1);
1580 return -1;
1581 }
1582
1583 int
protossl_setup_src_ssl_from_dst(pxy_conn_ctx_t * ctx)1584 protossl_setup_src_ssl_from_dst(pxy_conn_ctx_t *ctx)
1585 {
1586 // @attention We cannot engage passthrough mode upon ssl errors on already enabled src
1587 // This function is used by protoautossl only
1588 if (ctx->src.ssl || (ctx->src.ssl = protossl_srcssl_create(ctx, ctx->dst.ssl))) {
1589 return 0;
1590 }
1591 else if (ctx->term) {
1592 return -1;
1593 }
1594 pxy_conn_term(ctx, 1);
1595 return -1;
1596 }
1597
1598 int
protossl_setup_src_ssl_from_child_dst(pxy_conn_child_ctx_t * ctx)1599 protossl_setup_src_ssl_from_child_dst(pxy_conn_child_ctx_t *ctx)
1600 {
1601 // @attention We cannot engage passthrough mode upon ssl errors on already enabled src
1602 // This function is used by protoautossl only
1603 if (ctx->conn->src.ssl || (ctx->conn->src.ssl = protossl_srcssl_create(ctx->conn, ctx->dst.ssl))) {
1604 return 0;
1605 }
1606 else if (ctx->conn->term) {
1607 return -1;
1608 }
1609 pxy_conn_term(ctx->conn, 1);
1610 return -1;
1611 }
1612
1613 static int NONNULL(1)
protossl_setup_src(pxy_conn_ctx_t * ctx)1614 protossl_setup_src(pxy_conn_ctx_t *ctx)
1615 {
1616 int rv;
1617 if ((rv = protossl_setup_src_ssl(ctx)) != 0) {
1618 return rv;
1619 }
1620
1621 ctx->src.bev = protossl_bufferevent_setup(ctx, ctx->fd, ctx->src.ssl);
1622 if (!ctx->src.bev) {
1623 log_err_level_printf(LOG_CRIT, "Error creating src bufferevent\n");
1624 SSL_free(ctx->src.ssl);
1625 ctx->src.ssl = NULL;
1626 pxy_conn_term(ctx, 1);
1627 return -1;
1628 }
1629 ctx->src.free = protossl_bufferevent_free_and_close_fd;
1630 return 0;
1631 }
1632
1633 int
protossl_setup_src_new_bev_ssl_accepting(pxy_conn_ctx_t * ctx)1634 protossl_setup_src_new_bev_ssl_accepting(pxy_conn_ctx_t *ctx)
1635 {
1636 ctx->src.bev = bufferevent_openssl_filter_new(ctx->thr->evbase, ctx->src.bev, ctx->src.ssl,
1637 BUFFEREVENT_SSL_ACCEPTING, BEV_OPT_DEFER_CALLBACKS);
1638 if (!ctx->src.bev) {
1639 log_err_level_printf(LOG_CRIT, "Error creating src bufferevent\n");
1640 SSL_free(ctx->src.ssl);
1641 ctx->src.ssl = NULL;
1642 pxy_conn_term(ctx, 1);
1643 return -1;
1644 }
1645 ctx->src.free = protossl_bufferevent_free_and_close_fd;
1646 return 0;
1647 }
1648
1649 int
protossl_setup_dst_new_bev_ssl_connecting(pxy_conn_ctx_t * ctx)1650 protossl_setup_dst_new_bev_ssl_connecting(pxy_conn_ctx_t *ctx)
1651 {
1652 ctx->dst.bev = bufferevent_openssl_filter_new(ctx->thr->evbase, ctx->dst.bev, ctx->dst.ssl,
1653 BUFFEREVENT_SSL_CONNECTING, BEV_OPT_DEFER_CALLBACKS);
1654 if (!ctx->dst.bev) {
1655 log_err_level_printf(LOG_CRIT, "Error creating dst bufferevent\n");
1656 SSL_free(ctx->dst.ssl);
1657 ctx->dst.ssl = NULL;
1658 pxy_conn_term(ctx, 1);
1659 return -1;
1660 }
1661 ctx->dst.free = protossl_bufferevent_free_and_close_fd;
1662 return 0;
1663 }
1664
1665 int
protossl_setup_dst_new_bev_ssl_connecting_child(pxy_conn_child_ctx_t * ctx)1666 protossl_setup_dst_new_bev_ssl_connecting_child(pxy_conn_child_ctx_t *ctx)
1667 {
1668 ctx->dst.bev = bufferevent_openssl_filter_new(ctx->conn->thr->evbase, ctx->dst.bev, ctx->dst.ssl,
1669 BUFFEREVENT_SSL_CONNECTING, BEV_OPT_DEFER_CALLBACKS);
1670 if (!ctx->dst.bev) {
1671 log_err_level_printf(LOG_CRIT, "Error creating dst bufferevent\n");
1672 SSL_free(ctx->dst.ssl);
1673 ctx->dst.ssl = NULL;
1674 pxy_conn_term(ctx->conn, 1);
1675 return -1;
1676 }
1677 ctx->dst.free = protossl_bufferevent_free_and_close_fd;
1678 return 0;
1679 }
1680
1681 int
protossl_enable_src(pxy_conn_ctx_t * ctx)1682 protossl_enable_src(pxy_conn_ctx_t *ctx)
1683 {
1684 // @todo The return value of protossl_enable_src() never used, just return?
1685 int rv;
1686 if ((rv = protossl_setup_src(ctx)) != 0) {
1687 // Might have switched to passthrough mode
1688 return rv;
1689 }
1690 bufferevent_setcb(ctx->src.bev, pxy_bev_readcb, pxy_bev_writecb, pxy_bev_eventcb, ctx);
1691
1692 // Save the srvdst ssl info for logging
1693 ctx->sslctx->srvdst_ssl_version = strdup(SSL_get_version(ctx->srvdst.ssl));
1694 ctx->sslctx->srvdst_ssl_cipher = strdup(SSL_get_cipher(ctx->srvdst.ssl));
1695
1696 if (pxy_setup_child_listener(ctx) == -1) {
1697 return -1;
1698 }
1699
1700 log_finer("Enabling src");
1701 // Now open the gates
1702 bufferevent_enable(ctx->src.bev, EV_READ|EV_WRITE);
1703 return 0;
1704 }
1705
1706 static void NONNULL(1,2)
protossl_bev_eventcb_connected_dst(struct bufferevent * bev,pxy_conn_ctx_t * ctx)1707 protossl_bev_eventcb_connected_dst(struct bufferevent *bev, pxy_conn_ctx_t *ctx)
1708 {
1709 log_finest("ENTER");
1710
1711 ctx->connected = 1;
1712 bufferevent_enable(bev, EV_READ|EV_WRITE);
1713
1714 protossl_enable_src(ctx);
1715 }
1716
1717 static void
protossl_bev_eventcb_connected_srvdst(UNUSED struct bufferevent * bev,pxy_conn_ctx_t * ctx)1718 protossl_bev_eventcb_connected_srvdst(UNUSED struct bufferevent *bev, pxy_conn_ctx_t *ctx)
1719 {
1720 log_finest("ENTER");
1721
1722 #ifndef WITHOUT_USERAUTH
1723 pxy_userauth(ctx);
1724 if (ctx->term || ctx->enomem) {
1725 return;
1726 }
1727 #endif /* !WITHOUT_USERAUTH */
1728
1729 // Defer any pass or block action until SSL filter application below
1730 if (pxy_conn_apply_filter(ctx, FILTER_ACTION_PASS | FILTER_ACTION_BLOCK)) {
1731 // We never reach here, since we defer pass and block actions
1732 return;
1733 }
1734
1735 // Set src ssl up early to apply SSL filter,
1736 // this is the last moment we can take divert or split action
1737 if (protossl_setup_src_ssl(ctx) != 0) {
1738 return;
1739 }
1740
1741 if (prototcp_setup_dst(ctx) == -1) {
1742 return;
1743 }
1744
1745 if (ctx->divert) {
1746 bufferevent_setcb(ctx->dst.bev, pxy_bev_readcb, pxy_bev_writecb, pxy_bev_eventcb, ctx);
1747 if (bufferevent_socket_connect(ctx->dst.bev, (struct sockaddr *)&ctx->spec->divert_addr, ctx->spec->divert_addrlen) == -1) {
1748 log_fine("FAILED bufferevent_socket_connect for divert addr");
1749 pxy_conn_term(ctx, 1);
1750 return;
1751 }
1752 }
1753 }
1754
1755 static void NONNULL(1,2)
protossl_bev_eventcb_error_srvdst(UNUSED struct bufferevent * bev,pxy_conn_ctx_t * ctx)1756 protossl_bev_eventcb_error_srvdst(UNUSED struct bufferevent *bev, pxy_conn_ctx_t *ctx)
1757 {
1758 log_fine("ENTER");
1759
1760 if (!ctx->connected) {
1761 log_fine("!ctx->connected");
1762
1763 /* the callout to the original destination failed,
1764 * e.g. because it asked for client cert auth, so
1765 * close the accepted socket and clean up */
1766 if (((ctx->conn_opts->passthrough && ctx->sslctx->have_sslerr) || (ctx->pass && !ctx->sslctx->have_sslerr))) {
1767 /* ssl callout failed, fall back to plain TCP passthrough of SSL connection */
1768 log_err_level_printf(LOG_WARNING, "SSL srvdst connection failed; falling back to passthrough\n");
1769 ctx->sslctx->have_sslerr = 0;
1770 protopassthrough_engage(ctx);
1771 return;
1772 }
1773 pxy_conn_term(ctx, 0);
1774 }
1775 }
1776
1777 static void NONNULL(1)
protossl_bev_eventcb_dst(struct bufferevent * bev,short events,pxy_conn_ctx_t * ctx)1778 protossl_bev_eventcb_dst(struct bufferevent *bev, short events, pxy_conn_ctx_t *ctx)
1779 {
1780 if (events & BEV_EVENT_CONNECTED) {
1781 protossl_bev_eventcb_connected_dst(bev, ctx);
1782 } else if (events & BEV_EVENT_EOF) {
1783 prototcp_bev_eventcb_eof_dst(bev, ctx);
1784 } else if (events & BEV_EVENT_ERROR) {
1785 prototcp_bev_eventcb_error_dst(bev, ctx);
1786 }
1787 }
1788
1789 void
protossl_bev_eventcb_srvdst(struct bufferevent * bev,short events,pxy_conn_ctx_t * ctx)1790 protossl_bev_eventcb_srvdst(struct bufferevent *bev, short events, pxy_conn_ctx_t *ctx)
1791 {
1792 if (events & BEV_EVENT_CONNECTED) {
1793 protossl_bev_eventcb_connected_srvdst(bev, ctx);
1794 } else if (events & BEV_EVENT_EOF) {
1795 prototcp_bev_eventcb_eof_srvdst(bev, ctx);
1796 } else if (events & BEV_EVENT_ERROR) {
1797 protossl_bev_eventcb_error_srvdst(bev, ctx);
1798 }
1799 }
1800
1801 void
protossl_bev_eventcb(struct bufferevent * bev,short events,void * arg)1802 protossl_bev_eventcb(struct bufferevent *bev, short events, void *arg)
1803 {
1804 pxy_conn_ctx_t *ctx = arg;
1805
1806 if (events & BEV_EVENT_ERROR) {
1807 protossl_log_ssl_error(bev, ctx);
1808 }
1809
1810 if (bev == ctx->src.bev) {
1811 prototcp_bev_eventcb_src(bev, events, ctx);
1812 } else if (bev == ctx->dst.bev) {
1813 protossl_bev_eventcb_dst(bev, events, ctx);
1814 } else if (bev == ctx->srvdst.bev) {
1815 protossl_bev_eventcb_srvdst(bev, events, ctx);
1816 } else {
1817 log_err_printf("protossl_bev_eventcb: UNKWN conn end\n");
1818 }
1819 }
1820
1821 void
protossl_bev_eventcb_child(struct bufferevent * bev,short events,void * arg)1822 protossl_bev_eventcb_child(struct bufferevent *bev, short events, void *arg)
1823 {
1824 pxy_conn_child_ctx_t *ctx = arg;
1825
1826 if (events & BEV_EVENT_ERROR) {
1827 protossl_log_ssl_error(bev, ctx->conn);
1828 }
1829
1830 if (bev == ctx->src.bev) {
1831 prototcp_bev_eventcb_src_child(bev, events, ctx);
1832 } else if (bev == ctx->dst.bev) {
1833 prototcp_bev_eventcb_dst_child(bev, events, ctx);
1834 } else {
1835 log_err_printf("protossl_bev_eventcb_child: UNKWN conn end\n");
1836 }
1837 }
1838
1839 // @attention Called by thrmgr thread
1840 protocol_t
protossl_setup(pxy_conn_ctx_t * ctx)1841 protossl_setup(pxy_conn_ctx_t *ctx)
1842 {
1843 ctx->protoctx->proto = PROTO_SSL;
1844 ctx->protoctx->connectcb = protossl_conn_connect;
1845 ctx->protoctx->init_conn = protossl_init_conn;
1846
1847 ctx->protoctx->bev_eventcb = protossl_bev_eventcb;
1848
1849 ctx->protoctx->proto_free = protossl_free;
1850
1851 ctx->sslctx = malloc(sizeof(ssl_ctx_t));
1852 if (!ctx->sslctx) {
1853 return PROTO_ERROR;
1854 }
1855 memset(ctx->sslctx, 0, sizeof(ssl_ctx_t));
1856
1857 return PROTO_SSL;
1858 }
1859
1860 protocol_t
protossl_setup_child(pxy_conn_child_ctx_t * ctx)1861 protossl_setup_child(pxy_conn_child_ctx_t *ctx)
1862 {
1863 ctx->protoctx->proto = PROTO_SSL;
1864 ctx->protoctx->connectcb = protossl_connect_child;
1865
1866 ctx->protoctx->bev_eventcb = protossl_bev_eventcb_child;
1867
1868 return PROTO_SSL;
1869 }
1870
1871 /* vim: set noet ft=c: */
1872