diff --git a/radiuscontroller/Services/AccountEnforcementService.cs b/radiuscontroller/Services/AccountEnforcementService.cs index 50a33af..706796a 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"; - // Remove Cleartext-Password from radcheck so FreeRADIUS rejects future auth + // Replace password with a zeroed NT-Password hash so mschap runs + // but always fails — returns MS-CHAP-Error E=691, prompting iOS + // to show "Incorrect Password" instead of "Unable to join network". var checks = await db.RadCheck .Where(rc => rc.Username == profile.Username) .ToListAsync(ct); db.RadCheck.RemoveRange(checks); - // Insert Auth-Type := Reject to explicitly deny db.RadCheck.Add(new RadCheck { Username = profile.Username, - Attribute = "Auth-Type", + Attribute = "NT-Password", Op = ":=", - Value = "Reject" + Value = "0x00000000000000000000000000000000" }); _logger.LogInformation("Account '{Username}' disabled. Reason: {Reason}", profile.Username, reason); diff --git a/radiuscontroller/Services/RadiusService.cs b/radiuscontroller/Services/RadiusService.cs index 164dffa..a7c7b2e 100644 --- a/radiuscontroller/Services/RadiusService.cs +++ b/radiuscontroller/Services/RadiusService.cs @@ -272,17 +272,18 @@ public class RadiusService : IRadiusService profile.Status = "Revoked"; - // Remove Cleartext-Password from radcheck so FreeRADIUS rejects future auth with MS-CHAP error 691, - // prompting iOS / clients to re-enter credentials instead of requiring 'Forget Network'. + // Replace password with a zeroed NT-Password hash so mschap runs + // but always fails — returns MS-CHAP-Error E=691, prompting iOS to show + // "Incorrect Password" instead of "Unable to join network". var checks = await _db.RadCheck.Where(rc => rc.Username == profile.Username).ToListAsync(); _db.RadCheck.RemoveRange(checks); _db.RadCheck.Add(new RadCheck { Username = profile.Username, - Attribute = "Auth-Type", + Attribute = "NT-Password", Op = ":=", - Value = "Reject" + Value = "0x00000000000000000000000000000000" }); await _db.SaveChangesAsync(); @@ -335,11 +336,6 @@ public class RadiusService : IRadiusService if (profile.Status == "Revoked") { profile.Status = "Active"; - var rejectCheck = await _db.RadCheck.FirstOrDefaultAsync(rc => rc.Username == profile.Username && rc.Attribute == "Auth-Type"); - if (rejectCheck != null) - { - _db.RadCheck.Remove(rejectCheck); - } } await _db.SaveChangesAsync(); diff --git a/radiuscontroller/raddb/mods-enabled/mschap b/radiuscontroller/raddb/mods-enabled/mschap index f1204b0..747312e 100644 --- a/radiuscontroller/raddb/mods-enabled/mschap +++ b/radiuscontroller/raddb/mods-enabled/mschap @@ -2,10 +2,4 @@ mschap { # Send MS-CHAP-Error with E=691 on authentication failure, # so iOS / Windows show "Incorrect Password" instead of "Unable to join network". send_error = yes - - # Force the rejection format to return the MSCHAPv2 failure code - # (Error 691 explicitly maps to an incorrect password on iOS) - passchange { - ntlm_auth = "/usr/bin/ntlm_auth" - } }