LCOV - code coverage report
Current view: top level - src - engine.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 263 433 60.7 %
Date: 2016-09-12 12:35:26 Functions: 36 46 78.3 %

          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 <http://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         392 : engine_get_file_name (gpgme_protocol_t proto)
      74             : {
      75         392 :   if (proto > DIM (engine_ops))
      76           0 :     return NULL;
      77             : 
      78         392 :   if (engine_ops[proto] && engine_ops[proto]->get_file_name)
      79         392 :     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         472 : engine_get_home_dir (gpgme_protocol_t proto)
      88             : {
      89         472 :   if (proto > DIM (engine_ops))
      90           0 :     return NULL;
      91             : 
      92         472 :   if (engine_ops[proto] && engine_ops[proto]->get_home_dir)
      93          56 :     return (*engine_ops[proto]->get_home_dir) ();
      94             :   else
      95         416 :     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         472 : engine_get_version (gpgme_protocol_t proto, const char *file_name)
     104             : {
     105         472 :   if (proto > DIM (engine_ops))
     106           0 :     return NULL;
     107             : 
     108         472 :   if (engine_ops[proto] && engine_ops[proto]->get_version)
     109         472 :     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         336 : engine_get_req_version (gpgme_protocol_t proto)
     119             : {
     120         336 :   if (proto > DIM (engine_ops))
     121           0 :     return NULL;
     122             : 
     123         336 :   if (engine_ops[proto] && engine_ops[proto]->get_req_version)
     124         336 :     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         115 : 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         115 :   LOCK (engine_info_lock);
     139         115 :   info = engine_info;
     140         115 :   if (!info)
     141             :     {
     142             :       /* Make sure it is initialized.  */
     143          52 :       UNLOCK (engine_info_lock);
     144          52 :       err = gpgme_get_engine_info (&info);
     145          52 :       if (err)
     146           0 :         return err;
     147             : 
     148          52 :       LOCK (engine_info_lock);
     149             :     }
     150             : 
     151         240 :   while (info && info->protocol != proto)
     152          10 :     info = info->next;
     153             : 
     154         115 :   if (!info)
     155           0 :     result = 0;
     156             :   else
     157         115 :     result = _gpgme_compare_versions (info->version,
     158         115 :                                       info->req_version);
     159             : 
     160         115 :   UNLOCK (engine_info_lock);
     161         115 :   return result ? 0 : trace_gpg_error (GPG_ERR_INV_ENGINE);
     162             : }
     163             : 
     164             : 
     165             : /* Release the engine info INFO.  */
     166             : void
     167         222 : _gpgme_engine_info_release (gpgme_engine_info_t info)
     168             : {
     169        1776 :   while (info)
     170             :     {
     171        1332 :       gpgme_engine_info_t next_info = info->next;
     172             : 
     173        1332 :       if (info->file_name)
     174        1332 :         free (info->file_name);
     175        1332 :       if (info->home_dir)
     176         222 :         free (info->home_dir);
     177        1332 :       if (info->version)
     178        1332 :         free (info->version);
     179        1332 :       free (info);
     180        1332 :       info = next_info;
     181             :     }
     182         222 : }
     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          60 : gpgme_get_engine_info (gpgme_engine_info_t *info)
     211             : {
     212             :   gpgme_error_t err;
     213             : 
     214          60 :   LOCK (engine_info_lock);
     215          60 :   if (!engine_info)
     216             :     {
     217          56 :       gpgme_engine_info_t *lastp = &engine_info;
     218          56 :       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          56 :       err = 0;
     228         448 :       for (proto = 0; proto < DIM (proto_list); proto++)
     229             :         {
     230         392 :           const char *ofile_name = engine_get_file_name (proto_list[proto]);
     231         392 :           const char *ohome_dir  = engine_get_home_dir (proto_list[proto]);
     232         392 :           char *version = engine_get_version (proto_list[proto], NULL);
     233             :           char *file_name;
     234             :           char *home_dir;
     235             : 
     236         392 :           if (!ofile_name)
     237          56 :             continue;
     238             : 
     239         336 :           file_name = strdup (ofile_name);
     240         336 :           if (!file_name)
     241           0 :             err = gpg_error_from_syserror ();
     242             : 
     243         336 :           if (ohome_dir)
     244             :             {
     245          56 :               home_dir = strdup (ohome_dir);
     246          56 :               if (!home_dir && !err)
     247           0 :                 err = gpg_error_from_syserror ();
     248             :             }
     249             :           else
     250         280 :             home_dir = NULL;
     251             : 
     252         336 :           *lastp = calloc (1, sizeof (*engine_info));
     253         336 :           if (!*lastp && !err)
     254           0 :             err = gpg_error_from_syserror ();
     255             : 
     256             :           /* Check against the optional minimal engine version.  */
     257         336 :           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         336 :           if (!err && !version)
     269             :             {
     270         168 :               version = strdup ("1.0.0");
     271         168 :               if (!version)
     272           0 :                 err = gpg_error_from_syserror ();
     273             :             }
     274             : 
     275         336 :           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         336 :           (*lastp)->protocol = proto_list[proto];
     292         336 :           (*lastp)->file_name = file_name;
     293         336 :           (*lastp)->home_dir = home_dir;
     294         336 :           (*lastp)->version = version;
     295         336 :           (*lastp)->req_version = engine_get_req_version (proto_list[proto]);
     296         336 :           if (!(*lastp)->req_version)
     297         168 :             (*lastp)->req_version = "1.0.0"; /* Dummy for pseudo engines. */
     298         336 :           (*lastp)->next = NULL;
     299         336 :           lastp = &(*lastp)->next;
     300             :         }
     301             :     }
     302             : 
     303          60 :   *info = engine_info;
     304          60 :   UNLOCK (engine_info_lock);
     305          60 :   return 0;
     306             : }
     307             : 
     308             : 
     309             : /* Get a deep copy of the engine info and return it in INFO.  */
     310             : gpgme_error_t
     311         225 : _gpgme_engine_info_copy (gpgme_engine_info_t *r_info)
     312             : {
     313         225 :   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         225 :   LOCK (engine_info_lock);
     319         225 :   info = engine_info;
     320         225 :   if (!info)
     321             :     {
     322             :       /* Make sure it is initialized.  */
     323           1 :       UNLOCK (engine_info_lock);
     324           1 :       err = gpgme_get_engine_info (&info);
     325           1 :       if (err)
     326           0 :         return err;
     327             : 
     328           1 :       LOCK (engine_info_lock);
     329             :     }
     330             : 
     331         225 :   new_info = NULL;
     332         225 :   lastp = &new_info;
     333             : 
     334        1800 :   while (info)
     335             :     {
     336             :       char *file_name;
     337             :       char *home_dir;
     338             :       char *version;
     339             : 
     340        1350 :       assert (info->file_name);
     341        1350 :       file_name = strdup (info->file_name);
     342        1350 :       if (!file_name)
     343           0 :         err = gpg_error_from_syserror ();
     344             : 
     345        1350 :       if (info->home_dir)
     346             :         {
     347         225 :           home_dir = strdup (info->home_dir);
     348         225 :           if (!home_dir && !err)
     349           0 :             err = gpg_error_from_syserror ();
     350             :         }
     351             :       else
     352        1125 :         home_dir = NULL;
     353             : 
     354        1350 :       if (info->version)
     355             :         {
     356        1350 :           version = strdup (info->version);
     357        1350 :           if (!version && !err)
     358           0 :             err = gpg_error_from_syserror ();
     359             :         }
     360             :       else
     361           0 :         version = NULL;
     362             : 
     363        1350 :       *lastp = malloc (sizeof (*engine_info));
     364        1350 :       if (!*lastp && !err)
     365           0 :         err = gpg_error_from_syserror ();
     366             : 
     367        1350 :       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        1350 :       (*lastp)->protocol = info->protocol;
     382        1350 :       (*lastp)->file_name = file_name;
     383        1350 :       (*lastp)->home_dir = home_dir;
     384        1350 :       (*lastp)->version = version;
     385        1350 :       (*lastp)->req_version = info->req_version;
     386        1350 :       (*lastp)->next = NULL;
     387        1350 :       lastp = &(*lastp)->next;
     388             : 
     389        1350 :       info = info->next;
     390             :     }
     391             : 
     392         225 :   *r_info = new_info;
     393         225 :   UNLOCK (engine_info_lock);
     394         225 :   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          80 : _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          80 :   if (proto > DIM (engine_ops))
     410           0 :     return gpg_error (GPG_ERR_INV_VALUE);
     411             : 
     412         161 :   while (info && info->protocol != proto)
     413           1 :     info = info->next;
     414             : 
     415          80 :   if (!info)
     416           0 :     return trace_gpg_error (GPG_ERR_INV_ENGINE);
     417             : 
     418             :   /* Prepare new members.  */
     419          80 :   if (file_name)
     420          80 :     new_file_name = strdup (file_name);
     421             :   else
     422             :     {
     423           0 :       const char *ofile_name = engine_get_file_name (proto);
     424           0 :       assert (ofile_name);
     425           0 :       new_file_name = strdup (ofile_name);
     426             :     }
     427          80 :   if (!new_file_name)
     428           0 :     return gpg_error_from_syserror ();
     429             : 
     430          80 :   if (home_dir)
     431             :     {
     432           0 :       new_home_dir = strdup (home_dir);
     433           0 :       if (!new_home_dir)
     434             :         {
     435           0 :           free (new_file_name);
     436           0 :           return gpg_error_from_syserror ();
     437             :         }
     438             :     }
     439             :   else
     440             :     {
     441          80 :       const char *ohome_dir = engine_get_home_dir (proto);
     442          80 :       if (ohome_dir)
     443             :         {
     444           0 :           new_home_dir = strdup (ohome_dir);
     445           0 :           if (!new_home_dir)
     446             :             {
     447           0 :               free (new_file_name);
     448           0 :               return gpg_error_from_syserror ();
     449             :             }
     450             :         }
     451             :       else
     452          80 :         new_home_dir = NULL;
     453             :     }
     454             : 
     455          80 :   new_version = engine_get_version (proto, new_file_name);
     456          80 :   if (!new_version)
     457             :     {
     458           0 :       new_version = strdup ("1.0.0"); /* Fake one for dummy entries.  */
     459           0 :       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          80 :   assert (info->file_name);
     468          80 :   free (info->file_name);
     469          80 :   if (info->home_dir)
     470           0 :     free (info->home_dir);
     471          80 :   if (info->version)
     472          80 :     free (info->version);
     473             : 
     474             :   /* Install the new members.  */
     475          80 :   info->file_name = new_file_name;
     476          80 :   info->home_dir = new_home_dir;
     477          80 :   info->version = new_version;
     478             : 
     479          80 :   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         275 : _gpgme_engine_new (gpgme_engine_info_t info, engine_t *r_engine)
     513             : {
     514             :   engine_t engine;
     515             : 
     516         275 :   if (!info->file_name || !info->version)
     517           0 :     return trace_gpg_error (GPG_ERR_INV_ENGINE);
     518             : 
     519         275 :   engine = calloc (1, sizeof *engine);
     520         275 :   if (!engine)
     521           0 :     return gpg_error_from_syserror ();
     522             : 
     523         275 :   engine->ops = engine_ops[info->protocol];
     524         275 :   if (engine->ops->new)
     525             :     {
     526             :       gpgme_error_t err;
     527         550 :       err = (*engine->ops->new) (&engine->engine,
     528         275 :                                  info->file_name, info->home_dir,
     529         275 :                                  info->version);
     530         275 :       if (err)
     531             :         {
     532           0 :           free (engine);
     533           0 :           return err;
     534             :         }
     535             :     }
     536             :   else
     537           0 :     engine->engine = NULL;
     538             : 
     539         275 :   *r_engine = engine;
     540         275 :   return 0;
     541             : }
     542             : 
     543             : 
     544             : gpgme_error_t
     545          60 : _gpgme_engine_reset (engine_t engine)
     546             : {
     547          60 :   if (!engine)
     548           0 :     return gpg_error (GPG_ERR_INV_VALUE);
     549             : 
     550          60 :   if (!engine->ops->reset)
     551          56 :     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
     552             : 
     553           4 :   return (*engine->ops->reset) (engine->engine);
     554             : }
     555             : 
     556             : 
     557             : void
     558         278 : _gpgme_engine_release (engine_t engine)
     559             : {
     560         278 :   if (!engine)
     561         285 :     return;
     562             : 
     563         271 :   if (engine->ops->release)
     564         271 :     (*engine->ops->release) (engine->engine);
     565         271 :   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           2 : _gpgme_engine_set_status_cb (engine_t engine,
     574             :                              gpgme_status_cb_t cb, void *cb_value)
     575             : {
     576           2 :   if (!engine)
     577           2 :     return;
     578             : 
     579           2 :   if (engine->ops->set_status_cb)
     580           2 :     (*engine->ops->set_status_cb) (engine->engine, cb, cb_value);
     581             : }
     582             : 
     583             : 
     584             : void
     585         302 : _gpgme_engine_set_status_handler (engine_t engine,
     586             :                                   engine_status_handler_t fnc, void *fnc_value)
     587             : {
     588         302 :   if (!engine)
     589         302 :     return;
     590             : 
     591         302 :   if (engine->ops->set_status_handler)
     592         302 :     (*engine->ops->set_status_handler) (engine->engine, fnc, fnc_value);
     593             : }
     594             : 
     595             : 
     596             : gpgme_error_t
     597          63 : _gpgme_engine_set_command_handler (engine_t engine,
     598             :                                    engine_command_handler_t fnc,
     599             :                                    void *fnc_value,
     600             :                                    gpgme_data_t linked_data)
     601             : {
     602          63 :   if (!engine)
     603           0 :     return gpg_error (GPG_ERR_INV_VALUE);
     604             : 
     605          63 :   if (!engine->ops->set_command_handler)
     606           0 :     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
     607             : 
     608          63 :   return (*engine->ops->set_command_handler) (engine->engine,
     609             :                                               fnc, fnc_value, linked_data);
     610             : }
     611             : 
     612             : gpgme_error_t
     613         102 : _gpgme_engine_set_colon_line_handler (engine_t engine,
     614             :                                       engine_colon_line_handler_t fnc,
     615             :                                       void *fnc_value)
     616             : {
     617         102 :   if (!engine)
     618           0 :     return gpg_error (GPG_ERR_INV_VALUE);
     619             : 
     620         102 :   if (!engine->ops->set_colon_line_handler)
     621           0 :     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
     622             : 
     623         102 :   return (*engine->ops->set_colon_line_handler) (engine->engine,
     624             :                                                  fnc, fnc_value);
     625             : }
     626             : 
     627             : gpgme_error_t
     628         558 : _gpgme_engine_set_locale (engine_t engine, int category,
     629             :                           const char *value)
     630             : {
     631         558 :   if (!engine)
     632           0 :     return gpg_error (GPG_ERR_INV_VALUE);
     633             : 
     634         558 :   if (!engine->ops->set_locale)
     635           0 :     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
     636             : 
     637         558 :   return (*engine->ops->set_locale) (engine->engine, category, value);
     638             : }
     639             : 
     640             : 
     641             : gpgme_error_t
     642           0 : _gpgme_engine_set_protocol (engine_t engine, gpgme_protocol_t protocol)
     643             : {
     644           0 :   if (!engine)
     645           0 :     return gpg_error (GPG_ERR_INV_VALUE);
     646             : 
     647           0 :   if (!engine->ops->set_protocol)
     648           0 :     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
     649             : 
     650           0 :   return (*engine->ops->set_protocol) (engine->engine, protocol);
     651             : }
     652             : 
     653             : 
     654             : gpgme_error_t
     655          29 : _gpgme_engine_op_decrypt (engine_t engine, gpgme_data_t ciph,
     656             :                           gpgme_data_t plain)
     657             : {
     658          29 :   if (!engine)
     659           0 :     return gpg_error (GPG_ERR_INV_VALUE);
     660             : 
     661          29 :   if (!engine->ops->decrypt)
     662           0 :     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
     663             : 
     664          29 :   return (*engine->ops->decrypt) (engine->engine, ciph, plain);
     665             : }
     666             : 
     667             : 
     668             : gpgme_error_t
     669           7 : _gpgme_engine_op_decrypt_verify (engine_t engine, gpgme_data_t ciph,
     670             :                                  gpgme_data_t plain)
     671             : {
     672           7 :   if (!engine)
     673           0 :     return gpg_error (GPG_ERR_INV_VALUE);
     674             : 
     675           7 :   if (!engine->ops->decrypt_verify)
     676           0 :     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
     677             : 
     678           7 :   return (*engine->ops->decrypt_verify) (engine->engine, ciph, plain);
     679             : }
     680             : 
     681             : 
     682             : gpgme_error_t
     683           0 : _gpgme_engine_op_delete (engine_t engine, gpgme_key_t key,
     684             :                          int allow_secret)
     685             : {
     686           0 :   if (!engine)
     687           0 :     return gpg_error (GPG_ERR_INV_VALUE);
     688             : 
     689           0 :   if (!engine->ops->delete)
     690           0 :     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
     691             : 
     692           0 :   return (*engine->ops->delete) (engine->engine, key, allow_secret);
     693             : }
     694             : 
     695             : 
     696             : gpgme_error_t
     697           7 : _gpgme_engine_op_edit (engine_t engine, int type, gpgme_key_t key,
     698             :                        gpgme_data_t out, gpgme_ctx_t ctx /* FIXME */)
     699             : {
     700           7 :   if (!engine)
     701           0 :     return gpg_error (GPG_ERR_INV_VALUE);
     702             : 
     703           7 :   if (!engine->ops->edit)
     704           0 :     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
     705             : 
     706           7 :   return (*engine->ops->edit) (engine->engine, type, key, out, ctx);
     707             : }
     708             : 
     709             : 
     710             : gpgme_error_t
     711          47 : _gpgme_engine_op_encrypt (engine_t engine, gpgme_key_t recp[],
     712             :                           gpgme_encrypt_flags_t flags,
     713             :                           gpgme_data_t plain, gpgme_data_t ciph, int use_armor)
     714             : {
     715          47 :   if (!engine)
     716           0 :     return gpg_error (GPG_ERR_INV_VALUE);
     717             : 
     718          47 :   if (!engine->ops->encrypt)
     719           0 :     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
     720             : 
     721          47 :   return (*engine->ops->encrypt) (engine->engine, recp, flags, plain, ciph,
     722             :                                   use_armor);
     723             : }
     724             : 
     725             : 
     726             : gpgme_error_t
     727           7 : _gpgme_engine_op_encrypt_sign (engine_t engine, gpgme_key_t recp[],
     728             :                                gpgme_encrypt_flags_t flags,
     729             :                                gpgme_data_t plain, gpgme_data_t ciph,
     730             :                                int use_armor, gpgme_ctx_t ctx /* FIXME */)
     731             : {
     732           7 :   if (!engine)
     733           0 :     return gpg_error (GPG_ERR_INV_VALUE);
     734             : 
     735           7 :   if (!engine->ops->encrypt_sign)
     736           0 :     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
     737             : 
     738           7 :   return (*engine->ops->encrypt_sign) (engine->engine, recp, flags,
     739             :                                        plain, ciph, use_armor, ctx);
     740             : }
     741             : 
     742             : 
     743             : gpgme_error_t
     744           0 : _gpgme_engine_op_export (engine_t engine, const char *pattern,
     745             :                          gpgme_export_mode_t mode, gpgme_data_t keydata,
     746             :                          int use_armor)
     747             : {
     748           0 :   if (!engine)
     749           0 :     return gpg_error (GPG_ERR_INV_VALUE);
     750             : 
     751           0 :   if (!engine->ops->export)
     752           0 :     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
     753             : 
     754           0 :   return (*engine->ops->export) (engine->engine, pattern, mode,
     755             :                                  keydata, use_armor);
     756             : }
     757             : 
     758             : 
     759             : gpgme_error_t
     760           6 : _gpgme_engine_op_export_ext (engine_t engine, const char *pattern[],
     761             :                              unsigned int reserved, gpgme_data_t keydata,
     762             :                              int use_armor)
     763             : {
     764           6 :   if (!engine)
     765           0 :     return gpg_error (GPG_ERR_INV_VALUE);
     766             : 
     767           6 :   if (!engine->ops->export_ext)
     768           0 :     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
     769             : 
     770           6 :   return (*engine->ops->export_ext) (engine->engine, pattern, reserved,
     771             :                                      keydata, use_armor);
     772             : }
     773             : 
     774             : 
     775             : gpgme_error_t
     776           2 : _gpgme_engine_op_genkey (engine_t engine, gpgme_data_t help_data,
     777             :                          int use_armor, gpgme_data_t pubkey,
     778             :                          gpgme_data_t seckey)
     779             : {
     780           2 :   if (!engine)
     781           0 :     return gpg_error (GPG_ERR_INV_VALUE);
     782             : 
     783           2 :   if (!engine->ops->genkey)
     784           0 :     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
     785             : 
     786           2 :   return (*engine->ops->genkey) (engine->engine, help_data, use_armor,
     787             :                                  pubkey, seckey);
     788             : }
     789             : 
     790             : 
     791             : gpgme_error_t
     792           8 : _gpgme_engine_op_import (engine_t engine, gpgme_data_t keydata,
     793             :                          gpgme_key_t *keyarray)
     794             : {
     795           8 :   if (!engine)
     796           0 :     return gpg_error (GPG_ERR_INV_VALUE);
     797             : 
     798           8 :   if (!engine->ops->import)
     799           0 :     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
     800             : 
     801           8 :   return (*engine->ops->import) (engine->engine, keydata, keyarray);
     802             : }
     803             : 
     804             : 
     805             : gpgme_error_t
     806          99 : _gpgme_engine_op_keylist (engine_t engine, const char *pattern,
     807             :                           int secret_only, gpgme_keylist_mode_t mode,
     808             :                           int engine_flags)
     809             : {
     810          99 :   if (!engine)
     811           0 :     return gpg_error (GPG_ERR_INV_VALUE);
     812             : 
     813          99 :   if (!engine->ops->keylist)
     814           0 :     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
     815             : 
     816          99 :   return (*engine->ops->keylist) (engine->engine, pattern, secret_only, mode,
     817             :                                   engine_flags);
     818             : }
     819             : 
     820             : 
     821             : gpgme_error_t
     822           0 : _gpgme_engine_op_keylist_ext (engine_t engine, const char *pattern[],
     823             :                               int secret_only, int reserved,
     824             :                               gpgme_keylist_mode_t mode, int engine_flags)
     825             : {
     826           0 :   if (!engine)
     827           0 :     return gpg_error (GPG_ERR_INV_VALUE);
     828             : 
     829           0 :   if (!engine->ops->keylist_ext)
     830           0 :     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
     831             : 
     832           0 :   return (*engine->ops->keylist_ext) (engine->engine, pattern, secret_only,
     833             :                                       reserved, mode, engine_flags);
     834             : }
     835             : 
     836             : 
     837             : gpgme_error_t
     838          32 : _gpgme_engine_op_sign (engine_t engine, gpgme_data_t in, gpgme_data_t out,
     839             :                        gpgme_sig_mode_t mode, int use_armor,
     840             :                        int use_textmode, int include_certs,
     841             :                        gpgme_ctx_t ctx /* FIXME */)
     842             : {
     843          32 :   if (!engine)
     844           0 :     return gpg_error (GPG_ERR_INV_VALUE);
     845             : 
     846          32 :   if (!engine->ops->sign)
     847           0 :     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
     848             : 
     849          32 :   return (*engine->ops->sign) (engine->engine, in, out, mode, use_armor,
     850             :                                use_textmode, include_certs, ctx);
     851             : }
     852             : 
     853             : 
     854             : gpgme_error_t
     855           3 : _gpgme_engine_op_trustlist (engine_t engine, const char *pattern)
     856             : {
     857           3 :   if (!engine)
     858           0 :     return gpg_error (GPG_ERR_INV_VALUE);
     859             : 
     860           3 :   if (!engine->ops->trustlist)
     861           0 :     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
     862             : 
     863           3 :   return (*engine->ops->trustlist) (engine->engine, pattern);
     864             : }
     865             : 
     866             : 
     867             : gpgme_error_t
     868          31 : _gpgme_engine_op_verify (engine_t engine, gpgme_data_t sig,
     869             :                          gpgme_data_t signed_text, gpgme_data_t plaintext)
     870             : {
     871          31 :   if (!engine)
     872           0 :     return gpg_error (GPG_ERR_INV_VALUE);
     873             : 
     874          31 :   if (!engine->ops->verify)
     875           0 :     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
     876             : 
     877          31 :   return (*engine->ops->verify) (engine->engine, sig, signed_text, plaintext);
     878             : }
     879             : 
     880             : 
     881             : gpgme_error_t
     882          24 : _gpgme_engine_op_getauditlog (engine_t engine, gpgme_data_t output,
     883             :                               unsigned int flags)
     884             : {
     885          24 :   if (!engine)
     886           0 :     return gpg_error (GPG_ERR_INV_VALUE);
     887             : 
     888          24 :   if (!engine->ops->getauditlog)
     889          22 :     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
     890             : 
     891           2 :   return (*engine->ops->getauditlog) (engine->engine, output, flags);
     892             : }
     893             : 
     894             : 
     895             : gpgme_error_t
     896           8 : _gpgme_engine_op_assuan_transact (engine_t engine,
     897             :                                   const char *command,
     898             :                                   gpgme_assuan_data_cb_t data_cb,
     899             :                                   void *data_cb_value,
     900             :                                   gpgme_assuan_inquire_cb_t inq_cb,
     901             :                                   void *inq_cb_value,
     902             :                                   gpgme_assuan_status_cb_t status_cb,
     903             :                                   void *status_cb_value)
     904             : {
     905           8 :   if (!engine)
     906           0 :     return gpg_error (GPG_ERR_INV_VALUE);
     907             : 
     908           8 :   if (!engine->ops->opassuan_transact)
     909           0 :     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
     910             : 
     911           8 :   return (*engine->ops->opassuan_transact) (engine->engine,
     912             :                                             command,
     913             :                                             data_cb, data_cb_value,
     914             :                                             inq_cb, inq_cb_value,
     915             :                                             status_cb, status_cb_value);
     916             : }
     917             : 
     918             : 
     919             : gpgme_error_t
     920           0 : _gpgme_engine_op_conf_load (engine_t engine, gpgme_conf_comp_t *conf_p)
     921             : {
     922           0 :   if (!engine)
     923           0 :     return gpg_error (GPG_ERR_INV_VALUE);
     924             : 
     925           0 :   if (!engine->ops->conf_load)
     926           0 :     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
     927             : 
     928           0 :   return (*engine->ops->conf_load) (engine->engine, conf_p);
     929             : }
     930             : 
     931             : 
     932             : gpgme_error_t
     933           0 : _gpgme_engine_op_conf_save (engine_t engine, gpgme_conf_comp_t conf)
     934             : {
     935           0 :   if (!engine)
     936           0 :     return gpg_error (GPG_ERR_INV_VALUE);
     937             : 
     938           0 :   if (!engine->ops->conf_save)
     939           0 :     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
     940             : 
     941           0 :   return (*engine->ops->conf_save) (engine->engine, conf);
     942             : }
     943             : 
     944             : 
     945             : void
     946         310 : _gpgme_engine_set_io_cbs (engine_t engine, gpgme_io_cbs_t io_cbs)
     947             : {
     948         310 :   if (!engine)
     949         310 :     return;
     950             : 
     951         310 :   (*engine->ops->set_io_cbs) (engine->engine, io_cbs);
     952             : }
     953             : 
     954             : 
     955             : void
     956         566 : _gpgme_engine_io_event (engine_t engine,
     957             :                         gpgme_event_io_t type, void *type_data)
     958             : {
     959         566 :   if (!engine)
     960         566 :     return;
     961             : 
     962         566 :   (*engine->ops->io_event) (engine->engine, type, type_data);
     963             : }
     964             : 
     965             : 
     966             : /* Cancel the session and the pending operation if any.  */
     967             : gpgme_error_t
     968          13 : _gpgme_engine_cancel (engine_t engine)
     969             : {
     970          13 :   if (!engine)
     971           0 :     return gpg_error (GPG_ERR_INV_VALUE);
     972             : 
     973          13 :   if (!engine->ops->cancel)
     974           0 :     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
     975             : 
     976          13 :   return (*engine->ops->cancel) (engine->engine);
     977             : }
     978             : 
     979             : 
     980             : /* Cancel the pending operation, but not the complete session.  */
     981             : gpgme_error_t
     982           1 : _gpgme_engine_cancel_op (engine_t engine)
     983             : {
     984           1 :   if (!engine)
     985           0 :     return gpg_error (GPG_ERR_INV_VALUE);
     986             : 
     987           1 :   if (!engine->ops->cancel_op)
     988           0 :     return 0;
     989             : 
     990           1 :   return (*engine->ops->cancel_op) (engine->engine);
     991             : }
     992             : 
     993             : 
     994             : /* Change the passphrase for KEY.  */
     995             : gpgme_error_t
     996           0 : _gpgme_engine_op_passwd (engine_t engine, gpgme_key_t key,
     997             :                          unsigned int flags)
     998             : {
     999           0 :   if (!engine)
    1000           0 :     return gpg_error (GPG_ERR_INV_VALUE);
    1001             : 
    1002           0 :   if (!engine->ops->passwd)
    1003           0 :     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
    1004             : 
    1005           0 :   return (*engine->ops->passwd) (engine->engine, key, flags);
    1006             : }
    1007             : 
    1008             : 
    1009             : /* Set the pinentry mode for ENGINE to MODE.  */
    1010             : gpgme_error_t
    1011         279 : _gpgme_engine_set_pinentry_mode (engine_t engine, gpgme_pinentry_mode_t mode)
    1012             : {
    1013         279 :   if (!engine)
    1014           0 :     return gpg_error (GPG_ERR_INV_VALUE);
    1015             : 
    1016         279 :   if (!engine->ops->set_pinentry_mode)
    1017          13 :     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
    1018             : 
    1019         266 :   return (*engine->ops->set_pinentry_mode) (engine->engine, mode);
    1020             : }
    1021             : 
    1022             : 
    1023             : gpgme_error_t
    1024           0 : _gpgme_engine_op_spawn (engine_t engine,
    1025             :                         const char *file, const char *argv[],
    1026             :                         gpgme_data_t datain,
    1027             :                         gpgme_data_t dataout, gpgme_data_t dataerr,
    1028             :                         unsigned int flags)
    1029             : {
    1030           0 :   if (!engine)
    1031           0 :     return gpg_error (GPG_ERR_INV_VALUE);
    1032             : 
    1033           0 :   if (!engine->ops->opspawn)
    1034           0 :     return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
    1035             : 
    1036           0 :   return (*engine->ops->opspawn) (engine->engine, file, argv,
    1037             :                                   datain, dataout, dataerr, flags);
    1038             : }

Generated by: LCOV version 1.11