00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include "asterisk.h"
00033
00034 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 416067 $")
00035
00036 #ifdef HAVE_FCNTL_H
00037 #include <fcntl.h>
00038 #endif
00039
00040 #include <signal.h>
00041 #include <sys/signal.h>
00042
00043 #include "asterisk/compat.h"
00044 #include "asterisk/tcptls.h"
00045 #include "asterisk/http.h"
00046 #include "asterisk/utils.h"
00047 #include "asterisk/strings.h"
00048 #include "asterisk/options.h"
00049 #include "asterisk/manager.h"
00050 #include "asterisk/astobj2.h"
00051 #include "asterisk/pbx.h"
00052
00053
00054 struct ast_tcptls_stream {
00055
00056 SSL *ssl;
00057
00058
00059
00060
00061
00062
00063
00064 struct timeval start;
00065
00066
00067
00068
00069
00070 int fd;
00071
00072
00073
00074
00075
00076
00077
00078
00079 int timeout;
00080
00081 int exclusive_input;
00082 };
00083
00084 void ast_tcptls_stream_set_timeout_disable(struct ast_tcptls_stream *stream)
00085 {
00086 ast_assert(stream != NULL);
00087
00088 stream->timeout = -1;
00089 }
00090
00091 void ast_tcptls_stream_set_timeout_inactivity(struct ast_tcptls_stream *stream, int timeout)
00092 {
00093 ast_assert(stream != NULL);
00094
00095 stream->start.tv_sec = 0;
00096 stream->timeout = timeout;
00097 }
00098
00099 void ast_tcptls_stream_set_timeout_sequence(struct ast_tcptls_stream *stream, struct timeval start, int timeout)
00100 {
00101 ast_assert(stream != NULL);
00102
00103 stream->start = start;
00104 stream->timeout = timeout;
00105 }
00106
00107 void ast_tcptls_stream_set_exclusive_input(struct ast_tcptls_stream *stream, int exclusive_input)
00108 {
00109 ast_assert(stream != NULL);
00110
00111 stream->exclusive_input = exclusive_input;
00112 }
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126 static HOOK_T tcptls_stream_read(void *cookie, char *buf, LEN_T size)
00127 {
00128 struct ast_tcptls_stream *stream = cookie;
00129 struct timeval start;
00130 int ms;
00131 int res;
00132
00133 if (!size) {
00134
00135 return 0;
00136 }
00137
00138 if (!stream || stream->fd == -1) {
00139 errno = EBADF;
00140 return -1;
00141 }
00142
00143 if (stream->start.tv_sec) {
00144 start = stream->start;
00145 } else {
00146 start = ast_tvnow();
00147 }
00148
00149 #if defined(DO_SSL)
00150 if (stream->ssl) {
00151 for (;;) {
00152 res = SSL_read(stream->ssl, buf, size);
00153 if (0 < res) {
00154
00155 return res;
00156 }
00157 switch (SSL_get_error(stream->ssl, res)) {
00158 case SSL_ERROR_ZERO_RETURN:
00159
00160 ast_debug(1, "TLS clean shutdown alert reading data\n");
00161 return 0;
00162 case SSL_ERROR_WANT_READ:
00163 if (!stream->exclusive_input) {
00164
00165 errno = EAGAIN;
00166 return -1;
00167 }
00168 while ((ms = ast_remaining_ms(start, stream->timeout))) {
00169 res = ast_wait_for_input(stream->fd, ms);
00170 if (0 < res) {
00171
00172 break;
00173 }
00174 if (res < 0) {
00175 if (errno == EINTR || errno == EAGAIN) {
00176
00177 continue;
00178 }
00179 ast_debug(1, "TLS socket error waiting for read data: %s\n",
00180 strerror(errno));
00181 return -1;
00182 }
00183 }
00184 break;
00185 case SSL_ERROR_WANT_WRITE:
00186 while ((ms = ast_remaining_ms(start, stream->timeout))) {
00187 res = ast_wait_for_output(stream->fd, ms);
00188 if (0 < res) {
00189
00190 break;
00191 }
00192 if (res < 0) {
00193 if (errno == EINTR || errno == EAGAIN) {
00194
00195 continue;
00196 }
00197 ast_debug(1, "TLS socket error waiting for write space: %s\n",
00198 strerror(errno));
00199 return -1;
00200 }
00201 }
00202 break;
00203 default:
00204
00205 ast_debug(1, "TLS transport or SSL error reading data\n");
00206 return 0;
00207 }
00208 if (!ms) {
00209
00210 ast_debug(1, "TLS timeout reading data\n");
00211 return 0;
00212 }
00213 }
00214 }
00215 #endif
00216
00217 for (;;) {
00218 res = read(stream->fd, buf, size);
00219 if (0 <= res || !stream->exclusive_input) {
00220
00221 return res;
00222 }
00223 if (errno != EINTR && errno != EAGAIN) {
00224
00225 ast_debug(1, "TCP socket error reading data: %s\n",
00226 strerror(errno));
00227 return -1;
00228 }
00229 ms = ast_remaining_ms(start, stream->timeout);
00230 if (!ms) {
00231
00232 ast_debug(1, "TCP timeout reading data\n");
00233 return 0;
00234 }
00235 ast_wait_for_input(stream->fd, ms);
00236 }
00237 }
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250 static HOOK_T tcptls_stream_write(void *cookie, const char *buf, LEN_T size)
00251 {
00252 struct ast_tcptls_stream *stream = cookie;
00253 struct timeval start;
00254 int ms;
00255 int res;
00256 int written;
00257 int remaining;
00258
00259 if (!size) {
00260
00261 return 0;
00262 }
00263
00264 if (!stream || stream->fd == -1) {
00265 errno = EBADF;
00266 return -1;
00267 }
00268
00269 if (stream->start.tv_sec) {
00270 start = stream->start;
00271 } else {
00272 start = ast_tvnow();
00273 }
00274
00275 #if defined(DO_SSL)
00276 if (stream->ssl) {
00277 written = 0;
00278 remaining = size;
00279 for (;;) {
00280 res = SSL_write(stream->ssl, buf + written, remaining);
00281 if (res == remaining) {
00282
00283 return size;
00284 }
00285 if (0 < res) {
00286
00287 written += res;
00288 remaining -= res;
00289 continue;
00290 }
00291 switch (SSL_get_error(stream->ssl, res)) {
00292 case SSL_ERROR_ZERO_RETURN:
00293 ast_debug(1, "TLS clean shutdown alert writing data\n");
00294 if (written) {
00295
00296 return written;
00297 }
00298 errno = EBADF;
00299 return -1;
00300 case SSL_ERROR_WANT_READ:
00301 ms = ast_remaining_ms(start, stream->timeout);
00302 if (!ms) {
00303
00304 ast_debug(1, "TLS timeout writing data (want read)\n");
00305 return written;
00306 }
00307 ast_wait_for_input(stream->fd, ms);
00308 break;
00309 case SSL_ERROR_WANT_WRITE:
00310 ms = ast_remaining_ms(start, stream->timeout);
00311 if (!ms) {
00312
00313 ast_debug(1, "TLS timeout writing data (want write)\n");
00314 return written;
00315 }
00316 ast_wait_for_output(stream->fd, ms);
00317 break;
00318 default:
00319
00320 ast_debug(1, "TLS transport or SSL error writing data\n");
00321 if (written) {
00322
00323 return written;
00324 }
00325 errno = EBADF;
00326 return -1;
00327 }
00328 }
00329 }
00330 #endif
00331
00332 written = 0;
00333 remaining = size;
00334 for (;;) {
00335 res = write(stream->fd, buf + written, remaining);
00336 if (res == remaining) {
00337
00338 return size;
00339 }
00340 if (0 < res) {
00341
00342 written += res;
00343 remaining -= res;
00344 continue;
00345 }
00346 if (errno != EINTR && errno != EAGAIN) {
00347
00348 ast_debug(1, "TCP socket error writing: %s\n", strerror(errno));
00349 if (written) {
00350 return written;
00351 }
00352 return -1;
00353 }
00354 ms = ast_remaining_ms(start, stream->timeout);
00355 if (!ms) {
00356
00357 ast_debug(1, "TCP timeout writing data\n");
00358 return written;
00359 }
00360 ast_wait_for_output(stream->fd, ms);
00361 }
00362 }
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373 static int tcptls_stream_close(void *cookie)
00374 {
00375 struct ast_tcptls_stream *stream = cookie;
00376
00377 if (!stream) {
00378 errno = EBADF;
00379 return -1;
00380 }
00381
00382 if (stream->fd != -1) {
00383 #if defined(DO_SSL)
00384 if (stream->ssl) {
00385 int res;
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395 res = SSL_shutdown(stream->ssl);
00396 if (res < 0) {
00397 ast_log(LOG_ERROR, "SSL_shutdown() failed: %d\n",
00398 SSL_get_error(stream->ssl, res));
00399 }
00400
00401 if (!stream->ssl->server) {
00402
00403 ERR_remove_state(0);
00404 }
00405
00406 SSL_free(stream->ssl);
00407 stream->ssl = NULL;
00408 }
00409 #endif
00410
00411
00412
00413
00414
00415
00416 shutdown(stream->fd, SHUT_RDWR);
00417 if (close(stream->fd)) {
00418 ast_log(LOG_ERROR, "close() failed: %s\n", strerror(errno));
00419 }
00420 stream->fd = -1;
00421 }
00422 ao2_t_ref(stream, -1, "Closed tcptls stream cookie");
00423
00424 return 0;
00425 }
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435 static void tcptls_stream_dtor(void *cookie)
00436 {
00437 struct ast_tcptls_stream *stream = cookie;
00438
00439 ast_assert(stream->fd == -1);
00440 }
00441
00442
00443
00444
00445
00446
00447
00448
00449 static struct ast_tcptls_stream *tcptls_stream_alloc(void)
00450 {
00451 struct ast_tcptls_stream *stream;
00452
00453 stream = ao2_alloc_options(sizeof(*stream), tcptls_stream_dtor,
00454 AO2_ALLOC_OPT_LOCK_NOLOCK);
00455 if (stream) {
00456 stream->fd = -1;
00457 stream->timeout = -1;
00458 }
00459 return stream;
00460 }
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474 static FILE *tcptls_stream_fopen(struct ast_tcptls_stream *stream, SSL *ssl, int fd, int timeout)
00475 {
00476 FILE *fp;
00477
00478 #if defined(HAVE_FOPENCOOKIE)
00479 static const cookie_io_functions_t cookie_funcs = {
00480 tcptls_stream_read,
00481 tcptls_stream_write,
00482 NULL,
00483 tcptls_stream_close
00484 };
00485 #endif
00486
00487 if (fd == -1) {
00488
00489 return NULL;
00490 }
00491
00492 stream->ssl = ssl;
00493 stream->fd = fd;
00494 stream->timeout = timeout;
00495 ao2_t_ref(stream, +1, "Opening tcptls stream cookie");
00496
00497 #if defined(HAVE_FUNOPEN)
00498 fp = funopen(stream, tcptls_stream_read, tcptls_stream_write, NULL,
00499 tcptls_stream_close);
00500 #elif defined(HAVE_FOPENCOOKIE)
00501 fp = fopencookie(stream, "w+", cookie_funcs);
00502 #else
00503
00504 ast_debug(2, "No stream FILE methods attempted!\n");
00505 fp = NULL;
00506 #endif
00507
00508 if (!fp) {
00509 stream->fd = -1;
00510 ao2_t_ref(stream, -1, "Failed to open tcptls stream cookie");
00511 }
00512 return fp;
00513 }
00514
00515 HOOK_T ast_tcptls_server_read(struct ast_tcptls_session_instance *tcptls_session, void *buf, size_t count)
00516 {
00517 if (!tcptls_session->stream_cookie || tcptls_session->stream_cookie->fd == -1) {
00518 ast_log(LOG_ERROR, "TCP/TLS read called on invalid stream.\n");
00519 errno = EIO;
00520 return -1;
00521 }
00522
00523 return tcptls_stream_read(tcptls_session->stream_cookie, buf, count);
00524 }
00525
00526 HOOK_T ast_tcptls_server_write(struct ast_tcptls_session_instance *tcptls_session, const void *buf, size_t count)
00527 {
00528 if (!tcptls_session->stream_cookie || tcptls_session->stream_cookie->fd == -1) {
00529 ast_log(LOG_ERROR, "TCP/TLS write called on invalid stream.\n");
00530 errno = EIO;
00531 return -1;
00532 }
00533
00534 return tcptls_stream_write(tcptls_session->stream_cookie, buf, count);
00535 }
00536
00537 static void session_instance_destructor(void *obj)
00538 {
00539 struct ast_tcptls_session_instance *i = obj;
00540
00541 if (i->stream_cookie) {
00542 ao2_t_ref(i->stream_cookie, -1, "Destroying tcptls session instance");
00543 i->stream_cookie = NULL;
00544 }
00545 ast_free(i->overflow_buf);
00546 }
00547
00548
00549
00550
00551
00552
00553
00554
00555 static void *handle_tcptls_connection(void *data)
00556 {
00557 struct ast_tcptls_session_instance *tcptls_session = data;
00558 #ifdef DO_SSL
00559 int (*ssl_setup)(SSL *) = (tcptls_session->client) ? SSL_connect : SSL_accept;
00560 int ret;
00561 char err[256];
00562 #endif
00563
00564
00565
00566
00567
00568
00569 if (ast_thread_inhibit_escalations()) {
00570 ast_log(LOG_ERROR, "Failed to inhibit privilege escalations; killing connection\n");
00571 ast_tcptls_close_session_file(tcptls_session);
00572 ao2_ref(tcptls_session, -1);
00573 return NULL;
00574 }
00575
00576 tcptls_session->stream_cookie = tcptls_stream_alloc();
00577 if (!tcptls_session->stream_cookie) {
00578 ast_tcptls_close_session_file(tcptls_session);
00579 ao2_ref(tcptls_session, -1);
00580 return NULL;
00581 }
00582
00583
00584
00585
00586 if (!tcptls_session->parent->tls_cfg) {
00587 tcptls_session->f = tcptls_stream_fopen(tcptls_session->stream_cookie, NULL,
00588 tcptls_session->fd, -1);
00589 if (tcptls_session->f) {
00590 if (setvbuf(tcptls_session->f, NULL, _IONBF, 0)) {
00591 ast_tcptls_close_session_file(tcptls_session);
00592 }
00593 }
00594 }
00595 #ifdef DO_SSL
00596 else if ( (tcptls_session->ssl = SSL_new(tcptls_session->parent->tls_cfg->ssl_ctx)) ) {
00597 SSL_set_fd(tcptls_session->ssl, tcptls_session->fd);
00598 if ((ret = ssl_setup(tcptls_session->ssl)) <= 0) {
00599 ast_verb(2, "Problem setting up ssl connection: %s\n", ERR_error_string(ERR_get_error(), err));
00600 } else if ((tcptls_session->f = tcptls_stream_fopen(tcptls_session->stream_cookie,
00601 tcptls_session->ssl, tcptls_session->fd, -1))) {
00602 if ((tcptls_session->client && !ast_test_flag(&tcptls_session->parent->tls_cfg->flags, AST_SSL_DONT_VERIFY_SERVER))
00603 || (!tcptls_session->client && ast_test_flag(&tcptls_session->parent->tls_cfg->flags, AST_SSL_VERIFY_CLIENT))) {
00604 X509 *peer;
00605 long res;
00606 peer = SSL_get_peer_certificate(tcptls_session->ssl);
00607 if (!peer) {
00608 ast_log(LOG_ERROR, "No peer SSL certificate to verify\n");
00609 ast_tcptls_close_session_file(tcptls_session);
00610 ao2_ref(tcptls_session, -1);
00611 return NULL;
00612 }
00613
00614 res = SSL_get_verify_result(tcptls_session->ssl);
00615 if (res != X509_V_OK) {
00616 ast_log(LOG_ERROR, "Certificate did not verify: %s\n", X509_verify_cert_error_string(res));
00617 X509_free(peer);
00618 ast_tcptls_close_session_file(tcptls_session);
00619 ao2_ref(tcptls_session, -1);
00620 return NULL;
00621 }
00622 if (!ast_test_flag(&tcptls_session->parent->tls_cfg->flags, AST_SSL_IGNORE_COMMON_NAME)) {
00623 ASN1_STRING *str;
00624 unsigned char *str2;
00625 X509_NAME *name = X509_get_subject_name(peer);
00626 int pos = -1;
00627 int found = 0;
00628
00629 for (;;) {
00630
00631
00632 pos = X509_NAME_get_index_by_NID(name, NID_commonName, pos);
00633 if (pos < 0) {
00634 break;
00635 }
00636 str = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name, pos));
00637 ASN1_STRING_to_UTF8(&str2, str);
00638 if (str2) {
00639 if (!strcasecmp(tcptls_session->parent->hostname, (char *) str2)) {
00640 found = 1;
00641 }
00642 ast_debug(3, "SSL Common Name compare s1='%s' s2='%s'\n", tcptls_session->parent->hostname, str2);
00643 OPENSSL_free(str2);
00644 }
00645 if (found) {
00646 break;
00647 }
00648 }
00649 if (!found) {
00650 ast_log(LOG_ERROR, "Certificate common name did not match (%s)\n", tcptls_session->parent->hostname);
00651 X509_free(peer);
00652 ast_tcptls_close_session_file(tcptls_session);
00653 ao2_ref(tcptls_session, -1);
00654 return NULL;
00655 }
00656 }
00657 X509_free(peer);
00658 }
00659 }
00660 if (!tcptls_session->f) {
00661 SSL_free(tcptls_session->ssl);
00662 }
00663 }
00664 #endif
00665
00666 if (!tcptls_session->f) {
00667 ast_tcptls_close_session_file(tcptls_session);
00668 ast_log(LOG_WARNING, "FILE * open failed!\n");
00669 #ifndef DO_SSL
00670 if (tcptls_session->parent->tls_cfg) {
00671 ast_log(LOG_WARNING, "Attempted a TLS connection without OpenSSL support. This will not work!\n");
00672 }
00673 #endif
00674 ao2_ref(tcptls_session, -1);
00675 return NULL;
00676 }
00677
00678 if (tcptls_session->parent->worker_fn) {
00679 return tcptls_session->parent->worker_fn(tcptls_session);
00680 } else {
00681 return tcptls_session;
00682 }
00683 }
00684
00685 void *ast_tcptls_server_root(void *data)
00686 {
00687 struct ast_tcptls_session_args *desc = data;
00688 int fd;
00689 struct ast_sockaddr addr;
00690 struct ast_tcptls_session_instance *tcptls_session;
00691 pthread_t launched;
00692
00693 for (;;) {
00694 int i, flags;
00695
00696 if (desc->periodic_fn) {
00697 desc->periodic_fn(desc);
00698 }
00699 i = ast_wait_for_input(desc->accept_fd, desc->poll_timeout);
00700 if (i <= 0) {
00701 continue;
00702 }
00703 fd = ast_accept(desc->accept_fd, &addr);
00704 if (fd < 0) {
00705 if ((errno != EAGAIN) && (errno != EINTR)) {
00706 ast_log(LOG_WARNING, "Accept failed: %s\n", strerror(errno));
00707 }
00708 continue;
00709 }
00710 tcptls_session = ao2_alloc(sizeof(*tcptls_session), session_instance_destructor);
00711 if (!tcptls_session) {
00712 ast_log(LOG_WARNING, "No memory for new session: %s\n", strerror(errno));
00713 if (close(fd)) {
00714 ast_log(LOG_ERROR, "close() failed: %s\n", strerror(errno));
00715 }
00716 continue;
00717 }
00718
00719 tcptls_session->overflow_buf = ast_str_create(128);
00720 flags = fcntl(fd, F_GETFL);
00721 fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
00722 tcptls_session->fd = fd;
00723 tcptls_session->parent = desc;
00724 ast_sockaddr_copy(&tcptls_session->remote_address, &addr);
00725
00726 tcptls_session->client = 0;
00727
00728
00729 if (ast_pthread_create_detached_background(&launched, NULL, handle_tcptls_connection, tcptls_session)) {
00730 ast_log(LOG_WARNING, "Unable to launch helper thread: %s\n", strerror(errno));
00731 ast_tcptls_close_session_file(tcptls_session);
00732 ao2_ref(tcptls_session, -1);
00733 }
00734 }
00735 return NULL;
00736 }
00737
00738 static int __ssl_setup(struct ast_tls_config *cfg, int client)
00739 {
00740 #ifndef DO_SSL
00741 cfg->enabled = 0;
00742 return 0;
00743 #else
00744 if (!cfg->enabled) {
00745 return 0;
00746 }
00747
00748
00749
00750
00751 if (cfg->ssl_ctx) {
00752 SSL_CTX_free(cfg->ssl_ctx);
00753 cfg->ssl_ctx = NULL;
00754 }
00755
00756 if (client) {
00757 #ifndef OPENSSL_NO_SSL2
00758 if (ast_test_flag(&cfg->flags, AST_SSL_SSLV2_CLIENT)) {
00759 cfg->ssl_ctx = SSL_CTX_new(SSLv2_client_method());
00760 } else
00761 #endif
00762 if (ast_test_flag(&cfg->flags, AST_SSL_SSLV3_CLIENT)) {
00763 cfg->ssl_ctx = SSL_CTX_new(SSLv3_client_method());
00764 } else if (ast_test_flag(&cfg->flags, AST_SSL_TLSV1_CLIENT)) {
00765 cfg->ssl_ctx = SSL_CTX_new(TLSv1_client_method());
00766 } else {
00767
00768
00769
00770
00771 cfg->ssl_ctx = SSL_CTX_new(SSLv23_client_method());
00772 }
00773 } else {
00774
00775 cfg->ssl_ctx = SSL_CTX_new(SSLv23_server_method());
00776 }
00777
00778 if (!cfg->ssl_ctx) {
00779 ast_debug(1, "Sorry, SSL_CTX_new call returned null...\n");
00780 cfg->enabled = 0;
00781 return 0;
00782 }
00783
00784 SSL_CTX_set_verify(cfg->ssl_ctx,
00785 ast_test_flag(&cfg->flags, AST_SSL_VERIFY_CLIENT) ? SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT : SSL_VERIFY_NONE,
00786 NULL);
00787
00788 if (!ast_strlen_zero(cfg->certfile)) {
00789 char *tmpprivate = ast_strlen_zero(cfg->pvtfile) ? cfg->certfile : cfg->pvtfile;
00790 if (SSL_CTX_use_certificate_chain_file(cfg->ssl_ctx, cfg->certfile) == 0) {
00791 if (!client) {
00792
00793 ast_verb(0, "SSL error loading cert file. <%s>\n", cfg->certfile);
00794 cfg->enabled = 0;
00795 SSL_CTX_free(cfg->ssl_ctx);
00796 cfg->ssl_ctx = NULL;
00797 return 0;
00798 }
00799 }
00800 if ((SSL_CTX_use_PrivateKey_file(cfg->ssl_ctx, tmpprivate, SSL_FILETYPE_PEM) == 0) || (SSL_CTX_check_private_key(cfg->ssl_ctx) == 0 )) {
00801 if (!client) {
00802
00803 ast_verb(0, "SSL error loading private key file. <%s>\n", tmpprivate);
00804 cfg->enabled = 0;
00805 SSL_CTX_free(cfg->ssl_ctx);
00806 cfg->ssl_ctx = NULL;
00807 return 0;
00808 }
00809 }
00810 }
00811 if (!ast_strlen_zero(cfg->cipher)) {
00812 if (SSL_CTX_set_cipher_list(cfg->ssl_ctx, cfg->cipher) == 0 ) {
00813 if (!client) {
00814 ast_verb(0, "SSL cipher error <%s>\n", cfg->cipher);
00815 cfg->enabled = 0;
00816 SSL_CTX_free(cfg->ssl_ctx);
00817 cfg->ssl_ctx = NULL;
00818 return 0;
00819 }
00820 }
00821 }
00822 if (!ast_strlen_zero(cfg->cafile) || !ast_strlen_zero(cfg->capath)) {
00823 if (SSL_CTX_load_verify_locations(cfg->ssl_ctx, S_OR(cfg->cafile, NULL), S_OR(cfg->capath,NULL)) == 0) {
00824 ast_verb(0, "SSL CA file(%s)/path(%s) error\n", cfg->cafile, cfg->capath);
00825 }
00826 }
00827
00828 ast_verb(0, "SSL certificate ok\n");
00829 return 1;
00830 #endif
00831 }
00832
00833 int ast_ssl_setup(struct ast_tls_config *cfg)
00834 {
00835 return __ssl_setup(cfg, 0);
00836 }
00837
00838 void ast_ssl_teardown(struct ast_tls_config *cfg)
00839 {
00840 #ifdef DO_SSL
00841 if (cfg->ssl_ctx) {
00842 SSL_CTX_free(cfg->ssl_ctx);
00843 cfg->ssl_ctx = NULL;
00844 }
00845 #endif
00846 }
00847
00848 struct ast_tcptls_session_instance *ast_tcptls_client_start(struct ast_tcptls_session_instance *tcptls_session)
00849 {
00850 struct ast_tcptls_session_args *desc;
00851 int flags;
00852
00853 if (!(desc = tcptls_session->parent)) {
00854 goto client_start_error;
00855 }
00856
00857 if (ast_connect(desc->accept_fd, &desc->remote_address)) {
00858 ast_log(LOG_ERROR, "Unable to connect %s to %s: %s\n",
00859 desc->name,
00860 ast_sockaddr_stringify(&desc->remote_address),
00861 strerror(errno));
00862 goto client_start_error;
00863 }
00864
00865 flags = fcntl(desc->accept_fd, F_GETFL);
00866 fcntl(desc->accept_fd, F_SETFL, flags & ~O_NONBLOCK);
00867
00868 if (desc->tls_cfg) {
00869 desc->tls_cfg->enabled = 1;
00870 __ssl_setup(desc->tls_cfg, 1);
00871 }
00872
00873 return handle_tcptls_connection(tcptls_session);
00874
00875 client_start_error:
00876 if (desc) {
00877 close(desc->accept_fd);
00878 desc->accept_fd = -1;
00879 }
00880 ao2_ref(tcptls_session, -1);
00881 return NULL;
00882
00883 }
00884
00885 struct ast_tcptls_session_instance *ast_tcptls_client_create(struct ast_tcptls_session_args *desc)
00886 {
00887 int x = 1;
00888 struct ast_tcptls_session_instance *tcptls_session = NULL;
00889
00890
00891 if (!ast_sockaddr_cmp(&desc->old_address, &desc->remote_address)) {
00892 ast_debug(1, "Nothing changed in %s\n", desc->name);
00893 return NULL;
00894 }
00895
00896
00897 ast_sockaddr_setnull(&desc->old_address);
00898
00899 if (desc->accept_fd != -1) {
00900 close(desc->accept_fd);
00901 }
00902
00903 desc->accept_fd = socket(ast_sockaddr_is_ipv6(&desc->remote_address) ?
00904 AF_INET6 : AF_INET, SOCK_STREAM, IPPROTO_TCP);
00905 if (desc->accept_fd < 0) {
00906 ast_log(LOG_WARNING, "Unable to allocate socket for %s: %s\n",
00907 desc->name, strerror(errno));
00908 return NULL;
00909 }
00910
00911
00912
00913 if (!ast_sockaddr_isnull(&desc->local_address)) {
00914 setsockopt(desc->accept_fd, SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x));
00915 if (ast_bind(desc->accept_fd, &desc->local_address)) {
00916 ast_log(LOG_ERROR, "Unable to bind %s to %s: %s\n",
00917 desc->name,
00918 ast_sockaddr_stringify(&desc->local_address),
00919 strerror(errno));
00920 goto error;
00921 }
00922 }
00923
00924 if (!(tcptls_session = ao2_alloc(sizeof(*tcptls_session), session_instance_destructor))) {
00925 goto error;
00926 }
00927
00928 tcptls_session->overflow_buf = ast_str_create(128);
00929 tcptls_session->client = 1;
00930 tcptls_session->fd = desc->accept_fd;
00931 tcptls_session->parent = desc;
00932 tcptls_session->parent->worker_fn = NULL;
00933 ast_sockaddr_copy(&tcptls_session->remote_address,
00934 &desc->remote_address);
00935
00936
00937 ast_sockaddr_copy(&desc->old_address, &desc->remote_address);
00938 return tcptls_session;
00939
00940 error:
00941 close(desc->accept_fd);
00942 desc->accept_fd = -1;
00943 if (tcptls_session) {
00944 ao2_ref(tcptls_session, -1);
00945 }
00946 return NULL;
00947 }
00948
00949 void ast_tcptls_server_start(struct ast_tcptls_session_args *desc)
00950 {
00951 int flags;
00952 int x = 1;
00953
00954
00955 if (!ast_sockaddr_cmp(&desc->old_address, &desc->local_address)) {
00956 ast_debug(1, "Nothing changed in %s\n", desc->name);
00957 return;
00958 }
00959
00960
00961 ast_sockaddr_setnull(&desc->old_address);
00962
00963
00964 if (desc->master != AST_PTHREADT_NULL) {
00965 pthread_cancel(desc->master);
00966 pthread_kill(desc->master, SIGURG);
00967 pthread_join(desc->master, NULL);
00968 }
00969
00970 if (desc->accept_fd != -1) {
00971 close(desc->accept_fd);
00972 }
00973
00974
00975 if (ast_sockaddr_isnull(&desc->local_address)) {
00976 ast_debug(2, "Server disabled: %s\n", desc->name);
00977 return;
00978 }
00979
00980 desc->accept_fd = socket(ast_sockaddr_is_ipv6(&desc->local_address) ?
00981 AF_INET6 : AF_INET, SOCK_STREAM, 0);
00982 if (desc->accept_fd < 0) {
00983 ast_log(LOG_ERROR, "Unable to allocate socket for %s: %s\n", desc->name, strerror(errno));
00984 return;
00985 }
00986
00987 setsockopt(desc->accept_fd, SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x));
00988 if (ast_bind(desc->accept_fd, &desc->local_address)) {
00989 ast_log(LOG_ERROR, "Unable to bind %s to %s: %s\n",
00990 desc->name,
00991 ast_sockaddr_stringify(&desc->local_address),
00992 strerror(errno));
00993 goto error;
00994 }
00995 if (listen(desc->accept_fd, 10)) {
00996 ast_log(LOG_ERROR, "Unable to listen for %s!\n", desc->name);
00997 goto error;
00998 }
00999 flags = fcntl(desc->accept_fd, F_GETFL);
01000 fcntl(desc->accept_fd, F_SETFL, flags | O_NONBLOCK);
01001 if (ast_pthread_create_background(&desc->master, NULL, desc->accept_fn, desc)) {
01002 ast_log(LOG_ERROR, "Unable to launch thread for %s on %s: %s\n",
01003 desc->name,
01004 ast_sockaddr_stringify(&desc->local_address),
01005 strerror(errno));
01006 goto error;
01007 }
01008
01009
01010 ast_sockaddr_copy(&desc->old_address, &desc->local_address);
01011
01012 return;
01013
01014 error:
01015 close(desc->accept_fd);
01016 desc->accept_fd = -1;
01017 }
01018
01019 void ast_tcptls_close_session_file(struct ast_tcptls_session_instance *tcptls_session)
01020 {
01021 if (tcptls_session->f) {
01022 fflush(tcptls_session->f);
01023 if (fclose(tcptls_session->f)) {
01024 ast_log(LOG_ERROR, "fclose() failed: %s\n", strerror(errno));
01025 }
01026 tcptls_session->f = NULL;
01027 tcptls_session->fd = -1;
01028 } else if (tcptls_session->fd != -1) {
01029
01030
01031
01032
01033
01034 shutdown(tcptls_session->fd, SHUT_RDWR);
01035 if (close(tcptls_session->fd)) {
01036 ast_log(LOG_ERROR, "close() failed: %s\n", strerror(errno));
01037 }
01038 tcptls_session->fd = -1;
01039 } else {
01040 ast_log(LOG_ERROR, "ast_tcptls_close_session_file invoked on session instance without file or file descriptor\n");
01041 }
01042 }
01043
01044 void ast_tcptls_server_stop(struct ast_tcptls_session_args *desc)
01045 {
01046 if (desc->master != AST_PTHREADT_NULL) {
01047 pthread_cancel(desc->master);
01048 pthread_kill(desc->master, SIGURG);
01049 pthread_join(desc->master, NULL);
01050 desc->master = AST_PTHREADT_NULL;
01051 }
01052 if (desc->accept_fd != -1) {
01053 close(desc->accept_fd);
01054 }
01055 desc->accept_fd = -1;
01056 ast_debug(2, "Stopped server :: %s\n", desc->name);
01057 }
01058
01059 int ast_tls_read_conf(struct ast_tls_config *tls_cfg, struct ast_tcptls_session_args *tls_desc, const char *varname, const char *value)
01060 {
01061 if (!strcasecmp(varname, "tlsenable") || !strcasecmp(varname, "sslenable")) {
01062 tls_cfg->enabled = ast_true(value) ? 1 : 0;
01063 } else if (!strcasecmp(varname, "tlscertfile") || !strcasecmp(varname, "sslcert") || !strcasecmp(varname, "tlscert")) {
01064 ast_free(tls_cfg->certfile);
01065 tls_cfg->certfile = ast_strdup(value);
01066 } else if (!strcasecmp(varname, "tlsprivatekey") || !strcasecmp(varname, "sslprivatekey")) {
01067 ast_free(tls_cfg->pvtfile);
01068 tls_cfg->pvtfile = ast_strdup(value);
01069 } else if (!strcasecmp(varname, "tlscipher") || !strcasecmp(varname, "sslcipher")) {
01070 ast_free(tls_cfg->cipher);
01071 tls_cfg->cipher = ast_strdup(value);
01072 } else if (!strcasecmp(varname, "tlscafile")) {
01073 ast_free(tls_cfg->cafile);
01074 tls_cfg->cafile = ast_strdup(value);
01075 } else if (!strcasecmp(varname, "tlscapath") || !strcasecmp(varname, "tlscadir")) {
01076 ast_free(tls_cfg->capath);
01077 tls_cfg->capath = ast_strdup(value);
01078 } else if (!strcasecmp(varname, "tlsverifyclient")) {
01079 ast_set2_flag(&tls_cfg->flags, ast_true(value), AST_SSL_VERIFY_CLIENT);
01080 } else if (!strcasecmp(varname, "tlsdontverifyserver")) {
01081 ast_set2_flag(&tls_cfg->flags, ast_true(value), AST_SSL_DONT_VERIFY_SERVER);
01082 } else if (!strcasecmp(varname, "tlsbindaddr") || !strcasecmp(varname, "sslbindaddr")) {
01083 if (ast_parse_arg(value, PARSE_ADDR, &tls_desc->local_address))
01084 ast_log(LOG_WARNING, "Invalid %s '%s'\n", varname, value);
01085 } else if (!strcasecmp(varname, "tlsclientmethod") || !strcasecmp(varname, "sslclientmethod")) {
01086 if (!strcasecmp(value, "tlsv1")) {
01087 ast_set_flag(&tls_cfg->flags, AST_SSL_TLSV1_CLIENT);
01088 ast_clear_flag(&tls_cfg->flags, AST_SSL_SSLV3_CLIENT);
01089 ast_clear_flag(&tls_cfg->flags, AST_SSL_SSLV2_CLIENT);
01090 } else if (!strcasecmp(value, "sslv3")) {
01091 ast_set_flag(&tls_cfg->flags, AST_SSL_SSLV3_CLIENT);
01092 ast_clear_flag(&tls_cfg->flags, AST_SSL_SSLV2_CLIENT);
01093 ast_clear_flag(&tls_cfg->flags, AST_SSL_TLSV1_CLIENT);
01094 } else if (!strcasecmp(value, "sslv2")) {
01095 ast_set_flag(&tls_cfg->flags, AST_SSL_SSLV2_CLIENT);
01096 ast_clear_flag(&tls_cfg->flags, AST_SSL_TLSV1_CLIENT);
01097 ast_clear_flag(&tls_cfg->flags, AST_SSL_SSLV3_CLIENT);
01098 }
01099 } else {
01100 return -1;
01101 }
01102
01103 return 0;
01104 }