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_ENABLE_EMBEDDED_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_connection_lock (transport->connection);
00067 _dbus_transport_ref (transport);
00068
00069 #if 0
00070 _dbus_verbose ("Size counter value is now %d\n",
00071 (int) _dbus_counter_get_size_value (counter));
00072 _dbus_verbose ("Unix FD counter value is now %d\n",
00073 (int) _dbus_counter_get_unix_fd_value (counter));
00074 #endif
00075
00076
00077
00078
00079 if (transport->vtable->live_messages_changed)
00080 {
00081 (* transport->vtable->live_messages_changed) (transport);
00082 }
00083
00084 _dbus_transport_unref (transport);
00085 _dbus_connection_unlock (transport->connection);
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
00249 static DBusTransport*
00250 check_address (const char *address, DBusError *error)
00251 {
00252 DBusAddressEntry **entries;
00253 DBusTransport *transport = NULL;
00254 int len, i;
00255
00256 _dbus_assert (address != NULL);
00257
00258 if (!dbus_parse_address (address, &entries, &len, error))
00259 return NULL;
00260
00261 for (i = 0; i < len; i++)
00262 {
00263 transport = _dbus_transport_open (entries[i], error);
00264 if (transport != NULL)
00265 break;
00266 }
00267
00268 dbus_address_entries_free (entries);
00269 return transport;
00270 }
00271
00280 static DBusTransport*
00281 _dbus_transport_new_for_autolaunch (const char *scope, DBusError *error)
00282 {
00283 DBusString address;
00284 DBusTransport *result = NULL;
00285
00286 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00287
00288 if (!_dbus_string_init (&address))
00289 {
00290 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00291 return NULL;
00292 }
00293
00294 if (!_dbus_get_autolaunch_address (scope, &address, error))
00295 {
00296 _DBUS_ASSERT_ERROR_IS_SET (error);
00297 goto out;
00298 }
00299
00300 result = check_address (_dbus_string_get_const_data (&address), error);
00301 if (result == NULL)
00302 _DBUS_ASSERT_ERROR_IS_SET (error);
00303 else
00304 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00305
00306 out:
00307 _dbus_string_free (&address);
00308 return result;
00309 }
00310
00311 static DBusTransportOpenResult
00312 _dbus_transport_open_autolaunch (DBusAddressEntry *entry,
00313 DBusTransport **transport_p,
00314 DBusError *error)
00315 {
00316 const char *method;
00317
00318 method = dbus_address_entry_get_method (entry);
00319 _dbus_assert (method != NULL);
00320
00321 if (strcmp (method, "autolaunch") == 0)
00322 {
00323 const char *scope = dbus_address_entry_get_value (entry, "scope");
00324
00325 *transport_p = _dbus_transport_new_for_autolaunch (scope, error);
00326
00327 if (*transport_p == NULL)
00328 {
00329 _DBUS_ASSERT_ERROR_IS_SET (error);
00330 return DBUS_TRANSPORT_OPEN_DID_NOT_CONNECT;
00331 }
00332 else
00333 {
00334 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00335 return DBUS_TRANSPORT_OPEN_OK;
00336 }
00337 }
00338 else
00339 {
00340 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00341 return DBUS_TRANSPORT_OPEN_NOT_HANDLED;
00342 }
00343 }
00344
00345 static const struct {
00346 DBusTransportOpenResult (* func) (DBusAddressEntry *entry,
00347 DBusTransport **transport_p,
00348 DBusError *error);
00349 } open_funcs[] = {
00350 { _dbus_transport_open_socket },
00351 { _dbus_transport_open_platform_specific },
00352 { _dbus_transport_open_autolaunch }
00353 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
00354 , { _dbus_transport_open_debug_pipe }
00355 #endif
00356 };
00357
00366 DBusTransport*
00367 _dbus_transport_open (DBusAddressEntry *entry,
00368 DBusError *error)
00369 {
00370 DBusTransport *transport;
00371 const char *expected_guid_orig;
00372 char *expected_guid;
00373 int i;
00374 DBusError tmp_error = DBUS_ERROR_INIT;
00375
00376 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00377
00378 transport = NULL;
00379 expected_guid_orig = dbus_address_entry_get_value (entry, "guid");
00380 expected_guid = _dbus_strdup (expected_guid_orig);
00381
00382 if (expected_guid_orig != NULL && expected_guid == NULL)
00383 {
00384 _DBUS_SET_OOM (error);
00385 return NULL;
00386 }
00387
00388 for (i = 0; i < (int) _DBUS_N_ELEMENTS (open_funcs); ++i)
00389 {
00390 DBusTransportOpenResult result;
00391
00392 _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error);
00393 result = (* open_funcs[i].func) (entry, &transport, &tmp_error);
00394
00395 switch (result)
00396 {
00397 case DBUS_TRANSPORT_OPEN_OK:
00398 _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error);
00399 goto out;
00400 break;
00401 case DBUS_TRANSPORT_OPEN_NOT_HANDLED:
00402 _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error);
00403
00404 break;
00405 case DBUS_TRANSPORT_OPEN_BAD_ADDRESS:
00406 _DBUS_ASSERT_ERROR_IS_SET (&tmp_error);
00407 goto out;
00408 break;
00409 case DBUS_TRANSPORT_OPEN_DID_NOT_CONNECT:
00410 _DBUS_ASSERT_ERROR_IS_SET (&tmp_error);
00411 goto out;
00412 break;
00413 }
00414 }
00415
00416 out:
00417
00418 if (transport == NULL)
00419 {
00420 if (!dbus_error_is_set (&tmp_error))
00421 _dbus_set_bad_address (&tmp_error,
00422 NULL, NULL,
00423 "Unknown address type (examples of valid types are \"tcp\" and on UNIX \"unix\")");
00424
00425 _DBUS_ASSERT_ERROR_IS_SET (&tmp_error);
00426 dbus_move_error(&tmp_error, error);
00427 dbus_free (expected_guid);
00428 }
00429 else
00430 {
00431 _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error);
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446 if(expected_guid)
00447 transport->expected_guid = expected_guid;
00448 }
00449
00450 return transport;
00451 }
00452
00459 DBusTransport *
00460 _dbus_transport_ref (DBusTransport *transport)
00461 {
00462 _dbus_assert (transport->refcount > 0);
00463
00464 transport->refcount += 1;
00465
00466 return transport;
00467 }
00468
00476 void
00477 _dbus_transport_unref (DBusTransport *transport)
00478 {
00479 _dbus_assert (transport != NULL);
00480 _dbus_assert (transport->refcount > 0);
00481
00482 transport->refcount -= 1;
00483 if (transport->refcount == 0)
00484 {
00485 _dbus_verbose ("finalizing\n");
00486
00487 _dbus_assert (transport->vtable->finalize != NULL);
00488
00489 (* transport->vtable->finalize) (transport);
00490 }
00491 }
00492
00501 void
00502 _dbus_transport_disconnect (DBusTransport *transport)
00503 {
00504 _dbus_verbose ("start\n");
00505
00506 _dbus_assert (transport->vtable->disconnect != NULL);
00507
00508 if (transport->disconnected)
00509 return;
00510
00511 (* transport->vtable->disconnect) (transport);
00512
00513 transport->disconnected = TRUE;
00514
00515 _dbus_verbose ("end\n");
00516 }
00517
00526 dbus_bool_t
00527 _dbus_transport_get_is_connected (DBusTransport *transport)
00528 {
00529 return !transport->disconnected;
00530 }
00531
00532 static dbus_bool_t
00533 auth_via_unix_user_function (DBusTransport *transport)
00534 {
00535 DBusCredentials *auth_identity;
00536 dbus_bool_t allow;
00537 DBusConnection *connection;
00538 DBusAllowUnixUserFunction unix_user_function;
00539 void *unix_user_data;
00540 dbus_uid_t uid;
00541
00542
00543
00544 auth_identity = _dbus_auth_get_identity (transport->auth);
00545 _dbus_assert (auth_identity != NULL);
00546
00547 connection = transport->connection;
00548 unix_user_function = transport->unix_user_function;
00549 unix_user_data = transport->unix_user_data;
00550 uid = _dbus_credentials_get_unix_uid (auth_identity);
00551
00552 _dbus_verbose ("unlock\n");
00553 _dbus_connection_unlock (connection);
00554
00555 allow = (* unix_user_function) (connection,
00556 uid,
00557 unix_user_data);
00558
00559 _dbus_verbose ("lock post unix user function\n");
00560 _dbus_connection_lock (connection);
00561
00562 if (allow)
00563 {
00564 _dbus_verbose ("Client UID "DBUS_UID_FORMAT" authorized\n", uid);
00565 }
00566 else
00567 {
00568 _dbus_verbose ("Client UID "DBUS_UID_FORMAT
00569 " was rejected, disconnecting\n",
00570 _dbus_credentials_get_unix_uid (auth_identity));
00571 _dbus_transport_disconnect (transport);
00572 }
00573
00574 return allow;
00575 }
00576
00577 static dbus_bool_t
00578 auth_via_windows_user_function (DBusTransport *transport)
00579 {
00580 DBusCredentials *auth_identity;
00581 dbus_bool_t allow;
00582 DBusConnection *connection;
00583 DBusAllowWindowsUserFunction windows_user_function;
00584 void *windows_user_data;
00585 char *windows_sid;
00586
00587
00588
00589 auth_identity = _dbus_auth_get_identity (transport->auth);
00590 _dbus_assert (auth_identity != NULL);
00591
00592 connection = transport->connection;
00593 windows_user_function = transport->windows_user_function;
00594 windows_user_data = transport->unix_user_data;
00595 windows_sid = _dbus_strdup (_dbus_credentials_get_windows_sid (auth_identity));
00596
00597 if (windows_sid == NULL)
00598 {
00599
00600 return FALSE;
00601 }
00602
00603 _dbus_verbose ("unlock\n");
00604 _dbus_connection_unlock (connection);
00605
00606 allow = (* windows_user_function) (connection,
00607 windows_sid,
00608 windows_user_data);
00609
00610 _dbus_verbose ("lock post windows user function\n");
00611 _dbus_connection_lock (connection);
00612
00613 if (allow)
00614 {
00615 _dbus_verbose ("Client SID '%s' authorized\n", windows_sid);
00616 }
00617 else
00618 {
00619 _dbus_verbose ("Client SID '%s' was rejected, disconnecting\n",
00620 _dbus_credentials_get_windows_sid (auth_identity));
00621 _dbus_transport_disconnect (transport);
00622 }
00623
00624 return allow;
00625 }
00626
00627 static dbus_bool_t
00628 auth_via_default_rules (DBusTransport *transport)
00629 {
00630 DBusCredentials *auth_identity;
00631 DBusCredentials *our_identity;
00632 dbus_bool_t allow;
00633
00634 auth_identity = _dbus_auth_get_identity (transport->auth);
00635 _dbus_assert (auth_identity != NULL);
00636
00637
00638
00639
00640
00641 our_identity = _dbus_credentials_new_from_current_process ();
00642 if (our_identity == NULL)
00643 {
00644
00645 return FALSE;
00646 }
00647
00648 if (transport->allow_anonymous ||
00649 _dbus_credentials_get_unix_uid (auth_identity) == 0 ||
00650 _dbus_credentials_same_user (our_identity,
00651 auth_identity))
00652 {
00653 if (_dbus_credentials_include(our_identity,DBUS_CREDENTIAL_WINDOWS_SID))
00654 _dbus_verbose ("Client authorized as SID '%s'"
00655 "matching our SID '%s'\n",
00656 _dbus_credentials_get_windows_sid(auth_identity),
00657 _dbus_credentials_get_windows_sid(our_identity));
00658 else
00659 _dbus_verbose ("Client authorized as UID "DBUS_UID_FORMAT
00660 " matching our UID "DBUS_UID_FORMAT"\n",
00661 _dbus_credentials_get_unix_uid(auth_identity),
00662 _dbus_credentials_get_unix_uid(our_identity));
00663
00664 allow = TRUE;
00665 }
00666 else
00667 {
00668 if (_dbus_credentials_include(our_identity,DBUS_CREDENTIAL_WINDOWS_SID))
00669 _dbus_verbose ("Client authorized as SID '%s'"
00670 " but our SID is '%s', disconnecting\n",
00671 (_dbus_credentials_get_windows_sid(auth_identity) ?
00672 _dbus_credentials_get_windows_sid(auth_identity) : "<null>"),
00673 (_dbus_credentials_get_windows_sid(our_identity) ?
00674 _dbus_credentials_get_windows_sid(our_identity) : "<null>"));
00675 else
00676 _dbus_verbose ("Client authorized as UID "DBUS_UID_FORMAT
00677 " but our UID is "DBUS_UID_FORMAT", disconnecting\n",
00678 _dbus_credentials_get_unix_uid(auth_identity),
00679 _dbus_credentials_get_unix_uid(our_identity));
00680 _dbus_transport_disconnect (transport);
00681 allow = FALSE;
00682 }
00683
00684 _dbus_credentials_unref (our_identity);
00685
00686 return allow;
00687 }
00688
00700 dbus_bool_t
00701 _dbus_transport_peek_is_authenticated (DBusTransport *transport)
00702 {
00703 return transport->authenticated;
00704 }
00705
00723 dbus_bool_t
00724 _dbus_transport_try_to_authenticate (DBusTransport *transport)
00725 {
00726 if (transport->authenticated)
00727 return TRUE;
00728 else
00729 {
00730 dbus_bool_t maybe_authenticated;
00731
00732 if (transport->disconnected)
00733 return FALSE;
00734
00735
00736 _dbus_connection_ref_unlocked (transport->connection);
00737
00738 maybe_authenticated =
00739 (!(transport->send_credentials_pending ||
00740 transport->receive_credentials_pending));
00741
00742 if (maybe_authenticated)
00743 {
00744 switch (_dbus_auth_do_work (transport->auth))
00745 {
00746 case DBUS_AUTH_STATE_AUTHENTICATED:
00747
00748 break;
00749 default:
00750 maybe_authenticated = FALSE;
00751 }
00752 }
00753
00754
00755
00756 if (maybe_authenticated && !transport->is_server)
00757 {
00758 const char *server_guid;
00759
00760 server_guid = _dbus_auth_get_guid_from_server (transport->auth);
00761 _dbus_assert (server_guid != NULL);
00762
00763 if (transport->expected_guid &&
00764 strcmp (transport->expected_guid, server_guid) != 0)
00765 {
00766 _dbus_verbose ("Client expected GUID '%s' and we got '%s' from the server\n",
00767 transport->expected_guid, server_guid);
00768 _dbus_transport_disconnect (transport);
00769 _dbus_connection_unref_unlocked (transport->connection);
00770 return FALSE;
00771 }
00772 }
00773
00774
00775
00776 if (maybe_authenticated && transport->is_server)
00777 {
00778 dbus_bool_t allow;
00779 DBusCredentials *auth_identity;
00780
00781 auth_identity = _dbus_auth_get_identity (transport->auth);
00782 _dbus_assert (auth_identity != NULL);
00783
00784
00785
00786
00787
00788 if (transport->unix_user_function != NULL &&
00789 _dbus_credentials_include (auth_identity, DBUS_CREDENTIAL_UNIX_USER_ID))
00790 {
00791 allow = auth_via_unix_user_function (transport);
00792 }
00793 else if (transport->windows_user_function != NULL &&
00794 _dbus_credentials_include (auth_identity, DBUS_CREDENTIAL_WINDOWS_SID))
00795 {
00796 allow = auth_via_windows_user_function (transport);
00797 }
00798 else
00799 {
00800 allow = auth_via_default_rules (transport);
00801 }
00802
00803 if (!allow)
00804 maybe_authenticated = FALSE;
00805 }
00806
00807 transport->authenticated = maybe_authenticated;
00808
00809 _dbus_connection_unref_unlocked (transport->connection);
00810 return maybe_authenticated;
00811 }
00812 }
00813
00820 dbus_bool_t
00821 _dbus_transport_get_is_anonymous (DBusTransport *transport)
00822 {
00823 DBusCredentials *auth_identity;
00824
00825 if (!transport->authenticated)
00826 return TRUE;
00827
00828 auth_identity = _dbus_auth_get_identity (transport->auth);
00829
00830 if (_dbus_credentials_are_anonymous (auth_identity))
00831 return TRUE;
00832 else
00833 return FALSE;
00834 }
00835
00842 dbus_bool_t
00843 _dbus_transport_can_pass_unix_fd(DBusTransport *transport)
00844 {
00845 return DBUS_TRANSPORT_CAN_SEND_UNIX_FD(transport);
00846 }
00847
00855 const char*
00856 _dbus_transport_get_address (DBusTransport *transport)
00857 {
00858 return transport->address;
00859 }
00860
00868 const char*
00869 _dbus_transport_get_server_id (DBusTransport *transport)
00870 {
00871 if (transport->is_server)
00872 return NULL;
00873 else if (transport->authenticated)
00874 return _dbus_auth_get_guid_from_server (transport->auth);
00875 else
00876 return transport->expected_guid;
00877 }
00878
00888 dbus_bool_t
00889 _dbus_transport_handle_watch (DBusTransport *transport,
00890 DBusWatch *watch,
00891 unsigned int condition)
00892 {
00893 dbus_bool_t retval;
00894
00895 _dbus_assert (transport->vtable->handle_watch != NULL);
00896
00897 if (transport->disconnected)
00898 return TRUE;
00899
00900 if (dbus_watch_get_socket (watch) < 0)
00901 {
00902 _dbus_warn_check_failed ("Tried to handle an invalidated watch; this watch should have been removed\n");
00903 return TRUE;
00904 }
00905
00906 _dbus_watch_sanitize_condition (watch, &condition);
00907
00908 _dbus_transport_ref (transport);
00909 _dbus_watch_ref (watch);
00910 retval = (* transport->vtable->handle_watch) (transport, watch, condition);
00911 _dbus_watch_unref (watch);
00912 _dbus_transport_unref (transport);
00913
00914 return retval;
00915 }
00916
00926 dbus_bool_t
00927 _dbus_transport_set_connection (DBusTransport *transport,
00928 DBusConnection *connection)
00929 {
00930 _dbus_assert (transport->vtable->connection_set != NULL);
00931 _dbus_assert (transport->connection == NULL);
00932
00933 transport->connection = connection;
00934
00935 _dbus_transport_ref (transport);
00936 if (!(* transport->vtable->connection_set) (transport))
00937 transport->connection = NULL;
00938 _dbus_transport_unref (transport);
00939
00940 return transport->connection != NULL;
00941 }
00942
00950 dbus_bool_t
00951 _dbus_transport_get_socket_fd (DBusTransport *transport,
00952 DBusSocket *fd_p)
00953 {
00954 dbus_bool_t retval;
00955
00956 if (transport->vtable->get_socket_fd == NULL)
00957 return FALSE;
00958
00959 if (transport->disconnected)
00960 return FALSE;
00961
00962 _dbus_transport_ref (transport);
00963
00964 retval = (* transport->vtable->get_socket_fd) (transport,
00965 fd_p);
00966
00967 _dbus_transport_unref (transport);
00968
00969 return retval;
00970 }
00971
00983 void
00984 _dbus_transport_do_iteration (DBusTransport *transport,
00985 unsigned int flags,
00986 int timeout_milliseconds)
00987 {
00988 _dbus_assert (transport->vtable->do_iteration != NULL);
00989
00990 _dbus_verbose ("Transport iteration flags 0x%x timeout %d connected = %d\n",
00991 flags, timeout_milliseconds, !transport->disconnected);
00992
00993 if ((flags & (DBUS_ITERATION_DO_WRITING |
00994 DBUS_ITERATION_DO_READING)) == 0)
00995 return;
00996
00997 if (transport->disconnected)
00998 return;
00999
01000 _dbus_transport_ref (transport);
01001 (* transport->vtable->do_iteration) (transport, flags,
01002 timeout_milliseconds);
01003 _dbus_transport_unref (transport);
01004
01005 _dbus_verbose ("end\n");
01006 }
01007
01008 static dbus_bool_t
01009 recover_unused_bytes (DBusTransport *transport)
01010 {
01011 if (_dbus_auth_needs_decoding (transport->auth))
01012 {
01013 DBusString plaintext;
01014 const DBusString *encoded;
01015 DBusString *buffer;
01016 int orig_len;
01017
01018 if (!_dbus_string_init (&plaintext))
01019 goto nomem;
01020
01021 _dbus_auth_get_unused_bytes (transport->auth,
01022 &encoded);
01023
01024 if (!_dbus_auth_decode_data (transport->auth,
01025 encoded, &plaintext))
01026 {
01027 _dbus_string_free (&plaintext);
01028 goto nomem;
01029 }
01030
01031 _dbus_message_loader_get_buffer (transport->loader,
01032 &buffer);
01033
01034 orig_len = _dbus_string_get_length (buffer);
01035
01036 if (!_dbus_string_move (&plaintext, 0, buffer,
01037 orig_len))
01038 {
01039 _dbus_string_free (&plaintext);
01040 goto nomem;
01041 }
01042
01043 _dbus_verbose (" %d unused bytes sent to message loader\n",
01044 _dbus_string_get_length (buffer) -
01045 orig_len);
01046
01047 _dbus_message_loader_return_buffer (transport->loader,
01048 buffer);
01049
01050 _dbus_auth_delete_unused_bytes (transport->auth);
01051
01052 _dbus_string_free (&plaintext);
01053 }
01054 else
01055 {
01056 const DBusString *bytes;
01057 DBusString *buffer;
01058 int orig_len;
01059 dbus_bool_t succeeded;
01060
01061 _dbus_message_loader_get_buffer (transport->loader,
01062 &buffer);
01063
01064 orig_len = _dbus_string_get_length (buffer);
01065
01066 _dbus_auth_get_unused_bytes (transport->auth,
01067 &bytes);
01068
01069 succeeded = TRUE;
01070 if (!_dbus_string_copy (bytes, 0, buffer, _dbus_string_get_length (buffer)))
01071 succeeded = FALSE;
01072
01073 _dbus_verbose (" %d unused bytes sent to message loader\n",
01074 _dbus_string_get_length (buffer) -
01075 orig_len);
01076
01077 _dbus_message_loader_return_buffer (transport->loader,
01078 buffer);
01079
01080 if (succeeded)
01081 _dbus_auth_delete_unused_bytes (transport->auth);
01082 else
01083 goto nomem;
01084 }
01085
01086 return TRUE;
01087
01088 nomem:
01089 _dbus_verbose ("Not enough memory to transfer unused bytes from auth conversation\n");
01090 return FALSE;
01091 }
01092
01100 DBusDispatchStatus
01101 _dbus_transport_get_dispatch_status (DBusTransport *transport)
01102 {
01103 if (_dbus_counter_get_size_value (transport->live_messages) >= transport->max_live_messages_size ||
01104 _dbus_counter_get_unix_fd_value (transport->live_messages) >= transport->max_live_messages_unix_fds)
01105 return DBUS_DISPATCH_COMPLETE;
01106
01107 if (!_dbus_transport_try_to_authenticate (transport))
01108 {
01109 if (_dbus_auth_do_work (transport->auth) ==
01110 DBUS_AUTH_STATE_WAITING_FOR_MEMORY)
01111 return DBUS_DISPATCH_NEED_MEMORY;
01112 else if (!_dbus_transport_try_to_authenticate (transport))
01113 return DBUS_DISPATCH_COMPLETE;
01114 }
01115
01116 if (!transport->unused_bytes_recovered &&
01117 !recover_unused_bytes (transport))
01118 return DBUS_DISPATCH_NEED_MEMORY;
01119
01120 transport->unused_bytes_recovered = TRUE;
01121
01122 if (!_dbus_message_loader_queue_messages (transport->loader))
01123 return DBUS_DISPATCH_NEED_MEMORY;
01124
01125 if (_dbus_message_loader_peek_message (transport->loader) != NULL)
01126 return DBUS_DISPATCH_DATA_REMAINS;
01127 else
01128 return DBUS_DISPATCH_COMPLETE;
01129 }
01130
01139 dbus_bool_t
01140 _dbus_transport_queue_messages (DBusTransport *transport)
01141 {
01142 DBusDispatchStatus status;
01143
01144 #if 0
01145 _dbus_verbose ("_dbus_transport_queue_messages()\n");
01146 #endif
01147
01148
01149 while ((status = _dbus_transport_get_dispatch_status (transport)) == DBUS_DISPATCH_DATA_REMAINS)
01150 {
01151 DBusMessage *message;
01152 DBusList *link;
01153
01154 link = _dbus_message_loader_pop_message_link (transport->loader);
01155 _dbus_assert (link != NULL);
01156
01157 message = link->data;
01158
01159 _dbus_verbose ("queueing received message %p\n", message);
01160
01161 if (!_dbus_message_add_counter (message, transport->live_messages))
01162 {
01163 _dbus_message_loader_putback_message_link (transport->loader,
01164 link);
01165 status = DBUS_DISPATCH_NEED_MEMORY;
01166 break;
01167 }
01168 else
01169 {
01170
01171
01172
01173
01174 if (transport->vtable->live_messages_changed)
01175 (* transport->vtable->live_messages_changed) (transport);
01176
01177
01178 _dbus_connection_queue_received_message_link (transport->connection,
01179 link);
01180 }
01181 }
01182
01183 if (_dbus_message_loader_get_is_corrupted (transport->loader))
01184 {
01185 _dbus_verbose ("Corrupted message stream, disconnecting\n");
01186 _dbus_transport_disconnect (transport);
01187 }
01188
01189 return status != DBUS_DISPATCH_NEED_MEMORY;
01190 }
01191
01198 void
01199 _dbus_transport_set_max_message_size (DBusTransport *transport,
01200 long size)
01201 {
01202 _dbus_message_loader_set_max_message_size (transport->loader, size);
01203 }
01204
01211 void
01212 _dbus_transport_set_max_message_unix_fds (DBusTransport *transport,
01213 long n)
01214 {
01215 _dbus_message_loader_set_max_message_unix_fds (transport->loader, n);
01216 }
01217
01224 long
01225 _dbus_transport_get_max_message_size (DBusTransport *transport)
01226 {
01227 return _dbus_message_loader_get_max_message_size (transport->loader);
01228 }
01229
01236 long
01237 _dbus_transport_get_max_message_unix_fds (DBusTransport *transport)
01238 {
01239 return _dbus_message_loader_get_max_message_unix_fds (transport->loader);
01240 }
01241
01248 void
01249 _dbus_transport_set_max_received_size (DBusTransport *transport,
01250 long size)
01251 {
01252 transport->max_live_messages_size = size;
01253 _dbus_counter_set_notify (transport->live_messages,
01254 transport->max_live_messages_size,
01255 transport->max_live_messages_unix_fds,
01256 live_messages_notify,
01257 transport);
01258 }
01259
01266 void
01267 _dbus_transport_set_max_received_unix_fds (DBusTransport *transport,
01268 long n)
01269 {
01270 transport->max_live_messages_unix_fds = n;
01271 _dbus_counter_set_notify (transport->live_messages,
01272 transport->max_live_messages_size,
01273 transport->max_live_messages_unix_fds,
01274 live_messages_notify,
01275 transport);
01276 }
01277
01284 long
01285 _dbus_transport_get_max_received_size (DBusTransport *transport)
01286 {
01287 return transport->max_live_messages_size;
01288 }
01289
01296 long
01297 _dbus_transport_get_max_received_unix_fds (DBusTransport *transport)
01298 {
01299 return transport->max_live_messages_unix_fds;
01300 }
01301
01309 dbus_bool_t
01310 _dbus_transport_get_unix_user (DBusTransport *transport,
01311 unsigned long *uid)
01312 {
01313 DBusCredentials *auth_identity;
01314
01315 *uid = _DBUS_INT32_MAX;
01316
01317
01318
01319
01320 if (!transport->authenticated)
01321 return FALSE;
01322
01323 auth_identity = _dbus_auth_get_identity (transport->auth);
01324
01325 if (_dbus_credentials_include (auth_identity,
01326 DBUS_CREDENTIAL_UNIX_USER_ID))
01327 {
01328 *uid = _dbus_credentials_get_unix_uid (auth_identity);
01329 return TRUE;
01330 }
01331 else
01332 return FALSE;
01333 }
01334
01342 dbus_bool_t
01343 _dbus_transport_get_unix_process_id (DBusTransport *transport,
01344 unsigned long *pid)
01345 {
01346 DBusCredentials *auth_identity;
01347
01348 *pid = DBUS_PID_UNSET;
01349
01350
01351
01352
01353 if (!transport->authenticated)
01354 return FALSE;
01355
01356 auth_identity = _dbus_auth_get_identity (transport->auth);
01357
01358 if (_dbus_credentials_include (auth_identity,
01359 DBUS_CREDENTIAL_UNIX_PROCESS_ID))
01360 {
01361 *pid = _dbus_credentials_get_pid (auth_identity);
01362 return TRUE;
01363 }
01364 else
01365 return FALSE;
01366 }
01367
01376 dbus_bool_t
01377 _dbus_transport_get_adt_audit_session_data (DBusTransport *transport,
01378 void **data,
01379 int *data_size)
01380 {
01381 DBusCredentials *auth_identity;
01382
01383 *data = NULL;
01384 *data_size = 0;
01385
01386 if (!transport->authenticated)
01387 return FALSE;
01388
01389 auth_identity = _dbus_auth_get_identity (transport->auth);
01390
01391 if (_dbus_credentials_include (auth_identity,
01392 DBUS_CREDENTIAL_ADT_AUDIT_DATA_ID))
01393 {
01394 *data = (void *) _dbus_credentials_get_adt_audit_data (auth_identity);
01395 *data_size = _dbus_credentials_get_adt_audit_data_size (auth_identity);
01396 return TRUE;
01397 }
01398 else
01399 return FALSE;
01400 }
01401
01412 void
01413 _dbus_transport_set_unix_user_function (DBusTransport *transport,
01414 DBusAllowUnixUserFunction function,
01415 void *data,
01416 DBusFreeFunction free_data_function,
01417 void **old_data,
01418 DBusFreeFunction *old_free_data_function)
01419 {
01420 *old_data = transport->unix_user_data;
01421 *old_free_data_function = transport->free_unix_user_data;
01422
01423 transport->unix_user_function = function;
01424 transport->unix_user_data = data;
01425 transport->free_unix_user_data = free_data_function;
01426 }
01427
01428 dbus_bool_t
01429 _dbus_transport_get_linux_security_label (DBusTransport *transport,
01430 char **label_p)
01431 {
01432 DBusCredentials *auth_identity;
01433
01434 *label_p = NULL;
01435
01436 if (!transport->authenticated)
01437 return FALSE;
01438
01439 auth_identity = _dbus_auth_get_identity (transport->auth);
01440
01441 if (_dbus_credentials_include (auth_identity,
01442 DBUS_CREDENTIAL_LINUX_SECURITY_LABEL))
01443 {
01444
01445 *label_p = _dbus_strdup (_dbus_credentials_get_linux_security_label (auth_identity));
01446
01447 return TRUE;
01448 }
01449 else
01450 {
01451 return FALSE;
01452 }
01453 }
01454
01462 dbus_bool_t
01463 _dbus_transport_get_windows_user (DBusTransport *transport,
01464 char **windows_sid_p)
01465 {
01466 DBusCredentials *auth_identity;
01467
01468 *windows_sid_p = NULL;
01469
01470 if (!transport->authenticated)
01471 return FALSE;
01472
01473 auth_identity = _dbus_auth_get_identity (transport->auth);
01474
01475 if (_dbus_credentials_include (auth_identity,
01476 DBUS_CREDENTIAL_WINDOWS_SID))
01477 {
01478
01479 *windows_sid_p = _dbus_strdup (_dbus_credentials_get_windows_sid (auth_identity));
01480
01481 return TRUE;
01482 }
01483 else
01484 return FALSE;
01485 }
01486
01498 void
01499 _dbus_transport_set_windows_user_function (DBusTransport *transport,
01500 DBusAllowWindowsUserFunction function,
01501 void *data,
01502 DBusFreeFunction free_data_function,
01503 void **old_data,
01504 DBusFreeFunction *old_free_data_function)
01505 {
01506 *old_data = transport->windows_user_data;
01507 *old_free_data_function = transport->free_windows_user_data;
01508
01509 transport->windows_user_function = function;
01510 transport->windows_user_data = data;
01511 transport->free_windows_user_data = free_data_function;
01512 }
01513
01522 dbus_bool_t
01523 _dbus_transport_set_auth_mechanisms (DBusTransport *transport,
01524 const char **mechanisms)
01525 {
01526 return _dbus_auth_set_mechanisms (transport->auth, mechanisms);
01527 }
01528
01535 void
01536 _dbus_transport_set_allow_anonymous (DBusTransport *transport,
01537 dbus_bool_t value)
01538 {
01539 transport->allow_anonymous = value != FALSE;
01540 }
01541
01547 int
01548 _dbus_transport_get_pending_fds_count (DBusTransport *transport)
01549 {
01550 return _dbus_message_loader_get_pending_fds_count (transport->loader);
01551 }
01552
01560 void
01561 _dbus_transport_set_pending_fds_function (DBusTransport *transport,
01562 void (* callback) (void *),
01563 void *data)
01564 {
01565 _dbus_message_loader_set_pending_fds_function (transport->loader,
01566 callback, data);
01567 }
01568
01569 #ifdef DBUS_ENABLE_STATS
01570 void
01571 _dbus_transport_get_stats (DBusTransport *transport,
01572 dbus_uint32_t *queue_bytes,
01573 dbus_uint32_t *queue_fds,
01574 dbus_uint32_t *peak_queue_bytes,
01575 dbus_uint32_t *peak_queue_fds)
01576 {
01577 if (queue_bytes != NULL)
01578 *queue_bytes = _dbus_counter_get_size_value (transport->live_messages);
01579
01580 if (queue_fds != NULL)
01581 *queue_fds = _dbus_counter_get_unix_fd_value (transport->live_messages);
01582
01583 if (peak_queue_bytes != NULL)
01584 *peak_queue_bytes = _dbus_counter_get_peak_size_value (transport->live_messages);
01585
01586 if (peak_queue_fds != NULL)
01587 *peak_queue_fds = _dbus_counter_get_peak_unix_fd_value (transport->live_messages);
01588 }
01589 #endif
01590