SPDX-FileCopyrightText: 2008 Nicola Gigante <nicola.gigante@gmail.com>
SPDX-FileCopyrightText: 2014, 2016 René Bertin <rjvbertin@gmail.com>
SPDX-License-Identifier: LGPL-2.1-or-later
*/
#include "AuthServicesBackend.h"
#include <qplugin.h>
#include <QDebug>
#include <QLoggingCategory>
Q_DECLARE_LOGGING_CATEGORY(KAUTH_OSX)
Q_LOGGING_CATEGORY(KAUTH_OSX, "kf.auth.apple", QtWarningMsg)
namespace KAuth
{
static AuthorizationRef s_authRef = NULL;
AuthorizationRef authRef()
{
if (!s_authRef) {
AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment, kAuthorizationFlagDefaults, &s_authRef);
}
return s_authRef;
}
static OSStatus GetActionRights(const QString &action, AuthorizationFlags flags, AuthorizationRef auth)
{
AuthorizationItem item;
item.name = action.toUtf8().constData();
item.valueLength = 0;
item.value = NULL;
item.flags = 0;
AuthorizationRights rights;
rights.count = 1;
rights.items = &item;
OSStatus result = AuthorizationCopyRights(auth, &rights, kAuthorizationEmptyEnvironment, flags, NULL);
return result;
}
AuthServicesBackend::AuthServicesBackend()
: AuthBackend()
{
setCapabilities(AuthorizeFromClientCapability);
}
AuthServicesBackend::~AuthServicesBackend()
{
if (s_authRef) {
OSStatus err = AuthorizationFree(s_authRef, kAuthorizationFlagDefaults);
qCDebug(KAUTH_OSX) << "AuthorizationFree(" << s_authRef << ") returned" << err;
s_authRef = NULL;
}
}
void AuthServicesBackend::setupAction(const QString &)
{
}
Action::AuthStatus AuthServicesBackend::authorizeAction(const QString &action)
{
Action::AuthStatus retval;
OSStatus result = GetActionRights(action, kAuthorizationFlagExtendRights | kAuthorizationFlagInteractionAllowed, authRef());
qCDebug(KAUTH_OSX) << "AuthServicesBackend::authorizeAction(" << action << ") AuthorizationCopyRights returned" << result;
switch (result) {
case errAuthorizationSuccess:
retval = Action::AuthorizedStatus;
break;
case errAuthorizationCanceled:
retval = Action::UserCancelledStatus;
break;
case errAuthorizationInteractionNotAllowed:
case errAuthorizationDenied:
retval = Action::DeniedStatus;
break;
case errAuthorizationInternal:
retval = Action::AuthRequiredStatus;
break;
case errAuthorizationExternalizeNotAllowed:
case errAuthorizationInternalizeNotAllowed:
case errAuthorizationToolExecuteFailure:
case errAuthorizationToolEnvironmentError:
case errAuthorizationBadAddress:
retval = Action::ErrorStatus;
break;
default:
retval = Action::InvalidStatus;
break;
}
return retval;
}
Action::AuthStatus AuthServicesBackend::actionStatus(const QString &action)
{
Action::AuthStatus retval;
OSStatus result = GetActionRights(action, kAuthorizationFlagExtendRights | kAuthorizationFlagPreAuthorize, authRef());
qCDebug(KAUTH_OSX) << "AuthServicesBackend::actionStatus(" << action << ") AuthorizationCopyRights returned" << result;
switch (result) {
case errAuthorizationSuccess:
retval = Action::AuthorizedStatus;
break;
case errAuthorizationCanceled:
retval = Action::UserCancelledStatus;
break;
case errAuthorizationInteractionNotAllowed:
retval = Action::AuthRequiredStatus;
break;
default:
retval = Action::DeniedStatus;
break;
}
return retval;
}
QByteArray AuthServicesBackend::callerID() const
{
AuthorizationExternalForm ext;
AuthorizationMakeExternalForm(authRef(), &ext);
QByteArray id((const char *)&ext, sizeof(ext));
return id;
}
bool AuthServicesBackend::isCallerAuthorized(const QString &action, const QByteArray &callerID, const QVariantMap &details)
{
Q_UNUSED(details);
AuthorizationExternalForm ext;
memcpy(&ext, callerID.data(), sizeof(ext));
AuthorizationRef auth;
if (AuthorizationCreateFromExternalForm(&ext, &auth) != noErr) {
qCWarning(KAUTH_OSX()) << "AuthorizationCreateFromExternalForm(" << action << "," << callerID.constData() << ") failed";
return false;
}
OSStatus result = GetActionRights(action, kAuthorizationFlagExtendRights | kAuthorizationFlagInteractionAllowed, auth);
AuthorizationFree(auth, kAuthorizationFlagDefaults);
qCDebug(KAUTH_OSX) << "AuthServicesBackend::isCallerAuthorized(" << action << "," << callerID.constData() << ") AuthorizationCopyRights returned" << result;
return result == errAuthorizationSuccess;
}
};
#include "moc_AuthServicesBackend.cpp"