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: 411463 $")
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
00055
00056
00057
00058
00059 #ifdef DO_SSL
00060 static HOOK_T ssl_read(void *cookie, char *buf, LEN_T len)
00061 {
00062 int i = SSL_read(cookie, buf, len-1);
00063 #if 0
00064 if (i >= 0) {
00065 buf[i] = '\0';
00066 }
00067 ast_verb(0, "ssl read size %d returns %d <%s>\n", (int)len, i, buf);
00068 #endif
00069 return i;
00070 }
00071
00072 static HOOK_T ssl_write(void *cookie, const char *buf, LEN_T len)
00073 {
00074 #if 0
00075 char *s = ast_alloca(len+1);
00076
00077 strncpy(s, buf, len);
00078 s[len] = '\0';
00079 ast_verb(0, "ssl write size %d <%s>\n", (int)len, s);
00080 #endif
00081 return SSL_write(cookie, buf, len);
00082 }
00083
00084 static int ssl_close(void *cookie)
00085 {
00086 int cookie_fd = SSL_get_fd(cookie);
00087 int ret;
00088
00089 if (cookie_fd > -1) {
00090
00091
00092
00093
00094
00095 if ((ret = SSL_shutdown(cookie)) < 0) {
00096 ast_log(LOG_ERROR, "SSL_shutdown() failed: %d\n", SSL_get_error(cookie, ret));
00097 }
00098
00099 if (!((SSL*)cookie)->server) {
00100
00101 ERR_remove_state(0);
00102 }
00103
00104 SSL_free(cookie);
00105
00106 if (close(cookie_fd)) {
00107 ast_log(LOG_ERROR, "close() failed: %s\n", strerror(errno));
00108 }
00109 }
00110 return 0;
00111 }
00112 #endif
00113
00114 HOOK_T ast_tcptls_server_read(struct ast_tcptls_session_instance *tcptls_session, void *buf, size_t count)
00115 {
00116 if (tcptls_session->fd == -1) {
00117 ast_log(LOG_ERROR, "server_read called with an fd of -1\n");
00118 errno = EIO;
00119 return -1;
00120 }
00121
00122 #ifdef DO_SSL
00123 if (tcptls_session->ssl) {
00124 return ssl_read(tcptls_session->ssl, buf, count);
00125 }
00126 #endif
00127 return read(tcptls_session->fd, buf, count);
00128 }
00129
00130 HOOK_T ast_tcptls_server_write(struct ast_tcptls_session_instance *tcptls_session, const void *buf, size_t count)
00131 {
00132 if (tcptls_session->fd == -1) {
00133 ast_log(LOG_ERROR, "server_write called with an fd of -1\n");
00134 errno = EIO;
00135 return -1;
00136 }
00137
00138 #ifdef DO_SSL
00139 if (tcptls_session->ssl) {
00140 return ssl_write(tcptls_session->ssl, buf, count);
00141 }
00142 #endif
00143 return write(tcptls_session->fd, buf, count);
00144 }
00145
00146 static void session_instance_destructor(void *obj)
00147 {
00148 struct ast_tcptls_session_instance *i = obj;
00149 ast_free(i->overflow_buf);
00150 }
00151
00152
00153
00154
00155
00156
00157
00158
00159 static void *handle_tcptls_connection(void *data)
00160 {
00161 struct ast_tcptls_session_instance *tcptls_session = data;
00162 #ifdef DO_SSL
00163 int (*ssl_setup)(SSL *) = (tcptls_session->client) ? SSL_connect : SSL_accept;
00164 int ret;
00165 char err[256];
00166 #endif
00167
00168
00169
00170
00171
00172
00173 if (ast_thread_inhibit_escalations()) {
00174 ast_log(LOG_ERROR, "Failed to inhibit privilege escalations; killing connection\n");
00175 ast_tcptls_close_session_file(tcptls_session);
00176 ao2_ref(tcptls_session, -1);
00177 return NULL;
00178 }
00179
00180
00181
00182
00183 if (!tcptls_session->parent->tls_cfg) {
00184 if ((tcptls_session->f = fdopen(tcptls_session->fd, "w+"))) {
00185 if(setvbuf(tcptls_session->f, NULL, _IONBF, 0)) {
00186 ast_tcptls_close_session_file(tcptls_session);
00187 }
00188 }
00189 }
00190 #ifdef DO_SSL
00191 else if ( (tcptls_session->ssl = SSL_new(tcptls_session->parent->tls_cfg->ssl_ctx)) ) {
00192 SSL_set_fd(tcptls_session->ssl, tcptls_session->fd);
00193 if ((ret = ssl_setup(tcptls_session->ssl)) <= 0) {
00194 ast_verb(2, "Problem setting up ssl connection: %s\n", ERR_error_string(ERR_get_error(), err));
00195 } else {
00196 #if defined(HAVE_FUNOPEN)
00197 tcptls_session->f = funopen(tcptls_session->ssl, ssl_read, ssl_write, NULL, ssl_close);
00198
00199 #elif defined(HAVE_FOPENCOOKIE)
00200 static const cookie_io_functions_t cookie_funcs = {
00201 ssl_read, ssl_write, NULL, ssl_close
00202 };
00203 tcptls_session->f = fopencookie(tcptls_session->ssl, "w+", cookie_funcs);
00204 #else
00205
00206 ast_debug(2, "no tcptls_session->f methods attempted!\n");
00207 #endif
00208 if ((tcptls_session->client && !ast_test_flag(&tcptls_session->parent->tls_cfg->flags, AST_SSL_DONT_VERIFY_SERVER))
00209 || (!tcptls_session->client && ast_test_flag(&tcptls_session->parent->tls_cfg->flags, AST_SSL_VERIFY_CLIENT))) {
00210 X509 *peer;
00211 long res;
00212 peer = SSL_get_peer_certificate(tcptls_session->ssl);
00213 if (!peer) {
00214 ast_log(LOG_ERROR, "No peer SSL certificate to verify\n");
00215 ast_tcptls_close_session_file(tcptls_session);
00216 ao2_ref(tcptls_session, -1);
00217 return NULL;
00218 }
00219
00220 res = SSL_get_verify_result(tcptls_session->ssl);
00221 if (res != X509_V_OK) {
00222 ast_log(LOG_ERROR, "Certificate did not verify: %s\n", X509_verify_cert_error_string(res));
00223 X509_free(peer);
00224 ast_tcptls_close_session_file(tcptls_session);
00225 ao2_ref(tcptls_session, -1);
00226 return NULL;
00227 }
00228 if (!ast_test_flag(&tcptls_session->parent->tls_cfg->flags, AST_SSL_IGNORE_COMMON_NAME)) {
00229 ASN1_STRING *str;
00230 unsigned char *str2;
00231 X509_NAME *name = X509_get_subject_name(peer);
00232 int pos = -1;
00233 int found = 0;
00234
00235 for (;;) {
00236
00237
00238 pos = X509_NAME_get_index_by_NID(name, NID_commonName, pos);
00239 if (pos < 0) {
00240 break;
00241 }
00242 str = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name, pos));
00243 ASN1_STRING_to_UTF8(&str2, str);
00244 if (str2) {
00245 if (!strcasecmp(tcptls_session->parent->hostname, (char *) str2)) {
00246 found = 1;
00247 }
00248 ast_debug(3, "SSL Common Name compare s1='%s' s2='%s'\n", tcptls_session->parent->hostname, str2);
00249 OPENSSL_free(str2);
00250 }
00251 if (found) {
00252 break;
00253 }
00254 }
00255 if (!found) {
00256 ast_log(LOG_ERROR, "Certificate common name did not match (%s)\n", tcptls_session->parent->hostname);
00257 X509_free(peer);
00258 ast_tcptls_close_session_file(tcptls_session);
00259 ao2_ref(tcptls_session, -1);
00260 return NULL;
00261 }
00262 }
00263 X509_free(peer);
00264 }
00265 }
00266 if (!tcptls_session->f) {
00267 SSL_free(tcptls_session->ssl);
00268 }
00269 }
00270 #endif
00271
00272 if (!tcptls_session->f) {
00273 ast_tcptls_close_session_file(tcptls_session);
00274 ast_log(LOG_WARNING, "FILE * open failed!\n");
00275 #ifndef DO_SSL
00276 if (tcptls_session->parent->tls_cfg) {
00277 ast_log(LOG_WARNING, "Attempted a TLS connection without OpenSSL support. This will not work!\n");
00278 }
00279 #endif
00280 ao2_ref(tcptls_session, -1);
00281 return NULL;
00282 }
00283
00284 if (tcptls_session->parent->worker_fn) {
00285 return tcptls_session->parent->worker_fn(tcptls_session);
00286 } else {
00287 return tcptls_session;
00288 }
00289 }
00290
00291 void *ast_tcptls_server_root(void *data)
00292 {
00293 struct ast_tcptls_session_args *desc = data;
00294 int fd;
00295 struct ast_sockaddr addr;
00296 struct ast_tcptls_session_instance *tcptls_session;
00297 pthread_t launched;
00298
00299 for (;;) {
00300 int i, flags;
00301
00302 if (desc->periodic_fn) {
00303 desc->periodic_fn(desc);
00304 }
00305 i = ast_wait_for_input(desc->accept_fd, desc->poll_timeout);
00306 if (i <= 0) {
00307 continue;
00308 }
00309 fd = ast_accept(desc->accept_fd, &addr);
00310 if (fd < 0) {
00311 if ((errno != EAGAIN) && (errno != EINTR)) {
00312 ast_log(LOG_WARNING, "Accept failed: %s\n", strerror(errno));
00313 }
00314 continue;
00315 }
00316 tcptls_session = ao2_alloc(sizeof(*tcptls_session), session_instance_destructor);
00317 if (!tcptls_session) {
00318 ast_log(LOG_WARNING, "No memory for new session: %s\n", strerror(errno));
00319 if (close(fd)) {
00320 ast_log(LOG_ERROR, "close() failed: %s\n", strerror(errno));
00321 }
00322 continue;
00323 }
00324
00325 tcptls_session->overflow_buf = ast_str_create(128);
00326 flags = fcntl(fd, F_GETFL);
00327 fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
00328 tcptls_session->fd = fd;
00329 tcptls_session->parent = desc;
00330 ast_sockaddr_copy(&tcptls_session->remote_address, &addr);
00331
00332 tcptls_session->client = 0;
00333
00334
00335 if (ast_pthread_create_detached_background(&launched, NULL, handle_tcptls_connection, tcptls_session)) {
00336 ast_log(LOG_WARNING, "Unable to launch helper thread: %s\n", strerror(errno));
00337 ast_tcptls_close_session_file(tcptls_session);
00338 ao2_ref(tcptls_session, -1);
00339 }
00340 }
00341 return NULL;
00342 }
00343
00344 static int __ssl_setup(struct ast_tls_config *cfg, int client)
00345 {
00346 #ifndef DO_SSL
00347 cfg->enabled = 0;
00348 return 0;
00349 #else
00350 if (!cfg->enabled) {
00351 return 0;
00352 }
00353
00354
00355
00356
00357 if (cfg->ssl_ctx) {
00358 SSL_CTX_free(cfg->ssl_ctx);
00359 cfg->ssl_ctx = NULL;
00360 }
00361
00362 if (client) {
00363 #ifndef OPENSSL_NO_SSL2
00364 if (ast_test_flag(&cfg->flags, AST_SSL_SSLV2_CLIENT)) {
00365 cfg->ssl_ctx = SSL_CTX_new(SSLv2_client_method());
00366 } else
00367 #endif
00368 if (ast_test_flag(&cfg->flags, AST_SSL_SSLV3_CLIENT)) {
00369 cfg->ssl_ctx = SSL_CTX_new(SSLv3_client_method());
00370 } else if (ast_test_flag(&cfg->flags, AST_SSL_TLSV1_CLIENT)) {
00371 cfg->ssl_ctx = SSL_CTX_new(TLSv1_client_method());
00372 } else {
00373
00374
00375
00376
00377 cfg->ssl_ctx = SSL_CTX_new(SSLv23_client_method());
00378 }
00379 } else {
00380
00381 cfg->ssl_ctx = SSL_CTX_new(SSLv23_server_method());
00382 }
00383
00384 if (!cfg->ssl_ctx) {
00385 ast_debug(1, "Sorry, SSL_CTX_new call returned null...\n");
00386 cfg->enabled = 0;
00387 return 0;
00388 }
00389
00390 SSL_CTX_set_verify(cfg->ssl_ctx,
00391 ast_test_flag(&cfg->flags, AST_SSL_VERIFY_CLIENT) ? SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT : SSL_VERIFY_NONE,
00392 NULL);
00393
00394 if (!ast_strlen_zero(cfg->certfile)) {
00395 char *tmpprivate = ast_strlen_zero(cfg->pvtfile) ? cfg->certfile : cfg->pvtfile;
00396 if (SSL_CTX_use_certificate_chain_file(cfg->ssl_ctx, cfg->certfile) == 0) {
00397 if (!client) {
00398
00399 ast_verb(0, "SSL error loading cert file. <%s>\n", cfg->certfile);
00400 cfg->enabled = 0;
00401 SSL_CTX_free(cfg->ssl_ctx);
00402 cfg->ssl_ctx = NULL;
00403 return 0;
00404 }
00405 }
00406 if ((SSL_CTX_use_PrivateKey_file(cfg->ssl_ctx, tmpprivate, SSL_FILETYPE_PEM) == 0) || (SSL_CTX_check_private_key(cfg->ssl_ctx) == 0 )) {
00407 if (!client) {
00408
00409 ast_verb(0, "SSL error loading private key file. <%s>\n", tmpprivate);
00410 cfg->enabled = 0;
00411 SSL_CTX_free(cfg->ssl_ctx);
00412 cfg->ssl_ctx = NULL;
00413 return 0;
00414 }
00415 }
00416 }
00417 if (!ast_strlen_zero(cfg->cipher)) {
00418 if (SSL_CTX_set_cipher_list(cfg->ssl_ctx, cfg->cipher) == 0 ) {
00419 if (!client) {
00420 ast_verb(0, "SSL cipher error <%s>\n", cfg->cipher);
00421 cfg->enabled = 0;
00422 SSL_CTX_free(cfg->ssl_ctx);
00423 cfg->ssl_ctx = NULL;
00424 return 0;
00425 }
00426 }
00427 }
00428 if (!ast_strlen_zero(cfg->cafile) || !ast_strlen_zero(cfg->capath)) {
00429 if (SSL_CTX_load_verify_locations(cfg->ssl_ctx, S_OR(cfg->cafile, NULL), S_OR(cfg->capath,NULL)) == 0) {
00430 ast_verb(0, "SSL CA file(%s)/path(%s) error\n", cfg->cafile, cfg->capath);
00431 }
00432 }
00433
00434 ast_verb(0, "SSL certificate ok\n");
00435 return 1;
00436 #endif
00437 }
00438
00439 int ast_ssl_setup(struct ast_tls_config *cfg)
00440 {
00441 return __ssl_setup(cfg, 0);
00442 }
00443
00444 void ast_ssl_teardown(struct ast_tls_config *cfg)
00445 {
00446 #ifdef DO_SSL
00447 if (cfg->ssl_ctx) {
00448 SSL_CTX_free(cfg->ssl_ctx);
00449 cfg->ssl_ctx = NULL;
00450 }
00451 #endif
00452 }
00453
00454 struct ast_tcptls_session_instance *ast_tcptls_client_start(struct ast_tcptls_session_instance *tcptls_session)
00455 {
00456 struct ast_tcptls_session_args *desc;
00457 int flags;
00458
00459 if (!(desc = tcptls_session->parent)) {
00460 goto client_start_error;
00461 }
00462
00463 if (ast_connect(desc->accept_fd, &desc->remote_address)) {
00464 ast_log(LOG_ERROR, "Unable to connect %s to %s: %s\n",
00465 desc->name,
00466 ast_sockaddr_stringify(&desc->remote_address),
00467 strerror(errno));
00468 goto client_start_error;
00469 }
00470
00471 flags = fcntl(desc->accept_fd, F_GETFL);
00472 fcntl(desc->accept_fd, F_SETFL, flags & ~O_NONBLOCK);
00473
00474 if (desc->tls_cfg) {
00475 desc->tls_cfg->enabled = 1;
00476 __ssl_setup(desc->tls_cfg, 1);
00477 }
00478
00479 return handle_tcptls_connection(tcptls_session);
00480
00481 client_start_error:
00482 if (desc) {
00483 close(desc->accept_fd);
00484 desc->accept_fd = -1;
00485 }
00486 ao2_ref(tcptls_session, -1);
00487 return NULL;
00488
00489 }
00490
00491 struct ast_tcptls_session_instance *ast_tcptls_client_create(struct ast_tcptls_session_args *desc)
00492 {
00493 int x = 1;
00494 struct ast_tcptls_session_instance *tcptls_session = NULL;
00495
00496
00497 if (!ast_sockaddr_cmp(&desc->old_address, &desc->remote_address)) {
00498 ast_debug(1, "Nothing changed in %s\n", desc->name);
00499 return NULL;
00500 }
00501
00502
00503 ast_sockaddr_setnull(&desc->old_address);
00504
00505 if (desc->accept_fd != -1) {
00506 close(desc->accept_fd);
00507 }
00508
00509 desc->accept_fd = socket(ast_sockaddr_is_ipv6(&desc->remote_address) ?
00510 AF_INET6 : AF_INET, SOCK_STREAM, IPPROTO_TCP);
00511 if (desc->accept_fd < 0) {
00512 ast_log(LOG_WARNING, "Unable to allocate socket for %s: %s\n",
00513 desc->name, strerror(errno));
00514 return NULL;
00515 }
00516
00517
00518
00519 if (!ast_sockaddr_isnull(&desc->local_address)) {
00520 setsockopt(desc->accept_fd, SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x));
00521 if (ast_bind(desc->accept_fd, &desc->local_address)) {
00522 ast_log(LOG_ERROR, "Unable to bind %s to %s: %s\n",
00523 desc->name,
00524 ast_sockaddr_stringify(&desc->local_address),
00525 strerror(errno));
00526 goto error;
00527 }
00528 }
00529
00530 if (!(tcptls_session = ao2_alloc(sizeof(*tcptls_session), session_instance_destructor))) {
00531 goto error;
00532 }
00533
00534 tcptls_session->overflow_buf = ast_str_create(128);
00535 tcptls_session->client = 1;
00536 tcptls_session->fd = desc->accept_fd;
00537 tcptls_session->parent = desc;
00538 tcptls_session->parent->worker_fn = NULL;
00539 ast_sockaddr_copy(&tcptls_session->remote_address,
00540 &desc->remote_address);
00541
00542
00543 ast_sockaddr_copy(&desc->old_address, &desc->remote_address);
00544 return tcptls_session;
00545
00546 error:
00547 close(desc->accept_fd);
00548 desc->accept_fd = -1;
00549 if (tcptls_session) {
00550 ao2_ref(tcptls_session, -1);
00551 }
00552 return NULL;
00553 }
00554
00555 void ast_tcptls_server_start(struct ast_tcptls_session_args *desc)
00556 {
00557 int flags;
00558 int x = 1;
00559
00560
00561 if (!ast_sockaddr_cmp(&desc->old_address, &desc->local_address)) {
00562 ast_debug(1, "Nothing changed in %s\n", desc->name);
00563 return;
00564 }
00565
00566
00567 ast_sockaddr_setnull(&desc->old_address);
00568
00569
00570 if (desc->master != AST_PTHREADT_NULL) {
00571 pthread_cancel(desc->master);
00572 pthread_kill(desc->master, SIGURG);
00573 pthread_join(desc->master, NULL);
00574 }
00575
00576 if (desc->accept_fd != -1) {
00577 close(desc->accept_fd);
00578 }
00579
00580
00581 if (ast_sockaddr_isnull(&desc->local_address)) {
00582 ast_debug(2, "Server disabled: %s\n", desc->name);
00583 return;
00584 }
00585
00586 desc->accept_fd = socket(ast_sockaddr_is_ipv6(&desc->local_address) ?
00587 AF_INET6 : AF_INET, SOCK_STREAM, 0);
00588 if (desc->accept_fd < 0) {
00589 ast_log(LOG_ERROR, "Unable to allocate socket for %s: %s\n", desc->name, strerror(errno));
00590 return;
00591 }
00592
00593 setsockopt(desc->accept_fd, SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x));
00594 if (ast_bind(desc->accept_fd, &desc->local_address)) {
00595 ast_log(LOG_ERROR, "Unable to bind %s to %s: %s\n",
00596 desc->name,
00597 ast_sockaddr_stringify(&desc->local_address),
00598 strerror(errno));
00599 goto error;
00600 }
00601 if (listen(desc->accept_fd, 10)) {
00602 ast_log(LOG_ERROR, "Unable to listen for %s!\n", desc->name);
00603 goto error;
00604 }
00605 flags = fcntl(desc->accept_fd, F_GETFL);
00606 fcntl(desc->accept_fd, F_SETFL, flags | O_NONBLOCK);
00607 if (ast_pthread_create_background(&desc->master, NULL, desc->accept_fn, desc)) {
00608 ast_log(LOG_ERROR, "Unable to launch thread for %s on %s: %s\n",
00609 desc->name,
00610 ast_sockaddr_stringify(&desc->local_address),
00611 strerror(errno));
00612 goto error;
00613 }
00614
00615
00616 ast_sockaddr_copy(&desc->old_address, &desc->local_address);
00617
00618 return;
00619
00620 error:
00621 close(desc->accept_fd);
00622 desc->accept_fd = -1;
00623 }
00624
00625 void ast_tcptls_close_session_file(struct ast_tcptls_session_instance *tcptls_session)
00626 {
00627 if (tcptls_session->f) {
00628
00629
00630
00631
00632
00633 fflush(tcptls_session->f);
00634 if (tcptls_session->fd != -1) {
00635 shutdown(tcptls_session->fd, SHUT_RDWR);
00636 }
00637 if (fclose(tcptls_session->f)) {
00638 ast_log(LOG_ERROR, "fclose() failed: %s\n", strerror(errno));
00639 }
00640 tcptls_session->f = NULL;
00641 tcptls_session->fd = -1;
00642 } else if (tcptls_session->fd != -1) {
00643 shutdown(tcptls_session->fd, SHUT_RDWR);
00644 if (close(tcptls_session->fd)) {
00645 ast_log(LOG_ERROR, "close() failed: %s\n", strerror(errno));
00646 }
00647 tcptls_session->fd = -1;
00648 } else {
00649 ast_log(LOG_ERROR, "ast_tcptls_close_session_file invoked on session instance without file or file descriptor\n");
00650 }
00651 }
00652
00653 void ast_tcptls_server_stop(struct ast_tcptls_session_args *desc)
00654 {
00655 if (desc->master != AST_PTHREADT_NULL) {
00656 pthread_cancel(desc->master);
00657 pthread_kill(desc->master, SIGURG);
00658 pthread_join(desc->master, NULL);
00659 desc->master = AST_PTHREADT_NULL;
00660 }
00661 if (desc->accept_fd != -1) {
00662 close(desc->accept_fd);
00663 }
00664 desc->accept_fd = -1;
00665 ast_debug(2, "Stopped server :: %s\n", desc->name);
00666 }
00667
00668 int ast_tls_read_conf(struct ast_tls_config *tls_cfg, struct ast_tcptls_session_args *tls_desc, const char *varname, const char *value)
00669 {
00670 if (!strcasecmp(varname, "tlsenable") || !strcasecmp(varname, "sslenable")) {
00671 tls_cfg->enabled = ast_true(value) ? 1 : 0;
00672 } else if (!strcasecmp(varname, "tlscertfile") || !strcasecmp(varname, "sslcert") || !strcasecmp(varname, "tlscert")) {
00673 ast_free(tls_cfg->certfile);
00674 tls_cfg->certfile = ast_strdup(value);
00675 } else if (!strcasecmp(varname, "tlsprivatekey") || !strcasecmp(varname, "sslprivatekey")) {
00676 ast_free(tls_cfg->pvtfile);
00677 tls_cfg->pvtfile = ast_strdup(value);
00678 } else if (!strcasecmp(varname, "tlscipher") || !strcasecmp(varname, "sslcipher")) {
00679 ast_free(tls_cfg->cipher);
00680 tls_cfg->cipher = ast_strdup(value);
00681 } else if (!strcasecmp(varname, "tlscafile")) {
00682 ast_free(tls_cfg->cafile);
00683 tls_cfg->cafile = ast_strdup(value);
00684 } else if (!strcasecmp(varname, "tlscapath") || !strcasecmp(varname, "tlscadir")) {
00685 ast_free(tls_cfg->capath);
00686 tls_cfg->capath = ast_strdup(value);
00687 } else if (!strcasecmp(varname, "tlsverifyclient")) {
00688 ast_set2_flag(&tls_cfg->flags, ast_true(value), AST_SSL_VERIFY_CLIENT);
00689 } else if (!strcasecmp(varname, "tlsdontverifyserver")) {
00690 ast_set2_flag(&tls_cfg->flags, ast_true(value), AST_SSL_DONT_VERIFY_SERVER);
00691 } else if (!strcasecmp(varname, "tlsbindaddr") || !strcasecmp(varname, "sslbindaddr")) {
00692 if (ast_parse_arg(value, PARSE_ADDR, &tls_desc->local_address))
00693 ast_log(LOG_WARNING, "Invalid %s '%s'\n", varname, value);
00694 } else if (!strcasecmp(varname, "tlsclientmethod") || !strcasecmp(varname, "sslclientmethod")) {
00695 if (!strcasecmp(value, "tlsv1")) {
00696 ast_set_flag(&tls_cfg->flags, AST_SSL_TLSV1_CLIENT);
00697 ast_clear_flag(&tls_cfg->flags, AST_SSL_SSLV3_CLIENT);
00698 ast_clear_flag(&tls_cfg->flags, AST_SSL_SSLV2_CLIENT);
00699 } else if (!strcasecmp(value, "sslv3")) {
00700 ast_set_flag(&tls_cfg->flags, AST_SSL_SSLV3_CLIENT);
00701 ast_clear_flag(&tls_cfg->flags, AST_SSL_SSLV2_CLIENT);
00702 ast_clear_flag(&tls_cfg->flags, AST_SSL_TLSV1_CLIENT);
00703 } else if (!strcasecmp(value, "sslv2")) {
00704 ast_set_flag(&tls_cfg->flags, AST_SSL_SSLV2_CLIENT);
00705 ast_clear_flag(&tls_cfg->flags, AST_SSL_TLSV1_CLIENT);
00706 ast_clear_flag(&tls_cfg->flags, AST_SSL_SSLV3_CLIENT);
00707 }
00708 } else {
00709 return -1;
00710 }
00711
00712 return 0;
00713 }