From 3b20b7481e4b7798925f4856697c1d346b6fcd14 Mon Sep 17 00:00:00 2001 From: Tygozwolle Date: Fri, 24 Jul 2026 20:33:08 +0200 Subject: [PATCH] feat: implement RadiusService for guest registration, session management, and usage tracking with AccountEnforcementService support. --- .../Services/AccountEnforcementService.cs | 23 ++++++++++--------- radiuscontroller/Services/RadiusService.cs | 21 ++++++++--------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/radiuscontroller/Services/AccountEnforcementService.cs b/radiuscontroller/Services/AccountEnforcementService.cs index c6ea89f..50a33af 100644 --- a/radiuscontroller/Services/AccountEnforcementService.cs +++ b/radiuscontroller/Services/AccountEnforcementService.cs @@ -87,19 +87,20 @@ public class AccountEnforcementService : BackgroundService // Disable the account profile.Status = "Expired"; - // Scramble the password so the device prompts for new credentials - var check = await db.RadCheck.FirstOrDefaultAsync(rc => rc.Username == profile.Username && rc.Attribute == "Cleartext-Password", ct); - if (check != null) - { - check.Value = "REJECT_" + Guid.NewGuid().ToString("N").Substring(0, 8); - } + // Remove Cleartext-Password from radcheck so FreeRADIUS rejects future auth + var checks = await db.RadCheck + .Where(rc => rc.Username == profile.Username) + .ToListAsync(ct); + db.RadCheck.RemoveRange(checks); - // Cleanup any old Auth-Type Reject entries - var rejectCheck = await db.RadCheck.FirstOrDefaultAsync(rc => rc.Username == profile.Username && rc.Attribute == "Auth-Type", ct); - if (rejectCheck != null) + // Insert Auth-Type := Reject to explicitly deny + db.RadCheck.Add(new RadCheck { - db.RadCheck.Remove(rejectCheck); - } + Username = profile.Username, + Attribute = "Auth-Type", + Op = ":=", + Value = "Reject" + }); _logger.LogInformation("Account '{Username}' disabled. Reason: {Reason}", profile.Username, reason); diff --git a/radiuscontroller/Services/RadiusService.cs b/radiuscontroller/Services/RadiusService.cs index cf0be54..ac1bca5 100644 --- a/radiuscontroller/Services/RadiusService.cs +++ b/radiuscontroller/Services/RadiusService.cs @@ -272,18 +272,17 @@ public class RadiusService : IRadiusService profile.Status = "Revoked"; - // Scramble the password instead of Auth-Type := Reject so devices prompt for new credentials - var check = await _db.RadCheck.FirstOrDefaultAsync(rc => rc.Username == profile.Username && rc.Attribute == "Cleartext-Password"); - if (check != null) - { - check.Value = "REJECT_" + Guid.NewGuid().ToString("N").Substring(0, 8); - } + // Remove Cleartext-Password and insert Auth-Type := Reject + var checks = await _db.RadCheck.Where(rc => rc.Username == profile.Username).ToListAsync(); + _db.RadCheck.RemoveRange(checks); - var rejectCheck = await _db.RadCheck.FirstOrDefaultAsync(rc => rc.Username == profile.Username && rc.Attribute == "Auth-Type"); - if (rejectCheck != null) + _db.RadCheck.Add(new RadCheck { - _db.RadCheck.Remove(rejectCheck); - } + Username = profile.Username, + Attribute = "Auth-Type", + Op = ":=", + Value = "Reject" + }); await _db.SaveChangesAsync(); @@ -332,7 +331,7 @@ public class RadiusService : IRadiusService }); } - if (profile.Status == "Revoked" || profile.Status == "Expired") + if (profile.Status == "Revoked") { profile.Status = "Active"; var rejectCheck = await _db.RadCheck.FirstOrDefaultAsync(rc => rc.Username == profile.Username && rc.Attribute == "Auth-Type");