src/daemon/dbus/Makefile
src/daemon/dbus/services/com.google.code.AccountsSSO.gSingleSignOn.service
src/daemon/plugins/Makefile
+src/daemon/plugins/plugind/Makefile
src/extensions/Makefile
src/extensions/test/Makefile
src/extensions/tizen/Makefile
"/IdentityTimeout"
#define GSIGNOND_CONFIG_DBUS_AUTH_SESSION_TIMEOUT GSIGNOND_CONFIG_DBUS_TIMEOUTS \
"/AuthSessionTimeout"
-
+#define GSIGNOND_CONFIG_DBUS_PLUGIN_TIMEOUT GSIGNOND_CONFIG_DBUS_TIMEOUTS \
+ "/PluginTimeout"
#endif /* __GSIGNOND_CONFIG_DBUS_H_ */
"/ExtensionsDir"
#define GSIGNOND_CONFIG_GENERAL_PLUGINS_DIR GSIGNOND_CONFIG_GENERAL \
"/PluginsDir"
+#define GSIGNOND_CONFIG_GENERAL_BIN_DIR GSIGNOND_CONFIG_GENERAL \
+ "/BinDir"
#define GSIGNOND_CONFIG_GENERAL_EXTENSION GSIGNOND_CONFIG_GENERAL \
"/Extension"
#define GSIGNOND_CONFIG_GENERAL_SECURE_DIR GSIGNOND_CONFIG_GENERAL \
const gchar *str2);
GString*
-gsignond_prepend_domain_to_error_msg (const GError *err);
+gsignond_prepend_domain_to_error_msg (
+ const GError *err);
+
+GError *
+gsignond_error_new_from_variant (
+ GVariant *var);
+
+GVariant *
+gsignond_error_to_variant (
+ GError *error);
#define gsignond_get_gerror_for_id(err, message, args...) \
g_error_new (gsignond_error_quark(), err, message, ##args);
#include <glib.h>
-#define INFO(frmt, args...) g_message("%s:%d " frmt , __FILE__, __LINE__, ##args)
-#define ERR(frmt, args...) g_error("%s:%d " frmt , __FILE__, __LINE__, ##args)
-#define WARN(frmt, args...) g_warning("%s:%d " frmt , __FILE__, __LINE__, ##args)
-#define DBG(frmt, args...) g_debug("%s:%d " frmt , __FILE__, __LINE__, ##args)
+#define INFO(frmt, args...) g_message("%s:%d %s " frmt , __FILE__, __LINE__, \
+ __PRETTY_FUNCTION__, ##args)
+#define ERR(frmt, args...) g_error("%s:%d %s " frmt , __FILE__, __LINE__, \
+ __PRETTY_FUNCTION__, ##args)
+#define WARN(frmt, args...) g_warning("%s:%d %s " frmt , __FILE__, __LINE__, \
+ __PRETTY_FUNCTION__, ##args)
+#define DBG(frmt, args...) g_debug("%s:%d %s " frmt , __FILE__, __LINE__, \
+ __PRETTY_FUNCTION__, ##args)
#endif /* __GSIGNOND_LOG_H_ */
--- /dev/null
+/* vi: set et sw=4 ts=4 cino=t0,(0: */
+/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of gsignond
+ *
+ * Copyright (C) 2013 Intel Corporation.
+ *
+ * Contact: Imran Zaman <imran.zaman@linux.intel.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#ifndef __GSIGNOND_PIPE_STREAM_H__
+#define __GSIGNOND_PIPE_STREAM_H__
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+/*
+ * Type macros.
+ */
+#define GSIGNOND_TYPE_PIPE_STREAM (gsignond_pipe_stream_get_type ())
+#define GSIGNOND_PIPE_STREAM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+ GSIGNOND_TYPE_PIPE_STREAM, \
+ GSignondPipeStream))
+#define GSIGNOND_IS_PIPE_STREAM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+ GSIGNOND_TYPE_PIPE_STREAM))
+#define GSIGNOND_PIPE_STREAM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), \
+ GSIGNOND_TYPE_PIPE_STREAM, \
+ GSignondPipeStreamClass))
+#define GSIGNOND_IS_PIPE_STREAM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),\
+ GSIGNOND_TYPE_PIPE_STREAM))
+#define GSIGNOND_PIPE_STREAM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+ GSIGNOND_TYPE_PIPE_STREAM, \
+ GSignondPipeStreamClass))
+
+typedef struct _GSignondPipeStreamPrivate GSignondPipeStreamPrivate;
+
+typedef struct {
+ GIOStream parent_instance;
+
+ /*< private >*/
+ GSignondPipeStreamPrivate *priv;
+} GSignondPipeStream;
+
+typedef struct {
+ GIOStreamClass parent_class;
+
+} GSignondPipeStreamClass;
+
+/* used by GSIGNOND_TYPE_PIPE_STREAM */
+GType
+gsignond_pipe_stream_get_type (void);
+
+GSignondPipeStream *
+gsignond_pipe_stream_new (
+ gint in_fd,
+ gint out_fd);
+
+G_END_DECLS
+
+#endif /* __GSIGNOND_PIPE_STREAM_H__ */
GTypeInterface parent;
void (*cancel) (GSignondPlugin *self);
- void (*abort) (GSignondPlugin *self);
void (*request_initial) (GSignondPlugin *self,
GSignondSessionData *session_data,
const gchar *mechanism);
void
gsignond_plugin_cancel (GSignondPlugin *self);
void
-gsignond_plugin_abort (GSignondPlugin *self);
-void
gsignond_plugin_request_initial (GSignondPlugin *self,
GSignondSessionData *session_data,
const gchar *mechanism);
G_BEGIN_DECLS
GSignondPlugin*
-gsignond_load_plugin(GSignondConfig* config, gchar* plugin_type);
+gsignond_load_plugin(
+ GSignondConfig* config,
+ gchar* plugin_type);
+
+GSignondPlugin*
+gsignond_load_plugin_with_filename(
+ gchar *plugin_type,
+ gchar *plugin_filename);
G_END_DECLS
-#endif /* _GSIGNOND_PLUGIN_LOADER_H_ */
\ No newline at end of file
+#endif /* _GSIGNOND_PLUGIN_LOADER_H_ */
+
$(GSIGNOND_CFLAGS) \
-DGSIGNOND_PLUGINS_DIR='"$(pluginsdir)"' \
-DGSIGNOND_EXTENSIONS_DIR='"$(extensionsdir)"' \
+ -DGSIGNOND_BIN_DIR='"$(bindir)"' \
$(NULL)
libgsignond_common_la_DEPENDENCIES = \
gsignond-signonui-data.c \
gsignond-plugin-loader.c \
gsignond-utils.c \
+ gsignond-pipe-stream.c \
$(BUILT_SOURCES) \
$(NULL)
def_config = g_build_filename (*sysconfdirs,
"gsignond/gsignond.conf",
NULL);
- DBG ("try to load config from %s", def_config);
if (g_access (def_config, R_OK) == 0) {
- DBG ("use config from %s", def_config);
self->priv->config_file_path = def_config;
break;
}
GSIGNOND_CONFIG_GENERAL_EXTENSIONS_DIR,
e_val);
+ e_val = g_getenv ("SSO_BIN_DIR");
+ if (e_val)
+ gsignond_config_set_string (self,
+ GSIGNOND_CONFIG_GENERAL_BIN_DIR,
+ e_val);
+
e_val = g_getenv ("SSO_EXTENSION");
if (e_val)
gsignond_config_set_string (self,
gsignond_config_set_string (self,
GSIGNOND_CONFIG_GENERAL_EXTENSIONS_DIR,
(GSIGNOND_EXTENSIONS_DIR));
+ gsignond_config_set_string (self,
+ (GSIGNOND_CONFIG_GENERAL_BIN_DIR),
+ (GSIGNOND_BIN_DIR));
gchar *default_data_path =
g_build_filename (g_get_user_data_dir (), "gsignond", NULL);
*/
#include <gsignond/gsignond-dictionary.h>
+#include <gsignond/gsignond-log.h>
/**
* gsignond_dictionary_new_from_variant:
g_return_val_if_fail (value != NULL, FALSE);
g_variant_ref_sink(value);
-
g_hash_table_replace (
dict,
g_strdup(key),
return msg;
}
+/**
+ * gsignond_error_new_from_variant:
+ * @var: instance of #GVariant
+ *
+ * Converts the GVariant to GError.
+ *
+ * Returns: (transfer full) #GError object if successful, NULL otherwise.
+ */
+GError *
+gsignond_error_new_from_variant (
+ GVariant *var)
+{
+ GError *error = NULL;
+ gchar *message;
+ GQuark domain;
+ gint code;
+
+ if (!var) {
+ return NULL;
+ }
+
+ g_variant_get (var, "(uis)", &domain, &code, &message);
+ error = g_error_new_literal (domain, code, message);
+ g_free (message);
+ return error;
+}
+
+/**
+ * gsignond_error_to_variant:
+ * @error: instance of #GError
+ *
+ * Converts the GError to GVariant.
+ *
+ * Returns: (transfer full) #GVariant object if successful, NULL otherwise.
+ */
+GVariant *
+gsignond_error_to_variant (
+ GError *error)
+{
+ if (!error) {
+ return NULL;
+ }
+
+ return g_variant_new ("(uis)", error->domain, error->code, error->message);
+}
+
--- /dev/null
+/* vi: set et sw=4 ts=4 cino=t0,(0: */
+/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of gsignond
+ *
+ * Copyright (C) 2013 Intel Corporation.
+ *
+ * Contact: Imran Zaman <imran.zaman@linux.intel.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+#include <gio/gunixinputstream.h>
+#include <gio/gunixoutputstream.h>
+
+#include "gsignond/gsignond-pipe-stream.h"
+
+#define GSIGNOND_PIPE_STREAM_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((obj),\
+ GSIGNOND_TYPE_PIPE_STREAM, \
+ GSignondPipeStreamPrivate))
+
+struct _GSignondPipeStreamPrivate
+{
+ GInputStream *input_stream;
+ GOutputStream *output_stream;
+};
+
+G_DEFINE_TYPE (GSignondPipeStream, gsignond_pipe_stream, G_TYPE_IO_STREAM);
+
+static GInputStream *
+_gsignond_pipe_stream_get_input_stream (GIOStream *io_stream)
+{
+ return GSIGNOND_PIPE_STREAM (io_stream)->priv->input_stream;
+}
+
+static GOutputStream *
+_gsignond_pipe_stream_get_output_stream (GIOStream *io_stream)
+{
+ return GSIGNOND_PIPE_STREAM (io_stream)->priv->output_stream;
+}
+
+static void
+_gsignond_pipe_stream_dispose (GObject *gobject)
+{
+ g_return_if_fail (GSIGNOND_IS_PIPE_STREAM (gobject));
+
+ GSignondPipeStream *stream = GSIGNOND_PIPE_STREAM (gobject);
+
+ if (stream->priv->input_stream) {
+ g_object_unref (stream->priv->input_stream);
+ stream->priv->input_stream = NULL;
+ }
+
+ if (stream->priv->output_stream) {
+ g_object_unref (stream->priv->output_stream);
+ stream->priv->output_stream = NULL;
+ }
+
+ /* Chain up to the parent class */
+ G_OBJECT_CLASS (gsignond_pipe_stream_parent_class)->dispose (gobject);
+}
+
+static void
+_gsignond_pipe_stream_finalize (GObject *gobject)
+{
+ G_OBJECT_CLASS (gsignond_pipe_stream_parent_class)->finalize (gobject);
+}
+
+static void
+gsignond_pipe_stream_class_init (GSignondPipeStreamClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GIOStreamClass *stream_class = G_IO_STREAM_CLASS (klass);
+
+ gobject_class->finalize = _gsignond_pipe_stream_finalize;
+ gobject_class->dispose = _gsignond_pipe_stream_dispose;
+
+ /* virtual methods */
+ stream_class->get_input_stream = _gsignond_pipe_stream_get_input_stream;
+ stream_class->get_output_stream = _gsignond_pipe_stream_get_output_stream;
+
+ g_type_class_add_private (klass, sizeof (GSignondPipeStreamPrivate));
+}
+
+static void
+gsignond_pipe_stream_init (GSignondPipeStream *self)
+{
+ self->priv = GSIGNOND_PIPE_STREAM_GET_PRIVATE (self);
+ self->priv->input_stream = NULL;
+ self->priv->output_stream = NULL;
+}
+
+GSignondPipeStream *
+gsignond_pipe_stream_new (
+ gint in_fd,
+ gint out_fd)
+{
+ GSignondPipeStream *stream = GSIGNOND_PIPE_STREAM (g_object_new (
+ GSIGNOND_TYPE_PIPE_STREAM, NULL));
+ if (stream) {
+ stream->priv->input_stream = (GInputStream *)
+ g_unix_input_stream_new (in_fd, TRUE);
+ stream->priv->output_stream = (GOutputStream *)
+ g_unix_output_stream_new (out_fd, TRUE);
+ }
+ return stream;
+}
+
+
G_SIGNAL_RUN_FIRST, 0, NULL, NULL, NULL, G_TYPE_NONE,
2, GSIGNOND_TYPE_PLUGIN_STATE, G_TYPE_STRING);
- g_object_interface_install_property (g_class,
- g_param_spec_string ("type", "Type", "Plugin type", "none",
- G_PARAM_READABLE|G_PARAM_STATIC_STRINGS));
-
- g_object_interface_install_property (g_class,
- g_param_spec_boxed ("mechanisms", "Mechanisms",
- "List of plugin mechanisms",
- G_TYPE_STRV, G_PARAM_READABLE|
- G_PARAM_STATIC_STRINGS));
+ g_object_interface_install_property (g_class, g_param_spec_string ("type",
+ "Type", "Plugin type", "none",
+ G_PARAM_READABLE|G_PARAM_STATIC_STRINGS));
+
+ g_object_interface_install_property (g_class, g_param_spec_boxed (
+ "mechanisms", "Mechanisms", "List of plugin mechanisms",
+ G_TYPE_STRV, G_PARAM_READABLE|G_PARAM_STATIC_STRINGS));
}
GSIGNOND_PLUGIN_GET_INTERFACE (self)->cancel (self);
}
-void gsignond_plugin_abort (GSignondPlugin *self)
-{
- g_return_if_fail (GSIGNOND_IS_PLUGIN (self));
-
- GSIGNOND_PLUGIN_GET_INTERFACE (self)->abort (self);
-}
-
void gsignond_plugin_request_initial (GSignondPlugin *self,
GSignondSessionData *session_data,
const gchar *mechanism)
{
g_return_if_fail (GSIGNOND_IS_PLUGIN (self));
- GSIGNOND_PLUGIN_GET_INTERFACE (self)->request_initial (self, session_data, mechanism);
+ GSIGNOND_PLUGIN_GET_INTERFACE (self)->request_initial (self, session_data,
+ mechanism);
}
void gsignond_plugin_request (GSignondPlugin *self,
g_signal_emit (self, signals[REFRESHED], 0, ui_data);
}
-void gsignond_plugin_status_changed (GSignondPlugin *self, GSignondPluginState state,
- const gchar *message)
+void gsignond_plugin_status_changed (GSignondPlugin *self,
+ GSignondPluginState state, const gchar *message)
{
g_signal_emit (self, signals[STATUS_CHANGED], 0, state, message);
}
#include <gmodule.h>
GSignondPlugin*
-gsignond_load_plugin(GSignondConfig* config, gchar* plugin_type)
+gsignond_load_plugin(
+ GSignondConfig* config,
+ gchar* plugin_type)
{
gchar* plugin_filename = g_module_build_path (
- gsignond_config_get_string (config,
- GSIGNOND_CONFIG_GENERAL_PLUGINS_DIR),
- plugin_type);
+ gsignond_config_get_string (config,
+ GSIGNOND_CONFIG_GENERAL_PLUGINS_DIR), plugin_type);
+ GSignondPlugin *plugin = gsignond_load_plugin_with_filename (plugin_type,
+ plugin_filename);
+ g_free(plugin_filename);
+ return plugin;
+}
+
+GSignondPlugin*
+gsignond_load_plugin_with_filename(
+ gchar *plugin_type,
+ gchar *plugin_filename)
+{
DBG("Loading plugin %s", plugin_filename);
GModule* plugin_module = g_module_open (plugin_filename,
- G_MODULE_BIND_LOCAL);
- g_free(plugin_filename);
+ G_MODULE_BIND_LOCAL);
if (plugin_module == NULL) {
DBG("Plugin couldn't be opened: %s", g_module_error());
return NULL;
}
-
+
gchar* plugin_get_type = g_strdup_printf("gsignond_%s_plugin_get_type",
plugin_type);
gpointer p;
gsignond-dbus-identity-gen.h \
gsignond-dbus-signonui-gen.c \
gsignond-dbus-signonui-gen.h \
+ gsignond-dbus-remote-plugin-gen.c \
+ gsignond-dbus-remote-plugin-gen.h \
$(NULL)
DBUS_BUILT_DOCS = \
gsignond-dbus-auth-session-doc-gen-com.google.code.AccountsSSO.gSingleSignOn.AuthSession.xml \
gsignond-dbus-identity-doc-gen-com.google.code.AccountsSSO.gSingleSignOn.Identity.xml \
gsignond-dbus-signonui-doc-gen-org.tizen.SSO.singlesignonui.xml \
+ gsignond-dbus-remote-plugin-doc-gen-com.google.code.AccountsSSO.gSingleSignOn.RemotePlugin.xml \
$(NULL)
DBUS_INTERFACE_PREFIX="com.google.code.AccountsSSO.gSingleSignOn."
--generate-docbook gsignond-dbus-signonui-doc-gen\
$<
+gsignond-dbus-remote-plugin-gen.c gsignond-dbus-remote-plugin-gen.h : $(INTERFACES_DIR)/com.google.code.AccountsSSO.gSingleSignOn.RemotePlugin.xml
+ gdbus-codegen \
+ --interface-prefix $(DBUS_INTERFACE_PREFIX) \
+ --c-namespace GSignondDbus \
+ --generate-c-code gsignond-dbus-remote-plugin-gen \
+ --generate-docbook gsignond-dbus-remote-plugin-doc-gen \
+ $<
+
lib_LTLIBRARIES = libgsignond-dbus-glue.la
libgsignond_dbus_glue_la_CPPFLAGS = \
$(INTERFACES_DIR)/com.google.code.AccountsSSO.gSingleSignOn.AuthService.xml \
$(INTERFACES_DIR)/com.google.code.AccountsSSO.gSingleSignOn.AuthSession.xml \
$(INTERFACES_DIR)/com.google.code.AccountsSSO.gSingleSignOn.Identity.xml \
- $(INTERFACES_DIR)/org.tizen.SSO.singlesignonui.xml
+ $(INTERFACES_DIR)/org.tizen.SSO.singlesignonui.xml \
+ $(INTERFACES_DIR)/com.google.code.AccountsSSO.gSingleSignOn.RemotePlugin.xml
EXTRA_DIST = dbusservice
#define GSIGNOND_DAEMON_INTERFACE GSIGNOND_SERVICE_PREFIX ".AuthService"
#define GSIGNOND_IDENTITY_INTERFACE GSIGNOND_SERVICE_PREFIX ".Identity"
#define GSIGNOND_AUTH_SESSION_INTERFACE GSIGNOND_SERVICE_PREFIX ".AuthSession"
+#define GSIGNOND_PLUGIN_OBJECTPATH GSIGNOND_DAEMON_OBJECTPATH "/Plugin"
#define SIGNONUI_SERVICE "org.tizen.SSO"
#define SIGNONUI_OBJECTPATH "/org/tizen/SSO/SignonUi"
--- /dev/null
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
+<node>
+ <interface name="com.google.code.AccountsSSO.gSingleSignOn.RemotePlugin">
+ <method name="cancel">
+ </method>
+ <method name="requestInitial">
+ <arg name="sessionData" type="a{sv}" direction="in"/>
+ <arg name="mechanism" type="s" direction="in"/>
+ </method>
+ <method name="request">
+ <arg name="sessionData" type="a{sv}" direction="in"/>
+ </method>
+ <method name="userActionFinished">
+ <arg name="uiData" type="a{sv}" direction="in"/>
+ </method>
+ <method name="refresh">
+ <arg name="uiData" type="a{sv}" direction="in"/>
+ </method>
+ <method name="getInfo">
+ <arg name="type" type="s" direction="out"/>
+ <arg name="mechanisms" type="as" direction="out"/>
+ </method>
+
+ <signal name="response">
+ <arg name="sessionData" type="a{sv}" direction="out"/>
+ </signal>
+ <signal name="responseFinal">
+ <arg name="sessionData" type="a{sv}" direction="out"/>
+ </signal>
+ <signal name="store">
+ <arg name="sessionData" type="a{sv}" direction="out"/>
+ </signal>
+ <signal name="error">
+ <arg name="error" type="(uis)" direction="out"/>
+ </signal>
+ <signal name="userActionRequired">
+ <arg name="uiData" type="a{sv}" direction="out"/>
+ </signal>
+ <signal name="refreshed">
+ <arg name="uiData" type="a{sv}" direction="out"/>
+ </signal>
+ <signal name="statusChanged">
+ <arg name="state" type="i" direction="out"/>
+ <arg name="message" type="s" direction="out"/>
+ </signal>
+ </interface>
+</node>
+SUBDIRS = plugind
+
lib_LTLIBRARIES = libgsignond-plugins.la
libgsignond_plugins_la_CPPFLAGS = \
libgsignond_plugins_la_LIBADD = \
$(top_srcdir)/src/common/libgsignond-common.la \
+ $(top_srcdir)/src/daemon/dbus/libgsignond-dbus-glue.la \
$(GSIGNOND_LIBS)
libgsignond_plugins_la_SOURCES = \
gsignond-plugin-proxy.c \
- gsignond-plugin-proxy-factory.c
+ gsignond-plugin-proxy-factory.c \
+ gsignond-plugin-remote.c
CLEANFILES =
#include <stdio.h>
#include <gsignond/gsignond-log.h>
#include <gsignond/gsignond-plugin-loader.h>
+#include "gsignond-plugin-remote.h"
G_DEFINE_TYPE (GSignondPluginProxyFactory, gsignond_plugin_proxy_factory, G_TYPE_OBJECT);
if (g_strcmp0 (plugin_type, plugin_name) == 0) {
*method_iter = plugin_type;
method_iter++;
- DBG ("method %s (%p)", plugin_type, plugin);
g_hash_table_insert(self->mechanisms,
plugin_type, mechanisms);
} else {
gtype, n_properties, properties);
}
- /* update the object state depending on constructor properties */
- GSignondPluginProxyFactory* self = GSIGNOND_PLUGIN_PROXY_FACTORY(obj);
-
- _enumerate_plugins(self);
-
return obj;
}
gsignond_plugin_proxy_factory_get_plugin_types(
GSignondPluginProxyFactory* factory)
{
- return (gpointer)factory->methods;
+ if (factory->methods == NULL) {
+ _enumerate_plugins (factory);
+ }
+ return (const gchar**)factory->methods;
}
const gchar**
{
g_return_val_if_fail(factory->mechanisms, NULL);
- return g_hash_table_lookup(factory->mechanisms, plugin_type);
+ const gchar **mechanisms = NULL;
+ mechanisms = g_hash_table_lookup(factory->mechanisms, plugin_type);
+ if (mechanisms == NULL) {
+ GSignondPlugin* plugin = GSIGNOND_PLUGIN (gsignond_plugin_remote_new (
+ factory->config, plugin_type));
+ if (plugin != NULL) {
+ gchar **mechs = NULL;
+ g_object_get (plugin, "mechanisms", &mechs, NULL);
+ if (mechs != NULL) {
+ g_hash_table_insert(factory->mechanisms, g_strdup(plugin_type),
+ mechs);
+ mechanisms = (const gchar **)mechs;
+ }
+ }
+ }
+ return mechanisms;
}
*/
#include "gsignond-plugin-proxy.h"
-#include <gsignond/gsignond-plugin-loader.h>
-#include <gsignond/gsignond-error.h>
-#include <gsignond/gsignond-log.h>
-#include "../gsignond-auth-session.h"
+#include "gsignond/gsignond-plugin-loader.h"
+#include "gsignond/gsignond-error.h"
+#include "gsignond/gsignond-log.h"
+#include "gsignond/gsignond-config.h"
+#include "daemon/gsignond-auth-session.h"
+#include "gsignond-plugin-remote.h"
#define GSIGNOND_PLUGIN_PROXY_PRIV(obj) \
G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
G_DEFINE_TYPE (GSignondPluginProxy, gsignond_plugin_proxy, G_TYPE_OBJECT);
-static void gsignond_plugin_proxy_response_final_callback(GSignondPlugin* plugin,
- GSignondSessionData* result,
- gpointer user_data);
-static void gsignond_plugin_proxy_response_callback(GSignondPlugin* plugin,
- GSignondSessionData* result,
- gpointer user_data);
-static void gsignond_plugin_proxy_store_callback(GSignondPlugin* plugin,
- GSignondDictionary* token_data,
- gpointer user_data);
-static void gsignond_plugin_proxy_refreshed_callback(GSignondPlugin* plugin,
- GSignondSessionData* result,
- gpointer user_data);
-static void gsignond_plugin_proxy_user_action_required_callback(
- GSignondPlugin* plugin,
- GSignondSignonuiData* ui_request,
- gpointer user_data);
-static void gsignond_plugin_proxy_error_callback(GSignondPlugin* plugin,
- GError* error,
- gpointer user_data);
-static void gsignond_plugin_proxy_status_changed_callback(GSignondPlugin* plugin,
- GSignondPluginState status,
- const gchar* message,
- gpointer user_data);
-
-static GSignondProcessData*
-gsignond_process_data_new (GSignondAuthSession* auth_session,
- GSignondSessionData *session_data,
- const gchar* mechanism,
- gpointer userdata)
+static GSignondProcessData*
+gsignond_process_data_new (
+ GSignondAuthSession* auth_session,
+ GSignondSessionData *session_data,
+ const gchar* mechanism,
+ gpointer userdata)
{
GSignondProcessData* data = g_slice_new0 (GSignondProcessData);
- g_object_ref (auth_session);
- data->auth_session = auth_session;
+ data->auth_session = g_object_ref (auth_session);
data->session_data = gsignond_dictionary_copy (session_data);
data->mechanism = g_strdup (mechanism);
data->userdata = userdata;
return data;
}
-static void gsignond_process_data_free (GSignondProcessData* data)
+static void
+gsignond_process_data_free (
+ GSignondProcessData* data)
{
g_object_unref (data->auth_session);
gsignond_dictionary_unref (data->session_data);
g_slice_free (GSignondProcessData, data);
}
+static void
+gsignond_plugin_proxy_process_queue (
+ GSignondPluginProxy *self)
+{
+ g_assert (GSIGNOND_IS_PLUGIN_PROXY (self));
+
+ GSignondPluginProxyPrivate *priv = self->priv;
+ GSignondProcessData* next_data = g_queue_pop_head (priv->session_queue);
+ if (next_data) {
+ priv->expecting_request = FALSE;
+ priv->active_process_userdata = next_data->userdata;
+ priv->active_session = next_data->auth_session;
+ g_object_ref (priv->active_session);
+ gsignond_auth_session_notify_state_changed (
+ priv->active_session, GSIGNOND_PLUGIN_STATE_STARTED,
+ "The request is being processed.",
+ priv->active_process_userdata);
+ gsignond_plugin_request_initial (priv->plugin,
+ next_data->session_data,
+ next_data->mechanism);
+ gsignond_process_data_free (next_data);
+ }
+}
+
+static void
+gsignond_plugin_proxy_response_final_callback (
+ GSignondPlugin *plugin,
+ GSignondSessionData *result,
+ gpointer user_data)
+{
+ GSignondPluginProxy *self = GSIGNOND_PLUGIN_PROXY (user_data);
+ GSignondPluginProxyPrivate *priv = self->priv;
+
+ DBG ("");
+ if (priv->active_session == NULL) {
+ WARN("Error: plugin %s reported 'response_final', but no active session"
+ " in plugin proxy", priv->plugin_type);
+ return;
+ }
+ gsignond_auth_session_notify_process_result (priv->active_session, result,
+ priv->active_process_userdata);
+ g_object_unref (priv->active_session);
+ priv->active_session = NULL;
+ priv->active_process_userdata = NULL;
+ gsignond_plugin_proxy_process_queue (self);
+}
+
+static void
+gsignond_plugin_proxy_response_callback(
+ GSignondPlugin *plugin,
+ GSignondSessionData *result,
+ gpointer user_data)
+{
+ GSignondPluginProxy *self = GSIGNOND_PLUGIN_PROXY (user_data);
+ GSignondPluginProxyPrivate *priv = self->priv;
+
+ if (priv->active_session == NULL) {
+ WARN("Error: plugin %s reported 'response', but no active session "
+ "in plugin proxy", priv->plugin_type);
+ return;
+ }
+ priv->expecting_request = TRUE;
+ gsignond_auth_session_notify_process_result (priv->active_session,
+ result, priv->active_process_userdata);
+}
+
+static void
+gsignond_plugin_proxy_store_callback (
+ GSignondPlugin *plugin,
+ GSignondSessionData *result,
+ gpointer user_data)
+{
+ GSignondPluginProxy *self = GSIGNOND_PLUGIN_PROXY (user_data);
+ GSignondPluginProxyPrivate *priv = self->priv;
+
+ if (priv->active_session == NULL) {
+ WARN("Error: plugin %s reported 'store', but no active session "
+ "in plugin proxy", priv->plugin_type);
+ return;
+ }
+ gsignond_auth_session_notify_store (priv->active_session, result);
+}
+
+static void
+gsignond_plugin_proxy_refreshed_callback (
+ GSignondPlugin *plugin,
+ GSignondSignonuiData *ui_result,
+ gpointer user_data)
+{
+ GSignondPluginProxy *self = GSIGNOND_PLUGIN_PROXY (user_data);
+ GSignondPluginProxyPrivate *priv = self->priv;
+
+ if (priv->active_session == NULL) {
+ WARN("Error: plugin %s reported 'refreshed', but no active session"
+ " in plugin proxy", priv->plugin_type);
+ return;
+ }
+ gsignond_auth_session_notify_refreshed (priv->active_session, ui_result);
+}
+
+static void
+gsignond_plugin_proxy_user_action_required_callback (
+ GSignondPlugin *plugin,
+ GSignondSignonuiData *ui_request,
+ gpointer user_data)
+{
+ GSignondPluginProxy *self = GSIGNOND_PLUGIN_PROXY (user_data);
+ GSignondPluginProxyPrivate *priv = self->priv;
+
+ if (priv->active_session == NULL) {
+ WARN("Error: plugin %s reported 'user_action_required', but no active"
+ " session in plugin proxy", priv->plugin_type);
+ return;
+ }
+ gsignond_auth_session_notify_user_action_required(
+ priv->active_session, ui_request);
+}
+
+static void
+gsignond_plugin_proxy_error_callback (
+ GSignondPlugin* plugin,
+ GError* error,
+ gpointer user_data)
+{
+ GSignondPluginProxy *self = GSIGNOND_PLUGIN_PROXY (user_data);
+ GSignondPluginProxyPrivate *priv = self->priv;
+
+ if (priv->active_session == NULL) {
+ WARN("Error: plugin %s reported error %s, but no active session "
+ "in plugin proxy", priv->plugin_type, error->message);
+ return;
+ }
+ gsignond_auth_session_notify_process_error (priv->active_session, error,
+ priv->active_process_userdata);
+ g_object_unref (priv->active_session);
+ priv->active_session = NULL;
+ priv->active_process_userdata = NULL;
+ gsignond_plugin_proxy_process_queue (self);
+}
+
+static void
+gsignond_plugin_proxy_status_changed_callback (
+ GSignondPlugin *plugin,
+ GSignondPluginState state,
+ const gchar *message,
+ gpointer user_data)
+{
+ GSignondPluginProxy *self = GSIGNOND_PLUGIN_PROXY (user_data);
+ GSignondPluginProxyPrivate *priv = self->priv;
+
+ if (priv->active_session == NULL) {
+ WARN("Error: plugin %s reported change in state %d with message %s, "
+ "but no active session in plugin proxy", priv->plugin_type,
+ state, message);
+ return;
+ }
+ gsignond_auth_session_notify_state_changed (priv->active_session,
+ (gint) state, message,
+ priv->active_process_userdata);
+}
+
+static void
+gsignond_plugin_proxy_user_action_finished_triggered_cb(
+ GSignondPluginRemote* plugin,
+ gpointer user_data)
+{
+ GSignondPluginProxy *self = GSIGNOND_PLUGIN_PROXY (user_data);
+
+ gsignond_plugin_proxy_process_queue (self);
+}
+
static GObject *
-gsignond_plugin_proxy_constructor (GType gtype,
- guint n_properties,
- GObjectConstructParam *properties)
+gsignond_plugin_proxy_constructor (
+ GType gtype,
+ guint n_properties,
+ GObjectConstructParam *properties)
{
GObject *obj;
/* update the object state depending on constructor properties */
GSignondPluginProxy* self = GSIGNOND_PLUGIN_PROXY (obj);
GSignondPluginProxyPrivate *priv = self->priv;
- priv->plugin = gsignond_load_plugin (priv->config,
- priv->plugin_type);
+ priv->plugin = GSIGNOND_PLUGIN (gsignond_plugin_remote_new (priv->config,
+ priv->plugin_type));
if (priv->plugin == NULL) {
g_free (priv->plugin_type);
priv->plugin_type = NULL;
+
} else {
- gchar *type;
- g_object_get (priv->plugin, "type", &type, NULL);
- if (g_strcmp0 (type, priv->plugin_type) != 0) {
- g_free (priv->plugin_type);
- priv->plugin_type = NULL;
- }
- g_free (type);
+ gchar *type = NULL;
g_signal_connect(priv->plugin, "response", G_CALLBACK(
gsignond_plugin_proxy_response_callback), self);
gsignond_plugin_proxy_refreshed_callback), self);
g_signal_connect(priv->plugin, "status-changed", G_CALLBACK(
gsignond_plugin_proxy_status_changed_callback), self);
+
+ g_signal_connect(GSIGNOND_PLUGIN_REMOTE (priv->plugin),
+ "user-action-finished-triggered", G_CALLBACK(
+ gsignond_plugin_proxy_user_action_finished_triggered_cb),
+ self);
+
+ g_object_get (priv->plugin, "type", &type, NULL);
+ if (g_strcmp0 (type, priv->plugin_type) != 0) {
+ g_free (priv->plugin_type);
+ priv->plugin_type = NULL;
+ }
+ g_free (type);
+
}
return obj;
}
static void
-gsignond_plugin_proxy_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec)
+gsignond_plugin_proxy_set_property (
+ GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
{
GSignondPluginProxy *self = GSIGNOND_PLUGIN_PROXY (object);
GSignondPluginProxyPrivate *priv = self->priv;
}
static void
-gsignond_plugin_proxy_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
+gsignond_plugin_proxy_get_property (
+ GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
{
GSignondPluginProxy *self = GSIGNOND_PLUGIN_PROXY (object);
GSignondPluginProxyPrivate *priv = self->priv;
}
static void
-gsignond_plugin_proxy_dispose (GObject *gobject)
+gsignond_plugin_proxy_dispose (
+ GObject *gobject)
{
GSignondPluginProxy *self = GSIGNOND_PLUGIN_PROXY (gobject);
GSignondPluginProxyPrivate *priv = self->priv;
static void
-gsignond_plugin_proxy_class_init (GSignondPluginProxyClass *klass)
+gsignond_plugin_proxy_class_init (
+ GSignondPluginProxyClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
"List of plugin mechanisms",
G_TYPE_STRV, G_PARAM_READABLE);
-
obj_properties[PROP_CONFIG] = g_param_spec_object ("config",
"config",
"Configuration object",
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS);
-
g_object_class_install_properties (gobject_class,
N_PROPERTIES,
obj_properties);
+
}
static void
-gsignond_plugin_proxy_init (GSignondPluginProxy *self)
+gsignond_plugin_proxy_init (
+ GSignondPluginProxy *self)
{
GSignondPluginProxyPrivate *priv = GSIGNOND_PLUGIN_PROXY_PRIV (self);
self->priv = priv;
}
static const gchar *
-gsignond_plugin_proxy_get_plugin_type (GSignondPluginProxy *self)
+gsignond_plugin_proxy_get_plugin_type (
+ GSignondPluginProxy *self)
{
g_assert (GSIGNOND_IS_PLUGIN_PROXY (self));
}
GSignondPluginProxy*
-gsignond_plugin_proxy_new (GSignondConfig *config, const gchar *plugin_type)
+gsignond_plugin_proxy_new (
+ GSignondConfig *config,
+ const gchar *plugin_type)
{
GSignondPluginProxy* proxy = g_object_new (GSIGNOND_TYPE_PLUGIN_PROXY,
"config", config,
return NULL;
}
-static void
-gsignond_plugin_proxy_process_queue (GSignondPluginProxy *self)
-{
- g_assert (GSIGNOND_IS_PLUGIN_PROXY (self));
-
- GSignondPluginProxyPrivate *priv = self->priv;
- GSignondProcessData* next_data = g_queue_pop_head (priv->session_queue);
- if (next_data) {
- priv->expecting_request = FALSE;
- priv->active_process_userdata = next_data->userdata;
- priv->active_session = next_data->auth_session;
- g_object_ref (priv->active_session);
- gsignond_auth_session_notify_state_changed (
- priv->active_session,
- GSIGNOND_PLUGIN_STATE_STARTED,
- "The request is being processed.",
- priv->active_process_userdata);
- gsignond_plugin_request_initial (priv->plugin,
- next_data->session_data,
- next_data->mechanism);
- gsignond_process_data_free (next_data);
- }
-}
-
-void gsignond_plugin_proxy_process (GSignondPluginProxy *self,
- GSignondAuthSession *session,
- GSignondSessionData *session_data,
- const gchar *mechanism,
- gpointer userdata)
+void
+gsignond_plugin_proxy_process (
+ GSignondPluginProxy *self,
+ GSignondAuthSession *session,
+ GSignondSessionData *session_data,
+ const gchar *mechanism,
+ gpointer userdata)
{
g_assert (GSIGNOND_IS_PLUGIN_PROXY (self));
g_assert (GSIGNOND_IS_AUTH_SESSION (session));
session_data,
mechanism, userdata));
gsignond_auth_session_notify_state_changed (
- session,
- GSIGNOND_PLUGIN_STATE_PROCESS_PENDING,
- "The request has been queued.", userdata);
+ session, GSIGNOND_PLUGIN_STATE_PROCESS_PENDING,
+ "The request has been queued.", userdata);
if (priv->active_session == NULL) {
gsignond_plugin_proxy_process_queue (self);
}
}
static gint
-gsignond_plugin_proxy_compare_process_data (gconstpointer process_data,
- gconstpointer auth_session)
+gsignond_plugin_proxy_compare_process_data (
+ gconstpointer process_data,
+ gconstpointer auth_session)
{
g_return_val_if_fail (process_data && auth_session, 0);
}
static GSignondProcessData*
-gsignond_plugin_proxy_find_by_session_iface (GSignondPluginProxy *self,
- GSignondAuthSession *session)
+gsignond_plugin_proxy_find_by_session_iface (
+ GSignondPluginProxy *self,
+ GSignondAuthSession *session)
{
g_assert (GSIGNOND_IS_PLUGIN_PROXY (self));
}
void
-gsignond_plugin_proxy_cancel (GSignondPluginProxy *self,
- GSignondAuthSession *session)
+gsignond_plugin_proxy_cancel (
+ GSignondPluginProxy *self,
+ GSignondAuthSession *session)
{
g_assert (GSIGNOND_IS_PLUGIN_PROXY (self));
g_assert (GSIGNOND_IS_AUTH_SESSION (session));
/* cancel active session */
if (session == priv->active_session) {
gsignond_plugin_cancel (priv->plugin);
- g_object_unref (priv->active_session);
- priv->active_session = NULL;
- priv->active_process_userdata = NULL;
- gsignond_plugin_proxy_process_queue (self);
} else { /* cancel by de-queue */
GSignondProcessData* data =
gsignond_plugin_proxy_find_by_session_iface (self, session);
}
void
-gsignond_plugin_proxy_user_action_finished (GSignondPluginProxy *self,
- GSignondSignonuiData *ui_data)
+gsignond_plugin_proxy_user_action_finished (
+ GSignondPluginProxy *self,
+ GSignondSignonuiData *ui_data)
{
g_assert (GSIGNOND_IS_PLUGIN_PROXY (self));
if (self->priv->active_session == NULL) {
- ERR("Error: 'user_action_finished' requested for plugin %s but no \
- active session", self->priv->plugin_type);
+ WARN("Error: 'user_action_finished' requested for plugin %s but no "
+ "active session", self->priv->plugin_type);
return;
}
gsignond_plugin_user_action_finished (self->priv->plugin, ui_data);
}
void
-gsignond_plugin_proxy_refresh (GSignondPluginProxy *self,
- GSignondSignonuiData *ui_data)
+gsignond_plugin_proxy_refresh (
+ GSignondPluginProxy *self,
+ GSignondSignonuiData *ui_data)
{
g_assert (GSIGNOND_IS_PLUGIN_PROXY (self));
if (self->priv->active_session == NULL) {
- ERR("Error: 'refresh' requested for plugin %s but no active session",
- self->priv->plugin_type);
+ WARN("Error: 'refresh' requested for plugin %s but no active session",
+ self->priv->plugin_type);
return;
}
gsignond_plugin_refresh (self->priv->plugin, ui_data);
}
-static void
-gsignond_plugin_proxy_response_final_callback (GSignondPlugin *plugin,
- GSignondSessionData *result,
- gpointer user_data)
-{
- GSignondPluginProxy *self = GSIGNOND_PLUGIN_PROXY (user_data);
- GSignondPluginProxyPrivate *priv = self->priv;
-
- if (priv->active_session == NULL) {
- ERR("Error: plugin %s reported 'response_final', but no active session \
- in plugin proxy", priv->plugin_type);
- return;
- }
- // This avoids problems if cancel() is called from AuthSession handler
- GSignondAuthSession* active_session = priv->active_session;
- priv->active_session = NULL;
- gsignond_auth_session_notify_process_result (active_session, result, priv->active_process_userdata);
- g_object_unref (active_session);
- gsignond_plugin_proxy_process_queue (self);
-}
-
-static void
-gsignond_plugin_proxy_response_callback(GSignondPlugin *plugin,
- GSignondSessionData *result,
- gpointer user_data)
-{
- GSignondPluginProxy *self = GSIGNOND_PLUGIN_PROXY (user_data);
- GSignondPluginProxyPrivate *priv = self->priv;
-
- if (priv->active_session == NULL) {
- ERR("Error: plugin %s reported 'response', but no active session \
- in plugin proxy", priv->plugin_type);
- return;
- }
- priv->expecting_request = TRUE;
- gsignond_auth_session_notify_process_result (priv->active_session,
- result, priv->active_process_userdata);
-}
-
-static void
-gsignond_plugin_proxy_store_callback (GSignondPlugin *plugin,
- GSignondDictionary *token_data,
- gpointer user_data)
-{
- GSignondPluginProxy *self = GSIGNOND_PLUGIN_PROXY (user_data);
- GSignondPluginProxyPrivate *priv = self->priv;
-
- if (priv->active_session == NULL) {
- ERR("Error: plugin %s reported 'store', but no active session \
- in plugin proxy", priv->plugin_type);
- return;
- }
- gsignond_auth_session_notify_store (priv->active_session, token_data);
-}
-
-static void
-gsignond_plugin_proxy_refreshed_callback (GSignondPlugin *plugin,
- GSignondSignonuiData *ui_result,
- gpointer user_data)
-{
- GSignondPluginProxy *self = GSIGNOND_PLUGIN_PROXY (user_data);
- GSignondPluginProxyPrivate *priv = self->priv;
-
- if (priv->active_session == NULL) {
- ERR("Error: plugin %s reported 'refreshed', but no active session \
- in plugin proxy", priv->plugin_type);
- return;
- }
- gsignond_auth_session_notify_refreshed (priv->active_session, ui_result);
-}
-
-static void
-gsignond_plugin_proxy_user_action_required_callback (
- GSignondPlugin *plugin,
- GSignondSignonuiData *ui_request,
- gpointer user_data)
-{
- GSignondPluginProxy *self = GSIGNOND_PLUGIN_PROXY (user_data);
- GSignondPluginProxyPrivate *priv = self->priv;
-
- if (priv->active_session == NULL) {
- ERR("Error: plugin %s reported 'user_action_required', but no active session \
- in plugin proxy", priv->plugin_type);
- return;
- }
- gsignond_auth_session_notify_user_action_required(
- priv->active_session, ui_request);
-}
-
-static void
-gsignond_plugin_proxy_error_callback (GSignondPlugin* plugin,
- GError* error,
- gpointer user_data)
-{
- GSignondPluginProxy *self = GSIGNOND_PLUGIN_PROXY (user_data);
- GSignondPluginProxyPrivate *priv = self->priv;
-
- if (priv->active_session == NULL) {
- ERR("Error: plugin %s reported error %s, but no active session \
- in plugin proxy", priv->plugin_type, error->message);
- return;
- }
- // This avoids problems if cancel() is called from AuthSession handler
- GSignondAuthSession *active_session = priv->active_session;
- priv->active_session = NULL;
- gsignond_auth_session_notify_process_error (active_session, error, priv->active_process_userdata);
- g_object_unref (active_session);
- gsignond_plugin_proxy_process_queue (self);
-}
-
-static void
-gsignond_plugin_proxy_status_changed_callback (GSignondPlugin *plugin,
- GSignondPluginState state,
- const gchar *message,
- gpointer user_data)
-{
- GSignondPluginProxy *self = GSIGNOND_PLUGIN_PROXY (user_data);
- GSignondPluginProxyPrivate *priv = self->priv;
-
- if (priv->active_session == NULL) {
- ERR("Error: plugin %s reported change in state %d with message %s, \
- but no active session in plugin proxy", priv->plugin_type, state,
- message);
- return;
- }
- gsignond_auth_session_notify_state_changed (priv->active_session,
- (gint) state, message,
- priv->active_process_userdata);
-}
#include <gsignond/gsignond-plugin-interface.h>
#include <gsignond/gsignond-config.h>
-#define GSIGNOND_TYPE_PLUGIN_PROXY (gsignond_plugin_proxy_get_type ())
-#define GSIGNOND_PLUGIN_PROXY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSIGNOND_TYPE_PLUGIN_PROXY, GSignondPluginProxy))
-#define GSIGNOND_IS_PLUGIN_PROXY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GSIGNOND_TYPE_PLUGIN_PROXY))
-#define GSIGNOND_PLUGIN_PROXY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GSIGNOND_TYPE_PLUGIN_PROXY, GSignondPluginProxyClass))
-#define GSIGNOND_IS_PLUGIN_PROXY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GSIGNOND_TYPE_PLUGIN_PROXY))
-#define GSIGNOND_PLUGIN_PROXY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GSIGNOND_TYPE_PLUGIN_PROXY, GSignondPluginProxyClass))
-
+#define GSIGNOND_TYPE_PLUGIN_PROXY \
+ (gsignond_plugin_proxy_get_type ())
+#define GSIGNOND_PLUGIN_PROXY(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSIGNOND_TYPE_PLUGIN_PROXY, \
+ GSignondPluginProxy))
+#define GSIGNOND_IS_PLUGIN_PROXY(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GSIGNOND_TYPE_PLUGIN_PROXY))
+#define GSIGNOND_PLUGIN_PROXY_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), GSIGNOND_TYPE_PLUGIN_PROXY, \
+ GSignondPluginProxyClass))
+#define GSIGNOND_IS_PLUGIN_PROXY_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), GSIGNOND_TYPE_PLUGIN_PROXY))
+#define GSIGNOND_PLUGIN_PROXY_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), GSIGNOND_TYPE_PLUGIN_PROXY, \
+ GSignondPluginProxyClass))
typedef struct _GSignondPluginProxy GSignondPluginProxy;
typedef struct _GSignondPluginProxyClass GSignondPluginProxyClass;
GObjectClass parent_class;
};
-GType gsignond_plugin_proxy_get_type (void);
+GType
+gsignond_plugin_proxy_get_type (void);
GSignondPluginProxy*
-gsignond_plugin_proxy_new(GSignondConfig *config, const gchar* plugin_type);
-
+gsignond_plugin_proxy_new(
+ GSignondConfig *config,
+ const gchar* plugin_type);
void
-gsignond_plugin_proxy_cancel (GSignondPluginProxy *self,
- GSignondAuthSession* session);
-void gsignond_plugin_proxy_process (GSignondPluginProxy *self,
- GSignondAuthSession* session,
- GSignondSessionData *session_data,
- const gchar *mechanism,
- gpointer userdata);
-void gsignond_plugin_proxy_user_action_finished (GSignondPluginProxy *self,
- GSignondSignonuiData *ui_data);
-void gsignond_plugin_proxy_refresh (GSignondPluginProxy *self,
- GSignondSignonuiData *ui_data);
-
+gsignond_plugin_proxy_cancel (
+ GSignondPluginProxy *self,
+ GSignondAuthSession* session);
+void
+gsignond_plugin_proxy_process (
+ GSignondPluginProxy *self,
+ GSignondAuthSession* session,
+ GSignondSessionData *session_data,
+ const gchar *mechanism,
+ gpointer userdata);
+void
+gsignond_plugin_proxy_user_action_finished (
+ GSignondPluginProxy *self,
+ GSignondSignonuiData *ui_data);
+void
+gsignond_plugin_proxy_refresh (
+ GSignondPluginProxy *self,
+ GSignondSignonuiData *ui_data);
#endif /* __GSIGNOND_PLUGIN_PROXY_H__ */
--- /dev/null
+/* vi: set et sw=4 ts=4 cino=t0,(0: */
+/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of gsignond
+ *
+ * Copyright (C) 2013 Intel Corporation.
+ *
+ * Contact: Imran Zaman <imran.zaman@intel.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#include "gsignond/gsignond-log.h"
+#include "gsignond/gsignond-error.h"
+#include "gsignond/gsignond-pipe-stream.h"
+#include "gsignond/gsignond-plugin-interface.h"
+#include "daemon/dbus/gsignond-dbus.h"
+#include "gsignond-plugin-remote.h"
+
+enum
+{
+ PROP_0,
+ PROP_TYPE,
+ PROP_MECHANISMS,
+ N_PROPERTIES
+};
+
+//static GParamSpec *properties[N_PROPERTIES];
+
+struct _GSignondPluginRemotePrivate
+{
+ GDBusConnection *connection;
+ GSignondDbusRemotePlugin *dbus_plugin_proxy;
+ GIOChannel *err_watch_ch;
+ gchar *plugin_type;
+ gchar **plugin_mechanisms;
+ GPid cpid;
+ guint child_watch_id;
+ guint err_watch_id;
+
+ /* Signals */
+ guint signal_response;
+ guint signal_response_final;
+ guint signal_store;
+ guint signal_error;
+ guint signal_user_action_required;
+ guint signal_refreshed;
+ guint signal_status_changed;
+};
+
+static void
+gsignond_plugin_remote_interface_init (
+ GSignondPluginInterface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GSignondPluginRemote, gsignond_plugin_remote,
+ G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE (GSIGNOND_TYPE_PLUGIN,
+ gsignond_plugin_remote_interface_init));
+
+#define GSIGNOND_PLUGIN_REMOTE_GET_PRIV(obj) \
+ G_TYPE_INSTANCE_GET_PRIVATE ((obj), GSIGNOND_TYPE_PLUGIN_REMOTE, \
+ GSignondPluginRemotePrivate)
+
+#define GSIGNOND_PLUGIND_NAME "gsignond-plugind"
+
+static void
+gsignond_plugin_remote_set_property (
+ GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ }
+}
+
+static void
+gsignond_plugin_remote_get_property (
+ GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GSignondPluginRemote *self = GSIGNOND_PLUGIN_REMOTE (object);
+
+ switch (property_id) {
+ case PROP_TYPE: {
+ if (!self->priv->plugin_type) {
+ GError *error = NULL;
+ gsignond_dbus_remote_plugin_call_get_info_sync (
+ self->priv->dbus_plugin_proxy, &self->priv->plugin_type,
+ &self->priv->plugin_mechanisms, NULL, &error);
+ if (error) {
+ DBG ("Plugin type retrieval error :: %s", error->message);
+ g_error_free (error);
+ self->priv->plugin_type = NULL;
+ }
+ }
+ g_value_set_string (value, self->priv->plugin_type);
+ break;
+ }
+ case PROP_MECHANISMS: {
+ if (!self->priv->plugin_mechanisms) {
+ GError *error = NULL;
+ gsignond_dbus_remote_plugin_call_get_info_sync (
+ self->priv->dbus_plugin_proxy, &self->priv->plugin_type,
+ &self->priv->plugin_mechanisms, NULL, &error);
+ if (error) {
+ DBG ("Plugin mechanisms retrieval error :: %s",
+ error->message);
+ g_error_free (error);
+ self->priv->plugin_mechanisms = NULL;
+ }
+ }
+ g_value_set_boxed (value, self->priv->plugin_mechanisms);
+ break;
+ }
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ }
+
+}
+
+static void
+gsignond_plugin_remote_dispose (GObject *object)
+{
+ GSignondPluginRemote *self = GSIGNOND_PLUGIN_REMOTE (object);
+
+ if (self->priv->err_watch_ch) {
+ g_io_channel_shutdown (self->priv->err_watch_ch, FALSE, NULL);
+ g_io_channel_unref (self->priv->err_watch_ch);
+ g_source_remove (self->priv->err_watch_id);
+ self->priv->err_watch_ch = NULL;
+ }
+
+ if (self->priv->connection) {
+ g_object_unref (self->priv->connection);
+ self->priv->connection = NULL;
+ }
+
+ if (self->priv->dbus_plugin_proxy) {
+ g_signal_handler_disconnect (self->priv->dbus_plugin_proxy,
+ self->priv->signal_response);
+ g_signal_handler_disconnect (self->priv->dbus_plugin_proxy,
+ self->priv->signal_response_final);
+ g_signal_handler_disconnect (self->priv->dbus_plugin_proxy,
+ self->priv->signal_store);
+ g_signal_handler_disconnect (self->priv->dbus_plugin_proxy,
+ self->priv->signal_error);
+ g_signal_handler_disconnect (self->priv->dbus_plugin_proxy,
+ self->priv->signal_user_action_required);
+ g_signal_handler_disconnect (self->priv->dbus_plugin_proxy,
+ self->priv->signal_refreshed);
+ g_signal_handler_disconnect (self->priv->dbus_plugin_proxy,
+ self->priv->signal_status_changed);
+ g_object_unref (self->priv->dbus_plugin_proxy);
+ self->priv->dbus_plugin_proxy = NULL;
+ }
+
+ if (self->priv->cpid > 0) {
+ if (self->priv->child_watch_id) {
+ g_source_remove (self->priv->child_watch_id);
+ self->priv->child_watch_id = 0;
+ }
+ kill (self->priv->cpid, SIGTERM);
+ self->priv->cpid = 0;
+ }
+
+ G_OBJECT_CLASS (gsignond_plugin_remote_parent_class)->dispose (object);
+}
+
+static void
+gsignond_plugin_remote_finalize (GObject *object)
+{
+ GSignondPluginRemote *self = GSIGNOND_PLUGIN_REMOTE (object);
+
+ if (self->priv->plugin_type) {
+ g_free (self->priv->plugin_type);
+ self->priv->plugin_type = NULL;
+ }
+
+ if (self->priv->plugin_mechanisms) {
+ g_strfreev (self->priv->plugin_mechanisms);
+ self->priv->plugin_mechanisms = NULL;
+ }
+
+ G_OBJECT_CLASS (gsignond_plugin_remote_parent_class)->finalize (object);
+}
+
+static void
+gsignond_plugin_remote_class_init (GSignondPluginRemoteClass *klass)
+{
+ GObjectClass* object_class = G_OBJECT_CLASS (klass);
+
+ g_type_class_add_private (object_class,
+ sizeof (GSignondPluginRemotePrivate));
+
+ object_class->get_property = gsignond_plugin_remote_get_property;
+ object_class->set_property = gsignond_plugin_remote_set_property;
+ object_class->dispose = gsignond_plugin_remote_dispose;
+ object_class->finalize = gsignond_plugin_remote_finalize;
+
+ g_object_class_override_property (object_class, PROP_TYPE, "type");
+ g_object_class_override_property (object_class, PROP_MECHANISMS,
+ "mechanisms");
+
+}
+
+/* signals */
+enum
+{
+ USER_ACTION_FINISHED_TRIGGERED,
+ LAST_SIGNAL
+};
+static guint task_signals[LAST_SIGNAL] = { 0 };
+
+static void
+gsignond_plugin_remote_init (GSignondPluginRemote *self)
+{
+ self->priv = GSIGNOND_PLUGIN_REMOTE_GET_PRIV(self);
+
+ self->priv->connection = NULL;
+ self->priv->dbus_plugin_proxy = NULL;
+ self->priv->err_watch_ch = NULL;
+ self->priv->plugin_type = NULL;
+ self->priv->plugin_mechanisms = NULL;
+ self->priv->cpid = 0;
+ self->priv->child_watch_id = 0;
+
+}
+
+static void
+_cancel_async_cb (
+ GObject *object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GError *error = NULL;
+ GSignondDbusRemotePlugin *proxy = GSIGNOND_DBUS_REMOTE_PLUGIN (object);
+ GSignondPluginRemote *self = GSIGNOND_PLUGIN_REMOTE (user_data);
+
+ gsignond_dbus_remote_plugin_call_cancel_finish (proxy, res, &error);
+ if (error) {
+ gsignond_plugin_error (GSIGNOND_PLUGIN(self), error);
+ g_error_free (error);
+ }
+}
+
+static void
+gsignond_plugin_remote_cancel (
+ GSignondPlugin *plugin)
+{
+ g_return_if_fail (plugin && GSIGNOND_IS_PLUGIN_REMOTE (plugin));
+ GSignondPluginRemote *self = GSIGNOND_PLUGIN_REMOTE (plugin);
+
+ gsignond_dbus_remote_plugin_call_cancel (
+ self->priv->dbus_plugin_proxy, NULL, _cancel_async_cb, self);
+}
+
+static void
+_request_initial_async_cb (
+ GObject *object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GError *error = NULL;
+ GSignondDbusRemotePlugin *proxy = GSIGNOND_DBUS_REMOTE_PLUGIN (object);
+ GSignondPluginRemote *self = GSIGNOND_PLUGIN_REMOTE (user_data);
+ gsignond_dbus_remote_plugin_call_request_initial_finish (proxy,
+ res, &error);
+ if (error) {
+ gsignond_plugin_error (GSIGNOND_PLUGIN(self), error);
+ g_error_free (error);
+ }
+}
+
+static void
+gsignond_plugin_remote_request_initial (
+ GSignondPlugin *plugin,
+ GSignondSessionData *session_data,
+ const gchar *mechanism)
+{
+ g_return_if_fail (session_data && plugin &&
+ GSIGNOND_IS_PLUGIN_REMOTE (plugin));
+ GSignondPluginRemote *self = GSIGNOND_PLUGIN_REMOTE (plugin);
+
+ GVariant *data = gsignond_dictionary_to_variant (session_data);
+ gsignond_dbus_remote_plugin_call_request_initial (
+ self->priv->dbus_plugin_proxy, data, mechanism, NULL,
+ _request_initial_async_cb, self);
+}
+
+static void
+_request_async_cb (
+ GObject *object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GError *error = NULL;
+ GSignondDbusRemotePlugin *proxy = GSIGNOND_DBUS_REMOTE_PLUGIN (object);
+ GSignondPluginRemote *self = GSIGNOND_PLUGIN_REMOTE (user_data);
+
+ gsignond_dbus_remote_plugin_call_request_finish (proxy, res, &error);
+ if (error) {
+ gsignond_plugin_error (GSIGNOND_PLUGIN(self), error);
+ g_error_free (error);
+ }
+}
+
+static void
+gsignond_plugin_remote_request (
+ GSignondPlugin *plugin,
+ GSignondSessionData *session_data)
+{
+ g_return_if_fail (session_data && plugin &&
+ GSIGNOND_IS_PLUGIN_REMOTE (plugin));
+ GSignondPluginRemote *self = GSIGNOND_PLUGIN_REMOTE (plugin);
+
+ GVariant *data = gsignond_dictionary_to_variant (session_data);
+ gsignond_dbus_remote_plugin_call_request (
+ self->priv->dbus_plugin_proxy, data, NULL, _request_async_cb, self);
+}
+
+static void
+_user_action_finished_async_cb (
+ GObject *object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GError *error = NULL;
+ GSignondDbusRemotePlugin *proxy = GSIGNOND_DBUS_REMOTE_PLUGIN (object);
+ GSignondPluginRemote *self = GSIGNOND_PLUGIN_REMOTE (user_data);
+
+ gsignond_dbus_remote_plugin_call_user_action_finished_finish (proxy,
+ res, &error);
+ if (error) {
+ gsignond_plugin_error (GSIGNOND_PLUGIN(self), error);
+ g_error_free (error);
+ } else {
+ g_signal_emit (self, task_signals[USER_ACTION_FINISHED_TRIGGERED], 0);
+ }
+}
+
+static void
+gsignond_plugin_remote_user_action_finished (
+ GSignondPlugin *plugin,
+ GSignondSignonuiData *signonui_data)
+{
+ g_return_if_fail (signonui_data && plugin &&
+ GSIGNOND_IS_PLUGIN_REMOTE (plugin));
+ GSignondPluginRemote *self = GSIGNOND_PLUGIN_REMOTE (plugin);
+
+ GVariant *data = gsignond_signonui_data_to_variant (signonui_data);
+ gsignond_dbus_remote_plugin_call_user_action_finished (
+ self->priv->dbus_plugin_proxy, data, NULL,
+ _user_action_finished_async_cb, self);
+}
+
+static void
+_refresh_async_cb (
+ GObject *object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GError *error = NULL;
+ GSignondDbusRemotePlugin *proxy = GSIGNOND_DBUS_REMOTE_PLUGIN (object);
+ GSignondPluginRemote *self = GSIGNOND_PLUGIN_REMOTE (user_data);
+
+ gsignond_dbus_remote_plugin_call_refresh_finish (proxy, res, &error);
+ if (error) {
+ gsignond_plugin_error (GSIGNOND_PLUGIN(self), error);
+ g_error_free (error);
+ }
+}
+
+static void
+gsignond_plugin_remote_refresh (
+ GSignondPlugin *plugin,
+ GSignondSignonuiData *signonui_data)
+{
+ g_return_if_fail (signonui_data && plugin &&
+ GSIGNOND_IS_PLUGIN_REMOTE (plugin));
+ GSignondPluginRemote *self = GSIGNOND_PLUGIN_REMOTE (plugin);
+
+ GVariant *data = gsignond_signonui_data_to_variant (signonui_data);
+ gsignond_dbus_remote_plugin_call_refresh (
+ self->priv->dbus_plugin_proxy, data, NULL, _refresh_async_cb, self);
+}
+
+static void
+gsignond_plugin_remote_interface_init (GSignondPluginInterface *iface)
+{
+ iface->cancel = gsignond_plugin_remote_cancel;
+ iface->request_initial = gsignond_plugin_remote_request_initial;
+ iface->request = gsignond_plugin_remote_request;
+ iface->user_action_finished = gsignond_plugin_remote_user_action_finished;
+ iface->refresh = gsignond_plugin_remote_refresh;
+
+ task_signals[USER_ACTION_FINISHED_TRIGGERED] = g_signal_new (
+ "user-action-finished-triggered", G_TYPE_FROM_CLASS (iface),
+ G_SIGNAL_RUN_FIRST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0);
+}
+
+static void
+_response_cb (
+ GSignondPluginRemote *self,
+ GVariant *session_data,
+ gpointer user_data)
+{
+ g_return_if_fail (self && GSIGNOND_IS_PLUGIN_REMOTE (self));
+
+ GSignondSessionData *data = (GSignondSessionData *)
+ gsignond_dictionary_new_from_variant (session_data);
+ gsignond_plugin_response (GSIGNOND_PLUGIN(self), data);
+ gsignond_dictionary_unref (data);
+}
+
+static void
+_response_final_cb (
+ GSignondPluginRemote *self,
+ GVariant *session_data,
+ gpointer user_data)
+{
+ g_return_if_fail (self && GSIGNOND_IS_PLUGIN_REMOTE (self));
+
+ GSignondSessionData *data = (GSignondSessionData *)
+ gsignond_dictionary_new_from_variant (session_data);
+ gsignond_plugin_response_final (GSIGNOND_PLUGIN(self), data);
+ gsignond_dictionary_unref (data);
+}
+
+static void
+_store_cb (
+ GSignondPluginRemote *self,
+ GVariant *session_data,
+ gpointer user_data)
+{
+ g_return_if_fail (self && GSIGNOND_IS_PLUGIN_REMOTE (self));
+
+ GSignondSessionData *data = (GSignondSessionData *)
+ gsignond_dictionary_new_from_variant (session_data);
+ gsignond_plugin_store (GSIGNOND_PLUGIN(self), data);
+ gsignond_dictionary_unref (data);
+}
+
+static void
+_error_cb (
+ GSignondPluginRemote *self,
+ GVariant *error,
+ gpointer user_data)
+{
+ g_return_if_fail (self && GSIGNOND_IS_PLUGIN_REMOTE (self));
+ GError *gerror = gsignond_error_new_from_variant (error);
+ gsignond_plugin_error (GSIGNOND_PLUGIN(self), gerror);
+ g_error_free (gerror);
+}
+
+static void
+_user_action_required_cb (
+ GSignondPluginRemote *self,
+ GVariant *ui_data,
+ gpointer user_data)
+{
+ g_return_if_fail (self && GSIGNOND_IS_PLUGIN_REMOTE (self));
+
+ GSignondSignonuiData *data = (GSignondSignonuiData *)
+ gsignond_signonui_data_new_from_variant (ui_data);
+ gsignond_plugin_user_action_required (GSIGNOND_PLUGIN(self), data);
+ gsignond_signonui_data_unref (data);
+}
+
+static void
+_refreshed_cb(
+ GSignondPluginRemote *self,
+ GVariant *ui_data,
+ gpointer user_data)
+{
+ g_return_if_fail (self && GSIGNOND_IS_PLUGIN_REMOTE (self));
+
+ GSignondSignonuiData *data = (GSignondSignonuiData *)
+ gsignond_signonui_data_new_from_variant (ui_data);
+ gsignond_plugin_refreshed (GSIGNOND_PLUGIN(self), data);
+ gsignond_signonui_data_unref (data);
+}
+
+static void
+_status_changed_cb (
+ GSignondPluginRemote *self,
+ gint status,
+ gchar *message,
+ gpointer user_data)
+{
+ g_return_if_fail (self && GSIGNOND_IS_PLUGIN_REMOTE (self));
+
+ gsignond_plugin_status_changed (GSIGNOND_PLUGIN(self),
+ (GSignondPluginState)status, message);
+}
+
+static gboolean
+_error_watch_cb (
+ GIOChannel *channel,
+ GIOCondition condition,
+ gpointer data)
+{
+
+ GSignondPluginRemote *plugin = (GSignondPluginRemote*)data;
+
+ if (condition == G_IO_HUP || condition == G_IO_ERR ||
+ condition == G_IO_NVAL) {
+ g_io_channel_shutdown (plugin->priv->err_watch_ch, FALSE, NULL);
+ g_io_channel_unref (plugin->priv->err_watch_ch);
+ plugin->priv->err_watch_ch = NULL;
+ g_source_remove (plugin->priv->err_watch_id);
+ DBG ("Plugind (%s) is down",
+ plugin->priv->plugin_type ? plugin->priv->plugin_type : "");
+ return FALSE;
+ }
+
+ if (g_io_channel_get_flags (channel) & G_IO_FLAG_IS_READABLE) {
+ gchar * string = NULL;
+ GError *error = NULL;
+ gsize bytes_read = 0;
+ gboolean keep_error_source = TRUE;
+ GIOStatus status = g_io_channel_read_line (channel, &string,
+ &bytes_read, NULL, &error);
+ if (status == G_IO_STATUS_NORMAL && bytes_read > 0 && error == NULL) {
+ DBG ("(%s) %s",plugin->priv?(plugin->priv->plugin_type ?
+ plugin->priv->plugin_type : "NULL"):"NULL", string);
+ }
+ if (string) {
+ g_free (string);
+ }
+ keep_error_source = (bytes_read > 0 && error == NULL);
+ if (error) {
+ g_error_free (error);
+ }
+ if (!keep_error_source) {
+ DBG ("Removing error source- bytes_read %d, error %p",
+ (gint)bytes_read, error?error:NULL);
+ }
+ return keep_error_source;
+ }
+
+ return TRUE;
+}
+
+static void
+_child_watch_cb (
+ GPid pid,
+ gint status,
+ gpointer data)
+{
+ GSignondPluginRemote *plugin = (GSignondPluginRemote*)data;
+ DBG ("Plugin process (%s) with pid (%d) closed",
+ plugin->priv->plugin_type ? plugin->priv->plugin_type : "", pid);
+ g_spawn_close_pid (pid);
+ g_source_remove (plugin->priv->child_watch_id);
+ plugin->priv->child_watch_id = 0;
+}
+
+GSignondPluginRemote *
+gsignond_plugin_remote_new (
+ GSignondConfig *config,
+ const gchar *plugin_type)
+{
+ gchar *object_path = NULL;
+ GError *error = NULL;
+ GPid cpid = 0;
+ gchar **argv;
+ gint cin_fd, cout_fd, cerr_fd;
+ GSignondPluginRemote *plugin = NULL;
+ GSignondPipeStream *stream = NULL;
+ gboolean ret = FALSE;
+
+ /* Spawn child process */
+ argv = g_malloc0 ((3 + 1) * sizeof (gchar *));
+ argv[0] = g_build_filename (gsignond_config_get_string (config,
+ GSIGNOND_CONFIG_GENERAL_BIN_DIR), GSIGNOND_PLUGIND_NAME, NULL);
+ argv[1] = g_module_build_path (gsignond_config_get_string (config,
+ GSIGNOND_CONFIG_GENERAL_PLUGINS_DIR), plugin_type);
+ argv[2] = g_strdup(plugin_type);
+ ret = g_spawn_async_with_pipes (NULL, argv, NULL,
+ G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_SEARCH_PATH, NULL,
+ NULL, &cpid, &cin_fd, &cout_fd, &cerr_fd, &error);
+ g_strfreev (argv);
+ if (ret == FALSE || (kill(cpid, 0) != 0)) {
+ DBG ("failed to start plugind: ret(%d)", ret);
+ if (error) g_error_free (error);
+ return NULL;
+ }
+ /* Create dbus plugin object */
+ plugin = GSIGNOND_PLUGIN_REMOTE (g_object_new (GSIGNOND_TYPE_PLUGIN_REMOTE,
+ NULL));
+
+ plugin->priv->child_watch_id = g_child_watch_add (cpid,
+ (GChildWatchFunc)_child_watch_cb, plugin);
+ plugin->priv->cpid = cpid;
+
+ object_path = g_strdup_printf ("%s_%s", GSIGNOND_PLUGIN_OBJECTPATH,
+ plugin_type);
+
+ /* Create dbus connection */
+ stream = gsignond_pipe_stream_new (cout_fd, cin_fd);
+ plugin->priv->connection = g_dbus_connection_new_sync (G_IO_STREAM (stream),
+ NULL, G_DBUS_CONNECTION_FLAGS_NONE, NULL, NULL, NULL);
+ g_object_unref (stream);
+
+ /* Create dbus proxy */
+ plugin->priv->dbus_plugin_proxy =
+ gsignond_dbus_remote_plugin_proxy_new_sync (
+ plugin->priv->connection,
+ G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES,
+ NULL,
+ object_path,
+ NULL,
+ &error);
+ if (error) {
+ DBG ("Failed to register object: %s", error->message);
+ g_error_free (error);
+ g_free (object_path);
+ g_object_unref (plugin);
+ return NULL;
+ }
+ DBG("'%s' object exported(%p)", object_path, plugin);
+ g_free (object_path);
+
+ plugin->priv->signal_response = g_signal_connect_swapped (
+ plugin->priv->dbus_plugin_proxy, "response",
+ G_CALLBACK (_response_cb), plugin);
+ plugin->priv->signal_response_final = g_signal_connect_swapped (
+ plugin->priv->dbus_plugin_proxy, "response-final",
+ G_CALLBACK(_response_final_cb), plugin);
+ plugin->priv->signal_store = g_signal_connect_swapped (
+ plugin->priv->dbus_plugin_proxy, "store",
+ G_CALLBACK(_store_cb), plugin);
+ plugin->priv->signal_error = g_signal_connect_swapped (
+ plugin->priv->dbus_plugin_proxy, "error",
+ G_CALLBACK(_error_cb), plugin);
+ plugin->priv->signal_user_action_required = g_signal_connect_swapped (
+ plugin->priv->dbus_plugin_proxy, "user-action-required",
+ G_CALLBACK(_user_action_required_cb), plugin);
+ plugin->priv->signal_refreshed = g_signal_connect_swapped (
+ plugin->priv->dbus_plugin_proxy, "refreshed",
+ G_CALLBACK(_refreshed_cb), plugin);
+ plugin->priv->signal_status_changed = g_signal_connect_swapped (
+ plugin->priv->dbus_plugin_proxy, "status-changed",
+ G_CALLBACK(_status_changed_cb), plugin);
+
+ /* Create watch for error messages */
+ plugin->priv->err_watch_ch = g_io_channel_unix_new (cerr_fd);
+ plugin->priv->err_watch_id = g_io_add_watch (plugin->priv->err_watch_ch,
+ G_IO_IN | G_IO_HUP, (GIOFunc)_error_watch_cb, plugin);
+ g_io_channel_set_close_on_unref (plugin->priv->err_watch_ch, TRUE);
+ g_io_channel_set_flags (plugin->priv->err_watch_ch, G_IO_FLAG_NONBLOCK,
+ NULL);
+
+ return plugin;
+}
+
--- /dev/null
+/* vi: set et sw=4 ts=4 cino=t0,(0: */
+/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of gsignond
+ *
+ * Copyright (C) 2013 Intel Corporation.
+ *
+ * Contact: Imran Zaman <imran.zaman@intel.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#ifndef __GSIGNOND_PLUGIN_REMOTE_H_
+#define __GSIGNOND_PLUGIN_REMOTE_H_
+
+#include <glib.h>
+#include <daemon/dbus/gsignond-dbus-remote-plugin-gen.h>
+#include <gsignond/gsignond-config.h>
+
+G_BEGIN_DECLS
+
+#define GSIGNOND_TYPE_PLUGIN_REMOTE \
+ (gsignond_plugin_remote_get_type())
+#define GSIGNOND_PLUGIN_REMOTE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),\
+ GSIGNOND_TYPE_PLUGIN_REMOTE, GSignondPluginRemote))
+#define GSIGNOND_PLUGIN_REMOTE_CLASS(klass)\
+ (G_TYPE_CHECK_CLASS_CAST((klass), GSIGNOND_TYPE_PLUGIN_REMOTE, \
+ GSignondPluginRemoteClass))
+#define GSIGNOND_IS_PLUGIN_REMOTE(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj), GSIGNOND_TYPE_PLUGIN_REMOTE))
+#define GSIGNOND_IS_PLUGIN_REMOTE_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass), GSIGNOND_TYPE_PLUGIN_REMOTE))
+#define GSIGNOND_PLUGIN_REMOTE_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS((obj), GSIGNOND_TYPE_PLUGIN_REMOTE, \
+ GSignondPluginRemoteClass))
+
+typedef struct _GSignondPluginRemote GSignondPluginRemote;
+typedef struct _GSignondPluginRemoteClass GSignondPluginRemoteClass;
+typedef struct _GSignondPluginRemotePrivate GSignondPluginRemotePrivate;
+
+struct _GSignondPluginRemote
+{
+ GObject parent;
+
+ /* priv */
+ GSignondPluginRemotePrivate *priv;
+};
+
+struct _GSignondPluginRemoteClass
+{
+ GObjectClass parent_class;
+};
+
+GType
+gsignond_plugin_remote_get_type (void) G_GNUC_CONST;
+
+GSignondPluginRemote *
+gsignond_plugin_remote_new (
+ GSignondConfig *config,
+ const gchar *plugin_type);
+
+G_END_DECLS
+
+#endif /* __GSIGNOND_PLUGIN_REMOTE_H_ */
--- /dev/null
+SUBDIRS=
+NULL=
+
+bin_PROGRAMS = gsignond-plugind
+
+gsignond_plugind_SOURCES = \
+ main.c \
+ gsignond-plugin-daemon.c \
+ $(NULL)
+
+gsignond_plugind_CFLAGS = \
+ -I$(top_srcdir) \
+ -I$(top_srcdir)/include/ \
+ -I$(top_srcdir)/src/ \
+ $(GSIGNOND_CFLAGS) \
+ $(NULL)
+
+gsignond_plugind_LDADD = \
+ $(top_srcdir)/src/common/libgsignond-common.la \
+ $(top_srcdir)/src/daemon/dbus/libgsignond-dbus-glue.la \
+ $(GSIGNOND_LIBS) \
+ $(NULL)
+
--- /dev/null
+/* vi: set et sw=4 ts=4 cino=t0,(0: */
+/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of gsignond
+ *
+ * Copyright (C) 2013 Intel Corporation.
+ *
+ * Contact: Imran Zaman <imran.zaman@intel.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#include "gsignond/gsignond-plugin-interface.h"
+#include "daemon/dbus/gsignond-dbus-remote-plugin-gen.h"
+#include "daemon/dbus/gsignond-dbus.h"
+#include "gsignond/gsignond-plugin-loader.h"
+#include "gsignond/gsignond-pipe-stream.h"
+#include "gsignond/gsignond-log.h"
+#include "gsignond/gsignond-error.h"
+#include "gsignond-plugin-daemon.h"
+
+struct _GSignondPluginDaemonPrivate
+{
+ GDBusConnection *connection;
+ GSignondDbusRemotePlugin *dbus_remote_plugin;
+ GSignondPlugin *plugin;
+ gchar *plugin_type;
+};
+
+G_DEFINE_TYPE (GSignondPluginDaemon, gsignond_plugin_daemon, G_TYPE_OBJECT)
+
+
+#define GSIGNOND_PLUGIN_DAEMON_GET_PRIV(obj) \
+ G_TYPE_INSTANCE_GET_PRIVATE ((obj), GSIGNOND_TYPE_PLUGIN_DAEMON,\
+ GSignondPluginDaemonPrivate)
+
+static void
+_dispose (GObject *object)
+{
+ GSignondPluginDaemon *self = GSIGNOND_PLUGIN_DAEMON (object);
+
+ if (self->priv->dbus_remote_plugin) {
+ g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (
+ self->priv->dbus_remote_plugin));
+ g_object_unref (self->priv->dbus_remote_plugin);
+ self->priv->dbus_remote_plugin = NULL;
+ }
+
+ if (self->priv->connection) {
+ g_object_unref (self->priv->connection);
+ self->priv->connection = NULL;
+ }
+
+ if (self->priv->plugin) {
+ g_object_unref (self->priv->plugin);
+ self->priv->plugin = NULL;
+ }
+
+ G_OBJECT_CLASS (gsignond_plugin_daemon_parent_class)->dispose (object);
+}
+
+static void
+_finalize (GObject *object)
+{
+ GSignondPluginDaemon *self = GSIGNOND_PLUGIN_DAEMON (object);
+
+ if (self->priv->plugin_type) {
+ g_free (self->priv->plugin_type);
+ self->priv->plugin_type = NULL;
+ }
+
+ G_OBJECT_CLASS (gsignond_plugin_daemon_parent_class)->finalize (object);
+}
+
+static void
+gsignond_plugin_daemon_class_init (
+ GSignondPluginDaemonClass *klass)
+{
+ GObjectClass* object_class = G_OBJECT_CLASS (klass);
+
+ g_type_class_add_private (object_class, sizeof (
+ GSignondPluginDaemonPrivate));
+
+ object_class->dispose = _dispose;
+ object_class->finalize = _finalize;
+
+}
+
+static void
+gsignond_plugin_daemon_init (
+ GSignondPluginDaemon *self)
+{
+ self->priv = GSIGNOND_PLUGIN_DAEMON_GET_PRIV(self);
+ self->priv->connection = NULL;
+ self->priv->dbus_remote_plugin = NULL;
+ self->priv->plugin_type = NULL;
+ self->priv->plugin = NULL;
+}
+
+static void
+_on_connection_closed (
+ GDBusConnection *connection,
+ gboolean remote_peer_vanished,
+ GError *error,
+ gpointer user_data)
+{
+ GSignondPluginDaemon *daemon = GSIGNOND_PLUGIN_DAEMON (user_data);
+
+ g_signal_handlers_disconnect_by_func (connection, _on_connection_closed,
+ user_data);
+ DBG("dbus connection(%p) closed (peer vanished : %d)", connection,
+ remote_peer_vanished);
+ if (error) {
+ DBG("...reason : %s", error->message);
+ }
+ g_object_unref (daemon);
+}
+
+static gboolean
+_handle_cancel_from_dbus (
+ GSignondPluginDaemon *self,
+ GDBusMethodInvocation *invocation,
+ gpointer user_data)
+{
+ DBG ("");
+ g_return_val_if_fail (self && GSIGNOND_IS_PLUGIN_DAEMON (self), FALSE);
+ gsignond_dbus_remote_plugin_complete_cancel (self->priv->dbus_remote_plugin,
+ invocation);
+
+ gsignond_plugin_cancel (self->priv->plugin);
+ return TRUE;
+}
+
+static gboolean
+_handle_request_from_dbus (
+ GSignondPluginDaemon *self,
+ GDBusMethodInvocation *invocation,
+ const GVariant *session_data,
+ gpointer user_data)
+{
+ DBG ("");
+ g_return_val_if_fail (self && GSIGNOND_IS_PLUGIN_DAEMON (self), FALSE);
+
+ gsignond_dbus_remote_plugin_complete_request (
+ self->priv->dbus_remote_plugin, invocation);
+
+ GSignondSessionData *data = (GSignondSessionData *)
+ gsignond_dictionary_new_from_variant ((GVariant *)session_data);
+ gsignond_plugin_request (self->priv->plugin, data);
+ gsignond_dictionary_unref (data);
+ return TRUE;
+}
+
+static void
+_handle_response_final_from_plugin (
+ GSignondPluginDaemon *self,
+ GSignondSessionData *session_data,
+ gpointer user_data);
+
+static gboolean
+_handle_request_initial_from_dbus (
+ GSignondPluginDaemon *self,
+ GDBusMethodInvocation *invocation,
+ const GVariant *session_data,
+ const gchar *mechanism,
+ gpointer user_data)
+{
+ DBG ("");
+ g_return_val_if_fail (self && GSIGNOND_IS_PLUGIN_DAEMON (self), FALSE);
+
+ gsignond_dbus_remote_plugin_complete_request_initial (
+ self->priv->dbus_remote_plugin, invocation);
+
+ GSignondSessionData *data = (GSignondSessionData *)
+ gsignond_dictionary_new_from_variant ((GVariant *)session_data);
+ gsignond_plugin_request_initial (self->priv->plugin, data, mechanism);
+ gsignond_dictionary_unref (data);
+
+ return TRUE;
+}
+
+static gboolean
+_handle_user_action_finished_from_dbus (
+ GSignondPluginDaemon *self,
+ GDBusMethodInvocation *invocation,
+ const GVariant *ui_data,
+ gpointer user_data)
+{
+ DBG ("");
+ g_return_val_if_fail (self && GSIGNOND_IS_PLUGIN_DAEMON (self), FALSE);
+
+ gsignond_dbus_remote_plugin_complete_user_action_finished (
+ self->priv->dbus_remote_plugin, invocation);
+
+ GSignondSignonuiData *data = (GSignondSignonuiData *)
+ gsignond_signonui_data_new_from_variant ((GVariant *)ui_data);
+ gsignond_plugin_user_action_finished (self->priv->plugin, data);
+ gsignond_signonui_data_unref (data);
+ return TRUE;
+}
+
+static gboolean
+_handle_refresh_from_dbus (
+ GSignondPluginDaemon *self,
+ GDBusMethodInvocation *invocation,
+ const GVariant *ui_data,
+ gpointer user_data)
+{
+ DBG ("");
+ g_return_val_if_fail (self && GSIGNOND_IS_PLUGIN_DAEMON (self), FALSE);
+
+ gsignond_dbus_remote_plugin_complete_refresh (
+ self->priv->dbus_remote_plugin, invocation);
+
+ GSignondSignonuiData *data = (GSignondSignonuiData *)
+ gsignond_signonui_data_new_from_variant ((GVariant *)ui_data);
+ gsignond_plugin_refresh (self->priv->plugin, data);
+ gsignond_signonui_data_unref (data);
+ return TRUE;
+}
+
+static gboolean
+_handle_get_info_from_dbus (
+ GSignondPluginDaemon *self,
+ GDBusMethodInvocation *invocation,
+ gpointer user_data)
+{
+ DBG ("");
+ g_return_val_if_fail (self && GSIGNOND_IS_PLUGIN_DAEMON (self), FALSE);
+ gchar *type = NULL;
+ gchar **mechanisms = NULL;
+
+ g_object_get (self->priv->plugin, "type", &type, "mechanisms", &mechanisms,
+ NULL);
+ gsignond_dbus_remote_plugin_complete_get_info (
+ self->priv->dbus_remote_plugin, invocation, (const gchar*)type,
+ (const gchar *const *)mechanisms);
+ g_free (type);
+ g_strfreev (mechanisms);
+ return TRUE;
+}
+
+static void
+_handle_response_from_plugin (
+ GSignondPluginDaemon *self,
+ GSignondSessionData *session_data,
+ gpointer user_data)
+{
+ DBG ("");
+ g_return_if_fail (self && GSIGNOND_IS_PLUGIN_DAEMON (self));
+
+ GVariant *data = gsignond_dictionary_to_variant (
+ (GSignondDictionary *)session_data);
+ gsignond_dbus_remote_plugin_emit_response (self->priv->dbus_remote_plugin,
+ data);
+}
+
+static void
+_handle_response_final_from_plugin (
+ GSignondPluginDaemon *self,
+ GSignondSessionData *session_data,
+ gpointer user_data)
+{
+ DBG ("");
+ g_return_if_fail (self && GSIGNOND_IS_PLUGIN_DAEMON (self));
+
+ GVariant *data = gsignond_dictionary_to_variant (
+ (GSignondDictionary *)session_data);
+ gsignond_dbus_remote_plugin_emit_response_final (
+ self->priv->dbus_remote_plugin, data);
+}
+
+static void
+_handle_store_from_plugin (
+ GSignondPluginDaemon *self,
+ GSignondSessionData *session_data,
+ gpointer user_data)
+{
+ DBG ("");
+ g_return_if_fail (self && GSIGNOND_IS_PLUGIN_DAEMON (self));
+
+ GVariant *data = gsignond_dictionary_to_variant (
+ (GSignondDictionary *)session_data);
+ gsignond_dbus_remote_plugin_emit_store (self->priv->dbus_remote_plugin,
+ data);
+}
+
+static void
+_handle_error_from_plugin (
+ GSignondPluginDaemon *self,
+ GError *gerror,
+ gpointer user_data)
+{
+ DBG ("");
+ g_return_if_fail (self && GSIGNOND_IS_PLUGIN_DAEMON (self));
+
+ GVariant *error = gsignond_error_to_variant (gerror);
+ gsignond_dbus_remote_plugin_emit_error (self->priv->dbus_remote_plugin,
+ error);
+}
+
+static void
+_handle_user_action_required_from_plugin (
+ GSignondPluginDaemon *self,
+ GSignondSignonuiData *ui_data,
+ gpointer user_data)
+{
+ DBG ("");
+ g_return_if_fail (self && GSIGNOND_IS_PLUGIN_DAEMON (self));
+
+ GVariant *data = gsignond_signonui_data_to_variant (ui_data);
+ gsignond_dbus_remote_plugin_emit_user_action_required (
+ self->priv->dbus_remote_plugin, data);
+}
+
+static void
+_handle_refreshed_from_plugin(
+ GSignondPluginDaemon *self,
+ GSignondSignonuiData *ui_data,
+ gpointer user_data)
+{
+ DBG ("");
+ g_return_if_fail (self && GSIGNOND_IS_PLUGIN_DAEMON (self));
+
+ GVariant *data = gsignond_signonui_data_to_variant (ui_data);
+ gsignond_dbus_remote_plugin_emit_refreshed (self->priv->dbus_remote_plugin,
+ data);
+}
+
+static void
+_handle_status_changed_from_plugin (
+ GSignondPluginDaemon *self,
+ GSignondPluginState status,
+ gchar *message,
+ gpointer user_data)
+{
+ DBG ("");
+ g_return_if_fail (self && GSIGNOND_IS_PLUGIN_DAEMON (self));
+
+ gsignond_dbus_remote_plugin_emit_status_changed (
+ self->priv->dbus_remote_plugin, (gint)status,
+ (const gchar *)message);
+}
+
+GSignondPluginDaemon *
+gsignond_plugin_daemon_new (
+ const gchar* filename,
+ const gchar* plugin_type)
+{
+ GError *error = NULL;
+ gchar *object_path = NULL;
+ GSignondPipeStream *stream = NULL;
+
+ g_return_val_if_fail (filename != NULL && plugin_type != NULL, NULL);
+
+ GSignondPluginDaemon *daemon = GSIGNOND_PLUGIN_DAEMON (g_object_new (
+ GSIGNOND_TYPE_PLUGIN_DAEMON, NULL));
+
+ /* Load plugin */
+ daemon->priv->plugin = gsignond_load_plugin_with_filename (
+ (gchar *)plugin_type, (gchar *)filename);
+ if (!daemon->priv->plugin) {
+ DBG ("failed to load plugin");
+ g_object_unref (daemon);
+ return NULL;
+ }
+
+ daemon->priv->plugin_type = g_strdup (plugin_type);
+
+ /* Create dbus connection */
+ stream = gsignond_pipe_stream_new (0, 1);
+ daemon->priv->connection = g_dbus_connection_new_sync (G_IO_STREAM (stream),
+ NULL, G_DBUS_CONNECTION_FLAGS_NONE, NULL, NULL, NULL);
+ g_object_unref (stream);
+
+ /* Create dbus object */
+ daemon->priv->dbus_remote_plugin =
+ gsignond_dbus_remote_plugin_skeleton_new ();
+
+ object_path = g_strdup_printf ("%s_%s", GSIGNOND_PLUGIN_OBJECTPATH,
+ daemon->priv->plugin_type);
+ g_dbus_interface_skeleton_export (
+ G_DBUS_INTERFACE_SKELETON(daemon->priv->dbus_remote_plugin),
+ daemon->priv->connection, object_path, &error);
+ if (error) {
+ DBG ("failed to register object: %s", error->message);
+ g_error_free (error);
+ g_free (object_path);
+ g_object_unref (daemon);
+ return NULL;
+ }
+ DBG("Started plugin daemon '%p' at path '%s' on conneciton '%p'",
+ daemon, object_path, daemon->priv->connection);
+ g_free (object_path);
+
+ /* Connect dbus remote plugin signals to handlers */
+ g_signal_connect_swapped (daemon->priv->dbus_remote_plugin,
+ "handle-cancel", G_CALLBACK (_handle_cancel_from_dbus), daemon);
+ g_signal_connect_swapped (daemon->priv->dbus_remote_plugin,
+ "handle-request", G_CALLBACK(_handle_request_from_dbus), daemon);
+ g_signal_connect_swapped (daemon->priv->dbus_remote_plugin,
+ "handle-request-initial",
+ G_CALLBACK(_handle_request_initial_from_dbus), daemon);
+ g_signal_connect_swapped (daemon->priv->dbus_remote_plugin,
+ "handle-user-action-finished",
+ G_CALLBACK(_handle_user_action_finished_from_dbus), daemon);
+ g_signal_connect_swapped (daemon->priv->dbus_remote_plugin,
+ "handle-refresh", G_CALLBACK(_handle_refresh_from_dbus), daemon);
+ g_signal_connect_swapped (daemon->priv->dbus_remote_plugin,
+ "handle-get-info", G_CALLBACK(_handle_get_info_from_dbus), daemon);
+
+ /* Connect plugin signals to handlers */
+ g_signal_connect_swapped (daemon->priv->plugin, "response",
+ G_CALLBACK (_handle_response_from_plugin), daemon);
+ g_signal_connect_swapped (daemon->priv->plugin, "response-final",
+ G_CALLBACK(_handle_response_final_from_plugin), daemon);
+ g_signal_connect_swapped (daemon->priv->plugin, "store",
+ G_CALLBACK(_handle_store_from_plugin), daemon);
+ g_signal_connect_swapped (daemon->priv->plugin, "error",
+ G_CALLBACK(_handle_error_from_plugin), daemon);
+ g_signal_connect_swapped (daemon->priv->plugin, "user-action-required",
+ G_CALLBACK(_handle_user_action_required_from_plugin), daemon);
+ g_signal_connect_swapped (daemon->priv->plugin, "refreshed",
+ G_CALLBACK(_handle_refreshed_from_plugin), daemon);
+ g_signal_connect_swapped (daemon->priv->plugin, "status-changed",
+ G_CALLBACK(_handle_status_changed_from_plugin), daemon);
+
+ g_signal_connect (daemon->priv->connection, "closed",
+ G_CALLBACK(_on_connection_closed), daemon);
+
+ return daemon;
+}
+
--- /dev/null
+/* vi: set et sw=4 ts=4 cino=t0,(0: */
+/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of gsignond
+ *
+ * Copyright (C) 2013 Intel Corporation.
+ *
+ * Contact: Imran Zaman <imran.zaman@intel.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#ifndef __GSIGNOND_PLUGIN_DAEMON_H_
+#define __GSIGNOND_PLUGIN_DAEMON_H_
+
+#include <glib.h>
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define GSIGNOND_TYPE_PLUGIN_DAEMON (gsignond_plugin_daemon_get_type())
+#define GSIGNOND_PLUGIN_DAEMON(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), \
+ GSIGNOND_TYPE_PLUGIN_DAEMON, GSignondPluginDaemon))
+#define GSIGNOND_PLUGIN_DAEMON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), \
+ GSIGNOND_TYPE_PLUGIN_DAEMON, GSignondPluginDaemonClass))
+#define GSIGNOND_IS_PLUGIN_DAEMON(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), \
+ GSIGNOND_TYPE_PLUGIN_DAEMON))
+#define GSIGNOND_IS_PLUGIN_DAEMON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),\
+ GSIGNOND_TYPE_PLUGIN_DAEMON))
+#define GSIGNOND_PLUGIN_DAEMON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj),\
+ GSIGNOND_TYPE_PLUGIN_DAEMON, GSignondPluginDaemonClass))
+
+typedef struct _GSignondPluginDaemon GSignondPluginDaemon;
+typedef struct _GSignondPluginDaemonClass GSignondPluginDaemonClass;
+typedef struct _GSignondPluginDaemonPrivate GSignondPluginDaemonPrivate;
+
+struct _GSignondPluginDaemon
+{
+ GObject parent;
+
+ /* priv */
+ GSignondPluginDaemonPrivate *priv;
+};
+
+struct _GSignondPluginDaemonClass
+{
+ GObjectClass parent_class;
+};
+
+GType gsignond_plugin_daemon_get_type();
+
+GSignondPluginDaemon *
+gsignond_plugin_daemon_new (
+ const gchar* filename,
+ const gchar* plugin_type);
+
+#endif /* __GSIGNOND_PLUGIN_DAEMON_H_ */
--- /dev/null
+/* vi: set et sw=4 ts=4 cino=t0,(0: */
+/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of gsignond
+ *
+ * Copyright (C) 2013 Intel Corporation.
+ *
+ * Contact: Imran Zaman <imran.zaman@intel.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#include <config.h>
+#include <errno.h>
+#include <signal.h>
+#include <string.h>
+#include <stdio.h>
+#include <glib-unix.h>
+#include <glib.h>
+#include <gio/gio.h>
+
+#include "gsignond/gsignond-log.h"
+#include "daemon/dbus/gsignond-dbus.h"
+#include "gsignond-plugin-daemon.h"
+
+static GSignondPluginDaemon *_daemon = NULL;
+static guint _sig_source_id[2];
+
+static void
+_on_daemon_closed (gpointer data, GObject *server)
+{
+ _daemon = NULL;
+ DBG ("Daemon closed");
+ if (data) g_main_loop_quit ((GMainLoop *)data);
+}
+
+static gboolean
+_handle_quit_signal (gpointer user_data)
+{
+ GMainLoop *ml = (GMainLoop *) user_data;
+
+ g_return_val_if_fail (ml != NULL, FALSE);
+ DBG ("Received quit signal");
+ if (ml) g_main_loop_quit (ml);
+
+ return FALSE;
+}
+
+static void
+_install_sighandlers (GMainLoop *main_loop)
+{
+ GSource *source = NULL;
+ GMainContext *ctx = g_main_loop_get_context (main_loop);
+
+ source = g_unix_signal_source_new (SIGTERM);
+ g_source_set_callback (source,
+ _handle_quit_signal,
+ main_loop,
+ NULL);
+ _sig_source_id[0] = g_source_attach (source, ctx);
+ source = g_unix_signal_source_new (SIGINT);
+ g_source_set_callback (source,
+ _handle_quit_signal,
+ main_loop,
+ NULL);
+ _sig_source_id[1] = g_source_attach (source, ctx);
+}
+
+static void
+_default_log_handler (
+ const gchar *log_domain,
+ GLogLevelFlags log_level,
+ const gchar *message,
+ gpointer unused_data)
+{
+ const gchar *strvect[16];
+ gchar *msg = NULL;
+ guint ind = 0;
+ if (log_domain) {
+ strvect[ind++] = log_domain;
+ strvect[ind++] = "-";
+ }
+ strvect[ind++] = "plugind";
+ if (log_level & G_LOG_LEVEL_ERROR)
+ strvect[ind++] = "-ERROR: ";
+ else if (log_level & G_LOG_LEVEL_CRITICAL)
+ strvect[ind++] = "-CRITICAL: ";
+ else if (log_level & G_LOG_LEVEL_WARNING)
+ strvect[ind++] = "-WARNING: ";
+ else if (log_level & G_LOG_LEVEL_MESSAGE)
+ strvect[ind++] = "-MESSAGE: ";
+ else if (log_level & G_LOG_LEVEL_INFO)
+ strvect[ind++] = "-INFO: ";
+ else if (log_level & G_LOG_LEVEL_DEBUG)
+ strvect[ind++] = "-DEBUG: ";
+ else
+ strvect[ind++] = ": ";
+ strvect[ind++] = message;
+ strvect[ind++] = NULL;
+
+ msg = g_strjoinv ("", (gchar**) strvect);
+ fprintf (stderr, "%s\n", msg);
+ fflush (stderr);
+ g_free (msg);
+}
+
+int main (int argc, char **argv)
+{
+ GError *error = NULL;
+ GMainLoop *main_loop = NULL;
+ GOptionContext *opt_context = NULL;
+ gchar **plugin_args = NULL;
+ GOptionEntry opt_entries[] = {
+ {G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &plugin_args,
+ "Plugin Args", NULL},
+ {NULL}
+ };
+
+ g_type_init ();
+
+ g_log_set_default_handler (_default_log_handler, NULL);
+
+ opt_context = g_option_context_new ("SSO plugin daemon");
+ g_option_context_add_main_entries (opt_context, opt_entries, NULL);
+ g_option_context_parse (opt_context, &argc, &argv, &error);
+ g_option_context_free (opt_context);
+ if (error) {
+ DBG ("Error parsing options: %s", error->message);
+ g_error_free (error);
+ if (plugin_args) g_strfreev(plugin_args);
+ return -1;
+ }
+
+ _daemon = gsignond_plugin_daemon_new (plugin_args[0], plugin_args[1]);
+ g_strfreev(plugin_args);
+ if (_daemon == NULL) {
+ DBG ("Error creating daemon object");
+ return -1;
+ }
+
+ main_loop = g_main_loop_new (NULL, FALSE);
+ g_object_weak_ref (G_OBJECT (_daemon), _on_daemon_closed, main_loop);
+ _install_sighandlers(main_loop);
+
+ DBG ("Entering main event loop");
+
+ g_main_loop_run (main_loop);
+
+ if(_daemon) {
+ g_object_unref (_daemon);
+ }
+
+ if (main_loop) {
+ g_main_loop_unref (main_loop);
+ }
+
+ return 0;
+}
}
static void
-gsignond_digest_plugin_abort (GSignondPlugin *self)
-{
-
-}
-
-static void
gsignond_digest_plugin_request (
GSignondPlugin *self,
GSignondSessionData *session_data)
gsignond_plugin_interface_init (GSignondPluginInterface *iface)
{
iface->cancel = gsignond_digest_plugin_cancel;
- iface->abort = gsignond_digest_plugin_abort;
iface->request_initial = gsignond_digest_plugin_request_initial;
iface->request = gsignond_digest_plugin_request;
iface->user_action_finished = gsignond_digest_plugin_user_action_finished;
g_error_free(error);
}
-static void gsignond_password_plugin_abort (GSignondPlugin *self)
-{
-
-}
-
static void gsignond_password_plugin_request (
GSignondPlugin *self, GSignondSessionData *session_data)
{
gsignond_plugin_interface_init (GSignondPluginInterface *iface)
{
iface->cancel = gsignond_password_plugin_cancel;
- iface->abort = gsignond_password_plugin_abort;
iface->request_initial = gsignond_password_plugin_request_initial;
iface->request = gsignond_password_plugin_request;
iface->user_action_finished = gsignond_password_plugin_user_action_finished;
self->priv->is_canceled = TRUE;
}
-static void gsignond_ssotest_plugin_abort (GSignondPlugin *plugin)
-{
- g_return_if_fail (GSIGNOND_IS_SSOTEST_PLUGIN (plugin));
-}
-
static void gsignond_ssotest_plugin_request_initial (
GSignondPlugin *plugin, GSignondSessionData *session_data,
const gchar *mechanism)
gsignond_plugin_status_changed (GSIGNOND_PLUGIN (self),
GSIGNOND_PLUGIN_STATE_WAITING,
"hello from the test plugin");
- INFO ("Signal is sent");
- g_usleep (1000 * 1000 / 10);
+ g_usleep (1000 * 1000 / 100);
g_main_context_iteration (NULL, FALSE);
}
}
gsignond_plugin_interface_init (GSignondPluginInterface *iface)
{
iface->cancel = gsignond_ssotest_plugin_cancel;
- iface->abort = gsignond_ssotest_plugin_abort;
iface->request_initial = gsignond_ssotest_plugin_request_initial;
iface->user_action_finished = gsignond_ssotest_plugin_user_action_finished;
iface->refresh = gsignond_ssotest_plugin_refresh;
pluginproxytest_CFLAGS = \
$(GSIGNOND_CFLAGS) \
$(CHECK_CFLAGS) \
+ -I$(top_srcdir)/src \
-I$(top_srcdir)/src/daemon/plugins \
- -I$(top_srcdir)/include/
+ -I$(top_srcdir)/include/
pluginproxytest_LDADD = \
$(top_builddir)/src/common/libgsignond-common.la \
$(CHECK_LIBS)
-
#include <check.h>
#include <stdlib.h>
#include <glib-object.h>
+
#include "gsignond-plugin-proxy.h"
#include "gsignond-plugin-proxy-factory.h"
+#include "gsignond-plugin-remote.h"
#include <gsignond/gsignond-plugin-loader.h>
#include <gsignond/gsignond-error.h>
#include <gsignond/gsignond-log.h>
+static GMainLoop *main_loop = NULL;
+
typedef struct _GSignondAuthSession GSignondAuthSession;
typedef struct _GSignondAuthSessionClass GSignondAuthSessionClass;
+static void
+_stop_mainloop ()
+{
+ if (main_loop) {
+ g_main_loop_quit (main_loop);
+ }
+}
+
+static void
+_start_mainloop ()
+{
+ g_main_loop_run (main_loop);
+}
+
+
+static void
+_setup ()
+{
+ g_type_init ();
+ if (main_loop == NULL) {
+ main_loop = g_main_loop_new (NULL, FALSE);
+ }
+}
+
+static void
+_teardown ()
+{
+ if (main_loop) {
+ _stop_mainloop ();
+ g_main_loop_unref (main_loop);
+ main_loop = NULL;
+ }
+}
+
struct _GSignondAuthSession
{
GObject parent;
GObjectClass parent_class;
};
-G_DEFINE_TYPE (GSignondAuthSession, gsignond_auth_session,
- G_TYPE_OBJECT);
+G_DEFINE_TYPE (GSignondAuthSession, gsignond_auth_session, G_TYPE_OBJECT);
static void
-gsignond_auth_session_init (GSignondAuthSession *self)
+gsignond_auth_session_init (
+ GSignondAuthSession *self)
{
}
static void
-gsignond_auth_session_class_init (GSignondAuthSessionClass *klass)
+gsignond_auth_session_class_init (
+ GSignondAuthSessionClass *klass)
{
// GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
-
}
-static void check_plugin_proxy(GSignondPluginProxy* proxy)
-{
- gchar* type;
- gchar** mechanisms;
-
- fail_if(proxy == NULL);
-
- g_object_get(proxy, "type", &type, "mechanisms", &mechanisms, NULL);
-
- fail_unless(g_strcmp0(type, "password") == 0);
- fail_unless(g_strcmp0(mechanisms[0], "password") == 0);
- fail_unless(mechanisms[1] == NULL);
-
- g_free(type);
- g_strfreev(mechanisms);
-}
-
-START_TEST (test_pluginproxy_create)
-{
- GSignondConfig* config = gsignond_config_new();
- fail_if(config == NULL);
-
- GSignondPluginProxy* proxy = gsignond_plugin_proxy_new(config, "password");
- fail_if (proxy == NULL);
- check_plugin_proxy(proxy);
-
- GSignondPluginProxy* proxy2 = gsignond_plugin_proxy_new(config, "absentplugin");
- fail_if (proxy2 != NULL);
-
- g_object_unref(proxy);
- g_object_unref(config);
-}
-END_TEST
-
gboolean testing_proxy_process = FALSE;
gboolean testing_proxy_process_cancel = FALSE;
gboolean testing_proxy_process_queue = FALSE;
gint proxy_process_queue_cancel_results = 0;
void
-gsignond_auth_session_notify_process_result (GSignondAuthSession *iface,
- GSignondSessionData *result,
- gpointer user_data)
+gsignond_auth_session_notify_process_result (
+ GSignondAuthSession *iface,
+ GSignondSessionData *result,
+ gpointer user_data)
{
int i;
-
+
+ DBG ("");
+
if (testing_proxy_process) {
testing_proxy_process = FALSE;
fail_if(g_strcmp0(
gsignond_session_data_get_username(result), "megauser") != 0);
fail_if(g_strcmp0(
gsignond_session_data_get_secret(result), "megapassword") != 0);
- } else if (testing_proxy_process_cancel) {
- GSignondPluginProxy* proxy = GSIGNOND_PLUGIN_PROXY(user_data);
- gsignond_plugin_proxy_cancel(proxy, iface);
+ _stop_mainloop ();
+
} else if (testing_proxy_process_queue) {
proxy_process_queue_results++;
if (proxy_process_queue_results == 1) {
gsignond_session_data_set_username(data, "megauser");
gsignond_session_data_set_secret(data, "megapassword");
- gsignond_plugin_proxy_process(proxy, iface, data, "password", proxy);
- gsignond_plugin_proxy_process(proxy, iface, data, "password", proxy);
+ gsignond_plugin_proxy_process(proxy, iface, data, "password",
+ proxy);
+
+ gsignond_plugin_proxy_process(proxy, iface, data, "password",
+ proxy);
gsignond_dictionary_unref(data);
}
if (proxy_process_queue_results == 3) {
testing_proxy_process_queue = FALSE;
+ _stop_mainloop ();
}
} else if (testing_proxy_process_queue_cancel) {
proxy_process_queue_cancel_results++;
GSignondPluginProxy* proxy = GSIGNOND_PLUGIN_PROXY(user_data);
GSignondSessionData* data = gsignond_dictionary_new();
fail_if(data == NULL);
- gsignond_session_data_set_username(data, "megauser");
- gsignond_session_data_set_secret(data, "megapassword");
- for (i = 0; i < 9; i++)
- gsignond_plugin_proxy_process(proxy, iface, data, "password", proxy);
-
+ for (i = 0; i < 9; i++) {
+ gsignond_plugin_proxy_process(proxy, iface, data, "mech1",
+ proxy);
+ }
gsignond_dictionary_unref(data);
}
- if (proxy_process_queue_cancel_results == 5) {
- GSignondPluginProxy* proxy = GSIGNOND_PLUGIN_PROXY(user_data);
- gsignond_plugin_proxy_cancel(proxy, iface);
- }
if (proxy_process_queue_cancel_results == 10) {
testing_proxy_process_queue_cancel = FALSE;
+ _stop_mainloop ();
}
} else
fail_if(TRUE);
void
gsignond_auth_session_notify_process_error (
- GSignondAuthSession *iface,
- const GError *error,
- gpointer user_data
- )
+ GSignondAuthSession *iface,
+ const GError *error,
+ gpointer user_data)
{
+ DBG ("");
+
if (testing_proxy_process_cancel) {
- fail_if(error->code != GSIGNOND_ERROR_WRONG_STATE);
+ fail_if(error->code != GSIGNOND_ERROR_SESSION_CANCELED);
testing_proxy_process_cancel = FALSE;
+ _stop_mainloop ();
} else if (testing_proxy_process_queue_cancel) {
- fail_if(error->code != GSIGNOND_ERROR_WRONG_STATE);
- } else
- fail_if(TRUE);
+ fail_if(error->code != GSIGNOND_ERROR_SESSION_CANCELED);
+ proxy_process_queue_cancel_results++;
+ }
+
}
void
-gsignond_auth_session_notify_store (GSignondAuthSession *self,
- GSignondSessionData *session_data)
+gsignond_auth_session_notify_store (
+ GSignondAuthSession *self,
+ GSignondSessionData *session_data)
{
+ DBG ("");
fail_if(TRUE);
}
void
-gsignond_auth_session_notify_user_action_required (GSignondAuthSession *self,
- GSignondSignonuiData *session_data
- )
+gsignond_auth_session_notify_user_action_required (
+ GSignondAuthSession *self,
+ GSignondSignonuiData *session_data)
{
+ DBG ("");
fail_if(TRUE);
}
void
-gsignond_auth_session_notify_refreshed (GSignondAuthSession *self,
- GSignondSignonuiData *session_data
- )
+gsignond_auth_session_notify_refreshed (
+ GSignondAuthSession *self,
+ GSignondSignonuiData *session_data)
{
+ DBG ("");
fail_if(TRUE);
}
void
-gsignond_auth_session_notify_state_changed (GSignondAuthSession *self,
- gint state,
- const gchar *message,
- gpointer user_data
- )
+gsignond_auth_session_notify_state_changed (
+ GSignondAuthSession *self,
+ gint state,
+ const gchar *message,
+ gpointer user_data)
+{
+ if (testing_proxy_process_cancel &&
+ state == GSIGNOND_PLUGIN_STATE_WAITING) {
+ GSignondPluginProxy* proxy = GSIGNOND_PLUGIN_PROXY(user_data);
+ gsignond_plugin_proxy_cancel(proxy, self);
+ } else if (testing_proxy_process_queue_cancel &&
+ state == GSIGNOND_PLUGIN_STATE_WAITING &&
+ proxy_process_queue_cancel_results == 5) {
+ GSignondPluginProxy* proxy = GSIGNOND_PLUGIN_PROXY(user_data);
+ gsignond_plugin_proxy_cancel(proxy, self);
+ }
+}
+
+static void
+check_plugin_proxy(
+ GSignondPluginProxy* proxy,
+ gchar *type,
+ gchar **mechanisms)
{
- INFO("AuthSession state changed %d %s", state, message);
+ gchar* ptype = NULL;
+ gchar** pmechanisms = NULL;
+
+ fail_if(proxy == NULL);
+
+ g_object_get(proxy, "type", &ptype, "mechanisms", &pmechanisms, NULL);
+ fail_unless(g_strcmp0(ptype, type) == 0);
+ if (pmechanisms == NULL) {
+ fail_unless (mechanisms[0] == NULL);
+ } else {
+ fail_unless(g_strcmp0(pmechanisms[0], mechanisms[0]) == 0);
+ fail_unless(pmechanisms[1] == NULL && mechanisms[1] == NULL);
+ }
+
+ g_free(ptype);
+ g_strfreev(pmechanisms);
}
+START_TEST (test_pluginproxy_create)
+{
+ DBG("test_pluginproxy_create\n");
+
+ gchar *pass_mechs[] = {"password", NULL};
+
+ GSignondConfig* config = gsignond_config_new();
+ fail_if(config == NULL);
+
+ GSignondPluginProxy* proxy2 = gsignond_plugin_proxy_new(config,
+ "absentplugin");
+ fail_if (proxy2 != NULL);
+
+ GSignondPluginProxy* proxy = gsignond_plugin_proxy_new(config, "password");
+ fail_if (proxy == NULL);
+ check_plugin_proxy(proxy, "password", pass_mechs);
+
+ g_object_unref(proxy);
+ g_object_unref(config);
+}
+END_TEST
+
START_TEST (test_pluginproxy_process)
{
+ DBG("test_pluginproxy_process\n");
+
GSignondConfig* config = gsignond_config_new();
fail_if(config == NULL);
gsignond_session_data_set_username(data, "megauser");
gsignond_session_data_set_secret(data, "megapassword");
- GSignondAuthSession* test_auth_session = g_object_new(gsignond_auth_session_get_type(), NULL);
+ GSignondAuthSession* test_auth_session =
+ g_object_new(gsignond_auth_session_get_type(), NULL);
testing_proxy_process = TRUE;
- gsignond_plugin_proxy_process(proxy, test_auth_session, data, "password", proxy);
+ gsignond_plugin_proxy_process(proxy, test_auth_session, data, "password",
+ proxy);
+
+ _start_mainloop ();
+
fail_if(testing_proxy_process);
gsignond_dictionary_unref(data);
START_TEST (test_pluginproxy_process_cancel)
{
+ DBG("test_pluginproxy_process_cancel\n");
+
GSignondConfig* config = gsignond_config_new();
fail_if(config == NULL);
- GSignondPluginProxy* proxy = gsignond_plugin_proxy_new(config, "password");
+ GSignondPluginProxy* proxy = gsignond_plugin_proxy_new(config, "ssotest");
fail_if (proxy == NULL);
GSignondSessionData* data = gsignond_dictionary_new();
fail_if(data == NULL);
- gsignond_session_data_set_username(data, "megauser");
- gsignond_session_data_set_secret(data, "megapassword");
- GSignondAuthSession* test_auth_session = g_object_new(gsignond_auth_session_get_type(), NULL);
+ GSignondAuthSession* test_auth_session = g_object_new(
+ gsignond_auth_session_get_type(), NULL);
testing_proxy_process_cancel = TRUE;
- gsignond_plugin_proxy_process(proxy, test_auth_session, data, "password", proxy);
+ gsignond_plugin_proxy_process(proxy, test_auth_session, data, "mech1",
+ proxy);
+
+ _start_mainloop ();
+
fail_if(testing_proxy_process_cancel);
gsignond_dictionary_unref(data);
START_TEST (test_pluginproxy_process_queue)
{
+ DBG("test_pluginproxy_process_queue\n");
+
GSignondConfig* config = gsignond_config_new();
fail_if(config == NULL);
gsignond_session_data_set_username(data, "megauser");
gsignond_session_data_set_secret(data, "megapassword");
- GSignondAuthSession* test_auth_session = g_object_new(gsignond_auth_session_get_type(), NULL);
+ GSignondAuthSession* test_auth_session = g_object_new(
+ gsignond_auth_session_get_type(), NULL);
testing_proxy_process_queue = TRUE;
- gsignond_plugin_proxy_process(proxy, test_auth_session, data, "password", proxy);
+ gsignond_plugin_proxy_process(proxy, test_auth_session, data, "password",
+ proxy);
+ _start_mainloop ();
+
fail_if(testing_proxy_process_queue);
fail_if(proxy_process_queue_results < 3);
GSignondConfig* config = gsignond_config_new();
fail_if(config == NULL);
- GSignondPluginProxy* proxy = gsignond_plugin_proxy_new(config, "password");
+ GSignondPluginProxy* proxy = gsignond_plugin_proxy_new(config, "ssotest");
fail_if (proxy == NULL);
GSignondSessionData* data = gsignond_dictionary_new();
fail_if(data == NULL);
- gsignond_session_data_set_username(data, "megauser");
- gsignond_session_data_set_secret(data, "megapassword");
- GSignondAuthSession* test_auth_session = g_object_new(gsignond_auth_session_get_type(), NULL);
+ GSignondAuthSession* test_auth_session = g_object_new(
+ gsignond_auth_session_get_type(), NULL);
testing_proxy_process_queue_cancel = TRUE;
- gsignond_plugin_proxy_process(proxy, test_auth_session, data, "password", proxy);
+ gsignond_plugin_proxy_process(proxy, test_auth_session, data, "mech1",
+ proxy);
+
+ _start_mainloop ();
+
fail_if(testing_proxy_process_queue_cancel);
fail_if(proxy_process_queue_cancel_results != 10);
START_TEST (test_pluginproxyfactory_methods_and_mechanisms)
{
+ DBG("");
GSignondConfig* config = gsignond_config_new();
fail_if(config == NULL);
- GSignondPluginProxyFactory* factory = gsignond_plugin_proxy_factory_new(config);
+ GSignondPluginProxyFactory* factory = gsignond_plugin_proxy_factory_new(
+ config);
fail_if(factory == NULL);
+ const gchar *pass_method = NULL;
+ const gchar** pmethods = NULL;
- const gchar** methods = gsignond_plugin_proxy_factory_get_plugin_types(factory);
+ const gchar** methods = gsignond_plugin_proxy_factory_get_plugin_types(
+ factory);
fail_if(methods == NULL);
- fail_if(strcmp(methods[0], "password") != 0);
- fail_if(methods[1] != NULL);
-
- const gchar** mechanisms = gsignond_plugin_proxy_factory_get_plugin_mechanisms(factory, methods[0]);
+ pmethods = methods;
+ while (pmethods[0] != NULL) {
+ DBG ("Method %s", pmethods[0]);
+ if (g_strcmp0 (pmethods[0], "password") == 0) {
+ pass_method = pmethods[0];
+ }
+ pmethods++;
+ }
+ const gchar** mechanisms =
+ gsignond_plugin_proxy_factory_get_plugin_mechanisms(factory,
+ pass_method);
fail_if(mechanisms == NULL);
fail_if(strcmp(mechanisms[0], "password") != 0);
fail_if(mechanisms[1] != NULL);
-
g_object_unref(factory);
g_object_unref(config);
}
START_TEST (test_pluginproxyfactory_get)
{
+ DBG("");
+ gchar *pass_mechs[] = {"password", NULL};
GSignondConfig* config = gsignond_config_new();
fail_if(config == NULL);
- GSignondPluginProxyFactory* factory = gsignond_plugin_proxy_factory_new(config);
+ GSignondPluginProxyFactory* factory = gsignond_plugin_proxy_factory_new(
+ config);
fail_if(factory == NULL);
- fail_if(gsignond_plugin_proxy_factory_get_plugin(factory, "absentplugin") != NULL);
+ fail_if(gsignond_plugin_proxy_factory_get_plugin(factory, "absentplugin")
+ != NULL);
GSignondPluginProxy* proxy1 = gsignond_plugin_proxy_factory_get_plugin(
factory, "password");
factory, "password");
fail_if(proxy1 == NULL || proxy2 == NULL || proxy3 == NULL);
fail_if(proxy1 != proxy3 || proxy1 != proxy2);
- check_plugin_proxy(proxy1);
+ check_plugin_proxy(proxy1, "password", pass_mechs);
g_object_unref(proxy1);
g_object_unref(proxy2);
START_TEST (test_pluginproxyfactory_add)
{
+ DBG("");
GSignondConfig* config = gsignond_config_new();
fail_if(config == NULL);
- GSignondPluginProxyFactory* factory = gsignond_plugin_proxy_factory_new(config);
+ GSignondPluginProxyFactory* factory = gsignond_plugin_proxy_factory_new(
+ config);
fail_if(factory == NULL);
GSignondPluginProxy* proxy = gsignond_plugin_proxy_new(config, "password");
fail_if (proxy == NULL);
fail_if(gsignond_plugin_proxy_factory_add_plugin(factory, proxy) == FALSE);
fail_if(gsignond_plugin_proxy_factory_add_plugin(factory, proxy) == TRUE);
- fail_if(gsignond_plugin_proxy_factory_get_plugin(factory, "password") != proxy);
+ fail_if(gsignond_plugin_proxy_factory_get_plugin(factory, "password")
+ != proxy);
g_object_unref(proxy);
g_object_unref(factory);
}
END_TEST
-
Suite* pluginproxy_suite (void)
{
Suite *s = suite_create ("Plugin proxy");
/* Core test case */
TCase *tc_core = tcase_create ("Tests");
+ tcase_add_checked_fixture (tc_core, _setup, _teardown);
+
tcase_add_test (tc_core, test_pluginproxy_create);
tcase_add_test (tc_core, test_pluginproxy_process);
tcase_add_test (tc_core, test_pluginproxy_process_cancel);
- //FIXME: we need an asynchronous or remote testing plugin to really test
- // cancellation and queueuing. Password plugin is totally synchronous.
tcase_add_test (tc_core, test_pluginproxy_process_queue);
tcase_add_test (tc_core, test_pluginproxy_process_queue_cancel);
tcase_add_test (tc_core, test_pluginproxyfactory_methods_and_mechanisms);
tcase_add_test (tc_core, test_pluginproxyfactory_get);
tcase_add_test (tc_core, test_pluginproxyfactory_add);
+
suite_add_tcase (s, tc_core);
return s;
}
{
int number_failed;
- g_type_init();
-
Suite *s = pluginproxy_suite();
SRunner *sr = srunner_create(s);
srunner_run_all(sr, CK_NORMAL);