~ubuntu-branches/ubuntu/saucy/unity8/saucy-proposed

« back to all changes in this revision

Viewing changes to plugins/Unity/IndicatorsLegacy/Network/secret-agent.c

  • Committer: Package Import Robot
  • Author(s): Loïc Minier
  • Date: 2013-10-04 21:22:29 UTC
  • Revision ID: package-import@ubuntu.com-20131004212229-a2j9c8et8gfd7xue
Tags: 7.82+13.10.20131004.2-0ubuntu1
Revert 7.82+13.10.20131004.1-0ubuntu1 back to
7.81.3+13.10.20130927.3-0ubuntu1 due to CPU hogging issue with
7.82+13.10.20131004.1-0ubuntu1.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright 2013 Canonical Ltd.
 
3
 *
 
4
 * This program is free software; you can redistribute it and/or modify
 
5
 * it under the terms of the GNU Lesser General Public License as published by
 
6
 * the Free Software Foundation; version 3.
 
7
 *
 
8
 * This program is distributed in the hope that it will be useful,
 
9
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
 * GNU Lesser General Public License for more details.
 
12
 *
 
13
 * You should have received a copy of the GNU Lesser General Public License
 
14
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
15
 *
 
16
 * Authors:
 
17
 *     Alberto Ruiz <alberto.ruiz@canonical.com>
 
18
 *     Renato Araujo Oliveira Filho <renato@canonical.com>
 
19
 */
 
20
 
 
21
 
 
22
#include <glib.h>
 
23
#include <glib-object.h>
 
24
#include <nm-secret-agent.h>
 
25
#include "secret-agent.h"
 
26
 
 
27
#define UNITY_SETTINGS_TYPE_SECRET_AGENT (unity_settings_secret_agent_get_type ())
 
28
#define UNITY_SETTINGS_SECRET_AGENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), UNITY_SETTINGS_TYPE_SECRET_AGENT, UnitySettingsSecretAgent))
 
29
#define UNITY_SETTINGS_SECRET_AGENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), UNITY_SETTINGS_TYPE_SECRET_AGENT, UnitySettingsSecretAgentClass))
 
30
#define UNITY_SETTINGS_IS_SECRET_AGENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), UNITY_SETTINGS_TYPE_SECRET_AGENT))
 
31
#define UNITY_SETTINGS_IS_SECRET_AGENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), UNITY_SETTINGS_TYPE_SECRET_AGENT))
 
32
#define UNITY_SETTINGS_SECRET_AGENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), UNITY_SETTINGS_TYPE_SECRET_AGENT, UnitySettingsSecretAgentClass))
 
33
#define UNITY_SETTINGS_SECRET_AGENT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), UNITY_SETTINGS_TYPE_SECRET_AGENT, UnitySettingsSecretAgentPrivate))
 
34
 
 
35
#define AGENT_ID "com.canonical.settings.network.nm-agent"
 
36
 
 
37
static gpointer unity_settings_secret_agent_parent_class = NULL;
 
38
 
 
39
typedef struct _UnitySettingsSecretAgentPrivate UnitySettingsSecretAgentPrivate;
 
40
 
 
41
struct _UnitySettingsSecretAgentPrivate {
 
42
  GQueue  *requests;
 
43
};
 
44
 
 
45
typedef struct _SecretRequest {
 
46
  gint                           id;
 
47
  NMSecretAgent                 *agent;
 
48
  NMConnection                  *connection;
 
49
  const char                    *connection_path;
 
50
  const char                    *setting_name;
 
51
  const char                   **hints;
 
52
  NMSecretAgentGetSecretsFlags   flags;
 
53
  NMSecretAgentGetSecretsFunc    callback;
 
54
  gpointer                       callback_data;
 
55
} SecretRequest;
 
56
 
 
57
GType unity_settings_secret_agent_get_type (void) G_GNUC_CONST;
 
58
enum  {
 
59
    UNITY_SETTINGS_SECRET_AGENT_DUMMY_PROPERTY
 
60
};
 
61
 
 
62
enum {
 
63
  SECRET_REQUESTED,
 
64
  REQUEST_CANCELLED,
 
65
  LAST_SIGNAL
 
66
};
 
67
 
 
68
static guint signals[LAST_SIGNAL] = { 0 };
 
69
 
 
70
UnitySettingsSecretAgent* unity_settings_secret_agent_new       (void);
 
