Fri Feb 10 06:37:37 2012

Asterisk developer's documentation


tcptls.h File Reference

Generic support for tcp/tls servers in Asterisk. More...

#include "asterisk/netsock2.h"
#include "asterisk/utils.h"

Include dependency graph for tcptls.h:

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  ast_tcptls_session_args
 arguments for the accepting thread More...
struct  ast_tcptls_session_instance
 describes a server instance More...
struct  ast_tls_config
struct  SSL
struct  SSL_CTX

Defines

#define AST_CERTFILE   "asterisk.pem"
#define HOOK_T   ssize_t
#define LEN_T   size_t

Enumerations

enum  ast_ssl_flags {
  AST_SSL_VERIFY_CLIENT = (1 << 0), AST_SSL_DONT_VERIFY_SERVER = (1 << 1), AST_SSL_IGNORE_COMMON_NAME = (1 << 2), AST_SSL_SSLV2_CLIENT = (1 << 3),
  AST_SSL_SSLV3_CLIENT = (1 << 4), AST_SSL_TLSV1_CLIENT = (1 << 5)
}

Functions

int ast_ssl_setup (struct ast_tls_config *cfg)
struct
ast_tcptls_session_instance
ast_tcptls_client_create (struct ast_tcptls_session_args *desc)
struct
ast_tcptls_session_instance
ast_tcptls_client_start (struct ast_tcptls_session_instance *tcptls_session)
 attempts to connect and start tcptls session, on error the tcptls_session's ref count is decremented, fd and file are closed, and NULL is returned.
void ast_tcptls_close_session_file (struct ast_tcptls_session_instance *tcptls_session)
 Closes a tcptls session instance's file and/or file descriptor. The tcptls_session will be set to NULL and it's file descriptor will be set to -1 by this function.
HOOK_T ast_tcptls_server_read (struct ast_tcptls_session_instance *ser, void *buf, size_t count)
 replacement read/write functions for SSL support. We use wrappers rather than SSL_read/SSL_write directly so we can put in some debugging.
void * ast_tcptls_server_root (void *)
void ast_tcptls_server_start (struct ast_tcptls_session_args *desc)
 This is a generic (re)start routine for a TCP server, which does the socket/bind/listen and starts a thread for handling accept().
void ast_tcptls_server_stop (struct ast_tcptls_session_args *desc)
 Shutdown a running server if there is one.
HOOK_T ast_tcptls_server_write (struct ast_tcptls_session_instance *ser, const void *buf, size_t count)
int ast_tls_read_conf (struct ast_tls_config *tls_cfg, struct ast_tcptls_session_args *tls_desc, const char *varname, const char *value)
 Used to parse conf files containing tls/ssl options.


Detailed Description

Generic support for tcp/tls servers in Asterisk.

Note:
In order to have TLS/SSL support, we need the openssl libraries. Still we can decide whether or not to use them by commenting in or out the DO_SSL macro.
TLS/SSL support is basically implemented by reading from a config file (currently manager.conf, http.conf and sip.conf) the names of the certificate files and cipher to use, and then run ssl_setup() to create an appropriate data structure named ssl_ctx.

If we support multiple domains, presumably we need to read multiple certificates.

When we are requested to open a TLS socket, we run make_file_from_fd() on the socket, to do the necessary setup. At the moment the context's name is hardwired in the function, but we can certainly make it into an extra parameter to the function.

We declare most of ssl support variables unconditionally, because their number is small and this simplifies the code.

Note:
The ssl-support variables (ssl_ctx, do_ssl, certfile, cipher) and their setup should be moved to a more central place, e.g. asterisk.conf and the source files that processes it. Similarly, ssl_setup() should be run earlier in the startup process so modules have it available.
TLS Implementation Overview

Todo:
For SIP, the SubjectAltNames should be checked on verification of the certificate. (Check RFC 5922)

Definition in file tcptls.h.


Define Documentation

#define AST_CERTFILE   "asterisk.pem"

SSL support

Definition at line 75 of file tcptls.h.

Referenced by __ast_http_load(), __init_manager(), and reload_config().

#define HOOK_T   ssize_t

Definition at line 164 of file tcptls.h.

#define LEN_T   size_t

Definition at line 165 of file tcptls.h.


Enumeration Type Documentation

