Fix getauxval error at qemu
[platform/upstream/glib.git] / gio / gdbusauthobserver.c
1 /* GDBus - GLib D-Bus Library
2  *
3  * Copyright (C) 2008-2010 Red Hat, Inc.
4  *
5  * SPDX-License-Identifier: LGPL-2.1-or-later
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General
18  * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
19  *
20  * Author: David Zeuthen <davidz@redhat.com>
21  */
22
23 #include "config.h"
24
25 #include "gdbusauthobserver.h"
26 #include "gcredentials.h"
27 #include "gioenumtypes.h"
28 #include "giostream.h"
29 #include "gdbusprivate.h"
30
31 #include "glibintl.h"
32 #include "gmarshal-internal.h"
33
34 /**
35  * SECTION:gdbusauthobserver
36  * @short_description: Object used for authenticating connections
37  * @include: gio/gio.h
38  *
39  * The #GDBusAuthObserver type provides a mechanism for participating
40  * in how a #GDBusServer (or a #GDBusConnection) authenticates remote
41  * peers. Simply instantiate a #GDBusAuthObserver and connect to the
42  * signals you are interested in. Note that new signals may be added
43  * in the future
44  *
45  * ## Controlling Authentication Mechanisms
46  *
47  * By default, a #GDBusServer or server-side #GDBusConnection will allow
48  * any authentication mechanism to be used. If you only
49  * want to allow D-Bus connections with the `EXTERNAL` mechanism,
50  * which makes use of credentials passing and is the recommended
51  * mechanism for modern Unix platforms such as Linux and the BSD family,
52  * you would use a signal handler like this:
53  *
54  * |[<!-- language="C" -->
55  * static gboolean
56  * on_allow_mechanism (GDBusAuthObserver *observer,
57  *                     const gchar       *mechanism,
58  *                     gpointer           user_data)
59  * {
60  *   if (g_strcmp0 (mechanism, "EXTERNAL") == 0)
61  *     {
62  *       return TRUE;
63  *     }
64  *
65  *   return FALSE;
66  * }
67  * ]|
68  *
69  * ## Controlling Authorization # {#auth-observer}
70  *
71  * By default, a #GDBusServer or server-side #GDBusConnection will accept
72  * connections from any successfully authenticated user (but not from
73  * anonymous connections using the `ANONYMOUS` mechanism). If you only
74  * want to allow D-Bus connections from processes owned by the same uid
75  * as the server, since GLib 2.68, you should use the
76  * %G_DBUS_SERVER_FLAGS_AUTHENTICATION_REQUIRE_SAME_USER flag. It’s equivalent
77  * to the following signal handler:
78  * 
79  * |[<!-- language="C" -->
80  * static gboolean
81  * on_authorize_authenticated_peer (GDBusAuthObserver *observer,
82  *                                  GIOStream         *stream,
83  *                                  GCredentials      *credentials,
84  *                                  gpointer           user_data)
85  * {
86  *   gboolean authorized;
87  *
88  *   authorized = FALSE;
89  *   if (credentials != NULL)
90  *     {
91  *       GCredentials *own_credentials;
92  *       own_credentials = g_credentials_new ();
93  *       if (g_credentials_is_same_user (credentials, own_credentials, NULL))
94  *         authorized = TRUE;
95  *       g_object_unref (own_credentials);
96  *     }
97  *
98  *   return authorized;
99  * }
100  * ]|
101  */
102
103 typedef struct _GDBusAuthObserverClass GDBusAuthObserverClass;
104
105 /**
106  * GDBusAuthObserverClass:
107  * @authorize_authenticated_peer: Signal class handler for the #GDBusAuthObserver::authorize-authenticated-peer signal.
108  *
109  * Class structure for #GDBusAuthObserverClass.
110  *
111  * Since: 2.26
112  */
113 struct _GDBusAuthObserverClass
114 {
115   /*< private >*/
116   GObjectClass parent_class;
117
118   /*< public >*/
119
120   /* Signals */
121   gboolean (*authorize_authenticated_peer) (GDBusAuthObserver  *observer,
122                                             GIOStream          *stream,
123                                             GCredentials       *credentials);
124
125   gboolean (*allow_mechanism) (GDBusAuthObserver  *observer,
126                                const gchar        *mechanism);
127 };
128
129 /**
130  * GDBusAuthObserver:
131  *
132  * The #GDBusAuthObserver structure contains only private data and
133  * should only be accessed using the provided API.
134  *
135  * Since: 2.26
136  */
137 struct _GDBusAuthObserver
138 {
139   GObject parent_instance;
140 };
141
142 enum
143 {
144   AUTHORIZE_AUTHENTICATED_PEER_SIGNAL,
145   ALLOW_MECHANISM_SIGNAL,
146   LAST_SIGNAL,
147 };
148
149 static guint signals[LAST_SIGNAL] = { 0 };
150
151 G_DEFINE_TYPE (GDBusAuthObserver, g_dbus_auth_observer, G_TYPE_OBJECT)
152
153 /* ---------------------------------------------------------------------------------------------------- */
154
155 static void
156 g_dbus_auth_observer_finalize (GObject *object)
157 {
158   G_OBJECT_CLASS (g_dbus_auth_observer_parent_class)->finalize (object);
159 }
160
161 static gboolean
162 g_dbus_auth_observer_authorize_authenticated_peer_real (GDBusAuthObserver  *observer,
163                                                         GIOStream          *stream,
164                                                         GCredentials       *credentials)
165 {
166   return TRUE;
167 }
168
169 static gboolean
170 g_dbus_auth_observer_allow_mechanism_real (GDBusAuthObserver  *observer,
171                                            const gchar        *mechanism)
172 {
173   return TRUE;
174 }
175
176 static void
177 g_dbus_auth_observer_class_init (GDBusAuthObserverClass *klass)
178 {
179   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
180
181   gobject_class->finalize = g_dbus_auth_observer_finalize;
182
183   klass->authorize_authenticated_peer = g_dbus_auth_observer_authorize_authenticated_peer_real;
184   klass->allow_mechanism = g_dbus_auth_observer_allow_mechanism_real;
185
186   /**
187    * GDBusAuthObserver::authorize-authenticated-peer:
188    * @observer: The #GDBusAuthObserver emitting the signal.
189    * @stream: A #GIOStream for the #GDBusConnection.
190    * @credentials: (nullable): Credentials received from the peer or %NULL.
191    *
192    * Emitted to check if a peer that is successfully authenticated
193    * is authorized.
194    *
195    * Returns: %TRUE if the peer is authorized, %FALSE if not.
196    *
197    * Since: 2.26
198    */
199   signals[AUTHORIZE_AUTHENTICATED_PEER_SIGNAL] =
200     g_signal_new (I_("authorize-authenticated-peer"),
201                   G_TYPE_DBUS_AUTH_OBSERVER,
202                   G_SIGNAL_RUN_LAST,
203                   G_STRUCT_OFFSET (GDBusAuthObserverClass, authorize_authenticated_peer),
204                   _g_signal_accumulator_false_handled,
205                   NULL, /* accu_data */
206                   _g_cclosure_marshal_BOOLEAN__OBJECT_OBJECT,
207                   G_TYPE_BOOLEAN,
208                   2,
209                   G_TYPE_IO_STREAM,
210                   G_TYPE_CREDENTIALS);
211   g_signal_set_va_marshaller (signals[AUTHORIZE_AUTHENTICATED_PEER_SIGNAL],
212                               G_TYPE_FROM_CLASS (klass),
213                               _g_cclosure_marshal_BOOLEAN__OBJECT_OBJECTv);
214
215   /**
216    * GDBusAuthObserver::allow-mechanism:
217    * @observer: The #GDBusAuthObserver emitting the signal.
218    * @mechanism: The name of the mechanism, e.g. `DBUS_COOKIE_SHA1`.
219    *
220    * Emitted to check if @mechanism is allowed to be used.
221    *
222    * Returns: %TRUE if @mechanism can be used to authenticate the other peer, %FALSE if not.
223    *
224    * Since: 2.34
225    */
226   signals[ALLOW_MECHANISM_SIGNAL] =
227     g_signal_new (I_("allow-mechanism"),
228                   G_TYPE_DBUS_AUTH_OBSERVER,
229                   G_SIGNAL_RUN_LAST,
230                   G_STRUCT_OFFSET (GDBusAuthObserverClass, allow_mechanism),
231                   _g_signal_accumulator_false_handled,
232                   NULL, /* accu_data */
233                   _g_cclosure_marshal_BOOLEAN__STRING,
234                   G_TYPE_BOOLEAN,
235                   1,
236                   G_TYPE_STRING);
237   g_signal_set_va_marshaller (signals[ALLOW_MECHANISM_SIGNAL],
238                               G_TYPE_FROM_CLASS (klass),
239                               _g_cclosure_marshal_BOOLEAN__STRINGv);
240 }
241
242 static void
243 g_dbus_auth_observer_init (GDBusAuthObserver *observer)
244 {
245 }
246
247 /**
248  * g_dbus_auth_observer_new:
249  *
250  * Creates a new #GDBusAuthObserver object.
251  *
252  * Returns: A #GDBusAuthObserver. Free with g_object_unref().
253  *
254  * Since: 2.26
255  */
256 GDBusAuthObserver *
257 g_dbus_auth_observer_new (void)
258 {
259   return g_object_new (G_TYPE_DBUS_AUTH_OBSERVER, NULL);
260 }
261
262 /* ---------------------------------------------------------------------------------------------------- */
263
264 /**
265  * g_dbus_auth_observer_authorize_authenticated_peer:
266  * @observer: A #GDBusAuthObserver.
267  * @stream: A #GIOStream for the #GDBusConnection.
268  * @credentials: (nullable): Credentials received from the peer or %NULL.
269  *
270  * Emits the #GDBusAuthObserver::authorize-authenticated-peer signal on @observer.
271  *
272  * Returns: %TRUE if the peer is authorized, %FALSE if not.
273  *
274  * Since: 2.26
275  */
276 gboolean
277 g_dbus_auth_observer_authorize_authenticated_peer (GDBusAuthObserver  *observer,
278                                                    GIOStream          *stream,
279                                                    GCredentials       *credentials)
280 {
281   gboolean denied;
282
283   denied = FALSE;
284   g_signal_emit (observer,
285                  signals[AUTHORIZE_AUTHENTICATED_PEER_SIGNAL],
286                  0,
287                  stream,
288                  credentials,
289                  &denied);
290   return denied;
291 }
292
293 /**
294  * g_dbus_auth_observer_allow_mechanism:
295  * @observer: A #GDBusAuthObserver.
296  * @mechanism: The name of the mechanism, e.g. `DBUS_COOKIE_SHA1`.
297  *
298  * Emits the #GDBusAuthObserver::allow-mechanism signal on @observer.
299  *
300  * Returns: %TRUE if @mechanism can be used to authenticate the other peer, %FALSE if not.
301  *
302  * Since: 2.34
303  */
304 gboolean
305 g_dbus_auth_observer_allow_mechanism (GDBusAuthObserver  *observer,
306                                       const gchar        *mechanism)
307 {
308   gboolean ret;
309
310   ret = FALSE;
311   g_signal_emit (observer,
312                  signals[ALLOW_MECHANISM_SIGNAL],
313                  0,
314                  mechanism,
315                  &ret);
316   return ret;
317 }