Support dynamic switching of card store type
[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         items.foreach((entry) => {
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         items.foreach((entry) => {
56             IdCard id_card = new IdCard ();
57             int i;
58             int rules_patterns_index = -1;
59             int rules_always_confirm_index = -1;
60             for (i=0; i<entry.attributes.len; i++) {
61                 var attribute = entry.attributes.data[i];
62                 string value = attribute.string_value;
63                 if (attribute.name == "Issuer") {
64                     id_card.issuer = value;
65                 } else if (attribute.name == "Username") {
66                     id_card.username = value;
67                 } else if (attribute.name == "DisplayName") {
68                     id_card.display_name = value;
69                 } else if (attribute.name == "Services") {
70                     id_card.services = value.split(";");
71                 } else if (attribute.name == "Rules-Pattern") {
72                     rules_patterns_index = i;
73                 } else if (attribute.name == "Rules-AlwaysConfirm") {
74                     rules_always_confirm_index = i;
75                 } else if (attribute.name == "CA-Cert") {
76                     id_card.trust_anchor.ca_cert = value;
77                 } else if (attribute.name == "Server-Cert") {
78                     id_card.trust_anchor.server_cert = value;
79                 } else if (attribute.name == "Subject") {
80                     id_card.trust_anchor.subject = value;
81                 } else if (attribute.name == "Subject-Alt") {
82                     id_card.trust_anchor.subject_alt = value;
83                 }
84             }
85             if ((rules_always_confirm_index != -1) && (rules_patterns_index != -1)) {
86                 string rules_patterns_all = entry.attributes.data[rules_patterns_index].string_value;
87                 string rules_always_confirm_all = entry.attributes.data[rules_always_confirm_index].string_value;
88                 string [] rules_always_confirm = rules_always_confirm_all.split(";");
89                 string [] rules_patterns = rules_patterns_all.split(";");
90                 if (rules_patterns.length == rules_always_confirm.length) {
91                    Rule[] rules = new Rule[rules_patterns.length];
92                    for (int j=0; j<rules_patterns.length; j++) {
93                        rules[j].pattern = rules_patterns[j];
94                        rules[j].always_confirm = rules_always_confirm[j];
95                    }
96                    id_card.rules = rules;
97                 }
98             }
99             id_card.password = entry.secret;
100             id_card_list.add(id_card);
101         });
102     }
103
104     public void store_id_cards () {
105         clear_keyring();
106         foreach (IdCard id_card in this.id_card_list) {
107             string[] rules_patterns = new string[id_card.rules.length];
108             string[] rules_always_conf = new string[id_card.rules.length];
109             
110             for (int i=0; i<id_card.rules.length; i++) {
111                 rules_patterns[i] = id_card.rules[i].pattern;
112                 rules_always_conf[i] = id_card.rules[i].always_confirm;
113             }
114             string patterns = string.joinv(";", rules_patterns);
115             string always_conf = string.joinv(";", rules_always_conf);
116             string services = string.joinv(";", id_card.services);
117             GnomeKeyring.AttributeList attributes = new GnomeKeyring.AttributeList();
118             uint32 item_id;
119             attributes.append_string(keyring_store_attribute, keyring_store_version);
120             attributes.append_string("Issuer", id_card.issuer);
121             attributes.append_string("Username", id_card.username);
122             attributes.append_string("DisplayName", id_card.display_name);
123             attributes.append_string("Services", services);
124             attributes.append_string("Rules-Pattern", patterns);
125             attributes.append_string("Rules-AlwaysConfirm", always_conf);
126             attributes.append_string("CA-Cert", id_card.trust_anchor.ca_cert);
127             attributes.append_string("Server-Cert", id_card.trust_anchor.server_cert);
128             attributes.append_string("Subject", id_card.trust_anchor.subject);
129             attributes.append_string("Subject-Alt", id_card.trust_anchor.subject_alt);
130
131             GnomeKeyring.Result result = GnomeKeyring.item_create_sync(null,
132                 item_type, id_card.display_name,
133                 attributes, id_card.password, true, out item_id);
134             if (result != GnomeKeyring.Result.OK) {
135                 stdout.printf("GnomeKeyring.item_create_sync() failed. result: %d", result);
136             }
137         }
138         load_id_cards();
139     }
140
141     public KeyringStore () {
142         id_card_list = new LinkedList<IdCard>();
143         load_id_cards();
144     }
145 }
146
147 #endif