mirror of
https://github.com/QRouland/UTPass.git
synced 2025-02-11 06:57:15 +00:00
Fix build rnp for arm64
This commit is contained in:
parent
b9b038b1ae
commit
93361f9ba5
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -1,3 +1,6 @@
|
||||
[submodule "libs/rnp"]
|
||||
path = libs/rnp
|
||||
url = https://github.com/rnpgp/rnp
|
||||
[submodule "libs/botan"]
|
||||
path = libs/botan
|
||||
url = https://github.com/randombit/botan
|
||||
|
@ -10,12 +10,19 @@ scripts:
|
||||
dependencies_target:
|
||||
- libgit2-dev
|
||||
- libquazip5-dev
|
||||
- libgpgmepp-dev
|
||||
- libgpgme-dev
|
||||
- libjson-c-dev
|
||||
- gpg
|
||||
|
||||
libraries:
|
||||
botan:
|
||||
builder: custom
|
||||
make_jobs: 2
|
||||
dependencies_host:
|
||||
- python
|
||||
prebuild:
|
||||
- $SRC_DIR/configure.py --cpu $ARCH --prefix $INSTALL_DIR --with-build-dir $BUILD_DIR
|
||||
build:
|
||||
- make
|
||||
- make install
|
||||
rnp:
|
||||
builder: cmake
|
||||
make_jobs: 2
|
||||
@ -23,9 +30,8 @@ libraries:
|
||||
- libbz2-dev
|
||||
- zlib1g-dev
|
||||
- libjson-c-dev
|
||||
build_args: [
|
||||
-DCRYPTO_BACKEND=openssl
|
||||
]
|
||||
build_args: -DBUILD_SHARED_LIBS=on -DBUILD_TESTING=off -DCRYPTO_BACKEND=botan
|
||||
|
||||
|
||||
install_lib:
|
||||
- "libgit2.so*"
|
||||
@ -35,9 +41,6 @@ install_lib:
|
||||
- "libhttp_parser.so*"
|
||||
- "libssh2.so*"
|
||||
- "libquazip5.so*"
|
||||
- "libgpg-error.so.0.28.0"
|
||||
- "libassuan.so*"
|
||||
- "libgpgme.so*"
|
||||
- "libgpgmepp.so*"
|
||||
- "libqgpgme.so*"
|
||||
- "librnp.so*"
|
||||
- "libbotan-2.so*"
|
||||
|
||||
|
1
libs/botan
Submodule
1
libs/botan
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 935055e839794a076d209c9e9a1e9cd2255aae01
|
2
libs/rnp
2
libs/rnp
@ -1 +1 @@
|
||||
Subproject commit c41cef116443d1572118844ecff0292f3ed4e55b
|
||||
Subproject commit 2e249423d617cf91714624a76bfe4ff613b41ac4
|
@ -6,10 +6,12 @@ set(
|
||||
plugin.cpp
|
||||
pass.cpp
|
||||
passkeymodel.h
|
||||
passphraseprovider2.h
|
||||
jobs/rmjob.cpp
|
||||
jobs/rnpjob.cpp
|
||||
jobs/getkeysjob.cpp
|
||||
jobs/importkeyjob.cpp
|
||||
jobs/decryptjob.cpp
|
||||
)
|
||||
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
@ -29,37 +31,23 @@ set_target_properties(${PLUGIN} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${PLUGIN})
|
||||
qt5_use_modules(${PLUGIN} Qml Quick DBus)
|
||||
|
||||
|
||||
|
||||
set(RNP_BUILD_DIR "${CMAKE_SOURCE_DIR}/build/${ARCH_TRIPLET}/rnp/install")
|
||||
set(RNP_INSTALL_DIR "${CMAKE_SOURCE_DIR}/build/${ARCH_TRIPLET}/rnp/install")
|
||||
|
||||
find_package(OpenSSL REQUIRED)
|
||||
find_package(JSON-C 0.11)
|
||||
|
||||
INCLUDE_DIRECTORIES(${RNP_BUILD_DIR}/include)
|
||||
INCLUDE_DIRECTORIES(${RNP_INSTALL_DIR}/include)
|
||||
|
||||
add_library(rnp STATIC IMPORTED)
|
||||
set_property(TARGET rnp PROPERTY IMPORTED_LOCATION "${RNP_BUILD_DIR}/lib/librnp.a")
|
||||
# add_library(rnp STATIC IMPORTED)
|
||||
# set_property(TARGET rnp PROPERTY IMPORTED_LOCATION "${RNP_BUILD_DIR}/lib/librnp.a")
|
||||
|
||||
add_library(sexpp STATIC IMPORTED)
|
||||
set_property(TARGET sexpp PROPERTY IMPORTED_LOCATION "${RNP_BUILD_DIR}/lib/libsexpp.a")
|
||||
# add_library(sexpp STATIC IMPORTED)
|
||||
# set_property(TARGET sexpp PROPERTY IMPORTED_LOCATION "${RNP_BUILD_DIR}/lib/libsexpp.a")
|
||||
|
||||
add_library(gpgerror SHARED IMPORTED)
|
||||
set_property(TARGET gpgerror PROPERTY IMPORTED_LOCATION "/usr/lib/${ARCH_TRIPLET}/libgpg-error.so.0.28.0")
|
||||
add_library(rnp SHARED IMPORTED)
|
||||
set_property(TARGET rnp PROPERTY IMPORTED_LOCATION "${RNP_INSTALL_DIR}/lib/librnp.so")
|
||||
|
||||
add_library(libassuan SHARED IMPORTED)
|
||||
set_property(TARGET libassuan PROPERTY IMPORTED_LOCATION "/usr/lib/${ARCH_TRIPLET}/libassuan.so")
|
||||
|
||||
add_library(libgpgme SHARED IMPORTED)
|
||||
set_property(TARGET libgpgme PROPERTY IMPORTED_LOCATION "/usr/lib/${ARCH_TRIPLET}/libgpgme.so")
|
||||
|
||||
add_library(libgpgmepp SHARED IMPORTED)
|
||||
set_property(TARGET libgpgmepp PROPERTY IMPORTED_LOCATION "/usr/lib/${ARCH_TRIPLET}/libgpgmepp.so")
|
||||
|
||||
add_library(libqgpgme SHARED IMPORTED)
|
||||
set_property(TARGET libqgpgme PROPERTY IMPORTED_LOCATION "/usr/lib/${ARCH_TRIPLET}/libqgpgme.so")
|
||||
|
||||
|
||||
target_link_libraries(${PLUGIN} rnp sexpp gpgerror libassuan libgpgme libgpgmepp libqgpgme OpenSSL::Crypto JSON-C::JSON-C)
|
||||
target_link_libraries(${PLUGIN} rnp OpenSSL::Crypto JSON-C::JSON-C)
|
||||
|
||||
set(QT_IMPORTS_DIR "/lib/${ARCH_TRIPLET}")
|
||||
install(TARGETS ${PLUGIN} DESTINATION ${QT_IMPORTS_DIR}/${PLUGIN}/)
|
||||
|
@ -1,7 +1,13 @@
|
||||
#include "decryptjob.h"
|
||||
#include "qdebug.h"
|
||||
extern "C" {
|
||||
#include <rnp/rnp.h>
|
||||
#include <rnp/rnp_err.h>
|
||||
}
|
||||
|
||||
DecryptJob::DecryptJob(QString path, QString keyfile):
|
||||
m_path(path)
|
||||
DecryptJob::DecryptJob(QDir rnp_homedir, QString path):
|
||||
RnpJob(rnp_homedir),
|
||||
m_encrypted_file_path(path)
|
||||
{
|
||||
this->setObjectName("DecryptJob");
|
||||
}
|
||||
@ -9,7 +15,33 @@ DecryptJob::DecryptJob(QString path, QString keyfile):
|
||||
|
||||
void DecryptJob::run()
|
||||
{
|
||||
this->load_sec_keyring();
|
||||
rnp_input_from_path(&keyfile, "secring.pgp"));
|
||||
qFatal("To be implemented !")
|
||||
qDebug() << "[DecryptJob] Starting";
|
||||
this->load_sec_keyring(NULL);
|
||||
|
||||
rnp_input_t input = NULL;
|
||||
rnp_output_t output = NULL;
|
||||
uint8_t * buf = NULL;
|
||||
size_t buf_len = 0;
|
||||
|
||||
auto ret = rnp_input_from_path(&input, this->m_encrypted_file_path.toLocal8Bit().data());
|
||||
if (ret == RNP_SUCCESS) {
|
||||
ret = rnp_output_to_memory(&output, 0);
|
||||
}
|
||||
if (ret == RNP_SUCCESS) {
|
||||
ret = rnp_decrypt(this->m_ffi, input, output);
|
||||
}
|
||||
if (ret == RNP_SUCCESS) {
|
||||
ret = rnp_output_memory_get_buf(output, &buf, &buf_len, false);
|
||||
}
|
||||
if (ret == RNP_SUCCESS) {
|
||||
emit resultSuccess(this->m_encrypted_file_path, QString::fromUtf8((char*)buf));
|
||||
}
|
||||
|
||||
rnp_input_destroy(input);
|
||||
rnp_output_destroy(output);
|
||||
|
||||
terminateOnError(ret);
|
||||
|
||||
emit resultSuccess(this->m_encrypted_file_path, QString::fromUtf8((char*)buf));
|
||||
qDebug() << "[DecryptJob] Finished Successfully ";
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ signals:
|
||||
* @param encrypted_file_path The path to the encrypted file that was decrypted.
|
||||
* @param clear_txt The decrypted content in clear-text. If an error occurs, this may be empty.
|
||||
*/
|
||||
void resultReady(QString encrypted_file_path, QString clear_txt);
|
||||
void resultSuccess(QString encrypted_file_path, QString clear_txt);
|
||||
|
||||
private:
|
||||
QString m_encrypted_file_path; /**< The path to the encrypted file that is to be decrypted. */
|
||||
@ -46,9 +46,10 @@ public:
|
||||
* This constructor initializes the DecryptJob with the encrypted file path. The decryption
|
||||
* operation will be executed in a background thread when the job is started.
|
||||
*
|
||||
* @param rnp_homedir The directory containing the keyrings.
|
||||
* @param path The path to the encrypted file that needs to be decrypted.
|
||||
*/
|
||||
DecryptJob(QString path);
|
||||
DecryptJob(QDir rnp_homedir, QString path);
|
||||
};
|
||||
|
||||
#endif // DECRYPTJOB_H
|
||||
|
@ -32,13 +32,14 @@ void GetKeysJob::run()
|
||||
QSet<QString> fingerprints = QSet<QString>();
|
||||
this->load_full_keyring(&fingerprints);
|
||||
|
||||
//Get infos keys
|
||||
auto key_infos = QList<QJsonDocument>();
|
||||
QList<QJsonDocument>::iterator i;
|
||||
for (auto i = fingerprints.begin(), end = fingerprints.end(); i != end; ++i) {
|
||||
key_infos.append(this->fingerprint_map_key_info(*i));
|
||||
}
|
||||
|
||||
//Get all infos keys
|
||||
// Emit result
|
||||
emit resultSuccess(key_infos);
|
||||
qDebug() << "[GetKeysJob] Finished Successfully ";
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ bool RnpJob::passProvider(rnp_ffi_t ffi,
|
||||
|
||||
void RnpJob::load_key_file(QSet<QString> *result_fingerprints, const QString path, const uint32_t flags)
|
||||
{
|
||||
qDebug() << "[RnpJob] load keyring at" << path;
|
||||
qDebug() << "[RnpJob] Load keyring at" << path;
|
||||
rnp_input_t input = NULL;
|
||||
if (QFileInfo::exists(this->pubringPath())) {
|
||||
auto ret = rnp_input_from_path(&input, path.toLocal8Bit().constData());
|
||||
@ -75,9 +75,9 @@ void RnpJob::load_key_file(QSet<QString> *result_fingerprints, const QString pat
|
||||
rnp_input_destroy(input);
|
||||
rnp_buffer_destroy(json);
|
||||
terminateOnError(ret);
|
||||
qDebug() << "[RnpJob] keyring loaded successfully";
|
||||
qDebug() << "[RnpJob] Keyring loaded successfully";
|
||||
} else {
|
||||
qDebug() << "[RnpJob] No keyring" << path << "not found";
|
||||
qDebug() << "[RnpJob] Keyring" << path << "not found";
|
||||
}
|
||||
}
|
||||
|
||||
@ -85,18 +85,15 @@ void RnpJob::load_key_file(QSet<QString> *result_fingerprints, const QString pat
|
||||
void RnpJob::load_pub_keyring(QSet<QString> *result_fingerprints = NULL)
|
||||
{
|
||||
this->load_key_file(result_fingerprints, this->pubringPath(), RNP_LOAD_SAVE_PUBLIC_KEYS);
|
||||
qDebug() << "[RnpJob] pub fingerprints" << *result_fingerprints;
|
||||
}
|
||||
|
||||
void RnpJob::load_sec_keyring(QSet<QString> *result_fingerprints = NULL)
|
||||
{
|
||||
this->load_key_file(result_fingerprints, this->secringPath(), RNP_LOAD_SAVE_SECRET_KEYS);
|
||||
qDebug() << "[RnpJob] sec fingerprints" << *result_fingerprints;
|
||||
}
|
||||
|
||||
void RnpJob::load_full_keyring(QSet<QString> *result_fingerprints = NULL)
|
||||
{
|
||||
this->load_pub_keyring(result_fingerprints);
|
||||
this->load_sec_keyring(result_fingerprints);
|
||||
qDebug() << "[RnpJob] full fingerprints" << *result_fingerprints;
|
||||
}
|
||||
|
@ -153,6 +153,11 @@ public:
|
||||
* the RNP FFI handle.
|
||||
*/
|
||||
~RnpJob();
|
||||
|
||||
|
||||
void setPassProvider(rnp_password_cb pass_provider_cb) {
|
||||
rnp_ffi_set_pass_provider(this->m_ffi, pass_provider_cb, NULL);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // RNPJOB_H
|
||||
|
@ -2,9 +2,12 @@
|
||||
#include <QtCore/QStandardPaths>
|
||||
#include <QtCore/QDir>
|
||||
|
||||
#include "jobs/decryptjob.h"
|
||||
#include "jobs/getkeysjob.h"
|
||||
#include "jobs/importkeyjob.h"
|
||||
#include "pass.h"
|
||||
#include "passphraseprovider2.h"
|
||||
//#include "passphraseprovider2.h"
|
||||
|
||||
|
||||
|
||||
@ -13,18 +16,19 @@ Pass::Pass():
|
||||
QStandardPaths::AppDataLocation).append("/.password-store")),
|
||||
m_gpg_home (QStandardPaths::writableLocation(
|
||||
QStandardPaths::AppDataLocation).append("/.rnp")),
|
||||
m_passphrase_provider(&UTPassphraseProvider::get_pass_provider),
|
||||
m_sem(std::unique_ptr<QSemaphore>(new QSemaphore(1)))
|
||||
{
|
||||
|
||||
}
|
||||
{}
|
||||
|
||||
void Pass::initialize(QObject *window)
|
||||
{
|
||||
if (!window) {
|
||||
qWarning("[Pass] Window should be null only for testing");
|
||||
}
|
||||
this->initGpgHome();
|
||||
this->initPasswordStore();
|
||||
if (!window) {
|
||||
qWarning("[Pass] Window should be null only for testing");
|
||||
} else {
|
||||
UTPassphraseProvider::instance().setWindow(window);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -53,36 +57,37 @@ void Pass::initPasswordStore()
|
||||
qInfo() << "[Pass] Password Store is :" << m_password_store;
|
||||
}
|
||||
|
||||
// bool Pass::show(QUrl url)
|
||||
// {
|
||||
// if (!this->m_sem->tryAcquire(1, 500)) {
|
||||
// return false;
|
||||
// }
|
||||
// auto path = url.toLocalFile();
|
||||
// qInfo() << "Pass show " << path;
|
||||
// QFileInfo file_info(path);
|
||||
// this->m_show_filename = file_info.completeBaseName();
|
||||
// return this->m_gpg->decryptFromFile(path);
|
||||
// }
|
||||
bool Pass::show(QUrl url)
|
||||
{
|
||||
if (!this->m_sem->tryAcquire(1, 500)) {
|
||||
qInfo() << "[Pass] A command is already running";
|
||||
return false;
|
||||
}
|
||||
auto job = new DecryptJob(this->m_gpg_home, url.toLocalFile());
|
||||
job->setPassProvider(this->m_passphrase_provider);
|
||||
QObject::connect(job, &DecryptJob::resultError, this, &Pass::slotShowError);
|
||||
QObject::connect(job, &DecryptJob::resultSuccess, this, &Pass::slotShowSucceed);
|
||||
connect(job, &DecryptJob::finished, job, &QObject::deleteLater);
|
||||
job->start();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// void Pass::showResult(Error err, QString plain_text)
|
||||
// {
|
||||
// qDebug() << "Pass show Result";
|
||||
// if (err) {
|
||||
// qInfo() << "Pass show Failed";
|
||||
// emit showFailed(err.asString());
|
||||
void Pass::slotShowError(rnp_result_t err)
|
||||
{
|
||||
qInfo() << "[Pass] Show Failed";
|
||||
emit showFailed(rnp_result_to_string(err));
|
||||
this->m_sem->release(1);
|
||||
}
|
||||
|
||||
// } else if (err.isCanceled()) {
|
||||
// qInfo() << "Pass show Cancelled";
|
||||
// emit showCancelled();
|
||||
// } else {
|
||||
// qInfo() << "Pass show Succeed";
|
||||
// emit showSucceed(this->m_show_filename, plain_text);
|
||||
// }
|
||||
// this->m_show_filename = QString();
|
||||
// this->m_sem->release(1);
|
||||
// }
|
||||
|
||||
void Pass::slotShowSucceed(QString encrypted_file_path, QString plain_text)
|
||||
{
|
||||
qDebug() << "[Pass] Show Succeed";
|
||||
QFileInfo file_info(encrypted_file_path);
|
||||
emit showSucceed(file_info.completeBaseName(), plain_text);
|
||||
this->m_sem->release(1);
|
||||
}
|
||||
|
||||
// bool Pass::deletePasswordStore()
|
||||
// {
|
||||
|
@ -6,14 +6,10 @@
|
||||
#include <QObject>
|
||||
#include <QUrl>
|
||||
#include <QVariant>
|
||||
#include <gpgme++/context.h>
|
||||
#include <QSemaphore>
|
||||
extern "C" {
|
||||
#include <rnp/rnp.h>
|
||||
}
|
||||
|
||||
using namespace GpgME;
|
||||
|
||||
/**
|
||||
* @class Pass
|
||||
* @brief A class for managing password storage using GPG encryption.
|
||||
@ -33,13 +29,15 @@ private slots:
|
||||
* @param err The error that occurred during the operation.
|
||||
* @param plain_text The decrypted plain text (password).
|
||||
*/
|
||||
void showResult(Error err, QString plain_text);
|
||||
void slotShowError(rnp_result_t err);
|
||||
|
||||
void slotShowSucceed(QString encrypted_file_path, QString plain_text);
|
||||
|
||||
/**
|
||||
* @brief Slot to handle the result of a GPG key deletion operation.
|
||||
* @param err The error that occurred during the operation.
|
||||
*/
|
||||
void deleteGPGKeyResult(Error err);
|
||||
// void deleteGPGKeyResult(Error err);
|
||||
|
||||
/**
|
||||
* @brief Slot to handle the error result of a GPG key import operation.
|
||||
@ -148,7 +146,7 @@ private:
|
||||
QString m_gpg_home; /**< The path to the gpg home. */
|
||||
std::unique_ptr<PassKeyringModel>
|
||||
m_keyring_model; /**< Meta data on the keyring uid, name, secrecy ... of the availble keys. */
|
||||
PassphraseProvider *m_passphrase_provider; /**< Pointer on passphrase povider for operations using secret keys. */
|
||||
rnp_password_cb m_passphrase_provider; /**< Pointer on passphrase povider for operations using secret keys. */
|
||||
std::unique_ptr<QSemaphore> m_sem; /**< Semaphore for managing concurrent operations. */
|
||||
|
||||
|
||||
@ -206,14 +204,8 @@ public:
|
||||
this->m_gpg_home = gpg_home;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Sets the window passphrase provider used for GPG authentication.
|
||||
*
|
||||
* PassphraseProvider will be deleted with destructor.
|
||||
*
|
||||
* @param The window used by passphrase provider.
|
||||
*/
|
||||
void set_passphrase_provider(PassphraseProvider* passphrase_provider)
|
||||
|
||||
void set_passphrase_provider(rnp_password_cb passphrase_provider)
|
||||
{
|
||||
this->m_passphrase_provider = passphrase_provider;
|
||||
}
|
||||
|
@ -11,12 +11,6 @@
|
||||
* @class PassKeyModel
|
||||
* @brief A model representing a GPG (GNU Privacy Guard) key.
|
||||
*
|
||||
* This class encapsulates the properties of a GPG key, such as its key ID, associated
|
||||
* user IDs, secret key status, and expiration status. It is used within an application
|
||||
* to manage and represent GPG keys, providing easy access to key data and related user information.
|
||||
*
|
||||
* This class supports properties such as the key's fingerprint, key ID, user IDs, and whether
|
||||
* the key has a secret key associated with it.
|
||||
*/
|
||||
class PassKeyModel : public QObject
|
||||
{
|
||||
|
132
plugins/Pass/passphraseprovider2.h
Normal file
132
plugins/Pass/passphraseprovider2.h
Normal file
@ -0,0 +1,132 @@
|
||||
#ifndef UTPASSPHRASEPROVIDER2_H
|
||||
#define UTPASSPHRASEPROVIDER2_H
|
||||
|
||||
#include <QDebug>
|
||||
#include <memory>
|
||||
#include <stdio.h>
|
||||
#include <QObject>
|
||||
#include <QQmlProperty>
|
||||
#include <QEventLoop>
|
||||
#include <QSemaphore>
|
||||
extern "C" {
|
||||
#include <rnp/rnp.h>
|
||||
}
|
||||
|
||||
/**
|
||||
* @class UTPassphraseProvider
|
||||
* @brief A passphrase provider for GPG operations that interacts with a QML dialog.
|
||||
*/
|
||||
|
||||
class UTPassphraseProvider : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public slots:
|
||||
/**
|
||||
* @brief Slot to handle the user's response from the passphrase dialog.
|
||||
*
|
||||
* This method processes the response from the passphrase dialog. If the user provides a passphrase,
|
||||
* it is stored; if the operation is canceled, a flag is set.
|
||||
*
|
||||
* @param canceled Whether the user canceled the passphrase entry.
|
||||
* @param passphrase The passphrase entered by the user.
|
||||
*/
|
||||
void handleResponse(bool canceled, QString passphrase)
|
||||
{
|
||||
qDebug() << "call handleResponse";
|
||||
if (!canceled)
|
||||
this->m_passphrase = passphrase;
|
||||
else
|
||||
m_canceled = true;
|
||||
emit unlockEventLoop();
|
||||
};
|
||||
|
||||
signals:
|
||||
/**
|
||||
* @brief Signal to unlock the event loop.
|
||||
*
|
||||
* This signal is emitted when the passphrase has been entered or the operation has been canceled,
|
||||
* unlocking the event loop waiting for the response.
|
||||
*/
|
||||
void unlockEventLoop();
|
||||
|
||||
|
||||
private:
|
||||
explicit UTPassphraseProvider(QObject * parent = nullptr)
|
||||
: m_sem(std::make_unique<QSemaphore>(1)),
|
||||
m_passphrase(QString::Null()),
|
||||
m_canceled(false)
|
||||
{}
|
||||
QObject *m_window; /**< The window object that triggers the QML dialog. */
|
||||
std::unique_ptr<QSemaphore> m_sem; /**< Semaphore for managing access. */
|
||||
QString m_passphrase; /**< The passphrase provided by the user. */
|
||||
bool m_canceled; /**< Flag indicating whether the passphrase operation was canceled. */
|
||||
|
||||
public:
|
||||
~UTPassphraseProvider() = default;
|
||||
|
||||
static UTPassphraseProvider& instance()
|
||||
{
|
||||
static UTPassphraseProvider instance;
|
||||
return instance;
|
||||
}
|
||||
UTPassphraseProvider(UTPassphraseProvider const &) = delete;
|
||||
void operator=(UTPassphraseProvider const &) = delete;
|
||||
|
||||
static bool
|
||||
get_pass_provider(rnp_ffi_t ffi,
|
||||
void * app_ctx,
|
||||
rnp_key_handle_t key,
|
||||
const char * pgp_context,
|
||||
char buf[],
|
||||
size_t buf_len)
|
||||
{
|
||||
qDebug() << "Call the getPassphrase";
|
||||
|
||||
if (!UTPassphraseProvider::instance().m_sem->tryAcquire(1, 500))
|
||||
{
|
||||
qWarning() << "Cannot acquire UTPassphraseProvider semaphore.";
|
||||
UTPassphraseProvider::instance().m_canceled = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
UTPassphraseProvider::instance().m_passphrase = nullptr;
|
||||
UTPassphraseProvider::instance().m_canceled = false;
|
||||
|
||||
qDebug() << "Call the QML Dialog Passphrase Provider";
|
||||
QMetaObject::invokeMethod(
|
||||
UTPassphraseProvider::instance().m_window, "callPassphraseDialog",
|
||||
Q_ARG(QVariant, "useridHint"), // TODO
|
||||
Q_ARG(QVariant, "description"), // TODO
|
||||
Q_ARG(QVariant, "previousWasBad") // TODO
|
||||
);
|
||||
|
||||
qDebug() << "Waiting for response";
|
||||
|
||||
QEventLoop loop;
|
||||
QObject::connect(&UTPassphraseProvider::instance(), &UTPassphraseProvider::unlockEventLoop, &loop, &QEventLoop::quit);
|
||||
loop.exec();
|
||||
|
||||
qDebug() << "Prepare Returns";
|
||||
auto ret = false;
|
||||
if(!UTPassphraseProvider::instance().m_canceled) {
|
||||
strncpy(buf, UTPassphraseProvider::instance().m_passphrase.toLocal8Bit().data(), buf_len);
|
||||
ret = true;
|
||||
};
|
||||
|
||||
qDebug() << "Clean";
|
||||
if (UTPassphraseProvider::instance().m_passphrase.isNull())
|
||||
{
|
||||
UTPassphraseProvider::instance().m_passphrase = QString::Null();
|
||||
}
|
||||
UTPassphraseProvider::instance().m_canceled = false;
|
||||
UTPassphraseProvider::instance().m_sem->release(1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void setWindow(QObject* window){
|
||||
this->m_window = window;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: utpass.qrouland\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-02-01 14:08+0100\n"
|
||||
"POT-Creation-Date: 2025-02-03 16:44+0000\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"
|
||||
@ -123,7 +123,7 @@ msgstr ""
|
||||
|
||||
#: ../qml/pages/settings/DeleteRepo.qml:56
|
||||
#: ../qml/pages/settings/ImportZip.qml:64
|
||||
#: ../qml/pages/settings/InfoKeys.qml:170
|
||||
#: ../qml/pages/settings/InfoKeys.qml:167
|
||||
#: ../qml/pages/settings/git/ImportGitClone.qml:56
|
||||
msgid "Yes"
|
||||
msgstr ""
|
||||
@ -137,7 +137,7 @@ msgid "Password Store deleted !"
|
||||
msgstr ""
|
||||
|
||||
#: ../qml/pages/settings/DeleteRepo.qml:90
|
||||
#: ../qml/pages/settings/InfoKeys.qml:212
|
||||
#: ../qml/pages/settings/InfoKeys.qml:209
|
||||
msgid "Info Keys"
|
||||
msgstr ""
|
||||
|
||||
@ -171,35 +171,35 @@ msgstr ""
|
||||
msgid "Zip Password Store Import"
|
||||
msgstr ""
|
||||
|
||||
#: ../qml/pages/settings/InfoKeys.qml:50
|
||||
#: ../qml/pages/settings/InfoKeys.qml:47
|
||||
msgid "No key found"
|
||||
msgstr ""
|
||||
|
||||
#: ../qml/pages/settings/InfoKeys.qml:86
|
||||
#: ../qml/pages/settings/InfoKeys.qml:83
|
||||
msgid "Key ID :"
|
||||
msgstr ""
|
||||
|
||||
#: ../qml/pages/settings/InfoKeys.qml:120
|
||||
#: ../qml/pages/settings/InfoKeys.qml:117
|
||||
msgid "Users IDs : "
|
||||
msgstr ""
|
||||
|
||||
#: ../qml/pages/settings/InfoKeys.qml:147
|
||||
#: ../qml/pages/settings/InfoKeys.qml:144
|
||||
msgid "Delete this key"
|
||||
msgstr ""
|
||||
|
||||
#: ../qml/pages/settings/InfoKeys.qml:169
|
||||
#: ../qml/pages/settings/InfoKeys.qml:166
|
||||
msgid "You're are about to delete<br>%1.<br>Continue ?"
|
||||
msgstr ""
|
||||
|
||||
#: ../qml/pages/settings/InfoKeys.qml:183
|
||||
#: ../qml/pages/settings/InfoKeys.qml:180
|
||||
msgid "Key removal failed !"
|
||||
msgstr ""
|
||||
|
||||
#: ../qml/pages/settings/InfoKeys.qml:192
|
||||
#: ../qml/pages/settings/InfoKeys.qml:189
|
||||
msgid "Key successfully deleted !"
|
||||
msgstr ""
|
||||
|
||||
#: ../qml/pages/settings/InfoKeys.qml:204
|
||||
#: ../qml/pages/settings/InfoKeys.qml:201
|
||||
msgid "An Error occured getting GPG keys !"
|
||||
msgstr ""
|
||||
|
||||
|
@ -26,9 +26,6 @@ MainView {
|
||||
automaticOrientation: true
|
||||
width: units.gu(45)
|
||||
height: units.gu(75)
|
||||
Component.onCompleted: {
|
||||
myWorker.sendMessage("Hello World !");
|
||||
}
|
||||
|
||||
PageStack {
|
||||
id: pageStack
|
||||
|
@ -14,10 +14,7 @@ Page {
|
||||
|
||||
Component.onCompleted: {
|
||||
Pass.getAllGPGKeysSucceed.connect(function(keys_info) {
|
||||
infoKeysPage.__keys = keys_info;
|
||||
for (var i = 0; i < keys_info.length; ++i) {
|
||||
console.debug("is secret " + keys_info[i].isSecret);
|
||||
}
|
||||
infoKeysPage.__keys = keys_info.keys;
|
||||
});
|
||||
Pass.getAllGPGKeysFailed.connect(function(message) {
|
||||
PopupUtils.open(infoKeysPageGetAllError);
|
||||
@ -91,7 +88,7 @@ Page {
|
||||
width: parent.width
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
text: model.modelData.uid
|
||||
text: model.modelData.keyid
|
||||
color: theme.palette.normal.backgroundText
|
||||
}
|
||||
|
||||
@ -105,9 +102,9 @@ Page {
|
||||
id: userIdsModel
|
||||
|
||||
Component.onCompleted: {
|
||||
for (var i = 0; i < model.modelData.userIds.length; ++i) {
|
||||
for (var i = 0; i < model.modelData.userids.length; ++i) {
|
||||
userIdsModel.append({
|
||||
"model": model.modelData.userIds[i]
|
||||
"model": model.modelData.userids[i]
|
||||
});
|
||||
}
|
||||
}
|
||||
|
1
tests/assets/gpg/clear_text.txt
Normal file
1
tests/assets/gpg/clear_text.txt
Normal file
@ -0,0 +1 @@
|
||||
SomePassword
|
1
tests/assets/gpg/clear_text.txt.gpg
Normal file
1
tests/assets/gpg/clear_text.txt.gpg
Normal file
@ -0,0 +1 @@
|
||||
„^űÚáÝÎ8m@ă˘z,fL<66>?ŐŽĄŔjÜö—'ś§!ř[Pfi0 p<C2A0>—:ĘÉ0Cď9e;ĽÓţ/¤˘ë<04>cń;Y\ěÉ×ŮĂL‡GwšHßÔ` ÔPt.E8Ääšy—ů[z[mŠ<6D>Îĺď ÖŃOŢô<C5A2>XkL´°c·Ź°ëś<C3AB>ěpC<70>+ŇÔ$ąÔIéI{ÝHîvłÂÎ0±]Śr‹ÓH˙·Žl/‚!lžÁ´őĚĂ0
|
0
tests/assets/gpg/encrypted.gpg
Normal file
0
tests/assets/gpg/encrypted.gpg
Normal file
@ -3,23 +3,38 @@
|
||||
|
||||
#include <QObject>
|
||||
#include <gpg-error.h>
|
||||
#include <gpgme++/interfaces/passphraseprovider.h>
|
||||
extern "C" {
|
||||
#include <rnp/rnp.h>
|
||||
}
|
||||
|
||||
class TesTPassphraseProvider : public QObject, public GpgME::PassphraseProvider
|
||||
class TesTPassphraseProvider : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
explicit TesTPassphraseProvider(QObject * parent = nullptr)
|
||||
{}
|
||||
|
||||
public:
|
||||
char *getPassphrase(const char *useridHint,
|
||||
const char *description,
|
||||
bool previousWasBad,
|
||||
bool &canceled) override
|
||||
~TesTPassphraseProvider() = default;
|
||||
|
||||
static TesTPassphraseProvider& instance()
|
||||
{
|
||||
static TesTPassphraseProvider instance;
|
||||
return instance;
|
||||
}
|
||||
TesTPassphraseProvider(TesTPassphraseProvider const &) = delete;
|
||||
void operator=(TesTPassphraseProvider const &) = delete;
|
||||
|
||||
char *ret;
|
||||
gpgrt_asprintf(&ret, "%s", "utpasspassphrase");
|
||||
return ret;
|
||||
};
|
||||
};
|
||||
|
||||
static bool
|
||||
example_pass_provider(rnp_ffi_t ffi,
|
||||
void * app_ctx,
|
||||
rnp_key_handle_t key,
|
||||
const char * pgp_context,
|
||||
char buf[],
|
||||
size_t buf_len)
|
||||
{ strncpy(buf, "utpasspassphrase", buf_len);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
@ -70,7 +70,7 @@ void TestsUtils::copyFolder(QUrl sourceFolderUrl, QUrl destFolderUrl)
|
||||
|
||||
QObject *TestsUtils::getTestPassphraseProvider()
|
||||
{
|
||||
return this->m_passphrase_povider.get();
|
||||
return &TesTPassphraseProvider::instance();
|
||||
}
|
||||
|
||||
|
||||
|
@ -11,9 +11,6 @@ class TestsUtils : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
std::unique_ptr<TesTPassphraseProvider> m_passphrase_povider;
|
||||
|
||||
public:
|
||||
TestsUtils();
|
||||
~TestsUtils() override = default;
|
||||
|
@ -9,13 +9,11 @@ PassTestCase {
|
||||
function init_data() {
|
||||
return [{
|
||||
"spy": getAllGPGKeysSucceed,
|
||||
"signal": Pass.getAllGPGKeysSucceed,
|
||||
"err_msg": null,
|
||||
"add_home_gpg_data": false,
|
||||
"keys": []
|
||||
}, {
|
||||
"spy": getAllGPGKeysSucceed,
|
||||
"signal": Pass.getAllGPGKeysSucceed,
|
||||
"err_msg": null,
|
||||
"add_home_gpg_data": true,
|
||||
"keys": [{
|
||||
@ -32,7 +30,7 @@ PassTestCase {
|
||||
TestsUtils.copyFolder(Qt.resolvedUrl("../../assets/gpghome"), Qt.resolvedUrl(gpg_home));
|
||||
|
||||
var keys;
|
||||
data.signal.connect(function(keys_info) {
|
||||
Pass.getAllGPGKeysSucceed.connect(function(keys_info) {
|
||||
keys = keys_info;
|
||||
});
|
||||
Pass.getAllGPGKeys();
|
||||
|
@ -8,30 +8,27 @@ PassTestCase {
|
||||
return [{
|
||||
"file": Qt.resolvedUrl("../../assets/gpg/test_key.gpg"),
|
||||
"spy": importGPGKeySucceed,
|
||||
"signal": Pass.importGPGKeySucceed,
|
||||
"err_msg": null
|
||||
}, {
|
||||
"file": Qt.resolvedUrl("../../assets/gpg/test_key_do_not_exist.gpg"),
|
||||
"spy": importGPGKeyFailed,
|
||||
"signal": Pass.importGPGKeyFailed,
|
||||
"err_msg": "Error reading file"
|
||||
}, {
|
||||
"file": Qt.resolvedUrl("../../assets/gpg/test_key_invalid.gpg"),
|
||||
"spy": importGPGKeyFailed,
|
||||
"signal": Pass.importGPGKeyFailed,
|
||||
"err_msg": "Bad state"
|
||||
}];
|
||||
}
|
||||
|
||||
function test_import_key(data) {
|
||||
var err_msg;
|
||||
data.signal.connect(function(message) {
|
||||
Pass.importGPGKeyFailed.connect(function(message) {
|
||||
err_msg = message;
|
||||
});
|
||||
Pass.importGPGKey(data.file);
|
||||
data.spy.wait();
|
||||
if (data.err_msg) {
|
||||
verify(err_msg === data.err_msg, "Should return arg msg %1 but return %2".arg(data.err_msg).arg(err_msg));
|
||||
verify(err_msg === data.err_msg, "Should return %1 but return %2".arg(data.err_msg).arg(err_msg));
|
||||
} else {
|
||||
console.info(Qt.resolvedUrl("%1/pubkeyring.pgp".arg(gpg_home)));
|
||||
verify(TestsUtils.fileExists(Qt.resolvedUrl("%1/pubring.pgp".arg(gpg_home))), "%1/pubring.pgp should be created".arg(gpg_home));
|
||||
|
61
tests/units/pass/tst_show.qml
Normal file
61
tests/units/pass/tst_show.qml
Normal file
@ -0,0 +1,61 @@
|
||||
import Pass 1.0
|
||||
import QtQuick 2.9
|
||||
import QtTest 1.2
|
||||
import TestsUtils 1.0
|
||||
|
||||
PassTestCase {
|
||||
//TODO some additionanl error test
|
||||
|
||||
function init_data() {
|
||||
return [{
|
||||
"spy": showFailed,
|
||||
"err_msg": "Bad password",
|
||||
"add_home_gpg_data": true,
|
||||
"file": "../../assets/gpg/clear_text.txt.gpg"
|
||||
}, {
|
||||
"spy": showFailed,
|
||||
"err_msg": "No suitable key",
|
||||
"add_home_gpg_data": false,
|
||||
"file": "../../assets/gpg/clear_text.txt.gpg"
|
||||
}];
|
||||
}
|
||||
|
||||
function test_pass_show(data) {
|
||||
if (data.add_home_gpg_data === true) {
|
||||
TestsUtils.copyFolder(Qt.resolvedUrl("../../assets/gpghome"), Qt.resolvedUrl(gpg_home));
|
||||
}
|
||||
|
||||
var fname, ctext;
|
||||
Pass.showSucceed.connect(function(file_name, clear_text) {
|
||||
fname = file_name;
|
||||
ctext = clear_text;
|
||||
});
|
||||
var err_msg;
|
||||
Pass.showFailed.connect(function(err) {
|
||||
err_msg = err;
|
||||
});
|
||||
|
||||
Pass.show(Qt.resolvedUrl(data.file));
|
||||
data.spy.wait();
|
||||
if (data.err_msg) {
|
||||
verify(err_msg === data.err_msg, "Should return %1 but return %2".arg(data.err_msg).arg(err_msg));
|
||||
} else {
|
||||
verify(false);
|
||||
}
|
||||
}
|
||||
|
||||
SignalSpy {
|
||||
id: showSucceed
|
||||
|
||||
target: Pass
|
||||
signalName: "showSucceed"
|
||||
}
|
||||
|
||||
SignalSpy {
|
||||
id: showFailed
|
||||
|
||||
target: Pass
|
||||
signalName: "showFailed"
|
||||
}
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user