[svn-commits] mmichelson: branch mmichelson/authenticate r381196 - in /team/mmichelson/auth...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Mon Feb 11 12:59:00 CST 2013


Author: mmichelson
Date: Mon Feb 11 12:58:56 2013
New Revision: 381196

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=381196
Log:
Stop storing authentication parameters in a container.

Now we store the sorcery IDs of auth sections in the endpoint.
When the time comes to actually use them, we grab them from
sorcery.


Modified:
    team/mmichelson/authenticate/include/asterisk/res_sip.h
    team/mmichelson/authenticate/res/res_sip/config_auth.c
    team/mmichelson/authenticate/res/res_sip/sip_configuration.c
    team/mmichelson/authenticate/res/res_sip_authenticator_digest.c

Modified: team/mmichelson/authenticate/include/asterisk/res_sip.h
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/authenticate/include/asterisk/res_sip.h?view=diff&rev=381196&r1=381195&r2=381196
==============================================================================
--- team/mmichelson/authenticate/include/asterisk/res_sip.h (original)
+++ team/mmichelson/authenticate/include/asterisk/res_sip.h Mon Feb 11 12:58:56 2013
@@ -187,7 +187,10 @@
 	AST_SIP_AUTH_TYPE_MD5,
 };
 
+#define SIP_SORCERY_AUTH_TYPE "auth"
+
 struct ast_sip_auth {
+	/* Sorcery ID of the auth is its name */
 	SORCERY_OBJECT(details);
 	AST_DECLARE_STRING_FIELDS(
 		/* Identification for these credentials */
@@ -226,8 +229,10 @@
 	struct ast_codec_pref prefs;
 	/*! Configured codecs */
 	struct ast_format_cap *codecs;
-	/*! Authentication credentials */
-	struct ao2_container *sip_auths;
+	/*! Names of authentication credentials */
+	const char **sip_auths;
+	/*! Number of configured auths */
+	size_t num_auths;
 	/*! DTMF mode to use with this endpoint */
 	enum ast_sip_dtmf_mode dtmf;
 	/*! Enabled SIP extensions */

Modified: team/mmichelson/authenticate/res/res_sip/config_auth.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/authenticate/res/res_sip/config_auth.c?view=diff&rev=381196&r1=381195&r2=381196
==============================================================================
--- team/mmichelson/authenticate/res/res_sip/config_auth.c (original)
+++ team/mmichelson/authenticate/res/res_sip/config_auth.c Mon Feb 11 12:58:56 2013
@@ -97,19 +97,26 @@
 /*! \brief Initialize sorcery with auth support */
 int ast_sip_initialize_sorcery_auth(struct ast_sorcery *sorcery)
 {
-	ast_sorcery_apply_default(sorcery, "auth", "config", "res_sip.conf,criteria=type=auth");
+	ast_sorcery_apply_default(sorcery, SIP_SORCERY_AUTH_TYPE, "config", "res_sip.conf,criteria=type=auth");
 
-	if (ast_sorcery_object_register(sorcery, "auth", auth_alloc, NULL, auth_apply)) {
+	if (ast_sorcery_object_register(sorcery, SIP_SORCERY_AUTH_TYPE, auth_alloc, NULL, auth_apply)) {
 		return -1;
 	}
 
-	ast_sorcery_object_field_register(sorcery, "auth", "type", "", OPT_NOOP_T, 0, 0);
-	ast_sorcery_object_field_register(sorcery, "auth", "username", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_auth, auth_user));
-	ast_sorcery_object_field_register(sorcery, "auth", "password", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_auth, auth_pass));
-	ast_sorcery_object_field_register(sorcery, "auth", "md5_cred", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_auth, md5_creds));
-	ast_sorcery_object_field_register(sorcery, "auth", "realm", "asterisk", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_auth, realm));
-	ast_sorcery_object_field_register(sorcery, "auth", "nonce_lifetime", "32", OPT_UINT_T, 0, FLDSET(struct ast_sip_auth, nonce_lifetime));
-	ast_sorcery_object_field_register_custom(sorcery, "auth", "auth_type", "userpass", auth_type_handler, NULL, 0, 0);
+	ast_sorcery_object_field_register(sorcery, SIP_SORCERY_AUTH_TYPE, "type", "",
+			OPT_NOOP_T, 0, 0);
+	ast_sorcery_object_field_register(sorcery, SIP_SORCERY_AUTH_TYPE, "username",
+			"", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_auth, auth_user));
+	ast_sorcery_object_field_register(sorcery, SIP_SORCERY_AUTH_TYPE, "password",
+			"", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_auth, auth_pass));
+	ast_sorcery_object_field_register(sorcery, SIP_SORCERY_AUTH_TYPE, "md5_cred",
+			"", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_auth, md5_creds));
+	ast_sorcery_object_field_register(sorcery, SIP_SORCERY_AUTH_TYPE, "realm",
+			"asterisk", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_auth, realm));
+	ast_sorcery_object_field_register(sorcery, SIP_SORCERY_AUTH_TYPE, "nonce_lifetime",
+			"32", OPT_UINT_T, 0, FLDSET(struct ast_sip_auth, nonce_lifetime));
+	ast_sorcery_object_field_register_custom(sorcery, SIP_SORCERY_AUTH_TYPE, "auth_type",
+			"userpass", auth_type_handler, NULL, 0, 0);
 
 	return 0;
 }

