|
|
@ -21,6 +21,7 @@ |
|
|
|
#include "widget/widget.h" |
|
|
|
#include "widget/widget.h" |
|
|
|
|
|
|
|
|
|
|
|
#include <tox/tox.h> |
|
|
|
#include <tox/tox.h> |
|
|
|
|
|
|
|
#include <tox/toxencryptsave.h> |
|
|
|
|
|
|
|
|
|
|
|
#include <ctime> |
|
|
|
#include <ctime> |
|
|
|
#include <functional> |
|
|
|
#include <functional> |
|
|
@ -113,6 +114,8 @@ Core::~Core() |
|
|
|
alcCloseDevice(alOutDev); |
|
|
|
alcCloseDevice(alOutDev); |
|
|
|
if (alInDev) |
|
|
|
if (alInDev) |
|
|
|
alcCaptureCloseDevice(alInDev); |
|
|
|
alcCaptureCloseDevice(alInDev); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
clearPassword(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Core* Core::getInstance() |
|
|
|
Core* Core::getInstance() |
|
|
@ -1100,14 +1103,27 @@ bool Core::loadConfiguration(QString path) |
|
|
|
} |
|
|
|
} |
|
|
|
else if (error == 1) // Encrypted data save
|
|
|
|
else if (error == 1) // Encrypted data save
|
|
|
|
{ |
|
|
|
{ |
|
|
|
qWarning() << "Core: Can not open encrypted tox save"; |
|
|
|
if (!pwsaltedkey) |
|
|
|
if (QMessageBox::Ok != QMessageBox::warning(nullptr, tr("Encrypted profile"), |
|
|
|
|
|
|
|
tr("Your tox profile seems to be encrypted, qTox can't open it\nDo you want to erase this profile ?"), |
|
|
|
|
|
|
|
QMessageBox::Ok | QMessageBox::Cancel)) |
|
|
|
|
|
|
|
{ |
|
|
|
{ |
|
|
|
qWarning() << "Core: Couldn't open encrypted save, giving up"; |
|
|
|
qWarning() << "Core: Can not open encrypted tox save"; |
|
|
|
configurationFile.close(); |
|
|
|
if (QMessageBox::Ok != QMessageBox::warning(nullptr, tr("Encrypted profile"), |
|
|
|
return false; |
|
|
|
tr("Your tox profile seems to be encrypted, qTox can't open it\nDo you want to erase this profile ?"), |
|
|
|
|
|
|
|
QMessageBox::Ok | QMessageBox::Cancel)) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
qWarning() << "Core: Couldn't open encrypted save, giving up"; |
|
|
|
|
|
|
|
configurationFile.close(); |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
{ /*
|
|
|
|
|
|
|
|
while (error != 0) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
error = tox_encrypted_load(tox, reinterpret_cast<uint8_t *>(data.data()), data.size(), pwsaltedkey, TOX_HASH_LENGTH); |
|
|
|
|
|
|
|
emit blockingGetPassword(); |
|
|
|
|
|
|
|
if (!pwsaltedkey) |
|
|
|
|
|
|
|
// we need a way to start core without any profile
|
|
|
|
|
|
|
|
} */ |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -1137,22 +1153,18 @@ void Core::saveConfiguration() |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
QString profile = Settings::getInstance().getCurrentProfile(); |
|
|
|
QString profile = Settings::getInstance().getCurrentProfile(); |
|
|
|
//qDebug() << "saveConf read profile: " << profile;
|
|
|
|
|
|
|
|
if (profile == "") |
|
|
|
if (profile == "") |
|
|
|
{ // no profile active; this should only happen on startup, if at all
|
|
|
|
{ // no profile active; this should only happen on startup, if at all
|
|
|
|
profile = sanitize(getUsername()); |
|
|
|
profile = sanitize(getUsername()); |
|
|
|
|
|
|
|
|
|
|
|
if (profile == "") // happens on creation of a new Tox ID
|
|
|
|
if (profile == "") // happens on creation of a new Tox ID
|
|
|
|
profile = getIDString(); |
|
|
|
profile = getIDString(); |
|
|
|
//qDebug() << "saveConf: read sanitized user as " << profile;
|
|
|
|
|
|
|
|
Settings::getInstance().setCurrentProfile(profile); |
|
|
|
Settings::getInstance().setCurrentProfile(profile); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
QString path = dir + QDir::separator() + profile + TOX_EXT; |
|
|
|
QString path = directory.filePath(profile + TOX_EXT); |
|
|
|
QFileInfo info(path); |
|
|
|
|
|
|
|
// if (!info.exists()) // fall back to old school 'data'
|
|
|
|
|
|
|
|
// { //path = dir + QDir::separator() + CONFIG_FILE_NAME;
|
|
|
|
|
|
|
|
// qDebug() << "Core:" << path << " does not exist";
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
saveConfiguration(path); |
|
|
|
saveConfiguration(path); |
|
|
|
} |
|
|
|
} |
|
|
@ -1174,10 +1186,32 @@ void Core::saveConfiguration(const QString& path) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
qDebug() << "Core: writing tox_save to " << path; |
|
|
|
qDebug() << "Core: writing tox_save to " << path; |
|
|
|
uint32_t fileSize = tox_size(tox); |
|
|
|
|
|
|
|
|
|
|
|
uint32_t fileSize; |
|
|
|
|
|
|
|
if (Settings::getInstance().getEncryptTox()) |
|
|
|
|
|
|
|
fileSize = tox_encrypted_size(tox); |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
fileSize = tox_size(tox); |
|
|
|
|
|
|
|
|
|
|
|
if (fileSize > 0 && fileSize <= INT32_MAX) { |
|
|
|
if (fileSize > 0 && fileSize <= INT32_MAX) { |
|
|
|
uint8_t *data = new uint8_t[fileSize]; |
|
|
|
uint8_t *data = new uint8_t[fileSize]; |
|
|
|
tox_save(tox, data); |
|
|
|
|
|
|
|
|
|
|
|
if (Settings::getInstance().getEncryptTox()) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (!pwsaltedkey) |
|
|
|
|
|
|
|
emit blockingGetPassword(); |
|
|
|
|
|
|
|
//if (!pwsaltedkey)
|
|
|
|
|
|
|
|
// revert to unsaved...? or maybe we shouldn't even try to get a pw from here ^
|
|
|
|
|
|
|
|
int ret = tox_encrypted_save(tox, data, pwsaltedkey, TOX_HASH_LENGTH); |
|
|
|
|
|
|
|
if (ret == -1) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
qCritical() << "Core::saveConfiguration: encryption of save file failed!!!"; |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
tox_save(tox, data); |
|
|
|
|
|
|
|
|
|
|
|
configurationFile.write(reinterpret_cast<char *>(data), fileSize); |
|
|
|
configurationFile.write(reinterpret_cast<char *>(data), fileSize); |
|
|
|
configurationFile.commit(); |
|
|
|
configurationFile.commit(); |
|
|
|
delete[] data; |
|
|
|
delete[] data; |
|
|
@ -1193,8 +1227,9 @@ void Core::switchConfiguration(const QString& profile) |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
else |
|
|
|
qDebug() << "Core: switching from" << Settings::getInstance().getCurrentProfile() << "to" << profile; |
|
|
|
qDebug() << "Core: switching from" << Settings::getInstance().getCurrentProfile() << "to" << profile; |
|
|
|
saveConfiguration(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
saveConfiguration(); |
|
|
|
|
|
|
|
clearPassword(); |
|
|
|
toxTimer->stop(); |
|
|
|
toxTimer->stop(); |
|
|
|
|
|
|
|
|
|
|
|
if (tox) { |
|
|
|
if (tox) { |
|
|
@ -1488,3 +1523,54 @@ QList<CString> Core::splitMessage(const QString &message) |
|
|
|
|
|
|
|
|
|
|
|
return splittedMsgs; |
|
|
|
return splittedMsgs; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Core::setPassword(QString& password) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (password.isEmpty()) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
clearPassword(); |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (!pwsaltedkey) |
|
|
|
|
|
|
|
pwsaltedkey = new uint8_t[tox_pass_key_length()]; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
CString str(password); |
|
|
|
|
|
|
|
tox_derive_key_from_pass(str.data(), str.size(), pwsaltedkey); |
|
|
|
|
|
|
|
password.clear(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Core::clearPassword() |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (pwsaltedkey) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
delete[] pwsaltedkey; |
|
|
|
|
|
|
|
pwsaltedkey = nullptr; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
QByteArray Core::encryptData(const QByteArray& data) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (!pwsaltedkey) |
|
|
|
|
|
|
|
return QByteArray(); |
|
|
|
|
|
|
|
uint8_t encrypted[data.size() + tox_pass_encryption_extra_length()]; |
|
|
|
|
|
|
|
if (tox_pass_key_encrypt(reinterpret_cast<const uint8_t*>(data.data()), data.size(), pwsaltedkey, encrypted) == -1) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
qWarning() << "Core::encryptData: encryption failed"; |
|
|
|
|
|
|
|
return QByteArray(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return QByteArray(reinterpret_cast<char*>(encrypted), data.size() + tox_pass_encryption_extra_length()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
QByteArray Core::decryptData(const QByteArray& data) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (!pwsaltedkey) |
|
|
|
|
|
|
|
return QByteArray(); |
|
|
|
|
|
|
|
int sz = data.size() - tox_pass_encryption_extra_length(); |
|
|
|
|
|
|
|
uint8_t decrypted[sz]; |
|
|
|
|
|
|
|
if (tox_pass_key_decrypt(reinterpret_cast<const uint8_t*>(data.data()), data.size(), pwsaltedkey, decrypted) != sz) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
qWarning() << "Core::decryptData: decryption failed"; |
|
|
|
|
|
|
|
return QByteArray(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return QByteArray(reinterpret_cast<char*>(decrypted), sz); |
|
|
|
|
|
|
|
} |
|
|
|