Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save stephancasas/9af4ef15ee37620b3a1e8e41295a6e38 to your computer and use it in GitHub Desktop.
Save stephancasas/9af4ef15ee37620b3a1e8e41295a6e38 to your computer and use it in GitHub Desktop.
Synchronously prompt the user for permission to dispatch a new privilege-escalated Process.
//
// Process+InteractiveEscalation.swift
//
//
// Created by Stephan Casas on 6/26/24.
//
import Foundation;
import OSAKit;
extension Process {
/// A type representing a misconfigured interactively-escalated process.
enum InteractiveProcessEscalationError: Error {
case argumentError;
}
/// Synchronously prompt the user with an interactive privilege-escalation dialog before dispatching the the target executable.
func runWithInteractivePrivilegeEscalation() throws {
guard let path = self.executableURL?.path() else {
return;
}
let escapedArgs = (self.arguments ?? []).map({
$0.replacing("\\", with: "\\\\")
}).map({
$0.replacing("`", with: "\\`")
}).map({
$0.replacing("\"", with: "\\\"")
}).joined(separator: " ");
let script = OSAScript(source: [
"function run() {",
" const app = Application.currentApplication();",
" app.includeStandardAdditions = true;",
" app.doShellScript(`\(path) \(escapedArgs)`, { administratorPrivileges: true });",
"}"
].joined(separator: "\n"), language: .init(forName: "JavaScript")!);
var compileError: NSDictionary?;
script.compileAndReturnError(&compileError);
guard compileError == nil else {
throw InteractiveProcessEscalationError.argumentError;
}
var executeResult: NSAttributedString?;
var executeError: NSDictionary?;
script.executeAndReturnDisplayValue(&executeResult, error: &executeError);
self.executableURL = .init(
filePath: "/usr/bin/\(String(describing: executeError == nil))");
try self.run();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment