From ee505b4e8b409ccd3c9f45029d5a789130f696f1 Mon Sep 17 00:00:00 2001 From: Tadayuki Onishi Date: Fri, 26 Oct 2018 21:03:06 +0900 Subject: [PATCH 1/4] Add verification of Xcode.app * Verify authority of first signing chain * Verify team identifier --- lib/xcode/install.rb | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/xcode/install.rb b/lib/xcode/install.rb index 2e828380..fc41c981 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") @@ -450,7 +450,14 @@ def prereleases def verify_integrity(path) puts `/usr/sbin/spctl --assess --verbose=4 --type execute #{path}` - $?.exitstatus.zero? + $?.exitstatus.zero? && verify_cert(path) + end + + def verify_cert(path) + cert_info = Fastlane::Actions::VerifyBuildAction.gather_cert_info(path) + apple_team_identifier_result = cert_info['team_identifier'] == '59GAB85EFG' + apple_authority_result = cert_info['authority'].include?('Apple Mac OS Application Signing') + apple_team_identifier_result && apple_authority_result end def hdiutil(*args) From ead4020d6c2fecf293eebf37346e4c7870fbf2a6 Mon Sep 17 00:00:00 2001 From: Tadayuki Onishi Date: Sun, 28 Oct 2018 20:44:18 +0900 Subject: [PATCH 2/4] Aggregate verification methods into the InstalledXcode class --- lib/xcode/install.rb | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/lib/xcode/install.rb b/lib/xcode/install.rb index fc41c981..b43b488d 100644 --- a/lib/xcode/install.rb +++ b/lib/xcode/install.rb @@ -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 @@ -450,14 +451,7 @@ def prereleases def verify_integrity(path) puts `/usr/sbin/spctl --assess --verbose=4 --type execute #{path}` - $?.exitstatus.zero? && verify_cert(path) - end - - def verify_cert(path) - cert_info = Fastlane::Actions::VerifyBuildAction.gather_cert_info(path) - apple_team_identifier_result = cert_info['team_identifier'] == '59GAB85EFG' - apple_authority_result = cert_info['authority'].include?('Apple Mac OS Application Signing') - apple_team_identifier_result && apple_authority_result + $?.exitstatus.zero? end def hdiutil(*args) @@ -585,6 +579,9 @@ def apply_variables(template) end class InstalledXcode + TEAM_IDENTIFIER = '59GAB85EFG'.freeze + AUTHORITY = 'Apple Mac OS Application Signing'.freeze + attr_reader :path attr_reader :version attr_reader :bundle_version @@ -662,6 +659,10 @@ def fetch_version output.split("\n").first.split(' ')[1] end + def verify_integrity + verify_app_security_assessment && verify_app_cert + end + :private def bundle_version_string @@ -676,6 +677,18 @@ 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 end # A version of Xcode we fetched from the Apple Developer Portal From fab68c56b3c3613689e0f8ac9750940475a5fe01 Mon Sep 17 00:00:00 2001 From: Tadayuki Onishi Date: Sun, 28 Oct 2018 20:56:56 +0900 Subject: [PATCH 3/4] Remove the verify_integrity method of Installer class because it does not use it --- lib/xcode/install.rb | 5 ----- 1 file changed, 5 deletions(-) diff --git a/lib/xcode/install.rb b/lib/xcode/install.rb index b43b488d..aeec5d59 100644 --- a/lib/xcode/install.rb +++ b/lib/xcode/install.rb @@ -449,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 From b579212f0da008c81ccaa2189e12e767770a5f90 Mon Sep 17 00:00:00 2001 From: Tadayuki Onishi Date: Sun, 28 Oct 2018 21:10:00 +0900 Subject: [PATCH 4/4] Add verifing component pkg files mechanism. --- lib/xcode/install.rb | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/lib/xcode/install.rb b/lib/xcode/install.rb index aeec5d59..b1e10db6 100644 --- a/lib/xcode/install.rb +++ b/lib/xcode/install.rb @@ -576,6 +576,7 @@ def apply_variables(template) 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 @@ -637,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,7 +656,7 @@ def fetch_version end def verify_integrity - verify_app_security_assessment && verify_app_cert + verify_app_security_assessment && verify_app_cert && verify_components end :private @@ -684,6 +685,20 @@ def verify_app_cert 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