6836393ac392974fb98f1419e659f9377739a14f
[moonshot-ui.git] / src / moonshot-keyring-store-secret.vala
1 /*
2 * Copyright (C) 2018   Sam Hartman
3 * Copyright (c) 2011-2016, JANET(UK)
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  *
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.
16  *
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.
20  *
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
31  * SUCH DAMAGE.
32 */
33
34 #if LIBSECRET_KEYRING
35
36 using Secret;
37
38 public class KeyringStore : KeyringStoreBase {
39     /*
40     * We choose to remain compatible with the way we stored secrets
41     * using libgnomekeyring.  As a result, we cannot use our own schema
42     * identifier.  Using our own schema might get us a nice icon in
43     * seahorse, but would not save much code. 
44     */
45     private static Schema schema = new Schema("org.freedesktop.Secret.Generic", SchemaFlags.NONE);
46     private static Collection secret_collection;
47     
48
49     /* clear all keyring-stored ids (in preparation to store current list) */
50     protected override void clear_keyring() {
51         GLib.List<Item> items;
52         try {
53             items = secret_collection.search_sync(schema, match_attributes,
54                                                   SearchFlags.NONE);
55         } catch (GLib.Error e) {
56             stdout.printf("Failed to find items to delete: %s\n", e.message);
57             return;
58         }
59         foreach(unowned Item  entry in items) {
60             try {
61                 bool res = entry.delete_sync();
62                 if (!res) {
63                     stdout.printf("Failed to delete item: %s\n", entry.get_label());
64                 }
65             } catch (GLib.Error e) {
66                 stdout.printf("Error deleting item: %s\n", e.message);
67             }
68         }
69     }
70
71     protected override void load_id_cards()  throws GLib.Error {
72         id_card_list.clear();
73
74         GLib.List<Item> items = secret_collection.search_sync(
75                                                               schema, match_attributes,
76                                                               SearchFlags.UNLOCK|SearchFlags.LOAD_SECRETS);
77         foreach(unowned Item entry in items) {
78             var secret = entry.get_secret();
79             string secret_text = null;
80             if (secret != null)
81                 secret_text = secret.get_text();
82             var id_card = deserialize(entry.attributes, secret_text);
83             id_card_list.add(id_card);
84         }
85     }
86
87     internal override void store_id_cards() {
88         logger.trace("store_id_cards");
89         clear_keyring();
90         foreach (IdCard id_card in this.id_card_list) {
91             try {
92                 /* workaround for Centos vala array property bug: use temp array */
93                 var rules = id_card.rules;
94                 string[] rules_patterns = new string[rules.length];
95                 string[] rules_always_conf = new string[rules.length];
96             
97                 for (int i = 0; i < rules.length; i++) {
98                     rules_patterns[i] = rules[i].pattern;
99                     rules_always_conf[i] = rules[i].always_confirm;
100                 }
101                 string patterns = string.joinv(";", rules_patterns);
102                 string always_conf = string.joinv(";", rules_always_conf);
103                 string services = id_card.get_services_string(";");
104                 KeyringStoreBase.Attributes attributes = new KeyringStoreBase.Attributes();
105                 attributes.insert(keyring_store_attribute, keyring_store_version);
106                 attributes.insert("Issuer", id_card.issuer);
107                 attributes.insert("Username", id_card.username);
108                 attributes.insert("DisplayName", id_card.display_name);
109                 attributes.insert("Services", services);
110                 attributes.insert("Rules-Pattern", patterns);
111                 attributes.insert("Rules-AlwaysConfirm", always_conf);
112                 attributes.insert("CA-Cert", id_card.trust_anchor.ca_cert);
113                 attributes.insert("Server-Cert", id_card.trust_anchor.server_cert);
114                 attributes.insert("Subject", id_card.trust_anchor.subject);
115                 attributes.insert("Subject-Alt", id_card.trust_anchor.subject_alt);
116                 attributes.insert("TA_DateTime_Added", id_card.trust_anchor.datetime_added);
117                 attributes.insert("StorePassword", id_card.store_password ? "yes" : "no");
118
119                 password_storev_sync(schema, attributes, null, id_card.display_name,
120                                      id_card.store_password?id_card.password: "");
121             } catch(GLib.Error e) {
122                 logger.error(@"Unable to store $(id_card.display_name): $(e.message)\n");
123         }
124         
125         }
126         try {
127             load_id_cards();
128         } catch (GLib.Error e) {
129             logger.error(@"Unable to load ID Cards: $(e.message)\n");
130         }
131         
132      }
133
134 }
135
136 #endif