mirror of
https://github.com/fleetdm/fleet
synced 2026-05-24 09:28:54 +00:00
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #42405 Demo video: https://www.youtube.com/watch?v=F3nfFvwdj-c # Checklist for submitter If some of the following don't apply, delete the relevant line. - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. ## Testing - [x] Added/updated automated tests - [x] QA'd all new/changed functionality manually <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Android Wi‑Fi configuration profiles that reference client certificates are withheld until the certificate is installed or reaches a terminal state. * Host OS settings now show the specific pending reason in the detail column when Android profiles are waiting on certificate installation. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
81 lines
2.7 KiB
Go
81 lines
2.7 KiB
Go
package android
|
|
|
|
import "encoding/json"
|
|
|
|
// ONC structs. Minimal types for extracting certificate alias references from
|
|
// Android's openNetworkConfiguration policy field (Chrome OS ONC spec).
|
|
|
|
type oncConfig struct {
|
|
NetworkConfigurations []oncNetworkConfiguration `json:"NetworkConfigurations"`
|
|
}
|
|
|
|
type oncNetworkConfiguration struct {
|
|
WiFi *oncEAPWrapper `json:"WiFi,omitempty"`
|
|
Ethernet *oncEAPWrapper `json:"Ethernet,omitempty"`
|
|
VPN *oncCertKeyHolder `json:"VPN,omitempty"`
|
|
}
|
|
|
|
// oncEAPWrapper is shared by WiFi and Ethernet, which nest the cert alias inside an EAP sub-object.
|
|
type oncEAPWrapper struct {
|
|
EAP *oncCertKeyHolder `json:"EAP,omitempty"`
|
|
}
|
|
|
|
// oncCertKeyHolder holds certificate client auth fields. ClientCertKeyPairAlias is only
|
|
// meaningful when ClientCertType is "KeyPairAlias" per the ONC spec; otherwise it is ignored.
|
|
type oncCertKeyHolder struct {
|
|
ClientCertType string `json:"ClientCertType,omitempty"`
|
|
ClientCertKeyPairAlias string `json:"ClientCertKeyPairAlias,omitempty"`
|
|
}
|
|
|
|
// extractAlias returns the ClientCertKeyPairAlias only when ClientCertType is "KeyPairAlias".
|
|
// Per the ONC spec, the alias field is ignored for all other ClientCertType values.
|
|
func extractAlias(h *oncCertKeyHolder) string {
|
|
if h.ClientCertType == "KeyPairAlias" && h.ClientCertKeyPairAlias != "" {
|
|
return h.ClientCertKeyPairAlias
|
|
}
|
|
return ""
|
|
}
|
|
|
|
// ExtractCertAliasesFromONC parses an openNetworkConfiguration JSON blob
|
|
// and returns all ClientCertKeyPairAlias values found.
|
|
func ExtractCertAliasesFromONC(oncJSON json.RawMessage) ([]string, error) {
|
|
var onc oncConfig
|
|
if err := json.Unmarshal(oncJSON, &onc); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
var aliases []string
|
|
for _, nc := range onc.NetworkConfigurations {
|
|
if nc.WiFi != nil && nc.WiFi.EAP != nil {
|
|
if a := extractAlias(nc.WiFi.EAP); a != "" {
|
|
aliases = append(aliases, a)
|
|
}
|
|
}
|
|
if nc.Ethernet != nil && nc.Ethernet.EAP != nil {
|
|
if a := extractAlias(nc.Ethernet.EAP); a != "" {
|
|
aliases = append(aliases, a)
|
|
}
|
|
}
|
|
if nc.VPN != nil {
|
|
if a := extractAlias(nc.VPN); a != "" {
|
|
aliases = append(aliases, a)
|
|
}
|
|
}
|
|
}
|
|
return aliases, nil
|
|
}
|
|
|
|
// ExtractCertAliasesFromProfileJSON parses an Android profile's raw JSON
|
|
// and returns any ClientCertKeyPairAlias values found in its
|
|
// openNetworkConfiguration field. Returns nil if no ONC field exists.
|
|
func ExtractCertAliasesFromProfileJSON(profileJSON json.RawMessage) ([]string, error) {
|
|
var fields map[string]json.RawMessage
|
|
if err := json.Unmarshal(profileJSON, &fields); err != nil {
|
|
return nil, err
|
|
}
|
|
oncJSON, hasONC := fields["openNetworkConfiguration"]
|
|
if !hasONC {
|
|
return nil, nil
|
|
}
|
|
return ExtractCertAliasesFromONC(oncJSON)
|
|
}
|