Enumerator:
AST_SSL_VERIFY_CLIENT  Verify certificate when acting as server
AST_SSL_DONT_VERIFY_SERVER  Don't verify certificate when connecting to a server
AST_SSL_IGNORE_COMMON_NAME  Don't compare "Common Name" against IP or hostname
AST_SSL_SSLV2_CLIENT  Use SSLv2 for outgoing client connections
AST_SSL_SSLV3_CLIENT  Use SSLv3 for outgoing client connections
AST_SSL_TLSV1_CLIENT  Use TLSv1 for outgoing client connections

Definition at line 77 of file tcptls.h.

00077                    {
00078    /*! Verify certificate when acting as server */
00079    AST_SSL_VERIFY_CLIENT = (1 << 0),
00080    /*! Don't verify certificate when connecting to a server */
00081    AST_SSL_DONT_VERIFY_SERVER = (1 << 1),
00082    /*! Don't compare "Common Name" against IP or hostname */
00083    AST_SSL_IGNORE_COMMON_NAME = (1 << 2),
00084    /*! Use SSLv2 for outgoing client connections */
00085    AST_SSL_SSLV2_CLIENT = (1 << 3),
00086    /*! Use SSLv3 for outgoing client connections */
00087    AST_SSL_SSLV3_CLIENT = (1 << 4),
00088    /*! Use TLSv1 for outgoing client connections */
00089    AST_SSL_TLSV1_CLIENT = (1 << 5)
00090 };


Function Documentation

int ast_ssl_setup ( struct ast_tls_config cfg  ) 

Definition at line 399 of file tcptls.c.

References __ssl_setup().

Referenced by __ast_http_load(), __init_manager(), and reload_config().

00400 {
00401    return __ssl_setup(cfg, 0);
00402 }

struct ast_tcptls_session_instance* ast_tcptls_client_create ( struct ast_tcptls_session_args desc  )  [read]

Definition at line 441 of file tcptls.c.

References ast_tcptls_session_args::accept_fd, ao2_alloc, ao2_ref, ast_bind(), ast_debug, ast_log(), ast_mutex_init, ast_sockaddr_cmp(), ast_sockaddr_copy(), ast_sockaddr_is_ipv6(), ast_sockaddr_isnull(), ast_sockaddr_setnull(), ast_sockaddr_stringify(), ast_tcptls_session_instance::client, errno, ast_tcptls_session_instance::fd, ast_tcptls_session_args::local_address, ast_tcptls_session_instance::lock, LOG_ERROR, LOG_WARNING, ast_tcptls_session_args::name, ast_tcptls_session_args::old_address, ast_tcptls_session_instance::parent, ast_tcptls_session_instance::remote_address, ast_tcptls_session_args::remote_address, session_instance_destructor(), and ast_tcptls_session_args::worker_fn.

Referenced by app_exec(), and sip_prepare_socket().

00442 {
00443    int x = 1;
00444    struct ast_tcptls_session_instance *tcptls_session = NULL;
00445 
00446    /* Do nothing if nothing has changed */
00447    if (!ast_sockaddr_cmp(&desc->old_address, &desc->remote_address)) {
00448       ast_debug(1, "Nothing changed in %s\n", desc->name);
00449       return NULL;
00450    }
00451 
00452    /* If we return early, there is no connection */
00453    ast_sockaddr_setnull(&desc->old_address);
00454 
00455    if (desc->accept_fd != -1) {
00456       close(desc->accept_fd);
00457    }
00458 
00459    desc->accept_fd = socket(ast_sockaddr_is_ipv6(&desc->remote_address) ?
00460              AF_INET6 : AF_INET, SOCK_STREAM, IPPROTO_TCP);
00461    if (desc->accept_fd < 0) {
00462       ast_log(LOG_WARNING, "Unable to allocate socket for %s: %s\n",
00463          desc->name, strerror(errno));
00464       return NULL;
00465    }
00466 
00467    /* if a local address was specified, bind to it so the connection will
00468       originate from the desired address */
00469    if (!ast_sockaddr_isnull(&desc->local_address)) {
00470       setsockopt(desc->accept_fd, SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x));
00471       if (ast_bind(desc->accept_fd, &desc->local_address)) {
00472          ast_log(LOG_ERROR, "Unable to bind %s to %s: %s\n",
00473             desc->name,
00474             ast_sockaddr_stringify(&desc->local_address),
00475             strerror(errno));
00476          goto error;
00477       }
00478    }
00479 
00480    if (!(tcptls_session = ao2_alloc(sizeof(*tcptls_session), session_instance_destructor))) {
00481       goto error;
00482    }
00483 
00484    ast_mutex_init(&tcptls_session->lock);
00485    tcptls_session->client = 1;
00486    tcptls_session->fd = desc->accept_fd;
00487    tcptls_session->parent = desc;
00488    tcptls_session->parent->worker_fn = NULL;
00489    ast_sockaddr_copy(&tcptls_session->remote_address,
00490            &desc->remote_address);
00491 
00492    /* Set current info */
00493    ast_sockaddr_copy(&desc->old_address, &desc->remote_address);
00494    return tcptls_session;
00495 
00496 error:
00497    close(desc->accept_fd);
00498    desc->accept_fd = -1;
00499    if (tcptls_session) {
00500       ao2_ref(tcptls_session, -1);
00501    }
00502    return NULL;
00503 }

