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