Skip to content

Latest commit

 

History

History
298 lines (221 loc) · 11.7 KB

DeveloperNotes.md

File metadata and controls

298 lines (221 loc) · 11.7 KB

Tiny RADIUS Client Library

Copyright (C) 2022 David M. Syzdek [email protected].
All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  • Neither the name of David M. Syzdek nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DAVID M. SYZDEK BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Table of Contents

  • Overview
  • Coding Style and Guidelines
  • Tiny RADIUS Libraries
  • Memory Management
  • Tiny RADIUS Dictionary
    • Dictionary Vendor
    • Dictionary Attribute
    • Dictionary Value
    • Dictionary OID
    • Dictionary Thread Safety

Overview

This file contains miscellaneous notes from the developer regarding the project design, system/compiler assumptions, and code style of TinyRad (Tiny RADIUS Client Library). Please review these notes before submitting patches to the developer.

Coding Style and Guidelines

To be written.

Tiny RADIUS Libraries

TinyRad contains the libraries libutils and libtinyrad. libutils is a static library which contains functions, macros, and definitions which are used by one or more TinyRad utilities or tests. libutils is intended to be used only when builing the package and should not be installed into the system. libtinyrad contains both a public API for use by client applications and an internal API used by TinyRad utilities and tests. Client applications should only use functions, macros, and definitions defined in tinyrad.h. The API defined in tinyrad_internal.h and tinyrad_utils.h are subject to change without notice and should not be used for applications external to the project nor should they be installed into the system.

  • tinyrad.h is the public API
  • tinyrad_compat.h sets standards compatibility information.
  • tinyrad_internal.h contains API used by both TinyRad utilities, tests, and libtinyrad itself.
  • tinyrad_utils.h is the internal API for common functions used by TinyRad utilities and tests.

Memory Management

TinyRad uses manual reference counters internally to manage memory of nested data structures. TinyRad data structures utilizing reference counters must be declared with the first member of the type TinyRadObj (struct _tinyrad_obj). TinyRadObj contains a magic number, a counter with an atomic data type, and a pointer to the function used to free the memory and resources used by the data structure. All data structures using reference counters should be allocated using tinyrad_obj_alloc().

The TinyRad library uses the following functions to manage data structures utilizing reference counters:

  • tinyrad_obj_alloc() allocates memory for a managed data structure. The reference counter is initialized to zero. Functions calling tinyrad_obj_alloc() must call tinyrad_obj_retain() or tinyrad_obj_release() before exiting.

  • tinyrad_obj_retain() increments the reference counter using an atomic operation and returns a pointer to the data structure retained.

  • tinyrad_obj_retain_count() returns the value of the current reference counter of the referenced data structure.

  • tinyrad_obj_release() decrements the reference counter using an atomic operation. If the reference counter equals zero or less, the function referenced in the TinyRadObj member will be called to free the memory and resources.

  • tinyrad_verify_is_obj() returns TRAD_YES if the referenced memory uses reference counters and returns TRAD_NO if the referenced memory does not use reference counters. tinyrad_verify_is_obj is primarily used by tinyrad_free() to distinguish between managed memory and unmanaged memory.

  • tinyrad_free() is a public function which uses the function tinyrad_verify_is_obj() to determine if a pointer references managed memory or unmanaged memory. If the memory is unmanaged, tinyrad_free() will call the equivalent of free() to free the referenced memory. If the memory is managed, then the function tinyrad_obj_release() will be called.

Unless otherwise specified in the TinyRad documentation, programs and libraries external to the TinyRad library must use the tinyrad_free() function to free data structures and memory allocated by the TinyRad library. A process which calls either tinyrad_free() or tinyrad_obj_release() on managed memory should consider the referenced memory unallocated.

Tiny RADIUS Dictionary

The TinyRad dictionary containes definitions for vendors (TinyRadDictVendor), attributes (TinyRadDictAttr), and values (TinyRadDictValue). These three entity types are used to convert between user friendly names and binary data.

The first entity, is the TinyRadDictAttr. TinyRadDictAttr is the primary entity and represents a RADIUS attribute definition. A TinyRadDictAttr may reference a TinyRadDictVendor which contains a vendor definition of one or more attributes. A TinyRadDictVendor will contain the vendor's common specifications for its attributes such as "length octets" and "type octets". Some attributes have enumerated values, these are defined in TinyRadDictValue. Each TinyRadDictValue references the associated TinyRadDictAttr.

Dictionary Vendor

