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)
|
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()
|
endif()
|
||||||
|
|
||||||
target_link_libraries(${LICENSE_GENERATOR_PROJECT_NAME} ${LIB_LICENSE_PROJECT_NAME} ${Boost_LIBRARIES} )
|
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);
|
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)
|
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;
|
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.writeToFile("license.txt");
|
||||||
license.print();
|
license.print();
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ public:
|
|||||||
Generator(const std::string& version = "x");
|
Generator(const std::string& version = "x");
|
||||||
~Generator();
|
~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);
|
std::string encodeLicense(const std::string& message, const int days);
|
||||||
bool verifyLicense(const std::string& filename = "license.txt");
|
bool verifyLicense(const std::string& filename = "license.txt");
|
||||||
void generateKeys();
|
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
|
int License::getTimeLeft() const
|
||||||
{
|
{
|
||||||
const std::string testText = "Test License - valid till ";
|
const std::string testText = "Test License - valid till ";
|
||||||
@@ -156,10 +171,17 @@ int License::getTimeLeft() const
|
|||||||
|
|
||||||
void License::create(
|
void License::create(
|
||||||
const std::string& user, const std::string& version,
|
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;
|
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
|
//encode message
|
||||||
Botan::PK_Signer signer(*privateKey, *(m_rng.get()), "EMSA4(SHA-256)");
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string License::getHashedLicense() const
|
||||||
|
{
|
||||||
|
return getEncodeKey("fakeKey");
|
||||||
|
}
|
||||||
|
|
||||||
std::string License::getEncodeKey(const std::string applicationLocation) const
|
std::string License::getEncodeKey(const std::string applicationLocation) const
|
||||||
{
|
{
|
||||||
if (applicationLocation.size() <= 0)
|
if (applicationLocation.size() <= 0)
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ public:
|
|||||||
|
|
||||||
std::string getPublicKeyFilename() const;
|
std::string getPublicKeyFilename() const;
|
||||||
std::string getVersion() const;
|
std::string getVersion() const;
|
||||||
|
uint getSeats() const;
|
||||||
|
|
||||||
/// if Test License return >=0 or -1 if expired
|
/// if Test License return >=0 or -1 if expired
|
||||||
/// for non Test License -2
|
/// for non Test License -2
|
||||||
@@ -34,11 +35,13 @@ public:
|
|||||||
|
|
||||||
void create(
|
void create(
|
||||||
const std::string& user, const std::string& version,
|
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 getLicenseString() const;
|
||||||
std::string getLicenseEncodedString(const std::string& applicationLocation) const;
|
std::string getLicenseEncodedString(const std::string& applicationLocation) const;
|
||||||
|
std::string getHashedLicense() const;
|
||||||
|
|
||||||
void writeToFile(const std::string& filename);
|
void writeToFile(const std::string& filename);
|
||||||
bool load(std::istream& stream);
|
bool load(std::istream& stream);
|
||||||
|
|||||||
@@ -15,38 +15,84 @@ bool process_command_line(int argc, char** argv)
|
|||||||
{
|
{
|
||||||
std::string user;
|
std::string user;
|
||||||
std::string version;
|
std::string version;
|
||||||
std::string privateKey;
|
std::string privateKeyFile;
|
||||||
std::string publicKey;
|
std::string publicKeyFile;
|
||||||
std::string license = "";
|
std::string licenseFile = "";
|
||||||
std::string type = "";
|
std::string type = "";
|
||||||
int days = 0;
|
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()
|
desc.add_options()
|
||||||
("help,h", "Print this help message")
|
("help,h", "Print this help message");
|
||||||
("key,k", "Generate the private and public key")
|
desc.add(modes_description).add(required).add(keygen_description);
|
||||||
("generate,g", po::value<std::string>(&user), "Generate a License, USERNAME as value")
|
|
||||||
("check,c", "Validate a License")
|
po::options_description allDescriptions("Coati Generator");
|
||||||
("version,v", po::value<std::string>(&version), "Versionnumber of Coati")
|
allDescriptions.add_options();
|
||||||
("licenseType,t", po::value<std::string>(&type), "License Type of ")
|
allDescriptions.add(modes_description).add(required).add(keygen_description).add(hidden_description);
|
||||||
("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")
|
|
||||||
;
|
|
||||||
po::variables_map vm;
|
po::variables_map vm;
|
||||||
|
|
||||||
po::store(po::parse_command_line(argc,argv,desc), vm);
|
po::store(po::parse_command_line(argc,argv,desc), vm);
|
||||||
po::notify(vm);
|
po::notify(vm);
|
||||||
|
|
||||||
Generator keygen(version);
|
// display help if no argument or the help argument is given
|
||||||
|
if (vm.count("help") || vm.size() == 0)
|
||||||
if(vm.count("help"))
|
|
||||||
{
|
{
|
||||||
std::cout << desc << std::endl;
|
std::cout << desc << std::endl;
|
||||||
return 1;
|
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"))
|
if (vm.count("key"))
|
||||||
{
|
{
|
||||||
keygen.generateKeys();
|
keygen.generateKeys();
|
||||||
@@ -55,28 +101,23 @@ bool process_command_line(int argc, char** argv)
|
|||||||
|
|
||||||
if (vm.count("public-file"))
|
if (vm.count("public-file"))
|
||||||
{
|
{
|
||||||
keygen.setCustomPublicKeyFile(publicKey);
|
keygen.setCustomPublicKeyFile(publicKeyFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vm.count("private-file"))
|
if (vm.count("private-file"))
|
||||||
{
|
{
|
||||||
keygen.setCustomPrivateKeyFile(privateKey);
|
keygen.setCustomPrivateKeyFile(privateKeyFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(vm.count("generate"))
|
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"))
|
if(vm.count("testLicense"))
|
||||||
{
|
{
|
||||||
keygen.encodeLicense(user,days);
|
keygen.encodeLicense(user,days);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
keygen.encodeLicense(user,type);
|
keygen.encodeLicense(user,type,seats);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,19 @@ public:
|
|||||||
TS_ASSERT(ok);
|
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()
|
void test_create_license_and_validate()
|
||||||
{
|
{
|
||||||
Generator generator("v2");
|
Generator generator("v2");
|
||||||
|
|||||||
Reference in New Issue
Block a user