1
0
mirror of https://github.com/QRouland/UTPass.git synced 2025-02-11 15:07:16 +00:00

Fix build rnp for arm64

This commit is contained in:
Quentin Rouland 2025-02-03 17:48:30 +01:00
parent b9b038b1ae
commit 93361f9ba5
27 changed files with 365 additions and 147 deletions

3
.gitmodules vendored
View File

@ -1,3 +1,6 @@
[submodule "libs/rnp"] [submodule "libs/rnp"]
path = libs/rnp path = libs/rnp
url = https://github.com/rnpgp/rnp url = https://github.com/rnpgp/rnp
[submodule "libs/botan"]
path = libs/botan
url = https://github.com/randombit/botan

View File

@ -10,12 +10,19 @@ scripts:
dependencies_target: dependencies_target:
- libgit2-dev - libgit2-dev
- libquazip5-dev - libquazip5-dev
- libgpgmepp-dev
- libgpgme-dev
- libjson-c-dev - libjson-c-dev
- gpg
libraries: 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: rnp:
builder: cmake builder: cmake
make_jobs: 2 make_jobs: 2
@ -23,9 +30,8 @@ libraries:
- libbz2-dev - libbz2-dev
- zlib1g-dev - zlib1g-dev
- libjson-c-dev - libjson-c-dev
build_args: [ build_args: -DBUILD_SHARED_LIBS=on -DBUILD_TESTING=off -DCRYPTO_BACKEND=botan
-DCRYPTO_BACKEND=openssl
]
install_lib: install_lib:
- "libgit2.so*" - "libgit2.so*"
@ -35,9 +41,6 @@ install_lib:
- "libhttp_parser.so*" - "libhttp_parser.so*"
- "libssh2.so*" - "libssh2.so*"
- "libquazip5.so*" - "libquazip5.so*"
- "libgpg-error.so.0.28.0" - "librnp.so*"
- "libassuan.so*" - "libbotan-2.so*"
- "libgpgme.so*"
- "libgpgmepp.so*"
- "libqgpgme.so*"

1
libs/botan Submodule

@ -0,0 +1 @@
Subproject commit 935055e839794a076d209c9e9a1e9cd2255aae01

@ -1 +1 @@
Subproject commit c41cef116443d1572118844ecff0292f3ed4e55b Subproject commit 2e249423d617cf91714624a76bfe4ff613b41ac4

View File

@ -6,10 +6,12 @@ set(
plugin.cpp plugin.cpp
pass.cpp pass.cpp
passkeymodel.h passkeymodel.h
passphraseprovider2.h
jobs/rmjob.cpp jobs/rmjob.cpp
jobs/rnpjob.cpp jobs/rnpjob.cpp
jobs/getkeysjob.cpp jobs/getkeysjob.cpp
jobs/importkeyjob.cpp jobs/importkeyjob.cpp
jobs/decryptjob.cpp
) )
set(CMAKE_AUTOMOC ON) set(CMAKE_AUTOMOC ON)
@ -29,37 +31,23 @@ set_target_properties(${PLUGIN} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${PLUGIN})
qt5_use_modules(${PLUGIN} Qml Quick DBus) qt5_use_modules(${PLUGIN} Qml Quick DBus)
set(RNP_INSTALL_DIR "${CMAKE_SOURCE_DIR}/build/${ARCH_TRIPLET}/rnp/install")
set(RNP_BUILD_DIR "${CMAKE_SOURCE_DIR}/build/${ARCH_TRIPLET}/rnp/install")
find_package(OpenSSL REQUIRED) find_package(OpenSSL REQUIRED)
find_package(JSON-C 0.11) find_package(JSON-C 0.11)
INCLUDE_DIRECTORIES(${RNP_BUILD_DIR}/include) INCLUDE_DIRECTORIES(${RNP_INSTALL_DIR}/include)
add_library(rnp STATIC IMPORTED) # add_library(rnp STATIC IMPORTED)
set_property(TARGET rnp PROPERTY IMPORTED_LOCATION "${RNP_BUILD_DIR}/lib/librnp.a") # set_property(TARGET rnp PROPERTY IMPORTED_LOCATION "${RNP_BUILD_DIR}/lib/librnp.a")
add_library(sexpp STATIC IMPORTED) # add_library(sexpp STATIC IMPORTED)
set_property(TARGET sexpp PROPERTY IMPORTED_LOCATION "${RNP_BUILD_DIR}/lib/libsexpp.a") # set_property(TARGET sexpp PROPERTY IMPORTED_LOCATION "${RNP_BUILD_DIR}/lib/libsexpp.a")
add_library(gpgerror SHARED IMPORTED) add_library(rnp SHARED IMPORTED)
set_property(TARGET gpgerror PROPERTY IMPORTED_LOCATION "/usr/lib/${ARCH_TRIPLET}/libgpg-error.so.0.28.0") set_property(TARGET rnp PROPERTY IMPORTED_LOCATION "${RNP_INSTALL_DIR}/lib/librnp.so")
add_library(libassuan SHARED IMPORTED) target_link_libraries(${PLUGIN} rnp OpenSSL::Crypto JSON-C::JSON-C)
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)
set(QT_IMPORTS_DIR "/lib/${ARCH_TRIPLET}") set(QT_IMPORTS_DIR "/lib/${ARCH_TRIPLET}")
install(TARGETS ${PLUGIN} DESTINATION ${QT_IMPORTS_DIR}/${PLUGIN}/) install(TARGETS ${PLUGIN} DESTINATION ${QT_IMPORTS_DIR}/${PLUGIN}/)

