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 59 return "Internal SSL error";
60 case SSL_ERROR_SYSCALL:
62 return "System call EOF";
63 }
else if (ret == -1) {
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;
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),
234 ast_debug(1,
"TLS transport or SSL error reading data: %s, %s\n", ERR_error_string(sslerr, err),
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;
311 len = newline - stream->
rbufhead + 1;
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;
364 ret =
ast_iostream_read(stream, buf, remaining >
sizeof(buf) ?
sizeof(buf) : remaining);
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),
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);
556 #if !defined(LIBRESSL_VERSION_NUMBER) && (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);
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
#define AST_THREADSTORAGE(name)
Define a thread storage variable.
ssize_t ast_iostream_write(struct ast_iostream *stream, const void *buffer, size_t size)
Write data to an iostream.
static const char * ssl_error_to_string(int sslerr, int ret)
Asterisk main include file. File version handling, generic pbx functions.
void * ast_threadstorage_get(struct ast_threadstorage *ts, size_t init_size)
Retrieve thread storage.
String manipulation functions.
Time-related functions and macros.
ssize_t ast_iostream_discard(struct ast_iostream *stream, size_t size)
Discard the specified number of bytes from 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.
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
#define ao2_alloc_options(data_size, destructor_fn, options)
Definitions to aid in the use of thread local storage.
static struct ast_threadstorage err2str_threadbuf
struct ast_iostream * ast_iostream_from_fd(int *fd)
Create an iostream from a file descriptor.
#define ast_fd_set_flags(fd, flags)
Set flags on the given file descriptor.
#define ast_debug(level,...)
Log a DEBUG message.
int ast_iostream_start_tls(struct ast_iostream **pstream, SSL_CTX *ssl_ctx, int client)
Begin TLS on an iostream.
void ast_iostream_nonblock(struct ast_iostream *stream)
Make an iostream non-blocking.
void ast_iostream_set_timeout_sequence(struct ast_iostream *stream, struct timeval start, int timeout)
Set the iostream I/O sequence timeout timer.
int ast_iostream_close(struct ast_iostream *stream)
Close an iostream.
#define ast_malloc(len)
A wrapper for malloc()
SSL * ast_iostream_get_ssl(struct ast_iostream *stream)
Get a pointer to an iostream's OpenSSL SSL structure.
void ast_iostream_set_timeout_idle_inactivity(struct ast_iostream *stream, int timeout, int timeout_reset)
Set the iostream inactivity & idle timeout timers.
int ast_remaining_ms(struct timeval start, int max_ms)
Calculate remaining milliseconds given a starting timestamp and upper bound.
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
void ast_iostream_set_timeout_inactivity(struct ast_iostream *stream, int timeout)
Set the iostream inactivity timeout timer.
static void iostream_dtor(void *cookie)
ssize_t ast_iostream_printf(struct ast_iostream *stream, const char *format,...)
Write a formatted string to an iostream.
Generic abstraction for input/output streams.
Support for logging to various files, console and syslog Configuration in file logger.conf.
int ast_wait_for_output(int fd, int ms)
void ast_iostream_set_timeout_disable(struct ast_iostream *stream)
Disable the iostream timeout timer.
struct ssl_ctx_st SSL_CTX
int ast_iostream_get_fd(struct ast_iostream *stream)
Get an iostream's file descriptor.
static ssize_t iostream_read(struct ast_iostream *stream, void *buf, size_t size)
int error(const char *format,...)
int ast_wait_for_input(int fd, int ms)
ssize_t ast_iostream_gets(struct ast_iostream *stream, char *buffer, size_t size)
Read a LF-terminated string from an iostream.
static snd_pcm_format_t format
ssize_t ast_iostream_read(struct ast_iostream *stream, void *buffer, size_t count)
Read data from an iostream.
int ast_iostream_wait_for_input(struct ast_iostream *stream, int timeout)
Wait for input on the iostream's file descriptor.