|
|
@ -12,6 +12,38 @@ class RadiusUnit extends Unit {
|
|
|
|
return [...super.services, 'configs', 'output', 'models']
|
|
|
|
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) {
|
|
|
|
async go(app) {
|
|
|
|
if ( !(await this.port_free()) ) {
|
|
|
|
if ( !(await this.port_free()) ) {
|
|
|
|
this.output.info('RADIUS server port is in use. Will not start!')
|
|
|
|
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 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
|
|
|
|
// 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 ) {
|
|
|
|
for ( const key in config ) {
|
|
|
|
if ( !Object.hasOwnProperty.apply(config, [key]) ) continue
|
|
|
|
if ( !Object.hasOwnProperty.apply(config, [key]) ) continue
|
|
|
|
radiusConfig[key] = config[key]
|
|
|
|
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 { UDPServer } = require('radius-server/dist/server/UDPServer')
|
|
|
|
const { RadiusService } = require('radius-server/dist/radius/RadiusService')
|
|
|
|
const { RadiusService } = require('radius-server/dist/radius/RadiusService')
|
|
|
|
|
|
|
|
|
|
|
@ -65,15 +109,21 @@ class RadiusUnit extends Unit {
|
|
|
|
|
|
|
|
|
|
|
|
// Start the radius server
|
|
|
|
// Start the radius server
|
|
|
|
await this.server.start()
|
|
|
|
await this.server.start()
|
|
|
|
this.output.success('Started RADIUS server!')
|
|
|
|
this.output.success('Started RADIUS server!')*/
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async cleanup(app) {
|
|
|
|
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
|
|
|
|
// radius-server doesn't expose a "close" method explicitly, which is annoying
|
|
|
|
// instead, reach in and close the internal UDP socket
|
|
|
|
// instead, reach in and close the internal UDP socket
|
|
|
|
this.server.server.close()
|
|
|
|
this.server.server.close()
|
|
|
|
}
|
|
|
|
}*/
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -92,7 +142,7 @@ class RadiusUnit extends Unit {
|
|
|
|
let packet
|
|
|
|
let packet
|
|
|
|
for ( const client of clients ) {
|
|
|
|
for ( const client of clients ) {
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
packet = radius.decode({ packet: msg, secret: client.secret })
|
|
|
|
packet = radius.decode({ packet: msg, secret: this.getConfig().secret /*client.secret*/ })
|
|
|
|
authenticatedClient = client
|
|
|
|
authenticatedClient = client
|
|
|
|
break
|
|
|
|
break
|
|
|
|
} catch (e) {}
|
|
|
|
} catch (e) {}
|
|
|
@ -107,12 +157,14 @@ class RadiusUnit extends Unit {
|
|
|
|
// This allows us to check IAM access in the controller
|
|
|
|
// This allows us to check IAM access in the controller
|
|
|
|
packet.attributes['User-Name'] = `${packet.attributes['User-Name']}@${authenticatedClient.id}`
|
|
|
|
packet.attributes['User-Name'] = `${packet.attributes['User-Name']}@${authenticatedClient.id}`
|
|
|
|
this.output.info(`RADIUS auth attempt: ${packet.attributes['User-Name']}`)
|
|
|
|
this.output.info(`RADIUS auth attempt: ${packet.attributes['User-Name']}`)
|
|
|
|
|
|
|
|
this.output.debug(packet)
|
|
|
|
|
|
|
|
|
|
|
|
const response = await this.radiusService.packetHandler.handlePacket(packet)
|
|
|
|
const response = await this.radiusService.packetHandler.handlePacket(packet)
|
|
|
|
|
|
|
|
|
|
|
|
// still no response, we are done here
|
|
|
|
// still no response, we are done here
|
|
|
|
if (!response || !response.code) {
|
|
|
|
if (!response || !response.code) {
|
|
|
|
this.output.debug(`RADIUS error: no response / response code`)
|
|
|
|
this.output.debug(`RADIUS error: no response / response code`)
|
|
|
|
|
|
|
|
this.output.debug(response)
|
|
|
|
return
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -121,7 +173,7 @@ class RadiusUnit extends Unit {
|
|
|
|
data: radius.encode_response({
|
|
|
|
data: radius.encode_response({
|
|
|
|
packet,
|
|
|
|
packet,
|
|
|
|
code: response.code,
|
|
|
|
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,
|
|
|
|
attributes: response.attributes,
|
|
|
|
}),
|
|
|
|
}),
|
|
|
|
|
|
|
|
|
|
|
@ -150,7 +202,7 @@ class RadiusUnit extends Unit {
|
|
|
|
|
|
|
|
|
|
|
|
const config = {
|
|
|
|
const config = {
|
|
|
|
port: this.configs.get('radius.port', 1812),
|
|
|
|
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: {
|
|
|
|
certificate: {
|
|
|
|
cert: fs.readFileSync(this.configs.get('radius.cert_file.public')),
|
|
|
|
cert: fs.readFileSync(this.configs.get('radius.cert_file.public')),
|
|
|
|
key: [
|
|
|
|
key: [
|
|
|
|