daemon/dbus: security checks added for auth session
authorAmarnath Valluri <amarnath.valluri@linux.intel.com>
Thu, 7 Mar 2013 11:40:27 +0000 (13:40 +0200)
committerJussi Laako <jussi.laako@linux.intel.com>
Tue, 19 Mar 2013 14:17:58 +0000 (16:17 +0200)
src/daemon/dbus/gsignond-dbus-auth-session-adapter.c
src/daemon/gsignond-auth-session-iface.c
src/daemon/gsignond-auth-session-iface.h
src/daemon/gsignond-auth-session.c

index fcc714b..8595372 100644 (file)
@@ -31,6 +31,7 @@ enum
 {
     PROP_0,
     PROP_IMPL,
+    PROP_APP_CONTEXT,
     N_PROPERTIES
 };
 
@@ -39,7 +40,10 @@ static GParamSpec *properties[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;
@@ -50,6 +54,18 @@ G_DEFINE_TYPE (GSignondDbusAuthSessionAdapter, gsignond_dbus_auth_session_adapte
 
 #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);
@@ -78,6 +94,11 @@ gsignond_dbus_auth_session_adapter_set_property (GObject *object,
             }
             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);
     }
@@ -96,6 +117,9 @@ gsignond_dbus_auth_session_adapter_get_property (GObject *object,
             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);
     }
@@ -134,6 +158,11 @@ gsignond_dbus_auth_session_adapter_finalize (GObject *object)
         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));
 
@@ -156,6 +185,12 @@ gsignond_dbus_auth_session_adapter_class_init (GSignondDbusAuthSessionAdapterCla
                                                   "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);
 }
 
@@ -207,7 +242,10 @@ _handle_query_available_mechanisms (GSignondDbusAuthSessionAdapter *self,
     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);
@@ -285,7 +323,9 @@ _handle_process (GSignondDbusAuthSessionAdapter *self,
     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);
     
@@ -306,7 +346,9 @@ _handle_cancel (GSignondDbusAuthSessionAdapter *self,
     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);
@@ -329,4 +371,3 @@ gsignond_dbus_auth_session_adapter_new (GSignondAuthSessionIface *impl)
 {
     return g_object_new (GSIGNOND_TYPE_DBUS_AUTH_SESSION_ADAPTER, "auth-session-impl", impl, NULL);
 }
-
index d065001..11b9538 100644 (file)
@@ -126,27 +126,36 @@ gchar **
 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 
@@ -209,4 +218,3 @@ gsignond_auth_session_iface_notify_state_changed (GSignondAuthSessionIface *self
     g_signal_emit (self, signals[SIG_PROCESS_STATE_CHANGED], 0, state,
         message);
 }
-
index 625cf91..f06e990 100644 (file)
@@ -29,6 +29,8 @@
 #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
 
@@ -47,6 +49,7 @@ struct _GSignondAuthSessionIfaceInterface {
      * 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
@@ -58,6 +61,7 @@ struct _GSignondAuthSessionIfaceInterface {
      */
     gchar **   (*query_available_mechanisms) (GSignondAuthSessionIface *session,
                                               const gchar **desired_mechanisms,
+                                              const GSignondSecurityContext *ctx,
                                               GError **error);
 
     /**
@@ -65,6 +69,7 @@ struct _GSignondAuthSessionIfaceInterface {
      * @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.
@@ -75,17 +80,22 @@ struct _GSignondAuthSessionIfaceInterface {
     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);
 
@@ -99,14 +109,17 @@ GType gsignond_auth_session_iface_get_type (void);
 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, 
@@ -139,6 +152,9 @@ void
 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);
index 0d0993d..ef88e98 100644 (file)
@@ -38,6 +38,7 @@ enum
 {
        PROP_0,
        PROP_METHOD,
+    PROP_APP_CONTEXT,
        N_PROPERTIES
 };
 
@@ -63,6 +64,21 @@ G_DEFINE_TYPE_WITH_CODE (GSignondAuthSession, gsignond_auth_session,
     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)
 {
@@ -74,6 +90,7 @@ _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)) {
@@ -83,6 +100,8 @@ _query_available_mechanisms (GSignondAuthSessionIface *iface,
     }
     GSignondAuthSession *self = GSIGNOND_AUTH_SESSION (iface);
 
+    VALIDATE_READ_ACCESS (self->priv->identity_info, ctx, NULL);
+
     gchar **mechanisms, **iter;
     const gchar **src_iter;
 
@@ -118,8 +137,10 @@ _query_available_mechanisms (GSignondAuthSessionIface *iface,
 }
 
 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)) {
@@ -129,6 +150,8 @@ _process (GSignondAuthSessionIface *iface, GSignondSessionData *session_data,
     }
     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) {
@@ -146,7 +169,9 @@ _process (GSignondAuthSessionIface *iface, GSignondSessionData *session_data,
 }
 
 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");
@@ -155,6 +180,8 @@ _cancel (GSignondAuthSessionIface *iface, GError **error)
     }
     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;
@@ -178,6 +205,12 @@ _refresh (GSignondAuthSessionIface *iface,
     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)
@@ -189,6 +222,9 @@ _get_property (GObject *object, guint property_id, GValue *value,
         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);
     }
@@ -205,6 +241,9 @@ _set_property (GObject *object, guint property_id, const GValue *value,
         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);
     }
@@ -278,7 +317,16 @@ gsignond_auth_session_class_init (GSignondAuthSessionClass *klass)
                              "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);
 }
@@ -294,6 +342,7 @@ gsignond_auth_session_iface_init (gpointer g_iface)
     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;
 }
 
 /**
@@ -364,7 +413,10 @@ gsignond_auth_session_new (GSignondIdentityInfo *info, const gchar *app_context,
     }
 
     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);