hook gvariant vectors up to kdbus
[platform/upstream/glib.git] / gio / gdbusauth.c
index 2d47060..a29f97e 100644 (file)
@@ -1,6 +1,6 @@
 /* GDBus - GLib D-Bus Library
  *
- * Copyright (C) 2008-2009 Red Hat, Inc.
+ * Copyright (C) 2008-2010 Red Hat, Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General
- * Public License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
- * Boston, MA 02111-1307, USA.
+ * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
  *
  * Author: David Zeuthen <davidz@redhat.com>
  */
 
 #include "config.h"
 
-#include <glib/gi18n.h>
-
 #include "gdbusauth.h"
+
 #include "gdbusauthmechanismanon.h"
 #include "gdbusauthmechanismexternal.h"
 #include "gdbusauthmechanismsha1.h"
-
 #include "gdbusauthobserver.h"
 
 #include "gdbuserror.h"
 #include "gioenumtypes.h"
 #include "gcredentials.h"
 #include "gdbusprivate.h"
+#include "giostream.h"
+#include "gdatainputstream.h"
+#include "gdataoutputstream.h"
 
 #ifdef G_OS_UNIX
-#include <gio/gunixconnection.h>
+#include "gnetworking.h"
+#include "gunixconnection.h"
 #include "gunixcredentialsmessage.h"
-#include <sys/types.h>
-#include <sys/socket.h>
 #endif
 
-#define DEBUG_ENABLED 1
+#include "glibintl.h"
 
+G_GNUC_PRINTF(1, 2)
 static void
 debug_print (const gchar *message, ...)
 {
-#if DEBUG_ENABLED
   if (G_UNLIKELY (_g_dbus_debug_authentication ()))
     {
       gchar *s;
@@ -57,6 +55,8 @@ debug_print (const gchar *message, ...)
       va_list var_args;
       guint n;
 
+      _g_dbus_debug_print_lock ();
+
       va_start (var_args, message);
       s = g_strdup_vprintf (message, var_args);
       va_end (var_args);
@@ -74,8 +74,9 @@ debug_print (const gchar *message, ...)
       g_print ("GDBus-debug:Auth: %s\n", str->str);
       g_string_free (str, TRUE);
       g_free (s);
+
+      _g_dbus_debug_print_unlock ();
     }
-#endif
 }
 
 typedef struct
@@ -101,7 +102,7 @@ enum
   PROP_STREAM
 };
 
-G_DEFINE_TYPE (GDBusAuth, _g_dbus_auth, G_TYPE_OBJECT);
+G_DEFINE_TYPE_WITH_PRIVATE (GDBusAuth, _g_dbus_auth, G_TYPE_OBJECT)
 
 /* ---------------------------------------------------------------------------------------------------- */
 
@@ -112,8 +113,7 @@ _g_dbus_auth_finalize (GObject *object)
 
   if (auth->priv->stream != NULL)
     g_object_unref (auth->priv->stream);
-  g_list_foreach (auth->priv->available_mechanisms, (GFunc) mechanism_free, NULL);
-  g_list_free (auth->priv->available_mechanisms);
+  g_list_free_full (auth->priv->available_mechanisms, (GDestroyNotify) mechanism_free);
 
   if (G_OBJECT_CLASS (_g_dbus_auth_parent_class)->finalize != NULL)
     G_OBJECT_CLASS (_g_dbus_auth_parent_class)->finalize (object);
