| 29 | using namespace openmittsu::dataproviders::messages; |
| 30 | |
| 31 | SimpleDatabase::SimpleDatabase(QString const& filename, QString const& password, QDir const& mediaStorageLocation, bool useCompatibilityToVersionThree) : Database(), database(), m_driverNameCrypto("QSQLCIPHER"), m_driverNameStandard("QSQLITE"), m_connectionName(QStringLiteral("openMittsuDatabaseConnection%1").arg(QDateTime::currentMSecsSinceEpoch())), m_password(password), m_selfContact(0), m_selfLongTermKeyPair(), m_identityBackup(), m_contactAndGroupDataProvider(this, this), m_mediaFileStorage(mediaStorageLocation, this) { |
| 32 | if (!(QSqlDatabase::isDriverAvailable(m_driverNameCrypto) || QSqlDatabase::isDriverAvailable(m_driverNameStandard))) { |
| 33 | throw openmittsu::exceptions::InternalErrorException() << "Neither the SQL driver " << m_driverNameCrypto.toStdString() << " nor the driver " << m_driverNameStandard.toStdString() << " are available. Available are: " << QSqlDatabase::drivers().join(", ").toStdString(); |
| 34 | } |
| 35 | |
| 36 | if (QSqlDatabase::isDriverAvailable(m_driverNameCrypto)) { |
| 37 | LOGGER()->info("Using the crypto-database interface (QSQLCIPHER)."); |
| 38 | database = QSqlDatabase::addDatabase(m_driverNameCrypto, m_connectionName); |
| 39 | m_usingCryptoDb = true; |
| 40 | } else { |
| 41 | #ifdef OPENMITTSU_CONFIG_ALLOW_MISSING_QSQLCIPHER |
| 42 | LOGGER()->info("Using the non-crypto-database interface (QSQLITE)."); |
| 43 | database = QSqlDatabase::addDatabase(m_driverNameStandard, m_connectionName); |
| 44 | m_usingCryptoDb = false; |
| 45 | #else |
| 46 | LOGGER()->error("QSqlCipher is not available, no encryption available. Quiting!"); |
| 47 | throw openmittsu::exceptions::MissingQSqlCipherException() << "QSqlCipher is not available, no encryption available!"; |
| 48 | #endif |
| 49 | } |
| 50 | database.setDatabaseName(filename); |
| 51 | if (!database.open()) { |
| 52 | throw openmittsu::exceptions::InternalErrorException() << "Could not open database file."; |
| 53 | } else if (database.isOpenError()) { |
| 54 | throw openmittsu::exceptions::InternalErrorException() << "Could not open database file, error: " << database.lastError().text().toStdString(); |
| 55 | } else if (!database.isOpen()) { |
| 56 | throw openmittsu::exceptions::InternalErrorException() << "Could not open database file, open failed."; |
| 57 | } |
| 58 | |
| 59 | if (m_usingCryptoDb) { |
| 60 | QString const sqlCipherVersion = getSqlCipherVersion(); |
| 61 | LOGGER()->info("SQLCipher Version reported as '{}'", sqlCipherVersion.toStdString()); |
| 62 | } |
| 63 | |
| 64 | setKey(m_password); |
| 65 | if (m_usingCryptoDb && useCompatibilityToVersionThree) { |
| 66 | QString const sqlCipherVersion = getSqlCipherVersion(); |
| 67 | if (!sqlCipherVersion.startsWith('3')) { |
| 68 | setCompatibilityMode(true); |
| 69 | LOGGER_DEBUG("Trying to open database file with backwards compatiblity flags for version 3!"); |
| 70 | } else { |
| 71 | LOGGER()->info("SQLCipher Version 3 detected, ignoring request for opening database with compatiblity flags."); |
| 72 | } |
| 73 | } |
| 74 | |
| 75 | if (!isDatabaseFileReadableAndValid()) { |
| 76 | throw openmittsu::exceptions::InvalidPasswordOrDatabaseException() << "SQLITE master table does not exist or not readable, invalid database or incorrect password."; |
| 77 | } |
| 78 | |
| 79 | createOrUpdateTables(); |
| 80 | |
| 81 | updateCachedIdentityBackup(); |
| 82 | m_selfContact = m_identityBackup->getClientContactId(); |
| 83 | m_selfLongTermKeyPair = m_identityBackup->getClientLongTermKeyPair(); |
| 84 | |
| 85 | if (!hasContact(m_selfContact)) { |
| 86 | storeNewContact(m_selfContact, m_selfLongTermKeyPair); |
| 87 | } |
| 88 | |