//============================================================================= // // OpenFlipper // Copyright (C) 2008 by Computer Graphics Group, RWTH Aachen // www.openflipper.org // //----------------------------------------------------------------------------- // // License // // OpenFlipper is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // OpenFlipper is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with OpenFlipper. If not, see . // //----------------------------------------------------------------------------- // // $Revision: 6574 $ // $Author: moebius $ // $Date: 2009-07-08 14:06:06 +0200 (Mi, 08. Jul 2009) $ // //============================================================================= #include #include #include #include #include /* // // CpuIDSupported will return 0 if CPUID instruction is unavailable. Otherwise, it will return // the maximum supported standard function. // unsigned int CpuIDSupported(void) { unsigned int MaxInputValue; // If CPUID instruction is supported #ifndef WIN32 try { MaxInputValue = 0; // call cpuid with eax = 0 asm ( "xorl %%eax,%%eax\n\t" "cpuid\n\t" : "=a" (MaxInputValue) : : "%ebx", "%ecx", "%edx" ); } catch (...) { return(0); // cpuid instruction is unavailable } #else //Win32 try { MaxInputValue = 0; // call cpuid with eax = 0 __asm { xor eax, eax cpuid mov MaxInputValue, eax } } catch (...) { return(0); // cpuid instruction is unavailable } #endif return MaxInputValue; } // // GenuineIntel will return 0 if the processor is not a Genuine Intel Processor // unsigned int GenuineIntel(void) { #ifndef WIN32 unsigned int VendorIDb = 0,VendorIDd = 0, VendorIDc = 0; try // If CPUID instruction is supported { // Get vendor id string asm ( //get the vendor string // call cpuid with eax = 0 "xorl %%eax, %%eax\n\t" "cpuid\n\t" : "=b" (VendorIDb), "=d" (VendorIDd), "=c" (VendorIDc) : : "%eax" ); } catch (...) { return(0); // cpuid instruction is unavailable } return ( (VendorIDb == 'uneG') && (VendorIDd == 'Ieni') && (VendorIDc == 'letn') ); #else unsigned int VendorID[3] = {0, 0, 0}; try // If CPUID instruction is supported { __asm { xor eax, eax // call cpuid with eax = 0 cpuid // Get vendor id string mov VendorID, ebx mov VendorID + 4, edx mov VendorID + 8, ecx } } catch (...) { return(0); unsigned int MaxInputValue =0; // cpuid instruction is unavailable } return ( (VendorID[0] == 'uneG') && (VendorID[1] == 'Ieni') && (VendorID[2] == 'letn') ); #endif } */ LicenseManager::~LicenseManager() { exit(0); } LicenseManager::LicenseManager() { authenticated_ = false; std::cerr << "Constructor Security Interface" << std::endl; QObject::blockSignals( true ); } void LicenseManager::blockSignals( bool _state) { std::cerr << "Block Signals called" << std::endl; if ( !authenticated() ) { QObject::blockSignals( true ); std::cerr << "Request to unblock plugin denied" << std::endl; } else { QObject::blockSignals(_state); std::cerr << "Unblocked Signal" << std::endl; } } bool LicenseManager::authenticate() { std::cerr << "Auth slot" << std::endl; std::cerr << "Application Directory: " << OpenFlipper::Options::applicationDirStr().toStdString() << std::endl; std::cerr << "Plugin Directory: " << OpenFlipper::Options::pluginDirStr().toStdString() << std::endl; std::cerr << "Name: " << name().toStdString() << std::endl; // =============================================================================================== // Compute hash of Core application // =============================================================================================== #ifdef WIN32 QFile coreApp(OpenFlipper::Options::applicationDirStr() + QDir::separator() + "bin" + QDir::separator() + "OpenFlipper.exe"); #else QFile coreApp(OpenFlipper::Options::applicationDirStr() + QDir::separator() + "bin" + QDir::separator() + "OpenFlipper"); #endif if ( ! coreApp.exists() ) { std::cerr << "Error finding core application for security check! : " << coreApp.fileName().toStdString() << std::endl; return false; } coreApp.open(QIODevice::ReadOnly); QCryptographicHash sha1sumCore( QCryptographicHash::Sha1 ); sha1sumCore.addData(coreApp.readAll() ); coreApp.close(); QString coreHash = QString(sha1sumCore.result().toHex()); // =============================================================================================== // Compute hash of Plugin application // =============================================================================================== #ifdef WIN32 QFile pluginFile(OpenFlipper::Options::pluginDirStr() + QDir::separator() + pluginFileName() + ".dll"); #else QFile pluginFile(OpenFlipper::Options::pluginDirStr() + QDir::separator() + pluginFileName() + ".so"); #endif if ( ! pluginFile.exists() ) { std::cerr << "Error finding plugin file for security check!" << std::endl; return false; } pluginFile.open(QIODevice::ReadOnly); QCryptographicHash sha1sumPlugin( QCryptographicHash::Sha1 ); sha1sumPlugin.addData(pluginFile.readAll()); pluginFile.close(); QString pluginHash = QString(sha1sumPlugin.result().toHex()); QString mac; // Get all Network Interfaces QList interfaces = QNetworkInterface::allInterfaces(); foreach ( QNetworkInterface interface, interfaces ) { mac = mac + interface.hardwareAddress().remove(":"); } QString macHash = QCryptographicHash::hash ( mac.toAscii() , QCryptographicHash::Sha1 ).toHex(); // std::cerr << "CPUID Supported : " << CpuIDSupported() << std::endl; // std::cerr << "GenuineIntel : " << GenuineIntel() << std::endl; 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)) { std::cerr << "Unable to find license File " << licenseFileName.toStdString() << std::endl; } else { QString licenseContents = file.readAll(); QStringList elements = licenseContents.split('\n'); for ( int i = 0 ; i < elements.size(); ++i ) elements[i] = elements[i].simplified(); if ( elements.size() != 6 ) { QString sizeMismatchMessage = "The license file for plugin \"" + name() + "\" is invalid!"; QMessageBox::critical(0,"License file size invalid",sizeMismatchMessage ); } else { // Check signature of license file QString license = saltPre + elements[0] + elements[1] + elements[2] + elements[3] + elements[4] + saltPost; license = saltPre + license + saltPost; QString licenseHash = QCryptographicHash::hash ( license.toAscii() , QCryptographicHash::Sha1 ).toHex(); QDate currentDate = QDate::currentDate(); QDate expiryDate = QDate::fromString(elements[4],Qt::ISODate); if ( licenseHash != elements[5] ) { QString signatureMismatchMessage = "The license file signature for plugin \"" + name() + "\" is invalid!"; QMessageBox::critical(0,"License file signature invalid",signatureMismatchMessage ); } else if ( elements[0] != pluginFileName() ) { QString nameMismatchMessage = "The license file contains plugin name\"" + elements[0] + "\" but this is plugin \"" + name() + "\"!"; QMessageBox::critical(0,"License invalid for this plugin",nameMismatchMessage ); } else if ( elements[1] != coreHash ) { QString coreMismatchMessage = "The license file for plugin \"" + name() + "\" is invalid for the currently running OpenFlipper Core!"; QMessageBox::critical(0,"License invalid for current core",coreMismatchMessage ); } else if ( elements[2] != pluginHash ) { QString pluginMismatchMessage = "The plugin \"" + name() + "\" is a different version than specified in license file!"; QMessageBox::critical(0,"License invalid for this plugin",pluginMismatchMessage ); } else if ( elements[3] != macHash ) { QString hardwareMismatchMessage = "The plugin \"" + name() + "\" is not allowed to run on the current system (Changed Hardware?)!"; QMessageBox::critical(0,"License invalid for current System",hardwareMismatchMessage ); } else if ( currentDate > expiryDate ) { QString expiredMessage = "The license for plugin \"" + name() + "\" has expired on " + elements[1] + "!"; QMessageBox::critical(0,"License expired",expiredMessage ); } else { authenticated_ = true; } } } if ( authenticated_ ) std::cerr << "Authentication succcessfull for Plugin " << name().toStdString() << std::endl; else { QString text = "License check for plugin has failed.\n"; text += "Please get a valid License!\n"; text += "Send the following Information to " + CONTACTMAIL + "\n\n"; text += pluginFileName() +"\n"; text += coreHash +"\n"; text += pluginHash +"\n"; text += macHash +"\n"; QString keyRequest = saltPre + pluginFileName() + coreHash+pluginHash+macHash +saltPost; QString requestSig = QCryptographicHash::hash ( keyRequest.toAscii() , QCryptographicHash::Sha1 ).toHex(); text += requestSig + "\n"; QMessageBox::warning ( 0, "Plugin License check failed", text ); std::cerr << "Authentication failed" << std::endl; authenticated_ = false; } // authenticated_ = true; return authenticated_; } bool LicenseManager::authenticated() { return authenticated_; } void LicenseManager::connectNotify ( const char * /*signal*/ ) { std::cerr << "connectNotify Security Interface" << std::endl; if ( !authenticated() ) { blockSignals(true); std::cerr << "Connects failed due to blocked Plugin" << std::endl; } disconnect(); } QString LicenseManager::pluginFileName() { return QString("unset"); }