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;
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");
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");
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");
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 ) {
}
} 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;
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;
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)
{
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;
}
}
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;
}
}
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 */
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");
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");
}
end:
- rc_destroy(new_handle);
-
+ if ( new_handle) {
+ rc_destroy(new_handle);
+ }
+
return SWITCH_STATUS_SUCCESS;
}
<param vendor="Cisco" name="Cisco-AVPair" variable="ip" format="src-gw-ip=%s"/>
<param vendor="Cisco" name="Cisco-AVPair" variable="sip_from_user" format="src-gw-name=%s"/>
<param vendor="Cisco" name="h323-conf-id" variable="Core-UUID" format="%s"/>
+ <param vendor="Cisco" name="Cisco-AVPair" variable="ip" format="number"/>
<param name="Called-Station-Id" variable="sip_to_user" format="%s"/>
<param name="Calling-Station-Id" variable="sip_from_user" format="%s"/>
+ <param name="User-Name" variable="sip_from_user" format="%s"/>
+ <param name="Digest-Response" variable="sip_auth_response" format="%s"/>
+ <param name="Digest-Realm" variable="sip_auth_realm" format="%s"/>
+ <param name="Digest-Nonce" variable="sip_auth_nonce" format="%s"/>
+ <param name="Digest-Username" variable="sip_auth_username" format="%s"/>
+ <param name="Digest-URI" variable="sip_auth_uri" format="%s"/>
+ <param name="Digest-Method" variable="sip_auth_method" format="%s"/>
+ <param name="Digest-Algorithm" variable="sip_auth_method" format="MD5"/>
+ <param name="Digest-Qop" variable="sip_auth_qop" format="%s"/>
+ <param name="Digest-CNonce" variable="sip_auth_cnonce" format="%s"/>
+ <param name="Digest-Nonce-Count" variable="sip_auth_nc" format="%s"/>
</fields>
</auth_invite>
+ <auth_reg>
+ <connection name="testing">
+ <param name="authserver" value="127.0.0.1:1812:testing123"/>
+ <param name="radius_timeout" value="10"/>
+ <param name="radius_retries" value="2"/>
+ <param name="radius_deadtime" value="0"/>
+ <param name="dictionary" value="/usr/local/src/freeswitch/src/mod/xml_int/mod_xml_radius/dictionaries/dictionary"/>
+ <param name="seqfile" value="/var/run/radius.seq"/>
+ </connection>
+ <fields>
+ <param vendor="Cisco" name="Cisco-AVPair" variable="ip" format="user"/>
+ <param vendor="Cisco" name="Cisco-AVPair" variable="ip" format="src-gw-ip=%s"/>
+ <param vendor="Cisco" name="Cisco-AVPair" variable="sip_from_user" format="src-gw-name=%s"/>
+ <param name="User-Name" variable="sip_from_user" format="%s"/>
+ <param name="Digest-Response" variable="sip_auth_response" format="%s"/>
+ <param name="Digest-Realm" variable="sip_auth_realm" format="%s"/>
+ <param name="Digest-Nonce" variable="sip_auth_nonce" format="%s"/>
+ <param name="Digest-Username" variable="sip_auth_username" format="%s"/>
+ <param name="Digest-URI" variable="sip_auth_uri" format="%s"/>
+ <param name="Digest-Method" variable="sip_auth_method" format="%s"/>
+ <param name="Digest-Algorithm" variable="sip_auth_method" format="MD5"/>
+ <param name="Digest-Qop" variable="sip_auth_qop" format="%s"/>
+ <param name="Digest-CNonce" variable="sip_auth_cnonce" format="%s"/>
+ <param name="Digest-Nonce-Count" variable="sip_auth_nc" format="%s"/>
+ </fields>
+ </auth_reg>
<auth_app>
<connection name="testing">
<param name="authserver" value="127.0.0.1:1812:testing123"/>
<param name="seqfile" value="/var/run/radius.seq"/>
</connection>
<fields>
- <param vendor="Cisco" name="Cisco-AVPair" variable="sip_network_ip" format="src-gw-ip=%s"/>
+ <param vendor="Cisco" name="Cisco-AVPair" variable="sip_from_host" format="src-gw-ip=%s"/>
<param vendor="Cisco" name="Cisco-AVPair" variable="sip_from_user" format="src-gw-name=%s"/>
<param vendor="Cisco" name="h323-conf-id" variable="Core-UUID" format="%s"/>
<param name="Called-Station-Id" variable="sip_to_user" format="%s"/>
<fields>
<param vendor="Cisco" name="Cisco-AVPair" variable="sip_from_host" format="src-gw-ip=%s"/>
<param vendor="Cisco" name="Cisco-AVPair" variable="sip_from_user" format="src-gw-name=%s"/>
- <param vendor="Cisco" name="Cisco-AVPair" variable="sip_to_host" format="dst-gw-ip=%s"/>
- <param vendor="Cisco" name="h323-conf-id" variable="uuid" format="%s"/>
+ <param vendor="Cisco" name="Cisco-AVPair" variable="sip_to_host" format="dst-gw-ip=%s"/>
+ <param vendor="Cisco" name="h323-conf-id" variable_secondary="uuid" variable="originating_leg_uuid" format="%s"/>
<param vendor="Cisco" name="h323-setup-time"/>
<param vendor="Cisco" name="h323-connect-time"/>
+ <param vendor="Cisco" name="h323-call-origin" variable="h323-call-origin" default="answer" format="%s"/>
<param name="Called-Station-Id" variable="sip_to_user" format="%s"/>
<param name="Calling-Station-Id" variable="sip_from_user" format="%s"/>
</fields>
- <conditions>
+<!-- <conditions>
<condition>
- <param var="direction" regex="inbound"/>
- </condition>
- </conditions>
+ <param var="direction" regex="^outbound$"/>
+ </condition>
+ </conditions> -->
</acct_start>
<acct_end>
<connection name="testing">
<fields>
<param vendor="Cisco" name="Cisco-AVPair" variable="sip_from_host" format="src-gw-ip=%s"/>
<param vendor="Cisco" name="Cisco-AVPair" variable="sip_from_user" format="src-gw-name=%s"/>
- <param vendor="Cisco" name="Cisco-AVPair" variable="sip_to_host" format="dst-gw-ip=%s"/>
- <param vendor="Cisco" name="h323-conf-id" variable="uuid" format="%s"/>
+ <param vendor="Cisco" name="Cisco-AVPair" variable="sip_to_host" format="dst-gw-ip=%s"/>
+ <param vendor="Cisco" name="h323-conf-id" variable_secondary="uuid" variable="originating_leg_uuid" format="%s"/>
<param vendor="Cisco" name="h323-setup-time"/>
<param vendor="Cisco" name="h323-connect-time"/>
<param vendor="Cisco" name="h323-disconnect-time"/>
<param vendor="Cisco" name="h323-disconnect-cause"/>
+ <param vendor="Cisco" name="h323-call-origin" variable="h323-call-origin" format="%s" default="answer"/>
<param name="Called-Station-Id" variable="sip_to_user" format="%s"/>
<param name="Acct-Session-Time" variable="billsec" format="%s"/>
<param name="Calling-Station-Id" variable="sip_from_user" format="%s"/>
<param vendor="Cisco" name="Cisco-AVPair" variable="sip_from_user" format="src-number-out=%s"/>
<param vendor="Cisco" name="Cisco-AVPair" variable="sip_to_user" format="dst-number-out=%s"/>
</fields>
- <conditions>
+<!-- <conditions>
<condition>
- <param var="direction" regex="inbound"/>
- </condition>
- </conditions>
+ <param var="direction" regex="^outbound$"/>
+ </condition>
+ </conditions> -->
</acct_end>
</configuration>