mirror of
https://github.com/QRouland/UTPass.git
synced 2025-02-11 15:07:16 +00:00
Fix rnp passphrase provider version
This commit is contained in:
parent
93361f9ba5
commit
e56c16f27b
@ -30,7 +30,7 @@ libraries:
|
|||||||
- libbz2-dev
|
- libbz2-dev
|
||||||
- zlib1g-dev
|
- zlib1g-dev
|
||||||
- libjson-c-dev
|
- libjson-c-dev
|
||||||
build_args: -DBUILD_SHARED_LIBS=on -DBUILD_TESTING=off -DCRYPTO_BACKEND=botan
|
build_args: -DBUILD_TESTING=off -DCRYPTO_BACKEND=botan
|
||||||
|
|
||||||
|
|
||||||
install_lib:
|
install_lib:
|
||||||
@ -41,6 +41,4 @@ install_lib:
|
|||||||
- "libhttp_parser.so*"
|
- "libhttp_parser.so*"
|
||||||
- "libssh2.so*"
|
- "libssh2.so*"
|
||||||
- "libquazip5.so*"
|
- "libquazip5.so*"
|
||||||
- "librnp.so*"
|
|
||||||
- "libbotan-2.so*"
|
|
||||||
|
|
||||||
|
@ -5,8 +5,8 @@ set(
|
|||||||
SRC
|
SRC
|
||||||
plugin.cpp
|
plugin.cpp
|
||||||
pass.cpp
|
pass.cpp
|
||||||
passkeymodel.h
|
passkeyringmodel.h
|
||||||
passphraseprovider2.h
|
passphraseprovider.h
|
||||||
jobs/rmjob.cpp
|
jobs/rmjob.cpp
|
||||||
jobs/rnpjob.cpp
|
jobs/rnpjob.cpp
|
||||||
jobs/getkeysjob.cpp
|
jobs/getkeysjob.cpp
|
||||||
@ -32,22 +32,22 @@ qt5_use_modules(${PLUGIN} Qml Quick DBus)
|
|||||||
|
|
||||||
|
|
||||||
set(RNP_INSTALL_DIR "${CMAKE_SOURCE_DIR}/build/${ARCH_TRIPLET}/rnp/install")
|
set(RNP_INSTALL_DIR "${CMAKE_SOURCE_DIR}/build/${ARCH_TRIPLET}/rnp/install")
|
||||||
|
set(BOTAN_INSTALL_DIR "${CMAKE_SOURCE_DIR}/build/${ARCH_TRIPLET}/botan/install")
|
||||||
|
|
||||||
find_package(OpenSSL REQUIRED)
|
|
||||||
find_package(JSON-C 0.11)
|
find_package(JSON-C 0.11)
|
||||||
|
|
||||||
INCLUDE_DIRECTORIES(${RNP_INSTALL_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_INSTALL_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_INSTALL_DIR}/lib/libsexpp.a")
|
||||||
|
|
||||||
add_library(rnp SHARED IMPORTED)
|
add_library(botan STATIC IMPORTED)
|
||||||
set_property(TARGET rnp PROPERTY IMPORTED_LOCATION "${RNP_INSTALL_DIR}/lib/librnp.so")
|
set_property(TARGET botan PROPERTY IMPORTED_LOCATION "${BOTAN_INSTALL_DIR}/lib/libbotan-2.a")
|
||||||
|
|
||||||
target_link_libraries(${PLUGIN} rnp OpenSSL::Crypto JSON-C::JSON-C)
|
target_link_libraries(${PLUGIN} rnp sexpp botan 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}/)
|
||||||
|
@ -6,8 +6,7 @@
|
|||||||
#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 "passphraseprovider.h"
|
||||||
//#include "passphraseprovider2.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -18,12 +17,15 @@ Pass::Pass():
|
|||||||
QStandardPaths::AppDataLocation).append("/.rnp")),
|
QStandardPaths::AppDataLocation).append("/.rnp")),
|
||||||
m_passphrase_provider(&UTPassphraseProvider::get_pass_provider),
|
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)
|
|
||||||
{
|
{
|
||||||
this->initGpgHome();
|
this->initGpgHome();
|
||||||
this->initPasswordStore();
|
this->initPasswordStore();
|
||||||
|
QObject::connect(this, &Pass::responsePassphraseDialogPropagate,
|
||||||
|
&UTPassphraseProvider::instance(), &UTPassphraseProvider::handleResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Pass::initialize(QObject *window)
|
||||||
|
{
|
||||||
if (!window) {
|
if (!window) {
|
||||||
qWarning("[Pass] Window should be null only for testing");
|
qWarning("[Pass] Window should be null only for testing");
|
||||||
} else {
|
} else {
|
||||||
@ -202,8 +204,8 @@ void Pass::slotGetAllGPGKeysSucceed(QList<QJsonDocument> result)
|
|||||||
this->m_sem->release(1);
|
this->m_sem->release(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// void Pass::responsePassphraseDialog(bool cancel, QString passphrase)
|
void Pass::responsePassphraseDialog(bool cancel, QString passphrase)
|
||||||
// {
|
{
|
||||||
// qDebug() << "Propagate responsePassphraseDialog";
|
qDebug() << "Propagate responsePassphraseDialog";
|
||||||
// emit responsePassphraseDialogPropagate(cancel, passphrase);
|
emit responsePassphraseDialogPropagate(cancel, passphrase);
|
||||||
// }
|
}
|
||||||
|
@ -1,15 +1,17 @@
|
|||||||
#ifndef PASS_H
|
#ifndef PASS_H
|
||||||
#define PASS_H
|
#define PASS_H
|
||||||
|
|
||||||
#include "passkeymodel.h"
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
#include <QSemaphore>
|
#include <QSemaphore>
|
||||||
|
#include <memory>
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include <rnp/rnp.h>
|
#include <rnp/rnp.h>
|
||||||
}
|
}
|
||||||
|
#include "passkeyringmodel.h"
|
||||||
/**
|
/**
|
||||||
* @class Pass
|
* @class Pass
|
||||||
* @brief A class for managing password storage using GPG encryption.
|
* @brief A class for managing password storage using GPG encryption.
|
||||||
@ -144,8 +146,7 @@ signals:
|
|||||||
private:
|
private:
|
||||||
QString m_password_store; /**< The path to the password store. */
|
QString m_password_store; /**< The path to the password store. */
|
||||||
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. */
|
|
||||||
rnp_password_cb 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. */
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#ifndef PASSKEYMODEL_H
|
#ifndef PASSKEYRINGMODEL_H
|
||||||
#define PASSKEYMODEL_H
|
#define PASSKEYRINGMODEL_H
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
@ -126,4 +126,4 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif // PASSKEYRINGMODEL_H
|
190
plugins/Pass/passphraseprovider.h
Normal file
190
plugins/Pass/passphraseprovider.h
Normal file
@ -0,0 +1,190 @@
|
|||||||
|
#ifndef UTPASSPHRASEPROVIDER_H
|
||||||
|
#define UTPASSPHRASEPROVIDER_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.
|
||||||
|
*
|
||||||
|
* This class is used to prompt the user for a passphrase through a QML-based dialog. It manages
|
||||||
|
* the passphrase entry process and signals whether the user has provided a passphrase or canceled
|
||||||
|
* the operation.
|
||||||
|
*/
|
||||||
|
class UTPassphraseProvider : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
/**
|
||||||
|
* @brief Slot to handle the user's response from the passphrase dialog.
|
||||||
|
*
|
||||||
|
* This slot is called when the user provides a passphrase or cancels the passphrase entry.
|
||||||
|
* If the user provides a passphrase, it is stored; if the user cancels, a cancellation flag
|
||||||
|
* is set.
|
||||||
|
*
|
||||||
|
* @param canceled Indicates whether the user canceled the passphrase entry.
|
||||||
|
* @param passphrase The passphrase entered by the user (if not canceled).
|
||||||
|
*/
|
||||||
|
void handleResponse(bool canceled, QString passphrase)
|
||||||
|
{
|
||||||
|
qDebug() << "[UTPassphraseProvider] Call handleResponse";
|
||||||
|
if (!canceled) {
|
||||||
|
this->m_canceled = false;
|
||||||
|
this->m_passphrase = passphrase;
|
||||||
|
}
|
||||||
|
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,
|
||||||
|
* causing the event loop waiting for the response to exit.
|
||||||
|
*/
|
||||||
|
void unlockEventLoop();
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* @brief Private constructor for singleton pattern.
|
||||||
|
*
|
||||||
|
* Initializes the passphrase provider with a semaphore to manage access, and a flag to indicate
|
||||||
|
* whether the operation was canceled.
|
||||||
|
*
|
||||||
|
* @param parent Parent QObject (default is nullptr).
|
||||||
|
*/
|
||||||
|
explicit UTPassphraseProvider(QObject * parent = nullptr)
|
||||||
|
: m_sem(std::make_unique<QSemaphore>(1)),
|
||||||
|
m_passphrase(QString::Null()),
|
||||||
|
m_canceled(true)
|
||||||
|
{}
|
||||||
|
|
||||||
|
QObject *m_window; /**< The window object that triggers the QML dialog. */
|
||||||
|
std::unique_ptr<QSemaphore> m_sem; /**< Semaphore for managing access to the passphrase entry process. */
|
||||||
|
QString m_passphrase; /**< The passphrase provided by the user. */
|
||||||
|
bool m_canceled; /**< Flag indicating whether the passphrase operation was canceled. */
|
||||||
|
|
||||||
|
public:
|
||||||
|
~UTPassphraseProvider() = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets the singleton instance of UTPassphraseProvider.
|
||||||
|
*
|
||||||
|
* This method ensures that only one instance of the passphrase provider exists throughout the application.
|
||||||
|
*
|
||||||
|
* @return The singleton instance of UTPassphraseProvider.
|
||||||
|
*/
|
||||||
|
static UTPassphraseProvider& instance()
|
||||||
|
{
|
||||||
|
static UTPassphraseProvider instance;
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
UTPassphraseProvider(UTPassphraseProvider const &) = delete; /**< Prevents copying of the instance. */
|
||||||
|
void operator=(UTPassphraseProvider const &) = delete; /**< Prevents assignment of the instance. */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Callback function to retrieve the passphrase for GPG operations.
|
||||||
|
*
|
||||||
|
* This static method is called by the GPG library when it requires a passphrase for a specific key operation.
|
||||||
|
* It triggers a QML dialog to prompt the user for the passphrase and waits for a response.
|
||||||
|
*
|
||||||
|
* @param ffi The RNP FFI instance.
|
||||||
|
* @param app_ctx provided by application
|
||||||
|
* @param key the key, if any, for which the password is being requested.
|
||||||
|
* Note: this key handle should not be held by the application,
|
||||||
|
* it is destroyed after the callback. It should only be used to
|
||||||
|
* retrieve information like the userids, grip, etc.
|
||||||
|
* @param pgp_context a descriptive string on why the password is being
|
||||||
|
* requested, may have one of the following values:
|
||||||
|
* - "add subkey": add subkey to the encrypted secret key
|
||||||
|
* - "add userid": add userid to the encrypted secret key
|
||||||
|
* - "sign": sign data
|
||||||
|
* - "decrypt": decrypt data using the encrypted secret key
|
||||||
|
* - "unlock": temporary unlock secret key (decrypting its fields), so it may be used
|
||||||
|
* later without need to decrypt
|
||||||
|
* - "protect": encrypt secret key fields
|
||||||
|
* - "unprotect": decrypt secret key fields, leaving those in a raw format
|
||||||
|
* - "decrypt (symmetric)": decrypt data, using the password
|
||||||
|
* - "encrypt (symmetric)": encrypt data, using the password
|
||||||
|
* @param buf to which the callback should write the returned password, NULL terminated.
|
||||||
|
* @param buf_len the size of buf
|
||||||
|
*
|
||||||
|
* @return true if a password was provided, false otherwise
|
||||||
|
*/
|
||||||
|
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() << "[UTPassphraseProvider] Call the getPassphrase";
|
||||||
|
|
||||||
|
if (!UTPassphraseProvider::instance().m_window) {
|
||||||
|
qWarning() << "[UTPassphraseProvider] Aborting : window is not set";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!UTPassphraseProvider::instance().m_sem->tryAcquire(1, 500))
|
||||||
|
{
|
||||||
|
qWarning() << "[UTPassphraseProvider] Aborting : Cannot acquire UTPassphraseProvider semaphore";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
UTPassphraseProvider::instance().m_passphrase = QString::Null();
|
||||||
|
UTPassphraseProvider::instance().m_canceled = true;
|
||||||
|
|
||||||
|
qDebug() << "[UTPassphraseProvider] 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() << "[UTPassphraseProvider] Waiting for response";
|
||||||
|
|
||||||
|
QEventLoop loop;
|
||||||
|
QObject::connect(&UTPassphraseProvider::instance(), &UTPassphraseProvider::unlockEventLoop, &loop, &QEventLoop::quit);
|
||||||
|
loop.exec();
|
||||||
|
|
||||||
|
qDebug() << "[UTPassphraseProvider] Prepare Returns";
|
||||||
|
auto ret = false;
|
||||||
|
if(!UTPassphraseProvider::instance().m_canceled) {
|
||||||
|
strncpy(buf, UTPassphraseProvider::instance().m_passphrase.toLocal8Bit().data(), buf_len);
|
||||||
|
ret = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
qDebug() << "[UTPassphraseProvider] Clean Up";
|
||||||
|
UTPassphraseProvider::instance().m_passphrase = QString::Null();
|
||||||
|
UTPassphraseProvider::instance().m_canceled = true;
|
||||||
|
UTPassphraseProvider::instance().m_sem->release(1);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets the window object that triggers the passphrase dialog.
|
||||||
|
*
|
||||||
|
* This method allows the passphrase provider to know which window should invoke the QML dialog.
|
||||||
|
*
|
||||||
|
* @param window The window object to set.
|
||||||
|
*/
|
||||||
|
void setWindow(QObject* window){
|
||||||
|
this->m_window = window;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // UTPASSPHRASEPROVIDER_H
|
@ -1,132 +0,0 @@
|
|||||||
#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
|
|
@ -1,139 +0,0 @@
|
|||||||
#ifndef UTPASSPHRASEPROVIDER_H
|
|
||||||
#define UTPASSPHRASEPROVIDER_H
|
|
||||||
|
|
||||||
#include <QDebug>
|
|
||||||
#include <gpg-error.h>
|
|
||||||
#include <memory>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <QObject>
|
|
||||||
#include <QQmlProperty>
|
|
||||||
#include <QEventLoop>
|
|
||||||
#include <QSemaphore>
|
|
||||||
#include <gpgme++/interfaces/passphraseprovider.h>
|
|
||||||
|
|
||||||
using namespace GpgME;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @class UTPassphraseProvider
|
|
||||||
* @brief A passphrase provider for GPG operations that interacts with a QML dialog.
|
|
||||||
*
|
|
||||||
* This class implements the `PassphraseProvider` interface from GPGME and is responsible for
|
|
||||||
* obtaining passphrases for GPG operations.
|
|
||||||
*/
|
|
||||||
class UTPassphraseProvider : public QObject, public GpgME::PassphraseProvider
|
|
||||||
{
|
|
||||||
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)
|
|
||||||
gpgrt_asprintf(&m_passphrase, "%s", passphrase.toUtf8().constData());
|
|
||||||
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:
|
|
||||||
std::unique_ptr<QSemaphore> m_sem; /**< Semaphore for managing access. */
|
|
||||||
char *m_passphrase; /**< The passphrase provided by the user. */
|
|
||||||
bool m_canceled; /**< Flag indicating whether the passphrase operation was canceled. */
|
|
||||||
QObject *m_window; /**< The window object that triggers the QML dialog. */
|
|
||||||
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* @brief Constructs a UTPassphraseProvider.
|
|
||||||
*
|
|
||||||
* Initializes the semaphore, passphrase, and canceled flag. Sets the window object that will
|
|
||||||
* trigger the passphrase dialog.
|
|
||||||
*
|
|
||||||
* @param window The QObject representing the window that interacts with QML.
|
|
||||||
*/
|
|
||||||
UTPassphraseProvider(QObject* window)
|
|
||||||
: m_sem(std::make_unique<QSemaphore>(1)),
|
|
||||||
m_passphrase(nullptr),
|
|
||||||
m_canceled(false),
|
|
||||||
m_window(window)
|
|
||||||
{
|
|
||||||
qDebug() << "Initialize UTPassphraseProvider";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Implements the PassphraseProvider's `getPassphrase` method.
|
|
||||||
*
|
|
||||||
* This method is called by GPGME to retrieve the passphrase needed for GPG operations. It triggers
|
|
||||||
* a QML dialog for the user to input their passphrase. The method waits for the response and returns
|
|
||||||
* the passphrase if successful, or null if canceled.
|
|
||||||
*
|
|
||||||
* @param useridHint A hint for the user ID to which the passphrase corresponds.
|
|
||||||
* @param description A description of the passphrase request.
|
|
||||||
* @param previousWasBad Flag indicating whether the previous passphrase attempt was incorrect.
|
|
||||||
* @param canceled Reference to a boolean flag that will be set if the operation is canceled.
|
|
||||||
*
|
|
||||||
* @return The passphrase as a `char *` or `nullptr` if canceled.
|
|
||||||
*/
|
|
||||||
char *getPassphrase(const char *useridHint,
|
|
||||||
const char *description,
|
|
||||||
bool previousWasBad,
|
|
||||||
bool &canceled) Q_DECL_OVERRIDE {
|
|
||||||
qDebug() << "Call the getPassphrase";
|
|
||||||
if (!this->m_sem->tryAcquire(1, 500))
|
|
||||||
{
|
|
||||||
qWarning() << "Cannot acquire UTPassphraseProvider semaphore.";
|
|
||||||
canceled = true;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
this->m_passphrase = nullptr;
|
|
||||||
this->m_canceled = false;
|
|
||||||
|
|
||||||
qDebug() << "Call the QML Dialog Passphrase Provider";
|
|
||||||
QMetaObject::invokeMethod(
|
|
||||||
this->m_window, "callPassphraseDialog",
|
|
||||||
Q_ARG(QVariant, useridHint),
|
|
||||||
Q_ARG(QVariant, description),
|
|
||||||
Q_ARG(QVariant, previousWasBad)
|
|
||||||
);
|
|
||||||
|
|
||||||
qDebug() << "Waiting for response";
|
|
||||||
|
|
||||||
QEventLoop loop;
|
|
||||||
QObject::connect(this, &UTPassphraseProvider::unlockEventLoop, &loop, &QEventLoop::quit);
|
|
||||||
loop.exec();
|
|
||||||
|
|
||||||
qDebug() << "Prepare Returns";
|
|
||||||
char *ret;
|
|
||||||
gpgrt_asprintf(&ret, "%s", m_passphrase);
|
|
||||||
canceled = this->m_canceled;
|
|
||||||
|
|
||||||
qDebug() << "Clean";
|
|
||||||
if (this->m_passphrase)
|
|
||||||
{
|
|
||||||
free(m_passphrase);
|
|
||||||
}
|
|
||||||
this->m_canceled = false;
|
|
||||||
this->m_sem->release(1);
|
|
||||||
return ret;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
@ -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-03 16:44+0000\n"
|
"POT-Creation-Date: 2025-02-03 19:54+0100\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"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user