1 /*
2  * tube-dbus.c - Source for GabbleTubeDBus
3  * Copyright (C) 2007-2008 Collabora Ltd.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18  */
19 
20 #include "config.h"
21 #include "tube-dbus.h"
22 
23 #include <string.h>
24 #include <errno.h>
25 
26 #include <glib/gstdio.h>
27 #include <dbus/dbus-glib.h>
28 #include <dbus/dbus-glib-lowlevel.h>
29 #include <wocky/wocky.h>
30 #include <telepathy-glib/telepathy-glib.h>
31 #include <telepathy-glib/telepathy-glib-dbus.h>
32 
33 #include "extensions/extensions.h"
34 
35 #define DEBUG_FLAG GABBLE_DEBUG_TUBES
36 
37 #include "bytestream-factory.h"
38 #include "bytestream-ibb.h"
39 #include "bytestream-iface.h"
40 #include "connection.h"
41 #include "debug.h"
42 #include "disco.h"
43 #include "gabble-signals-marshal.h"
44 #include "muc-tube-dbus.h"
45 #include "namespaces.h"
46 #include "presence-cache.h"
47 #include "tube-iface.h"
48 #include "util.h"
49 
50 /* When we receive D-Bus messages to be delivered to the application and the
51  * application is not yet connected to the D-Bus tube, theses D-Bus messages
52  * are queued and delivered when the application connects to the D-Bus tube.
53  *
54  * If the application never connects, there is a risk that the contact sends
55  * too many messages and eat all the memory. To avoid this, there is an
56  * arbitrary limit on the queue size set to 4MB. */
57 #define MAX_QUEUE_SIZE (4096*1024)
58 
59 static void tube_iface_init (gpointer g_iface, gpointer iface_data);
60 static void dbustube_iface_init (gpointer g_iface, gpointer iface_data);
61 
62 G_DEFINE_TYPE_WITH_CODE (GabbleTubeDBus, gabble_tube_dbus,
63     TP_TYPE_BASE_CHANNEL,
64     G_IMPLEMENT_INTERFACE (GABBLE_TYPE_TUBE_IFACE, tube_iface_init);
65     G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_TYPE_DBUS_TUBE,
66       dbustube_iface_init);
67     G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_TUBE,
68       NULL);
69     G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_GROUP,
70       tp_external_group_mixin_iface_init);
71 );
72 
73 static const gchar * const gabble_tube_dbus_channel_allowed_properties[] = {
74     TP_IFACE_CHANNEL ".TargetHandle",
75     TP_IFACE_CHANNEL ".TargetID",
76     TP_IFACE_CHANNEL_TYPE_DBUS_TUBE ".ServiceName",
77     NULL
78 };
79 
80 /* signals */
81 enum
82 {
83   OPENED,
84   CLOSED,
85   OFFERED,
86   LAST_SIGNAL
87 };
88 
89 static guint signals[LAST_SIGNAL] = {0};
90 
91 /* properties */
92 enum
93 {
94   PROP_SELF_HANDLE = 1,
95   PROP_ID,
96   PROP_BYTESTREAM,
97   PROP_STREAM_ID,
98   PROP_TYPE,
99   PROP_SERVICE,
100   PROP_PARAMETERS,
101   PROP_STATE,
102   PROP_DBUS_ADDRESS,
103   PROP_DBUS_NAME,
104   PROP_DBUS_NAMES,
105   PROP_MUC,
106   PROP_SUPPORTED_ACCESS_CONTROLS,
107   LAST_PROPERTY
108 };
109 
110 struct _GabbleTubeDBusPrivate
111 {
112   TpHandle self_handle;
113   guint64 id;
114   GabbleBytestreamIface *bytestream;
115   gchar *stream_id;
116   gchar *service;
117   GHashTable *parameters;
118   GabbleMucChannel *muc;
119   TpSocketAccessControl access_control;
120   /* GArray of guint */
121   GArray *supported_access_controls;
122 
123   /* For outgoing tubes, TRUE if the offer has been sent over the network. For
124    * incoming tubes, always TRUE.
125    */
126   gboolean offered;
127 
128   /* our unique D-Bus name on the virtual tube bus (NULL for 1-1 D-Bus tubes)*/
129   gchar *dbus_local_name;
130   /* the address that we are listening for D-Bus connections on */
131   gchar *dbus_srv_addr;
132   /* the path of the UNIX socket used by the D-Bus server */
133   gchar *socket_path;
134   /* the server that's listening on dbus_srv_addr */
135   DBusServer *dbus_srv;
136   /* the connection to dbus_srv from a local client, or NULL */
137   DBusConnection *dbus_conn;
138   /* the queue of D-Bus messages to be delivered to a local client when it
139    * will connect */
140   GSList *dbus_msg_queue;
141   /* current size of the queue in bytes. The maximum is MAX_QUEUE_SIZE */
142   unsigned long dbus_msg_queue_size;
143   /* mapping of contact handle -> D-Bus name (empty for 1-1 D-Bus tubes) */
144   GHashTable *dbus_names;
145   /* mapping of D-Bus name -> contact handle */
146   GHashTable *dbus_name_to_handle;
147 
148   /* Message reassembly buffer (CONTACT tubes only) */
149   GString *reassembly_buffer;
150   /* Number of bytes that will be in the next message, 0 if unknown */
151   guint32 reassembly_bytes_needed;
152 
153   gboolean dispose_has_run;
154 };
155 
156 #define GABBLE_TUBE_DBUS_GET_PRIVATE(obj) ((obj)->priv)
157 
158 static GPtrArray *
gabble_tube_dbus_get_interfaces(TpBaseChannel * base)159 gabble_tube_dbus_get_interfaces (TpBaseChannel *base)
160 {
161   GPtrArray *interfaces;
162 
163   interfaces = TP_BASE_CHANNEL_CLASS (
164       gabble_tube_dbus_parent_class)->get_interfaces (base);
165 
166   g_ptr_array_add (interfaces, TP_IFACE_CHANNEL_INTERFACE_TUBE);
167 
168   return interfaces;
169 }
170 
171 static void data_received_cb (GabbleBytestreamIface *stream, TpHandle sender,
172     GString *data, gpointer user_data);
173 
174 /*
175  * Characters used are permissible both in filenames and in D-Bus names. (See
176  * D-Bus specification for restrictions.)
177  */
178 static void
generate_ascii_string(guint len,gchar * buf)179 generate_ascii_string (guint len,
180                        gchar *buf)
181 {
182   const gchar *chars =
183     "0123456789"
184     "abcdefghijklmnopqrstuvwxyz"
185     "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
186     "_-";
187   guint i;
188 
189   for (i = 0; i < len; i++)
190     buf[i] = chars[g_random_int_range (0, 64)];
191 }
192 
193 static DBusHandlerResult
filter_cb(DBusConnection * conn,DBusMessage * msg,void * user_data)194 filter_cb (DBusConnection *conn,
195            DBusMessage *msg,
196            void *user_data)
197 {
198   GabbleTubeDBus *tube = GABBLE_TUBE_DBUS (user_data);
199   GabbleTubeDBusPrivate *priv = GABBLE_TUBE_DBUS_GET_PRIVATE (tube);
200   gchar *marshalled = NULL;
201   gint len;
202 
203   if (dbus_message_get_type (msg) == DBUS_MESSAGE_TYPE_SIGNAL &&
204       !tp_strdiff (dbus_message_get_interface (msg),
205         "org.freedesktop.DBus.Local") &&
206       !tp_strdiff (dbus_message_get_member (msg), "Disconnected"))
207     {
208       /* connection was disconnected */
209       DEBUG ("connection was disconnected");
210       dbus_connection_close (priv->dbus_conn);
211       tp_clear_pointer (&priv->dbus_conn, dbus_connection_unref);
212       goto out;
213     }
214 
215   if (priv->dbus_local_name != NULL)
216     {
217       if (!dbus_message_set_sender (msg, priv->dbus_local_name))
218         DEBUG ("dbus_message_set_sender failed");
219     }
220 
221   if (!dbus_message_marshal (msg, &marshalled, &len))
222     goto out;
223 
224   if (GABBLE_IS_BYTESTREAM_MUC (priv->bytestream))
225     {
226       /* This bytestream support direct send */
227       const gchar *dest;
228 
229       dest = dbus_message_get_destination (msg);
230 
231       if (dest != NULL)
232         {
233           TpHandle handle;
234 
235           handle = GPOINTER_TO_UINT (g_hash_table_lookup (
236                 priv->dbus_name_to_handle, dest));
237 
238           if (handle == 0)
239             {
240               DEBUG ("Unknown D-Bus name: %s", dest);
241               goto out;
242             }
243 
244           gabble_bytestream_muc_send_to (
245               GABBLE_BYTESTREAM_MUC (priv->bytestream), handle, len,
246               marshalled);
247 
248           goto out;
249         }
250     }
251 
252   gabble_bytestream_iface_send (priv->bytestream, len, marshalled);
253 
254 out:
255   if (marshalled != NULL)
256     g_free (marshalled);
257 
258   return DBUS_HANDLER_RESULT_HANDLED;
259 }
260 
261 static dbus_bool_t
allow_all_connections(DBusConnection * conn,unsigned long uid,void * data)262 allow_all_connections (DBusConnection *conn,
263                        unsigned long uid,
264                        void *data)
265 {
266   return TRUE;
267 }
268 
269 static void
new_connection_cb(DBusServer * server,DBusConnection * conn,void * data)270 new_connection_cb (DBusServer *server,
271                    DBusConnection *conn,
272                    void *data)
273 {
274   GabbleTubeDBus *tube = GABBLE_TUBE_DBUS (data);
275   GabbleTubeDBusPrivate *priv = GABBLE_TUBE_DBUS_GET_PRIVATE (tube);
276   guint32 serial;
277   GSList *i;
278 
279   if (priv->dbus_conn != NULL)
280     /* we already have a connection; drop this new one */
281     /* return without reffing conn means it will be dropped */
282     return;
283 
284   DEBUG ("got connection");
285 
286   dbus_connection_ref (conn);
287   dbus_connection_setup_with_g_main (conn, NULL);
288   dbus_connection_add_filter (conn, filter_cb, tube, NULL);
289   priv->dbus_conn = conn;
290 
291   if (priv->access_control == TP_SOCKET_ACCESS_CONTROL_LOCALHOST)
292     {
293       /* By default libdbus use Credentials access control. If user wants
294        * to use the Localhost access control, we need to bypass this check. */
295       dbus_connection_set_unix_user_function (conn, allow_all_connections,
296           NULL, NULL);
297     }
298 
299   /* We may have received messages to deliver before the local connection is
300    * established. Theses messages are kept in the dbus_msg_queue list and are
301    * delivered as soon as we get the connection. */
302   DEBUG ("%u messages in the queue (%lu bytes)",
303          g_slist_length (priv->dbus_msg_queue), priv->dbus_msg_queue_size);
304   priv->dbus_msg_queue = g_slist_reverse (priv->dbus_msg_queue);
305   for (i = priv->dbus_msg_queue; i != NULL; i = g_slist_delete_link (i, i))
306     {
307       DBusMessage *msg = i->data;
308       DEBUG ("delivering queued message from '%s' to '%s' on the "
309              "new connection",
310              dbus_message_get_sender (msg),
311              dbus_message_get_destination (msg));
312       dbus_connection_send (priv->dbus_conn, msg, &serial);
313       dbus_message_unref (msg);
314     }
315   priv->dbus_msg_queue = NULL;
316   priv->dbus_msg_queue_size = 0;
317 }
318 
319 static void
gabble_tube_dbus_close(TpBaseChannel * base)320 gabble_tube_dbus_close (TpBaseChannel *base)
321 {
322   GabbleTubeDBus *self = GABBLE_TUBE_DBUS (base);
323   GabbleTubeDBusPrivate *priv = GABBLE_TUBE_DBUS_GET_PRIVATE (self);
324 
325   /* Take a ref to ourselves as when we emit tube-closed
326    * GabbleTubesChannel will drop our last ref but we still need to
327    * declare ourselves as destroyed. This is rubbish, but will
328    * disappear when we finally remove the Tubes channel type.. */
329   g_object_ref (base);
330 
331   if (priv->bytestream != NULL)
332     gabble_bytestream_iface_close (priv->bytestream, NULL);
333   else
334     g_signal_emit (G_OBJECT (self), signals[CLOSED],0);
335 
336   tp_base_channel_destroyed (base);
337 
338   g_object_unref (base);
339 }
340 
341 /* There is two step to enable receiving a D-Bus connection from the local
342  * application:
343  * - listen on the socket
344  * - add the socket in the mainloop
345  *
346  * We need to know the socket path to return from the AcceptDBusTube D-Bus
347  * call but the socket in the mainloop must be added only when we are ready
348  * to receive connections, that is when the bytestream is fully open with the
349  * remote contact.
350  *
351  * See also Bug 13891:
352  * https://bugs.freedesktop.org/show_bug.cgi?id=13891
353  * */
354 static gboolean
create_dbus_server(GabbleTubeDBus * self,GError ** err)355 create_dbus_server (GabbleTubeDBus *self,
356                     GError **err)
357 {
358 #define SERVER_LISTEN_MAX_TRIES 5
359   GabbleTubeDBusPrivate *priv = GABBLE_TUBE_DBUS_GET_PRIVATE (self);
360   guint i;
361 
362   if (priv->dbus_srv != NULL)
363     return TRUE;
364 
365   for (i = 0; i < SERVER_LISTEN_MAX_TRIES; i++)
366     {
367       gchar suffix[8];
368       DBusError error;
369 
370       g_free (priv->dbus_srv_addr);
371       g_free (priv->socket_path);
372 
373       generate_ascii_string (8, suffix);
374       priv->socket_path = g_strdup_printf ("%s/dbus-gabble-%.8s",
375           g_get_tmp_dir (), suffix);
376       priv->dbus_srv_addr = g_strdup_printf ("unix:path=%s",
377           priv->socket_path);
378 
379       dbus_error_init (&error);
380       priv->dbus_srv = dbus_server_listen (priv->dbus_srv_addr, &error);
381 
382       if (priv->dbus_srv != NULL)
383         break;
384 
385       DEBUG ("dbus_server_listen failed (try %u): %s: %s", i, error.name,
386           error.message);
387       dbus_error_free (&error);
388     }
389 
390   if (priv->dbus_srv == NULL)
391     {
392       DEBUG ("all attempts failed. Close the tube");
393 
394       g_free (priv->dbus_srv_addr);
395       priv->dbus_srv_addr = NULL;
396 
397       g_free (priv->socket_path);
398       priv->socket_path = NULL;
399 
400       g_set_error (err, TP_ERROR, TP_ERROR_NOT_AVAILABLE,
401           "Can't create D-Bus server");
402       return FALSE;
403     }
404 
405   DEBUG ("listening on %s", priv->dbus_srv_addr);
406 
407   dbus_server_set_new_connection_function (priv->dbus_srv, new_connection_cb,
408       self, NULL);
409 
410   return TRUE;
411 }
412 
413 static void
tube_dbus_open(GabbleTubeDBus * self)414 tube_dbus_open (GabbleTubeDBus *self)
415 {
416   GabbleTubeDBusPrivate *priv = GABBLE_TUBE_DBUS_GET_PRIVATE (self);
417   TpBaseChannel *base = TP_BASE_CHANNEL (self);
418   TpBaseChannelClass *cls = TP_BASE_CHANNEL_GET_CLASS (base);
419 
420   g_signal_connect (priv->bytestream, "data-received",
421       G_CALLBACK (data_received_cb), self);
422 
423   /* TODO: we should remove this call once muc D-Bus tube new API are
424    * implemented  as the server should already exist. */
425   if (!create_dbus_server (self, NULL))
426     tp_base_channel_close (TP_BASE_CHANNEL (self));
427 
428   if (priv->dbus_srv != NULL)
429     {
430       dbus_server_setup_with_g_main (priv->dbus_srv, NULL);
431     }
432 
433   if (cls->target_handle_type == TP_HANDLE_TYPE_ROOM)
434     {
435       /* add yourself in dbus names */
436       gabble_tube_dbus_add_name (self, priv->self_handle,
437           priv->dbus_local_name);
438 
439       gabble_muc_channel_send_presence (priv->muc);
440     }
441 }
442 
443 static void
gabble_tube_dbus_init(GabbleTubeDBus * self)444 gabble_tube_dbus_init (GabbleTubeDBus *self)
445 {
446   GabbleTubeDBusPrivate *priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
447       GABBLE_TYPE_TUBE_DBUS, GabbleTubeDBusPrivate);
448 
449   self->priv = priv;
450 }
451 
452 static TpTubeChannelState
get_tube_state(GabbleTubeDBus * self)453 get_tube_state (GabbleTubeDBus *self)
454 {
455   GabbleTubeDBusPrivate *priv = GABBLE_TUBE_DBUS_GET_PRIVATE (self);
456   GabbleBytestreamState bytestream_state;
457 
458   if (!priv->offered)
459     return TP_TUBE_CHANNEL_STATE_NOT_OFFERED;
460 
461   if (priv->bytestream == NULL)
462     /* bytestream not yet created as we're waiting for the SI reply */
463     return TP_TUBE_CHANNEL_STATE_REMOTE_PENDING;
464 
465   g_object_get (priv->bytestream, "state", &bytestream_state, NULL);
466 
467   switch (bytestream_state)
468     {
469       case GABBLE_BYTESTREAM_STATE_OPEN:
470         return TP_TUBE_CHANNEL_STATE_OPEN;
471         break;
472       case GABBLE_BYTESTREAM_STATE_LOCAL_PENDING:
473       case GABBLE_BYTESTREAM_STATE_ACCEPTED:
474         return TP_TUBE_CHANNEL_STATE_LOCAL_PENDING;
475         break;
476       case GABBLE_BYTESTREAM_STATE_INITIATING:
477         return TP_TUBE_CHANNEL_STATE_REMOTE_PENDING;
478         break;
479       default:
480         g_return_val_if_reached (0);
481     }
482 }
483 
484 static void
bytestream_state_changed_cb(GabbleBytestreamIface * bytestream,GabbleBytestreamState state,gpointer user_data)485 bytestream_state_changed_cb (GabbleBytestreamIface *bytestream,
486                              GabbleBytestreamState state,
487                              gpointer user_data)
488 {
489   GabbleTubeDBus *self = GABBLE_TUBE_DBUS (user_data);
490   GabbleTubeDBusPrivate *priv = GABBLE_TUBE_DBUS_GET_PRIVATE (self);
491   TpBaseChannel *base = TP_BASE_CHANNEL (self);
492   TpBaseChannelClass *cls = TP_BASE_CHANNEL_GET_CLASS (base);
493 
494   if (state == GABBLE_BYTESTREAM_STATE_CLOSED)
495     {
496       tp_clear_object (&priv->bytestream);
497       g_signal_emit (G_OBJECT (self), signals[CLOSED], 0);
498 
499       if (cls->target_handle_type == TP_HANDLE_TYPE_ROOM)
500         gabble_muc_channel_send_presence (priv->muc);
501     }
502   else if (state == GABBLE_BYTESTREAM_STATE_OPEN)
503     {
504       tube_dbus_open (self);
505 
506       tp_svc_channel_interface_tube_emit_tube_channel_state_changed (self,
507           TP_TUBE_CHANNEL_STATE_OPEN);
508 
509       g_signal_emit (G_OBJECT (self), signals[OPENED], 0);
510     }
511 }
512 
513 static void
gabble_tube_dbus_dispose(GObject * object)514 gabble_tube_dbus_dispose (GObject *object)
515 {
516   GabbleTubeDBus *self = GABBLE_TUBE_DBUS (object);
517   GabbleTubeDBusPrivate *priv = GABBLE_TUBE_DBUS_GET_PRIVATE (self);
518 
519   DEBUG ("called");
520 
521   if (priv->dispose_has_run)
522     return;
523 
524   priv->dispose_has_run = TRUE;
525 
526   if (priv->bytestream != NULL)
527     gabble_bytestream_iface_close (priv->bytestream, NULL);
528 
529   if (priv->dbus_conn != NULL)
530     dbus_connection_close (priv->dbus_conn);
531 
532   tp_clear_pointer (&priv->dbus_conn, dbus_connection_unref);
533 
534   if (priv->dbus_srv != NULL)
535     dbus_server_disconnect (priv->dbus_srv);
536 
537   tp_clear_pointer (&priv->dbus_srv, dbus_server_unref);
538 
539   if (priv->socket_path != NULL)
540     {
541       if (g_unlink (priv->socket_path) != 0)
542         {
543           DEBUG ("unlink of %s failed: %s", priv->socket_path,
544               g_strerror (errno));
545         }
546     }
547 
548   if (priv->dbus_msg_queue != NULL)
549     {
550       GSList *i;
551       for (i = priv->dbus_msg_queue; i != NULL; i = g_slist_delete_link (i, i))
552         {
553           DBusMessage *msg = i->data;
554           dbus_message_unref (msg);
555         }
556       priv->dbus_msg_queue = NULL;
557       priv->dbus_msg_queue_size = 0;
558     }
559 
560   tp_clear_pointer (&priv->dbus_srv_addr, g_free);
561   tp_clear_pointer (&priv->socket_path, g_free);
562   tp_clear_pointer (&priv->dbus_local_name, g_free);
563   tp_clear_pointer (&priv->dbus_names, g_hash_table_unref);
564   tp_clear_pointer (&priv->dbus_name_to_handle, g_hash_table_unref);
565 
566   if (priv->reassembly_buffer)
567     g_string_free (priv->reassembly_buffer, TRUE);
568 
569   if (G_OBJECT_CLASS (gabble_tube_dbus_parent_class)->dispose)
570     G_OBJECT_CLASS (gabble_tube_dbus_parent_class)->dispose (object);
571 }
572 
573 static void
gabble_tube_dbus_finalize(GObject * object)574 gabble_tube_dbus_finalize (GObject *object)
575 {
576   GabbleTubeDBus *self = GABBLE_TUBE_DBUS (object);
577   GabbleTubeDBusPrivate *priv = GABBLE_TUBE_DBUS_GET_PRIVATE (self);
578 
579   g_free (priv->stream_id);
580   g_free (priv->service);
581   g_hash_table_unref (priv->parameters);
582   g_array_unref (priv->supported_access_controls);
583 
584   if (priv->muc != NULL)
585     tp_external_group_mixin_finalize (object);
586 
587   G_OBJECT_CLASS (gabble_tube_dbus_parent_class)->finalize (object);
588 }
589 
590 static void
gabble_tube_dbus_get_property(GObject * object,guint property_id,GValue * value,GParamSpec * pspec)591 gabble_tube_dbus_get_property (GObject *object,
592                                guint property_id,
593                                GValue *value,
594                                GParamSpec *pspec)
595 {
596   GabbleTubeDBus *self = GABBLE_TUBE_DBUS (object);
597   GabbleTubeDBusPrivate *priv = GABBLE_TUBE_DBUS_GET_PRIVATE (self);
598 
599   switch (property_id)
600     {
601       case PROP_SELF_HANDLE:
602         g_value_set_uint (value, priv->self_handle);
603         break;
604       case PROP_ID:
605         g_value_set_uint64 (value, priv->id);
606         break;
607       case PROP_BYTESTREAM:
608         g_value_set_object (value, priv->bytestream);
609         break;
610       case PROP_STREAM_ID:
611         g_value_set_string (value, priv->stream_id);
612         break;
613       case PROP_TYPE:
614         g_value_set_uint (value, TP_TUBE_TYPE_DBUS);
615         break;
616       case PROP_SERVICE:
617         g_value_set_string (value, priv->service);
618         break;
619       case PROP_PARAMETERS:
620         g_value_set_boxed (value, priv->parameters);
621         break;
622       case PROP_STATE:
623         g_value_set_uint (value, get_tube_state (self));
624         break;
625       case PROP_DBUS_ADDRESS:
626         g_value_set_string (value, priv->dbus_srv_addr);
627         break;
628       case PROP_DBUS_NAME:
629         g_value_set_string (value, priv->dbus_local_name);
630         break;
631       case PROP_DBUS_NAMES:
632         g_value_set_boxed (value, priv->dbus_names);
633         break;
634       case PROP_MUC:
635         g_value_set_object (value, priv->muc);
636         break;
637       case PROP_SUPPORTED_ACCESS_CONTROLS:
638         g_value_set_boxed (value, priv->supported_access_controls);
639         break;
640       default:
641         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
642         break;
643     }
644 }
645 
646 static void
gabble_tube_dbus_set_property(GObject * object,guint property_id,const GValue * value,GParamSpec * pspec)647 gabble_tube_dbus_set_property (GObject *object,
648                                guint property_id,
649                                const GValue *value,
650                                GParamSpec *pspec)
651 {
652   GabbleTubeDBus *self = GABBLE_TUBE_DBUS (object);
653   GabbleTubeDBusPrivate *priv = GABBLE_TUBE_DBUS_GET_PRIVATE (self);
654 
655   switch (property_id)
656     {
657       case PROP_SELF_HANDLE:
658         priv->self_handle = g_value_get_uint (value);
659         break;
660       case PROP_ID:
661         priv->id = g_value_get_uint64 (value);
662         break;
663       case PROP_BYTESTREAM:
664         if (priv->bytestream == NULL)
665           {
666             GabbleBytestreamState state;
667 
668             priv->bytestream = g_value_get_object (value);
669             g_object_ref (priv->bytestream);
670 
671             g_object_get (priv->bytestream, "state", &state, NULL);
672             if (state == GABBLE_BYTESTREAM_STATE_OPEN)
673               {
674                 tube_dbus_open (self);
675               }
676 
677             g_signal_connect (priv->bytestream, "state-changed",
678                 G_CALLBACK (bytestream_state_changed_cb), self);
679           }
680         break;
681       case PROP_STREAM_ID:
682         g_free (priv->stream_id);
683         priv->stream_id = g_value_dup_string (value);
684         break;
685       case PROP_SERVICE:
686         g_free (priv->service);
687         priv->service = g_value_dup_string (value);
688         break;
689       case PROP_PARAMETERS:
690         if (priv->parameters != NULL)
691           g_hash_table_unref (priv->parameters);
692         priv->parameters = g_value_dup_boxed (value);
693         break;
694       case PROP_MUC:
695         priv->muc = g_value_get_object (value);
696         break;
697       default:
698         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
699         break;
700     }
701 }
702 
703 static void
gabble_tube_dbus_constructed(GObject * obj)704 gabble_tube_dbus_constructed (GObject *obj)
705 {
706   GabbleTubeDBus *self = GABBLE_TUBE_DBUS (obj);
707   GabbleTubeDBusPrivate *priv = self->priv;
708   TpBaseChannel *base = TP_BASE_CHANNEL (obj);
709   TpBaseChannelClass *cls = TP_BASE_CHANNEL_GET_CLASS (base);
710   TpBaseConnection *base_conn = tp_base_channel_get_connection (base);
711   GabbleConnection *conn = GABBLE_CONNECTION (base_conn);
712   TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (
713       base_conn, TP_HANDLE_TYPE_CONTACT);
714   guint access_control;
715 
716   void (*chain_up) (GObject *) =
717     ((GObjectClass *) gabble_tube_dbus_parent_class)->constructed;
718 
719   if (chain_up != NULL)
720     chain_up (obj);
721 
722   priv->dbus_names = g_hash_table_new_full (g_direct_hash, g_direct_equal,
723       NULL, g_free);
724 
725   g_assert (priv->self_handle != 0);
726   if (cls->target_handle_type == TP_HANDLE_TYPE_ROOM)
727     {
728       /* We have to create a pseudo-IBB bytestream that will be
729        * used by this MUC tube to communicate.
730        */
731       GabbleBytestreamMuc *bytestream;
732       gchar *nick;
733 
734       g_assert (priv->stream_id != NULL);
735 
736       priv->dbus_name_to_handle = g_hash_table_new_full (g_str_hash,
737          g_str_equal, NULL, NULL);
738 
739       g_assert (wocky_decode_jid (
740           tp_handle_inspect (contact_repo, priv->self_handle),
741           NULL, NULL, &nick));
742       g_assert (nick != NULL);
743 
744       priv->dbus_local_name = _gabble_generate_dbus_unique_name (nick);
745 
746       DEBUG ("local name: %s", priv->dbus_local_name);
747 
748       bytestream = gabble_bytestream_factory_create_muc (
749           conn->bytestream_factory,
750           tp_base_channel_get_target_handle (base),
751           priv->stream_id,
752           GABBLE_BYTESTREAM_STATE_LOCAL_PENDING);
753 
754       g_object_set (self, "bytestream", bytestream, NULL);
755 
756       g_free (nick);
757 
758       g_assert (priv->muc != NULL);
759       tp_external_group_mixin_init (obj, (GObject *) priv->muc);
760     }
761   else
762     {
763       /* The D-Bus names mapping is used in muc tubes only */
764       priv->dbus_local_name = NULL;
765       priv->dbus_name_to_handle = NULL;
766 
767       /* For contact (IBB) tubes we need to be able to reassemble messages. */
768       priv->reassembly_buffer = g_string_new ("");
769       priv->reassembly_bytes_needed = 0;
770 
771       g_assert (priv->muc == NULL);
772 
773       if (tp_base_channel_is_requested (base))
774         {
775           /* We created this outgoing 1-1 D-Bus tube and so will need SOCKS5
776            * proxies when we'll offer it. */
777           gabble_bytestream_factory_query_socks5_proxies (
778               conn->bytestream_factory);
779         }
780     }
781 
782   /* Tube needs to be offered if we initiated AND requested it. Being
783    * the initiator is not enough as we could re-join a muc containing and old
784    * tube we created when we were in this room some time ago. In that case, we
785    * have to accept it if we want to re-join the tube. */
786   if (tp_base_channel_get_initiator (base) == priv->self_handle &&
787       tp_base_channel_is_requested (base))
788     {
789       priv->offered = FALSE;
790     }
791   else
792     {
793       /* Incoming tubes have already been offered, as it were. */
794       priv->offered = TRUE;
795     }
796 
797   /* default access control is Credentials as that's the one used by the old
798    * tube API */
799   priv->access_control = TP_SOCKET_ACCESS_CONTROL_CREDENTIALS;
800 
801   /* Set SupportedAccessesControl */
802   priv->supported_access_controls = g_array_sized_new (FALSE, FALSE,
803       sizeof (guint), 1);
804   access_control = TP_SOCKET_ACCESS_CONTROL_CREDENTIALS;
805   g_array_append_val (priv->supported_access_controls, access_control);
806   access_control = TP_SOCKET_ACCESS_CONTROL_LOCALHOST;
807   g_array_append_val (priv->supported_access_controls, access_control);
808 }
809 
810 static void
gabble_tube_dbus_fill_immutable_properties(TpBaseChannel * chan,GHashTable * properties)811 gabble_tube_dbus_fill_immutable_properties (TpBaseChannel *chan,
812     GHashTable *properties)
813 {
814   TpBaseChannelClass *cls = TP_BASE_CHANNEL_CLASS (
815       gabble_tube_dbus_parent_class);
816 
817   cls->fill_immutable_properties (chan, properties);
818 
819   tp_dbus_properties_mixin_fill_properties_hash (
820       G_OBJECT (chan), properties,
821       TP_IFACE_CHANNEL_TYPE_DBUS_TUBE, "ServiceName",
822       TP_IFACE_CHANNEL_TYPE_DBUS_TUBE, "SupportedAccessControls",
823       NULL);
824 
825   if (!tp_base_channel_is_requested (chan))
826     {
827       tp_dbus_properties_mixin_fill_properties_hash (
828           G_OBJECT (chan), properties,
829           TP_IFACE_CHANNEL_INTERFACE_TUBE, "Parameters",
830           NULL);
831     }
832 }
833 
834 static gchar *
gabble_tube_dbus_get_object_path_suffix(TpBaseChannel * base)835 gabble_tube_dbus_get_object_path_suffix (TpBaseChannel *base)
836 {
837   GabbleTubeDBus *self = GABBLE_TUBE_DBUS (base);
838 
839   return g_strdup_printf ("DBusTubeChannel/%u/%" G_GUINT64_FORMAT,
840       tp_base_channel_get_target_handle (base),
841       self->priv->id);
842 }
843 
844 static void
gabble_tube_dbus_class_init(GabbleTubeDBusClass * gabble_tube_dbus_class)845 gabble_tube_dbus_class_init (GabbleTubeDBusClass *gabble_tube_dbus_class)
846 {
847   static TpDBusPropertiesMixinPropImpl dbus_tube_props[] = {
848       { "ServiceName", "service", NULL },
849       { "DBusNames", "dbus-names", NULL },
850       { "SupportedAccessControls", "supported-access-controls", NULL },
851       { NULL }
852   };
853   static TpDBusPropertiesMixinPropImpl tube_iface_props[] = {
854       { "Parameters", "parameters", NULL },
855       { "State", "state", NULL },
856       { NULL }
857   };
858   static TpDBusPropertiesMixinIfaceImpl prop_interfaces[] = {
859       { TP_IFACE_CHANNEL_TYPE_DBUS_TUBE,
860         tp_dbus_properties_mixin_getter_gobject_properties,
861         NULL,
862         dbus_tube_props,
863       },
864       { TP_IFACE_CHANNEL_INTERFACE_TUBE,
865         tp_dbus_properties_mixin_getter_gobject_properties,
866         NULL,
867         tube_iface_props,
868       },
869       { NULL }
870   };
871   GObjectClass *object_class = G_OBJECT_CLASS (gabble_tube_dbus_class);
872   TpBaseChannelClass *base_class = TP_BASE_CHANNEL_CLASS (gabble_tube_dbus_class);
873   GParamSpec *param_spec;
874 
875   object_class->get_property = gabble_tube_dbus_get_property;
876   object_class->set_property = gabble_tube_dbus_set_property;
877   object_class->constructed = gabble_tube_dbus_constructed;
878   object_class->dispose = gabble_tube_dbus_dispose;
879   object_class->finalize = gabble_tube_dbus_finalize;
880 
881   base_class->channel_type = TP_IFACE_CHANNEL_TYPE_DBUS_TUBE;
882   base_class->get_interfaces = gabble_tube_dbus_get_interfaces;
883   base_class->target_handle_type = TP_HANDLE_TYPE_CONTACT;
884   base_class->close = gabble_tube_dbus_close;
885   base_class->fill_immutable_properties =
886     gabble_tube_dbus_fill_immutable_properties;
887   base_class->get_object_path_suffix =
888     gabble_tube_dbus_get_object_path_suffix;
889 
890   g_type_class_add_private (gabble_tube_dbus_class,
891       sizeof (GabbleTubeDBusPrivate));
892 
893   g_object_class_override_property (object_class, PROP_SELF_HANDLE,
894     "self-handle");
895   g_object_class_override_property (object_class, PROP_ID,
896     "id");
897   g_object_class_override_property (object_class, PROP_TYPE,
898     "type");
899   g_object_class_override_property (object_class, PROP_SERVICE,
900     "service");
901   g_object_class_override_property (object_class, PROP_PARAMETERS,
902     "parameters");
903   g_object_class_override_property (object_class, PROP_STATE,
904     "state");
905 
906   param_spec = g_param_spec_object (
907       "bytestream",
908       "Object implementing the GabbleBytestreamIface interface",
909       "Bytestream object used for streaming data for this"
910       "tube object.",
911       G_TYPE_OBJECT,
912       G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
913   g_object_class_install_property (object_class, PROP_BYTESTREAM,
914       param_spec);
915 
916   param_spec = g_param_spec_string (
917       "stream-id",
918       "stream id",
919       "The identifier of this tube's bytestream",
920       "",
921       G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
922   g_object_class_install_property (object_class, PROP_STREAM_ID,
923       param_spec);
924 
925   param_spec = g_param_spec_string (
926       "dbus-address",
927       "D-Bus address",
928       "The D-Bus address on which this tube will listen for connections",
929       "",
930       G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
931   g_object_class_install_property (object_class, PROP_DBUS_ADDRESS,
932       param_spec);
933 
934   param_spec = g_param_spec_string (
935       "dbus-name",
936       "D-Bus name",
937       "The local D-Bus name on the virtual bus (used for muc tubes only).",
938       "",
939       G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
940   g_object_class_install_property (object_class, PROP_DBUS_NAME, param_spec);
941 
942   param_spec = g_param_spec_boxed (
943       "dbus-names",
944       "D-Bus names",
945       "Mapping of contact handles to D-Bus names (used for muc tubes only).",
946       TP_HASH_TYPE_DBUS_TUBE_PARTICIPANTS,
947       G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
948   g_object_class_install_property (object_class, PROP_DBUS_NAMES, param_spec);
949 
950   param_spec = g_param_spec_object ("muc", "GabbleMucChannel object",
951       "Gabble text MUC channel corresponding to this Tube channel object, "
952       "if the handle type is ROOM.",
953       GABBLE_TYPE_MUC_CHANNEL,
954       G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
955 
956   g_object_class_install_property (object_class, PROP_MUC, param_spec);
957 
958   param_spec = g_param_spec_boxed (
959       "supported-access-controls",
960       "Supported access-controls",
961       "GArray containing supported access controls.",
962       DBUS_TYPE_G_UINT_ARRAY,
963       G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
964   g_object_class_install_property (object_class,
965       PROP_SUPPORTED_ACCESS_CONTROLS, param_spec);
966 
967   signals[OPENED] =
968     g_signal_new ("tube-opened",
969                   G_OBJECT_CLASS_TYPE (gabble_tube_dbus_class),
970                   G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
971                   0,
972                   NULL, NULL,
973                   g_cclosure_marshal_VOID__VOID,
974                   G_TYPE_NONE, 0);
975 
976   signals[CLOSED] =
977     g_signal_new ("tube-closed",
978                   G_OBJECT_CLASS_TYPE (gabble_tube_dbus_class),
979                   G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
980                   0,
981                   NULL, NULL,
982                   g_cclosure_marshal_VOID__VOID,
983                   G_TYPE_NONE, 0);
984 
985   signals[OFFERED] =
986     g_signal_new ("tube-offered",
987                   G_OBJECT_CLASS_TYPE (gabble_tube_dbus_class),
988                   G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
989                   0,
990                   NULL, NULL,
991                   g_cclosure_marshal_VOID__VOID,
992                   G_TYPE_NONE, 0);
993 
994   gabble_tube_dbus_class->dbus_props_class.interfaces = prop_interfaces;
995   tp_dbus_properties_mixin_class_init (object_class,
996       G_STRUCT_OFFSET (GabbleTubeDBusClass, dbus_props_class));
997 
998   tp_external_group_mixin_init_dbus_properties (object_class);
999 }
1000 
1001 static void
bytestream_negotiate_cb(GabbleBytestreamIface * bytestream,WockyStanza * msg,GObject * object,gpointer user_data)1002 bytestream_negotiate_cb (GabbleBytestreamIface *bytestream,
1003                          WockyStanza *msg,
1004                          GObject *object,
1005                          gpointer user_data)
1006 {
1007   GabbleTubeIface *tube = user_data;
1008 
1009   if (bytestream == NULL)
1010     {
1011       /* Tube was declined by remote user. Close it */
1012       gabble_tube_iface_close (tube, TRUE);
1013       return;
1014     }
1015 
1016   /* Tube was accepted by remote user */
1017 
1018   g_object_set (tube,
1019       "bytestream", bytestream,
1020       NULL);
1021 
1022   gabble_tube_iface_accept (tube, NULL);
1023 }
1024 
1025 gboolean
gabble_tube_dbus_offer(GabbleTubeDBus * tube,GError ** error)1026 gabble_tube_dbus_offer (GabbleTubeDBus *tube,
1027                         GError **error)
1028 {
1029   GabbleTubeDBusPrivate *priv = tube->priv;
1030   TpBaseChannel *base = TP_BASE_CHANNEL (tube);
1031   TpBaseChannelClass *cls = TP_BASE_CHANNEL_GET_CLASS (base);
1032   TpBaseConnection *base_conn = tp_base_channel_get_connection (base);
1033   GabbleConnection *conn = GABBLE_CONNECTION (base_conn);
1034 
1035   if (priv->offered)
1036     {
1037       g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT,
1038           "Tube has already been offered");
1039       return FALSE;
1040     }
1041 
1042   if (cls->target_handle_type == TP_HANDLE_TYPE_CONTACT)
1043     {
1044       TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (
1045           base_conn, TP_HANDLE_TYPE_CONTACT);
1046       const gchar *jid, *resource;
1047       gchar *full_jid;
1048       GabblePresence *presence;
1049       WockyNode *tube_node, *si_node;
1050       WockyStanza *msg;
1051 
1052       jid = tp_handle_inspect (contact_repo,
1053           tp_base_channel_get_target_handle (base));
1054       presence = gabble_presence_cache_get (conn->presence_cache,
1055           tp_base_channel_get_target_handle (base));
1056 
1057       if (presence == NULL)
1058         {
1059           DEBUG ("can't find contact %s's presence", jid);
1060           g_set_error (error, TP_ERROR, TP_ERROR_NOT_AVAILABLE,
1061               "can't find contact %s's presence", jid);
1062           return FALSE;
1063         }
1064 
1065       resource = gabble_presence_pick_resource_by_caps (presence, 0,
1066           gabble_capability_set_predicate_has, NS_TUBES);
1067 
1068       if (resource == NULL)
1069         {
1070           DEBUG ("contact %s doesn't have tubes capabilities", jid);
1071           g_set_error (error, TP_ERROR, TP_ERROR_NOT_AVAILABLE,
1072               "contact %s doesn't have tubes capabilities", jid);
1073           return FALSE;
1074         }
1075 
1076       full_jid = g_strdup_printf ("%s/%s", jid, resource);
1077       msg = gabble_bytestream_factory_make_stream_init_iq (full_jid,
1078           priv->stream_id, NS_TUBES);
1079       si_node = wocky_node_get_child_ns (
1080           wocky_stanza_get_top_node (msg), "si", NS_SI);
1081       g_assert (si_node != NULL);
1082 
1083       tube_node = wocky_node_add_child_ns (si_node, "tube", NS_TUBES);
1084       gabble_tube_iface_publish_in_node (GABBLE_TUBE_IFACE (tube),
1085           base_conn, tube_node);
1086 
1087       tube->priv->offered = TRUE;
1088       gabble_bytestream_factory_negotiate_stream (
1089           conn->bytestream_factory, msg, priv->stream_id,
1090           bytestream_negotiate_cb, tube, G_OBJECT (tube));
1091 
1092       /* We don't create the bytestream of private D-Bus tube yet.
1093        * It will be when we'll receive the answer of the SI request */
1094       g_object_unref (msg);
1095       g_free (full_jid);
1096 
1097       tp_svc_channel_interface_tube_emit_tube_channel_state_changed (tube,
1098           TP_TUBE_CHANNEL_STATE_REMOTE_PENDING);
1099     }
1100   else
1101     {
1102       tube->priv->offered = TRUE;
1103       g_object_set (priv->bytestream,
1104           "state", GABBLE_BYTESTREAM_STATE_OPEN,
1105           NULL);
1106 
1107       gabble_muc_channel_send_presence (priv->muc);
1108     }
1109 
1110   if (!create_dbus_server (tube, error))
1111     return FALSE;
1112 
1113   g_signal_emit (G_OBJECT (tube), signals[OFFERED], 0);
1114 
1115   return TRUE;
1116 }
1117 
1118 static void
message_received(GabbleTubeDBus * tube,TpHandle sender,const char * data,size_t len)1119 message_received (GabbleTubeDBus *tube,
1120                   TpHandle sender,
1121                   const char *data,
1122                   size_t len)
1123 {
1124   GabbleTubeDBusPrivate *priv = GABBLE_TUBE_DBUS_GET_PRIVATE (tube);
1125   TpBaseChannel *base = TP_BASE_CHANNEL (tube);
1126   TpBaseChannelClass *cls = TP_BASE_CHANNEL_GET_CLASS (base);
1127   DBusMessage *msg;
1128   DBusError error = {0,};
1129   const gchar *sender_name;
1130   const gchar *destination;
1131   guint32 serial;
1132 
1133   msg = dbus_message_demarshal (data, len, &error);
1134 
1135   if (msg == NULL)
1136     {
1137       /* message was corrupted */
1138       DEBUG ("received corrupted message from %d: %s: %s", sender,
1139           error.name, error.message);
1140       dbus_error_free (&error);
1141       return;
1142     }
1143 
1144   if (cls->target_handle_type == TP_HANDLE_TYPE_ROOM)
1145     {
1146       destination = dbus_message_get_destination (msg);
1147       /* If destination is NULL this msg is broadcasted (signals) so we don't
1148        * have to check it */
1149       if (destination != NULL && tp_strdiff (priv->dbus_local_name,
1150             destination))
1151         {
1152           /* This message is not intended for this participant.
1153            * Discard it. */
1154           DEBUG ("message not intended for this participant (destination = "
1155               "%s)", destination);
1156           goto unref;
1157         }
1158 
1159       sender_name = g_hash_table_lookup (priv->dbus_names,
1160           GUINT_TO_POINTER (sender));
1161 
1162       if (tp_strdiff (sender_name, dbus_message_get_sender (msg)))
1163         {
1164           DEBUG ("invalid sender %s (expected %s for sender handle %d)",
1165                  dbus_message_get_sender (msg), sender_name, sender);
1166           goto unref;
1167         }
1168     }
1169 
1170   if (!priv->dbus_conn)
1171     {
1172       DEBUG ("no D-Bus connection: queuing the message");
1173 
1174       /* If the application never connects to the private dbus connection, we
1175        * don't want to eat all the memory. Only queue MAX_QUEUE_SIZE bytes. If
1176        * there are more messages, drop them. */
1177       if (priv->dbus_msg_queue_size + len > MAX_QUEUE_SIZE)
1178         {
1179           DEBUG ("D-Bus message queue size limit reached (%u bytes). "
1180                  "Ignore this message.",
1181                  MAX_QUEUE_SIZE);
1182           goto unref;
1183         }
1184 
1185       priv->dbus_msg_queue = g_slist_prepend (priv->dbus_msg_queue, msg);
1186       priv->dbus_msg_queue_size += len;
1187 
1188       /* returns without unref the message */
1189       return;
1190     }
1191 
1192   DEBUG ("delivering message from '%s' to '%s'",
1193          dbus_message_get_sender (msg),
1194          dbus_message_get_destination (msg));
1195 
1196   /* XXX: what do do if this returns FALSE? */
1197   dbus_connection_send (priv->dbus_conn, msg, &serial);
1198 
1199 unref:
1200   dbus_message_unref (msg);
1201 }
1202 
1203 static guint32
collect_le32(char * str)1204 collect_le32 (char *str)
1205 {
1206   unsigned char *bytes = (unsigned char *) str;
1207 
1208   return bytes[0] | (bytes[1] << 8) | (bytes[2] << 16) | (bytes[3] << 24);
1209 }
1210 
1211 static guint32
collect_be32(char * str)1212 collect_be32 (char *str)
1213 {
1214   unsigned char *bytes = (unsigned char *) str;
1215 
1216   return (bytes[0] << 24) | (bytes[1] << 16) | (bytes[2] << 24) | bytes[3];
1217 }
1218 
1219 static void
data_received_cb(GabbleBytestreamIface * stream,TpHandle sender,GString * data,gpointer user_data)1220 data_received_cb (GabbleBytestreamIface *stream,
1221                   TpHandle sender,
1222                   GString *data,
1223                   gpointer user_data)
1224 {
1225   GabbleTubeDBus *tube = GABBLE_TUBE_DBUS (user_data);
1226   GabbleTubeDBusPrivate *priv = GABBLE_TUBE_DBUS_GET_PRIVATE (tube);
1227   TpBaseChannel *base = TP_BASE_CHANNEL (tube);
1228   TpBaseChannelClass *cls = TP_BASE_CHANNEL_GET_CLASS (base);
1229 
1230   if (cls->target_handle_type == TP_HANDLE_TYPE_CONTACT)
1231     {
1232       GString *buf = priv->reassembly_buffer;
1233 
1234       g_assert (buf != NULL);
1235 
1236       g_string_append_len (buf, data->str, data->len);
1237       DEBUG ("Received %" G_GSIZE_FORMAT " bytes, so we now have %"
1238           G_GSIZE_FORMAT " bytes in reassembly buffer", data->len, buf->len);
1239 
1240       /* Each D-Bus message has a 16-byte fixed header, in which
1241        *
1242        * * byte 0 is 'l' (ell) or 'B' for endianness
1243        * * bytes 4-7 are body length "n" in bytes in that endianness
1244        * * bytes 12-15 are length "m" of param array in bytes in that
1245        *   endianness
1246        *
1247        * followed by m + n + ((8 - (m % 8)) % 8) bytes of other content.
1248        */
1249 
1250       while (buf->len >= 16)
1251         {
1252           guint32 body_length, params_length, m;
1253 
1254           /* see if we have a whole message and have already calculated
1255            * how many bytes it needs */
1256 
1257           if (priv->reassembly_bytes_needed != 0)
1258             {
1259               if (buf->len >= priv->reassembly_bytes_needed)
1260                 {
1261                   DEBUG ("Received complete D-Bus message of size %"
1262                       G_GINT32_FORMAT, priv->reassembly_bytes_needed);
1263                   message_received (tube, sender, buf->str,
1264                       priv->reassembly_bytes_needed);
1265                   g_string_erase (buf, 0, priv->reassembly_bytes_needed);
1266                   priv->reassembly_bytes_needed = 0;
1267                 }
1268               else
1269                 {
1270                   /* we'll have to wait for more data */
1271                   break;
1272                 }
1273             }
1274 
1275           if (buf->len < 16)
1276             break;
1277 
1278           /* work out how big the next message is going to be */
1279 
1280           if (buf->str[0] == DBUS_BIG_ENDIAN)
1281             {
1282               body_length = collect_be32 (buf->str + 4);
1283               m = collect_be32 (buf->str + 12);
1284             }
1285           else if (buf->str[0] == DBUS_LITTLE_ENDIAN)
1286             {
1287               body_length = collect_le32 (buf->str + 4);
1288               m = collect_le32 (buf->str + 12);
1289             }
1290           else
1291             {
1292               DEBUG ("D-Bus message has unknown endianness byte 0x%x, "
1293                   "closing tube", (unsigned int) buf->str[0]);
1294               gabble_tube_iface_close ((GabbleTubeIface *) tube, TRUE);
1295               return;
1296             }
1297 
1298           /* pad to 8-byte boundary */
1299           params_length = m + ((8 - (m % 8)) % 8);
1300           g_assert (params_length % 8 == 0);
1301           g_assert (params_length >= m);
1302           g_assert (params_length < m + 8);
1303 
1304           priv->reassembly_bytes_needed = params_length + body_length + 16;
1305 
1306           /* n.b.: this looks as if it could be simplified to just the third
1307            * test, but that would be wrong if the addition had overflowed, so
1308            * don't do that. The first and second tests are sufficient to
1309            * ensure no overflow on 32-bit platforms */
1310           if (body_length > DBUS_MAXIMUM_MESSAGE_LENGTH ||
1311               params_length > DBUS_MAXIMUM_ARRAY_LENGTH ||
1312               priv->reassembly_bytes_needed > DBUS_MAXIMUM_MESSAGE_LENGTH)
1313             {
1314               DEBUG ("D-Bus message is too large to be valid, closing tube");
1315               gabble_tube_iface_close ((GabbleTubeIface *) tube, TRUE);
1316               return;
1317             }
1318 
1319           g_assert (priv->reassembly_bytes_needed != 0);
1320           DEBUG ("We need %" G_GINT32_FORMAT " bytes for the next full "
1321               "message", priv->reassembly_bytes_needed);
1322         }
1323     }
1324   else
1325     {
1326       /* MUC bytestreams are message-boundary preserving, which is necessary,
1327        * because we can't assume we started at the beginning */
1328       g_assert (GABBLE_IS_BYTESTREAM_MUC (priv->bytestream));
1329       message_received (tube, sender, data->str, data->len);
1330     }
1331 }
1332 
1333 GabbleTubeDBus *
gabble_tube_dbus_new(GabbleConnection * conn,TpHandle handle,TpHandleType handle_type,TpHandle self_handle,TpHandle initiator,const gchar * service,GHashTable * parameters,const gchar * stream_id,guint64 id,GabbleBytestreamIface * bytestream,GabbleMucChannel * muc,gboolean requested)1334 gabble_tube_dbus_new (GabbleConnection *conn,
1335                       TpHandle handle,
1336                       TpHandleType handle_type,
1337                       TpHandle self_handle,
1338                       TpHandle initiator,
1339                       const gchar *service,
1340                       GHashTable *parameters,
1341                       const gchar *stream_id,
1342                       guint64 id,
1343                       GabbleBytestreamIface *bytestream,
1344                       GabbleMucChannel *muc,
1345                       gboolean requested)
1346 {
1347   GabbleTubeDBus *tube;
1348   GType gtype = GABBLE_TYPE_TUBE_DBUS;
1349 
1350   if (handle_type == TP_HANDLE_TYPE_ROOM)
1351     gtype = GABBLE_TYPE_MUC_TUBE_DBUS;
1352 
1353   tube = g_object_new (gtype,
1354       "connection", conn,
1355       "handle", handle,
1356       "self-handle", self_handle,
1357       "initiator-handle", initiator,
1358       "service", service,
1359       "parameters", parameters,
1360       "stream-id", stream_id,
1361       "id", id,
1362       "muc", muc,
1363       "requested", requested,
1364       NULL);
1365 
1366   if (bytestream != NULL)
1367     g_object_set (tube, "bytestream", bytestream, NULL);
1368 
1369   return tube;
1370 }
1371 
1372 static void
augment_si_accept_iq(WockyNode * si,gpointer user_data)1373 augment_si_accept_iq (WockyNode *si,
1374                       gpointer user_data)
1375 {
1376   wocky_node_add_child_ns (si, "tube", NS_TUBES);
1377 }
1378 
1379 /*
1380  * gabble_tube_dbus_accept
1381  *
1382  * Implements gabble_tube_iface_accept on GabbleTubeIface
1383  */
1384 static gboolean
gabble_tube_dbus_accept(GabbleTubeIface * tube,GError ** error)1385 gabble_tube_dbus_accept (GabbleTubeIface *tube,
1386                          GError **error)
1387 {
1388   GabbleTubeDBus *self = GABBLE_TUBE_DBUS (tube);
1389   GabbleTubeDBusPrivate *priv = GABBLE_TUBE_DBUS_GET_PRIVATE (self);
1390   TpBaseChannel *base = TP_BASE_CHANNEL (tube);
1391   TpBaseChannelClass *cls = TP_BASE_CHANNEL_GET_CLASS (base);
1392   GabbleBytestreamState state;
1393 
1394   g_assert (priv->bytestream != NULL);
1395 
1396   g_object_get (priv->bytestream,
1397       "state", &state,
1398       NULL);
1399 
1400   if (state != GABBLE_BYTESTREAM_STATE_LOCAL_PENDING)
1401     return TRUE;
1402 
1403   if (cls->target_handle_type == TP_HANDLE_TYPE_CONTACT)
1404     {
1405       /* Bytestream was created using a SI request so
1406        * we have to accept it */
1407 
1408       DEBUG ("accept the SI request");
1409 
1410       gabble_bytestream_iface_accept (priv->bytestream, augment_si_accept_iq,
1411           self);
1412     }
1413   else
1414     {
1415       /* No SI so the bytestream is open */
1416       DEBUG ("no SI, bytestream open");
1417       g_object_set (priv->bytestream,
1418           "state", GABBLE_BYTESTREAM_STATE_OPEN,
1419           NULL);
1420     }
1421 
1422   if (!create_dbus_server (self, error))
1423     return FALSE;
1424 
1425   return TRUE;
1426 }
1427 
1428 /*
1429  * gabble_tube_iface_dbus_close
1430  *
1431  * Implements gabble_tube_iface_close on GabbleTubeIface
1432  */
1433 static void
gabble_tube_iface_dbus_close(GabbleTubeIface * tube,gboolean closed_remotely)1434 gabble_tube_iface_dbus_close (GabbleTubeIface *tube,
1435     gboolean closed_remotely)
1436 {
1437   tp_base_channel_close (TP_BASE_CHANNEL (tube));
1438 }
1439 
1440 /**
1441  * gabble_tube_dbus_add_bytestream
1442  *
1443  * Implements gabble_tube_iface_add_bytestream on GabbleTubeIface
1444  */
1445 static void
gabble_tube_dbus_add_bytestream(GabbleTubeIface * tube,GabbleBytestreamIface * bytestream)1446 gabble_tube_dbus_add_bytestream (GabbleTubeIface *tube,
1447                                  GabbleBytestreamIface *bytestream)
1448 {
1449   /* FIXME: should we support this, if we don't have a bytestream yet? */
1450   DEBUG ("D-Bus doesn't support extra bytestream");
1451   gabble_bytestream_iface_close (bytestream, NULL);
1452 }
1453 
1454 gboolean
gabble_tube_dbus_add_name(GabbleTubeDBus * self,TpHandle handle,const gchar * name)1455 gabble_tube_dbus_add_name (GabbleTubeDBus *self,
1456                            TpHandle handle,
1457                            const gchar *name)
1458 {
1459   GabbleTubeDBusPrivate *priv = GABBLE_TUBE_DBUS_GET_PRIVATE (self);
1460   TpBaseChannel *base = TP_BASE_CHANNEL (self);
1461   TpBaseChannelClass *cls = TP_BASE_CHANNEL_GET_CLASS (base);
1462   TpBaseConnection *base_conn = tp_base_channel_get_connection (base);
1463   TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (
1464       base_conn, TP_HANDLE_TYPE_CONTACT);
1465   gchar *name_copy;
1466   GHashTable *added;
1467   GArray *removed;
1468 
1469   g_assert (cls->target_handle_type == TP_HANDLE_TYPE_ROOM);
1470   g_assert (g_hash_table_size (priv->dbus_names) ==
1471       g_hash_table_size (priv->dbus_name_to_handle));
1472 
1473   if (g_hash_table_lookup (priv->dbus_names, GUINT_TO_POINTER (handle))
1474       != NULL)
1475     {
1476       DEBUG ("contact %d has already announced his D-Bus name", handle);
1477       return FALSE;
1478     }
1479 
1480   if (g_hash_table_lookup (priv->dbus_name_to_handle, name) != NULL)
1481     {
1482       DEBUG ("D-Bus name %s already used", name);
1483       return FALSE;
1484     }
1485 
1486   if (g_str_has_prefix (name, ":2."))
1487     {
1488       gchar *nick, *supposed_name;
1489       const gchar *jid;
1490 
1491       jid = tp_handle_inspect (contact_repo, handle);
1492       g_assert (wocky_decode_jid (jid, NULL, NULL, &nick));
1493       supposed_name = _gabble_generate_dbus_unique_name (nick);
1494       g_free (nick);
1495 
1496       if (tp_strdiff (name, supposed_name))
1497         {
1498           DEBUG ("contact %s announces %s as D-Bus name but it should be %s",
1499               jid, name, supposed_name);
1500           g_free (supposed_name);
1501           return FALSE;
1502         }
1503       g_free (supposed_name);
1504     }
1505 
1506   name_copy = g_strdup (name);
1507   g_hash_table_insert (priv->dbus_names, GUINT_TO_POINTER (handle),
1508       name_copy);
1509 
1510   g_hash_table_insert (priv->dbus_name_to_handle, name_copy,
1511       GUINT_TO_POINTER (handle));
1512 
1513   /* Fire DBusNamesChanged (new API) */
1514   added = g_hash_table_new (g_direct_hash, g_direct_equal);
1515   removed = g_array_new (FALSE, FALSE, sizeof (TpHandle));
1516 
1517   g_hash_table_insert (added, GUINT_TO_POINTER (handle), (gchar *) name);
1518 
1519   tp_svc_channel_type_dbus_tube_emit_dbus_names_changed (self, added,
1520       removed);
1521 
1522   g_hash_table_unref (added);
1523   g_array_unref (removed);
1524 
1525   return TRUE;
1526 }
1527 
1528 gboolean
gabble_tube_dbus_remove_name(GabbleTubeDBus * self,TpHandle handle)1529 gabble_tube_dbus_remove_name (GabbleTubeDBus *self,
1530                               TpHandle handle)
1531 {
1532   GabbleTubeDBusPrivate *priv = GABBLE_TUBE_DBUS_GET_PRIVATE (self);
1533   TpBaseChannel *base = TP_BASE_CHANNEL (self);
1534   TpBaseChannelClass *cls = TP_BASE_CHANNEL_GET_CLASS (base);
1535   const gchar *name;
1536   GHashTable *added;
1537   GArray *removed;
1538 
1539   g_assert (cls->target_handle_type == TP_HANDLE_TYPE_ROOM);
1540 
1541   name = g_hash_table_lookup (priv->dbus_names, GUINT_TO_POINTER (handle));
1542   if (name == NULL)
1543     return FALSE;
1544 
1545   g_hash_table_remove (priv->dbus_name_to_handle, name);
1546   g_hash_table_remove (priv->dbus_names, GUINT_TO_POINTER (handle));
1547 
1548   g_assert (g_hash_table_size (priv->dbus_names) ==
1549       g_hash_table_size (priv->dbus_name_to_handle));
1550 
1551   /* Fire DBusNamesChanged (new API) */
1552   added = g_hash_table_new (g_direct_hash, g_direct_equal);
1553   removed = g_array_new (FALSE, FALSE, sizeof (TpHandle));
1554 
1555   g_array_append_val (removed, handle);
1556 
1557   tp_svc_channel_type_dbus_tube_emit_dbus_names_changed (self, added,
1558       removed);
1559 
1560   g_hash_table_unref (added);
1561   g_array_unref (removed);
1562   return TRUE;
1563 }
1564 
1565 gboolean
gabble_tube_dbus_handle_in_names(GabbleTubeDBus * self,TpHandle handle)1566 gabble_tube_dbus_handle_in_names (GabbleTubeDBus *self,
1567                                   TpHandle handle)
1568 {
1569   GabbleTubeDBusPrivate *priv = GABBLE_TUBE_DBUS_GET_PRIVATE (self);
1570   TpBaseChannelClass *cls = TP_BASE_CHANNEL_GET_CLASS (self);
1571 
1572   g_assert (cls->target_handle_type == TP_HANDLE_TYPE_ROOM);
1573 
1574   return (g_hash_table_lookup (priv->dbus_names, GUINT_TO_POINTER (handle))
1575       != NULL);
1576 }
1577 
1578 gchar *
_gabble_generate_dbus_unique_name(const gchar * nick)1579 _gabble_generate_dbus_unique_name (const gchar *nick)
1580 {
1581   gchar *encoded, *result;
1582   size_t len;
1583   guint i;
1584 
1585   len = strlen (nick);
1586 
1587   if (len <= 186)
1588     {
1589       encoded = g_base64_encode ((const guchar *) nick, len);
1590     }
1591   else
1592     {
1593       guchar sha1[20];
1594       GString *tmp;
1595 
1596       sha1_bin (nick, len, sha1);
1597       tmp = g_string_sized_new (169 + 20);
1598 
1599       g_string_append_len (tmp, nick, 169);
1600       g_string_append_len (tmp, (const gchar *) sha1, 20);
1601 
1602       encoded = g_base64_encode ((const guchar *) tmp->str, tmp->len);
1603 
1604       g_string_free (tmp, TRUE);
1605     }
1606 
1607   for (i = 0; encoded[i] != '\0'; i++)
1608     {
1609       switch (encoded[i])
1610         {
1611           case '+':
1612             encoded[i] = '_';
1613             break;
1614           case '/':
1615             encoded[i] = '-';
1616             break;
1617           case '=':
1618             encoded[i] = 'A';
1619             break;
1620         }
1621     }
1622 
1623   result = g_strdup_printf (":2.%s", encoded);
1624 
1625   g_free (encoded);
1626   return result;
1627 }
1628 
1629 const gchar * const *
gabble_tube_dbus_channel_get_allowed_properties(void)1630 gabble_tube_dbus_channel_get_allowed_properties (void)
1631 {
1632   return gabble_tube_dbus_channel_allowed_properties;
1633 }
1634 
1635 static gboolean
gabble_tube_dbus_check_access_control(GabbleTubeDBus * self,guint access_control,GError ** error)1636 gabble_tube_dbus_check_access_control (GabbleTubeDBus *self,
1637     guint access_control,
1638     GError **error)
1639 {
1640   switch (access_control)
1641     {
1642       case TP_SOCKET_ACCESS_CONTROL_CREDENTIALS:
1643       case TP_SOCKET_ACCESS_CONTROL_LOCALHOST:
1644         break;
1645 
1646       default:
1647         g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT,
1648             "%u socket access control is not supported", access_control);
1649         return FALSE;
1650     }
1651 
1652   return TRUE;
1653 }
1654 
1655 /**
1656  * gabble_tube_dbus_offer_async
1657  *
1658  * Implemnets D-Bus method Offer on interface
1659  * org.freedesktop.Telepathy.Channel.Type.DBusTube
1660  */
1661 static void
gabble_tube_dbus_offer_async(TpSvcChannelTypeDBusTube * self,GHashTable * parameters,guint access_control,DBusGMethodInvocation * context)1662 gabble_tube_dbus_offer_async (TpSvcChannelTypeDBusTube *self,
1663     GHashTable *parameters,
1664     guint access_control,
1665     DBusGMethodInvocation *context)
1666 {
1667   GabbleTubeDBus *tube = GABBLE_TUBE_DBUS (self);
1668   GabbleTubeDBusPrivate *priv = GABBLE_TUBE_DBUS_GET_PRIVATE (tube);
1669   GError *error = NULL;
1670 
1671   if (!gabble_tube_dbus_check_access_control (tube, access_control, &error))
1672     {
1673       dbus_g_method_return_error (context, error);
1674       g_error_free (error);
1675       return;
1676     }
1677 
1678   priv->access_control = access_control;
1679 
1680   g_object_set (self, "parameters", parameters, NULL);
1681 
1682   if (gabble_tube_dbus_offer (tube, &error))
1683     {
1684       tp_svc_channel_type_dbus_tube_return_from_offer (context,
1685           tube->priv->dbus_srv_addr);
1686     }
1687   else
1688     {
1689       g_assert (error != NULL);
1690       dbus_g_method_return_error (context, error);
1691       g_error_free (error);
1692     }
1693 }
1694 
1695 /**
1696  * gabble_tube_dbus_accept_async
1697  *
1698  * Implements D-Bus method Accept on interface
1699  * org.freedesktop.Telepathy.Channel.Type.DBusTube
1700  */
1701 static void
gabble_tube_dbus_accept_async(TpSvcChannelTypeDBusTube * self,guint access_control,DBusGMethodInvocation * context)1702 gabble_tube_dbus_accept_async (TpSvcChannelTypeDBusTube *self,
1703     guint access_control,
1704     DBusGMethodInvocation *context)
1705 {
1706   GabbleTubeDBus *tube = GABBLE_TUBE_DBUS (self);
1707   GError *error = NULL;
1708 
1709   if (!gabble_tube_dbus_check_access_control (tube, access_control, &error))
1710     {
1711       dbus_g_method_return_error (context, error);
1712       g_error_free (error);
1713       return;
1714     }
1715 
1716   if (gabble_tube_dbus_accept (GABBLE_TUBE_IFACE (tube), &error))
1717     {
1718       tp_svc_channel_type_dbus_tube_return_from_accept (context,
1719           tube->priv->dbus_srv_addr);
1720       ;
1721     }
1722   else
1723     {
1724       g_assert (error != NULL);
1725       dbus_g_method_return_error (context, error);
1726       g_error_free (error);
1727     }
1728 }
1729 
1730 static void
tube_iface_init(gpointer g_iface,gpointer iface_data)1731 tube_iface_init (gpointer g_iface,
1732                  gpointer iface_data)
1733 {
1734   GabbleTubeIfaceClass *klass = (GabbleTubeIfaceClass *) g_iface;
1735 
1736   klass->accept = gabble_tube_dbus_accept;
1737   klass->close = gabble_tube_iface_dbus_close;
1738   klass->add_bytestream = gabble_tube_dbus_add_bytestream;
1739 }
1740 
1741 static void
dbustube_iface_init(gpointer g_iface,gpointer iface_data)1742 dbustube_iface_init (gpointer g_iface,
1743                      gpointer iface_data)
1744 {
1745   TpSvcChannelTypeDBusTubeClass *klass =
1746       (TpSvcChannelTypeDBusTubeClass *) g_iface;
1747 
1748 #define IMPLEMENT(x, suffix) tp_svc_channel_type_dbus_tube_implement_##x (\
1749     klass, gabble_tube_dbus_##x##suffix)
1750   IMPLEMENT(offer,_async);
1751   IMPLEMENT(accept,_async);
1752 #undef IMPLEMENT
1753 }
1754