dbus-transport.c

00001 /* -*- mode: C; c-file-style: "gnu" -*- */
00002 /* dbus-transport.c DBusTransport object (internal to D-Bus implementation)
00003  *
00004  * Copyright (C) 2002, 2003  Red Hat Inc.
00005  *
00006  * Licensed under the Academic Free License version 2.1
00007  * 
00008  * This program is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation; either version 2 of the License, or
00011  * (at your option) any later version.
00012  *
00013  * This program is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  * GNU General Public License for more details.
00017  * 
00018  * You should have received a copy of the GNU General Public License
00019  * along with this program; if not, write to the Free Software
00020  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021  *
00022  */
00023 
00024 #include "dbus-transport-protected.h"
00025 #include "dbus-transport-unix.h"
00026 #include "dbus-connection-internal.h"
00027 #include "dbus-watch.h"
00028 #include "dbus-auth.h"
00029 #include "dbus-address.h"
00030 #ifdef DBUS_BUILD_TESTS
00031 #include "dbus-server-debug-pipe.h"
00032 #endif
00033 
00055 static void
00056 live_messages_size_notify (DBusCounter *counter,
00057                            void        *user_data)
00058 {
00059   DBusTransport *transport = user_data;
00060 
00061   _dbus_transport_ref (transport);
00062 
00063 #if 0
00064   _dbus_verbose ("Counter value is now %d\n",
00065                  (int) _dbus_counter_get_value (counter));
00066 #endif
00067   
00068   /* disable or re-enable the read watch for the transport if
00069    * required.
00070    */
00071   if (transport->vtable->live_messages_changed)
00072     (* transport->vtable->live_messages_changed) (transport);
00073 
00074   _dbus_transport_unref (transport);
00075 }
00076 
00090 dbus_bool_t
00091 _dbus_transport_init_base (DBusTransport             *transport,
00092                            const DBusTransportVTable *vtable,
00093                            const DBusString          *server_guid,
00094                            const DBusString          *address)
00095 {
00096   DBusMessageLoader *loader;
00097   DBusAuth *auth;
00098   DBusCounter *counter;
00099   char *address_copy;
00100   
00101   loader = _dbus_message_loader_new ();
00102   if (loader == NULL)
00103     return FALSE;
00104   
00105   if (server_guid)
00106     auth = _dbus_auth_server_new (server_guid);
00107   else
00108     auth = _dbus_auth_client_new ();
00109   if (auth == NULL)
00110     {
00111       _dbus_message_loader_unref (loader);
00112       return FALSE;
00113     }
00114 
00115   counter = _dbus_counter_new ();
00116   if (counter == NULL)
00117     {
00118       _dbus_auth_unref (auth);
00119       _dbus_message_loader_unref (loader);
00120       return FALSE;
00121     }  
00122   
00123   if (server_guid)
00124     {
00125       _dbus_assert (address == NULL);
00126       address_copy = NULL;
00127     }
00128   else
00129     {
00130       _dbus_assert (address != NULL);
00131 
00132       if (!_dbus_string_copy_data (address, &address_copy))
00133         {
00134           _dbus_counter_unref (counter);
00135           _dbus_auth_unref (auth);
00136           _dbus_message_loader_unref (loader);
00137           return FALSE;
00138         }
00139     }
00140   
00141   transport->refcount = 1;
00142   transport->vtable = vtable;
00143   transport->loader = loader;
00144   transport->auth = auth;
00145   transport->live_messages_size = counter;
00146   transport->authenticated = FALSE;
00147   transport->disconnected = FALSE;
00148   transport->is_server = (server_guid != NULL);
00149   transport->send_credentials_pending = !transport->is_server;
00150   transport->receive_credentials_pending = transport->is_server;
00151   transport->address = address_copy;
00152   
00153   transport->unix_user_function = NULL;
00154   transport->unix_user_data = NULL;
00155   transport->free_unix_user_data = NULL;
00156 
00157   transport->expected_guid = NULL;
00158   
00159   /* Try to default to something that won't totally hose the system,
00160    * but doesn't impose too much of a limitation.
00161    */
00162   transport->max_live_messages_size = _DBUS_ONE_MEGABYTE * 63;
00163   
00164   transport->credentials.pid = -1;
00165   transport->credentials.uid = -1;
00166   transport->credentials.gid = -1;
00167 
00168   _dbus_counter_set_notify (transport->live_messages_size,
00169                             transport->max_live_messages_size,
00170                             live_messages_size_notify,
00171                             transport);
00172 
00173   if (transport->address)
00174     _dbus_verbose ("Initialized transport on address %s\n", transport->address);
00175   
00176   return TRUE;
00177 }
00178 
00185 void
00186 _dbus_transport_finalize_base (DBusTransport *transport)
00187 {
00188   if (!transport->disconnected)
00189     _dbus_transport_disconnect (transport);
00190 
00191   if (transport->free_unix_user_data != NULL)
00192     (* transport->free_unix_user_data) (transport->unix_user_data);
00193   
00194   _dbus_message_loader_unref (transport->loader);
00195   _dbus_auth_unref (transport->auth);
00196   _dbus_counter_set_notify (transport->live_messages_size,
00197                             0, NULL, NULL);
00198   _dbus_counter_unref (transport->live_messages_size);
00199   dbus_free (transport->address);
00200   dbus_free (transport->expected_guid);
00201 }
00202 
00211 DBusTransport*
00212 _dbus_transport_open (DBusAddressEntry *entry,
00213                       DBusError        *error)
00214 {
00215   DBusTransport *transport;
00216   const char *address_problem_type;
00217   const char *address_problem_field;
00218   const char *address_problem_other;
00219   const char *method;
00220   const char *expected_guid_orig;
00221   char *expected_guid;
00222 
00223   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00224   
00225   transport = NULL;
00226   address_problem_type = NULL;
00227   address_problem_field = NULL;
00228   address_problem_other = NULL;
00229   expected_guid_orig = dbus_address_entry_get_value (entry, "guid");
00230   expected_guid = _dbus_strdup (expected_guid_orig);
00231 
00232   if (expected_guid_orig != NULL && expected_guid == NULL)
00233     {
00234       _DBUS_SET_OOM (error);
00235       return NULL;
00236     }
00237   
00238   method = dbus_address_entry_get_method (entry);
00239   _dbus_assert (method != NULL);
00240       
00241   if (strcmp (method, "unix") == 0)
00242     {
00243       const char *path = dbus_address_entry_get_value (entry, "path");
00244       const char *tmpdir = dbus_address_entry_get_value (entry, "tmpdir");
00245       const char *abstract = dbus_address_entry_get_value (entry, "abstract");
00246           
00247       if (tmpdir != NULL)
00248         {
00249           address_problem_other = "cannot use the \"tmpdir\" option for an address to connect to, only in an address to listen on";
00250           goto bad_address;
00251         }
00252           
00253       if (path == NULL && abstract == NULL)
00254         {
00255           address_problem_type = "unix";
00256           address_problem_field = "path or abstract";  
00257           goto bad_address;
00258         }
00259 
00260       if (path != NULL && abstract != NULL)
00261         {
00262           address_problem_other = "can't specify both \"path\" and \"abstract\" options in an address";
00263           goto bad_address;
00264         }
00265 
00266       if (path)
00267         transport = _dbus_transport_new_for_domain_socket (path, FALSE,
00268                                                            error);
00269       else
00270         transport = _dbus_transport_new_for_domain_socket (abstract, TRUE,
00271                                                            error);
00272     }
00273   else if (strcmp (method, "tcp") == 0)
00274     {
00275       const char *host = dbus_address_entry_get_value (entry, "host");
00276       const char *port = dbus_address_entry_get_value (entry, "port");
00277       DBusString  str;
00278       long lport;
00279       dbus_bool_t sresult;
00280           
00281       if (port == NULL)
00282         {
00283           address_problem_type = "tcp";
00284           address_problem_field = "port";
00285           goto bad_address;
00286         }
00287 
00288       _dbus_string_init_const (&str, port);
00289       sresult = _dbus_string_parse_int (&str, 0, &lport, NULL);
00290       _dbus_string_free (&str);
00291           
00292       if (sresult == FALSE || lport <= 0 || lport > 65535)
00293         {
00294           address_problem_other = "Port is not an integer between 0 and 65535";
00295           goto bad_address;
00296         }
00297           
00298       transport = _dbus_transport_new_for_tcp_socket (host, lport, error);
00299     }
00300 #ifdef DBUS_BUILD_TESTS
00301   else if (strcmp (method, "debug-pipe") == 0)
00302     {
00303       const char *name = dbus_address_entry_get_value (entry, "name");
00304 
00305       if (name == NULL)
00306         {
00307           address_problem_type = "debug-pipe";
00308           address_problem_field = "name";
00309           goto bad_address;
00310         }
00311           
00312       transport = _dbus_transport_debug_pipe_new (name, error);
00313     }
00314 #endif
00315   else
00316     {
00317       address_problem_other = "Unknown address type (examples of valid types are \"unix\" and \"tcp\")";
00318       goto bad_address;
00319     }
00320 
00321   if (transport == NULL)
00322     {
00323       _DBUS_ASSERT_ERROR_IS_SET (error);
00324       dbus_free (expected_guid);
00325     }
00326   else
00327     {
00328       transport->expected_guid = expected_guid;
00329     }
00330   
00331   return transport;
00332   
00333  bad_address:
00334   dbus_free (expected_guid);
00335   
00336   if (address_problem_type != NULL)
00337     dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
00338                     "Address of type %s was missing argument %s",
00339                     address_problem_type, address_problem_field);
00340   else
00341     dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
00342                     "Could not parse address: %s",
00343                     address_problem_other);
00344 
00345   return NULL;
00346 }
00347 
00354 DBusTransport *
00355 _dbus_transport_ref (DBusTransport *transport)
00356 {
00357   _dbus_assert (transport->refcount > 0);
00358   
00359   transport->refcount += 1;
00360 
00361   return transport;
00362 }
00363 
00371 void
00372 _dbus_transport_unref (DBusTransport *transport)
00373 {
00374   _dbus_assert (transport != NULL);
00375   _dbus_assert (transport->refcount > 0);
00376   
00377   transport->refcount -= 1;
00378   if (transport->refcount == 0)
00379     {
00380       _dbus_verbose ("%s: finalizing\n", _DBUS_FUNCTION_NAME);
00381       
00382       _dbus_assert (transport->vtable->finalize != NULL);
00383       
00384       (* transport->vtable->finalize) (transport);
00385     }
00386 }
00387 
00396 void
00397 _dbus_transport_disconnect (DBusTransport *transport)
00398 {
00399   _dbus_verbose ("%s start\n", _DBUS_FUNCTION_NAME);
00400   
00401   _dbus_assert (transport->vtable->disconnect != NULL);
00402   
00403   if (transport->disconnected)
00404     return;
00405 
00406   (* transport->vtable->disconnect) (transport);
00407   
00408   transport->disconnected = TRUE;
00409 
00410   _dbus_verbose ("%s end\n", _DBUS_FUNCTION_NAME);
00411 }
00412 
00421 dbus_bool_t
00422 _dbus_transport_get_is_connected (DBusTransport *transport)
00423 {
00424   return !transport->disconnected;
00425 }
00426 
00437 dbus_bool_t
00438 _dbus_transport_get_is_authenticated (DBusTransport *transport)
00439 {  
00440   if (transport->authenticated)
00441     return TRUE;
00442   else
00443     {
00444       dbus_bool_t maybe_authenticated;
00445       
00446       if (transport->disconnected)
00447         return FALSE;
00448 
00449       /* paranoia ref since we call user callbacks sometimes */
00450       _dbus_connection_ref_unlocked (transport->connection);
00451       
00452       maybe_authenticated =
00453         (!(transport->send_credentials_pending ||
00454            transport->receive_credentials_pending));
00455 
00456       if (maybe_authenticated)
00457         {
00458           switch (_dbus_auth_do_work (transport->auth))
00459             {
00460             case DBUS_AUTH_STATE_AUTHENTICATED:
00461               /* leave as maybe_authenticated */
00462               break;
00463             default:
00464               maybe_authenticated = FALSE;
00465             }
00466         }
00467 
00468       if (maybe_authenticated && !transport->is_server)
00469         {
00470           const char *server_guid;
00471 
00472           server_guid = _dbus_auth_get_guid_from_server (transport->auth);
00473           _dbus_assert (server_guid != NULL);
00474 
00475           if (transport->expected_guid &&
00476               strcmp (transport->expected_guid, server_guid) != 0)
00477             {
00478               _dbus_verbose ("Client expected GUID '%s' and we got '%s' from the server\n",
00479                              transport->expected_guid, server_guid);
00480               _dbus_transport_disconnect (transport);
00481               _dbus_connection_unref_unlocked (transport->connection);
00482               return FALSE;
00483             }
00484 
00485           if (transport->expected_guid == NULL)
00486             {
00487               transport->expected_guid = _dbus_strdup (server_guid);
00488 
00489               if (transport->expected_guid == NULL)
00490                 {
00491                   _dbus_verbose ("No memory to complete auth in %s\n", _DBUS_FUNCTION_NAME);
00492                   return FALSE;
00493                 }
00494             }
00495         }
00496       
00497       /* If we've authenticated as some identity, check that the auth
00498        * identity is the same as our own identity.  In the future, we
00499        * may have API allowing applications to specify how this is
00500        * done, for example they may allow connection as any identity,
00501        * but then impose restrictions on certain identities.
00502        * Or they may give certain identities extra privileges.
00503        */
00504       
00505       if (maybe_authenticated && transport->is_server)
00506         {
00507           DBusCredentials auth_identity;
00508 
00509           _dbus_auth_get_identity (transport->auth, &auth_identity);
00510 
00511           if (transport->unix_user_function != NULL)
00512             {
00513               dbus_bool_t allow;
00514               DBusConnection *connection;
00515               DBusAllowUnixUserFunction unix_user_function;
00516               void *unix_user_data;
00517               
00518               /* Dropping the lock here probably isn't that safe. */
00519 
00520               connection = transport->connection;
00521               unix_user_function = transport->unix_user_function;
00522               unix_user_data = transport->unix_user_data;
00523 
00524               _dbus_verbose ("unlock %s\n", _DBUS_FUNCTION_NAME);
00525               _dbus_connection_unlock (connection);
00526               
00527               allow = (* unix_user_function) (connection,
00528                                               auth_identity.uid,
00529                                               unix_user_data);
00530 
00531               _dbus_verbose ("lock %s post unix user function\n", _DBUS_FUNCTION_NAME);
00532               _dbus_connection_lock (connection);
00533 
00534               if (allow)
00535                 {
00536                   _dbus_verbose ("Client UID "DBUS_UID_FORMAT" authorized\n", auth_identity.uid);
00537                 }
00538               else
00539                 {
00540                   _dbus_verbose ("Client UID "DBUS_UID_FORMAT
00541                                  " was rejected, disconnecting\n",
00542                                  auth_identity.uid);
00543                   _dbus_transport_disconnect (transport);
00544                   _dbus_connection_unref_unlocked (connection);
00545                   return FALSE;
00546                 }
00547             }
00548           else
00549             {
00550               DBusCredentials our_identity;
00551               
00552               _dbus_credentials_from_current_process (&our_identity);
00553               
00554               if (!_dbus_credentials_match (&our_identity,
00555                                             &auth_identity))
00556                 {
00557                   _dbus_verbose ("Client authorized as UID "DBUS_UID_FORMAT
00558                                  " but our UID is "DBUS_UID_FORMAT", disconnecting\n",
00559                                  auth_identity.uid, our_identity.uid);
00560                   _dbus_transport_disconnect (transport);
00561                   _dbus_connection_unref_unlocked (transport->connection);
00562                   return FALSE;
00563                 }
00564               else
00565                 {
00566                   _dbus_verbose ("Client authorized as UID "DBUS_UID_FORMAT
00567                                  " matching our UID "DBUS_UID_FORMAT"\n",
00568                                  auth_identity.uid, our_identity.uid);
00569                 }
00570             }
00571         }
00572       
00573       transport->authenticated = maybe_authenticated;
00574 
00575       _dbus_connection_unref_unlocked (transport->connection);
00576       return maybe_authenticated;
00577     }
00578 }
00579 
00587 const char*
00588 _dbus_transport_get_address (DBusTransport *transport)
00589 {
00590   return transport->address;
00591 }
00592 
00602 dbus_bool_t
00603 _dbus_transport_handle_watch (DBusTransport           *transport,
00604                               DBusWatch               *watch,
00605                               unsigned int             condition)
00606 {
00607   dbus_bool_t retval;
00608   
00609   _dbus_assert (transport->vtable->handle_watch != NULL);
00610 
00611   if (transport->disconnected)
00612     return TRUE;
00613 
00614   if (dbus_watch_get_fd (watch) < 0)
00615     {
00616       _dbus_warn ("Tried to handle an invalidated watch; this watch should have been removed\n");
00617       return TRUE;
00618     }
00619   
00620   _dbus_watch_sanitize_condition (watch, &condition);
00621 
00622   _dbus_transport_ref (transport);
00623   _dbus_watch_ref (watch);
00624   retval = (* transport->vtable->handle_watch) (transport, watch, condition);
00625   _dbus_watch_unref (watch);
00626   _dbus_transport_unref (transport);
00627 
00628   return retval;
00629 }
00630 
00640 dbus_bool_t
00641 _dbus_transport_set_connection (DBusTransport  *transport,
00642                                 DBusConnection *connection)
00643 {
00644   _dbus_assert (transport->vtable->connection_set != NULL);
00645   _dbus_assert (transport->connection == NULL);
00646   
00647   transport->connection = connection;
00648 
00649   _dbus_transport_ref (transport);
00650   if (!(* transport->vtable->connection_set) (transport))
00651     transport->connection = NULL;
00652   _dbus_transport_unref (transport);
00653 
00654   return transport->connection != NULL;
00655 }
00656 
00664 dbus_bool_t
00665 _dbus_transport_get_unix_fd (DBusTransport *transport,
00666                              int           *fd_p)
00667 {
00668   dbus_bool_t retval;
00669   
00670   if (transport->vtable->get_unix_fd == NULL)
00671     return FALSE;
00672 
00673   if (transport->disconnected)
00674     return FALSE;
00675 
00676   _dbus_transport_ref (transport);
00677 
00678   retval = (* transport->vtable->get_unix_fd) (transport,
00679                                                fd_p);
00680   
00681   _dbus_transport_unref (transport);
00682 
00683   return retval;
00684 }
00685 
00697 void
00698 _dbus_transport_do_iteration (DBusTransport  *transport,
00699                               unsigned int    flags,
00700                               int             timeout_milliseconds)
00701 {
00702   _dbus_assert (transport->vtable->do_iteration != NULL);
00703 
00704   _dbus_verbose ("Transport iteration flags 0x%x timeout %d connected = %d\n",
00705                  flags, timeout_milliseconds, !transport->disconnected);
00706   
00707   if ((flags & (DBUS_ITERATION_DO_WRITING |
00708                 DBUS_ITERATION_DO_READING)) == 0)
00709     return; /* Nothing to do */
00710 
00711   if (transport->disconnected)
00712     return;
00713 
00714   _dbus_transport_ref (transport);
00715   (* transport->vtable->do_iteration) (transport, flags,
00716                                        timeout_milliseconds);
00717   _dbus_transport_unref (transport);
00718 
00719   _dbus_verbose ("%s end\n", _DBUS_FUNCTION_NAME);
00720 }
00721 
00722 static dbus_bool_t
00723 recover_unused_bytes (DBusTransport *transport)
00724 {
00725   if (_dbus_auth_needs_decoding (transport->auth))
00726     {
00727       DBusString plaintext;
00728       const DBusString *encoded;
00729       DBusString *buffer;
00730       int orig_len;
00731       
00732       if (!_dbus_string_init (&plaintext))
00733         goto nomem;
00734       
00735       _dbus_auth_get_unused_bytes (transport->auth,
00736                                    &encoded);
00737 
00738       if (!_dbus_auth_decode_data (transport->auth,
00739                                    encoded, &plaintext))
00740         {
00741           _dbus_string_free (&plaintext);
00742           goto nomem;
00743         }
00744       
00745       _dbus_message_loader_get_buffer (transport->loader,
00746                                        &buffer);
00747       
00748       orig_len = _dbus_string_get_length (buffer);
00749       
00750       if (!_dbus_string_move (&plaintext, 0, buffer,
00751                               orig_len))
00752         {
00753           _dbus_string_free (&plaintext);
00754           goto nomem;
00755         }
00756       
00757       _dbus_verbose (" %d unused bytes sent to message loader\n", 
00758                      _dbus_string_get_length (buffer) -
00759                      orig_len);
00760       
00761       _dbus_message_loader_return_buffer (transport->loader,
00762                                           buffer,
00763                                           _dbus_string_get_length (buffer) -
00764                                           orig_len);
00765 
00766       _dbus_auth_delete_unused_bytes (transport->auth);
00767       
00768       _dbus_string_free (&plaintext);
00769     }
00770   else
00771     {
00772       const DBusString *bytes;
00773       DBusString *buffer;
00774       int orig_len;
00775       dbus_bool_t succeeded;
00776 
00777       _dbus_message_loader_get_buffer (transport->loader,
00778                                        &buffer);
00779                 
00780       orig_len = _dbus_string_get_length (buffer);
00781                 
00782       _dbus_auth_get_unused_bytes (transport->auth,
00783                                    &bytes);
00784 
00785       succeeded = TRUE;
00786       if (!_dbus_string_copy (bytes, 0, buffer, _dbus_string_get_length (buffer)))
00787         succeeded = FALSE;
00788       
00789       _dbus_verbose (" %d unused bytes sent to message loader\n", 
00790                      _dbus_string_get_length (buffer) -
00791                      orig_len);
00792       
00793       _dbus_message_loader_return_buffer (transport->loader,
00794                                           buffer,
00795                                           _dbus_string_get_length (buffer) -
00796                                           orig_len);
00797 
00798       if (succeeded)
00799         _dbus_auth_delete_unused_bytes (transport->auth);
00800       else
00801         goto nomem;
00802     }
00803 
00804   return TRUE;
00805 
00806  nomem:
00807   _dbus_verbose ("Not enough memory to transfer unused bytes from auth conversation\n");
00808   return FALSE;
00809 }
00810 
00818 DBusDispatchStatus
00819 _dbus_transport_get_dispatch_status (DBusTransport *transport)
00820 {
00821   if (_dbus_counter_get_value (transport->live_messages_size) >= transport->max_live_messages_size)
00822     return DBUS_DISPATCH_COMPLETE; /* complete for now */
00823 
00824   if (!_dbus_transport_get_is_authenticated (transport))
00825     {
00826       if (_dbus_auth_do_work (transport->auth) ==
00827           DBUS_AUTH_STATE_WAITING_FOR_MEMORY)
00828         return DBUS_DISPATCH_NEED_MEMORY;
00829       else if (!_dbus_transport_get_is_authenticated (transport))
00830         return DBUS_DISPATCH_COMPLETE;
00831     }
00832 
00833   if (!transport->unused_bytes_recovered &&
00834       !recover_unused_bytes (transport))
00835     return DBUS_DISPATCH_NEED_MEMORY;
00836 
00837   transport->unused_bytes_recovered = TRUE;
00838   
00839   if (!_dbus_message_loader_queue_messages (transport->loader))
00840     return DBUS_DISPATCH_NEED_MEMORY;
00841 
00842   if (_dbus_message_loader_peek_message (transport->loader) != NULL)
00843     return DBUS_DISPATCH_DATA_REMAINS;
00844   else
00845     return DBUS_DISPATCH_COMPLETE;
00846 }
00847 
00856 dbus_bool_t
00857 _dbus_transport_queue_messages (DBusTransport *transport)
00858 {
00859   DBusDispatchStatus status;
00860 
00861 #if 0
00862   _dbus_verbose ("_dbus_transport_queue_messages()\n");
00863 #endif
00864   
00865   /* Queue any messages */
00866   while ((status = _dbus_transport_get_dispatch_status (transport)) == DBUS_DISPATCH_DATA_REMAINS)
00867     {
00868       DBusMessage *message;
00869       DBusList *link;
00870 
00871       link = _dbus_message_loader_pop_message_link (transport->loader);
00872       _dbus_assert (link != NULL);
00873       
00874       message = link->data;
00875       
00876       _dbus_verbose ("queueing received message %p\n", message);
00877 
00878       if (!_dbus_message_add_size_counter (message, transport->live_messages_size))
00879         {
00880           _dbus_message_loader_putback_message_link (transport->loader,
00881                                                      link);
00882           status = DBUS_DISPATCH_NEED_MEMORY;
00883           break;
00884         }
00885       else
00886         {
00887           /* pass ownership of link and message ref to connection */
00888           _dbus_connection_queue_received_message_link (transport->connection,
00889                                                         link);
00890         }
00891     }
00892 
00893   if (_dbus_message_loader_get_is_corrupted (transport->loader))
00894     {
00895       _dbus_verbose ("Corrupted message stream, disconnecting\n");
00896       _dbus_transport_disconnect (transport);
00897     }
00898 
00899   return status != DBUS_DISPATCH_NEED_MEMORY;
00900 }
00901 
00908 void
00909 _dbus_transport_set_max_message_size (DBusTransport  *transport,
00910                                       long            size)
00911 {
00912   _dbus_message_loader_set_max_message_size (transport->loader, size);
00913 }
00914 
00921 long
00922 _dbus_transport_get_max_message_size (DBusTransport  *transport)
00923 {
00924   return _dbus_message_loader_get_max_message_size (transport->loader);
00925 }
00926 
00933 void
00934 _dbus_transport_set_max_received_size (DBusTransport  *transport,
00935                                        long            size)
00936 {
00937   transport->max_live_messages_size = size;
00938   _dbus_counter_set_notify (transport->live_messages_size,
00939                             transport->max_live_messages_size,
00940                             live_messages_size_notify,
00941                             transport);
00942 }
00943 
00944 
00951 long
00952 _dbus_transport_get_max_received_size (DBusTransport  *transport)
00953 {
00954   return transport->max_live_messages_size;
00955 }
00956 
00964 dbus_bool_t
00965 _dbus_transport_get_unix_user (DBusTransport *transport,
00966                                unsigned long *uid)
00967 {
00968   DBusCredentials auth_identity;
00969 
00970   *uid = _DBUS_INT32_MAX; /* better than some root or system user in
00971                            * case of bugs in the caller. Caller should
00972                            * never use this value on purpose, however.
00973                            */
00974   
00975   if (!transport->authenticated)
00976     return FALSE;
00977   
00978   _dbus_auth_get_identity (transport->auth, &auth_identity);
00979 
00980   if (auth_identity.uid != DBUS_UID_UNSET)
00981     {
00982       *uid = auth_identity.uid;
00983       return TRUE;
00984     }
00985   else
00986     return FALSE;
00987 }
00988 
00996 dbus_bool_t
00997 _dbus_transport_get_unix_process_id (DBusTransport *transport,
00998                                      unsigned long *pid)
00999 {
01000   DBusCredentials auth_identity;
01001 
01002   *pid = DBUS_PID_UNSET; /* Caller should never use this value on purpose,
01003                           * but we set it to a safe number, INT_MAX,
01004                           * just to root out possible bugs in bad callers.
01005                           */
01006   
01007   if (!transport->authenticated)
01008     return FALSE;
01009   
01010   _dbus_auth_get_identity (transport->auth, &auth_identity);
01011 
01012   if (auth_identity.pid != DBUS_PID_UNSET)
01013     {
01014       *pid = auth_identity.pid;
01015       return TRUE;
01016     }
01017   else
01018     return FALSE;
01019 }
01020 
01031 void
01032 _dbus_transport_set_unix_user_function (DBusTransport             *transport,
01033                                         DBusAllowUnixUserFunction  function,
01034                                         void                      *data,
01035                                         DBusFreeFunction           free_data_function,
01036                                         void                     **old_data,
01037                                         DBusFreeFunction          *old_free_data_function)
01038 {  
01039   *old_data = transport->unix_user_data;
01040   *old_free_data_function = transport->free_unix_user_data;
01041 
01042   transport->unix_user_function = function;
01043   transport->unix_user_data = data;
01044   transport->free_unix_user_data = free_data_function;
01045 }
01046 
01055 dbus_bool_t
01056 _dbus_transport_set_auth_mechanisms (DBusTransport  *transport,
01057                                      const char    **mechanisms)
01058 {
01059   return _dbus_auth_set_mechanisms (transport->auth, mechanisms);
01060 }
01061 
01062 

Generated on Wed Jan 3 04:58:29 2007 for D-Bus by  doxygen 1.4.7