View File

@ -1,7 +1,13 @@
#include "decryptjob.h" #include "decryptjob.h"
#include "qdebug.h"
extern "C" {
#include <rnp/rnp.h>
#include <rnp/rnp_err.h>
}
DecryptJob::DecryptJob(QString path, QString keyfile): DecryptJob::DecryptJob(QDir rnp_homedir, QString path):
m_path(path) RnpJob(rnp_homedir),
m_encrypted_file_path(path)
{ {
this->setObjectName("DecryptJob"); this->setObjectName("DecryptJob");
} }
@ -9,7 +15,33 @@ DecryptJob::DecryptJob(QString path, QString keyfile):
void DecryptJob::run() void DecryptJob::run()
{ {
this->load_sec_keyring(); qDebug() << "[DecryptJob] Starting";
rnp_input_from_path(&keyfile, "secring.pgp")); this->load_sec_keyring(NULL);
qFatal("To be implemented !")
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 ";
} }

View File

@ -34,7 +34,7 @@ signals:
* @param encrypted_file_path The path to the encrypted file that was decrypted. * @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. * @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: private:
QString m_encrypted_file_path; /**< The path to the encrypted file that is to be decrypted. */ 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 * 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. * 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. * @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 #endif // DECRYPTJOB_H

View File

@ -32,13 +32,14 @@ void GetKeysJob::run()
QSet<QString> fingerprints = QSet<QString>(); QSet<QString> fingerprints = QSet<QString>();
this->load_full_keyring(&fingerprints); this->load_full_keyring(&fingerprints);
//Get infos keys
auto key_infos = QList<QJsonDocument>(); auto key_infos = QList<QJsonDocument>();
QList<QJsonDocument>::iterator i; QList<QJsonDocument>::iterator i;
for (auto i = fingerprints.begin(), end = fingerprints.end(); i != end; ++i) { for (auto i = fingerprints.begin(), end = fingerprints.end(); i != end; ++i) {
key_infos.append(this->fingerprint_map_key_info(*i)); key_infos.append(this->fingerprint_map_key_info(*i));
} }
//Get all infos keys // Emit result
emit resultSuccess(key_infos); emit resultSuccess(key_infos);
qDebug() << "[GetKeysJob] Finished Successfully "; qDebug() << "[GetKeysJob] Finished Successfully ";
} }

View File

