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

Signing script called twice for each binary in jar #126

Open
alwaysbemark opened this issue Oct 11, 2024 · 5 comments
Open

Signing script called twice for each binary in jar #126

alwaysbemark opened this issue Oct 11, 2024 · 5 comments

Comments

@alwaysbemark
Copy link
Contributor

alwaysbemark commented Oct 11, 2024

Describe the bug

We have a signing script set up via app.mac.sign.scripts. The script sets up an SSH tunnel to our intranet and uses an internal service to sign individual binaries or app bundles. The signing process seems to work but for some reason the entire script is called twice for each binary.

To Reproduce

Set up the scripts as such:

  mac {
    icons = "installer/conveyor/mac-icon.tif"

    sign {
      scripts {
        app = "./sign-notarization-script.sh bundle $ENTITLEMENTS $BUNDLE"
        binary = "./sign-notarization-script.sh file $ENTITLEMENTS $FILE"
      }
    }
  }

With a script that looks like this (with irrelevant commands sanitised):

#!/usr/bin/env bash

echo "Signing: $@"

if [[ "$1" == "bundle" ]]; then
    echo "Bundle $1 $2 $3"
else
    echo "Signing binary file: $3 with entitlements: $2"
    zip -j "$3.zip" "$3"
    echo "Signing the binary here"
    rm "$3"
    unzip -o "$3.zip" -d "$(dirname $3)"
    rm "$3.zip"
fi

Run conveyor -Kapp.machines=mac.aarch64 make mac-app --rerun.

Observe the line

Signing: file /var/folders/5n/02wrtg_95nv26cb01vfpxcy40000gp/T/.tmp-7426078686834927/entitlements.plist /Users/<user>/Library/Caches/Hydraulic/Conveyor/working/99b1b8442de59de4/content/jars/signed/jna-5_13_0_jar_libjnidispatch.jnilib

being printed twice (of course, dependent on the binaries that you need signed).

Expected behavior

The script runs only once, signing the binary.

Desktop (please complete the following information):

MacOS.

Thanks in advance!

@mikehearn
Copy link
Member

Hi, sorry about that and apologies for the slow reply.

Unfortunately the reason for the slow reply is that I haven't been able to reproduce this problem. Using the same script and your instructions, I see the "Signing:" line being printed only once. I think it'd be useful here to see a log file. Could you do a run that exhibits this problem and then run conveyor --show-log=report ?

@alwaysbemark
Copy link
Contributor Author

Hey @mikehearn - I've got something better - a straightforward reproduction: https://github.com/alwaysbemark/conveyor-reproduction

When I run conveyor -Kapp.machines=mac.aarch64 make mac-app I get the double call to the binary signing script:

Starting signing script with arguments: binary
Starting signing script with arguments: binary
Starting signing script with arguments: app

I suspect it's the way I'm including the JAR file: https://github.com/alwaysbemark/conveyor-reproduction/blob/main/build.gradle#L14

Thanks in advance!

@mikehearn
Copy link
Member

Thanks! That helps a lot.

If we adjust the script a bit to contain if [[ $1 == "binary" ]]; then file $2; fi and add the arguments in the config file, then we see:

/Users/mike/Library/Caches/Hydraulic/Conveyor/working/20be897a350a3452/content/jars/signed/jna-5_13_0_jar_libjnidispatch.jnilib: Mach-O 64-bit dynamically linked shared library x86_64
/Users/mike/Library/Caches/Hydraulic/Conveyor/working/20be897a350a3452/content/jars/signed/jna-5_13_0_jar_libjnidispatch.jnilib: Mach-O 64-bit dynamically linked shared library arm64

So the reason it's being called twice is because the JNA library contains two Mac binaries. It might be a bit surprising that Conveyor includes both but it's by design:

https://conveyor.hydraulic.dev/15.1/configs/jvm/#native-code

If false then libraries are left alone, except that libraries for macOS and Windows will be signed in-place (inside the JAR). This ensures that Apple's notarization process accepts them, and that when the libraries are extracted the operating system won't cause problems due to them being unsigned.

Basically, Conveyor defaults to tampering with JARs as little as possible to avoid breaking things. To make the extra file invocations go away you can add this line to the config:

include required("https://raw.githubusercontent.com/hydraulic-software/conveyor/master/configs/jvm/extract-native-libraries.conf")

... and of course fix the usage of the signing script ...

  mac {
    sign {
      scripts {
        app = "./mac-sign-script.sh app $BUNDLE $ENTITLEMENTS"
        binary = "./mac-sign-script.sh binary $FILE $ENTITLEMENTS $IDENTIFIER"
      }
    }
  }

then the script is invoked once, for the bundle, and not at all for binary. The config that's included also configures JNA's system properties correctly.

I'll have a think about how to avoid this being confusing. Probably, we should detect that the app includes JNA and print a hint suggesting to turn on library extraction.

@mikehearn
Copy link
Member

Oh, by the way. If you try the above then Conveyor will crash. It's fixed in the next release already but the cause is that your JNA jar is "corrupted" by the presence of Apple MacDouble metadata files named like ._jnidispatch.dll which look like DLLs but aren't, and we should handle such files more gracefully than we currently do. I'm not sure how it got that way or if upstream has shipped a JAR like this, but it's a bit odd. You can strip the files from the JAR and then things will work.

@alwaysbemark
Copy link
Contributor Author

Thanks Mike - that makes sense. I had no idea that both MacOS binaries are included and signed and it being called twice was a tad confusing but this makes sense. Also aware of the native library extraction feature but have yet to tinker with it.

For the binary invocation - we do refer to the files/entitlements/identifiers, I just removed them from the example for the sake of brevity :)

All clear now - happy to close this for now, thank you so much :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants