Allow exporting secret keys.
Requests the passphrase with a popup. As from GPGME 1.15.0, the loopback pinentry is functional when exporting secret keys. It works fine when the exact passphrase is provided. If it's a wrong passphrase, GPGME does not generate an ::Error, but the app crashes with 'free(): double free detected in tcache 2'. Hence, this patch cannot be committed to master. Status : dangerous Result : works and works not Reason : a wrong passphrase means a crash
This commit is contained in:
@@ -9,37 +9,6 @@
|
||||
|
||||
#include "GpgMECWorker.h"
|
||||
|
||||
#ifdef DEVTIME
|
||||
|
||||
/**
|
||||
* This callback is never called when exporting private keys.
|
||||
* From gpgme-1.14.0/tests/run-support.h
|
||||
*/
|
||||
gpgme_error_t passphrase_cb(void *opaque, const char *uid_hint, const char *passphrase_info,
|
||||
int last_was_bad, int fd)
|
||||
{
|
||||
int res;
|
||||
char pass[] = "test_pwd\n";
|
||||
int passlen = strlen(pass);
|
||||
int off = 0;
|
||||
|
||||
(void) opaque;
|
||||
(void) uid_hint;
|
||||
(void) passphrase_info;
|
||||
(void) last_was_bad;
|
||||
|
||||
do
|
||||
{
|
||||
res = gpgme_io_write(fd, &pass[off], passlen - off);
|
||||
if (res > 0)
|
||||
off += res;
|
||||
}
|
||||
while (res > 0 && off != passlen);
|
||||
|
||||
return off == passlen ? 0 : gpgme_error_from_errno(errno);
|
||||
}
|
||||
#endif
|
||||
|
||||
GpgMECWorker::GpgMECWorker()
|
||||
{
|
||||
gpgme_error_t c_err = gpgme_new(&c_ctx);
|
||||
@@ -68,66 +37,3 @@ bool GpgMECWorker::DeleteKey(const char * fpr, bool secret, GpgME::Error& e)
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef DEVTIME
|
||||
|
||||
/**
|
||||
* Much code here is obtained from gpgme-1.14.0/tests/run-export.c
|
||||
* @param fpr
|
||||
* @param e
|
||||
* @return
|
||||
*/
|
||||
bool GpgMECWorker::ExportPrivateKey(const char* fpr, GpgME::Error& e)
|
||||
{
|
||||
gpgme_key_t c_key;
|
||||
gpgme_data_t out;
|
||||
gpgme_set_armor(c_ctx, 1);
|
||||
|
||||
gpgme_error_t c_err = gpgme_get_key(c_ctx, fpr, &c_key, true);
|
||||
if (c_key == NULL)
|
||||
{
|
||||
e = GpgME::Error::fromCode(c_err);
|
||||
return false;
|
||||
}
|
||||
|
||||
FILE * kFp = fopen("/tmp/data", "wb");
|
||||
if (kFp == NULL)
|
||||
return false;
|
||||
c_err = gpgme_data_new_from_stream(&out, kFp);
|
||||
if (c_err != 0)
|
||||
{
|
||||
fclose(kFp);
|
||||
e = GpgME::Error::fromCode(c_err);
|
||||
return false;
|
||||
}
|
||||
|
||||
gpgme_key_t aKeys[2];
|
||||
aKeys[0] = c_key;
|
||||
aKeys[1] = NULL;
|
||||
|
||||
c_err = gpgme_set_pinentry_mode(c_ctx, GPGME_PINENTRY_MODE_LOOPBACK);
|
||||
if (c_err != 0)
|
||||
{
|
||||
fclose(kFp);
|
||||
e = GpgME::Error::fromCode(c_err);
|
||||
return false;
|
||||
}
|
||||
gpgme_set_passphrase_cb(c_ctx, passphrase_cb, NULL);
|
||||
|
||||
gpgme_export_mode_t flags = GPGME_EXPORT_MODE_SECRET;
|
||||
c_err = gpgme_op_export_keys(c_ctx, aKeys, flags, out);
|
||||
if (c_err != 0)
|
||||
{
|
||||
fclose(kFp);
|
||||
gpgme_data_release(out);
|
||||
e = GpgME::Error::fromCode(c_err);
|
||||
return false;
|
||||
}
|
||||
fflush(NULL);
|
||||
fclose(kFp);
|
||||
|
||||
gpgme_data_release(out);
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -31,20 +31,6 @@ public:
|
||||
*/
|
||||
bool DeleteKey(const char * fpr, bool secret, GpgME::Error& e);
|
||||
|
||||
#ifdef DEVTIME
|
||||
/**
|
||||
* Status : testing
|
||||
* \n Result : fails to export a private key
|
||||
* \n Reason : passphrase callback is never called
|
||||
* \n With default pinentry mode, the password is requested normally
|
||||
* and the private key is exported. But this can't be done on a web server.
|
||||
* @param fpr
|
||||
* @param e
|
||||
* @return
|
||||
*/
|
||||
bool ExportPrivateKey(const char* fpr, GpgME::Error& e);
|
||||
#endif
|
||||
|
||||
private:
|
||||
gpgme_ctx_t c_ctx;
|
||||
};
|
||||
|
||||
@@ -308,8 +308,6 @@ const Error GpgMEWorker::CreateSubKey(GpgME::Key& k,
|
||||
return e;
|
||||
}
|
||||
|
||||
#ifdef DEVTIME
|
||||
|
||||
const Error GpgMEWorker::ExportPrivateKey(const char * pattern, string& buffer,
|
||||
const string& passphrase)
|
||||
{
|
||||
@@ -324,14 +322,13 @@ const Error GpgMEWorker::ExportPrivateKey(const char * pattern, string& buffer,
|
||||
uint flags = Context::ExportSecret;
|
||||
|
||||
Error e = ctx->exportPublicKeys(pattern, kData, flags);
|
||||
buffer = kData.toString(); // Empty
|
||||
buffer = kData.toString();
|
||||
|
||||
delete ppp;
|
||||
delete ctx;
|
||||
|
||||
return e;
|
||||
}
|
||||
#endif
|
||||
|
||||
const Error GpgMEWorker::ExportPublicKey(const char* pattern, string& buffer)
|
||||
{
|
||||
|
||||
@@ -162,21 +162,14 @@ public:
|
||||
const char * algo,
|
||||
const string& passphrase,
|
||||
ulong expires = 63072000);
|
||||
|
||||
#ifdef DEVTIME
|
||||
/**
|
||||
* Status : testing
|
||||
* \n Result : fails to export a private key
|
||||
* \n Reason : loopback passphrase provider is never called
|
||||
* \n With default pinentry mode, the password is requested normally
|
||||
* and the private key is exported. But this can't be done on a web server.
|
||||
* @param fpr
|
||||
* @param e
|
||||
* Export a secret key.
|
||||
* @param pattern : a key fingerprint
|
||||
* @param buffer : returns data in armor mode
|
||||
* @return
|
||||
*/
|
||||
const Error ExportPrivateKey(const char * pattern, string& buffer,
|
||||
const string& passphrase = "");
|
||||
#endif
|
||||
/**
|
||||
* Export a public key.
|
||||
* @param pattern : a key fingerprint
|
||||
|
||||
@@ -142,7 +142,6 @@ K7Main::Create()
|
||||
vblButtons->addStretch(1);
|
||||
// Everyone can export a key
|
||||
m_btnExport = new WPushButton(TR("Export"));
|
||||
m_btnExport->setToolTip(TR("TTTExport"));
|
||||
m_btnExport->hide();
|
||||
vblButtons->addWidget(unique_ptr<WPushButton> (m_btnExport));
|
||||
if (m_config->CanCreateKeys())
|
||||
@@ -315,6 +314,7 @@ void K7Main::OnKeyAnchorClicked(WAnchor * source)
|
||||
if (m_config->CanDelete()) // m_btnDelete is NULL otherwise
|
||||
m_btnDelete->setHidden(!m_keyringIO->CanKeyBeDeleted(id));
|
||||
|
||||
m_btnExport->show();
|
||||
m_keyringIO->PrepareExport(id, secret);
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ KeyringIO::KeyringIO(K7Main * owner)
|
||||
m_popupUpload = NULL;
|
||||
m_popupDelete = NULL;
|
||||
m_popupCreate = NULL;
|
||||
m_popupExportSecretKey = NULL;
|
||||
m_config = m_owner->m_config;
|
||||
m_tmwMessage = m_owner->m_tmwMessage;
|
||||
m_btnUpload = m_owner->m_btnUpload;
|
||||
@@ -250,18 +251,54 @@ void KeyringIO::DoCreateKey()
|
||||
}
|
||||
}
|
||||
|
||||
void KeyringIO::ShowPopupExportSecretKey(const WString& fpr)
|
||||
{
|
||||
m_popupExportSecretKey = new PopupExportSecretKey(m_btnExport,
|
||||
m_owner->m_tmwMessage);
|
||||
m_popupExportSecretKey->Create();
|
||||
m_popupExportSecretKey->GetPreApplyButton()
|
||||
->clicked().connect(std::bind(&KeyringIO::OnPreExportSecretKey,
|
||||
this, fpr));
|
||||
m_popupExportSecretKey->show();
|
||||
}
|
||||
|
||||
void KeyringIO::PrepareExport(const WString& fpr, bool isSecret)
|
||||
{
|
||||
// K7Main::m_btnExport
|
||||
m_btnExport->setLink(WLink());
|
||||
m_btnExport->clicked().disconnect(m_exportSecretConnection);
|
||||
if (isSecret)
|
||||
{
|
||||
m_exportSecretConnection = m_btnExport->clicked().connect
|
||||
(std::bind(&KeyringIO::ShowPopupExportSecretKey,
|
||||
this, fpr));
|
||||
}
|
||||
else
|
||||
{
|
||||
WLink link;
|
||||
shared_ptr<ExportKeyStreamResource> shResource =
|
||||
make_shared<ExportKeyStreamResource>
|
||||
(fpr, isSecret, "appliation/pgp-keys", m_tmwMessage);
|
||||
link.setResource(shResource);
|
||||
m_btnExport->setLink(link);
|
||||
if (isSecret)
|
||||
m_btnExport->hide();
|
||||
else
|
||||
m_btnExport->show();
|
||||
}
|
||||
// Never reuse when selecting keys.
|
||||
delete m_popupExportSecretKey;
|
||||
m_popupExportSecretKey = NULL;
|
||||
}
|
||||
|
||||
void KeyringIO::OnPreExportSecretKey(const WString& fpr)
|
||||
{
|
||||
// On preExport button of popup
|
||||
WLink link;
|
||||
shared_ptr<ExportKeyStreamResource> shResource =
|
||||
make_shared<ExportKeyStreamResource>
|
||||
(fpr, true, "appliation/pgp-keys", m_tmwMessage);
|
||||
link.setResource(shResource);
|
||||
shResource->SetPassphrase(m_popupExportSecretKey->GetPassphrase());
|
||||
m_popupExportSecretKey->GetApplyButton()->setLink(link);
|
||||
m_popupExportSecretKey->GetApplyButton()->enable();
|
||||
|
||||
}
|
||||
|
||||
ExportKeyStreamResource::ExportKeyStreamResource(const WString& fpr,
|
||||
@@ -271,6 +308,7 @@ ExportKeyStreamResource::ExportKeyStreamResource(const WString& fpr,
|
||||
{
|
||||
m_fpr = fpr;
|
||||
m_isSecret = isSecret;
|
||||
m_passphrase = WString::Empty;
|
||||
m_tmwMessage = tmw;
|
||||
}
|
||||
|
||||
@@ -282,6 +320,7 @@ ExportKeyStreamResource::ExportKeyStreamResource(const WString& fpr,
|
||||
{
|
||||
m_fpr = fpr;
|
||||
m_isSecret = isSecret;
|
||||
m_passphrase = WString::Empty;
|
||||
m_tmwMessage = tmw;
|
||||
}
|
||||
|
||||
@@ -294,20 +333,18 @@ void ExportKeyStreamResource::handleRequest(const Http::Request& request,
|
||||
Http::Response& response)
|
||||
{
|
||||
/*
|
||||
* Private keys cannot be exported with loopback pinentry.
|
||||
* Let's hope it gets better someday.
|
||||
* Private keys can be exported as from GPGME 1.15.0.
|
||||
*/
|
||||
if (m_isSecret)
|
||||
{
|
||||
m_tmwMessage->SetText(TR("TTTExport"));
|
||||
return;
|
||||
}
|
||||
|
||||
string buffer;
|
||||
if (!request.continuation()) // Needed for WStreamResource ?
|
||||
{
|
||||
Error e;
|
||||
GpgMEWorker gpgw;
|
||||
e = gpgw.ExportPublicKey(m_fpr.toUTF8().c_str(), buffer);
|
||||
e = m_isSecret
|
||||
? gpgw.ExportPrivateKey(m_fpr.toUTF8().c_str(), buffer,
|
||||
m_passphrase.toUTF8())
|
||||
: gpgw.ExportPublicKey(m_fpr.toUTF8().c_str(), buffer);
|
||||
if (e.code() != 0)
|
||||
{
|
||||
m_tmwMessage->SetText(e.asString());
|
||||
|
||||
24
KeyringIO.h
24
KeyringIO.h
@@ -16,6 +16,7 @@
|
||||
#include "PopupUploader.h"
|
||||
#include "PopupDeleter.h"
|
||||
#include "PopupCreate.h"
|
||||
#include "PopupExportSecretKey.h"
|
||||
|
||||
using namespace Wt;
|
||||
|
||||
@@ -41,6 +42,7 @@ private:
|
||||
PopupUpload * m_popupUpload;
|
||||
PopupDelete * m_popupDelete;
|
||||
PopupCreate * m_popupCreate;
|
||||
PopupExportSecretKey * m_popupExportSecretKey;
|
||||
|
||||
// Variables from m_owner mapped here.
|
||||
AppConfig * m_config;
|
||||
@@ -52,6 +54,8 @@ private:
|
||||
WPushButton * m_btnExport;
|
||||
WLineEdit * m_leSearch;
|
||||
|
||||
// Used to disconnect m_btnExport from previous slot.
|
||||
Signals::connection m_exportSecretConnection;
|
||||
|
||||
/**
|
||||
* Shows a non-blocking popup to upload a key,
|
||||
@@ -66,6 +70,10 @@ private:
|
||||
* Shows a non-blocking popup to delete a key
|
||||
*/
|
||||
void ShowPopupDelete();
|
||||
/**
|
||||
* Shows a non-blocking popup to export a secret key
|
||||
*/
|
||||
void ShowPopupExportSecretKey(const WString& fpr);
|
||||
/**
|
||||
* All public keys can be deleted.
|
||||
* Private keys can be deleted only if the user
|
||||
@@ -91,8 +99,17 @@ private:
|
||||
* @param spool
|
||||
*/
|
||||
void OnUploadCompleted(const WString& spool);
|
||||
|
||||
/**
|
||||
* If isSecret is true, shows a popup for passphrase input befort exporting.
|
||||
* Else, adds a link with a shared resource to the export button.
|
||||
* @param fpr
|
||||
* @param isSecret
|
||||
*/
|
||||
void PrepareExport(const WString& fpr, bool isSecret);
|
||||
/**
|
||||
* Adds a link with a shared resource to the export button of the popup.
|
||||
*/
|
||||
void OnPreExportSecretKey(const WString& fpr);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -118,10 +135,15 @@ public:
|
||||
*/
|
||||
void handleRequest(const Http::Request& request,
|
||||
Http::Response& response) override;
|
||||
void SetPassphrase(const WString& passphrase)
|
||||
{
|
||||
m_passphrase = passphrase;
|
||||
}
|
||||
|
||||
private:
|
||||
WString m_fpr;
|
||||
bool m_isSecret;
|
||||
WString m_passphrase;
|
||||
TransientMessageWidget * m_tmwMessage;
|
||||
};
|
||||
|
||||
|
||||
58
PopupExportSecretKey.cpp
Normal file
58
PopupExportSecretKey.cpp
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* File: PopupExportSecretKey.cpp
|
||||
* Author: SET - nmset@yandex.com
|
||||
* License : GPL v2
|
||||
* Copyright SET - © 2019
|
||||
*
|
||||
* Created on November 19, 2020, 9:01 PM
|
||||
*/
|
||||
|
||||
#include "PopupExportSecretKey.h"
|
||||
#include <Wt/WVBoxLayout.h>
|
||||
#include <Wt/WHBoxLayout.h>
|
||||
#include "global.h"
|
||||
|
||||
PopupExportSecretKey::PopupExportSecretKey(WWidget * anchorWidget,
|
||||
TransientMessageWidget * txtMessage,
|
||||
const WLength& width)
|
||||
: WPopupWidget(cpp14::make_unique<WContainerWidget>())
|
||||
{
|
||||
m_tmwMessage = txtMessage;
|
||||
m_cwMain = NULL;
|
||||
m_lblPassphrase = NULL;
|
||||
m_lePassphrase = NULL;
|
||||
m_btnPreApply = NULL;
|
||||
m_btnApply = NULL;
|
||||
|
||||
setTransient(true);
|
||||
setAnchorWidget(anchorWidget);
|
||||
setWidth(width);
|
||||
}
|
||||
|
||||
PopupExportSecretKey::~PopupExportSecretKey()
|
||||
{
|
||||
}
|
||||
|
||||
void PopupExportSecretKey::Create()
|
||||
{
|
||||
m_cwMain = static_cast<WContainerWidget*> (implementation());
|
||||
m_cwMain->setStyleClass("popup");
|
||||
|
||||
WVBoxLayout * vblMain = new WVBoxLayout();
|
||||
m_cwMain->setLayout(unique_ptr<WVBoxLayout> (vblMain));
|
||||
WHBoxLayout * hblPassphrase = new WHBoxLayout();
|
||||
m_lblPassphrase = new WText(TR("Passphrase"));
|
||||
hblPassphrase->addWidget(unique_ptr<WText> (m_lblPassphrase));
|
||||
m_lePassphrase = new WLineEdit();
|
||||
m_lePassphrase->setEchoMode(EchoMode::Password);
|
||||
hblPassphrase->addWidget(unique_ptr<WLineEdit> (m_lePassphrase));
|
||||
vblMain->addLayout(unique_ptr<WHBoxLayout> (hblPassphrase));
|
||||
|
||||
m_btnPreApply = new WPushButton(TR("PreExportSecretKey"));
|
||||
vblMain->addWidget(unique_ptr<WPushButton> (m_btnPreApply));
|
||||
m_btnApply = new WPushButton(TR("ExportSecretKey"));
|
||||
m_btnApply->setToolTip(TR("TTTExportSecretKey"));
|
||||
vblMain->addWidget(unique_ptr<WPushButton> (m_btnApply));
|
||||
|
||||
m_lePassphrase->keyPressed().connect(m_btnApply, &WPushButton::disable);
|
||||
}
|
||||
64
PopupExportSecretKey.h
Normal file
64
PopupExportSecretKey.h
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* File: PopupExportSecretKey.h
|
||||
* Author: SET - nmset@yandex.com
|
||||
* License : GPL v2
|
||||
* Copyright SET - © 2019
|
||||
*
|
||||
* Created on November 19, 2020, 9:01 PM
|
||||
*/
|
||||
|
||||
#ifndef POPUPEXPORTSECRETKEY_H
|
||||
#define POPUPEXPORTSECRETKEY_H
|
||||
|
||||
#include <Wt/WPopupWidget.h>
|
||||
#include <Wt/WContainerWidget.h>
|
||||
#include <Wt/WLineEdit.h>
|
||||
#include <Wt/WPushButton.h>
|
||||
#include "TransientMessageWidget.h"
|
||||
|
||||
using namespace Wt;
|
||||
|
||||
class PopupExportSecretKey : public WPopupWidget
|
||||
{
|
||||
public:
|
||||
PopupExportSecretKey(WWidget * anchorWidget,
|
||||
TransientMessageWidget * txtMessage,
|
||||
const WLength& width = 300);
|
||||
virtual ~PopupExportSecretKey();
|
||||
void Create();
|
||||
/**
|
||||
* Used to forward the passphrase to the loopback passphrase provider.
|
||||
* @return
|
||||
*/
|
||||
const string GetPassphrase()
|
||||
{
|
||||
return m_lePassphrase->text().toUTF8();
|
||||
}
|
||||
/**
|
||||
* Caller binds its function here to add a link to the apply button.
|
||||
* @return
|
||||
*/
|
||||
WPushButton* GetPreApplyButton()
|
||||
{
|
||||
return m_btnPreApply;
|
||||
}
|
||||
/**
|
||||
* Expects a link with a shared resource that generates the secret key
|
||||
* and forwards it to the browser.
|
||||
* @return
|
||||
*/
|
||||
WPushButton* GetApplyButton()
|
||||
{
|
||||
return m_btnApply;
|
||||
}
|
||||
private:
|
||||
TransientMessageWidget * m_tmwMessage;
|
||||
WContainerWidget * m_cwMain;
|
||||
WLineEdit * m_lePassphrase;
|
||||
WPushButton * m_btnPreApply;
|
||||
WPushButton * m_btnApply;
|
||||
WText * m_lblPassphrase;
|
||||
};
|
||||
|
||||
#endif /* POPUPEXPORTSECRETKEY_H */
|
||||
|
||||
@@ -131,7 +131,9 @@
|
||||
<message id='CreateSuccess'>Create success : </message>
|
||||
|
||||
<message id='Export'>Export</message>
|
||||
<message id='TTTExport'>Exporting secret keys is technically impossible</message>
|
||||
<message id='PreExportSecretKey'>Prepare download link</message>
|
||||
<message id='ExportSecretKey'>Export secret key</message>
|
||||
<message id='TTTExportSecretKey'>Requires GPGME >= 1.15.0</message>
|
||||
|
||||
<message id='AddUid'>Add an identity</message>
|
||||
<message id='RevokeUid'>Revoke identity</message>
|
||||
|
||||
@@ -131,7 +131,9 @@
|
||||
<message id='CreateSuccess'>Création réussie : </message>
|
||||
|
||||
<message id='Export'>Exporter</message>
|
||||
<message id='TTTExport'>L'export des clés secrètes est techniquement impossible</message>
|
||||
<message id='PreExportSecretKey'>Préparer le téléchargement</message>
|
||||
<message id='ExportSecretKey'>Exporter la secrète</message>
|
||||
<message id='TTTExportSecretKey'>Requiert GPGME >= 1.15.0</message>
|
||||
|
||||
<message id='AddUid'>Ajouter une identité</message>
|
||||
<message id='RevokeUid'>Revoquer une identité</message>
|
||||
|
||||
@@ -47,6 +47,7 @@ OBJECTFILES= \
|
||||
${OBJECTDIR}/PopupCreate.o \
|
||||
${OBJECTDIR}/PopupDeleter.o \
|
||||
${OBJECTDIR}/PopupExpiryTime.o \
|
||||
${OBJECTDIR}/PopupExportSecretKey.o \
|
||||
${OBJECTDIR}/PopupUploader.o \
|
||||
${OBJECTDIR}/SensitiveTreeTableNodeText.o \
|
||||
${OBJECTDIR}/Tools.o \
|
||||
@@ -138,6 +139,11 @@ ${OBJECTDIR}/PopupExpiryTime.o: PopupExpiryTime.cpp
|
||||
${RM} "$@.d"
|
||||
$(COMPILE.cc) -O2 -s -DLARGEFILE_SOURCE=1 -D_FILE_OFFSET_BITS=64 -I/usr/local/Wt/include -I/usr/include/gpgme++ -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/PopupExpiryTime.o PopupExpiryTime.cpp
|
||||
|
||||
${OBJECTDIR}/PopupExportSecretKey.o: PopupExportSecretKey.cpp
|
||||
${MKDIR} -p ${OBJECTDIR}
|
||||
${RM} "$@.d"
|
||||
$(COMPILE.cc) -O2 -s -DLARGEFILE_SOURCE=1 -D_FILE_OFFSET_BITS=64 -I/usr/local/Wt/include -I/usr/include/gpgme++ -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/PopupExportSecretKey.o PopupExportSecretKey.cpp
|
||||
|
||||
${OBJECTDIR}/PopupUploader.o: PopupUploader.cpp
|
||||
${MKDIR} -p ${OBJECTDIR}
|
||||
${RM} "$@.d"
|
||||
|
||||
@@ -47,6 +47,7 @@ OBJECTFILES= \
|
||||
${OBJECTDIR}/PopupCreate.o \
|
||||
${OBJECTDIR}/PopupDeleter.o \
|
||||
${OBJECTDIR}/PopupExpiryTime.o \
|
||||
${OBJECTDIR}/PopupExportSecretKey.o \
|
||||
${OBJECTDIR}/PopupUploader.o \
|
||||
${OBJECTDIR}/SensitiveTreeTableNodeText.o \
|
||||
${OBJECTDIR}/Tools.o \
|
||||
@@ -138,6 +139,11 @@ ${OBJECTDIR}/PopupExpiryTime.o: PopupExpiryTime.cpp
|
||||
${RM} "$@.d"
|
||||
$(COMPILE.cc) -g -DDEVTIME -I/usr/local/Wt-Debug/include -I/usr/include/gpgme++ -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/PopupExpiryTime.o PopupExpiryTime.cpp
|
||||
|
||||
${OBJECTDIR}/PopupExportSecretKey.o: PopupExportSecretKey.cpp
|
||||
${MKDIR} -p ${OBJECTDIR}
|
||||
${RM} "$@.d"
|
||||
$(COMPILE.cc) -g -DDEVTIME -I/usr/local/Wt-Debug/include -I/usr/include/gpgme++ -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/PopupExportSecretKey.o PopupExportSecretKey.cpp
|
||||
|
||||
${OBJECTDIR}/PopupUploader.o: PopupUploader.cpp
|
||||
${MKDIR} -p ${OBJECTDIR}
|
||||
${RM} "$@.d"
|
||||
|
||||
@@ -47,6 +47,7 @@ OBJECTFILES= \
|
||||
${OBJECTDIR}/PopupCreate.o \
|
||||
${OBJECTDIR}/PopupDeleter.o \
|
||||
${OBJECTDIR}/PopupExpiryTime.o \
|
||||
${OBJECTDIR}/PopupExportSecretKey.o \
|
||||
${OBJECTDIR}/PopupUploader.o \
|
||||
${OBJECTDIR}/SensitiveTreeTableNodeText.o \
|
||||
${OBJECTDIR}/Tools.o \
|
||||
@@ -138,6 +139,11 @@ ${OBJECTDIR}/PopupExpiryTime.o: PopupExpiryTime.cpp
|
||||
${RM} "$@.d"
|
||||
$(COMPILE.cc) -O2 -s -I/usr/local/Wt/include -I/usr/include/gpgme++ -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/PopupExpiryTime.o PopupExpiryTime.cpp
|
||||
|
||||
${OBJECTDIR}/PopupExportSecretKey.o: PopupExportSecretKey.cpp
|
||||
${MKDIR} -p ${OBJECTDIR}
|
||||
${RM} "$@.d"
|
||||
$(COMPILE.cc) -O2 -s -I/usr/local/Wt/include -I/usr/include/gpgme++ -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/PopupExportSecretKey.o PopupExportSecretKey.cpp
|
||||
|
||||
${OBJECTDIR}/PopupUploader.o: PopupUploader.cpp
|
||||
${MKDIR} -p ${OBJECTDIR}
|
||||
${RM} "$@.d"
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
<itemPath>PopupCreate.h</itemPath>
|
||||
<itemPath>PopupDeleter.h</itemPath>
|
||||
<itemPath>PopupExpiryTime.h</itemPath>
|
||||
<itemPath>PopupExportSecretKey.h</itemPath>
|
||||
<itemPath>PopupUploader.h</itemPath>
|
||||
<itemPath>SensitiveTreeTableNodeText.h</itemPath>
|
||||
<itemPath>Tools.h</itemPath>
|
||||
@@ -45,6 +46,7 @@
|
||||
<itemPath>PopupCreate.cpp</itemPath>
|
||||
<itemPath>PopupDeleter.cpp</itemPath>
|
||||
<itemPath>PopupExpiryTime.cpp</itemPath>
|
||||
<itemPath>PopupExportSecretKey.cpp</itemPath>
|
||||
<itemPath>PopupUploader.cpp</itemPath>
|
||||
<itemPath>SensitiveTreeTableNodeText.cpp</itemPath>
|
||||
<itemPath>Tools.cpp</itemPath>
|
||||
@@ -142,6 +144,10 @@
|
||||
</item>
|
||||
<item path="PopupExpiryTime.h" ex="false" tool="3" flavor2="0">
|
||||
</item>
|
||||
<item path="PopupExportSecretKey.cpp" ex="false" tool="1" flavor2="0">
|
||||
</item>
|
||||
<item path="PopupExportSecretKey.h" ex="false" tool="3" flavor2="0">
|
||||
</item>
|
||||
<item path="PopupUploader.cpp" ex="false" tool="1" flavor2="0">
|
||||
</item>
|
||||
<item path="PopupUploader.h" ex="false" tool="3" flavor2="0">
|
||||
@@ -258,6 +264,10 @@
|
||||
</item>
|
||||
<item path="PopupExpiryTime.h" ex="false" tool="3" flavor2="0">
|
||||
</item>
|
||||
<item path="PopupExportSecretKey.cpp" ex="false" tool="1" flavor2="0">
|
||||
</item>
|
||||
<item path="PopupExportSecretKey.h" ex="false" tool="3" flavor2="0">
|
||||
</item>
|
||||
<item path="PopupUploader.cpp" ex="false" tool="1" flavor2="0">
|
||||
</item>
|
||||
<item path="PopupUploader.h" ex="false" tool="3" flavor2="0">
|
||||
@@ -378,6 +388,10 @@
|
||||
</item>
|
||||
<item path="PopupExpiryTime.h" ex="false" tool="3" flavor2="0">
|
||||
</item>
|
||||
<item path="PopupExportSecretKey.cpp" ex="false" tool="1" flavor2="0">
|
||||
</item>
|
||||
<item path="PopupExportSecretKey.h" ex="false" tool="3" flavor2="0">
|
||||
</item>
|
||||
<item path="PopupUploader.cpp" ex="false" tool="1" flavor2="0">
|
||||
</item>
|
||||
<item path="PopupUploader.h" ex="false" tool="3" flavor2="0">
|
||||
|
||||
Reference in New Issue
Block a user