This commit is contained in:
@@ -139,4 +139,73 @@ struct LocalNetworkPolicyTests {
|
||||
#expect(candidates.contains("/Library/Preferences/\(LocalNetworkPolicy.domain).plist"))
|
||||
#expect(candidates.contains(NSHomeDirectory() + "/Library/Preferences/\(LocalNetworkPolicy.domain).plist"))
|
||||
}
|
||||
|
||||
// MARK: - Parsing preferences
|
||||
|
||||
/// A preferences file carrying `entries` under both allowlist keys.
|
||||
private func preferences(_ entries: [String]) throws -> Data {
|
||||
try PropertyListSerialization.data(
|
||||
fromPropertyList: [
|
||||
LocalNetworkPolicy.ethernetKey: entries,
|
||||
LocalNetworkPolicy.wifiKey: entries,
|
||||
"UnrelatedKey": "ignored",
|
||||
],
|
||||
format: .xml,
|
||||
options: 0)
|
||||
}
|
||||
|
||||
@Test("both keys are read, and the same entry in both is not counted twice")
|
||||
func entriesAreUnionedAcrossKeys() throws {
|
||||
let data = try preferences(["10.0.0.0/8", "192.168.0.0/16"])
|
||||
#expect(LocalNetworkPolicy.entries(inPreferences: data) == ["10.0.0.0/8", "192.168.0.0/16"])
|
||||
}
|
||||
|
||||
@Test("data that is not a preferences file reads as empty rather than throwing")
|
||||
func unparseablePreferencesReadEmpty() {
|
||||
#expect(LocalNetworkPolicy.entries(inPreferences: Data("not a plist".utf8)).isEmpty)
|
||||
#expect(LocalNetworkPolicy.entries(inPreferences: Data()).isEmpty)
|
||||
}
|
||||
|
||||
@Test("only files that contribute an entry are named as sources")
|
||||
func sourcePathsNameOnlyContributingFiles() throws {
|
||||
let empty = try preferences([])
|
||||
let real = try preferences(["192.168.0.0/16"])
|
||||
// The same entries again: a second copy of a value already seen adds
|
||||
// nothing, so its path must not be reported as a source.
|
||||
let duplicate = try preferences(["192.168.0.0/16"])
|
||||
|
||||
let status = LocalNetworkPolicy.status(fromContentsOf: [
|
||||
("/first.plist", empty),
|
||||
("/second.plist", real),
|
||||
("/third.plist", duplicate),
|
||||
])
|
||||
|
||||
#expect(status.allowlist == ["192.168.0.0/16"])
|
||||
#expect(status.sourcePaths == ["/second.plist"])
|
||||
#expect(status.coversGuestRange)
|
||||
}
|
||||
|
||||
@Test("an unreadable candidate makes the answer unknown, not unconfigured")
|
||||
func unreadableCandidatesAreIndeterminate() throws {
|
||||
// The real case: `sudo defaults write` lands in /var/root, which is
|
||||
// mode 700, so an ordinary user is refused before it can learn whether
|
||||
// the file is even there. Reporting that as "no allowlist" is how a
|
||||
// successful grant gets called a failure.
|
||||
let blind = LocalNetworkPolicy.status(
|
||||
fromContentsOf: [], unreadablePaths: ["/var/root/Library/Preferences/x.plist"])
|
||||
#expect(!blind.isConfigured)
|
||||
#expect(blind.isIndeterminate)
|
||||
|
||||
// Nothing found and nothing refused really is unconfigured.
|
||||
let empty = LocalNetworkPolicy.status(fromContentsOf: [])
|
||||
#expect(!empty.isConfigured)
|
||||
#expect(!empty.isIndeterminate)
|
||||
|
||||
// Something found outweighs a refusal elsewhere: the answer is known.
|
||||
let found = LocalNetworkPolicy.status(
|
||||
fromContentsOf: [("/a.plist", try preferences(["10.0.0.0/8"]))],
|
||||
unreadablePaths: ["/var/root/Library/Preferences/x.plist"])
|
||||
#expect(found.isConfigured)
|
||||
#expect(!found.isIndeterminate)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user