daemon: add access checks for QueryIdentities/Clear
authorJussi Laako <jussi.laako@linux.intel.com>
Tue, 30 Apr 2013 11:57:06 +0000 (14:57 +0300)
committerJussi Laako <jussi.laako@linux.intel.com>
Thu, 2 May 2013 12:55:37 +0000 (15:55 +0300)
tizen: fix access control manager

src/daemon/dbus/gsignond-dbus-auth-service-adapter.c
src/daemon/gsignond-daemon.c
src/daemon/gsignond-daemon.h
src/extensions/tizen/tizen-access-control-manager.c

index b82df81..2138933 100644 (file)
@@ -464,8 +464,30 @@ _handle_query_identities (GSignondDbusAuthServiceAdapter *self,
 {
     GList *identities = NULL;
     GError *error = NULL;
+    GSignondSecurityContext *sec_context;
+    const gchar *sender =  NULL;
+    int fd = -1;
+
+#ifdef USE_P2P
+    GDBusConnection *connection = NULL;
+    connection = g_dbus_method_invocation_get_connection (invocation);
+    fd = g_socket_get_fd (g_socket_connection_get_socket (G_SOCKET_CONNECTION (g_dbus_connection_get_stream(connection))));
+#else
+    sender = g_dbus_method_invocation_get_sender (invocation);
+#endif
+    sec_context = gsignond_security_context_new ();
+    gsignond_access_control_manager_security_context_of_peer(
+            gsignond_daemon_get_access_control_manager (self->priv->auth_service),
+            sec_context,
+            fd,
+            sender, "");
 
-    identities = gsignond_daemon_query_identities (self->priv->auth_service, filter, &error);
+    identities = gsignond_daemon_query_identities (self->priv->auth_service,
+                                                   filter,
+                                                   sec_context,
+                                                   &error);
+
+    gsignond_security_context_free (sec_context);
 
     if (identities) {
         GVariantBuilder builder;
@@ -499,8 +521,29 @@ _handle_clear (GSignondDbusAuthServiceAdapter *self,
 {
     gboolean res ;
     GError *error = NULL;
+    GSignondSecurityContext *sec_context;
+    const gchar *sender =  NULL;
+    int fd = -1;
+
+#ifdef USE_P2P
+    GDBusConnection *connection = NULL;
+    connection = g_dbus_method_invocation_get_connection (invocation);
+    fd = g_socket_get_fd (g_socket_connection_get_socket (G_SOCKET_CONNECTION (g_dbus_connection_get_stream(connection))));
+#else
+    sender = g_dbus_method_invocation_get_sender (invocation);
+#endif
+    sec_context = gsignond_security_context_new ();
+    gsignond_access_control_manager_security_context_of_peer(
+            gsignond_daemon_get_access_control_manager (self->priv->auth_service),
+            sec_context,
+            fd,
+            sender, "");
 
-    res = gsignond_daemon_clear (self->priv->auth_service, &error);
+    res = gsignond_daemon_clear (self->priv->auth_service,
+                                 sec_context,
+                                 &error);
+
+    gsignond_security_context_free (sec_context);
 
     if (!error)
         gsignond_dbus_auth_service_complete_clear (self->priv->dbus_auth_service, invocation, res);
index 17d796c..a0ce94e 100644 (file)
@@ -526,14 +526,43 @@ gsignond_daemon_query_mechanisms (GSignondDaemon *daemon, const gchar *method, G
     return mechanisms;
 }
 
+static gboolean
+_check_keychain_access (GSignondDaemon *self,
+                        const GSignondSecurityContext *ctx,
+                        GError **error)
+{
+    GSignondAccessControlManager *acm = self->priv->acm;
+    GSignondSecurityContext *keychain =
+        gsignond_access_control_manager_security_context_of_keychain (acm);
+    gboolean has_access =
+        (gsignond_security_context_compare (keychain, ctx) == 0);
+    gsignond_security_context_free (keychain);
+    if (!has_access) {
+        WARN ("keychain access check failed");
+        if (error) {
+            *error = gsignond_get_gerror_for_id (
+                                    GSIGNOND_ERROR_PERMISSION_DENIED,
+                                    "Can not access keychain functionality");
+        }
+    }
+    return has_access;
+}
+
 GList *
-gsignond_daemon_query_identities (GSignondDaemon *self, GVariant *filter, GError **error)
+gsignond_daemon_query_identities (GSignondDaemon *self,
+                                  GVariant *filter,
+                                  const GSignondSecurityContext *ctx,
+                                  GError **error)
 {
     if (!self || !GSIGNOND_IS_DAEMON (self)) {
         WARN ("assertion (self && GSIGNOND_IS_DAEMON(self)) failed");
         if (error) *error = gsignond_get_gerror_for_id (GSIGNOND_ERROR_UNKNOWN, "Unknown error");
         return NULL;
     }
+
+    if (!_check_keychain_access (self, ctx, error))
+        return FALSE;
+
     (void)filter;
 
     if (error) *error = gsignond_get_gerror_for_id (GSIGNOND_ERROR_UNKNOWN, "Not supported");
@@ -542,7 +571,9 @@ gsignond_daemon_query_identities (GSignondDaemon *self, GVariant *filter, GError
 }
 
 gboolean 
-gsignond_daemon_clear (GSignondDaemon *self, GError **error)
+gsignond_daemon_clear (GSignondDaemon *self,
+                       const GSignondSecurityContext *ctx,
+                       GError **error)
 {
     if (!self || !GSIGNOND_IS_DAEMON (self)) {
         WARN ("assertion (self && GSIGNOND_IS_DAEMON(self)) failed");
@@ -550,6 +581,9 @@ gsignond_daemon_clear (GSignondDaemon *self, GError **error)
         return FALSE;
     }
 
+    if (!_check_keychain_access (self, ctx, error))
+        return FALSE;
+
     gboolean retval = TRUE;
     GSignondDaemonPrivate *priv = self->priv;
 
index bd80eab..a3aff37 100644 (file)
@@ -85,10 +85,13 @@ gsignond_daemon_query_mechanisms (GSignondDaemon *daemon,
 GList *
 gsignond_daemon_query_identities (GSignondDaemon *daemon,
                                   GVariant *filter,
+                                  const GSignondSecurityContext *ctx,
                                   GError **error);
 
 gboolean 
-gsignond_daemon_clear (GSignondDaemon *daemon, GError **error);
+gsignond_daemon_clear (GSignondDaemon *daemon,
+                       const GSignondSecurityContext *ctx,
+                       GError **error);
 
 guint32
 gsignond_daemon_store_identity (GSignondDaemon *daemon, GSignondIdentity *identity);
index 2abd31e..f47808c 100644 (file)
@@ -92,7 +92,10 @@ extension_tizen_access_control_manager_security_context_of_peer (
         smack_new_label_from_socket(peer_fd, &label);
         if (label) 
         {
-            peer_ctx = gsignond_security_context_new_from_values ((const gchar*)label, peer_app_ctx);
+            gsignond_security_context_set_system_context (peer_ctx,
+                                                          (const gchar *) label);
+            gsignond_security_context_set_application_context (peer_ctx,
+                                                               peer_app_ctx);
         }
         
         return;
@@ -144,9 +147,13 @@ extension_tizen_access_control_manager_security_context_of_peer (
         g_variant_get (response, "s", &label);
         g_print ("Obtained label from dbus: %s\n", label);
         
-        if (label)
-            peer_ctx = gsignond_security_context_new_from_values ((const gchar*)label, peer_app_ctx);
-            
+        if (label) {
+            gsignond_security_context_set_system_context (peer_ctx,
+                                                          (const gchar *) label);
+            gsignond_security_context_set_application_context (peer_ctx,
+                                                               peer_app_ctx);
+        }
+
         g_object_unref (proxy);
         return;
     } 
@@ -187,7 +194,7 @@ extension_tizen_access_control_manager_peer_is_owner_of_identity (
 {
     (void) self;
 
-    return gsignond_security_context_compare(peer_ctx, identity_owner);
+    return (gsignond_security_context_compare(peer_ctx, identity_owner) == 0);
 }
 
 GSignondSecurityContext *