summaryrefslogtreecommitdiff
blob: b0f26a3ae988525b7c2977b5ddb84e9844e5e6c0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
commit 1e20082a62fb4d1460f1df307cb7c72eed9da015
Author: Albert Astals Cid <aacid@kde.org>
Date:   Wed May 10 10:03:45 2017 +0200

    Verify that whoever is calling us is actually who he says he is
    
    CVE-2017-8422 (backported)

diff --git a/src/AuthBackend.cpp b/src/AuthBackend.cpp
index ff91dd5..fa8c258 100644
--- a/src/AuthBackend.cpp
+++ b/src/AuthBackend.cpp
@@ -54,6 +54,11 @@ void AuthBackend::setCapabilities(AuthBackend::Capabilities capabilities)
     d->capabilities = capabilities;
 }
 
+AuthBackend::ExtraCallerIDVerificationMethod AuthBackend::extraCallerIDVerificationMethod() const
+{
+    return NoExtraCallerIDVerificationMethod;
+}
+
 bool AuthBackend::actionExists(const QString &action)
 {
     Q_UNUSED(action);
diff --git a/src/AuthBackend.h b/src/AuthBackend.h
index c67a706..09195ef 100644
--- a/src/AuthBackend.h
+++ b/src/AuthBackend.h
@@ -43,6 +43,12 @@ public:
     };
     Q_DECLARE_FLAGS(Capabilities, Capability)
 
+    enum ExtraCallerIDVerificationMethod {
+        NoExtraCallerIDVerificationMethod,
+        VerifyAgainstDBusServiceName,
+        VerifyAgainstDBusServicePid,
+    };
+
     AuthBackend();
     virtual ~AuthBackend();
     virtual void setupAction(const QString &action) = 0;
@@ -50,6 +56,7 @@ public:
     virtual Action::AuthStatus authorizeAction(const QString &action) = 0;
     virtual Action::AuthStatus actionStatus(const QString &action) = 0;
     virtual QByteArray callerID() const = 0;
+    virtual ExtraCallerIDVerificationMethod extraCallerIDVerificationMethod() const;
     virtual bool isCallerAuthorized(const QString &action, QByteArray callerID) = 0;
     virtual bool actionExists(const QString &action);
 
diff --git a/src/backends/dbus/DBusHelperProxy.cpp b/src/backends/dbus/DBusHelperProxy.cpp
index e861ebb..9612f9a 100644
--- a/src/backends/dbus/DBusHelperProxy.cpp
+++ b/src/backends/dbus/DBusHelperProxy.cpp
@@ -232,6 +232,29 @@ bool DBusHelperProxy::hasToStopAction()
     return m_stopRequest;
 }
 
