?? radius_authorize.c
字號(hào):
/* radius_authorize.c *//* Implementations of encryption and decryption of RADIUS attributes if needed. *//* Currently we only encrypt User-Password and decrypt Tunnel-Password *//* Copyright 1984 - 2000 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history____________________01f,26aug03,snd Changes done to remove compilation warnings01e,22mar02,md Bug fix - zeroing out the wrong MA when EAP packet is larged01d,15mar02,md Merge Mark's changes for EAP support01c,04mar02,md Add support for EAP01b,27feb02,md Add a fourth parameter to radius_accounting_fill_in_request_authenticator to authenticate the accounting response from radius server01a,19dec00,md merged from visual source safe*//************************************************************************//* Copyright (C) 1993 - 1999 RouterWare, Inc. *//* Unpublished - rights reserved under the Copyright Laws of the *//* United States. Use, duplication, or disclosure by the *//* Government is subject to restrictions as set forth in *//* subparagraph (c)(1)(ii) of the Rights in Technical Data and *//* Computer Software clause at 252.227-7013. *//* RouterWare, Inc., 3961 MacArthur Suite 212 Newport Beach, CA 92660 *//************************************************************************/#include <string.h>#include "radius.h"#include <rwutils.h>#ifdef __EAP__#include "radius_message_digest.h"#endif /* __EAP__ *//*****************************************************************************************/static bool do_radius_md5_encryption (BYTE *cptr_identifier, USHORT identifier_length, BYTE *p_secret, USHORT secret_length, BYTE *p_data, USHORT data_length);static bool do_radius_md5_decryption (BYTE *cptr_identifier, USHORT identifier_length, BYTE *p_secret, USHORT secret_length, BYTE *p_data, USHORT data_length);#ifdef __EAP__static bool radius_get_message_authenticator_attribute (RADIUS_PACKET *sptr_packet, BYTE* p_buffer, RADIUS_LIST_CONTROLLER* p_radius_attribute_list_controller);#endif /* __EAP__ *//*****************************************************************************************//* encrypts all attributes that need encryption - this is user_password only, right now */ enum TEST radius_encrypt_attributes_with_authenticator (RW_CONTAINER* p_attribute_list, BYTE *bptr_authenticator, RADIUS_SERVER* p_server){ RW_CONTAINER_ITERATOR attribute_iterator; RADIUS_ATTRIBUTE_ENTRY *p_attribute; RADIUS_ATTRIBUTE_ENTRY *sptr_new_attribute; UINT new_attribute_value_length; UINT new_attribute_entry_size; bool encrypted ; bool attribute_removed ; encrypted = false; attribute_iterator = rw_container_create_iterator (p_attribute_list); rw_container_goto_front (attribute_iterator); while (rw_container_is_at_end (attribute_iterator) == false) { p_attribute = rw_container_at (attribute_iterator); attribute_removed = false; if (p_attribute->type == RADIUS_USER_PASSWORD) { if ((p_attribute->length_of_attribute_value % RADIUS_PASSWORD_MODULUS) != 0x00) { new_attribute_value_length = p_attribute->length_of_attribute_value + (RADIUS_PASSWORD_MODULUS - (p_attribute->length_of_attribute_value % RADIUS_PASSWORD_MODULUS)); new_attribute_entry_size = new_attribute_value_length + sizeof (RADIUS_MESSAGE_ATTRIBUTE_HEADER); sptr_new_attribute = (RADIUS_ATTRIBUTE_ENTRY *) table_malloc (1, new_attribute_entry_size); if (sptr_new_attribute == NULL) { rw_container_free_iterator (attribute_iterator); return (FAIL); } memset ((BYTE *) sptr_new_attribute, 0, new_attribute_entry_size); memcpy (sptr_new_attribute, p_attribute, (p_attribute->length_of_attribute_value + sizeof (RADIUS_MESSAGE_ATTRIBUTE_HEADER))); sptr_new_attribute->length_of_attribute_value = (BYTE) new_attribute_value_length; rw_container_remove (attribute_iterator); table_free (p_attribute); attribute_removed = true; rw_container_add_front (p_attribute_list, (RW_CONTAINER_ITEM*) sptr_new_attribute); p_attribute = sptr_new_attribute; } encrypted = do_radius_md5_encryption (bptr_authenticator, RADIUS_SIZE_OF_AUTHENTICATOR, p_server->bp_secret, (USHORT) p_server->secret_length, (BYTE *)&p_attribute->value[0], (USHORT) p_attribute->length_of_attribute_value); if (encrypted == false) { rw_container_free_iterator (attribute_iterator); return (FAIL); } } if (attribute_removed == false) { rw_container_next (attribute_iterator); } } rw_container_free_iterator (attribute_iterator); return (PASS);} /*****************************************************************************************//* Decrypts all attributes that need encryption - this is tunnel_password only, right now */ enum TEST radius_decrypt_attributes_with_authenticator (RW_CONTAINER* p_attribute_list, BYTE *bptr_authenticator, RADIUS_SERVER* p_server){ RW_CONTAINER_ITERATOR attribute_iterator; RADIUS_ATTRIBUTE_ENTRY *p_attribute; RADIUS_ATTRIBUTE_ENTRY *sptr_new_attribute; UINT new_attribute_value_length; UINT new_attribute_entry_size; BYTE *bptr_new_authenticator; UINT new_authenticator_length; bool decrypted ;#ifdef __EAP__ int headerLen; int saltPos; UINT32 vendorId;#endif /* __EAP__ */ decrypted = false; attribute_iterator = rw_container_create_iterator (p_attribute_list); rw_container_goto_front (attribute_iterator); while (rw_container_is_at_end (attribute_iterator) == false) { p_attribute = (RADIUS_ATTRIBUTE_ENTRY *)rw_container_at (attribute_iterator); if (p_attribute->type == RADIUS_TUNNEL_PASSWORD) { rw_container_remove (attribute_iterator); new_authenticator_length = RADIUS_SIZE_OF_AUTHENTICATOR + TUNNEL_PASSWORD_SALT_LENGTH; bptr_new_authenticator = (BYTE *) table_malloc (1, new_authenticator_length); if (bptr_new_authenticator == NULL) { rw_container_free_iterator (attribute_iterator); return (FAIL); } memset ((BYTE *) bptr_new_authenticator, 0, new_authenticator_length); memcpy (bptr_new_authenticator, bptr_authenticator, RADIUS_SIZE_OF_AUTHENTICATOR); memcpy (bptr_new_authenticator + RADIUS_SIZE_OF_AUTHENTICATOR, (BYTE *)&p_attribute->value[TUNNEL_ATTRIBUTE_TAG_LENGTH], TUNNEL_PASSWORD_SALT_LENGTH); if (((p_attribute->length_of_attribute_value - TUNNEL_PASSWORD_SALT_LENGTH - TUNNEL_ATTRIBUTE_TAG_LENGTH) % RADIUS_PASSWORD_MODULUS) == 0x00) { decrypted = do_radius_md5_decryption (bptr_new_authenticator, new_authenticator_length, p_server->bp_secret, (USHORT) p_server->secret_length, (BYTE *)&p_attribute->value[TUNNEL_PASSWORD_SALT_LENGTH + TUNNEL_ATTRIBUTE_TAG_LENGTH], (USHORT) p_attribute->length_of_attribute_value - TUNNEL_PASSWORD_SALT_LENGTH - TUNNEL_ATTRIBUTE_TAG_LENGTH); table_free (bptr_new_authenticator); if (decrypted == false) { rw_container_free_iterator (attribute_iterator); return (FAIL); } new_attribute_value_length = TUNNEL_ATTRIBUTE_TAG_LENGTH + (UINT)p_attribute->value[TUNNEL_PASSWORD_SALT_LENGTH + TUNNEL_ATTRIBUTE_TAG_LENGTH]; new_attribute_entry_size = new_attribute_value_length + sizeof (RADIUS_MESSAGE_ATTRIBUTE_HEADER); sptr_new_attribute = (RADIUS_ATTRIBUTE_ENTRY *) table_malloc (1, new_attribute_entry_size); if (sptr_new_attribute == NULL) { rw_container_free_iterator (attribute_iterator); return (FAIL); } memset ((BYTE *) sptr_new_attribute, 0, new_attribute_entry_size); sptr_new_attribute->type = p_attribute->type; sptr_new_attribute->length_of_attribute_value = (BYTE) new_attribute_value_length; memcpy (&(sptr_new_attribute->value [0]),&(p_attribute->value [0]), TUNNEL_ATTRIBUTE_TAG_LENGTH); memcpy (&(sptr_new_attribute->value [TUNNEL_ATTRIBUTE_TAG_LENGTH]), &(p_attribute->value [TUNNEL_PASSWORD_SALT_LENGTH + TUNNEL_ATTRIBUTE_TAG_LENGTH + 1]), new_attribute_value_length - TUNNEL_ATTRIBUTE_TAG_LENGTH); rw_container_insert (attribute_iterator, (RW_CONTAINER_ITEM*) sptr_new_attribute); table_free (p_attribute); sptr_new_attribute = NULL; } }#ifdef __EAP__ if (p_attribute->type == RADIUS_VENDOR_SPECIFIC) { /* vendor id - 4 bytes */ /* vendor type - 1 byte */ /* vendor length - 1 byte */ /* salt - 2 bytes */ /* key length - 1 byte */ /* key - depend on key length */ headerLen = VENDOR_SPECIFIC_ID_LENGTH + VENDOR_TYPE_LENGTH + VENDOR_LENGTH; /* retrieve the vendor ID */ bcopy((BYTE *)&p_attribute->value[0], (char *)&vendorId, 4); vendorId = ntohl(vendorId); if (vendorId == VENDOR_ID_CISCO) { char sKeyId[] = "leap:session-key="; /* the Cisco key message has this format: *------------------------------------------------------------ *vendorType | vendorLen |"leap:session-key="|Salt|Key string | *------------------------------------------------------------ */ /* make sure this is a session key message */ if (memcmp((BYTE *)&p_attribute->value[headerLen], sKeyId,strlen(sKeyId))) { /* not a key message */ rw_container_next (attribute_iterator); continue; } /* calculate the Salt position */ saltPos = headerLen + strlen(sKeyId); } else if (vendorId == VENDOR_ID_MICROSOFT) { /* the Microsoft key message has this format: *------------------------------------------------------------ *vendorType | vendorLen |Salt| Key string *------------------------------------------------------------ */ /* make sure it is the key types */ if ((p_attribute->value[VENDOR_SPECIFIC_ID_LENGTH] != VENDOR_TYPE_MS_MPPE_SEND_KEY) && (p_attribute->value[VENDOR_SPECIFIC_ID_LENGTH] != VENDOR_TYPE_MS_MPPE_RECV_KEY)) { /* not a key message */ rw_container_next (attribute_iterator); continue; } saltPos = headerLen; } else { /* not supported for now */ printf("RADIUS: Not supported VendorID\n"); rw_container_next (attribute_iterator); continue; } new_authenticator_length = RADIUS_SIZE_OF_AUTHENTICATOR + VENDOR_SALT_LENGTH; bptr_new_authenticator = (BYTE *) table_malloc (1, new_authenticator_length); if (bptr_new_authenticator == NULL) { rw_container_free_iterator (attribute_iterator); return (FAIL); } memset ((BYTE *) bptr_new_authenticator, 0, new_authenticator_length); /* copy request authenticator */ memcpy (bptr_new_authenticator, bptr_authenticator, RADIUS_SIZE_OF_AUTHENTICATOR); /* retrieve the salt value */ bcopy(&p_attribute->value[saltPos], bptr_new_authenticator + RADIUS_SIZE_OF_AUTHENTICATOR, VENDOR_SALT_LENGTH); /* check the integrity of the encrypted key string */ if (((p_attribute->length_of_attribute_value - saltPos- VENDOR_SALT_LENGTH) % RADIUS_PASSWORD_MODULUS) == 0x00) { decrypted = do_radius_md5_decryption ( bptr_new_authenticator, new_authenticator_length, p_server->bp_secret, (USHORT) p_server->secret_length, (BYTE *)&p_attribute->value[saltPos + VENDOR_SALT_LENGTH], (USHORT) p_attribute->length_of_attribute_value - saltPos - VENDOR_SALT_LENGTH); /* after decryption the key string should have * key length field + key field + padding */ if (decrypted == false) { rw_container_free_iterator (attribute_iterator); return (FAIL); } /* new attr len = header len + real key len */ new_attribute_value_length = headerLen + (UINT)p_attribute->value[saltPos + VENDOR_SALT_LENGTH]; new_attribute_entry_size = new_attribute_value_length + sizeof (RADIUS_MESSAGE_ATTRIBUTE_HEADER); sptr_new_attribute = (RADIUS_ATTRIBUTE_ENTRY *) table_malloc (1, new_attribute_entry_size); if (sptr_new_attribute == NULL) { rw_container_free_iterator(attribute_iterator); return (FAIL); } memset ((BYTE *) sptr_new_attribute, 0, new_attribute_entry_size); sptr_new_attribute->type = p_attribute->type; sptr_new_attribute->length_of_attribute_value = (BYTE) new_attribute_value_length; /* copy original attribute's header */ memcpy (&(sptr_new_attribute->value [0]), &(p_attribute->value [0]), headerLen); /* copy the decrypted key */ memcpy (&(sptr_new_attribute->value[headerLen]), &(p_attribute->value[saltPos + VENDOR_SALT_LENGTH + VENDOR_KEY_LENGTH]), new_attribute_value_length - headerLen); /* now set the vendor length field */ sptr_new_attribute->value[VENDOR_SPECIFIC_ID_LENGTH + VENDOR_TYPE_LENGTH] = new_attribute_value_length - VENDOR_SPECIFIC_ID_LENGTH; /* remove the original attribute */ rw_container_remove (attribute_iterator); /* insert this newly created attribute */ rw_container_insert (attribute_iterator, (RW_CONTAINER_ITEM*) sptr_new_attribute); /* free the memory of the original attribute */ table_free (p_attribute); sptr_new_attribute = NULL; } table_free (bptr_new_authenticator); }#endif /* __EAP__ */ rw_container_next (attribute_iterator); } rw_container_free_iterator (attribute_iterator); return (PASS);}/*****************************************************************************************//* uses the request authenticator, and the response packet, to authenticate the response authenticator. refer to draft rfc for details */enum TEST verify_radius_response_authenticator (RADIUS_PACKET *sptr_rx_packet, BYTE *bptr_authenticator, RADIUS_SERVER* p_server){ BYTE *bptr_authentication_string; RADIUS_PACKET *sptr_packet; USHORT packet_length; USHORT buffer_length; BYTE md5_result[MD5_RESULT_LENGTH]; packet_length = swap (sptr_rx_packet->header.length); buffer_length = (USHORT) (packet_length + p_server->secret_length); bptr_authentication_string = (BYTE *) table_malloc (1, buffer_length); if (bptr_authentication_string == NULL) { return (FAIL);
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -