Asterisk - The Open Source Telephony Project  21.4.1
Macros | Functions
tcptls.c File Reference

Code to support TCP and TLS server/client. More...

#include "asterisk.h"
#include "asterisk/tcptls.h"
#include "asterisk/iostream.h"
#include <fcntl.h>
#include <netinet/in.h>
#include <openssl/asn1.h>
#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/opensslconf.h>
#include <openssl/opensslv.h>
#include <openssl/safestack.h>
#include <openssl/ssl.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <openssl/bio.h>
#include <openssl/dh.h>
#include <openssl/pem.h>
#include <openssl/ec.h>
#include <pthread.h>
#include <signal.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include "asterisk/app.h"
#include "asterisk/astobj2.h"
#include "asterisk/compat.h"
#include "asterisk/config.h"
#include "asterisk/io.h"
#include "asterisk/lock.h"
#include "asterisk/logger.h"
#include "asterisk/netsock2.h"
#include "asterisk/pbx.h"
#include "asterisk/utils.h"

Go to the source code of this file.

Macros

#define SSL_CTRL_SET_ECDH_AUTO   94
 

Functions

static int __ssl_setup (struct ast_tls_config *cfg, int client)
 
static void __ssl_setup_certs (struct ast_tls_config *cfg, const size_t cert_file_len, const char *key_type_extension, const char *key_type)
 
int ast_ssl_setup (struct ast_tls_config *cfg)
 Set up an SSL server. More...
 
void ast_ssl_teardown (struct ast_tls_config *cfg)
 free resources used by an SSL server More...
 
struct ast_tcptls_session_instanceast_tcptls_client_create (struct ast_tcptls_session_args *desc)
 Creates a client connection's ast_tcptls_session_instance.
 
struct ast_tcptls_session_instanceast_tcptls_client_start (struct ast_tcptls_session_instance *tcptls_session)
 Attempt to connect and start a tcptls session. More...
 
struct ast_tcptls_session_instanceast_tcptls_client_start_timeout (struct ast_tcptls_session_instance *tcptls_session, int timeout)
 Attempt to connect and start a tcptls session within the given timeout. More...
 
void ast_tcptls_close_session_file (struct ast_tcptls_session_instance *tcptls_session)
 Closes a tcptls session instance's file and/or file descriptor. The tcptls_session will be set to NULL and it's file descriptor will be set to -1 by this function.
 
void * ast_tcptls_server_root (void *data)
 
void ast_tcptls_server_start (struct ast_tcptls_session_args *desc)
 This is a generic (re)start routine for a TCP server, which does the socket/bind/listen and starts a thread for handling accept(). More...
 
void ast_tcptls_server_stop (struct ast_tcptls_session_args *desc)
 Shutdown a running server if there is one. More...
 
int ast_tls_read_conf (struct ast_tls_config *tls_cfg, struct ast_tcptls_session_args *tls_desc, const char *varname, const char *value)
 Used to parse conf files containing tls/ssl options.
 
static int check_tcptls_cert_name (ASN1_STRING *cert_str, const char *hostname, const char *desc)
 
static void * handle_tcptls_connection (void *data)
 creates a FILE * from the fd passed by the accept thread. This operation is potentially expensive (certificate verification), so we do it in the child thread context. More...
 
static void session_instance_destructor (void *obj)
 
static int socket_connect (int sockfd, const struct ast_sockaddr *addr, int timeout)
 
static void write_openssl_error_to_log (void)
 

Detailed Description

Code to support TCP and TLS server/client.

Author
Luigi Rizzo
Brett Bryant brett.nosp@m.brya.nosp@m.nt@gm.nosp@m.ail..nosp@m.com

Definition in file tcptls.c.

Function Documentation

int ast_ssl_setup ( struct ast_tls_config cfg)

Set up an SSL server.

Parameters
cfgConfiguration for the SSL server
Return values
1Success
0Failure

Definition at line 570 of file tcptls.c.

571 {
572  return __ssl_setup(cfg, 0);
573 }
void ast_ssl_teardown ( struct ast_tls_config cfg)

free resources used by an SSL server

Note
This only needs to be called if ast_ssl_setup() was directly called first.
Parameters
cfgConfiguration for the SSL server

Definition at line 575 of file tcptls.c.

