00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <config.h>
00025 #include "dbus-transport-protected.h"
00026 #include "dbus-transport-unix.h"
00027 #include "dbus-transport-socket.h"
00028 #include "dbus-connection-internal.h"
00029 #include "dbus-watch.h"
00030 #include "dbus-auth.h"
00031 #include "dbus-address.h"
00032 #include "dbus-credentials.h"
00033 #include "dbus-message-private.h"
00034 #include "dbus-marshal-header.h"
00035 #ifdef DBUS_BUILD_TESTS
00036 #include "dbus-server-debug-pipe.h"
00037 #endif
00038
00060 static void
00061 live_messages_notify (DBusCounter *counter,
00062 void *user_data)
00063 {
00064 DBusTransport *transport = user_data;
00065
00066 _dbus_transport_ref (transport);
00067
00068 #if 0
00069 _dbus_verbose ("Size counter value is now %d\n",
00070 (int) _dbus_counter_get_size_value (counter));
00071 _dbus_verbose ("Unix FD counter value is now %d\n",
00072 (int) _dbus_counter_get_unix_fd_value (counter));
00073 #endif
00074
00075
00076
00077
00078 if (transport->vtable->live_messages_changed)
00079 (* transport->vtable->live_messages_changed) (transport);
00080
00081 _dbus_transport_unref (transport);
00082 }
00083
00097 dbus_bool_t
00098 _dbus_transport_init_base (DBusTransport *transport,
00099 const DBusTransportVTable *vtable,
00100 const DBusString *server_guid,
00101 const DBusString *address)
00102 {
00103 DBusMessageLoader *loader;
00104 DBusAuth *auth;
00105 DBusCounter *counter;
00106 char *address_copy;
00107 DBusCredentials *creds;
00108
00109 loader = _dbus_message_loader_new ();
00110 if (loader == NULL)
00111 return FALSE;
00112
00113 if (server_guid)
00114 auth = _dbus_auth_server_new (server_guid);
00115 else
00116 auth = _dbus_auth_client_new ();
00117 if (auth == NULL)
00118 {
00119 _dbus_message_loader_unref (loader);
00120 return FALSE;
00121 }
00122
00123 counter = _dbus_counter_new ();
00124 if (counter == NULL)
00125 {
00126 _dbus_auth_unref (auth);
00127 _dbus_message_loader_unref (loader);
00128 return FALSE;
00129 }
00130
00131 creds = _dbus_credentials_new ();
00132 if (creds == NULL)
00133 {
00134 _dbus_counter_unref (counter);
00135 _dbus_auth_unref (auth);
00136 _dbus_message_loader_unref (loader);
00137 return FALSE;
00138 }
00139
00140 if (server_guid)
00141 {
00142 _dbus_assert (address == NULL);
00143 address_copy = NULL;
00144 }
00145 else
00146 {
00147 _dbus_assert (address != NULL);
00148
00149 if (!_dbus_string_copy_data (address, &address_copy))
00150 {
00151 _dbus_credentials_unref (creds);
00152 _dbus_counter_unref (counter);
00153 _dbus_auth_unref (auth);
00154 _dbus_message_loader_unref (loader);
00155 return FALSE;
00156 }
00157 }
00158
00159 transport->refcount = 1;
00160 transport->vtable = vtable;
00161 transport->loader = loader;
00162 transport->auth = auth;
00163 transport->live_messages = counter;
00164 transport->authenticated = FALSE;
00165 transport->disconnected = FALSE;
00166 transport->is_server = (server_guid != NULL);
00167 transport->send_credentials_pending = !transport->is_server;
00168 transport->receive_credentials_pending = transport->is_server;
00169 transport->address = address_copy;
00170
00171 transport->unix_user_function = NULL;
00172 transport->unix_user_data = NULL;
00173 transport->free_unix_user_data = NULL;
00174
00175 transport->windows_user_function = NULL;
00176 transport->windows_user_data = NULL;
00177 transport->free_windows_user_data = NULL;
00178
00179 transport->expected_guid = NULL;
00180
00181
00182
00183
00184 transport->max_live_messages_size = _DBUS_ONE_MEGABYTE * 63;
00185
00186
00187
00188 transport->max_live_messages_unix_fds = 4096;
00189
00190
00191 transport->credentials = creds;
00192
00193 _dbus_counter_set_notify (transport->live_messages,
00194 transport->max_live_messages_size,
00195 transport->max_live_messages_unix_fds,
00196 live_messages_notify,
00197 transport);
00198
00199 if (transport->address)
00200 _dbus_verbose ("Initialized transport on address %s\n", transport->address);
00201
00202 return TRUE;
00203 }
00204
00211 void
00212 _dbus_transport_finalize_base (DBusTransport *transport)
00213 {
00214 if (!transport->disconnected)
00215 _dbus_transport_disconnect (transport);
00216
00217 if (transport->free_unix_user_data != NULL)
00218 (* transport->free_unix_user_data) (transport->unix_user_data);
00219
00220 if (transport->free_windows_user_data != NULL)
00221 (* transport->free_windows_user_data) (transport->windows_user_data);
00222
00223 _dbus_message_loader_unref (transport->loader);
00224 _dbus_auth_unref (transport->auth);
00225 _dbus_counter_set_notify (transport->live_messages,
00226 0, 0, NULL, NULL);
00227 _dbus_counter_unref (transport->live_messages);
00228 dbus_free (transport->address);
00229 dbus_free (transport->expected_guid);
00230 if (transport->credentials)
00231 _dbus_credentials_unref (transport->credentials);
00232 }
00233
00234
00244 static DBusTransport*
00245 check_address (const char *address, DBusError *error)
00246 {
00247 DBusAddressEntry **entries;
00248 DBusTransport *transport = NULL;
00249 int len, i;
00250
00251 _dbus_assert (address != NULL);
00252 _dbus_assert (*address != '\0');
00253
00254 if (!dbus_parse_address (address, &entries, &len, error))
00255 return NULL;
00256
00257 for (i = 0; i < len; i++)
00258 {
00259 transport = _dbus_transport_open (entries[i], error);
00260 if (transport != NULL)
00261 break;
00262 }
00263
00264 dbus_address_entries_free (entries);
00265 return transport;
00266 }
00267
00275 static DBusTransport*
00276 _dbus_transport_new_for_autolaunch (const char *scope, DBusError *error)
00277 {
00278 DBusString address;
00279 DBusTransport *result = NULL;
00280
00281 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00282
00283 if (!_dbus_string_init (&address))
00284 {
00285 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00286 return NULL;
00287 }
00288
00289 if (!_dbus_get_autolaunch_address (scope, &address, error))
00290 {
00291 _DBUS_ASSERT_ERROR_IS_SET (error);
00292 goto out;
00293 }
00294
00295 result = check_address (_dbus_string_get_const_data (&address), error);
00296 if (result == NULL)
00297 _DBUS_ASSERT_ERROR_IS_SET (error);
00298 else
00299 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00300
00301 out:
00302 _dbus_string_free (&address);
00303 return result;
00304 }
00305
00306 static DBusTransportOpenResult
00307 _dbus_transport_open_autolaunch (DBusAddressEntry *entry,
00308 DBusTransport **transport_p,
00309 DBusError *error)
00310 {
00311 const char *method;
00312
00313 method = dbus_address_entry_get_method (entry);
00314 _dbus_assert (method != NULL);
00315
00316 if (strcmp (method, "autolaunch") == 0)
00317 {
00318 const char *scope = dbus_address_entry_get_value (entry, "scope");
00319
00320 *transport_p = _dbus_transport_new_for_autolaunch (scope, error);
00321
00322 if (*transport_p == NULL)
00323 {
00324 _DBUS_ASSERT_ERROR_IS_SET (error);
00325 return DBUS_TRANSPORT_OPEN_DID_NOT_CONNECT;
00326 }
00327 else
00328 {
00329 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00330 return DBUS_TRANSPORT_OPEN_OK;
00331 }
00332 }
00333 else
00334 {
00335 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00336 return DBUS_TRANSPORT_OPEN_NOT_HANDLED;
00337 }
00338 }
00339
00340 static const struct {
00341 DBusTransportOpenResult (* func) (DBusAddressEntry *entry,
00342 DBusTransport **transport_p,
00343 DBusError *error);
00344 } open_funcs[] = {
00345 { _dbus_transport_open_socket },
00346 { _dbus_transport_open_platform_specific },
00347 { _dbus_transport_open_autolaunch }
00348 #ifdef DBUS_BUILD_TESTS
00349 , { _dbus_transport_open_debug_pipe }
00350 #endif
00351 };
00352
00361 DBusTransport*
00362 _dbus_transport_open (DBusAddressEntry *entry,
00363 DBusError *error)
00364 {
00365 DBusTransport *transport;
00366 const char *expected_guid_orig;
00367 char *expected_guid;
00368 int i;
00369 DBusError tmp_error = DBUS_ERROR_INIT;
00370
00371 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00372
00373 transport = NULL;
00374 expected_guid_orig = dbus_address_entry_get_value (entry, "guid");
00375 expected_guid = _dbus_strdup (expected_guid_orig);
00376
00377 if (expected_guid_orig != NULL && expected_guid == NULL)
00378 {
00379 _DBUS_SET_OOM (error);
00380 return NULL;
00381 }
00382
00383 for (i = 0; i < (int) _DBUS_N_ELEMENTS (open_funcs); ++i)
00384 {
00385 DBusTransportOpenResult result;
00386
00387 _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error);
00388 result = (* open_funcs[i].func) (entry, &transport, &tmp_error);
00389
00390 switch (result)
00391 {
00392 case DBUS_TRANSPORT_OPEN_OK:
00393 _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error);
00394 goto out;
00395 break;
00396 case DBUS_TRANSPORT_OPEN_NOT_HANDLED:
00397 _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error);
00398
00399 break;
00400 case DBUS_TRANSPORT_OPEN_BAD_ADDRESS:
00401 _DBUS_ASSERT_ERROR_IS_SET (&tmp_error);
00402 goto out;
00403 break;
00404 case DBUS_TRANSPORT_OPEN_DID_NOT_CONNECT:
00405 _DBUS_ASSERT_ERROR_IS_SET (&tmp_error);
00406 goto out;
00407 break;
00408 }
00409 }
00410
00411 out:
00412
00413 if (transport == NULL)
00414 {
00415 if (!dbus_error_is_set (&tmp_error))
00416 _dbus_set_bad_address (&tmp_error,
00417 NULL, NULL,
00418 "Unknown address type (examples of valid types are \"tcp\" and on UNIX \"unix\")");
00419
00420 _DBUS_ASSERT_ERROR_IS_SET (&tmp_error);
00421 dbus_move_error(&tmp_error, error);
00422 dbus_free (expected_guid);
00423 }
00424 else
00425 {
00426 _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error);
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441 if(expected_guid)
00442 transport->expected_guid = expected_guid;
00443 }
00444
00445 return transport;
00446 }
00447
00454 DBusTransport *
00455 _dbus_transport_ref (DBusTransport *transport)
00456 {
00457 _dbus_assert (transport->refcount > 0);
00458
00459 transport->refcount += 1;
00460
00461 return transport;
00462 }
00463
00471 void
00472 _dbus_transport_unref (DBusTransport *transport)
00473 {
00474 _dbus_assert (transport != NULL);
00475 _dbus_assert (transport->refcount > 0);
00476
00477 transport->refcount -= 1;
00478 if (transport->refcount == 0)
00479 {
00480 _dbus_verbose ("finalizing\n");
00481
00482 _dbus_assert (transport->vtable->finalize != NULL);
00483
00484 (* transport->vtable->finalize) (transport);
00485 }
00486 }
00487
00496 void
00497 _dbus_transport_disconnect (DBusTransport *transport)
00498 {
00499 _dbus_verbose ("start\n");
00500
00501 _dbus_assert (transport->vtable->disconnect != NULL);
00502
00503 if (transport->disconnected)
00504 return;
00505
00506 (* transport->vtable->disconnect) (transport);
00507
00508 transport->disconnected = TRUE;
00509
00510 _dbus_verbose ("end\n");
00511 }
00512
00521 dbus_bool_t
00522 _dbus_transport_get_is_connected (DBusTransport *transport)
00523 {
00524 return !transport->disconnected;
00525 }
00526
00527 static dbus_bool_t
00528 auth_via_unix_user_function (DBusTransport *transport)
00529 {
00530 DBusCredentials *auth_identity;
00531 dbus_bool_t allow;
00532 DBusConnection *connection;
00533 DBusAllowUnixUserFunction unix_user_function;
00534 void *unix_user_data;
00535 dbus_uid_t uid;
00536
00537
00538
00539 auth_identity = _dbus_auth_get_identity (transport->auth);
00540 _dbus_assert (auth_identity != NULL);
00541
00542 connection = transport->connection;
00543 unix_user_function = transport->unix_user_function;
00544 unix_user_data = transport->unix_user_data;
00545 uid = _dbus_credentials_get_unix_uid (auth_identity);
00546
00547 _dbus_verbose ("unlock\n");
00548 _dbus_connection_unlock (connection);
00549
00550 allow = (* unix_user_function) (connection,
00551 uid,
00552 unix_user_data);
00553
00554 _dbus_verbose ("lock post unix user function\n");
00555 _dbus_connection_lock (connection);
00556
00557 if (allow)
00558 {
00559 _dbus_verbose ("Client UID "DBUS_UID_FORMAT" authorized\n", uid);
00560 }
00561 else
00562 {
00563 _dbus_verbose ("Client UID "DBUS_UID_FORMAT
00564 " was rejected, disconnecting\n",
00565 _dbus_credentials_get_unix_uid (auth_identity));
00566 _dbus_transport_disconnect (transport);
00567 }
00568
00569 return allow;
00570 }
00571
00572 static dbus_bool_t
00573 auth_via_windows_user_function (DBusTransport *transport)
00574 {
00575 DBusCredentials *auth_identity;
00576 dbus_bool_t allow;
00577 DBusConnection *connection;
00578 DBusAllowWindowsUserFunction windows_user_function;
00579 void *windows_user_data;
00580 char *windows_sid;
00581
00582
00583
00584 auth_identity = _dbus_auth_get_identity (transport->auth);
00585 _dbus_assert (auth_identity != NULL);
00586
00587 connection = transport->connection;
00588 windows_user_function = transport->windows_user_function;
00589 windows_user_data = transport->unix_user_data;
00590 windows_sid = _dbus_strdup (_dbus_credentials_get_windows_sid (auth_identity));
00591
00592 if (windows_sid == NULL)
00593 {
00594
00595 return FALSE;
00596 }
00597
00598 _dbus_verbose ("unlock\n");
00599 _dbus_connection_unlock (connection);
00600
00601 allow = (* windows_user_function) (connection,
00602 windows_sid,
00603 windows_user_data);
00604
00605 _dbus_verbose ("lock post windows user function\n");
00606 _dbus_connection_lock (connection);
00607
00608 if (allow)
00609 {
00610 _dbus_verbose ("Client SID '%s' authorized\n", windows_sid);
00611 }
00612 else
00613 {
00614 _dbus_verbose ("Client SID '%s' was rejected, disconnecting\n",
00615 _dbus_credentials_get_windows_sid (auth_identity));
00616 _dbus_transport_disconnect (transport);
00617 }
00618
00619 return allow;
00620 }
00621
00622 static dbus_bool_t
00623 auth_via_default_rules (DBusTransport *transport)
00624 {
00625 DBusCredentials *auth_identity;
00626 DBusCredentials *our_identity;
00627 dbus_bool_t allow;
00628
00629 auth_identity = _dbus_auth_get_identity (transport->auth);
00630 _dbus_assert (auth_identity != NULL);
00631
00632
00633
00634
00635
00636 our_identity = _dbus_credentials_new_from_current_process ();
00637 if (our_identity == NULL)
00638 {
00639
00640 return FALSE;
00641 }
00642
00643 if (transport->allow_anonymous ||
00644 _dbus_credentials_get_unix_uid (auth_identity) == 0 ||
00645 _dbus_credentials_same_user (our_identity,
00646 auth_identity))
00647 {
00648 if (_dbus_credentials_include(our_identity,DBUS_CREDENTIAL_WINDOWS_SID))
00649 _dbus_verbose ("Client authorized as SID '%s'"
00650 "matching our SID '%s'\n",
00651 _dbus_credentials_get_windows_sid(auth_identity),
00652 _dbus_credentials_get_windows_sid(our_identity));
00653 else
00654 _dbus_verbose ("Client authorized as UID "DBUS_UID_FORMAT
00655 " matching our UID "DBUS_UID_FORMAT"\n",
00656 _dbus_credentials_get_unix_uid(auth_identity),
00657 _dbus_credentials_get_unix_uid(our_identity));
00658
00659 allow = TRUE;
00660 }
00661 else
00662 {
00663 if (_dbus_credentials_include(our_identity,DBUS_CREDENTIAL_WINDOWS_SID))
00664 _dbus_verbose ("Client authorized as SID '%s'"
00665 " but our SID is '%s', disconnecting\n",
00666 (_dbus_credentials_get_windows_sid(auth_identity) ?
00667 _dbus_credentials_get_windows_sid(auth_identity) : "<null>"),
00668 (_dbus_credentials_get_windows_sid(our_identity) ?
00669 _dbus_credentials_get_windows_sid(our_identity) : "<null>"));
00670 else
00671 _dbus_verbose ("Client authorized as UID "DBUS_UID_FORMAT
00672 " but our UID is "DBUS_UID_FORMAT", disconnecting\n",
00673 _dbus_credentials_get_unix_uid(auth_identity),
00674 _dbus_credentials_get_unix_uid(our_identity));
00675 _dbus_transport_disconnect (transport);
00676 allow = FALSE;
00677 }
00678
00679 _dbus_credentials_unref (our_identity);
00680
00681 return allow;
00682 }
00683
00684
00695 dbus_bool_t
00696 _dbus_transport_get_is_authenticated (DBusTransport *transport)
00697 {
00698 if (transport->authenticated)
00699 return TRUE;
00700 else
00701 {
00702 dbus_bool_t maybe_authenticated;
00703
00704 if (transport->disconnected)
00705 return FALSE;
00706
00707
00708 _dbus_connection_ref_unlocked (transport->connection);
00709
00710 maybe_authenticated =
00711 (!(transport->send_credentials_pending ||
00712 transport->receive_credentials_pending));
00713
00714 if (maybe_authenticated)
00715 {
00716 switch (_dbus_auth_do_work (transport->auth))
00717 {
00718 case DBUS_AUTH_STATE_AUTHENTICATED:
00719
00720 break;
00721 default:
00722 maybe_authenticated = FALSE;
00723 }
00724 }
00725
00726
00727
00728 if (maybe_authenticated && !transport->is_server)
00729 {
00730 const char *server_guid;
00731
00732 server_guid = _dbus_auth_get_guid_from_server (transport->auth);
00733 _dbus_assert (server_guid != NULL);
00734
00735 if (transport->expected_guid &&
00736 strcmp (transport->expected_guid, server_guid) != 0)
00737 {
00738 _dbus_verbose ("Client expected GUID '%s' and we got '%s' from the server\n",
00739 transport->expected_guid, server_guid);
00740 _dbus_transport_disconnect (transport);
00741 _dbus_connection_unref_unlocked (transport->connection);
00742 return FALSE;
00743 }
00744
00745 if (transport->expected_guid == NULL)
00746 {
00747 transport->expected_guid = _dbus_strdup (server_guid);
00748
00749 if (transport->expected_guid == NULL)
00750 {
00751 _dbus_verbose ("No memory to complete auth\n");
00752 return FALSE;
00753 }
00754 }
00755 }
00756
00757
00758
00759 if (maybe_authenticated && transport->is_server)
00760 {
00761 dbus_bool_t allow;
00762 DBusCredentials *auth_identity;
00763
00764 auth_identity = _dbus_auth_get_identity (transport->auth);
00765 _dbus_assert (auth_identity != NULL);
00766
00767
00768
00769
00770
00771 if (transport->unix_user_function != NULL &&
00772 _dbus_credentials_include (auth_identity, DBUS_CREDENTIAL_UNIX_USER_ID))
00773 {
00774 allow = auth_via_unix_user_function (transport);
00775 }
00776 else if (transport->windows_user_function != NULL &&
00777 _dbus_credentials_include (auth_identity, DBUS_CREDENTIAL_WINDOWS_SID))
00778 {
00779 allow = auth_via_windows_user_function (transport);
00780 }
00781 else
00782 {
00783 allow = auth_via_default_rules (transport);
00784 }
00785
00786 if (!allow)
00787 maybe_authenticated = FALSE;
00788 }
00789
00790 transport->authenticated = maybe_authenticated;
00791
00792 _dbus_connection_unref_unlocked (transport->connection);
00793 return maybe_authenticated;
00794 }
00795 }
00796
00803 dbus_bool_t
00804 _dbus_transport_get_is_anonymous (DBusTransport *transport)
00805 {
00806 DBusCredentials *auth_identity;
00807
00808 if (!transport->authenticated)
00809 return TRUE;
00810
00811 auth_identity = _dbus_auth_get_identity (transport->auth);
00812
00813 if (_dbus_credentials_are_anonymous (auth_identity))
00814 return TRUE;
00815 else
00816 return FALSE;
00817 }
00818
00825 dbus_bool_t
00826 _dbus_transport_can_pass_unix_fd(DBusTransport *transport)
00827 {
00828 return DBUS_TRANSPORT_CAN_SEND_UNIX_FD(transport);
00829 }
00830
00838 const char*
00839 _dbus_transport_get_address (DBusTransport *transport)
00840 {
00841 return transport->address;
00842 }
00843
00851 const char*
00852 _dbus_transport_get_server_id (DBusTransport *transport)
00853 {
00854 if (transport->is_server)
00855 return NULL;
00856 else
00857 return transport->expected_guid;
00858 }
00859
00869 dbus_bool_t
00870 _dbus_transport_handle_watch (DBusTransport *transport,
00871 DBusWatch *watch,
00872 unsigned int condition)
00873 {
00874 dbus_bool_t retval;
00875
00876 _dbus_assert (transport->vtable->handle_watch != NULL);
00877
00878 if (transport->disconnected)
00879 return TRUE;
00880
00881 if (dbus_watch_get_socket (watch) < 0)
00882 {
00883 _dbus_warn_check_failed ("Tried to handle an invalidated watch; this watch should have been removed\n");
00884 return TRUE;
00885 }
00886
00887 _dbus_watch_sanitize_condition (watch, &condition);
00888
00889 _dbus_transport_ref (transport);
00890 _dbus_watch_ref (watch);
00891 retval = (* transport->vtable->handle_watch) (transport, watch, condition);
00892 _dbus_watch_unref (watch);
00893 _dbus_transport_unref (transport);
00894
00895 return retval;
00896 }
00897
00907 dbus_bool_t
00908 _dbus_transport_set_connection (DBusTransport *transport,
00909 DBusConnection *connection)
00910 {
00911 _dbus_assert (transport->vtable->connection_set != NULL);
00912 _dbus_assert (transport->connection == NULL);
00913
00914 transport->connection = connection;
00915
00916 _dbus_transport_ref (transport);
00917 if (!(* transport->vtable->connection_set) (transport))
00918 transport->connection = NULL;
00919 _dbus_transport_unref (transport);
00920
00921 return transport->connection != NULL;
00922 }
00923
00931 dbus_bool_t
00932 _dbus_transport_get_socket_fd (DBusTransport *transport,
00933 int *fd_p)
00934 {
00935 dbus_bool_t retval;
00936
00937 if (transport->vtable->get_socket_fd == NULL)
00938 return FALSE;
00939
00940 if (transport->disconnected)
00941 return FALSE;
00942
00943 _dbus_transport_ref (transport);
00944
00945 retval = (* transport->vtable->get_socket_fd) (transport,
00946 fd_p);
00947
00948 _dbus_transport_unref (transport);
00949
00950 return retval;
00951 }
00952
00964 void
00965 _dbus_transport_do_iteration (DBusTransport *transport,
00966 unsigned int flags,
00967 int timeout_milliseconds)
00968 {
00969 _dbus_assert (transport->vtable->do_iteration != NULL);
00970
00971 _dbus_verbose ("Transport iteration flags 0x%x timeout %d connected = %d\n",
00972 flags, timeout_milliseconds, !transport->disconnected);
00973
00974 if ((flags & (DBUS_ITERATION_DO_WRITING |
00975 DBUS_ITERATION_DO_READING)) == 0)
00976 return;
00977
00978 if (transport->disconnected)
00979 return;
00980
00981 _dbus_transport_ref (transport);
00982 (* transport->vtable->do_iteration) (transport, flags,
00983 timeout_milliseconds);
00984 _dbus_transport_unref (transport);
00985
00986 _dbus_verbose ("end\n");
00987 }
00988
00989 static dbus_bool_t
00990 recover_unused_bytes (DBusTransport *transport)
00991 {
00992 if (_dbus_auth_needs_decoding (transport->auth))
00993 {
00994 DBusString plaintext;
00995 const DBusString *encoded;
00996 DBusString *buffer;
00997 int orig_len;
00998
00999 if (!_dbus_string_init (&plaintext))
01000 goto nomem;
01001
01002 _dbus_auth_get_unused_bytes (transport->auth,
01003 &encoded);
01004
01005 if (!_dbus_auth_decode_data (transport->auth,
01006 encoded, &plaintext))
01007 {
01008 _dbus_string_free (&plaintext);
01009 goto nomem;
01010 }
01011
01012 _dbus_message_loader_get_buffer (transport->loader,
01013 &buffer);
01014
01015 orig_len = _dbus_string_get_length (buffer);
01016
01017 if (!_dbus_string_move (&plaintext, 0, buffer,
01018 orig_len))
01019 {
01020 _dbus_string_free (&plaintext);
01021 goto nomem;
01022 }
01023
01024 _dbus_verbose (" %d unused bytes sent to message loader\n",
01025 _dbus_string_get_length (buffer) -
01026 orig_len);
01027
01028 _dbus_message_loader_return_buffer (transport->loader,
01029 buffer,
01030 _dbus_string_get_length (buffer) -
01031 orig_len);
01032
01033 _dbus_auth_delete_unused_bytes (transport->auth);
01034
01035 _dbus_string_free (&plaintext);
01036 }
01037 else
01038 {
01039 const DBusString *bytes;
01040 DBusString *buffer;
01041 int orig_len;
01042 dbus_bool_t succeeded;
01043
01044 _dbus_message_loader_get_buffer (transport->loader,
01045 &buffer);
01046
01047 orig_len = _dbus_string_get_length (buffer);
01048
01049 _dbus_auth_get_unused_bytes (transport->auth,
01050 &bytes);
01051
01052 succeeded = TRUE;
01053 if (!_dbus_string_copy (bytes, 0, buffer, _dbus_string_get_length (buffer)))
01054 succeeded = FALSE;
01055
01056 _dbus_verbose (" %d unused bytes sent to message loader\n",
01057 _dbus_string_get_length (buffer) -
01058 orig_len);
01059
01060 _dbus_message_loader_return_buffer (transport->loader,
01061 buffer,
01062 _dbus_string_get_length (buffer) -
01063 orig_len);
01064
01065 if (succeeded)
01066 _dbus_auth_delete_unused_bytes (transport->auth);
01067 else
01068 goto nomem;
01069 }
01070
01071 return TRUE;
01072
01073 nomem:
01074 _dbus_verbose ("Not enough memory to transfer unused bytes from auth conversation\n");
01075 return FALSE;
01076 }
01077
01085 DBusDispatchStatus
01086 _dbus_transport_get_dispatch_status (DBusTransport *transport)
01087 {
01088 if (_dbus_counter_get_size_value (transport->live_messages) >= transport->max_live_messages_size ||
01089 _dbus_counter_get_unix_fd_value (transport->live_messages) >= transport->max_live_messages_unix_fds)
01090 return DBUS_DISPATCH_COMPLETE;
01091
01092 if (!_dbus_transport_get_is_authenticated (transport))
01093 {
01094 if (_dbus_auth_do_work (transport->auth) ==
01095 DBUS_AUTH_STATE_WAITING_FOR_MEMORY)
01096 return DBUS_DISPATCH_NEED_MEMORY;
01097 else if (!_dbus_transport_get_is_authenticated (transport))
01098 return DBUS_DISPATCH_COMPLETE;
01099 }
01100
01101 if (!transport->unused_bytes_recovered &&
01102 !recover_unused_bytes (transport))
01103 return DBUS_DISPATCH_NEED_MEMORY;
01104
01105 transport->unused_bytes_recovered = TRUE;
01106
01107 if (!_dbus_message_loader_queue_messages (transport->loader))
01108 return DBUS_DISPATCH_NEED_MEMORY;
01109
01110 if (_dbus_message_loader_peek_message (transport->loader) != NULL)
01111 return DBUS_DISPATCH_DATA_REMAINS;
01112 else
01113 return DBUS_DISPATCH_COMPLETE;
01114 }
01115
01124 dbus_bool_t
01125 _dbus_transport_queue_messages (DBusTransport *transport)
01126 {
01127 DBusDispatchStatus status;
01128
01129 #if 0
01130 _dbus_verbose ("_dbus_transport_queue_messages()\n");
01131 #endif
01132
01133
01134 while ((status = _dbus_transport_get_dispatch_status (transport)) == DBUS_DISPATCH_DATA_REMAINS)
01135 {
01136 DBusMessage *message;
01137 DBusList *link;
01138
01139 link = _dbus_message_loader_pop_message_link (transport->loader);
01140 _dbus_assert (link != NULL);
01141
01142 message = link->data;
01143
01144 _dbus_verbose ("queueing received message %p\n", message);
01145
01146 if (!_dbus_message_add_counter (message, transport->live_messages))
01147 {
01148 _dbus_message_loader_putback_message_link (transport->loader,
01149 link);
01150 status = DBUS_DISPATCH_NEED_MEMORY;
01151 break;
01152 }
01153 else
01154 {
01155
01156 _dbus_connection_queue_received_message_link (transport->connection,
01157 link);
01158 }
01159 }
01160
01161 if (_dbus_message_loader_get_is_corrupted (transport->loader))
01162 {
01163 _dbus_verbose ("Corrupted message stream, disconnecting\n");
01164 _dbus_transport_disconnect (transport);
01165 }
01166
01167 return status != DBUS_DISPATCH_NEED_MEMORY;
01168 }
01169
01176 void
01177 _dbus_transport_set_max_message_size (DBusTransport *transport,
01178 long size)
01179 {
01180 _dbus_message_loader_set_max_message_size (transport->loader, size);
01181 }
01182
01189 void
01190 _dbus_transport_set_max_message_unix_fds (DBusTransport *transport,
01191 long n)
01192 {
01193 _dbus_message_loader_set_max_message_unix_fds (transport->loader, n);
01194 }
01195
01202 long
01203 _dbus_transport_get_max_message_size (DBusTransport *transport)
01204 {
01205 return _dbus_message_loader_get_max_message_size (transport->loader);
01206 }
01207
01214 long
01215 _dbus_transport_get_max_message_unix_fds (DBusTransport *transport)
01216 {
01217 return _dbus_message_loader_get_max_message_unix_fds (transport->loader);
01218 }
01219
01226 void
01227 _dbus_transport_set_max_received_size (DBusTransport *transport,
01228 long size)
01229 {
01230 transport->max_live_messages_size = size;
01231 _dbus_counter_set_notify (transport->live_messages,
01232 transport->max_live_messages_size,
01233 transport->max_live_messages_unix_fds,
01234 live_messages_notify,
01235 transport);
01236 }
01237
01244 void
01245 _dbus_transport_set_max_received_unix_fds (DBusTransport *transport,
01246 long n)
01247 {
01248 transport->max_live_messages_unix_fds = n;
01249 _dbus_counter_set_notify (transport->live_messages,
01250 transport->max_live_messages_size,
01251 transport->max_live_messages_unix_fds,
01252 live_messages_notify,
01253 transport);
01254 }
01255
01262 long
01263 _dbus_transport_get_max_received_size (DBusTransport *transport)
01264 {
01265 return transport->max_live_messages_size;
01266 }
01267
01274 long
01275 _dbus_transport_get_max_received_unix_fds (DBusTransport *transport)
01276 {
01277 return transport->max_live_messages_unix_fds;
01278 }
01279
01287 dbus_bool_t
01288 _dbus_transport_get_unix_user (DBusTransport *transport,
01289 unsigned long *uid)
01290 {
01291 DBusCredentials *auth_identity;
01292
01293 *uid = _DBUS_INT32_MAX;
01294
01295
01296
01297
01298 if (!transport->authenticated)
01299 return FALSE;
01300
01301 auth_identity = _dbus_auth_get_identity (transport->auth);
01302
01303 if (_dbus_credentials_include (auth_identity,
01304 DBUS_CREDENTIAL_UNIX_USER_ID))
01305 {
01306 *uid = _dbus_credentials_get_unix_uid (auth_identity);
01307 return TRUE;
01308 }
01309 else
01310 return FALSE;
01311 }
01312
01320 dbus_bool_t
01321 _dbus_transport_get_unix_process_id (DBusTransport *transport,
01322 unsigned long *pid)
01323 {
01324 DBusCredentials *auth_identity;
01325
01326 *pid = DBUS_PID_UNSET;
01327
01328
01329
01330
01331 if (!transport->authenticated)
01332 return FALSE;
01333
01334 auth_identity = _dbus_auth_get_identity (transport->auth);
01335
01336 if (_dbus_credentials_include (auth_identity,
01337 DBUS_CREDENTIAL_UNIX_PROCESS_ID))
01338 {
01339 *pid = _dbus_credentials_get_unix_pid (auth_identity);
01340 return TRUE;
01341 }
01342 else
01343 return FALSE;
01344 }
01345
01354 dbus_bool_t
01355 _dbus_transport_get_adt_audit_session_data (DBusTransport *transport,
01356 void **data,
01357 int *data_size)
01358 {
01359 DBusCredentials *auth_identity;
01360
01361 *data = NULL;
01362 *data_size = 0;
01363
01364 if (!transport->authenticated)
01365 return FALSE;
01366
01367 auth_identity = _dbus_auth_get_identity (transport->auth);
01368
01369 if (_dbus_credentials_include (auth_identity,
01370 DBUS_CREDENTIAL_ADT_AUDIT_DATA_ID))
01371 {
01372 *data = (void *) _dbus_credentials_get_adt_audit_data (auth_identity);
01373 *data_size = _dbus_credentials_get_adt_audit_data_size (auth_identity);
01374 return TRUE;
01375 }
01376 else
01377 return FALSE;
01378 }
01379
01390 void
01391 _dbus_transport_set_unix_user_function (DBusTransport *transport,
01392 DBusAllowUnixUserFunction function,
01393 void *data,
01394 DBusFreeFunction free_data_function,
01395 void **old_data,
01396 DBusFreeFunction *old_free_data_function)
01397 {
01398 *old_data = transport->unix_user_data;
01399 *old_free_data_function = transport->free_unix_user_data;
01400
01401 transport->unix_user_function = function;
01402 transport->unix_user_data = data;
01403 transport->free_unix_user_data = free_data_function;
01404 }
01405
01413 dbus_bool_t
01414 _dbus_transport_get_windows_user (DBusTransport *transport,
01415 char **windows_sid_p)
01416 {
01417 DBusCredentials *auth_identity;
01418
01419 *windows_sid_p = NULL;
01420
01421 if (!transport->authenticated)
01422 return FALSE;
01423
01424 auth_identity = _dbus_auth_get_identity (transport->auth);
01425
01426 if (_dbus_credentials_include (auth_identity,
01427 DBUS_CREDENTIAL_WINDOWS_SID))
01428 {
01429
01430 *windows_sid_p = _dbus_strdup (_dbus_credentials_get_windows_sid (auth_identity));
01431
01432 return TRUE;
01433 }
01434 else
01435 return FALSE;
01436 }
01437
01449 void
01450 _dbus_transport_set_windows_user_function (DBusTransport *transport,
01451 DBusAllowWindowsUserFunction function,
01452 void *data,
01453 DBusFreeFunction free_data_function,
01454 void **old_data,
01455 DBusFreeFunction *old_free_data_function)
01456 {
01457 *old_data = transport->windows_user_data;
01458 *old_free_data_function = transport->free_windows_user_data;
01459
01460 transport->windows_user_function = function;
01461 transport->windows_user_data = data;
01462 transport->free_windows_user_data = free_data_function;
01463 }
01464
01473 dbus_bool_t
01474 _dbus_transport_set_auth_mechanisms (DBusTransport *transport,
01475 const char **mechanisms)
01476 {
01477 return _dbus_auth_set_mechanisms (transport->auth, mechanisms);
01478 }
01479
01486 void
01487 _dbus_transport_set_allow_anonymous (DBusTransport *transport,
01488 dbus_bool_t value)
01489 {
01490 transport->allow_anonymous = value != FALSE;
01491 }
01492