1
0
mirror of https://github.com/QRouland/UTPass.git synced 2025-01-24 07:36:39 +00:00

Refactor gpg for more clean job handling

This commit is contained in:
Quentin Rouland 2025-01-15 23:15:00 +01:00
parent 00116aea8c
commit e589abd10c
11 changed files with 381 additions and 242 deletions

View File

@ -3,6 +3,7 @@
#include <QFile>
#include <QDir>
#include <QtCore/QStandardPaths>
#include <QProcess>
#include <gpgme.h>
#include <gpgme++/data.h>
@ -22,9 +23,11 @@
#include <qgpgme/keylistjob.h>
#include <qgpgme/changeownertrustjob.h>
#include "gpg.h"
#include "passkeymodel.h"
#include "passphraseprovider.h"
#include "qprocess.h"
@ -32,9 +35,9 @@
using namespace GpgME;
using namespace QGpgME;
Gpg::Gpg()
Gpg::Gpg(QObject* windows)
{
m_window = nullptr;
this->m_passphrase_provider = new UTPassphraseProvider(windows);
Gpg::initGpgConfig();
@ -50,6 +53,10 @@ Gpg::Gpg()
qDebug() << "GNUPG Home is :" << engineInfo(OpenPGP).homeDirectory();
}
Gpg::~Gpg(){
delete this->m_passphrase_provider;
}
QString Gpg::initGpgHome()
{
@ -124,37 +131,28 @@ void Gpg::initGpgConfig()
}
QPair<Error, QString> Gpg::decrypt(QByteArray cipherText)
Error Gpg::decrypt(QByteArray cipher_text)
{
auto job = openpgp()->decryptJob();
auto ctx = DecryptJob::context(job);
auto provider = new UTPassphraseProvider;
ctx->setPassphraseProvider(provider);
ctx->setPassphraseProvider(this->m_passphrase_provider);
ctx->setPinentryMode(Context::PinentryLoopback);
QByteArray plain_text;
auto decResult = job->exec(cipherText, plain_text);
QObject::connect(job, &DecryptJob::result,
this, &Gpg::decryptResultSlot);
delete job;
delete provider;
if (decResult.error()) {
qWarning() << "something gone wrong on decrypt";
qDebug() << "Code Error : " << decResult.error().code();
qDebug() << "Error str : " << decResult.error().asString();
}
return QPair<Error, QString>(decResult.error(), QString::fromUtf8(plain_text));
return job->start(cipher_text);
}
QPair<Error, QString> Gpg::decryptFromFile(QString path)
Error Gpg::decryptFromFile(QString path)
{
qDebug() << "Decrypt from " << path;
QFile file(path);
if (!file.open(QIODevice::ReadOnly)) {
qWarning() << "Can't open the File";
return QPair<Error, QString>(Error(), QString());;
return Error();
}
QByteArray cipherText = file.readAll();
file.close();
@ -162,77 +160,83 @@ QPair<Error, QString> Gpg::decryptFromFile(QString path)
}
QPair<Error, QByteArray> Gpg::encrypt(QString str, QString uid, bool ascii_armor, bool text_mode)
void Gpg::decryptResultSlot(const GpgME::DecryptionResult &result, const QByteArray &plainText, const QString &auditLogAsHtml, const GpgME::Error &auditLogError)
{
qDebug() << "Encrypt to QByteArray";
auto keys = getKeys(uid);
if (keys.first) {
return QPair<Error, QByteArray>(keys.first, QByteArray());
if (result.error()) {
qWarning() << "Something gone wrong on decrypt";
qDebug() << "Code Error : " << result.error().code();
qDebug() << "Error str : " << result.error().asString();
}
auto job = std::unique_ptr<EncryptJob>(openpgp()->encryptJob(ascii_armor, text_mode));
QByteArray cipherText;
auto result = job->exec(keys.second, str.toUtf8(), Context::AlwaysTrust, cipherText);
qDebug() << "Encrypted to QByteArray";
return QPair<Error, QByteArray>(result.error(), cipherText);
emit decryptResult(result.error(), QString::fromUtf8(plainText));
}
Error Gpg::encryptToFile(QString str, QString path, QString uid, bool ascii_armor,
bool text_mode)
{
qDebug() << "Encrypting to file " << path;
QFile file(path);
if (!file.open(QIODevice::WriteOnly)) {
qWarning() << "Can't open the file to write it" ;
return Error();
}
auto encrypt_ret = encrypt(str, uid, ascii_armor, text_mode);
if (encrypt_ret.first) {
file.write(encrypt_ret.second);
}
qDebug() << "Encrypting to file " << path;
return encrypt_ret.first;
}
// QPair<Error, QByteArray> Gpg::encrypt(QString str, QString uid, bool ascii_armor, bool text_mode)
// {
// qDebug() << "Encrypt to QByteArray";
// auto keys = getKeys(uid);
// if (keys.first) {
// return QPair<Error, QByteArray>(keys.first, QByteArray());
// }
// auto job = std::unique_ptr<EncryptJob>(openpgp()->encryptJob(ascii_armor, text_mode));
// QByteArray cipherText;
// auto result = job->exec(keys.second, str.toUtf8(), Context::AlwaysTrust, cipherText);
// qDebug() << "Encrypted to QByteArray";
// return QPair<Error, QByteArray>(result.error(), cipherText);
// }
QPair<Error, std::vector< GpgME::Key >> Gpg::getAllKeys ( bool remote, const bool include_sigs,
// Error Gpg::encryptToFile(QString str, QString path, QString uid, bool ascii_armor,
// bool text_mode)
// {
// qDebug() << "Encrypting to file " << path;
// QFile file(path);
// if (!file.open(QIODevice::WriteOnly)) {
// qWarning() << "Can't open the file to write it" ;
// return Error();
// }
// auto encrypt_ret = encrypt(str, uid, ascii_armor, text_mode);
// if (encrypt_ret.first) {
// file.write(encrypt_ret.second);
// }
// qDebug() << "Encrypting to file " << path;
// return encrypt_ret.first;
// }
Error Gpg::getAllKeys ( bool remote, const bool include_sigs,
bool validate )
{
return getKeys(QString(""), remote, include_sigs, validate);
}
QPair<Error, std::vector<Key >> Gpg::getKeys(QString pattern_uid, bool remote, bool include_sigs,
Error Gpg::getKeys(QString pattern_uid, bool remote, bool include_sigs,
bool validate)
{
qDebug() << "Getting the keys " << pattern_uid;
auto job = std::unique_ptr<KeyListJob>(openpgp()->keyListJob(remote, include_sigs, validate));
auto job = openpgp()->keyListJob(remote, include_sigs, validate);
std::vector<Key> keys;
auto result = job->exec(QStringList() << pattern_uid, false, keys);
QObject::connect(job, &KeyListJob::result,
this, &Gpg::getKeysJobResultSlot);
qDebug() << "Got the keys " << pattern_uid;
return QPair<Error, std::vector< Key >> (result.error(), keys);
return job->start(QStringList() << pattern_uid, false);
}
QPair<Error, Key> Gpg::getKey(QString uid, bool remote, bool include_sigs, bool validate)
void Gpg::getKeysJobResultSlot(const GpgME::KeyListResult &result, const std::vector<GpgME::Key> &keys, const QString &auditLogAsHtml , const GpgME::Error &auditLogError)
{
qDebug() << "Getting the key " << uid;
auto keys = getKeys(uid, remote, include_sigs, validate);
if (keys.first or keys.second.size() != 1) {
qWarning() << "Bad id";
return QPair<Error, Key>(keys.first, Key::null);
if (result.error()) {
qWarning() << "Something gone wrong on decrypt";
qDebug() << "Code Error : " << result.error().code();
qDebug() << "Error str : " << result.error().asString();
}
qDebug() << "Got the key " << uid;
return QPair<Error, Key>(keys.first, keys.second.front());
emit getKeysResult(result.error(), keys);
}
Error Gpg::importKeysFromFile(QString path)
{
qDebug() << "Importing the key file" << path;
@ -242,51 +246,52 @@ Error Gpg::importKeysFromFile(QString path)
qWarning() << "Can't open the File";
return Error();
}
auto data = file.readAll();
file.close();
auto job = openpgp()->importJob();
auto ctx = ImportJob::context(job);
auto result = job->exec(file.readAll());
QObject::connect(job, &ImportJob::result,
this, &Gpg::importKeysFromFileSlot);
return job->start(data);
}
void Gpg::importKeysFromFileSlot(const GpgME::ImportResult &result, const QString &auditLogAsHtml, const GpgME::Error &auditLogError)
{
qDebug() << "numImported" << result.numImported();
qDebug() << "numSecretKeysImported" << result.numSecretKeysImported();
qDebug() << "numSecretKeysConsidered" << result.numSecretKeysConsidered();
qDebug() << "numSecretKeysUnchanged" << result.numSecretKeysUnchanged();
qDebug() << "numUnchanged" << result.numUnchanged();
file.close();
delete job;
if (result.error()) {
qWarning() << "Import go wrong";
qWarning() << "Something gone wrong on decrypt";
qDebug() << "Code Error : " << result.error().code();
qDebug() << "Error str : " << result.error().asString();
}
qDebug() << "Imported the key file" << path;
return result.error();
emit importKeysFromFileResult(result.error());
}
Error Gpg::deleteKeyId(QString uid)
Error Gpg::deleteKey(const Key key)
{
qDebug() << "Deleting key id " << uid;
auto key = getKey(uid);
auto job = openpgp()->deleteJob();
if (key.first) {
return key.first;
QObject::connect(job, &DeleteJob::result,
this, &Gpg::deleteKeySlot);
return openpgp()->deleteJob()->start(key, true);
}
auto ctx = std::unique_ptr<Context>(Context::createForProtocol(OpenPGP));
auto err = ctx->deleteKey(key.second, true);
void Gpg::deleteKeySlot(const GpgME::Error &error, const QString &auditLogAsHtml, const GpgME::Error &auditLogError) {
if (err) {
qWarning() << "Delete go wrong";
qDebug() << "Code Error : " << err.code();
qDebug() << "Error str : " << err.asString();
return err;
if (error) {
qWarning() << "Something gone wrong on decrypt";
qDebug() << "Code Error : " << error.code();
qDebug() << "Error str : " << error.asString();
}
emit deleteKeyResult(error);
}
qDebug() << "Deleted key id" << uid;
return err;
}

View File

@ -1,61 +1,95 @@
#ifndef GPG_H
#define GPG_H
#include "passkeymodel.h"
#include "passphraseprovider.h"
#include <memory>
#include <QQuickWindow>
#include <gpgme++/context.h>
#include <qgpgme/changeownertrustjob.h>
#include <QSemaphore>
#include <gpgme.h>
#include <qgpgme/importjob.h>
#include <qgpgme/deletejob.h>
#include <qgpgme/decryptjob.h>
#include <qgpgme/encryptjob.h>
#include <qgpgme/protocol.h>
#include <qgpgme/keylistjob.h>
#include <qgpgme/changeownertrustjob.h>
using namespace GpgME;
using namespace QGpgME;
class Gpg
class Gpg: public QObject
{
private:
Gpg();
Q_OBJECT
Q_PROPERTY(UTPassphraseProvider* passphrase_provider READ passphrase_provider MEMBER m_passphrase_provider )
QObject *m_window;
private slots:
void decryptResultSlot(
const DecryptionResult &result,
const QByteArray &plain_text,
const QString &auditLogAsHtml,
const Error &auditLogError
);
void getKeysJobResultSlot(
const GpgME::KeyListResult &result,
const std::vector<GpgME::Key> &keys,
const QString &auditLogAsHtml ,
const GpgME::Error &auditLogError
);
void importKeysFromFileSlot(
const GpgME::ImportResult &result,
const QString &auditLogAsHtml,
const GpgME::Error &auditLogError
);
void deleteKeySlot(
const GpgME::Error &result,
const QString &auditLogAsHtml,
const GpgME::Error &auditLogError
);
signals:
void importKeysFromFileResult(Error err);
void getKeysResult(Error err, std::vector<GpgME::Key> keys);
void deleteKeyResult(Error err);
void decryptResult(Error err, QString plain_text);
private:
UTPassphraseProvider* m_passphrase_provider;
QString findCommandPath(const QString &command);
QString initGpgHome();
QString initGpgExec();
void initGpgConfig();
Error getKey(QString uid, bool remote = false, bool include_sigs = false,
bool validate = false);
public:
static std::shared_ptr<Gpg> instance()
Gpg(QObject* window);
~Gpg();
UTPassphraseProvider* passphrase_provider() const
{
static std::shared_ptr<Gpg> s{new Gpg};
return s;
return m_passphrase_provider;
}
Gpg(Gpg const &) = delete;
void operator=(Gpg const &) = delete;
void setWindow(QObject *window)
{
m_window = window;
};
QObject *getWindow()
{
return m_window;
};
QPair<Error, std::vector<Key >> getAllKeys(bool remote = false, bool include_sigs = {}, bool
Error importKeysFromFile(const QString path);
Error getKeys(const QString pattern_uid, const bool remote = false,
const bool include_sigs = false,
const bool validate = false);
Error getAllKeys (bool remote = false, bool include_sigs = {}, bool
validate = false);
QPair<Error, std::vector<Key >> getKeys( QString pattern_uid, bool remote = false,
bool include_sigs = false,
bool validate = false);
QPair<Error, Key> getKey( QString uid, bool remote = false, bool include_sigs = false,
bool validate = false);
QPair<Error, QString> decrypt( QByteArray cipherText);
QPair<Error, QString> decryptFromFile( QString path);
QPair<Error, QByteArray> encrypt( QString str, QString uid, bool ascii_armor = true,
bool text_mode = true);
Error encryptToFile( QString str, QString path, QString uid, bool ascii_armor = true,
bool text_mode = true);
Error importKeysFromFile( QString path);
Error deleteKeyId( QString uid);
Error deleteKey(const Key key);
Error decrypt(const QByteArray cipher_text);
Error decryptFromFile(const QString path);
//Error encrypt (QString str, QString uid, bool ascii_armor = true,
// bool text_mode = true);
};
#endif

View File

@ -8,8 +8,11 @@
Pass::Pass(): m_password_store (QStandardPaths::writableLocation(
QStandardPaths::AppDataLocation).append("/.password-store"))
Pass::Pass():
m_password_store (QStandardPaths::writableLocation(
QStandardPaths::AppDataLocation).append("/.password-store")),
m_sem(std::unique_ptr<QSemaphore>(new QSemaphore(1))),
m_show_filename(QString())
{}
void Pass::initialize(QObject *window)
@ -18,7 +21,13 @@ void Pass::initialize(QObject *window)
qFatal("window is invalid. Abording.");
}
Gpg::instance()->setWindow(window);
this->m_gpg = std::unique_ptr<Gpg>(new Gpg(window));
QObject::connect(this, &Pass::responsePassphraseDialogPropagate, this->m_gpg->passphrase_provider(), &UTPassphraseProvider::handleResponse);
QObject::connect(this->m_gpg.get(), &Gpg::importKeysFromFileResult, this, &Pass::importGPGKeyResult);
QObject::connect(this->m_gpg.get(), &Gpg::getKeysResult, this, &Pass::getAllGPGKeysResult);
QObject::connect(this->m_gpg.get(), &Gpg::deleteKeyResult, this, &Pass::deleteGPGKeyResult);
QObject::connect(this->m_gpg.get(), &Gpg::decryptResult, this, &Pass::showResult);
QDir dir(m_password_store);
if (!dir.exists()) {
@ -27,38 +36,78 @@ void Pass::initialize(QObject *window)
qInfo() << "Password Store is :" << m_password_store;
}
void Pass::show(QUrl url)
bool Pass::show(QUrl url)
{
qInfo() << "Decrypting";
auto decrypt_ret = Gpg::instance()->decryptFromFile(url.toLocalFile());
if (decrypt_ret.first) {
qInfo() << "Decrypt Failed";
emit decryptFailed();
} else if (decrypt_ret.second.isNull()) {
qInfo() << "Decrypt Canceled";
emit decryptCanceled();
} else {
qInfo() << "Decrypt OK";
emit decrypted(url.fileName(), decrypt_ret.second);
}
if (!this->m_sem->tryAcquire(1, 500)){ return false; }
auto path = url.toLocalFile();
qInfo() << "Staring decrypting job for " << path;
QFileInfo file_info(path);
this->m_show_filename = file_info.completeBaseName();
return this->m_gpg->decryptFromFile(path);
}
bool Pass::deleteGPGKey(QString id)
void Pass::showResult(Error err, QString plain_text) {
qInfo() << "Result for decrypting job";
if (err) {
qInfo() << "Decrypt Failed";
emit showFailed(err.asString());
} else {
qInfo() << "Decrypt OK";
emit showSucceed(this->m_show_filename, plain_text);
}
this->m_show_filename = QString();
this->m_sem->release(1);
}
bool Pass::deleteGPGKey(Key key)
{
qInfo() << "Deleting Key id " << id;
return !Gpg::instance()->deleteKeyId(id);
if (!this->m_sem->tryAcquire(1, 500)){ return false;}
qInfo() << "Deleting Key";
return this->m_gpg->deleteKey(key);
}
void Pass::deleteGPGKeyResult(Error err) {
if(err) {
emit deleteGPGKeyFailed(err.asString());
} else {
emit deleteGPGKeySucceed();
}
this->m_sem->release(1);
}
bool Pass::importGPGKey(QUrl url)
{
if (!this->m_sem->tryAcquire(1, 500)){ return false;}
qInfo() << "Importing Key from " << url;
return !Gpg::instance()->importKeysFromFile(url.toLocalFile());
return this->m_gpg->importKeysFromFile(url.toLocalFile());
}
QVariant Pass::getAllGPGKeys()
void Pass::importGPGKeyResult(Error err) {
if(err) {
emit importGPGKeyFailed(err.asString());
} else {
emit importGPGKeySucceed();
}
this->m_sem->release(1);
}
bool Pass::getAllGPGKeys()
{
if (!this->m_sem->tryAcquire(1, 500)){ return false; }
qInfo() << "Getting all key form gpg ";
return QVariant::fromValue(PassKeyModel::keysToPassKey(
Gpg::instance()->getAllKeys().second)); // TODO Error handling
return this->m_gpg->getAllKeys();
}
void Pass::getAllGPGKeysResult(Error err, std::vector<GpgME::Key> keys_info) {
if(err) {
emit getAllGPGKeysFailed(err.asString());
} else {
emit getAllGPGKeysSucceed(QVariant::fromValue(PassKeyModel::keysToPassKey(keys_info)));
}
this->m_sem->release(1);
}
void Pass::responsePassphraseDialog(bool cancel, QString passphrase) {
qDebug() << "responsePassphraseDialog";
emit responsePassphraseDialogPropagate(cancel, passphrase);
}

View File

@ -4,20 +4,44 @@
#include <QObject>
#include <QUrl>
#include <QVariant>
#include <gpgme++/context.h>
#include "gpg.h"
using namespace GpgME;
class Pass : public QObject
{
Q_OBJECT
Q_PROPERTY(QString password_store READ password_store)
Q_PROPERTY(QString password_store READ password_store MEMBER m_password_store CONSTANT)
private slots:
void showResult(Error err, QString plain_text);
void deleteGPGKeyResult(Error err);
void importGPGKeyResult(Error err);
void getAllGPGKeysResult(Error err, std::vector< GpgME::Key > keys_info);
signals:
// GPG
void deleteGPGKeySucceed();
void deleteGPGKeyFailed(QString message);
void importGPGKeySucceed();
void importGPGKeyFailed(QString message);
void getAllGPGKeysSucceed(QVariant keys_info);
void getAllGPGKeysFailed(QString message);
void responsePassphraseDialogPropagate(bool cancel, QString passphrase);
// pass show
void showSucceed(QString name, QString text);
void showFailed(QString message);
private:
QString m_password_store;
signals:
void decrypted(QString name, QString text);
void decryptCanceled();
void decryptFailed();
std::unique_ptr<Gpg> m_gpg;
std::unique_ptr<QSemaphore> m_sem;
QString m_show_filename;
public:
Pass();
@ -29,10 +53,16 @@ public:
}
Q_INVOKABLE void initialize(QObject *window);
Q_INVOKABLE void show(QUrl url);
Q_INVOKABLE bool deleteGPGKey(QString id);
// GPG
Q_INVOKABLE bool deleteGPGKey(Key key);
Q_INVOKABLE bool importGPGKey(QUrl url);
Q_INVOKABLE QVariant getAllGPGKeys();
Q_INVOKABLE bool getAllGPGKeys();
Q_INVOKABLE void responsePassphraseDialog(bool cancel, QString passphrase);
// PASS
Q_INVOKABLE bool show(QUrl url);
};
#endif

View File

@ -9,14 +9,13 @@ using namespace GpgME;
class UserIdModel : public QObject
{
Q_OBJECT
Q_PROPERTY(QString uid READ uid MEMBER m_uid CONSTANT)
Q_PROPERTY(QString name READ name MEMBER m_name CONSTANT)
Q_PROPERTY(QString email READ email MEMBER m_email CONSTANT)
Q_PROPERTY(QString uid READ uid CONSTANT)
Q_PROPERTY(QString name READ name CONSTANT)
Q_PROPERTY(QString email READ email CONSTANT)
private:
UserID m_user_id;
public:
UserIdModel(UserID key):
m_user_id(key)
{};
@ -38,10 +37,11 @@ public:
class PassKeyModel : public QObject
{
Q_OBJECT
Q_PROPERTY(QString uid READ uid MEMBER m_uid CONSTANT)
Q_PROPERTY(QList<QObject *> userIds READ userIds MEMBER m_user_ids CONSTANT)
Q_PROPERTY(bool isSecret READ isSecret MEMBER m_secret CONSTANT)
Q_PROPERTY(bool isExpired READ isExpired MEMBER m_expired CONSTANT)
Q_PROPERTY(Key key READ key MEMBER m_key CONSTANT)
Q_PROPERTY(QString uid READ uid CONSTANT)
Q_PROPERTY(QList<QObject *> userIds READ userIds CONSTANT)
Q_PROPERTY(bool isSecret READ isSecret CONSTANT)
Q_PROPERTY(bool isExpired READ isExpired CONSTANT)
Key m_key;
public:
@ -58,6 +58,11 @@ public:
return ret;
};
Key key() const
{
return m_key;
};
QString uid() const
{
return QString::fromUtf8(m_key.keyID());

View File

@ -1,6 +1,7 @@
#ifndef UTPASSPHRASEPROVIDER_H
#define UTPASSPHRASEPROVIDER_H
#include <QDebug>
#include <stdio.h>
#include <QObject>
#include <QQmlProperty>
@ -14,48 +15,57 @@
class UTPassphraseProvider : public QObject, public PassphraseProvider
{
Q_OBJECT
private:
std::unique_ptr<QEventLoop> m_loop;
std::unique_ptr<QSemaphore> m_sem;
char *m_passphrase;
bool m_canceled;
public slots:
void handleResponse(bool canceled, QString p)
{
qDebug() << "call handleResponse";
if (!canceled)
gpgrt_asprintf(&m_passphrase, "%s", p.toUtf8().constData());
else
m_canceled = true;
m_loop->quit();
emit unlockEventLoop();
};
signals:
void unlockEventLoop();
private:
std::unique_ptr<QSemaphore> m_sem;
char *m_passphrase;
bool m_canceled;
QObject* m_window;
public:
UTPassphraseProvider():
m_loop(std::unique_ptr<QEventLoop>(new QEventLoop)),
UTPassphraseProvider(QObject* window):
m_sem(std::unique_ptr<QSemaphore>(new QSemaphore(1))),
m_passphrase(nullptr),
m_canceled(false)
{}
m_canceled(false),
m_window(window)
{
qDebug() << "Initialize UTPassphraseProviderr";
}
char *getPassphrase( const char *useridHint,
const char *description,
bool previousWasBad,
bool &canceled ) Q_DECL_OVERRIDE {
if (!m_sem->tryAcquire(1, 3000))
qDebug() << "Call the getPassphrase";
if (!this->m_sem->tryAcquire(1, 500))
{
qWarning() << "Cannot acquire UTPassphraseProvider semaphore.";
canceled = true;
return nullptr;
}
m_passphrase = nullptr;
m_canceled = false;
this->m_passphrase = nullptr;
this->m_canceled = false;
qDebug() << "Call the QML Dialog Passphrase Provider";
QMetaObject::invokeMethod(
Gpg::instance()->getWindow(), "callPassphraseDialog",
this->m_window, "callPassphraseDialog",
Q_ARG(QVariant, useridHint),
Q_ARG(QVariant, description),
Q_ARG(QVariant, previousWasBad)
@ -63,24 +73,22 @@ public:
qDebug() << "Waiting for response";
QObject::connect(
Gpg::instance()->getWindow(), SIGNAL(responsePassphraseDialog(bool, QString)),
this, SLOT(handleResponse(bool, QString))
);
m_loop->exec();
QEventLoop loop;
QObject::connect(this, &UTPassphraseProvider::unlockEventLoop, &loop, &QEventLoop::quit);
loop.exec();
qDebug() << "Prepare Returns";
char *ret;
gpgrt_asprintf(&ret, "%s", m_passphrase);
canceled = m_canceled;
canceled = this->m_canceled;
qDebug() << "Clean";
if (m_passphrase)
if (this->m_passphrase)
{
free(m_passphrase);
}
m_canceled = false;
m_sem->release(1);
this->m_canceled = false;
this->m_sem->release(1);
return ret;
};
};

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: utpass.qrouland\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-01-14 13:57+0100\n"
"POT-Creation-Date: 2025-01-15 23:14+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -17,10 +17,6 @@ msgstr ""
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
#: ../qml/components/FileDir.qml:59
msgid "Decryption failed !"
msgstr ""
#: ../qml/dialogs/ErrorDialog.qml:12
msgid "Error !"
msgstr ""
@ -83,21 +79,25 @@ msgstr ""
msgid "Info"
msgstr ""
#: ../qml/pages/PasswordList.qml:22
#: ../qml/pages/PasswordList.qml:37
msgid ""
"No password found<br>You can import a password store by cloning or importing "
"a zip in the settings"
msgstr ""
#: ../qml/pages/PasswordList.qml:61
#: ../qml/pages/PasswordList.qml:76
msgid "Back"
msgstr ""
#: ../qml/pages/PasswordList.qml:68 ../qml/pages/headers/MainHeader.qml:9
#: ../qml/pages/PasswordList.qml:83 ../qml/pages/headers/MainHeader.qml:9
#: ../qml/pages/headers/StackHeader.qml:9 UTPass.desktop.in.h:1
msgid "UTPass"
msgstr ""
#: ../qml/pages/PasswordList.qml:96
msgid "Decryption failed !"
msgstr ""
#: ../qml/pages/headers/MainHeader.qml:26 ../qml/pages/settings/Settings.qml:70
msgid "Settings"
msgstr ""

View File

@ -10,8 +10,6 @@ MainView {
id: root
signal responsePassphraseDialog(bool canceled, string passphrase)
function initPass(rootView) {
Pass.initialize(rootView);
pageStack.push(Qt.resolvedUrl("pages/PasswordList.qml"));
@ -19,30 +17,36 @@ MainView {
function callPassphraseDialog(useridHint, description, previousWasBad) {
//TODO use parameters to impove passphrase dialog
var passphraseDialog = PopupUtils.open(Qt.resolvedUrl("dialogs/PassphraseDialog.qml"));
passphraseDialog.activateFocus();
var validated = function validated(passphrase) {
responsePassphraseDialog(false, passphrase);
};
var canceled = function canceled() {
responsePassphraseDialog(true, "");
};
passphraseDialog.validated.connect(validated);
passphraseDialog.canceled.connect(canceled);
var pop = PopupUtils.open(passphraseDialog);
pop.activateFocus();
}
objectName: "mainView"
applicationName: "utpass.qrouland"
automaticOrientation: false
width: units.gu(48)
height: units.gu(80)
automaticOrientation: true
width: units.gu(45)
height: units.gu(75)
PageStack {
id: pageStack
anchors.fill: parent
Component.onCompleted: {
}
Component {
id: passphraseDialog
PassphraseDialog {
onValidated: {
console.info("valided");
Pass.responsePassphraseDialog(false, passphrase);
}
onCanceled: {
console.info("canceled");
Pass.responsePassphraseDialog(true, "");
}
}
}
}

View File

@ -33,12 +33,14 @@ Component {
MouseArea {
anchors.fill: parent
onClicked: {
var path = folderModel.folder + "/" + fileName;
if (fileIsDir) {
folderModel.folder = folderModel.folder + "/" + fileName;
folderModel.folder = path;
backAction.visible = true;
passwordListHeader.title = fileName;
} else {
Pass.show(folderModel.folder + "/" + fileName);
console.debug("pass show %1".arg(path))
Pass.show(path);
}
}
}
@ -52,15 +54,6 @@ Component {
borderColor: LomiriColors.warmGrey
}
Component {
id: passwordPageDecryptError
ErrorDialog {
textError: i18n.tr("Decryption failed !")
}
}
}
}

View File

@ -49,11 +49,11 @@ Page {
iconName: "back"
text: "Back"
onTriggered: {
// passwordPage.plainText = "";
// for (var object in objects) {
// object.text = "";
// object.destroy();
// }
passwordPage.plainText = null;
for (var object in objects) {
object.text = null;
object.destroy();
}
pageStack.pop();
}
}

View File

@ -1,9 +1,11 @@
import "headers"
import "../components"
import "../dialogs"
import Lomiri.Components 1.3
import Pass 1.0
import Qt.labs.folderlistmodel 2.1
import QtQuick 2.4
import "headers"
import Lomiri.Components.Popups 1.3
Page {
id: passwordListPage
@ -13,13 +15,13 @@ Page {
anchors.fill: parent
Component.onCompleted: {
passwordStorePath = "file:" + Pass.password_store;
Pass.onDecrypted.connect(function(filename, text) {
Pass.onShowSucceed.connect(function(filename, text) {
pageStack.push(Qt.resolvedUrl("../pages/Password.qml"), {
"plainText": text,
"title": filename
});
});
Pass.onDecryptFailed.connect(function() {
Pass.onShowFailed.connect(function(message) {
PopupUtils.open(passwordPageDecryptError);
});
}
@ -87,4 +89,13 @@ Page {
]
}
Component {
id: passwordPageDecryptError
ErrorDialog {
textError: i18n.tr("Decryption failed !")
}
}
}