LCOV - code coverage report
Current view: top level - glib/gio/tests - gdbus-example-peer.c (source / functions) Hit Total Coverage
Test: unnamed Lines: 0 120 0.0 %
Date: 2024-04-23 05:16:05 Functions: 0 6 0.0 %
Branches: 0 28 0.0 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            : 
       3                 :            : Usage examples (modulo addresses / credentials).
       4                 :            : 
       5                 :            : UNIX domain socket transport:
       6                 :            : 
       7                 :            :  Server:
       8                 :            :    $ ./gdbus-example-peer --server --address unix:abstract=myaddr
       9                 :            :    Server is listening at: unix:abstract=myaddr
      10                 :            :    Client connected.
      11                 :            :    Peer credentials: GCredentials:unix-user=500,unix-group=500,unix-process=13378
      12                 :            :    Negotiated capabilities: unix-fd-passing=1
      13                 :            :    Client said: Hey, it's 1273093080 already!
      14                 :            : 
      15                 :            :  Client:
      16                 :            :    $ ./gdbus-example-peer --address unix:abstract=myaddr
      17                 :            :    Connected.
      18                 :            :    Negotiated capabilities: unix-fd-passing=1
      19                 :            :    Server said: You said 'Hey, it's 1273093080 already!'. KTHXBYE!
      20                 :            : 
      21                 :            : Nonce-secured TCP transport on the same host:
      22                 :            : 
      23                 :            :  Server:
      24                 :            :    $ ./gdbus-example-peer --server --address nonce-tcp:
      25                 :            :    Server is listening at: nonce-tcp:host=localhost,port=43077,noncefile=/tmp/gdbus-nonce-file-X1ZNCV
      26                 :            :    Client connected.
      27                 :            :    Peer credentials: (no credentials received)
      28                 :            :    Negotiated capabilities: unix-fd-passing=0
      29                 :            :    Client said: Hey, it's 1273093206 already!
      30                 :            : 
      31                 :            :  Client:
      32                 :            :    $ ./gdbus-example-peer -address nonce-tcp:host=localhost,port=43077,noncefile=/tmp/gdbus-nonce-file-X1ZNCV
      33                 :            :    Connected.
      34                 :            :    Negotiated capabilities: unix-fd-passing=0
      35                 :            :    Server said: You said 'Hey, it's 1273093206 already!'. KTHXBYE!
      36                 :            : 
      37                 :            : TCP transport on two different hosts with a shared home directory:
      38                 :            : 
      39                 :            :  Server:
      40                 :            :    host1 $ ./gdbus-example-peer --server --address tcp:host=0.0.0.0
      41                 :            :    Server is listening at: tcp:host=0.0.0.0,port=46314
      42                 :            :    Client connected.
      43                 :            :    Peer credentials: (no credentials received)
      44                 :            :    Negotiated capabilities: unix-fd-passing=0
      45                 :            :    Client said: Hey, it's 1273093337 already!
      46                 :            : 
      47                 :            :  Client:
      48                 :            :    host2 $ ./gdbus-example-peer -a tcp:host=host1,port=46314
      49                 :            :    Connected.
      50                 :            :    Negotiated capabilities: unix-fd-passing=0
      51                 :            :    Server said: You said 'Hey, it's 1273093337 already!'. KTHXBYE!
      52                 :            : 
      53                 :            : TCP transport on two different hosts without authentication:
      54                 :            : 
      55                 :            :  Server:
      56                 :            :    host1 $ ./gdbus-example-peer --server --address tcp:host=0.0.0.0 --allow-anonymous
      57                 :            :    Server is listening at: tcp:host=0.0.0.0,port=59556
      58                 :            :    Client connected.
      59                 :            :    Peer credentials: (no credentials received)
      60                 :            :    Negotiated capabilities: unix-fd-passing=0
      61                 :            :    Client said: Hey, it's 1273093652 already!
      62                 :            : 
      63                 :            :  Client:
      64                 :            :    host2 $ ./gdbus-example-peer -a tcp:host=host1,port=59556
      65                 :            :    Connected.
      66                 :            :    Negotiated capabilities: unix-fd-passing=0
      67                 :            :    Server said: You said 'Hey, it's 1273093652 already!'. KTHXBYE!
      68                 :            : 
      69                 :            :  */
      70                 :            : 
      71                 :            : #include <gio/gio.h>
      72                 :            : #include <stdlib.h>
      73                 :            : 
      74                 :            : /* ---------------------------------------------------------------------------------------------------- */
      75                 :            : 
      76                 :            : static GDBusNodeInfo *introspection_data = NULL;
      77                 :            : 
      78                 :            : /* Introspection data for the service we are exporting */
      79                 :            : static const gchar introspection_xml[] =
      80                 :            :   "<node>"
      81                 :            :   "  <interface name='org.gtk.GDBus.TestPeerInterface'>"
      82                 :            :   "    <method name='HelloWorld'>"
      83                 :            :   "      <arg type='s' name='greeting' direction='in'/>"
      84                 :            :   "      <arg type='s' name='response' direction='out'/>"
      85                 :            :   "    </method>"
      86                 :            :   "  </interface>"
      87                 :            :   "</node>";
      88                 :            : 
      89                 :            : /* ---------------------------------------------------------------------------------------------------- */
      90                 :            : 
      91                 :            : static void
      92                 :          0 : handle_method_call (GDBusConnection       *connection,
      93                 :            :                     const gchar           *sender,
      94                 :            :                     const gchar           *object_path,
      95                 :            :                     const gchar           *interface_name,
      96                 :            :                     const gchar           *method_name,
      97                 :            :                     GVariant              *parameters,
      98                 :            :                     GDBusMethodInvocation *invocation,
      99                 :            :                     gpointer               user_data)
     100                 :            : {
     101         [ #  # ]:          0 :   if (g_strcmp0 (method_name, "HelloWorld") == 0)
     102                 :            :     {
     103                 :            :       const gchar *greeting;
     104                 :            :       gchar *response;
     105                 :            : 
     106                 :          0 :       g_variant_get (parameters, "(&s)", &greeting);
     107                 :          0 :       response = g_strdup_printf ("You said '%s'. KTHXBYE!", greeting);
     108                 :          0 :       g_dbus_method_invocation_return_value (invocation,
     109                 :            :                                              g_variant_new ("(s)", response));
     110                 :          0 :       g_free (response);
     111                 :          0 :       g_print ("Client said: %s\n", greeting);
     112                 :            :     }
     113                 :          0 : }
     114                 :            : 
     115                 :            : static const GDBusInterfaceVTable interface_vtable =
     116                 :            : {
     117                 :            :   handle_method_call,
     118                 :            :   NULL,
     119                 :            :   NULL,
     120                 :            :   { 0 }
     121                 :            : };
     122                 :            : 
     123                 :            : /* ---------------------------------------------------------------------------------------------------- */
     124                 :            : 
     125                 :            : static void
     126                 :          0 : connection_closed (GDBusConnection *connection,
     127                 :            :                    gboolean remote_peer_vanished,
     128                 :            :                    GError *Error,
     129                 :            :                    gpointer user_data)
     130                 :            : {
     131                 :          0 :   g_print ("Client disconnected.\n");
     132                 :          0 :   g_object_unref (connection);
     133                 :          0 : }
     134                 :            : 
     135                 :            : static gboolean
     136                 :          0 : on_new_connection (GDBusServer *server,
     137                 :            :                    GDBusConnection *connection,
     138                 :            :                    gpointer user_data)
     139                 :            : {
     140                 :            :   guint registration_id;
     141                 :            :   GCredentials *credentials;
     142                 :            :   gchar *s;
     143                 :            : 
     144                 :          0 :   credentials = g_dbus_connection_get_peer_credentials (connection);
     145         [ #  # ]:          0 :   if (credentials == NULL)
     146                 :          0 :     s = g_strdup ("(no credentials received)");
     147                 :            :   else
     148                 :          0 :     s = g_credentials_to_string (credentials);
     149                 :            : 
     150                 :          0 :   g_print ("Client connected.\n"
     151                 :            :            "Peer credentials: %s\n"
     152                 :            :            "Negotiated capabilities: unix-fd-passing=%d\n",
     153                 :            :            s,
     154                 :          0 :            g_dbus_connection_get_capabilities (connection) & G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING);
     155                 :            : 
     156                 :          0 :   g_object_ref (connection);
     157                 :          0 :   g_signal_connect (connection, "closed", G_CALLBACK (connection_closed), NULL);
     158                 :          0 :   registration_id = g_dbus_connection_register_object (connection,
     159                 :            :                                                        "/org/gtk/GDBus/TestObject",
     160                 :          0 :                                                        introspection_data->interfaces[0],
     161                 :            :                                                        &interface_vtable,
     162                 :            :                                                        NULL,  /* user_data */
     163                 :            :                                                        NULL,  /* user_data_free_func */
     164                 :            :                                                        NULL); /* GError** */
     165                 :          0 :   g_assert (registration_id > 0);
     166                 :            : 
     167                 :          0 :   g_free (s);
     168                 :            : 
     169                 :          0 :   return TRUE;
     170                 :            : }
     171                 :            : 
     172                 :            : /* ---------------------------------------------------------------------------------------------------- */
     173                 :            : 
     174                 :            : static gboolean
     175                 :          0 : allow_mechanism_cb (GDBusAuthObserver *observer,
     176                 :            :                     const gchar *mechanism,
     177                 :            :                     G_GNUC_UNUSED gpointer user_data)
     178                 :            : {
     179                 :            :   /*
     180                 :            :    * In a production GDBusServer that only needs to work on modern Unix
     181                 :            :    * platforms, consider requiring EXTERNAL (credentials-passing),
     182                 :            :    * which is the recommended authentication mechanism for AF_UNIX
     183                 :            :    * sockets:
     184                 :            :    *
     185                 :            :    * if (g_strcmp0 (mechanism, "EXTERNAL") == 0)
     186                 :            :    *   return TRUE;
     187                 :            :    *
     188                 :            :    * return FALSE;
     189                 :            :    *
     190                 :            :    * For this example we accept everything.
     191                 :            :    */
     192                 :            : 
     193                 :          0 :   g_print ("Considering whether to accept %s authentication...\n", mechanism);
     194                 :          0 :   return TRUE;
     195                 :            : }
     196                 :            : 
     197                 :            : static gboolean
     198                 :          0 : authorize_authenticated_peer_cb (GDBusAuthObserver *observer,
     199                 :            :                                  G_GNUC_UNUSED GIOStream *stream,
     200                 :            :                                  GCredentials *credentials,
     201                 :            :                                  G_GNUC_UNUSED gpointer user_data)
     202                 :            : {
     203                 :          0 :   gboolean authorized = FALSE;
     204                 :            : 
     205                 :          0 :   g_print ("Considering whether to authorize authenticated peer...\n");
     206                 :            : 
     207         [ #  # ]:          0 :   if (credentials != NULL)
     208                 :            :     {
     209                 :            :       GCredentials *own_credentials;
     210                 :          0 :       gchar *credentials_string = NULL;
     211                 :            : 
     212                 :          0 :       credentials_string = g_credentials_to_string (credentials);
     213                 :          0 :       g_print ("Peer's credentials: %s\n", credentials_string);
     214                 :          0 :       g_free (credentials_string);
     215                 :            : 
     216                 :          0 :       own_credentials = g_credentials_new ();
     217                 :            : 
     218                 :          0 :       credentials_string = g_credentials_to_string (own_credentials);
     219                 :          0 :       g_print ("Server's credentials: %s\n", credentials_string);
     220                 :          0 :       g_free (credentials_string);
     221                 :            : 
     222         [ #  # ]:          0 :       if (g_credentials_is_same_user (credentials, own_credentials, NULL))
     223                 :          0 :         authorized = TRUE;
     224                 :            : 
     225                 :          0 :       g_object_unref (own_credentials);
     226                 :            :     }
     227                 :            : 
     228         [ #  # ]:          0 :   if (!authorized)
     229                 :            :     {
     230                 :            :       /* In most servers you'd want to reject this, but for this example
     231                 :            :        * we allow it. */
     232                 :          0 :       g_print ("A server would often not want to authorize this identity\n");
     233                 :          0 :       g_print ("Authorizing it anyway for demonstration purposes\n");
     234                 :          0 :       authorized = TRUE;
     235                 :            :     }
     236                 :            : 
     237                 :          0 :   return authorized;
     238                 :            : }
     239                 :            : 
     240                 :            : /* ---------------------------------------------------------------------------------------------------- */
     241                 :            : 
     242                 :            : int
     243                 :          0 : main (int argc, char *argv[])
     244                 :            : {
     245                 :            :   gint ret;
     246                 :            :   gboolean opt_server;
     247                 :            :   gchar *opt_address;
     248                 :            :   GOptionContext *opt_context;
     249                 :            :   gboolean opt_allow_anonymous;
     250                 :            :   GError *error;
     251                 :          0 :   GOptionEntry opt_entries[] =
     252                 :            :     {
     253                 :            :       { "server", 's', 0, G_OPTION_ARG_NONE, &opt_server, "Start a server instead of a client", NULL },
     254                 :            :       { "address", 'a', 0, G_OPTION_ARG_STRING, &opt_address, "D-Bus address to use", NULL },
     255                 :            :       { "allow-anonymous", 'n', 0, G_OPTION_ARG_NONE, &opt_allow_anonymous, "Allow anonymous authentication", NULL },
     256                 :            :       G_OPTION_ENTRY_NULL
     257                 :            :     };
     258                 :            : 
     259                 :          0 :   ret = 1;
     260                 :            : 
     261                 :          0 :   opt_address = NULL;
     262                 :          0 :   opt_server = FALSE;
     263                 :          0 :   opt_allow_anonymous = FALSE;
     264                 :            : 
     265                 :          0 :   opt_context = g_option_context_new ("peer-to-peer example");
     266                 :          0 :   error = NULL;
     267                 :          0 :   g_option_context_add_main_entries (opt_context, opt_entries, NULL);
     268         [ #  # ]:          0 :   if (!g_option_context_parse (opt_context, &argc, &argv, &error))
     269                 :            :     {
     270                 :          0 :       g_option_context_free (opt_context);
     271                 :          0 :       g_printerr ("Error parsing options: %s\n", error->message);
     272                 :          0 :       g_error_free (error);
     273                 :          0 :       goto out;
     274                 :            :     }
     275                 :            : 
     276                 :          0 :   g_option_context_free (opt_context);
     277                 :            : 
     278         [ #  # ]:          0 :   if (opt_address == NULL)
     279                 :            :     {
     280                 :          0 :       g_printerr ("Incorrect usage, try --help.\n");
     281                 :          0 :       goto out;
     282                 :            :     }
     283   [ #  #  #  # ]:          0 :   if (!opt_server && opt_allow_anonymous)
     284                 :            :     {
     285                 :          0 :       g_printerr ("The --allow-anonymous option only makes sense when used with --server.\n");
     286                 :          0 :       goto out;
     287                 :            :     }
     288                 :            : 
     289                 :            :   /* We are lazy here - we don't want to manually provide
     290                 :            :    * the introspection data structures - so we just build
     291                 :            :    * them from XML.
     292                 :            :    */
     293                 :          0 :   introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL);
     294                 :          0 :   g_assert (introspection_data != NULL);
     295                 :            : 
     296         [ #  # ]:          0 :   if (opt_server)
     297                 :            :     {
     298                 :            :       GDBusAuthObserver *observer;
     299                 :            :       GDBusServer *server;
     300                 :            :       gchar *guid;
     301                 :            :       GMainLoop *loop;
     302                 :            :       GDBusServerFlags server_flags;
     303                 :            : 
     304                 :          0 :       guid = g_dbus_generate_guid ();
     305                 :            : 
     306                 :          0 :       server_flags = G_DBUS_SERVER_FLAGS_NONE;
     307         [ #  # ]:          0 :       if (opt_allow_anonymous)
     308                 :          0 :         server_flags |= G_DBUS_SERVER_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS;
     309                 :            : 
     310                 :          0 :       observer = g_dbus_auth_observer_new ();
     311                 :          0 :       g_signal_connect (observer, "allow-mechanism", G_CALLBACK (allow_mechanism_cb), NULL);
     312                 :          0 :       g_signal_connect (observer, "authorize-authenticated-peer", G_CALLBACK (authorize_authenticated_peer_cb), NULL);
     313                 :            : 
     314                 :          0 :       error = NULL;
     315                 :          0 :       server = g_dbus_server_new_sync (opt_address,
     316                 :            :                                        server_flags,
     317                 :            :                                        guid,
     318                 :            :                                        observer,
     319                 :            :                                        NULL, /* GCancellable */
     320                 :            :                                        &error);
     321                 :          0 :       g_dbus_server_start (server);
     322                 :            : 
     323                 :          0 :       g_object_unref (observer);
     324                 :          0 :       g_free (guid);
     325                 :            : 
     326         [ #  # ]:          0 :       if (server == NULL)
     327                 :            :         {
     328                 :          0 :           g_printerr ("Error creating server at address %s: %s\n", opt_address, error->message);
     329                 :          0 :           g_error_free (error);
     330                 :          0 :           goto out;
     331                 :            :         }
     332                 :          0 :       g_print ("Server is listening at: %s\n", g_dbus_server_get_client_address (server));
     333                 :          0 :       g_signal_connect (server,
     334                 :            :                         "new-connection",
     335                 :            :                         G_CALLBACK (on_new_connection),
     336                 :            :                         NULL);
     337                 :            : 
     338                 :          0 :       loop = g_main_loop_new (NULL, FALSE);
     339                 :          0 :       g_main_loop_run (loop);
     340                 :            : 
     341                 :          0 :       g_object_unref (server);
     342                 :          0 :       g_main_loop_unref (loop);
     343                 :            :     }
     344                 :            :   else
     345                 :            :     {
     346                 :            :       GDBusConnection *connection;
     347                 :            :       const gchar *greeting_response;
     348                 :            :       GVariant *value;
     349                 :            :       gchar *greeting;
     350                 :            : 
     351                 :          0 :       error = NULL;
     352                 :          0 :       connection = g_dbus_connection_new_for_address_sync (opt_address,
     353                 :            :                                                            G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
     354                 :            :                                                            NULL, /* GDBusAuthObserver */
     355                 :            :                                                            NULL, /* GCancellable */
     356                 :            :                                                            &error);
     357         [ #  # ]:          0 :       if (connection == NULL)
     358                 :            :         {
     359                 :          0 :           g_printerr ("Error connecting to D-Bus address %s: %s\n", opt_address, error->message);
     360                 :          0 :           g_error_free (error);
     361                 :          0 :           goto out;
     362                 :            :         }
     363                 :            : 
     364                 :          0 :       g_print ("Connected.\n"
     365                 :            :                "Negotiated capabilities: unix-fd-passing=%d\n",
     366                 :          0 :                g_dbus_connection_get_capabilities (connection) & G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING);
     367                 :            : 
     368                 :          0 :       greeting = g_strdup_printf ("Hey, it's %" G_GINT64_FORMAT " already!",
     369                 :          0 :                                   g_get_real_time () / G_USEC_PER_SEC);
     370                 :          0 :       value = g_dbus_connection_call_sync (connection,
     371                 :            :                                            NULL, /* bus_name */
     372                 :            :                                            "/org/gtk/GDBus/TestObject",
     373                 :            :                                            "org.gtk.GDBus.TestPeerInterface",
     374                 :            :                                            "HelloWorld",
     375                 :            :                                            g_variant_new ("(s)", greeting),
     376                 :            :                                            G_VARIANT_TYPE ("(s)"),
     377                 :            :                                            G_DBUS_CALL_FLAGS_NONE,
     378                 :            :                                            -1,
     379                 :            :                                            NULL,
     380                 :            :                                            &error);
     381                 :          0 :       g_free (greeting);
     382                 :            : 
     383         [ #  # ]:          0 :       if (value == NULL)
     384                 :            :         {
     385                 :          0 :           g_printerr ("Error invoking HelloWorld(): %s\n", error->message);
     386                 :          0 :           g_error_free (error);
     387                 :          0 :           goto out;
     388                 :            :         }
     389                 :          0 :       g_variant_get (value, "(&s)", &greeting_response);
     390                 :          0 :       g_print ("Server said: %s\n", greeting_response);
     391                 :          0 :       g_variant_unref (value);
     392                 :            : 
     393                 :          0 :       g_object_unref (connection);
     394                 :            :     }
     395                 :          0 :   g_dbus_node_info_unref (introspection_data);
     396                 :            : 
     397                 :          0 :   ret = 0;
     398                 :            : 
     399                 :          0 :  out:
     400                 :          0 :   g_free (opt_address);
     401                 :            : 
     402                 :          0 :   return ret;
     403                 :            : }

Generated by: LCOV version 1.14