576 {
577 #ifdef DO_SSL
578  if (cfg && cfg->ssl_ctx) {
579  SSL_CTX_free(cfg->ssl_ctx);
580  cfg->ssl_ctx = NULL;
581  }
582 #endif
583 }
struct ast_tcptls_session_instance* ast_tcptls_client_start ( struct ast_tcptls_session_instance tcptls_session)

Attempt to connect and start a tcptls session.

Blocks until a connection is established, or an error occurs.

Note
On error the tcptls_session's ref count is decremented, fd and file are closed, and NULL is returned.
Parameters
tcptls_sessionThe session instance to connect and start
Returns
The tcptls_session, or NULL on error

Definition at line 673 of file tcptls.c.

References ast_tcptls_client_start_timeout().

674 {
675  return ast_tcptls_client_start_timeout(tcptls_session, -1);
676 }
struct ast_tcptls_session_instance * ast_tcptls_client_start_timeout(struct ast_tcptls_session_instance *tcptls_session, int timeout)
Attempt to connect and start a tcptls session within the given timeout.
Definition: tcptls.c:645
struct ast_tcptls_session_instance* ast_tcptls_client_start_timeout ( struct ast_tcptls_session_instance tcptls_session,
int  timeout 
)

Attempt to connect and start a tcptls session within the given timeout.

Note
On error the tcptls_session's ref count is decremented, fd and file are closed, and NULL is returned.
Parameters
tcptls_sessionThe session instance to connect and start
timeoutHow long (in milliseconds) to attempt to connect (-1 equals infinite)
Returns
The tcptls_session, or NULL on error

Definition at line 645 of file tcptls.c.

References ao2_ref, ast_fd_clear_flags, ast_sockaddr_stringify(), handle_tcptls_connection(), and ast_tcptls_session_args::tls_cfg.

Referenced by ast_tcptls_client_start().