@ -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) 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; rnp_input_t input = NULL;
if (QFileInfo::exists(this->pubringPath())) { if (QFileInfo::exists(this->pubringPath())) {
auto ret = rnp_input_from_path(&input, path.toLocal8Bit().constData()); 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_input_destroy(input);
rnp_buffer_destroy(json); rnp_buffer_destroy(json);
terminateOnError(ret); terminateOnError(ret);
qDebug() << "[RnpJob] keyring loaded successfully"; qDebug() << "[RnpJob] Keyring loaded successfully";
} else { } 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) void RnpJob::load_pub_keyring(QSet<QString> *result_fingerprints = NULL)
{ {
this->load_key_file(result_fingerprints, this->pubringPath(), RNP_LOAD_SAVE_PUBLIC_KEYS); 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) void RnpJob::load_sec_keyring(QSet<QString> *result_fingerprints = NULL)
{ {
this->load_key_file(result_fingerprints, this->secringPath(), RNP_LOAD_SAVE_SECRET_KEYS); 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) void RnpJob::load_full_keyring(QSet<QString> *result_fingerprints = NULL)
{ {
this->load_pub_keyring(result_fingerprints); this->load_pub_keyring(result_fingerprints);
this->load_sec_keyring(result_fingerprints); this->load_sec_keyring(result_fingerprints);
qDebug() << "[RnpJob] full fingerprints" << *result_fingerprints;
} }

View File

@ -153,6 +153,11 @@ public:
* the RNP FFI handle. * the RNP FFI handle.
*/ */
~RnpJob(); ~RnpJob();
void setPassProvider(rnp_password_cb pass_provider_cb) {
rnp_ffi_set_pass_provider(this->m_ffi, pass_provider_cb, NULL);
}
}; };
#endif // RNPJOB_H #endif // RNPJOB_H

View File

@ -2,9 +2,12 @@
#include <QtCore/QStandardPaths> #include <QtCore/QStandardPaths>
#include <QtCore/QDir> #include <QtCore/QDir>
#include "jobs/decryptjob.h"
#include "jobs/getkeysjob.h" #include "jobs/getkeysjob.h"
#include "jobs/importkeyjob.h" #include "jobs/importkeyjob.h"
#include "pass.h" #include "pass.h"
#include "passphraseprovider2.h"
//#include "passphraseprovider2.h"
@ -13,18 +16,19 @@ Pass::Pass():
QStandardPaths::AppDataLocation).append("/.password-store")), QStandardPaths::AppDataLocation).append("/.password-store")),
m_gpg_home (QStandardPaths::writableLocation( m_gpg_home (QStandardPaths::writableLocation(
QStandardPaths::AppDataLocation).append("/.rnp")), QStandardPaths::AppDataLocation).append("/.rnp")),
m_passphrase_provider(&UTPassphraseProvider::get_pass_provider),
m_sem(std::unique_ptr<QSemaphore>(new QSemaphore(1))) m_sem(std::unique_ptr<QSemaphore>(new QSemaphore(1)))
{ {}
}
void Pass::initialize(QObject *window) void Pass::initialize(QObject *window)
{ {
if (!window) {
qWarning("[Pass] Window should be null only for testing");
}
this->initGpgHome(); this->initGpgHome();
this->initPasswordStore(); 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; qInfo() << "[Pass] Password Store is :" << m_password_store;
} }
// bool Pass::show(QUrl url) bool Pass::show(QUrl url)
// { {
// if (!this->m_sem->tryAcquire(1, 500)) { if (!this->m_sem->tryAcquire(1, 500)) {
// return false; qInfo() << "[Pass] A command is already running";
// } return false;
// auto path = url.toLocalFile(); }
// qInfo() << "Pass show " << path; auto job = new DecryptJob(this->m_gpg_home, url.toLocalFile());
// QFileInfo file_info(path); job->setPassProvider(this->m_passphrase_provider);
// this->m_show_filename = file_info.completeBaseName(); QObject::connect(job, &DecryptJob::resultError, this, &Pass::slotShowError);
// return this->m_gpg->decryptFromFile(path); 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) void Pass::slotShowError(rnp_result_t err)
// { {
// qDebug() << "Pass show Result"; qInfo() << "[Pass] Show Failed";
// if (err) { emit showFailed(rnp_result_to_string(err));
// qInfo() << "Pass show Failed"; this->m_sem->release(1);
// emit showFailed(err.asString()); }
// } else if (err.isCanceled()) {
// qInfo() << "Pass show Cancelled"; void Pass::slotShowSucceed(QString encrypted_file_path, QString plain_text)
// emit showCancelled(); {
// } else { qDebug() << "[Pass] Show Succeed";
// qInfo() << "Pass show Succeed"; QFileInfo file_info(encrypted_file_path);
// emit showSucceed(this->m_show_filename, plain_text); emit showSucceed(file_info.completeBaseName(), plain_text);
// } this->m_sem->release(1);
// this->m_show_filename = QString(); }
// this->m_sem->release(1);
// }
// bool Pass::deletePasswordStore() // bool Pass::deletePasswordStore()
// { // {

