mirror of
https://gitlab.freedesktop.org/dbus/dbus.git
synced 2025-12-22 07:50:09 +01:00
* configure.in (LT_*): add notes on how the libtool versioning works to save thinking. Increment soname to indicate protocol breakage (though really the library interface hasn't changed I guess) * dbus/dbus-transport.c (_dbus_transport_get_is_authenticated): verify the GUID received from server matches what we were expecting, if we had an expectation * dbus/dbus-auth.c (send_ok): send GUID along with the OK command (_dbus_auth_get_guid_from_server): new function (send_begin): parse the OK args * doc/dbus-specification.xml: add GUID to the auth protocol
3431 lines
135 KiB
XML
3431 lines
135 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.11</releaseinfo>
|
|
<date>6 February 2005</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>
|
|
</authorgroup>
|
|
</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. 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>
|
|
|
|
</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 inteprets 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 same type system and format for
|
|
serializing data. Each type of value has a wire format.
|
|
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>
|
|
<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.</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</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)</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
|
|
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" is OK, "ii" is not.
|
|
</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>
|
|
</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>
|
|
|
|
</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>
|
|
|
|
<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 0.
|
|
FIXME this field is stupid and pointless to put in
|
|
every message.
|
|
</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.
|
|
</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.
|
|
</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.
|
|
</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>
|
|
</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>They 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>They must contain at least one '.' (period)
|
|
character (and thus at least two elements).
|
|
</para></listitem>
|
|
|
|
<listitem><para>They must not begin with a '.' (period) character.</para></listitem>
|
|
<listitem><para>They must not exceed the maximum name length.</para></listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
</sect3>
|
|
<sect3 id="message-protocol-names-bus">
|
|
<title>Bus names</title>
|
|
<para>
|
|
Bus names have the same restrictions as interface names, with a
|
|
special exception for unique connection names. A unique name's first
|
|
element must start with a colon (':') character. After the colon, any
|
|
characters in "[A-Z][a-z][0-9]_" may appear. Elements after
|
|
the first must follow the usual rules, except that they may start with
|
|
a digit. Bus names not starting with a colon have none of these
|
|
exceptions and follow the same rules as interface names.
|
|
</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>
|
|
</sect3>
|
|
<sect3 id="message-protocol-names-error">
|
|
<title>Error names</title>
|
|
<para>
|
|
Error names have the same restrictions as interface names.
|
|
</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.
|
|
</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 idiosyncracy 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>
|
|
</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>
|
|
</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 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 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-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,
|
|
and that further communication will be a stream of D-BUS messages
|
|
(optionally encrypted, as negotiated) rather than this protocol.
|
|
</para>
|
|
<para>
|
|
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 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 OK command has been sent.
|
|
</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-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>
|
|
</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>
|
|
Authentication proceeds as follows:
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>
|
|
The client sends the username it would like to authenticate
|
|
as.
|
|
</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
|
|
hex-encoded randomly-generated challenge string.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para>
|
|
The client locates the cookie, and generates its own hex-encoded
|
|
randomly-generated challenge string. The client then
|
|
concatentates the server's hex-encoded challenge, a ":"
|
|
character, its own hex-encoded challenge, another ":" character,
|
|
and the hex-encoded cookie. It computes the SHA-1 hash of this
|
|
composite string. It sends back to the server the client's
|
|
hex-encoded challenge string, a space character, and the SHA-1
|
|
hash.
|
|
</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. This globally unique ID must
|
|
be created by filling the first 4 bytes with a 32-bit UNIX time since the
|
|
epoch, and the remaining 12 bytes with random bytes. If present, the GUID
|
|
may be used to distinguish one server from another. A server should use a
|
|
different GUID 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 GUIDs to distinguish
|
|
the kinds of connection.
|
|
</para>
|
|
|
|
<para>
|
|
The intent of the GUID 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.
|
|
</para>
|
|
|
|
<para>
|
|
[FIXME clarify if attempting to connect to each is a requirement
|
|
or just a suggestion]
|
|
When connecting to a server, multiple server addresses can be
|
|
separated by a semi-colon. The library will then try to connect
|
|
to the first address and if that fails, it'll try to connect to
|
|
the next one specified, and so forth. For example
|
|
<programlisting>unix:path=/tmp/dbus-test;unix:path=/tmp/dbus-test2</programlisting>
|
|
</para>
|
|
<para>
|
|
[FIXME we need to specify in detail each transport and its possible arguments]
|
|
Current transports include: unix domain sockets (including
|
|
abstract namespace on linux), TCP/IP, and a debug/testing transport using
|
|
in-process pipes. Future possible transports include one that
|
|
tunnels over X11 protocol.
|
|
</para>
|
|
</sect1>
|
|
|
|
<sect1 id="naming-conventions">
|
|
<title>Naming Conventions</title>
|
|
|
|
<para>
|
|
D-BUS namespaces are all lowercase and correspond to reversed domain
|
|
names, as with Java. e.g. "org.freedesktop"
|
|
</para>
|
|
<para>
|
|
Interface, signal, method, and property names are "WindowsStyleCaps", note
|
|
that the first letter is capitalized, unlike Java.
|
|
</para>
|
|
<para>
|
|
Object paths are normally all lowercase with underscores used rather than
|
|
hyphens.
|
|
</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 one method:
|
|
<programlisting>
|
|
org.freedesktop.DBus.Peer.Ping ()
|
|
</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 should simply handle this method on behalf of
|
|
all objects, though it doesn't yet. (The point is, you're really pinging
|
|
the peer process, not a specific object.)
|
|
</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);
|
|
</programlisting>
|
|
</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>
|
|
</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>
|
|
</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>
|
|
Messages may have a <literal>DESTINATION</literal> field (see <xref
|
|
linkend="message-protocol-header-fields"/>). If the
|
|
<literal>DESTINATION</literal> field is present, it specifies a message
|
|
recipient by name. Method calls and replies normally specify this field.
|
|
</para>
|
|
|
|
<para>
|
|
Signals normally do not specify a destination; they are sent to all
|
|
applications with <firstterm>message matching rules</firstterm> that
|
|
match the message.
|
|
</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>
|
|
</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.
|
|
</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. 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_PROHIBIT_REPLACEMENT</entry>
|
|
<entry>0x1</entry>
|
|
<entry>
|
|
If the application succeeds in becoming the owner of the specified name,
|
|
then ownership of the name can't be transferred until the application
|
|
disconnects. If this flag is not set, then any application trying to become
|
|
the owner of the name will succeed and the previous owner will be
|
|
sent a <literal>org.freedesktop.DBus.NameLost</literal> signal.
|
|
</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.
|
|
</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 did not
|
|
specify DBUS_NAME_FLAG_PROHIBIT_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_REPLACE_EXISTING was not specified, and the current owner specified DBUS_NAME_FLAG_PROHIBIT_REPLACEMENT.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>DBUS_REQUEST_NAME_REPLY_EXISTS</entry>
|
|
<entry>3</entry>
|
|
<entry>The name already has an owner, and DBUS_NAME_FLAG_REPLACE_EXISTING was not specified.</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>
|
|
</sect2>
|
|
|
|
<sect2 id="message-bus-routing">
|
|
<title>Message Bus Message Routing</title>
|
|
<para>
|
|
FIXME
|
|
</para>
|
|
</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>
|
|
[FIXME the file format should be much better specified than "similar to
|
|
.desktop entries" esp. since desktop entries are already
|
|
badly-specified. ;-)] 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://www.freedesktop.org/standards/desktop-entry-spec/desktop-entry-spec.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.
|
|
|
|
<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>
|
|
[FIXME specify location of .service files, probably using
|
|
DESKTOP_DIRS etc. from basedir specification, though login session
|
|
bus is not really desktop-specific]
|
|
</para>
|
|
</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>
|
|
[FIXME specify location of system bus .service files]
|
|
</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-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-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 connection_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 of the connection to query</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 uid of the process connected to the server. If unable to
|
|
determine it, a <literal>org.freedesktop.DBus.Error.Failed</literal>
|
|
error is returned.
|
|
</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>
|
|
</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 or bus
|
|
names. The convention used is the same one Java uses for defining
|
|
classes: a reversed domain name.
|
|
</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>
|
|
|