Merge remote branch 'gvdb/master'
[platform/upstream/glib.git] / gio / gdbusauthobserver.c
1 /* GDBus - GLib D-Bus Library
2  *
3  * Copyright (C) 2008-2010 Red Hat, Inc.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General
16  * Public License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18  * Boston, MA 02111-1307, USA.
19  *
20  * Author: David Zeuthen <davidz@redhat.com>
21  */
22
23 #include "config.h"
24
25 #include "gdbusauthobserver.h"
26 #include "gio-marshal.h"
27 #include "gcredentials.h"
28 #include "gioenumtypes.h"
29 #include "giostream.h"
30
31 #include "glibintl.h"
32
33 /**
34  * SECTION:gdbusauthobserver
35  * @short_description: Object used for authenticating connections
36  * @include: gio/gio.h
37  *
38  * The #GDBusAuthObserver type provides a mechanism for participating
39  * in how a #GDBusServer (or a #GDBusConnection) authenticates remote
40  * peers. Simply instantiate a #GDBusAuthObserver and connect to the
41  * signals you are interested in. Note that new signals may be added
42  * in the future
43  *
44  * For example, if you only want to allow D-Bus connections from
45  * processes owned by the same uid as the server, you would use a
46  * signal handler like the following:
47  * <example id="auth-observer"><title>Controlling Authentication</title><programlisting>
48  * static gboolean
49  * on_authorize_authenticated_peer (GDBusAuthObserver *observer,
50  *                                  GIOStream         *stream,
51  *                                  GCredentials      *credentials,
52  *                                  gpointer           user_data)
53  * {
54  *   gboolean authorized;
55  *
56  *   authorized = FALSE;
57  *   if (credentials != NULL)
58  *     {
59  *       GCredentials *own_credentials;
60  *       own_credentials = g_credentials_new ();
61  *       if (g_credentials_is_same_user (credentials, own_credentials, NULL))
62  *         authorized = TRUE;
63  *       g_object_unref (own_credentials);
64  *     }
65  *
66  *   return authorized;
67  * }
68  * </programlisting></example>
69  */
70
71 typedef struct _GDBusAuthObserverClass GDBusAuthObserverClass;
72
73 /**
74  * GDBusAuthObserverClass:
75  * @authorize_authenticated_peer: Signal class handler for the #GDBusAuthObserver::authorize-authenticated-peer signal.
76  *
77  * Class structure for #GDBusAuthObserverClass.
78  *
79  * Since: 2.26
80  */
81 struct _GDBusAuthObserverClass
82 {
83   /*< private >*/
84   GObjectClass parent_class;
85
86   /*< public >*/
87
88   /* Signals */
89   gboolean (*authorize_authenticated_peer) (GDBusAuthObserver  *observer,
90                                             GIOStream          *stream,
91                                             GCredentials       *credentials);
92 };
93
94 /**
95  * GDBusAuthObserver:
96  *
97  * The #GDBusAuthObserver structure contains only private data and
98  * should only be accessed using the provided API.
99  *
100  * Since: 2.26
101  */
102 struct _GDBusAuthObserver
103 {
104   GObject parent_instance;
105 };
106
107 enum
108 {
109   AUTHORIZE_AUTHENTICATED_PEER_SIGNAL,
110   LAST_SIGNAL,
111 };
112
113 static guint signals[LAST_SIGNAL] = { 0 };
114
115 G_DEFINE_TYPE (GDBusAuthObserver, g_dbus_auth_observer, G_TYPE_OBJECT);
116
117 /* ---------------------------------------------------------------------------------------------------- */
118
119 static void
120 g_dbus_auth_observer_finalize (GObject *object)
121 {
122   G_OBJECT_CLASS (g_dbus_auth_observer_parent_class)->finalize (object);
123 }
124
125 static gboolean
126 g_dbus_auth_observer_authorize_authenticated_peer_real (GDBusAuthObserver  *observer,
127                                                         GIOStream          *stream,
128                                                         GCredentials       *credentials)
129 {
130   return TRUE;
131 }
132
133 gboolean
134 _g_signal_accumulator_false_handled (GSignalInvocationHint *ihint,
135                                      GValue                *return_accu,
136                                      const GValue          *handler_return,
137                                      gpointer               dummy)
138 {
139   gboolean continue_emission;
140   gboolean signal_handled;
141
142   signal_handled = g_value_get_boolean (handler_return);
143   g_value_set_boolean (return_accu, signal_handled);
144   continue_emission = signal_handled;
145
146   return continue_emission;
147 }
148
149 static void
150 g_dbus_auth_observer_class_init (GDBusAuthObserverClass *klass)
151 {
152   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
153
154   gobject_class->finalize = g_dbus_auth_observer_finalize;
155
156   klass->authorize_authenticated_peer = g_dbus_auth_observer_authorize_authenticated_peer_real;
157
158   /**
159    * GDBusAuthObserver::authorize-authenticated-peer:
160    * @observer: The #GDBusAuthObserver emitting the signal.
161    * @stream: A #GIOStream for the #GDBusConnection.
162    * @credentials: Credentials received from the peer or %NULL.
163    *
164    * Emitted to check if a peer that is successfully authenticated
165    * is authorized.
166    *
167    * Returns: %TRUE if the peer is authorized, %FALSE if not.
168    *
169    * Since: 2.26
170    */
171   signals[AUTHORIZE_AUTHENTICATED_PEER_SIGNAL] =
172     g_signal_new ("authorize-authenticated-peer",
173                   G_TYPE_DBUS_AUTH_OBSERVER,
174                   G_SIGNAL_RUN_LAST,
175                   G_STRUCT_OFFSET (GDBusAuthObserverClass, authorize_authenticated_peer),
176                   _g_signal_accumulator_false_handled,
177                   NULL, /* accu_data */
178                   _gio_marshal_BOOLEAN__OBJECT_OBJECT,
179                   G_TYPE_BOOLEAN,
180                   2,
181                   G_TYPE_IO_STREAM,
182                   G_TYPE_CREDENTIALS);
183 }
184
185 static void
186 g_dbus_auth_observer_init (GDBusAuthObserver *observer)
187 {
188 }
189
190 /**
191  * g_dbus_auth_observer_new:
192  *
193  * Creates a new #GDBusAuthObserver object.
194  *
195  * Returns: A #GDBusAuthObserver. Free with g_object_unref().
196  *
197  * Since: 2.26
198  */
199 GDBusAuthObserver *
200 g_dbus_auth_observer_new (void)
201 {
202   return g_object_new (G_TYPE_DBUS_AUTH_OBSERVER, NULL);
203 }
204
205 /* ---------------------------------------------------------------------------------------------------- */
206
207 /**
208  * g_dbus_auth_observer_authorize_authenticated_peer:
209  * @observer: A #GDBusAuthObserver.
210  * @stream: A #GIOStream for the #GDBusConnection.
211  * @credentials: Credentials received from the peer or %NULL.
212  *
213  * Emits the #GDBusAuthObserver::authorize-authenticated-peer signal on @observer.
214  *
215  * Returns: %TRUE if the peer is authorized, %FALSE if not.
216  *
217  * Since: 2.26
218  */
219 gboolean
220 g_dbus_auth_observer_authorize_authenticated_peer (GDBusAuthObserver  *observer,
221                                                    GIOStream          *stream,
222                                                    GCredentials       *credentials)
223 {
224   gboolean denied;
225
226   denied = FALSE;
227   g_signal_emit (observer,
228                  signals[AUTHORIZE_AUTHENTICATED_PEER_SIGNAL],
229                  0,
230                  stream,
231                  credentials,
232                  &denied);
233   return denied;
234 }