Cleaning up compilation warnings
[moonshot-ui.git] / src / moonshot-provisioning-common.vala
1 /*
2  * Copyright (c) 2011-2016, JANET(UK)
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * 3. Neither the name of JANET(UK) nor the names of its contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31 */
32
33
34
35 namespace WebProvisioning
36 {
37     bool check_stack(SList<string> stack, string[] reference) {
38
39         if (stack.length() < reference.length)
40             return false;
41
42         for (int i = 0; i < reference.length; i++)
43         {
44             if (stack.nth_data(i) != reference[i])
45                 return false;
46         }
47
48         return true;
49     }
50
51     bool always_confirm_handler(SList<string> stack)
52     {
53         string[] always_confirm_path = {"always-confirm", "rule", "selection-rules", "identity", "identities"};
54
55         return check_stack(stack, always_confirm_path);
56     }
57
58     bool
59     pattern_handler(SList<string> stack)
60     {
61         string[] pattern_path = {"pattern", "rule", "selection-rules", "identity", "identities"};
62
63         return check_stack(stack, pattern_path);
64     }
65
66     bool server_cert_handler(SList<string> stack)
67     {
68         string[] server_cert_path = {"server-cert", "trust-anchor", "identity", "identities"};
69
70         return check_stack(stack, server_cert_path);
71     }
72
73     bool subject_alt_handler(SList<string> stack)
74     {
75         string[] subject_alt_path = {"subject-alt", "trust-anchor", "identity", "identities"};
76
77         return check_stack(stack, subject_alt_path);
78     }
79
80     bool subject_handler(SList<string> stack)
81     {
82         string[] subject_path = {"subject", "trust-anchor", "identity", "identities"};
83
84         return check_stack(stack, subject_path);
85     }
86
87     bool ca_cert_handler(SList<string> stack)
88     {
89         string[] ca_path = {"ca-cert", "trust-anchor", "identity", "identities"};
90
91         return check_stack(stack, ca_path);
92     }
93
94     bool realm_handler(SList<string> stack)
95     {
96         string[] realm_path = {"realm", "identity", "identities"};
97
98         return check_stack(stack, realm_path);
99     }
100
101     bool password_handler(SList<string> stack)
102     {
103         string[] password_path = {"password", "identity", "identities"};
104
105         return check_stack(stack, password_path);
106     }
107
108     bool user_handler(SList<string> stack)
109     {
110         string[] user_path = {"user", "identity", "identities"};
111
112         return check_stack(stack, user_path);
113     }
114
115     bool display_name_handler(SList<string> stack)
116     {
117         string[] display_name_path = {"display-name", "identity", "identities"};
118
119         return check_stack(stack, display_name_path);
120     }
121
122     public class Parser : Object
123     {
124         // private static MoonshotLogger logger = new MoonshotLogger("WebProvisioning");
125
126         private void start_element_func(MarkupParseContext context,
127                                         string element_name,
128                                         string[] attribute_names,
129                                         string[] attribute_values) throws MarkupError
130             {
131                 if (element_name == "identity")
132                 {
133                     card = new IdCard();
134                     _cards += card;
135
136                     ta_ca_cert = "";
137                     ta_server_cert = "";
138                     ta_subject = "";
139                     ta_subject_alt = "";
140                 }
141                 else if (element_name == "rule")
142                 {
143                     card.add_rule(Rule());
144                 }
145             }
146
147             private void end_element_func(MarkupParseContext context,
148                                           string element_name) throws MarkupError
149             {
150                 if (element_name == "identity")
151                 {
152                     if (ta_ca_cert != "" || ta_server_cert != "") {
153                         var ta = new TrustAnchor(ta_ca_cert,
154                                                  ta_server_cert,
155                                                  ta_subject,
156                                                  ta_subject_alt,
157                                                  false);
158                         card.set_trust_anchor_from_store(ta);
159                     }
160                 }
161             }
162
163             private void
164             text_element_func(MarkupParseContext context,
165                               string             text,
166                               size_t             text_len) throws MarkupError {
167                 unowned SList<string> stack = context.get_element_stack();
168
169                 if (text_len < 1)
170                     return;
171
172                 if (stack.nth_data(0) == "display-name" && display_name_handler(stack))
173                 {
174                     card.display_name = text;
175                 }
176                 else if (stack.nth_data(0) == "user" && user_handler(stack))
177                 {
178                     card.username = text;
179                 }
180                 else if (stack.nth_data(0) == "password" && password_handler(stack))
181                 {
182                     card.password = text;
183                 }
184                 else if (stack.nth_data(0) == "realm" && realm_handler(stack))
185                 {
186                     card.issuer = text;
187                 }
188                 else if (stack.nth_data(0) == "service")
189                 {
190                     card.services.add(text);
191                 }
192
193                 /* Rules */
194                 else if (stack.nth_data(0) == "pattern" && pattern_handler(stack))
195                 {
196                     /* use temp array to workaround valac 0.10 bug accessing array property length */
197                     var temp = card.rules;
198                     card.rules[temp.length - 1].pattern = text;
199                 }
200                 else if (stack.nth_data(0) == "always-confirm" && always_confirm_handler(stack))
201                 {
202                     if (text == "true" || text == "false") {
203                         /* use temp array to workaround valac 0.10 bug accessing array property length*/
204                         var temp = card.rules;
205                         card.rules[temp.length - 1].always_confirm = text;
206                     }
207                 }
208                 else if (stack.nth_data(0) == "ca-cert" && ca_cert_handler(stack))
209                 {
210                     ta_ca_cert = text ?? "";
211                 }
212                 else if (stack.nth_data(0) == "server-cert" && server_cert_handler(stack))
213                 {
214                     ta_server_cert = text ?? "";
215                 }
216                 else if (stack.nth_data(0) == "subject" && subject_handler(stack))
217                 {
218                     ta_subject = text;
219                 }
220                 else if (stack.nth_data(0) == "subject-alt" && subject_alt_handler(stack))
221                 {
222                     ta_subject_alt = text;
223                 }
224             }
225
226         private const MarkupParser parser = {
227             start_element_func, end_element_func, text_element_func, null, null
228         };
229
230         private MarkupParseContext ctx;
231
232         private string       text;
233         private string       path;
234
235         private string ta_ca_cert;
236         private string ta_server_cert;
237         private string ta_subject;
238         private string ta_subject_alt;
239
240         private IdCard card;
241         private IdCard[] _cards = {};
242
243         public IdCard[] cards {
244             get {return _cards;}
245             private set {_cards = value ?? new IdCard[0] ;}
246         }
247
248         public Parser(string path) {
249
250             ctx = new MarkupParseContext(parser, 0, this, null);
251
252             text = "";
253             this.path = path;
254
255             var file = File.new_for_path(path);
256
257             try
258             {
259                 var dis = new DataInputStream(file.read());
260                 string line;
261                 while ((line = dis.read_line(null)) != null) {
262                     text += line;
263
264                     // Preserve newlines.
265                     //
266                     // This may add an extra newline at EOF. Maybe use
267                     // dis.read_upto("\n", ...) followed by dis.read_byte() instead?
268                     text += "\n";
269                 }
270             }
271             catch(GLib.Error e)
272             {
273                 error("Could not retreive file size");
274             }
275         }
276
277         public void parse() {
278             try
279             {
280                 ctx.parse(text, text.length);
281             }
282             catch(GLib.Error e)
283             {
284                 error("Could not parse %s, invalid content", path);
285             }
286         }
287     }
288 }