21927042a3b051319c61b339ce5d9b44618f5243
[moonshot-ui.git] / src / moonshot-keyring-store.vala
1 using Gee;
2
3 #if GNOME_KEYRING
4 public class KeyringStore : Object, IIdentityCardStore {
5     private LinkedList<IdCard> id_card_list;
6     private const string keyring_store_attribute = "Moonshot";
7     private const string keyring_store_version = "1.0";
8     private const GnomeKeyring.ItemType item_type = GnomeKeyring.ItemType.GENERIC_SECRET;
9
10     public void add_card(IdCard card) {
11         id_card_list.add(card);
12         store_id_cards ();
13     }
14
15     public void update_card(IdCard card) {
16         id_card_list.remove(card);
17         id_card_list.add(card);
18         store_id_cards ();
19     }
20
21     public void remove_card(IdCard card) {
22         id_card_list.remove(card);
23         store_id_cards ();
24     }
25
26     public IIdentityCardStore.StoreType get_store_type() {
27         return IIdentityCardStore.StoreType.KEYRING;
28     }
29
30     public LinkedList<IdCard> get_card_list() {
31         return id_card_list;
32     }
33
34     /* clear all keyring-stored ids (in preparation to store current list) */
35     private void clear_keyring() {
36         GnomeKeyring.AttributeList match = new GnomeKeyring.AttributeList();
37         match.append_string(keyring_store_attribute, keyring_store_version);
38         GLib.List<GnomeKeyring.Found> items;
39         GnomeKeyring.find_items_sync(item_type, match, out items);
40         foreach(unowned GnomeKeyring.Found entry in items) {
41             GnomeKeyring.Result result = GnomeKeyring.item_delete_sync(null, entry.item_id);
42             if (result != GnomeKeyring.Result.OK) {
43                 stdout.printf("GnomeKeyring.item_delete_sync() failed. result: %d", result);
44             }
45         }
46     }
47      
48     private void load_id_cards() {
49         id_card_list.clear();
50
51         GnomeKeyring.AttributeList match = new GnomeKeyring.AttributeList();
52         match.append_string(keyring_store_attribute, keyring_store_version);
53         GLib.List<GnomeKeyring.Found> items;
54         GnomeKeyring.find_items_sync(item_type, match, out items);
55         foreach(unowned GnomeKeyring.Found entry in items) {
56             IdCard id_card = new IdCard ();
57             int i;
58             int rules_patterns_index = -1;
59             int rules_always_confirm_index = -1;
60             string store_password = null;
61             for (i=0; i<entry.attributes.len; i++) {
62                 var attribute = ((GnomeKeyring.Attribute *) entry.attributes.data)[i];
63                 string value = attribute.string_value;
64                 if (attribute.name == "Issuer") {
65                     id_card.issuer = value;
66                 } else if (attribute.name == "Username") {
67                     id_card.username = value;
68                 } else if (attribute.name == "DisplayName") {
69                     id_card.display_name = value;
70                 } else if (attribute.name == "Services") {
71                     id_card.services = value.split(";");
72                 } else if (attribute.name == "Rules-Pattern") {
73                     rules_patterns_index = i;
74                 } else if (attribute.name == "Rules-AlwaysConfirm") {
75                     rules_always_confirm_index = i;
76                 } else if (attribute.name == "CA-Cert") {
77                     id_card.trust_anchor.ca_cert = value;
78                 } else if (attribute.name == "Server-Cert") {
79                     id_card.trust_anchor.server_cert = value;
80                 } else if (attribute.name == "Subject") {
81                     id_card.trust_anchor.subject = value;
82                 } else if (attribute.name == "Subject-Alt") {
83                     id_card.trust_anchor.subject_alt = value;
84                 } else if (attribute.name == "StorePassword") {
85                     store_password = value;
86                 }
87             }
88             if ((rules_always_confirm_index != -1) && (rules_patterns_index != -1)) {
89                 string rules_patterns_all = ((GnomeKeyring.Attribute *) entry.attributes.data)[rules_patterns_index].string_value;
90                 string rules_always_confirm_all = ((GnomeKeyring.Attribute *) entry.attributes.data)[rules_always_confirm_index].string_value;
91                 string [] rules_always_confirm = rules_always_confirm_all.split(";");
92                 string [] rules_patterns = rules_patterns_all.split(";");
93                 if (rules_patterns.length == rules_always_confirm.length) {
94                    Rule[] rules = new Rule[rules_patterns.length];
95                    for (int j=0; j<rules_patterns.length; j++) {
96                        rules[j].pattern = rules_patterns[j];
97                        rules[j].always_confirm = rules_always_confirm[j];
98                    }
99                    id_card.rules = rules;
100                 }
101             }
102
103             if (store_password != null)
104                 id_card.store_password = (store_password == "yes");
105             else
106                 id_card.store_password = ((entry.secret != null) && (entry.secret != ""));
107
108             if (id_card.store_password)
109                 id_card.password = entry.secret;
110             else
111                 id_card.password = null;
112             id_card_list.add(id_card);
113         }
114     }
115
116     public void store_id_cards () {
117         clear_keyring();
118         foreach (IdCard id_card in this.id_card_list) {
119             string[] rules_patterns = new string[id_card.rules.length];
120             string[] rules_always_conf = new string[id_card.rules.length];
121             
122             for (int i=0; i<id_card.rules.length; i++) {
123                 rules_patterns[i] = id_card.rules[i].pattern;
124                 rules_always_conf[i] = id_card.rules[i].always_confirm;
125             }
126             string patterns = string.joinv(";", rules_patterns);
127             string always_conf = string.joinv(";", rules_always_conf);
128             string services = string.joinv(";", id_card.services);
129             GnomeKeyring.AttributeList attributes = new GnomeKeyring.AttributeList();
130             uint32 item_id;
131             attributes.append_string(keyring_store_attribute, keyring_store_version);
132             attributes.append_string("Issuer", id_card.issuer);
133             attributes.append_string("Username", id_card.username);
134             attributes.append_string("DisplayName", id_card.display_name);
135             attributes.append_string("Services", services);
136             attributes.append_string("Rules-Pattern", patterns);
137             attributes.append_string("Rules-AlwaysConfirm", always_conf);
138             attributes.append_string("CA-Cert", id_card.trust_anchor.ca_cert);
139             attributes.append_string("Server-Cert", id_card.trust_anchor.server_cert);
140             attributes.append_string("Subject", id_card.trust_anchor.subject);
141             attributes.append_string("Subject-Alt", id_card.trust_anchor.subject_alt);
142             attributes.append_string("StorePassword", id_card.store_password ? "yes" : "no");
143
144             GnomeKeyring.Result result = GnomeKeyring.item_create_sync(null,
145                 item_type, id_card.display_name, attributes,
146                 id_card.store_password ? id_card.password : "",
147                 true, out item_id);
148             if (result != GnomeKeyring.Result.OK) {
149                 stdout.printf("GnomeKeyring.item_create_sync() failed. result: %d", result);
150             }
151         }
152         load_id_cards();
153     }
154
155     public KeyringStore () {
156         id_card_list = new LinkedList<IdCard>();
157         load_id_cards();
158     }
159 }
160
161 #endif