Coverage Report

Created: 2018-09-25 13:52

/src/glib/gio/gdbusauthobserver.c
Line
Count
Source (jump to first uncovered line)
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.1 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, see <http://www.gnu.org/licenses/>.
17
 *
18
 * Author: David Zeuthen <davidz@redhat.com>
19
 */
20
21
#include "config.h"
22
23
#include "gdbusauthobserver.h"
24
#include "gcredentials.h"
25
#include "gioenumtypes.h"
26
#include "giostream.h"
27
#include "gdbusprivate.h"
28
29
#include "glibintl.h"
30
31
/**
32
 * SECTION:gdbusauthobserver
33
 * @short_description: Object used for authenticating connections
34
 * @include: gio/gio.h
35
 *
36
 * The #GDBusAuthObserver type provides a mechanism for participating
37
 * in how a #GDBusServer (or a #GDBusConnection) authenticates remote
38
 * peers. Simply instantiate a #GDBusAuthObserver and connect to the
39
 * signals you are interested in. Note that new signals may be added
40
 * in the future
41
 *
42
 * ## Controlling Authentication # {#auth-observer}
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
 * 
48
 * |[<!-- language="C" -->
49
 * static gboolean
50
 * on_authorize_authenticated_peer (GDBusAuthObserver *observer,
51
 *                                  GIOStream         *stream,
52
 *                                  GCredentials      *credentials,
53
 *                                  gpointer           user_data)
54
 * {
55
 *   gboolean authorized;
56
 *
57
 *   authorized = FALSE;
58
 *   if (credentials != NULL)
59
 *     {
60
 *       GCredentials *own_credentials;
61
 *       own_credentials = g_credentials_new ();
62
 *       if (g_credentials_is_same_user (credentials, own_credentials, NULL))
63
 *         authorized = TRUE;
64
 *       g_object_unref (own_credentials);
65
 *     }
66
 *
67
 *   return authorized;
68
 * }
69
 * ]|
70
 */
71
72
typedef struct _GDBusAuthObserverClass GDBusAuthObserverClass;
73
74
/**
75
 * GDBusAuthObserverClass:
76
 * @authorize_authenticated_peer: Signal class handler for the #GDBusAuthObserver::authorize-authenticated-peer signal.
77
 *
78
 * Class structure for #GDBusAuthObserverClass.
79
 *
80
 * Since: 2.26
81
 */
82
struct _GDBusAuthObserverClass
83
{
84
  /*< private >*/
85
  GObjectClass parent_class;
86
87
  /*< public >*/
88
89
  /* Signals */
90
  gboolean (*authorize_authenticated_peer) (GDBusAuthObserver  *observer,
91
                                            GIOStream          *stream,
92
                                            GCredentials       *credentials);
93
94
  gboolean (*allow_mechanism) (GDBusAuthObserver  *observer,
95
                               const gchar        *mechanism);
96
};
97
98
/**
99
 * GDBusAuthObserver:
100
 *
101
 * The #GDBusAuthObserver structure contains only private data and
102
 * should only be accessed using the provided API.
103
 *
104
 * Since: 2.26
105
 */
106
struct _GDBusAuthObserver
107
{
108
  GObject parent_instance;
109
};
110
111
enum
112
{
113
  AUTHORIZE_AUTHENTICATED_PEER_SIGNAL,
114
  ALLOW_MECHANISM_SIGNAL,
115
  LAST_SIGNAL,
116
};
117
118
static guint signals[LAST_SIGNAL] = { 0 };
119
120
G_DEFINE_TYPE (GDBusAuthObserver, g_dbus_auth_observer, G_TYPE_OBJECT)
121
122
/* ---------------------------------------------------------------------------------------------------- */
123
124
static void
125
g_dbus_auth_observer_finalize (GObject *object)
126
0
{
127
0
  G_OBJECT_CLASS (g_dbus_auth_observer_parent_class)->finalize (object);
128
0
}
129
130
static gboolean
131
g_dbus_auth_observer_authorize_authenticated_peer_real (GDBusAuthObserver  *observer,
132
                                                        GIOStream          *stream,
133
                                                        GCredentials       *credentials)
134
0
{
135
0
  return TRUE;
136
0
}
137
138
static gboolean
139
g_dbus_auth_observer_allow_mechanism_real (GDBusAuthObserver  *observer,
140
                                           const gchar        *mechanism)
