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