struct ast_tcptls_session_instance* ast_tcptls_client_start ( struct ast_tcptls_session_instance tcptls_session  )  [read]

attempts to connect and start tcptls session, on error the tcptls_session's ref count is decremented, fd and file are closed, and NULL is returned.

Definition at line 404 of file tcptls.c.

References __ssl_setup(), ast_tcptls_session_args::accept_fd, ao2_ref, ast_connect(), ast_log(), ast_sockaddr_stringify(), desc, ast_tls_config::enabled, errno, handle_tcptls_connection(), LOG_ERROR, ast_tcptls_session_args::name, ast_tcptls_session_instance::parent, ast_tcptls_session_args::remote_address, and ast_tcptls_session_args::tls_cfg.

Referenced by _sip_tcp_helper_thread(), and app_exec().

00405 {
00406    struct ast_tcptls_session_args *desc;
00407    int flags;
00408 
00409    if (!(desc = tcptls_session->parent)) {
00410       goto client_start_error;
00411    }
00412 
00413    if (ast_connect(desc->accept_fd, &desc->remote_address)) {
00414       ast_log(LOG_ERROR, "Unable to connect %s to %s: %s\n",
00415          desc->name,
00416          ast_sockaddr_stringify(&desc->remote_address),
00417          strerror(errno));
00418       goto client_start_error;
00419    }
00420 
00421    flags = fcntl(desc->accept_fd, F_GETFL);
00422    fcntl(desc->accept_fd, F_SETFL, flags & ~O_NONBLOCK);
00423 
00424    if (desc->tls_cfg) {
00425       desc->tls_cfg->enabled = 1;
00426       __ssl_setup(desc->tls_cfg, 1);
00427    }
00428 
00429    return handle_tcptls_connection(tcptls_session);
00430 
00431 client_start_error:
00432    close(desc->accept_fd);
00433    desc->accept_fd = -1;
00434    if (tcptls_session) {
00435       ao2_ref(tcptls_session, -1);
00436    }
00437    return NULL;
00438 
00439 }

void ast_tcptls_close_session_file ( struct ast_tcptls_session_instance tcptls_session  ) 

Closes a tcptls session instance's file and/or file descriptor. The tcptls_session will be set to NULL and it's file descriptor will be set to -1 by this function.

Definition at line 575 of file tcptls.c.

References ast_log(), errno, ast_tcptls_session_instance::f, ast_tcptls_session_instance::fd, and LOG_ERROR.

Referenced by _sip_tcp_helper_thread(), ast_tcptls_server_root(), handle_tcptls_connection(), and sip_prepare_socket().

00576 {
00577    if (tcptls_session->f) {
00578       if (fclose(tcptls_session->f)) {
00579          ast_log(LOG_ERROR, "fclose() failed: %s\n", strerror(errno));
00580       }
00581       tcptls_session->f = NULL;
00582       tcptls_session->fd = -1;
00583    } else if (tcptls_session->fd != -1) {
00584       if (close(tcptls_session->fd)) {
00585          ast_log(LOG_ERROR, "close() failed: %s\n", strerror(errno));
00586       }
00587       tcptls_session->fd = -1;
00588    } else {
00589       ast_log(LOG_ERROR, "ast_tcptls_close_session_file invoked on session instance without file or file descriptor\n");
00590    }
00591 }

HOOK_T ast_tcptls_server_read ( struct ast_tcptls_session_instance ser,
void *  buf,
size_t  count 
)

replacement read/write functions for SSL support. We use wrappers rather than SSL_read/SSL_write directly so we can put in some debugging.

Definition at line 102 of file tcptls.c.

References ast_log(), errno, ast_tcptls_session_instance::fd, LOG_ERROR, and ast_tcptls_session_instance::ssl.

