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