$(moonshot_LIBS)
if OS_WIN32
-AM_CFLAGS += -mwindows
+src_moonshot_CFLAGS = -mwindows
AM_VALAFLAGS += --define=OS_WIN32
endif
src_moonshot_SOURCES += \
src/moonshot-msrpc-server.vala \
src/moonshot-msrpc_s.c \
- src/moonshot-msrpc-vala.c \
src/moonshot-msrpc.vapi
bin_PROGRAMS += src/msrpc-client
src_msrpc_client_SOURCES = \
src/msrpc-client.vala \
src/moonshot-msrpc_c.c \
- src/moonshot-msrpc-vala.c \
src/moonshot-msrpc.vapi
src_msrpc_client_LDADD = \
using Rpc;
using MoonshotRpcInterface;
+/* Apologies in advance */
+[CCode (cname = "g_strdup")]
+public extern char *strdup (string str);
+
/* This class is the closure when we pass execution from the RPC thread
* to the GLib main loop thread; we need to be executing inside the main
* loop before we can access any state or make any Gtk+ calls.
/* Fixme: can you make *this* an async callback? */
public class IdentityRequest : Object {
private MainWindow main_window;
- private Identity **result;
private unowned Mutex mutex;
private unowned Cond cond;
+ internal IdCard? id_card = null;
+
public IdentityRequest (Gtk.Window window,
- Identity **_result,
Mutex _mutex,
Cond _cond)
{
main_window = (MainWindow)window;
- result = _result;
mutex = _mutex;
cond = _cond;
}
public bool id_card_selected_cb ()
{
- var id_card = this.main_window.selected_id_card_widget.id_card;
+ this.id_card = this.main_window.selected_id_card_widget.id_card;
mutex.lock ();
- *result = new Identity();
-
- (*result)->identity = "identity";
- (*result)->password = id_card.password;
- (*result)->service = "certificate";
-
cond.signal ();
- mutex.unlock ();
- // 'result' is freed by the RPC runtime
+ // Block the mainloop until the ID card details have been read and
+ // sent, to prevent races
+ cond.wait (mutex);
+ mutex.unlock ();
return false;
}
* process ends
*/
public class MoonshotServer : Object {
- private static int counter;
private static MainWindow main_window;
private static MoonshotServer instance = null;
return instance;
}
- /* Note that these RPC callbacks execute outside the GLib main loop,
- * in threads owned by the RPC runtime
- */
-
- [CCode (cname = "moonshot_ping")]
- public static int ping (string msg)
- {
- stdout.printf ("%s\n", msg);
- return counter ++;
- }
-
[CCode (cname = "moonshot_get_identity")]
public static void moonshot_get_identity (Rpc.AsyncCall call,
- string in_identity,
- string in_password,
- string in_service,
- Identity **result)
+ string nai,
+ string password,
+ string service,
+ char **nai_out,
+ char **password_out,
+ char **certificate_out)
{
Mutex mutex = new Mutex ();
Cond cond = new Cond ();
+ bool result;
mutex.lock ();
- *result = null;
- IdentityRequest request = new IdentityRequest (main_window, result, mutex, cond);
+ IdentityRequest request = new IdentityRequest (main_window, mutex, cond);
// Pass execution to the main loop thread and wait for
// the 'send' action to be signalled.
Idle.add (request.main_loop_cb);
- while (*result == null)
+ while (request.id_card == null)
cond.wait (mutex);
- mutex.unlock ();
- call.return (null);
+ // Send back the results. Memory is freed by the RPC runtime.
+ if (request.id_card.nai == nai || request.id_card.password == password)
+ {
+ *nai_out = strdup (request.id_card.nai);
+ *password_out = strdup (request.id_card.password);
+ *certificate_out = strdup ("certificate");
+ result = true;
+ }
+ else
+ {
+ *nai_out = null;
+ *password_out = null;
+ *certificate_out = null;
+ result = false;
+ }
+
+ call.return (&result);
+
+ cond.signal ();
+ mutex.unlock ();
}
}
+++ /dev/null
-/* Allocation functions required to bind the MSRPC interface to
- * Vala: these functions are required for all structs/classes that
- * are accessed from inside Vala.
- */
-
-#include "moonshot-msrpc.h"
-
-MoonshotRpcInterfaceIdentity *moonshot_rpc_interface_identity_new () {
- MoonshotRpcInterfaceIdentity *data = MIDL_user_allocate (sizeof (MoonshotRpcInterfaceIdentity));
- memset (data, 0, sizeof(MoonshotRpcInterfaceIdentity));
- return data;
-}
-
-void moonshot_rpc_interface_identity_free (MoonshotRpcInterfaceIdentity *data) {
- MIDL_user_free (data);
-}
+++ /dev/null
-/* Helper .h file for inclusion in Vala-generated C code */
-
-#include "moonshot-msrpc.h"
-
-MoonshotRpcInterfaceIdentity *moonshot_rpc_interface_identity_new ();
-void moonshot_rpc_interface_identity_free (MoonshotRpcInterfaceIdentity *data);
]
interface moonshot
{
- int moonshot_ping ([in, string] const char *message);
-
- /* Returning arrays in MSRPC is difficult, because it's hard to
- * get it to understand the size of the array and still have the
- * C code bindable in Vala. A struct is more practical.
- * Output parameters are also much more practical than function
- * return values.
- */
- typedef struct {
- [ref, string] char *identity;
- [ref, string] char *password;
- [ref, string] char *service;
- } MoonshotRpcInterfaceIdentity;
-
- void moonshot_get_identity ([in, string] const char *identity,
- [in, string] const char *password,
- [in, string] const char *service,
- [out] MoonshotRpcInterfaceIdentity **result);
+ int moonshot_get_identity ([in, string] const char *nai,
+ [in, string] const char *password,
+ [in, string] const char *certificate,
+ [out, string] char **nai_out,
+ [out, string] char **password_out,
+ [out, string] char **certificate_out);
}
using Rpc;
-[CCode (cheader_filename = "moonshot-msrpc-vala.h")]
+[CCode (cheader_filename = "moonshot-msrpc.h")]
namespace MoonshotRpcInterface {
[CCode (cname = "moonshot_v1_0_s_ifspec")]
public const InterfaceHandle spec;
[CCode (cname = "moonshot_binding_handle")]
public BindingHandle binding_handle;
- [CCode (cname = "MoonshotRpcInterfaceIdentity")]
- [Compact]
- public class Identity {
- public Identity() {}
- public string identity;
- public string password;
- public string service;
- }
-
- [CCode (cname = "moonshot_ping")]
- public extern int ping (string message);
-
[CCode (cname = "moonshot_get_identity")]
public extern void get_identity (Rpc.AsyncCall call,
- string in_identity,
- string in_password,
- string in_service,
- MoonshotRpcInterface.Identity **identity);
+ string nai,
+ string password,
+ string service,
+ char **nai_out,
+ char **password_out,
+ char **certificate_out);
}
void main () {
Rpc.client_bind (ref MoonshotRpcInterface.binding_handle, "/org/janet/Moonshot");
- int pong = ping ("Hello from Vala");
- stdout.printf ("%d\n", pong);
+ char *nai_out = null;
+ char *password_out = null;
+ char *certificate_out = null;
+ bool result = false;
- Identity *id = null;
Rpc.AsyncCall call = Rpc.AsyncCall();
- get_identity (call, "identity", "username", "pass", &id);
+ get_identity (call, "username@issuer", "pass", "service", &nai_out, &password_out, &certificate_out);
+ result = call.complete_bool ();
- call.complete ();
-
- if (id == null)
- /* FIXME: this is happening when moonshot crashes instead
- * of returning a result - surely RpcAsyncCompleteCall should
- * *tell* us that the call failed !
- */
- error ("Call failed but error was not raised\n");
+ if (result == false)
+ error ("The nai, password or service does not match the selected identity\n");
else
- stdout.printf ("%s %s %s\n", id->identity, id->password, id->service);
+ stdout.printf ("%s %s %s\n", (string)nai_out, (string)password_out, (string)certificate_out);
- delete id;
+ delete nai_out;
+ delete password_out;
+ delete certificate_out;
Rpc.client_unbind (ref MoonshotRpcInterface.binding_handle);
}