Line data Source code
1 : /*
2 : * gnome-keyring
3 : *
4 : * Copyright (C) 2008 Stefan Walter
5 : *
6 : * This program is free software; you can redistribute it and/or modify
7 : * it under the terms of the GNU Lesser General Public License as
8 : * published by the Free Software Foundation; either version 2.1 of
9 : * the License, or (at your option) any later version.
10 : *
11 : * This program is distributed in the hope that it will be useful, but
12 : * WITHOUT ANY WARRANTY; without even the implied warranty of
13 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 : * Lesser General Public License for more details.
15 : *
16 : * You should have received a copy of the GNU Lesser General Public
17 : * License along with this program; if not, see
18 : * <http://www.gnu.org/licenses/>.
19 : */
20 :
21 : #include "config.h"
22 :
23 : #include "gkd-secret-dispatch.h"
24 : #include "gkd-secret-error.h"
25 : #include "gkd-secret-secret.h"
26 : #include "gkd-secret-service.h"
27 : #include "gkd-secret-session.h"
28 :
29 : #include "egg/egg-secure-memory.h"
30 :
31 : #include <glib-object.h>
32 :
33 : #include <string.h>
34 :
35 : GkdSecretSecret *
36 1 : gkd_secret_secret_new (GkdSecretSession *session,
37 : gconstpointer parameter,
38 : gsize n_parameter,
39 : gconstpointer value,
40 : gsize n_value)
41 : {
42 1 : return gkd_secret_secret_new_take_memory (session,
43 : g_memdup (parameter, n_parameter),
44 : n_parameter,
45 : g_memdup (value, n_value),
46 : n_value);
47 : }
48 :
49 : static void
50 0 : destroy_with_owned_memory (gpointer data)
51 : {
52 0 : GkdSecretSecret *secret = data;
53 0 : g_free (secret->parameter);
54 0 : g_free (secret->value);
55 0 : }
56 :
57 : GkdSecretSecret*
58 1 : gkd_secret_secret_new_take_memory (GkdSecretSession *session,
59 : gpointer parameter, gsize n_parameter,
60 : gpointer value, gsize n_value)
61 : {
62 : GkdSecretSecret *secret;
63 :
64 1 : g_return_val_if_fail (GKD_SECRET_IS_SESSION (session), NULL);
65 :
66 1 : secret = g_slice_new0 (GkdSecretSecret);
67 1 : secret->session = g_object_ref (session);
68 1 : secret->parameter = parameter;
69 1 : secret->n_parameter = n_parameter;
70 1 : secret->value = value;
71 1 : secret->n_value = n_value;
72 :
73 1 : secret->destroy_func = destroy_with_owned_memory;
74 1 : secret->destroy_data = secret;
75 :
76 1 : return secret;
77 : }
78 :
79 : GkdSecretSecret*
80 18 : gkd_secret_secret_parse (GkdSecretService *service,
81 : const char *sender,
82 : GVariant *variant,
83 : GError **error)
84 : {
85 18 : GkdSecretSecret *secret = NULL;
86 : GkdSecretSession *session;
87 : const char *parameter, *value, *path, *content_type;
88 : gsize n_parameter, n_value;
89 : GVariant *parameter_variant, *value_variant;
90 :
91 18 : g_return_val_if_fail (GKD_SECRET_IS_SERVICE (service), NULL);
92 18 : g_return_val_if_fail (variant, NULL);
93 18 : g_return_val_if_fail (sender, NULL);
94 :
95 18 : g_variant_get (variant, "(&o^&ay^&ay&s)", &path, NULL, NULL, &content_type);
96 :
97 : /* parameter */
98 18 : parameter_variant = g_variant_get_child_value (variant, 1);
99 18 : parameter = g_variant_get_fixed_array (parameter_variant, &n_parameter, sizeof (guchar));
100 :
101 : /* value */
102 18 : value_variant = g_variant_get_child_value (variant, 2);
103 18 : value = g_variant_get_fixed_array (value_variant, &n_value, sizeof (guchar));
104 :
105 : /* Try to lookup the session */
106 18 : session = gkd_secret_service_lookup_session (service, path, sender);
107 18 : if (session == NULL) {
108 0 : g_set_error_literal (error, GKD_SECRET_ERROR,
109 : GKD_SECRET_ERROR_NO_SESSION,
110 : "The session wrapping the secret does not exist");
111 0 : goto out;
112 : }
113 :
114 18 : secret = g_slice_new0 (GkdSecretSecret);
115 18 : secret->session = g_object_ref (session);
116 18 : secret->parameter = g_memdup (parameter, n_parameter);
117 18 : secret->n_parameter = n_parameter;
118 18 : secret->value = g_memdup (value, n_value);
119 18 : secret->n_value = n_value;
120 :
121 18 : out:
122 18 : g_variant_unref (parameter_variant);
123 18 : g_variant_unref (value_variant);
124 :
125 18 : return secret;
126 : }
127 :
128 : GVariant *
129 0 : gkd_secret_secret_append (GkdSecretSecret *secret)
130 : {
131 0 : const gchar *content_type = "text/plain";
132 : const gchar *path;
133 : GVariant *parameter, *value;
134 :
135 0 : path = gkd_secret_dispatch_get_object_path (GKD_SECRET_DISPATCH (secret->session));
136 0 : g_return_val_if_fail (path, NULL);
137 :
138 0 : parameter = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE,
139 0 : secret->parameter, secret->n_parameter,
140 : sizeof (guchar));
141 0 : value = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE,
142 0 : secret->value, secret->n_value,
143 : sizeof (guchar));
144 :
145 0 : return g_variant_new ("(o@ay@ays)", path, parameter, value, content_type);
146 : }
147 :
148 : void
149 20 : gkd_secret_secret_free (gpointer data)
150 : {
151 : GkdSecretSecret *secret;
152 :
153 20 : if (!data)
154 2 : return;
155 :
156 18 : secret = data;
157 :
158 : /*
159 : * These are not usually actual plain text secrets. However in
160 : * the case that they are, we want to clear them from memory.
161 : *
162 : * This is not foolproof in any way. If they're plaintext, they would
163 : * have been sent over DBus, and through all sorts of processes.
164 : */
165 :
166 18 : egg_secure_clear (secret->parameter, secret->n_parameter);
167 18 : egg_secure_clear (secret->value, secret->n_value);
168 :
169 18 : g_object_unref (secret->session);
170 :
171 : /* Call the destructor of memory */
172 18 : if (secret->destroy_func)
173 0 : (secret->destroy_func) (secret->destroy_data);
174 :
175 18 : g_slice_free (GkdSecretSecret, secret);
176 : }
|