1#!/bin/bash 2# 3# USAGE 4# notarize-dmg -u <developer id> "/path/to/Wireshark x.y.z arch.dmg" 5 6# https://developer.apple.com/documentation/security/notarizing_your_app_before_distribution 7# https://developer.apple.com/documentation/security/notarizing_your_app_before_distribution/customizing_the_notarization_workflow 8 9bundle_id="org.wireshark.dmg.$( printf "%04x" $RANDOM )" 10 11# Parse command line arguments 12while getopts u: OPTCHAR 13do 14 case $OPTCHAR in 15 u) 16 username="$OPTARG" 17 shift 2 18 ;; 19 *) 20 echo "Invalid command line option" 21 exit 2 ;; 22 esac 23done 24 25dmg_file="$1" 26 27if [[ "$username" != *?@*? ]] ; then 28 echo "Username doesn't appear to be a valid Apple developer ID." 29 exit 1 30fi 31 32if [ ! -r "$dmg_file" ] ; then 33 echo "Can't find file: ${dmg_file:-No file specified}" 34 exit 1 35fi 36 37# XXX Set account to $username instead? 38generic_pw_service="WS_DMG_NOTARIZE" 39 40if ! security find-generic-password -a "$username" -s "$generic_pw_service" > /dev/null 2>&1 ; then 41 echo -e "No keychain credentials found. You can add them by running\\n" 42 echo -e " security add-generic-password -a $username -s $generic_pw_service -T altool -w\\n" 43 exit 2 44fi 45 46echo -e "Notarizing $dmg_file\\n" 47echo -e "SHA256 pre: $(shasum -a 256 "$dmg_file" | awk '{print $1}' )\\n" 48 49if ! altool_out=$( mktemp /tmp/notarize-dmg.out.XXXXX ) ; then 50 echo "Unable to create temp file" 51 exit 1 52fi 53# trap 'rm -f "$altool_out"' EXIT 54 55xcrun altool \ 56 --notarize-app \ 57 --type osx \ 58 --username "$username" \ 59 --password "@keychain:${generic_pw_service}" \ 60 --primary-bundle-id "$bundle_id" \ 61 --file "$dmg_file" \ 62 2>&1 | tee "$altool_out" 63 64request_uuid=$( awk '/^RequestUUID/ { print $3 }' < "$altool_out") 65if [[ "$request_uuid" != *-*-*-*-* ]] ; then 66 echo "Unable to fetch request UUID" 67 exit 1 68fi 69 70eval_info_cmd=(xcrun altool \ 71 --eval-info "$request_uuid" \ 72 --user "$username" \ 73 --password "@keychain:${generic_pw_service}" \ 74 ) 75 76start=$SECONDS 77 78max_status_wait=$(( 20 * 60)) 79start=$SECONDS 80while true ; do 81 printf "\\nWaiting 15s \xe2\x80\xa6 " 82 sleep 15 83 elapsed=$(( SECONDS - start )) 84 echo "done. Checking status after ${elapsed}s" 85 "${eval_info_cmd[@]}" 2>&1 | tee "$altool_out" 86 grep "Status: in progress" "$altool_out" > /dev/null 2>&1 || break 87 if [[ $elapsed -gt $max_status_wait ]] ; then break ; fi 88done 89 90staple_cmd=(xcrun stapler staple "$dmg_file") 91 92if ! grep "Status: success" "$altool_out" > /dev/null 2>&1 ; then 93 echo "Notarization failed or timed out:" 94 cat "$altool_out" 95 echo -e "\\nInfo command:" 96 echo "${eval_info_cmd[@]}" 97 echo -e "\\nStaple command:" 98 echo "${staple_cmd[@]}" 99 echo "You can check the status of the Notary Service at https://developer.apple.com/system-status/." 100 exit 1 101fi 102 103echo -e "\\nStapling $dmg_file" 104"${staple_cmd[@]}" 105 106echo -e "\\nSHA256 post: $(shasum -a 256 "$dmg_file" | awk '{print $1}' )" 107 108# macOS 10.14.5+ requires notarization in order for this to pass? 109# https://wiki.lazarus.freepascal.org/Notarization_for_macOS_10.14.5%2B 110spctl --assess --type open --context context:primary-signature --verbose=2 "$dmg_file" || exit 1 111