diff -urN ../exim-4.95.orig/src/functions.h ./src/functions.h --- ../exim-4.95.orig/src/functions.h 2021-09-28 11:24:46.000000000 +0300 +++ ./src/functions.h 2023-05-23 02:25:03.737198000 +0300 @@ -53,6 +53,8 @@ extern void tls_clean_env(void); extern BOOL tls_client_start(client_conn_ctx *, smtp_connect_args *, void *, tls_support *, uschar **); +extern BOOL tls_client_adjunct_start(host_item *, client_conn_ctx *, + const uschar *, uschar **); extern void tls_client_creds_reload(BOOL); extern void tls_close(void *, int); diff -urN ../exim-4.95.orig/src/lookups/readsock.c ./src/lookups/readsock.c --- ../exim-4.95.orig/src/lookups/readsock.c 2021-09-28 11:24:46.000000000 +0300 +++ ./src/lookups/readsock.c 2023-05-23 02:24:25.197132000 +0300 @@ -11,7 +11,7 @@ static int internal_readsock_open(client_conn_ctx * cctx, const uschar * sspec, - int timeout, BOOL do_tls, uschar ** errmsg) + int timeout, uschar * do_tls, uschar ** errmsg) { const uschar * server_name; host_item host; @@ -114,17 +114,8 @@ #ifndef DISABLE_TLS if (do_tls) - { - smtp_connect_args conn_args = {.host = &host }; - tls_support tls_dummy = {.sni=NULL}; - uschar * errstr; - - if (!tls_client_start(cctx, &conn_args, NULL, &tls_dummy, &errstr)) - { - *errmsg = string_sprintf("TLS connect failed: %s", errstr); + if (!tls_client_adjunct_start(&host, cctx, do_tls, errmsg)) goto bad; - } - } #endif DEBUG(D_expand|D_lookup) debug_printf_indent(" connected to socket %s\n", sspec); @@ -175,8 +166,8 @@ int sep = ','; struct { BOOL do_shutdown:1; - BOOL do_tls:1; BOOL cache:1; + uschar * do_tls; /* NULL, empty-string, or SNI */ } lf = {.do_shutdown = TRUE}; uschar * eol = NULL; int timeout = 5; @@ -195,8 +186,10 @@ else if (Ustrncmp(s, "shutdown=", 9) == 0) lf.do_shutdown = Ustrcmp(s + 9, "no") != 0; #ifndef DISABLE_TLS - else if (Ustrncmp(s, "tls=", 4) == 0 && Ustrcmp(s + 4, US"no") != 0) - lf.do_tls = TRUE; + else if (Ustrncmp(s, "tls=", 4) == 0 && Ustrcmp(s + 4, US"no") != 0 && !lf.do_tls) + lf.do_tls = US""; + else if (Ustrncmp(s, "sni=", 4) == 0) + lf.do_tls = s + 4; #endif else if (Ustrncmp(s, "eol=", 4) == 0) eol = string_unprinting(s + 4); diff -urN ../exim-4.95.orig/src/tls.c ./src/tls.c --- ../exim-4.95.orig/src/tls.c 2021-09-28 11:24:46.000000000 +0300 +++ ./src/tls.c 2023-05-23 02:32:31.007776000 +0300 @@ -789,6 +789,57 @@ +/* Start TLS as a client for an ajunct connection, eg. readsocket +Return boolean success. +*/ + +#define GET_UNTAINTED (const void *)0 +#define GET_TAINTED (const void *)1 + +BOOL +tls_client_adjunct_start(host_item * host, client_conn_ctx * cctx, + const uschar * sni, uschar ** errmsg) +{ +union sockaddr_46 interface_sock; +EXIM_SOCKLEN_T size = sizeof(interface_sock); +smtp_connect_args conn_args = {.host = host }; +tls_support tls_dummy = { .sni = NULL }; +uschar * errstr; + +//if (getsockname(cctx->sock, (struct sockaddr *) &interface_sock, &size) == 0) +// conn_args.sending_ip_address = host_ntoa(-1, &interface_sock, NULL, NULL); +//else +// { +// *errmsg = string_sprintf("getsockname failed: %s", strerror(errno)); +// return FALSE; +// } + +/* To handle SNI we need to emulate more of a real transport because the +base tls code assumes that is where the SNI string lives. */ + +if (*sni) + { + transport_instance * tb; + smtp_transport_options_block * ob; + + conn_args.tblock = tb = store_get(sizeof(*tb), GET_UNTAINTED); + memset(tb, 0, sizeof(*tb)); + + tb->options_block = ob = store_get(sizeof(*ob), GET_UNTAINTED); + memcpy(ob, &smtp_transport_option_defaults, sizeof(*ob)); + + ob->tls_sni = sni; + } + +if (!tls_client_start(cctx, &conn_args, NULL, &tls_dummy, &errstr)) + { + *errmsg = string_sprintf("TLS connect failed: %s", errstr); + return FALSE; + } +return TRUE; +} + + #endif /*!DISABLE_TLS*/ #endif /*!MACRO_PREDEF*/