More RADIUS work
This commit is contained in:
parent
6e161dd383
commit
ffbcf1b514
1
.gitignore
vendored
1
.gitignore
vendored
@ -150,3 +150,4 @@ tmp.uploads/*
|
|||||||
!tmp.uploads/.gitkeep
|
!tmp.uploads/.gitkeep
|
||||||
uploads/*
|
uploads/*
|
||||||
!uploads/.gitkeep
|
!uploads/.gitkeep
|
||||||
|
ttls-pap.conf
|
||||||
|
@ -9,6 +9,9 @@ class RadiusController extends Controller {
|
|||||||
const User = this.models.get('auth:User')
|
const User = this.models.get('auth:User')
|
||||||
const Client = this.models.get('radius:Client')
|
const Client = this.models.get('radius:Client')
|
||||||
|
|
||||||
|
this.output.debug('RADIUS attempt:')
|
||||||
|
this.output.debug(req.body)
|
||||||
|
|
||||||
if ( !req.body.username || !req.body.password ) {
|
if ( !req.body.username || !req.body.password ) {
|
||||||
this.output.error('RADIUS error: missing username or password')
|
this.output.error('RADIUS error: missing username or password')
|
||||||
return this.fail(res)
|
return this.fail(res)
|
||||||
@ -21,7 +24,9 @@ class RadiusController extends Controller {
|
|||||||
parts.reverse()
|
parts.reverse()
|
||||||
|
|
||||||
const username = parts.join('@')
|
const username = parts.join('@')
|
||||||
const password = req.body.password
|
const password = String(req.body.password).replace(/\0/g, '')
|
||||||
|
|
||||||
|
this.output.debug(`clientId: ${clientId}, username: ${username}, password: ${password}`)
|
||||||
|
|
||||||
const user = await User.findOne({ uid: username, active: true })
|
const user = await User.findOne({ uid: username, active: true })
|
||||||
if ( !user ) {
|
if ( !user ) {
|
||||||
|
@ -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: [
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
"author": "Garrett Mills <garrett@glmdev.tech> (https://garrettmills.dev/)",
|
"author": "Garrett Mills <garrett@glmdev.tech> (https://garrettmills.dev/)",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@coreid/radius-server": "^1.2.6",
|
||||||
"bullmq": "^1.8.8",
|
"bullmq": "^1.8.8",
|
||||||
"email-validator": "^2.0.4",
|
"email-validator": "^2.0.4",
|
||||||
"flitter-auth": "^0.19.6",
|
"flitter-auth": "^0.19.6",
|
||||||
@ -40,7 +41,6 @@
|
|||||||
"oidc-provider": "^6.29.0",
|
"oidc-provider": "^6.29.0",
|
||||||
"qrcode": "^1.4.4",
|
"qrcode": "^1.4.4",
|
||||||
"radius": "^1.1.4",
|
"radius": "^1.1.4",
|
||||||
"radius-server": "^1.2.0",
|
|
||||||
"samlp": "^3.4.1",
|
"samlp": "^3.4.1",
|
||||||
"speakeasy": "^2.0.0",
|
"speakeasy": "^2.0.0",
|
||||||
"uuid": "^8.3.0",
|
"uuid": "^8.3.0",
|
||||||
|
54
yarn.lock
54
yarn.lock
@ -182,7 +182,24 @@
|
|||||||
lodash "^4.17.13"
|
lodash "^4.17.13"
|
||||||
to-fast-properties "^2.0.0"
|
to-fast-properties "^2.0.0"
|
||||||
|
|
||||||
"@hokify/node-ts-cache@^5.4.1":
|
"@coreid/radius-server@^1.2.6":
|
||||||
|
version "1.2.6"
|
||||||
|
resolved "https://registry.yarnpkg.com/@coreid/radius-server/-/radius-server-1.2.6.tgz#51914c20740a5ba7a3eed36deb67f3def4e69ced"
|
||||||
|
integrity sha512-oYmEytDUf1uiTd+pnqHlODXoz/ybjkPZpEjUmB9gjF/DQ/PwwiUDtRXfRLD6fjkY58Z4y4LF4YXDilAgSnPWlA==
|
||||||
|
dependencies:
|
||||||
|
"@hokify/node-ts-cache" "^5.5.1"
|
||||||
|
axios "^0.21.1"
|
||||||
|
debug "^4.3.1"
|
||||||
|
imap-simple "^5.0.0"
|
||||||
|
ldapauth-fork "^5.0.1"
|
||||||
|
ldapjs "^2.3.0"
|
||||||
|
native-duplexpair "^1.0.0"
|
||||||
|
node-cache "^5.1.2"
|
||||||
|
radius "~1.1.4"
|
||||||
|
smtp-client "^0.4.0"
|
||||||
|
yargs "~17.0.1"
|
||||||
|
|
||||||
|
"@hokify/node-ts-cache@^5.5.1":
|
||||||
version "5.6.0"
|
version "5.6.0"
|
||||||
resolved "https://registry.yarnpkg.com/@hokify/node-ts-cache/-/node-ts-cache-5.6.0.tgz#47a7b9f2be426c03f1c1d92adcecfda06e3fa60c"
|
resolved "https://registry.yarnpkg.com/@hokify/node-ts-cache/-/node-ts-cache-5.6.0.tgz#47a7b9f2be426c03f1c1d92adcecfda06e3fa60c"
|
||||||
integrity sha512-VdjeFjLAT9gGrRlzjZsMeY9ZWJyfz8y8ODeZsUdSnDdwxqb0keZNAtS3PMswBzSECBfNV1RT+NGiC8j6P1Cv6w==
|
integrity sha512-VdjeFjLAT9gGrRlzjZsMeY9ZWJyfz8y8ODeZsUdSnDdwxqb0keZNAtS3PMswBzSECBfNV1RT+NGiC8j6P1Cv6w==
|
||||||
@ -3310,7 +3327,7 @@ ldapjs@^1.0.2:
|
|||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
dtrace-provider "~0.8"
|
dtrace-provider "~0.8"
|
||||||
|
|
||||||
ldapjs@^2.2.1, ldapjs@^2.2.3:
|
ldapjs@^2.2.1, ldapjs@^2.3.0:
|
||||||
version "2.3.1"
|
version "2.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/ldapjs/-/ldapjs-2.3.1.tgz#04136815fb1f21d692ac87fab5961a04d86e8b04"
|
resolved "https://registry.yarnpkg.com/ldapjs/-/ldapjs-2.3.1.tgz#04136815fb1f21d692ac87fab5961a04d86e8b04"
|
||||||
integrity sha512-kf0tHHLrpwKaBAQOhYHXgdeh2PkFuCCxWgLb1MRn67ZQVo787D2pij3mmHVZx193GIdM8xcfi8HF6AIYYnj0fQ==
|
integrity sha512-kf0tHHLrpwKaBAQOhYHXgdeh2PkFuCCxWgLb1MRn67ZQVo787D2pij3mmHVZx193GIdM8xcfi8HF6AIYYnj0fQ==
|
||||||
@ -4576,23 +4593,6 @@ quoted-printable@^1.0.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
utf8 "^2.1.0"
|
utf8 "^2.1.0"
|
||||||
|
|
||||||
radius-server@^1.2.0:
|
|
||||||
version "1.2.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/radius-server/-/radius-server-1.2.0.tgz#74d5932b66906c0b5ea7763bb11bb1c6a6a219e6"
|
|
||||||
integrity sha512-JRscm5uafissZMgJYFOemiUjnwpmIWEjVAL0O/tn9Fiy2mqPAX+xVKqWEopu2BZ7NZzHScqlQnVomLyzyHk08Q==
|
|
||||||
dependencies:
|
|
||||||
"@hokify/node-ts-cache" "^5.4.1"
|
|
||||||
axios "^0.21.1"
|
|
||||||
debug "^4.3.1"
|
|
||||||
imap-simple "^5.0.0"
|
|
||||||
ldapauth-fork "^5.0.1"
|
|
||||||
ldapjs "^2.2.3"
|
|
||||||
native-duplexpair "^1.0.0"
|
|
||||||
node-cache "^5.1.2"
|
|
||||||
radius "~1.1.4"
|
|
||||||
smtp-client "^0.3.3"
|
|
||||||
yargs "~16.2.0"
|
|
||||||
|
|
||||||
radius@^1.1.4, radius@~1.1.4:
|
radius@^1.1.4, radius@~1.1.4:
|
||||||
version "1.1.4"
|
version "1.1.4"
|
||||||
resolved "https://registry.yarnpkg.com/radius/-/radius-1.1.4.tgz#3ce58d18a497d615618bc7d9286464ebecb50cb5"
|
resolved "https://registry.yarnpkg.com/radius/-/radius-1.1.4.tgz#3ce58d18a497d615618bc7d9286464ebecb50cb5"
|
||||||
@ -5136,10 +5136,10 @@ smtp-channel@0.2.3:
|
|||||||
line-buffer "^0.1.4"
|
line-buffer "^0.1.4"
|
||||||
promised-timeout "^0.2.0"
|
promised-timeout "^0.2.0"
|
||||||
|
|
||||||
smtp-client@^0.3.3:
|
smtp-client@^0.4.0:
|
||||||
version "0.3.3"
|
version "0.4.0"
|
||||||
resolved "https://registry.yarnpkg.com/smtp-client/-/smtp-client-0.3.3.tgz#54f5211b5613f86cb801892e298c53f60cdde515"
|
resolved "https://registry.yarnpkg.com/smtp-client/-/smtp-client-0.4.0.tgz#2015da1f4d9821e67bf22ced01568b027d305245"
|
||||||
integrity sha512-bneg34/4sug5MAVROUaOgQFEEDQDcmv5qXa/E9mDdwjV9jOvexidMzGH9jR1cgQCsFh1yWrVToY0MCWvoVwWSA==
|
integrity sha512-TvxdX02b96hN6732TGkXcXHsaTeXgVMXjdAhYzz/pLGE6V1p/5jh1XYJa/PfE+O21jHLmwHYWVP3c7JNFWwmOg==
|
||||||
dependencies:
|
dependencies:
|
||||||
promised-timeout "0.5.1"
|
promised-timeout "0.5.1"
|
||||||
smtp-channel "0.2.3"
|
smtp-channel "0.2.3"
|
||||||
@ -5977,10 +5977,10 @@ yargs@^15.0.2:
|
|||||||
y18n "^4.0.0"
|
y18n "^4.0.0"
|
||||||
yargs-parser "^18.1.1"
|
yargs-parser "^18.1.1"
|
||||||
|
|
||||||
yargs@~16.2.0:
|
yargs@~17.0.1:
|
||||||
version "16.2.0"
|
version "17.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66"
|
resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.0.1.tgz#6a1ced4ed5ee0b388010ba9fd67af83b9362e0bb"
|
||||||
integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==
|
integrity sha512-xBBulfCc8Y6gLFcrPvtqKz9hz8SO0l1Ni8GgDekvBX2ro0HRQImDGnikfc33cgzcYUSncapnNcZDjVFIH3f6KQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
cliui "^7.0.2"
|
cliui "^7.0.2"
|
||||||
escalade "^3.1.1"
|
escalade "^3.1.1"
|
||||||
|
Loading…
Reference in New Issue
Block a user