diff --git a/lib/xcode/install.rb b/lib/xcode/install.rb index 2e828380..b1e10db6 100644 --- a/lib/xcode/install.rb +++ b/lib/xcode/install.rb @@ -8,7 +8,7 @@ require 'xcode/install/version' require 'shellwords' require 'open3' -require 'fileutils' +require 'fastlane/actions/actions_helper' module XcodeInstall CACHE_DIR = Pathname.new("#{ENV['HOME']}/Library/Caches/XcodeInstall") @@ -250,13 +250,14 @@ def install_dmg(dmg_path, suffix = '', switch = true, clean = true) `umount "/Volumes/Xcode"` end - unless verify_integrity(xcode_path) + xcode = InstalledXcode.new(xcode_path) + + unless xcode.verify_integrity `sudo rm -rf #{xcode_path}` return end enable_developer_mode - xcode = InstalledXcode.new(xcode_path) xcode.approve_license xcode.install_components @@ -448,11 +449,6 @@ def prereleases links end - def verify_integrity(path) - puts `/usr/sbin/spctl --assess --verbose=4 --type execute #{path}` - $?.exitstatus.zero? - end - def hdiutil(*args) io = IO.popen(['hdiutil', *args]) result = io.read @@ -578,6 +574,10 @@ def apply_variables(template) end class InstalledXcode + TEAM_IDENTIFIER = '59GAB85EFG'.freeze + AUTHORITY = 'Apple Mac OS Application Signing'.freeze + COMPONENT_SIGNING_COMMON_NAME = 'Apple Software'.freeze + attr_reader :path attr_reader :version attr_reader :bundle_version @@ -638,7 +638,7 @@ def install_components if Gem::Version.new(version) >= Gem::Version.new('9') `sudo #{@path}/Contents/Developer/usr/bin/xcodebuild -runFirstLaunch` else - Dir.glob("#{@path}/Contents/Resources/Packages/*.pkg").each do |pkg| + component_pkg_paths.each do |pkg| `sudo installer -pkg #{pkg} -target /` end end @@ -655,6 +655,10 @@ def fetch_version output.split("\n").first.split(' ')[1] end + def verify_integrity + verify_app_security_assessment && verify_app_cert && verify_components + end + :private def bundle_version_string @@ -669,6 +673,32 @@ def bundle_version_string def plist_entry(keypath) `/usr/libexec/PlistBuddy -c "Print :#{keypath}" "#{path}/Contents/Info.plist"`.chomp end + + def verify_app_security_assessment + puts `/usr/sbin/spctl --assess --verbose=4 --type execute #{@path}` + $?.exitstatus.zero? + end + + def verify_app_cert + cert_info = Fastlane::Actions::VerifyBuildAction.gather_cert_info(@path) + apple_team_identifier_result = cert_info['team_identifier'] == TEAM_IDENTIFIER + apple_authority_result = cert_info['authority'].include?(AUTHORITY) + apple_team_identifier_result && apple_authority_result + end + + def verify_components + return true if Gem::Version.new(version) >= Gem::Version.new('9') + + result = component_pkg_paths.map do |pkg| + result = `pkgutil --verbose --check-signature #{pkg} | grep 'Status'` + result.strip.split(':')[1].strip == "signed #{COMPONENT_SIGNING_COMMON_NAME}" + end + result.all? + end + + def component_pkg_paths + @component_pkg_paths ||= Dir.glob(File.join(@path, 'Contents/Resources/Packages/*.pkg')) + end end # A version of Xcode we fetched from the Apple Developer Portal