5579 lines
226 KiB
XML
5579 lines
226 KiB
XML
<?xml version="1.0" standalone="no" ?>
|
|
<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
|
|
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd"
|
|
[
|
|
]>
|
|
<article id="index">
|
|
<articleinfo>
|
|
<title>D-Bus Specification</title>
|
|
<releaseinfo>Version 0.19</releaseinfo>
|
|
<date>2012-02-21</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>simon.mcvittie@collabora.co.uk</email>
|
|
</address>
|
|
</affiliation>
|
|
</author>
|
|
<author>
|
|
<firstname>David</firstname>
|
|
<surname>Zeuthen</surname>
|
|
<affiliation>
|
|
<orgname>Red Hat, Inc.</orgname>
|
|
<address>
|
|
<email>davidz@redhat.com</email>
|
|
</address>
|
|
</affiliation>
|
|
</author>
|
|
</authorgroup>
|
|
<revhistory>
|
|
<revision>
|
|
<revnumber>current</revnumber>
|
|
<date><ulink url='http://cgit.freedesktop.org/dbus/dbus/log/doc/dbus-specification.xml'>commit log</ulink></date>
|
|
<authorinitials></authorinitials>
|
|
<revremark></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-latency, low-overhead, easy to use
|
|
interprocess communication (IPC). In more detail:
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>
|
|
D-Bus is <emphasis>low-latency</emphasis> because it is designed
|
|
to avoid round trips and allow asynchronous operation, much like
|
|
the X protocol.
|
|
</para>
|
|
</listitem>
|
|
<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.
|
|
</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>
|
|
|
|
<sect2 id="message-protocol-signatures">
|
|
<title>Type Signatures</title>
|
|
|
|
<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 <firstterm>type
|
|
codes</firstterm>. 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>
|
|
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>
|
|
All <firstterm>basic</firstterm> types work like
|
|
<literal>INT32</literal> in this example. To marshal and unmarshal
|
|
basic types, you simply read one value from the data
|
|
block corresponding to each type code in the signature.
|
|
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>
|
|
The phrase <firstterm>single complete type</firstterm> deserves some
|
|
definition. 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.
|
|
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.
|
|
</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>
|
|
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>
|
|
|
|
<para>
|
|
The following table summarizes the D-Bus types.
|
|
<informaltable>
|
|
<tgroup cols="3">
|
|
<thead>
|
|
<row>
|
|
<entry>Conventional Name</entry>
|
|
<entry>Code</entry>
|
|
<entry>Description</entry>
|
|
</row>
|
|
</thead>
|
|
<tbody>
|
|
<row>
|
|
<entry><literal>INVALID</literal></entry>
|
|
<entry>0 (ASCII NUL)</entry>
|
|
<entry>Not a valid type code, used to terminate signatures</entry>
|
|
</row><row>
|
|
<entry><literal>BYTE</literal></entry>
|
|
<entry>121 (ASCII 'y')</entry>
|
|
<entry>8-bit unsigned integer</entry>
|
|
</row><row>
|
|
<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><literal>INT16</literal></entry>
|
|
<entry>110 (ASCII 'n')</entry>
|
|
<entry>16-bit signed integer</entry>
|
|
</row><row>
|
|
<entry><literal>UINT16</literal></entry>
|
|
<entry>113 (ASCII 'q')</entry>
|
|
<entry>16-bit unsigned integer</entry>
|
|
</row><row>
|
|
<entry><literal>INT32</literal></entry>
|
|
<entry>105 (ASCII 'i')</entry>
|
|
<entry>32-bit signed integer</entry>
|
|
</row><row>
|
|
<entry><literal>UINT32</literal></entry>
|
|
<entry>117 (ASCII 'u')</entry>
|
|
<entry>32-bit unsigned integer</entry>
|
|
</row><row>
|
|
<entry><literal>INT64</literal></entry>
|
|
<entry>120 (ASCII 'x')</entry>
|
|
<entry>64-bit signed integer</entry>
|
|
</row><row>
|
|
<entry><literal>UINT64</literal></entry>
|
|
<entry>116 (ASCII 't')</entry>
|
|
<entry>64-bit unsigned integer</entry>
|
|
</row><row>
|
|
<entry><literal>DOUBLE</literal></entry>
|
|
<entry>100 (ASCII 'd')</entry>
|
|
<entry>IEEE 754 double</entry>
|
|
</row><row>
|
|
<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><literal>OBJECT_PATH</literal></entry>
|
|
<entry>111 (ASCII 'o')</entry>
|
|
<entry>Name of an object instance</entry>
|
|
</row><row>
|
|
<entry><literal>SIGNATURE</literal></entry>
|
|
<entry>103 (ASCII 'g')</entry>
|
|
<entry>A type signature</entry>
|
|
</row><row>
|
|
<entry><literal>ARRAY</literal></entry>
|
|
<entry>97 (ASCII 'a')</entry>
|
|
<entry>Array</entry>
|
|
</row><row>
|
|
<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><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><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><literal>UNIX_FD</literal></entry>
|
|
<entry>104 (ASCII 'h')</entry>
|
|
<entry>Unix file descriptor</entry>
|
|
</row>
|
|
<row>
|
|
<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>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>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>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>
|
|
|
|
<sect2 id="message-protocol-marshaling">
|
|
<title>Marshaling (Wire Format)</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. To properly align a value, <firstterm>alignment
|
|
padding</firstterm> may be necessary. 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>
|
|
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 below).
|
|
</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 below).
|
|
</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. The array length is from the
|
|
end of the alignment padding to the end of the last element,
|
|
i.e. it does not include the padding after the length,
|
|
or any padding after the last element.
|
|
Arrays have a maximum length defined to be 2 to the 26th power or
|
|
67108864. Implementations must not send or accept arrays exceeding this
|
|
length.
|
|
</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>
|
|
A variant type has a marshaled
|
|
<literal>SIGNATURE</literal> followed by a marshaled
|
|
value with the type given in the signature. 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.
|
|
</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>
|
|
|
|
<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>
|
|
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>
|
|
|
|
<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>
|
|
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>
|
|
</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 ends with a nul byte.
|
|
</para>
|
|
</listitem>
|
|
<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 and open and close parentheses are
|
|
allowed in the signature. The <literal>STRUCT</literal> type code
|
|
is not allowed in signatures, because parentheses
|
|
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>
|
|
<listitem>
|
|
<para>
|
|
Signatures must be nul-terminated.
|
|
</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
</sect3>
|
|
|
|
</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. 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.</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>This message does not expect method return replies or
|
|
error replies; the reply can be omitted as an
|
|
optimization. However, it is compliant with this specification
|
|
to return the reply despite this flag and the only harm
|
|
from doing so is extra network traffic.
|
|
</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>
|
|
</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 ignore fields they do not
|
|
understand. Implementations must not invent their own header fields;
|
|
only changes to this specification may introduce new header fields.
|
|
</para>
|
|
|
|
<para>
|
|
Again, if an implementation sees a header field code that it does not
|
|
expect, it must 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>
|
|
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.
|
|
</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.
|
|
</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.</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.)</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.
|
|
Only used in combination with the message bus, see
|
|
<xref linkend="message-bus"/>.</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.
|
|
The message bus fills in this field so it is reliable; the field is
|
|
only meaningful in combination with the message bus.</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).</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.</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 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]_" and must not begin with a digit.
|
|
</para>
|
|
</listitem>
|
|
|
|
<listitem><para>Interface names must contain at least one '.' (period)
|
|
character (and thus at least two elements).
|
|
</para></listitem>
|
|
|
|
<listitem><para>Interface names must not begin with a '.' (period) character.</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>
|
|
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]_-". 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.
|
|
</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>
|
|
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.MusicPlayer.Error.FileNotFound</literal>
|
|
and <literal>com.example.MusicPlayer.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. In the
|
|
absence of an <literal>INTERFACE</literal> field, if two interfaces on the same object have
|
|
a method with the same name, it is undefined which of the two methods
|
|
will be invoked. Implementations may also choose to return an error in
|
|
this ambiguous case. However, if a method name is unique
|
|
implementations must not require an interface field.
|
|
</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 as an optimization the application receiving the method
|
|
call may choose to omit the reply message (regardless of
|
|
whether the reply would have been <literal>METHOD_RETURN</literal> or <literal>ERROR</literal>).
|
|
However, it is also acceptable to ignore the <literal>NO_REPLY_EXPECTED</literal>
|
|
flag and reply anyway.
|
|
</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 before the message is delivered. 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>
|
|
In examples, "C:" and "S:" indicate lines sent by the client and
|
|
server respectively.
|
|
</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</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>
|
|
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>
|
|
<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>
|
|
If BEGIN is received by the server, 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.
|
|
</para>
|
|
</sect2>
|
|
<sect2 id="auth-command-cancel">
|
|
<title>CANCEL Command</title>
|
|
<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.
|
|
</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 acknowledges that the client has received an
|
|
OK command from the server, and 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>
|
|
</sect2>
|
|
<sect2 id="auth-command-rejected">
|
|
<title>REJECTED Command</title>
|
|
<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 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 a client sends BEGIN 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.
|
|
</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 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 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 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 magic cookie authentication</title>
|
|
<programlisting>
|
|
(MAGIC_COOKIE is a made up mechanism)
|
|
|
|
C: AUTH MAGIC_COOKIE 3138363935333137393635383634
|
|
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>
|
|
C: FOOBAR
|
|
S: ERROR
|
|
C: AUTH MAGIC_COOKIE 3736343435313230333039
|
|
S: OK 1234deadbeef
|
|
C: BEGIN
|
|
</programlisting>
|
|
</figure>
|
|
<figure>
|
|
<title>Example of server doesn't support initial auth mechanism</title>
|
|
<programlisting>
|
|
C: AUTH MAGIC_COOKIE 3736343435313230333039
|
|
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 MAGIC_COOKIE 3736343435313230333039
|
|
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 MAGIC_COOKIE 3736343435313230333039
|
|
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 magic cookie authentication with successful negotiation of Unix FD passing</title>
|
|
<programlisting>
|
|
(MAGIC_COOKIE is a made up mechanism)
|
|
|
|
C: AUTH MAGIC_COOKIE 3138363935333137393635383634
|
|
S: OK 1234deadbeef
|
|
C: NEGOTIATE_UNIX_FD
|
|
S: AGREE_UNIX_FD
|
|
C: BEGIN
|
|
</programlisting>
|
|
</figure>
|
|
<figure>
|
|
<title>Example of successful magic cookie authentication with unsuccessful negotiation of Unix FD passing</title>
|
|
<programlisting>
|
|
(MAGIC_COOKIE is a made up mechanism)
|
|
|
|
C: AUTH MAGIC_COOKIE 3138363935333137393635383634
|
|
S: OK 1234deadbeef
|
|
C: NEGOTIATE_UNIX_FD
|
|
S: ERROR
|
|
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 → send
|
|
BEGIN, terminate auth
|
|
conversation, authenticated
|
|
</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 → send BEGIN, terminate auth
|
|
conversation, <emphasis>authenticated</emphasis>
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para>
|
|
Receive REJECT [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 REJECT [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>
|
|
|
|
</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>
|
|
REJECT 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 REJECT → 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 REJECT → 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 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 new authentication mechanisms.
|
|
D-Bus also allows any standard SASL mechanism of course.
|
|
</para>
|
|
<sect3 id="auth-mechanisms-sha">
|
|
<title>DBUS_COOKIE_SHA1</title>
|
|
<para>
|
|
The DBUS_COOKIE_SHA1 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.
|
|
</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). If no recent keys remain, the
|
|
server may generate a new key.
|
|
</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>
|
|
</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>
|
|
|
|
</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.
|
|
</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. If set, the "tmpdir" and "abstract" key must not be set.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>tmpdir</entry>
|
|
<entry>(path)</entry>
|
|
<entry>temporary 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. If set, the "path" and "abstract" key must not be set.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>abstract</entry>
|
|
<entry>(string)</entry>
|
|
<entry>unique string (path) in the abstract namespace. If set, the "path" or "tempdir" key must not be set.</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</informaltable>
|
|
</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>
|
|
<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>
|
|
</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.
|
|
</para>
|
|
<para>
|
|
The systemd transport is not available on non-Linux operating systems.
|
|
</para>
|
|
<para>
|
|
The systemd transport defines no parameter keys.
|
|
</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>
|
|
Using tcp transport without any additional secure authentification mechanismus
|
|
over a network is unsecure.
|
|
</para>
|
|
<para>
|
|
Windows notes: Because of the tcp stack on Windows does not provide sending
|
|
credentials over a tcp connection, the EXTERNAL authentification
|
|
mechanismus does not work.
|
|
</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>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-secured TCP Sockets</title>
|
|
<para>
|
|
The nonce-tcp transport provides a secured 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>
|
|
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 unsecured 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 unsecured tcp transport.
|
|
</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>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</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>
|
|
<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>
|
|
<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>
|
|
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 DICT<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 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,
|
|
DICT<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 DICT<OBJPATH,DICT<STRING,DICT<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,
|
|
DICT<STRING,DICT<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',name='org.example.App',path_namespace='/org/example/App'");
|
|
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="/org/freedesktop/sample_object">
|
|
<interface name="org.freedesktop.SampleInterface">
|
|
<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, and signal 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,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>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>
|
|
</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
|
|
"org.freedesktop.TextEditor". 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>.
|
|
This name routes messages to the bus, allowing applications to make
|
|
administrative requests. 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 "org.freedesktop.TextEditor",
|
|
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>
|
|
|
|
<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>
|
|
This method call should be sent to
|
|
<literal>org.freedesktop.DBus</literal> and asks 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>
|
|
This method call should be sent to
|
|
<literal>org.freedesktop.DBus</literal> and asks 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>
|
|
This method call should be sent to
|
|
<literal>org.freedesktop.DBus</literal> and lists the connections
|
|
currently queued for a bus name (see
|
|
<xref linkend="term-queued-owner"/>).
|
|
</para>
|
|
</sect3>
|
|
</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.
|
|
</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 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 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. If the message bus'
|
|
security policy does not allow eavesdropping, the match rule can
|
|
still be added, but will not have any practical effect. 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.
|
|
</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>
|
|
The following table describes the keys that can be used to create
|
|
a match rule:
|
|
The following table summarizes the D-Bus types.
|
|
<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.backend'</literal>
|
|
matches name owner changes for bus names such as
|
|
<literal>com.example.backend.foo</literal>,
|
|
<literal>com.example.backend.foo.bar</literal>, and
|
|
<literal>com.example.backend</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>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.
|
|
If the message bus has a security policy which forbids
|
|
eavesdropping, this match may still be used without error,
|
|
but will not have any practical effect.
|
|
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.
|
|
</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</informaltable>
|
|
</para>
|
|
</sect3>
|
|
</sect2>
|
|
<sect2 id="message-bus-starting-services">
|
|
<title>Message Bus Starting Services</title>
|
|
<para>
|
|
The message bus can start applications on behalf of other applications.
|
|
In CORBA terms, this would be called <firstterm>activation</firstterm>.
|
|
An application that can be started in this way is called a
|
|
<firstterm>service</firstterm>.
|
|
</para>
|
|
<para>
|
|
With D-Bus, starting a service is normally done by name. That is,
|
|
applications ask the message bus to start some program that will own a
|
|
well-known name, such as <literal>org.freedesktop.TextEditor</literal>.
|
|
This implies a contract documented along with the name
|
|
<literal>org.freedesktop.TextEditor</literal> for which objects
|
|
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>
|
|
[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>
|
|
|
|
<figure>
|
|
<title>Example service description file</title>
|
|
<programlisting>
|
|
# Sample service description file
|
|
[D-BUS Service]
|
|
Names=org.freedesktop.ConfigurationDatabase;org.gnome.GConf;
|
|
Exec=/usr/libexec/gconfd-2
|
|
</programlisting>
|
|
</figure>
|
|
</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. [FIXME what happens if two .service files offer the same service;
|
|
what kind of error is reported, should we have a way for the client to
|
|
choose one?]
|
|
</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>
|
|
</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></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, which
|
|
should be searched with lower priority than anything in
|
|
XDG_DATA_HOME, XDG_DATA_DIRS or their respective defaults;
|
|
for example, the reference implementation also
|
|
looks in <literal>${datadir}/dbus-1/services</literal> as
|
|
set at compile time.
|
|
</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.
|
|
</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-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-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. For more information, see <xref linkend="message-bus-starting-services"/>.
|
|
|
|
</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<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<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-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>
|
|
|
|
</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
|
|
"org.freedesktop.Screensaver", have a singleton object
|
|
"/org/freedesktop/Application", and that object will implement the
|
|
interface "org.freedesktop.ScreensaverControl".
|
|
</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>
|