📄 radius_interface.c
字号:
/* radius_interface.c *//* Implementations of RADIUS interface fucntions. *//* Copyright 1984 - 2000 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history____________________Date Init Change description031102 md Enhancement - moving polling socket read to seperate tasks and replace taskLock/unLock with rwos_radius_data_mutex022702 md Add radius_remove_attribute()111401 md Fixed SPR#70426 - pool packet identifiers per server052301 tk Added a counter user_count to keep track of the copies of server handles handed out to clients. Destroy the server only if there is an explicit call to do so, and there is no pending request, no client still owns any copy of the server handle.020801 tk Added a new API radius_any_server_request() for request to automatically use back-up server if the target server doesn't respond.012601 tk ifdef all RADIUS MIBs code with __RADIUS_MIB__121900 md replaced rwos_mutex_acquire and rwos_mutex_release with taskLock() and taskUnlock()121900 md merged from visual source safe*/#include <string.h>#include <stdio.h>#include "radius.h"#include <vnvrmstr.h>/***************************************************************************/extern RWOS_MUTEX rwos_radius_data_mutex;/************************************************************************/RADIUS_SERVER_HANDLE radius_server_create (enum RADIUS_SERVER_TYPE type, IP_ADDRESS ip_address, UINT port, UINT max_retransmit_count, UINT retransmission_interval, char* cp_secret){ RADIUS_SERVER* p_server; RW_CONTAINER_ITERATOR server_iterator; if ((UINT) type >= (UINT) RADIUS_TOTAL_TYPES_OF_SERVERS) { radius_printf (RADIUS_ALARM_PRINTF, "RADIUS: Failed to recognize RADIUS server type - %d\n", type); return (INVALID_HANDLE); } p_server = (RADIUS_SERVER*) table_malloc (1, sizeof (RADIUS_SERVER)); if (p_server == NULL) { radius_printf (RADIUS_ALARM_PRINTF,"RADIUS: radius_server_create: Out of memory\r\n"); return (INVALID_HANDLE); } p_server->ip_address = ip_address; p_server->port = port; p_server->type = type; p_server->max_retransmit_count = max_retransmit_count; p_server->retransmission_interval = retransmission_interval; p_server->deleted = false; p_server->pending_request_count = 0; p_server->user_count = 1; p_server->secret_length = strlen (cp_secret); p_server->bp_secret = table_malloc (1, p_server->secret_length); if (p_server->bp_secret != NULL) { memcpy (p_server->bp_secret, cp_secret, p_server->secret_length); } else { radius_printf (RADIUS_ALARM_PRINTF,"RADIUS: radius_server_create: Out of memory\r\n"); table_free (p_server); return (INVALID_HANDLE); } p_server->packet_identifier_count = 0; radius_initialize_packet_pool_identifier_per_server (p_server); rwos_mutex_acquire (rwos_radius_data_mutex, WAIT_FOREVER); rw_container_add_front (radius.server_controller.p_list, (RW_CONTAINER_ITEM*) p_server); server_iterator = rw_container_create_copy_of_iterator (radius.server_controller.iterator); rw_container_goto_front (server_iterator); rwos_mutex_release (rwos_radius_data_mutex); return ((RADIUS_SERVER_HANDLE) server_iterator);}/***************************************************************************/bool radius_server_add_type (RADIUS_SERVER_HANDLE server_handle, enum RADIUS_SERVER_TYPE type){#if 0 /* 12/13/00 */ RADIUS_SERVER* p_server; /* it is the responsibility of the RADIUS user to ensure that a valid handle is passed */ p_server = rw_container_at ((RW_CONTAINER_ITERATOR) server_handle); switch (type) { case RADIUS_AUTHENTICATION_SERVER_TYPE: if (p_server->type == RADIUS_ACCOUNTING_SERVER_TYPE) { p_server->type = RADIUS_AUTHENTICATION_AND_ACCOUNTING_SERVER_TYPE; } break; case RADIUS_ACCOUNTING_SERVER_TYPE: if (p_server->type == RADIUS_AUTHENTICATION_SERVER_TYPE) { p_server->type = RADIUS_AUTHENTICATION_AND_ACCOUNTING_SERVER_TYPE; } break; default: return (false); } return (true);#endif return (false);} /***************************************************************************/bool radius_server_change_secret (RADIUS_SERVER_HANDLE server_handle, char* cp_secret){ RADIUS_SERVER* p_server; rwos_mutex_acquire (rwos_radius_data_mutex, WAIT_FOREVER); /* it is the responsibility of the RADIUS user to ensure that a valid handle is passed */ p_server = rw_container_at ((RW_CONTAINER_ITERATOR) server_handle); if (p_server == NULL) { radius_printf (RADIUS_ALARM_PRINTF,"RADIUS: radius_server_change_secret: Illegal server handle\r\n"); rwos_mutex_release (rwos_radius_data_mutex); return (false); } if (p_server->bp_secret != NULL) { table_free (p_server->bp_secret); p_server->secret_length = 0; } p_server->secret_length = strlen (cp_secret); p_server->bp_secret = table_malloc (1, p_server->secret_length); memcpy (p_server->bp_secret, cp_secret, p_server->secret_length); rwos_mutex_release (rwos_radius_data_mutex); return (true);}/****************************************************************************Description: This function is called by client to free the server handle it obtained previously from the RADIUS Client. Since the server handle can be freed by the client asynchronously from the deletion of the server, and there can be multiple copies of server handle to the same server, the user_count is used to keep track of the server handles which have not been freed. If there is a pending call to destroy the server, delete the server only if the user_count is 0 and there is no pending request.****************************************************************************/void radius_free_server_handle (RADIUS_SERVER_HANDLE server_handle){ RW_CONTAINER_ITERATOR server_iterator; RADIUS_SERVER* p_server; rwos_mutex_acquire (rwos_radius_data_mutex, WAIT_FOREVER); server_iterator = (RW_CONTAINER_ITERATOR) server_handle; p_server = rw_container_at (server_iterator); if (p_server == NULL) { radius_printf (RADIUS_ALARM_PRINTF, "RADIUS: radius_free_server_handle: Server with handle %d not found\r\n", (UINT) server_handle); rwos_mutex_release (rwos_radius_data_mutex); return; /*Server Not Found*/ } if (p_server->user_count > 0) { --p_server->user_count; } if (p_server->deleted == true && p_server->pending_request_count == 0 && p_server->user_count == 0) { if (p_server->bp_secret != NULL) { table_free (p_server->bp_secret); } table_free (p_server); rw_container_remove (server_iterator); radius_printf (RADIUS_ALARM_PRINTF, "RADIUS: radius_free_server_handle: server deleted\n"); } rwos_mutex_release (rwos_radius_data_mutex); rw_container_free_iterator ((RW_CONTAINER_ITERATOR) server_handle);}/***************************************************************************/bool radius_server_destroy (RADIUS_SERVER_HANDLE server_handle){ RW_CONTAINER_ITERATOR server_iterator; RADIUS_SERVER* p_server; rwos_mutex_acquire (rwos_radius_data_mutex, WAIT_FOREVER); server_iterator = (RW_CONTAINER_ITERATOR) server_handle; p_server = rw_container_at (server_iterator); if (p_server == NULL) { radius_printf (RADIUS_ALARM_PRINTF, "RADIUS: radius_server_destroy: Server with handle %d not found\r\n", (UINT) server_handle); rwos_mutex_release (rwos_radius_data_mutex); return (false); /*Server Not Found*/ } /* destroy server only if there is no pending request and no client still owns any handle of the server */ if (p_server->pending_request_count == 0 && p_server->user_count == 0) { if (p_server->bp_secret != NULL) { table_free (p_server->bp_secret); } table_free (p_server); rw_container_remove (server_iterator); rwos_mutex_release (rwos_radius_data_mutex); return (true); } if (p_server->deleted == false) { p_server->deleted = true; } radius_printf (RADIUS_ALARM_PRINTF, "RADIUS: Server destroy pending ..., pending request = %d, user count = %d\n", p_server->pending_request_count, p_server->user_count); rwos_mutex_release (rwos_radius_data_mutex); return (true);}#ifdef __RADIUS_MIB__/***************************************************************************/UINT radius_get_server_index_in_mib_table (RADIUS_SERVER_HANDLE server_handle){ RW_CONTAINER_ITERATOR server_iterator; RADIUS_SERVER* p_server; server_iterator = (RW_CONTAINER_ITERATOR) server_handle; p_server = rw_container_at (server_iterator); return ((UINT)p_server);}/***************************************************************************/#endifRADIUS_SERVER_HANDLE radius_get_first_server (enum RADIUS_SERVER_TYPE type){ RW_CONTAINER_ITERATOR server_iterator; RADIUS_SERVER* p_server; if (type >= RADIUS_TOTAL_TYPES_OF_SERVERS) { radius_printf (RADIUS_ALARM_PRINTF,"RADIUS: radius_get_first_server: Illegal type %d\r\n", (UINT) type); return (INVALID_HANDLE); } rwos_mutex_acquire (rwos_radius_data_mutex, WAIT_FOREVER); server_iterator = rw_container_create_copy_of_iterator (radius.server_controller.iterator); rw_container_goto_front (server_iterator); while (rw_container_is_at_end (server_iterator) == false) { p_server = rw_container_at (server_iterator); if (p_server->deleted == false) { if (p_server->type == type) { ++p_server->user_count; rwos_mutex_release (rwos_radius_data_mutex); return ((RADIUS_SERVER_HANDLE) server_iterator); /* server_iterator already points to the new server */ } } rw_container_next (server_iterator); } rw_container_free_iterator (server_iterator); radius_printf (RADIUS_ALARM_PRINTF,"RADIUS: radius_get_first_server: Could not find server of type %d\r\n", (UINT) type); rwos_mutex_release (rwos_radius_data_mutex); return (INVALID_HANDLE);}/***************************************************************************/RADIUS_SERVER_HANDLE radius_get_next_server (RADIUS_SERVER_HANDLE server_handle, enum RADIUS_SERVER_TYPE type){ RW_CONTAINER_ITERATOR server_iterator; RADIUS_SERVER* p_server; rwos_mutex_acquire (rwos_radius_data_mutex, WAIT_FOREVER); server_iterator = rw_container_create_copy_of_iterator ((RW_CONTAINER_ITERATOR) server_handle); rw_container_next (server_iterator); while (rw_container_is_at_end (server_iterator) == false) { p_server = rw_container_at (server_iterator); if (p_server->deleted == false) { if ((p_server->type == RADIUS_AUTHENTICATION_AND_ACCOUNTING_SERVER_TYPE) || (p_server->type == type)) { ++p_server->user_count; rwos_mutex_release (rwos_radius_data_mutex); return ((RADIUS_SERVER_HANDLE) server_iterator); /* server_iterator already points to the new server */ } } rw_container_next (server_iterator); } rw_container_free_iterator (server_iterator); radius_printf (RADIUS_ALARM_PRINTF,"RADIUS: radius_get_next_server: Could not find next server of type %d\r\n", (UINT) type); rwos_mutex_release (rwos_radius_data_mutex); return (INVALID_HANDLE);}/***************************************************************************/RADIUS_SERVER_HANDLE radius_find_server_with_specified_parameters (char* cp_ip_address, UINT port, enum RADIUS_SERVER_TYPE type){ ULONG tmp0; ULONG tmp1; ULONG tmp2; ULONG tmp3; IP_ADDRESS ip_address; RW_CONTAINER_ITERATOR server_iterator; RADIUS_SERVER* p_server; if (cp_ip_address == NULL) { return (INVALID_HANDLE); } if (type >= RADIUS_TOTAL_TYPES_OF_SERVERS) { radius_printf (RADIUS_ALARM_PRINTF,"RADIUS: radius_find_server_with_specified_parameters: Illegal type %d\r\n", (UINT) type); return (INVALID_HANDLE); } rwos_mutex_acquire (rwos_radius_data_mutex, WAIT_FOREVER); sscanf (cp_ip_address,"%03lu.%03lu.%03lu.%03lu", &tmp0, &tmp1, &tmp2, &tmp3); ip_address = convert_4_bytes_to_ulong ((BYTE) tmp3, (BYTE) tmp2, (BYTE) tmp1, (BYTE) tmp0); server_iterator = rw_container_create_copy_of_iterator (radius.server_controller.iterator); rw_container_goto_front (server_iterator); while (rw_container_is_at_end (server_iterator) == false)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -