Merge branch 'master' of origin
authorSam Thursfield <samthursfield@codethink.co.uk>
Wed, 29 Jun 2011 17:06:30 +0000 (18:06 +0100)
committerSam Thursfield <samthursfield@codethink.co.uk>
Wed, 29 Jun 2011 17:06:30 +0000 (18:06 +0100)
Conflicts:
Makefile.am
src/moonshot-dbus-server.vala
src/moonshot-msrpc-server.vala

1  2 
src/moonshot-server.vala

index 05d41d3,0000000..8770b63
mode 100644,000000..100644
--- /dev/null
@@@ -1,180 -1,0 +1,238 @@@
 +#if IPC_DBUS
 +
 +[DBus (name = "org.janet.Moonshot")]
 +public class MoonshotServer : Object {
 +
 +    private MainWindow main_window;
 +
 +    public MoonshotServer (Gtk.Window window)
 +    {
 +        this.main_window = (MainWindow) window;
 +    }
 +
 +    /**
 +     * This is the function used by the GSS mechanism to get the NAI,
 +     * password and certificate of the ID card for the specificated service.
 +     *
 +     * The function will block until the user choose the ID card.
 +     *
 +     * @param nai NAI of the ID Card (optional)
 +     * @param password Password of the ID Card (optional)
 +     * @param service Service application request an ID Card for
 +     * @param nai_out NAI stored in the ID Card
 +     * @param password_out Password stored in the ID Card
 +     * @param certificate Certificate stored in th ID Card
 +     *
 +     * @return true if the user choose a correct ID card for that service,
 +     *         false otherwise.
 +     */
 +    public async bool get_identity (string nai,
 +                                    string password,
 +                                    string service,
 +                                    out string nai_out,
 +                                    out string password_out,
 +                                    out string certificate_out)
 +    {
 +        bool has_service = false;
 +
 +        var request = new IdentityRequest (main_window,
 +                                           nai,
 +                                           password,
 +                                           service);
 +        request.set_callback ((IdentityRequest) => get_identity.callback());
 +        request.execute ();
 +        yield;
 +
 +        nai_out = "";
 +        password_out = "";
 +        certificate_out = "";
 +
 +        var id_card = request.id_card;
 +
 +        if (id_card != null) {
 +            foreach (string id_card_service in id_card.services)
 +            {
 +                if (id_card_service == service)
 +                    has_service = true;
 +            }
 +
 +            if (has_service)
 +            {
 +                nai_out = id_card.nai;
 +                password_out = id_card.password;
 +                certificate_out = "certificate";
 +
 +                return true;
 +            }
 +        }
 +
 +        return false;
 +    }
 +}
 +
 +#elif IPC_MSRPC
 +
 +using Rpc;
 +using MoonshotRpcInterface;
 +
 +/* This class must be a singleton, because we use a global RPC
 + * binding handle. I cannot picture a situation where more than
 + * one instance of the same interface would be needed so this
 + * shouldn't be a problem.
 + *
 + * Shutdown is automatically done by the RPC runtime when the
 + * process ends
 + */
 +public class MoonshotServer : Object {
 +    private static MainWindow main_window;
 +
 +    private static MoonshotServer instance = null;
 +
 +    public static void start (Gtk.Window window)
 +    {
 +        main_window = (MainWindow) window;
 +        Rpc.server_start (MoonshotRpcInterface.spec, "/org/janet/Moonshot", Rpc.Flags.PER_USER);
 +    }
 +
 +    public static MoonshotServer get_instance ()
 +    {
 +        if (instance == null)
 +            instance = new MoonshotServer ();
 +        return instance;
 +    }
 +
 +    [CCode (cname = "moonshot_get_identity")]
 +    public static void moonshot_get_identity (Rpc.AsyncCall call,
 +                                              string nai,
 +                                              string password,
 +                                              string service,
 +                                              ref string nai_out,
 +                                              ref string password_out,
 +                                              ref string certificate_out)
 +    {
 +        bool result = false;
 +
 +        var request = new IdentityRequest (main_window,
 +                                           nai,
 +                                           password,
 +                                           service);
 +
 +        // Pass execution to the main loop and block the RPC thread
 +        request.mutex = new Mutex ();
 +        request.cond = new Cond ();
 +        request.set_callback (return_identity_cb);
 +
 +        request.mutex.lock ();
 +        Idle.add (request.execute);
 +
 +        while (request.complete == false)
 +            request.cond.wait (request.mutex);
 +
 +        nai_out = "";
 +        password_out = "";
 +        certificate_out = "";
 +
 +        var id_card = request.id_card;
 +        bool has_service = false;
 +
 +        if (id_card == null) {
 +            foreach (string id_card_service in id_card.services)
 +            {
 +                if (id_card_service == service)
 +                    has_service = true;
 +            }
 +
 +            if (has_service)
 +            {
 +                // The strings are freed by the RPC runtime
++                nai_out = id_card.nai;
++                password_out = id_card.password;
++                certificate_out = "certificate";
++
++                result = true;
++            }
++        }
++
++        // The outputs must be set before this function is called. For this
++        // reason they are 'ref' not 'out' parameters - Vala assigns to the
++        // 'out' parameters only at the end of the function, which is too
++        // late.
++        call.return (&result);
++
++        request.cond.signal ();
++        request.mutex.unlock ();
++    }
++
++    [CCode (cname = "moonshot_get_default_identity")]
++    public static void get_default_identity (Rpc.AsyncCall call,
++                                             ref string nai_out,
++                                             ref string password_out)
++    {
++        bool result = false;
++
++        var request = new IdentityRequest.default (main_window);
++
++        // This is really a lot of work to get a default identity.
++        // However, it's really best to do so in the main loop to avoid
++        // races (the alternative is add a mutex to the ID card data,
++        // but this is the only place it would be used).
++        request.mutex = new Mutex ();
++        request.cond = new Cond ();
++        request.set_callback (return_identity_cb);
++
++        request.mutex.lock ();
++        Idle.add (request.execute);
++
++        while (request.complete == false)
++            request.cond.wait (request.mutex);
++
++        nai_out = "";
++        password_out = "";
++        certificate_out = "";
++
++        var id_card = request.id_card;
++        bool has_service = false;
++
++        if (id_card == null) {
++            foreach (string id_card_service in id_card.services)
++            {
++                if (id_card_service == service)
++                    has_service = true;
++            }
++
++            if (has_service)
++            {
++                // The strings are freed by the RPC runtime
 +                nai_out = id_card.nai;
 +                password_out = id_card.password;
 +                certificate_out = "certificate";
 +
 +                result = true;
 +            }
 +        }
 +
 +        // The outputs must be set before this function is called. For this
 +        // reason they are 'ref' not 'out' parameters - Vala assigns to the
 +        // 'out' parameters only at the end of the function, which is too
 +        // late.
 +        call.return (&result);
 +
 +        request.cond.signal ();
 +        request.mutex.unlock ();
 +    }
 +
 +    // Called from the main loop thread when an identity has
 +    // been selected
 +    static void return_identity_cb (IdentityRequest request) {
 +        // Notify the RPC thread that the request is complete
 +        request.mutex.lock ();
 +        request.cond.signal ();
 +
 +        // Block the main loop until the RPC call has returned
 +        // to avoid any races
 +        request.cond.wait (request.mutex);
 +        request.mutex.unlock ();
 +    }
 +}
 +
 +#endif