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: 434386 $")
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 ret = ASN1_STRING_to_UTF8(&str2, str);
00642 if (ret < 0) {
00643 continue;
00644 }
00645
00646 if (str2) {
00647 if (strlen((char *) str2) != ret) {
00648 ast_log(LOG_WARNING, "Invalid certificate common name length (contains NULL bytes?)\n");
00649 } else if (!strcasecmp(tcptls_session->parent->hostname, (char *) str2)) {
00650 found = 1;
00651 }
00652 ast_debug(3, "SSL Common Name compare s1='%s' s2='%s'\n", tcptls_session->parent->hostname, str2);
00653 OPENSSL_free(str2);
00654 }
00655 if (found)
00656 break;
00657 }
00658 if (!found) {
00659 ast_log(LOG_ERROR, "Certificate common name did not match (%s)\n", tcptls_session->parent->hostname);
00660 X509_free(peer);
00661 ast_tcptls_close_session_file(tcptls_session);
00662 ao2_ref(tcptls_session, -1);
00663 return NULL;
00664 }
00665 }
00666 X509_free(peer);
00667 }
00668 }
00669 if (!tcptls_session->f)
00670 SSL_free(tcptls_session->ssl);
00671 }
00672 #endif
00673
00674 if (!tcptls_session->f) {
00675 ast_tcptls_close_session_file(tcptls_session);
00676 ast_log(LOG_WARNING, "FILE * open failed!\n");
00677 #ifndef DO_SSL
00678 if (tcptls_session->parent->tls_cfg) {
00679 ast_log(LOG_WARNING, "Attempted a TLS connection without OpenSSL support. This will not work!\n");
00680 }
00681 #endif
00682 ao2_ref(tcptls_session, -1);
00683 return NULL;
00684 }
00685
00686 if (tcptls_session->parent->worker_fn) {
00687 return tcptls_session->parent->worker_fn(tcptls_session);
00688 } else {
00689 return tcptls_session;
00690 }
00691 }
00692
00693 void *ast_tcptls_server_root(void *data)
00694 {
00695 struct ast_tcptls_session_args *desc = data;
00696 int fd;
00697 struct ast_sockaddr addr;
00698 struct ast_tcptls_session_instance *tcptls_session;
00699 pthread_t launched;
00700
00701 for (;;) {
00702 int i, flags;
00703
00704 if (desc->periodic_fn)
00705 desc->periodic_fn(desc);
00706 i = ast_wait_for_input(desc->accept_fd, desc->poll_timeout);
00707 if (i <= 0)
00708 continue;
00709 fd = ast_accept(desc->accept_fd, &addr);
00710 if (fd < 0) {
00711 if ((errno != EAGAIN) && (errno != EINTR))
00712 ast_log(LOG_WARNING, "Accept failed: %s\n", strerror(errno));
00713 continue;
00714 }
00715 tcptls_session = ao2_alloc(sizeof(*tcptls_session), session_instance_destructor);
00716 if (!tcptls_session) {
00717 ast_log(LOG_WARNING, "No memory for new session: %s\n", strerror(errno));
00718 if (close(fd)) {
00719 ast_log(LOG_ERROR, "close() failed: %s\n", strerror(errno));
00720 }
00721 continue;
00722 }
00723
00724 ast_mutex_init(&tcptls_session->lock);
00725 tcptls_session->overflow_buf = ast_str_create(128);
00726
00727 flags = fcntl(fd, F_GETFL);
00728 fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
00729 tcptls_session->fd = fd;
00730 tcptls_session->parent = desc;
00731 ast_sockaddr_copy(&tcptls_session->remote_address, &addr);
00732
00733 tcptls_session->client = 0;
00734
00735
00736 if (ast_pthread_create_detached_background(&launched, NULL, handle_tcptls_connection, tcptls_session)) {
00737 ast_log(LOG_WARNING, "Unable to launch helper thread: %s\n", strerror(errno));
00738 ast_tcptls_close_session_file(tcptls_session);
00739 ao2_ref(tcptls_session, -1);
00740 }
00741 }
00742 return NULL;
00743 }
00744
00745 static int __ssl_setup(struct ast_tls_config *cfg, int client)
00746 {
00747 #ifndef DO_SSL
00748 cfg->enabled = 0;
00749 return 0;
00750 #else
00751 int disable_ssl = 0;
00752
00753 if (!cfg->enabled)
00754 return 0;
00755
00756
00757
00758
00759 if (cfg->ssl_ctx) {
00760 SSL_CTX_free(cfg->ssl_ctx);
00761 cfg->ssl_ctx = NULL;
00762 }
00763
00764 if (client) {
00765 #ifndef OPENSSL_NO_SSL2
00766 if (ast_test_flag(&cfg->flags, AST_SSL_SSLV2_CLIENT)) {
00767 ast_log(LOG_WARNING, "Usage of SSLv2 is discouraged due to known vulnerabilities. Please use 'tlsv1' or leave the TLS method unspecified!\n");
00768 cfg->ssl_ctx = SSL_CTX_new(SSLv2_client_method());
00769 } else
00770 #endif
00771 if (ast_test_flag(&cfg->flags, AST_SSL_SSLV3_CLIENT)) {
00772 ast_log(LOG_WARNING, "Usage of SSLv3 is discouraged due to known vulnerabilities. Please use 'tlsv1' or leave the TLS method unspecified!\n");
00773 cfg->ssl_ctx = SSL_CTX_new(SSLv3_client_method());
00774 } else if (ast_test_flag(&cfg->flags, AST_SSL_TLSV1_CLIENT)) {
00775 cfg->ssl_ctx = SSL_CTX_new(TLSv1_client_method());
00776 } else {
00777 disable_ssl = 1;
00778 cfg->ssl_ctx = SSL_CTX_new(SSLv23_client_method());
00779 }
00780 } else {
00781 disable_ssl = 1;
00782 cfg->ssl_ctx = SSL_CTX_new(SSLv23_server_method());
00783 }
00784
00785 if (!cfg->ssl_ctx) {
00786 ast_debug(1, "Sorry, SSL_CTX_new call returned null...\n");
00787 cfg->enabled = 0;
00788 return 0;
00789 }
00790
00791
00792
00793
00794
00795 if (disable_ssl) {
00796 long ssl_opts;
00797
00798 ssl_opts = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3;
00799 SSL_CTX_set_options(cfg->ssl_ctx, ssl_opts);
00800 }
00801
00802 SSL_CTX_set_verify(cfg->ssl_ctx,
00803 ast_test_flag(&cfg->flags, AST_SSL_VERIFY_CLIENT) ? SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT : SSL_VERIFY_NONE,
00804 NULL);
00805
00806 if (!ast_strlen_zero(cfg->certfile)) {
00807 char *tmpprivate = ast_strlen_zero(cfg->pvtfile) ? cfg->certfile : cfg->pvtfile;
00808 if (SSL_CTX_use_certificate_chain_file(cfg->ssl_ctx, cfg->certfile) == 0) {
00809 if (!client) {
00810
00811 ast_verb(0, "SSL error loading cert file. <%s>", cfg->certfile);
00812 cfg->enabled = 0;
00813 SSL_CTX_free(cfg->ssl_ctx);
00814 cfg->ssl_ctx = NULL;
00815 return 0;
00816 }
00817 }
00818 if ((SSL_CTX_use_PrivateKey_file(cfg->ssl_ctx, tmpprivate, SSL_FILETYPE_PEM) == 0) || (SSL_CTX_check_private_key(cfg->ssl_ctx) == 0 )) {
00819 if (!client) {
00820
00821 ast_verb(0, "SSL error loading private key file. <%s>", tmpprivate);
00822 cfg->enabled = 0;
00823 SSL_CTX_free(cfg->ssl_ctx);
00824 cfg->ssl_ctx = NULL;
00825 return 0;
00826 }
00827 }
00828 }
00829 if (!ast_strlen_zero(cfg->cipher)) {
00830 if (SSL_CTX_set_cipher_list(cfg->ssl_ctx, cfg->cipher) == 0 ) {
00831 if (!client) {
00832 ast_verb(0, "SSL cipher error <%s>", cfg->cipher);
00833 cfg->enabled = 0;
00834 SSL_CTX_free(cfg->ssl_ctx);
00835 cfg->ssl_ctx = NULL;
00836 return 0;
00837 }
00838 }
00839 }
00840 if (!ast_strlen_zero(cfg->cafile) || !ast_strlen_zero(cfg->capath)) {
00841 if (SSL_CTX_load_verify_locations(cfg->ssl_ctx, S_OR(cfg->cafile, NULL), S_OR(cfg->capath,NULL)) == 0)
00842 ast_verb(0, "SSL CA file(%s)/path(%s) error\n", cfg->cafile, cfg->capath);
00843 }
00844
00845 ast_verb(0, "SSL certificate ok\n");
00846 return 1;
00847 #endif
00848 }
00849
00850 int ast_ssl_setup(struct ast_tls_config *cfg)
00851 {
00852 return __ssl_setup(cfg, 0);
00853 }
00854
00855 void ast_ssl_teardown(struct ast_tls_config *cfg)
00856 {
00857 #ifdef DO_SSL
00858 if (cfg->ssl_ctx) {
00859 SSL_CTX_free(cfg->ssl_ctx);
00860 cfg->ssl_ctx = NULL;
00861 }
00862 #endif
00863 }
00864
00865 struct ast_tcptls_session_instance *ast_tcptls_client_start(struct ast_tcptls_session_instance *tcptls_session)
00866 {
00867 struct ast_tcptls_session_args *desc;
00868 int flags;
00869
00870 if (!(desc = tcptls_session->parent)) {
00871 goto client_start_error;
00872 }
00873
00874 if (ast_connect(desc->accept_fd, &desc->remote_address)) {
00875 ast_log(LOG_ERROR, "Unable to connect %s to %s: %s\n",
00876 desc->name,
00877 ast_sockaddr_stringify(&desc->remote_address),
00878 strerror(errno));
00879 goto client_start_error;
00880 }
00881
00882 flags = fcntl(desc->accept_fd, F_GETFL);
00883 fcntl(desc->accept_fd, F_SETFL, flags & ~O_NONBLOCK);
00884
00885 if (desc->tls_cfg) {
00886 desc->tls_cfg->enabled = 1;
00887 __ssl_setup(desc->tls_cfg, 1);
00888 }
00889
00890 return handle_tcptls_connection(tcptls_session);
00891
00892 client_start_error:
00893 if (desc) {
00894 close(desc->accept_fd);
00895 desc->accept_fd = -1;
00896 }
00897 ao2_ref(tcptls_session, -1);
00898 return NULL;
00899
00900 }
00901
00902 struct ast_tcptls_session_instance *ast_tcptls_client_create(struct ast_tcptls_session_args *desc)
00903 {
00904 int x = 1;
00905 struct ast_tcptls_session_instance *tcptls_session = NULL;
00906
00907
00908 if (!ast_sockaddr_cmp(&desc->old_address, &desc->remote_address)) {
00909 ast_debug(1, "Nothing changed in %s\n", desc->name);
00910 return NULL;
00911 }
00912
00913
00914 ast_sockaddr_setnull(&desc->old_address);
00915
00916 if (desc->accept_fd != -1)
00917 close(desc->accept_fd);
00918
00919 desc->accept_fd = socket(ast_sockaddr_is_ipv6(&desc->remote_address) ?
00920 AF_INET6 : AF_INET, SOCK_STREAM, IPPROTO_TCP);
00921 if (desc->accept_fd < 0) {
00922 ast_log(LOG_WARNING, "Unable to allocate socket for %s: %s\n",
00923 desc->name, strerror(errno));
00924 return NULL;
00925 }
00926
00927
00928
00929 if (!ast_sockaddr_isnull(&desc->local_address)) {
00930 setsockopt(desc->accept_fd, SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x));
00931 if (ast_bind(desc->accept_fd, &desc->local_address)) {
00932 ast_log(LOG_ERROR, "Unable to bind %s to %s: %s\n",
00933 desc->name,
00934 ast_sockaddr_stringify(&desc->local_address),
00935 strerror(errno));
00936 goto error;
00937 }
00938 }
00939
00940 if (!(tcptls_session = ao2_alloc(sizeof(*tcptls_session), session_instance_destructor)))
00941 goto error;
00942
00943 ast_mutex_init(&tcptls_session->lock);
00944 tcptls_session->overflow_buf = ast_str_create(128);
00945 tcptls_session->client = 1;
00946 tcptls_session->fd = desc->accept_fd;
00947 tcptls_session->parent = desc;
00948 tcptls_session->parent->worker_fn = NULL;
00949 ast_sockaddr_copy(&tcptls_session->remote_address,
00950 &desc->remote_address);
00951
00952
00953 ast_sockaddr_copy(&desc->old_address, &desc->remote_address);
00954 return tcptls_session;
00955
00956 error:
00957 close(desc->accept_fd);
00958 desc->accept_fd = -1;
00959 if (tcptls_session)
00960 ao2_ref(tcptls_session, -1);
00961 return NULL;
00962 }
00963
00964 void ast_tcptls_server_start(struct ast_tcptls_session_args *desc)
00965 {
00966 int flags;
00967 int x = 1;
00968
00969
00970 if (!ast_sockaddr_cmp(&desc->old_address, &desc->local_address)) {
00971 ast_debug(1, "Nothing changed in %s\n", desc->name);
00972 return;
00973 }
00974
00975
00976 ast_sockaddr_setnull(&desc->old_address);
00977
00978
00979 if (desc->master != AST_PTHREADT_NULL) {
00980 pthread_cancel(desc->master);
00981 pthread_kill(desc->master, SIGURG);
00982 pthread_join(desc->master, NULL);
00983 }
00984
00985 if (desc->accept_fd != -1)
00986 close(desc->accept_fd);
00987
00988
00989 if (ast_sockaddr_isnull(&desc->local_address)) {
00990 ast_debug(2, "Server disabled: %s\n", desc->name);
00991 return;
00992 }
00993
00994 desc->accept_fd = socket(ast_sockaddr_is_ipv6(&desc->local_address) ?
00995 AF_INET6 : AF_INET, SOCK_STREAM, 0);
00996 if (desc->accept_fd < 0) {
00997 ast_log(LOG_ERROR, "Unable to allocate socket for %s: %s\n", desc->name, strerror(errno));
00998 return;
00999 }
01000
01001 setsockopt(desc->accept_fd, SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x));
01002 if (ast_bind(desc->accept_fd, &desc->local_address)) {
01003 ast_log(LOG_ERROR, "Unable to bind %s to %s: %s\n",
01004 desc->name,
01005 ast_sockaddr_stringify(&desc->local_address),
01006 strerror(errno));
01007 goto error;
01008 }
01009 if (listen(desc->accept_fd, 10)) {
01010 ast_log(LOG_ERROR, "Unable to listen for %s!\n", desc->name);
01011 goto error;
01012 }
01013 flags = fcntl(desc->accept_fd, F_GETFL);
01014 fcntl(desc->accept_fd, F_SETFL, flags | O_NONBLOCK);
01015 if (ast_pthread_create_background(&desc->master, NULL, desc->accept_fn, desc)) {
01016 ast_log(LOG_ERROR, "Unable to launch thread for %s on %s: %s\n",
01017 desc->name,
01018 ast_sockaddr_stringify(&desc->local_address),
01019 strerror(errno));
01020 goto error;
01021 }
01022
01023
01024 ast_sockaddr_copy(&desc->old_address, &desc->local_address);
01025
01026 return;
01027
01028 error:
01029 close(desc->accept_fd);
01030 desc->accept_fd = -1;
01031 }
01032
01033 void ast_tcptls_close_session_file(struct ast_tcptls_session_instance *tcptls_session)
01034 {
01035 if (tcptls_session->f) {
01036 fflush(tcptls_session->f);
01037 if (fclose(tcptls_session->f)) {
01038 ast_log(LOG_ERROR, "fclose() failed: %s\n", strerror(errno));
01039 }
01040 tcptls_session->f = NULL;
01041 tcptls_session->fd = -1;
01042 } else if (tcptls_session->fd != -1) {
01043
01044
01045
01046
01047
01048 shutdown(tcptls_session->fd, SHUT_RDWR);
01049 if (close(tcptls_session->fd)) {
01050 ast_log(LOG_ERROR, "close() failed: %s\n", strerror(errno));
01051 }
01052 tcptls_session->fd = -1;
01053 } else {
01054 ast_log(LOG_ERROR, "ast_tcptls_close_session_file invoked on session instance without file or file descriptor\n");
01055 }
01056 }
01057
01058 void ast_tcptls_server_stop(struct ast_tcptls_session_args *desc)
01059 {
01060 if (desc->master != AST_PTHREADT_NULL) {
01061 pthread_cancel(desc->master);
01062 pthread_kill(desc->master, SIGURG);
01063 pthread_join(desc->master, NULL);
01064 desc->master = AST_PTHREADT_NULL;
01065 }
01066 if (desc->accept_fd != -1)
01067 close(desc->accept_fd);
01068 desc->accept_fd = -1;
01069 ast_debug(2, "Stopped server :: %s\n", desc->name);
01070 }
01071
01072 int ast_tls_read_conf(struct ast_tls_config *tls_cfg, struct ast_tcptls_session_args *tls_desc, const char *varname, const char *value)
01073 {
01074 if (!strcasecmp(varname, "tlsenable") || !strcasecmp(varname, "sslenable")) {
01075 tls_cfg->enabled = ast_true(value) ? 1 : 0;
01076 } else if (!strcasecmp(varname, "tlscertfile") || !strcasecmp(varname, "sslcert") || !strcasecmp(varname, "tlscert")) {
01077 ast_free(tls_cfg->certfile);
01078 tls_cfg->certfile = ast_strdup(value);
01079 } else if (!strcasecmp(varname, "tlsprivatekey") || !strcasecmp(varname, "sslprivatekey")) {
01080 ast_free(tls_cfg->pvtfile);
01081 tls_cfg->pvtfile = ast_strdup(value);
01082 } else if (!strcasecmp(varname, "tlscipher") || !strcasecmp(varname, "sslcipher")) {
01083 ast_free(tls_cfg->cipher);
01084 tls_cfg->cipher = ast_strdup(value);
01085 } else if (!strcasecmp(varname, "tlscafile")) {
01086 ast_free(tls_cfg->cafile);
01087 tls_cfg->cafile = ast_strdup(value);
01088 } else if (!strcasecmp(varname, "tlscapath") || !strcasecmp(varname, "tlscadir")) {
01089 ast_free(tls_cfg->capath);
01090 tls_cfg->capath = ast_strdup(value);
01091 } else if (!strcasecmp(varname, "tlsverifyclient")) {
01092 ast_set2_flag(&tls_cfg->flags, ast_true(value), AST_SSL_VERIFY_CLIENT);
01093 } else if (!strcasecmp(varname, "tlsdontverifyserver")) {
01094 ast_set2_flag(&tls_cfg->flags, ast_true(value), AST_SSL_DONT_VERIFY_SERVER);
01095 } else if (!strcasecmp(varname, "tlsbindaddr") || !strcasecmp(varname, "sslbindaddr")) {
01096 if (ast_parse_arg(value, PARSE_ADDR, &tls_desc->local_address))
01097 ast_log(LOG_WARNING, "Invalid %s '%s'\n", varname, value);
01098 } else if (!strcasecmp(varname, "tlsclientmethod") || !strcasecmp(varname, "sslclientmethod")) {
01099 if (!strcasecmp(value, "tlsv1")) {
01100 ast_set_flag(&tls_cfg->flags, AST_SSL_TLSV1_CLIENT);
01101 ast_clear_flag(&tls_cfg->flags, AST_SSL_SSLV3_CLIENT);
01102 ast_clear_flag(&tls_cfg->flags, AST_SSL_SSLV2_CLIENT);
01103 } else if (!strcasecmp(value, "sslv3")) {
01104 ast_set_flag(&tls_cfg->flags, AST_SSL_SSLV3_CLIENT);
01105 ast_clear_flag(&tls_cfg->flags, AST_SSL_SSLV2_CLIENT);
01106 ast_clear_flag(&tls_cfg->flags, AST_SSL_TLSV1_CLIENT);
01107 } else if (!strcasecmp(value, "sslv2")) {
01108 ast_set_flag(&tls_cfg->flags, AST_SSL_SSLV2_CLIENT);
01109 ast_clear_flag(&tls_cfg->flags, AST_SSL_TLSV1_CLIENT);
01110 ast_clear_flag(&tls_cfg->flags, AST_SSL_SSLV3_CLIENT);
01111 }
01112 } else {
01113 return -1;
01114 }
01115
01116 return 0;
01117 }