From 511bd16ff7bf9f3a205cd9b3ba3e7963dc9819dd Mon Sep 17 00:00:00 2001 From: Sam Thursfield Date: Mon, 18 Jul 2011 18:51:24 +0100 Subject: [PATCH] Implement web provisioning on Windows --- Makefile.am | 32 +++++------ libmoonshot/libmoonshot-dbus.c | 84 ++++++++++++++++++++++++++- libmoonshot/libmoonshot-msrpc.c | 57 +++++++++++++++++++ libmoonshot/libmoonshot.h | 46 ++++++++++++++- libmoonshot/libmoonshot.vapi | 53 ++++++++++++++++++ libmoonshot/moonshot-msrpc.idl | 16 +++++- src/moonshot-id.vala | 2 - src/moonshot-idcard-widget.vala | 3 +- src/moonshot-identities-manager.vala | 2 +- src/moonshot-msrpc.vapi | 6 ++ src/moonshot-server.vala | 86 +++++++++++++++++++--------- src/moonshot-utils.vala | 2 +- src/moonshot-webp-parser.vala | 106 ++++++++++------------------------- src/moonshot-window.vala | 43 ++++++++++---- 14 files changed, 399 insertions(+), 139 deletions(-) create mode 100644 libmoonshot/libmoonshot.vapi diff --git a/Makefile.am b/Makefile.am index 9ade16d..33bebef 100644 --- a/Makefile.am +++ b/Makefile.am @@ -5,8 +5,9 @@ SUBDIRS = po lib_LTLIBRARIES = libmoonshot/libmoonshot.la -bin_PROGRAMS = src/moonshot - +bin_PROGRAMS = \ + src/moonshot \ + src/moonshot-webp AM_CFLAGS = @@ -16,8 +17,8 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/libmoonshot AM_VALAFLAGS = \ - config.vapi \ - --pkg gtk+-2.0 + config.vapi \ + --pkg gio-2.0 libmoonshot_libmoonshot_la_CPPFLAGS = \ @@ -43,21 +44,24 @@ src_moonshot_SOURCES = \ src/moonshot-password-dialog.vala \ src/moonshot-utils.vala -src_moonshot_LDADD = \ - $(moonshot_LIBS) - -src_moonshot_CPPFLAGS = \ - $(moonshot_CFLAGS) \ - $(AM_CPPFLAGS) +src_moonshot_webp_SOURCES = \ + src/moonshot-webp-parser.vala \ + src/moonshot-id.vala +src_moonshot_VALAFLAGS = --pkg gtk+-2.0 $(AM_VALAFLAGS) +src_moonshot_CPPFLAGS = $(moonshot_CFLAGS) $(AM_CPPFLAGS) +src_moonshot_LDADD = $(moonshot_LIBS) +src_moonshot_webp_VALAFLAGS = --vapidir=$(top_srcdir)/libmoonshot --pkg libmoonshot $(AM_VALAFLAGS) +src_moonshot_webp_CPPFLAGS = $(moonshot_CFLAGS) $(AM_CPPFLAGS) +src_moonshot_webp_LDADD = $(moonshot_LIBS) ${top_builddir}/libmoonshot/libmoonshot.la if OS_WIN32 libmoonshot_libmoonshot_la_LDFLAGS = -no-undefined src_moonshot_CFLAGS = -mwindows -#src_moonshot_webp_CFLAGS = -mwindows +src_moonshot_webp_CFLAGS = -mwindows AM_CPPFLAGS += -DOS_WIN32 AM_VALAFLAGS += --define=OS_WIN32 @@ -71,12 +75,6 @@ endif if OS_LINUX -bin_PROGRAMS += src/moonshot-webp - -src_moonshot_webp_SOURCES = src/moonshot-webp-parser.vala src/moonshot-id.vala -src_moonshot_webp_CPPFLAGS = $(moonshot_CFLAGS) $(AM_CPPFLAGS) -src_moonshot_webp_LDADD = $(moonshot_LIBS) - ## Installing mime type data mimedir = $(datadir)/mime/packages mime_DATA = webprovisioning/moonshot.xml diff --git a/libmoonshot/libmoonshot-dbus.c b/libmoonshot/libmoonshot-dbus.c index b2a62d3..92ca58b 100644 --- a/libmoonshot/libmoonshot-dbus.c +++ b/libmoonshot/libmoonshot-dbus.c @@ -192,9 +192,9 @@ int moonshot_get_identity (const char *nai, dbus_proxy = get_dbus_proxy (error); if (*error != NULL) - return; + return FALSE; - g_return_if_fail (DBUS_IS_G_PROXY (dbus_proxy)); + g_return_val_if_fail (DBUS_IS_G_PROXY (dbus_proxy), FALSE); dbus_g_proxy_call (dbus_proxy, "GetIdentity", @@ -247,7 +247,7 @@ int moonshot_get_default_identity (char **nai_out, if (*error != NULL) return FALSE; - g_return_if_fail (DBUS_IS_G_PROXY (dbus_proxy)); + g_return_val_if_fail (DBUS_IS_G_PROXY (dbus_proxy), FALSE); dbus_g_proxy_call (dbus_proxy, "GetDefaultIdentity", @@ -279,3 +279,81 @@ int moonshot_get_default_identity (char **nai_out, return TRUE; } + +int moonshot_install_id_card (const char *display_name, + const char *user_name, + const char *password, + const char *realm, + char *rules_patterns[], + int rules_patterns_length, + char *rules_always_confirm[], + int rules_always_confirm_length, + char *services[], + int services_length, + const char *ca_cert, + const char *subject, + const char *subject_alt, + const char *server_cert, + MoonshotError **error) +{ + GError *g_error = NULL; + DBusGProxy *dbus_proxy; + int success = FALSE; + int i; + const char **rules_patterns_strv, + **rules_always_confirm_strv, + **services_strv; + + dbus_proxy = get_dbus_proxy (error); + + if (*error != NULL) + return FALSE; + + g_return_val_if_fail (DBUS_IS_G_PROXY (dbus_proxy), FALSE); + g_return_val_if_fail (rules_patterns_length == rules_always_confirm_length), FALSE); + + /* Marshall array and struct parameters for DBus */ + rules_patterns_strv = g_malloc ((rules_length + 1) * sizeof (const char *)); + rules_always_confirm_strv = g_malloc ((rules_length + 1) * sizeof (const char *)); + services_strv = g_malloc ((services_length + 1) * sizeof (const char *)); + + for (i = 0; i < rules_patterns_length; i ++) { + rules_pattern_strv[i] = rules_patterns[i]; + rules_always_confirm_strv[i] = rules_always_confirm[i]; + } + + for (i = 0; i < services_length; i ++) + services_strv[i] = services[i]; + + rules_pattern_strv[rules_patterns_length] = NULL; + rules_always_confirm_strv[rules_patterns_length] = NULL; + services_strv[services_length] = NULL; + + dbus_g_proxy_call (dbus_proxy, + "InstallIdCard", + &g_error, + G_TYPE_STRING, display_name, + G_TYPE_STRING, user_name, + G_TYPE_STRING, password, + G_TYPE_STRING, realm, + G_TYPE_STRV, rules_pattern_strv, + G_TYPE_STRV, rules_always_confirm_strv, + G_TYPE_STRV, services_strv, + G_TYPE_STRING, ca_cert, + G_TYPE_STRING, subject, + G_TYPE_STRING, subject_alt, + G_TYPE_STRING, server_cert, + G_TYPE_INVALID, + 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; + } + + return success; +} diff --git a/libmoonshot/libmoonshot-msrpc.c b/libmoonshot/libmoonshot-msrpc.c index 8345483..3563939 100644 --- a/libmoonshot/libmoonshot-msrpc.c +++ b/libmoonshot/libmoonshot-msrpc.c @@ -284,6 +284,10 @@ int moonshot_get_identity (const char *nai, rpc_async_call_init (&call); + if (nai == NULL) nai = ""; + if (password == NULL) password = ""; + if (service == NULL) service = ""; + *nai_out = NULL; *password_out = NULL; *server_certificate_hash_out = NULL; @@ -380,6 +384,59 @@ int moonshot_get_default_identity (char **nai_out, return TRUE; }; +int moonshot_install_id_card (const char *display_name, + const char *user_name, + const char *password, + const char *realm, + char *rules_patterns[], + int rules_patterns_length, + char *rules_always_confirm[], + int rules_always_confirm_length, + char *services[], + int services_length, + const char *ca_cert, + const char *subject, + const char *subject_alt, + const char *server_cert, + MoonshotError **error) +{ + int success = FALSE; + + init_rpc (error); + + if (user_name == NULL) user_name = ""; + if (password == NULL) password = ""; + if (realm == NULL) realm = ""; + if (ca_cert == NULL) ca_cert = ""; + if (subject == NULL) subject = ""; + if (subject_alt == NULL) subject_alt = ""; + if (server_cert == NULL) server_cert = ""; + + RPC_TRY_EXCEPT { + success = moonshot_install_id_card_rpc (display_name, + user_name, + password, + realm, + rules_patterns, + rules_patterns_length, + rules_always_confirm, + rules_always_confirm_length, + services, + services_length, + ca_cert, + subject, + subject_alt, + server_cert); + } + RPC_EXCEPT { + *error = moonshot_error_new_from_status (MOONSHOT_ERROR_IPC_ERROR, + RPC_GET_EXCEPTION_CODE ()); + } + RPC_END_EXCEPT + + return success; +} + BOOL WINAPI DllMain (HINSTANCE hinst, DWORD reason, void *reserved) diff --git a/libmoonshot/libmoonshot.h b/libmoonshot/libmoonshot.h index a324d61..670dd87 100644 --- a/libmoonshot/libmoonshot.h +++ b/libmoonshot/libmoonshot.h @@ -134,7 +134,7 @@ int moonshot_get_identity (const char *nai, * * Return value: %TRUE if an identity was available, otherwise %FALSE. */ -int moonshot_default_get_identity (char **nai_out, +int moonshot_get_default_identity (char **nai_out, char **password_out, char **server_certificate_hash_out, char **ca_certificate_out, @@ -142,4 +142,48 @@ int moonshot_default_get_identity (char **nai_out, char **subject_alt_name_constraint_out, MoonshotError **error); + +/** + * moonshot_install_id_card: + * @display_name: Display name of card + * @user_name: Username for identity, or %NULL + * @password: Password for identity, or %NULL + * @realm: Realm for identity, or %NULL + * @rules_patterns: Array of patterns for the service matching rules + * @rules_patterns_length: Length of @rules_patterns and @rules_always_confirm arrays + * @rules_always_confirm: Array of 'always confirm' flags corresponding to patterns + * @rules_always_confirm_length: Length of @rules_patterns and @rules_always_confirm arrays + * @services: Array of strings listing the services this identity provides + * @services_length: Length of @services array + * @ca_cert: The CA certificate, or %NULL + * @subject: Subject name constraint for @ca_cert, or %NULL + * @subject_alt: Subject alternative name constraint for @ca_cert, or %NULL + * @server_cert: Hash of the server certificate; required if @ca_cert is %NULL + * @error: Return location for a #MoonshotError. + * + * Calls the Moonshot server to add a new identity. The user will be prompted + * if they would like to add the ID card. + * + * The values for @rules_patterns_length and @rules_always_confirm_length should + * always be the same. They are present as separate parameters as a concession to + * the Vala bindings. + * + * Return value: %TRUE if the ID card was successfully added, %FALSE otherwise + */ +int moonshot_install_id_card (const char *display_name, + const char *user_name, + const char *password, + const char *realm, + char *rules_patterns[], + int rules_patterns_length, + char *rules_always_confirm[], + int rules_always_confirm_length, + char *services[], + int services_length, + const char *ca_cert, + const char *subject, + const char *subject_alt, + const char *server_cert, + MoonshotError **error); + #endif diff --git a/libmoonshot/libmoonshot.vapi b/libmoonshot/libmoonshot.vapi new file mode 100644 index 0000000..d927663 --- /dev/null +++ b/libmoonshot/libmoonshot.vapi @@ -0,0 +1,53 @@ +/* Vala binding between libmoonshot helper library */ + +[CCode (cheader_filename = "libmoonshot.h")] +namespace Moonshot { + [Compact] + [CCode (cname = "MoonshotError", free_function = "moonshot_error_free")] + public class Error { + public int code; + public string message; + } + + /* A service matching rule; duplicated in moonshot-id.vala */ + [CCode (cname = "MoonshotServiceRule")] + public struct ServiceRule { + public string pattern; + public string always_confirm; + } + + [CCode (cname = "moonshot_get_identity")] + public bool get_identity (string nai, + string password, + string service, + out string nai_out, + out string password_out, + out string server_certificate_hash_out, + out string ca_certificate_out, + out string subject_name_constraint_out, + out string subject_alt_name_constraint_out, + out Moonshot.Error error); + + [CCode (cname = "moonshot_get_default_identity")] + public bool get_default_identity (out string nai_out, + out string password_out, + out string server_certificate_hash_out, + out string ca_certificate_out, + out string subject_name_constraint_out, + out string subject_alt_name_constraint_out, + out Moonshot.Error error); + + [CCode (cname = "moonshot_install_id_card")] + public bool install_id_card (string display_name, + string? user_name, + string? password, + string? realm, + string rules_patterns[], + string rules_always_confirm[], + string services[], + string? ca_cert, + string? subject, + string? subject_alt, + string? server_cert, + out Moonshot.Error error); +} diff --git a/libmoonshot/moonshot-msrpc.idl b/libmoonshot/moonshot-msrpc.idl index e02ff2c..2dc0d7e 100644 --- a/libmoonshot/moonshot-msrpc.idl +++ b/libmoonshot/moonshot-msrpc.idl @@ -20,5 +20,19 @@ interface moonshot [out, string] char **ca_certificate, [out, string] char **subject_name_constraint, [out, string] char **subject_alt_name_constraint); -} + int moonshot_install_id_card_rpc ([in, string] const char *display_name, + [in, string] const char *user_name, + [in, string] const char *password, + [in, string] const char *realm, + [size_is(rules_patterns_length), in, string] char *rules_patterns[*], + int rules_patterns_length, + [size_is(rules_always_confirm_length), in, string] char *rules_always_confirm[*], + int rules_always_confirm_length, + [size_is(services_length), in, string] char *services[*], + int services_length, + [in, string] const char *ca_cert, + [in, string] const char *subject, + [in, string] const char *subject_alt, + [in, string] const char *server_cert); +} diff --git a/src/moonshot-id.vala b/src/moonshot-id.vala index dbc75da..c372ad3 100644 --- a/src/moonshot-id.vala +++ b/src/moonshot-id.vala @@ -29,8 +29,6 @@ public class IdCard : Object public TrustAnchor trust_anchor { get; set; default = new TrustAnchor (); } - public Gdk.Pixbuf pixbuf { get; set; default = null; } - //TODO: Set the getter and remove the setter/default public unowned string nai { get { _nai = username + "@" + password; return _nai;}} } diff --git a/src/moonshot-idcard-widget.vala b/src/moonshot-idcard-widget.vala index 7a81f4d..7633de0 100644 --- a/src/moonshot-idcard-widget.vala +++ b/src/moonshot-idcard-widget.vala @@ -77,6 +77,7 @@ class IdCardWidget : Box update_id_card_label () { string services_text = ""; + var display_name = Markup.printf_escaped ("%s", this.id_card.display_name); for (int i=0; i { + mutex.lock (); + success = main_window.add_identity (idcard); + cond.signal (); + mutex.unlock (); + return false; + }); + + cond.wait (mutex); + mutex.unlock (); + + return success; + } } #endif diff --git a/src/moonshot-utils.vala b/src/moonshot-utils.vala index 9f11c12..b3a16f8 100644 --- a/src/moonshot-utils.vala +++ b/src/moonshot-utils.vala @@ -23,7 +23,7 @@ public Gdk.Pixbuf? find_icon (string name, int size) // Hack to allow running within the source tree int last_dir_index = base_path.last_index_of_char ('\\'); - if (base_path.substring (last_dir_index) == "\\src") + if (base_path.substring (last_dir_index) == "\\.libs" || base_path.substring (last_dir_index) == "src") base_path = base_path.slice(0, last_dir_index); string? filename = Path.build_filename (base_path, "share", "icons", "%s.png".printf (name)); diff --git a/src/moonshot-webp-parser.vala b/src/moonshot-webp-parser.vala index 4f5bbfd..94b8e52 100644 --- a/src/moonshot-webp-parser.vala +++ b/src/moonshot-webp-parser.vala @@ -1,42 +1,4 @@ -namespace Moonshot -{ - [DBus (name = "org.janet.Moonshot")] - public interface MoonshotServer : Object - { - public async 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 async 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; - - public async abstract bool install_id_card (string display_name, - string user_name, - string password, - string realm, - string[] rules_patterns, - string[] rules_always_confirm, - string[] services, - string ca_cert, - string subject, - string subject_alt, - string server_cert) - throws DBus.Error; - } -} - +using Moonshot; namespace WebProvisioning { @@ -253,7 +215,7 @@ namespace WebProvisioning while ((line = dis.read_line (null)) != null) text += line; } - catch (Error e) + catch (GLib.Error e) { error ("Could not retreive file size"); } @@ -270,7 +232,7 @@ namespace WebProvisioning { ctx.parse (text, text.length); } - catch (Error e) + catch (GLib.Error e) { error ("Could not parse %s, invalid content", path); } @@ -294,45 +256,39 @@ namespace WebProvisioning foreach (IdCard card in cards) { - try - { - var conn = DBus.Bus.get (DBus.BusType.SESSION); - dynamic DBus.Object bus = conn.get_object ("org.janet.Moonshot", - "/org/janet/moonshot", - "org.janet.Moonshot"); - - string[] rules_patterns = {}; - string[] rules_always_confirm = {}; + Moonshot.Error error; + string[] rules_patterns = {}; + string[] rules_always_confirm = {}; - if (card.rules.length > 0) + if (card.rules.length > 0) + { + int i = 0; + rules_patterns = new string[card.rules.length]; + rules_always_confirm = new string[card.rules.length]; + foreach (Rule r in card.rules) { - int i = 0; - rules_patterns = new string[card.rules.length]; - rules_always_confirm = new string[card.rules.length]; - foreach (Rule r in card.rules) - { - rules_patterns[i] = r.pattern; - rules_always_confirm[i] = r.always_confirm; - i++; - } + rules_patterns[i] = r.pattern; + rules_always_confirm[i] = r.always_confirm; + i++; } - - bus.install_id_card (card.display_name, - card.username, - card.password, - card.issuer, - rules_patterns, - rules_always_confirm, - card.services, - card.trust_anchor.ca_cert, - card.trust_anchor.subject, - card.trust_anchor.subject_alt, - card.trust_anchor.server_cert); - } - catch (Error e) + + Moonshot.install_id_card (card.display_name, + card.username, + card.password, + card.issuer, + rules_patterns, + rules_always_confirm, + card.services, + card.trust_anchor.ca_cert, + card.trust_anchor.subject, + card.trust_anchor.subject_alt, + card.trust_anchor.server_cert, + out error); + + if (error != null) { - stderr.printf ("Error: %s", e.message); + stderr.printf ("Error: %s", error.message); continue; } } diff --git a/src/moonshot-window.vala b/src/moonshot-window.vala index d349a84..d40e1d7 100644 --- a/src/moonshot-window.vala +++ b/src/moonshot-window.vala @@ -193,20 +193,22 @@ class MainWindow : Window id_card.issuer = "Issuer"; id_card.username = dialog.username; id_card.password = dialog.password; - id_card.pixbuf = find_icon ("avatar-default", 48); id_card.services = {}; + id_card.set_data("pixbuf", find_icon ("avatar-default", 48)); return id_card; } private void add_id_card_data (IdCard id_card) { - TreeIter iter; + TreeIter iter; + Gdk.Pixbuf pixbuf; this.listmodel.append (out iter); + pixbuf = id_card.get_data("pixbuf"); listmodel.set (iter, Columns.IDCARD_COL, id_card, - Columns.LOGO_COL, id_card.pixbuf, + Columns.LOGO_COL, pixbuf, Columns.ISSUER_COL, id_card.issuer, Columns.USERNAME_COL, id_card.username, Columns.PASSWORD_COL, id_card.password); @@ -247,11 +249,6 @@ class MainWindow : Window id_card_widget.expanded.connect (fill_details); } - private void add_identity (AddIdentityDialog dialog) - { - insert_id_card (get_id_card_data (dialog)); - } - /* This method finds a valid display name */ public bool display_name_is_valid (string name, out string? candidate) @@ -295,14 +292,38 @@ class MainWindow : Window add_id_card_widget (id_card); } - private void add_identity_cb () + public bool add_identity (IdCard id_card) + { + /* TODO: Check if display name already exists */ + + var dialog = new Gtk.MessageDialog (this, + Gtk.DialogFlags.DESTROY_WITH_PARENT, + Gtk.MessageType.QUESTION, + Gtk.ButtonsType.YES_NO, + _("Would you like to add '%s' ID Card to the ID Card Organizer?"), + id_card.display_name); + + dialog.show_all (); + var ret = dialog.run (); + dialog.hide (); + + if (ret == Gtk.ResponseType.YES) { + id_card.set_data ("pixbuf", find_icon ("avatar-default", 48)); + this.insert_id_card (id_card); + return true; + } + + return false; + } + + private void add_identity_manual_cb () { var dialog = new AddIdentityDialog (); var result = dialog.run (); switch (result) { case ResponseType.OK: - add_identity (dialog); + insert_id_card (get_id_card_data (dialog)); break; default: break; @@ -596,7 +617,7 @@ SUCH DAMAGE. N_("Add ID Card"), null, N_("Add a new ID Card"), - add_identity_cb }; + add_identity_manual_cb }; actions += add; Gtk.ActionEntry quit = { "QuitAction", #if VALA_0_12 -- 2.1.4