75e64eca8ef0e66f9794cb70cfc33ace210dadbf
[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 MainWindow main_window;
7
8     public MoonshotServer (Gtk.Window window)
9     {
10         this.main_window = (MainWindow) 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 = "certificate";
45
46             // User should have been prompted if there was no p/w.
47             return_if_fail (nai_out != null);
48             return_if_fail (password_out != null);
49
50             return true;
51         }
52
53         return false;
54     }
55
56     public async bool get_default_identity (out string nai_out,
57                                             out string password_out,
58                                             out string server_certificate_hash,
59                                             out string ca_certificate,
60                                             out string subject_name_constraint,
61                                             out string subject_alt_name_constraint)
62     {
63         var request = new IdentityRequest.default (main_window);
64         request.set_callback ((IdentityRequest) => get_default_identity.callback());
65         request.execute ();
66         yield;
67
68         nai_out = "";
69         password_out = "";
70         server_certificate_hash = "";
71         ca_certificate = "";
72         subject_name_constraint = "";
73         subject_alt_name_constraint = "";
74
75         if (request.id_card != null)
76         {
77             nai_out = request.id_card.nai;
78             password_out = request.id_card.password;
79
80             server_certificate_hash = "certificate";
81
82             // User should have been prompted if there was no p/w.
83             return_val_if_fail (nai_out != null, false);
84             return_val_if_fail (password_out != null, false);
85
86             return true;
87         }
88
89         return false;
90     }
91
92     public bool install_id_card (string   display_name,
93                                  string   user_name,
94                                  string   password,
95                                  string   realm,
96                                  string[] rules_patterns,
97                                  string[] rules_always_confirm,
98                                  string[] services,
99                                  string   ca_cert,
100                                  string   subject,
101                                  string   subject_alt,
102                                  string   server_cert)
103     {
104       IdCard idcard = new IdCard ();
105
106       idcard.display_name = display_name;
107       idcard.username = user_name;
108       idcard.password = password;
109       idcard.issuer = realm;
110       idcard.services = services;
111       idcard.trust_anchor.ca_cert = ca_cert;
112       idcard.trust_anchor.subject = subject;
113       idcard.trust_anchor.subject_alt = subject_alt;
114       idcard.trust_anchor.server_cert = server_cert;
115
116       if (rules_patterns.length == rules_always_confirm.length)
117       {
118         idcard.rules = new Rule[rules_patterns.length];
119          
120         for (int i=0; i<idcard.rules.length; i++)
121         { 
122           idcard.rules[i].pattern = rules_patterns[i];
123           idcard.rules[i].always_confirm = rules_always_confirm[i];
124         }
125       }
126
127       return this.main_window.add_identity (idcard);
128     }
129 }
130
131 #elif IPC_MSRPC
132
133 using Rpc;
134 using MoonshotRpcInterface;
135
136 /* This class must be a singleton, because we use a global RPC
137  * binding handle. I cannot picture a situation where more than
138  * one instance of the same interface would be needed so this
139  * shouldn't be a problem.
140  *
141  * Shutdown is automatically done by the RPC runtime when the
142  * process ends
143  */
144 public class MoonshotServer : Object {
145     private static MainWindow main_window;
146
147     private static MoonshotServer instance = null;
148
149     public static void start (Gtk.Window window)
150     {
151         main_window = (MainWindow) window;
152         Rpc.server_start (MoonshotRpcInterface.spec, "/org/janet/Moonshot", Rpc.Flags.PER_USER);
153     }
154
155     public static MoonshotServer get_instance ()
156     {
157         if (instance == null)
158             instance = new MoonshotServer ();
159         return instance;
160     }
161
162     [CCode (cname = "moonshot_get_identity_rpc")]
163     public static void get_identity (Rpc.AsyncCall call,
164                                      string nai,
165                                      string password,
166                                      string service,
167                                      ref string nai_out,
168                                      ref string password_out,
169                                      ref string server_certificate_hash,
170                                      ref string ca_certificate,
171                                      ref string subject_name_constraint,
172                                      ref string subject_alt_name_constraint)
173     {
174         bool result = false;
175
176         var request = new IdentityRequest (main_window,
177                                            nai,
178                                            password,
179                                            service);
180
181         // Pass execution to the main loop and block the RPC thread
182         request.mutex = new Mutex ();
183         request.cond = new Cond ();
184         request.set_callback (return_identity_cb);
185
186         request.mutex.lock ();
187         Idle.add (request.execute);
188
189         while (request.complete == false)
190             request.cond.wait (request.mutex);
191
192         nai_out = "";
193         password_out = "";
194         server_certificate_hash = "";
195         ca_certificate = "";
196         subject_name_constraint = "";
197         subject_alt_name_constraint = "";
198
199         var id_card = request.id_card;
200
201         if (id_card == null) {
202             // The strings are freed by the RPC runtime
203             nai_out = id_card.nai;
204             password_out = id_card.password;
205             server_certificate_hash = "certificate";
206
207             return_if_fail (nai_out != null);
208             return_if_fail (password_out != null);
209             return_if_fail (server_certificate_hash != null);
210             return_if_fail (ca_certificate != null);
211             return_if_fail (subject_name_constraint != null);
212             return_if_fail (subject_alt_name_constraint != null);
213
214             result = true;
215         }
216
217         // The outputs must be set before this function is called. For this
218         // reason they are 'ref' not 'out' parameters - Vala assigns to the
219         // 'out' parameters only at the end of the function, which is too
220         // late.
221         call.return (&result);
222
223         request.cond.signal ();
224         request.mutex.unlock ();
225     }
226
227     [CCode (cname = "moonshot_get_default_identity_rpc")]
228     public static void get_default_identity (Rpc.AsyncCall call,
229                                              ref string nai_out,
230                                              ref string password_out,
231                                              ref string server_certificate_hash,
232                                              ref string ca_certificate,
233                                              ref string subject_name_constraint,
234                                              ref string subject_alt_name_constraint)
235     {
236         bool result;
237
238         var request = new IdentityRequest.default (main_window);
239         request.mutex = new Mutex ();
240         request.cond = new Cond ();
241         request.set_callback (return_identity_cb);
242
243         request.mutex.lock ();
244         Idle.add (request.execute);
245
246         while (request.complete == false)
247             request.cond.wait (request.mutex);
248
249         nai_out = "";
250         password_out = "";
251         server_certificate_hash = "";
252         ca_certificate = "";
253         subject_name_constraint = "";
254         subject_alt_name_constraint = "";
255
256         if (request.id_card != null)
257         {
258             nai_out = request.id_card.nai;
259             password_out = request.id_card.password;
260             server_certificate_hash = "certificate";
261
262             return_if_fail (nai_out != null);
263             return_if_fail (password_out != null);
264             return_if_fail (server_certificate_hash != null);
265             return_if_fail (ca_certificate != null);
266             return_if_fail (subject_name_constraint != null);
267             return_if_fail (subject_alt_name_constraint != null);
268
269             result = true;
270         }
271         else
272         {
273             result = false;
274         }
275
276         call.return (&result);
277
278         request.cond.signal ();
279         request.mutex.unlock ();
280     }
281
282     // Called from the main loop thread when an identity has
283     // been selected
284     static void return_identity_cb (IdentityRequest request) {
285         // Notify the RPC thread that the request is complete
286         request.mutex.lock ();
287         request.cond.signal ();
288
289         // Block the main loop until the RPC call has returned
290         // to avoid any races
291         request.cond.wait (request.mutex);
292         request.mutex.unlock ();
293     }
294
295     [CCode (cname = "moonshot_install_id_card_rpc")]
296     public static bool install_id_card (string     display_name,
297                                         string     user_name,
298                                         string     password,
299                                         string     realm,
300                                         string[]   rules_patterns,
301                                         string[]   rules_always_confirm,
302                                         string[]   services,
303                                         string     ca_cert,
304                                         string     subject,
305                                         string     subject_alt,
306                                         string     server_cert)
307     {
308         IdCard idcard = new IdCard ();
309         bool success = false;
310         Mutex mutex = new Mutex();
311         Cond cond = new Cond();
312
313         idcard.display_name = display_name;
314         idcard.username = user_name;
315         idcard.password = password;
316         idcard.issuer = realm;
317         idcard.services = services;
318         idcard.trust_anchor.ca_cert = ca_cert;
319         idcard.trust_anchor.subject = subject;
320         idcard.trust_anchor.subject_alt = subject_alt;
321         idcard.trust_anchor.server_cert = server_cert;
322
323         if (rules_patterns.length == rules_always_confirm.length)
324         {
325             idcard.rules = new Rule[rules_patterns.length];
326          
327             for (int i=0; i<idcard.rules.length; i++)
328             { 
329                 idcard.rules[i].pattern = rules_patterns[i];
330                 idcard.rules[i].always_confirm = rules_always_confirm[i];
331             }
332         }
333
334         mutex.lock ();
335
336         // Defer addition to the main loop thread.
337         Idle.add (() => {
338             mutex.lock ();
339             success = main_window.add_identity (idcard);
340             cond.signal ();
341             mutex.unlock ();
342             return false;
343         });
344
345         cond.wait (mutex);
346         mutex.unlock ();
347
348         return success;
349     }
350 }
351
352 #endif