File indexing completed on 2024-04-21 04:43:22
0001 /* 0002 This file is part of the Polkit-qt project 0003 SPDX-FileCopyrightText: 2009 Daniel Nicoletti <dantti85-pk@yahoo.com.br> 0004 SPDX-FileCopyrightText: 2009 Dario Freddi <drf@kde.org> 0005 SPDX-FileCopyrightText: 2009 Jaroslav Reznik <jreznik@redhat.com> 0006 SPDX-FileCopyrightText: 2009 Radek Novacek <rnovacek@redhat.com> 0007 0008 SPDX-License-Identifier: LGPL-2.0-or-later 0009 */ 0010 0011 #include "polkitqt1-authority.h" 0012 0013 #include <QDBusInterface> 0014 #include <QDBusMessage> 0015 #include <QDBusReply> 0016 0017 #include <polkit/polkit.h> 0018 0019 namespace PolkitQt1 0020 { 0021 0022 class AuthorityHelper 0023 { 0024 public: 0025 AuthorityHelper() : q(nullptr) {} 0026 ~AuthorityHelper() { 0027 delete q; 0028 } 0029 Authority *q; 0030 }; 0031 0032 Q_GLOBAL_STATIC(AuthorityHelper, s_globalAuthority) 0033 0034 Authority *Authority::instance(PolkitAuthority *authority) 0035 { 0036 if (!s_globalAuthority()->q) { 0037 new Authority(authority); 0038 } 0039 0040 return s_globalAuthority()->q; 0041 } 0042 0043 Authority::Result polkitResultToResult(PolkitAuthorizationResult *result) 0044 { 0045 if (polkit_authorization_result_get_is_challenge(result)) { 0046 return Authority::Challenge; 0047 } else if (polkit_authorization_result_get_is_authorized(result)) { 0048 return Authority::Yes; 0049 } else { 0050 return Authority::No; 0051 } 0052 } 0053 0054 ActionDescription::List actionsToListAndFree(GList *glist) 0055 { 0056 ActionDescription::List result; 0057 for (GList *glist2 = glist; glist2; glist2 = g_list_next(glist2)) { 0058 gpointer i = glist2->data; 0059 result.append(ActionDescription(static_cast<PolkitActionDescription *>(i))); 0060 g_object_unref(i); 0061 } 0062 0063 g_list_free(glist); 0064 return result; 0065 } 0066 0067 class Q_DECL_HIDDEN Authority::Private 0068 { 0069 public: 0070 // Polkit will return NULL on failures, hence we use it instead of 0 0071 Private(Authority *qq) : q(qq) 0072 , pkAuthority(nullptr) 0073 , m_hasError(false) 0074 , m_systemBus(nullptr) 0075 { 0076 } 0077 0078 ~Private(); 0079 0080 void init(); 0081 0082 /** Use this method to set the error message to \p message. Set recover to \c true 0083 * to try to reinitialize this object with init() method 0084 */ 0085 void setError(Authority::ErrorCode code, const QString &details = QString(), bool recover = false); 0086 0087 void dbusFilter(const QDBusMessage &message); 0088 void dbusSignalAdd(const QString &service, const QString &path, const QString &interface, const QString &name); 0089 void seatSignalsConnect(const QString &seat); 0090 0091 Authority *q; 0092 PolkitAuthority *pkAuthority; 0093 bool m_hasError; 0094 Authority::ErrorCode m_lastError; 0095 QString m_errorDetails; 0096 // Local system bus. QDBusConnection::systemBus() may only be safely used 0097 // inside a QCoreApplication scope as for example destruction of connected 0098 // objects need to happen before the bus disappears. Since this class however 0099 // is a global static and systemBus() internally is a global static we 0100 // cannot assure destruction order. Instead we create a local copy of the 0101 // global systemBus instance so we can make life time to our needs. 0102 // This prevents crashes when cleaning up the global statics. 0103 QDBusConnection *m_systemBus; 0104 GCancellable *m_checkAuthorizationCancellable, 0105 *m_enumerateActionsCancellable, 0106 *m_registerAuthenticationAgentCancellable, 0107 *m_unregisterAuthenticationAgentCancellable, 0108 *m_authenticationAgentResponseCancellable, 0109 *m_enumerateTemporaryAuthorizationsCancellable, 0110 *m_revokeTemporaryAuthorizationsCancellable, 0111 *m_revokeTemporaryAuthorizationCancellable; 0112 0113 /** 0114 * \brief Convert a Qt DetailsMap to the lower level PolkitDetails type 0115 * 0116 * The returned pointer needs to be freed via g_object_unref when no 0117 * longer needed. Returns nullptr if details is empty. 0118 */ 0119 static PolkitDetails* convertDetailsMap(const DetailsMap &details); 0120 static void pk_config_changed(); 0121 static void checkAuthorizationCallback(GObject *object, GAsyncResult *result, gpointer user_data); 0122 static void enumerateActionsCallback(GObject *object, GAsyncResult *result, gpointer user_data); 0123 static void registerAuthenticationAgentCallback(GObject *object, GAsyncResult *result, gpointer user_data); 0124 static void unregisterAuthenticationAgentCallback(GObject *object, GAsyncResult *result, gpointer user_data); 0125 static void authenticationAgentResponseCallback(GObject *object, GAsyncResult *result, gpointer user_data); 0126 static void enumerateTemporaryAuthorizationsCallback(GObject *object, GAsyncResult *result, gpointer user_data); 0127 static void revokeTemporaryAuthorizationsCallback(GObject *object, GAsyncResult *result, gpointer user_data); 0128 static void revokeTemporaryAuthorizationCallback(GObject *object, GAsyncResult *result, gpointer user_data); 0129 }; 0130 0131 Authority::Private::~Private() 0132 { 0133 delete m_systemBus; 0134 g_object_unref(m_checkAuthorizationCancellable); 0135 g_object_unref(m_enumerateActionsCancellable); 0136 g_object_unref(m_registerAuthenticationAgentCancellable); 0137 g_object_unref(m_unregisterAuthenticationAgentCancellable); 0138 g_object_unref(m_authenticationAgentResponseCancellable); 0139 g_object_unref(m_enumerateTemporaryAuthorizationsCancellable); 0140 g_object_unref(m_revokeTemporaryAuthorizationsCancellable); 0141 g_object_unref(m_revokeTemporaryAuthorizationCancellable); 0142 } 0143 0144 Authority::Authority(PolkitAuthority *authority, QObject *parent) 0145 : QObject(parent) 0146 , d(new Private(this)) 0147 { 0148 qRegisterMetaType<PolkitQt1::Authority::Result> (); 0149 qRegisterMetaType<PolkitQt1::ActionDescription::List>(); 0150 0151 Q_ASSERT(!s_globalAuthority()->q); 0152 s_globalAuthority()->q = this; 0153 0154 if (authority) { 0155 d->pkAuthority = authority; 0156 } 0157 0158 d->init(); 0159 } 0160 0161 Authority::~Authority() 0162 { 0163 if (d->pkAuthority != nullptr) { 0164 g_object_unref(d->pkAuthority); 0165 } 0166 0167 delete d; 0168 } 0169 0170 void Authority::Private::init() 0171 { 0172 QDBusError error; 0173 QDBusError dbus_error; 0174 0175 m_systemBus = new QDBusConnection(QDBusConnection::connectToBus(QDBusConnection::SystemBus, 0176 QStringLiteral("polkit_qt_system_bus"))); 0177 0178 m_checkAuthorizationCancellable = g_cancellable_new(); 0179 m_enumerateActionsCancellable = g_cancellable_new(); 0180 m_registerAuthenticationAgentCancellable = g_cancellable_new(); 0181 m_unregisterAuthenticationAgentCancellable = g_cancellable_new(); 0182 m_authenticationAgentResponseCancellable = g_cancellable_new(); 0183 m_enumerateTemporaryAuthorizationsCancellable = g_cancellable_new(); 0184 m_revokeTemporaryAuthorizationsCancellable = g_cancellable_new(); 0185 m_revokeTemporaryAuthorizationCancellable = g_cancellable_new(); 0186 0187 #ifndef POLKIT_QT_1_COMPATIBILITY_MODE 0188 GError *gerror = nullptr; 0189 #endif 0190 if (pkAuthority == nullptr) { 0191 #ifndef POLKIT_QT_1_COMPATIBILITY_MODE 0192 pkAuthority = polkit_authority_get_sync(nullptr, &gerror); 0193 if (gerror != nullptr) { 0194 setError(E_GetAuthority, gerror->message); 0195 g_error_free(gerror); 0196 return; 0197 } 0198 #else 0199 pkAuthority = polkit_authority_get(); 0200 #endif 0201 } 0202 0203 if (pkAuthority == nullptr) { 0204 #ifdef POLKIT_QT_1_COMPATIBILITY_MODE 0205 (E_GetAuthority); 0206 #endif 0207 return; 0208 } 0209 0210 // connect changed signal 0211 g_signal_connect(G_OBJECT(pkAuthority), "changed", G_CALLBACK(pk_config_changed), NULL); 0212 0213 // need to listen to NameOwnerChanged 0214 dbusSignalAdd("org.freedesktop.DBus", "/", "org.freedesktop.DBus", "NameOwnerChanged"); 0215 0216 QString consoleKitService("org.freedesktop.ConsoleKit"); 0217 QString consoleKitManagerPath("/org/freedesktop/ConsoleKit/Manager"); 0218 QString consoleKitManagerInterface("org.freedesktop.ConsoleKit.Manager"); 0219 0220 // first, add signals SeadAdded and SeatRemoved from ConsoleKit Manager 0221 dbusSignalAdd(consoleKitService, consoleKitManagerPath, consoleKitManagerInterface, "SeatAdded"); 0222 dbusSignalAdd(consoleKitService, consoleKitManagerPath, consoleKitManagerInterface, "SeatRemoved"); 0223 0224 // then we need to extract all seats from ConsoleKit 0225 QDBusMessage msg = QDBusMessage::createMethodCall(consoleKitService, consoleKitManagerPath, consoleKitManagerInterface, "GetSeats"); 0226 const QDBusMessage reply = m_systemBus->call(msg); 0227 0228 if (reply.type() != QDBusMessage::ErrorMessage && !reply.arguments().isEmpty()) { 0229 // this method returns a list with present seats 0230 QStringList seats; 0231 QVariant arg = reply.arguments()[0]; 0232 if (arg.type() == qMetaTypeId<QDBusArgument>()) { 0233 arg.value<QDBusArgument>() >> seats; 0234 } else { 0235 seats = arg.toStringList(); 0236 } 0237 // it can be multiple seats present so connect all their signals 0238 Q_FOREACH(const QString &seat, seats) { 0239 seatSignalsConnect(seat); 0240 } 0241 } 0242 } 0243 0244 void Authority::Private::setError(Authority::ErrorCode code, const QString &details, bool recover) 0245 { 0246 if (recover) { 0247 init(); 0248 } 0249 m_lastError = code; 0250 m_errorDetails = details; 0251 m_hasError = true; 0252 } 0253 0254 void Authority::Private::seatSignalsConnect(const QString &seat) 0255 { 0256 QString consoleKitService("org.freedesktop.ConsoleKit"); 0257 QString consoleKitSeatInterface("org.freedesktop.ConsoleKit.Seat"); 0258 // we want to connect to all slots of the seat 0259 dbusSignalAdd(consoleKitService, seat, consoleKitSeatInterface, "DeviceAdded"); 0260 dbusSignalAdd(consoleKitService, seat, consoleKitSeatInterface, "DeviceRemoved"); 0261 dbusSignalAdd(consoleKitService, seat, consoleKitSeatInterface, "SessionAdded"); 0262 dbusSignalAdd(consoleKitService, seat, consoleKitSeatInterface, "SessionRemoved"); 0263 dbusSignalAdd(consoleKitService, seat, consoleKitSeatInterface, "ActiveSessionChanged"); 0264 } 0265 0266 void Authority::Private::dbusSignalAdd(const QString &service, const QString &path, const QString &interface, const QString &name) 0267 { 0268 // FIXME: This code seems to be nonfunctional - it needs to be fixed somewhere (is it Qt BUG?) 0269 m_systemBus->connect(service, path, interface, name, q, SLOT(dbusFilter(QDBusMessage))); 0270 } 0271 0272 void Authority::Private::dbusFilter(const QDBusMessage &message) 0273 { 0274 if (message.type() == QDBusMessage::SignalMessage) { 0275 Q_EMIT q->consoleKitDBChanged(); 0276 0277 // TODO: Test this with the multiseat support 0278 if (message.member() == "SeatAdded") { 0279 seatSignalsConnect(message.arguments()[0].value<QDBusObjectPath>().path()); 0280 } 0281 } 0282 } 0283 0284 bool Authority::hasError() const 0285 { 0286 return d->m_hasError; 0287 } 0288 0289 Authority::ErrorCode Authority::lastError() const 0290 { 0291 return d->m_lastError; 0292 } 0293 0294 const QString Authority::errorDetails() const 0295 { 0296 if (d->m_lastError == E_None) { 0297 return QString(); 0298 } else { 0299 return d->m_errorDetails; 0300 } 0301 } 0302 0303 void Authority::clearError() 0304 { 0305 d->m_hasError = false; 0306 d->m_lastError = E_None; 0307 } 0308 0309 PolkitDetails* Authority::Private::convertDetailsMap(const DetailsMap &details) 0310 { 0311 if (details.empty()) 0312 return nullptr; 0313 0314 auto ret = polkit_details_new(); 0315 0316 for (const auto &entry: details.toStdMap()) { 0317 const auto &key = entry.first; 0318 const auto &value = entry.second; 0319 0320 polkit_details_insert(ret, key.toUtf8().constData(), value.toUtf8().data()); 0321 } 0322 0323 return ret; 0324 } 0325 0326 void Authority::Private::pk_config_changed() 0327 { 0328 Q_EMIT Authority::instance()->configChanged(); 0329 } 0330 0331 PolkitAuthority *Authority::polkitAuthority() const 0332 { 0333 return d->pkAuthority; 0334 } 0335 0336 Authority::Result Authority::checkAuthorizationSyncWithDetails(const QString &actionId, const Subject &subject, AuthorizationFlags flags, const DetailsMap &details) 0337 { 0338 PolkitAuthorizationResult *pk_result; 0339 GError *error = nullptr; 0340 0341 if (Authority::instance()->hasError()) { 0342 return Unknown; 0343 } 0344 0345 if (!subject.isValid()) { 0346 d->setError(E_WrongSubject); 0347 return Unknown; 0348 } 0349 0350 auto pk_details = Authority::Private::convertDetailsMap(details); 0351 0352 pk_result = polkit_authority_check_authorization_sync(d->pkAuthority, 0353 subject.subject(), 0354 actionId.toLatin1().data(), 0355 pk_details, 0356 (PolkitCheckAuthorizationFlags)(int)flags, 0357 nullptr, 0358 &error); 0359 0360 if (pk_details) { 0361 g_object_unref(pk_details); 0362 } 0363 0364 if (error != nullptr) { 0365 d->setError(E_CheckFailed, error->message); 0366 g_error_free(error); 0367 return Unknown; 0368 } 0369 0370 if (!pk_result) { 0371 d->setError(E_UnknownResult); 0372 return Unknown; 0373 } else { 0374 Authority::Result res = polkitResultToResult(pk_result); 0375 g_object_unref(pk_result); 0376 return res; 0377 } 0378 } 0379 0380 Authority::Result Authority::checkAuthorizationSync(const QString &actionId, const Subject &subject, AuthorizationFlags flags) 0381 { 0382 return checkAuthorizationSyncWithDetails(actionId, subject, flags, DetailsMap()); 0383 } 0384 0385 void Authority::checkAuthorizationWithDetails(const QString &actionId, const Subject &subject, AuthorizationFlags flags, const DetailsMap &details) 0386 { 0387 if (Authority::instance()->hasError()) { 0388 return; 0389 } 0390 0391 if (!subject.isValid()) { 0392 d->setError(E_WrongSubject); 0393 return; 0394 } 0395 0396 auto pk_details = Authority::Private::convertDetailsMap(details); 0397 0398 polkit_authority_check_authorization(d->pkAuthority, 0399 subject.subject(), 0400 actionId.toLatin1().data(), 0401 pk_details, 0402 (PolkitCheckAuthorizationFlags)(int)flags, 0403 d->m_checkAuthorizationCancellable, 0404 d->checkAuthorizationCallback, this); 0405 0406 if (pk_details) { 0407 g_object_unref(pk_details); 0408 } 0409 } 0410 0411 void Authority::checkAuthorization(const QString &actionId, const Subject &subject, AuthorizationFlags flags) 0412 { 0413 checkAuthorizationWithDetails(actionId, subject, flags, DetailsMap()); 0414 } 0415 0416 void Authority::Private::checkAuthorizationCallback(GObject *object, GAsyncResult *result, gpointer user_data) 0417 { 0418 Authority *authority = (Authority *) user_data; 0419 0420 Q_ASSERT(authority != nullptr); 0421 0422 GError *error = nullptr; 0423 PolkitAuthorizationResult *pkResult = polkit_authority_check_authorization_finish((PolkitAuthority *) object, result, &error); 0424 0425 if (error != nullptr) { 0426 // We don't want to set error if this is cancellation of some action 0427 if (error->code != 1) { 0428 authority->d->setError(E_CheckFailed, error->message); 0429 } 0430 g_error_free(error); 0431 return; 0432 } 0433 if (pkResult != nullptr) { 0434 Q_EMIT authority->checkAuthorizationFinished(polkitResultToResult(pkResult)); 0435 g_object_unref(pkResult); 0436 } else { 0437 authority->d->setError(E_UnknownResult); 0438 } 0439 } 0440 0441 void Authority::checkAuthorizationCancel() 0442 { 0443 if (!g_cancellable_is_cancelled(d->m_checkAuthorizationCancellable)) { 0444 g_cancellable_cancel(d->m_checkAuthorizationCancellable); 0445 } 0446 } 0447 0448 ActionDescription::List Authority::enumerateActionsSync() 0449 { 0450 if (Authority::instance()->hasError()) { 0451 return ActionDescription::List(); 0452 } 0453 0454 GError *error = nullptr; 0455 0456 GList *glist = polkit_authority_enumerate_actions_sync(d->pkAuthority, 0457 nullptr, 0458 &error); 0459 0460 if (error != nullptr) { 0461 d->setError(E_EnumFailed, error->message); 0462 g_error_free(error); 0463 return ActionDescription::List(); 0464 } 0465 0466 return actionsToListAndFree(glist); 0467 } 0468 0469 void Authority::enumerateActions() 0470 { 0471 if (Authority::instance()->hasError()) { 0472 return; 0473 } 0474 0475 polkit_authority_enumerate_actions(d->pkAuthority, 0476 d->m_enumerateActionsCancellable, 0477 d->enumerateActionsCallback, 0478 Authority::instance()); 0479 } 0480 0481 void Authority::Private::enumerateActionsCallback(GObject *object, GAsyncResult *result, gpointer user_data) 0482 { 0483 Authority *authority = (Authority *) user_data; 0484 Q_ASSERT(authority != nullptr); 0485 GError *error = nullptr; 0486 GList *list = polkit_authority_enumerate_actions_finish((PolkitAuthority *) object, result, &error); 0487 if (error != nullptr) { 0488 // We don't want to set error if this is cancellation of some action 0489 if (error->code != 1) { 0490 authority->d->setError(E_EnumFailed, error->message); 0491 } 0492 g_error_free(error); 0493 return; 0494 } 0495 0496 Q_EMIT authority->enumerateActionsFinished(actionsToListAndFree(list)); 0497 } 0498 0499 void Authority::enumerateActionsCancel() 0500 { 0501 if (!g_cancellable_is_cancelled(d->m_enumerateActionsCancellable)) { 0502 g_cancellable_cancel(d->m_enumerateActionsCancellable); 0503 } 0504 } 0505 0506 bool Authority::registerAuthenticationAgentSync(const Subject &subject, const QString &locale, const QString &objectPath) 0507 { 0508 if (Authority::instance()->hasError()) { 0509 return false; 0510 } 0511 0512 gboolean result; 0513 GError *error = nullptr; 0514 0515 if (!subject.isValid()) { 0516 d->setError(E_WrongSubject); 0517 return false; 0518 } 0519 0520 result = polkit_authority_register_authentication_agent_sync(d->pkAuthority, 0521 subject.subject(), locale.toLatin1().data(), 0522 objectPath.toLatin1().data(), nullptr, &error); 0523 0524 if (error) { 0525 d->setError(E_RegisterFailed, error->message); 0526 g_error_free(error); 0527 return false; 0528 } 0529 0530 return result; 0531 } 0532 0533 void Authority::registerAuthenticationAgent(const Subject &subject, const QString &locale, const QString &objectPath) 0534 { 0535 if (Authority::instance()->hasError()) { 0536 return; 0537 } 0538 0539 if (!subject.isValid()) { 0540 d->setError(E_WrongSubject); 0541 return; 0542 } 0543 0544 polkit_authority_register_authentication_agent(d->pkAuthority, 0545 subject.subject(), 0546 locale.toLatin1().data(), 0547 objectPath.toLatin1().data(), 0548 d->m_registerAuthenticationAgentCancellable, 0549 d->registerAuthenticationAgentCallback, 0550 this); 0551 } 0552 0553 void Authority::Private::registerAuthenticationAgentCallback(GObject *object, GAsyncResult *result, gpointer user_data) 0554 { 0555 Authority *authority = (Authority *) user_data; 0556 Q_ASSERT(authority != nullptr); 0557 GError *error = nullptr; 0558 bool res = polkit_authority_register_authentication_agent_finish((PolkitAuthority *) object, result, &error); 0559 if (error != nullptr) { 0560 // We don't want to set error if this is cancellation of some action 0561 if (error->code != 1) { 0562 authority->d->setError(E_EnumFailed , error->message); 0563 } 0564 g_error_free(error); 0565 return; 0566 } 0567 0568 Q_EMIT authority->registerAuthenticationAgentFinished(res); 0569 } 0570 0571 void Authority::registerAuthenticationAgentCancel() 0572 { 0573 if (!g_cancellable_is_cancelled(d->m_registerAuthenticationAgentCancellable)) { 0574 g_cancellable_cancel(d->m_registerAuthenticationAgentCancellable); 0575 } 0576 } 0577 0578 bool Authority::unregisterAuthenticationAgentSync(const Subject &subject, const QString &objectPath) 0579 { 0580 if (d->pkAuthority) { 0581 return false; 0582 } 0583 0584 if (!subject.isValid()) { 0585 d->setError(E_WrongSubject); 0586 return false; 0587 } 0588 0589 GError *error = nullptr; 0590 0591 bool result = polkit_authority_unregister_authentication_agent_sync(d->pkAuthority, 0592 subject.subject(), 0593 objectPath.toUtf8().data(), 0594 nullptr, 0595 &error); 0596 0597 if (error != nullptr) { 0598 d->setError(E_UnregisterFailed, error->message); 0599 g_error_free(error); 0600 return false; 0601 } 0602 0603 return result; 0604 } 0605 0606 void Authority::unregisterAuthenticationAgent(const Subject &subject, const QString &objectPath) 0607 { 0608 if (Authority::instance()->hasError()) { 0609 return; 0610 } 0611 0612 if (!subject.isValid()) { 0613 d->setError(E_WrongSubject); 0614 return; 0615 } 0616 0617 polkit_authority_unregister_authentication_agent(d->pkAuthority, 0618 subject.subject(), 0619 objectPath.toUtf8().data(), 0620 d->m_unregisterAuthenticationAgentCancellable, 0621 d->unregisterAuthenticationAgentCallback, 0622 this); 0623 } 0624 0625 void Authority::Private::unregisterAuthenticationAgentCallback(GObject *object, GAsyncResult *result, gpointer user_data) 0626 { 0627 Authority *authority = (Authority *) user_data; 0628 Q_ASSERT(authority); 0629 GError *error = nullptr; 0630 bool res = polkit_authority_unregister_authentication_agent_finish((PolkitAuthority *) object, result, &error); 0631 if (error != nullptr) { 0632 // We don't want to set error if this is cancellation of some action 0633 if (error->code != 1) { 0634 authority->d->setError(E_UnregisterFailed, error->message); 0635 } 0636 g_error_free(error); 0637 return; 0638 } 0639 0640 Q_EMIT authority->unregisterAuthenticationAgentFinished(res); 0641 } 0642 0643 void Authority::unregisterAuthenticationAgentCancel() 0644 { 0645 if (!g_cancellable_is_cancelled(d->m_unregisterAuthenticationAgentCancellable)) { 0646 g_cancellable_cancel(d->m_unregisterAuthenticationAgentCancellable); 0647 } 0648 } 0649 0650 bool Authority::authenticationAgentResponseSync(const QString &cookie, const Identity &identity) 0651 { 0652 if (Authority::instance()->hasError()) { 0653 return false; 0654 } 0655 0656 if (cookie.isEmpty() || !identity.isValid()) { 0657 d->setError(E_CookieOrIdentityEmpty); 0658 return false; 0659 } 0660 0661 GError *error = nullptr; 0662 0663 bool result = polkit_authority_authentication_agent_response_sync(d->pkAuthority, 0664 cookie.toUtf8().data(), 0665 identity.identity(), 0666 nullptr, 0667 &error); 0668 if (error != nullptr) { 0669 d->setError(E_AgentResponseFailed, error->message); 0670 g_error_free(error); 0671 return false; 0672 } 0673 0674 return result; 0675 } 0676 0677 void Authority::authenticationAgentResponse(const QString &cookie, const Identity &identity) 0678 { 0679 if (Authority::instance()->hasError()) { 0680 return; 0681 } 0682 0683 if (cookie.isEmpty() || !identity.isValid()) { 0684 d->setError(E_CookieOrIdentityEmpty); 0685 return; 0686 } 0687 0688 polkit_authority_authentication_agent_response(d->pkAuthority, 0689 cookie.toUtf8().data(), 0690 identity.identity(), 0691 d->m_authenticationAgentResponseCancellable, 0692 d->authenticationAgentResponseCallback, 0693 this); 0694 } 0695 0696 void Authority::Private::authenticationAgentResponseCallback(GObject *object, GAsyncResult *result, gpointer user_data) 0697 { 0698 Authority *authority = (Authority *) user_data; 0699 Q_ASSERT(authority); 0700 GError *error = nullptr; 0701 bool res = polkit_authority_authentication_agent_response_finish((PolkitAuthority *) object, result, &error); 0702 if (error != nullptr) { 0703 // We don't want to set error if this is cancellation of some action 0704 if (error->code != 1) { 0705 authority->d->setError(E_AgentResponseFailed, error->message); 0706 } 0707 g_error_free(error); 0708 return; 0709 } 0710 0711 Q_EMIT authority->authenticationAgentResponseFinished(res); 0712 } 0713 0714 void Authority::authenticationAgentResponseCancel() 0715 { 0716 if (!g_cancellable_is_cancelled(d->m_authenticationAgentResponseCancellable)) { 0717 g_cancellable_cancel(d->m_authenticationAgentResponseCancellable); 0718 } 0719 } 0720 0721 TemporaryAuthorization::List Authority::enumerateTemporaryAuthorizationsSync(const Subject &subject) 0722 { 0723 TemporaryAuthorization::List result; 0724 0725 GError *error = nullptr; 0726 GList *glist = polkit_authority_enumerate_temporary_authorizations_sync(d->pkAuthority, 0727 subject.subject(), 0728 nullptr, 0729 &error); 0730 if (error != nullptr) { 0731 d->setError(E_EnumFailed, error->message); 0732 g_error_free(error); 0733 return result; 0734 } 0735 0736 GList *glist2; 0737 for (glist2 = glist; glist2 != nullptr; glist2 = g_list_next(glist2)) { 0738 result.append(TemporaryAuthorization((PolkitTemporaryAuthorization *) glist2->data)); 0739 g_object_unref(glist2->data); 0740 } 0741 0742 g_list_free(glist); 0743 0744 return result; 0745 } 0746 0747 void Authority::Private::enumerateTemporaryAuthorizationsCallback(GObject *object, GAsyncResult *result, gpointer user_data) 0748 { 0749 Authority *authority = (Authority *) user_data; 0750 Q_ASSERT(authority); 0751 GError *error = nullptr; 0752 0753 GList *glist = polkit_authority_enumerate_temporary_authorizations_finish((PolkitAuthority *) object, result, &error); 0754 0755 if (error != nullptr) { 0756 // We don't want to set error if this is cancellation of some action 0757 if (error->code != 1) { 0758 authority->d->setError(E_EnumFailed, error->message); 0759 } 0760 g_error_free(error); 0761 return; 0762 } 0763 TemporaryAuthorization::List res; 0764 GList *glist2; 0765 for (glist2 = glist; glist2 != nullptr; glist2 = g_list_next(glist2)) { 0766 res.append(TemporaryAuthorization((PolkitTemporaryAuthorization *) glist2->data)); 0767 g_object_unref(glist2->data); 0768 } 0769 0770 g_list_free(glist); 0771 0772 Q_EMIT authority->enumerateTemporaryAuthorizationsFinished(res); 0773 } 0774 0775 void Authority::enumerateTemporaryAuthorizationsCancel() 0776 { 0777 if (!g_cancellable_is_cancelled(d->m_enumerateTemporaryAuthorizationsCancellable)) { 0778 g_cancellable_cancel(d->m_enumerateTemporaryAuthorizationsCancellable); 0779 } 0780 } 0781 0782 bool Authority::revokeTemporaryAuthorizationsSync(const Subject &subject) 0783 { 0784 bool result; 0785 if (Authority::instance()->hasError()) { 0786 return false; 0787 } 0788 0789 GError *error = nullptr; 0790 result = polkit_authority_revoke_temporary_authorizations_sync(d->pkAuthority, 0791 subject.subject(), 0792 nullptr, 0793 &error); 0794 if (error != nullptr) { 0795 d->setError(E_RevokeFailed, error->message); 0796 g_error_free(error); 0797 return false; 0798 } 0799 return result; 0800 } 0801 0802 void Authority::revokeTemporaryAuthorizations(const Subject &subject) 0803 { 0804 if (Authority::instance()->hasError()) { 0805 return; 0806 } 0807 0808 polkit_authority_revoke_temporary_authorizations(d->pkAuthority, 0809 subject.subject(), 0810 d->m_revokeTemporaryAuthorizationsCancellable, 0811 d->revokeTemporaryAuthorizationsCallback, 0812 this); 0813 } 0814 0815 void Authority::Private::revokeTemporaryAuthorizationsCallback(GObject *object, GAsyncResult *result, gpointer user_data) 0816 { 0817 Authority *authority = (Authority *) user_data; 0818 Q_ASSERT(authority != nullptr); 0819 GError *error = nullptr; 0820 0821 bool res = polkit_authority_revoke_temporary_authorizations_finish((PolkitAuthority *) object, result, &error); 0822 0823 if (error != nullptr) { 0824 // We don't want to set error if this is cancellation of some action 0825 if (error->code != 1) { 0826 authority->d->setError(E_RevokeFailed, error->message); 0827 } 0828 g_error_free(error); 0829 return; 0830 } 0831 0832 Q_EMIT authority->revokeTemporaryAuthorizationsFinished(res); 0833 } 0834 0835 void Authority::revokeTemporaryAuthorizationsCancel() 0836 { 0837 if (!g_cancellable_is_cancelled(d->m_revokeTemporaryAuthorizationsCancellable)) { 0838 g_cancellable_cancel(d->m_revokeTemporaryAuthorizationsCancellable); 0839 } 0840 } 0841 0842 bool Authority::revokeTemporaryAuthorizationSync(const QString &id) 0843 { 0844 bool result; 0845 if (Authority::instance()->hasError()) { 0846 return false; 0847 } 0848 0849 GError *error = nullptr; 0850 result = polkit_authority_revoke_temporary_authorization_by_id_sync(d->pkAuthority, 0851 id.toUtf8().data(), 0852 nullptr, 0853 &error); 0854 if (error != nullptr) { 0855 d->setError(E_RevokeFailed, error->message); 0856 g_error_free(error); 0857 return false; 0858 } 0859 return result; 0860 } 0861 0862 void Authority::revokeTemporaryAuthorization(const QString &id) 0863 { 0864 if (Authority::instance()->hasError()) { 0865 return; 0866 } 0867 0868 polkit_authority_revoke_temporary_authorization_by_id(d->pkAuthority, 0869 id.toUtf8().data(), 0870 d->m_revokeTemporaryAuthorizationCancellable, 0871 d->revokeTemporaryAuthorizationCallback, 0872 this); 0873 } 0874 0875 void Authority::Private::revokeTemporaryAuthorizationCallback(GObject *object, GAsyncResult *result, gpointer user_data) 0876 { 0877 Authority *authority = (Authority *) user_data; 0878 Q_ASSERT(authority != nullptr); 0879 GError *error = nullptr; 0880 0881 bool res = polkit_authority_revoke_temporary_authorization_by_id_finish((PolkitAuthority *) object, result, &error); 0882 0883 if (error != nullptr) { 0884 // We don't want to set error if this is cancellation of some action 0885 if (error->code != 1) { 0886 authority->d->setError(E_RevokeFailed, error->message); 0887 } 0888 g_error_free(error); 0889 return; 0890 } 0891 0892 Q_EMIT authority->revokeTemporaryAuthorizationFinished(res); 0893 } 0894 0895 void Authority::revokeTemporaryAuthorizationCancel() 0896 { 0897 if (!g_cancellable_is_cancelled(d->m_revokeTemporaryAuthorizationCancellable)) { 0898 g_cancellable_cancel(d->m_revokeTemporaryAuthorizationCancellable); 0899 } 0900 } 0901 0902 } 0903 0904 #include "moc_polkitqt1-authority.cpp"