[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