client library: Use local exception handling; correct API
[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
172             result = true;
173         }
174
175         // The outputs must be set before this function is called. For this
176         // reason they are 'ref' not 'out' parameters - Vala assigns to the
177         // 'out' parameters only at the end of the function, which is too
178         // late.
179         call.return (&result);
180
181         request.cond.signal ();
182         request.mutex.unlock ();
183     }
184
185     [CCode (cname = "moonshot_get_default_identity_rpc")]
186     public static void get_default_identity (Rpc.AsyncCall call,
187                                              ref string nai_out,
188                                              ref string password_out,
189                                              ref string server_certificate_hash,
190                                              ref string ca_certificate,
191                                              ref string subject_name_constraint,
192                                              ref string subject_alt_name_constraint)
193     {
194         bool result;
195
196         var request = new IdentityRequest.default (main_window);
197         request.mutex = new Mutex ();
198         request.cond = new Cond ();
199         request.set_callback (return_identity_cb);
200
201         request.mutex.lock ();
202         Idle.add (request.execute);
203
204         while (request.complete == false)
205             request.cond.wait (request.mutex);
206
207         nai_out = "";
208         password_out = "";
209         server_certificate_hash = "";
210         ca_certificate = "";
211         subject_name_constraint = "";
212         subject_alt_name_constraint = "";
213
214         if (request.id_card != null)
215         {
216             nai_out = request.id_card.nai;
217             password_out = request.id_card.password;
218             server_certificate_hash = "certificate";
219
220             return_if_fail (nai_out != null);
221             return_if_fail (password_out != null);
222
223             result = true;
224         }
225         else
226         {
227             result = false;
228         }
229
230         call.return (&result);
231
232         request.cond.signal ();
233         request.mutex.unlock ();
234     }
235
236     // Called from the main loop thread when an identity has
237     // been selected
238     static void return_identity_cb (IdentityRequest request) {
239         // Notify the RPC thread that the request is complete
240         request.mutex.lock ();
241         request.cond.signal ();
242
243         // Block the main loop until the RPC call has returned
244         // to avoid any races
245         request.cond.wait (request.mutex);
246         request.mutex.unlock ();
247     }
248 }
249
250 #endif