iOS 如何使用系统密码运行脚本?

问题描述 投票:0回答:1

我正在创建一个 macOS 应用程序(使用 SwiftUI),它将运行一个脚本。要运行脚本,我需要系统(或管理员)密码。因为当我在终端中运行该脚本时,它会询问用户密码然后运行该脚本。 我可以使用 securefeild 在按钮单击时运行脚本,但是 在应用程序中向用户显示安全字段并询问其系统密码是不合适的,同时也违反了苹果的指导方针。所以我删除了那个字段。 现在我不知道如何在系统密码身份验证后运行脚本。 为了显示用户身份验证,我正在使用它。

    let context = LAContext()

    func authorize() {
        var error: NSError? = nil // Create optional error variable
        let reason = "This action requires your authentication for security purposes."

        let policy: LAPolicy = .deviceOwnerAuthentication // Adjust policy based on device capabilities (e.g., biometrics, passcode)
        context.evaluatePolicy(policy, localizedReason: reason, reply: { (success, error) in
            if success {
                // User was successfully authenticated
                **// Proceed with your script execution here, but the problem is I dont have user password here, and not found even from the Keychain, because before fetch password from keychain it should be store there**
                print("Success")
            } else {
                // Authentication failed or was canceled
                if let error = error {
                    // Handle the error appropriately
                    print(error.localizedDescription)
                }
            }
        })
}

我认为,为了安全起见,我应该将密码保存在钥匙串中,而不是访问,但是,首先我需要在不违反苹果指南的情况下获取密码。

这就是整个问题,我没有找到相关的东西。

编辑:

当我在成功案例中运行脚本时,它会在终端下方的 Xcode 中显示消息。

sudo: a password is required
sudo: a terminal is required to read the password; either use the -S option to read from standard input or configure an askpass helper
ios xcode macos shell
1个回答
0
投票

我自己找到了问题的解决方案。就我而言,

let context = LAContext()
不起作用,也没有必要。

用管理员运行脚本不需要在钥匙串中存储密码。当时编写脚本时用这个东西编写脚本。

let osacScript = "osascript -e 'do shell script \"\(script)\" with administrator privileges'"

我们可以像这样编写

sudo
脚本(当我们想要执行一些操作(例如创建文件夹或移动文件夹)时需要sudo脚本)

let osacScript = "osascript -e 'do shell script \"sudo \(script)\" with administrator privileges'"

解决我的问题的代码如下:

func installScript(scriptPath: String, installingDir: String) {
    let script = "\(scriptPath) --noprompt --dir \(installingDir) --key ABCKEY --region name-for-region --server https://myserver.com"
    DispatchQueue.global(qos: .background).async { // I am using SwiftUI so to avoid blocking the UI running script in the background.
        let osacScript = "osascript -e 'do shell script \"\(script)\" with administrator privileges'"
        print(osacScript)
        var arguments = [String]()
        arguments.append("-c")
        arguments .append(osacScript)
        let process = Process()
        process.launchPath = "/bin/bash" // Specify the shell to use
        process.arguments = arguments
        
        let pipe = Pipe()
        process.standardOutput = pipe
        process.standardError = pipe // Redirect standard error to the same pipe

        let fileHandle = pipe.fileHandleForReading
        process.launch()
        process.waitUntilExit()
        let data = fileHandle.readDataToEndOfFile()
        let logFilePath = Bundle.main.path(forResource: "logfile", ofType: "txt")! // This thing can lead to error if file does not exist, so make sure it should be optional.
        if let output = String(data: data, encoding: .utf8) {
            print("output:\(output)")
            // Write output to file
            do {
                try output.write(toFile: logFilePath, atomically: true, encoding: .utf8)
            } catch {
                print("Error writing to file: \(error)")
            }
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.