71
UnitySettingsSecretAgent* unity_settings_secret_agent_construct (GType object_type);
 
72
 
 
73
int
 
74
secret_request_find (SecretRequest  *req,
 
75
                     guint          *id)
 
76
{
 
77
  if (req->id > *id)
 
78
      return -1;
 
79
 
 
80
  if (req->id < *id)
 
81
      return 1;
 
82
 
 
83
  return 0;
 
84
}
 
85
 
 
86
void
 
87
unity_settings_secret_agent_provide_secret (UnitySettingsSecretAgent *agent,
 
88
                                            guint                     request,
 
89
                                            GHashTable               *secrets)
 
90
{
 
91
  GList                           *iter;
 
92
  SecretRequest                   *req;
 
93
  UnitySettingsSecretAgentPrivate *priv = agent->priv;
 
94
 
 
95
  iter = g_queue_find_custom (priv->requests,
 
96
                              &request,
 
97
                              (GCompareFunc)secret_request_find);
 
98
 
 
99
  if (iter == NULL || iter->data == NULL)
 
100
    {
 
101
      g_warning ("Secret request with id <%d> was not found", (int)request);
 
102
      return;
 
103
    }
 
104
 
 
105
  req = iter->data;
 
106
 
 
107
  req->callback (NM_SECRET_AGENT (agent),
 
108
                 req->connection,
 
109
                 secrets,
 
110
                 NULL,
 
111
                 req->callback_data);
 
112
 
 
113
  g_queue_remove_all (priv->requests, req);
 
114
  g_free (req);
 
115
  return;
 
116
}
 
117
 
 
118
void
 
119
free_request (SecretRequest *req)
 
120
{
 
121
  g_object_unref (req->connection);
 
122
  g_free (req);
 
123
}
 
124
 
 
125
void
 
126
unity_settings_secret_agent_cancel_request (UnitySettingsSecretAgent *agent,
 
127
                                            guint                     request)
 
128
{
 
129
  GList                           *iter;
 
130
  SecretRequest                   *req;
 
131
  UnitySettingsSecretAgentPrivate *priv = agent->priv;
 
132
  GError *error;
 
133
 
 
134
  iter = g_queue_find_custom (priv->requests,
 
135
                              &request,
 
136
                              (GCompareFunc)secret_request_find);
 
137
 
 
138
  if (iter == NULL || iter->data == NULL)
 
139
    {
 
140
      g_warning ("Secret request with id <%d> was not found", (int)request);
 
141
      return;
 
142
    }
 
143
 
 
144
  req = iter->data;
 
145
  error = g_error_new (NM_SECRET_AGENT_ERROR,
 
146
                       NM_SECRET_AGENT_ERROR_INTERNAL_ERROR,
 
147
                       "This secret request was canceled by the user.");
 
148
 
 
149
  req->callback (NM_SECRET_AGENT (agent),
 
150
                 req->connection,
 
151
                 NULL,
 
152
                 error,
 
153
                 req->callback_data);
 
154
 
 
155
  g_queue_remove_all (priv->requests, req);
 
156
  free_request (req);
 
157
  return;
 
158
}
 
159
 
 
160
static void
 
161
delete_secrets (NMSecretAgent *agent,
 
162
                NMConnection *connection,
 
163
                const char *connection_path,
 
164
                NMSecretAgentDeleteSecretsFunc callback,
 
165
                gpointer callback_data)
 
166
{
 
167
  g_debug ("delete secrets");
 
168
}
 
169
 
 
170
/* If it returns G_MAXUINT it's considered an error */
 
171
static guint
 
172
find_available_id (UnitySettingsSecretAgentPrivate *priv)
 
173
{
 
174
  guint i         = 0;
 
175
  guint candidate = 0;
 
176
 
 
177
  if (g_queue_get_length (priv->requests) == G_MAXUINT)
 
178
    return G_MAXUINT;
 
179
 
 
180
  while (i < g_queue_get_length (priv->requests))
 
181
    {
 
182
      SecretRequest *req = (SecretRequest*)g_queue_peek_nth (priv->requests, i);
 
183
 
 
184
      if (req->id == candidate)
 
185
      {
 
186
        candidate++;
 
187
        i = 0;
 
188
      }
 
189
      else
 
190
      {
 
191
        i++;
 
192
      }
 
193
    }
 
194
 
 
195
  return i;
 
196
}
 
