From: Sam Thursfield Date: Tue, 5 Jul 2011 10:49:02 +0000 (+0100) Subject: Client library: make MT-safe; add get_default_identity() X-Git-Tag: 0.7.1~217 X-Git-Url: http://www.project-moonshot.org/gitweb/?p=moonshot-ui.git;a=commitdiff_plain;h=81d5fdbb22f5d346bd4cbf9eb82317e1dad913f5 Client library: make MT-safe; add get_default_identity() --- diff --git a/libmoonshot/libmoonshot-dbus.c b/libmoonshot/libmoonshot-dbus.c index 04d6da6..17a7246 100644 --- a/libmoonshot/libmoonshot-dbus.c +++ b/libmoonshot/libmoonshot-dbus.c @@ -52,8 +52,6 @@ * waiting for calls. */ -static DBusGProxy *moonshot_dbus_proxy = NULL; - static DBusGProxy *dbus_connect (MoonshotError **error) { DBusConnection *connection; @@ -148,6 +146,24 @@ static DBusGProxy *dbus_connect (MoonshotError **error) return g_proxy; } +static DBusGProxy *get_dbus_proxy (MoonshotError **error) +{ + static DBusGProxy *dbus_proxy = NULL; + static GStaticMutex init_lock = G_STATIC_MUTEX_INIT; + + g_static_mutex_lock (&init_lock); + + if (dbus_proxy == NULL) + dbus_proxy = dbus_connect (error); + + if (dbus_proxy != NULL) + g_object_ref (dbus_proxy); + + g_static_mutex_unlock (&init_lock); + + return dbus_proxy; +} + int moonshot_get_identity (const char *nai, const char *password, const char *service, @@ -159,18 +175,18 @@ int moonshot_get_identity (const char *nai, char **subject_alt_name_constraint_out, MoonshotError **error) { - GError *g_error = NULL; - int success; + GError *g_error = NULL; + DBusGProxy *dbus_proxy; + int success; - if (moonshot_dbus_proxy == NULL) - moonshot_dbus_proxy = dbus_connect (error); + dbus_proxy = get_dbus_proxy (error); if (*error != NULL) return; - g_return_if_fail (DBUS_IS_G_PROXY (moonshot_dbus_proxy)); + g_return_if_fail (DBUS_IS_G_PROXY (dbus_proxy)); - dbus_g_proxy_call (moonshot_dbus_proxy, + dbus_g_proxy_call (dbus_proxy, "GetIdentity", &g_error, G_TYPE_STRING, nai, @@ -186,6 +202,8 @@ int moonshot_get_identity (const char *nai, G_TYPE_BOOLEAN, &success, G_TYPE_INVALID); + g_object_unref (dbus_proxy); + if (g_error != NULL) { *error = moonshot_error_new (MOONSHOT_ERROR_IPC_ERROR, g_error->message); @@ -202,13 +220,52 @@ int moonshot_get_identity (const char *nai, return TRUE; } +int moonshot_get_default_identity (char **nai_out, + char **password_out, + char **server_certificate_hash_out, + char **ca_certificate_out, + char **subject_name_constraint_out, + char **subject_alt_name_constraint_out, + MoonshotError **error) +{ + GError *g_error = NULL; + DBusGProxy *dbus_proxy; + int success = FALSE; + + dbus_proxy = get_dbus_proxy (error); + + if (*error != NULL) + return FALSE; + g_return_if_fail (DBUS_IS_G_PROXY (dbus_proxy)); - /** - * Returns the default identity - most recently used. - * - * @param nai_out NAI stored in the ID card - * @param password_out Password stored in the ID card - * - * @return true on success, false if no identities are stored - */ + dbus_g_proxy_call (dbus_proxy, + "GetDefaultIdentity", + &g_error, + G_TYPE_INVALID, + G_TYPE_STRING, nai_out, + G_TYPE_STRING, password_out, + G_TYPE_STRING, server_certificate_hash_out, + G_TYPE_STRING, ca_certificate_out, + G_TYPE_STRING, subject_name_constraint_out, + G_TYPE_STRING, subject_alt_name_constraint_out, + G_TYPE_BOOLEAN, &success, + G_TYPE_INVALID); + + g_object_unref (dbus_proxy); + + if (g_error != NULL) { + *error = moonshot_error_new (MOONSHOT_ERROR_IPC_ERROR, + g_error->message); + return FALSE; + } + + if (success == FALSE) { + *error = moonshot_error_new (MOONSHOT_ERROR_NO_IDENTITY_SELECTED, + "No identity was returned by the Moonshot " + "user interface."); + return FALSE; + } + + return TRUE; +} diff --git a/libmoonshot/libmoonshot.h b/libmoonshot/libmoonshot.h index 65924b7..2429314 100644 --- a/libmoonshot/libmoonshot.h +++ b/libmoonshot/libmoonshot.h @@ -55,10 +55,10 @@ void moonshot_error_free (MoonshotError *error); * @password: Password for the identity, or %NULL. * @service: Service constraint for the required identity, or %NULL. * @nai_out: A pointer to a string which receives the name and issuer of the - * selected identity. + * selected identity. * @password_out: A pointer to a string which receives the password. * @server_certificate_hash_out: Receives a hash of the identity server's - * certificate, or %NULL. + * certificate, or %NULL. * @ca_certificate_out: The CA certificate, if @server_certificate_hash was * %NULL. * @subject_name_constraint_out: Set if @ca_certificate is set, otherwise %NULL. @@ -94,4 +94,32 @@ int moonshot_get_identity (const char *nai, char **subject_alt_name_constraint_out, MoonshotError **error); +/** + * moonshot_get_default_identity: + * @nai_out: A pointer to a string which receives the name and issuer of the + * identity. + * @password_out: A pointer to a string which receives the password. + * @server_certificate_hash_out: Receives a hash of the identity server's + * certificate, or %NULL. + * @ca_certificate_out: The CA certificate, if @server_certificate_hash was + * %NULL. + * @subject_name_constraint_out: Set if @ca_certificate is set, otherwise %NULL. + * @subject_alt_name_constraint_out: Set if @ca_certificate is set, otherwise + * %NULL. + * @error: Return location for a #MoonshotError, or %NULL. + * + * This function calls the Moonshot server to request the default identity + * (the one most recently used). Its semantics are otherwise the same as + * moonshot_get_identity(). + * + * Return value: %TRUE if an identity was available, otherwise %FALSE. + */ +int moonshot_default_get_identity (char **nai_out, + char **password_out, + char **server_certificate_hash_out, + char **ca_certificate_out, + char **subject_name_constraint_out, + char **subject_alt_name_constraint_out, + MoonshotError **error); + #endif diff --git a/src/dbus-client.vala b/src/dbus-client.vala index de30262..3844eef 100644 --- a/src/dbus-client.vala +++ b/src/dbus-client.vala @@ -3,7 +3,8 @@ interface Moonshot : Object { public abstract bool get_identity (string nai, string password, string service, out string nai_out, out string password_out, out string server_certificate_hash, out string ca_certificate, out string subject_name_constraint, out string subject_alt_name_constraint) throws DBus.Error; - public abstract bool get_default_identity (out string nai_out, out string password_out) throws DBus.Error; + public abstract bool get_default_identity (out string nai_out, out string password_out, + out string server_certificate_hash, out string ca_certificate, out string subject_name_constraint, out string subject_alt_name_constraint) throws DBus.Error; } void main () { @@ -16,7 +17,12 @@ void main () { "/org/janet/moonshot"); - if (demo.get_default_identity (out nai_out, out password_out)) + if (demo.get_default_identity (out nai_out, + out password_out, + out certificate_out, + out a, + out b, + out c)) { stdout.printf ("default identity: %s %s\n", nai_out, password_out); } diff --git a/src/moonshot-server.vala b/src/moonshot-server.vala index f83d5ea..145d6bf 100644 --- a/src/moonshot-server.vala +++ b/src/moonshot-server.vala @@ -54,7 +54,11 @@ public class MoonshotServer : Object { } public async bool get_default_identity (out string nai_out, - out string password_out) + out string password_out, + out string server_certificate_hash, + out string ca_certificate, + out string subject_name_constraint, + out string subject_alt_name_constraint) { var request = new IdentityRequest.default (main_window); request.set_callback ((IdentityRequest) => get_default_identity.callback()); @@ -63,12 +67,18 @@ public class MoonshotServer : Object { nai_out = ""; password_out = ""; + server_certificate_hash = ""; + ca_certificate = ""; + subject_name_constraint = ""; + subject_alt_name_constraint = ""; if (request.id_card != null) { nai_out = request.id_card.nai; password_out = request.id_card.password; + server_certificate_hash = "certificate"; + // User should have been prompted if there was no p/w. return_val_if_fail (nai_out != null, false); return_val_if_fail (password_out != null, false); diff --git a/tests/basic.c b/tests/basic.c index 8bd09a0..0d1e127 100644 --- a/tests/basic.c +++ b/tests/basic.c @@ -2,32 +2,79 @@ #include "libmoonshot.h" -void test_connect () +/* FIXME: Using XDG_HOME_DIR and a test runner, we could give + * moonshot-ui a set of test identities and assert that they + * are returned correctly + */ + +gpointer test_func (gpointer data) { + MoonshotError **error = data; + gboolean success; + char *nai, *password, *server_certificate_hash, *ca_certificate, *subject_name_constraint, *subject_alt_name_constraint; - int success; + + success = moonshot_get_default_identity (&nai, + &password, + &server_certificate_hash, + &ca_certificate, + &subject_name_constraint, + &subject_alt_name_constraint, + error); + + g_print ("Got id: %s %s\n", nai, password); + + return GINT_TO_POINTER (success); +} + + +void test_connect () +{ MoonshotError *error = NULL; + gboolean success; + + success = GPOINTER_TO_INT (test_func (&error)); + + if (success) + return; + + g_print ("FAIL: %s\n", error->message); + g_assert_not_reached (); +} + +void test_multithread () +{ + const int N = 100; + + GThread *thread[N]; + MoonshotError *error[N]; + gboolean success[N]; + + GError *g_error = NULL; + int i; + + for (i=0; imessage); - } else { - g_print ("PASS\n"); + for (i=0; imessage); + g_assert_not_reached (); + } } } @@ -35,6 +82,7 @@ void test_connect () * - server not available (dbus fail) * - no identities available (moonshot fail) * - valgrind + * - mt */ int main (int argc, char *argv[]) @@ -43,6 +91,7 @@ int main (int argc, char *argv[]) g_test_init (&argc, &argv, NULL); g_test_add_func ("/basic/connect", test_connect); + g_test_add_func ("/basic/multithread", test_multithread); g_test_run (); }