0e0ff5ca13e9426e7707fc14bba933dd735eb4c4
[moonshot-ui.git] / src / moonshot-keyring-store-gnome.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 GNOME_KEYRING
35
36 using Gee;
37 public class KeyringStore : KeyringStoreBase {
38     private const GnomeKeyring.ItemType item_type = GnomeKeyring.ItemType.GENERIC_SECRET;
39
40     /* clear all keyring-stored ids (in preparation to store current list) */
41     protected override void clear_keyring() {
42       GnomeKeyring.AttributeList match = new GnomeKeyring.AttributeList();
43       match.append_string(keyring_store_attribute, keyring_store_version);
44       GLib.List<GnomeKeyring.Found> items;
45       GnomeKeyring.find_items_sync(item_type, match, out items);
46       foreach(unowned GnomeKeyring.Found entry in items) {
47         GnomeKeyring.Result result = GnomeKeyring.item_delete_sync(null, entry.item_id);
48         if (result != GnomeKeyring.Result.OK) {
49           stdout.printf("GnomeKeyring.item_delete_sync() failed. result: %d", result);
50         }
51       }
52     }
53
54     protected override void load_id_cards() {
55         id_card_list.clear();
56
57         GnomeKeyring.AttributeList match = new GnomeKeyring.AttributeList();
58         match.append_string(keyring_store_attribute, keyring_store_version);
59         GLib.List<GnomeKeyring.Found> items;
60         GnomeKeyring.find_items_sync(item_type, match, out items);
61         foreach(unowned GnomeKeyring.Found entry in items) {
62             IdCard id_card = new IdCard();
63             int i;
64             int rules_patterns_index = -1;
65             int rules_always_confirm_index = -1;
66             string store_password = null;
67             string ca_cert = "";
68             string server_cert = "";
69             string subject = "";
70             string subject_alt = "";
71             string ta_datetime_added = "";
72             for (i = 0; i < entry.attributes.len; i++) {
73                 var attribute = ((GnomeKeyring.Attribute *) entry.attributes.data)[i];
74                 string value = "";
75                 if (attribute.type == GnomeKeyring.AttributeType.STRING) {
76                     value = attribute.string_value;
77                 }
78
79                 if (attribute.name == "Issuer") {
80                     id_card.issuer = value;
81                 } else if (attribute.name == "Username") {
82                     id_card.username = value;
83                 } else if (attribute.name == "DisplayName") {
84                     id_card.display_name = value;
85                 } else if (attribute.name == "Services") {
86                     id_card.update_services(value.split(";"));
87                 } else if (attribute.name == "Rules-Pattern") {
88                     rules_patterns_index = i;
89                 } else if (attribute.name == "Rules-AlwaysConfirm") {
90                     rules_always_confirm_index = i;
91                 } else if (attribute.name == "CA-Cert") {
92                     ca_cert = value.strip();
93                 } else if (attribute.name == "Server-Cert") {
94                     server_cert = value;
95                 } else if (attribute.name == "Subject") {
96                     subject = value;
97                 } else if (attribute.name == "Subject-Alt") {
98                     subject_alt = value;
99                 } else if (attribute.name == "StorePassword") {
100                     store_password = value;
101                 } else if (attribute.name == "TA_DateTime_Added") {
102                     ta_datetime_added = value;
103                 }
104             }
105
106             var ta = new TrustAnchor(ca_cert, server_cert, subject, subject_alt);
107             if (ta_datetime_added != "") {
108                 ta.set_datetime_added(ta_datetime_added);
109             }
110             id_card.set_trust_anchor_from_store(ta);
111
112             if ((rules_always_confirm_index != -1) && (rules_patterns_index != -1)) {
113                 string rules_patterns_all = ((GnomeKeyring.Attribute *) entry.attributes.data)[rules_patterns_index].string_value;
114                 string rules_always_confirm_all = ((GnomeKeyring.Attribute *) entry.attributes.data)[rules_always_confirm_index].string_value;
115                 string [] rules_always_confirm = rules_always_confirm_all.split(";");
116                 string [] rules_patterns = rules_patterns_all.split(";");
117                 if (rules_patterns.length == rules_always_confirm.length) {
118                     Rule[] rules = new Rule[rules_patterns.length];
119                     for (int j = 0; j < rules_patterns.length; j++) {
120                         rules[j].pattern = rules_patterns[j];
121                         rules[j].always_confirm = rules_always_confirm[j];
122                     }
123                     id_card.rules = rules;
124                 }
125             }
126
127             if (store_password != null)
128                 id_card.store_password = (store_password == "yes");
129             else
130                 id_card.store_password = ((entry.secret != null) && (entry.secret != ""));
131
132             if (id_card.store_password)
133                 id_card.password = entry.secret;
134             else
135                 id_card.password = null;
136
137             id_card_list.add(id_card);
138         }
139     }
140
141     internal override void store_id_cards() {
142         logger.trace("store_id_cards");
143         clear_keyring();
144         foreach (IdCard id_card in this.id_card_list) {
145             /* workaround for Centos vala array property bug: use temp array */
146             var rules = id_card.rules;
147             string[] rules_patterns = new string[rules.length];
148             string[] rules_always_conf = new string[rules.length];
149             
150             for (int i = 0; i < rules.length; i++) {
151                 rules_patterns[i] = rules[i].pattern;
152                 rules_always_conf[i] = rules[i].always_confirm;
153             }
154             string patterns = string.joinv(";", rules_patterns);
155             string always_conf = string.joinv(";", rules_always_conf);
156             string services = id_card.get_services_string(";");
157             GnomeKeyring.AttributeList attributes = new GnomeKeyring.AttributeList();
158             uint32 item_id;
159             attributes.append_string(keyring_store_attribute, keyring_store_version);
160             attributes.append_string("Issuer", id_card.issuer);
161             attributes.append_string("Username", id_card.username);
162             attributes.append_string("DisplayName", id_card.display_name);
163             attributes.append_string("Services", services);
164             attributes.append_string("Rules-Pattern", patterns);
165             attributes.append_string("Rules-AlwaysConfirm", always_conf);
166             attributes.append_string("CA-Cert", id_card.trust_anchor.ca_cert);
167             attributes.append_string("Server-Cert", id_card.trust_anchor.server_cert);
168             attributes.append_string("Subject", id_card.trust_anchor.subject);
169             attributes.append_string("Subject-Alt", id_card.trust_anchor.subject_alt);
170             attributes.append_string("TA_DateTime_Added", id_card.trust_anchor.datetime_added);
171             attributes.append_string("StorePassword", id_card.store_password ? "yes" : "no");
172
173             GnomeKeyring.Result result = GnomeKeyring.item_create_sync(null,
174                                                                        item_type, id_card.display_name, attributes,
175                                                                        id_card.store_password ? id_card.password : "",
176                                                                        true, out item_id);
177             if (result != GnomeKeyring.Result.OK) {
178                 stdout.printf("GnomeKeyring.item_create_sync() failed. result: %d", result);
179             }
180         }
181         load_id_cards();
182     }
183
184 }
185
186 #endif