File indexing completed on 2024-04-28 03:52:38
0001 /* 0002 SPDX-FileCopyrightText: 2008 Nicola Gigante <nicola.gigante@gmail.com> 0003 SPDX-FileCopyrightText: 2014, 2016 René Bertin <rjvbertin@gmail.com> 0004 0005 SPDX-License-Identifier: LGPL-2.1-or-later 0006 */ 0007 0008 #include "AuthServicesBackend.h" 0009 0010 #include <qplugin.h> 0011 0012 #include <QDebug> 0013 #include <QLoggingCategory> 0014 0015 Q_DECLARE_LOGGING_CATEGORY(KAUTH_OSX) 0016 // logging category for this backend, default: log stuff >= warning 0017 Q_LOGGING_CATEGORY(KAUTH_OSX, "kf.auth.apple", QtWarningMsg) 0018 0019 namespace KAuth 0020 { 0021 static AuthorizationRef s_authRef = NULL; 0022 0023 AuthorizationRef authRef() 0024 { 0025 if (!s_authRef) { 0026 AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment, kAuthorizationFlagDefaults, &s_authRef); 0027 } 0028 0029 return s_authRef; 0030 } 0031 0032 // GetActionRights return codes: 0033 // errAuthorizationSuccess = 0, 0034 // errAuthorizationInvalidSet = -60001, /* The authorization rights are invalid. */ 0035 // errAuthorizationInvalidRef = -60002, /* The authorization reference is invalid. */ 0036 // errAuthorizationInvalidTag = -60003, /* The authorization tag is invalid. */ 0037 // errAuthorizationInvalidPointer = -60004, /* The returned authorization is invalid. */ 0038 // errAuthorizationDenied = -60005, /* The authorization was denied. */ 0039 // errAuthorizationCanceled = -60006, /* The authorization was cancelled by the user. */ 0040 // errAuthorizationInteractionNotAllowed = -60007, /* The authorization was denied since no user interaction was possible. */ 0041 // errAuthorizationInternal = -60008, /* Unable to obtain authorization for this operation. */ 0042 // errAuthorizationExternalizeNotAllowed = -60009, /* The authorization is not allowed to be converted to an external format. */ 0043 // errAuthorizationInternalizeNotAllowed = -60010, /* The authorization is not allowed to be created from an external format. */ 0044 // errAuthorizationInvalidFlags = -60011, /* The provided option flag(s) are invalid for this authorization operation. */ 0045 // errAuthorizationToolExecuteFailure = -60031, /* The specified program could not be executed. */ 0046 // errAuthorizationToolEnvironmentError = -60032, /* An invalid status was returned during execution of a privileged tool. */ 0047 // errAuthorizationBadAddress = -60033, /* The requested socket address is invalid (must be 0-1023 inclusive). */ 0048 static OSStatus GetActionRights(const QString &action, AuthorizationFlags flags, AuthorizationRef auth) 0049 { 0050 AuthorizationItem item; 0051 item.name = action.toUtf8().constData(); 0052 item.valueLength = 0; 0053 item.value = NULL; 0054 item.flags = 0; 0055 0056 AuthorizationRights rights; 0057 rights.count = 1; 0058 rights.items = &item; 0059 0060 OSStatus result = AuthorizationCopyRights(auth, &rights, kAuthorizationEmptyEnvironment, flags, NULL); 0061 return result; 0062 } 0063 0064 // On OS X we avoid using a helper but grab privilege from here, the client. 0065 AuthServicesBackend::AuthServicesBackend() 0066 : AuthBackend() 0067 { 0068 setCapabilities(AuthorizeFromClientCapability); 0069 } 0070 0071 AuthServicesBackend::~AuthServicesBackend() 0072 { 0073 if (s_authRef) { 0074 OSStatus err = AuthorizationFree(s_authRef, kAuthorizationFlagDefaults); 0075 qCDebug(KAUTH_OSX) << "AuthorizationFree(" << s_authRef << ") returned" << err; 0076 s_authRef = NULL; 0077 } 0078 } 0079 0080 void AuthServicesBackend::setupAction(const QString &) 0081 { 0082 // Nothing to do here... 0083 } 0084 0085 Action::AuthStatus AuthServicesBackend::authorizeAction(const QString &action) 0086 { 0087 Action::AuthStatus retval; 0088 OSStatus result = GetActionRights(action, kAuthorizationFlagExtendRights | kAuthorizationFlagInteractionAllowed, authRef()); 0089 qCDebug(KAUTH_OSX) << "AuthServicesBackend::authorizeAction(" << action << ") AuthorizationCopyRights returned" << result; 0090 switch (result) { 0091 case errAuthorizationSuccess: 0092 retval = Action::AuthorizedStatus; 0093 break; 0094 case errAuthorizationCanceled: 0095 retval = Action::UserCancelledStatus; 0096 break; 0097 case errAuthorizationInteractionNotAllowed: 0098 case errAuthorizationDenied: 0099 retval = Action::DeniedStatus; 0100 break; 0101 case errAuthorizationInternal: 0102 // does this make sense? 0103 retval = Action::AuthRequiredStatus; 0104 break; 0105 case errAuthorizationExternalizeNotAllowed: 0106 case errAuthorizationInternalizeNotAllowed: 0107 case errAuthorizationToolExecuteFailure: 0108 case errAuthorizationToolEnvironmentError: 0109 case errAuthorizationBadAddress: 0110 retval = Action::ErrorStatus; 0111 break; 0112 default: 0113 retval = Action::InvalidStatus; 0114 break; 0115 } 0116 return retval; 0117 } 0118 0119 Action::AuthStatus AuthServicesBackend::actionStatus(const QString &action) 0120 { 0121 Action::AuthStatus retval; 0122 OSStatus result = GetActionRights(action, kAuthorizationFlagExtendRights | kAuthorizationFlagPreAuthorize, authRef()); 0123 qCDebug(KAUTH_OSX) << "AuthServicesBackend::actionStatus(" << action << ") AuthorizationCopyRights returned" << result; 0124 // this function has a simpler return code parser: 0125 switch (result) { 0126 case errAuthorizationSuccess: 0127 retval = Action::AuthorizedStatus; 0128 break; 0129 case errAuthorizationCanceled: 0130 retval = Action::UserCancelledStatus; 0131 break; 0132 case errAuthorizationInteractionNotAllowed: 0133 retval = Action::AuthRequiredStatus; 0134 break; 0135 default: 0136 retval = Action::DeniedStatus; 0137 break; 0138 } 0139 return retval; 0140 } 0141 0142 QByteArray AuthServicesBackend::callerID() const 0143 { 0144 AuthorizationExternalForm ext; 0145 AuthorizationMakeExternalForm(authRef(), &ext); 0146 QByteArray id((const char *)&ext, sizeof(ext)); 0147 0148 return id; 0149 } 0150 0151 bool AuthServicesBackend::isCallerAuthorized(const QString &action, const QByteArray &callerID, const QVariantMap &details) 0152 { 0153 Q_UNUSED(details); 0154 0155 AuthorizationExternalForm ext; 0156 memcpy(&ext, callerID.data(), sizeof(ext)); 0157 0158 AuthorizationRef auth; 0159 0160 if (AuthorizationCreateFromExternalForm(&ext, &auth) != noErr) { 0161 qCWarning(KAUTH_OSX()) << "AuthorizationCreateFromExternalForm(" << action << "," << callerID.constData() << ") failed"; 0162 return false; 0163 } 0164 0165 OSStatus result = GetActionRights(action, kAuthorizationFlagExtendRights | kAuthorizationFlagInteractionAllowed, auth); 0166 0167 AuthorizationFree(auth, kAuthorizationFlagDefaults); 0168 qCDebug(KAUTH_OSX) << "AuthServicesBackend::isCallerAuthorized(" << action << "," << callerID.constData() << ") AuthorizationCopyRights returned" << result; 0169 0170 return result == errAuthorizationSuccess; 0171 } 0172 0173 }; // namespace KAuth 0174 0175 #include "moc_AuthServicesBackend.cpp"