[asterisk-commits] dvossel: trunk r191177 - in /trunk: ./ configs/ include/asterisk/ main/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Wed Apr 29 16:13:48 CDT 2009


Author: dvossel
Date: Wed Apr 29 16:13:43 2009
New Revision: 191177

URL: http://svn.digium.com/svn-view/asterisk?view=rev&rev=191177
Log:
SIP option to specify outbound TLS/SSL client protocol.

chan_sip allows for outbound TLS connections, but does not allow the user to specify what protocol to use (default was SSLv2, and still is if this new option is not specified).  This patch lets the user pick the SSL/TLS client method for outbound connections in sip.

(closes issue #14770)
Reported by: TheOldSaint

(closes issue #14768)
Reported by: TheOldSaint

Review: http://reviewboard.digium.com/r/240/


Modified:
    trunk/CHANGES
    trunk/configs/sip.conf.sample
    trunk/include/asterisk/tcptls.h
    trunk/main/tcptls.c

Modified: trunk/CHANGES
URL: http://svn.digium.com/svn-view/asterisk/trunk/CHANGES?view=diff&rev=191177&r1=191176&r2=191177
==============================================================================
--- trunk/CHANGES (original)
+++ trunk/CHANGES Wed Apr 29 16:13:43 2009
@@ -23,6 +23,8 @@
  * Added tlsprivatekey option to sip.conf.  This allows a separate .pem file
    to be used for holding a private key.  If tlsprivatekey is not specified,
    tlscertfile is searched for both public and private key.
+ * Added tlsclientmethod option to sip.conf.  This allows the protocol for
+   outbound client connections to be specified.
 
 Applications
 ------------

Modified: trunk/configs/sip.conf.sample
URL: http://svn.digium.com/svn-view/asterisk/trunk/configs/sip.conf.sample?view=diff&rev=191177&r1=191176&r2=191177
==============================================================================
--- trunk/configs/sip.conf.sample (original)
+++ trunk/configs/sip.conf.sample Wed Apr 29 16:13:43 2009
@@ -142,8 +142,12 @@
 
 ;tlscipher=<SSL cipher string>
 ;        A string specifying which SSL ciphers to use or not use
-;        A list of valid SSL cipher strings can be found at: 
+;        A list of valid SSL cipher strings can be found at:
 ;                http://www.openssl.org/docs/apps/ciphers.html#CIPHER_STRINGS
+;
+;tlsclientmethod=tlsv1     ; values include tlsv1, sslv3, sslv2.
+                           ; Specify protocol for outbound client connections.
+                           ; If left unspecified, the default is sslv2.
 
 srvlookup=yes                   ; Enable DNS SRV lookups on outbound calls
                                 ; Note: Asterisk only uses the first host 

Modified: trunk/include/asterisk/tcptls.h
URL: http://svn.digium.com/svn-view/asterisk/trunk/include/asterisk/tcptls.h?view=diff&rev=191177&r1=191176&r2=191177
==============================================================================
--- trunk/include/asterisk/tcptls.h (original)
+++ trunk/include/asterisk/tcptls.h Wed Apr 29 16:13:43 2009
@@ -72,7 +72,13 @@
 	/*! Don't verify certificate when connecting to a server */
 	AST_SSL_DONT_VERIFY_SERVER = (1 << 1),
 	/*! Don't compare "Common Name" against IP or hostname */
-	AST_SSL_IGNORE_COMMON_NAME = (1 << 2)
+	AST_SSL_IGNORE_COMMON_NAME = (1 << 2),
+	/*! Use SSLv2 for outgoing client connections */
+	AST_SSL_SSLV2_CLIENT = (1 << 3),
+	/*! Use SSLv3 for outgoing client connections */
+	AST_SSL_SSLV3_CLIENT = (1 << 4),
+	/*! Use TLSv1 for outgoing client connections */
+	AST_SSL_TLSV1_CLIENT = (1 << 5)
 };
 
 struct ast_tls_config {

Modified: trunk/main/tcptls.c
URL: http://svn.digium.com/svn-view/asterisk/trunk/main/tcptls.c?view=diff&rev=191177&r1=191176&r2=191177
==============================================================================
--- trunk/main/tcptls.c (original)
+++ trunk/main/tcptls.c Wed Apr 29 16:13:43 2009
@@ -173,7 +173,7 @@
 					X509_NAME *name = X509_get_subject_name(peer);
 					int pos = -1;
 					int found = 0;
-				
+
 					for (;;) {
 						/* Walk the certificate to check all available "Common Name" */
 						/* XXX Probably should do a gethostbyname on the hostname and compare that as well */
@@ -229,7 +229,7 @@
 	socklen_t sinlen;
 	struct ast_tcptls_session_instance *tcptls_session;
 	pthread_t launched;
-	
+
 	for (;;) {
 		int i, flags;
 
@@ -261,7 +261,7 @@
 		memcpy(&tcptls_session->remote_address, &sin, sizeof(tcptls_session->remote_address));
 
 		tcptls_session->client = 0;
-			
+
 		if (ast_pthread_create_detached_background(&launched, NULL, handle_tls_connection, tcptls_session)) {
 			ast_log(LOG_WARNING, "Unable to launch helper thread: %s\n", strerror(errno));
 			close(tcptls_session->fd);
@@ -283,7 +283,26 @@
 	SSL_load_error_strings();
 	SSLeay_add_ssl_algorithms();
 
-	if (!(cfg->ssl_ctx = SSL_CTX_new( client ? SSLv23_client_method() : SSLv23_server_method() ))) {
+	if (client) {
+		if (ast_test_flag(&cfg->flags, AST_SSL_SSLV2_CLIENT)) {
+			cfg->ssl_ctx = SSL_CTX_new(SSLv2_client_method());
+		} else if (ast_test_flag(&cfg->flags, AST_SSL_SSLV3_CLIENT)) {
+			cfg->ssl_ctx = SSL_CTX_new(SSLv3_client_method());
+		} else if (ast_test_flag(&cfg->flags, AST_SSL_TLSV1_CLIENT)) {
+			cfg->ssl_ctx = SSL_CTX_new(TLSv1_client_method());
+		} else {
+			/* SSLv23_client_method() sends SSLv2, this was the original
+			 * default for ssl clients before the option was given to
+			 * pick what protocol a client should use.  In order not
+			 * to break expected behavior it remains the default. */
+			cfg->ssl_ctx = SSL_CTX_new(SSLv23_client_method());
+		}
+	} else {
+		/* SSLv23_server_method() supports TLSv1, SSLv2, and SSLv3 inbound connections. */
+		cfg->ssl_ctx = SSL_CTX_new(SSLv23_server_method());
+	}
+
+	if (!cfg->ssl_ctx) {
 		ast_debug(1, "Sorry, SSL_CTX_new call returned null...\n");
 		cfg->enabled = 0;
 		return 0;
@@ -417,22 +436,22 @@
 {
 	int flags;
 	int x = 1;
-	
+
 	/* Do nothing if nothing has changed */
 	if (!memcmp(&desc->old_address, &desc->local_address, sizeof(desc->old_address))) {
 		ast_debug(1, "Nothing changed in %s\n", desc->name);
 		return;
 	}
-	
+
 	desc->old_address = desc->local_address;
-	
+
 	/* Shutdown a running server if there is one */
 	if (desc->master != AST_PTHREADT_NULL) {
 		pthread_cancel(desc->master);
 		pthread_kill(desc->master, SIGURG);
 		pthread_join(desc->master, NULL);
 	}
-	
+
 	if (desc->accept_fd != -1)
 		close(desc->accept_fd);
 
@@ -447,7 +466,7 @@
 		ast_log(LOG_ERROR, "Unable to allocate socket for %s: %s\n", desc->name, strerror(errno));
 		return;
 	}
-	
+
 	setsockopt(desc->accept_fd, SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x));
 	if (bind(desc->accept_fd, (struct sockaddr *) &desc->local_address, sizeof(desc->local_address))) {
 		ast_log(LOG_ERROR, "Unable to bind %s to %s:%d: %s\n",
@@ -494,7 +513,7 @@
 	if (!strcasecmp(varname, "tlsenable") || !strcasecmp(varname, "sslenable")) {
 		tls_cfg->enabled = ast_true(value) ? 1 : 0;
 		tls_desc->local_address.sin_family = AF_INET;
-	} else if (!strcasecmp(varname, "tlscertfile") || !strcasecmp(varname, "sslcert")) {
+	} else if (!strcasecmp(varname, "tlscertfile") || !strcasecmp(varname, "sslcert") || !strcasecmp(varname, "tlscert")) {
 		ast_free(tls_cfg->certfile);
 		tls_cfg->certfile = ast_strdup(value);
 	} else if (!strcasecmp(varname, "tlsprivatekey") || !strcasecmp(varname, "sslprivatekey")) {
@@ -518,6 +537,20 @@
 			ast_log(LOG_WARNING, "Invalid %s '%s'\n", varname, value);
 	} else if (!strcasecmp(varname, "tlsbindport") || !strcasecmp(varname, "sslbindport")) {
 		tls_desc->local_address.sin_port = htons(atoi(value));
+	} else if (!strcasecmp(varname, "tlsclientmethod") || !strcasecmp(varname, "sslclientmethod")) {
+		if (!strcasecmp(value, "tlsv1")) {
+			ast_set_flag(&tls_cfg->flags, AST_SSL_TLSV1_CLIENT);
+			ast_clear_flag(&tls_cfg->flags, AST_SSL_SSLV3_CLIENT);
+			ast_clear_flag(&tls_cfg->flags, AST_SSL_SSLV2_CLIENT);
+		} else if (!strcasecmp(value, "sslv3")) {
+			ast_set_flag(&tls_cfg->flags, AST_SSL_SSLV3_CLIENT);
+			ast_clear_flag(&tls_cfg->flags, AST_SSL_SSLV2_CLIENT);
+			ast_clear_flag(&tls_cfg->flags, AST_SSL_TLSV1_CLIENT);
+		} else if (!strcasecmp(value, "sslv2")) {
+			ast_set_flag(&tls_cfg->flags, AST_SSL_SSLV2_CLIENT);
+			ast_clear_flag(&tls_cfg->flags, AST_SSL_TLSV1_CLIENT);
+			ast_clear_flag(&tls_cfg->flags, AST_SSL_SSLV3_CLIENT);
+		}
 	} else {
 		return -1;
 	}




More information about the asterisk-commits mailing list