197
 
 
198
static void
 
199
get_secrets (NMSecretAgent                 *agent,
 
200
             NMConnection                  *connection,
 
201
             const char                    *connection_path,
 
202
             const char                    *setting_name,
 
203
             const char                   **hints,
 
204
             NMSecretAgentGetSecretsFlags   flags,
 
205
             NMSecretAgentGetSecretsFunc    callback,
 
206
             gpointer                       callback_data)
 
207
{
 
208
  guint   id;
 
209
  UnitySettingsSecretAgentPrivate *priv = UNITY_SETTINGS_SECRET_AGENT_GET_PRIVATE (agent);
 
210
  SecretRequest *req = NULL;
 
211
 
 
212
  if (flags == NM_SECRET_AGENT_GET_SECRETS_FLAG_NONE)
 
213
    {
 
214
      GError *error = g_error_new (NM_SECRET_AGENT_ERROR,
 
215
                                   NM_SECRET_AGENT_ERROR_INTERNAL_ERROR,
 
216
                                   "No password found for this connection.");
 
217
      callback (agent, connection, NULL, error, callback_data);
 
218
      g_error_free (error);
 
219
      return;
 
220
    }
 
221
 
 
222
  id = find_available_id (priv);
 
223
  if (id == G_MAXUINT)
 
224
    {
 
225
      GError *error = g_error_new (NM_SECRET_AGENT_ERROR,
 
226
                                   NM_SECRET_AGENT_ERROR_INTERNAL_ERROR,
 
227
                                   "Reached maximum number of requests.");
 
228
      callback (agent, connection, NULL, error, callback_data);
 
229
      g_error_free (error);
 
230
      return;
 
231
    }
 
232
 
 
233
  /* Adding a request */
 
234
  req = (SecretRequest*) g_malloc0 (sizeof (SecretRequest));
 
235
  *req = ((SecretRequest)
 
236
          { id,
 
237
            agent,
 
238
            connection,
 
239
            connection_path,
 
240
            setting_name,
 
241
            hints,
 
242
            flags,
 
243
            callback,
 
244
            callback_data });
 
245
 
 
246
  g_object_ref (connection);
 
247
 
 
248
  g_queue_push_tail (priv->requests, req);
 
249
 
 
250
  g_signal_emit_by_name (agent,
 
251
                         UNITY_SETTINGS_SECRET_AGENT_SECRET_REQUESTED,
 
252
                         id,
 
253
                         connection,
 
254
                         setting_name,
 
255
                         hints,
 
256
                         flags);
 
257
}
 
258
 
 
259
static void
 
260
save_secrets (NMSecretAgent                *agent,
 
261
              NMConnection                 *connection,
 
262
              const char                   *connection_path,
 
263
              NMSecretAgentSaveSecretsFunc  callback,
 
264
              gpointer                      callback_data)
 
265
{
 
266
  g_debug ("save secrets");
 
267
}
 
268
 
 
269
static void
 
270
cancel_get_secrets (NMSecretAgent *agent,
 
271
                    const char *connection_path,
 
272
                    const char *setting_name)
 
273
{
 
274
  g_debug ("cancel get secrets");
 
275
}
 
276
 
 
277
UnitySettingsSecretAgent*
 
278
unity_settings_secret_agent_construct (GType object_type)
 
279
{
 
280
  UnitySettingsSecretAgent * self = NULL;
 
281
  self = (UnitySettingsSecretAgent*) g_object_new (object_type,
 
282
                                                   NM_SECRET_AGENT_IDENTIFIER, AGENT_ID,
 
283
                                                   NULL);
 
284
  return self;
 
285
}
 
286
 
 
287
 
 
288
UnitySettingsSecretAgent*
 
289
unity_settings_secret_agent_new (void)
 
290
{
 
291
  return unity_settings_secret_agent_construct (UNITY_SETTINGS_TYPE_SECRET_AGENT);
 
292
}
 
293
 
 
294
static void
 
295
destroy_pending_request (gpointer data)
 
296
{
 
297
  SecretRequest* req = (SecretRequest*)data;
 
298
  /* Reporting the cancellation of all pending requests */
 
299
  g_signal_emit_by_name (req->agent,
 
300
                         UNITY_SETTINGS_SECRET_AGENT_REQUEST_CANCELLED,
 
301
                         req->id);
 
302
 
 
303
  free_request (req);
 
304
}
 
