2 * Copyright (c) 2011-2016, 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
37 using MoonshotRpcInterface;
39 /* This class must be a singleton, because we use a global RPC
40 * binding handle. I cannot picture a situation where more than
41 * one instance of the same interface would be needed so this
42 * shouldn't be a problem.
44 * Shutdown is automatically done by the RPC runtime when the
47 public class MoonshotServer : Object {
48 private static IdentityManagerApp parent_app;
50 private static MoonshotServer instance = null;
52 public static void start(IdentityManagerApp app)
55 Rpc.server_start(MoonshotRpcInterface.spec, "/org/janet/Moonshot", Rpc.Flags.PER_USER);
58 public static MoonshotServer get_instance()
61 instance = new MoonshotServer();
65 [CCode (cname = "moonshot_get_identity_rpc")]
66 public static void get_identity(Rpc.AsyncCall call,
71 ref string password_out,
72 ref string server_certificate_hash,
73 ref string ca_certificate,
74 ref string subject_name_constraint,
75 ref string subject_alt_name_constraint)
77 logger.trace("(static) get_identity");
81 var request = new IdentityRequest(parent_app,
86 // Pass execution to the main loop and block the RPC thread
87 request.mutex = new Mutex();
88 request.cond = new Cond();
89 request.set_callback(return_identity_cb);
92 Idle.add(request.execute);
94 while (request.complete == false)
95 request.cond.wait(request.mutex);
99 server_certificate_hash = "";
101 subject_name_constraint = "";
102 subject_alt_name_constraint = "";
104 var id_card = request.id_card;
106 if (id_card != null) {
107 // The strings are freed by the RPC runtime
108 nai_out = id_card.nai;
109 password_out = id_card.password;
110 server_certificate_hash = id_card.trust_anchor.server_cert;
111 ca_certificate = id_card.trust_anchor.ca_cert;
112 subject_name_constraint = id_card.trust_anchor.subject;
113 subject_alt_name_constraint = id_card.trust_anchor.subject_alt;
115 return_if_fail(nai_out != null);
116 return_if_fail(password_out != null);
117 return_if_fail(server_certificate_hash != null);
118 return_if_fail(ca_certificate != null);
119 return_if_fail(subject_name_constraint != null);
120 return_if_fail(subject_alt_name_constraint != null);
125 // The outputs must be set before this function is called. For this
126 // reason they are 'ref' not 'out' parameters - Vala assigns to the
127 // 'out' parameters only at the end of the function, which is too
129 call.return(&result);
131 request.cond.signal();
132 request.mutex.unlock();
135 [CCode (cname = "moonshot_get_default_identity_rpc")]
136 public static void get_default_identity(Rpc.AsyncCall call,
138 ref string password_out,
139 ref string server_certificate_hash,
140 ref string ca_certificate,
141 ref string subject_name_constraint,
142 ref string subject_alt_name_constraint)
144 logger.trace("(static) get_default_identity");
148 var request = new IdentityRequest.default(parent_app);
149 request.mutex = new Mutex();
150 request.cond = new Cond();
151 request.set_callback(return_identity_cb);
153 request.mutex.lock();
154 Idle.add(request.execute);
156 while (request.complete == false)
157 request.cond.wait(request.mutex);
161 server_certificate_hash = "";
163 subject_name_constraint = "";
164 subject_alt_name_constraint = "";
166 if (request.id_card != null)
168 nai_out = request.id_card.nai;
169 password_out = request.id_card.password;
170 server_certificate_hash = "certificate";
172 return_if_fail(nai_out != null);
173 return_if_fail(password_out != null);
174 return_if_fail(server_certificate_hash != null);
175 return_if_fail(ca_certificate != null);
176 return_if_fail(subject_name_constraint != null);
177 return_if_fail(subject_alt_name_constraint != null);
186 call.return(&result);
188 request.cond.signal();
189 request.mutex.unlock();
192 // Called from the main loop thread when an identity has
194 static void return_identity_cb(IdentityRequest request) {
195 // Notify the RPC thread that the request is complete
196 request.mutex.lock();
197 request.cond.signal();
199 // Block the main loop until the RPC call has returned
200 // to avoid any races
201 request.cond.wait(request.mutex);
202 request.mutex.unlock();
205 [CCode (cname = "moonshot_install_id_card_rpc")]
206 public static bool install_id_card(string display_name,
210 string[] rules_patterns,
211 string[] rules_always_confirm,
217 bool force_flat_file_store)
219 logger.trace("(static) install_id_card");
220 IdCard idcard = new IdCard();
222 bool success = false;
223 Mutex mutex = new Mutex();
224 Cond cond = new Cond();
226 idcard.display_name = display_name;
227 idcard.username = user_name;
228 idcard.password = password;
229 idcard.issuer = realm;
230 idcard.services = services;
231 idcard.trust_anchor.ca_cert = ca_cert;
232 idcard.trust_anchor.subject = subject;
233 idcard.trust_anchor.subject_alt = subject_alt;
234 idcard.trust_anchor.server_cert = server_cert;
236 if (rules_patterns.length == rules_always_confirm.length)
238 idcard.rules = new Rule[rules_patterns.length];
240 for (int i = 0; i < idcard.rules.length; i++)
242 idcard.rules[i].pattern = rules_patterns[i];
243 idcard.rules[i].always_confirm = rules_always_confirm[i];
249 ArrayList<IdCard>? old_duplicates = null;
250 // Defer addition to the main loop thread.
253 success = parent_app.add_identity(idcard, force_flat_file_store, out old_duplicates);
254 foreach (IdCard id_card in old_duplicates) {
255 stdout.printf("removing duplicate id for '%s'\n", new_card.nai);