View File

@ -6,14 +6,10 @@
#include <QObject> #include <QObject>
#include <QUrl> #include <QUrl>
#include <QVariant> #include <QVariant>
#include <gpgme++/context.h>
#include <QSemaphore> #include <QSemaphore>
extern "C" { extern "C" {
#include <rnp/rnp.h> #include <rnp/rnp.h>
} }
using namespace GpgME;
/** /**
* @class Pass * @class Pass
* @brief A class for managing password storage using GPG encryption. * @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 err The error that occurred during the operation.
* @param plain_text The decrypted plain text (password). * @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. * @brief Slot to handle the result of a GPG key deletion operation.
* @param err The error that occurred during the 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. * @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. */ QString m_gpg_home; /**< The path to the gpg home. */
std::unique_ptr<PassKeyringModel> std::unique_ptr<PassKeyringModel>
m_keyring_model; /**< Meta data on the keyring uid, name, secrecy ... of the availble keys. */ 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. */ std::unique_ptr<QSemaphore> m_sem; /**< Semaphore for managing concurrent operations. */
@ -206,14 +204,8 @@ public:
this->m_gpg_home = gpg_home; this->m_gpg_home = gpg_home;
}; };
/**
* @brief Sets the window passphrase provider used for GPG authentication. void set_passphrase_provider(rnp_password_cb passphrase_provider)
*
* PassphraseProvider will be deleted with destructor.
*
* @param The window used by passphrase provider.
*/
void set_passphrase_provider(PassphraseProvider* passphrase_provider)
{ {
this->m_passphrase_provider = passphrase_provider; this->m_passphrase_provider = passphrase_provider;
} }

View File