647 {
648  struct ast_tcptls_session_args *desc;
649 
650  if (!(desc = tcptls_session->parent)) {
651  ao2_ref(tcptls_session, -1);
652  return NULL;
653  }
654 
655  if (socket_connect(desc->accept_fd, &desc->remote_address, timeout)) {
656  ast_log(LOG_WARNING, "Unable to connect %s to %s: %s\n", desc->name,
657  ast_sockaddr_stringify(&desc->remote_address), strerror(errno));
658 
659  ao2_ref(tcptls_session, -1);
660  return NULL;
661  }
662 
663  ast_fd_clear_flags(desc->accept_fd, O_NONBLOCK);
664 
665  if (desc->tls_cfg) {
666  desc->tls_cfg->enabled = 1;
667  __ssl_setup(desc->tls_cfg, 1);
668  }
669 
670  return handle_tcptls_connection(tcptls_session);
671 }
static void * handle_tcptls_connection(void *data)
creates a FILE * from the fd passed by the accept thread. This operation is potentially expensive (ce...
Definition: tcptls.c:140
arguments for the accepting thread
Definition: tcptls.h:130
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:256
#define ast_fd_clear_flags(fd, flags)
Clear flags on the given file descriptor.
Definition: utils.h:1055
struct ast_tls_config * tls_cfg
Definition: tcptls.h:135
void ast_tcptls_server_start ( struct ast_tcptls_session_args desc)

This is a generic (re)start routine for a TCP server, which does the socket/bind/listen and starts a thread for handling accept().

Version
1.6.1 changed desc parameter to be of ast_tcptls_session_args type

Definition at line 760 of file tcptls.c.

References ast_tcptls_session_args::accept_fn, ast_bind(), ast_calloc, ast_debug, ast_read_textfile(), ast_sd_get_fd(), ast_sha1_hash(), ast_sockaddr_cmp(), ast_sockaddr_copy(), ast_sockaddr_is_ipv6(), ast_sockaddr_isnull(), ast_sockaddr_setnull(), ast_sockaddr_stringify(), ast_socket_nonblock, ast_strdup, ast_tcptls_session_args::master, ast_tcptls_session_args::old_address, ast_tcptls_session_args::old_tls_cfg, and ast_tcptls_session_args::tls_cfg.

761 {
762  int x = 1;
763  int tls_changed = 0;
764  int sd_socket;
765 
766  if (desc->tls_cfg) {
767  char hash[41];
768  char *str = NULL;
769  struct stat st;
770 
771  /* Store the hashes of the TLS certificate etc. */
772  if (stat(desc->tls_cfg->certfile, &st) || NULL == (str = ast_read_textfile(desc->tls_cfg->certfile))) {
773  memset(hash, 0, 41);
774  } else {
775  ast_sha1_hash(hash, str);
776  }
777  ast_free(str);
778  str = NULL;
779  memcpy(desc->tls_cfg->certhash, hash, 41);
780  if (stat(desc->tls_cfg->pvtfile, &st) || NULL == (str = ast_read_textfile(desc->tls_cfg->pvtfile))) {
781  memset(hash, 0, 41);
782  } else {
783  ast_sha1_hash(hash, str);
784  }
785  ast_free(str);
786  str = NULL;
787  memcpy(desc->tls_cfg->pvthash, hash, 41);
788  if (stat(desc->tls_cfg->cafile, &st) || NULL == (str = ast_read_textfile(desc->tls_cfg->cafile))) {
789  memset(hash, 0, 41);
790  } else {
791  ast_sha1_hash(hash, str);
792  }
793  ast_free(str);
794  str = NULL;
795  memcpy(desc->tls_cfg->cahash, hash, 41);
796 
797  /* Check whether TLS configuration has changed */
798  if (!desc->old_tls_cfg) { /* No previous configuration */
799  tls_changed = 1;
800  desc->old_tls_cfg = ast_calloc(1, sizeof(*desc->old_tls_cfg));
801  } else if (memcmp(desc->tls_cfg->certhash, desc->old_tls_cfg->certhash, 41)) {
802  tls_changed = 1;
803  } else if (memcmp(desc->tls_cfg->pvthash, desc->old_tls_cfg->pvthash, 41)) {
804  tls_changed = 1;
805  } else if (strcmp(desc->tls_cfg->cipher, desc->old_tls_cfg->cipher)) {
806  tls_changed = 1;
807  } else if (memcmp(desc->tls_cfg->cahash, desc->old_tls_cfg->cahash, 41)) {
808  tls_changed = 1;
809  } else if (strcmp(desc->tls_cfg->capath, desc->old_tls_cfg->capath)) {
810  tls_changed = 1;
811  } else if (memcmp(&desc->tls_cfg->flags, &desc->old_tls_cfg->flags, sizeof(desc->tls_cfg->flags))) {
812  tls_changed = 1;
813  }
814 
815  if (tls_changed) {
816  ast_debug(1, "Changed parameters for %s found\n", desc->name);
817  }
818  }
819 
820  /* Do nothing if nothing has changed */
821  if (!tls_changed && !ast_sockaddr_cmp(&desc->old_address, &desc->local_address)) {
822  ast_debug(1, "Nothing changed in %s\n", desc->name);
823  return;
824  }
825 
826  /* If we return early, there is no one listening */
828 
829  /* Shutdown a running server if there is one */
830  if (desc->master != AST_PTHREADT_NULL) {
831  pthread_cancel(desc->master);
832  pthread_kill(desc->master, SIGURG);
833  pthread_join(desc->master, NULL);
834  }
835 
836  sd_socket = ast_sd_get_fd(SOCK_STREAM, &desc->local_address);
837 
838  if (sd_socket != -1) {
839  if (desc->accept_fd != sd_socket) {
840  if (desc->accept_fd != -1) {
841  close(desc->accept_fd);
842  }
843  desc->accept_fd = sd_socket;
844  }
845 
846  goto systemd_socket_activation;
847  }
848 
849  if (desc->accept_fd != -1) {
850  close(desc->accept_fd);
851  desc->accept_fd = -1;
852  }
853 
854  /* If there's no new server, stop here */
855  if (ast_sockaddr_isnull(&desc->local_address)) {
856  ast_debug(2, "Server disabled: %s\n", desc->name);
857  return;
858  }
859 
860  desc->accept_fd = ast_socket_nonblock(ast_sockaddr_is_ipv6(&desc->local_address) ?
861  AF_INET6 : AF_INET, SOCK_STREAM, 0);
862  if (desc->accept_fd < 0) {
863  ast_log(LOG_ERROR, "Unable to allocate socket for %s: %s\n", desc->name, strerror(errno));
864  return;
865  }
866 
867  setsockopt(desc->accept_fd, SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x));
868  if (ast_bind(desc->accept_fd, &desc->local_address)) {
869  ast_log(LOG_ERROR, "Unable to bind %s to %s: %s\n",
870  desc->name,
871  ast_sockaddr_stringify(&desc->local_address),
872  strerror(errno));
873  goto error;
874  }
875  if (listen(desc->accept_fd, 10)) {
876  ast_log(LOG_ERROR, "Unable to listen for %s!\n", desc->name);
877  goto error;
878  }
879 
880 systemd_socket_activation:
881  if (ast_pthread_create_background(&desc->master, NULL, desc->accept_fn, desc)) {
882  ast_log(LOG_ERROR, "Unable to launch thread for %s on %s: %s\n",
883  desc->name,
884  ast_sockaddr_stringify(&desc->local_address),
885  strerror(errno));
886  goto error;
887  }
888 
889  /* Set current info */
890  ast_sockaddr_copy(&desc->old_address, &desc->local_address);
891  if (desc->old_tls_cfg) {
892  ast_free(desc->old_tls_cfg->certfile);
893  ast_free(desc->old_tls_cfg->pvtfile);
894  ast_free(desc->old_tls_cfg->cipher);
895  ast_free(desc->old_tls_cfg->cafile);
896  ast_free(desc->old_tls_cfg->capath);
897  desc->old_tls_cfg->certfile = ast_strdup(desc->tls_cfg->certfile);
898  desc->old_tls_cfg->pvtfile = ast_strdup(desc->tls_cfg->pvtfile);
899  desc->old_tls_cfg->cipher = ast_strdup(desc->tls_cfg->cipher);
900  desc->old_tls_cfg->cafile = ast_strdup(desc->tls_cfg->cafile);
901  desc->old_tls_cfg->capath = ast_strdup(desc->tls_cfg->capath);
902  memcpy(desc->old_tls_cfg->certhash, desc->tls_cfg->certhash, 41);
903  memcpy(desc->old_tls_cfg->pvthash, desc->tls_cfg->pvthash, 41);
904  memcpy(desc->old_tls_cfg->cahash, desc->tls_cfg->cahash, 41);
905  memcpy(&desc->old_tls_cfg->flags, &desc->tls_cfg->flags, sizeof(desc->old_tls_cfg->flags));
906  }
907 
908  return;
909 
910 error:
911  close(desc->accept_fd);
912  desc->accept_fd = -1;
913 }
static void ast_sockaddr_copy(struct ast_sockaddr *dst, const struct ast_sockaddr *src)
Copies the data from one ast_sockaddr to another.
Definition: netsock2.h:167
#define ast_socket_nonblock(domain, type, protocol)
Create a non-blocking socket.
Definition: utils.h:1073
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
int ast_sockaddr_cmp(const struct ast_sockaddr *a, const struct ast_sockaddr *b)
Compares two ast_sockaddr structures.
Definition: netsock2.c:388
int ast_bind(int sockfd, const struct ast_sockaddr *addr)
Wrapper around bind(2) that uses struct ast_sockaddr.
Definition: netsock2.c:590
char * ast_read_textfile(const char *file)
Read a file into asterisk.
Definition: main/app.c:2949
int ast_sd_get_fd(int type, const struct ast_sockaddr *addr)
Find a listening file descriptor provided by socket activation.
Definition: io.c:438
static void ast_sockaddr_setnull(struct ast_sockaddr *addr)
Sets address addr to null.
Definition: netsock2.h:138
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:127
#define ast_debug(level,...)
Log a DEBUG message.
void ast_sha1_hash(char *output, const char *input)
Produces SHA1 hash based on input string.
Definition: utils.c:266
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:256
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
struct ast_sockaddr old_address
Definition: tcptls.h:132
struct ast_tls_config * old_tls_cfg
Definition: tcptls.h:144
struct ast_tls_config * tls_cfg
Definition: tcptls.h:135
int ast_sockaddr_is_ipv6(const struct ast_sockaddr *addr)
Determine if this is an IPv6 address.
Definition: netsock2.c:524
void *(* accept_fn)(void *)
Definition: tcptls.h:140
void ast_tcptls_server_stop ( struct ast_tcptls_session_args desc)