305
 
 
306
static void
 
307
unity_settings_secret_agent_finalize (GObject *agent)
 
308
{
 
309
  UnitySettingsSecretAgentPrivate *priv = UNITY_SETTINGS_SECRET_AGENT_GET_PRIVATE (agent);
 
310
 
 
311
  g_queue_free_full (priv->requests, destroy_pending_request);
 
312
}
 
313
 
 
314
static void
 
315
unity_settings_secret_agent_class_init (UnitySettingsSecretAgentClass *klass)
 
316
{
 
317
  unity_settings_secret_agent_parent_class = g_type_class_peek_parent (klass);
 
318
  NMSecretAgentClass         *parent_class = NM_SECRET_AGENT_CLASS (klass);
 
319
  parent_class->get_secrets = get_secrets;
 
320
  parent_class->save_secrets = save_secrets;
 
321
  parent_class->delete_secrets = delete_secrets;
 
322
  parent_class->cancel_get_secrets = cancel_get_secrets;
 
323
 
 
324
  g_type_class_add_private (klass, sizeof(UnitySettingsSecretAgentPrivate));
 
325
  G_OBJECT_CLASS (klass)->finalize = unity_settings_secret_agent_finalize;
 
326
 
 
327
 
 
328
  signals[SECRET_REQUESTED] = g_signal_new (UNITY_SETTINGS_SECRET_AGENT_SECRET_REQUESTED,
 
329
                                            G_OBJECT_CLASS_TYPE (G_OBJECT_CLASS (klass)),
 
330
                                            G_SIGNAL_RUN_FIRST,
 
331
                                            G_STRUCT_OFFSET (UnitySettingsSecretAgentClass, secret_requested),
 
332
                                            NULL, NULL, NULL,
 
333
                                            G_TYPE_NONE, 5,
 
334
                                            G_TYPE_UINT, G_TYPE_POINTER, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_UINT);
 
335
 
 
336
  signals[REQUEST_CANCELLED] = g_signal_new (UNITY_SETTINGS_SECRET_AGENT_REQUEST_CANCELLED,
 
337
                                             G_OBJECT_CLASS_TYPE (G_OBJECT_CLASS (klass)),
 
338
                                             G_SIGNAL_RUN_FIRST,
 
339
                                             G_STRUCT_OFFSET (UnitySettingsSecretAgentClass, request_cancelled),
 
340
                                             NULL, NULL, NULL,
 
341
                                             G_TYPE_NONE, 1,
 
342
                                             G_TYPE_UINT);
 
343
}
 
344
 
 
345
 
 
346
static void
 
347
unity_settings_secret_agent_instance_init (UnitySettingsSecretAgent *self)
 
348
{
 
349
  self->priv = UNITY_SETTINGS_SECRET_AGENT_GET_PRIVATE (self);
 
350
  self->priv->requests = g_queue_new ();
 
351
}
 
352
 
 
353
GType
 
354
unity_settings_secret_agent_get_type (void)
 
355
{
 
356
  static volatile gsize unity_settings_secret_agent_type_id__volatile = 0;
 
357
  if (g_once_init_enter (&unity_settings_secret_agent_type_id__volatile))
 
358
    {
 
359
      static const GTypeInfo g_define_type_info =
 
360
        {
 
361
          sizeof (UnitySettingsSecretAgentClass),
 
362
          (GBaseInitFunc) NULL,
 
363
          (GBaseFinalizeFunc) NULL,
 
364
          (GClassInitFunc) unity_settings_secret_agent_class_init,
 
365
          (GClassFinalizeFunc) NULL,
 
366
          NULL,
 
367
          sizeof (UnitySettingsSecretAgent),
 
368
          0,
 
369
          (GInstanceInitFunc) unity_settings_secret_agent_instance_init,
 
370
          NULL
 
371
        };
 
372
      GType unity_settings_secret_agent_type_id;
 
373
      unity_settings_secret_agent_type_id = g_type_register_static (NM_TYPE_SECRET_AGENT,
 
374
                                                                    "UnitySettingsSecretAgent",
 
375
                                                                    &g_define_type_info,
 
376
                                                                    0);
 
377
      g_once_init_leave (&unity_settings_secret_agent_type_id__volatile,
 
378
                         unity_settings_secret_agent_type_id);
 
379
    }
 
380
 
 
381
  return unity_settings_secret_agent_type_id__volatile;
 
382
}