LCOV - code coverage report
Current view: top level - gio - gdbusserver.c (source / functions) Coverage Total Hit
Test: unnamed Lines: 87.0 % 353 307
Test Date: 2026-02-03 14:41:24 Functions: 100.0 % 24 24
Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : /* GDBus - GLib D-Bus Library
       2                 :             :  *
       3                 :             :  * Copyright (C) 2008-2010 Red Hat, Inc.
       4                 :             :  *
       5                 :             :  * SPDX-License-Identifier: LGPL-2.1-or-later
       6                 :             :  *
       7                 :             :  * This library is free software; you can redistribute it and/or
       8                 :             :  * modify it under the terms of the GNU Lesser General Public
       9                 :             :  * License as published by the Free Software Foundation; either
      10                 :             :  * version 2.1 of the License, or (at your option) any later version.
      11                 :             :  *
      12                 :             :  * This library is distributed in the hope that it will be useful,
      13                 :             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      14                 :             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      15                 :             :  * Lesser General Public License for more details.
      16                 :             :  *
      17                 :             :  * You should have received a copy of the GNU Lesser General
      18                 :             :  * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
      19                 :             :  *
      20                 :             :  * Author: David Zeuthen <davidz@redhat.com>
      21                 :             :  */
      22                 :             : 
      23                 :             : #include "config.h"
      24                 :             : 
      25                 :             : #include <stdlib.h>
      26                 :             : #include <string.h>
      27                 :             : #include <errno.h>
      28                 :             : 
      29                 :             : #include "giotypes.h"
      30                 :             : #include "gioerror.h"
      31                 :             : #include "gdbusaddress.h"
      32                 :             : #include "gdbusutils.h"
      33                 :             : #include "gdbusconnection.h"
      34                 :             : #include "gdbusserver.h"
      35                 :             : #include "gioenumtypes.h"
      36                 :             : #include "gdbusprivate.h"
      37                 :             : #include "gdbusauthobserver.h"
      38                 :             : #include "ginitable.h"
      39                 :             : #include "gsocketservice.h"
      40                 :             : #include "gthreadedsocketservice.h"
      41                 :             : #include "gresolver.h"
      42                 :             : #include "glib/gstdio.h"
      43                 :             : #include "ginetaddress.h"
      44                 :             : #include "ginetsocketaddress.h"
      45                 :             : #include "ginputstream.h"
      46                 :             : #include "giostream.h"
      47                 :             : #include "gmarshal-internal.h"
      48                 :             : #include "gnetworking.h"
      49                 :             : 
      50                 :             : #ifdef G_OS_UNIX
      51                 :             : #include <unistd.h>
      52                 :             : #endif
      53                 :             : #ifdef G_OS_WIN32
      54                 :             : #include <io.h>
      55                 :             : #include "giowin32-afunix.h"
      56                 :             : #endif
      57                 :             : 
      58                 :             : #include "gunixsocketaddress.h"
      59                 :             : 
      60                 :             : #include "glibintl.h"
      61                 :             : 
      62                 :             : #define G_DBUS_SERVER_FLAGS_ALL \
      63                 :             :   (G_DBUS_SERVER_FLAGS_RUN_IN_THREAD | \
      64                 :             :    G_DBUS_SERVER_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS | \
      65                 :             :    G_DBUS_SERVER_FLAGS_AUTHENTICATION_REQUIRE_SAME_USER)
      66                 :             : 
      67                 :             : #ifndef UNIX_PATH_MAX
      68                 :             : #define UNIX_PATH_MAX G_SIZEOF_MEMBER (struct sockaddr_un, sun_path)
      69                 :             : #endif
      70                 :             : 
      71                 :             : /**
      72                 :             :  * GDBusServer:
      73                 :             :  *
      74                 :             :  * `GDBusServer` is a helper for listening to and accepting D-Bus
      75                 :             :  * connections. This can be used to create a new D-Bus server, allowing two
      76                 :             :  * peers to use the D-Bus protocol for their own specialized communication.
      77                 :             :  * A server instance provided in this way will not perform message routing or
      78                 :             :  * implement the
      79                 :             :  * [`org.freedesktop.DBus` interface](https://dbus.freedesktop.org/doc/dbus-specification.html#message-bus-messages).
      80                 :             :  *
      81                 :             :  * To just export an object on a well-known name on a message bus, such as the
      82                 :             :  * session or system bus, you should instead use [func@Gio.bus_own_name].
      83                 :             :  *
      84                 :             :  * An example of peer-to-peer communication with GDBus can be found
      85                 :             :  * in [gdbus-example-peer.c](https://gitlab.gnome.org/GNOME/glib/-/blob/HEAD/gio/tests/gdbus-example-peer.c).
      86                 :             :  *
      87                 :             :  * Note that a minimal `GDBusServer` will accept connections from any
      88                 :             :  * peer. In many use-cases it will be necessary to add a
      89                 :             :  * [class@Gio.DBusAuthObserver] that only accepts connections that have
      90                 :             :  * successfully authenticated as the same user that is running the
      91                 :             :  * `GDBusServer`. Since GLib 2.68 this can be achieved more simply by passing
      92                 :             :  * the `G_DBUS_SERVER_FLAGS_AUTHENTICATION_REQUIRE_SAME_USER` flag to the
      93                 :             :  * server.
      94                 :             :  *
      95                 :             :  * Since: 2.26
      96                 :             :  */
      97                 :             : struct _GDBusServer
      98                 :             : {
      99                 :             :   /*< private >*/
     100                 :             :   GObject parent_instance;
     101                 :             : 
     102                 :             :   GDBusServerFlags flags;
     103                 :             :   gchar *address;
     104                 :             :   gchar *guid;
     105                 :             : 
     106                 :             :   guchar *nonce;
     107                 :             :   gchar *nonce_file;
     108                 :             : 
     109                 :             :   gchar *client_address;
     110                 :             : 
     111                 :             :   gchar *unix_socket_path;
     112                 :             :   GSocketListener *listener;
     113                 :             :   gboolean is_using_listener;
     114                 :             :   gulong run_signal_handler_id;
     115                 :             : 
     116                 :             :   /* The result of g_main_context_ref_thread_default() when the object
     117                 :             :    * was created (the GObject _init() function) - this is used for delivery
     118                 :             :    * of the :new-connection GObject signal.
     119                 :             :    */
     120                 :             :   GMainContext *main_context_at_construction;
     121                 :             : 
     122                 :             :   gboolean active;
     123                 :             : 
     124                 :             :   GDBusAuthObserver *authentication_observer;
     125                 :             : };
     126                 :             : 
     127                 :             : typedef struct _GDBusServerClass GDBusServerClass;
     128                 :             : 
     129                 :             : /**
     130                 :             :  * GDBusServerClass:
     131                 :             :  * @new_connection: Signal class handler for the #GDBusServer::new-connection signal.
     132                 :             :  *
     133                 :             :  * Class structure for #GDBusServer.
     134                 :             :  *
     135                 :             :  * Since: 2.26
     136                 :             :  */
     137                 :             : struct _GDBusServerClass
     138                 :             : {
     139                 :             :   /*< private >*/
     140                 :             :   GObjectClass parent_class;
     141                 :             : 
     142                 :             :   /*< public >*/
     143                 :             :   /* Signals */
     144                 :             :   gboolean (*new_connection) (GDBusServer      *server,
     145                 :             :                               GDBusConnection  *connection);
     146                 :             : };
     147                 :             : 
     148                 :             : enum
     149                 :             : {
     150                 :             :   PROP_0,
     151                 :             :   PROP_ADDRESS,
     152                 :             :   PROP_CLIENT_ADDRESS,
     153                 :             :   PROP_FLAGS,
     154                 :             :   PROP_GUID,
     155                 :             :   PROP_ACTIVE,
     156                 :             :   PROP_AUTHENTICATION_OBSERVER,
     157                 :             : };
     158                 :             : 
     159                 :             : enum
     160                 :             : {
     161                 :             :   NEW_CONNECTION_SIGNAL,
     162                 :             :   LAST_SIGNAL,
     163                 :             : };
     164                 :             : 
     165                 :             : static guint _signals[LAST_SIGNAL] = {0};
     166                 :             : 
     167                 :             : static void initable_iface_init       (GInitableIface *initable_iface);
     168                 :             : 
     169                 :         709 : G_DEFINE_TYPE_WITH_CODE (GDBusServer, g_dbus_server, G_TYPE_OBJECT,
     170                 :             :                          G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, initable_iface_init))
     171                 :             : 
     172                 :             : static void
     173                 :          26 : g_dbus_server_dispose (GObject *object)
     174                 :             : {
     175                 :          26 :   GDBusServer *server = G_DBUS_SERVER (object);
     176                 :             : 
     177                 :          26 :   if (server->active)
     178                 :           0 :     g_dbus_server_stop (server);
     179                 :             : 
     180                 :          26 :   G_OBJECT_CLASS (g_dbus_server_parent_class)->dispose (object);
     181                 :          26 : }
     182                 :             : 
     183                 :             : static void
     184                 :          26 : g_dbus_server_finalize (GObject *object)
     185                 :             : {
     186                 :          26 :   GDBusServer *server = G_DBUS_SERVER (object);
     187                 :             : 
     188                 :          26 :   g_assert (!server->active);
     189                 :             : 
     190                 :          26 :   if (server->authentication_observer != NULL)
     191                 :          19 :     g_object_unref (server->authentication_observer);
     192                 :             : 
     193                 :          26 :   if (server->run_signal_handler_id > 0)
     194                 :           0 :     g_signal_handler_disconnect (server->listener, server->run_signal_handler_id);
     195                 :             : 
     196                 :          26 :   if (server->listener != NULL)
     197                 :          26 :     g_object_unref (server->listener);
     198                 :             : 
     199                 :          26 :   g_free (server->address);
     200                 :          26 :   g_free (server->guid);
     201                 :          26 :   g_free (server->client_address);
     202                 :          26 :   if (server->nonce != NULL)
     203                 :             :     {
     204                 :           1 :       memset (server->nonce, '\0', 16);
     205                 :           1 :       g_free (server->nonce);
     206                 :             :     }
     207                 :             : 
     208                 :          26 :   g_free (server->unix_socket_path);
     209                 :          26 :   g_free (server->nonce_file);
     210                 :             : 
     211                 :          26 :   g_main_context_unref (server->main_context_at_construction);
     212                 :             : 
     213                 :          26 :   G_OBJECT_CLASS (g_dbus_server_parent_class)->finalize (object);
     214                 :          26 : }
     215                 :             : 
     216                 :             : static void
     217                 :          20 : g_dbus_server_get_property (GObject    *object,
     218                 :             :                             guint       prop_id,
     219                 :             :                             GValue     *value,
     220                 :             :                             GParamSpec *pspec)
     221                 :             : {
     222                 :          20 :   GDBusServer *server = G_DBUS_SERVER (object);
     223                 :             : 
     224                 :          20 :   switch (prop_id)
     225                 :             :     {
     226                 :           4 :     case PROP_FLAGS:
     227                 :           4 :       g_value_set_flags (value, server->flags);
     228                 :           4 :       break;
     229                 :             : 
     230                 :           4 :     case PROP_GUID:
     231                 :           4 :       g_value_set_string (value, server->guid);
     232                 :           4 :       break;
     233                 :             : 
     234                 :           4 :     case PROP_ADDRESS:
     235                 :           4 :       g_value_set_string (value, server->address);
     236                 :           4 :       break;
     237                 :             : 
     238                 :           0 :     case PROP_CLIENT_ADDRESS:
     239                 :           0 :       g_value_set_string (value, server->client_address);
     240                 :           0 :       break;
     241                 :             : 
     242                 :           4 :     case PROP_ACTIVE:
     243                 :           4 :       g_value_set_boolean (value, server->active);
     244                 :           4 :       break;
     245                 :             : 
     246                 :           4 :     case PROP_AUTHENTICATION_OBSERVER:
     247                 :           4 :       g_value_set_object (value, server->authentication_observer);
     248                 :           4 :       break;
     249                 :             : 
     250                 :           0 :     default:
     251                 :           0 :       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
     252                 :           0 :       break;
     253                 :             :     }
     254                 :          20 : }
     255                 :             : 
     256                 :             : static void
     257                 :         104 : g_dbus_server_set_property (GObject      *object,
     258                 :             :                             guint         prop_id,
     259                 :             :                             const GValue *value,
     260                 :             :                             GParamSpec   *pspec)
     261                 :             : {
     262                 :         104 :   GDBusServer *server = G_DBUS_SERVER (object);
     263                 :             : 
     264                 :         104 :   switch (prop_id)
     265                 :             :     {
     266                 :          26 :     case PROP_FLAGS:
     267                 :          26 :       server->flags = g_value_get_flags (value);
     268                 :          26 :       break;
     269                 :             : 
     270                 :          26 :     case PROP_GUID:
     271                 :          26 :       server->guid = g_value_dup_string (value);
     272                 :          26 :       break;
     273                 :             : 
     274                 :          26 :     case PROP_ADDRESS:
     275                 :          26 :       server->address = g_value_dup_string (value);
     276                 :          26 :       break;
     277                 :             : 
     278                 :          26 :     case PROP_AUTHENTICATION_OBSERVER:
     279                 :          26 :       server->authentication_observer = g_value_dup_object (value);
     280                 :          26 :       break;
     281                 :             : 
     282                 :           0 :     default:
     283                 :           0 :       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
     284                 :           0 :       break;
     285                 :             :     }
     286                 :         104 : }
     287                 :             : 
     288                 :             : static void
     289                 :           6 : g_dbus_server_class_init (GDBusServerClass *klass)
     290                 :             : {
     291                 :           6 :   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
     292                 :             : 
     293                 :           6 :   gobject_class->dispose      = g_dbus_server_dispose;
     294                 :           6 :   gobject_class->finalize     = g_dbus_server_finalize;
     295                 :           6 :   gobject_class->set_property = g_dbus_server_set_property;
     296                 :           6 :   gobject_class->get_property = g_dbus_server_get_property;
     297                 :             : 
     298                 :             :   /**
     299                 :             :    * GDBusServer:flags:
     300                 :             :    *
     301                 :             :    * Flags from the #GDBusServerFlags enumeration.
     302                 :             :    *
     303                 :             :    * Since: 2.26
     304                 :             :    */
     305                 :           6 :   g_object_class_install_property (gobject_class,
     306                 :             :                                    PROP_FLAGS,
     307                 :             :                                    g_param_spec_flags ("flags", NULL, NULL,
     308                 :             :                                                        G_TYPE_DBUS_SERVER_FLAGS,
     309                 :             :                                                        G_DBUS_SERVER_FLAGS_NONE,
     310                 :             :                                                        G_PARAM_READABLE |
     311                 :             :                                                        G_PARAM_WRITABLE |
     312                 :             :                                                        G_PARAM_CONSTRUCT_ONLY |
     313                 :             :                                                        G_PARAM_STATIC_NAME |
     314                 :             :                                                        G_PARAM_STATIC_BLURB |
     315                 :             :                                                        G_PARAM_STATIC_NICK));
     316                 :             : 
     317                 :             :   /**
     318                 :             :    * GDBusServer:guid:
     319                 :             :    *
     320                 :             :    * The GUID of the server.
     321                 :             :    *
     322                 :             :    * See #GDBusConnection:guid for more details.
     323                 :             :    *
     324                 :             :    * Since: 2.26
     325                 :             :    */
     326                 :           6 :   g_object_class_install_property (gobject_class,
     327                 :             :                                    PROP_GUID,
     328                 :             :                                    g_param_spec_string ("guid", NULL, NULL,
     329                 :             :                                                         NULL,
     330                 :             :                                                         G_PARAM_READABLE |
     331                 :             :                                                         G_PARAM_WRITABLE |
     332                 :             :                                                         G_PARAM_CONSTRUCT_ONLY |
     333                 :             :                                                         G_PARAM_STATIC_NAME |
     334                 :             :                                                         G_PARAM_STATIC_BLURB |
     335                 :             :                                                         G_PARAM_STATIC_NICK));
     336                 :             : 
     337                 :             :   /**
     338                 :             :    * GDBusServer:address:
     339                 :             :    *
     340                 :             :    * The D-Bus address to listen on.
     341                 :             :    *
     342                 :             :    * Since: 2.26
     343                 :             :    */
     344                 :           6 :   g_object_class_install_property (gobject_class,
     345                 :             :                                    PROP_ADDRESS,
     346                 :             :                                    g_param_spec_string ("address", NULL, NULL,
     347                 :             :                                                         NULL,
     348                 :             :                                                         G_PARAM_READABLE |
     349                 :             :                                                         G_PARAM_WRITABLE |
     350                 :             :                                                         G_PARAM_CONSTRUCT_ONLY |
     351                 :             :                                                         G_PARAM_STATIC_NAME |
     352                 :             :                                                         G_PARAM_STATIC_BLURB |
     353                 :             :                                                         G_PARAM_STATIC_NICK));
     354                 :             : 
     355                 :             :   /**
     356                 :             :    * GDBusServer:client-address:
     357                 :             :    *
     358                 :             :    * The D-Bus address that clients can use.
     359                 :             :    *
     360                 :             :    * Since: 2.26
     361                 :             :    */
     362                 :           6 :   g_object_class_install_property (gobject_class,
     363                 :             :                                    PROP_CLIENT_ADDRESS,
     364                 :             :                                    g_param_spec_string ("client-address", NULL, NULL,
     365                 :             :                                                         NULL,
     366                 :             :                                                         G_PARAM_READABLE |
     367                 :             :                                                         G_PARAM_STATIC_NAME |
     368                 :             :                                                         G_PARAM_STATIC_BLURB |
     369                 :             :                                                         G_PARAM_STATIC_NICK));
     370                 :             : 
     371                 :             :   /**
     372                 :             :    * GDBusServer:active:
     373                 :             :    *
     374                 :             :    * Whether the server is currently active.
     375                 :             :    *
     376                 :             :    * Since: 2.26
     377                 :             :    */
     378                 :           6 :   g_object_class_install_property (gobject_class,
     379                 :             :                                    PROP_ACTIVE,
     380                 :             :                                    g_param_spec_boolean ("active", NULL, NULL,
     381                 :             :                                                          FALSE,
     382                 :             :                                                          G_PARAM_READABLE |
     383                 :             :                                                          G_PARAM_STATIC_NAME |
     384                 :             :                                                          G_PARAM_STATIC_BLURB |
     385                 :             :                                                          G_PARAM_STATIC_NICK));
     386                 :             : 
     387                 :             :   /**
     388                 :             :    * GDBusServer:authentication-observer:
     389                 :             :    *
     390                 :             :    * A #GDBusAuthObserver object to assist in the authentication process or %NULL.
     391                 :             :    *
     392                 :             :    * Since: 2.26
     393                 :             :    */
     394                 :           6 :   g_object_class_install_property (gobject_class,
     395                 :             :                                    PROP_AUTHENTICATION_OBSERVER,
     396                 :             :                                    g_param_spec_object ("authentication-observer", NULL, NULL,
     397                 :             :                                                         G_TYPE_DBUS_AUTH_OBSERVER,
     398                 :             :                                                         G_PARAM_READABLE |
     399                 :             :                                                         G_PARAM_WRITABLE |
     400                 :             :                                                         G_PARAM_CONSTRUCT_ONLY |
     401                 :             :                                                         G_PARAM_STATIC_NAME |
     402                 :             :                                                         G_PARAM_STATIC_BLURB |
     403                 :             :                                                         G_PARAM_STATIC_NICK));
     404                 :             : 
     405                 :             :   /**
     406                 :             :    * GDBusServer::new-connection:
     407                 :             :    * @server: The #GDBusServer emitting the signal.
     408                 :             :    * @connection: A #GDBusConnection for the new connection.
     409                 :             :    *
     410                 :             :    * Emitted when a new authenticated connection has been made. Use
     411                 :             :    * g_dbus_connection_get_peer_credentials() to figure out what
     412                 :             :    * identity (if any), was authenticated.
     413                 :             :    *
     414                 :             :    * If you want to accept the connection, take a reference to the
     415                 :             :    * @connection object and return %TRUE. When you are done with the
     416                 :             :    * connection call g_dbus_connection_close() and give up your
     417                 :             :    * reference. Note that the other peer may disconnect at any time -
     418                 :             :    * a typical thing to do when accepting a connection is to listen to
     419                 :             :    * the #GDBusConnection::closed signal.
     420                 :             :    *
     421                 :             :    * If #GDBusServer:flags contains %G_DBUS_SERVER_FLAGS_RUN_IN_THREAD
     422                 :             :    * then the signal is emitted in a new thread dedicated to the
     423                 :             :    * connection. Otherwise the signal is emitted in the thread-default
     424                 :             :    * main context (see [method@GLib.MainContext.push_thread_default])
     425                 :             :    * of the thread that @server was constructed in.
     426                 :             :    *
     427                 :             :    * You are guaranteed that signal handlers for this signal runs
     428                 :             :    * before incoming messages on @connection are processed. This means
     429                 :             :    * that it's suitable to call g_dbus_connection_register_object() or
     430                 :             :    * similar from the signal handler.
     431                 :             :    *
     432                 :             :    * Returns: %TRUE to claim @connection, %FALSE to let other handlers
     433                 :             :    * run.
     434                 :             :    *
     435                 :             :    * Since: 2.26
     436                 :             :    */
     437                 :           6 :   _signals[NEW_CONNECTION_SIGNAL] = g_signal_new (I_("new-connection"),
     438                 :             :                                                   G_TYPE_DBUS_SERVER,
     439                 :             :                                                   G_SIGNAL_RUN_LAST,
     440                 :             :                                                   G_STRUCT_OFFSET (GDBusServerClass, new_connection),
     441                 :             :                                                   g_signal_accumulator_true_handled,
     442                 :             :                                                   NULL, /* accu_data */
     443                 :             :                                                   _g_cclosure_marshal_BOOLEAN__OBJECT,
     444                 :             :                                                   G_TYPE_BOOLEAN,
     445                 :             :                                                   1,
     446                 :             :                                                   G_TYPE_DBUS_CONNECTION);
     447                 :           6 :   g_signal_set_va_marshaller (_signals[NEW_CONNECTION_SIGNAL],
     448                 :             :                               G_TYPE_FROM_CLASS (klass),
     449                 :             :                               _g_cclosure_marshal_BOOLEAN__OBJECTv);
     450                 :           6 : }
     451                 :             : 
     452                 :             : static void
     453                 :          26 : g_dbus_server_init (GDBusServer *server)
     454                 :             : {
     455                 :          26 :   server->main_context_at_construction = g_main_context_ref_thread_default ();
     456                 :          26 : }
     457                 :             : 
     458                 :             : static gboolean
     459                 :             : on_run (GSocketService    *service,
     460                 :             :         GSocketConnection *socket_connection,
     461                 :             :         GObject           *source_object,
     462                 :             :         gpointer           user_data);
     463                 :             : 
     464                 :             : /**
     465                 :             :  * g_dbus_server_new_sync:
     466                 :             :  * @address: A D-Bus address.
     467                 :             :  * @flags: Flags from the #GDBusServerFlags enumeration.
     468                 :             :  * @guid: A D-Bus GUID.
     469                 :             :  * @observer: (nullable): A #GDBusAuthObserver or %NULL.
     470                 :             :  * @cancellable: (nullable): A #GCancellable or %NULL.
     471                 :             :  * @error: Return location for server or %NULL.
     472                 :             :  *
     473                 :             :  * Creates a new D-Bus server that listens on the first address in
     474                 :             :  * @address that works.
     475                 :             :  *
     476                 :             :  * Once constructed, you can use g_dbus_server_get_client_address() to
     477                 :             :  * get a D-Bus address string that clients can use to connect.
     478                 :             :  *
     479                 :             :  * To have control over the available authentication mechanisms and
     480                 :             :  * the users that are authorized to connect, it is strongly recommended
     481                 :             :  * to provide a non-%NULL #GDBusAuthObserver.
     482                 :             :  *
     483                 :             :  * Connect to the #GDBusServer::new-connection signal to handle
     484                 :             :  * incoming connections.
     485                 :             :  *
     486                 :             :  * The returned #GDBusServer isn't active - you have to start it with
     487                 :             :  * g_dbus_server_start().
     488                 :             :  *
     489                 :             :  * #GDBusServer is used in this [example](https://gitlab.gnome.org/GNOME/glib/-/blob/HEAD/gio/tests/gdbus-example-peer.c).
     490                 :             :  *
     491                 :             :  * This is a synchronous failable constructor. There is currently no
     492                 :             :  * asynchronous version.
     493                 :             :  *
     494                 :             :  * Returns: A #GDBusServer or %NULL if @error is set. Free with
     495                 :             :  * g_object_unref().
     496                 :             :  *
     497                 :             :  * Since: 2.26
     498                 :             :  */
     499                 :             : GDBusServer *
     500                 :          26 : g_dbus_server_new_sync (const gchar        *address,
     501                 :             :                         GDBusServerFlags    flags,
     502                 :             :                         const gchar        *guid,
     503                 :             :                         GDBusAuthObserver  *observer,
     504                 :             :                         GCancellable       *cancellable,
     505                 :             :                         GError            **error)
     506                 :             : {
     507                 :             :   GDBusServer *server;
     508                 :             : 
     509                 :          26 :   g_return_val_if_fail (address != NULL, NULL);
     510                 :          26 :   g_return_val_if_fail (g_dbus_is_guid (guid), NULL);
     511                 :          26 :   g_return_val_if_fail ((flags & ~G_DBUS_SERVER_FLAGS_ALL) == 0, NULL);
     512                 :          26 :   g_return_val_if_fail (error == NULL || *error == NULL, NULL);
     513                 :             : 
     514                 :          26 :   server = g_initable_new (G_TYPE_DBUS_SERVER,
     515                 :             :                            cancellable,
     516                 :             :                            error,
     517                 :             :                            "address", address,
     518                 :             :                            "flags", flags,
     519                 :             :                            "guid", guid,
     520                 :             :                            "authentication-observer", observer,
     521                 :             :                            NULL);
     522                 :             : 
     523                 :          26 :   return server;
     524                 :             : }
     525                 :             : 
     526                 :             : /**
     527                 :             :  * g_dbus_server_get_client_address:
     528                 :             :  * @server: A #GDBusServer.
     529                 :             :  *
     530                 :             :  * Gets a
     531                 :             :  * [D-Bus address](https://dbus.freedesktop.org/doc/dbus-specification.html#addresses)
     532                 :             :  * string that can be used by clients to connect to @server.
     533                 :             :  *
     534                 :             :  * This is valid and non-empty if initializing the #GDBusServer succeeded.
     535                 :             :  *
     536                 :             :  * Returns: (not nullable): A D-Bus address string. Do not free, the string is owned
     537                 :             :  * by @server.
     538                 :             :  *
     539                 :             :  * Since: 2.26
     540                 :             :  */
     541                 :             : const gchar *
     542                 :          33 : g_dbus_server_get_client_address (GDBusServer *server)
     543                 :             : {
     544                 :          33 :   g_return_val_if_fail (G_IS_DBUS_SERVER (server), NULL);
     545                 :          33 :   return server->client_address;
     546                 :             : }
     547                 :             : 
     548                 :             : /**
     549                 :             :  * g_dbus_server_get_guid:
     550                 :             :  * @server: A #GDBusServer.
     551                 :             :  *
     552                 :             :  * Gets the GUID for @server, as provided to g_dbus_server_new_sync().
     553                 :             :  *
     554                 :             :  * Returns: (not nullable): A D-Bus GUID. Do not free this string, it is owned by @server.
     555                 :             :  *
     556                 :             :  * Since: 2.26
     557                 :             :  */
     558                 :             : const gchar *
     559                 :           4 : g_dbus_server_get_guid (GDBusServer *server)
     560                 :             : {
     561                 :           4 :   g_return_val_if_fail (G_IS_DBUS_SERVER (server), NULL);
     562                 :           4 :   return server->guid;
     563                 :             : }
     564                 :             : 
     565                 :             : /**
     566                 :             :  * g_dbus_server_get_flags:
     567                 :             :  * @server: A #GDBusServer.
     568                 :             :  *
     569                 :             :  * Gets the flags for @server.
     570                 :             :  *
     571                 :             :  * Returns: A set of flags from the #GDBusServerFlags enumeration.
     572                 :             :  *
     573                 :             :  * Since: 2.26
     574                 :             :  */
     575                 :             : GDBusServerFlags
     576                 :           4 : g_dbus_server_get_flags (GDBusServer *server)
     577                 :             : {
     578                 :           4 :   g_return_val_if_fail (G_IS_DBUS_SERVER (server), G_DBUS_SERVER_FLAGS_NONE);
     579                 :           4 :   return server->flags;
     580                 :             : }
     581                 :             : 
     582                 :             : /**
     583                 :             :  * g_dbus_server_is_active:
     584                 :             :  * @server: A #GDBusServer.
     585                 :             :  *
     586                 :             :  * Gets whether @server is active.
     587                 :             :  *
     588                 :             :  * Returns: %TRUE if server is active, %FALSE otherwise.
     589                 :             :  *
     590                 :             :  * Since: 2.26
     591                 :             :  */
     592                 :             : gboolean
     593                 :           1 : g_dbus_server_is_active (GDBusServer *server)
     594                 :             : {
     595                 :           1 :   g_return_val_if_fail (G_IS_DBUS_SERVER (server), G_DBUS_SERVER_FLAGS_NONE);
     596                 :           1 :   return server->active;
     597                 :             : }
     598                 :             : 
     599                 :             : /**
     600                 :             :  * g_dbus_server_start:
     601                 :             :  * @server: A #GDBusServer.
     602                 :             :  *
     603                 :             :  * Starts @server.
     604                 :             :  *
     605                 :             :  * Since: 2.26
     606                 :             :  */
     607                 :             : void
     608                 :          25 : g_dbus_server_start (GDBusServer *server)
     609                 :             : {
     610                 :          25 :   g_return_if_fail (G_IS_DBUS_SERVER (server));
     611                 :          25 :   if (server->active)
     612                 :           0 :     return;
     613                 :             :   /* Right now we don't have any transport not using the listener... */
     614                 :          25 :   g_assert (server->is_using_listener);
     615                 :          25 :   server->run_signal_handler_id = g_signal_connect_data (G_SOCKET_SERVICE (server->listener),
     616                 :             :                                                          "run",
     617                 :             :                                                          G_CALLBACK (on_run),
     618                 :             :                                                          g_object_ref (server),
     619                 :             :                                                          (GClosureNotify) g_object_unref,
     620                 :             :                                                          G_CONNECT_DEFAULT);
     621                 :          25 :   g_socket_service_start (G_SOCKET_SERVICE (server->listener));
     622                 :          25 :   server->active = TRUE;
     623                 :          25 :   g_object_notify (G_OBJECT (server), "active");
     624                 :             : }
     625                 :             : 
     626                 :             : /**
     627                 :             :  * g_dbus_server_stop:
     628                 :             :  * @server: A #GDBusServer.
     629                 :             :  *
     630                 :             :  * Stops @server.
     631                 :             :  *
     632                 :             :  * Since: 2.26
     633                 :             :  */
     634                 :             : void
     635                 :          25 : g_dbus_server_stop (GDBusServer *server)
     636                 :             : {
     637                 :          25 :   g_return_if_fail (G_IS_DBUS_SERVER (server));
     638                 :          25 :   if (!server->active)
     639                 :           0 :     return;
     640                 :             :   /* Right now we don't have any transport not using the listener... */
     641                 :          25 :   g_assert (server->is_using_listener);
     642                 :          25 :   g_assert (server->run_signal_handler_id > 0);
     643                 :          25 :   g_clear_signal_handler (&server->run_signal_handler_id, server->listener);
     644                 :          25 :   g_socket_service_stop (G_SOCKET_SERVICE (server->listener));
     645                 :          25 :   server->active = FALSE;
     646                 :          25 :   g_object_notify (G_OBJECT (server), "active");
     647                 :             : 
     648                 :          25 :   if (server->unix_socket_path)
     649                 :             :     {
     650                 :          20 :       if (g_unlink (server->unix_socket_path) != 0)
     651                 :           0 :         g_warning ("Failed to delete %s: %s", server->unix_socket_path, g_strerror (errno));
     652                 :             :     }
     653                 :             : 
     654                 :          25 :   if (server->nonce_file)
     655                 :             :     {
     656                 :           1 :       if (g_unlink (server->nonce_file) != 0)
     657                 :           0 :         g_warning ("Failed to delete %s: %s", server->nonce_file, g_strerror (errno));
     658                 :             :     }
     659                 :             : }
     660                 :             : 
     661                 :             : /* ---------------------------------------------------------------------------------------------------- */
     662                 :             : 
     663                 :             : static gint
     664                 :         152 : random_ascii (void)
     665                 :             : {
     666                 :             :   gint ret;
     667                 :         152 :   ret = g_random_int_range (0, 60);
     668                 :         152 :   if (ret < 25)
     669                 :          56 :     ret += 'A';
     670                 :          96 :   else if (ret < 50)
     671                 :          63 :     ret += 'a' - 25;
     672                 :             :   else
     673                 :          33 :     ret += '0' - 50;
     674                 :         152 :   return ret;
     675                 :             : }
     676                 :             : 
     677                 :             : /* note that address_entry has already been validated => exactly one of path, dir, tmpdir, or abstract keys are set */
     678                 :             : static gboolean
     679                 :          21 : try_unix (GDBusServer  *server,
     680                 :             :           const gchar  *address_entry,
     681                 :             :           GHashTable   *key_value_pairs,
     682                 :             :           GError      **error)
     683                 :             : {
     684                 :             :   gboolean ret;
     685                 :             :   const gchar *path;
     686                 :             :   const gchar *dir;
     687                 :             :   const gchar *tmpdir;
     688                 :             :   const gchar *abstract;
     689                 :             :   GSocketAddress *address;
     690                 :             : 
     691                 :          21 :   ret = FALSE;
     692                 :          21 :   address = NULL;
     693                 :             : 
     694                 :          21 :   path = g_hash_table_lookup (key_value_pairs, "path");
     695                 :          21 :   dir = g_hash_table_lookup (key_value_pairs, "dir");
     696                 :          21 :   tmpdir = g_hash_table_lookup (key_value_pairs, "tmpdir");
     697                 :          21 :   abstract = g_hash_table_lookup (key_value_pairs, "abstract");
     698                 :             : 
     699                 :          21 :   if (path != NULL)
     700                 :             :     {
     701                 :           2 :       address = g_unix_socket_address_new (path);
     702                 :             :     }
     703                 :          19 :   else if (dir != NULL || tmpdir != NULL)
     704                 :             :     {
     705                 :             :       gint n;
     706                 :             :       GString *s;
     707                 :             :       GError *local_error;
     708                 :          19 :       gsize orig_path_len = 0; // length before random characters are added
     709                 :             : 
     710                 :          19 :     retry:
     711                 :          19 :       s = g_string_new (tmpdir != NULL ? tmpdir : dir);
     712                 :          19 :       g_string_append (s, "/dbus-");
     713                 :          19 :       orig_path_len = s->len;
     714                 :         171 :       for (n = 0; n < 8; n++)
     715                 :         152 :         g_string_append_c (s, random_ascii ());
     716                 :             : 
     717                 :          19 :       address = g_unix_socket_address_new (s->str);
     718                 :          19 :       g_string_free (s, TRUE);
     719                 :             : 
     720                 :          19 :       local_error = NULL;
     721                 :          19 :       if (!g_socket_listener_add_address (server->listener,
     722                 :             :                                           address,
     723                 :             :                                           G_SOCKET_TYPE_STREAM,
     724                 :             :                                           G_SOCKET_PROTOCOL_DEFAULT,
     725                 :             :                                           NULL, /* source_object */
     726                 :             :                                           NULL, /* effective_address */
     727                 :             :                                           &local_error))
     728                 :             :         {
     729                 :           1 :           if (local_error->domain == G_IO_ERROR && local_error->code == G_IO_ERROR_ADDRESS_IN_USE)
     730                 :             :             {
     731                 :           1 :               if (orig_path_len < UNIX_PATH_MAX - 2) /* random_ascii + NULL byte */
     732                 :             :                 {
     733                 :           0 :                   g_error_free (local_error);
     734                 :           0 :                   goto retry;
     735                 :             :                 }
     736                 :             :             }
     737                 :           1 :           g_propagate_error (error, local_error);
     738                 :           1 :           goto out;
     739                 :             :         }
     740                 :          18 :       ret = TRUE;
     741                 :          18 :       goto out;
     742                 :             :     }
     743                 :           0 :   else if (abstract != NULL)
     744                 :             :     {
     745                 :           0 :       if (!g_unix_socket_address_abstract_names_supported ())
     746                 :             :         {
     747                 :           0 :           g_set_error_literal (error,
     748                 :             :                                G_IO_ERROR,
     749                 :             :                                G_IO_ERROR_NOT_SUPPORTED,
     750                 :             :                                _("Abstract namespace not supported"));
     751                 :           0 :           goto out;
     752                 :             :         }
     753                 :           0 :       address = g_unix_socket_address_new_with_type (abstract,
     754                 :             :                                                      -1,
     755                 :             :                                                      G_UNIX_SOCKET_ADDRESS_ABSTRACT);
     756                 :             :     }
     757                 :             :   else
     758                 :             :     {
     759                 :             :       g_assert_not_reached ();
     760                 :             :     }
     761                 :             : 
     762                 :           2 :   if (!g_socket_listener_add_address (server->listener,
     763                 :             :                                       address,
     764                 :             :                                       G_SOCKET_TYPE_STREAM,
     765                 :             :                                       G_SOCKET_PROTOCOL_DEFAULT,
     766                 :             :                                       NULL, /* source_object */
     767                 :             :                                       NULL, /* effective_address */
     768                 :             :                                       error))
     769                 :           0 :     goto out;
     770                 :             : 
     771                 :           2 :   ret = TRUE;
     772                 :             : 
     773                 :          21 :  out:
     774                 :             : 
     775                 :          21 :   if (address != NULL)
     776                 :             :     {
     777                 :             :       /* Fill out client_address if the connection attempt worked */
     778                 :          21 :       if (ret)
     779                 :             :         {
     780                 :             :           const char *address_path;
     781                 :             :           char *escaped_path;
     782                 :             : 
     783                 :          20 :           server->is_using_listener = TRUE;
     784                 :          20 :           address_path = g_unix_socket_address_get_path (G_UNIX_SOCKET_ADDRESS (address));
     785                 :          20 :           escaped_path = g_dbus_address_escape_value (address_path);
     786                 :             : 
     787                 :          20 :           switch (g_unix_socket_address_get_address_type (G_UNIX_SOCKET_ADDRESS (address)))
     788                 :             :             {
     789                 :           0 :             case G_UNIX_SOCKET_ADDRESS_ABSTRACT:
     790                 :           0 :               server->client_address = g_strdup_printf ("unix:abstract=%s", escaped_path);
     791                 :           0 :               break;
     792                 :             : 
     793                 :          20 :             case G_UNIX_SOCKET_ADDRESS_PATH:
     794                 :          20 :               server->client_address = g_strdup_printf ("unix:path=%s", escaped_path);
     795                 :          20 :               server->unix_socket_path = g_strdup (address_path);
     796                 :          20 :               break;
     797                 :             : 
     798                 :           0 :             default:
     799                 :             :               g_assert_not_reached ();
     800                 :             :               break;
     801                 :             :             }
     802                 :             : 
     803                 :          20 :           g_free (escaped_path);
     804                 :             :         }
     805                 :          21 :       g_object_unref (address);
     806                 :             :     }
     807                 :          21 :   return ret;
     808                 :             : }
     809                 :             : 
     810                 :             : /* ---------------------------------------------------------------------------------------------------- */
     811                 :             : 
     812                 :             : /* note that address_entry has already been validated =>
     813                 :             :  *  both host and port (guaranteed to be a number in [0, 65535]) are set (family is optional)
     814                 :             :  */
     815                 :             : static gboolean
     816                 :           5 : try_tcp (GDBusServer  *server,
     817                 :             :          const gchar  *address_entry,
     818                 :             :          GHashTable   *key_value_pairs,
     819                 :             :          gboolean      do_nonce,
     820                 :             :          GError      **error)
     821                 :             : {
     822                 :             :   gboolean ret;
     823                 :             :   const gchar *host;
     824                 :             :   const gchar *port;
     825                 :             :   gint port_num;
     826                 :             :   GResolver *resolver;
     827                 :             :   GList *resolved_addresses;
     828                 :             :   GList *l;
     829                 :             : 
     830                 :           5 :   ret = FALSE;
     831                 :           5 :   resolver = NULL;
     832                 :           5 :   resolved_addresses = NULL;
     833                 :             : 
     834                 :           5 :   host = g_hash_table_lookup (key_value_pairs, "host");
     835                 :           5 :   port = g_hash_table_lookup (key_value_pairs, "port");
     836                 :             :   /* family = g_hash_table_lookup (key_value_pairs, "family"); */
     837                 :           5 :   if (g_hash_table_lookup (key_value_pairs, "noncefile") != NULL)
     838                 :             :     {
     839                 :           0 :       g_set_error_literal (error,
     840                 :             :                            G_IO_ERROR,
     841                 :             :                            G_IO_ERROR_INVALID_ARGUMENT,
     842                 :             :                            _("Cannot specify nonce file when creating a server"));
     843                 :           0 :       goto out;
     844                 :             :     }
     845                 :             : 
     846                 :           5 :   if (host == NULL)
     847                 :           0 :     host = "localhost";
     848                 :           5 :   if (port == NULL)
     849                 :           5 :     port = "0";
     850                 :           5 :   port_num = strtol (port, NULL, 10);
     851                 :             : 
     852                 :           5 :   resolver = g_resolver_get_default ();
     853                 :           5 :   resolved_addresses = g_resolver_lookup_by_name (resolver,
     854                 :             :                                                   host,
     855                 :             :                                                   NULL,
     856                 :             :                                                   error);
     857                 :           5 :   if (resolved_addresses == NULL)
     858                 :           0 :     goto out;
     859                 :             : 
     860                 :             :   /* TODO: handle family */
     861                 :          10 :   for (l = resolved_addresses; l != NULL; l = l->next)
     862                 :             :     {
     863                 :           5 :       GInetAddress *address = G_INET_ADDRESS (l->data);
     864                 :             :       GSocketAddress *socket_address;
     865                 :             :       GSocketAddress *effective_address;
     866                 :             : 
     867                 :           5 :       socket_address = g_inet_socket_address_new (address, port_num);
     868                 :           5 :       if (!g_socket_listener_add_address (server->listener,
     869                 :             :                                           socket_address,
     870                 :             :                                           G_SOCKET_TYPE_STREAM,
     871                 :             :                                           G_SOCKET_PROTOCOL_TCP,
     872                 :             :                                           NULL, /* GObject *source_object */
     873                 :             :                                           &effective_address,
     874                 :             :                                           error))
     875                 :             :         {
     876                 :           0 :           g_object_unref (socket_address);
     877                 :           0 :           goto out;
     878                 :             :         }
     879                 :           5 :       if (port_num == 0)
     880                 :             :         /* make sure we allocate the same port number for other listeners */
     881                 :           5 :         port_num = g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (effective_address));
     882                 :             : 
     883                 :           5 :       g_object_unref (effective_address);
     884                 :           5 :       g_object_unref (socket_address);
     885                 :             :     }
     886                 :             : 
     887                 :           5 :   if (do_nonce)
     888                 :             :     {
     889                 :             :       gint fd;
     890                 :             :       guint n;
     891                 :             :       gsize bytes_written;
     892                 :             :       gsize bytes_remaining;
     893                 :             :       char *file_escaped;
     894                 :             :       char *host_escaped;
     895                 :             : 
     896                 :           1 :       server->nonce = g_new0 (guchar, 16);
     897                 :          17 :       for (n = 0; n < 16; n++)
     898                 :          16 :         server->nonce[n] = g_random_int_range (0, 256);
     899                 :           1 :       fd = g_file_open_tmp ("gdbus-nonce-file-XXXXXX",
     900                 :             :                             &server->nonce_file,
     901                 :             :                             error);
     902                 :           1 :       if (fd == -1)
     903                 :             :         {
     904                 :           0 :           g_socket_listener_close (server->listener);
     905                 :           0 :           goto out;
     906                 :             :         }
     907                 :           1 :     again:
     908                 :           1 :       bytes_written = 0;
     909                 :           1 :       bytes_remaining = 16;
     910                 :           2 :       while (bytes_remaining > 0)
     911                 :             :         {
     912                 :             :           gssize size;
     913                 :             :           int errsv;
     914                 :             : 
     915                 :           1 :           size = write (fd, server->nonce + bytes_written, bytes_remaining);
     916                 :           1 :           errsv = errno;
     917                 :           1 :           if (size == -1)
     918                 :             :             {
     919                 :           0 :               if (errsv == EINTR)
     920                 :           0 :                 goto again;
     921                 :           0 :               g_set_error (error,
     922                 :             :                            G_IO_ERROR,
     923                 :           0 :                            g_io_error_from_errno (errsv),
     924                 :             :                            _("Error writing nonce file at “%s”: %s"),
     925                 :             :                            server->nonce_file,
     926                 :             :                            g_strerror (errsv));
     927                 :           0 :               goto out;
     928                 :             :             }
     929                 :           1 :           bytes_written += size;
     930                 :           1 :           bytes_remaining -= size;
     931                 :             :         }
     932                 :           1 :       if (!g_close (fd, error))
     933                 :           0 :         goto out;
     934                 :           1 :       host_escaped = g_dbus_address_escape_value (host);
     935                 :           1 :       file_escaped = g_dbus_address_escape_value (server->nonce_file);
     936                 :           1 :       server->client_address = g_strdup_printf ("nonce-tcp:host=%s,port=%d,noncefile=%s",
     937                 :             :                                                 host_escaped,
     938                 :             :                                                 port_num,
     939                 :             :                                                 file_escaped);
     940                 :           1 :       g_free (host_escaped);
     941                 :           1 :       g_free (file_escaped);
     942                 :             :     }
     943                 :             :   else
     944                 :             :     {
     945                 :           4 :       server->client_address = g_strdup_printf ("tcp:host=%s,port=%d", host, port_num);
     946                 :             :     }
     947                 :           5 :   server->is_using_listener = TRUE;
     948                 :           5 :   ret = TRUE;
     949                 :             : 
     950                 :           5 :  out:
     951                 :           5 :   g_list_free_full (resolved_addresses, g_object_unref);
     952                 :           5 :   if (resolver)
     953                 :           5 :     g_object_unref (resolver);
     954                 :           5 :   return ret;
     955                 :             : }
     956                 :             : 
     957                 :             : /* ---------------------------------------------------------------------------------------------------- */
     958                 :             : 
     959                 :             : typedef struct
     960                 :             : {
     961                 :             :   GDBusServer *server;
     962                 :             :   GDBusConnection *connection;
     963                 :             : } EmitIdleData;
     964                 :             : 
     965                 :             : static void
     966                 :          20 : emit_idle_data_free (EmitIdleData *data)
     967                 :             : {
     968                 :          20 :   g_object_unref (data->server);
     969                 :          20 :   g_object_unref (data->connection);
     970                 :          20 :   g_free (data);
     971                 :          20 : }
     972                 :             : 
     973                 :             : static gboolean
     974                 :          20 : emit_new_connection_in_idle (gpointer user_data)
     975                 :             : {
     976                 :          20 :   EmitIdleData *data = user_data;
     977                 :             :   gboolean claimed;
     978                 :             : 
     979                 :          20 :   claimed = FALSE;
     980                 :          20 :   g_signal_emit (data->server,
     981                 :             :                  _signals[NEW_CONNECTION_SIGNAL],
     982                 :             :                  0,
     983                 :             :                  data->connection,
     984                 :             :                  &claimed);
     985                 :             : 
     986                 :          20 :   if (claimed)
     987                 :          15 :     g_dbus_connection_start_message_processing (data->connection);
     988                 :          20 :   g_object_unref (data->connection);
     989                 :             : 
     990                 :          20 :   return FALSE;
     991                 :             : }
     992                 :             : 
     993                 :             : /* Called in new thread */
     994                 :             : static gboolean
     995                 :         219 : on_run (GSocketService    *service,
     996                 :             :         GSocketConnection *socket_connection,
     997                 :             :         GObject           *source_object,
     998                 :             :         gpointer           user_data)
     999                 :             : {
    1000                 :         219 :   GDBusServer *server = G_DBUS_SERVER (user_data);
    1001                 :             :   GDBusConnection *connection;
    1002                 :             :   GDBusConnectionFlags connection_flags;
    1003                 :             : 
    1004                 :         219 :   if (server->nonce != NULL)
    1005                 :             :     {
    1006                 :             :       gchar buf[16];
    1007                 :             :       gsize bytes_read;
    1008                 :             : 
    1009                 :           2 :       if (!g_input_stream_read_all (g_io_stream_get_input_stream (G_IO_STREAM (socket_connection)),
    1010                 :             :                                     buf,
    1011                 :             :                                     16,
    1012                 :             :                                     &bytes_read,
    1013                 :             :                                     NULL,  /* GCancellable */
    1014                 :             :                                     NULL)) /* GError */
    1015                 :           1 :         goto out;
    1016                 :             : 
    1017                 :           2 :       if (bytes_read != 16)
    1018                 :           0 :         goto out;
    1019                 :             : 
    1020                 :           2 :       if (memcmp (buf, server->nonce, 16) != 0)
    1021                 :           1 :         goto out;
    1022                 :             :     }
    1023                 :             : 
    1024                 :         218 :   connection_flags =
    1025                 :             :     G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_SERVER |
    1026                 :             :     G_DBUS_CONNECTION_FLAGS_DELAY_MESSAGE_PROCESSING;
    1027                 :         218 :   if (server->flags & G_DBUS_SERVER_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS)
    1028                 :          44 :     connection_flags |= G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS;
    1029                 :         218 :   if (server->flags & G_DBUS_SERVER_FLAGS_AUTHENTICATION_REQUIRE_SAME_USER)
    1030                 :          21 :     connection_flags |= G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_REQUIRE_SAME_USER;
    1031                 :             : 
    1032                 :         218 :   connection = g_dbus_connection_new_sync (G_IO_STREAM (socket_connection),
    1033                 :         218 :                                            server->guid,
    1034                 :             :                                            connection_flags,
    1035                 :             :                                            server->authentication_observer,
    1036                 :             :                                            NULL,  /* GCancellable */
    1037                 :             :                                            NULL); /* GError */
    1038                 :         218 :   if (connection == NULL)
    1039                 :           9 :       goto out;
    1040                 :             : 
    1041                 :         209 :   if (server->flags & G_DBUS_SERVER_FLAGS_RUN_IN_THREAD)
    1042                 :             :     {
    1043                 :             :       gboolean claimed;
    1044                 :             : 
    1045                 :         189 :       claimed = FALSE;
    1046                 :         189 :       g_signal_emit (server,
    1047                 :             :                      _signals[NEW_CONNECTION_SIGNAL],
    1048                 :             :                      0,
    1049                 :             :                      connection,
    1050                 :             :                      &claimed);
    1051                 :         189 :       if (claimed)
    1052                 :         189 :         g_dbus_connection_start_message_processing (connection);
    1053                 :         189 :       g_object_unref (connection);
    1054                 :             :     }
    1055                 :             :   else
    1056                 :             :     {
    1057                 :             :       GSource *idle_source;
    1058                 :             :       EmitIdleData *data;
    1059                 :             : 
    1060                 :          20 :       data = g_new0 (EmitIdleData, 1);
    1061                 :          20 :       data->server = g_object_ref (server);
    1062                 :          20 :       data->connection = g_object_ref (connection);
    1063                 :             : 
    1064                 :          20 :       idle_source = g_idle_source_new ();
    1065                 :          20 :       g_source_set_priority (idle_source, G_PRIORITY_DEFAULT);
    1066                 :          20 :       g_source_set_callback (idle_source,
    1067                 :             :                              emit_new_connection_in_idle,
    1068                 :             :                              data,
    1069                 :             :                              (GDestroyNotify) emit_idle_data_free);
    1070                 :          20 :       g_source_set_static_name (idle_source, "[gio] emit_new_connection_in_idle");
    1071                 :          20 :       g_source_attach (idle_source, server->main_context_at_construction);
    1072                 :          20 :       g_source_unref (idle_source);
    1073                 :             :     }
    1074                 :             : 
    1075                 :         219 :  out:
    1076                 :         219 :   return TRUE;
    1077                 :             : }
    1078                 :             : 
    1079                 :             : static gboolean
    1080                 :          26 : initable_init (GInitable     *initable,
    1081                 :             :                GCancellable  *cancellable,
    1082                 :             :                GError       **error)
    1083                 :             : {
    1084                 :          26 :   GDBusServer *server = G_DBUS_SERVER (initable);
    1085                 :             :   gboolean ret;
    1086                 :             :   guint n;
    1087                 :             :   gchar **addr_array;
    1088                 :             :   GError *last_error;
    1089                 :             : 
    1090                 :          26 :   ret = FALSE;
    1091                 :          26 :   addr_array = NULL;
    1092                 :          26 :   last_error = NULL;
    1093                 :             : 
    1094                 :          26 :   if (!g_dbus_is_guid (server->guid))
    1095                 :             :     {
    1096                 :           0 :       g_set_error (&last_error,
    1097                 :             :                    G_IO_ERROR,
    1098                 :             :                    G_IO_ERROR_INVALID_ARGUMENT,
    1099                 :             :                    _("The string “%s” is not a valid D-Bus GUID"),
    1100                 :             :                    server->guid);
    1101                 :           0 :       goto out;
    1102                 :             :     }
    1103                 :             : 
    1104                 :          26 :   server->listener = G_SOCKET_LISTENER (g_threaded_socket_service_new (-1));
    1105                 :             : 
    1106                 :          26 :   addr_array = g_strsplit (server->address, ";", 0);
    1107                 :          26 :   last_error = NULL;
    1108                 :          27 :   for (n = 0; addr_array != NULL && addr_array[n] != NULL; n++)
    1109                 :             :     {
    1110                 :          26 :       const gchar *address_entry = addr_array[n];
    1111                 :             :       GHashTable *key_value_pairs;
    1112                 :             :       gchar *transport_name;
    1113                 :             :       GError *this_error;
    1114                 :             : 
    1115                 :          26 :       this_error = NULL;
    1116                 :          26 :       if (g_dbus_is_supported_address (address_entry,
    1117                 :          26 :                                        &this_error) &&
    1118                 :          26 :           _g_dbus_address_parse_entry (address_entry,
    1119                 :             :                                        &transport_name,
    1120                 :             :                                        &key_value_pairs,
    1121                 :             :                                        &this_error))
    1122                 :             :         {
    1123                 :             : 
    1124                 :             :           if (FALSE)
    1125                 :             :             {
    1126                 :             :             }
    1127                 :          26 :           else if (g_strcmp0 (transport_name, "unix") == 0)
    1128                 :          21 :             ret = try_unix (server, address_entry, key_value_pairs, &this_error);
    1129                 :           5 :           else if (g_strcmp0 (transport_name, "tcp") == 0)
    1130                 :           4 :             ret = try_tcp (server, address_entry, key_value_pairs, FALSE, &this_error);
    1131                 :           1 :           else if (g_strcmp0 (transport_name, "nonce-tcp") == 0)
    1132                 :           1 :             ret = try_tcp (server, address_entry, key_value_pairs, TRUE, &this_error);
    1133                 :             :           else
    1134                 :           0 :             g_set_error (&this_error,
    1135                 :             :                          G_IO_ERROR,
    1136                 :             :                          G_IO_ERROR_INVALID_ARGUMENT,
    1137                 :             :                          _("Cannot listen on unsupported transport “%s”"),
    1138                 :             :                          transport_name);
    1139                 :             : 
    1140                 :          26 :           g_free (transport_name);
    1141                 :          26 :           if (key_value_pairs != NULL)
    1142                 :          26 :             g_hash_table_unref (key_value_pairs);
    1143                 :             : 
    1144                 :          26 :           if (ret)
    1145                 :             :             {
    1146                 :          25 :               g_assert (this_error == NULL);
    1147                 :          25 :               goto out;
    1148                 :             :             }
    1149                 :             :         }
    1150                 :             : 
    1151                 :           1 :       if (this_error != NULL)
    1152                 :             :         {
    1153                 :           1 :           if (last_error != NULL)
    1154                 :           0 :             g_error_free (last_error);
    1155                 :           1 :           last_error = this_error;
    1156                 :             :         }
    1157                 :             :     }
    1158                 :             : 
    1159                 :           1 :  out:
    1160                 :             : 
    1161                 :          26 :   g_strfreev (addr_array);
    1162                 :             : 
    1163                 :          26 :   if (ret)
    1164                 :             :     {
    1165                 :          25 :       g_clear_error (&last_error);
    1166                 :             :     }
    1167                 :             :   else
    1168                 :             :     {
    1169                 :           1 :       g_assert (last_error != NULL);
    1170                 :           1 :       g_propagate_error (error, last_error);
    1171                 :             :     }
    1172                 :          26 :   return ret;
    1173                 :             : }
    1174                 :             : 
    1175                 :             : 
    1176                 :             : static void
    1177                 :           6 : initable_iface_init (GInitableIface *initable_iface)
    1178                 :             : {
    1179                 :           6 :   initable_iface->init = initable_init;
    1180                 :           6 : }
    1181                 :             : 
    1182                 :             : /* ---------------------------------------------------------------------------------------------------- */
        

Generated by: LCOV version 2.0-1