TinyRadDictVendor represents a RADIUS vendor. A TinyRadDictVendor will define the number of octets used to specify the vendor's attribute length (len_octets) and define the number of octets used to specify the vendor's attribute type (type_octets). If an unknown vendor ID is encountered, the library will assume the vendor uses a 1 byte "vendor length" and a 1 byte "vendor type" as illustrated by the example in section 5.26 of RFC 2865. The dictionary reference maintains the definitions of TinyRadDictVendor in an array sorted by name and in an array nominally sorted by Vendor-Id.

The array sorted by name must not contain duplicate names and sorts using the following criteria:

  • Vendor Name

The array sorted nominally by Vendor-Id may contain duplicate Vendor-ID values if the Vendor-Id, type_octets and len_octets are identical among the vendors with duplicate Vendor-Id. The array sorted nominally by Vendor-Id uses the following sort criteria:

  • Vendor-Id
  • Order of Creation

Dictionary Attribute

TinyRadDictAttr represents a RADIUS attribute definition. If the attribute is specific to a vendor, then the TinyRadDictAttr will reference a TinyRadDictVendor. The dictionary reference maintains the definitions of TinyRadDictAttr in an array sorted by name and in an array nominally sorted by OID.

The array sorted by name must not contain duplicate names and sorts using the following criteria:

  • Attribute Name

The array sorted nominally by OID may contain duplicate OID values if the OID, vendor, data type, and flags are identical among the attributes with duplicate OID. Allowing duplicate OID allow an attribute to be referenced by multiple names (i.e. if a later RFC updates the name of an attribute defined in a previous RFC). The array sorted nominally by OID uses the following sort criteria:

  • Vendor-Id
  • Attribute OID
  • Order of Creation

Dictionary Value

TinyRadDictValue represents an enumerated value of a RADIUS attribute of data types enum, integer, integer64, byte, short, and signed. The dictionary reference maintains the definitions of TinyRadDictValue in an array nominally sorted by name and in an array nominally sorted by OID.

The array sorted nominally by name must not contain duplicate value names for same attribute. Value names may be duplicated in different attributes. The array nominally sorted by name uses the following criteria:

  • OID of Associated Attribute
  • Value Name

The array sorted nominally by name may contain duplicate values for the same attribute. The array sorted nominally by OID uses the following sort criteria:

  • OID of Associated Attribute
  • Value (i.e. integer data)
  • Order of Creation

Dictionary OID

Internally, individual TinyRadDictAttr are uniquely identified using a numeric OID (TinyRadOID). TinyRadDictVendor are indirectly identified in TinyRadDictAttr and TinyRadDictValue using a numeric OID. The first element of the OID always identifies a RADIUS attribute type defined by an RFC. The value of each subsequent element of an OID is dependent upon the attribute type and contains either an optional attribute sub-type or an optional Vendor-ID.

The simplest OID consists of just an attribute type such as :

2

Where:

  • 2 is the type of the User-Password attribute (RFC 2865 Section 5.2)

An example of an OID for a Vendor-Specific attribute may be:

26.32473.57

Where:

  • 26 is the type of the Vendor-Specific attribute (RFC 2865 Section 5.26)
  • 32473 is the Vendor-Id (example Enterprise Number defined in RFC 5612)
  • 57 is the vendor type

An example of an OID for an attribute of the EVS (Extended-Vendor-Specific) data type which contains two TLV (Type-Length-Value) data subtypes may be:

243.26.32473.122.54.231

Where:

  • 243 is the type of the Extended-Type-3 attribute (RFC 6929 Section 3.3)
  • 26 is the Extended-Type for Vendor sub-types (RFC 6929 Section 4.3)
  • 32473 is the Vendor-Id (example Enterprise Number defined in RFC 5612)
  • 122 is the vendor sub-type
  • 54 is the TLV sub-type of 243.26.32473.122
  • 231 is the TLB sub-type of 243.26.32473.122.54

Dictionary Thread Safety

The dictionary reference is not thread safe for read-write operations due to the lack of internal locks, however a dictionary reference can be safely used for read-only operations by multiple threads simultaneously. Multiple TinyRad functions retain references and share references to the dictionary, so external locks are unable to ensure thread-saftey across mutiple threads for read-write access to the dictionary.

A dictionary reference can be marked as read-only to ensure that it is not modified in a multi-threaded application after the definitions have been imported or loaded from defaults. The following example snippet demonstrates how to make the dictionary read-only:

int opt = TRAD_YES;
tinyrad_dict_set_option(dict, TRAD_DICT_OPT_READONLY, &opt);

Setting the dictionary to read-only disables the following functions for the specific dictionary reference:

  • tinyrad_dict_defaults()
  • tinyrad_dict_import()
  • tinyrad_dict_parse()
  • tinyrad_dict_set_option()