From: Sam Hartman Date: Sun, 2 Dec 2018 17:04:30 +0000 (-0500) Subject: Working libsecret keystore X-Git-Url: http://www.project-moonshot.org/gitweb/?p=moonshot-ui.git;a=commitdiff_plain;h=b1a1ad76aafd0e01a79ef1588f18afb2532a7955 Working libsecret keystore * The App can use KeyringStore either when GNOME_KEYRING or LIBSECRET_KEYRING are defined * Clean up libsecret initialization * libsecret wants a full schema so specify one. --- diff --git a/src/moonshot-identities-manager.vala b/src/moonshot-identities-manager.vala index a11e726..78b1dc3 100644 --- a/src/moonshot-identities-manager.vala +++ b/src/moonshot-identities-manager.vala @@ -300,7 +300,7 @@ public class IdentityManagerModel : Object { if ((store != null) && (store.get_store_type() == type)) return; switch (type) { - #if GNOME_KEYRING + #if GNOME_KEYRING||LIBSECRET_KEYRING case IIdentityCardStore.StoreType.KEYRING: store = new KeyringStore(); break; diff --git a/src/moonshot-identity-manager-app.vala b/src/moonshot-identity-manager-app.vala index 350b68e..5a7857e 100644 --- a/src/moonshot-identity-manager-app.vala +++ b/src/moonshot-identity-manager-app.vala @@ -94,8 +94,8 @@ public class IdentityManagerApp { use_flat_file_store |= UserForcesFlatFileStore(); this.use_flat_file_store = use_flat_file_store; -#if GNOME_KEYRING - bool keyring_available = (!use_flat_file_store) && GnomeKeyring.is_available(); +#if GNOME_KEYRING || LIBSECRET_KEYRING + bool keyring_available = (!use_flat_file_store) && KeyringStore.is_available(); #else bool keyring_available = false; #endif diff --git a/src/moonshot-keyring-store-base.vala b/src/moonshot-keyring-store-base.vala index d23764d..cdafbe4 100644 --- a/src/moonshot-keyring-store-base.vala +++ b/src/moonshot-keyring-store-base.vala @@ -56,7 +56,7 @@ public abstract class KeyringStoreBase : Object, IIdentityCardStore { protected static Attributes match_attributes; - protected IdCard deserialize(GLib.HashTable attrs, string? secret) + protected static IdCard deserialize(GLib.HashTable attrs, string? secret) { IdCard id_card = new IdCard(); unowned string store_password = attrs["StorePassword"]; @@ -109,7 +109,38 @@ public abstract class KeyringStoreBase : Object, IIdentityCardStore { return id_card; } - + + internal static Attributes serialize(IdCard id_card) + { + /* workaround for Centos vala array property bug: use temp array */ + var rules = id_card.rules; + string[] rules_patterns = new string[rules.length]; + string[] rules_always_conf = new string[rules.length]; + + for (int i = 0; i < rules.length; i++) { + rules_patterns[i] = rules[i].pattern; + rules_always_conf[i] = rules[i].always_confirm; + } + string patterns = string.joinv(";", rules_patterns); + string always_conf = string.joinv(";", rules_always_conf); + string services = id_card.get_services_string(";"); + Attributes attributes = new Attributes(); + attributes.insert(keyring_store_attribute, keyring_store_version); + attributes.insert("Issuer", id_card.issuer); + attributes.insert("Username", id_card.username); + attributes.insert("DisplayName", id_card.display_name); + attributes.insert("Services", services); + attributes.insert("Rules-Pattern", patterns); + attributes.insert("Rules-AlwaysConfirm", always_conf); + attributes.insert("CA-Cert", id_card.trust_anchor.ca_cert); + attributes.insert("Server-Cert", id_card.trust_anchor.server_cert); + attributes.insert("Subject", id_card.trust_anchor.subject); + attributes.insert("Subject-Alt", id_card.trust_anchor.subject_alt); + attributes.insert("TA_DateTime_Added", id_card.trust_anchor.datetime_added); + attributes.insert("StorePassword", id_card.store_password ? "yes" : "no"); + return attributes; + } + class construct { match_attributes = new Attributes(); match_attributes.insert(keyring_store_attribute, keyring_store_version); @@ -158,6 +189,7 @@ public abstract class KeyringStoreBase : Object, IIdentityCardStore { protected abstract void clear_keyring(); protected abstract void load_id_cards() throws GLib.Error; internal abstract void store_id_cards(); + diff --git a/src/moonshot-keyring-store-gnome.vala b/src/moonshot-keyring-store-gnome.vala index 0e0ff5c..100de7c 100644 --- a/src/moonshot-keyring-store-gnome.vala +++ b/src/moonshot-keyring-store-gnome.vala @@ -59,81 +59,17 @@ public class KeyringStore : KeyringStoreBase { GLib.List items; GnomeKeyring.find_items_sync(item_type, match, out items); foreach(unowned GnomeKeyring.Found entry in items) { - IdCard id_card = new IdCard(); - int i; - int rules_patterns_index = -1; - int rules_always_confirm_index = -1; - string store_password = null; - string ca_cert = ""; - string server_cert = ""; - string subject = ""; - string subject_alt = ""; - string ta_datetime_added = ""; - for (i = 0; i < entry.attributes.len; i++) { + KeyringStoreBase.Attributes new_attrs = new KeyringStoreBase.Attributes(); + for (int i = 0; i < entry.attributes.len; i++) { var attribute = ((GnomeKeyring.Attribute *) entry.attributes.data)[i]; - string value = ""; if (attribute.type == GnomeKeyring.AttributeType.STRING) { - value = attribute.string_value; + unowned string value = attribute.string_value; + new_attrs.insert(attribute.name, value); } - - if (attribute.name == "Issuer") { - id_card.issuer = value; - } else if (attribute.name == "Username") { - id_card.username = value; - } else if (attribute.name == "DisplayName") { - id_card.display_name = value; - } else if (attribute.name == "Services") { - id_card.update_services(value.split(";")); - } else if (attribute.name == "Rules-Pattern") { - rules_patterns_index = i; - } else if (attribute.name == "Rules-AlwaysConfirm") { - rules_always_confirm_index = i; - } else if (attribute.name == "CA-Cert") { - ca_cert = value.strip(); - } else if (attribute.name == "Server-Cert") { - server_cert = value; - } else if (attribute.name == "Subject") { - subject = value; - } else if (attribute.name == "Subject-Alt") { - subject_alt = value; - } else if (attribute.name == "StorePassword") { - store_password = value; - } else if (attribute.name == "TA_DateTime_Added") { - ta_datetime_added = value; - } - } - - var ta = new TrustAnchor(ca_cert, server_cert, subject, subject_alt); - if (ta_datetime_added != "") { - ta.set_datetime_added(ta_datetime_added); - } - id_card.set_trust_anchor_from_store(ta); - - if ((rules_always_confirm_index != -1) && (rules_patterns_index != -1)) { - string rules_patterns_all = ((GnomeKeyring.Attribute *) entry.attributes.data)[rules_patterns_index].string_value; - string rules_always_confirm_all = ((GnomeKeyring.Attribute *) entry.attributes.data)[rules_always_confirm_index].string_value; - string [] rules_always_confirm = rules_always_confirm_all.split(";"); - string [] rules_patterns = rules_patterns_all.split(";"); - if (rules_patterns.length == rules_always_confirm.length) { - Rule[] rules = new Rule[rules_patterns.length]; - for (int j = 0; j < rules_patterns.length; j++) { - rules[j].pattern = rules_patterns[j]; - rules[j].always_confirm = rules_always_confirm[j]; - } - id_card.rules = rules; - } - } - - if (store_password != null) - id_card.store_password = (store_password == "yes"); - else - id_card.store_password = ((entry.secret != null) && (entry.secret != "")); - - if (id_card.store_password) - id_card.password = entry.secret; - else - id_card.password = null; - + } + + var id_card = deserialize(new_attrs, entry.secret); + id_card_list.add(id_card); } } @@ -143,32 +79,13 @@ public class KeyringStore : KeyringStoreBase { clear_keyring(); foreach (IdCard id_card in this.id_card_list) { /* workaround for Centos vala array property bug: use temp array */ - var rules = id_card.rules; - string[] rules_patterns = new string[rules.length]; - string[] rules_always_conf = new string[rules.length]; - - for (int i = 0; i < rules.length; i++) { - rules_patterns[i] = rules[i].pattern; - rules_always_conf[i] = rules[i].always_confirm; - } - string patterns = string.joinv(";", rules_patterns); - string always_conf = string.joinv(";", rules_always_conf); - string services = id_card.get_services_string(";"); GnomeKeyring.AttributeList attributes = new GnomeKeyring.AttributeList(); uint32 item_id; + var hash_attrs = serialize(id_card); + hash_attrs.foreach((k, v) => { + attributes.append_string(k,v); }); + attributes.append_string(keyring_store_attribute, keyring_store_version); - attributes.append_string("Issuer", id_card.issuer); - attributes.append_string("Username", id_card.username); - attributes.append_string("DisplayName", id_card.display_name); - attributes.append_string("Services", services); - attributes.append_string("Rules-Pattern", patterns); - attributes.append_string("Rules-AlwaysConfirm", always_conf); - attributes.append_string("CA-Cert", id_card.trust_anchor.ca_cert); - attributes.append_string("Server-Cert", id_card.trust_anchor.server_cert); - attributes.append_string("Subject", id_card.trust_anchor.subject); - attributes.append_string("Subject-Alt", id_card.trust_anchor.subject_alt); - attributes.append_string("TA_DateTime_Added", id_card.trust_anchor.datetime_added); - attributes.append_string("StorePassword", id_card.store_password ? "yes" : "no"); GnomeKeyring.Result result = GnomeKeyring.item_create_sync(null, item_type, id_card.display_name, attributes, @@ -178,9 +95,19 @@ public class KeyringStore : KeyringStoreBase { stdout.printf("GnomeKeyring.item_create_sync() failed. result: %d", result); } } - load_id_cards(); + try { + load_id_cards(); + } catch(GLib.Error e) { + logger.error(@"Unable to load ID cards: $(e.message)\n"); + } + } + public static bool is_available() + { + return GnomeKeyring.is_available(); + } + } #endif diff --git a/src/moonshot-keyring-store-secret.vala b/src/moonshot-keyring-store-secret.vala index 6836393..ad89faf 100644 --- a/src/moonshot-keyring-store-secret.vala +++ b/src/moonshot-keyring-store-secret.vala @@ -35,6 +35,20 @@ using Secret; +private Collection? find_secret_collection() +{ + Collection secret_collection = null; + stdout.printf("In find_secret_collection\n"); + try { + Service service = Service.get_sync(ServiceFlags.OPEN_SESSION); + secret_collection = Collection.for_alias_sync(service, COLLECTION_DEFAULT, + CollectionFlags.NONE); + } catch(GLib.Error e) { + stdout.printf("Unable to load secret service: %s\n", e.message); + } + return secret_collection; + } + public class KeyringStore : KeyringStoreBase { /* * We choose to remain compatible with the way we stored secrets @@ -42,8 +56,24 @@ public class KeyringStore : KeyringStoreBase { * identifier. Using our own schema might get us a nice icon in * seahorse, but would not save much code. */ - private static Schema schema = new Schema("org.freedesktop.Secret.Generic", SchemaFlags.NONE); - private static Collection secret_collection; + private const SchemaAttributeType sstring = SchemaAttributeType.STRING; + private static Schema schema = new Schema("org.freedesktop.Secret.Generic", SchemaFlags.NONE, + "Moonshot", sstring, + "Issuer", sstring, + "Username", sstring, + "DisplayName", sstring, + "Services", sstring, + "Rules-Pattern", sstring, + "Rules-AlwaysConfirm", sstring, + "CA-Cert", sstring, + "Server-Cert", sstring, + "Subject", sstring, + "Subject-Alt", sstring, + "TA_DateTime_Added", sstring, + "StorePassword", sstring); + private static Collection? secret_collection = find_secret_collection(); + + /* clear all keyring-stored ids (in preparation to store current list) */ @@ -51,7 +81,7 @@ public class KeyringStore : KeyringStoreBase { GLib.List items; try { items = secret_collection.search_sync(schema, match_attributes, - SearchFlags.NONE); + SearchFlags.ALL); } catch (GLib.Error e) { stdout.printf("Failed to find items to delete: %s\n", e.message); return; @@ -73,7 +103,7 @@ public class KeyringStore : KeyringStoreBase { GLib.List items = secret_collection.search_sync( schema, match_attributes, - SearchFlags.UNLOCK|SearchFlags.LOAD_SECRETS); + SearchFlags.UNLOCK|SearchFlags.LOAD_SECRETS|SearchFlags.ALL); foreach(unowned Item entry in items) { var secret = entry.get_secret(); string secret_text = null; @@ -89,33 +119,7 @@ public class KeyringStore : KeyringStoreBase { clear_keyring(); foreach (IdCard id_card in this.id_card_list) { try { - /* workaround for Centos vala array property bug: use temp array */ - var rules = id_card.rules; - string[] rules_patterns = new string[rules.length]; - string[] rules_always_conf = new string[rules.length]; - - for (int i = 0; i < rules.length; i++) { - rules_patterns[i] = rules[i].pattern; - rules_always_conf[i] = rules[i].always_confirm; - } - string patterns = string.joinv(";", rules_patterns); - string always_conf = string.joinv(";", rules_always_conf); - string services = id_card.get_services_string(";"); - KeyringStoreBase.Attributes attributes = new KeyringStoreBase.Attributes(); - attributes.insert(keyring_store_attribute, keyring_store_version); - attributes.insert("Issuer", id_card.issuer); - attributes.insert("Username", id_card.username); - attributes.insert("DisplayName", id_card.display_name); - attributes.insert("Services", services); - attributes.insert("Rules-Pattern", patterns); - attributes.insert("Rules-AlwaysConfirm", always_conf); - attributes.insert("CA-Cert", id_card.trust_anchor.ca_cert); - attributes.insert("Server-Cert", id_card.trust_anchor.server_cert); - attributes.insert("Subject", id_card.trust_anchor.subject); - attributes.insert("Subject-Alt", id_card.trust_anchor.subject_alt); - attributes.insert("TA_DateTime_Added", id_card.trust_anchor.datetime_added); - attributes.insert("StorePassword", id_card.store_password ? "yes" : "no"); - +var attributes = serialize(id_card); password_storev_sync(schema, attributes, null, id_card.display_name, id_card.store_password?id_card.password: ""); } catch(GLib.Error e) { @@ -129,8 +133,17 @@ public class KeyringStore : KeyringStoreBase { logger.error(@"Unable to load ID Cards: $(e.message)\n"); } - } + } + public static bool is_available() + { + if (secret_collection == null) { + secret_collection = find_secret_collection(); + } + + return secret_collection != null; + } + } #endif