logic: Licenses with seats
This commit is contained in:
+1
-1
@@ -534,7 +534,7 @@ target_include_directories(${LICENSE_GENERATOR_PROJECT_NAME} SYSTEM
|
||||
)
|
||||
|
||||
if(UNIX AND NOT APPLE)
|
||||
target_link_libraries(${LICENSE_GENERATOR_PROJECT_NAME} pthread dl rt)
|
||||
target_link_libraries(${LICENSE_GENERATOR_PROJECT_NAME} pthread rt)
|
||||
endif()
|
||||
|
||||
target_link_libraries(${LICENSE_GENERATOR_PROJECT_NAME} ${LIB_LICENSE_PROJECT_NAME} ${Boost_LIBRARIES} )
|
||||
|
||||
@@ -62,7 +62,7 @@ std::string Generator::encodeLicense(const std::string& user, const int days)
|
||||
return encodeLicense(user, testLicenseTypeString);
|
||||
}
|
||||
|
||||
std::string Generator::encodeLicense(const std::string& user, const std::string& licenseType)
|
||||
std::string Generator::encodeLicense(const std::string& user, const std::string& licenseType, const int seats)
|
||||
{
|
||||
if (user.size() <= 0)
|
||||
{
|
||||
@@ -91,7 +91,7 @@ std::string Generator::encodeLicense(const std::string& user, const std::string&
|
||||
std::cout << "The key is not a RSA key" << std::endl;
|
||||
}
|
||||
|
||||
license.create(user, m_version, rsaKey, licenseType);
|
||||
license.create(user, m_version, rsaKey, licenseType, seats);
|
||||
license.writeToFile("license.txt");
|
||||
license.print();
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ public:
|
||||
Generator(const std::string& version = "x");
|
||||
~Generator();
|
||||
|
||||
std::string encodeLicense(const std::string& message, const std::string& licenseType);
|
||||
std::string encodeLicense(const std::string& message, const std::string& licenseType, const int seats = 0);
|
||||
std::string encodeLicense(const std::string& message, const int days);
|
||||
bool verifyLicense(const std::string& filename = "license.txt");
|
||||
void generateKeys();
|
||||
|
||||
@@ -124,6 +124,21 @@ std::string License::getLicenseTypeLine() const
|
||||
}
|
||||
}
|
||||
|
||||
uint License::getSeats() const
|
||||
{
|
||||
std::string licenseTypeLine = getLicenseTypeLine();
|
||||
std::size_t found = licenseTypeLine.find(":");
|
||||
if (found != std::string::npos)
|
||||
{
|
||||
// +2 (": ")
|
||||
std::stringstream seatsStream(licenseTypeLine.substr(found+2));
|
||||
int seats;
|
||||
seatsStream>>seats;
|
||||
return seats;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int License::getTimeLeft() const
|
||||
{
|
||||
const std::string testText = "Test License - valid till ";
|
||||
@@ -156,10 +171,17 @@ int License::getTimeLeft() const
|
||||
|
||||
void License::create(
|
||||
const std::string& user, const std::string& version,
|
||||
Botan::RSA_PrivateKey* privateKey, const std::string& type)
|
||||
Botan::RSA_PrivateKey* privateKey, const std::string& type, const uint seats)
|
||||
{
|
||||
m_version = version;
|
||||
createMessage(user, version, type);
|
||||
if (seats > 0)
|
||||
{
|
||||
createMessage(user, version, type + ": " + std::to_string(seats) + " seats");
|
||||
}
|
||||
else
|
||||
{
|
||||
createMessage(user, version, type);
|
||||
}
|
||||
|
||||
//encode message
|
||||
Botan::PK_Signer signer(*privateKey, *(m_rng.get()), "EMSA4(SHA-256)");
|
||||
@@ -522,6 +544,11 @@ bool License::loadFromEncodedString(const std::string& encodedLicense, const std
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string License::getHashedLicense() const
|
||||
{
|
||||
return getEncodeKey("fakeKey");
|
||||
}
|
||||
|
||||
std::string License::getEncodeKey(const std::string applicationLocation) const
|
||||
{
|
||||
if (applicationLocation.size() <= 0)
|
||||
|
||||
@@ -27,6 +27,7 @@ public:
|
||||
|
||||
std::string getPublicKeyFilename() const;
|
||||
std::string getVersion() const;
|
||||
uint getSeats() const;
|
||||
|
||||
/// if Test License return >=0 or -1 if expired
|
||||
/// for non Test License -2
|
||||
@@ -34,11 +35,13 @@ public:
|
||||
|
||||
void create(
|
||||
const std::string& user, const std::string& version,
|
||||
Botan::RSA_PrivateKey* privateKey, const std::string& type="Private License"
|
||||
Botan::RSA_PrivateKey* privateKey, const std::string& type="Private License",
|
||||
const uint seats = 0
|
||||
);
|
||||
|
||||
std::string getLicenseString() const;
|
||||
std::string getLicenseEncodedString(const std::string& applicationLocation) const;
|
||||
std::string getHashedLicense() const;
|
||||
|
||||
void writeToFile(const std::string& filename);
|
||||
bool load(std::istream& stream);
|
||||
|
||||
@@ -15,38 +15,84 @@ bool process_command_line(int argc, char** argv)
|
||||
{
|
||||
std::string user;
|
||||
std::string version;
|
||||
std::string privateKey;
|
||||
std::string publicKey;
|
||||
std::string license = "";
|
||||
std::string privateKeyFile;
|
||||
std::string publicKeyFile;
|
||||
std::string licenseFile = "";
|
||||
std::string type = "";
|
||||
int days = 0;
|
||||
po::options_description desc("Coati Generator");
|
||||
int seats = 0;
|
||||
|
||||
po::options_description modes_description("Coati 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 required("Required Options");
|
||||
required.add_options()
|
||||
("version,v", po::value<std::string>(&version), "Versionnumber of Coati");
|
||||
|
||||
po::options_description keygen_description("Options Keygeneration");
|
||||
keygen_description.add_options()
|
||||
("seats,s", po::value<int>(&seats), "Generate a License, USERNAME as value")
|
||||
("version,v", po::value<std::string>(&version), "Versionnumber of Coati")
|
||||
("licenseType,t", po::value<std::string>(&type), "License Type of ")
|
||||
("testLicense,e", po::value<int>(&days), "Generates a test license for <value> days");
|
||||
|
||||
po::options_description hidden_description("Hidden Options");
|
||||
hidden_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")
|
||||
("hidden", "Print this help message");
|
||||
|
||||
po::options_description desc("Coati Generator");
|
||||
desc.add_options()
|
||||
("help,h", "Print this help message")
|
||||
("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")
|
||||
("version,v", po::value<std::string>(&version), "Versionnumber of Coati")
|
||||
("licenseType,t", po::value<std::string>(&type), "License Type of ")
|
||||
("testLicense,e", po::value<int>(&days), "Generates a test license for <value> days")
|
||||
("public-file", po::value<std::string>(&publicKey), "Custom public key file")
|
||||
("private-file", po::value<std::string>(&privateKey), "Custom private key file")
|
||||
("license-file", po::value<std::string>(&license), "Custom license")
|
||||
;
|
||||
("help,h", "Print this help message");
|
||||
desc.add(modes_description).add(required).add(keygen_description);
|
||||
|
||||
po::options_description allDescriptions("Coati Generator");
|
||||
allDescriptions.add_options();
|
||||
allDescriptions.add(modes_description).add(required).add(keygen_description).add(hidden_description);
|
||||
|
||||
po::variables_map vm;
|
||||
|
||||
po::store(po::parse_command_line(argc,argv,desc), vm);
|
||||
po::notify(vm);
|
||||
|
||||
Generator keygen(version);
|
||||
|
||||
if(vm.count("help"))
|
||||
// display help if no argument or the help argument is given
|
||||
if (vm.count("help") || vm.size() == 0)
|
||||
{
|
||||
std::cout << desc << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (vm.count("hidden"))
|
||||
{
|
||||
std::cout << allDescriptions << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// we need a version for all modes
|
||||
// if no version is given there is nothing to do
|
||||
if (!vm.count("version"))
|
||||
{
|
||||
std::cout << "No version specified" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
Generator keygen(version);
|
||||
|
||||
// make sure there are no negative amount of seats
|
||||
if (vm.count("seats"))
|
||||
{
|
||||
if (seats < 0)
|
||||
{
|
||||
std::cout << "Invalid amount of seats. (Must be > 0)" << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (vm.count("key"))
|
||||
{
|
||||
keygen.generateKeys();
|
||||
@@ -55,28 +101,23 @@ bool process_command_line(int argc, char** argv)
|
||||
|
||||
if (vm.count("public-file"))
|
||||
{
|
||||
keygen.setCustomPublicKeyFile(publicKey);
|
||||
keygen.setCustomPublicKeyFile(publicKeyFile);
|
||||
}
|
||||
|
||||
if (vm.count("private-file"))
|
||||
{
|
||||
keygen.setCustomPrivateKeyFile(privateKey);
|
||||
keygen.setCustomPrivateKeyFile(privateKeyFile);
|
||||
}
|
||||
|
||||
if(vm.count("generate"))
|
||||
{
|
||||
if(!vm.count("version"))
|
||||
{
|
||||
std::cout << "Version of Coati is needed to generate a License" << std::endl;
|
||||
return false;
|
||||
}
|
||||
if(vm.count("testLicense"))
|
||||
{
|
||||
keygen.encodeLicense(user,days);
|
||||
}
|
||||
else
|
||||
{
|
||||
keygen.encodeLicense(user,type);
|
||||
keygen.encodeLicense(user,type,seats);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,19 @@ public:
|
||||
TS_ASSERT(ok);
|
||||
}
|
||||
|
||||
void test_create_volume_license_and_validate()
|
||||
{
|
||||
Generator generator("v2");
|
||||
generator.generateKeys();
|
||||
generator.loadPrivateKeyFromString(generator.getPrivateKeyPEMFileAsString());
|
||||
|
||||
License license;
|
||||
license.create("TestUser", "v2", generator.getPrivateKey(), "Volume License", 20);
|
||||
license.loadPublicKeyFromString(generator.getPublicKeyPEMFileAsString());
|
||||
|
||||
TS_ASSERT_EQUALS(license.getSeats(), 20);
|
||||
}
|
||||
|
||||
void test_create_license_and_validate()
|
||||
{
|
||||
Generator generator("v2");
|
||||
|
||||
Reference in New Issue
Block a user