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