Skip to content

Commit 011a75d

Browse files
committed
Refine posture model and update tests
1 parent eb9ef52 commit 011a75d

File tree

7 files changed

+265
-164
lines changed

7 files changed

+265
-164
lines changed

agent/internal/posture/default.go

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,29 @@ import "runtime"
66
type DefaultCollector struct{}
77

88
// CollectPosture returns minimal posture information for unsupported platforms
9-
func (_ *DefaultCollector) CollectPosture() (*DevicePosture, error) {
9+
func (c *DefaultCollector) CollectPosture() (*DevicePosture, error) {
10+
_ = c
1011
posture := &DevicePosture{
11-
OS: OperatingSystem{
12+
OS: &OperatingSystem{
1213
Name: UnknownValue,
1314
Version: UnknownValue,
1415
Build: UnknownValue,
1516
Arch: runtime.GOARCH,
1617
Kernel: UnknownValue,
1718
Supported: false,
1819
},
19-
Firewall: FirewallStatus{
20-
Enabled: false,
21-
Rules: DefaultRules,
20+
Firewall: &FirewallStatus{
2221
Service: UnknownService,
22+
Ports: nil,
23+
Rules: DefaultRules,
24+
Enabled: false,
25+
},
26+
SecurityFeatureSet: SecurityFeatureSet{
27+
AntiVirus: false,
28+
SystemUpdate: false,
29+
DiskEncrypted: false,
30+
ScreenLock: false,
2331
},
24-
AntiVirus: false,
25-
SystemUpdate: false,
26-
DiskEncrypted: false,
27-
ScreenLock: false,
2832
}
2933

3034
// Calculate trust score (will be low due to unknown status)

agent/internal/posture/linux.go

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,56 +8,55 @@ import (
88
const (
99
// OS constants
1010
linuxOSName = "Linux"
11-
11+
1212
// Service names
1313
ufwService = "ufw"
1414
iptablesService = "iptables"
15-
15+
1616
// Command keywords
1717
ufwStatusActive = "status: active"
1818
cryptoLUKS = "crypto_luks"
1919
cryptKeyword = "crypt"
2020
trueKeyword = "true"
21-
21+
2222
// Firewall rule keywords
2323
allowKeyword = "ALLOW"
2424
denyKeyword = "DENY"
2525
acceptKeyword = "ACCEPT"
2626
dropKeyword = "DROP"
2727
rejectKeyword = "REJECT"
28-
28+
2929
// Table headers to ignore
3030
chainPrefix = "Chain"
3131
targetPrefix = "target"
3232
numPrefix = "num"
3333
)
3434

35-
var (
36-
// Common Linux antivirus software
37-
linuxAntivirusSoftware = []string{"clamav", "sophos", "avast", "bitdefender", "eset"}
38-
)
35+
// Common Linux antivirus software
36+
var linuxAntivirusSoftware = []string{"clamav", "sophos", "avast", "bitdefender", "eset"}
3937

4038
// LinuxCollector collects device posture on Linux systems
4139
type LinuxCollector struct{}
4240

4341
// CollectPosture collects device posture information on Linux
4442
func (c *LinuxCollector) CollectPosture() (*DevicePosture, error) {
4543
posture := &DevicePosture{
46-
OS: OperatingSystem{
44+
OS: &OperatingSystem{
4745
Name: linuxOSName,
4846
Arch: runtime.GOARCH,
4947
},
48+
Firewall: &FirewallStatus{},
5049
}
5150

5251
// Collect OS information
53-
if err := c.collectOSInfo(&posture.OS); err != nil {
52+
if err := c.collectOSInfo(posture.OS); err != nil {
5453
return nil, err
5554
}
5655

5756
// Collect firewall status
58-
if err := c.collectFirewallStatus(&posture.Firewall); err != nil {
57+
if err := c.collectFirewallStatus(posture.Firewall); err != nil {
5958
// Non-fatal error, continue with default values
60-
posture.Firewall = FirewallStatus{Enabled: false, Service: UnknownService}
59+
*posture.Firewall = FirewallStatus{Service: UnknownService}
6160
}
6261

6362
// Collect other security posture information
@@ -132,8 +131,8 @@ func checkUFW(fw *FirewallStatus) bool {
132131
fw.Enabled = strings.Contains(strings.ToLower(output), ufwStatusActive)
133132

134133
// Count rules (simplified)
135-
lines := strings.Split(output, "\n")
136-
ruleCount := 0
134+
lines := strings.Split(output, newline)
135+
ruleCount := initialCapacity
137136
for _, line := range lines {
138137
line = strings.TrimSpace(line)
139138
if line != "" && !strings.HasPrefix(line, "Status:") &&
@@ -150,6 +149,7 @@ func checkUFW(fw *FirewallStatus) bool {
150149

151150
// checkIptables checks iptables firewall status
152151
func (c *LinuxCollector) checkIptables(fw *FirewallStatus) error {
152+
_ = c
153153
output, err := runCommand("iptables", "-L")
154154
if err != nil {
155155
fw.Enabled = false
@@ -160,7 +160,7 @@ func (c *LinuxCollector) checkIptables(fw *FirewallStatus) error {
160160
fw.Service = iptablesService
161161
// If iptables returns without error and has rules, consider it enabled
162162
lines := strings.Split(output, "\n")
163-
ruleCount := 0
163+
ruleCount := initialCapacity
164164
for _, line := range lines {
165165
line = strings.TrimSpace(line)
166166
if line != "" && !strings.HasPrefix(line, chainPrefix) &&
@@ -180,6 +180,7 @@ func (c *LinuxCollector) checkIptables(fw *FirewallStatus) error {
180180

181181
// checkAntiVirus checks for antivirus software
182182
func (c *LinuxCollector) checkAntiVirus() bool {
183+
_ = c
183184
// Check for common Linux antivirus solutions
184185
antivirusSoftware := linuxAntivirusSoftware
185186

@@ -199,12 +200,14 @@ func (c *LinuxCollector) checkAntiVirus() bool {
199200

200201
// checkSystemUpdated checks if system is up to date
201202
func (c *LinuxCollector) checkSystemUpdated() bool {
203+
_ = c
202204
// Check for pending updates (works on Debian/Ubuntu systems)
203205
output, err := runCommand("apt", "list", "--upgradable")
204206
if err == nil {
205-
lines := strings.Split(output, "\n")
207+
lines := strings.Split(output, newline)
206208
// If only header line, no updates available
207-
return len(lines) <= 2
209+
const headerAndFooterLines = 2
210+
return len(lines) <= headerAndFooterLines
208211
}
209212

210213
// Try yum/dnf for Red Hat systems
@@ -214,11 +217,12 @@ func (c *LinuxCollector) checkSystemUpdated() bool {
214217
return true
215218
}
216219

217-
return strings.TrimSpace(output) == ""
220+
return strings.TrimSpace(output) == emptyString
218221
}
219222

220223
// checkDiskEncryption checks if disk encryption is enabled
221224
func (c *LinuxCollector) checkDiskEncryption() bool {
225+
_ = c
222226
// Check for LUKS encrypted devices
223227
output, err := runCommand("lsblk", "-f")
224228
if err != nil {
@@ -232,6 +236,7 @@ func (c *LinuxCollector) checkDiskEncryption() bool {
232236

233237
// checkScreenLock checks if screen lock is configured
234238
func (c *LinuxCollector) checkScreenLock() bool {
239+
_ = c
235240
// Check GNOME settings
236241
if output, err := runCommand("gsettings", "get", "org.gnome.desktop.screensaver", "lock-enabled"); err == nil {
237242
return strings.Contains(strings.ToLower(output), trueKeyword)
@@ -248,6 +253,7 @@ func (c *LinuxCollector) checkScreenLock() bool {
248253

249254
// isOSSupported checks if the OS version is supported
250255
func (c *LinuxCollector) isOSSupported(osName string) bool {
256+
_ = c
251257
supportedDistros := []string{
252258
"ubuntu", "debian", "centos", "rhel", "fedora",
253259
"suse", "opensuse", "arch", "mint", "elementary",

agent/internal/posture/macos.go

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,27 +5,30 @@ import (
55
"strings"
66
)
77

8+
const macOSDefaultRuleCount = 1
9+
810
// MacOSCollector collects device posture on macOS systems
911
type MacOSCollector struct{}
1012

1113
// CollectPosture collects device posture information on macOS
1214
func (c *MacOSCollector) CollectPosture() (*DevicePosture, error) {
1315
posture := &DevicePosture{
14-
OS: OperatingSystem{
16+
OS: &OperatingSystem{
1517
Name: "macOS",
1618
Arch: runtime.GOARCH,
1719
},
20+
Firewall: &FirewallStatus{},
1821
}
1922

2023
// Collect OS information
21-
if err := c.collectOSInfo(&posture.OS); err != nil {
24+
if err := c.collectOSInfo(posture.OS); err != nil {
2225
return nil, err
2326
}
2427

2528
// Collect firewall status
26-
if err := c.collectFirewallStatus(&posture.Firewall); err != nil {
29+
if err := c.collectFirewallStatus(posture.Firewall); err != nil {
2730
// Non-fatal error, continue with default values
28-
posture.Firewall = FirewallStatus{Enabled: false, Service: UnknownService}
31+
*posture.Firewall = FirewallStatus{Service: UnknownService}
2932
}
3033

3134
// Collect other security posture information
@@ -69,9 +72,9 @@ func (c *MacOSCollector) collectOSInfo(os *OperatingSystem) error {
6972
// Extract version number
7073
parts = strings.Fields(versionInfo)
7174
if len(parts) >= minPartsTriple {
72-
os.Name = strings.Join(parts[:2], spaceSeparator)
73-
os.Version = parts[2]
74-
} else if len(parts) >= 2 {
75+
os.Name = strings.Join(parts[:keyValueParts], spaceSeparator)
76+
os.Version = parts[versionPartIndex]
77+
} else if len(parts) >= keyValueParts {
7578
os.Version = parts[len(parts)-indexIncrement]
7679
}
7780
}
@@ -91,6 +94,7 @@ func (c *MacOSCollector) collectOSInfo(os *OperatingSystem) error {
9194

9295
// collectFirewallStatus checks macOS firewall status
9396
func (c *MacOSCollector) collectFirewallStatus(fw *FirewallStatus) error {
97+
_ = c
9498
fw.Service = macOSFirewallService
9599

96100
// Check if firewall is enabled
@@ -104,14 +108,15 @@ func (c *MacOSCollector) collectFirewallStatus(fw *FirewallStatus) error {
104108

105109
// Get firewall rules (simplified - macOS firewall is less rule-based)
106110
if fw.Enabled {
107-
fw.Rules = 1
111+
fw.Rules = macOSDefaultRuleCount
108112
}
109113

110114
return nil
111115
}
112116

113117
// checkAntiVirus checks for antivirus software on macOS
114118
func (c *MacOSCollector) checkAntiVirus() bool {
119+
_ = c
115120
// Check for common macOS antivirus applications
116121
antivirusApps := []string{
117122
"/Applications/Bitdefender Virus Scanner.app",
@@ -147,6 +152,7 @@ func (c *MacOSCollector) checkAntiVirus() bool {
147152

148153
// checkSystemUpdated checks if system updates are available
149154
func (c *MacOSCollector) checkSystemUpdated() bool {
155+
_ = c
150156
// Check for available updates
151157
output, err := runCommand("softwareupdate", "-l")
152158
if err != nil {
@@ -161,6 +167,7 @@ func (c *MacOSCollector) checkSystemUpdated() bool {
161167

162168
// checkDiskEncryption checks if FileVault is enabled
163169
func (c *MacOSCollector) checkDiskEncryption() bool {
170+
_ = c
164171
output, err := runCommand("fdesetup", "status")
165172
if err != nil {
166173
return false
@@ -171,6 +178,7 @@ func (c *MacOSCollector) checkDiskEncryption() bool {
171178

172179
// checkScreenLock checks if screen lock/password is required
173180
func (c *MacOSCollector) checkScreenLock() bool {
181+
_ = c
174182
// Check if password is required after screensaver
175183
output, err := runCommand(defaultsCommand, readCommand, "com.apple.screensaver", macOSScreenPassword)
176184
if err == nil && strings.Contains(output, macOSPasswordEnabled) {
@@ -185,8 +193,7 @@ func (c *MacOSCollector) checkScreenLock() bool {
185193
}
186194

187195
// Check System Preferences security settings
188-
output, err = runCommand(defaultsCommand, readCommand, "com.apple.screensaver", macOSScreenDelay)
189-
if err == nil {
196+
if _, err = runCommand(defaultsCommand, readCommand, "com.apple.screensaver", macOSScreenDelay); err == nil {
190197
return true
191198
}
192199

@@ -195,13 +202,14 @@ func (c *MacOSCollector) checkScreenLock() bool {
195202

196203
// isOSSupported checks if the macOS version is supported
197204
func (c *MacOSCollector) isOSSupported(version string) bool {
205+
_ = c
198206
if version == "" {
199207
return false
200208
}
201209

202210
// Parse major version (e.g., "12.6.1" -> 12)
203211
parts := strings.Split(version, ".")
204-
if len(parts) == 0 {
212+
if len(parts) == initialCapacity {
205213
return false
206214
}
207215

0 commit comments

Comments
 (0)