Fixed S598 [bug] 911172 - File Association
[moonshot-ui.git] / src / moonshot-server.vala
1 #if IPC_DBUS
2
3 [DBus (name = "org.janet.Moonshot")]
4 public class MoonshotServer : Object {
5
6     private static IdentityManagerView main_window;
7
8     public MoonshotServer (Gtk.Window window)
9     {
10         this.main_window = (IdentityManagerView) window;
11     }
12
13     public async bool get_identity (string nai,
14                                     string password,
15                                     string service,
16                                     out string nai_out,
17                                     out string password_out,
18                                     out string server_certificate_hash,
19                                     out string ca_certificate,
20                                     out string subject_name_constraint,
21                                     out string subject_alt_name_constraint)
22     {
23         var request = new IdentityRequest (main_window,
24                                            nai,
25                                            password,
26                                            service);
27         request.set_callback ((IdentityRequest) => get_identity.callback());
28         request.execute ();
29         yield;
30
31         nai_out = "";
32         password_out = "";
33         server_certificate_hash = "";
34         ca_certificate = "";
35         subject_name_constraint = "";
36         subject_alt_name_constraint = "";
37
38         var id_card = request.id_card;
39
40         if (id_card != null) {
41             nai_out = id_card.nai;
42             password_out = id_card.password;
43
44             server_certificate_hash = id_card.trust_anchor.server_cert;
45             ca_certificate = id_card.trust_anchor.ca_cert;
46             subject_name_constraint = id_card.trust_anchor.subject;
47             subject_alt_name_constraint = id_card.trust_anchor.subject_alt;
48
49             if (nai_out == null)
50                 nai_out = "";
51             if (password_out == null)
52                 password_out = "";
53             if (server_certificate_hash == null)
54                 server_certificate_hash = "";
55             if (ca_certificate == null)
56                 ca_certificate = "";
57             if (subject_name_constraint == null)
58                 subject_name_constraint = "";
59             if (subject_alt_name_constraint == null)
60                 subject_alt_name_constraint = "";
61
62             return true;
63         }
64
65         return false;
66     }
67
68     public async bool get_default_identity (out string nai_out,
69                                             out string password_out,
70                                             out string server_certificate_hash,
71                                             out string ca_certificate,
72                                             out string subject_name_constraint,
73                                             out string subject_alt_name_constraint)
74     {
75         var request = new IdentityRequest.default (main_window);
76         request.set_callback ((IdentityRequest) => get_default_identity.callback());
77         request.execute ();
78         yield;
79
80         nai_out = "";
81         password_out = "";
82         server_certificate_hash = "";
83         ca_certificate = "";
84         subject_name_constraint = "";
85         subject_alt_name_constraint = "";
86
87         if (request.id_card != null)
88         {
89             nai_out = request.id_card.nai;
90             password_out = request.id_card.password;
91
92             server_certificate_hash = request.id_card.trust_anchor.server_cert;
93             ca_certificate = request.id_card.trust_anchor.ca_cert;
94             subject_name_constraint = request.id_card.trust_anchor.subject;
95             subject_alt_name_constraint = request.id_card.trust_anchor.subject_alt;
96
97             if (nai_out == null)
98                 nai_out = "";
99             if (password_out == null)
100                 password_out = "";
101             if (server_certificate_hash == null)
102                 server_certificate_hash = "";
103             if (ca_certificate == null)
104                 ca_certificate = "";
105             if (subject_name_constraint == null)
106                 subject_name_constraint = "";
107             if (subject_alt_name_constraint == null)
108                 subject_alt_name_constraint = "";
109
110             return true;
111         }
112
113         return false;
114     }
115
116     public bool install_id_card (string   display_name,
117                                  string   user_name,
118                                  string   ?password,
119                                  string   ?realm,
120                                  string[] ?rules_patterns,
121                                  string[] ?rules_always_confirm,
122                                  string[] ?services,
123                                  string   ?ca_cert,
124                                  string   ?subject,
125                                  string   ?subject_alt,
126                                  string   ?server_cert)
127     {
128       IdCard idcard = new IdCard ();
129
130       idcard.display_name = display_name;
131       idcard.username = user_name;
132       idcard.password = password;
133       idcard.issuer = realm;
134       idcard.services = services;
135       idcard.trust_anchor.ca_cert = ca_cert;
136       idcard.trust_anchor.subject = subject;
137       idcard.trust_anchor.subject_alt = subject_alt;
138       idcard.trust_anchor.server_cert = server_cert;
139
140       if (rules_patterns.length == rules_always_confirm.length)
141       {
142         idcard.rules = new Rule[rules_patterns.length];
143          
144         for (int i=0; i<idcard.rules.length; i++)
145         { 
146           idcard.rules[i].pattern = rules_patterns[i];
147           idcard.rules[i].always_confirm = rules_always_confirm[i];
148         }
149       }
150
151       return main_window.add_identity (idcard);
152     }
153
154
155     public bool install_from_file (string file_name)
156     {
157     var webp = new WebProvisioning.Parser (file_name);
158         print ("install_from_file()  file_name = %s", file_name);
159     webp.parse();
160     bool result = false;
161     
162     foreach (IdCard card in WebProvisioning.cards)
163     {
164       string[] rules_patterns = {};
165       string[] rules_always_confirm = {};
166         
167       if (card.rules.length > 0)
168       {
169         int i = 0;
170         rules_patterns = new string[card.rules.length];
171         rules_always_confirm = new string[card.rules.length];
172         foreach (Rule r in card.rules)
173         {
174           rules_patterns[i] = r.pattern;
175           rules_always_confirm[i] = r.always_confirm;
176           i++;
177         }
178       } 
179       result = install_id_card (card.display_name,
180                                 card.username,
181                                 card.password,
182                                 card.issuer,
183                                 rules_patterns,
184                                 rules_always_confirm,
185                                 card.services,
186                                 card.trust_anchor.ca_cert,
187                                 card.trust_anchor.subject,
188                                 card.trust_anchor.subject_alt,
189                                 card.trust_anchor.server_cert);
190        }
191
192 print ("install_from_file() result %s\n", result.to_string());
193     return result;
194     }
195
196 }
197
198
199 #elif IPC_MSRPC
200
201 using Rpc;
202 using MoonshotRpcInterface;
203
204 /* This class must be a singleton, because we use a global RPC
205  * binding handle. I cannot picture a situation where more than
206  * one instance of the same interface would be needed so this
207  * shouldn't be a problem.
208  *
209  * Shutdown is automatically done by the RPC runtime when the
210  * process ends
211  */
212 public class MoonshotServer : Object {
213     private static IdentityManagerView main_window;
214
215     private static MoonshotServer instance = null;
216
217     public static void start (Gtk.Window window)
218     {
219         main_window = (IdentityManagerView) window;
220         Rpc.server_start (MoonshotRpcInterface.spec, "/org/janet/Moonshot", Rpc.Flags.PER_USER);
221     }
222
223     public static MoonshotServer get_instance ()
224     {
225         if (instance == null)
226             instance = new MoonshotServer ();
227         return instance;
228     }
229
230     [CCode (cname = "moonshot_get_identity_rpc")]
231     public static void get_identity (Rpc.AsyncCall call,
232                                      string nai,
233                                      string password,
234                                      string service,
235                                      ref string nai_out,
236                                      ref string password_out,
237                                      ref string server_certificate_hash,
238                                      ref string ca_certificate,
239                                      ref string subject_name_constraint,
240                                      ref string subject_alt_name_constraint)
241     {
242         bool result = false;
243
244         var request = new IdentityRequest (main_window,
245                                            nai,
246                                            password,
247                                            service);
248
249         // Pass execution to the main loop and block the RPC thread
250         request.mutex = new Mutex ();
251         request.cond = new Cond ();
252         request.set_callback (return_identity_cb);
253
254         request.mutex.lock ();
255         Idle.add (request.execute);
256
257         while (request.complete == false)
258             request.cond.wait (request.mutex);
259
260         nai_out = "";
261         password_out = "";
262         server_certificate_hash = "";
263         ca_certificate = "";
264         subject_name_constraint = "";
265         subject_alt_name_constraint = "";
266
267         var id_card = request.id_card;
268
269         if (id_card == null) {
270             // The strings are freed by the RPC runtime
271             nai_out = id_card.nai;
272             password_out = id_card.password;
273             server_certificate_hash = "certificate";
274
275             return_if_fail (nai_out != null);
276             return_if_fail (password_out != null);
277             return_if_fail (server_certificate_hash != null);
278             return_if_fail (ca_certificate != null);
279             return_if_fail (subject_name_constraint != null);
280             return_if_fail (subject_alt_name_constraint != null);
281
282             result = true;
283         }
284
285         // The outputs must be set before this function is called. For this
286         // reason they are 'ref' not 'out' parameters - Vala assigns to the
287         // 'out' parameters only at the end of the function, which is too
288         // late.
289         call.return (&result);
290
291         request.cond.signal ();
292         request.mutex.unlock ();
293     }
294
295     [CCode (cname = "moonshot_get_default_identity_rpc")]
296     public static void get_default_identity (Rpc.AsyncCall call,
297                                              ref string nai_out,
298                                              ref string password_out,
299                                              ref string server_certificate_hash,
300                                              ref string ca_certificate,
301                                              ref string subject_name_constraint,
302                                              ref string subject_alt_name_constraint)
303     {
304         bool result;
305
306         var request = new IdentityRequest.default (main_window);
307         request.mutex = new Mutex ();
308         request.cond = new Cond ();
309         request.set_callback (return_identity_cb);
310
311         request.mutex.lock ();
312         Idle.add (request.execute);
313
314         while (request.complete == false)
315             request.cond.wait (request.mutex);
316
317         nai_out = "";
318         password_out = "";
319         server_certificate_hash = "";
320         ca_certificate = "";
321         subject_name_constraint = "";
322         subject_alt_name_constraint = "";
323
324         if (request.id_card != null)
325         {
326             nai_out = request.id_card.nai;
327             password_out = request.id_card.password;
328             server_certificate_hash = "certificate";
329
330             return_if_fail (nai_out != null);
331             return_if_fail (password_out != null);
332             return_if_fail (server_certificate_hash != null);
333             return_if_fail (ca_certificate != null);
334             return_if_fail (subject_name_constraint != null);
335             return_if_fail (subject_alt_name_constraint != null);
336
337             result = true;
338         }
339         else
340         {
341             result = false;
342         }
343
344         call.return (&result);
345
346         request.cond.signal ();
347         request.mutex.unlock ();
348     }
349
350     // Called from the main loop thread when an identity has
351     // been selected
352     static void return_identity_cb (IdentityRequest request) {
353         // Notify the RPC thread that the request is complete
354         request.mutex.lock ();
355         request.cond.signal ();
356
357         // Block the main loop until the RPC call has returned
358         // to avoid any races
359         request.cond.wait (request.mutex);
360         request.mutex.unlock ();
361     }
362
363     [CCode (cname = "moonshot_install_id_card_rpc")]
364     public static bool install_id_card (string     display_name,
365                                         string     user_name,
366                                         string     password,
367                                         string     realm,
368                                         string[]   rules_patterns,
369                                         string[]   rules_always_confirm,
370                                         string[]   services,
371                                         string     ca_cert,
372                                         string     subject,
373                                         string     subject_alt,
374                                         string     server_cert)
375     {
376         IdCard idcard = new IdCard ();
377         bool success = false;
378         Mutex mutex = new Mutex();
379         Cond cond = new Cond();
380
381         idcard.display_name = display_name;
382         idcard.username = user_name;
383         idcard.password = password;
384         idcard.issuer = realm;
385         idcard.services = services;
386         idcard.trust_anchor.ca_cert = ca_cert;
387         idcard.trust_anchor.subject = subject;
388         idcard.trust_anchor.subject_alt = subject_alt;
389         idcard.trust_anchor.server_cert = server_cert;
390
391         if (rules_patterns.length == rules_always_confirm.length)
392         {
393             idcard.rules = new Rule[rules_patterns.length];
394          
395             for (int i=0; i<idcard.rules.length; i++)
396             { 
397                 idcard.rules[i].pattern = rules_patterns[i];
398                 idcard.rules[i].always_confirm = rules_always_confirm[i];
399             }
400         }
401
402         mutex.lock ();
403
404         // Defer addition to the main loop thread.
405         Idle.add (() => {
406             mutex.lock ();
407             success = main_window.add_identity (idcard);
408             cond.signal ();
409             mutex.unlock ();
410             return false;
411         });
412
413         cond.wait (mutex);
414         mutex.unlock ();
415
416         return success;
417     }
418
419 }
420
421
422 #endif