Line data Source code
1 : /*
2 : decryptionresult.cpp - wraps a gpgme keygen result
3 : Copyright (C) 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 : #ifdef HAVE_CONFIG_H
24 : #include "config.h"
25 : #endif
26 :
27 : #include <decryptionresult.h>
28 : #include "result_p.h"
29 : #include "util.h"
30 :
31 : #include <gpgme.h>
32 :
33 : #include <algorithm>
34 : #include <iterator>
35 : #include <cstring>
36 : #include <cstdlib>
37 : #include <istream>
38 :
39 : #include <string.h>
40 :
41 : class GpgME::DecryptionResult::Private
42 : {
43 : public:
44 2 : explicit Private(const _gpgme_op_decrypt_result &r) : res(r)
45 : {
46 2 : if (res.unsupported_algorithm) {
47 0 : res.unsupported_algorithm = strdup(res.unsupported_algorithm);
48 : }
49 2 : if (res.file_name) {
50 0 : res.file_name = strdup(res.file_name);
51 : }
52 : //FIXME: copying gpgme_recipient_t objects invalidates the keyid member,
53 : //thus we use _keyid for now (internal API)
54 3 : for (gpgme_recipient_t r = res.recipients ; r ; r = r->next) {
55 1 : recipients.push_back(*r);
56 : }
57 2 : res.recipients = 0;
58 2 : }
59 2 : ~Private()
60 2 : {
61 2 : if (res.unsupported_algorithm) {
62 0 : std::free(res.unsupported_algorithm);
63 : }
64 2 : res.unsupported_algorithm = 0;
65 2 : if (res.file_name) {
66 0 : std::free(res.file_name);
67 : }
68 2 : res.file_name = 0;
69 2 : }
70 :
71 : _gpgme_op_decrypt_result res;
72 : std::vector<_gpgme_recipient> recipients;
73 : };
74 :
75 0 : GpgME::DecryptionResult::DecryptionResult(gpgme_ctx_t ctx, int error)
76 0 : : GpgME::Result(error), d()
77 : {
78 0 : init(ctx);
79 0 : }
80 :
81 2 : GpgME::DecryptionResult::DecryptionResult(gpgme_ctx_t ctx, const Error &error)
82 2 : : GpgME::Result(error), d()
83 : {
84 2 : init(ctx);
85 2 : }
86 :
87 2 : void GpgME::DecryptionResult::init(gpgme_ctx_t ctx)
88 : {
89 2 : if (!ctx) {
90 0 : return;
91 : }
92 2 : gpgme_decrypt_result_t res = gpgme_op_decrypt_result(ctx);
93 2 : if (!res) {
94 0 : return;
95 : }
96 2 : d.reset(new Private(*res));
97 : }
98 :
99 4 : make_standard_stuff(DecryptionResult)
100 :
101 0 : const char *GpgME::DecryptionResult::unsupportedAlgorithm() const
102 : {
103 0 : return d ? d->res.unsupported_algorithm : 0 ;
104 : }
105 :
106 0 : bool GpgME::DecryptionResult::isWrongKeyUsage() const
107 : {
108 0 : return d && d->res.wrong_key_usage;
109 : }
110 :
111 0 : const char *GpgME::DecryptionResult::fileName() const
112 : {
113 0 : return d ? d->res.file_name : 0 ;
114 : }
115 :
116 0 : unsigned int GpgME::DecryptionResult::numRecipients() const
117 : {
118 0 : return d ? d->recipients.size() : 0 ;
119 : }
120 :
121 0 : GpgME::DecryptionResult::Recipient GpgME::DecryptionResult::recipient(unsigned int idx) const
122 : {
123 0 : if (d && idx < d->recipients.size()) {
124 0 : return Recipient(&d->recipients[idx]);
125 : }
126 0 : return Recipient();
127 : }
128 :
129 : namespace
130 : {
131 : struct make_recipient {
132 0 : GpgME::DecryptionResult::Recipient operator()(_gpgme_recipient &t)
133 : {
134 0 : return GpgME::DecryptionResult::Recipient(&t);
135 : }
136 : };
137 : }
138 :
139 0 : std::vector<GpgME::DecryptionResult::Recipient> GpgME::DecryptionResult::recipients() const
140 : {
141 0 : std::vector<Recipient> result;
142 0 : if (d) {
143 0 : result.reserve(d->recipients.size());
144 0 : std::transform(d->recipients.begin(), d->recipients.end(),
145 : std::back_inserter(result),
146 0 : make_recipient());
147 : }
148 0 : return result;
149 : }
150 :
151 : class GpgME::DecryptionResult::Recipient::Private : public _gpgme_recipient
152 : {
153 : public:
154 0 : Private(gpgme_recipient_t reci) : _gpgme_recipient(*reci) {}
155 : };
156 :
157 0 : GpgME::DecryptionResult::Recipient::Recipient()
158 0 : : d()
159 : {
160 :
161 0 : }
162 :
163 0 : GpgME::DecryptionResult::Recipient::Recipient(gpgme_recipient_t r)
164 0 : : d()
165 : {
166 0 : if (r) {
167 0 : d.reset(new Private(r));
168 : }
169 0 : }
170 :
171 0 : bool GpgME::DecryptionResult::Recipient::isNull() const
172 : {
173 0 : return !d;
174 : }
175 :
176 0 : const char *GpgME::DecryptionResult::Recipient::keyID() const
177 : {
178 : //_keyid is internal API, but the public keyid is invalid after copying (see above)
179 0 : if (d) {
180 0 : return d->_keyid;
181 : }
182 0 : return 0;
183 : }
184 :
185 0 : const char *GpgME::DecryptionResult::Recipient::shortKeyID() const
186 : {
187 : //_keyid is internal API, but the public keyid is invalid after copying (see above)
188 0 : if (d) {
189 0 : return d->_keyid + 8;
190 : }
191 0 : return 0;
192 : }
193 :
194 0 : unsigned int GpgME::DecryptionResult::Recipient::publicKeyAlgorithm() const
195 : {
196 0 : if (d) {
197 0 : return d->pubkey_algo;
198 : }
199 0 : return 0;
200 : }
201 :
202 0 : const char *GpgME::DecryptionResult::Recipient::publicKeyAlgorithmAsString() const
203 : {
204 0 : if (d) {
205 0 : return gpgme_pubkey_algo_name(d->pubkey_algo);
206 : }
207 0 : return 0;
208 : }
209 :
210 0 : GpgME::Error GpgME::DecryptionResult::Recipient::status() const
211 : {
212 0 : if (d) {
213 0 : return Error(d->status);
214 : }
215 0 : return Error();
216 : }
217 :
218 0 : std::ostream &GpgME::operator<<(std::ostream &os, const DecryptionResult &result)
219 : {
220 0 : os << "GpgME::DecryptionResult(";
221 0 : if (!result.isNull()) {
222 0 : os << "\n error: " << result.error()
223 : << "\n fileName: " << protect(result.fileName())
224 : << "\n unsupportedAlgorithm: " << protect(result.unsupportedAlgorithm())
225 0 : << "\n isWrongKeyUsage: " << result.isWrongKeyUsage()
226 0 : << "\n recipients:\n";
227 0 : const std::vector<DecryptionResult::Recipient> recipients = result.recipients();
228 : std::copy(recipients.begin(), recipients.end(),
229 0 : std::ostream_iterator<DecryptionResult::Recipient>(os, "\n"));
230 : }
231 0 : return os << ')';
232 : }
233 :
234 0 : std::ostream &GpgME::operator<<(std::ostream &os, const DecryptionResult::Recipient &reci)
235 : {
236 0 : os << "GpgME::DecryptionResult::Recipient(";
237 0 : if (!reci.isNull()) {
238 : os << "\n keyID: " << protect(reci.keyID())
239 : << "\n shortKeyID: " << protect(reci.shortKeyID())
240 : << "\n publicKeyAlgorithm: " << protect(reci.publicKeyAlgorithmAsString())
241 0 : << "\n status: " << reci.status();
242 : }
243 0 : return os << ')';
244 24 : }
|