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: 426015 $")
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 #ifdef AST_DEVMODE
00438
00439
00440
00441 struct ast_tcptls_stream *stream = cookie;
00442 #endif
00443
00444 ast_assert(stream->fd == -1);
00445 }
00446
00447
00448
00449
00450
00451
00452
00453
00454 static struct ast_tcptls_stream *tcptls_stream_alloc(void)
00455 {
00456 struct ast_tcptls_stream *stream;
00457
00458 stream = ao2_alloc(sizeof(*stream), tcptls_stream_dtor);
00459 if (stream) {
00460 stream->fd = -1;
00461 stream->timeout = -1;
00462 }
00463 return stream;
00464 }
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478 static FILE *tcptls_stream_fopen(struct ast_tcptls_stream *stream, SSL *ssl, int fd, int timeout)
00479 {
00480 FILE *fp;
00481
00482 #if defined(HAVE_FOPENCOOKIE)
00483 static const cookie_io_functions_t cookie_funcs = {
00484 tcptls_stream_read,
00485 tcptls_stream_write,
00486 NULL,
00487 tcptls_stream_close
00488 };
00489 #endif
00490
00491 if (fd == -1) {
00492
00493 return NULL;
00494 }
00495
00496 stream->ssl = ssl;
00497 stream->fd = fd;
00498 stream->timeout = timeout;
00499 ao2_t_ref(stream, +1, "Opening tcptls stream cookie");
00500
00501 #if defined(HAVE_FUNOPEN)
00502 fp = funopen(stream, tcptls_stream_read, tcptls_stream_write, NULL,
00503 tcptls_stream_close);
00504 #elif defined(HAVE_FOPENCOOKIE)
00505 fp = fopencookie(stream, "w+", cookie_funcs);
00506 #else
00507
00508 ast_debug(2, "No stream FILE methods attempted!\n");
00509 fp = NULL;
00510 #endif
00511
00512 if (!fp) {
00513 stream->fd = -1;
00514 ao2_t_ref(stream, -1, "Failed to open tcptls stream cookie");
00515 }
00516 return fp;
00517 }
00518
00519 HOOK_T ast_tcptls_server_read(struct ast_tcptls_session_instance *tcptls_session, void *buf, size_t count)
00520 {
00521 if (!tcptls_session->stream_cookie || tcptls_session->stream_cookie->fd == -1) {
00522 ast_log(LOG_ERROR, "TCP/TLS read called on invalid stream.\n");
00523 errno = EIO;
00524 return -1;
00525 }
00526
00527 return tcptls_stream_read(tcptls_session->stream_cookie, buf, count);
00528 }
00529
00530 HOOK_T ast_tcptls_server_write(struct ast_tcptls_session_instance *tcptls_session, const void *buf, size_t count)
00531 {
00532 if (!tcptls_session->stream_cookie || tcptls_session->stream_cookie->fd == -1) {
00533 ast_log(LOG_ERROR, "TCP/TLS write called on invalid stream.\n");
00534 errno = EIO;
00535 return -1;
00536 }
00537
00538 return tcptls_stream_write(tcptls_session->stream_cookie, buf, count);
00539 }
00540
00541 static void session_instance_destructor(void *obj)
00542 {
00543 struct ast_tcptls_session_instance *i = obj;
00544
00545 if (i->stream_cookie) {
00546 ao2_t_ref(i->stream_cookie, -1, "Destroying tcptls session instance");
00547 i->stream_cookie = NULL;
00548 }
00549 ast_free(i->overflow_buf);
00550 ast_mutex_destroy(&i->lock);
00551 }
00552
00553
00554
00555
00556
00557
00558
00559
00560 static void *handle_tcptls_connection(void *data)
00561 {
00562 struct ast_tcptls_session_instance *tcptls_session = data;
00563 #ifdef DO_SSL
00564 int (*ssl_setup)(SSL *) = (tcptls_session->client) ? SSL_connect : SSL_accept;
00565 int ret;
00566 char err[256];
00567 #endif
00568
00569
00570
00571
00572
00573
00574 if (ast_thread_inhibit_escalations()) {
00575 ast_log(LOG_ERROR, "Failed to inhibit privilege escalations; killing connection\n");
00576 ast_tcptls_close_session_file(tcptls_session);
00577 ao2_ref(tcptls_session, -1);
00578 return NULL;
00579 }
00580
00581 tcptls_session->stream_cookie = tcptls_stream_alloc();
00582 if (!tcptls_session->stream_cookie) {
00583 ast_tcptls_close_session_file(tcptls_session);
00584 ao2_ref(tcptls_session, -1);
00585 return NULL;
00586 }
00587
00588
00589
00590
00591 if (!tcptls_session->parent->tls_cfg) {
00592 tcptls_session->f = tcptls_stream_fopen(tcptls_session->stream_cookie, NULL,
00593 tcptls_session->fd, -1);
00594 if (tcptls_session->f) {
00595 if (setvbuf(tcptls_session->f, NULL, _IONBF, 0)) {
00596 ast_tcptls_close_session_file(tcptls_session);
00597 }
00598 }
00599 }
00600 #ifdef DO_SSL
00601 else if ( (tcptls_session->ssl = SSL_new(tcptls_session->parent->tls_cfg->ssl_ctx)) ) {
00602 SSL_set_fd(tcptls_session->ssl, tcptls_session->fd);
00603 if ((ret = ssl_setup(tcptls_session->ssl)) <= 0) {
00604 ast_verb(2, "Problem setting up ssl connection: %s\n", ERR_error_string(ERR_get_error(), err));
00605 } else if ((tcptls_session->f = tcptls_stream_fopen(tcptls_session->stream_cookie,
00606 tcptls_session->ssl, tcptls_session->fd, -1))) {
00607 if ((tcptls_session->client && !ast_test_flag(&tcptls_session->parent->tls_cfg->flags, AST_SSL_DONT_VERIFY_SERVER))
00608 || (!tcptls_session->client && ast_test_flag(&tcptls_session->parent->tls_cfg->flags, AST_SSL_VERIFY_CLIENT))) {
00609 X509 *peer;
00610 long res;
00611 peer = SSL_get_peer_certificate(tcptls_session->ssl);
00612 if (!peer) {
00613 ast_log(LOG_ERROR, "No peer SSL certificate to verify\n");
00614 ast_tcptls_close_session_file(tcptls_session);
00615 ao2_ref(tcptls_session, -1);
00616 return NULL;
00617 }
00618
00619 res = SSL_get_verify_result(tcptls_session->ssl);
00620 if (res != X509_V_OK) {
00621 ast_log(LOG_ERROR, "Certificate did not verify: %s\n", X509_verify_cert_error_string(res));
00622 X509_free(peer);
00623 ast_tcptls_close_session_file(tcptls_session);
00624 ao2_ref(tcptls_session, -1);
00625 return NULL;
00626 }
00627 if (!ast_test_flag(&tcptls_session->parent->tls_cfg->flags, AST_SSL_IGNORE_COMMON_NAME)) {
00628 ASN1_STRING *str;
00629 unsigned char *str2;
00630 X509_NAME *name = X509_get_subject_name(peer);
00631 int pos = -1;
00632 int found = 0;
00633
00634 for (;;) {
00635
00636
00637 pos = X509_NAME_get_index_by_NID(name, NID_commonName, pos);
00638 if (pos < 0)
00639 break;
00640 str = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name, pos));
00641 ASN1_STRING_to_UTF8(&str2, str);
00642 if (str2) {
00643 if (!strcasecmp(tcptls_session->parent->hostname, (char *) str2))
00644 found = 1;
00645 ast_debug(3, "SSL Common Name compare s1='%s' s2='%s'\n", tcptls_session->parent->hostname, str2);
00646 OPENSSL_free(str2);
00647 }
00648 if (found)
00649 break;
00650 }
00651 if (!found) {
00652 ast_log(LOG_ERROR, "Certificate common name did not match (%s)\n", tcptls_session->parent->hostname);
00653 X509_free(peer);
00654 ast_tcptls_close_session_file(tcptls_session);
00655 ao2_ref(tcptls_session, -1);
00656 return NULL;
00657 }
00658 }
00659 X509_free(peer);
00660 }
00661 }
00662 if (!tcptls_session->f)
00663 SSL_free(tcptls_session->ssl);
00664 }
00665 #endif
00666
00667 if (!tcptls_session->f) {
00668 ast_tcptls_close_session_file(tcptls_session);
00669 ast_log(LOG_WARNING, "FILE * open failed!\n");
00670 #ifndef DO_SSL
00671 if (tcptls_session->parent->tls_cfg) {
00672 ast_log(LOG_WARNING, "Attempted a TLS connection without OpenSSL support. This will not work!\n");
00673 }
00674 #endif
00675 ao2_ref(tcptls_session, -1);
00676 return NULL;
00677 }
00678
00679 if (tcptls_session->parent->worker_fn) {
00680 return tcptls_session->parent->worker_fn(tcptls_session);
00681 } else {
00682 return tcptls_session;
00683 }
00684 }
00685
00686 void *ast_tcptls_server_root(void *data)
00687 {
00688 struct ast_tcptls_session_args *desc = data;
00689 int fd;
00690 struct ast_sockaddr addr;
00691 struct ast_tcptls_session_instance *tcptls_session;
00692 pthread_t launched;
00693
00694 for (;;) {
00695 int i, flags;
00696
00697 if (desc->periodic_fn)
00698 desc->periodic_fn(desc);
00699 i = ast_wait_for_input(desc->accept_fd, desc->poll_timeout);
00700 if (i <= 0)
00701 continue;
00702 fd = ast_accept(desc->accept_fd, &addr);
00703 if (fd < 0) {
00704 if ((errno != EAGAIN) && (errno != EINTR))
00705 ast_log(LOG_WARNING, "Accept failed: %s\n", strerror(errno));
00706 continue;
00707 }
00708 tcptls_session = ao2_alloc(sizeof(*tcptls_session), session_instance_destructor);
00709 if (!tcptls_session) {
00710 ast_log(LOG_WARNING, "No memory for new session: %s\n", strerror(errno));
00711 if (close(fd)) {
00712 ast_log(LOG_ERROR, "close() failed: %s\n", strerror(errno));
00713 }
00714 continue;
00715 }
00716
00717 ast_mutex_init(&tcptls_session->lock);
00718 tcptls_session->overflow_buf = ast_str_create(128);
00719
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 int disable_ssl = 0;
00745
00746 if (!cfg->enabled)
00747 return 0;
00748
00749
00750
00751
00752 if (cfg->ssl_ctx) {
00753 SSL_CTX_free(cfg->ssl_ctx);
00754 cfg->ssl_ctx = NULL;
00755 }
00756
00757 if (client) {
00758 #ifndef OPENSSL_NO_SSL2
00759 if (ast_test_flag(&cfg->flags, AST_SSL_SSLV2_CLIENT)) {
00760 ast_log(LOG_WARNING, "Usage of SSLv2 is discouraged due to known vulnerabilities. Please use 'tlsv1' or leave the TLS method unspecified!\n");
00761 cfg->ssl_ctx = SSL_CTX_new(SSLv2_client_method());
00762 } else
00763 #endif
00764 if (ast_test_flag(&cfg->flags, AST_SSL_SSLV3_CLIENT)) {
00765 ast_log(LOG_WARNING, "Usage of SSLv3 is discouraged due to known vulnerabilities. Please use 'tlsv1' or leave the TLS method unspecified!\n");
00766 cfg->ssl_ctx = SSL_CTX_new(SSLv3_client_method());
00767 } else if (ast_test_flag(&cfg->flags, AST_SSL_TLSV1_CLIENT)) {
00768 cfg->ssl_ctx = SSL_CTX_new(TLSv1_client_method());
00769 } else {
00770 disable_ssl = 1;
00771 cfg->ssl_ctx = SSL_CTX_new(SSLv23_client_method());
00772 }
00773 } else {
00774 disable_ssl = 1;
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
00785
00786
00787
00788 if (disable_ssl) {
00789 long ssl_opts;
00790
00791 ssl_opts = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3;
00792 SSL_CTX_set_options(cfg->ssl_ctx, ssl_opts);
00793 }
00794
00795 SSL_CTX_set_verify(cfg->ssl_ctx,
00796 ast_test_flag(&cfg->flags, AST_SSL_VERIFY_CLIENT) ? SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT : SSL_VERIFY_NONE,
00797 NULL);
00798
00799 if (!ast_strlen_zero(cfg->certfile)) {
00800 char *tmpprivate = ast_strlen_zero(cfg->pvtfile) ? cfg->certfile : cfg->pvtfile;
00801 if (SSL_CTX_use_certificate_chain_file(cfg->ssl_ctx, cfg->certfile) == 0) {
00802 if (!client) {
00803
00804 ast_verb(0, "SSL error loading cert file. <%s>", cfg->certfile);
00805 cfg->enabled = 0;
00806 SSL_CTX_free(cfg->ssl_ctx);
00807 cfg->ssl_ctx = NULL;
00808 return 0;
00809 }
00810 }
00811 if ((SSL_CTX_use_PrivateKey_file(cfg->ssl_ctx, tmpprivate, SSL_FILETYPE_PEM) == 0) || (SSL_CTX_check_private_key(cfg->ssl_ctx) == 0 )) {
00812 if (!client) {
00813
00814 ast_verb(0, "SSL error loading private key file. <%s>", tmpprivate);
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->cipher)) {
00823 if (SSL_CTX_set_cipher_list(cfg->ssl_ctx, cfg->cipher) == 0 ) {
00824 if (!client) {
00825 ast_verb(0, "SSL cipher error <%s>", cfg->cipher);
00826 cfg->enabled = 0;
00827 SSL_CTX_free(cfg->ssl_ctx);
00828 cfg->ssl_ctx = NULL;
00829 return 0;
00830 }
00831 }
00832 }
00833 if (!ast_strlen_zero(cfg->cafile) || !ast_strlen_zero(cfg->capath)) {
00834 if (SSL_CTX_load_verify_locations(cfg->ssl_ctx, S_OR(cfg->cafile, NULL), S_OR(cfg->capath,NULL)) == 0)
00835 ast_verb(0, "SSL CA file(%s)/path(%s) error\n", cfg->cafile, cfg->capath);
00836 }
00837
00838 ast_verb(0, "SSL certificate ok\n");
00839 return 1;
00840 #endif
00841 }
00842
00843 int ast_ssl_setup(struct ast_tls_config *cfg)
00844 {
00845 return __ssl_setup(cfg, 0);
00846 }
00847
00848 void ast_ssl_teardown(struct ast_tls_config *cfg)
00849 {
00850 #ifdef DO_SSL
00851 if (cfg->ssl_ctx) {
00852 SSL_CTX_free(cfg->ssl_ctx);
00853 cfg->ssl_ctx = NULL;
00854 }
00855 #endif
00856 }
00857
00858 struct ast_tcptls_session_instance *ast_tcptls_client_start(struct ast_tcptls_session_instance *tcptls_session)
00859 {
00860 struct ast_tcptls_session_args *desc;
00861 int flags;
00862
00863 if (!(desc = tcptls_session->parent)) {
00864 goto client_start_error;
00865 }
00866
00867 if (ast_connect(desc->accept_fd, &desc->remote_address)) {
00868 ast_log(LOG_ERROR, "Unable to connect %s to %s: %s\n",
00869 desc->name,
00870 ast_sockaddr_stringify(&desc->remote_address),
00871 strerror(errno));
00872 goto client_start_error;
00873 }
00874
00875 flags = fcntl(desc->accept_fd, F_GETFL);
00876 fcntl(desc->accept_fd, F_SETFL, flags & ~O_NONBLOCK);
00877
00878 if (desc->tls_cfg) {
00879 desc->tls_cfg->enabled = 1;
00880 __ssl_setup(desc->tls_cfg, 1);
00881 }
00882
00883 return handle_tcptls_connection(tcptls_session);
00884
00885 client_start_error:
00886 if (desc) {
00887 close(desc->accept_fd);
00888 desc->accept_fd = -1;
00889 }
00890 ao2_ref(tcptls_session, -1);
00891 return NULL;
00892
00893 }
00894
00895 struct ast_tcptls_session_instance *ast_tcptls_client_create(struct ast_tcptls_session_args *desc)
00896 {
00897 int x = 1;
00898 struct ast_tcptls_session_instance *tcptls_session = NULL;
00899
00900
00901 if (!ast_sockaddr_cmp(&desc->old_address, &desc->remote_address)) {
00902 ast_debug(1, "Nothing changed in %s\n", desc->name);
00903 return NULL;
00904 }
00905
00906
00907 ast_sockaddr_setnull(&desc->old_address);
00908
00909 if (desc->accept_fd != -1)
00910 close(desc->accept_fd);
00911
00912 desc->accept_fd = socket(ast_sockaddr_is_ipv6(&desc->remote_address) ?
00913 AF_INET6 : AF_INET, SOCK_STREAM, IPPROTO_TCP);
00914 if (desc->accept_fd < 0) {
00915 ast_log(LOG_WARNING, "Unable to allocate socket for %s: %s\n",
00916 desc->name, strerror(errno));
00917 return NULL;
00918 }
00919
00920
00921
00922 if (!ast_sockaddr_isnull(&desc->local_address)) {
00923 setsockopt(desc->accept_fd, SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x));
00924 if (ast_bind(desc->accept_fd, &desc->local_address)) {
00925 ast_log(LOG_ERROR, "Unable to bind %s to %s: %s\n",
00926 desc->name,
00927 ast_sockaddr_stringify(&desc->local_address),
00928 strerror(errno));
00929 goto error;
00930 }
00931 }
00932
00933 if (!(tcptls_session = ao2_alloc(sizeof(*tcptls_session), session_instance_destructor)))
00934 goto error;
00935
00936 ast_mutex_init(&tcptls_session->lock);
00937 tcptls_session->overflow_buf = ast_str_create(128);
00938 tcptls_session->client = 1;
00939 tcptls_session->fd = desc->accept_fd;
00940 tcptls_session->parent = desc;
00941 tcptls_session->parent->worker_fn = NULL;
00942 ast_sockaddr_copy(&tcptls_session->remote_address,
00943 &desc->remote_address);
00944
00945
00946 ast_sockaddr_copy(&desc->old_address, &desc->remote_address);
00947 return tcptls_session;
00948
00949 error:
00950 close(desc->accept_fd);
00951 desc->accept_fd = -1;
00952 if (tcptls_session)
00953 ao2_ref(tcptls_session, -1);
00954 return NULL;
00955 }
00956
00957 void ast_tcptls_server_start(struct ast_tcptls_session_args *desc)
00958 {
00959 int flags;
00960 int x = 1;
00961
00962
00963 if (!ast_sockaddr_cmp(&desc->old_address, &desc->local_address)) {
00964 ast_debug(1, "Nothing changed in %s\n", desc->name);
00965 return;
00966 }
00967
00968
00969 ast_sockaddr_setnull(&desc->old_address);
00970
00971
00972 if (desc->master != AST_PTHREADT_NULL) {
00973 pthread_cancel(desc->master);
00974 pthread_kill(desc->master, SIGURG);
00975 pthread_join(desc->master, NULL);
00976 }
00977
00978 if (desc->accept_fd != -1)
00979 close(desc->accept_fd);
00980
00981
00982 if (ast_sockaddr_isnull(&desc->local_address)) {
00983 ast_debug(2, "Server disabled: %s\n", desc->name);
00984 return;
00985 }
00986
00987 desc->accept_fd = socket(ast_sockaddr_is_ipv6(&desc->local_address) ?
00988 AF_INET6 : AF_INET, SOCK_STREAM, 0);
00989 if (desc->accept_fd < 0) {
00990 ast_log(LOG_ERROR, "Unable to allocate socket for %s: %s\n", desc->name, strerror(errno));
00991 return;
00992 }
00993
00994 setsockopt(desc->accept_fd, SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x));
00995 if (ast_bind(desc->accept_fd, &desc->local_address)) {
00996 ast_log(LOG_ERROR, "Unable to bind %s to %s: %s\n",
00997 desc->name,
00998 ast_sockaddr_stringify(&desc->local_address),
00999 strerror(errno));
01000 goto error;
01001 }
01002 if (listen(desc->accept_fd, 10)) {
01003 ast_log(LOG_ERROR, "Unable to listen for %s!\n", desc->name);
01004 goto error;
01005 }
01006 flags = fcntl(desc->accept_fd, F_GETFL);
01007 fcntl(desc->accept_fd, F_SETFL, flags | O_NONBLOCK);
01008 if (ast_pthread_create_background(&desc->master, NULL, desc->accept_fn, desc)) {
01009 ast_log(LOG_ERROR, "Unable to launch thread for %s on %s: %s\n",
01010 desc->name,
01011 ast_sockaddr_stringify(&desc->local_address),
01012 strerror(errno));
01013 goto error;
01014 }
01015
01016
01017 ast_sockaddr_copy(&desc->old_address, &desc->local_address);
01018
01019 return;
01020
01021 error:
01022 close(desc->accept_fd);
01023 desc->accept_fd = -1;
01024 }
01025
01026 void ast_tcptls_close_session_file(struct ast_tcptls_session_instance *tcptls_session)
01027 {
01028 if (tcptls_session->f) {
01029 fflush(tcptls_session->f);
01030 if (fclose(tcptls_session->f)) {
01031 ast_log(LOG_ERROR, "fclose() failed: %s\n", strerror(errno));
01032 }
01033 tcptls_session->f = NULL;
01034 tcptls_session->fd = -1;
01035 } else if (tcptls_session->fd != -1) {
01036
01037
01038
01039
01040
01041 shutdown(tcptls_session->fd, SHUT_RDWR);
01042 if (close(tcptls_session->fd)) {
01043 ast_log(LOG_ERROR, "close() failed: %s\n", strerror(errno));
01044 }
01045 tcptls_session->fd = -1;
01046 } else {
01047 ast_log(LOG_ERROR, "ast_tcptls_close_session_file invoked on session instance without file or file descriptor\n");
01048 }
01049 }
01050
01051 void ast_tcptls_server_stop(struct ast_tcptls_session_args *desc)
01052 {
01053 if (desc->master != AST_PTHREADT_NULL) {
01054 pthread_cancel(desc->master);
01055 pthread_kill(desc->master, SIGURG);
01056 pthread_join(desc->master, NULL);
01057 desc->master = AST_PTHREADT_NULL;
01058 }
01059 if (desc->accept_fd != -1)
01060 close(desc->accept_fd);
01061 desc->accept_fd = -1;
01062 ast_debug(2, "Stopped server :: %s\n", desc->name);
01063 }
01064
01065 int ast_tls_read_conf(struct ast_tls_config *tls_cfg, struct ast_tcptls_session_args *tls_desc, const char *varname, const char *value)
01066 {
01067 if (!strcasecmp(varname, "tlsenable") || !strcasecmp(varname, "sslenable")) {
01068 tls_cfg->enabled = ast_true(value) ? 1 : 0;
01069 } else if (!strcasecmp(varname, "tlscertfile") || !strcasecmp(varname, "sslcert") || !strcasecmp(varname, "tlscert")) {
01070 ast_free(tls_cfg->certfile);
01071 tls_cfg->certfile = ast_strdup(value);
01072 } else if (!strcasecmp(varname, "tlsprivatekey") || !strcasecmp(varname, "sslprivatekey")) {
01073 ast_free(tls_cfg->pvtfile);
01074 tls_cfg->pvtfile = ast_strdup(value);
01075 } else if (!strcasecmp(varname, "tlscipher") || !strcasecmp(varname, "sslcipher")) {
01076 ast_free(tls_cfg->cipher);
01077 tls_cfg->cipher = ast_strdup(value);
01078 } else if (!strcasecmp(varname, "tlscafile")) {
01079 ast_free(tls_cfg->cafile);
01080 tls_cfg->cafile = ast_strdup(value);
01081 } else if (!strcasecmp(varname, "tlscapath") || !strcasecmp(varname, "tlscadir")) {
01082 ast_free(tls_cfg->capath);
01083 tls_cfg->capath = ast_strdup(value);
01084 } else if (!strcasecmp(varname, "tlsverifyclient")) {
01085 ast_set2_flag(&tls_cfg->flags, ast_true(value), AST_SSL_VERIFY_CLIENT);
01086 } else if (!strcasecmp(varname, "tlsdontverifyserver")) {
01087 ast_set2_flag(&tls_cfg->flags, ast_true(value), AST_SSL_DONT_VERIFY_SERVER);
01088 } else if (!strcasecmp(varname, "tlsbindaddr") || !strcasecmp(varname, "sslbindaddr")) {
01089 if (ast_parse_arg(value, PARSE_ADDR, &tls_desc->local_address))
01090 ast_log(LOG_WARNING, "Invalid %s '%s'\n", varname, value);
01091 } else if (!strcasecmp(varname, "tlsclientmethod") || !strcasecmp(varname, "sslclientmethod")) {
01092 if (!strcasecmp(value, "tlsv1")) {
01093 ast_set_flag(&tls_cfg->flags, AST_SSL_TLSV1_CLIENT);
01094 ast_clear_flag(&tls_cfg->flags, AST_SSL_SSLV3_CLIENT);
01095 ast_clear_flag(&tls_cfg->flags, AST_SSL_SSLV2_CLIENT);
01096 } else if (!strcasecmp(value, "sslv3")) {
01097 ast_set_flag(&tls_cfg->flags, AST_SSL_SSLV3_CLIENT);
01098 ast_clear_flag(&tls_cfg->flags, AST_SSL_SSLV2_CLIENT);
01099 ast_clear_flag(&tls_cfg->flags, AST_SSL_TLSV1_CLIENT);
01100 } else if (!strcasecmp(value, "sslv2")) {
01101 ast_set_flag(&tls_cfg->flags, AST_SSL_SSLV2_CLIENT);
01102 ast_clear_flag(&tls_cfg->flags, AST_SSL_TLSV1_CLIENT);
01103 ast_clear_flag(&tls_cfg->flags, AST_SSL_SSLV3_CLIENT);
01104 }
01105 } else {
01106 return -1;
01107 }
01108
01109 return 0;
01110 }