1 /*
2 * libvirt-gobject-secret.c: libvirt glib integration
3 *
4 * Copyright (C) 2008 Daniel P. Berrange
5 * Copyright (C) 2010-2011 Red Hat, Inc.
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 Public
18 * License along with this library. If not, see
19 * <http://www.gnu.org/licenses/>.
20 *
21 * Author: Daniel P. Berrange <berrange@redhat.com>
22 */
23
24 #include <config.h>
25
26 #include <libvirt/virterror.h>
27 #include <string.h>
28
29 #include "libvirt-glib/libvirt-glib.h"
30 #include "libvirt-gobject/libvirt-gobject.h"
31 #include "libvirt-gobject-compat.h"
32
33 #define GVIR_SECRET_GET_PRIVATE(obj) \
34 (G_TYPE_INSTANCE_GET_PRIVATE((obj), GVIR_TYPE_SECRET, GVirSecretPrivate))
35
36 struct _GVirSecretPrivate
37 {
38 virSecretPtr handle;
39 gchar uuid[VIR_UUID_STRING_BUFLEN];
40 };
41
42 G_DEFINE_TYPE_WITH_PRIVATE(GVirSecret, gvir_secret, G_TYPE_OBJECT);
43
44
45 enum {
46 PROP_0,
47 PROP_HANDLE,
48 };
49
50
51 #define GVIR_SECRET_ERROR gvir_secret_error_quark()
52
53
54 static GQuark
gvir_secret_error_quark(void)55 gvir_secret_error_quark(void)
56 {
57 return g_quark_from_static_string("gvir-secret");
58 }
59
gvir_secret_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)60 static void gvir_secret_get_property(GObject *object,
61 guint prop_id,
62 GValue *value,
63 GParamSpec *pspec)
64 {
65 GVirSecret *secret = GVIR_SECRET(object);
66 GVirSecretPrivate *priv = secret->priv;
67
68 switch (prop_id) {
69 case PROP_HANDLE:
70 g_value_set_boxed(value, priv->handle);
71 break;
72
73 default:
74 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
75 }
76 }
77
78
gvir_secret_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)79 static void gvir_secret_set_property(GObject *object,
80 guint prop_id,
81 const GValue *value,
82 GParamSpec *pspec)
83 {
84 GVirSecret *secret = GVIR_SECRET(object);
85 GVirSecretPrivate *priv = secret->priv;
86
87 switch (prop_id) {
88 case PROP_HANDLE:
89 if (priv->handle)
90 virSecretFree(priv->handle);
91 priv->handle = g_value_dup_boxed(value);
92 break;
93
94 default:
95 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
96 }
97 }
98
99
gvir_secret_finalize(GObject * object)100 static void gvir_secret_finalize(GObject *object)
101 {
102 GVirSecret *secret = GVIR_SECRET(object);
103 GVirSecretPrivate *priv = secret->priv;
104
105 virSecretFree(priv->handle);
106
107 G_OBJECT_CLASS(gvir_secret_parent_class)->finalize(object);
108 }
109
110
gvir_secret_constructed(GObject * object)111 static void gvir_secret_constructed(GObject *object)
112 {
113 GVirSecret *secret = GVIR_SECRET(object);
114 GVirSecretPrivate *priv = secret->priv;
115
116 G_OBJECT_CLASS(gvir_secret_parent_class)->constructed(object);
117
118 /* xxx we may want to turn this into an initable */
119 if (virSecretGetUUIDString(priv->handle, priv->uuid) < 0)
120 gvir_warning("Failed to get secret UUID on %p", priv->handle);
121 }
122
123
gvir_secret_class_init(GVirSecretClass * klass)124 static void gvir_secret_class_init(GVirSecretClass *klass)
125 {
126 GObjectClass *object_class = G_OBJECT_CLASS (klass);
127
128 object_class->finalize = gvir_secret_finalize;
129 object_class->get_property = gvir_secret_get_property;
130 object_class->set_property = gvir_secret_set_property;
131 object_class->constructed = gvir_secret_constructed;
132
133 g_object_class_install_property(object_class,
134 PROP_HANDLE,
135 g_param_spec_boxed("handle",
136 "Handle",
137 "The secret handle",
138 GVIR_TYPE_SECRET_HANDLE,
139 G_PARAM_READABLE |
140 G_PARAM_WRITABLE |
141 G_PARAM_CONSTRUCT_ONLY |
142 G_PARAM_STATIC_STRINGS));
143 }
144
145
gvir_secret_init(GVirSecret * secret)146 static void gvir_secret_init(GVirSecret *secret)
147 {
148 secret->priv = GVIR_SECRET_GET_PRIVATE(secret);
149 }
150
151 typedef struct virSecret GVirSecretHandle;
152
153 static GVirSecretHandle*
gvir_secret_handle_copy(GVirSecretHandle * src)154 gvir_secret_handle_copy(GVirSecretHandle *src)
155 {
156 virSecretRef((virSecretPtr)src);
157 return src;
158 }
159
160 static void
gvir_secret_handle_free(GVirSecretHandle * src)161 gvir_secret_handle_free(GVirSecretHandle *src)
162 {
163 virSecretFree((virSecretPtr)src);
164 }
165
G_DEFINE_BOXED_TYPE(GVirSecretHandle,gvir_secret_handle,gvir_secret_handle_copy,gvir_secret_handle_free)166 G_DEFINE_BOXED_TYPE(GVirSecretHandle, gvir_secret_handle,
167 gvir_secret_handle_copy, gvir_secret_handle_free)
168
169 const gchar *gvir_secret_get_uuid(GVirSecret *secret)
170 {
171 g_return_val_if_fail(GVIR_IS_SECRET(secret), NULL);
172
173 return secret->priv->uuid;
174 }
175
176
177 /**
178 * gvir_secret_get_config:
179 * @secret: the secret
180 * @flags: the flags
181 * @err: Place-holder for possible errors
182 *
183 * Returns: (transfer full): the config. The returned object should be
184 * unreffed with g_object_unref() when no longer needed.
185
186 */
gvir_secret_get_config(GVirSecret * secret,guint flags,GError ** err)187 GVirConfigSecret *gvir_secret_get_config(GVirSecret *secret,
188 guint flags,
189 GError **err)
190 {
191 GVirSecretPrivate *priv;
192 gchar *xml;
193
194 g_return_val_if_fail(GVIR_IS_SECRET(secret), NULL);
195 g_return_val_if_fail(err == NULL || *err == NULL, NULL);
196
197 priv = secret->priv;
198 if (!(xml = virSecretGetXMLDesc(priv->handle, flags))) {
199 gvir_set_error_literal(err, GVIR_SECRET_ERROR,
200 0,
201 "Unable to get secret XML config");
202 return NULL;
203 }
204
205 GVirConfigSecret *conf = gvir_config_secret_new_from_xml(xml, err);
206
207 free(xml);
208 return conf;
209 }
210