+bool DBusHelperProxy::isCallerAuthorized(const QString &action, const QByteArray &callerID)
+{
+    // Check the caller is really who it says it is
+    switch (BackendsManager::authBackend()->extraCallerIDVerificationMethod()) {
+        case AuthBackend::NoExtraCallerIDVerificationMethod:
+        break;
+
+        case AuthBackend::VerifyAgainstDBusServiceName:
+            if (message().service().toUtf8() != callerID) {
+                return false;
+            }
+        break;
+
+        case AuthBackend::VerifyAgainstDBusServicePid:
+            if (connection().interface()->servicePid(message().service()).value() != callerID.toUInt()) {
+                return false;
+            }
+        break;
+    }
+
+    return BackendsManager::authBackend()->isCallerAuthorized(action, callerID);
+}
+
 QByteArray DBusHelperProxy::performAction(const QString &action, const QByteArray &callerID, QByteArray arguments)
 {
     if (!responder) {
@@ -256,7 +279,7 @@ QByteArray DBusHelperProxy::performAction(const QString &action, const QByteArra
     QTimer *timer = responder->property("__KAuth_Helper_Shutdown_Timer").value<QTimer *>();
     timer->stop();
 
-    if (BackendsManager::authBackend()->isCallerAuthorized(action, callerID)) {
+    if (isCallerAuthorized(action, callerID)) {
         QString slotname = action;
         if (slotname.startsWith(m_name + QLatin1Char('.'))) {
             slotname = slotname.right(slotname.length() - m_name.length() - 1);
@@ -298,7 +321,7 @@ uint DBusHelperProxy::authorizeAction(const QString &action, const QByteArray &c
     QTimer *timer = responder->property("__KAuth_Helper_Shutdown_Timer").value<QTimer *>();
     timer->stop();
 
-    if (BackendsManager::authBackend()->isCallerAuthorized(action, callerID)) {
+    if (isCallerAuthorized(action, callerID)) {
         retVal = static_cast<uint>(Action::AuthorizedStatus);
     } else {
         retVal = static_cast<uint>(Action::DeniedStatus);
diff --git a/src/backends/dbus/DBusHelperProxy.h b/src/backends/dbus/DBusHelperProxy.h
index 52b0ac4..82cec5a 100644
--- a/src/backends/dbus/DBusHelperProxy.h
+++ b/src/backends/dbus/DBusHelperProxy.h
@@ -25,12 +25,13 @@
 #include "kauthactionreply.h"
 
 #include <QDBusConnection>
+#include <QDBusContext>
 #include <QVariant>
 
 namespace KAuth
 {
 
-class DBusHelperProxy : public HelperProxy
+class DBusHelperProxy : public HelperProxy, protected QDBusContext
 {
     Q_OBJECT
     Q_PLUGIN_METADATA(IID "org.kde.DBusHelperProxy")
@@ -79,6 +80,9 @@ Q_SIGNALS:
 
 private Q_SLOTS:
     void remoteSignalReceived(int type, const QString &action, QByteArray blob);
+
+private:
+    bool isCallerAuthorized(const QString &action, const QByteArray &callerID);
 };
 
 } // namespace Auth
diff --git a/src/backends/policykit/PolicyKitBackend.cpp b/src/backends/policykit/PolicyKitBackend.cpp
index c2b4d42..bf038a8 100644
--- a/src/backends/policykit/PolicyKitBackend.cpp
+++ b/src/backends/policykit/PolicyKitBackend.cpp
@@ -78,6 +78,11 @@ QByteArray PolicyKitBackend::callerID() const
     return a;
 }
 
+AuthBackend::ExtraCallerIDVerificationMethod Polkit1Backend::extraCallerIDVerificationMethod() const
+{
+    return VerifyAgainstDBusServicePid;
+}
+
 bool PolicyKitBackend::isCallerAuthorized(const QString &action, QByteArray callerID)
 {
     QDataStream s(&callerID, QIODevice::ReadOnly);
diff --git a/src/backends/policykit/PolicyKitBackend.h b/src/backends/policykit/PolicyKitBackend.h
index eb17a3a..38b0240 100644
--- a/src/backends/policykit/PolicyKitBackend.h
+++ b/src/backends/policykit/PolicyKitBackend.h
@@ -40,6 +40,7 @@ public:
     virtual Action::AuthStatus authorizeAction(const QString &);
     virtual Action::AuthStatus actionStatus(const QString &);
     virtual QByteArray callerID() const;
+    ExtraCallerIDVerificationMethod extraCallerIDVerificationMethod() const Q_DECL_OVERRIDE;
     virtual bool isCallerAuthorized(const QString &action, QByteArray callerID);
 
 private Q_SLOTS:
diff --git a/src/backends/polkit-1/Polkit1Backend.cpp b/src/backends/polkit-1/Polkit1Backend.cpp
index 78ee5bb..774588c 100644
--- a/src/backends/polkit-1/Polkit1Backend.cpp
+++ b/src/backends/polkit-1/Polkit1Backend.cpp
@@ -162,6 +162,11 @@ QByteArray Polkit1Backend::callerID() const
         return QDBusConnection::systemBus().baseService().toUtf8();
 }
 
+AuthBackend::ExtraCallerIDVerificationMethod Polkit1Backend::extraCallerIDVerificationMethod() const
+{
+    return VerifyAgainstDBusServiceName;
+}
+
 bool Polkit1Backend::isCallerAuthorized(const QString &action, QByteArray callerID)
 {
     PolkitQt1::SystemBusNameSubject subject(QString::fromUtf8(callerID));
diff --git a/src/backends/polkit-1/Polkit1Backend.h b/src/backends/polkit-1/Polkit1Backend.h
index e0d661b..d816664 100644
--- a/src/backends/polkit-1/Polkit1Backend.h
+++ b/src/backends/polkit-1/Polkit1Backend.h
@@ -49,6 +49,7 @@ public:
     virtual Action::AuthStatus authorizeAction(const QString &);
     virtual Action::AuthStatus actionStatus(const QString &);
     virtual QByteArray callerID() const;
+    ExtraCallerIDVerificationMethod extraCallerIDVerificationMethod() const Q_DECL_OVERRIDE;
     virtual bool isCallerAuthorized(const QString &action, QByteArray callerID);
     virtual bool actionExists(const QString &action);