141
0
{
142
0
  return TRUE;
143
0
}
144
145
static void
146
g_dbus_auth_observer_class_init (GDBusAuthObserverClass *klass)
147
0
{
148
0
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
149
0
150
0
  gobject_class->finalize = g_dbus_auth_observer_finalize;
151
0
152
0
  klass->authorize_authenticated_peer = g_dbus_auth_observer_authorize_authenticated_peer_real;
153
0
  klass->allow_mechanism = g_dbus_auth_observer_allow_mechanism_real;
154
0
155
0
  /**
156
0
   * GDBusAuthObserver::authorize-authenticated-peer:
157
0
   * @observer: The #GDBusAuthObserver emitting the signal.
158
0
   * @stream: A #GIOStream for the #GDBusConnection.
159
0
   * @credentials: (nullable): Credentials received from the peer or %NULL.
160
0
   *
161
0
   * Emitted to check if a peer that is successfully authenticated
162
0
   * is authorized.
163
0
   *
164
0
   * Returns: %TRUE if the peer is authorized, %FALSE if not.
165
0
   *
166
0
   * Since: 2.26
167
0
   */
168
0
  signals[AUTHORIZE_AUTHENTICATED_PEER_SIGNAL] =
169
0
    g_signal_new (I_("authorize-authenticated-peer"),
170
0
                  G_TYPE_DBUS_AUTH_OBSERVER,
171
0
                  G_SIGNAL_RUN_LAST,
172
0
                  G_STRUCT_OFFSET (GDBusAuthObserverClass, authorize_authenticated_peer),
173
0
                  _g_signal_accumulator_false_handled,
174
0
                  NULL, /* accu_data */
175
0
                  NULL,
176
0
                  G_TYPE_BOOLEAN,
177
0
                  2,
178
0
                  G_TYPE_IO_STREAM,
179
0
                  G_TYPE_CREDENTIALS);
180
0
181
0
  /**
182
0
   * GDBusAuthObserver::allow-mechanism:
183
0
   * @observer: The #GDBusAuthObserver emitting the signal.
184
0
   * @mechanism: The name of the mechanism, e.g. `DBUS_COOKIE_SHA1`.
185
0
   *
186
0
   * Emitted to check if @mechanism is allowed to be used.
187
0
   *
188
0
   * Returns: %TRUE if @mechanism can be used to authenticate the other peer, %FALSE if not.
189
0
   *
190
0
   * Since: 2.34
191
0
   */
192
0
  signals[ALLOW_MECHANISM_SIGNAL] =
193
0
    g_signal_new (I_("allow-mechanism"),
194
0
                  G_TYPE_DBUS_AUTH_OBSERVER,
195
0
                  G_SIGNAL_RUN_LAST,
196
0
                  G_STRUCT_OFFSET (GDBusAuthObserverClass, allow_mechanism),
197
0
                  _g_signal_accumulator_false_handled,
198
0
                  NULL, /* accu_data */
199
0
                  NULL,
200
0
                  G_TYPE_BOOLEAN,
201
0
                  1,
202
0
                  G_TYPE_STRING);
203
0
}
204
205
static void
206
g_dbus_auth_observer_init (GDBusAuthObserver *observer)
207
0
{
208
0
}
209
210
/**
211
 * g_dbus_auth_observer_new:
212
 *
213
 * Creates a new #GDBusAuthObserver object.
214
 *
215
 * Returns: A #GDBusAuthObserver. Free with g_object_unref().
216
 *
217
 * Since: 2.26
218
 */
219
GDBusAuthObserver *
220
g_dbus_auth_observer_new (void)
221
0
{
222
0
  return g_object_new (G_TYPE_DBUS_AUTH_OBSERVER, NULL);
223
0
}
224
225
/* ---------------------------------------------------------------------------------------------------- */
226
227
/**
228
 * g_dbus_auth_observer_authorize_authenticated_peer:
229
 * @observer: A #GDBusAuthObserver.
230
 * @stream: A #GIOStream for the #GDBusConnection.
231
 * @credentials: (nullable): Credentials received from the peer or %NULL.
232
 *
233
 * Emits the #GDBusAuthObserver::authorize-authenticated-peer signal on @observer.
234
 *
235
 * Returns: %TRUE if the peer is authorized, %FALSE if not.
236
 *
237
 * Since: 2.26
238
 */
239
gboolean
240
g_dbus_auth_observer_authorize_authenticated_peer (GDBusAuthObserver  *observer,
241
                                                   GIOStream          *stream,
242
                                                   GCredentials       *credentials)
243
0
{
244
0
  gboolean denied;
245
0
246
0
  denied = FALSE;
247
0
  g_signal_emit (observer,
248
0
                 signals[AUTHORIZE_AUTHENTICATED_PEER_SIGNAL],
249
0
                 0,
250
0
                 stream,
251
0
                 credentials,
252
0
                 &denied);
253
0
  return denied;
254
0
}
255
256
/**
257
 * g_dbus_auth_observer_allow_mechanism:
258
 * @observer: A #GDBusAuthObserver.
259
 * @mechanism: The name of the mechanism, e.g. `DBUS_COOKIE_SHA1`.
260
 *
261
 * Emits the #GDBusAuthObserver::allow-mechanism signal on @observer.
262
 *
263
 * Returns: %TRUE if @mechanism can be used to authenticate the other peer, %FALSE if not.
264
 *
265
 * Since: 2.34
266
 */
267
gboolean
268
g_dbus_auth_observer_allow_mechanism (GDBusAuthObserver  *observer,
269
                                      const gchar        *mechanism)
270
0
{
271
0
  gboolean ret;
272
0
273
0
  ret = FALSE;
274
0
  g_signal_emit (observer,
275
0
                 signals[ALLOW_MECHANISM_SIGNAL],
276
0
                 0,
277
0
                 mechanism,
278
0
                 &ret);
279
0
  return ret;
280
0
}
281