Commit 1fc57025 authored by Matthias Möller's avatar Matthias Möller

- fix generating/accepting keys with ascii encoding

- fix crash, if lic file is empty or is a "ERROR" file

git-svn-id: http://www.openflipper.org/svnrepo/OpenFlipper/branches/Free@19540 383ad7c9-94d9-4d36-a494-682f7c89f535
parent 84653c60
...@@ -79,7 +79,7 @@ License File format: ...@@ -79,7 +79,7 @@ License File format:
LicenseManager::~LicenseManager() LicenseManager::~LicenseManager()
{ {
exit(0); exit(0);
} }
...@@ -112,6 +112,56 @@ bool LicenseManager::authenticate() { ...@@ -112,6 +112,56 @@ bool LicenseManager::authenticate() {
authstring_ = "==\n"; authstring_ = "==\n";
authstring_ += "PluginName: " + pluginFileName() + "\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 // Compute hash value of Core application binary
// =============================================================================================== // ===============================================================================================
...@@ -228,7 +278,7 @@ bool LicenseManager::authenticate() { ...@@ -228,7 +278,7 @@ bool LicenseManager::authenticate() {
if ( (currentMac.count(":") == 5) && if ( (currentMac.count(":") == 5) &&
( pCurrAddresses->IfType == IF_TYPE_IEEE80211 || pCurrAddresses->IfType == IF_TYPE_ETHERNET_CSMACD ) ) { ( pCurrAddresses->IfType == IF_TYPE_IEEE80211 || pCurrAddresses->IfType == IF_TYPE_ETHERNET_CSMACD ) ) {
// Cleanup and remember mac adress // Cleanup and remember mac adress
currentMac = currentMac.toUtf8().toUpper(); currentMac = (currentMac.*codingfun)().toUpper();
currentMac = currentMac.remove(":"); currentMac = currentMac.remove(":");
macHashes.push_back(currentMac); macHashes.push_back(currentMac);
} }
...@@ -262,7 +312,7 @@ bool LicenseManager::authenticate() { ...@@ -262,7 +312,7 @@ bool LicenseManager::authenticate() {
} }
// Cleanup mac adress // Cleanup mac adress
QString currentMac = netInterface.hardwareAddress().toUtf8().toUpper(); QString currentMac = (netInterface.hardwareAddress().*codingfun)().toUpper();
currentMac = currentMac.remove(":"); currentMac = currentMac.remove(":");
macHashes.push_back(currentMac); macHashes.push_back(currentMac);
...@@ -276,7 +326,7 @@ bool LicenseManager::authenticate() { ...@@ -276,7 +326,7 @@ bool LicenseManager::authenticate() {
// generate hashes // generate hashes
for (int i = 0 ; i < macHashes.size(); ++i ) 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 // Compute hash of processor information
...@@ -327,7 +377,7 @@ bool LicenseManager::authenticate() { ...@@ -327,7 +377,7 @@ bool LicenseManager::authenticate() {
} }
#endif #endif
QString cpuHash = QCryptographicHash::hash ( processor.toUtf8() , QCryptographicHash::Sha1 ).toHex(); QString cpuHash = QCryptographicHash::hash ( (processor.*codingfun)() , QCryptographicHash::Sha1 ).toHex();
// =============================================================================================== // ===============================================================================================
// Get windows product id // Get windows product id
...@@ -342,54 +392,29 @@ bool LicenseManager::authenticate() { ...@@ -342,54 +392,29 @@ bool LicenseManager::authenticate() {
QString productId = "-"; QString productId = "-";
#endif #endif
QString productHash = QCryptographicHash::hash ( productId.toUtf8() , QCryptographicHash::Sha1 ).toHex(); QString productHash = QCryptographicHash::hash ( (productId.*codingfun)() , QCryptographicHash::Sha1 ).toHex();
// =============================================================================================== // ===============================================================================================
// Check License or generate request // Check License or generate request
// =============================================================================================== // ===============================================================================================
if (!elements.empty()) //valid file was found
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];
// Check expiry date // Check expiry date
QDate currentDate = QDate::currentDate(); QDate currentDate = QDate::currentDate();
QDate expiryDate = QDate::fromString(elements[1],Qt::ISODate); QDate expiryDate = QDate::fromString(elements[1],Qt::ISODate);
bool expired = (currentDate > expiryDate); bool expired = (currentDate > expiryDate);
// Get number of available mac adresses // Get number of available mac adresses
QStringList licensedMacs; QStringList licensedMacs;
for ( int i = 7 ; i < elements.size(); ++i ) { for ( int i = 7 ; i < elements.size(); ++i ) {
licensedMacs.push_back(elements[i]); licensedMacs.push_back(elements[i]);
} }
bool macFound = false; bool macFound = false;
for ( int i = 0; i < macHashes.size(); ++i ) { for ( int i = 0; i < macHashes.size(); ++i ) {
if ( licensedMacs.contains(macHashes[i]) ) if ( licensedMacs.contains(macHashes[i]) )
macFound = true; macFound = true;
} }
if ( !signatureOk ) { if ( !signatureOk ) {
authstring_ += tr("License Error: The license file signature for Plugin \"") + name() + tr("\" is invalid!\n\n"); authstring_ += tr("License Error: The license file signature for Plugin \"") + name() + tr("\" is invalid!\n\n");
} else if ( expired ) { } else if ( expired ) {
...@@ -413,7 +438,7 @@ bool LicenseManager::authenticate() { ...@@ -413,7 +438,7 @@ bool LicenseManager::authenticate() {
// Clean it on success // Clean it on success
if ( authenticated_ ) if ( authenticated_ )
authstring_ = ""; authstring_ = "";
} }
if ( authenticated_ ) { if ( authenticated_ ) {
......
...@@ -65,9 +65,23 @@ ...@@ -65,9 +65,23 @@
</widget> </widget>
</item> </item>
<item> <item>
<layout class="QHBoxLayout" name="horizontalLayout_9" stretch="1,1,2"> <layout class="QHBoxLayout" name="horizontalLayout_9" stretch="0,1,2">
<item> <item>
<widget class="QListWidget" name="keyList"/> <layout class="QVBoxLayout" name="verticalLayout_6">
<property name="leftMargin">
<number>0</number>
</property>
<item>
<widget class="QListWidget" name="keyList"/>
</item>
<item>
<widget class="QLabel" name="lbWarning">
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item> </item>
<item> <item>
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="verticalLayout">
......
...@@ -66,7 +66,7 @@ KeyGen::KeyGen(QString n, QString cHash, QString pHash, QString cpHash, QString ...@@ -66,7 +66,7 @@ KeyGen::KeyGen(QString n, QString cHash, QString pHash, QString cpHash, QString
requestSig = request; requestSig = request;
} }
QString KeyGen::computeSignature() const { QString KeyGen::computeSignature(QByteArray (QString::*_codingfun)()const ) const {
// Get the salts // Get the salts
QString saltPre; QString saltPre;
ADD_SALT_PRE(saltPre); ADD_SALT_PRE(saltPre);
...@@ -76,15 +76,23 @@ QString KeyGen::computeSignature() const { ...@@ -76,15 +76,23 @@ QString KeyGen::computeSignature() const {
QString keyRequest = saltPre + name + coreHash + pluginHash + cpuHash QString keyRequest = saltPre + name + coreHash + pluginHash + cpuHash
+ productHash + macHashes.join("") + saltPost; + productHash + macHashes.join("") + saltPost;
QString requestSigCheck = QString requestSigCheck =
QCryptographicHash::hash(keyRequest.toUtf8(), QCryptographicHash::hash((keyRequest.*_codingfun)(),
QCryptographicHash::Sha1).toHex(); QCryptographicHash::Sha1).toHex();
return requestSigCheck; 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 QString KeyGen::Generate(QString expiryDate) const
...@@ -95,10 +103,9 @@ QString KeyGen::Generate(QString expiryDate) const ...@@ -95,10 +103,9 @@ QString KeyGen::Generate(QString expiryDate) const
QString saltPost; QString saltPost;
ADD_SALT_POST(saltPost); ADD_SALT_POST(saltPost);
QString keyRequest = saltPre + name + coreHash + pluginHash + cpuHash + productHash + macHashes.join("") + saltPost; KeyGen::ValidationResult valid = isValid();
QString requestSigCheck = QCryptographicHash::hash ( keyRequest.toUtf8() , QCryptographicHash::Sha1 ).toHex();
if ( requestSig != requestSigCheck ){ if ( !valid ){
return "ERROR"; return "ERROR";
} }
else{ else{
...@@ -114,8 +121,11 @@ QString KeyGen::Generate(QString expiryDate) const ...@@ -114,8 +121,11 @@ QString KeyGen::Generate(QString expiryDate) const
license_ += macHashes.join("\n") + "\n"; license_ += macHashes.join("\n") + "\n";
QString licenseTmp = saltPre + expiryDate + name + coreHash + pluginHash + cpuHash + productHash + macHashes.join("") + saltPost; 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 // Prepend signature
license_ = licenseHash + "\n" + license_; license_ = licenseHash + "\n" + license_;
return license_; return license_;
...@@ -244,8 +254,11 @@ void KeyGenWidget::slotAnalyze() { ...@@ -244,8 +254,11 @@ void KeyGenWidget::slotAnalyze() {
QListWidgetItem *newItem = new QListWidgetItem( keyList); QListWidgetItem *newItem = new QListWidgetItem( keyList);
newItem->setText(it->name); newItem->setText(it->name);
newItem->setHidden(false); newItem->setHidden(false);
if (!it->isValid()) KeyGen::ValidationResult r = it->isValid();
newItem->setTextColor(QColor(255, 0, 0)); if (!r)
newItem->setTextColor(QColor(255, 0, 0));
else if (r == KeyGen::LATIN1)
newItem->setTextColor(QColor(128, 128, 0));
} }
generateLocalButton->setVisible(false); generateLocalButton->setVisible(false);
...@@ -273,6 +286,14 @@ void KeyGenWidget::handleSelectionChanged(const QItemSelection& selection){ ...@@ -273,6 +286,14 @@ void KeyGenWidget::handleSelectionChanged(const QItemSelection& selection){
setKeyGen(&keygens_[i]); setKeyGen(&keygens_[i]);
generateLocalButton->setVisible(true); generateLocalButton->setVisible(true);
generateAllButton->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("");
} }
} }
......
...@@ -61,8 +61,15 @@ class KeyGen ...@@ -61,8 +61,15 @@ class KeyGen
//returns string containing the key //returns string containing the key
QString Generate(QString expiryDate) const; QString Generate(QString expiryDate) const;
//finds all occurrences of info in messy string //finds all occurrences of info in messy string
QString computeSignature() const; QString computeSignature(QByteArray (QString::*_codingfun)()const = &QString::toUtf8) const;
bool isValid() 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) { void copyHardwareHashesFrom(const KeyGen &rhs) {
cpuHash = rhs.cpuHash; cpuHash = rhs.cpuHash;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment