feat(smartradius): Implement full RADIUS server and client with RFC 2865/2866 compliance, including packet handling, authenticators, attributes, secrets manager, client APIs, and comprehensive tests and documentation

This commit is contained in:
2026-02-01 17:40:36 +00:00
parent 5a6a3cf66e
commit be9f49fff9
45 changed files with 11694 additions and 70 deletions

222
ts_shared/enums.ts Normal file
View File

@@ -0,0 +1,222 @@
/**
* RADIUS Protocol Enums
* Based on RFC 2865 (Authentication) and RFC 2866 (Accounting)
*/
/**
* RADIUS Packet Codes (RFC 2865 Section 3)
*/
export enum ERadiusCode {
AccessRequest = 1,
AccessAccept = 2,
AccessReject = 3,
AccountingRequest = 4,
AccountingResponse = 5,
AccessChallenge = 11,
StatusServer = 12, // Experimental
StatusClient = 13, // Experimental
}
/**
* RADIUS Attribute Types (RFC 2865 Section 5)
*/
export enum ERadiusAttributeType {
UserName = 1,
UserPassword = 2,
ChapPassword = 3,
NasIpAddress = 4,
NasPort = 5,
ServiceType = 6,
FramedProtocol = 7,
FramedIpAddress = 8,
FramedIpNetmask = 9,
FramedRouting = 10,
FilterId = 11,
FramedMtu = 12,
FramedCompression = 13,
LoginIpHost = 14,
LoginService = 15,
LoginTcpPort = 16,
ReplyMessage = 18,
CallbackNumber = 19,
CallbackId = 20,
FramedRoute = 22,
FramedIpxNetwork = 23,
State = 24,
Class = 25,
VendorSpecific = 26,
SessionTimeout = 27,
IdleTimeout = 28,
TerminationAction = 29,
CalledStationId = 30,
CallingStationId = 31,
NasIdentifier = 32,
ProxyState = 33,
LoginLatService = 34,
LoginLatNode = 35,
LoginLatGroup = 36,
FramedAppleTalkLink = 37,
FramedAppleTalkNetwork = 38,
FramedAppleTalkZone = 39,
ChapChallenge = 60,
NasPortType = 61,
PortLimit = 62,
LoginLatPort = 63,
// Accounting attributes (RFC 2866)
AcctStatusType = 40,
AcctDelayTime = 41,
AcctInputOctets = 42,
AcctOutputOctets = 43,
AcctSessionId = 44,
AcctAuthentic = 45,
AcctSessionTime = 46,
AcctInputPackets = 47,
AcctOutputPackets = 48,
AcctTerminateCause = 49,
AcctMultiSessionId = 50,
AcctLinkCount = 51,
// EAP support
EapMessage = 79,
MessageAuthenticator = 80,
}
/**
* Service-Type values (RFC 2865 Section 5.6)
*/
export enum EServiceType {
Login = 1,
Framed = 2,
CallbackLogin = 3,
CallbackFramed = 4,
Outbound = 5,
Administrative = 6,
NasPrompt = 7,
AuthenticateOnly = 8,
CallbackNasPrompt = 9,
CallCheck = 10,
CallbackAdministrative = 11,
}
/**
* Framed-Protocol values (RFC 2865 Section 5.7)
*/
export enum EFramedProtocol {
Ppp = 1,
Slip = 2,
Arap = 3,
Gandalf = 4,
Xylogics = 5,
X75 = 6,
}
/**
* Framed-Routing values (RFC 2865 Section 5.10)
*/
export enum EFramedRouting {
None = 0,
Send = 1,
Listen = 2,
SendAndListen = 3,
}
/**
* Framed-Compression values (RFC 2865 Section 5.13)
*/
export enum EFramedCompression {
None = 0,
VjTcpIp = 1,
IpxHeaderCompression = 2,
StacLzs = 3,
}
/**
* Login-Service values (RFC 2865 Section 5.15)
*/
export enum ELoginService {
Telnet = 0,
Rlogin = 1,
TcpClear = 2,
PortMaster = 3,
Lat = 4,
X25Pad = 5,
X25T3Pos = 6,
TcpClearQuiet = 8,
}
/**
* Termination-Action values (RFC 2865 Section 5.29)
*/
export enum ETerminationAction {
Default = 0,
RadiusRequest = 1,
}
/**
* NAS-Port-Type values (RFC 2865 Section 5.41)
*/
export enum ENasPortType {
Async = 0,
Sync = 1,
IsdnSync = 2,
IsdnAsyncV120 = 3,
IsdnAsyncV110 = 4,
Virtual = 5,
Piafs = 6,
HdlcClearChannel = 7,
X25 = 8,
X75 = 9,
G3Fax = 10,
Sdsl = 11,
AdslCap = 12,
AdslDmt = 13,
Idsl = 14,
Ethernet = 15,
Xdsl = 16,
Cable = 17,
WirelessOther = 18,
WirelessIeee80211 = 19,
}
/**
* Acct-Status-Type values (RFC 2866 Section 5.1)
*/
export enum EAcctStatusType {
Start = 1,
Stop = 2,
InterimUpdate = 3,
AccountingOn = 7,
AccountingOff = 8,
}
/**
* Acct-Authentic values (RFC 2866 Section 5.6)
*/
export enum EAcctAuthentic {
Radius = 1,
Local = 2,
Remote = 3,
}
/**
* Acct-Terminate-Cause values (RFC 2866 Section 5.10)
*/
export enum EAcctTerminateCause {
UserRequest = 1,
LostCarrier = 2,
LostService = 3,
IdleTimeout = 4,
SessionTimeout = 5,
AdminReset = 6,
AdminReboot = 7,
PortError = 8,
NasError = 9,
NasRequest = 10,
NasReboot = 11,
PortUnneeded = 12,
PortPreempted = 13,
PortSuspended = 14,
ServiceUnavailable = 15,
Callback = 16,
UserError = 17,
HostRequest = 18,
}

