Merge branch 'master' of ssh://69.25.196.28:822/srv/git/moonshot-ui
[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 async bool install_id_card (string   display_name,
93                                        string   user_name,
94                                        string   password,
95                                        string   realm,
96                                        Rule[]   rules,
97                                        string[] services,
98                                        string   ca_cert,
99                                        string   subject,
100                                        string   subject_alt,
101                                        string   server_cert)
102     {
103       IdCard idcard = new IdCard ();
104       
105       idcard.display_name = display_name;
106       idcard.username = user_name;
107       idcard.password = password;
108       idcard.issuer = realm;
109       idcard.rules = rules;
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       /* TODO: Ask for confirmation */
116       /* TODO: Check if display name already exists */
117       
118       return true;
119     }
120                                        
121 }
122
123 #elif IPC_MSRPC
124
125 using Rpc;
126 using MoonshotRpcInterface;
127
128 /* This class must be a singleton, because we use a global RPC
129  * binding handle. I cannot picture a situation where more than
130  * one instance of the same interface would be needed so this
131  * shouldn't be a problem.
132  *
133  * Shutdown is automatically done by the RPC runtime when the
134  * process ends
135  */
136 public class MoonshotServer : Object {
137     private static MainWindow main_window;
138
139     private static MoonshotServer instance = null;
140
141     public static void start (Gtk.Window window)
142     {
143         main_window = (MainWindow) window;
144         Rpc.server_start (MoonshotRpcInterface.spec, "/org/janet/Moonshot", Rpc.Flags.PER_USER);
145     }
146
147     public static MoonshotServer get_instance ()
148     {
149         if (instance == null)
150             instance = new MoonshotServer ();
151         return instance;
152     }
153
154     [CCode (cname = "moonshot_get_identity_rpc")]
155     public static void get_identity (Rpc.AsyncCall call,
156                                      string nai,
157                                      string password,
158                                      string service,
159                                      ref string nai_out,
160                                      ref string password_out,
161                                      ref string server_certificate_hash,
162                                      ref string ca_certificate,
163                                      ref string subject_name_constraint,
164                                      ref string subject_alt_name_constraint)
165     {
166         bool result = false;
167
168         var request = new IdentityRequest (main_window,
169                                            nai,
170                                            password,
171                                            service);
172
173         // Pass execution to the main loop and block the RPC thread
174         request.mutex = new Mutex ();
175         request.cond = new Cond ();
176         request.set_callback (return_identity_cb);
177
178         request.mutex.lock ();
179         Idle.add (request.execute);
180
181         while (request.complete == false)
182             request.cond.wait (request.mutex);
183
184         nai_out = "";
185         password_out = "";
186         server_certificate_hash = "";
187         ca_certificate = "";
188         subject_name_constraint = "";
189         subject_alt_name_constraint = "";
190
191         var id_card = request.id_card;
192
193         if (id_card == null) {
194             // The strings are freed by the RPC runtime
195             nai_out = id_card.nai;
196             password_out = id_card.password;
197             server_certificate_hash = "certificate";
198
199             return_if_fail (nai_out != null);
200             return_if_fail (password_out != null);
201             return_if_fail (server_certificate_hash != null);
202             return_if_fail (ca_certificate != null);
203             return_if_fail (subject_name_constraint != null);
204             return_if_fail (subject_alt_name_constraint != null);
205
206             result = true;
207         }
208
209         // The outputs must be set before this function is called. For this
210         // reason they are 'ref' not 'out' parameters - Vala assigns to the
211         // 'out' parameters only at the end of the function, which is too
212         // late.
213         call.return (&result);
214
215         request.cond.signal ();
216         request.mutex.unlock ();
217     }
218
219     [CCode (cname = "moonshot_get_default_identity_rpc")]
220     public static void get_default_identity (Rpc.AsyncCall call,
221                                              ref string nai_out,
222                                              ref string password_out,
223                                              ref string server_certificate_hash,
224                                              ref string ca_certificate,
225                                              ref string subject_name_constraint,
226                                              ref string subject_alt_name_constraint)
227     {
228         bool result;
229
230         var request = new IdentityRequest.default (main_window);
231         request.mutex = new Mutex ();
232         request.cond = new Cond ();
233         request.set_callback (return_identity_cb);
234
235         request.mutex.lock ();
236         Idle.add (request.execute);
237
238         while (request.complete == false)
239             request.cond.wait (request.mutex);
240
241         nai_out = "";
242         password_out = "";
243         server_certificate_hash = "";
244         ca_certificate = "";
245         subject_name_constraint = "";
246         subject_alt_name_constraint = "";
247
248         if (request.id_card != null)
249         {
250             nai_out = request.id_card.nai;
251             password_out = request.id_card.password;
252             server_certificate_hash = "certificate";
253
254             return_if_fail (nai_out != null);
255             return_if_fail (password_out != null);
256             return_if_fail (server_certificate_hash != null);
257             return_if_fail (ca_certificate != null);
258             return_if_fail (subject_name_constraint != null);
259             return_if_fail (subject_alt_name_constraint != null);
260
261             result = true;
262         }
263         else
264         {
265             result = false;
266         }
267
268         call.return (&result);
269
270         request.cond.signal ();
271         request.mutex.unlock ();
272     }
273
274     // Called from the main loop thread when an identity has
275     // been selected
276     static void return_identity_cb (IdentityRequest request) {
277         // Notify the RPC thread that the request is complete
278         request.mutex.lock ();
279         request.cond.signal ();
280
281         // Block the main loop until the RPC call has returned
282         // to avoid any races
283         request.cond.wait (request.mutex);
284         request.mutex.unlock ();
285     }
286 }
287
288 #endif