00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <config.h>
00025 #include "dbus-transport-protected.h"
00026 #include "dbus-transport-unix.h"
00027 #include "dbus-transport-socket.h"
00028 #include "dbus-connection-internal.h"
00029 #include "dbus-watch.h"
00030 #include "dbus-auth.h"
00031 #include "dbus-address.h"
00032 #include "dbus-credentials.h"
00033 #include "dbus-mainloop.h"
00034 #include "dbus-message.h"
00035 #ifdef DBUS_BUILD_TESTS
00036 #include "dbus-server-debug-pipe.h"
00037 #endif
00038
00060 static void
00061 live_messages_notify (DBusCounter *counter,
00062 void *user_data)
00063 {
00064 DBusTransport *transport = user_data;
00065
00066 _dbus_transport_ref (transport);
00067
00068 #if 0
00069 _dbus_verbose ("Size counter value is now %d\n",
00070 (int) _dbus_counter_get_size_value (counter));
00071 _dbus_verbose ("Unix FD counter value is now %d\n",
00072 (int) _dbus_counter_get_unix_fd_value (counter));
00073 #endif
00074
00075
00076
00077
00078 if (transport->vtable->live_messages_changed)
00079 {
00080 _dbus_connection_lock (transport->connection);
00081 (* transport->vtable->live_messages_changed) (transport);
00082 _dbus_connection_unlock (transport->connection);
00083 }
00084
00085 _dbus_transport_unref (transport);
00086 }
00087
00101 dbus_bool_t
00102 _dbus_transport_init_base (DBusTransport *transport,
00103 const DBusTransportVTable *vtable,
00104 const DBusString *server_guid,
00105 const DBusString *address)
00106 {
00107 DBusMessageLoader *loader;
00108 DBusAuth *auth;
00109 DBusCounter *counter;
00110 char *address_copy;
00111 DBusCredentials *creds;
00112
00113 loader = _dbus_message_loader_new ();
00114 if (loader == NULL)
00115 return FALSE;
00116
00117 if (server_guid)
00118 auth = _dbus_auth_server_new (server_guid);
00119 else
00120 auth = _dbus_auth_client_new ();
00121 if (auth == NULL)
00122 {
00123 _dbus_message_loader_unref (loader);
00124 return FALSE;
00125 }
00126
00127 counter = _dbus_counter_new ();
00128 if (counter == NULL)
00129 {
00130 _dbus_auth_unref (auth);
00131 _dbus_message_loader_unref (loader);
00132 return FALSE;
00133 }
00134
00135 creds = _dbus_credentials_new ();
00136 if (creds == NULL)
00137 {
00138 _dbus_counter_unref (counter);
00139 _dbus_auth_unref (auth);
00140 _dbus_message_loader_unref (loader);
00141 return FALSE;
00142 }
00143
00144 if (server_guid)
00145 {
00146 _dbus_assert (address == NULL);
00147 address_copy = NULL;
00148 }
00149 else
00150 {
00151 _dbus_assert (address != NULL);
00152
00153 if (!_dbus_string_copy_data (address, &address_copy))
00154 {
00155 _dbus_credentials_unref (creds);
00156 _dbus_counter_unref (counter);
00157 _dbus_auth_unref (auth);
00158 _dbus_message_loader_unref (loader);
00159 return FALSE;
00160 }
00161 }
00162
00163 transport->refcount = 1;
00164 transport->vtable = vtable;
00165 transport->loader = loader;
00166 transport->auth = auth;
00167 transport->live_messages = counter;
00168 transport->authenticated = FALSE;
00169 transport->disconnected = FALSE;
00170 transport->is_server = (server_guid != NULL);
00171 transport->send_credentials_pending = !transport->is_server;
00172 transport->receive_credentials_pending = transport->is_server;
00173 transport->address = address_copy;
00174
00175 transport->unix_user_function = NULL;
00176 transport->unix_user_data = NULL;
00177 transport->free_unix_user_data = NULL;
00178
00179 transport->windows_user_function = NULL;
00180 transport->windows_user_data = NULL;
00181 transport->free_windows_user_data = NULL;
00182
00183 transport->expected_guid = NULL;
00184
00185
00186
00187
00188 transport->max_live_messages_size = _DBUS_ONE_MEGABYTE * 63;
00189
00190
00191
00192 transport->max_live_messages_unix_fds = 4096;
00193
00194
00195 transport->credentials = creds;
00196
00197 _dbus_counter_set_notify (transport->live_messages,
00198 transport->max_live_messages_size,
00199 transport->max_live_messages_unix_fds,
00200 live_messages_notify,
00201 transport);
00202
00203 if (transport->address)
00204 _dbus_verbose ("Initialized transport on address %s\n", transport->address);
00205
00206 return TRUE;
00207 }
00208
00215 void
00216 _dbus_transport_finalize_base (DBusTransport *transport)
00217 {
00218 if (!transport->disconnected)
00219 _dbus_transport_disconnect (transport);
00220
00221 if (transport->free_unix_user_data != NULL)
00222 (* transport->free_unix_user_data) (transport->unix_user_data);
00223
00224 if (transport->free_windows_user_data != NULL)
00225 (* transport->free_windows_user_data) (transport->windows_user_data);
00226
00227 _dbus_message_loader_unref (transport->loader);
00228 _dbus_auth_unref (transport->auth);
00229 _dbus_counter_set_notify (transport->live_messages,
00230 0, 0, NULL, NULL);
00231 _dbus_counter_unref (transport->live_messages);
00232 dbus_free (transport->address);
00233 dbus_free (transport->expected_guid);
00234 if (transport->credentials)
00235 _dbus_credentials_unref (transport->credentials);
00236 }
00237
00238
00248 static DBusTransport*
00249 check_address (const char *address, DBusError *error)
00250 {
00251 DBusAddressEntry **entries;
00252 DBusTransport *transport = NULL;
00253 int len, i;
00254
00255 _dbus_assert (address != NULL);
00256
00257 if (!dbus_parse_address (address, &entries, &len, error))
00258 return NULL;
00259
00260 for (i = 0; i < len; i++)
00261 {
00262 transport = _dbus_transport_open (entries[i], error);
00263 if (transport != NULL)
00264 break;
00265 }
00266
00267 dbus_address_entries_free (entries);
00268 return transport;
00269 }
00270
00278 static DBusTransport*
00279 _dbus_transport_new_for_autolaunch (const char *scope, DBusError *error)
00280 {
00281 DBusString address;
00282 DBusTransport *result = NULL;
00283
00284 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00285
00286 if (!_dbus_string_init (&address))
00287 {
00288 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00289 return NULL;
00290 }
00291
00292 if (!_dbus_get_autolaunch_address (scope, &address, error))
00293 {
00294 _DBUS_ASSERT_ERROR_IS_SET (error);
00295 goto out;
00296 }
00297
00298 result = check_address (_dbus_string_get_const_data (&address), error);
00299 if (result == NULL)
00300 _DBUS_ASSERT_ERROR_IS_SET (error);
00301 else
00302 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00303
00304 out:
00305 _dbus_string_free (&address);
00306 return result;
00307 }
00308
00309 static DBusTransportOpenResult
00310 _dbus_transport_open_autolaunch (DBusAddressEntry *entry,
00311 DBusTransport **transport_p,
00312 DBusError *error)
00313 {
00314 const char *method;
00315
00316 method = dbus_address_entry_get_method (entry);
00317 _dbus_assert (method != NULL);
00318
00319 if (strcmp (method, "autolaunch") == 0)
00320 {
00321 const char *scope = dbus_address_entry_get_value (entry, "scope");
00322
00323 *transport_p = _dbus_transport_new_for_autolaunch (scope, error);
00324
00325 if (*transport_p == NULL)
00326 {
00327 _DBUS_ASSERT_ERROR_IS_SET (error);
00328 return DBUS_TRANSPORT_OPEN_DID_NOT_CONNECT;
00329 }
00330 else
00331 {
00332 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00333 return DBUS_TRANSPORT_OPEN_OK;
00334 }
00335 }
00336 else
00337 {
00338 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00339 return DBUS_TRANSPORT_OPEN_NOT_HANDLED;
00340 }
00341 }
00342
00343 static const struct {
00344 DBusTransportOpenResult (* func) (DBusAddressEntry *entry,
00345 DBusTransport **transport_p,
00346 DBusError *error);
00347 } open_funcs[] = {
00348 { _dbus_transport_open_socket },
00349 { _dbus_transport_open_platform_specific },
00350 { _dbus_transport_open_autolaunch }
00351 #ifdef DBUS_BUILD_TESTS
00352 , { _dbus_transport_open_debug_pipe }
00353 #endif
00354 };
00355
00364 DBusTransport*
00365 _dbus_transport_open (DBusAddressEntry *entry,
00366 DBusError *error)
00367 {
00368 DBusTransport *transport;
00369 const char *expected_guid_orig;
00370 char *expected_guid;
00371 int i;
00372 DBusError tmp_error = DBUS_ERROR_INIT;
00373
00374 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00375
00376 transport = NULL;
00377 expected_guid_orig = dbus_address_entry_get_value (entry, "guid");
00378 expected_guid = _dbus_strdup (expected_guid_orig);
00379
00380 if (expected_guid_orig != NULL && expected_guid == NULL)
00381 {
00382 _DBUS_SET_OOM (error);
00383 return NULL;
00384 }
00385
00386 for (i = 0; i < (int) _DBUS_N_ELEMENTS (open_funcs); ++i)
00387 {
00388 DBusTransportOpenResult result;
00389
00390 _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error);
00391 result = (* open_funcs[i].func) (entry, &transport, &tmp_error);
00392
00393 switch (result)
00394 {
00395 case DBUS_TRANSPORT_OPEN_OK:
00396 _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error);
00397 goto out;
00398 break;
00399 case DBUS_TRANSPORT_OPEN_NOT_HANDLED:
00400 _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error);
00401
00402 break;
00403 case DBUS_TRANSPORT_OPEN_BAD_ADDRESS:
00404 _DBUS_ASSERT_ERROR_IS_SET (&tmp_error);
00405 goto out;
00406 break;
00407 case DBUS_TRANSPORT_OPEN_DID_NOT_CONNECT:
00408 _DBUS_ASSERT_ERROR_IS_SET (&tmp_error);
00409 goto out;
00410 break;
00411 }
00412 }
00413
00414 out:
00415
00416 if (transport == NULL)
00417 {
00418 if (!dbus_error_is_set (&tmp_error))
00419 _dbus_set_bad_address (&tmp_error,
00420 NULL, NULL,
00421 "Unknown address type (examples of valid types are \"tcp\" and on UNIX \"unix\")");
00422
00423 _DBUS_ASSERT_ERROR_IS_SET (&tmp_error);
00424 dbus_move_error(&tmp_error, error);
00425 dbus_free (expected_guid);
00426 }
00427 else
00428 {
00429 _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error);
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444 if(expected_guid)
00445 transport->expected_guid = expected_guid;
00446 }
00447
00448 return transport;
00449 }
00450
00457 DBusTransport *
00458 _dbus_transport_ref (DBusTransport *transport)
00459 {
00460 _dbus_assert (transport->refcount > 0);
00461
00462 transport->refcount += 1;
00463
00464 return transport;
00465 }
00466
00474 void
00475 _dbus_transport_unref (DBusTransport *transport)
00476 {
00477 _dbus_assert (transport != NULL);
00478 _dbus_assert (transport->refcount > 0);
00479
00480 transport->refcount -= 1;
00481 if (transport->refcount == 0)
00482 {
00483 _dbus_verbose ("finalizing\n");
00484
00485 _dbus_assert (transport->vtable->finalize != NULL);
00486
00487 (* transport->vtable->finalize) (transport);
00488 }
00489 }
00490
00499 void
00500 _dbus_transport_disconnect (DBusTransport *transport)
00501 {
00502 _dbus_verbose ("start\n");
00503
00504 _dbus_assert (transport->vtable->disconnect != NULL);
00505
00506 if (transport->disconnected)
00507 return;
00508
00509 (* transport->vtable->disconnect) (transport);
00510
00511 transport->disconnected = TRUE;
00512
00513 _dbus_verbose ("end\n");
00514 }
00515
00524 dbus_bool_t
00525 _dbus_transport_get_is_connected (DBusTransport *transport)
00526 {
00527 return !transport->disconnected;
00528 }
00529
00530 static dbus_bool_t
00531 auth_via_unix_user_function (DBusTransport *transport)
00532 {
00533 DBusCredentials *auth_identity;
00534 dbus_bool_t allow;
00535 DBusConnection *connection;
00536 DBusAllowUnixUserFunction unix_user_function;
00537 void *unix_user_data;
00538 dbus_uid_t uid;
00539
00540
00541
00542 auth_identity = _dbus_auth_get_identity (transport->auth);
00543 _dbus_assert (auth_identity != NULL);
00544
00545 connection = transport->connection;
00546 unix_user_function = transport->unix_user_function;
00547 unix_user_data = transport->unix_user_data;
00548 uid = _dbus_credentials_get_unix_uid (auth_identity);
00549
00550 _dbus_verbose ("unlock\n");
00551 _dbus_connection_unlock (connection);
00552
00553 allow = (* unix_user_function) (connection,
00554 uid,
00555 unix_user_data);
00556
00557 _dbus_verbose ("lock post unix user function\n");
00558 _dbus_connection_lock (connection);
00559
00560 if (allow)
00561 {
00562 _dbus_verbose ("Client UID "DBUS_UID_FORMAT" authorized\n", uid);
00563 }
00564 else
00565 {
00566 _dbus_verbose ("Client UID "DBUS_UID_FORMAT
00567 " was rejected, disconnecting\n",
00568 _dbus_credentials_get_unix_uid (auth_identity));
00569 _dbus_transport_disconnect (transport);
00570 }
00571
00572 return allow;
00573 }
00574
00575 static dbus_bool_t
00576 auth_via_windows_user_function (DBusTransport *transport)
00577 {
00578 DBusCredentials *auth_identity;
00579 dbus_bool_t allow;
00580 DBusConnection *connection;
00581 DBusAllowWindowsUserFunction windows_user_function;
00582 void *windows_user_data;
00583 char *windows_sid;
00584
00585
00586
00587 auth_identity = _dbus_auth_get_identity (transport->auth);
00588 _dbus_assert (auth_identity != NULL);
00589
00590 connection = transport->connection;
00591 windows_user_function = transport->windows_user_function;
00592 windows_user_data = transport->unix_user_data;
00593 windows_sid = _dbus_strdup (_dbus_credentials_get_windows_sid (auth_identity));
00594
00595 if (windows_sid == NULL)
00596 {
00597
00598 return FALSE;
00599 }
00600
00601 _dbus_verbose ("unlock\n");
00602 _dbus_connection_unlock (connection);
00603
00604 allow = (* windows_user_function) (connection,
00605 windows_sid,
00606 windows_user_data);
00607
00608 _dbus_verbose ("lock post windows user function\n");
00609 _dbus_connection_lock (connection);
00610
00611 if (allow)
00612 {
00613 _dbus_verbose ("Client SID '%s' authorized\n", windows_sid);
00614 }
00615 else
00616 {
00617 _dbus_verbose ("Client SID '%s' was rejected, disconnecting\n",
00618 _dbus_credentials_get_windows_sid (auth_identity));
00619 _dbus_transport_disconnect (transport);
00620 }
00621
00622 return allow;
00623 }
00624
00625 static dbus_bool_t
00626 auth_via_default_rules (DBusTransport *transport)
00627 {
00628 DBusCredentials *auth_identity;
00629 DBusCredentials *our_identity;
00630 dbus_bool_t allow;
00631
00632 auth_identity = _dbus_auth_get_identity (transport->auth);
00633 _dbus_assert (auth_identity != NULL);
00634
00635
00636
00637
00638
00639 our_identity = _dbus_credentials_new_from_current_process ();
00640 if (our_identity == NULL)
00641 {
00642
00643 return FALSE;
00644 }
00645
00646 if (transport->allow_anonymous ||
00647 _dbus_credentials_get_unix_uid (auth_identity) == 0 ||
00648 _dbus_credentials_same_user (our_identity,
00649 auth_identity))
00650 {
00651 if (_dbus_credentials_include(our_identity,DBUS_CREDENTIAL_WINDOWS_SID))
00652 _dbus_verbose ("Client authorized as SID '%s'"
00653 "matching our SID '%s'\n",
00654 _dbus_credentials_get_windows_sid(auth_identity),
00655 _dbus_credentials_get_windows_sid(our_identity));
00656 else
00657 _dbus_verbose ("Client authorized as UID "DBUS_UID_FORMAT
00658 " matching our UID "DBUS_UID_FORMAT"\n",
00659 _dbus_credentials_get_unix_uid(auth_identity),
00660 _dbus_credentials_get_unix_uid(our_identity));
00661
00662 allow = TRUE;
00663 }
00664 else
00665 {
00666 if (_dbus_credentials_include(our_identity,DBUS_CREDENTIAL_WINDOWS_SID))
00667 _dbus_verbose ("Client authorized as SID '%s'"
00668 " but our SID is '%s', disconnecting\n",
00669 (_dbus_credentials_get_windows_sid(auth_identity) ?
00670 _dbus_credentials_get_windows_sid(auth_identity) : "<null>"),
00671 (_dbus_credentials_get_windows_sid(our_identity) ?
00672 _dbus_credentials_get_windows_sid(our_identity) : "<null>"));
00673 else
00674 _dbus_verbose ("Client authorized as UID "DBUS_UID_FORMAT
00675 " but our UID is "DBUS_UID_FORMAT", disconnecting\n",
00676 _dbus_credentials_get_unix_uid(auth_identity),
00677 _dbus_credentials_get_unix_uid(our_identity));
00678 _dbus_transport_disconnect (transport);
00679 allow = FALSE;
00680 }
00681
00682 _dbus_credentials_unref (our_identity);
00683
00684 return allow;
00685 }
00686
00687
00698 dbus_bool_t
00699 _dbus_transport_get_is_authenticated (DBusTransport *transport)
00700 {
00701 if (transport->authenticated)
00702 return TRUE;
00703 else
00704 {
00705 dbus_bool_t maybe_authenticated;
00706
00707 if (transport->disconnected)
00708 return FALSE;
00709
00710
00711 _dbus_connection_ref_unlocked (transport->connection);
00712
00713 maybe_authenticated =
00714 (!(transport->send_credentials_pending ||
00715 transport->receive_credentials_pending));
00716
00717 if (maybe_authenticated)
00718 {
00719 switch (_dbus_auth_do_work (transport->auth))
00720 {
00721 case DBUS_AUTH_STATE_AUTHENTICATED:
00722
00723 break;
00724 default:
00725 maybe_authenticated = FALSE;
00726 }
00727 }
00728
00729
00730
00731 if (maybe_authenticated && !transport->is_server)
00732 {
00733 const char *server_guid;
00734
00735 server_guid = _dbus_auth_get_guid_from_server (transport->auth);
00736 _dbus_assert (server_guid != NULL);
00737
00738 if (transport->expected_guid &&
00739 strcmp (transport->expected_guid, server_guid) != 0)
00740 {
00741 _dbus_verbose ("Client expected GUID '%s' and we got '%s' from the server\n",
00742 transport->expected_guid, server_guid);
00743 _dbus_transport_disconnect (transport);
00744 _dbus_connection_unref_unlocked (transport->connection);
00745 return FALSE;
00746 }
00747 }
00748
00749
00750
00751 if (maybe_authenticated && transport->is_server)
00752 {
00753 dbus_bool_t allow;
00754 DBusCredentials *auth_identity;
00755
00756 auth_identity = _dbus_auth_get_identity (transport->auth);
00757 _dbus_assert (auth_identity != NULL);
00758
00759
00760
00761
00762
00763 if (transport->unix_user_function != NULL &&
00764 _dbus_credentials_include (auth_identity, DBUS_CREDENTIAL_UNIX_USER_ID))
00765 {
00766 allow = auth_via_unix_user_function (transport);
00767 }
00768 else if (transport->windows_user_function != NULL &&
00769 _dbus_credentials_include (auth_identity, DBUS_CREDENTIAL_WINDOWS_SID))
00770 {
00771 allow = auth_via_windows_user_function (transport);
00772 }
00773 else
00774 {
00775 allow = auth_via_default_rules (transport);
00776 }
00777
00778 if (!allow)
00779 maybe_authenticated = FALSE;
00780 }
00781
00782 transport->authenticated = maybe_authenticated;
00783
00784 _dbus_connection_unref_unlocked (transport->connection);
00785 return maybe_authenticated;
00786 }
00787 }
00788
00795 dbus_bool_t
00796 _dbus_transport_get_is_anonymous (DBusTransport *transport)
00797 {
00798 DBusCredentials *auth_identity;
00799
00800 if (!transport->authenticated)
00801 return TRUE;
00802
00803 auth_identity = _dbus_auth_get_identity (transport->auth);
00804
00805 if (_dbus_credentials_are_anonymous (auth_identity))
00806 return TRUE;
00807 else
00808 return FALSE;
00809 }
00810
00817 dbus_bool_t
00818 _dbus_transport_can_pass_unix_fd(DBusTransport *transport)
00819 {
00820 return DBUS_TRANSPORT_CAN_SEND_UNIX_FD(transport);
00821 }
00822
00830 const char*
00831 _dbus_transport_get_address (DBusTransport *transport)
00832 {
00833 return transport->address;
00834 }
00835
00843 const char*
00844 _dbus_transport_get_server_id (DBusTransport *transport)
00845 {
00846 if (transport->is_server)
00847 return NULL;
00848 else if (transport->authenticated)
00849 return _dbus_auth_get_guid_from_server (transport->auth);
00850 else
00851 return transport->expected_guid;
00852 }
00853
00863 dbus_bool_t
00864 _dbus_transport_handle_watch (DBusTransport *transport,
00865 DBusWatch *watch,
00866 unsigned int condition)
00867 {
00868 dbus_bool_t retval;
00869
00870 _dbus_assert (transport->vtable->handle_watch != NULL);
00871
00872 if (transport->disconnected)
00873 return TRUE;
00874
00875 if (dbus_watch_get_socket (watch) < 0)
00876 {
00877 _dbus_warn_check_failed ("Tried to handle an invalidated watch; this watch should have been removed\n");
00878 return TRUE;
00879 }
00880
00881 _dbus_watch_sanitize_condition (watch, &condition);
00882
00883 _dbus_transport_ref (transport);
00884 _dbus_watch_ref (watch);
00885 retval = (* transport->vtable->handle_watch) (transport, watch, condition);
00886 _dbus_watch_unref (watch);
00887 _dbus_transport_unref (transport);
00888
00889 return retval;
00890 }
00891
00901 dbus_bool_t
00902 _dbus_transport_set_connection (DBusTransport *transport,
00903 DBusConnection *connection)
00904 {
00905 _dbus_assert (transport->vtable->connection_set != NULL);
00906 _dbus_assert (transport->connection == NULL);
00907
00908 transport->connection = connection;
00909
00910 _dbus_transport_ref (transport);
00911 if (!(* transport->vtable->connection_set) (transport))
00912 transport->connection = NULL;
00913 _dbus_transport_unref (transport);
00914
00915 return transport->connection != NULL;
00916 }
00917
00925 dbus_bool_t
00926 _dbus_transport_get_socket_fd (DBusTransport *transport,
00927 int *fd_p)
00928 {
00929 dbus_bool_t retval;
00930
00931 if (transport->vtable->get_socket_fd == NULL)
00932 return FALSE;
00933
00934 if (transport->disconnected)
00935 return FALSE;
00936
00937 _dbus_transport_ref (transport);
00938
00939 retval = (* transport->vtable->get_socket_fd) (transport,
00940 fd_p);
00941
00942 _dbus_transport_unref (transport);
00943
00944 return retval;
00945 }
00946
00958 void
00959 _dbus_transport_do_iteration (DBusTransport *transport,
00960 unsigned int flags,
00961 int timeout_milliseconds)
00962 {
00963 _dbus_assert (transport->vtable->do_iteration != NULL);
00964
00965 _dbus_verbose ("Transport iteration flags 0x%x timeout %d connected = %d\n",
00966 flags, timeout_milliseconds, !transport->disconnected);
00967
00968 if ((flags & (DBUS_ITERATION_DO_WRITING |
00969 DBUS_ITERATION_DO_READING)) == 0)
00970 return;
00971
00972 if (transport->disconnected)
00973 return;
00974
00975 _dbus_transport_ref (transport);
00976 (* transport->vtable->do_iteration) (transport, flags,
00977 timeout_milliseconds);
00978 _dbus_transport_unref (transport);
00979
00980 _dbus_verbose ("end\n");
00981 }
00982
00983 static dbus_bool_t
00984 recover_unused_bytes (DBusTransport *transport)
00985 {
00986 if (_dbus_auth_needs_decoding (transport->auth))
00987 {
00988 DBusString plaintext;
00989 const DBusString *encoded;
00990 DBusString *buffer;
00991 int orig_len;
00992
00993 if (!_dbus_string_init (&plaintext))
00994 goto nomem;
00995
00996 _dbus_auth_get_unused_bytes (transport->auth,
00997 &encoded);
00998
00999 if (!_dbus_auth_decode_data (transport->auth,
01000 encoded, &plaintext))
01001 {
01002 _dbus_string_free (&plaintext);
01003 goto nomem;
01004 }
01005
01006 _dbus_message_loader_get_buffer (transport->loader,
01007 &buffer);
01008
01009 orig_len = _dbus_string_get_length (buffer);
01010
01011 if (!_dbus_string_move (&plaintext, 0, buffer,
01012 orig_len))
01013 {
01014 _dbus_string_free (&plaintext);
01015 goto nomem;
01016 }
01017
01018 _dbus_verbose (" %d unused bytes sent to message loader\n",
01019 _dbus_string_get_length (buffer) -
01020 orig_len);
01021
01022 _dbus_message_loader_return_buffer (transport->loader,
01023 buffer,
01024 _dbus_string_get_length (buffer) -
01025 orig_len);
01026
01027 _dbus_auth_delete_unused_bytes (transport->auth);
01028
01029 _dbus_string_free (&plaintext);
01030 }
01031 else
01032 {
01033 const DBusString *bytes;
01034 DBusString *buffer;
01035 int orig_len;
01036 dbus_bool_t succeeded;
01037
01038 _dbus_message_loader_get_buffer (transport->loader,
01039 &buffer);
01040
01041 orig_len = _dbus_string_get_length (buffer);
01042
01043 _dbus_auth_get_unused_bytes (transport->auth,
01044 &bytes);
01045
01046 succeeded = TRUE;
01047 if (!_dbus_string_copy (bytes, 0, buffer, _dbus_string_get_length (buffer)))
01048 succeeded = FALSE;
01049
01050 _dbus_verbose (" %d unused bytes sent to message loader\n",
01051 _dbus_string_get_length (buffer) -
01052 orig_len);
01053
01054 _dbus_message_loader_return_buffer (transport->loader,
01055 buffer,
01056 _dbus_string_get_length (buffer) -
01057 orig_len);
01058
01059 if (succeeded)
01060 _dbus_auth_delete_unused_bytes (transport->auth);
01061 else
01062 goto nomem;
01063 }
01064
01065 return TRUE;
01066
01067 nomem:
01068 _dbus_verbose ("Not enough memory to transfer unused bytes from auth conversation\n");
01069 return FALSE;
01070 }
01071
01079 DBusDispatchStatus
01080 _dbus_transport_get_dispatch_status (DBusTransport *transport)
01081 {
01082 if (_dbus_counter_get_size_value (transport->live_messages) >= transport->max_live_messages_size ||
01083 _dbus_counter_get_unix_fd_value (transport->live_messages) >= transport->max_live_messages_unix_fds)
01084 return DBUS_DISPATCH_COMPLETE;
01085
01086 if (!_dbus_transport_get_is_authenticated (transport))
01087 {
01088 if (_dbus_auth_do_work (transport->auth) ==
01089 DBUS_AUTH_STATE_WAITING_FOR_MEMORY)
01090 return DBUS_DISPATCH_NEED_MEMORY;
01091 else if (!_dbus_transport_get_is_authenticated (transport))
01092 return DBUS_DISPATCH_COMPLETE;
01093 }
01094
01095 if (!transport->unused_bytes_recovered &&
01096 !recover_unused_bytes (transport))
01097 return DBUS_DISPATCH_NEED_MEMORY;
01098
01099 transport->unused_bytes_recovered = TRUE;
01100
01101 if (!_dbus_message_loader_queue_messages (transport->loader))
01102 return DBUS_DISPATCH_NEED_MEMORY;
01103
01104 if (_dbus_message_loader_peek_message (transport->loader) != NULL)
01105 return DBUS_DISPATCH_DATA_REMAINS;
01106 else
01107 return DBUS_DISPATCH_COMPLETE;
01108 }
01109
01118 dbus_bool_t
01119 _dbus_transport_queue_messages (DBusTransport *transport)
01120 {
01121 DBusDispatchStatus status;
01122
01123 #if 0
01124 _dbus_verbose ("_dbus_transport_queue_messages()\n");
01125 #endif
01126
01127
01128 while ((status = _dbus_transport_get_dispatch_status (transport)) == DBUS_DISPATCH_DATA_REMAINS)
01129 {
01130 DBusMessage *message;
01131 DBusList *link;
01132
01133 link = _dbus_message_loader_pop_message_link (transport->loader);
01134 _dbus_assert (link != NULL);
01135
01136 message = link->data;
01137
01138 _dbus_verbose ("queueing received message %p\n", message);
01139
01140 if (!_dbus_message_add_counter (message, transport->live_messages))
01141 {
01142 _dbus_message_loader_putback_message_link (transport->loader,
01143 link);
01144 status = DBUS_DISPATCH_NEED_MEMORY;
01145 break;
01146 }
01147 else
01148 {
01149
01150
01151
01152
01153 if (transport->vtable->live_messages_changed)
01154 (* transport->vtable->live_messages_changed) (transport);
01155
01156
01157 _dbus_connection_queue_received_message_link (transport->connection,
01158 link);
01159 }
01160 }
01161
01162 if (_dbus_message_loader_get_is_corrupted (transport->loader))
01163 {
01164 _dbus_verbose ("Corrupted message stream, disconnecting\n");
01165 _dbus_transport_disconnect (transport);
01166 }
01167
01168 return status != DBUS_DISPATCH_NEED_MEMORY;
01169 }
01170
01177 void
01178 _dbus_transport_set_max_message_size (DBusTransport *transport,
01179 long size)
01180 {
01181 _dbus_message_loader_set_max_message_size (transport->loader, size);
01182 }
01183
01190 void
01191 _dbus_transport_set_max_message_unix_fds (DBusTransport *transport,
01192 long n)
01193 {
01194 _dbus_message_loader_set_max_message_unix_fds (transport->loader, n);
01195 }
01196
01203 long
01204 _dbus_transport_get_max_message_size (DBusTransport *transport)
01205 {
01206 return _dbus_message_loader_get_max_message_size (transport->loader);
01207 }
01208
01215 long
01216 _dbus_transport_get_max_message_unix_fds (DBusTransport *transport)
01217 {
01218 return _dbus_message_loader_get_max_message_unix_fds (transport->loader);
01219 }
01220
01227 void
01228 _dbus_transport_set_max_received_size (DBusTransport *transport,
01229 long size)
01230 {
01231 transport->max_live_messages_size = size;
01232 _dbus_counter_set_notify (transport->live_messages,
01233 transport->max_live_messages_size,
01234 transport->max_live_messages_unix_fds,
01235 live_messages_notify,
01236 transport);
01237 }
01238
01245 void
01246 _dbus_transport_set_max_received_unix_fds (DBusTransport *transport,
01247 long n)
01248 {
01249 transport->max_live_messages_unix_fds = n;
01250 _dbus_counter_set_notify (transport->live_messages,
01251 transport->max_live_messages_size,
01252 transport->max_live_messages_unix_fds,
01253 live_messages_notify,
01254 transport);
01255 }
01256
01263 long
01264 _dbus_transport_get_max_received_size (DBusTransport *transport)
01265 {
01266 return transport->max_live_messages_size;
01267 }
01268
01275 long
01276 _dbus_transport_get_max_received_unix_fds (DBusTransport *transport)
01277 {
01278 return transport->max_live_messages_unix_fds;
01279 }
01280
01288 dbus_bool_t
01289 _dbus_transport_get_unix_user (DBusTransport *transport,
01290 unsigned long *uid)
01291 {
01292 DBusCredentials *auth_identity;
01293
01294 *uid = _DBUS_INT32_MAX;
01295
01296
01297
01298
01299 if (!transport->authenticated)
01300 return FALSE;
01301
01302 auth_identity = _dbus_auth_get_identity (transport->auth);
01303
01304 if (_dbus_credentials_include (auth_identity,
01305 DBUS_CREDENTIAL_UNIX_USER_ID))
01306 {
01307 *uid = _dbus_credentials_get_unix_uid (auth_identity);
01308 return TRUE;
01309 }
01310 else
01311 return FALSE;
01312 }
01313
01321 dbus_bool_t
01322 _dbus_transport_get_unix_process_id (DBusTransport *transport,
01323 unsigned long *pid)
01324 {
01325 DBusCredentials *auth_identity;
01326
01327 *pid = DBUS_PID_UNSET;
01328
01329
01330
01331
01332 if (!transport->authenticated)
01333 return FALSE;
01334
01335 auth_identity = _dbus_auth_get_identity (transport->auth);
01336
01337 if (_dbus_credentials_include (auth_identity,
01338 DBUS_CREDENTIAL_UNIX_PROCESS_ID))
01339 {
01340 *pid = _dbus_credentials_get_unix_pid (auth_identity);
01341 return TRUE;
01342 }
01343 else
01344 return FALSE;
01345 }
01346
01355 dbus_bool_t
01356 _dbus_transport_get_adt_audit_session_data (DBusTransport *transport,
01357 void **data,
01358 int *data_size)
01359 {
01360 DBusCredentials *auth_identity;
01361
01362 *data = NULL;
01363 *data_size = 0;
01364
01365 if (!transport->authenticated)
01366 return FALSE;
01367
01368 auth_identity = _dbus_auth_get_identity (transport->auth);
01369
01370 if (_dbus_credentials_include (auth_identity,
01371 DBUS_CREDENTIAL_ADT_AUDIT_DATA_ID))
01372 {
01373 *data = (void *) _dbus_credentials_get_adt_audit_data (auth_identity);
01374 *data_size = _dbus_credentials_get_adt_audit_data_size (auth_identity);
01375 return TRUE;
01376 }
01377 else
01378 return FALSE;
01379 }
01380
01391 void
01392 _dbus_transport_set_unix_user_function (DBusTransport *transport,
01393 DBusAllowUnixUserFunction function,
01394 void *data,
01395 DBusFreeFunction free_data_function,
01396 void **old_data,
01397 DBusFreeFunction *old_free_data_function)
01398 {
01399 *old_data = transport->unix_user_data;
01400 *old_free_data_function = transport->free_unix_user_data;
01401
01402 transport->unix_user_function = function;
01403 transport->unix_user_data = data;
01404 transport->free_unix_user_data = free_data_function;
01405 }
01406
01414 dbus_bool_t
01415 _dbus_transport_get_windows_user (DBusTransport *transport,
01416 char **windows_sid_p)
01417 {
01418 DBusCredentials *auth_identity;
01419
01420 *windows_sid_p = NULL;
01421
01422 if (!transport->authenticated)
01423 return FALSE;
01424
01425 auth_identity = _dbus_auth_get_identity (transport->auth);
01426
01427 if (_dbus_credentials_include (auth_identity,
01428 DBUS_CREDENTIAL_WINDOWS_SID))
01429 {
01430
01431 *windows_sid_p = _dbus_strdup (_dbus_credentials_get_windows_sid (auth_identity));
01432
01433 return TRUE;
01434 }
01435 else
01436 return FALSE;
01437 }
01438
01450 void
01451 _dbus_transport_set_windows_user_function (DBusTransport *transport,
01452 DBusAllowWindowsUserFunction function,
01453 void *data,
01454 DBusFreeFunction free_data_function,
01455 void **old_data,
01456 DBusFreeFunction *old_free_data_function)
01457 {
01458 *old_data = transport->windows_user_data;
01459 *old_free_data_function = transport->free_windows_user_data;
01460
01461 transport->windows_user_function = function;
01462 transport->windows_user_data = data;
01463 transport->free_windows_user_data = free_data_function;
01464 }
01465
01474 dbus_bool_t
01475 _dbus_transport_set_auth_mechanisms (DBusTransport *transport,
01476 const char **mechanisms)
01477 {
01478 return _dbus_auth_set_mechanisms (transport->auth, mechanisms);
01479 }
01480
01487 void
01488 _dbus_transport_set_allow_anonymous (DBusTransport *transport,
01489 dbus_bool_t value)
01490 {
01491 transport->allow_anonymous = value != FALSE;
01492 }
01493
01494 #ifdef DBUS_ENABLE_STATS
01495 void
01496 _dbus_transport_get_stats (DBusTransport *transport,
01497 dbus_uint32_t *queue_bytes,
01498 dbus_uint32_t *queue_fds,
01499 dbus_uint32_t *peak_queue_bytes,
01500 dbus_uint32_t *peak_queue_fds)
01501 {
01502 if (queue_bytes != NULL)
01503 *queue_bytes = _dbus_counter_get_size_value (transport->live_messages);
01504
01505 if (queue_fds != NULL)
01506 *queue_fds = _dbus_counter_get_unix_fd_value (transport->live_messages);
01507
01508 if (peak_queue_bytes != NULL)
01509 *peak_queue_bytes = _dbus_counter_get_peak_size_value (transport->live_messages);
01510
01511 if (peak_queue_fds != NULL)
01512 *peak_queue_fds = _dbus_counter_get_peak_unix_fd_value (transport->live_messages);
01513 }
01514 #endif
01515