LCOV - code coverage report
Current view: top level - gcr - gcr-gnupg-importer.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 159 0.0 %
Date: 2022-09-04 10:20:22 Functions: 0 22 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 77 0.0 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * gnome-keyring
       3                 :            :  *
       4                 :            :  * Copyright (C) 2011 Collabora Ltd.
       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 <http://www.gnu.org/licenses/>.
      18                 :            :  *
      19                 :            :  * Author: Stef Walter <stefw@collabora.co.uk>
      20                 :            :  */
      21                 :            : 
      22                 :            : #include "config.h"
      23                 :            : 
      24                 :            : #include "gcr-gnupg-importer.h"
      25                 :            : #include "gcr-gnupg-process.h"
      26                 :            : #include "gcr-internal.h"
      27                 :            : 
      28                 :            : #include <glib/gi18n-lib.h>
      29                 :            : 
      30                 :            : enum {
      31                 :            :         PROP_0,
      32                 :            :         PROP_LABEL,
      33                 :            :         PROP_IMPORTED,
      34                 :            :         PROP_DIRECTORY,
      35                 :            :         PROP_INTERACTION,
      36                 :            :         PROP_URI
      37                 :            : };
      38                 :            : 
      39                 :            : struct _GcrGnupgImporterPrivate {
      40                 :            :         GcrGnupgProcess *process;
      41                 :            :         GMemoryInputStream *packets;
      42                 :            :         GTlsInteraction *interaction;
      43                 :            :         gchar *first_error;
      44                 :            :         GArray *imported;
      45                 :            : };
      46                 :            : 
      47                 :            : static void gcr_gnupg_importer_iface (GcrImporterInterface *iface);
      48                 :            : 
      49   [ #  #  #  #  :          0 : G_DEFINE_TYPE_WITH_CODE (GcrGnupgImporter, _gcr_gnupg_importer, G_TYPE_OBJECT,
                   #  # ]
      50                 :            :                          G_ADD_PRIVATE (GcrGnupgImporter);
      51                 :            :                          G_IMPLEMENT_INTERFACE (GCR_TYPE_IMPORTER, gcr_gnupg_importer_iface);
      52                 :            : );
      53                 :            : 
      54                 :            : static void
      55                 :          0 : _gcr_gnupg_importer_init (GcrGnupgImporter *self)
      56                 :            : {
      57                 :          0 :         self->pv = _gcr_gnupg_importer_get_instance_private (self);
      58                 :          0 :         self->pv->packets = G_MEMORY_INPUT_STREAM (g_memory_input_stream_new ());
      59                 :          0 :         self->pv->imported = g_array_new (TRUE, TRUE, sizeof (gchar *));
      60                 :          0 : }
      61                 :            : 
      62                 :            : static void
      63                 :          0 : _gcr_gnupg_importer_dispose (GObject *obj)
      64                 :            : {
      65                 :          0 :         GcrGnupgImporter *self = GCR_GNUPG_IMPORTER (obj);
      66                 :            : 
      67         [ #  # ]:          0 :         if (self->pv->process)
      68                 :          0 :                 g_object_run_dispose (G_OBJECT (self->pv->process));
      69         [ #  # ]:          0 :         g_clear_object (&self->pv->process);
      70         [ #  # ]:          0 :         g_clear_object (&self->pv->packets);
      71         [ #  # ]:          0 :         g_clear_object (&self->pv->interaction);
      72                 :            : 
      73                 :          0 :         G_OBJECT_CLASS (_gcr_gnupg_importer_parent_class)->dispose (obj);
      74                 :          0 : }
      75                 :            : 
      76                 :            : static void
      77                 :          0 : _gcr_gnupg_importer_finalize (GObject *obj)
      78                 :            : {
      79                 :          0 :         GcrGnupgImporter *self = GCR_GNUPG_IMPORTER (obj);
      80                 :            : 
      81                 :          0 :         g_array_free (self->pv->imported, TRUE);
      82                 :          0 :         g_free (self->pv->first_error);
      83                 :            : 
      84                 :          0 :         G_OBJECT_CLASS (_gcr_gnupg_importer_parent_class)->finalize (obj);
      85                 :          0 : }
      86                 :            : 
      87                 :            : static gchar *
      88                 :          0 : calculate_label (GcrGnupgImporter *self)
      89                 :            : {
      90                 :            :         const gchar *directory;
      91                 :            : 
      92                 :          0 :         directory = _gcr_gnupg_process_get_directory (self->pv->process);
      93         [ #  # ]:          0 :         if (directory == NULL)
      94                 :          0 :                 return g_strdup (_("GnuPG Keyring"));
      95                 :            :         else
      96                 :          0 :                 return g_strdup_printf (_("GnuPG Keyring: %s"), directory);
      97                 :            : }
      98                 :            : 
      99                 :            : static gchar *
     100                 :          0 : calculate_uri (GcrGnupgImporter *self)
     101                 :            : {
     102                 :            :         const gchar *directory;
     103                 :            : 
     104                 :          0 :         directory = _gcr_gnupg_process_get_directory (self->pv->process);
     105         [ #  # ]:          0 :         if (directory == NULL)
     106                 :          0 :                 return g_strdup ("gnupg://");
     107                 :            :         else
     108                 :          0 :                 return g_strdup_printf ("gnupg://%s", directory);
     109                 :            : }
     110                 :            : 
     111                 :            : static gboolean
     112                 :          0 : on_process_error_line (GcrGnupgProcess *process,
     113                 :            :                        const gchar *line,
     114                 :            :                        gpointer user_data)
     115                 :            : {
     116                 :          0 :         GcrGnupgImporter *self = GCR_GNUPG_IMPORTER (user_data);
     117                 :            : 
     118         [ #  # ]:          0 :         if (self->pv->first_error)
     119                 :          0 :                 return TRUE;
     120                 :            : 
     121         [ #  # ]:          0 :         if (g_str_has_prefix (line, "gpg: ")) {
     122                 :          0 :                 line += 5;
     123         [ #  # ]:          0 :                 if (g_pattern_match_simple ("key ????????:*", line))
     124                 :          0 :                         line += 13;
     125                 :            :         }
     126                 :            : 
     127   [ #  #  #  # ]:          0 :         while (line[0] && g_ascii_isspace (line[0]))
     128                 :          0 :                 line++;
     129                 :            : 
     130                 :          0 :         self->pv->first_error = g_strdup (line);
     131                 :          0 :         g_strstrip (self->pv->first_error);
     132                 :          0 :         return TRUE;
     133                 :            : }
     134                 :            : 
     135                 :            : static gboolean
     136                 :          0 : on_process_status_record (GcrGnupgProcess *process,
     137                 :            :                           GcrRecord *record,
     138                 :            :                           gpointer user_data)
     139                 :            : {
     140                 :          0 :         GcrGnupgImporter *self = GCR_GNUPG_IMPORTER (user_data);
     141                 :            :         const gchar *value;
     142                 :            :         gchar *fingerprint;
     143                 :            : 
     144         [ #  # ]:          0 :         if (_gcr_record_get_schema (record) != GCR_RECORD_SCHEMA_IMPORT_OK)
     145                 :          0 :                 return TRUE;
     146                 :            : 
     147                 :          0 :         value = _gcr_record_get_raw (record, GCR_RECORD_IMPORT_FINGERPRINT);
     148   [ #  #  #  # ]:          0 :         if (value != NULL && value[0] != 0) {
     149                 :          0 :                 fingerprint = g_strdup (value);
     150                 :          0 :                 g_array_append_val (self->pv->imported, fingerprint);
     151                 :            :         }
     152                 :            : 
     153                 :          0 :         return TRUE;
     154                 :            : }
     155                 :            : 
     156                 :            : static void
     157                 :          0 : _gcr_gnupg_importer_set_property (GObject *obj,
     158                 :            :                                   guint prop_id,
     159                 :            :                                   const GValue *value,
     160                 :            :                                   GParamSpec *pspec)
     161                 :            : {
     162                 :          0 :         GcrGnupgImporter *self = GCR_GNUPG_IMPORTER (obj);
     163                 :            : 
     164      [ #  #  # ]:          0 :         switch (prop_id) {
     165                 :          0 :         case PROP_DIRECTORY:
     166                 :          0 :                 self->pv->process = _gcr_gnupg_process_new (g_value_get_string (value), NULL);
     167                 :          0 :                 _gcr_gnupg_process_set_input_stream (self->pv->process, G_INPUT_STREAM (self->pv->packets));
     168                 :          0 :                 g_signal_connect (self->pv->process, "error-line", G_CALLBACK (on_process_error_line), self);
     169                 :          0 :                 g_signal_connect (self->pv->process, "status-record", G_CALLBACK (on_process_status_record), self);
     170                 :          0 :                 break;
     171                 :          0 :         case PROP_INTERACTION:
     172         [ #  # ]:          0 :                 g_clear_object (&self->pv->interaction);
     173                 :          0 :                 self->pv->interaction = g_value_dup_object (value);
     174                 :          0 :                 break;
     175                 :          0 :         default:
     176                 :          0 :                 G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
     177                 :          0 :                 break;
     178                 :            :         }
     179                 :          0 : }
     180                 :            : 
     181                 :            : static void
     182                 :          0 : _gcr_gnupg_importer_get_property (GObject *obj,
     183                 :            :                                   guint prop_id,
     184                 :            :                                   GValue *value,
     185                 :            :                                   GParamSpec *pspec)
     186                 :            : {
     187                 :          0 :         GcrGnupgImporter *self = GCR_GNUPG_IMPORTER (obj);
     188                 :            : 
     189   [ #  #  #  #  :          0 :         switch (prop_id) {
                   #  # ]
     190                 :          0 :         case PROP_LABEL:
     191                 :          0 :                 g_value_take_string (value, calculate_label (self));
     192                 :          0 :                 break;
     193                 :          0 :         case PROP_IMPORTED:
     194                 :          0 :                 g_value_set_boxed (value, _gcr_gnupg_importer_get_imported (self));
     195                 :          0 :                 break;
     196                 :          0 :         case PROP_DIRECTORY:
     197                 :          0 :                 g_value_set_string (value, _gcr_gnupg_process_get_directory (self->pv->process));
     198                 :          0 :                 break;
     199                 :          0 :         case PROP_INTERACTION:
     200                 :          0 :                 g_value_set_object (value, self->pv->interaction);
     201                 :          0 :                 break;
     202                 :          0 :         case PROP_URI:
     203                 :          0 :                 g_value_take_string (value, calculate_uri (self));
     204                 :          0 :                 break;
     205                 :          0 :         default:
     206                 :          0 :                 G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
     207                 :          0 :                 break;
     208                 :            :         }
     209                 :          0 : }
     210                 :            : 
     211                 :            : static void
     212                 :          0 : _gcr_gnupg_importer_class_init (GcrGnupgImporterClass *klass)
     213                 :            : {
     214                 :          0 :         GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
     215                 :          0 :         GckBuilder builder = GCK_BUILDER_INIT;
     216                 :            : 
     217                 :          0 :         gobject_class->dispose = _gcr_gnupg_importer_dispose;
     218                 :          0 :         gobject_class->finalize = _gcr_gnupg_importer_finalize;
     219                 :          0 :         gobject_class->set_property = _gcr_gnupg_importer_set_property;
     220                 :          0 :         gobject_class->get_property = _gcr_gnupg_importer_get_property;
     221                 :            : 
     222                 :          0 :         g_object_class_override_property (gobject_class, PROP_LABEL, "label");
     223                 :          0 :         g_object_class_override_property (gobject_class, PROP_INTERACTION, "interaction");
     224                 :          0 :         g_object_class_override_property (gobject_class, PROP_URI, "uri");
     225                 :            : 
     226                 :          0 :         g_object_class_install_property (gobject_class, PROP_IMPORTED,
     227                 :            :                 g_param_spec_boxed ("imported", "Imported", "Fingerprints of imported keys",
     228                 :            :                                     G_TYPE_STRV,
     229                 :            :                                     G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
     230                 :            : 
     231                 :          0 :         g_object_class_install_property (gobject_class, PROP_DIRECTORY,
     232                 :            :                 g_param_spec_string ("directory", "Directory", "Directory to import keys to",
     233                 :            :                                      NULL,
     234                 :            :                                      G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
     235                 :            : 
     236                 :          0 :         gck_builder_add_ulong (&builder, CKA_CLASS, CKO_GCR_GNUPG_RECORDS);
     237                 :          0 :         gcr_importer_register (GCR_TYPE_GNUPG_IMPORTER, gck_builder_end (&builder));
     238                 :            : 
     239                 :          0 :         _gcr_initialize_library ();
     240                 :          0 : }
     241                 :            : 
     242                 :            : static GList *
     243                 :          0 : _gcr_gnupg_importer_create_for_parsed (GcrParsed *parsed)
     244                 :            : {
     245                 :            :         GcrImporter *self;
     246                 :            : 
     247         [ #  # ]:          0 :         if (gcr_parsed_get_format (parsed) != GCR_FORMAT_OPENPGP_PACKET)
     248                 :          0 :                 return NULL;
     249                 :            : 
     250                 :          0 :         self = _gcr_gnupg_importer_new (NULL);
     251         [ #  # ]:          0 :         if (!gcr_importer_queue_for_parsed (self, parsed))
     252                 :          0 :                 g_assert_not_reached ();
     253                 :            : 
     254                 :          0 :         return g_list_append (NULL, self);
     255                 :            : }
     256                 :            : 
     257                 :            : static gboolean
     258                 :          0 : _gcr_gnupg_importer_queue_for_parsed (GcrImporter *importer,
     259                 :            :                                       GcrParsed *parsed)
     260                 :            : {
     261                 :          0 :         GcrGnupgImporter *self = GCR_GNUPG_IMPORTER (importer);
     262                 :            :         gconstpointer block;
     263                 :            :         gsize n_block;
     264                 :            : 
     265         [ #  # ]:          0 :         if (gcr_parsed_get_format (parsed) != GCR_FORMAT_OPENPGP_PACKET)
     266                 :          0 :                 return FALSE;
     267                 :            : 
     268                 :          0 :         block = gcr_parsed_get_data (parsed, &n_block);
     269         [ #  # ]:          0 :         g_return_val_if_fail (block, FALSE);
     270                 :            : 
     271                 :          0 :         g_memory_input_stream_add_data (self->pv->packets, g_memdup2 (block, n_block),
     272                 :            :                                         n_block, g_free);
     273                 :          0 :         return TRUE;
     274                 :            : }
     275                 :            : 
     276                 :            : static void
     277                 :          0 : on_process_run_complete (GObject *source,
     278                 :            :                          GAsyncResult *result,
     279                 :            :                          gpointer user_data)
     280                 :            : {
     281                 :          0 :         GTask *task = G_TASK (user_data);
     282                 :          0 :         GcrGnupgImporter *self = GCR_GNUPG_IMPORTER (g_task_get_source_object (task));
     283                 :          0 :         GError *error = NULL;
     284                 :            : 
     285         [ #  # ]:          0 :         if (!_gcr_gnupg_process_run_finish (GCR_GNUPG_PROCESS (source), result, &error)) {
     286   [ #  #  #  # ]:          0 :                 if (g_error_matches (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED) && self->pv->first_error) {
     287                 :          0 :                         g_task_return_new_error (task, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED,
     288                 :          0 :                                                  "%s", self->pv->first_error);
     289                 :          0 :                         g_error_free (error);
     290                 :            :                 } else {
     291                 :          0 :                         g_task_return_error (task, g_steal_pointer (&error));
     292                 :            :                 }
     293                 :            :         } else {
     294                 :          0 :                 g_task_return_boolean (task, TRUE);
     295                 :            :         }
     296                 :            : 
     297         [ #  # ]:          0 :         g_clear_object (&task);
     298                 :          0 : }
     299                 :            : 
     300                 :            : static void
     301                 :          0 : _gcr_gnupg_importer_import_async (GcrImporter *importer,
     302                 :            :                                   GCancellable *cancellable,
     303                 :            :                                   GAsyncReadyCallback callback,
     304                 :            :                                   gpointer user_data)
     305                 :            : {
     306                 :          0 :         GcrGnupgImporter *self = GCR_GNUPG_IMPORTER (importer);
     307                 :            :         GTask *task;
     308                 :          0 :         const gchar *argv[] = { "--import", NULL };
     309                 :            : 
     310         [ #  # ]:          0 :         g_clear_pointer (&self->pv->first_error, g_free);
     311                 :            : 
     312                 :          0 :         task = g_task_new (importer, cancellable, callback, user_data);
     313         [ #  # ]:          0 :         g_task_set_source_tag (task, _gcr_gnupg_importer_import_async);
     314                 :            : 
     315                 :          0 :         _gcr_gnupg_process_run_async (self->pv->process, argv, NULL,
     316                 :            :                                       GCR_GNUPG_PROCESS_WITH_STATUS,
     317                 :            :                                       cancellable, on_process_run_complete,
     318                 :            :                                       g_steal_pointer (&task));
     319                 :            : 
     320         [ #  # ]:          0 :         g_clear_object (&task);
     321                 :          0 : }
     322                 :            : 
     323                 :            : static gboolean
     324                 :          0 : _gcr_gnupg_importer_import_finish (GcrImporter *importer,
     325                 :            :                                    GAsyncResult *result,
     326                 :            :                                    GError **error)
     327                 :            : {
     328         [ #  # ]:          0 :         g_return_val_if_fail (g_task_is_valid (result, importer), FALSE);
     329                 :            : 
     330                 :          0 :         return g_task_propagate_boolean (G_TASK (result), error);
     331                 :            : }
     332                 :            : 
     333                 :            : static void
     334                 :          0 : gcr_gnupg_importer_iface (GcrImporterInterface *iface)
     335                 :            : {
     336                 :          0 :         iface->create_for_parsed = _gcr_gnupg_importer_create_for_parsed;
     337                 :          0 :         iface->queue_for_parsed = _gcr_gnupg_importer_queue_for_parsed;
     338                 :          0 :         iface->import_async = _gcr_gnupg_importer_import_async;
     339                 :          0 :         iface->import_finish = _gcr_gnupg_importer_import_finish;
     340                 :          0 : }
     341                 :            : 
     342                 :            : /**
     343                 :            :  * _gcr_gnupg_importer_new:
     344                 :            :  * @directory: (nullable): the directory to import to, or %NULL for default
     345                 :            :  *
     346                 :            :  * Create a new #GcrGnupgImporter.
     347                 :            :  *
     348                 :            :  * Returns: (transfer full) (type Gcr.GnupgImporter): the new importer
     349                 :            :  */
     350                 :            : GcrImporter *
     351                 :          0 : _gcr_gnupg_importer_new (const gchar *directory)
     352                 :            : {
     353                 :          0 :         return g_object_new (GCR_TYPE_GNUPG_IMPORTER,
     354                 :            :                              "directory", directory,
     355                 :            :                              NULL);
     356                 :            : }
     357                 :            : 
     358                 :            : const gchar **
     359                 :          0 : _gcr_gnupg_importer_get_imported (GcrGnupgImporter *self)
     360                 :            : {
     361   [ #  #  #  #  :          0 :         g_return_val_if_fail (GCR_IS_GNUPG_IMPORTER (self), NULL);
             #  #  #  # ]
     362                 :          0 :         return (const gchar **)self->pv->imported->data;
     363                 :            : }

Generated by: LCOV version 1.14