Add a regression test for invalid BecomeMonitor calls
[platform/upstream/dbus.git] / test / monitor.c
1 /* Integration tests for monitor-mode D-Bus connections
2  *
3  * Copyright © 2010-2011 Nokia Corporation
4  * Copyright © 2015 Collabora Ltd.
5  *
6  * Permission is hereby granted, free of charge, to any person
7  * obtaining a copy of this software and associated documentation files
8  * (the "Software"), to deal in the Software without restriction,
9  * including without limitation the rights to use, copy, modify, merge,
10  * publish, distribute, sublicense, and/or sell copies of the Software,
11  * and to permit persons to whom the Software is furnished to do so,
12  * subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be
15  * included in all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
21  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
22  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24  * SOFTWARE.
25  */
26
27 #include <config.h>
28
29 #include <string.h>
30
31 #include "test-utils-glib.h"
32
33 typedef struct {
34     const char *config_file;
35     const char * const *match_rules;
36     gboolean care_about_our_names;
37 } Config;
38
39 typedef struct {
40     const Config *config;
41     TestMainContext *ctx;
42     DBusError e;
43     GError *ge;
44
45     gchar *address;
46     GPid daemon_pid;
47
48     DBusConnection *monitor;
49     DBusConnection *sender;
50     DBusConnection *recipient;
51
52     GQueue monitored;
53
54     const char *monitor_name;
55     const char *sender_name;
56     const char *recipient_name;
57
58     DBusConnection *systemd;
59     const char *systemd_name;
60     DBusMessage *systemd_message;
61     DBusConnection *activated;
62     const char *activated_name;
63     DBusMessage *activated_message;
64 } Fixture;
65
66 static const char * const no_match_rules[] = {
67     NULL
68 };
69
70 static const char * const wildcard_match_rules[] = {
71     "",
72     NULL,
73     FALSE
74 };
75
76 static const char * const eavesdrop_match_rules[] = {
77     "eavesdrop=true",
78     NULL,
79     FALSE
80 };
81
82 static const char * const no_eavesdrop_match_rules[] = {
83     "eavesdrop=false",
84     NULL,
85     FALSE
86 };
87
88 static const char * const selective_match_rules[] = {
89     "interface='com.example.Interesting'",
90     "interface='com.example.Fun'",
91     NULL,
92     FALSE
93 };
94
95 static Config forbidding_config = {
96     "valid-config-files/forbidding.conf",
97     NULL,
98     FALSE
99 };
100
101 static Config wildcard_config = {
102     NULL,
103     wildcard_match_rules,
104     FALSE
105 };
106
107 static Config selective_config = {
108     NULL,
109     selective_match_rules,
110     FALSE
111 };
112
113 static Config no_rules_config = {
114     NULL,
115     no_match_rules,
116     FALSE
117 };
118
119 static Config eavesdrop_config = {
120     NULL,
121     eavesdrop_match_rules,
122     FALSE
123 };
124
125 static Config no_eavesdrop_config = {
126     NULL,
127     no_eavesdrop_match_rules,
128     FALSE
129 };
130
131 #ifdef DBUS_UNIX
132 static Config fake_systemd_config = {
133     "valid-config-files/systemd-activation.conf",
134     NULL,
135     FALSE
136 };
137 #endif
138
139 static Config side_effects_config = {
140     NULL,
141     NULL,
142     TRUE
143 };
144
145 static inline const char *
146 not_null2 (const char *x,
147     const char *fallback)
148 {
149   if (x == NULL)
150     return fallback;
151
152   return x;
153 }
154
155 static inline const char *
156 not_null (const char *x)
157 {
158   return not_null2 (x, "(null)");
159 }
160
161 #define log_message(m) _log_message (m, __FILE__, __LINE__)
162
163 G_GNUC_UNUSED
164 static void
165 _log_message (DBusMessage *m,
166     const char *file,
167     int line)
168 {
169   g_test_message ("%s:%d: message type %d (%s)", file, line,
170       dbus_message_get_type (m),
171       dbus_message_type_to_string (dbus_message_get_type (m)));
172   g_test_message ("\tfrom: %s",
173       not_null2 (dbus_message_get_sender (m), "(dbus-daemon)"));
174   g_test_message ("\tto: %s",
175       not_null2 (dbus_message_get_destination (m), "(broadcast)"));
176   g_test_message ("\tpath: %s",
177       not_null (dbus_message_get_path (m)));
178   g_test_message ("\tinterface: %s",
179       not_null (dbus_message_get_interface (m)));
180   g_test_message ("\tmember: %s",
181       not_null (dbus_message_get_member (m)));
182   g_test_message ("\tsignature: %s",
183       not_null (dbus_message_get_signature (m)));
184   g_test_message ("\terror name: %s",
185       not_null (dbus_message_get_error_name (m)));
186
187   if (strcmp ("s", dbus_message_get_signature (m)) == 0)
188     {
189       DBusError e = DBUS_ERROR_INIT;
190       const char *s;
191
192       dbus_message_get_args (m, &e,
193             DBUS_TYPE_STRING, &s,
194             DBUS_TYPE_INVALID);
195       test_assert_no_error (&e);
196       g_test_message ("\tstring payload: %s", s);
197     }
198 }
199
200 /* these are macros so they get the right line number */
201
202 #define assert_hello(m) \
203 do { \
204   g_assert_cmpstr (dbus_message_type_to_string (dbus_message_get_type (m)), \
205       ==, dbus_message_type_to_string (DBUS_MESSAGE_TYPE_METHOD_CALL)); \
206   g_assert_cmpstr (dbus_message_get_destination (m), ==, DBUS_SERVICE_DBUS); \
207   g_assert_cmpstr (dbus_message_get_path (m), ==, DBUS_PATH_DBUS); \
208   g_assert_cmpstr (dbus_message_get_interface (m), ==, DBUS_INTERFACE_DBUS); \
209   g_assert_cmpstr (dbus_message_get_member (m), ==, "Hello"); \
210   g_assert_cmpstr (dbus_message_get_signature (m), ==, ""); \
211   g_assert_cmpint (dbus_message_get_serial (m), !=, 0); \
212   g_assert_cmpint (dbus_message_get_reply_serial (m), ==, 0); \
213 } while (0)
214
215 #define assert_hello_reply(m) \
216 do { \
217   DBusError _e = DBUS_ERROR_INIT; \
218   const char *_s; \
219     \
220   g_assert_cmpstr (dbus_message_type_to_string (dbus_message_get_type (m)), \
221       ==, dbus_message_type_to_string (DBUS_MESSAGE_TYPE_METHOD_RETURN)); \
222   g_assert_cmpstr (dbus_message_get_sender (m), ==, DBUS_SERVICE_DBUS); \
223   g_assert_cmpstr (dbus_message_get_path (m), ==, NULL); \
224   g_assert_cmpstr (dbus_message_get_interface (m), ==, NULL); \
225   g_assert_cmpstr (dbus_message_get_member (m), ==, NULL); \
226   g_assert_cmpstr (dbus_message_get_signature (m), ==, "s"); \
227   g_assert_cmpint (dbus_message_get_serial (m), !=, 0); \
228   g_assert_cmpint (dbus_message_get_reply_serial (m), !=, 0); \
229     \
230   dbus_message_get_args (m, &_e, \
231         DBUS_TYPE_STRING, &_s, \
232         DBUS_TYPE_INVALID); \
233   test_assert_no_error (&_e); \
234   g_assert_cmpstr (dbus_message_get_destination (m), ==, _s); \
235 } while (0)
236
237 #define assert_name_acquired(m) \
238 do { \
239   DBusError _e = DBUS_ERROR_INIT; \
240   const char *_s; \
241     \
242   g_assert_cmpstr (dbus_message_type_to_string (dbus_message_get_type (m)), \
243       ==, dbus_message_type_to_string (DBUS_MESSAGE_TYPE_SIGNAL)); \
244   g_assert_cmpstr (dbus_message_get_sender (m), ==, DBUS_SERVICE_DBUS); \
245   g_assert_cmpstr (dbus_message_get_path (m), ==, DBUS_PATH_DBUS); \
246   g_assert_cmpstr (dbus_message_get_interface (m), ==, DBUS_INTERFACE_DBUS); \
247   g_assert_cmpstr (dbus_message_get_member (m), ==, "NameAcquired"); \
248   g_assert_cmpstr (dbus_message_get_signature (m), ==, "s"); \
249   g_assert_cmpint (dbus_message_get_serial (m), !=, 0); \
250   g_assert_cmpint (dbus_message_get_reply_serial (m), ==, 0); \
251     \
252   dbus_message_get_args (m, &_e, \
253         DBUS_TYPE_STRING, &_s, \
254         DBUS_TYPE_INVALID); \
255   test_assert_no_error (&_e); \
256   g_assert_cmpstr (dbus_message_get_destination (m), ==, _s); \
257 } while (0)
258
259 #define assert_method_call(m, sender, \
260     destination, path, iface, method, signature) \
261 do { \
262   g_assert_cmpstr (dbus_message_type_to_string (dbus_message_get_type (m)), \
263       ==, dbus_message_type_to_string (DBUS_MESSAGE_TYPE_METHOD_CALL)); \
264   g_assert_cmpstr (dbus_message_get_sender (m), ==, sender); \
265   g_assert_cmpstr (dbus_message_get_destination (m), ==, destination); \
266   g_assert_cmpstr (dbus_message_get_path (m), ==, path); \
267   g_assert_cmpstr (dbus_message_get_interface (m), ==, iface); \
268   g_assert_cmpstr (dbus_message_get_member (m), ==, method); \
269   g_assert_cmpstr (dbus_message_get_signature (m), ==, signature); \
270   g_assert_cmpint (dbus_message_get_serial (m), !=, 0); \
271   g_assert_cmpint (dbus_message_get_reply_serial (m), ==, 0); \
272 } while (0)
273
274 #define assert_signal(m, \
275     sender, path, iface, member, signature, \
276     destination) \
277 do { \
278   g_assert_cmpstr (dbus_message_type_to_string (dbus_message_get_type (m)), \
279       ==, dbus_message_type_to_string (DBUS_MESSAGE_TYPE_SIGNAL)); \
280   g_assert_cmpstr (dbus_message_get_sender (m), ==, sender); \
281   g_assert_cmpstr (dbus_message_get_destination (m), ==, destination); \
282   g_assert_cmpstr (dbus_message_get_path (m), ==, path); \
283   g_assert_cmpstr (dbus_message_get_interface (m), ==, iface); \
284   g_assert_cmpstr (dbus_message_get_member (m), ==, member); \
285   g_assert_cmpstr (dbus_message_get_signature (m), ==, signature); \
286   g_assert_cmpint (dbus_message_get_serial (m), !=, 0); \
287   g_assert_cmpint (dbus_message_get_reply_serial (m), ==, 0); \
288 } while (0)
289
290 #define assert_method_reply(m, sender, destination, signature) \
291 do { \
292   g_assert_cmpstr (dbus_message_type_to_string (dbus_message_get_type (m)), \
293       ==, dbus_message_type_to_string (DBUS_MESSAGE_TYPE_METHOD_RETURN)); \
294   g_assert_cmpstr (dbus_message_get_sender (m), ==, sender); \
295   g_assert_cmpstr (dbus_message_get_destination (m), ==, destination); \
296   g_assert_cmpstr (dbus_message_get_path (m), ==, NULL); \
297   g_assert_cmpstr (dbus_message_get_interface (m), ==, NULL); \
298   g_assert_cmpstr (dbus_message_get_member (m), ==, NULL); \
299   g_assert_cmpstr (dbus_message_get_signature (m), ==, signature); \
300   g_assert_cmpint (dbus_message_get_serial (m), !=, 0); \
301   g_assert_cmpint (dbus_message_get_reply_serial (m), !=, 0); \
302 } while (0)
303
304 #define assert_error_reply(m, sender, destination, error_name) \
305 do { \
306   g_assert_cmpstr (dbus_message_type_to_string (dbus_message_get_type (m)), \
307       ==, dbus_message_type_to_string (DBUS_MESSAGE_TYPE_ERROR)); \
308   g_assert_cmpstr (dbus_message_get_sender (m), ==, sender); \
309   g_assert_cmpstr (dbus_message_get_destination (m), ==, destination); \
310   g_assert_cmpstr (dbus_message_get_error_name (m), ==, error_name); \
311   g_assert_cmpstr (dbus_message_get_path (m), ==, NULL); \
312   g_assert_cmpstr (dbus_message_get_interface (m), ==, NULL); \
313   g_assert_cmpstr (dbus_message_get_member (m), ==, NULL); \
314   g_assert_cmpstr (dbus_message_get_signature (m), ==, "s"); \
315   g_assert_cmpint (dbus_message_get_serial (m), !=, 0); \
316   g_assert_cmpint (dbus_message_get_reply_serial (m), !=, 0); \
317 } while (0)
318
319 /* This is called after processing pending replies to our own method
320  * calls, but before anything else.
321  */
322 static DBusHandlerResult
323 monitor_filter (DBusConnection *connection,
324     DBusMessage *message,
325     void *user_data)
326 {
327   Fixture *f = user_data;
328
329   g_assert_cmpstr (dbus_message_get_interface (message), !=,
330       "com.example.Tedious");
331
332   /* we are not interested in the monitor getting NameAcquired or NameLost
333    * for most tests */
334   if (f->config == NULL || !f->config->care_about_our_names)
335     {
336       if (dbus_message_is_signal (message, DBUS_INTERFACE_DBUS,
337             "NameAcquired") ||
338           dbus_message_is_signal (message, DBUS_INTERFACE_DBUS,
339             "NameLost"))
340         {
341           DBusError e = DBUS_ERROR_INIT;
342           const char *s;
343
344           dbus_message_get_args (message, &e,
345                 DBUS_TYPE_STRING, &s,
346                 DBUS_TYPE_INVALID);
347           test_assert_no_error (&e);
348
349           if (strcmp (s, f->monitor_name) == 0)
350             {
351               /* ignore */
352               return DBUS_HANDLER_RESULT_HANDLED;
353             }
354         }
355     }
356
357   g_queue_push_tail (&f->monitored, dbus_message_ref (message));
358
359   return DBUS_HANDLER_RESULT_HANDLED;
360 }
361
362 static DBusHandlerResult
363 recipient_filter (DBusConnection *connection,
364     DBusMessage *message,
365     void *user_data)
366 {
367   g_assert_cmpstr (dbus_message_get_interface (message), !=,
368       "com.example.CannotSend");
369   g_assert_cmpstr (dbus_message_get_interface (message), !=,
370       "com.example.CannotReceive");
371
372   return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
373 }
374
375 static DBusHandlerResult
376 systemd_filter (DBusConnection *connection,
377     DBusMessage *message,
378     void *user_data)
379 {
380   Fixture *f = user_data;
381
382   if (dbus_message_is_signal (message, DBUS_INTERFACE_DBUS,
383         "NameAcquired") ||
384       dbus_message_is_signal (message, DBUS_INTERFACE_DBUS,
385         "NameLost"))
386     {
387       return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
388     }
389
390   g_assert (f->systemd_message == NULL);
391   f->systemd_message = dbus_message_ref (message);
392
393   return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
394 }
395
396 static DBusHandlerResult
397 activated_filter (DBusConnection *connection,
398     DBusMessage *message,
399     void *user_data)
400 {
401   Fixture *f = user_data;
402
403   if (dbus_message_is_signal (message, DBUS_INTERFACE_DBUS,
404         "NameAcquired") ||
405       dbus_message_is_signal (message, DBUS_INTERFACE_DBUS,
406         "NameLost"))
407     {
408       return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
409     }
410
411   g_assert (f->activated_message == NULL);
412   f->activated_message = dbus_message_ref (message);
413
414   return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
415 }
416
417 static void
418 setup (Fixture *f,
419     gconstpointer context)
420 {
421   f->config = context;
422
423   f->ctx = test_main_context_get ();
424
425   f->ge = NULL;
426   dbus_error_init (&f->e);
427
428   f->address = test_get_dbus_daemon (f->config ? f->config->config_file : NULL,
429       TEST_USER_ME, &f->daemon_pid);
430
431   if (f->address == NULL)
432     return;
433
434   f->monitor = test_connect_to_bus (f->ctx, f->address);
435   f->monitor_name = dbus_bus_get_unique_name (f->monitor);
436   f->sender = test_connect_to_bus (f->ctx, f->address);
437   f->sender_name = dbus_bus_get_unique_name (f->sender);
438   f->recipient = test_connect_to_bus (f->ctx, f->address);
439   f->recipient_name = dbus_bus_get_unique_name (f->recipient);
440
441   if (!dbus_connection_add_filter (f->monitor, monitor_filter, f, NULL))
442     g_error ("OOM");
443
444   if (!dbus_connection_add_filter (f->recipient, recipient_filter, f, NULL))
445     g_error ("OOM");
446 }
447
448 static void
449 become_monitor (Fixture *f)
450 {
451   DBusMessage *m;
452   DBusPendingCall *pc;
453   dbus_bool_t ok;
454   DBusMessageIter appender, array_appender;
455   const char * const *match_rules;
456   int i;
457   dbus_uint32_t zero = 0;
458
459   dbus_connection_set_route_peer_messages (f->monitor, TRUE);
460
461   if (f->config != NULL && f->config->match_rules != NULL)
462     match_rules = f->config->match_rules;
463   else
464     match_rules = wildcard_match_rules;
465
466   m = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
467       DBUS_PATH_DBUS, DBUS_INTERFACE_MONITORING, "BecomeMonitor");
468
469   if (m == NULL)
470     g_error ("OOM");
471
472   dbus_message_iter_init_append (m, &appender);
473
474   if (!dbus_message_iter_open_container (&appender, DBUS_TYPE_ARRAY, "s",
475         &array_appender))
476     g_error ("OOM");
477
478   for (i = 0; match_rules[i] != NULL; i++)
479     {
480       if (!dbus_message_iter_append_basic (&array_appender, DBUS_TYPE_STRING,
481             &match_rules[i]))
482         g_error ("OOM");
483     }
484
485   if (!dbus_message_iter_close_container (&appender, &array_appender) ||
486       !dbus_message_iter_append_basic (&appender, DBUS_TYPE_UINT32, &zero))
487     g_error ("OOM");
488
489   if (!dbus_connection_send_with_reply (f->monitor, m, &pc,
490         DBUS_TIMEOUT_USE_DEFAULT) ||
491       pc == NULL)
492     g_error ("OOM");
493
494   dbus_message_unref (m);
495   m = NULL;
496
497   if (dbus_pending_call_get_completed (pc))
498     test_pending_call_store_reply (pc, &m);
499   else if (!dbus_pending_call_set_notify (pc, test_pending_call_store_reply,
500         &m, NULL))
501     g_error ("OOM");
502
503   while (m == NULL)
504     test_main_context_iterate (f->ctx, TRUE);
505
506   ok = dbus_message_get_args (m, &f->e,
507       DBUS_TYPE_INVALID);
508   test_assert_no_error (&f->e);
509   g_assert (ok);
510
511   dbus_pending_call_unref (pc);
512   dbus_message_unref (m);
513   m = NULL;
514 }
515
516 /*
517  * Test what happens if the method call arguments are invalid.
518  */
519 static void
520 test_invalid (Fixture *f,
521     gconstpointer context)
522 {
523   DBusMessage *m;
524   DBusPendingCall *pc;
525   dbus_bool_t ok;
526   DBusMessageIter appender, array_appender;
527   dbus_uint32_t zero = 0;
528   dbus_uint32_t invalid_flags = G_MAXUINT32;
529   const char *s;
530
531   if (f->address == NULL)
532     return;
533
534   dbus_connection_set_route_peer_messages (f->monitor, TRUE);
535
536   /* Try to become a monitor but specify nonzero flags - not allowed */
537
538   m = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
539       DBUS_PATH_DBUS, DBUS_INTERFACE_MONITORING, "BecomeMonitor");
540
541   if (m == NULL)
542     g_error ("OOM");
543
544   dbus_message_iter_init_append (m, &appender);
545
546   if (!dbus_message_iter_open_container (&appender, DBUS_TYPE_ARRAY, "s",
547         &array_appender))
548     g_error ("OOM");
549
550   if (!dbus_message_iter_close_container (&appender, &array_appender) ||
551       !dbus_message_iter_append_basic (&appender, DBUS_TYPE_UINT32,
552         &invalid_flags))
553     g_error ("OOM");
554
555   if (!dbus_connection_send_with_reply (f->monitor, m, &pc,
556         DBUS_TIMEOUT_USE_DEFAULT) ||
557       pc == NULL)
558     g_error ("OOM");
559
560   dbus_message_unref (m);
561   m = NULL;
562
563   if (dbus_pending_call_get_completed (pc))
564     test_pending_call_store_reply (pc, &m);
565   else if (!dbus_pending_call_set_notify (pc, test_pending_call_store_reply,
566         &m, NULL))
567     g_error ("OOM");
568
569   while (m == NULL)
570     test_main_context_iterate (f->ctx, TRUE);
571
572   g_assert_cmpint (dbus_message_get_type (m), ==, DBUS_MESSAGE_TYPE_ERROR);
573   g_assert_cmpstr (dbus_message_get_error_name (m), ==,
574       DBUS_ERROR_INVALID_ARGS);
575
576   /* Try to become a monitor but specify a bad match rule -
577    * also not allowed */
578
579   dbus_pending_call_unref (pc);
580   dbus_message_unref (m);
581
582   m = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
583       DBUS_PATH_DBUS, DBUS_INTERFACE_MONITORING, "BecomeMonitor");
584
585   if (m == NULL)
586     g_error ("OOM");
587
588   dbus_message_iter_init_append (m, &appender);
589
590   if (!dbus_message_iter_open_container (&appender, DBUS_TYPE_ARRAY, "s",
591         &array_appender))
592     g_error ("OOM");
593
594   /* Syntactically incorrect match rule taken from #92298 - was probably
595    * intended to be path='/modules/...'
596    */
597   s = "interface='org.kde.walletd',member='/modules/kwalletd/org.kde.KWallet/walletOpened'";
598
599   if (!dbus_message_iter_append_basic (&array_appender, DBUS_TYPE_STRING,
600         &s) ||
601       !dbus_message_iter_close_container (&appender, &array_appender) ||
602       !dbus_message_iter_append_basic (&appender, DBUS_TYPE_UINT32, &zero) ||
603       !dbus_connection_send_with_reply (f->monitor, m, &pc,
604         DBUS_TIMEOUT_USE_DEFAULT) ||
605       pc == NULL)
606     g_error ("OOM");
607
608   dbus_message_unref (m);
609   m = NULL;
610
611   if (dbus_pending_call_get_completed (pc))
612     test_pending_call_store_reply (pc, &m);
613   else if (!dbus_pending_call_set_notify (pc, test_pending_call_store_reply,
614         &m, NULL))
615     g_error ("OOM");
616
617   while (m == NULL)
618     test_main_context_iterate (f->ctx, TRUE);
619
620   g_assert_cmpint (dbus_message_get_type (m), ==, DBUS_MESSAGE_TYPE_ERROR);
621   g_assert_cmpstr (dbus_message_get_error_name (m), ==,
622       DBUS_ERROR_MATCH_RULE_INVALID);
623
624   dbus_pending_call_unref (pc);
625   dbus_message_unref (m);
626
627   /* We did not become a monitor, so we can still call methods. */
628
629   pc = NULL;
630   m = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
631       DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, "GetId");
632
633   if (m == NULL)
634     g_error ("OOM");
635
636   if (!dbus_connection_send_with_reply (f->monitor, m, &pc,
637         DBUS_TIMEOUT_USE_DEFAULT) ||
638       pc == NULL)
639     g_error ("OOM");
640
641   dbus_message_unref (m);
642   m = NULL;
643
644   if (dbus_pending_call_get_completed (pc))
645     test_pending_call_store_reply (pc, &m);
646   else if (!dbus_pending_call_set_notify (pc, test_pending_call_store_reply,
647         &m, NULL))
648     g_error ("OOM");
649
650   while (m == NULL)
651     test_main_context_iterate (f->ctx, TRUE);
652
653   ok = dbus_message_get_args (m, &f->e,
654       DBUS_TYPE_STRING, &s,
655       DBUS_TYPE_INVALID);
656   test_assert_no_error (&f->e);
657   g_assert (ok);
658   g_assert_cmpstr (s, !=, NULL);
659   g_assert_cmpstr (s, !=, "");
660
661   dbus_pending_call_unref (pc);
662   dbus_message_unref (m);
663 }
664
665 /*
666  * Test the side-effects of becoming a monitor.
667  */
668 static void
669 test_become_monitor (Fixture *f,
670     gconstpointer context)
671 {
672   DBusMessage *m;
673   int ret;
674   dbus_bool_t got_unique = FALSE, got_a = FALSE, got_b = FALSE, got_c = FALSE;
675   dbus_bool_t lost_unique = FALSE, lost_a = FALSE, lost_b = FALSE, lost_c = FALSE;
676
677   if (f->address == NULL)
678     return;
679
680   ret = dbus_bus_request_name (f->monitor, "com.example.A",
681       DBUS_NAME_FLAG_DO_NOT_QUEUE, &f->e);
682   test_assert_no_error (&f->e);
683   g_assert_cmpint (ret, ==, DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER);
684
685   ret = dbus_bus_request_name (f->monitor, "com.example.B",
686       DBUS_NAME_FLAG_DO_NOT_QUEUE, &f->e);
687   test_assert_no_error (&f->e);
688   g_assert_cmpint (ret, ==, DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER);
689
690   ret = dbus_bus_request_name (f->monitor, "com.example.C",
691       DBUS_NAME_FLAG_DO_NOT_QUEUE, &f->e);
692   test_assert_no_error (&f->e);
693   g_assert_cmpint (ret, ==, DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER);
694
695   while (!got_unique || !got_a || !got_b || !got_c)
696     {
697       if (g_queue_is_empty (&f->monitored))
698         test_main_context_iterate (f->ctx, TRUE);
699
700       while ((m = g_queue_pop_head (&f->monitored)) != NULL)
701         {
702           if (dbus_message_is_signal (m, DBUS_INTERFACE_DBUS,
703                 "NameAcquired"))
704             {
705               const char *name;
706               dbus_bool_t ok = dbus_message_get_args (m, &f->e,
707                   DBUS_TYPE_STRING, &name,
708                   DBUS_TYPE_INVALID);
709
710               g_assert_cmpstr (dbus_message_get_path (m), ==,
711                   DBUS_PATH_DBUS);
712
713               test_assert_no_error (&f->e);
714               g_assert (ok);
715
716               if (g_str_equal (name, f->monitor_name))
717                 {
718                   g_assert (!got_unique);
719                   got_unique = TRUE;
720                 }
721               else if (g_str_equal (name, "com.example.A"))
722                 {
723                   g_assert (!got_a);
724                   got_a = TRUE;
725                 }
726               else if (g_str_equal (name, "com.example.B"))
727                 {
728                   g_assert (!got_b);
729                   got_b = TRUE;
730                 }
731               else
732                 {
733                   g_assert_cmpstr (name, ==, "com.example.C");
734                   g_assert (!got_c);
735                   got_c = TRUE;
736                 }
737             }
738           else
739             {
740               g_error ("unexpected message %s.%s",
741                   dbus_message_get_interface (m),
742                   dbus_message_get_member (m));
743             }
744
745           dbus_message_unref (m);
746         }
747     }
748
749   become_monitor (f);
750
751   while (!lost_unique || !lost_a || !lost_b || !lost_c)
752     {
753       if (g_queue_is_empty (&f->monitored))
754         test_main_context_iterate (f->ctx, TRUE);
755
756       while ((m = g_queue_pop_head (&f->monitored)) != NULL)
757         {
758           if (dbus_message_is_signal (m, DBUS_INTERFACE_DBUS,
759                 "NameLost"))
760             {
761               const char *name;
762               dbus_bool_t ok = dbus_message_get_args (m, &f->e,
763                   DBUS_TYPE_STRING, &name,
764                   DBUS_TYPE_INVALID);
765
766               test_assert_no_error (&f->e);
767               g_assert (ok);
768
769               if (g_str_equal (name, f->monitor_name))
770                 {
771                   g_assert (!lost_unique);
772                   lost_unique = TRUE;
773                 }
774               else if (g_str_equal (name, "com.example.A"))
775                 {
776                   g_assert (!lost_a);
777                   lost_a = TRUE;
778                 }
779               else if (g_str_equal (name, "com.example.B"))
780                 {
781                   g_assert (!lost_b);
782                   lost_b = TRUE;
783                 }
784               else
785                 {
786                   g_assert_cmpstr (name, ==, "com.example.C");
787                   g_assert (!lost_c);
788                   lost_c = TRUE;
789                 }
790             }
791           else
792             {
793               g_error ("unexpected message %s.%s",
794                   dbus_message_get_interface (m),
795                   dbus_message_get_member (m));
796             }
797
798           dbus_message_unref (m);
799         }
800     }
801
802   /* Calling methods is forbidden; we get disconnected. */
803   dbus_bus_add_match (f->monitor, "", &f->e);
804   g_assert_cmpstr (f->e.name, ==, DBUS_ERROR_NO_REPLY);
805   g_assert (!dbus_connection_get_is_connected (f->monitor));
806
807   while (TRUE)
808     {
809       if (g_queue_is_empty (&f->monitored))
810         test_main_context_iterate (f->ctx, TRUE);
811
812       /* When we iterate all the connection's messages, we see ourselves
813        * losing all our names, then we're disconnected. */
814       while ((m = g_queue_pop_head (&f->monitored)) != NULL)
815         {
816           if (dbus_message_is_signal (m, DBUS_INTERFACE_LOCAL, "Disconnected"))
817             {
818               dbus_message_unref (m);
819               goto disconnected;
820             }
821           else
822             {
823               g_error ("unexpected message %s.%s",
824                   dbus_message_get_interface (m),
825                   dbus_message_get_member (m));
826             }
827
828           dbus_message_unref (m);
829         }
830     }
831
832 disconnected:
833
834   g_assert (lost_a);
835   g_assert (lost_b);
836   g_assert (lost_c);
837 }
838
839 static void
840 test_broadcast (Fixture *f,
841     gconstpointer context)
842 {
843   DBusMessage *m;
844
845   if (f->address == NULL)
846     return;
847
848   dbus_bus_add_match (f->recipient, "type='signal'", &f->e);
849   test_assert_no_error (&f->e);
850
851   become_monitor (f);
852
853   m = dbus_message_new_signal ("/foo", "com.example.bar", "BroadcastSignal1");
854   dbus_connection_send (f->sender, m, NULL);
855   dbus_message_unref (m);
856
857   m = dbus_message_new_signal ("/foo", "com.example.bar", "BroadcastSignal2");
858   dbus_connection_send (f->sender, m, NULL);
859   dbus_message_unref (m);
860
861   m = dbus_message_new_signal ("/foo", "com.example.bar", "BroadcastSignal3");
862   dbus_connection_send (f->sender, m, NULL);
863   dbus_message_unref (m);
864
865   while (g_queue_get_length (&f->monitored) < 3)
866     test_main_context_iterate (f->ctx, TRUE);
867
868   m = g_queue_pop_head (&f->monitored);
869   assert_signal (m, f->sender_name, "/foo", "com.example.bar",
870       "BroadcastSignal1", "", NULL);
871   dbus_message_unref (m);
872
873   m = g_queue_pop_head (&f->monitored);
874   assert_signal (m, f->sender_name, "/foo", "com.example.bar",
875       "BroadcastSignal2", "", NULL);
876   dbus_message_unref (m);
877
878   m = g_queue_pop_head (&f->monitored);
879   assert_signal (m, f->sender_name, "/foo", "com.example.bar",
880       "BroadcastSignal3", "", NULL);
881   dbus_message_unref (m);
882
883   m = g_queue_pop_head (&f->monitored);
884   g_assert (m == NULL);
885 }
886
887 static void
888 test_forbidden_broadcast (Fixture *f,
889     gconstpointer context)
890 {
891   DBusMessage *m;
892
893   if (f->address == NULL)
894     return;
895
896   dbus_bus_add_match (f->recipient, "type='signal'", &f->e);
897   test_assert_no_error (&f->e);
898
899   become_monitor (f);
900
901   m = dbus_message_new_signal ("/foo", "com.example.CannotSend",
902       "BroadcastSignal1");
903   dbus_connection_send (f->sender, m, NULL);
904   dbus_message_unref (m);
905
906   m = dbus_message_new_signal ("/foo", "com.example.CannotReceive",
907       "BroadcastSignal2");
908   dbus_connection_send (f->sender, m, NULL);
909   dbus_message_unref (m);
910
911   m = dbus_message_new_signal ("/foo", "com.example.CannotSend",
912       "BroadcastSignal3");
913   dbus_connection_send (f->sender, m, NULL);
914   dbus_message_unref (m);
915
916   while (g_queue_get_length (&f->monitored) < 6)
917     test_main_context_iterate (f->ctx, TRUE);
918
919   m = g_queue_pop_head (&f->monitored);
920   assert_signal (m, f->sender_name, "/foo", "com.example.CannotSend",
921       "BroadcastSignal1", "", NULL);
922   dbus_message_unref (m);
923
924   m = g_queue_pop_head (&f->monitored);
925   assert_error_reply (m, DBUS_SERVICE_DBUS, f->sender_name,
926       DBUS_ERROR_ACCESS_DENIED);
927   dbus_message_unref (m);
928
929   m = g_queue_pop_head (&f->monitored);
930   assert_signal (m, f->sender_name, "/foo", "com.example.CannotReceive",
931       "BroadcastSignal2", "", NULL);
932   dbus_message_unref (m);
933
934   m = g_queue_pop_head (&f->monitored);
935   assert_error_reply (m, DBUS_SERVICE_DBUS, f->sender_name,
936       DBUS_ERROR_ACCESS_DENIED);
937   dbus_message_unref (m);
938
939   m = g_queue_pop_head (&f->monitored);
940   assert_signal (m, f->sender_name, "/foo", "com.example.CannotSend",
941       "BroadcastSignal3", "", NULL);
942   dbus_message_unref (m);
943
944   m = g_queue_pop_head (&f->monitored);
945   assert_error_reply (m, DBUS_SERVICE_DBUS, f->sender_name,
946       DBUS_ERROR_ACCESS_DENIED);
947   dbus_message_unref (m);
948
949   m = g_queue_pop_head (&f->monitored);
950   g_assert (m == NULL);
951 }
952
953 static void
954 test_unicast_signal (Fixture *f,
955     gconstpointer context)
956 {
957   DBusMessage *m;
958
959   if (f->address == NULL)
960     return;
961
962   become_monitor (f);
963
964   m = dbus_message_new_signal ("/foo", "com.example.bar", "UnicastSignal1");
965   if (!dbus_message_set_destination (m, f->recipient_name))
966     g_error ("OOM");
967   dbus_connection_send (f->sender, m, NULL);
968   dbus_message_unref (m);
969
970   m = dbus_message_new_signal ("/foo", "com.example.bar", "UnicastSignal2");
971   if (!dbus_message_set_destination (m, f->recipient_name))
972     g_error ("OOM");
973   dbus_connection_send (f->sender, m, NULL);
974   dbus_message_unref (m);
975
976   m = dbus_message_new_signal ("/foo", "com.example.bar", "UnicastSignal3");
977   if (!dbus_message_set_destination (m, f->recipient_name))
978     g_error ("OOM");
979   dbus_connection_send (f->sender, m, NULL);
980   dbus_message_unref (m);
981
982   while (g_queue_get_length (&f->monitored) < 3)
983     test_main_context_iterate (f->ctx, TRUE);
984
985   m = g_queue_pop_head (&f->monitored);
986   assert_signal (m, f->sender_name, "/foo",
987       "com.example.bar", "UnicastSignal1", "", f->recipient_name);
988   dbus_message_unref (m);
989
990   m = g_queue_pop_head (&f->monitored);
991   assert_signal (m, f->sender_name, "/foo",
992       "com.example.bar", "UnicastSignal2", "", f->recipient_name);
993   dbus_message_unref (m);
994
995   m = g_queue_pop_head (&f->monitored);
996   assert_signal (m, f->sender_name, "/foo",
997       "com.example.bar", "UnicastSignal3", "", f->recipient_name);
998   dbus_message_unref (m);
999
1000   m = g_queue_pop_head (&f->monitored);
1001   g_assert (m == NULL);
1002 }
1003
1004 static void
1005 test_forbidden (Fixture *f,
1006     gconstpointer context)
1007 {
1008   DBusMessage *m;
1009
1010   if (f->address == NULL)
1011     return;
1012
1013   become_monitor (f);
1014
1015   m = dbus_message_new_signal ("/foo", "com.example.CannotSend",
1016       "UnicastSignal1");
1017   if (!dbus_message_set_destination (m, f->recipient_name))
1018     g_error ("OOM");
1019   dbus_connection_send (f->sender, m, NULL);
1020   dbus_message_unref (m);
1021
1022   m = dbus_message_new_signal ("/foo", "com.example.CannotReceive",
1023       "UnicastSignal2");
1024   if (!dbus_message_set_destination (m, f->recipient_name))
1025     g_error ("OOM");
1026   dbus_connection_send (f->sender, m, NULL);
1027   dbus_message_unref (m);
1028
1029   m = dbus_message_new_signal ("/foo", "com.example.CannotSend",
1030       "UnicastSignal3");
1031   if (!dbus_message_set_destination (m, f->recipient_name))
1032     g_error ("OOM");
1033   dbus_connection_send (f->sender, m, NULL);
1034   dbus_message_unref (m);
1035
1036   while (g_queue_get_length (&f->monitored) < 6)
1037     test_main_context_iterate (f->ctx, TRUE);
1038
1039   m = g_queue_pop_head (&f->monitored);
1040   assert_signal (m, f->sender_name, "/foo",
1041       "com.example.CannotSend", "UnicastSignal1", "", f->recipient_name);
1042   dbus_message_unref (m);
1043
1044   m = g_queue_pop_head (&f->monitored);
1045   assert_error_reply (m, DBUS_SERVICE_DBUS, f->sender_name,
1046       DBUS_ERROR_ACCESS_DENIED);
1047   dbus_message_unref (m);
1048
1049   m = g_queue_pop_head (&f->monitored);
1050   assert_signal (m, f->sender_name, "/foo",
1051       "com.example.CannotReceive", "UnicastSignal2", "", f->recipient_name);
1052   dbus_message_unref (m);
1053
1054   m = g_queue_pop_head (&f->monitored);
1055   assert_error_reply (m, DBUS_SERVICE_DBUS, f->sender_name,
1056       DBUS_ERROR_ACCESS_DENIED);
1057   dbus_message_unref (m);
1058
1059   m = g_queue_pop_head (&f->monitored);
1060   assert_signal (m, f->sender_name, "/foo",
1061       "com.example.CannotSend", "UnicastSignal3", "", f->recipient_name);
1062   dbus_message_unref (m);
1063
1064   m = g_queue_pop_head (&f->monitored);
1065   assert_error_reply (m, DBUS_SERVICE_DBUS, f->sender_name,
1066       DBUS_ERROR_ACCESS_DENIED);
1067   dbus_message_unref (m);
1068
1069   m = g_queue_pop_head (&f->monitored);
1070   g_assert (m == NULL);
1071 }
1072
1073 static void
1074 test_method_call (Fixture *f,
1075     gconstpointer context)
1076 {
1077   DBusMessage *m;
1078
1079   if (f->address == NULL)
1080     return;
1081
1082   become_monitor (f);
1083
1084   /* regression test for
1085    * https://bugs.freedesktop.org/show_bug.cgi?id=90952 */
1086   m = dbus_message_new_method_call (f->recipient_name, "/foo",
1087       DBUS_INTERFACE_PEER, "Ping");
1088   dbus_connection_send (f->sender, m, NULL);
1089   dbus_message_unref (m);
1090
1091   while (g_queue_get_length (&f->monitored) < 2)
1092     test_main_context_iterate (f->ctx, TRUE);
1093
1094   m = g_queue_pop_head (&f->monitored);
1095   assert_method_call (m, f->sender_name, f->recipient_name, "/foo",
1096       DBUS_INTERFACE_PEER, "Ping", "");
1097   dbus_message_unref (m);
1098
1099   m = g_queue_pop_head (&f->monitored);
1100   assert_method_reply (m, f->recipient_name, f->sender_name, "");
1101   dbus_message_unref (m);
1102
1103   m = g_queue_pop_head (&f->monitored);
1104   g_assert (m == NULL);
1105
1106   m = dbus_message_new_method_call (f->recipient_name, "/foo", "com.example.bar",
1107       "Call1");
1108   dbus_connection_send (f->sender, m, NULL);
1109   dbus_message_unref (m);
1110
1111   while (g_queue_get_length (&f->monitored) < 2)
1112     test_main_context_iterate (f->ctx, TRUE);
1113
1114   m = g_queue_pop_head (&f->monitored);
1115   assert_method_call (m, f->sender_name, f->recipient_name, "/foo",
1116       "com.example.bar", "Call1", "");
1117   dbus_message_unref (m);
1118
1119   m = g_queue_pop_head (&f->monitored);
1120   assert_error_reply (m, f->recipient_name, f->sender_name,
1121       DBUS_ERROR_UNKNOWN_METHOD);
1122   dbus_message_unref (m);
1123
1124   m = g_queue_pop_head (&f->monitored);
1125   g_assert (m == NULL);
1126 }
1127
1128 static void
1129 test_forbidden_method_call (Fixture *f,
1130     gconstpointer context)
1131 {
1132   DBusMessage *m;
1133
1134   if (f->address == NULL)
1135     return;
1136
1137   become_monitor (f);
1138
1139   m = dbus_message_new_method_call (f->recipient_name, "/foo",
1140       "com.example.CannotSend", "Call1");
1141   dbus_connection_send (f->sender, m, NULL);
1142   dbus_message_unref (m);
1143
1144   while (g_queue_get_length (&f->monitored) < 2)
1145     test_main_context_iterate (f->ctx, TRUE);
1146
1147   m = g_queue_pop_head (&f->monitored);
1148   assert_method_call (m, f->sender_name, f->recipient_name, "/foo",
1149       "com.example.CannotSend", "Call1", "");
1150   dbus_message_unref (m);
1151
1152   m = g_queue_pop_head (&f->monitored);
1153   assert_error_reply (m, DBUS_SERVICE_DBUS, f->sender_name,
1154       DBUS_ERROR_ACCESS_DENIED);
1155   dbus_message_unref (m);
1156
1157   m = g_queue_pop_head (&f->monitored);
1158   g_assert (m == NULL);
1159
1160   m = dbus_message_new_method_call (f->recipient_name, "/foo",
1161       "com.example.CannotReceive", "Call2");
1162   dbus_connection_send (f->sender, m, NULL);
1163   dbus_message_unref (m);
1164
1165   while (g_queue_get_length (&f->monitored) < 2)
1166     test_main_context_iterate (f->ctx, TRUE);
1167
1168   m = g_queue_pop_head (&f->monitored);
1169   assert_method_call (m, f->sender_name, f->recipient_name, "/foo",
1170       "com.example.CannotReceive", "Call2", "");
1171   dbus_message_unref (m);
1172
1173   m = g_queue_pop_head (&f->monitored);
1174   assert_error_reply (m, DBUS_SERVICE_DBUS, f->sender_name,
1175       DBUS_ERROR_ACCESS_DENIED);
1176   dbus_message_unref (m);
1177
1178   m = g_queue_pop_head (&f->monitored);
1179   g_assert (m == NULL);
1180 }
1181
1182 static void
1183 test_dbus_daemon (Fixture *f,
1184     gconstpointer context)
1185 {
1186   DBusMessage *m;
1187   int res;
1188
1189   if (f->address == NULL)
1190     return;
1191
1192   become_monitor (f);
1193
1194   res = dbus_bus_request_name (f->sender, "com.example.Sender",
1195       DBUS_NAME_FLAG_DO_NOT_QUEUE, &f->e);
1196   test_assert_no_error (&f->e);
1197   g_assert_cmpint (res, ==, DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER);
1198
1199   res = dbus_bus_release_name (f->sender, "com.example.Sender", &f->e);
1200   test_assert_no_error (&f->e);
1201   g_assert_cmpint (res, ==, DBUS_RELEASE_NAME_REPLY_RELEASED);
1202
1203   while (g_queue_get_length (&f->monitored) < 8)
1204     test_main_context_iterate (f->ctx, TRUE);
1205
1206   m = g_queue_pop_head (&f->monitored);
1207   assert_method_call (m, f->sender_name, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS,
1208       DBUS_INTERFACE_DBUS, "RequestName", "su");
1209   dbus_message_unref (m);
1210
1211   m = g_queue_pop_head (&f->monitored);
1212   assert_signal (m, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS,
1213       "NameOwnerChanged", "sss", NULL);
1214   dbus_message_unref (m);
1215
1216   /* FIXME: should we get this? */
1217   m = g_queue_pop_head (&f->monitored);
1218   assert_signal (m, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS,
1219       "NameAcquired", "s", f->sender_name);
1220   dbus_message_unref (m);
1221
1222   m = g_queue_pop_head (&f->monitored);
1223   assert_method_reply (m, DBUS_SERVICE_DBUS, f->sender_name, "u");
1224   dbus_message_unref (m);
1225
1226   m = g_queue_pop_head (&f->monitored);
1227   assert_method_call (m, f->sender_name, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS,
1228       DBUS_INTERFACE_DBUS, "ReleaseName", "s");
1229   dbus_message_unref (m);
1230
1231   /* FIXME: should we get this? */
1232   m = g_queue_pop_head (&f->monitored);
1233   assert_signal (m, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS,
1234       "NameLost", "s", f->sender_name);
1235   dbus_message_unref (m);
1236
1237   m = g_queue_pop_head (&f->monitored);
1238   assert_signal (m, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS,
1239       "NameOwnerChanged", "sss", NULL);
1240   dbus_message_unref (m);
1241
1242   m = g_queue_pop_head (&f->monitored);
1243   assert_method_reply (m, DBUS_SERVICE_DBUS, f->sender_name, "u");
1244   dbus_message_unref (m);
1245
1246   m = g_queue_pop_head (&f->monitored);
1247   g_assert (m == NULL);
1248 }
1249
1250 static void
1251 test_selective (Fixture *f,
1252     gconstpointer context)
1253 {
1254   DBusMessage *m;
1255
1256   if (f->address == NULL)
1257     return;
1258
1259   /* Match rules added before becoming a monitor should be cleared:
1260    * if they weren't, this test would get Interesting twice, then Tedious,
1261    * and only see Fun after that. */
1262   dbus_bus_add_match (f->monitor,
1263       "eavesdrop='true',interface='com.example.Interesting'", &f->e);
1264   test_assert_no_error (&f->e);
1265   dbus_bus_add_match (f->monitor,
1266       "eavesdrop='true',interface='com.example.Tedious'", &f->e);
1267   test_assert_no_error (&f->e);
1268
1269   become_monitor (f);
1270
1271   m = dbus_message_new_signal ("/foo", "com.example.Interesting",
1272       "UnicastSignal1");
1273   if (!dbus_message_set_destination (m, f->recipient_name))
1274     g_error ("OOM");
1275   dbus_connection_send (f->sender, m, NULL);
1276   dbus_message_unref (m);
1277
1278   m = dbus_message_new_signal ("/foo", "com.example.Tedious",
1279       "UnicastSignal2");
1280   if (!dbus_message_set_destination (m, f->recipient_name))
1281     g_error ("OOM");
1282   dbus_connection_send (f->sender, m, NULL);
1283   dbus_message_unref (m);
1284
1285   m = dbus_message_new_signal ("/foo", "com.example.Fun",
1286       "UnicastSignal3");
1287   if (!dbus_message_set_destination (m, f->recipient_name))
1288     g_error ("OOM");
1289   dbus_connection_send (f->sender, m, NULL);
1290   dbus_message_unref (m);
1291
1292   while (g_queue_get_length (&f->monitored) < 2)
1293     test_main_context_iterate (f->ctx, TRUE);
1294
1295   /* We get the interesting signal and the fun signal, but not the tedious
1296    * signal. */
1297
1298   m = g_queue_pop_head (&f->monitored);
1299   assert_signal (m, f->sender_name, "/foo",
1300       "com.example.Interesting", "UnicastSignal1", "", f->recipient_name);
1301   dbus_message_unref (m);
1302
1303   m = g_queue_pop_head (&f->monitored);
1304   assert_signal (m, f->sender_name, "/foo",
1305       "com.example.Fun", "UnicastSignal3", "", f->recipient_name);
1306   dbus_message_unref (m);
1307
1308   m = g_queue_pop_head (&f->monitored);
1309   g_assert (m == NULL);
1310 }
1311
1312 #ifdef DBUS_UNIX
1313 /* currently only used for the systemd activation test */
1314 static void
1315 expect_new_connection (Fixture *f)
1316 {
1317   DBusMessage *m;
1318
1319   while (g_queue_get_length (&f->monitored) < 4)
1320     test_main_context_iterate (f->ctx, TRUE);
1321
1322   m = g_queue_pop_head (&f->monitored);
1323   assert_hello (m);
1324   dbus_message_unref (m);
1325
1326   m = g_queue_pop_head (&f->monitored);
1327   assert_hello_reply (m);
1328   dbus_message_unref (m);
1329
1330   m = g_queue_pop_head (&f->monitored);
1331   assert_signal (m, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS,
1332       "NameOwnerChanged", "sss", NULL);
1333   dbus_message_unref (m);
1334
1335   m = g_queue_pop_head (&f->monitored);
1336   assert_name_acquired (m);
1337   dbus_message_unref (m);
1338 }
1339
1340 /* currently only used for the systemd activation test */
1341 static void
1342 take_well_known_name (Fixture *f,
1343     DBusConnection *connection,
1344     const char *name)
1345 {
1346   int ret;
1347
1348   ret = dbus_bus_request_name (connection, name,
1349       DBUS_NAME_FLAG_DO_NOT_QUEUE, &f->e);
1350   test_assert_no_error (&f->e);
1351   g_assert_cmpint (ret, ==, DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER);
1352 }
1353
1354 /* currently only used for the systemd activation test */
1355 static void
1356 expect_take_well_known_name (Fixture *f,
1357     DBusConnection *connection,
1358     const char *name)
1359 {
1360   DBusMessage *m;
1361   const char *connection_name = dbus_bus_get_unique_name (connection);
1362
1363   while (g_queue_get_length (&f->monitored) < 4)
1364     test_main_context_iterate (f->ctx, TRUE);
1365
1366   m = g_queue_pop_head (&f->monitored);
1367   assert_method_call (m, connection_name, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS,
1368       DBUS_INTERFACE_DBUS, "RequestName", "su");
1369   dbus_message_unref (m);
1370
1371   m = g_queue_pop_head (&f->monitored);
1372   assert_signal (m, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS,
1373       "NameOwnerChanged", "sss", NULL);
1374   dbus_message_unref (m);
1375
1376   m = g_queue_pop_head (&f->monitored);
1377   assert_signal (m, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS,
1378       "NameAcquired", "s", connection_name);
1379   dbus_message_unref (m);
1380
1381   m = g_queue_pop_head (&f->monitored);
1382   assert_method_reply (m, DBUS_SERVICE_DBUS, connection_name, "u");
1383   dbus_message_unref (m);
1384 }
1385
1386 static void
1387 test_activation (Fixture *f,
1388     gconstpointer context)
1389 {
1390   DBusMessage *m;
1391
1392   if (f->address == NULL)
1393     return;
1394
1395   become_monitor (f);
1396
1397   /* The sender sends a message to an activatable service. */
1398   m = dbus_message_new_signal ("/foo", "com.example.bar", "UnicastSignal1");
1399   if (!dbus_message_set_destination (m, "com.example.SystemdActivatable1"))
1400     g_error ("OOM");
1401   dbus_connection_send (f->sender, m, NULL);
1402   dbus_message_unref (m);
1403
1404   /* We observe the activation request, and the message that caused it,
1405    * before systemd has even joined the bus. */
1406   while (g_queue_get_length (&f->monitored) < 2)
1407     test_main_context_iterate (f->ctx, TRUE);
1408
1409   m = g_queue_pop_head (&f->monitored);
1410   assert_signal (m, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS,
1411       "org.freedesktop.systemd1.Activator", "ActivationRequest", "s",
1412       "org.freedesktop.systemd1");
1413   dbus_message_unref (m);
1414   m = g_queue_pop_head (&f->monitored);
1415   assert_signal (m, f->sender_name, "/foo",
1416       "com.example.bar", "UnicastSignal1", "",
1417       "com.example.SystemdActivatable1");
1418   dbus_message_unref (m);
1419
1420   /* The fake systemd connects to the bus. */
1421   f->systemd = test_connect_to_bus (f->ctx, f->address);
1422   if (!dbus_connection_add_filter (f->systemd, systemd_filter, f, NULL))
1423     g_error ("OOM");
1424   f->systemd_name = dbus_bus_get_unique_name (f->systemd);
1425
1426   expect_new_connection (f);
1427   take_well_known_name (f, f->systemd, "org.freedesktop.systemd1");
1428   expect_take_well_known_name (f, f->systemd, "org.freedesktop.systemd1");
1429
1430   /* It gets its activation request. */
1431   while (f->systemd_message == NULL)
1432     test_main_context_iterate (f->ctx, TRUE);
1433
1434   m = f->systemd_message;
1435   f->systemd_message = NULL;
1436   assert_signal (m, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS,
1437       "org.freedesktop.systemd1.Activator", "ActivationRequest", "s",
1438       "org.freedesktop.systemd1");
1439   dbus_message_unref (m);
1440
1441   /* systemd starts the activatable service. */
1442   f->activated = test_connect_to_bus (f->ctx, f->address);
1443   if (!dbus_connection_add_filter (f->activated, activated_filter,
1444         f, NULL))
1445     g_error ("OOM");
1446   f->activated_name = dbus_bus_get_unique_name (f->activated);
1447
1448   expect_new_connection (f);
1449   take_well_known_name (f, f->activated, "com.example.SystemdActivatable1");
1450   expect_take_well_known_name (f, f->activated,
1451       "com.example.SystemdActivatable1");
1452
1453   /* The message is delivered to the activatable service. */
1454   while (f->activated_message == NULL)
1455     test_main_context_iterate (f->ctx, TRUE);
1456
1457   m = f->activated_message;
1458   f->activated_message = NULL;
1459   assert_signal (m, f->sender_name, "/foo",
1460       "com.example.bar", "UnicastSignal1", "",
1461       "com.example.SystemdActivatable1");
1462   dbus_message_unref (m);
1463
1464   /* The sender sends a message to a different activatable service. */
1465   m = dbus_message_new_signal ("/foo", "com.example.bar", "UnicastSignal2");
1466   if (!dbus_message_set_destination (m, "com.example.SystemdActivatable2"))
1467     g_error ("OOM");
1468   dbus_connection_send (f->sender, m, NULL);
1469   dbus_message_unref (m);
1470
1471   /* This time systemd is already ready for it. */
1472   while (g_queue_get_length (&f->monitored) < 2 ||
1473       f->systemd_message == NULL)
1474     test_main_context_iterate (f->ctx, TRUE);
1475
1476   m = f->systemd_message;
1477   f->systemd_message = NULL;
1478   assert_signal (m, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS,
1479       "org.freedesktop.systemd1.Activator", "ActivationRequest", "s",
1480       "org.freedesktop.systemd1");
1481   dbus_message_unref (m);
1482
1483   /* The monitor sees the activation request and the signal that
1484    * prompted it.*/
1485   m = g_queue_pop_head (&f->monitored);
1486   assert_signal (m, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS,
1487       "org.freedesktop.systemd1.Activator", "ActivationRequest", "s",
1488       "org.freedesktop.systemd1");
1489   dbus_message_unref (m);
1490   m = g_queue_pop_head (&f->monitored);
1491   assert_signal (m, f->sender_name, "/foo",
1492       "com.example.bar", "UnicastSignal2", "",
1493       "com.example.SystemdActivatable2");
1494   dbus_message_unref (m);
1495
1496   /* The activatable service takes its name. Here I'm faking it by using
1497    * an existing connection. */
1498   take_well_known_name (f, f->activated, "com.example.SystemdActivatable2");
1499
1500   /* The message is delivered to the activatable service.
1501    * Implementation detail: the monitor sees this happen before it even
1502    * sees that the name request happened, which is pretty odd. */
1503   while (f->activated_message == NULL)
1504     test_main_context_iterate (f->ctx, TRUE);
1505
1506   m = f->activated_message;
1507   f->activated_message = NULL;
1508   assert_signal (m, f->sender_name, "/foo",
1509       "com.example.bar", "UnicastSignal2", "",
1510       "com.example.SystemdActivatable2");
1511   dbus_message_unref (m);
1512
1513   expect_take_well_known_name (f, f->activated,
1514       "com.example.SystemdActivatable2");
1515
1516   /* A third activation. */
1517   m = dbus_message_new_signal ("/foo", "com.example.bar", "UnicastSignal3");
1518   if (!dbus_message_set_destination (m, "com.example.SystemdActivatable3"))
1519     g_error ("OOM");
1520   dbus_connection_send (f->sender, m, NULL);
1521   dbus_message_unref (m);
1522
1523   /* Once again, we see the activation request and the reason. */
1524   while (g_queue_get_length (&f->monitored) < 2)
1525     test_main_context_iterate (f->ctx, TRUE);
1526
1527   m = g_queue_pop_head (&f->monitored);
1528   assert_signal (m, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS,
1529       "org.freedesktop.systemd1.Activator", "ActivationRequest", "s",
1530       "org.freedesktop.systemd1");
1531   dbus_message_unref (m);
1532   m = g_queue_pop_head (&f->monitored);
1533   assert_signal (m, f->sender_name, "/foo",
1534       "com.example.bar", "UnicastSignal3", "",
1535       "com.example.SystemdActivatable3");
1536   dbus_message_unref (m);
1537
1538   /* systemd gets the request too. */
1539   while (f->systemd_message == NULL)
1540     test_main_context_iterate (f->ctx, TRUE);
1541
1542   m = f->systemd_message;
1543   f->systemd_message = NULL;
1544   assert_signal (m, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS,
1545       "org.freedesktop.systemd1.Activator", "ActivationRequest", "s",
1546       "org.freedesktop.systemd1");
1547   dbus_message_unref (m);
1548
1549   /* This time activation fails */
1550   m = dbus_message_new_signal ("/org/freedesktop/systemd1",
1551       "org.freedesktop.systemd1.Activator", "ActivationFailure");
1552
1553   do
1554     {
1555       const char *unit = "dbus-com.example.SystemdActivatable3.service";
1556       const char *error_name = "com.example.Nope";
1557       const char *error_message = "Computer says no";
1558
1559       if (!dbus_message_append_args (m,
1560             DBUS_TYPE_STRING, &unit,
1561             DBUS_TYPE_STRING, &error_name,
1562             DBUS_TYPE_STRING, &error_message,
1563             DBUS_TYPE_INVALID))
1564         g_error ("OOM");
1565     }
1566   while (0);
1567
1568   if (!dbus_message_set_destination (m, "org.freedesktop.DBus"))
1569     g_error ("OOM");
1570   dbus_connection_send (f->systemd, m, NULL);
1571   dbus_message_unref (m);
1572
1573   /* The monitor sees activation fail */
1574
1575   /* Once again, we see the activation request and the reason. */
1576   while (g_queue_get_length (&f->monitored) < 1)
1577     test_main_context_iterate (f->ctx, TRUE);
1578
1579   m = g_queue_pop_head (&f->monitored);
1580   assert_error_reply (m, DBUS_SERVICE_DBUS, f->sender_name,
1581       "com.example.Nope");
1582   dbus_message_unref (m);
1583 }
1584 #endif /* DBUS_UNIX */
1585
1586 static void
1587 teardown (Fixture *f,
1588     gconstpointer context G_GNUC_UNUSED)
1589 {
1590   dbus_error_free (&f->e);
1591   g_clear_error (&f->ge);
1592
1593   if (f->monitor != NULL)
1594     {
1595       dbus_connection_remove_filter (f->monitor, monitor_filter, f);
1596       dbus_connection_close (f->monitor);
1597       dbus_connection_unref (f->monitor);
1598       f->monitor = NULL;
1599     }
1600
1601   if (f->sender != NULL)
1602     {
1603       dbus_connection_close (f->sender);
1604       dbus_connection_unref (f->sender);
1605       f->sender = NULL;
1606     }
1607
1608   if (f->recipient != NULL)
1609     {
1610       dbus_connection_remove_filter (f->recipient, recipient_filter, f);
1611       dbus_connection_close (f->recipient);
1612       dbus_connection_unref (f->recipient);
1613       f->recipient = NULL;
1614     }
1615
1616   if (f->systemd != NULL)
1617     {
1618       dbus_connection_remove_filter (f->systemd, systemd_filter, f);
1619       dbus_connection_close (f->systemd);
1620       dbus_connection_unref (f->systemd);
1621       f->systemd = NULL;
1622     }
1623
1624   if (f->activated != NULL)
1625     {
1626       dbus_connection_remove_filter (f->activated, activated_filter, f);
1627       dbus_connection_close (f->activated);
1628       dbus_connection_unref (f->activated);
1629       f->activated = NULL;
1630     }
1631
1632   test_kill_pid (f->daemon_pid);
1633   g_spawn_close_pid (f->daemon_pid);
1634
1635   test_main_context_unref (f->ctx);
1636
1637   g_queue_foreach (&f->monitored, (GFunc) dbus_message_unref, NULL);
1638   g_queue_clear (&f->monitored);
1639
1640   g_free (f->address);
1641 }
1642
1643 int
1644 main (int argc,
1645     char **argv)
1646 {
1647   test_init (&argc, &argv);
1648
1649   g_test_add ("/monitor/invalid", Fixture, NULL,
1650       setup, test_invalid, teardown);
1651   g_test_add ("/monitor/become", Fixture, &side_effects_config,
1652       setup, test_become_monitor, teardown);
1653   g_test_add ("/monitor/broadcast", Fixture, NULL,
1654       setup, test_broadcast, teardown);
1655   g_test_add ("/monitor/forbidden-broadcast", Fixture, &forbidding_config,
1656       setup, test_forbidden_broadcast, teardown);
1657   g_test_add ("/monitor/unicast-signal", Fixture, NULL,
1658       setup, test_unicast_signal, teardown);
1659   g_test_add ("/monitor/forbidden", Fixture, &forbidding_config,
1660       setup, test_forbidden, teardown);
1661   g_test_add ("/monitor/method-call", Fixture, NULL,
1662       setup, test_method_call, teardown);
1663   g_test_add ("/monitor/forbidden-method", Fixture, &forbidding_config,
1664       setup, test_forbidden_method_call, teardown);
1665   g_test_add ("/monitor/dbus-daemon", Fixture, NULL,
1666       setup, test_dbus_daemon, teardown);
1667   g_test_add ("/monitor/selective", Fixture, &selective_config,
1668       setup, test_selective, teardown);
1669   g_test_add ("/monitor/wildcard", Fixture, &wildcard_config,
1670       setup, test_unicast_signal, teardown);
1671   g_test_add ("/monitor/no-rule", Fixture, &no_rules_config,
1672       setup, test_unicast_signal, teardown);
1673   g_test_add ("/monitor/eavesdrop", Fixture, &eavesdrop_config,
1674       setup, test_unicast_signal, teardown);
1675   g_test_add ("/monitor/no-eavesdrop", Fixture, &no_eavesdrop_config,
1676       setup, test_unicast_signal, teardown);
1677
1678 #ifdef DBUS_UNIX
1679   /* this relies on the systemd activation code path */
1680   g_test_add ("/monitor/activation", Fixture, &fake_systemd_config,
1681       setup, test_activation, teardown);
1682 #endif
1683
1684   return g_test_run ();
1685 }