Implement gnome keyring data store.
[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 LinkedList<IdCard> get_card_list() {
27         return id_card_list;
28     }
29
30     /* clear all keyring-stored ids (in preparation to store current list) */
31     private void clear_keyring() {
32         GnomeKeyring.AttributeList match = new GnomeKeyring.AttributeList();
33         match.append_string(keyring_store_attribute, keyring_store_version);
34         GLib.List<GnomeKeyring.Found> items;
35         GnomeKeyring.find_items_sync(item_type, match, out items);
36         items.foreach((entry) => {
37             GnomeKeyring.Result result = GnomeKeyring.item_delete_sync(null, entry.item_id);
38             if (result != GnomeKeyring.Result.OK) {
39                 stdout.printf("GnomeKeyring.item_delete_sync() failed. result: %d", result);
40             }
41         });
42     }
43      
44     private void load_id_cards() {
45         id_card_list.clear();
46
47         GnomeKeyring.AttributeList match = new GnomeKeyring.AttributeList();
48         match.append_string(keyring_store_attribute, keyring_store_version);
49         GLib.List<GnomeKeyring.Found> items;
50         GnomeKeyring.find_items_sync(item_type, match, out items);
51         items.foreach((entry) => {
52             IdCard id_card = new IdCard ();
53             int i;
54             int rules_patterns_index = -1;
55             int rules_always_confirm_index = -1;
56             for (i=0; i<entry.attributes.len; i++) {
57                 var attribute = entry.attributes.data[i];
58                 string value = attribute.string_value;
59                 if (attribute.name == "Issuer") {
60                     id_card.issuer = value;
61                 } else if (attribute.name == "Username") {
62                     id_card.username = value;
63                 } else if (attribute.name == "DisplayName") {
64                     id_card.display_name = value;
65                 } else if (attribute.name == "Services") {
66                     id_card.services = value.split(";");
67                 } else if (attribute.name == "Rules-Pattern") {
68                     rules_patterns_index = i;
69                 } else if (attribute.name == "Rules-AlwaysConfirm") {
70                     rules_always_confirm_index = i;
71                 } else if (attribute.name == "CA-Cert") {
72                     id_card.trust_anchor.ca_cert = value;
73                 } else if (attribute.name == "Server-Cert") {
74                     id_card.trust_anchor.server_cert = value;
75                 } else if (attribute.name == "Subject") {
76                     id_card.trust_anchor.subject = value;
77                 } else if (attribute.name == "Subject-Alt") {
78                     id_card.trust_anchor.subject_alt = value;
79                 }
80             }
81             if ((rules_always_confirm_index != -1) && (rules_patterns_index != -1)) {
82                 string rules_patterns_all = entry.attributes.data[rules_patterns_index].string_value;
83                 string rules_always_confirm_all = entry.attributes.data[rules_always_confirm_index].string_value;
84                 string [] rules_always_confirm = rules_always_confirm_all.split(";");
85                 string [] rules_patterns = rules_patterns_all.split(";");
86                 if (rules_patterns.length == rules_always_confirm.length) {
87                    Rule[] rules = new Rule[rules_patterns.length];
88                    for (int j=0; j<rules_patterns.length; j++) {
89                        rules[j].pattern = rules_patterns[j];
90                        rules[j].always_confirm = rules_always_confirm[j];
91                    }
92                    id_card.rules = rules;
93                 }
94             }
95             id_card.password = entry.secret;
96             id_card_list.add(id_card);
97         });
98     }
99
100     public void store_id_cards () {
101         clear_keyring();
102         foreach (IdCard id_card in this.id_card_list) {
103             string[] rules_patterns = new string[id_card.rules.length];
104             string[] rules_always_conf = new string[id_card.rules.length];
105             
106             for (int i=0; i<id_card.rules.length; i++) {
107                 rules_patterns[i] = id_card.rules[i].pattern;
108                 rules_always_conf[i] = id_card.rules[i].always_confirm;
109             }
110             string patterns = string.joinv(";", rules_patterns);
111             string always_conf = string.joinv(";", rules_always_conf);
112             string services = string.joinv(";", id_card.services);
113             GnomeKeyring.AttributeList attributes = new GnomeKeyring.AttributeList();
114             uint32 item_id;
115             attributes.append_string(keyring_store_attribute, keyring_store_version);
116             attributes.append_string("Issuer", id_card.issuer);
117             attributes.append_string("Username", id_card.username);
118             attributes.append_string("DisplayName", id_card.display_name);
119             attributes.append_string("Services", services);
120             attributes.append_string("Rules-Pattern", patterns);
121             attributes.append_string("Rules-AlwaysConfirm", always_conf);
122             attributes.append_string("CA-Cert", id_card.trust_anchor.ca_cert);
123             attributes.append_string("Server-Cert", id_card.trust_anchor.server_cert);
124             attributes.append_string("Subject", id_card.trust_anchor.subject);
125             attributes.append_string("Subject-Alt", id_card.trust_anchor.subject_alt);
126
127             GnomeKeyring.Result result = GnomeKeyring.item_create_sync(null,
128                 item_type, id_card.display_name,
129                 attributes, id_card.password, true, out item_id);
130             if (result != GnomeKeyring.Result.OK) {
131                 stdout.printf("GnomeKeyring.item_create_sync() failed. result: %d", result);
132             }
133         }
134         load_id_cards();
135     }
136
137     public KeyringStore () {
138         id_card_list = new LinkedList<IdCard>();
139         load_id_cards();
140     }
141 }
142
143 #endif