@@ -164,8 +164,6 @@ _g_dbus_auth_class_init (GDBusAuthClass *klass)
 {
   GObjectClass *gobject_class;
 
-  g_type_class_add_private (klass, sizeof (GDBusAuthPrivate));
-
   gobject_class = G_OBJECT_CLASS (klass);
   gobject_class->get_property = _g_dbus_auth_get_property;
   gobject_class->set_property = _g_dbus_auth_set_property;
@@ -174,8 +172,8 @@ _g_dbus_auth_class_init (GDBusAuthClass *klass)
   g_object_class_install_property (gobject_class,
                                    PROP_STREAM,
                                    g_param_spec_object ("stream",
-                                                        _("IO Stream"),
-                                                        _("The underlying GIOStream used for I/O"),
+                                                        P_("IO Stream"),
+                                                        P_("The underlying GIOStream used for I/O"),
                                                         G_TYPE_IO_STREAM,
                                                         G_PARAM_READABLE |
                                                         G_PARAM_WRITABLE |
@@ -192,17 +190,22 @@ mechanism_free (Mechanism *m)
 }
 
 static void
-add_mechanism (GDBusAuth *auth,
-               GType      mechanism_type)
+add_mechanism (GDBusAuth         *auth,
+               GDBusAuthObserver *observer,
+               GType              mechanism_type)
 {
-  Mechanism *m;
-
-  m = g_new0 (Mechanism, 1);
-  m->name = _g_dbus_auth_mechanism_get_name (mechanism_type);
-  m->priority = _g_dbus_auth_mechanism_get_priority (mechanism_type);
-  m->gtype = mechanism_type;
+  const gchar *name;
 
-  auth->priv->available_mechanisms = g_list_prepend (auth->priv->available_mechanisms, m);
+  name = _g_dbus_auth_mechanism_get_name (mechanism_type);
+  if (observer == NULL || g_dbus_auth_observer_allow_mechanism (observer, name))
+    {
+      Mechanism *m;
+      m = g_new0 (Mechanism, 1);
+      m->name = name;
+      m->priority = _g_dbus_auth_mechanism_get_priority (mechanism_type);
+      m->gtype = mechanism_type;
+      auth->priv->available_mechanisms = g_list_prepend (auth->priv->available_mechanisms, m);
+    }
 }
 
 static gint
@@ -219,12 +222,17 @@ mech_compare_func (Mechanism *a, Mechanism *b)
 static void
 _g_dbus_auth_init (GDBusAuth *auth)
 {
-  auth->priv = G_TYPE_INSTANCE_GET_PRIVATE (auth, G_TYPE_DBUS_AUTH, GDBusAuthPrivate);
+  auth->priv = _g_dbus_auth_get_instance_private (auth);
+}
 
+static void
+_g_dbus_auth_add_mechs (GDBusAuth         *auth,
+                        GDBusAuthObserver *observer)
+{
   /* TODO: trawl extension points */
-  add_mechanism (auth, G_TYPE_DBUS_AUTH_MECHANISM_ANON);
-  add_mechanism (auth, G_TYPE_DBUS_AUTH_MECHANISM_SHA1);
-  add_mechanism (auth, G_TYPE_DBUS_AUTH_MECHANISM_EXTERNAL);
+  add_mechanism (auth, observer, G_TYPE_DBUS_AUTH_MECHANISM_ANON);
+  add_mechanism (auth, observer, G_TYPE_DBUS_AUTH_MECHANISM_SHA1);
+  add_mechanism (auth, observer, G_TYPE_DBUS_AUTH_MECHANISM_EXTERNAL);
 
   auth->priv->available_mechanisms = g_list_sort (auth->priv->available_mechanisms,
                                                   (GCompareFunc) mech_compare_func);
@@ -388,7 +396,7 @@ hexdecode (const gchar  *str,
           g_set_error (error,
                        G_IO_ERROR,
                        G_IO_ERROR_FAILED,
-                       "Error hexdecoding string `%s' around position %d",
+                       "Error hexdecoding string '%s' around position %d",
                        str, n);
           goto out;
         }
@@ -510,7 +518,7 @@ client_choose_mech_and_send_initial_response (GDBusAuth           *auth,
                        "stream", auth->priv->stream,
                        "credentials", credentials_that_were_sent,
                        NULL);
-  debug_print ("CLIENT: Trying mechanism `%s'", _g_dbus_auth_mechanism_get_name (auth_mech_to_use_gtype));
+  debug_print ("CLIENT: Trying mechanism '%s'", _g_dbus_auth_mechanism_get_name (auth_mech_to_use_gtype));
   g_ptr_array_add (attempted_auth_mechs, (gpointer) _g_dbus_auth_mechanism_get_name (auth_mech_to_use_gtype));
 
   /* the auth mechanism may not be supported
@@ -518,7 +526,7 @@ client_choose_mech_and_send_initial_response (GDBusAuth           *auth,
    */
   if (!_g_dbus_auth_mechanism_is_supported (mech))
     {
-      debug_print ("CLIENT: Mechanism `%s' says it is not supported", _g_dbus_auth_mechanism_get_name (auth_mech_to_use_gtype));
+      debug_print ("CLIENT: Mechanism '%s' says it is not supported", _g_dbus_auth_mechanism_get_name (auth_mech_to_use_gtype));
       g_object_unref (mech);
       mech = NULL;
       goto again;
@@ -528,14 +536,14 @@ client_choose_mech_and_send_initial_response (GDBusAuth           *auth,
   initial_response = _g_dbus_auth_mechanism_client_initiate (mech,
                                                              &initial_response_len);
 #if 0
-  g_printerr ("using auth mechanism with name `%s' of type `%s' with initial response `%s'\n",
+  g_printerr ("using auth mechanism with name '%s' of type '%s' with initial response '%s'\n",
               _g_dbus_auth_mechanism_get_name (auth_mech_to_use_gtype),
               g_type_name (G_TYPE_FROM_INSTANCE (mech)),
               initial_response);
 #endif
   if (initial_response != NULL)
     {
-      //g_printerr ("initial_response = `%s'\n", initial_response);
+      //g_printerr ("initial_response = '%s'\n", initial_response);
       encoded = hexencode (initial_response);
       s = g_strdup_printf ("AUTH %s %s\r\n",
                            _g_dbus_auth_mechanism_get_name (auth_mech_to_use_gtype),
@@ -547,7 +555,7 @@ client_choose_mech_and_send_initial_response (GDBusAuth           *auth,
     {
       s = g_strdup_printf ("AUTH %s\r\n", _g_dbus_auth_mechanism_get_name (auth_mech_to_use_gtype));
     }
-  debug_print ("CLIENT: writing `%s'", s);
+  debug_print ("CLIENT: writing '%s'", s);
   if (!g_data_output_stream_put_string (dos, s, cancellable, error))
     {
       g_object_unref (mech);
@@ -574,6 +582,7 @@ typedef enum
 
 gchar *
 _g_dbus_auth_run_client (GDBusAuth     *auth,
+                         GDBusAuthObserver     *observer,
                          GDBusCapabilityFlags offered_capabilities,
                          GDBusCapabilityFlags *out_negotiated_capabilities,
                          GCancellable  *cancellable,
@@ -594,6 +603,8 @@ _g_dbus_auth_run_client (GDBusAuth     *auth,
 
   debug_print ("CLIENT: initiating");
 
+  _g_dbus_auth_add_mechs (auth, observer);
+
   ret_guid = NULL;
   supported_auth_mechs = NULL;
   attempted_auth_mechs = g_ptr_array_new ();
@@ -603,15 +614,16 @@ _g_dbus_auth_run_client (GDBusAuth     *auth,
 
   dis = G_DATA_INPUT_STREAM (g_data_input_stream_new (g_io_stream_get_input_stream (auth->priv->stream)));
   dos = G_DATA_OUTPUT_STREAM (g_data_output_stream_new (g_io_stream_get_output_stream (auth->priv->stream)));
+  g_filter_input_stream_set_close_base_stream (G_FILTER_INPUT_STREAM (dis), FALSE);
+  g_filter_output_stream_set_close_base_stream (G_FILTER_OUTPUT_STREAM (dos), FALSE);
 
   g_data_input_stream_set_newline_type (dis, G_DATA_STREAM_NEWLINE_TYPE_CR_LF);
 
 #ifdef G_OS_UNIX
-  if (G_IS_UNIX_CONNECTION (auth->priv->stream) && g_unix_credentials_message_is_supported ())
+  if (G_IS_UNIX_CONNECTION (auth->priv->stream))
     {
-      credentials = g_credentials_new_for_process ();
+      credentials = g_credentials_new ();
       if (!g_unix_connection_send_credentials (G_UNIX_CONNECTION (auth->priv->stream),
-                                               credentials,
                                                cancellable,
                                                error))
         goto out;
@@ -631,7 +643,7 @@ _g_dbus_auth_run_client (GDBusAuth     *auth,
       if (G_UNLIKELY (_g_dbus_debug_authentication ()))
         {
           s = g_credentials_to_string (credentials);
-          debug_print ("CLIENT: sent credentials `%s'", s);
+          debug_print ("CLIENT: sent credentials '%s'", s);
           g_free (s);
         }
     }
@@ -640,11 +652,11 @@ _g_dbus_auth_run_client (GDBusAuth     *auth,
       debug_print ("CLIENT: didn't send any credentials");
     }
 
-  /* TODO: to reduce rountrips, try to pick an auth mechanism to start with */
+  /* TODO: to reduce roundtrips, try to pick an auth mechanism to start with */
 
   /* Get list of supported authentication mechanisms */
   s = "AUTH\r\n";
-  debug_print ("CLIENT: writing `%s'", s);
+  debug_print ("CLIENT: writing '%s'", s);
   if (!g_data_output_stream_put_string (dos, s, cancellable, error))
     goto out;
   state = CLIENT_STATE_WAITING_FOR_REJECT;
@@ -659,13 +671,14 @@ _g_dbus_auth_run_client (GDBusAuth     *auth,
           if (line == NULL)
             goto out;
           debug_print ("CLIENT: WaitingForReject, read '%s'", line);
-        foobar:
+
+        choose_mechanism:
           if (!g_str_has_prefix (line, "REJECTED "))
             {
               g_set_error (error,
                            G_IO_ERROR,
                            G_IO_ERROR_FAILED,
-                           "In WaitingForReject: Expected `REJECTED am1 am2 ... amN', got `%s'",
+                           "In WaitingForReject: Expected 'REJECTED am1 am2 ... amN', got '%s'",
                            line);
               g_free (line);
               goto out;
@@ -675,7 +688,7 @@ _g_dbus_auth_run_client (GDBusAuth     *auth,
               supported_auth_mechs = g_strsplit (line + sizeof ("REJECTED ") - 1, " ", 0);
 #if 0
               for (n = 0; supported_auth_mechs != NULL && supported_auth_mechs[n] != NULL; n++)
-                g_printerr ("supported_auth_mechs[%d] = `%s'\n", n, supported_auth_mechs[n]);
+                g_printerr ("supported_auth_mechs[%d] = '%s'\n", n, supported_auth_mechs[n]);
 #endif
             }
           g_free (line);
@@ -699,7 +712,7 @@ _g_dbus_auth_run_client (GDBusAuth     *auth,
           line = _my_g_data_input_stream_read_line (dis, &line_length, cancellable, error);
           if (line == NULL)
             goto out;
-          debug_print ("CLIENT: WaitingForOK, read `%s'", line);
+          debug_print ("CLIENT: WaitingForOK, read '%s'", line);
           if (g_str_has_prefix (line, "OK "))
             {
               if (!g_dbus_is_guid (line + 3))
@@ -707,7 +720,7 @@ _g_dbus_auth_run_client (GDBusAuth     *auth,
                   g_set_error (error,
                                G_IO_ERROR,
                                G_IO_ERROR_FAILED,
-                               "Invalid OK response `%s'",
+                               "Invalid OK response '%s'",
                                line);
                   g_free (line);
                   goto out;
@@ -718,7 +731,7 @@ _g_dbus_auth_run_client (GDBusAuth     *auth,
               if (offered_capabilities & G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING)
                 {
                   s = "NEGOTIATE_UNIX_FD\r\n";
-                  debug_print ("CLIENT: writing `%s'", s);
+                  debug_print ("CLIENT: writing '%s'", s);
                   if (!g_data_output_stream_put_string (dos, s, cancellable, error))
                     goto out;
                   state = CLIENT_STATE_WAITING_FOR_AGREE_UNIX_FD;
@@ -726,7 +739,7 @@ _g_dbus_auth_run_client (GDBusAuth     *auth,
               else
                 {
                   s = "BEGIN\r\n";
-                  debug_print ("CLIENT: writing `%s'", s);
+                  debug_print ("CLIENT: writing '%s'", s);
                   if (!g_data_output_stream_put_string (dos, s, cancellable, error))
                     goto out;
                   /* and we're done! */
@@ -735,7 +748,7 @@ _g_dbus_auth_run_client (GDBusAuth     *auth,
             }
           else if (g_str_has_prefix (line, "REJECTED "))
             {
-              goto foobar;
+              goto choose_mechanism;
             }
           else
             {
@@ -743,7 +756,7 @@ _g_dbus_auth_run_client (GDBusAuth     *auth,
               g_set_error (error,
                            G_IO_ERROR,
                            G_IO_ERROR_FAILED,
-                           "In WaitingForOk: unexpected response `%s'",
+                           "In WaitingForOk: unexpected response '%s'",
                            line);
               g_free (line);
               goto out;
@@ -755,12 +768,13 @@ _g_dbus_auth_run_client (GDBusAuth     *auth,
           line = _my_g_data_input_stream_read_line (dis, &line_length, cancellable, error);
           if (line == NULL)
             goto out;
-          debug_print ("CLIENT: WaitingForAgreeUnixFD, read=`%s'", line);
+          debug_print ("CLIENT: WaitingForAgreeUnixFD, read='%s'", line);
           if (g_strcmp0 (line, "AGREE_UNIX_FD") == 0)
             {
+              g_free (line);
               negotiated_capabilities |= G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING;
               s = "BEGIN\r\n";
-              debug_print ("CLIENT: writing `%s'", s);
+              debug_print ("CLIENT: writing '%s'", s);
               if (!g_data_output_stream_put_string (dos, s, cancellable, error))
                 goto out;
               /* and we're done! */
@@ -768,10 +782,10 @@ _g_dbus_auth_run_client (GDBusAuth     *auth,
             }
           else if (g_str_has_prefix (line, "ERROR") && (line[5] == 0 || g_ascii_isspace (line[5])))
             {
-              //g_strstrip (line + 5); g_debug ("bah, no unix_fd: `%s'", line + 5);
+              //g_strstrip (line + 5); g_debug ("bah, no unix_fd: '%s'", line + 5);
               g_free (line);
               s = "BEGIN\r\n";
-              debug_print ("CLIENT: writing `%s'", s);
+              debug_print ("CLIENT: writing '%s'", s);
               if (!g_data_output_stream_put_string (dos, s, cancellable, error))
                 goto out;
               /* and we're done! */
@@ -783,7 +797,7 @@ _g_dbus_auth_run_client (GDBusAuth     *auth,
               g_set_error (error,
                            G_IO_ERROR,
                            G_IO_ERROR_FAILED,
-                           "In WaitingForAgreeUnixFd: unexpected response `%s'",
+                           "In WaitingForAgreeUnixFd: unexpected response '%s'",
                            line);
               g_free (line);
               goto out;
@@ -795,12 +809,12 @@ _g_dbus_auth_run_client (GDBusAuth     *auth,
           line = _my_g_data_input_stream_read_line (dis, &line_length, cancellable, error);
           if (line == NULL)
             goto out;
-          debug_print ("CLIENT: WaitingForData, read=`%s'", line);
+          debug_print ("CLIENT: WaitingForData, read='%s'", line);
           if (g_str_has_prefix (line, "DATA "))
             {
               gchar *encoded;
               gchar *decoded_data;
-              gsize decoded_data_len;
+              gsize decoded_data_len = 0;
 
               encoded = g_strdup (line + 5);
               g_free (line);
@@ -826,7 +840,7 @@ _g_dbus_auth_run_client (GDBusAuth     *auth,
                   s = g_strdup_printf ("DATA %s\r\n", encoded_data);
                   g_free (encoded_data);
                   g_free (data);
-                  debug_print ("CLIENT: writing `%s'", s);
+                  debug_print ("CLIENT: writing '%s'", s);
                   if (!g_data_output_stream_put_string (dos, s, cancellable, error))
                     {
                       g_free (s);
@@ -836,12 +850,19 @@ _g_dbus_auth_run_client (GDBusAuth     *auth,
                 }
               state = CLIENT_STATE_WAITING_FOR_OK;
             }
+          else if (g_str_has_prefix (line, "REJECTED "))
+            {
+              /* could be the chosen authentication method just doesn't work. Try
+               * another one...
+               */
+              goto choose_mechanism;
+            }
           else
             {
               g_set_error (error,
                            G_IO_ERROR,
                            G_IO_ERROR_FAILED,
-                           "In WaitingForData: unexpected response `%s'",
+                           "In WaitingForData: unexpected response '%s'",
                            line);
               g_free (line);
               goto out;
@@ -860,8 +881,8 @@ _g_dbus_auth_run_client (GDBusAuth     *auth,
     g_object_unref (mech);
   g_ptr_array_unref (attempted_auth_mechs);
   g_strfreev (supported_auth_mechs);
-  g_object_ref (dis);
-  g_object_ref (dos);
+  g_object_unref (dis);
+  g_object_unref (dos);
 
   /* ensure return value is NULL if error is set */
   if (error != NULL && *error != NULL)
@@ -950,6 +971,8 @@ _g_dbus_auth_run_server (GDBusAuth              *auth,
 
   debug_print ("SERVER: initiating");
 
+  _g_dbus_auth_add_mechs (auth, observer);
+
   ret = FALSE;
   dis = NULL;
   dos = NULL;
@@ -962,25 +985,27 @@ _g_dbus_auth_run_server (GDBusAuth              *auth,
       g_set_error (error,
                    G_IO_ERROR,
                    G_IO_ERROR_FAILED,
-                   "The given guid `%s' is not valid",
+                   "The given guid '%s' is not valid",
                    guid);
       goto out;
     }
 
   dis = G_DATA_INPUT_STREAM (g_data_input_stream_new (g_io_stream_get_input_stream (auth->priv->stream)));
   dos = G_DATA_OUTPUT_STREAM (g_data_output_stream_new (g_io_stream_get_output_stream (auth->priv->stream)));
+  g_filter_input_stream_set_close_base_stream (G_FILTER_INPUT_STREAM (dis), FALSE);
+  g_filter_output_stream_set_close_base_stream (G_FILTER_OUTPUT_STREAM (dos), FALSE);
 
   g_data_input_stream_set_newline_type (dis, G_DATA_STREAM_NEWLINE_TYPE_CR_LF);
 
   /* first read the NUL-byte (TODO: read credentials if using a unix domain socket) */
 #ifdef G_OS_UNIX
-  if (G_IS_UNIX_CONNECTION (auth->priv->stream) && g_unix_credentials_message_is_supported ())
+  if (G_IS_UNIX_CONNECTION (auth->priv->stream))
     {
       local_error = NULL;
       credentials = g_unix_connection_receive_credentials (G_UNIX_CONNECTION (auth->priv->stream),
                                                            cancellable,
                                                            &local_error);
-      if (credentials == NULL)
+      if (credentials == NULL && !g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED))
         {
           g_propagate_error (error, local_error);
           goto out;
@@ -990,6 +1015,7 @@ _g_dbus_auth_run_server (GDBusAuth              *auth,
     {
       local_error = NULL;
       byte = g_data_input_stream_read_byte (dis, cancellable, &local_error);
+      byte = byte; /* To avoid -Wunused-but-set-variable */
       if (local_error != NULL)
         {
           g_propagate_error (error, local_error);
@@ -999,6 +1025,7 @@ _g_dbus_auth_run_server (GDBusAuth              *auth,
 #else
   local_error = NULL;
   byte = g_data_input_stream_read_byte (dis, cancellable, &local_error);
+  byte = byte; /* To avoid -Wunused-but-set-variable */
   if (local_error != NULL)
     {
       g_propagate_error (error, local_error);
@@ -1010,7 +1037,7 @@ _g_dbus_auth_run_server (GDBusAuth              *auth,
       if (G_UNLIKELY (_g_dbus_debug_authentication ()))
         {
           s = g_credentials_to_string (credentials);
-          debug_print ("SERVER: received credentials `%s'", s);
+          debug_print ("SERVER: received credentials '%s'", s);
           g_free (s);
         }
     }
@@ -1027,13 +1054,13 @@ _g_dbus_auth_run_server (GDBusAuth              *auth,
         case SERVER_STATE_WAITING_FOR_AUTH:
           debug_print ("SERVER: WaitingForAuth");
           line = _my_g_data_input_stream_read_line (dis, &line_length, cancellable, error);
-          debug_print ("SERVER: WaitingForAuth, read `%s'", line);
+          debug_print ("SERVER: WaitingForAuth, read '%s'", line);
           if (line == NULL)
             goto out;
           if (g_strcmp0 (line, "AUTH") == 0)
             {
               s = get_auth_mechanisms (auth, allow_anonymous, "REJECTED ", "\r\n", " ");
-              debug_print ("SERVER: writing `%s'", s);
+              debug_print ("SERVER: writing '%s'", s);
               if (!g_data_output_stream_put_string (dos, s, cancellable, error))
                 {
                   g_free (s);
@@ -1070,14 +1097,14 @@ _g_dbus_auth_run_server (GDBusAuth              *auth,
                   g_set_error (error,
                                G_IO_ERROR,
                                G_IO_ERROR_FAILED,
-                               "Unexpected line `%s' while in WaitingForAuth state",
+                               "Unexpected line '%s' while in WaitingForAuth state",
                                line);
                   g_strfreev (tokens);
                   goto out;
                 }
 
               /* TODO: record that the client has attempted to use this mechanism */
-              //g_debug ("client is trying `%s'", mech_name);
+              //g_debug ("client is trying '%s'", mech_name);
 
               auth_mech_to_use_gtype = find_mech_by_name (auth, mech_name);
               if ((auth_mech_to_use_gtype == (GType) 0) ||
@@ -1086,7 +1113,7 @@ _g_dbus_auth_run_server (GDBusAuth              *auth,
                   /* We don't support this auth mechanism */
                   g_strfreev (tokens);
                   s = get_auth_mechanisms (auth, allow_anonymous, "REJECTED ", "\r\n", " ");
-                  debug_print ("SERVER: writing `%s'", s);
+                  debug_print ("SERVER: writing '%s'", s);
                   if (!g_data_output_stream_put_string (dos, s, cancellable, error))
                     {
                       g_free (s);
@@ -1132,21 +1159,21 @@ _g_dbus_auth_run_server (GDBusAuth              *auth,
                     {
                     case G_DBUS_AUTH_MECHANISM_STATE_ACCEPTED:
                       if (observer != NULL &&
-                          g_dbus_auth_observer_deny_authenticated_peer (observer,
-                                                                        auth->priv->stream,
-                                                                        credentials))
+                          !g_dbus_auth_observer_authorize_authenticated_peer (observer,
+                                                                              auth->priv->stream,
+                                                                              credentials))
                         {
                           /* disconnect */
                           g_set_error_literal (error,
                                                G_IO_ERROR,
                                                G_IO_ERROR_FAILED,
-                                               _("Cancelled via GDBusAuthObserver::deny-authenticated-peer"));
+                                               _("Cancelled via GDBusAuthObserver::authorize-authenticated-peer"));
                           goto out;
                         }
                       else
                         {
                           s = g_strdup_printf ("OK %s\r\n", guid);
-                          debug_print ("SERVER: writing `%s'", s);
+                          debug_print ("SERVER: writing '%s'", s);
                           if (!g_data_output_stream_put_string (dos, s, cancellable, error))
                             {
                               g_free (s);
@@ -1159,7 +1186,7 @@ _g_dbus_auth_run_server (GDBusAuth              *auth,
 
                     case G_DBUS_AUTH_MECHANISM_STATE_REJECTED:
                       s = get_auth_mechanisms (auth, allow_anonymous, "REJECTED ", "\r\n", " ");
-                      debug_print ("SERVER: writing `%s'", s);
+                      debug_print ("SERVER: writing '%s'", s);
                       if (!g_data_output_stream_put_string (dos, s, cancellable, error))
                         {
                           g_free (s);
@@ -1183,7 +1210,7 @@ _g_dbus_auth_run_server (GDBusAuth              *auth,
                         s = g_strdup_printf ("DATA %s\r\n", encoded_data);
                         g_free (encoded_data);
                         g_free (data);
-                        debug_print ("SERVER: writing `%s'", s);
+                        debug_print ("SERVER: writing '%s'", s);
                         if (!g_data_output_stream_put_string (dos, s, cancellable, error))
                           {
                             g_free (s);
@@ -1206,7 +1233,7 @@ _g_dbus_auth_run_server (GDBusAuth              *auth,
               g_set_error (error,
                            G_IO_ERROR,
                            G_IO_ERROR_FAILED,
-                           "Unexpected line `%s' while in WaitingForAuth state",
+                           "Unexpected line '%s' while in WaitingForAuth state",
                            line);
               g_free (line);
               goto out;
@@ -1216,14 +1243,14 @@ _g_dbus_auth_run_server (GDBusAuth              *auth,
         case SERVER_STATE_WAITING_FOR_DATA:
           debug_print ("SERVER: WaitingForData");
           line = _my_g_data_input_stream_read_line (dis, &line_length, cancellable, error);
-          debug_print ("SERVER: WaitingForData, read `%s'", line);
+          debug_print ("SERVER: WaitingForData, read '%s'", line);
           if (line == NULL)
             goto out;
           if (g_str_has_prefix (line, "DATA "))
             {
               gchar *encoded;
               gchar *decoded_data;
-              gsize decoded_data_len;
+              gsize decoded_data_len = 0;
 
               encoded = g_strdup (line + 5);
               g_free (line);
@@ -1246,7 +1273,7 @@ _g_dbus_auth_run_server (GDBusAuth              *auth,
               g_set_error (error,
                            G_IO_ERROR,
                            G_IO_ERROR_FAILED,
-                           "Unexpected line `%s' while in WaitingForData state",
+                           "Unexpected line '%s' while in WaitingForData state",
                            line);
               g_free (line);
             }
@@ -1265,7 +1292,7 @@ _g_dbus_auth_run_server (GDBusAuth              *auth,
                                                     &line_length,
                                                     cancellable,
                                                     error);
-          debug_print ("SERVER: WaitingForBegin, read `%s'", line);
+          debug_print ("SERVER: WaitingForBegin, read '%s'", line);
           if (line == NULL)
             goto out;
           if (g_strcmp0 (line, "BEGIN") == 0)
@@ -1277,28 +1304,29 @@ _g_dbus_auth_run_server (GDBusAuth              *auth,
             }
           else if (g_strcmp0 (line, "NEGOTIATE_UNIX_FD") == 0)
             {
+              g_free (line);
               if (offered_capabilities & G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING)
                 {
                   negotiated_capabilities |= G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING;
                   s = "AGREE_UNIX_FD\r\n";
-                  debug_print ("SERVER: writing `%s'", s);
+                  debug_print ("SERVER: writing '%s'", s);
                   if (!g_data_output_stream_put_string (dos, s, cancellable, error))
                     goto out;
                 }
               else
                 {
                   s = "ERROR \"fd passing not offered\"\r\n";
-                  debug_print ("SERVER: writing `%s'", s);
+                  debug_print ("SERVER: writing '%s'", s);
                   if (!g_data_output_stream_put_string (dos, s, cancellable, error))
                     goto out;
                 }
             }
           else
             {
-              g_debug ("Unexpected line `%s' while in WaitingForBegin state", line);
+              g_debug ("Unexpected line '%s' while in WaitingForBegin state", line);
               g_free (line);
               s = "ERROR \"Unknown Command\"\r\n";
-              debug_print ("SERVER: writing `%s'", s);
+              debug_print ("SERVER: writing '%s'", s);
               if (!g_data_output_stream_put_string (dos, s, cancellable, error))
                 goto out;
             }
@@ -1320,9 +1348,9 @@ _g_dbus_auth_run_server (GDBusAuth              *auth,
   if (mech != NULL)
     g_object_unref (mech);
   if (dis != NULL)
-    g_object_ref (dis);
-  if (dis != NULL)
-    g_object_ref (dos);
+    g_object_unref (dis);
+  if (dos != NULL)
+    g_object_unref (dos);
 
   /* ensure return value is FALSE if error is set */
   if (error != NULL && *error != NULL)