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