[asterisk-commits] mmichelson: branch mmichelson/authenticate r381196 - in /team/mmichelson/auth...
SVN commits to the Asterisk project
asterisk-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 asterisk-commits
mailing list