adb-toolkit/backend_overview.go

98 lines
2.9 KiB
Go

package main
import (
"strings"
"sync"
)
// SecurityOverview is a quick at-a-glance device security/diagnostic summary
// for the Dashboard. All fields are best-effort (N/A when unavailable).
type SecurityOverview struct {
Root string `json:"root"`
SELinux string `json:"selinux"`
VerifiedBoot string `json:"verifiedBoot"`
BootloaderLocked string `json:"bootloaderLocked"`
Encryption string `json:"encryption"`
SecurityPatch string `json:"securityPatch"`
DmVerity string `json:"dmVerity"`
Debuggable string `json:"debuggable"`
Secure string `json:"secure"`
BuildType string `json:"buildType"`
BuildTags string `json:"buildTags"`
AdbEnabled string `json:"adbEnabled"`
DevOptions string `json:"devOptions"`
}
// GetSecurityOverview gathers security-relevant device state concurrently.
func (a *App) GetSecurityOverview() (SecurityOverview, error) {
var o SecurityOverview
var wg sync.WaitGroup
var mu sync.Mutex
run := func(f func()) { wg.Add(1); go func() { defer wg.Done(); f() }() }
put := func(set func()) { mu.Lock(); set(); mu.Unlock() }
run(func() {
su, _ := a.runAdbShell("which", "su")
put(func() {
if strings.TrimSpace(su) != "" {
o.Root = "su present"
} else {
o.Root = "not detected"
}
})
})
run(func() {
e, _ := a.runAdbShell("getenforce")
if e = strings.TrimSpace(e); e != "" {
put(func() { o.SELinux = e })
}
})
run(func() {
v := a.getProp("ro.boot.verifiedbootstate")
put(func() { o.VerifiedBoot = v })
})
run(func() {
locked := a.getProp("ro.boot.flash.locked")
put(func() {
switch locked {
case "1":
o.BootloaderLocked = "Locked"
case "0":
o.BootloaderLocked = "Unlocked"
default:
o.BootloaderLocked = "unknown"
}
})
})
run(func() {
st, ty := a.getProp("ro.crypto.state"), a.getProp("ro.crypto.type")
put(func() {
if ty != "" && ty != "N/A" {
o.Encryption = st + " (" + ty + ")"
} else {
o.Encryption = st
}
})
})
run(func() { v := a.getProp("ro.build.version.security_patch"); put(func() { o.SecurityPatch = v }) })
run(func() { v := a.getProp("ro.boot.veritymode"); put(func() { o.DmVerity = v }) })
run(func() { v := a.getProp("ro.debuggable"); put(func() { o.Debuggable = v }) })
run(func() { v := a.getProp("ro.secure"); put(func() { o.Secure = v }) })
run(func() { v := a.getProp("ro.build.type"); put(func() { o.BuildType = v }) })
run(func() { v := a.getProp("ro.build.tags"); put(func() { o.BuildTags = v }) })
run(func() {
v, _ := a.runAdbShell("settings", "get", "global", "adb_enabled")
if v = strings.TrimSpace(v); v != "" {
put(func() { o.AdbEnabled = v })
}
})
run(func() {
v, _ := a.runAdbShell("settings", "get", "global", "development_settings_enabled")
if v = strings.TrimSpace(v); v != "" {
put(func() { o.DevOptions = v })
}
})
wg.Wait()
return o, nil
}