00103 {
00104    if (tcptls_session->fd == -1) {
00105       ast_log(LOG_ERROR, "server_read called with an fd of -1\n");
00106       errno = EIO;
00107       return -1;
00108    }
00109 
00110 #ifdef DO_SSL
00111    if (tcptls_session->ssl) {
00112       return ssl_read(tcptls_session->ssl, buf, count);
00113    }
00114 #endif
00115    return read(tcptls_session->fd, buf, count);
00116 }

void* ast_tcptls_server_root ( void *   ) 

Definition at line 263 of file tcptls.c.

References ast_tcptls_session_args::accept_fd, ao2_alloc, ao2_ref, ast_accept(), ast_log(), ast_mutex_init, ast_pthread_create_detached_background, ast_sockaddr_copy(), ast_tcptls_close_session_file(), ast_wait_for_input(), ast_tcptls_session_instance::client, desc, errno, ast_tcptls_session_instance::fd, handle_tcptls_connection(), ast_tcptls_session_instance::lock, LOG_ERROR, LOG_WARNING, ast_tcptls_session_instance::parent, ast_tcptls_session_args::periodic_fn, ast_tcptls_session_args::poll_timeout, ast_tcptls_session_instance::remote_address, and session_instance_destructor().

00264 {
00265    struct ast_tcptls_session_args *desc = data;
00266    int fd;
00267    struct ast_sockaddr addr;
00268    struct ast_tcptls_session_instance *tcptls_session;
00269    pthread_t launched;
00270 
00271    for (;;) {
00272       int i, flags;
00273 
00274       if (desc->periodic_fn) {
00275          desc->periodic_fn(desc);
00276       }
00277       i = ast_wait_for_input(desc->accept_fd, desc->poll_timeout);
00278       if (i <= 0) {
00279          continue;
00280       }
00281       fd = ast_accept(desc->accept_fd, &addr);
00282       if (fd < 0) {
00283          if ((errno != EAGAIN) && (errno != EINTR)) {
00284             ast_log(LOG_WARNING, "Accept failed: %s\n", strerror(errno));
00285          }
00286          continue;
00287       }
00288       tcptls_session = ao2_alloc(sizeof(*tcptls_session), session_instance_destructor);
00289       if (!tcptls_session) {
00290          ast_log(LOG_WARNING, "No memory for new session: %s\n", strerror(errno));
00291          if (close(fd)) {
00292             ast_log(LOG_ERROR, "close() failed: %s\n", strerror(errno));
00293          }
00294          continue;
00295       }
00296 
00297       ast_mutex_init(&tcptls_session->lock);
00298 
00299       flags = fcntl(fd, F_GETFL);
00300       fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
00301       tcptls_session->fd = fd;
00302       tcptls_session->parent = desc;
00303       ast_sockaddr_copy(&tcptls_session->remote_address, &addr);
00304 
00305       tcptls_session->client = 0;
00306 
00307       /* This thread is now the only place that controls the single ref to tcptls_session */
00308       if (ast_pthread_create_detached_background(&launched, NULL, handle_tcptls_connection, tcptls_session)) {
00309          ast_log(LOG_WARNING, "Unable to launch helper thread: %s\n", strerror(errno));
00310          ast_tcptls_close_session_file(tcptls_session);
00311          ao2_ref(tcptls_session, -1);
00312       }
00313    }
00314    return NULL;
00315 }

void ast_tcptls_server_start ( struct ast_tcptls_session_args desc  ) 

This is a generic (re)start routine for a TCP server, which does the socket/bind/listen and starts a thread for handling accept().

Version:
1.6.1 changed desc parameter to be of ast_tcptls_session_args type

Definition at line 505 of file tcptls.c.

References ast_tcptls_session_args::accept_fd, ast_tcptls_session_args::accept_fn, ast_bind(), ast_debug, ast_log(), ast_pthread_create_background, AST_PTHREADT_NULL, ast_sockaddr_cmp(), ast_sockaddr_copy(), ast_sockaddr_is_ipv6(), ast_sockaddr_isnull(), ast_sockaddr_setnull(), ast_sockaddr_stringify(), errno, ast_tcptls_session_args::local_address, LOG_ERROR, ast_tcptls_session_args::master, ast_tcptls_session_args::name, and ast_tcptls_session_args::old_address.

Referenced by __ast_http_load(), __init_manager(), and reload_config().

