LCOV - code coverage report
Current view: top level - src - op-support.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 96 175 54.9 %
Date: 2015-11-05 17:14:26 Functions: 3 5 60.0 %

          Line data    Source code
       1             : /* op-support.c - Supporting functions.
       2             :    Copyright (C) 2002, 2003, 2004, 2007 g10 Code GmbH
       3             : 
       4             :    This file is part of GPGME.
       5             : 
       6             :    GPGME is free software; you can redistribute it and/or modify it
       7             :    under the terms of the GNU Lesser General Public License as
       8             :    published by the Free Software Foundation; either version 2.1 of
       9             :    the License, or (at your option) any later version.
      10             : 
      11             :    GPGME is distributed in the hope that it will be useful, but
      12             :    WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      14             :    Lesser General Public License for more details.
      15             : 
      16             :    You should have received a copy of the GNU Lesser General Public
      17             :    License along with this program; if not, see <http://www.gnu.org/licenses/>.
      18             :  */
      19             : 
      20             : #if HAVE_CONFIG_H
      21             : #include <config.h>
      22             : #endif
      23             : #include <stdlib.h>
      24             : #include <errno.h>
      25             : #include <string.h>
      26             : #ifdef HAVE_LOCALE_H
      27             : #include <locale.h>
      28             : #endif
      29             : 
      30             : #include "gpgme.h"
      31             : #include "context.h"
      32             : #include "ops.h"
      33             : #include "util.h"
      34             : #include "debug.h"
      35             : 
      36             : 
      37             : gpgme_error_t
      38        2090 : _gpgme_op_data_lookup (gpgme_ctx_t ctx, ctx_op_data_id_t type, void **hook,
      39             :                        int size, void (*cleanup) (void *))
      40             : {
      41             :   struct ctx_op_data *data;
      42             : 
      43        2090 :   if (!ctx)
      44           0 :     return gpg_error (GPG_ERR_INV_VALUE);
      45             : 
      46        2090 :   data = ctx->op_data;
      47        4659 :   while (data && data->type != type)
      48         479 :     data = data->next;
      49        2090 :   if (!data)
      50             :     {
      51         178 :       if (size < 0)
      52             :         {
      53           0 :           *hook = NULL;
      54           0 :           return 0;
      55             :         }
      56             : 
      57         178 :       data = calloc (1, sizeof (struct ctx_op_data) + size);
      58         178 :       if (!data)
      59           0 :         return gpg_error_from_syserror ();
      60         178 :       data->magic = CTX_OP_DATA_MAGIC;
      61         178 :       data->next = ctx->op_data;
      62         178 :       data->type = type;
      63         178 :       data->cleanup = cleanup;
      64         178 :       data->hook = (void *) (((char *) data) + sizeof (struct ctx_op_data));
      65         178 :       data->references = 1;
      66         178 :       ctx->op_data = data;
      67             :     }
      68        2090 :   *hook = data->hook;
      69        2090 :   return 0;
      70             : }
      71             : 
      72             : 
      73             : /* type is: 0: asynchronous operation (use global or user event loop).
      74             :             1: synchronous operation (always use private event loop).
      75             :             2: asynchronous private operation (use private or user
      76             :             event loop).
      77             :             256: Modification flag to suppress the engine reset.
      78             : */
      79             : gpgme_error_t
      80         139 : _gpgme_op_reset (gpgme_ctx_t ctx, int type)
      81             : {
      82         139 :   gpgme_error_t err = 0;
      83             :   struct gpgme_io_cbs io_cbs;
      84         139 :   int no_reset = (type & 256);
      85         139 :   int reuse_engine = 0;
      86             : 
      87         139 :   type &= 255;
      88             : 
      89         139 :   _gpgme_release_result (ctx);
      90         139 :   LOCK (ctx->lock);
      91         139 :   ctx->canceled = 0;
      92         139 :   UNLOCK (ctx->lock);
      93             : 
      94         139 :   if (ctx->engine && no_reset)
      95           2 :     reuse_engine = 1;
      96         137 :   else if (ctx->engine)
      97             :     {
      98             :       /* Attempt to reset an existing engine.  */
      99             : 
     100          19 :       err = _gpgme_engine_reset (ctx->engine);
     101          19 :       if (gpg_err_code (err) == GPG_ERR_NOT_IMPLEMENTED)
     102             :         {
     103          15 :           _gpgme_engine_release (ctx->engine);
     104          15 :           ctx->engine = NULL;
     105             :         }
     106             :     }
     107             : 
     108         139 :   if (!ctx->engine)
     109             :     {
     110             :       gpgme_engine_info_t info;
     111         133 :       info = ctx->engine_info;
     112         274 :       while (info && info->protocol != ctx->protocol)
     113           8 :         info = info->next;
     114             : 
     115         133 :       if (!info)
     116           0 :         return gpg_error (GPG_ERR_UNSUPPORTED_PROTOCOL);
     117             : 
     118             :       /* Create an engine object.  */
     119         133 :       err = _gpgme_engine_new (info, &ctx->engine);
     120         133 :       if (err)
     121           0 :         return err;
     122             :     }
     123             : 
     124         139 :   if (!reuse_engine)
     125             :     {
     126         137 :       err = 0;
     127             : #ifdef LC_CTYPE
     128         137 :       err = _gpgme_engine_set_locale (ctx->engine, LC_CTYPE, ctx->lc_ctype);
     129             : #endif
     130             : #ifdef LC_MESSAGES
     131         137 :       if (!err)
     132         137 :         err = _gpgme_engine_set_locale (ctx->engine,
     133         137 :                                         LC_MESSAGES, ctx->lc_messages);
     134             : #endif
     135         137 :       if (gpg_err_code (err) == GPG_ERR_NOT_IMPLEMENTED)
     136           0 :         err = 0;
     137             : 
     138         137 :       if (!err)
     139             :         {
     140         137 :           err = _gpgme_engine_set_pinentry_mode (ctx->engine,
     141             :                                                  ctx->pinentry_mode);
     142         137 :           if (gpg_err_code (err) == GPG_ERR_NOT_IMPLEMENTED)
     143          12 :             err = 0;
     144             :         }
     145             : 
     146         137 :       if (err)
     147             :         {
     148           0 :           _gpgme_engine_release (ctx->engine);
     149           0 :           ctx->engine = NULL;
     150           0 :           return err;
     151             :         }
     152             :     }
     153             : 
     154         139 :   if (ctx->sub_protocol != GPGME_PROTOCOL_DEFAULT)
     155             :     {
     156           0 :       err = _gpgme_engine_set_protocol (ctx->engine, ctx->sub_protocol);
     157           0 :       if (err)
     158           0 :         return err;
     159             :     }
     160             : 
     161         139 :   if (type == 1 || (type == 2 && !ctx->io_cbs.add))
     162             :     {
     163             :       /* Use private event loop.  */
     164         137 :       io_cbs.add = _gpgme_add_io_cb;
     165         137 :       io_cbs.add_priv = ctx;
     166         137 :       io_cbs.remove = _gpgme_remove_io_cb;
     167         137 :       io_cbs.event = _gpgme_wait_private_event_cb;
     168         137 :       io_cbs.event_priv = ctx;
     169             :     }
     170           2 :   else if (! ctx->io_cbs.add)
     171             :     {
     172             :       /* Use global event loop.  */
     173           1 :       io_cbs.add = _gpgme_add_io_cb;
     174           1 :       io_cbs.add_priv = ctx;
     175           1 :       io_cbs.remove = _gpgme_remove_io_cb;
     176           1 :       io_cbs.event = _gpgme_wait_global_event_cb;
     177           1 :       io_cbs.event_priv = ctx;
     178             :     }
     179             :   else
     180             :     {
     181             :       /* Use user event loop.  */
     182           1 :       io_cbs.add = _gpgme_wait_user_add_io_cb;
     183           1 :       io_cbs.add_priv = ctx;
     184           1 :       io_cbs.remove = _gpgme_wait_user_remove_io_cb;
     185           1 :       io_cbs.event = _gpgme_wait_user_event_cb;
     186           1 :       io_cbs.event_priv = ctx;
     187             :     }
     188         139 :   _gpgme_engine_set_io_cbs (ctx->engine, &io_cbs);
     189         139 :   return err;
     190             : }
     191             : 
     192             : 
     193             : /* Parse the INV_RECP or INV-SNDR status line in ARGS and return the
     194             :    result in KEY.  */
     195             : gpgme_error_t
     196           0 : _gpgme_parse_inv_recp (char *args, gpgme_invalid_key_t *key)
     197             : {
     198             :   gpgme_invalid_key_t inv_key;
     199             :   char *tail;
     200             :   long int reason;
     201             : 
     202           0 :   inv_key = malloc (sizeof (*inv_key));
     203           0 :   if (!inv_key)
     204           0 :     return gpg_error_from_syserror ();
     205           0 :   inv_key->next = NULL;
     206           0 :   gpg_err_set_errno (0);
     207           0 :   reason = strtol (args, &tail, 0);
     208           0 :   if (errno || args == tail || (*tail && *tail != ' '))
     209             :     {
     210             :       /* The crypto backend does not behave.  */
     211           0 :       free (inv_key);
     212           0 :       return trace_gpg_error (GPG_ERR_INV_ENGINE);
     213             :     }
     214             : 
     215           0 :   switch (reason)
     216             :     {
     217             :     default:
     218             :     case 0:
     219           0 :       inv_key->reason = gpg_error (GPG_ERR_GENERAL);
     220           0 :       break;
     221             : 
     222             :     case 1:
     223           0 :       inv_key->reason = gpg_error (GPG_ERR_NO_PUBKEY);
     224           0 :       break;
     225             : 
     226             :     case 2:
     227           0 :       inv_key->reason = gpg_error (GPG_ERR_AMBIGUOUS_NAME);
     228           0 :       break;
     229             : 
     230             :     case 3:
     231           0 :       inv_key->reason = gpg_error (GPG_ERR_WRONG_KEY_USAGE);
     232           0 :       break;
     233             : 
     234             :     case 4:
     235           0 :       inv_key->reason = gpg_error (GPG_ERR_CERT_REVOKED);
     236           0 :       break;
     237             : 
     238             :     case 5:
     239           0 :       inv_key->reason = gpg_error (GPG_ERR_CERT_EXPIRED);
     240           0 :       break;
     241             : 
     242             :     case 6:
     243           0 :       inv_key->reason = gpg_error (GPG_ERR_NO_CRL_KNOWN);
     244           0 :       break;
     245             : 
     246             :     case 7:
     247           0 :       inv_key->reason = gpg_error (GPG_ERR_CRL_TOO_OLD);
     248           0 :       break;
     249             : 
     250             :     case 8:
     251           0 :       inv_key->reason = gpg_error (GPG_ERR_NO_POLICY_MATCH);
     252           0 :       break;
     253             : 
     254             :     case 9:
     255           0 :       inv_key->reason = gpg_error (GPG_ERR_NO_SECKEY);
     256           0 :       break;
     257             : 
     258             :     case 10:
     259           0 :       inv_key->reason = gpg_error (GPG_ERR_PUBKEY_NOT_TRUSTED);
     260           0 :       break;
     261             : 
     262             :     case 11:
     263           0 :       inv_key->reason = gpg_error (GPG_ERR_MISSING_CERT);
     264           0 :       break;
     265             : 
     266             :     case 12:
     267           0 :       inv_key->reason = gpg_error (GPG_ERR_MISSING_ISSUER_CERT);
     268           0 :       break;
     269             : 
     270             :     case 13:
     271           0 :       inv_key->reason = gpg_error (252); /*GPG_ERR_KEY_DISABLED*/
     272           0 :       break;
     273             : 
     274             :     case 14:
     275           0 :       inv_key->reason = gpg_error (GPG_ERR_INV_USER_ID);
     276           0 :       break;
     277             :     }
     278             : 
     279           0 :   while (*tail && *tail == ' ')
     280           0 :     tail++;
     281           0 :   if (*tail)
     282             :     {
     283           0 :       inv_key->fpr = strdup (tail);
     284           0 :       if (!inv_key->fpr)
     285             :         {
     286           0 :           free (inv_key);
     287           0 :           return gpg_error_from_syserror ();
     288             :         }
     289             :     }
     290             :   else
     291           0 :     inv_key->fpr = NULL;
     292             : 
     293           0 :   *key = inv_key;
     294           0 :   return 0;
     295             : }
     296             : 
     297             : 
     298             : /* Parse the PLAINTEXT status line in ARGS and return the result in
     299             :    FILENAMEP.  */
     300             : gpgme_error_t
     301          28 : _gpgme_parse_plaintext (char *args, char **filenamep)
     302             : {
     303             :   char *tail;
     304             : 
     305          56 :   while (*args == ' ')
     306           0 :     args++;
     307          28 :   if (*args == '\0')
     308           0 :     return 0;
     309             : 
     310             :   /* First argument is file type.  */
     311         112 :   while (*args != ' ' && *args != '\0')
     312          56 :     args++;
     313          84 :   while (*args == ' ')
     314          28 :     args++;
     315          28 :   if (*args == '\0')
     316           0 :     return 0;
     317             : 
     318             :   /* Second argument is the timestamp.  */
     319         315 :   while (*args != ' ' && *args != '\0')
     320         259 :     args++;
     321          84 :   while (*args == ' ')
     322          28 :     args++;
     323          28 :   if (*args == '\0')
     324          23 :     return 0;
     325             : 
     326           5 :   tail = args;
     327          40 :   while (*tail != ' ' && *tail != '\0')
     328          30 :     tail++;
     329           5 :   *tail = '\0';
     330           5 :   if (filenamep && *args != '\0')
     331             :     {
     332           5 :       char *filename = strdup (args);
     333           5 :       if (!filename)
     334           0 :         return gpg_error_from_syserror ();
     335             : 
     336           5 :       *filenamep = filename;
     337             :     }
     338           5 :   return 0;
     339             : }
     340             : 
     341             : 
     342             : /* Parse a FAILURE status line and return the error code.  ARGS is
     343             :    modified to contain the location part.  */
     344             : gpgme_error_t
     345           0 : _gpgme_parse_failure (char *args)
     346             : {
     347             :   char *where, *which;
     348             : 
     349           0 :   where = strchr (args, ' ');
     350           0 :   if (!where)
     351           0 :     return trace_gpg_error (GPG_ERR_INV_ENGINE);
     352             : 
     353           0 :   *where = '\0';
     354           0 :   which = where + 1;
     355             : 
     356           0 :   where = strchr (which, ' ');
     357           0 :   if (where)
     358           0 :     *where = '\0';
     359             : 
     360           0 :   where = args;
     361             : 
     362           0 :   return atoi (which);
     363             : }

Generated by: LCOV version 1.11