@ -11,12 +11,6 @@
* @class PassKeyModel * @class PassKeyModel
* @brief A model representing a GPG (GNU Privacy Guard) key. * @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 class PassKeyModel : public QObject
{ {

View 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

View File

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: utpass.qrouland\n" "Project-Id-Version: utpass.qrouland\n"
"Report-Msgid-Bugs-To: \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" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -123,7 +123,7 @@ msgstr ""
#: ../qml/pages/settings/DeleteRepo.qml:56 #: ../qml/pages/settings/DeleteRepo.qml:56
#: ../qml/pages/settings/ImportZip.qml:64 #: ../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 #: ../qml/pages/settings/git/ImportGitClone.qml:56
msgid "Yes" msgid "Yes"
msgstr "" msgstr ""
@ -137,7 +137,7 @@ msgid "Password Store deleted !"
msgstr "" msgstr ""
#: ../qml/pages/settings/DeleteRepo.qml:90 #: ../qml/pages/settings/DeleteRepo.qml:90
#: ../qml/pages/settings/InfoKeys.qml:212 #: ../qml/pages/settings/InfoKeys.qml:209
msgid "Info Keys" msgid "Info Keys"
msgstr "" msgstr ""
@ -171,35 +171,35 @@ msgstr ""
msgid "Zip Password Store Import" msgid "Zip Password Store Import"
msgstr "" msgstr ""
#: ../qml/pages/settings/InfoKeys.qml:50 #: ../qml/pages/settings/InfoKeys.qml:47
msgid "No key found" msgid "No key found"
msgstr "" msgstr ""
#: ../qml/pages/settings/InfoKeys.qml:86 #: ../qml/pages/settings/InfoKeys.qml:83
msgid "Key ID :" msgid "Key ID :"
msgstr "" msgstr ""
#: ../qml/pages/settings/InfoKeys.qml:120 #: ../qml/pages/settings/InfoKeys.qml:117
msgid "Users IDs : " msgid "Users IDs : "
msgstr "" msgstr ""
#: ../qml/pages/settings/InfoKeys.qml:147 #: ../qml/pages/settings/InfoKeys.qml:144
msgid "Delete this key" msgid "Delete this key"
msgstr "" msgstr ""
#: ../qml/pages/settings/InfoKeys.qml:169 #: ../qml/pages/settings/InfoKeys.qml:166
msgid "You're are about to delete<br>%1.<br>Continue ?" msgid "You're are about to delete<br>%1.<br>Continue ?"
msgstr "" msgstr ""
#: ../qml/pages/settings/InfoKeys.qml:183 #: ../qml/pages/settings/InfoKeys.qml:180
msgid "Key removal failed !" msgid "Key removal failed !"
msgstr "" msgstr ""
#: ../qml/pages/settings/InfoKeys.qml:192 #: ../qml/pages/settings/InfoKeys.qml:189
msgid "Key successfully deleted !" msgid "Key successfully deleted !"
msgstr "" msgstr ""
#: ../qml/pages/settings/InfoKeys.qml:204 #: ../qml/pages/settings/InfoKeys.qml:201
msgid "An Error occured getting GPG keys !" msgid "An Error occured getting GPG keys !"
msgstr "" msgstr ""

View File

@ -26,9 +26,6 @@ MainView {
automaticOrientation: true automaticOrientation: true
width: units.gu(45) width: units.gu(45)
height: units.gu(75) height: units.gu(75)
Component.onCompleted: {
myWorker.sendMessage("Hello World !");
}
PageStack { PageStack {
id: pageStack id: pageStack

View File

@ -14,10 +14,7 @@ Page {
Component.onCompleted: { Component.onCompleted: {
Pass.getAllGPGKeysSucceed.connect(function(keys_info) { Pass.getAllGPGKeysSucceed.connect(function(keys_info) {
infoKeysPage.__keys = keys_info; infoKeysPage.__keys = keys_info.keys;
for (var i = 0; i < keys_info.length; ++i) {
console.debug("is secret " + keys_info[i].isSecret);
}
}); });
Pass.getAllGPGKeysFailed.connect(function(message) { Pass.getAllGPGKeysFailed.connect(function(message) {
PopupUtils.open(infoKeysPageGetAllError); PopupUtils.open(infoKeysPageGetAllError);
@ -91,7 +88,7 @@ Page {
width: parent.width width: parent.width
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
text: model.modelData.uid text: model.modelData.keyid
color: theme.palette.normal.backgroundText color: theme.palette.normal.backgroundText
} }
@ -105,9 +102,9 @@ Page {
id: userIdsModel id: userIdsModel
Component.onCompleted: { Component.onCompleted: {
for (var i = 0; i < model.modelData.userIds.length; ++i) { for (var i = 0; i < model.modelData.userids.length; ++i) {
userIdsModel.append({ userIdsModel.append({
"model": model.modelData.userIds[i] "model": model.modelData.userids[i]
}); });
} }
} }

View File

@ -0,0 +1 @@
SomePassword

View File

@ -0,0 +1 @@
„^űÚáÝÎ8m@ă˘z­,fL<66>?ŐŽĄŔjÜö—'ś§!ř[Pfi0 p<C2A0>É0Cď9e;ĽÓţ/¤˘ë<04>;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

View File

View File

@ -3,23 +3,38 @@
#include <QObject> #include <QObject>
#include <gpg-error.h> #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 Q_OBJECT
private:
explicit TesTPassphraseProvider(QObject * parent = nullptr)
{}
public: public:
char *getPassphrase(const char *useridHint, ~TesTPassphraseProvider() = default;
const char *description,
bool previousWasBad, static TesTPassphraseProvider& instance()
bool &canceled) override
{ {
static TesTPassphraseProvider instance;
return instance;
}
TesTPassphraseProvider(TesTPassphraseProvider const &) = delete;
void operator=(TesTPassphraseProvider const &) = delete;
char *ret;
gpgrt_asprintf(&ret, "%s", "utpasspassphrase"); static bool
return ret; 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 #endif

View File

@ -70,7 +70,7 @@ void TestsUtils::copyFolder(QUrl sourceFolderUrl, QUrl destFolderUrl)
QObject *TestsUtils::getTestPassphraseProvider() QObject *TestsUtils::getTestPassphraseProvider()
{ {
return this->m_passphrase_povider.get(); return &TesTPassphraseProvider::instance();
} }

View File

@ -11,9 +11,6 @@ class TestsUtils : public QObject
{ {
Q_OBJECT Q_OBJECT
private:
std::unique_ptr<TesTPassphraseProvider> m_passphrase_povider;
public: public:
TestsUtils(); TestsUtils();
~TestsUtils() override = default; ~TestsUtils() override = default;

View File

@ -9,13 +9,11 @@ PassTestCase {
function init_data() { function init_data() {
return [{ return [{
"spy": getAllGPGKeysSucceed, "spy": getAllGPGKeysSucceed,
"signal": Pass.getAllGPGKeysSucceed,
"err_msg": null, "err_msg": null,
"add_home_gpg_data": false, "add_home_gpg_data": false,
"keys": [] "keys": []
}, { }, {
"spy": getAllGPGKeysSucceed, "spy": getAllGPGKeysSucceed,
"signal": Pass.getAllGPGKeysSucceed,
"err_msg": null, "err_msg": null,
"add_home_gpg_data": true, "add_home_gpg_data": true,
"keys": [{ "keys": [{
@ -32,7 +30,7 @@ PassTestCase {
TestsUtils.copyFolder(Qt.resolvedUrl("../../assets/gpghome"), Qt.resolvedUrl(gpg_home)); TestsUtils.copyFolder(Qt.resolvedUrl("../../assets/gpghome"), Qt.resolvedUrl(gpg_home));
var keys; var keys;
data.signal.connect(function(keys_info) { Pass.getAllGPGKeysSucceed.connect(function(keys_info) {
keys = keys_info; keys = keys_info;
}); });
Pass.getAllGPGKeys(); Pass.getAllGPGKeys();

View File

@ -8,30 +8,27 @@ PassTestCase {
return [{ return [{
"file": Qt.resolvedUrl("../../assets/gpg/test_key.gpg"), "file": Qt.resolvedUrl("../../assets/gpg/test_key.gpg"),
"spy": importGPGKeySucceed, "spy": importGPGKeySucceed,
"signal": Pass.importGPGKeySucceed,
"err_msg": null "err_msg": null
}, { }, {
"file": Qt.resolvedUrl("../../assets/gpg/test_key_do_not_exist.gpg"), "file": Qt.resolvedUrl("../../assets/gpg/test_key_do_not_exist.gpg"),
"spy": importGPGKeyFailed, "spy": importGPGKeyFailed,
"signal": Pass.importGPGKeyFailed,
"err_msg": "Error reading file" "err_msg": "Error reading file"
}, { }, {
"file": Qt.resolvedUrl("../../assets/gpg/test_key_invalid.gpg"), "file": Qt.resolvedUrl("../../assets/gpg/test_key_invalid.gpg"),
"spy": importGPGKeyFailed, "spy": importGPGKeyFailed,
"signal": Pass.importGPGKeyFailed,
"err_msg": "Bad state" "err_msg": "Bad state"
}]; }];
} }
function test_import_key(data) { function test_import_key(data) {
var err_msg; var err_msg;
data.signal.connect(function(message) { Pass.importGPGKeyFailed.connect(function(message) {
err_msg = message; err_msg = message;
}); });
Pass.importGPGKey(data.file); Pass.importGPGKey(data.file);
data.spy.wait(); data.spy.wait();
if (data.err_msg) { 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 { } else {
console.info(Qt.resolvedUrl("%1/pubkeyring.pgp".arg(gpg_home))); 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)); verify(TestsUtils.fileExists(Qt.resolvedUrl("%1/pubring.pgp".arg(gpg_home))), "%1/pubring.pgp should be created".arg(gpg_home));

View 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"
}
}