5
ts_shared/index.ts Normal file
View File

@@ -0,0 +1,5 @@
// RADIUS Protocol Shared Module
// Contains RFC 2865/2866 protocol definitions used by both server and client
export * from './enums.js';
export * from './interfaces.js';

65
ts_shared/interfaces.ts Normal file
View File

@@ -0,0 +1,65 @@
/**
* RADIUS Protocol Core Interfaces
* Based on RFC 2865 (Authentication) and RFC 2866 (Accounting)
*/
import { ERadiusCode } from './enums.js';
/**
* Attribute value type
*/
export type TAttributeValueType = 'text' | 'string' | 'address' | 'integer' | 'time' | 'vsa';
/**
* Attribute definition
*/
export interface IAttributeDefinition {
type: number;
name: string;
valueType: TAttributeValueType;
encrypted?: boolean;
}
/**
* Raw attribute (type-length-value)
*/
export interface IRadiusAttribute {
type: number;
value: Buffer;
}
/**
* Parsed attribute with named value
*/
export interface IParsedAttribute {
type: number;
name: string;
value: string | number | Buffer;
rawValue: Buffer;
}
/**
* Vendor-Specific Attribute
*/
export interface IVendorSpecificAttribute {
vendorId: number;
vendorType: number;
vendorValue: Buffer;
}
/**
* RADIUS Packet structure
*/
export interface IRadiusPacket {
code: ERadiusCode;
identifier: number;
authenticator: Buffer;
attributes: IRadiusAttribute[];
}
/**
* Parsed RADIUS packet with named attributes
*/
export interface IParsedRadiusPacket extends IRadiusPacket {
parsedAttributes: IParsedAttribute[];
}

81
ts_shared/readme.md Normal file
View File

@@ -0,0 +1,81 @@
# @push.rocks/smartradius/shared
> 📡 RADIUS Protocol Definitions - Shared types and enums for RFC 2865/2866 compliance
## Overview
This module contains the core RADIUS protocol definitions shared between the server and client implementations. It provides all the RFC 2865 (Authentication) and RFC 2866 (Accounting) enums and interfaces that represent the RADIUS protocol.
## Contents
### Enums (`enums.ts`)
All RFC-compliant protocol constants:
| Enum | Description | RFC Reference |
|------|-------------|---------------|
| `ERadiusCode` | Packet types (Access-Request, Access-Accept, etc.) | RFC 2865 §3 |
| `ERadiusAttributeType` | Standard attribute types (1-63, 79-80) | RFC 2865 §5 |
| `EServiceType` | Service-Type attribute values | RFC 2865 §5.6 |
| `EFramedProtocol` | Framed-Protocol values | RFC 2865 §5.7 |
| `EFramedRouting` | Framed-Routing values | RFC 2865 §5.10 |
| `EFramedCompression` | Framed-Compression values | RFC 2865 §5.13 |
| `ELoginService` | Login-Service values | RFC 2865 §5.15 |
| `ETerminationAction` | Termination-Action values | RFC 2865 §5.29 |
| `ENasPortType` | NAS-Port-Type values | RFC 2865 §5.41 |
| `EAcctStatusType` | Acct-Status-Type values | RFC 2866 §5.1 |
| `EAcctAuthentic` | Acct-Authentic values | RFC 2866 §5.6 |
| `EAcctTerminateCause` | Acct-Terminate-Cause values | RFC 2866 §5.10 |
### Interfaces (`interfaces.ts`)
Core data structures representing RADIUS protocol elements:
| Interface | Description |
|-----------|-------------|
| `TAttributeValueType` | Value type union ('text', 'string', 'address', 'integer', 'time', 'vsa') |
| `IAttributeDefinition` | Attribute metadata (type, name, valueType, encrypted) |
| `IRadiusAttribute` | Raw TLV (type-length-value) format |
| `IParsedAttribute` | Parsed attribute with name and decoded value |
| `IVendorSpecificAttribute` | VSA format (vendorId, vendorType, vendorValue) |
| `IRadiusPacket` | Packet structure (code, identifier, authenticator, attributes) |
| `IParsedRadiusPacket` | Packet with parsed attributes |
## Usage
```typescript
import {
ERadiusCode,
ERadiusAttributeType,
EAcctStatusType,
IRadiusPacket,
IParsedAttribute,
} from '@push.rocks/smartradius';
// Check packet type
if (packet.code === ERadiusCode.AccessRequest) {
// Handle authentication request
}
// Check accounting status
if (request.statusType === EAcctStatusType.Start) {
// Session started
}
// Access attribute by type
const username = packet.attributes.find(
a => a.type === ERadiusAttributeType.UserName
);
```
## Why a Shared Module?
This module provides clear separation between:
- **Protocol definitions** (what RADIUS is) - lives here
- **Server implementation** (how to serve RADIUS) - lives in ts_server
- **Client implementation** (how to consume RADIUS) - lives in ts_client
This separation provides:
- 🎯 Better semantic clarity for API consumers
- 📦 Smaller imports when only types are needed
- 🔄 Clean dependency graph (shared → server/client → main)

1
ts_shared/tspublish.json Normal file
View File

@@ -0,0 +1 @@
{ "order": 1 }