Modified: team/mmichelson/authenticate/res/res_sip/sip_configuration.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/authenticate/res/res_sip/sip_configuration.c?view=diff&rev=381196&r1=381195&r2=381196
==============================================================================
--- team/mmichelson/authenticate/res/res_sip/sip_configuration.c (original)
+++ team/mmichelson/authenticate/res/res_sip/sip_configuration.c Mon Feb 11 12:58:56 2013
@@ -193,24 +193,45 @@
 	return 0;
 }
 
+static void destroy_endpoint_auths(const struct ast_sip_endpoint *endpoint)
+{
+	int i;
+	for (i = 0; i < endpoint->num_auths; ++i) {
+		ast_free((char *) endpoint->sip_auths[i]);
+	}
+	ast_free(endpoint->sip_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);
 	char *val;
 	struct ast_sip_endpoint *endpoint = obj;
+	int num_alloced = 0;
 
 	while ((val = strsep(&auths, ","))) {
-		RAII_VAR(struct ast_sip_auth *, to_add,
-				ast_sorcery_retrieve_by_id(sip_sorcery, "auth", val), ao2_cleanup);
-		if (!to_add) {
-			ast_log(LOG_WARNING, "Unknown auth '%s' specified.\n", val);
-			return -1;
+		if (endpoint->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) {
+				goto failure;
+			}
 		}
-		if (!ao2_link(endpoint->sip_auths, to_add)) {
-			return -1;
+		endpoint->sip_auths[endpoint->num_auths] = ast_strdup(val);
+		if (!endpoint->sip_auths[endpoint->num_auths]) {
+			goto failure;
 		}
-	}
-	return 0;
+		++endpoint->num_auths;
+	}
+	return 0;
+
+failure:
+	destroy_endpoint_auths(endpoint);
+	return -1;
 }
 
 int ast_res_sip_initialize_configuration(void)
@@ -297,15 +318,7 @@
 	if (endpoint->codecs) {
 		ast_format_cap_destroy(endpoint->codecs);
 	}
-	ao2_cleanup(endpoint->sip_auths);
-}
-
-static int auth_cmp(void *obj, void *arg, int flags)
-{
-	struct ast_sip_auth *auth1 = obj;
-	const char *id2 = flags & OBJ_KEY ? arg : ast_sorcery_object_get_id(arg);
-
-	return strcasecmp(ast_sorcery_object_get_id(auth1), id2) ? 0 : CMP_MATCH;
+	destroy_endpoint_auths(endpoint);
 }
 
 void *ast_sip_endpoint_alloc(const char *name)
@@ -319,11 +332,6 @@
 		return NULL;
 	}
 	if (!(endpoint->codecs = ast_format_cap_alloc_nolock())) {
-		ao2_cleanup(endpoint);
-		return NULL;
-	}
-	if (!(endpoint->sip_auths = ao2_container_alloc_list(AO2_ALLOC_OPT_LOCK_NOLOCK,
-					AO2_CONTAINER_ALLOC_OPT_DUPS_REJECT, NULL, auth_cmp))) {
 		ao2_cleanup(endpoint);
 		return NULL;
 	}

