25#include <openssl/err.h>
26#include <openssl/opensslv.h>
27#include <openssl/ssl.h>
29#include <sys/socket.h>
53#define ERR2STR_BUFSIZE 128
55static const char *ssl_error_to_string(
int sslerr,
int ret)
59 return "Internal SSL error";
60 case SSL_ERROR_SYSCALL:
62 return "System call EOF";
63 }
else if (ret == -1) {
71 snprintf(
buf, ERR2STR_BUFSIZE,
"Underlying BIO error: %s", strerror(
errno));
74 return "System call other";
96 if (stream->
ssl && SSL_pending(stream->
ssl)) {
125 stream->
start.tv_sec = 0;
134 stream->
start.tv_sec = 0;
143 stream->
start = start;
157 struct timeval start;
161 if (stream->
start.tv_sec) {
162 start = stream->
start;
172 res = SSL_read(stream->
ssl,
buf, size);
178 sslerr = SSL_get_error(stream->
ssl, res);
180 case SSL_ERROR_ZERO_RETURN:
182 ast_debug(1,
"TLS clean shutdown alert reading data\n");
184 case SSL_ERROR_WANT_READ:
201 ast_debug(1,
"TLS socket error waiting for read data: %s\n",
207 case SSL_ERROR_WANT_WRITE:
219 ast_debug(1,
"TLS socket error waiting for write space: %s\n",
225 case SSL_ERROR_SYSCALL:
229 ast_debug(1,
"TLS non-recoverable I/O error occurred: %s, %s\n", ERR_error_string(sslerr, err),
230 ssl_error_to_string(sslerr, res));
234 ast_debug(1,
"TLS transport or SSL error reading data: %s, %s\n", ERR_error_string(sslerr, err),
235 ssl_error_to_string(sslerr, res));
240 ast_debug(1,
"TLS timeout reading data\n");
248 res = read(stream->
fd,
buf, size);
259 ast_debug(1,
"TCP socket error reading data: %s\n",
266 ast_debug(1,
"TCP timeout reading data\n");
280 if (!stream || stream->
fd == -1) {
291 memcpy(buffer, stream->
rbufhead, r);
302 size_t remaining = size;
303 ssize_t accum_size = 0;
312 if (
len > remaining - 1) {
319 if (stream->
rbuflen >= remaining - 1) {
349 memcpy(buffer + accum_size, stream->
rbufhead,
len);
350 buffer[accum_size +
len] = 0;
354 return accum_size +
len;
360 size_t remaining = size;
376 struct timeval start;
387 if (!stream || stream->
fd == -1) {
392 if (stream->
start.tv_sec) {
393 start = stream->
start;
405 res = SSL_write(stream->
ssl, buffer + written, remaining);
406 if (res == remaining) {
416 sslerr = SSL_get_error(stream->
ssl, res);
418 case SSL_ERROR_ZERO_RETURN:
419 ast_debug(1,
"TLS clean shutdown alert writing data\n");
426 case SSL_ERROR_WANT_READ:
430 ast_debug(1,
"TLS timeout writing data (want read)\n");
435 case SSL_ERROR_WANT_WRITE:
439 ast_debug(1,
"TLS timeout writing data (want write)\n");
446 ast_debug(1,
"TLS transport or SSL error writing data: %s, %s\n", ERR_error_string(sslerr, err),
447 ssl_error_to_string(sslerr, res));
462 res = write(stream->
fd, buffer + written, remaining);
463 if (res == remaining) {
484 ast_debug(1,
"TCP timeout writing data\n");
493 char sbuf[512], *
buf = sbuf;
494 int len, len2, ret = -1;
497 va_start(va, format);
498 len = vsnprintf(
buf,
sizeof(sbuf), format, va);
501 if (
len >
sizeof(sbuf) - 1) {
503 size_t buf_len =
len + 1;
509 va_start(va, format);
510 len2 = vsnprintf(
buf, buf_len, format, va);
535 if (stream->
fd != -1) {
548 res = SSL_shutdown(stream->
ssl);
550 int sslerr = SSL_get_error(stream->
ssl, res);
553 ERR_error_string(sslerr, err), ssl_error_to_string(sslerr, res));
556#if !(defined(LIBRESSL_VERSION_NUMBER) && (LIBRESSL_VERSION_NUMBER < 0x2070000L)) && (OPENSSL_VERSION_NUMBER >= 0x10100000L)
557 if (!SSL_is_server(stream->
ssl)) {
559 if (!stream->
ssl->server) {
562#if defined(LIBRESSL_VERSION_NUMBER) || (OPENSSL_VERSION_NUMBER < 0x10100000L)
563#if OPENSSL_VERSION_NUMBER >= 0x10000000L
564 ERR_remove_thread_state(
NULL);
571 SSL_free(stream->
ssl);
581 shutdown(stream->
fd, SHUT_RDWR);
582 if (close(stream->
fd)) {
587 ao2_t_ref(stream, -1,
"Closed ast_iostream");
624 int (*ssl_setup)(
SSL *) = client ? SSL_connect : SSL_accept;
627 stream->
ssl = SSL_new(ssl_ctx);
640 SSL_set_fd(stream->
ssl, stream->
fd);
642 res = ssl_setup(stream->
ssl);
644 int sslerr = SSL_get_error(stream->
ssl, res);
648 ERR_error_string(sslerr, err), ssl_error_to_string(sslerr, res));
Asterisk main include file. File version handling, generic pbx functions.
#define ast_malloc(len)
A wrapper for malloc()
#define ao2_t_ref(o, delta, tag)
@ AO2_ALLOC_OPT_LOCK_NOLOCK
#define ao2_alloc_options(data_size, destructor_fn, options)
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
Support for logging to various files, console and syslog Configuration in file logger....
#define ast_debug(level,...)
Log a DEBUG message.
ssize_t ast_iostream_printf(struct ast_iostream *stream, const char *format,...)
Write a formatted string to an iostream.
ssize_t ast_iostream_gets(struct ast_iostream *stream, char *buffer, size_t size)
Read a LF-terminated string from an iostream.
ssize_t ast_iostream_discard(struct ast_iostream *stream, size_t size)
Discard the specified number of bytes from an iostream.
ssize_t ast_iostream_write(struct ast_iostream *stream, const void *buffer, size_t size)
Write data to an iostream.
void ast_iostream_set_timeout_inactivity(struct ast_iostream *stream, int timeout)
Set the iostream inactivity timeout timer.
struct ast_iostream * ast_iostream_from_fd(int *fd)
Create an iostream from a file descriptor.
void ast_iostream_set_timeout_idle_inactivity(struct ast_iostream *stream, int timeout, int timeout_reset)
Set the iostream inactivity & idle timeout timers.
SSL * ast_iostream_get_ssl(struct ast_iostream *stream)
Get a pointer to an iostream's OpenSSL SSL structure.
int ast_iostream_get_fd(struct ast_iostream *stream)
Get an iostream's file descriptor.
int ast_iostream_start_tls(struct ast_iostream **pstream, SSL_CTX *ssl_ctx, int client)
Begin TLS on an iostream.
void ast_iostream_set_exclusive_input(struct ast_iostream *stream, int exclusive_input)
Set the iostream if it can exclusively depend upon the set timeouts.
ssize_t ast_iostream_read(struct ast_iostream *stream, void *buffer, size_t count)
Read data from an iostream.
static ssize_t iostream_read(struct ast_iostream *stream, void *buf, size_t size)
void ast_iostream_set_timeout_sequence(struct ast_iostream *stream, struct timeval start, int timeout)
Set the iostream I/O sequence timeout timer.
void ast_iostream_nonblock(struct ast_iostream *stream)
Make an iostream non-blocking.
int ast_iostream_close(struct ast_iostream *stream)
Close an iostream.
void ast_iostream_set_timeout_disable(struct ast_iostream *stream)
Disable the iostream timeout timer.
int ast_iostream_wait_for_input(struct ast_iostream *stream, int timeout)
Wait for input on the iostream's file descriptor.
static void iostream_dtor(void *cookie)
Generic abstraction for input/output streams.
struct ssl_ctx_st SSL_CTX
String manipulation functions.
Definitions to aid in the use of thread local storage.
void * ast_threadstorage_get(struct ast_threadstorage *ts, size_t init_size)
Retrieve thread storage.
#define AST_THREADSTORAGE(name)
Define a thread storage variable.
Time-related functions and macros.
int ast_remaining_ms(struct timeval start, int max_ms)
Calculate remaining milliseconds given a starting timestamp and upper bound.
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
int error(const char *format,...)
int ast_wait_for_input(int fd, int ms)
int ast_wait_for_output(int fd, int ms)
#define ast_fd_set_flags(fd, flags)
Set flags on the given file descriptor.