Line data Source code
1 : /*
2 : data.cpp - wraps a gpgme data object
3 : Copyright (C) 2003 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 : #ifdef HAVE_CONFIG_H
24 : #include "config.h"
25 : #endif
26 :
27 : #include "data_p.h"
28 : #include "context_p.h"
29 : #include <error.h>
30 : #include <interfaces/dataprovider.h>
31 :
32 : #include <gpgme.h>
33 :
34 : #ifndef NDEBUG
35 : #include <iostream>
36 : #endif
37 :
38 298 : GpgME::Data::Private::~Private()
39 : {
40 149 : if (data) {
41 88 : gpgme_data_release(data);
42 : }
43 149 : }
44 :
45 8 : const GpgME::Data::Null GpgME::Data::null;
46 :
47 0 : GpgME::Data::Data()
48 : {
49 : gpgme_data_t data;
50 0 : const gpgme_error_t e = gpgme_data_new(&data);
51 0 : d.reset(new Private(e ? 0 : data));
52 0 : }
53 :
54 61 : GpgME::Data::Data(const Null &)
55 61 : : d(new Private(0))
56 : {
57 :
58 61 : }
59 :
60 0 : GpgME::Data::Data(gpgme_data_t data)
61 0 : : d(new Private(data))
62 : {
63 :
64 0 : }
65 :
66 0 : GpgME::Data::Data(const char *buffer, size_t size, bool copy)
67 : {
68 : gpgme_data_t data;
69 0 : const gpgme_error_t e = gpgme_data_new_from_mem(&data, buffer, size, int(copy));
70 0 : std::string sizestr = std::to_string(size);
71 : // Ignore errors as this is optional
72 0 : gpgme_data_set_flag(data, "size-hint", sizestr.c_str());
73 0 : d.reset(new Private(e ? 0 : data));
74 0 : }
75 :
76 0 : GpgME::Data::Data(const char *filename)
77 : {
78 : gpgme_data_t data;
79 0 : const gpgme_error_t e = gpgme_data_new(&data);
80 0 : d.reset(new Private(e ? 0 : data));
81 0 : if (!e) {
82 0 : setFileName(filename);
83 : }
84 0 : }
85 :
86 0 : GpgME::Data::Data(const char *filename, off_t offset, size_t length)
87 : {
88 : gpgme_data_t data;
89 0 : const gpgme_error_t e = gpgme_data_new_from_filepart(&data, filename, 0, offset, length);
90 0 : d.reset(new Private(e ? 0 : data));
91 0 : }
92 :
93 0 : GpgME::Data::Data(FILE *fp)
94 : {
95 : gpgme_data_t data;
96 0 : const gpgme_error_t e = gpgme_data_new_from_stream(&data, fp);
97 0 : d.reset(new Private(e ? 0 : data));
98 0 : }
99 :
100 0 : GpgME::Data::Data(FILE *fp, off_t offset, size_t length)
101 : {
102 : gpgme_data_t data;
103 0 : const gpgme_error_t e = gpgme_data_new_from_filepart(&data, 0, fp, offset, length);
104 0 : d.reset(new Private(e ? 0 : data));
105 0 : }
106 :
107 0 : GpgME::Data::Data(int fd)
108 : {
109 : gpgme_data_t data;
110 0 : const gpgme_error_t e = gpgme_data_new_from_fd(&data, fd);
111 0 : d.reset(new Private(e ? 0 : data));
112 0 : }
113 :
114 88 : GpgME::Data::Data(DataProvider *dp)
115 : {
116 88 : d.reset(new Private);
117 88 : if (!dp) {
118 0 : return;
119 : }
120 88 : if (!dp->isSupported(DataProvider::Read)) {
121 1 : d->cbs.read = 0;
122 : }
123 88 : if (!dp->isSupported(DataProvider::Write)) {
124 26 : d->cbs.write = 0;
125 : }
126 88 : if (!dp->isSupported(DataProvider::Seek)) {
127 0 : d->cbs.seek = 0;
128 : }
129 88 : if (!dp->isSupported(DataProvider::Release)) {
130 0 : d->cbs.release = 0;
131 : }
132 88 : const gpgme_error_t e = gpgme_data_new_from_cbs(&d->data, &d->cbs, dp);
133 88 : if (e) {
134 0 : d->data = 0;
135 : }
136 88 : if (dp->isSupported(DataProvider::Seek)) {
137 88 : off_t size = seek(0, SEEK_END);
138 88 : seek(0, SEEK_SET);
139 176 : std::string sizestr = std::to_string(size);
140 : // Ignore errors as this is optional
141 88 : gpgme_data_set_flag(d->data, "size-hint", sizestr.c_str());
142 : }
143 : #ifndef NDEBUG
144 : //std::cerr << "GpgME::Data(): DataProvider supports: "
145 : // << ( d->cbs.read ? "read" : "no read" ) << ", "
146 : // << ( d->cbs.write ? "write" : "no write" ) << ", "
147 : // << ( d->cbs.seek ? "seek" : "no seek" ) << ", "
148 : // << ( d->cbs.release ? "release" : "no release" ) << std::endl;
149 : #endif
150 : }
151 :
152 35 : bool GpgME::Data::isNull() const
153 : {
154 35 : return !d || !d->data;
155 : }
156 :
157 0 : GpgME::Data::Encoding GpgME::Data::encoding() const
158 : {
159 0 : switch (gpgme_data_get_encoding(d->data)) {
160 0 : case GPGME_DATA_ENCODING_NONE: return AutoEncoding;
161 0 : case GPGME_DATA_ENCODING_BINARY: return BinaryEncoding;
162 0 : case GPGME_DATA_ENCODING_BASE64: return Base64Encoding;
163 0 : case GPGME_DATA_ENCODING_ARMOR: return ArmorEncoding;
164 0 : case GPGME_DATA_ENCODING_MIME: return MimeEncoding;
165 0 : case GPGME_DATA_ENCODING_URL: return UrlEncoding;
166 0 : case GPGME_DATA_ENCODING_URLESC: return UrlEscEncoding;
167 0 : case GPGME_DATA_ENCODING_URL0: return Url0Encoding;
168 : }
169 0 : return AutoEncoding;
170 : }
171 :
172 0 : GpgME::Error GpgME::Data::setEncoding(Encoding enc)
173 : {
174 0 : gpgme_data_encoding_t ge = GPGME_DATA_ENCODING_NONE;
175 0 : switch (enc) {
176 0 : case AutoEncoding: ge = GPGME_DATA_ENCODING_NONE; break;
177 0 : case BinaryEncoding: ge = GPGME_DATA_ENCODING_BINARY; break;
178 0 : case Base64Encoding: ge = GPGME_DATA_ENCODING_BASE64; break;
179 0 : case ArmorEncoding: ge = GPGME_DATA_ENCODING_ARMOR; break;
180 0 : case MimeEncoding: ge = GPGME_DATA_ENCODING_MIME; break;
181 0 : case UrlEncoding: ge = GPGME_DATA_ENCODING_URL; break;
182 0 : case UrlEscEncoding: ge = GPGME_DATA_ENCODING_URLESC; break;
183 0 : case Url0Encoding: ge = GPGME_DATA_ENCODING_URL0; break;
184 : }
185 0 : return Error(gpgme_data_set_encoding(d->data, ge));
186 : }
187 :
188 0 : GpgME::Data::Type GpgME::Data::type() const
189 : {
190 0 : if (isNull()) {
191 0 : return Invalid;
192 : }
193 0 : switch (gpgme_data_identify(d->data, 0)) {
194 0 : case GPGME_DATA_TYPE_INVALID: return Invalid;
195 0 : case GPGME_DATA_TYPE_UNKNOWN: return Unknown;
196 0 : case GPGME_DATA_TYPE_PGP_SIGNED: return PGPSigned;
197 0 : case GPGME_DATA_TYPE_PGP_OTHER: return PGPOther;
198 0 : case GPGME_DATA_TYPE_PGP_KEY: return PGPKey;
199 0 : case GPGME_DATA_TYPE_CMS_SIGNED: return CMSSigned;
200 0 : case GPGME_DATA_TYPE_CMS_ENCRYPTED: return CMSEncrypted;
201 0 : case GPGME_DATA_TYPE_CMS_OTHER: return CMSOther;
202 0 : case GPGME_DATA_TYPE_X509_CERT: return X509Cert;
203 0 : case GPGME_DATA_TYPE_PKCS12: return PKCS12;
204 0 : case GPGME_DATA_TYPE_PGP_ENCRYPTED: return PGPEncrypted;
205 0 : case GPGME_DATA_TYPE_PGP_SIGNATURE: return PGPSignature;
206 : }
207 0 : return Invalid;
208 : }
209 :
210 0 : char *GpgME::Data::fileName() const
211 : {
212 0 : return gpgme_data_get_file_name(d->data);
213 : }
214 :
215 0 : GpgME::Error GpgME::Data::setFileName(const char *name)
216 : {
217 0 : return Error(gpgme_data_set_file_name(d->data, name));
218 : }
219 :
220 1 : ssize_t GpgME::Data::read(void *buffer, size_t length)
221 : {
222 1 : return gpgme_data_read(d->data, buffer, length);
223 : }
224 :
225 0 : ssize_t GpgME::Data::write(const void *buffer, size_t length)
226 : {
227 0 : return gpgme_data_write(d->data, buffer, length);
228 : }
229 :
230 176 : off_t GpgME::Data::seek(off_t offset, int whence)
231 : {
232 176 : return gpgme_data_seek(d->data, offset, whence);
233 : }
234 :
235 1 : GpgME::Error GpgME::Data::rewind()
236 : {
237 1 : return Error(gpgme_data_rewind(d->data));
238 : }
239 :
240 3 : std::vector<GpgME::Key> GpgME::Data::toKeys(Protocol proto) const
241 : {
242 3 : std::vector<GpgME::Key> ret;
243 3 : if (isNull()) {
244 0 : return ret;
245 : }
246 3 : auto ctx = GpgME::Context::createForProtocol(proto);
247 3 : if (!ctx) {
248 0 : return ret;
249 : }
250 :
251 3 : if (gpgme_op_keylist_from_data_start (ctx->impl()->ctx, d->data, 0)) {
252 0 : return ret;
253 : }
254 :
255 : gpgme_key_t key;
256 7 : while (!gpgme_op_keylist_next (ctx->impl()->ctx, &key)) {
257 2 : ret.push_back(GpgME::Key(key, false));
258 : }
259 3 : delete ctx;
260 3 : return ret;
261 : }
262 :
263 0 : std::string GpgME::Data::toString()
264 : {
265 0 : std::string ret;
266 : char buf[4096];
267 : size_t nread;
268 0 : seek (0, SEEK_SET);
269 0 : while ((nread = read (buf, 4096)) > 0)
270 : {
271 0 : ret += std::string (buf, nread);
272 : }
273 0 : seek (0, SEEK_SET);
274 0 : return ret;
275 24 : }
|