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

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Sat Mar 2 15:11:35 CST 2013


Author: mmichelson
Date: Sat Mar  2 15:11:31 2013
New Revision: 382366

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=382366
Log:
Create a temporary means of performing outbound auth on out-of-dialog requests.

This creates a PJSIP module whose job is to intercept 401 and 407 responses
and send follow-up authentication requests. There are a few issues here:

1) Endpoints have to be looked up on 401 and 407 responses
2) Authentication is pretty inflexible. We only ever will send authentication
   headers on 401 or 407 responses. We'll enver attempt to put auth info into
   initial requests.
3) We have to hope people are sending stateful requests instead of stateless
   ones at the moment. Once it's all handled in ast_sip_send_request, it'll
   be much more controllable.

The actual way forward will be to do what is specified in the large XXX comment
block in ast_sip_send_request.


Added:
    team/mmichelson/outbound_auth/res/res_sip/sip_outbound_auth.c   (with props)
Modified:
    team/mmichelson/outbound_auth/include/asterisk/res_sip.h
    team/mmichelson/outbound_auth/res/res_sip.c
    team/mmichelson/outbound_auth/res/res_sip.exports.in
    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=382366&r1=382365&r2=382366
==============================================================================
--- team/mmichelson/outbound_auth/include/asterisk/res_sip.h (original)
+++ team/mmichelson/outbound_auth/include/asterisk/res_sip.h Sat Mar  2 15:11:31 2013
@@ -476,6 +476,14 @@
 int ast_sip_initialize_sorcery_auth(struct ast_sorcery *sorcery);
 
 /*!
+ * \brief Initialize outbound authentication support
+ *
+ * \retval 0 Success
+ * \retval non-zero Failure
+ */
+int ast_sip_initialize_outbound_authentication(void);
+
+/*!
  * \brief Initialize the distributor module
  *
  * The distributor module is responsible for taking an incoming
@@ -669,6 +677,16 @@
 		pjsip_rx_data *rdata, pjsip_tx_data *tdata);
  
 /*!
+ * \brief Set authentication credentials for outbound authentication
+ *
+ * \param auth_sess The client auth session to set credentials for
+ * \param endpoint Endpoint from whom to get credentials
+ * \retval 0 Success
+ * \retval non-zero Failure
+ */
+int ast_sip_set_outbound_authentication_credentials(pjsip_auth_clt_sess *auth_sess, struct ast_sip_endpoint *endpoint);
+
+/*!
  * \brief Determine the endpoint that has sent a SIP message
  *
  * This will call into each of the registered endpoint identifiers'

Modified: team/mmichelson/outbound_auth/res/res_sip.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/outbound_auth/res/res_sip.c?view=diff&rev=382366&r1=382365&r2=382366
==============================================================================
--- team/mmichelson/outbound_auth/res/res_sip.c (original)
+++ team/mmichelson/outbound_auth/res/res_sip.c Sat Mar  2 15:11:31 2013
@@ -130,6 +130,41 @@
 	return registered_authenticator->check_authentication(endpoint, rdata, tdata);
 }
 
+int ast_sip_set_outbound_authentication_credentials(pjsip_auth_clt_sess *auth_sess, 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 res = 0;
+	int i;
+
+	if (ast_sip_retrieve_auths(endpoint->sip_outbound_auths, endpoint->num_outbound_auths, auths)) {
+		res = -1;
+		goto cleanup;
+	}
+
+	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(auth_sess, endpoint->num_outbound_auths, auth_creds);
+
+cleanup:
+	ast_sip_cleanup_auths(auths, endpoint->num_outbound_auths);
+	return res;
+}
+
 struct endpoint_identifier_list {
 	struct ast_sip_endpoint_identifier *identifier;
 	AST_RWLIST_ENTRY(endpoint_identifier_list) list;
@@ -556,6 +591,11 @@
 		goto error;
 	}
 
+	if (ast_sip_initialize_outbound_authentication()) {
+		ast_log(LOG_ERROR, "Failed to initialize outbound authentication. Aborting load\n");
+		goto error;
+	}
+
 	ast_res_sip_init_options_handling(0);
 
 return AST_MODULE_LOAD_SUCCESS;

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=382366&r1=382365&r2=382366
==============================================================================
--- team/mmichelson/outbound_auth/res/res_sip.exports.in (original)
+++ team/mmichelson/outbound_auth/res/res_sip.exports.in Sat Mar  2 15:11:31 2013
@@ -14,6 +14,7 @@
 		LINKER_SYMBOL_PREFIXast_sip_authenticate_request;
 		LINKER_SYMBOL_PREFIXast_sip_get_authentication_credentials;
 		LINKER_SYMBOL_PREFIXast_sip_check_authentication;
+		LINKER_SYMBOL_PREFIXast_sip_set_outbound_authentication_credentials;
 		LINKER_SYMBOL_PREFIXast_sip_add_digest_to_challenge;
 		LINKER_SYMBOL_PREFIXast_sip_identify_endpoint;
 		LINKER_SYMBOL_PREFIXast_sip_add_header;

Added: team/mmichelson/outbound_auth/res/res_sip/sip_outbound_auth.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/outbound_auth/res/res_sip/sip_outbound_auth.c?view=auto&rev=382366
==============================================================================
--- team/mmichelson/outbound_auth/res/res_sip/sip_outbound_auth.c (added)
+++ team/mmichelson/outbound_auth/res/res_sip/sip_outbound_auth.c Sat Mar  2 15:11:31 2013
@@ -1,0 +1,73 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2013, Digium, Inc.
+ *
+ * Mark Michelson <mmichelson at digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+#include "asterisk.h"
+#undef bzero
+#define bzero bzero
+#include "pjsip.h"
+
+#include "asterisk/res_sip.h"
+
+static pj_bool_t outbound_auth(pjsip_rx_data *rdata)
+{
+	RAII_VAR(struct ast_sip_endpoint *, endpoint, NULL, ao2_cleanup);
+	pjsip_transaction *tsx;
+	pjsip_auth_clt_sess auth_sess;
+	pjsip_tx_data *tdata;
+	if (rdata->msg_info.msg->line.status.code != 401 &&
+			rdata->msg_info.msg->line.status.code != 407) {
+		/* Doesn't pertain to us. Move on */
+		return PJ_FALSE;
+	}
+
+	/* Endpoint identification is not automatically done on responses,
+	 * so we have to do it ourselves here
+	 */
+	endpoint = ast_sip_identify_endpoint(rdata);
+	if (endpoint == NULL) {
+		ast_log(LOG_WARNING, "Cannot respond to authentication challenge because"
+				"endpoint could not be identified\n");
+		return PJ_FALSE;
+	}
+
+	tsx = pjsip_rdata_get_tsx(rdata);
+	if (!tsx) {
+		ast_log(LOG_WARNING, "Cannot respond to authentication challenge because"
+				"initial request was sent statelessly\n");
+		return PJ_FALSE;
+	}
+	ast_sip_set_outbound_authentication_credentials(&auth_sess, endpoint);
+	pjsip_auth_clt_reinit_req(&auth_sess, rdata, tsx->last_tx, &tdata);
+	pjsip_endpt_send_request(ast_sip_get_pjsip_endpoint(), tdata, -1, NULL, NULL);
+	return PJ_TRUE;
+}
+
+/* XXX This module is intended to be a temporary solution for doing
+ * out-of-dialog outbound authentication. Once endpoint location
+ * is merged, then out of dialog outbound authentication will be
+ * handled entirely within the ast_sip_send_request() function.
+ */
+static pjsip_module outbound_auth_mod = {
+	.name = {"Outbound Authentication", 19},
+	.priority = PJSIP_MOD_PRIORITY_APPLICATION - 1,
+	.on_rx_response = outbound_auth,
+};
+
+int ast_sip_initialize_outbound_authentication(void) {
+	return ast_sip_register_service(&outbound_auth_mod);
+}

Propchange: team/mmichelson/outbound_auth/res/res_sip/sip_outbound_auth.c
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: team/mmichelson/outbound_auth/res/res_sip/sip_outbound_auth.c
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: team/mmichelson/outbound_auth/res/res_sip/sip_outbound_auth.c
------------------------------------------------------------------------------
    svn:mime-type = text/plain

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=382366&r1=382365&r2=382366
==============================================================================
--- team/mmichelson/outbound_auth/res/res_sip_session.c (original)
+++ team/mmichelson/outbound_auth/res/res_sip_session.c Sat Mar  2 15:11:31 2013
@@ -581,38 +581,6 @@
 	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);
@@ -628,7 +596,7 @@
 		return NULL;
 	}
 
-	if (set_auth_credentials(dlg, endpoint)) {
+	if (ast_sip_set_outbound_authentication_credentials(&dlg->auth_sess, endpoint)) {
 		pjsip_dlg_terminate(dlg);
 		return NULL;
 	}




More information about the asterisk-commits mailing list