switch_status_t mod_xml_radius_new_handle(rc_handle **new_handle, switch_xml_t xml) { switch_xml_t server, param; *new_handle = rc_new(); if ( *new_handle == NULL ) { goto err; } *new_handle = rc_config_init(*new_handle); if ( *new_handle == NULL ) { goto err; } if (rc_add_config(*new_handle, "auth_order", "radius", "mod_radius_cdr.c", 0) != 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error adding auth_order\n"); goto err; } if ((server = switch_xml_child(xml, "connection")) == NULL ) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not find 'connection' section in config file.\n"); goto err; } for (param = switch_xml_child(server, "param"); param; param = param->next) { char *var = (char *) switch_xml_attr_soft(param, "name"); char *val = (char *) switch_xml_attr_soft(param, "value"); if ( GLOBAL_DEBUG ) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Attempting to add param '%s' with value '%s' \n", var, val); } if (strncmp(var, "dictionary", 10) == 0) { rc_read_dictionary(*new_handle, val); } else if (rc_add_config(*new_handle, var, val, "mod_xml_radius", 0) != 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error adding param '%s' with value '%s' \n", var, val); goto err; } } return SWITCH_STATUS_SUCCESS; err: if ( *new_handle ) { rc_destroy( *new_handle ); *new_handle = NULL; } return SWITCH_STATUS_GENERR; }
int radius_auth(switch_channel_t *channel, char* called_number, char* username, char* password , char* auth_result/*, char* biling_model, char* credit_amount, char* currency, char* preffered_lang*/) { int result = OK_RC; VALUE_PAIR *send = NULL; VALUE_PAIR *received = NULL; VALUE_PAIR *service_vp; DICT_ATTR *pda; CONFIG_VSAS* PCONFIGVSAS = NULL; char *default_realm = NULL; rc_handle *rh = NULL; int attrid =0; char msg[STR_LENGTH * 10 + 1]; char username_realm[STR_LENGTH + 1]; char value[STR_LENGTH + 1]; int integer; memset(msg, 0, STR_LENGTH * 10); memset(username_realm, 0, STR_LENGTH); send = NULL; do { #if EMBENDED_CONFIG CONFIG_CLIENT* PCONFIGCLIENT = CONFIGCLIENT; rh = rc_new(); if (rh == NULL) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ERROR: Failed to allocate initial structure.\n"); result = ERROR_RC; break; } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "allocate initial structure.\n"); /* Initialize the config structure */ rh = rc_config_init(rh); if (rh == NULL) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,"ERROR: Failed to initialze configuration.\n"); result = ERROR_RC; break; } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,"initialzed configuration.\n"); while(PCONFIGCLIENT) { //if (rc_add_config(rh, "auth_order", "radius", "config", 0) != 0) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "set %s := %s.\n", PCONFIGCLIENT->name, PCONFIGCLIENT->value); if (rc_add_config(rh, PCONFIGCLIENT->name, PCONFIGCLIENT->value, "config", 0) != 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ERROR: Unable to set %s := %s.\n", PCONFIGCLIENT->name, PCONFIGCLIENT->value); result = ERROR_RC; break; } PCONFIGCLIENT = PCONFIGCLIENT->pNext; } if (result == ERROR_RC) break; #else if ((rh = rc_read_config(!rc_config_file ? RC_CONFIG_FILE : rc_config_file)) == NULL) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error loading radius config file\n"); result = ERROR_RC; break; } #endif if (rc_read_dictionary(rh, rc_conf_str(rh, "dictionary")) != 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error loading radius dictionary\n"); result = ERROR_RC; break; } default_realm = rc_conf_str(rh, "default_realm"); if (default_realm == NULL) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "default_realm is null object.\n"); result = ERROR_RC; break; } strncpy(username_realm, username, sizeof(username_realm)); if ((strchr(username_realm, '@') == NULL) && default_realm && (*default_realm != '\0')) { strncat(username_realm, "@", sizeof(username_realm)-strlen(username_realm)-1); strncat(username_realm, default_realm, sizeof(username_realm)-strlen(username_realm)-1); } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "... radius: User-Name: %s\n", username); if (rc_avpair_add(rh, &send, PW_USER_NAME, username_realm, -1, 0)== NULL) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "An Error occured during rc_avpair_add : username\n"); result = ERROR_RC; break; } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "... radius: User-Password: %s\n", password); if (rc_avpair_add(rh, &send, PW_USER_PASSWORD, password, -1, 0) == NULL) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "An Error occured during rc_avpair_add : password\n"); result = ERROR_RC; break; } if (!called_number || strcmp(called_number, "") == 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "... radius: Called-station-Id is empty, ignoring...\n"); } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "... radius: Called-station-Id: %s\n", called_number); if (rc_avpair_add(rh, &send, 30, called_number, -1, 0) == NULL) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "An Error occured during rc_avpair_add : Called-station-Id\n"); result = ERROR_RC; break; } } PCONFIGVSAS = CONFIGVSAS; while(PCONFIGVSAS) { if (PCONFIGVSAS->direction == 1) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Handle attribute: %s\n", PCONFIGVSAS->name ); memset(value, 0, STR_LENGTH); GetValue(channel, PCONFIGVSAS, value); if (PCONFIGVSAS->pec != 0) attrid = PCONFIGVSAS->id | (PCONFIGVSAS->pec << 16); else attrid = PCONFIGVSAS->id ; pda = rc_dict_getattr(rh, attrid); if (pda == NULL) { result = ERROR_RC; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unknown attribute: key:%s, not found in dictionary\n", PCONFIGVSAS->name); break; } if (PCONFIGVSAS->pec != 0 && rc_dict_getvend(rh, PCONFIGVSAS->pec) == NULL) { result = ERROR_RC; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unknown vendor specific id: key:%s, id:%dnot found in dictionary\n", PCONFIGVSAS->name, PCONFIGVSAS->pec); break; } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "... dictionary data: id:%d, vendor id:%d, attr type:%d, attr name:%s (%d)\n", PCONFIGVSAS->id, PCONFIGVSAS->pec, pda->type, pda->name, attrid); switch(pda->type) { case PW_TYPE_STRING: switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "... radius: key:%s, value:%s (%s) as string\n", PCONFIGVSAS->name, PCONFIGVSAS->value, value); if (rc_avpair_add(rh, &send, PCONFIGVSAS->id, value, -1, PCONFIGVSAS->pec) == NULL) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "An Error occured during rc_avpair_add : %s\n", PCONFIGVSAS->name); result = ERROR_RC; break; } break; //case PW_TYPE_DATE: case PW_TYPE_INTEGER: integer = atoi(value); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "... radius: key:%s, value:%s (%d) as integer\n", PCONFIGVSAS->name, PCONFIGVSAS->value, integer); if (rc_avpair_add(rh, &send, PCONFIGVSAS->id, &integer, -1, PCONFIGVSAS->pec) == NULL) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "An Error occured during rc_avpair_add : %s\n", PCONFIGVSAS->name); result = ERROR_RC; break; } break; case PW_TYPE_IPADDR: integer = rc_get_ipaddr(value); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "... radius: key:%s, value:%s (%d) as ipaddr\n", PCONFIGVSAS->name, PCONFIGVSAS->value, integer); if (rc_avpair_add(rh, &send, PCONFIGVSAS->id, &integer, -1, PCONFIGVSAS->pec) == NULL) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "An Error occured during rc_avpair_add : %s\n", PCONFIGVSAS->name); result = ERROR_RC; break; } break; default: switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unknown attribute type: key:%s, type %d\n", PCONFIGVSAS->name, pda->type); break; } } PCONFIGVSAS = PCONFIGVSAS->pNext; } if (result != ERROR_RC) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "sending radius packet ...\n" ); result = rc_auth(rh, 0, send, &received, msg); if (result == OK_RC) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "RADIUS Authentication OK\n"); strcpy(auth_result, "OK"); } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, " RADIUS Authentication failure (RC=%d)\n", result); strcpy(auth_result, "NOK"); } PCONFIGVSAS = CONFIGVSAS; while(PCONFIGVSAS) { if (PCONFIGVSAS->direction == 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Handle attribute: %s\n", PCONFIGVSAS->name ); if ((service_vp = rc_avpair_get(received, PCONFIGVSAS->id, PCONFIGVSAS->pec)) != NULL) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "\tattribute (%s) found in radius packet\n", PCONFIGVSAS->name); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "\tset variable %s := %s\n", PCONFIGVSAS->value, service_vp->strvalue); switch_channel_set_variable(channel, PCONFIGVSAS->value, service_vp->strvalue); } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "\tNo found out attribute id: %d, pec:%d, (%s)\n", PCONFIGVSAS->id, PCONFIGVSAS->pec, PCONFIGVSAS->name ); } } PCONFIGVSAS = PCONFIGVSAS->pNext; } } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "abort sending radius packet.\n" ); break; } } while(1 == 0); if (result == ERROR_RC) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "An error occured during RADIUS Authentication(RC=%d)\n", result); } free_radius_auth_value_pair(send, received, rh); return result; }
static rc_handle *my_radius_init(void) { int i = 0; rc_handle *rad_config; rad_config = rc_new(); if (rad_config == NULL) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "[mod_radius_cdr] Error initializing rc_handle!\n"); return NULL; } rad_config = rc_config_init(rad_config); if (rad_config == NULL) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "error initializing radius config!\n"); rc_destroy(rad_config); return NULL; } /* Some hardcoded ( for now ) defaults needed to initialize radius */ if (rc_add_config(rad_config, "auth_order", "radius", "mod_radius_cdr.c", 0) != 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "setting auth_order = radius failed\n"); rc_destroy(rad_config); return NULL; } if (rc_add_config(rad_config, "seqfile", my_seqfile, "mod_radius_cdr.c", 0) != 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "setting seqfile = %s failed\n", my_seqfile); rc_destroy(rad_config); return NULL; } /* Add the module configs to initialize rad_config */ for (i = 0; i < SERVER_MAX && my_servers[i][0] != '\0'; i++) { if (rc_add_config(rad_config, "acctserver", my_servers[i], cf, 0) != 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "setting acctserver = %s failed\n", my_servers[i]); rc_destroy(rad_config); return NULL; } } if (rc_add_config(rad_config, "dictionary", my_dictionary, cf, 0) != 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed setting dictionary = %s failed\n", my_dictionary); rc_destroy(rad_config); return NULL; } if (rc_add_config(rad_config, "radius_deadtime", my_deadtime, cf, 0) != 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "setting radius_deadtime = %s failed\n", my_deadtime); rc_destroy(rad_config); return NULL; } if (rc_add_config(rad_config, "radius_timeout", my_timeout, cf, 0) != 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "setting radius_timeout = %s failed\n", my_timeout); rc_destroy(rad_config); return NULL; } if (rc_add_config(rad_config, "radius_retries", my_retries, cf, 0) != 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "setting radius_retries = %s failed\n", my_retries); rc_destroy(rad_config); return NULL; } /* Read the dictionary file(s) */ if (rc_read_dictionary(rad_config, rc_conf_str(rad_config, "dictionary")) != 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "reading dictionary file(s): %s\n", my_dictionary); rc_destroy(rad_config); return NULL; } return rad_config; }