11package io .github .fvarrui .javapackager .packagers ;
22
3+ import io .github .fvarrui .javapackager .model .MacStartup ;
4+ import io .github .fvarrui .javapackager .model .Platform ;
5+ import io .github .fvarrui .javapackager .utils .*;
6+ import org .apache .commons .lang3 .StringUtils ;
7+ import org .apache .commons .lang3 .SystemUtils ;
8+ import org .codehaus .plexus .util .cli .CommandLineException ;
9+
310import java .io .File ;
11+ import java .io .IOException ;
412import java .util .ArrayList ;
513import java .util .Arrays ;
14+ import java .util .Collection ;
615import java .util .List ;
716import java .util .stream .Collectors ;
817
9- import org .apache .commons .lang3 .StringUtils ;
10- import org .apache .commons .lang3 .SystemUtils ;
11-
12- import io .github .fvarrui .javapackager .model .MacStartup ;
13- import io .github .fvarrui .javapackager .model .Platform ;
14- import io .github .fvarrui .javapackager .utils .CommandUtils ;
15- import io .github .fvarrui .javapackager .utils .FileUtils ;
16- import io .github .fvarrui .javapackager .utils .Logger ;
17- import io .github .fvarrui .javapackager .utils .VelocityUtils ;
18- import io .github .fvarrui .javapackager .utils .VersionUtils ;
19- import io .github .fvarrui .javapackager .utils .XMLUtils ;
20-
2118/**
2219 * Packager for MacOS
2320 */
@@ -38,12 +35,10 @@ public void doInit() throws Exception {
3835
3936 this .macConfig .setDefaults (this );
4037
41- // FIX useResourcesAsWorkingDir=false doesn't work fine on MacOS (option
42- // disabled)
38+ // FIX useResourcesAsWorkingDir=false doesn't work fine on Mac OS (option disabled)
4339 if (!this .isUseResourcesAsWorkingDir ()) {
4440 this .useResourcesAsWorkingDir = true ;
45- Logger .warn (
46- "'useResourcesAsWorkingDir' property disabled on MacOS (useResourcesAsWorkingDir is always true)" );
41+ Logger .warn ("'useResourcesAsWorkingDir' property disabled on Mac OS (useResourcesAsWorkingDir is always true)" );
4742 }
4843
4944 }
@@ -122,7 +117,7 @@ private void processStartupScript() throws Exception {
122117 } else {
123118
124119 File launcher = macConfig .getCustomLauncher ();
125- if (launcher != null && launcher .canRead () && launcher .isFile ()){
120+ if (launcher != null && launcher .canRead () && launcher .isFile ()){
126121 FileUtils .copyFileToFolder (launcher , macOSFolder );
127122 this .executable = new File (macOSFolder , launcher .getName ());
128123 } else {
@@ -200,41 +195,80 @@ private File preparePrecompiledStartupStub() throws Exception {
200195
201196 private void codesign (String developerId , File entitlements , File appFile ) throws Exception {
202197
203- // checks --option flags
204- List <String > flags = new ArrayList <>();
205- if (macConfig .isHardenedCodesign ()) {
206- if (VersionUtils .compareVersions ("10.13.6" , SystemUtils .OS_VERSION ) >= 0 ) {
207- flags .add ("runtime" ); // enable hardened runtime if MacOS version >= 10.13.6
208- } else {
209- Logger .warn ("MacOS version detected: " + SystemUtils .OS_VERSION + " ... hardened runtime disabled!" );
210- }
211- }
212-
198+ prepareEntitlementFile (entitlements );
199+
200+ manualDeepSign (appFile , developerId , entitlements );
201+
202+ }
203+
204+ private void prepareEntitlementFile (File entitlements ) throws Exception {
213205 // if entitlements.plist file not specified, use a default one
214- if (entitlements == null ) {
215- Logger .warn ("Entitlements file not specified. Using defaults!" );
206+ if (entitlements == null ) {
207+ Logger .warn ("Entitlements file not specified. Using defaults!" );
216208 entitlements = new File (assetsFolder , "entitlements.plist" );
217209 VelocityUtils .render ("mac/entitlements.plist.vtl" , entitlements , this );
218210 } else if (!entitlements .exists ()) {
219211 throw new Exception ("Entitlements file doesn't exist: " + entitlements );
220212 }
213+ }
214+
215+ private void manualDeepSign (File appFolder , String developerCertificateName , File entitlements ) throws IOException , CommandLineException {
216+
217+ List <Object > findCommandArgs = new ArrayList <>();
218+ findCommandArgs .add (appFolder );
219+ findCommandArgs .add ("-depth" ); // execute 'codesign' in 'reverse order', i.e., deepest files first
220+ findCommandArgs .add ("-type" );
221+ findCommandArgs .add ("f" ); // filter for files only
222+ findCommandArgs .add ("-exec" );
223+ findCommandArgs .add ("codesign" );
224+ findCommandArgs .add ("-f" );
225+
226+ addHardenedCodesign (findCommandArgs );
227+
228+ findCommandArgs .add ("-s" );
229+ findCommandArgs .add (developerCertificateName );
230+ findCommandArgs .add ("--entitlements" );
231+ findCommandArgs .add (entitlements );
232+ findCommandArgs .add ("{}" );
233+ findCommandArgs .add ("\\ ;" );
234+
235+ CommandUtils .execute ("find" , findCommandArgs .toArray (new Object [0 ]));
236+
237+ // make sure the executable is signed last
238+ List <Object > codeSignExe = new ArrayList <>();
239+ codeSignExe .add ("-f" );
240+ addHardenedCodesign (codeSignExe );
241+ codeSignExe .add ("--entitlements" );
242+ codeSignExe .add (entitlements );
243+ codeSignExe .add ("-s" );
244+ codeSignExe .add (developerCertificateName );
245+ codeSignExe .add (this .executable );
246+
247+ CommandUtils .execute ("codesign" , codeSignExe .toArray (new Object [0 ]));
248+
249+ // finally, sign the top level directory
250+ List <Object > codeSignTopLevelDir = new ArrayList <>();
251+ codeSignTopLevelDir .add ("-f" );
252+ addHardenedCodesign (codeSignTopLevelDir );
253+ codeSignTopLevelDir .add ("--entitlements" );
254+ codeSignTopLevelDir .add (entitlements );
255+ codeSignTopLevelDir .add ("-s" );
256+ codeSignTopLevelDir .add (developerCertificateName );
257+ codeSignTopLevelDir .add (appFolder );
258+
259+ CommandUtils .execute ("codesign" , codeSignTopLevelDir .toArray (new Object [0 ]));
221260
222- // prepare params array
223- List <Object > codesignArgs = new ArrayList <>();
224- codesignArgs .add ("--force" );
225- if (!flags .isEmpty ()) {
226- codesignArgs .add ("--options" );
227- codesignArgs .add (StringUtils .join (flags , "," ));
261+ }
262+
263+ private void addHardenedCodesign (Collection <Object > args ){
264+ if (macConfig .isHardenedCodesign ()) {
265+ if (VersionUtils .compareVersions ("10.13.6" , SystemUtils .OS_VERSION ) >= 0 ) {
266+ args .add ("-o" );
267+ args .add ("runtime" ); // enable hardened runtime if Mac OS version >= 10.13.6
268+ } else {
269+ Logger .warn ("Mac OS version detected: " + SystemUtils .OS_VERSION + " ... hardened runtime disabled!" );
270+ }
228271 }
229- codesignArgs .add ("--deep" );
230- codesignArgs .add ("--entitlements" );
231- codesignArgs .add (entitlements );
232- codesignArgs .add ("--sign" );
233- codesignArgs .add (developerId );
234- codesignArgs .add (appFile );
235-
236- // run codesign
237- CommandUtils .execute ("codesign" , codesignArgs .toArray (new Object [codesignArgs .size ()]));
238272 }
239273
240274}
0 commit comments