Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

improve signing apps with extensions #97

Merged
merged 6 commits into from
Jul 20, 2019
95 changes: 36 additions & 59 deletions AppSigner/MainView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -50,22 +50,20 @@ class MainView: NSView, URLSessionDataDelegate, URLSessionDelegate, URLSessionDo
// let plistbuddyPath = "/usr/libexec/plistbuddy"

//MARK: Drag / Drop
@objc var fileTypes: [String] = ["ipa","deb","app","xcarchive","mobileprovision"]
@objc var urlFileTypes: [String] = ["ipa","deb"]
static let urlFileTypes = ["ipa", "deb"]
static let allowedFileTypes = urlFileTypes + ["app", "appex", "xcarchive"]
static let fileTypes = allowedFileTypes + ["mobileprovision"]
@objc var fileTypeIsOk = false

@objc func fileDropped(_ filename: String){
switch(filename.pathExtension.lowercased()){
case "ipa", "deb", "app", "xcarchive":
switch filename.pathExtension.lowercased() {
case let ext where MainView.allowedFileTypes.contains(ext):
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why aren't urlFileTypes also included here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

allowedFileTypes is a superset of urlFileTypes, check line 54

InputFileText.stringValue = filename
break

case "mobileprovision":
ProvisioningProfilesPopup.selectItem(at: 1)
checkProfileID(ProvisioningProfile(filename: filename))
default:
break
default: break

}
}

Expand Down Expand Up @@ -115,13 +113,13 @@ class MainView: NSView, URLSessionDataDelegate, URLSessionDelegate, URLSessionDo
@objc func checkExtension(_ drag: NSDraggingInfo) -> Bool {
if let board = drag.draggingPasteboard.propertyList(forType: NSPasteboard.PasteboardType(rawValue: "NSFilenamesPboardType")) as? NSArray,
let path = board[0] as? String {
return self.fileTypes.contains(path.pathExtension.lowercased())
return MainView.fileTypes.contains(path.pathExtension.lowercased())
}
if let types = drag.draggingPasteboard.types {
if types.contains(NSPasteboard.PasteboardType(rawValue: "NSURLPboardType")) {
if let url = NSURL(from: drag.draggingPasteboard),
let suffix = url.pathExtension {
return self.urlFileTypes.contains(suffix.lowercased())
return MainView.urlFileTypes.contains(suffix.lowercased())
}
}
}
Expand Down Expand Up @@ -490,47 +488,37 @@ class MainView: NSView, URLSessionDataDelegate, URLSessionDelegate, URLSessionDo
//MARK: Codesigning
@discardableResult
func codeSign(_ file: String, certificate: String, entitlements: String?,before:((_ file: String, _ certificate: String, _ entitlements: String?)->Void)?, after: ((_ file: String, _ certificate: String, _ entitlements: String?, _ codesignTask: AppSignerTaskOutput)->Void)?)->AppSignerTaskOutput{

let hasEntitlements: Bool = ({
if entitlements == nil {
return false
} else {
if fileManager.fileExists(atPath: entitlements!) {
return true
} else {
return false
}
}
})()


var needEntitlements: Bool = false
var filePath = file
let fileExtension = file.lastPathComponent.pathExtension
if fileExtension == "framework" {
// appene execute file in framework
let fileName = file.lastPathComponent.stringByDeletingPathExtension
filePath = file.stringByAppendingPathComponent(fileName)
} else if fileExtension == "app" {
// appene execute file in app
let filePath: String
switch file.pathExtension.lowercased() {
case "framework":
// append executable file in framework
let fileName = file.lastPathComponent.stringByDeletingPathExtension
filePath = file.stringByAppendingPathComponent(fileName)
needEntitlements = hasEntitlements
} else {
//
case "app", "appex":
// read executable file from Info.plist
let infoPlist = file.stringByAppendingPathComponent("Info.plist")
let executableFile = getPlistKey(infoPlist, keyName: "CFBundleExecutable")!
filePath = file.stringByAppendingPathComponent(executableFile)

if let entitlementsPath = entitlements, fileManager.fileExists(atPath: entitlementsPath) {
needEntitlements = true
}
default:
filePath = file
}

if let beforeFunc = before {
beforeFunc(file, certificate, entitlements)
}
var arguments = [String]()


var arguments = ["-f", "-s", certificate]
if needEntitlements {
arguments.append("--entitlements")
arguments.append(entitlements!)
arguments += ["--entitlements", entitlements!]
}
arguments.append(contentsOf: ["-f", "-s", certificate])
arguments.append(filePath)

let codesignTask = Process().execute(codesignPath, workingDirectory: nil, arguments: arguments)
if let afterFunc = after {
afterFunc(file, certificate, entitlements, codesignTask)
Expand Down Expand Up @@ -771,7 +759,6 @@ class MainView: NSView, URLSessionDataDelegate, URLSessionDelegate, URLSessionDo
setStatus("Error processing deb file")
cleanup(tempFolder); return
}
break

case "ipa":
//MARK: --Unzip ipa
Expand All @@ -788,9 +775,8 @@ class MainView: NSView, URLSessionDataDelegate, URLSessionDelegate, URLSessionDo
setStatus("Error extracting ipa file")
cleanup(tempFolder); return
}
break

case "app":
case "app", "appex":
//MARK: --Copy app bundle
if !inputIsDirectory.boolValue {
setStatus("Unsupported input file")
Expand All @@ -804,7 +790,6 @@ class MainView: NSView, URLSessionDataDelegate, URLSessionDelegate, URLSessionDo
setStatus("Error copying app to payload directory")
cleanup(tempFolder); return
}
break

case "xcarchive":
//MARK: --Copy app bundle from xcarchive
Expand All @@ -820,7 +805,6 @@ class MainView: NSView, URLSessionDataDelegate, URLSessionDelegate, URLSessionDo
setStatus("Error copying app to payload directory")
cleanup(tempFolder); return
}
break

default:
setStatus("Unsupported input file")
Expand Down Expand Up @@ -1093,7 +1077,6 @@ class MainView: NSView, URLSessionDataDelegate, URLSessionDelegate, URLSessionDo
NewApplicationIDTextField.isEnabled = true
NewApplicationIDTextField.stringValue = ""
}
break

case 1:
let openDialog = NSOpenPanel()
Expand All @@ -1109,17 +1092,14 @@ class MainView: NSView, URLSessionDataDelegate, URLSessionDelegate, URLSessionDo
sender.selectItem(at: 0)
chooseProvisioningProfile(sender)
}
break

