2 * Copyright (c) 2011-2014, JANET(UK)
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
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.
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.
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
34 [DBus (name = "org.janet.Moonshot")]
35 public class MoonshotServer : Object {
37 private static Log4Vala.Logger logger = get_logger("MoonshotServer");
39 private string app_name = "Moonshot";
41 private IdentityManagerApp parent_app;
43 public MoonshotServer (IdentityManagerApp app)
45 logger.trace("MoonshotServer.<constructor>; app=" + (app == null ? "null" : "non-null"));
46 this.parent_app = app;
51 logger.trace("MoonshotServer.show_ui");
53 if (parent_app.view == null) {
54 stderr.printf(app_name, "show_ui: parent_app.view is null!\n");
55 logger.warn("show_ui: parent_app.view is null!");
59 parent_app.explicitly_launched = true;
60 logger.trace("MoonshotServer.show_ui: returning true");
64 private async bool get_identity (string nai,
68 out string password_out,
69 out string server_certificate_hash,
70 out string ca_certificate,
71 out string subject_name_constraint,
72 out string subject_alt_name_constraint)
74 logger.trace(@"MoonshotServer.get_identity: nai='$nai'; service='$service'");
76 var request = new IdentityRequest (parent_app,
80 request.set_callback ((IdentityRequest) => get_identity.callback());
81 logger.trace(@"MoonshotServer.get_identity: Calling request.execute()");
83 logger.trace(@"MoonshotServer.get_identity: Back from request.execute()");
85 logger.trace(@"MoonshotServer.get_identity: back from yield");
89 server_certificate_hash = "";
91 subject_name_constraint = "";
92 subject_alt_name_constraint = "";
94 var id_card = request.id_card;
96 if ((id_card != null) && (id_card.display_name != IdCard.NO_IDENTITY)) {
97 nai_out = id_card.nai;
98 if ((request.password!=null) && (request.password != ""))
99 password_out = request.password;
101 password_out = id_card.password;
103 server_certificate_hash = id_card.trust_anchor.server_cert;
104 ca_certificate = id_card.trust_anchor.ca_cert;
105 subject_name_constraint = id_card.trust_anchor.subject;
106 subject_alt_name_constraint = id_card.trust_anchor.subject_alt;
110 if (password_out == null)
112 if (server_certificate_hash == null)
113 server_certificate_hash = "";
114 if (ca_certificate == null)
116 if (subject_name_constraint == null)
117 subject_name_constraint = "";
118 if (subject_alt_name_constraint == null)
119 subject_alt_name_constraint = "";
121 logger.trace("MoonshotServer.get_identity: returning true");
126 logger.trace("MoonshotServer.get_identity: returning false");
130 public async bool get_default_identity (out string nai_out,
131 out string password_out,
132 out string server_certificate_hash,
133 out string ca_certificate,
134 out string subject_name_constraint,
135 out string subject_alt_name_constraint)
137 logger.trace("MoonshotServer.get_default_identity");
139 var request = new IdentityRequest.default (parent_app);
140 request.set_callback ((IdentityRequest) => get_default_identity.callback());
146 server_certificate_hash = "";
148 subject_name_constraint = "";
149 subject_alt_name_constraint = "";
151 if (request.id_card != null)
153 nai_out = request.id_card.nai;
154 password_out = request.id_card.password;
156 server_certificate_hash = request.id_card.trust_anchor.server_cert;
157 ca_certificate = request.id_card.trust_anchor.ca_cert;
158 subject_name_constraint = request.id_card.trust_anchor.subject;
159 subject_alt_name_constraint = request.id_card.trust_anchor.subject_alt;
163 if (password_out == null)
165 if (server_certificate_hash == null)
166 server_certificate_hash = "";
167 if (ca_certificate == null)
169 if (subject_name_constraint == null)
170 subject_name_constraint = "";
171 if (subject_alt_name_constraint == null)
172 subject_alt_name_constraint = "";
174 logger.trace("MoonshotServer.get_default_identity: returning true");
181 public bool install_id_card (string display_name,
185 string[] ?rules_patterns,
186 string[] ?rules_always_confirm,
192 int force_flat_file_store)
194 IdCard idcard = new IdCard ();
196 idcard.display_name = display_name;
197 idcard.username = user_name;
198 idcard.password = password;
199 if ((password != null) && (password != ""))
200 idcard.store_password = true;
201 idcard.issuer = realm;
202 idcard.services = services;
203 idcard.trust_anchor.ca_cert = ca_cert;
204 idcard.trust_anchor.subject = subject;
205 idcard.trust_anchor.subject_alt = subject_alt;
206 idcard.trust_anchor.server_cert = server_cert;
208 if (rules_patterns.length == rules_always_confirm.length)
210 /* workaround Centos vala array property bug: use temp array */
211 Rule[] rules = new Rule[rules_patterns.length];
213 for (int i=0; i<rules.length; i++)
215 rules[i].pattern = rules_patterns[i];
216 rules[i].always_confirm = rules_always_confirm[i];
218 idcard.rules = rules;
221 return parent_app.add_identity (idcard, force_flat_file_store!=0);
225 public int install_from_file (string file_name)
227 var webp = new WebProvisioning.Parser (file_name);
231 int installed_cards = 0;
232 foreach (IdCard card in WebProvisioning.cards)
234 string[] rules_patterns = {};
235 string[] rules_always_confirm = {};
237 if (card.rules.length > 0)
240 rules_patterns = new string[card.rules.length];
241 rules_always_confirm = new string[card.rules.length];
242 foreach (Rule r in card.rules)
244 rules_patterns[i] = r.pattern;
245 rules_always_confirm[i] = r.always_confirm;
250 result = install_id_card (card.display_name,
255 rules_always_confirm,
257 card.trust_anchor.ca_cert,
258 card.trust_anchor.subject,
259 card.trust_anchor.subject_alt,
260 card.trust_anchor.server_cert,
266 return installed_cards;
274 using MoonshotRpcInterface;
276 /* This class must be a singleton, because we use a global RPC
277 * binding handle. I cannot picture a situation where more than
278 * one instance of the same interface would be needed so this
279 * shouldn't be a problem.
281 * Shutdown is automatically done by the RPC runtime when the
284 public class MoonshotServer : Object {
285 private static IdentityManagerApp parent_app;
287 private static MoonshotServer instance = null;
289 public static void start (IdentityManagerApp app)
292 Rpc.server_start (MoonshotRpcInterface.spec, "/org/janet/Moonshot", Rpc.Flags.PER_USER);
295 public static MoonshotServer get_instance ()
297 if (instance == null)
298 instance = new MoonshotServer ();
302 [CCode (cname = "moonshot_get_identity_rpc")]
303 public static void get_identity (Rpc.AsyncCall call,
308 ref string password_out,
309 ref string server_certificate_hash,
310 ref string ca_certificate,
311 ref string subject_name_constraint,
312 ref string subject_alt_name_constraint)
314 logger.trace("(static) get_identity");
318 var request = new IdentityRequest (parent_app,
323 // Pass execution to the main loop and block the RPC thread
324 request.mutex = new Mutex ();
325 request.cond = new Cond ();
326 request.set_callback (return_identity_cb);
328 request.mutex.lock ();
329 Idle.add (request.execute);
331 while (request.complete == false)
332 request.cond.wait (request.mutex);
336 server_certificate_hash = "";
338 subject_name_constraint = "";
339 subject_alt_name_constraint = "";
341 var id_card = request.id_card;
343 if (id_card != null) {
344 // The strings are freed by the RPC runtime
345 nai_out = id_card.nai;
346 password_out = id_card.password;
347 server_certificate_hash = id_card.trust_anchor.server_cert;
348 ca_certificate = id_card.trust_anchor.ca_cert;
349 subject_name_constraint = id_card.trust_anchor.subject;
350 subject_alt_name_constraint = id_card.trust_anchor.subject_alt;
352 return_if_fail (nai_out != null);
353 return_if_fail (password_out != null);
354 return_if_fail (server_certificate_hash != null);
355 return_if_fail (ca_certificate != null);
356 return_if_fail (subject_name_constraint != null);
357 return_if_fail (subject_alt_name_constraint != null);
362 // The outputs must be set before this function is called. For this
363 // reason they are 'ref' not 'out' parameters - Vala assigns to the
364 // 'out' parameters only at the end of the function, which is too
366 call.return (&result);
368 request.cond.signal ();
369 request.mutex.unlock ();
372 [CCode (cname = "moonshot_get_default_identity_rpc")]
373 public static void get_default_identity (Rpc.AsyncCall call,
375 ref string password_out,
376 ref string server_certificate_hash,
377 ref string ca_certificate,
378 ref string subject_name_constraint,
379 ref string subject_alt_name_constraint)
381 logger.trace("(static) get_default_identity");
385 var request = new IdentityRequest.default (parent_app);
386 request.mutex = new Mutex ();
387 request.cond = new Cond ();
388 request.set_callback (return_identity_cb);
390 request.mutex.lock ();
391 Idle.add (request.execute);
393 while (request.complete == false)
394 request.cond.wait (request.mutex);
398 server_certificate_hash = "";
400 subject_name_constraint = "";
401 subject_alt_name_constraint = "";
403 if (request.id_card != null)
405 nai_out = request.id_card.nai;
406 password_out = request.id_card.password;
407 server_certificate_hash = "certificate";
409 return_if_fail (nai_out != null);
410 return_if_fail (password_out != null);
411 return_if_fail (server_certificate_hash != null);
412 return_if_fail (ca_certificate != null);
413 return_if_fail (subject_name_constraint != null);
414 return_if_fail (subject_alt_name_constraint != null);
423 call.return (&result);
425 request.cond.signal ();
426 request.mutex.unlock ();
429 // Called from the main loop thread when an identity has
431 static void return_identity_cb (IdentityRequest request) {
432 // Notify the RPC thread that the request is complete
433 request.mutex.lock ();
434 request.cond.signal ();
436 // Block the main loop until the RPC call has returned
437 // to avoid any races
438 request.cond.wait (request.mutex);
439 request.mutex.unlock ();
442 [CCode (cname = "moonshot_install_id_card_rpc")]
443 public static bool install_id_card (string display_name,
447 string[] rules_patterns,
448 string[] rules_always_confirm,
454 bool force_flat_file_store)
456 logger.trace("(static) install_id_card");
458 IdCard idcard = new IdCard ();
459 bool success = false;
460 Mutex mutex = new Mutex();
461 Cond cond = new Cond();
463 idcard.display_name = display_name;
464 idcard.username = user_name;
465 idcard.password = password;
466 idcard.issuer = realm;
467 idcard.services = services;
468 idcard.trust_anchor.ca_cert = ca_cert;
469 idcard.trust_anchor.subject = subject;
470 idcard.trust_anchor.subject_alt = subject_alt;
471 idcard.trust_anchor.server_cert = server_cert;
473 if (rules_patterns.length == rules_always_confirm.length)
475 idcard.rules = new Rule[rules_patterns.length];
477 for (int i=0; i<idcard.rules.length; i++)
479 idcard.rules[i].pattern = rules_patterns[i];
480 idcard.rules[i].always_confirm = rules_always_confirm[i];
486 // Defer addition to the main loop thread.
489 success = parent_app.add_identity (idcard, force_flat_file_store);