From 47e78be7e9111142f51fb1c106e04ab8583f5a7a Mon Sep 17 00:00:00 2001 From: SET Date: Fri, 25 Oct 2019 20:16:43 +0200 Subject: [PATCH] Initial commit --- .dep.inc | 5 + .gitignore | 2 + AppConfig.cpp | 147 ++++++ AppConfig.h | 73 +++ GpgMECWorker.cpp | 34 ++ GpgMECWorker.h | 38 ++ GpgMEWorker.cpp | 80 +++ GpgMEWorker.h | 59 +++ K7Main.cpp | 470 ++++++++++++++++++ K7Main.h | 128 +++++ LICENSE | 339 +++++++++++++ Makefile | 128 +++++ PopupDeleter.cpp | 62 +++ PopupDeleter.h | 48 ++ PopupUploader.cpp | 92 ++++ PopupUploader.h | 63 +++ README.md | 37 ++ TransientMessageWidget.cpp | 71 +++ TransientMessageWidget.h | 69 +++ WTAPPROOT/K7/K7.xml | 65 +++ WTAPPROOT/K7/K7_fr.xml | 65 +++ WTAPPROOT/K7/k7config.json | 15 + global.h | 26 + main.cpp | 31 ++ nbproject/Makefile-ARM-Release.mk | 125 +++++ nbproject/Makefile-Debug.mk | 125 +++++ nbproject/Makefile-Release.mk | 125 +++++ nbproject/Makefile-impl.mk | 133 +++++ nbproject/Makefile-variables.mk | 43 ++ nbproject/Package-ARM-Release.bash | 76 +++ nbproject/Package-Debug.bash | 76 +++ nbproject/Package-Release.bash | 76 +++ nbproject/configurations.xml | 268 ++++++++++ nbproject/private/Makefile-variables.mk | 8 + .../private/c_standard_headers_indexer.c | 75 +++ nbproject/private/configurations.xml | 114 +++++ .../private/cpp_standard_headers_indexer.cpp | 135 +++++ nbproject/private/launcher.properties | 42 ++ nbproject/private/private.xml | 15 + nbproject/project.xml | 35 ++ resources | 1 + 41 files changed, 3619 insertions(+) create mode 100644 .dep.inc create mode 100644 .gitignore create mode 100644 AppConfig.cpp create mode 100644 AppConfig.h create mode 100644 GpgMECWorker.cpp create mode 100644 GpgMECWorker.h create mode 100644 GpgMEWorker.cpp create mode 100644 GpgMEWorker.h create mode 100644 K7Main.cpp create mode 100644 K7Main.h create mode 100644 LICENSE create mode 100644 Makefile create mode 100644 PopupDeleter.cpp create mode 100644 PopupDeleter.h create mode 100644 PopupUploader.cpp create mode 100644 PopupUploader.h create mode 100644 README.md create mode 100644 TransientMessageWidget.cpp create mode 100644 TransientMessageWidget.h create mode 100644 WTAPPROOT/K7/K7.xml create mode 100644 WTAPPROOT/K7/K7_fr.xml create mode 100644 WTAPPROOT/K7/k7config.json create mode 100644 global.h create mode 100644 main.cpp create mode 100644 nbproject/Makefile-ARM-Release.mk create mode 100644 nbproject/Makefile-Debug.mk create mode 100644 nbproject/Makefile-Release.mk create mode 100644 nbproject/Makefile-impl.mk create mode 100644 nbproject/Makefile-variables.mk create mode 100644 nbproject/Package-ARM-Release.bash create mode 100644 nbproject/Package-Debug.bash create mode 100644 nbproject/Package-Release.bash create mode 100644 nbproject/configurations.xml create mode 100644 nbproject/private/Makefile-variables.mk create mode 100644 nbproject/private/c_standard_headers_indexer.c create mode 100644 nbproject/private/configurations.xml create mode 100644 nbproject/private/cpp_standard_headers_indexer.cpp create mode 100644 nbproject/private/launcher.properties create mode 100644 nbproject/private/private.xml create mode 100644 nbproject/project.xml create mode 120000 resources diff --git a/.dep.inc b/.dep.inc new file mode 100644 index 0000000..38ba445 --- /dev/null +++ b/.dep.inc @@ -0,0 +1,5 @@ +# This code depends on make tool being used +DEPFILES=$(wildcard $(addsuffix .d, ${OBJECTFILES} ${TESTOBJECTFILES})) +ifneq (${DEPFILES},) +include ${DEPFILES} +endif diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c0f64a8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +dist/ +build/ diff --git a/AppConfig.cpp b/AppConfig.cpp new file mode 100644 index 0000000..690b4c3 --- /dev/null +++ b/AppConfig.cpp @@ -0,0 +1,147 @@ +/* + * File: AppConfig.cpp + * Author: SET - nmset@netcourrier.com + * License : GPL v2 + * Copyright SET - © 2019 + * + * Created on 9 octobre 2019, 20:23 + */ + +#include "AppConfig.h" +#include "global.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + +// Hard coded. File must be in WT_APP_ROOT +#define JSON_CONFIG_FILE "k7config.json" +/* + { + "sCommonName" : { + "UserCommonName1" : { + "canImport" : true, + "canDelete" : true, + "privKeyIds" : [ + "fullKeyId1", + "fullKeyId2" + ] + }, + "UserCommonName2" : { + ... + } + } +} + */ + +AppConfig::AppConfig(WText * notifyWidget) +{ + m_notifyWidget = notifyWidget; +} + +AppConfig::~AppConfig() +{ +} + +bool AppConfig::LoadConfig() +{ + // Read config file + ifstream jsonFile; + const WString f(WApplication::appRoot() + WString(JSON_CONFIG_FILE)); + jsonFile.open(f.toUTF8().c_str()); + if (!jsonFile.is_open()) + { + m_notifyWidget->setText(TR("CantLoadConfig")); + return false; + } + string line; + WString configData; + while (getline(jsonFile, line)) + { + configData += WString(line); + } + jsonFile.close(); + + Json::ParseError pe; + Json::parse(configData.toUTF8(), m_RootObject, pe, false); + if (!string(pe.what()).empty()) + { + // pe.what() dumps all Json data + m_notifyWidget->setText(TR("CantParseJson")); + } + + if (!m_RootObject.contains("sCommonName")) + { + m_notifyWidget->setText(TR("CNObjectMissing")); + return false; + } + m_SubjectCNObject = m_RootObject.get("sCommonName"); + // If the client cert's subject common name is not listed, deny access. + const WString commonName = GetSubjectDnAttribute(WSslCertificate::DnAttributeName::CommonName); + if (!m_SubjectCNObject.contains(commonName.toUTF8())) + { + m_notifyWidget->setText(TR("AccessDenied")); + return false; + } + return true; +} + +bool AppConfig::CanImport() const +{ + const WString commonName = GetSubjectDnAttribute(WSslCertificate::DnAttributeName::CommonName); + if (!m_SubjectCNObject.contains(commonName.toUTF8())) // Should not happen, see above + return false; + Json::Object cnObject = m_SubjectCNObject.get(commonName.toUTF8()); + if (!cnObject.contains("canImport")) + return false; + return cnObject.get("canImport"); +} + +bool AppConfig::CanDelete() const +{ + const WString commonName = GetSubjectDnAttribute(WSslCertificate::DnAttributeName::CommonName); + if (!m_SubjectCNObject.contains(commonName.toUTF8())) + return false; + Json::Object cnObject = m_SubjectCNObject.get(commonName.toUTF8()); + if (!cnObject.contains("canDelete")) + return false; + return cnObject.get("canDelete"); +} + +vector AppConfig::PrivateKeyIds() const +{ + // List private key identifiers. + vector pKeyIds; + const WString commonName = GetSubjectDnAttribute(WSslCertificate::DnAttributeName::CommonName); + if (!m_SubjectCNObject.contains(commonName.toUTF8())) + return pKeyIds; + Json::Object cnObject = m_SubjectCNObject.get(commonName.toUTF8()); + if (!cnObject.contains("privKeyIds")) + return pKeyIds; + Json::Array aKeyId = cnObject.get("privKeyIds"); + for (uint i = 0; i < aKeyId.size(); i++) + { + pKeyIds.push_back(aKeyId.at(i)); + } + return pKeyIds; +} + +const WString AppConfig::GetSubjectDnAttribute(const WSslCertificate::DnAttributeName& attrName) const +{ + // Get an X509 client certificate attribute value + const vector * dnAttr + = &(WApplication::instance()->environment().sslInfo()->clientCertificate().subjectDn()); + for (uint i = 0; i < dnAttr->size(); i++) + { + if (dnAttr->at(i).name() == attrName) + return dnAttr->at(i).value(); + } + return WString::Empty; +} \ No newline at end of file diff --git a/AppConfig.h b/AppConfig.h new file mode 100644 index 0000000..cd8c516 --- /dev/null +++ b/AppConfig.h @@ -0,0 +1,73 @@ +/* + * File: AppConfig.h + * Author: SET - nmset@netcourrier.com + * License : GPL v2 + * Copyright SET - © 2019 + * + * Created on 9 octobre 2019, 20:23 + */ + +#ifndef APPCONFIG_H +#define APPCONFIG_H + +#include +#include +#include +#include +#include + +using namespace Wt; +using namespace std; + +/** + * Json configuration file reader. + */ +class AppConfig { +public: + AppConfig(WText * notifyWidget); + virtual ~AppConfig(); + /** + * Must be called by app. No autoloading of config file. + * @return + */ + bool LoadConfig(); + /** + * Can the user import keys ? + * @return + */ + bool CanImport() const; + /** + * Can the user delete keys ? N.B. : he may delete private keys + * only if he manages these keys. + * @return + */ + bool CanDelete() const; + /** + * List of full private key identifiers. The user may delete these private keys. + * Must be full keyid, short keyid or fingerprint. + * @return + */ + vector PrivateKeyIds() const; +private: + /** + * To display error messages + */ + WText * m_notifyWidget; + /** + * Root object of the config file + */ + Json::Object m_RootObject; + /** + * User object, identified by the Subject Common Name of the X509 client certificate. + */ + Json::Object m_SubjectCNObject; + /** + * Get an X509 client certificate attribute value + * @param attrName + * @return + */ + const WString GetSubjectDnAttribute(const WSslCertificate::DnAttributeName& attrName) const; +}; + +#endif /* APPCONFIG_H */ + diff --git a/GpgMECWorker.cpp b/GpgMECWorker.cpp new file mode 100644 index 0000000..daa86ee --- /dev/null +++ b/GpgMECWorker.cpp @@ -0,0 +1,34 @@ +/* + * File: GpgMECWorker.cpp + * Author: SET - nmset@netcourrier.com + * License : LGPL v2.1 + * Copyright SET - © 2019 + * + * Created on 14 octobre 2019, 15:22 + */ + +#include "GpgMECWorker.h" + +GpgMECWorker::GpgMECWorker() { + gpgme_error_t c_err = gpgme_new(&c_ctx); +} + +GpgMECWorker::~GpgMECWorker() { + gpgme_release(c_ctx); +} + +bool GpgMECWorker::DeleteKey(const char * fullKeyId, bool secret, GpgME::Error& e) { + gpgme_key_t c_key; + gpgme_error_t c_err = gpgme_get_key(c_ctx, fullKeyId, &c_key, secret); + if (c_key == NULL) { + e = GpgME::Error::fromCode(c_err); + return false; + } + int flags = secret ? GPGME_DELETE_ALLOW_SECRET | GPGME_DELETE_FORCE : GPGME_DELETE_FORCE; + c_err = gpgme_op_delete_ext(c_ctx, c_key, flags); + if (c_err != 0) { + e = GpgME::Error::fromCode(c_err); + return false; + } + return true; +} \ No newline at end of file diff --git a/GpgMECWorker.h b/GpgMECWorker.h new file mode 100644 index 0000000..5f337e2 --- /dev/null +++ b/GpgMECWorker.h @@ -0,0 +1,38 @@ +/* + * File: GpgMECWorker.h + * Author: SET - nmset@netcourrier.com + * License : LGPL v2.1 + * Copyright SET - © 2019 + * + * Created on 14 octobre 2019, 15:22 + */ + +#ifndef GPGMECWORKER_H +#define GPGMECWORKER_H + +#include +#include + +class GpgMECWorker { +public: + GpgMECWorker(); + virtual ~GpgMECWorker(); + + /** + * Deleting keys must be done with the C API because + * gpgmepp does not provide a way to use GPGME_DELETE_FORCE, + * resulting in a confirmation dialog triggered by GPG. + * This does not fit use on a web werver. + * @param fullKeyId + * @param secret delete secret key ? + * @param e + * @return + */ + bool DeleteKey(const char * fullKeyId, bool secret, GpgME::Error& e); + +private: + gpgme_ctx_t c_ctx; +}; + +#endif /* GPGMECWORKER_H */ + diff --git a/GpgMEWorker.cpp b/GpgMEWorker.cpp new file mode 100644 index 0000000..943ba26 --- /dev/null +++ b/GpgMEWorker.cpp @@ -0,0 +1,80 @@ +/* + * File: GpgMEWorker.cpp + * Author: SET - nmset@netcourrier.com + * License : LGPL v2.1 + * Copyright SET - © 2019 + * + * Created on 11 octobre 2019, 16:34 + */ + +#include "GpgMEWorker.h" +#include +#include +#include +#include +#include + +GpgMEWorker::GpgMEWorker() +{ + m_ctx = Context::createForProtocol(Protocol::OpenPGP); +} + +GpgMEWorker::~GpgMEWorker() +{ + delete m_ctx; +} + +vector GpgMEWorker::FindKeys(const char * pattern, bool hasSecret, Error& e) const +{ + vector klst; + e = m_ctx->startKeyListing(pattern, hasSecret); + if (e.code() != 0) + return klst; + KeyListResult klr = m_ctx->keyListResult(); + if (klr.error().code() != 0) + { + e = klr.error(); + return klst; + } + while (e.code() == 0) + { + Key k = m_ctx->nextKey(e); + if (!k.isNull()) + { // What is that null key alongside ? + klst.push_back(k); + } + } + // e.code() != 0 here + klr = m_ctx->endKeyListing(); + e = klr.error(); + return klst; +} + +GpgME::Key GpgMEWorker::FindKey(const char * anyFullId, Error& e, bool secret) const +{ + return m_ctx->key(anyFullId, e, secret); +} + +const string GpgMEWorker::ImportKey(const char * filePath, Error& e) +{ + // Should we use a mutex here ? + FILE * kFp = fopen(filePath, "rb"); + GpgME::Data dKey(kFp); + vector keys = dKey.toKeys(); + if (keys.size() == 0) + { + fclose(kFp); + return ""; + } + const string keyid = string(dKey.toKeys().at(0).keyID()); // Must be done before import + ImportResult rImportKey = m_ctx->importKeys(dKey); + e = rImportKey.error(); + if (e.code() != 0) + { + fclose(kFp); + return ""; + } + + fclose(kFp); + return keyid; +} \ No newline at end of file diff --git a/GpgMEWorker.h b/GpgMEWorker.h new file mode 100644 index 0000000..ca62567 --- /dev/null +++ b/GpgMEWorker.h @@ -0,0 +1,59 @@ +/* + * File: GpgMEWorker.h + * Author: SET - nmset@netcourrier.com + * License : LGPL v2.1 + * Copyright SET - © 2019 + * + * Created on 11 octobre 2019, 16:34 + */ + +#ifndef GPGMEWORKER_H +#define GPGMEWORKER_H + +#include +#include +#include +#include + +using namespace std; +using namespace GpgME; +/** + * Main class for GPGME OP, except deleting keys. + */ +class GpgMEWorker +{ +public: + GpgMEWorker(); + virtual ~GpgMEWorker(); + + /** + * Find keys corresponding to pattern. GPGME searches in many fields : + * keyid, fingerprint, name, email... + * @param pattern + * @param hasSecret + * @param e + * @return + */ + vector FindKeys(const char * pattern, bool hasSecret, Error& e) const; + /** + * Search for a single key fully identified : keyid, short keyid, fingerprint. + * @param anyFullId + * @param e + * @param secret + * @return + */ + GpgME::Key FindKey(const char * anyFullId, Error& e, bool secret = false) const; + /** + * Import a key from file. + * @param filePath + * @param e + * @return the keyid + */ + const string ImportKey(const char * filePath, Error& e); + +private: + Context * m_ctx; +}; + +#endif /* GPGMEWORKER_H */ + diff --git a/K7Main.cpp b/K7Main.cpp new file mode 100644 index 0000000..0a89a12 --- /dev/null +++ b/K7Main.cpp @@ -0,0 +1,470 @@ +/* + * File: K7Main.cpp + * Author: SET - nmset@netcourrier.com + * License : GPL v2 + * Copyright SET - © 2019 + * + * Created on 7 octobre 2019, 21:29 + */ + +#include "K7Main.h" +#include "global.h" +#include +#include +#include +#include +#include +#include +#include +#include "GpgMEWorker.h" +#include "GpgMECWorker.h" + +using namespace std; + +K7Main::K7Main(const WEnvironment& env) +: WApplication(env) +{ + m_config = NULL; + WApplication::setTitle(_APPNAME_); + const WString bundle = WApplication::appRoot() + _APPNAME_; + WApplication::instance()->messageResourceBundle().use(bundle.toUTF8()); + if (!env.javaScript() || !env.ajax()) + { + root()->addWidget(cpp14::make_unique(TR("NoJS"))); + WApplication::quit(WString::Empty); + } + // We want users to authenticate with an X509 certificate + if (WApplication::instance()->environment().sslInfo() == NULL) + { + root()->addWidget(cpp14::make_unique(TR("NoAuth"))); + WApplication::quit(WString::Empty); + } + // Translate UID trusts to string + UidValidities[UserID::Validity::Full] = TR("UidFull"); + UidValidities[UserID::Validity::Marginal] = TR("UidMarginal"); + UidValidities[UserID::Validity::Never] = TR("UidNever"); + UidValidities[UserID::Validity::Ultimate] = TR("UidUltimate"); + UidValidities[UserID::Validity::Undefined] = TR("UidUndefined"); + UidValidities[UserID::Validity::Unknown] = TR("UidUnknown"); + m_uploader = NULL; m_deleter = NULL; +} + +K7Main::~K7Main() +{ + delete m_config; delete m_uploader; delete m_deleter; +} + +void +K7Main::Create() +{ + WContainerWidget * cwHeader = new WContainerWidget(); + WHBoxLayout * hblHeader = new WHBoxLayout(); + cwHeader->setLayout(unique_ptr (hblHeader)); + hblHeader->addWidget(cpp14::make_unique(_APPNAME_)); + // Error messages will go here + m_tmwMessage = new TransientMessageWidget(); + m_tmwMessage->setTextAlignment(AlignmentFlag::Right); + hblHeader->addWidget(unique_ptr(m_tmwMessage)); + root()->addWidget(unique_ptr (cwHeader)); + hblHeader->setStretchFactor(m_tmwMessage, 1); + + /* + * Load config JSON file. + * On error, just abort, AppConfig will print an error message in m_tmwMessage + */ + m_config = new AppConfig(m_tmwMessage); + if (!m_config->LoadConfig()) + return; + + m_cwMain = new WContainerWidget(); + WGridLayout * grlMain = new WGridLayout(); + grlMain->setColumnStretch(0, 1); + grlMain->setColumnStretch(1, 0); + m_cwMain->setLayout(unique_ptr (grlMain)); + // Add a search zone : line edit and button + m_leSearch = new WLineEdit(); + grlMain->addWidget(unique_ptr (m_leSearch), 0, 0); + m_leSearch->enterPressed().connect(this, &K7Main::Search); + WPushButton * btnSearch = new WPushButton(TR("Search")); + btnSearch->setToolTip(TR("TTTSearch")); + grlMain->addWidget(unique_ptr (btnSearch), 0, 1); + btnSearch->clicked().connect(this, &K7Main::Search); + // Add a result zone as a tree table + m_ttbKeys = new WTreeTable(); + grlMain->addWidget(unique_ptr (m_ttbKeys), 1, 0); + + WContainerWidget * cwButtons = new WContainerWidget(); + WVBoxLayout * vblButtons = new WVBoxLayout(); + cwButtons->setLayout(unique_ptr (vblButtons)); + // Add an import button if current user is allowed + if (m_config->CanImport()) + { + m_btnUpload = new WPushButton(TR("Upload")); + m_btnUpload->setToolTip(TR("TTTUpload")); + vblButtons->addWidget(unique_ptr (m_btnUpload)); + m_btnUpload->clicked().connect(this, &K7Main::PopupUploader); + m_btnImport = new WPushButton(TR("Import")); + m_btnImport->setToolTip(TR("TTTImport")); + vblButtons->addWidget(unique_ptr (m_btnImport)); + m_btnImport->clicked().connect(this, &K7Main::DoImportKey); + m_btnImport->hide(); + } + // Add a delete button if current user is allowed + if (m_config->CanDelete()) + { + m_btnDelete = new WPushButton(TR("Delete")); + m_btnDelete->setToolTip(TR("TTTDelete")); + vblButtons->addWidget(unique_ptr (m_btnDelete)); + m_btnDelete->clicked().connect(this, &K7Main::PopupDeleter); + m_btnDelete->hide(); + } + vblButtons->addSpacing(300); + grlMain->addWidget(unique_ptr (cwButtons), 1, 1); + + // Add and hide detail tables + m_ttbUids = new WTreeTable(); + grlMain->addWidget(unique_ptr (m_ttbUids), 2, 0); + m_ttbUids->hide(); + m_ttbSubKeys = new WTreeTable(); + grlMain->addWidget(unique_ptr (m_ttbSubKeys), 3, 0); + m_ttbSubKeys->hide(); + + root()->addWidget(cpp14::make_unique()); + root()->addWidget(unique_ptr (m_cwMain)); +#ifdef DEVTIME + // Save my fingertips. + m_leSearch->setText("s"); +#endif +} + +void K7Main::Search() +{ +#ifndef DEVTIME + // A reasonable minimal search criteria + if (!m_leSearch->text().empty() && m_leSearch->text().toUTF8().length() < 3) + { + m_tmwMessage->SetText(TR("CriteriaTooShort")); + return; + } +#endif + m_ttbSubKeys->hide(); + m_ttbUids->hide(); + Error e; + vector configPrivKeys = m_config->PrivateKeyIds(); + GpgMEWorker gpgw; + vector privkList, pubkList; + + // Find private keys if any is declared in config file for current user. + for (uint i = 0; i < configPrivKeys.size(); i++) + { + /* + * User may manage more than one private key. + * configPrivKeys.at(i) : we want this to be a full key id(short, normal or fpr) + * But it can be any string in the config file (name, email...). + * lst can hence contain many keys. + */ + vector lst = gpgw.FindKeys(configPrivKeys.at(i).toUTF8().c_str(), true, e); + if (e.code() != 0) + { + privkList.clear(); + m_tmwMessage->SetText(e.asString()); + return; + } + /* + * If any key is not a full key id, abort. + */ + for (uint j = 0; j < lst.size(); j++) + { + const GpgME::Key k = lst.at(j); + if (!ConfigKeyIdMatchesKey(k, configPrivKeys.at(i))) + { + m_tmwMessage->SetText(configPrivKeys.at(i) + TR("BadConfigKeyId")); + privkList.clear(); + return; + } + privkList.push_back(k); + } + } + // Find public keys as per criteria + if (!m_leSearch->text().empty()) + { + pubkList = gpgw.FindKeys(m_leSearch->text().toUTF8().c_str(), false, e); + if (e.code() != 0) + { + pubkList.clear(); + m_tmwMessage->SetText(e.asString()); + return; + } + } + + if (m_ttbKeys->columnCount() == 1) { + m_ttbKeys->addColumn(TR("ID"), 120); + m_ttbKeys->addColumn(TR("Fpr"), 300); + } + // The previous tree root is auto deleted by the use of smart pointers !! + WTreeTableNode * rootNode = new WTreeTableNode(TR("Keys")); + rootNode->setChildCountPolicy(ChildCountPolicy::Enabled); + m_ttbKeys->setTreeRoot(unique_ptr (rootNode), TR("KeyRing")); + rootNode->expand(); + // Show available keys + if (pubkList.size()) + DisplayKeys(pubkList, TR("Publics"), true); + if (privkList.size() && m_config->PrivateKeyIds().size() > 0) + DisplayKeys(privkList, TR("Secrets"), false); +} + +bool K7Main::ConfigKeyIdMatchesKey(const GpgME::Key& k, const WString& configKeyId) const +{ + // We want key identifier in config file to be real and complete. + return (configKeyId == WString(k.shortKeyID()) + || configKeyId == WString(k.keyID()) + || configKeyId == WString(k.primaryFingerprint())); +} + +WString K7Main::MakeDateTimeLabel(time_t ticks) +{ + std::chrono::minutes offset = WApplication::instance()->environment().timeZoneOffset(); + const WDateTime dt = WDateTime::fromTime_t(ticks + (time_t) offset.count() * 60); + return dt.toString(WString("yyyy-MM-dd - hh:mm:ss")); +} + +void K7Main::DisplayKeys(const vector& kList, const WString& grpLabel, bool expand) +{ + WTreeTableNode * grpNode = new WTreeTableNode(grpLabel); + m_ttbKeys->treeRoot()->addChildNode(unique_ptr (grpNode)); + for (uint i = 0; i < kList.size(); i++) + { + const GpgME::Key k = kList.at(i); + WTreeTableNode * keyNode = new WTreeTableNode(k.userID(0).name()); + WLink ln; + ln.setUrl(WString(L"javascript:void(0)").toUTF8()); + WAnchor * anc = new WAnchor(ln, k.shortKeyID()); + anc->setId(k.shortKeyID()); + // We use widget attribute values to buffer properties. + anc->setAttributeValue("hasSecret", k.hasSecret() ? "1" : "0"); + anc->clicked().connect(std::bind(&K7Main::OnKeyAnchorClicked, this, anc)); + keyNode->setColumnWidget(1, unique_ptr (anc)); + keyNode->setColumnWidget(2, cpp14::make_unique (k.primaryFingerprint())); + grpNode->addChildNode(unique_ptr (keyNode)); + } + if (expand) + grpNode->expand(); +} + +void K7Main::OnKeyAnchorClicked(WAnchor * source) +{ + // Show key details + const WString hasSecret = source->attributeValue("hasSecret"); + bool secret = true; + if (hasSecret == WString("0")) + secret = false; + const string id = source->id(); + DisplayUids(id, secret); + DisplaySubKeys(id, secret); + if (m_config->CanDelete()) // m_btnDelete is NULL otherwise + m_btnDelete->setHidden(!CanKeyBeDeleted(id)); +} + +void K7Main::DisplayUids(const WString& fullKeyID, bool secret) +{ + // Show UID details for a key + Error e; + GpgMEWorker gpgw; + m_ttbUids->hide(); + const GpgME::Key k = gpgw.FindKey(fullKeyID.toUTF8().c_str(), e, secret); + if (e.code() != 0) + { + m_tmwMessage->SetText(e.asString()); + return; + } + if (m_ttbUids->columnCount() == 1) + { + m_ttbUids->addColumn(TR("Email"), 200); + m_ttbUids->addColumn(TR("Trust"), 100); + m_ttbUids->addColumn(TR("Comment"), 300); + } + WTreeTableNode * rootNode = new WTreeTableNode(fullKeyID); + rootNode->setChildCountPolicy(ChildCountPolicy::Enabled); + m_ttbUids->setTreeRoot(unique_ptr (rootNode), TR("UIDs")); + rootNode->expand(); + for (uint i = 0; i < k.numUserIDs(); i++) + { + UserID uid = k.userID(i); + WTreeTableNode * uidNode = new WTreeTableNode(uid.name()); + uidNode->setColumnWidget(1, cpp14::make_unique (uid.email())); + uidNode->setColumnWidget(2, cpp14::make_unique (UidValidities[uid.validity()])); + uidNode->setColumnWidget(3, cpp14::make_unique (uid.comment())); + rootNode->addChildNode(unique_ptr (uidNode)); + // uid.numSignatures() is always 0, even for signed keys ! + for (uint s = 0; s < uid.numSignatures(); s++) + { + UserID::Signature sig = uid.signature(s); + const WString signer = WString(sig.signerName()) + _SPACE_ + + WString(sig.signerKeyID()); + WTreeTableNode * sigNode = new WTreeTableNode(signer); + sigNode->setColumnWidget(1, cpp14::make_unique (sig.signerEmail())); + WString exp = TR("Expiration") + _SPACE_ + _COLON_ + _SPACE_; + exp += sig.neverExpires() ? TR("Never") : MakeDateTimeLabel(sig.expirationTime()); + sigNode->setColumnWidget(2, cpp14::make_unique (exp)); + sigNode->setColumnWidget(3, cpp14::make_unique (sig.signerComment())); + uidNode->addChild(unique_ptr (sigNode)); + } + } + m_ttbUids->show(); +} + +void K7Main::DisplaySubKeys(const WString& fullKeyID, bool secret) +{ + // Show subkey details for a key + Error e; + GpgMEWorker gpgw; + m_ttbSubKeys->hide(); + const GpgME::Key k = gpgw.FindKey(fullKeyID.toUTF8().c_str(), e, secret); + if (e.code() != 0) + { + m_tmwMessage->SetText(e.asString()); + return; + } + if (m_ttbSubKeys->columnCount() == 1) + { + m_ttbSubKeys->addColumn(TR("Fpr"), 300); + m_ttbSubKeys->addColumn(TR("Expiration"), 150); + m_ttbSubKeys->addColumn(TR("Usage"), 70); + m_ttbSubKeys->addColumn(TR("Secret"), 50); + } + WTreeTableNode * rootNode = new WTreeTableNode(fullKeyID); + rootNode->setChildCountPolicy(ChildCountPolicy::Enabled); + m_ttbSubKeys->setTreeRoot(unique_ptr (rootNode), TR("SubKeys")); + rootNode->expand(); + for (uint i = 0; i < k.numSubkeys(); i++) + { + Subkey sk = k.subkey(i); + WTreeTableNode * skNode = new WTreeTableNode(sk.keyID()); + skNode->setColumnWidget(1, cpp14::make_unique (sk.fingerprint())); + WString exp = sk.neverExpires() ? TR("Never") : MakeDateTimeLabel(sk.expirationTime()); + skNode->setColumnWidget(2, cpp14::make_unique (exp)); + WString usage = sk.canAuthenticate() ? WString("A") : WString::Empty; + usage += sk.canCertify() ? WString("C") : WString::Empty; + usage += sk.canEncrypt() ? WString("E") : WString::Empty; + usage += sk.canSign() ? WString("S") : WString::Empty; + skNode->setColumnWidget(3, cpp14::make_unique (usage)); + const WString isSecret = sk.isSecret() ? TR("Yes") : TR("No"); + skNode->setColumnWidget(4, cpp14::make_unique (isSecret)); + rootNode->addChildNode(unique_ptr (skNode)); + } + m_ttbSubKeys->show(); +} + +void K7Main::PopupUploader() { + if (m_uploader == NULL) { + m_uploader = new Uploader(m_btnUpload, m_tmwMessage); + m_uploader->Create(); + m_uploader->UploadDone().connect(this, &K7Main::OnUploadCompleted); + } + m_uploader->show(); +} + +void K7Main::OnUploadCompleted(const WString& spool) { + // Buffer the spool file name in the import button + m_btnImport->setAttributeValue("spool", spool); + m_btnImport->show(); + m_uploader->hide(); +} + +void K7Main::DoImportKey() { + const WString spool = m_btnImport->attributeValue("spool"); + Error e; + GpgMEWorker gpgw; + const WString keyid = gpgw.ImportKey(spool.toUTF8().c_str(), e); + m_btnImport->hide(); + m_btnImport->setAttributeValue("spool", ""); + if (e.code() != 0) { + m_tmwMessage->SetText(e.asString()); + return; + } + if (keyid.empty()) { + m_tmwMessage->SetText(TR("ImportError") + keyid); + return; + } + // Show the imported key + GpgME::Key k = gpgw.FindKey(keyid.toUTF8().c_str(), e, false); // A public is present anyway + if (e.code() != 0) { + m_tmwMessage->SetText(e.asString()); + return; + } + m_tmwMessage->SetText(TR("ImportSuccess") + keyid + WString(" - ") + WString(k.userID(0).name())); + m_leSearch->setText(keyid); + Search(); +} + +bool K7Main::CanKeyBeDeleted(const WString& fullKeyID) { + // Caller should check m_config->canDelete first. m_btnDelete is null if can't delete. + Error e; + GpgMEWorker gpgw; + GpgME::Key k = gpgw.FindKey(fullKeyID.toUTF8().c_str(), e, true); // Look for a private key + if (e.code() != 0 && e.code() != 16383) { // 16383 : end of file, when key is not private + m_tmwMessage->SetText(e.asString()); + return false; + } + // k can now be secret or public + if (k.isNull()) {// Is a public key + k = gpgw.FindKey(fullKeyID.toUTF8().c_str(), e, false); + // Prepare actual delete + m_btnDelete->setAttributeValue("keyid", k.keyID()); + m_btnDelete->setAttributeValue("hasSecret", "0"); + return true; + } + /* + * k is now secret + * Is selected private key one of those that the current user manages ? + */ + vector curUserPrivKeys = m_config->PrivateKeyIds(); + vector::iterator it; + for (it = curUserPrivKeys.begin(); it != curUserPrivKeys.end(); it++) { + if (ConfigKeyIdMatchesKey(k, *it)) { + m_btnDelete->setAttributeValue("keyid", k.keyID()); + m_btnDelete->setAttributeValue("hasSecret", "1"); + return true; + } + } + return false; +} + +void K7Main::PopupDeleter() { + if (m_deleter == NULL) { + m_deleter = new Deleter(m_btnDelete, m_tmwMessage); + m_deleter->Create(); + m_deleter->GetDeleteButton()->clicked().connect(this, &K7Main::DoDeleteKey); + } + m_deleter->show(); +} + +void K7Main::DoDeleteKey() { + // Deleting keys requires the GPGME C API + Error c_e, e; + GpgMECWorker gpgcw; + GpgMEWorker gpgw; + const WString fullKeyID = m_btnDelete->attributeValue("keyid"); + const WString hasSecret = m_btnDelete->attributeValue("hasSecret"); + bool secret = true; + if (hasSecret == WString("0")) + secret = false; + // Get the key before deletion, to show its ID on success + GpgME::Key k = gpgw.FindKey(fullKeyID.toUTF8().c_str(), e, secret); + if (e.code() != 0) { + m_tmwMessage->SetText(e.asString()); + return; + } + // Delete the key using the C API + bool res = gpgcw.DeleteKey(fullKeyID.toUTF8().c_str(), secret, c_e); + if (c_e.code() != 0) { + m_tmwMessage->SetText(c_e.asString()); + } else { + m_tmwMessage->SetText(TR("DeleteSuccess") + fullKeyID + WString(" - ") + WString(k.userID(0).name())); + } + m_btnDelete->hide(); + m_deleter->hide(); + // Show that the key is no longer available + m_leSearch->setText(fullKeyID); + Search(); +} diff --git a/K7Main.h b/K7Main.h new file mode 100644 index 0000000..ad05cd9 --- /dev/null +++ b/K7Main.h @@ -0,0 +1,128 @@ +/* + * File: K7Main.h + * Author: SET - nmset@netcourrier.com + * License : GPL v2 + * Copyright SET - © 2019 + * + * Created on 7 octobre 2019, 21:29 + */ + +#ifndef K7MAIN_H +#define K7MAIN_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "AppConfig.h" +#include "PopupUploader.h" +#include "PopupDeleter.h" +#include "TransientMessageWidget.h" + +using namespace Wt; + +class K7Main : public WApplication +{ +public: + K7Main(const WEnvironment& env); + virtual ~K7Main(); + void Create(); + +private: + /** + * Translate UID trusts to string + */ + typedef map UidValidityMap; + UidValidityMap UidValidities; + AppConfig * m_config; + WGridLayout * m_grlMain; + WContainerWidget * m_cwMain; + TransientMessageWidget * m_tmwMessage; + WLineEdit * m_leSearch; + WPushButton * m_btnUpload; + WPushButton * m_btnImport; + WPushButton * m_btnDelete ; + WTreeTable * m_ttbKeys; + WTreeTable * m_ttbUids; + WTreeTable * m_ttbSubKeys; + Uploader * m_uploader; + Deleter * m_deleter; + /** + * Finds public keys as per criteria, + * and private keys if any is declared in config file for current client. + * \nShows the keys in tree table. + */ + void Search(); + /** + * We want key identifier in config file to be real and complete. + * @param k + * @param configKeyId key identifier as entered in configuration file + * @return + */ + bool ConfigKeyIdMatchesKey(const GpgME::Key& k, const WString& configKeyId) const; + /** + * Show keys in tree table + */ + void DisplayKeys(const vector& kList, const WString& grpLabel, bool expand); + /** + * Show key details + * @param source + */ + void OnKeyAnchorClicked(WAnchor * source); + /** + * Show UID details for a key + * @param fullKeyID + * @param secret + */ + void DisplayUids(const WString& fullKeyID, bool secret = false); + /** + * Show subkey details for a key + * @param fullKeyID + * @param secret + */ + void DisplaySubKeys(const WString& fullKeyID, bool secret = false); + /** + * Shows a non-blocking popup to upload a key, + * with forward confirmation for upload. + */ + void PopupUploader(); + /** + * Shows a button to import an uploaded key + * @param spool + */ + void OnUploadCompleted(const WString& spool); + /** + * Actually import the uploaded file. + */ + void DoImportKey(); + /** + * Shows a non-blocking popup to delete a key + */ + void PopupDeleter(); + /** + * All public keys can be deleted. + * Private keys can be deleted only if the user + * manages that key, as declared in the configuration file. + * @param fullKeyID + * @return + */ + bool CanKeyBeDeleted(const WString& fullKeyID); + /** + * Actually delete the key, with forward confirmation in the popup. + */ + void DoDeleteKey(); + /** + * Translates unit time to readable date. + */ + WString MakeDateTimeLabel(time_t ticks); +}; + +#endif /* K7MAIN_H */ + diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d159169 --- /dev/null +++ b/LICENSE @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..05de621 --- /dev/null +++ b/Makefile @@ -0,0 +1,128 @@ +# +# There exist several targets which are by default empty and which can be +# used for execution of your targets. These targets are usually executed +# before and after some main targets. They are: +# +# .build-pre: called before 'build' target +# .build-post: called after 'build' target +# .clean-pre: called before 'clean' target +# .clean-post: called after 'clean' target +# .clobber-pre: called before 'clobber' target +# .clobber-post: called after 'clobber' target +# .all-pre: called before 'all' target +# .all-post: called after 'all' target +# .help-pre: called before 'help' target +# .help-post: called after 'help' target +# +# Targets beginning with '.' are not intended to be called on their own. +# +# Main targets can be executed directly, and they are: +# +# build build a specific configuration +# clean remove built files from a configuration +# clobber remove all built files +# all build all configurations +# help print help mesage +# +# Targets .build-impl, .clean-impl, .clobber-impl, .all-impl, and +# .help-impl are implemented in nbproject/makefile-impl.mk. +# +# Available make variables: +# +# CND_BASEDIR base directory for relative paths +# CND_DISTDIR default top distribution directory (build artifacts) +# CND_BUILDDIR default top build directory (object files, ...) +# CONF name of current configuration +# CND_PLATFORM_${CONF} platform name (current configuration) +# CND_ARTIFACT_DIR_${CONF} directory of build artifact (current configuration) +# CND_ARTIFACT_NAME_${CONF} name of build artifact (current configuration) +# CND_ARTIFACT_PATH_${CONF} path to build artifact (current configuration) +# CND_PACKAGE_DIR_${CONF} directory of package (current configuration) +# CND_PACKAGE_NAME_${CONF} name of package (current configuration) +# CND_PACKAGE_PATH_${CONF} path to package (current configuration) +# +# NOCDDL + + +# Environment +MKDIR=mkdir +CP=cp +CCADMIN=CCadmin + + +# build +build: .build-post + +.build-pre: +# Add your pre 'build' code here... + +.build-post: .build-impl +# Add your post 'build' code here... + + +# clean +clean: .clean-post + +.clean-pre: +# Add your pre 'clean' code here... + +.clean-post: .clean-impl +# Add your post 'clean' code here... + + +# clobber +clobber: .clobber-post + +.clobber-pre: +# Add your pre 'clobber' code here... + +.clobber-post: .clobber-impl +# Add your post 'clobber' code here... + + +# all +all: .all-post + +.all-pre: +# Add your pre 'all' code here... + +.all-post: .all-impl +# Add your post 'all' code here... + + +# build tests +build-tests: .build-tests-post + +.build-tests-pre: +# Add your pre 'build-tests' code here... + +.build-tests-post: .build-tests-impl +# Add your post 'build-tests' code here... + + +# run tests +test: .test-post + +.test-pre: build-tests +# Add your pre 'test' code here... + +.test-post: .test-impl +# Add your post 'test' code here... + + +# help +help: .help-post + +.help-pre: +# Add your pre 'help' code here... + +.help-post: .help-impl +# Add your post 'help' code here... + + + +# include project implementation makefile +include nbproject/Makefile-impl.mk + +# include project make variables +include nbproject/Makefile-variables.mk diff --git a/PopupDeleter.cpp b/PopupDeleter.cpp new file mode 100644 index 0000000..27f9b8b --- /dev/null +++ b/PopupDeleter.cpp @@ -0,0 +1,62 @@ +/* + * File: PopupDeleter.cpp + * Author: SET - nmset@netcourrier.com + * License : GPL v2 + * Copyright SET - © 2019 + * + * Created on 15 octobre 2019, 18:39 + */ + +#include "PopupDeleter.h" +#include "global.h" +#include +#include + +using namespace std; + +Deleter::Deleter(WWidget * anchorWidget, TransientMessageWidget * txtMessage, const WLength& width) +: WPopupWidget(cpp14::make_unique()) { + m_tmwMessage = txtMessage; m_cwMain = NULL; m_cbConfirm = NULL; + m_cbReConfirm = NULL; m_btnDelete = NULL; + setTransient(true); + setAnchorWidget(anchorWidget); + setWidth(width); +} + +Deleter::~Deleter() { +} + +void Deleter::Create() { + m_cwMain = static_cast (implementation()); + WVBoxLayout * vblMain = new WVBoxLayout(); + m_cwMain->setLayout(unique_ptr (vblMain)); + m_cbConfirm = new WCheckBox(TR("Confirm")); + vblMain->addWidget(unique_ptr (m_cbConfirm)); + m_cbReConfirm = new WCheckBox(TR("ReConfirm")); + vblMain->addWidget(unique_ptr (m_cbReConfirm)); + m_btnDelete = new WPushButton(TR("Delete")); + vblMain->addWidget(unique_ptr (m_btnDelete)); + m_cbReConfirm->hide(); + m_btnDelete->hide(); + m_cbConfirm->changed().connect(this, &Deleter::OnCbConfirm); + m_cbReConfirm->changed().connect(this, &Deleter::OnCbReConfirm); + this->hidden().connect(this, &Deleter::Reset); +} + +void Deleter::Reset() { + m_btnDelete->hide(); + m_cbReConfirm->setUnChecked(); + m_cbReConfirm->hide(); + m_cbConfirm->setUnChecked(); + m_cbConfirm->show(); +} + +void Deleter::OnCbConfirm() { + m_cbReConfirm->setHidden(m_cbConfirm->checkState() != CheckState::Checked); + m_cbReConfirm->setUnChecked(); + m_btnDelete->setHidden(m_cbReConfirm->checkState() != CheckState::Checked); +} + +void Deleter::OnCbReConfirm() { + m_btnDelete->setHidden(m_cbReConfirm->checkState() != CheckState::Checked); +} diff --git a/PopupDeleter.h b/PopupDeleter.h new file mode 100644 index 0000000..fcfbd76 --- /dev/null +++ b/PopupDeleter.h @@ -0,0 +1,48 @@ +/* + * File: PopupDeleter.h + * Author: SET - nmset@netcourrier.com + * License : GPL v2 + * Copyright SET - © 2019 + * + * Created on 15 octobre 2019, 18:39 + */ + +#ifndef POPUPDELETER_H +#define POPUPDELETER_H + +#include +#include +#include +#include +#include "TransientMessageWidget.h" + +using namespace Wt; +/** + * A transient popup window with a forward confirmation + * before deleting a key. + */ +class Deleter : public WPopupWidget { +public: + Deleter(WWidget * anchorWidget, TransientMessageWidget * txtMessage, const WLength& width = 350); + virtual ~Deleter(); + void Create(); + /** + * Caller can bind the delete function to this button. + * @return + */ + WPushButton* GetDeleteButton() {return m_btnDelete;} +private: + TransientMessageWidget * m_tmwMessage; + WContainerWidget * m_cwMain; + WCheckBox * m_cbConfirm; + WCheckBox * m_cbReConfirm; + WPushButton * m_btnDelete; + + // Visibility management + void Reset(); + void OnCbConfirm(); + void OnCbReConfirm(); +}; + +#endif /* POPUPDELETER_H */ + diff --git a/PopupUploader.cpp b/PopupUploader.cpp new file mode 100644 index 0000000..ab654a0 --- /dev/null +++ b/PopupUploader.cpp @@ -0,0 +1,92 @@ +/* + * File: PopupUploader.cpp + * Author: SET - nmset@netcourrier.com + * License : GPL v2 + * Copyright SET - © 2019 + * + * Created on 13 octobre 2019, 18:48 + */ + +#include "PopupUploader.h" +#include "global.h" +#include +#include + +using namespace std; + +Uploader::Uploader(WWidget * anchorWidget, TransientMessageWidget * txtMessage, const WLength& width) +: WPopupWidget(cpp14::make_unique()) { + m_tmwMessage = txtMessage; m_upload = NULL; m_cwMain = NULL; + m_cbConfirm = NULL; m_cbReConfirm = NULL; m_btnUpload = NULL; + setTransient(true); + setAnchorWidget(anchorWidget); + setWidth(width); +} + +Uploader::~Uploader() { +} + +void Uploader::Create() { + m_upload = new WFileUpload(); + m_upload->setFileTextSize(10240); // Is really approximate + m_upload->setMultiple(false); + m_cwMain = static_cast (implementation()); + WVBoxLayout * vblMain = new WVBoxLayout(); + m_cwMain->setLayout(unique_ptr (vblMain)); + vblMain->addWidget(unique_ptr (m_upload)); + m_cbConfirm = new WCheckBox(TR("Confirm")); + vblMain->addWidget(unique_ptr (m_cbConfirm)); + m_cbReConfirm = new WCheckBox(TR("ReConfirm")); + vblMain->addWidget(unique_ptr (m_cbReConfirm)); + m_btnUpload = new WPushButton(TR("Upload")); + vblMain->addWidget(unique_ptr (m_btnUpload)); + m_cbReConfirm->hide(); + m_cbConfirm->hide(); + m_btnUpload->hide(); + m_cbConfirm->changed().connect(this, &Uploader::OnCbConfirm); + m_cbReConfirm->changed().connect(this, &Uploader::OnCbReConfirm); + m_btnUpload->clicked().connect(this, &Uploader::DoUpload); + m_upload->uploaded().connect(this, &Uploader::OnUploadDone); + m_upload->fileTooLarge().connect(this, &Uploader::OnFileTooLarge); + m_upload->changed().connect(this, &Uploader::Reset); + this->hidden().connect(this, &Uploader::Reset); +} + +void Uploader::Reset() { + m_btnUpload->hide(); + m_cbReConfirm->setUnChecked(); + m_cbReConfirm->hide(); + m_cbConfirm->setUnChecked(); + m_cbConfirm->show(); + m_btnUpload->enable(); +} +void Uploader::OnCbConfirm() { + m_cbReConfirm->setHidden(m_cbConfirm->checkState() != CheckState::Checked); + m_cbReConfirm->setUnChecked(); + m_btnUpload->setHidden(m_cbReConfirm->checkState() != CheckState::Checked); +} + +void Uploader::OnCbReConfirm() { + m_btnUpload->setHidden(m_cbReConfirm->checkState() != CheckState::Checked); +} + +void Uploader::DoUpload() { + if (m_upload->canUpload()) { + m_btnUpload->disable(); + m_upload->upload(); + } else { + m_tmwMessage->SetText(TR("CantUpload")); + } +} + +void Uploader::OnUploadDone() { + m_sigUploadDone.emit(m_upload->spoolFileName()); + m_btnUpload->enable(); +} + +void Uploader::OnFileTooLarge() { + m_tmwMessage->SetText(TR("FileTooLarge")); + m_btnUpload->enable(); +} + + diff --git a/PopupUploader.h b/PopupUploader.h new file mode 100644 index 0000000..bbca4e6 --- /dev/null +++ b/PopupUploader.h @@ -0,0 +1,63 @@ +/* + * File: PopupUploader.h + * Author: SET - nmset@netcourrier.com + * License : GPL v2 + * Copyright SET - © 2019 + * + * Created on 13 octobre 2019, 18:48 + */ + +#ifndef POPUPUPLOADER_H +#define POPUPUPLOADER_H + +#include +#include +#include +#include +#include +#include +#include "TransientMessageWidget.h" + +using namespace Wt; +/** + * A transient popup window to upload a key + * that will next be imported. + * @param anchorWidget + * @param txtMessage + * @param width + */ +class Uploader : public WPopupWidget +{ +public: + Uploader(WWidget * anchorWidget, TransientMessageWidget * txtMessage, const WLength& width = 350); + virtual ~Uploader(); + void Create(); + + /** + * Forward WFileUpload::uploaded() to caller + * @return + */ + Signal& UploadDone() + { + return m_sigUploadDone; + } +private: + TransientMessageWidget * m_tmwMessage; + WFileUpload * m_upload; + WContainerWidget * m_cwMain; + WCheckBox * m_cbConfirm; + WCheckBox * m_cbReConfirm; + WPushButton * m_btnUpload; + Signal m_sigUploadDone; + + void Reset(); + void OnCbConfirm(); + void OnCbReConfirm(); + void DoUpload(); + void OnUploadDone(); + void OnFileTooLarge(); + +}; + +#endif /* POPUPUPLOADER_H */ + diff --git a/README.md b/README.md new file mode 100644 index 0000000..bf38dae --- /dev/null +++ b/README.md @@ -0,0 +1,37 @@ +K7 is an application for minimal remote management of GPG keys on a web server. +It allows to view, import and delete keys. +It does not intend nor need to be a full blown key manager. +Key generation and editing is not implemented, and it probably cannot be done this way. + +K7 is developed as a NetBeans project on the [WebToolkit](https://www.webtoolkit.eu/)(Wt) libraries. +It is released under the GPL version 2 license. + +The intent is solely to add and delete keys in the default GPG keyring of the running user. +These keys can then be used by other Wt applications, or applications based on other libraries, to encrypt and sign data. As such, it suits my personal needs. + +BUILDING + +As a NetBeans project, a Makefile exists in the project root. +cd /path/to/K7 +make CONF=Debug #linked to wthttp here +make CONF=Release #linked to wtfcgi + +INSTALLING AND RUNNING + +Please see Wt's manuals about the modes of installing and running Wt applications. +In particular, K7 needs the enviromment variable WT_APP_ROOT that should point to the directory containing configuration and translation files. In the project's tree, it's WTAPPROOT/K7. + +MAIN CONFIGURATION FILE + +This file is hard coded as k7config.json, and must be found in WT_APP_ROOT. +It controls access to the application. All users must authenticate by sending a client X509 certificate, and access is allowed if the subject's common name is listed as a JSON key in the configuration file. +An allowed user can always view keys. He can optionally import any GPG key, and delete GPG public keys. +An allowed user can optionally delete private GPG keys. For this, a full key identifier must be declared in a JSON array in the configuration file. This should be a normal key identifier, a short key identifier or a fingerprint, but always a full identifier. + +TRANSLATION FILES + +K7.xml contains user facing strings for English default language. K7_fr.xml is translated in French . + +DISCLAIMER + +As usual, use at your own risks or don't use. I don't claim that K7 is fit for any purpose. Programming is just my hobby. diff --git a/TransientMessageWidget.cpp b/TransientMessageWidget.cpp new file mode 100644 index 0000000..2d09833 --- /dev/null +++ b/TransientMessageWidget.cpp @@ -0,0 +1,71 @@ +/* + * File: TransientMessageWidget.cpp + * Author: SET - nmset@netcourrier.com + * License : LGPL v2.1 + * Copyright SET - © 2019 + * + * Created on 16 octobre 2019, 18:25 + */ + +#include "TransientMessageWidget.h" + +TransientMessageWidget::TransientMessageWidget() +: WText() +{ + Init(); +} + +TransientMessageWidget::TransientMessageWidget(const WString& text) +: WText(text) +{ + Init(); +} + +TransientMessageWidget::TransientMessageWidget(const WString& text, TextFormat textFormat) +: WText(text, textFormat) +{ + Init(); +} + +TransientMessageWidget::~TransientMessageWidget() +{ + m_timer.stop(); +} + +void TransientMessageWidget::Init() +{ + m_stackSize = 8; + m_interval = (std::chrono::milliseconds) 10 * 1000; + m_timer.setSingleShot(true); + SetInterval(m_interval); + m_timer.timeout().connect(this, &TransientMessageWidget::OnTimer); +} + +void TransientMessageWidget::OnTimer() +{ + WText::setText(WString::Empty); +} + +void TransientMessageWidget::SetText(const WString& text, bool stack) +{ + m_timer.stop(); + if (stack) { + // Remove the oldest message if stack is full + if (m_stack.size() == m_stackSize) { + m_stack.pop_back(); + } + m_stack.push_front(text); + } + WText::setText(text); + // List messages in the tool tip + WString ttt = WString::Empty; + list::iterator it; + uint idx = m_stack.size(); + for (it = m_stack.begin(); it != m_stack.end(); it++) + { + ttt += WString(to_string(idx)) + WString(". ") + *it + WString("\n"); + idx--; + } + setToolTip(ttt); + m_timer.start(); +} \ No newline at end of file diff --git a/TransientMessageWidget.h b/TransientMessageWidget.h new file mode 100644 index 0000000..d8990c7 --- /dev/null +++ b/TransientMessageWidget.h @@ -0,0 +1,69 @@ +/* + * File: TransientMessageWidget.h + * Author: SET - nmset@netcourrier.com + * License : LGPL v2.1 + * Copyright SET - © 2019 + * + * Created on 16 octobre 2019, 18:25 + */ + +#ifndef TRANSIENTMESSAGEWIDGET_H +#define TRANSIENTMESSAGEWIDGET_H + +#include +#include +#include + +using namespace Wt; +using namespace std; + +/** + * A transient stacked message zone. + * By default, 8 messages can be stacked in a list shown + * in the tool tip; each message is shown for 10 seconds. + */ +class TransientMessageWidget : public WText +{ +public: + TransientMessageWidget(); + TransientMessageWidget(const WString& text); + TransientMessageWidget(const WString& text, TextFormat textFormat); + virtual ~TransientMessageWidget(); + + void SetInterval(std::chrono::milliseconds interval) + { + m_timer.setInterval(interval); + } + + std::chrono::milliseconds Interval() + { + return m_timer.interval(); + } + + void SetStackSize(uint sz) + { + m_stackSize = sz; + } + + uint GetStackSize() + { + return m_stackSize; + } + /** + * Main function to show and pile up messages. + * @param text + * @param stack + */ + void SetText(const WString& text, bool stack = true); +private: + uint m_stackSize; + std::chrono::milliseconds m_interval; + WTimer m_timer; + list m_stack; + + void Init(); + void OnTimer(); +}; + +#endif /* TRANSIENTMESSAGEWIDGET_H */ + diff --git a/WTAPPROOT/K7/K7.xml b/WTAPPROOT/K7/K7.xml new file mode 100644 index 0000000..16e24ba --- /dev/null +++ b/WTAPPROOT/K7/K7.xml @@ -0,0 +1,65 @@ + + + + Browser does not provide Javascript or AJAX + Browser does not send a client certificate + Search + Upload + Import + Delete + Sign key + Find keys with this pattern + Upload a new key + Add a new key + Delete selected key + Sign selected key with your secret key if available + Can't upload + + Can't load config file + Can't parse json file + Can't identify certificates in config file + in configuration file is not a valid key identifier + Access denied + + Keyring + Key + Keys + Public + Public + Secret + Secret + Fingerprint + + ID + User ID + User IDs + Email + Validity + Trust + + Full + Marginal + Never + Ultimate + Undefined + Unknown + Comment + Signers + Expiration + Never + + Subkeys + IDs + Usage + + Yes + No + At least 3 characters required, or use an empty criteria to list your private keys if any + + Confirm + Confirm again + File is too big + Import success : + Uploaded file could not be imported in the keyring + Delete success : + \ No newline at end of file diff --git a/WTAPPROOT/K7/K7_fr.xml b/WTAPPROOT/K7/K7_fr.xml new file mode 100644 index 0000000..b74e1fc --- /dev/null +++ b/WTAPPROOT/K7/K7_fr.xml @@ -0,0 +1,65 @@ + + + + Javascript or AJAX manquant dans le navigateur + Le navigateur ne s'est pas authentifié + Rechercher + Télécharger + Importer + Supprimer + Signer + Rechercher des clés correspondant au motif + Télécharger une nouvelle clé + Ajouter une nouvelle clé au porte clés + Supprimer la clé sélectionnée + Signer la clé sélectionnée avec votre clé secrète si elle est disponible + Ne peut télécharger + + Ne peut charger le fichier de configuration + Ne peur traiter le fichier de configuration + Ne peut trouver les certificats d'identité dans le fichier de configuration + dans le fichier de configuration n'est pas un identifiant de clé valide + Accès non autorisé + + Porte clés + Clé + Clés + Publique + Publiques + Secrète + Secrètes + Empreinte + + Identifiant + Identifiant utilisateur + Identifiants utilisateur + Courriel + Validité + Confiance + + Complète + Marginale + Jamais + Ultime + Non définie + Inconnue + Commentaires + Signataires + Expiration + Jamais + + Sous-clés + IDs + Utilisation + + Oui + Non + Au moins 3 caractères requis, ou aucin critère pour sélectionner vos clés privées si elles sont déclarées + + Confirmer + Reconfirmer + Fichier trop volumineux + Importation réussie : + Le fichier téléchargé n'a pu être importé dans le trousseau + Suppression réussie : + diff --git a/WTAPPROOT/K7/k7config.json b/WTAPPROOT/K7/k7config.json new file mode 100644 index 0000000..0623526 --- /dev/null +++ b/WTAPPROOT/K7/k7config.json @@ -0,0 +1,15 @@ +{ + "sCommonName" : { + "user1" : { + "canImport" : true, + "canDelete" : true, + "privKeyIds" : [ + "FullKeyId1", + "FullKeyId2" + ] + }, + "user2" : { + "canImport" : true + } + } +} diff --git a/global.h b/global.h new file mode 100644 index 0000000..3725914 --- /dev/null +++ b/global.h @@ -0,0 +1,26 @@ +/* + * File: global.h + * Author: SET - nmset@netcourrier.com + * License : GPL v2 + * Copyright SET - © 2019 + * + * Created on 8 octobre 2019, 20:52 + */ + +#ifndef GLOBAL_H +#define GLOBAL_H + +#include +using namespace Wt; +using namespace std; + +#define TR(sk) WString::tr(sk) + +const WString _APPNAME_("K7"); +const WString _APPVERSION_("1"); +const WString _SPACE_(" "); +const WString _COLON_(":"); + + +#endif /* GLOBAL_H */ + diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..cbf4e77 --- /dev/null +++ b/main.cpp @@ -0,0 +1,31 @@ +/* + * File: main.cpp + * Author: SET - nmset@netcourrier.com + * License : GPL v2 + * Copyright SET - © 2019 + * + * Created on 7 octobre 2019, 21:06 + */ + +#include +#include "K7Main.h" +#include +#include +#include +using namespace std; +using namespace Wt; + + +unique_ptr createApplication(const WEnvironment& env) +{ + unique_ptr app = cpp14::make_unique(env); + app->Create(); + return (app); +} + +int main(int argc, char** argv) +{ + GpgME::initializeLibrary(); + return WRun(argc, argv, &createApplication); +} + diff --git a/nbproject/Makefile-ARM-Release.mk b/nbproject/Makefile-ARM-Release.mk new file mode 100644 index 0000000..c24c1bd --- /dev/null +++ b/nbproject/Makefile-ARM-Release.mk @@ -0,0 +1,125 @@ +# +# Generated Makefile - do not edit! +# +# Edit the Makefile in the project folder instead (../Makefile). Each target +# has a -pre and a -post target defined where you can add customized code. +# +# This makefile implements configuration specific macros and targets. + + +# Environment +MKDIR=mkdir +CP=cp +GREP=grep +NM=nm +CCADMIN=CCadmin +RANLIB=ranlib +CC=gcc +CCC=g++ +CXX=g++ +FC=gfortran +AS=as + +# Macros +CND_PLATFORM=GNU-Linux +CND_DLIB_EXT=so +CND_CONF=ARM-Release +CND_DISTDIR=dist +CND_BUILDDIR=build + +# Include project Makefile +include Makefile + +# Object Directory +OBJECTDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM} + +# Object Files +OBJECTFILES= \ + ${OBJECTDIR}/AppConfig.o \ + ${OBJECTDIR}/GpgMECWorker.o \ + ${OBJECTDIR}/GpgMEWorker.o \ + ${OBJECTDIR}/K7Main.o \ + ${OBJECTDIR}/PopupDeleter.o \ + ${OBJECTDIR}/PopupUploader.o \ + ${OBJECTDIR}/TransientMessageWidget.o \ + ${OBJECTDIR}/main.o + + +# C Compiler Flags +CFLAGS= + +# CC Compiler Flags +CCFLAGS=-Wno-deprecated -Wno-deprecated-declarations +CXXFLAGS=-Wno-deprecated -Wno-deprecated-declarations + +# Fortran Compiler Flags +FFLAGS= + +# Assembler Flags +ASFLAGS= + +# Link Libraries and Options +LDLIBSOPTIONS=-L/usr/local/Wt/lib -lwt -lwtfcgi -lgpgmepp -lgpgme + +# Build Targets +.build-conf: ${BUILD_SUBPROJECTS} + "${MAKE}" -f nbproject/Makefile-${CND_CONF}.mk ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/k7 + +${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/k7: ${OBJECTFILES} + ${MKDIR} -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM} + ${LINK.cc} -o ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/k7 ${OBJECTFILES} ${LDLIBSOPTIONS} -s + +${OBJECTDIR}/AppConfig.o: AppConfig.cpp + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -O2 -s -DLARGEFILE_SOURCE=1 -D_FILE_OFFSET_BITS=64 -I/usr/local/Wt/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/AppConfig.o AppConfig.cpp + +${OBJECTDIR}/GpgMECWorker.o: GpgMECWorker.cpp + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -O2 -s -DLARGEFILE_SOURCE=1 -D_FILE_OFFSET_BITS=64 -I/usr/local/Wt/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/GpgMECWorker.o GpgMECWorker.cpp + +${OBJECTDIR}/GpgMEWorker.o: GpgMEWorker.cpp + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -O2 -s -DLARGEFILE_SOURCE=1 -D_FILE_OFFSET_BITS=64 -I/usr/local/Wt/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/GpgMEWorker.o GpgMEWorker.cpp + +${OBJECTDIR}/K7Main.o: K7Main.cpp + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -O2 -s -DLARGEFILE_SOURCE=1 -D_FILE_OFFSET_BITS=64 -I/usr/local/Wt/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/K7Main.o K7Main.cpp + +${OBJECTDIR}/PopupDeleter.o: PopupDeleter.cpp + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -O2 -s -DLARGEFILE_SOURCE=1 -D_FILE_OFFSET_BITS=64 -I/usr/local/Wt/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/PopupDeleter.o PopupDeleter.cpp + +${OBJECTDIR}/PopupUploader.o: PopupUploader.cpp + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -O2 -s -DLARGEFILE_SOURCE=1 -D_FILE_OFFSET_BITS=64 -I/usr/local/Wt/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/PopupUploader.o PopupUploader.cpp + +${OBJECTDIR}/TransientMessageWidget.o: TransientMessageWidget.cpp + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -O2 -s -DLARGEFILE_SOURCE=1 -D_FILE_OFFSET_BITS=64 -I/usr/local/Wt/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/TransientMessageWidget.o TransientMessageWidget.cpp + +${OBJECTDIR}/main.o: main.cpp + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -O2 -s -DLARGEFILE_SOURCE=1 -D_FILE_OFFSET_BITS=64 -I/usr/local/Wt/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/main.o main.cpp + +# Subprojects +.build-subprojects: + +# Clean Targets +.clean-conf: ${CLEAN_SUBPROJECTS} + ${RM} -r ${CND_BUILDDIR}/${CND_CONF} + +# Subprojects +.clean-subprojects: + +# Enable dependency checking +.dep.inc: .depcheck-impl + +include .dep.inc diff --git a/nbproject/Makefile-Debug.mk b/nbproject/Makefile-Debug.mk new file mode 100644 index 0000000..b21e215 --- /dev/null +++ b/nbproject/Makefile-Debug.mk @@ -0,0 +1,125 @@ +# +# Generated Makefile - do not edit! +# +# Edit the Makefile in the project folder instead (../Makefile). Each target +# has a -pre and a -post target defined where you can add customized code. +# +# This makefile implements configuration specific macros and targets. + + +# Environment +MKDIR=mkdir +CP=cp +GREP=grep +NM=nm +CCADMIN=CCadmin +RANLIB=ranlib +CC=gcc +CCC=g++ +CXX=g++ +FC=gfortran +AS=as + +# Macros +CND_PLATFORM=GNU-Linux +CND_DLIB_EXT=so +CND_CONF=Debug +CND_DISTDIR=dist +CND_BUILDDIR=build + +# Include project Makefile +include Makefile + +# Object Directory +OBJECTDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM} + +# Object Files +OBJECTFILES= \ + ${OBJECTDIR}/AppConfig.o \ + ${OBJECTDIR}/GpgMECWorker.o \ + ${OBJECTDIR}/GpgMEWorker.o \ + ${OBJECTDIR}/K7Main.o \ + ${OBJECTDIR}/PopupDeleter.o \ + ${OBJECTDIR}/PopupUploader.o \ + ${OBJECTDIR}/TransientMessageWidget.o \ + ${OBJECTDIR}/main.o + + +# C Compiler Flags +CFLAGS= + +# CC Compiler Flags +CCFLAGS=-Wno-deprecated -Wno-deprecated-declarations +CXXFLAGS=-Wno-deprecated -Wno-deprecated-declarations + +# Fortran Compiler Flags +FFLAGS= + +# Assembler Flags +ASFLAGS= + +# Link Libraries and Options +LDLIBSOPTIONS=-L/usr/local/Wt-Debug/lib -lwtd -lwthttpd -lgpgmepp -lgpgme + +# Build Targets +.build-conf: ${BUILD_SUBPROJECTS} + "${MAKE}" -f nbproject/Makefile-${CND_CONF}.mk ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/k7 + +${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/k7: ${OBJECTFILES} + ${MKDIR} -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM} + ${LINK.cc} -o ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/k7 ${OBJECTFILES} ${LDLIBSOPTIONS} + +${OBJECTDIR}/AppConfig.o: AppConfig.cpp + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEVTIME -I/usr/local/Wt-Debug/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/AppConfig.o AppConfig.cpp + +${OBJECTDIR}/GpgMECWorker.o: GpgMECWorker.cpp + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEVTIME -I/usr/local/Wt-Debug/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/GpgMECWorker.o GpgMECWorker.cpp + +${OBJECTDIR}/GpgMEWorker.o: GpgMEWorker.cpp + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEVTIME -I/usr/local/Wt-Debug/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/GpgMEWorker.o GpgMEWorker.cpp + +${OBJECTDIR}/K7Main.o: K7Main.cpp + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEVTIME -I/usr/local/Wt-Debug/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/K7Main.o K7Main.cpp + +${OBJECTDIR}/PopupDeleter.o: PopupDeleter.cpp + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEVTIME -I/usr/local/Wt-Debug/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/PopupDeleter.o PopupDeleter.cpp + +${OBJECTDIR}/PopupUploader.o: PopupUploader.cpp + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEVTIME -I/usr/local/Wt-Debug/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/PopupUploader.o PopupUploader.cpp + +${OBJECTDIR}/TransientMessageWidget.o: TransientMessageWidget.cpp + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEVTIME -I/usr/local/Wt-Debug/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/TransientMessageWidget.o TransientMessageWidget.cpp + +${OBJECTDIR}/main.o: main.cpp + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -g -DDEVTIME -I/usr/local/Wt-Debug/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/main.o main.cpp + +# Subprojects +.build-subprojects: + +# Clean Targets +.clean-conf: ${CLEAN_SUBPROJECTS} + ${RM} -r ${CND_BUILDDIR}/${CND_CONF} + +# Subprojects +.clean-subprojects: + +# Enable dependency checking +.dep.inc: .depcheck-impl + +include .dep.inc diff --git a/nbproject/Makefile-Release.mk b/nbproject/Makefile-Release.mk new file mode 100644 index 0000000..1293e5c --- /dev/null +++ b/nbproject/Makefile-Release.mk @@ -0,0 +1,125 @@ +# +# Generated Makefile - do not edit! +# +# Edit the Makefile in the project folder instead (../Makefile). Each target +# has a -pre and a -post target defined where you can add customized code. +# +# This makefile implements configuration specific macros and targets. + + +# Environment +MKDIR=mkdir +CP=cp +GREP=grep +NM=nm +CCADMIN=CCadmin +RANLIB=ranlib +CC=gcc +CCC=g++ +CXX=g++ +FC=gfortran +AS=as + +# Macros +CND_PLATFORM=GNU-Linux +CND_DLIB_EXT=so +CND_CONF=Release +CND_DISTDIR=dist +CND_BUILDDIR=build + +# Include project Makefile +include Makefile + +# Object Directory +OBJECTDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM} + +# Object Files +OBJECTFILES= \ + ${OBJECTDIR}/AppConfig.o \ + ${OBJECTDIR}/GpgMECWorker.o \ + ${OBJECTDIR}/GpgMEWorker.o \ + ${OBJECTDIR}/K7Main.o \ + ${OBJECTDIR}/PopupDeleter.o \ + ${OBJECTDIR}/PopupUploader.o \ + ${OBJECTDIR}/TransientMessageWidget.o \ + ${OBJECTDIR}/main.o + + +# C Compiler Flags +CFLAGS= + +# CC Compiler Flags +CCFLAGS=-Wno-deprecated -Wno-deprecated-declarations +CXXFLAGS=-Wno-deprecated -Wno-deprecated-declarations + +# Fortran Compiler Flags +FFLAGS= + +# Assembler Flags +ASFLAGS= + +# Link Libraries and Options +LDLIBSOPTIONS=-L/usr/local/Wt/lib -lwt -lwtfcgi -lgpgmepp -lgpgme + +# Build Targets +.build-conf: ${BUILD_SUBPROJECTS} + "${MAKE}" -f nbproject/Makefile-${CND_CONF}.mk ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/k7 + +${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/k7: ${OBJECTFILES} + ${MKDIR} -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM} + ${LINK.cc} -o ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/k7 ${OBJECTFILES} ${LDLIBSOPTIONS} -s + +${OBJECTDIR}/AppConfig.o: AppConfig.cpp + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -O2 -s -I/usr/local/Wt/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/AppConfig.o AppConfig.cpp + +${OBJECTDIR}/GpgMECWorker.o: GpgMECWorker.cpp + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -O2 -s -I/usr/local/Wt/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/GpgMECWorker.o GpgMECWorker.cpp + +${OBJECTDIR}/GpgMEWorker.o: GpgMEWorker.cpp + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -O2 -s -I/usr/local/Wt/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/GpgMEWorker.o GpgMEWorker.cpp + +${OBJECTDIR}/K7Main.o: K7Main.cpp + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -O2 -s -I/usr/local/Wt/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/K7Main.o K7Main.cpp + +${OBJECTDIR}/PopupDeleter.o: PopupDeleter.cpp + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -O2 -s -I/usr/local/Wt/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/PopupDeleter.o PopupDeleter.cpp + +${OBJECTDIR}/PopupUploader.o: PopupUploader.cpp + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -O2 -s -I/usr/local/Wt/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/PopupUploader.o PopupUploader.cpp + +${OBJECTDIR}/TransientMessageWidget.o: TransientMessageWidget.cpp + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -O2 -s -I/usr/local/Wt/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/TransientMessageWidget.o TransientMessageWidget.cpp + +${OBJECTDIR}/main.o: main.cpp + ${MKDIR} -p ${OBJECTDIR} + ${RM} "$@.d" + $(COMPILE.cc) -O2 -s -I/usr/local/Wt/include -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/main.o main.cpp + +# Subprojects +.build-subprojects: + +# Clean Targets +.clean-conf: ${CLEAN_SUBPROJECTS} + ${RM} -r ${CND_BUILDDIR}/${CND_CONF} + +# Subprojects +.clean-subprojects: + +# Enable dependency checking +.dep.inc: .depcheck-impl + +include .dep.inc diff --git a/nbproject/Makefile-impl.mk b/nbproject/Makefile-impl.mk new file mode 100644 index 0000000..68cd4d4 --- /dev/null +++ b/nbproject/Makefile-impl.mk @@ -0,0 +1,133 @@ +# +# Generated Makefile - do not edit! +# +# Edit the Makefile in the project folder instead (../Makefile). Each target +# has a pre- and a post- target defined where you can add customization code. +# +# This makefile implements macros and targets common to all configurations. +# +# NOCDDL + + +# Building and Cleaning subprojects are done by default, but can be controlled with the SUB +# macro. If SUB=no, subprojects will not be built or cleaned. The following macro +# statements set BUILD_SUB-CONF and CLEAN_SUB-CONF to .build-reqprojects-conf +# and .clean-reqprojects-conf unless SUB has the value 'no' +SUB_no=NO +SUBPROJECTS=${SUB_${SUB}} +BUILD_SUBPROJECTS_=.build-subprojects +BUILD_SUBPROJECTS_NO= +BUILD_SUBPROJECTS=${BUILD_SUBPROJECTS_${SUBPROJECTS}} +CLEAN_SUBPROJECTS_=.clean-subprojects +CLEAN_SUBPROJECTS_NO= +CLEAN_SUBPROJECTS=${CLEAN_SUBPROJECTS_${SUBPROJECTS}} + + +# Project Name +PROJECTNAME=K7 + +# Active Configuration +DEFAULTCONF=Debug +CONF=${DEFAULTCONF} + +# All Configurations +ALLCONFS=Debug Release ARM-Release + + +# build +.build-impl: .build-pre .validate-impl .depcheck-impl + @#echo "=> Running $@... Configuration=$(CONF)" + "${MAKE}" -f nbproject/Makefile-${CONF}.mk QMAKE=${QMAKE} SUBPROJECTS=${SUBPROJECTS} .build-conf + + +# clean +.clean-impl: .clean-pre .validate-impl .depcheck-impl + @#echo "=> Running $@... Configuration=$(CONF)" + "${MAKE}" -f nbproject/Makefile-${CONF}.mk QMAKE=${QMAKE} SUBPROJECTS=${SUBPROJECTS} .clean-conf + + +# clobber +.clobber-impl: .clobber-pre .depcheck-impl + @#echo "=> Running $@..." + for CONF in ${ALLCONFS}; \ + do \ + "${MAKE}" -f nbproject/Makefile-$${CONF}.mk QMAKE=${QMAKE} SUBPROJECTS=${SUBPROJECTS} .clean-conf; \ + done + +# all +.all-impl: .all-pre .depcheck-impl + @#echo "=> Running $@..." + for CONF in ${ALLCONFS}; \ + do \ + "${MAKE}" -f nbproject/Makefile-$${CONF}.mk QMAKE=${QMAKE} SUBPROJECTS=${SUBPROJECTS} .build-conf; \ + done + +# build tests +.build-tests-impl: .build-impl .build-tests-pre + @#echo "=> Running $@... Configuration=$(CONF)" + "${MAKE}" -f nbproject/Makefile-${CONF}.mk SUBPROJECTS=${SUBPROJECTS} .build-tests-conf + +# run tests +.test-impl: .build-tests-impl .test-pre + @#echo "=> Running $@... Configuration=$(CONF)" + "${MAKE}" -f nbproject/Makefile-${CONF}.mk SUBPROJECTS=${SUBPROJECTS} .test-conf + +# dependency checking support +.depcheck-impl: + @echo "# This code depends on make tool being used" >.dep.inc + @if [ -n "${MAKE_VERSION}" ]; then \ + echo "DEPFILES=\$$(wildcard \$$(addsuffix .d, \$${OBJECTFILES} \$${TESTOBJECTFILES}))" >>.dep.inc; \ + echo "ifneq (\$${DEPFILES},)" >>.dep.inc; \ + echo "include \$${DEPFILES}" >>.dep.inc; \ + echo "endif" >>.dep.inc; \ + else \ + echo ".KEEP_STATE:" >>.dep.inc; \ + echo ".KEEP_STATE_FILE:.make.state.\$${CONF}" >>.dep.inc; \ + fi + +# configuration validation +.validate-impl: + @if [ ! -f nbproject/Makefile-${CONF}.mk ]; \ + then \ + echo ""; \ + echo "Error: can not find the makefile for configuration '${CONF}' in project ${PROJECTNAME}"; \ + echo "See 'make help' for details."; \ + echo "Current directory: " `pwd`; \ + echo ""; \ + fi + @if [ ! -f nbproject/Makefile-${CONF}.mk ]; \ + then \ + exit 1; \ + fi + + +# help +.help-impl: .help-pre + @echo "This makefile supports the following configurations:" + @echo " ${ALLCONFS}" + @echo "" + @echo "and the following targets:" + @echo " build (default target)" + @echo " clean" + @echo " clobber" + @echo " all" + @echo " help" + @echo "" + @echo "Makefile Usage:" + @echo " make [CONF=] [SUB=no] build" + @echo " make [CONF=] [SUB=no] clean" + @echo " make [SUB=no] clobber" + @echo " make [SUB=no] all" + @echo " make help" + @echo "" + @echo "Target 'build' will build a specific configuration and, unless 'SUB=no'," + @echo " also build subprojects." + @echo "Target 'clean' will clean a specific configuration and, unless 'SUB=no'," + @echo " also clean subprojects." + @echo "Target 'clobber' will remove all built files from all configurations and," + @echo " unless 'SUB=no', also from subprojects." + @echo "Target 'all' will will build all configurations and, unless 'SUB=no'," + @echo " also build subprojects." + @echo "Target 'help' prints this message." + @echo "" + diff --git a/nbproject/Makefile-variables.mk b/nbproject/Makefile-variables.mk new file mode 100644 index 0000000..19bf140 --- /dev/null +++ b/nbproject/Makefile-variables.mk @@ -0,0 +1,43 @@ +# +# Generated - do not edit! +# +# NOCDDL +# +CND_BASEDIR=`pwd` +CND_BUILDDIR=build +CND_DISTDIR=dist +# Debug configuration +CND_PLATFORM_Debug=GNU-Linux +CND_ARTIFACT_DIR_Debug=dist/Debug/GNU-Linux +CND_ARTIFACT_NAME_Debug=k7 +CND_ARTIFACT_PATH_Debug=dist/Debug/GNU-Linux/k7 +CND_PACKAGE_DIR_Debug=dist/Debug/GNU-Linux/package +CND_PACKAGE_NAME_Debug=k7.tar +CND_PACKAGE_PATH_Debug=dist/Debug/GNU-Linux/package/k7.tar +# Release configuration +CND_PLATFORM_Release=GNU-Linux +CND_ARTIFACT_DIR_Release=dist/Release/GNU-Linux +CND_ARTIFACT_NAME_Release=k7 +CND_ARTIFACT_PATH_Release=dist/Release/GNU-Linux/k7 +CND_PACKAGE_DIR_Release=dist/Release/GNU-Linux/package +CND_PACKAGE_NAME_Release=k7.tar +CND_PACKAGE_PATH_Release=dist/Release/GNU-Linux/package/k7.tar +# ARM-Release configuration +CND_PLATFORM_ARM-Release=GNU-Linux +CND_ARTIFACT_DIR_ARM-Release=dist/ARM-Release/GNU-Linux +CND_ARTIFACT_NAME_ARM-Release=k7 +CND_ARTIFACT_PATH_ARM-Release=dist/ARM-Release/GNU-Linux/k7 +CND_PACKAGE_DIR_ARM-Release=dist/ARM-Release/GNU-Linux/package +CND_PACKAGE_NAME_ARM-Release=k7.tar +CND_PACKAGE_PATH_ARM-Release=dist/ARM-Release/GNU-Linux/package/k7.tar +# +# include compiler specific variables +# +# dmake command +ROOT:sh = test -f nbproject/private/Makefile-variables.mk || \ + (mkdir -p nbproject/private && touch nbproject/private/Makefile-variables.mk) +# +# gmake command +.PHONY: $(shell test -f nbproject/private/Makefile-variables.mk || (mkdir -p nbproject/private && touch nbproject/private/Makefile-variables.mk)) +# +include nbproject/private/Makefile-variables.mk diff --git a/nbproject/Package-ARM-Release.bash b/nbproject/Package-ARM-Release.bash new file mode 100644 index 0000000..6f944f8 --- /dev/null +++ b/nbproject/Package-ARM-Release.bash @@ -0,0 +1,76 @@ +#!/bin/bash -x + +# +# Generated - do not edit! +# + +# Macros +TOP=`pwd` +CND_PLATFORM=GNU-Linux +CND_CONF=ARM-Release +CND_DISTDIR=dist +CND_BUILDDIR=build +CND_DLIB_EXT=so +NBTMPDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}/tmp-packaging +TMPDIRNAME=tmp-packaging +OUTPUT_PATH=${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/k7 +OUTPUT_BASENAME=k7 +PACKAGE_TOP_DIR=k7/ + +# Functions +function checkReturnCode +{ + rc=$? + if [ $rc != 0 ] + then + exit $rc + fi +} +function makeDirectory +# $1 directory path +# $2 permission (optional) +{ + mkdir -p "$1" + checkReturnCode + if [ "$2" != "" ] + then + chmod $2 "$1" + checkReturnCode + fi +} +function copyFileToTmpDir +# $1 from-file path +# $2 to-file path +# $3 permission +{ + cp "$1" "$2" + checkReturnCode + if [ "$3" != "" ] + then + chmod $3 "$2" + checkReturnCode + fi +} + +# Setup +cd "${TOP}" +mkdir -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package +rm -rf ${NBTMPDIR} +mkdir -p ${NBTMPDIR} + +# Copy files and create directories and links +cd "${TOP}" +makeDirectory "${NBTMPDIR}/k7/bin" +copyFileToTmpDir "${OUTPUT_PATH}" "${NBTMPDIR}/${PACKAGE_TOP_DIR}bin/${OUTPUT_BASENAME}" 0755 + + +# Generate tar file +cd "${TOP}" +rm -f ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/k7.tar +cd ${NBTMPDIR} +tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/k7.tar * +checkReturnCode + +# Cleanup +cd "${TOP}" +rm -rf ${NBTMPDIR} diff --git a/nbproject/Package-Debug.bash b/nbproject/Package-Debug.bash new file mode 100644 index 0000000..a66a45a --- /dev/null +++ b/nbproject/Package-Debug.bash @@ -0,0 +1,76 @@ +#!/bin/bash -x + +# +# Generated - do not edit! +# + +# Macros +TOP=`pwd` +CND_PLATFORM=GNU-Linux +CND_CONF=Debug +CND_DISTDIR=dist +CND_BUILDDIR=build +CND_DLIB_EXT=so +NBTMPDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}/tmp-packaging +TMPDIRNAME=tmp-packaging +OUTPUT_PATH=${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/k7 +OUTPUT_BASENAME=k7 +PACKAGE_TOP_DIR=k7/ + +# Functions +function checkReturnCode +{ + rc=$? + if [ $rc != 0 ] + then + exit $rc + fi +} +function makeDirectory +# $1 directory path +# $2 permission (optional) +{ + mkdir -p "$1" + checkReturnCode + if [ "$2" != "" ] + then + chmod $2 "$1" + checkReturnCode + fi +} +function copyFileToTmpDir +# $1 from-file path +# $2 to-file path +# $3 permission +{ + cp "$1" "$2" + checkReturnCode + if [ "$3" != "" ] + then + chmod $3 "$2" + checkReturnCode + fi +} + +# Setup +cd "${TOP}" +mkdir -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package +rm -rf ${NBTMPDIR} +mkdir -p ${NBTMPDIR} + +# Copy files and create directories and links +cd "${TOP}" +makeDirectory "${NBTMPDIR}/k7/bin" +copyFileToTmpDir "${OUTPUT_PATH}" "${NBTMPDIR}/${PACKAGE_TOP_DIR}bin/${OUTPUT_BASENAME}" 0755 + + +# Generate tar file +cd "${TOP}" +rm -f ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/k7.tar +cd ${NBTMPDIR} +tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/k7.tar * +checkReturnCode + +# Cleanup +cd "${TOP}" +rm -rf ${NBTMPDIR} diff --git a/nbproject/Package-Release.bash b/nbproject/Package-Release.bash new file mode 100644 index 0000000..2dcd6aa --- /dev/null +++ b/nbproject/Package-Release.bash @@ -0,0 +1,76 @@ +#!/bin/bash -x + +# +# Generated - do not edit! +# + +# Macros +TOP=`pwd` +CND_PLATFORM=GNU-Linux +CND_CONF=Release +CND_DISTDIR=dist +CND_BUILDDIR=build +CND_DLIB_EXT=so +NBTMPDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}/tmp-packaging +TMPDIRNAME=tmp-packaging +OUTPUT_PATH=${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/k7 +OUTPUT_BASENAME=k7 +PACKAGE_TOP_DIR=k7/ + +# Functions +function checkReturnCode +{ + rc=$? + if [ $rc != 0 ] + then + exit $rc + fi +} +function makeDirectory +# $1 directory path +# $2 permission (optional) +{ + mkdir -p "$1" + checkReturnCode + if [ "$2" != "" ] + then + chmod $2 "$1" + checkReturnCode + fi +} +function copyFileToTmpDir +# $1 from-file path +# $2 to-file path +# $3 permission +{ + cp "$1" "$2" + checkReturnCode + if [ "$3" != "" ] + then + chmod $3 "$2" + checkReturnCode + fi +} + +# Setup +cd "${TOP}" +mkdir -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package +rm -rf ${NBTMPDIR} +mkdir -p ${NBTMPDIR} + +# Copy files and create directories and links +cd "${TOP}" +makeDirectory "${NBTMPDIR}/k7/bin" +copyFileToTmpDir "${OUTPUT_PATH}" "${NBTMPDIR}/${PACKAGE_TOP_DIR}bin/${OUTPUT_BASENAME}" 0755 + + +# Generate tar file +cd "${TOP}" +rm -f ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/k7.tar +cd ${NBTMPDIR} +tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/package/k7.tar * +checkReturnCode + +# Cleanup +cd "${TOP}" +rm -rf ${NBTMPDIR} diff --git a/nbproject/configurations.xml b/nbproject/configurations.xml new file mode 100644 index 0000000..51be029 --- /dev/null +++ b/nbproject/configurations.xml @@ -0,0 +1,268 @@ + + + + + AppConfig.h + GpgMECWorker.h + GpgMEWorker.h + K7Main.h + PopupDeleter.h + PopupUploader.h + TransientMessageWidget.h + global.h + + + WTAPPROOT/K7/K7.xml + WTAPPROOT/K7/K7_fr.xml + + + AppConfig.cpp + GpgMECWorker.cpp + GpgMEWorker.cpp + K7Main.cpp + PopupDeleter.cpp + PopupUploader.cpp + TransientMessageWidget.cpp + main.cpp + + + + + Makefile + + + Makefile + + + + default + true + false + + + + + /usr/local/Wt-Debug/include + + -Wno-deprecated -Wno-deprecated-declarations + + DEVTIME + + + + + /usr/local/Wt-Debug/lib + + + wtd + wthttpd + gpgmepp + gpgme + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + default + true + false + + + + 5 + true + + + 5 + true + + /usr/local/Wt/include + + -Wno-deprecated -Wno-deprecated-declarations + + + 5 + + + 5 + + + + /usr/local/Wt/lib + + true + + wt + wtfcgi + gpgmepp + gpgme + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + default + true + false + + + + 5 + true + + + 5 + true + + /usr/local/Wt/include + + -Wno-deprecated -Wno-deprecated-declarations + + LARGEFILE_SOURCE=1 + _FILE_OFFSET_BITS=64 + + + + 5 + + + 5 + + + + /usr/local/Wt/lib + + true + + wt + wtfcgi + gpgmepp + gpgme + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/nbproject/private/Makefile-variables.mk b/nbproject/private/Makefile-variables.mk new file mode 100644 index 0000000..2ed1418 --- /dev/null +++ b/nbproject/private/Makefile-variables.mk @@ -0,0 +1,8 @@ +# +# Generated - do not edit! +# +# NOCDDL +# +# Debug configuration +# Release configuration +# ARM-Release configuration diff --git a/nbproject/private/c_standard_headers_indexer.c b/nbproject/private/c_standard_headers_indexer.c new file mode 100644 index 0000000..c2548d2 --- /dev/null +++ b/nbproject/private/c_standard_headers_indexer.c @@ -0,0 +1,75 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + */ + +// List of standard headers was taken in http://en.cppreference.com/w/c/header + +#include // Conditionally compiled macro that compares its argument to zero +#include // Functions to determine the type contained in character data +#include // Macros reporting error conditions +#include // Limits of float types +#include // Sizes of basic types +#include // Localization utilities +#include // Common mathematics functions +#include // Nonlocal jumps +#include // Signal handling +#include // Variable arguments +#include // Common macro definitions +#include // Input/output +#include // String handling +#include // General utilities: memory management, program utilities, string conversions, random numbers +#include // Time/date utilities +#include // (since C95) Alternative operator spellings +#include // (since C95) Extended multibyte and wide character utilities +#include // (since C95) Wide character classification and mapping utilities +#ifdef _STDC_C99 +#include // (since C99) Complex number arithmetic +#include // (since C99) Floating-point environment +#include // (since C99) Format conversion of integer types +#include // (since C99) Boolean type +#include // (since C99) Fixed-width integer types +#include // (since C99) Type-generic math (macros wrapping math.h and complex.h) +#endif +#ifdef _STDC_C11 +#include // (since C11) alignas and alignof convenience macros +#include // (since C11) Atomic types +#include // (since C11) noreturn convenience macros +#include // (since C11) Thread library +#include // (since C11) UTF-16 and UTF-32 character utilities +#endif diff --git a/nbproject/private/configurations.xml b/nbproject/private/configurations.xml new file mode 100644 index 0000000..c6b9916 --- /dev/null +++ b/nbproject/private/configurations.xml @@ -0,0 +1,114 @@ + + + Makefile + + + + localhost + 2 + + + + + + + + + + + + + + + gdb + + + + "${OUTPUT_PATH}" + "${OUTPUT_PATH}" --docroot . --https-address localhost --https-port 8080 --ssl-client-verification required --ssl-ca-certificates /home/user/tmp/ca.crt --ssl-certificate /home/user/tmp/cert.pem --ssl-private-key /home/user/tmp/cert.key --ssl-tmp-dh /home/user/tmp/dh.pem + + "${OUTPUT_PATH}" --docroot . --https-address localhost --https-port 8080 --ssl-client-verification required --ssl-ca-certificates /home/user/tmp/ca.crt --ssl-certificate /home/user/tmp/cert.pem --ssl-private-key /home/user/tmp/cert.key --ssl-tmp-dh /home/user/tmp/dh.pem + + true + 0 + 0 + + + + + + + + + localhost + 2 + + + + + + + + + + + + + + + gdb + + + + "${OUTPUT_PATH}" + "${OUTPUT_PATH}" --docroot . --https-address localhost --https-port 8080 --ssl-client-verification required --ssl-ca-certificates /home/user/tmp/ca.crt --ssl-certificate /home/user/tmp/cert.pem --ssl-private-key /home/user/tmp/cert.key --ssl-tmp-dh /home/user/tmp/dh.pem + + "${OUTPUT_PATH}" --docroot . --https-address localhost --https-port 8080 --ssl-client-verification required --ssl-ca-certificates /home/user/tmp/ca.crt --ssl-certificate /home/user/tmp/cert.pem --ssl-private-key /home/user/tmp/cert.key --ssl-tmp-dh /home/user/tmp/dh.pem + + true + 0 + 0 + + + + + + + + + localhost + 2 + + + + + + + + + + + + + + + gdb + + + + "${OUTPUT_PATH}" + "${OUTPUT_PATH}" --docroot . --https-address localhost --https-port 8080 --ssl-client-verification required --ssl-ca-certificates /home/user/tmp/ca.crt --ssl-certificate /home/user/tmp/cert.pem --ssl-private-key /home/user/tmp/cert.key --ssl-tmp-dh /home/user/tmp/dh.pem + + "${OUTPUT_PATH}" --docroot . --https-address localhost --https-port 8080 --ssl-client-verification required --ssl-ca-certificates /home/user/tmp/ca.crt --ssl-certificate /home/user/tmp/cert.pem --ssl-private-key /home/user/tmp/cert.key --ssl-tmp-dh /home/user/tmp/dh.pem + + true + 0 + 0 + + + + + + + + diff --git a/nbproject/private/cpp_standard_headers_indexer.cpp b/nbproject/private/cpp_standard_headers_indexer.cpp new file mode 100644 index 0000000..04f6fa6 --- /dev/null +++ b/nbproject/private/cpp_standard_headers_indexer.cpp @@ -0,0 +1,135 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + */ + +// List of standard headers was taken in http://en.cppreference.com/w/cpp/header + +#include // General purpose utilities: program control, dynamic memory allocation, random numbers, sort and search +#include // Functions and macro constants for signal management +#include // Macro (and function) that saves (and jumps) to an execution context +#include // Handling of variable length argument lists +#include // Runtime type information utilities +#include // std::bitset class template +#include // Function objects, designed for use with the standard algorithms +#include // Various utility components +#include // C-style time/date utilites +#include // typedefs for types such as size_t, NULL and others +#include // Low-level memory management utilities +#include // Higher level memory management utilities +#include // limits of integral types +#include // limits of float types +#include // standardized way to query properties of arithmetic types +#include // Exception handling utilities +#include // Standard exception objects +#include // Conditionally compiled macro that compares its argument to zero +#include // Macro containing the last error number +#include // functions to determine the type contained in character data +#include // functions for determining the type of wide character data +#include // various narrow character string handling functions +#include // various wide and multibyte string handling functions +#include // std::basic_string class template +#include // std::vector container +#include // std::deque container +#include // std::list container +#include // std::set and std::multiset associative containers +#include // std::map and std::multimap associative containers +#include // std::stack container adaptor +#include // std::queue and std::priority_queue container adaptors +#include // Algorithms that operate on containers +#include // Container iterators +#include // Common mathematics functions +#include // Complex number type +#include // Class for representing and manipulating arrays of values +#include // Numeric operations on values in containers +#include // forward declarations of all classes in the input/output library +#include // std::ios_base class, std::basic_ios class template and several typedefs +#include // std::basic_istream class template and several typedefs +#include // std::basic_ostream, std::basic_iostream class templates and several typedefs +#include // several standard stream objects +#include // std::basic_fstream, std::basic_ifstream, std::basic_ofstream class templates and several typedefs +#include // std::basic_stringstream, std::basic_istringstream, std::basic_ostringstream class templates and several typedefs +#include // std::strstream, std::istrstream, std::ostrstream(deprecated) +#include // Helper functions to control the format or input and output +#include // std::basic_streambuf class template +#include // C-style input-output functions +#include // Localization utilities +#include // C localization utilities +#include // empty header. The macros that appear in iso646.h in C are keywords in C++ +#if __cplusplus >= 201103L +#include // (since C++11) std::type_index +#include // (since C++11) Compile-time type information +#include // (since C++11) C++ time utilites +#include // (since C++11) std::initializer_list class template +#include // (since C++11) std::tuple class template +#include // (since C++11) Nested allocator class +#include // (since C++11) fixed-size types and limits of other types +#include // (since C++11) formatting macros , intmax_t and uintmax_t math and conversions +#include // (since C++11) defines std::error_code, a platform-dependent error code +#include // (since C++11) C-style Unicode character conversion functions +#include // (since C++11) std::array container +#include // (since C++11) std::forward_list container +#include // (since C++11) std::unordered_set and std::unordered_multiset unordered associative containers +#include // (since C++11) std::unordered_map and std::unordered_multimap unordered associative containers +#include // (since C++11) Random number generators and distributions +#include // (since C++11) Compile-time rational arithmetic +#include // (since C++11) Floating-point environment access functions +#include // (since C++11) Unicode conversion facilities +#include // (since C++11) Classes, algorithms and iterators to support regular expression processing +#include // (since C++11) Atomic operations library +#include // (since C++11)(deprecated in C++17) simply includes the header +#include // (since C++11)(deprecated in C++17) simply includes the headers (until C++17) (since C++17) and : the overloads equivalent to the contents of the C header tgmath.h are already provided by those headers +#include // (since C++11)(deprecated in C++17) defines one compatibility macro constant +#include // (since C++11)(deprecated in C++17) defines one compatibility macro constant +#include // (since C++11) std::thread class and supporting functions +#include // (since C++11) mutual exclusion primitives +#include // (since C++11) primitives for asynchronous computations +#include // (since C++11) thread waiting conditions +#endif +#if __cplusplus >= 201300L +#include // (since C++14) shared mutual exclusion primitives +#endif +#if __cplusplus >= 201500L +#include // (since C++17) std::any class template +#include // (since C++17) std::optional class template +#include // (since C++17) std::variant class template +#include // (since C++17) Polymorphic allocators and memory resources +#include // (since C++17) std::basic_string_view class template +#include // (since C++17) Predefined execution policies for parallel versions of the algorithms +#include // (since C++17) std::path class and supporting functions +#endif diff --git a/nbproject/private/launcher.properties b/nbproject/private/launcher.properties new file mode 100644 index 0000000..3edc2d8 --- /dev/null +++ b/nbproject/private/launcher.properties @@ -0,0 +1,42 @@ +# Launchers File syntax: +# +# [Must-have property line] +# launcher1.runCommand= +# [Optional extra properties] +# launcher1.displayName= +# launcher1.hide= +# launcher1.buildCommand= +# launcher1.runDir= +# launcher1.runInOwnTab= +# launcher1.symbolFiles= +# launcher1.env.= +# (If this value is quoted with ` it is handled as a native command which execution result will become the value) +# [Common launcher properties] +# common.runDir= +# (This value is overwritten by a launcher specific runDir value if the latter exists) +# common.env.= +# (Environment variables from common launcher are merged with launcher specific variables) +# common.symbolFiles= +# (This value is overwritten by a launcher specific symbolFiles value if the latter exists) +# +# In runDir, symbolFiles and env fields you can use these macroses: +# ${PROJECT_DIR} - project directory absolute path +# ${OUTPUT_PATH} - linker output path (relative to project directory path) +# ${OUTPUT_BASENAME}- linker output filename +# ${TESTDIR} - test files directory (relative to project directory path) +# ${OBJECTDIR} - object files directory (relative to project directory path) +# ${CND_DISTDIR} - distribution directory (relative to project directory path) +# ${CND_BUILDDIR} - build directory (relative to project directory path) +# ${CND_PLATFORM} - platform name +# ${CND_CONF} - configuration name +# ${CND_DLIB_EXT} - dynamic library extension +# +# All the project launchers must be listed in the file! +# +# launcher1.runCommand=... +# launcher2.runCommand=... +# ... +# common.runDir=... +# common.env.KEY=VALUE + +# launcher1.runCommand= \ No newline at end of file diff --git a/nbproject/private/private.xml b/nbproject/private/private.xml new file mode 100644 index 0000000..ca16eb4 --- /dev/null +++ b/nbproject/private/private.xml @@ -0,0 +1,15 @@ + + + + 1 + 0 + + + + + file:/home/user/tmp/cpp/WTProjects/K7/main.cpp + file:/home/user/tmp/cpp/WTProjects/K7/K7Main.h + file:/home/user/tmp/cpp/WTProjects/K7/K7Main.cpp + + + diff --git a/nbproject/project.xml b/nbproject/project.xml new file mode 100644 index 0000000..8103df2 --- /dev/null +++ b/nbproject/project.xml @@ -0,0 +1,35 @@ + + + org.netbeans.modules.cnd.makeproject + + + K7 + + cpp + h + UTF-8 + + + + + Debug + 1 + + + Release + 1 + + + ARM-Release + 1 + + + + true + ANSI|ANSI + ANSI|ANSI + ANSI|ANSI + + + + diff --git a/resources b/resources new file mode 120000 index 0000000..00dac7e --- /dev/null +++ b/resources @@ -0,0 +1 @@ +/usr/local/Wt/share/Wt/resources \ No newline at end of file