You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

64 lines
1.8 KiB

import * as radius from 'radius';
import { IAuthentication } from '../types/Authentication';
import {IPacket, IPacketHandlerResult, PacketResponseCode} from '../types/PacketHandler';
import { PacketHandler } from './PacketHandler';
import PackageInterface from '../interface';
const packageInterface = PackageInterface.get();
export class RadiusService {
private packetHandler: PacketHandler;
constructor(private secret: string, authentication: IAuthentication) {
this.packetHandler = new PacketHandler(authentication);
}
defaultDecoder(msg: Buffer): { packet?: radius.RadiusPacket & IPacket; secret: string } {
const packet = radius.decode({ packet: msg, secret: this.secret });
return {
packet,
secret: this.secret,
};
}
async handleMessage(
msg: Buffer
): Promise<{ data: Buffer; expectAcknowledgment?: boolean } | undefined> {
const { packet, secret } = packageInterface.packetDecoder
? packageInterface.packetDecoder(msg)
: this.defaultDecoder(msg);
if (!packet) {
packageInterface.log('Unable to parse packet from message.');
return undefined;
}
if (packet.code !== 'Access-Request') {
packageInterface.log('unknown packet type: ', packet.code);
return undefined;
}
const response: IPacketHandlerResult = await this.packetHandler.handlePacket(packet);
// still no response, we are done here
if (!response || !response.code) {
return undefined;
}
// all fine, return radius encoded response
return {
data: radius.encode_response({
packet,
code: response.code,
secret,
attributes: response.attributes,
}),
// if message is accept or reject, we conside this as final message
// this means we do not expect a reponse from the client again (acknowledgement for package)
expectAcknowledgment: response.code === PacketResponseCode.AccessChallenge,
};
}
}