Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add verification of components in Xcode.app #314

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 39 additions & 9 deletions lib/xcode/install.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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?
Copy link
Collaborator Author

@kenchan0130 kenchan0130 Dec 26, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have thought that you can verify comprehensively by checking root ca.

I'll try to change this logic.

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
Expand Down