Merge pull request #4796 from amyspark/quarantine-swift-clt

Cask: check that the tools for quarantining are available
This commit is contained in:
Mike McQuaid 2018-09-06 08:56:04 +01:00 committed by GitHub
commit 11ac4db05e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 102 additions and 49 deletions

View File

@ -22,6 +22,7 @@ module Hbc
def run def run
check_software_versions check_software_versions
check_quarantine_support
check_install_location check_install_location
check_staging_location check_staging_location
check_taps check_taps
@ -116,6 +117,23 @@ module Hbc
(locale_variables + environment_variables).sort.each(&method(:render_env_var)) (locale_variables + environment_variables).sort.each(&method(:render_env_var))
end end
def check_quarantine_support
ohai "Gatekeeper support"
status = Quarantine.check_quarantine_support
case status
when :quarantine_available
puts "Enabled"
when :no_swift
add_error "Swift is not available on this system."
when :no_quarantine
add_error "This feature requires the macOS 10.10 SDK or higher."
else
onoe "Unknown support status"
end
end
def user_tilde(path) def user_tilde(path)
self.class.user_tilde(path) self.class.user_tilde(path)
end end

View File

@ -186,7 +186,7 @@ module Hbc
return unless quarantine? return unless quarantine?
return unless Quarantine.available? return unless Quarantine.available?
Quarantine.propagate(from: @downloaded_path, to: @cask.staged_path, command: @command) Quarantine.propagate(from: @downloaded_path, to: @cask.staged_path)
end end
def install_artifacts def install_artifacts

View File

@ -12,10 +12,29 @@ module Hbc
@swift ||= DevelopmentTools.locate("swift") @swift ||= DevelopmentTools.locate("swift")
end end
def check_quarantine_support
odebug "Checking quarantine support"
if swift.nil?
odebug "Swift is not available on this system."
return :no_swift
end
api_check = system_command(swift, args: [QUARANTINE_SCRIPT])
if api_check.exit_status == 5
odebug "This feature requires the macOS 10.10 SDK or higher."
return :no_quarantine
end
odebug "Quarantine is available."
:quarantine_available
end
def available? def available?
status = !swift.nil? @status ||= check_quarantine_support
odebug "Quarantine is #{status ? "available" : "not available"}."
status @status == :quarantine_available
end end
def detect(file) def detect(file)
@ -30,24 +49,24 @@ module Hbc
quarantine_status quarantine_status
end end
def status(file, command: SystemCommand) def status(file)
command.run("/usr/bin/xattr", system_command("/usr/bin/xattr",
args: ["-p", QUARANTINE_ATTRIBUTE, file], args: ["-p", QUARANTINE_ATTRIBUTE, file],
print_stderr: false).stdout.rstrip print_stderr: false).stdout.rstrip
end end
def cask(cask: nil, download_path: nil, command: SystemCommand) def cask(cask: nil, download_path: nil)
return if cask.nil? || download_path.nil? return if cask.nil? || download_path.nil?
odebug "Quarantining #{download_path}" odebug "Quarantining #{download_path}"
quarantiner = command.run(swift, quarantiner = system_command(swift,
args: [ args: [
QUARANTINE_SCRIPT, QUARANTINE_SCRIPT,
download_path, download_path,
cask.url.to_s, cask.url.to_s,
cask.homepage.to_s, cask.homepage.to_s,
]) ])
return if quarantiner.success? return if quarantiner.success?
@ -59,18 +78,29 @@ module Hbc
end end
end end
def propagate(from: nil, to: nil, command: SystemCommand) def propagate(from: nil, to: nil)
return if from.nil? || to.nil? return if from.nil? || to.nil?
raise CaskError, "#{from} was not quarantined properly." unless detect(from) raise CaskError, "#{from} was not quarantined properly." unless detect(from)
odebug "Propagating quarantine from #{from} to #{to}" odebug "Propagating quarantine from #{from} to #{to}"
quarantine_status = status(from, command: command) quarantine_status = status(from)
quarantiner = command.run("/usr/bin/xattr", resolved_paths = Pathname.glob(to/"**/*", File::FNM_DOTMATCH)
args: ["-w", "-rs", QUARANTINE_ATTRIBUTE, quarantine_status, to],
print_stderr: false) quarantiner = system_command("/usr/bin/xargs",
args: [
"-0",
"--",
"/usr/bin/xattr",
"-w",
"-s",
QUARANTINE_ATTRIBUTE,
quarantine_status,
],
input: resolved_paths.join("\0"),
print_stderr: false)
return if quarantiner.success? return if quarantiner.success?

View File

@ -7,36 +7,41 @@ struct swifterr: TextOutputStream {
mutating func write(_ string: String) { fputs(string, stderr) } mutating func write(_ string: String) { fputs(string, stderr) }
} }
if (CommandLine.arguments.count < 4) { if #available(macOS 10.10, *) {
exit(2) if (CommandLine.arguments.count < 4) {
} exit(2)
let dataLocationUrl: NSURL = NSURL.init(fileURLWithPath: CommandLine.arguments[1])
var errorBag: NSError?
let quarantineProperties: [String: Any] = [
kLSQuarantineAgentNameKey as String: "Homebrew Cask",
kLSQuarantineTypeKey as String: kLSQuarantineTypeWebDownload,
kLSQuarantineDataURLKey as String: CommandLine.arguments[2],
kLSQuarantineOriginURLKey as String: CommandLine.arguments[3]
]
if (dataLocationUrl.checkResourceIsReachableAndReturnError(&errorBag)) {
do {
try dataLocationUrl.setResourceValue(
quarantineProperties as NSDictionary,
forKey: URLResourceKey.quarantinePropertiesKey
)
} }
catch {
print(error.localizedDescription, to: &swifterr.stream) let dataLocationUrl: NSURL = NSURL.init(fileURLWithPath: CommandLine.arguments[1])
exit(1)
var errorBag: NSError?
let quarantineProperties: [String: Any] = [
kLSQuarantineAgentNameKey as String: "Homebrew Cask",
kLSQuarantineTypeKey as String: kLSQuarantineTypeWebDownload,
kLSQuarantineDataURLKey as String: CommandLine.arguments[2],
kLSQuarantineOriginURLKey as String: CommandLine.arguments[3]
]
if (dataLocationUrl.checkResourceIsReachableAndReturnError(&errorBag)) {
do {
try dataLocationUrl.setResourceValue(
quarantineProperties as NSDictionary,
forKey: URLResourceKey.quarantinePropertiesKey
)
}
catch {
print(error.localizedDescription, to: &swifterr.stream)
exit(1)
}
} }
else {
print(errorBag!.localizedDescription, to: &swifterr.stream)
exit(3)
}
exit(0)
} }
else { else {
print(errorBag!.localizedDescription, to: &swifterr.stream) exit(5)
exit(3)
} }
exit(0)