Skip to content

Commit 148ed48

Browse files
committed
fix: use pint service principal for org controller RadSec client cert
The org controller cert was being requested under the "root" user principal, which does not exist in FreeIPA. Split issueClientCredentials into separate username (store key) and principal (FreeIPA principal + CSR CN) parameters so the org controller cert is issued to cfg.IPAPrincipal, matching how the RadSec server cert and signing cert are issued.
1 parent b2380d9 commit 148ed48

2 files changed

Lines changed: 12 additions & 10 deletions

File tree

internal/handlers/admin.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ func AdminRegenerateHandler(log *zap.Logger, ipaClient *freeipa.Client, cfg *con
7474
}
7575
existing := store.FindByUsername(username)
7676
revokeExistingCert(log, ipaClient, existing, cfg.RadSecCAName, freeipa.RevocationReasonSuperseded)
77-
entry, _, _, err := issueClientCredentials(ipaClient, cfg, username)
77+
entry, _, _, err := issueClientCredentials(ipaClient, cfg, username, username)
7878
if err != nil {
7979
log.Error("admin: credential regeneration failed", zap.String("target", username), zap.Error(err))
8080
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
@@ -106,7 +106,7 @@ func AdminRootProvisionHandler(log *zap.Logger, ipaClient *freeipa.Client, cfg *
106106
c.Redirect(http.StatusFound, "/admin/radius?warn="+url.QueryEscape("Root client already provisioned — use Regenerate to reissue credentials"))
107107
return
108108
}
109-
entry, keyPEM, certPEM, err := issueClientCredentials(ipaClient, cfg, rootUsername)
109+
entry, keyPEM, certPEM, err := issueClientCredentials(ipaClient, cfg, rootUsername, cfg.IPAPrincipal)
110110
if err != nil {
111111
log.Error("admin: root client provisioning failed", zap.Error(err))
112112
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
@@ -135,7 +135,7 @@ func AdminRootRegenerateHandler(log *zap.Logger, ipaClient *freeipa.Client, cfg
135135
}
136136
existing := store.FindByUsername(rootUsername)
137137
revokeExistingCert(log, ipaClient, existing, cfg.RadSecCAName, freeipa.RevocationReasonSuperseded)
138-
entry, keyPEM, certPEM, err := issueClientCredentials(ipaClient, cfg, rootUsername)
138+
entry, keyPEM, certPEM, err := issueClientCredentials(ipaClient, cfg, rootUsername, cfg.IPAPrincipal)
139139
if err != nil {
140140
log.Error("admin: root credential regeneration failed", zap.Error(err))
141141
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})

internal/handlers/radius.go

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ func SaveSecretHandler(log *zap.Logger, ipaClient *freeipa.Client, cfg *config.C
5050
if !ok {
5151
return
5252
}
53-
entry, keyPEM, certPEM, err := issueClientCredentials(ipaClient, cfg, nav.Username)
53+
entry, keyPEM, certPEM, err := issueClientCredentials(ipaClient, cfg, nav.Username, nav.Username)
5454
if err != nil {
5555
log.Error("radius enrollment failed", zap.Error(err))
5656
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
@@ -90,7 +90,7 @@ func RegenerateHandler(log *zap.Logger, ipaClient *freeipa.Client, cfg *config.C
9090
existing := store.FindByUsername(nav.Username)
9191
revokeExistingCert(log, ipaClient, existing, cfg.RadSecCAName, freeipa.RevocationReasonSuperseded)
9292

93-
entry, keyPEM, certPEM, err := issueClientCredentials(ipaClient, cfg, nav.Username)
93+
entry, keyPEM, certPEM, err := issueClientCredentials(ipaClient, cfg, nav.Username, nav.Username)
9494
if err != nil {
9595
log.Error("radius credential regeneration failed", zap.Error(err))
9696
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
@@ -219,16 +219,18 @@ func commitStore(c *gin.Context, log *zap.Logger, store *radius.ClientStore, k8s
219219
return "", nil
220220
}
221221

222-
// issueClientCredentials generates an EC key and RadSec client cert for username.
223-
// Returns the RadiusClient to store (no PEM fields), plus the one-time keyPEM and certPEM.
222+
// issueClientCredentials generates an EC key and RadSec client cert.
223+
// username is the store key; principal is the FreeIPA principal and CSR CN.
224+
// For user certs these are the same value; for the org controller cert, principal
225+
// is the pint service principal (cfg.IPAPrincipal) while username is the reserved key.
224226
// The RADIUS shared secret is always "radsec" and is not stored on the client.
225-
func issueClientCredentials(ipaClient *freeipa.Client, cfg *config.Config, username string) (*radius.RadiusClient, string, string, error) {
226-
privKey, csrPEM, err := profile.GenerateKeyAndCSR(username)
227+
func issueClientCredentials(ipaClient *freeipa.Client, cfg *config.Config, username, principal string) (*radius.RadiusClient, string, string, error) {
228+
privKey, csrPEM, err := profile.GenerateKeyAndCSR(principal)
227229
if err != nil {
228230
return nil, "", "", err
229231
}
230232

231-
certDER, err := ipaClient.CertRequest(username, string(csrPEM), cfg.RadSecCAName, cfg.RadSecClientCertProfile)
233+
certDER, err := ipaClient.CertRequest(principal, string(csrPEM), cfg.RadSecCAName, cfg.RadSecClientCertProfile)
232234
if err != nil {
233235
return nil, "", "", err
234236
}

0 commit comments

Comments
 (0)