Modified: team/mmichelson/authenticate/res/res_sip_authenticator_digest.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/authenticate/res/res_sip_authenticator_digest.c?view=diff&rev=381196&r1=381195&r2=381196
==============================================================================
--- team/mmichelson/authenticate/res/res_sip_authenticator_digest.c (original)
+++ team/mmichelson/authenticate/res/res_sip_authenticator_digest.c Mon Feb 11 12:58:56 2013
@@ -41,7 +41,7 @@
  */
 static int digest_requires_authentication(struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata)
 {
-	return ao2_container_count(endpoint->sip_auths);
+	return endpoint->num_auths > 0;
 }
 
 static void auth_store_cleanup(void *data)
@@ -277,17 +277,14 @@
 /*!
  * \brief astobj2 callback for verifying incoming credentials
  *
- * \param obj The ast_sip_auth to check against
- * \param arg The incoming request
- * \param data A pool to use for the auth server
+ * \param auth The ast_sip_auth to check against
+ * \param rdata The incoming request
+ * \param pool A pool to use for the auth server
  * \return CMP_MATCH on successful authentication
  * \return 0 on failed authentication
  */
-static int verify(void *obj, void *arg, void *data, int flags)
-{
-	struct ast_sip_auth *auth = obj;
-	pj_pool_t *pool = data;
-	pjsip_rx_data *rdata = arg;
+static int verify(struct ast_sip_auth *auth, pjsip_rx_data *rdata, pj_pool_t *pool)
+{
 	pj_status_t authed;
 	int response_code;
 	pjsip_auth_srv auth_server;
@@ -312,15 +309,12 @@
 /*!
  * \brief astobj2 callback for adding digest challenges to responses
  *
- * \param obj The ast_aip_auth to build a challenge from
- * \param arg The response to add the challenge to
- * \return 0
- */
-static int challenge(void *obj, void *arg, void *data, int flags)
-{
-	struct ast_sip_auth *auth = obj;
-	pjsip_tx_data *tdata = arg;
-	pjsip_rx_data *rdata = data;
+ * \param auth The ast_aip_auth to build a challenge from
+ * \param tdata The response to add the challenge to
+ * \param rdata The request the challenge is in response to
+ */
+static void challenge(struct ast_sip_auth *auth, pjsip_tx_data *tdata, pjsip_rx_data *rdata)
+{
 	pj_str_t qop;
 	pj_str_t pj_nonce;
 	pjsip_auth_srv auth_server;
@@ -337,7 +331,29 @@
 	pj_cstr(&pj_nonce, ast_str_buffer(nonce));
 	pj_cstr(&qop, "auth");
 	pjsip_auth_srv_challenge(&auth_server, &qop, &pj_nonce, NULL, PJ_FALSE, tdata);
-	return 0;
+}
+
+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]);
+	}
 }
 
 /*!
@@ -352,16 +368,36 @@
 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 *auth;
-
-	auth = ao2_callback_data(endpoint->sip_auths, 0, verify, rdata, tdata->pool);
-	if (auth) {
-		ao2_ref(auth, -1);
-		return AST_SIP_AUTHENTICATION_SUCCESS;
+	struct ast_sip_auth **auths = ast_calloc(endpoint->num_auths, sizeof(struct ast_sip_auth *));
+	enum ast_sip_check_auth_result res;
+	int i;
+
+	if (!auths) {
+		return AST_SIP_AUTHENTICATION_ERROR;
+	}
+
+	if (retrieve_sip_auths_from_sorcery(endpoint->sip_auths, endpoint->num_auths, auths)) {
+		res = AST_SIP_AUTHENTICATION_ERROR;
+		goto cleanup;
+	}
+
+	for (i = 0; i < endpoint->num_auths; ++i) {
+		if (verify(auths[i], rdata, tdata->pool)) {
+			res = AST_SIP_AUTHENTICATION_SUCCESS;
+			goto cleanup;
+		}
+	}
+
+	for (i = 0; i < endpoint->num_auths; ++i) {
+		challenge(auths[i], tdata, rdata);
 	}
 	
-	ao2_callback_data(endpoint->sip_auths, 0, challenge, tdata, rdata);
-	return AST_SIP_AUTHENTICATION_CHALLENGE;
+	res = AST_SIP_AUTHENTICATION_CHALLENGE;
+
+cleanup:
+	cleanup_auths(auths, endpoint->num_auths);
+	ast_free(auths);
+	return res;
 }
 
 static struct ast_sip_authenticator digest_authenticator = {




More information about the svn-commits mailing list