[asterisk-commits] mmichelson: branch mmichelson/outbound_auth r382357 - in /team/mmichelson/out...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Fri Mar 1 16:31:39 CST 2013


Author: mmichelson
Date: Fri Mar  1 16:31:36 2013
New Revision: 382357

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=382357
Log:
Set up outbound authentication for SIP sessions.

This creates the authentication options necessary for setting
up outbound authentication. Now in addition to "auth=" for endpoints,
there is also "outbound_auth=" that can be set. These are used in case
a request to that endpoint is challenged.

In res_sip_session.c, we now set up authentication credentials on
the dialog. This *should* have the effect of having challenges be
automatically handled by the dialog.

A more generic method will need to be devised for situations where
no dialog is in use.


Modified:
    team/mmichelson/outbound_auth/include/asterisk/res_sip.h
    team/mmichelson/outbound_auth/res/res_sip.exports.in
    team/mmichelson/outbound_auth/res/res_sip/sip_configuration.c
    team/mmichelson/outbound_auth/res/res_sip_authenticator_digest.c
    team/mmichelson/outbound_auth/res/res_sip_session.c

Modified: team/mmichelson/outbound_auth/include/asterisk/res_sip.h
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/outbound_auth/include/asterisk/res_sip.h?view=diff&rev=382357&r1=382356&r2=382357
==============================================================================
--- team/mmichelson/outbound_auth/include/asterisk/res_sip.h (original)
+++ team/mmichelson/outbound_auth/include/asterisk/res_sip.h Fri Mar  1 16:31:36 2013
@@ -236,10 +236,14 @@
 	struct ast_codec_pref prefs;
 	/*! Configured codecs */
 	struct ast_format_cap *codecs;
-	/*! Names of authentication credentials */
-	const char **sip_auths;
+	/*! Names of inbound authentication credentials */
+	const char **sip_inbound_auths;
 	/*! Number of configured auths */
-	size_t num_auths;
+	size_t num_inbound_auths;
+	/*! Names of outbound authentication credentials */
+	const char **sip_outbound_auths;
+	/*! Number of configured outbound auths */
+	size_t num_outbound_auths;
 	/*! DTMF mode to use with this endpoint */
 	enum ast_sip_dtmf_mode dtmf;
 	/*! Whether IPv6 RTP is enabled or not */
@@ -762,4 +766,24 @@
  */
 struct ast_sip_endpoint *ast_pjsip_rdata_get_endpoint(pjsip_rx_data *rdata);
 
+/*!
+ * \brief Retrieve relevant SIP auth structures from sorcery
+ *
+ * \param auth_names The sorcery IDs of auths to retrieve
+ * \param num_auths The number of auths to retrieve
+ * \param[out] out The retrieved auths are stored here
+ */
+int ast_sip_retrieve_auths(const char *auth_names[], size_t num_auths, struct ast_sip_auth **out);
+
+/*!
+ * \brief Clean up retrieved auth structures from memory
+ *
+ * Call this function once you have completed operating on auths
+ * retrieved from \ref ast_sip_retrieve_auths
+ *
+ * \param auths An array of auth structures to clean up
+ * \param num_auths The number of auths in the array
+ */
+void ast_sip_cleanup_auths(struct ast_sip_auth *auths[], size_t num_auths);
+
 #endif /* _RES_SIP_H */

Modified: team/mmichelson/outbound_auth/res/res_sip.exports.in
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/outbound_auth/res/res_sip.exports.in?view=diff&rev=382357&r1=382356&r2=382357
==============================================================================
--- team/mmichelson/outbound_auth/res/res_sip.exports.in (original)
+++ team/mmichelson/outbound_auth/res/res_sip.exports.in Fri Mar  1 16:31:36 2013
@@ -28,6 +28,8 @@
 		LINKER_SYMBOL_PREFIXast_sip_endpoint_get_location;
 		LINKER_SYMBOL_PREFIXast_pjsip_rdata_get_endpoint;
 		LINKER_SYMBOL_PREFIXast_sip_thread_is_servant;
