mirror of
https://gitlab.freedesktop.org/dbus/dbus.git
synced 2025-12-24 13:30:08 +01:00
D-Bus names are in an ASCII subset, so IDNs have to be in their ACE encoding (Punycode). ACE-encoded labels contain hyphen/minus characters, and like any other label containing a hyphen/minus, we recommend replacing those with underscores, to improve interoperability with contexts that allow underscores but not hyphen/minus, such as D-Bus object paths and Flatpak app-IDs. Prompted by <https://github.com/flatpak/flatpak/issues/4974>. Signed-off-by: Simon McVittie <smcv@collabora.com>
7596 lines
317 KiB
XML
7596 lines
317 KiB
XML
<?xml version="1.0" standalone="no" ?>
|
||
<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
|
||
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd"
|
||
[
|
||
]>
|
||
<article id="index">
|
||
<articleinfo>
|
||
<title>D-Bus Specification</title>
|
||
<releaseinfo>Version 0.39</releaseinfo>
|
||
<date>(not yet finalized)</date>
|
||
<authorgroup>
|
||
<author>
|
||
<firstname>Havoc</firstname>
|
||
<surname>Pennington</surname>
|
||
<affiliation>
|
||
<orgname>Red Hat, Inc.</orgname>
|
||
<address>
|
||
<email>hp@pobox.com</email>
|
||
</address>
|
||
</affiliation>
|
||
</author>
|
||
<author>
|
||
<firstname>Anders</firstname>
|
||
<surname>Carlsson</surname>
|
||
<affiliation>
|
||
<orgname>CodeFactory AB</orgname>
|
||
<address>
|
||
<email>andersca@codefactory.se</email>
|
||
</address>
|
||
</affiliation>
|
||
</author>
|
||
<author>
|
||
<firstname>Alexander</firstname>
|
||
<surname>Larsson</surname>
|
||
<affiliation>
|
||
<orgname>Red Hat, Inc.</orgname>
|
||
<address>
|
||
<email>alexl@redhat.com</email>
|
||
</address>
|
||
</affiliation>
|
||
</author>
|
||
<author>
|
||
<firstname>Sven</firstname>
|
||
<surname>Herzberg</surname>
|
||
<affiliation>
|
||
<orgname>Imendio AB</orgname>
|
||
<address>
|
||
<email>sven@imendio.com</email>
|
||
</address>
|
||
</affiliation>
|
||
</author>
|
||
<author>
|
||
<firstname>Simon</firstname>
|
||
<surname>McVittie</surname>
|
||
<affiliation>
|
||
<orgname>Collabora Ltd.</orgname>
|
||
<address>
|
||
<email>smcv@collabora.com</email>
|
||
</address>
|
||
</affiliation>
|
||
</author>
|
||
<author>
|
||
<firstname>David</firstname>
|
||
<surname>Zeuthen</surname>
|
||
<affiliation>
|
||
<address>
|
||
<email>zeuthen@gmail.com</email>
|
||
</address>
|
||
</affiliation>
|
||
</author>
|
||
</authorgroup>
|
||
<revhistory>
|
||
<revision>
|
||
<revnumber>latest</revnumber>
|
||
<date></date>
|
||
<authorinitials></authorinitials>
|
||
<revremark>
|
||
See <ulink url='http://cgit.freedesktop.org/dbus/dbus/log/doc/dbus-specification.xml'>commit log</ulink>
|
||
</revremark>
|
||
</revision>
|
||
<revision>
|
||
<revnumber>0.38</revnumber>
|
||
<date>2022-02-23</date>
|
||
<authorinitials></authorinitials>
|
||
<revdescription>
|
||
<itemizedlist>
|
||
<listitem><simpara>Add ActivatableServicesChanged signal and feature flag</simpara></listitem>
|
||
<listitem><simpara><literal>*</literal> is optionally-escaped in addresses</simpara></listitem>
|
||
</itemizedlist>
|
||
</revdescription>
|
||
</revision>
|
||
<revision>
|
||
<revnumber>0.37</revnumber>
|
||
<date>2021-12-17</date>
|
||
<authorinitials></authorinitials>
|
||
<revdescription>
|
||
<itemizedlist>
|
||
<listitem><simpara>Update recommendations for interoperable DBUS_COOKIE_SHA1 timeouts</simpara></listitem>
|
||
<listitem><simpara>Clarify padding requirements for arrays and variants</simpara></listitem>
|
||
<listitem><simpara>Describe where the interoperable machine ID comes from</simpara></listitem>
|
||
<listitem><simpara>Clarify use of dictionary (array of dict-entry) types</simpara></listitem>
|
||
</itemizedlist>
|
||
</revdescription>
|
||
</revision>
|
||
<revision>
|
||
<revnumber>0.36</revnumber>
|
||
<date>2020-04-21</date>
|
||
<authorinitials></authorinitials>
|
||
<revdescription>
|
||
<itemizedlist>
|
||
<listitem><simpara>Fix a typo in an annotated hexdump of part of a message</simpara></listitem>
|
||
</itemizedlist>
|
||
</revdescription>
|
||
</revision>
|
||
<revision>
|
||
<revnumber>0.35</revnumber>
|
||
<date>2019-05-13</date>
|
||
<authorinitials></authorinitials>
|
||
<revdescription>
|
||
<itemizedlist>
|
||
<listitem><simpara>Add UnixGroupIDs to GetConnectionCredentials</simpara></listitem>
|
||
<listitem><simpara>Avoid redundancy in defining interface name syntax</simpara></listitem>
|
||
</itemizedlist>
|
||
</revdescription>
|
||
</revision>
|
||
<revision>
|
||
<revnumber>0.34</revnumber>
|
||
<date>2018-12-04</date>
|
||
<authorinitials>pwithnall</authorinitials>
|
||
<revdescription>
|
||
<itemizedlist>
|
||
<listitem><simpara>Correct ObjectManager example AddMatch rule</simpara></listitem>
|
||
</itemizedlist>
|
||
</revdescription>
|
||
</revision>
|
||
<revision>
|
||
<revnumber>0.33</revnumber>
|
||
<date>2018-04-27</date>
|
||
<authorinitials>smcv</authorinitials>
|
||
<revdescription>
|
||
<itemizedlist>
|
||
<listitem><simpara>Deprecate TCP on Unix</simpara></listitem>
|
||
<listitem><simpara>Deprecate non-local TCP everywhere</simpara></listitem>
|
||
</itemizedlist>
|
||
</revdescription>
|
||
</revision>
|
||
<revision>
|
||
<revnumber>0.32</revnumber>
|
||
<date>2018-01-30</date>
|
||
<authorinitials>smcv</authorinitials>
|
||
<revdescription>
|
||
<itemizedlist>
|
||
<listitem><simpara>Deprecate hyphen/minus in bus names, with
|
||
underscore as the recommended replacement</simpara></listitem>
|
||
<listitem><simpara>Document the convention for escaping
|
||
leading digits in interface and bus names
|
||
(org._7_zip)</simpara></listitem>
|
||
<listitem><simpara>Recommend using SASL EXTERNAL where
|
||
possible, or DBUS_COOKIE_SHA1 otherwise</simpara></listitem>
|
||
<listitem><simpara>Message buses should not accept SASL
|
||
ANONYMOUS</simpara></listitem>
|
||
<listitem><simpara>Document the meaning of non-empty SASL
|
||
authorization identity strings</simpara></listitem>
|
||
<listitem><simpara>Document the optional argument to SASL
|
||
ERROR</simpara></listitem>
|
||
<listitem><simpara>Document who sends each SASL command, and
|
||
the possible replies</simpara></listitem>
|
||
<listitem><simpara>Document the authentication states used to
|
||
negotiate Unix fd-passing</simpara></listitem>
|
||
<listitem><simpara>Servers that relay messages should remove
|
||
header fields they do not understand</simpara></listitem>
|
||
<listitem><simpara>Clarify who controls each header
|
||
field</simpara></listitem>
|
||
<listitem><simpara>Document the HeaderFiltering message bus
|
||
feature flag</simpara></listitem>
|
||
<listitem><simpara>Non-message-bus servers may use the SENDER
|
||
and DESTINATION fields</simpara></listitem>
|
||
</itemizedlist>
|
||
</revdescription>
|
||
</revision>
|
||
<revision>
|
||
<revnumber>0.31</revnumber>
|
||
<date>2017-06-29</date>
|
||
<authorinitials>smcv, TG</authorinitials>
|
||
<revdescription>
|
||
<itemizedlist>
|
||
<listitem><simpara>Don't require implementation-specific search
|
||
paths to be lowest priority</simpara></listitem>
|
||
<listitem><simpara>Correct regex syntax for optionally-escaped
|
||
bytes in addresses so it includes hyphen-minus, forward slash
|
||
and underscore as intended</simpara></listitem>
|
||
<listitem><simpara>Describe all message bus methods in the same
|
||
section</simpara></listitem>
|
||
<listitem><simpara>Clarify the correct object path for method calls
|
||
to the message bus</simpara></listitem>
|
||
<listitem><simpara>Document that the message bus implements
|
||
Introspectable, Peer and Properties</simpara></listitem>
|
||
<listitem><simpara>Add new Features and Interfaces properties for
|
||
message bus feature-discovery</simpara></listitem>
|
||
<listitem><simpara>Add unix:dir=..., which resembles
|
||
unix:tmpdir=... but never uses abstract
|
||
sockets</simpara></listitem>
|
||
<listitem><simpara>Don't require eavesdrop='true' to be accepted
|
||
from connections not sufficiently privileged to use it
|
||
successfully</simpara></listitem>
|
||
<listitem><simpara>Formally deprecate eavesdropping in favour of
|
||
BecomeMonitor</simpara></listitem>
|
||
</itemizedlist>
|
||
</revdescription>
|
||
</revision>
|
||
<revision>
|
||
<revnumber>0.30</revnumber>
|
||
<date>2016-11-28</date>
|
||
<authorinitials>smcv, PW</authorinitials>
|
||
<revremark>
|
||
Define the jargon terms service activation and auto-starting more
|
||
clearly. Document the SystemdService key in service files.
|
||
Document how AppArmor interacts with service activation, and the
|
||
new AssumedAppArmorLabel key in service files (dbus-daemon 1.11.8).
|
||
Clarify intended behaviour of Properties.GetAll.
|
||
Use versioned interface and bus names in most examples.
|
||
</revremark>
|
||
</revision>
|
||
<revision>
|
||
<revnumber>0.29</revnumber>
|
||
<date>2016-10-10</date>
|
||
<authorinitials>PW</authorinitials>
|
||
<revremark>
|
||
Introspection arguments may contain annotations; recommend against
|
||
using the object path '/'
|
||
</revremark>
|
||
</revision>
|
||
<revision>
|
||
<revnumber>0.28</revnumber>
|
||
<date>2016-08-15</date>
|
||
<authorinitials>PW</authorinitials>
|
||
<revremark>Clarify serialization</revremark>
|
||
</revision>
|
||
<revision>
|
||
<revnumber>0.27</revnumber>
|
||
<date>2015-12-02</date>
|
||
<authorinitials>LU</authorinitials>
|
||
<revremark>Services should not send unwanted replies</revremark>
|
||
</revision>
|
||
<revision>
|
||
<revnumber>0.26</revnumber>
|
||
<date>2015-02-19</date>
|
||
<authorinitials>smcv, rh</authorinitials>
|
||
<revremark>
|
||
GetConnectionCredentials can return LinuxSecurityLabel or
|
||
WindowsSID; add privileged BecomeMonitor method
|
||
</revremark>
|
||
</revision>
|
||
<revision>
|
||
<revnumber>0.25</revnumber>
|
||
<date>2014-11-10</date>
|
||
<authorinitials>smcv, lennart</authorinitials>
|
||
<revremark>
|
||
ALLOW_INTERACTIVE_AUTHORIZATION flag, EmitsChangedSignal=const
|
||
</revremark>
|
||
</revision>
|
||
<revision>
|
||
<revnumber>0.24</revnumber>
|
||
<date>2014-10-01</date>
|
||
<authorinitials>SMcV</authorinitials>
|
||
<revremark>
|
||
non-method-calls never expect a reply even without NO_REPLY_EXPECTED;
|
||
document how to quote match rules
|
||
</revremark>
|
||
</revision>
|
||
<revision>
|
||
<revnumber>0.23</revnumber>
|
||
<date>2014-01-06</date>
|
||
<authorinitials>SMcV, CY</authorinitials>
|
||
<revremark>
|
||
method call messages with no INTERFACE may be considered an error;
|
||
document tcp:bind=... and nonce-tcp:bind=...; define listenable
|
||
and connectable addresses
|
||
</revremark>
|
||
</revision>
|
||
<revision>
|
||
<revnumber>0.22</revnumber>
|
||
<date>2013-10-09</date>
|
||
<authorinitials></authorinitials>
|
||
<revremark>add GetConnectionCredentials, document
|
||
GetAtdAuditSessionData, document GetConnectionSELinuxSecurityContext,
|
||
document and correct .service file syntax and naming
|
||
</revremark>
|
||
</revision>
|
||
<revision>
|
||
<revnumber>0.21</revnumber>
|
||
<date>2013-04-25</date>
|
||
<authorinitials>smcv</authorinitials>
|
||
<revremark>allow Unicode noncharacters in UTF-8 (Unicode
|
||
Corrigendum #9)</revremark>
|
||
</revision>
|
||
<revision>
|
||
<revnumber>0.20</revnumber>
|
||
<date>22 February 2013</date>
|
||
<authorinitials>smcv, walters</authorinitials>
|
||
<revremark>reorganise for clarity, remove false claims about
|
||
basic types, mention /o/fd/DBus</revremark>
|
||
</revision>
|
||
<revision>
|
||
<revnumber>0.19</revnumber>
|
||
<date>20 February 2012</date>
|
||
<authorinitials>smcv/lp</authorinitials>
|
||
<revremark>formally define unique connection names and well-known
|
||
bus names; document best practices for interface, bus, member and
|
||
error names, and object paths; document the search path for session
|
||
and system services on Unix; document the systemd transport</revremark>
|
||
</revision>
|
||
<revision>
|
||
<revnumber>0.18</revnumber>
|
||
<date>29 July 2011</date>
|
||
<authorinitials>smcv</authorinitials>
|
||
<revremark>define eavesdropping, unicast, broadcast; add eavesdrop
|
||
match keyword; promote type system to a top-level section</revremark>
|
||
</revision>
|
||
<revision>
|
||
<revnumber>0.17</revnumber>
|
||
<date>1 June 2011</date>
|
||
<authorinitials>smcv/davidz</authorinitials>
|
||
<revremark>define ObjectManager; reserve extra pseudo-type-codes used
|
||
by GVariant</revremark>
|
||
</revision>
|
||
<revision>
|
||
<revnumber>0.16</revnumber>
|
||
<date>11 April 2011</date>
|
||
<authorinitials></authorinitials>
|
||
<revremark>add path_namespace, arg0namespace; argNpath matches object
|
||
paths</revremark>
|
||
</revision>
|
||
<revision>
|
||
<revnumber>0.15</revnumber>
|
||
<date>3 November 2010</date>
|
||
<authorinitials></authorinitials>
|
||
<revremark></revremark>
|
||
</revision>
|
||
<revision>
|
||
<revnumber>0.14</revnumber>
|
||
<date>12 May 2010</date>
|
||
<authorinitials></authorinitials>
|
||
<revremark></revremark>
|
||
</revision>
|
||
<revision>
|
||
<revnumber>0.13</revnumber>
|
||
<date>23 Dezember 2009</date>
|
||
<authorinitials></authorinitials>
|
||
<revremark></revremark>
|
||
</revision>
|
||
<revision>
|
||
<revnumber>0.12</revnumber>
|
||
<date>7 November, 2006</date>
|
||
<authorinitials></authorinitials>
|
||
<revremark></revremark>
|
||
</revision>
|
||
<revision>
|
||
<revnumber>0.11</revnumber>
|
||
<date>6 February 2005</date>
|
||
<authorinitials></authorinitials>
|
||
<revremark></revremark>
|
||
</revision>
|
||
<revision>
|
||
<revnumber>0.10</revnumber>
|
||
<date>28 January 2005</date>
|
||
<authorinitials></authorinitials>
|
||
<revremark></revremark>
|
||
</revision>
|
||
<revision>
|
||
<revnumber>0.9</revnumber>
|
||
<date>7 Januar 2005</date>
|
||
<authorinitials></authorinitials>
|
||
<revremark></revremark>
|
||
</revision>
|
||
<revision>
|
||
<revnumber>0.8</revnumber>
|
||
<date>06 September 2003</date>
|
||
<authorinitials></authorinitials>
|
||
<revremark>First released document.</revremark>
|
||
</revision>
|
||
</revhistory>
|
||
</articleinfo>
|
||
|
||
<sect1 id="introduction">
|
||
<title>Introduction</title>
|
||
<para>
|
||
D-Bus is a system for low-overhead, easy to use
|
||
interprocess communication (IPC). In more detail:
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>
|
||
D-Bus is <emphasis>low-overhead</emphasis> because it uses a
|
||
binary protocol, and does not have to convert to and from a text
|
||
format such as XML. Because D-Bus is intended for potentially
|
||
high-resolution same-machine IPC, not primarily for Internet IPC,
|
||
this is an interesting optimization. D-Bus is also designed to
|
||
avoid round trips and allow asynchronous operation, much like
|
||
the X protocol.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>
|
||
D-Bus is <emphasis>easy to use</emphasis> because it works in terms
|
||
of <firstterm>messages</firstterm> rather than byte streams, and
|
||
automatically handles a lot of the hard IPC issues. Also, the D-Bus
|
||
library is designed to be wrapped in a way that lets developers use
|
||
their framework's existing object/type system, rather than learning
|
||
a new one specifically for IPC.
|
||
</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
</para>
|
||
|
||
<para>
|
||
The base D-Bus protocol is a one-to-one (peer-to-peer or client-server)
|
||
protocol, specified in <xref linkend="message-protocol"/>. That is, it is
|
||
a system for one application to talk to a single other
|
||
application. However, the primary intended application of the protocol is the
|
||
D-Bus <firstterm>message bus</firstterm>, specified in <xref
|
||
linkend="message-bus"/>. The message bus is a special application that
|
||
accepts connections from multiple other applications, and forwards
|
||
messages among them.
|
||
</para>
|
||
|
||
<para>
|
||
Uses of D-Bus include notification of system changes (notification of when
|
||
a camera is plugged in to a computer, or a new version of some software
|
||
has been installed), or desktop interoperability, for example a file
|
||
monitoring service or a configuration service.
|
||
</para>
|
||
|
||
<para>
|
||
D-Bus is designed for two specific use cases:
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>
|
||
A "system bus" for notifications from the system to user sessions,
|
||
and to allow the system to request input from user sessions.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>
|
||
A "session bus" used to implement desktop environments such as
|
||
GNOME and KDE.
|
||
</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
D-Bus is not intended to be a generic IPC system for any possible
|
||
application, and intentionally omits many features found in other
|
||
IPC systems for this reason.
|
||
</para>
|
||
|
||
<para>
|
||
At the same time, the bus daemons offer a number of features not found in
|
||
other IPC systems, such as single-owner "bus names" (similar to X
|
||
selections), on-demand startup of services, and security policies.
|
||
In many ways, these features are the primary motivation for developing
|
||
D-Bus; other systems would have sufficed if IPC were the only goal.
|
||
</para>
|
||
|
||
<para>
|
||
D-Bus may turn out to be useful in unanticipated applications, but future
|
||
versions of this spec and the reference implementation probably will not
|
||
incorporate features that interfere with the core use cases.
|
||
</para>
|
||
|
||
<para>
|
||
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
|
||
"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
|
||
document are to be interpreted as described in RFC 2119. However, the
|
||
document could use a serious audit to be sure it makes sense to do
|
||
so. Also, they are not capitalized.
|
||
</para>
|
||
|
||
<sect2 id="stability">
|
||
<title>Protocol and Specification Stability</title>
|
||
<para>
|
||
The D-Bus protocol is frozen (only compatible extensions are allowed) as
|
||
of November 8, 2006. However, this specification could still use a fair
|
||
bit of work to make interoperable reimplementation possible without
|
||
reference to the D-Bus reference implementation. Thus, this
|
||
specification is not marked 1.0. To mark it 1.0, we'd like to see
|
||
someone invest significant effort in clarifying the specification
|
||
language, and growing the specification to cover more aspects of the
|
||
reference implementation's behavior.
|
||
</para>
|
||
<para>
|
||
Until this work is complete, any attempt to reimplement D-Bus will
|
||
probably require looking at the reference implementation and/or asking
|
||
questions on the D-Bus mailing list about intended behavior.
|
||
Questions on the list are very welcome.
|
||
</para>
|
||
<para>
|
||
Nonetheless, this document should be a useful starting point and is
|
||
to our knowledge accurate, though incomplete.
|
||
</para>
|
||
</sect2>
|
||
|
||
</sect1>
|
||
|
||
<sect1 id="type-system">
|
||
<title>Type System</title>
|
||
|
||
<para>
|
||
D-Bus has a type system, in which values of various types can be
|
||
serialized into a sequence of bytes referred to as the
|
||
<firstterm>wire format</firstterm> in a standard way.
|
||
Converting a value from some other representation into the wire
|
||
format is called <firstterm>marshaling</firstterm> and converting
|
||
it back from the wire format is <firstterm>unmarshaling</firstterm>.
|
||
</para>
|
||
|
||
<para>
|
||
The D-Bus protocol does not include type tags in the marshaled data; a
|
||
block of marshaled values must have a known <firstterm>type
|
||
signature</firstterm>. The type signature is made up of zero or more
|
||
<firstterm id="term-single-complete-type">single complete
|
||
types</firstterm>, each made up of one or more
|
||
<firstterm>type codes</firstterm>.
|
||
</para>
|
||
|
||
<para>
|
||
A type code is an ASCII character representing the
|
||
type of a value. Because ASCII characters are used, the type signature
|
||
will always form a valid ASCII string. A simple string compare
|
||
determines whether two type signatures are equivalent.
|
||
</para>
|
||
|
||
<para>
|
||
A single complete type is a sequence of type codes that fully describes
|
||
one type: either a basic type, or a single fully-described container type.
|
||
A single complete type is a basic type code, a variant type code,
|
||
an array with its element type, or a struct with its fields (all of which
|
||
are defined below). So the following signatures are not single complete
|
||
types:
|
||
<programlisting>
|
||
"aa"
|
||
</programlisting>
|
||
<programlisting>
|
||
"(ii"
|
||
</programlisting>
|
||
<programlisting>
|
||
"ii)"
|
||
</programlisting>
|
||
And the following signatures contain multiple complete types:
|
||
<programlisting>
|
||
"ii"
|
||
</programlisting>
|
||
<programlisting>
|
||
"aiai"
|
||
</programlisting>
|
||
<programlisting>
|
||
"(ii)(ii)"
|
||
</programlisting>
|
||
Note however that a single complete type may <emphasis>contain</emphasis>
|
||
multiple other single complete types, by containing a struct or dict
|
||
entry.
|
||
</para>
|
||
|
||
<sect2 id="basic-types">
|
||
<title>Basic types</title>
|
||
|
||
<para>
|
||
The simplest type codes are the <firstterm id="term-basic-type">basic
|
||
types</firstterm>, which are the types whose structure is entirely
|
||
defined by their 1-character type code. Basic types consist of
|
||
fixed types and string-like types.
|
||
</para>
|
||
|
||
<para>
|
||
The <firstterm id="term-fixed-type">fixed types</firstterm>
|
||
are basic types whose values have a fixed length, namely BYTE,
|
||
BOOLEAN, DOUBLE, UNIX_FD, and signed or unsigned integers of length
|
||
16, 32 or 64 bits.
|
||
</para>
|
||
|
||
<para>
|
||
As a simple example, the type code for 32-bit integer (<literal>INT32</literal>) is
|
||
the ASCII character 'i'. So the signature for a block of values
|
||
containing a single <literal>INT32</literal> would be:
|
||
<programlisting>
|
||
"i"
|
||
</programlisting>
|
||
A block of values containing two <literal>INT32</literal> would have this signature:
|
||
<programlisting>
|
||
"ii"
|
||
</programlisting>
|
||
</para>
|
||
|
||
<para>
|
||
The characteristics of the fixed types are listed in this table.
|
||
|
||
<informaltable>
|
||
<tgroup cols="3">
|
||
<thead>
|
||
<row>
|
||
<entry>Conventional name</entry>
|
||
<entry>ASCII type-code</entry>
|
||
<entry>Encoding</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row>
|
||
<entry><literal>BYTE</literal></entry>
|
||
<entry><literal>y</literal> (121)</entry>
|
||
<entry>Unsigned 8-bit integer</entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>BOOLEAN</literal></entry>
|
||
<entry><literal>b</literal> (98)</entry>
|
||
<entry>Boolean value: 0 is false, 1 is true, any other value
|
||
allowed by the marshalling format is invalid</entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>INT16</literal></entry>
|
||
<entry><literal>n</literal> (110)</entry>
|
||
<entry>Signed (two's complement) 16-bit integer</entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>UINT16</literal></entry>
|
||
<entry><literal>q</literal> (113)</entry>
|
||
<entry>Unsigned 16-bit integer</entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>INT32</literal></entry>
|
||
<entry><literal>i</literal> (105)</entry>
|
||
<entry>Signed (two's complement) 32-bit integer</entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>UINT32</literal></entry>
|
||
<entry><literal>u</literal> (117)</entry>
|
||
<entry>Unsigned 32-bit integer</entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>INT64</literal></entry>
|
||
<entry><literal>x</literal> (120)</entry>
|
||
<entry>Signed (two's complement) 64-bit integer
|
||
(mnemonic: x and t are the first characters in "sixty" not
|
||
already used for something more common)</entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>UINT64</literal></entry>
|
||
<entry><literal>t</literal> (116)</entry>
|
||
<entry>Unsigned 64-bit integer</entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>DOUBLE</literal></entry>
|
||
<entry><literal>d</literal> (100)</entry>
|
||
<entry>IEEE 754 double-precision floating point</entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>UNIX_FD</literal></entry>
|
||
<entry><literal>h</literal> (104)</entry>
|
||
<entry>Unsigned 32-bit integer representing an index into an
|
||
out-of-band array of file descriptors, transferred via some
|
||
platform-specific mechanism (mnemonic: h for handle)</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
</para>
|
||
|
||
<para>
|
||
The <firstterm id="term-string-like-type">string-like types</firstterm>
|
||
are basic types with a variable length. The value of any string-like
|
||
type is conceptually 0 or more Unicode codepoints encoded in UTF-8,
|
||
none of which may be U+0000. The UTF-8 text must be validated
|
||
strictly: in particular, it must not contain overlong sequences
|
||
or codepoints above U+10FFFF.
|
||
</para>
|
||
|
||
<para>
|
||
Since D-Bus Specification version 0.21, in accordance with Unicode
|
||
Corrigendum #9, the "noncharacters" U+FDD0..U+FDEF, U+nFFFE and
|
||
U+nFFFF are allowed in UTF-8 strings (but note that older versions of
|
||
D-Bus rejected these noncharacters).
|
||
</para>
|
||
|
||
<para>
|
||
The marshalling formats for the string-like types all end with a
|
||
single zero (NUL) byte, but that byte is not considered to be part of
|
||
the text.
|
||
</para>
|
||
|
||
<para>
|
||
The characteristics of the string-like types are listed in this table.
|
||
|
||
<informaltable>
|
||
<tgroup cols="3">
|
||
<thead>
|
||
<row>
|
||
<entry>Conventional name</entry>
|
||
<entry>ASCII type-code</entry>
|
||
<entry>Validity constraints</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row>
|
||
<entry><literal>STRING</literal></entry>
|
||
<entry><literal>s</literal> (115)</entry>
|
||
<entry>No extra constraints</entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>OBJECT_PATH</literal></entry>
|
||
<entry><literal>o</literal> (111)</entry>
|
||
<entry>Must be
|
||
<link linkend="message-protocol-marshaling-object-path">a
|
||
syntactically valid object path</link></entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>SIGNATURE</literal></entry>
|
||
<entry><literal>g</literal> (103)</entry>
|
||
<entry>Zero or more
|
||
<firstterm linkend="term-single-complete-type">single
|
||
complete types</firstterm></entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
</para>
|
||
|
||
<sect3 id="message-protocol-marshaling-object-path">
|
||
<title>Valid Object Paths</title>
|
||
|
||
<para>
|
||
An object path is a name used to refer to an object instance.
|
||
Conceptually, each participant in a D-Bus message exchange may have
|
||
any number of object instances (think of C++ or Java objects) and each
|
||
such instance will have a path. Like a filesystem, the object
|
||
instances in an application form a hierarchical tree.
|
||
</para>
|
||
|
||
<para>
|
||
Object paths are often namespaced by starting with a reversed
|
||
domain name and containing an interface version number, in the
|
||
same way as
|
||
<link linkend="message-protocol-names-interface">interface
|
||
names</link> and
|
||
<link linkend="message-protocol-names-bus">well-known
|
||
bus names</link>.
|
||
This makes it possible to implement more than one service, or
|
||
more than one version of a service, in the same process,
|
||
even if the services share a connection but cannot otherwise
|
||
co-operate (for instance, if they are implemented by different
|
||
plugins).
|
||
</para>
|
||
|
||
<para>
|
||
Using an object path of <literal>/</literal> is allowed, but
|
||
recommended against, as it makes versioning of interfaces hard. Any
|
||
signals emitted from a D-Bus object have the service’s unique bus name
|
||
associated with them, rather than its well-known name. This means that
|
||
receipients of the signals must rely entirely on the signal name and
|
||
object path to work out which interface the signal originated from.
|
||
</para>
|
||
|
||
<para>
|
||
For instance, if the owner of <literal>example.com</literal> is
|
||
developing a D-Bus API for a music player, they might use the
|
||
hierarchy of object paths that start with
|
||
<literal>/com/example/MusicPlayer1</literal> for its objects.
|
||
</para>
|
||
|
||
<para>
|
||
The following rules define a valid object path. Implementations must
|
||
not send or accept messages with invalid object paths.
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>
|
||
The path may be of any length.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>
|
||
The path must begin with an ASCII '/' (integer 47) character,
|
||
and must consist of elements separated by slash characters.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>
|
||
Each element must only contain the ASCII characters
|
||
"[A-Z][a-z][0-9]_"
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>
|
||
No element may be the empty string.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>
|
||
Multiple '/' characters cannot occur in sequence.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>
|
||
A trailing '/' character is not allowed unless the
|
||
path is the root path (a single '/' character).
|
||
</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
</para>
|
||
|
||
</sect3>
|
||
|
||
<sect3 id="message-protocol-marshaling-signature">
|
||
<title>Valid Signatures</title>
|
||
<para>
|
||
An implementation must not send or accept invalid signatures.
|
||
Valid signatures will conform to the following rules:
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>
|
||
The signature is a list of single complete types.
|
||
Arrays must have element types, and structs must
|
||
have both open and close parentheses.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>
|
||
Only type codes, open and close parentheses, and open and
|
||
close curly brackets are allowed in the signature. The
|
||
<literal>STRUCT</literal> type code
|
||
is not allowed in signatures, because parentheses
|
||
are used instead. Similarly, the
|
||
<literal>DICT_ENTRY</literal> type code is not allowed in
|
||
signatures, because curly brackets are used instead.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>
|
||
The maximum depth of container type nesting is 32 array type
|
||
codes and 32 open parentheses. This implies that the maximum
|
||
total depth of recursion is 64, for an "array of array of array
|
||
of ... struct of struct of struct of ..." where there are 32
|
||
array and 32 struct.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>
|
||
The maximum length of a signature is 255.
|
||
</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
</para>
|
||
|
||
<para>
|
||
When signatures appear in messages, the marshalling format
|
||
guarantees that they will be followed by a nul byte (which can
|
||
be interpreted as either C-style string termination or the INVALID
|
||
type-code), but this is not conceptually part of the signature.
|
||
</para>
|
||
</sect3>
|
||
|
||
</sect2>
|
||
|
||
<sect2 id="container-types">
|
||
<title>Container types</title>
|
||
|
||
<para>
|
||
In addition to basic types, there are four <firstterm>container</firstterm>
|
||
types: <literal>STRUCT</literal>, <literal>ARRAY</literal>, <literal>VARIANT</literal>,
|
||
and <literal>DICT_ENTRY</literal>.
|
||
</para>
|
||
|
||
<para>
|
||
<literal>STRUCT</literal> has a type code, ASCII character 'r', but this type
|
||
code does not appear in signatures. Instead, ASCII characters
|
||
'(' and ')' are used to mark the beginning and end of the struct.
|
||
So for example, a struct containing two integers would have this
|
||
signature:
|
||
<programlisting>
|
||
"(ii)"
|
||
</programlisting>
|
||
Structs can be nested, so for example a struct containing
|
||
an integer and another struct:
|
||
<programlisting>
|
||
"(i(ii))"
|
||
</programlisting>
|
||
The value block storing that struct would contain three integers; the
|
||
type signature allows you to distinguish "(i(ii))" from "((ii)i)" or
|
||
"(iii)" or "iii".
|
||
</para>
|
||
|
||
<para>
|
||
The <literal>STRUCT</literal> type code 'r' is not currently used in the D-Bus protocol,
|
||
but is useful in code that implements the protocol. This type code
|
||
is specified to allow such code to interoperate in non-protocol contexts.
|
||
</para>
|
||
|
||
<para>
|
||
Empty structures are not allowed; there must be at least one
|
||
type code between the parentheses.
|
||
</para>
|
||
|
||
<para>
|
||
<literal>ARRAY</literal> has ASCII character 'a' as type code. The array type code must be
|
||
followed by a <firstterm>single complete type</firstterm>. The single
|
||
complete type following the array is the type of each array element. So
|
||
the simple example is:
|
||
<programlisting>
|
||
"ai"
|
||
</programlisting>
|
||
which is an array of 32-bit integers. But an array can be of any type,
|
||
such as this array-of-struct-with-two-int32-fields:
|
||
<programlisting>
|
||
"a(ii)"
|
||
</programlisting>
|
||
Or this array of array of integer:
|
||
<programlisting>
|
||
"aai"
|
||
</programlisting>
|
||
</para>
|
||
|
||
<para>
|
||
<literal>VARIANT</literal> has ASCII character 'v' as its type code. A marshaled value of
|
||
type <literal>VARIANT</literal> will have the signature of a single complete type as part
|
||
of the <emphasis>value</emphasis>. This signature will be followed by a
|
||
marshaled value of that type.
|
||
</para>
|
||
|
||
<para>
|
||
Unlike a message signature, the variant signature can
|
||
contain only a single complete type. So "i", "ai"
|
||
or "(ii)" is OK, but "ii" is not. Use of variants may not
|
||
cause a total message depth to be larger than 64, including
|
||
other container types such as structures.
|
||
</para>
|
||
|
||
<para>
|
||
A <literal>DICT_ENTRY</literal> works exactly like a struct, but rather
|
||
than parentheses it uses curly braces, and it has more restrictions.
|
||
The restrictions are: it occurs only as an array element type; it has
|
||
exactly two single complete types inside the curly braces; the first
|
||
single complete type (the "key") must be a basic type rather than a
|
||
container type. Implementations must not accept dict entries outside of
|
||
arrays, must not accept dict entries with zero, one, or more than two
|
||
fields, and must not accept dict entries with non-basic-typed keys. A
|
||
dict entry is always a key-value pair.
|
||
</para>
|
||
|
||
<para>
|
||
The first field in the <literal>DICT_ENTRY</literal> is always the key.
|
||
A message is considered corrupt if the same key occurs twice in the same
|
||
array of <literal>DICT_ENTRY</literal>. However, for performance reasons
|
||
implementations are not required to reject dicts with duplicate keys.
|
||
</para>
|
||
|
||
<para>
|
||
In most languages, an array of dict entry would be represented as a
|
||
map, hash table, or dict object.
|
||
</para>
|
||
</sect2>
|
||
|
||
<sect2>
|
||
<title>Summary of types</title>
|
||
|
||
<para>
|
||
The following table summarizes the D-Bus types.
|
||
<informaltable>
|
||
<tgroup cols="3">
|
||
<thead>
|
||
<row>
|
||
<entry>Category</entry>
|
||
<entry>Conventional Name</entry>
|
||
<entry>Code</entry>
|
||
<entry>Description</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row>
|
||
<entry>reserved</entry>
|
||
<entry><literal>INVALID</literal></entry>
|
||
<entry>0 (ASCII NUL)</entry>
|
||
<entry>Not a valid type code, used to terminate signatures</entry>
|
||
</row><row>
|
||
<entry>fixed, basic</entry>
|
||
<entry><literal>BYTE</literal></entry>
|
||
<entry>121 (ASCII 'y')</entry>
|
||
<entry>8-bit unsigned integer</entry>
|
||
</row><row>
|
||
<entry>fixed, basic</entry>
|
||
<entry><literal>BOOLEAN</literal></entry>
|
||
<entry>98 (ASCII 'b')</entry>
|
||
<entry>Boolean value, 0 is <literal>FALSE</literal> and 1 is <literal>TRUE</literal>. Everything else is invalid.</entry>
|
||
</row><row>
|
||
<entry>fixed, basic</entry>
|
||
<entry><literal>INT16</literal></entry>
|
||
<entry>110 (ASCII 'n')</entry>
|
||
<entry>16-bit signed integer</entry>
|
||
</row><row>
|
||
<entry>fixed, basic</entry>
|
||
<entry><literal>UINT16</literal></entry>
|
||
<entry>113 (ASCII 'q')</entry>
|
||
<entry>16-bit unsigned integer</entry>
|
||
</row><row>
|
||
<entry>fixed, basic</entry>
|
||
<entry><literal>INT32</literal></entry>
|
||
<entry>105 (ASCII 'i')</entry>
|
||
<entry>32-bit signed integer</entry>
|
||
</row><row>
|
||
<entry>fixed, basic</entry>
|
||
<entry><literal>UINT32</literal></entry>
|
||
<entry>117 (ASCII 'u')</entry>
|
||
<entry>32-bit unsigned integer</entry>
|
||
</row><row>
|
||
<entry>fixed, basic</entry>
|
||
<entry><literal>INT64</literal></entry>
|
||
<entry>120 (ASCII 'x')</entry>
|
||
<entry>64-bit signed integer</entry>
|
||
</row><row>
|
||
<entry>fixed, basic</entry>
|
||
<entry><literal>UINT64</literal></entry>
|
||
<entry>116 (ASCII 't')</entry>
|
||
<entry>64-bit unsigned integer</entry>
|
||
</row><row>
|
||
<entry>fixed, basic</entry>
|
||
<entry><literal>DOUBLE</literal></entry>
|
||
<entry>100 (ASCII 'd')</entry>
|
||
<entry>IEEE 754 double</entry>
|
||
</row><row>
|
||
<entry>string-like, basic</entry>
|
||
<entry><literal>STRING</literal></entry>
|
||
<entry>115 (ASCII 's')</entry>
|
||
<entry>UTF-8 string (<emphasis>must</emphasis> be valid UTF-8). Must be nul terminated and contain no other nul bytes.</entry>
|
||
</row><row>
|
||
<entry>string-like, basic</entry>
|
||
<entry><literal>OBJECT_PATH</literal></entry>
|
||
<entry>111 (ASCII 'o')</entry>
|
||
<entry>Name of an object instance</entry>
|
||
</row><row>
|
||
<entry>string-like, basic</entry>
|
||
<entry><literal>SIGNATURE</literal></entry>
|
||
<entry>103 (ASCII 'g')</entry>
|
||
<entry>A type signature</entry>
|
||
</row><row>
|
||
<entry>container</entry>
|
||
<entry><literal>ARRAY</literal></entry>
|
||
<entry>97 (ASCII 'a')</entry>
|
||
<entry>Array</entry>
|
||
</row><row>
|
||
<entry>container</entry>
|
||
<entry><literal>STRUCT</literal></entry>
|
||
<entry>114 (ASCII 'r'), 40 (ASCII '('), 41 (ASCII ')')</entry>
|
||
<entry>Struct; type code 114 'r' is reserved for use in
|
||
bindings and implementations to represent the general
|
||
concept of a struct, and must not appear in signatures
|
||
used on D-Bus.</entry>
|
||
</row><row>
|
||
<entry>container</entry>
|
||
<entry><literal>VARIANT</literal></entry>
|
||
<entry>118 (ASCII 'v') </entry>
|
||
<entry>Variant type (the type of the value is part of the value itself)</entry>
|
||
</row><row>
|
||
<entry>container</entry>
|
||
<entry><literal>DICT_ENTRY</literal></entry>
|
||
<entry>101 (ASCII 'e'), 123 (ASCII '{'), 125 (ASCII '}') </entry>
|
||
<entry>Entry in a dict or map (array of key-value pairs).
|
||
Type code 101 'e' is reserved for use in bindings and
|
||
implementations to represent the general concept of a
|
||
dict or dict-entry, and must not appear in signatures
|
||
used on D-Bus.</entry>
|
||
</row><row>
|
||
<entry>fixed, basic</entry>
|
||
<entry><literal>UNIX_FD</literal></entry>
|
||
<entry>104 (ASCII 'h')</entry>
|
||
<entry>Unix file descriptor</entry>
|
||
</row>
|
||
<row>
|
||
<entry>reserved</entry>
|
||
<entry>(reserved)</entry>
|
||
<entry>109 (ASCII 'm')</entry>
|
||
<entry>Reserved for <ulink
|
||
url="https://bugs.freedesktop.org/show_bug.cgi?id=27857">a
|
||
'maybe' type compatible with the one in GVariant</ulink>,
|
||
and must not appear in signatures used on D-Bus until
|
||
specified here</entry>
|
||
</row>
|
||
<row>
|
||
<entry>reserved</entry>
|
||
<entry>(reserved)</entry>
|
||
<entry>42 (ASCII '*')</entry>
|
||
<entry>Reserved for use in bindings/implementations to
|
||
represent any <firstterm>single complete type</firstterm>,
|
||
and must not appear in signatures used on D-Bus.</entry>
|
||
</row>
|
||
<row>
|
||
<entry>reserved</entry>
|
||
<entry>(reserved)</entry>
|
||
<entry>63 (ASCII '?')</entry>
|
||
<entry>Reserved for use in bindings/implementations to
|
||
represent any <firstterm>basic type</firstterm>, and must
|
||
not appear in signatures used on D-Bus.</entry>
|
||
</row>
|
||
<row>
|
||
<entry>reserved</entry>
|
||
<entry>(reserved)</entry>
|
||
<entry>64 (ASCII '@'), 38 (ASCII '&'),
|
||
94 (ASCII '^')</entry>
|
||
<entry>Reserved for internal use by bindings/implementations,
|
||
and must not appear in signatures used on D-Bus.
|
||
GVariant uses these type-codes to encode calling
|
||
conventions.</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
</para>
|
||
|
||
</sect2>
|
||
</sect1>
|
||
|
||
<sect1 id="message-protocol-marshaling">
|
||
<title>Marshaling (Wire Format)</title>
|
||
|
||
<para>
|
||
D-Bus defines a marshalling format for its type system, which is
|
||
used in D-Bus messages. This is not the only possible marshalling
|
||
format for the type system: for instance, GVariant (part of GLib)
|
||
re-uses the D-Bus type system but implements an alternative marshalling
|
||
format.
|
||
</para>
|
||
|
||
<sect2>
|
||
<title>Byte order and alignment</title>
|
||
|
||
<para>
|
||
Given a type signature, a block of bytes can be converted into typed
|
||
values. This section describes the format of the block of bytes. Byte
|
||
order and alignment issues are handled uniformly for all D-Bus types.
|
||
</para>
|
||
|
||
<para>
|
||
A block of bytes has an associated byte order. The byte order
|
||
has to be discovered in some way; for D-Bus messages, the
|
||
byte order is part of the message header as described in
|
||
<xref linkend="message-protocol-messages"/>. For now, assume
|
||
that the byte order is known to be either little endian or big
|
||
endian.
|
||
</para>
|
||
|
||
<para>
|
||
Each value in a block of bytes is aligned "naturally," for example
|
||
4-byte values are aligned to a 4-byte boundary, and 8-byte values to an
|
||
8-byte boundary. Boundaries are calculated globally, with respect to
|
||
the first byte in the message. To properly align a value,
|
||
<firstterm>alignment padding</firstterm> may be necessary before the
|
||
value. The alignment padding must always
|
||
be the minimum required padding to properly align the following value;
|
||
and it must always be made up of nul bytes. The alignment padding must
|
||
not be left uninitialized (it can't contain garbage), and more padding
|
||
than required must not be used.
|
||
</para>
|
||
|
||
<para>
|
||
As an exception to natural alignment, <literal>STRUCT</literal> and
|
||
<literal>DICT_ENTRY</literal> values are always aligned to an 8-byte
|
||
boundary, regardless of the alignments of their contents.
|
||
</para>
|
||
</sect2>
|
||
|
||
<sect2>
|
||
<title>Marshalling basic types</title>
|
||
|
||
<para>
|
||
To marshal and unmarshal fixed types, you simply read one value
|
||
from the data block corresponding to each type code in the signature.
|
||
All signed integer values are encoded in two's complement, DOUBLE
|
||
values are IEEE 754 double-precision floating-point, and BOOLEAN
|
||
values are encoded in 32 bits (of which only the least significant
|
||
bit is used).
|
||
</para>
|
||
|
||
<para>
|
||
The string-like types (STRING, OBJECT_PATH and SIGNATURE) are all
|
||
marshalled as a
|
||
fixed-length unsigned integer <varname>n</varname> giving the
|
||
length of the variable part, followed by <varname>n</varname>
|
||
nonzero bytes of UTF-8 text, followed by a single zero (nul) byte
|
||
which is not considered to be part of the text. The alignment
|
||
of the string-like type is the same as the alignment of
|
||
<varname>n</varname>: any padding required for <varname>n</varname>
|
||
appears immediately before <varname>n</varname> itself. There is never
|
||
any alignment padding between <varname>n</varname> and the string text,
|
||
or between the string text and the trailing nul. The alignment padding
|
||
for the next value in the message (if there is one) starts after the
|
||
trailing nul.
|
||
</para>
|
||
|
||
<para>
|
||
For the STRING and OBJECT_PATH types, <varname>n</varname> is
|
||
encoded in 4 bytes (a <literal>UINT32</literal>), leading to 4-byte
|
||
alignment. For the SIGNATURE type, <varname>n</varname> is encoded as a
|
||
single byte (a <literal>UINT8</literal>). As a result, alignment
|
||
padding is never required before a SIGNATURE.
|
||
</para>
|
||
|
||
<para>
|
||
For example, if the current position is a multiple of 8 bytes from the
|
||
beginning of a little-endian message, strings ‘foo’, ‘+’ and ‘bar’
|
||
would be serialized in sequence as follows:
|
||
|
||
<screen>
|
||
<lineannotation>no padding required, we are already at a multiple of 4</lineannotation>
|
||
0x03 0x00 0x00 0x00 <lineannotation>length of ‘foo’ = 3</lineannotation>
|
||
0x66 0x6f 0x6f <lineannotation>‘foo’</lineannotation>
|
||
0x00 <lineannotation>trailing nul</lineannotation>
|
||
|
||
<lineannotation>no padding required, we are already at a multiple of 4</lineannotation>
|
||
0x01 0x00 0x00 0x00 <lineannotation>length of ‘+’ = 1</lineannotation>
|
||
0x2b <lineannotation>‘+’</lineannotation>
|
||
0x00 <lineannotation>trailing nul</lineannotation>
|
||
|
||
0x00 0x00 <lineannotation>2 bytes of padding to reach next multiple of 4</lineannotation>
|
||
0x03 0x00 0x00 0x00 <lineannotation>length of ‘bar’ = 3</lineannotation>
|
||
0x62 0x61 0x72 <lineannotation>‘bar’</lineannotation>
|
||
0x00 <lineannotation>trailing nul</lineannotation>
|
||
</screen>
|
||
</para>
|
||
</sect2>
|
||
|
||
<sect2>
|
||
<title>Marshalling containers</title>
|
||
|
||
<para>
|
||
Arrays are marshalled as a <literal>UINT32</literal>
|
||
<varname>n</varname> giving the length of the array data in bytes,
|
||
followed by alignment padding to the alignment boundary of the array
|
||
element type, followed by the <varname>n</varname> bytes of the
|
||
array elements marshalled in sequence. <varname>n</varname> does not
|
||
include the padding after the length, or any padding after the
|
||
last element. i.e. <varname>n</varname> should be divisible by the
|
||
number of elements in the array. Note that the alignment padding for the
|
||
first element is required even if there is no first element (an
|
||
empty array, where <varname>n</varname> is zero).
|
||
</para>
|
||
|
||
<para>
|
||
For instance, if the current position in the message is a multiple
|
||
of 8 bytes and the byte-order is big-endian, an array containing only
|
||
the 64-bit integer 5 would be marshalled as:
|
||
|
||
<screen>
|
||
00 00 00 08 <lineannotation><varname>n</varname> = 8 bytes of data</lineannotation>
|
||
00 00 00 00 <lineannotation>padding to 8-byte boundary</lineannotation>
|
||
00 00 00 00 00 00 00 05 <lineannotation>first element = 5</lineannotation>
|
||
</screen>
|
||
</para>
|
||
|
||
<para>
|
||
Arrays have a maximum length defined to be 2 to the 26th power or
|
||
67108864 (64 MiB). Implementations must not send or accept arrays
|
||
exceeding this length.
|
||
</para>
|
||
|
||
<para>
|
||
Structs and dict entries are marshalled in the same way as their
|
||
contents, but their alignment is always to an 8-byte boundary,
|
||
even if their contents would normally be less strictly aligned.
|
||
</para>
|
||
|
||
<para>
|
||
Variants are marshalled as the <literal>SIGNATURE</literal> of
|
||
the contents (which must be a single complete type), followed by a
|
||
marshalled value with the type given by that signature. The
|
||
variant has the same 1-byte alignment as the signature, which means
|
||
that alignment padding before a variant is never needed.
|
||
Use of variants must not cause a total message depth to be larger
|
||
than 64, including other container types such as structures.
|
||
(See <link linkend="message-protocol-marshaling-signature">Valid
|
||
Signatures</link>.)
|
||
</para>
|
||
|
||
<para>
|
||
It should be noted that while a variant itself does not require any
|
||
alignment padding, the contained value does need to be padded
|
||
according to the alignment rules of its type.
|
||
</para>
|
||
|
||
<para>
|
||
For instance, if the current position in the message is at a multiple of
|
||
8 bytes and the byte-order is big-endian, a variant containing a 64-bit
|
||
integer 5 would be marshalled as:
|
||
|
||
<screen>
|
||
0x01 0x74 0x00 <lineannotation>signature bytes (length = 1, signature = 't' and trailing nul)</lineannotation>
|
||
0x00 0x00 0x00 0x00 0x00 <lineannotation>padding to 8-byte boundary</lineannotation>
|
||
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x05 <lineannotation>8 bytes of contained value</lineannotation>
|
||
</screen>
|
||
</para>
|
||
</sect2>
|
||
|
||
<sect2>
|
||
<title>Summary of D-Bus marshalling</title>
|
||
|
||
<para>
|
||
Given all this, the types are marshaled on the wire as follows:
|
||
<informaltable>
|
||
<tgroup cols="3">
|
||
<thead>
|
||
<row>
|
||
<entry>Conventional Name</entry>
|
||
<entry>Encoding</entry>
|
||
<entry>Alignment</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row>
|
||
<entry><literal>INVALID</literal></entry>
|
||
<entry>Not applicable; cannot be marshaled.</entry>
|
||
<entry>N/A</entry>
|
||
</row><row>
|
||
<entry><literal>BYTE</literal></entry>
|
||
<entry>A single 8-bit byte.</entry>
|
||
<entry>1</entry>
|
||
</row><row>
|
||
<entry><literal>BOOLEAN</literal></entry>
|
||
<entry>As for <literal>UINT32</literal>, but only 0 and 1 are valid values.</entry>
|
||
<entry>4</entry>
|
||
</row><row>
|
||
<entry><literal>INT16</literal></entry>
|
||
<entry>16-bit signed integer in the message's byte order.</entry>
|
||
<entry>2</entry>
|
||
</row><row>
|
||
<entry><literal>UINT16</literal></entry>
|
||
<entry>16-bit unsigned integer in the message's byte order.</entry>
|
||
<entry>2</entry>
|
||
</row><row>
|
||
<entry><literal>INT32</literal></entry>
|
||
<entry>32-bit signed integer in the message's byte order.</entry>
|
||
<entry>4</entry>
|
||
</row><row>
|
||
<entry><literal>UINT32</literal></entry>
|
||
<entry>32-bit unsigned integer in the message's byte order.</entry>
|
||
<entry>4</entry>
|
||
</row><row>
|
||
<entry><literal>INT64</literal></entry>
|
||
<entry>64-bit signed integer in the message's byte order.</entry>
|
||
<entry>8</entry>
|
||
</row><row>
|
||
<entry><literal>UINT64</literal></entry>
|
||
<entry>64-bit unsigned integer in the message's byte order.</entry>
|
||
<entry>8</entry>
|
||
</row><row>
|
||
<entry><literal>DOUBLE</literal></entry>
|
||
<entry>64-bit IEEE 754 double in the message's byte order.</entry>
|
||
<entry>8</entry>
|
||
</row><row>
|
||
<entry><literal>STRING</literal></entry>
|
||
<entry>A <literal>UINT32</literal> indicating the string's
|
||
length in bytes excluding its terminating nul, followed by
|
||
non-nul string data of the given length, followed by a terminating nul
|
||
byte.
|
||
</entry>
|
||
<entry>
|
||
4 (for the length)
|
||
</entry>
|
||
</row><row>
|
||
<entry><literal>OBJECT_PATH</literal></entry>
|
||
<entry>Exactly the same as <literal>STRING</literal> except the
|
||
content must be a valid object path (see above).
|
||
</entry>
|
||
<entry>
|
||
4 (for the length)
|
||
</entry>
|
||
</row><row>
|
||
<entry><literal>SIGNATURE</literal></entry>
|
||
<entry>The same as <literal>STRING</literal> except the length is a single
|
||
byte (thus signatures have a maximum length of 255)
|
||
and the content must be a valid signature (see above).
|
||
</entry>
|
||
<entry>
|
||
1
|
||
</entry>
|
||
</row><row>
|
||
<entry><literal>ARRAY</literal></entry>
|
||
<entry>
|
||
A <literal>UINT32</literal> giving the length of the array data in bytes, followed by
|
||
alignment padding to the alignment boundary of the array element type,
|
||
followed by each array element.
|
||
</entry>
|
||
<entry>
|
||
4 (for the length)
|
||
</entry>
|
||
</row><row>
|
||
<entry><literal>STRUCT</literal></entry>
|
||
<entry>
|
||
A struct must start on an 8-byte boundary regardless of the
|
||
type of the struct fields. The struct value consists of each
|
||
field marshaled in sequence starting from that 8-byte
|
||
alignment boundary.
|
||
</entry>
|
||
<entry>
|
||
8
|
||
</entry>
|
||
</row><row>
|
||
<entry><literal>VARIANT</literal></entry>
|
||
<entry>
|
||
The marshaled <literal>SIGNATURE</literal> of a single
|
||
complete type, followed by a marshaled value with the type
|
||
given in the signature.
|
||
</entry>
|
||
<entry>
|
||
1 (alignment of the signature)
|
||
</entry>
|
||
</row><row>
|
||
<entry><literal>DICT_ENTRY</literal></entry>
|
||
<entry>
|
||
Identical to STRUCT.
|
||
</entry>
|
||
<entry>
|
||
8
|
||
</entry>
|
||
</row><row>
|
||
<entry><literal>UNIX_FD</literal></entry>
|
||
<entry>32-bit unsigned integer in the message's byte
|
||
order. The actual file descriptors need to be
|
||
transferred out-of-band via some platform specific
|
||
mechanism. On the wire, values of this type store the index to the
|
||
file descriptor in the array of file descriptors that
|
||
accompany the message.</entry>
|
||
<entry>4</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
</para>
|
||
|
||
</sect2>
|
||
|
||
</sect1>
|
||
|
||
<sect1 id="message-protocol">
|
||
<title>Message Protocol</title>
|
||
|
||
<para>
|
||
A <firstterm>message</firstterm> consists of a
|
||
<firstterm>header</firstterm> and a <firstterm>body</firstterm>. If you
|
||
think of a message as a package, the header is the address, and the body
|
||
contains the package contents. The message delivery system uses the header
|
||
information to figure out where to send the message and how to interpret
|
||
it; the recipient interprets the body of the message.
|
||
</para>
|
||
|
||
<para>
|
||
The body of the message is made up of zero or more
|
||
<firstterm>arguments</firstterm>, which are typed values, such as an
|
||
integer or a byte array.
|
||
</para>
|
||
|
||
<para>
|
||
Both header and body use the D-Bus <link linkend="type-system">type
|
||
system</link> and format for serializing data.
|
||
</para>
|
||
|
||
<sect2 id="message-protocol-messages">
|
||
<title>Message Format</title>
|
||
|
||
<para>
|
||
A message consists of a header and a body. The header is a block of
|
||
values with a fixed signature and meaning. The body is a separate block
|
||
of values, with a signature specified in the header.
|
||
</para>
|
||
|
||
<para>
|
||
The length of the header must be a multiple of 8, allowing the body to
|
||
begin on an 8-byte boundary when storing the entire message in a single
|
||
buffer. If the header does not naturally end on an 8-byte boundary
|
||
up to 7 bytes of nul-initialized alignment padding must be added.
|
||
</para>
|
||
|
||
<para>
|
||
The message body need not end on an 8-byte boundary.
|
||
</para>
|
||
|
||
<para>
|
||
The maximum length of a message, including header, header alignment padding,
|
||
and body is 2 to the 27th power or 134217728 (128 MiB).
|
||
Implementations must not send or accept messages exceeding this size.
|
||
</para>
|
||
|
||
<para>
|
||
The signature of the header is:
|
||
<programlisting>
|
||
"yyyyuua(yv)"
|
||
</programlisting>
|
||
Written out more readably, this is:
|
||
<programlisting>
|
||
BYTE, BYTE, BYTE, BYTE, UINT32, UINT32, ARRAY of STRUCT of (BYTE,VARIANT)
|
||
</programlisting>
|
||
</para>
|
||
|
||
<para>
|
||
These values have the following meanings:
|
||
<informaltable>
|
||
<tgroup cols="2">
|
||
<thead>
|
||
<row>
|
||
<entry>Value</entry>
|
||
<entry>Description</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row>
|
||
<entry>1st <literal>BYTE</literal></entry>
|
||
<entry>Endianness flag; ASCII 'l' for little-endian
|
||
or ASCII 'B' for big-endian. Both header and body are
|
||
in this endianness.</entry>
|
||
</row>
|
||
<row>
|
||
<entry>2nd <literal>BYTE</literal></entry>
|
||
<entry><firstterm>Message type</firstterm>. Unknown types must be ignored.
|
||
Currently-defined types are described below.
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry>3rd <literal>BYTE</literal></entry>
|
||
<entry>Bitwise OR of flags. Unknown flags
|
||
must be ignored. Currently-defined flags are described below.
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry>4th <literal>BYTE</literal></entry>
|
||
<entry>Major protocol version of the sending application. If
|
||
the major protocol version of the receiving application does not
|
||
match, the applications will not be able to communicate and the
|
||
D-Bus connection must be disconnected. The major protocol
|
||
version for this version of the specification is 1.
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry>1st <literal>UINT32</literal></entry>
|
||
<entry>Length in bytes of the message body, starting
|
||
from the end of the header. The header ends after
|
||
its alignment padding to an 8-boundary.
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry>2nd <literal>UINT32</literal></entry>
|
||
<entry>The serial of this message, used as a cookie
|
||
by the sender to identify the reply corresponding
|
||
to this request. This must not be zero.
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>ARRAY</literal> of <literal>STRUCT</literal> of (<literal>BYTE</literal>,<literal>VARIANT</literal>)</entry>
|
||
<entry>An array of zero or more <firstterm>header
|
||
fields</firstterm> where the byte is the field code, and the
|
||
variant is the field value. The message type determines
|
||
which fields are required.
|
||
</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
</para>
|
||
<para>
|
||
<firstterm>Message types</firstterm> that can appear in the second byte
|
||
of the header are:
|
||
<informaltable>
|
||
<tgroup cols="3">
|
||
<thead>
|
||
<row>
|
||
<entry>Conventional name</entry>
|
||
<entry>Decimal value</entry>
|
||
<entry>Description</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row>
|
||
<entry><literal>INVALID</literal></entry>
|
||
<entry>0</entry>
|
||
<entry>This is an invalid type.</entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>METHOD_CALL</literal></entry>
|
||
<entry>1</entry>
|
||
<entry>Method call. This message type may prompt a
|
||
reply.</entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>METHOD_RETURN</literal></entry>
|
||
<entry>2</entry>
|
||
<entry>Method reply with returned data.</entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>ERROR</literal></entry>
|
||
<entry>3</entry>
|
||
<entry>Error reply. If the first argument exists and is a
|
||
string, it is an error message.</entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>SIGNAL</literal></entry>
|
||
<entry>4</entry>
|
||
<entry>Signal emission.</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
</para>
|
||
<para>
|
||
Flags that can appear in the third byte of the header:
|
||
<informaltable>
|
||
<tgroup cols="3">
|
||
<thead>
|
||
<row>
|
||
<entry>Conventional name</entry>
|
||
<entry>Hex value</entry>
|
||
<entry>Description</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row>
|
||
<entry><literal>NO_REPLY_EXPECTED</literal></entry>
|
||
<entry>0x1</entry>
|
||
<entry>
|
||
<para>
|
||
This message does not expect method return replies or
|
||
error replies, even if it is of a type that can
|
||
have a reply; the reply should be omitted.
|
||
</para>
|
||
<para>
|
||
Note that METHOD_CALL is the only message type currently
|
||
defined in this specification that can expect a reply,
|
||
so the presence or absence of this flag in the other
|
||
three message types that are currently
|
||
documented is meaningless: replies to those message
|
||
types should not be sent, whether this flag is present
|
||
or not.
|
||
</para>
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>NO_AUTO_START</literal></entry>
|
||
<entry>0x2</entry>
|
||
<entry>The bus must not launch an owner
|
||
for the destination name in response to this message.
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>ALLOW_INTERACTIVE_AUTHORIZATION</literal></entry>
|
||
<entry>0x4</entry>
|
||
<entry>
|
||
<para>
|
||
This flag may be set on a method call message to
|
||
inform the receiving side that the caller is prepared
|
||
to wait for interactive authorization, which might
|
||
take a considerable time to complete. For instance,
|
||
if this flag is set, it would be appropriate to
|
||
query the user for passwords or confirmation via
|
||
Polkit or a similar framework.
|
||
</para>
|
||
<para>
|
||
This flag is only useful when
|
||
unprivileged code calls a more privileged method call,
|
||
and an authorization framework is deployed that allows
|
||
possibly interactive authorization. If no such framework
|
||
is deployed it has no effect. This flag should not
|
||
be set by default by client implementations. If it is
|
||
set, the caller should also set a suitably long timeout
|
||
on the method call to make sure the user interaction
|
||
may complete. This flag is only valid for method call
|
||
messages, and shall be ignored otherwise.
|
||
</para>
|
||
<para>
|
||
Interaction that takes place as a part of the
|
||
effect of the method being called is outside the scope
|
||
of this flag, even if it could also be characterized
|
||
as authentication or authorization. For instance, in
|
||
a method call that directs a network management service
|
||
to attempt to connect to a virtual private network,
|
||
this flag should control how the network management
|
||
service makes the decision "is this user allowed to
|
||
change system network configuration?", but it should
|
||
not affect how or whether the network management
|
||
service interacts with the user to obtain the credentials
|
||
that are required for access to the VPN.
|
||
</para>
|
||
<para>
|
||
If a this flag is not set on a method call, and a
|
||
service determines that the requested operation is
|
||
not allowed without interactive authorization, but
|
||
could be allowed after successful interactive
|
||
authorization, it may return the
|
||
<literal>org.freedesktop.DBus.Error.InteractiveAuthorizationRequired</literal>
|
||
error.
|
||
</para>
|
||
<para>
|
||
The absence of this flag does not guarantee that
|
||
interactive authorization will not be applied, since
|
||
existing services that pre-date this flag might
|
||
already use interactive authorization. However,
|
||
existing D-Bus APIs that will use interactive
|
||
authorization should document that the call may take
|
||
longer than usual, and new D-Bus APIs should avoid
|
||
interactive authorization in the absence of this flag.
|
||
</para>
|
||
</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
</para>
|
||
|
||
<sect3 id="message-protocol-header-fields">
|
||
<title>Header Fields</title>
|
||
|
||
<para>
|
||
The array at the end of the header contains <firstterm>header
|
||
fields</firstterm>, where each field is a 1-byte field code followed
|
||
by a field value. A header must contain the required header fields for
|
||
its message type, and zero or more of any optional header
|
||
fields. Future versions of this protocol specification may add new
|
||
fields. Implementations must not invent their own header fields;
|
||
only changes to this specification may introduce new header fields.
|
||
</para>
|
||
|
||
<para>
|
||
If an implementation sees a header field code that it does not
|
||
expect, it must accept and ignore that field, as it will be part
|
||
of a new
|
||
(but compatible) version of this specification. This also applies
|
||
to known header fields appearing in unexpected messages, for
|
||
example: if a signal has a reply serial it must be ignored
|
||
even though it has no meaning as of this version of the spec.
|
||
</para>
|
||
|
||
<para>
|
||
However, implementations must not send or accept known header fields
|
||
with the wrong type stored in the field value. So for example a
|
||
message with an <literal>INTERFACE</literal> field of type
|
||
<literal>UINT32</literal> would be considered corrupt.
|
||
</para>
|
||
|
||
<para>
|
||
Server implementations that might relay messages from one
|
||
mutually-distrustful client to another, such as the message
|
||
bus, should remove header fields that the server does not
|
||
recognise. However, a client must assume that the server has
|
||
not done so, unless it has evidence to the contrary,
|
||
such as having checked for the <literal>HeaderFiltering</literal>
|
||
<link linkend="message-bus-properties-features">message bus
|
||
feature</link>.
|
||
</para>
|
||
|
||
<para>
|
||
New header fields controlled by the message bus
|
||
(similar to <literal>SENDER</literal>) might be added to this
|
||
specification in future. Such message fields should normally
|
||
only be added to messages that are going to be delivered to a
|
||
client that specifically requested them (for example by calling
|
||
some method), and the message bus should remove those header
|
||
fields from all other messages that it relays. This design
|
||
principle serves two main purposes. One is to avoid unnecessary
|
||
memory and throughput overhead when delivering messages to
|
||
clients that are not interested in the new header fields.
|
||
The other is to give clients a reason to call the method that
|
||
requests those messages (otherwise, the clients would not work).
|
||
This is desirable because looking at the reply to that method
|
||
call is a natural way to check that the message bus guarantees
|
||
to filter out faked header fields that might have been sent by
|
||
malicious peers.
|
||
</para>
|
||
|
||
<para>
|
||
Here are the currently-defined header fields:
|
||
<informaltable>
|
||
<tgroup cols="5">
|
||
<thead>
|
||
<row>
|
||
<entry>Conventional Name</entry>
|
||
<entry>Decimal Code</entry>
|
||
<entry>Type</entry>
|
||
<entry>Required In</entry>
|
||
<entry>Description</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row>
|
||
<entry><literal>INVALID</literal></entry>
|
||
<entry>0</entry>
|
||
<entry>N/A</entry>
|
||
<entry>not allowed</entry>
|
||
<entry>Not a valid field name (error if it appears in a message)</entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>PATH</literal></entry>
|
||
<entry>1</entry>
|
||
<entry><literal>OBJECT_PATH</literal></entry>
|
||
<entry><literal>METHOD_CALL</literal>, <literal>SIGNAL</literal></entry>
|
||
<entry>The object to send a call to,
|
||
or the object a signal is emitted from.
|
||
The special path
|
||
<literal>/org/freedesktop/DBus/Local</literal> is reserved;
|
||
implementations should not send messages with this path,
|
||
and the reference implementation of the bus daemon will
|
||
disconnect any application that attempts to do so.
|
||
This header field is controlled by the message sender.
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>INTERFACE</literal></entry>
|
||
<entry>2</entry>
|
||
<entry><literal>STRING</literal></entry>
|
||
<entry><literal>SIGNAL</literal></entry>
|
||
<entry>
|
||
The interface to invoke a method call on, or
|
||
that a signal is emitted from. Optional for
|
||
method calls, required for signals.
|
||
The special interface
|
||
<literal>org.freedesktop.DBus.Local</literal> is reserved;
|
||
implementations should not send messages with this
|
||
interface, and the reference implementation of the bus
|
||
daemon will disconnect any application that attempts to
|
||
do so.
|
||
This header field is controlled by the message sender.
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>MEMBER</literal></entry>
|
||
<entry>3</entry>
|
||
<entry><literal>STRING</literal></entry>
|
||
<entry><literal>METHOD_CALL</literal>, <literal>SIGNAL</literal></entry>
|
||
<entry>
|
||
The member, either the method name or signal name.
|
||
This header field is controlled by the message sender.
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>ERROR_NAME</literal></entry>
|
||
<entry>4</entry>
|
||
<entry><literal>STRING</literal></entry>
|
||
<entry><literal>ERROR</literal></entry>
|
||
<entry>The name of the error that occurred, for errors</entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>REPLY_SERIAL</literal></entry>
|
||
<entry>5</entry>
|
||
<entry><literal>UINT32</literal></entry>
|
||
<entry><literal>ERROR</literal>, <literal>METHOD_RETURN</literal></entry>
|
||
<entry>
|
||
The serial number of the message this message is a reply
|
||
to. (The serial number is the second <literal>UINT32</literal>
|
||
in the header.)
|
||
This header field is controlled by the message sender.
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>DESTINATION</literal></entry>
|
||
<entry>6</entry>
|
||
<entry><literal>STRING</literal></entry>
|
||
<entry>optional</entry>
|
||
<entry>
|
||
The name of the connection this message is intended for.
|
||
This field is usually only meaningful in combination with
|
||
the message bus (see <xref linkend="message-bus"/>),
|
||
but other servers may define their own meanings for it.
|
||
This header field is controlled by the message sender.
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>SENDER</literal></entry>
|
||
<entry>7</entry>
|
||
<entry><literal>STRING</literal></entry>
|
||
<entry>optional</entry>
|
||
<entry>Unique name of the sending connection.
|
||
This field is usually only meaningful in combination with
|
||
the message bus, but other servers may define their own
|
||
meanings for it.
|
||
On a message bus, this header field is controlled by
|
||
the message bus, so it is as reliable and trustworthy
|
||
as the message bus itself.
|
||
Otherwise, this header field is controlled by the message
|
||
sender, unless there is out-of-band information that
|
||
indicates otherwise.
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>SIGNATURE</literal></entry>
|
||
<entry>8</entry>
|
||
<entry><literal>SIGNATURE</literal></entry>
|
||
<entry>optional</entry>
|
||
<entry>
|
||
The signature of the message body.
|
||
If omitted, it is assumed to be the
|
||
empty signature "" (i.e. the body must be 0-length).
|
||
This header field is controlled by the message sender.
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>UNIX_FDS</literal></entry>
|
||
<entry>9</entry>
|
||
<entry><literal>UINT32</literal></entry>
|
||
<entry>optional</entry>
|
||
<entry>The number of Unix file descriptors that
|
||
accompany the message. If omitted, it is assumed
|
||
that no Unix file descriptors accompany the
|
||
message. The actual file descriptors need to be
|
||
transferred via platform specific mechanism
|
||
out-of-band. They must be sent at the same time as
|
||
part of the message itself. They may not be sent
|
||
before the first byte of the message itself is
|
||
transferred or after the last byte of the message
|
||
itself.
|
||
This header field is controlled by the message sender.
|
||
</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
</para>
|
||
</sect3>
|
||
</sect2>
|
||
|
||
<sect2 id="message-protocol-names">
|
||
<title>Valid Names</title>
|
||
<para>
|
||
The various names in D-Bus messages have some restrictions.
|
||
</para>
|
||
<para>
|
||
There is a <firstterm>maximum name length</firstterm>
|
||
of 255 which applies to bus names, interfaces, and members.
|
||
</para>
|
||
<sect3 id="message-protocol-names-interface">
|
||
<title>Interface names</title>
|
||
<para>
|
||
Interfaces have names with type <literal>STRING</literal>, meaning that
|
||
they must be valid UTF-8. However, there are also some
|
||
additional restrictions that apply to interface names
|
||
specifically:
|
||
<itemizedlist>
|
||
<listitem><para>Interface names are composed of 2 or more elements separated by
|
||
a period ('.') character. All elements must contain at least
|
||
one character.
|
||
</para>
|
||
</listitem>
|
||
<listitem><para>Each element must only contain the ASCII characters
|
||
"[A-Z][a-z][0-9]_" and must not begin with a digit.
|
||
</para>
|
||
</listitem>
|
||
|
||
<listitem><para>Interface names must not exceed the maximum name length.</para></listitem>
|
||
</itemizedlist>
|
||
</para>
|
||
|
||
<para>
|
||
Interface names should start with the reversed DNS domain name of
|
||
the author of the interface (in lower-case), like interface names
|
||
in Java. It is conventional for the rest of the interface name
|
||
to consist of words run together, with initial capital letters
|
||
on all words ("CamelCase"). Several levels of hierarchy can be used.
|
||
It is also a good idea to include the major version of the interface
|
||
in the name, and increment it if incompatible changes are made;
|
||
this way, a single object can implement several versions of an
|
||
interface in parallel, if necessary.
|
||
</para>
|
||
|
||
<para>
|
||
For instance, if the owner of <literal>example.com</literal> is
|
||
developing a D-Bus API for a music player, they might define
|
||
interfaces called <literal>com.example.MusicPlayer1</literal>,
|
||
<literal>com.example.MusicPlayer1.Track</literal> and
|
||
<literal>com.example.MusicPlayer1.Seekable</literal>.
|
||
</para>
|
||
|
||
<para>
|
||
If the author's DNS domain name contains hyphen/minus characters
|
||
('-'), which are not allowed in D-Bus interface names, they
|
||
should be replaced by underscores. If the DNS domain name
|
||
contains a digit immediately following a period ('.'), which
|
||
is also not allowed in interface names), the interface name
|
||
should add an underscore before that digit. For example, if
|
||
the owner of 7-zip.org defined an interface for out-of-process
|
||
plugins, it might be named <literal>org._7_zip.Plugin</literal>.
|
||
</para>
|
||
|
||
<para>
|
||
If the author's DNS domain name is an internationalized domain
|
||
name (IDN) such as <literal>δοκιμή.example</literal>,
|
||
the ASCII encoding (known as ACE-encoding or Punycode) such as
|
||
<literal>xn--jxalpdlp.example</literal>
|
||
should be used as a basis for the reversed-domain-name form.
|
||
As with any other name, hyphen/minus characters should be
|
||
replaced by underscores in the reversed-domain-name form, for
|
||
example <literal>example.xn__jxalpdlp.ExampleService1</literal>.
|
||
For more information about internationalized domain names, see
|
||
<ulink url="https://datatracker.ietf.org/doc/html/rfc5890">RFC
|
||
5890 "Internationalized Domain Names for Applications (IDNA):
|
||
Definitions and Document Framework"</ulink>.
|
||
</para>
|
||
|
||
<para>
|
||
D-Bus does not distinguish between the concepts that would be
|
||
called classes and interfaces in Java: either can be identified on
|
||
D-Bus by an interface name.
|
||
</para>
|
||
</sect3>
|
||
<sect3 id="message-protocol-names-bus">
|
||
<title>Bus names</title>
|
||
<para>
|
||
Connections have one or more bus names associated with them.
|
||
A connection has exactly one bus name that is a <firstterm>unique
|
||
connection name</firstterm>. The unique connection name remains
|
||
with the connection for its entire lifetime.
|
||
A bus name is of type <literal>STRING</literal>,
|
||
meaning that it must be valid UTF-8. However, there are also
|
||
some additional restrictions that apply to bus names
|
||
specifically:
|
||
<itemizedlist>
|
||
<listitem><para>Bus names that start with a colon (':')
|
||
character are unique connection names. Other bus names
|
||
are called <firstterm>well-known bus names</firstterm>.
|
||
</para>
|
||
</listitem>
|
||
<listitem><para>Bus names are composed of 1 or more elements separated by
|
||
a period ('.') character. All elements must contain at least
|
||
one character.
|
||
</para>
|
||
</listitem>
|
||
<listitem><para>Each element must only contain the ASCII characters
|
||
"[A-Z][a-z][0-9]_-", with "-" discouraged in new bus
|
||
names. Only elements that are part of a unique
|
||
connection name may begin with a digit, elements in
|
||
other bus names must not begin with a digit.
|
||
</para>
|
||
</listitem>
|
||
|
||
<listitem><para>Bus names must contain at least one '.' (period)
|
||
character (and thus at least two elements).
|
||
</para></listitem>
|
||
|
||
<listitem><para>Bus names must not begin with a '.' (period) character.</para></listitem>
|
||
<listitem><para>Bus names must not exceed the maximum name length.</para></listitem>
|
||
</itemizedlist>
|
||
</para>
|
||
<para>
|
||
Note that the hyphen ('-') character is allowed in bus names
|
||
but not in interface names. It is also problematic or not
|
||
allowed in various specifications and APIs that refer to
|
||
D-Bus, such as <ulink
|
||
url="http://docs.flatpak.org/en/latest/introduction.html#identifiers"
|
||
>Flatpak application IDs</ulink>,
|
||
<ulink
|
||
url="https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html#dbus"
|
||
>the <literal>DBusActivatable</literal> interface in the
|
||
Desktop Entry Specification</ulink>, and the convention
|
||
that an application's "main" interface and object path
|
||
resemble its bus name. To avoid situations that require
|
||
special-case handling, it is recommended that new D-Bus names
|
||
consistently replace hyphens with underscores.
|
||
</para>
|
||
|
||
<para>
|
||
Like <link linkend="message-protocol-names-interface">interface
|
||
names</link>, well-known bus names should start with the
|
||
reversed DNS domain name of the author of the interface (in
|
||
lower-case), and it is conventional for the rest of the well-known
|
||
bus name to consist of words run together, with initial
|
||
capital letters. As with interface names, including a version
|
||
number in well-known bus names is a good idea; it's possible to
|
||
have the well-known bus name for more than one version
|
||
simultaneously if backwards compatibility is required.
|
||
</para>
|
||
|
||
<para>
|
||
As with <link linkend="message-protocol-names-interface">interface
|
||
names</link>, if the author's DNS domain name
|
||
contains hyphen/minus characters they should be replaced by
|
||
underscores, if it contains leading digits they should be
|
||
escaped by prepending an underscore, and internationalized
|
||
domain names (IDN) need to be encoded in their ASCII form
|
||
(ACE-encoding, Punycode) before replacing dashes with underscores.
|
||
For example, if the owner
|
||
of 7-zip.org used a D-Bus name for an archiving application,
|
||
it might be named <literal>org._7_zip.Archiver</literal>,
|
||
while the owner of <literal>δοκιμή.example</literal> might
|
||
use the name <literal>example.xn__jxalpdlp.ExampleService1</literal>.
|
||
</para>
|
||
|
||
<para>
|
||
If a well-known bus name implies the presence of a "main" interface,
|
||
that "main" interface is often given the same name as
|
||
the well-known bus name, and situated at the corresponding object
|
||
path. For instance, if the owner of <literal>example.com</literal>
|
||
is developing a D-Bus API for a music player, they might define
|
||
that any application that takes the well-known name
|
||
<literal>com.example.MusicPlayer1</literal> should have an object
|
||
at the object path <literal>/com/example/MusicPlayer1</literal>
|
||
which implements the interface
|
||
<literal>com.example.MusicPlayer1</literal>.
|
||
</para>
|
||
</sect3>
|
||
<sect3 id="message-protocol-names-member">
|
||
<title>Member names</title>
|
||
<para>
|
||
Member (i.e. method or signal) names:
|
||
<itemizedlist>
|
||
<listitem><para>Must only contain the ASCII characters
|
||
"[A-Z][a-z][0-9]_" and may not begin with a
|
||
digit.</para></listitem>
|
||
<listitem><para>Must not contain the '.' (period) character.</para></listitem>
|
||
<listitem><para>Must not exceed the maximum name length.</para></listitem>
|
||
<listitem><para>Must be at least 1 byte in length.</para></listitem>
|
||
</itemizedlist>
|
||
</para>
|
||
|
||
<para>
|
||
It is conventional for member names on D-Bus to consist of
|
||
capitalized words with no punctuation ("camel-case").
|
||
Method names should usually be verbs, such as
|
||
<literal>GetItems</literal>, and signal names should usually be
|
||
a description of an event, such as <literal>ItemsChanged</literal>.
|
||
</para>
|
||
</sect3>
|
||
<sect3 id="message-protocol-names-error">
|
||
<title>Error names</title>
|
||
<para>
|
||
Error names have the same restrictions as interface names.
|
||
</para>
|
||
|
||
<para>
|
||
Error names have the same naming conventions as interface
|
||
names, and often contain <literal>.Error.</literal>; for instance,
|
||
the owner of <literal>example.com</literal> might define the
|
||
errors <literal>com.example.MusicPlayer1.Error.FileNotFound</literal>
|
||
and <literal>com.example.MusicPlayer1.Error.OutOfMemory</literal>.
|
||
The errors defined by D-Bus itself, such as
|
||
<literal>org.freedesktop.DBus.Error.Failed</literal>, follow a
|
||
similar pattern.
|
||
</para>
|
||
</sect3>
|
||
</sect2>
|
||
|
||
<sect2 id="message-protocol-types">
|
||
<title>Message Types</title>
|
||
<para>
|
||
Each of the message types (<literal>METHOD_CALL</literal>, <literal>METHOD_RETURN</literal>, <literal>ERROR</literal>, and
|
||
<literal>SIGNAL</literal>) has its own expected usage conventions and header fields.
|
||
This section describes these conventions.
|
||
</para>
|
||
<sect3 id="message-protocol-types-method">
|
||
<title>Method Calls</title>
|
||
<para>
|
||
Some messages invoke an operation on a remote object. These are
|
||
called method call messages and have the type tag <literal>METHOD_CALL</literal>. Such
|
||
messages map naturally to methods on objects in a typical program.
|
||
</para>
|
||
<para>
|
||
A method call message is required to have a <literal>MEMBER</literal> header field
|
||
indicating the name of the method. Optionally, the message has an
|
||
<literal>INTERFACE</literal> field giving the interface the method is a part of.
|
||
Including the <literal>INTERFACE</literal> in all method call
|
||
messages is strongly recommended.
|
||
</para>
|
||
<para>
|
||
In the absence of an <literal>INTERFACE</literal> field, if two
|
||
or more interfaces on the same object have a method with the same
|
||
name, it is undefined which of those methods will be invoked.
|
||
Implementations may choose to either return an error, or deliver the
|
||
message as though it had an arbitrary one of those interfaces.
|
||
</para>
|
||
<para>
|
||
In some situations (such as the well-known system bus), messages
|
||
are filtered through an access-control list external to the
|
||
remote object implementation. If that filter rejects certain
|
||
messages by matching their interface, or accepts only messages
|
||
to specific interfaces, it must also reject messages that have no
|
||
<literal>INTERFACE</literal>: otherwise, malicious
|
||
applications could use this to bypass the filter.
|
||
</para>
|
||
<para>
|
||
Method call messages also include a <literal>PATH</literal> field
|
||
indicating the object to invoke the method on. If the call is passing
|
||
through a message bus, the message will also have a
|
||
<literal>DESTINATION</literal> field giving the name of the connection
|
||
to receive the message.
|
||
</para>
|
||
<para>
|
||
When an application handles a method call message, it is required to
|
||
return a reply. The reply is identified by a <literal>REPLY_SERIAL</literal> header field
|
||
indicating the serial number of the <literal>METHOD_CALL</literal> being replied to. The
|
||
reply can have one of two types; either <literal>METHOD_RETURN</literal> or <literal>ERROR</literal>.
|
||
</para>
|
||
<para>
|
||
If the reply has type <literal>METHOD_RETURN</literal>, the arguments to the reply message
|
||
are the return value(s) or "out parameters" of the method call.
|
||
If the reply has type <literal>ERROR</literal>, then an "exception" has been thrown,
|
||
and the call fails; no return value will be provided. It makes
|
||
no sense to send multiple replies to the same method call.
|
||
</para>
|
||
<para>
|
||
Even if a method call has no return values, a <literal>METHOD_RETURN</literal>
|
||
reply is required, so the caller will know the method
|
||
was successfully processed.
|
||
</para>
|
||
<para>
|
||
The <literal>METHOD_RETURN</literal> or <literal>ERROR</literal> reply message must have the <literal>REPLY_SERIAL</literal>
|
||
header field.
|
||
</para>
|
||
<para>
|
||
If a <literal>METHOD_CALL</literal> message has the flag <literal>NO_REPLY_EXPECTED</literal>,
|
||
then the application receiving the method should not send the reply message (regardless of
|
||
whether the reply would have been <literal>METHOD_RETURN</literal> or <literal>ERROR</literal>).
|
||
</para>
|
||
<para>
|
||
Unless a message has the flag <literal>NO_AUTO_START</literal>, if the
|
||
destination name does not exist then a program to own the destination
|
||
name will be started (activated) before the message is delivered. See
|
||
<xref linkend="message-bus-starting-services"/>.
|
||
The message
|
||
will be held until the new program is successfully started or has
|
||
failed to start; in case of failure, an error will be returned. This
|
||
flag is only relevant in the context of a message bus, it is ignored
|
||
during one-to-one communication with no intermediate bus.
|
||
</para>
|
||
<sect4 id="message-protocol-types-method-apis">
|
||
<title>Mapping method calls to native APIs</title>
|
||
<para>
|
||
APIs for D-Bus may map method calls to a method call in a specific
|
||
programming language, such as C++, or may map a method call written
|
||
in an IDL to a D-Bus message.
|
||
</para>
|
||
<para>
|
||
In APIs of this nature, arguments to a method are often termed "in"
|
||
(which implies sent in the <literal>METHOD_CALL</literal>), or "out" (which implies
|
||
returned in the <literal>METHOD_RETURN</literal>). Some APIs such as CORBA also have
|
||
"inout" arguments, which are both sent and received, i.e. the caller
|
||
passes in a value which is modified. Mapped to D-Bus, an "inout"
|
||
argument is equivalent to an "in" argument, followed by an "out"
|
||
argument. You can't pass things "by reference" over the wire, so
|
||
"inout" is purely an illusion of the in-process API.
|
||
</para>
|
||
<para>
|
||
Given a method with zero or one return values, followed by zero or more
|
||
arguments, where each argument may be "in", "out", or "inout", the
|
||
caller constructs a message by appending each "in" or "inout" argument,
|
||
in order. "out" arguments are not represented in the caller's message.
|
||
</para>
|
||
<para>
|
||
The recipient constructs a reply by appending first the return value
|
||
if any, then each "out" or "inout" argument, in order.
|
||
"in" arguments are not represented in the reply message.
|
||
</para>
|
||
<para>
|
||
Error replies are normally mapped to exceptions in languages that have
|
||
exceptions.
|
||
</para>
|
||
<para>
|
||
In converting from native APIs to D-Bus, it is perhaps nice to
|
||
map D-Bus naming conventions ("FooBar") to native conventions
|
||
such as "fooBar" or "foo_bar" automatically. This is OK
|
||
as long as you can say that the native API is one that
|
||
was specifically written for D-Bus. It makes the most sense
|
||
when writing object implementations that will be exported
|
||
over the bus. Object proxies used to invoke remote D-Bus
|
||
objects probably need the ability to call any D-Bus method,
|
||
and thus a magic name mapping like this could be a problem.
|
||
</para>
|
||
<para>
|
||
This specification doesn't require anything of native API bindings;
|
||
the preceding is only a suggested convention for consistency
|
||
among bindings.
|
||
</para>
|
||
</sect4>
|
||
</sect3>
|
||
|
||
<sect3 id="message-protocol-types-signal">
|
||
<title>Signal Emission</title>
|
||
<para>
|
||
Unlike method calls, signal emissions have no replies.
|
||
A signal emission is simply a single message of type <literal>SIGNAL</literal>.
|
||
It must have three header fields: <literal>PATH</literal> giving the object
|
||
the signal was emitted from, plus <literal>INTERFACE</literal> and <literal>MEMBER</literal> giving
|
||
the fully-qualified name of the signal. The <literal>INTERFACE</literal> header is required
|
||
for signals, though it is optional for method calls.
|
||
</para>
|
||
</sect3>
|
||
|
||
<sect3 id="message-protocol-types-errors">
|
||
<title>Errors</title>
|
||
<para>
|
||
Messages of type <literal>ERROR</literal> are most commonly replies
|
||
to a <literal>METHOD_CALL</literal>, but may be returned in reply
|
||
to any kind of message. The message bus for example
|
||
will return an <literal>ERROR</literal> in reply to a signal emission if
|
||
the bus does not have enough memory to send the signal.
|
||
</para>
|
||
<para>
|
||
An <literal>ERROR</literal> may have any arguments, but if the first
|
||
argument is a <literal>STRING</literal>, it must be an error message.
|
||
The error message may be logged or shown to the user
|
||
in some way.
|
||
</para>
|
||
</sect3>
|
||
|
||
<sect3 id="message-protocol-types-notation">
|
||
<title>Notation in this document</title>
|
||
<para>
|
||
This document uses a simple pseudo-IDL to describe particular method
|
||
calls and signals. Here is an example of a method call:
|
||
<programlisting>
|
||
org.freedesktop.DBus.StartServiceByName (in STRING name, in UINT32 flags,
|
||
out UINT32 resultcode)
|
||
</programlisting>
|
||
This means <literal>INTERFACE</literal> = org.freedesktop.DBus, <literal>MEMBER</literal> = StartServiceByName,
|
||
<literal>METHOD_CALL</literal> arguments are <literal>STRING</literal> and <literal>UINT32</literal>, <literal>METHOD_RETURN</literal> argument
|
||
is <literal>UINT32</literal>. Remember that the <literal>MEMBER</literal> field can't contain any '.' (period)
|
||
characters so it's known that the last part of the name in
|
||
the "IDL" is the member name.
|
||
</para>
|
||
<para>
|
||
In C++ that might end up looking like this:
|
||
<programlisting>
|
||
unsigned int org::freedesktop::DBus::StartServiceByName (const char *name,
|
||
unsigned int flags);
|
||
</programlisting>
|
||
or equally valid, the return value could be done as an argument:
|
||
<programlisting>
|
||
void org::freedesktop::DBus::StartServiceByName (const char *name,
|
||
unsigned int flags,
|
||
unsigned int *resultcode);
|
||
</programlisting>
|
||
It's really up to the API designer how they want to make
|
||
this look. You could design an API where the namespace wasn't used
|
||
in C++, using STL or Qt, using varargs, or whatever you wanted.
|
||
</para>
|
||
<para>
|
||
Signals are written as follows:
|
||
<programlisting>
|
||
org.freedesktop.DBus.NameLost (STRING name)
|
||
</programlisting>
|
||
Signals don't specify "in" vs. "out" because only
|
||
a single direction is possible.
|
||
</para>
|
||
<para>
|
||
It isn't especially encouraged to use this lame pseudo-IDL in actual
|
||
API implementations; you might use the native notation for the
|
||
language you're using, or you might use COM or CORBA IDL, for example.
|
||
</para>
|
||
</sect3>
|
||
</sect2>
|
||
|
||
<sect2 id="message-protocol-handling-invalid">
|
||
<title>Invalid Protocol and Spec Extensions</title>
|
||
|
||
<para>
|
||
For security reasons, the D-Bus protocol should be strictly parsed and
|
||
validated, with the exception of defined extension points. Any invalid
|
||
protocol or spec violations should result in immediately dropping the
|
||
connection without notice to the other end. Exceptions should be
|
||
carefully considered, e.g. an exception may be warranted for a
|
||
well-understood idiosyncrasy of a widely-deployed implementation. In
|
||
cases where the other end of a connection is 100% trusted and known to
|
||
be friendly, skipping validation for performance reasons could also make
|
||
sense in certain cases.
|
||
</para>
|
||
|
||
<para>
|
||
Generally speaking violations of the "must" requirements in this spec
|
||
should be considered possible attempts to exploit security, and violations
|
||
of the "should" suggestions should be considered legitimate (though perhaps
|
||
they should generate an error in some cases).
|
||
</para>
|
||
|
||
<para>
|
||
The following extension points are built in to D-Bus on purpose and must
|
||
not be treated as invalid protocol. The extension points are intended
|
||
for use by future versions of this spec, they are not intended for third
|
||
parties. At the moment, the only way a third party could extend D-Bus
|
||
without breaking interoperability would be to introduce a way to negotiate new
|
||
feature support as part of the auth protocol, using EXTENSION_-prefixed
|
||
commands. There is not yet a standard way to negotiate features.
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>
|
||
In the authentication protocol (see <xref linkend="auth-protocol"/>) unknown
|
||
commands result in an ERROR rather than a disconnect. This enables
|
||
future extensions to the protocol. Commands starting with EXTENSION_ are
|
||
reserved for third parties.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>
|
||
The authentication protocol supports pluggable auth mechanisms.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>
|
||
The address format (see <xref linkend="addresses"/>) supports new
|
||
kinds of transport.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>
|
||
Messages with an unknown type (something other than
|
||
<literal>METHOD_CALL</literal>, <literal>METHOD_RETURN</literal>,
|
||
<literal>ERROR</literal>, <literal>SIGNAL</literal>) are ignored.
|
||
Unknown-type messages must still be well-formed in the same way
|
||
as the known messages, however. They still have the normal
|
||
header and body.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>
|
||
Header fields with an unknown or unexpected field code must be ignored,
|
||
though again they must still be well-formed.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>
|
||
New standard interfaces (with new methods and signals) can of course be added.
|
||
</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
</para>
|
||
|
||
</sect2>
|
||
|
||
</sect1>
|
||
|
||
<sect1 id="auth-protocol">
|
||
<title>Authentication Protocol</title>
|
||
<para>
|
||
Before the flow of messages begins, two applications must
|
||
authenticate. A simple plain-text protocol is used for
|
||
authentication; this protocol is a SASL profile, and maps fairly
|
||
directly from the SASL specification. The message encoding is
|
||
NOT used here, only plain text messages.
|
||
</para>
|
||
<para>
|
||
Using SASL in D-Bus requires that we define the meaning of non-empty
|
||
authorization identity strings. When D-Bus is used on Unix platforms,
|
||
a non-empty SASL authorization identity represents a Unix user. An
|
||
authorization identity consisting entirely of ASCII decimal digits
|
||
represents a numeric user ID as defined by POSIX, for example
|
||
<literal>0</literal> for the root user or <literal>1000</literal>
|
||
for the first user created on many systems. Non-numeric authorization
|
||
identities are not required to be accepted or supported, but if used,
|
||
they must be interpreted as a login name as found in the
|
||
<literal>pw_name</literal> field of POSIX
|
||
<literal>struct passwd</literal>, for example
|
||
<literal>root</literal>, and normalized to the corresponding
|
||
numeric user ID. For best interoperability, clients and servers
|
||
should use numeric user IDs.
|
||
</para>
|
||
<para>
|
||
When D-Bus is used on Windows platforms, a non-empty SASL
|
||
authorization identity represents a Windows security identifier
|
||
(SID) in its string form, for example
|
||
<literal>S-1-5-21-3623811015-3361044348-30300820-1013</literal> for
|
||
a domain or local computer user or <literal>S-1-5-18</literal> for
|
||
the LOCAL_SYSTEM user. The user-facing usernames such as
|
||
<literal>Administrator</literal> or <literal>LOCAL_SYSTEM</literal>
|
||
are not used in the D-Bus protocol.
|
||
</para>
|
||
<para>
|
||
In examples, "C:" and "S:" indicate lines sent by the client and
|
||
server respectively. The client sends the first line, and the
|
||
server must respond to each line from the client with a single-line
|
||
reply, with one exception: there is no reply to the BEGIN command.
|
||
</para>
|
||
<sect2 id="auth-protocol-overview">
|
||
<title>Protocol Overview</title>
|
||
<para>
|
||
The protocol is a line-based protocol, where each line ends with
|
||
\r\n. Each line begins with an all-caps ASCII command name containing
|
||
only the character range [A-Z_], a space, then any arguments for the
|
||
command, then the \r\n ending the line. The protocol is
|
||
case-sensitive. All bytes must be in the ASCII character set.
|
||
|
||
Commands from the client to the server are as follows:
|
||
|
||
<itemizedlist>
|
||
<listitem><para>AUTH [mechanism] [initial-response]</para></listitem>
|
||
<listitem><para>CANCEL</para></listitem>
|
||
<listitem><para>BEGIN</para></listitem>
|
||
<listitem><para>DATA <data in hex encoding></para></listitem>
|
||
<listitem><para>ERROR [human-readable error explanation]</para></listitem>
|
||
<listitem><para>NEGOTIATE_UNIX_FD</para></listitem>
|
||
</itemizedlist>
|
||
|
||
From server to client are as follows:
|
||
|
||
<itemizedlist>
|
||
<listitem><para>REJECTED <space-separated list of mechanism names></para></listitem>
|
||
<listitem><para>OK <GUID in hex></para></listitem>
|
||
<listitem><para>DATA <data in hex encoding></para></listitem>
|
||
<listitem><para>ERROR [human-readable error explanation]</para></listitem>
|
||
<listitem><para>AGREE_UNIX_FD</para></listitem>
|
||
</itemizedlist>
|
||
</para>
|
||
<para>
|
||
Unofficial extensions to the command set must begin with the letters
|
||
"EXTENSION_", to avoid conflicts with future official commands.
|
||
For example, "EXTENSION_COM_MYDOMAIN_DO_STUFF".
|
||
</para>
|
||
</sect2>
|
||
<sect2 id="auth-nul-byte">
|
||
<title>Special credentials-passing nul byte</title>
|
||
<para>
|
||
Immediately after connecting to the server, the client must send a
|
||
single nul byte. This byte may be accompanied by credentials
|
||
information on some operating systems that use sendmsg() with
|
||
SCM_CREDS or SCM_CREDENTIALS to pass credentials over UNIX domain
|
||
sockets. However, the nul byte must be sent even on other kinds of
|
||
socket, and even on operating systems that do not require a byte to be
|
||
sent in order to transmit credentials. The text protocol described in
|
||
this document begins after the single nul byte. If the first byte
|
||
received from the client is not a nul byte, the server may disconnect
|
||
that client.
|
||
</para>
|
||
<para>
|
||
A nul byte in any context other than the initial byte is an error;
|
||
the protocol is ASCII-only.
|
||
</para>
|
||
<para>
|
||
The credentials sent along with the nul byte may be used with the
|
||
SASL mechanism EXTERNAL.
|
||
</para>
|
||
</sect2>
|
||
<sect2 id="auth-command-auth">
|
||
<title>AUTH command</title>
|
||
<para>
|
||
The AUTH command is sent by the client to the server.
|
||
The server replies with DATA, OK or REJECTED.
|
||
</para>
|
||
<para>
|
||
If an AUTH command has no arguments, it is a request to list
|
||
available mechanisms. The server must respond with a REJECTED
|
||
command listing the mechanisms it understands, or with an error.
|
||
</para>
|
||
<para>
|
||
If an AUTH command specifies a mechanism, and the server supports
|
||
said mechanism, the server should begin exchanging SASL
|
||
challenge-response data with the client using DATA commands.
|
||
</para>
|
||
<para>
|
||
If the server does not support the mechanism given in the AUTH
|
||
command, it must send either a REJECTED command listing the mechanisms
|
||
it does support, or an error.
|
||
</para>
|
||
<para>
|
||
If the [initial-response] argument is provided, it is intended for use
|
||
with mechanisms that have no initial challenge (or an empty initial
|
||
challenge), as if it were the argument to an initial DATA command. If
|
||
the selected mechanism has an initial challenge and [initial-response]
|
||
was provided, the server should reject authentication by sending
|
||
REJECTED.
|
||
</para>
|
||
<para>
|
||
If authentication succeeds after exchanging DATA commands,
|
||
an OK command must be sent to the client.
|
||
</para>
|
||
</sect2>
|
||
<sect2 id="auth-command-cancel">
|
||
<title>CANCEL Command</title>
|
||
<para>
|
||
The CANCEL command is sent by the client to the server.
|
||
The server replies with REJECTED.
|
||
</para>
|
||
<para>
|
||
At any time up to sending the BEGIN command, the client may send a
|
||
CANCEL command. On receiving the CANCEL command, the server must
|
||
send a REJECTED command and abort the current authentication
|
||
exchange.
|
||
</para>
|
||
</sect2>
|
||
<sect2 id="auth-command-data">
|
||
<title>DATA Command</title>
|
||
<para>
|
||
The DATA command may come from either client or server, and simply
|
||
contains a hex-encoded block of data to be interpreted
|
||
according to the SASL mechanism in use.
|
||
If sent by the client, the server replies with DATA, OK or REJECTED.
|
||
</para>
|
||
<para>
|
||
Some SASL mechanisms support sending an "empty string";
|
||
FIXME we need some way to do this.
|
||
</para>
|
||
</sect2>
|
||
<sect2 id="auth-command-begin">
|
||
<title>BEGIN Command</title>
|
||
<para>
|
||
The BEGIN command is sent by the client to the server.
|
||
The server does not reply.
|
||
</para>
|
||
<para>
|
||
The BEGIN command acknowledges that the client has received an
|
||
OK command from the server and completed any feature negotiation
|
||
that it wishes to do, and declares that the stream of messages
|
||
is about to begin.
|
||
</para>
|
||
<para>
|
||
The first octet received by the server after the \r\n of the BEGIN
|
||
command from the client must be the first octet of the
|
||
authenticated/encrypted stream of D-Bus messages.
|
||
</para>
|
||
<para>
|
||
Unlike all other commands, the server does not reply to
|
||
the BEGIN command with an authentication command of its own.
|
||
After the \r\n of the reply to the command before BEGIN,
|
||
the next octet received by the client must be the first octet
|
||
of the authenticated/encrypted stream of D-Bus messages.
|
||
</para>
|
||
</sect2>
|
||
<sect2 id="auth-command-rejected">
|
||
<title>REJECTED Command</title>
|
||
<para>
|
||
The REJECTED command is sent by the server to the client.
|
||
</para>
|
||
<para>
|
||
The REJECTED command indicates that the current authentication
|
||
exchange has failed, and further exchange of DATA is inappropriate.
|
||
The client would normally try another mechanism, or try providing
|
||
different responses to challenges.
|
||
</para><para>
|
||
Optionally, the REJECTED command has a space-separated list of
|
||
available auth mechanisms as arguments. If a server ever provides
|
||
a list of supported mechanisms, it must provide the same list
|
||
each time it sends a REJECTED message. Clients are free to
|
||
ignore all lists received after the first.
|
||
</para>
|
||
</sect2>
|
||
<sect2 id="auth-command-ok">
|
||
<title>OK Command</title>
|
||
<para>
|
||
The OK command is sent by the server to the client.
|
||
</para>
|
||
<para>
|
||
The OK command indicates that the client has been
|
||
authenticated. The client may now proceed with negotiating
|
||
Unix file descriptor passing. To do that it shall send
|
||
NEGOTIATE_UNIX_FD to the server.
|
||
</para>
|
||
<para>
|
||
Otherwise, the client must respond to the OK command by
|
||
sending a BEGIN command, followed by its stream of messages,
|
||
or by disconnecting. The server must not accept additional
|
||
commands using this protocol after the BEGIN command has been
|
||
received. Further communication will be a stream of D-Bus
|
||
messages (optionally encrypted, as negotiated) rather than
|
||
this protocol.
|
||
</para>
|
||
<para>
|
||
If there is no negotiation, the first octet received by the client
|
||
after the \r\n of the OK command must be the first octet of
|
||
the authenticated/encrypted stream of D-Bus messages. If the
|
||
client negotiates Unix file descriptor passing, the first
|
||
octet received by the client after the \r\n of the AGREE_UNIX_FD
|
||
or ERROR reply must be the first octet of the
|
||
authenticated/encrypted stream.
|
||
</para>
|
||
<para>
|
||
The OK command has one argument, which is the GUID of the server.
|
||
See <xref linkend="addresses"/> for more on server GUIDs.
|
||
</para>
|
||
</sect2>
|
||
<sect2 id="auth-command-error">
|
||
<title>ERROR Command</title>
|
||
<para>
|
||
The ERROR command can be sent in either direction.
|
||
If sent by the client, the server replies with REJECTED.
|
||
</para>
|
||
<para>
|
||
The ERROR command indicates that either server or client did not
|
||
know a command, does not accept the given command in the current
|
||
context, or did not understand the arguments to the command. This
|
||
allows the protocol to be extended; a client or server can send a
|
||
command present or permitted only in new protocol versions, and if
|
||
an ERROR is received instead of an appropriate response, fall back
|
||
to using some other technique.
|
||
</para>
|
||
<para>
|
||
If an ERROR is sent, the server or client that sent the
|
||
error must continue as if the command causing the ERROR had never been
|
||
received. However, the the server or client receiving the error
|
||
should try something other than whatever caused the error;
|
||
if only canceling/rejecting the authentication.
|
||
</para>
|
||
<para>
|
||
If the D-Bus protocol changes incompatibly at some future time,
|
||
applications implementing the new protocol would probably be able to
|
||
check for support of the new protocol by sending a new command and
|
||
receiving an ERROR from applications that don't understand it. Thus the
|
||
ERROR feature of the auth protocol is an escape hatch that lets us
|
||
negotiate extensions or changes to the D-Bus protocol in the future.
|
||
</para>
|
||
</sect2>
|
||
<sect2 id="auth-command-negotiate-unix-fd">
|
||
<title>NEGOTIATE_UNIX_FD Command</title>
|
||
<para>
|
||
The NEGOTIATE_UNIX_FD command is sent by the client to the server.
|
||
The server replies with AGREE_UNIX_FD or ERROR.
|
||
</para>
|
||
<para>
|
||
The NEGOTIATE_UNIX_FD command indicates that the client
|
||
supports Unix file descriptor passing. This command may only
|
||
be sent after the connection is authenticated, i.e. after OK
|
||
was received by the client. This command may only be sent on
|
||
transports that support Unix file descriptor passing.
|
||
</para>
|
||
<para>
|
||
On receiving NEGOTIATE_UNIX_FD the server must respond with
|
||
either AGREE_UNIX_FD or ERROR. It shall respond the former if
|
||
the transport chosen supports Unix file descriptor passing and
|
||
the server supports this feature. It shall respond the latter
|
||
if the transport does not support Unix file descriptor
|
||
passing, the server does not support this feature, or the
|
||
server decides not to enable file descriptor passing due to
|
||
security or other reasons.
|
||
</para>
|
||
</sect2>
|
||
<sect2 id="auth-command-agree-unix-fd">
|
||
<title>AGREE_UNIX_FD Command</title>
|
||
<para>
|
||
The AGREE_UNIX_FD command is sent by the server to the client.
|
||
</para>
|
||
<para>
|
||
The AGREE_UNIX_FD command indicates that the server supports
|
||
Unix file descriptor passing. This command may only be sent
|
||
after the connection is authenticated, and the client sent
|
||
NEGOTIATE_UNIX_FD to enable Unix file descriptor passing. This
|
||
command may only be sent on transports that support Unix file
|
||
descriptor passing.
|
||
</para>
|
||
<para>
|
||
On receiving AGREE_UNIX_FD the client must respond with BEGIN,
|
||
followed by its stream of messages, or by disconnecting. The
|
||
server must not accept additional commands using this protocol
|
||
after the BEGIN command has been received. Further
|
||
communication will be a stream of D-Bus messages (optionally
|
||
encrypted, as negotiated) rather than this protocol.
|
||
</para>
|
||
</sect2>
|
||
<sect2 id="auth-command-future">
|
||
<title>Future Extensions</title>
|
||
<para>
|
||
Future extensions to the authentication and negotiation
|
||
protocol are possible. For that new commands may be
|
||
introduced. If a client or server receives an unknown command
|
||
it shall respond with ERROR and not consider this fatal. New
|
||
commands may be introduced both before, and after
|
||
authentication, i.e. both before and after the OK command.
|
||
</para>
|
||
</sect2>
|
||
<sect2 id="auth-examples">
|
||
<title>Authentication examples</title>
|
||
|
||
<para>
|
||
<figure>
|
||
<title>Example of successful EXTERNAL authentication</title>
|
||
<programlisting>
|
||
31303030 is ASCII decimal "1000" represented in hex, so
|
||
the client is authenticating as Unix uid 1000 in this example.
|
||
|
||
C: AUTH EXTERNAL 31303030
|
||
S: OK 1234deadbeef
|
||
C: BEGIN
|
||
</programlisting>
|
||
</figure>
|
||
<figure>
|
||
<title>Example of finding out mechanisms then picking one</title>
|
||
<programlisting>
|
||
C: AUTH
|
||
S: REJECTED KERBEROS_V4 SKEY
|
||
C: AUTH SKEY 7ab83f32ee
|
||
S: DATA 8799cabb2ea93e
|
||
C: DATA 8ac876e8f68ee9809bfa876e6f9876g8fa8e76e98f
|
||
S: OK 1234deadbeef
|
||
C: BEGIN
|
||
</programlisting>
|
||
</figure>
|
||
<figure>
|
||
<title>Example of client sends unknown command then falls back to regular auth</title>
|
||
<programlisting>
|
||
532d312d352d3138 is the Windows SID "S-1-5-18" in hex,
|
||
so the client is authenticating as Windows SID S-1-5-18
|
||
in this example.
|
||
|
||
C: FOOBAR
|
||
S: ERROR
|
||
C: AUTH EXTERNAL 532d312d352d3138
|
||
S: OK 1234deadbeef
|
||
C: BEGIN
|
||
</programlisting>
|
||
</figure>
|
||
<figure>
|
||
<title>Example of server doesn't support initial auth mechanism</title>
|
||
<programlisting>
|
||
C: AUTH EXTERNAL
|
||
S: REJECTED KERBEROS_V4 SKEY
|
||
C: AUTH SKEY 7ab83f32ee
|
||
S: DATA 8799cabb2ea93e
|
||
C: DATA 8ac876e8f68ee9809bfa876e6f9876g8fa8e76e98f
|
||
S: OK 1234deadbeef
|
||
C: BEGIN
|
||
</programlisting>
|
||
</figure>
|
||
<figure>
|
||
<title>Example of wrong password or the like followed by successful retry</title>
|
||
<programlisting>
|
||
C: AUTH EXTERNAL 736d6376
|
||
S: REJECTED KERBEROS_V4 SKEY
|
||
C: AUTH SKEY 7ab83f32ee
|
||
S: DATA 8799cabb2ea93e
|
||
C: DATA 8ac876e8f68ee9809bfa876e6f9876g8fa8e76e98f
|
||
S: REJECTED
|
||
C: AUTH SKEY 7ab83f32ee
|
||
S: DATA 8799cabb2ea93e
|
||
C: DATA 8ac876e8f68ee9809bfa876e6f9876g8fa8e76e98f
|
||
S: OK 1234deadbeef
|
||
C: BEGIN
|
||
</programlisting>
|
||
</figure>
|
||
<figure>
|
||
<title>Example of skey cancelled and restarted</title>
|
||
<programlisting>
|
||
C: AUTH EXTERNAL 32303438
|
||
S: REJECTED KERBEROS_V4 SKEY
|
||
C: AUTH SKEY 7ab83f32ee
|
||
S: DATA 8799cabb2ea93e
|
||
C: CANCEL
|
||
S: REJECTED
|
||
C: AUTH SKEY 7ab83f32ee
|
||
S: DATA 8799cabb2ea93e
|
||
C: DATA 8ac876e8f68ee9809bfa876e6f9876g8fa8e76e98f
|
||
S: OK 1234deadbeef
|
||
C: BEGIN
|
||
</programlisting>
|
||
</figure>
|
||
<figure>
|
||
<title>Example of successful EXTERNAL authentication with successful negotiation of Unix FD passing</title>
|
||
<programlisting>
|
||
C: AUTH EXTERNAL 31303030
|
||
S: OK 1234deadbeef
|
||
C: NEGOTIATE_UNIX_FD
|
||
S: AGREE_UNIX_FD
|
||
C: BEGIN
|
||
</programlisting>
|
||
</figure>
|
||
<figure>
|
||
<title>Example of successful EXTERNAL authentication with unsuccessful negotiation of Unix FD passing</title>
|
||
<programlisting>
|
||
C: AUTH EXTERNAL 31303030
|
||
S: OK 1234deadbeef
|
||
C: NEGOTIATE_UNIX_FD
|
||
S: ERROR Not supported on this OS
|
||
C: BEGIN
|
||
</programlisting>
|
||
</figure>
|
||
</para>
|
||
</sect2>
|
||
<sect2 id="auth-states">
|
||
<title>Authentication state diagrams</title>
|
||
|
||
<para>
|
||
This section documents the auth protocol in terms of
|
||
a state machine for the client and the server. This is
|
||
probably the most robust way to implement the protocol.
|
||
</para>
|
||
|
||
<sect3 id="auth-states-client">
|
||
<title>Client states</title>
|
||
|
||
<para>
|
||
To more precisely describe the interaction between the
|
||
protocol state machine and the authentication mechanisms the
|
||
following notation is used: MECH(CHALL) means that the
|
||
server challenge CHALL was fed to the mechanism MECH, which
|
||
returns one of
|
||
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>
|
||
CONTINUE(RESP) means continue the auth conversation
|
||
and send RESP as the response to the server;
|
||
</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>
|
||
OK(RESP) means that after sending RESP to the server
|
||
the client side of the auth conversation is finished
|
||
and the server should return "OK";
|
||
</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>
|
||
ERROR means that CHALL was invalid and could not be
|
||
processed.
|
||
</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
|
||
Both RESP and CHALL may be empty.
|
||
</para>
|
||
|
||
<para>
|
||
The Client starts by getting an initial response from the
|
||
default mechanism and sends AUTH MECH RESP, or AUTH MECH if
|
||
the mechanism did not provide an initial response. If the
|
||
mechanism returns CONTINUE, the client starts in state
|
||
<emphasis>WaitingForData</emphasis>, if the mechanism
|
||
returns OK the client starts in state
|
||
<emphasis>WaitingForOK</emphasis>.
|
||
</para>
|
||
|
||
<para>
|
||
The client should keep track of available mechanisms and
|
||
which it mechanisms it has already attempted. This list is
|
||
used to decide which AUTH command to send. When the list is
|
||
exhausted, the client should give up and close the
|
||
connection.
|
||
</para>
|
||
|
||
<formalpara>
|
||
<title><emphasis>WaitingForData</emphasis></title>
|
||
<para>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>
|
||
Receive DATA CHALL
|
||
<simplelist>
|
||
<member>
|
||
MECH(CHALL) returns CONTINUE(RESP) → send
|
||
DATA RESP, goto
|
||
<emphasis>WaitingForData</emphasis>
|
||
</member>
|
||
|
||
<member>
|
||
MECH(CHALL) returns OK(RESP) → send DATA
|
||
RESP, goto <emphasis>WaitingForOK</emphasis>
|
||
</member>
|
||
|
||
<member>
|
||
MECH(CHALL) returns ERROR → send ERROR
|
||
[msg], goto <emphasis>WaitingForData</emphasis>
|
||
</member>
|
||
</simplelist>
|
||
</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>
|
||
Receive REJECTED [mechs] →
|
||
send AUTH [next mech], goto
|
||
WaitingForData or <emphasis>WaitingForOK</emphasis>
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>
|
||
Receive ERROR → send
|
||
CANCEL, goto
|
||
<emphasis>WaitingForReject</emphasis>
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>
|
||
Receive OK → <emphasis>authenticated</emphasis>,
|
||
choose one:
|
||
|
||
<simplelist>
|
||
<member>
|
||
send NEGOTIATE_UNIX_FD, goto
|
||
<emphasis>WaitingForAgreeUnixFD</emphasis>
|
||
</member>
|
||
|
||
<member>
|
||
send BEGIN, terminate auth conversation (successfully)
|
||
</member>
|
||
</simplelist>
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>
|
||
Receive anything else → send
|
||
ERROR, goto
|
||
<emphasis>WaitingForData</emphasis>
|
||
</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
</para>
|
||
</formalpara>
|
||
|
||
<formalpara>
|
||
<title><emphasis>WaitingForOK</emphasis></title>
|
||
<para>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>
|
||
Receive OK → <emphasis>authenticated</emphasis>,
|
||
choose one:
|
||
|
||
<simplelist>
|
||
<member>
|
||
send NEGOTIATE_UNIX_FD, goto
|
||
<emphasis>WaitingForAgreeUnixFD</emphasis>
|
||
</member>
|
||
|
||
<member>
|
||
send BEGIN, terminate auth conversation (successfully)
|
||
</member>
|
||
</simplelist>
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>
|
||
Receive REJECTED [mechs] → send AUTH [next mech],
|
||
goto <emphasis>WaitingForData</emphasis> or
|
||
<emphasis>WaitingForOK</emphasis>
|
||
</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>
|
||
Receive DATA → send CANCEL, goto
|
||
<emphasis>WaitingForReject</emphasis>
|
||
</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>
|
||
Receive ERROR → send CANCEL, goto
|
||
<emphasis>WaitingForReject</emphasis>
|
||
</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>
|
||
Receive anything else → send ERROR, goto
|
||
<emphasis>WaitingForOK</emphasis>
|
||
</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
</para>
|
||
</formalpara>
|
||
|
||
<formalpara>
|
||
<title><emphasis>WaitingForReject</emphasis></title>
|
||
<para>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>
|
||
Receive REJECTED [mechs] → send AUTH [next mech],
|
||
goto <emphasis>WaitingForData</emphasis> or
|
||
<emphasis>WaitingForOK</emphasis>
|
||
</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>
|
||
Receive anything else → terminate auth
|
||
conversation, disconnect
|
||
</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
</para>
|
||
</formalpara>
|
||
|
||
<formalpara>
|
||
<title><emphasis>WaitingForAgreeUnixFD</emphasis></title>
|
||
<para>
|
||
By the time this state is reached, the client has already
|
||
been authenticated.
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>
|
||
Receive AGREE_UNIX_FD → enable Unix fd passing,
|
||
send BEGIN, terminate auth conversation (successfully)
|
||
</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>
|
||
Receive ERROR → disable Unix fd passing,
|
||
send BEGIN, terminate auth conversation (successfully)
|
||
</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>
|
||
Receive anything else → terminate auth
|
||
conversation, disconnect
|
||
</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
</para>
|
||
</formalpara>
|
||
|
||
</sect3>
|
||
|
||
<sect3 id="auth-states-server">
|
||
<title>Server states</title>
|
||
|
||
<para>
|
||
For the server MECH(RESP) means that the client response
|
||
RESP was fed to the the mechanism MECH, which returns one of
|
||
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>
|
||
CONTINUE(CHALL) means continue the auth conversation and
|
||
send CHALL as the challenge to the client;
|
||
</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>
|
||
OK means that the client has been successfully
|
||
authenticated;
|
||
</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>
|
||
REJECTED means that the client failed to authenticate or
|
||
there was an error in RESP.
|
||
</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
|
||
The server starts out in state
|
||
<emphasis>WaitingForAuth</emphasis>. If the client is
|
||
rejected too many times the server must disconnect the
|
||
client.
|
||
</para>
|
||
|
||
<formalpara>
|
||
<title><emphasis>WaitingForAuth</emphasis></title>
|
||
<para>
|
||
<itemizedlist>
|
||
|
||
<listitem>
|
||
<para>
|
||
Receive AUTH → send REJECTED [mechs], goto
|
||
<emphasis>WaitingForAuth</emphasis>
|
||
</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>
|
||
Receive AUTH MECH RESP
|
||
|
||
<simplelist>
|
||
<member>
|
||
MECH not valid mechanism → send REJECTED
|
||
[mechs], goto
|
||
<emphasis>WaitingForAuth</emphasis>
|
||
</member>
|
||
|
||
<member>
|
||
MECH(RESP) returns CONTINUE(CHALL) → send
|
||
DATA CHALL, goto
|
||
<emphasis>WaitingForData</emphasis>
|
||
</member>
|
||
|
||
<member>
|
||
MECH(RESP) returns OK → send OK, goto
|
||
<emphasis>WaitingForBegin</emphasis>
|
||
</member>
|
||
|
||
<member>
|
||
MECH(RESP) returns REJECTED → send REJECTED
|
||
[mechs], goto
|
||
<emphasis>WaitingForAuth</emphasis>
|
||
</member>
|
||
</simplelist>
|
||
</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>
|
||
Receive BEGIN → terminate
|
||
auth conversation, disconnect
|
||
</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>
|
||
Receive ERROR → send REJECTED [mechs], goto
|
||
<emphasis>WaitingForAuth</emphasis>
|
||
</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>
|
||
Receive anything else → send
|
||
ERROR, goto
|
||
<emphasis>WaitingForAuth</emphasis>
|
||
</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
</para>
|
||
</formalpara>
|
||
|
||
|
||
<formalpara>
|
||
<title><emphasis>WaitingForData</emphasis></title>
|
||
<para>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>
|
||
Receive DATA RESP
|
||
<simplelist>
|
||
<member>
|
||
MECH(RESP) returns CONTINUE(CHALL) → send
|
||
DATA CHALL, goto
|
||
<emphasis>WaitingForData</emphasis>
|
||
</member>
|
||
|
||
<member>
|
||
MECH(RESP) returns OK → send OK, goto
|
||
<emphasis>WaitingForBegin</emphasis>
|
||
</member>
|
||
|
||
<member>
|
||
MECH(RESP) returns REJECTED → send REJECTED
|
||
[mechs], goto
|
||
<emphasis>WaitingForAuth</emphasis>
|
||
</member>
|
||
</simplelist>
|
||
</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>
|
||
Receive BEGIN → terminate auth conversation,
|
||
disconnect
|
||
</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>
|
||
Receive CANCEL → send REJECTED [mechs], goto
|
||
<emphasis>WaitingForAuth</emphasis>
|
||
</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>
|
||
Receive ERROR → send REJECTED [mechs], goto
|
||
<emphasis>WaitingForAuth</emphasis>
|
||
</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>
|
||
Receive anything else → send ERROR, goto
|
||
<emphasis>WaitingForData</emphasis>
|
||
</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
</para>
|
||
</formalpara>
|
||
|
||
<formalpara>
|
||
<title><emphasis>WaitingForBegin</emphasis></title>
|
||
<para>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>
|
||
Receive BEGIN → terminate auth conversation,
|
||
client authenticated
|
||
</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>
|
||
Receive NEGOTIATE_UNIX_FD → send AGREE_UNIX_FD
|
||
or ERROR, goto <emphasis>WaitingForBegin</emphasis>
|
||
</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>
|
||
Receive CANCEL → send REJECTED [mechs], goto
|
||
<emphasis>WaitingForAuth</emphasis>
|
||
</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>
|
||
Receive ERROR → send REJECTED [mechs], goto
|
||
<emphasis>WaitingForAuth</emphasis>
|
||
</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>
|
||
Receive anything else → send ERROR, goto
|
||
<emphasis>WaitingForBegin</emphasis>
|
||
</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
</para>
|
||
</formalpara>
|
||
|
||
</sect3>
|
||
|
||
</sect2>
|
||
<sect2 id="auth-mechanisms">
|
||
<title>Authentication mechanisms</title>
|
||
<para>
|
||
This section describes some authentication mechanisms that are
|
||
often supported by practical D-Bus implementations. The D-Bus
|
||
protocol also allows any other standard SASL mechanism, although
|
||
implementations of D-Bus often do not.
|
||
</para>
|
||
<sect3 id="auth-mechanisms-external">
|
||
<title>EXTERNAL</title>
|
||
<para>
|
||
The EXTERNAL mechanism is defined in <ulink
|
||
url="https://tools.ietf.org/html/rfc4422#appendix-A">RFC 4422
|
||
"Simple Authentication and Security Layer (SASL)", appendix A
|
||
"The SASL EXTERNAL Mechanism"</ulink>. This is the recommended
|
||
authentication mechanism on platforms where credentials can be
|
||
transferred out-of-band, in particular Unix platforms that can
|
||
perform credentials-passing over the
|
||
<link linkend="transports-unix-domain-sockets-addresses"
|
||
>unix: transport</link>.
|
||
</para>
|
||
<para>
|
||
On Unix platforms, interoperable clients should prefer to send
|
||
the ASCII decimal string form of the integer Unix user ID as
|
||
the authorization identity, for example 1000. When encoded in
|
||
hex by the authentication protocol, this will typically result
|
||
in a line like <literal>AUTH EXTERNAL 31303030</literal> followed
|
||
by \r\n.
|
||
</para>
|
||
<para>
|
||
On Windows platforms, clients that use the EXTERNAL mechanism
|
||
should use the Windows security identifier in its string form
|
||
as the authorization identity, for example
|
||
<literal>S-1-5-21-3623811015-3361044348-30300820-1013</literal> for
|
||
a domain or local computer user or <literal>S-1-5-18</literal> for
|
||
the LOCAL_SYSTEM user. When encoded in hex by the authentication
|
||
protocol, this will typically result in a line like
|
||
<literal>AUTH EXTERNAL 532d312d352d3138</literal> followed by
|
||
\r\n.
|
||
</para>
|
||
</sect3>
|
||
<sect3 id="auth-mechanisms-sha">
|
||
<title>DBUS_COOKIE_SHA1</title>
|
||
<para>
|
||
DBUS_COOKIE_SHA1 is a D-Bus-specific SASL mechanism. Its
|
||
reference implementation is part of the reference implementation
|
||
of D-Bus.
|
||
</para>
|
||
<para>
|
||
This mechanism is designed to establish that a client
|
||
has the ability to read a private file owned by the user being
|
||
authenticated. If the client can prove that it has access to a secret
|
||
cookie stored in this file, then the client is authenticated.
|
||
Thus the security of DBUS_COOKIE_SHA1 depends on a secure home
|
||
directory. This is the recommended authentication mechanism
|
||
for platforms and configurations where EXTERNAL cannot be used.
|
||
</para>
|
||
<para>
|
||
Throughout this description, "hex encoding" must output the digits
|
||
from a to f in lower-case; the digits A to F must not be used
|
||
in the DBUS_COOKIE_SHA1 mechanism.
|
||
</para>
|
||
<para>
|
||
Authentication proceeds as follows:
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>
|
||
The client sends the username it would like to authenticate
|
||
as, hex-encoded.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>
|
||
The server sends the name of its "cookie context" (see below); a
|
||
space character; the integer ID of the secret cookie the client
|
||
must demonstrate knowledge of; a space character; then a
|
||
randomly-generated challenge string, all of this hex-encoded into
|
||
one, single string.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>
|
||
The client locates the cookie and generates its own
|
||
randomly-generated challenge string. The client then concatenates
|
||
the server's decoded challenge, a ":" character, its own challenge,
|
||
another ":" character, and the cookie. It computes the SHA-1 hash
|
||
of this composite string as a hex digest. It concatenates the
|
||
client's challenge string, a space character, and the SHA-1 hex
|
||
digest, hex-encodes the result and sends it back to the server.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>
|
||
The server generates the same concatenated string used by the
|
||
client and computes its SHA-1 hash. It compares the hash with
|
||
the hash received from the client; if the two hashes match, the
|
||
client is authenticated.
|
||
</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
</para>
|
||
<para>
|
||
Each server has a "cookie context," which is a name that identifies a
|
||
set of cookies that apply to that server. A sample context might be
|
||
"org_freedesktop_session_bus". Context names must be valid ASCII,
|
||
nonzero length, and may not contain the characters slash ("/"),
|
||
backslash ("\"), space (" "), newline ("\n"), carriage return ("\r"),
|
||
tab ("\t"), or period ("."). There is a default context,
|
||
"org_freedesktop_general" that's used by servers that do not specify
|
||
otherwise.
|
||
</para>
|
||
<para>
|
||
Cookies are stored in a user's home directory, in the directory
|
||
<filename>~/.dbus-keyrings/</filename>. This directory must
|
||
not be readable or writable by other users. If it is,
|
||
clients and servers must ignore it. The directory
|
||
contains cookie files named after the cookie context.
|
||
</para>
|
||
<para>
|
||
A cookie file contains one cookie per line. Each line
|
||
has three space-separated fields:
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>
|
||
The cookie ID number, which must be a non-negative integer and
|
||
may not be used twice in the same file.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>
|
||
The cookie's creation time, in UNIX seconds-since-the-epoch
|
||
format.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>
|
||
The cookie itself, a hex-encoded random block of bytes. The cookie
|
||
may be of any length, though obviously security increases
|
||
as the length increases.
|
||
</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
</para>
|
||
<para>
|
||
Only server processes modify the cookie file.
|
||
They must do so with this procedure:
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>
|
||
Create a lockfile name by appending ".lock" to the name of the
|
||
cookie file. The server should attempt to create this file
|
||
using <literal>O_CREAT | O_EXCL</literal>. If file creation
|
||
fails, the lock fails. Servers should retry for a reasonable
|
||
period of time, then they may choose to delete an existing lock
|
||
to keep users from having to manually delete a stale
|
||
lock. <footnote><para>Lockfiles are used instead of real file
|
||
locking <literal>fcntl()</literal> because real locking
|
||
implementations are still flaky on network
|
||
filesystems.</para></footnote>
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>
|
||
Once the lockfile has been created, the server loads the cookie
|
||
file. It should then delete any cookies that are old (the
|
||
timeout can be fairly short), or more than a reasonable
|
||
time in the future (so that cookies never accidentally
|
||
become permanent, if the clock was set far into the future
|
||
at some point). The reference implementation deletes cookies
|
||
that are more than 5 minutes into the future, or more than
|
||
7 minutes in the past. For interoperability, using the
|
||
same arbitrary times in other implementations is suggested.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>
|
||
If no sufficiently recent cookies remain, the server
|
||
generates a new cookie. To avoid spurious authentication
|
||
failures, cookies that are close to their deletion time
|
||
should not be used for new authentication operations.
|
||
For example, this avoids a client starting to use a cookie
|
||
whose age is 6m59s, and having authentication subsequently
|
||
fail because it takes 2 seconds, during which time the
|
||
cookie's age became 7m01s, greater than 7 minutes, causing
|
||
the server to delete it. The reference implementation
|
||
generates a new cookie whenever the most recent cookie is
|
||
older than 5 minutes, giving clients at least 2 minutes
|
||
to finish authentication. For interoperability, using the
|
||
same arbitrary time in other implementations is suggested.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>
|
||
The pruned and possibly added-to cookie file
|
||
must be resaved atomically (using a temporary
|
||
file which is rename()'d).
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>
|
||
The lock must be dropped by deleting the lockfile.
|
||
</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
</para>
|
||
<para>
|
||
Clients need not lock the file in order to load it,
|
||
because servers are required to save the file atomically.
|
||
</para>
|
||
</sect3>
|
||
<sect3 id="auth-mechanisms-anonymous">
|
||
<title>ANONYMOUS</title>
|
||
<para>
|
||
The ANONYMOUS mechanism is defined in <ulink
|
||
url="https://tools.ietf.org/html/rfc4505">RFC 4505 "Anonymous
|
||
Simple Authentication and Security Layer (SASL)
|
||
Mechanism"</ulink>.
|
||
It does not perform any authentication at all, and should not
|
||
be accepted by message buses. However, it might sometimes be
|
||
useful for non-message-bus uses of D-Bus.
|
||
</para>
|
||
</sect3>
|
||
</sect2>
|
||
</sect1>
|
||
<sect1 id="addresses">
|
||
<title>Server Addresses</title>
|
||
<para>
|
||
Server addresses consist of a transport name followed by a colon, and
|
||
then an optional, comma-separated list of keys and values in the form key=value.
|
||
Each value is escaped.
|
||
</para>
|
||
<para>
|
||
For example:
|
||
<programlisting>unix:path=/tmp/dbus-test</programlisting>
|
||
Which is the address to a unix socket with the path /tmp/dbus-test.
|
||
</para>
|
||
<para>
|
||
Value escaping is similar to URI escaping but simpler.
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>
|
||
The set of optionally-escaped bytes is:
|
||
<literal>[-0-9A-Za-z_/.\*]</literal>. To escape, each
|
||
<emphasis>byte</emphasis> (note, not character) which is not in the
|
||
set of optionally-escaped bytes must be replaced with an ASCII
|
||
percent (<literal>%</literal>) and the value of the byte in hex.
|
||
The hex value must always be two digits, even if the first digit is
|
||
zero. The optionally-escaped bytes may be escaped if desired.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>
|
||
To unescape, append each byte in the value; if a byte is an ASCII
|
||
percent (<literal>%</literal>) character then append the following
|
||
hex value instead. It is an error if a <literal>%</literal> byte
|
||
does not have two hex digits following. It is an error if a
|
||
non-optionally-escaped byte is seen unescaped.
|
||
</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
The set of optionally-escaped bytes is intended to preserve address
|
||
readability and convenience.
|
||
</para>
|
||
|
||
<para>
|
||
A server may specify a key-value pair with the key <literal>guid</literal>
|
||
and the value a hex-encoded 16-byte sequence. <xref linkend="uuids"/>
|
||
describes the format of the <literal>guid</literal> field. If present,
|
||
this UUID may be used to distinguish one server address from another. A
|
||
server should use a different UUID for each address it listens on. For
|
||
example, if a message bus daemon offers both UNIX domain socket and TCP
|
||
connections, but treats clients the same regardless of how they connect,
|
||
those two connections are equivalent post-connection but should have
|
||
distinct UUIDs to distinguish the kinds of connection.
|
||
</para>
|
||
|
||
<para>
|
||
The intent of the address UUID feature is to allow a client to avoid
|
||
opening multiple identical connections to the same server, by allowing the
|
||
client to check whether an address corresponds to an already-existing
|
||
connection. Comparing two addresses is insufficient, because addresses
|
||
can be recycled by distinct servers, and equivalent addresses may look
|
||
different if simply compared as strings (for example, the host in a TCP
|
||
address can be given as an IP address or as a hostname).
|
||
</para>
|
||
|
||
<para>
|
||
Note that the address key is <literal>guid</literal> even though the
|
||
rest of the API and documentation says "UUID," for historical reasons.
|
||
</para>
|
||
|
||
<para>
|
||
[FIXME clarify if attempting to connect to each is a requirement
|
||
or just a suggestion]
|
||
When connecting to a server, multiple server addresses can be
|
||
separated by a semi-colon. The library will then try to connect
|
||
to the first address and if that fails, it'll try to connect to
|
||
the next one specified, and so forth. For example
|
||
<programlisting>unix:path=/tmp/dbus-test;unix:path=/tmp/dbus-test2</programlisting>
|
||
</para>
|
||
|
||
<para>
|
||
Some addresses are <firstterm>connectable</firstterm>. A connectable
|
||
address is one containing enough information for a client to connect
|
||
to it. For instance, <literal>tcp:host=127.0.0.1,port=4242</literal>
|
||
is a connectable address. It is not necessarily possible to listen
|
||
on every connectable address: for instance, it is not possible to
|
||
listen on a <literal>unixexec:</literal> address.
|
||
</para>
|
||
|
||
<para>
|
||
Some addresses are <firstterm>listenable</firstterm>. A listenable
|
||
address is one containing enough information for a server to listen on
|
||
it, producing a connectable address (which may differ from the
|
||
original address). Many listenable addresses are not connectable:
|
||
for instance, <literal>tcp:host=127.0.0.1</literal>
|
||
is listenable, but not connectable (because it does not specify
|
||
a port number).
|
||
</para>
|
||
|
||
<para>
|
||
Listening on an address that is not connectable will result in a
|
||
connectable address that is not the same as the listenable address.
|
||
For instance, listening on <literal>tcp:host=127.0.0.1</literal>
|
||
might result in the connectable address
|
||
<literal>tcp:host=127.0.0.1,port=30958</literal>,
|
||
listening on <literal>unix:tmpdir=/tmp</literal>
|
||
might result in the connectable address
|
||
<literal>unix:abstract=/tmp/dbus-U8OSdmf7</literal>, or
|
||
listening on <literal>unix:runtime=yes</literal>
|
||
might result in the connectable address
|
||
<literal>unix:path=/run/user/1234/bus</literal>.
|
||
</para>
|
||
</sect1>
|
||
|
||
<sect1 id="transports">
|
||
<title>Transports</title>
|
||
<para>
|
||
[FIXME we need to specify in detail each transport and its possible arguments]
|
||
|
||
Current transports include: unix domain sockets (including
|
||
abstract namespace on linux), launchd, systemd, TCP/IP, an executed subprocess and a debug/testing transport
|
||
using in-process pipes. Future possible transports include one that
|
||
tunnels over X11 protocol.
|
||
</para>
|
||
|
||
<sect2 id="transports-unix-domain-sockets">
|
||
<title>Unix Domain Sockets</title>
|
||
<para>
|
||
Unix domain sockets can be either paths in the file system or on Linux
|
||
kernels, they can be abstract which are similar to paths but
|
||
do not show up in the file system.
|
||
</para>
|
||
|
||
<para>
|
||
When a socket is opened by the D-Bus library it truncates the path
|
||
name right before the first trailing Nul byte. This is true for both
|
||
normal paths and abstract paths. Note that this is a departure from
|
||
previous versions of D-Bus that would create sockets with a fixed
|
||
length path name. Names which were shorter than the fixed length
|
||
would be padded by Nul bytes.
|
||
</para>
|
||
<para>
|
||
Unix domain sockets are not available on Windows.
|
||
On all other platforms, they are the recommended transport for
|
||
D-Bus, either used alone or in conjunction with
|
||
<link linkend="transports-systemd">systemd</link> or
|
||
<link linkend="transports-launchd">launchd</link> addresses.
|
||
</para>
|
||
<para>
|
||
Unix addresses that specify <literal>path</literal> or
|
||
<literal>abstract</literal> are both listenable and connectable.
|
||
Unix addresses that specify <literal>tmpdir</literal>
|
||
or <literal>dir</literal> are only
|
||
listenable: the corresponding connectable address will specify
|
||
either <literal>path</literal> or <literal>abstract</literal>.
|
||
Similarly, Unix addresses that specify <literal>runtime</literal>
|
||
are only listenable, and the corresponding connectable address
|
||
will specify <literal>path</literal>.
|
||
</para>
|
||
<sect3 id="transports-unix-domain-sockets-addresses">
|
||
<title>Server Address Format</title>
|
||
<para>
|
||
Unix domain socket addresses are identified by the "unix:" prefix
|
||
and support the following key/value pairs:
|
||
</para>
|
||
<informaltable>
|
||
<tgroup cols="3">
|
||
<thead>
|
||
<row>
|
||
<entry>Name</entry>
|
||
<entry>Values</entry>
|
||
<entry>Description</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row>
|
||
<entry>path</entry>
|
||
<entry>(path)</entry>
|
||
<entry>
|
||
Path of the unix domain socket.
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry>dir</entry>
|
||
<entry>(path)</entry>
|
||
<entry>
|
||
Directory in which a socket file with a random file name
|
||
starting with 'dbus-' will be created by the server. This key
|
||
can only be used in server addresses, not in client addresses;
|
||
the resulting client address will have the "path" key instead.
|
||
be set.
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry>tmpdir</entry>
|
||
<entry>(path)</entry>
|
||
<entry>
|
||
The same as "dir", except that on platforms with
|
||
abstract sockets, the server may attempt to create an
|
||
abstract socket whose name starts with this directory instead
|
||
of a path-based socket. This key can only be used in server
|
||
addresses, not in client addresses; the resulting client address
|
||
will have the "abstract" or "path" key instead.
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry>abstract</entry>
|
||
<entry>(string)</entry>
|
||
<entry>
|
||
Unique string in the abstract namespace, often syntactically
|
||
resembling a path but unconnected to the filesystem namespace.
|
||
This key is only supported on platforms with abstract Unix
|
||
sockets, of which Linux is the only known example.
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry>runtime</entry>
|
||
<entry><literal>yes</literal></entry>
|
||
<entry>If given, This key can only be used in server addresses, not in client addresses. If set, its value must be <literal>yes</literal>. This is typically used in an address string like <literal>unix:runtime=yes;unix:tmpdir=/tmp</literal> so that there can be a fallback if <literal>XDG_RUNTIME_DIR</literal> is not set.</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
<para>
|
||
Exactly one of the keys <literal>path</literal>,
|
||
<literal>abstract</literal>, <literal>runtime</literal>,
|
||
<literal>dir</literal> or <literal>tmpdir</literal> must be provided.
|
||
</para>
|
||
</sect3>
|
||
</sect2>
|
||
<sect2 id="transports-launchd">
|
||
<title>launchd</title>
|
||
<para>
|
||
launchd is an open-source server management system that replaces init, inetd
|
||
and cron on Apple Mac OS X versions 10.4 and above. It provides a common session
|
||
bus address for each user and deprecates the X11-enabled D-Bus launcher on OSX.
|
||
</para>
|
||
|
||
<para>
|
||
launchd allocates a socket and provides it with the unix path through the
|
||
DBUS_LAUNCHD_SESSION_BUS_SOCKET variable in launchd's environment. Every process
|
||
spawned by launchd (or dbus-daemon, if it was started by launchd) can access
|
||
it through its environment.
|
||
Other processes can query for the launchd socket by executing:
|
||
$ launchctl getenv DBUS_LAUNCHD_SESSION_BUS_SOCKET
|
||
This is normally done by the D-Bus client library so doesn't have to be done
|
||
manually.
|
||
</para>
|
||
<para>
|
||
launchd is not available on Microsoft Windows.
|
||
</para>
|
||
<para>
|
||
launchd addresses are listenable and connectable.
|
||
</para>
|
||
<sect3 id="transports-launchd-addresses">
|
||
<title>Server Address Format</title>
|
||
<para>
|
||
launchd addresses are identified by the "launchd:" prefix
|
||
and support the following key/value pairs:
|
||
</para>
|
||
<informaltable>
|
||
<tgroup cols="3">
|
||
<thead>
|
||
<row>
|
||
<entry>Name</entry>
|
||
<entry>Values</entry>
|
||
<entry>Description</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row>
|
||
<entry>env</entry>
|
||
<entry>(environment variable)</entry>
|
||
<entry>path of the unix domain socket for the launchd created dbus-daemon.</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
<para>
|
||
The <literal>env</literal> key is required.
|
||
</para>
|
||
</sect3>
|
||
</sect2>
|
||
<sect2 id="transports-systemd">
|
||
<title>systemd</title>
|
||
<para>
|
||
systemd is an open-source server management system that
|
||
replaces init and inetd on newer Linux systems. It supports
|
||
socket activation. The D-Bus systemd transport is used to acquire
|
||
socket activation file descriptors from systemd and use them
|
||
as D-Bus transport when the current process is spawned by
|
||
socket activation from it.
|
||
</para>
|
||
<para>
|
||
The systemd transport accepts only one or more Unix domain or
|
||
TCP streams sockets passed in via socket activation. Using
|
||
Unix domain sockets is strongly recommended.
|
||
</para>
|
||
<para>
|
||
The systemd transport is not available on non-Linux operating systems.
|
||
</para>
|
||
<para>
|
||
The systemd transport defines no parameter keys.
|
||
</para>
|
||
<para>
|
||
systemd addresses are listenable, but not connectable. The
|
||
corresponding connectable address is the <literal>unix</literal>
|
||
or <literal>tcp</literal> address of the socket.
|
||
</para>
|
||
</sect2>
|
||
<sect2 id="transports-tcp-sockets">
|
||
<title>TCP Sockets</title>
|
||
<para>
|
||
The tcp transport provides TCP/IP based connections between clients
|
||
located on the same or different hosts.
|
||
</para>
|
||
<para>
|
||
Similar to remote X11, the TCP transport has no integrity or
|
||
confidentiality protection, so it should normally only be
|
||
used across the local loopback interface, for example using an
|
||
address like <literal>tcp:host=127.0.0.1</literal> or
|
||
<literal>tcp:host=localhost</literal>. In particular,
|
||
configuring the well-known system bus or the well-known session
|
||
bus to listen on a non-loopback TCP address is insecure.
|
||
</para>
|
||
<para>
|
||
On Windows and most Unix platforms, the TCP stack is unable to transfer
|
||
credentials over a TCP connection, so the
|
||
<link linkend="auth-mechanisms-external">EXTERNAL</link>
|
||
authentication mechanism does not normally work for this transport
|
||
(although the reference implementation of D-Bus is able to identify
|
||
loopback TCPv4 connections on Windows by their port number,
|
||
partially enabling the EXTERNAL mechanism).
|
||
The <link linkend="auth-mechanisms-sha">DBUS_COOKIE_SHA1</link>
|
||
mechanism is normally used instead.
|
||
</para>
|
||
<para>
|
||
Developers are sometimes tempted to use remote TCP as a debugging
|
||
tool. However, if this functionality is left enabled in finished
|
||
products, the result will be dangerously insecure. Instead of
|
||
using remote TCP, developers should <ulink
|
||
url="https://lists.freedesktop.org/archives/dbus/2018-April/017447.html"
|
||
>relay connections via Secure Shell or a similar protocol</ulink>.
|
||
<!-- TODO: Ideally someone would write a more formal guide to
|
||
remote D-Bus debugging, and we could link to that instead -->
|
||
</para>
|
||
<para>
|
||
Remote TCP connections were historically sometimes used to share
|
||
a single session bus between login sessions of the same user on
|
||
different machines within a trusted local area network, in
|
||
conjunction with unencrypted remote X11, a NFS-shared home
|
||
directory and NIS (YP) authentication. This is insecure against
|
||
an attacker on the same LAN and should be considered strongly
|
||
deprecated; more specifically, it is insecure in the same ways
|
||
and for the same reasons as unencrypted remote X11 and NFSv2/NFSv3.
|
||
The D-Bus maintainers
|
||
recommend using a separate session bus per (user, machine) pair,
|
||
only accessible from within that machine.
|
||
</para>
|
||
<para>
|
||
All <literal>tcp</literal> addresses are listenable.
|
||
<literal>tcp</literal> addresses in which both
|
||
<literal>host</literal> and <literal>port</literal> are
|
||
specified, and <literal>port</literal> is non-zero,
|
||
are also connectable.
|
||
</para>
|
||
<sect3 id="transports-tcp-sockets-addresses">
|
||
<title>Server Address Format</title>
|
||
<para>
|
||
TCP/IP socket addresses are identified by the "tcp:" prefix
|
||
and support the following key/value pairs:
|
||
</para>
|
||
<informaltable>
|
||
<tgroup cols="3">
|
||
<thead>
|
||
<row>
|
||
<entry>Name</entry>
|
||
<entry>Values</entry>
|
||
<entry>Description</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row>
|
||
<entry>host</entry>
|
||
<entry>(string)</entry>
|
||
<entry>DNS name or IP address</entry>
|
||
</row>
|
||
<row>
|
||
<entry>bind</entry>
|
||
<entry>(string)</entry>
|
||
<entry>Used in a listenable address to configure the interface
|
||
on which the server will listen: either the IP address of one of
|
||
the local machine's interfaces (most commonly <literal>127.0.0.1
|
||
</literal>), or a DNS name that resolves to one of those IP
|
||
addresses, or '*' to listen on all interfaces simultaneously.
|
||
If not specified, the default is the same value as "host".
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry>port</entry>
|
||
<entry>(number)</entry>
|
||
<entry>The tcp port the server will open. A zero value let the server
|
||
choose a free port provided from the underlaying operating system.
|
||
libdbus is able to retrieve the real used port from the server.
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry>family</entry>
|
||
<entry>(string)</entry>
|
||
<entry>If set, provide the type of socket family either "ipv4" or "ipv6". If unset, the family is unspecified.</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
</sect3>
|
||
</sect2>
|
||
<sect2 id="transports-nonce-tcp-sockets">
|
||
<title>Nonce-authenticated TCP Sockets</title>
|
||
<para>
|
||
The nonce-tcp transport provides a modified TCP transport using a
|
||
simple authentication mechanism, to ensure that only clients with read
|
||
access to a certain location in the filesystem can connect to the server.
|
||
The server writes a secret, the nonce, to a file and an incoming client
|
||
connection is only accepted if the client sends the nonce right after
|
||
the connect. The nonce mechanism requires no setup and is orthogonal to
|
||
the higher-level authentication mechanisms described in the
|
||
Authentication section.
|
||
</para>
|
||
<para>
|
||
The nonce-tcp transport is conceptually similar to a combination
|
||
of the <link linkend="auth-mechanisms-sha">DBUS_COOKIE_SHA1</link>
|
||
authentication mechanism and the
|
||
<link linkend="transports-tcp-sockets">tcp</link> transport,
|
||
and appears to have originally been implemented as a result of
|
||
a misunderstanding of the SASL authentication mechanisms.
|
||
</para>
|
||
<para>
|
||
Like the ordinary tcp transport, the nonce-tcp transport has no
|
||
integrity or confidentiality protection, so it should normally
|
||
only be used across the local loopback interface, for example
|
||
using an address like <literal>tcp:host=127.0.0.1</literal> or
|
||
<literal>tcp:host=localhost</literal>. Other uses are insecure.
|
||
See <xref linkend="transports-tcp-sockets"/> for more
|
||
information on situations where these transports have been used,
|
||
and alternatives to these transports.
|
||
</para>
|
||
<para>
|
||
Implementations of D-Bus on Windows operating systems normally
|
||
use a nonce-tcp transport via the local loopback interface.
|
||
This is because the
|
||
<link linkend="transports-unix-domain-sockets">unix</link>
|
||
transport, which would otherwise be recommended, is not
|
||
available on these operating systems.
|
||
</para>
|
||
|
||
<para>
|
||
On start, the server generates a random 16 byte nonce and writes it
|
||
to a file in the user's temporary directory. The nonce file location
|
||
is published as part of the server's D-Bus address using the
|
||
"noncefile" key-value pair.
|
||
|
||
After an accept, the server reads 16 bytes from the socket. If the
|
||
read bytes do not match the nonce stored in the nonce file, the
|
||
server MUST immediately drop the connection.
|
||
If the nonce match the received byte sequence, the client is accepted
|
||
and the transport behaves like an ordinary tcp transport.
|
||
</para>
|
||
<para>
|
||
After a successful connect to the server socket, the client MUST read
|
||
the nonce from the file published by the server via the noncefile=
|
||
key-value pair and send it over the socket. After that, the
|
||
transport behaves like an ordinary tcp transport.
|
||
</para>
|
||
<para>
|
||
All nonce-tcp addresses are listenable. nonce-tcp addresses in which
|
||
<literal>host</literal>, <literal>port</literal> and
|
||
<literal>noncefile</literal> are all specified,
|
||
and <literal>port</literal> is nonzero, are also connectable.
|
||
</para>
|
||
<sect3 id="transports-nonce-tcp-sockets-addresses">
|
||
<title>Server Address Format</title>
|
||
<para>
|
||
Nonce TCP/IP socket addresses uses the "nonce-tcp:" prefix
|
||
and support the following key/value pairs:
|
||
</para>
|
||
<informaltable>
|
||
<tgroup cols="3">
|
||
<thead>
|
||
<row>
|
||
<entry>Name</entry>
|
||
<entry>Values</entry>
|
||
<entry>Description</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row>
|
||
<entry>host</entry>
|
||
<entry>(string)</entry>
|
||
<entry>DNS name or IP address</entry>
|
||
</row>
|
||
<row>
|
||
<entry>bind</entry>
|
||
<entry>(string)</entry>
|
||
<entry>The same as for tcp: addresses
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry>port</entry>
|
||
<entry>(number)</entry>
|
||
<entry>The tcp port the server will open. A zero value let the server
|
||
choose a free port provided from the underlaying operating system.
|
||
libdbus is able to retrieve the real used port from the server.
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry>family</entry>
|
||
<entry>(string)</entry>
|
||
<entry>If set, provide the type of socket family either "ipv4" or "ipv6". If unset, the family is unspecified.</entry>
|
||
</row>
|
||
<row>
|
||
<entry>noncefile</entry>
|
||
<entry>(path)</entry>
|
||
<entry>File location containing the secret.
|
||
This is only meaningful in connectable addresses:
|
||
a listening D-Bus server that offers this transport
|
||
will always create a new nonce file.</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
</sect3>
|
||
</sect2>
|
||
<sect2 id="transports-exec">
|
||
<title>Executed Subprocesses on Unix</title>
|
||
<para>
|
||
This transport forks off a process and connects its standard
|
||
input and standard output with an anonymous Unix domain
|
||
socket. This socket is then used for communication by the
|
||
transport. This transport may be used to use out-of-process
|
||
forwarder programs as basis for the D-Bus protocol.
|
||
</para>
|
||
<para>
|
||
The forked process will inherit the standard error output and
|
||
process group from the parent process.
|
||
</para>
|
||
<para>
|
||
Executed subprocesses are not available on Windows.
|
||
</para>
|
||
<para>
|
||
<literal>unixexec</literal> addresses are connectable, but are not
|
||
listenable.
|
||
</para>
|
||
<sect3 id="transports-exec-addresses">
|
||
<title>Server Address Format</title>
|
||
<para>
|
||
Executed subprocess addresses are identified by the "unixexec:" prefix
|
||
and support the following key/value pairs:
|
||
</para>
|
||
<informaltable>
|
||
<tgroup cols="3">
|
||
<thead>
|
||
<row>
|
||
<entry>Name</entry>
|
||
<entry>Values</entry>
|
||
<entry>Description</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row>
|
||
<entry>path</entry>
|
||
<entry>(path)</entry>
|
||
<entry>Path of the binary to execute, either an absolute
|
||
path or a binary name that is searched for in the default
|
||
search path of the OS. This corresponds to the first
|
||
argument of execlp(). This key is mandatory.</entry>
|
||
</row>
|
||
<row>
|
||
<entry>argv0</entry>
|
||
<entry>(string)</entry>
|
||
<entry>The program name to use when executing the
|
||
binary. If omitted the same value as specified for path=
|
||
will be used. This corresponds to the second argument of
|
||
execlp().</entry>
|
||
</row>
|
||
<row>
|
||
<entry>argv1, argv2, ...</entry>
|
||
<entry>(string)</entry>
|
||
<entry>Arguments to pass to the binary. This corresponds
|
||
to the third and later arguments of execlp(). If a
|
||
specific argvX is not specified no further argvY for Y > X
|
||
are taken into account.</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
</sect3>
|
||
</sect2>
|
||
</sect1>
|
||
<sect1 id="meta-transports">
|
||
<title>Meta Transports</title>
|
||
<para>
|
||
Meta transports are a kind of transport with special enhancements or
|
||
behavior. Currently available meta transports include: autolaunch
|
||
</para>
|
||
|
||
<sect2 id="meta-transports-autolaunch">
|
||
<title>Autolaunch</title>
|
||
<para>The autolaunch transport provides a way for dbus clients to autodetect
|
||
a running dbus session bus and to autolaunch a session bus if not present.
|
||
</para>
|
||
<para>
|
||
On Unix, <literal>autolaunch</literal> addresses are connectable,
|
||
but not listenable.
|
||
</para>
|
||
<para>
|
||
On Windows, <literal>autolaunch</literal> addresses are both
|
||
connectable and listenable.
|
||
</para>
|
||
|
||
<sect3 id="meta-transports-autolaunch-addresses">
|
||
<title>Server Address Format</title>
|
||
<para>
|
||
Autolaunch addresses uses the "autolaunch:" prefix and support the
|
||
following key/value pairs:
|
||
</para>
|
||
<informaltable>
|
||
<tgroup cols="3">
|
||
<thead>
|
||
<row>
|
||
<entry>Name</entry>
|
||
<entry>Values</entry>
|
||
<entry>Description</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row>
|
||
<entry>scope</entry>
|
||
<entry>(string)</entry>
|
||
<entry>scope of autolaunch (Windows only)
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>
|
||
"*install-path" - limit session bus to dbus installation path.
|
||
The dbus installation path is determined from the location of
|
||
the shared dbus library. If the library is located in a 'bin'
|
||
subdirectory the installation root is the directory above,
|
||
otherwise the directory where the library lives is taken as
|
||
installation root.
|
||
<programlisting>
|
||
<install-root>/bin/[lib]dbus-1.dll
|
||
<install-root>/[lib]dbus-1.dll
|
||
</programlisting>
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>
|
||
"*user" - limit session bus to the recent user.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>
|
||
other values - specify dedicated session bus like "release",
|
||
"debug" or other
|
||
</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
</sect3>
|
||
|
||
<sect3 id="meta-transports-autolaunch-windows-implementation">
|
||
<title>Windows implementation</title>
|
||
<para>
|
||
On start, the server opens a platform specific transport, creates a mutex
|
||
and a shared memory section containing the related session bus address.
|
||
This mutex will be inspected by the dbus client library to detect a
|
||
running dbus session bus. The access to the mutex and the shared memory
|
||
section are protected by global locks.
|
||
</para>
|
||
<para>
|
||
In the recent implementation the autolaunch transport uses a tcp transport
|
||
on localhost with a port choosen from the operating system. This detail may
|
||
change in the future.
|
||
</para>
|
||
<para>
|
||
Disclaimer: The recent implementation is in an early state and may not
|
||
work in all cirumstances and/or may have security issues. Because of this
|
||
the implementation is not documentated yet.
|
||
</para>
|
||
</sect3>
|
||
</sect2>
|
||
</sect1>
|
||
|
||
<sect1 id="uuids">
|
||
<title>UUIDs</title>
|
||
<para>
|
||
A working D-Bus implementation uses universally-unique IDs in two places.
|
||
First, each server address has a UUID identifying the address,
|
||
as described in <xref linkend="addresses"/>. Second, each operating
|
||
system kernel instance running a D-Bus client or server has a UUID
|
||
identifying that kernel, retrieved by invoking the method
|
||
org.freedesktop.DBus.Peer.GetMachineId() (see <xref
|
||
linkend="standard-interfaces-peer"/>).
|
||
</para>
|
||
<para>
|
||
The term "UUID" in this document is intended literally, i.e. an
|
||
identifier that is universally unique. It is not intended to refer to
|
||
RFC4122, and in fact the D-Bus UUID is not compatible with that RFC.
|
||
</para>
|
||
<para>
|
||
The UUID must contain 128 bits of data and be hex-encoded. The
|
||
hex-encoded string may not contain hyphens or other non-hex-digit
|
||
characters, and it must be exactly 32 characters long. To generate a
|
||
UUID, the current reference implementation concatenates 96 bits of random
|
||
data followed by the 32-bit time in seconds since the UNIX epoch (in big
|
||
endian byte order).
|
||
</para>
|
||
<para>
|
||
It would also be acceptable and probably better to simply generate 128
|
||
bits of random data, as long as the random number generator is of high
|
||
quality. The timestamp could conceivably help if the random bits are not
|
||
very random. With a quality random number generator, collisions are
|
||
extremely unlikely even with only 96 bits, so it's somewhat academic.
|
||
</para>
|
||
<para>
|
||
Implementations should, however, stick to random data for the first 96 bits
|
||
of the UUID.
|
||
</para>
|
||
</sect1>
|
||
|
||
<sect1 id="standard-interfaces">
|
||
<title>Standard Interfaces</title>
|
||
<para>
|
||
See <xref linkend="message-protocol-types-notation"/> for details on
|
||
the notation used in this section. There are some standard interfaces
|
||
that may be useful across various D-Bus applications.
|
||
</para>
|
||
<sect2 id="standard-interfaces-peer">
|
||
<title><literal>org.freedesktop.DBus.Peer</literal></title>
|
||
<para>
|
||
The <literal>org.freedesktop.DBus.Peer</literal> interface
|
||
has two methods:
|
||
<programlisting>
|
||
org.freedesktop.DBus.Peer.Ping ()
|
||
org.freedesktop.DBus.Peer.GetMachineId (out STRING machine_uuid)
|
||
</programlisting>
|
||
</para>
|
||
<para>
|
||
On receipt of the <literal>METHOD_CALL</literal> message
|
||
<literal>org.freedesktop.DBus.Peer.Ping</literal>, an application should do
|
||
nothing other than reply with a <literal>METHOD_RETURN</literal> as
|
||
usual. It does not matter which object path a ping is sent to. The
|
||
reference implementation handles this method automatically.
|
||
</para>
|
||
<para>
|
||
On receipt of the <literal>METHOD_CALL</literal> message
|
||
<literal>org.freedesktop.DBus.Peer.GetMachineId</literal>, an application should
|
||
reply with a <literal>METHOD_RETURN</literal> containing a hex-encoded
|
||
UUID representing the identity of the machine the process is running on.
|
||
This UUID must be the same for all processes on a single system at least
|
||
until that system next reboots. It should be the same across reboots
|
||
if possible, but this is not always possible to implement and is not
|
||
guaranteed.
|
||
It does not matter which object path a GetMachineId is sent to. The
|
||
reference implementation handles this method automatically.
|
||
</para>
|
||
<para>
|
||
On Unix, implementations should try to read the machine ID from
|
||
<literal>/var/lib/dbus/machine-id</literal> and
|
||
<literal>/etc/machine-id</literal>. The latter is
|
||
<ulink url='https://www.freedesktop.org/software/systemd/man/machine-id.html'>
|
||
defined by systemd</ulink>, but systems not using systemd may provide
|
||
an equivalent file.
|
||
If both exist, they are expected to have the same contents, and if they
|
||
differ, the spec does not define which takes precedence (the reference
|
||
implementation prefers <literal>/var/lib/dbus/machine-id</literal>,
|
||
but sd-bus does not).
|
||
</para>
|
||
<para>
|
||
On Windows, the hardware profile GUID is used as the machine ID,
|
||
with the punctuation removed. This can be obtained with the
|
||
<ulink url='https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-getcurrenthwprofilea'>
|
||
<function>GetCurrentHwProfile</function></ulink> function.
|
||
</para>
|
||
<para>
|
||
The UUID is intended to be per-instance-of-the-operating-system, so may represent
|
||
a virtual machine running on a hypervisor, rather than a physical machine.
|
||
Basically if two processes see the same UUID, they should also see the same
|
||
shared memory, UNIX domain sockets, process IDs, and other features that require
|
||
a running OS kernel in common between the processes.
|
||
</para>
|
||
<para>
|
||
The UUID is often used where other programs might use a hostname. Hostnames
|
||
can change without rebooting, however, or just be "localhost" - so the UUID
|
||
is more robust.
|
||
</para>
|
||
<para>
|
||
<xref linkend="uuids"/> explains the format of the UUID.
|
||
</para>
|
||
</sect2>
|
||
|
||
<sect2 id="standard-interfaces-introspectable">
|
||
<title><literal>org.freedesktop.DBus.Introspectable</literal></title>
|
||
<para>
|
||
This interface has one method:
|
||
<programlisting>
|
||
org.freedesktop.DBus.Introspectable.Introspect (out STRING xml_data)
|
||
</programlisting>
|
||
</para>
|
||
<para>
|
||
Objects instances may implement
|
||
<literal>Introspect</literal> which returns an XML description of
|
||
the object, including its interfaces (with signals and methods), objects
|
||
below it in the object path tree, and its properties.
|
||
</para>
|
||
<para>
|
||
<xref linkend="introspection-format"/> describes the format of this XML string.
|
||
</para>
|
||
</sect2>
|
||
<sect2 id="standard-interfaces-properties">
|
||
<title><literal>org.freedesktop.DBus.Properties</literal></title>
|
||
<para>
|
||
Many native APIs will have a concept of object <firstterm>properties</firstterm>
|
||
or <firstterm>attributes</firstterm>. These can be exposed via the
|
||
<literal>org.freedesktop.DBus.Properties</literal> interface.
|
||
</para>
|
||
<para>
|
||
<programlisting>
|
||
org.freedesktop.DBus.Properties.Get (in STRING interface_name,
|
||
in STRING property_name,
|
||
out VARIANT value);
|
||
org.freedesktop.DBus.Properties.Set (in STRING interface_name,
|
||
in STRING property_name,
|
||
in VARIANT value);
|
||
org.freedesktop.DBus.Properties.GetAll (in STRING interface_name,
|
||
out ARRAY of DICT_ENTRY<STRING,VARIANT> props);
|
||
</programlisting>
|
||
</para>
|
||
<para>
|
||
It is conventional to give D-Bus properties names consisting of
|
||
capitalized words without punctuation ("CamelCase"), like
|
||
<link linkend="message-protocol-names-member">member names</link>.
|
||
For instance, the GObject property
|
||
<literal>connection-status</literal> or the Qt property
|
||
<literal>connectionStatus</literal> could be represented on D-Bus
|
||
as <literal>ConnectionStatus</literal>.
|
||
</para>
|
||
<para>
|
||
Strictly speaking, D-Bus property names are not required to follow
|
||
the same naming restrictions as member names, but D-Bus property
|
||
names that would not be valid member names (in particular,
|
||
GObject-style dash-separated property names) can cause interoperability
|
||
problems and should be avoided.
|
||
</para>
|
||
<para>
|
||
The available properties and whether they are writable can be determined
|
||
by calling <literal>org.freedesktop.DBus.Introspectable.Introspect</literal>,
|
||
see <xref linkend="standard-interfaces-introspectable"/>.
|
||
</para>
|
||
<para>
|
||
An empty string may be provided for the interface name; in this case,
|
||
if there are multiple properties on an object with the same name,
|
||
the results are undefined (picking one by according to an arbitrary
|
||
deterministic rule, or returning an error, are the reasonable
|
||
possibilities).
|
||
</para>
|
||
<para>
|
||
If <literal>org.freedesktop.DBus.Properties.GetAll</literal> is called
|
||
with a valid interface name which contains no properties, an empty array
|
||
should be returned. If it is called with a valid interface name for
|
||
which some properties are not accessible to the caller (for example, due
|
||
to per-property access control implemented in the service), those
|
||
properties should be silently omitted from the result array.
|
||
If <literal>org.freedesktop.DBus.Properties.Get</literal> is called for
|
||
any such properties, an appropriate access control error should be
|
||
returned.
|
||
</para>
|
||
<para>
|
||
If one or more properties change on an object, the
|
||
<literal>org.freedesktop.DBus.Properties.PropertiesChanged</literal>
|
||
signal may be emitted (this signal was added in 0.14):
|
||
</para>
|
||
<para>
|
||
<programlisting>
|
||
org.freedesktop.DBus.Properties.PropertiesChanged (STRING interface_name,
|
||
ARRAY of DICT_ENTRY<STRING,VARIANT> changed_properties,
|
||
ARRAY<STRING> invalidated_properties);
|
||
</programlisting>
|
||
</para>
|
||
<para>
|
||
where <literal>changed_properties</literal> is a dictionary
|
||
containing the changed properties with the new values and
|
||
<literal>invalidated_properties</literal> is an array of
|
||
properties that changed but the value is not conveyed.
|
||
</para>
|
||
<para>
|
||
Whether the <literal>PropertiesChanged</literal> signal is
|
||
supported can be determined by calling
|
||
<literal>org.freedesktop.DBus.Introspectable.Introspect</literal>. Note
|
||
that the signal may be supported for an object but it may
|
||
differ how whether and how it is used on a per-property basis
|
||
(for e.g. performance or security reasons). Each property (or
|
||
the parent interface) must be annotated with the
|
||
<literal>org.freedesktop.DBus.Property.EmitsChangedSignal</literal>
|
||
annotation to convey this (usually the default value
|
||
<literal>true</literal> is sufficient meaning that the
|
||
annotation does not need to be used). See <xref
|
||
linkend="introspection-format"/> for details on this
|
||
annotation.
|
||
</para>
|
||
</sect2>
|
||
|
||
<sect2 id="standard-interfaces-objectmanager">
|
||
<title><literal>org.freedesktop.DBus.ObjectManager</literal></title>
|
||
<para>
|
||
An API can optionally make use of this interface for one or
|
||
more sub-trees of objects. The root of each sub-tree implements
|
||
this interface so other applications can get all objects,
|
||
interfaces and properties in a single method call. It is
|
||
appropriate to use this interface if users of the tree of
|
||
objects are expected to be interested in all interfaces of all
|
||
objects in the tree; a more granular API should be used if
|
||
users of the objects are expected to be interested in a small
|
||
subset of the objects, a small subset of their interfaces, or
|
||
both.
|
||
</para>
|
||
<para>
|
||
The method that applications can use to get all objects and
|
||
properties is <literal>GetManagedObjects</literal>:
|
||
</para>
|
||
<para>
|
||
<programlisting>
|
||
org.freedesktop.DBus.ObjectManager.GetManagedObjects (out ARRAY of DICT_ENTRY<OBJPATH,ARRAY of DICT_ENTRY<STRING,ARRAY of DICT_ENTRY<STRING,VARIANT>>> objpath_interfaces_and_properties);
|
||
</programlisting>
|
||
</para>
|
||
<para>
|
||
The return value of this method is a dict whose keys are
|
||
object paths. All returned object paths are children of the
|
||
object path implementing this interface, i.e. their object
|
||
paths start with the ObjectManager's object path plus '/'.
|
||
</para>
|
||
<para>
|
||
Each value is a dict whose keys are interfaces names. Each
|
||
value in this inner dict is the same dict that would be
|
||
returned by the <link
|
||
linkend="standard-interfaces-properties">org.freedesktop.DBus.Properties.GetAll()</link>
|
||
method for that combination of object path and interface. If
|
||
an interface has no properties, the empty dict is returned.
|
||
</para>
|
||
<para>
|
||
Changes are emitted using the following two signals:
|
||
</para>
|
||
<para>
|
||
<programlisting>
|
||
org.freedesktop.DBus.ObjectManager.InterfacesAdded (OBJPATH object_path,
|
||
ARRAY of DICT_ENTRY<STRING,ARRAY of DICT_ENTRY<STRING,VARIANT>> interfaces_and_properties);
|
||
org.freedesktop.DBus.ObjectManager.InterfacesRemoved (OBJPATH object_path,
|
||
ARRAY<STRING> interfaces);
|
||
</programlisting>
|
||
</para>
|
||
<para>
|
||
The <literal>InterfacesAdded</literal> signal is emitted when
|
||
either a new object is added or when an existing object gains
|
||
one or more interfaces. The
|
||
<literal>InterfacesRemoved</literal> signal is emitted
|
||
whenever an object is removed or it loses one or more
|
||
interfaces. The second parameter of the
|
||
<literal>InterfacesAdded</literal> signal contains a dict with
|
||
the interfaces and properties (if any) that have been added to
|
||
the given object path. Similarly, the second parameter of the
|
||
<literal>InterfacesRemoved</literal> signal contains an array
|
||
of the interfaces that were removed. Note that changes on
|
||
properties on existing interfaces are not reported using this
|
||
interface - an application should also monitor the existing <link
|
||
linkend="standard-interfaces-properties">PropertiesChanged</link>
|
||
signal on each object.
|
||
</para>
|
||
<para>
|
||
Applications SHOULD NOT export objects that are children of an
|
||
object (directly or otherwise) implementing this interface but
|
||
which are not returned in the reply from the
|
||
<literal>GetManagedObjects()</literal> method of this
|
||
interface on the given object.
|
||
</para>
|
||
<para>
|
||
The intent of the <literal>ObjectManager</literal> interface
|
||
is to make it easy to write a robust client
|
||
implementation. The trivial client implementation only needs
|
||
to make two method calls:
|
||
</para>
|
||
<para>
|
||
<programlisting>
|
||
org.freedesktop.DBus.AddMatch (bus_proxy,
|
||
"type='signal',sender='org.example.App2',path_namespace='/org/example/App2'");
|
||
objects = org.freedesktop.DBus.ObjectManager.GetManagedObjects (app_proxy);
|
||
</programlisting>
|
||
</para>
|
||
<para>
|
||
on the message bus and the remote application's
|
||
<literal>ObjectManager</literal>, respectively. Whenever a new
|
||
remote object is created (or an existing object gains a new
|
||
interface), the <literal>InterfacesAdded</literal> signal is
|
||
emitted, and since this signal contains all properties for the
|
||
interfaces, no calls to the
|
||
<literal>org.freedesktop.Properties</literal> interface on the
|
||
remote object are needed. Additionally, since the initial
|
||
<literal>AddMatch()</literal> rule already includes signal
|
||
messages from the newly created child object, no new
|
||
<literal>AddMatch()</literal> call is needed.
|
||
</para>
|
||
|
||
<para>
|
||
<emphasis>
|
||
The <literal>org.freedesktop.DBus.ObjectManager</literal>
|
||
interface was added in version 0.17 of the D-Bus
|
||
specification.
|
||
</emphasis>
|
||
</para>
|
||
</sect2>
|
||
</sect1>
|
||
|
||
<sect1 id="introspection-format">
|
||
<title>Introspection Data Format</title>
|
||
<para>
|
||
As described in <xref linkend="standard-interfaces-introspectable"/>,
|
||
objects may be introspected at runtime, returning an XML string
|
||
that describes the object. The same XML format may be used in
|
||
other contexts as well, for example as an "IDL" for generating
|
||
static language bindings.
|
||
</para>
|
||
<para>
|
||
Here is an example of introspection data:
|
||
<programlisting>
|
||
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
|
||
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
|
||
<node name="/com/example/sample_object0">
|
||
<interface name="com.example.SampleInterface0">
|
||
<method name="Frobate">
|
||
<arg name="foo" type="i" direction="in"/>
|
||
<arg name="bar" type="s" direction="out"/>
|
||
<arg name="baz" type="a{us}" direction="out"/>
|
||
<annotation name="org.freedesktop.DBus.Deprecated" value="true"/>
|
||
</method>
|
||
<method name="Bazify">
|
||
<arg name="bar" type="(iiu)" direction="in"/>
|
||
<arg name="bar" type="v" direction="out"/>
|
||
</method>
|
||
<method name="Mogrify">
|
||
<arg name="bar" type="(iiav)" direction="in"/>
|
||
</method>
|
||
<signal name="Changed">
|
||
<arg name="new_value" type="b"/>
|
||
</signal>
|
||
<property name="Bar" type="y" access="readwrite"/>
|
||
</interface>
|
||
<node name="child_of_sample_object"/>
|
||
<node name="another_child_of_sample_object"/>
|
||
</node>
|
||
</programlisting>
|
||
</para>
|
||
<para>
|
||
A more formal DTD and spec needs writing, but here are some quick notes.
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>
|
||
Only the root <node> element can omit the node name, as it's
|
||
known to be the object that was introspected. If the root
|
||
<node> does have a name attribute, it must be an absolute
|
||
object path. If child <node> have object paths, they must be
|
||
relative.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>
|
||
If a child <node> has any sub-elements, then they
|
||
must represent a complete introspection of the child.
|
||
If a child <node> is empty, then it may or may
|
||
not have sub-elements; the child must be introspected
|
||
in order to find out. The intent is that if an object
|
||
knows that its children are "fast" to introspect
|
||
it can go ahead and return their information, but
|
||
otherwise it can omit it.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>
|
||
The direction element on <arg> may be omitted,
|
||
in which case it defaults to "in" for method calls
|
||
and "out" for signals. Signals only allow "out"
|
||
so while direction may be specified, it's pointless.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>
|
||
The possible directions are "in" and "out",
|
||
unlike CORBA there is no "inout"
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>
|
||
The possible property access flags are
|
||
"readwrite", "read", and "write"
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>
|
||
Multiple interfaces can of course be listed for
|
||
one <node>.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>
|
||
The "name" attribute on arguments is optional.
|
||
</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
</para>
|
||
<para>
|
||
Method, interface, property, signal, and argument elements may have
|
||
"annotations", which are generic key/value pairs of metadata.
|
||
They are similar conceptually to Java's annotations and C# attributes.
|
||
Well-known annotations:
|
||
</para>
|
||
<informaltable>
|
||
<tgroup cols="3">
|
||
<thead>
|
||
<row>
|
||
<entry>Name</entry>
|
||
<entry>Values (separated by ,)</entry>
|
||
<entry>Description</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row>
|
||
<entry>org.freedesktop.DBus.Deprecated</entry>
|
||
<entry>true,false</entry>
|
||
<entry>Whether or not the entity is deprecated; defaults to false</entry>
|
||
</row>
|
||
<row>
|
||
<entry>org.freedesktop.DBus.GLib.CSymbol</entry>
|
||
<entry>(string)</entry>
|
||
<entry>The C symbol; may be used for methods and interfaces</entry>
|
||
</row>
|
||
<row>
|
||
<entry>org.freedesktop.DBus.Method.NoReply</entry>
|
||
<entry>true,false</entry>
|
||
<entry>If set, don't expect a reply to the method call; defaults to false.</entry>
|
||
</row>
|
||
<row>
|
||
<entry>org.freedesktop.DBus.Property.EmitsChangedSignal</entry>
|
||
<entry>true,invalidates,const,false</entry>
|
||
<entry>
|
||
<para>
|
||
If set to <literal>false</literal>, the
|
||
<literal>org.freedesktop.DBus.Properties.PropertiesChanged</literal>
|
||
signal, see <xref
|
||
linkend="standard-interfaces-properties"/> is not
|
||
guaranteed to be emitted if the property changes.
|
||
</para>
|
||
<para>
|
||
If set to <literal>const</literal> the property never
|
||
changes value during the lifetime of the object it
|
||
belongs to, and hence the signal is never emitted for
|
||
it.
|
||
</para>
|
||
<para>
|
||
If set to <literal>invalidates</literal> the signal
|
||
is emitted but the value is not included in the
|
||
signal.
|
||
</para>
|
||
<para>
|
||
If set to <literal>true</literal> the signal is
|
||
emitted with the value included.
|
||
</para>
|
||
<para>
|
||
The value for the annotation defaults to
|
||
<literal>true</literal> if the enclosing interface
|
||
element does not specify the annotation. Otherwise it
|
||
defaults to the value specified in the enclosing
|
||
interface element.
|
||
</para>
|
||
<para>
|
||
This annotation is intended to be used by code
|
||
generators to implement client-side caching of
|
||
property values. For all properties for which the
|
||
annotation is set to <literal>const</literal>,
|
||
<literal>invalidates</literal> or
|
||
<literal>true</literal> the client may
|
||
unconditionally cache the values as the properties
|
||
don't change or notifications are generated for them
|
||
if they do.
|
||
</para>
|
||
</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
</sect1>
|
||
<sect1 id="message-bus">
|
||
<title>Message Bus Specification</title>
|
||
<sect2 id="message-bus-overview">
|
||
<title>Message Bus Overview</title>
|
||
<para>
|
||
The message bus accepts connections from one or more applications.
|
||
Once connected, applications can exchange messages with other
|
||
applications that are also connected to the bus.
|
||
</para>
|
||
<para>
|
||
In order to route messages among connections, the message bus keeps a
|
||
mapping from names to connections. Each connection has one
|
||
unique-for-the-lifetime-of-the-bus name automatically assigned.
|
||
Applications may request additional names for a connection. Additional
|
||
names are usually "well-known names" such as
|
||
"com.example.TextEditor1". When a name is bound to a connection,
|
||
that connection is said to <firstterm>own</firstterm> the name.
|
||
</para>
|
||
<para>
|
||
The bus itself owns a special name,
|
||
<literal>org.freedesktop.DBus</literal>, with an object
|
||
located at <literal>/org/freedesktop/DBus</literal> that
|
||
implements the <literal>org.freedesktop.DBus</literal>
|
||
interface. This service allows applications to make
|
||
administrative requests of the bus itself. For example,
|
||
applications can ask the bus to assign a name to a connection.
|
||
</para>
|
||
<para>
|
||
Each name may have <firstterm>queued owners</firstterm>. When an
|
||
application requests a name for a connection and the name is already in
|
||
use, the bus will optionally add the connection to a queue waiting for
|
||
the name. If the current owner of the name disconnects or releases
|
||
the name, the next connection in the queue will become the new owner.
|
||
</para>
|
||
|
||
<para>
|
||
This feature causes the right thing to happen if you start two text
|
||
editors for example; the first one may request "com.example.TextEditor1",
|
||
and the second will be queued as a possible owner of that name. When
|
||
the first exits, the second will take over.
|
||
</para>
|
||
|
||
<para>
|
||
Applications may send <firstterm>unicast messages</firstterm> to
|
||
a specific recipient or to the message bus itself, or
|
||
<firstterm>broadcast messages</firstterm> to all interested recipients.
|
||
See <xref linkend="message-bus-routing"/> for details.
|
||
</para>
|
||
</sect2>
|
||
|
||
<sect2 id="message-bus-names">
|
||
<title>Message Bus Names</title>
|
||
<para>
|
||
Each connection has at least one name, assigned at connection time and
|
||
returned in response to the
|
||
<literal>org.freedesktop.DBus.Hello</literal> method call. This
|
||
automatically-assigned name is called the connection's <firstterm>unique
|
||
name</firstterm>. Unique names are never reused for two different
|
||
connections to the same bus.
|
||
</para>
|
||
<para>
|
||
Ownership of a unique name is a prerequisite for interaction with
|
||
the message bus. It logically follows that the unique name is always
|
||
the first name that an application comes to own, and the last
|
||
one that it loses ownership of.
|
||
</para>
|
||
<para>
|
||
Unique connection names must begin with the character ':' (ASCII colon
|
||
character); bus names that are not unique names must not begin
|
||
with this character. (The bus must reject any attempt by an application
|
||
to manually request a name beginning with ':'.) This restriction
|
||
categorically prevents "spoofing"; messages sent to a unique name
|
||
will always go to the expected connection.
|
||
</para>
|
||
<para>
|
||
When a connection is closed, all the names that it owns are deleted (or
|
||
transferred to the next connection in the queue if any).
|
||
</para>
|
||
<para>
|
||
A connection can request additional names to be associated with it using
|
||
the <literal>org.freedesktop.DBus.RequestName</literal> message. <xref
|
||
linkend="message-protocol-names-bus"/> describes the format of a valid
|
||
name. These names can be released again using the
|
||
<literal>org.freedesktop.DBus.ReleaseName</literal> message.
|
||
</para>
|
||
</sect2>
|
||
|
||
<sect2 id="message-bus-routing">
|
||
<title>Message Bus Message Routing</title>
|
||
|
||
<para>
|
||
Messages may have a <literal>DESTINATION</literal> field (see <xref
|
||
linkend="message-protocol-header-fields"/>), resulting in a
|
||
<firstterm>unicast message</firstterm>. If the
|
||
<literal>DESTINATION</literal> field is present, it specifies a message
|
||
recipient by name. Method calls and replies normally specify this field.
|
||
The message bus must send messages (of any type) with the
|
||
<literal>DESTINATION</literal> field set to the specified recipient,
|
||
regardless of whether the recipient has set up a match rule matching
|
||
the message.
|
||
</para>
|
||
|
||
<para>
|
||
When the message bus receives a signal, if the
|
||
<literal>DESTINATION</literal> field is absent, it is considered to
|
||
be a <firstterm>broadcast signal</firstterm>, and is sent to all
|
||
applications with <firstterm>message matching rules</firstterm> that
|
||
match the message. Most signal messages are broadcasts, and
|
||
no other message types currently defined in this specification
|
||
may be broadcast.
|
||
</para>
|
||
|
||
<para>
|
||
Unicast signal messages (those with a <literal>DESTINATION</literal>
|
||
field) are not commonly used, but they are treated like any unicast
|
||
message: they are delivered to the specified receipient,
|
||
regardless of its match rules. One use for unicast signals is to
|
||
avoid a race condition in which a signal is emitted before the intended
|
||
recipient can call <xref linkend="bus-messages-add-match"/> to
|
||
receive that signal: if the signal is sent directly to that recipient
|
||
using a unicast message, it does not need to add a match rule at all,
|
||
and there is no race condition. Another use for unicast signals,
|
||
on message buses whose security policy prevents eavesdropping, is to
|
||
send sensitive information which should only be visible to one
|
||
recipient.
|
||
</para>
|
||
|
||
<para>
|
||
When the message bus receives a method call, if the
|
||
<literal>DESTINATION</literal> field is absent, the call is taken to be
|
||
a standard one-to-one message and interpreted by the message bus
|
||
itself. For example, sending an
|
||
<literal>org.freedesktop.DBus.Peer.Ping</literal> message with no
|
||
<literal>DESTINATION</literal> will cause the message bus itself to
|
||
reply to the ping immediately; the message bus will not make this
|
||
message visible to other applications.
|
||
</para>
|
||
|
||
<para>
|
||
Continuing the <literal>org.freedesktop.DBus.Peer.Ping</literal> example, if
|
||
the ping message were sent with a <literal>DESTINATION</literal> name of
|
||
<literal>com.yoyodyne.Screensaver</literal>, then the ping would be
|
||
forwarded, and the Yoyodyne Corporation screensaver application would be
|
||
expected to reply to the ping.
|
||
</para>
|
||
|
||
<para>
|
||
Message bus implementations may impose a security policy which
|
||
prevents certain messages from being sent or received.
|
||
When a method call message cannot be sent or received due to a security
|
||
policy, the message bus should send an error reply, unless the
|
||
original message had the <literal>NO_REPLY</literal> flag.
|
||
</para>
|
||
|
||
<sect3 id="message-bus-routing-eavesdropping">
|
||
<title>Eavesdropping</title>
|
||
<para>
|
||
Receiving a unicast message whose <literal>DESTINATION</literal>
|
||
indicates a different recipient is called
|
||
<firstterm>eavesdropping</firstterm>. On a message bus which acts as
|
||
a security boundary (like the standard system bus), the security
|
||
policy should usually prevent eavesdropping, since unicast messages
|
||
are normally kept private and may contain security-sensitive
|
||
information.
|
||
</para>
|
||
|
||
<para>
|
||
Eavesdropping interacts poorly with buses with non-trivial
|
||
access control restrictions, and is deprecated. The
|
||
<literal>BecomeMonitor</literal> method (see
|
||
<xref linkend="bus-messages-become-monitor"/>) provides
|
||
a preferable way to monitor buses.
|
||
</para>
|
||
|
||
<para>
|
||
Eavesdropping is mainly useful for debugging tools, such as
|
||
the <literal>dbus-monitor</literal> tool in the reference
|
||
implementation of D-Bus. Tools which eavesdrop on the message bus
|
||
should be careful to avoid sending a reply or error in response to
|
||
messages intended for a different client.
|
||
</para>
|
||
|
||
<para>
|
||
Clients may attempt to eavesdrop by adding match rules
|
||
(see <xref linkend="message-bus-routing-match-rules"/>) containing
|
||
the <literal>eavesdrop='true'</literal> match. For
|
||
compatibility with older message bus implementations, if adding such
|
||
a match rule results in an error reply, the client may fall back to
|
||
adding the same rule with the <literal>eavesdrop</literal> match
|
||
omitted.
|
||
</para>
|
||
</sect3>
|
||
|
||
<sect3 id="message-bus-routing-match-rules">
|
||
<title>Match Rules</title>
|
||
<para>
|
||
An important part of the message bus routing protocol is match
|
||
rules. Match rules describe the messages that should be sent to a
|
||
client, based on the contents of the message. Broadcast signals
|
||
are only sent to clients which have a suitable match rule: this
|
||
avoids waking up client processes to deal with signals that are
|
||
not relevant to that client.
|
||
</para>
|
||
<para>
|
||
Messages that list a client as their <literal>DESTINATION</literal>
|
||
do not need to match the client's match rules, and are sent to that
|
||
client regardless. As a result, match rules are mainly used to
|
||
receive a subset of broadcast signals.
|
||
</para>
|
||
<para>
|
||
Match rules can also be used for eavesdropping
|
||
(see <xref linkend="message-bus-routing-eavesdropping"/>),
|
||
if the security policy of the message bus allows it, but this
|
||
usage is deprecated in favour of the <literal>BecomeMonitor</literal>
|
||
method (see <xref linkend="bus-messages-become-monitor"/>).
|
||
</para>
|
||
<para>
|
||
Match rules are added using the AddMatch bus method
|
||
(see <xref linkend="bus-messages-add-match"/>). Rules are
|
||
specified as a string of comma separated key/value pairs.
|
||
Excluding a key from the rule indicates a wildcard match.
|
||
For instance excluding the the member from a match rule but
|
||
adding a sender would let all messages from that sender through.
|
||
An example of a complete rule would be
|
||
"type='signal',sender='org.freedesktop.DBus',interface='org.freedesktop.DBus',member='Foo',path='/bar/foo',destination=':452345.34',arg2='bar'"
|
||
</para>
|
||
<para>
|
||
Within single quotes (ASCII apostrophe, U+0027), a backslash
|
||
(U+005C) represents itself, and an apostrophe ends the quoted
|
||
section. Outside single quotes, \' (backslash, apostrophe)
|
||
represents an apostrophe, and any backslash not followed by
|
||
an apostrophe represents itself. For instance, the match rules
|
||
<literal>arg0=''\''',arg1='\',arg2=',',arg3='\\'</literal> and
|
||
<literal>arg0=\',arg1=\,arg2=',',arg3=\\</literal>
|
||
both match messages where the arguments are a 1-character string
|
||
containing an apostrophe, a 1-character string containing a
|
||
backslash, a 1-character string containing a comma, and a
|
||
2-character string containing two backslashes<footnote>
|
||
<para>
|
||
This idiosyncratic quoting style is based on the rules for
|
||
escaping items to appear inside single-quoted strings
|
||
in POSIX <literal>/bin/sh</literal>, but please
|
||
note that backslashes that are not inside single quotes have
|
||
different behaviour. This syntax does not offer any way to
|
||
represent an apostrophe inside single quotes (it is necessary
|
||
to leave the single-quoted section, backslash-escape the
|
||
apostrophe and re-enter single quotes), or to represent a
|
||
comma outside single quotes (it is necessary to wrap it in
|
||
a single-quoted section).
|
||
</para>
|
||
</footnote>.
|
||
</para>
|
||
<para>
|
||
The following table describes the keys that can be used to create
|
||
a match rule.
|
||
<informaltable>
|
||
<tgroup cols="3">
|
||
<thead>
|
||
<row>
|
||
<entry>Key</entry>
|
||
<entry>Possible Values</entry>
|
||
<entry>Description</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row>
|
||
<entry><literal>type</literal></entry>
|
||
<entry>'signal', 'method_call', 'method_return', 'error'</entry>
|
||
<entry>Match on the message type. An example of a type match is type='signal'</entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>sender</literal></entry>
|
||
<entry>A bus or unique name (see <xref linkend="term-bus-name"/>
|
||
and <xref linkend="term-unique-name"/> respectively)
|
||
</entry>
|
||
<entry>Match messages sent by a particular sender. An example of a sender match
|
||
is sender='org.freedesktop.Hal'</entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>interface</literal></entry>
|
||
<entry>An interface name (see <xref linkend="message-protocol-names-interface"/>)</entry>
|
||
<entry>Match messages sent over or to a particular interface. An example of an
|
||
interface match is interface='org.freedesktop.Hal.Manager'.
|
||
If a message omits the interface header, it must not match any rule
|
||
that specifies this key.</entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>member</literal></entry>
|
||
<entry>Any valid method or signal name</entry>
|
||
<entry>Matches messages which have the give method or signal name. An example of
|
||
a member match is member='NameOwnerChanged'</entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>path</literal></entry>
|
||
<entry>An object path (see <xref linkend="message-protocol-marshaling-object-path"/>)</entry>
|
||
<entry>Matches messages which are sent from or to the given object. An example of a
|
||
path match is path='/org/freedesktop/Hal/Manager'</entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>path_namespace</literal></entry>
|
||
<entry>An object path</entry>
|
||
<entry>
|
||
<para>
|
||
Matches messages which are sent from or to an
|
||
object for which the object path is either the
|
||
given value, or that value followed by one or
|
||
more path components.
|
||
</para>
|
||
|
||
<para>
|
||
For example,
|
||
<literal>path_namespace='/com/example/foo'</literal>
|
||
would match signals sent by
|
||
<literal>/com/example/foo</literal>
|
||
or by
|
||
<literal>/com/example/foo/bar</literal>,
|
||
but not by
|
||
<literal>/com/example/foobar</literal>.
|
||
</para>
|
||
|
||
<para>
|
||
Using both <literal>path</literal> and
|
||
<literal>path_namespace</literal> in the same match
|
||
rule is not allowed.
|
||
</para>
|
||
|
||
<para>
|
||
<emphasis>
|
||
This match key was added in version 0.16 of the
|
||
D-Bus specification and implemented by the bus
|
||
daemon in dbus 1.5.0 and later.
|
||
</emphasis>
|
||
</para>
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>destination</literal></entry>
|
||
<entry>A unique name (see <xref linkend="term-unique-name"/>)</entry>
|
||
<entry>Matches messages which are being sent to the given unique name. An
|
||
example of a destination match is destination=':1.0'</entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>arg[0, 1, 2, 3, ...]</literal></entry>
|
||
<entry>Any string</entry>
|
||
<entry>Arg matches are special and are used for further restricting the
|
||
match based on the arguments in the body of a message. Only arguments of type
|
||
STRING can be matched in this way. An example of an argument match
|
||
would be arg3='Foo'. Only argument indexes from 0 to 63 should be
|
||
accepted.</entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>arg[0, 1, 2, 3, ...]path</literal></entry>
|
||
<entry>Any string</entry>
|
||
<entry>
|
||
<para>Argument path matches provide a specialised form of wildcard matching for
|
||
path-like namespaces. They can match arguments whose type is either STRING or
|
||
OBJECT_PATH. As with normal argument matches,
|
||
if the argument is exactly equal to the string given in the match
|
||
rule then the rule is satisfied. Additionally, there is also a
|
||
match when either the string given in the match rule or the
|
||
appropriate message argument ends with '/' and is a prefix of the
|
||
other. An example argument path match is arg0path='/aa/bb/'. This
|
||
would match messages with first arguments of '/', '/aa/',
|
||
'/aa/bb/', '/aa/bb/cc/' and '/aa/bb/cc'. It would not match
|
||
messages with first arguments of '/aa/b', '/aa' or even '/aa/bb'.</para>
|
||
|
||
<para>This is intended for monitoring “directories” in file system-like
|
||
hierarchies, as used in the <citetitle>dconf</citetitle> configuration
|
||
system. An application interested in all nodes in a particular hierarchy would
|
||
monitor <literal>arg0path='/ca/example/foo/'</literal>. Then the service could
|
||
emit a signal with zeroth argument <literal>"/ca/example/foo/bar"</literal> to
|
||
represent a modification to the “bar” property, or a signal with zeroth
|
||
argument <literal>"/ca/example/"</literal> to represent atomic modification of
|
||
many properties within that directory, and the interested application would be
|
||
notified in both cases.</para>
|
||
<para>
|
||
<emphasis>
|
||
This match key was added in version 0.12 of the
|
||
D-Bus specification, implemented for STRING
|
||
arguments by the bus daemon in dbus 1.2.0 and later,
|
||
and implemented for OBJECT_PATH arguments in dbus 1.5.0
|
||
and later.
|
||
</emphasis>
|
||
</para>
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>arg0namespace</literal></entry>
|
||
<entry>Like a bus name, except that the string is not
|
||
required to contain a '.' (period)</entry>
|
||
<entry>
|
||
<para>Match messages whose first argument is of type STRING, and is a bus name
|
||
or interface name within the specified namespace. This is primarily intended
|
||
for watching name owner changes for a group of related bus names, rather than
|
||
for a single name or all name changes.</para>
|
||
|
||
<para>Because every valid interface name is also a valid
|
||
bus name, this can also be used for messages whose
|
||
first argument is an interface name.</para>
|
||
|
||
<para>For example, the match rule
|
||
<literal>member='NameOwnerChanged',arg0namespace='com.example.backend1'</literal>
|
||
matches name owner changes for bus names such as
|
||
<literal>com.example.backend1.foo</literal>,
|
||
<literal>com.example.backend1.foo.bar</literal>, and
|
||
<literal>com.example.backend1</literal> itself.</para>
|
||
|
||
<para>See also <xref linkend='bus-messages-name-owner-changed'/>.</para>
|
||
<para>
|
||
<emphasis>
|
||
This match key was added in version 0.16 of the
|
||
D-Bus specification and implemented by the bus
|
||
daemon in dbus 1.5.0 and later.
|
||
</emphasis>
|
||
</para>
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>eavesdrop</literal></entry>
|
||
<entry><literal>'true'</literal>, <literal>'false'</literal></entry>
|
||
<entry>
|
||
<para>
|
||
Since D-Bus 1.5.6, match rules do not
|
||
match messages which have a <literal>DESTINATION</literal>
|
||
field unless the match rule specifically
|
||
requests this
|
||
(see <xref linkend="message-bus-routing-eavesdropping"/>)
|
||
by specifying <literal>eavesdrop='true'</literal>
|
||
in the match rule. <literal>eavesdrop='false'</literal>
|
||
restores the default behaviour. Messages are
|
||
delivered to their <literal>DESTINATION</literal>
|
||
regardless of match rules, so this match does not
|
||
affect normal delivery of unicast messages.
|
||
In older versions of D-Bus, this match was not allowed
|
||
in match rules, and all match rules behaved as if
|
||
<literal>eavesdrop='true'</literal> had been used.
|
||
</para>
|
||
<para>
|
||
Use of <literal>eavesdrop='true'</literal> is
|
||
deprecated. Monitors should prefer to use the
|
||
<literal>BecomeMonitor</literal> method (see
|
||
<xref linkend="bus-messages-become-monitor"/>),
|
||
which was introduced in version 0.26 of the D-Bus
|
||
specification and version 1.9.10 of the reference
|
||
dbus-daemon.
|
||
</para>
|
||
<para>
|
||
Message bus implementations may restrict match rules
|
||
with <literal>eavesdrop='true'</literal> so that they
|
||
can only be added by privileged connections.
|
||
</para>
|
||
<para>
|
||
<emphasis>
|
||
This match key was added in version 0.18 of the
|
||
D-Bus specification and implemented by the bus
|
||
daemon in dbus 1.5.6 and later.
|
||
</emphasis>
|
||
</para>
|
||
</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
</para>
|
||
</sect3>
|
||
</sect2>
|
||
<sect2 id="message-bus-starting-services">
|
||
<title>Message Bus Starting Services (Activation)</title>
|
||
<para>
|
||
The message bus can start applications on behalf of other applications.
|
||
This is referred to as <firstterm>service activation</firstterm> or
|
||
<firstterm>activation</firstterm>.
|
||
An application that can be started in this way is called a
|
||
<firstterm>service</firstterm> or an
|
||
<firstterm>activatable service</firstterm>.
|
||
</para>
|
||
|
||
<para>
|
||
<firstterm>Starting a service</firstterm> should be read as synonymous
|
||
with service activation.
|
||
</para>
|
||
|
||
<para>
|
||
In D-Bus, service activation is normally done by
|
||
<firstterm>auto-starting</firstterm>.
|
||
In auto-starting, applications send a
|
||
message to a particular well-known name, such as
|
||
<literal>com.example.TextEditor1</literal>, without specifying the
|
||
<literal>NO_AUTO_START</literal> flag in the message header.
|
||
If no application on the bus owns the requested name, but the bus
|
||
daemon does know how to start an activatable service for that name,
|
||
then the bus daemon will start that service, wait for it to request
|
||
that name, and deliver the message to it.
|
||
</para>
|
||
|
||
<para>
|
||
It is also possible for applications to send an explicit request to
|
||
start a service: this is another form of activation, distinct from
|
||
auto-starting. See
|
||
<xref linkend="bus-messages-start-service-by-name"/> for details.
|
||
</para>
|
||
|
||
<para>
|
||
In either case, this implies a contract documented along with the name
|
||
<literal>com.example.TextEditor1</literal> for which object
|
||
the owner of that name will provide, and what interfaces those
|
||
objects will have.
|
||
</para>
|
||
|
||
<para>
|
||
To find an executable corresponding to a particular name, the bus daemon
|
||
looks for <firstterm>service description files</firstterm>. Service
|
||
description files define a mapping from names to executables. Different
|
||
kinds of message bus will look for these files in different places, see
|
||
<xref linkend="message-bus-types"/>.
|
||
</para>
|
||
<para>
|
||
Service description files have the ".service" file
|
||
extension. The message bus will only load service description files
|
||
ending with .service; all other files will be ignored. The file format
|
||
is similar to that of <ulink
|
||
url="http://standards.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html">desktop
|
||
entries</ulink>. All service description files must be in UTF-8
|
||
encoding. To ensure that there will be no name collisions, service files
|
||
must be namespaced using the same mechanism as messages and service
|
||
names.
|
||
</para>
|
||
|
||
<para>
|
||
On the well-known system bus, the name of a service description file
|
||
must be its well-known name plus <literal>.service</literal>,
|
||
for instance
|
||
<literal>com.example.ConfigurationDatabase1.service</literal>.
|
||
</para>
|
||
|
||
<para>
|
||
On the well-known session bus, services should follow the same
|
||
service description file naming convention as on the system bus,
|
||
but for backwards compatibility they are not required to do so.
|
||
</para>
|
||
|
||
<para>
|
||
[FIXME the file format should be much better specified than "similar to
|
||
.desktop entries" esp. since desktop entries are already
|
||
badly-specified. ;-)]
|
||
These sections from the specification apply to service files as well:
|
||
|
||
<itemizedlist>
|
||
<listitem><para>General syntax</para></listitem>
|
||
<listitem><para>Comment format</para></listitem>
|
||
</itemizedlist>
|
||
|
||
Service description files must contain a
|
||
<literal>D-BUS Service</literal> group with at least the keys
|
||
<literal>Name</literal> (the well-known name of the service)
|
||
and <literal>Exec</literal> (the command to be executed).
|
||
|
||
<figure>
|
||
<title>Example service description file</title>
|
||
<programlisting>
|
||
# Sample service description file
|
||
[D-BUS Service]
|
||
Name=com.example.ConfigurationDatabase1
|
||
Exec=/usr/bin/sample-configd
|
||
</programlisting>
|
||
</figure>
|
||
</para>
|
||
|
||
<para>
|
||
Additionally, service description files for the well-known system
|
||
bus on Unix must contain a <literal>User</literal> key, whose value
|
||
is the name of a user account (e.g. <literal>root</literal>).
|
||
The system service will be run as that user.
|
||
</para>
|
||
|
||
<para>
|
||
When an application asks to start a service by name, the bus daemon tries to
|
||
find a service that will own that name. It then tries to spawn the
|
||
executable associated with it. If this fails, it will report an
|
||
error.
|
||
</para>
|
||
|
||
<para>
|
||
On the well-known system bus, it is not possible for two .service files
|
||
in the same directory to offer the same service, because they are
|
||
constrained to have names that match the service name.
|
||
</para>
|
||
|
||
<para>
|
||
On the well-known session bus, if two .service files in the same
|
||
directory offer the same service name, the result is undefined.
|
||
Distributors should avoid this situation, for instance by naming
|
||
session services' .service files according to their service name.
|
||
</para>
|
||
|
||
<para>
|
||
If two .service files in different directories offer the same
|
||
service name, the one in the higher-priority directory is used:
|
||
for instance, on the system bus, .service files in
|
||
/usr/local/share/dbus-1/system-services take precedence over those
|
||
in /usr/share/dbus-1/system-services.
|
||
</para>
|
||
<para>
|
||
The executable launched will have the environment variable
|
||
<literal>DBUS_STARTER_ADDRESS</literal> set to the address of the
|
||
message bus so it can connect and request the appropriate names.
|
||
</para>
|
||
<para>
|
||
The executable being launched may want to know whether the message bus
|
||
starting it is one of the well-known message buses (see <xref
|
||
linkend="message-bus-types"/>). To facilitate this, the bus must also set
|
||
the <literal>DBUS_STARTER_BUS_TYPE</literal> environment variable if it is one
|
||
of the well-known buses. The currently-defined values for this variable
|
||
are <literal>system</literal> for the systemwide message bus,
|
||
and <literal>session</literal> for the per-login-session message
|
||
bus. The new executable must still connect to the address given
|
||
in <literal>DBUS_STARTER_ADDRESS</literal>, but may assume that the
|
||
resulting connection is to the well-known bus.
|
||
</para>
|
||
<para>
|
||
[FIXME there should be a timeout somewhere, either specified
|
||
in the .service file, by the client, or just a global value
|
||
and if the client being activated fails to connect within that
|
||
timeout, an error should be sent back.]
|
||
</para>
|
||
|
||
<sect3 id="message-bus-starting-services-scope">
|
||
<title>Message Bus Service Scope</title>
|
||
<para>
|
||
The "scope" of a service is its "per-", such as per-session,
|
||
per-machine, per-home-directory, or per-display. The reference
|
||
implementation doesn't yet support starting services in a different
|
||
scope from the message bus itself. So e.g. if you start a service
|
||
on the session bus its scope is per-session.
|
||
</para>
|
||
<para>
|
||
We could add an optional scope to a bus name. For example, for
|
||
per-(display,session pair), we could have a unique ID for each display
|
||
generated automatically at login and set on screen 0 by executing a
|
||
special "set display ID" binary. The ID would be stored in a
|
||
<literal>_DBUS_DISPLAY_ID</literal> property and would be a string of
|
||
random bytes. This ID would then be used to scope names.
|
||
Starting/locating a service could be done by ID-name pair rather than
|
||
only by name.
|
||
</para>
|
||
<para>
|
||
Contrast this with a per-display scope. To achieve that, we would
|
||
want a single bus spanning all sessions using a given display.
|
||
So we might set a <literal>_DBUS_DISPLAY_BUS_ADDRESS</literal>
|
||
property on screen 0 of the display, pointing to this bus.
|
||
</para>
|
||
</sect3>
|
||
|
||
<sect3 id="message-bus-starting-services-systemd">
|
||
<title>systemd Activation</title>
|
||
|
||
<para>
|
||
Service description files may contain a
|
||
<literal>SystemdService</literal> key. Its value is the name of a
|
||
<ulink
|
||
url="https://www.freedesktop.org/wiki/Software/systemd/">systemd</ulink>
|
||
service, for example
|
||
<literal>dbus-com.example.MyDaemon.service</literal>.
|
||
</para>
|
||
|
||
<para>
|
||
If this key is present, the bus daemon may carry out activation for
|
||
this D-Bus service by sending a request to systemd asking it to
|
||
start the systemd service whose name is the value of
|
||
<literal>SystemdService</literal>. For example, the reference
|
||
<literal>dbus-daemon</literal> has a
|
||
<literal>--systemd-activation</literal> option that enables this
|
||
feature, and that option is given when it is started by systemd.
|
||
</para>
|
||
|
||
<para>
|
||
On the well-known system bus, it is a common practice to set
|
||
<literal>SystemdService</literal> to <literal>dbus-</literal>,
|
||
followed by the well-known bus name, followed by
|
||
<literal>.service</literal>, then register that name as an alias
|
||
for the real systemd service. This allows D-Bus activation of a
|
||
service to be enabled or disabled independently of whether the
|
||
service is started by systemd during boot.
|
||
</para>
|
||
</sect3>
|
||
|
||
<sect3 id="message-bus-starting-services-apparmor">
|
||
<title>Mediating Activation with AppArmor</title>
|
||
|
||
<para>
|
||
Please refer to
|
||
<ulink url="http://wiki.apparmor.net/index.php/Documentation">AppArmor documentation</ulink>
|
||
for general information on AppArmor, and how it mediates D-Bus
|
||
messages when used in conjunction with a kernel and
|
||
<literal>dbus-daemon</literal> that support this.
|
||
</para>
|
||
|
||
<para>
|
||
In recent versions of the reference <literal>dbus-daemon</literal>,
|
||
AppArmor policy rules of type <literal>dbus send</literal>
|
||
are also used to control auto-starting: if a message is sent to
|
||
the well-known name of an activatable service, the
|
||
<literal>dbus-daemon</literal> will attempt to determine whether
|
||
it would deliver the message to that service
|
||
<emphasis>before</emphasis>auto-starting it, by making some
|
||
assumptions about the resulting process's credentials.
|
||
</para>
|
||
|
||
<para>
|
||
If it does proceed with auto-starting, when the service appears, the
|
||
<literal>dbus-daemon</literal> repeats the policy check (with
|
||
the service's true credentials, which might not be identical)
|
||
before delivering the message. In practice, this second check will
|
||
usually be more strict than the first; the first check would only
|
||
be more strict if there are "blacklist"-style rules like
|
||
<literal>deny dbus send peer=(label=/usr/bin/protected)</literal>
|
||
that match on the peer's specific credentials, but AppArmor is
|
||
normally used in a "whitelist" style where this does not apply.
|
||
</para>
|
||
|
||
<para>
|
||
To support this process, service description files may contain a
|
||
<literal>AssumedAppArmorLabel</literal> key. Its value is the name
|
||
of an AppArmor label, for example
|
||
<literal>/usr/sbin/mydaemon</literal>.
|
||
If present, AppArmor mediation of messages that auto-start a
|
||
service will decide whether to allow auto-starting to occur based
|
||
on the assumption that the activated service will be confined
|
||
under the specified label; in particular, rules of the form
|
||
<literal>dbus send peer=(label=/usr/sbin/mydaemon)</literal> or
|
||
<literal>deny dbus send peer=(label=/usr/sbin/mydaemon)</literal>
|
||
will match it, allowing or denying as appropriate
|
||
(even if there is in fact no profile of that name loaded).
|
||
</para>
|
||
|
||
<para>
|
||
Otherwise, AppArmor mediation of messages that auto-start a
|
||
service will decide whether to allow auto-starting to occur
|
||
without specifying any particular label. In particular, any rule of
|
||
the form <literal>dbus send peer=(label=X)</literal> or
|
||
<literal>deny dbus send peer=(label=X)</literal>
|
||
(for any value of X, including the special label
|
||
<literal>unconfined</literal>) will not influence whether the
|
||
auto-start is allowed.
|
||
</para>
|
||
|
||
<para>
|
||
Rules of type <literal>dbus receive</literal> are not checked
|
||
when deciding whether to allow auto-starting; they are only checked
|
||
against the service's profile after the service has started, when
|
||
deciding whether to deliver the message that caused the auto-starting
|
||
operation.
|
||
</para>
|
||
|
||
<para>
|
||
Explicit activation via
|
||
<xref linkend="bus-messages-start-service-by-name"/> is not currently
|
||
affected by this mediation: if a confined process is to be prevented
|
||
from starting arbitrary services, then it must not be allowed to call
|
||
that method.
|
||
</para>
|
||
</sect3>
|
||
</sect2>
|
||
|
||
<sect2 id="message-bus-types">
|
||
<title>Well-known Message Bus Instances</title>
|
||
<para>
|
||
Two standard message bus instances are defined here, along with how
|
||
to locate them and where their service files live.
|
||
</para>
|
||
<sect3 id="message-bus-types-login">
|
||
<title>Login session message bus</title>
|
||
<para>
|
||
Each time a user logs in, a <firstterm>login session message
|
||
bus</firstterm> may be started. All applications in the user's login
|
||
session may interact with one another using this message bus.
|
||
</para>
|
||
<para>
|
||
The address of the login session message bus is given
|
||
in the <literal>DBUS_SESSION_BUS_ADDRESS</literal> environment
|
||
variable. If that variable is not set, applications may
|
||
also try to read the address from the X Window System root
|
||
window property <literal>_DBUS_SESSION_BUS_ADDRESS</literal>.
|
||
The root window property must have type <literal>STRING</literal>.
|
||
The environment variable should have precedence over the
|
||
root window property.
|
||
</para>
|
||
<para>The address of the login session message bus is given in the
|
||
<literal>DBUS_SESSION_BUS_ADDRESS</literal> environment variable. If
|
||
DBUS_SESSION_BUS_ADDRESS is not set, or if it's set to the string
|
||
"autolaunch:", the system should use platform-specific methods of
|
||
locating a running D-Bus session server, or starting one if a running
|
||
instance cannot be found. Note that this mechanism is not recommended
|
||
for attempting to determine if a daemon is running. It is inherently
|
||
racy to attempt to make this determination, since the bus daemon may
|
||
be started just before or just after the determination is made.
|
||
Therefore, it is recommended that applications do not try to make this
|
||
determination for their functionality purposes, and instead they
|
||
should attempt to start the server.</para>
|
||
|
||
<sect4 id="message-bus-types-login-x-windows">
|
||
<title>X Windowing System</title>
|
||
<para>
|
||
For the X Windowing System, the application must locate the
|
||
window owner of the selection represented by the atom formed by
|
||
concatenating:
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>the literal string "_DBUS_SESSION_BUS_SELECTION_"</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>the current user's username</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>the literal character '_' (underscore)</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>the machine's ID</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
</para>
|
||
|
||
<para>
|
||
The following properties are defined for the window that owns
|
||
this X selection:
|
||
<informaltable frame="all">
|
||
<tgroup cols="2">
|
||
<tbody>
|
||
<row>
|
||
<entry>
|
||
<para>Atom</para>
|
||
</entry>
|
||
|
||
<entry>
|
||
<para>meaning</para>
|
||
</entry>
|
||
</row>
|
||
|
||
<row>
|
||
<entry>
|
||
<para>_DBUS_SESSION_BUS_ADDRESS</para>
|
||
</entry>
|
||
|
||
<entry>
|
||
<para>the actual address of the server socket</para>
|
||
</entry>
|
||
</row>
|
||
|
||
<row>
|
||
<entry>
|
||
<para>_DBUS_SESSION_BUS_PID</para>
|
||
</entry>
|
||
|
||
<entry>
|
||
<para>the PID of the server process</para>
|
||
</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
</para>
|
||
|
||
<para>
|
||
At least the _DBUS_SESSION_BUS_ADDRESS property MUST be
|
||
present in this window.
|
||
</para>
|
||
|
||
<para>
|
||
If the X selection cannot be located or if reading the
|
||
properties from the window fails, the implementation MUST conclude
|
||
that there is no D-Bus server running and proceed to start a new
|
||
server. (See below on concurrency issues)
|
||
</para>
|
||
|
||
<para>
|
||
Failure to connect to the D-Bus server address thus obtained
|
||
MUST be treated as a fatal connection error and should be reported
|
||
to the application.
|
||
</para>
|
||
|
||
<para>
|
||
As an alternative, an implementation MAY find the information
|
||
in the following file located in the current user's home directory,
|
||
in subdirectory .dbus/session-bus/:
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>the machine's ID</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>the literal character '-' (dash)</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>the X display without the screen number, with the
|
||
following prefixes removed, if present: ":", "localhost:"
|
||
."localhost.localdomain:". That is, a display of
|
||
"localhost:10.0" produces just the number "10"</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
</para>
|
||
|
||
<para>
|
||
The contents of this file NAME=value assignment pairs and
|
||
lines starting with # are comments (no comments are allowed
|
||
otherwise). The following variable names are defined:
|
||
<informaltable
|
||
frame="all">
|
||
<tgroup cols="2">
|
||
<tbody>
|
||
<row>
|
||
<entry>
|
||
<para>Variable</para>
|
||
</entry>
|
||
|
||
<entry>
|
||
<para>meaning</para>
|
||
</entry>
|
||
</row>
|
||
|
||
<row>
|
||
<entry>
|
||
<para>DBUS_SESSION_BUS_ADDRESS</para>
|
||
</entry>
|
||
|
||
<entry>
|
||
<para>the actual address of the server socket</para>
|
||
</entry>
|
||
</row>
|
||
|
||
<row>
|
||
<entry>
|
||
<para>DBUS_SESSION_BUS_PID</para>
|
||
</entry>
|
||
|
||
<entry>
|
||
<para>the PID of the server process</para>
|
||
</entry>
|
||
</row>
|
||
|
||
<row>
|
||
<entry>
|
||
<para>DBUS_SESSION_BUS_WINDOWID</para>
|
||
</entry>
|
||
|
||
<entry>
|
||
<para>the window ID</para>
|
||
</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
</para>
|
||
|
||
<para>
|
||
At least the DBUS_SESSION_BUS_ADDRESS variable MUST be present
|
||
in this file.
|
||
</para>
|
||
|
||
<para>
|
||
Failure to open this file MUST be interpreted as absence of a
|
||
running server. Therefore, the implementation MUST proceed to
|
||
attempting to launch a new bus server if the file cannot be
|
||
opened.
|
||
</para>
|
||
|
||
<para>
|
||
However, success in opening this file MUST NOT lead to the
|
||
conclusion that the server is running. Thus, a failure to connect to
|
||
the bus address obtained by the alternative method MUST NOT be
|
||
considered a fatal error. If the connection cannot be established,
|
||
the implementation MUST proceed to check the X selection settings or
|
||
to start the server on its own.
|
||
</para>
|
||
|
||
<para>
|
||
If the implementation concludes that the D-Bus server is not
|
||
running it MUST attempt to start a new server and it MUST also
|
||
ensure that the daemon started as an effect of the "autolaunch"
|
||
mechanism provides the lookup mechanisms described above, so
|
||
subsequent calls can locate the newly started server. The
|
||
implementation MUST also ensure that if two or more concurrent
|
||
initiations happen, only one server remains running and all other
|
||
initiations are able to obtain the address of this server and
|
||
connect to it. In other words, the implementation MUST ensure that
|
||
the X selection is not present when it attempts to set it, without
|
||
allowing another process to set the selection between the
|
||
verification and the setting (e.g., by using XGrabServer /
|
||
XungrabServer).
|
||
</para>
|
||
</sect4>
|
||
<sect4>
|
||
<title>Finding session services</title>
|
||
<para>
|
||
On Unix systems, the session bus should search for .service files
|
||
in <literal>$XDG_DATA_DIRS/dbus-1/services</literal> as defined
|
||
by the
|
||
<ulink url="http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html">XDG Base Directory Specification</ulink>.
|
||
Implementations may also search additional locations,
|
||
with a higher or lower priority than the XDG directories.
|
||
</para>
|
||
<para>
|
||
As described in the XDG Base Directory Specification, software
|
||
packages should install their session .service files to their
|
||
configured <literal>${datadir}/dbus-1/services</literal>,
|
||
where <literal>${datadir}</literal> is as defined by the GNU
|
||
coding standards. System administrators or users can arrange
|
||
for these service files to be read by setting XDG_DATA_DIRS or by
|
||
symlinking them into the default locations.
|
||
</para>
|
||
</sect4>
|
||
</sect3>
|
||
<sect3 id="message-bus-types-system">
|
||
<title>System message bus</title>
|
||
<para>
|
||
A computer may have a <firstterm>system message bus</firstterm>,
|
||
accessible to all applications on the system. This message bus may be
|
||
used to broadcast system events, such as adding new hardware devices,
|
||
changes in the printer queue, and so forth.
|
||
</para>
|
||
<para>
|
||
The address of the system message bus is given
|
||
in the <literal>DBUS_SYSTEM_BUS_ADDRESS</literal> environment
|
||
variable. If that variable is not set, applications should try
|
||
to connect to the well-known address
|
||
<literal>unix:path=/var/run/dbus/system_bus_socket</literal>.
|
||
<footnote>
|
||
<para>
|
||
The D-Bus reference implementation actually honors the
|
||
<literal>$(localstatedir)</literal> configure option
|
||
for this address, on both client and server side.
|
||
</para>
|
||
</footnote>
|
||
</para>
|
||
<para>
|
||
On Unix systems, the system bus should default to searching
|
||
for .service files in
|
||
<literal>/usr/local/share/dbus-1/system-services</literal>,
|
||
<literal>/usr/share/dbus-1/system-services</literal> and
|
||
<literal>/lib/dbus-1/system-services</literal>, with that order
|
||
of precedence. It may also search other implementation-specific
|
||
locations, but should not vary these locations based on environment
|
||
variables.
|
||
<footnote>
|
||
<para>
|
||
The system bus is security-sensitive and is typically executed
|
||
by an init system with a clean environment. Its launch helper
|
||
process is particularly security-sensitive, and specifically
|
||
clears its own environment.
|
||
</para>
|
||
</footnote>
|
||
</para>
|
||
<para>
|
||
Software packages should install their system .service
|
||
files to their configured
|
||
<literal>${datadir}/dbus-1/system-services</literal>,
|
||
where <literal>${datadir}</literal> is as defined by the GNU
|
||
coding standards. System administrators can arrange
|
||
for these service files to be read by editing the system bus'
|
||
configuration file or by symlinking them into the default
|
||
locations.
|
||
</para>
|
||
</sect3>
|
||
</sect2>
|
||
|
||
<sect2 id="message-bus-messages">
|
||
<title>Message Bus Messages</title>
|
||
<para>
|
||
The special message bus name <literal>org.freedesktop.DBus</literal>
|
||
responds to a number of additional messages at the object path
|
||
<literal>/org/freedesktop/DBus</literal>.
|
||
That object path is also used when emitting the
|
||
<xref linkend='bus-messages-name-owner-changed'/> signal.
|
||
</para>
|
||
|
||
<para>
|
||
For historical reasons, some of the methods in the
|
||
<literal>org.freedesktop.DBus</literal> interface are available
|
||
on multiple object paths. Message bus implementations should
|
||
accept method calls that were added before specification version
|
||
0.26 on any object path. Message bus implementations should
|
||
not accept newer method calls on unexpected object paths,
|
||
and as a security hardening measure, older method calls
|
||
that are security-sensitive may be rejected with the error
|
||
<literal>org.freedesktop.DBus.Error.AccessDenied</literal> when
|
||
called on an unexpected object path. Client software should send
|
||
all method calls to <literal>/org/freedesktop/DBus</literal>
|
||
instead of relying on this.
|
||
</para>
|
||
|
||
<para>
|
||
In addition to the method calls listed below, the message bus
|
||
should implement the standard Introspectable, Properties and Peer
|
||
interfaces (see <xref linkend="standard-interfaces"/>).
|
||
Support for the Properties and Peer interfaces was added in version
|
||
1.11.x of the reference implementation of the message bus.
|
||
</para>
|
||
|
||
<sect3 id="bus-messages-hello">
|
||
<title><literal>org.freedesktop.DBus.Hello</literal></title>
|
||
<para>
|
||
As a method:
|
||
<programlisting>
|
||
STRING Hello ()
|
||
</programlisting>
|
||
Reply arguments:
|
||
<informaltable>
|
||
<tgroup cols="3">
|
||
<thead>
|
||
<row>
|
||
<entry>Argument</entry>
|
||
<entry>Type</entry>
|
||
<entry>Description</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row>
|
||
<entry>0</entry>
|
||
<entry>STRING</entry>
|
||
<entry>Unique name assigned to the connection</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
</para>
|
||
<para>
|
||
Before an application is able to send messages to other applications
|
||
it must send the <literal>org.freedesktop.DBus.Hello</literal> message
|
||
to the message bus to obtain a unique name. If an application without
|
||
a unique name tries to send a message to another application, or a
|
||
message to the message bus itself that isn't the
|
||
<literal>org.freedesktop.DBus.Hello</literal> message, it will be
|
||
disconnected from the bus.
|
||
</para>
|
||
<para>
|
||
There is no corresponding "disconnect" request; if a client wishes to
|
||
disconnect from the bus, it simply closes the socket (or other
|
||
communication channel).
|
||
</para>
|
||
</sect3>
|
||
|
||
<sect3 id="bus-messages-request-name">
|
||
<title><literal>org.freedesktop.DBus.RequestName</literal></title>
|
||
<para>
|
||
As a method:
|
||
<programlisting>
|
||
UINT32 RequestName (in STRING name, in UINT32 flags)
|
||
</programlisting>
|
||
Message arguments:
|
||
<informaltable>
|
||
<tgroup cols="3">
|
||
<thead>
|
||
<row>
|
||
<entry>Argument</entry>
|
||
<entry>Type</entry>
|
||
<entry>Description</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row>
|
||
<entry>0</entry>
|
||
<entry>STRING</entry>
|
||
<entry>Name to request</entry>
|
||
</row>
|
||
<row>
|
||
<entry>1</entry>
|
||
<entry>UINT32</entry>
|
||
<entry>Flags</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
Reply arguments:
|
||
<informaltable>
|
||
<tgroup cols="3">
|
||
<thead>
|
||
<row>
|
||
<entry>Argument</entry>
|
||
<entry>Type</entry>
|
||
<entry>Description</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row>
|
||
<entry>0</entry>
|
||
<entry>UINT32</entry>
|
||
<entry>Return value</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
</para>
|
||
<para>
|
||
Ask the message bus to assign the given name to the method caller. Each
|
||
name maintains a queue of possible owners, where the head of the queue is
|
||
the primary or current owner of the name. Each potential owner in the
|
||
queue maintains the DBUS_NAME_FLAG_ALLOW_REPLACEMENT and
|
||
DBUS_NAME_FLAG_DO_NOT_QUEUE settings from its latest RequestName call.
|
||
When RequestName is invoked the following occurs:
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>
|
||
If the method caller is currently the primary owner of the name,
|
||
the DBUS_NAME_FLAG_ALLOW_REPLACEMENT and DBUS_NAME_FLAG_DO_NOT_QUEUE
|
||
values are updated with the values from the new RequestName call,
|
||
and nothing further happens.
|
||
</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>
|
||
If the current primary owner (head of the queue) has
|
||
DBUS_NAME_FLAG_ALLOW_REPLACEMENT set, and the RequestName
|
||
invocation has the DBUS_NAME_FLAG_REPLACE_EXISTING flag, then
|
||
the caller of RequestName replaces the current primary owner at
|
||
the head of the queue and the current primary owner moves to the
|
||
second position in the queue. If the caller of RequestName was
|
||
in the queue previously its flags are updated with the values from
|
||
the new RequestName in addition to moving it to the head of the queue.
|
||
</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>
|
||
If replacement is not possible, and the method caller is
|
||
currently in the queue but not the primary owner, its flags are
|
||
updated with the values from the new RequestName call.
|
||
</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>
|
||
If replacement is not possible, and the method caller is
|
||
currently not in the queue, the method caller is appended to the
|
||
queue.
|
||
</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>
|
||
If any connection in the queue has DBUS_NAME_FLAG_DO_NOT_QUEUE
|
||
set and is not the primary owner, it is removed from the
|
||
queue. This can apply to the previous primary owner (if it
|
||
was replaced) or the method caller (if it updated the
|
||
DBUS_NAME_FLAG_DO_NOT_QUEUE flag while still stuck in the
|
||
queue, or if it was just added to the queue with that flag set).
|
||
</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
</para>
|
||
<para>
|
||
Note that DBUS_NAME_FLAG_REPLACE_EXISTING results in "jumping the
|
||
queue," even if another application already in the queue had specified
|
||
DBUS_NAME_FLAG_REPLACE_EXISTING. This comes up if a primary owner
|
||
that does not allow replacement goes away, and the next primary owner
|
||
does allow replacement. In this case, queued items that specified
|
||
DBUS_NAME_FLAG_REPLACE_EXISTING <emphasis>do not</emphasis>
|
||
automatically replace the new primary owner. In other words,
|
||
DBUS_NAME_FLAG_REPLACE_EXISTING is not saved, it is only used at the
|
||
time RequestName is called. This is deliberate to avoid an infinite loop
|
||
anytime two applications are both DBUS_NAME_FLAG_ALLOW_REPLACEMENT
|
||
and DBUS_NAME_FLAG_REPLACE_EXISTING.
|
||
</para>
|
||
<para>
|
||
The flags argument contains any of the following values logically ORed
|
||
together:
|
||
|
||
<informaltable>
|
||
<tgroup cols="3">
|
||
<thead>
|
||
<row>
|
||
<entry>Conventional Name</entry>
|
||
<entry>Value</entry>
|
||
<entry>Description</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row>
|
||
<entry>DBUS_NAME_FLAG_ALLOW_REPLACEMENT</entry>
|
||
<entry>0x1</entry>
|
||
<entry>
|
||
|
||
If an application A specifies this flag and succeeds in
|
||
becoming the owner of the name, and another application B
|
||
later calls RequestName with the
|
||
DBUS_NAME_FLAG_REPLACE_EXISTING flag, then application A
|
||
will lose ownership and receive a
|
||
<literal>org.freedesktop.DBus.NameLost</literal> signal, and
|
||
application B will become the new owner. If DBUS_NAME_FLAG_ALLOW_REPLACEMENT
|
||
is not specified by application A, or DBUS_NAME_FLAG_REPLACE_EXISTING
|
||
is not specified by application B, then application B will not replace
|
||
application A as the owner.
|
||
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry>DBUS_NAME_FLAG_REPLACE_EXISTING</entry>
|
||
<entry>0x2</entry>
|
||
<entry>
|
||
|
||
Try to replace the current owner if there is one. If this
|
||
flag is not set the application will only become the owner of
|
||
the name if there is no current owner. If this flag is set,
|
||
the application will replace the current owner if
|
||
the current owner specified DBUS_NAME_FLAG_ALLOW_REPLACEMENT.
|
||
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry>DBUS_NAME_FLAG_DO_NOT_QUEUE</entry>
|
||
<entry>0x4</entry>
|
||
<entry>
|
||
|
||
Without this flag, if an application requests a name that is
|
||
already owned, the application will be placed in a queue to
|
||
own the name when the current owner gives it up. If this
|
||
flag is given, the application will not be placed in the
|
||
queue, the request for the name will simply fail. This flag
|
||
also affects behavior when an application is replaced as
|
||
name owner; by default the application moves back into the
|
||
waiting queue, unless this flag was provided when the application
|
||
became the name owner.
|
||
|
||
</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
|
||
The return code can be one of the following values:
|
||
|
||
<informaltable>
|
||
<tgroup cols="3">
|
||
<thead>
|
||
<row>
|
||
<entry>Conventional Name</entry>
|
||
<entry>Value</entry>
|
||
<entry>Description</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row>
|
||
<entry>DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER</entry>
|
||
<entry>1</entry> <entry>The caller is now the primary owner of
|
||
the name, replacing any previous owner. Either the name had no
|
||
owner before, or the caller specified
|
||
DBUS_NAME_FLAG_REPLACE_EXISTING and the current owner specified
|
||
DBUS_NAME_FLAG_ALLOW_REPLACEMENT.</entry>
|
||
</row>
|
||
<row>
|
||
<entry>DBUS_REQUEST_NAME_REPLY_IN_QUEUE</entry>
|
||
<entry>2</entry>
|
||
|
||
<entry>The name already had an owner,
|
||
DBUS_NAME_FLAG_DO_NOT_QUEUE was not specified, and either
|
||
the current owner did not specify
|
||
DBUS_NAME_FLAG_ALLOW_REPLACEMENT or the requesting
|
||
application did not specify DBUS_NAME_FLAG_REPLACE_EXISTING.
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry>DBUS_REQUEST_NAME_REPLY_EXISTS</entry> <entry>3</entry>
|
||
<entry>The name already has an owner,
|
||
DBUS_NAME_FLAG_DO_NOT_QUEUE was specified, and either
|
||
DBUS_NAME_FLAG_ALLOW_REPLACEMENT was not specified by the
|
||
current owner, or DBUS_NAME_FLAG_REPLACE_EXISTING was not
|
||
specified by the requesting application.</entry>
|
||
</row>
|
||
<row>
|
||
<entry>DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER</entry>
|
||
<entry>4</entry>
|
||
<entry>The application trying to request ownership of a name is already the owner of it.</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
</para>
|
||
</sect3>
|
||
|
||
<sect3 id="bus-messages-release-name">
|
||
<title><literal>org.freedesktop.DBus.ReleaseName</literal></title>
|
||
<para>
|
||
As a method:
|
||
<programlisting>
|
||
UINT32 ReleaseName (in STRING name)
|
||
</programlisting>
|
||
Message arguments:
|
||
<informaltable>
|
||
<tgroup cols="3">
|
||
<thead>
|
||
<row>
|
||
<entry>Argument</entry>
|
||
<entry>Type</entry>
|
||
<entry>Description</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row>
|
||
<entry>0</entry>
|
||
<entry>STRING</entry>
|
||
<entry>Name to release</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
Reply arguments:
|
||
<informaltable>
|
||
<tgroup cols="3">
|
||
<thead>
|
||
<row>
|
||
<entry>Argument</entry>
|
||
<entry>Type</entry>
|
||
<entry>Description</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row>
|
||
<entry>0</entry>
|
||
<entry>UINT32</entry>
|
||
<entry>Return value</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
</para>
|
||
<para>
|
||
Ask the message bus to release the method caller's claim to the given
|
||
name. If the caller is the primary owner, a new primary owner will be
|
||
selected from the queue if any other owners are waiting. If the
|
||
caller is waiting in the queue for the name, the caller will removed
|
||
from the queue and will not be made an owner of the name if it later
|
||
becomes available. If there are no other owners in the queue for the
|
||
name, it will be removed from the bus entirely.
|
||
|
||
The return code can be one of the following values:
|
||
|
||
<informaltable>
|
||
<tgroup cols="3">
|
||
<thead>
|
||
<row>
|
||
<entry>Conventional Name</entry>
|
||
<entry>Value</entry>
|
||
<entry>Description</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row>
|
||
<entry>DBUS_RELEASE_NAME_REPLY_RELEASED</entry>
|
||
<entry>1</entry> <entry>The caller has released his claim on
|
||
the given name. Either the caller was the primary owner of
|
||
the name, and the name is now unused or taken by somebody
|
||
waiting in the queue for the name, or the caller was waiting
|
||
in the queue for the name and has now been removed from the
|
||
queue.</entry>
|
||
</row>
|
||
<row>
|
||
<entry>DBUS_RELEASE_NAME_REPLY_NON_EXISTENT</entry>
|
||
<entry>2</entry>
|
||
<entry>The given name does not exist on this bus.</entry>
|
||
</row>
|
||
<row>
|
||
<entry>DBUS_RELEASE_NAME_REPLY_NOT_OWNER</entry>
|
||
<entry>3</entry>
|
||
<entry>The caller was not the primary owner of this name,
|
||
and was also not waiting in the queue to own this name.</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
</para>
|
||
</sect3>
|
||
|
||
<sect3 id="bus-messages-list-queued-owners">
|
||
<title><literal>org.freedesktop.DBus.ListQueuedOwners</literal></title>
|
||
<para>
|
||
As a method:
|
||
<programlisting>
|
||
ARRAY of STRING ListQueuedOwners (in STRING name)
|
||
</programlisting>
|
||
Message arguments:
|
||
<informaltable>
|
||
<tgroup cols="3">
|
||
<thead>
|
||
<row>
|
||
<entry>Argument</entry>
|
||
<entry>Type</entry>
|
||
<entry>Description</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row>
|
||
<entry>0</entry>
|
||
<entry>STRING</entry>
|
||
<entry>The well-known bus name to query, such as
|
||
<literal>com.example.cappuccino</literal></entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
Reply arguments:
|
||
<informaltable>
|
||
<tgroup cols="3">
|
||
<thead>
|
||
<row>
|
||
<entry>Argument</entry>
|
||
<entry>Type</entry>
|
||
<entry>Description</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row>
|
||
<entry>0</entry>
|
||
<entry>ARRAY of STRING</entry>
|
||
<entry>The unique bus names of connections currently queued
|
||
for the name</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
</para>
|
||
<para>
|
||
List the connections currently queued for a bus name (see
|
||
<xref linkend="term-queued-owner"/>).
|
||
</para>
|
||
</sect3>
|
||
|
||
<sect3 id="bus-messages-list-names">
|
||
<title><literal>org.freedesktop.DBus.ListNames</literal></title>
|
||
<para>
|
||
As a method:
|
||
<programlisting>
|
||
ARRAY of STRING ListNames ()
|
||
</programlisting>
|
||
Reply arguments:
|
||
<informaltable>
|
||
<tgroup cols="3">
|
||
<thead>
|
||
<row>
|
||
<entry>Argument</entry>
|
||
<entry>Type</entry>
|
||
<entry>Description</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row>
|
||
<entry>0</entry>
|
||
<entry>ARRAY of STRING</entry>
|
||
<entry>Array of strings where each string is a bus name</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
</para>
|
||
<para>
|
||
Returns a list of all currently-owned names on the bus.
|
||
</para>
|
||
</sect3>
|
||
<sect3 id="bus-messages-list-activatable-names">
|
||
<title><literal>org.freedesktop.DBus.ListActivatableNames</literal></title>
|
||
<para>
|
||
As a method:
|
||
<programlisting>
|
||
ARRAY of STRING ListActivatableNames ()
|
||
</programlisting>
|
||
Reply arguments:
|
||
<informaltable>
|
||
<tgroup cols="3">
|
||
<thead>
|
||
<row>
|
||
<entry>Argument</entry>
|
||
<entry>Type</entry>
|
||
<entry>Description</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row>
|
||
<entry>0</entry>
|
||
<entry>ARRAY of STRING</entry>
|
||
<entry>Array of strings where each string is a bus name</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
</para>
|
||
<para>
|
||
Returns a list of all names that can be activated on the bus.
|
||
</para>
|
||
</sect3>
|
||
<sect3 id="bus-messages-name-exists">
|
||
<title><literal>org.freedesktop.DBus.NameHasOwner</literal></title>
|
||
<para>
|
||
As a method:
|
||
<programlisting>
|
||
BOOLEAN NameHasOwner (in STRING name)
|
||
</programlisting>
|
||
Message arguments:
|
||
<informaltable>
|
||
<tgroup cols="3">
|
||
<thead>
|
||
<row>
|
||
<entry>Argument</entry>
|
||
<entry>Type</entry>
|
||
<entry>Description</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row>
|
||
<entry>0</entry>
|
||
<entry>STRING</entry>
|
||
<entry>Name to check</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
Reply arguments:
|
||
<informaltable>
|
||
<tgroup cols="3">
|
||
<thead>
|
||
<row>
|
||
<entry>Argument</entry>
|
||
<entry>Type</entry>
|
||
<entry>Description</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row>
|
||
<entry>0</entry>
|
||
<entry>BOOLEAN</entry>
|
||
<entry>Return value, true if the name exists</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
</para>
|
||
<para>
|
||
Checks if the specified name exists (currently has an owner).
|
||
</para>
|
||
</sect3>
|
||
|
||
<sect3 id="bus-messages-name-owner-changed">
|
||
<title><literal>org.freedesktop.DBus.NameOwnerChanged</literal></title>
|
||
<para>
|
||
This is a signal:
|
||
<programlisting>
|
||
NameOwnerChanged (STRING name, STRING old_owner, STRING new_owner)
|
||
</programlisting>
|
||
Message arguments:
|
||
<informaltable>
|
||
<tgroup cols="3">
|
||
<thead>
|
||
<row>
|
||
<entry>Argument</entry>
|
||
<entry>Type</entry>
|
||
<entry>Description</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row>
|
||
<entry>0</entry>
|
||
<entry>STRING</entry>
|
||
<entry>Name with a new owner</entry>
|
||
</row>
|
||
<row>
|
||
<entry>1</entry>
|
||
<entry>STRING</entry>
|
||
<entry>Old owner or empty string if none</entry>
|
||
</row>
|
||
<row>
|
||
<entry>2</entry>
|
||
<entry>STRING</entry>
|
||
<entry>New owner or empty string if none</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
</para>
|
||
<para>
|
||
This signal indicates that the owner of a name has changed.
|
||
It's also the signal to use to detect the appearance of
|
||
new names on the bus.
|
||
</para>
|
||
</sect3>
|
||
<sect3 id="bus-messages-name-lost">
|
||
<title><literal>org.freedesktop.DBus.NameLost</literal></title>
|
||
<para>
|
||
This is a signal:
|
||
<programlisting>
|
||
NameLost (STRING name)
|
||
</programlisting>
|
||
Message arguments:
|
||
<informaltable>
|
||
<tgroup cols="3">
|
||
<thead>
|
||
<row>
|
||
<entry>Argument</entry>
|
||
<entry>Type</entry>
|
||
<entry>Description</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row>
|
||
<entry>0</entry>
|
||
<entry>STRING</entry>
|
||
<entry>Name which was lost</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
</para>
|
||
<para>
|
||
This signal is sent to a specific application when it loses
|
||
ownership of a name.
|
||
</para>
|
||
</sect3>
|
||
|
||
<sect3 id="bus-messages-name-acquired">
|
||
<title><literal>org.freedesktop.DBus.NameAcquired</literal></title>
|
||
<para>
|
||
This is a signal:
|
||
<programlisting>
|
||
NameAcquired (STRING name)
|
||
</programlisting>
|
||
Message arguments:
|
||
<informaltable>
|
||
<tgroup cols="3">
|
||
<thead>
|
||
<row>
|
||
<entry>Argument</entry>
|
||
<entry>Type</entry>
|
||
<entry>Description</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row>
|
||
<entry>0</entry>
|
||
<entry>STRING</entry>
|
||
<entry>Name which was acquired</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
</para>
|
||
<para>
|
||
This signal is sent to a specific application when it gains
|
||
ownership of a name.
|
||
</para>
|
||
</sect3>
|
||
|
||
<sect3 id="bus-messages-activatable-services-changed">
|
||
<title><literal>org.freedesktop.DBus.ActivatableServicesChanged</literal></title>
|
||
<para>
|
||
This is a signal:
|
||
<programlisting>
|
||
ActivatableServicesChanged ()
|
||
</programlisting>
|
||
</para>
|
||
<para>
|
||
This signal is sent when the list of activatable services,
|
||
as returned by ListActivatableNames(), might have changed
|
||
(see <xref linkend="bus-messages-list-activatable-names"/>).
|
||
Clients that have cached information about the activatable
|
||
services should call ListActivatableNames() again to update
|
||
their cache.
|
||
</para>
|
||
<para>
|
||
The presence of this signal is indicated by a
|
||
bus feature property (for details see
|
||
<xref linkend="message-bus-properties-features"/>).
|
||
In older implementations that do not have this feature,
|
||
there is no way to be informed when the list of activatable
|
||
names has changed.
|
||
</para>
|
||
</sect3>
|
||
|
||
<sect3 id="bus-messages-start-service-by-name">
|
||
<title><literal>org.freedesktop.DBus.StartServiceByName</literal></title>
|
||
<para>
|
||
As a method:
|
||
<programlisting>
|
||
UINT32 StartServiceByName (in STRING name, in UINT32 flags)
|
||
</programlisting>
|
||
Message arguments:
|
||
<informaltable>
|
||
<tgroup cols="3">
|
||
<thead>
|
||
<row>
|
||
<entry>Argument</entry>
|
||
<entry>Type</entry>
|
||
<entry>Description</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row>
|
||
<entry>0</entry>
|
||
<entry>STRING</entry>
|
||
<entry>Name of the service to start</entry>
|
||
</row>
|
||
<row>
|
||
<entry>1</entry>
|
||
<entry>UINT32</entry>
|
||
<entry>Flags (currently not used)</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
Reply arguments:
|
||
<informaltable>
|
||
<tgroup cols="3">
|
||
<thead>
|
||
<row>
|
||
<entry>Argument</entry>
|
||
<entry>Type</entry>
|
||
<entry>Description</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row>
|
||
<entry>0</entry>
|
||
<entry>UINT32</entry>
|
||
<entry>Return value</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
Tries to launch the executable associated with a name (service
|
||
activation), as an explicit request. This is an alternative to
|
||
relying on auto-starting. For more information on how services
|
||
are activated and the difference between auto-starting and explicit
|
||
activation, see
|
||
<xref linkend="message-bus-starting-services"/>.
|
||
</para>
|
||
<para>
|
||
It is often preferable to carry out auto-starting
|
||
instead of calling this method. This is because calling this method
|
||
is subject to a
|
||
<ulink url="https://en.wikipedia.org/wiki/Time_of_check_to_time_of_use">time-of-check/time-of-use</ulink>
|
||
issue: if a caller asks the message bus to start a service so that
|
||
the same caller can make follow-up method calls to that service,
|
||
the fact that the message bus was able to start the required
|
||
service is no guarantee that it will not have crashed or otherwise
|
||
exited by the time the caller makes those follow-up method calls.
|
||
As a result, calling this method does not remove the need for
|
||
the caller to handle errors from method calls. Given that fact,
|
||
it is usually simpler to rely on auto-starting, in which the
|
||
required service starts as a side-effect of the first method call.
|
||
</para>
|
||
<para>
|
||
The return value can be one of the following values:
|
||
<informaltable>
|
||
<tgroup cols="3">
|
||
<thead>
|
||
<row>
|
||
<entry>Identifier</entry>
|
||
<entry>Value</entry>
|
||
<entry>Description</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row>
|
||
<entry>DBUS_START_REPLY_SUCCESS</entry>
|
||
<entry>1</entry>
|
||
<entry>The service was successfully started.</entry>
|
||
</row>
|
||
<row>
|
||
<entry>DBUS_START_REPLY_ALREADY_RUNNING</entry>
|
||
<entry>2</entry>
|
||
<entry>A connection already owns the given name.</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
</para>
|
||
|
||
</sect3>
|
||
|
||
<sect3 id="bus-messages-update-activation-environment">
|
||
<title><literal>org.freedesktop.DBus.UpdateActivationEnvironment</literal></title>
|
||
<para>
|
||
As a method:
|
||
<programlisting>
|
||
UpdateActivationEnvironment (in ARRAY of DICT_ENTRY<STRING,STRING> environment)
|
||
</programlisting>
|
||
Message arguments:
|
||
<informaltable>
|
||
<tgroup cols="3">
|
||
<thead>
|
||
<row>
|
||
<entry>Argument</entry>
|
||
<entry>Type</entry>
|
||
<entry>Description</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row>
|
||
<entry>0</entry>
|
||
<entry>ARRAY of DICT_ENTRY<STRING,STRING></entry>
|
||
<entry>Environment to add or update</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
Normally, session bus activated services inherit the environment of the bus daemon. This method adds to or modifies that environment when activating services.
|
||
</para>
|
||
<para>
|
||
Some bus instances, such as the standard system bus, may disable access to this method for some or all callers.
|
||
</para>
|
||
<para>
|
||
Note, both the environment variable names and values must be valid UTF-8. There's no way to update the activation environment with data that is invalid UTF-8.
|
||
</para>
|
||
|
||
</sect3>
|
||
|
||
<sect3 id="bus-messages-get-name-owner">
|
||
<title><literal>org.freedesktop.DBus.GetNameOwner</literal></title>
|
||
<para>
|
||
As a method:
|
||
<programlisting>
|
||
STRING GetNameOwner (in STRING name)
|
||
</programlisting>
|
||
Message arguments:
|
||
<informaltable>
|
||
<tgroup cols="3">
|
||
<thead>
|
||
<row>
|
||
<entry>Argument</entry>
|
||
<entry>Type</entry>
|
||
<entry>Description</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row>
|
||
<entry>0</entry>
|
||
<entry>STRING</entry>
|
||
<entry>Name to get the owner of</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
Reply arguments:
|
||
<informaltable>
|
||
<tgroup cols="3">
|
||
<thead>
|
||
<row>
|
||
<entry>Argument</entry>
|
||
<entry>Type</entry>
|
||
<entry>Description</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row>
|
||
<entry>0</entry>
|
||
<entry>STRING</entry>
|
||
<entry>Return value, a unique connection name</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
Returns the unique connection name of the primary owner of the name
|
||
given. If the requested name doesn't have an owner, returns a
|
||
<literal>org.freedesktop.DBus.Error.NameHasNoOwner</literal> error.
|
||
</para>
|
||
</sect3>
|
||
|
||
<sect3 id="bus-messages-get-connection-unix-user">
|
||
<title><literal>org.freedesktop.DBus.GetConnectionUnixUser</literal></title>
|
||
<para>
|
||
As a method:
|
||
<programlisting>
|
||
UINT32 GetConnectionUnixUser (in STRING bus_name)
|
||
</programlisting>
|
||
Message arguments:
|
||
<informaltable>
|
||
<tgroup cols="3">
|
||
<thead>
|
||
<row>
|
||
<entry>Argument</entry>
|
||
<entry>Type</entry>
|
||
<entry>Description</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row>
|
||
<entry>0</entry>
|
||
<entry>STRING</entry>
|
||
<entry>Unique or well-known bus name of the connection to
|
||
query, such as <literal>:12.34</literal> or
|
||
<literal>com.example.tea</literal></entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
Reply arguments:
|
||
<informaltable>
|
||
<tgroup cols="3">
|
||
<thead>
|
||
<row>
|
||
<entry>Argument</entry>
|
||
<entry>Type</entry>
|
||
<entry>Description</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row>
|
||
<entry>0</entry>
|
||
<entry>UINT32</entry>
|
||
<entry>Unix user ID</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
Returns the Unix user ID of the process connected to the server. If
|
||
unable to determine it (for instance, because the process is not on the
|
||
same machine as the bus daemon), an error is returned.
|
||
</para>
|
||
</sect3>
|
||
|
||
<sect3 id="bus-messages-get-connection-unix-process-id">
|
||
<title><literal>org.freedesktop.DBus.GetConnectionUnixProcessID</literal></title>
|
||
<para>
|
||
As a method:
|
||
<programlisting>
|
||
UINT32 GetConnectionUnixProcessID (in STRING bus_name)
|
||
</programlisting>
|
||
Message arguments:
|
||
<informaltable>
|
||
<tgroup cols="3">
|
||
<thead>
|
||
<row>
|
||
<entry>Argument</entry>
|
||
<entry>Type</entry>
|
||
<entry>Description</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row>
|
||
<entry>0</entry>
|
||
<entry>STRING</entry>
|
||
<entry>Unique or well-known bus name of the connection to
|
||
query, such as <literal>:12.34</literal> or
|
||
<literal>com.example.tea</literal></entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
Reply arguments:
|
||
<informaltable>
|
||
<tgroup cols="3">
|
||
<thead>
|
||
<row>
|
||
<entry>Argument</entry>
|
||
<entry>Type</entry>
|
||
<entry>Description</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row>
|
||
<entry>0</entry>
|
||
<entry>UINT32</entry>
|
||
<entry>Unix process id</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
Returns the Unix process ID of the process connected to the server. If
|
||
unable to determine it (for instance, because the process is not on the
|
||
same machine as the bus daemon), an error is returned.
|
||
</para>
|
||
</sect3>
|
||
|
||
<sect3 id="bus-messages-get-connection-credentials">
|
||
<title><literal>org.freedesktop.DBus.GetConnectionCredentials</literal></title>
|
||
<para>
|
||
As a method:
|
||
<programlisting>
|
||
ARRAY of DICT_ENTRY<STRING,VARIANT> GetConnectionCredentials (in STRING bus_name)
|
||
</programlisting>
|
||
Message arguments:
|
||
<informaltable>
|
||
<tgroup cols="3">
|
||
<thead>
|
||
<row>
|
||
<entry>Argument</entry>
|
||
<entry>Type</entry>
|
||
<entry>Description</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row>
|
||
<entry>0</entry>
|
||
<entry>STRING</entry>
|
||
<entry>Unique or well-known bus name of the connection to
|
||
query, such as <literal>:12.34</literal> or
|
||
<literal>com.example.tea</literal></entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
Reply arguments:
|
||
<informaltable>
|
||
<tgroup cols="3">
|
||
<thead>
|
||
<row>
|
||
<entry>Argument</entry>
|
||
<entry>Type</entry>
|
||
<entry>Description</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row>
|
||
<entry>0</entry>
|
||
<entry>ARRAY of DICT_ENTRY<STRING,VARIANT></entry>
|
||
<entry>Credentials</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
</para>
|
||
|
||
<para>
|
||
Returns as many credentials as possible for the process connected to
|
||
the server. If unable to determine certain credentials (for instance,
|
||
because the process is not on the same machine as the bus daemon,
|
||
or because this version of the bus daemon does not support a
|
||
particular security framework), or if the values of those credentials
|
||
cannot be represented as documented here, then those credentials
|
||
are omitted.
|
||
</para>
|
||
|
||
<para>
|
||
Keys in the returned dictionary not containing "." are defined
|
||
by this specification. Bus daemon implementors supporting
|
||
credentials frameworks not mentioned in this document should either
|
||
contribute patches to this specification, or use keys containing
|
||
"." and starting with a reversed domain name.
|
||
<informaltable>
|
||
<tgroup cols="3">
|
||
<thead>
|
||
<row>
|
||
<entry>Key</entry>
|
||
<entry>Value type</entry>
|
||
<entry>Value</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row>
|
||
<entry>UnixUserID</entry>
|
||
<entry>UINT32</entry>
|
||
<entry>The numeric Unix user ID, as defined by POSIX</entry>
|
||
</row>
|
||
<row>
|
||
<entry>UnixGroupIDs</entry>
|
||
<entry>ARRAY of UINT32</entry>
|
||
<entry>The numeric Unix group IDs (including both the primary
|
||
group and the supplementary groups), as defined by POSIX, in
|
||
numerically sorted order. This array is either complete or
|
||
absent: if the message bus is able to determine some but not
|
||
all of the caller's groups, or if one of the groups is not
|
||
representable in a UINT32, it must not add this credential
|
||
to the dictionary.
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry>ProcessID</entry>
|
||
<entry>UINT32</entry>
|
||
<entry>The numeric process ID, on platforms that have
|
||
this concept. On Unix, this is the process ID defined by
|
||
POSIX.</entry>
|
||
</row>
|
||
<row>
|
||
<entry>WindowsSID</entry>
|
||
<entry>STRING</entry>
|
||
<entry>The Windows security identifier in its string form,
|
||
e.g. "S-1-5-21-3623811015-3361044348-30300820-1013" for
|
||
a domain or local computer user or "S-1-5-18" for the
|
||
LOCAL_SYSTEM user</entry>
|
||
</row>
|
||
|
||
<row>
|
||
<entry>LinuxSecurityLabel</entry>
|
||
<entry>ARRAY of BYTE</entry>
|
||
<entry>
|
||
<para>On Linux systems, the security label that would result
|
||
from the SO_PEERSEC getsockopt call. The array contains
|
||
the non-zero bytes of the security label in an unspecified
|
||
ASCII-compatible encoding<footnote>
|
||
<para>It could be ASCII or UTF-8, but could also be
|
||
ISO Latin-1 or any other encoding.</para>
|
||
</footnote>, followed by a single zero byte.</para>
|
||
<para>
|
||
For example, the SELinux context
|
||
<literal>system_u:system_r:init_t:s0</literal>
|
||
(a string of length 27) would be encoded as 28 bytes
|
||
ending with ':', 's', '0', '\x00'.<footnote>
|
||
<para>Note that this is not the same as the older
|
||
GetConnectionSELinuxContext method, which does
|
||
not append the zero byte. Always appending the
|
||
zero byte allows callers to read the string
|
||
from the message payload without copying.</para>
|
||
</footnote>
|
||
</para>
|
||
<para>
|
||
On SELinux systems this is the SELinux context, as output
|
||
by <literal>ps -Z</literal> or <literal>ls -Z</literal>.
|
||
Typical values might include
|
||
<literal>system_u:system_r:init_t:s0</literal>,
|
||
<literal>unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023</literal>,
|
||
or
|
||
<literal>unconfined_u:unconfined_r:chrome_sandbox_t:s0-s0:c0.c1023</literal>.
|
||
</para>
|
||
<para>
|
||
On Smack systems, this is the Smack label.
|
||
Typical values might include
|
||
<literal>_</literal>, <literal>*</literal>,
|
||
<literal>User</literal>, <literal>System</literal>
|
||
or <literal>System::Shared</literal>.
|
||
</para>
|
||
<para>
|
||
On AppArmor systems, this is the AppArmor context,
|
||
a composite string encoding the AppArmor label (one or more
|
||
profiles) and the enforcement mode.
|
||
Typical values might include <literal>unconfined</literal>,
|
||
<literal>/usr/bin/firefox (enforce)</literal> or
|
||
<literal>user1 (complain)</literal>.
|
||
</para>
|
||
</entry>
|
||
</row>
|
||
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
</para>
|
||
|
||
<para>
|
||
This method was added in D-Bus 1.7 to reduce the round-trips
|
||
required to list a process's credentials. In older versions, calling
|
||
this method will fail: applications should recover by using the
|
||
separate methods such as
|
||
<xref linkend="bus-messages-get-connection-unix-user"/>
|
||
instead.
|
||
</para>
|
||
</sect3>
|
||
|
||
<sect3 id="bus-messages-get-adt-audit-session-data">
|
||
<title><literal>org.freedesktop.DBus.GetAdtAuditSessionData</literal></title>
|
||
<para>
|
||
As a method:
|
||
<programlisting>
|
||
ARRAY of BYTE GetAdtAuditSessionData (in STRING bus_name)
|
||
</programlisting>
|
||
Message arguments:
|
||
<informaltable>
|
||
<tgroup cols="3">
|
||
<thead>
|
||
<row>
|
||
<entry>Argument</entry>
|
||
<entry>Type</entry>
|
||
<entry>Description</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row>
|
||
<entry>0</entry>
|
||
<entry>STRING</entry>
|
||
<entry>Unique or well-known bus name of the connection to
|
||
query, such as <literal>:12.34</literal> or
|
||
<literal>com.example.tea</literal></entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
Reply arguments:
|
||
<informaltable>
|
||
<tgroup cols="3">
|
||
<thead>
|
||
<row>
|
||
<entry>Argument</entry>
|
||
<entry>Type</entry>
|
||
<entry>Description</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row>
|
||
<entry>0</entry>
|
||
<entry>ARRAY of BYTE</entry>
|
||
<entry>auditing data as returned by
|
||
adt_export_session_data()</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
Returns auditing data used by Solaris ADT, in an unspecified
|
||
binary format. If you know what this means, please contribute
|
||
documentation via the D-Bus bug tracking system.
|
||
This method is on the core DBus interface for historical reasons;
|
||
the same information should be made available via
|
||
<xref linkend="bus-messages-get-connection-credentials"/>
|
||
in future.
|
||
</para>
|
||
</sect3>
|
||
|
||
<sect3 id="bus-messages-get-connection-selinux-security-context">
|
||
<title><literal>org.freedesktop.DBus.GetConnectionSELinuxSecurityContext</literal></title>
|
||
<para>
|
||
As a method:
|
||
<programlisting>
|
||
ARRAY of BYTE GetConnectionSELinuxSecurityContext (in STRING bus_name)
|
||
</programlisting>
|
||
Message arguments:
|
||
<informaltable>
|
||
<tgroup cols="3">
|
||
<thead>
|
||
<row>
|
||
<entry>Argument</entry>
|
||
<entry>Type</entry>
|
||
<entry>Description</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row>
|
||
<entry>0</entry>
|
||
<entry>STRING</entry>
|
||
<entry>Unique or well-known bus name of the connection to
|
||
query, such as <literal>:12.34</literal> or
|
||
<literal>com.example.tea</literal></entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
Reply arguments:
|
||
<informaltable>
|
||
<tgroup cols="3">
|
||
<thead>
|
||
<row>
|
||
<entry>Argument</entry>
|
||
<entry>Type</entry>
|
||
<entry>Description</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row>
|
||
<entry>0</entry>
|
||
<entry>ARRAY of BYTE</entry>
|
||
<entry>some sort of string of bytes, not necessarily UTF-8,
|
||
not including '\0'</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
Returns the security context used by SELinux, in an unspecified
|
||
format. If you know what this means, please contribute
|
||
documentation via the D-Bus bug tracking system.
|
||
This method is on the core DBus interface for historical reasons;
|
||
the same information should be made available via
|
||
<xref linkend="bus-messages-get-connection-credentials"/>
|
||
in future.
|
||
</para>
|
||
</sect3>
|
||
|
||
|
||
<sect3 id="bus-messages-add-match">
|
||
<title><literal>org.freedesktop.DBus.AddMatch</literal></title>
|
||
<para>
|
||
As a method:
|
||
<programlisting>
|
||
AddMatch (in STRING rule)
|
||
</programlisting>
|
||
Message arguments:
|
||
<informaltable>
|
||
<tgroup cols="3">
|
||
<thead>
|
||
<row>
|
||
<entry>Argument</entry>
|
||
<entry>Type</entry>
|
||
<entry>Description</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row>
|
||
<entry>0</entry>
|
||
<entry>STRING</entry>
|
||
<entry>Match rule to add to the connection</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
Adds a match rule to match messages going through the message bus (see <xref linkend='message-bus-routing-match-rules'/>).
|
||
If the bus does not have enough resources the <literal>org.freedesktop.DBus.Error.OOM</literal>
|
||
error is returned.
|
||
</para>
|
||
</sect3>
|
||
<sect3 id="bus-messages-remove-match">
|
||
<title><literal>org.freedesktop.DBus.RemoveMatch</literal></title>
|
||
<para>
|
||
As a method:
|
||
<programlisting>
|
||
RemoveMatch (in STRING rule)
|
||
</programlisting>
|
||
Message arguments:
|
||
<informaltable>
|
||
<tgroup cols="3">
|
||
<thead>
|
||
<row>
|
||
<entry>Argument</entry>
|
||
<entry>Type</entry>
|
||
<entry>Description</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row>
|
||
<entry>0</entry>
|
||
<entry>STRING</entry>
|
||
<entry>Match rule to remove from the connection</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
Removes the first rule that matches (see <xref linkend='message-bus-routing-match-rules'/>).
|
||
If the rule is not found the <literal>org.freedesktop.DBus.Error.MatchRuleNotFound</literal>
|
||
error is returned.
|
||
</para>
|
||
</sect3>
|
||
|
||
<sect3 id="bus-messages-get-id">
|
||
<title><literal>org.freedesktop.DBus.GetId</literal></title>
|
||
<para>
|
||
As a method:
|
||
<programlisting>
|
||
GetId (out STRING id)
|
||
</programlisting>
|
||
Reply arguments:
|
||
<informaltable>
|
||
<tgroup cols="3">
|
||
<thead>
|
||
<row>
|
||
<entry>Argument</entry>
|
||
<entry>Type</entry>
|
||
<entry>Description</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row>
|
||
<entry>0</entry>
|
||
<entry>STRING</entry>
|
||
<entry>Unique ID identifying the bus daemon</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
Gets the unique ID of the bus. The unique ID here is shared among all addresses the
|
||
bus daemon is listening on (TCP, UNIX domain socket, etc.) and its format is described in
|
||
<xref linkend="uuids"/>. Each address the bus is listening on also has its own unique
|
||
ID, as described in <xref linkend="addresses"/>. The per-bus and per-address IDs are not related.
|
||
There is also a per-machine ID, described in <xref linkend="standard-interfaces-peer"/> and returned
|
||
by org.freedesktop.DBus.Peer.GetMachineId().
|
||
For a desktop session bus, the bus ID can be used as a way to uniquely identify a user's session.
|
||
</para>
|
||
</sect3>
|
||
|
||
<sect3 id="bus-messages-become-monitor">
|
||
<title><literal>org.freedesktop.DBus.Monitoring.BecomeMonitor</literal></title>
|
||
<para>
|
||
As a method:
|
||
<programlisting>
|
||
BecomeMonitor (in ARRAY of STRING rule, in UINT32 flags)
|
||
</programlisting>
|
||
Message arguments:
|
||
<informaltable>
|
||
<tgroup cols="3">
|
||
<thead>
|
||
<row>
|
||
<entry>Argument</entry>
|
||
<entry>Type</entry>
|
||
<entry>Description</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row>
|
||
<entry>0</entry>
|
||
<entry>ARRAY of STRING</entry>
|
||
<entry>Match rules to add to the connection</entry>
|
||
</row>
|
||
<row>
|
||
<entry>1</entry>
|
||
<entry>UINT32</entry>
|
||
<entry>Not used, must be 0</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</informaltable>
|
||
</para>
|
||
|
||
<para>
|
||
Converts the connection into a <emphasis>monitor
|
||
connection</emphasis> which can be used as a debugging/monitoring
|
||
tool. Only a user who is privileged on this
|
||
bus (by some implementation-specific definition) may create
|
||
monitor connections<footnote>
|
||
<para>
|
||
In the reference implementation,
|
||
the default configuration is that each user (identified by
|
||
numeric user ID) may monitor their own session bus,
|
||
and the root user (user ID zero) may monitor the
|
||
system bus.
|
||
</para>
|
||
</footnote>.
|
||
</para>
|
||
|
||
<para>
|
||
Monitor connections lose all their bus names, including the unique
|
||
connection name, and all their match rules. Sending messages on a
|
||
monitor connection is not allowed: applications should use a private
|
||
connection for monitoring.
|
||
</para>
|
||
|
||
<para>
|
||
Monitor connections may receive all messages, even messages that
|
||
should only have gone to some other connection ("eavesdropping").
|
||
The first argument is a list of match rules, which replace any
|
||
match rules that were previously active for this connection.
|
||
These match rules are always treated as if they contained the
|
||
special <literal>eavesdrop='true'</literal> member.
|
||
</para>
|
||
|
||
<para>
|
||
As a special case, an empty list of match rules (which would
|
||
otherwise match nothing, making the monitor useless) is treated
|
||
as a shorthand for matching all messages.
|
||
</para>
|
||
|
||
<para>
|
||
The second argument might be used for flags to influence the
|
||
behaviour of the monitor connection in future D-Bus versions.
|
||
</para>
|
||
|
||
<para>
|
||
Message bus implementations should attempt to minimize the
|
||
side-effects of monitoring — in particular, unlike ordinary
|
||
eavesdropping, monitoring the system bus does not require the
|
||
access control rules to be relaxed, which would change the set
|
||
of messages that can be delivered to their (non-monitor)
|
||
destinations. However, it is unavoidable that monitoring
|
||
will increase the message bus's resource consumption. In
|
||
edge cases where there was barely enough time or memory without
|
||
monitoring, this might result in message deliveries failing
|
||
when they would otherwise have succeeded.
|
||
</para>
|
||
</sect3>
|
||
|
||
</sect2>
|
||
|
||
<sect2 id="message-bus-properties">
|
||
<title>Message Bus Properties</title>
|
||
<para>
|
||
The special message bus name <literal>org.freedesktop.DBus</literal>
|
||
exports several properties (see
|
||
<xref linkend="standard-interfaces-properties"/>) on the object path
|
||
<literal>/org/freedesktop/DBus</literal>.
|
||
</para>
|
||
|
||
<sect3 id="message-bus-properties-features">
|
||
<title><literal>org.freedesktop.DBus.Features</literal></title>
|
||
<para>
|
||
As a property:
|
||
<programlisting>
|
||
Read-only constant ARRAY of STRING Features
|
||
</programlisting>
|
||
This property lists abstract “features” provided by the message
|
||
bus, and can be used by clients to detect the capabilities
|
||
of the message bus with which they are communicating.
|
||
This property was added in version 1.11.x of the reference
|
||
implementation of the message bus.
|
||
</para>
|
||
|
||
<para>
|
||
Items in the returned array not containing “.” are defined
|
||
by this specification. Bus daemon implementors wishing to advertise
|
||
features not mentioned in this document should either contribute
|
||
patches to this specification, or use keys containing “.” and
|
||
starting with their own reversed domain name, for example
|
||
<literal>com.example.MyBus.SubliminalMessages</literal>.
|
||
</para>
|
||
|
||
<para>
|
||
The features currently defined in this specification are as follows:
|
||
<variablelist>
|
||
|
||
<varlistentry>
|
||
<term><literal>ActivatableServicesChanged</literal></term>
|
||
<listitem>
|
||
<para>
|
||
This message bus emits the <literal>ActivatableServicesChanged</literal>
|
||
signal whenever its list of activatable services might have changed
|
||
(for details see <xref linkend="bus-messages-activatable-services-changed"/>).
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
|
||
<varlistentry>
|
||
<term><literal>AppArmor</literal></term>
|
||
<listitem>
|
||
<para>
|
||
This message bus filters messages via the
|
||
<ulink url="http://wiki.apparmor.net/">AppArmor</ulink>
|
||
security framework. This feature should only be
|
||
advertised if AppArmor mediation is enabled and
|
||
active at runtime; merely compiling in support
|
||
for AppArmor should not result in this feature being
|
||
advertised on message bus instances where it is disabled by
|
||
message bus or operating system configuration.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
|
||
<varlistentry>
|
||
<term><literal>HeaderFiltering</literal></term>
|
||
<listitem>
|
||
<para>
|
||
This message bus guarantees that it will remove
|
||
header fields that it does not understand when it
|
||
relays messages, so that a client receiving a
|
||
recently-defined header field that is specified to be
|
||
controlled by the message bus can safely assume that
|
||
it was in fact set by the message bus. This check is
|
||
needed because older message bus implementations did
|
||
not guarantee to filter headers in this way, so a
|
||
malicious client could send any recently-defined
|
||
header field with a crafted value of its choice
|
||
through an older message bus that did not understand
|
||
that header field.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
|
||
<varlistentry>
|
||
<term><literal>SELinux</literal></term>
|
||
<listitem>
|
||
<para>
|
||
This message bus filters messages via the
|
||
<ulink url="https://selinuxproject.org/">SELinux</ulink>
|
||
security framework. Similar to <literal>apparmor</literal>,
|
||
this feature should only be advertised if SELinux mediation
|
||
is enabled and active at runtime (if SELinux is placed in
|
||
permissive mode, that is still considered to be active).
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
|
||
<varlistentry>
|
||
<term><literal>SystemdActivation</literal></term>
|
||
<listitem>
|
||
<para>
|
||
When asked to activate a service that has the
|
||
<literal>SystemdService</literal> field in its
|
||
<filename>.service</filename> file, this message bus will
|
||
carry out systemd activation (for details see
|
||
<xref linkend="message-bus-starting-services-systemd"/>).
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
|
||
</variablelist>
|
||
</para>
|
||
</sect3>
|
||
|
||
<sect3 id="message-bus-properties-interfaces">
|
||
<title><literal>org.freedesktop.DBus.Interfaces</literal></title>
|
||
<para>
|
||
As a property:
|
||
<programlisting>
|
||
Read-only constant ARRAY of STRING Interfaces
|
||
</programlisting>
|
||
This property lists interfaces provided by the
|
||
<literal>/org/freedesktop/DBus</literal> object,
|
||
and can be used by clients to detect the capabilities
|
||
of the message bus with which they are communicating.
|
||
Unlike the standard Introspectable interface, querying this
|
||
property does not require parsing XML.
|
||
This property was added in version 1.11.x of the reference
|
||
implementation of the message bus.
|
||
</para>
|
||
|
||
<para>
|
||
The standard <literal>org.freedesktop.DBus</literal> and
|
||
<literal>org.freedesktop.DBus.Properties</literal> interfaces
|
||
are not included in the value of this property, because their
|
||
presence can be inferred from the fact that a method call on
|
||
<literal>org.freedesktop.DBus.Properties</literal> asking for
|
||
properties of <literal>org.freedesktop.DBus</literal> was
|
||
successful. The standard <literal>org.freedesktop.DBus.Peer</literal>
|
||
and <literal>org.freedesktop.DBus.Introspectable</literal>
|
||
interfaces are not included in the value of this property either,
|
||
because they do not indicate features of the message bus
|
||
implementation.
|
||
</para>
|
||
</sect3>
|
||
</sect2>
|
||
|
||
</sect1>
|
||
<!--
|
||
<appendix id="implementation-notes">
|
||
<title>Implementation notes</title>
|
||
<sect1 id="implementation-notes-subsection">
|
||
<title></title>
|
||
<para>
|
||
</para>
|
||
</sect1>
|
||
</appendix>
|
||
-->
|
||
|
||
<glossary><title>Glossary</title>
|
||
<para>
|
||
This glossary defines some of the terms used in this specification.
|
||
</para>
|
||
|
||
<glossentry id="term-bus-name"><glossterm>Bus Name</glossterm>
|
||
<glossdef>
|
||
<para>
|
||
The message bus maintains an association between names and
|
||
connections. (Normally, there's one connection per application.) A
|
||
bus name is simply an identifier used to locate connections. For
|
||
example, the hypothetical <literal>com.yoyodyne.Screensaver</literal>
|
||
name might be used to send a message to a screensaver from Yoyodyne
|
||
Corporation. An application is said to <firstterm>own</firstterm> a
|
||
name if the message bus has associated the application's connection
|
||
with the name. Names may also have <firstterm>queued
|
||
owners</firstterm> (see <xref linkend="term-queued-owner"/>).
|
||
The bus assigns a unique name to each connection,
|
||
see <xref linkend="term-unique-name"/>. Other names
|
||
can be thought of as "well-known names" and are
|
||
used to find applications that offer specific functionality.
|
||
</para>
|
||
|
||
<para>
|
||
See <xref linkend="message-protocol-names-bus"/> for details of
|
||
the syntax and naming conventions for bus names.
|
||
</para>
|
||
</glossdef>
|
||
</glossentry>
|
||
|
||
<glossentry id="term-message"><glossterm>Message</glossterm>
|
||
<glossdef>
|
||
<para>
|
||
A message is the atomic unit of communication via the D-Bus
|
||
protocol. It consists of a <firstterm>header</firstterm> and a
|
||
<firstterm>body</firstterm>; the body is made up of
|
||
<firstterm>arguments</firstterm>.
|
||
</para>
|
||
</glossdef>
|
||
</glossentry>
|
||
|
||
<glossentry id="term-message-bus"><glossterm>Message Bus</glossterm>
|
||
<glossdef>
|
||
<para>
|
||
The message bus is a special application that forwards
|
||
or routes messages between a group of applications
|
||
connected to the message bus. It also manages
|
||
<firstterm>names</firstterm> used for routing
|
||
messages.
|
||
</para>
|
||
</glossdef>
|
||
</glossentry>
|
||
|
||
<glossentry id="term-name"><glossterm>Name</glossterm>
|
||
<glossdef>
|
||
<para>
|
||
See <xref linkend="term-bus-name"/>. "Name" may
|
||
also be used to refer to some of the other names
|
||
in D-Bus, such as interface names.
|
||
</para>
|
||
</glossdef>
|
||
</glossentry>
|
||
|
||
<glossentry id="namespace"><glossterm>Namespace</glossterm>
|
||
<glossdef>
|
||
<para>
|
||
Used to prevent collisions when defining new interfaces, bus names
|
||
etc. The convention used is the same one Java uses for defining
|
||
classes: a reversed domain name.
|
||
See <xref linkend="message-protocol-names-bus"/>,
|
||
<xref linkend="message-protocol-names-interface"/>,
|
||
<xref linkend="message-protocol-names-error"/>,
|
||
<xref linkend="message-protocol-marshaling-object-path"/>.
|
||
</para>
|
||
</glossdef>
|
||
</glossentry>
|
||
|
||
<glossentry id="term-object"><glossterm>Object</glossterm>
|
||
<glossdef>
|
||
<para>
|
||
Each application contains <firstterm>objects</firstterm>, which have
|
||
<firstterm>interfaces</firstterm> and
|
||
<firstterm>methods</firstterm>. Objects are referred to by a name,
|
||
called a <firstterm>path</firstterm>.
|
||
</para>
|
||
</glossdef>
|
||
</glossentry>
|
||
|
||
<glossentry id="one-to-one"><glossterm>One-to-One</glossterm>
|
||
<glossdef>
|
||
<para>
|
||
An application talking directly to another application, without going
|
||
through a message bus. One-to-one connections may be "peer to peer" or
|
||
"client to server." The D-Bus protocol has no concept of client
|
||
vs. server after a connection has authenticated; the flow of messages
|
||
is symmetrical (full duplex).
|
||
</para>
|
||
</glossdef>
|
||
</glossentry>
|
||
|
||
<glossentry id="term-path"><glossterm>Path</glossterm>
|
||
<glossdef>
|
||
<para>
|
||
Object references (object names) in D-Bus are organized into a
|
||
filesystem-style hierarchy, so each object is named by a path. As in
|
||
LDAP, there's no difference between "files" and "directories"; a path
|
||
can refer to an object, while still having child objects below it.
|
||
</para>
|
||
</glossdef>
|
||
</glossentry>
|
||
|
||
<glossentry id="term-queued-owner"><glossterm>Queued Name Owner</glossterm>
|
||
<glossdef>
|
||
<para>
|
||
Each bus name has a primary owner; messages sent to the name go to the
|
||
primary owner. However, certain names also maintain a queue of
|
||
secondary owners "waiting in the wings." If the primary owner releases
|
||
the name, then the first secondary owner in the queue automatically
|
||
becomes the new owner of the name.
|
||
</para>
|
||
</glossdef>
|
||
</glossentry>
|
||
|
||
<glossentry id="term-service"><glossterm>Service</glossterm>
|
||
<glossdef>
|
||
<para>
|
||
A service is an executable that can be launched by the bus daemon.
|
||
Services normally guarantee some particular features, for example they
|
||
may guarantee that they will request a specific name such as
|
||
"com.example.Screensaver1", have a singleton object
|
||
"/com/example/Screensaver1", and that object will implement the
|
||
interface "com.example.Screensaver1.Control".
|
||
</para>
|
||
</glossdef>
|
||
</glossentry>
|
||
|
||
<glossentry id="term-service-description-files"><glossterm>Service Description Files</glossterm>
|
||
<glossdef>
|
||
<para>
|
||
".service files" tell the bus about service applications that can be
|
||
launched (see <xref linkend="term-service"/>). Most importantly they
|
||
provide a mapping from bus names to services that will request those
|
||
names when they start up.
|
||
</para>
|
||
</glossdef>
|
||
</glossentry>
|
||
|
||
<glossentry id="term-unique-name"><glossterm>Unique Connection Name</glossterm>
|
||
<glossdef>
|
||
<para>
|
||
The special name automatically assigned to each connection by the
|
||
message bus. This name will never change owner, and will be unique
|
||
(never reused during the lifetime of the message bus).
|
||
It will begin with a ':' character.
|
||
</para>
|
||
</glossdef>
|
||
</glossentry>
|
||
|
||
</glossary>
|
||
</article>
|