{
PROP_0,
PROP_IMPL,
+ PROP_APP_CONTEXT,
N_PROPERTIES
};
struct _GSignondDbusAuthSessionAdapterPrivate
{
GDBusConnection *connection;
+ gchar *app_context;
+ GSignondSecurityContext ctx;
GSignondAuthSessionIface *parent;
+ /* signal handlers */
guint state_changed_handler_id;
guint process_result_handler_id;
guint process_error_handler_id;
#define GSIGNOND_DBUS_AUTH_SESSION_ADAPTER_GET_PRIV(obj) G_TYPE_INSTANCE_GET_PRIVATE ((obj), GSIGNOND_TYPE_DBUS_AUTH_SESSION_ADAPTER, GSignondDbusAuthSessionAdapterPrivate)
+#define PREPARE_SECURITY_CONTEXT(dbus_object, invocation) \
+{ \
+ GSignondDbusAuthSessionAdapterPrivate *priv = dbus_object->priv; \
+ const gchar *sender = g_dbus_method_invocation_get_sender (invocation); \
+ GSignondAccessControlManager *acm = gsignond_auth_session_iface_get_acm (priv->parent); \
+ gsignond_access_control_manager_security_context_of_peer( \
+ acm, \
+ &priv->ctx, \
+ -1, \
+ sender, \
+ priv->app_context); \
+}
static void _handle_query_available_mechanisms (GSignondDbusAuthSessionAdapter *, GDBusMethodInvocation *, const gchar **, gpointer);
static void _handle_process (GSignondDbusAuthSessionAdapter *, GDBusMethodInvocation *, const GVariant *, const gchar *, gpointer);
static void _handle_cancel (GSignondDbusAuthSessionAdapter *, GDBusMethodInvocation *, gpointer);
}
break;
}
+ case PROP_APP_CONTEXT: {
+ if (self->priv->app_context) g_free (self->priv->app_context);
+ self->priv->app_context = g_strdup (g_value_get_string (value));
+ break;
+ }
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
g_value_set_pointer (value, self->priv->parent);
break;
}
+ case PROP_APP_CONTEXT:
+ g_value_set_string (value, self->priv->app_context);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
self->priv->parent = NULL;
}
+ if (self->priv->app_context) {
+ g_free (self->priv->app_context);
+ self->priv->app_context = NULL;
+ }
+
DBG("(-)'%s' object unexported", g_dbus_interface_skeleton_get_object_path (G_DBUS_INTERFACE_SKELETON(object)));
g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (object));
"Auth session impl",
"AuthSessionIface implementation object",
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
+ properties[PROP_APP_CONTEXT] = g_param_spec_string (
+ "app-context",
+ "application security context",
+ "Application security context of the identity object creater",
+ NULL,
+ G_PARAM_READWRITE);
g_object_class_install_properties (object_class, N_PROPERTIES, properties);
}
gchar **mechanisms = NULL;
GError *error = NULL;
- mechanisms = gsignond_auth_session_iface_query_available_mechanisms (self->priv->parent, wanted_mechanisms, &error);
+ PREPARE_SECURITY_CONTEXT (self, invocation);
+
+ mechanisms = gsignond_auth_session_iface_query_available_mechanisms (
+ self->priv->parent, wanted_mechanisms, &self->priv->ctx, &error);
if (mechanisms) {
gsignond_dbus_auth_session_complete_query_available_mechanisms (iface, invocation, (const gchar * const *)mechanisms);
self->priv->process_result_handler_id =
g_signal_connect (self->priv->parent, "process-result", G_CALLBACK (_on_process_result), info);
- if (!gsignond_auth_session_iface_process (self->priv->parent, data, mechanisms, &error)) {
+ PREPARE_SECURITY_CONTEXT (self, invocation);
+
+ if (!gsignond_auth_session_iface_process (self->priv->parent, data, mechanisms, &self->priv->ctx, &error)) {
g_dbus_method_invocation_return_gerror (invocation, error);
g_error_free (error);
GSignondDbusAuthSession *iface = GSIGNOND_DBUS_AUTH_SESSION (self);
GError *error = NULL;
- if (gsignond_auth_session_iface_cancel (self->priv->parent, &error))
+ PREPARE_SECURITY_CONTEXT (self, invocation);
+
+ if (gsignond_auth_session_iface_cancel (self->priv->parent, &self->priv->ctx, &error))
gsignond_dbus_auth_session_complete_cancel (iface, invocation);
else {
g_dbus_method_invocation_return_gerror (invocation, error);
{
return g_object_new (GSIGNOND_TYPE_DBUS_AUTH_SESSION_ADAPTER, "auth-session-impl", impl, NULL);
}
-
gsignond_auth_session_iface_query_available_mechanisms (
GSignondAuthSessionIface *self,
const gchar **wanted_mechanisms,
+ const GSignondSecurityContext *ctx,
GError **error)
{
return GSIGNOND_AUTH_SESSION_GET_INTERFACE (self)->
- query_available_mechanisms (self, wanted_mechanisms, error);
+ query_available_mechanisms (self, wanted_mechanisms, ctx, error);
}
gboolean
gsignond_auth_session_iface_process (GSignondAuthSessionIface *self,
GSignondSessionData *session_data,
const gchar *mechanism,
+ const GSignondSecurityContext *ctx,
GError **error)
{
return GSIGNOND_AUTH_SESSION_GET_INTERFACE (self)->
- process (self, session_data, mechanism, error);
+ process (self, session_data, mechanism, ctx, error);
}
gboolean
gsignond_auth_session_iface_cancel (GSignondAuthSessionIface *self,
+ const GSignondSecurityContext *ctx,
GError **error)
{
- return GSIGNOND_AUTH_SESSION_GET_INTERFACE (self)->cancel (self, error);
+ return GSIGNOND_AUTH_SESSION_GET_INTERFACE (self)->cancel (self, ctx, error);
+}
+
+GSignondAccessControlManager *
+gsignond_auth_session_iface_get_acm (GSignondAuthSessionIface *self)
+{
+ return GSIGNOND_AUTH_SESSION_GET_INTERFACE (self)->get_acm (self);
}
void
g_signal_emit (self, signals[SIG_PROCESS_STATE_CHANGED], 0, state,
message);
}
-
#include <glib.h>
#include <glib-object.h>
#include <gsignond/gsignond-session-data.h>
+#include <gsignond/gsignond-access-control-manager.h>
+#include <gsignond/gsignond-security-context.h>
G_BEGIN_DECLS
* query_available_mechanisms:
* @session: instance of #GSignondAuthSessionIface
* @desired_mechanisms: desired authentication mechanisms
+ * @ctx: security context of the caller
* @error: return location for error
*
* Checks for support of desired authentication mechanisms #desired_mechanisms for this
*/
gchar ** (*query_available_mechanisms) (GSignondAuthSessionIface *session,
const gchar **desired_mechanisms,
+ const GSignondSecurityContext *ctx,
GError **error);
/**
* @session: instance of #GSignondAuthSessionIface
* @session_data: authentication session data to use
* @mechansims: authentication mechanism to use
+ * @ctx: security context of the caller
* @error: return location for error
*
* Initiates authentication process on #session, On successful authentication #gsignond_auth_session_iface_notify_process_result will be called.
gboolean (*process) (GSignondAuthSessionIface *session,
GSignondSessionData *session_data,
const gchar *mechanism,
+ const GSignondSecurityContext *ctx,
GError **error);
/**
* cancel:
* @session: instance of #GSignondAuthSessionIface
+ * @ctx: security context of the caller
* @error: return location for error
*
*/
gboolean (*cancel) (GSignondAuthSessionIface *session,
+ const GSignondSecurityContext *ctx,
GError **error);
+ GSignondAccessControlManager * (*get_acm) (GSignondAuthSessionIface *session);
+
void (*user_action_finished) (GSignondAuthSessionIface *session,
GSignondSessionData *session_data);
gchar **
gsignond_auth_session_iface_query_available_mechanisms (GSignondAuthSessionIface *self,
const gchar **wanted_mechanisms,
+ const GSignondSecurityContext *ctx,
GError **error);
gboolean
gsignond_auth_session_iface_process (GSignondAuthSessionIface *self,
GSignondSessionData *session_data,
const gchar *mechanism,
+ const GSignondSecurityContext *ctx,
GError **error);
gboolean
gsignond_auth_session_iface_cancel (GSignondAuthSessionIface *self,
+ const GSignondSecurityContext *ctx,
GError **error);
void
gsignond_auth_session_iface_user_action_finished (GSignondAuthSessionIface *self,
gsignond_auth_session_iface_notify_process_error (GSignondAuthSessionIface *iface,
const GError *error);
+GSignondAccessControlManager *
+gsignond_auth_session_iface_get_acm (GSignondAuthSessionIface *self);
+
void
gsignond_auth_session_iface_notify_store (GSignondAuthSessionIface *self,
GSignondSessionData *session_data);
{
PROP_0,
PROP_METHOD,
+ PROP_APP_CONTEXT,
N_PROPERTIES
};
G_TYPE_INSTANCE_GET_PRIVATE ((obj), GSIGNOND_TYPE_AUTH_SESSION, \
GSignondAuthSessionPrivate)
+#define VALIDATE_READ_ACCESS(info, ctx, ret) \
+{ \
+ GSignondAccessControlManager *acm = gsignond_get_access_control_manager(); \
+ GSignondSecurityContextList *acl = gsignond_identity_info_get_access_control_list (info); \
+ gboolean valid = gsignond_access_control_manager_peer_is_allowed_to_use_identity (acm, ctx, acl); \
+ gsignond_security_context_list_free (acl); \
+ if (!valid) { \
+ WARN ("security check failed"); \
+ if (error) { \
+ *error = gsignond_get_gerror_for_id (GSIGNOND_ERROR_PERMISSION_DENIED, "Can not access identity"); \
+ } \
+ return ret; \
+ } \
+}
+
static gint
_sort_cmp (gconstpointer str1, gconstpointer str2, gpointer user_data)
{
static gchar **
_query_available_mechanisms (GSignondAuthSessionIface *iface,
const gchar **wanted_mechanisms,
+ const GSignondSecurityContext *ctx,
GError **error)
{
if (!iface || !GSIGNOND_IS_AUTH_SESSION (iface)) {
}
GSignondAuthSession *self = GSIGNOND_AUTH_SESSION (iface);
+ VALIDATE_READ_ACCESS (self->priv->identity_info, ctx, NULL);
+
gchar **mechanisms, **iter;
const gchar **src_iter;
}
static gboolean
-_process (GSignondAuthSessionIface *iface, GSignondSessionData *session_data,
+_process (GSignondAuthSessionIface *iface,
+ GSignondSessionData *session_data,
const gchar *mechanism,
+ const GSignondSecurityContext *ctx,
GError **error)
{
if (G_LIKELY ((iface && GSIGNOND_IS_AUTH_SESSION (iface)) == 0)) {
}
GSignondAuthSession *self = GSIGNOND_AUTH_SESSION (iface);
+ VALIDATE_READ_ACCESS (self->priv->identity_info, ctx, FALSE);
+
if (session_data &&
!gsignond_session_data_get_username (session_data)
&& self->priv->identity_info) {
}
static gboolean
-_cancel (GSignondAuthSessionIface *iface, GError **error)
+_cancel (GSignondAuthSessionIface *iface,
+ const GSignondSecurityContext *ctx,
+ GError **error)
{
if (G_LIKELY ((iface && GSIGNOND_IS_AUTH_SESSION (iface)) == 0)) {
WARN ("assertion G_LIKELY ((iface && GSIGNOND_IS_AUTH_SESSION (iface)) == 0) failed");
}
GSignondAuthSession *self = GSIGNOND_AUTH_SESSION (iface);
+ VALIDATE_READ_ACCESS (self->priv->identity_info, ctx, FALSE);
+
gsignond_plugin_proxy_cancel(self->priv->proxy, iface);
return TRUE;
gsignond_plugin_proxy_refresh(self->priv->proxy, session_data);
}
+GSignondAccessControlManager *
+_get_acm (GSignondAuthSessionIface *iface)
+{
+ return gsignond_get_access_control_manager ();
+}
+
static void
_get_property (GObject *object, guint property_id, GValue *value,
GParamSpec *pspec)
case PROP_METHOD:
g_value_set_string (value, self->priv->method);
break;
+ case PROP_APP_CONTEXT:
+ g_object_get_property (G_OBJECT (self->priv->session_adapter), "app-context", value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
case PROP_METHOD:
self->priv->method = g_value_dup_string (value);
break;
+ case PROP_APP_CONTEXT:
+ g_object_set_property (G_OBJECT (self->priv->session_adapter), "app-context", value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
"authentication method",
"Authentication method used",
NULL,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY
+ | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB);
+
+ properties[PROP_APP_CONTEXT] =
+ g_param_spec_string ("app-context",
+ "application security context",
+ "Application security context",
+ NULL,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY
+ | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB);
g_object_class_install_properties (object_class, N_PROPERTIES, properties);
}
auth_session_iface->cancel = _cancel;
auth_session_iface->user_action_finished = _user_action_finished;
auth_session_iface->refresh = _refresh;
+ auth_session_iface->get_acm = _get_acm;
}
/**
}
GSignondAuthSession *auth_session =
- g_object_new (GSIGNOND_TYPE_AUTH_SESSION, "method", method, "timeout", timeout, NULL);
+ g_object_new (GSIGNOND_TYPE_AUTH_SESSION, "method", method,
+ "app-context", app_context,
+ "timeout", timeout,
+ NULL);
auth_session->priv->proxy = proxy;
auth_session->priv->identity_info = g_hash_table_ref ((GHashTable *)info);