Blame lang/qt/src/qgpgmenewcryptoconfig.cpp

Packit Service 672cf4
/*
Packit Service 672cf4
    qgpgmenewcryptoconfig.cpp
Packit Service 672cf4
Packit Service 672cf4
    This file is part of qgpgme, the Qt API binding for gpgme
Packit Service 672cf4
    Copyright (c) 2010 Klarälvdalens Datakonsult AB
Packit Service 672cf4
    Copyright (c) 2016 by Bundesamt für Sicherheit in der Informationstechnik
Packit Service 672cf4
    Software engineering by Intevation GmbH
Packit Service 672cf4
Packit Service 672cf4
    QGpgME is free software; you can redistribute it and/or
Packit Service 672cf4
    modify it under the terms of the GNU General Public License as
Packit Service 672cf4
    published by the Free Software Foundation; either version 2 of the
Packit Service 672cf4
    License, or (at your option) any later version.
Packit Service 672cf4
Packit Service 672cf4
    QGpgME is distributed in the hope that it will be useful,
Packit Service 672cf4
    but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 672cf4
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 672cf4
    General Public License for more details.
Packit Service 672cf4
Packit Service 672cf4
    You should have received a copy of the GNU General Public License
Packit Service 672cf4
    along with this program; if not, write to the Free Software
Packit Service 672cf4
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
Packit Service 672cf4
Packit Service 672cf4
    In addition, as a special exception, the copyright holders give
Packit Service 672cf4
    permission to link the code of this program with any edition of
Packit Service 672cf4
    the Qt library by Trolltech AS, Norway (or with modified versions
Packit Service 672cf4
    of Qt that use the same license as Qt), and distribute linked
Packit Service 672cf4
    combinations including the two.  You must obey the GNU General
Packit Service 672cf4
    Public License in all respects for all of the code used other than
Packit Service 672cf4
    Qt.  If you modify this file, you may extend this exception to
Packit Service 672cf4
    your version of the file, but you are not obligated to do so.  If
Packit Service 672cf4
    you do not wish to do so, delete this exception statement from
Packit Service 672cf4
    your version.
Packit Service 672cf4
*/
Packit Service 672cf4
Packit Service 672cf4
#ifdef HAVE_CONFIG_H
Packit Service 672cf4
 #include "config.h"