Shutdown a running server if there is one.

Version
1.6.1 changed desc parameter to be of ast_tcptls_session_args type

Definition at line 925 of file tcptls.c.

References ast_debug, ast_tcptls_session_args::master, and ast_tcptls_session_args::old_tls_cfg.

926 {
927  if (desc->master != AST_PTHREADT_NULL) {
928  pthread_cancel(desc->master);
929  pthread_kill(desc->master, SIGURG);
930  pthread_join(desc->master, NULL);
931  desc->master = AST_PTHREADT_NULL;
932  }
933  if (desc->accept_fd != -1) {
934  close(desc->accept_fd);
935  }
936  desc->accept_fd = -1;
937 
938  if (desc->old_tls_cfg) {
939  ast_free(desc->old_tls_cfg->certfile);
940  ast_free(desc->old_tls_cfg->pvtfile);
941  ast_free(desc->old_tls_cfg->cipher);
942  ast_free(desc->old_tls_cfg->cafile);
943  ast_free(desc->old_tls_cfg->capath);
944  ast_free(desc->old_tls_cfg);
945  desc->old_tls_cfg = NULL;
946  }
947 
948  ast_debug(2, "Stopped server :: %s\n", desc->name);
949 }
#define ast_debug(level,...)
Log a DEBUG message.
struct ast_tls_config * old_tls_cfg
Definition: tcptls.h:144
static void* handle_tcptls_connection ( void *  data)
static

