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 "dbus-transport-protected.h"
00025 #include "dbus-transport-unix.h"
00026 #include "dbus-transport-socket.h"
00027 #include "dbus-connection-internal.h"
00028 #include "dbus-watch.h"
00029 #include "dbus-auth.h"
00030 #include "dbus-address.h"
00031 #include "dbus-credentials.h"
00032 #ifdef DBUS_BUILD_TESTS
00033 #include "dbus-server-debug-pipe.h"
00034 #endif
00035
00057 static void
00058 live_messages_size_notify (DBusCounter *counter,
00059 void *user_data)
00060 {
00061 DBusTransport *transport = user_data;
00062
00063 _dbus_transport_ref (transport);
00064
00065 #if 0
00066 _dbus_verbose ("Counter value is now %d\n",
00067 (int) _dbus_counter_get_value (counter));
00068 #endif
00069
00070
00071
00072
00073 if (transport->vtable->live_messages_changed)
00074 (* transport->vtable->live_messages_changed) (transport);
00075
00076 _dbus_transport_unref (transport);
00077 }
00078
00092 dbus_bool_t
00093 _dbus_transport_init_base (DBusTransport *transport,
00094 const DBusTransportVTable *vtable,
00095 const DBusString *server_guid,
00096 const DBusString *address)
00097 {
00098 DBusMessageLoader *loader;
00099 DBusAuth *auth;
00100 DBusCounter *counter;
00101 char *address_copy;
00102 DBusCredentials *creds;
00103
00104 loader = _dbus_message_loader_new ();
00105 if (loader == NULL)
00106 return FALSE;
00107
00108 if (server_guid)
00109 auth = _dbus_auth_server_new (server_guid);
00110 else
00111 auth = _dbus_auth_client_new ();
00112 if (auth == NULL)
00113 {
00114 _dbus_message_loader_unref (loader);
00115 return FALSE;
00116 }
00117
00118 counter = _dbus_counter_new ();
00119 if (counter == NULL)
00120 {
00121 _dbus_auth_unref (auth);
00122 _dbus_message_loader_unref (loader);
00123 return FALSE;
00124 }
00125
00126 creds = _dbus_credentials_new ();
00127 if (creds == NULL)
00128 {
00129 _dbus_counter_unref (counter);
00130 _dbus_auth_unref (auth);
00131 _dbus_message_loader_unref (loader);
00132 return FALSE;
00133 }
00134
00135 if (server_guid)
00136 {
00137 _dbus_assert (address == NULL);
00138 address_copy = NULL;
00139 }
00140 else
00141 {
00142 _dbus_assert (address != NULL);
00143
00144 if (!_dbus_string_copy_data (address, &address_copy))
00145 {
00146 _dbus_credentials_unref (creds);
00147 _dbus_counter_unref (counter);
00148 _dbus_auth_unref (auth);
00149 _dbus_message_loader_unref (loader);
00150 return FALSE;
00151 }
00152 }
00153
00154 transport->refcount = 1;
00155 transport->vtable = vtable;
00156 transport->loader = loader;
00157 transport->auth = auth;
00158 transport->live_messages_size = counter;
00159 transport->authenticated = FALSE;
00160 transport->disconnected = FALSE;
00161 transport->is_server = (server_guid != NULL);
00162 transport->send_credentials_pending = !transport->is_server;
00163 transport->receive_credentials_pending = transport->is_server;
00164 transport->address = address_copy;
00165
00166 transport->unix_user_function = NULL;
00167 transport->unix_user_data = NULL;
00168 transport->free_unix_user_data = NULL;
00169
00170 transport->windows_user_function = NULL;
00171 transport->windows_user_data = NULL;
00172 transport->free_windows_user_data = NULL;
00173
00174 transport->expected_guid = NULL;
00175
00176
00177
00178
00179 transport->max_live_messages_size = _DBUS_ONE_MEGABYTE * 63;
00180
00181
00182 transport->credentials = creds;
00183
00184 _dbus_counter_set_notify (transport->live_messages_size,
00185 transport->max_live_messages_size,
00186 live_messages_size_notify,
00187 transport);
00188
00189 if (transport->address)
00190 _dbus_verbose ("Initialized transport on address %s\n", transport->address);
00191
00192 return TRUE;
00193 }
00194
00201 void
00202 _dbus_transport_finalize_base (DBusTransport *transport)
00203 {
00204 if (!transport->disconnected)
00205 _dbus_transport_disconnect (transport);
00206
00207 if (transport->free_unix_user_data != NULL)
00208 (* transport->free_unix_user_data) (transport->unix_user_data);
00209
00210 if (transport->free_windows_user_data != NULL)
00211 (* transport->free_windows_user_data) (transport->windows_user_data);
00212
00213 _dbus_message_loader_unref (transport->loader);
00214 _dbus_auth_unref (transport->auth);
00215 _dbus_counter_set_notify (transport->live_messages_size,
00216 0, NULL, NULL);
00217 _dbus_counter_unref (transport->live_messages_size);
00218 dbus_free (transport->address);
00219 dbus_free (transport->expected_guid);
00220 if (transport->credentials)
00221 _dbus_credentials_unref (transport->credentials);
00222 }
00223
00224
00234 static DBusTransport*
00235 check_address (const char *address, DBusError *error)
00236 {
00237 DBusAddressEntry **entries;
00238 DBusTransport *transport = NULL;
00239 int len, i;
00240
00241 _dbus_assert (address != NULL);
00242 _dbus_assert (*address != '\0');
00243
00244 if (!dbus_parse_address (address, &entries, &len, error))
00245 return FALSE;
00246
00247 for (i = 0; i < len; i++)
00248 {
00249 transport = _dbus_transport_open (entries[i], error);
00250 if (transport != NULL)
00251 break;
00252 }
00253
00254 dbus_address_entries_free (entries);
00255 return transport;
00256 }
00257
00265 static DBusTransport*
00266 _dbus_transport_new_for_autolaunch (DBusError *error)
00267 {
00268 DBusString address;
00269 DBusTransport *result = NULL;
00270
00271 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00272
00273 if (!_dbus_string_init (&address))
00274 {
00275 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00276 return NULL;
00277 }
00278
00279 if (!_dbus_get_autolaunch_address (&address, error))
00280 {
00281 _DBUS_ASSERT_ERROR_IS_SET (error);
00282 goto out;
00283 }
00284
00285 result = check_address (_dbus_string_get_const_data (&address), error);
00286 if (result == NULL)
00287 _DBUS_ASSERT_ERROR_IS_SET (error);
00288 else
00289 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00290
00291 out:
00292 _dbus_string_free (&address);
00293 return result;
00294 }
00295
00296 static DBusTransportOpenResult
00297 _dbus_transport_open_autolaunch (DBusAddressEntry *entry,
00298 DBusTransport **transport_p,
00299 DBusError *error)
00300 {
00301 const char *method;
00302
00303 method = dbus_address_entry_get_method (entry);
00304 _dbus_assert (method != NULL);
00305
00306 if (strcmp (method, "autolaunch") == 0)
00307 {
00308 *transport_p = _dbus_transport_new_for_autolaunch (error);
00309
00310 if (*transport_p == NULL)
00311 {
00312 _DBUS_ASSERT_ERROR_IS_SET (error);
00313 return DBUS_TRANSPORT_OPEN_DID_NOT_CONNECT;
00314 }
00315 else
00316 {
00317 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00318 return DBUS_TRANSPORT_OPEN_OK;
00319 }
00320 }
00321 else
00322 {
00323 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00324 return DBUS_TRANSPORT_OPEN_NOT_HANDLED;
00325 }
00326 }
00327
00328 static const struct {
00329 DBusTransportOpenResult (* func) (DBusAddressEntry *entry,
00330 DBusTransport **transport_p,
00331 DBusError *error);
00332 } open_funcs[] = {
00333 { _dbus_transport_open_socket },
00334 { _dbus_transport_open_platform_specific },
00335 { _dbus_transport_open_autolaunch }
00336 #ifdef DBUS_BUILD_TESTS
00337 , { _dbus_transport_open_debug_pipe }
00338 #endif
00339 };
00340
00349 DBusTransport*
00350 _dbus_transport_open (DBusAddressEntry *entry,
00351 DBusError *error)
00352 {
00353 DBusTransport *transport;
00354 const char *expected_guid_orig;
00355 char *expected_guid;
00356 int i;
00357 DBusError tmp_error = DBUS_ERROR_INIT;
00358
00359 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00360
00361 transport = NULL;
00362 expected_guid_orig = dbus_address_entry_get_value (entry, "guid");
00363 expected_guid = _dbus_strdup (expected_guid_orig);
00364
00365 if (expected_guid_orig != NULL && expected_guid == NULL)
00366 {
00367 _DBUS_SET_OOM (error);
00368 return NULL;
00369 }
00370
00371 for (i = 0; i < (int) _DBUS_N_ELEMENTS (open_funcs); ++i)
00372 {
00373 DBusTransportOpenResult result;
00374
00375 _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error);
00376 result = (* open_funcs[i].func) (entry, &transport, &tmp_error);
00377
00378 switch (result)
00379 {
00380 case DBUS_TRANSPORT_OPEN_OK:
00381 _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error);
00382 goto out;
00383 break;
00384 case DBUS_TRANSPORT_OPEN_NOT_HANDLED:
00385 _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error);
00386
00387 break;
00388 case DBUS_TRANSPORT_OPEN_BAD_ADDRESS:
00389 _DBUS_ASSERT_ERROR_IS_SET (&tmp_error);
00390 goto out;
00391 break;
00392 case DBUS_TRANSPORT_OPEN_DID_NOT_CONNECT:
00393 _DBUS_ASSERT_ERROR_IS_SET (&tmp_error);
00394 goto out;
00395 break;
00396 }
00397 }
00398
00399 out:
00400
00401 if (transport == NULL)
00402 {
00403 if (!dbus_error_is_set (&tmp_error))
00404 _dbus_set_bad_address (&tmp_error,
00405 NULL, NULL,
00406 "Unknown address type (examples of valid types are \"tcp\" and on UNIX \"unix\")");
00407
00408 _DBUS_ASSERT_ERROR_IS_SET (&tmp_error);
00409 dbus_move_error(&tmp_error, error);
00410 dbus_free (expected_guid);
00411 }
00412 else
00413 {
00414 _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error);
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429 if(expected_guid)
00430 transport->expected_guid = expected_guid;
00431 }
00432
00433 return transport;
00434 }
00435
00442 DBusTransport *
00443 _dbus_transport_ref (DBusTransport *transport)
00444 {
00445 _dbus_assert (transport->refcount > 0);
00446
00447 transport->refcount += 1;
00448
00449 return transport;
00450 }
00451
00459 void
00460 _dbus_transport_unref (DBusTransport *transport)
00461 {
00462 _dbus_assert (transport != NULL);
00463 _dbus_assert (transport->refcount > 0);
00464
00465 transport->refcount -= 1;
00466 if (transport->refcount == 0)
00467 {
00468 _dbus_verbose ("%s: finalizing\n", _DBUS_FUNCTION_NAME);
00469
00470 _dbus_assert (transport->vtable->finalize != NULL);
00471
00472 (* transport->vtable->finalize) (transport);
00473 }
00474 }
00475
00484 void
00485 _dbus_transport_disconnect (DBusTransport *transport)
00486 {
00487 _dbus_verbose ("%s start\n", _DBUS_FUNCTION_NAME);
00488
00489 _dbus_assert (transport->vtable->disconnect != NULL);
00490
00491 if (transport->disconnected)
00492 return;
00493
00494 (* transport->vtable->disconnect) (transport);
00495
00496 transport->disconnected = TRUE;
00497
00498 _dbus_verbose ("%s end\n", _DBUS_FUNCTION_NAME);
00499 }
00500
00509 dbus_bool_t
00510 _dbus_transport_get_is_connected (DBusTransport *transport)
00511 {
00512 return !transport->disconnected;
00513 }
00514
00515 static dbus_bool_t
00516 auth_via_unix_user_function (DBusTransport *transport)
00517 {
00518 DBusCredentials *auth_identity;
00519 dbus_bool_t allow;
00520 DBusConnection *connection;
00521 DBusAllowUnixUserFunction unix_user_function;
00522 void *unix_user_data;
00523 dbus_uid_t uid;
00524
00525
00526
00527 auth_identity = _dbus_auth_get_identity (transport->auth);
00528 _dbus_assert (auth_identity != NULL);
00529
00530 connection = transport->connection;
00531 unix_user_function = transport->unix_user_function;
00532 unix_user_data = transport->unix_user_data;
00533 uid = _dbus_credentials_get_unix_uid (auth_identity);
00534
00535 _dbus_verbose ("unlock %s\n", _DBUS_FUNCTION_NAME);
00536 _dbus_connection_unlock (connection);
00537
00538 allow = (* unix_user_function) (connection,
00539 uid,
00540 unix_user_data);
00541
00542 _dbus_verbose ("lock %s post unix user function\n", _DBUS_FUNCTION_NAME);
00543 _dbus_connection_lock (connection);
00544
00545 if (allow)
00546 {
00547 _dbus_verbose ("Client UID "DBUS_UID_FORMAT" authorized\n", uid);
00548 }
00549 else
00550 {
00551 _dbus_verbose ("Client UID "DBUS_UID_FORMAT
00552 " was rejected, disconnecting\n",
00553 _dbus_credentials_get_unix_uid (auth_identity));
00554 _dbus_transport_disconnect (transport);
00555 }
00556
00557 return allow;
00558 }
00559
00560 static dbus_bool_t
00561 auth_via_windows_user_function (DBusTransport *transport)
00562 {
00563 DBusCredentials *auth_identity;
00564 dbus_bool_t allow;
00565 DBusConnection *connection;
00566 DBusAllowWindowsUserFunction windows_user_function;
00567 void *windows_user_data;
00568 char *windows_sid;
00569
00570
00571
00572 auth_identity = _dbus_auth_get_identity (transport->auth);
00573 _dbus_assert (auth_identity != NULL);
00574
00575 connection = transport->connection;
00576 windows_user_function = transport->windows_user_function;
00577 windows_user_data = transport->unix_user_data;
00578 windows_sid = _dbus_strdup (_dbus_credentials_get_windows_sid (auth_identity));
00579
00580 if (windows_sid == NULL)
00581 {
00582
00583 return FALSE;
00584 }
00585
00586 _dbus_verbose ("unlock %s\n", _DBUS_FUNCTION_NAME);
00587 _dbus_connection_unlock (connection);
00588
00589 allow = (* windows_user_function) (connection,
00590 windows_sid,
00591 windows_user_data);
00592
00593 _dbus_verbose ("lock %s post windows user function\n", _DBUS_FUNCTION_NAME);
00594 _dbus_connection_lock (connection);
00595
00596 if (allow)
00597 {
00598 _dbus_verbose ("Client SID '%s' authorized\n", windows_sid);
00599 }
00600 else
00601 {
00602 _dbus_verbose ("Client SID '%s' was rejected, disconnecting\n",
00603 _dbus_credentials_get_windows_sid (auth_identity));
00604 _dbus_transport_disconnect (transport);
00605 }
00606
00607 return allow;
00608 }
00609
00610 static dbus_bool_t
00611 auth_via_default_rules (DBusTransport *transport)
00612 {
00613 DBusCredentials *auth_identity;
00614 DBusCredentials *our_identity;
00615 dbus_bool_t allow;
00616
00617 auth_identity = _dbus_auth_get_identity (transport->auth);
00618 _dbus_assert (auth_identity != NULL);
00619
00620
00621
00622
00623
00624 our_identity = _dbus_credentials_new_from_current_process ();
00625 if (our_identity == NULL)
00626 {
00627
00628 return FALSE;
00629 }
00630
00631 if (transport->allow_anonymous ||
00632 _dbus_credentials_get_unix_uid (auth_identity) == 0 ||
00633 _dbus_credentials_same_user (our_identity,
00634 auth_identity))
00635 {
00636 if (_dbus_credentials_include(our_identity,DBUS_CREDENTIAL_WINDOWS_SID))
00637 _dbus_verbose ("Client authorized as SID '%s'"
00638 "matching our SID '%s'\n",
00639 _dbus_credentials_get_windows_sid(auth_identity),
00640 _dbus_credentials_get_windows_sid(our_identity));
00641 else
00642 _dbus_verbose ("Client authorized as UID "DBUS_UID_FORMAT
00643 " matching our UID "DBUS_UID_FORMAT"\n",
00644 _dbus_credentials_get_unix_uid(auth_identity),
00645 _dbus_credentials_get_unix_uid(our_identity));
00646
00647 allow = TRUE;
00648 }
00649 else
00650 {
00651 if (_dbus_credentials_include(our_identity,DBUS_CREDENTIAL_WINDOWS_SID))
00652 _dbus_verbose ("Client authorized as SID '%s'"
00653 " but our SID is '%s', disconnecting\n",
00654 _dbus_credentials_get_windows_sid(our_identity),
00655 _dbus_credentials_get_windows_sid(our_identity));
00656 else
00657 _dbus_verbose ("Client authorized as UID "DBUS_UID_FORMAT
00658 " but our UID is "DBUS_UID_FORMAT", disconnecting\n",
00659 _dbus_credentials_get_unix_uid(our_identity),
00660 _dbus_credentials_get_unix_uid(our_identity));
00661 _dbus_transport_disconnect (transport);
00662 allow = FALSE;
00663 }
00664
00665 _dbus_credentials_unref (our_identity);
00666
00667 return allow;
00668 }
00669
00670
00681 dbus_bool_t
00682 _dbus_transport_get_is_authenticated (DBusTransport *transport)
00683 {
00684 if (transport->authenticated)
00685 return TRUE;
00686 else
00687 {
00688 dbus_bool_t maybe_authenticated;
00689
00690 if (transport->disconnected)
00691 return FALSE;
00692
00693
00694 _dbus_connection_ref_unlocked (transport->connection);
00695
00696 maybe_authenticated =
00697 (!(transport->send_credentials_pending ||
00698 transport->receive_credentials_pending));
00699
00700 if (maybe_authenticated)
00701 {
00702 switch (_dbus_auth_do_work (transport->auth))
00703 {
00704 case DBUS_AUTH_STATE_AUTHENTICATED:
00705
00706 break;
00707 default:
00708 maybe_authenticated = FALSE;
00709 }
00710 }
00711
00712
00713
00714 if (maybe_authenticated && !transport->is_server)
00715 {
00716 const char *server_guid;
00717
00718 server_guid = _dbus_auth_get_guid_from_server (transport->auth);
00719 _dbus_assert (server_guid != NULL);
00720
00721 if (transport->expected_guid &&
00722 strcmp (transport->expected_guid, server_guid) != 0)
00723 {
00724 _dbus_verbose ("Client expected GUID '%s' and we got '%s' from the server\n",
00725 transport->expected_guid, server_guid);
00726 _dbus_transport_disconnect (transport);
00727 _dbus_connection_unref_unlocked (transport->connection);
00728 return FALSE;
00729 }
00730
00731 if (transport->expected_guid == NULL)
00732 {
00733 transport->expected_guid = _dbus_strdup (server_guid);
00734
00735 if (transport->expected_guid == NULL)
00736 {
00737 _dbus_verbose ("No memory to complete auth in %s\n", _DBUS_FUNCTION_NAME);
00738 return FALSE;
00739 }
00740 }
00741 }
00742
00743
00744
00745 if (maybe_authenticated && transport->is_server)
00746 {
00747 dbus_bool_t allow;
00748 DBusCredentials *auth_identity;
00749
00750 auth_identity = _dbus_auth_get_identity (transport->auth);
00751 _dbus_assert (auth_identity != NULL);
00752
00753
00754
00755
00756
00757 if (transport->unix_user_function != NULL &&
00758 _dbus_credentials_include (auth_identity, DBUS_CREDENTIAL_UNIX_USER_ID))
00759 {
00760 allow = auth_via_unix_user_function (transport);
00761 }
00762 else if (transport->windows_user_function != NULL &&
00763 _dbus_credentials_include (auth_identity, DBUS_CREDENTIAL_WINDOWS_SID))
00764 {
00765 allow = auth_via_windows_user_function (transport);
00766 }
00767 else
00768 {
00769 allow = auth_via_default_rules (transport);
00770 }
00771
00772 if (!allow)
00773 maybe_authenticated = FALSE;
00774 }
00775
00776 transport->authenticated = maybe_authenticated;
00777
00778 _dbus_connection_unref_unlocked (transport->connection);
00779 return maybe_authenticated;
00780 }
00781 }
00782
00789 dbus_bool_t
00790 _dbus_transport_get_is_anonymous (DBusTransport *transport)
00791 {
00792 DBusCredentials *auth_identity;
00793
00794 if (!transport->authenticated)
00795 return TRUE;
00796
00797 auth_identity = _dbus_auth_get_identity (transport->auth);
00798
00799 if (_dbus_credentials_are_anonymous (auth_identity))
00800 return TRUE;
00801 else
00802 return FALSE;
00803 }
00804
00812 const char*
00813 _dbus_transport_get_address (DBusTransport *transport)
00814 {
00815 return transport->address;
00816 }
00817
00825 const char*
00826 _dbus_transport_get_server_id (DBusTransport *transport)
00827 {
00828 if (transport->is_server)
00829 return NULL;
00830 else
00831 return transport->expected_guid;
00832 }
00833
00843 dbus_bool_t
00844 _dbus_transport_handle_watch (DBusTransport *transport,
00845 DBusWatch *watch,
00846 unsigned int condition)
00847 {
00848 dbus_bool_t retval;
00849
00850 _dbus_assert (transport->vtable->handle_watch != NULL);
00851
00852 if (transport->disconnected)
00853 return TRUE;
00854
00855 if (dbus_watch_get_socket (watch) < 0)
00856 {
00857 _dbus_warn_check_failed ("Tried to handle an invalidated watch; this watch should have been removed\n");
00858 return TRUE;
00859 }
00860
00861 _dbus_watch_sanitize_condition (watch, &condition);
00862
00863 _dbus_transport_ref (transport);
00864 _dbus_watch_ref (watch);
00865 retval = (* transport->vtable->handle_watch) (transport, watch, condition);
00866 _dbus_watch_unref (watch);
00867 _dbus_transport_unref (transport);
00868
00869 return retval;
00870 }
00871
00881 dbus_bool_t
00882 _dbus_transport_set_connection (DBusTransport *transport,
00883 DBusConnection *connection)
00884 {
00885 _dbus_assert (transport->vtable->connection_set != NULL);
00886 _dbus_assert (transport->connection == NULL);
00887
00888 transport->connection = connection;
00889
00890 _dbus_transport_ref (transport);
00891 if (!(* transport->vtable->connection_set) (transport))
00892 transport->connection = NULL;
00893 _dbus_transport_unref (transport);
00894
00895 return transport->connection != NULL;
00896 }
00897
00905 dbus_bool_t
00906 _dbus_transport_get_socket_fd (DBusTransport *transport,
00907 int *fd_p)
00908 {
00909 dbus_bool_t retval;
00910
00911 if (transport->vtable->get_socket_fd == NULL)
00912 return FALSE;
00913
00914 if (transport->disconnected)
00915 return FALSE;
00916
00917 _dbus_transport_ref (transport);
00918
00919 retval = (* transport->vtable->get_socket_fd) (transport,
00920 fd_p);
00921
00922 _dbus_transport_unref (transport);
00923
00924 return retval;
00925 }
00926
00938 void
00939 _dbus_transport_do_iteration (DBusTransport *transport,
00940 unsigned int flags,
00941 int timeout_milliseconds)
00942 {
00943 _dbus_assert (transport->vtable->do_iteration != NULL);
00944
00945 _dbus_verbose ("Transport iteration flags 0x%x timeout %d connected = %d\n",
00946 flags, timeout_milliseconds, !transport->disconnected);
00947
00948 if ((flags & (DBUS_ITERATION_DO_WRITING |
00949 DBUS_ITERATION_DO_READING)) == 0)
00950 return;
00951
00952 if (transport->disconnected)
00953 return;
00954
00955 _dbus_transport_ref (transport);
00956 (* transport->vtable->do_iteration) (transport, flags,
00957 timeout_milliseconds);
00958 _dbus_transport_unref (transport);
00959
00960 _dbus_verbose ("%s end\n", _DBUS_FUNCTION_NAME);
00961 }
00962
00963 static dbus_bool_t
00964 recover_unused_bytes (DBusTransport *transport)
00965 {
00966 if (_dbus_auth_needs_decoding (transport->auth))
00967 {
00968 DBusString plaintext;
00969 const DBusString *encoded;
00970 DBusString *buffer;
00971 int orig_len;
00972
00973 if (!_dbus_string_init (&plaintext))
00974 goto nomem;
00975
00976 _dbus_auth_get_unused_bytes (transport->auth,
00977 &encoded);
00978
00979 if (!_dbus_auth_decode_data (transport->auth,
00980 encoded, &plaintext))
00981 {
00982 _dbus_string_free (&plaintext);
00983 goto nomem;
00984 }
00985
00986 _dbus_message_loader_get_buffer (transport->loader,
00987 &buffer);
00988
00989 orig_len = _dbus_string_get_length (buffer);
00990
00991 if (!_dbus_string_move (&plaintext, 0, buffer,
00992 orig_len))
00993 {
00994 _dbus_string_free (&plaintext);
00995 goto nomem;
00996 }
00997
00998 _dbus_verbose (" %d unused bytes sent to message loader\n",
00999 _dbus_string_get_length (buffer) -
01000 orig_len);
01001
01002 _dbus_message_loader_return_buffer (transport->loader,
01003 buffer,
01004 _dbus_string_get_length (buffer) -
01005 orig_len);
01006
01007 _dbus_auth_delete_unused_bytes (transport->auth);
01008
01009 _dbus_string_free (&plaintext);
01010 }
01011 else
01012 {
01013 const DBusString *bytes;
01014 DBusString *buffer;
01015 int orig_len;
01016 dbus_bool_t succeeded;
01017
01018 _dbus_message_loader_get_buffer (transport->loader,
01019 &buffer);
01020
01021 orig_len = _dbus_string_get_length (buffer);
01022
01023 _dbus_auth_get_unused_bytes (transport->auth,
01024 &bytes);
01025
01026 succeeded = TRUE;
01027 if (!_dbus_string_copy (bytes, 0, buffer, _dbus_string_get_length (buffer)))
01028 succeeded = FALSE;
01029
01030 _dbus_verbose (" %d unused bytes sent to message loader\n",
01031 _dbus_string_get_length (buffer) -
01032 orig_len);
01033
01034 _dbus_message_loader_return_buffer (transport->loader,
01035 buffer,
01036 _dbus_string_get_length (buffer) -
01037 orig_len);
01038
01039 if (succeeded)
01040 _dbus_auth_delete_unused_bytes (transport->auth);
01041 else
01042 goto nomem;
01043 }
01044
01045 return TRUE;
01046
01047 nomem:
01048 _dbus_verbose ("Not enough memory to transfer unused bytes from auth conversation\n");
01049 return FALSE;
01050 }
01051
01059 DBusDispatchStatus
01060 _dbus_transport_get_dispatch_status (DBusTransport *transport)
01061 {
01062 if (_dbus_counter_get_value (transport->live_messages_size) >= transport->max_live_messages_size)
01063 return DBUS_DISPATCH_COMPLETE;
01064
01065 if (!_dbus_transport_get_is_authenticated (transport))
01066 {
01067 if (_dbus_auth_do_work (transport->auth) ==
01068 DBUS_AUTH_STATE_WAITING_FOR_MEMORY)
01069 return DBUS_DISPATCH_NEED_MEMORY;
01070 else if (!_dbus_transport_get_is_authenticated (transport))
01071 return DBUS_DISPATCH_COMPLETE;
01072 }
01073
01074 if (!transport->unused_bytes_recovered &&
01075 !recover_unused_bytes (transport))
01076 return DBUS_DISPATCH_NEED_MEMORY;
01077
01078 transport->unused_bytes_recovered = TRUE;
01079
01080 if (!_dbus_message_loader_queue_messages (transport->loader))
01081 return DBUS_DISPATCH_NEED_MEMORY;
01082
01083 if (_dbus_message_loader_peek_message (transport->loader) != NULL)
01084 return DBUS_DISPATCH_DATA_REMAINS;
01085 else
01086 return DBUS_DISPATCH_COMPLETE;
01087 }
01088
01097 dbus_bool_t
01098 _dbus_transport_queue_messages (DBusTransport *transport)
01099 {
01100 DBusDispatchStatus status;
01101
01102 #if 0
01103 _dbus_verbose ("_dbus_transport_queue_messages()\n");
01104 #endif
01105
01106
01107 while ((status = _dbus_transport_get_dispatch_status (transport)) == DBUS_DISPATCH_DATA_REMAINS)
01108 {
01109 DBusMessage *message;
01110 DBusList *link;
01111
01112 link = _dbus_message_loader_pop_message_link (transport->loader);
01113 _dbus_assert (link != NULL);
01114
01115 message = link->data;
01116
01117 _dbus_verbose ("queueing received message %p\n", message);
01118
01119 if (!_dbus_message_add_size_counter (message, transport->live_messages_size))
01120 {
01121 _dbus_message_loader_putback_message_link (transport->loader,
01122 link);
01123 status = DBUS_DISPATCH_NEED_MEMORY;
01124 break;
01125 }
01126 else
01127 {
01128
01129 _dbus_connection_queue_received_message_link (transport->connection,
01130 link);
01131 }
01132 }
01133
01134 if (_dbus_message_loader_get_is_corrupted (transport->loader))
01135 {
01136 _dbus_verbose ("Corrupted message stream, disconnecting\n");
01137 _dbus_transport_disconnect (transport);
01138 }
01139
01140 return status != DBUS_DISPATCH_NEED_MEMORY;
01141 }
01142
01149 void
01150 _dbus_transport_set_max_message_size (DBusTransport *transport,
01151 long size)
01152 {
01153 _dbus_message_loader_set_max_message_size (transport->loader, size);
01154 }
01155
01162 long
01163 _dbus_transport_get_max_message_size (DBusTransport *transport)
01164 {
01165 return _dbus_message_loader_get_max_message_size (transport->loader);
01166 }
01167
01174 void
01175 _dbus_transport_set_max_received_size (DBusTransport *transport,
01176 long size)
01177 {
01178 transport->max_live_messages_size = size;
01179 _dbus_counter_set_notify (transport->live_messages_size,
01180 transport->max_live_messages_size,
01181 live_messages_size_notify,
01182 transport);
01183 }
01184
01185
01192 long
01193 _dbus_transport_get_max_received_size (DBusTransport *transport)
01194 {
01195 return transport->max_live_messages_size;
01196 }
01197
01205 dbus_bool_t
01206 _dbus_transport_get_unix_user (DBusTransport *transport,
01207 unsigned long *uid)
01208 {
01209 DBusCredentials *auth_identity;
01210
01211 *uid = _DBUS_INT32_MAX;
01212
01213
01214
01215
01216 if (!transport->authenticated)
01217 return FALSE;
01218
01219 auth_identity = _dbus_auth_get_identity (transport->auth);
01220
01221 if (_dbus_credentials_include (auth_identity,
01222 DBUS_CREDENTIAL_UNIX_USER_ID))
01223 {
01224 *uid = _dbus_credentials_get_unix_uid (auth_identity);
01225 return TRUE;
01226 }
01227 else
01228 return FALSE;
01229 }
01230
01238 dbus_bool_t
01239 _dbus_transport_get_unix_process_id (DBusTransport *transport,
01240 unsigned long *pid)
01241 {
01242 DBusCredentials *auth_identity;
01243
01244 *pid = DBUS_PID_UNSET;
01245
01246
01247
01248
01249 if (!transport->authenticated)
01250 return FALSE;
01251
01252 auth_identity = _dbus_auth_get_identity (transport->auth);
01253
01254 if (_dbus_credentials_include (auth_identity,
01255 DBUS_CREDENTIAL_UNIX_PROCESS_ID))
01256 {
01257 *pid = _dbus_credentials_get_unix_pid (auth_identity);
01258 return TRUE;
01259 }
01260 else
01261 return FALSE;
01262 }
01263
01272 dbus_bool_t
01273 _dbus_transport_get_adt_audit_session_data (DBusTransport *transport,
01274 void **data,
01275 int *data_size)
01276 {
01277 DBusCredentials *auth_identity;
01278
01279 *data = NULL;
01280 *data_size = 0;
01281
01282 if (!transport->authenticated)
01283 return FALSE;
01284
01285 auth_identity = _dbus_auth_get_identity (transport->auth);
01286
01287 if (_dbus_credentials_include (auth_identity,
01288 DBUS_CREDENTIAL_ADT_AUDIT_DATA_ID))
01289 {
01290 *data = (void *) _dbus_credentials_get_adt_audit_data (auth_identity);
01291 *data_size = _dbus_credentials_get_adt_audit_data_size (auth_identity);
01292 return TRUE;
01293 }
01294 else
01295 return FALSE;
01296 }
01297
01308 void
01309 _dbus_transport_set_unix_user_function (DBusTransport *transport,
01310 DBusAllowUnixUserFunction function,
01311 void *data,
01312 DBusFreeFunction free_data_function,
01313 void **old_data,
01314 DBusFreeFunction *old_free_data_function)
01315 {
01316 *old_data = transport->unix_user_data;
01317 *old_free_data_function = transport->free_unix_user_data;
01318
01319 transport->unix_user_function = function;
01320 transport->unix_user_data = data;
01321 transport->free_unix_user_data = free_data_function;
01322 }
01323
01331 dbus_bool_t
01332 _dbus_transport_get_windows_user (DBusTransport *transport,
01333 char **windows_sid_p)
01334 {
01335 DBusCredentials *auth_identity;
01336
01337 *windows_sid_p = NULL;
01338
01339 if (!transport->authenticated)
01340 return FALSE;
01341
01342 auth_identity = _dbus_auth_get_identity (transport->auth);
01343
01344 if (_dbus_credentials_include (auth_identity,
01345 DBUS_CREDENTIAL_WINDOWS_SID))
01346 {
01347
01348 *windows_sid_p = _dbus_strdup (_dbus_credentials_get_windows_sid (auth_identity));
01349
01350 return TRUE;
01351 }
01352 else
01353 return FALSE;
01354 }
01355
01367 void
01368 _dbus_transport_set_windows_user_function (DBusTransport *transport,
01369 DBusAllowWindowsUserFunction function,
01370 void *data,
01371 DBusFreeFunction free_data_function,
01372 void **old_data,
01373 DBusFreeFunction *old_free_data_function)
01374 {
01375 *old_data = transport->windows_user_data;
01376 *old_free_data_function = transport->free_windows_user_data;
01377
01378 transport->windows_user_function = function;
01379 transport->windows_user_data = data;
01380 transport->free_windows_user_data = free_data_function;
01381 }
01382
01391 dbus_bool_t
01392 _dbus_transport_set_auth_mechanisms (DBusTransport *transport,
01393 const char **mechanisms)
01394 {
01395 return _dbus_auth_set_mechanisms (transport->auth, mechanisms);
01396 }
01397
01404 void
01405 _dbus_transport_set_allow_anonymous (DBusTransport *transport,
01406 dbus_bool_t value)
01407 {
01408 transport->allow_anonymous = value != FALSE;
01409 }
01410