Packit Service 672cf4
#endif
Packit Service 672cf4
Packit Service 672cf4
#include "qgpgmenewcryptoconfig.h"
Packit Service 672cf4
Packit Service 672cf4
#include <QDebug>
Packit Service 672cf4
#include "gpgme_backend_debug.h"
Packit Service 672cf4
Packit Service 672cf4
#include <QFile>
Packit Service 672cf4
Packit Service 672cf4
#include "global.h"
Packit Service 672cf4
#include "error.h"
Packit Service 672cf4
Packit Service 672cf4
Packit Service 672cf4
#include <sstream>
Packit Service 672cf4
#include <string>
Packit Service 672cf4
#include <functional>
Packit Service 672cf4
#include <cassert>
Packit Service 672cf4
#include <functional>
Packit Service 672cf4
Packit Service 672cf4
using namespace QGpgME;
Packit Service 672cf4
using namespace GpgME;
Packit Service 672cf4
using namespace GpgME::Configuration;
Packit Service 672cf4
Packit Service 672cf4
namespace
Packit Service 672cf4
{
Packit Service 672cf4
struct Select1St {
Packit Service 672cf4
    template <typename U, typename V>
Packit Service 672cf4
    const U &operator()(const std::pair<U, V> &p) const
Packit Service 672cf4
    {
Packit Service 672cf4
        return p.first;
Packit Service 672cf4
    }
Packit Service 672cf4
    template <typename U, typename V>
Packit Service 672cf4
    const U &operator()(const QPair<U, V> &p) const
Packit Service 672cf4
    {
Packit Service 672cf4
        return p.first;
Packit Service 672cf4
    }
Packit Service 672cf4
};
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
// Just for the Q_ASSERT in the dtor. Not thread-safe, but who would
Packit Service 672cf4
// have 2 threads talking to gpgconf anyway? :)
Packit Service 672cf4
static bool s_duringClear = false;
Packit Service 672cf4
Packit Service 672cf4
QGpgMENewCryptoConfig::QGpgMENewCryptoConfig()
Packit Service 672cf4
    :  m_parsed(false)
Packit Service 672cf4
{
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
QGpgMENewCryptoConfig::~QGpgMENewCryptoConfig()
Packit Service 672cf4
{
Packit Service 672cf4
    clear();
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
void QGpgMENewCryptoConfig::reloadConfiguration(bool)
Packit Service 672cf4
{
Packit Service 672cf4
    clear();
Packit Service 672cf4
Packit Service 672cf4
    Error error;
Packit Service 672cf4
    const std::vector<Component> components = Component::load(error);
Packit Service 672cf4
#ifndef NDEBUG
Packit Service 672cf4
    {
Packit Service 672cf4
        std::stringstream ss;
Packit Service 672cf4
        ss << "error: " << error
Packit Service 672cf4
           << "components:\n";
Packit Service 672cf4
        std::copy(components.begin(), components.end(),
Packit Service 672cf4
                  std::ostream_iterator<Component>(ss, "\n"));
Packit Service 672cf4
        qCDebug(GPGPME_BACKEND_LOG) << ss.str().c_str();
Packit Service 672cf4
    }
Packit Service 672cf4
#endif
Packit Service 672cf4
#if 0
Packit Service 672cf4
    TODO port?
Packit Service 672cf4
    if (error && showErrors) {
Packit Service 672cf4
        const QString wmsg = i18n("<qt>Failed to execute gpgconf:

%1

</qt>", QString::fromLocal8Bit(error.asString()));
Packit Service 672cf4
        qCWarning(GPGPME_BACKEND_LOG) << wmsg; // to see it from test_cryptoconfig.cpp
Packit Service 672cf4
        KMessageBox::error(0, wmsg);
Packit Service 672cf4
    }
Packit Service 672cf4
#endif
Packit Service 672cf4
    Q_FOREACH(const Component & c, components) {
Packit Service 672cf4
        const std::shared_ptr<QGpgMENewCryptoConfigComponent> comp(new QGpgMENewCryptoConfigComponent);
Packit Service 672cf4
        comp->setComponent(c);
Packit Service 672cf4
        m_componentsByName[ comp->name() ] = comp;
Packit Service 672cf4
    }
Packit Service 672cf4
    m_parsed = true;
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
QStringList QGpgMENewCryptoConfig::componentList() const
Packit Service 672cf4
{
Packit Service 672cf4
    if (!m_parsed) {
Packit Service 672cf4
        const_cast<QGpgMENewCryptoConfig *>(this)->reloadConfiguration(true);
Packit Service 672cf4
    }
Packit Service 672cf4
    QStringList result;
Packit Service 672cf4
    std::transform(m_componentsByName.begin(), m_componentsByName.end(),
Packit Service 672cf4
                   std::back_inserter(result),
Packit Service 672cf4
                   mem_fn(&QGpgMENewCryptoConfigComponent::name));
Packit Service 672cf4
    return result;
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
QGpgMENewCryptoConfigComponent *QGpgMENewCryptoConfig::component(const QString &name) const
Packit Service 672cf4
{
Packit Service 672cf4
    if (!m_parsed) {
Packit Service 672cf4
        const_cast<QGpgMENewCryptoConfig *>(this)->reloadConfiguration(false);
Packit Service 672cf4
    }
Packit Service 672cf4
    return m_componentsByName.value(name).get();
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
void QGpgMENewCryptoConfig::sync(bool runtime)
Packit Service 672cf4
{
Packit Service 672cf4
    Q_FOREACH(const std::shared_ptr<QGpgMENewCryptoConfigComponent> &c, m_componentsByName)
Packit Service 672cf4
    c->sync(runtime);
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
void QGpgMENewCryptoConfig::clear()
Packit Service 672cf4
{
Packit Service 672cf4
    s_duringClear = true;
Packit Service 672cf4
    m_componentsByName.clear();
Packit Service 672cf4
    s_duringClear = false;
Packit Service 672cf4
    m_parsed = false; // next call to componentList/component will need to run gpgconf again
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
////
Packit Service 672cf4
Packit Service 672cf4
QGpgMENewCryptoConfigComponent::QGpgMENewCryptoConfigComponent()
Packit Service 672cf4
    : CryptoConfigComponent(),
Packit Service 672cf4
      m_component()
Packit Service 672cf4
{
Packit Service 672cf4
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
void QGpgMENewCryptoConfigComponent::setComponent(const Component &component)
Packit Service 672cf4
{
Packit Service 672cf4
    m_component = component;
Packit Service 672cf4
    m_groupsByName.clear();
Packit Service 672cf4
Packit Service 672cf4
    std::shared_ptr<QGpgMENewCryptoConfigGroup> group;
Packit Service 672cf4
Packit Service 672cf4
    const std::vector<Option> options = m_component.options();
Packit Service 672cf4
    Q_FOREACH(const Option & o, options)
Packit Service 672cf4
    if (o.flags() & Group) {
Packit Service 672cf4
        if (group) {
Packit Service 672cf4
            m_groupsByName[group->name()] = group;
Packit Service 672cf4
        }
Packit Service 672cf4
        group.reset(new QGpgMENewCryptoConfigGroup(shared_from_this(), o));
Packit Service 672cf4
    } else if (group) {
Packit Service 672cf4
        const std::shared_ptr<QGpgMENewCryptoConfigEntry> entry(new QGpgMENewCryptoConfigEntry(group, o));
Packit Service 672cf4
        const QString name = entry->name();
Packit Service 672cf4
        group->m_entryNames.push_back(name);
Packit Service 672cf4
        group->m_entriesByName[name] = entry;
Packit Service 672cf4
    } else {
Packit Service 672cf4
        qCWarning(GPGPME_BACKEND_LOG) << "found no group for entry" << o.name() << "of component" << name();
Packit Service 672cf4
    }
Packit Service 672cf4
    if (group) {
Packit Service 672cf4
        m_groupsByName[group->name()] = group;
Packit Service 672cf4
    }
Packit Service 672cf4
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
QGpgMENewCryptoConfigComponent::~QGpgMENewCryptoConfigComponent() {}
Packit Service 672cf4
Packit Service 672cf4
QString QGpgMENewCryptoConfigComponent::name() const
Packit Service 672cf4
{
Packit Service 672cf4
    return QString::fromUtf8(m_component.name());
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
QString QGpgMENewCryptoConfigComponent::description() const
Packit Service 672cf4
{
Packit Service 672cf4
    return QString::fromUtf8(m_component.description());
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
QStringList QGpgMENewCryptoConfigComponent::groupList() const
Packit Service 672cf4
{
Packit Service 672cf4
    QStringList result;
Packit Service 672cf4
    result.reserve(m_groupsByName.size());
Packit Service 672cf4
    std::transform(m_groupsByName.begin(), m_groupsByName.end(),
Packit Service 672cf4
                   std::back_inserter(result),
Packit Service 672cf4
                   std::mem_fn(&QGpgMENewCryptoConfigGroup::name));
Packit Service 672cf4
    return result;
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
QGpgMENewCryptoConfigGroup *QGpgMENewCryptoConfigComponent::group(const QString &name) const
Packit Service 672cf4
{
Packit Service 672cf4
    return m_groupsByName.value(name).get();
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
void QGpgMENewCryptoConfigComponent::sync(bool runtime)
Packit Service 672cf4
{
Packit Service 672cf4
    Q_UNUSED(runtime) // runtime is always set by engine_gpgconf
Packit Service 672cf4
    if (const Error err = m_component.save()) {
Packit Service 672cf4
        qCWarning(GPGPME_BACKEND_LOG) << ":"
Packit Service 672cf4
            << "Error from gpgconf while saving configuration: %1"
Packit Service 672cf4
            << QString::fromLocal8Bit(err.asString());
Packit Service 672cf4
    }
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
////
Packit Service 672cf4
Packit Service 672cf4
QGpgMENewCryptoConfigGroup::QGpgMENewCryptoConfigGroup(const std::shared_ptr<QGpgMENewCryptoConfigComponent> &comp, const Option &option)
Packit Service 672cf4
    : CryptoConfigGroup(),
Packit Service 672cf4
      m_component(comp),
Packit Service 672cf4
      m_option(option)
Packit Service 672cf4
{
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
QGpgMENewCryptoConfigGroup::~QGpgMENewCryptoConfigGroup() {}
Packit Service 672cf4
Packit Service 672cf4
QString QGpgMENewCryptoConfigGroup::name() const
Packit Service 672cf4
{
Packit Service 672cf4
    return QString::fromUtf8(m_option.name());
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
QString QGpgMENewCryptoConfigGroup::description() const
Packit Service 672cf4
{
Packit Service 672cf4
    return QString::fromUtf8(m_option.description());
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
QString QGpgMENewCryptoConfigGroup::path() const
Packit Service 672cf4
{
Packit Service 672cf4
    if (const std::shared_ptr<QGpgMENewCryptoConfigComponent> c = m_component.lock()) {
Packit Service 672cf4
        return c->name() + QLatin1Char('/') + name();
Packit Service 672cf4
    } else {
Packit Service 672cf4
        return QString();
Packit Service 672cf4
    }
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
CryptoConfigEntry::Level QGpgMENewCryptoConfigGroup::level() const
Packit Service 672cf4
{
Packit Service 672cf4
    // two casts to make SunCC happy:
Packit Service 672cf4
    return static_cast<CryptoConfigEntry::Level>(static_cast<unsigned int>(m_option.level()));
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
QStringList QGpgMENewCryptoConfigGroup::entryList() const
Packit Service 672cf4
{
Packit Service 672cf4
    return m_entryNames;
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
QGpgMENewCryptoConfigEntry *QGpgMENewCryptoConfigGroup::entry(const QString &name) const
Packit Service 672cf4
{
Packit Service 672cf4
    return m_entriesByName.value(name).get();
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
static QString urlpart_encode(const QString &str)
Packit Service 672cf4
{
Packit Service 672cf4
    QString enc(str);
Packit Service 672cf4
    enc.replace(QLatin1Char('%'), QStringLiteral("%25"));   // first!
Packit Service 672cf4
    enc.replace(QLatin1Char(':'), QStringLiteral("%3a"));
Packit Service 672cf4
    //qCDebug(GPGPME_BACKEND_LOG) <<"  urlpart_encode:" << str <<" ->" << enc;
Packit Service 672cf4
    return enc;
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
static QString urlpart_decode(const QString &str)
Packit Service 672cf4
{
Packit Service 672cf4
    return QUrl::fromPercentEncoding(str.toLatin1());
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
// gpgconf arg type number -> NewCryptoConfigEntry arg type enum mapping
Packit Service 672cf4
static QGpgME::CryptoConfigEntry::ArgType knownArgType(int argType, bool &ok)
Packit Service 672cf4
{
Packit Service 672cf4
    ok = true;
Packit Service 672cf4
    switch (argType) {
Packit Service 672cf4
    case 0: // none
Packit Service 672cf4
        return QGpgME::CryptoConfigEntry::ArgType_None;
Packit Service 672cf4
    case 1: // string
Packit Service 672cf4
        return QGpgME::CryptoConfigEntry::ArgType_String;
Packit Service 672cf4
    case 2: // int32
Packit Service 672cf4
        return QGpgME::CryptoConfigEntry::ArgType_Int;
Packit Service 672cf4
    case 3: // uint32
Packit Service 672cf4
        return QGpgME::CryptoConfigEntry::ArgType_UInt;
Packit Service 672cf4
    case 32: // pathname
Packit Service 672cf4
        return QGpgME::CryptoConfigEntry::ArgType_Path;
Packit Service 672cf4
    case 33: // ldap server
Packit Service 672cf4
        return QGpgME::CryptoConfigEntry::ArgType_LDAPURL;
Packit Service 672cf4
    default:
Packit Service 672cf4
        ok = false;
Packit Service 672cf4
        return QGpgME::CryptoConfigEntry::ArgType_None;
Packit Service 672cf4
    }
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
QGpgMENewCryptoConfigEntry::QGpgMENewCryptoConfigEntry(const std::shared_ptr<QGpgMENewCryptoConfigGroup> &group, const Option &option)
Packit Service 672cf4
    : m_group(group), m_option(option)
Packit Service 672cf4
{
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
#if 0
Packit Service 672cf4
QVariant QGpgMENewCryptoConfigEntry::stringToValue(const QString &str, bool unescape) const
Packit Service 672cf4
{
Packit Service 672cf4
    const bool isString = isStringType();
Packit Service 672cf4
Packit Service 672cf4
    if (isList()) {
Packit Service 672cf4
        if (argType() == ArgType_None) {
Packit Service 672cf4
            bool ok = true;
Packit Service 672cf4
            const QVariant v = str.isEmpty() ? 0U : str.toUInt(&ok;;
Packit Service 672cf4
            if (!ok) {
Packit Service 672cf4
                qCWarning(GPGPME_BACKEND_LOG) << "list-of-none should have an unsigned int as value:" << str;
Packit Service 672cf4
            }
Packit Service 672cf4
            return v;
Packit Service 672cf4
        }
Packit Service 672cf4
        QList<QVariant> lst;
Packit Service 672cf4
        QStringList items = str.split(',', QString::SkipEmptyParts);
Packit Service 672cf4
        for (QStringList::const_iterator valit = items.constBegin(); valit != items.constEnd(); ++valit) {
Packit Service 672cf4
            QString val = *valit;
Packit Service 672cf4
            if (isString) {
Packit Service 672cf4
                if (val.isEmpty()) {
Packit Service 672cf4
                    lst << QVariant(QString());
Packit Service 672cf4
                    continue;
Packit Service 672cf4
                } else if (unescape) {
Packit Service 672cf4
                    if (val[0] != '"') { // see README.gpgconf
Packit Service 672cf4
                        qCWarning(GPGPME_BACKEND_LOG) << "String value should start with '\"' :" << val;
Packit Service 672cf4
                    }
Packit Service 672cf4
                    val = val.mid(1);
Packit Service 672cf4
                }
Packit Service 672cf4
            }
Packit Service 672cf4
            lst << QVariant(unescape ? gpgconf_unescape(val) : val);
Packit Service 672cf4
        }
Packit Service 672cf4
        return lst;
Packit Service 672cf4
    } else { // not a list
Packit Service 672cf4
        QString val(str);
Packit Service 672cf4
        if (isString) {
Packit Service 672cf4
            if (val.isEmpty()) {
Packit Service 672cf4
                return QVariant(QString());    // not set  [ok with lists too?]
Packit Service 672cf4
            } else if (unescape) {
Packit Service 672cf4
                if (val[0] != '"') { // see README.gpgconf
Packit Service 672cf4
                    qCWarning(GPGPME_BACKEND_LOG) << "String value should start with '\"' :" << val;
Packit Service 672cf4
                }
Packit Service 672cf4
                val = val.mid(1);
Packit Service 672cf4
            }
Packit Service 672cf4
        }
Packit Service 672cf4
        return QVariant(unescape ? gpgconf_unescape(val) : val);
Packit Service 672cf4
    }
Packit Service 672cf4
}
Packit Service 672cf4
#endif
Packit Service 672cf4
Packit Service 672cf4
QGpgMENewCryptoConfigEntry::~QGpgMENewCryptoConfigEntry()
Packit Service 672cf4
{
Packit Service 672cf4
#ifndef NDEBUG
Packit Service 672cf4
    if (!s_duringClear && m_option.dirty())
Packit Service 672cf4
        qCWarning(GPGPME_BACKEND_LOG) << "Deleting a QGpgMENewCryptoConfigEntry that was modified (" << m_option.description() << ")"
Packit Service 672cf4
                                      << "You forgot to call sync() (to commit) or clear() (to discard)";
Packit Service 672cf4
#endif
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
QString QGpgMENewCryptoConfigEntry::name() const
Packit Service 672cf4
{
Packit Service 672cf4
    return QString::fromUtf8(m_option.name());
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
QString QGpgMENewCryptoConfigEntry::description() const
Packit Service 672cf4
{
Packit Service 672cf4
    return QString::fromUtf8(m_option.description());
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
QString QGpgMENewCryptoConfigEntry::path() const
Packit Service 672cf4
{
Packit Service 672cf4
    if (const std::shared_ptr<QGpgMENewCryptoConfigGroup> g = m_group.lock()) {
Packit Service 672cf4
        return g->path() + QLatin1Char('/') + name();
Packit Service 672cf4
    } else {
Packit Service 672cf4
        return QString();
Packit Service 672cf4
    }
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
bool QGpgMENewCryptoConfigEntry::isOptional() const
Packit Service 672cf4
{
Packit Service 672cf4
    return m_option.flags() & Optional;
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
bool QGpgMENewCryptoConfigEntry::isReadOnly() const
Packit Service 672cf4
{
Packit Service 672cf4
    return m_option.flags() & NoChange;
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
bool QGpgMENewCryptoConfigEntry::isList() const
Packit Service 672cf4
{
Packit Service 672cf4
    return m_option.flags() & List;
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
bool QGpgMENewCryptoConfigEntry::isRuntime() const
Packit Service 672cf4
{
Packit Service 672cf4
    return m_option.flags() & Runtime;
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
CryptoConfigEntry::Level QGpgMENewCryptoConfigEntry::level() const
Packit Service 672cf4
{
Packit Service 672cf4
    // two casts to make SunCC happy:
Packit Service 672cf4
    return static_cast<Level>(static_cast<unsigned int>(m_option.level()));
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
CryptoConfigEntry::ArgType QGpgMENewCryptoConfigEntry::argType() const
Packit Service 672cf4
{
Packit Service 672cf4
    bool ok = false;
Packit Service 672cf4
    const ArgType type = knownArgType(m_option.type(), ok);
Packit Service 672cf4
    if (ok) {
Packit Service 672cf4
        return type;
Packit Service 672cf4
    } else {
Packit Service 672cf4
        return knownArgType(m_option.alternateType(), ok);
Packit Service 672cf4
    }
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
bool QGpgMENewCryptoConfigEntry::isSet() const
Packit Service 672cf4
{
Packit Service 672cf4
    return m_option.set();
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
bool QGpgMENewCryptoConfigEntry::boolValue() const
Packit Service 672cf4
{
Packit Service 672cf4
    Q_ASSERT(m_option.alternateType() == NoType);
Packit Service 672cf4
    Q_ASSERT(!isList());
Packit Service 672cf4
    return m_option.currentValue().boolValue();
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
QString QGpgMENewCryptoConfigEntry::stringValue() const
Packit Service 672cf4
{
Packit Service 672cf4
    //return toString( false );
Packit Service 672cf4
    Q_ASSERT(m_option.alternateType() == StringType);
Packit Service 672cf4
    Q_ASSERT(!isList());
Packit Service 672cf4
    return QString::fromUtf8(m_option.currentValue().stringValue());
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
int QGpgMENewCryptoConfigEntry::intValue() const
Packit Service 672cf4
{
Packit Service 672cf4
    Q_ASSERT(m_option.alternateType() == IntegerType);
Packit Service 672cf4
    Q_ASSERT(!isList());
Packit Service 672cf4
    return m_option.currentValue().intValue();
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
unsigned int QGpgMENewCryptoConfigEntry::uintValue() const
Packit Service 672cf4
{
Packit Service 672cf4
    Q_ASSERT(m_option.alternateType() == UnsignedIntegerType);
Packit Service 672cf4
    Q_ASSERT(!isList());
Packit Service 672cf4
    return m_option.currentValue().uintValue();
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
static QUrl parseURL(int mRealArgType, const QString &str)
Packit Service 672cf4
{
Packit Service 672cf4
    if (mRealArgType == 33) {   // LDAP server
Packit Service 672cf4
        // The format is HOSTNAME:PORT:USERNAME:PASSWORD:BASE_DN
Packit Service 672cf4
        QStringList items = str.split(QLatin1Char(':'));
Packit Service 672cf4
        if (items.count() == 5) {
Packit Service 672cf4
            QStringList::const_iterator it = items.constBegin();
Packit Service 672cf4
            QUrl url;
Packit Service 672cf4
            url.setScheme(QStringLiteral("ldap"));
Packit Service 672cf4
            url.setHost(urlpart_decode(*it++));
Packit Service 672cf4
Packit Service 672cf4
            bool ok;
Packit Service 672cf4
            const int port = (*it++).toInt(&ok;;
Packit Service 672cf4
            if (ok) {
Packit Service 672cf4
                url.setPort(port);
Packit Service 672cf4
            } else if (!it->isEmpty()) {
Packit Service 672cf4
                qCWarning(GPGPME_BACKEND_LOG) << "parseURL: malformed LDAP server port, ignoring: \"" << *it << "\"";
Packit Service 672cf4
            }
Packit Service 672cf4
Packit Service 672cf4
            const QString userName = urlpart_decode(*it++);
Packit Service 672cf4
            if (!userName.isEmpty()) {
Packit Service 672cf4
                url.setUserName(userName);
Packit Service 672cf4
            }
Packit Service 672cf4
            const QString passWord = urlpart_decode(*it++);
Packit Service 672cf4
            if (!passWord.isEmpty()) {
Packit Service 672cf4
                url.setPassword(passWord);
Packit Service 672cf4
            }
Packit Service 672cf4
            url.setQuery(urlpart_decode(*it));
Packit Service 672cf4
            return url;
Packit Service 672cf4
        } else {
Packit Service 672cf4
            qCWarning(GPGPME_BACKEND_LOG) << "parseURL: malformed LDAP server:" << str;
Packit Service 672cf4
        }
Packit Service 672cf4
    }
Packit Service 672cf4
    // other URLs : assume wellformed URL syntax.
Packit Service 672cf4
    return QUrl(str);
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
// The opposite of parseURL
Packit Service 672cf4
static QString splitURL(int mRealArgType, const QUrl &url)
Packit Service 672cf4
{
Packit Service 672cf4
    if (mRealArgType == 33) {   // LDAP server
Packit Service 672cf4
        // The format is HOSTNAME:PORT:USERNAME:PASSWORD:BASE_DN
Packit Service 672cf4
        Q_ASSERT(url.scheme() == QLatin1String("ldap"));
Packit Service 672cf4
        return urlpart_encode(url.host()) + QLatin1Char(':') +
Packit Service 672cf4
               (url.port() != -1 ? QString::number(url.port()) : QString()) + QLatin1Char(':') +     // -1 is used for default ports, omit
Packit Service 672cf4
               urlpart_encode(url.userName()) + QLatin1Char(':') +
Packit Service 672cf4
               urlpart_encode(url.password()) + QLatin1Char(':') +
Packit Service 672cf4
               urlpart_encode(url.query());
Packit Service 672cf4
    }
Packit Service 672cf4
    return url.path();
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
QUrl QGpgMENewCryptoConfigEntry::urlValue() const
Packit Service 672cf4
{
Packit Service 672cf4
    const Type type = m_option.type();
Packit Service 672cf4
    Q_ASSERT(type == FilenameType || type == LdapServerType);
Packit Service 672cf4
    Q_ASSERT(!isList());
Packit Service 672cf4
    if (type == FilenameType) {
Packit Service 6c01f9
        QUrl url;
Packit Service 6c01f9
        url.setPath(QFile::decodeName(m_option.currentValue().stringValue()));
Packit Service 672cf4
        return url;
Packit Service 672cf4
    }
Packit Service 672cf4
    return parseURL(type, stringValue());
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
unsigned int QGpgMENewCryptoConfigEntry::numberOfTimesSet() const
Packit Service 672cf4
{
Packit Service 672cf4
    Q_ASSERT(m_option.alternateType() == NoType);
Packit Service 672cf4
    Q_ASSERT(isList());
Packit Service 672cf4
    return m_option.currentValue().uintValue();
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
std::vector<int> QGpgMENewCryptoConfigEntry::intValueList() const
Packit Service 672cf4
{
Packit Service 672cf4
    Q_ASSERT(m_option.alternateType() == IntegerType);
Packit Service 672cf4
    Q_ASSERT(isList());
Packit Service 672cf4
    return m_option.currentValue().intValues();
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
std::vector<unsigned int> QGpgMENewCryptoConfigEntry::uintValueList() const
Packit Service 672cf4
{
Packit Service 672cf4
    Q_ASSERT(m_option.alternateType() == UnsignedIntegerType);
Packit Service 672cf4
    Q_ASSERT(isList());
Packit Service 672cf4
    return m_option.currentValue().uintValues();
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
QStringList QGpgMENewCryptoConfigEntry::stringValueList() const
Packit Service 672cf4
{
Packit Service 672cf4
    Q_ASSERT(isList());
Packit Service 672cf4
    const Argument arg = m_option.currentValue();
Packit Service 672cf4
    const std::vector<const char *> values = arg.stringValues();
Packit Service 672cf4
    QStringList ret;
Packit Service 672cf4
    for(const char *value: values) {
Packit Service 672cf4
        ret << QString::fromUtf8(value);
Packit Service 672cf4
    }
Packit Service 672cf4
    return ret;
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
QList<QUrl> QGpgMENewCryptoConfigEntry::urlValueList() const
Packit Service 672cf4
{
Packit Service 672cf4
    const Type type = m_option.type();
Packit Service 672cf4
    Q_ASSERT(type == FilenameType || type == LdapServerType);
Packit Service 672cf4
    Q_ASSERT(isList());
Packit Service 672cf4
    const Argument arg = m_option.currentValue();
Packit Service 672cf4
    const std::vector<const char *> values = arg.stringValues();
Packit Service 672cf4
    QList<QUrl> ret;
Packit Service 672cf4
    Q_FOREACH(const char *value, values)
Packit Service 672cf4
    if (type == FilenameType) {
Packit Service 672cf4
        QUrl url;
Packit Service 672cf4
        url.setPath(QFile::decodeName(value));
Packit Service 672cf4
        ret << url;
Packit Service 672cf4
    } else {
Packit Service 672cf4
        ret << parseURL(type, QString::fromUtf8(value));
Packit Service 672cf4
    }
Packit Service 672cf4
    return ret;
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
void QGpgMENewCryptoConfigEntry::resetToDefault()
Packit Service 672cf4
{
Packit Service 672cf4
    m_option.resetToDefaultValue();
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
void QGpgMENewCryptoConfigEntry::setBoolValue(bool b)
Packit Service 672cf4
{
Packit Service 672cf4
    Q_ASSERT(m_option.alternateType() == NoType);
Packit Service 672cf4
    Q_ASSERT(!isList());
Packit Service 672cf4
    // A "no arg" option is either set or not set.
Packit Service 672cf4
    // Being set means createNoneArgument(), being unset means resetToDefault()
Packit Service 672cf4
    m_option.setNewValue(m_option.createNoneArgument(b));
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
void QGpgMENewCryptoConfigEntry::setStringValue(const QString &str)
Packit Service 672cf4
{
Packit Service 672cf4
    Q_ASSERT(m_option.alternateType() == StringType);
Packit Service 672cf4
    Q_ASSERT(!isList());
Packit Service 672cf4
    const Type type = m_option.type();
Packit Service 672cf4
    // When setting a string to empty (and there's no default), we need to act like resetToDefault
Packit Service 672cf4
    // Otherwise we try e.g. "ocsp-responder:0:" and gpgconf answers:
Packit Service 672cf4
    // "gpgconf: argument required for option ocsp-responder"
Packit Service 672cf4
    if (str.isEmpty() && !isOptional()) {
Packit Service 672cf4
        m_option.resetToDefaultValue();
Packit Service 672cf4
    } else if (type == FilenameType) {
Packit Service 672cf4
        m_option.setNewValue(m_option.createStringArgument(QFile::encodeName(str).constData()));
Packit Service 672cf4
    } else {
Packit Service 672cf4
        m_option.setNewValue(m_option.createStringArgument(str.toUtf8().constData()));
Packit Service 672cf4
    }
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
void QGpgMENewCryptoConfigEntry::setIntValue(int i)
Packit Service 672cf4
{
Packit Service 672cf4
    Q_ASSERT(m_option.alternateType() == IntegerType);
Packit Service 672cf4
    Q_ASSERT(!isList());
Packit Service 672cf4
    m_option.setNewValue(m_option.createIntArgument(i));
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
void QGpgMENewCryptoConfigEntry::setUIntValue(unsigned int i)
Packit Service 672cf4
{
Packit Service 672cf4
    Q_ASSERT(m_option.alternateType() == UnsignedIntegerType);
Packit Service 672cf4
    Q_ASSERT(!isList());
Packit Service 672cf4
    m_option.setNewValue(m_option.createUIntArgument(i));
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
void QGpgMENewCryptoConfigEntry::setURLValue(const QUrl &url)
Packit Service 672cf4
{
Packit Service 672cf4
    const Type type = m_option.type();
Packit Service 672cf4
    Q_ASSERT(type == FilenameType || type == LdapServerType);
Packit Service 672cf4
    Q_ASSERT(!isList());
Packit Service 672cf4
    const QString str = splitURL(type, url);
Packit Service 672cf4
    // cf. setStringValue()
Packit Service 672cf4
    if (str.isEmpty() && !isOptional()) {
Packit Service 672cf4
        m_option.resetToDefaultValue();
Packit Service 672cf4
    } else if (type == FilenameType) {
Packit Service 6c01f9
        m_option.setNewValue(m_option.createStringArgument(QFile::encodeName(str).constData()));
Packit Service 672cf4
    } else {
Packit Service 672cf4
        m_option.setNewValue(m_option.createStringArgument(str.toUtf8().constData()));
Packit Service 672cf4
    }
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
void QGpgMENewCryptoConfigEntry::setNumberOfTimesSet(unsigned int i)
Packit Service 672cf4
{
Packit Service 672cf4
    Q_ASSERT(m_option.alternateType() == NoType);
Packit Service 672cf4
    Q_ASSERT(isList());
Packit Service 672cf4
    m_option.setNewValue(m_option.createNoneListArgument(i));
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
void QGpgMENewCryptoConfigEntry::setIntValueList(const std::vector<int> &lst)
Packit Service 672cf4
{
Packit Service 672cf4
    Q_ASSERT(m_option.alternateType() == IntegerType);
Packit Service 672cf4
    Q_ASSERT(isList());
Packit Service 672cf4
    m_option.setNewValue(m_option.createIntListArgument(lst));
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
void QGpgMENewCryptoConfigEntry::setUIntValueList(const std::vector<unsigned int> &lst)
Packit Service 672cf4
{
Packit Service 672cf4
    Q_ASSERT(m_option.alternateType() == UnsignedIntegerType);
Packit Service 672cf4
    Q_ASSERT(isList());
Packit Service 672cf4
    m_option.setNewValue(m_option.createUIntListArgument(lst));
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
void QGpgMENewCryptoConfigEntry::setURLValueList(const QList<QUrl> &urls)
Packit Service 672cf4
{
Packit Service 672cf4
    const Type type = m_option.type();
Packit Service 672cf4
    Q_ASSERT(m_option.alternateType() == StringType);
Packit Service 672cf4
    Q_ASSERT(isList());
Packit Service 672cf4
    std::vector<std::string> values;
Packit Service 672cf4
    values.reserve(urls.size());
Packit Service 672cf4
    Q_FOREACH (const QUrl &url, urls)
Packit Service 672cf4
        if (type == FilenameType) {
Packit Service 672cf4
            values.push_back(QFile::encodeName(url.path()).constData());
Packit Service 672cf4
        } else {
Packit Service 672cf4
            values.push_back(splitURL(type, url).toUtf8().constData());
Packit Service 672cf4
        }
Packit Service 672cf4
    m_option.setNewValue(m_option.createStringListArgument(values));
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
bool QGpgMENewCryptoConfigEntry::isDirty() const
Packit Service 672cf4
{
Packit Service 672cf4
    return m_option.dirty();
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
#if 0
Packit Service 672cf4
QString QGpgMENewCryptoConfigEntry::toString(bool escape) const
Packit Service 672cf4
{
Packit Service 672cf4
    // Basically the opposite of stringToValue
Packit Service 672cf4
    if (isStringType()) {
Packit Service 672cf4
        if (mValue.isNull()) {
Packit Service 672cf4
            return QString();
Packit Service 672cf4
        } else if (isList()) { // string list
Packit Service 672cf4
            QStringList lst = mValue.toStringList();
Packit Service 672cf4
            if (escape) {
Packit Service 672cf4
                for (QStringList::iterator it = lst.begin(); it != lst.end(); ++it) {
Packit Service 672cf4
                    if (!(*it).isNull()) {
Packit Service 672cf4
                        *it = gpgconf_escape(*it).prepend("\"");
Packit Service 672cf4
                    }
Packit Service 672cf4
                }
Packit Service 672cf4
            }
Packit Service 672cf4
            QString res = lst.join(",");
Packit Service 672cf4
            //qCDebug(GPGPME_BACKEND_LOG) <<"toString:" << res;
Packit Service 672cf4
            return res;
Packit Service 672cf4
        } else { // normal string
Packit Service 672cf4
            QString res = mValue.toString();
Packit Service 672cf4
            if (escape) {
Packit Service 672cf4
                res = gpgconf_escape(res).prepend("\"");
Packit Service 672cf4
            }
Packit Service 672cf4
            return res;
Packit Service 672cf4
        }
Packit Service 672cf4
    }
Packit Service 672cf4
    if (!isList()) { // non-list non-string
Packit Service 672cf4
        if (mArgType == ArgType_None) {
Packit Service 672cf4
            return mValue.toBool() ? QString::fromLatin1("1") : QString();
Packit Service 672cf4
        } else { // some int
Packit Service 672cf4
            Q_ASSERT(mArgType == ArgType_Int || mArgType == ArgType_UInt);
Packit Service 672cf4
            return mValue.toString(); // int to string conversion
Packit Service 672cf4
        }
Packit Service 672cf4
    }
Packit Service 672cf4
Packit Service 672cf4
    // Lists (of other types than strings)
Packit Service 672cf4
    if (mArgType == ArgType_None) {
Packit Service 672cf4
        return QString::number(numberOfTimesSet());
Packit Service 672cf4
    }
Packit Service 672cf4
    QStringList ret;
Packit Service 672cf4
    QList<QVariant> lst = mValue.toList();
Packit Service 672cf4
    for (QList<QVariant>::const_iterator it = lst.constBegin(); it != lst.constEnd(); ++it) {
Packit Service 672cf4
        ret << (*it).toString(); // QVariant does the conversion
Packit Service 672cf4
    }
Packit Service 672cf4
    return ret.join(",");
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
QString QGpgMENewCryptoConfigEntry::outputString() const
Packit Service 672cf4
{
Packit Service 672cf4
    Q_ASSERT(mSet);
Packit Service 672cf4
    return toString(true);
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
bool QGpgMENewCryptoConfigEntry::isStringType() const
Packit Service 672cf4
{
Packit Service 672cf4
    return (mArgType == QGpgME::NewCryptoConfigEntry::ArgType_String
Packit Service 672cf4
            || mArgType == QGpgME::NewCryptoConfigEntry::ArgType_Path
Packit Service 672cf4
            || mArgType == QGpgME::NewCryptoConfigEntry::ArgType_URL
Packit Service 672cf4
            || mArgType == QGpgME::NewCryptoConfigEntry::ArgType_LDAPURL);
Packit Service 672cf4
}
Packit Service 672cf4
Packit Service 672cf4
void QGpgMENewCryptoConfigEntry::setDirty(bool b)
Packit Service 672cf4
{
Packit Service 672cf4
    mDirty = b;
Packit Service 672cf4
}
Packit Service 672cf4
#endif