D-Bus  1.6.2
dbus-transport.c
1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2 /* dbus-transport.c DBusTransport object (internal to D-Bus implementation)
3  *
4  * Copyright (C) 2002, 2003 Red Hat Inc.
5  *
6  * Licensed under the Academic Free License version 2.1
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  *
22  */
23 
24 #include <config.h>
25 #include "dbus-transport-protected.h"
26 #include "dbus-transport-unix.h"
27 #include "dbus-transport-socket.h"
28 #include "dbus-connection-internal.h"
29 #include "dbus-watch.h"
30 #include "dbus-auth.h"
31 #include "dbus-address.h"
32 #include "dbus-credentials.h"
33 #include "dbus-mainloop.h"
34 #include "dbus-message.h"
35 #ifdef DBUS_BUILD_TESTS
36 #include "dbus-server-debug-pipe.h"
37 #endif
38 
60 static void
61 live_messages_notify (DBusCounter *counter,
62  void *user_data)
63 {
64  DBusTransport *transport = user_data;
65 
66  _dbus_transport_ref (transport);
67 
68 #if 0
69  _dbus_verbose ("Size counter value is now %d\n",
70  (int) _dbus_counter_get_size_value (counter));
71  _dbus_verbose ("Unix FD counter value is now %d\n",
72  (int) _dbus_counter_get_unix_fd_value (counter));
73 #endif
74 
75  /* disable or re-enable the read watch for the transport if
76  * required.
77  */
78  if (transport->vtable->live_messages_changed)
79  {
80  _dbus_connection_lock (transport->connection);
81  (* transport->vtable->live_messages_changed) (transport);
83  }
84 
85  _dbus_transport_unref (transport);
86 }
87 
103  const DBusTransportVTable *vtable,
104  const DBusString *server_guid,
105  const DBusString *address)
106 {
107  DBusMessageLoader *loader;
108  DBusAuth *auth;
109  DBusCounter *counter;
110  char *address_copy;
111  DBusCredentials *creds;
112 
113  loader = _dbus_message_loader_new ();
114  if (loader == NULL)
115  return FALSE;
116 
117  if (server_guid)
118  auth = _dbus_auth_server_new (server_guid);
119  else
120  auth = _dbus_auth_client_new ();
121  if (auth == NULL)
122  {
124  return FALSE;
125  }
126 
127  counter = _dbus_counter_new ();
128  if (counter == NULL)
129  {
130  _dbus_auth_unref (auth);
132  return FALSE;
133  }
134 
135  creds = _dbus_credentials_new ();
136  if (creds == NULL)
137  {
138  _dbus_counter_unref (counter);
139  _dbus_auth_unref (auth);
141  return FALSE;
142  }
143 
144  if (server_guid)
145  {
146  _dbus_assert (address == NULL);
147  address_copy = NULL;
148  }
149  else
150  {
151  _dbus_assert (address != NULL);
152 
153  if (!_dbus_string_copy_data (address, &address_copy))
154  {
155  _dbus_credentials_unref (creds);
156  _dbus_counter_unref (counter);
157  _dbus_auth_unref (auth);
159  return FALSE;
160  }
161  }
162 
163  transport->refcount = 1;
164  transport->vtable = vtable;
165  transport->loader = loader;
166  transport->auth = auth;
167  transport->live_messages = counter;
168  transport->authenticated = FALSE;
169  transport->disconnected = FALSE;
170  transport->is_server = (server_guid != NULL);
171  transport->send_credentials_pending = !transport->is_server;
172  transport->receive_credentials_pending = transport->is_server;
173  transport->address = address_copy;
174 
175  transport->unix_user_function = NULL;
176  transport->unix_user_data = NULL;
177  transport->free_unix_user_data = NULL;
178 
179  transport->windows_user_function = NULL;
180  transport->windows_user_data = NULL;
181  transport->free_windows_user_data = NULL;
182 
183  transport->expected_guid = NULL;
184 
185  /* Try to default to something that won't totally hose the system,
186  * but doesn't impose too much of a limitation.
187  */
188  transport->max_live_messages_size = _DBUS_ONE_MEGABYTE * 63;
189 
190  /* On Linux RLIMIT_NOFILE defaults to 1024, so allowing 4096 fds live
191  should be more than enough */
192  transport->max_live_messages_unix_fds = 4096;
193 
194  /* credentials read from socket if any */
195  transport->credentials = creds;
196 
198  transport->max_live_messages_size,
199  transport->max_live_messages_unix_fds,
200  live_messages_notify,
201  transport);
202 
203  if (transport->address)
204  _dbus_verbose ("Initialized transport on address %s\n", transport->address);
205 
206  return TRUE;
207 }
208 
215 void
217 {
218  if (!transport->disconnected)
219  _dbus_transport_disconnect (transport);
220 
221  if (transport->free_unix_user_data != NULL)
222  (* transport->free_unix_user_data) (transport->unix_user_data);
223 
224  if (transport->free_windows_user_data != NULL)
225  (* transport->free_windows_user_data) (transport->windows_user_data);
226 
227  _dbus_message_loader_unref (transport->loader);
228  _dbus_auth_unref (transport->auth);
230  0, 0, NULL, NULL);
231  _dbus_counter_unref (transport->live_messages);
232  dbus_free (transport->address);
233  dbus_free (transport->expected_guid);
234  if (transport->credentials)
236 }
237 
238 
248 static DBusTransport*
249 check_address (const char *address, DBusError *error)
250 {
251  DBusAddressEntry **entries;
252  DBusTransport *transport = NULL;
253  int len, i;
254 
255  _dbus_assert (address != NULL);
256  _dbus_assert (*address != '\0');
257 
258  if (!dbus_parse_address (address, &entries, &len, error))
259  return NULL; /* not a valid address */
260 
261  for (i = 0; i < len; i++)
262  {
263  transport = _dbus_transport_open (entries[i], error);
264  if (transport != NULL)
265  break;
266  }
267 
268  dbus_address_entries_free (entries);
269  return transport;
270 }
271 
279 static DBusTransport*
280 _dbus_transport_new_for_autolaunch (const char *scope, DBusError *error)
281 {
282  DBusString address;
283  DBusTransport *result = NULL;
284 
285  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
286 
287  if (!_dbus_string_init (&address))
288  {
290  return NULL;
291  }
292 
293  if (!_dbus_get_autolaunch_address (scope, &address, error))
294  {
295  _DBUS_ASSERT_ERROR_IS_SET (error);
296  goto out;
297  }
298 
299  result = check_address (_dbus_string_get_const_data (&address), error);
300  if (result == NULL)
301  _DBUS_ASSERT_ERROR_IS_SET (error);
302  else
303  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
304 
305  out:
306  _dbus_string_free (&address);
307  return result;
308 }
309 
310 static DBusTransportOpenResult
311 _dbus_transport_open_autolaunch (DBusAddressEntry *entry,
312  DBusTransport **transport_p,
313  DBusError *error)
314 {
315  const char *method;
316 
317  method = dbus_address_entry_get_method (entry);
318  _dbus_assert (method != NULL);
319 
320  if (strcmp (method, "autolaunch") == 0)
321  {
322  const char *scope = dbus_address_entry_get_value (entry, "scope");
323 
324  *transport_p = _dbus_transport_new_for_autolaunch (scope, error);
325 
326  if (*transport_p == NULL)
327  {
328  _DBUS_ASSERT_ERROR_IS_SET (error);
329  return DBUS_TRANSPORT_OPEN_DID_NOT_CONNECT;
330  }
331  else
332  {
333  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
334  return DBUS_TRANSPORT_OPEN_OK;
335  }
336  }
337  else
338  {
339  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
340  return DBUS_TRANSPORT_OPEN_NOT_HANDLED;
341  }
342 }
343 
344 static const struct {
345  DBusTransportOpenResult (* func) (DBusAddressEntry *entry,
346  DBusTransport **transport_p,
347  DBusError *error);
348 } open_funcs[] = {
351  { _dbus_transport_open_autolaunch }
352 #ifdef DBUS_BUILD_TESTS
353  , { _dbus_transport_open_debug_pipe }
354 #endif
355 };
356 
367  DBusError *error)
368 {
369  DBusTransport *transport;
370  const char *expected_guid_orig;
371  char *expected_guid;
372  int i;
373  DBusError tmp_error = DBUS_ERROR_INIT;
374 
375  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
376 
377  transport = NULL;
378  expected_guid_orig = dbus_address_entry_get_value (entry, "guid");
379  expected_guid = _dbus_strdup (expected_guid_orig);
380 
381  if (expected_guid_orig != NULL && expected_guid == NULL)
382  {
383  _DBUS_SET_OOM (error);
384  return NULL;
385  }
386 
387  for (i = 0; i < (int) _DBUS_N_ELEMENTS (open_funcs); ++i)
388  {
389  DBusTransportOpenResult result;
390 
391  _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error);
392  result = (* open_funcs[i].func) (entry, &transport, &tmp_error);
393 
394  switch (result)
395  {
396  case DBUS_TRANSPORT_OPEN_OK:
397  _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error);
398  goto out;
399  break;
400  case DBUS_TRANSPORT_OPEN_NOT_HANDLED:
401  _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error);
402  /* keep going through the loop of open funcs */
403  break;
404  case DBUS_TRANSPORT_OPEN_BAD_ADDRESS:
405  _DBUS_ASSERT_ERROR_IS_SET (&tmp_error);
406  goto out;
407  break;
408  case DBUS_TRANSPORT_OPEN_DID_NOT_CONNECT:
409  _DBUS_ASSERT_ERROR_IS_SET (&tmp_error);
410  goto out;
411  break;
412  }
413  }
414 
415  out:
416 
417  if (transport == NULL)
418  {
419  if (!dbus_error_is_set (&tmp_error))
420  _dbus_set_bad_address (&tmp_error,
421  NULL, NULL,
422  "Unknown address type (examples of valid types are \"tcp\" and on UNIX \"unix\")");
423 
424  _DBUS_ASSERT_ERROR_IS_SET (&tmp_error);
425  dbus_move_error(&tmp_error, error);
426  dbus_free (expected_guid);
427  }
428  else
429  {
430  _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error);
431 
432  /* In the case of autostart the initial guid is NULL
433  * and the autostart transport recursively calls
434  * _dbus_open_transport wich returns a transport
435  * with a guid. That guid is the definitive one.
436  *
437  * FIXME: if more transports are added they may have
438  * an effect on the expected_guid semantics (i.e.
439  * expected_guid and transport->expected_guid may
440  * both have values). This is very unlikely though
441  * we should either throw asserts here for those
442  * corner cases or refactor the code so it is
443  * clearer on what is expected and what is not
444  */
445  if(expected_guid)
446  transport->expected_guid = expected_guid;
447  }
448 
449  return transport;
450 }
451 
460 {
461  _dbus_assert (transport->refcount > 0);
462 
463  transport->refcount += 1;
464 
465  return transport;
466 }
467 
475 void
477 {
478  _dbus_assert (transport != NULL);
479  _dbus_assert (transport->refcount > 0);
480 
481  transport->refcount -= 1;
482  if (transport->refcount == 0)
483  {
484  _dbus_verbose ("finalizing\n");
485 
486  _dbus_assert (transport->vtable->finalize != NULL);
487 
488  (* transport->vtable->finalize) (transport);
489  }
490 }
491 
500 void
502 {
503  _dbus_verbose ("start\n");
504 
505  _dbus_assert (transport->vtable->disconnect != NULL);
506 
507  if (transport->disconnected)
508  return;
509 
510  (* transport->vtable->disconnect) (transport);
511 
512  transport->disconnected = TRUE;
513 
514  _dbus_verbose ("end\n");
515 }
516 
527 {
528  return !transport->disconnected;
529 }
530 
531 static dbus_bool_t
532 auth_via_unix_user_function (DBusTransport *transport)
533 {
534  DBusCredentials *auth_identity;
535  dbus_bool_t allow;
536  DBusConnection *connection;
537  DBusAllowUnixUserFunction unix_user_function;
538  void *unix_user_data;
539  dbus_uid_t uid;
540 
541  /* Dropping the lock here probably isn't that safe. */
542 
543  auth_identity = _dbus_auth_get_identity (transport->auth);
544  _dbus_assert (auth_identity != NULL);
545 
546  connection = transport->connection;
547  unix_user_function = transport->unix_user_function;
548  unix_user_data = transport->unix_user_data;
549  uid = _dbus_credentials_get_unix_uid (auth_identity);
550 
551  _dbus_verbose ("unlock\n");
552  _dbus_connection_unlock (connection);
553 
554  allow = (* unix_user_function) (connection,
555  uid,
556  unix_user_data);
557 
558  _dbus_verbose ("lock post unix user function\n");
559  _dbus_connection_lock (connection);
560 
561  if (allow)
562  {
563  _dbus_verbose ("Client UID "DBUS_UID_FORMAT" authorized\n", uid);
564  }
565  else
566  {
567  _dbus_verbose ("Client UID "DBUS_UID_FORMAT
568  " was rejected, disconnecting\n",
569  _dbus_credentials_get_unix_uid (auth_identity));
570  _dbus_transport_disconnect (transport);
571  }
572 
573  return allow;
574 }
575 
576 static dbus_bool_t
577 auth_via_windows_user_function (DBusTransport *transport)
578 {
579  DBusCredentials *auth_identity;
580  dbus_bool_t allow;
581  DBusConnection *connection;
582  DBusAllowWindowsUserFunction windows_user_function;
583  void *windows_user_data;
584  char *windows_sid;
585 
586  /* Dropping the lock here probably isn't that safe. */
587 
588  auth_identity = _dbus_auth_get_identity (transport->auth);
589  _dbus_assert (auth_identity != NULL);
590 
591  connection = transport->connection;
592  windows_user_function = transport->windows_user_function;
593  windows_user_data = transport->unix_user_data;
594  windows_sid = _dbus_strdup (_dbus_credentials_get_windows_sid (auth_identity));
595 
596  if (windows_sid == NULL)
597  {
598  /* OOM */
599  return FALSE;
600  }
601 
602  _dbus_verbose ("unlock\n");
603  _dbus_connection_unlock (connection);
604 
605  allow = (* windows_user_function) (connection,
606  windows_sid,
607  windows_user_data);
608 
609  _dbus_verbose ("lock post windows user function\n");
610  _dbus_connection_lock (connection);
611 
612  if (allow)
613  {
614  _dbus_verbose ("Client SID '%s' authorized\n", windows_sid);
615  }
616  else
617  {
618  _dbus_verbose ("Client SID '%s' was rejected, disconnecting\n",
619  _dbus_credentials_get_windows_sid (auth_identity));
620  _dbus_transport_disconnect (transport);
621  }
622 
623  return allow;
624 }
625 
626 static dbus_bool_t
627 auth_via_default_rules (DBusTransport *transport)
628 {
629  DBusCredentials *auth_identity;
630  DBusCredentials *our_identity;
631  dbus_bool_t allow;
632 
633  auth_identity = _dbus_auth_get_identity (transport->auth);
634  _dbus_assert (auth_identity != NULL);
635 
636  /* By default, connection is allowed if the client is 1) root or 2)
637  * has the same UID as us or 3) anonymous is allowed.
638  */
639 
641  if (our_identity == NULL)
642  {
643  /* OOM */
644  return FALSE;
645  }
646 
647  if (transport->allow_anonymous ||
648  _dbus_credentials_get_unix_uid (auth_identity) == 0 ||
649  _dbus_credentials_same_user (our_identity,
650  auth_identity))
651  {
652  if (_dbus_credentials_include(our_identity,DBUS_CREDENTIAL_WINDOWS_SID))
653  _dbus_verbose ("Client authorized as SID '%s'"
654  "matching our SID '%s'\n",
655  _dbus_credentials_get_windows_sid(auth_identity),
656  _dbus_credentials_get_windows_sid(our_identity));
657  else
658  _dbus_verbose ("Client authorized as UID "DBUS_UID_FORMAT
659  " matching our UID "DBUS_UID_FORMAT"\n",
660  _dbus_credentials_get_unix_uid(auth_identity),
661  _dbus_credentials_get_unix_uid(our_identity));
662  /* We have authenticated! */
663  allow = TRUE;
664  }
665  else
666  {
667  if (_dbus_credentials_include(our_identity,DBUS_CREDENTIAL_WINDOWS_SID))
668  _dbus_verbose ("Client authorized as SID '%s'"
669  " but our SID is '%s', disconnecting\n",
670  (_dbus_credentials_get_windows_sid(auth_identity) ?
671  _dbus_credentials_get_windows_sid(auth_identity) : "<null>"),
672  (_dbus_credentials_get_windows_sid(our_identity) ?
673  _dbus_credentials_get_windows_sid(our_identity) : "<null>"));
674  else
675  _dbus_verbose ("Client authorized as UID "DBUS_UID_FORMAT
676  " but our UID is "DBUS_UID_FORMAT", disconnecting\n",
677  _dbus_credentials_get_unix_uid(auth_identity),
678  _dbus_credentials_get_unix_uid(our_identity));
679  _dbus_transport_disconnect (transport);
680  allow = FALSE;
681  }
682 
683  _dbus_credentials_unref (our_identity);
684 
685  return allow;
686 }
687 
688 
701 {
702  if (transport->authenticated)
703  return TRUE;
704  else
705  {
706  dbus_bool_t maybe_authenticated;
707 
708  if (transport->disconnected)
709  return FALSE;
710 
711  /* paranoia ref since we call user callbacks sometimes */
713 
714  maybe_authenticated =
715  (!(transport->send_credentials_pending ||
716  transport->receive_credentials_pending));
717 
718  if (maybe_authenticated)
719  {
720  switch (_dbus_auth_do_work (transport->auth))
721  {
722  case DBUS_AUTH_STATE_AUTHENTICATED:
723  /* leave as maybe_authenticated */
724  break;
725  default:
726  maybe_authenticated = FALSE;
727  }
728  }
729 
730  /* If we're the client, verify the GUID
731  */
732  if (maybe_authenticated && !transport->is_server)
733  {
734  const char *server_guid;
735 
736  server_guid = _dbus_auth_get_guid_from_server (transport->auth);
737  _dbus_assert (server_guid != NULL);
738 
739  if (transport->expected_guid &&
740  strcmp (transport->expected_guid, server_guid) != 0)
741  {
742  _dbus_verbose ("Client expected GUID '%s' and we got '%s' from the server\n",
743  transport->expected_guid, server_guid);
744  _dbus_transport_disconnect (transport);
746  return FALSE;
747  }
748  }
749 
750  /* If we're the server, see if we want to allow this identity to proceed.
751  */
752  if (maybe_authenticated && transport->is_server)
753  {
754  dbus_bool_t allow;
755  DBusCredentials *auth_identity;
756 
757  auth_identity = _dbus_auth_get_identity (transport->auth);
758  _dbus_assert (auth_identity != NULL);
759 
760  /* If we have an auth'd user and a user function, delegate
761  * deciding whether auth credentials are good enough to the
762  * app; otherwise, use our default decision process.
763  */
764  if (transport->unix_user_function != NULL &&
765  _dbus_credentials_include (auth_identity, DBUS_CREDENTIAL_UNIX_USER_ID))
766  {
767  allow = auth_via_unix_user_function (transport);
768  }
769  else if (transport->windows_user_function != NULL &&
770  _dbus_credentials_include (auth_identity, DBUS_CREDENTIAL_WINDOWS_SID))
771  {
772  allow = auth_via_windows_user_function (transport);
773  }
774  else
775  {
776  allow = auth_via_default_rules (transport);
777  }
778 
779  if (!allow)
780  maybe_authenticated = FALSE;
781  }
782 
783  transport->authenticated = maybe_authenticated;
784 
786  return maybe_authenticated;
787  }
788 }
789 
798 {
799  DBusCredentials *auth_identity;
800 
801  if (!transport->authenticated)
802  return TRUE;
803 
804  auth_identity = _dbus_auth_get_identity (transport->auth);
805 
806  if (_dbus_credentials_are_anonymous (auth_identity))
807  return TRUE;
808  else
809  return FALSE;
810 }
811 
820 {
821  return DBUS_TRANSPORT_CAN_SEND_UNIX_FD(transport);
822 }
823 
831 const char*
833 {
834  return transport->address;
835 }
836 
844 const char*
846 {
847  if (transport->is_server)
848  return NULL;
849  else if (transport->authenticated)
850  return _dbus_auth_get_guid_from_server (transport->auth);
851  else
852  return transport->expected_guid;
853 }
854 
866  DBusWatch *watch,
867  unsigned int condition)
868 {
869  dbus_bool_t retval;
870 
871  _dbus_assert (transport->vtable->handle_watch != NULL);
872 
873  if (transport->disconnected)
874  return TRUE;
875 
876  if (dbus_watch_get_socket (watch) < 0)
877  {
878  _dbus_warn_check_failed ("Tried to handle an invalidated watch; this watch should have been removed\n");
879  return TRUE;
880  }
881 
882  _dbus_watch_sanitize_condition (watch, &condition);
883 
884  _dbus_transport_ref (transport);
885  _dbus_watch_ref (watch);
886  retval = (* transport->vtable->handle_watch) (transport, watch, condition);
887  _dbus_watch_unref (watch);
888  _dbus_transport_unref (transport);
889 
890  return retval;
891 }
892 
904  DBusConnection *connection)
905 {
906  _dbus_assert (transport->vtable->connection_set != NULL);
907  _dbus_assert (transport->connection == NULL);
908 
909  transport->connection = connection;
910 
911  _dbus_transport_ref (transport);
912  if (!(* transport->vtable->connection_set) (transport))
913  transport->connection = NULL;
914  _dbus_transport_unref (transport);
915 
916  return transport->connection != NULL;
917 }
918 
928  int *fd_p)
929 {
930  dbus_bool_t retval;
931 
932  if (transport->vtable->get_socket_fd == NULL)
933  return FALSE;
934 
935  if (transport->disconnected)
936  return FALSE;
937 
938  _dbus_transport_ref (transport);
939 
940  retval = (* transport->vtable->get_socket_fd) (transport,
941  fd_p);
942 
943  _dbus_transport_unref (transport);
944 
945  return retval;
946 }
947 
959 void
961  unsigned int flags,
962  int timeout_milliseconds)
963 {
964  _dbus_assert (transport->vtable->do_iteration != NULL);
965 
966  _dbus_verbose ("Transport iteration flags 0x%x timeout %d connected = %d\n",
967  flags, timeout_milliseconds, !transport->disconnected);
968 
969  if ((flags & (DBUS_ITERATION_DO_WRITING |
970  DBUS_ITERATION_DO_READING)) == 0)
971  return; /* Nothing to do */
972 
973  if (transport->disconnected)
974  return;
975 
976  _dbus_transport_ref (transport);
977  (* transport->vtable->do_iteration) (transport, flags,
978  timeout_milliseconds);
979  _dbus_transport_unref (transport);
980 
981  _dbus_verbose ("end\n");
982 }
983 
984 static dbus_bool_t
985 recover_unused_bytes (DBusTransport *transport)
986 {
987  if (_dbus_auth_needs_decoding (transport->auth))
988  {
989  DBusString plaintext;
990  const DBusString *encoded;
991  DBusString *buffer;
992  int orig_len;
993 
994  if (!_dbus_string_init (&plaintext))
995  goto nomem;
996 
997  _dbus_auth_get_unused_bytes (transport->auth,
998  &encoded);
999 
1000  if (!_dbus_auth_decode_data (transport->auth,
1001  encoded, &plaintext))
1002  {
1003  _dbus_string_free (&plaintext);
1004  goto nomem;
1005  }
1006 
1008  &buffer);
1009 
1010  orig_len = _dbus_string_get_length (buffer);
1011 
1012  if (!_dbus_string_move (&plaintext, 0, buffer,
1013  orig_len))
1014  {
1015  _dbus_string_free (&plaintext);
1016  goto nomem;
1017  }
1018 
1019  _dbus_verbose (" %d unused bytes sent to message loader\n",
1020  _dbus_string_get_length (buffer) -
1021  orig_len);
1022 
1024  buffer,
1025  _dbus_string_get_length (buffer) -
1026  orig_len);
1027 
1028  _dbus_auth_delete_unused_bytes (transport->auth);
1029 
1030  _dbus_string_free (&plaintext);
1031  }
1032  else
1033  {
1034  const DBusString *bytes;
1035  DBusString *buffer;
1036  int orig_len;
1037  dbus_bool_t succeeded;
1038 
1040  &buffer);
1041 
1042  orig_len = _dbus_string_get_length (buffer);
1043 
1044  _dbus_auth_get_unused_bytes (transport->auth,
1045  &bytes);
1046 
1047  succeeded = TRUE;
1048  if (!_dbus_string_copy (bytes, 0, buffer, _dbus_string_get_length (buffer)))
1049  succeeded = FALSE;
1050 
1051  _dbus_verbose (" %d unused bytes sent to message loader\n",
1052  _dbus_string_get_length (buffer) -
1053  orig_len);
1054 
1056  buffer,
1057  _dbus_string_get_length (buffer) -
1058  orig_len);
1059 
1060  if (succeeded)
1061  _dbus_auth_delete_unused_bytes (transport->auth);
1062  else
1063  goto nomem;
1064  }
1065 
1066  return TRUE;
1067 
1068  nomem:
1069  _dbus_verbose ("Not enough memory to transfer unused bytes from auth conversation\n");
1070  return FALSE;
1071 }
1072 
1082 {
1083  if (_dbus_counter_get_size_value (transport->live_messages) >= transport->max_live_messages_size ||
1085  return DBUS_DISPATCH_COMPLETE; /* complete for now */
1086 
1087  if (!_dbus_transport_get_is_authenticated (transport))
1088  {
1089  if (_dbus_auth_do_work (transport->auth) ==
1090  DBUS_AUTH_STATE_WAITING_FOR_MEMORY)
1092  else if (!_dbus_transport_get_is_authenticated (transport))
1093  return DBUS_DISPATCH_COMPLETE;
1094  }
1095 
1096  if (!transport->unused_bytes_recovered &&
1097  !recover_unused_bytes (transport))
1099 
1100  transport->unused_bytes_recovered = TRUE;
1101 
1102  if (!_dbus_message_loader_queue_messages (transport->loader))
1104 
1105  if (_dbus_message_loader_peek_message (transport->loader) != NULL)
1107  else
1108  return DBUS_DISPATCH_COMPLETE;
1109 }
1110 
1121 {
1122  DBusDispatchStatus status;
1123 
1124 #if 0
1125  _dbus_verbose ("_dbus_transport_queue_messages()\n");
1126 #endif
1127 
1128  /* Queue any messages */
1129  while ((status = _dbus_transport_get_dispatch_status (transport)) == DBUS_DISPATCH_DATA_REMAINS)
1130  {
1131  DBusMessage *message;
1132  DBusList *link;
1133 
1134  link = _dbus_message_loader_pop_message_link (transport->loader);
1135  _dbus_assert (link != NULL);
1136 
1137  message = link->data;
1138 
1139  _dbus_verbose ("queueing received message %p\n", message);
1140 
1141  if (!_dbus_message_add_counter (message, transport->live_messages))
1142  {
1144  link);
1145  status = DBUS_DISPATCH_NEED_MEMORY;
1146  break;
1147  }
1148  else
1149  {
1150  /* We didn't call the notify function when we added the counter, so
1151  * catch up now. Since we have the connection's lock, it's desirable
1152  * that we bypass the notify function and call this virtual method
1153  * directly. */
1154  if (transport->vtable->live_messages_changed)
1155  (* transport->vtable->live_messages_changed) (transport);
1156 
1157  /* pass ownership of link and message ref to connection */
1159  link);
1160  }
1161  }
1162 
1164  {
1165  _dbus_verbose ("Corrupted message stream, disconnecting\n");
1166  _dbus_transport_disconnect (transport);
1167  }
1168 
1169  return status != DBUS_DISPATCH_NEED_MEMORY;
1170 }
1171 
1178 void
1180  long size)
1181 {
1183 }
1184 
1191 void
1193  long n)
1194 {
1196 }
1197 
1204 long
1206 {
1208 }
1209 
1216 long
1218 {
1220 }
1221 
1228 void
1230  long size)
1231 {
1232  transport->max_live_messages_size = size;
1234  transport->max_live_messages_size,
1235  transport->max_live_messages_unix_fds,
1236  live_messages_notify,
1237  transport);
1238 }
1239 
1246 void
1248  long n)
1249 {
1250  transport->max_live_messages_unix_fds = n;
1252  transport->max_live_messages_size,
1253  transport->max_live_messages_unix_fds,
1254  live_messages_notify,
1255  transport);
1256 }
1257 
1264 long
1266 {
1267  return transport->max_live_messages_size;
1268 }
1269 
1276 long
1278 {
1279  return transport->max_live_messages_unix_fds;
1280 }
1281 
1291  unsigned long *uid)
1292 {
1293  DBusCredentials *auth_identity;
1294 
1295  *uid = _DBUS_INT32_MAX; /* better than some root or system user in
1296  * case of bugs in the caller. Caller should
1297  * never use this value on purpose, however.
1298  */
1299 
1300  if (!transport->authenticated)
1301  return FALSE;
1302 
1303  auth_identity = _dbus_auth_get_identity (transport->auth);
1304 
1305  if (_dbus_credentials_include (auth_identity,
1306  DBUS_CREDENTIAL_UNIX_USER_ID))
1307  {
1308  *uid = _dbus_credentials_get_unix_uid (auth_identity);
1309  return TRUE;
1310  }
1311  else
1312  return FALSE;
1313 }
1314 
1324  unsigned long *pid)
1325 {
1326  DBusCredentials *auth_identity;
1327 
1328  *pid = DBUS_PID_UNSET; /* Caller should never use this value on purpose,
1329  * but we set it to a safe number, INT_MAX,
1330  * just to root out possible bugs in bad callers.
1331  */
1332 
1333  if (!transport->authenticated)
1334  return FALSE;
1335 
1336  auth_identity = _dbus_auth_get_identity (transport->auth);
1337 
1338  if (_dbus_credentials_include (auth_identity,
1339  DBUS_CREDENTIAL_UNIX_PROCESS_ID))
1340  {
1341  *pid = _dbus_credentials_get_unix_pid (auth_identity);
1342  return TRUE;
1343  }
1344  else
1345  return FALSE;
1346 }
1347 
1358  void **data,
1359  int *data_size)
1360 {
1361  DBusCredentials *auth_identity;
1362 
1363  *data = NULL;
1364  *data_size = 0;
1365 
1366  if (!transport->authenticated)
1367  return FALSE;
1368 
1369  auth_identity = _dbus_auth_get_identity (transport->auth);
1370 
1371  if (_dbus_credentials_include (auth_identity,
1372  DBUS_CREDENTIAL_ADT_AUDIT_DATA_ID))
1373  {
1374  *data = (void *) _dbus_credentials_get_adt_audit_data (auth_identity);
1375  *data_size = _dbus_credentials_get_adt_audit_data_size (auth_identity);
1376  return TRUE;
1377  }
1378  else
1379  return FALSE;
1380 }
1381 
1392 void
1394  DBusAllowUnixUserFunction function,
1395  void *data,
1396  DBusFreeFunction free_data_function,
1397  void **old_data,
1398  DBusFreeFunction *old_free_data_function)
1399 {
1400  *old_data = transport->unix_user_data;
1401  *old_free_data_function = transport->free_unix_user_data;
1402 
1403  transport->unix_user_function = function;
1404  transport->unix_user_data = data;
1405  transport->free_unix_user_data = free_data_function;
1406 }
1407 
1417  char **windows_sid_p)
1418 {
1419  DBusCredentials *auth_identity;
1420 
1421  *windows_sid_p = NULL;
1422 
1423  if (!transport->authenticated)
1424  return FALSE;
1425 
1426  auth_identity = _dbus_auth_get_identity (transport->auth);
1427 
1428  if (_dbus_credentials_include (auth_identity,
1429  DBUS_CREDENTIAL_WINDOWS_SID))
1430  {
1431  /* If no memory, we are supposed to return TRUE and set NULL */
1432  *windows_sid_p = _dbus_strdup (_dbus_credentials_get_windows_sid (auth_identity));
1433 
1434  return TRUE;
1435  }
1436  else
1437  return FALSE;
1438 }
1439 
1451 void
1454  void *data,
1455  DBusFreeFunction free_data_function,
1456  void **old_data,
1457  DBusFreeFunction *old_free_data_function)
1458 {
1459  *old_data = transport->windows_user_data;
1460  *old_free_data_function = transport->free_windows_user_data;
1461 
1462  transport->windows_user_function = function;
1463  transport->windows_user_data = data;
1464  transport->free_windows_user_data = free_data_function;
1465 }
1466 
1477  const char **mechanisms)
1478 {
1479  return _dbus_auth_set_mechanisms (transport->auth, mechanisms);
1480 }
1481 
1488 void
1490  dbus_bool_t value)
1491 {
1492  transport->allow_anonymous = value != FALSE;
1493 }
1494 
1495 #ifdef DBUS_ENABLE_STATS
1496 void
1497 _dbus_transport_get_stats (DBusTransport *transport,
1498  dbus_uint32_t *queue_bytes,
1499  dbus_uint32_t *queue_fds,
1500  dbus_uint32_t *peak_queue_bytes,
1501  dbus_uint32_t *peak_queue_fds)
1502 {
1503  if (queue_bytes != NULL)
1504  *queue_bytes = _dbus_counter_get_size_value (transport->live_messages);
1505 
1506  if (queue_fds != NULL)
1507  *queue_fds = _dbus_counter_get_unix_fd_value (transport->live_messages);
1508 
1509  if (peak_queue_bytes != NULL)
1510  *peak_queue_bytes = _dbus_counter_get_peak_size_value (transport->live_messages);
1511 
1512  if (peak_queue_fds != NULL)
1513  *peak_queue_fds = _dbus_counter_get_peak_unix_fd_value (transport->live_messages);
1514 }
1515 #endif /* DBUS_ENABLE_STATS */
1516