More RADIUS work

This commit is contained in:
2021-11-22 09:08:22 -06:00
parent 6e161dd383
commit ffbcf1b514
5 changed files with 96 additions and 38 deletions

View File

@@ -12,6 +12,38 @@ class RadiusUnit extends Unit {
return [...super.services, 'configs', 'output', 'models']
}
getPacketDecoder() {
const RadiusClient = this.models.get('radius:Client')
return async (msg) => {
const clients = await RadiusClient.find({ active: true })
// Try the secrets for all active clients.
// If we can successfully decode the packet with a client's secret, then we know
// that the message came from that client.
let authenticatedClient
let packet
for ( const client of clients ) {
try {
packet = radius.decode({ packet: msg, secret: client.secret })
authenticatedClient = client
break
} catch (e) {}
}
packet.credentialMiddleware = (username, password) => {
this.output.debug(`Called credential middleware: ${username}`)
return [`${username}@${authenticatedClient.id}`, password]
}
return {
packet,
secret: authenticatedClient.secret || '',
}
}
}
async go(app) {
if ( !(await this.port_free()) ) {
this.output.info('RADIUS server port is in use. Will not start!')
@@ -19,15 +51,27 @@ class RadiusUnit extends Unit {
}
const config = this.getConfig()
const packageInterface = require('@coreid/radius-server/dist/interface').default.get()
packageInterface.setConfig(config)
packageInterface.packetDecoder = this.getPacketDecoder()
packageInterface.log = (...any) => any.forEach(x => this.output.info(x))
const { RadiusServer } = require('@coreid/radius-server/dist/radius/RadiusServer')
const server = RadiusServer.get()
await server.up()
this.output.success('Started RADIUS server!')
// await packageInterface.up()
// Overwrite radius-server's global config object with the user-provided values
const radiusConfig = require('radius-server/config')
/*const radiusConfig = require('radius-server/config')
for ( const key in config ) {
if ( !Object.hasOwnProperty.apply(config, [key]) ) continue
radiusConfig[key] = config[key]
}
}*/
const { Authentication } = require('radius-server/dist/auth')
/*const { Authentication } = require('radius-server/dist/auth')
const { UDPServer } = require('radius-server/dist/server/UDPServer')
const { RadiusService } = require('radius-server/dist/radius/RadiusService')
@@ -65,15 +109,21 @@ class RadiusUnit extends Unit {
// Start the radius server
await this.server.start()
this.output.success('Started RADIUS server!')
this.output.success('Started RADIUS server!')*/
}
async cleanup(app) {
if ( this.server ) {
const { RadiusServer } = require('@coreid/radius-server/dist/radius/RadiusServer')
const server = RadiusServer.get()
await server.down()
// const packageInterface = require('@coreid/radius-server/dist/interface').get()
// await packageInterface.down()
/*if ( this.server ) {
// radius-server doesn't expose a "close" method explicitly, which is annoying
// instead, reach in and close the internal UDP socket
this.server.server.close()
}
}*/
}
/**
@@ -92,7 +142,7 @@ class RadiusUnit extends Unit {
let packet
for ( const client of clients ) {
try {
packet = radius.decode({ packet: msg, secret: client.secret })
packet = radius.decode({ packet: msg, secret: this.getConfig().secret /*client.secret*/ })
authenticatedClient = client
break
} catch (e) {}
@@ -107,12 +157,14 @@ class RadiusUnit extends Unit {
// This allows us to check IAM access in the controller
packet.attributes['User-Name'] = `${packet.attributes['User-Name']}@${authenticatedClient.id}`
this.output.info(`RADIUS auth attempt: ${packet.attributes['User-Name']}`)
this.output.debug(packet)
const response = await this.radiusService.packetHandler.handlePacket(packet)
// still no response, we are done here
if (!response || !response.code) {
this.output.debug(`RADIUS error: no response / response code`)
this.output.debug(response)
return
}
@@ -121,7 +173,7 @@ class RadiusUnit extends Unit {
data: radius.encode_response({
packet,
code: response.code,
secret: authenticatedClient.secret, // use the client's secret to encode the response
secret: this.getConfig().secret, // authenticatedClient.secret, // use the client's secret to encode the response
attributes: response.attributes,
}),
@@ -150,7 +202,7 @@ class RadiusUnit extends Unit {
const config = {
port: this.configs.get('radius.port', 1812),
secret: uuid(), // this is never used - client-specific secrets are injected instead
secret: 'testing123', // uuid(), // this is never used - client-specific secrets are injected instead
certificate: {
cert: fs.readFileSync(this.configs.get('radius.cert_file.public')),
key: [