Branch data Line data Source code
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 : : * GDBusAuthObserver:
36 : : *
37 : : * `GDBusAuthObserver` provides a mechanism for participating
38 : : * in how a [class@Gio.DBusServer] (or a [class@Gio.DBusConnection])
39 : : * authenticates remote peers.
40 : : *
41 : : * 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 want to allow D-Bus
49 : : * connections with the `EXTERNAL` mechanism, which makes use of credentials
50 : : * passing and is the recommended mechanism for modern Unix platforms such
51 : : * as Linux and the BSD family, you would use a signal handler like this:
52 : : *
53 : : * ```c
54 : : * static gboolean
55 : : * on_allow_mechanism (GDBusAuthObserver *observer,
56 : : * const gchar *mechanism,
57 : : * gpointer user_data)
58 : : * {
59 : : * if (g_strcmp0 (mechanism, "EXTERNAL") == 0)
60 : : * {
61 : : * return TRUE;
62 : : * }
63 : : *
64 : : * return FALSE;
65 : : * }
66 : : * ```
67 : : *
68 : : * ## Controlling Authorization
69 : : *
70 : : * By default, a `GDBusServer` or server-side `GDBusConnection` will accept
71 : : * connections from any successfully authenticated user (but not from
72 : : * anonymous connections using the `ANONYMOUS` mechanism). If you only
73 : : * want to allow D-Bus connections from processes owned by the same uid
74 : : * as the server, since GLib 2.68, you should use the
75 : : * `G_DBUS_SERVER_FLAGS_AUTHENTICATION_REQUIRE_SAME_USER` flag. It’s equivalent
76 : : * to the following signal handler:
77 : : *
78 : : * ```c
79 : : * static gboolean
80 : : * on_authorize_authenticated_peer (GDBusAuthObserver *observer,
81 : : * GIOStream *stream,
82 : : * GCredentials *credentials,
83 : : * gpointer user_data)
84 : : * {
85 : : * gboolean authorized;
86 : : *
87 : : * authorized = FALSE;
88 : : * if (credentials != NULL)
89 : : * {
90 : : * GCredentials *own_credentials;
91 : : * own_credentials = g_credentials_new ();
92 : : * if (g_credentials_is_same_user (credentials, own_credentials, NULL))
93 : : * authorized = TRUE;
94 : : * g_object_unref (own_credentials);
95 : : * }
96 : : *
97 : : * return authorized;
98 : : * }
99 : : * ```
100 : : *
101 : : * Since: 2.26
102 : : */
103 : :
104 : : typedef struct _GDBusAuthObserverClass GDBusAuthObserverClass;
105 : :
106 : : /**
107 : : * GDBusAuthObserverClass:
108 : : * @authorize_authenticated_peer: Signal class handler for the #GDBusAuthObserver::authorize-authenticated-peer signal.
109 : : *
110 : : * Class structure for #GDBusAuthObserverClass.
111 : : *
112 : : * Since: 2.26
113 : : */
114 : : struct _GDBusAuthObserverClass
115 : : {
116 : : /*< private >*/
117 : : GObjectClass parent_class;
118 : :
119 : : /*< public >*/
120 : :
121 : : /* Signals */
122 : : gboolean (*authorize_authenticated_peer) (GDBusAuthObserver *observer,
123 : : GIOStream *stream,
124 : : GCredentials *credentials);
125 : :
126 : : gboolean (*allow_mechanism) (GDBusAuthObserver *observer,
127 : : const gchar *mechanism);
128 : : };
129 : :
130 : : struct _GDBusAuthObserver
131 : : {
132 : : GObject parent_instance;
133 : : };
134 : :
135 : : enum
136 : : {
137 : : AUTHORIZE_AUTHENTICATED_PEER_SIGNAL,
138 : : ALLOW_MECHANISM_SIGNAL,
139 : : LAST_SIGNAL,
140 : : };
141 : :
142 : : static guint signals[LAST_SIGNAL] = { 0 };
143 : :
144 : 779 : G_DEFINE_TYPE (GDBusAuthObserver, g_dbus_auth_observer, G_TYPE_OBJECT)
145 : :
146 : : /* ---------------------------------------------------------------------------------------------------- */
147 : :
148 : : static void
149 : 25 : g_dbus_auth_observer_finalize (GObject *object)
150 : : {
151 : 25 : G_OBJECT_CLASS (g_dbus_auth_observer_parent_class)->finalize (object);
152 : 25 : }
153 : :
154 : : static gboolean
155 : 199 : g_dbus_auth_observer_authorize_authenticated_peer_real (GDBusAuthObserver *observer,
156 : : GIOStream *stream,
157 : : GCredentials *credentials)
158 : : {
159 : 199 : return TRUE;
160 : : }
161 : :
162 : : static gboolean
163 : 359 : g_dbus_auth_observer_allow_mechanism_real (GDBusAuthObserver *observer,
164 : : const gchar *mechanism)
165 : : {
166 : 359 : return TRUE;
167 : : }
168 : :
169 : : static void
170 : 125 : g_dbus_auth_observer_class_init (GDBusAuthObserverClass *klass)
171 : : {
172 : 125 : GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
173 : :
174 : 125 : gobject_class->finalize = g_dbus_auth_observer_finalize;
175 : :
176 : 125 : klass->authorize_authenticated_peer = g_dbus_auth_observer_authorize_authenticated_peer_real;
177 : 125 : klass->allow_mechanism = g_dbus_auth_observer_allow_mechanism_real;
178 : :
179 : : /**
180 : : * GDBusAuthObserver::authorize-authenticated-peer:
181 : : * @observer: The #GDBusAuthObserver emitting the signal.
182 : : * @stream: A #GIOStream for the #GDBusConnection.
183 : : * @credentials: (nullable): Credentials received from the peer or %NULL.
184 : : *
185 : : * Emitted to check if a peer that is successfully authenticated
186 : : * is authorized.
187 : : *
188 : : * Returns: %TRUE if the peer is authorized, %FALSE if not.
189 : : *
190 : : * Since: 2.26
191 : : */
192 : 125 : signals[AUTHORIZE_AUTHENTICATED_PEER_SIGNAL] =
193 : 125 : g_signal_new (I_("authorize-authenticated-peer"),
194 : : G_TYPE_DBUS_AUTH_OBSERVER,
195 : : G_SIGNAL_RUN_LAST,
196 : : G_STRUCT_OFFSET (GDBusAuthObserverClass, authorize_authenticated_peer),
197 : : _g_signal_accumulator_false_handled,
198 : : NULL, /* accu_data */
199 : : _g_cclosure_marshal_BOOLEAN__OBJECT_OBJECT,
200 : : G_TYPE_BOOLEAN,
201 : : 2,
202 : : G_TYPE_IO_STREAM,
203 : : G_TYPE_CREDENTIALS);
204 : 125 : g_signal_set_va_marshaller (signals[AUTHORIZE_AUTHENTICATED_PEER_SIGNAL],
205 : : G_TYPE_FROM_CLASS (klass),
206 : : _g_cclosure_marshal_BOOLEAN__OBJECT_OBJECTv);
207 : :
208 : : /**
209 : : * GDBusAuthObserver::allow-mechanism:
210 : : * @observer: The #GDBusAuthObserver emitting the signal.
211 : : * @mechanism: The name of the mechanism, e.g. `DBUS_COOKIE_SHA1`.
212 : : *
213 : : * Emitted to check if @mechanism is allowed to be used.
214 : : *
215 : : * Returns: %TRUE if @mechanism can be used to authenticate the other peer, %FALSE if not.
216 : : *
217 : : * Since: 2.34
218 : : */
219 : 125 : signals[ALLOW_MECHANISM_SIGNAL] =
220 : 125 : g_signal_new (I_("allow-mechanism"),
221 : : G_TYPE_DBUS_AUTH_OBSERVER,
222 : : G_SIGNAL_RUN_LAST,
223 : : G_STRUCT_OFFSET (GDBusAuthObserverClass, allow_mechanism),
224 : : _g_signal_accumulator_false_handled,
225 : : NULL, /* accu_data */
226 : : _g_cclosure_marshal_BOOLEAN__STRING,
227 : : G_TYPE_BOOLEAN,
228 : : 1,
229 : : G_TYPE_STRING);
230 : 125 : g_signal_set_va_marshaller (signals[ALLOW_MECHANISM_SIGNAL],
231 : : G_TYPE_FROM_CLASS (klass),
232 : : _g_cclosure_marshal_BOOLEAN__STRINGv);
233 : 125 : }
234 : :
235 : : static void
236 : 25 : g_dbus_auth_observer_init (GDBusAuthObserver *observer)
237 : : {
238 : 25 : }
239 : :
240 : : /**
241 : : * g_dbus_auth_observer_new:
242 : : *
243 : : * Creates a new #GDBusAuthObserver object.
244 : : *
245 : : * Returns: A #GDBusAuthObserver. Free with g_object_unref().
246 : : *
247 : : * Since: 2.26
248 : : */
249 : : GDBusAuthObserver *
250 : 24 : g_dbus_auth_observer_new (void)
251 : : {
252 : 24 : return g_object_new (G_TYPE_DBUS_AUTH_OBSERVER, NULL);
253 : : }
254 : :
255 : : /* ---------------------------------------------------------------------------------------------------- */
256 : :
257 : : /**
258 : : * g_dbus_auth_observer_authorize_authenticated_peer:
259 : : * @observer: A #GDBusAuthObserver.
260 : : * @stream: A #GIOStream for the #GDBusConnection.
261 : : * @credentials: (nullable): Credentials received from the peer or %NULL.
262 : : *
263 : : * Emits the #GDBusAuthObserver::authorize-authenticated-peer signal on @observer.
264 : : *
265 : : * Returns: %TRUE if the peer is authorized, %FALSE if not.
266 : : *
267 : : * Since: 2.26
268 : : */
269 : : gboolean
270 : 202 : g_dbus_auth_observer_authorize_authenticated_peer (GDBusAuthObserver *observer,
271 : : GIOStream *stream,
272 : : GCredentials *credentials)
273 : : {
274 : : gboolean denied;
275 : :
276 : 202 : denied = FALSE;
277 : 202 : g_signal_emit (observer,
278 : : signals[AUTHORIZE_AUTHENTICATED_PEER_SIGNAL],
279 : : 0,
280 : : stream,
281 : : credentials,
282 : : &denied);
283 : 202 : return denied;
284 : : }
285 : :
286 : : /**
287 : : * g_dbus_auth_observer_allow_mechanism:
288 : : * @observer: A #GDBusAuthObserver.
289 : : * @mechanism: The name of the mechanism, e.g. `DBUS_COOKIE_SHA1`.
290 : : *
291 : : * Emits the #GDBusAuthObserver::allow-mechanism signal on @observer.
292 : : *
293 : : * Returns: %TRUE if @mechanism can be used to authenticate the other peer, %FALSE if not.
294 : : *
295 : : * Since: 2.34
296 : : */
297 : : gboolean
298 : 621 : g_dbus_auth_observer_allow_mechanism (GDBusAuthObserver *observer,
299 : : const gchar *mechanism)
300 : : {
301 : : gboolean ret;
302 : :
303 : 621 : ret = FALSE;
304 : 621 : g_signal_emit (observer,
305 : : signals[ALLOW_MECHANISM_SIGNAL],
306 : : 0,
307 : : mechanism,
308 : : &ret);
309 : 621 : return ret;
310 : : }
|