creates a FILE * from the fd passed by the accept thread. This operation is potentially expensive (certificate verification), so we do it in the child thread context.

Note
must decrement ref count before returning NULL on error

Definition at line 140 of file tcptls.c.

References ao2_ref, ast_iostream_get_ssl(), ast_iostream_start_tls(), ast_sockaddr_stringify(), AST_SSL_DONT_VERIFY_SERVER, AST_SSL_IGNORE_COMMON_NAME, AST_SSL_VERIFY_CLIENT, ast_tcptls_close_session_file(), ast_thread_inhibit_escalations(), ast_thread_user_interface_set(), ast_tcptls_session_args::hostname, ast_tcptls_session_instance::stream, ast_tcptls_session_args::tls_cfg, and ast_tcptls_session_args::worker_fn.

Referenced by ast_tcptls_client_start_timeout().

141 {
142  struct ast_tcptls_session_instance *tcptls_session = data;
143 #ifdef DO_SSL
144  SSL *ssl;
145 #endif
146 
147  /* TCP/TLS connections are associated with external protocols, and
148  * should not be allowed to execute 'dangerous' functions. This may
149  * need to be pushed down into the individual protocol handlers, but
150  * this seems like a good general policy.
151  */
153  ast_log(LOG_ERROR, "Failed to inhibit privilege escalations; killing connection from peer '%s'\n",
154  ast_sockaddr_stringify(&tcptls_session->remote_address));
155  ast_tcptls_close_session_file(tcptls_session);
156  ao2_ref(tcptls_session, -1);
157  return NULL;
158  }
159 
160  /*
161  * TCP/TLS connections are associated with external protocols which can
162  * be considered to be user interfaces (even for SIP messages), and
163  * will not handle channel media. This may need to be pushed down into
164  * the individual protocol handlers, but this seems like a good start.
165  */
167  ast_log(LOG_ERROR, "Failed to set user interface status; killing connection from peer '%s'\n",
168  ast_sockaddr_stringify(&tcptls_session->remote_address));
169  ast_tcptls_close_session_file(tcptls_session);
170  ao2_ref(tcptls_session, -1);
171  return NULL;
172  }
173 
174  if (tcptls_session->parent->tls_cfg) {
175 #ifdef DO_SSL
176  if (ast_iostream_start_tls(&tcptls_session->stream, tcptls_session->parent->tls_cfg->ssl_ctx, tcptls_session->client) < 0) {
177  SSL *ssl = ast_iostream_get_ssl(tcptls_session->stream);
178  if (ssl) {
179  ast_log(LOG_ERROR, "Unable to set up ssl connection with peer '%s'\n",
180  ast_sockaddr_stringify(&tcptls_session->remote_address));
181  }
182  ast_tcptls_close_session_file(tcptls_session);
183  ao2_ref(tcptls_session, -1);
184  return NULL;
185  }
186 
187  ssl = ast_iostream_get_ssl(tcptls_session->stream);
188  if ((tcptls_session->client && !ast_test_flag(&tcptls_session->parent->tls_cfg->flags, AST_SSL_DONT_VERIFY_SERVER))
189  || (!tcptls_session->client && ast_test_flag(&tcptls_session->parent->tls_cfg->flags, AST_SSL_VERIFY_CLIENT))) {
190  X509 *peer;
191  long res;
192  peer = SSL_get_peer_certificate(ssl);
193  if (!peer) {
194  ast_log(LOG_ERROR, "No SSL certificate to verify from peer '%s'\n",
195  ast_sockaddr_stringify(&tcptls_session->remote_address));
196  ast_tcptls_close_session_file(tcptls_session);
197  ao2_ref(tcptls_session, -1);
198  return NULL;
199  }
200 
201  res = SSL_get_verify_result(ssl);
202  if (res != X509_V_OK) {
203  ast_log(LOG_ERROR, "Certificate from peer '%s' did not verify: %s\n",
204  ast_sockaddr_stringify(&tcptls_session->remote_address),
205  X509_verify_cert_error_string(res));
206  X509_free(peer);
207  ast_tcptls_close_session_file(tcptls_session);
208  ao2_ref(tcptls_session, -1);
209  return NULL;
210  }
211  if (!ast_test_flag(&tcptls_session->parent->tls_cfg->flags, AST_SSL_IGNORE_COMMON_NAME)) {
212  ASN1_STRING *str;
213  X509_NAME *name = X509_get_subject_name(peer);
214  STACK_OF(GENERAL_NAME) *alt_names;
215  int pos = -1;
216  int found = 0;
217 
218  for (;;) {
219  /* Walk the certificate to check all available "Common Name" */
220  /* XXX Probably should do a gethostbyname on the hostname and compare that as well */
221  pos = X509_NAME_get_index_by_NID(name, NID_commonName, pos);
222  if (pos < 0) {
223  break;
224  }
225  str = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name, pos));
226  if (!check_tcptls_cert_name(str, tcptls_session->parent->hostname, "common name")) {
227  found = 1;
228  break;
229  }
230  }
231 
232  if (!found) {
233  alt_names = X509_get_ext_d2i(peer, NID_subject_alt_name, NULL, NULL);
234  if (alt_names != NULL) {
235  int alt_names_count = sk_GENERAL_NAME_num(alt_names);
236 
237  for (pos = 0; pos < alt_names_count; pos++) {
238  const GENERAL_NAME *alt_name = sk_GENERAL_NAME_value(alt_names, pos);
239 
240  if (alt_name->type != GEN_DNS) {
241  continue;
242  }
243 
244  if (!check_tcptls_cert_name(alt_name->d.dNSName, tcptls_session->parent->hostname, "alt name")) {
245  found = 1;
246  break;
247  }
248  }
249 
250  sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
251  }
252  }
253 
254  if (!found) {
255  ast_log(LOG_ERROR, "Certificate common name from peer '%s' did not match (%s)\n",
256  ast_sockaddr_stringify(&tcptls_session->remote_address), tcptls_session->parent->hostname);
257  X509_free(peer);
258  ast_tcptls_close_session_file(tcptls_session);
259  ao2_ref(tcptls_session, -1);
260  return NULL;
261  }
262  }
263  X509_free(peer);
264  }
265 #else
266  ast_log(LOG_ERROR, "TLS client failed: Asterisk is compiled without OpenSSL support. Install OpenSSL development headers and rebuild Asterisk after running ./configure\n");
267  ast_tcptls_close_session_file(tcptls_session);
268  ao2_ref(tcptls_session, -1);
269  return NULL;
270 #endif /* DO_SSL */
271  }
272 
273  if (tcptls_session->parent->worker_fn) {
274  return tcptls_session->parent->worker_fn(tcptls_session);
275  } else {
276  return tcptls_session;
277  }
278 }
int ast_iostream_start_tls(struct ast_iostream **stream, SSL_CTX *ctx, int client)
Begin TLS on an iostream.
Definition: iostream.c:627
SSL * ast_iostream_get_ssl(struct ast_iostream *stream)
Get a pointer to an iostream's OpenSSL SSL structure.
Definition: iostream.c:109
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
describes a server instance
Definition: tcptls.h:150
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:256
void *(* worker_fn)(void *)
Definition: tcptls.h:142
struct ast_iostream * stream
Definition: tcptls.h:161
void ast_tcptls_close_session_file(struct ast_tcptls_session_instance *tcptls_session)
Closes a tcptls session instance's file and/or file descriptor. The tcptls_session will be set to NUL...
Definition: tcptls.c:915
int ast_thread_user_interface_set(int is_user_interface)
Set the current thread's user interface status.
Definition: utils.c:3233
int ast_thread_inhibit_escalations(void)
Inhibit (in the current thread) the execution of dialplan functions which cause privilege escalations...
struct ast_tls_config * tls_cfg
Definition: tcptls.h:135
char hostname[MAXHOSTNAMELEN]
Definition: tcptls.h:134