From 519a170da3aa0a4a5511e87b0cc232c763a92ff1 Mon Sep 17 00:00:00 2001 From: Marcio Barbosa Date: Thu, 12 Dec 2024 14:51:11 -0800 Subject: [PATCH] DARWIN: Use notarytool for notarization At WWDC 2021, Apple introduced notarytool, a new utility for interacting with the Apple notary service. Concurrently, Apple deprecated altool for notarization purposes, with plans to discontinue its functionality on November 1, 2023. Currently, notarize.pl relies on the deprecated altool, which is no longer supported. This commit updates this script to use notarytool, ensuring it remains fully functional for notarizing the OpenAFS package. Note that the arguments for notarize.pl have changed. Users can no longer provide a plain password or keychain reference using the @keychain prefix. Instead, a keychain profile for the credentials must be created first, with the profile name provided as an argument. This change is mandated by the new notarytool workflow. Additionally, update pkgbuild.sh.in, as this script calls notarize.pl if the --apple-id option is provided. Since notarize.pl now requires a keychain profile name instead of an Apple ID and password, remove the --apple-id option from pkgbuild.sh.in and introduce a new option, --keychain-profile, which specifies the name of the keychain profile to be used by notarize.pl. Change-Id: I8b513e3eebb38e49f0d7c5ff9ea4e1d46e87aa3f Reviewed-on: https://gerrit.openafs.org/15976 Tested-by: BuildBot Reviewed-by: Mark Vitale Reviewed-by: Andrew Deason --- src/packaging/MacOS/notarize.pl | 130 +++++++++++------------------ src/packaging/MacOS/pkgbuild.sh.in | 26 ++---- 2 files changed, 54 insertions(+), 102 deletions(-) diff --git a/src/packaging/MacOS/notarize.pl b/src/packaging/MacOS/notarize.pl index 026563012b..d39b3ecfe0 100755 --- a/src/packaging/MacOS/notarize.pl +++ b/src/packaging/MacOS/notarize.pl @@ -32,57 +32,60 @@ # # On success, the following output can be expected: # -# $ sudo notarize.pl foo@bar.com "@keychain:PASSWORD" OpenAFS.dmg +# $ sudo notarize.pl keychain-profile OpenAFS.dmg # -# notarize.pl: submitting package... -# notarize.pl: checking status... -# notarize.pl: checking status... -# notarize.pl: checking status... -# (...) -# notarize.pl: checking status... +# notarize.pl: processing package... # notarize.pl: package successfully notarized use strict; use File::Which; sub usage { - print(STDERR "usage: notarize.pl \n"); - print(STDERR "\tusername: apple id\n"); - print(STDERR "\tpassword: password of your apple id account\n"); + print(STDERR "usage: notarize.pl \n"); + print(STDERR "\tprofile: keychain-profile for the credentials to be used\n"); print(STDERR "\tpackage: package to be notarized\n"); print(STDERR "\tnote: must be root\n"); - print(STDERR "\t can be a reference to a keychain item.\n"); - print(STDERR "\t as cleartext is not recommended.\n"); - print(STDERR "e.g.: \$ sudo notarize.pl foo\@bar.com \"\@keychain:PASSWORD\" OpenAFS.dmg\n\n"); + print(STDERR "e.g.: \$ sudo notarize.pl keychain-profile OpenAFS.dmg\n\n"); exit(1); } sub check_prerequisites { - my (@ARGS) = @_; + my ($profile, $package) = @_; if ($> != 0) { print(STDERR "error: must be root\n\n"); usage(); } - if (scalar @ARGS != 3) { - print(STDERR "error: check arguments\n\n"); - usage(); - } if (!which('xcrun')) { print(STDERR "error: xcrun not found in \$PATH\n\n"); usage(); } - if (not -e $ARGS[2]) { + + # Check if the given keychain-profile exists + my $output = qx(xcrun notarytool history --keychain-profile "$profile" 2>&1); + my $exitcode = $? >> 8; + + if ($exitcode) { + print(STDERR "error: $exitcode\n"); + print(STDERR $output); + exit(1); + } + + # Check if the given package exists + if (not -e $package) { print(STDERR "error: package not found\n\n"); + exit(1); } } -sub submit_package { - my ($username, $password, $package) = @_; +sub process_package { + my ($profile, $package) = @_; - print(STDOUT "notarize.pl: submitting package...\n"); + print(STDOUT "notarize.pl: processing package...\n"); - my $output = qx(xcrun altool -t osx -f "$package" --primary-bundle-id org.openafs.OpenAFS --notarize-app --username "$username" --password "$password" 2>&1); + # returns after submitting and processing the package, or times out if it + # takes longer than 5 minutes + my $output = qx(xcrun notarytool submit "$package" --keychain-profile "$profile" --wait --timeout 5m 2>&1); my $exitcode = $? >> 8; if ($exitcode) { @@ -92,9 +95,18 @@ sub submit_package { } # $output looks like the following sample: # - # No errors uploading 'OpenAFS.dmg'. - # RequestUUID = 565a4d1b-9608-47a6-aba9-53136c991bb8 - $output =~ m{RequestUUID = ([A-Za-z0-9\-]+)}; + # Conducting pre-submission checks for OpenAFS.dmg and initiating connection + # to the Apple notary service... + # Submission ID received + # id: fe4249d2-c3f7-428e-8bcd-8af665e57189 + # Successfully uploaded file + # id: fe4249d2-c3f7-428e-8bcd-8af665e57189 + # path: ./OpenAFS.dmg + # Waiting for processing to complete. Wait timeout is set to 300.0 second(s). + # Current status: In Progress... Current status: Accepted...... Processing complete + # id: fe4249d2-c3f7-428e-8bcd-8af665e57189 + # status: Accepted + $output =~ m{id: ([A-Za-z0-9\-]+)}; if (not defined $1) { print(STDERR "error: uuid not found\n"); exit(1); @@ -102,57 +114,6 @@ sub submit_package { return $1; } -sub check_status { - my ($username, $password, $uuid) = @_; - my $output; - my $status; - my $exitcode; - - while (1) { - print(STDOUT "notarize.pl: checking status...\n"); - $output = qx(xcrun altool --notarization-info "$uuid" --username "$username" --password "$password" 2>&1); - $exitcode = $? >> 8; - - if ($exitcode) { - print(STDERR "error: $exitcode\n"); - print(STDERR $output); - exit(1); - } - # $output looks like the following samples: - # - # First, second, ..., (N-1)'th attempts: - # - # No errors getting notarization info. - # - # Date: 2019-11-26 21:07:46 +0000 - # Hash: 4e10ebb01518de9eb007d4579006acda2d6ff773fe040d97786bcc686ec93gg1 - # RequestUUID: 565a4d1b-9608-47a6-aba9-53136c991bb8 - # Status: in progress - # - # N'th attempt: - # - # No errors getting notarization info. - # - # Date: 2019-11-26 21:07:46 +0000 - # Hash: 4e10ebb01518de9eb007d4579006acda2d6ff773fe040d97786bcc686ec93gg1 - # RequestUUID: 565a4d1b-9608-47a6-aba9-53136c991bb8 - # Status: in progress - # Status Code: 0 - # Status Message: Package Approved - $output =~ m{Status Code: (\d+)}; - if (defined $1) { - $status = $1; - last; - } - sleep(5); - } - if ($status) { - print(STDERR "error: $status (uuid: $uuid)\n"); - print(STDERR $output); - exit(1); - } -} - sub notarize_package { my ($package, $uuid) = @_; @@ -172,13 +133,16 @@ sub notarize_package { sub main { my (@ARGS) = @_; - check_prerequisites(@ARGS); - my $username = $ARGS[0]; - my $password = $ARGS[1]; - my $package = $ARGS[2]; + if (scalar @ARGS != 2) { + print(STDERR "error: check arguments\n\n"); + usage(); + } + my $profile = $ARGS[0]; + my $package = $ARGS[1]; - my $uuid = submit_package($username, $password, $package); - check_status($username, $password, $uuid); + check_prerequisites($profile, $package); + + my $uuid = process_package($profile, $package); notarize_package($package, $uuid); exit(0); diff --git a/src/packaging/MacOS/pkgbuild.sh.in b/src/packaging/MacOS/pkgbuild.sh.in index edaa7212d6..4a95b0ab9e 100644 --- a/src/packaging/MacOS/pkgbuild.sh.in +++ b/src/packaging/MacOS/pkgbuild.sh.in @@ -6,20 +6,11 @@ usage() { exec >&2 echo 'Usage: pkgbuild.sh [-x] [--app-key ] [--inst-key ]' - echo ' [--apple-id ]' + echo ' [--keychain-profile ]' echo ' [--pass N] [--csdb ] ' echo echo '--app-key and --inst-key are for signing. -x prints all comamnds as ' - echo 'they are run. --apple-id is for notarizing.' - echo - echo 'Note: the password associated with can be a reference to a' - echo 'keychain item. Including your password as cleartext is not' - echo 'recommended. e.g.' - echo - echo '--apple-id foo@bar.com "@keychain:PASSWORD"' - echo - echo 'In this case, keychain must hold a keychain item named PASSWORD with' - echo 'an account matching foo@bar.com.' + echo 'they are run. --keychain-profile is for notarizing.' echo echo 'By default, all passes are run. Available passes:' echo ' --pass 1: prepare pkgroot' @@ -40,10 +31,9 @@ PASS2= APP_KEY= INST_KEY= -APPLE_ID= -APPLE_PW= DEST_DIR= CSDB= +KEYCHAIN_PROFILE= CODESIGN_OPTS= @@ -60,10 +50,8 @@ while [ x"$#" != x0 ] ; do INST_KEY="$1" shift ;; - --apple-id) - APPLE_ID="$1" - shift - APPLE_PW="$1" + --keychain-profile) + KEYCHAIN_PROFILE="$1" shift ;; --csdb) @@ -583,8 +571,8 @@ if [ x"$PASS2" = x1 ]; then echo echo "Created $CURDIR/OpenAFS-@PACKAGE_VERSION@-$RELNAME".dmg - if [ x"$APPLE_ID" != x ] ; then + if [ x"$KEYCHAIN_PROFILE" != x ] ; then echo "Notarizing package..." - ./notarize.pl "$APPLE_ID" "$APPLE_PW" "$CURDIR/OpenAFS-@PACKAGE_VERSION@-$RELNAME.dmg" + ./notarize.pl "$KEYCHAIN_PROFILE" "$CURDIR/OpenAFS-@PACKAGE_VERSION@-$RELNAME.dmg" fi fi