mirror of
https://github.com/keepassxreboot/keepassxc.git
synced 2025-02-22 15:39:57 -05:00
FdoSecrets: add unit tests
This commit is contained in:
parent
af6493b07b
commit
44779bc862
@ -31,7 +31,8 @@
|
||||
using FdoSecrets::Service;
|
||||
|
||||
FdoSecretsPlugin::FdoSecretsPlugin(DatabaseTabWidget* tabWidget)
|
||||
: m_dbTabs(tabWidget)
|
||||
: QObject(tabWidget)
|
||||
, m_dbTabs(tabWidget)
|
||||
{
|
||||
FdoSecrets::registerDBusTypes();
|
||||
}
|
||||
|
@ -75,6 +75,8 @@ namespace FdoSecrets
|
||||
m_registered = false;
|
||||
}
|
||||
|
||||
Q_ASSERT(m_backend);
|
||||
|
||||
// make sure we have updated copy of the filepath, which is used to identify the database.
|
||||
m_backendPath = m_backend->database()->filePath();
|
||||
|
||||
@ -310,13 +312,13 @@ namespace FdoSecrets
|
||||
QString itemPath;
|
||||
StringStringMap attributes;
|
||||
|
||||
// check existing item using attributes
|
||||
auto iterAttr = properties.find(QStringLiteral(DBUS_INTERFACE_SECRET_ITEM ".Attributes"));
|
||||
if (iterAttr != properties.end()) {
|
||||
attributes = qdbus_cast<StringStringMap>(iterAttr.value().value<QDBusArgument>());
|
||||
attributes = iterAttr.value().value<StringStringMap>();
|
||||
|
||||
itemPath = attributes.value(ItemAttributes::PathKey);
|
||||
|
||||
// check existing item using attributes
|
||||
auto existings = searchItems(attributes);
|
||||
if (existings.isError()) {
|
||||
return existings;
|
||||
@ -614,6 +616,11 @@ namespace FdoSecrets
|
||||
|
||||
void Collection::doDelete()
|
||||
{
|
||||
if (!m_backend) {
|
||||
// I'm already deleted
|
||||
return;
|
||||
}
|
||||
|
||||
emit collectionAboutToDelete();
|
||||
|
||||
unregisterCurrentPath();
|
||||
@ -623,7 +630,11 @@ namespace FdoSecrets
|
||||
removeAlias(a).okOrDie();
|
||||
}
|
||||
|
||||
// cleanup connection on Database
|
||||
cleanupConnections();
|
||||
// cleanup connection on Backend itself
|
||||
m_backend->disconnect(this);
|
||||
parent()->disconnect(this);
|
||||
|
||||
m_exposedGroup = nullptr;
|
||||
|
||||
|
@ -59,9 +59,9 @@ namespace FdoSecrets
|
||||
createItem(const QVariantMap& properties, const SecretStruct& secret, bool replace, PromptBase*& prompt);
|
||||
|
||||
signals:
|
||||
void itemCreated(const Item* item);
|
||||
void itemDeleted(const Item* item);
|
||||
void itemChanged(const Item* item);
|
||||
void itemCreated(Item* item);
|
||||
void itemDeleted(Item* item);
|
||||
void itemChanged(Item* item);
|
||||
|
||||
void collectionChanged();
|
||||
void collectionAboutToDelete();
|
||||
|
@ -51,6 +51,11 @@ namespace FdoSecrets
|
||||
return m_objectPath;
|
||||
}
|
||||
|
||||
QDBusAbstractAdaptor& dbusAdaptor() const
|
||||
{
|
||||
return *m_dbusAdaptor;
|
||||
}
|
||||
|
||||
protected:
|
||||
void registerWithPath(const QString& path, QDBusAbstractAdaptor* adaptor);
|
||||
|
||||
@ -74,11 +79,6 @@ namespace FdoSecrets
|
||||
|
||||
QString callingPeerName() const;
|
||||
|
||||
template <typename Adaptor> Adaptor& dbusAdaptor() const
|
||||
{
|
||||
return *static_cast<Adaptor*>(m_dbusAdaptor);
|
||||
}
|
||||
|
||||
DBusObject* p() const
|
||||
{
|
||||
return qobject_cast<DBusObject*>(parent());
|
||||
|
@ -35,6 +35,16 @@ namespace FdoSecrets
|
||||
qRegisterMetaType<ObjectPathSecretMap>();
|
||||
qDBusRegisterMetaType<ObjectPathSecretMap>();
|
||||
|
||||
QMetaType::registerConverter<QDBusArgument, StringStringMap>([](const QDBusArgument& arg) {
|
||||
if (arg.currentSignature() != "a{ss}") {
|
||||
return StringStringMap{};
|
||||
}
|
||||
// QDBusArgument is COW and qdbus_cast modifies it by detaching even it is const.
|
||||
// we don't want to modify the instance (arg) stored in the qvariant so we create a copy
|
||||
const auto copy = arg; // NOLINT(performance-unnecessary-copy-initialization)
|
||||
return qdbus_cast<StringStringMap>(copy);
|
||||
});
|
||||
|
||||
// NOTE: this is already registered by Qt in qtextratypes.h
|
||||
// qRegisterMetaType<QList<QDBusObjectPath > >();
|
||||
// qDBusRegisterMetaType<QList<QDBusObjectPath> >();
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "core/Entry.h"
|
||||
#include "core/EntryAttributes.h"
|
||||
#include "core/Group.h"
|
||||
#include "core/Metadata.h"
|
||||
#include "core/Tools.h"
|
||||
|
||||
#include <QMimeDatabase>
|
||||
@ -274,8 +275,8 @@ namespace FdoSecrets
|
||||
return ret;
|
||||
}
|
||||
|
||||
auto attributes = qdbus_cast<StringStringMap>(
|
||||
properties.value(QStringLiteral(DBUS_INTERFACE_SECRET_ITEM ".Attributes")).value<QDBusArgument>());
|
||||
auto attributes =
|
||||
properties.value(QStringLiteral(DBUS_INTERFACE_SECRET_ITEM ".Attributes")).value<StringStringMap>();
|
||||
ret = setAttributes(attributes);
|
||||
if (ret.isError()) {
|
||||
return ret;
|
||||
@ -350,6 +351,13 @@ namespace FdoSecrets
|
||||
return pathComponents.join('/');
|
||||
}
|
||||
|
||||
bool Item::isDeletePermanent() const
|
||||
{
|
||||
auto recycleBin = backend()->database()->metadata()->recycleBin();
|
||||
return (recycleBin && recycleBin->findEntryByUuid(backend()->uuid()))
|
||||
|| !backend()->database()->metadata()->recycleBinEnabled();
|
||||
}
|
||||
|
||||
void setEntrySecret(Entry* entry, const QByteArray& data, const QString& contentType)
|
||||
{
|
||||
auto mimeName = contentType.split(';').takeFirst().trimmed();
|
||||
@ -369,7 +377,8 @@ namespace FdoSecrets
|
||||
}
|
||||
|
||||
if (!mimeType.isValid() || !mimeType.inherits(QStringLiteral("text/plain")) || !codec) {
|
||||
// we can't handle this content type, save the data as attachment
|
||||
// we can't handle this content type, save the data as attachment, and clear the password field
|
||||
entry->setPassword("");
|
||||
entry->attachments()->set(FDO_SECRETS_DATA, data);
|
||||
entry->attributes()->set(FDO_SECRETS_CONTENT_TYPE, contentType);
|
||||
return;
|
||||
@ -393,8 +402,13 @@ namespace FdoSecrets
|
||||
|
||||
if (entry->attachments()->hasKey(FDO_SECRETS_DATA)) {
|
||||
ss.value = entry->attachments()->value(FDO_SECRETS_DATA);
|
||||
Q_ASSERT(entry->attributes()->hasKey(FDO_SECRETS_CONTENT_TYPE));
|
||||
ss.contentType = entry->attributes()->value(FDO_SECRETS_CONTENT_TYPE);
|
||||
if (entry->attributes()->hasKey(FDO_SECRETS_CONTENT_TYPE)) {
|
||||
ss.contentType = entry->attributes()->value(FDO_SECRETS_CONTENT_TYPE);
|
||||
} else {
|
||||
// the entry is somehow corrupted, maybe the user deleted it.
|
||||
// set to binary and hope for the best...
|
||||
ss.contentType = QStringLiteral("application/octet-stream");
|
||||
}
|
||||
return ss;
|
||||
}
|
||||
|
||||
|
@ -79,6 +79,14 @@ namespace FdoSecrets
|
||||
*/
|
||||
QString path() const;
|
||||
|
||||
/**
|
||||
* If the containing db does not have recycle bin enabled,
|
||||
* or the entry is already in the recycle bin (not possible for item, though),
|
||||
* the delete is permanent
|
||||
* @return true if delete is permanent
|
||||
*/
|
||||
bool isDeletePermanent() const;
|
||||
|
||||
public slots:
|
||||
void doDelete();
|
||||
|
||||
|
@ -68,9 +68,9 @@ namespace FdoSecrets
|
||||
incomplete = false;
|
||||
|
||||
std::unique_ptr<CipherPair> cipher{};
|
||||
if (algorithm == QLatin1Literal("plain")) {
|
||||
if (algorithm == QLatin1String(PlainCipher::Algorithm)) {
|
||||
cipher.reset(new PlainCipher);
|
||||
} else if (algorithm == QLatin1Literal("dh-ietf1024-sha256-aes128-cbc-pkcs7")) {
|
||||
} else if (algorithm == QLatin1String(DhIetf1024Sha256Aes128CbcPkcs7::Algorithm)) {
|
||||
QByteArray clientPublicKey = input.toByteArray();
|
||||
cipher.reset(new DhIetf1024Sha256Aes128CbcPkcs7(clientPublicKey));
|
||||
} else {
|
||||
|
@ -43,6 +43,9 @@ namespace
|
||||
|
||||
namespace FdoSecrets
|
||||
{
|
||||
// XXX: remove the redundant definitions once we are at C++17
|
||||
constexpr char PlainCipher::Algorithm[];
|
||||
constexpr char DhIetf1024Sha256Aes128CbcPkcs7::Algorithm[];
|
||||
|
||||
DhIetf1024Sha256Aes128CbcPkcs7::DhIetf1024Sha256Aes128CbcPkcs7(const QByteArray& clientPublicKeyBytes)
|
||||
: m_valid(false)
|
||||
@ -51,13 +54,24 @@ namespace FdoSecrets
|
||||
auto clientPub = MpiFromBytes(clientPublicKeyBytes, false);
|
||||
|
||||
// generate server side private, 128 bytes
|
||||
GcryptMPI serverPrivate(gcry_mpi_snew(KEY_SIZE_BYTES * 8));
|
||||
gcry_mpi_randomize(serverPrivate.get(), KEY_SIZE_BYTES * 8, GCRY_STRONG_RANDOM);
|
||||
GcryptMPI serverPrivate = nullptr;
|
||||
if (NextPrivKey) {
|
||||
serverPrivate = std::move(NextPrivKey);
|
||||
} else {
|
||||
serverPrivate.reset(gcry_mpi_snew(KEY_SIZE_BYTES * 8));
|
||||
gcry_mpi_randomize(serverPrivate.get(), KEY_SIZE_BYTES * 8, GCRY_STRONG_RANDOM);
|
||||
}
|
||||
|
||||
// generate server side public key
|
||||
GcryptMPI serverPublic(gcry_mpi_snew(KEY_SIZE_BYTES * 8));
|
||||
// the generator of Second Oakley Group is 2
|
||||
gcry_mpi_powm(serverPublic.get(), GCRYMPI_CONST_TWO, serverPrivate.get(), IETF1024_SECOND_OAKLEY_GROUP_P.get());
|
||||
GcryptMPI serverPublic = nullptr;
|
||||
if (NextPubKey) {
|
||||
serverPublic = std::move(NextPubKey);
|
||||
} else {
|
||||
serverPublic.reset(gcry_mpi_snew(KEY_SIZE_BYTES * 8));
|
||||
// the generator of Second Oakley Group is 2
|
||||
gcry_mpi_powm(
|
||||
serverPublic.get(), GCRYMPI_CONST_TWO, serverPrivate.get(), IETF1024_SECOND_OAKLEY_GROUP_P.get());
|
||||
}
|
||||
|
||||
initialize(std::move(clientPub), std::move(serverPublic), std::move(serverPrivate));
|
||||
}
|
||||
@ -216,4 +230,13 @@ namespace FdoSecrets
|
||||
return m_publicKey;
|
||||
}
|
||||
|
||||
void DhIetf1024Sha256Aes128CbcPkcs7::fixNextServerKeys(GcryptMPI priv, GcryptMPI pub)
|
||||
{
|
||||
NextPrivKey = std::move(priv);
|
||||
NextPubKey = std::move(pub);
|
||||
}
|
||||
|
||||
GcryptMPI DhIetf1024Sha256Aes128CbcPkcs7::NextPrivKey = nullptr;
|
||||
GcryptMPI DhIetf1024Sha256Aes128CbcPkcs7::NextPubKey = nullptr;
|
||||
|
||||
} // namespace FdoSecrets
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "fdosecrets/objects/Session.h"
|
||||
|
||||
class TestFdoSecrets;
|
||||
class TestGuiFdoSecrets;
|
||||
|
||||
namespace FdoSecrets
|
||||
{
|
||||
@ -42,6 +43,8 @@ namespace FdoSecrets
|
||||
{
|
||||
Q_DISABLE_COPY(PlainCipher)
|
||||
public:
|
||||
static constexpr const char Algorithm[] = "plain";
|
||||
|
||||
PlainCipher() = default;
|
||||
SecretStruct encrypt(const SecretStruct& input) override
|
||||
{
|
||||
@ -113,6 +116,8 @@ namespace FdoSecrets
|
||||
}
|
||||
|
||||
public:
|
||||
static constexpr const char Algorithm[] = "dh-ietf1024-sha256-aes128-cbc-pkcs7";
|
||||
|
||||
explicit DhIetf1024Sha256Aes128CbcPkcs7(const QByteArray& clientPublicKeyBytes);
|
||||
|
||||
SecretStruct encrypt(const SecretStruct& input) override;
|
||||
@ -123,9 +128,18 @@ namespace FdoSecrets
|
||||
|
||||
QVariant negotiationOutput() const override;
|
||||
|
||||
private:
|
||||
/**
|
||||
* For test only, fix the server side private and public key.
|
||||
*/
|
||||
static void fixNextServerKeys(GcryptMPI priv, GcryptMPI pub);
|
||||
static GcryptMPI NextPrivKey;
|
||||
static GcryptMPI NextPubKey;
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(DhIetf1024Sha256Aes128CbcPkcs7);
|
||||
friend class ::TestFdoSecrets;
|
||||
friend class ::TestGuiFdoSecrets;
|
||||
};
|
||||
|
||||
} // namespace FdoSecrets
|
||||
|
@ -335,9 +335,7 @@ namespace FdoSecrets
|
||||
{
|
||||
switch (role) {
|
||||
case Qt::EditRole: {
|
||||
auto v = QVariant::fromValue(sess);
|
||||
qDebug() << v << v.type() << v.userType();
|
||||
return v;
|
||||
return QVariant::fromValue(sess);
|
||||
}
|
||||
default:
|
||||
return {};
|
||||
|
@ -49,7 +49,7 @@ DatabaseTabWidget::DatabaseTabWidget(QWidget* parent)
|
||||
: QTabWidget(parent)
|
||||
, m_dbWidgetStateSync(new DatabaseWidgetStateSync(this))
|
||||
, m_dbWidgetPendingLock(nullptr)
|
||||
, m_databaseOpenDialog(new DatabaseOpenDialog())
|
||||
, m_databaseOpenDialog(new DatabaseOpenDialog(this))
|
||||
{
|
||||
auto* tabBar = new DragTabBar(this);
|
||||
setTabBar(tabBar);
|
||||
|
@ -108,7 +108,7 @@ private:
|
||||
|
||||
QPointer<DatabaseWidgetStateSync> m_dbWidgetStateSync;
|
||||
QPointer<DatabaseWidget> m_dbWidgetPendingLock;
|
||||
QScopedPointer<DatabaseOpenDialog> m_databaseOpenDialog;
|
||||
QPointer<DatabaseOpenDialog> m_databaseOpenDialog;
|
||||
};
|
||||
|
||||
#endif // KEEPASSX_DATABASETABWIDGET_H
|
||||
|
@ -57,8 +57,9 @@ macro(parse_arguments prefix arg_names option_names)
|
||||
endmacro(parse_arguments)
|
||||
|
||||
macro(add_unit_test)
|
||||
parse_arguments(TEST "NAME;SOURCES;LIBS" "" ${ARGN})
|
||||
parse_arguments(TEST "NAME;SOURCES;LIBS;LAUNCHER" "" ${ARGN})
|
||||
set(_test_NAME ${TEST_NAME})
|
||||
set(_test_LAUNCHER ${TEST_LAUNCHER})
|
||||
set(_srcList ${TEST_SOURCES})
|
||||
add_executable(${_test_NAME} ${_srcList})
|
||||
target_link_libraries(${_test_NAME} ${TEST_LIBS})
|
||||
@ -69,9 +70,9 @@ macro(add_unit_test)
|
||||
set(TEST_OUTPUT ${TEST_OUTPUT} CACHE STRING "The output to generate when running the QTest unit tests")
|
||||
|
||||
if(KDE4_TEST_OUTPUT STREQUAL "xml")
|
||||
add_test(${_test_NAME} ${_test_NAME} -xml -o ${_test_NAME}.tml)
|
||||
add_test(${_test_NAME} ${_test_LAUNCHER} ${_test_NAME} -xml -o ${_test_NAME}.tml)
|
||||
else(KDE4_TEST_OUTPUT STREQUAL "xml")
|
||||
add_test(${_test_NAME} ${_test_NAME})
|
||||
add_test(${_test_NAME} ${_test_LAUNCHER} ${_test_NAME})
|
||||
endif(KDE4_TEST_OUTPUT STREQUAL "xml")
|
||||
|
||||
if(NOT MSVC_IDE) #not needed for the ide
|
||||
|
@ -0,0 +1,33 @@
|
||||
<interface name="org.freedesktop.Secret.Collection">
|
||||
<property name="Items" type="ao" access="read"/>
|
||||
<property name="Label" type="s" access="readwrite"/>
|
||||
<property name="Locked" type="b" access="read"/>
|
||||
<property name="Created" type="t" access="read"/>
|
||||
<property name="Modified" type="t" access="read"/>
|
||||
<signal name="ItemCreated">
|
||||
<arg name="item" type="o" direction="out"/>
|
||||
</signal>
|
||||
<signal name="ItemDeleted">
|
||||
<arg name="item" type="o" direction="out"/>
|
||||
</signal>
|
||||
<signal name="ItemChanged">
|
||||
<arg name="item" type="o" direction="out"/>
|
||||
</signal>
|
||||
<method name="Delete">
|
||||
<arg type="o" direction="out"/>
|
||||
</method>
|
||||
<method name="SearchItems">
|
||||
<arg type="ao" direction="out"/>
|
||||
<arg name="attributes" type="a{ss}" direction="in"/>
|
||||
<annotation name="org.qtproject.QtDBus.QtTypeName.In0" value="StringStringMap"/>
|
||||
</method>
|
||||
<method name="CreateItem">
|
||||
<arg type="o" direction="out"/>
|
||||
<arg name="properties" type="a{sv}" direction="in"/>
|
||||
<annotation name="org.qtproject.QtDBus.QtTypeName.In0" value="QVariantMap"/>
|
||||
<arg name="secret" type="(oayays)" direction="in"/>
|
||||
<annotation name="org.qtproject.QtDBus.QtTypeName.In1" value="FdoSecrets::SecretStruct"/>
|
||||
<arg name="replace" type="b" direction="in"/>
|
||||
<arg name="prompt" type="o" direction="out"/>
|
||||
</method>
|
||||
</interface>
|
21
tests/data/dbus/interfaces/org.freedesktop.Secret.Item.xml
Normal file
21
tests/data/dbus/interfaces/org.freedesktop.Secret.Item.xml
Normal file
@ -0,0 +1,21 @@
|
||||
<interface name="org.freedesktop.Secret.Item">
|
||||
<property name="Locked" type="b" access="read"/>
|
||||
<property name="Attributes" type="a{ss}" access="readwrite">
|
||||
<annotation name="org.qtproject.QtDBus.QtTypeName" value="StringStringMap"/>
|
||||
</property>
|
||||
<property name="Label" type="s" access="readwrite"/>
|
||||
<property name="Created" type="t" access="read"/>
|
||||
<property name="Modified" type="t" access="read"/>
|
||||
<method name="Delete">
|
||||
<arg type="o" direction="out"/>
|
||||
</method>
|
||||
<method name="GetSecret">
|
||||
<arg type="(oayays)" direction="out"/>
|
||||
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="FdoSecrets::SecretStruct"/>
|
||||
<arg name="session" type="o" direction="in"/>
|
||||
</method>
|
||||
<method name="SetSecret">
|
||||
<arg name="secret" type="(oayays)" direction="in"/>
|
||||
<annotation name="org.qtproject.QtDBus.QtTypeName.In0" value="FdoSecrets::SecretStruct"/>
|
||||
</method>
|
||||
</interface>
|
11
tests/data/dbus/interfaces/org.freedesktop.Secret.Prompt.xml
Normal file
11
tests/data/dbus/interfaces/org.freedesktop.Secret.Prompt.xml
Normal file
@ -0,0 +1,11 @@
|
||||
<interface name="org.freedesktop.Secret.Prompt">
|
||||
<signal name="Completed">
|
||||
<arg name="dismissed" type="b" direction="out"/>
|
||||
<arg name="result" type="v" direction="out"/>
|
||||
</signal>
|
||||
<method name="Prompt">
|
||||
<arg name="windowId" type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="Dismiss">
|
||||
</method>
|
||||
</interface>
|
@ -0,0 +1,55 @@
|
||||
<interface name="org.freedesktop.Secret.Service">
|
||||
<property name="Collections" type="ao" access="read"/>
|
||||
<signal name="CollectionCreated">
|
||||
<arg name="collection" type="o" direction="out"/>
|
||||
</signal>
|
||||
<signal name="CollectionDeleted">
|
||||
<arg name="collection" type="o" direction="out"/>
|
||||
</signal>
|
||||
<signal name="CollectionChanged">
|
||||
<arg name="collection" type="o" direction="out"/>
|
||||
</signal>
|
||||
<method name="OpenSession">
|
||||
<arg type="v" direction="out"/>
|
||||
<arg name="algorithm" type="s" direction="in"/>
|
||||
<arg name="input" type="v" direction="in"/>
|
||||
<arg name="result" type="o" direction="out"/>
|
||||
</method>
|
||||
<method name="CreateCollection">
|
||||
<arg type="o" direction="out"/>
|
||||
<arg name="properties" type="a{sv}" direction="in"/>
|
||||
<annotation name="org.qtproject.QtDBus.QtTypeName.In0" value="QVariantMap"/>
|
||||
<arg name="alias" type="s" direction="in"/>
|
||||
<arg name="prompt" type="o" direction="out"/>
|
||||
</method>
|
||||
<method name="SearchItems">
|
||||
<arg type="ao" direction="out"/>
|
||||
<arg name="attributes" type="a{ss}" direction="in"/>
|
||||
<annotation name="org.qtproject.QtDBus.QtTypeName.In0" value="StringStringMap"/>
|
||||
<arg name="locked" type="ao" direction="out"/>
|
||||
</method>
|
||||
<method name="Unlock">
|
||||
<arg type="ao" direction="out"/>
|
||||
<arg name="paths" type="ao" direction="in"/>
|
||||
<arg name="prompt" type="o" direction="out"/>
|
||||
</method>
|
||||
<method name="Lock">
|
||||
<arg type="ao" direction="out"/>
|
||||
<arg name="paths" type="ao" direction="in"/>
|
||||
<arg name="prompt" type="o" direction="out"/>
|
||||
</method>
|
||||
<method name="GetSecrets">
|
||||
<arg type="a{o(oayays)}" direction="out"/>
|
||||
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="ObjectPathSecretMap"/>
|
||||
<arg name="items" type="ao" direction="in"/>
|
||||
<arg name="session" type="o" direction="in"/>
|
||||
</method>
|
||||
<method name="ReadAlias">
|
||||
<arg type="o" direction="out"/>
|
||||
<arg name="name" type="s" direction="in"/>
|
||||
</method>
|
||||
<method name="SetAlias">
|
||||
<arg name="name" type="s" direction="in"/>
|
||||
<arg name="collection" type="o" direction="in"/>
|
||||
</method>
|
||||
</interface>
|
@ -0,0 +1,4 @@
|
||||
<interface name="org.freedesktop.Secret.Session">
|
||||
<method name="Close">
|
||||
</method>
|
||||
</interface>
|
39
tests/data/dbus/session.conf
Normal file
39
tests/data/dbus/session.conf
Normal file
@ -0,0 +1,39 @@
|
||||
<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-Bus Bus Configuration 1.0//EN"
|
||||
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
|
||||
<busconfig>
|
||||
<type>session</type>
|
||||
<keep_umask/>
|
||||
<listen>unix:tmpdir=/tmp</listen>
|
||||
<auth>EXTERNAL</auth>
|
||||
<standard_session_servicedirs />
|
||||
<policy context="default">
|
||||
<allow send_destination="*" eavesdrop="true"/>
|
||||
<allow eavesdrop="true"/>
|
||||
<allow own="*"/>
|
||||
</policy>
|
||||
<include ignore_missing="yes">/etc/dbus-1/session.conf</include>
|
||||
<includedir>session.d</includedir>
|
||||
<includedir>/etc/dbus-1/session.d</includedir>
|
||||
<include ignore_missing="yes">/etc/dbus-1/session-local.conf</include>
|
||||
<include if_selinux_enabled="yes" selinux_root_relative="yes">contexts/dbus_contexts</include>
|
||||
<limit name="max_incoming_bytes">1000000000</limit>
|
||||
<limit name="max_incoming_unix_fds">250000000</limit>
|
||||
<limit name="max_outgoing_bytes">1000000000</limit>
|
||||
<limit name="max_outgoing_unix_fds">250000000</limit>
|
||||
<limit name="max_message_size">1000000000</limit>
|
||||
<limit name="auth_timeout">240000</limit>
|
||||
<limit name="pending_fd_timeout">150000</limit>
|
||||
<limit name="max_completed_connections">100000</limit>
|
||||
<limit name="max_incomplete_connections">10000</limit>
|
||||
<limit name="max_connections_per_user">100000</limit>
|
||||
<limit name="max_pending_service_starts">10000</limit>
|
||||
<limit name="max_names_per_connection">50000</limit>
|
||||
<limit name="max_match_rules_per_connection">50000</limit>
|
||||
<limit name="max_replies_per_connection">50000</limit>
|
||||
<!-- The above is copied from session bus conf.
|
||||
Our only intent here is to set a low service_start_timeout,
|
||||
such that ctest can exit sooner when dbus-run-session is used
|
||||
to launch tests and some service fails to start.
|
||||
-->
|
||||
<limit name="service_start_timeout">500</limit>
|
||||
</busconfig>
|
@ -21,3 +21,12 @@ add_unit_test(NAME testguipixmaps SOURCES TestGuiPixmaps.cpp LIBS ${TEST_LIBRARI
|
||||
if(WITH_XC_BROWSER)
|
||||
add_unit_test(NAME testguibrowser SOURCES TestGuiBrowser.cpp ../util/TemporaryFile.cpp LIBS ${TEST_LIBRARIES})
|
||||
endif()
|
||||
|
||||
if(WITH_XC_FDOSECRETS)
|
||||
add_unit_test(NAME testguifdosecrets
|
||||
SOURCES TestGuiFdoSecrets.cpp ../util/TemporaryFile.cpp
|
||||
LIBS ${TEST_LIBRARIES}
|
||||
# The following doesn't work because dbus-run-session expects execname to be in PATH
|
||||
# dbus-run-session -- execname
|
||||
LAUNCHER dbus-run-session --config-file ${CMAKE_CURRENT_SOURCE_DIR}/../data/dbus/session.conf -- sh -c "exec ./$0")
|
||||
endif()
|
||||
|
1175
tests/gui/TestGuiFdoSecrets.cpp
Normal file
1175
tests/gui/TestGuiFdoSecrets.cpp
Normal file
File diff suppressed because it is too large
Load Diff
121
tests/gui/TestGuiFdoSecrets.h
Normal file
121
tests/gui/TestGuiFdoSecrets.h
Normal file
@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Aetf <aetf@unlimitedcodeworks.xyz>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 or (at your option)
|
||||
* version 3 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef KEEPASSXC_TESTGUIFDOSECRETS_H
|
||||
#define KEEPASSXC_TESTGUIFDOSECRETS_H
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QObject>
|
||||
#include <QPointer>
|
||||
#include <QScopedPointer>
|
||||
#include <QSharedPointer>
|
||||
#include <QString>
|
||||
|
||||
#include "fdosecrets/GcryptMPI.h"
|
||||
#include "fdosecrets/objects/DBusTypes.h"
|
||||
|
||||
class MainWindow;
|
||||
class Database;
|
||||
class DatabaseTabWidget;
|
||||
class DatabaseWidget;
|
||||
class TemporaryFile;
|
||||
class FdoSecretsPlugin;
|
||||
namespace FdoSecrets
|
||||
{
|
||||
class Service;
|
||||
class Session;
|
||||
class Collection;
|
||||
class Item;
|
||||
class Prompt;
|
||||
class DhIetf1024Sha256Aes128CbcPkcs7;
|
||||
} // namespace FdoSecrets
|
||||
|
||||
class QAbstractItemView;
|
||||
|
||||
class TestGuiFdoSecrets : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
~TestGuiFdoSecrets() override;
|
||||
|
||||
private slots:
|
||||
void initTestCase();
|
||||
void init();
|
||||
void cleanup();
|
||||
void cleanupTestCase();
|
||||
|
||||
void testDBusSpec();
|
||||
|
||||
void testServiceEnable();
|
||||
void testServiceEnableNoExposedDatabase();
|
||||
void testServiceSearch();
|
||||
void testServiceUnlock();
|
||||
void testServiceLock();
|
||||
|
||||
void testSessionOpen();
|
||||
void testSessionClose();
|
||||
|
||||
void testCollectionCreate();
|
||||
void testCollectionDelete();
|
||||
|
||||
void testItemCreate();
|
||||
void testItemReplace();
|
||||
void testItemSecret();
|
||||
void testItemDelete();
|
||||
|
||||
void testAlias();
|
||||
void testDefaultAliasAlwaysPresent();
|
||||
|
||||
void testExposeSubgroup();
|
||||
void testModifiyingExposedGroup();
|
||||
|
||||
protected slots:
|
||||
void createDatabaseCallback();
|
||||
|
||||
private:
|
||||
void lockDatabaseInBackend();
|
||||
void unlockDatabaseInBackend();
|
||||
QPointer<FdoSecrets::Service> enableService();
|
||||
QPointer<FdoSecrets::Session> openSession(FdoSecrets::Service* service, const QString& algo);
|
||||
QPointer<FdoSecrets::Collection> getDefaultCollection(FdoSecrets::Service* service);
|
||||
QPointer<FdoSecrets::Item> getFirstItem(FdoSecrets::Collection* coll);
|
||||
QPointer<FdoSecrets::Item> createItem(FdoSecrets::Session* sess,
|
||||
FdoSecrets::Collection* coll,
|
||||
const QString& label,
|
||||
const QString& pass,
|
||||
const StringStringMap& attr,
|
||||
bool replace);
|
||||
|
||||
private:
|
||||
QScopedPointer<MainWindow> m_mainWindow;
|
||||
QPointer<DatabaseTabWidget> m_tabWidget;
|
||||
QPointer<DatabaseWidget> m_dbWidget;
|
||||
QSharedPointer<Database> m_db;
|
||||
|
||||
QPointer<FdoSecretsPlugin> m_plugin;
|
||||
|
||||
// For DH session tests
|
||||
GcryptMPI m_serverPrivate;
|
||||
GcryptMPI m_serverPublic;
|
||||
std::unique_ptr<FdoSecrets::DhIetf1024Sha256Aes128CbcPkcs7> m_cipher;
|
||||
|
||||
QByteArray m_dbData;
|
||||
QScopedPointer<TemporaryFile> m_dbFile;
|
||||
};
|
||||
|
||||
#endif // KEEPASSXC_TESTGUIFDOSECRETS_H
|
Loading…
x
Reference in New Issue
Block a user