00506 {
00507    int flags;
00508    int x = 1;
00509 
00510    /* Do nothing if nothing has changed */
00511    if (!ast_sockaddr_cmp(&desc->old_address, &desc->local_address)) {
00512       ast_debug(1, "Nothing changed in %s\n", desc->name);
00513       return;
00514    }
00515 
00516    /* If we return early, there is no one listening */
00517    ast_sockaddr_setnull(&desc->old_address);
00518 
00519    /* Shutdown a running server if there is one */
00520    if (desc->master != AST_PTHREADT_NULL) {
00521       pthread_cancel(desc->master);
00522       pthread_kill(desc->master, SIGURG);
00523       pthread_join(desc->master, NULL);
00524    }
00525 
00526    if (desc->accept_fd != -1) {
00527       close(desc->accept_fd);
00528    }
00529 
00530    /* If there's no new server, stop here */
00531    if (ast_sockaddr_isnull(&desc->local_address)) {
00532       ast_debug(2, "Server disabled:  %s\n", desc->name);
00533       return;
00534    }
00535 
00536    desc->accept_fd = socket(ast_sockaddr_is_ipv6(&desc->local_address) ?
00537              AF_INET6 : AF_INET, SOCK_STREAM, 0);
00538    if (desc->accept_fd < 0) {
00539       ast_log(LOG_ERROR, "Unable to allocate socket for %s: %s\n", desc->name, strerror(errno));
00540       return;
00541    }
00542 
00543    setsockopt(desc->accept_fd, SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x));
00544    if (ast_bind(desc->accept_fd, &desc->local_address)) {
00545       ast_log(LOG_ERROR, "Unable to bind %s to %s: %s\n",
00546          desc->name,
00547          ast_sockaddr_stringify(&desc->local_address),
00548          strerror(errno));
00549       goto error;
00550    }
00551    if (listen(desc->accept_fd, 10)) {
00552       ast_log(LOG_ERROR, "Unable to listen for %s!\n", desc->name);
00553       goto error;
00554    }
00555    flags = fcntl(desc->accept_fd, F_GETFL);
00556    fcntl(desc->accept_fd, F_SETFL, flags | O_NONBLOCK);
00557    if (ast_pthread_create_background(&desc->master, NULL, desc->accept_fn, desc)) {
00558       ast_log(LOG_ERROR, "Unable to launch thread for %s on %s: %s\n",
00559          desc->name,
00560          ast_sockaddr_stringify(&desc->local_address),
00561          strerror(errno));
00562       goto error;
00563    }
00564 
00565    /* Set current info */
00566    ast_sockaddr_copy(&desc->old_address, &desc->local_address);
00567 
00568    return;
00569 
00570 error:
00571    close(desc->accept_fd);
00572    desc->accept_fd = -1;
00573 }

void ast_tcptls_server_stop ( struct ast_tcptls_session_args desc  ) 

Shutdown a running server if there is one.

Version:
1.6.1 changed desc parameter to be of ast_tcptls_session_args type

Definition at line 593 of file tcptls.c.

References ast_tcptls_session_args::accept_fd, ast_debug, AST_PTHREADT_NULL, ast_tcptls_session_args::master, and ast_tcptls_session_args::name.

Referenced by __ast_http_load(), __init_manager(), and unload_module().

00594 {
00595    if (desc->master != AST_PTHREADT_NULL) {
00596       pthread_cancel(desc->master);
00597       pthread_kill(desc->master, SIGURG);
00598       pthread_join(desc->master, NULL);
00599       desc->master = AST_PTHREADT_NULL;
00600    }
00601    if (desc->accept_fd != -1) {
00602       close(desc->accept_fd);
00603    }
00604    desc->accept_fd = -1;
00605    ast_debug(2, "Stopped server :: %s\n", desc->name);
00606 }

HOOK_T ast_tcptls_server_write ( struct ast_tcptls_session_instance ser,
const void *  buf,
size_t  count 
)

Definition at line 118 of file tcptls.c.

References ast_log(), errno, ast_tcptls_session_instance::fd, LOG_ERROR, and ast_tcptls_session_instance::ssl.

Referenced by _sip_tcp_helper_thread().

00119 {
00120    if (tcptls_session->fd == -1) {
00121       ast_log(LOG_ERROR, "server_write called with an fd of -1\n");
00122       errno = EIO;
00123       return -1;
00124    }
00125 
00126 #ifdef DO_SSL
00127    if (tcptls_session->ssl) {
00128       return ssl_write(tcptls_session->ssl, buf, count);
00129    }
00130 #endif
00131    return write(tcptls_session->fd, buf, count);
00132 }

int ast_tls_read_conf ( struct ast_tls_config tls_cfg,
struct ast_tcptls_session_args tls_desc,
const char *  varname,
const char *  value 
)

