LCOV - code coverage report
Current view: top level - pkcs11/gkm - gkm-store.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 89.3 % 149 133
Test Date: 2024-04-08 13:24:42 Functions: 89.5 % 19 17

            Line data    Source code
       1              : /*
       2              :  * gnome-keyring
       3              :  *
       4              :  * Copyright (C) 2008 Stefan Walter
       5              :  *
       6              :  * This program is free software; you can redistribute it and/or modify
       7              :  * it under the terms of the GNU Lesser General Public License as
       8              :  * published by the Free Software Foundation; either version 2.1 of
       9              :  * the License, or (at your option) any later version.
      10              :  *
      11              :  * This program is distributed in the hope that it will be useful, but
      12              :  * WITHOUT ANY WARRANTY; without even the implied warranty of
      13              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      14              :  * Lesser General Public License for more details.
      15              :  *
      16              :  * You should have received a copy of the GNU Lesser General Public
      17              :  * License along with this program; if not, see
      18              :  * <http://www.gnu.org/licenses/>.
      19              :  */
      20              : 
      21              : #include "config.h"
      22              : 
      23              : #include "gkm-attributes.h"
      24              : #define DEBUG_FLAG GKM_DEBUG_OBJECT
      25              : #include "gkm-debug.h"
      26              : #include "gkm-object.h"
      27              : #include "gkm-store.h"
      28              : #include "gkm-transaction.h"
      29              : #include "gkm-util.h"
      30              : 
      31              : typedef struct _Schema {
      32              :         CK_ATTRIBUTE_TYPE type;
      33              :         gpointer default_value;
      34              :         gsize default_length;
      35              :         GkmStoreValidator validator;
      36              :         guint flags;
      37              : } Schema;
      38              : 
      39              : struct _GkmStorePrivate {
      40              :         GHashTable *schemas;
      41              : };
      42              : 
      43         3867 : G_DEFINE_TYPE_WITH_PRIVATE (GkmStore, gkm_store, G_TYPE_OBJECT);
      44              : 
      45              : /* -----------------------------------------------------------------------------
      46              :  * INTERNAL
      47              :  */
      48              : 
      49              : static void
      50          591 : schema_free (gpointer data)
      51              : {
      52              :         Schema *schema;
      53              : 
      54          591 :         if (data == NULL)
      55            0 :                 return;
      56              : 
      57          591 :         schema = data;
      58          591 :         g_free (schema->default_value);
      59          591 :         g_slice_free (Schema, schema);
      60              : }
      61              : 
      62              : /* -----------------------------------------------------------------------------
      63              :  * OBJECT
      64              :  */
      65              : 
      66              : static GObject*
      67          557 : gkm_store_constructor (GType type, guint n_props, GObjectConstructParam *props)
      68              : {
      69          557 :         GkmStore *self = GKM_STORE (G_OBJECT_CLASS (gkm_store_parent_class)->constructor(type, n_props, props));
      70          557 :         g_return_val_if_fail (self, NULL);
      71              : 
      72          557 :         return G_OBJECT (self);
      73              : }
      74              : 
      75              : static void
      76          557 : gkm_store_init (GkmStore *self)
      77              : {
      78          557 :         self->pv = gkm_store_get_instance_private (self);
      79          557 :         self->pv->schemas = g_hash_table_new_full (gkm_util_ulong_hash, gkm_util_ulong_equal,
      80              :                                                    NULL, schema_free);
      81          557 : }
      82              : 
      83              : static void
      84          557 : gkm_store_dispose (GObject *obj)
      85              : {
      86          557 :         GkmStore *self = GKM_STORE (obj);
      87              : 
      88          557 :         g_hash_table_remove_all (self->pv->schemas);
      89              : 
      90          557 :         G_OBJECT_CLASS (gkm_store_parent_class)->dispose (obj);
      91          557 : }
      92              : 
      93              : static void
      94          557 : gkm_store_finalize (GObject *obj)
      95              : {
      96          557 :         GkmStore *self = GKM_STORE (obj);
      97              : 
      98          557 :         g_hash_table_destroy (self->pv->schemas);
      99              : 
     100          557 :         G_OBJECT_CLASS (gkm_store_parent_class)->finalize (obj);
     101          557 : }
     102              : 
     103              : static void
     104            0 : gkm_store_set_property (GObject *obj, guint prop_id, const GValue *value,
     105              :                            GParamSpec *pspec)
     106              : {
     107              :         switch (prop_id) {
     108              :         default:
     109            0 :                 G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
     110            0 :                 break;
     111              :         }
     112            0 : }
     113              : 
     114              : static void
     115            0 : gkm_store_get_property (GObject *obj, guint prop_id, GValue *value,
     116              :                            GParamSpec *pspec)
     117              : {
     118              :         switch (prop_id) {
     119              :         default:
     120            0 :                 G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
     121            0 :                 break;
     122              :         }
     123            0 : }
     124              : 
     125              : static void
     126           47 : gkm_store_class_init (GkmStoreClass *klass)
     127              : {
     128           47 :         GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
     129              : 
     130           47 :         gobject_class->constructor = gkm_store_constructor;
     131           47 :         gobject_class->dispose = gkm_store_dispose;
     132           47 :         gobject_class->finalize = gkm_store_finalize;
     133           47 :         gobject_class->set_property = gkm_store_set_property;
     134           47 :         gobject_class->get_property = gkm_store_get_property;
     135           47 : }
     136              : 
     137              : /* -----------------------------------------------------------------------------
     138              :  * PUBLIC
     139              :  */
     140              : 
     141              : gconstpointer
     142           14 : gkm_store_read_value (GkmStore *self, GkmObject *object,
     143              :                       CK_ATTRIBUTE_TYPE type, gsize *n_value)
     144              : {
     145              :         CK_ATTRIBUTE at;
     146              :         Schema *schema;
     147              :         CK_RV rv;
     148              : 
     149           14 :         g_return_val_if_fail (GKM_IS_STORE (self), NULL);
     150           14 :         g_return_val_if_fail (GKM_IS_OBJECT (object), NULL);
     151           14 :         g_return_val_if_fail (n_value, NULL);
     152              : 
     153           14 :         g_assert (GKM_STORE_GET_CLASS (self)->read_value);
     154              : 
     155           14 :         schema = g_hash_table_lookup (self->pv->schemas, &type);
     156           14 :         if (schema == NULL)
     157            0 :                 return NULL;
     158              : 
     159           14 :         at.type = type;
     160           14 :         at.pValue = NULL;
     161           14 :         at.ulValueLen = 0;
     162              : 
     163           14 :         rv = GKM_STORE_GET_CLASS (self)->read_value (self, object, &at);
     164           14 :         if (rv == CKR_ATTRIBUTE_TYPE_INVALID || rv == CKR_USER_NOT_LOGGED_IN) {
     165            4 :                 at.pValue = schema->default_value;
     166            4 :                 at.ulValueLen = schema->default_length;
     167           10 :         } else if (rv != CKR_OK) {
     168            0 :                 g_return_val_if_reached (NULL);
     169              :         }
     170              : 
     171           14 :         *n_value = at.ulValueLen;
     172           14 :         return at.pValue;
     173              : }
     174              : 
     175              : gchar*
     176            3 : gkm_store_read_string (GkmStore *self, GkmObject *object, CK_ATTRIBUTE_TYPE type)
     177              : {
     178              :         gconstpointer value;
     179              :         gsize n_value;
     180              : 
     181            3 :         g_return_val_if_fail (GKM_IS_STORE (self), NULL);
     182            3 :         g_return_val_if_fail (GKM_IS_OBJECT (object), NULL);
     183              : 
     184            3 :         value = gkm_store_read_value (self, object, type, &n_value);
     185            3 :         if (!value)
     186            0 :                 return NULL;
     187              : 
     188            3 :         return g_strndup (value, n_value);
     189              : }
     190              : 
     191              : CK_RV
     192          139 : gkm_store_get_attribute (GkmStore *self, GkmObject *object, CK_ATTRIBUTE_PTR attr)
     193              : {
     194              :         CK_ATTRIBUTE at;
     195              :         Schema *schema;
     196              :         CK_RV rv;
     197              : 
     198          139 :         g_return_val_if_fail (GKM_IS_STORE (self), CKR_GENERAL_ERROR);
     199          139 :         g_return_val_if_fail (GKM_IS_OBJECT (object), CKR_GENERAL_ERROR);
     200          139 :         g_return_val_if_fail (attr, CKR_GENERAL_ERROR);
     201              : 
     202          139 :         g_assert (GKM_STORE_GET_CLASS (self)->read_value);
     203              : 
     204          139 :         schema = g_hash_table_lookup (self->pv->schemas, &(attr->type));
     205          139 :         if (schema == NULL) {
     206          133 :                 gkm_debug ("CKR_ATTRIBUTE_TYPE_INVALID: %s not in schema",
     207              :                            gkm_log_attr_type (attr->type));
     208          133 :                 return CKR_ATTRIBUTE_TYPE_INVALID;
     209              :         }
     210              : 
     211            6 :         if (schema->flags & GKM_STORE_IS_INTERNAL) {
     212            1 :                 gkm_debug ("CKR_ATTRIBUTE_TYPE_INVALID: %s is an internal attribute",
     213              :                            gkm_log_attr_type (attr->type));
     214            1 :                 return CKR_ATTRIBUTE_TYPE_INVALID;
     215              :         }
     216              : 
     217            5 :         if (schema->flags & GKM_STORE_IS_SENSITIVE)
     218            1 :                 return CKR_ATTRIBUTE_SENSITIVE;
     219              : 
     220            4 :         at.type = attr->type;
     221            4 :         at.pValue = NULL;
     222            4 :         at.ulValueLen = 0;
     223              : 
     224            4 :         rv = GKM_STORE_GET_CLASS (self)->read_value (self, object, &at);
     225            4 :         if (rv == CKR_ATTRIBUTE_TYPE_INVALID) {
     226            3 :                 at.pValue = schema->default_value;
     227            3 :                 at.ulValueLen = schema->default_length;
     228            1 :         } else if (rv != CKR_OK) {
     229            0 :                 return rv;
     230              :         }
     231              : 
     232              :         /*
     233              :          * If we get an assert here, then the derived class is probably
     234              :          * trying to fill the  buffer in the attribute passed. It should
     235              :          * actually just be setting the pValue to its own buffers.
     236              :          */
     237            4 :         g_assert (at.pValue || !at.ulValueLen);
     238              : 
     239            4 :         return gkm_attribute_set_data (attr, at.pValue, at.ulValueLen);
     240              : }
     241              : 
     242              : void
     243            3 : gkm_store_write_value (GkmStore *self, GkmTransaction *transaction,
     244              :                        GkmObject *object, CK_ATTRIBUTE_PTR attr)
     245              : {
     246              :         Schema *schema;
     247              : 
     248            3 :         g_return_if_fail (GKM_IS_STORE (self));
     249            3 :         g_return_if_fail (GKM_IS_TRANSACTION (transaction));
     250            3 :         g_return_if_fail (GKM_IS_OBJECT (object));
     251            3 :         g_return_if_fail (attr);
     252              : 
     253            3 :         g_return_if_fail (!gkm_transaction_get_failed (transaction));
     254            3 :         g_assert (GKM_STORE_GET_CLASS (self)->write_value);
     255              : 
     256            3 :         schema = g_hash_table_lookup (self->pv->schemas, &(attr->type));
     257            3 :         if (schema == NULL) {
     258            0 :                 gkm_debug ("CKR_ATTRIBUTE_TYPE_INVALID: %s not in schema",
     259              :                            gkm_log_attr_type (attr->type));
     260            0 :                 gkm_transaction_fail (transaction, CKR_ATTRIBUTE_TYPE_INVALID);
     261            0 :                 return;
     262              :         }
     263              : 
     264            3 :         GKM_STORE_GET_CLASS (self)->write_value (self, transaction, object, attr);
     265              : }
     266              : 
     267              : void
     268           13 : gkm_store_set_attribute (GkmStore *self, GkmTransaction *transaction,
     269              :                          GkmObject *object, CK_ATTRIBUTE_PTR attr)
     270              : {
     271              :         Schema *schema;
     272           13 :         CK_RV rv = CKR_OK;
     273              : 
     274           13 :         g_return_if_fail (GKM_IS_STORE (self));
     275           13 :         g_return_if_fail (GKM_IS_TRANSACTION (transaction));
     276           13 :         g_return_if_fail (GKM_IS_OBJECT (object));
     277           13 :         g_return_if_fail (attr);
     278              : 
     279           13 :         g_return_if_fail (!gkm_transaction_get_failed (transaction));
     280           13 :         g_assert (GKM_STORE_GET_CLASS (self)->write_value);
     281              : 
     282           13 :         schema = g_hash_table_lookup (self->pv->schemas, &(attr->type));
     283           13 :         if (schema == NULL) {
     284            2 :                 gkm_debug ("CKR_ATTRIBUTE_TYPE_INVALID: %s not in schema",
     285              :                            gkm_log_attr_type (attr->type));
     286            2 :                 rv = CKR_ATTRIBUTE_TYPE_INVALID;
     287           11 :         } else if (schema->flags & GKM_STORE_IS_INTERNAL) {
     288            1 :                 gkm_debug ("CKR_ATTRIBUTE_TYPE_INVALID: %s is internal",
     289              :                            gkm_log_attr_type (attr->type));
     290            1 :                 rv = CKR_ATTRIBUTE_TYPE_INVALID;
     291           10 :         } else if (schema->validator) {
     292            8 :                 rv = (schema->validator) (object, attr);
     293              :         }
     294              : 
     295           13 :         if (rv != CKR_OK) {
     296            4 :                 gkm_transaction_fail (transaction, rv);
     297            4 :                 return;
     298              :         }
     299              : 
     300            9 :         GKM_STORE_GET_CLASS (self)->write_value (self, transaction, object, attr);
     301              : }
     302              : 
     303              : void
     304          591 : gkm_store_register_schema (GkmStore *self, CK_ATTRIBUTE_PTR attr,
     305              :                            GkmStoreValidator validator, guint flags)
     306              : {
     307              :         Schema *schema;
     308              : 
     309          591 :         g_return_if_fail (GKM_IS_STORE (self));
     310          591 :         g_return_if_fail (g_hash_table_lookup (self->pv->schemas, &(attr->type)) == NULL);
     311          591 :         g_return_if_fail (!attr->ulValueLen || attr->pValue);
     312          591 :         g_return_if_fail (attr->ulValueLen != (CK_ULONG)-1);
     313              : 
     314          591 :         schema = g_slice_new0 (Schema);
     315          591 :         schema->type = attr->type;
     316          591 :         schema->flags = flags;
     317          591 :         schema->validator = validator;
     318          591 :         schema->default_value = attr->pValue;
     319          591 :         schema->default_length = attr->ulValueLen;
     320          591 :         if (schema->default_value)
     321          571 :                 schema->default_value = g_memdup (schema->default_value,
     322          571 :                                                   schema->default_length);
     323              : 
     324          591 :         g_hash_table_insert (self->pv->schemas, &(schema->type), schema);
     325              : }
     326              : 
     327              : gboolean
     328           18 : gkm_store_lookup_schema (GkmStore *self, CK_ATTRIBUTE_TYPE type, guint *flags)
     329              : {
     330              :         Schema *schema;
     331              : 
     332           18 :         g_return_val_if_fail (GKM_IS_STORE (self), FALSE);
     333              : 
     334           18 :         schema = g_hash_table_lookup (self->pv->schemas, &type);
     335           18 :         if (!schema)
     336            1 :                 return FALSE;
     337           17 :         if (flags)
     338            1 :                 *flags = schema->flags;
     339           17 :         return TRUE;
     340              : }
        

Generated by: LCOV version 2.0-1