+		LINKER_SYMBOL_PREFIXast_sip_retrieve_auths;
+		LINKER_SYMBOL_PREFIXast_sip_cleanup_auths;
 		LINKER_SYMBOL_PREFIXpj_*;
 		LINKER_SYMBOL_PREFIXpjsip_*;
 		LINKER_SYMBOL_PREFIXpjmedia_*;

Modified: team/mmichelson/outbound_auth/res/res_sip/sip_configuration.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/outbound_auth/res/res_sip/sip_configuration.c?view=diff&rev=382357&r1=382356&r2=382357
==============================================================================
--- team/mmichelson/outbound_auth/res/res_sip/sip_configuration.c (original)
+++ team/mmichelson/outbound_auth/res/res_sip/sip_configuration.c Fri Mar  1 16:31:36 2013
@@ -193,45 +193,66 @@
 	return 0;
 }
 
-static void destroy_endpoint_auths(const struct ast_sip_endpoint *endpoint)
+static void destroy_auths(const char **auths, size_t num_auths)
 {
 	int i;
-	for (i = 0; i < endpoint->num_auths; ++i) {
-		ast_free((char *) endpoint->sip_auths[i]);
-	}
-	ast_free(endpoint->sip_auths);
+	for (i = 0; i < num_auths; ++i) {
+		ast_free((char *) auths[i]);
+	}
+	ast_free(auths);
 }
 
 #define AUTH_INCREMENT 4
 
-static int auth_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
-{
-	char *auths = ast_strdupa(var->value);
+static const char **auth_alloc(const char *value, size_t *num_auths)
+{
+	char *auths = ast_strdupa(value);
 	char *val;
-	struct ast_sip_endpoint *endpoint = obj;
 	int num_alloced = 0;
+	const char **alloced_auths = NULL;
 
 	while ((val = strsep(&auths, ","))) {
-		if (endpoint->num_auths >= num_alloced) {
+		if (*num_auths >= num_alloced) {
 			size_t size;
 			num_alloced += AUTH_INCREMENT;
 			size = num_alloced * sizeof(char *);
-			endpoint->sip_auths = ast_realloc(endpoint->sip_auths, size);
-			if (!endpoint->sip_auths) {
+			alloced_auths = ast_realloc(alloced_auths, size);
+			if (!alloced_auths) {
 				goto failure;
 			}
 		}
-		endpoint->sip_auths[endpoint->num_auths] = ast_strdup(val);
-		if (!endpoint->sip_auths[endpoint->num_auths]) {
+		alloced_auths[*num_auths] = ast_strdup(val);
+		if (!alloced_auths[*num_auths]) {
 			goto failure;
 		}
-		++endpoint->num_auths;
-	}
-	return 0;
+		++(*num_auths);
+	}
+	return alloced_auths;
 
 failure:
-	destroy_endpoint_auths(endpoint);
-	return -1;
+	destroy_auths(alloced_auths, *num_auths);
+	return NULL;
+}
+
+static int inbound_auth_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
+{
+	struct ast_sip_endpoint *endpoint = obj;
+
+	endpoint->sip_inbound_auths = auth_alloc(var->value, &endpoint->num_inbound_auths);
+	if (!endpoint->sip_inbound_auths) {
+		return -1;
+	}
+	return 0;
+}
+static int outbound_auth_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
+{
+	struct ast_sip_endpoint *endpoint = obj;
+
+	endpoint->sip_outbound_auths = auth_alloc(var->value, &endpoint->num_outbound_auths);
+	if (!endpoint->sip_outbound_auths) {
+		return -1;
+	}
+	return 0;
 }
 
 static int ident_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
@@ -305,7 +326,8 @@
 	ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "timers", "yes", timers_handler, NULL, 0, 0);
 	ast_sorcery_object_field_register(sip_sorcery, "endpoint", "timers_min_se", "90", OPT_UINT_T, 0, FLDSET(struct ast_sip_endpoint, min_se));
 	ast_sorcery_object_field_register(sip_sorcery, "endpoint", "timers_sess_expires", "1800", OPT_UINT_T, 0, FLDSET(struct ast_sip_endpoint, sess_expires));
-	ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "auth", "", auth_handler, NULL, 0, 0);
+	ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "auth", "", inbound_auth_handler, NULL, 0, 0);
+	ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "outbound_auth", "", outbound_auth_handler, NULL, 0, 0);
 	ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "identify_by", "username,location", ident_handler, NULL, 0, 0);
 
 	if (ast_sip_initialize_sorcery_transport(sip_sorcery)) {
@@ -343,7 +365,8 @@
 	if (endpoint->codecs) {
 		ast_format_cap_destroy(endpoint->codecs);
 	}
-	destroy_endpoint_auths(endpoint);
+	destroy_auths(endpoint->sip_inbound_auths, endpoint->num_inbound_auths);
+	destroy_auths(endpoint->sip_outbound_auths, endpoint->num_outbound_auths);
 }
 
 void *ast_sip_endpoint_alloc(const char *name)
