Line data Source code
1 : /*
2 : qgpgmenewcryptoconfig.cpp
3 :
4 : This file is part of qgpgme, the Qt API binding for gpgme
5 : Copyright (c) 2010 Klarälvdalens Datakonsult AB
6 : Copyright (c) 2016 by Bundesamt für Sicherheit in der Informationstechnik
7 : Software engineering by Intevation GmbH
8 :
9 : QGpgME is free software; you can redistribute it and/or
10 : modify it under the terms of the GNU General Public License as
11 : published by the Free Software Foundation; either version 2 of the
12 : License, or (at your option) any later version.
13 :
14 : QGpgME 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 GNU
17 : General Public License for more details.
18 :
19 : You should have received a copy of the GNU General Public License
20 : along with this program; if not, write to the Free Software
21 : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 :
23 : In addition, as a special exception, the copyright holders give
24 : permission to link the code of this program with any edition of
25 : the Qt library by Trolltech AS, Norway (or with modified versions
26 : of Qt that use the same license as Qt), and distribute linked
27 : combinations including the two. You must obey the GNU General
28 : Public License in all respects for all of the code used other than
29 : Qt. If you modify this file, you may extend this exception to
30 : your version of the file, but you are not obligated to do so. If
31 : you do not wish to do so, delete this exception statement from
32 : your version.
33 : */
34 :
35 : #ifdef HAVE_CONFIG_H
36 : #include "config.h"
37 : #endif
38 :
39 : #include "qgpgmenewcryptoconfig.h"
40 :
41 : #include <QDebug>
42 : #include "gpgme_backend_debug.h"
43 :
44 : #include <QFile>
45 : #include <QDir>
46 :
47 : #include "global.h"
48 : #include "error.h"
49 :
50 :
51 : #include <sstream>
52 : #include <string>
53 : #include <functional>
54 : #include <cassert>
55 : #include <functional>
56 :
57 : using namespace QGpgME;
58 : using namespace GpgME;
59 : using namespace GpgME::Configuration;
60 :
61 : namespace
62 : {
63 : struct Select1St {
64 : template <typename U, typename V>
65 : const U &operator()(const std::pair<U, V> &p) const
66 : {
67 : return p.first;
68 : }
69 : template <typename U, typename V>
70 : const U &operator()(const QPair<U, V> &p) const
71 : {
72 : return p.first;
73 : }
74 : };
75 : }
76 :
77 : // Just for the Q_ASSERT in the dtor. Not thread-safe, but who would
78 : // have 2 threads talking to gpgconf anyway? :)
79 : static bool s_duringClear = false;
80 :
81 1 : QGpgMENewCryptoConfig::QGpgMENewCryptoConfig()
82 1 : : m_parsed(false)
83 : {
84 1 : }
85 :
86 0 : QGpgMENewCryptoConfig::~QGpgMENewCryptoConfig()
87 : {
88 0 : clear();
89 0 : }
90 :
91 23 : void QGpgMENewCryptoConfig::reloadConfiguration(bool)
92 : {
93 23 : clear();
94 :
95 46 : Error error;
96 46 : const std::vector<Component> components = Component::load(error);
97 : #ifndef NDEBUG
98 : {
99 46 : std::stringstream ss;
100 23 : ss << "error: " << error
101 23 : << "components:\n";
102 : std::copy(components.begin(), components.end(),
103 23 : std::ostream_iterator<Component>(ss, "\n"));
104 23 : qCDebug(GPGPME_BACKEND_LOG) << ss.str().c_str();
105 : }
106 : #endif
107 : #if 0
108 : TODO port?
109 : if (error && showErrors) {
110 : const QString wmsg = i18n("<qt>Failed to execute gpgconf:<p>%1</p></qt>", QString::fromLocal8Bit(error.asString()));
111 : qCWarning(GPGPME_BACKEND_LOG) << wmsg; // to see it from test_cryptoconfig.cpp
112 : KMessageBox::error(0, wmsg);
113 : }
114 : #endif
115 161 : Q_FOREACH(const Component & c, components) {
116 276 : const std::shared_ptr<QGpgMENewCryptoConfigComponent> comp(new QGpgMENewCryptoConfigComponent);
117 138 : comp->setComponent(c);
118 138 : m_componentsByName[ comp->name() ] = comp;
119 : }
120 23 : m_parsed = true;
121 23 : }
122 :
123 0 : QStringList QGpgMENewCryptoConfig::componentList() const
124 : {
125 0 : if (!m_parsed) {
126 0 : const_cast<QGpgMENewCryptoConfig *>(this)->reloadConfiguration(true);
127 : }
128 0 : QStringList result;
129 : std::transform(m_componentsByName.begin(), m_componentsByName.end(),
130 : std::back_inserter(result),
131 0 : mem_fn(&QGpgMENewCryptoConfigComponent::name));
132 0 : return result;
133 : }
134 :
135 33 : QGpgMENewCryptoConfigComponent *QGpgMENewCryptoConfig::component(const QString &name) const
136 : {
137 33 : if (!m_parsed) {
138 23 : const_cast<QGpgMENewCryptoConfig *>(this)->reloadConfiguration(false);
139 : }
140 33 : return m_componentsByName.value(name).get();
141 : }
142 :
143 22 : void QGpgMENewCryptoConfig::sync(bool runtime)
144 : {
145 154 : Q_FOREACH(const std::shared_ptr<QGpgMENewCryptoConfigComponent> &c, m_componentsByName)
146 132 : c->sync(runtime);
147 22 : }
148 :
149 45 : void QGpgMENewCryptoConfig::clear()
150 : {
151 45 : s_duringClear = true;
152 45 : m_componentsByName.clear();
153 45 : s_duringClear = false;
154 45 : m_parsed = false; // next call to componentList/component will need to run gpgconf again
155 45 : }
156 :
157 : ////
158 :
159 138 : QGpgMENewCryptoConfigComponent::QGpgMENewCryptoConfigComponent()
160 : : CryptoConfigComponent(),
161 138 : m_component()
162 : {
163 :
164 138 : }
165 :
166 138 : void QGpgMENewCryptoConfigComponent::setComponent(const Component &component)
167 : {
168 138 : m_component = component;
169 138 : m_groupsByName.clear();
170 :
171 276 : std::shared_ptr<QGpgMENewCryptoConfigGroup> group;
172 :
173 276 : const std::vector<Option> options = m_component.options();
174 3082 : Q_FOREACH(const Option & o, options)
175 2944 : if (o.flags() & Group) {
176 621 : if (group) {
177 506 : m_groupsByName[group->name()] = group;
178 : }
179 621 : group.reset(new QGpgMENewCryptoConfigGroup(shared_from_this(), o));
180 2323 : } else if (group) {
181 4646 : const std::shared_ptr<QGpgMENewCryptoConfigEntry> entry(new QGpgMENewCryptoConfigEntry(group, o));
182 4646 : const QString name = entry->name();
183 2323 : group->m_entryNames.push_back(name);
184 2323 : group->m_entriesByName[name] = entry;
185 : } else {
186 0 : qCWarning(GPGPME_BACKEND_LOG) << "found no group for entry" << o.name() << "of component" << name();
187 : }
188 138 : if (group) {
189 115 : m_groupsByName[group->name()] = group;
190 : }
191 :
192 138 : }
193 :
194 264 : QGpgMENewCryptoConfigComponent::~QGpgMENewCryptoConfigComponent() {}
195 :
196 138 : QString QGpgMENewCryptoConfigComponent::name() const
197 : {
198 138 : return QString::fromUtf8(m_component.name());
199 : }
200 :
201 0 : QString QGpgMENewCryptoConfigComponent::description() const
202 : {
203 0 : return QString::fromUtf8(m_component.description());
204 : }
205 :
206 0 : QStringList QGpgMENewCryptoConfigComponent::groupList() const
207 : {
208 0 : QStringList result;
209 0 : result.reserve(m_groupsByName.size());
210 : std::transform(m_groupsByName.begin(), m_groupsByName.end(),
211 : std::back_inserter(result),
212 0 : std::mem_fn(&QGpgMENewCryptoConfigGroup::name));
213 0 : return result;
214 : }
215 :
216 33 : QGpgMENewCryptoConfigGroup *QGpgMENewCryptoConfigComponent::group(const QString &name) const
217 : {
218 33 : return m_groupsByName.value(name).get();
219 : }
220 :
221 132 : void QGpgMENewCryptoConfigComponent::sync(bool runtime)
222 : {
223 : Q_UNUSED(runtime) // runtime is always set by engine_gpgconf
224 264 : if (const Error err = m_component.save()) {
225 0 : qCWarning(GPGPME_BACKEND_LOG) << ":"
226 0 : << "Error from gpgconf while saving configuration: %1"
227 0 : << QString::fromLocal8Bit(err.asString());
228 : }
229 132 : }
230 :
231 : ////
232 :
233 621 : QGpgMENewCryptoConfigGroup::QGpgMENewCryptoConfigGroup(const std::shared_ptr<QGpgMENewCryptoConfigComponent> &comp, const Option &option)
234 : : CryptoConfigGroup(),
235 : m_component(comp),
236 621 : m_option(option)
237 : {
238 621 : }
239 :
240 1188 : QGpgMENewCryptoConfigGroup::~QGpgMENewCryptoConfigGroup() {}
241 :
242 621 : QString QGpgMENewCryptoConfigGroup::name() const
243 : {
244 621 : return QString::fromUtf8(m_option.name());
245 : }
246 :
247 0 : QString QGpgMENewCryptoConfigGroup::description() const
248 : {
249 0 : return QString::fromUtf8(m_option.description());
250 : }
251 :
252 0 : QString QGpgMENewCryptoConfigGroup::path() const
253 : {
254 0 : if (const std::shared_ptr<QGpgMENewCryptoConfigComponent> c = m_component.lock()) {
255 0 : return c->name() + QLatin1Char('/') + name();
256 : } else {
257 0 : return QString();
258 : }
259 : }
260 :
261 0 : CryptoConfigEntry::Level QGpgMENewCryptoConfigGroup::level() const
262 : {
263 : // two casts to make SunCC happy:
264 0 : return static_cast<CryptoConfigEntry::Level>(static_cast<unsigned int>(m_option.level()));
265 : }
266 :
267 0 : QStringList QGpgMENewCryptoConfigGroup::entryList() const
268 : {
269 0 : return m_entryNames;
270 : }
271 :
272 33 : QGpgMENewCryptoConfigEntry *QGpgMENewCryptoConfigGroup::entry(const QString &name) const
273 : {
274 33 : return m_entriesByName.value(name).get();
275 : }
276 :
277 0 : static QString urlpart_encode(const QString &str)
278 : {
279 0 : QString enc(str);
280 0 : enc.replace(QLatin1Char('%'), QStringLiteral("%25")); // first!
281 0 : enc.replace(QLatin1Char(':'), QStringLiteral("%3a"));
282 : //qCDebug(GPGPME_BACKEND_LOG) <<" urlpart_encode:" << str <<" ->" << enc;
283 0 : return enc;
284 : }
285 :
286 0 : static QString urlpart_decode(const QString &str)
287 : {
288 0 : return QUrl::fromPercentEncoding(str.toLatin1());
289 : }
290 :
291 : // gpgconf arg type number -> NewCryptoConfigEntry arg type enum mapping
292 0 : static QGpgME::CryptoConfigEntry::ArgType knownArgType(int argType, bool &ok)
293 : {
294 0 : ok = true;
295 0 : switch (argType) {
296 : case 0: // none
297 0 : return QGpgME::CryptoConfigEntry::ArgType_None;
298 : case 1: // string
299 0 : return QGpgME::CryptoConfigEntry::ArgType_String;
300 : case 2: // int32
301 0 : return QGpgME::CryptoConfigEntry::ArgType_Int;
302 : case 3: // uint32
303 0 : return QGpgME::CryptoConfigEntry::ArgType_UInt;
304 : case 32: // pathname
305 0 : return QGpgME::CryptoConfigEntry::ArgType_Path;
306 : case 33: // ldap server
307 0 : return QGpgME::CryptoConfigEntry::ArgType_LDAPURL;
308 : default:
309 0 : ok = false;
310 0 : return QGpgME::CryptoConfigEntry::ArgType_None;
311 : }
312 : }
313 :
314 2323 : QGpgMENewCryptoConfigEntry::QGpgMENewCryptoConfigEntry(const std::shared_ptr<QGpgMENewCryptoConfigGroup> &group, const Option &option)
315 2323 : : m_group(group), m_option(option)
316 : {
317 2323 : }
318 :
319 : #if 0
320 : QVariant QGpgMENewCryptoConfigEntry::stringToValue(const QString &str, bool unescape) const
321 : {
322 : const bool isString = isStringType();
323 :
324 : if (isList()) {
325 : if (argType() == ArgType_None) {
326 : bool ok = true;
327 : const QVariant v = str.isEmpty() ? 0U : str.toUInt(&ok);
328 : if (!ok) {
329 : qCWarning(GPGPME_BACKEND_LOG) << "list-of-none should have an unsigned int as value:" << str;
330 : }
331 : return v;
332 : }
333 : QList<QVariant> lst;
334 : QStringList items = str.split(',', QString::SkipEmptyParts);
335 : for (QStringList::const_iterator valit = items.constBegin(); valit != items.constEnd(); ++valit) {
336 : QString val = *valit;
337 : if (isString) {
338 : if (val.isEmpty()) {
339 : lst << QVariant(QString());
340 : continue;
341 : } else if (unescape) {
342 : if (val[0] != '"') { // see README.gpgconf
343 : qCWarning(GPGPME_BACKEND_LOG) << "String value should start with '\"' :" << val;
344 : }
345 : val = val.mid(1);
346 : }
347 : }
348 : lst << QVariant(unescape ? gpgconf_unescape(val) : val);
349 : }
350 : return lst;
351 : } else { // not a list
352 : QString val(str);
353 : if (isString) {
354 : if (val.isEmpty()) {
355 : return QVariant(QString()); // not set [ok with lists too?]
356 : } else if (unescape) {
357 : if (val[0] != '"') { // see README.gpgconf
358 : qCWarning(GPGPME_BACKEND_LOG) << "String value should start with '\"' :" << val;
359 : }
360 : val = val.mid(1);
361 : }
362 : }
363 : return QVariant(unescape ? gpgconf_unescape(val) : val);
364 : }
365 : }
366 : #endif
367 :
368 6666 : QGpgMENewCryptoConfigEntry::~QGpgMENewCryptoConfigEntry()
369 : {
370 : #ifndef NDEBUG
371 2222 : if (!s_duringClear && m_option.dirty())
372 0 : qCWarning(GPGPME_BACKEND_LOG) << "Deleting a QGpgMENewCryptoConfigEntry that was modified (" << m_option.description() << ")"
373 0 : << "You forgot to call sync() (to commit) or clear() (to discard)";
374 : #endif
375 4444 : }
376 :
377 2323 : QString QGpgMENewCryptoConfigEntry::name() const
378 : {
379 2323 : return QString::fromUtf8(m_option.name());
380 : }
381 :
382 0 : QString QGpgMENewCryptoConfigEntry::description() const
383 : {
384 0 : return QString::fromUtf8(m_option.description());
385 : }
386 :
387 0 : QString QGpgMENewCryptoConfigEntry::path() const
388 : {
389 0 : if (const std::shared_ptr<QGpgMENewCryptoConfigGroup> g = m_group.lock()) {
390 0 : return g->path() + QLatin1Char('/') + name();
391 : } else {
392 0 : return QString();
393 : }
394 : }
395 :
396 10 : bool QGpgMENewCryptoConfigEntry::isOptional() const
397 : {
398 10 : return m_option.flags() & Optional;
399 : }
400 :
401 0 : bool QGpgMENewCryptoConfigEntry::isReadOnly() const
402 : {
403 0 : return m_option.flags() & NoChange;
404 : }
405 :
406 43 : bool QGpgMENewCryptoConfigEntry::isList() const
407 : {
408 43 : return m_option.flags() & List;
409 : }
410 :
411 0 : bool QGpgMENewCryptoConfigEntry::isRuntime() const
412 : {
413 0 : return m_option.flags() & Runtime;
414 : }
415 :
416 0 : CryptoConfigEntry::Level QGpgMENewCryptoConfigEntry::level() const
417 : {
418 : // two casts to make SunCC happy:
419 0 : return static_cast<Level>(static_cast<unsigned int>(m_option.level()));
420 : }
421 :
422 0 : CryptoConfigEntry::ArgType QGpgMENewCryptoConfigEntry::argType() const
423 : {
424 0 : bool ok = false;
425 0 : const ArgType type = knownArgType(m_option.type(), ok);
426 0 : if (ok) {
427 0 : return type;
428 : } else {
429 0 : return knownArgType(m_option.alternateType(), ok);
430 : }
431 : }
432 :
433 0 : bool QGpgMENewCryptoConfigEntry::isSet() const
434 : {
435 0 : return m_option.set();
436 : }
437 :
438 0 : bool QGpgMENewCryptoConfigEntry::boolValue() const
439 : {
440 0 : Q_ASSERT(m_option.alternateType() == NoType);
441 0 : Q_ASSERT(!isList());
442 0 : return m_option.currentValue().boolValue();
443 : }
444 :
445 22 : QString QGpgMENewCryptoConfigEntry::stringValue() const
446 : {
447 : //return toString( false );
448 22 : Q_ASSERT(m_option.alternateType() == StringType);
449 22 : Q_ASSERT(!isList());
450 22 : return QString::fromUtf8(m_option.currentValue().stringValue());
451 : }
452 :
453 0 : int QGpgMENewCryptoConfigEntry::intValue() const
454 : {
455 0 : Q_ASSERT(m_option.alternateType() == IntegerType);
456 0 : Q_ASSERT(!isList());
457 0 : return m_option.currentValue().intValue();
458 : }
459 :
460 0 : unsigned int QGpgMENewCryptoConfigEntry::uintValue() const
461 : {
462 0 : Q_ASSERT(m_option.alternateType() == UnsignedIntegerType);
463 0 : Q_ASSERT(!isList());
464 0 : return m_option.currentValue().uintValue();
465 : }
466 :
467 0 : static QUrl parseURL(int mRealArgType, const QString &str)
468 : {
469 0 : if (mRealArgType == 33) { // LDAP server
470 : // The format is HOSTNAME:PORT:USERNAME:PASSWORD:BASE_DN
471 0 : QStringList items = str.split(QLatin1Char(':'));
472 0 : if (items.count() == 5) {
473 0 : QStringList::const_iterator it = items.constBegin();
474 0 : QUrl url;
475 0 : url.setScheme(QStringLiteral("ldap"));
476 0 : url.setHost(urlpart_decode(*it++));
477 :
478 : bool ok;
479 0 : const int port = (*it++).toInt(&ok);
480 0 : if (ok) {
481 0 : url.setPort(port);
482 0 : } else if (!it->isEmpty()) {
483 0 : qCWarning(GPGPME_BACKEND_LOG) << "parseURL: malformed LDAP server port, ignoring: \"" << *it << "\"";
484 : }
485 :
486 0 : const QString userName = urlpart_decode(*it++);
487 0 : if (!userName.isEmpty()) {
488 0 : url.setUserName(userName);
489 : }
490 0 : const QString passWord = urlpart_decode(*it++);
491 0 : if (!passWord.isEmpty()) {
492 0 : url.setPassword(passWord);
493 : }
494 0 : url.setQuery(urlpart_decode(*it));
495 0 : return url;
496 : } else {
497 0 : qCWarning(GPGPME_BACKEND_LOG) << "parseURL: malformed LDAP server:" << str;
498 : }
499 : }
500 : // other URLs : assume wellformed URL syntax.
501 0 : return QUrl(str);
502 : }
503 :
504 : // The opposite of parseURL
505 0 : static QString splitURL(int mRealArgType, const QUrl &url)
506 : {
507 0 : if (mRealArgType == 33) { // LDAP server
508 : // The format is HOSTNAME:PORT:USERNAME:PASSWORD:BASE_DN
509 0 : Q_ASSERT(url.scheme() == QLatin1String("ldap"));
510 0 : return urlpart_encode(url.host()) + QLatin1Char(':') +
511 0 : (url.port() != -1 ? QString::number(url.port()) : QString()) + QLatin1Char(':') + // -1 is used for default ports, omit
512 0 : urlpart_encode(url.userName()) + QLatin1Char(':') +
513 0 : urlpart_encode(url.password()) + QLatin1Char(':') +
514 0 : urlpart_encode(url.query());
515 : }
516 0 : return url.path();
517 : }
518 :
519 0 : QUrl QGpgMENewCryptoConfigEntry::urlValue() const
520 : {
521 0 : const Type type = m_option.type();
522 0 : Q_ASSERT(type == FilenameType || type == LdapServerType);
523 0 : Q_ASSERT(!isList());
524 0 : if (type == FilenameType) {
525 0 : QUrl url = QUrl::fromLocalFile(m_option.currentValue().stringValue());
526 0 : return url;
527 : }
528 0 : return parseURL(type, stringValue());
529 : }
530 :
531 0 : unsigned int QGpgMENewCryptoConfigEntry::numberOfTimesSet() const
532 : {
533 0 : Q_ASSERT(m_option.alternateType() == NoType);
534 0 : Q_ASSERT(isList());
535 0 : return m_option.currentValue().uintValue();
536 : }
537 :
538 0 : std::vector<int> QGpgMENewCryptoConfigEntry::intValueList() const
539 : {
540 0 : Q_ASSERT(m_option.alternateType() == IntegerType);
541 0 : Q_ASSERT(isList());
542 0 : return m_option.currentValue().intValues();
543 : }
544 :
545 0 : std::vector<unsigned int> QGpgMENewCryptoConfigEntry::uintValueList() const
546 : {
547 0 : Q_ASSERT(m_option.alternateType() == UnsignedIntegerType);
548 0 : Q_ASSERT(isList());
549 0 : return m_option.currentValue().uintValues();
550 : }
551 :
552 0 : QStringList QGpgMENewCryptoConfigEntry::stringValueList() const
553 : {
554 0 : Q_ASSERT(isList());
555 0 : const Argument arg = m_option.currentValue();
556 0 : const std::vector<const char *> values = arg.stringValues();
557 0 : QStringList ret;
558 0 : for(const char *value: values) {
559 0 : ret << QString::fromUtf8(value);
560 : }
561 0 : return ret;
562 : }
563 :
564 0 : QList<QUrl> QGpgMENewCryptoConfigEntry::urlValueList() const
565 : {
566 0 : const Type type = m_option.type();
567 0 : Q_ASSERT(type == FilenameType || type == LdapServerType);
568 0 : Q_ASSERT(isList());
569 0 : const Argument arg = m_option.currentValue();
570 0 : const std::vector<const char *> values = arg.stringValues();
571 0 : QList<QUrl> ret;
572 0 : Q_FOREACH(const char *value, values)
573 0 : if (type == FilenameType) {
574 0 : QUrl url;
575 0 : url.setPath(QFile::decodeName(value));
576 0 : ret << url;
577 : } else {
578 0 : ret << parseURL(type, QString::fromUtf8(value));
579 : }
580 0 : return ret;
581 : }
582 :
583 1 : void QGpgMENewCryptoConfigEntry::resetToDefault()
584 : {
585 1 : m_option.resetToDefaultValue();
586 1 : }
587 :
588 0 : void QGpgMENewCryptoConfigEntry::setBoolValue(bool b)
589 : {
590 0 : Q_ASSERT(m_option.alternateType() == NoType);
591 0 : Q_ASSERT(!isList());
592 : // A "no arg" option is either set or not set.
593 : // Being set means createNoneArgument(), being unset means resetToDefault()
594 0 : m_option.setNewValue(m_option.createNoneArgument(b));
595 0 : }
596 :
597 21 : void QGpgMENewCryptoConfigEntry::setStringValue(const QString &str)
598 : {
599 21 : Q_ASSERT(m_option.alternateType() == StringType);
600 21 : Q_ASSERT(!isList());
601 21 : const Type type = m_option.type();
602 : // When setting a string to empty (and there's no default), we need to act like resetToDefault
603 : // Otherwise we try e.g. "ocsp-responder:0:" and gpgconf answers:
604 : // "gpgconf: argument required for option ocsp-responder"
605 21 : if (str.isEmpty() && !isOptional()) {
606 10 : m_option.resetToDefaultValue();
607 11 : } else if (type == FilenameType) {
608 0 : m_option.setNewValue(m_option.createStringArgument(QFile::encodeName(str).constData()));
609 : } else {
610 11 : m_option.setNewValue(m_option.createStringArgument(str.toUtf8().constData()));
611 : }
612 21 : }
613 :
614 0 : void QGpgMENewCryptoConfigEntry::setIntValue(int i)
615 : {
616 0 : Q_ASSERT(m_option.alternateType() == IntegerType);
617 0 : Q_ASSERT(!isList());
618 0 : m_option.setNewValue(m_option.createIntArgument(i));
619 0 : }
620 :
621 0 : void QGpgMENewCryptoConfigEntry::setUIntValue(unsigned int i)
622 : {
623 0 : Q_ASSERT(m_option.alternateType() == UnsignedIntegerType);
624 0 : Q_ASSERT(!isList());
625 0 : m_option.setNewValue(m_option.createUIntArgument(i));
626 0 : }
627 :
628 0 : void QGpgMENewCryptoConfigEntry::setURLValue(const QUrl &url)
629 : {
630 0 : const Type type = m_option.type();
631 0 : Q_ASSERT(type == FilenameType || type == LdapServerType);
632 0 : Q_ASSERT(!isList());
633 0 : const QString str = splitURL(type, url);
634 : // cf. setStringValue()
635 0 : if (str.isEmpty() && !isOptional()) {
636 0 : m_option.resetToDefaultValue();
637 0 : } else if (type == FilenameType) {
638 0 : m_option.setNewValue(m_option.createStringArgument(QDir::toNativeSeparators(url.toLocalFile()).toUtf8().constData()));
639 : } else {
640 0 : m_option.setNewValue(m_option.createStringArgument(str.toUtf8().constData()));
641 : }
642 0 : }
643 :
644 0 : void QGpgMENewCryptoConfigEntry::setNumberOfTimesSet(unsigned int i)
645 : {
646 0 : Q_ASSERT(m_option.alternateType() == NoType);
647 0 : Q_ASSERT(isList());
648 0 : m_option.setNewValue(m_option.createNoneListArgument(i));
649 0 : }
650 :
651 0 : void QGpgMENewCryptoConfigEntry::setIntValueList(const std::vector<int> &lst)
652 : {
653 0 : Q_ASSERT(m_option.alternateType() == IntegerType);
654 0 : Q_ASSERT(isList());
655 0 : m_option.setNewValue(m_option.createIntListArgument(lst));
656 0 : }
657 :
658 0 : void QGpgMENewCryptoConfigEntry::setUIntValueList(const std::vector<unsigned int> &lst)
659 : {
660 0 : Q_ASSERT(m_option.alternateType() == UnsignedIntegerType);
661 0 : Q_ASSERT(isList());
662 0 : m_option.setNewValue(m_option.createUIntListArgument(lst));
663 0 : }
664 :
665 0 : void QGpgMENewCryptoConfigEntry::setURLValueList(const QList<QUrl> &urls)
666 : {
667 0 : const Type type = m_option.type();
668 0 : Q_ASSERT(m_option.alternateType() == StringType);
669 0 : Q_ASSERT(isList());
670 0 : std::vector<std::string> values;
671 0 : values.reserve(urls.size());
672 0 : Q_FOREACH (const QUrl &url, urls)
673 0 : if (type == FilenameType) {
674 0 : values.push_back(QFile::encodeName(url.path()).constData());
675 : } else {
676 0 : values.push_back(splitURL(type, url).toUtf8().constData());
677 : }
678 0 : m_option.setNewValue(m_option.createStringListArgument(values));
679 0 : }
680 :
681 0 : bool QGpgMENewCryptoConfigEntry::isDirty() const
682 : {
683 0 : return m_option.dirty();
684 : }
685 :
686 : #if 0
687 : QString QGpgMENewCryptoConfigEntry::toString(bool escape) const
688 : {
689 : // Basically the opposite of stringToValue
690 : if (isStringType()) {
691 : if (mValue.isNull()) {
692 : return QString();
693 : } else if (isList()) { // string list
694 : QStringList lst = mValue.toStringList();
695 : if (escape) {
696 : for (QStringList::iterator it = lst.begin(); it != lst.end(); ++it) {
697 : if (!(*it).isNull()) {
698 : *it = gpgconf_escape(*it).prepend("\"");
699 : }
700 : }
701 : }
702 : QString res = lst.join(",");
703 : //qCDebug(GPGPME_BACKEND_LOG) <<"toString:" << res;
704 : return res;
705 : } else { // normal string
706 : QString res = mValue.toString();
707 : if (escape) {
708 : res = gpgconf_escape(res).prepend("\"");
709 : }
710 : return res;
711 : }
712 : }
713 : if (!isList()) { // non-list non-string
714 : if (mArgType == ArgType_None) {
715 : return mValue.toBool() ? QString::fromLatin1("1") : QString();
716 : } else { // some int
717 : Q_ASSERT(mArgType == ArgType_Int || mArgType == ArgType_UInt);
718 : return mValue.toString(); // int to string conversion
719 : }
720 : }
721 :
722 : // Lists (of other types than strings)
723 : if (mArgType == ArgType_None) {
724 : return QString::number(numberOfTimesSet());
725 : }
726 : QStringList ret;
727 : QList<QVariant> lst = mValue.toList();
728 : for (QList<QVariant>::const_iterator it = lst.constBegin(); it != lst.constEnd(); ++it) {
729 : ret << (*it).toString(); // QVariant does the conversion
730 : }
731 : return ret.join(",");
732 : }
733 :
734 : QString QGpgMENewCryptoConfigEntry::outputString() const
735 : {
736 : Q_ASSERT(mSet);
737 : return toString(true);
738 : }
739 :
740 : bool QGpgMENewCryptoConfigEntry::isStringType() const
741 : {
742 : return (mArgType == QGpgME::NewCryptoConfigEntry::ArgType_String
743 : || mArgType == QGpgME::NewCryptoConfigEntry::ArgType_Path
744 : || mArgType == QGpgME::NewCryptoConfigEntry::ArgType_URL
745 : || mArgType == QGpgME::NewCryptoConfigEntry::ArgType_LDAPURL);
746 : }
747 :
748 : void QGpgMENewCryptoConfigEntry::setDirty(bool b)
749 : {
750 : mDirty = b;
751 : }
752 : #endif
|