src: Removed everything license key related

* removed license check
* removed license from ApplicationSettings
* removed LicenseGenerator
* removed license tests
* removed lib_license
* removed dependency on Botan
* removed license generation in all scripts
This commit is contained in:
Eberhard Graether
2019-10-18 13:05:30 +02:00
parent 2cfce03f6e
commit 0d8e992bdf
61 changed files with 63 additions and 3639 deletions
+1
View File
@@ -1,6 +1,7 @@
#include "includes.h"
#include <csignal>
#include <iostream>
#include "Application.h"
#include "ApplicationSettings.h"
+2
View File
@@ -680,4 +680,6 @@ add_files(
utility/utilityWindows.h
utility/utilityXml.cpp
utility/utilityXml.h
utility/Version.cpp
utility/Version.h
)
+1 -53
View File
@@ -7,7 +7,6 @@
#include "FileSystem.h"
#include "GraphViewStyle.h"
#include "IDECommunicationController.h"
#include "LicenseChecker.h"
#include "logging.h"
#include "LogManager.h"
#include "MainView.h"
@@ -42,8 +41,6 @@ void Application::createInstance(
bool hasGui = (viewFactory != nullptr);
Version::setApplicationVersion(version);
LicenseChecker::loadPublicKey();
LicenseChecker::setEncodeKey(AppPath::getAppPath().str());
if (hasGui)
{
@@ -128,7 +125,6 @@ void Application::loadStyle(const FilePath& colorSchemePath)
Application::Application(bool withGUI)
: m_hasGUI(withGUI)
, m_lastLicenseCheck(TimeStamp::now())
{
}
@@ -362,17 +358,6 @@ void Application::handleMessage(MessageWindowFocus* message)
{
m_updateChecker->checkUpdate();
}
if (!ApplicationSettings::getInstance()->getNonCommercialUse() && TimeStamp::now().deltaHours(m_lastLicenseCheck) > 1)
{
m_lastLicenseCheck = TimeStamp::now();
LicenseChecker::LicenseState state = LicenseChecker::checkCurrentLicense();
if (state != LicenseChecker::LicenseState::VALID)
{
m_mainView->forceEnterLicense(LicenseChecker::getLicenseErrorForState(state));
}
}
}
FilePath Application::migrateProjectSettings(const FilePath& projectSettingsFilePath) const
@@ -437,36 +422,11 @@ void Application::loadWindow(bool showStartWindow)
appSettings->save();
}
LicenseChecker::LicenseState state = LicenseChecker::LicenseState::VALID;
std::string licenseError;
if (!appSettings->getNonCommercialUse())
{
state = LicenseChecker::setCurrentLicenseStringEncoded(appSettings->getLicenseString());
licenseError = LicenseChecker::getLicenseErrorForState(state);
if (state == LicenseChecker::LicenseState::VALID)
{
MessageStatus(L"Found valid license key, unlocked application.").dispatch();
}
else if (state == LicenseChecker::LicenseState::EMPTY)
{
licenseError = "";
}
else if (state == LicenseChecker::LicenseState::MALFORMED)
{
licenseError = "Plese re-enter your license key.";
appSettings->setLicenseString("");
appSettings->save();
}
}
updateTitle();
bool showEula = (EULA_ACCEPT_REQUIRED && appSettings->getAcceptedEulaVersion() < EULA_VERSION);
bool enterLicense = (state != LicenseChecker::LicenseState::VALID);
m_mainView->loadWindow(showStartWindow, showEula, enterLicense, licenseError);
m_mainView->loadWindow(showStartWindow, showEula);
m_loadedWindow = true;
}
else if (!showStartWindow)
@@ -550,18 +510,6 @@ void Application::updateTitle()
{
std::wstring title = L"Sourcetrail";
switch (LicenseChecker::getCurrentLicenseType())
{
case LicenseType::TEST:
title += L" [test]";
break;
case LicenseType::NON_COMMERCIAL:
title += L" [non-commercial]";
break;
case LicenseType::COMMERCIAL:
break;
}
if (m_project)
{
FilePath projectPath = m_project->getProjectSettingsFilePath();
-3
View File
@@ -14,7 +14,6 @@
#include "MessageSwitchColorScheme.h"
#include "MessageWindowFocus.h"
#include "Project.h"
#include "TimeStamp.h"
class Bookmark;
class IDECommunicationController;
@@ -102,8 +101,6 @@ private:
std::shared_ptr<IDECommunicationController> m_ideCommunicationController;
std::shared_ptr<UpdateChecker> m_updateChecker;
TimeStamp m_lastLicenseCheck;
};
#endif // APPLICATION_H
+1 -2
View File
@@ -32,12 +32,11 @@ public:
virtual void refreshView() = 0;
virtual void loadWindow(bool showStartWindow, bool showEULA, bool enterLicense, std::string licenseError) = 0;
virtual void loadWindow(bool showStartWindow, bool showEULA) = 0;
virtual void hideStartScreen() = 0;
virtual void setTitle(const std::wstring& title) = 0;
virtual void activateWindow() = 0;
virtual void forceEnterLicense(std::string licenseError) = 0;
virtual void updateRecentProjectMenu() = 0;
-21
View File
@@ -1,7 +1,6 @@
#include "ApplicationSettings.h"
#include "AppPath.h"
#include "License.h"
#include "Logger.h"
#include "ResourcePaths.h"
#include "SettingsMigrator.h"
@@ -689,23 +688,3 @@ void ApplicationSettings::setControlsGraphZoomOnMouseWheel(bool zoomingDefault)
{
setValue<bool>("controls/graph_zoom_on_mouse_wheel", zoomingDefault);
}
std::string ApplicationSettings::getLicenseString() const
{
return getValue<std::string>("user/license/license", "");
}
void ApplicationSettings::setLicenseString(const std::string& licenseString)
{
setValue<std::string>("user/license/license", licenseString);
}
bool ApplicationSettings::getNonCommercialUse() const
{
return getValue<bool>("user/license/non_commercial_use", false);
}
void ApplicationSettings::setNonCommercialUse(bool nonCommercialUse)
{
setValue<bool>("user/license/non_commercial_use", nonCommercialUse);
}
-7
View File
@@ -193,13 +193,6 @@ public:
bool getControlsGraphZoomOnMouseWheel() const;
void setControlsGraphZoomOnMouseWheel(bool zoomingDefault);
// license
std::string getLicenseString() const;
void setLicenseString(const std::string& licenseString);
bool getNonCommercialUse() const;
void setNonCommercialUse(bool nonCommercialUse);
private:
ApplicationSettings(const ApplicationSettings&);
void operator=(const ApplicationSettings&);
-2
View File
@@ -297,8 +297,6 @@ add_files(
qt/window/QtIndexingDialog.h
qt/window/QtKeyboardShortcuts.cpp
qt/window/QtKeyboardShortcuts.h
qt/window/QtLicenseWindow.cpp
qt/window/QtLicenseWindow.h
qt/window/QtMainWindow.cpp
qt/window/QtMainWindow.h
qt/window/QtPathListDialog.cpp
@@ -7,7 +7,6 @@
#include <QStyle>
#include "ApplicationSettings.h"
#include "LicenseChecker.h"
#include "logging.h"
#include "QtTextEdit.h"
#include "TimeStamp.h"
@@ -50,7 +49,6 @@ syntax:
// optional
"conditions":
{
"license": ["test", "private", "commercial"],
"os": ["windows", "macOS", "linux"],
"min_version": "2017.2.0",
"max_version": "2018.4.2",
@@ -183,20 +181,6 @@ bool QtNewsWidget::checkConditions(const QJsonObject& conditions) const
}
}
// license
{
QJsonArray licenseStrings = conditions.value("license").toArray();
if (!licenseStrings.isEmpty())
{
QString licenseString = QString::fromStdString(LicenseChecker::getCurrentLicenseTypeString());
if (!licenseStrings.contains(QJsonValue(licenseString)))
{
LOG_INFO_STREAM(<< "Failed condition license.");
return false;
}
}
}
// OS
{
QJsonArray osStrings = conditions.value("os").toArray();
+2 -4
View File
@@ -7,7 +7,6 @@
#include <QUrl>
#include "ApplicationSettings.h"
#include "LicenseChecker.h"
#include "logging.h"
#include "MessageStatus.h"
#include "QtRequest.h"
@@ -38,7 +37,7 @@ void QtUpdateChecker::check(bool force, std::function<void(Result)> callback)
appSettings->setUpdateDownloadUrl("");
appSettings->save();
QString urlString = "https://www.sourcetrail.com/api/v2/versions/latest";
QString urlString = "https://staging.sourcetrail.com/api/v2/versions/latest";
// OS
std::string osString = utility::getOsTypeString();
@@ -53,8 +52,7 @@ void QtUpdateChecker::check(bool force, std::function<void(Result)> callback)
urlString += ("&version=" + Version::getApplicationVersion().toDisplayString()).c_str();
// license
std::string licenseString = LicenseChecker::getCurrentLicenseTypeString();
urlString += ("&license=" + licenseString).c_str();
urlString += "&license=free"; // options: test, private, commercial
// user token
std::string token = appSettings->getUserToken();
+2 -12
View File
@@ -98,12 +98,12 @@ void QtMainView::saveLayout()
m_window->saveLayout();
}
void QtMainView::loadWindow(bool showStartWindow, bool showEULA, bool enterLicense, std::string licenseError)
void QtMainView::loadWindow(bool showStartWindow, bool showEULA)
{
m_onQtThread(
[=]()
{
m_window->loadWindow(showStartWindow, showEULA, enterLicense, licenseError);
m_window->loadWindow(showStartWindow, showEULA);
}
);
}
@@ -163,16 +163,6 @@ void QtMainView::activateWindow()
);
}
void QtMainView::forceEnterLicense(std::string licenseError)
{
m_onQtThread(
[=]()
{
m_window->forceEnterLicense(licenseError);
}
);
}
void QtMainView::updateRecentProjectMenu()
{
m_onQtThread(
+1 -2
View File
@@ -48,14 +48,13 @@ public:
void loadLayout() override;
void saveLayout() override;
void loadWindow(bool showStartWindow, bool showEULA, bool enterLicense, std::string licenseError) override;
void loadWindow(bool showStartWindow, bool showEULA) override;
void refreshView() override;
void hideStartScreen() override;
void setTitle(const std::wstring& title) override;
void activateWindow() override;
void forceEnterLicense(std::string licenseError) override;
void updateRecentProjectMenu() override;
-306
View File
@@ -1,306 +0,0 @@
#include "QtLicenseWindow.h"
#include <QApplication>
#include <QCheckBox>
#include <QLabel>
#include <QLineEdit>
#include <QRadioButton>
#include <QTextEdit>
#include "LicenseChecker.h"
#include "utilityQt.h"
#include "ApplicationSettings.h"
#include "ResourcePaths.h"
QtLicenseWindow::QtLicenseWindow(QWidget *parent)
: QtWindow(false, parent)
{
}
QSize QtLicenseWindow::sizeHint() const
{
return QSize(740, 550);
}
void QtLicenseWindow::clear()
{
if (m_licenseText)
{
m_commercialUse->setChecked(false);
m_privateUse->setChecked(false);
m_licenseText->setText("");
m_errorLabel->setText(" ");
}
}
void QtLicenseWindow::load()
{
clear();
std::string licenseString = LicenseChecker::getCurrentLicenseString();
if (licenseString.size() && m_licenseText)
{
m_commercialUse->setChecked(true);
m_licenseText->setEnabled(true);
m_licenseText->setText(licenseString.c_str());
}
else if (ApplicationSettings::getInstance()->getNonCommercialUse())
{
m_privateUse->setChecked(true);
}
}
void QtLicenseWindow::setErrorMessage(const QString& errorMessage)
{
if (m_errorLabel)
{
m_errorLabel->setText(errorMessage);
}
}
void QtLicenseWindow::populateWindow(QWidget* widget)
{
QVBoxLayout* subLayout = new QVBoxLayout();
subLayout->setContentsMargins(270, 0, 0, 0);
// commercial
m_commercialUse = new QRadioButton("Commercial Use");
m_commercialUse->setObjectName("licenseOption");
subLayout->addWidget(m_commercialUse);
QLabel* linkLabel = new QLabel(this);
linkLabel->setText(
"For commercial use please <a href=\"http://sourcetrail.com/buy-license\" style=\"color: #007AC2;\">purchase a license</a>, "
"or get a temporary <a href=\"http://sourcetrail.com/test-license\" style=\"color: #007AC2;\">test license</a>.");
linkLabel->setOpenExternalLinks(true);
linkLabel->setWordWrap(true);
subLayout->addWidget(linkLabel);
m_licenseText = new QTextEdit();
m_licenseText->setObjectName("licenseField");
m_licenseText->setAcceptRichText(false);
m_licenseText->setPlaceholderText(
"-----BEGIN LICENSE-----\n"
"Product: Sourcetrail\n"
"License holder:\n"
"License type:\n"
"Licensed number of users:\n"
"Licensed product version:\n"
"Licensed usage period:\n"
"-\n"
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n"
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n"
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n"
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n"
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n"
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n"
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n"
"xxxxxxxxxxxxxx\n"
"-----END LICENSE-----\n"
);
m_licenseText->setEnabled(false);
subLayout->addWidget(m_licenseText);
m_errorLabel = new QLabel(" ", this);
m_errorLabel->setObjectName("licenseError");
m_errorLabel->setWordWrap(true);
subLayout->addWidget(m_errorLabel);
subLayout->addSpacing(10);
// private
m_privateUse = new QRadioButton("Non-Commercial Use");
m_privateUse->setObjectName("licenseOption");
subLayout->addWidget(m_privateUse);
QLabel* licenseIntro2 = new QLabel("You confirm that you will use Sourcetrail solely for non-commercial purposes.");
licenseIntro2->setWordWrap(true);
subLayout->addWidget(licenseIntro2);
QVBoxLayout* layout = new QVBoxLayout();
layout->setContentsMargins(0, 0, 0, 0);
layout->addLayout(subLayout);
layout->addSpacing(20);
widget->setLayout(layout);
connect(m_commercialUse, &QRadioButton::toggled, this, &QtLicenseWindow::optionChanged);
connect(m_privateUse, &QRadioButton::toggled, this, &QtLicenseWindow::optionChanged);
}
void QtLicenseWindow::windowReady()
{
m_content->setStyleSheet(m_content->styleSheet() +
utility::getStyleSheet(ResourcePaths::getGuiPath().concatenate(L"license/license.css")).c_str());
addLogo();
updateTitle("Select License Option");
updateNextButton("Activate");
setNextEnabled(false);
setPreviousVisible(false);
updateCloseButton("Cancel");
}
void QtLicenseWindow::handleNext()
{
if (m_commercialUse->isChecked())
{
std::string licenseString = m_licenseText->toPlainText().toStdString();
LicenseChecker::LicenseState state = LicenseChecker::checkLicenseString(licenseString);
std::string errorString = LicenseChecker::getLicenseErrorForState(state);
if (state == LicenseChecker::LicenseState::VALID)
{
ApplicationSettings* appSettings = ApplicationSettings::getInstance().get();
LicenseChecker::setCurrentLicenseString(licenseString);
appSettings->setLicenseString(LicenseChecker::getCurrentLicenseStringEncoded());
appSettings->setNonCommercialUse(false);
appSettings->save();
emit finished();
return;
}
m_errorLabel->setText(errorString.c_str());
}
else if (m_privateUse->isChecked())
{
if (!m_confirmWindow)
{
m_confirmWindow = new QtNonCommercialInfoWindow();
m_confirmWindow->setup();
connect(m_confirmWindow, &QtWindow::canceled,
[this]()
{
m_confirmWindow->hideWindow();
raise();
}
);
connect(m_confirmWindow, &QtWindow::finished,
[this]()
{
m_confirmWindow->hideWindow();
raise();
ApplicationSettings* appSettings = ApplicationSettings::getInstance().get();
appSettings->setLicenseString("");
appSettings->setNonCommercialUse(true);
appSettings->save();
emit finished();
}
);
}
m_confirmWindow->showWindow();
}
}
void QtLicenseWindow::optionChanged()
{
m_licenseText->setEnabled(m_commercialUse->isChecked());
setNextEnabled(true);
}
QtNonCommercialInfoWindow::QtNonCommercialInfoWindow(QWidget *parent)
: QtWindow(false, parent)
{
}
QSize QtNonCommercialInfoWindow::sizeHint() const
{
return QSize(450, 500);
}
void QtNonCommercialInfoWindow::populateWindow(QWidget* widget)
{
QVBoxLayout* layout = new QVBoxLayout(widget);
layout->setContentsMargins(0, 0, 0, 0);
QLabel* titleLabel;
QLabel* textLabel;
titleLabel = new QLabel("Is your use non-commercial?");
textLabel = new QLabel(
"A use is non-commercial only if it is in no manner primarily intended for or directed toward "
"commercial advantage or private monetary compensation.");
QFont font = titleLabel->font();
font.setBold(true);
titleLabel->setFont(font);
textLabel->setWordWrap(true);
layout->addWidget(titleLabel);
layout->addWidget(textLabel);
layout->addSpacing(10);
titleLabel = new QLabel("When does non-commercial use NOT apply?");
textLabel = new QLabel(
"<p>Running Sourcetrail for 'Non-Commercial Use' is not permitted, if your use is in some sense commercial. "
"Examples of commercial uses are:</p>"
"<ul><li> you are using Sourcetrail to work on your company's projects (no matter whether you are working on "
"open-source projects as well),</li>"
"<li> you are a student and you use Sourcetrail for your work as a freelancer,</li>"
"<li> you use Sourcetrail in your spare time to help on your friend's new game and you are getting paid for that.</li></ul>"
"<p>In cases like these you will need a commercial license.</p>"
);
titleLabel->setFont(font);
textLabel->setWordWrap(true);
layout->addWidget(titleLabel);
layout->addWidget(textLabel);
layout->addSpacing(10);
titleLabel = new QLabel("Not sure?");
textLabel = new QLabel(
"Contact mail@sourcetrail.com and explain your intended use in detail, then we may confirm whether a "
"non-commercial license applies."
);
titleLabel->setFont(font);
textLabel->setWordWrap(true);
layout->addWidget(titleLabel);
layout->addWidget(textLabel);
layout->addStretch();
QCheckBox* checkbox = new QCheckBox("I confirm solely non-commercial use of Sourcetrail according to above conditions.");
connect(checkbox, &QCheckBox::toggled,
[checkbox, this]()
{
setNextEnabled(checkbox->isChecked());
}
);
layout->addWidget(checkbox);
layout->addStretch();
widget->setLayout(layout);
}
void QtNonCommercialInfoWindow::windowReady()
{
updateTitle("Non-Commercial Use Confirmation");
updateCloseButton("Cancel");
updateNextButton("Confirm");
setNextEnabled(false);
setPreviousVisible(false);
}
-60
View File
@@ -1,60 +0,0 @@
#ifndef QT_LICENSE_WINDOW_H
#define QT_LICENSE_WINDOW_H
#include "QtWindow.h"
class QLabel;
class QRadioButton;
class QTextEdit;
class QtLicenseWindow
: public QtWindow
{
Q_OBJECT
public:
QtLicenseWindow(QWidget* parent = 0);
QSize sizeHint() const override;
void clear();
void load();
void setErrorMessage(const QString& errorMessage);
protected:
// QtWindow implementation
virtual void populateWindow(QWidget* widget) override;
virtual void windowReady() override;
virtual void handleNext() override;
private slots:
void optionChanged();
private:
QRadioButton* m_commercialUse;
QRadioButton* m_privateUse;
QTextEdit* m_licenseText;
QLabel* m_errorLabel;
QtWindow* m_confirmWindow = nullptr;
};
class QtNonCommercialInfoWindow
: public QtWindow
{
Q_OBJECT
public:
QtNonCommercialInfoWindow(QWidget* parent = 0);
QSize sizeHint() const override;
protected:
// QtWindow implementation
virtual void populateWindow(QWidget* widget) override;
virtual void windowReady() override;
};
#endif // QT_LICENSE_WINDOW_H
+1 -72
View File
@@ -24,12 +24,10 @@
#include "QtAboutLicense.h"
#include "QtEulaWindow.h"
#include "QtKeyboardShortcuts.h"
#include "QtLicenseWindow.h"
#include "QtPreferencesWindow.h"
#include "QtStartScreen.h"
#include "ApplicationSettings.h"
#include "FileSystem.h"
#include "LicenseChecker.h"
#include "logging.h"
#include "MessageErrorsHelpMessage.h"
#include "MessageHistoryRedo.h"
@@ -325,18 +323,13 @@ void QtMainWindow::loadDockWidgetLayout()
}
}
void QtMainWindow::loadWindow(bool showStartWindow, bool showEULA, bool enterLicense, const std::string& licenseError)
void QtMainWindow::loadWindow(bool showStartWindow, bool showEULA)
{
if (showStartWindow)
{
showStartScreen();
}
if (enterLicense)
{
forceEnterLicense(licenseError);
}
if (showEULA)
{
showEula(true);
@@ -360,37 +353,6 @@ void QtMainWindow::saveLayout()
settings.setValue("DOCK_LOCATIONS", this->saveState());
}
void QtMainWindow::forceEnterLicense(const std::string& licenseError)
{
QtLicenseWindow* window = dynamic_cast<QtLicenseWindow*>(m_windowStack.getTopWindow());
if (window)
{
return;
}
enterLicense();
window = dynamic_cast<QtLicenseWindow*>(m_windowStack.getTopWindow());
if (!window)
{
LOG_ERROR("No enter license window on top of stack");
return;
}
if (licenseError.size())
{
window->setErrorMessage(QString::fromStdString(licenseError));
}
window->updateCloseButton("Quit");
setEnabled(false);
window->setEnabled(true);
disconnect(window, &QtWindow::canceled, &m_windowStack, &QtWindowStack::popWindow);
connect(window, &QtWindow::canceled, dynamic_cast<QApplication*>(QCoreApplication::instance()), &QApplication::quit);
}
void QtMainWindow::updateHistoryMenu(std::shared_ptr<MessageBase> message)
{
const size_t historyMenuSize = 20;
@@ -601,37 +563,6 @@ void QtMainWindow::showLicenses()
licenseWindow->setup();
}
void QtMainWindow::enterLicense()
{
QtLicenseWindow* enterLicenseWindow = createWindow<QtLicenseWindow>();
enterLicenseWindow->setup();
disconnect(enterLicenseWindow, &QtLicenseWindow::finished, &m_windowStack, &QtWindowStack::clearWindows);
connect(enterLicenseWindow, &QtLicenseWindow::finished, this, &QtMainWindow::enteredLicense);
enterLicenseWindow->load();
}
void QtMainWindow::enteredLicense()
{
bool showStartWindow = false;
if (m_windowStack.getWindowCount() > 0 && dynamic_cast<QtStartScreen*>(m_windowStack.getBottomWindow()))
{
showStartWindow = true;
}
m_windowStack.clearWindows();
MessageRefreshUI().dispatch();
setEnabled(true);
if (showStartWindow)
{
showStartScreen();
}
}
void QtMainWindow::showDataFolder()
{
QDesktopServices::openUrl(QUrl(QString::fromStdWString(L"file:///" + UserPaths::getUserDataPath().makeCanonical().wstr()), QUrl::TolerantMode));
@@ -674,7 +605,6 @@ void QtMainWindow::showStartScreen()
connect(startScreen, &QtStartScreen::openOpenProjectDialog, this, &QtMainWindow::openProject);
connect(startScreen, &QtStartScreen::openNewProjectDialog, this, &QtMainWindow::newProject);
connect(startScreen, &QtStartScreen::openEnterLicenseDialog, this, &QtMainWindow::enterLicense);
}
void QtMainWindow::hideStartScreen()
@@ -1122,7 +1052,6 @@ void QtMainWindow::setupHelpMenu()
menu->addSeparator();
menu->addAction(tr("Select License..."), this, &QtMainWindow::enterLicense);
menu->addAction(tr("End User License Agreement"), this, &QtMainWindow::showEula);
menu->addAction(tr("3rd Party Licenses"), this, &QtMainWindow::showLicenses);
menu->addAction(tr("&About Sourcetrail"), this, &QtMainWindow::about);
+1 -5
View File
@@ -73,9 +73,7 @@ public:
void saveLayout();
void loadDockWidgetLayout();
void loadWindow(bool showStartWindow, bool showEULA, bool enterLicense, const std::string& licenseError);
void forceEnterLicense(const std::string& licenseError);
void loadWindow(bool showStartWindow, bool showEULA);
void updateHistoryMenu(std::shared_ptr<MessageBase> message);
void clearHistoryMenu();
@@ -111,8 +109,6 @@ public slots:
void showEula(bool forceAccept = false);
void acceptedEula();
void showLicenses();
void enterLicense();
void enteredLicense();
void showDataFolder();
void showLogFolder();
-33
View File
@@ -8,7 +8,6 @@
#include <QMessageBox>
#include "ApplicationSettings.h"
#include "LicenseChecker.h"
#include "MessageLoadProject.h"
#include "ProjectSettings.h"
#include "QtUpdateCheckerWidget.h"
@@ -169,33 +168,6 @@ void QtStartScreen::setupStartScreen()
col->addSpacing(15);
if (LicenseChecker::checkCurrentLicense() == LicenseChecker::LicenseState::VALID)
{
std::string licenseInfo = LicenseChecker::getCurrentLicense()->getLicenseInfo();
QLabel* licenseHeader = new QLabel("Licensed to:");
licenseHeader->setObjectName("boldLabel");
col->addWidget(licenseHeader);
col->addSpacing(2);
QLabel* licenseLabel = new QLabel(licenseInfo.c_str());
licenseLabel->setObjectName("textLabel");
col->addWidget(licenseLabel);
}
else
{
QLabel* licenseHeader = new QLabel("Not licensed for<br />commercial use.");
licenseHeader->setObjectName("boldLabel");
col->addWidget(licenseHeader);
QPushButton* upgradeButton = new QPushButton("upgrade");
upgradeButton->setObjectName("upgradeButton");
upgradeButton->setCursor(Qt::PointingHandCursor);
col->addWidget(upgradeButton);
connect(upgradeButton, &QPushButton::clicked, [this](){ emit openEnterLicenseDialog(); });
}
col->addSpacing(15);
{
QLabel* newsHeader = new QLabel("News:");
newsHeader->setObjectName("boldLabel");
@@ -276,11 +248,6 @@ void QtStartScreen::handleOpenProjectButton()
emit openOpenProjectDialog();
}
void QtStartScreen::handleUnlockButton()
{
emit openEnterLicenseDialog();
}
void QtStartScreen::handleRecentButton()
{
emit finished();
-2
View File
@@ -39,12 +39,10 @@ public:
signals:
void openOpenProjectDialog();
void openNewProjectDialog();
void openEnterLicenseDialog();
private slots:
void handleNewProjectButton();
void handleOpenProjectButton();
void handleUnlockButton();
void handleRecentButton();
void updateButtons();
-1
View File
@@ -9,7 +9,6 @@
#include <qprocessordetection.h>
#include <QRegularExpression>
#include "License.h"
#include "ApplicationSettings.h"
#include "logging.h"
#include "AppPath.h"
-2
View File
@@ -7,8 +7,6 @@
#include "OsType.h"
#include "FilePath.h"
class License;
namespace utility
{
std::pair<int, std::string> executeProcess(
-12
View File
@@ -1,12 +0,0 @@
add_files(
LIB_LICENSE
utility/Version.cpp
utility/Version.h
License.cpp
License.h
LicenseChecker.cpp
LicenseChecker.h
LicenseType.h
)
-576
View File
@@ -1,576 +0,0 @@
#include "License.h"
#include <algorithm>
#include <cctype>
#include <fstream>
#include <iostream>
#include <istream>
#include <boost/date_time.hpp>
#include <boost/date_time/gregorian/gregorian.hpp>
// #include <botan_all.h>
#include <botan/auto_rng.h>
#include <botan/passhash9.h>
#include "Version.h"
namespace
{
std::string trim(const std::string &str)
{
auto wsfront = std::find_if_not(str.begin(), str.end(), [](int c) { return std::isspace(c); });
auto wsback = std::find_if_not(str.rbegin(), str.rend(), [](int c) { return std::isspace(c); }).base();
return (wsback <= wsfront ? std::string() : std::string(wsfront, wsback));
}
std::string toLowerCase(const std::string& in)
{
std::string out;
std::transform(in.begin(), in.end(), std::back_inserter(out), towlower);
return out;
}
std::string removeCaption(const std::string& line, const std::string& caption)
{
if (line.substr(0, caption.length()) == caption)
{
return line.substr(caption.length());
}
return "";
}
}
License::License()
{
}
License::~License()
{
}
std::string License::getUser() const
{
return m_user;
}
std::string License::getType() const
{
return m_type;
}
size_t License::getNumberOfUsers() const
{
return m_numberOfUsers;
}
std::string License::getLicenseInfo() const
{
std::string info = m_user + "\n";
info += m_type + "\n";
// get info depending on license type
if (m_numberOfUsers == 0)
{
info += "unlimited users\n";
}
else if (m_numberOfUsers > 1)
{
info += std::to_string(m_numberOfUsers) + " users\n";
}
else
{
info += "1 user\n";
}
if (m_expirationVersion != LicenseConstants::VALID_UNLIMITED)
{
info += "valid up to version " + m_expirationVersion;
}
else if (m_expirationDate != LicenseConstants::VALID_UNLIMITED)
{
info += "valid until " + m_expirationDate;
}
else
{
info += "valid perpetually";
}
return info;
}
std::string License::getMessage(bool withNewlines) const
{
if (m_user.empty() || m_type.empty() || m_expirationVersion.empty() || m_expirationDate.empty() || m_hashLine.empty())
{
return "";
}
const std::string separator = (withNewlines ? "\n" : "");
std::string message = LicenseConstants::PRODUCT + separator;
if (m_isOldFormat)
{
message += LicenseConstants::LICENSED_TO_OLD + m_user + separator;
message += LicenseConstants::LICENSE_TYPE + m_type;
if (m_numberOfUsers == 0)
{
message += (m_createdWithSeats ? " (unlimited seats)" : " (unlimited users)");
}
else if (m_numberOfUsers == 1)
{
message += (m_createdWithSeats ? " (1 Seat)" : " (1 user)");
}
else if (m_numberOfUsers > 1)
{
message += " (" + std::to_string(m_numberOfUsers) + (m_createdWithSeats ? " Seats)" : " users)");
}
message += separator;
if (m_expirationVersion != LicenseConstants::VALID_UNLIMITED)
{
message += LicenseConstants::VALID_UP_TO_OLD + m_expirationVersion + separator;
}
else if (m_expirationDate != LicenseConstants::VALID_UNLIMITED)
{
message += LicenseConstants::VALID_UNTIL_OLD + m_expirationDate + separator;
}
}
else
{
std::string s;
message += LicenseConstants::LICENSE_HOLDER + m_user + separator;
message += LicenseConstants::LICENSE_TYPE + m_type + separator;
if (m_numberOfUsers > 0)
{
message += LicenseConstants::LICENSED_USERS + std::to_string(m_numberOfUsers) + separator;
}
else
{
message += s + LicenseConstants::LICENSED_USERS + LicenseConstants::VALID_UNLIMITED + separator;
}
if (m_expirationVersion != LicenseConstants::VALID_UNLIMITED)
{
message += s + LicenseConstants::LICENSED_VERSION + LicenseConstants::VALID_UP_TO + m_expirationVersion + separator;
}
else
{
message += s + LicenseConstants::LICENSED_VERSION + LicenseConstants::VALID_UNLIMITED + separator;
}
if (m_expirationDate != LicenseConstants::VALID_UNLIMITED)
{
message += s + LicenseConstants::LICENSED_PERIOD + LicenseConstants::VALID_UNTIL + m_expirationDate + separator;
}
else
{
message += s + LicenseConstants::LICENSED_PERIOD + LicenseConstants::VALID_UNLIMITED + separator;
}
}
message += LicenseConstants::SEPARATOR + separator;
message += m_hashLine;
return message;
}
void License::setMessage(
const std::string& user,
const std::string& type,
size_t numberOfUsers,
const std::string& expirationVersion,
const std::string& expirationDate
){
if (user.empty() || type.empty() || (numberOfUsers == 0 && expirationVersion.empty() && expirationDate.empty()))
{
return;
}
m_user = user;
m_type = type;
m_numberOfUsers = numberOfUsers;
m_expirationVersion = expirationVersion.size() ? expirationVersion : LicenseConstants::VALID_UNLIMITED;
m_expirationDate = expirationDate.size() ? expirationDate : LicenseConstants::VALID_UNLIMITED;
m_hashLine = generateHash(user + type);
}
const std::string& License::getSignature() const
{
return m_signature;
}
void License::setSignature(const std::string& signature)
{
m_signature = signature;
}
int License::getTimeLeft() const
{
const std::string dateText = "YYYY-MMM-DD";
std::string dateString = m_expirationDate;
if (dateString.length() != dateText.length())
{
return -2;
}
boost::gregorian::date expireDate(
boost::gregorian::from_simple_string(dateString));
boost::gregorian::date today = boost::gregorian::day_clock::local_day();
boost::gregorian::days daysLeft = expireDate - today;
return (daysLeft.days() < 0 ? -1 : daysLeft.days());
}
void License::writeToFile(const std::string& filename)
{
std::ofstream licenseFile(filename);
licenseFile << getLicenseString() << std::endl;
}
bool License::loadFromString(const std::string& licenseText)
{
std::istringstream license(licenseText);
return load(license);
}
bool License::loadFromFile(const std::string& filename)
{
std::ifstream sigfile(filename);
return load(sigfile);
}
void License::print()
{
std::cout << getLicenseString();
}
bool License::isEmpty() const
{
if (m_user.empty() && m_type.empty() &&
m_expirationVersion.empty() && m_expirationDate.empty() &&
m_hashLine.empty() && m_signature.empty())
{
return true;
}
return false;
}
bool License::isComplete() const
{
if (m_user.empty() || m_type.empty() ||
m_expirationVersion.empty() || m_expirationDate.empty() ||
m_hashLine.empty() || m_signature.empty())
{
return false;
}
return true;
}
bool License::isExpired() const
{
if (m_expirationVersion != LicenseConstants::VALID_UNLIMITED)
{
Version version = Version::fromString(m_expirationVersion);
return Version::getApplicationVersion().toShortVersion() > version;
}
else if (m_expirationDate != LicenseConstants::VALID_UNLIMITED)
{
return (getTimeLeft() == -1);
}
else if (m_expirationVersion == LicenseConstants::VALID_UNLIMITED &&
m_expirationDate == LicenseConstants::VALID_UNLIMITED)
{
return false;
}
return true;
}
bool License::isTestLicense() const
{
return m_type == LicenseConstants::TEST_LICENSE;
}
std::string License::getLicenseString() const
{
if (m_user.empty() || m_type.empty() || m_expirationVersion.empty() || m_expirationDate.empty())
{
return "";
}
std::string signatureLines;
std::stringstream ss;
const int lineLength = 55;
for (size_t i = 0; i < m_signature.size(); i++)
{
if (i % lineLength == 0 && i != 0)
{
signatureLines += ss.str() + "\n";
ss.str("");
}
ss << m_signature[i];
}
signatureLines += ss.str();
std::string license = "";
license += LicenseConstants::BEGIN_LICENSE;
license += "\n";
license += getMessage(true) + "\n";
license += signatureLines + "\n";
license += LicenseConstants::END_LICENSE;
license += "\n";
return license;
}
std::string License::generateHash(const std::string& str) const
{
if (str.size() <= 0)
{
return "";
}
Botan::AutoSeeded_RNG rng;
return Botan::generate_passhash9(str, rng);
}
bool License::checkHash(const std::string& str, const std::string& hash)
{
if (str.empty() || hash.empty())
{
return true;
}
return Botan::check_passhash9(str, hash);
}
bool License::load(std::istream& stream)
{
std::string line;
std::vector<std::string> lines;
while (getline(stream, line, '\n'))
{
line = trim(line);
if ((!lines.size() && line == LicenseConstants::BEGIN_LICENSE) || line == LicenseConstants::END_LICENSE)
{
continue;
}
if (line.size())
{
lines.push_back(line);
}
}
if (lines.size() == 15)
{
m_isOldFormat = false;
return loadFromLines(lines);
}
else if (lines.size() == 13)
{
m_isOldFormat = true;
return loadFromLinesOld(lines);
}
return false;
}
bool License::loadFromLines(const std::vector<std::string>& lines)
{
if (lines.size() != 15)
{
return false;
}
// sourcetrail line
if (lines[0] != LicenseConstants::PRODUCT)
{
return false;
}
// user line
m_user = removeCaption(lines[1], LicenseConstants::LICENSE_HOLDER);
if (m_user.empty())
{
return false;
}
// type line
m_type = removeCaption(lines[2], LicenseConstants::LICENSE_TYPE);
if (m_type.empty())
{
return false;
}
// number of users
std::string users = removeCaption(lines[3], LicenseConstants::LICENSED_USERS);
if (users != LicenseConstants::VALID_UNLIMITED)
{
try
{
m_numberOfUsers = std::stoi(users);
}
catch (std::invalid_argument e)
{
m_numberOfUsers = 0;
return false;
}
}
else
{
m_numberOfUsers = 0;
}
// expiration version
m_expirationVersion = removeCaption(lines[4], LicenseConstants::LICENSED_VERSION);
if (m_expirationVersion != LicenseConstants::VALID_UNLIMITED)
{
m_expirationVersion = removeCaption(m_expirationVersion, LicenseConstants::VALID_UP_TO);
if (!Version::fromString(m_expirationVersion).isValid())
{
return false;
}
}
// expiration date
m_expirationDate = removeCaption(lines[5], LicenseConstants::LICENSED_PERIOD);
if (m_expirationDate != LicenseConstants::VALID_UNLIMITED)
{
m_expirationDate = removeCaption(m_expirationDate, LicenseConstants::VALID_UNTIL);
if (m_expirationDate.size() != 11 || m_expirationDate[4] != '-' || m_expirationDate[8] != '-')
{
return false;
}
}
// separator line
if (lines[6] != LicenseConstants::SEPARATOR)
{
return false;
}
// hash line
m_hashLine = lines[7];
if (m_hashLine.length() != 55)
{
return false;
}
// signature
m_signature = lines[8] + lines[9] + lines[10] + lines[11] + lines[12] + lines[13] + lines[14];
if (m_signature.length() != 344)
{
return false;
}
return true;
}
bool License::loadFromLinesOld(const std::vector<std::string>& lines)
{
if (lines.size() != 13)
{
return false;
}
// sourcetrail line
if (lines[0] != LicenseConstants::PRODUCT)
{
return false;
}
// user line
m_user = removeCaption(lines[1], LicenseConstants::LICENSED_TO_OLD);
if (m_user.empty())
{
return false;
}
// type line
{
std::string line = removeCaption(lines[2], LicenseConstants::LICENSE_TYPE);
size_t pos = line.find("(");
if (pos != line.npos)
{
m_type = line.substr(0, pos - 1);
try
{
m_numberOfUsers = std::stoi(line.substr(pos+1));
}
catch (std::invalid_argument e)
{
m_numberOfUsers = 0;
}
if (toLowerCase(line).find("seat") != line.npos)
{
m_createdWithSeats = true;
}
}
else
{
m_type = line;
m_numberOfUsers = 0;
}
if (m_type.empty())
{
return false;
}
}
// expire line
m_expirationVersion = removeCaption(lines[3], LicenseConstants::VALID_UP_TO_OLD);
m_expirationDate = removeCaption(lines[3], LicenseConstants::VALID_UNTIL_OLD);
if (m_expirationVersion.empty() && m_expirationDate.empty())
{
return false;
}
if (m_expirationVersion.empty())
{
m_expirationVersion = LicenseConstants::VALID_UNLIMITED;
}
if (m_expirationDate.empty())
{
m_expirationDate = LicenseConstants::VALID_UNLIMITED;
}
// separator line
if (lines[4] != LicenseConstants::SEPARATOR)
{
return false;
}
// hash line
m_hashLine = lines[5];
if (m_hashLine.length() != 55)
{
return false;
}
// signature
m_signature = lines[6] + lines[7] + lines[8] + lines[9] + lines[10] + lines[11] + lines[12];
if (m_signature.length() != 344)
{
return false;
}
return true;
}
-97
View File
@@ -1,97 +0,0 @@
#ifndef SOURCETRAIL_LICENSE_H
#define SOURCETRAIL_LICENSE_H
#include <memory>
#include <string>
#include <vector>
namespace LicenseConstants
{
const char BEGIN_LICENSE[] = "-----BEGIN LICENSE-----";
const char END_LICENSE[] = "-----END LICENSE-----";
const char TEST_LICENSE[] = "Test License";
const char PRODUCT[] = "Product: Sourcetrail";
const char LICENSE_HOLDER[] = "License holder: ";
const char LICENSE_TYPE[] = "License type: ";
const char LICENSED_USERS[] = "Licensed number of users: ";
const char LICENSED_VERSION[] = "Licensed product version: ";
const char LICENSED_PERIOD[] = "Licensed usage period: ";
const char VALID_UNTIL[] = "until ";
const char VALID_UP_TO[] = "up to ";
const char VALID_UNLIMITED[] = "unlimited";
const char LICENSED_TO_OLD[] = "Licensed to: ";
const char VALID_UNTIL_OLD[] = "Valid until: ";
const char VALID_UP_TO_OLD[] = "Valid up to version: ";
const char SEPARATOR[] = "-";
}
class License
{
public:
License();
~License();
std::string getType() const;
std::string getUser() const;
size_t getNumberOfUsers() const;
std::string getLicenseInfo() const;
std::string getMessage(bool withNewlines) const;
void setMessage(
const std::string& user,
const std::string& type,
size_t numberOfUsers,
const std::string& expirationVersion,
const std::string& expirationDate
);
const std::string& getSignature() const;
void setSignature(const std::string& signature);
std::string getLicenseString() const;
void writeToFile(const std::string& filename);
bool loadFromString(const std::string& licenseText);
bool loadFromFile(const std::string& filename);
bool isEmpty() const;
bool isComplete() const;
bool isExpired() const;
bool isTestLicense() const;
// if Test License return >=0 or -1 if expired
// for non Test License -2
int getTimeLeft() const;
void print();
std::string generateHash(const std::string& str) const;
static bool checkHash(const std::string& str, const std::string& hash);
private:
bool load(std::istream& stream);
bool loadFromLines(const std::vector<std::string>& lines);
bool loadFromLinesOld(const std::vector<std::string>& lines);
std::string m_user;
std::string m_type;
size_t m_numberOfUsers = 0;
bool m_createdWithSeats = false;
std::string m_expirationVersion;
std::string m_expirationDate;
std::string m_hashLine;
std::string m_signature;
bool m_isOldFormat = false;
};
#endif // SOURCETRAIL_LICENSE_H
-336
View File
@@ -1,336 +0,0 @@
#include "LicenseChecker.h"
#include <iostream>
#include <sstream>
#include <boost/filesystem.hpp>
// #include <botan_all.h>
#include <botan/auto_rng.h>
#include <botan/base64.h>
#include <botan/cryptobox.h>
#include <botan/pbkdf.h>
#include <botan/pk_keys.h>
#include <botan/pubkey.h>
#include <botan/rsa.h>
#include "License.h"
#include "PublicKey.h"
std::string LicenseChecker::s_encodeKey;
Botan::RSA_PublicKey* LicenseChecker::s_publicKey = nullptr;
std::unique_ptr<License> LicenseChecker::s_currentLicense;
void LicenseChecker::setEncodeKey(const std::string& key)
{
if (key.empty())
{
return;
}
Botan::PBKDF *pbkdf = Botan::get_pbkdf("PBKDF2(SHA-256)");
Botan::secure_vector<Botan::byte> salt = Botan::base64_decode("34zA54n60v4CxjY5n20k3J40c976n690", 32);
s_encodeKey = pbkdf->derive_key(32, key, &salt[0], salt.size(), 10000).as_string();
}
bool LicenseChecker::loadPublicKeyFromFile(std::string fileName)
{
if (!boost::filesystem::exists(fileName))
{
std::cout << "Public key file does not exist: " << fileName << std::endl;
return false;
}
return createPublicKey(dynamic_cast<Botan::RSA_PublicKey*>(Botan::X509::load_key(fileName)));
}
bool LicenseChecker::loadPublicKeyFromString(const std::string& publicKey)
{
if (publicKey.empty())
{
std::cout << "Public key is empty" << std::endl;
return false;
}
Botan::DataSource_Memory in(publicKey);
return createPublicKey(dynamic_cast<Botan::RSA_PublicKey *>(Botan::X509::load_key(in)));
}
bool LicenseChecker::loadPublicKey()
{
return loadPublicKeyFromString(PUBLIC_KEY);
}
const License* LicenseChecker::getCurrentLicense()
{
return s_currentLicense.get();
}
std::string LicenseChecker::getCurrentLicenseString()
{
if (s_currentLicense)
{
return s_currentLicense->getLicenseString();
}
return "";
}
std::string LicenseChecker::getCurrentLicenseStringEncoded()
{
if (!s_currentLicense)
{
std::cout << "No current license" << std::endl;
return "";
}
if (s_encodeKey.empty())
{
std::cout << "No encode key" << std::endl;
return "";
}
Botan::AutoSeeded_RNG rng;
std::vector<Botan::byte> fileContents;
std::stringstream input(s_currentLicense->getLicenseString());
// prepare the license string to work with the botan cryptobox
while (input.good())
{
Botan::byte filebuffer[4096] = { 0 };
input.read((char*)filebuffer, sizeof(filebuffer));
size_t got = input.gcount();
fileContents.insert(fileContents.end(), filebuffer, filebuffer + got);
}
if (fileContents.size() <= 0)
{
std::cout << "Failed to read license string" << std::endl;
return "";
}
std::string result = Botan::CryptoBox::encrypt(&fileContents[0], fileContents.size(), s_encodeKey, rng);
// remove Botan Cryptobox begin and end
// should not be in the application settings
const int cryptoboxBeginLength = 40;
const int cryptoboxEndLength = 38;
if (result.length() < cryptoboxBeginLength + cryptoboxEndLength)
{
std::cout << "Invalid result" << std::endl;
return "";
}
result = result.substr(cryptoboxBeginLength, result.length() - (cryptoboxBeginLength + cryptoboxEndLength));
return result;
}
LicenseChecker::LicenseState LicenseChecker::setCurrentLicenseString(const std::string& licenseStr)
{
s_currentLicense = nullptr;
if (licenseStr.empty())
{
return LicenseState::EMPTY;
}
s_currentLicense = std::make_unique<License>();
if (!s_currentLicense->loadFromString(licenseStr))
{
s_currentLicense = nullptr;
return LicenseState::MALFORMED;
}
return checkCurrentLicense();
}
LicenseChecker::LicenseState LicenseChecker::setCurrentLicenseStringEncoded(const std::string& licenseStr)
{
s_currentLicense = nullptr;
if (licenseStr.empty())
{
return LicenseState::EMPTY;
}
if (s_encodeKey.empty())
{
std::cout << "No key available" << std::endl;
return LicenseState::EMPTY;
}
s_currentLicense = std::make_unique<License>();
try
{
// add cryptobox begin and end to loaded string
std::string cryptoboxInput = "-----BEGIN BOTAN CRYPTOBOX MESSAGE-----\n";
cryptoboxInput += licenseStr;
cryptoboxInput += "-----END BOTAN CRYPTOBOX MESSAGE-----";
// decrypt license
if (!s_currentLicense->loadFromString(Botan::CryptoBox::decrypt(cryptoboxInput, s_encodeKey)))
{
s_currentLicense = nullptr;
return LicenseState::MALFORMED;
}
}
catch (...)
{
s_currentLicense = nullptr;
return LicenseState::MALFORMED;
}
return checkCurrentLicense();
}
LicenseChecker::LicenseState LicenseChecker::checkLicense(const License& license)
{
if (license.isEmpty())
{
return LicenseState::EMPTY;
}
if (!license.isComplete())
{
return LicenseState::INCOMPLETE;
}
std::string message = license.getMessage(false);
std::string signature = license.getSignature();
if (message.empty() || signature.empty())
{
return LicenseState::INCOMPLETE;
}
if (!s_publicKey)
{
std::cout << "No public key loaded" << std::endl;
return LicenseState::INCOMPLETE;
}
try
{
Botan::PK_Verifier verifier(*s_publicKey, "EMSA4(SHA-256)");
Botan::DataSource_Memory in(message);
Botan::byte buffer[4096] = { 0 };
while (size_t got = in.read(buffer, sizeof(buffer)))
{
verifier.update(buffer, got);
}
Botan::secure_vector<Botan::byte> sig = Botan::base64_decode(signature);
if (!verifier.check_signature(sig))
{
return LicenseState::INVALID;
}
}
catch (...)
{
std::cout << "Invalid character in Licensekey" << std::endl;
return LicenseState::MALFORMED;
}
if (license.isExpired())
{
return LicenseState::EXPIRED;
}
return LicenseState::VALID;
}
LicenseChecker::LicenseState LicenseChecker::checkLicenseString(const std::string& licenseString)
{
if (licenseString.size() == 0)
{
return LicenseState::EMPTY;
}
License license;
bool isLoaded = license.loadFromString(licenseString);
if (!isLoaded)
{
return LicenseState::MALFORMED;
}
return checkLicense(license);
}
LicenseChecker::LicenseState LicenseChecker::checkCurrentLicense()
{
if (!s_currentLicense)
{
return LicenseState::EMPTY;
}
return checkLicense(*s_currentLicense.get());
}
LicenseType LicenseChecker::getCurrentLicenseType()
{
if (!s_currentLicense)
{
return LicenseType::NON_COMMERCIAL;
}
LicenseState state = checkLicense(*s_currentLicense.get());
if (state != LicenseState::VALID)
{
return LicenseType::NON_COMMERCIAL;
}
else if (s_currentLicense->isTestLicense())
{
return LicenseType::TEST;
}
return LicenseType::COMMERCIAL;
}
std::string LicenseChecker::getCurrentLicenseTypeString()
{
// WARNING: Don't change these strings. The analytics API on the server relies on them.
switch (getCurrentLicenseType())
{
case LicenseType::NON_COMMERCIAL:
return "private";
case LicenseType::TEST:
return "test";
case LicenseType::COMMERCIAL:
return "commercial";
}
return "private";
}
std::string LicenseChecker::getLicenseErrorForState(LicenseState state)
{
switch (state)
{
case LicenseState::EMPTY:
return "No license key was entered.";
case LicenseState::INCOMPLETE:
return "The license key is incomplete.";
case LicenseState::MALFORMED:
return "The license key is malformed.";
case LicenseState::INVALID:
return "The license key is invalid.";
case LicenseState::EXPIRED:
return "The license key is expired.";
case LicenseState::VALID:
return "";
}
}
bool LicenseChecker::createPublicKey(Botan::RSA_PublicKey *rsaPublicKey)
{
if (!rsaPublicKey)
{
std::cout << "The loaded key is not a RSA key" << std::endl;
return false;
}
s_publicKey = rsaPublicKey;
return true;
}
-59
View File
@@ -1,59 +0,0 @@
#ifndef LICENSE_CHECKER_H
#define LICENSE_CHECKER_H
#include <string>
#include <memory>
#include "License.h"
#include "LicenseType.h"
namespace Botan
{
class RSA_PublicKey;
}
class LicenseChecker
{
public:
enum class LicenseState
{
EMPTY,
INCOMPLETE,
MALFORMED,
INVALID,
EXPIRED,
VALID
};
static void setEncodeKey(const std::string& key);
static bool loadPublicKeyFromFile(std::string fileName);
static bool loadPublicKeyFromString(const std::string& publicKey);
static bool loadPublicKey();
static const License* getCurrentLicense();
static std::string getCurrentLicenseString();
static std::string getCurrentLicenseStringEncoded();
static LicenseState setCurrentLicenseString(const std::string& licenseStr);
static LicenseState setCurrentLicenseStringEncoded(const std::string& licenseStr);
static LicenseState checkLicense(const License& license);
static LicenseState checkLicenseString(const std::string& licenseString);
static LicenseState checkCurrentLicense();
static LicenseType getCurrentLicenseType();
static std::string getCurrentLicenseTypeString();
static std::string getLicenseErrorForState(LicenseState state);
private:
static bool createPublicKey(Botan::RSA_PublicKey *rsaPublicKey);
static std::string s_encodeKey;
static Botan::RSA_PublicKey* s_publicKey; // Intentional memory leak, because destruction can cause crash
static std::unique_ptr<License> s_currentLicense;
};
#endif // LICENSE_CHECKER_H
-11
View File
@@ -1,11 +0,0 @@
#ifndef LICENSE_TYPE_H
#define LICENSE_TYPE_H
enum class LicenseType
{
TEST,
NON_COMMERCIAL,
COMMERCIAL
};
#endif // LICENSE_TYPE_H
-13
View File
@@ -1,13 +0,0 @@
add_files(
LICENSE_GENERATOR
LicenseGenerator.cpp
LicenseGenerator.h
)
# split for tests
add_files(
LICENSE_GENERATOR_MAIN
main.cpp
)
-243
View File
@@ -1,243 +0,0 @@
#include "LicenseGenerator.h"
#include <iostream>
#include <fstream>
#include <memory>
#include <sstream>
#include <boost/date_time/gregorian/gregorian.hpp>
#include <boost/filesystem.hpp>
#include <botan/auto_rng.h>
#include <botan/base64.h>
#include <botan/passhash9.h>
#include <botan/pbkdf.h>
#include <botan/pk_keys.h>
#include <botan/pkcs8.h>
#include <botan/pubkey.h>
#include <botan/rsa.h>
#include "Version.h"
const char PRIVATE_KEY_PASSWORD[] = "BA#jk5vbklAiKL9K3k$";
LicenseGenerator::LicenseGenerator()
{
}
LicenseGenerator::~LicenseGenerator()
{
}
void LicenseGenerator::generatePrivateKey()
{
m_privateKey = std::make_unique<Botan::RSA_PrivateKey>(m_rng, 2048);
}
std::unique_ptr<License> LicenseGenerator::createLicenseByVersion(
const std::string& user,
const std::string& licenseType,
size_t numberOfUsers,
const std::string& version
){
if (version.empty())
{
std::cout << "No version given" << std::endl;
return nullptr;
}
Version tempVersion = Version::fromString(version);
if (tempVersion.isValid())
{
return createLicense(user, licenseType, numberOfUsers, tempVersion.toShortString(), LicenseConstants::VALID_UNLIMITED);
}
return nullptr;
}
std::unique_ptr<License> LicenseGenerator::createLicenseByQuarters(
const std::string& user,
const std::string& type,
size_t numberOfUsers,
size_t quarters
){
boost::gregorian::date today = boost::gregorian::day_clock::local_day();
int quarter = (today.month().as_number() - 1) / 3 + 1;
Version version(today.year(), quarter);
version += quarters;
return createLicenseByVersion(user, type, numberOfUsers, version.toShortString());
}
std::unique_ptr<License> LicenseGenerator::createLicenseByDays(
const std::string& user,
const std::string& type,
size_t numberOfUsers,
size_t days
){
boost::gregorian::date today = boost::gregorian::day_clock::local_day();
boost::gregorian::days daysToTry(days);
boost::gregorian::date expireDate = today + daysToTry;
return createLicense(
user,
(type.size() ? type : LicenseConstants::TEST_LICENSE), numberOfUsers,
LicenseConstants::VALID_UNLIMITED,
boost::gregorian::to_simple_string(expireDate)
);
}
std::unique_ptr<License> LicenseGenerator::createLicenseLifelong(
const std::string& user,
const std::string& type,
size_t numberOfUsers
){
if (numberOfUsers == 0)
{
std::cout << "No user count given" << std::endl;
return nullptr;
}
return createLicense(user, type, numberOfUsers, LicenseConstants::VALID_UNLIMITED, LicenseConstants::VALID_UNLIMITED);
}
std::string LicenseGenerator::getPublicKeyPEMFileAsString()
{
if (!m_privateKey)
{
std::cout << "No private key loaded" << std::endl;
return "";
}
return Botan::X509::PEM_encode(*m_privateKey);
}
std::string LicenseGenerator::getPrivateKeyPEMFileAsString()
{
if (!m_privateKey)
{
std::cout << "No private key loaded" << std::endl;
return "";
}
return Botan::PKCS8::PEM_encode(*m_privateKey, m_rng, PRIVATE_KEY_PASSWORD);
}
void LicenseGenerator::writeKeysToFiles(const std::string& publicKeyFilename, const std::string& privateKeyFilename)
{
if (publicKeyFilename.size() <= 0)
{
std::cout << "Public key file path is empty" << std::endl;
return;
}
if (privateKeyFilename.size() <= 0)
{
std::cout << "Private key file path is empty" << std::endl;
return;
}
std::cout << "public key filename: " << publicKeyFilename << std::endl;
std::ofstream pub(publicKeyFilename);
pub << getPublicKeyPEMFileAsString();
pub.close();
std::cout << "public key created" << std::endl;
std::cout << "private key filename: " << privateKeyFilename << std::endl;
std::ofstream priv(privateKeyFilename);
priv << getPrivateKeyPEMFileAsString();
priv.close();
std::cout << "private key created" << std::endl;
}
bool LicenseGenerator::loadPrivateKeyFromFile(const std::string& file)
{
if (!boost::filesystem::exists(file))
{
std::cout << "Private key not found: " << file << std::endl;
return false;
}
return createPrivateKey(dynamic_cast<Botan::RSA_PrivateKey *>(Botan::PKCS8::load_key(file, m_rng, PRIVATE_KEY_PASSWORD)));
}
bool LicenseGenerator::loadPrivateKeyFromString(const std::string& key)
{
if (key.empty())
{
std::cout << "No key string given" << std::endl;
return false;
}
Botan::DataSource_Memory in(key);
return createPrivateKey(dynamic_cast<Botan::RSA_PrivateKey *>(Botan::PKCS8::load_key(in, m_rng, PRIVATE_KEY_PASSWORD)));
}
Botan::RSA_PrivateKey* LicenseGenerator::getPrivateKey() const
{
return m_privateKey.get();
}
bool LicenseGenerator::createPrivateKey(Botan::RSA_PrivateKey* rsaPrivateKey)
{
if (!rsaPrivateKey)
{
std::cout << "The key is not a RSA key" << std::endl;
return false;
}
m_privateKey = std::unique_ptr<Botan::RSA_PrivateKey>(rsaPrivateKey);
return true;
}
std::unique_ptr<License> LicenseGenerator::createLicense(
const std::string& user,
const std::string& type,
size_t numberOfUsers,
const std::string& expirationVersion,
const std::string& expirationDate
){
if (user.empty())
{
std::cout << "No user given" << std::endl;
return nullptr;
}
if (type.empty())
{
std::cout << "No license type given" << std::endl;
return nullptr;
}
if (expirationVersion.empty())
{
std::cout << "No expiration version given" << std::endl;
return nullptr;
}
if (expirationDate.empty())
{
std::cout << "No expiration date given" << std::endl;
return nullptr;
}
std::unique_ptr<License> license = std::make_unique<License>();
license->setMessage(user, type, numberOfUsers, expirationVersion, expirationDate);
Botan::AutoSeeded_RNG rng;
// encode message
const std::string emsa = "EMSA4(SHA-256)";
Botan::PK_Signer signer(*(m_privateKey.get()), rng, emsa);
Botan::DataSource_Memory in(license->getMessage(false));
Botan::byte buffer[4096] = {0};
while (size_t got = in.read(buffer, sizeof(buffer)))
{
signer.update(buffer, got);
}
const std::string signature = Botan::base64_encode(signer.signature(rng));
license->setSignature(signature);
return license;
}
-78
View File
@@ -1,78 +0,0 @@
#ifndef LICENSE_GENERATOR_H
#define LICENSE_GENERATOR_H
#include <string>
#include <memory>
#include <botan/auto_rng.h>
#include "License.h"
namespace Botan
{
class RSA_PrivateKey;
}
class License;
class LicenseGenerator
{
public:
LicenseGenerator();
~LicenseGenerator();
void generatePrivateKey();
bool loadPrivateKeyFromFile(const std::string& file);
bool loadPrivateKeyFromString(const std::string& key);
Botan::RSA_PrivateKey* getPrivateKey() const;
std::string getPublicKeyPEMFileAsString();
std::string getPrivateKeyPEMFileAsString();
void writeKeysToFiles(const std::string& publicKeyFilename, const std::string& privateKeyFilename);
std::unique_ptr<License> createLicenseByVersion(
const std::string& user,
const std::string& type,
size_t numberOfUsers,
const std::string& version
);
std::unique_ptr<License> createLicenseByQuarters(
const std::string& user,
const std::string& type,
size_t numberOfUsers,
size_t quarters
);
std::unique_ptr<License> createLicenseByDays(
const std::string& user,
const std::string& type,
size_t numberOfUsers,
size_t days
);
std::unique_ptr<License> createLicenseLifelong(
const std::string& user,
const std::string& type,
size_t numberOfUsers
);
private:
bool createPrivateKey(Botan::RSA_PrivateKey* rsaPrivateKey);
std::unique_ptr<License> createLicense(
const std::string& user,
const std::string& type,
size_t numberOfUsers,
const std::string& expirationVersion,
const std::string& expirationDate
);
//Botan
Botan::AutoSeeded_RNG m_rng;
std::unique_ptr<Botan::RSA_PrivateKey> m_privateKey;
};
#endif // KEYGEN_H
-178
View File
@@ -1,178 +0,0 @@
#include <iostream>
#include <fstream>
#include <sstream>
#include <memory>
#include <boost/program_options.hpp>
#include "LicenseChecker.h"
#include "LicenseGenerator.h"
#include "PrivateKey.h"
#include "PublicKey.h"
namespace po = boost::program_options;
bool process_command_line(int argc, char** argv)
{
try
{
std::string user;
std::string version;
std::string privateKeyFile = "private-sourcetrail.pem";
std::string publicKeyFile = "public-sourcetrail.pem";
std::string licenseFile = "license.txt";
std::string type = "";
int quarters = 4;
int days = 0;
int numberOfUsers = 0;
po::options_description modes_description("Sourcetrail Generator Modes");
modes_description.add_options()
("key,k", "Generate the private and public key")
("generate,g", po::value<std::string>(&user), "Generate a License, USERNAME as value")
("check,c", "Validate a License");
po::options_description keygen_description("Options License Generation");
keygen_description.add_options()
("version,v", po::value<std::string>(&version), "Versionnumber (in format 20xx.x) until Sourcetrail valid")
("quarters,q", po::value<int>(&quarters), "Number of quarters Sourcetrail is valid from now")
("users,u", po::value<int>(&numberOfUsers), "Number of users")
("licenseType,t", po::value<std::string>(&type), "License Type of ")
("expiration,e", po::value<int>(&days), "Valid for <value> days")
("lifelong,l", "Valid perpetually");
po::options_description advanced_description("Advanced Options");
advanced_description.add_options()
("public-file", po::value<std::string>(&publicKeyFile), "Custom public key file")
("private-file", po::value<std::string>(&privateKeyFile), "Custom private key file")
("license-file", po::value<std::string>(&licenseFile), "Custom license (default: license.txt)");
po::options_description desc("Sourcetrail Generator");
desc.add_options()
("help,h", "Print this help message");
desc.add(modes_description).add(keygen_description).add(advanced_description);
po::variables_map vm;
po::store(po::parse_command_line(argc,argv,desc), vm);
po::notify(vm);
// display help if no argument or the help argument is given
if (vm.count("help"))
{
std::cout << desc << std::endl;
return true;
}
// no mode chosen -> display help
if ( vm.size() == 0 || !(vm.count("hidden") || vm.count("key") || vm.count("check") || vm.count("generate")))
{
std::cout << "*****************************\nNo mode chosen, display help: "
<< "\n*****************************\n\n" << desc << std::endl;
return false;
}
LicenseGenerator keygen;
if (vm.count("key"))
{
keygen.generatePrivateKey();
keygen.writeKeysToFiles(publicKeyFile, privateKeyFile);
return true;
}
if (vm.count("private-file"))
{
keygen.loadPrivateKeyFromFile(privateKeyFile);
}
else
{
keygen.loadPrivateKeyFromString(PRIVATE_KEY);
}
if (vm.count("generate"))
{
// make sure there is no negative amount of users
if (vm.count("users"))
{
if (numberOfUsers < 0)
{
std::cout << "Invalid amount of users. (Must be > 0)" << std::endl;
return false;
}
}
std::unique_ptr<License> license;
if (vm.count("lifelong"))
{
license = keygen.createLicenseLifelong(user, type, numberOfUsers);
}
else if (vm.count("expiration"))
{
license = keygen.createLicenseByDays(user, type, numberOfUsers, days);
}
else if (!version.empty())
{
license = keygen.createLicenseByVersion(user, type, numberOfUsers, version);
}
else
{
license = keygen.createLicenseByQuarters(user, type, numberOfUsers, quarters);
}
if (license)
{
license->print();
license->writeToFile(licenseFile);
}
}
if (vm.count("check"))
{
if (vm.count("public-file"))
{
LicenseChecker::loadPublicKeyFromFile(publicKeyFile);
}
else
{
LicenseChecker::loadPublicKey();
}
License license;
LicenseChecker::LicenseState state = LicenseChecker::LicenseState::EMPTY;
if (license.loadFromFile(licenseFile))
{
state = LicenseChecker::checkLicense(license);
}
else
{
state = LicenseChecker::LicenseState::MALFORMED;
}
if (state == LicenseChecker::LicenseState::VALID)
{
std::cout << "License valid" << std::endl;
}
else
{
std::cout << LicenseChecker::getLicenseErrorForState(state) << std::endl;
}
}
}
catch (std::exception& e)
{
std::cout << "Exception caught: " << e.what() << std::endl;
return false;
}
return true;
}
int main(int argc, char *argv[])
{
process_command_line(argc, argv);
return 0;
}
-2
View File
@@ -19,8 +19,6 @@ add_files(
FilePathTestSuite.h
FileSystemTestSuite.h
GraphTestSuite.h
LicenseCheckerTestSuite.h
LicenseGeneratorTestSuite.h
LogManagerTestSuite.h
LowMemoryStringMapTestSuite.h
MatrixBaseTestSuite.h
-704
View File
@@ -1,704 +0,0 @@
#include <cxxtest/TestSuite.h>
#include "License.h"
#include "LicenseChecker.h"
#include "Version.h"
class LicenseCheckerTestSuite : public CxxTest::TestSuite
{
public:
void test_check_empty_license()
{
LicenseChecker::loadPublicKey();
LicenseChecker::LicenseState state = LicenseChecker::checkLicenseString("");
TS_ASSERT_EQUALS(state, LicenseChecker::LicenseState::EMPTY);
}
void test_check_malformed_license()
{
LicenseChecker::loadPublicKey();
LicenseChecker::LicenseState state = LicenseChecker::checkLicenseString(
R"(-----BEGIN LICENSE-----
Product: Sourcetrail
License holder: Jane Doe
License type: Commercial License
Licensed number of users: 3
Licensed usage period: until 2021-Dec-10
-
$9$AQAKpvMMWlY7aWaMQY/AScwUo/nhqFdj+skS46v+7QHoj7X6qS+W
IErtt71WhVoqM8eki8IS+BDuO+TyLCAKhpNYQhvgykgfAx16T3ypD4A
4/DKGZbm/ZzZ3J5KD30Ko7pZfsgCnBMZu+VHSkoxtntDCzmhNySF4yo
fiDVhR9NYeWjgd0jtj1+dpBfjmQeXLgf4DqtYvgW446pUfEIIur174y
ffYziDA9VhIpgx2ZEYfFFXWNY+0esAkN389UxZ5UgQcs0LHTdEBphYO
oZJKdZdPbF+zSPwUeRej9SkCOpionrJ9lvVMo3p2pro0boeM4/bAs/p
MyEDaYFJdoazS3T8CXB0oPdEoyvYR6kOBZCw9YeW1Ud0azN8BeMx68c
gwitGhNQeI9A==
-----END LICENSE-----)"
);
TS_ASSERT_EQUALS(state, LicenseChecker::LicenseState::MALFORMED);
}
void test_check_invalid_license()
{
LicenseChecker::loadPublicKey();
LicenseChecker::LicenseState state = LicenseChecker::checkLicenseString(
R"(-----BEGIN LICENSE-----
Product: Sourcetrail
License holder: Jane Doe
License type: Commercial License
Licensed number of users: 3
Licensed product version: unlimited
Licensed usage period: until 2021-Dec-10
-
$9$AQAKpvMMWlY7aWaMQY/AScwUo/nhqFdj+skS46v+7QHoj7X6qS+W
IErtt71WhVoqM8eki8IS+BDuO+TyLCAKhpNYQhvgykgfAx16T3ypD4A
4/DKGZbm/ZzZ3J5KD30Ko7pZfsgCnBMZu+VHSkoxtntDCzmhNySF4yo
fiDVhR9NYeWjgd0jtj1+dpBfjmQeXLgf4DqtYvgW446pUfEIIur174y
ffYziDA9VhIpgx2ZEYfFFXWNY+0esAkN389UxZ5UgQcs0LHTdEBphYO
oZJKdZdPbF+zSPwUeRej9SkCOpionrJ9lvVMo3p2pro0boeM4/bAs/p
MyEDaYFJdoazS3T8CXB0oPdEoyvYR6kOBZCw9YeW1Ud0azN8BeMx68C
gwitGhNQeI9A==
-----END LICENSE-----)"
);
TS_ASSERT_EQUALS(state, LicenseChecker::LicenseState::INVALID);
}
void test_check_license_without_start_end()
{
LicenseChecker::loadPublicKey();
LicenseChecker::LicenseState state = LicenseChecker::checkLicenseString(
R"(
Product: Sourcetrail
License holder: Jane Doe
License type: Commercial License
Licensed number of users: 3
Licensed product version: unlimited
Licensed usage period: until 2021-Dec-10
-
$9$AQAKpvMMWlY7aWaMQY/AScwUo/nhqFdj+skS46v+7QHoj7X6qS+W
IErtt71WhVoqM8eki8IS+BDuO+TyLCAKhpNYQhvgykgfAx16T3ypD4A
4/DKGZbm/ZzZ3J5KD30Ko7pZfsgCnBMZu+VHSkoxtntDCzmhNySF4yo
fiDVhR9NYeWjgd0jtj1+dpBfjmQeXLgf4DqtYvgW446pUfEIIur174y
ffYziDA9VhIpgx2ZEYfFFXWNY+0esAkN389UxZ5UgQcs0LHTdEBphYO
oZJKdZdPbF+zSPwUeRej9SkCOpionrJ9lvVMo3p2pro0boeM4/bAs/p
MyEDaYFJdoazS3T8CXB0oPdEoyvYR6kOBZCw9YeW1Ud0azN8BeMx68c
gwitGhNQeI9A==
)"
);
TS_ASSERT_EQUALS(state, LicenseChecker::LicenseState::VALID);
}
void test_license_encoding()
{
LicenseChecker::loadPublicKey();
LicenseChecker::setCurrentLicenseString(
R"(-----BEGIN LICENSE-----
Product: Sourcetrail
License holder: Jane Doe
License type: Commercial License
Licensed number of users: 3
Licensed product version: unlimited
Licensed usage period: until 2021-Dec-10
-
$9$AQAKpvMMWlY7aWaMQY/AScwUo/nhqFdj+skS46v+7QHoj7X6qS+W
IErtt71WhVoqM8eki8IS+BDuO+TyLCAKhpNYQhvgykgfAx16T3ypD4A
4/DKGZbm/ZzZ3J5KD30Ko7pZfsgCnBMZu+VHSkoxtntDCzmhNySF4yo
fiDVhR9NYeWjgd0jtj1+dpBfjmQeXLgf4DqtYvgW446pUfEIIur174y
ffYziDA9VhIpgx2ZEYfFFXWNY+0esAkN389UxZ5UgQcs0LHTdEBphYO
oZJKdZdPbF+zSPwUeRej9SkCOpionrJ9lvVMo3p2pro0boeM4/bAs/p
MyEDaYFJdoazS3T8CXB0oPdEoyvYR6kOBZCw9YeW1Ud0azN8BeMx68c
gwitGhNQeI9A==
-----END LICENSE-----)"
);
LicenseChecker::LicenseState state = LicenseChecker::checkCurrentLicense();
TS_ASSERT_EQUALS(state, LicenseChecker::LicenseState::VALID);
LicenseChecker::setEncodeKey("test_key");
std::string encodedLicenseString = LicenseChecker::getCurrentLicenseStringEncoded();
LicenseChecker::setEncodeKey("test_key_new");
state = LicenseChecker::setCurrentLicenseStringEncoded(encodedLicenseString);
TS_ASSERT_EQUALS(state, LicenseChecker::LicenseState::MALFORMED);
LicenseChecker::setEncodeKey("test_key");
state = LicenseChecker::setCurrentLicenseStringEncoded(encodedLicenseString);
TS_ASSERT_EQUALS(state, LicenseChecker::LicenseState::VALID);
}
void test_check_version_license()
{
License license;
bool ok = license.loadFromString(
R"(-----BEGIN LICENSE-----
Product: Sourcetrail
License holder: Jane Doe
License type: Commercial License
Licensed number of users: 1
Licensed product version: up to 2020.2
Licensed usage period: unlimited
-
$9$AQAKrGHpbkd9I+FVXZ8YtKK7rJePuPqJcWwaLoNYze14fRNiIBQV
QcelksnNcsztdUVCSp1MPkEbuWHkhR74m5qJ3wECnMekfVmP3GhbvwL
cqAEyrpR4PrZCRM2oxEgcRVk6QrPM9pHYPaPHe8sV74odOGQtHUrEW6
N8ZNL0NMLzSxurD/hXdDLdgxya9UptYIJ6c2Bbu33xJ87Ofs07pptc0
4VzBXJYG5iKIbmQAnrU6KOBL5iIZ11/sM8VbkTw+nSySI4yr3/f8BWe
7PhDAmhvDTX9aMMfpaXXeL3PyC/023FwyAqimB1vzoo28Pm1p1tN9mF
l7Ci+UazTnVY34DLVoXYUaDVlt8t8VYq05Z7f6sfcGtqpthuevGatM0
e6G8hqqTc+CQ==
-----END LICENSE-----)"
);
Version version = Version::getApplicationVersion();
Version::setApplicationVersion(Version(2020, 2, 11, "asdfasdf"));
TS_ASSERT(ok);
TS_ASSERT_EQUALS(license.getUser(), "Jane Doe");
TS_ASSERT_EQUALS(license.getType(), "Commercial License");
TS_ASSERT_EQUALS(license.getNumberOfUsers(), 1);
TS_ASSERT_EQUALS(license.getTimeLeft(), -2);
TS_ASSERT(license.isComplete());
TS_ASSERT(!license.isEmpty());
TS_ASSERT(!license.isExpired());
TS_ASSERT(!license.isTestLicense());
LicenseChecker::loadPublicKey();
TS_ASSERT_EQUALS(LicenseChecker::checkLicense(license), LicenseChecker::LicenseState::VALID);
Version::setApplicationVersion(version);
}
void test_check_version_license_expired()
{
License license;
bool ok = license.loadFromString(
R"(-----BEGIN LICENSE-----
Product: Sourcetrail
License holder: Jane Doe
License type: Commercial License
Licensed number of users: 1
Licensed product version: up to 2018.2
Licensed usage period: unlimited
-
$9$AQAKshj0tavIV6xR/dL9nXxaxib80g8Kxho0CGpvdypb4xujP5nw
mIQi3TiVrBTCszJLONCdnhyzotj1R370JPHWa/FFbGqABhexI5PGdIb
3Pa1EqQP9otCJZvDhQTxkm2Ev3zFEgDsA8njBQjr09Blcbt6F9F5zpJ
Ld75PRPLgvVmrxJfwOOg0tYQ/WrKzmm68gcF7XUHS1N7QDSrxjkqihu
xvHd6PoQSmX8pbNpYbkNF6N1T7rR5B8o7BnCc1PEw13J6k8CsomyQ4Q
qg2qAz0IOXk+r7ZagNvR9XedqcytIu6e0u48ujpEUv+1TSj7VBrOq1a
5La45aDoFn2XgdX/mlJh4RPeTEtg6u06PHf4pHFWiOXyKcvvAWuy7GT
YeDldWiy3iwA==
-----END LICENSE-----)"
);
Version version = Version::getApplicationVersion();
Version::setApplicationVersion(Version(2018, 3, 11, "asdfasdf"));
TS_ASSERT(ok);
TS_ASSERT_EQUALS(license.getUser(), "Jane Doe");
TS_ASSERT_EQUALS(license.getType(), "Commercial License");
TS_ASSERT_EQUALS(license.getNumberOfUsers(), 1);
TS_ASSERT_EQUALS(license.getTimeLeft(), -2);
TS_ASSERT(license.isComplete());
TS_ASSERT(!license.isEmpty());
TS_ASSERT(license.isExpired());
TS_ASSERT(!license.isTestLicense());
LicenseChecker::loadPublicKey();
TS_ASSERT_EQUALS(LicenseChecker::checkLicense(license), LicenseChecker::LicenseState::EXPIRED);
Version::setApplicationVersion(version);
}
void test_check_period_license()
{
License license;
bool ok = license.loadFromString(
R"(-----BEGIN LICENSE-----
Product: Sourcetrail
License holder: Jane Doe
License type: Commercial License
Licensed number of users: 3
Licensed product version: unlimited
Licensed usage period: until 2021-Dec-10
-
$9$AQAKpvMMWlY7aWaMQY/AScwUo/nhqFdj+skS46v+7QHoj7X6qS+W
IErtt71WhVoqM8eki8IS+BDuO+TyLCAKhpNYQhvgykgfAx16T3ypD4A
4/DKGZbm/ZzZ3J5KD30Ko7pZfsgCnBMZu+VHSkoxtntDCzmhNySF4yo
fiDVhR9NYeWjgd0jtj1+dpBfjmQeXLgf4DqtYvgW446pUfEIIur174y
ffYziDA9VhIpgx2ZEYfFFXWNY+0esAkN389UxZ5UgQcs0LHTdEBphYO
oZJKdZdPbF+zSPwUeRej9SkCOpionrJ9lvVMo3p2pro0boeM4/bAs/p
MyEDaYFJdoazS3T8CXB0oPdEoyvYR6kOBZCw9YeW1Ud0azN8BeMx68c
gwitGhNQeI9A==
-----END LICENSE-----)"
);
TS_ASSERT(ok);
TS_ASSERT_EQUALS(license.getUser(), "Jane Doe");
TS_ASSERT_EQUALS(license.getType(), "Commercial License");
TS_ASSERT_EQUALS(license.getNumberOfUsers(), 3);
TS_ASSERT(license.getTimeLeft() >= 0);
TS_ASSERT(license.isComplete());
TS_ASSERT(!license.isEmpty());
TS_ASSERT(!license.isExpired());
TS_ASSERT(!license.isTestLicense());
LicenseChecker::loadPublicKey();
TS_ASSERT_EQUALS(LicenseChecker::checkLicense(license), LicenseChecker::LicenseState::VALID);
}
void test_check_period_license_expired()
{
License license;
bool ok = license.loadFromString(
R"(-----BEGIN LICENSE-----
Product: Sourcetrail
License holder: Jane Doe
License type: Commercial License
Licensed number of users: 3
Licensed product version: unlimited
Licensed usage period: until 2018-Dec-06
-
$9$AQAKkgTBy1koMv8CusfbUVWyMQtbTc67dSMTv+96bnVWSQdc/Bti
O8300TO2SWEVuyMo/BQkmXTnEFWLtwnAPqtAJXLR4oDTqlHUNs8Ur5q
iL6dMVsiyp41EHrzuof1/u+pgX03kCyIgD6TAn42En3+2pgo1zhDxnx
vaBxQTUcUW8+kJyNdSlJ6E2DgwGX2uXmf8MF8nsJtwHhOe/3qyV6fm0
PtXmWwjesNX7qGA8L+pcZKsB6AdC4dEJ71iFr8u/O1i8ab0v5xorJM3
zJ40jE0kcucpag5sW43ch0eX6PntXSwXuFfaQ7gTUH6qYTvxqIFUZGW
r0TrPuhiyxHS80ki5QApv9AShXlt3LRM41SJSCuv71Z30kGIVV6Itoo
+rtjllrh9TBA==
-----END LICENSE-----)"
);
TS_ASSERT(ok);
TS_ASSERT_EQUALS(license.getUser(), "Jane Doe");
TS_ASSERT_EQUALS(license.getType(), "Commercial License");
TS_ASSERT_EQUALS(license.getNumberOfUsers(), 3);
TS_ASSERT_EQUALS(license.getTimeLeft(), -1);
TS_ASSERT(license.isComplete());
TS_ASSERT(!license.isEmpty());
TS_ASSERT(license.isExpired());
TS_ASSERT(!license.isTestLicense());
LicenseChecker::loadPublicKey();
TS_ASSERT_EQUALS(LicenseChecker::checkLicense(license), LicenseChecker::LicenseState::EXPIRED);
}
void test_check_site_license()
{
License license;
bool ok = license.loadFromString(
R"(-----BEGIN LICENSE-----
Product: Sourcetrail
License holder: Jane Doe
License type: Commercial License
Licensed number of users: unlimited
Licensed product version: unlimited
Licensed usage period: until 2021-Dec-10
-
$9$AQAKM0lWahp0xKiqVObgsjtpg9LNh+knuPSDbbv/6LuJqbZYA2F2
ibdICkHLfDTIiUjqXdmLbNWbavWwcrtOnzw7zxExIyCcJPXrQxUjmRU
kvVe+mPlN+4Re1jFBmCY18X13fb9JSShOjWGEnpCR/o6Fq1EKoOoYg1
NyWoVDy+Jv/Tr0Zr1/xFyhQJMw3dr0LiCrmYG0+J9P4lndI7MI4QG3z
0e625imrkJVDJsRUk3V9YXu8XxJTpSfc8tZjolzxCpaAKNzzCQeghdh
hwAEZEqUd3+ULN6lY36laCzRSMOts6506wMMhv4wzT65h8RRrrgJJjw
lnOALOwf+YcHvMpHWBBL18utvvxn1dWUdywBXPfmJnncglP7Cg+/B6q
gPxec/V8S5mA==
-----END LICENSE-----)"
);
TS_ASSERT(ok);
TS_ASSERT_EQUALS(license.getUser(), "Jane Doe");
TS_ASSERT_EQUALS(license.getType(), "Commercial License");
TS_ASSERT_EQUALS(license.getNumberOfUsers(), 0);
TS_ASSERT(license.getTimeLeft() >= 0);
TS_ASSERT(license.isComplete());
TS_ASSERT(!license.isEmpty());
TS_ASSERT(!license.isExpired());
TS_ASSERT(!license.isTestLicense());
LicenseChecker::loadPublicKey();
TS_ASSERT_EQUALS(LicenseChecker::checkLicense(license), LicenseChecker::LicenseState::VALID);
}
void test_check_site_license_expired()
{
License license;
bool ok = license.loadFromString(
R"(-----BEGIN LICENSE-----
Product: Sourcetrail
License holder: Jane Doe
License type: Commercial License
Licensed number of users: unlimited
Licensed product version: unlimited
Licensed usage period: until 2018-Dec-08
-
$9$AQAKi2K2OESpqYwzOE6EPg5ltiYYNV3FYzGT9O/mf8fp8+ovGL5T
aJjHkXuWYsZ71yG4SH7DKrtSKc3nSHT6eBKpxkGeQ/50KMIqbFHUNWm
qsv7mzFeKeoA7e9Hf2X/RfWqBmHTV8eIhaE4qqMKF5DY+fG9Y1qlHEs
oeKJCM6BaxYiPZjG4sMKG2K/6AkT4TbNaHjrBktlE1l4ad8mW1xBXn5
p6ph0waObobOioNZINvLuRrIModAnfjCFVdKtL+HzM8Kg/2Tx7ZPCQV
4Tvj6Jm61OiXAdgZcIoL1DYsZWqIb3HFIJQw7Q+IGsKFgh64oNwh/WP
LZi4XroeDeOJnhX5+sfr0WZoV2BKCsNCsvKNHTtEG9ZGtKSgp8ktgBt
XCElsg55RjkQ==
-----END LICENSE-----)"
);
TS_ASSERT(ok);
TS_ASSERT_EQUALS(license.getUser(), "Jane Doe");
TS_ASSERT_EQUALS(license.getType(), "Commercial License");
TS_ASSERT_EQUALS(license.getNumberOfUsers(), 0);
TS_ASSERT_EQUALS(license.getTimeLeft(), -1);
TS_ASSERT(license.isComplete());
TS_ASSERT(!license.isEmpty());
TS_ASSERT(license.isExpired());
TS_ASSERT(!license.isTestLicense());
LicenseChecker::loadPublicKey();
TS_ASSERT_EQUALS(LicenseChecker::checkLicense(license), LicenseChecker::LicenseState::EXPIRED);
}
void test_check_test_license()
{
License license;
bool ok = license.loadFromString(
R"(-----BEGIN LICENSE-----
Product: Sourcetrail
License holder: Jane Doe
License type: Test License
Licensed number of users: unlimited
Licensed product version: unlimited
Licensed usage period: until 2021-Dec-10
-
$9$AQAKrvzvSMvN038BfcgVNT8rN6/X4pFbYKpU0gMSeH62+Vsd55MC
E6rIwc+vMlHlLzHZsn6+YpSsPX2Hs31JUpkRTAb2X2ln0SZU2mZUL/V
SD4trO/jCUoTaC7FbaXD6F1A8DWuJos706g/MaNWyXc0tUnd3N6HSnZ
UEX0HHQXaKatZh5imexO5NncQtdhObU9PFo0UhXTxQ9wFxrKFzgyIIl
EQqQq4ExHzMz41wDD/476lf43W8O6tfbSRaO2aSlALy/3IqnrZBjllm
girrswPR5tAq8JCL8hxenkajWK7plnlg4tUuvpvnj/fif/2Km5v7Xls
+MDZZ7EC7hRX2UUHmIWAnCaiv25k/NHfu1GBQ19mS8mWYnRmxXOccAO
qCavX9fMG6pQ==
-----END LICENSE-----)"
);
TS_ASSERT(ok);
TS_ASSERT_EQUALS(license.getUser(), "Jane Doe");
TS_ASSERT_EQUALS(license.getType(), "Test License");
TS_ASSERT_EQUALS(license.getNumberOfUsers(), 0);
TS_ASSERT(license.getTimeLeft() >= 0);
TS_ASSERT(license.isComplete());
TS_ASSERT(!license.isEmpty());
TS_ASSERT(!license.isExpired());
TS_ASSERT(license.isTestLicense());
LicenseChecker::loadPublicKey();
TS_ASSERT_EQUALS(LicenseChecker::checkLicense(license), LicenseChecker::LicenseState::VALID);
}
void test_check_test_license_expired()
{
License license;
bool ok = license.loadFromString(
R"(-----BEGIN LICENSE-----
Product: Sourcetrail
License holder: Jane Doe
License type: Test License
Licensed number of users: unlimited
Licensed product version: unlimited
Licensed usage period: until 2018-Dec-06
-
$9$AQAKML9uOsAwGbhR/GdF+idZBjBwcvYuNvym5yLvTweDEOs70IHy
NQBPgvq3TOUPtmKc3DE1lHLB7Fe2/8VNwcg1hkncle9fKh44WGuNIRX
dFPJ40Hl+be8ekrjyKwz1x9fb85mkzheiDQUEC8QOHUUdJJoETgp3Il
dcLDe/UL7Sq3/GpPDH+SaThMM5y+3tluf7yO/4qqRuzbV68YW/DTHEL
47/LvlW1iAypllpeJD7igpCzUEiRYa2m2pSmpOiS0FoXaZ0jhr0LNXm
C6/zLqHZ4xRnUmhDlmTf1mfybi86xOiPeZFfvSVnv5HPtf5Nsk2wGkW
pwim1/hpoCxGJ4hiN9a3cbgnjtqG7yTbfMIiBAxM4JcHt2Dzhs3+r6d
gabQRg1nODDw==
-----END LICENSE-----)"
);
TS_ASSERT(ok);
TS_ASSERT_EQUALS(license.getUser(), "Jane Doe");
TS_ASSERT_EQUALS(license.getType(), "Test License");
TS_ASSERT_EQUALS(license.getNumberOfUsers(), 0);
TS_ASSERT_EQUALS(license.getTimeLeft(), -1);
TS_ASSERT(license.isComplete());
TS_ASSERT(!license.isEmpty());
TS_ASSERT(license.isExpired());
TS_ASSERT(license.isTestLicense());
LicenseChecker::loadPublicKey();
TS_ASSERT_EQUALS(LicenseChecker::checkLicense(license), LicenseChecker::LicenseState::EXPIRED);
}
void test_check_lifelong_license()
{
License license;
bool ok = license.loadFromString(
R"(-----BEGIN LICENSE-----
Product: Sourcetrail
License holder: Jane Doe
License type: Commercial License
Licensed number of users: 2
Licensed product version: unlimited
Licensed usage period: unlimited
-
$9$AQAKIZaofFkJU73SLfokexujrBlm792b2tF+oQksC40P+Z8vUtgT
hesYyYrRxFXK2OALm7zLkdeJYNwC60+oJx0wA19D6PLQo09d5Tf3hHx
0pkdV0J+2NwidLoJX6ZHWB2KQxg1Vg0yvczZs4uzNLLd6JRdBubN3XF
0hO9m/sYLMRzeh5sn7WJjV2M/BR1bGmgmY0itW0UXw+hYGZaViiDo1f
7erXFcZq5TJwhYM447TjoWa+KDjPd/hCohO8SKKtJ33qWWuTfJNPL5q
7iqyQemOnBOtW+nXHmg/89F+YXoyGeICxinnFs1kmqMey94s/08OUcB
GSlQ649gX2BuuACmHR/JW/0SY4ik/DgkesVHuRWXD8VTq8cOBMCKjOe
YHCqvUCFHVMA==
-----END LICENSE-----)"
);
TS_ASSERT(ok);
TS_ASSERT_EQUALS(license.getUser(), "Jane Doe");
TS_ASSERT_EQUALS(license.getType(), "Commercial License");
TS_ASSERT_EQUALS(license.getNumberOfUsers(), 2);
TS_ASSERT_EQUALS(license.getTimeLeft(), -2);
TS_ASSERT(license.isComplete());
TS_ASSERT(!license.isEmpty());
TS_ASSERT(!license.isExpired());
TS_ASSERT(!license.isTestLicense());
LicenseChecker::loadPublicKey();
TS_ASSERT_EQUALS(LicenseChecker::checkLicense(license), LicenseChecker::LicenseState::VALID);
}
void test_check_long_name()
{
License license;
bool ok = license.loadFromString(
R"(-----BEGIN LICENSE-----
Product: Sourcetrail
License holder: Janestanasolinaria Doestopolstiminikovasotanibanastovic
License type: Commercial License
Licensed number of users: 2
Licensed product version: up to 2023.4
Licensed usage period: unlimited
-
$9$AQAKD2gin+JhXldRL5AkVpoTgNHibszdfWpKSgm+p5zC5wCYiGWd
Vtd8nzkj4Gys3liNW5K1Yu/bfgcoOwjBOh6ZpNXCs9MQaNtfHTNeNXA
6vKwBCyrKruO1Ez1y+63pYN+erVtrxIpy6bTxuSIuD115j++V7sDE6f
oMCTYVAtMoPBxkIDrMB/dRDVu+ZPffAtPl9qA/1Okl697UpFLIC5kOP
YoJmSgwXC0k0lOvF7OyzR95oKUjQifdWgnEH5kpPJ3DqcKsAvSh0bQj
Rmk10RSZo1OmjgYEssKlD04BZMWsgKEeNHVAkovY6mxR4160wOuELxP
Y8odKqEzRcdV/ZWysqZEGPpdeBIqeBd4ZVgN6kEDZqpGktGZL0LThEB
Muf9wa0CwXuw==
-----END LICENSE-----)"
);
TS_ASSERT(ok);
TS_ASSERT_EQUALS(license.getUser(), "Janestanasolinaria Doestopolstiminikovasotanibanastovic");
TS_ASSERT_EQUALS(license.getType(), "Commercial License");
TS_ASSERT_EQUALS(license.getNumberOfUsers(), 2);
TS_ASSERT_EQUALS(license.getTimeLeft(), -2);
TS_ASSERT(license.isComplete());
TS_ASSERT(!license.isEmpty());
TS_ASSERT(!license.isExpired());
TS_ASSERT(!license.isTestLicense());
LicenseChecker::loadPublicKey();
TS_ASSERT_EQUALS(LicenseChecker::checkLicense(license), LicenseChecker::LicenseState::VALID);
}
void test_check_old_format_license()
{
License license;
bool ok = license.loadFromString(
R"(-----BEGIN LICENSE-----
Product: Sourcetrail
Licensed to: Jane Doe
License type: Commercial License (5 users)
Valid up to version: 2020.2
-
$9$AQAKDowaE3jU5qows5JQrqt6iEfM+BKO0uCgN8lYCIAy/qUzfDsI
S8pZMKD9fBNP0QHK1RNAaiwD8qszcnksDHcURUelnCBk2fpAd4YdR2a
IU6CBwkPWAT92K7KE5OfWV2h2odlSTirPb99WqWYnEngibVeBA4cGZD
k+fSpsPz3Dwg66dNUKajf+snii5wE9qa/2XYhV3gLm3Utls2jhpom31
9Ri0uP/5b8Zx8ZWtlT5BDoS8LvVBsOtBe788DSmmF+7hA8xLel+VRvt
mNzs/MWbKg+m0JrIdwaqhDlx+Fpc+rlhb0uWTJxKO2ruRkLcXkZ4ZbS
fnOHl2FZZgsRjnT0AbI9hHNf3clXuJsu85ymGa9ZESBvKRmYWvjpdcs
0yeCOCcxABmw==
-----END LICENSE-----)"
);
Version version = Version::getApplicationVersion();
Version::setApplicationVersion(Version(2019, 1, 11, "asdfasdf"));
TS_ASSERT(ok);
TS_ASSERT_EQUALS(license.getUser(), "Jane Doe");
TS_ASSERT_EQUALS(license.getType(), "Commercial License");
TS_ASSERT_EQUALS(license.getNumberOfUsers(), 5);
TS_ASSERT_EQUALS(license.getTimeLeft(), -2);
TS_ASSERT(license.isComplete());
TS_ASSERT(!license.isEmpty());
TS_ASSERT(!license.isExpired());
TS_ASSERT(!license.isTestLicense());
LicenseChecker::loadPublicKey();
TS_ASSERT_EQUALS(LicenseChecker::checkLicense(license), LicenseChecker::LicenseState::VALID);
Version::setApplicationVersion(version);
}
void test_check_old_format_license_expired()
{
License license;
bool ok = license.loadFromString(
R"(-----BEGIN LICENSE-----
Product: Sourcetrail
Licensed to: Jane Doe
License type: Commercial License (3 users)
Valid up to version: 2018.1
-
$9$AQAK2j5OkBlxfT/3y0XTbMUu/tRchYJxfD1dHgSFXJMXeFPN9h1N
RVewaFTRWub12WkRSq4rHaEt6MKZCtO3ntj8bGJxuvH4ggridXBoJjP
nkHGPMlUvrdbhs/O7uaWvVXf+n7YrZPxeBBdHiXEUI2AaNbig5FzCeS
Gt31yDkLjSkNwdR4zJGoAB2zWfhxFLIzBXv6z+rToBy71hzMbRHnUX2
B8zkBAt12QVCZszbV1XJ8LqOhxkGKdo6RsieBc5s2HJB16IFf0gcxkL
2FRzN6wMlTqs4K4pk8+kxwzB+Ywm+griLgzZo1jbg0JUm4Ou9nppaht
m4mgTH3FBGtob6Spi7H8hGNGgrT1gRmnHLyomwPfKXKuO/snvK3CZCB
yBAHSwjidKqg==
-----END LICENSE-----)"
);
Version version = Version::getApplicationVersion();
Version::setApplicationVersion(Version(2019, 1, 11, "asdfasdf"));
TS_ASSERT(ok);
TS_ASSERT_EQUALS(license.getUser(), "Jane Doe");
TS_ASSERT_EQUALS(license.getType(), "Commercial License");
TS_ASSERT_EQUALS(license.getNumberOfUsers(), 3);
TS_ASSERT_EQUALS(license.getTimeLeft(), -2);
TS_ASSERT(license.isComplete());
TS_ASSERT(!license.isEmpty());
TS_ASSERT(license.isExpired());
TS_ASSERT(!license.isTestLicense());
LicenseChecker::loadPublicKey();
TS_ASSERT_EQUALS(LicenseChecker::checkLicense(license), LicenseChecker::LicenseState::EXPIRED);
Version::setApplicationVersion(version);
}
void test_check_old_format_test_license()
{
License license;
bool ok = license.loadFromString(
R"(-----BEGIN LICENSE-----
Product: Sourcetrail
Licensed to: Jane Doe
License type: Test License (unlimited users)
Valid until: 2022-Jan-30
-
$9$AQAK6jsDjs5kS109CigXYuu89ixUkcRA6BAVOy4PN89wfuFDBY5v
fVaBI7FcM967hoAIM6RHO928Ba8Ct21eZtTwRmvuYpXC4xmKxw9zxEH
eAcxbDrTY+qZJLM9b3cClCHQK+PN+zjOtcEUxm/Yi05hbRv6F5Hq6P+
jv18gIfk2Jz+RnS5ev7ajENop7INhnTex6QW7B3G9W5GD89mzlNhSmQ
aKaqGeUyBEFDwBVdHDo7NlxBCbW5b/o0+xiOHsaMESINkFz7B7tPwtv
JDWHHJYC6gPoQ3E7EtsjoTsUSiNvVuxy2yTozFkCiNfrul9gHUD0Kt8
p/L7p61+0LrU2qRJmJ3j5DHfYK/nc7uIBVrT1juAxYkAtpSSd17NUZW
Yqov3eYdCVEw==
-----END LICENSE-----)"
);
TS_ASSERT(ok);
TS_ASSERT_EQUALS(license.getUser(), "Jane Doe");
TS_ASSERT_EQUALS(license.getType(), "Test License");
TS_ASSERT_EQUALS(license.getNumberOfUsers(), 0);
TS_ASSERT(license.getTimeLeft() >= 0);
TS_ASSERT(license.isComplete());
TS_ASSERT(!license.isEmpty());
TS_ASSERT(!license.isExpired());
TS_ASSERT(license.isTestLicense());
LicenseChecker::loadPublicKey();
TS_ASSERT_EQUALS(LicenseChecker::checkLicense(license), LicenseChecker::LicenseState::VALID);
}
void test_check_old_format_test_license_expired()
{
License license;
bool ok = license.loadFromString(
R"(-----BEGIN LICENSE-----
Product: Sourcetrail
Licensed to: Jane Doe
License type: Test License (unlimited users)
Valid until: 2019-May-04
-
$9$AQAKTC9+XnNMcOoQSd3f+hMUd6zIKvtPVoMMYEC54gAWRSP3UE6r
k9wzoOr91V6HrisqtEprRyaWplxina6feelNv2XeNlFGoTpEa/3b94K
vIJFxViTRP80KPsC463Ef0a9eW6ZQiWJ+eDDUUokKtxikimb+lw3Dkd
e5Q+i6eGmarrrTi6OxEnMuNTSYS8ZpvzjhdEkvksKY+AAjQa44uwoFE
5Bda1BpZOZS7tFq9Sr+dkerAL+SDaHgx8grNuWMxb1YhZvROk7YguNL
jexviF8On4aw2R5LAjXmRDw/E1pzA/JRYfw7rLRz72/8gL034yCRUwu
HjIOkNTpWRBlXCbBZrDfXpjZrfYHLsYOZMmjwTo7I/OHrzUR0cxV6Qh
tgkMf1OQTpsw==
-----END LICENSE-----)"
);
TS_ASSERT(ok);
TS_ASSERT_EQUALS(license.getUser(), "Jane Doe");
TS_ASSERT_EQUALS(license.getType(), "Test License");
TS_ASSERT_EQUALS(license.getNumberOfUsers(), 0);
TS_ASSERT_EQUALS(license.getTimeLeft(), -1);
TS_ASSERT(license.isComplete());
TS_ASSERT(!license.isEmpty());
TS_ASSERT(license.isExpired());
TS_ASSERT(license.isTestLicense());
LicenseChecker::loadPublicKey();
TS_ASSERT_EQUALS(LicenseChecker::checkLicense(license), LicenseChecker::LicenseState::EXPIRED);
}
void test_check_one_hundred_year_testimonial_license()
{
License license;
bool ok = license.loadFromString(
R"(-----BEGIN LICENSE-----
Product: Sourcetrail
Licensed to: Jane Doe
License type: Commercial License (1 Seat)
Valid up to version: 2117.2
-
$9$AQAKhOnW2QeCuuNbHLpUN7CT7DE/FRuOvEOEcHDNOn7yGs0CUIMS
Ox9zCpz0xH/XsNmL6NTyS3P4DOm9snvaJZM90ttr3nxy4Dv3IRWVXvg
OsvwbkYYC+N2WUKJ+ahk8zU7Uz179tdX2FLbce6/xcOi8Utv3thWWWs
EbV62Ja3DS7Qt9Oq7ui+9PrpvPmsc81yK5g993vOsZkPuOuoE8KNX1m
Dhl9UxaBZfmfQVtiAWx1vP8zCJ4nnANgfAAKPBXfYyuvf8/+GDC7CLo
9e5e0swhcMt0z0DfKdwR59sQPZnXSZyouW5GzTUi2E8nw5IStxi3/GX
z3TR0g8ERzP07KrzdYklfYv+cxtlev/H869p0USn5kPBwW8+ZFX+5Id
8CVzujNAz//w==
-----END LICENSE-----)"
);
Version version = Version::getApplicationVersion();
Version::setApplicationVersion(Version(2019, 1, 11, "asdfasdf"));
TS_ASSERT(ok);
TS_ASSERT_EQUALS(license.getUser(), "Jane Doe");
TS_ASSERT_EQUALS(license.getType(), "Commercial License");
TS_ASSERT_EQUALS(license.getNumberOfUsers(), 1);
TS_ASSERT_EQUALS(license.getTimeLeft(), -2);
TS_ASSERT(license.isComplete());
TS_ASSERT(!license.isEmpty());
TS_ASSERT(!license.isExpired());
TS_ASSERT(!license.isTestLicense());
LicenseChecker::loadPublicKey();
TS_ASSERT_EQUALS(LicenseChecker::checkLicense(license), LicenseChecker::LicenseState::VALID);
Version::setApplicationVersion(version);
}
};
-163
View File
@@ -1,163 +0,0 @@
#include <cxxtest/TestSuite.h>
#include "License.h"
#include "LicenseChecker.h"
#include "LicenseGenerator.h"
class LicenseGeneratorTestSuite : public CxxTest::TestSuite
{
public:
void test_create_Keys_with_Version_and_check()
{
LicenseGenerator generator;
generator.generatePrivateKey();
std::string privateKey = generator.getPrivateKeyPEMFileAsString();
std::string publicKey = generator.getPublicKeyPEMFileAsString();
// normally the size is 1886
// sometimes it could happen that the size is 1866
// to prevent the test of failing both sizes are valid
TS_ASSERT(privateKey.size() == 1886 || privateKey.size() == 1866);
TS_ASSERT_EQUALS(publicKey.size(), 451);
}
void test_load_private_Key_from_file()
{
LicenseGenerator generator;
bool ok = generator.loadPrivateKeyFromFile("./data/LicenseGeneratorTestSuite/private-v2.pem");
TS_ASSERT(ok);
}
void test_load_private_key_from_string()
{
LicenseGenerator generator;
bool ok = generator.loadPrivateKeyFromString(m_privateKey);
TS_ASSERT(ok);
}
void test_create_volume_license_and_validate()
{
LicenseGenerator generator;
generator.generatePrivateKey();
std::unique_ptr<License> license = generator.createLicenseByQuarters("TestUser", "VolumeLicense", 20, 4);
TS_ASSERT(license.get());
TS_ASSERT_EQUALS(license->getUser(), "TestUser");
TS_ASSERT_EQUALS(license->getType(), "VolumeLicense");
TS_ASSERT_EQUALS(license->getNumberOfUsers(), 20);
TS_ASSERT_EQUALS(license->isEmpty(), false);
TS_ASSERT_EQUALS(license->isComplete(), true);
TS_ASSERT_EQUALS(license->isExpired(), false);
TS_ASSERT_EQUALS(license->isTestLicense(), false);
TS_ASSERT_EQUALS(license->getTimeLeft(), -2);
TS_ASSERT(LicenseChecker::loadPublicKeyFromString(generator.getPublicKeyPEMFileAsString()));
TS_ASSERT_EQUALS(LicenseChecker::checkLicense(*license.get()), LicenseChecker::LicenseState::VALID);
}
void test_create_test_license_and_validate()
{
LicenseGenerator generator;
generator.generatePrivateKey();
std::unique_ptr<License> license = generator.createLicenseByDays("User", "", 0, 10);
TS_ASSERT(license.get());
TS_ASSERT_EQUALS(license->getUser(), "User");
TS_ASSERT_EQUALS(license->getType(), "Test License");
TS_ASSERT_EQUALS(license->getNumberOfUsers(), 0);
TS_ASSERT_EQUALS(license->isEmpty(), false);
TS_ASSERT_EQUALS(license->isComplete(), true);
TS_ASSERT_EQUALS(license->isExpired(), false);
TS_ASSERT_EQUALS(license->isTestLicense(), true);
TS_ASSERT_EQUALS(license->getTimeLeft(), 10);
TS_ASSERT(LicenseChecker::loadPublicKeyFromString(generator.getPublicKeyPEMFileAsString()));
TS_ASSERT_EQUALS(LicenseChecker::checkLicense(*license.get()), LicenseChecker::LicenseState::VALID);
license = generator.createLicenseByDays("User", "", 0, -10);
TS_ASSERT(license.get());
TS_ASSERT_EQUALS(license->getUser(), "User");
TS_ASSERT_EQUALS(license->getType(), "Test License");
TS_ASSERT_EQUALS(license->getNumberOfUsers(), 0);
TS_ASSERT_EQUALS(license->isEmpty(), false);
TS_ASSERT_EQUALS(license->isComplete(), true);
TS_ASSERT_EQUALS(license->isExpired(), true);
TS_ASSERT_EQUALS(license->isTestLicense(), true);
TS_ASSERT_EQUALS(license->getTimeLeft(), -1);
TS_ASSERT_EQUALS(LicenseChecker::checkLicense(*license.get()), LicenseChecker::LicenseState::EXPIRED);
}
void test_create_licenses_and_check_the_license_info()
{
LicenseGenerator generator;
generator.generatePrivateKey();
std::unique_ptr<License> license = generator.createLicenseByVersion("TestUser", "Private License", 1, "2017.4");
std::string testInfo = "TestUser\nPrivate License\n1 user\nvalid up to version 2017.4";
TS_ASSERT(license.get());
TS_ASSERT_EQUALS(license->getLicenseInfo(), testInfo);
license = generator.createLicenseByVersion("TestUser", "Volume License", 20, "2017.3");
testInfo = "TestUser\nVolume License\n20 users\nvalid up to version 2017.3";
TS_ASSERT(license.get());
TS_ASSERT_EQUALS(license->getLicenseInfo(), testInfo);
license = generator.createLicenseByVersion("TestUser", "Volume License", 0, "2018.3");
testInfo = "TestUser\nVolume License\nunlimited users\nvalid up to version 2018.3";
TS_ASSERT(license.get());
TS_ASSERT_EQUALS(license->getLicenseInfo(), testInfo);
license = generator.createLicenseLifelong("TestUser", "Volume License", 1);
testInfo = "TestUser\nVolume License\n1 user\nvalid perpetually";
TS_ASSERT(license.get());
TS_ASSERT_EQUALS(license->getLicenseInfo(), testInfo);
}
private:
std::string m_privateKey = "-----BEGIN ENCRYPTED PRIVATE KEY-----\n"
"MIIFNTBfBgkqhkiG9w0BBQ0wUjAxBgkqhkiG9w0BBQwwJAQMWEDuADurEQ4T8kJO\n"
"AgMDDUACASAwDAYIKoZIhvcNAgkFADAdBglghkgBZQMEASoEEGNDHYI3xozW5JBg\n"
"pOLkhIMEggTQPwClVPQbk+AVqOAXndQqCs0Ad+eihbekCHt5zkRrYl6JbLq9fvfs\n"
"kGgn1j7xtFZflcZimlLaao8pLWybJfa3xGSJnlYrJsGVMlmKJw/ee3fZG7y4/Tgo\n"
"FytAIP51He4YAZ+4fOXyOoAT0+k2DBekZHeMADX7eXVpCLQXuoQpECvf2IPd/de4\n"
"QKS12FRTd7Hkq7DwYs5D7aBizftcsB6FDqwKvvrheglMHfMt3/ChV8u3F8Zuqnh5\n"
"S1NVl2b8geAnYWLEfN/V8SDu00heVHq+z2CIQrvonsTwN1c9ppgMC7/udcr4GEKU\n"
"kqn/2h1sVRdlCxHf9p2nKRdOUXbSgQi16dKnEim3j3QCLVeNeX5Z6Tkb5pJA397i\n"
"mbL0ihdUvbVcPMG9Rh8NONY+MkE4NKye+NHzWjsd+egaeA79qy/Xd4cJRG7GFy68\n"
"pBWhf/xNpkhXJNV+O/KLszZG6f/UNDPJHovTp47aetD2/EqasvuYkPpapfYuqiZh\n"
"3vtNlgL1uNIN/TjoSaut5+ifJonJnQBrMQdWLTN6I8/lZFfxZB4jLkHffLS/zTA+\n"
"tPLxBcfZiec9dJDmuJ+P55D/3E+p6CL++yw15cgBNPFHrvfatikHvQXkRJl03S6Q\n"
"FvrBmbjWKwT+iSZAvJrdkCeFO53CYA3tJ23GtG9pxBHP+VFyJSBu7MukjcCEMSbU\n"
"HduNcsIIo8/p/X/CXYxJGYIfbrqz0n4z0QkZvCtyJoexoqqjTGclWoN3//j8lenL\n"
"SbrPCwLEn1coGr6rx97LHDBjdR1WouWeGkQOyMF/dC70p4QyE3Ru0cbhsjAWeo7P\n"
"HpGgQHJllJBFM9OkymRD32NnTCtr5Vu6epfiAsi16rfg1j1H9f0hnPbfULx+Q2WM\n"
"sCzuUbKUcjRNXOhwDxQXGVrMXEjRzJKmqy2kpMFX/v38iKfqIx+pHMOs+/+ESwwp\n"
"frKZ2mUwa7DdDv6fZwPUPtZk/6HyqiDoJcoiN05IxdPt6SXGPsseQWcwTdiHhDX2\n"
"3YsTJK0O/CAf/ouqWQiZMAifTZtalTArTvTtlTE7TpAT3I0OmwNG/nI1v/orHBbZ\n"
"M7sa9mlBDMzE4rTHIYMOttNKLxkXRChjgO2JfFDLxscSMw8wsrbGTbKh7VGFgg7Q\n"
"Tj6KAGPiU7WbaXiIhO4adgYp3Bpbo15BhhO5bdaYzxBjOhYw1ShLEgBOC7MsOt3N\n"
"8oChFJB1Gls5+RU6Ef27az+RE6uSumToT1HKgYDYX1TN68WWjT7Pa0lUMtZ4Bv1f\n"
"rXMH8igPXg62kzh/hjnEtl8y2+ySAs7RnZ0vUywaKcI0Tu5tqJSLtXSfJKAPmmzE\n"
"QYsg70kpufXccznTYvLSbM99FIbC6s+cSkJ43Ku4dwbEal+9FfqK639i2X9hdsLc\n"
"bYXIb0Fguo2IbWruBeSIc8lukOKCOVjanVZhfOCev8ye/Wz+SS8zbEixWZMzMCzC\n"
"if4dF/CUHnJK32IVlqKr9XGEe8ympqwMqN0eOdJn8IB+BQGCcaF6805D3R/OG4FU\n"
"hedhIvg1cODtoi8ri41Pz7o1x9Ia0zZr7oxhQuSgHiTfRfFN0xhCFZ+sIfGNpgUs\n"
"54IZGQlI0nQHOK8h2NI0wp3uo+fDEjjVIjQxINOSBa5awSReBpBUW2I=\n"
"-----END ENCRYPTED PRIVATE KEY-----";
std::string m_publicKey = "-----BEGIN PUBLIC KEY-----\n"
"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAugYah7LOU0ssdSnyDA8h\n"
"nOeW2lwE+NmZGxIKnqZKYNePY7Tg0c1pI0lfgJ2WYtxbubDFNDYk6bJF6mFg3jjN\n"
"gCdocj6pyyibIISbRst+gl/1FwI8vbIkfkJBoZtftO5mKVBbO5mmrxm32fDQs1vo\n"
"zgVxcWx3LXW87pzdQQYRACdkLSxPd+ADs+KNv6UxlOEvucDaenX3ckl3HdcWruL8\n"
"xdYoM7z/C+PRShSGvY3wB7Y6A5IcdBmzsTR6xayCmTzzW83dmFzjCX5DSOJLHxq7\n"
"+Fs26xZU83P1boX7eg4TjMViTxJwsCCW/2wfsZAoF0cSYCxhrkSdMHroH7Edz1PM\n"
"fwIDAQAB\n"
"-----END PUBLIC KEY-----\n";
};