2 * Copyright (C) 2018 Sam Hartman
3 * Copyright (c) 2011-2016, JANET(UK)
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of JANET(UK) nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38 private Collection? find_secret_collection()
40 Collection secret_collection = null;
41 stdout.printf("In find_secret_collection\n");
43 Service service = Service.get_sync(ServiceFlags.OPEN_SESSION);
44 secret_collection = Collection.for_alias_sync(service, COLLECTION_DEFAULT,
45 CollectionFlags.NONE);
46 } catch(GLib.Error e) {
47 stdout.printf("Unable to load secret service: %s\n", e.message);
49 return secret_collection;
52 public class KeyringStore : KeyringStoreBase {
54 * We choose to remain compatible with the way we stored secrets
55 * using libgnomekeyring. As a result, we cannot use our own schema
56 * identifier. Using our own schema might get us a nice icon in
57 * seahorse, but would not save much code.
59 private const SchemaAttributeType sstring = SchemaAttributeType.STRING;
60 private static Schema schema = new Schema("org.freedesktop.Secret.Generic", SchemaFlags.NONE,
64 "DisplayName", sstring,
66 "Rules-Pattern", sstring,
67 "Rules-AlwaysConfirm", sstring,
69 "Server-Cert", sstring,
71 "Subject-Alt", sstring,
72 "TA_DateTime_Added", sstring,
73 "StorePassword", sstring);
74 private static Collection? secret_collection = find_secret_collection();
79 /* clear all keyring-stored ids (in preparation to store current list) */
80 protected override void clear_keyring() {
81 GLib.List<Item> items;
83 items = secret_collection.search_sync(schema, match_attributes,
85 } catch (GLib.Error e) {
86 stdout.printf("Failed to find items to delete: %s\n", e.message);
89 foreach(unowned Item entry in items) {
91 bool res = entry.delete_sync();
93 stdout.printf("Failed to delete item: %s\n", entry.get_label());
95 } catch (GLib.Error e) {
96 stdout.printf("Error deleting item: %s\n", e.message);
101 protected override void load_id_cards() throws GLib.Error {
102 id_card_list.clear();
104 GLib.List<Item> items = secret_collection.search_sync(
105 schema, match_attributes,
106 SearchFlags.UNLOCK|SearchFlags.LOAD_SECRETS|SearchFlags.ALL);
107 foreach(unowned Item entry in items) {
108 var secret = entry.get_secret();
109 string secret_text = null;
111 secret_text = secret.get_text();
112 var id_card = deserialize(entry.attributes, secret_text);
113 id_card_list.add(id_card);
117 internal override void store_id_cards() {
118 logger.trace("store_id_cards");
120 foreach (IdCard id_card in this.id_card_list) {
122 var attributes = serialize(id_card);
123 password_storev_sync(schema, attributes, null, id_card.display_name,
124 id_card.store_password?id_card.password: "");
125 } catch(GLib.Error e) {
126 logger.error(@"Unable to store $(id_card.display_name): $(e.message)\n");
132 } catch (GLib.Error e) {
133 logger.error(@"Unable to load ID Cards: $(e.message)\n");
138 public static bool is_available()
140 if (secret_collection == null) {
141 secret_collection = find_secret_collection();
144 return secret_collection != null;