diff --git a/.gitignore b/.gitignore index a8e46c2..bb7a684 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,7 @@ DerivedData *.ipa *.xcuserstate *.orig + +# Archives +buildArchive/ +*.xcarchive diff --git a/EFIgy.xcodeproj/project.pbxproj b/EFIgy.xcodeproj/project.pbxproj index 79ae012..95ba072 100644 --- a/EFIgy.xcodeproj/project.pbxproj +++ b/EFIgy.xcodeproj/project.pbxproj @@ -29,6 +29,7 @@ /* Begin PBXFileReference section */ 3C5DCF54285F6F23935B75CB /* Pods_EFIgy.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_EFIgy.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 571A5A3E2305C12D006B8E53 /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = ""; }; 57291B0A1F86A479009C7BEE /* EFIgy.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = EFIgy.app; sourceTree = BUILT_PRODUCTS_DIR; }; 57291B0D1F86A479009C7BEE /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 57291B0E1F86A479009C7BEE /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; @@ -70,6 +71,7 @@ 57291B011F86A479009C7BEE = { isa = PBXGroup; children = ( + 571A5A3E2305C12D006B8E53 /* Release.xcconfig */, 57291B0C1F86A479009C7BEE /* EFIgy */, 57291B201F86A479009C7BEE /* EFIgyTests */, 57291B0B1F86A479009C7BEE /* Products */, @@ -141,7 +143,6 @@ 57291B071F86A479009C7BEE /* Frameworks */, 57291B081F86A479009C7BEE /* Resources */, B01B80882ACE63DE6E105B2C /* [CP] Embed Pods Frameworks */, - 08E6EFDC17B02CD07BDE1FE5 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -176,12 +177,17 @@ 57291B021F86A479009C7BEE /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0900; + LastUpgradeCheck = 1030; ORGANIZATIONNAME = "Duo Security"; TargetAttributes = { 57291B091F86A479009C7BEE = { CreatedOnToolsVersion = 9.0; ProvisioningStyle = Automatic; + SystemCapabilities = { + com.apple.HardenedRuntime = { + enabled = 1; + }; + }; }; 57291B1C1F86A479009C7BEE = { CreatedOnToolsVersion = 9.0; @@ -229,34 +235,26 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ - 08E6EFDC17B02CD07BDE1FE5 /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "[CP] Copy Pods Resources"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-EFIgy/Pods-EFIgy-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; B01B80882ACE63DE6E105B2C /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-EFIgy/Pods-EFIgy-frameworks.sh", + "${BUILT_PRODUCTS_DIR}/LetsMove/LetsMove.framework", + "${PODS_ROOT}/Sparkle/Sparkle.framework", + "${PODS_ROOT}/Sparkle/Sparkle.framework.dSYM", ); name = "[CP] Embed Pods Frameworks"; outputPaths = ( + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/LetsMove.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Sparkle.framework", + "${DWARF_DSYM_FOLDER_PATH}/Sparkle.framework.dSYM", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-EFIgy/Pods-EFIgy-frameworks.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-EFIgy/Pods-EFIgy-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; E1D351456D47D1D538DFD9ED /* [CP] Check Pods Manifest.lock */ = { @@ -265,13 +263,16 @@ files = ( ); inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", ); name = "[CP] Check Pods Manifest.lock"; outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-EFIgy-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; /* End PBXShellScriptBuildPhase section */ @@ -330,6 +331,7 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; @@ -337,6 +339,7 @@ CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; @@ -385,6 +388,7 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; @@ -392,6 +396,7 @@ CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; @@ -425,12 +430,16 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_ENTITLEMENTS = EFIgy/EFIgy.entitlements; + CODE_SIGN_IDENTITY = "Mac Developer"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; + DEVELOPMENT_TEAM = FNN8Z5JMFP; + ENABLE_HARDENED_RUNTIME = YES; INFOPLIST_FILE = EFIgy/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.duosecurity.EFIgy; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Debug; }; @@ -440,12 +449,16 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_ENTITLEMENTS = EFIgy/EFIgy.entitlements; + CODE_SIGN_IDENTITY = "Mac Developer"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; + DEVELOPMENT_TEAM = FNN8Z5JMFP; + ENABLE_HARDENED_RUNTIME = YES; INFOPLIST_FILE = EFIgy/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.duosecurity.EFIgy; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Release; }; diff --git a/EFIgy/Info.plist b/EFIgy/Info.plist index 87c7748..f4606f6 100644 --- a/EFIgy/Info.plist +++ b/EFIgy/Info.plist @@ -17,9 +17,9 @@ CFBundlePackageType APPL CFBundleShortVersionString - 1.0.3 + 1.0.4 CFBundleVersion - 4 + 5 LSMinimumSystemVersion $(MACOSX_DEPLOYMENT_TARGET) NSHumanReadableCopyright diff --git a/ExportOptions.plist b/ExportOptions.plist new file mode 100644 index 0000000..c1e8fb6 --- /dev/null +++ b/ExportOptions.plist @@ -0,0 +1,8 @@ + + + + + method + mac-application + + diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..5962cb6 --- /dev/null +++ b/Makefile @@ -0,0 +1,70 @@ +.PHONY: notarize + +# Mostly cribbed from https://gist.github.com/shpakovski/31067c499d69d1d4180856be3d67e5a5. + +# XCS_ARCHIVE is an environment variable typically set by Xcode Server. +# We're not using Xcode server so I'm hardcoding it here. +# +# https://developer.apple.com/library/archive/documentation/IDEs/Conceptual/xcode_guide-continuous_integration/EnvironmentVariableReference.html +XCS_ARCHIVE := "buildArchive/EFIgy.xcarchive" + +EXPORT_PATH := $(XCS_ARCHIVE)/Submissions +BUNDLE_APP := $(EXPORT_PATH)/EFIgy.app +BUNDLE_ZIP := $(EXPORT_PATH)/EFIgy.zip +UPLOAD_INFO_PLIST := $(EXPORT_PATH)/UploadInfo.plist +REQUEST_INFO_PLIST := $(EXPORT_PATH)/RequestInfo.plist +AUDIT_INFO_JSON := $(EXPORT_PATH)/AuditInfo.json +PRODUCT_DIR := $(XCS_ARCHIVE)/Products/Applications +PRODUCT_APP := $(PRODUCT_DIR)/EFIgy.app +PRIMARY_BUNDLE_ID := "com.duosecurity.EFIgy" +CODE_SIGN_IDENTITY_NAME := "Developer ID Application: Duo Security, Inc. (FNN8Z5JMFP)" + +define notify + @ /usr/bin/osascript -e 'display notification $2 with title $1' +endef + +define wait_while_in_progress + while true; do \ + /usr/bin/xcrun altool --notarization-info `/usr/libexec/PlistBuddy -c "Print :notarization-upload:RequestUUID" $(UPLOAD_INFO_PLIST)` -u $(DEVELOPER_USERNAME) -p $(DEVELOPER_PASSWORD) --output-format xml > $(REQUEST_INFO_PLIST) ;\ + if [ "`/usr/libexec/PlistBuddy -c "Print :notarization-info:Status" $(REQUEST_INFO_PLIST)`" != "in progress" ]; then \ + break ;\ + fi ;\ + /usr/bin/osascript -e 'display notification "Zzz..." with title "Notarization"' ;\ + sleep 60 ;\ + done +endef + +archive: + $(call notify, "Archiving", "Creating archive...") + xcodebuild -workspace EFIgy.xcworkspace -scheme EFIgy -configuration Release clean archive -archivePath "$XCS_ARCHIVE" CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO + +export-archive: + $(call notify, "Archiving", "Exporting an archive...") + /usr/bin/xcrun xcodebuild -exportArchive -archivePath $(XCS_ARCHIVE) -exportPath $(EXPORT_PATH) -exportOptionsPlist ./ExportOptions.plist -IDEPostProgressNotifications=YES -DVTAllowServerCertificates=YES -DVTProvisioningUseServerAccounts=YES -configuration Release + +codesign: + $(call notify, "Code Signing", "Code signing Sparkle AutoUpdate. Please enter PIN and touch the security key...") + codesign --timestamp --verbose --force --deep -o runtime --sign $(CODE_SIGN_IDENTITY_NAME) $(BUNDLE_APP)/Contents/Frameworks/Sparkle.framework/Versions/A/Resources/Autoupdate.app + $(call notify, "Code Signing", "Code signing app. Please enter PIN and touch the security key...") + codesign --timestamp --verbose --deep -o runtime -s $(CODE_SIGN_IDENTITY_NAME) -fv $(BUNDLE_APP) + +notarize: + $(call notify, "Notarization", "Building a ZIP archive...") + /usr/bin/ditto -c -k --rsrc --keepParent $(BUNDLE_APP) $(BUNDLE_ZIP) + $(call notify, "Notarization", "Uploading for notarization...") + /usr/bin/xcrun altool --notarize-app --primary-bundle-id $(PRIMARY_BUNDLE_ID) -u $(DEVELOPER_USERNAME) -p $(DEVELOPER_PASSWORD) -f $(BUNDLE_ZIP) --output-format xml > $(UPLOAD_INFO_PLIST) + sleep 2 + $(call notify, "Notarization", "Waiting while notarized...") + /usr/bin/xcrun altool --notarization-info `/usr/libexec/PlistBuddy -c "Print :notarization-upload:RequestUUID" $(UPLOAD_INFO_PLIST)` -u $(DEVELOPER_USERNAME) -p $(DEVELOPER_PASSWORD) --output-format xml > $(REQUEST_INFO_PLIST) + $(call wait_while_in_progress) + $(call notify, "Notarization", "Downloading log file...") + /usr/bin/curl -o $(AUDIT_INFO_JSON) `/usr/libexec/PlistBuddy -c "Print :notarization-info:LogFileURL" $(REQUEST_INFO_PLIST)` + if [ `/usr/libexec/PlistBuddy -c "Print :notarization-info:Status" $(REQUEST_INFO_PLIST)` != "success" ]; then \ + false; \ + fi + $(call notify, "Notarization", "Stapling...") + /usr/bin/xcrun stapler staple $(BUNDLE_APP) + $(call notify, "Notarization", "Replacing original product...") + rm -rf $(PRODUCT_APP) + mv $(BUNDLE_APP) $(PRODUCT_DIR)/ + $(call notify, "Notarization", "✅ Done!") diff --git a/Podfile b/Podfile index 7f393a9..cfb28c8 100644 --- a/Podfile +++ b/Podfile @@ -1,3 +1,5 @@ +platform :osx, '10.12' + target 'EFIgy' do use_frameworks! pod 'LetsMove' diff --git a/Podfile.lock b/Podfile.lock index 838d808..cc12a49 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -1,15 +1,20 @@ PODS: - - LetsMove (1.22) - - Sparkle (1.16.0) + - LetsMove (1.24) + - Sparkle (1.21.3) DEPENDENCIES: - LetsMove - Sparkle +SPEC REPOS: + https://github.com/cocoapods/specs.git: + - LetsMove + - Sparkle + SPEC CHECKSUMS: - LetsMove: 407d4d14815e6dc1549b6a9fe8e4b0f6aed3e305 - Sparkle: 57650c525b8922b1ef72021f9d92287fc7d5d6f0 + LetsMove: fefe56bc7bc7fb7d37049e28a14f297961229fc5 + Sparkle: 3f75576db8b0265adef36c43249d747f22d0b708 -PODFILE CHECKSUM: de348ddbda39c9c335ba8bbbacbb300ace8ff4d2 +PODFILE CHECKSUM: 2a9995deee40fbd399df209dcfa18ef1319235c8 -COCOAPODS: 1.1.1 +COCOAPODS: 1.7.0.beta.3 diff --git a/Release.xcconfig b/Release.xcconfig new file mode 100644 index 0000000..7511b11 --- /dev/null +++ b/Release.xcconfig @@ -0,0 +1,13 @@ +// +// Common.xcconfig +// EFIgy +// +// Created by James Barclay on 8/15/19. +// Copyright © 2019 Duo Security. All rights reserved. +// + +// Configuration settings file format documentation can be found at: +// https://help.apple.com/xcode/#/dev745c5c974 + +ENABLE_HARDENED_RUNTIME = YES +OTHER_CODE_SIGN_FLAGS = --deep --timestamp