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; \
|
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
|
#else // defined QT_LINKED_LIBDBUS
|
||||||
|
|
||||||
inline bool qdbus_loadLibDBus() { return true; }
|
inline bool qdbus_loadLibDBus() { return true; }
|
||||||
@ -300,6 +313,26 @@ DEFINEFUNC(const char* , dbus_message_get_signature, (DBusMessage *message),
|
|||||||
(message), return)
|
(message), return)
|
||||||
DEFINEFUNC(int , dbus_message_get_type, (DBusMessage *message),
|
DEFINEFUNC(int , dbus_message_get_type, (DBusMessage *message),
|
||||||
(message), return)
|
(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,
|
DEFINEFUNC(dbus_bool_t , dbus_message_iter_append_basic, (DBusMessageIter *iter,
|
||||||
int type,
|
int type,
|
||||||
const void *value),
|
const void *value),
|
||||||
@ -378,9 +411,33 @@ DEFINEFUNC(dbus_bool_t , dbus_message_set_sender, (DBusMessage *message,
|
|||||||
DEFINEFUNC(void , dbus_message_unref, (DBusMessage *message),
|
DEFINEFUNC(void , dbus_message_unref, (DBusMessage *message),
|
||||||
(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 */
|
/* dbus-misc.h */
|
||||||
DEFINEFUNC(char* , dbus_get_local_machine_id , (void), (), return)
|
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 */
|
/* dbus-pending-call.h */
|
||||||
DEFINEFUNC(dbus_bool_t , dbus_pending_call_set_notify, (DBusPendingCall *pending,
|
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()
|
QDBusMessagePrivate::QDBusMessagePrivate()
|
||||||
: msg(0), reply(0), localReply(0), ref(1), type(QDBusMessage::InvalidMessage),
|
: msg(0), reply(0), localReply(0), ref(1), type(QDBusMessage::InvalidMessage),
|
||||||
delayedReply(false), localMessage(false),
|
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(),
|
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());
|
data(d_ptr->interface.toUtf8()), d_ptr->name.toUtf8());
|
||||||
q_dbus_message_set_auto_start( msg, d_ptr->autoStartService );
|
q_dbus_message_set_auto_start( msg, d_ptr->autoStartService );
|
||||||
|
q_dbus_message_set_allow_interactive_authorization(msg, d_ptr->interactiveAuthorizationAllowed);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case QDBusMessage::ReplyMessage:
|
case QDBusMessage::ReplyMessage:
|
||||||
msg = q_dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_RETURN);
|
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));
|
QString::fromUtf8(q_dbus_message_get_member(dmsg));
|
||||||
message.d_ptr->service = QString::fromUtf8(q_dbus_message_get_sender(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->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);
|
message.d_ptr->msg = q_dbus_message_ref(dmsg);
|
||||||
|
|
||||||
QDBusDemarshaller demarshaller(capabilities);
|
QDBusDemarshaller demarshaller(capabilities);
|
||||||
@ -724,6 +728,44 @@ bool QDBusMessage::autoStartService() const
|
|||||||
return d_ptr->autoStartService;
|
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
|
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.
|
will be the arguments to a method call or the parameters in the signal.
|
||||||
|
@ -119,6 +119,9 @@ public:
|
|||||||
void setAutoStartService(bool enable);
|
void setAutoStartService(bool enable);
|
||||||
bool autoStartService() const;
|
bool autoStartService() const;
|
||||||
|
|
||||||
|
void setInteractiveAuthorizationAllowed(bool enable);
|
||||||
|
bool isInteractiveAuthorizationAllowed() const;
|
||||||
|
|
||||||
void setArguments(const QList<QVariant> &arguments);
|
void setArguments(const QList<QVariant> &arguments);
|
||||||
QList<QVariant> arguments() const;
|
QList<QVariant> arguments() const;
|
||||||
|
|
||||||
|
@ -87,6 +87,7 @@ public:
|
|||||||
uint localMessage : 1;
|
uint localMessage : 1;
|
||||||
mutable uint parametersValidated : 1;
|
mutable uint parametersValidated : 1;
|
||||||
uint autoStartService : 1;
|
uint autoStartService : 1;
|
||||||
|
uint interactiveAuthorizationAllowed : 1;
|
||||||
|
|
||||||
static void setParametersValidated(QDBusMessage &msg, bool enable)
|
static void setParametersValidated(QDBusMessage &msg, bool enable)
|
||||||
{ msg.d_ptr->parametersValidated = enable; }
|
{ msg.d_ptr->parametersValidated = enable; }
|
||||||
|
@ -4,4 +4,11 @@ HEADERS += ../myobject.h
|
|||||||
TARGET = ../tst_qdbusinterface
|
TARGET = ../tst_qdbusinterface
|
||||||
DESTDIR = ./
|
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;
|
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()
|
void quit()
|
||||||
{
|
{
|
||||||
qApp->quit();
|
qApp->quit();
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
#include <QtTest/QtTest>
|
#include <QtTest/QtTest>
|
||||||
#include <QtCore/qvariant.h>
|
#include <QtCore/qvariant.h>
|
||||||
#include <QtDBus/QtDBus>
|
#include <QtDBus/QtDBus>
|
||||||
|
#include <QtDBus/private/qdbus_symbols_p.h>
|
||||||
#include <qdebug.h>
|
#include <qdebug.h>
|
||||||
#include "../qdbusmarshall/common.h"
|
#include "../qdbusmarshall/common.h"
|
||||||
#include "myobject.h"
|
#include "myobject.h"
|
||||||
@ -213,6 +214,8 @@ private slots:
|
|||||||
void propertyWritePeer();
|
void propertyWritePeer();
|
||||||
void complexPropertyReadPeer();
|
void complexPropertyReadPeer();
|
||||||
void complexPropertyWritePeer();
|
void complexPropertyWritePeer();
|
||||||
|
|
||||||
|
void interactiveAuthorizationRequired();
|
||||||
private:
|
private:
|
||||||
QProcess proc;
|
QProcess proc;
|
||||||
};
|
};
|
||||||
@ -1127,6 +1130,30 @@ void tst_QDBusInterface::complexPropertyWritePeer()
|
|||||||
QCOMPARE(complexPropPeer(), arg);
|
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)
|
QTEST_MAIN(tst_QDBusInterface)
|
||||||
|
|
||||||
#include "tst_qdbusinterface.moc"
|
#include "tst_qdbusinterface.moc"
|
||||||
|
Loading…
Reference in New Issue
Block a user