diff --git a/src/mod/xml_int/mod_xml_radius/00_dialplan_auth.xml b/src/mod/xml_int/mod_xml_radius/00_dialplan_auth.xml
index 4085a68de0..8b8ceae9cd 100644
--- a/src/mod/xml_int/mod_xml_radius/00_dialplan_auth.xml
+++ b/src/mod/xml_int/mod_xml_radius/00_dialplan_auth.xml
@@ -1,7 +1,7 @@
-
+
@@ -18,5 +18,10 @@
+
+
+
+
+
diff --git a/src/mod/xml_int/mod_xml_radius/mod_xml_radius.c b/src/mod/xml_int/mod_xml_radius/mod_xml_radius.c
index 9a5176bcee..2a74f9cff9 100644
--- a/src/mod/xml_int/mod_xml_radius/mod_xml_radius.c
+++ b/src/mod/xml_int/mod_xml_radius/mod_xml_radius.c
@@ -34,6 +34,7 @@
static struct {
switch_memory_pool_t *pool;
switch_xml_t auth_invite_configs;
+ switch_xml_t auth_reg_configs;
switch_xml_t auth_app_configs;
switch_xml_t acct_start_configs;
switch_xml_t acct_end_configs;
@@ -149,7 +150,42 @@ switch_status_t do_config()
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Could not find 'auth_invite' section in config file.\n");
}
- if ((tmp = switch_xml_dup(switch_xml_child(cfg, "auth_app"))) == NULL ) {
+ serv = timeout = deadtime = retries = dict = seq = 0;
+ if ((tmp = switch_xml_dup(switch_xml_child(cfg, "auth_reg"))) != NULL ) {
+ if ( (server = switch_xml_child(tmp, "connection")) != NULL) {
+ for (param = switch_xml_child(server, "param"); param; param = param->next) {
+ char *var = (char *) switch_xml_attr_soft(param, "name");
+ if ( strncmp(var, "authserver", 10) == 0 ) {
+ serv = 1;
+ } else if ( strncmp(var, "radius_timeout", 14) == 0 ) {
+ timeout = 1;
+ } else if ( strncmp(var, "radius_deadtime", 15) == 0 ) {
+ deadtime = 1;
+ } else if ( strncmp(var, "radius_retries", 14) == 0 ) {
+ retries = 1;
+ } else if ( strncmp(var, "dictionary", 10) == 0 ) {
+ dict = 1;
+ } else if ( strncmp(var, "seqfile", 7) == 0 ) {
+ seq = 1;
+ }
+ }
+
+ if ( serv && timeout && deadtime && retries && dict && seq ) {
+ globals.auth_reg_configs = tmp;
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing a require section for radius connections\n");
+ goto err;
+ }
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not find 'connection' section for auth_invite\n");
+ goto err;
+ }
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Could not find 'auth_invite' section in config file.\n");
+ }
+
+ serv = timeout = deadtime = retries = dict = seq = 0;
+ if ((tmp = switch_xml_dup(switch_xml_child(cfg, "auth_app"))) != NULL ) {
if ( (server = switch_xml_child(tmp, "connection")) != NULL) {
for (param = switch_xml_child(server, "param"); param; param = param->next) {
char *var = (char *) switch_xml_attr_soft(param, "name");
@@ -182,7 +218,8 @@ switch_status_t do_config()
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Could not find 'auth_app' section in config file.\n");
}
- if (( tmp = switch_xml_dup(switch_xml_child(cfg, "acct_start"))) == NULL ) {
+ serv = timeout = deadtime = retries = dict = seq = 0;
+ if (( tmp = switch_xml_dup(switch_xml_child(cfg, "acct_start"))) != NULL ) {
if ( (server = switch_xml_child(tmp, "connection")) != NULL) {
for (param = switch_xml_child(server, "param"); param; param = param->next) {
char *var = (char *) switch_xml_attr_soft(param, "name");
@@ -215,7 +252,8 @@ switch_status_t do_config()
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Could not find 'acct_start' section in config file.\n");
}
- if (( tmp = switch_xml_dup(switch_xml_child(cfg, "acct_end"))) == NULL ) {
+ serv = timeout = deadtime = retries = dict = seq = 0;
+ if (( tmp = switch_xml_dup(switch_xml_child(cfg, "acct_end"))) != NULL ) {
if ( (server = switch_xml_child(tmp, "connection")) != NULL) {
for (param = switch_xml_child(server, "param"); param; param = param->next) {
char *var = (char *) switch_xml_attr_soft(param, "name");
@@ -281,8 +319,11 @@ switch_status_t mod_xml_radius_add_params(switch_core_session_t *session, switch
char *var = (char *) switch_xml_attr(param, "name");
char *vend = (char *) switch_xml_attr(param, "vendor");
char *variable = (char *) switch_xml_attr(param, "variable");
+ char *variable_secondary = (char *) switch_xml_attr(param, "variable_secondary");
+ char *val_default = (char *) switch_xml_attr(param, "default");
char *format = (char *) switch_xml_attr(param, "format");
-
+ char *other_leg = (char *) switch_xml_attr(param, "other_leg");
+
attribute = rc_dict_findattr(handle, var);
if ( attribute == NULL ) {
@@ -375,8 +416,36 @@ switch_status_t mod_xml_radius_add_params(switch_core_session_t *session, switch
}
} else {
+ if ( format == NULL ) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing format attribute for %s variable\n", variable);
+ goto err;
+ }
+
if ( attribute->type == 0 ) {
- av_value = switch_mprintf(format, switch_channel_get_variable(channel, variable));
+ const char *val = NULL;
+
+ if ( other_leg ) {
+ val = switch_channel_get_variable_partner(channel, variable);
+ if ( val == NULL && variable_secondary != NULL) {
+ val = switch_channel_get_variable_partner(channel, variable_secondary);
+ }
+ } else {
+ val = switch_channel_get_variable(channel, variable);
+ if ( val == NULL && variable_secondary != NULL) {
+ val = switch_channel_get_variable(channel, variable_secondary);
+ }
+ }
+
+ if ( val == NULL && val_default != NULL) {
+ av_value = switch_mprintf(format, val_default);
+ } else {
+ av_value = switch_mprintf(format, val);
+ }
+
+ if ( GLOBAL_DEBUG ) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: value: %s\n", (char *) av_value);
+ }
+
if (rc_avpair_add(handle, send, attr_num, av_value, -1, vend_num) == NULL) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: failed to add option with val '%s' to handle\n", (char *) av_value);
goto err;
@@ -487,7 +556,10 @@ switch_xml_t mod_xml_radius_auth_invite(switch_event_t *params) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: starting invite authentication\n");
}
- mod_xml_radius_new_handle(&new_handle, globals.auth_invite_configs);
+ if ( mod_xml_radius_new_handle(&new_handle, globals.auth_invite_configs) != SWITCH_STATUS_SUCCESS ) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to load radius handle\n");
+ goto err;
+ }
if ( new_handle == NULL ) {
goto err;
@@ -565,6 +637,100 @@ switch_xml_t mod_xml_radius_auth_invite(switch_event_t *params) {
return NULL;
}
+switch_xml_t mod_xml_radius_auth_reg(switch_event_t *params) {
+ int result = 0, param_idx = 0;
+ VALUE_PAIR *send = NULL, *recv = NULL, *service_vp = NULL;
+ char msg[512 * 10 + 1] = {0};
+ uint32_t service = PW_AUTHENTICATE_ONLY;
+ rc_handle *new_handle = NULL;
+ switch_xml_t fields, xml, dir, dom, usr, vars, var;
+ char name[512], value[512], *strtmp;
+
+ if (GLOBAL_DEBUG ) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: starting registration authentication\n");
+ }
+
+ if ( mod_xml_radius_new_handle(&new_handle, globals.auth_invite_configs) != SWITCH_STATUS_SUCCESS ) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to load radius handle\n");
+ goto err;
+ }
+
+ if ( new_handle == NULL ) {
+ goto err;
+ }
+
+ if ((fields = switch_xml_child(globals.auth_reg_configs, "fields")) == NULL ) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not find 'fields' section in config file.\n");
+ goto err;
+ }
+
+ if ( mod_xml_radius_add_params(NULL, params, new_handle, &send, fields) != SWITCH_STATUS_SUCCESS ) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to add params to rc_handle\n");
+ goto err;
+ }
+
+ if (rc_avpair_add(new_handle, &send, PW_SERVICE_TYPE, &service, -1, 0) == NULL) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: failed to add option to handle\n");
+ goto err;
+ }
+
+ result = rc_auth(new_handle, 0, send, &recv, msg);
+
+ if ( GLOBAL_DEBUG ){
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: result(RC=%d) %s \n", result, msg);
+ }
+
+ if ( result != 0 ) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: Failed to authenticate\n");
+ goto err;
+ }
+
+ xml = switch_xml_new("document");
+ switch_xml_set_attr_d(xml, "type", "freeswitch/xml");
+ dir = switch_xml_add_child_d(xml, "section", 0);
+ switch_xml_set_attr_d(dir, "name", "directory");
+ dom = switch_xml_add_child_d(dir, "domain", 0);
+ switch_xml_set_attr_d(dom, "name", switch_event_get_header(params, "domain"));
+ usr = switch_xml_add_child_d(dom, "user", 0);
+ vars = switch_xml_add_child_d(usr, "variables", 0);
+
+ switch_xml_set_attr_d(usr, "id", switch_event_get_header(params, "user"));
+
+ service_vp = recv;
+ while (service_vp != NULL) {
+ rc_avpair_tostr(new_handle, service_vp, name, 512, value, 512);
+ if ( GLOBAL_DEBUG )
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "\tattribute (%s)[%s] found in radius packet\n", name, value);
+ var = switch_xml_add_child_d(vars, "variable", param_idx++);
+ strtmp = strdup(name);
+ switch_xml_set_attr_d(var, "name", strtmp);
+ free(strtmp);
+ strtmp = strdup(value);
+ switch_xml_set_attr_d(var, "value", strtmp);
+ free(strtmp);
+ service_vp = service_vp->next;
+ }
+
+ if ( GLOBAL_DEBUG ) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "XML: %s \n", switch_xml_toxml(xml, 1));
+ }
+
+ rc_avpair_free(recv);
+ rc_destroy(new_handle);
+ return xml;
+ err:
+ if ( recv ) {
+ rc_avpair_free(recv);
+ recv = NULL;
+ }
+ if ( new_handle ) {
+ rc_destroy(new_handle);
+ new_handle = NULL;
+ }
+
+ return NULL;
+}
+
static switch_xml_t mod_xml_radius_directory_search(const char *section, const char *tag_name, const char *key_name, const char *key_value,
switch_event_t *params, void *user_data)
{
@@ -584,9 +750,11 @@ static switch_xml_t mod_xml_radius_directory_search(const char *section, const c
if ( auth_method == NULL) {
return NULL;
}
-
+
if ( strncmp( "INVITE", auth_method, 6) == 0) {
xml = mod_xml_radius_auth_invite(params);
+ } else if ( strncmp( "REGISTER", auth_method, 8) == 0) {
+ xml = mod_xml_radius_auth_reg(params);
} else {
xml = NULL;
}
@@ -622,6 +790,7 @@ switch_status_t mod_xml_radius_check_conditions(switch_channel_t *channel, switc
}
if ( switch_regex_match( switch_channel_get_variable(channel, channel_var), regex) != SWITCH_STATUS_SUCCESS) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Didn't match: %s == %s \n", switch_channel_get_variable(channel, channel_var), regex);
all_matched = 0;
}
}
@@ -643,6 +812,7 @@ switch_status_t mod_xml_radius_accounting_start(switch_core_session_t *session){
if (GLOBAL_DEBUG ) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: starting accounting start\n");
+ switch_core_session_execute_application(session, "info", NULL);
}
/* If there are conditions defined, and none of them pass, then skip this accounting */
@@ -651,7 +821,10 @@ switch_status_t mod_xml_radius_accounting_start(switch_core_session_t *session){
goto end;
}
- mod_xml_radius_new_handle(&new_handle, globals.acct_start_configs);
+ if ( mod_xml_radius_new_handle(&new_handle, globals.acct_start_configs) != SWITCH_STATUS_SUCCESS ) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to load radius handle\n");
+ goto end;
+ }
if ((fields = switch_xml_child(globals.acct_start_configs, "fields")) == NULL ) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not find 'fields' section in config file.\n");
@@ -700,7 +873,10 @@ switch_status_t mod_xml_radius_accounting_end(switch_core_session_t *session){
goto end;
}
- mod_xml_radius_new_handle(&new_handle, globals.acct_end_configs);
+ if ( mod_xml_radius_new_handle(&new_handle, globals.acct_end_configs) != SWITCH_STATUS_SUCCESS ) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to load radius handle\n");
+ goto end;
+ }
if ((fields = switch_xml_child(globals.acct_end_configs, "fields")) == NULL ) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not find 'fields' section in config file.\n");
@@ -724,8 +900,10 @@ switch_status_t mod_xml_radius_accounting_end(switch_core_session_t *session){
}
end:
- rc_destroy(new_handle);
-
+ if ( new_handle) {
+ rc_destroy(new_handle);
+ }
+
return SWITCH_STATUS_SUCCESS;
}
diff --git a/src/mod/xml_int/mod_xml_radius/xml_radius.conf.xml b/src/mod/xml_int/mod_xml_radius/xml_radius.conf.xml
index cb0ec3a01a..eb3070c929 100644
--- a/src/mod/xml_int/mod_xml_radius/xml_radius.conf.xml
+++ b/src/mod/xml_int/mod_xml_radius/xml_radius.conf.xml
@@ -22,10 +22,48 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -36,7 +74,7 @@
-
+
@@ -67,18 +105,19 @@
-
-
+
+
+
-
+
@@ -92,22 +131,23 @@
-
-
+
+
+
-
+