@@ -48,23 +48,48 @@ public UpdateStep secondStep(Path workDir, Path assetPath, DownloadUpdateInfo up
4848
4949 private UpdateStep unpack (Path workDir , Path assetPath ) throws IOException {
5050 // Extract Cryptomator.app from the .dmg file
51- String script = """
52- hdiutil attach "${DMG_PATH}" -mountpoint "/Volumes/Cryptomator_${MOUNT_ID}" -nobrowse -quiet &&
53- cp -R "/Volumes/Cryptomator_${MOUNT_ID}/Cryptomator.app" 'Cryptomator.app' &&
54- hdiutil detach "/Volumes/Cryptomator_${MOUNT_ID}" -quiet
55- """ ;
56- var command = List .of ("/bin/zsh" , "-c" , script );
57- var processBuilder = new ProcessBuilder (command );
51+ var processBuilder = new ProcessBuilder (List .of ("/bin/zsh" , "-s" ));
5852 processBuilder .directory (workDir .toFile ());
5953 processBuilder .environment ().put ("DMG_PATH" , assetPath .toString ());
6054 processBuilder .environment ().put ("MOUNT_ID" , UUID .randomUUID ().toString ());
6155 Process p = processBuilder .start ();
6256 try {
57+ try (var stdin = p .outputWriter ()) {
58+ stdin .write ("""
59+ trap 'hdiutil detach "/Volumes/Cryptomator_${MOUNT_ID}" -quiet || true' EXIT
60+ hdiutil attach "${DMG_PATH}" -mountpoint "/Volumes/Cryptomator_${MOUNT_ID}" -nobrowse -quiet
61+ cp -R "/Volumes/Cryptomator_${MOUNT_ID}/Cryptomator.app" 'Cryptomator.app'
62+ """ );
63+ }
6364 if (p .waitFor () != 0 ) {
6465 LOG .error ("Failed to extract DMG, exit code: {}, output: {}" , p .exitValue (), new String (p .getErrorStream ().readAllBytes ()));
6566 throw new IOException ("Failed to extract DMG, exit code: " + p .exitValue ());
6667 }
67- LOG .debug ("Update ready: {}" , workDir .resolve ("Cryptomator.app" ));
68+ LOG .debug ("Unpacked app: {}" , workDir .resolve ("Cryptomator.app" ));
69+ } catch (InterruptedException e ) {
70+ Thread .currentThread ().interrupt ();
71+ throw new InterruptedIOException ("Failed to extract DMG, interrupted" );
72+ }
73+ return UpdateStep .of (Localization .get ().getString ("org.cryptomator.macos.update.dmg.verifying" ), () -> this .verify (workDir , assetPath ));
74+ }
75+
76+ private UpdateStep verify (Path workDir , Path assetPath ) throws IOException {
77+ // Verify code signature of the extracted .app
78+ var processBuilder = new ProcessBuilder (List .of ("/bin/zsh" , "-s" ));
79+ processBuilder .directory (workDir .toFile ());
80+ Process p = processBuilder .start ();
81+ try {
82+ try (var stdin = p .outputWriter ()) {
83+ stdin .write ("""
84+ codesign --verify --deep --strict 'Cryptomator.app'
85+ spctl --assess --type execute 'Cryptomator.app'
86+ """ );
87+ }
88+ if (p .waitFor () != 0 ) {
89+ LOG .error ("Checking code signature failed: {}, output: {}" , p .exitValue (), new String (p .getErrorStream ().readAllBytes ()));
90+ throw new UpdateFailedException ("Invalid Code Signature." );
91+ }
92+ LOG .debug ("Verified app: {}" , workDir .resolve ("Cryptomator.app" ));
6893 } catch (InterruptedException e ) {
6994 Thread .currentThread ().interrupt ();
7095 throw new InterruptedIOException ("Failed to extract DMG, interrupted" );
@@ -84,14 +109,14 @@ public UpdateStep restart(Path workDir) throws IllegalStateException, IOExceptio
84109 }
85110 LOG .info ("Restarting to apply Update in {} now..." , workDir );
86111 String script = """
87- while kill -0 ${CRYPTOMATOR_PID} 2> /dev/null; do sleep 0.2; done;
88- if [ -d "${CRYPTOMATOR_INSTALL_PATH}" ]; then
89- echo "Removing old installation at ${CRYPTOMATOR_INSTALL_PATH}";
90- rm -rf "${CRYPTOMATOR_INSTALL_PATH}"
91- fi
92- mv 'Cryptomator.app' "${CRYPTOMATOR_INSTALL_PATH}";
93- open "${CRYPTOMATOR_INSTALL_PATH}";
94- """ ;
112+ while kill -0 ${CRYPTOMATOR_PID} 2> /dev/null; do sleep 0.2; done;
113+ if [ -d "${CRYPTOMATOR_INSTALL_PATH}" ]; then
114+ echo "Removing old installation at ${CRYPTOMATOR_INSTALL_PATH}";
115+ rm -rf "${CRYPTOMATOR_INSTALL_PATH}"
116+ fi
117+ mv 'Cryptomator.app' "${CRYPTOMATOR_INSTALL_PATH}";
118+ open "${CRYPTOMATOR_INSTALL_PATH}";
119+ """ ;
95120 Files .writeString (workDir .resolve ("install.sh" ), script , StandardCharsets .US_ASCII , StandardOpenOption .WRITE , StandardOpenOption .CREATE_NEW );
96121 var command = List .of ("/bin/zsh" , "-c" , "/usr/bin/nohup zsh install.sh >install.log 2>&1 &" );
97122 var processBuilder = new ProcessBuilder (command );
0 commit comments