case 2:
sender.selectItem(at: 0)
chooseProvisioningProfile(sender)
break

default:
let profile = provisioningProfiles[sender.indexOfSelectedItem - 3]
checkProfileID(profile)
break
}

}
Expand All @@ -1129,7 +1109,7 @@ class MainView: NSView, URLSessionDataDelegate, URLSessionDelegate, URLSessionDo
openDialog.canChooseDirectories = false
openDialog.allowsMultipleSelection = false
openDialog.allowsOtherFileTypes = false
openDialog.allowedFileTypes = ["ipa","IPA","deb","DEB","app","APP","xcarchive","XCARCHIVE"]
openDialog.allowedFileTypes = MainView.allowedFileTypes + MainView.allowedFileTypes.map({ $0.uppercased() })
openDialog.runModal()
if let filename = openDialog.urls.first {
InputFileText.stringValue = filename.path
Expand All @@ -1141,14 +1121,11 @@ class MainView: NSView, URLSessionDataDelegate, URLSessionDelegate, URLSessionDo
}

@IBAction func doSign(_ sender: NSButton) {
switch(true){
case (codesigningCerts.count == 0):
showCodesignCertsErrorAlert()
break

default:
NSApplication.shared.windows[0].makeFirstResponder(self)
startSigning()
if codesigningCerts.count > 0 {
NSApplication.shared.windows[0].makeFirstResponder(self)
startSigning()
} else {
showCodesignCertsErrorAlert()
}
}

Expand Down