Support interactive authorization flag in DBusMessage
This flag was introduced to serve as a replacement for a dedicated "interactive" boolean argument in method calls guarded by Polkit. Change-Id: Ida91c9872e70f8ca6672563d0ca6642f38c498ab Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
parent
5c5af7155a
commit
d743df975d
@ -161,6 +161,19 @@ template <> struct TraceReturn<void> { typedef void Type; };
|
||||
funcret DEBUGRET(ret) ptr argcall; \
|
||||
}
|
||||
|
||||
# define DEFINEFUNC_CONDITIONALLY(ret, func, args, argcall, funcret, failret) \
|
||||
typedef ret (* _q_PTR_##func) args; \
|
||||
static inline ret q_##func args \
|
||||
{ \
|
||||
static _q_PTR_##func ptr; \
|
||||
DEBUGCALL(#func, argcall); \
|
||||
if (!ptr) \
|
||||
ptr = (_q_PTR_##func) qdbus_resolve_conditionally(#func); \
|
||||
if (!ptr) \
|
||||
failret; \
|
||||
funcret DEBUGRET(ret) ptr argcall; \
|
||||
}
|
||||
|
||||
#else // defined QT_LINKED_LIBDBUS
|
||||
|
||||
inline bool qdbus_loadLibDBus() { return true; }
|
||||
@ -300,6 +313,26 @@ DEFINEFUNC(const char* , dbus_message_get_signature, (DBusMessage *message),
|
||||
(message), return)
|
||||
DEFINEFUNC(int , dbus_message_get_type, (DBusMessage *message),
|
||||
(message), return)
|
||||
|
||||
#if !defined QT_LINKED_LIBDBUS
|
||||
|
||||
DEFINEFUNC_CONDITIONALLY(dbus_bool_t , dbus_message_get_allow_interactive_authorization, (DBusMessage *message),
|
||||
(message), return, return false)
|
||||
|
||||
#else // defined QT_LINKED_LIBDBUS
|
||||
|
||||
static inline dbus_bool_t q_dbus_message_get_allow_interactive_authorization(DBusMessage *message)
|
||||
{
|
||||
#ifdef DBUS_HEADER_FLAG_ALLOW_INTERACTIVE_AUTHORIZATION
|
||||
return dbus_message_get_allow_interactive_authorization(message);
|
||||
#else
|
||||
Q_UNUSED(message);
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // defined QT_LINKED_LIBDBUS
|
||||
|
||||
DEFINEFUNC(dbus_bool_t , dbus_message_iter_append_basic, (DBusMessageIter *iter,
|
||||
int type,
|
||||
const void *value),
|
||||
@ -378,9 +411,33 @@ DEFINEFUNC(dbus_bool_t , dbus_message_set_sender, (DBusMessage *message,
|
||||
DEFINEFUNC(void , dbus_message_unref, (DBusMessage *message),
|
||||
(message), )
|
||||
|
||||
#if !defined QT_LINKED_LIBDBUS
|
||||
|
||||
DEFINEFUNC_CONDITIONALLY(void, dbus_message_set_allow_interactive_authorization,
|
||||
(DBusMessage *message, dbus_bool_t allow), (message, allow), return, return)
|
||||
|
||||
|
||||
#else // defined QT_LINKED_LIBDBUS
|
||||
|
||||
static inline void q_dbus_message_set_allow_interactive_authorization(DBusMessage *message, dbus_bool_t allow)
|
||||
{
|
||||
#ifdef DBUS_HEADER_FLAG_ALLOW_INTERACTIVE_AUTHORIZATION
|
||||
dbus_message_set_allow_interactive_authorization(message, allow);
|
||||
#else
|
||||
Q_UNUSED(message);
|
||||
Q_UNUSED(allow);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // defined QT_LINKED_LIBDBUS
|
||||
|
||||
/* dbus-misc.h */
|
||||
DEFINEFUNC(char* , dbus_get_local_machine_id , (void), (), return)
|
||||
|
||||
DEFINEFUNC(void , dbus_get_version , (int *major_version, int *minor_version, int *micro_version)
|
||||
, (major_version, minor_version, micro_version)
|
||||
, return)
|
||||
|
||||
|
||||
/* dbus-pending-call.h */
|
||||
DEFINEFUNC(dbus_bool_t , dbus_pending_call_set_notify, (DBusPendingCall *pending,
|
||||
|
@ -70,7 +70,8 @@ static inline const char *data(const QByteArray &arr)
|
||||
QDBusMessagePrivate::QDBusMessagePrivate()
|
||||
: msg(0), reply(0), localReply(0), ref(1), type(QDBusMessage::InvalidMessage),
|
||||
delayedReply(false), localMessage(false),
|
||||
parametersValidated(false), autoStartService(true)
|
||||
parametersValidated(false), autoStartService(true),
|
||||
interactiveAuthorizationAllowed(false)
|
||||
{
|
||||
}
|
||||
|
||||
@ -138,6 +139,8 @@ DBusMessage *QDBusMessagePrivate::toDBusMessage(const QDBusMessage &message, QDB
|
||||
msg = q_dbus_message_new_method_call(data(d_ptr->service.toUtf8()), d_ptr->path.toUtf8(),
|
||||
data(d_ptr->interface.toUtf8()), d_ptr->name.toUtf8());
|
||||
q_dbus_message_set_auto_start( msg, d_ptr->autoStartService );
|
||||
q_dbus_message_set_allow_interactive_authorization(msg, d_ptr->interactiveAuthorizationAllowed);
|
||||
|
||||
break;
|
||||
case QDBusMessage::ReplyMessage:
|
||||
msg = q_dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_RETURN);
|
||||
@ -242,6 +245,7 @@ QDBusMessage QDBusMessagePrivate::fromDBusMessage(DBusMessage *dmsg, QDBusConnec
|
||||
QString::fromUtf8(q_dbus_message_get_member(dmsg));
|
||||
message.d_ptr->service = QString::fromUtf8(q_dbus_message_get_sender(dmsg));
|
||||
message.d_ptr->signature = QString::fromUtf8(q_dbus_message_get_signature(dmsg));
|
||||
message.d_ptr->interactiveAuthorizationAllowed = q_dbus_message_get_allow_interactive_authorization(dmsg);
|
||||
message.d_ptr->msg = q_dbus_message_ref(dmsg);
|
||||
|
||||
QDBusDemarshaller demarshaller(capabilities);
|
||||
@ -724,6 +728,44 @@ bool QDBusMessage::autoStartService() const
|
||||
return d_ptr->autoStartService;
|
||||
}
|
||||
|
||||
/*!
|
||||
Sets the interactive authorization flag to \a enable.
|
||||
This flag only makes sense for method call messages, where it
|
||||
tells the D-Bus server that the caller of the method is prepared
|
||||
to wait for interactive authorization to take place (for instance
|
||||
via Polkit) before the actual method is processed.
|
||||
|
||||
By default this flag is false and the other end is expected to
|
||||
make any authorization decisions non-interactively and promptly.
|
||||
|
||||
The \c org.freedesktop.DBus.Error.InteractiveAuthorizationRequired
|
||||
error indicates that authorization failed, but could have succeeded
|
||||
if this flag had been set.
|
||||
|
||||
\sa isInteractiveAuthorizationAllowed()
|
||||
|
||||
\since 5.12
|
||||
*/
|
||||
void QDBusMessage::setInteractiveAuthorizationAllowed(bool enable)
|
||||
{
|
||||
d_ptr->interactiveAuthorizationAllowed = enable;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the interactive authorization allowed flag, as set by
|
||||
setInteractiveAuthorizationAllowed(). By default this flag
|
||||
is false and the other end is expected to make any authorization
|
||||
decisions non-interactively and promptly.
|
||||
|
||||
\sa setInteractiveAuthorizationAllowed()
|
||||
|
||||
\since 5.12
|
||||
*/
|
||||
bool QDBusMessage::isInteractiveAuthorizationAllowed() const
|
||||
{
|
||||
return d_ptr->interactiveAuthorizationAllowed;
|
||||
}
|
||||
|
||||
/*!
|
||||
Sets the arguments that are going to be sent over D-Bus to \a arguments. Those
|
||||
will be the arguments to a method call or the parameters in the signal.
|
||||
|
@ -119,6 +119,9 @@ public:
|
||||
void setAutoStartService(bool enable);
|
||||
bool autoStartService() const;
|
||||
|
||||
void setInteractiveAuthorizationAllowed(bool enable);
|
||||
bool isInteractiveAuthorizationAllowed() const;
|
||||
|
||||
void setArguments(const QList<QVariant> &arguments);
|
||||
QList<QVariant> arguments() const;
|
||||
|
||||
|
@ -87,6 +87,7 @@ public:
|
||||
uint localMessage : 1;
|
||||
mutable uint parametersValidated : 1;
|
||||
uint autoStartService : 1;
|
||||
uint interactiveAuthorizationAllowed : 1;
|
||||
|
||||
static void setParametersValidated(QDBusMessage &msg, bool enable)
|
||||
{ msg.d_ptr->parametersValidated = enable; }
|
||||
|
@ -4,4 +4,11 @@ HEADERS += ../myobject.h
|
||||
TARGET = ../tst_qdbusinterface
|
||||
DESTDIR = ./
|
||||
|
||||
QT = core core-private dbus testlib
|
||||
QT = core core-private dbus dbus-private testlib
|
||||
|
||||
qtConfig(dbus-linked) {
|
||||
DEFINES += QT_LINKED_LIBDBUS
|
||||
QMAKE_USE += dbus
|
||||
} else {
|
||||
SOURCES += ../../../../src/dbus/qdbus_symbols.cpp
|
||||
}
|
||||
|
@ -115,6 +115,16 @@ public slots:
|
||||
return obj.m_complexProp;
|
||||
}
|
||||
|
||||
bool interactiveAuthorization()
|
||||
{
|
||||
if (message().isInteractiveAuthorizationAllowed())
|
||||
return true;
|
||||
|
||||
sendErrorReply(QStringLiteral("org.freedesktop.DBus.Error.InteractiveAuthorizationRequired"),
|
||||
QStringLiteral("Interactive authentication required."));
|
||||
return false;
|
||||
}
|
||||
|
||||
void quit()
|
||||
{
|
||||
qApp->quit();
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include <QtTest/QtTest>
|
||||
#include <QtCore/qvariant.h>
|
||||
#include <QtDBus/QtDBus>
|
||||
#include <QtDBus/private/qdbus_symbols_p.h>
|
||||
#include <qdebug.h>
|
||||
#include "../qdbusmarshall/common.h"
|
||||
#include "myobject.h"
|
||||
@ -213,6 +214,8 @@ private slots:
|
||||
void propertyWritePeer();
|
||||
void complexPropertyReadPeer();
|
||||
void complexPropertyWritePeer();
|
||||
|
||||
void interactiveAuthorizationRequired();
|
||||
private:
|
||||
QProcess proc;
|
||||
};
|
||||
@ -1127,6 +1130,30 @@ void tst_QDBusInterface::complexPropertyWritePeer()
|
||||
QCOMPARE(complexPropPeer(), arg);
|
||||
}
|
||||
|
||||
void tst_QDBusInterface::interactiveAuthorizationRequired()
|
||||
{
|
||||
int major;
|
||||
int minor;
|
||||
int micro;
|
||||
q_dbus_get_version(&major, &minor, µ);
|
||||
|
||||
QVersionNumber dbusVersion(major, minor, micro);
|
||||
if (dbusVersion < QVersionNumber(1, 9, 2))
|
||||
QSKIP("Your DBus library is too old to support interactive authorization");
|
||||
|
||||
QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "interactiveAuthorization");
|
||||
QDBusMessage reply = QDBusConnection::sessionBus().call(req);
|
||||
|
||||
QCOMPARE(reply.type(), QDBusMessage::ErrorMessage);
|
||||
QCOMPARE(reply.errorName(), QStringLiteral("org.freedesktop.DBus.Error.InteractiveAuthorizationRequired"));
|
||||
|
||||
req.setInteractiveAuthorizationAllowed(true);
|
||||
reply = QDBusConnection::sessionBus().call(req);
|
||||
|
||||
QCOMPARE(reply.type(), QDBusMessage::ReplyMessage);
|
||||
QVERIFY(reply.arguments().at(0).toBool());
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QDBusInterface)
|
||||
|
||||
#include "tst_qdbusinterface.moc"
|
||||
|
Loading…
Reference in New Issue
Block a user