LCOV - code coverage report
Current view: top level - src - engine.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 296 463 63.9 %
Date: 2018-11-14 16:53:58 Functions: 42 51 82.4 %

          Line data    Source code
       1             : /* engine.c - GPGME engine support.
       2             :    Copyright (C) 2000 Werner Koch (dd9jn)
       3             :    Copyright (C) 2001, 2002, 2003, 2004, 2006, 2009, 2010 g10 Code GmbH
       4             : 
       5             :    This file is part of GPGME.
       6             : 
       7             :    GPGME is free software; you can redistribute it and/or modify it
       8             :    under the terms of the GNU Lesser General Public License as
       9             :    published by the Free Software Foundation; either version 2.1 of
      10             :    the License, or (at your option) any later version.
      11             : 
      12             :    GPGME is distributed in the hope that it will be useful, but
      13             :    WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      15             :    Lesser General Public License for more details.
      16             : 
      17             :    You should have received a copy of the GNU Lesser General Public
      18             :    License along with this program; if not, see <https://www.gnu.org/licenses/>.
      19             : */
      20             : 
      21             : #ifdef HAVE_CONFIG_H
      22             : #include <config.h>
      23             : #endif
      24             : #include <stdlib.h>
      25             : #include <string.h>
      26             : #include <errno.h>
      27             : #include <assert.h>
      28             : 
      29             : #include "gpgme.h"
      30             : #include "util.h"
      31             : #include "sema.h"
      32             : #include "ops.h"
      33             : #include "debug.h"
      34             : 
      35             : #include "engine.h"
      36             : #include "engine-backend.h"
      37             : 
      38             : 
      39             : struct engine
      40             : {
      41             :   struct engine_ops *ops;
      42             :   void *engine;
      43             : };
      44             : 
      45             : 
      46             : static struct engine_ops *engine_ops[] =
      47             :   {
      48             :     &_gpgme_engine_ops_gpg,         /* OpenPGP.  */
      49             :     &_gpgme_engine_ops_gpgsm,               /* CMS.  */
      50             :     &_gpgme_engine_ops_gpgconf,             /* gpg-conf.  */
      51             :     &_gpgme_engine_ops_assuan,              /* Low-Level Assuan.  */
      52             :     &_gpgme_engine_ops_g13,         /* Crypto VFS.  */
      53             : #ifdef ENABLE_UISERVER
      54             :     &_gpgme_engine_ops_uiserver,    /* UI-Server.  */
      55             : #else
      56             :     NULL,
      57             : #endif
      58             :     &_gpgme_engine_ops_spawn
      59             :   };
      60             : 
      61             : 
      62             : /* The engine info.  */
      63             : static gpgme_engine_info_t engine_info;
      64             : DEFINE_STATIC_LOCK (engine_info_lock);
      65             : 
      66             : /* If non-NULL, the minimal version required for all engines.  */
      67             : static char *engine_minimal_version;
      68             : 
      69             : 
      70             : 
      71             : /* Get the file name of the engine for PROTOCOL.  */
      72             : static const char *
      73         855 : engine_get_file_name (gpgme_protocol_t proto)
      74             : {
      75         855 :   if (proto > DIM (engine_ops))
      76           0 :     return NULL;
      77             : 
      78         855 :   if (engine_ops[proto] && engine_ops[proto]->get_file_name)
      79         855 :     return (*engine_ops[proto]->get_file_name) ();
      80             :   else
      81           0 :     return NULL;
      82             : }
      83             : 
      84             : 
      85             : /* Get the standard home dir of the engine for PROTOCOL.  */
      86             : static const char *
      87        1026 : engine_get_home_dir (gpgme_protocol_t proto)
      88             : {
      89        1026 :   if (proto > DIM (engine_ops))
      90           0 :     return NULL;
      91             : 
      92        1026 :   if (engine_ops[proto] && engine_ops[proto]->get_home_dir)
      93         112 :     return (*engine_ops[proto]->get_home_dir) ();
      94             :   else
      95         914 :     return NULL;
      96             : }
      97             : 
      98             : 
      99             : /* Get a malloced string containing the version number of the engine
     100             :  * for PROTOCOL.  If this function returns NULL for a valid protocol,
     101             :  * it should be assumed that the engine is a pseudo engine. */
     102             : static char *
     103        1113 : engine_get_version (gpgme_protocol_t proto, const char *file_name)
     104             : {
     105        1113 :   if (proto > DIM (engine_ops))
     106           0 :     return NULL;
     107             : 
     108        1113 :   if (engine_ops[proto] && engine_ops[proto]->get_version)
     109        1113 :     return (*engine_ops[proto]->get_version) (file_name);
     110             :   else
     111           0 :     return NULL;
     112             : }
     113             : 
     114             : 
     115             : /* Get the required version number of the engine for PROTOCOL.  This
     116             :  * may be NULL. */
     117             : static const char *
     118         588 : engine_get_req_version (gpgme_protocol_t proto)
     119             : {
     120         588 :   if (proto > DIM (engine_ops))
     121           0 :     return NULL;
     122             : 
     123         588 :   if (engine_ops[proto] && engine_ops[proto]->get_req_version)
     124         588 :     return (*engine_ops[proto]->get_req_version) ();
     125             :   else
     126           0 :     return NULL;
     127             : }
     128             : 
     129             : 
     130             : /* Verify the version requirement for the engine for PROTOCOL.  */
     131             : gpgme_error_t
     132         235 : gpgme_engine_check_version (gpgme_protocol_t proto)
     133             : {
     134             :   gpgme_error_t err;
     135             :   gpgme_engine_info_t info;
     136             :   int result;
     137             : 
     138         235 :   LOCK (engine_info_lock);
     139         235 :   info = engine_info;
     140         235 :   if (!info)
     141             :     {
     142             :       /* Make sure it is initialized.  */
     143          35 :       UNLOCK (engine_info_lock);
     144          35 :       err = gpgme_get_engine_info (&info);
     145          35 :       if (err)
     146           0 :         return err;
     147             : 
     148          35 :       LOCK (engine_info_lock);
     149             :     }
     150             : 
     151         521 :   while (info && info->protocol != proto)
     152          51 :     info = info->next;
     153             : 
     154         235 :   if (!info)
     155           0 :     result = 0;
     156             :   else
     157         235 :     result = _gpgme_compare_versions (info->version,
     158         235 :                                       info->req_version);
     159             : 
     160         235 :   UNLOCK (engine_info_lock);
     161         235 :   return result ? 0 : trace_gpg_error (GPG_ERR_INV_ENGINE);
     162             : }
     163             : 
     164             : 
     165             : /* Release the engine info INFO.  */
     166             : void
     167         702 : _gpgme_engine_info_release (gpgme_engine_info_t info)
     168             : {
     169        5616 :   while (info)
     170             :     {
     171        4212 :       gpgme_engine_info_t next_info = info->next;
     172             : 
     173        4212 :       if (info->file_name)
     174        4212 :         free (info->file_name);
     175        4212 :       if (info->home_dir)
     176         788 :         free (info->home_dir);
     177        4212 :       if (info->version)
     178        4212 :         free (info->version);
     179        4212 :       free (info);
     180        4212 :       info = next_info;
     181             :     }
     182         702 : }
     183             : 
     184             : 
     185             : /* This is an internal function to set a mimimal required version.
     186             :  * This function must only be called by gpgme_set_global_flag.
     187             :  * Returns 0 on success.  */
     188             : int
     189           0 : _gpgme_set_engine_minimal_version (const char *value)
     190             : {
     191           0 :   free (engine_minimal_version);
     192           0 :   if (value)
     193             :     {
     194           0 :       engine_minimal_version = strdup (value);
     195           0 :       return !engine_minimal_version;
     196             :     }
     197             :   else
     198             :     {
     199           0 :       engine_minimal_version = NULL;
     200           0 :       return 0;
     201             :     }
     202             : }
     203             : 
     204             : 
     205             : /* Get the information about the configured and installed engines.  A
     206             :    pointer to the first engine in the statically allocated linked list
     207             :    is returned in *INFO.  If an error occurs, it is returned.  The
     208             :    returned data is valid until the next gpgme_set_engine_info.  */
     209             : gpgme_error_t
     210         105 : gpgme_get_engine_info (gpgme_engine_info_t *info)
     211             : {
     212             :   gpgme_error_t err;
     213             : 
     214         105 :   LOCK (engine_info_lock);
     215         105 :   if (!engine_info)
     216             :     {
     217          98 :       gpgme_engine_info_t *lastp = &engine_info;
     218          98 :       gpgme_protocol_t proto_list[] = { GPGME_PROTOCOL_OpenPGP,
     219             :                                         GPGME_PROTOCOL_CMS,
     220             :                                         GPGME_PROTOCOL_GPGCONF,
     221             :                                         GPGME_PROTOCOL_ASSUAN,
     222             :                                         GPGME_PROTOCOL_G13,
     223             :                                         GPGME_PROTOCOL_UISERVER,
     224             :                                         GPGME_PROTOCOL_SPAWN    };
     225             :       unsigned int proto;
     226             : 
     227          98 :       err = 0;
     228         784 :       for (proto = 0; proto < DIM (proto_list); proto++)
     229             :         {
     230         686 :           const char *ofile_name = engine_get_file_name (proto_list[proto]);
     231         686 :           const char *ohome_dir  = engine_get_home_dir (proto_list[proto]);
     232         686 :           char *version = engine_get_version (proto_list[proto], NULL);
     233             :           char *file_name;
     234             :           char *home_dir;
     235             : 
     236         686 :           if (!ofile_name)
     237          98 :             continue;
     238             : 
     239         588 :           file_name = strdup (ofile_name);
     240         588 :           if (!file_name)
     241           0 :             err = gpg_error_from_syserror ();
     242             : 
     243         588 :           if (ohome_dir)
     244             :             {
     245          98 :               home_dir = strdup (ohome_dir);
     246          98 :               if (!home_dir && !err)
     247           0 :                 err = gpg_error_from_syserror ();
     248             :             }
     249             :           else
     250         490 :             home_dir = NULL;
     251             : 
     252         588 :           *lastp = calloc (1, sizeof (*engine_info));
     253         588 :           if (!*lastp && !err)
     254           0 :             err = gpg_error_from_syserror ();
     255             : 
     256             :           /* Check against the optional minimal engine version.  */
     257         588 :           if (!err && version && engine_minimal_version
     258           0 :               && !_gpgme_compare_versions (version, engine_minimal_version))
     259             :             {
     260             : #if GPG_ERROR_VERSION_NUMBER < 0x011900 /* 1.25 */
     261             :               err = gpg_error (GPG_ERR_NO_ENGINE);
     262             : #else
     263           0 :               err = gpg_error (GPG_ERR_ENGINE_TOO_OLD);
     264             : #endif
     265             :             }
     266             : 
     267             :           /* Now set the dummy version for pseudo engines.  */
     268         588 :           if (!err && !version)
     269             :             {
     270         294 :               version = strdup ("1.0.0");
     271         294 :               if (!version)
     272           0 :                 err = gpg_error_from_syserror ();
     273             :             }
     274             : 
     275         588 :           if (err)
     276             :             {
     277           0 :               _gpgme_engine_info_release (engine_info);
     278           0 :               engine_info = NULL;
     279             : 
     280           0 :               if (file_name)
     281           0 :                 free (file_name);
     282           0 :               if (home_dir)
     283           0 :                 free (home_dir);
     284           0 :               if (version)
     285           0 :                 free (version);
     286             : 
     287           0 :               UNLOCK (engine_info_lock);
     288           0 :               return err;
     289             :             }
     290             : 
     291         588 :           (*lastp)->protocol = proto_list[proto];
     292         588 :           (*lastp)->file_name = file_name;
     293         588 :           (*lastp)->home_dir = home_dir;
     294         588 :           (*lastp)->version = version;
     295         588 :           (*lastp)->req_version = engine_get_req_version (proto_list[proto]);
     296         588 :           if (!(*lastp)->req_version)
     297         294 :             (*lastp)->req_version = "1.0.0"; /* Dummy for pseudo engines. */
     298         588 :           (*lastp)->next = NULL;
     299         588 :           lastp = &(*lastp)->next;
     300             :         }
     301             :     }
     302             : 
     303         105 :   *info = engine_info;
     304         105 :   UNLOCK (engine_info_lock);
     305         105 :   return 0;
     306             : }
     307             : 
     308             : 
     309             : /* Get a deep copy of the engine info and return it in INFO.  */
     310             : gpgme_error_t
     311         724 : _gpgme_engine_info_copy (gpgme_engine_info_t *r_info)
     312             : {
     313         724 :   gpgme_error_t err = 0;
     314             :   gpgme_engine_info_t info;
     315             :   gpgme_engine_info_t new_info;
     316             :   gpgme_engine_info_t *lastp;
     317             : 
     318         724 :   LOCK (engine_info_lock);
     319         724 :   info = engine_info;
     320         724 :   if (!info)
     321             :     {
     322             :       /* Make sure it is initialized.  */
     323          59 :       UNLOCK (engine_info_lock);
     324          59 :       err = gpgme_get_engine_info (&info);
     325          59 :       if (err)
     326           0 :         return err;
     327             : 
     328          59 :       LOCK (engine_info_lock);
     329             :     }
     330             : 
     331         724 :   new_info = NULL;
     332         724 :   lastp = &new_info;
     333             : 
     334        5792 :   while (info)
     335             :     {
     336             :       char *file_name;
     337             :       char *home_dir;
     338             :       char *version;
     339             : 
     340        4344 :       assert (info->file_name);
     341        4344 :       file_name = strdup (info->file_name);
     342        4344 :       if (!file_name)
     343           0 :         err = gpg_error_from_syserror ();
     344             : 
     345        4344 :       if (info->home_dir)
     346             :         {
     347         724 :           home_dir = strdup (info->home_dir);
     348         724 :           if (!home_dir && !err)
     349           0 :             err = gpg_error_from_syserror ();
     350             :         }
     351             :       else
     352        3620 :         home_dir = NULL;
     353             : 
     354        4344 :       if (info->version)
     355             :         {
     356        4344 :           version = strdup (info->version);
     357        4344 :           if (!version && !err)
     358           0 :             err = gpg_error_from_syserror ();
     359             :         }
     360             :       else
     361           0 :         version = NULL;
     362             : 
     363        4344 :       *lastp = malloc (sizeof (*engine_info));
     364        4344 :       if (!*lastp && !err)
     365           0 :         err = gpg_error_from_syserror ();
     366             : 
     367        4344 :       if (err)
     368             :         {
     369           0 :           _gpgme_engine_info_release (new_info);
     370           0 :           if (file_name)
     371           0 :             free (file_name);
     372           0 :           if (home_dir)
     373           0 :             free (home_dir);
     374           0 :           if (version)
     375           0 :             free (version);
     376             : 
     377           0 :           UNLOCK (engine_info_lock);
     378           0 :           return err;
     379             :         }
     380             : 
     381        4344 :       (*lastp)->protocol = info->protocol;
     382        4344 :       (*lastp)->file_name = file_name;
     383        4344 :       (*lastp)->home_dir = home_dir;
     384        4344 :       (*lastp)->version = version;
     385        4344 :       (*lastp)->req_version = info->req_version;
     386        4344 :       (*lastp)->next = NULL;
     387        4344 :       lastp = &(*lastp)->next;
     388             : 
     389        4344 :       info = info->next;
     390             :     }
     391             : 
     392         724 :   *r_info = new_info;
     393         724 :   UNLOCK (engine_info_lock);
     394         724 :   return 0;
     395             : }
     396             : 
     397             : 
     398             : /* Set the engine info for the info list INFO, protocol PROTO, to the
     399             :    file name FILE_NAME and the home directory HOME_DIR.  */
     400             : gpgme_error_t
     401         427 : _gpgme_set_engine_info (gpgme_engine_info_t info, gpgme_protocol_t proto,
     402             :                         const char *file_name, const char *home_dir)
     403             : {
     404             :   char *new_file_name;
     405             :   char *new_home_dir;
     406             :   char *new_version;
     407             : 
     408             :   /* FIXME: Use some PROTO_MAX definition.  */
     409         427 :   if (proto > DIM (engine_ops))
     410           0 :     return gpg_error (GPG_ERR_INV_VALUE);
     411             : 
     412         901 :   while (info && info->protocol != proto)
     413          47 :     info = info->next;
     414             : 
     415         427 :   if (!info)
     416           0 :     return trace_gpg_error (GPG_ERR_INV_ENGINE);
     417             : 
     418             :   /* Prepare new members.  */
     419         427 :   if (file_name)
     420         258 :     new_file_name = strdup (file_name);
     421             :   else
     422             :     {
     423         169 :       const char *ofile_name = engine_get_file_name (proto);
     424         169 :       assert (ofile_name);
     425         169 :       new_file_name = strdup (ofile_name);
     426             :     }
     427         427 :   if (!new_file_name)
     428           0 :     return gpg_error_from_syserror ();
     429             : 
     430         427 :   if (home_dir)
     431             :     {
     432          87 :       new_home_dir = strdup (home_dir);
     433          87 :       if (!new_home_dir)
     434             :         {
     435           0 :           free (new_file_name);
     436           0 :           return gpg_error_from_syserror ();
     437             :         }
     438             :     }
     439             :   else
     440             :     {
     441         340 :       const char *ohome_dir = engine_get_home_dir (proto);
     442         340 :       if (ohome_dir)
     443             :         {
     444          14 :           new_home_dir = strdup (ohome_dir);
     445          14 :           if (!new_home_dir)
     446             :             {
     447           0 :               free (new_file_name);
     448           0 :               return gpg_error_from_syserror ();
     449             :             }
     450             :         }
     451             :       else
     452         326 :         new_home_dir = NULL;
     453             :     }
     454             : 
     455         427 :   new_version = engine_get_version (proto, new_file_name);
     456         428 :   if (!new_version)
     457             :     {
     458          14 :       new_version = strdup ("1.0.0"); /* Fake one for dummy entries.  */
     459          14 :       if (!new_version)
     460             :         {
     461           0 :           free (new_file_name);
     462           0 :           free (new_home_dir);
     463             :         }
     464             :     }
     465             : 
     466             :   /* Remove the old members.  */
     467         428 :   assert (info->file_name);
     468         428 :   free (info->file_name);
     469         428 :   if (info->home_dir)
     470          15 :     free (info->home_dir);
     471         428 :   if (info->version)
     472         428 :     free (info->version);
     473             : 
     474             :   /* Install the new members.  */
     475         428 :   info->file_name = new_file_name;
     476         428 :   info->home_dir = new_home_dir;
     477         428 :   info->version = new_version;
     478             : 
     479         428 :   return 0;
     480             : }
     481             : 
     482             : 
     483             : /* Set the default engine info for the protocol PROTO to the file name
     484             :    FILE_NAME and the home directory HOME_DIR.  */
     485             : gpgme_error_t
     486           0 : gpgme_set_engine_info (gpgme_protocol_t proto,
     487             :                        const char *file_name, const char *home_dir)
     488             : {
     489             :   gpgme_error_t err;
     490             :   gpgme_engine_info_t info;
     491             : 
     492           0 :   LOCK (engine_info_lock);
     493           0 :   info = engine_info;
     494           0 :   if (!info)
     495             :     {
     496             :       /* Make sure it is initialized.  */
     497           0 :       UNLOCK (engine_info_lock);
     498           0 :       err = gpgme_get_engine_info (&info);
     499           0 :       if (err)
     500           0 :         return err;
     501             : 
     502           0 :       LOCK (engine_info_lock);
     503             :     }
     504             : 
     505           0 :   err = _gpgme_set_engine_info (info, proto, file_name, home_dir);
     506           0 :   UNLOCK (engine_info_lock);
     507           0 :   return err;
     508             : }
     509             : 
     510             : 
     511             : gpgme_error_t
     512         952 : _gpgme_engine_new (gpgme_engine_info_t info, engine_t *r_engine)
     513             : {
     514             :   engine_t engine;
     515             : 
     516         952 :   if (!info->file_name || !info->version)
     517           0 :     return trace_gpg_error (GPG_ERR_INV_ENGINE);
     518             : 
     519         952 :   engine = calloc (1, sizeof *engine);
     520         952 :   if (!engine)
     521           0 :     return gpg_error_from_syserror ();
     522             : 
     523         952 :   engine->ops = engine_ops[info->protocol];
     524         952 :   if (engine->ops->new)
     525             :     {
     526             :       gpgme_error_t err;
     527        1904 :       err = (*engine->ops->new) (&engine->engine,
     528         952 :                                  info->file_name, info->home_dir,
     529         952 :                                  info->version);
     530         952 :       if (err)
     531             :         {
     532          12 :           free (engine);
     533          12 :           return err;
     534             :         }
     535             :     }
     536             :   else
     537           0 :     engine->engine = NULL;
     538             : 
     539         940 :   *r_engine = engine;
     540         940 :   return 0;
     541             : }
     542             : 
     543             : 
     544             : gpgme_error_t
     545         300 : _gpgme_engine_reset (engine_t engine)
     546             : {
     547         300 :   if (!engine)
     548           0 :     return gpg_error (GPG_ERR_INV_VALUE);
     549             : 
     550         300 :   if (!engine->ops->reset)
     551         296 :     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
     552             : 
     553           4 :   return (*engine->ops->reset) (engine->engine);
     554             : }
     555             : 
     556             : 
     557             : void
     558        1013 : _gpgme_engine_release (engine_t engine)
     559             : {
     560        1013 :   if (!engine)
     561          94 :     return;
     562             : 
     563         919 :   if (engine->ops->release)
     564         919 :     (*engine->ops->release) (engine->engine);
     565         917 :   free (engine);
     566             : }
     567             : 
     568             : 
     569             : /* Set a status callback which is used to monitor the status values
     570             :  * before they are passed to a handler set with
     571             :  * _gpgme_engine_set_status_handler.  */
     572             : void
     573           4 : _gpgme_engine_set_status_cb (engine_t engine,
     574             :                              gpgme_status_cb_t cb, void *cb_value)
     575             : {
     576           4 :   if (!engine)
     577           0 :     return;
     578             : 
     579           4 :   if (engine->ops->set_status_cb)
     580           4 :     (*engine->ops->set_status_cb) (engine->engine, cb, cb_value);
     581             : }
     582             : 
     583             : 
     584             : void
     585         776 : _gpgme_engine_set_status_handler (engine_t engine,
     586             :                                   engine_status_handler_t fnc, void *fnc_value)
     587             : {
     588         776 :   if (!engine)
     589           0 :     return;
     590             : 
     591         776 :   if (engine->ops->set_status_handler)
     592         776 :     (*engine->ops->set_status_handler) (engine->engine, fnc, fnc_value);
     593             : }
     594             : 
     595             : 
     596             : gpgme_error_t
     597          96 : _gpgme_engine_set_command_handler (engine_t engine,
     598             :                                    engine_command_handler_t fnc,
     599             :                                    void *fnc_value)
     600             : {
     601          96 :   if (!engine)
     602           0 :     return gpg_error (GPG_ERR_INV_VALUE);
     603             : 
     604          96 :   if (!engine->ops->set_command_handler)
     605           0 :     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
     606             : 
     607          96 :   return (*engine->ops->set_command_handler) (engine->engine, fnc, fnc_value);
     608             : }
     609             : 
     610             : gpgme_error_t
     611         339 : _gpgme_engine_set_colon_line_handler (engine_t engine,
     612             :                                       engine_colon_line_handler_t fnc,
     613             :                                       void *fnc_value)
     614             : {
     615         339 :   if (!engine)
     616           0 :     return gpg_error (GPG_ERR_INV_VALUE);
     617             : 
     618         339 :   if (!engine->ops->set_colon_line_handler)
     619           0 :     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
     620             : 
     621         339 :   return (*engine->ops->set_colon_line_handler) (engine->engine,
     622             :                                                  fnc, fnc_value);
     623             : }
     624             : 
     625             : gpgme_error_t
     626        1690 : _gpgme_engine_set_locale (engine_t engine, int category,
     627             :                           const char *value)
     628             : {
     629        1690 :   if (!engine)
     630           0 :     return gpg_error (GPG_ERR_INV_VALUE);
     631             : 
     632        1690 :   if (!engine->ops->set_locale)
     633         198 :     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
     634             : 
     635        1492 :   return (*engine->ops->set_locale) (engine->engine, category, value);
     636             : }
     637             : 
     638             : 
     639             : gpgme_error_t
     640           0 : _gpgme_engine_set_protocol (engine_t engine, gpgme_protocol_t protocol)
     641             : {
     642           0 :   if (!engine)
     643           0 :     return gpg_error (GPG_ERR_INV_VALUE);
     644             : 
     645           0 :   if (!engine->ops->set_protocol)
     646           0 :     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
     647             : 
     648           0 :   return (*engine->ops->set_protocol) (engine->engine, protocol);
     649             : }
     650             : 
     651             : 
     652             : /* Pass information about the current context to the engine.  The
     653             :  * engine may use this context to retrieve context specific flags.
     654             :  * Important: The engine is required to immediately copy the required
     655             :  * flags to its own context!
     656             :  *
     657             :  * This function will eventually be used to reduce the number of
     658             :  * explicit passed flags.  */
     659             : void
     660         944 : _gpgme_engine_set_engine_flags (engine_t engine, gpgme_ctx_t ctx)
     661             : {
     662         944 :   if (!engine)
     663           0 :     return;
     664             : 
     665         944 :   if (!engine->ops->set_engine_flags)
     666         198 :     return;
     667             : 
     668         746 :   (*engine->ops->set_engine_flags) (engine->engine, ctx);
     669             : }
     670             : 
     671             : 
     672             : gpgme_error_t
     673          50 : _gpgme_engine_op_decrypt (engine_t engine,
     674             :                           gpgme_decrypt_flags_t flags,
     675             :                           gpgme_data_t ciph,
     676             :                           gpgme_data_t plain, int export_session_key,
     677             :                           const char *override_session_key,
     678             :                           int auto_key_retrieve)
     679             : {
     680          50 :   if (!engine)
     681           0 :     return gpg_error (GPG_ERR_INV_VALUE);
     682             : 
     683          50 :   if (!engine->ops->decrypt)
     684           0 :     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
     685             : 
     686          50 :   return (*engine->ops->decrypt) (engine->engine, flags, ciph, plain,
     687             :                                   export_session_key, override_session_key,
     688             :                                   auto_key_retrieve);
     689             : }
     690             : 
     691             : 
     692             : gpgme_error_t
     693           0 : _gpgme_engine_op_delete (engine_t engine, gpgme_key_t key,
     694             :                          unsigned int flags)
     695             : {
     696           0 :   if (!engine)
     697           0 :     return gpg_error (GPG_ERR_INV_VALUE);
     698             : 
     699           0 :   if (!engine->ops->delete)
     700           0 :     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
     701             : 
     702           0 :   return (*engine->ops->delete) (engine->engine, key, flags);
     703             : }
     704             : 
     705             : 
     706             : gpgme_error_t
     707          13 : _gpgme_engine_op_edit (engine_t engine, int type, gpgme_key_t key,
     708             :                        gpgme_data_t out, gpgme_ctx_t ctx /* FIXME */)
     709             : {
     710          13 :   if (!engine)
     711           0 :     return gpg_error (GPG_ERR_INV_VALUE);
     712             : 
     713          13 :   if (!engine->ops->edit)
     714           0 :     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
     715             : 
     716          13 :   return (*engine->ops->edit) (engine->engine, type, key, out, ctx);
     717             : }
     718             : 
     719             : 
     720             : gpgme_error_t
     721          64 : _gpgme_engine_op_encrypt (engine_t engine, gpgme_key_t recp[],
     722             :                           const char *recpstring,
     723             :                           gpgme_encrypt_flags_t flags,
     724             :                           gpgme_data_t plain, gpgme_data_t ciph, int use_armor)
     725             : {
     726          64 :   if (!engine)
     727           0 :     return gpg_error (GPG_ERR_INV_VALUE);
     728             : 
     729          64 :   if (!engine->ops->encrypt)
     730           0 :     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
     731             : 
     732          64 :   return (*engine->ops->encrypt) (engine->engine, recp, recpstring,
     733             :                                   flags, plain, ciph, use_armor);
     734             : }
     735             : 
     736             : 
     737             : gpgme_error_t
     738          17 : _gpgme_engine_op_encrypt_sign (engine_t engine, gpgme_key_t recp[],
     739             :                                const char *recpstring,
     740             :                                gpgme_encrypt_flags_t flags,
     741             :                                gpgme_data_t plain, gpgme_data_t ciph,
     742             :                                int use_armor, gpgme_ctx_t ctx /* FIXME */)
     743             : {
     744          17 :   if (!engine)
     745           0 :     return gpg_error (GPG_ERR_INV_VALUE);
     746             : 
     747          17 :   if (!engine->ops->encrypt_sign)
     748           0 :     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
     749             : 
     750          17 :   return (*engine->ops->encrypt_sign) (engine->engine, recp, recpstring,
     751             :                                        flags, plain, ciph, use_armor, ctx);
     752             : }
     753             : 
     754             : 
     755             : gpgme_error_t
     756           0 : _gpgme_engine_op_export (engine_t engine, const char *pattern,
     757             :                          gpgme_export_mode_t mode, gpgme_data_t keydata,
     758             :                          int use_armor)
     759             : {
     760           0 :   if (!engine)
     761           0 :     return gpg_error (GPG_ERR_INV_VALUE);
     762             : 
     763           0 :   if (!engine->ops->export)
     764           0 :     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
     765             : 
     766           0 :   return (*engine->ops->export) (engine->engine, pattern, mode,
     767             :                                  keydata, use_armor);
     768             : }
     769             : 
     770             : 
     771             : gpgme_error_t
     772          10 : _gpgme_engine_op_export_ext (engine_t engine, const char *pattern[],
     773             :                              unsigned int reserved, gpgme_data_t keydata,
     774             :                              int use_armor)
     775             : {
     776          10 :   if (!engine)
     777           0 :     return gpg_error (GPG_ERR_INV_VALUE);
     778             : 
     779          10 :   if (!engine->ops->export_ext)
     780           0 :     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
     781             : 
     782          10 :   return (*engine->ops->export_ext) (engine->engine, pattern, reserved,
     783             :                                      keydata, use_armor);
     784             : }
     785             : 
     786             : 
     787             : gpgme_error_t
     788         108 : _gpgme_engine_op_genkey (engine_t engine,
     789             :                          const char *userid, const char *algo,
     790             :                          unsigned long reserved, unsigned long expires,
     791             :                          gpgme_key_t key, unsigned int flags,
     792             :                          gpgme_data_t help_data,
     793             :                          unsigned int extraflags,
     794             :                          gpgme_data_t pubkey, gpgme_data_t seckey)
     795             : {
     796         108 :   if (!engine)
     797           0 :     return gpg_error (GPG_ERR_INV_VALUE);
     798             : 
     799         108 :   if (!engine->ops->genkey)
     800           0 :     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
     801             : 
     802         108 :   return (*engine->ops->genkey) (engine->engine,
     803             :                                  userid, algo, reserved, expires, key, flags,
     804             :                                  help_data, extraflags,
     805             :                                  pubkey, seckey);
     806             : }
     807             : 
     808             : 
     809             : gpgme_error_t
     810           8 : _gpgme_engine_op_keysign (engine_t engine, gpgme_key_t key, const char *userid,
     811             :                           unsigned long expires, unsigned int flags,
     812             :                           gpgme_ctx_t ctx)
     813             : {
     814           8 :   if (!engine)
     815           0 :     return gpg_error (GPG_ERR_INV_VALUE);
     816             : 
     817           8 :   if (!engine->ops->keysign)
     818           0 :     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
     819             : 
     820           8 :   return (*engine->ops->keysign) (engine->engine,
     821             :                                   key, userid, expires, flags, ctx);
     822             : }
     823             : 
     824             : 
     825             : gpgme_error_t
     826          12 : _gpgme_engine_op_tofu_policy (engine_t engine,
     827             :                               gpgme_key_t key,  gpgme_tofu_policy_t policy)
     828             : {
     829          12 :   if (!engine)
     830           0 :     return gpg_error (GPG_ERR_INV_VALUE);
     831             : 
     832          12 :   if (!engine->ops->tofu_policy)
     833           0 :     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
     834             : 
     835          12 :   return (*engine->ops->tofu_policy) (engine->engine, key, policy);
     836             : }
     837             : 
     838             : 
     839             : gpgme_error_t
     840          16 : _gpgme_engine_op_import (engine_t engine, gpgme_data_t keydata,
     841             :                          gpgme_key_t *keyarray)
     842             : {
     843          16 :   if (!engine)
     844           0 :     return gpg_error (GPG_ERR_INV_VALUE);
     845             : 
     846          16 :   if (!engine->ops->import)
     847           0 :     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
     848             : 
     849          16 :   return (*engine->ops->import) (engine->engine, keydata, keyarray);
     850             : }
     851             : 
     852             : 
     853             : gpgme_error_t
     854         329 : _gpgme_engine_op_keylist (engine_t engine, const char *pattern,
     855             :                           int secret_only, gpgme_keylist_mode_t mode,
     856             :                           int engine_flags)
     857             : {
     858         329 :   if (!engine)
     859           0 :     return gpg_error (GPG_ERR_INV_VALUE);
     860             : 
     861         329 :   if (!engine->ops->keylist)
     862           0 :     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
     863             : 
     864         329 :   return (*engine->ops->keylist) (engine->engine, pattern, secret_only, mode,
     865             :                                   engine_flags);
     866             : }
     867             : 
     868             : 
     869             : gpgme_error_t
     870           0 : _gpgme_engine_op_keylist_ext (engine_t engine, const char *pattern[],
     871             :                               int secret_only, int reserved,
     872             :                               gpgme_keylist_mode_t mode, int engine_flags)
     873             : {
     874           0 :   if (!engine)
     875           0 :     return gpg_error (GPG_ERR_INV_VALUE);
     876             : 
     877           0 :   if (!engine->ops->keylist_ext)
     878           0 :     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
     879             : 
     880           0 :   return (*engine->ops->keylist_ext) (engine->engine, pattern, secret_only,
     881             :                                       reserved, mode, engine_flags);
     882             : }
     883             : 
     884             : 
     885             : gpgme_error_t
     886           5 : _gpgme_engine_op_keylist_data (engine_t engine, gpgme_data_t data)
     887             : {
     888           5 :   if (!engine)
     889           0 :     return gpg_error (GPG_ERR_INV_VALUE);
     890             : 
     891           5 :   if (!engine->ops->keylist_data)
     892           0 :     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
     893             : 
     894           5 :   return (*engine->ops->keylist_data) (engine->engine, data);
     895             : }
     896             : 
     897             : 
     898             : gpgme_error_t
     899          48 : _gpgme_engine_op_sign (engine_t engine, gpgme_data_t in, gpgme_data_t out,
     900             :                        gpgme_sig_mode_t mode, int use_armor,
     901             :                        int use_textmode, int include_certs,
     902             :                        gpgme_ctx_t ctx /* FIXME */)
     903             : {
     904          48 :   if (!engine)
     905           0 :     return gpg_error (GPG_ERR_INV_VALUE);
     906             : 
     907          48 :   if (!engine->ops->sign)
     908           0 :     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
     909             : 
     910          48 :   return (*engine->ops->sign) (engine->engine, in, out, mode, use_armor,
     911             :                                use_textmode, include_certs, ctx);
     912             : }
     913             : 
     914             : 
     915             : gpgme_error_t
     916           5 : _gpgme_engine_op_trustlist (engine_t engine, const char *pattern)
     917             : {
     918           5 :   if (!engine)
     919           0 :     return gpg_error (GPG_ERR_INV_VALUE);
     920             : 
     921           5 :   if (!engine->ops->trustlist)
     922           0 :     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
     923             : 
     924           5 :   return (*engine->ops->trustlist) (engine->engine, pattern);
     925             : }
     926             : 
     927             : 
     928             : gpgme_error_t
     929          59 : _gpgme_engine_op_verify (engine_t engine, gpgme_data_t sig,
     930             :                          gpgme_data_t signed_text, gpgme_data_t plaintext,
     931             :                          gpgme_ctx_t ctx)
     932             : {
     933          59 :   if (!engine)
     934           0 :     return gpg_error (GPG_ERR_INV_VALUE);
     935             : 
     936          59 :   if (!engine->ops->verify)
     937           0 :     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
     938             : 
     939          59 :   return (*engine->ops->verify) (engine->engine, sig, signed_text, plaintext,
     940             :                                  ctx);
     941             : }
     942             : 
     943             : 
     944             : gpgme_error_t
     945          32 : _gpgme_engine_op_getauditlog (engine_t engine, gpgme_data_t output,
     946             :                               unsigned int flags)
     947             : {
     948          32 :   if (!engine)
     949           0 :     return gpg_error (GPG_ERR_INV_VALUE);
     950             : 
     951          32 :   if (!engine->ops->getauditlog)
     952           0 :     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
     953             : 
     954          32 :   return (*engine->ops->getauditlog) (engine->engine, output, flags);
     955             : }
     956             : 
     957             : 
     958             : gpgme_error_t
     959          16 : _gpgme_engine_op_assuan_transact (engine_t engine,
     960             :                                   const char *command,
     961             :                                   gpgme_assuan_data_cb_t data_cb,
     962             :                                   void *data_cb_value,
     963             :                                   gpgme_assuan_inquire_cb_t inq_cb,
     964             :                                   void *inq_cb_value,
     965             :                                   gpgme_assuan_status_cb_t status_cb,
     966             :                                   void *status_cb_value)
     967             : {
     968          16 :   if (!engine)
     969           0 :     return gpg_error (GPG_ERR_INV_VALUE);
     970             : 
     971          16 :   if (!engine->ops->opassuan_transact)
     972           0 :     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
     973             : 
     974          16 :   return (*engine->ops->opassuan_transact) (engine->engine,
     975             :                                             command,
     976             :                                             data_cb, data_cb_value,
     977             :                                             inq_cb, inq_cb_value,
     978             :                                             status_cb, status_cb_value);
     979             : }
     980             : 
     981             : 
     982             : gpgme_error_t
     983          44 : _gpgme_engine_op_conf_load (engine_t engine, gpgme_conf_comp_t *conf_p)
     984             : {
     985          44 :   if (!engine)
     986           0 :     return gpg_error (GPG_ERR_INV_VALUE);
     987             : 
     988          44 :   if (!engine->ops->conf_load)
     989           0 :     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
     990             : 
     991          44 :   return (*engine->ops->conf_load) (engine->engine, conf_p);
     992             : }
     993             : 
     994             : 
     995             : gpgme_error_t
     996         152 : _gpgme_engine_op_conf_save (engine_t engine, gpgme_conf_comp_t conf)
     997             : {
     998         152 :   if (!engine)
     999           0 :     return gpg_error (GPG_ERR_INV_VALUE);
    1000             : 
    1001         152 :   if (!engine->ops->conf_save)
    1002           0 :     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
    1003             : 
    1004         152 :   return (*engine->ops->conf_save) (engine->engine, conf);
    1005             : }
    1006             : 
    1007             : 
    1008             : gpgme_error_t
    1009           2 : _gpgme_engine_op_conf_dir (engine_t engine, const char *what, char **result)
    1010             : {
    1011           2 :   if (!engine)
    1012           0 :     return gpg_error (GPG_ERR_INV_VALUE);
    1013             : 
    1014           2 :   if (!engine->ops->conf_dir)
    1015           0 :     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
    1016             : 
    1017           2 :   return (*engine->ops->conf_dir) (engine->engine, what, result);
    1018             : }
    1019             : 
    1020             : 
    1021             : gpgme_error_t
    1022           0 : _gpgme_engine_op_query_swdb (engine_t engine,
    1023             :                              const char *name, const char *iversion,
    1024             :                              gpgme_query_swdb_result_t result)
    1025             : {
    1026           0 :   if (!engine)
    1027           0 :     return gpg_error (GPG_ERR_INV_VALUE);
    1028             : 
    1029           0 :   if (!engine->ops->query_swdb)
    1030           0 :     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
    1031             : 
    1032           0 :   return (*engine->ops->query_swdb) (engine->engine, name, iversion, result);
    1033             : }
    1034             : 
    1035             : 
    1036             : void
    1037         959 : _gpgme_engine_set_io_cbs (engine_t engine, gpgme_io_cbs_t io_cbs)
    1038             : {
    1039         959 :   if (!engine)
    1040           0 :     return;
    1041             : 
    1042         959 :   (*engine->ops->set_io_cbs) (engine->engine, io_cbs);
    1043             : }
    1044             : 
    1045             : 
    1046             : void
    1047        2018 : _gpgme_engine_io_event (engine_t engine,
    1048             :                         gpgme_event_io_t type, void *type_data)
    1049             : {
    1050        2018 :   if (!engine)
    1051           0 :     return;
    1052             : 
    1053        2018 :   (*engine->ops->io_event) (engine->engine, type, type_data);
    1054             : }
    1055             : 
    1056             : 
    1057             : /* Cancel the session and the pending operation if any.  */
    1058             : gpgme_error_t
    1059          30 : _gpgme_engine_cancel (engine_t engine)
    1060             : {
    1061          30 :   if (!engine)
    1062           0 :     return gpg_error (GPG_ERR_INV_VALUE);
    1063             : 
    1064          30 :   if (!engine->ops->cancel)
    1065           0 :     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
    1066             : 
    1067          30 :   return (*engine->ops->cancel) (engine->engine);
    1068             : }
    1069             : 
    1070             : 
    1071             : /* Cancel the pending operation, but not the complete session.  */
    1072             : gpgme_error_t
    1073           2 : _gpgme_engine_cancel_op (engine_t engine)
    1074             : {
    1075           2 :   if (!engine)
    1076           0 :     return gpg_error (GPG_ERR_INV_VALUE);
    1077             : 
    1078           2 :   if (!engine->ops->cancel_op)
    1079           0 :     return 0;
    1080             : 
    1081           2 :   return (*engine->ops->cancel_op) (engine->engine);
    1082             : }
    1083             : 
    1084             : 
    1085             : /* Change the passphrase for KEY.  */
    1086             : gpgme_error_t
    1087           0 : _gpgme_engine_op_passwd (engine_t engine, gpgme_key_t key,
    1088             :                          unsigned int flags)
    1089             : {
    1090           0 :   if (!engine)
    1091           0 :     return gpg_error (GPG_ERR_INV_VALUE);
    1092             : 
    1093           0 :   if (!engine->ops->passwd)
    1094           0 :     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
    1095             : 
    1096           0 :   return (*engine->ops->passwd) (engine->engine, key, flags);
    1097             : }
    1098             : 
    1099             : 
    1100             : /* Set the pinentry mode for ENGINE to MODE.  */
    1101             : gpgme_error_t
    1102         943 : _gpgme_engine_set_pinentry_mode (engine_t engine, gpgme_pinentry_mode_t mode)
    1103             : {
    1104         943 :   if (!engine)
    1105           0 :     return gpg_error (GPG_ERR_INV_VALUE);
    1106             : 
    1107         943 :   if (!engine->ops->set_pinentry_mode)
    1108         212 :     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
    1109             : 
    1110         731 :   return (*engine->ops->set_pinentry_mode) (engine->engine, mode);
    1111             : }
    1112             : 
    1113             : 
    1114             : gpgme_error_t
    1115           0 : _gpgme_engine_op_spawn (engine_t engine,
    1116             :                         const char *file, const char *argv[],
    1117             :                         gpgme_data_t datain,
    1118             :                         gpgme_data_t dataout, gpgme_data_t dataerr,
    1119             :                         unsigned int flags)
    1120             : {
    1121           0 :   if (!engine)
    1122           0 :     return gpg_error (GPG_ERR_INV_VALUE);
    1123             : 
    1124           0 :   if (!engine->ops->opspawn)
    1125           0 :     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
    1126             : 
    1127           0 :   return (*engine->ops->opspawn) (engine->engine, file, argv,
    1128             :                                   datain, dataout, dataerr, flags);
    1129             : }

Generated by: LCOV version 1.13