public async Task NotarizeExecutables(FileInfo zipArchive, DirectoryInfo appDirectory, string developerUsername, string developerPassword)
        {
            logger.LogInformation($"Notarizing executables in {zipArchive.Name} with developer {developerUsername}");

            logger.LogInformation($"Submitting {zipArchive.Name} to Apple");

            var sharedArguments = $"--username \"{developerUsername}\" --password \"{developerPassword}\" --output-format xml";

            var upload = processRunner.RunProcess <AltoolUpload>("xcrun", $"altool {sharedArguments} --notarize-app -primary-bundle-id \"{zipArchive.Name}\" --file \"{zipArchive.FullName}\"");

            if (upload.NotarizationUpload?.RequestId == null)
            {
                throw new Exception("Didn't get a request ID from the notarization service.");
            }

            logger.LogInformation($"Got request ID {upload.NotarizationUpload.RequestId.Value}");

            var startWaitTime = DateTime.UtcNow;

            AltoolInfo info;

            do
            {
                logger.LogInformation("Waiting 1 minute");
                await Task.Delay(TimeSpan.FromMinutes(1));

                var waitedTime = DateTime.UtcNow - startWaitTime;
                if (waitedTime > TimeSpan.FromMinutes(30))
                {
                    throw new Exception("Waited over 30 minutes for notarization");
                }

                info = processRunner.RunProcess <AltoolInfo>("xcrun", $"altool {sharedArguments} --notarization-info {upload.NotarizationUpload.RequestId.Value}");
            }while (info.NotarizationInfo.Status == AltoolStatus.InProgress);

            logger.LogInformation($"Status message: {info.NotarizationInfo?.StatusMessage}");
            logger.LogInformation($"Log file URL: {info.NotarizationInfo?.LogFileURL}");

            if (info.NotarizationInfo.Status != AltoolStatus.Success)
            {
                throw new Exception("Notarization was not successful. See log for details.");
            }

            processRunner.RunProcess("xcrun", $"stapler staple \"{appDirectory.FullName}\"");

            logger.LogInformation("Testing whether gatekeeper would run the app");
            processRunner.RunProcess("xcrun", $"spctl -vvv --assess --type exec \"{appDirectory.FullName}\"");
        }
Beispiel #2
0
        public FileInfo BuildZipFile(DirectoryInfo appDirectory, IEnumerable <FileInfo> executables)
        {
            var zipFolder = appDirectory.Parent;
            var zipFile   = new FileInfo(Path.Combine(zipFolder.FullName, $"executables-{Guid.NewGuid()}.zip"));

            logger.LogInformation($"Building ZIP file {zipFile.Name}");

            processRunner.RunProcess("/bin/bash", $"-c \"cd {zipFolder.FullName} && ditto -c -k --sequesterRsrc --keepParent {appDirectory.Name} {zipFile.Name}\"");

            return(zipFile);
        }
Beispiel #3
0
        public void SignExecutable(string certificateId, FileSystemInfo executable, IReadOnlyDictionary <string, string[]> entitlementsMap)
        {
            var entitlements = entitlementsMap.ContainsKey(executable.Name) ? entitlementsMap[executable.Name] : new string[0];

            var sharedArguments = $"--options runtime --timestamp --sign \"{certificateId}\" --force";

            if (entitlements.Length > 0)
            {
                logger.LogInformation($"Signing executable {executable.Name} with entitlements \"{string.Join(",", entitlements)}\"");
                var entitlementsFile = WriteEntitlements(entitlements);
                processRunner.RunProcess("codesign", $"{sharedArguments} --entitlements \"{entitlementsFile.FullName}\" \"{executable.FullName}\"");
                entitlementsFile.Delete();
            }
            else
            {
                logger.LogInformation($"Signing executable {executable.Name} with no entitlements");
                processRunner.RunProcess("codesign", $"{sharedArguments} \"{executable.FullName}\"");
            }

            logger.LogInformation($"Validating signature for executable");
            processRunner.RunProcess("codesign", $"--verify --deep --strict --verbose=2 \"{executable.FullName}\"");
        }