8230629: jpackage signing on macOS does not work as expected JDK-8200758-branch
authorherrick
Mon, 16 Sep 2019 19:24:32 -0400
branchJDK-8200758-branch
changeset 58172 bf06a1d3aef6
parent 58147 45a9084fe981
child 58301 e0efb29609bd
8230629: jpackage signing on macOS does not work as expected Submitted-by: almatvee Reviewed-by: herrick, asemenyuk
src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacAppImageBuilder.java
--- a/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacAppImageBuilder.java	Sun Sep 15 07:34:39 2019 -0400
+++ b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacAppImageBuilder.java	Mon Sep 16 19:24:32 2019 -0400
@@ -779,12 +779,10 @@
         String keyChain = SIGNING_KEYCHAIN.fetchFrom(params);
 
         // sign all dylibs and jars
-        Files.walk(appLocation)
-                // fix permissions
-                .peek(path -> {
+        Files.walk(appLocation).peek(path -> { // fix permissions
                     try {
                         Set<PosixFilePermission> pfp =
-                            Files.getPosixFilePermissions(path);
+                                Files.getPosixFilePermissions(path);
                         if (!pfp.contains(PosixFilePermission.OWNER_WRITE)) {
                             pfp = EnumSet.copyOf(pfp);
                             pfp.add(PosixFilePermission.OWNER_WRITE);
@@ -793,60 +791,65 @@
                     } catch (IOException e) {
                         Log.verbose(e);
                     }
-                })
-                .filter(p -> Files.isRegularFile(p) &&
-                        !(p.toString().contains("/Contents/MacOS/libjli.dylib")
-                        || p.toString().endsWith(appExecutable))
-                ).forEach(p -> {
-            //noinspection ThrowableResultOfMethodCallIgnored
-            if (toThrow.get() != null) return;
+                }).filter(p -> Files.isRegularFile(p)
+                          && !(p.toString().contains("/Contents/MacOS/libjli.dylib")
+                          || p.toString().endsWith(appExecutable)
+                          || p.toString().contains("/Contents/runtime")
+                          || p.toString().contains("/Contents/Frameworks"))).forEach(p -> {
+                    //noinspection ThrowableResultOfMethodCallIgnored
+                    if (toThrow.get() != null) return;
 
-            // If p is a symlink then skip the signing process.
-            if (Files.isSymbolicLink(p)) {
-                if (VERBOSE.fetchFrom(params)) {
-                    Log.verbose(MessageFormat.format(I18N.getString(
-                            "message.ignoring.symlink"), p.toString()));
-                }
-            }
-            else {
-                List<String> args = new ArrayList<>();
-                args.addAll(Arrays.asList("codesign",
-                        "-s", signingIdentity, // sign with this key
-                        "--prefix", identifierPrefix,
+                    // If p is a symlink then skip the signing process.
+                    if (Files.isSymbolicLink(p)) {
+                        if (VERBOSE.fetchFrom(params)) {
+                            Log.verbose(MessageFormat.format(I18N.getString(
+                                    "message.ignoring.symlink"), p.toString()));
+                        }
+                    } else {
+                        if (p.toString().endsWith(LIBRARY_NAME)) {
+                            if (isFileSigned(p)) {
+                                return;
+                            }
+                        }
+
+                        List<String> args = new ArrayList<>();
+                        args.addAll(Arrays.asList("codesign",
+                                "-s", signingIdentity, // sign with this key
+                                "--prefix", identifierPrefix,
                                 // use the identifier as a prefix
-                        "-vvvv"));
-                if (entitlementsFile != null &&
-                        (p.toString().endsWith(".jar")
+                                "-vvvv"));
+                        if (entitlementsFile != null &&
+                                (p.toString().endsWith(".jar")
                                 || p.toString().endsWith(".dylib"))) {
-                    args.add("--entitlements");
-                    args.add(entitlementsFile); // entitlements
-                } else if (inheritedEntitlements != null &&
-                        Files.isExecutable(p)) {
-                    args.add("--entitlements");
-                    args.add(inheritedEntitlements);
+                            args.add("--entitlements");
+                            args.add(entitlementsFile); // entitlements
+                        } else if (inheritedEntitlements != null &&
+                                Files.isExecutable(p)) {
+                            args.add("--entitlements");
+                            args.add(inheritedEntitlements);
                             // inherited entitlements for executable processes
-                }
-                if (keyChain != null && !keyChain.isEmpty()) {
-                    args.add("--keychain");
-                    args.add(keyChain);
-                }
-                args.add(p.toString());
+                        }
+                        if (keyChain != null && !keyChain.isEmpty()) {
+                            args.add("--keychain");
+                            args.add(keyChain);
+                        }
+                        args.add(p.toString());
 
-                try {
-                    Set<PosixFilePermission> oldPermissions =
-                            Files.getPosixFilePermissions(p);
-                    File f = p.toFile();
-                    f.setWritable(true, true);
+                        try {
+                            Set<PosixFilePermission> oldPermissions =
+                                    Files.getPosixFilePermissions(p);
+                            File f = p.toFile();
+                            f.setWritable(true, true);
 
-                    ProcessBuilder pb = new ProcessBuilder(args);
-                    IOUtils.exec(pb);
+                            ProcessBuilder pb = new ProcessBuilder(args);
+                            IOUtils.exec(pb);
 
-                    Files.setPosixFilePermissions(p, oldPermissions);
-                } catch (IOException ioe) {
-                    toThrow.set(ioe);
-                }
-            }
-        });
+                            Files.setPosixFilePermissions(p, oldPermissions);
+                        } catch (IOException ioe) {
+                            toThrow.set(ioe);
+                        }
+                    }
+                });
 
         IOException ioe = toThrow.get();
         if (ioe != null) {
@@ -863,7 +866,7 @@
                 args.addAll(Arrays.asList("codesign",
                         "-s", signingIdentity, // sign with this key
                         "--prefix", identifierPrefix,
-                                // use the identifier as a prefix
+                        // use the identifier as a prefix
                         "-vvvv"));
                 if (keyChain != null && !keyChain.isEmpty()) {
                     args.add("--keychain");
@@ -877,7 +880,7 @@
                 args.addAll(Arrays.asList("codesign",
                         "-s", signingIdentity, // sign with this key
                         "--prefix", identifierPrefix,
-                                // use the identifier as a prefix
+                        // use the identifier as a prefix
                         "-vvvv"));
                 if (keyChain != null && !keyChain.isEmpty()) {
                     args.add("--keychain");
@@ -932,4 +935,17 @@
         IOUtils.exec(pb);
     }
 
+    private static boolean isFileSigned(Path file) {
+        ProcessBuilder pb =
+                new ProcessBuilder("codesign", "--verify", file.toString());
+
+        try {
+            IOUtils.exec(pb);
+        } catch (IOException ex) {
+            return false;
+        }
+
+        return true;
+    }
+
 }