1/* -*- mode: C; c-file-style: "gnu" -*- */ 2/* dispatch.c Message dispatcher 3 * 4 * Copyright (C) 2003 CodeFactory AB 5 * Copyright (C) 2003, 2004, 2005 Red Hat, Inc. 6 * Copyright (C) 2004 Imendio HB 7 * 8 * Licensed under the Academic Free License version 2.1 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License as published by 12 * the Free Software Foundation; either version 2 of the License, or 13 * (at your option) any later version. 14 * 15 * This program is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with this program; if not, write to the Free Software 22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23 * 24 */ 25 26#include "dispatch.h" 27#include "connection.h" 28#include "driver.h" 29#include "services.h" 30#include "activation.h" 31#include "utils.h" 32#include "bus.h" 33#include "signals.h" 34#include "test.h" 35#include <dbus/dbus-internals.h> 36#include <string.h> 37 38static dbus_bool_t 39send_one_message (DBusConnection *connection, 40 BusContext *context, 41 DBusConnection *sender, 42 DBusConnection *addressed_recipient, 43 DBusMessage *message, 44 BusTransaction *transaction, 45 DBusError *error) 46{ 47 if (!bus_context_check_security_policy (context, transaction, 48 sender, 49 addressed_recipient, 50 connection, 51 message, 52 NULL)) 53 return TRUE; /* silently don't send it */ 54 55 if (!bus_transaction_send (transaction, 56 connection, 57 message)) 58 { 59 BUS_SET_OOM (error); 60 return FALSE; 61 } 62 63 return TRUE; 64} 65 66dbus_bool_t 67bus_dispatch_matches (BusTransaction *transaction, 68 DBusConnection *sender, 69 DBusConnection *addressed_recipient, 70 DBusMessage *message, 71 DBusError *error) 72{ 73 DBusError tmp_error; 74 BusConnections *connections; 75 DBusList *recipients; 76 BusMatchmaker *matchmaker; 77 DBusList *link; 78 BusContext *context; 79 80 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 81 82 /* sender and recipient can both be NULL for the bus driver, 83 * or for signals with no particular recipient 84 */ 85 86 _dbus_assert (sender == NULL || bus_connection_is_active (sender)); 87 _dbus_assert (dbus_message_get_sender (message) != NULL); 88 89 connections = bus_transaction_get_connections (transaction); 90 91 dbus_error_init (&tmp_error); 92 context = bus_transaction_get_context (transaction); 93 matchmaker = bus_context_get_matchmaker (context); 94 95 recipients = NULL; 96 if (!bus_matchmaker_get_recipients (matchmaker, connections, 97 sender, addressed_recipient, message, 98 &recipients)) 99 { 100 BUS_SET_OOM (error); 101 return FALSE; 102 } 103 104 link = _dbus_list_get_first_link (&recipients); 105 while (link != NULL) 106 { 107 DBusConnection *dest; 108 109 dest = link->data; 110 111 if (!send_one_message (dest, context, sender, addressed_recipient, 112 message, transaction, &tmp_error)) 113 break; 114 115 link = _dbus_list_get_next_link (&recipients, link); 116 } 117 118 _dbus_list_clear (&recipients); 119 120 if (dbus_error_is_set (&tmp_error)) 121 { 122 dbus_move_error (&tmp_error, error); 123 return FALSE; 124 } 125 else 126 return TRUE; 127} 128 129static DBusHandlerResult 130bus_dispatch (DBusConnection *connection, 131 DBusMessage *message) 132{ 133 const char *sender, *service_name; 134 DBusError error; 135 BusTransaction *transaction; 136 BusContext *context; 137 DBusHandlerResult result; 138 DBusConnection *addressed_recipient; 139 140 result = DBUS_HANDLER_RESULT_HANDLED; 141 142 transaction = NULL; 143 addressed_recipient = NULL; 144 dbus_error_init (&error); 145 146 context = bus_connection_get_context (connection); 147 _dbus_assert (context != NULL); 148 149 /* If we can't even allocate an OOM error, we just go to sleep 150 * until we can. 151 */ 152 while (!bus_connection_preallocate_oom_error (connection)) 153 _dbus_wait_for_memory (); 154 155 /* Ref connection in case we disconnect it at some point in here */ 156 dbus_connection_ref (connection); 157 158 service_name = dbus_message_get_destination (message); 159 160#ifdef DBUS_ENABLE_VERBOSE_MODE 161 { 162 const char *interface_name, *member_name, *error_name; 163 164 interface_name = dbus_message_get_interface (message); 165 member_name = dbus_message_get_member (message); 166 error_name = dbus_message_get_error_name (message); 167 168 _dbus_verbose ("DISPATCH: %s %s %s to %s\n", 169 interface_name ? interface_name : "(no interface)", 170 member_name ? member_name : "(no member)", 171 error_name ? error_name : "(no error name)", 172 service_name ? service_name : "peer"); 173 } 174#endif /* DBUS_ENABLE_VERBOSE_MODE */ 175 176 /* If service_name is NULL, if it's a signal we send it to all 177 * connections with a match rule. If it's not a signal, there 178 * are some special cases here but mostly we just bail out. 179 */ 180 if (service_name == NULL) 181 { 182 if (dbus_message_is_signal (message, 183 DBUS_INTERFACE_LOCAL, 184 "Disconnected")) 185 { 186 bus_connection_disconnected (connection); 187 goto out; 188 } 189 190 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_SIGNAL) 191 { 192 /* DBusConnection also handles some of these automatically, we leave 193 * it to do so. 194 */ 195 result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 196 goto out; 197 } 198 } 199 200 /* Create our transaction */ 201 transaction = bus_transaction_new (context); 202 if (transaction == NULL) 203 { 204 BUS_SET_OOM (&error); 205 goto out; 206 } 207 208 /* Assign a sender to the message */ 209 if (bus_connection_is_active (connection)) 210 { 211 sender = bus_connection_get_name (connection); 212 _dbus_assert (sender != NULL); 213 214 if (!dbus_message_set_sender (message, sender)) 215 { 216 BUS_SET_OOM (&error); 217 goto out; 218 } 219 220 /* We need to refetch the service name here, because 221 * dbus_message_set_sender can cause the header to be 222 * reallocated, and thus the service_name pointer will become 223 * invalid. 224 */ 225 service_name = dbus_message_get_destination (message); 226 } 227 228 if (service_name && 229 strcmp (service_name, DBUS_SERVICE_DBUS) == 0) /* to bus driver */ 230 { 231 if (!bus_context_check_security_policy (context, transaction, 232 connection, NULL, NULL, message, &error)) 233 { 234 _dbus_verbose ("Security policy rejected message\n"); 235 goto out; 236 } 237 238 _dbus_verbose ("Giving message to %s\n", DBUS_SERVICE_DBUS); 239 if (!bus_driver_handle_message (connection, transaction, message, &error)) 240 goto out; 241 } 242 else if (!bus_connection_is_active (connection)) /* clients must talk to bus driver first */ 243 { 244 _dbus_verbose ("Received message from non-registered client. Disconnecting.\n"); 245 dbus_connection_close (connection); 246 goto out; 247 } 248 else if (service_name != NULL) /* route to named service */ 249 { 250 DBusString service_string; 251 BusService *service; 252 BusRegistry *registry; 253 254 _dbus_assert (service_name != NULL); 255 256 registry = bus_connection_get_registry (connection); 257 258 _dbus_string_init_const (&service_string, service_name); 259 service = bus_registry_lookup (registry, &service_string); 260 261 if (service == NULL && dbus_message_get_auto_start (message)) 262 { 263 BusActivation *activation; 264 /* We can't do the security policy check here, since the addressed 265 * recipient service doesn't exist yet. We do it before sending the 266 * message after the service has been created. 267 */ 268 activation = bus_connection_get_activation (connection); 269 270 if (!bus_activation_activate_service (activation, connection, transaction, TRUE, 271 message, service_name, &error)) 272 { 273 _DBUS_ASSERT_ERROR_IS_SET (&error); 274 _dbus_verbose ("bus_activation_activate_service() failed: %s\n", error.name); 275 goto out; 276 } 277 278 goto out; 279 } 280 else if (service == NULL) 281 { 282 dbus_set_error (&error, 283 DBUS_ERROR_NAME_HAS_NO_OWNER, 284 "Name \"%s\" does not exist", 285 service_name); 286 goto out; 287 } 288 else 289 { 290 addressed_recipient = bus_service_get_primary_owners_connection (service); 291 _dbus_assert (addressed_recipient != NULL); 292 293 if (!bus_context_check_security_policy (context, transaction, 294 connection, addressed_recipient, 295 addressed_recipient, 296 message, &error)) 297 goto out; 298 299 /* Dispatch the message */ 300 if (!bus_transaction_send (transaction, addressed_recipient, message)) 301 { 302 BUS_SET_OOM (&error); 303 goto out; 304 } 305 } 306 } 307 308 /* Now match the messages against any match rules, which will send 309 * out signals and such. addressed_recipient may == NULL. 310 */ 311 if (!bus_dispatch_matches (transaction, connection, addressed_recipient, message, &error)) 312 goto out; 313 314 out: 315 if (dbus_error_is_set (&error)) 316 { 317 if (!dbus_connection_get_is_connected (connection)) 318 { 319 /* If we disconnected it, we won't bother to send it any error 320 * messages. 321 */ 322 _dbus_verbose ("Not sending error to connection we disconnected\n"); 323 } 324 else if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY)) 325 { 326 bus_connection_send_oom_error (connection, message); 327 328 /* cancel transaction due to OOM */ 329 if (transaction != NULL) 330 { 331 bus_transaction_cancel_and_free (transaction); 332 transaction = NULL; 333 } 334 } 335 else 336 { 337 /* Try to send the real error, if no mem to do that, send 338 * the OOM error 339 */ 340 _dbus_assert (transaction != NULL); 341 if (!bus_transaction_send_error_reply (transaction, connection, 342 &error, message)) 343 { 344 bus_connection_send_oom_error (connection, message); 345 346 /* cancel transaction due to OOM */ 347 if (transaction != NULL) 348 { 349 bus_transaction_cancel_and_free (transaction); 350 transaction = NULL; 351 } 352 } 353 } 354 355 356 dbus_error_free (&error); 357 } 358 359 if (transaction != NULL) 360 { 361 bus_transaction_execute_and_free (transaction); 362 } 363 364 dbus_connection_unref (connection); 365 366 return result; 367} 368 369static DBusHandlerResult 370bus_dispatch_message_filter (DBusConnection *connection, 371 DBusMessage *message, 372 void *user_data) 373{ 374 return bus_dispatch (connection, message); 375} 376 377dbus_bool_t 378bus_dispatch_add_connection (DBusConnection *connection) 379{ 380 if (!dbus_connection_add_filter (connection, 381 bus_dispatch_message_filter, 382 NULL, NULL)) 383 return FALSE; 384 385 return TRUE; 386} 387 388void 389bus_dispatch_remove_connection (DBusConnection *connection) 390{ 391 /* Here we tell the bus driver that we want to get off. */ 392 bus_driver_remove_connection (connection); 393 394 dbus_connection_remove_filter (connection, 395 bus_dispatch_message_filter, 396 NULL); 397} 398 399#ifdef DBUS_BUILD_TESTS 400 401#include <stdio.h> 402 403/* This is used to know whether we need to block in order to finish 404 * sending a message, or whether the initial dbus_connection_send() 405 * already flushed the queue. 406 */ 407#define SEND_PENDING(connection) (dbus_connection_has_messages_to_send (connection)) 408 409typedef dbus_bool_t (* Check1Func) (BusContext *context); 410typedef dbus_bool_t (* Check2Func) (BusContext *context, 411 DBusConnection *connection); 412 413static dbus_bool_t check_no_leftovers (BusContext *context); 414 415static void 416block_connection_until_message_from_bus (BusContext *context, 417 DBusConnection *connection, 418 const char *what_is_expected) 419{ 420 _dbus_verbose ("expecting: %s\n", what_is_expected); 421 422 while (dbus_connection_get_dispatch_status (connection) == 423 DBUS_DISPATCH_COMPLETE && 424 dbus_connection_get_is_connected (connection)) 425 { 426 bus_test_run_bus_loop (context, TRUE); 427 bus_test_run_clients_loop (FALSE); 428 } 429} 430 431static void 432spin_connection_until_authenticated (BusContext *context, 433 DBusConnection *connection) 434{ 435 _dbus_verbose ("Spinning to auth connection %p\n", connection); 436 while (!dbus_connection_get_is_authenticated (connection) && 437 dbus_connection_get_is_connected (connection)) 438 { 439 bus_test_run_bus_loop (context, FALSE); 440 bus_test_run_clients_loop (FALSE); 441 } 442 _dbus_verbose (" ... done spinning to auth connection %p\n", connection); 443} 444 445/* compensate for fact that pop_message() can return #NULL due to OOM */ 446static DBusMessage* 447pop_message_waiting_for_memory (DBusConnection *connection) 448{ 449 while (dbus_connection_get_dispatch_status (connection) == 450 DBUS_DISPATCH_NEED_MEMORY) 451 _dbus_wait_for_memory (); 452 453 return dbus_connection_pop_message (connection); 454} 455 456static DBusMessage* 457borrow_message_waiting_for_memory (DBusConnection *connection) 458{ 459 while (dbus_connection_get_dispatch_status (connection) == 460 DBUS_DISPATCH_NEED_MEMORY) 461 _dbus_wait_for_memory (); 462 463 return dbus_connection_borrow_message (connection); 464} 465 466static void 467warn_unexpected_real (DBusConnection *connection, 468 DBusMessage *message, 469 const char *expected, 470 const char *function, 471 int line) 472{ 473 if (message) 474 _dbus_warn ("%s:%d received message interface \"%s\" member \"%s\" error name \"%s\" on %p, expecting %s\n", 475 function, line, 476 dbus_message_get_interface (message) ? 477 dbus_message_get_interface (message) : "(unset)", 478 dbus_message_get_member (message) ? 479 dbus_message_get_member (message) : "(unset)", 480 dbus_message_get_error_name (message) ? 481 dbus_message_get_error_name (message) : "(unset)", 482 connection, 483 expected); 484 else 485 _dbus_warn ("%s:%d received no message on %p, expecting %s\n", 486 function, line, connection, expected); 487} 488 489#define warn_unexpected(connection, message, expected) \ 490 warn_unexpected_real (connection, message, expected, _DBUS_FUNCTION_NAME, __LINE__) 491 492static void 493verbose_message_received (DBusConnection *connection, 494 DBusMessage *message) 495{ 496 _dbus_verbose ("Received message interface \"%s\" member \"%s\" error name \"%s\" on %p\n", 497 dbus_message_get_interface (message) ? 498 dbus_message_get_interface (message) : "(unset)", 499 dbus_message_get_member (message) ? 500 dbus_message_get_member (message) : "(unset)", 501 dbus_message_get_error_name (message) ? 502 dbus_message_get_error_name (message) : "(unset)", 503 connection); 504} 505 506typedef enum 507{ 508 SERVICE_CREATED, 509 OWNER_CHANGED, 510 SERVICE_DELETED 511} ServiceInfoKind; 512 513typedef struct 514{ 515 ServiceInfoKind expected_kind; 516 const char *expected_service_name; 517 dbus_bool_t failed; 518 DBusConnection *skip_connection; 519} CheckServiceOwnerChangedData; 520 521static dbus_bool_t 522check_service_owner_changed_foreach (DBusConnection *connection, 523 void *data) 524{ 525 CheckServiceOwnerChangedData *d = data; 526 DBusMessage *message; 527 DBusError error; 528 const char *service_name, *old_owner, *new_owner; 529 530 if (d->expected_kind == SERVICE_CREATED 531 && connection == d->skip_connection) 532 return TRUE; 533 534 dbus_error_init (&error); 535 d->failed = TRUE; 536 537 message = pop_message_waiting_for_memory (connection); 538 if (message == NULL) 539 { 540 _dbus_warn ("Did not receive a message on %p, expecting %s\n", 541 connection, "NameOwnerChanged"); 542 goto out; 543 } 544 else if (!dbus_message_is_signal (message, 545 DBUS_INTERFACE_DBUS, 546 "NameOwnerChanged")) 547 { 548 warn_unexpected (connection, message, "NameOwnerChanged"); 549 550 goto out; 551 } 552 else 553 { 554 reget_service_info_data: 555 service_name = NULL; 556 old_owner = NULL; 557 new_owner = NULL; 558 559 dbus_message_get_args (message, &error, 560 DBUS_TYPE_STRING, &service_name, 561 DBUS_TYPE_STRING, &old_owner, 562 DBUS_TYPE_STRING, &new_owner, 563 DBUS_TYPE_INVALID); 564 565 if (dbus_error_is_set (&error)) 566 { 567 if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY)) 568 { 569 dbus_error_free (&error); 570 _dbus_wait_for_memory (); 571 goto reget_service_info_data; 572 } 573 else 574 { 575 _dbus_warn ("Did not get the expected arguments\n"); 576 goto out; 577 } 578 } 579 580 if ((d->expected_kind == SERVICE_CREATED && ( old_owner[0] || !new_owner[0])) 581 || (d->expected_kind == OWNER_CHANGED && (!old_owner[0] || !new_owner[0])) 582 || (d->expected_kind == SERVICE_DELETED && (!old_owner[0] || new_owner[0]))) 583 { 584 _dbus_warn ("inconsistent NameOwnerChanged arguments\n"); 585 goto out; 586 } 587 588 if (strcmp (service_name, d->expected_service_name) != 0) 589 { 590 _dbus_warn ("expected info on service %s, got info on %s\n", 591 d->expected_service_name, 592 service_name); 593 goto out; 594 } 595 596 if (*service_name == ':' && new_owner[0] 597 && strcmp (service_name, new_owner) != 0) 598 { 599 _dbus_warn ("inconsistent ServiceOwnedChanged message (\"%s\" [ %s -> %s ])\n", 600 service_name, old_owner, new_owner); 601 goto out; 602 } 603 } 604 605 d->failed = FALSE; 606 607 out: 608 dbus_error_free (&error); 609 610 if (message) 611 dbus_message_unref (message); 612 613 return !d->failed; 614} 615 616 617static void 618kill_client_connection (BusContext *context, 619 DBusConnection *connection) 620{ 621 char *base_service; 622 const char *s; 623 CheckServiceOwnerChangedData socd; 624 625 _dbus_verbose ("killing connection %p\n", connection); 626 627 s = dbus_bus_get_unique_name (connection); 628 _dbus_assert (s != NULL); 629 630 while ((base_service = _dbus_strdup (s)) == NULL) 631 _dbus_wait_for_memory (); 632 633 dbus_connection_ref (connection); 634 635 /* kick in the disconnect handler that unrefs the connection */ 636 dbus_connection_close (connection); 637 638 bus_test_run_everything (context); 639 640 _dbus_assert (bus_test_client_listed (connection)); 641 642 /* Run disconnect handler in test.c */ 643 if (bus_connection_dispatch_one_message (connection)) 644 _dbus_assert_not_reached ("something received on connection being killed other than the disconnect"); 645 646 _dbus_assert (!dbus_connection_get_is_connected (connection)); 647 dbus_connection_unref (connection); 648 connection = NULL; 649 _dbus_assert (!bus_test_client_listed (connection)); 650 651 socd.expected_kind = SERVICE_DELETED; 652 socd.expected_service_name = base_service; 653 socd.failed = FALSE; 654 socd.skip_connection = NULL; 655 656 bus_test_clients_foreach (check_service_owner_changed_foreach, 657 &socd); 658 659 dbus_free (base_service); 660 661 if (socd.failed) 662 _dbus_assert_not_reached ("didn't get the expected NameOwnerChanged (deletion) messages"); 663 664 if (!check_no_leftovers (context)) 665 _dbus_assert_not_reached ("stuff left in message queues after disconnecting a client"); 666} 667 668static void 669kill_client_connection_unchecked (DBusConnection *connection) 670{ 671 /* This kills the connection without expecting it to affect 672 * the rest of the bus. 673 */ 674 _dbus_verbose ("Unchecked kill of connection %p\n", connection); 675 676 dbus_connection_ref (connection); 677 dbus_connection_close (connection); 678 /* dispatching disconnect handler will unref once */ 679 if (bus_connection_dispatch_one_message (connection)) 680 _dbus_assert_not_reached ("message other than disconnect dispatched after failure to register"); 681 682 _dbus_assert (!bus_test_client_listed (connection)); 683 dbus_connection_unref (connection); 684} 685 686typedef struct 687{ 688 dbus_bool_t failed; 689} CheckNoMessagesData; 690 691static dbus_bool_t 692check_no_messages_foreach (DBusConnection *connection, 693 void *data) 694{ 695 CheckNoMessagesData *d = data; 696 DBusMessage *message; 697 698 message = pop_message_waiting_for_memory (connection); 699 if (message != NULL) 700 { 701 warn_unexpected (connection, message, "no messages"); 702 703 d->failed = TRUE; 704 } 705 706 if (message) 707 dbus_message_unref (message); 708 return !d->failed; 709} 710 711static dbus_bool_t 712check_no_leftovers (BusContext *context) 713{ 714 CheckNoMessagesData nmd; 715 716 nmd.failed = FALSE; 717 bus_test_clients_foreach (check_no_messages_foreach, 718 &nmd); 719 720 if (nmd.failed) 721 { 722 _dbus_verbose ("%s: leftover message found\n", 723 _DBUS_FUNCTION_NAME); 724 return FALSE; 725 } 726 else 727 return TRUE; 728} 729 730/* returns TRUE if the correct thing happens, 731 * but the correct thing may include OOM errors. 732 */ 733static dbus_bool_t 734check_hello_message (BusContext *context, 735 DBusConnection *connection) 736{ 737 DBusMessage *message; 738 DBusMessage *name_message; 739 dbus_uint32_t serial; 740 dbus_bool_t retval; 741 DBusError error; 742 const char *name; 743 const char *acquired; 744 745 retval = FALSE; 746 dbus_error_init (&error); 747 name = NULL; 748 acquired = NULL; 749 message = NULL; 750 name_message = NULL; 751 752 _dbus_verbose ("check_hello_message for %p\n", connection); 753 754 message = dbus_message_new_method_call (DBUS_SERVICE_DBUS, 755 DBUS_PATH_DBUS, 756 DBUS_INTERFACE_DBUS, 757 "Hello"); 758 759 if (message == NULL) 760 return TRUE; 761 762 dbus_connection_ref (connection); /* because we may get disconnected */ 763 764 if (!dbus_connection_send (connection, message, &serial)) 765 { 766 dbus_message_unref (message); 767 dbus_connection_unref (connection); 768 return TRUE; 769 } 770 771 _dbus_assert (dbus_message_has_signature (message, "")); 772 773 dbus_message_unref (message); 774 message = NULL; 775 776 if (!dbus_connection_get_is_connected (connection)) 777 { 778 _dbus_verbose ("connection was disconnected (presumably auth failed)\n"); 779 780 dbus_connection_unref (connection); 781 782 return TRUE; 783 } 784 785 /* send our message */ 786 bus_test_run_clients_loop (SEND_PENDING (connection)); 787 788 if (!dbus_connection_get_is_connected (connection)) 789 { 790 _dbus_verbose ("connection was disconnected (presumably auth failed)\n"); 791 792 dbus_connection_unref (connection); 793 794 return TRUE; 795 } 796 797 block_connection_until_message_from_bus (context, connection, "reply to Hello"); 798 799 if (!dbus_connection_get_is_connected (connection)) 800 { 801 _dbus_verbose ("connection was disconnected (presumably auth failed)\n"); 802 803 dbus_connection_unref (connection); 804 805 return TRUE; 806 } 807 808 dbus_connection_unref (connection); 809 810 message = pop_message_waiting_for_memory (connection); 811 if (message == NULL) 812 { 813 _dbus_warn ("Did not receive a reply to %s %d on %p\n", 814 "Hello", serial, connection); 815 goto out; 816 } 817 818 verbose_message_received (connection, message); 819 820 if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS)) 821 { 822 _dbus_warn ("Message has wrong sender %s\n", 823 dbus_message_get_sender (message) ? 824 dbus_message_get_sender (message) : "(none)"); 825 goto out; 826 } 827 828 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR) 829 { 830 if (dbus_message_is_error (message, 831 DBUS_ERROR_NO_MEMORY)) 832 { 833 ; /* good, this is a valid response */ 834 } 835 else 836 { 837 warn_unexpected (connection, message, "not this error"); 838 839 goto out; 840 } 841 } 842 else 843 { 844 CheckServiceOwnerChangedData socd; 845 846 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_RETURN) 847 { 848 ; /* good, expected */ 849 } 850 else 851 { 852 warn_unexpected (connection, message, "method return for Hello"); 853 854 goto out; 855 } 856 857 retry_get_hello_name: 858 if (!dbus_message_get_args (message, &error, 859 DBUS_TYPE_STRING, &name, 860 DBUS_TYPE_INVALID)) 861 { 862 if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY)) 863 { 864 _dbus_verbose ("no memory to get service name arg from hello\n"); 865 dbus_error_free (&error); 866 _dbus_wait_for_memory (); 867 goto retry_get_hello_name; 868 } 869 else 870 { 871 _dbus_assert (dbus_error_is_set (&error)); 872 _dbus_warn ("Did not get the expected single string argument to hello\n"); 873 goto out; 874 } 875 } 876 877 _dbus_verbose ("Got hello name: %s\n", name); 878 879 while (!dbus_bus_set_unique_name (connection, name)) 880 _dbus_wait_for_memory (); 881 882 socd.expected_kind = SERVICE_CREATED; 883 socd.expected_service_name = name; 884 socd.failed = FALSE; 885 socd.skip_connection = connection; /* we haven't done AddMatch so won't get it ourselves */ 886 bus_test_clients_foreach (check_service_owner_changed_foreach, 887 &socd); 888 889 if (socd.failed) 890 goto out; 891 892 name_message = message; 893 /* Client should also have gotten ServiceAcquired */ 894 895 message = pop_message_waiting_for_memory (connection); 896 if (message == NULL) 897 { 898 _dbus_warn ("Expecting %s, got nothing\n", 899 "NameAcquired"); 900 goto out; 901 } 902 if (! dbus_message_is_signal (message, DBUS_INTERFACE_DBUS, 903 "NameAcquired")) 904 { 905 _dbus_warn ("Expecting %s, got smthg else\n", 906 "NameAcquired"); 907 goto out; 908 } 909 910 retry_get_acquired_name: 911 if (!dbus_message_get_args (message, &error, 912 DBUS_TYPE_STRING, &acquired, 913 DBUS_TYPE_INVALID)) 914 { 915 if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY)) 916 { 917 _dbus_verbose ("no memory to get service name arg from acquired\n"); 918 dbus_error_free (&error); 919 _dbus_wait_for_memory (); 920 goto retry_get_acquired_name; 921 } 922 else 923 { 924 _dbus_assert (dbus_error_is_set (&error)); 925 _dbus_warn ("Did not get the expected single string argument to ServiceAcquired\n"); 926 goto out; 927 } 928 } 929 930 _dbus_verbose ("Got acquired name: %s\n", acquired); 931 932 if (strcmp (acquired, name) != 0) 933 { 934 _dbus_warn ("Acquired name is %s but expected %s\n", 935 acquired, name); 936 goto out; 937 } 938 acquired = NULL; 939 } 940 941 if (!check_no_leftovers (context)) 942 goto out; 943 944 retval = TRUE; 945 946 out: 947 _dbus_verbose ("ending %s retval = %d\n", _DBUS_FUNCTION_NAME, retval); 948 949 dbus_error_free (&error); 950 951 if (message) 952 dbus_message_unref (message); 953 954 if (name_message) 955 dbus_message_unref (name_message); 956 957 return retval; 958} 959 960/* returns TRUE if the correct thing happens, 961 * but the correct thing may include OOM errors. 962 */ 963static dbus_bool_t 964check_double_hello_message (BusContext *context, 965 DBusConnection *connection) 966{ 967 DBusMessage *message; 968 dbus_uint32_t serial; 969 dbus_bool_t retval; 970 DBusError error; 971 972 retval = FALSE; 973 dbus_error_init (&error); 974 message = NULL; 975 976 _dbus_verbose ("check_double_hello_message for %p\n", connection); 977 978 message = dbus_message_new_method_call (DBUS_SERVICE_DBUS, 979 DBUS_PATH_DBUS, 980 DBUS_INTERFACE_DBUS, 981 "Hello"); 982 983 if (message == NULL) 984 return TRUE; 985 986 if (!dbus_connection_send (connection, message, &serial)) 987 { 988 dbus_message_unref (message); 989 return TRUE; 990 } 991 992 dbus_message_unref (message); 993 message = NULL; 994 995 /* send our message */ 996 bus_test_run_clients_loop (SEND_PENDING (connection)); 997 998 dbus_connection_ref (connection); /* because we may get disconnected */ 999 block_connection_until_message_from_bus (context, connection, "reply to Hello"); 1000 1001 if (!dbus_connection_get_is_connected (connection)) 1002 { 1003 _dbus_verbose ("connection was disconnected: %s %d\n", _DBUS_FUNCTION_NAME, __LINE__); 1004 1005 dbus_connection_unref (connection); 1006 1007 return TRUE; 1008 } 1009 1010 dbus_connection_unref (connection); 1011 1012 message = pop_message_waiting_for_memory (connection); 1013 if (message == NULL) 1014 { 1015 _dbus_warn ("Did not receive a reply to %s %d on %p\n", 1016 "Hello", serial, connection); 1017 goto out; 1018 } 1019 1020 verbose_message_received (connection, message); 1021 1022 if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS)) 1023 { 1024 _dbus_warn ("Message has wrong sender %s\n", 1025 dbus_message_get_sender (message) ? 1026 dbus_message_get_sender (message) : "(none)"); 1027 goto out; 1028 } 1029 1030 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR) 1031 { 1032 warn_unexpected (connection, message, "method return for Hello"); 1033 goto out; 1034 } 1035 1036 if (!check_no_leftovers (context)) 1037 goto out; 1038 1039 retval = TRUE; 1040 1041 out: 1042 dbus_error_free (&error); 1043 1044 if (message) 1045 dbus_message_unref (message); 1046 1047 return retval; 1048} 1049 1050/* returns TRUE if the correct thing happens, 1051 * but the correct thing may include OOM errors. 1052 */ 1053static dbus_bool_t 1054check_get_connection_unix_user (BusContext *context, 1055 DBusConnection *connection) 1056{ 1057 DBusMessage *message; 1058 dbus_uint32_t serial; 1059 dbus_bool_t retval; 1060 DBusError error; 1061 const char *base_service_name; 1062 dbus_uint32_t uid; 1063 1064 retval = FALSE; 1065 dbus_error_init (&error); 1066 message = NULL; 1067 1068 _dbus_verbose ("check_get_connection_unix_user for %p\n", connection); 1069 1070 message = dbus_message_new_method_call (DBUS_SERVICE_DBUS, 1071 DBUS_PATH_DBUS, 1072 DBUS_INTERFACE_DBUS, 1073 "GetConnectionUnixUser"); 1074 1075 if (message == NULL) 1076 return TRUE; 1077 1078 base_service_name = dbus_bus_get_unique_name (connection); 1079 1080 if (!dbus_message_append_args (message, 1081 DBUS_TYPE_STRING, &base_service_name, 1082 DBUS_TYPE_INVALID)) 1083 { 1084 dbus_message_unref (message); 1085 return TRUE; 1086 } 1087 1088 if (!dbus_connection_send (connection, message, &serial)) 1089 { 1090 dbus_message_unref (message); 1091 return TRUE; 1092 } 1093 1094 /* send our message */ 1095 bus_test_run_clients_loop (SEND_PENDING (connection)); 1096 1097 dbus_message_unref (message); 1098 message = NULL; 1099 1100 dbus_connection_ref (connection); /* because we may get disconnected */ 1101 block_connection_until_message_from_bus (context, connection, "reply to GetConnectionUnixUser"); 1102 1103 if (!dbus_connection_get_is_connected (connection)) 1104 { 1105 _dbus_verbose ("connection was disconnected: %s %d\n", _DBUS_FUNCTION_NAME, __LINE__); 1106 1107 dbus_connection_unref (connection); 1108 1109 return TRUE; 1110 } 1111 1112 dbus_connection_unref (connection); 1113 1114 message = pop_message_waiting_for_memory (connection); 1115 if (message == NULL) 1116 { 1117 _dbus_warn ("Did not receive a reply to %s %d on %p\n", 1118 "GetConnectionUnixUser", serial, connection); 1119 goto out; 1120 } 1121 1122 verbose_message_received (connection, message); 1123 1124 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR) 1125 { 1126 if (dbus_message_is_error (message, DBUS_ERROR_NO_MEMORY)) 1127 { 1128 ; /* good, this is a valid response */ 1129 } 1130 else 1131 { 1132 warn_unexpected (connection, message, "not this error"); 1133 1134 goto out; 1135 } 1136 } 1137 else 1138 { 1139 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_RETURN) 1140 { 1141 ; /* good, expected */ 1142 } 1143 else 1144 { 1145 warn_unexpected (connection, message, 1146 "method_return for GetConnectionUnixUser"); 1147 1148 goto out; 1149 } 1150 1151 retry_get_property: 1152 1153 if (!dbus_message_get_args (message, &error, 1154 DBUS_TYPE_UINT32, &uid, 1155 DBUS_TYPE_INVALID)) 1156 { 1157 if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY)) 1158 { 1159 _dbus_verbose ("no memory to get uid by GetConnectionUnixUser\n"); 1160 dbus_error_free (&error); 1161 _dbus_wait_for_memory (); 1162 goto retry_get_property; 1163 } 1164 else 1165 { 1166 _dbus_assert (dbus_error_is_set (&error)); 1167 _dbus_warn ("Did not get the expected DBUS_TYPE_UINT32 from GetConnectionUnixUser\n"); 1168 goto out; 1169 } 1170 } 1171 } 1172 1173 if (!check_no_leftovers (context)) 1174 goto out; 1175 1176 retval = TRUE; 1177 1178 out: 1179 dbus_error_free (&error); 1180 1181 if (message) 1182 dbus_message_unref (message); 1183 1184 return retval; 1185} 1186 1187/* returns TRUE if the correct thing happens, 1188 * but the correct thing may include OOM errors. 1189 */ 1190static dbus_bool_t 1191check_get_connection_unix_process_id (BusContext *context, 1192 DBusConnection *connection) 1193{ 1194 DBusMessage *message; 1195 dbus_uint32_t serial; 1196 dbus_bool_t retval; 1197 DBusError error; 1198 const char *base_service_name; 1199 dbus_uint32_t pid; 1200 1201 retval = FALSE; 1202 dbus_error_init (&error); 1203 message = NULL; 1204 1205 _dbus_verbose ("check_get_connection_unix_process_id for %p\n", connection); 1206 1207 message = dbus_message_new_method_call (DBUS_SERVICE_DBUS, 1208 DBUS_PATH_DBUS, 1209 DBUS_INTERFACE_DBUS, 1210 "GetConnectionUnixProcessID"); 1211 1212 if (message == NULL) 1213 return TRUE; 1214 1215 base_service_name = dbus_bus_get_unique_name (connection); 1216 1217 if (!dbus_message_append_args (message, 1218 DBUS_TYPE_STRING, &base_service_name, 1219 DBUS_TYPE_INVALID)) 1220 { 1221 dbus_message_unref (message); 1222 return TRUE; 1223 } 1224 1225 if (!dbus_connection_send (connection, message, &serial)) 1226 { 1227 dbus_message_unref (message); 1228 return TRUE; 1229 } 1230 1231 /* send our message */ 1232 bus_test_run_clients_loop (SEND_PENDING (connection)); 1233 1234 dbus_message_unref (message); 1235 message = NULL; 1236 1237 dbus_connection_ref (connection); /* because we may get disconnected */ 1238 block_connection_until_message_from_bus (context, connection, "reply to GetConnectionUnixProcessID"); 1239 1240 if (!dbus_connection_get_is_connected (connection)) 1241 { 1242 _dbus_verbose ("connection was disconnected: %s %d\n", _DBUS_FUNCTION_NAME, __LINE__); 1243 1244 dbus_connection_unref (connection); 1245 1246 return TRUE; 1247 } 1248 1249 dbus_connection_unref (connection); 1250 1251 message = pop_message_waiting_for_memory (connection); 1252 if (message == NULL) 1253 { 1254 _dbus_warn ("Did not receive a reply to %s %d on %p\n", 1255 "GetConnectionUnixProcessID", serial, connection); 1256 goto out; 1257 } 1258 1259 verbose_message_received (connection, message); 1260 1261 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR) 1262 { 1263 if (dbus_message_is_error (message, DBUS_ERROR_NO_MEMORY)) 1264 { 1265 ; /* good, this is a valid response */ 1266 } 1267 else 1268 { 1269 warn_unexpected (connection, message, "not this error"); 1270 1271 goto out; 1272 } 1273 } 1274 else 1275 { 1276 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_RETURN) 1277 { 1278 ; /* good, expected */ 1279 } 1280 else 1281 { 1282 warn_unexpected (connection, message, 1283 "method_return for GetConnectionUnixProcessID"); 1284 1285 goto out; 1286 } 1287 1288 retry_get_property: 1289 1290 if (!dbus_message_get_args (message, &error, 1291 DBUS_TYPE_UINT32, &pid, 1292 DBUS_TYPE_INVALID)) 1293 { 1294 if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY)) 1295 { 1296 _dbus_verbose ("no memory to get pid by GetConnectionUnixProcessID\n"); 1297 dbus_error_free (&error); 1298 _dbus_wait_for_memory (); 1299 goto retry_get_property; 1300 } 1301 else 1302 { 1303 _dbus_assert (dbus_error_is_set (&error)); 1304 _dbus_warn ("Did not get the expected DBUS_TYPE_UINT32 from GetConnectionUnixProcessID\n"); 1305 goto out; 1306 } 1307 } else { 1308 1309 /* test if returned pid is the same as our own pid 1310 * 1311 * @todo It would probably be good to restructure the tests 1312 * in a way so our parent is the bus that we're testing 1313 * cause then we can test that the pid returned matches 1314 * getppid() 1315 */ 1316 if (pid != (dbus_uint32_t) _dbus_getpid ()) 1317 { 1318 _dbus_assert (dbus_error_is_set (&error)); 1319 _dbus_warn ("Result from GetConnectionUnixProcessID is not our own pid\n"); 1320 goto out; 1321 } 1322 } 1323 } 1324 1325 if (!check_no_leftovers (context)) 1326 goto out; 1327 1328 retval = TRUE; 1329 1330 out: 1331 dbus_error_free (&error); 1332 1333 if (message) 1334 dbus_message_unref (message); 1335 1336 return retval; 1337} 1338 1339/* returns TRUE if the correct thing happens, 1340 * but the correct thing may include OOM errors. 1341 */ 1342static dbus_bool_t 1343check_add_match_all (BusContext *context, 1344 DBusConnection *connection) 1345{ 1346 DBusMessage *message; 1347 dbus_bool_t retval; 1348 dbus_uint32_t serial; 1349 DBusError error; 1350 const char *empty = ""; 1351 1352 retval = FALSE; 1353 dbus_error_init (&error); 1354 message = NULL; 1355 1356 _dbus_verbose ("check_add_match_all for %p\n", connection); 1357 1358 message = dbus_message_new_method_call (DBUS_SERVICE_DBUS, 1359 DBUS_PATH_DBUS, 1360 DBUS_INTERFACE_DBUS, 1361 "AddMatch"); 1362 1363 if (message == NULL) 1364 return TRUE; 1365 1366 /* empty string match rule matches everything */ 1367 if (!dbus_message_append_args (message, DBUS_TYPE_STRING, &empty, 1368 DBUS_TYPE_INVALID)) 1369 { 1370 dbus_message_unref (message); 1371 return TRUE; 1372 } 1373 1374 if (!dbus_connection_send (connection, message, &serial)) 1375 { 1376 dbus_message_unref (message); 1377 return TRUE; 1378 } 1379 1380 dbus_message_unref (message); 1381 message = NULL; 1382 1383 dbus_connection_ref (connection); /* because we may get disconnected */ 1384 1385 /* send our message */ 1386 bus_test_run_clients_loop (SEND_PENDING (connection)); 1387 1388 if (!dbus_connection_get_is_connected (connection)) 1389 { 1390 _dbus_verbose ("connection was disconnected: %s %d\n", _DBUS_FUNCTION_NAME, __LINE__); 1391 1392 dbus_connection_unref (connection); 1393 1394 return TRUE; 1395 } 1396 1397 block_connection_until_message_from_bus (context, connection, "reply to AddMatch"); 1398 1399 if (!dbus_connection_get_is_connected (connection)) 1400 { 1401 _dbus_verbose ("connection was disconnected: %s %d\n", _DBUS_FUNCTION_NAME, __LINE__); 1402 1403 dbus_connection_unref (connection); 1404 1405 return TRUE; 1406 } 1407 1408 dbus_connection_unref (connection); 1409 1410 message = pop_message_waiting_for_memory (connection); 1411 if (message == NULL) 1412 { 1413 _dbus_warn ("Did not receive a reply to %s %d on %p\n", 1414 "AddMatch", serial, connection); 1415 goto out; 1416 } 1417 1418 verbose_message_received (connection, message); 1419 1420 if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS)) 1421 { 1422 _dbus_warn ("Message has wrong sender %s\n", 1423 dbus_message_get_sender (message) ? 1424 dbus_message_get_sender (message) : "(none)"); 1425 goto out; 1426 } 1427 1428 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR) 1429 { 1430 if (dbus_message_is_error (message, 1431 DBUS_ERROR_NO_MEMORY)) 1432 { 1433 ; /* good, this is a valid response */ 1434 } 1435 else 1436 { 1437 warn_unexpected (connection, message, "not this error"); 1438 1439 goto out; 1440 } 1441 } 1442 else 1443 { 1444 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_RETURN) 1445 { 1446 ; /* good, expected */ 1447 _dbus_assert (dbus_message_get_reply_serial (message) == serial); 1448 } 1449 else 1450 { 1451 warn_unexpected (connection, message, "method return for AddMatch"); 1452 1453 goto out; 1454 } 1455 } 1456 1457 if (!check_no_leftovers (context)) 1458 goto out; 1459 1460 retval = TRUE; 1461 1462 out: 1463 dbus_error_free (&error); 1464 1465 if (message) 1466 dbus_message_unref (message); 1467 1468 return retval; 1469} 1470 1471/* returns TRUE if the correct thing happens, 1472 * but the correct thing may include OOM errors. 1473 */ 1474static dbus_bool_t 1475check_hello_connection (BusContext *context) 1476{ 1477 DBusConnection *connection; 1478 DBusError error; 1479 1480 dbus_error_init (&error); 1481 1482 connection = dbus_connection_open_private ("debug-pipe:name=test-server", &error); 1483 if (connection == NULL) 1484 { 1485 _DBUS_ASSERT_ERROR_IS_SET (&error); 1486 dbus_error_free (&error); 1487 return TRUE; 1488 } 1489 1490 if (!bus_setup_debug_client (connection)) 1491 { 1492 dbus_connection_close (connection); 1493 dbus_connection_unref (connection); 1494 return TRUE; 1495 } 1496 1497 spin_connection_until_authenticated (context, connection); 1498 1499 if (!check_hello_message (context, connection)) 1500 return FALSE; 1501 1502 if (dbus_bus_get_unique_name (connection) == NULL) 1503 { 1504 /* We didn't successfully register, so we can't 1505 * do the usual kill_client_connection() checks 1506 */ 1507 kill_client_connection_unchecked (connection); 1508 } 1509 else 1510 { 1511 if (!check_add_match_all (context, connection)) 1512 return FALSE; 1513 1514 kill_client_connection (context, connection); 1515 } 1516 1517 return TRUE; 1518} 1519 1520#define NONEXISTENT_SERVICE_NAME "test.this.service.does.not.exist.ewuoiurjdfxcvn" 1521 1522/* returns TRUE if the correct thing happens, 1523 * but the correct thing may include OOM errors. 1524 */ 1525static dbus_bool_t 1526check_nonexistent_service_no_auto_start (BusContext *context, 1527 DBusConnection *connection) 1528{ 1529 DBusMessage *message; 1530 dbus_uint32_t serial; 1531 dbus_bool_t retval; 1532 const char *nonexistent = NONEXISTENT_SERVICE_NAME; 1533 dbus_uint32_t flags; 1534 1535 message = dbus_message_new_method_call (DBUS_SERVICE_DBUS, 1536 DBUS_PATH_DBUS, 1537 DBUS_INTERFACE_DBUS, 1538 "StartServiceByName"); 1539 1540 if (message == NULL) 1541 return TRUE; 1542 1543 dbus_message_set_auto_start (message, FALSE); 1544 1545 flags = 0; 1546 if (!dbus_message_append_args (message, 1547 DBUS_TYPE_STRING, &nonexistent, 1548 DBUS_TYPE_UINT32, &flags, 1549 DBUS_TYPE_INVALID)) 1550 { 1551 dbus_message_unref (message); 1552 return TRUE; 1553 } 1554 1555 if (!dbus_connection_send (connection, message, &serial)) 1556 { 1557 dbus_message_unref (message); 1558 return TRUE; 1559 } 1560 1561 dbus_message_unref (message); 1562 message = NULL; 1563 1564 bus_test_run_everything (context); 1565 block_connection_until_message_from_bus (context, connection, "reply to ActivateService on nonexistent"); 1566 bus_test_run_everything (context); 1567 1568 if (!dbus_connection_get_is_connected (connection)) 1569 { 1570 _dbus_verbose ("connection was disconnected: %s %d\n", _DBUS_FUNCTION_NAME, __LINE__); 1571 return TRUE; 1572 } 1573 1574 retval = FALSE; 1575 1576 message = pop_message_waiting_for_memory (connection); 1577 if (message == NULL) 1578 { 1579 _dbus_warn ("Did not receive a reply to %s %d on %p\n", 1580 "StartServiceByName", serial, connection); 1581 goto out; 1582 } 1583 1584 verbose_message_received (connection, message); 1585 1586 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR) 1587 { 1588 if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS)) 1589 { 1590 _dbus_warn ("Message has wrong sender %s\n", 1591 dbus_message_get_sender (message) ? 1592 dbus_message_get_sender (message) : "(none)"); 1593 goto out; 1594 } 1595 1596 if (dbus_message_is_error (message, 1597 DBUS_ERROR_NO_MEMORY)) 1598 { 1599 ; /* good, this is a valid response */ 1600 } 1601 else if (dbus_message_is_error (message, 1602 DBUS_ERROR_SERVICE_UNKNOWN)) 1603 { 1604 ; /* good, this is expected also */ 1605 } 1606 else 1607 { 1608 warn_unexpected (connection, message, "not this error"); 1609 goto out; 1610 } 1611 } 1612 else 1613 { 1614 _dbus_warn ("Did not expect to successfully activate %s\n", 1615 NONEXISTENT_SERVICE_NAME); 1616 goto out; 1617 } 1618 1619 retval = TRUE; 1620 1621 out: 1622 if (message) 1623 dbus_message_unref (message); 1624 1625 return retval; 1626} 1627 1628/* returns TRUE if the correct thing happens, 1629 * but the correct thing may include OOM errors. 1630 */ 1631static dbus_bool_t 1632check_nonexistent_service_auto_start (BusContext *context, 1633 DBusConnection *connection) 1634{ 1635 DBusMessage *message; 1636 dbus_uint32_t serial; 1637 dbus_bool_t retval; 1638 1639 message = dbus_message_new_method_call (NONEXISTENT_SERVICE_NAME, 1640 "/org/freedesktop/TestSuite", 1641 "org.freedesktop.TestSuite", 1642 "Echo"); 1643 1644 if (message == NULL) 1645 return TRUE; 1646 1647 if (!dbus_connection_send (connection, message, &serial)) 1648 { 1649 dbus_message_unref (message); 1650 return TRUE; 1651 } 1652 1653 dbus_message_unref (message); 1654 message = NULL; 1655 1656 bus_test_run_everything (context); 1657 block_connection_until_message_from_bus (context, connection, "reply to Echo"); 1658 bus_test_run_everything (context); 1659 1660 if (!dbus_connection_get_is_connected (connection)) 1661 { 1662 _dbus_verbose ("connection was disconnected: %s %d\n", _DBUS_FUNCTION_NAME, __LINE__); 1663 return TRUE; 1664 } 1665 1666 retval = FALSE; 1667 1668 message = pop_message_waiting_for_memory (connection); 1669 1670 if (message == NULL) 1671 { 1672 _dbus_warn ("Did not receive a reply to %s %d on %p\n", 1673 "Echo message (auto activation)", serial, connection); 1674 goto out; 1675 } 1676 1677 verbose_message_received (connection, message); 1678 1679 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR) 1680 { 1681 if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS)) 1682 { 1683 _dbus_warn ("Message has wrong sender %s\n", 1684 dbus_message_get_sender (message) ? 1685 dbus_message_get_sender (message) : "(none)"); 1686 goto out; 1687 } 1688 1689 if (dbus_message_is_error (message, 1690 DBUS_ERROR_NO_MEMORY)) 1691 { 1692 ; /* good, this is a valid response */ 1693 } 1694 else if (dbus_message_is_error (message, 1695 DBUS_ERROR_SERVICE_UNKNOWN)) 1696 { 1697 ; /* good, this is expected also */ 1698 } 1699 else 1700 { 1701 warn_unexpected (connection, message, "not this error"); 1702 goto out; 1703 } 1704 } 1705 else 1706 { 1707 _dbus_warn ("Did not expect to successfully activate %s\n", 1708 NONEXISTENT_SERVICE_NAME); 1709 goto out; 1710 } 1711 1712 retval = TRUE; 1713 1714 out: 1715 if (message) 1716 dbus_message_unref (message); 1717 1718 return retval; 1719} 1720 1721static dbus_bool_t 1722check_base_service_activated (BusContext *context, 1723 DBusConnection *connection, 1724 DBusMessage *initial_message, 1725 const char **base_service_p) 1726{ 1727 DBusMessage *message; 1728 dbus_bool_t retval; 1729 DBusError error; 1730 const char *base_service, *base_service_from_bus, *old_owner; 1731 1732 retval = FALSE; 1733 1734 dbus_error_init (&error); 1735 base_service = NULL; 1736 old_owner = NULL; 1737 base_service_from_bus = NULL; 1738 1739 message = initial_message; 1740 dbus_message_ref (message); 1741 1742 if (dbus_message_is_signal (message, 1743 DBUS_INTERFACE_DBUS, 1744 "NameOwnerChanged")) 1745 { 1746 CheckServiceOwnerChangedData socd; 1747 1748 reget_service_name_arg: 1749 base_service = NULL; 1750 old_owner = NULL; 1751 base_service_from_bus = NULL; 1752 1753 if (!dbus_message_get_args (message, &error, 1754 DBUS_TYPE_STRING, &base_service, 1755 DBUS_TYPE_STRING, &old_owner, 1756 DBUS_TYPE_STRING, &base_service_from_bus, 1757 DBUS_TYPE_INVALID)) 1758 { 1759 if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY)) 1760 { 1761 dbus_error_free (&error); 1762 _dbus_wait_for_memory (); 1763 goto reget_service_name_arg; 1764 } 1765 else 1766 { 1767 _dbus_warn ("Message %s doesn't have a service name: %s\n", 1768 "NameOwnerChanged (creation)", 1769 error.message); 1770 goto out; 1771 } 1772 } 1773 1774 if (*base_service != ':') 1775 { 1776 _dbus_warn ("Expected base service activation, got \"%s\" instead\n", 1777 base_service); 1778 goto out; 1779 } 1780 1781 if (strcmp (base_service, base_service_from_bus) != 0) 1782 { 1783 _dbus_warn ("Expected base service activation, got \"%s\" instead with owner \"%s\"\n", 1784 base_service, base_service_from_bus); 1785 goto out; 1786 } 1787 1788 if (old_owner[0]) 1789 { 1790 _dbus_warn ("Received an old_owner argument during base service activation, \"%s\"\n", 1791 old_owner); 1792 goto out; 1793 } 1794 1795 socd.expected_kind = SERVICE_CREATED; 1796 socd.expected_service_name = base_service; 1797 socd.failed = FALSE; 1798 socd.skip_connection = connection; 1799 bus_test_clients_foreach (check_service_owner_changed_foreach, 1800 &socd); 1801 1802 if (socd.failed) 1803 goto out; 1804 } 1805 else 1806 { 1807 warn_unexpected (connection, message, "NameOwnerChanged (creation) for base service"); 1808 1809 goto out; 1810 } 1811 1812 if (base_service_p) 1813 *base_service_p = base_service; 1814 1815 retval = TRUE; 1816 1817 out: 1818 if (message) 1819 dbus_message_unref (message); 1820 dbus_error_free (&error); 1821 1822 return retval; 1823} 1824 1825static dbus_bool_t 1826check_service_activated (BusContext *context, 1827 DBusConnection *connection, 1828 const char *activated_name, 1829 const char *base_service_name, 1830 DBusMessage *initial_message) 1831{ 1832 DBusMessage *message; 1833 dbus_bool_t retval; 1834 DBusError error; 1835 dbus_uint32_t activation_result; 1836 1837 retval = FALSE; 1838 1839 dbus_error_init (&error); 1840 1841 message = initial_message; 1842 dbus_message_ref (message); 1843 1844 if (dbus_message_is_signal (message, 1845 DBUS_INTERFACE_DBUS, 1846 "NameOwnerChanged")) 1847 { 1848 CheckServiceOwnerChangedData socd; 1849 const char *service_name, *base_service_from_bus, *old_owner; 1850 1851 reget_service_name_arg: 1852 service_name = NULL; 1853 old_owner = NULL; 1854 base_service_from_bus = NULL; 1855 1856 if (!dbus_message_get_args (message, &error, 1857 DBUS_TYPE_STRING, &service_name, 1858 DBUS_TYPE_STRING, &old_owner, 1859 DBUS_TYPE_STRING, &base_service_from_bus, 1860 DBUS_TYPE_INVALID)) 1861 { 1862 if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY)) 1863 { 1864 dbus_error_free (&error); 1865 _dbus_wait_for_memory (); 1866 goto reget_service_name_arg; 1867 } 1868 else 1869 { 1870 _dbus_warn ("Message %s doesn't have a service name: %s\n", 1871 "NameOwnerChanged (creation)", 1872 error.message); 1873 goto out; 1874 } 1875 } 1876 1877 if (strcmp (service_name, activated_name) != 0) 1878 { 1879 _dbus_warn ("Expected to see service %s created, saw %s instead\n", 1880 activated_name, service_name); 1881 goto out; 1882 } 1883 1884 if (strcmp (base_service_name, base_service_from_bus) != 0) 1885 { 1886 _dbus_warn ("NameOwnerChanged reports wrong base service: %s owner, expected %s instead\n", 1887 base_service_from_bus, base_service_name); 1888 goto out; 1889 } 1890 1891 if (old_owner[0]) 1892 { 1893 _dbus_warn ("expected a %s, got a %s\n", 1894 "NameOwnerChanged (creation)", 1895 "NameOwnerChanged (change)"); 1896 goto out; 1897 } 1898 1899 socd.expected_kind = SERVICE_CREATED; 1900 socd.skip_connection = connection; 1901 socd.failed = FALSE; 1902 socd.expected_service_name = service_name; 1903 bus_test_clients_foreach (check_service_owner_changed_foreach, 1904 &socd); 1905 1906 if (socd.failed) 1907 goto out; 1908 1909 dbus_message_unref (message); 1910 service_name = NULL; 1911 old_owner = NULL; 1912 base_service_from_bus = NULL; 1913 1914 message = pop_message_waiting_for_memory (connection); 1915 if (message == NULL) 1916 { 1917 _dbus_warn ("Expected a reply to %s, got nothing\n", 1918 "StartServiceByName"); 1919 goto out; 1920 } 1921 } 1922 else 1923 { 1924 warn_unexpected (connection, message, "NameOwnerChanged for the activated name"); 1925 1926 goto out; 1927 } 1928 1929 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_RETURN) 1930 { 1931 warn_unexpected (connection, message, "reply to StartServiceByName"); 1932 1933 goto out; 1934 } 1935 1936 activation_result = 0; 1937 if (!dbus_message_get_args (message, &error, 1938 DBUS_TYPE_UINT32, &activation_result, 1939 DBUS_TYPE_INVALID)) 1940 { 1941 if (!dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY)) 1942 { 1943 _dbus_warn ("Did not have activation result first argument to %s: %s\n", 1944 "StartServiceByName", error.message); 1945 goto out; 1946 } 1947 1948 dbus_error_free (&error); 1949 } 1950 else 1951 { 1952 if (activation_result == DBUS_START_REPLY_SUCCESS) 1953 ; /* Good */ 1954 else if (activation_result == DBUS_START_REPLY_ALREADY_RUNNING) 1955 ; /* Good also */ 1956 else 1957 { 1958 _dbus_warn ("Activation result was %u, no good.\n", 1959 activation_result); 1960 goto out; 1961 } 1962 } 1963 1964 dbus_message_unref (message); 1965 message = NULL; 1966 1967 if (!check_no_leftovers (context)) 1968 { 1969 _dbus_warn ("Messages were left over after verifying existent activation results\n"); 1970 goto out; 1971 } 1972 1973 retval = TRUE; 1974 1975 out: 1976 if (message) 1977 dbus_message_unref (message); 1978 dbus_error_free (&error); 1979 1980 return retval; 1981} 1982 1983static dbus_bool_t 1984check_service_auto_activated (BusContext *context, 1985 DBusConnection *connection, 1986 const char *activated_name, 1987 const char *base_service_name, 1988 DBusMessage *initial_message) 1989{ 1990 DBusMessage *message; 1991 dbus_bool_t retval; 1992 DBusError error; 1993 1994 retval = FALSE; 1995 1996 dbus_error_init (&error); 1997 1998 message = initial_message; 1999 dbus_message_ref (message); 2000 2001 if (dbus_message_is_signal (message, 2002 DBUS_INTERFACE_DBUS, 2003 "NameOwnerChanged")) 2004 { 2005 const char *service_name; 2006 CheckServiceOwnerChangedData socd; 2007 2008 reget_service_name_arg: 2009 if (!dbus_message_get_args (message, &error, 2010 DBUS_TYPE_STRING, &service_name, 2011 DBUS_TYPE_INVALID)) 2012 { 2013 if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY)) 2014 { 2015 dbus_error_free (&error); 2016 _dbus_wait_for_memory (); 2017 goto reget_service_name_arg; 2018 } 2019 else 2020 { 2021 _dbus_warn ("Message %s doesn't have a service name: %s\n", 2022 "NameOwnerChanged", 2023 error.message); 2024 dbus_error_free (&error); 2025 goto out; 2026 } 2027 } 2028 2029 if (strcmp (service_name, activated_name) != 0) 2030 { 2031 _dbus_warn ("Expected to see service %s created, saw %s instead\n", 2032 activated_name, service_name); 2033 goto out; 2034 } 2035 2036 socd.expected_kind = SERVICE_CREATED; 2037 socd.expected_service_name = service_name; 2038 socd.failed = FALSE; 2039 socd.skip_connection = connection; 2040 bus_test_clients_foreach (check_service_owner_changed_foreach, 2041 &socd); 2042 2043 if (socd.failed) 2044 goto out; 2045 2046 /* Note that this differs from regular activation in that we don't get a 2047 * reply to ActivateService here. 2048 */ 2049 2050 dbus_message_unref (message); 2051 message = NULL; 2052 service_name = NULL; 2053 } 2054 else 2055 { 2056 warn_unexpected (connection, message, "NameOwnerChanged for the activated name"); 2057 2058 goto out; 2059 } 2060 2061 retval = TRUE; 2062 2063 out: 2064 if (message) 2065 dbus_message_unref (message); 2066 2067 return retval; 2068} 2069 2070static dbus_bool_t 2071check_service_deactivated (BusContext *context, 2072 DBusConnection *connection, 2073 const char *activated_name, 2074 const char *base_service) 2075{ 2076 dbus_bool_t retval; 2077 CheckServiceOwnerChangedData socd; 2078 2079 retval = FALSE; 2080 2081 /* Now we are expecting ServiceOwnerChanged (deletion) messages for the base 2082 * service and the activated_name. The base service 2083 * notification is required to come last. 2084 */ 2085 socd.expected_kind = SERVICE_DELETED; 2086 socd.expected_service_name = activated_name; 2087 socd.failed = FALSE; 2088 socd.skip_connection = NULL; 2089 bus_test_clients_foreach (check_service_owner_changed_foreach, 2090 &socd); 2091 2092 if (socd.failed) 2093 goto out; 2094 2095 socd.expected_kind = SERVICE_DELETED; 2096 socd.expected_service_name = base_service; 2097 socd.failed = FALSE; 2098 socd.skip_connection = NULL; 2099 bus_test_clients_foreach (check_service_owner_changed_foreach, 2100 &socd); 2101 2102 if (socd.failed) 2103 goto out; 2104 2105 retval = TRUE; 2106 2107 out: 2108 return retval; 2109} 2110 2111static dbus_bool_t 2112check_send_exit_to_service (BusContext *context, 2113 DBusConnection *connection, 2114 const char *service_name, 2115 const char *base_service) 2116{ 2117 dbus_bool_t got_error; 2118 DBusMessage *message; 2119 dbus_uint32_t serial; 2120 dbus_bool_t retval; 2121 2122 _dbus_verbose ("Sending exit message to the test service\n"); 2123 2124 retval = FALSE; 2125 2126 /* Kill off the test service by sending it a quit message */ 2127 message = dbus_message_new_method_call (service_name, 2128 "/org/freedesktop/TestSuite", 2129 "org.freedesktop.TestSuite", 2130 "Exit"); 2131 2132 if (message == NULL) 2133 { 2134 /* Do this again; we still need the service to exit... */ 2135 if (!check_send_exit_to_service (context, connection, 2136 service_name, base_service)) 2137 goto out; 2138 2139 return TRUE; 2140 } 2141 2142 if (!dbus_connection_send (connection, message, &serial)) 2143 { 2144 dbus_message_unref (message); 2145 2146 /* Do this again; we still need the service to exit... */ 2147 if (!check_send_exit_to_service (context, connection, 2148 service_name, base_service)) 2149 goto out; 2150 2151 return TRUE; 2152 } 2153 2154 dbus_message_unref (message); 2155 message = NULL; 2156 2157 /* send message */ 2158 bus_test_run_clients_loop (SEND_PENDING (connection)); 2159 2160 /* read it in and write it out to test service */ 2161 bus_test_run_bus_loop (context, FALSE); 2162 2163 /* see if we got an error during message bus dispatching */ 2164 bus_test_run_clients_loop (FALSE); 2165 message = borrow_message_waiting_for_memory (connection); 2166 got_error = message != NULL && dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR; 2167 if (message) 2168 { 2169 dbus_connection_return_message (connection, message); 2170 message = NULL; 2171 } 2172 2173 if (!got_error) 2174 { 2175 /* If no error, wait for the test service to exit */ 2176 block_connection_until_message_from_bus (context, connection, "test service to exit"); 2177 2178 bus_test_run_everything (context); 2179 } 2180 2181 if (got_error) 2182 { 2183 message = pop_message_waiting_for_memory (connection); 2184 _dbus_assert (message != NULL); 2185 2186 if (dbus_message_get_reply_serial (message) != serial) 2187 { 2188 warn_unexpected (connection, message, 2189 "error with the correct reply serial"); 2190 goto out; 2191 } 2192 2193 if (!dbus_message_is_error (message, 2194 DBUS_ERROR_NO_MEMORY)) 2195 { 2196 warn_unexpected (connection, message, 2197 "a no memory error from asking test service to exit"); 2198 goto out; 2199 } 2200 2201 _dbus_verbose ("Got error %s when asking test service to exit\n", 2202 dbus_message_get_error_name (message)); 2203 2204 /* Do this again; we still need the service to exit... */ 2205 if (!check_send_exit_to_service (context, connection, 2206 service_name, base_service)) 2207 goto out; 2208 } 2209 else 2210 { 2211 if (!check_service_deactivated (context, connection, 2212 service_name, base_service)) 2213 goto out; 2214 2215 /* Should now have a NoReply error from the Exit() method 2216 * call; it should have come after all the deactivation 2217 * stuff. 2218 */ 2219 message = pop_message_waiting_for_memory (connection); 2220 2221 if (message == NULL) 2222 { 2223 warn_unexpected (connection, NULL, 2224 "reply to Exit() method call"); 2225 goto out; 2226 } 2227 if (!dbus_message_is_error (message, 2228 DBUS_ERROR_NO_REPLY)) 2229 { 2230 warn_unexpected (connection, message, 2231 "NoReply error from Exit() method call"); 2232 goto out; 2233 } 2234 2235 if (dbus_message_get_reply_serial (message) != serial) 2236 { 2237 warn_unexpected (connection, message, 2238 "error with the correct reply serial"); 2239 goto out; 2240 } 2241 2242 _dbus_verbose ("Got error %s after test service exited\n", 2243 dbus_message_get_error_name (message)); 2244 2245 if (!check_no_leftovers (context)) 2246 { 2247 _dbus_warn ("Messages were left over after %s\n", 2248 _DBUS_FUNCTION_NAME); 2249 goto out; 2250 } 2251 } 2252 2253 retval = TRUE; 2254 2255 out: 2256 if (message) 2257 dbus_message_unref (message); 2258 2259 return retval; 2260} 2261 2262static dbus_bool_t 2263check_got_error (BusContext *context, 2264 DBusConnection *connection, 2265 const char *first_error_name, 2266 ...) 2267{ 2268 DBusMessage *message; 2269 dbus_bool_t retval; 2270 va_list ap; 2271 dbus_bool_t error_found; 2272 const char *error_name; 2273 2274 retval = FALSE; 2275 2276 message = pop_message_waiting_for_memory (connection); 2277 if (message == NULL) 2278 { 2279 _dbus_warn ("Did not get an expected error\n"); 2280 goto out; 2281 } 2282 2283 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR) 2284 { 2285 warn_unexpected (connection, message, "an error"); 2286 2287 goto out; 2288 } 2289 2290 error_found = FALSE; 2291 2292 va_start (ap, first_error_name); 2293 error_name = first_error_name; 2294 while (error_name != NULL) 2295 { 2296 if (dbus_message_is_error (message, error_name)) 2297 { 2298 error_found = TRUE; 2299 break; 2300 } 2301 error_name = va_arg (ap, char*); 2302 } 2303 va_end (ap); 2304 2305 if (!error_found) 2306 { 2307 _dbus_warn ("Expected error %s or other, got %s instead\n", 2308 first_error_name, 2309 dbus_message_get_error_name (message)); 2310 goto out; 2311 } 2312 2313 retval = TRUE; 2314 2315 out: 2316 if (message) 2317 dbus_message_unref (message); 2318 2319 return retval; 2320} 2321 2322typedef enum 2323{ 2324 GOT_SERVICE_CREATED, 2325 GOT_SERVICE_DELETED, 2326 GOT_ERROR, 2327 GOT_SOMETHING_ELSE 2328} GotServiceInfo; 2329 2330static GotServiceInfo 2331check_got_service_info (DBusMessage *message) 2332{ 2333 GotServiceInfo message_kind; 2334 2335 if (dbus_message_is_signal (message, 2336 DBUS_INTERFACE_DBUS, 2337 "NameOwnerChanged")) 2338 { 2339 DBusError error; 2340 const char *service_name, *old_owner, *new_owner; 2341 dbus_error_init (&error); 2342 2343 reget_service_info_data: 2344 service_name = NULL; 2345 old_owner = NULL; 2346 new_owner = NULL; 2347 2348 dbus_message_get_args (message, &error, 2349 DBUS_TYPE_STRING, &service_name, 2350 DBUS_TYPE_STRING, &old_owner, 2351 DBUS_TYPE_STRING, &new_owner, 2352 DBUS_TYPE_INVALID); 2353 if (dbus_error_is_set (&error)) 2354 { 2355 if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY)) 2356 { 2357 dbus_error_free (&error); 2358 goto reget_service_info_data; 2359 } 2360 else 2361 { 2362 _dbus_warn ("unexpected arguments for NameOwnerChanged message\n"); 2363 message_kind = GOT_SOMETHING_ELSE; 2364 } 2365 } 2366 else if (!old_owner[0]) 2367 message_kind = GOT_SERVICE_CREATED; 2368 else if (!new_owner[0]) 2369 message_kind = GOT_SERVICE_DELETED; 2370 else 2371 message_kind = GOT_SOMETHING_ELSE; 2372 2373 dbus_error_free (&error); 2374 } 2375 else if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR) 2376 message_kind = GOT_ERROR; 2377 else 2378 message_kind = GOT_SOMETHING_ELSE; 2379 2380 return message_kind; 2381} 2382 2383#define EXISTENT_SERVICE_NAME "org.freedesktop.DBus.TestSuiteEchoService" 2384 2385/* returns TRUE if the correct thing happens, 2386 * but the correct thing may include OOM errors. 2387 */ 2388static dbus_bool_t 2389check_existent_service_no_auto_start (BusContext *context, 2390 DBusConnection *connection) 2391{ 2392 DBusMessage *message; 2393 DBusMessage *base_service_message; 2394 const char *base_service; 2395 dbus_uint32_t serial; 2396 dbus_bool_t retval; 2397 const char *existent = EXISTENT_SERVICE_NAME; 2398 dbus_uint32_t flags; 2399 2400 base_service_message = NULL; 2401 2402 message = dbus_message_new_method_call (DBUS_SERVICE_DBUS, 2403 DBUS_PATH_DBUS, 2404 DBUS_INTERFACE_DBUS, 2405 "StartServiceByName"); 2406 2407 if (message == NULL) 2408 return TRUE; 2409 2410 dbus_message_set_auto_start (message, FALSE); 2411 2412 flags = 0; 2413 if (!dbus_message_append_args (message, 2414 DBUS_TYPE_STRING, &existent, 2415 DBUS_TYPE_UINT32, &flags, 2416 DBUS_TYPE_INVALID)) 2417 { 2418 dbus_message_unref (message); 2419 return TRUE; 2420 } 2421 2422 if (!dbus_connection_send (connection, message, &serial)) 2423 { 2424 dbus_message_unref (message); 2425 return TRUE; 2426 } 2427 2428 dbus_message_unref (message); 2429 message = NULL; 2430 2431 bus_test_run_everything (context); 2432 2433 /* now wait for the message bus to hear back from the activated 2434 * service. 2435 */ 2436 block_connection_until_message_from_bus (context, connection, "activated service to connect"); 2437 2438 bus_test_run_everything (context); 2439 2440 if (!dbus_connection_get_is_connected (connection)) 2441 { 2442 _dbus_verbose ("connection was disconnected: %s %d\n", _DBUS_FUNCTION_NAME, __LINE__); 2443 return TRUE; 2444 } 2445 2446 retval = FALSE; 2447 2448 message = pop_message_waiting_for_memory (connection); 2449 if (message == NULL) 2450 { 2451 _dbus_warn ("Did not receive any messages after %s %d on %p\n", 2452 "StartServiceByName", serial, connection); 2453 goto out; 2454 } 2455 2456 verbose_message_received (connection, message); 2457 _dbus_verbose (" (after sending %s)\n", "StartServiceByName"); 2458 2459 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR) 2460 { 2461 if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS)) 2462 { 2463 _dbus_warn ("Message has wrong sender %s\n", 2464 dbus_message_get_sender (message) ? 2465 dbus_message_get_sender (message) : "(none)"); 2466 goto out; 2467 } 2468 2469 if (dbus_message_is_error (message, 2470 DBUS_ERROR_NO_MEMORY)) 2471 { 2472 ; /* good, this is a valid response */ 2473 } 2474 else if (dbus_message_is_error (message, 2475 DBUS_ERROR_SPAWN_CHILD_EXITED) || 2476 dbus_message_is_error (message, 2477 DBUS_ERROR_SPAWN_CHILD_SIGNALED) || 2478 dbus_message_is_error (message, 2479 DBUS_ERROR_SPAWN_EXEC_FAILED)) 2480 { 2481 ; /* good, this is expected also */ 2482 } 2483 else 2484 { 2485 _dbus_warn ("Did not expect error %s\n", 2486 dbus_message_get_error_name (message)); 2487 goto out; 2488 } 2489 } 2490 else 2491 { 2492 GotServiceInfo message_kind; 2493 2494 if (!check_base_service_activated (context, connection, 2495 message, &base_service)) 2496 goto out; 2497 2498 base_service_message = message; 2499 message = NULL; 2500 2501 /* We may need to block here for the test service to exit or finish up */ 2502 block_connection_until_message_from_bus (context, connection, "test service to exit or finish up"); 2503 2504 message = dbus_connection_borrow_message (connection); 2505 if (message == NULL) 2506 { 2507 _dbus_warn ("Did not receive any messages after base service creation notification\n"); 2508 goto out; 2509 } 2510 2511 message_kind = check_got_service_info (message); 2512 2513 dbus_connection_return_message (connection, message); 2514 message = NULL; 2515 2516 switch (message_kind) 2517 { 2518 case GOT_SOMETHING_ELSE: 2519 _dbus_warn ("Unexpected message after ActivateService " 2520 "(should be an error or a service announcement"); 2521 goto out; 2522 2523 case GOT_ERROR: 2524 if (!check_got_error (context, connection, 2525 DBUS_ERROR_SPAWN_CHILD_EXITED, 2526 DBUS_ERROR_NO_MEMORY, 2527 NULL)) 2528 goto out; 2529 /* A service deleted should be coming along now after this error. 2530 * We can also get the error *after* the service deleted. 2531 */ 2532 2533 /* fall through */ 2534 2535 case GOT_SERVICE_DELETED: 2536 { 2537 /* The service started up and got a base address, but then 2538 * failed to register under EXISTENT_SERVICE_NAME 2539 */ 2540 CheckServiceOwnerChangedData socd; 2541 2542 socd.expected_kind = SERVICE_DELETED; 2543 socd.expected_service_name = base_service; 2544 socd.failed = FALSE; 2545 socd.skip_connection = NULL; 2546 2547 bus_test_clients_foreach (check_service_owner_changed_foreach, 2548 &socd); 2549 2550 if (socd.failed) 2551 goto out; 2552 2553 /* Now we should get an error about the service exiting 2554 * if we didn't get it before. 2555 */ 2556 if (message_kind != GOT_ERROR) 2557 { 2558 block_connection_until_message_from_bus (context, connection, "error about service exiting"); 2559 2560 /* and process everything again */ 2561 bus_test_run_everything (context); 2562 2563 if (!check_got_error (context, connection, 2564 DBUS_ERROR_SPAWN_CHILD_EXITED, 2565 DBUS_ERROR_NO_MEMORY, 2566 NULL)) 2567 goto out; 2568 } 2569 break; 2570 } 2571 2572 case GOT_SERVICE_CREATED: 2573 message = pop_message_waiting_for_memory (connection); 2574 if (message == NULL) 2575 { 2576 _dbus_warn ("Failed to pop message we just put back! " 2577 "should have been a NameOwnerChanged (creation)\n"); 2578 goto out; 2579 } 2580 2581 if (!check_service_activated (context, connection, EXISTENT_SERVICE_NAME, 2582 base_service, message)) 2583 goto out; 2584 2585 dbus_message_unref (message); 2586 message = NULL; 2587 2588 if (!check_no_leftovers (context)) 2589 { 2590 _dbus_warn ("Messages were left over after successful activation\n"); 2591 goto out; 2592 } 2593 2594 if (!check_send_exit_to_service (context, connection, 2595 EXISTENT_SERVICE_NAME, base_service)) 2596 goto out; 2597 2598 break; 2599 } 2600 } 2601 2602 retval = TRUE; 2603 2604 out: 2605 if (message) 2606 dbus_message_unref (message); 2607 2608 if (base_service_message) 2609 dbus_message_unref (base_service_message); 2610 2611 return retval; 2612} 2613 2614/* returns TRUE if the correct thing happens, 2615 * but the correct thing may include OOM errors. 2616 */ 2617static dbus_bool_t 2618check_segfault_service_no_auto_start (BusContext *context, 2619 DBusConnection *connection) 2620{ 2621 DBusMessage *message; 2622 dbus_uint32_t serial; 2623 dbus_bool_t retval; 2624 const char *segv_service; 2625 dbus_uint32_t flags; 2626 2627 message = dbus_message_new_method_call (DBUS_SERVICE_DBUS, 2628 DBUS_PATH_DBUS, 2629 DBUS_INTERFACE_DBUS, 2630 "StartServiceByName"); 2631 2632 if (message == NULL) 2633 return TRUE; 2634 2635 dbus_message_set_auto_start (message, FALSE); 2636 2637 segv_service = "org.freedesktop.DBus.TestSuiteSegfaultService"; 2638 flags = 0; 2639 if (!dbus_message_append_args (message, 2640 DBUS_TYPE_STRING, &segv_service, 2641 DBUS_TYPE_UINT32, &flags, 2642 DBUS_TYPE_INVALID)) 2643 { 2644 dbus_message_unref (message); 2645 return TRUE; 2646 } 2647 2648 if (!dbus_connection_send (connection, message, &serial)) 2649 { 2650 dbus_message_unref (message); 2651 return TRUE; 2652 } 2653 2654 dbus_message_unref (message); 2655 message = NULL; 2656 2657 bus_test_run_everything (context); 2658 block_connection_until_message_from_bus (context, connection, "reply to activating segfault service"); 2659 bus_test_run_everything (context); 2660 2661 if (!dbus_connection_get_is_connected (connection)) 2662 { 2663 _dbus_verbose ("connection was disconnected: %s %d\n", _DBUS_FUNCTION_NAME, __LINE__); 2664 return TRUE; 2665 } 2666 2667 retval = FALSE; 2668 2669 message = pop_message_waiting_for_memory (connection); 2670 if (message == NULL) 2671 { 2672 _dbus_warn ("Did not receive a reply to %s %d on %p\n", 2673 "StartServiceByName", serial, connection); 2674 goto out; 2675 } 2676 2677 verbose_message_received (connection, message); 2678 2679 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR) 2680 { 2681 if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS)) 2682 { 2683 _dbus_warn ("Message has wrong sender %s\n", 2684 dbus_message_get_sender (message) ? 2685 dbus_message_get_sender (message) : "(none)"); 2686 goto out; 2687 } 2688 2689 if (dbus_message_is_error (message, 2690 DBUS_ERROR_NO_MEMORY)) 2691 { 2692 ; /* good, this is a valid response */ 2693 } 2694 else if (dbus_message_is_error (message, 2695 DBUS_ERROR_SPAWN_CHILD_SIGNALED)) 2696 { 2697 ; /* good, this is expected also */ 2698 } 2699 else 2700 { 2701 warn_unexpected (connection, message, "not this error"); 2702 2703 goto out; 2704 } 2705 } 2706 else 2707 { 2708 _dbus_warn ("Did not expect to successfully activate segfault service\n"); 2709 goto out; 2710 } 2711 2712 retval = TRUE; 2713 2714 out: 2715 if (message) 2716 dbus_message_unref (message); 2717 2718 return retval; 2719} 2720 2721 2722/* returns TRUE if the correct thing happens, 2723 * but the correct thing may include OOM errors. 2724 */ 2725static dbus_bool_t 2726check_segfault_service_auto_start (BusContext *context, 2727 DBusConnection *connection) 2728{ 2729 DBusMessage *message; 2730 dbus_uint32_t serial; 2731 dbus_bool_t retval; 2732 2733 message = dbus_message_new_method_call ("org.freedesktop.DBus.TestSuiteSegfaultService", 2734 "/org/freedesktop/TestSuite", 2735 "org.freedesktop.TestSuite", 2736 "Echo"); 2737 2738 if (message == NULL) 2739 return TRUE; 2740 2741 if (!dbus_connection_send (connection, message, &serial)) 2742 { 2743 dbus_message_unref (message); 2744 return TRUE; 2745 } 2746 2747 dbus_message_unref (message); 2748 message = NULL; 2749 2750 bus_test_run_everything (context); 2751 block_connection_until_message_from_bus (context, connection, "reply to Echo on segfault service"); 2752 bus_test_run_everything (context); 2753 2754 if (!dbus_connection_get_is_connected (connection)) 2755 { 2756 _dbus_verbose ("connection was disconnected: %s %d\n", _DBUS_FUNCTION_NAME, __LINE__); 2757 return TRUE; 2758 } 2759 2760 retval = FALSE; 2761 2762 message = pop_message_waiting_for_memory (connection); 2763 if (message == NULL) 2764 { 2765 _dbus_warn ("Did not receive a reply to %s %d on %p\n", 2766 "Echo message (auto activation)", serial, connection); 2767 goto out; 2768 } 2769 2770 verbose_message_received (connection, message); 2771 2772 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR) 2773 { 2774 if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS)) 2775 { 2776 _dbus_warn ("Message has wrong sender %s\n", 2777 dbus_message_get_sender (message) ? 2778 dbus_message_get_sender (message) : "(none)"); 2779 goto out; 2780 } 2781 2782 if (dbus_message_is_error (message, 2783 DBUS_ERROR_NO_MEMORY)) 2784 { 2785 ; /* good, this is a valid response */ 2786 } 2787 else if (dbus_message_is_error (message, 2788 DBUS_ERROR_SPAWN_CHILD_SIGNALED)) 2789 { 2790 ; /* good, this is expected also */ 2791 } 2792 else 2793 { 2794 warn_unexpected (connection, message, "not this error"); 2795 2796 goto out; 2797 } 2798 } 2799 else 2800 { 2801 _dbus_warn ("Did not expect to successfully activate segfault service\n"); 2802 goto out; 2803 } 2804 2805 retval = TRUE; 2806 2807 out: 2808 if (message) 2809 dbus_message_unref (message); 2810 2811 return retval; 2812} 2813 2814#define TEST_ECHO_MESSAGE "Test echo message" 2815#define TEST_RUN_HELLO_FROM_SELF_MESSAGE "Test sending message to self" 2816 2817/* returns TRUE if the correct thing happens, 2818 * but the correct thing may include OOM errors. 2819 */ 2820static dbus_bool_t 2821check_existent_hello_from_self (BusContext *context, 2822 DBusConnection *connection) 2823{ 2824 DBusMessage *message; 2825 dbus_uint32_t serial; 2826 const char *text; 2827 2828 message = dbus_message_new_method_call (EXISTENT_SERVICE_NAME, 2829 "/org/freedesktop/TestSuite", 2830 "org.freedesktop.TestSuite", 2831 "RunHelloFromSelf"); 2832 2833 if (message == NULL) 2834 return TRUE; 2835 2836 text = TEST_RUN_HELLO_FROM_SELF_MESSAGE; 2837 if (!dbus_message_append_args (message, 2838 DBUS_TYPE_STRING, &text, 2839 DBUS_TYPE_INVALID)) 2840 { 2841 dbus_message_unref (message); 2842 return TRUE; 2843 } 2844 2845 if (!dbus_connection_send (connection, message, &serial)) 2846 { 2847 dbus_message_unref (message); 2848 return TRUE; 2849 } 2850 2851 dbus_message_unref (message); 2852 message = NULL; 2853 2854 bus_test_run_everything (context); 2855 2856 /* Note: if this test is run in OOM mode, it will block when the bus 2857 * doesn't send a reply due to OOM. 2858 */ 2859 block_connection_until_message_from_bus (context, connection, "reply from running hello from self"); 2860 2861 message = pop_message_waiting_for_memory (connection); 2862 if (message == NULL) 2863 { 2864 _dbus_warn ("Failed to pop message! Should have been reply from RunHelloFromSelf message\n"); 2865 return FALSE; 2866 } 2867 2868 if (dbus_message_get_reply_serial (message) != serial) 2869 { 2870 _dbus_warn ("Wrong reply serial\n"); 2871 dbus_message_unref (message); 2872 return FALSE; 2873 } 2874 2875 dbus_message_unref (message); 2876 message = NULL; 2877 2878 return TRUE; 2879} 2880 2881/* returns TRUE if the correct thing happens, 2882 * but the correct thing may include OOM errors. 2883 */ 2884static dbus_bool_t 2885check_existent_ping (BusContext *context, 2886 DBusConnection *connection) 2887{ 2888 DBusMessage *message; 2889 dbus_uint32_t serial; 2890 message = dbus_message_new_method_call (EXISTENT_SERVICE_NAME, 2891 "/org/freedesktop/TestSuite", 2892 "org.freedesktop.DBus.Peer", 2893 "Ping"); 2894 2895 if (message == NULL) 2896 return TRUE; 2897 2898 if (!dbus_connection_send (connection, message, &serial)) 2899 { 2900 dbus_message_unref (message); 2901 return TRUE; 2902 } 2903 2904 dbus_message_unref (message); 2905 message = NULL; 2906 2907 bus_test_run_everything (context); 2908 2909 /* Note: if this test is run in OOM mode, it will block when the bus 2910 * doesn't send a reply due to OOM. 2911 */ 2912 block_connection_until_message_from_bus (context, connection, "reply from running Ping"); 2913 2914 message = pop_message_waiting_for_memory (connection); 2915 if (message == NULL) 2916 { 2917 _dbus_warn ("Failed to pop message! Should have been reply from Ping message\n"); 2918 return FALSE; 2919 } 2920 2921 if (dbus_message_get_reply_serial (message) != serial) 2922 { 2923 _dbus_warn ("Wrong reply serial\n"); 2924 dbus_message_unref (message); 2925 return FALSE; 2926 } 2927 2928 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_RETURN) 2929 { 2930 _dbus_warn ("Unexpected message return during Ping\n"); 2931 dbus_message_unref (message); 2932 return FALSE; 2933 } 2934 2935 dbus_message_unref (message); 2936 message = NULL; 2937 2938 return TRUE; 2939} 2940 2941/* returns TRUE if the correct thing happens, 2942 * but the correct thing may include OOM errors. 2943 */ 2944static dbus_bool_t 2945check_existent_get_machine_id (BusContext *context, 2946 DBusConnection *connection) 2947{ 2948 DBusMessage *message; 2949 dbus_uint32_t serial; 2950 const char *machine_id; 2951 2952 message = dbus_message_new_method_call (EXISTENT_SERVICE_NAME, 2953 "/org/freedesktop/TestSuite", 2954 "org.freedesktop.DBus.Peer", 2955 "GetMachineId"); 2956 2957 if (message == NULL) 2958 return TRUE; 2959 2960 if (!dbus_connection_send (connection, message, &serial)) 2961 { 2962 dbus_message_unref (message); 2963 return TRUE; 2964 } 2965 2966 dbus_message_unref (message); 2967 message = NULL; 2968 2969 bus_test_run_everything (context); 2970 2971 /* Note: if this test is run in OOM mode, it will block when the bus 2972 * doesn't send a reply due to OOM. 2973 */ 2974 block_connection_until_message_from_bus (context, connection, "reply from running GetMachineId"); 2975 2976 message = pop_message_waiting_for_memory (connection); 2977 if (message == NULL) 2978 { 2979 _dbus_warn ("Failed to pop message! Should have been reply from GetMachineId message\n"); 2980 return FALSE; 2981 } 2982 2983 if (dbus_message_get_reply_serial (message) != serial) 2984 { 2985 _dbus_warn ("Wrong reply serial\n"); 2986 dbus_message_unref (message); 2987 return FALSE; 2988 } 2989 2990 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_RETURN) 2991 { 2992 _dbus_warn ("Unexpected message return during GetMachineId\n"); 2993 dbus_message_unref (message); 2994 return FALSE; 2995 } 2996 2997 machine_id = NULL; 2998 if (!dbus_message_get_args (message, NULL, DBUS_TYPE_STRING, &machine_id, DBUS_TYPE_INVALID)) 2999 { 3000 _dbus_warn ("Did not get a machine ID in reply to GetMachineId\n"); 3001 dbus_message_unref (message); 3002 return FALSE; 3003 } 3004 3005 if (machine_id == NULL || strlen (machine_id) != 32) 3006 { 3007 _dbus_warn ("Machine id looks bogus: '%s'\n", machine_id ? machine_id : "null"); 3008 dbus_message_unref (message); 3009 return FALSE; 3010 } 3011 3012 /* We can't check that the machine id is correct because during make check it is 3013 * just made up for each process separately 3014 */ 3015 3016 dbus_message_unref (message); 3017 message = NULL; 3018 3019 return TRUE; 3020} 3021 3022/* returns TRUE if the correct thing happens, 3023 * but the correct thing may include OOM errors. 3024 */ 3025static dbus_bool_t 3026check_existent_service_auto_start (BusContext *context, 3027 DBusConnection *connection) 3028{ 3029 DBusMessage *message; 3030 DBusMessage *base_service_message; 3031 dbus_uint32_t serial; 3032 dbus_bool_t retval; 3033 const char *base_service; 3034 const char *text; 3035 3036 base_service_message = NULL; 3037 3038 message = dbus_message_new_method_call (EXISTENT_SERVICE_NAME, 3039 "/org/freedesktop/TestSuite", 3040 "org.freedesktop.TestSuite", 3041 "Echo"); 3042 3043 if (message == NULL) 3044 return TRUE; 3045 3046 text = TEST_ECHO_MESSAGE; 3047 if (!dbus_message_append_args (message, 3048 DBUS_TYPE_STRING, &text, 3049 DBUS_TYPE_INVALID)) 3050 { 3051 dbus_message_unref (message); 3052 return TRUE; 3053 } 3054 3055 if (!dbus_connection_send (connection, message, &serial)) 3056 { 3057 dbus_message_unref (message); 3058 return TRUE; 3059 } 3060 3061 dbus_message_unref (message); 3062 message = NULL; 3063 3064 bus_test_run_everything (context); 3065 3066 /* now wait for the message bus to hear back from the activated 3067 * service. 3068 */ 3069 block_connection_until_message_from_bus (context, connection, "reply to Echo on existent service"); 3070 bus_test_run_everything (context); 3071 3072 if (!dbus_connection_get_is_connected (connection)) 3073 { 3074 _dbus_verbose ("connection was disconnected: %s %d\n", _DBUS_FUNCTION_NAME, __LINE__); 3075 return TRUE; 3076 } 3077 3078 retval = FALSE; 3079 3080 message = pop_message_waiting_for_memory (connection); 3081 if (message == NULL) 3082 { 3083 _dbus_warn ("Did not receive any messages after auto start %d on %p\n", 3084 serial, connection); 3085 goto out; 3086 } 3087 3088 verbose_message_received (connection, message); 3089 _dbus_verbose (" (after sending %s)\n", "auto start"); 3090 3091 /* we should get zero or two ServiceOwnerChanged signals */ 3092 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_SIGNAL) 3093 { 3094 GotServiceInfo message_kind; 3095 3096 if (!check_base_service_activated (context, connection, 3097 message, &base_service)) 3098 goto out; 3099 3100 base_service_message = message; 3101 message = NULL; 3102 3103 /* We may need to block here for the test service to exit or finish up */ 3104 block_connection_until_message_from_bus (context, connection, "service to exit"); 3105 3106 /* Should get a service creation notification for the activated 3107 * service name, or a service deletion on the base service name 3108 */ 3109 message = dbus_connection_borrow_message (connection); 3110 if (message == NULL) 3111 { 3112 _dbus_warn ("No message after auto activation " 3113 "(should be a service announcement)\n"); 3114 dbus_connection_return_message (connection, message); 3115 message = NULL; 3116 goto out; 3117 } 3118 3119 message_kind = check_got_service_info (message); 3120 3121 dbus_connection_return_message (connection, message); 3122 message = NULL; 3123 3124 switch (message_kind) 3125 { 3126 case GOT_SERVICE_CREATED: 3127 message = pop_message_waiting_for_memory (connection); 3128 if (message == NULL) 3129 { 3130 _dbus_warn ("Failed to pop message we just put back! " 3131 "should have been a NameOwnerChanged (creation)\n"); 3132 goto out; 3133 } 3134 3135 /* Check that ServiceOwnerChanged (creation) was correctly received */ 3136 if (!check_service_auto_activated (context, connection, EXISTENT_SERVICE_NAME, 3137 base_service, message)) 3138 goto out; 3139 3140 dbus_message_unref (message); 3141 message = NULL; 3142 3143 break; 3144 3145 case GOT_SERVICE_DELETED: 3146 { 3147 /* The service started up and got a base address, but then 3148 * failed to register under EXISTENT_SERVICE_NAME 3149 */ 3150 CheckServiceOwnerChangedData socd; 3151 3152 socd.expected_kind = SERVICE_DELETED; 3153 socd.expected_service_name = base_service; 3154 socd.failed = FALSE; 3155 socd.skip_connection = NULL; 3156 bus_test_clients_foreach (check_service_owner_changed_foreach, 3157 &socd); 3158 3159 if (socd.failed) 3160 goto out; 3161 3162 break; 3163 } 3164 3165 case GOT_ERROR: 3166 case GOT_SOMETHING_ELSE: 3167 _dbus_warn ("Unexpected message after auto activation\n"); 3168 goto out; 3169 } 3170 } 3171 3172 /* OK, now we've dealt with ServiceOwnerChanged signals, now should 3173 * come the method reply (or error) from the initial method call 3174 */ 3175 3176 /* Note: if this test is run in OOM mode, it will block when the bus 3177 * doesn't send a reply due to OOM. 3178 */ 3179 block_connection_until_message_from_bus (context, connection, "reply from echo message after auto-activation"); 3180 3181 message = pop_message_waiting_for_memory (connection); 3182 if (message == NULL) 3183 { 3184 _dbus_warn ("Failed to pop message! Should have been reply from echo message\n"); 3185 goto out; 3186 } 3187 3188 if (dbus_message_get_reply_serial (message) != serial) 3189 { 3190 _dbus_warn ("Wrong reply serial\n"); 3191 goto out; 3192 } 3193 3194 dbus_message_unref (message); 3195 message = NULL; 3196 3197 if (!check_existent_ping (context, connection)) 3198 goto out; 3199 3200 if (!check_existent_get_machine_id (context, connection)) 3201 goto out; 3202 3203 if (!check_existent_hello_from_self (context, connection)) 3204 goto out; 3205 3206 if (!check_send_exit_to_service (context, connection, 3207 EXISTENT_SERVICE_NAME, 3208 base_service)) 3209 goto out; 3210 3211 retval = TRUE; 3212 3213 out: 3214 if (message) 3215 dbus_message_unref (message); 3216 3217 if (base_service_message) 3218 dbus_message_unref (base_service_message); 3219 3220 return retval; 3221} 3222 3223#define SHELL_FAIL_SERVICE_NAME "org.freedesktop.DBus.TestSuiteShellEchoServiceFail" 3224 3225/* returns TRUE if the correct thing happens, 3226 * but the correct thing may include OOM errors. 3227 */ 3228static dbus_bool_t 3229check_shell_fail_service_auto_start (BusContext *context, 3230 DBusConnection *connection) 3231{ 3232 DBusMessage *message; 3233 dbus_uint32_t serial; 3234 dbus_bool_t retval; 3235 3236 message = dbus_message_new_method_call (SHELL_FAIL_SERVICE_NAME, 3237 "/org/freedesktop/TestSuite", 3238 "org.freedesktop.TestSuite", 3239 "Echo"); 3240 3241 if (message == NULL) 3242 return TRUE; 3243 3244 if (!dbus_connection_send (connection, message, &serial)) 3245 { 3246 dbus_message_unref (message); 3247 return TRUE; 3248 } 3249 3250 dbus_message_unref (message); 3251 message = NULL; 3252 3253 bus_test_run_everything (context); 3254 block_connection_until_message_from_bus (context, connection, "reply to shell Echo on service which should fail to auto-start"); 3255 bus_test_run_everything (context); 3256 3257 if (!dbus_connection_get_is_connected (connection)) 3258 { 3259 _dbus_verbose ("connection was disconnected: %s %d\n", _DBUS_FUNCTION_NAME, __LINE__); 3260 return TRUE; 3261 } 3262 3263 retval = FALSE; 3264 3265 message = pop_message_waiting_for_memory (connection); 3266 if (message == NULL) 3267 { 3268 _dbus_warn ("Did not receive a reply to %s %d on %p\n", 3269 "Echo message (auto activation)", serial, connection); 3270 goto out; 3271 } 3272 3273 verbose_message_received (connection, message); 3274 3275 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR) 3276 { 3277 if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS)) 3278 { 3279 _dbus_warn ("Message has wrong sender %s\n", 3280 dbus_message_get_sender (message) ? 3281 dbus_message_get_sender (message) : "(none)"); 3282 goto out; 3283 } 3284 3285 if (dbus_message_is_error (message, 3286 DBUS_ERROR_NO_MEMORY)) 3287 { 3288 ; /* good, this is a valid response */ 3289 } 3290 else if (dbus_message_is_error (message, 3291 DBUS_ERROR_INVALID_ARGS)) 3292 { 3293 _dbus_verbose("got invalid args\n"); 3294 ; /* good, this is expected also */ 3295 } 3296 else 3297 { 3298 warn_unexpected (connection, message, "not this error"); 3299 3300 goto out; 3301 } 3302 } 3303 else 3304 { 3305 _dbus_warn ("Did not expect to successfully auto-start shell fail service\n"); 3306 goto out; 3307 } 3308 3309 retval = TRUE; 3310 3311 out: 3312 if (message) 3313 dbus_message_unref (message); 3314 3315 return retval; 3316} 3317 3318#define SHELL_SUCCESS_SERVICE_NAME "org.freedesktop.DBus.TestSuiteShellEchoServiceSuccess" 3319 3320/* returns TRUE if the correct thing happens, 3321 * but the correct thing may include OOM errors. 3322 */ 3323static dbus_bool_t 3324check_shell_service_success_auto_start (BusContext *context, 3325 DBusConnection *connection) 3326{ 3327 DBusMessage *message; 3328 DBusMessage *base_service_message; 3329 dbus_uint32_t serial; 3330 dbus_bool_t retval; 3331 const char *base_service; 3332 const char *argv[7] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL}; 3333 3334 base_service_message = NULL; 3335 3336 message = dbus_message_new_method_call (SHELL_SUCCESS_SERVICE_NAME, 3337 "/org/freedesktop/TestSuite", 3338 "org.freedesktop.TestSuite", 3339 "Echo"); 3340 3341 if (message == NULL) 3342 return TRUE; 3343 3344 if (!dbus_connection_send (connection, message, &serial)) 3345 { 3346 dbus_message_unref (message); 3347 return TRUE; 3348 } 3349 3350 dbus_message_unref (message); 3351 message = NULL; 3352 3353 bus_test_run_everything (context); 3354 3355 /* now wait for the message bus to hear back from the activated 3356 * service. 3357 */ 3358 block_connection_until_message_from_bus (context, connection, "reply to Echo on shell success service"); 3359 bus_test_run_everything (context); 3360 3361 if (!dbus_connection_get_is_connected (connection)) 3362 { 3363 _dbus_verbose ("connection was disconnected: %s %d\n", _DBUS_FUNCTION_NAME, __LINE__); 3364 return TRUE; 3365 } 3366 3367 retval = FALSE; 3368 3369 message = pop_message_waiting_for_memory (connection); 3370 if (message == NULL) 3371 { 3372 _dbus_warn ("Did not receive any messages after auto start %d on %p\n", 3373 serial, connection); 3374 goto out; 3375 } 3376 3377 verbose_message_received (connection, message); 3378 _dbus_verbose (" (after sending %s)\n", "auto start"); 3379 3380 /* we should get zero or two ServiceOwnerChanged signals */ 3381 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_SIGNAL) 3382 { 3383 GotServiceInfo message_kind; 3384 3385 if (!check_base_service_activated (context, connection, 3386 message, &base_service)) 3387 goto out; 3388 3389 base_service_message = message; 3390 message = NULL; 3391 3392 /* We may need to block here for the test service to exit or finish up */ 3393 block_connection_until_message_from_bus (context, connection, "service to exit"); 3394 3395 /* Should get a service creation notification for the activated 3396 * service name, or a service deletion on the base service name 3397 */ 3398 message = dbus_connection_borrow_message (connection); 3399 if (message == NULL) 3400 { 3401 _dbus_warn ("No message after auto activation " 3402 "(should be a service announcement)\n"); 3403 dbus_connection_return_message (connection, message); 3404 message = NULL; 3405 goto out; 3406 } 3407 3408 message_kind = check_got_service_info (message); 3409 3410 dbus_connection_return_message (connection, message); 3411 message = NULL; 3412 3413 switch (message_kind) 3414 { 3415 case GOT_SERVICE_CREATED: 3416 message = pop_message_waiting_for_memory (connection); 3417 if (message == NULL) 3418 { 3419 _dbus_warn ("Failed to pop message we just put back! " 3420 "should have been a NameOwnerChanged (creation)\n"); 3421 goto out; 3422 } 3423 3424 /* Check that ServiceOwnerChanged (creation) was correctly received */ 3425 if (!check_service_auto_activated (context, connection, SHELL_SUCCESS_SERVICE_NAME, 3426 base_service, message)) 3427 goto out; 3428 3429 dbus_message_unref (message); 3430 message = NULL; 3431 3432 break; 3433 3434 case GOT_SERVICE_DELETED: 3435 { 3436 /* The service started up and got a base address, but then 3437 * failed to register under SHELL_SUCCESS_SERVICE_NAME 3438 */ 3439 CheckServiceOwnerChangedData socd; 3440 3441 socd.expected_kind = SERVICE_DELETED; 3442 socd.expected_service_name = base_service; 3443 socd.failed = FALSE; 3444 socd.skip_connection = NULL; 3445 bus_test_clients_foreach (check_service_owner_changed_foreach, 3446 &socd); 3447 3448 if (socd.failed) 3449 goto out; 3450 3451 break; 3452 } 3453 3454 case GOT_ERROR: 3455 case GOT_SOMETHING_ELSE: 3456 _dbus_warn ("Unexpected message after auto activation\n"); 3457 goto out; 3458 } 3459 } 3460 3461 /* OK, now we've dealt with ServiceOwnerChanged signals, now should 3462 * come the method reply (or error) from the initial method call 3463 */ 3464 3465 /* Note: if this test is run in OOM mode, it will block when the bus 3466 * doesn't send a reply due to OOM. 3467 */ 3468 block_connection_until_message_from_bus (context, connection, "reply from echo message after auto-activation"); 3469 3470 message = pop_message_waiting_for_memory (connection); 3471 if (message == NULL) 3472 { 3473 _dbus_warn ("Failed to pop message! Should have been reply from echo message\n"); 3474 goto out; 3475 } 3476 3477 if (dbus_message_get_reply_serial (message) != serial) 3478 { 3479 _dbus_warn ("Wrong reply serial\n"); 3480 goto out; 3481 } 3482 3483 if (!dbus_message_get_args (message, NULL, 3484 DBUS_TYPE_STRING, &argv[0], 3485 DBUS_TYPE_STRING, &argv[1], 3486 DBUS_TYPE_STRING, &argv[2], 3487 DBUS_TYPE_STRING, &argv[3], 3488 DBUS_TYPE_STRING, &argv[4], 3489 DBUS_TYPE_STRING, &argv[5], 3490 DBUS_TYPE_STRING, &argv[6], 3491 DBUS_TYPE_INVALID)) 3492 { 3493 _dbus_warn ("Error getting arguments from return\n"); 3494 goto out; 3495 } 3496 3497 /* don't worry about arg[0] as it may be different 3498 depending on the path to the tests 3499 */ 3500 if (strcmp("-test", argv[1]) != 0) 3501 { 3502 _dbus_warn ("Unexpected argv[1] in shell success service test (expected: %s, got: %s)\n", 3503 "-test", argv[1]); 3504 goto out; 3505 } 3506 3507 if (strcmp("that", argv[2]) != 0) 3508 { 3509 _dbus_warn ("Unexpected argv[2] in shell success service test (expected: %s, got: %s)\n", 3510 "that", argv[2]); 3511 goto out; 3512 } 3513 3514 if (strcmp("we get", argv[3]) != 0) 3515 { 3516 _dbus_warn ("Unexpected argv[3] in shell success service test (expected: %s, got: %s)\n", 3517 "we get", argv[3]); 3518 goto out; 3519 } 3520 3521 if (strcmp("back", argv[4]) != 0) 3522 { 3523 _dbus_warn ("Unexpected argv[4] in shell success service test (expected: %s, got: %s)\n", 3524 "back", argv[4]); 3525 goto out; 3526 } 3527 3528 if (strcmp("--what", argv[5]) != 0) 3529 { 3530 _dbus_warn ("Unexpected argv[5] in shell success service test (expected: %s, got: %s)\n", 3531 "--what", argv[5]); 3532 goto out; 3533 } 3534 3535 if (strcmp("we put in", argv[6]) != 0) 3536 { 3537 _dbus_warn ("Unexpected argv[6] in shell success service test (expected: %s, got: %s)\n", 3538 "we put in", argv[6]); 3539 goto out; 3540 } 3541 3542 dbus_message_unref (message); 3543 message = NULL; 3544 3545 if (!check_send_exit_to_service (context, connection, 3546 SHELL_SUCCESS_SERVICE_NAME, 3547 base_service)) 3548 goto out; 3549 3550 retval = TRUE; 3551 3552 out: 3553 if (message) 3554 dbus_message_unref (message); 3555 3556 if (base_service_message) 3557 dbus_message_unref (base_service_message); 3558 3559 return retval; 3560} 3561 3562typedef struct 3563{ 3564 Check1Func func; 3565 BusContext *context; 3566} Check1Data; 3567 3568static dbus_bool_t 3569check_oom_check1_func (void *data) 3570{ 3571 Check1Data *d = data; 3572 3573 if (! (* d->func) (d->context)) 3574 return FALSE; 3575 3576 if (!check_no_leftovers (d->context)) 3577 { 3578 _dbus_warn ("Messages were left over, should be covered by test suite\n"); 3579 return FALSE; 3580 } 3581 3582 return TRUE; 3583} 3584 3585static void 3586check1_try_iterations (BusContext *context, 3587 const char *description, 3588 Check1Func func) 3589{ 3590 Check1Data d; 3591 3592 d.func = func; 3593 d.context = context; 3594 3595 if (!_dbus_test_oom_handling (description, check_oom_check1_func, 3596 &d)) 3597 _dbus_assert_not_reached ("test failed"); 3598} 3599 3600static dbus_bool_t 3601check_get_services (BusContext *context, 3602 DBusConnection *connection, 3603 const char *method, 3604 char ***services, 3605 int *len) 3606{ 3607 DBusMessage *message; 3608 dbus_uint32_t serial; 3609 dbus_bool_t retval; 3610 DBusError error; 3611 char **srvs; 3612 int l; 3613 3614 retval = FALSE; 3615 dbus_error_init (&error); 3616 message = NULL; 3617 3618 message = dbus_message_new_method_call (DBUS_SERVICE_DBUS, 3619 DBUS_PATH_DBUS, 3620 DBUS_INTERFACE_DBUS, 3621 method); 3622 3623 if (message == NULL) 3624 return TRUE; 3625 3626 if (!dbus_connection_send (connection, message, &serial)) 3627 { 3628 dbus_message_unref (message); 3629 return TRUE; 3630 } 3631 3632 /* send our message */ 3633 bus_test_run_clients_loop (SEND_PENDING (connection)); 3634 3635 dbus_message_unref (message); 3636 message = NULL; 3637 3638 dbus_connection_ref (connection); /* because we may get disconnected */ 3639 block_connection_until_message_from_bus (context, connection, "reply to ListActivatableNames/ListNames"); 3640 3641 if (!dbus_connection_get_is_connected (connection)) 3642 { 3643 _dbus_verbose ("connection was disconnected: %s %d\n", _DBUS_FUNCTION_NAME, __LINE__); 3644 3645 dbus_connection_unref (connection); 3646 3647 return TRUE; 3648 } 3649 3650 dbus_connection_unref (connection); 3651 3652 message = pop_message_waiting_for_memory (connection); 3653 if (message == NULL) 3654 { 3655 _dbus_warn ("Did not receive a reply to %s %d on %p\n", 3656 method, serial, connection); 3657 goto out; 3658 } 3659 3660 verbose_message_received (connection, message); 3661 3662 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR) 3663 { 3664 if (dbus_message_is_error (message, DBUS_ERROR_NO_MEMORY)) 3665 { 3666 ; /* good, this is a valid response */ 3667 } 3668 else 3669 { 3670 warn_unexpected (connection, message, "not this error"); 3671 3672 goto out; 3673 } 3674 } 3675 else 3676 { 3677 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_RETURN) 3678 { 3679 ; /* good, expected */ 3680 } 3681 else 3682 { 3683 warn_unexpected (connection, message, 3684 "method_return for ListActivatableNames/ListNames"); 3685 3686 goto out; 3687 } 3688 3689 retry_get_property: 3690 3691 if (!dbus_message_get_args (message, &error, 3692 DBUS_TYPE_ARRAY, 3693 DBUS_TYPE_STRING, 3694 &srvs, &l, 3695 DBUS_TYPE_INVALID)) 3696 { 3697 if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY)) 3698 { 3699 _dbus_verbose ("no memory to list services by %s\n", method); 3700 dbus_error_free (&error); 3701 _dbus_wait_for_memory (); 3702 goto retry_get_property; 3703 } 3704 else 3705 { 3706 _dbus_assert (dbus_error_is_set (&error)); 3707 _dbus_warn ("Did not get the expected DBUS_TYPE_ARRAY from %s\n", method); 3708 goto out; 3709 } 3710 } else { 3711 *services = srvs; 3712 *len = l; 3713 } 3714 } 3715 3716 if (!check_no_leftovers (context)) 3717 goto out; 3718 3719 retval = TRUE; 3720 3721 out: 3722 dbus_error_free (&error); 3723 3724 if (message) 3725 dbus_message_unref (message); 3726 3727 return retval; 3728} 3729 3730/* returns TRUE if the correct thing happens, 3731 * but the correct thing may include OOM errors. 3732 */ 3733static dbus_bool_t 3734check_list_services (BusContext *context, 3735 DBusConnection *connection) 3736{ 3737 DBusMessage *message; 3738 DBusMessage *base_service_message; 3739 const char *base_service; 3740 dbus_uint32_t serial; 3741 dbus_bool_t retval; 3742 const char *existent = EXISTENT_SERVICE_NAME; 3743 dbus_uint32_t flags; 3744 char **services; 3745 int len; 3746 3747 _dbus_verbose ("check_list_services for %p\n", connection); 3748 3749 if (!check_get_services (context, connection, "ListActivatableNames", &services, &len)) 3750 { 3751 return TRUE; 3752 } 3753 3754 if (!_dbus_string_array_contains ((const char **)services, existent)) 3755 { 3756 _dbus_warn ("Did not get the expected %s from ListActivatableNames\n", existent); 3757 return FALSE; 3758 } 3759 3760 dbus_free_string_array (services); 3761 3762 base_service_message = NULL; 3763 3764 message = dbus_message_new_method_call (DBUS_SERVICE_DBUS, 3765 DBUS_PATH_DBUS, 3766 DBUS_INTERFACE_DBUS, 3767 "StartServiceByName"); 3768 3769 if (message == NULL) 3770 return TRUE; 3771 3772 dbus_message_set_auto_start (message, FALSE); 3773 3774 flags = 0; 3775 if (!dbus_message_append_args (message, 3776 DBUS_TYPE_STRING, &existent, 3777 DBUS_TYPE_UINT32, &flags, 3778 DBUS_TYPE_INVALID)) 3779 { 3780 dbus_message_unref (message); 3781 return TRUE; 3782 } 3783 3784 if (!dbus_connection_send (connection, message, &serial)) 3785 { 3786 dbus_message_unref (message); 3787 return TRUE; 3788 } 3789 3790 dbus_message_unref (message); 3791 message = NULL; 3792 3793 bus_test_run_everything (context); 3794 3795 /* now wait for the message bus to hear back from the activated 3796 * service. 3797 */ 3798 block_connection_until_message_from_bus (context, connection, "activated service to connect"); 3799 3800 bus_test_run_everything (context); 3801 3802 if (!dbus_connection_get_is_connected (connection)) 3803 { 3804 _dbus_verbose ("connection was disconnected: %s %d\n", _DBUS_FUNCTION_NAME, __LINE__); 3805 return TRUE; 3806 } 3807 3808 retval = FALSE; 3809 3810 message = pop_message_waiting_for_memory (connection); 3811 if (message == NULL) 3812 { 3813 _dbus_warn ("Did not receive any messages after %s %d on %p\n", 3814 "StartServiceByName", serial, connection); 3815 goto out; 3816 } 3817 3818 verbose_message_received (connection, message); 3819 _dbus_verbose (" (after sending %s)\n", "StartServiceByName"); 3820 3821 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR) 3822 { 3823 if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS)) 3824 { 3825 _dbus_warn ("Message has wrong sender %s\n", 3826 dbus_message_get_sender (message) ? 3827 dbus_message_get_sender (message) : "(none)"); 3828 goto out; 3829 } 3830 3831 if (dbus_message_is_error (message, 3832 DBUS_ERROR_NO_MEMORY)) 3833 { 3834 ; /* good, this is a valid response */ 3835 } 3836 else if (dbus_message_is_error (message, 3837 DBUS_ERROR_SPAWN_CHILD_EXITED) || 3838 dbus_message_is_error (message, 3839 DBUS_ERROR_SPAWN_CHILD_SIGNALED) || 3840 dbus_message_is_error (message, 3841 DBUS_ERROR_SPAWN_EXEC_FAILED)) 3842 { 3843 ; /* good, this is expected also */ 3844 } 3845 else 3846 { 3847 _dbus_warn ("Did not expect error %s\n", 3848 dbus_message_get_error_name (message)); 3849 goto out; 3850 } 3851 } 3852 else 3853 { 3854 GotServiceInfo message_kind; 3855 3856 if (!check_base_service_activated (context, connection, 3857 message, &base_service)) 3858 goto out; 3859 3860 base_service_message = message; 3861 message = NULL; 3862 3863 /* We may need to block here for the test service to exit or finish up */ 3864 block_connection_until_message_from_bus (context, connection, "test service to exit or finish up"); 3865 3866 message = dbus_connection_borrow_message (connection); 3867 if (message == NULL) 3868 { 3869 _dbus_warn ("Did not receive any messages after base service creation notification\n"); 3870 goto out; 3871 } 3872 3873 message_kind = check_got_service_info (message); 3874 3875 dbus_connection_return_message (connection, message); 3876 message = NULL; 3877 3878 switch (message_kind) 3879 { 3880 case GOT_SOMETHING_ELSE: 3881 case GOT_ERROR: 3882 case GOT_SERVICE_DELETED: 3883 _dbus_warn ("Unexpected message after ActivateService " 3884 "(should be an error or a service announcement)\n"); 3885 goto out; 3886 3887 case GOT_SERVICE_CREATED: 3888 message = pop_message_waiting_for_memory (connection); 3889 if (message == NULL) 3890 { 3891 _dbus_warn ("Failed to pop message we just put back! " 3892 "should have been a NameOwnerChanged (creation)\n"); 3893 goto out; 3894 } 3895 3896 if (!check_service_activated (context, connection, EXISTENT_SERVICE_NAME, 3897 base_service, message)) 3898 goto out; 3899 3900 dbus_message_unref (message); 3901 message = NULL; 3902 3903 if (!check_no_leftovers (context)) 3904 { 3905 _dbus_warn ("Messages were left over after successful activation\n"); 3906 goto out; 3907 } 3908 3909 break; 3910 } 3911 } 3912 3913 if (!check_get_services (context, connection, "ListNames", &services, &len)) 3914 { 3915 return TRUE; 3916 } 3917 3918 if (!_dbus_string_array_contains ((const char **)services, existent)) 3919 { 3920 _dbus_warn ("Did not get the expected %s from ListNames\n", existent); 3921 goto out; 3922 } 3923 3924 dbus_free_string_array (services); 3925 3926 if (!check_send_exit_to_service (context, connection, 3927 EXISTENT_SERVICE_NAME, base_service)) 3928 goto out; 3929 3930 retval = TRUE; 3931 3932 out: 3933 if (message) 3934 dbus_message_unref (message); 3935 3936 if (base_service_message) 3937 dbus_message_unref (base_service_message); 3938 3939 return retval; 3940} 3941 3942typedef struct 3943{ 3944 Check2Func func; 3945 BusContext *context; 3946 DBusConnection *connection; 3947} Check2Data; 3948 3949static dbus_bool_t 3950check_oom_check2_func (void *data) 3951{ 3952 Check2Data *d = data; 3953 3954 if (! (* d->func) (d->context, d->connection)) 3955 return FALSE; 3956 3957 if (!check_no_leftovers (d->context)) 3958 { 3959 _dbus_warn ("Messages were left over, should be covered by test suite\n"); 3960 return FALSE; 3961 } 3962 3963 return TRUE; 3964} 3965 3966static void 3967check2_try_iterations (BusContext *context, 3968 DBusConnection *connection, 3969 const char *description, 3970 Check2Func func) 3971{ 3972 Check2Data d; 3973 3974 d.func = func; 3975 d.context = context; 3976 d.connection = connection; 3977 3978 if (!_dbus_test_oom_handling (description, check_oom_check2_func, 3979 &d)) 3980 { 3981 _dbus_warn ("%s failed during oom\n", description); 3982 _dbus_assert_not_reached ("test failed"); 3983 } 3984} 3985 3986dbus_bool_t 3987bus_dispatch_test (const DBusString *test_data_dir) 3988{ 3989 BusContext *context; 3990 DBusConnection *foo; 3991 DBusConnection *bar; 3992 DBusConnection *baz; 3993 DBusError error; 3994 3995 dbus_error_init (&error); 3996 3997 context = bus_context_new_test (test_data_dir, 3998 "valid-config-files/debug-allow-all.conf"); 3999 if (context == NULL) 4000 return FALSE; 4001 4002 foo = dbus_connection_open_private ("debug-pipe:name=test-server", &error); 4003 if (foo == NULL) 4004 _dbus_assert_not_reached ("could not alloc connection"); 4005 4006 if (!bus_setup_debug_client (foo)) 4007 _dbus_assert_not_reached ("could not set up connection"); 4008 4009 spin_connection_until_authenticated (context, foo); 4010 4011 if (!check_hello_message (context, foo)) 4012 _dbus_assert_not_reached ("hello message failed"); 4013 4014 if (!check_double_hello_message (context, foo)) 4015 _dbus_assert_not_reached ("double hello message failed"); 4016 4017 if (!check_add_match_all (context, foo)) 4018 _dbus_assert_not_reached ("AddMatch message failed"); 4019 4020 bar = dbus_connection_open_private ("debug-pipe:name=test-server", &error); 4021 if (bar == NULL) 4022 _dbus_assert_not_reached ("could not alloc connection"); 4023 4024 if (!bus_setup_debug_client (bar)) 4025 _dbus_assert_not_reached ("could not set up connection"); 4026 4027 spin_connection_until_authenticated (context, bar); 4028 4029 if (!check_hello_message (context, bar)) 4030 _dbus_assert_not_reached ("hello message failed"); 4031 4032 if (!check_add_match_all (context, bar)) 4033 _dbus_assert_not_reached ("AddMatch message failed"); 4034 4035 baz = dbus_connection_open_private ("debug-pipe:name=test-server", &error); 4036 if (baz == NULL) 4037 _dbus_assert_not_reached ("could not alloc connection"); 4038 4039 if (!bus_setup_debug_client (baz)) 4040 _dbus_assert_not_reached ("could not set up connection"); 4041 4042 spin_connection_until_authenticated (context, baz); 4043 4044 if (!check_hello_message (context, baz)) 4045 _dbus_assert_not_reached ("hello message failed"); 4046 4047 if (!check_add_match_all (context, baz)) 4048 _dbus_assert_not_reached ("AddMatch message failed"); 4049 4050 if (!check_get_connection_unix_user (context, baz)) 4051 _dbus_assert_not_reached ("GetConnectionUnixUser message failed"); 4052 4053 if (!check_get_connection_unix_process_id (context, baz)) 4054 _dbus_assert_not_reached ("GetConnectionUnixProcessID message failed"); 4055 4056 if (!check_list_services (context, baz)) 4057 _dbus_assert_not_reached ("ListActivatableNames message failed"); 4058 4059 if (!check_no_leftovers (context)) 4060 { 4061 _dbus_warn ("Messages were left over after setting up initial connections\n"); 4062 _dbus_assert_not_reached ("initial connection setup failed"); 4063 } 4064 4065 check1_try_iterations (context, "create_and_hello", 4066 check_hello_connection); 4067 4068 check2_try_iterations (context, foo, "nonexistent_service_no_auto_start", 4069 check_nonexistent_service_no_auto_start); 4070 4071 check2_try_iterations (context, foo, "segfault_service_no_auto_start", 4072 check_segfault_service_no_auto_start); 4073 4074 check2_try_iterations (context, foo, "existent_service_no_auto_start", 4075 check_existent_service_no_auto_start); 4076 4077 check2_try_iterations (context, foo, "nonexistent_service_auto_start", 4078 check_nonexistent_service_auto_start); 4079 4080 check2_try_iterations (context, foo, "segfault_service_auto_start", 4081 check_segfault_service_auto_start); 4082 4083 check2_try_iterations (context, foo, "shell_fail_service_auto_start", 4084 check_shell_fail_service_auto_start); 4085 4086#if 0 4087 /* Note: need to resolve some issues with the testing code in order to run 4088 * this in oom (handle that we sometimes don't get replies back from the bus 4089 * when oom happens, without blocking the test). 4090 */ 4091 check2_try_iterations (context, foo, "existent_service_auto_auto_start", 4092 check_existent_service_auto_start); 4093#endif 4094 4095 if (!check_existent_service_auto_start (context, foo)) 4096 _dbus_assert_not_reached ("existent service auto start failed"); 4097 4098 if (!check_shell_service_success_auto_start (context, foo)) 4099 _dbus_assert_not_reached ("shell success service auto start failed"); 4100 4101 _dbus_verbose ("Disconnecting foo, bar, and baz\n"); 4102 4103 kill_client_connection_unchecked (foo); 4104 kill_client_connection_unchecked (bar); 4105 kill_client_connection_unchecked (baz); 4106 4107 bus_context_unref (context); 4108 4109 return TRUE; 4110} 4111 4112dbus_bool_t 4113bus_dispatch_sha1_test (const DBusString *test_data_dir) 4114{ 4115 BusContext *context; 4116 DBusConnection *foo; 4117 DBusError error; 4118 4119 dbus_error_init (&error); 4120 4121 /* Test SHA1 authentication */ 4122 _dbus_verbose ("Testing SHA1 context\n"); 4123 4124 context = bus_context_new_test (test_data_dir, 4125 "valid-config-files/debug-allow-all-sha1.conf"); 4126 if (context == NULL) 4127 return FALSE; 4128 4129 foo = dbus_connection_open_private ("debug-pipe:name=test-server", &error); 4130 if (foo == NULL) 4131 _dbus_assert_not_reached ("could not alloc connection"); 4132 4133 if (!bus_setup_debug_client (foo)) 4134 _dbus_assert_not_reached ("could not set up connection"); 4135 4136 spin_connection_until_authenticated (context, foo); 4137 4138 if (!check_hello_message (context, foo)) 4139 _dbus_assert_not_reached ("hello message failed"); 4140 4141 if (!check_add_match_all (context, foo)) 4142 _dbus_assert_not_reached ("addmatch message failed"); 4143 4144 if (!check_no_leftovers (context)) 4145 { 4146 _dbus_warn ("Messages were left over after setting up initial SHA-1 connection\n"); 4147 _dbus_assert_not_reached ("initial connection setup failed"); 4148 } 4149 4150 check1_try_iterations (context, "create_and_hello_sha1", 4151 check_hello_connection); 4152 4153 kill_client_connection_unchecked (foo); 4154 4155 bus_context_unref (context); 4156 4157 return TRUE; 4158} 4159 4160#endif /* DBUS_BUILD_TESTS */ 4161