LCOV - code coverage report
Current view: top level - lang/cpp/src - callbacks.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 42 56 75.0 %
Date: 2018-11-15 08:49:49 Functions: 8 9 88.9 %

          Line data    Source code
       1             : /*
       2             :   callbacks.cpp - callback targets for internal use:
       3             :   Copyright (C) 2003,2004 Klarälvdalens Datakonsult AB
       4             :   2016 Bundesamt für Sicherheit in der Informationstechnik
       5             :   Software engineering by Intevation GmbH
       6             : 
       7             :   This file is part of GPGME++.
       8             : 
       9             :   GPGME++ is free software; you can redistribute it and/or
      10             :   modify it under the terms of the GNU Library General Public
      11             :   License as published by the Free Software Foundation; either
      12             :   version 2 of the License, or (at your option) any later version.
      13             : 
      14             :   GPGME++ is distributed in the hope that it will be useful,
      15             :   but WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17             :   GNU Library General Public License for more details.
      18             : 
      19             :   You should have received a copy of the GNU Library General Public License
      20             :   along with GPGME++; see the file COPYING.LIB.  If not, write to the
      21             :   Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
      22             :   Boston, MA 02110-1301, USA.
      23             : */
      24             : 
      25             : #ifdef HAVE_CONFIG_H
      26             :  #include "config.h"
      27             : #endif
      28             : 
      29             : #include "callbacks.h"
      30             : #include "util.h"
      31             : 
      32             : #include <interfaces/progressprovider.h>
      33             : #include <interfaces/passphraseprovider.h>
      34             : #include <interfaces/dataprovider.h>
      35             : #include <error.h>
      36             : 
      37             : #include <gpgme.h>
      38             : #include <gpg-error.h>
      39             : 
      40             : #include <cassert>
      41             : #include <cerrno>
      42             : #include <cstring>
      43             : #include <unistd.h>
      44             : #include <stdlib.h>
      45             : 
      46           0 : static inline gpgme_error_t make_err_from_syserror()
      47             : {
      48           0 :     return gpgme_error_from_syserror();
      49             : }
      50             : 
      51             : using GpgME::ProgressProvider;
      52             : using GpgME::PassphraseProvider;
      53             : using GpgME::DataProvider;
      54             : 
      55          26 : void progress_callback(void *opaque, const char *what,
      56             :                        int type, int current, int total)
      57             : {
      58          26 :     ProgressProvider *provider = static_cast<ProgressProvider *>(opaque);
      59          26 :     if (provider) {
      60          26 :         provider->showProgress(what, type, current, total);
      61             :     }
      62          26 : }
      63             : 
      64             : /* To avoid that a compiler optimizes certain memset calls away, these
      65             :    macros may be used instead. */
      66             : #define wipememory2(_ptr,_set,_len) do { \
      67             :         volatile char *_vptr=(volatile char *)(_ptr); \
      68             :         size_t _vlen=(_len); \
      69             :         while(_vlen) { *_vptr=(_set); _vptr++; _vlen--; } \
      70             :     } while(0)
      71             : #define wipememory(_ptr,_len) wipememory2(_ptr,0,_len)
      72             : 
      73           6 : gpgme_error_t passphrase_callback(void *opaque, const char *uid_hint, const char *desc,
      74             :                                   int prev_was_bad, int fd)
      75             : {
      76           6 :     PassphraseProvider *provider = static_cast<PassphraseProvider *>(opaque);
      77           6 :     bool canceled = false;
      78           6 :     gpgme_error_t err = GPG_ERR_NO_ERROR;
      79           6 :     char *passphrase = provider ? provider->getPassphrase(uid_hint, desc, prev_was_bad, canceled) : 0 ;
      80           6 :     if (canceled) {
      81           0 :         err = make_error(GPG_ERR_CANCELED);
      82             :     } else {
      83           6 :         if (passphrase && *passphrase) {
      84           6 :             size_t passphrase_length = std::strlen(passphrase);
      85           6 :             size_t written = 0;
      86           0 :             do {
      87           6 :                 ssize_t now_written = gpgme_io_write(fd, passphrase + written, passphrase_length - written);
      88           6 :                 if (now_written < 0) {
      89           0 :                     err = make_err_from_syserror();
      90           0 :                     break;
      91             :                 }
      92           6 :                 written += now_written;
      93           6 :             } while (written < passphrase_length);
      94             :         }
      95             :     }
      96             : 
      97           6 :     if (passphrase && *passphrase) {
      98           6 :         wipememory(passphrase, std::strlen(passphrase));
      99             :     }
     100           6 :     free(passphrase);
     101           6 :     gpgme_io_write(fd, "\n", 1);
     102           6 :     return err;
     103             : }
     104             : 
     105             : static gpgme_ssize_t
     106         318 : data_read_callback(void *opaque, void *buf, size_t buflen)
     107             : {
     108         318 :     DataProvider *provider = static_cast<DataProvider *>(opaque);
     109         318 :     if (!provider) {
     110           0 :         gpgme_err_set_errno(gpgme_err_code_to_errno(GPG_ERR_EINVAL));
     111           0 :         return -1;
     112             :     }
     113         318 :     return (gpgme_ssize_t)provider->read(buf, buflen);
     114             : }
     115             : 
     116             : static gpgme_ssize_t
     117          61 : data_write_callback(void *opaque, const void *buf, size_t buflen)
     118             : {
     119          61 :     DataProvider *provider = static_cast<DataProvider *>(opaque);
     120          61 :     if (!provider) {
     121           0 :         gpgme_err_set_errno(gpgme_err_code_to_errno(GPG_ERR_EINVAL));
     122           0 :         return -1;
     123             :     }
     124          61 :     return (gpgme_ssize_t)provider->write(buf, buflen);
     125             : }
     126             : 
     127             : static gpgme_off_t
     128         205 : data_seek_callback(void *opaque, gpgme_off_t offset, int whence)
     129             : {
     130         205 :     DataProvider *provider = static_cast<DataProvider *>(opaque);
     131         205 :     if (!provider) {
     132           0 :         gpgme_err_set_errno(gpgme_err_code_to_errno(GPG_ERR_EINVAL));
     133           0 :         return -1;
     134             :     }
     135         205 :     if (whence != SEEK_SET && whence != SEEK_CUR && whence != SEEK_END) {
     136           0 :         gpgme_err_set_errno(gpgme_err_code_to_errno(GPG_ERR_EINVAL));
     137           0 :         return -1;
     138             :     }
     139         205 :     return provider->seek((off_t)offset, whence);
     140             : }
     141             : 
     142          88 : static void data_release_callback(void *opaque)
     143             : {
     144          88 :     DataProvider *provider = static_cast<DataProvider *>(opaque);
     145          88 :     if (provider) {
     146          88 :         provider->release();
     147             :     }
     148          88 : }
     149             : 
     150             : const gpgme_data_cbs GpgME::data_provider_callbacks = {
     151             :     &data_read_callback,
     152             :     &data_write_callback,
     153             :     &data_seek_callback,
     154             :     &data_release_callback
     155          24 : };

Generated by: LCOV version 1.13