├── portable-color.sh ├── .gitmodules ├── README.md └── check-macos-installer /portable-color.sh: -------------------------------------------------------------------------------- 1 | portable-color/portable-color.sh -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "portable-color"] 2 | path = portable-color 3 | url = git@github.com:mattieb/portable-color.git 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # check-macos-installer 2 | 3 | A script that deeply validates a macOS installer. 4 | 5 | Inspired by Howard Oakley's [Checking a macOS installer app is easier with Taccy 1.6](https://eclecticlight.co/2019/10/28/checking-a-macos-installer-app-is-easier-with-taccy-1-6/), but command-line-ized. Tested with macOS High Sierra, Mojave, and Catalina installers. 6 | 7 | Depends on [portable-color](https://github.com/mattieb/portable-color), which is included as a submodule if you wish to use it directly from your clone. However, if portable-color has been installed to your PATH, check-macos-installer will find it. 8 | 9 | ## Installation 10 | 11 | I recommend you install or link "check-macos-installer" to `${HOME}/.local/bin`, and add this directory to your PATH if it is not already there. 12 | 13 | portable-color will work if you follow [its installation instructions](https://github.com/mattieb/portable-color#installation) and put "portable-color.sh" on your PATH as well. 14 | 15 | ## Usage 16 | 17 | Just point it at an installer app: 18 | 19 | ``` 20 | check-macos-installer "Install macOS Catalina.app" 21 | ``` 22 | -------------------------------------------------------------------------------- /check-macos-installer: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Copyright (c) 2023 Mattie Behrens. 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in all 13 | # copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | # 23 | 24 | . portable-color.sh || exit 1 25 | 26 | installer="$1" 27 | 28 | if [ -z "${installer}" ] 29 | then 30 | echo $(bold $(red usage:)) $0 INSTALLER 31 | exit 1 32 | fi 33 | 34 | echo_task() { 35 | echo $(green ==\>) $(bold $@) 36 | } 37 | 38 | echo_subtask () { 39 | echo $(blue ==\>) $(bold $@) 40 | } 41 | 42 | echo_result() { 43 | echo $@ 44 | "$@" 45 | if [ $? = 0 ] 46 | then 47 | echo $(bold $(green ==\> ✅ Passed)) 48 | else 49 | echo $(bold $(red ==\> ⛔️ Failed with exit code $?)) 50 | fi 51 | } 52 | 53 | echo_task Inspecting $(green ${installer}) 54 | 55 | set +e 56 | echo_subtask Assessing with security assessment policy tool: $(blue ${installer}) 57 | echo_result spctl --assess -vv "${installer}" 58 | echo_subtask Checking code signature: $(blue ${installer}) 59 | echo_result codesign -dvv "${installer}" 60 | 61 | imagefile="${installer}/Contents/SharedSupport/InstallESD.dmg" 62 | 63 | echo_task Evaluating packages in $(green "${imagefile}") 64 | 65 | set -e 66 | tempdir="$(mktemp -d)" 67 | echo_subtask Attaching 68 | hdiutil attach -readonly -noautoopen -mountpoint "${tempdir}" "${imagefile}" 69 | 70 | __cleanup() { 71 | set -e 72 | echo_task Cleaning up 73 | diskutil unmount "${tempdir}" 74 | rmdir "${tempdir}" 75 | } 76 | trap __cleanup EXIT 77 | 78 | find "${tempdir}" -name \*.pkg | ( 79 | while read pkgfile 80 | do 81 | set +e 82 | echo_subtask Assessing with security assessment policy tool: $(blue ${pkgfile}) 83 | echo_result spctl --assess -t install -vv "${pkgfile}" 84 | echo_subtask Checking package signature: $(blue ${pkgfile}) 85 | echo_result pkgutil --check-signature "${pkgfile}" 86 | done 87 | ) 88 | --------------------------------------------------------------------------------