076f94baeb2506420de6f69270e57f7ae6b7455a
[asterisk/asterisk.git] / main / tcptls.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2007 - 2008, Digium, Inc.
5  *
6  * Luigi Rizzo (TCP and TLS server code)
7  * Brett Bryant <brettbryant@gmail.com> (updated for client support)
8  *
9  * See http://www.asterisk.org for more information about
10  * the Asterisk project. Please do not directly contact
11  * any of the maintainers of this project for assistance;
12  * the project provides a web site, mailing lists and IRC
13  * channels for your use.
14  *
15  * This program is free software, distributed under the terms of
16  * the GNU General Public License Version 2. See the LICENSE file
17  * at the top of the source tree.
18  */
19
20 /*!
21  * \file
22  * \brief Code to support TCP and TLS server/client
23  *
24  * \author Luigi Rizzo
25  * \author Brett Bryant <brettbryant@gmail.com>
26  */
27
28 /*** MODULEINFO
29         <support_level>core</support_level>
30  ***/
31
32 #include "asterisk.h"
33
34 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
35
36 #ifdef HAVE_FCNTL_H
37 #include <fcntl.h>
38 #endif
39
40 #include <signal.h>
41 #include <sys/signal.h>
42
43 #include "asterisk/compat.h"
44 #include "asterisk/tcptls.h"
45 #include "asterisk/http.h"
46 #include "asterisk/utils.h"
47 #include "asterisk/strings.h"
48 #include "asterisk/options.h"
49 #include "asterisk/manager.h"
50 #include "asterisk/astobj2.h"
51 #include "asterisk/pbx.h"
52
53 /*! ao2 object used for the FILE stream fopencookie()/funopen() cookie. */
54 struct ast_tcptls_stream {
55         /*! SSL state if not NULL */
56         SSL *ssl;
57         /*!
58          * \brief Start time from when an I/O sequence must complete
59          * by struct ast_tcptls_stream.timeout.
60          *
61          * \note If struct ast_tcptls_stream.start.tv_sec is zero then
62          * start time is the current I/O request.
63          */
64         struct timeval start;
65         /*!
66          * \brief The socket returned by accept().
67          *
68          * \note Set to -1 if the stream is closed.
69          */
70         int fd;
71         /*!
72          * \brief Timeout in ms relative to struct ast_tcptls_stream.start
73          * to wait for an event on struct ast_tcptls_stream.fd.
74          *
75          * \note Set to -1 to disable timeout.
76          * \note The socket needs to be set to non-blocking for the timeout
77          * feature to work correctly.
78          */
79         int timeout;
80 };
81
82 void ast_tcptls_stream_set_timeout_disable(struct ast_tcptls_stream *stream)
83 {
84         ast_assert(stream != NULL);
85
86         stream->timeout = -1;
87 }
88
89 void ast_tcptls_stream_set_timeout_inactivity(struct ast_tcptls_stream *stream, int timeout)
90 {
91         ast_assert(stream != NULL);
92
93         stream->start.tv_sec = 0;
94         stream->timeout = timeout;
95 }
96
97 void ast_tcptls_stream_set_timeout_sequence(struct ast_tcptls_stream *stream, struct timeval start, int timeout)
98 {
99         ast_assert(stream != NULL);
100
101         stream->start = start;
102         stream->timeout = timeout;
103 }
104
105 /*!
106  * \internal
107  * \brief fopencookie()/funopen() stream read function.
108  *
109  * \param cookie Stream control data.
110  * \param buf Where to put read data.
111  * \param size Size of the buffer.
112  *
113  * \retval number of bytes put into buf.
114  * \retval 0 on end of file.
115  * \retval -1 on error.
116  */
117 static HOOK_T tcptls_stream_read(void *cookie, char *buf, LEN_T size)
118 {
119         struct ast_tcptls_stream *stream = cookie;
120         struct timeval start;
121         int ms;
122         int res;
123
124         if (!size) {
125                 /* You asked for no data you got no data. */
126                 return 0;
127         }
128
129         if (!stream || stream->fd == -1) {
130                 errno = EBADF;
131                 return -1;
132         }
133
134         if (stream->start.tv_sec) {
135                 start = stream->start;
136         } else {
137                 start = ast_tvnow();
138         }
139
140 #if defined(DO_SSL)
141         if (stream->ssl) {
142                 for (;;) {
143                         res = SSL_read(stream->ssl, buf, size);
144                         if (0 < res) {
145                                 /* We read some payload data. */
146                                 return res;
147                         }
148                         switch (SSL_get_error(stream->ssl, res)) {
149                         case SSL_ERROR_ZERO_RETURN:
150                                 /* Report EOF for a shutdown */
151                                 ast_debug(1, "TLS clean shutdown alert reading data\n");
152                                 return 0;
153                         case SSL_ERROR_WANT_READ:
154                                 while ((ms = ast_remaining_ms(start, stream->timeout))) {
155                                         res = ast_wait_for_input(stream->fd, ms);
156                                         if (0 < res) {
157                                                 /* Socket is ready to be read. */
158                                                 break;
159                                         }
160                                         if (res < 0) {
161                                                 if (errno == EINTR || errno == EAGAIN) {
162                                                         /* Try again. */
163                                                         continue;
164                                                 }
165                                                 ast_debug(1, "TLS socket error waiting for read data: %s\n",
166                                                         strerror(errno));
167                                                 return -1;
168                                         }
169                                 }
170                                 break;
171                         case SSL_ERROR_WANT_WRITE:
172                                 while ((ms = ast_remaining_ms(start, stream->timeout))) {
173                                         res = ast_wait_for_output(stream->fd, ms);
174                                         if (0 < res) {
175                                                 /* Socket is ready to be written. */
176                                                 break;
177                                         }
178                                         if (res < 0) {
179                                                 if (errno == EINTR || errno == EAGAIN) {
180                                                         /* Try again. */
181                                                         continue;
182                                                 }
183                                                 ast_debug(1, "TLS socket error waiting for write space: %s\n",
184                                                         strerror(errno));
185                                                 return -1;
186                                         }
187                                 }
188                                 break;
189                         default:
190                                 /* Report EOF for an undecoded SSL or transport error. */
191                                 ast_debug(1, "TLS transport or SSL error reading data\n");
192                                 return 0;
193                         }
194                         if (!ms) {
195                                 /* Report EOF for a timeout */
196                                 ast_debug(1, "TLS timeout reading data\n");
197                                 return 0;
198                         }
199                 }
200         }
201 #endif  /* defined(DO_SSL) */
202
203         for (;;) {
204                 res = read(stream->fd, buf, size);
205                 if (0 <= res) {
206                         return res;
207                 }
208                 if (errno != EINTR && errno != EAGAIN) {
209                         /* Not a retryable error. */
210                         ast_debug(1, "TCP socket error reading data: %s\n",
211                                 strerror(errno));
212                         return -1;
213                 }
214                 ms = ast_remaining_ms(start, stream->timeout);
215                 if (!ms) {
216                         /* Report EOF for a timeout */
217                         ast_debug(1, "TCP timeout reading data\n");
218                         return 0;
219                 }
220                 ast_wait_for_input(stream->fd, ms);
221         }
222 }
223
224 /*!
225  * \internal
226  * \brief fopencookie()/funopen() stream write function.
227  *
228  * \param cookie Stream control data.
229  * \param buf Where to get data to write.
230  * \param size Size of the buffer.
231  *
232  * \retval number of bytes written from buf.
233  * \retval -1 on error.
234  */
235 static HOOK_T tcptls_stream_write(void *cookie, const char *buf, LEN_T size)
236 {
237         struct ast_tcptls_stream *stream = cookie;
238         struct timeval start;
239         int ms;
240         int res;
241         int written;
242         int remaining;
243
244         if (!size) {
245                 /* You asked to write no data you wrote no data. */
246                 return 0;
247         }
248
249         if (!stream || stream->fd == -1) {
250                 errno = EBADF;
251                 return -1;
252         }
253
254         if (stream->start.tv_sec) {
255                 start = stream->start;
256         } else {
257                 start = ast_tvnow();
258         }
259
260 #if defined(DO_SSL)
261         if (stream->ssl) {
262                 written = 0;
263                 remaining = size;
264                 for (;;) {
265                         res = SSL_write(stream->ssl, buf + written, remaining);
266                         if (res == remaining) {
267                                 /* Everything was written. */
268                                 return size;
269                         }
270                         if (0 < res) {
271                                 /* Successfully wrote part of the buffer.  Try to write the rest. */
272                                 written += res;
273                                 remaining -= res;
274                                 continue;
275                         }
276                         switch (SSL_get_error(stream->ssl, res)) {
277                         case SSL_ERROR_ZERO_RETURN:
278                                 ast_debug(1, "TLS clean shutdown alert writing data\n");
279                                 if (written) {
280                                         /* Report partial write. */
281                                         return written;
282                                 }
283                                 errno = EBADF;
284                                 return -1;
285                         case SSL_ERROR_WANT_READ:
286                                 ms = ast_remaining_ms(start, stream->timeout);
287                                 if (!ms) {
288                                         /* Report partial write. */
289                                         ast_debug(1, "TLS timeout writing data (want read)\n");
290                                         return written;
291                                 }
292                                 ast_wait_for_input(stream->fd, ms);
293                                 break;
294                         case SSL_ERROR_WANT_WRITE:
295                                 ms = ast_remaining_ms(start, stream->timeout);
296                                 if (!ms) {
297                                         /* Report partial write. */
298                                         ast_debug(1, "TLS timeout writing data (want write)\n");
299                                         return written;
300                                 }
301                                 ast_wait_for_output(stream->fd, ms);
302                                 break;
303                         default:
304                                 /* Undecoded SSL or transport error. */
305                                 ast_debug(1, "TLS transport or SSL error writing data\n");
306                                 if (written) {
307                                         /* Report partial write. */
308                                         return written;
309                                 }
310                                 errno = EBADF;
311                                 return -1;
312                         }
313                 }
314         }
315 #endif  /* defined(DO_SSL) */
316
317         written = 0;
318         remaining = size;
319         for (;;) {
320                 res = write(stream->fd, buf + written, remaining);
321                 if (res == remaining) {
322                         /* Yay everything was written. */
323                         return size;
324                 }
325                 if (0 < res) {
326                         /* Successfully wrote part of the buffer.  Try to write the rest. */
327                         written += res;
328                         remaining -= res;
329                         continue;
330                 }
331                 if (errno != EINTR && errno != EAGAIN) {
332                         /* Not a retryable error. */
333                         ast_debug(1, "TCP socket error writing: %s\n", strerror(errno));
334                         if (written) {
335                                 return written;
336                         }
337                         return -1;
338                 }
339                 ms = ast_remaining_ms(start, stream->timeout);
340                 if (!ms) {
341                         /* Report partial write. */
342                         ast_debug(1, "TCP timeout writing data\n");
343                         return written;
344                 }
345                 ast_wait_for_output(stream->fd, ms);
346         }
347 }
348
349 /*!
350  * \internal
351  * \brief fopencookie()/funopen() stream close function.
352  *
353  * \param cookie Stream control data.
354  *
355  * \retval 0 on success.
356  * \retval -1 on error.
357  */
358 static int tcptls_stream_close(void *cookie)
359 {
360         struct ast_tcptls_stream *stream = cookie;
361
362         if (!stream) {
363                 errno = EBADF;
364                 return -1;
365         }
366
367         if (stream->fd != -1) {
368 #if defined(DO_SSL)
369                 if (stream->ssl) {
370                         int res;
371
372                         /*
373                          * According to the TLS standard, it is acceptable for an
374                          * application to only send its shutdown alert and then
375                          * close the underlying connection without waiting for
376                          * the peer's response (this way resources can be saved,
377                          * as the process can already terminate or serve another
378                          * connection).
379                          */
380                         res = SSL_shutdown(stream->ssl);
381                         if (res < 0) {
382                                 ast_log(LOG_ERROR, "SSL_shutdown() failed: %d\n",
383                                         SSL_get_error(stream->ssl, res));
384                         }
385
386                         if (!stream->ssl->server) {
387                                 /* For client threads, ensure that the error stack is cleared */
388                                 ERR_remove_state(0);
389                         }
390
391                         SSL_free(stream->ssl);
392                         stream->ssl = NULL;
393                 }
394 #endif  /* defined(DO_SSL) */
395
396                 /*
397                  * Issuing shutdown() is necessary here to avoid a race
398                  * condition where the last data written may not appear
399                  * in the TCP stream.  See ASTERISK-23548
400                  */
401                 shutdown(stream->fd, SHUT_RDWR);
402                 if (close(stream->fd)) {
403                         ast_log(LOG_ERROR, "close() failed: %s\n", strerror(errno));
404                 }
405                 stream->fd = -1;
406         }
407         ao2_t_ref(stream, -1, "Closed tcptls stream cookie");
408
409         return 0;
410 }
411
412 /*!
413  * \internal
414  * \brief fopencookie()/funopen() stream destructor function.
415  *
416  * \param cookie Stream control data.
417  *
418  * \return Nothing
419  */
420 static void tcptls_stream_dtor(void *cookie)
421 {
422         struct ast_tcptls_stream *stream = cookie;
423
424         ast_assert(stream->fd == -1);
425 }
426
427 /*!
428  * \internal
429  * \brief fopencookie()/funopen() stream allocation function.
430  *
431  * \retval stream_cookie on success.
432  * \retval NULL on error.
433  */
434 static struct ast_tcptls_stream *tcptls_stream_alloc(void)
435 {
436         struct ast_tcptls_stream *stream;
437
438         stream = ao2_alloc_options(sizeof(*stream), tcptls_stream_dtor,
439                 AO2_ALLOC_OPT_LOCK_NOLOCK);
440         if (stream) {
441                 stream->fd = -1;
442                 stream->timeout = -1;
443         }
444         return stream;
445 }
446
447 /*!
448  * \internal
449  * \brief Open a custom FILE stream for tcptls.
450  *
451  * \param stream Stream cookie control data.
452  * \param ssl SSL state if not NULL.
453  * \param fd Socket file descriptor.
454  * \param timeout ms to wait for an event on fd. -1 if timeout disabled.
455  *
456  * \retval fp on success.
457  * \retval NULL on error.
458  */
459 static FILE *tcptls_stream_fopen(struct ast_tcptls_stream *stream, SSL *ssl, int fd, int timeout)
460 {
461         FILE *fp;
462
463 #if defined(HAVE_FOPENCOOKIE)   /* the glibc/linux interface */
464         static const cookie_io_functions_t cookie_funcs = {
465                 tcptls_stream_read,
466                 tcptls_stream_write,
467                 NULL,
468                 tcptls_stream_close
469         };
470 #endif  /* defined(HAVE_FOPENCOOKIE) */
471
472         if (fd == -1) {
473                 /* Socket not open. */
474                 return NULL;
475         }
476
477         stream->ssl = ssl;
478         stream->fd = fd;
479         stream->timeout = timeout;
480         ao2_t_ref(stream, +1, "Opening tcptls stream cookie");
481
482 #if defined(HAVE_FUNOPEN)       /* the BSD interface */
483         fp = funopen(stream, tcptls_stream_read, tcptls_stream_write, NULL,
484                 tcptls_stream_close);
485 #elif defined(HAVE_FOPENCOOKIE) /* the glibc/linux interface */
486         fp = fopencookie(stream, "w+", cookie_funcs);
487 #else
488         /* could add other methods here */
489         ast_debug(2, "No stream FILE methods attempted!\n");
490         fp = NULL;
491 #endif
492
493         if (!fp) {
494                 stream->fd = -1;
495                 ao2_t_ref(stream, -1, "Failed to open tcptls stream cookie");
496         }
497         return fp;
498 }
499
500 HOOK_T ast_tcptls_server_read(struct ast_tcptls_session_instance *tcptls_session, void *buf, size_t count)
501 {
502         if (!tcptls_session->stream_cookie || tcptls_session->stream_cookie->fd == -1) {
503                 ast_log(LOG_ERROR, "TCP/TLS read called on invalid stream.\n");
504                 errno = EIO;
505                 return -1;
506         }
507
508         return tcptls_stream_read(tcptls_session->stream_cookie, buf, count);
509 }
510
511 HOOK_T ast_tcptls_server_write(struct ast_tcptls_session_instance *tcptls_session, const void *buf, size_t count)
512 {
513         if (!tcptls_session->stream_cookie || tcptls_session->stream_cookie->fd == -1) {
514                 ast_log(LOG_ERROR, "TCP/TLS write called on invalid stream.\n");
515                 errno = EIO;
516                 return -1;
517         }
518
519         return tcptls_stream_write(tcptls_session->stream_cookie, buf, count);
520 }
521
522 static void session_instance_destructor(void *obj)
523 {
524         struct ast_tcptls_session_instance *i = obj;
525
526         if (i->stream_cookie) {
527                 ao2_t_ref(i->stream_cookie, -1, "Destroying tcptls session instance");
528                 i->stream_cookie = NULL;
529         }
530         ast_free(i->overflow_buf);
531 }
532
533 /*! \brief
534 * creates a FILE * from the fd passed by the accept thread.
535 * This operation is potentially expensive (certificate verification),
536 * so we do it in the child thread context.
537 *
538 * \note must decrement ref count before returning NULL on error
539 */
540 static void *handle_tcptls_connection(void *data)
541 {
542         struct ast_tcptls_session_instance *tcptls_session = data;
543 #ifdef DO_SSL
544         int (*ssl_setup)(SSL *) = (tcptls_session->client) ? SSL_connect : SSL_accept;
545         int ret;
546         char err[256];
547 #endif
548
549         /* TCP/TLS connections are associated with external protocols, and
550          * should not be allowed to execute 'dangerous' functions. This may
551          * need to be pushed down into the individual protocol handlers, but
552          * this seems like a good general policy.
553          */
554         if (ast_thread_inhibit_escalations()) {
555                 ast_log(LOG_ERROR, "Failed to inhibit privilege escalations; killing connection\n");
556                 ast_tcptls_close_session_file(tcptls_session);
557                 ao2_ref(tcptls_session, -1);
558                 return NULL;
559         }
560
561         tcptls_session->stream_cookie = tcptls_stream_alloc();
562         if (!tcptls_session->stream_cookie) {
563                 ast_tcptls_close_session_file(tcptls_session);
564                 ao2_ref(tcptls_session, -1);
565                 return NULL;
566         }
567
568         /*
569         * open a FILE * as appropriate.
570         */
571         if (!tcptls_session->parent->tls_cfg) {
572                 tcptls_session->f = tcptls_stream_fopen(tcptls_session->stream_cookie, NULL,
573                         tcptls_session->fd, -1);
574                 if (tcptls_session->f) {
575                         if (setvbuf(tcptls_session->f, NULL, _IONBF, 0)) {
576                                 ast_tcptls_close_session_file(tcptls_session);
577                         }
578                 }
579         }
580 #ifdef DO_SSL
581         else if ( (tcptls_session->ssl = SSL_new(tcptls_session->parent->tls_cfg->ssl_ctx)) ) {
582                 SSL_set_fd(tcptls_session->ssl, tcptls_session->fd);
583                 if ((ret = ssl_setup(tcptls_session->ssl)) <= 0) {
584                         ast_log(LOG_ERROR, "Problem setting up ssl connection: %s\n", ERR_error_string(ERR_get_error(), err));
585                 } else if ((tcptls_session->f = tcptls_stream_fopen(tcptls_session->stream_cookie,
586                         tcptls_session->ssl, tcptls_session->fd, -1))) {
587                         if ((tcptls_session->client && !ast_test_flag(&tcptls_session->parent->tls_cfg->flags, AST_SSL_DONT_VERIFY_SERVER))
588                                 || (!tcptls_session->client && ast_test_flag(&tcptls_session->parent->tls_cfg->flags, AST_SSL_VERIFY_CLIENT))) {
589                                 X509 *peer;
590                                 long res;
591                                 peer = SSL_get_peer_certificate(tcptls_session->ssl);
592                                 if (!peer) {
593                                         ast_log(LOG_ERROR, "No peer SSL certificate to verify\n");
594                                         ast_tcptls_close_session_file(tcptls_session);
595                                         ao2_ref(tcptls_session, -1);
596                                         return NULL;
597                                 }
598
599                                 res = SSL_get_verify_result(tcptls_session->ssl);
600                                 if (res != X509_V_OK) {
601                                         ast_log(LOG_ERROR, "Certificate did not verify: %s\n", X509_verify_cert_error_string(res));
602                                         X509_free(peer);
603                                         ast_tcptls_close_session_file(tcptls_session);
604                                         ao2_ref(tcptls_session, -1);
605                                         return NULL;
606                                 }
607                                 if (!ast_test_flag(&tcptls_session->parent->tls_cfg->flags, AST_SSL_IGNORE_COMMON_NAME)) {
608                                         ASN1_STRING *str;
609                                         unsigned char *str2;
610                                         X509_NAME *name = X509_get_subject_name(peer);
611                                         int pos = -1;
612                                         int found = 0;
613
614                                         for (;;) {
615                                                 /* Walk the certificate to check all available "Common Name" */
616                                                 /* XXX Probably should do a gethostbyname on the hostname and compare that as well */
617                                                 pos = X509_NAME_get_index_by_NID(name, NID_commonName, pos);
618                                                 if (pos < 0) {
619                                                         break;
620                                                 }
621                                                 str = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name, pos));
622                                                 ASN1_STRING_to_UTF8(&str2, str);
623                                                 if (str2) {
624                                                         if (!strcasecmp(tcptls_session->parent->hostname, (char *) str2)) {
625                                                                 found = 1;
626                                                         }
627                                                         ast_debug(3, "SSL Common Name compare s1='%s' s2='%s'\n", tcptls_session->parent->hostname, str2);
628                                                         OPENSSL_free(str2);
629                                                 }
630                                                 if (found) {
631                                                         break;
632                                                 }
633                                         }
634                                         if (!found) {
635                                                 ast_log(LOG_ERROR, "Certificate common name did not match (%s)\n", tcptls_session->parent->hostname);
636                                                 X509_free(peer);
637                                                 ast_tcptls_close_session_file(tcptls_session);
638                                                 ao2_ref(tcptls_session, -1);
639                                                 return NULL;
640                                         }
641                                 }
642                                 X509_free(peer);
643                         }
644                 }
645                 if (!tcptls_session->f) {       /* no success opening descriptor stacking */
646                         SSL_free(tcptls_session->ssl);
647                 }
648         }
649 #endif /* DO_SSL */
650
651         if (!tcptls_session->f) {
652                 ast_tcptls_close_session_file(tcptls_session);
653                 ast_log(LOG_WARNING, "FILE * open failed!\n");
654 #ifndef DO_SSL
655                 if (tcptls_session->parent->tls_cfg) {
656                         ast_log(LOG_ERROR, "Attempted a TLS connection without OpenSSL support. This will not work!\n");
657                 }
658 #endif
659                 ao2_ref(tcptls_session, -1);
660                 return NULL;
661         }
662
663         if (tcptls_session->parent->worker_fn) {
664                 return tcptls_session->parent->worker_fn(tcptls_session);
665         } else {
666                 return tcptls_session;
667         }
668 }
669
670 void *ast_tcptls_server_root(void *data)
671 {
672         struct ast_tcptls_session_args *desc = data;
673         int fd;
674         struct ast_sockaddr addr;
675         struct ast_tcptls_session_instance *tcptls_session;
676         pthread_t launched;
677
678         for (;;) {
679                 int i, flags;
680
681                 if (desc->periodic_fn) {
682                         desc->periodic_fn(desc);
683                 }
684                 i = ast_wait_for_input(desc->accept_fd, desc->poll_timeout);
685                 if (i <= 0) {
686                         continue;
687                 }
688                 fd = ast_accept(desc->accept_fd, &addr);
689                 if (fd < 0) {
690                         if ((errno != EAGAIN) && (errno != EINTR)) {
691                                 ast_log(LOG_ERROR, "Accept failed: %s\n", strerror(errno));
692                         }
693                         continue;
694                 }
695                 tcptls_session = ao2_alloc(sizeof(*tcptls_session), session_instance_destructor);
696                 if (!tcptls_session) {
697                         ast_log(LOG_WARNING, "No memory for new session: %s\n", strerror(errno));
698                         if (close(fd)) {
699                                 ast_log(LOG_ERROR, "close() failed: %s\n", strerror(errno));
700                         }
701                         continue;
702                 }
703
704                 tcptls_session->overflow_buf = ast_str_create(128);
705                 flags = fcntl(fd, F_GETFL);
706                 fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
707                 tcptls_session->fd = fd;
708                 tcptls_session->parent = desc;
709                 ast_sockaddr_copy(&tcptls_session->remote_address, &addr);
710
711                 tcptls_session->client = 0;
712
713                 /* This thread is now the only place that controls the single ref to tcptls_session */
714                 if (ast_pthread_create_detached_background(&launched, NULL, handle_tcptls_connection, tcptls_session)) {
715                         ast_log(LOG_ERROR, "Unable to launch helper thread: %s\n", strerror(errno));
716                         ast_tcptls_close_session_file(tcptls_session);
717                         ao2_ref(tcptls_session, -1);
718                 }
719         }
720         return NULL;
721 }
722
723 static int __ssl_setup(struct ast_tls_config *cfg, int client)
724 {
725 #ifndef DO_SSL
726         cfg->enabled = 0;
727         return 0;
728 #else
729         if (!cfg->enabled) {
730                 return 0;
731         }
732
733         /* Get rid of an old SSL_CTX since we're about to
734          * allocate a new one
735          */
736         if (cfg->ssl_ctx) {
737                 SSL_CTX_free(cfg->ssl_ctx);
738                 cfg->ssl_ctx = NULL;
739         }
740
741         if (client) {
742 #ifndef OPENSSL_NO_SSL2
743                 if (ast_test_flag(&cfg->flags, AST_SSL_SSLV2_CLIENT)) {
744                         cfg->ssl_ctx = SSL_CTX_new(SSLv2_client_method());
745                 } else
746 #endif
747                 if (ast_test_flag(&cfg->flags, AST_SSL_SSLV3_CLIENT)) {
748                         cfg->ssl_ctx = SSL_CTX_new(SSLv3_client_method());
749                 } else if (ast_test_flag(&cfg->flags, AST_SSL_TLSV1_CLIENT)) {
750                         cfg->ssl_ctx = SSL_CTX_new(TLSv1_client_method());
751                 } else {
752                         /* SSLv23_client_method() sends SSLv2, this was the original
753                          * default for ssl clients before the option was given to
754                          * pick what protocol a client should use.  In order not
755                          * to break expected behavior it remains the default. */
756                         cfg->ssl_ctx = SSL_CTX_new(SSLv23_client_method());
757                 }
758         } else {
759                 /* SSLv23_server_method() supports TLSv1, SSLv2, and SSLv3 inbound connections. */
760                 cfg->ssl_ctx = SSL_CTX_new(SSLv23_server_method());
761         }
762
763         if (!cfg->ssl_ctx) {
764                 ast_debug(1, "Sorry, SSL_CTX_new call returned null...\n");
765                 cfg->enabled = 0;
766                 return 0;
767         }
768
769         SSL_CTX_set_verify(cfg->ssl_ctx,
770                 ast_test_flag(&cfg->flags, AST_SSL_VERIFY_CLIENT) ? SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT : SSL_VERIFY_NONE,
771                 NULL);
772
773         if (!ast_strlen_zero(cfg->certfile)) {
774                 char *tmpprivate = ast_strlen_zero(cfg->pvtfile) ? cfg->certfile : cfg->pvtfile;
775                 if (SSL_CTX_use_certificate_chain_file(cfg->ssl_ctx, cfg->certfile) == 0) {
776                         if (!client) {
777                                 /* Clients don't need a certificate, but if its setup we can use it */
778                                 ast_log(LOG_ERROR, "TLS/SSL error loading cert file. <%s>\n", cfg->certfile);
779                                 cfg->enabled = 0;
780                                 SSL_CTX_free(cfg->ssl_ctx);
781                                 cfg->ssl_ctx = NULL;
782                                 return 0;
783                         }
784                 }
785                 if ((SSL_CTX_use_PrivateKey_file(cfg->ssl_ctx, tmpprivate, SSL_FILETYPE_PEM) == 0) || (SSL_CTX_check_private_key(cfg->ssl_ctx) == 0 )) {
786                         if (!client) {
787                                 /* Clients don't need a private key, but if its setup we can use it */
788                                 ast_log(LOG_ERROR, "TLS/SSL error loading private key file. <%s>\n", tmpprivate);
789                                 cfg->enabled = 0;
790                                 SSL_CTX_free(cfg->ssl_ctx);
791                                 cfg->ssl_ctx = NULL;
792                                 return 0;
793                         }
794                 }
795         }
796         if (!ast_strlen_zero(cfg->cipher)) {
797                 if (SSL_CTX_set_cipher_list(cfg->ssl_ctx, cfg->cipher) == 0 ) {
798                         if (!client) {
799                                 ast_log(LOG_ERROR, "TLS/SSL cipher error <%s>\n", cfg->cipher);
800                                 cfg->enabled = 0;
801                                 SSL_CTX_free(cfg->ssl_ctx);
802                                 cfg->ssl_ctx = NULL;
803                                 return 0;
804                         }
805                 }
806         }
807         if (!ast_strlen_zero(cfg->cafile) || !ast_strlen_zero(cfg->capath)) {
808                 if (SSL_CTX_load_verify_locations(cfg->ssl_ctx, S_OR(cfg->cafile, NULL), S_OR(cfg->capath,NULL)) == 0) {
809                         ast_log(LOG_ERROR, "TLS/SSL CA file(%s)/path(%s) error\n", cfg->cafile, cfg->capath);
810                 }
811         }
812
813         ast_verb(2, "TLS/SSL certificate ok\n");        /* We should log which one that is ok. This message doesn't really make sense in production use */
814         return 1;
815 #endif
816 }
817
818 int ast_ssl_setup(struct ast_tls_config *cfg)
819 {
820         return __ssl_setup(cfg, 0);
821 }
822
823 void ast_ssl_teardown(struct ast_tls_config *cfg)
824 {
825 #ifdef DO_SSL
826         if (cfg->ssl_ctx) {
827                 SSL_CTX_free(cfg->ssl_ctx);
828                 cfg->ssl_ctx = NULL;
829         }
830 #endif
831 }
832
833 struct ast_tcptls_session_instance *ast_tcptls_client_start(struct ast_tcptls_session_instance *tcptls_session)
834 {
835         struct ast_tcptls_session_args *desc;
836         int flags;
837
838         if (!(desc = tcptls_session->parent)) {
839                 goto client_start_error;
840         }
841
842         if (ast_connect(desc->accept_fd, &desc->remote_address)) {
843                 ast_log(LOG_ERROR, "Unable to connect %s to %s: %s\n",
844                         desc->name,
845                         ast_sockaddr_stringify(&desc->remote_address),
846                         strerror(errno));
847                 goto client_start_error;
848         }
849
850         flags = fcntl(desc->accept_fd, F_GETFL);
851         fcntl(desc->accept_fd, F_SETFL, flags & ~O_NONBLOCK);
852
853         if (desc->tls_cfg) {
854                 desc->tls_cfg->enabled = 1;
855                 __ssl_setup(desc->tls_cfg, 1);
856         }
857
858         return handle_tcptls_connection(tcptls_session);
859
860 client_start_error:
861         if (desc) {
862                 close(desc->accept_fd);
863                 desc->accept_fd = -1;
864         }
865         ao2_ref(tcptls_session, -1);
866         return NULL;
867
868 }
869
870 struct ast_tcptls_session_instance *ast_tcptls_client_create(struct ast_tcptls_session_args *desc)
871 {
872         int x = 1;
873         struct ast_tcptls_session_instance *tcptls_session = NULL;
874
875         /* Do nothing if nothing has changed */
876         if (!ast_sockaddr_cmp(&desc->old_address, &desc->remote_address)) {
877                 ast_debug(1, "Nothing changed in %s\n", desc->name);
878                 return NULL;
879         }
880
881         /* If we return early, there is no connection */
882         ast_sockaddr_setnull(&desc->old_address);
883
884         if (desc->accept_fd != -1) {
885                 close(desc->accept_fd);
886         }
887
888         desc->accept_fd = socket(ast_sockaddr_is_ipv6(&desc->remote_address) ?
889                                  AF_INET6 : AF_INET, SOCK_STREAM, IPPROTO_TCP);
890         if (desc->accept_fd < 0) {
891                 ast_log(LOG_ERROR, "Unable to allocate socket for %s: %s\n",
892                         desc->name, strerror(errno));
893                 return NULL;
894         }
895
896         /* if a local address was specified, bind to it so the connection will
897            originate from the desired address */
898         if (!ast_sockaddr_isnull(&desc->local_address)) {
899                 setsockopt(desc->accept_fd, SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x));
900                 if (ast_bind(desc->accept_fd, &desc->local_address)) {
901                         ast_log(LOG_ERROR, "Unable to bind %s to %s: %s\n",
902                                 desc->name,
903                                 ast_sockaddr_stringify(&desc->local_address),
904                                 strerror(errno));
905                         goto error;
906                 }
907         }
908
909         if (!(tcptls_session = ao2_alloc(sizeof(*tcptls_session), session_instance_destructor))) {
910                 goto error;
911         }
912
913         tcptls_session->overflow_buf = ast_str_create(128);
914         tcptls_session->client = 1;
915         tcptls_session->fd = desc->accept_fd;
916         tcptls_session->parent = desc;
917         tcptls_session->parent->worker_fn = NULL;
918         ast_sockaddr_copy(&tcptls_session->remote_address,
919                           &desc->remote_address);
920
921         /* Set current info */
922         ast_sockaddr_copy(&desc->old_address, &desc->remote_address);
923         return tcptls_session;
924
925 error:
926         close(desc->accept_fd);
927         desc->accept_fd = -1;
928         if (tcptls_session) {
929                 ao2_ref(tcptls_session, -1);
930         }
931         return NULL;
932 }
933
934 void ast_tcptls_server_start(struct ast_tcptls_session_args *desc)
935 {
936         int flags;
937         int x = 1;
938
939         /* Do nothing if nothing has changed */
940         if (!ast_sockaddr_cmp(&desc->old_address, &desc->local_address)) {
941                 ast_debug(1, "Nothing changed in %s\n", desc->name);
942                 return;
943         }
944
945         /* If we return early, there is no one listening */
946         ast_sockaddr_setnull(&desc->old_address);
947
948         /* Shutdown a running server if there is one */
949         if (desc->master != AST_PTHREADT_NULL) {
950                 pthread_cancel(desc->master);
951                 pthread_kill(desc->master, SIGURG);
952                 pthread_join(desc->master, NULL);
953         }
954
955         if (desc->accept_fd != -1) {
956                 close(desc->accept_fd);
957         }
958
959         /* If there's no new server, stop here */
960         if (ast_sockaddr_isnull(&desc->local_address)) {
961                 ast_debug(2, "Server disabled:  %s\n", desc->name);
962                 return;
963         }
964
965         desc->accept_fd = socket(ast_sockaddr_is_ipv6(&desc->local_address) ?
966                                  AF_INET6 : AF_INET, SOCK_STREAM, 0);
967         if (desc->accept_fd < 0) {
968                 ast_log(LOG_ERROR, "Unable to allocate socket for %s: %s\n", desc->name, strerror(errno));
969                 return;
970         }
971
972         setsockopt(desc->accept_fd, SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x));
973         if (ast_bind(desc->accept_fd, &desc->local_address)) {
974                 ast_log(LOG_ERROR, "Unable to bind %s to %s: %s\n",
975                         desc->name,
976                         ast_sockaddr_stringify(&desc->local_address),
977                         strerror(errno));
978                 goto error;
979         }
980         if (listen(desc->accept_fd, 10)) {
981                 ast_log(LOG_ERROR, "Unable to listen for %s!\n", desc->name);
982                 goto error;
983         }
984         flags = fcntl(desc->accept_fd, F_GETFL);
985         fcntl(desc->accept_fd, F_SETFL, flags | O_NONBLOCK);
986         if (ast_pthread_create_background(&desc->master, NULL, desc->accept_fn, desc)) {
987                 ast_log(LOG_ERROR, "Unable to launch thread for %s on %s: %s\n",
988                         desc->name,
989                         ast_sockaddr_stringify(&desc->local_address),
990                         strerror(errno));
991                 goto error;
992         }
993
994         /* Set current info */
995         ast_sockaddr_copy(&desc->old_address, &desc->local_address);
996
997         return;
998
999 error:
1000         close(desc->accept_fd);
1001         desc->accept_fd = -1;
1002 }
1003
1004 void ast_tcptls_close_session_file(struct ast_tcptls_session_instance *tcptls_session)
1005 {
1006         if (tcptls_session->f) {
1007                 fflush(tcptls_session->f);
1008                 if (fclose(tcptls_session->f)) {
1009                         ast_log(LOG_ERROR, "fclose() failed: %s\n", strerror(errno));
1010                 }
1011                 tcptls_session->f = NULL;
1012                 tcptls_session->fd = -1;
1013         } else if (tcptls_session->fd != -1) {
1014                 /*
1015                  * Issuing shutdown() is necessary here to avoid a race
1016                  * condition where the last data written may not appear
1017                  * in the TCP stream.  See ASTERISK-23548
1018                  */
1019                 shutdown(tcptls_session->fd, SHUT_RDWR);
1020                 if (close(tcptls_session->fd)) {
1021                         ast_log(LOG_ERROR, "close() failed: %s\n", strerror(errno));
1022                 }
1023                 tcptls_session->fd = -1;
1024         } else {
1025                 ast_log(LOG_ERROR, "ast_tcptls_close_session_file invoked on session instance without file or file descriptor\n");
1026         }
1027 }
1028
1029 void ast_tcptls_server_stop(struct ast_tcptls_session_args *desc)
1030 {
1031         if (desc->master != AST_PTHREADT_NULL) {
1032                 pthread_cancel(desc->master);
1033                 pthread_kill(desc->master, SIGURG);
1034                 pthread_join(desc->master, NULL);
1035                 desc->master = AST_PTHREADT_NULL;
1036         }
1037         if (desc->accept_fd != -1) {
1038                 close(desc->accept_fd);
1039         }
1040         desc->accept_fd = -1;
1041         ast_debug(2, "Stopped server :: %s\n", desc->name);
1042 }
1043
1044 int ast_tls_read_conf(struct ast_tls_config *tls_cfg, struct ast_tcptls_session_args *tls_desc, const char *varname, const char *value)
1045 {
1046         if (!strcasecmp(varname, "tlsenable") || !strcasecmp(varname, "sslenable")) {
1047                 tls_cfg->enabled = ast_true(value) ? 1 : 0;
1048         } else if (!strcasecmp(varname, "tlscertfile") || !strcasecmp(varname, "sslcert") || !strcasecmp(varname, "tlscert")) {
1049                 ast_free(tls_cfg->certfile);
1050                 tls_cfg->certfile = ast_strdup(value);
1051         } else if (!strcasecmp(varname, "tlsprivatekey") || !strcasecmp(varname, "sslprivatekey")) {
1052                 ast_free(tls_cfg->pvtfile);
1053                 tls_cfg->pvtfile = ast_strdup(value);
1054         } else if (!strcasecmp(varname, "tlscipher") || !strcasecmp(varname, "sslcipher")) {
1055                 ast_free(tls_cfg->cipher);
1056                 tls_cfg->cipher = ast_strdup(value);
1057         } else if (!strcasecmp(varname, "tlscafile")) {
1058                 ast_free(tls_cfg->cafile);
1059                 tls_cfg->cafile = ast_strdup(value);
1060         } else if (!strcasecmp(varname, "tlscapath") || !strcasecmp(varname, "tlscadir")) {
1061                 ast_free(tls_cfg->capath);
1062                 tls_cfg->capath = ast_strdup(value);
1063         } else if (!strcasecmp(varname, "tlsverifyclient")) {
1064                 ast_set2_flag(&tls_cfg->flags, ast_true(value), AST_SSL_VERIFY_CLIENT);
1065         } else if (!strcasecmp(varname, "tlsdontverifyserver")) {
1066                 ast_set2_flag(&tls_cfg->flags, ast_true(value), AST_SSL_DONT_VERIFY_SERVER);
1067         } else if (!strcasecmp(varname, "tlsbindaddr") || !strcasecmp(varname, "sslbindaddr")) {
1068                 if (ast_parse_arg(value, PARSE_ADDR, &tls_desc->local_address))
1069                         ast_log(LOG_ERROR, "Invalid %s '%s'\n", varname, value);
1070         } else if (!strcasecmp(varname, "tlsclientmethod") || !strcasecmp(varname, "sslclientmethod")) {
1071                 if (!strcasecmp(value, "tlsv1")) {
1072                         ast_set_flag(&tls_cfg->flags, AST_SSL_TLSV1_CLIENT);
1073                         ast_clear_flag(&tls_cfg->flags, AST_SSL_SSLV3_CLIENT);
1074                         ast_clear_flag(&tls_cfg->flags, AST_SSL_SSLV2_CLIENT);
1075                 } else if (!strcasecmp(value, "sslv3")) {
1076                         ast_set_flag(&tls_cfg->flags, AST_SSL_SSLV3_CLIENT);
1077                         ast_clear_flag(&tls_cfg->flags, AST_SSL_SSLV2_CLIENT);
1078                         ast_clear_flag(&tls_cfg->flags, AST_SSL_TLSV1_CLIENT);
1079                 } else if (!strcasecmp(value, "sslv2")) {
1080                         ast_set_flag(&tls_cfg->flags, AST_SSL_SSLV2_CLIENT);
1081                         ast_clear_flag(&tls_cfg->flags, AST_SSL_TLSV1_CLIENT);
1082                         ast_clear_flag(&tls_cfg->flags, AST_SSL_SSLV3_CLIENT);
1083                 }
1084         } else {
1085                 return -1;
1086         }
1087
1088         return 0;
1089 }