How to verify local macOS user's password using authorization services from Swift?

I'm trying to verify a local macOS user's password using the Authorization services API (via Swift 5) based on an Objective-C example I found.

I've tried every permutation of calls to AuthoricationCreate that I can think of, but they always fail with an OOStatus code of -60005 or -60007

My simple Swift 5 test code is as follows:

import Cocoa
import CoreFoundation

class log {
    static func debug(_ msg: String) {
        Swift.print(msg)
        fflush(stdout)
    }
    static func error(_ msg: String) {
        Swift.print(msg)
        fflush(stdout)
    }
}

struct MacAPIRequest_Authenticate {
    public var user: String = String()

    public var password: String = String()

    public init() {}
}

var auth: MacAPIRequest_Authenticate = MacAPIRequest_Authenticate()
auth.user=CommandLine.arguments[1]
auth.password=CommandLine.arguments[2]
log.debug("auth=\(auth)")

let authPassword = UnsafeMutablePointer<Int8>(mutating: (auth.password as NSString).utf8String)
log.debug("authPassword=\(String(cString: authPassword!))")
let authUser = UnsafeMutablePointer<Int8>(mutating: (auth.user as NSString).utf8String)
log.debug("authUser=\(String(cString: authUser!))")
var authEnvItems = [
  AuthorizationItem(name: kAuthorizationEnvironmentUsername,
                    valueLength: (auth.user as NSString).length, value: authUser, flags: UInt32(0)),
  AuthorizationItem(name: kAuthorizationEnvironmentPassword,
                    valueLength: (auth.password as NSString).length, value: authPassword, flags: UInt32(0))
]
log.debug("authEnvItems=\(authEnvItems)")
var authEnv = AuthorizationEnvironment(count: UInt32(authEnvItems.count), items: &authEnvItems)
var authRightsItems = [
  AuthorizationItem(name: "allow", valueLength: 0, value: nil, flags: 0)
]
var authRights = AuthorizationRights(count: UInt32(authRightsItems.count), items: &authRightsItems)
log.debug("authRights=\(authRights)")
var authRef: AuthorizationRef? = nil
var authStatus: OSStatus
var authFlags = AuthorizationFlags(rawValue: 0)

// First try permutation without using AuthorizationCopyRights:
authStatus = AuthorizationCreate(&authRights, &authEnv, authFlags, nil)
log.debug("0 authStatus=\(authStatus)")

// Using AuthorizationCopyRights:
authStatus = AuthorizationCreate(nil, &authEnv, authFlags, &authRef)
log.debug("1 authStatus=\(authStatus)")
authFlags = AuthorizationFlags([.extendRights, .preAuthorize])
authStatus = AuthorizationCopyRights(authRef!, &authRights, &authEnv, authFlags, nil)
log.debug("2 authStatus=\(authStatus)")
if (authStatus == errAuthorizationSuccess) {
    log.debug("auth(\(auth)) authorized")
} else {
    log.debug("auth(\(auth)) denied")
}

The above was based on what I found here - How verify account's password

Here's what this outputs:

auth=MacAPIRequest_Authenticate(user: "username", password: "password")
authPassword=password
authUser=uername
authEnvItems=[__C.AuthorizationItem(name: 0x00007fa52a4df030, valueLength: 8, value: Optional(0x00007fa52a4e9258), flags: 0), __C.AuthorizationItem(name: 0x00007fa52a4df030, valueLength: 8, value: Optional(0x00007fa52a4321d8), flags: 0)]
authRights=AuthorizationItemSet(count: 1, items: Optional(0x00007fa52a4c32a0))
0 authStatus=-60005
1 authStatus=0
2 authStatus=-60007
auth(MacAPIRequest_Authenticate(user: "username", password: "password")) denied

I expect OSStatus of 0 (zero) when providing the correct username/password combination.

This is more than a little off topic for Swift Forums. If you post your question to the Core OS > Security area on DevForums, I’ll respond there.

Share and Enjoy

Quinn “The Eskimo!” @ DTS @ Apple