Used to parse conf files containing tls/ssl options.

Definition at line 608 of file tcptls.c.

References ast_clear_flag, ast_free, ast_log(), ast_parse_arg(), ast_set2_flag, ast_set_flag, AST_SSL_DONT_VERIFY_SERVER, AST_SSL_SSLV2_CLIENT, AST_SSL_SSLV3_CLIENT, AST_SSL_TLSV1_CLIENT, AST_SSL_VERIFY_CLIENT, ast_strdup, ast_true(), ast_tls_config::cafile, ast_tls_config::capath, ast_tls_config::certfile, ast_tls_config::cipher, ast_tls_config::enabled, ast_tls_config::flags, ast_tcptls_session_args::local_address, LOG_WARNING, PARSE_ADDR, and ast_tls_config::pvtfile.

Referenced by __ast_http_load(), __init_manager(), and reload_config().

00609 {
00610    if (!strcasecmp(varname, "tlsenable") || !strcasecmp(varname, "sslenable")) {
00611       tls_cfg->enabled = ast_true(value) ? 1 : 0;
00612    } else if (!strcasecmp(varname, "tlscertfile") || !strcasecmp(varname, "sslcert") || !strcasecmp(varname, "tlscert")) {
00613       ast_free(tls_cfg->certfile);
00614       tls_cfg->certfile = ast_strdup(value);
00615    } else if (!strcasecmp(varname, "tlsprivatekey") || !strcasecmp(varname, "sslprivatekey")) {
00616       ast_free(tls_cfg->pvtfile);
00617       tls_cfg->pvtfile = ast_strdup(value);
00618    } else if (!strcasecmp(varname, "tlscipher") || !strcasecmp(varname, "sslcipher")) {
00619       ast_free(tls_cfg->cipher);
00620       tls_cfg->cipher = ast_strdup(value);
00621    } else if (!strcasecmp(varname, "tlscafile")) {
00622       ast_free(tls_cfg->cafile);
00623       tls_cfg->cafile = ast_strdup(value);
00624    } else if (!strcasecmp(varname, "tlscapath") || !strcasecmp(varname, "tlscadir")) {
00625       ast_free(tls_cfg->capath);
00626       tls_cfg->capath = ast_strdup(value);
00627    } else if (!strcasecmp(varname, "tlsverifyclient")) {
00628       ast_set2_flag(&tls_cfg->flags, ast_true(value), AST_SSL_VERIFY_CLIENT);
00629    } else if (!strcasecmp(varname, "tlsdontverifyserver")) {
00630       ast_set2_flag(&tls_cfg->flags, ast_true(value), AST_SSL_DONT_VERIFY_SERVER);
00631    } else if (!strcasecmp(varname, "tlsbindaddr") || !strcasecmp(varname, "sslbindaddr")) {
00632       if (ast_parse_arg(value, PARSE_ADDR, &tls_desc->local_address))
00633          ast_log(LOG_WARNING, "Invalid %s '%s'\n", varname, value);
00634    } else if (!strcasecmp(varname, "tlsclientmethod") || !strcasecmp(varname, "sslclientmethod")) {
00635       if (!strcasecmp(value, "tlsv1")) {
00636          ast_set_flag(&tls_cfg->flags, AST_SSL_TLSV1_CLIENT);
00637          ast_clear_flag(&tls_cfg->flags, AST_SSL_SSLV3_CLIENT);
00638          ast_clear_flag(&tls_cfg->flags, AST_SSL_SSLV2_CLIENT);
00639       } else if (!strcasecmp(value, "sslv3")) {
00640          ast_set_flag(&tls_cfg->flags, AST_SSL_SSLV3_CLIENT);
00641          ast_clear_flag(&tls_cfg->flags, AST_SSL_SSLV2_CLIENT);
00642          ast_clear_flag(&tls_cfg->flags, AST_SSL_TLSV1_CLIENT);
00643       } else if (!strcasecmp(value, "sslv2")) {
00644          ast_set_flag(&tls_cfg->flags, AST_SSL_SSLV2_CLIENT);
00645          ast_clear_flag(&tls_cfg->flags, AST_SSL_TLSV1_CLIENT);
00646          ast_clear_flag(&tls_cfg->flags, AST_SSL_SSLV3_CLIENT);
00647       }
00648    } else {
00649       return -1;
00650    }
00651 
00652    return 0;
00653 }


Generated on Fri Feb 10 06:37:37 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6