Remove ASTERISK_REGISTER_FILE.
[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 #ifdef HAVE_FCNTL_H
35 #include <fcntl.h>
36 #endif
37
38 #include <signal.h>
39
40 #include "asterisk/compat.h"
41 #include "asterisk/tcptls.h"
42 #include "asterisk/http.h"
43 #include "asterisk/utils.h"
44 #include "asterisk/strings.h"
45 #include "asterisk/options.h"
46 #include "asterisk/manager.h"
47 #include "asterisk/astobj2.h"
48 #include "asterisk/pbx.h"
49
50 /*! ao2 object used for the FILE stream fopencookie()/funopen() cookie. */
51 struct ast_tcptls_stream {
52         /*! SSL state if not NULL */
53         SSL *ssl;
54         /*!
55          * \brief Start time from when an I/O sequence must complete
56          * by struct ast_tcptls_stream.timeout.
57          *
58          * \note If struct ast_tcptls_stream.start.tv_sec is zero then
59          * start time is the current I/O request.
60          */
61         struct timeval start;
62         /*!
63          * \brief The socket returned by accept().
64          *
65          * \note Set to -1 if the stream is closed.
66          */
67         int fd;
68         /*!
69          * \brief Timeout in ms relative to struct ast_tcptls_stream.start
70          * to wait for an event on struct ast_tcptls_stream.fd.
71          *
72          * \note Set to -1 to disable timeout.
73          * \note The socket needs to be set to non-blocking for the timeout
74          * feature to work correctly.
75          */
76         int timeout;
77         /*! TRUE if stream can exclusively wait for fd input. */
78         int exclusive_input;
79 };
80
81 void ast_tcptls_stream_set_timeout_disable(struct ast_tcptls_stream *stream)
82 {
83         ast_assert(stream != NULL);
84
85         stream->timeout = -1;
86 }
87
88 void ast_tcptls_stream_set_timeout_inactivity(struct ast_tcptls_stream *stream, int timeout)
89 {
90         ast_assert(stream != NULL);
91
92         stream->start.tv_sec = 0;
93         stream->timeout = timeout;
94 }
95
96 void ast_tcptls_stream_set_timeout_sequence(struct ast_tcptls_stream *stream, struct timeval start, int timeout)
97 {
98         ast_assert(stream != NULL);
99
100         stream->start = start;
101         stream->timeout = timeout;
102 }
103
104 void ast_tcptls_stream_set_exclusive_input(struct ast_tcptls_stream *stream, int exclusive_input)
105 {
106         ast_assert(stream != NULL);
107
108         stream->exclusive_input = exclusive_input;
109 }
110
111 /*!
112  * \internal
113  * \brief fopencookie()/funopen() stream read function.
114  *
115  * \param cookie Stream control data.
116  * \param buf Where to put read data.
117  * \param size Size of the buffer.
118  *
119  * \retval number of bytes put into buf.
120  * \retval 0 on end of file.
121  * \retval -1 on error.
122  */
123 static HOOK_T tcptls_stream_read(void *cookie, char *buf, LEN_T size)
124 {
125         struct ast_tcptls_stream *stream = cookie;
126         struct timeval start;
127         int ms;
128         int res;
129
130         if (!size) {
131                 /* You asked for no data you got no data. */
132                 return 0;
133         }
134
135         if (!stream || stream->fd == -1) {
136                 errno = EBADF;
137                 return -1;
138         }
139
140         if (stream->start.tv_sec) {
141                 start = stream->start;
142         } else {
143                 start = ast_tvnow();
144         }
145
146 #if defined(DO_SSL)
147         if (stream->ssl) {
148                 for (;;) {
149                         res = SSL_read(stream->ssl, buf, size);
150                         if (0 < res) {
151                                 /* We read some payload data. */
152                                 return res;
153                         }
154                         switch (SSL_get_error(stream->ssl, res)) {
155                         case SSL_ERROR_ZERO_RETURN:
156                                 /* Report EOF for a shutdown */
157                                 ast_debug(1, "TLS clean shutdown alert reading data\n");
158                                 return 0;
159                         case SSL_ERROR_WANT_READ:
160                                 if (!stream->exclusive_input) {
161                                         /* We cannot wait for data now. */
162                                         errno = EAGAIN;
163                                         return -1;
164                                 }
165                                 while ((ms = ast_remaining_ms(start, stream->timeout))) {
166                                         res = ast_wait_for_input(stream->fd, ms);
167                                         if (0 < res) {
168                                                 /* Socket is ready to be read. */
169                                                 break;
170                                         }
171                                         if (res < 0) {
172                                                 if (errno == EINTR || errno == EAGAIN) {
173                                                         /* Try again. */
174                                                         continue;
175                                                 }
176                                                 ast_debug(1, "TLS socket error waiting for read data: %s\n",
177                                                         strerror(errno));
178                                                 return -1;
179                                         }
180                                 }
181                                 break;
182                         case SSL_ERROR_WANT_WRITE:
183                                 while ((ms = ast_remaining_ms(start, stream->timeout))) {
184                                         res = ast_wait_for_output(stream->fd, ms);
185                                         if (0 < res) {
186                                                 /* Socket is ready to be written. */
187                                                 break;
188                                         }
189                                         if (res < 0) {
190                                                 if (errno == EINTR || errno == EAGAIN) {
191                                                         /* Try again. */
192                                                         continue;
193                                                 }
194                                                 ast_debug(1, "TLS socket error waiting for write space: %s\n",
195                                                         strerror(errno));
196                                                 return -1;
197                                         }
198                                 }
199                                 break;
200                         default:
201                                 /* Report EOF for an undecoded SSL or transport error. */
202                                 ast_debug(1, "TLS transport or SSL error reading data\n");
203                                 return 0;
204                         }
205                         if (!ms) {
206                                 /* Report EOF for a timeout */
207                                 ast_debug(1, "TLS timeout reading data\n");
208                                 return 0;
209                         }
210                 }
211         }
212 #endif  /* defined(DO_SSL) */
213
214         for (;;) {
215                 res = read(stream->fd, buf, size);
216                 if (0 <= res || !stream->exclusive_input) {
217                         /* Got data or we cannot wait for it. */
218                         return res;
219                 }
220                 if (errno != EINTR && errno != EAGAIN) {
221                         /* Not a retryable error. */
222                         ast_debug(1, "TCP socket error reading data: %s\n",
223                                 strerror(errno));
224                         return -1;
225                 }
226                 ms = ast_remaining_ms(start, stream->timeout);
227                 if (!ms) {
228                         /* Report EOF for a timeout */
229                         ast_debug(1, "TCP timeout reading data\n");
230                         return 0;
231                 }
232                 ast_wait_for_input(stream->fd, ms);
233         }
234 }
235
236 /*!
237  * \internal
238  * \brief fopencookie()/funopen() stream write function.
239  *
240  * \param cookie Stream control data.
241  * \param buf Where to get data to write.
242  * \param size Size of the buffer.
243  *
244  * \retval number of bytes written from buf.
245  * \retval -1 on error.
246  */
247 static HOOK_T tcptls_stream_write(void *cookie, const char *buf, LEN_T size)
248 {
249         struct ast_tcptls_stream *stream = cookie;
250         struct timeval start;
251         int ms;
252         int res;
253         int written;
254         int remaining;
255
256         if (!size) {
257                 /* You asked to write no data you wrote no data. */
258                 return 0;
259         }
260
261         if (!stream || stream->fd == -1) {
262                 errno = EBADF;
263                 return -1;
264         }
265
266         if (stream->start.tv_sec) {
267                 start = stream->start;
268         } else {
269                 start = ast_tvnow();
270         }
271
272 #if defined(DO_SSL)
273         if (stream->ssl) {
274                 written = 0;
275                 remaining = size;
276                 for (;;) {
277                         res = SSL_write(stream->ssl, buf + written, remaining);
278                         if (res == remaining) {
279                                 /* Everything was written. */
280                                 return size;
281                         }
282                         if (0 < res) {
283                                 /* Successfully wrote part of the buffer.  Try to write the rest. */
284                                 written += res;
285                                 remaining -= res;
286                                 continue;
287                         }
288                         switch (SSL_get_error(stream->ssl, res)) {
289                         case SSL_ERROR_ZERO_RETURN:
290                                 ast_debug(1, "TLS clean shutdown alert writing data\n");
291                                 if (written) {
292                                         /* Report partial write. */
293                                         return written;
294                                 }
295                                 errno = EBADF;
296                                 return -1;
297                         case SSL_ERROR_WANT_READ:
298                                 ms = ast_remaining_ms(start, stream->timeout);
299                                 if (!ms) {
300                                         /* Report partial write. */
301                                         ast_debug(1, "TLS timeout writing data (want read)\n");
302                                         return written;
303                                 }
304                                 ast_wait_for_input(stream->fd, ms);
305                                 break;
306                         case SSL_ERROR_WANT_WRITE:
307                                 ms = ast_remaining_ms(start, stream->timeout);
308                                 if (!ms) {
309                                         /* Report partial write. */
310                                         ast_debug(1, "TLS timeout writing data (want write)\n");
311                                         return written;
312                                 }
313                                 ast_wait_for_output(stream->fd, ms);
314                                 break;
315                         default:
316                                 /* Undecoded SSL or transport error. */
317                                 ast_debug(1, "TLS transport or SSL error writing data\n");
318                                 if (written) {
319                                         /* Report partial write. */
320                                         return written;
321                                 }
322                                 errno = EBADF;
323                                 return -1;
324                         }
325                 }
326         }
327 #endif  /* defined(DO_SSL) */
328
329         written = 0;
330         remaining = size;
331         for (;;) {
332                 res = write(stream->fd, buf + written, remaining);
333                 if (res == remaining) {
334                         /* Yay everything was written. */
335                         return size;
336                 }
337                 if (0 < res) {
338                         /* Successfully wrote part of the buffer.  Try to write the rest. */
339                         written += res;
340                         remaining -= res;
341                         continue;
342                 }
343                 if (errno != EINTR && errno != EAGAIN) {
344                         /* Not a retryable error. */
345                         ast_debug(1, "TCP socket error writing: %s\n", strerror(errno));
346                         if (written) {
347                                 return written;
348                         }
349                         return -1;
350                 }
351                 ms = ast_remaining_ms(start, stream->timeout);
352                 if (!ms) {
353                         /* Report partial write. */
354                         ast_debug(1, "TCP timeout writing data\n");
355                         return written;
356                 }
357                 ast_wait_for_output(stream->fd, ms);
358         }
359 }
360
361 /*!
362  * \internal
363  * \brief fopencookie()/funopen() stream close function.
364  *
365  * \param cookie Stream control data.
366  *
367  * \retval 0 on success.
368  * \retval -1 on error.
369  */
370 static int tcptls_stream_close(void *cookie)
371 {
372         struct ast_tcptls_stream *stream = cookie;
373
374         if (!stream) {
375                 errno = EBADF;
376                 return -1;
377         }
378
379         if (stream->fd != -1) {
380 #if defined(DO_SSL)
381                 if (stream->ssl) {
382                         int res;
383
384                         /*
385                          * According to the TLS standard, it is acceptable for an
386                          * application to only send its shutdown alert and then
387                          * close the underlying connection without waiting for
388                          * the peer's response (this way resources can be saved,
389                          * as the process can already terminate or serve another
390                          * connection).
391                          */
392                         res = SSL_shutdown(stream->ssl);
393                         if (res < 0) {
394                                 ast_log(LOG_ERROR, "SSL_shutdown() failed: %d\n",
395                                         SSL_get_error(stream->ssl, res));
396                         }
397
398                         if (!stream->ssl->server) {
399                                 /* For client threads, ensure that the error stack is cleared */
400 #if OPENSSL_VERSION_NUMBER >= 0x10000000L
401                                 ERR_remove_thread_state(NULL);
402 #else
403                                 ERR_remove_state(0);
404 #endif  /* OPENSSL_VERSION_NUMBER >= 0x10000000L */
405                         }
406
407                         SSL_free(stream->ssl);
408                         stream->ssl = NULL;
409                 }
410 #endif  /* defined(DO_SSL) */
411
412                 /*
413                  * Issuing shutdown() is necessary here to avoid a race
414                  * condition where the last data written may not appear
415                  * in the TCP stream.  See ASTERISK-23548
416                  */
417                 shutdown(stream->fd, SHUT_RDWR);
418                 if (close(stream->fd)) {
419                         ast_log(LOG_ERROR, "close() failed: %s\n", strerror(errno));
420                 }
421                 stream->fd = -1;
422         }
423         ao2_t_ref(stream, -1, "Closed tcptls stream cookie");
424
425         return 0;
426 }
427
428 /*!
429  * \internal
430  * \brief fopencookie()/funopen() stream destructor function.
431  *
432  * \param cookie Stream control data.
433  *
434  * \return Nothing
435  */
436 static void tcptls_stream_dtor(void *cookie)
437 {
438 #ifdef AST_DEVMODE
439         /* Since the ast_assert below is the only one using stream,
440          * and ast_assert is only available with AST_DEVMODE, we
441          * put this in a conditional to avoid compiler warnings. */
442         struct ast_tcptls_stream *stream = cookie;
443 #endif
444
445         ast_assert(stream->fd == -1);
446 }
447
448 /*!
449  * \internal
450  * \brief fopencookie()/funopen() stream allocation function.
451  *
452  * \retval stream_cookie on success.
453  * \retval NULL on error.
454  */
455 static struct ast_tcptls_stream *tcptls_stream_alloc(void)
456 {
457         struct ast_tcptls_stream *stream;
458
459         stream = ao2_alloc_options(sizeof(*stream), tcptls_stream_dtor,
460                 AO2_ALLOC_OPT_LOCK_NOLOCK);
461         if (stream) {
462                 stream->fd = -1;
463                 stream->timeout = -1;
464         }
465         return stream;
466 }
467
468 /*!
469  * \internal
470  * \brief Open a custom FILE stream for tcptls.
471  *
472  * \param stream Stream cookie control data.
473  * \param ssl SSL state if not NULL.
474  * \param fd Socket file descriptor.
475  * \param timeout ms to wait for an event on fd. -1 if timeout disabled.
476  *
477  * \retval fp on success.
478  * \retval NULL on error.
479  */
480 static FILE *tcptls_stream_fopen(struct ast_tcptls_stream *stream, SSL *ssl, int fd, int timeout)
481 {
482         FILE *fp;
483
484 #if defined(HAVE_FOPENCOOKIE)   /* the glibc/linux interface */
485         static const cookie_io_functions_t cookie_funcs = {
486                 tcptls_stream_read,
487                 tcptls_stream_write,
488                 NULL,
489                 tcptls_stream_close
490         };
491 #endif  /* defined(HAVE_FOPENCOOKIE) */
492
493         if (fd == -1) {
494                 /* Socket not open. */
495                 return NULL;
496         }
497
498         stream->ssl = ssl;
499         stream->fd = fd;
500         stream->timeout = timeout;
501         ao2_t_ref(stream, +1, "Opening tcptls stream cookie");
502
503 #if defined(HAVE_FUNOPEN)       /* the BSD interface */
504         fp = funopen(stream, tcptls_stream_read, tcptls_stream_write, NULL,
505                 tcptls_stream_close);
506 #elif defined(HAVE_FOPENCOOKIE) /* the glibc/linux interface */
507         fp = fopencookie(stream, "w+", cookie_funcs);
508 #else
509         /* could add other methods here */
510         ast_debug(2, "No stream FILE methods attempted!\n");
511         fp = NULL;
512 #endif
513
514         if (!fp) {
515                 stream->fd = -1;
516                 ao2_t_ref(stream, -1, "Failed to open tcptls stream cookie");
517         }
518         return fp;
519 }
520
521 HOOK_T ast_tcptls_server_read(struct ast_tcptls_session_instance *tcptls_session, void *buf, size_t count)
522 {
523         if (!tcptls_session->stream_cookie || tcptls_session->stream_cookie->fd == -1) {
524                 ast_log(LOG_ERROR, "TCP/TLS read called on invalid stream.\n");
525                 errno = EIO;
526                 return -1;
527         }
528
529         return tcptls_stream_read(tcptls_session->stream_cookie, buf, count);
530 }
531
532 HOOK_T ast_tcptls_server_write(struct ast_tcptls_session_instance *tcptls_session, const void *buf, size_t count)
533 {
534         if (!tcptls_session->stream_cookie || tcptls_session->stream_cookie->fd == -1) {
535                 ast_log(LOG_ERROR, "TCP/TLS write called on invalid stream.\n");
536                 errno = EIO;
537                 return -1;
538         }
539
540         return tcptls_stream_write(tcptls_session->stream_cookie, buf, count);
541 }
542
543 static void session_instance_destructor(void *obj)
544 {
545         struct ast_tcptls_session_instance *i = obj;
546
547         if (i->stream_cookie) {
548                 ao2_t_ref(i->stream_cookie, -1, "Destroying tcptls session instance");
549                 i->stream_cookie = NULL;
550         }
551         ast_free(i->overflow_buf);
552         ao2_cleanup(i->private_data);
553 }
554
555 #ifdef DO_SSL
556 static int check_tcptls_cert_name(ASN1_STRING *cert_str, const char *hostname, const char *desc)
557 {
558         unsigned char *str;
559         int ret;
560
561         ret = ASN1_STRING_to_UTF8(&str, cert_str);
562         if (ret < 0 || !str) {
563                 return -1;
564         }
565
566         if (strlen((char *) str) != ret) {
567                 ast_log(LOG_WARNING, "Invalid certificate %s length (contains NULL bytes?)\n", desc);
568
569                 ret = -1;
570         } else if (!strcasecmp(hostname, (char *) str)) {
571                 ret = 0;
572         } else {
573                 ret = -1;
574         }
575
576         ast_debug(3, "SSL %s compare s1='%s' s2='%s'\n", desc, hostname, str);
577         OPENSSL_free(str);
578
579         return ret;
580 }
581 #endif
582
583 /*! \brief
584 * creates a FILE * from the fd passed by the accept thread.
585 * This operation is potentially expensive (certificate verification),
586 * so we do it in the child thread context.
587 *
588 * \note must decrement ref count before returning NULL on error
589 */
590 static void *handle_tcptls_connection(void *data)
591 {
592         struct ast_tcptls_session_instance *tcptls_session = data;
593 #ifdef DO_SSL
594         int (*ssl_setup)(SSL *) = (tcptls_session->client) ? SSL_connect : SSL_accept;
595         int ret;
596         char err[256];
597 #endif
598
599         /* TCP/TLS connections are associated with external protocols, and
600          * should not be allowed to execute 'dangerous' functions. This may
601          * need to be pushed down into the individual protocol handlers, but
602          * this seems like a good general policy.
603          */
604         if (ast_thread_inhibit_escalations()) {
605                 ast_log(LOG_ERROR, "Failed to inhibit privilege escalations; killing connection\n");
606                 ast_tcptls_close_session_file(tcptls_session);
607                 ao2_ref(tcptls_session, -1);
608                 return NULL;
609         }
610
611         tcptls_session->stream_cookie = tcptls_stream_alloc();
612         if (!tcptls_session->stream_cookie) {
613                 ast_tcptls_close_session_file(tcptls_session);
614                 ao2_ref(tcptls_session, -1);
615                 return NULL;
616         }
617
618         /*
619         * open a FILE * as appropriate.
620         */
621         if (!tcptls_session->parent->tls_cfg) {
622                 tcptls_session->f = tcptls_stream_fopen(tcptls_session->stream_cookie, NULL,
623                         tcptls_session->fd, -1);
624                 if (tcptls_session->f) {
625                         if (setvbuf(tcptls_session->f, NULL, _IONBF, 0)) {
626                                 ast_tcptls_close_session_file(tcptls_session);
627                         }
628                 }
629         }
630 #ifdef DO_SSL
631         else if ( (tcptls_session->ssl = SSL_new(tcptls_session->parent->tls_cfg->ssl_ctx)) ) {
632                 SSL_set_fd(tcptls_session->ssl, tcptls_session->fd);
633                 if ((ret = ssl_setup(tcptls_session->ssl)) <= 0) {
634                         ast_log(LOG_ERROR, "Problem setting up ssl connection: %s\n", ERR_error_string(ERR_get_error(), err));
635                 } else if ((tcptls_session->f = tcptls_stream_fopen(tcptls_session->stream_cookie,
636                         tcptls_session->ssl, tcptls_session->fd, -1))) {
637                         if ((tcptls_session->client && !ast_test_flag(&tcptls_session->parent->tls_cfg->flags, AST_SSL_DONT_VERIFY_SERVER))
638                                 || (!tcptls_session->client && ast_test_flag(&tcptls_session->parent->tls_cfg->flags, AST_SSL_VERIFY_CLIENT))) {
639                                 X509 *peer;
640                                 long res;
641                                 peer = SSL_get_peer_certificate(tcptls_session->ssl);
642                                 if (!peer) {
643                                         ast_log(LOG_ERROR, "No peer SSL certificate to verify\n");
644                                         ast_tcptls_close_session_file(tcptls_session);
645                                         ao2_ref(tcptls_session, -1);
646                                         return NULL;
647                                 }
648
649                                 res = SSL_get_verify_result(tcptls_session->ssl);
650                                 if (res != X509_V_OK) {
651                                         ast_log(LOG_ERROR, "Certificate did not verify: %s\n", X509_verify_cert_error_string(res));
652                                         X509_free(peer);
653                                         ast_tcptls_close_session_file(tcptls_session);
654                                         ao2_ref(tcptls_session, -1);
655                                         return NULL;
656                                 }
657                                 if (!ast_test_flag(&tcptls_session->parent->tls_cfg->flags, AST_SSL_IGNORE_COMMON_NAME)) {
658                                         ASN1_STRING *str;
659                                         X509_NAME *name = X509_get_subject_name(peer);
660                                         STACK_OF(GENERAL_NAME) *alt_names;
661                                         int pos = -1;
662                                         int found = 0;
663
664                                         for (;;) {
665                                                 /* Walk the certificate to check all available "Common Name" */
666                                                 /* XXX Probably should do a gethostbyname on the hostname and compare that as well */
667                                                 pos = X509_NAME_get_index_by_NID(name, NID_commonName, pos);
668                                                 if (pos < 0) {
669                                                         break;
670                                                 }
671
672                                                 str = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name, pos));
673                                                 if (!check_tcptls_cert_name(str, tcptls_session->parent->hostname, "common name")) {
674                                                         found = 1;
675                                                         break;
676                                                 }
677                                         }
678
679                                         if (!found) {
680                                                 alt_names = X509_get_ext_d2i(peer, NID_subject_alt_name, NULL, NULL);
681                                                 if (alt_names != NULL) {
682                                                         int alt_names_count = sk_GENERAL_NAME_num(alt_names);
683
684                                                         for (pos = 0; pos < alt_names_count; pos++) {
685                                                                 const GENERAL_NAME *alt_name = sk_GENERAL_NAME_value(alt_names, pos);
686
687                                                                 if (alt_name->type != GEN_DNS) {
688                                                                         continue;
689                                                                 }
690
691                                                                 if (!check_tcptls_cert_name(alt_name->d.dNSName, tcptls_session->parent->hostname, "alt name")) {
692                                                                         found = 1;
693                                                                         break;
694                                                                 }
695                                                         }
696
697                                                         sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
698                                                 }
699                                         }
700
701                                         if (!found) {
702                                                 ast_log(LOG_ERROR, "Certificate common name did not match (%s)\n", tcptls_session->parent->hostname);
703                                                 X509_free(peer);
704                                                 ast_tcptls_close_session_file(tcptls_session);
705                                                 ao2_ref(tcptls_session, -1);
706                                                 return NULL;
707                                         }
708                                 }
709                                 X509_free(peer);
710                         }
711                 }
712                 if (!tcptls_session->f) {       /* no success opening descriptor stacking */
713                         SSL_free(tcptls_session->ssl);
714                 }
715         }
716 #endif /* DO_SSL */
717
718         if (!tcptls_session->f) {
719                 ast_tcptls_close_session_file(tcptls_session);
720                 ast_log(LOG_WARNING, "FILE * open failed!\n");
721 #ifndef DO_SSL
722                 if (tcptls_session->parent->tls_cfg) {
723                         ast_log(LOG_ERROR, "Attempted a TLS connection without OpenSSL support. This will not work!\n");
724                 }
725 #endif
726                 ao2_ref(tcptls_session, -1);
727                 return NULL;
728         }
729
730         if (tcptls_session->parent->worker_fn) {
731                 return tcptls_session->parent->worker_fn(tcptls_session);
732         } else {
733                 return tcptls_session;
734         }
735 }
736
737 void *ast_tcptls_server_root(void *data)
738 {
739         struct ast_tcptls_session_args *desc = data;
740         int fd;
741         struct ast_sockaddr addr;
742         struct ast_tcptls_session_instance *tcptls_session;
743         pthread_t launched;
744
745         for (;;) {
746                 int i, flags;
747
748                 if (desc->periodic_fn) {
749                         desc->periodic_fn(desc);
750                 }
751                 i = ast_wait_for_input(desc->accept_fd, desc->poll_timeout);
752                 if (i <= 0) {
753                         continue;
754                 }
755                 fd = ast_accept(desc->accept_fd, &addr);
756                 if (fd < 0) {
757                         if ((errno != EAGAIN) && (errno != EWOULDBLOCK) && (errno != EINTR) && (errno != ECONNABORTED)) {
758                                 ast_log(LOG_ERROR, "Accept failed: %s\n", strerror(errno));
759                                 break;
760                         }
761                         continue;
762                 }
763                 tcptls_session = ao2_alloc(sizeof(*tcptls_session), session_instance_destructor);
764                 if (!tcptls_session) {
765                         ast_log(LOG_WARNING, "No memory for new session: %s\n", strerror(errno));
766                         if (close(fd)) {
767                                 ast_log(LOG_ERROR, "close() failed: %s\n", strerror(errno));
768                         }
769                         continue;
770                 }
771
772                 tcptls_session->overflow_buf = ast_str_create(128);
773                 flags = fcntl(fd, F_GETFL);
774                 fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
775                 tcptls_session->fd = fd;
776                 tcptls_session->parent = desc;
777                 ast_sockaddr_copy(&tcptls_session->remote_address, &addr);
778
779                 tcptls_session->client = 0;
780
781                 /* This thread is now the only place that controls the single ref to tcptls_session */
782                 if (ast_pthread_create_detached_background(&launched, NULL, handle_tcptls_connection, tcptls_session)) {
783                         ast_log(LOG_ERROR, "Unable to launch helper thread: %s\n", strerror(errno));
784                         ast_tcptls_close_session_file(tcptls_session);
785                         ao2_ref(tcptls_session, -1);
786                 }
787         }
788         return NULL;
789 }
790
791 #ifdef DO_SSL
792 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)
793 {
794         char *cert_file = ast_strdupa(cfg->certfile);
795
796         memcpy(cert_file + cert_file_len - 8, key_type_extension, 5);
797         if (access(cert_file, F_OK) == 0) {
798                 if (SSL_CTX_use_certificate_chain_file(cfg->ssl_ctx, cert_file) == 0) {
799                         ast_log(LOG_WARNING, "TLS/SSL error loading public %s key (certificate) from <%s>.\n", key_type, cert_file);
800                 } else if (SSL_CTX_use_PrivateKey_file(cfg->ssl_ctx, cert_file, SSL_FILETYPE_PEM) == 0) {
801                         ast_log(LOG_WARNING, "TLS/SSL error loading private %s key from <%s>.\n", key_type, cert_file);
802                 } else if (SSL_CTX_check_private_key(cfg->ssl_ctx) == 0) {
803                         ast_log(LOG_WARNING, "TLS/SSL error matching private %s key and certificate in <%s>.\n", key_type, cert_file);
804                 }
805         }
806 }
807 #endif
808
809 static int __ssl_setup(struct ast_tls_config *cfg, int client)
810 {
811 #ifndef DO_SSL
812         cfg->enabled = 0;
813         return 0;
814 #else
815         int disable_ssl = 0;
816         long ssl_opts = 0;
817
818         if (!cfg->enabled) {
819                 return 0;
820         }
821
822         /* Get rid of an old SSL_CTX since we're about to
823          * allocate a new one
824          */
825         if (cfg->ssl_ctx) {
826                 SSL_CTX_free(cfg->ssl_ctx);
827                 cfg->ssl_ctx = NULL;
828         }
829
830         if (client) {
831 #ifndef OPENSSL_NO_SSL2
832                 if (ast_test_flag(&cfg->flags, AST_SSL_SSLV2_CLIENT)) {
833                         ast_log(LOG_WARNING, "Usage of SSLv2 is discouraged due to known vulnerabilities. Please use 'tlsv1' or leave the TLS method unspecified!\n");
834                         cfg->ssl_ctx = SSL_CTX_new(SSLv2_client_method());
835                 } else
836 #endif
837 #ifndef OPENSSL_NO_SSL3_METHOD
838                 if (ast_test_flag(&cfg->flags, AST_SSL_SSLV3_CLIENT)) {
839                         ast_log(LOG_WARNING, "Usage of SSLv3 is discouraged due to known vulnerabilities. Please use 'tlsv1' or leave the TLS method unspecified!\n");
840                         cfg->ssl_ctx = SSL_CTX_new(SSLv3_client_method());
841                 } else
842 #endif
843                 if (ast_test_flag(&cfg->flags, AST_SSL_TLSV1_CLIENT)) {
844                         cfg->ssl_ctx = SSL_CTX_new(TLSv1_client_method());
845                 } else {
846                         disable_ssl = 1;
847                         cfg->ssl_ctx = SSL_CTX_new(SSLv23_client_method());
848                 }
849         } else {
850                 disable_ssl = 1;
851                 cfg->ssl_ctx = SSL_CTX_new(SSLv23_server_method());
852         }
853
854         if (!cfg->ssl_ctx) {
855                 ast_debug(1, "Sorry, SSL_CTX_new call returned null...\n");
856                 cfg->enabled = 0;
857                 return 0;
858         }
859
860         /* Due to the POODLE vulnerability, completely disable
861          * SSLv2 and SSLv3 if we are not explicitly told to use
862          * them. SSLv23_*_method supports TLSv1+.
863          */
864         if (disable_ssl) {
865                 ssl_opts |= SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3;
866         }
867
868         if (ast_test_flag(&cfg->flags, AST_SSL_SERVER_CIPHER_ORDER)) {
869                 ssl_opts |= SSL_OP_CIPHER_SERVER_PREFERENCE;
870         }
871
872         if (ast_test_flag(&cfg->flags, AST_SSL_DISABLE_TLSV1)) {
873                 ssl_opts |= SSL_OP_NO_TLSv1;
874         }
875 #if defined(HAVE_SSL_OP_NO_TLSV1_1) && defined(HAVE_SSL_OP_NO_TLSV1_2)
876         if (ast_test_flag(&cfg->flags, AST_SSL_DISABLE_TLSV11)) {
877                 ssl_opts |= SSL_OP_NO_TLSv1_1;
878         }
879         if (ast_test_flag(&cfg->flags, AST_SSL_DISABLE_TLSV12)) {
880                 ssl_opts |= SSL_OP_NO_TLSv1_2;
881         }
882 #else
883         ast_log(LOG_WARNING, "Your version of OpenSSL leaves you potentially vulnerable "
884                         "to the SSL BEAST attack. Please upgrade to OpenSSL 1.0.1 or later\n");
885 #endif
886
887         SSL_CTX_set_options(cfg->ssl_ctx, ssl_opts);
888
889         SSL_CTX_set_verify(cfg->ssl_ctx,
890                 ast_test_flag(&cfg->flags, AST_SSL_VERIFY_CLIENT) ? SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT : SSL_VERIFY_NONE,
891                 NULL);
892
893         if (!ast_strlen_zero(cfg->certfile)) {
894                 char *tmpprivate = ast_strlen_zero(cfg->pvtfile) ? cfg->certfile : cfg->pvtfile;
895                 if (SSL_CTX_use_certificate_chain_file(cfg->ssl_ctx, cfg->certfile) == 0) {
896                         if (!client) {
897                                 /* Clients don't need a certificate, but if its setup we can use it */
898                                 ast_log(LOG_ERROR, "TLS/SSL error loading cert file. <%s>\n", cfg->certfile);
899                                 cfg->enabled = 0;
900                                 SSL_CTX_free(cfg->ssl_ctx);
901                                 cfg->ssl_ctx = NULL;
902                                 return 0;
903                         }
904                 }
905                 if ((SSL_CTX_use_PrivateKey_file(cfg->ssl_ctx, tmpprivate, SSL_FILETYPE_PEM) == 0) || (SSL_CTX_check_private_key(cfg->ssl_ctx) == 0 )) {
906                         if (!client) {
907                                 /* Clients don't need a private key, but if its setup we can use it */
908                                 ast_log(LOG_ERROR, "TLS/SSL error loading private key file. <%s>\n", tmpprivate);
909                                 cfg->enabled = 0;
910                                 SSL_CTX_free(cfg->ssl_ctx);
911                                 cfg->ssl_ctx = NULL;
912                                 return 0;
913                         }
914                 }
915                 if (!client) {
916                         size_t certfile_len = strlen(cfg->certfile);
917
918                         /* expects a file name which contains _rsa. like asterisk_rsa.pem
919                          * ignores any 3-character file-extension like .pem, .cer, .crt
920                          */
921                         if (certfile_len >= 8 && !strncmp(cfg->certfile + certfile_len - 8, "_rsa.", 5)) {
922                                 __ssl_setup_certs(cfg, certfile_len, "_ecc.", "ECC");
923                                 __ssl_setup_certs(cfg, certfile_len, "_dsa.", "DSA");
924                         }
925                 }
926         }
927         if (!ast_strlen_zero(cfg->cipher)) {
928                 if (SSL_CTX_set_cipher_list(cfg->ssl_ctx, cfg->cipher) == 0 ) {
929                         if (!client) {
930                                 ast_log(LOG_ERROR, "TLS/SSL cipher error <%s>\n", cfg->cipher);
931                                 cfg->enabled = 0;
932                                 SSL_CTX_free(cfg->ssl_ctx);
933                                 cfg->ssl_ctx = NULL;
934                                 return 0;
935                         }
936                 }
937         }
938         if (!ast_strlen_zero(cfg->cafile) || !ast_strlen_zero(cfg->capath)) {
939                 if (SSL_CTX_load_verify_locations(cfg->ssl_ctx, S_OR(cfg->cafile, NULL), S_OR(cfg->capath,NULL)) == 0) {
940                         ast_log(LOG_ERROR, "TLS/SSL CA file(%s)/path(%s) error\n", cfg->cafile, cfg->capath);
941                 }
942         }
943
944 #ifdef HAVE_OPENSSL_EC
945
946         if (!ast_strlen_zero(cfg->pvtfile)) {
947                 BIO *bio = BIO_new_file(cfg->pvtfile, "r");
948                 if (bio != NULL) {
949                         DH *dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
950                         if (dh != NULL) {
951                                 if (SSL_CTX_set_tmp_dh(cfg->ssl_ctx, dh)) {
952                                         long options = SSL_OP_CIPHER_SERVER_PREFERENCE | SSL_OP_SINGLE_DH_USE | SSL_OP_SINGLE_ECDH_USE;
953                                         options = SSL_CTX_set_options(cfg->ssl_ctx, options);
954                                         ast_verb(2, "TLS/SSL DH initialized, PFS cipher-suites enabled\n");
955                                 }
956                                 DH_free(dh);
957                         }
958                         BIO_free(bio);
959                 }
960         }
961         #ifndef SSL_CTRL_SET_ECDH_AUTO
962                 #define SSL_CTRL_SET_ECDH_AUTO 94
963         #endif
964         /* SSL_CTX_set_ecdh_auto(cfg->ssl_ctx, on); requires OpenSSL 1.0.2 which wraps: */
965         if (SSL_CTX_ctrl(cfg->ssl_ctx, SSL_CTRL_SET_ECDH_AUTO, 1, NULL)) {
966                 ast_verb(2, "TLS/SSL ECDH initialized (automatic), faster PFS ciphers enabled\n");
967         } else {
968                 /* enables AES-128 ciphers, to get AES-256 use NID_secp384r1 */
969                 EC_KEY *ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
970                 if (ecdh != NULL) {
971                         if (SSL_CTX_set_tmp_ecdh(cfg->ssl_ctx, ecdh)) {
972                                 ast_verb(2, "TLS/SSL ECDH initialized (secp256r1), faster PFS cipher-suites enabled\n");
973                         }
974                         EC_KEY_free(ecdh);
975                 }
976         }
977
978 #endif /* #ifdef HAVE_OPENSSL_EC */
979
980         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 */
981         return 1;
982 #endif
983 }
984
985 int ast_ssl_setup(struct ast_tls_config *cfg)
986 {
987         return __ssl_setup(cfg, 0);
988 }
989
990 void ast_ssl_teardown(struct ast_tls_config *cfg)
991 {
992 #ifdef DO_SSL
993         if (cfg->ssl_ctx) {
994                 SSL_CTX_free(cfg->ssl_ctx);
995                 cfg->ssl_ctx = NULL;
996         }
997 #endif
998 }
999
1000 struct ast_tcptls_session_instance *ast_tcptls_client_start(struct ast_tcptls_session_instance *tcptls_session)
1001 {
1002         struct ast_tcptls_session_args *desc;
1003         int flags;
1004
1005         if (!(desc = tcptls_session->parent)) {
1006                 goto client_start_error;
1007         }
1008
1009         if (ast_connect(desc->accept_fd, &desc->remote_address)) {
1010                 ast_log(LOG_ERROR, "Unable to connect %s to %s: %s\n",
1011                         desc->name,
1012                         ast_sockaddr_stringify(&desc->remote_address),
1013                         strerror(errno));
1014                 goto client_start_error;
1015         }
1016
1017         flags = fcntl(desc->accept_fd, F_GETFL);
1018         fcntl(desc->accept_fd, F_SETFL, flags & ~O_NONBLOCK);
1019
1020         if (desc->tls_cfg) {
1021                 desc->tls_cfg->enabled = 1;
1022                 __ssl_setup(desc->tls_cfg, 1);
1023         }
1024
1025         return handle_tcptls_connection(tcptls_session);
1026
1027 client_start_error:
1028         if (desc) {
1029                 close(desc->accept_fd);
1030                 desc->accept_fd = -1;
1031         }
1032         ao2_ref(tcptls_session, -1);
1033         return NULL;
1034
1035 }
1036
1037 struct ast_tcptls_session_instance *ast_tcptls_client_create(struct ast_tcptls_session_args *desc)
1038 {
1039         int x = 1;
1040         struct ast_tcptls_session_instance *tcptls_session = NULL;
1041
1042         /* Do nothing if nothing has changed */
1043         if (!ast_sockaddr_cmp(&desc->old_address, &desc->remote_address)) {
1044                 ast_debug(1, "Nothing changed in %s\n", desc->name);
1045                 return NULL;
1046         }
1047
1048         /* If we return early, there is no connection */
1049         ast_sockaddr_setnull(&desc->old_address);
1050
1051         if (desc->accept_fd != -1) {
1052                 close(desc->accept_fd);
1053         }
1054
1055         desc->accept_fd = socket(ast_sockaddr_is_ipv6(&desc->remote_address) ?
1056                                  AF_INET6 : AF_INET, SOCK_STREAM, IPPROTO_TCP);
1057         if (desc->accept_fd < 0) {
1058                 ast_log(LOG_ERROR, "Unable to allocate socket for %s: %s\n",
1059                         desc->name, strerror(errno));
1060                 return NULL;
1061         }
1062
1063         /* if a local address was specified, bind to it so the connection will
1064            originate from the desired address */
1065         if (!ast_sockaddr_isnull(&desc->local_address)) {
1066                 setsockopt(desc->accept_fd, SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x));
1067                 if (ast_bind(desc->accept_fd, &desc->local_address)) {
1068                         ast_log(LOG_ERROR, "Unable to bind %s to %s: %s\n",
1069                                 desc->name,
1070                                 ast_sockaddr_stringify(&desc->local_address),
1071                                 strerror(errno));
1072                         goto error;
1073                 }
1074         }
1075
1076         if (!(tcptls_session = ao2_alloc(sizeof(*tcptls_session), session_instance_destructor))) {
1077                 goto error;
1078         }
1079
1080         tcptls_session->overflow_buf = ast_str_create(128);
1081         tcptls_session->client = 1;
1082         tcptls_session->fd = desc->accept_fd;
1083         tcptls_session->parent = desc;
1084         tcptls_session->parent->worker_fn = NULL;
1085         ast_sockaddr_copy(&tcptls_session->remote_address,
1086                           &desc->remote_address);
1087
1088         /* Set current info */
1089         ast_sockaddr_copy(&desc->old_address, &desc->remote_address);
1090         return tcptls_session;
1091
1092 error:
1093         close(desc->accept_fd);
1094         desc->accept_fd = -1;
1095         if (tcptls_session) {
1096                 ao2_ref(tcptls_session, -1);
1097         }
1098         return NULL;
1099 }
1100
1101 void ast_tcptls_server_start(struct ast_tcptls_session_args *desc)
1102 {
1103         int flags;
1104         int x = 1;
1105
1106         /* Do nothing if nothing has changed */
1107         if (!ast_sockaddr_cmp(&desc->old_address, &desc->local_address)) {
1108                 ast_debug(1, "Nothing changed in %s\n", desc->name);
1109                 return;
1110         }
1111
1112         /* If we return early, there is no one listening */
1113         ast_sockaddr_setnull(&desc->old_address);
1114
1115         /* Shutdown a running server if there is one */
1116         if (desc->master != AST_PTHREADT_NULL) {
1117                 pthread_cancel(desc->master);
1118                 pthread_kill(desc->master, SIGURG);
1119                 pthread_join(desc->master, NULL);
1120         }
1121
1122         if (desc->accept_fd != -1) {
1123                 close(desc->accept_fd);
1124         }
1125
1126         /* If there's no new server, stop here */
1127         if (ast_sockaddr_isnull(&desc->local_address)) {
1128                 ast_debug(2, "Server disabled:  %s\n", desc->name);
1129                 return;
1130         }
1131
1132         desc->accept_fd = socket(ast_sockaddr_is_ipv6(&desc->local_address) ?
1133                                  AF_INET6 : AF_INET, SOCK_STREAM, 0);
1134         if (desc->accept_fd < 0) {
1135                 ast_log(LOG_ERROR, "Unable to allocate socket for %s: %s\n", desc->name, strerror(errno));
1136                 return;
1137         }
1138
1139         setsockopt(desc->accept_fd, SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x));
1140         if (ast_bind(desc->accept_fd, &desc->local_address)) {
1141                 ast_log(LOG_ERROR, "Unable to bind %s to %s: %s\n",
1142                         desc->name,
1143                         ast_sockaddr_stringify(&desc->local_address),
1144                         strerror(errno));
1145                 goto error;
1146         }
1147         if (listen(desc->accept_fd, 10)) {
1148                 ast_log(LOG_ERROR, "Unable to listen for %s!\n", desc->name);
1149                 goto error;
1150         }
1151         flags = fcntl(desc->accept_fd, F_GETFL);
1152         fcntl(desc->accept_fd, F_SETFL, flags | O_NONBLOCK);
1153         if (ast_pthread_create_background(&desc->master, NULL, desc->accept_fn, desc)) {
1154                 ast_log(LOG_ERROR, "Unable to launch thread for %s on %s: %s\n",
1155                         desc->name,
1156                         ast_sockaddr_stringify(&desc->local_address),
1157                         strerror(errno));
1158                 goto error;
1159         }
1160
1161         /* Set current info */
1162         ast_sockaddr_copy(&desc->old_address, &desc->local_address);
1163
1164         return;
1165
1166 error:
1167         close(desc->accept_fd);
1168         desc->accept_fd = -1;
1169 }
1170
1171 void ast_tcptls_close_session_file(struct ast_tcptls_session_instance *tcptls_session)
1172 {
1173         if (tcptls_session->f) {
1174                 fflush(tcptls_session->f);
1175                 if (fclose(tcptls_session->f)) {
1176                         ast_log(LOG_ERROR, "fclose() failed: %s\n", strerror(errno));
1177                 }
1178                 tcptls_session->f = NULL;
1179                 tcptls_session->fd = -1;
1180         } else if (tcptls_session->fd != -1) {
1181                 /*
1182                  * Issuing shutdown() is necessary here to avoid a race
1183                  * condition where the last data written may not appear
1184                  * in the TCP stream.  See ASTERISK-23548
1185                  */
1186                 shutdown(tcptls_session->fd, SHUT_RDWR);
1187                 if (close(tcptls_session->fd)) {
1188                         ast_log(LOG_ERROR, "close() failed: %s\n", strerror(errno));
1189                 }
1190                 tcptls_session->fd = -1;
1191         } else {
1192                 ast_log(LOG_ERROR, "ast_tcptls_close_session_file invoked on session instance without file or file descriptor\n");
1193         }
1194 }
1195
1196 void ast_tcptls_server_stop(struct ast_tcptls_session_args *desc)
1197 {
1198         if (desc->master != AST_PTHREADT_NULL) {
1199                 pthread_cancel(desc->master);
1200                 pthread_kill(desc->master, SIGURG);
1201                 pthread_join(desc->master, NULL);
1202                 desc->master = AST_PTHREADT_NULL;
1203         }
1204         if (desc->accept_fd != -1) {
1205                 close(desc->accept_fd);
1206         }
1207         desc->accept_fd = -1;
1208         ast_debug(2, "Stopped server :: %s\n", desc->name);
1209 }
1210
1211 int ast_tls_read_conf(struct ast_tls_config *tls_cfg, struct ast_tcptls_session_args *tls_desc, const char *varname, const char *value)
1212 {
1213         if (!strcasecmp(varname, "tlsenable") || !strcasecmp(varname, "sslenable")) {
1214                 tls_cfg->enabled = ast_true(value) ? 1 : 0;
1215         } else if (!strcasecmp(varname, "tlscertfile") || !strcasecmp(varname, "sslcert") || !strcasecmp(varname, "tlscert")) {
1216                 ast_free(tls_cfg->certfile);
1217                 tls_cfg->certfile = ast_strdup(value);
1218         } else if (!strcasecmp(varname, "tlsprivatekey") || !strcasecmp(varname, "sslprivatekey")) {
1219                 ast_free(tls_cfg->pvtfile);
1220                 tls_cfg->pvtfile = ast_strdup(value);
1221         } else if (!strcasecmp(varname, "tlscipher") || !strcasecmp(varname, "sslcipher")) {
1222                 ast_free(tls_cfg->cipher);
1223                 tls_cfg->cipher = ast_strdup(value);
1224         } else if (!strcasecmp(varname, "tlscafile")) {
1225                 ast_free(tls_cfg->cafile);
1226                 tls_cfg->cafile = ast_strdup(value);
1227         } else if (!strcasecmp(varname, "tlscapath") || !strcasecmp(varname, "tlscadir")) {
1228                 ast_free(tls_cfg->capath);
1229                 tls_cfg->capath = ast_strdup(value);
1230         } else if (!strcasecmp(varname, "tlsverifyclient")) {
1231                 ast_set2_flag(&tls_cfg->flags, ast_true(value), AST_SSL_VERIFY_CLIENT);
1232         } else if (!strcasecmp(varname, "tlsdontverifyserver")) {
1233                 ast_set2_flag(&tls_cfg->flags, ast_true(value), AST_SSL_DONT_VERIFY_SERVER);
1234         } else if (!strcasecmp(varname, "tlsbindaddr") || !strcasecmp(varname, "sslbindaddr")) {
1235                 if (ast_parse_arg(value, PARSE_ADDR, &tls_desc->local_address))
1236                         ast_log(LOG_ERROR, "Invalid %s '%s'\n", varname, value);
1237         } else if (!strcasecmp(varname, "tlsclientmethod") || !strcasecmp(varname, "sslclientmethod")) {
1238                 if (!strcasecmp(value, "tlsv1")) {
1239                         ast_set_flag(&tls_cfg->flags, AST_SSL_TLSV1_CLIENT);
1240                         ast_clear_flag(&tls_cfg->flags, AST_SSL_SSLV3_CLIENT);
1241                         ast_clear_flag(&tls_cfg->flags, AST_SSL_SSLV2_CLIENT);
1242                 } else if (!strcasecmp(value, "sslv3")) {
1243                         ast_set_flag(&tls_cfg->flags, AST_SSL_SSLV3_CLIENT);
1244                         ast_clear_flag(&tls_cfg->flags, AST_SSL_SSLV2_CLIENT);
1245                         ast_clear_flag(&tls_cfg->flags, AST_SSL_TLSV1_CLIENT);
1246                 } else if (!strcasecmp(value, "sslv2")) {
1247                         ast_set_flag(&tls_cfg->flags, AST_SSL_SSLV2_CLIENT);
1248                         ast_clear_flag(&tls_cfg->flags, AST_SSL_TLSV1_CLIENT);
1249                         ast_clear_flag(&tls_cfg->flags, AST_SSL_SSLV3_CLIENT);
1250                 }
1251         } else if (!strcasecmp(varname, "tlsservercipherorder")) {
1252                 ast_set2_flag(&tls_cfg->flags, ast_true(value), AST_SSL_SERVER_CIPHER_ORDER);
1253         } else if (!strcasecmp(varname, "tlsdisablev1")) {
1254                 ast_set2_flag(&tls_cfg->flags, ast_true(value), AST_SSL_DISABLE_TLSV1);
1255         } else if (!strcasecmp(varname, "tlsdisablev11")) {
1256                 ast_set2_flag(&tls_cfg->flags, ast_true(value), AST_SSL_DISABLE_TLSV11);
1257         } else if (!strcasecmp(varname, "tlsdisablev12")) {
1258                 ast_set2_flag(&tls_cfg->flags, ast_true(value), AST_SSL_DISABLE_TLSV12);
1259         } else {
1260                 return -1;
1261         }
1262
1263         return 0;
1264 }