LCOV - code coverage report
Current view: top level - src - passwd.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 71 0.0 %
Date: 2018-11-14 16:53:58 Functions: 0 5 0.0 %

          Line data    Source code
       1             : /* passwd.c - Passphrase changing function
       2             :    Copyright (C) 2010 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 <https://www.gnu.org/licenses/>.
      18             :  */
      19             : 
      20             : #if HAVE_CONFIG_H
      21             : #include <config.h>
      22             : #endif
      23             : #include <stdlib.h>
      24             : 
      25             : #include "gpgme.h"
      26             : #include "debug.h"
      27             : #include "context.h"
      28             : #include "ops.h"
      29             : 
      30             : 
      31             : typedef struct
      32             : {
      33             :   /* The error code from a FAILURE status line or 0.  */
      34             :   gpg_error_t failure_code;
      35             : 
      36             :   int success_seen;
      37             :   int error_seen;
      38             : } *op_data_t;
      39             : 
      40             : 
      41             : 
      42             : /* Parse an error status line and return the error code.  */
      43             : static gpgme_error_t
      44           0 : parse_error (char *args)
      45             : {
      46             :   gpgme_error_t err;
      47           0 :   char *where = strchr (args, ' ');
      48             :   char *which;
      49             : 
      50           0 :   if (where)
      51             :     {
      52           0 :       *where = '\0';
      53           0 :       which = where + 1;
      54             : 
      55           0 :       where = strchr (which, ' ');
      56           0 :       if (where)
      57           0 :         *where = '\0';
      58             : 
      59           0 :       where = args;
      60             :     }
      61             :   else
      62           0 :     return trace_gpg_error (GPG_ERR_INV_ENGINE);
      63             : 
      64           0 :   err = atoi (which);
      65             : 
      66           0 :   if (!strcmp (where, "keyedit.passwd"))
      67           0 :     return err;
      68             : 
      69           0 :   return 0;
      70             : }
      71             : 
      72             : 
      73             : static gpgme_error_t
      74           0 : passwd_status_handler (void *priv, gpgme_status_code_t code, char *args)
      75             : {
      76           0 :   gpgme_ctx_t ctx = (gpgme_ctx_t) priv;
      77             :   gpgme_error_t err;
      78             :   void *hook;
      79             :   op_data_t opd;
      80             : 
      81           0 :   err = _gpgme_op_data_lookup (ctx, OPDATA_PASSWD, &hook, -1, NULL);
      82           0 :   opd = hook;
      83           0 :   if (err)
      84           0 :     return err;
      85             : 
      86           0 :   switch (code)
      87             :     {
      88             :     case GPGME_STATUS_ERROR:
      89           0 :       err = parse_error (args);
      90           0 :       if (err)
      91           0 :         opd->error_seen = 1;
      92           0 :       break;
      93             : 
      94             :     case GPGME_STATUS_SUCCESS:
      95           0 :       opd->success_seen = 1;
      96           0 :       break;
      97             : 
      98             :     case GPGME_STATUS_FAILURE:
      99           0 :       opd->failure_code = _gpgme_parse_failure (args);
     100           0 :       break;
     101             : 
     102             :     case GPGME_STATUS_EOF:
     103             :       /* In case the OpenPGP engine does not properly implement the
     104             :          passwd command we won't get a success status back and thus we
     105             :          conclude that this operation is not supported.  This is for
     106             :          example the case for GnuPG < 2.0.16.  Note that this test is
     107             :          obsolete for assuan based engines because they will properly
     108             :          return an error for an unknown command.  */
     109           0 :       if (ctx->protocol == GPGME_PROTOCOL_OpenPGP
     110           0 :           && !opd->error_seen && !opd->success_seen)
     111           0 :         err = gpg_error (GPG_ERR_NOT_SUPPORTED);
     112           0 :       else if (opd->failure_code)
     113           0 :         err = opd->failure_code;
     114           0 :       break;
     115             : 
     116             :     default:
     117           0 :       break;
     118             :     }
     119             : 
     120           0 :   return err;
     121             : }
     122             : 
     123             : 
     124             : static gpgme_error_t
     125           0 : passwd_start (gpgme_ctx_t ctx, int synchronous, gpgme_key_t key,
     126             :               unsigned int flags)
     127             : {
     128             :   gpgme_error_t err;
     129             :   void *hook;
     130             :   op_data_t opd;
     131             : 
     132           0 :   if (!key)
     133           0 :     return gpg_error (GPG_ERR_INV_VALUE);
     134           0 :   if (flags)
     135           0 :     return gpg_error (GPG_ERR_INV_FLAG);
     136             : 
     137           0 :   err = _gpgme_op_reset (ctx, synchronous);
     138           0 :   if (err)
     139           0 :     return err;
     140             : 
     141           0 :   err = _gpgme_op_data_lookup (ctx, OPDATA_PASSWD, &hook, sizeof (*opd), NULL);
     142           0 :   opd = hook;
     143           0 :   if (err)
     144           0 :     return err;
     145             : 
     146           0 :   opd->success_seen = 0;
     147           0 :   opd->error_seen = 0;
     148             : 
     149           0 :   _gpgme_engine_set_status_handler (ctx->engine, passwd_status_handler, ctx);
     150             : 
     151           0 :   if (ctx->passphrase_cb)
     152             :     {
     153           0 :       err = _gpgme_engine_set_command_handler
     154             :         (ctx->engine, _gpgme_passphrase_command_handler, ctx);
     155           0 :       if (err)
     156           0 :         return err;
     157             :     }
     158             : 
     159           0 :   return _gpgme_engine_op_passwd (ctx->engine, key, flags);
     160             : }
     161             : 
     162             : 
     163             : 
     164             : /* Change the passphrase for KEY.  FLAGS is reserved for future use
     165             :    and must be passed as 0.  The engine is expected to present a user
     166             :    interface to enter the old and the new passphrase.  This is the
     167             :    asynchronous variant.
     168             : 
     169             :    Note that if ever the need arises to supply a passphrase we can do
     170             :    this with a flag value and the passphrase callback feature.  */
     171             : gpgme_error_t
     172           0 : gpgme_op_passwd_start (gpgme_ctx_t ctx, gpgme_key_t key, unsigned int flags)
     173             : {
     174             :   gpg_error_t err;
     175           0 :   TRACE_BEG2 (DEBUG_CTX, "gpgme_op_passwd_start", ctx,
     176             :               "key=%p, flags=0x%x", key, flags);
     177             : 
     178           0 :   if (!ctx)
     179           0 :     return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
     180             : 
     181           0 :   err = passwd_start (ctx, 0, key, flags);
     182           0 :   return TRACE_ERR (err);
     183             : }
     184             : 
     185             : 
     186             : /* Change the passphrase for KEY.  FLAGS is reserved for future use
     187             :    and must be passed as 0.  This is the synchronous variant.  */
     188             : gpgme_error_t
     189           0 : gpgme_op_passwd (gpgme_ctx_t ctx, gpgme_key_t key, unsigned int flags)
     190             : {
     191             :   gpgme_error_t err;
     192             : 
     193           0 :   TRACE_BEG2 (DEBUG_CTX, "gpgme_op_passwd", ctx,
     194             :               "key=%p, flags=0x%x", key, flags);
     195             : 
     196           0 :   if (!ctx)
     197           0 :     return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
     198             : 
     199           0 :   err = passwd_start (ctx, 1, key, flags);
     200           0 :   if (!err)
     201           0 :     err = _gpgme_wait_one (ctx);
     202           0 :   return TRACE_ERR (err);
     203             : }
     204             : 

Generated by: LCOV version 1.13