diff --git a/LicenseManager/LicenseManagerActive.cc b/LicenseManager/LicenseManagerActive.cc index 64cfa77bc9d69adc260c88d4a6254878acce8390..2f9bf10ef546ed7a4a71e6580967c2381945e9ef 100644 --- a/LicenseManager/LicenseManagerActive.cc +++ b/LicenseManager/LicenseManagerActive.cc @@ -79,7 +79,7 @@ License File format: -LicenseManager::~LicenseManager() +LicenseManager::~LicenseManager() { exit(0); } @@ -112,6 +112,56 @@ bool LicenseManager::authenticate() { authstring_ = "==\n"; authstring_ += "PluginName: " + pluginFileName() + "\n"; + // =============================================================================================== + // Read License file, if exists + // =============================================================================================== + QString saltPre; + ADD_SALT_PRE(saltPre); + + QString saltPost; + ADD_SALT_POST(saltPost); + + QString licenseFileName = OpenFlipper::Options::licenseDirStr() + QDir::separator() + pluginFileName() + ".lic"; + QFile file( licenseFileName ); + QStringList elements; //has no elements, if file is invalid or was not found + bool signatureOk = false; + QByteArray (QString::*codingfun)()const = &QString::toUtf8; + + if (file.open(QIODevice::ReadOnly|QIODevice::Text)) + { + QString licenseContents = file.readAll(); + elements = licenseContents.split('\n',QString::SkipEmptyParts); + bool fileOk = !elements.empty() && elements[0] != "ERROR"; + + if (fileOk) + { + // simplify license file entries + for ( int i = 0 ; i < elements.size(); ++i ) + elements[i] = elements[i].simplified(); + + // Check the signature of the file (excluding first element as this is the signature itself) + QString license = saltPre; + for ( int i = 1 ; i < elements.size(); ++i ) + license += elements[i]; + license += saltPost; + QString licenseHash = QCryptographicHash::hash ( license.toUtf8() , QCryptographicHash::Sha1 ).toHex(); + signatureOk = licenseHash == elements[0]; + + if (signatureOk) + codingfun = &QString::toUtf8; + else + { + licenseHash = QCryptographicHash::hash ( license.toLatin1() , QCryptographicHash::Sha1 ).toHex(); + signatureOk = licenseHash == elements[0]; + if (signatureOk) + codingfun = &QString::toLatin1; + } + + } + else + elements = QStringList(); + } + // =============================================================================================== // Compute hash value of Core application binary // =============================================================================================== @@ -228,7 +278,7 @@ bool LicenseManager::authenticate() { if ( (currentMac.count(":") == 5) && ( pCurrAddresses->IfType == IF_TYPE_IEEE80211 || pCurrAddresses->IfType == IF_TYPE_ETHERNET_CSMACD ) ) { // Cleanup and remember mac adress - currentMac = currentMac.toUtf8().toUpper(); + currentMac = (currentMac.*codingfun)().toUpper(); currentMac = currentMac.remove(":"); macHashes.push_back(currentMac); } @@ -262,7 +312,7 @@ bool LicenseManager::authenticate() { } // Cleanup mac adress - QString currentMac = netInterface.hardwareAddress().toUtf8().toUpper(); + QString currentMac = (netInterface.hardwareAddress().*codingfun)().toUpper(); currentMac = currentMac.remove(":"); macHashes.push_back(currentMac); @@ -276,7 +326,7 @@ bool LicenseManager::authenticate() { // generate hashes for (int i = 0 ; i < macHashes.size(); ++i ) - macHashes[i] = QCryptographicHash::hash ( macHashes[i].toUtf8() , QCryptographicHash::Sha1 ).toHex(); + macHashes[i] = QCryptographicHash::hash ( (macHashes[i].*codingfun)() , QCryptographicHash::Sha1 ).toHex(); // =============================================================================================== // Compute hash of processor information @@ -327,7 +377,7 @@ bool LicenseManager::authenticate() { } #endif - QString cpuHash = QCryptographicHash::hash ( processor.toUtf8() , QCryptographicHash::Sha1 ).toHex(); + QString cpuHash = QCryptographicHash::hash ( (processor.*codingfun)() , QCryptographicHash::Sha1 ).toHex(); // =============================================================================================== // Get windows product id @@ -342,54 +392,29 @@ bool LicenseManager::authenticate() { QString productId = "-"; #endif - QString productHash = QCryptographicHash::hash ( productId.toUtf8() , QCryptographicHash::Sha1 ).toHex(); + QString productHash = QCryptographicHash::hash ( (productId.*codingfun)() , QCryptographicHash::Sha1 ).toHex(); // =============================================================================================== // Check License or generate request // =============================================================================================== - - QString saltPre; - ADD_SALT_PRE(saltPre); - - QString saltPost; - ADD_SALT_POST(saltPost); - - QString licenseFileName = OpenFlipper::Options::licenseDirStr() + QDir::separator() + pluginFileName() + ".lic"; - QFile file( licenseFileName ); - - if (file.open(QIODevice::ReadOnly|QIODevice::Text)) { - QString licenseContents = file.readAll(); - QStringList elements = licenseContents.split('\n',QString::SkipEmptyParts); - - // simplify license file entries - for ( int i = 0 ; i < elements.size(); ++i ) - elements[i] = elements[i].simplified(); - - // Check the signature of the file (excluding first element as this is the signature itself) - QString license = saltPre; - for ( int i = 1 ; i < elements.size(); ++i ) - license += elements[i]; - license += saltPost; - QString licenseHash = QCryptographicHash::hash ( license.toUtf8() , QCryptographicHash::Sha1 ).toHex(); - bool signatureOk = licenseHash == elements[0]; - + if (!elements.empty()) //valid file was found + { // Check expiry date QDate currentDate = QDate::currentDate(); QDate expiryDate = QDate::fromString(elements[1],Qt::ISODate); bool expired = (currentDate > expiryDate); - // Get number of available mac adresses QStringList licensedMacs; for ( int i = 7 ; i < elements.size(); ++i ) { licensedMacs.push_back(elements[i]); } - + bool macFound = false; for ( int i = 0; i < macHashes.size(); ++i ) { - if ( licensedMacs.contains(macHashes[i]) ) + if ( licensedMacs.contains(macHashes[i]) ) macFound = true; } - + if ( !signatureOk ) { authstring_ += tr("License Error: The license file signature for Plugin \"") + name() + tr("\" is invalid!\n\n"); } else if ( expired ) { @@ -413,7 +438,7 @@ bool LicenseManager::authenticate() { // Clean it on success if ( authenticated_ ) authstring_ = ""; - + } if ( authenticated_ ) { diff --git a/LicenseManager/keyGen/keygen.ui b/LicenseManager/keyGen/keygen.ui index 81e36d9630020e15c3a08e86f5596bec603851d8..2b1d234a333ea407a78d446a7e2b989f10c1c0f5 100644 --- a/LicenseManager/keyGen/keygen.ui +++ b/LicenseManager/keyGen/keygen.ui @@ -65,9 +65,23 @@ - + - + + + 0 + + + + + + + + + + + + diff --git a/LicenseManager/keyGen/keygenWidget.cc b/LicenseManager/keyGen/keygenWidget.cc index ef8c428f595b24cce232361b1f9731e18f8020e2..090d99d7c9c52ed64da378b753900a5bbe881cb4 100644 --- a/LicenseManager/keyGen/keygenWidget.cc +++ b/LicenseManager/keyGen/keygenWidget.cc @@ -66,7 +66,7 @@ KeyGen::KeyGen(QString n, QString cHash, QString pHash, QString cpHash, QString requestSig = request; } -QString KeyGen::computeSignature() const { +QString KeyGen::computeSignature(QByteArray (QString::*_codingfun)()const ) const { // Get the salts QString saltPre; ADD_SALT_PRE(saltPre); @@ -76,15 +76,23 @@ QString KeyGen::computeSignature() const { QString keyRequest = saltPre + name + coreHash + pluginHash + cpuHash + productHash + macHashes.join("") + saltPost; QString requestSigCheck = - QCryptographicHash::hash(keyRequest.toUtf8(), + QCryptographicHash::hash((keyRequest.*_codingfun)(), QCryptographicHash::Sha1).toHex(); return requestSigCheck; } -bool KeyGen::isValid() const +KeyGen::ValidationResult KeyGen::isValid() const { - return requestSig == computeSignature(); + if (requestSig == computeSignature(&QString::toUtf8)) + { + return UTF8; + } + else if(requestSig == computeSignature(&QString::toLatin1)) + { + return LATIN1; + } + return INVALID; } QString KeyGen::Generate(QString expiryDate) const @@ -95,10 +103,9 @@ QString KeyGen::Generate(QString expiryDate) const QString saltPost; ADD_SALT_POST(saltPost); - QString keyRequest = saltPre + name + coreHash + pluginHash + cpuHash + productHash + macHashes.join("") + saltPost; - QString requestSigCheck = QCryptographicHash::hash ( keyRequest.toUtf8() , QCryptographicHash::Sha1 ).toHex(); + KeyGen::ValidationResult valid = isValid(); - if ( requestSig != requestSigCheck ){ + if ( !valid ){ return "ERROR"; } else{ @@ -114,8 +121,11 @@ QString KeyGen::Generate(QString expiryDate) const license_ += macHashes.join("\n") + "\n"; QString licenseTmp = saltPre + expiryDate + name + coreHash + pluginHash + cpuHash + productHash + macHashes.join("") + saltPost; - QString licenseHash = QCryptographicHash::hash ( licenseTmp.toUtf8() , QCryptographicHash::Sha1 ).toHex(); - + QString licenseHash; + if (valid == UTF8) + licenseHash = QCryptographicHash::hash ( licenseTmp.toUtf8() , QCryptographicHash::Sha1 ).toHex(); + else + licenseHash = QCryptographicHash::hash ( licenseTmp.toLatin1() , QCryptographicHash::Sha1 ).toHex(); // Prepend signature license_ = licenseHash + "\n" + license_; return license_; @@ -244,8 +254,11 @@ void KeyGenWidget::slotAnalyze() { QListWidgetItem *newItem = new QListWidgetItem( keyList); newItem->setText(it->name); newItem->setHidden(false); - if (!it->isValid()) - newItem->setTextColor(QColor(255, 0, 0)); + KeyGen::ValidationResult r = it->isValid(); + if (!r) + newItem->setTextColor(QColor(255, 0, 0)); + else if (r == KeyGen::LATIN1) + newItem->setTextColor(QColor(128, 128, 0)); } generateLocalButton->setVisible(false); @@ -273,6 +286,14 @@ void KeyGenWidget::handleSelectionChanged(const QItemSelection& selection){ setKeyGen(&keygens_[i]); generateLocalButton->setVisible(true); generateAllButton->setVisible(true); + + KeyGen::ValidationResult valid = keygens_[i].isValid(); + if (valid == KeyGen::INVALID) + lbWarning->setText("ERROR: Signature does not match.\nCannot generate key"); + else if (valid == KeyGen::LATIN1) + lbWarning->setText("WARNING: Request uses old Ascii format.\nKey will be generated with Ascii encoding."); + else + lbWarning->setText(""); } } diff --git a/LicenseManager/keyGen/keygenWidget.hh b/LicenseManager/keyGen/keygenWidget.hh index 6d768a994ee9a6b573fa6b4dc9e9d71018b39373..d6ac8b16af8a6b5a8345154e75890e870316e8ca 100644 --- a/LicenseManager/keyGen/keygenWidget.hh +++ b/LicenseManager/keyGen/keygenWidget.hh @@ -61,8 +61,15 @@ class KeyGen //returns string containing the key QString Generate(QString expiryDate) const; //finds all occurrences of info in messy string - QString computeSignature() const; - bool isValid() const; + QString computeSignature(QByteArray (QString::*_codingfun)()const = &QString::toUtf8) const; + enum ValidationResult + { + INVALID = 0, + UTF8 = 1, + LATIN1 = 2 + }; + // returns if the result is valid. INVALID, if invalid, UTF8 if the signature is in new utf8 encoding, latin1 if the signature is in deprecated latin1 encoding + ValidationResult isValid() const; void copyHardwareHashesFrom(const KeyGen &rhs) { cpuHash = rhs.cpuHash;