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