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:
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_ ) {
......
......@@ -65,9 +65,23 @@
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_9" stretch="1,1,2">
<layout class="QHBoxLayout" name="horizontalLayout_9" stretch="0,1,2">
<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>
<layout class="QVBoxLayout" name="verticalLayout">
......
......@@ -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("");
}
}
......
......@@ -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;
......
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