1 /* libmoonshot - Moonshot client library
2 * Copyright (c) 2011, JANET(UK)
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of JANET(UK) nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * Author: Sam Thursfield <samthursfield@codethink.co.uk>
35 #include <dbus/dbus-glib.h>
36 #include <dbus/dbus.h>
38 #include "libmoonshot.h"
39 #include "libmoonshot-common.h"
41 #define MOONSHOT_DBUS_NAME "org.janet.Moonshot"
42 #define MOONSHOT_DBUS_PATH "/org/janet/moonshot"
44 /* This library is overly complicated currently due to the requirement
45 * that it work on Debian Squeeze - this has GLib 2.24 which requires us
46 * to use dbus-glib instead of GDBus. If/when this requirement is
47 * dropped the DBus version of the library can be greatly simplified.
50 /* Note that ideally this library would not depend on GLib. This would be
51 * possible using libdbus directly and running our own message loop while
55 void moonshot_free (void *data)
60 static DBusGProxy *dbus_connect (MoonshotError **error)
62 DBusConnection *connection;
64 DBusGConnection *g_connection;
67 dbus_bool_t name_has_owner;
69 g_return_val_if_fail (*error == NULL, NULL);
71 dbus_error_init (&dbus_error);
73 /* Check for moonshot server and start the service if possible. We use
74 * libdbus here because dbus-glib doesn't handle autostarting the service.
75 * If/when we move to GDBus this code can become a one-liner.
78 connection = dbus_bus_get (DBUS_BUS_SESSION, &dbus_error);
80 if (dbus_error_is_set (&dbus_error)) {
81 *error = moonshot_error_new (MOONSHOT_ERROR_IPC_ERROR,
84 dbus_error_free (&dbus_error);
88 name_has_owner = dbus_bus_name_has_owner (connection,
92 if (dbus_error_is_set (&dbus_error)) {
93 *error = moonshot_error_new (MOONSHOT_ERROR_IPC_ERROR,
96 dbus_error_free (&dbus_error);
100 if (! name_has_owner) {
101 dbus_bus_start_service_by_name (connection,
107 if (dbus_error_is_set (&dbus_error)) {
108 if (strcmp (dbus_error.name + 27, "ServiceUnknown") == 0) {
109 /* Missing .service file; the moonshot-ui install is broken */
110 *error = moonshot_error_new (MOONSHOT_ERROR_UNABLE_TO_START_SERVICE,
111 "The Moonshot service was not found. "
112 "Please make sure that moonshot-ui is "
113 "correctly installed.");
115 *error = moonshot_error_new (MOONSHOT_ERROR_IPC_ERROR,
119 dbus_error_free (&dbus_error);
124 /* Now the service should be running */
127 g_connection = dbus_g_bus_get (DBUS_BUS_SESSION, &g_error);
129 if (g_error != NULL) {
130 *error = moonshot_error_new (MOONSHOT_ERROR_IPC_ERROR,
133 g_error_free (g_error);
137 g_proxy = dbus_g_proxy_new_for_name_owner (g_connection,
143 if (g_error != NULL) {
144 *error = moonshot_error_new (MOONSHOT_ERROR_IPC_ERROR,
147 g_error_free (g_error);
154 static DBusGProxy *get_dbus_proxy (MoonshotError **error)
156 static DBusGProxy *dbus_proxy = NULL;
157 static GStaticMutex init_lock = G_STATIC_MUTEX_INIT;
159 g_static_mutex_lock (&init_lock);
161 if (dbus_proxy == NULL) {
162 /* Make sure GObject is initialised, in case we are the only user
163 * of GObject in the process
166 dbus_proxy = dbus_connect (error);
169 if (dbus_proxy != NULL)
170 g_object_ref (dbus_proxy);
172 g_static_mutex_unlock (&init_lock);
177 int moonshot_get_identity (const char *nai,
178 const char *password,
182 char **server_certificate_hash_out,
183 char **ca_certificate_out,
184 char **subject_name_constraint_out,
185 char **subject_alt_name_constraint_out,
186 MoonshotError **error)
188 GError *g_error = NULL;
189 DBusGProxy *dbus_proxy;
192 dbus_proxy = get_dbus_proxy (error);
197 g_return_if_fail (DBUS_IS_G_PROXY (dbus_proxy));
199 dbus_g_proxy_call (dbus_proxy,
203 G_TYPE_STRING, password,
204 G_TYPE_STRING, service,
206 G_TYPE_STRING, nai_out,
207 G_TYPE_STRING, password_out,
208 G_TYPE_STRING, server_certificate_hash_out,
209 G_TYPE_STRING, ca_certificate_out,
210 G_TYPE_STRING, subject_name_constraint_out,
211 G_TYPE_STRING, subject_alt_name_constraint_out,
212 G_TYPE_BOOLEAN, &success,
215 g_object_unref (dbus_proxy);
217 if (g_error != NULL) {
218 *error = moonshot_error_new (MOONSHOT_ERROR_IPC_ERROR,
223 if (success == FALSE) {
224 *error = moonshot_error_new (MOONSHOT_ERROR_NO_IDENTITY_SELECTED,
225 "No identity was returned by the Moonshot "
233 int moonshot_get_default_identity (char **nai_out,
235 char **server_certificate_hash_out,
236 char **ca_certificate_out,
237 char **subject_name_constraint_out,
238 char **subject_alt_name_constraint_out,
239 MoonshotError **error)
241 GError *g_error = NULL;
242 DBusGProxy *dbus_proxy;
245 dbus_proxy = get_dbus_proxy (error);
250 g_return_if_fail (DBUS_IS_G_PROXY (dbus_proxy));
252 dbus_g_proxy_call (dbus_proxy,
253 "GetDefaultIdentity",
256 G_TYPE_STRING, nai_out,
257 G_TYPE_STRING, password_out,
258 G_TYPE_STRING, server_certificate_hash_out,
259 G_TYPE_STRING, ca_certificate_out,
260 G_TYPE_STRING, subject_name_constraint_out,
261 G_TYPE_STRING, subject_alt_name_constraint_out,
262 G_TYPE_BOOLEAN, &success,
265 g_object_unref (dbus_proxy);
267 if (g_error != NULL) {
268 *error = moonshot_error_new (MOONSHOT_ERROR_IPC_ERROR,
273 if (success == FALSE) {
274 *error = moonshot_error_new (MOONSHOT_ERROR_NO_IDENTITY_SELECTED,
275 "No identity was returned by the Moonshot "