@@ -396,6 +419,29 @@
 	return endpoints;
 }
 
+int ast_sip_retrieve_auths(const char *auth_names[], size_t num_auths, struct ast_sip_auth **out)
+{
+	int i;
+
+	for (i = 0; i < num_auths; ++i) {
+		out[i] = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), SIP_SORCERY_AUTH_TYPE, auth_names[i]);
+		if (!out[i]) {
+			ast_log(LOG_NOTICE, "Couldn't find auth '%s'. Cannot authenticate\n", auth_names[i]);
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+void ast_sip_cleanup_auths(struct ast_sip_auth *auths[], size_t num_auths)
+{
+	int i;
+	for (i = 0; i < num_auths; ++i) {
+		ao2_cleanup(auths[i]);
+	}
+}
+
 struct ast_sorcery *ast_sip_get_sorcery(void)
 {
 	return sip_sorcery;

Modified: team/mmichelson/outbound_auth/res/res_sip_authenticator_digest.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/outbound_auth/res/res_sip_authenticator_digest.c?view=diff&rev=382357&r1=382356&r2=382357
==============================================================================
--- team/mmichelson/outbound_auth/res/res_sip_authenticator_digest.c (original)
+++ team/mmichelson/outbound_auth/res/res_sip_authenticator_digest.c Fri Mar  1 16:31:36 2013
@@ -41,7 +41,7 @@
  */
 static int digest_requires_authentication(struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata)
 {
-	return endpoint->num_auths > 0;
+	return endpoint->num_inbound_auths > 0;
 }
 
 static void auth_store_cleanup(void *data)
@@ -356,29 +356,6 @@
 	pjsip_auth_srv_challenge(&auth_server, &qop, &pj_nonce, NULL, is_stale ? PJ_TRUE : PJ_FALSE, tdata);
 }
 
-static int retrieve_sip_auths_from_sorcery(const char *auth_names[], size_t num_auths, struct ast_sip_auth **out)
-{
-	int i;
-
-	for (i = 0; i < num_auths; ++i) {
-		out[i] = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), SIP_SORCERY_AUTH_TYPE, auth_names[i]);
-		if (!out[i]) {
-			ast_log(LOG_NOTICE, "Couldn't find auth '%s'. Cannot authenticate\n", auth_names[i]);
-			return -1;
-		}
-	}
-
-	return 0;
-}
-
-static void cleanup_auths(struct ast_sip_auth *auths[], size_t num_auths)
-{
-	int i;
-	for (i = 0; i < num_auths; ++i) {
-		ao2_cleanup(auths[i]);
-	}
-}
-
 /*!
  * \brief Check authentication using Digest scheme
  *
@@ -391,8 +368,8 @@
 static enum ast_sip_check_auth_result digest_check_auth(struct ast_sip_endpoint *endpoint,
 		pjsip_rx_data *rdata, pjsip_tx_data *tdata)
 {
-	struct ast_sip_auth **auths = ast_alloca(endpoint->num_auths * sizeof(*auths));
-	enum digest_verify_result *verify_res = ast_alloca(endpoint->num_auths * sizeof(*verify_res));
+	struct ast_sip_auth **auths = ast_alloca(endpoint->num_inbound_auths * sizeof(*auths));
+	enum digest_verify_result *verify_res = ast_alloca(endpoint->num_inbound_auths * sizeof(*verify_res));
 	enum ast_sip_check_auth_result res;
 	int i;
 
@@ -400,12 +377,12 @@
 		return AST_SIP_AUTHENTICATION_ERROR;
 	}
 
-	if (retrieve_sip_auths_from_sorcery(endpoint->sip_auths, endpoint->num_auths, auths)) {
+	if (ast_sip_retrieve_auths(endpoint->sip_inbound_auths, endpoint->num_inbound_auths, auths)) {
 		res = AST_SIP_AUTHENTICATION_ERROR;
 		goto cleanup;
 	}
 
-	for (i = 0; i < endpoint->num_auths; ++i) {
+	for (i = 0; i < endpoint->num_inbound_auths; ++i) {
 		verify_res[i] = verify(auths[i], rdata, tdata->pool);
 		if (verify_res[i] == AUTH_SUCCESS) {
 			res = AST_SIP_AUTHENTICATION_SUCCESS;
@@ -413,14 +390,14 @@
 		}
 	}
 
-	for (i = 0; i < endpoint->num_auths; ++i) {
+	for (i = 0; i < endpoint->num_inbound_auths; ++i) {
 		challenge(auths[i], tdata, rdata, verify_res[i] == AUTH_STALE);
 	}
 	
 	res = AST_SIP_AUTHENTICATION_CHALLENGE;
 
 cleanup:
-	cleanup_auths(auths, endpoint->num_auths);
+	ast_sip_cleanup_auths(auths, endpoint->num_inbound_auths);
 	return res;
 }
 

Modified: team/mmichelson/outbound_auth/res/res_sip_session.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/outbound_auth/res/res_sip_session.c?view=diff&rev=382357&r1=382356&r2=382357
==============================================================================
--- team/mmichelson/outbound_auth/res/res_sip_session.c (original)
+++ team/mmichelson/outbound_auth/res/res_sip_session.c Fri Mar  1 16:31:36 2013
@@ -581,6 +581,38 @@
 	return 0;
 }
 
+static int set_auth_credentials(pjsip_dialog *dlg, struct ast_sip_endpoint *endpoint)
+{
+	struct ast_sip_auth **auths = ast_alloca(endpoint->num_outbound_auths * sizeof(*auths));
+	pjsip_cred_info *auth_creds = ast_alloca(endpoint->num_outbound_auths * sizeof(*auth_creds));
+	int i;
+
+	if (ast_sip_retrieve_auths(endpoint->sip_outbound_auths, endpoint->num_outbound_auths, auths)) {
+		return -1;
+	}
+
+	for (i = 0; i < endpoint->num_outbound_auths; ++i) {
+		pj_cstr(&auth_creds[i].realm, auths[i]->realm);
+		pj_cstr(&auth_creds[i].username, auths[i]->auth_user);
+		pj_cstr(&auth_creds[i].scheme, "digest");
+		switch (auths[i]->type) {
+		case AST_SIP_AUTH_TYPE_USER_PASS:
+			pj_cstr(&auth_creds[i].data, auths[i]->auth_pass);
+			auth_creds[i].data_type = PJSIP_CRED_DATA_PLAIN_PASSWD;
+			break;
+		case AST_SIP_AUTH_TYPE_MD5:
+			pj_cstr(&auth_creds[i].data, auths[i]->md5_creds);
+			auth_creds[i].data_type = PJSIP_CRED_DATA_DIGEST;
+			break;
+		}
+	}
+
+	pjsip_auth_clt_set_credentials(&dlg->auth_sess, endpoint->num_outbound_auths, auth_creds);
+
+	ast_sip_cleanup_auths(auths, endpoint->num_outbound_auths);
+	return 0;
+}
+
 struct ast_sip_session *ast_sip_session_create_outgoing(struct ast_sip_endpoint *endpoint, const char *uri)
 {
 	pj_str_t local_uri = pj_str("sip:temp at localhost"), remote_uri = pj_str((char*)uri);
@@ -593,6 +625,11 @@
 	pjsip_timer_setting timer;
 
 	if (pjsip_dlg_create_uac(pjsip_ua_instance(), &local_uri, NULL, &remote_uri, NULL, &dlg) != PJ_SUCCESS) {
+		return NULL;
+	}
+
+	if (set_auth_credentials(dlg, endpoint)) {
+		pjsip_dlg_terminate(dlg);
 		return NULL;
 	}
 




More information about the asterisk-commits mailing list