[svn-commits] mmichelson: branch mmichelson/authenticate r381056 - /team/mmichelson/authent...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Thu Feb 7 13:40:31 CST 2013


Author: mmichelson
Date: Thu Feb  7 13:40:27 2013
New Revision: 381056

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=381056
Log:
Add a response ID to all challenges.

This way, if we verify credentials on an incoming INVITE, we
can destroy all stored challenges that were sent in the 401 response.

The one thing still missing is to clean up unverified challenges after
a certain time period.


Modified:
    team/mmichelson/authenticate/res/res_sip_authenticator_digest.c

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=381056&r1=381055&r2=381056
==============================================================================
--- team/mmichelson/authenticate/res/res_sip_authenticator_digest.c (original)
+++ team/mmichelson/authenticate/res/res_sip_authenticator_digest.c Thu Feb  7 13:40:27 2013
@@ -37,9 +37,12 @@
 
 struct ao2_container *challenges;
 
+static int response_id_counter;
+
 struct challenge {
 	char nonce[AST_UUID_STR_LEN];
 	const char *realm;
+	unsigned int response_id;
 };
 
 static int challenge_hash(const void *obj, int flags)
@@ -65,7 +68,7 @@
 	ast_free((char *) chall->realm);
 }
 
-static struct challenge *create_challenge(struct ast_sip_auth *auth)
+static struct challenge *create_challenge(struct ast_sip_auth *auth, int response_id)
 {
 	struct challenge *chall = ao2_alloc(sizeof(*chall), challenge_destructor);
 	struct ast_uuid *uuid;
@@ -86,8 +89,22 @@
 		ao2_cleanup(chall);
 		return NULL;
 	}
+	chall->response_id = response_id;
 
 	return chall;
+}
+
+static int match_response_id(void *obj, void *arg, int flags)
+{
+	struct challenge *chall = obj;
+	int *response_id = arg;
+
+	return chall->response_id == *response_id ? CMP_MATCH : 0;
+}
+
+static void remove_challenges(int response_id)
+{
+	ao2_callback(challenges, OBJ_MULTIPLE | OBJ_UNLINK | OBJ_NODATA, match_response_id, &response_id);
 }
 
 /*!
@@ -295,6 +312,12 @@
 
 	remove_auth();
 
+	if (authed) {
+		/* Hey neat! They managed to authenticate. Now we need to delete
+		 * all challenges with the winning challenge's response ID
+		 */
+		remove_challenges(chall->response_id);
+	}
 	return authed == PJ_SUCCESS ? CMP_MATCH : 0;
 }
 
@@ -305,7 +328,7 @@
  * \param arg The response to add the challenge to
  * \return 0
  */
-static int challenge(void *obj, void *arg, int flags)
+static int challenge(void *obj, void *arg, void *data, int flags)
 {
 	struct ast_sip_auth *auth = obj;
 	RAII_VAR(struct challenge *, chall, NULL, ao2_cleanup);
@@ -313,8 +336,9 @@
 	pj_str_t qop;
 	pj_str_t nonce;
 	pjsip_auth_srv auth_server;
-
-	chall = create_challenge(auth);
+	int *response_id = data;
+
+	chall = create_challenge(auth, *response_id);
 	if (!chall) {
 		return 0;
 	}
@@ -340,6 +364,7 @@
 		pjsip_rx_data *rdata, pjsip_tx_data *tdata)
 {
 	struct ast_sip_auth *auth;
+	int response_id;
 
 	auth = ao2_callback_data(endpoint->sip_auths, 0, verify, rdata, tdata->pool);
 	if (auth) {
@@ -347,7 +372,8 @@
 		return AST_SIP_AUTHENTICATION_SUCCESS;
 	}
 	
-	ao2_callback(endpoint->sip_auths, 0, challenge, tdata);
+	response_id = ast_atomic_fetchadd_int(&response_id_counter, +1);
+	ao2_callback_data(endpoint->sip_auths, 0, challenge, tdata, &response_id);
 	return AST_SIP_AUTHENTICATION_CHALLENGE;
 }
 




More information about the svn-commits mailing list