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
00623 _dbus_verbose ("Client authorized as UID "DBUS_UID_FORMAT
00624 " matching our UID "DBUS_UID_FORMAT"\n",
00625 _dbus_credentials_get_unix_uid(auth_identity),
00626 _dbus_credentials_get_unix_uid(our_identity));
00627
00628 allow = TRUE;
00629 }
00630 else
00631 {
00632
00633 _dbus_verbose ("Client authorized as UID "DBUS_UID_FORMAT
00634 " but our UID is "DBUS_UID_FORMAT", disconnecting\n",
00635 _dbus_credentials_get_unix_uid(our_identity),
00636 _dbus_credentials_get_unix_uid(our_identity));
00637 _dbus_transport_disconnect (transport);
00638 allow = FALSE;
00639 }
00640
00641 _dbus_credentials_unref (our_identity);
00642
00643 return allow;
00644 }
00645
00646
00657 dbus_bool_t
00658 _dbus_transport_get_is_authenticated (DBusTransport *transport)
00659 {
00660 if (transport->authenticated)
00661 return TRUE;
00662 else
00663 {
00664 dbus_bool_t maybe_authenticated;
00665
00666 if (transport->disconnected)
00667 return FALSE;
00668
00669
00670 _dbus_connection_ref_unlocked (transport->connection);
00671
00672 maybe_authenticated =
00673 (!(transport->send_credentials_pending ||
00674 transport->receive_credentials_pending));
00675
00676 if (maybe_authenticated)
00677 {
00678 switch (_dbus_auth_do_work (transport->auth))
00679 {
00680 case DBUS_AUTH_STATE_AUTHENTICATED:
00681
00682 break;
00683 default:
00684 maybe_authenticated = FALSE;
00685 }
00686 }
00687
00688
00689
00690 if (maybe_authenticated && !transport->is_server)
00691 {
00692 const char *server_guid;
00693
00694 server_guid = _dbus_auth_get_guid_from_server (transport->auth);
00695 _dbus_assert (server_guid != NULL);
00696
00697 if (transport->expected_guid &&
00698 strcmp (transport->expected_guid, server_guid) != 0)
00699 {
00700 _dbus_verbose ("Client expected GUID '%s' and we got '%s' from the server\n",
00701 transport->expected_guid, server_guid);
00702 _dbus_transport_disconnect (transport);
00703 _dbus_connection_unref_unlocked (transport->connection);
00704 return FALSE;
00705 }
00706
00707 if (transport->expected_guid == NULL)
00708 {
00709 transport->expected_guid = _dbus_strdup (server_guid);
00710
00711 if (transport->expected_guid == NULL)
00712 {
00713 _dbus_verbose ("No memory to complete auth in %s\n", _DBUS_FUNCTION_NAME);
00714 return FALSE;
00715 }
00716 }
00717 }
00718
00719
00720
00721 if (maybe_authenticated && transport->is_server)
00722 {
00723 dbus_bool_t allow;
00724 DBusCredentials *auth_identity;
00725
00726 auth_identity = _dbus_auth_get_identity (transport->auth);
00727 _dbus_assert (auth_identity != NULL);
00728
00729
00730
00731
00732
00733 if (transport->unix_user_function != NULL &&
00734 _dbus_credentials_include (auth_identity, DBUS_CREDENTIAL_UNIX_USER_ID))
00735 {
00736 allow = auth_via_unix_user_function (transport);
00737 }
00738 else if (transport->windows_user_function != NULL &&
00739 _dbus_credentials_include (auth_identity, DBUS_CREDENTIAL_WINDOWS_SID))
00740 {
00741 allow = auth_via_windows_user_function (transport);
00742 }
00743 else
00744 {
00745 allow = auth_via_default_rules (transport);
00746 }
00747
00748 if (!allow)
00749 maybe_authenticated = FALSE;
00750 }
00751
00752 transport->authenticated = maybe_authenticated;
00753
00754 _dbus_connection_unref_unlocked (transport->connection);
00755 return maybe_authenticated;
00756 }
00757 }
00758
00765 dbus_bool_t
00766 _dbus_transport_get_is_anonymous (DBusTransport *transport)
00767 {
00768 DBusCredentials *auth_identity;
00769
00770 if (!transport->authenticated)
00771 return TRUE;
00772
00773 auth_identity = _dbus_auth_get_identity (transport->auth);
00774
00775 if (_dbus_credentials_are_anonymous (auth_identity))
00776 return TRUE;
00777 else
00778 return FALSE;
00779 }
00780
00788 const char*
00789 _dbus_transport_get_address (DBusTransport *transport)
00790 {
00791 return transport->address;
00792 }
00793
00801 const char*
00802 _dbus_transport_get_server_id (DBusTransport *transport)
00803 {
00804 if (transport->is_server)
00805 return NULL;
00806 else
00807 return transport->expected_guid;
00808 }
00809
00819 dbus_bool_t
00820 _dbus_transport_handle_watch (DBusTransport *transport,
00821 DBusWatch *watch,
00822 unsigned int condition)
00823 {
00824 dbus_bool_t retval;
00825
00826 _dbus_assert (transport->vtable->handle_watch != NULL);
00827
00828 if (transport->disconnected)
00829 return TRUE;
00830
00831 if (dbus_watch_get_socket (watch) < 0)
00832 {
00833 _dbus_warn_check_failed ("Tried to handle an invalidated watch; this watch should have been removed\n");
00834 return TRUE;
00835 }
00836
00837 _dbus_watch_sanitize_condition (watch, &condition);
00838
00839 _dbus_transport_ref (transport);
00840 _dbus_watch_ref (watch);
00841 retval = (* transport->vtable->handle_watch) (transport, watch, condition);
00842 _dbus_watch_unref (watch);
00843 _dbus_transport_unref (transport);
00844
00845 return retval;
00846 }
00847
00857 dbus_bool_t
00858 _dbus_transport_set_connection (DBusTransport *transport,
00859 DBusConnection *connection)
00860 {
00861 _dbus_assert (transport->vtable->connection_set != NULL);
00862 _dbus_assert (transport->connection == NULL);
00863
00864 transport->connection = connection;
00865
00866 _dbus_transport_ref (transport);
00867 if (!(* transport->vtable->connection_set) (transport))
00868 transport->connection = NULL;
00869 _dbus_transport_unref (transport);
00870
00871 return transport->connection != NULL;
00872 }
00873
00881 dbus_bool_t
00882 _dbus_transport_get_socket_fd (DBusTransport *transport,
00883 int *fd_p)
00884 {
00885 dbus_bool_t retval;
00886
00887 if (transport->vtable->get_socket_fd == NULL)
00888 return FALSE;
00889
00890 if (transport->disconnected)
00891 return FALSE;
00892
00893 _dbus_transport_ref (transport);
00894
00895 retval = (* transport->vtable->get_socket_fd) (transport,
00896 fd_p);
00897
00898 _dbus_transport_unref (transport);
00899
00900 return retval;
00901 }
00902
00914 void
00915 _dbus_transport_do_iteration (DBusTransport *transport,
00916 unsigned int flags,
00917 int timeout_milliseconds)
00918 {
00919 _dbus_assert (transport->vtable->do_iteration != NULL);
00920
00921 _dbus_verbose ("Transport iteration flags 0x%x timeout %d connected = %d\n",
00922 flags, timeout_milliseconds, !transport->disconnected);
00923
00924 if ((flags & (DBUS_ITERATION_DO_WRITING |
00925 DBUS_ITERATION_DO_READING)) == 0)
00926 return;
00927
00928 if (transport->disconnected)
00929 return;
00930
00931 _dbus_transport_ref (transport);
00932 (* transport->vtable->do_iteration) (transport, flags,
00933 timeout_milliseconds);
00934 _dbus_transport_unref (transport);
00935
00936 _dbus_verbose ("%s end\n", _DBUS_FUNCTION_NAME);
00937 }
00938
00939 static dbus_bool_t
00940 recover_unused_bytes (DBusTransport *transport)
00941 {
00942 if (_dbus_auth_needs_decoding (transport->auth))
00943 {
00944 DBusString plaintext;
00945 const DBusString *encoded;
00946 DBusString *buffer;
00947 int orig_len;
00948
00949 if (!_dbus_string_init (&plaintext))
00950 goto nomem;
00951
00952 _dbus_auth_get_unused_bytes (transport->auth,
00953 &encoded);
00954
00955 if (!_dbus_auth_decode_data (transport->auth,
00956 encoded, &plaintext))
00957 {
00958 _dbus_string_free (&plaintext);
00959 goto nomem;
00960 }
00961
00962 _dbus_message_loader_get_buffer (transport->loader,
00963 &buffer);
00964
00965 orig_len = _dbus_string_get_length (buffer);
00966
00967 if (!_dbus_string_move (&plaintext, 0, buffer,
00968 orig_len))
00969 {
00970 _dbus_string_free (&plaintext);
00971 goto nomem;
00972 }
00973
00974 _dbus_verbose (" %d unused bytes sent to message loader\n",
00975 _dbus_string_get_length (buffer) -
00976 orig_len);
00977
00978 _dbus_message_loader_return_buffer (transport->loader,
00979 buffer,
00980 _dbus_string_get_length (buffer) -
00981 orig_len);
00982
00983 _dbus_auth_delete_unused_bytes (transport->auth);
00984
00985 _dbus_string_free (&plaintext);
00986 }
00987 else
00988 {
00989 const DBusString *bytes;
00990 DBusString *buffer;
00991 int orig_len;
00992 dbus_bool_t succeeded;
00993
00994 _dbus_message_loader_get_buffer (transport->loader,
00995 &buffer);
00996
00997 orig_len = _dbus_string_get_length (buffer);
00998
00999 _dbus_auth_get_unused_bytes (transport->auth,
01000 &bytes);
01001
01002 succeeded = TRUE;
01003 if (!_dbus_string_copy (bytes, 0, buffer, _dbus_string_get_length (buffer)))
01004 succeeded = FALSE;
01005
01006 _dbus_verbose (" %d unused bytes sent to message loader\n",
01007 _dbus_string_get_length (buffer) -
01008 orig_len);
01009
01010 _dbus_message_loader_return_buffer (transport->loader,
01011 buffer,
01012 _dbus_string_get_length (buffer) -
01013 orig_len);
01014
01015 if (succeeded)
01016 _dbus_auth_delete_unused_bytes (transport->auth);
01017 else
01018 goto nomem;
01019 }
01020
01021 return TRUE;
01022
01023 nomem:
01024 _dbus_verbose ("Not enough memory to transfer unused bytes from auth conversation\n");
01025 return FALSE;
01026 }
01027
01035 DBusDispatchStatus
01036 _dbus_transport_get_dispatch_status (DBusTransport *transport)
01037 {
01038 if (_dbus_counter_get_value (transport->live_messages_size) >= transport->max_live_messages_size)
01039 return DBUS_DISPATCH_COMPLETE;
01040
01041 if (!_dbus_transport_get_is_authenticated (transport))
01042 {
01043 if (_dbus_auth_do_work (transport->auth) ==
01044 DBUS_AUTH_STATE_WAITING_FOR_MEMORY)
01045 return DBUS_DISPATCH_NEED_MEMORY;
01046 else if (!_dbus_transport_get_is_authenticated (transport))
01047 return DBUS_DISPATCH_COMPLETE;
01048 }
01049
01050 if (!transport->unused_bytes_recovered &&
01051 !recover_unused_bytes (transport))
01052 return DBUS_DISPATCH_NEED_MEMORY;
01053
01054 transport->unused_bytes_recovered = TRUE;
01055
01056 if (!_dbus_message_loader_queue_messages (transport->loader))
01057 return DBUS_DISPATCH_NEED_MEMORY;
01058
01059 if (_dbus_message_loader_peek_message (transport->loader) != NULL)
01060 return DBUS_DISPATCH_DATA_REMAINS;
01061 else
01062 return DBUS_DISPATCH_COMPLETE;
01063 }
01064
01073 dbus_bool_t
01074 _dbus_transport_queue_messages (DBusTransport *transport)
01075 {
01076 DBusDispatchStatus status;
01077
01078 #if 0
01079 _dbus_verbose ("_dbus_transport_queue_messages()\n");
01080 #endif
01081
01082
01083 while ((status = _dbus_transport_get_dispatch_status (transport)) == DBUS_DISPATCH_DATA_REMAINS)
01084 {
01085 DBusMessage *message;
01086 DBusList *link;
01087
01088 link = _dbus_message_loader_pop_message_link (transport->loader);
01089 _dbus_assert (link != NULL);
01090
01091 message = link->data;
01092
01093 _dbus_verbose ("queueing received message %p\n", message);
01094
01095 if (!_dbus_message_add_size_counter (message, transport->live_messages_size))
01096 {
01097 _dbus_message_loader_putback_message_link (transport->loader,
01098 link);
01099 status = DBUS_DISPATCH_NEED_MEMORY;
01100 break;
01101 }
01102 else
01103 {
01104
01105 _dbus_connection_queue_received_message_link (transport->connection,
01106 link);
01107 }
01108 }
01109
01110 if (_dbus_message_loader_get_is_corrupted (transport->loader))
01111 {
01112 _dbus_verbose ("Corrupted message stream, disconnecting\n");
01113 _dbus_transport_disconnect (transport);
01114 }
01115
01116 return status != DBUS_DISPATCH_NEED_MEMORY;
01117 }
01118
01125 void
01126 _dbus_transport_set_max_message_size (DBusTransport *transport,
01127 long size)
01128 {
01129 _dbus_message_loader_set_max_message_size (transport->loader, size);
01130 }
01131
01138 long
01139 _dbus_transport_get_max_message_size (DBusTransport *transport)
01140 {
01141 return _dbus_message_loader_get_max_message_size (transport->loader);
01142 }
01143
01150 void
01151 _dbus_transport_set_max_received_size (DBusTransport *transport,
01152 long size)
01153 {
01154 transport->max_live_messages_size = size;
01155 _dbus_counter_set_notify (transport->live_messages_size,
01156 transport->max_live_messages_size,
01157 live_messages_size_notify,
01158 transport);
01159 }
01160
01161
01168 long
01169 _dbus_transport_get_max_received_size (DBusTransport *transport)
01170 {
01171 return transport->max_live_messages_size;
01172 }
01173
01181 dbus_bool_t
01182 _dbus_transport_get_unix_user (DBusTransport *transport,
01183 unsigned long *uid)
01184 {
01185 DBusCredentials *auth_identity;
01186
01187 *uid = _DBUS_INT32_MAX;
01188
01189
01190
01191
01192 if (!transport->authenticated)
01193 return FALSE;
01194
01195 auth_identity = _dbus_auth_get_identity (transport->auth);
01196
01197 if (_dbus_credentials_include (auth_identity,
01198 DBUS_CREDENTIAL_UNIX_USER_ID))
01199 {
01200 *uid = _dbus_credentials_get_unix_uid (auth_identity);
01201 return TRUE;
01202 }
01203 else
01204 return FALSE;
01205 }
01206
01214 dbus_bool_t
01215 _dbus_transport_get_unix_process_id (DBusTransport *transport,
01216 unsigned long *pid)
01217 {
01218 DBusCredentials *auth_identity;
01219
01220 *pid = DBUS_PID_UNSET;
01221
01222
01223
01224
01225 if (!transport->authenticated)
01226 return FALSE;
01227
01228 auth_identity = _dbus_auth_get_identity (transport->auth);
01229
01230 if (_dbus_credentials_include (auth_identity,
01231 DBUS_CREDENTIAL_UNIX_PROCESS_ID))
01232 {
01233 *pid = _dbus_credentials_get_unix_pid (auth_identity);
01234 return TRUE;
01235 }
01236 else
01237 return FALSE;
01238 }
01239
01250 void
01251 _dbus_transport_set_unix_user_function (DBusTransport *transport,
01252 DBusAllowUnixUserFunction function,
01253 void *data,
01254 DBusFreeFunction free_data_function,
01255 void **old_data,
01256 DBusFreeFunction *old_free_data_function)
01257 {
01258 *old_data = transport->unix_user_data;
01259 *old_free_data_function = transport->free_unix_user_data;
01260
01261 transport->unix_user_function = function;
01262 transport->unix_user_data = data;
01263 transport->free_unix_user_data = free_data_function;
01264 }
01265
01273 dbus_bool_t
01274 _dbus_transport_get_windows_user (DBusTransport *transport,
01275 char **windows_sid_p)
01276 {
01277 DBusCredentials *auth_identity;
01278
01279 *windows_sid_p = NULL;
01280
01281 if (!transport->authenticated)
01282 return FALSE;
01283
01284 auth_identity = _dbus_auth_get_identity (transport->auth);
01285
01286 if (_dbus_credentials_include (auth_identity,
01287 DBUS_CREDENTIAL_WINDOWS_SID))
01288 {
01289
01290 *windows_sid_p = _dbus_strdup (_dbus_credentials_get_windows_sid (auth_identity));
01291
01292 return TRUE;
01293 }
01294 else
01295 return FALSE;
01296 }
01297
01309 void
01310 _dbus_transport_set_windows_user_function (DBusTransport *transport,
01311 DBusAllowWindowsUserFunction function,
01312 void *data,
01313 DBusFreeFunction free_data_function,
01314 void **old_data,
01315 DBusFreeFunction *old_free_data_function)
01316 {
01317 *old_data = transport->windows_user_data;
01318 *old_free_data_function = transport->free_windows_user_data;
01319
01320 transport->windows_user_function = function;
01321 transport->windows_user_data = data;
01322 transport->free_windows_user_data = free_data_function;
01323 }
01324
01333 dbus_bool_t
01334 _dbus_transport_set_auth_mechanisms (DBusTransport *transport,
01335 const char **mechanisms)
01336 {
01337 return _dbus_auth_set_mechanisms (transport->auth, mechanisms);
01338 }
01339
01346 void
01347 _dbus_transport_set_allow_anonymous (DBusTransport *transport,
01348 dbus_bool_t value)
01349 {
01350 transport->allow_anonymous = value != FALSE;
01351 }
01352