Merge branch 'master' into TestExportPrivateKeys
This commit is contained in:
57
GpgMELogger.h
Normal file
57
GpgMELogger.h
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* File: GpgMELogger.h
|
||||||
|
* Author: SET - nmset@yandex.com
|
||||||
|
* License : GPL v2
|
||||||
|
* Copyright SET - © 2019
|
||||||
|
*
|
||||||
|
* Created on November 23, 2020, 4:00 PM
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GPGMELOGGER_H
|
||||||
|
#define GPGMELOGGER_H
|
||||||
|
|
||||||
|
#include <Wt/WLogger.h>
|
||||||
|
#include <Wt/WApplication.h>
|
||||||
|
#include <Wt/WEnvironment.h>
|
||||||
|
#include <Wt/WSslCertificate.h>
|
||||||
|
#include <Wt/WSslInfo.h>
|
||||||
|
#include <gpgme++/error.h>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
|
using namespace Wt;
|
||||||
|
|
||||||
|
static std::mutex gs_logGpgMEError;
|
||||||
|
#define LGE(e) LogGpgMEError(e)
|
||||||
|
|
||||||
|
static void LogGpgMEError(const GpgME::Error& e)
|
||||||
|
{
|
||||||
|
if (e.code() == 0)
|
||||||
|
return;
|
||||||
|
std::unique_lock<std::mutex> lock(gs_logGpgMEError);
|
||||||
|
|
||||||
|
const vector<WSslCertificate::DnAttribute> * dnAttr
|
||||||
|
= &(WApplication::instance()->environment().sslInfo()
|
||||||
|
->clientCertificate().subjectDn());
|
||||||
|
WString subjectCommonName = WString::Empty;
|
||||||
|
for (uint i = 0; i < dnAttr->size(); i++)
|
||||||
|
{
|
||||||
|
if (dnAttr->at(i).name() == WSslCertificate::DnAttributeName::CommonName)
|
||||||
|
{
|
||||||
|
subjectCommonName = dnAttr->at(i).value();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const string logfile = WApplication::appRoot() + string("gpgme.log");
|
||||||
|
WLogger logger;
|
||||||
|
logger.setFile(logfile);
|
||||||
|
logger.entry("") << WLogger::timestamp
|
||||||
|
<< WLogger::sep << subjectCommonName
|
||||||
|
<< WLogger::sep << WApplication::instance()->environment().userAgent()
|
||||||
|
<< WLogger::sep << std::to_string(e.code())
|
||||||
|
<< WLogger::sep << e.asString();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* GPGMELOGGER_H */
|
||||||
|
|
||||||
@@ -145,15 +145,19 @@ const Error GpgMEWorker::CertifyKey(const char* fprSigningKey,
|
|||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Error GpgMEWorker::SetExpiryTime(const char * keyFpr,
|
const Error GpgMEWorker::RevokeKeyCertifications(const char* fprSigningKey,
|
||||||
const string& passphrase,
|
const char* fprKeyToSign,
|
||||||
const string& timeString)
|
vector<GpgME::UserID>& userIDsToRevoke,
|
||||||
|
const string& passphrase)
|
||||||
{
|
{
|
||||||
Error e;
|
Error e;
|
||||||
Key k = FindKey(keyFpr, e, true);
|
Key signingKey = FindKey(fprSigningKey, e, true);
|
||||||
if (e.code() != 0)
|
if (e.code() != 0)
|
||||||
return e;
|
return e;
|
||||||
e = m_ctx->addSigningKey(k); // +++
|
e = m_ctx->addSigningKey(signingKey); // +++
|
||||||
|
if (e.code() != 0)
|
||||||
|
return e;
|
||||||
|
Key keyToSign = FindKey(fprKeyToSign, e, false);
|
||||||
if (e.code() != 0)
|
if (e.code() != 0)
|
||||||
return e;
|
return e;
|
||||||
|
|
||||||
@@ -163,15 +167,49 @@ const Error GpgMEWorker::SetExpiryTime(const char * keyFpr,
|
|||||||
m_ppp->SetPassphrase(passphrase);
|
m_ppp->SetPassphrase(passphrase);
|
||||||
m_ctx->setPassphraseProvider(m_ppp);
|
m_ctx->setPassphraseProvider(m_ppp);
|
||||||
|
|
||||||
SetExpiryTimeEditInteractor * interactor
|
e = m_ctx->revokeSignature(keyToSign, signingKey, userIDsToRevoke);
|
||||||
= new SetExpiryTimeEditInteractor(timeString);
|
|
||||||
GpgME::Data d;
|
|
||||||
e = m_ctx->edit(k, std::unique_ptr<SetExpiryTimeEditInteractor> (interactor), d);
|
|
||||||
m_ctx->clearSigningKeys();
|
m_ctx->clearSigningKeys();
|
||||||
|
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Error GpgMEWorker::SetKeyExpiryTime(const char* keyFpr,
|
||||||
|
const char* subkeyFpr,
|
||||||
|
const string& passphrase,
|
||||||
|
ulong expires)
|
||||||
|
{
|
||||||
|
Error e;
|
||||||
|
Key k = FindKey(keyFpr, e, true);
|
||||||
|
if (e.code() != 0)
|
||||||
|
return e;
|
||||||
|
e = m_ctx->addSigningKey(k); // +++
|
||||||
|
if (e.code() != 0)
|
||||||
|
return e;
|
||||||
|
|
||||||
|
vector<GpgME::Subkey> subkey;
|
||||||
|
for (uint i = 0; i < k.subkeys().size(); i++)
|
||||||
|
{
|
||||||
|
GpgME::Subkey sk = k.subkey(i);
|
||||||
|
if (string(sk.fingerprint()) == string(subkeyFpr))
|
||||||
|
{
|
||||||
|
subkey.push_back(sk);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// There should always be at least one subkey (the key itself).
|
||||||
|
|
||||||
|
m_ctx->setPinentryMode(Context::PinentryMode::PinentryLoopback);
|
||||||
|
if (m_ppp == NULL)
|
||||||
|
m_ppp = new LoopbackPassphraseProvider();
|
||||||
|
m_ppp->SetPassphrase(passphrase);
|
||||||
|
m_ctx->setPassphraseProvider(m_ppp);
|
||||||
|
|
||||||
|
// setExpire() allows to expire all subkeys at once. Not implemented here.
|
||||||
|
e = m_ctx->setExpire(k, expires, subkey);
|
||||||
|
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
const Error GpgMEWorker::AddUserID(const char* keyFpr, const string& passphrase,
|
const Error GpgMEWorker::AddUserID(const char* keyFpr, const string& passphrase,
|
||||||
const string& name, const string& email,
|
const string& name, const string& email,
|
||||||
const string& comment)
|
const string& comment)
|
||||||
|
|||||||
@@ -78,13 +78,32 @@ public:
|
|||||||
vector<uint>& userIDsToSign, int options,
|
vector<uint>& userIDsToSign, int options,
|
||||||
const string& passphrase);
|
const string& passphrase);
|
||||||
/**
|
/**
|
||||||
* Set new expiry time of a secret key.
|
* Revoke UserID certifications.
|
||||||
* @param timeString
|
* \n Requires GnuPG >= 2.2.24
|
||||||
|
* @param fprSigningKey
|
||||||
|
* @param fprKeyToSign
|
||||||
|
* @param userIDsToRevoke : vector of ::UserID
|
||||||
|
* @param passphrase
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
const Error SetExpiryTime(const char * keyFpr,
|
const Error RevokeKeyCertifications(const char * fprSigningKey,
|
||||||
|
const char * fprKeyToSign,
|
||||||
|
vector<GpgME::UserID>& userIDsToRevoke,
|
||||||
|
const string& passphrase);
|
||||||
|
/**
|
||||||
|
* Sets the expiry time of a single (sub)key. Requires GPGME >= 1.15.0.
|
||||||
|
* \n If no subkey is found (wrong fpr) or not provided, the expiry time of
|
||||||
|
* key is set instead.
|
||||||
|
* @param keyFpr
|
||||||
|
* @param subkeyFpr
|
||||||
|
* @param passphrase
|
||||||
|
* @param expires : seconds from now. Use 0 for no expiry.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
const Error SetKeyExpiryTime(const char * keyFpr,
|
||||||
|
const char * subkeyFpr,
|
||||||
const string& passphrase,
|
const string& passphrase,
|
||||||
const string& timeString = "0");
|
ulong expires = 63072000);
|
||||||
/**
|
/**
|
||||||
* Adds a user identity to a key.
|
* Adds a user identity to a key.
|
||||||
* \n The email parameter must have a valid email address format here, else
|
* \n The email parameter must have a valid email address format here, else
|
||||||
@@ -225,20 +244,6 @@ public:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class SetExpiryTimeEditInteractor : public GpgSetExpiryTimeEditInteractor
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
SetExpiryTimeEditInteractor(const std::string& timeString = "0")
|
|
||||||
: GpgSetExpiryTimeEditInteractor(timeString)
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
virtual ~SetExpiryTimeEditInteractor()
|
|
||||||
{
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
class AddUserIDEditInteractor : public GpgAddUserIDEditInteractor
|
class AddUserIDEditInteractor : public GpgAddUserIDEditInteractor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|||||||
22
K7Main.cpp
22
K7Main.cpp
@@ -21,6 +21,7 @@
|
|||||||
#include "GpgMECWorker.h"
|
#include "GpgMECWorker.h"
|
||||||
#include "Tools.h"
|
#include "Tools.h"
|
||||||
#include "SensitiveTreeTableNodeText.h"
|
#include "SensitiveTreeTableNodeText.h"
|
||||||
|
#include "GpgMELogger.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
@@ -83,7 +84,9 @@ K7Main::Create()
|
|||||||
WContainerWidget * cwHeader = new WContainerWidget();
|
WContainerWidget * cwHeader = new WContainerWidget();
|
||||||
WHBoxLayout * hblHeader = new WHBoxLayout();
|
WHBoxLayout * hblHeader = new WHBoxLayout();
|
||||||
cwHeader->setLayout(unique_ptr<WHBoxLayout> (hblHeader));
|
cwHeader->setLayout(unique_ptr<WHBoxLayout> (hblHeader));
|
||||||
|
WText * lblTitle =
|
||||||
hblHeader->addWidget(cpp14::make_unique<WText>(_APPNAME_));
|
hblHeader->addWidget(cpp14::make_unique<WText>(_APPNAME_));
|
||||||
|
lblTitle->setStyleClass("title");
|
||||||
// Error messages will go here
|
// Error messages will go here
|
||||||
m_tmwMessage = new TransientMessageWidget();
|
m_tmwMessage = new TransientMessageWidget();
|
||||||
m_tmwMessage->setTextAlignment(AlignmentFlag::Right);
|
m_tmwMessage->setTextAlignment(AlignmentFlag::Right);
|
||||||
@@ -204,6 +207,7 @@ void K7Main::Search()
|
|||||||
{
|
{
|
||||||
privkList.clear();
|
privkList.clear();
|
||||||
m_tmwMessage->SetText(e.asString());
|
m_tmwMessage->SetText(e.asString());
|
||||||
|
LGE(e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@@ -229,6 +233,7 @@ void K7Main::Search()
|
|||||||
{
|
{
|
||||||
pubkList.clear();
|
pubkList.clear();
|
||||||
m_tmwMessage->SetText(e.asString());
|
m_tmwMessage->SetText(e.asString());
|
||||||
|
LGE(e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -293,6 +298,10 @@ void K7Main::DisplayKeys(const vector<GpgME::Key>& kList, const WString& grpLabe
|
|||||||
}
|
}
|
||||||
keyNode->setColumnWidget(2, unique_ptr<WText> (lblOwnerTrust));
|
keyNode->setColumnWidget(2, unique_ptr<WText> (lblOwnerTrust));
|
||||||
TreeTableNodeText * ttntFpr = new TreeTableNodeText(k.primaryFingerprint(), keyNode, 3);
|
TreeTableNodeText * ttntFpr = new TreeTableNodeText(k.primaryFingerprint(), keyNode, 3);
|
||||||
|
if (k.isBad())
|
||||||
|
ttntFpr->addStyleClass("red", true);
|
||||||
|
if (!k.hasSecret() && Tools::KeyHasSecret(k.primaryFingerprint()))
|
||||||
|
ttntFpr->addStyleClass("bold", true);
|
||||||
keyNode->setColumnWidget(3, unique_ptr<TreeTableNodeText> (ttntFpr));
|
keyNode->setColumnWidget(3, unique_ptr<TreeTableNodeText> (ttntFpr));
|
||||||
grpNode->addChildNode(unique_ptr<WTreeTableNode> (keyNode));
|
grpNode->addChildNode(unique_ptr<WTreeTableNode> (keyNode));
|
||||||
}
|
}
|
||||||
@@ -328,6 +337,7 @@ void K7Main::DisplayUids(const WString& fullKeyID, bool secret)
|
|||||||
if (e.code() != 0)
|
if (e.code() != 0)
|
||||||
{
|
{
|
||||||
m_tmwMessage->SetText(e.asString());
|
m_tmwMessage->SetText(e.asString());
|
||||||
|
LGE(e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (m_ttbUids->columnCount() == 1)
|
if (m_ttbUids->columnCount() == 1)
|
||||||
@@ -355,6 +365,8 @@ void K7Main::DisplayUids(const WString& fullKeyID, bool secret)
|
|||||||
lblUidEmail->setToolTip(TR("TTTDoubleCLick"));
|
lblUidEmail->setToolTip(TR("TTTDoubleCLick"));
|
||||||
lblUidEmail->doubleClicked().connect(std::bind(&KeyEdit::OnUidEmailClicked, m_keyEdit, uidNode, WString(k.primaryFingerprint())));
|
lblUidEmail->doubleClicked().connect(std::bind(&KeyEdit::OnUidEmailClicked, m_keyEdit, uidNode, WString(k.primaryFingerprint())));
|
||||||
}
|
}
|
||||||
|
if (uid.isBad())
|
||||||
|
lblUidEmail->setStyleClass("red");
|
||||||
uidNode->setColumnWidget(1, unique_ptr<WText> (lblUidEmail));
|
uidNode->setColumnWidget(1, unique_ptr<WText> (lblUidEmail));
|
||||||
// Show key certify popup on double click
|
// Show key certify popup on double click
|
||||||
WText * lblUidValidity = new WText(UidValidities[uid.validity()]);
|
WText * lblUidValidity = new WText(UidValidities[uid.validity()]);
|
||||||
@@ -376,6 +388,8 @@ void K7Main::DisplayUids(const WString& fullKeyID, bool secret)
|
|||||||
WTreeTableNode * sigNode = new WTreeTableNode(signer);
|
WTreeTableNode * sigNode = new WTreeTableNode(signer);
|
||||||
sigNode->setToolTip(Tools::GetSigStatus(sig));
|
sigNode->setToolTip(Tools::GetSigStatus(sig));
|
||||||
TreeTableNodeText * ttntEmail = new TreeTableNodeText(sig.signerEmail(), sigNode, 1);
|
TreeTableNodeText * ttntEmail = new TreeTableNodeText(sig.signerEmail(), sigNode, 1);
|
||||||
|
if (sig.isBad())
|
||||||
|
ttntEmail->addStyleClass("red", true);
|
||||||
sigNode->setColumnWidget(1, unique_ptr<TreeTableNodeText> (ttntEmail));
|
sigNode->setColumnWidget(1, unique_ptr<TreeTableNodeText> (ttntEmail));
|
||||||
WString exp = TR("Expiration") + _SPACE_ + _COLON_ + _SPACE_;
|
WString exp = TR("Expiration") + _SPACE_ + _COLON_ + _SPACE_;
|
||||||
exp += sig.neverExpires() ? TR("Never") : MakeDateTimeLabel(sig.expirationTime());
|
exp += sig.neverExpires() ? TR("Never") : MakeDateTimeLabel(sig.expirationTime());
|
||||||
@@ -398,6 +412,7 @@ void K7Main::DisplaySubKeys(const WString& fullKeyID, bool secret)
|
|||||||
if (e.code() != 0)
|
if (e.code() != 0)
|
||||||
{
|
{
|
||||||
m_tmwMessage->SetText(e.asString());
|
m_tmwMessage->SetText(e.asString());
|
||||||
|
LGE(e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (m_ttbSubKeys->columnCount() == 1)
|
if (m_ttbSubKeys->columnCount() == 1)
|
||||||
@@ -422,13 +437,18 @@ void K7Main::DisplaySubKeys(const WString& fullKeyID, bool secret)
|
|||||||
WTreeTableNode * skNode = new WTreeTableNode(sk.keyID());
|
WTreeTableNode * skNode = new WTreeTableNode(sk.keyID());
|
||||||
skNode->setToolTip(Tools::GetKeyStatus(k));
|
skNode->setToolTip(Tools::GetKeyStatus(k));
|
||||||
TreeTableNodeText * ttntFpr = new TreeTableNodeText(sk.fingerprint(), skNode, 1);
|
TreeTableNodeText * ttntFpr = new TreeTableNodeText(sk.fingerprint(), skNode, 1);
|
||||||
|
if (sk.isBad())
|
||||||
|
ttntFpr->setStyleClass("red");
|
||||||
skNode->setColumnWidget(1, unique_ptr<TreeTableNodeText> (ttntFpr));
|
skNode->setColumnWidget(1, unique_ptr<TreeTableNodeText> (ttntFpr));
|
||||||
WString exp = sk.neverExpires() ? TR("Never") : MakeDateTimeLabel(sk.expirationTime());
|
WString exp = sk.neverExpires() ? TR("Never") : MakeDateTimeLabel(sk.expirationTime());
|
||||||
WText * lblExpiry = new WText(exp);
|
WText * lblExpiry = new WText(exp);
|
||||||
if (canEditExpiry)
|
if (canEditExpiry)
|
||||||
{
|
{
|
||||||
lblExpiry->setToolTip(TR("TTTDoubleCLick"));
|
lblExpiry->setToolTip(TR("TTTDoubleCLick"));
|
||||||
lblExpiry->doubleClicked().connect(std::bind(&KeyEdit::OnExpiryClicked, m_keyEdit, skNode, WString(k.primaryFingerprint())));
|
lblExpiry->doubleClicked().connect(std::bind(&KeyEdit::OnExpiryClicked,
|
||||||
|
m_keyEdit, skNode,
|
||||||
|
WString(k.primaryFingerprint()),
|
||||||
|
WString(sk.fingerprint())));
|
||||||
}
|
}
|
||||||
skNode->setColumnWidget(2, unique_ptr<WText> (lblExpiry));
|
skNode->setColumnWidget(2, unique_ptr<WText> (lblExpiry));
|
||||||
WString usage = sk.canAuthenticate() ? WString("A") : WString::Empty;
|
WString usage = sk.canAuthenticate() ? WString("A") : WString::Empty;
|
||||||
|
|||||||
83
KeyEdit.cpp
83
KeyEdit.cpp
@@ -13,6 +13,7 @@
|
|||||||
#include <Wt/WStandardItem.h>
|
#include <Wt/WStandardItem.h>
|
||||||
#include "GpgMEWorker.h"
|
#include "GpgMEWorker.h"
|
||||||
#include "Tools.h"
|
#include "Tools.h"
|
||||||
|
#include "GpgMELogger.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
@@ -20,7 +21,7 @@ KeyEdit::KeyEdit(K7Main * owner)
|
|||||||
: WObject()
|
: WObject()
|
||||||
{
|
{
|
||||||
m_owner = owner;
|
m_owner = owner;
|
||||||
m_popupUid = NULL;
|
m_popupCertifyUid = NULL;
|
||||||
m_popupExpiryTime = NULL;
|
m_popupExpiryTime = NULL;
|
||||||
m_popupAddUid = NULL;
|
m_popupAddUid = NULL;
|
||||||
m_targetUidValidityKeyFpr = WString::Empty;
|
m_targetUidValidityKeyFpr = WString::Empty;
|
||||||
@@ -29,7 +30,7 @@ KeyEdit::KeyEdit(K7Main * owner)
|
|||||||
|
|
||||||
KeyEdit::~KeyEdit()
|
KeyEdit::~KeyEdit()
|
||||||
{
|
{
|
||||||
delete m_popupUid;
|
delete m_popupCertifyUid;
|
||||||
}
|
}
|
||||||
|
|
||||||
void KeyEdit::OnOwnerTrustDoubleClicked(WTreeTableNode * keyNode, bool keyHasSecret)
|
void KeyEdit::OnOwnerTrustDoubleClicked(WTreeTableNode * keyNode, bool keyHasSecret)
|
||||||
@@ -91,6 +92,7 @@ void KeyEdit::OnOwnerTrustBlurred(WTreeTableNode* keyNode, bool keyHasSecret)
|
|||||||
{
|
{
|
||||||
lblOwnerTrust->setText(previousTrustLevel);
|
lblOwnerTrust->setText(previousTrustLevel);
|
||||||
m_owner->m_tmwMessage->SetText(TR("OwnerTrustFailure"));
|
m_owner->m_tmwMessage->SetText(TR("OwnerTrustFailure"));
|
||||||
|
LGE(e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_owner->m_tmwMessage->SetText(TR("OwnerTrustSuccess"));
|
m_owner->m_tmwMessage->SetText(TR("OwnerTrustSuccess"));
|
||||||
@@ -130,47 +132,65 @@ void KeyEdit::OnUidValidityClicked(WTreeTableNode* uidNode, vector<WString>& pri
|
|||||||
if (targetKeyFpr != m_targetUidValidityKeyFpr)
|
if (targetKeyFpr != m_targetUidValidityKeyFpr)
|
||||||
{
|
{
|
||||||
bool passwordVisibility = true;
|
bool passwordVisibility = true;
|
||||||
if (m_popupUid)
|
if (m_popupCertifyUid)
|
||||||
passwordVisibility = m_popupUid->IsPasswordVisible();
|
passwordVisibility = m_popupCertifyUid->IsPasswordVisible();
|
||||||
delete m_popupUid;
|
delete m_popupCertifyUid;
|
||||||
WText * lblUidValidity = static_cast<WText*> (uidNode->columnWidget(2));
|
WText * lblUidValidity = static_cast<WText*> (uidNode->columnWidget(2));
|
||||||
m_popupUid = new PopupCertifyUserId(lblUidValidity, m_owner->m_tmwMessage);
|
m_popupCertifyUid = new PopupCertifyUserId(lblUidValidity, m_owner->m_tmwMessage);
|
||||||
m_popupUid->Create(privateKeys, targetKeyFpr);
|
m_popupCertifyUid->Create(privateKeys, targetKeyFpr);
|
||||||
m_popupUid->ShowPassphrase(passwordVisibility);
|
m_popupCertifyUid->ShowPassphrase(passwordVisibility);
|
||||||
m_targetUidValidityKeyFpr = targetKeyFpr;
|
m_targetUidValidityKeyFpr = targetKeyFpr;
|
||||||
m_popupUid->GetCertifyButton()->clicked().connect(this, &KeyEdit::CertifyKey);
|
m_popupCertifyUid->GetCertifyButton()->clicked().connect(this, &KeyEdit::EditUidValidity);
|
||||||
}
|
}
|
||||||
m_popupUid->show();
|
m_popupCertifyUid->show();
|
||||||
}
|
}
|
||||||
|
|
||||||
void KeyEdit::CertifyKey()
|
void KeyEdit::EditUidValidity()
|
||||||
{
|
{
|
||||||
vector<uint>& uidsToSign = m_popupUid->GetUidsToSign();
|
if (!m_popupCertifyUid->Validate())
|
||||||
if (uidsToSign.size() == 0)
|
|
||||||
{
|
{
|
||||||
m_owner->m_tmwMessage->SetText(TR("NoUidSelected"));
|
m_owner->m_tmwMessage->SetText(TR("InvalidInput"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const WString signingKey = m_popupUid->GetSelectedKey();
|
const WString signingKey = m_popupCertifyUid->GetSelectedKey();
|
||||||
const WString keyToSign = m_popupUid->GetKeyToSign();
|
const WString keyToSign = m_popupCertifyUid->GetKeyToSign();
|
||||||
int options = m_popupUid->GetCertifyOptions();
|
|
||||||
GpgMEWorker gpgWorker;
|
GpgMEWorker gpgWorker;
|
||||||
GpgME::Error e = gpgWorker.CertifyKey(signingKey.toUTF8().c_str(),
|
GpgME::Error e;
|
||||||
|
if (m_popupCertifyUid->WhatToDo() == PopupCertifyUserId::CertifyUid)
|
||||||
|
{
|
||||||
|
vector<uint>& uidsToSign = m_popupCertifyUid->GetUidsToSign();
|
||||||
|
int options = m_popupCertifyUid->GetCertifyOptions();
|
||||||
|
e = gpgWorker.CertifyKey(signingKey.toUTF8().c_str(),
|
||||||
keyToSign.toUTF8().c_str(),
|
keyToSign.toUTF8().c_str(),
|
||||||
uidsToSign, options,
|
uidsToSign, options,
|
||||||
m_popupUid->GetPassphrase());
|
m_popupCertifyUid->GetPassphrase());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vector<GpgME::UserID> uidsToRevoke
|
||||||
|
= m_popupCertifyUid->GetUidsToRevokeCertification();
|
||||||
|
e = gpgWorker.RevokeKeyCertifications(signingKey.toUTF8().c_str(),
|
||||||
|
keyToSign.toUTF8().c_str(),
|
||||||
|
uidsToRevoke,
|
||||||
|
m_popupCertifyUid->GetPassphrase());
|
||||||
|
}
|
||||||
if (e.code() != 0)
|
if (e.code() != 0)
|
||||||
{
|
{
|
||||||
m_owner->m_tmwMessage->SetText(TR("CertificationFailure"));
|
m_owner->m_tmwMessage->SetText(e.asString());
|
||||||
m_popupUid->ShowPassphrase(true);
|
m_popupCertifyUid->ShowPassphrase(true);
|
||||||
|
LGE(e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (m_popupCertifyUid->WhatToDo() == PopupCertifyUserId::CertifyUid)
|
||||||
m_owner->m_tmwMessage->SetText(TR("CertificationSuccess"));
|
m_owner->m_tmwMessage->SetText(TR("CertificationSuccess"));
|
||||||
m_popupUid->ShowPassphrase(false);
|
else
|
||||||
|
m_owner->m_tmwMessage->SetText(TR("RevocationSuccess"));
|
||||||
|
m_popupCertifyUid->ShowPassphrase(false);
|
||||||
m_owner->DisplayUids(keyToSign);
|
m_owner->DisplayUids(keyToSign);
|
||||||
}
|
}
|
||||||
|
|
||||||
void KeyEdit::OnExpiryClicked(WTreeTableNode* subkeyNode, const WString& keyFpr)
|
void KeyEdit::OnExpiryClicked(WTreeTableNode* subkeyNode, const WString& keyFpr,
|
||||||
|
const WString& subkeyFpr)
|
||||||
{
|
{
|
||||||
if (keyFpr != m_expiryEditedKeyFpr)
|
if (keyFpr != m_expiryEditedKeyFpr)
|
||||||
{
|
{
|
||||||
@@ -179,21 +199,29 @@ void KeyEdit::OnExpiryClicked(WTreeTableNode* subkeyNode, const WString& keyFpr)
|
|||||||
m_popupExpiryTime = new PopupExpiryTime(lblExpiry, m_owner->m_tmwMessage);
|
m_popupExpiryTime = new PopupExpiryTime(lblExpiry, m_owner->m_tmwMessage);
|
||||||
m_popupExpiryTime->Create(keyFpr);
|
m_popupExpiryTime->Create(keyFpr);
|
||||||
m_expiryEditedKeyFpr = keyFpr;
|
m_expiryEditedKeyFpr = keyFpr;
|
||||||
m_popupExpiryTime->GetApplyButton()->clicked().connect(this, &KeyEdit::SetExpiryTime);
|
m_popupExpiryTime->GetApplyButton()->clicked().connect(this, &KeyEdit::SetKeyExpiryTime);
|
||||||
}
|
}
|
||||||
|
m_popupExpiryTime->SetSubkeyFpr(subkeyFpr);
|
||||||
m_popupExpiryTime->show();
|
m_popupExpiryTime->show();
|
||||||
}
|
}
|
||||||
|
|
||||||
void KeyEdit::SetExpiryTime()
|
void KeyEdit::SetKeyExpiryTime()
|
||||||
{
|
{
|
||||||
GpgMEWorker gpgWorker;
|
GpgMEWorker gpgWorker;
|
||||||
GpgME::Error e = gpgWorker.SetExpiryTime(m_expiryEditedKeyFpr.toUTF8().c_str(),
|
GpgME::Error e;
|
||||||
|
const WString keyFpr = m_popupExpiryTime->GetKeyFpr();
|
||||||
|
WString subkeyFpr = m_popupExpiryTime->GetSubkeyFpr();
|
||||||
|
if (keyFpr == subkeyFpr)
|
||||||
|
subkeyFpr = WString::Empty;
|
||||||
|
e = gpgWorker.SetKeyExpiryTime(keyFpr.toUTF8().c_str(),
|
||||||
|
subkeyFpr.toUTF8().c_str(),
|
||||||
m_popupExpiryTime->GetPassphrase(),
|
m_popupExpiryTime->GetPassphrase(),
|
||||||
m_popupExpiryTime->GetExpiryTime());
|
m_popupExpiryTime->GetExpiry());
|
||||||
if (e.code() != 0)
|
if (e.code() != 0)
|
||||||
{
|
{
|
||||||
m_owner->m_tmwMessage->SetText(TR("SetExpirationTimeFailure"));
|
m_owner->m_tmwMessage->SetText(TR("SetExpirationTimeFailure"));
|
||||||
m_popupExpiryTime->ShowPassphrase(true);
|
m_popupExpiryTime->ShowPassphrase(true);
|
||||||
|
LGE(e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_owner->m_tmwMessage->SetText(TR("SetExpirationTimeSuccess"));
|
m_owner->m_tmwMessage->SetText(TR("SetExpirationTimeSuccess"));
|
||||||
@@ -250,6 +278,7 @@ void KeyEdit::AddOrRevokeUid()
|
|||||||
{
|
{
|
||||||
m_popupAddUid->ShowPassphrase(true);
|
m_popupAddUid->ShowPassphrase(true);
|
||||||
m_owner->m_tmwMessage->SetText(e.asString());
|
m_owner->m_tmwMessage->SetText(e.asString());
|
||||||
|
LGE(e);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ private:
|
|||||||
virtual ~KeyEdit();
|
virtual ~KeyEdit();
|
||||||
|
|
||||||
K7Main * m_owner;
|
K7Main * m_owner;
|
||||||
PopupCertifyUserId * m_popupUid;
|
PopupCertifyUserId * m_popupCertifyUid;
|
||||||
WString m_targetUidValidityKeyFpr;
|
WString m_targetUidValidityKeyFpr;
|
||||||
|
|
||||||
PopupExpiryTime * m_popupExpiryTime;
|
PopupExpiryTime * m_popupExpiryTime;
|
||||||
@@ -57,8 +57,8 @@ private:
|
|||||||
* @param keyHasSecret
|
* @param keyHasSecret
|
||||||
*/
|
*/
|
||||||
void FillOwnerTrustCombo(WComboBox * cmb, bool keyHasSecret);
|
void FillOwnerTrustCombo(WComboBox * cmb, bool keyHasSecret);
|
||||||
void CertifyKey();
|
void EditUidValidity();
|
||||||
void SetExpiryTime();
|
void SetKeyExpiryTime();
|
||||||
void AddOrRevokeUid();
|
void AddOrRevokeUid();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -85,7 +85,8 @@ private:
|
|||||||
* @param subkeyNode
|
* @param subkeyNode
|
||||||
* @param keyFpr
|
* @param keyFpr
|
||||||
*/
|
*/
|
||||||
void OnExpiryClicked(WTreeTableNode * subkeyNode, const WString& keyFpr);
|
void OnExpiryClicked(WTreeTableNode * subkeyNode, const WString& keyFpr,
|
||||||
|
const WString& subkeyFpr);
|
||||||
|
|
||||||
void OnUidEmailClicked(WTreeTableNode * uidNode, const WString& keyFpr);
|
void OnUidEmailClicked(WTreeTableNode * uidNode, const WString& keyFpr);
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#include "Tools.h"
|
#include "Tools.h"
|
||||||
#include <Wt/WLink.h>
|
#include <Wt/WLink.h>
|
||||||
#include <strstream>
|
#include <strstream>
|
||||||
|
#include "GpgMELogger.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
@@ -81,6 +82,7 @@ void KeyringIO::DoImportKey()
|
|||||||
if (e.code() != 0)
|
if (e.code() != 0)
|
||||||
{
|
{
|
||||||
m_tmwMessage->SetText(e.asString());
|
m_tmwMessage->SetText(e.asString());
|
||||||
|
LGE(e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (fpr.empty())
|
if (fpr.empty())
|
||||||
@@ -93,6 +95,7 @@ void KeyringIO::DoImportKey()
|
|||||||
if (e.code() != 0)
|
if (e.code() != 0)
|
||||||
{
|
{
|
||||||
m_tmwMessage->SetText(e.asString());
|
m_tmwMessage->SetText(e.asString());
|
||||||
|
LGE(e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_tmwMessage->SetText(TR("ImportSuccess") + fpr + WString(" - ") + WString(k.userID(0).name()));
|
m_tmwMessage->SetText(TR("ImportSuccess") + fpr + WString(" - ") + WString(k.userID(0).name()));
|
||||||
@@ -111,6 +114,7 @@ bool KeyringIO::CanKeyBeDeleted(const WString& fullKeyID)
|
|||||||
if (e.code() != 0 && e.code() != 16383)
|
if (e.code() != 0 && e.code() != 16383)
|
||||||
{ // 16383 : end of file, when key is not private
|
{ // 16383 : end of file, when key is not private
|
||||||
m_tmwMessage->SetText(e.asString());
|
m_tmwMessage->SetText(e.asString());
|
||||||
|
LGE(e);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// k can now be secret or public
|
// k can now be secret or public
|
||||||
@@ -168,6 +172,7 @@ void KeyringIO::DoDeleteKey()
|
|||||||
if (e.code() != 0)
|
if (e.code() != 0)
|
||||||
{
|
{
|
||||||
m_tmwMessage->SetText(e.asString());
|
m_tmwMessage->SetText(e.asString());
|
||||||
|
LGE(e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Delete the key using the C API
|
// Delete the key using the C API
|
||||||
@@ -234,6 +239,7 @@ void KeyringIO::DoCreateKey()
|
|||||||
if (e.code() != 0)
|
if (e.code() != 0)
|
||||||
{
|
{
|
||||||
m_tmwMessage->SetText(e.asString());
|
m_tmwMessage->SetText(e.asString());
|
||||||
|
LGE(e);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -337,8 +343,6 @@ void ExportKeyStreamResource::handleRequest(const Http::Request& request,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
string buffer;
|
string buffer;
|
||||||
if (!request.continuation()) // Needed for WStreamResource ?
|
|
||||||
{
|
|
||||||
Error e;
|
Error e;
|
||||||
GpgMEWorker gpgw;
|
GpgMEWorker gpgw;
|
||||||
e = m_isSecret
|
e = m_isSecret
|
||||||
@@ -348,10 +352,10 @@ void ExportKeyStreamResource::handleRequest(const Http::Request& request,
|
|||||||
if (e.code() != 0)
|
if (e.code() != 0)
|
||||||
{
|
{
|
||||||
m_tmwMessage->SetText(e.asString());
|
m_tmwMessage->SetText(e.asString());
|
||||||
|
LGE(e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
suggestFileName(m_fpr + WString(".asc"), ContentDisposition::Attachment);
|
suggestFileName(m_fpr + WString(".asc"), ContentDisposition::Attachment);
|
||||||
}
|
|
||||||
|
|
||||||
istrstream bufStream(buffer.c_str());
|
istrstream bufStream(buffer.c_str());
|
||||||
handleRequestPiecewise(request, response, bufStream);
|
handleRequestPiecewise(request, response, bufStream);
|
||||||
|
|||||||
@@ -12,7 +12,10 @@
|
|||||||
#include "Tools.h"
|
#include "Tools.h"
|
||||||
#include <Wt/WStandardItem.h>
|
#include <Wt/WStandardItem.h>
|
||||||
#include <Wt/WStandardItemModel.h>
|
#include <Wt/WStandardItemModel.h>
|
||||||
|
#include <Wt/WRadioButton.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <algorithm>
|
||||||
|
#include "GpgMELogger.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
@@ -26,6 +29,7 @@ PopupCertifyUserId::PopupCertifyUserId(WWidget * anchorWidget, TransientMessageW
|
|||||||
m_cbOptionExportable = NULL;
|
m_cbOptionExportable = NULL;
|
||||||
m_cbOptionNonRevocable = NULL;
|
m_cbOptionNonRevocable = NULL;
|
||||||
// m_cbOptionTrust = NULL;
|
// m_cbOptionTrust = NULL;
|
||||||
|
m_cbConfirm = NULL;
|
||||||
m_lblPassphrase = NULL;
|
m_lblPassphrase = NULL;
|
||||||
m_lePassphrase = NULL;
|
m_lePassphrase = NULL;
|
||||||
m_btnApply = NULL;
|
m_btnApply = NULL;
|
||||||
@@ -63,10 +67,10 @@ void PopupCertifyUserId::Create(vector<WString>& privateKeys,
|
|||||||
m_hblPreferences->addLayout(unique_ptr<WVBoxLayout> (m_vblEmail));
|
m_hblPreferences->addLayout(unique_ptr<WVBoxLayout> (m_vblEmail));
|
||||||
PresentEmail();
|
PresentEmail();
|
||||||
// Column 1
|
// Column 1
|
||||||
|
m_gbOptions = new WGroupBox(TR("Options"));
|
||||||
WVBoxLayout * vblOptions = new WVBoxLayout();
|
WVBoxLayout * vblOptions = new WVBoxLayout();
|
||||||
m_hblPreferences->addLayout(unique_ptr<WVBoxLayout> (vblOptions));
|
m_gbOptions->setLayout(unique_ptr<WVBoxLayout> (vblOptions));
|
||||||
WText * lblOptions = new WText(TR("Options"));
|
m_hblPreferences->addWidget(unique_ptr<WGroupBox> (m_gbOptions));
|
||||||
vblOptions->addWidget(unique_ptr<WText> (lblOptions));
|
|
||||||
m_cbOptionExportable = new WCheckBox(TR("ExportableCertification"));
|
m_cbOptionExportable = new WCheckBox(TR("ExportableCertification"));
|
||||||
m_cbOptionExportable->setToolTip(TR("OneWayHint"));
|
m_cbOptionExportable->setToolTip(TR("OneWayHint"));
|
||||||
vblOptions->addWidget(unique_ptr<WCheckBox> (m_cbOptionExportable));
|
vblOptions->addWidget(unique_ptr<WCheckBox> (m_cbOptionExportable));
|
||||||
@@ -74,7 +78,7 @@ void PopupCertifyUserId::Create(vector<WString>& privateKeys,
|
|||||||
m_cbOptionNonRevocable->setToolTip(TR("OneWayHint"));
|
m_cbOptionNonRevocable->setToolTip(TR("OneWayHint"));
|
||||||
vblOptions->addWidget(unique_ptr<WCheckBox> (m_cbOptionNonRevocable));
|
vblOptions->addWidget(unique_ptr<WCheckBox> (m_cbOptionNonRevocable));
|
||||||
/*m_cbOptionTrust = new WCheckBox(TR("TrustCertification"));
|
/*m_cbOptionTrust = new WCheckBox(TR("TrustCertification"));
|
||||||
vblOptions->addWidget(unique_ptr<WCheckBox> (m_cbOptionTrust));*/
|
gbOptions->addWidget(unique_ptr<WCheckBox> (m_cbOptionTrust));*/
|
||||||
|
|
||||||
WHBoxLayout * hblPassphrase = new WHBoxLayout();
|
WHBoxLayout * hblPassphrase = new WHBoxLayout();
|
||||||
m_lblPassphrase = new WText(TR("Passphrase"));
|
m_lblPassphrase = new WText(TR("Passphrase"));
|
||||||
@@ -84,6 +88,21 @@ void PopupCertifyUserId::Create(vector<WString>& privateKeys,
|
|||||||
hblPassphrase->addWidget(unique_ptr<WLineEdit> (m_lePassphrase), 1);
|
hblPassphrase->addWidget(unique_ptr<WLineEdit> (m_lePassphrase), 1);
|
||||||
vblMain->addLayout(unique_ptr<WHBoxLayout> (hblPassphrase));
|
vblMain->addLayout(unique_ptr<WHBoxLayout> (hblPassphrase));
|
||||||
|
|
||||||
|
WHBoxLayout * hblWhat = new WHBoxLayout();
|
||||||
|
WRadioButton * rbCertifyUid = new WRadioButton(TR("CertifyUid"));
|
||||||
|
hblWhat->addWidget(unique_ptr<WRadioButton> (rbCertifyUid));
|
||||||
|
WRadioButton * rbRevokeCertification =
|
||||||
|
new WRadioButton(TR("RevokeUidCertification"));
|
||||||
|
hblWhat->addWidget(unique_ptr<WRadioButton> (rbRevokeCertification));
|
||||||
|
m_bgWhat = make_shared<WButtonGroup>();
|
||||||
|
m_bgWhat->addButton(rbCertifyUid, What::CertifyUid);
|
||||||
|
m_bgWhat->addButton(rbRevokeCertification, What::RevokeUidCertification);
|
||||||
|
m_bgWhat->setCheckedButton(rbCertifyUid);
|
||||||
|
vblMain->addLayout(unique_ptr<WHBoxLayout> (hblWhat));
|
||||||
|
|
||||||
|
m_cbConfirm = new WCheckBox(TR("Confirm"));
|
||||||
|
vblMain->addWidget(unique_ptr<WCheckBox> (m_cbConfirm));
|
||||||
|
|
||||||
WHBoxLayout * hblButtons = new WHBoxLayout();
|
WHBoxLayout * hblButtons = new WHBoxLayout();
|
||||||
WPushButton * btnClose = new WPushButton(TR("Close"));
|
WPushButton * btnClose = new WPushButton(TR("Close"));
|
||||||
hblButtons->addWidget(unique_ptr<WPushButton> (btnClose));
|
hblButtons->addWidget(unique_ptr<WPushButton> (btnClose));
|
||||||
@@ -99,6 +118,7 @@ void PopupCertifyUserId::Create(vector<WString>& privateKeys,
|
|||||||
m_cbOptionNonRevocable->unChecked().connect(std::bind(&PopupCertifyUserId::OnCertifyOptionUnChecked, this, 2));
|
m_cbOptionNonRevocable->unChecked().connect(std::bind(&PopupCertifyUserId::OnCertifyOptionUnChecked, this, 2));
|
||||||
// m_cbOptionTrust->unChecked().connect(std::bind(&PopupCertifyUserId::OnCertifyOptionUnChecked, this, 4));
|
// m_cbOptionTrust->unChecked().connect(std::bind(&PopupCertifyUserId::OnCertifyOptionUnChecked, this, 4));
|
||||||
btnClose->clicked().connect(this, &WPopupWidget::hide);
|
btnClose->clicked().connect(this, &WPopupWidget::hide);
|
||||||
|
m_bgWhat->checkedChanged().connect(this, &PopupCertifyUserId::OnButtonGroupWhat);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PopupCertifyUserId::FillPrivateKeyComboBox(vector<WString>& privateKeys)
|
void PopupCertifyUserId::FillPrivateKeyComboBox(vector<WString>& privateKeys)
|
||||||
@@ -116,6 +136,7 @@ void PopupCertifyUserId::FillPrivateKeyComboBox(vector<WString>& privateKeys)
|
|||||||
if (e.code() != 0)
|
if (e.code() != 0)
|
||||||
{
|
{
|
||||||
m_tmwMessage->SetText(e.asString());
|
m_tmwMessage->SetText(e.asString());
|
||||||
|
LGE(e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@@ -158,6 +179,7 @@ void PopupCertifyUserId::PresentEmail()
|
|||||||
if (e.code() != 0)
|
if (e.code() != 0)
|
||||||
{
|
{
|
||||||
m_tmwMessage->SetText(e.asString());
|
m_tmwMessage->SetText(e.asString());
|
||||||
|
LGE(e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (lst.size() != 1)
|
if (lst.size() != 1)
|
||||||
@@ -175,8 +197,8 @@ void PopupCertifyUserId::PresentEmail()
|
|||||||
WCheckBox * cbEmail = new WCheckBox(it->email());
|
WCheckBox * cbEmail = new WCheckBox(it->email());
|
||||||
m_vblEmail->addWidget(unique_ptr<WCheckBox> (cbEmail));
|
m_vblEmail->addWidget(unique_ptr<WCheckBox> (cbEmail));
|
||||||
cbEmail->setId(std::to_string(id));
|
cbEmail->setId(std::to_string(id));
|
||||||
cbEmail->checked().connect(std::bind(&PopupCertifyUserId::OnEmailChecked, this, cbEmail));
|
cbEmail->checked().connect(std::bind(&PopupCertifyUserId::OnEmailChecked, this, cbEmail, (*it)));
|
||||||
cbEmail->unChecked().connect(std::bind(&PopupCertifyUserId::OnEmailUnChecked, this, cbEmail));
|
cbEmail->unChecked().connect(std::bind(&PopupCertifyUserId::OnEmailUnChecked, this, cbEmail, (*it)));
|
||||||
id++;
|
id++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -220,25 +242,32 @@ void PopupCertifyUserId::ShowPassphrase(bool show)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PopupCertifyUserId::OnEmailChecked(WCheckBox* cb)
|
void PopupCertifyUserId::OnEmailChecked(WCheckBox* cb, GpgME::UserID& uid)
|
||||||
{
|
{
|
||||||
int id = Tools::ToInt(cb->id());
|
int id = Tools::ToInt(cb->id());
|
||||||
m_uidsToSign.push_back(id);
|
m_uidsToSign.push_back(id);
|
||||||
|
m_uidsToRevokeCertification.push_back(uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PopupCertifyUserId::OnEmailUnChecked(WCheckBox* cb)
|
void PopupCertifyUserId::OnEmailUnChecked(WCheckBox* cb, GpgME::UserID& uid)
|
||||||
{
|
{
|
||||||
// Any tip to locate a known value in a vector without iterating over?
|
|
||||||
const uint id = Tools::ToInt(cb->id());
|
const uint id = Tools::ToInt(cb->id());
|
||||||
vector<uint>::iterator it;
|
vector<uint>::iterator it =
|
||||||
for (it = m_uidsToSign.begin(); it != m_uidsToSign.end(); it++)
|
std::find(m_uidsToSign.begin(), m_uidsToSign.end(), id);
|
||||||
{
|
if (it != m_uidsToSign.end())
|
||||||
if ((*it) == id)
|
|
||||||
{
|
|
||||||
m_uidsToSign.erase(it);
|
m_uidsToSign.erase(it);
|
||||||
return;
|
|
||||||
|
vector<GpgME::UserID>::iterator uit;
|
||||||
|
for (uit = m_uidsToRevokeCertification.begin();
|
||||||
|
uit != m_uidsToRevokeCertification.end(); uit++)
|
||||||
|
{
|
||||||
|
if ((*uit).uidhash() == uid.uidhash())
|
||||||
|
{
|
||||||
|
m_uidsToRevokeCertification.erase(uit);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PopupCertifyUserId::OnCertifyOptionChecked(int id)
|
void PopupCertifyUserId::OnCertifyOptionChecked(int id)
|
||||||
@@ -250,3 +279,27 @@ void PopupCertifyUserId::OnCertifyOptionUnChecked(int id)
|
|||||||
{
|
{
|
||||||
m_certifyOptions -= id;
|
m_certifyOptions -= id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PopupCertifyUserId::OnButtonGroupWhat(WRadioButton* btn)
|
||||||
|
{
|
||||||
|
m_gbOptions->setDisabled(m_bgWhat->checkedId()
|
||||||
|
== What::RevokeUidCertification);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PopupCertifyUserId::Validate() const
|
||||||
|
{
|
||||||
|
if (!m_cbConfirm->isChecked() || m_lePassphrase->text().empty())
|
||||||
|
return false;
|
||||||
|
if (m_bgWhat->checkedId() == What::CertifyUid)
|
||||||
|
{
|
||||||
|
if (m_uidsToSign.size() == 0)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (m_uidsToRevokeCertification.size() == 0)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|||||||
@@ -19,28 +19,32 @@
|
|||||||
#include <Wt/WLineEdit.h>
|
#include <Wt/WLineEdit.h>
|
||||||
#include <Wt/WVBoxLayout.h>
|
#include <Wt/WVBoxLayout.h>
|
||||||
#include <Wt/WHBoxLayout.h>
|
#include <Wt/WHBoxLayout.h>
|
||||||
|
#include <Wt/WGroupBox.h>
|
||||||
|
#include <Wt/WButtonGroup.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <gpgme++/key.h>
|
||||||
#include "TransientMessageWidget.h"
|
#include "TransientMessageWidget.h"
|
||||||
|
|
||||||
using namespace Wt;
|
using namespace Wt;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A popup with required parameters to certify a key :
|
* A popup with required parameters to certify or revoke a key uid :
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>Signer's private keys</li>
|
* <li>Signer's private keys</li>
|
||||||
* <li>Target key user identities (email)</li>
|
* <li>Target key user identities (email)</li>
|
||||||
* <li>Signing options : Exportable and non-revocable</li>
|
* <li>Signing options : Exportable and non-revocable</li>
|
||||||
* <li>Passphrase for selected private key</li>
|
* <li>Passphrase for selected private key</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
* The passphrase is cached by gpg-agent for default 10 mins.
|
* \n For revocation, GnuPG >= 2.2.24 is required.
|
||||||
* \n The popup hides the passphrase widget until a certify op fails.
|
|
||||||
* \n UserID::Validity:: lists many validity levels. How to selectively apply
|
|
||||||
* an arbitrary level ? Before signing, it's 'Unknown'. After signing, it's
|
|
||||||
* always 'Full'.
|
|
||||||
*/
|
*/
|
||||||
class PopupCertifyUserId : public WPopupWidget
|
class PopupCertifyUserId : public WPopupWidget
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
enum What
|
||||||
|
{
|
||||||
|
RevokeUidCertification = 0, CertifyUid
|
||||||
|
};
|
||||||
PopupCertifyUserId(WWidget * anchorWidget, TransientMessageWidget * txtMessage,
|
PopupCertifyUserId(WWidget * anchorWidget, TransientMessageWidget * txtMessage,
|
||||||
const WLength& width = 500);
|
const WLength& width = 500);
|
||||||
virtual ~PopupCertifyUserId();
|
virtual ~PopupCertifyUserId();
|
||||||
@@ -102,6 +106,27 @@ public:
|
|||||||
return m_uidsToSign;
|
return m_uidsToSign;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the certifications to revoke.
|
||||||
|
* \n GPGME >= 1.15.0 is required. It expects
|
||||||
|
* it as a vector of GpgME::UserID, instead of a vector of indices used in
|
||||||
|
* GetUidsToSign().
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
vector<GpgME::UserID>& GetUidsToRevokeCertification()
|
||||||
|
{
|
||||||
|
return m_uidsToRevokeCertification;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Certify selected user identities or revoke certifications.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
const What WhatToDo() const
|
||||||
|
{
|
||||||
|
return (What) m_bgWhat->checkedId();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sum of option values
|
* Sum of option values
|
||||||
* <ul>
|
* <ul>
|
||||||
@@ -124,6 +149,11 @@ public:
|
|||||||
{
|
{
|
||||||
return m_btnApply;
|
return m_btnApply;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Check required parameters are set and confirmed.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
bool Validate() const;
|
||||||
private:
|
private:
|
||||||
TransientMessageWidget * m_tmwMessage;
|
TransientMessageWidget * m_tmwMessage;
|
||||||
WContainerWidget * m_cwMain;
|
WContainerWidget * m_cwMain;
|
||||||
@@ -138,10 +168,14 @@ private:
|
|||||||
// WCheckBox * m_cbOptionTrust; // Always fails
|
// WCheckBox * m_cbOptionTrust; // Always fails
|
||||||
WText * m_lblPassphrase;
|
WText * m_lblPassphrase;
|
||||||
WLineEdit * m_lePassphrase;
|
WLineEdit * m_lePassphrase;
|
||||||
|
WCheckBox * m_cbConfirm;
|
||||||
WPushButton * m_btnApply;
|
WPushButton * m_btnApply;
|
||||||
|
|
||||||
vector<uint> m_uidsToSign;
|
vector<uint> m_uidsToSign;
|
||||||
|
vector<GpgME::UserID> m_uidsToRevokeCertification;
|
||||||
int m_certifyOptions;
|
int m_certifyOptions;
|
||||||
|
WGroupBox * m_gbOptions;
|
||||||
|
shared_ptr<WButtonGroup> m_bgWhat;
|
||||||
/**
|
/**
|
||||||
* Available private fingerprints in a combobox. The selected item is the
|
* Available private fingerprints in a combobox. The selected item is the
|
||||||
* signing key.
|
* signing key.
|
||||||
@@ -154,15 +188,17 @@ private:
|
|||||||
*/
|
*/
|
||||||
void PresentEmail();
|
void PresentEmail();
|
||||||
/**
|
/**
|
||||||
* Add the identity index in a vector.
|
* Add the identity index in a vector for certification.
|
||||||
|
* \n Add the ::UserID in a vector for signature revocation.
|
||||||
* @param cb
|
* @param cb
|
||||||
*/
|
*/
|
||||||
void OnEmailChecked(WCheckBox * cb);
|
void OnEmailChecked(WCheckBox * cb, GpgME::UserID& uid);
|
||||||
/**
|
/**
|
||||||
* Removes the identity index in a vector.
|
* Removes the identity index from a vector for certification.
|
||||||
|
* \n Removes the ::UserID from a vector for signature revocation.
|
||||||
* @param cb
|
* @param cb
|
||||||
*/
|
*/
|
||||||
void OnEmailUnChecked(WCheckBox * cb);
|
void OnEmailUnChecked(WCheckBox * cb, GpgME::UserID& uid);
|
||||||
/**
|
/**
|
||||||
* Adds the option value in m_certifyOptions.
|
* Adds the option value in m_certifyOptions.
|
||||||
* @param id
|
* @param id
|
||||||
@@ -173,6 +209,11 @@ private:
|
|||||||
* @param id
|
* @param id
|
||||||
*/
|
*/
|
||||||
void OnCertifyOptionUnChecked(int id);
|
void OnCertifyOptionUnChecked(int id);
|
||||||
|
/**
|
||||||
|
* Show certification options if certifying, else hide them.
|
||||||
|
* @param btn
|
||||||
|
*/
|
||||||
|
void OnButtonGroupWhat(WRadioButton * btn);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* POPUPCERTIFYUSERID_H */
|
#endif /* POPUPCERTIFYUSERID_H */
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ PopupExpiryTime::PopupExpiryTime(WWidget * anchorWidget, TransientMessageWidget
|
|||||||
m_tmwMessage = txtMessage;
|
m_tmwMessage = txtMessage;
|
||||||
m_cwMain = NULL;
|
m_cwMain = NULL;
|
||||||
m_keyFpr = WString::Empty;
|
m_keyFpr = WString::Empty;
|
||||||
|
m_subkeyFpr = WString::Empty;
|
||||||
/*
|
/*
|
||||||
* Trade-off.
|
* Trade-off.
|
||||||
* When the calendar of WDateEdit is clicked, this popup gets hidden,
|
* When the calendar of WDateEdit is clicked, this popup gets hidden,
|
||||||
@@ -82,6 +83,11 @@ const string PopupExpiryTime::GetExpiryTime() const
|
|||||||
return m_deExpiry->text().toUTF8();
|
return m_deExpiry->text().toUTF8();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ulong PopupExpiryTime::GetExpiry() const
|
||||||
|
{
|
||||||
|
return ((WDate::currentDate().daysTo(m_deExpiry->date())) * 24 * 3600);
|
||||||
|
}
|
||||||
|
|
||||||
void PopupExpiryTime::ShowPassphrase(bool show)
|
void PopupExpiryTime::ShowPassphrase(bool show)
|
||||||
{
|
{
|
||||||
// See comments in PopupCertifyUserId::ShowPassphrase
|
// See comments in PopupCertifyUserId::ShowPassphrase
|
||||||
|
|||||||
@@ -26,6 +26,21 @@ public:
|
|||||||
const WLength& width = 300);
|
const WLength& width = 300);
|
||||||
virtual ~PopupExpiryTime();
|
virtual ~PopupExpiryTime();
|
||||||
void Create(const WString& keyFpr);
|
void Create(const WString& keyFpr);
|
||||||
|
|
||||||
|
const WString GetKeyFpr()
|
||||||
|
{
|
||||||
|
return m_keyFpr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetSubkeyFpr(const WString& subkeyFpr)
|
||||||
|
{
|
||||||
|
m_subkeyFpr = subkeyFpr;
|
||||||
|
}
|
||||||
|
|
||||||
|
const WString GetSubkeyFpr()
|
||||||
|
{
|
||||||
|
return m_subkeyFpr;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Controls visibility of passphrase widgets.
|
* Controls visibility of passphrase widgets.
|
||||||
* \n Need not be always visible as the passphrase is cached by gpg-agent.
|
* \n Need not be always visible as the passphrase is cached by gpg-agent.
|
||||||
@@ -34,6 +49,7 @@ public:
|
|||||||
* @param show
|
* @param show
|
||||||
*/
|
*/
|
||||||
void ShowPassphrase(bool show = true);
|
void ShowPassphrase(bool show = true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to forward the passphrase to the loopback passphrase provider.
|
* Used to forward the passphrase to the loopback passphrase provider.
|
||||||
* @return
|
* @return
|
||||||
@@ -43,9 +59,15 @@ public:
|
|||||||
return m_lePassphrase->text().toUTF8();
|
return m_lePassphrase->text().toUTF8();
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Returns the new expiry date.
|
* Returns the new expiry date, or 0 if date is invalid.
|
||||||
*/
|
*/
|
||||||
const std::string GetExpiryTime() const;
|
const std::string GetExpiryTime() const;
|
||||||
|
/**
|
||||||
|
* Number of seconds from now.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
const ulong GetExpiry() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Caller binds its function here.
|
* Caller binds its function here.
|
||||||
* @return
|
* @return
|
||||||
@@ -63,6 +85,7 @@ private:
|
|||||||
WPushButton * m_btnApply;
|
WPushButton * m_btnApply;
|
||||||
WText * m_lblPassphrase;
|
WText * m_lblPassphrase;
|
||||||
WString m_keyFpr;
|
WString m_keyFpr;
|
||||||
|
WString m_subkeyFpr;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ void TreeTableNodeText::OnClick()
|
|||||||
m_lineEdit->setReadOnly(true);
|
m_lineEdit->setReadOnly(true);
|
||||||
m_lineEdit->blurred().connect(m_lineEdit, &TreeTableNodeLineEdit::OnBlurred);
|
m_lineEdit->blurred().connect(m_lineEdit, &TreeTableNodeLineEdit::OnBlurred);
|
||||||
m_lineEdit->setSelection(0, text().toUTF8().length());
|
m_lineEdit->setSelection(0, text().toUTF8().length());
|
||||||
|
m_lineEdit->HoldSourceWidget(removeFromParent());
|
||||||
m_node->setColumnWidget(m_colIndex, unique_ptr<WLineEdit> (m_lineEdit));
|
m_node->setColumnWidget(m_colIndex, unique_ptr<WLineEdit> (m_lineEdit));
|
||||||
m_lineEdit->setFocus(true); // +++
|
m_lineEdit->setFocus(true); // +++
|
||||||
}
|
}
|
||||||
@@ -78,13 +79,15 @@ void TreeTableNodeLineEdit::Init(WTreeTableNode* node, uint colIndex)
|
|||||||
{
|
{
|
||||||
m_node = node;
|
m_node = node;
|
||||||
m_colIndex = colIndex;
|
m_colIndex = colIndex;
|
||||||
m_text = NULL;
|
|
||||||
clicked().connect(this, &TreeTableNodeLineEdit::OnBlurred);
|
clicked().connect(this, &TreeTableNodeLineEdit::OnBlurred);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TreeTableNodeLineEdit::OnBlurred()
|
void TreeTableNodeLineEdit::OnBlurred()
|
||||||
{
|
{
|
||||||
m_text = new TreeTableNodeText(text(), m_node, m_colIndex);
|
m_node->setColumnWidget(m_colIndex, std::move(m_sourceWidget));
|
||||||
m_text->clicked().connect(m_text, &TreeTableNodeText::OnClick);
|
}
|
||||||
m_node->setColumnWidget(m_colIndex, unique_ptr<TreeTableNodeText> (m_text));
|
|
||||||
|
void TreeTableNodeLineEdit::HoldSourceWidget(std::unique_ptr<WWidget> sourceWidget)
|
||||||
|
{
|
||||||
|
m_sourceWidget.swap(sourceWidget);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,13 +58,19 @@ public:
|
|||||||
WTreeTableNode * node, uint colIndex);
|
WTreeTableNode * node, uint colIndex);
|
||||||
virtual ~TreeTableNodeLineEdit();
|
virtual ~TreeTableNodeLineEdit();
|
||||||
/**
|
/**
|
||||||
* Creates back a TreeTableNodeText replacing this TreeTableNodeLineEdit.
|
* Move back the original TreeTableNodeText replacing this
|
||||||
|
* TreeTableNodeLineEdit.
|
||||||
*/
|
*/
|
||||||
void OnBlurred();
|
void OnBlurred();
|
||||||
|
/**
|
||||||
|
* Keep the original TreeTableNodeText verbatim.
|
||||||
|
* @param text
|
||||||
|
*/
|
||||||
|
void HoldSourceWidget(std::unique_ptr<WWidget> sourceWidget);
|
||||||
private:
|
private:
|
||||||
WTreeTableNode * m_node;
|
WTreeTableNode * m_node;
|
||||||
uint m_colIndex;
|
uint m_colIndex;
|
||||||
TreeTableNodeText * m_text;
|
std::unique_ptr<WWidget> m_sourceWidget;
|
||||||
|
|
||||||
void Init(WTreeTableNode * node, uint colIndex);
|
void Init(WTreeTableNode * node, uint colIndex);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
#include "Tools.h"
|
#include "Tools.h"
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include "GpgMELogger.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
@@ -101,6 +102,7 @@ bool Tools::KeyHasSecret(const WString& fpr)
|
|||||||
GpgME::Key k = gpgw.FindKey(fpr.toUTF8().c_str(), e, true); // Look for a private key
|
GpgME::Key k = gpgw.FindKey(fpr.toUTF8().c_str(), e, true); // Look for a private key
|
||||||
if (e.code() != 0 && e.code() != 16383)
|
if (e.code() != 0 && e.code() != 16383)
|
||||||
{ // 16383 : end of file, when key is not private
|
{ // 16383 : end of file, when key is not private
|
||||||
|
LGE(e);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return (!k.isNull());
|
return (!k.isNull());
|
||||||
|
|||||||
@@ -6,5 +6,15 @@
|
|||||||
* are all 0.
|
* are all 0.
|
||||||
*/
|
*/
|
||||||
div.popup {
|
div.popup {
|
||||||
background-color: lavender;
|
background-color: floralwhite;
|
||||||
|
}
|
||||||
|
div.red {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
div.bold {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
span.title {
|
||||||
|
font-size: 125%;
|
||||||
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -83,8 +83,10 @@
|
|||||||
<message id='NoUidSelected'>No email address is selected</message>
|
<message id='NoUidSelected'>No email address is selected</message>
|
||||||
<message id='Apply'>Apply</message>
|
<message id='Apply'>Apply</message>
|
||||||
<message id='CertificationSuccess'>Key succesfully certified</message>
|
<message id='CertificationSuccess'>Key succesfully certified</message>
|
||||||
<message id='CertificationFailure'>Key certification failed</message>
|
<message id='RevocationSuccess'>Identity certification succesfully revoked</message>
|
||||||
<message id='OneWayHint'>Once set, this option cannot be removed. Use gpg cli for further edit.</message>
|
<message id='OneWayHint'>Once set, this option cannot be removed. Use gpg cli for further edit.</message>
|
||||||
|
<message id='CertifyUid'>Certify identities</message>
|
||||||
|
<message id='RevokeUidCertification'>Revoke certifications</message>
|
||||||
|
|
||||||
<message id='PrepareCopy'>Click to be able to copy next</message>
|
<message id='PrepareCopy'>Click to be able to copy next</message>
|
||||||
|
|
||||||
|
|||||||
@@ -83,8 +83,10 @@
|
|||||||
<message id='NoUidSelected'>Aucun courriel n'est sélectionné</message>
|
<message id='NoUidSelected'>Aucun courriel n'est sélectionné</message>
|
||||||
<message id='Apply'>Appliquer</message>
|
<message id='Apply'>Appliquer</message>
|
||||||
<message id='CertificationSuccess'>Succès de certification de la clé</message>
|
<message id='CertificationSuccess'>Succès de certification de la clé</message>
|
||||||
<message id='CertificationFailure'>Échec de certification de la clé</message>
|
<message id='RevocationSuccess'>Succès de révocation de l'identité</message>
|
||||||
<message id='OneWayHint'>Une fois appliquée, cette option ne pourra plus être enlevée. Utilisez gpg en ligne de commande pour édition ultérieure.</message>
|
<message id='OneWayHint'>Une fois appliquée, cette option ne pourra plus être enlevée. Utilisez gpg en ligne de commande pour édition ultérieure.</message>
|
||||||
|
<message id='CertifyUid'>Certifier les identités</message>
|
||||||
|
<message id='RevokeUidCertification'>Revoquer les certifications</message>
|
||||||
|
|
||||||
<message id='PrepareCopy'>Cliquez pour pouvoir ensuite copier</message>
|
<message id='PrepareCopy'>Cliquez pour pouvoir ensuite copier</message>
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
projectFiles="true">
|
projectFiles="true">
|
||||||
<itemPath>AppConfig.h</itemPath>
|
<itemPath>AppConfig.h</itemPath>
|
||||||
<itemPath>GpgMECWorker.h</itemPath>
|
<itemPath>GpgMECWorker.h</itemPath>
|
||||||
|
<itemPath>GpgMELogger.h</itemPath>
|
||||||
<itemPath>GpgMEWorker.h</itemPath>
|
<itemPath>GpgMEWorker.h</itemPath>
|
||||||
<itemPath>K7Main.h</itemPath>
|
<itemPath>K7Main.h</itemPath>
|
||||||
<itemPath>KeyEdit.h</itemPath>
|
<itemPath>KeyEdit.h</itemPath>
|
||||||
@@ -104,6 +105,8 @@
|
|||||||
</item>
|
</item>
|
||||||
<item path="GpgMECWorker.h" ex="false" tool="3" flavor2="0">
|
<item path="GpgMECWorker.h" ex="false" tool="3" flavor2="0">
|
||||||
</item>
|
</item>
|
||||||
|
<item path="GpgMELogger.h" ex="false" tool="3" flavor2="0">
|
||||||
|
</item>
|
||||||
<item path="GpgMEWorker.cpp" ex="false" tool="1" flavor2="0">
|
<item path="GpgMEWorker.cpp" ex="false" tool="1" flavor2="0">
|
||||||
</item>
|
</item>
|
||||||
<item path="GpgMEWorker.h" ex="false" tool="3" flavor2="0">
|
<item path="GpgMEWorker.h" ex="false" tool="3" flavor2="0">
|
||||||
@@ -224,6 +227,8 @@
|
|||||||
</item>
|
</item>
|
||||||
<item path="GpgMECWorker.h" ex="false" tool="3" flavor2="0">
|
<item path="GpgMECWorker.h" ex="false" tool="3" flavor2="0">
|
||||||
</item>
|
</item>
|
||||||
|
<item path="GpgMELogger.h" ex="false" tool="3" flavor2="0">
|
||||||
|
</item>
|
||||||
<item path="GpgMEWorker.cpp" ex="false" tool="1" flavor2="0">
|
<item path="GpgMEWorker.cpp" ex="false" tool="1" flavor2="0">
|
||||||
</item>
|
</item>
|
||||||
<item path="GpgMEWorker.h" ex="false" tool="3" flavor2="0">
|
<item path="GpgMEWorker.h" ex="false" tool="3" flavor2="0">
|
||||||
@@ -348,6 +353,8 @@
|
|||||||
</item>
|
</item>
|
||||||
<item path="GpgMECWorker.h" ex="false" tool="3" flavor2="0">
|
<item path="GpgMECWorker.h" ex="false" tool="3" flavor2="0">
|
||||||
</item>
|
</item>
|
||||||
|
<item path="GpgMELogger.h" ex="false" tool="3" flavor2="0">
|
||||||
|
</item>
|
||||||
<item path="GpgMEWorker.cpp" ex="false" tool="1" flavor2="0">
|
<item path="GpgMEWorker.cpp" ex="false" tool="1" flavor2="0">
|
||||||
</item>
|
</item>
|
||||||
<item path="GpgMEWorker.h" ex="false" tool="3" flavor2="0">
|
<item path="GpgMEWorker.h" ex="false" tool="3" flavor2="0">
|
||||||
|
|||||||
@@ -13,8 +13,6 @@
|
|||||||
<gdb_interceptlist>
|
<gdb_interceptlist>
|
||||||
<gdbinterceptoptions gdb_all="false" gdb_unhandled="true" gdb_unexpected="true"/>
|
<gdbinterceptoptions gdb_all="false" gdb_unhandled="true" gdb_unexpected="true"/>
|
||||||
</gdb_interceptlist>
|
</gdb_interceptlist>
|
||||||
<gdb_signals>
|
|
||||||
</gdb_signals>
|
|
||||||
<gdb_options>
|
<gdb_options>
|
||||||
<DebugOptions>
|
<DebugOptions>
|
||||||
</DebugOptions>
|
</DebugOptions>
|
||||||
|
|||||||
Reference in New Issue
Block a user