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