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