#include "asterisk/utils.h"
#include <openssl/ssl.h>
#include <openssl/err.h>
Go to the source code of this file.
Data Structures | |
struct | ast_tcptls_session_args |
arguments for the accepting thread More... | |
struct | ast_tcptls_session_instance |
struct | ast_tls_config |
struct | SSL |
struct | SSL_CTX |
Defines | |
#define | AST_CERTFILE "asterisk.pem" |
#define | HOOK_T ssize_t |
#define | LEN_T size_t |
Enumerations | |
enum | ast_ssl_flags { AST_SSL_VERIFY_CLIENT = (1 << 0), AST_SSL_DONT_VERIFY_SERVER = (1 << 1), AST_SSL_IGNORE_COMMON_NAME = (1 << 2) } |
Functions | |
int | ast_ssl_setup (struct ast_tls_config *cfg) |
ast_tcptls_session_instance * | ast_tcptls_client_start (struct ast_tcptls_session_args *desc) |
A generic client routine for a TCP client and starts a thread for handling accept(). | |
HOOK_T | ast_tcptls_server_read (struct ast_tcptls_session_instance *ser, void *buf, size_t count) |
void * | ast_tcptls_server_root (void *) |
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(). | |
void | ast_tcptls_server_stop (struct ast_tcptls_session_args *desc) |
Shutdown a running server if there is one. | |
HOOK_T | ast_tcptls_server_write (struct ast_tcptls_session_instance *ser, void *buf, size_t count) |
When we are requested to open a TLS socket, we run make_file_from_fd() on the socket, to do the necessary setup. At the moment the context's name is hardwired in the function, but we can certainly make it into an extra parameter to the function.
We declare most of ssl support variables unconditionally, because their number is small and this simplifies the code.
Definition in file tcptls.h.
#define AST_CERTFILE "asterisk.pem" |
SSL support
Definition at line 67 of file tcptls.h.
Referenced by __ast_http_load(), and __init_manager().
enum ast_ssl_flags |
Definition at line 69 of file tcptls.h.
00069 { 00070 /*! Verify certificate when acting as server */ 00071 AST_SSL_VERIFY_CLIENT = (1 << 0), 00072 /*! Don't verify certificate when connecting to a server */ 00073 AST_SSL_DONT_VERIFY_SERVER = (1 << 1), 00074 /*! Don't compare "Common Name" against IP or hostname */ 00075 AST_SSL_IGNORE_COMMON_NAME = (1 << 2) 00076 };
int ast_ssl_setup | ( | struct ast_tls_config * | cfg | ) |
Definition at line 324 of file tcptls.c.
References __ssl_setup().
00325 { 00326 return __ssl_setup(cfg, 0); 00327 }
struct ast_tcptls_session_instance* ast_tcptls_client_start | ( | struct ast_tcptls_session_args * | desc | ) |
A generic client routine for a TCP client and starts a thread for handling accept().
Definition at line 329 of file tcptls.c.
References __ssl_setup(), ao2_alloc, ao2_ref, ast_debug, ast_inet_ntoa(), ast_log(), ast_mutex_init(), desc, errno, handle_tls_connection(), LOG_ERROR, LOG_WARNING, and session_instance_destructor().
Referenced by sip_prepare_socket().
00330 { 00331 int flags; 00332 int x = 1; 00333 struct ast_tcptls_session_instance *tcptls_session = NULL; 00334 00335 /* Do nothing if nothing has changed */ 00336 if (!memcmp(&desc->old_address, &desc->remote_address, sizeof(desc->old_address))) { 00337 ast_debug(1, "Nothing changed in %s\n", desc->name); 00338 return NULL; 00339 } 00340 00341 desc->old_address = desc->remote_address; 00342 00343 if (desc->accept_fd != -1) 00344 close(desc->accept_fd); 00345 00346 desc->accept_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 00347 if (desc->accept_fd < 0) { 00348 ast_log(LOG_WARNING, "Unable to allocate socket for %s: %s\n", 00349 desc->name, strerror(errno)); 00350 return NULL; 00351 } 00352 00353 /* if a local address was specified, bind to it so the connection will 00354 originate from the desired address */ 00355 if (desc->local_address.sin_family != 0) { 00356 setsockopt(desc->accept_fd, SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x)); 00357 if (bind(desc->accept_fd, (struct sockaddr *) &desc->local_address, sizeof(desc->local_address))) { 00358 ast_log(LOG_ERROR, "Unable to bind %s to %s:%d: %s\n", 00359 desc->name, 00360 ast_inet_ntoa(desc->local_address.sin_addr), ntohs(desc->local_address.sin_port), 00361 strerror(errno)); 00362 goto error; 00363 } 00364 } 00365 00366 if (connect(desc->accept_fd, (const struct sockaddr *) &desc->remote_address, sizeof(desc->remote_address))) { 00367 ast_log(LOG_ERROR, "Unable to connect %s to %s:%d: %s\n", 00368 desc->name, 00369 ast_inet_ntoa(desc->remote_address.sin_addr), ntohs(desc->remote_address.sin_port), 00370 strerror(errno)); 00371 goto error; 00372 } 00373 00374 if (!(tcptls_session = ao2_alloc(sizeof(*tcptls_session), session_instance_destructor))) 00375 goto error; 00376 00377 ast_mutex_init(&tcptls_session->lock); 00378 00379 flags = fcntl(desc->accept_fd, F_GETFL); 00380 fcntl(desc->accept_fd, F_SETFL, flags & ~O_NONBLOCK); 00381 00382 tcptls_session->fd = desc->accept_fd; 00383 tcptls_session->parent = desc; 00384 tcptls_session->parent->worker_fn = NULL; 00385 memcpy(&tcptls_session->remote_address, &desc->remote_address, sizeof(tcptls_session->remote_address)); 00386 00387 tcptls_session->client = 1; 00388 00389 if (desc->tls_cfg) { 00390 desc->tls_cfg->enabled = 1; 00391 __ssl_setup(desc->tls_cfg, 1); 00392 } 00393 00394 ao2_ref(tcptls_session, +1); 00395 if (!handle_tls_connection(tcptls_session)) 00396 goto error; 00397 00398 return tcptls_session; 00399 00400 error: 00401 close(desc->accept_fd); 00402 desc->accept_fd = -1; 00403 if (tcptls_session) 00404 ao2_ref(tcptls_session, -1); 00405 return NULL; 00406 }
HOOK_T ast_tcptls_server_read | ( | struct ast_tcptls_session_instance * | ser, | |
void * | buf, | |||
size_t | count | |||
) |
Definition at line 85 of file tcptls.c.
References ast_log(), errno, ast_tcptls_session_instance::fd, LOG_ERROR, ast_tcptls_session_instance::ssl, and ssl_read().
00086 { 00087 if (tcptls_session->fd == -1) { 00088 ast_log(LOG_ERROR, "server_read called with an fd of -1\n"); 00089 errno = EIO; 00090 return -1; 00091 } 00092 00093 #ifdef DO_SSL 00094 if (tcptls_session->ssl) 00095 return ssl_read(tcptls_session->ssl, buf, count); 00096 #endif 00097 return read(tcptls_session->fd, buf, count); 00098 }
void* ast_tcptls_server_root | ( | void * | ) |
Definition at line 224 of file tcptls.c.
References ao2_alloc, ao2_ref, ast_log(), ast_mutex_init(), ast_pthread_create_detached_background, ast_wait_for_input(), desc, errno, handle_tls_connection(), LOG_WARNING, and session_instance_destructor().
00225 { 00226 struct ast_tcptls_session_args *desc = data; 00227 int fd; 00228 struct sockaddr_in sin; 00229 socklen_t sinlen; 00230 struct ast_tcptls_session_instance *tcptls_session; 00231 pthread_t launched; 00232 00233 for (;;) { 00234 int i, flags; 00235 00236 if (desc->periodic_fn) 00237 desc->periodic_fn(desc); 00238 i = ast_wait_for_input(desc->accept_fd, desc->poll_timeout); 00239 if (i <= 0) 00240 continue; 00241 sinlen = sizeof(sin); 00242 fd = accept(desc->accept_fd, (struct sockaddr *) &sin, &sinlen); 00243 if (fd < 0) { 00244 if ((errno != EAGAIN) && (errno != EINTR)) 00245 ast_log(LOG_WARNING, "Accept failed: %s\n", strerror(errno)); 00246 continue; 00247 } 00248 tcptls_session = ao2_alloc(sizeof(*tcptls_session), session_instance_destructor); 00249 if (!tcptls_session) { 00250 ast_log(LOG_WARNING, "No memory for new session: %s\n", strerror(errno)); 00251 close(fd); 00252 continue; 00253 } 00254 00255 ast_mutex_init(&tcptls_session->lock); 00256 00257 flags = fcntl(fd, F_GETFL); 00258 fcntl(fd, F_SETFL, flags & ~O_NONBLOCK); 00259 tcptls_session->fd = fd; 00260 tcptls_session->parent = desc; 00261 memcpy(&tcptls_session->remote_address, &sin, sizeof(tcptls_session->remote_address)); 00262 00263 tcptls_session->client = 0; 00264 00265 if (ast_pthread_create_detached_background(&launched, NULL, handle_tls_connection, tcptls_session)) { 00266 ast_log(LOG_WARNING, "Unable to launch helper thread: %s\n", strerror(errno)); 00267 close(tcptls_session->fd); 00268 ao2_ref(tcptls_session, -1); 00269 } 00270 } 00271 return NULL; 00272 }
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().
Definition at line 408 of file tcptls.c.
References ast_debug, ast_inet_ntoa(), ast_log(), ast_pthread_create_background, AST_PTHREADT_NULL, desc, errno, and LOG_ERROR.
00409 { 00410 int flags; 00411 int x = 1; 00412 00413 /* Do nothing if nothing has changed */ 00414 if (!memcmp(&desc->old_address, &desc->local_address, sizeof(desc->old_address))) { 00415 ast_debug(1, "Nothing changed in %s\n", desc->name); 00416 return; 00417 } 00418 00419 desc->old_address = desc->local_address; 00420 00421 /* Shutdown a running server if there is one */ 00422 if (desc->master != AST_PTHREADT_NULL) { 00423 pthread_cancel(desc->master); 00424 pthread_kill(desc->master, SIGURG); 00425 pthread_join(desc->master, NULL); 00426 } 00427 00428 if (desc->accept_fd != -1) 00429 close(desc->accept_fd); 00430 00431 /* If there's no new server, stop here */ 00432 if (desc->local_address.sin_family == 0) { 00433 return; 00434 } 00435 00436 desc->accept_fd = socket(AF_INET, SOCK_STREAM, 0); 00437 if (desc->accept_fd < 0) { 00438 ast_log(LOG_ERROR, "Unable to allocate socket for %s: %s\n", 00439 desc->name, strerror(errno)); 00440 return; 00441 } 00442 00443 setsockopt(desc->accept_fd, SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x)); 00444 if (bind(desc->accept_fd, (struct sockaddr *) &desc->local_address, sizeof(desc->local_address))) { 00445 ast_log(LOG_ERROR, "Unable to bind %s to %s:%d: %s\n", 00446 desc->name, 00447 ast_inet_ntoa(desc->local_address.sin_addr), ntohs(desc->local_address.sin_port), 00448 strerror(errno)); 00449 goto error; 00450 } 00451 if (listen(desc->accept_fd, 10)) { 00452 ast_log(LOG_ERROR, "Unable to listen for %s!\n", desc->name); 00453 goto error; 00454 } 00455 flags = fcntl(desc->accept_fd, F_GETFL); 00456 fcntl(desc->accept_fd, F_SETFL, flags | O_NONBLOCK); 00457 if (ast_pthread_create_background(&desc->master, NULL, desc->accept_fn, desc)) { 00458 ast_log(LOG_ERROR, "Unable to launch thread for %s on %s:%d: %s\n", 00459 desc->name, 00460 ast_inet_ntoa(desc->local_address.sin_addr), ntohs(desc->local_address.sin_port), 00461 strerror(errno)); 00462 goto error; 00463 } 00464 return; 00465 00466 error: 00467 close(desc->accept_fd); 00468 desc->accept_fd = -1; 00469 }
void ast_tcptls_server_stop | ( | struct ast_tcptls_session_args * | desc | ) |
Shutdown a running server if there is one.
Definition at line 471 of file tcptls.c.
References AST_PTHREADT_NULL, and desc.
Referenced by unload_module().
00472 { 00473 if (desc->master != AST_PTHREADT_NULL) { 00474 pthread_cancel(desc->master); 00475 pthread_kill(desc->master, SIGURG); 00476 pthread_join(desc->master, NULL); 00477 } 00478 if (desc->accept_fd != -1) 00479 close(desc->accept_fd); 00480 desc->accept_fd = -1; 00481 }
HOOK_T ast_tcptls_server_write | ( | struct ast_tcptls_session_instance * | ser, | |
void * | buf, | |||
size_t | count | |||
) |
Definition at line 100 of file tcptls.c.
References ast_log(), errno, ast_tcptls_session_instance::fd, LOG_ERROR, ast_tcptls_session_instance::ssl, and ssl_write().
Referenced by __sip_xmit().
00101 { 00102 if (tcptls_session->fd == -1) { 00103 ast_log(LOG_ERROR, "server_write called with an fd of -1\n"); 00104 errno = EIO; 00105 return -1; 00106 } 00107 00108 #ifdef DO_SSL 00109 if (tcptls_session->ssl) 00110 return ssl_write(tcptls_session->ssl, buf, count); 00111 #endif 00112 return write(tcptls_session->fd, buf, count); 00113 }