File indexing completed on 2024-04-28 16:59:41

0001 /*
0002    Copyright (C) 2019 Andreas Hartmetz <ahartmetz@gmail.com>
0003 
0004    This library is free software; you can redistribute it and/or
0005    modify it under the terms of the GNU Library General Public
0006    License as published by the Free Software Foundation; either
0007    version 2 of the License, or (at your option) any later version.
0008 
0009    This library is distributed in the hope that it will be useful,
0010    but WITHOUT ANY WARRANTY; without even the implied warranty of
0011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0012    Library General Public License for more details.
0013 
0014    You should have received a copy of the GNU Library General Public License
0015    along with this library; see the file COPYING.LGPL.  If not, write to
0016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0017    Boston, MA 02110-1301, USA.
0018 
0019    Alternatively, this file is available under the Mozilla Public License
0020    Version 1.1.  You may obtain a copy of the License at
0021    http://www.mozilla.org/MPL/
0022 */
0023 
0024 static Message createEavesdropMessage(const char *messageType)
0025 {
0026     Message ret = Message::createCall("/org/freedesktop/DBus", "org.freedesktop.DBus", "AddMatch");
0027     ret.setDestination("org.freedesktop.DBus");
0028     Arguments::Writer writer;
0029     std::string str = "eavesdrop=true,type=";
0030     str += messageType;
0031     writer.writeString(cstring(str.c_str()));
0032     ret.setArguments(writer.finish());
0033     return ret;
0034 }
0035 
0036 enum SetupEavesdroppingResult
0037 {
0038     OldStyleEavesdropping = 0,
0039     NewStyleEavesdropping,
0040     FailedEavesdropping
0041 };
0042 
0043 static SetupEavesdroppingResult setupEavesdropping(Connection *connection)
0044 {
0045     {
0046         // new way to request eavesdropping / monitoring, not yet universally available
0047         Message msg = Message::createCall("/org/freedesktop/DBus", "org.freedesktop.DBus.Monitoring",
0048                                           "BecomeMonitor");
0049         msg.setDestination("org.freedesktop.DBus");
0050         Arguments::Writer writer;
0051         writer.beginArray(Arguments::Writer::WriteTypesOfEmptyArray);
0052         writer.writeString(cstring());
0053         writer.endArray();
0054         writer.writeUint32(0);
0055         msg.setArguments(writer.finish());
0056         PendingReply pendingReply = connection->send(std::move(msg));
0057         while (!pendingReply.isFinished()) {
0058             connection->eventDispatcher()->poll();
0059         }
0060         if (!pendingReply.isError()) {
0061             return NewStyleEavesdropping;
0062         }
0063     }
0064 
0065     {
0066         // old way to request eavesdropping / monitoring, now disabled in some distributions
0067         static const int messageTypeCount = 4;
0068         const char *messageType[messageTypeCount] = {
0069             "signal",
0070             "method_call",
0071             "method_return",
0072             "error"
0073         };
0074 
0075         std::vector<PendingReply> pendingReplies;
0076         pendingReplies.reserve(messageTypeCount);
0077         for (int i = 0; i < messageTypeCount; i++) {
0078             pendingReplies.emplace_back(connection->send(createEavesdropMessage(messageType[i])));
0079         }
0080 
0081         bool done = false;
0082         while (!done) {
0083             connection->eventDispatcher()->poll();
0084             done = true;
0085             for (const PendingReply &PR : pendingReplies) {
0086                 done = done && PR.isFinished();
0087                 if (PR.isError()) {
0088                     // ### this error detection doesn't seem to work - on my test system with Kubuntu 19.10,
0089                     // eavesdropping failed silently(!)
0090                     return FailedEavesdropping;
0091                 }
0092             }
0093         }
0094     }
0095     return OldStyleEavesdropping;
0096 }