File indexing completed on 2024-04-28 13:31:52
0001 /* This file is part of the KDE project 0002 SPDX-FileCopyrightText: 2009 Jaroslav Reznik <jreznik@redhat.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include <QDBusConnection> 0008 #include <QDebug> 0009 0010 #include <KWindowSystem> 0011 0012 #include <PolkitQt1/Agent/Session> 0013 #include <PolkitQt1/Details> 0014 #include <PolkitQt1/Identity> 0015 #include <PolkitQt1/Subject> 0016 0017 #include "AuthDialog.h" 0018 #include "policykitlistener.h" 0019 #include "polkit1authagentadaptor.h" 0020 0021 PolicyKitListener::PolicyKitListener(QObject *parent) 0022 : Listener(parent) 0023 , m_inProgress(false) 0024 , m_selectedUser(nullptr) 0025 { 0026 (void)new Polkit1AuthAgentAdaptor(this); 0027 0028 if (!QDBusConnection::sessionBus().registerObject("/org/kde/Polkit1AuthAgent", 0029 this, 0030 QDBusConnection::ExportScriptableSlots | QDBusConnection::ExportScriptableProperties 0031 | QDBusConnection::ExportAdaptors)) { 0032 qWarning() << "Could not initiate DBus helper!"; 0033 } 0034 0035 qDebug() << "Listener online"; 0036 } 0037 0038 PolicyKitListener::~PolicyKitListener() 0039 { 0040 } 0041 0042 void PolicyKitListener::setWIdForAction(const QString &action, qulonglong wID) 0043 { 0044 qDebug() << "On to the handshake"; 0045 m_actionsToWID[action] = wID; 0046 } 0047 0048 void PolicyKitListener::initiateAuthentication(const QString &actionId, 0049 const QString &message, 0050 const QString &iconName, 0051 const PolkitQt1::Details &details, 0052 const QString &cookie, 0053 const PolkitQt1::Identity::List &identities, 0054 PolkitQt1::Agent::AsyncResult *result) 0055 { 0056 qDebug() << "Initiating authentication"; 0057 0058 if (m_inProgress) { 0059 result->setError(i18n("Another client is already authenticating, please try again later.")); 0060 result->setCompleted(); 0061 qDebug() << "Another client is already authenticating, please try again later."; 0062 return; 0063 } 0064 0065 m_identities = identities; 0066 m_cookie = cookie; 0067 m_result = result; 0068 m_session.clear(); 0069 0070 m_inProgress = true; 0071 0072 const WId parentId = m_actionsToWID.value(actionId, 0); 0073 0074 m_dialog = new AuthDialog(actionId, message, iconName, details, identities, parentId); 0075 connect(m_dialog.data(), SIGNAL(okClicked()), SLOT(dialogAccepted())); 0076 connect(m_dialog.data(), SIGNAL(rejected()), SLOT(dialogCanceled())); 0077 connect(m_dialog.data(), SIGNAL(adminUserSelected(PolkitQt1::Identity)), SLOT(userSelected(PolkitQt1::Identity))); 0078 0079 qDebug() << "WinId of the dialog is " << m_dialog.data()->winId() << m_dialog.data()->effectiveWinId(); 0080 m_dialog.data()->setOptions(); 0081 m_dialog.data()->show(); 0082 KWindowSystem::forceActiveWindow(m_dialog.data()->winId()); 0083 qDebug() << "WinId of the shown dialog is " << m_dialog.data()->winId() << m_dialog.data()->effectiveWinId(); 0084 0085 if (identities.length() == 1) { 0086 m_selectedUser = identities[0]; 0087 } else { 0088 m_selectedUser = m_dialog.data()->adminUserSelected(); 0089 } 0090 0091 m_numTries = 0; 0092 tryAgain(); 0093 } 0094 0095 void PolicyKitListener::tryAgain() 0096 { 0097 qDebug() << "Trying again"; 0098 m_wasCancelled = false; 0099 0100 // We will create new session only when some user is selected 0101 if (m_selectedUser.isValid()) { 0102 m_session = new Session(m_selectedUser, m_cookie, m_result); 0103 // clang-format off 0104 connect(m_session.data(), SIGNAL(request(QString,bool)), this, SLOT(request(QString,bool))); 0105 connect(m_session.data(), SIGNAL(completed(bool)), this, SLOT(completed(bool))); 0106 connect(m_session.data(), SIGNAL(showError(QString)), this, SLOT(showError(QString))); 0107 connect(m_session.data(), SIGNAL(showInfo(QString)), this, SLOT(showInfo(QString))); 0108 // clang-format on 0109 0110 m_session.data()->initiate(); 0111 } 0112 } 0113 0114 void PolicyKitListener::finishObtainPrivilege() 0115 { 0116 qDebug() << "Finishing obtaining privileges"; 0117 0118 // Number of tries increase only when some user is selected 0119 if (m_selectedUser.isValid()) { 0120 m_numTries++; 0121 } 0122 0123 if (!m_gainedAuthorization && !m_wasCancelled && !m_dialog.isNull()) { 0124 m_dialog.data()->authenticationFailure(); 0125 0126 if (m_numTries < 3) { 0127 m_session.data()->deleteLater(); 0128 0129 tryAgain(); 0130 return; 0131 } 0132 } 0133 0134 if (!m_session.isNull()) { 0135 m_session.data()->result()->setCompleted(); 0136 } else { 0137 m_result->setCompleted(); 0138 } 0139 m_session.data()->deleteLater(); 0140 0141 if (!m_dialog.isNull()) { 0142 m_dialog.data()->hide(); 0143 m_dialog.data()->deleteLater(); 0144 } 0145 0146 m_inProgress = false; 0147 0148 qDebug() << "Finish obtain authorization:" << m_gainedAuthorization; 0149 } 0150 0151 bool PolicyKitListener::initiateAuthenticationFinish() 0152 { 0153 qDebug() << "Finishing authentication"; 0154 return true; 0155 } 0156 0157 void PolicyKitListener::cancelAuthentication() 0158 { 0159 qDebug() << "Cancelling authentication"; 0160 0161 m_wasCancelled = true; 0162 finishObtainPrivilege(); 0163 } 0164 0165 void PolicyKitListener::request(const QString &request, bool echo) 0166 { 0167 Q_UNUSED(echo); 0168 qDebug() << "Request: " << request; 0169 0170 if (!m_dialog.isNull()) { 0171 m_dialog.data()->setRequest(request, m_selectedUser.isValid() && m_selectedUser.toString() == "unix-user:root"); 0172 } 0173 } 0174 0175 void PolicyKitListener::completed(bool gainedAuthorization) 0176 { 0177 qDebug() << "Completed: " << gainedAuthorization; 0178 0179 m_gainedAuthorization = gainedAuthorization; 0180 0181 finishObtainPrivilege(); 0182 } 0183 0184 void PolicyKitListener::showError(const QString &text) 0185 { 0186 qDebug() << "Error: " << text; 0187 if (!m_dialog.isNull()) { 0188 m_dialog.data()->showError(text); 0189 } 0190 } 0191 0192 void PolicyKitListener::showInfo(const QString &text) 0193 { 0194 qDebug() << "Info: " << text; 0195 if (!m_dialog.isNull()) { 0196 m_dialog.data()->showInfo(text); 0197 } 0198 } 0199 0200 void PolicyKitListener::dialogAccepted() 0201 { 0202 qDebug() << "Dialog accepted"; 0203 0204 if (!m_dialog.isNull()) { 0205 m_session.data()->setResponse(m_dialog.data()->password()); 0206 } 0207 } 0208 0209 void PolicyKitListener::dialogCanceled() 0210 { 0211 qDebug() << "Dialog cancelled"; 0212 0213 m_wasCancelled = true; 0214 if (!m_session.isNull()) { 0215 m_session.data()->cancel(); 0216 } 0217 0218 finishObtainPrivilege(); 0219 } 0220 0221 void PolicyKitListener::userSelected(const PolkitQt1::Identity &identity) 0222 { 0223 m_selectedUser = identity; 0224 // If some user is selected we must destroy existing session 0225 if (!m_session.isNull()) { 0226 m_session.data()->deleteLater(); 0227 } 0228 tryAgain(); 0229 }