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 static DBusGProxy *dbus_connect (MoonshotError **error)
57 DBusConnection *connection;
59 DBusGConnection *g_connection;
62 dbus_bool_t name_has_owner;
64 g_return_val_if_fail (*error == NULL, NULL);
66 dbus_error_init (&dbus_error);
68 /* Check for moonshot server and start the service if possible. We use
69 * libdbus here because dbus-glib doesn't handle autostarting the service.
70 * If/when we move to GDBus this code can become a one-liner.
73 connection = dbus_bus_get (DBUS_BUS_SESSION, &dbus_error);
75 if (dbus_error_is_set (&dbus_error)) {
76 *error = moonshot_error_new (MOONSHOT_ERROR_IPC_ERROR,
79 dbus_error_free (&dbus_error);
83 name_has_owner = dbus_bus_name_has_owner (connection,
87 if (dbus_error_is_set (&dbus_error)) {
88 *error = moonshot_error_new (MOONSHOT_ERROR_IPC_ERROR,
91 dbus_error_free (&dbus_error);
95 if (! name_has_owner) {
96 dbus_bus_start_service_by_name (connection,
102 if (dbus_error_is_set (&dbus_error)) {
103 if (strcmp (dbus_error.name + 27, "ServiceUnknown") == 0) {
104 /* Missing .service file; the moonshot-ui install is broken */
105 *error = moonshot_error_new (MOONSHOT_ERROR_UNABLE_TO_START_SERVICE,
106 "The Moonshot service was not found. "
107 "Please make sure that moonshot-ui is "
108 "correctly installed.");
110 *error = moonshot_error_new (MOONSHOT_ERROR_IPC_ERROR,
114 dbus_error_free (&dbus_error);
119 /* Now the service should be running */
122 g_connection = dbus_g_bus_get (DBUS_BUS_SESSION, &g_error);
124 if (g_error != NULL) {
125 *error = moonshot_error_new (MOONSHOT_ERROR_IPC_ERROR,
128 g_error_free (g_error);
132 g_proxy = dbus_g_proxy_new_for_name_owner (g_connection,
138 if (g_error != NULL) {
139 *error = moonshot_error_new (MOONSHOT_ERROR_IPC_ERROR,
142 g_error_free (g_error);
149 static DBusGProxy *get_dbus_proxy (MoonshotError **error)
151 static DBusGProxy *dbus_proxy = NULL;
152 static GStaticMutex init_lock = G_STATIC_MUTEX_INIT;
154 g_static_mutex_lock (&init_lock);
156 if (dbus_proxy == NULL)
157 dbus_proxy = dbus_connect (error);
159 if (dbus_proxy != NULL)
160 g_object_ref (dbus_proxy);
162 g_static_mutex_unlock (&init_lock);
167 int moonshot_get_identity (const char *nai,
168 const char *password,
172 char **server_certificate_hash_out,
173 char **ca_certificate_out,
174 char **subject_name_constraint_out,
175 char **subject_alt_name_constraint_out,
176 MoonshotError **error)
178 GError *g_error = NULL;
179 DBusGProxy *dbus_proxy;
182 dbus_proxy = get_dbus_proxy (error);
187 g_return_if_fail (DBUS_IS_G_PROXY (dbus_proxy));
189 dbus_g_proxy_call (dbus_proxy,
193 G_TYPE_STRING, password,
194 G_TYPE_STRING, service,
196 G_TYPE_STRING, nai_out,
197 G_TYPE_STRING, password_out,
198 G_TYPE_STRING, server_certificate_hash_out,
199 G_TYPE_STRING, ca_certificate_out,
200 G_TYPE_STRING, subject_name_constraint_out,
201 G_TYPE_STRING, subject_alt_name_constraint_out,
202 G_TYPE_BOOLEAN, &success,
205 g_object_unref (dbus_proxy);
207 if (g_error != NULL) {
208 *error = moonshot_error_new (MOONSHOT_ERROR_IPC_ERROR,
213 if (success == FALSE) {
214 *error = moonshot_error_new (MOONSHOT_ERROR_NO_IDENTITY_SELECTED,
215 "No identity was returned by the Moonshot "
223 int moonshot_get_default_identity (char **nai_out,
225 char **server_certificate_hash_out,
226 char **ca_certificate_out,
227 char **subject_name_constraint_out,
228 char **subject_alt_name_constraint_out,
229 MoonshotError **error)
231 GError *g_error = NULL;
232 DBusGProxy *dbus_proxy;
235 dbus_proxy = get_dbus_proxy (error);
240 g_return_if_fail (DBUS_IS_G_PROXY (dbus_proxy));
242 dbus_g_proxy_call (dbus_proxy,
243 "GetDefaultIdentity",
246 G_TYPE_STRING, nai_out,
247 G_TYPE_STRING, password_out,
248 G_TYPE_STRING, server_certificate_hash_out,
249 G_TYPE_STRING, ca_certificate_out,
250 G_TYPE_STRING, subject_name_constraint_out,
251 G_TYPE_STRING, subject_alt_name_constraint_out,
252 G_TYPE_BOOLEAN, &success,
255 g_object_unref (dbus_proxy);
257 if (g_error != NULL) {
258 *error = moonshot_error_new (MOONSHOT_ERROR_IPC_ERROR,
263 if (success == FALSE) {
264 *error = moonshot_error_new (MOONSHOT_ERROR_NO_IDENTITY_SELECTED,
265 "No identity was returned by the Moonshot "