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