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;
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 dbus_error_init (&tmp_error);
00372 for (i = 0; i < (int) _DBUS_N_ELEMENTS (open_funcs); ++i)
00373 {
00374 DBusTransportOpenResult result;
00375
00376 _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error);
00377 result = (* open_funcs[i].func) (entry, &transport, &tmp_error);
00378
00379 switch (result)
00380 {
00381 case DBUS_TRANSPORT_OPEN_OK:
00382 _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error);
00383 goto out;
00384 break;
00385 case DBUS_TRANSPORT_OPEN_NOT_HANDLED:
00386 _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error);
00387
00388 break;
00389 case DBUS_TRANSPORT_OPEN_BAD_ADDRESS:
00390 _DBUS_ASSERT_ERROR_IS_SET (&tmp_error);
00391 goto out;
00392 break;
00393 case DBUS_TRANSPORT_OPEN_DID_NOT_CONNECT:
00394 _DBUS_ASSERT_ERROR_IS_SET (&tmp_error);
00395 goto out;
00396 break;
00397 }
00398 }
00399
00400 out:
00401
00402 if (transport == NULL)
00403 {
00404 if (!dbus_error_is_set (&tmp_error))
00405 _dbus_set_bad_address (&tmp_error,
00406 NULL, NULL,
00407 "Unknown address type (examples of valid types are \"tcp\" and on UNIX \"unix\")");
00408
00409 _DBUS_ASSERT_ERROR_IS_SET (&tmp_error);
00410 dbus_move_error(&tmp_error, error);
00411 dbus_free (expected_guid);
00412 }
00413 else
00414 {
00415 _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error);
00416 transport->expected_guid = expected_guid;
00417 }
00418
00419 return transport;
00420 }
00421
00428 DBusTransport *
00429 _dbus_transport_ref (DBusTransport *transport)
00430 {
00431 _dbus_assert (transport->refcount > 0);
00432
00433 transport->refcount += 1;
00434
00435 return transport;
00436 }
00437
00445 void
00446 _dbus_transport_unref (DBusTransport *transport)
00447 {
00448 _dbus_assert (transport != NULL);
00449 _dbus_assert (transport->refcount > 0);
00450
00451 transport->refcount -= 1;
00452 if (transport->refcount == 0)
00453 {
00454 _dbus_verbose ("%s: finalizing\n", _DBUS_FUNCTION_NAME);
00455
00456 _dbus_assert (transport->vtable->finalize != NULL);
00457
00458 (* transport->vtable->finalize) (transport);
00459 }
00460 }
00461
00470 void
00471 _dbus_transport_disconnect (DBusTransport *transport)
00472 {
00473 _dbus_verbose ("%s start\n", _DBUS_FUNCTION_NAME);
00474
00475 _dbus_assert (transport->vtable->disconnect != NULL);
00476
00477 if (transport->disconnected)
00478 return;
00479
00480 (* transport->vtable->disconnect) (transport);
00481
00482 transport->disconnected = TRUE;
00483
00484 _dbus_verbose ("%s end\n", _DBUS_FUNCTION_NAME);
00485 }
00486
00495 dbus_bool_t
00496 _dbus_transport_get_is_connected (DBusTransport *transport)
00497 {
00498 return !transport->disconnected;
00499 }
00500
00501 static dbus_bool_t
00502 auth_via_unix_user_function (DBusTransport *transport)
00503 {
00504 DBusCredentials *auth_identity;
00505 dbus_bool_t allow;
00506 DBusConnection *connection;
00507 DBusAllowUnixUserFunction unix_user_function;
00508 void *unix_user_data;
00509 dbus_uid_t uid;
00510
00511
00512
00513 auth_identity = _dbus_auth_get_identity (transport->auth);
00514 _dbus_assert (auth_identity != NULL);
00515
00516 connection = transport->connection;
00517 unix_user_function = transport->unix_user_function;
00518 unix_user_data = transport->unix_user_data;
00519 uid = _dbus_credentials_get_unix_uid (auth_identity);
00520
00521 _dbus_verbose ("unlock %s\n", _DBUS_FUNCTION_NAME);
00522 _dbus_connection_unlock (connection);
00523
00524 allow = (* unix_user_function) (connection,
00525 uid,
00526 unix_user_data);
00527
00528 _dbus_verbose ("lock %s post unix user function\n", _DBUS_FUNCTION_NAME);
00529 _dbus_connection_lock (connection);
00530
00531 if (allow)
00532 {
00533 _dbus_verbose ("Client UID "DBUS_UID_FORMAT" authorized\n", uid);
00534 }
00535 else
00536 {
00537 _dbus_verbose ("Client UID "DBUS_UID_FORMAT
00538 " was rejected, disconnecting\n",
00539 _dbus_credentials_get_unix_uid (auth_identity));
00540 _dbus_transport_disconnect (transport);
00541 }
00542
00543 return allow;
00544 }
00545
00546 static dbus_bool_t
00547 auth_via_windows_user_function (DBusTransport *transport)
00548 {
00549 DBusCredentials *auth_identity;
00550 dbus_bool_t allow;
00551 DBusConnection *connection;
00552 DBusAllowWindowsUserFunction windows_user_function;
00553 void *windows_user_data;
00554 char *windows_sid;
00555
00556
00557
00558 auth_identity = _dbus_auth_get_identity (transport->auth);
00559 _dbus_assert (auth_identity != NULL);
00560
00561 connection = transport->connection;
00562 windows_user_function = transport->windows_user_function;
00563 windows_user_data = transport->unix_user_data;
00564 windows_sid = _dbus_strdup (_dbus_credentials_get_windows_sid (auth_identity));
00565
00566 if (windows_sid == NULL)
00567 {
00568
00569 return FALSE;
00570 }
00571
00572 _dbus_verbose ("unlock %s\n", _DBUS_FUNCTION_NAME);
00573 _dbus_connection_unlock (connection);
00574
00575 allow = (* windows_user_function) (connection,
00576 windows_sid,
00577 windows_user_data);
00578
00579 _dbus_verbose ("lock %s post windows user function\n", _DBUS_FUNCTION_NAME);
00580 _dbus_connection_lock (connection);
00581
00582 if (allow)
00583 {
00584 _dbus_verbose ("Client SID '%s' authorized\n", windows_sid);
00585 }
00586 else
00587 {
00588 _dbus_verbose ("Client SID '%s' was rejected, disconnecting\n",
00589 _dbus_credentials_get_windows_sid (auth_identity));
00590 _dbus_transport_disconnect (transport);
00591 }
00592
00593 return allow;
00594 }
00595
00596 static dbus_bool_t
00597 auth_via_default_rules (DBusTransport *transport)
00598 {
00599 DBusCredentials *auth_identity;
00600 DBusCredentials *our_identity;
00601 dbus_bool_t allow;
00602
00603 auth_identity = _dbus_auth_get_identity (transport->auth);
00604 _dbus_assert (auth_identity != NULL);
00605
00606
00607
00608
00609
00610 our_identity = _dbus_credentials_new_from_current_process ();
00611 if (our_identity == NULL)
00612 {
00613
00614 return FALSE;
00615 }
00616
00617 if (transport->allow_anonymous ||
00618 _dbus_credentials_get_unix_uid (auth_identity) == 0 ||
00619 _dbus_credentials_same_user (our_identity,
00620 auth_identity))
00621 {
00622 if (_dbus_credentials_include(our_identity,DBUS_CREDENTIAL_WINDOWS_SID))
00623 _dbus_verbose ("Client authorized as SID '%s'"
00624 "matching our SID '%s'\n",
00625 _dbus_credentials_get_windows_sid(auth_identity),
00626 _dbus_credentials_get_windows_sid(our_identity));
00627 else
00628 _dbus_verbose ("Client authorized as UID "DBUS_UID_FORMAT
00629 " matching our UID "DBUS_UID_FORMAT"\n",
00630 _dbus_credentials_get_unix_uid(auth_identity),
00631 _dbus_credentials_get_unix_uid(our_identity));
00632
00633 allow = TRUE;
00634 }
00635 else
00636 {
00637 if (_dbus_credentials_include(our_identity,DBUS_CREDENTIAL_WINDOWS_SID))
00638 _dbus_verbose ("Client authorized as SID '%s'"
00639 " but our SID is '%s', disconnecting\n",
00640 _dbus_credentials_get_windows_sid(our_identity),
00641 _dbus_credentials_get_windows_sid(our_identity));
00642 else
00643 _dbus_verbose ("Client authorized as UID "DBUS_UID_FORMAT
00644 " but our UID is "DBUS_UID_FORMAT", disconnecting\n",
00645 _dbus_credentials_get_unix_uid(our_identity),
00646 _dbus_credentials_get_unix_uid(our_identity));
00647 _dbus_transport_disconnect (transport);
00648 allow = FALSE;
00649 }
00650
00651 _dbus_credentials_unref (our_identity);
00652
00653 return allow;
00654 }
00655
00656
00667 dbus_bool_t
00668 _dbus_transport_get_is_authenticated (DBusTransport *transport)
00669 {
00670 if (transport->authenticated)
00671 return TRUE;
00672 else
00673 {
00674 dbus_bool_t maybe_authenticated;
00675
00676 if (transport->disconnected)
00677 return FALSE;
00678
00679
00680 _dbus_connection_ref_unlocked (transport->connection);
00681
00682 maybe_authenticated =
00683 (!(transport->send_credentials_pending ||
00684 transport->receive_credentials_pending));
00685
00686 if (maybe_authenticated)
00687 {
00688 switch (_dbus_auth_do_work (transport->auth))
00689 {
00690 case DBUS_AUTH_STATE_AUTHENTICATED:
00691
00692 break;
00693 default:
00694 maybe_authenticated = FALSE;
00695 }
00696 }
00697
00698
00699
00700 if (maybe_authenticated && !transport->is_server)
00701 {
00702 const char *server_guid;
00703
00704 server_guid = _dbus_auth_get_guid_from_server (transport->auth);
00705 _dbus_assert (server_guid != NULL);
00706
00707 if (transport->expected_guid &&
00708 strcmp (transport->expected_guid, server_guid) != 0)
00709 {
00710 _dbus_verbose ("Client expected GUID '%s' and we got '%s' from the server\n",
00711 transport->expected_guid, server_guid);
00712 _dbus_transport_disconnect (transport);
00713 _dbus_connection_unref_unlocked (transport->connection);
00714 return FALSE;
00715 }
00716
00717 if (transport->expected_guid == NULL)
00718 {
00719 transport->expected_guid = _dbus_strdup (server_guid);
00720
00721 if (transport->expected_guid == NULL)
00722 {
00723 _dbus_verbose ("No memory to complete auth in %s\n", _DBUS_FUNCTION_NAME);
00724 return FALSE;
00725 }
00726 }
00727 }
00728
00729
00730
00731 if (maybe_authenticated && transport->is_server)
00732 {
00733 dbus_bool_t allow;
00734 DBusCredentials *auth_identity;
00735
00736 auth_identity = _dbus_auth_get_identity (transport->auth);
00737 _dbus_assert (auth_identity != NULL);
00738
00739
00740
00741
00742
00743 if (transport->unix_user_function != NULL &&
00744 _dbus_credentials_include (auth_identity, DBUS_CREDENTIAL_UNIX_USER_ID))
00745 {
00746 allow = auth_via_unix_user_function (transport);
00747 }
00748 else if (transport->windows_user_function != NULL &&
00749 _dbus_credentials_include (auth_identity, DBUS_CREDENTIAL_WINDOWS_SID))
00750 {
00751 allow = auth_via_windows_user_function (transport);
00752 }
00753 else
00754 {
00755 allow = auth_via_default_rules (transport);
00756 }
00757
00758 if (!allow)
00759 maybe_authenticated = FALSE;
00760 }
00761
00762 transport->authenticated = maybe_authenticated;
00763
00764 _dbus_connection_unref_unlocked (transport->connection);
00765 return maybe_authenticated;
00766 }
00767 }
00768
00775 dbus_bool_t
00776 _dbus_transport_get_is_anonymous (DBusTransport *transport)
00777 {
00778 DBusCredentials *auth_identity;
00779
00780 if (!transport->authenticated)
00781 return TRUE;
00782
00783 auth_identity = _dbus_auth_get_identity (transport->auth);
00784
00785 if (_dbus_credentials_are_anonymous (auth_identity))
00786 return TRUE;
00787 else
00788 return FALSE;
00789 }
00790
00798 const char*
00799 _dbus_transport_get_address (DBusTransport *transport)
00800 {
00801 return transport->address;
00802 }
00803
00811 const char*
00812 _dbus_transport_get_server_id (DBusTransport *transport)
00813 {
00814 if (transport->is_server)
00815 return NULL;
00816 else
00817 return transport->expected_guid;
00818 }
00819
00829 dbus_bool_t
00830 _dbus_transport_handle_watch (DBusTransport *transport,
00831 DBusWatch *watch,
00832 unsigned int condition)
00833 {
00834 dbus_bool_t retval;
00835
00836 _dbus_assert (transport->vtable->handle_watch != NULL);
00837
00838 if (transport->disconnected)
00839 return TRUE;
00840
00841 if (dbus_watch_get_socket (watch) < 0)
00842 {
00843 _dbus_warn_check_failed ("Tried to handle an invalidated watch; this watch should have been removed\n");
00844 return TRUE;
00845 }
00846
00847 _dbus_watch_sanitize_condition (watch, &condition);
00848
00849 _dbus_transport_ref (transport);
00850 _dbus_watch_ref (watch);
00851 retval = (* transport->vtable->handle_watch) (transport, watch, condition);
00852 _dbus_watch_unref (watch);
00853 _dbus_transport_unref (transport);
00854
00855 return retval;
00856 }
00857
00867 dbus_bool_t
00868 _dbus_transport_set_connection (DBusTransport *transport,
00869 DBusConnection *connection)
00870 {
00871 _dbus_assert (transport->vtable->connection_set != NULL);
00872 _dbus_assert (transport->connection == NULL);
00873
00874 transport->connection = connection;
00875
00876 _dbus_transport_ref (transport);
00877 if (!(* transport->vtable->connection_set) (transport))
00878 transport->connection = NULL;
00879 _dbus_transport_unref (transport);
00880
00881 return transport->connection != NULL;
00882 }
00883
00891 dbus_bool_t
00892 _dbus_transport_get_socket_fd (DBusTransport *transport,
00893 int *fd_p)
00894 {
00895 dbus_bool_t retval;
00896
00897 if (transport->vtable->get_socket_fd == NULL)
00898 return FALSE;
00899
00900 if (transport->disconnected)
00901 return FALSE;
00902
00903 _dbus_transport_ref (transport);
00904
00905 retval = (* transport->vtable->get_socket_fd) (transport,
00906 fd_p);
00907
00908 _dbus_transport_unref (transport);
00909
00910 return retval;
00911 }
00912
00924 void
00925 _dbus_transport_do_iteration (DBusTransport *transport,
00926 unsigned int flags,
00927 int timeout_milliseconds)
00928 {
00929 _dbus_assert (transport->vtable->do_iteration != NULL);
00930
00931 _dbus_verbose ("Transport iteration flags 0x%x timeout %d connected = %d\n",
00932 flags, timeout_milliseconds, !transport->disconnected);
00933
00934 if ((flags & (DBUS_ITERATION_DO_WRITING |
00935 DBUS_ITERATION_DO_READING)) == 0)
00936 return;
00937
00938 if (transport->disconnected)
00939 return;
00940
00941 _dbus_transport_ref (transport);
00942 (* transport->vtable->do_iteration) (transport, flags,
00943 timeout_milliseconds);
00944 _dbus_transport_unref (transport);
00945
00946 _dbus_verbose ("%s end\n", _DBUS_FUNCTION_NAME);
00947 }
00948
00949 static dbus_bool_t
00950 recover_unused_bytes (DBusTransport *transport)
00951 {
00952 if (_dbus_auth_needs_decoding (transport->auth))
00953 {
00954 DBusString plaintext;
00955 const DBusString *encoded;
00956 DBusString *buffer;
00957 int orig_len;
00958
00959 if (!_dbus_string_init (&plaintext))
00960 goto nomem;
00961
00962 _dbus_auth_get_unused_bytes (transport->auth,
00963 &encoded);
00964
00965 if (!_dbus_auth_decode_data (transport->auth,
00966 encoded, &plaintext))
00967 {
00968 _dbus_string_free (&plaintext);
00969 goto nomem;
00970 }
00971
00972 _dbus_message_loader_get_buffer (transport->loader,
00973 &buffer);
00974
00975 orig_len = _dbus_string_get_length (buffer);
00976
00977 if (!_dbus_string_move (&plaintext, 0, buffer,
00978 orig_len))
00979 {
00980 _dbus_string_free (&plaintext);
00981 goto nomem;
00982 }
00983
00984 _dbus_verbose (" %d unused bytes sent to message loader\n",
00985 _dbus_string_get_length (buffer) -
00986 orig_len);
00987
00988 _dbus_message_loader_return_buffer (transport->loader,
00989 buffer,
00990 _dbus_string_get_length (buffer) -
00991 orig_len);
00992
00993 _dbus_auth_delete_unused_bytes (transport->auth);
00994
00995 _dbus_string_free (&plaintext);
00996 }
00997 else
00998 {
00999 const DBusString *bytes;
01000 DBusString *buffer;
01001 int orig_len;
01002 dbus_bool_t succeeded;
01003
01004 _dbus_message_loader_get_buffer (transport->loader,
01005 &buffer);
01006
01007 orig_len = _dbus_string_get_length (buffer);
01008
01009 _dbus_auth_get_unused_bytes (transport->auth,
01010 &bytes);
01011
01012 succeeded = TRUE;
01013 if (!_dbus_string_copy (bytes, 0, buffer, _dbus_string_get_length (buffer)))
01014 succeeded = FALSE;
01015
01016 _dbus_verbose (" %d unused bytes sent to message loader\n",
01017 _dbus_string_get_length (buffer) -
01018 orig_len);
01019
01020 _dbus_message_loader_return_buffer (transport->loader,
01021 buffer,
01022 _dbus_string_get_length (buffer) -
01023 orig_len);
01024
01025 if (succeeded)
01026 _dbus_auth_delete_unused_bytes (transport->auth);
01027 else
01028 goto nomem;
01029 }
01030
01031 return TRUE;
01032
01033 nomem:
01034 _dbus_verbose ("Not enough memory to transfer unused bytes from auth conversation\n");
01035 return FALSE;
01036 }
01037
01045 DBusDispatchStatus
01046 _dbus_transport_get_dispatch_status (DBusTransport *transport)
01047 {
01048 if (_dbus_counter_get_value (transport->live_messages_size) >= transport->max_live_messages_size)
01049 return DBUS_DISPATCH_COMPLETE;
01050
01051 if (!_dbus_transport_get_is_authenticated (transport))
01052 {
01053 if (_dbus_auth_do_work (transport->auth) ==
01054 DBUS_AUTH_STATE_WAITING_FOR_MEMORY)
01055 return DBUS_DISPATCH_NEED_MEMORY;
01056 else if (!_dbus_transport_get_is_authenticated (transport))
01057 return DBUS_DISPATCH_COMPLETE;
01058 }
01059
01060 if (!transport->unused_bytes_recovered &&
01061 !recover_unused_bytes (transport))
01062 return DBUS_DISPATCH_NEED_MEMORY;
01063
01064 transport->unused_bytes_recovered = TRUE;
01065
01066 if (!_dbus_message_loader_queue_messages (transport->loader))
01067 return DBUS_DISPATCH_NEED_MEMORY;
01068
01069 if (_dbus_message_loader_peek_message (transport->loader) != NULL)
01070 return DBUS_DISPATCH_DATA_REMAINS;
01071 else
01072 return DBUS_DISPATCH_COMPLETE;
01073 }
01074
01083 dbus_bool_t
01084 _dbus_transport_queue_messages (DBusTransport *transport)
01085 {
01086 DBusDispatchStatus status;
01087
01088 #if 0
01089 _dbus_verbose ("_dbus_transport_queue_messages()\n");
01090 #endif
01091
01092
01093 while ((status = _dbus_transport_get_dispatch_status (transport)) == DBUS_DISPATCH_DATA_REMAINS)
01094 {
01095 DBusMessage *message;
01096 DBusList *link;
01097
01098 link = _dbus_message_loader_pop_message_link (transport->loader);
01099 _dbus_assert (link != NULL);
01100
01101 message = link->data;
01102
01103 _dbus_verbose ("queueing received message %p\n", message);
01104
01105 if (!_dbus_message_add_size_counter (message, transport->live_messages_size))
01106 {
01107 _dbus_message_loader_putback_message_link (transport->loader,
01108 link);
01109 status = DBUS_DISPATCH_NEED_MEMORY;
01110 break;
01111 }
01112 else
01113 {
01114
01115 _dbus_connection_queue_received_message_link (transport->connection,
01116 link);
01117 }
01118 }
01119
01120 if (_dbus_message_loader_get_is_corrupted (transport->loader))
01121 {
01122 _dbus_verbose ("Corrupted message stream, disconnecting\n");
01123 _dbus_transport_disconnect (transport);
01124 }
01125
01126 return status != DBUS_DISPATCH_NEED_MEMORY;
01127 }
01128
01135 void
01136 _dbus_transport_set_max_message_size (DBusTransport *transport,
01137 long size)
01138 {
01139 _dbus_message_loader_set_max_message_size (transport->loader, size);
01140 }
01141
01148 long
01149 _dbus_transport_get_max_message_size (DBusTransport *transport)
01150 {
01151 return _dbus_message_loader_get_max_message_size (transport->loader);
01152 }
01153
01160 void
01161 _dbus_transport_set_max_received_size (DBusTransport *transport,
01162 long size)
01163 {
01164 transport->max_live_messages_size = size;
01165 _dbus_counter_set_notify (transport->live_messages_size,
01166 transport->max_live_messages_size,
01167 live_messages_size_notify,
01168 transport);
01169 }
01170
01171
01178 long
01179 _dbus_transport_get_max_received_size (DBusTransport *transport)
01180 {
01181 return transport->max_live_messages_size;
01182 }
01183
01191 dbus_bool_t
01192 _dbus_transport_get_unix_user (DBusTransport *transport,
01193 unsigned long *uid)
01194 {
01195 DBusCredentials *auth_identity;
01196
01197 *uid = _DBUS_INT32_MAX;
01198
01199
01200
01201
01202 if (!transport->authenticated)
01203 return FALSE;
01204
01205 auth_identity = _dbus_auth_get_identity (transport->auth);
01206
01207 if (_dbus_credentials_include (auth_identity,
01208 DBUS_CREDENTIAL_UNIX_USER_ID))
01209 {
01210 *uid = _dbus_credentials_get_unix_uid (auth_identity);
01211 return TRUE;
01212 }
01213 else
01214 return FALSE;
01215 }
01216
01224 dbus_bool_t
01225 _dbus_transport_get_unix_process_id (DBusTransport *transport,
01226 unsigned long *pid)
01227 {
01228 DBusCredentials *auth_identity;
01229
01230 *pid = DBUS_PID_UNSET;
01231
01232
01233
01234
01235 if (!transport->authenticated)
01236 return FALSE;
01237
01238 auth_identity = _dbus_auth_get_identity (transport->auth);
01239
01240 if (_dbus_credentials_include (auth_identity,
01241 DBUS_CREDENTIAL_UNIX_PROCESS_ID))
01242 {
01243 *pid = _dbus_credentials_get_unix_pid (auth_identity);
01244 return TRUE;
01245 }
01246 else
01247 return FALSE;
01248 }
01249
01260 void
01261 _dbus_transport_set_unix_user_function (DBusTransport *transport,
01262 DBusAllowUnixUserFunction function,
01263 void *data,
01264 DBusFreeFunction free_data_function,
01265 void **old_data,
01266 DBusFreeFunction *old_free_data_function)
01267 {
01268 *old_data = transport->unix_user_data;
01269 *old_free_data_function = transport->free_unix_user_data;
01270
01271 transport->unix_user_function = function;
01272 transport->unix_user_data = data;
01273 transport->free_unix_user_data = free_data_function;
01274 }
01275
01283 dbus_bool_t
01284 _dbus_transport_get_windows_user (DBusTransport *transport,
01285 char **windows_sid_p)
01286 {
01287 DBusCredentials *auth_identity;
01288
01289 *windows_sid_p = NULL;
01290
01291 if (!transport->authenticated)
01292 return FALSE;
01293
01294 auth_identity = _dbus_auth_get_identity (transport->auth);
01295
01296 if (_dbus_credentials_include (auth_identity,
01297 DBUS_CREDENTIAL_WINDOWS_SID))
01298 {
01299
01300 *windows_sid_p = _dbus_strdup (_dbus_credentials_get_windows_sid (auth_identity));
01301
01302 return TRUE;
01303 }
01304 else
01305 return FALSE;
01306 }
01307
01319 void
01320 _dbus_transport_set_windows_user_function (DBusTransport *transport,
01321 DBusAllowWindowsUserFunction function,
01322 void *data,
01323 DBusFreeFunction free_data_function,
01324 void **old_data,
01325 DBusFreeFunction *old_free_data_function)
01326 {
01327 *old_data = transport->windows_user_data;
01328 *old_free_data_function = transport->free_windows_user_data;
01329
01330 transport->windows_user_function = function;
01331 transport->windows_user_data = data;
01332 transport->free_windows_user_data = free_data_function;
01333 }
01334
01343 dbus_bool_t
01344 _dbus_transport_set_auth_mechanisms (DBusTransport *transport,
01345 const char **mechanisms)
01346 {
01347 return _dbus_auth_set_mechanisms (transport->auth, mechanisms);
01348 }
01349
01356 void
01357 _dbus_transport_set_allow_anonymous (DBusTransport *transport,
01358 dbus_bool_t value)
01359 {
01360 transport->allow_anonymous = value != FALSE;
01361 }
01362