spot-on-development Mailing List for Spot-On
Brought to you by:
textfield
You can subscribe to this list here.
2013 |
Jan
|
Feb
|
Mar
|
Apr
(121) |
May
(503) |
Jun
(192) |
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
---|
From: <tex...@us...> - 2013-06-17 14:12:28
|
Revision: 1314 http://sourceforge.net/p/spot-on/code/1314 Author: textfield Date: 2013-06-17 14:12:23 +0000 (Mon, 17 Jun 2013) Log Message: ----------- Do not retrieve the private key multiple times. Instead, store it in secure memory. Log errors. Comments. Modified Paths: -------------- branches/0.x/Common/spot-on-gcrypt.cc branches/0.x/Common/spot-on-gcrypt.h branches/0.x/Kernel/spot-on-listener.h Modified: branches/0.x/Common/spot-on-gcrypt.cc =================================================================== --- branches/0.x/Common/spot-on-gcrypt.cc 2013-06-17 12:55:14 UTC (rev 1313) +++ branches/0.x/Common/spot-on-gcrypt.cc 2013-06-17 14:12:23 UTC (rev 1314) @@ -732,6 +732,7 @@ m_iterationCount = 0; // We're not deriving keys. m_passphrase = 0; m_passphraseLength = 0; + m_privateKey = 0; m_symmetricKey = 0; if(m_cipherAlgorithm) @@ -826,6 +827,7 @@ m_iterationCount = iterationCount; m_passphrase = 0; m_passphraseLength = passphrase.length(); + m_privateKey = 0; m_symmetricKey = 0; if(m_cipherAlgorithm) @@ -924,6 +926,7 @@ { gcry_cipher_close(m_cipherHandle); gcry_free(m_passphrase); + gcry_free(m_privateKey); gcry_free(m_symmetricKey); } @@ -1511,58 +1514,79 @@ gcry_sexp_t raw_t = 0; size_t length = 0; - { - QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", "spoton_gcrypt"); + if(!m_privateKey) + { + { + QSqlDatabase db = QSqlDatabase::addDatabase + ("QSQLITE", "spoton_gcrypt"); - db.setDatabaseName(spoton_misc::homePath() + QDir::separator() + - "idiotes.db"); + db.setDatabaseName(spoton_misc::homePath() + QDir::separator() + + "idiotes.db"); - if(db.open()) - { - QSqlQuery query(db); + if(db.open()) + { + QSqlQuery query(db); - query.setForwardOnly(true); - query.prepare("SELECT private_key FROM idiotes WHERE id = ?"); - query.bindValue(0, m_id); + query.setForwardOnly(true); + query.prepare("SELECT private_key FROM idiotes WHERE id = ?"); + query.bindValue(0, m_id); - if(query.exec()) - if(query.next()) - keyData = QByteArray::fromBase64 - (query.value(0).toByteArray()); + if(query.exec()) + if(query.next()) + keyData = QByteArray::fromBase64 + (query.value(0).toByteArray()); + } + + db.close(); } - db.close(); - } + QSqlDatabase::removeDatabase("spoton_gcrypt"); - QSqlDatabase::removeDatabase("spoton_gcrypt"); + if(keyData.isEmpty()) + { + if(ok) + *ok = false; - if(keyData.isEmpty()) - { - if(ok) - *ok = false; + spoton_misc::logError + ("spoton_gcrypt::publicKeyDecrypt(): empty private key."); + goto done_label; + } - spoton_misc::logError - ("spoton_gcrypt::publicKeyDecrypt(): empty private key."); - goto done_label; - } + { + bool ok = true; - { - bool ok = true; + keyData = this->decrypted(keyData, &ok); - keyData = this->decrypted(keyData, &ok); + if(!ok) + keyData.clear(); + } - if(!ok) - keyData.clear(); - } + if(keyData.isEmpty()) + { + if(ok) + *ok = false; - if(keyData.isEmpty()) - { - if(ok) - *ok = false; + spoton_misc::logError + ("spoton_gcrypt::publicKeyDecrypt(): decrypted() failure."); + goto done_label; + } - spoton_misc::logError - ("spoton_gcrypt::publicKeyDecrypt(): decrypted() failure."); - goto done_label; + m_privateKeyLength = keyData.length(); + + if((m_privateKey = + static_cast<char *> (gcry_calloc_secure(m_privateKeyLength, + sizeof(char)))) == 0) + { + m_privateKeyLength = 0; + spoton_misc::logError + ("spoton_gcrypt::publicKeyDecrypt(): gcry_calloc_secure() " + "failure."); + goto done_label; + } + else + memcpy(static_cast<void *> (m_privateKey), + static_cast<const void *> (keyData.constData()), + m_privateKeyLength); } /* @@ -1570,13 +1594,16 @@ */ if((err = gcry_sexp_new(&key_t, - static_cast<const void *> (keyData.constData()), - static_cast<size_t> (keyData.length()), - 1)) != 0 || !key_t) + static_cast<const void *> (m_privateKey), + m_privateKeyLength, 1)) != 0 || !key_t) { if(ok) *ok = false; + gcry_free(m_privateKey); + m_privateKey = 0; + m_privateKeyLength = 0; + if(err != 0) spoton_misc::logError (QString("spoton_gcrypt::publicKeyDecrypt(): gcry_sexp_new() " @@ -1588,17 +1615,10 @@ goto done_label; } - if((err = gcry_pk_testkey(key_t)) != 0) - { - if(ok) - *ok = false; + /* + ** We once tested the private key via gcry_pk_testkey() here. + */ - spoton_misc::logError - (QString("spoton_gcrypt::publicKeyDecrypt(): gcry_pk_testkey() " - "failure (%1).").arg(gcry_strerror(err))); - goto done_label; - } - if((err = gcry_sexp_new(&data_t, static_cast<const void *> (data.constData()), static_cast<size_t> (data.length()), Modified: branches/0.x/Common/spot-on-gcrypt.h =================================================================== --- branches/0.x/Common/spot-on-gcrypt.h 2013-06-17 12:55:14 UTC (rev 1313) +++ branches/0.x/Common/spot-on-gcrypt.h 2013-06-17 14:12:23 UTC (rev 1314) @@ -113,12 +113,14 @@ QString m_hashType; QString m_id; char *m_passphrase; + char *m_privateKey; char *m_symmetricKey; gcry_cipher_hd_t m_cipherHandle; int m_cipherAlgorithm; int m_hashAlgorithm; int m_saltLength; size_t m_passphraseLength; + size_t m_privateKeyLength; size_t m_symmetricKeyLength; unsigned long m_iterationCount; static void init(void); Modified: branches/0.x/Kernel/spot-on-listener.h =================================================================== --- branches/0.x/Kernel/spot-on-listener.h 2013-06-17 12:55:14 UTC (rev 1313) +++ branches/0.x/Kernel/spot-on-listener.h 2013-06-17 14:12:23 UTC (rev 1314) @@ -35,6 +35,7 @@ #include <QTimer> #include "Common/spot-on-external-address.h" +#include "Common/spot-on-misc.h" #include "spot-on-neighbor.h" class QNetworkInterface; @@ -63,6 +64,11 @@ void incomingConnection(int socketDescriptor) #endif { + /* + ** We cannot use findChildren() because the neighbor object + ** may become a child of another object. + */ + if(m_neighbors >= maxPendingConnections()) { QTcpSocket socket; @@ -91,7 +97,12 @@ private slots: void slotNeighborDestroyed(void) { - m_neighbors -= 1; + if(m_neighbors > 0) + m_neighbors -= 1; + else + spoton_misc::logError + ("spoton_listener_tcp_server::slotNeighborDestroyed(): m_neighbors " + "equals zero. Cannot decrement. Internal problem. Please report."); } }; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <tex...@us...> - 2013-06-17 14:12:26
|
Revision: 1314 http://sourceforge.net/p/spot-on/code/1314 Author: textfield Date: 2013-06-17 14:12:23 +0000 (Mon, 17 Jun 2013) Log Message: ----------- Do not retrieve the private key multiple times. Instead, store it in secure memory. Log errors. Comments. Modified Paths: -------------- branches/0.x/Common/spot-on-gcrypt.cc branches/0.x/Common/spot-on-gcrypt.h branches/0.x/Kernel/spot-on-listener.h Modified: branches/0.x/Common/spot-on-gcrypt.cc =================================================================== --- branches/0.x/Common/spot-on-gcrypt.cc 2013-06-17 12:55:14 UTC (rev 1313) +++ branches/0.x/Common/spot-on-gcrypt.cc 2013-06-17 14:12:23 UTC (rev 1314) @@ -732,6 +732,7 @@ m_iterationCount = 0; // We're not deriving keys. m_passphrase = 0; m_passphraseLength = 0; + m_privateKey = 0; m_symmetricKey = 0; if(m_cipherAlgorithm) @@ -826,6 +827,7 @@ m_iterationCount = iterationCount; m_passphrase = 0; m_passphraseLength = passphrase.length(); + m_privateKey = 0; m_symmetricKey = 0; if(m_cipherAlgorithm) @@ -924,6 +926,7 @@ { gcry_cipher_close(m_cipherHandle); gcry_free(m_passphrase); + gcry_free(m_privateKey); gcry_free(m_symmetricKey); } @@ -1511,58 +1514,79 @@ gcry_sexp_t raw_t = 0; size_t length = 0; - { - QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", "spoton_gcrypt"); + if(!m_privateKey) + { + { + QSqlDatabase db = QSqlDatabase::addDatabase + ("QSQLITE", "spoton_gcrypt"); - db.setDatabaseName(spoton_misc::homePath() + QDir::separator() + - "idiotes.db"); + db.setDatabaseName(spoton_misc::homePath() + QDir::separator() + + "idiotes.db"); - if(db.open()) - { - QSqlQuery query(db); + if(db.open()) + { + QSqlQuery query(db); - query.setForwardOnly(true); - query.prepare("SELECT private_key FROM idiotes WHERE id = ?"); - query.bindValue(0, m_id); + query.setForwardOnly(true); + query.prepare("SELECT private_key FROM idiotes WHERE id = ?"); + query.bindValue(0, m_id); - if(query.exec()) - if(query.next()) - keyData = QByteArray::fromBase64 - (query.value(0).toByteArray()); + if(query.exec()) + if(query.next()) + keyData = QByteArray::fromBase64 + (query.value(0).toByteArray()); + } + + db.close(); } - db.close(); - } + QSqlDatabase::removeDatabase("spoton_gcrypt"); - QSqlDatabase::removeDatabase("spoton_gcrypt"); + if(keyData.isEmpty()) + { + if(ok) + *ok = false; - if(keyData.isEmpty()) - { - if(ok) - *ok = false; + spoton_misc::logError + ("spoton_gcrypt::publicKeyDecrypt(): empty private key."); + goto done_label; + } - spoton_misc::logError - ("spoton_gcrypt::publicKeyDecrypt(): empty private key."); - goto done_label; - } + { + bool ok = true; - { - bool ok = true; + keyData = this->decrypted(keyData, &ok); - keyData = this->decrypted(keyData, &ok); + if(!ok) + keyData.clear(); + } - if(!ok) - keyData.clear(); - } + if(keyData.isEmpty()) + { + if(ok) + *ok = false; - if(keyData.isEmpty()) - { - if(ok) - *ok = false; + spoton_misc::logError + ("spoton_gcrypt::publicKeyDecrypt(): decrypted() failure."); + goto done_label; + } - spoton_misc::logError - ("spoton_gcrypt::publicKeyDecrypt(): decrypted() failure."); - goto done_label; + m_privateKeyLength = keyData.length(); + + if((m_privateKey = + static_cast<char *> (gcry_calloc_secure(m_privateKeyLength, + sizeof(char)))) == 0) + { + m_privateKeyLength = 0; + spoton_misc::logError + ("spoton_gcrypt::publicKeyDecrypt(): gcry_calloc_secure() " + "failure."); + goto done_label; + } + else + memcpy(static_cast<void *> (m_privateKey), + static_cast<const void *> (keyData.constData()), + m_privateKeyLength); } /* @@ -1570,13 +1594,16 @@ */ if((err = gcry_sexp_new(&key_t, - static_cast<const void *> (keyData.constData()), - static_cast<size_t> (keyData.length()), - 1)) != 0 || !key_t) + static_cast<const void *> (m_privateKey), + m_privateKeyLength, 1)) != 0 || !key_t) { if(ok) *ok = false; + gcry_free(m_privateKey); + m_privateKey = 0; + m_privateKeyLength = 0; + if(err != 0) spoton_misc::logError (QString("spoton_gcrypt::publicKeyDecrypt(): gcry_sexp_new() " @@ -1588,17 +1615,10 @@ goto done_label; } - if((err = gcry_pk_testkey(key_t)) != 0) - { - if(ok) - *ok = false; + /* + ** We once tested the private key via gcry_pk_testkey() here. + */ - spoton_misc::logError - (QString("spoton_gcrypt::publicKeyDecrypt(): gcry_pk_testkey() " - "failure (%1).").arg(gcry_strerror(err))); - goto done_label; - } - if((err = gcry_sexp_new(&data_t, static_cast<const void *> (data.constData()), static_cast<size_t> (data.length()), Modified: branches/0.x/Common/spot-on-gcrypt.h =================================================================== --- branches/0.x/Common/spot-on-gcrypt.h 2013-06-17 12:55:14 UTC (rev 1313) +++ branches/0.x/Common/spot-on-gcrypt.h 2013-06-17 14:12:23 UTC (rev 1314) @@ -113,12 +113,14 @@ QString m_hashType; QString m_id; char *m_passphrase; + char *m_privateKey; char *m_symmetricKey; gcry_cipher_hd_t m_cipherHandle; int m_cipherAlgorithm; int m_hashAlgorithm; int m_saltLength; size_t m_passphraseLength; + size_t m_privateKeyLength; size_t m_symmetricKeyLength; unsigned long m_iterationCount; static void init(void); Modified: branches/0.x/Kernel/spot-on-listener.h =================================================================== --- branches/0.x/Kernel/spot-on-listener.h 2013-06-17 12:55:14 UTC (rev 1313) +++ branches/0.x/Kernel/spot-on-listener.h 2013-06-17 14:12:23 UTC (rev 1314) @@ -35,6 +35,7 @@ #include <QTimer> #include "Common/spot-on-external-address.h" +#include "Common/spot-on-misc.h" #include "spot-on-neighbor.h" class QNetworkInterface; @@ -63,6 +64,11 @@ void incomingConnection(int socketDescriptor) #endif { + /* + ** We cannot use findChildren() because the neighbor object + ** may become a child of another object. + */ + if(m_neighbors >= maxPendingConnections()) { QTcpSocket socket; @@ -91,7 +97,12 @@ private slots: void slotNeighborDestroyed(void) { - m_neighbors -= 1; + if(m_neighbors > 0) + m_neighbors -= 1; + else + spoton_misc::logError + ("spoton_listener_tcp_server::slotNeighborDestroyed(): m_neighbors " + "equals zero. Cannot decrement. Internal problem. Please report."); } }; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <tex...@us...> - 2013-06-17 12:55:20
|
Revision: 1313 http://sourceforge.net/p/spot-on/code/1313 Author: textfield Date: 2013-06-17 12:55:14 +0000 (Mon, 17 Jun 2013) Log Message: ----------- Allow listeners to accept just one client. Corrected spoton_listener_tcp_server::incomingConnection(). Disable the countries interface list if libGeoIP is not required. Modified Paths: -------------- branches/0.x/GUI/spot-on-a.cc branches/0.x/Kernel/spot-on-listener.h Modified: branches/0.x/GUI/spot-on-a.cc =================================================================== --- branches/0.x/GUI/spot-on-a.cc 2013-06-17 00:48:12 UTC (rev 1312) +++ branches/0.x/GUI/spot-on-a.cc 2013-06-17 12:55:14 UTC (rev 1313) @@ -74,6 +74,11 @@ m_neighborsLastModificationTime = QDateTime(); m_participantsLastModificationTime = QDateTime(); m_ui.setupUi(this); +#ifndef SPOTON_LINKED_WITH_LIBGEOIP + m_ui.countries->setEnabled(false); + m_ui.countries->setToolTip(tr("Spot-On was configured without " + "libGeoIP.")); +#endif #ifdef Q_OS_MAC #if QT_VERSION < 0x050000 setAttribute(Qt::WA_MacMetalStyle, true); @@ -1160,6 +1165,7 @@ box = new QComboBox(); box->setProperty("oid", query.value(10)); box->setProperty("table_row", row); + box->addItem("1"); for(int j = 1; j <= 10; j++) box->addItem(QString::number(5 * j)); @@ -1174,13 +1180,13 @@ box->setCurrentIndex(box->count() - 1); else if(box->findText(QString::number(query. value(i). - toInt()))) + toInt())) >= 0) box->setCurrentIndex (box->findText(QString::number(query. value(i). toInt()))); else - box->setCurrentIndex(box->count() - 2); + box->setCurrentIndex(1); // Default of five. connect(box, SIGNAL(currentIndexChanged(int)), @@ -2320,7 +2326,7 @@ "WHERE OID = ?"); if(index != comboBox->count() - 1) - query.bindValue(0, 5 * (index + 1)); + query.bindValue(0, comboBox->itemText(index).toInt()); else query.bindValue(0, std::numeric_limits<int>::max()); Modified: branches/0.x/Kernel/spot-on-listener.h =================================================================== --- branches/0.x/Kernel/spot-on-listener.h 2013-06-17 00:48:12 UTC (rev 1312) +++ branches/0.x/Kernel/spot-on-listener.h 2013-06-17 12:55:14 UTC (rev 1313) @@ -46,6 +46,7 @@ public: spoton_listener_tcp_server(QObject *parent):QTcpServer(parent) { + m_neighbors = 0; } QTcpSocket *nextPendingConnection(void) @@ -62,7 +63,7 @@ void incomingConnection(int socketDescriptor) #endif { - if(m_queue.size() + 1 >= maxPendingConnections()) + if(m_neighbors >= maxPendingConnections()) { QTcpSocket socket; @@ -74,12 +75,24 @@ QPointer<spoton_neighbor> neighbor = new spoton_neighbor (socketDescriptor, this); + connect(neighbor, + SIGNAL(destroyed(void)), + this, + SLOT(slotNeighborDestroyed(void))); m_queue.enqueue(neighbor); + m_neighbors += 1; } } private: + int m_neighbors; QQueue<QPointer<spoton_neighbor> > m_queue; + + private slots: + void slotNeighborDestroyed(void) + { + m_neighbors -= 1; + } }; class spoton_listener: public spoton_listener_tcp_server This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <tex...@us...> - 2013-06-17 12:55:18
|
Revision: 1313 http://sourceforge.net/p/spot-on/code/1313 Author: textfield Date: 2013-06-17 12:55:14 +0000 (Mon, 17 Jun 2013) Log Message: ----------- Allow listeners to accept just one client. Corrected spoton_listener_tcp_server::incomingConnection(). Disable the countries interface list if libGeoIP is not required. Modified Paths: -------------- branches/0.x/GUI/spot-on-a.cc branches/0.x/Kernel/spot-on-listener.h Modified: branches/0.x/GUI/spot-on-a.cc =================================================================== --- branches/0.x/GUI/spot-on-a.cc 2013-06-17 00:48:12 UTC (rev 1312) +++ branches/0.x/GUI/spot-on-a.cc 2013-06-17 12:55:14 UTC (rev 1313) @@ -74,6 +74,11 @@ m_neighborsLastModificationTime = QDateTime(); m_participantsLastModificationTime = QDateTime(); m_ui.setupUi(this); +#ifndef SPOTON_LINKED_WITH_LIBGEOIP + m_ui.countries->setEnabled(false); + m_ui.countries->setToolTip(tr("Spot-On was configured without " + "libGeoIP.")); +#endif #ifdef Q_OS_MAC #if QT_VERSION < 0x050000 setAttribute(Qt::WA_MacMetalStyle, true); @@ -1160,6 +1165,7 @@ box = new QComboBox(); box->setProperty("oid", query.value(10)); box->setProperty("table_row", row); + box->addItem("1"); for(int j = 1; j <= 10; j++) box->addItem(QString::number(5 * j)); @@ -1174,13 +1180,13 @@ box->setCurrentIndex(box->count() - 1); else if(box->findText(QString::number(query. value(i). - toInt()))) + toInt())) >= 0) box->setCurrentIndex (box->findText(QString::number(query. value(i). toInt()))); else - box->setCurrentIndex(box->count() - 2); + box->setCurrentIndex(1); // Default of five. connect(box, SIGNAL(currentIndexChanged(int)), @@ -2320,7 +2326,7 @@ "WHERE OID = ?"); if(index != comboBox->count() - 1) - query.bindValue(0, 5 * (index + 1)); + query.bindValue(0, comboBox->itemText(index).toInt()); else query.bindValue(0, std::numeric_limits<int>::max()); Modified: branches/0.x/Kernel/spot-on-listener.h =================================================================== --- branches/0.x/Kernel/spot-on-listener.h 2013-06-17 00:48:12 UTC (rev 1312) +++ branches/0.x/Kernel/spot-on-listener.h 2013-06-17 12:55:14 UTC (rev 1313) @@ -46,6 +46,7 @@ public: spoton_listener_tcp_server(QObject *parent):QTcpServer(parent) { + m_neighbors = 0; } QTcpSocket *nextPendingConnection(void) @@ -62,7 +63,7 @@ void incomingConnection(int socketDescriptor) #endif { - if(m_queue.size() + 1 >= maxPendingConnections()) + if(m_neighbors >= maxPendingConnections()) { QTcpSocket socket; @@ -74,12 +75,24 @@ QPointer<spoton_neighbor> neighbor = new spoton_neighbor (socketDescriptor, this); + connect(neighbor, + SIGNAL(destroyed(void)), + this, + SLOT(slotNeighborDestroyed(void))); m_queue.enqueue(neighbor); + m_neighbors += 1; } } private: + int m_neighbors; QQueue<QPointer<spoton_neighbor> > m_queue; + + private slots: + void slotNeighborDestroyed(void) + { + m_neighbors -= 1; + } }; class spoton_listener: public spoton_listener_tcp_server This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <tex...@us...> - 2013-06-17 00:48:17
|
Revision: 1312 http://sourceforge.net/p/spot-on/code/1312 Author: textfield Date: 2013-06-17 00:48:12 +0000 (Mon, 17 Jun 2013) Log Message: ----------- The standard close() function may not be available. Modified Paths: -------------- branches/0.x/Kernel/spot-on-listener.h Modified: branches/0.x/Kernel/spot-on-listener.h =================================================================== --- branches/0.x/Kernel/spot-on-listener.h 2013-06-17 00:44:42 UTC (rev 1311) +++ branches/0.x/Kernel/spot-on-listener.h 2013-06-17 00:48:12 UTC (rev 1312) @@ -63,7 +63,12 @@ #endif { if(m_queue.size() + 1 >= maxPendingConnections()) - ::close(socketDescriptor); + { + QTcpSocket socket; + + socket.setSocketDescriptor(socketDescriptor); + socket.close(); + } else { QPointer<spoton_neighbor> neighbor = new spoton_neighbor This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <tex...@us...> - 2013-06-17 00:48:15
|
Revision: 1312 http://sourceforge.net/p/spot-on/code/1312 Author: textfield Date: 2013-06-17 00:48:12 +0000 (Mon, 17 Jun 2013) Log Message: ----------- The standard close() function may not be available. Modified Paths: -------------- branches/0.x/Kernel/spot-on-listener.h Modified: branches/0.x/Kernel/spot-on-listener.h =================================================================== --- branches/0.x/Kernel/spot-on-listener.h 2013-06-17 00:44:42 UTC (rev 1311) +++ branches/0.x/Kernel/spot-on-listener.h 2013-06-17 00:48:12 UTC (rev 1312) @@ -63,7 +63,12 @@ #endif { if(m_queue.size() + 1 >= maxPendingConnections()) - ::close(socketDescriptor); + { + QTcpSocket socket; + + socket.setSocketDescriptor(socketDescriptor); + socket.close(); + } else { QPointer<spoton_neighbor> neighbor = new spoton_neighbor This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <tex...@us...> - 2013-06-17 00:44:48
|
Revision: 1311 http://sourceforge.net/p/spot-on/code/1311 Author: textfield Date: 2013-06-17 00:44:42 +0000 (Mon, 17 Jun 2013) Log Message: ----------- Close incoming peer socket if there are too many connections. Modified Paths: -------------- branches/0.x/Kernel/spot-on-listener.h Modified: branches/0.x/Kernel/spot-on-listener.h =================================================================== --- branches/0.x/Kernel/spot-on-listener.h 2013-06-17 00:05:40 UTC (rev 1310) +++ branches/0.x/Kernel/spot-on-listener.h 2013-06-17 00:44:42 UTC (rev 1311) @@ -1,5 +1,5 @@ /* -** Copyright (c) 2012 Alexis Megas +** Copyright (c) 2012, 2013 Alexis Megas ** All rights reserved. ** ** Redistribution and use in source and binary forms, with or without @@ -62,10 +62,15 @@ void incomingConnection(int socketDescriptor) #endif { - QPointer<spoton_neighbor> neighbor = new spoton_neighbor - (socketDescriptor, this); + if(m_queue.size() + 1 >= maxPendingConnections()) + ::close(socketDescriptor); + else + { + QPointer<spoton_neighbor> neighbor = new spoton_neighbor + (socketDescriptor, this); - m_queue.enqueue(neighbor); + m_queue.enqueue(neighbor); + } } private: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <tex...@us...> - 2013-06-17 00:44:45
|
Revision: 1311 http://sourceforge.net/p/spot-on/code/1311 Author: textfield Date: 2013-06-17 00:44:42 +0000 (Mon, 17 Jun 2013) Log Message: ----------- Close incoming peer socket if there are too many connections. Modified Paths: -------------- branches/0.x/Kernel/spot-on-listener.h Modified: branches/0.x/Kernel/spot-on-listener.h =================================================================== --- branches/0.x/Kernel/spot-on-listener.h 2013-06-17 00:05:40 UTC (rev 1310) +++ branches/0.x/Kernel/spot-on-listener.h 2013-06-17 00:44:42 UTC (rev 1311) @@ -1,5 +1,5 @@ /* -** Copyright (c) 2012 Alexis Megas +** Copyright (c) 2012, 2013 Alexis Megas ** All rights reserved. ** ** Redistribution and use in source and binary forms, with or without @@ -62,10 +62,15 @@ void incomingConnection(int socketDescriptor) #endif { - QPointer<spoton_neighbor> neighbor = new spoton_neighbor - (socketDescriptor, this); + if(m_queue.size() + 1 >= maxPendingConnections()) + ::close(socketDescriptor); + else + { + QPointer<spoton_neighbor> neighbor = new spoton_neighbor + (socketDescriptor, this); - m_queue.enqueue(neighbor); + m_queue.enqueue(neighbor); + } } private: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <tex...@us...> - 2013-06-17 00:05:48
|
Revision: 1310 http://sourceforge.net/p/spot-on/code/1310 Author: textfield Date: 2013-06-17 00:05:40 +0000 (Mon, 17 Jun 2013) Log Message: ----------- Separated spot-on.cc into two files. Modified Paths: -------------- branches/0.x/GUI/spot-on.h branches/0.x/spot-on-gui.freebsd.pro branches/0.x/spot-on-gui.freebsd.qt5.pro branches/0.x/spot-on-gui.osx.pro branches/0.x/spot-on-gui.osx.qt5.pro branches/0.x/spot-on-gui.pro branches/0.x/spot-on-gui.qt5.pro branches/0.x/spot-on-gui.win.pro branches/0.x/spot-on-gui.win.qt5.pro Added Paths: ----------- branches/0.x/GUI/spot-on-a.cc branches/0.x/GUI/spot-on-b.cc Removed Paths: ------------- branches/0.x/GUI/spot-on.cc Copied: branches/0.x/GUI/spot-on-a.cc (from rev 1309, branches/0.x/GUI/spot-on.cc) =================================================================== --- branches/0.x/GUI/spot-on-a.cc (rev 0) +++ branches/0.x/GUI/spot-on-a.cc 2013-06-17 00:05:40 UTC (rev 1310) @@ -0,0 +1,3004 @@ +/* +** Copyright (c) 2012, 2013 Alexis Megas +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from Spot-On without specific prior written permission. +** +** SPOT-ON IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** SPOT-ON, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "spot-on.h" + +int main(int argc, char *argv[]) +{ +#ifdef Q_OS_MAC +#if QT_VERSION < 0x050000 + QApplication::setStyle(new QMacStyle()); +#else + QApplication::setStyle("fusion"); +#endif +#endif + + QApplication qapplication(argc, argv); + + /* + ** Configure translations. + */ + + QTranslator qtTranslator; + + qtTranslator.load("qt_" + QLocale::system().name(), "Translations"); + qapplication.installTranslator(&qtTranslator); + + QTranslator myappTranslator; + + myappTranslator.load("spot-on_" + QLocale::system().name(), + "Translations"); + qapplication.installTranslator(&myappTranslator); + QCoreApplication::setApplicationName("Spot-On"); + QCoreApplication::setOrganizationName("Spot-On"); + QCoreApplication::setOrganizationDomain("spot-on.sf.net"); + QCoreApplication::setApplicationVersion(SPOTON_VERSION_STR); + QSettings::setPath(QSettings::IniFormat, QSettings::UserScope, + spoton_misc::homePath()); + QSettings::setDefaultFormat(QSettings::IniFormat); + Q_UNUSED(new spoton()); + return qapplication.exec(); +} + +spoton::spoton(void):QMainWindow() +{ + qsrand(QTime(0, 0, 0).secsTo(QTime::currentTime())); + QDir().mkdir(spoton_misc::homePath()); + m_crypt = 0; + m_countriesLastModificationTime = QDateTime(); + m_listenersLastModificationTime = QDateTime(); + m_neighborsLastModificationTime = QDateTime(); + m_participantsLastModificationTime = QDateTime(); + m_ui.setupUi(this); +#ifdef Q_OS_MAC +#if QT_VERSION < 0x050000 + setAttribute(Qt::WA_MacMetalStyle, true); +#endif +#endif + m_sbWidget = new QWidget(this); + m_sb.setupUi(m_sbWidget); + m_sb.chat->setVisible(false); + m_sb.email->setVisible(false); +#ifdef Q_OS_MAC + foreach(QToolButton *toolButton, m_sbWidget->findChildren<QToolButton *> ()) + toolButton->setStyleSheet + ("QToolButton {border: none;}" + "QToolButton::menu-button {border: none;}"); +#endif + connect(this, + SIGNAL(iconsChanged(void)), + &m_logViewer, + SLOT(slotSetIcons(void))); + connect(m_sb.chat, + SIGNAL(clicked(void)), + this, + SLOT(slotStatusButtonClicked(void))); + connect(m_sb.email, + SIGNAL(clicked(void)), + this, + SLOT(slotStatusButtonClicked(void))); + connect(m_sb.listeners, + SIGNAL(clicked(void)), + this, + SLOT(slotStatusButtonClicked(void))); + connect(m_sb.neighbors, + SIGNAL(clicked(void)), + this, + SLOT(slotStatusButtonClicked(void))); + connect(m_sb.errorlog, + SIGNAL(clicked(void)), + this, + SLOT(slotViewLog(void))); + connect(m_sb.kernelstatus, + SIGNAL(clicked(void)), + this, + SLOT(slotKernelStatus(void))); + statusBar()->addPermanentWidget(m_sbWidget, 100); + statusBar()->setStyleSheet("QStatusBar::item {" + "border: none; " + "}"); + statusBar()->setMaximumHeight(m_sbWidget->height()); + connect(m_ui.action_Quit, + SIGNAL(triggered(void)), + this, + SLOT(slotQuit(void))); + connect(m_ui.action_Log_Viewer, + SIGNAL(triggered(void)), + this, + SLOT(slotViewLog(void))); + connect(m_ui.addListener, + SIGNAL(clicked(void)), + this, + SLOT(slotAddListener(void))); + connect(m_ui.addNeighbor, + SIGNAL(clicked(void)), + this, + SLOT(slotAddNeighbor(void))); + connect(m_ui.dynamicdns, + SIGNAL(toggled(bool)), + this, + SLOT(slotProtocolRadioToggled(bool))); + connect(m_ui.ipv4Listener, + SIGNAL(toggled(bool)), + this, + SLOT(slotProtocolRadioToggled(bool))); + connect(m_ui.ipv4Neighbor, + SIGNAL(toggled(bool)), + this, + SLOT(slotProtocolRadioToggled(bool))); + connect(m_ui.ipv6Listener, + SIGNAL(toggled(bool)), + this, + SLOT(slotProtocolRadioToggled(bool))); + connect(m_ui.ipv6Neighbor, + SIGNAL(toggled(bool)), + this, + SLOT(slotProtocolRadioToggled(bool))); + connect(m_ui.activateKernel, + SIGNAL(clicked(void)), + this, + SLOT(slotActivateKernel(void))); + connect(m_ui.deactivateKernel, + SIGNAL(clicked(void)), + this, + SLOT(slotDeactivateKernel(void))); + connect(m_ui.selectKernelPath, + SIGNAL(clicked(void)), + this, + SLOT(slotSelectKernelPath(void))); + connect(m_ui.setPassphrase, + SIGNAL(clicked(void)), + this, + SLOT(slotSetPassphrase(void))); + connect(m_ui.kernelPath, + SIGNAL(returnPressed(void)), + this, + SLOT(slotSaveKernelPath(void))); + connect(m_ui.passphrase, + SIGNAL(returnPressed(void)), + this, + SLOT(slotValidatePassphrase(void))); + connect(m_ui.passphraseButton, + SIGNAL(clicked(void)), + this, + SLOT(slotValidatePassphrase(void))); + connect(m_ui.tab, + SIGNAL(currentChanged(int)), + this, + SLOT(slotTabChanged(int))); + connect(m_ui.sendMessage, + SIGNAL(clicked(void)), + this, + SLOT(slotSendMessage(void))); + connect(m_ui.message, + SIGNAL(returnPressed(void)), + this, + SLOT(slotSendMessage(void))); + connect(m_ui.clearMessages, + SIGNAL(clicked(void)), + m_ui.messages, + SLOT(clear(void))); + connect(m_ui.saveNodeName, + SIGNAL(clicked(void)), + this, + SLOT(slotSaveNodeName(void))); + connect(m_ui.nodeName, + SIGNAL(returnPressed(void)), + this, + SLOT(slotSaveNodeName(void))); + connect(m_ui.scrambler, + SIGNAL(toggled(bool)), + this, + SLOT(slotScramble(bool))); + connect(m_ui.action_Documentation, + SIGNAL(triggered(void)), + this, + SLOT(slotViewDocumentation(void))); + connect(m_ui.listenerIP, + SIGNAL(returnPressed(void)), + this, + SLOT(slotAddListener(void))); + connect(m_ui.neighborIP, + SIGNAL(returnPressed(void)), + this, + SLOT(slotAddNeighbor(void))); + connect(m_ui.listenerIPCombo, + SIGNAL(currentIndexChanged(int)), + this, + SLOT(slotListenerIPComboChanged(int))); + connect(m_ui.folder, + SIGNAL(currentIndexChanged(int)), + this, + SLOT(slotRefreshMail(void))); + connect(m_ui.chatSendMethod, + SIGNAL(currentIndexChanged(int)), + this, + SLOT(slotChatSendMethodChanged(int))); + connect(m_ui.status, + SIGNAL(currentIndexChanged(int)), + this, + SLOT(slotStatusChanged(int))); + connect(m_ui.addFriend, + SIGNAL(clicked(void)), + this, + SLOT(slotAddFriendsKey(void))); + connect(m_ui.clearFriend, + SIGNAL(clicked(void)), + m_ui.friendInformation, + SLOT(clear(void))); + connect(m_ui.resetSpotOn, + SIGNAL(clicked(void)), + this, + SLOT(slotResetAll(void))); + connect(m_ui.sendMail, + SIGNAL(clicked(void)), + this, + SLOT(slotSendMail(void))); + connect(m_ui.participants, + SIGNAL(itemChanged(QTableWidgetItem *)), + this, + SLOT(slotGeminiChanged(QTableWidgetItem *))); + connect(m_ui.generateGoldBug, + SIGNAL(clicked(void)), + this, + SLOT(slotGenerateGoldBug(void))); + connect(m_ui.keepOnlyUserDefinedNeighbors, + SIGNAL(toggled(bool)), + this, + SLOT(slotKeepOnlyUserDefinedNeighbors(bool))); + connect(m_ui.pushButtonClearMail, + SIGNAL(clicked(void)), + this, + SLOT(slotClearOutgoingMessage(void))); + connect(m_ui.pushButtonClearMail, + SIGNAL(clicked(void)), + this, + SLOT(slotDeleteMail(void))); + connect(m_ui.refreshMail, + SIGNAL(clicked(void)), + this, + SLOT(slotRefreshMail(void))); + connect(m_ui.refreshMail, + SIGNAL(clicked(void)), + this, + SLOT(slotRefreshPostOffice(void))); + connect(m_ui.mail, + SIGNAL(itemClicked(QTableWidgetItem *)), + this, + SLOT(slotMailSelected(QTableWidgetItem *))); + connect(m_ui.emptyTrash, + SIGNAL(clicked(void)), + this, + SLOT(slotEmptyTrash(void))); + connect(m_ui.retrieveMail, + SIGNAL(clicked(void)), + this, + SLOT(slotRetrieveMail(void))); + connect(m_ui.mailTab, + SIGNAL(currentChanged(int)), + this, + SLOT(slotMailTabChanged(int))); + connect(m_ui.postofficeCheckBox, + SIGNAL(toggled(bool)), + this, + SLOT(slotEnabledPostOffice(bool))); + connect(m_ui.saveCopy, + SIGNAL(toggled(bool)), + this, + SLOT(slotKeepCopy(bool))); + connect(m_ui.actionNouve, + SIGNAL(triggered(void)), + this, + SLOT(slotSetIcons(void))); + connect(m_ui.actionNuvola, + SIGNAL(triggered(void)), + this, + SLOT(slotSetIcons(void))); + connect(m_ui.newRSAKeys, + SIGNAL(toggled(bool)), + m_ui.rsaKeySize, + SLOT(setEnabled(bool))); + connect(m_ui.days, + SIGNAL(valueChanged(int)), + this, + SLOT(slotDaysChanged(int))); + connect(m_ui.reply, + SIGNAL(clicked(void)), + this, + SLOT(slotReply(void))); + connect(&m_generalTimer, + SIGNAL(timeout(void)), + this, + SLOT(slotGeneralTimerTimeout(void))); + connect(&m_tableTimer, + SIGNAL(timeout(void)), + this, + SLOT(slotPopulateCountries(void))); + connect(&m_tableTimer, + SIGNAL(timeout(void)), + this, + SLOT(slotPopulateListeners(void))); + connect(&m_tableTimer, + SIGNAL(timeout(void)), + this, + SLOT(slotPopulateNeighbors(void))); + connect(&m_tableTimer, + SIGNAL(timeout(void)), + this, + SLOT(slotPopulateParticipants(void))); + connect(&m_kernelSocket, + SIGNAL(connected(void)), + this, + SLOT(slotKernelSocketState(void))); + connect(&m_kernelSocket, + SIGNAL(disconnected(void)), + this, + SLOT(slotKernelSocketState(void))); + connect(&m_kernelSocket, + SIGNAL(readyRead(void)), + this, + SLOT(slotReceivedKernelMessage(void))); + m_sb.kernelstatus->setToolTip + (tr("Not connected to the kernel. Is the kernel " + "active?")); + m_sb.listeners->setToolTip(tr("Listeners are offline.")); + m_sb.neighbors->setToolTip(tr("Neighbors are offline.")); + + QMenu *menu = new QMenu(this); + + connect(menu->addAction(tr("Copy &Messaging Public Key")), + SIGNAL(triggered(void)), this, SLOT(slotCopyMyPublicKey(void))); + connect(menu->addAction(tr("Copy &URL Public Key")), + SIGNAL(triggered(void)), this, SLOT(slotCopyMyURLPublicKey(void))); + m_ui.toolButtonCopytoClipboard->setMenu(menu); + menu = new QMenu(this); + connect(menu->addAction(tr("Share &Messaging Public Key")), + SIGNAL(triggered(void)), this, SLOT(slotSharePublicKey(void))); + connect(menu->addAction(tr("Share &URL Public Key")), + SIGNAL(triggered(void)), this, SLOT(slotShareURLPublicKey(void))); + m_ui.toolButtonMakeFriends->setMenu(menu); + m_generalTimer.start(2500); + m_tableTimer.setInterval(2500); + m_ui.ipv4Listener->setChecked(true); + m_ui.listenerIP->setInputMask("000.000.000.000; "); + m_ui.listenerScopeId->setEnabled(false); + m_ui.listenerScopeIdLabel->setEnabled(false); + m_ui.neighborIP->setInputMask("000.000.000.000; "); + m_ui.neighborScopeId->setEnabled(false); + m_ui.neighborScopeIdLabel->setEnabled(false); + m_ui.participants->setStyleSheet + ("QTableView {selection-background-color: lightgreen}"); + + QSettings settings; + + if(!settings.contains("gui/saveCopy")) + settings.setValue("gui/saveCopy", true); + + if(!settings.contains("gui/uuid")) + { + QUuid uuid(QUuid::createUuid()); + + settings.setValue("gui/uuid", uuid.toString()); + } + + for(int i = 0; i < settings.allKeys().size(); i++) + m_settings[settings.allKeys().at(i)] = settings.value + (settings.allKeys().at(i)); + + if(m_settings.value("gui/iconSet", "nouve").toString() == "nouve") + { + m_ui.menu_Icons->actions().at(0)->setChecked(true); + m_ui.menu_Icons->actions().at(0)->trigger(); + } + else + { + m_ui.menu_Icons->actions().at(1)->setChecked(true); + m_ui.menu_Icons->actions().at(1)->trigger(); + } + + m_sb.kernelstatus->setIcon + (QIcon(QString(":/%1/deactivate.png"). + arg(m_settings.value("gui/iconSet", "nouve").toString()))); + m_sb.listeners->setIcon + (QIcon(QString(":/%1/status-offline.png"). + arg(m_settings.value("gui/iconSet", "nouve").toString()))); + m_sb.neighbors->setIcon + (QIcon(QString(":/%1/status-offline.png"). + arg(m_settings.value("gui/iconSet", "nouve").toString()))); + + if(spoton_misc::isGnome()) + setGeometry(m_settings.value("gui/geometry").toRect()); + else + restoreGeometry(m_settings.value("gui/geometry").toByteArray()); + + if(m_settings.contains("gui/kernelPath") && + QFileInfo(m_settings.value("gui/kernelPath").toString().trimmed()). + isExecutable()) + m_ui.kernelPath->setText(m_settings.value("gui/kernelPath").toString(). + trimmed()); + else + { + QString path(QCoreApplication::applicationDirPath() + + QDir::separator() + +#ifdef Q_OS_MAC + "Spot-On-Kernel.app" +#elif defined(Q_OS_WIN32) + "Spot-On-Kernel.exe" +#else + "Spot-On-Kernel" +#endif + ); + +#ifdef Q_OS_MAC + if(!QFileInfo(path).exists()) + path = QCoreApplication::applicationDirPath() + + QDir::separator() + "Spot-On-Kernel"; +#endif + + m_ui.kernelPath->setText(path); + } + + if(m_settings.value("gui/chatSendMethod", "Artificial_GET"). + toString() == "Artificial_GET") + m_ui.chatSendMethod->setCurrentIndex(0); + else + m_ui.chatSendMethod->setCurrentIndex(1); + + QByteArray status + (m_settings.value("gui/my_status", "Online").toByteArray()); + + if(status == "Away") + m_ui.status->setCurrentIndex(0); + else if(status == "Busy") + m_ui.status->setCurrentIndex(1); + else if(status == "Offline") + m_ui.status->setCurrentIndex(2); + else + m_ui.status->setCurrentIndex(3); + + m_ui.kernelPath->setToolTip(m_ui.kernelPath->text()); + m_ui.nodeName->setMaxLength(NAME_MAXIMUM_LENGTH); + m_ui.nodeName->setText + (QString::fromUtf8(m_settings.value("gui/nodeName", "unknown"). + toByteArray()).trimmed()); + m_ui.goldbug->setMaxLength + (spoton_gcrypt::cipherKeyLength("aes256")); + m_ui.cipherType->clear(); + m_ui.cipherType->addItems(spoton_gcrypt::cipherTypes()); + m_ui.days->setValue(m_settings.value("gui/postofficeDays", 1).toInt()); + m_ui.keepOnlyUserDefinedNeighbors->setChecked + (m_settings.value("gui/keepOnlyUserDefinedNeighbors", false).toBool()); + m_ui.postofficeCheckBox->setChecked + (m_settings.value("gui/postoffice_enabled", false).toBool()); + m_ui.saveCopy->setChecked + (m_settings.value("gui/saveCopy", true).toBool()); + m_ui.scrambler->setChecked + (m_settings.value("gui/scramblerEnabled", false).toBool()); + + /* + ** Please don't translate n/a. + */ + + if(m_ui.cipherType->count() == 0) + m_ui.cipherType->addItem("n/a"); + + m_ui.hashType->clear(); + m_ui.hashType->addItems(spoton_gcrypt::hashTypes()); + + if(m_ui.cipherType->count() == 0) + m_ui.cipherType->addItem("n/a"); + + QString str(""); + + str = m_settings.value("gui/cipherType", "aes256"). + toString().toLower().trimmed(); + + if(m_ui.cipherType->findText(str) > -1) + m_ui.cipherType->setCurrentIndex(m_ui.cipherType->findText(str)); + + str = m_settings.value("gui/hashType", "sha512"). + toString().toLower().trimmed(); + + if(m_ui.hashType->findText(str) > -1) + m_ui.hashType->setCurrentIndex(m_ui.hashType->findText(str)); + + m_ui.iterationCount->setValue(m_settings.value("gui/iterationCount", + 10000).toInt()); + str = m_settings.value("gui/rsaKeySize", "3072"). + toString().toLower().trimmed(); + + if(m_ui.rsaKeySize->findText(str) > -1) + m_ui.rsaKeySize->setCurrentIndex(m_ui.rsaKeySize->findText(str)); + + m_ui.saltLength->setValue(m_settings.value("gui/saltLength", 256).toInt()); + + if(spoton_gcrypt::passphraseSet()) + { + m_sb.kernelstatus->setEnabled(false); + m_sb.listeners->setEnabled(false); + m_sb.neighbors->setEnabled(false); + m_ui.passphrase1->setText("0000000000"); + m_ui.passphrase2->setText("0000000000"); + m_ui.rsaKeySize->setEnabled(false); + + for(int i = 0; i < m_ui.tab->count(); i++) + if(i == m_ui.tab->count() - 1) + { + m_ui.tab->blockSignals(true); + m_ui.tab->setCurrentIndex(i); + m_ui.tab->blockSignals(false); + m_ui.tab->setTabEnabled(i, true); + } + else + m_ui.tab->setTabEnabled(i, false); + + m_ui.passphrase->setFocus(); + } + else + { + m_sb.kernelstatus->setEnabled(false); + m_sb.listeners->setEnabled(false); + m_sb.neighbors->setEnabled(false); + m_ui.newRSAKeys->setChecked(true); + m_ui.newRSAKeys->setEnabled(false); + m_ui.passphrase->setEnabled(false); + m_ui.passphraseButton->setEnabled(false); + m_ui.passphraseLabel->setEnabled(false); + m_ui.kernelBox->setEnabled(false); + m_ui.listenersBox->setEnabled(false); + + for(int i = 0; i < m_ui.tab->count(); i++) + if(i == 5) // Settings + { + m_ui.tab->blockSignals(true); + m_ui.tab->setCurrentIndex(i); + m_ui.tab->blockSignals(false); + m_ui.tab->setTabEnabled(i, true); + } + else + m_ui.tab->setTabEnabled(i, false); + + m_ui.passphrase1->setFocus(); + } + + if(m_settings.contains("gui/chatHorizontalSplitter")) + m_ui.chatHorizontalSplitter->restoreState + (m_settings.value("gui/chatHorizontalSplitter").toByteArray()); + + if(m_settings.contains("gui/listenersHorizontalSplitter")) + m_ui.listenersHorizontalSplitter->restoreState + (m_settings.value("gui/listenersHorizontalSplitter").toByteArray()); + + if(m_settings.contains("gui/neighborsVerticalSplitter")) + m_ui.neighborsVerticalSplitter->restoreState + (m_settings.value("gui/neighborsVerticalSplitter").toByteArray()); + + if(m_settings.contains("gui/readVerticalSplitter")) + m_ui.readVerticalSplitter->restoreState + (m_settings.value("gui/readVerticalSplitter").toByteArray()); + + if(m_settings.contains("gui/urlsVerticalSplitter")) + m_ui.urlsVerticalSplitter->restoreState + (m_settings.value("gui/urlsVerticalSplitter").toByteArray()); + + m_ui.listeners->setContextMenuPolicy(Qt::CustomContextMenu); + m_ui.neighbors->setContextMenuPolicy(Qt::CustomContextMenu); + m_ui.participants->setContextMenuPolicy(Qt::CustomContextMenu); + connect(m_ui.listeners, + SIGNAL(customContextMenuRequested(const QPoint &)), + this, + SLOT(slotShowContextMenu(const QPoint &))); + connect(m_ui.neighbors, + SIGNAL(customContextMenuRequested(const QPoint &)), + this, + SLOT(slotShowContextMenu(const QPoint &))); + connect(m_ui.participants, + SIGNAL(customContextMenuRequested(const QPoint &)), + this, + SLOT(slotShowContextMenu(const QPoint &))); + m_ui.mail->setColumnHidden(4, true); // goldbug + m_ui.mail->setColumnHidden(5, true); // message + m_ui.mail->setColumnHidden(6, true); // message_digest + m_ui.mail->setColumnHidden(7, true); // receiver_sender_hash + m_ui.mail->setColumnHidden(8, true); // OID + m_ui.listeners->setColumnHidden(m_ui.listeners->columnCount() - 1, + true); // OID + m_ui.neighbors->setColumnHidden + (m_ui.neighbors->columnCount() - 1, true); // OID + m_ui.participants->setColumnHidden(1, true); // OID + m_ui.participants->setColumnHidden(2, true); // neighbor_oid + m_ui.participants->setColumnHidden(3, true); // public_key_hash + m_ui.participants->resizeColumnsToContents(); + m_ui.postoffice->setColumnHidden(2, true); // Recipient Hash + m_ui.mail->horizontalHeader()->setSortIndicator + (0, Qt::AscendingOrder); + m_ui.listeners->horizontalHeader()->setSortIndicator + (2, Qt::AscendingOrder); + m_ui.neighbors->horizontalHeader()->setSortIndicator + (1, Qt::AscendingOrder); + m_ui.participants->horizontalHeader()->setSortIndicator + (0, Qt::AscendingOrder); + m_ui.postoffice->horizontalHeader()->setSortIndicator + (0, Qt::AscendingOrder); + m_ui.listenersHorizontalSplitter->setStretchFactor(0, 1); + m_ui.listenersHorizontalSplitter->setStretchFactor(1, 0); + m_ui.neighborsVerticalSplitter->setStretchFactor(0, 1); + m_ui.neighborsVerticalSplitter->setStretchFactor(1, 0); + m_ui.readVerticalSplitter->setStretchFactor(0, 1); + m_ui.readVerticalSplitter->setStretchFactor(1, 0); + m_ui.urlsVerticalSplitter->setStretchFactor(0, 1); + m_ui.urlsVerticalSplitter->setStretchFactor(1, 0); + prepareListenerIPCombo(); + spoton_misc::prepareDatabases(); + + /* + ** Not wise! We may find things we're not prepared for. + */ + + foreach(QAbstractButton *button, + m_ui.participants->findChildren<QAbstractButton *> ()) + button->setToolTip(tr("Broadcast")); + + show(); +} + +void spoton::slotQuit(void) +{ + close(); +} + +void spoton::slotAddListener(void) +{ + if(!m_crypt) + return; + + bool ok = true; + + { + QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", "spoton"); + + db.setDatabaseName(spoton_misc::homePath() + QDir::separator() + + "listeners.db"); + + if(db.open()) + { + spoton_misc::prepareDatabases(); + + QString ip(""); + + if(m_ui.listenerIPCombo->currentIndex() == 0) + ip = m_ui.listenerIP->text().trimmed(); + else + ip = m_ui.listenerIPCombo->currentText(); + + QString port(QString::number(m_ui.listenerPort->value())); + QString protocol(""); + QString scopeId(m_ui.listenerScopeId->text().trimmed()); + QString status("online"); + QSqlQuery query(db); + + if(m_ui.ipv4Listener->isChecked()) + protocol = "IPv4"; + else + protocol = "IPv6"; + + query.prepare("INSERT INTO listeners " + "(ip_address, " + "port, " + "protocol, " + "scope_id, " + "status_control, " + "hash) " + "VALUES " + "(?, ?, ?, ?, ?, ?)"); + + if(ip.isEmpty()) + query.bindValue + (0, m_crypt->encrypted(QByteArray(), &ok).toBase64()); + else + { + QList<int> numbers; + QStringList list; + + if(protocol == "IPv4") + list = ip.split(".", QString::KeepEmptyParts); + else + list = ip.split(":", QString::KeepEmptyParts); + + for(int i = 0; i < list.size(); i++) + numbers.append(list.at(i).toInt()); + + if(protocol == "IPv4") + { + ip = QString::number(numbers.value(0)) + "." + + QString::number(numbers.value(1)) + "." + + QString::number(numbers.value(2)) + "." + + QString::number(numbers.value(3)); + ip.remove("..."); + } + else + { + if(m_ui.listenerIPCombo->currentIndex() == 0) + { + ip = QString::number(numbers.value(0)) + ":" + + QString::number(numbers.value(1)) + ":" + + QString::number(numbers.value(2)) + ":" + + QString::number(numbers.value(3)) + ":" + + QString::number(numbers.value(4)) + ":" + + QString::number(numbers.value(5)) + ":" + + QString::number(numbers.value(6)) + ":" + + QString::number(numbers.value(7)); + ip.remove(":::::::"); + + /* + ** Special exception. + */ + + if(ip == "0:0:0:0:0:0:0:0") + ip = "::"; + } + } + + if(ok) + query.bindValue + (0, m_crypt->encrypted(ip.toLatin1(), &ok).toBase64()); + } + + if(ok) + query.bindValue + (1, m_crypt->encrypted(port.toLatin1(), &ok).toBase64()); + + if(ok) + query.bindValue + (2, m_crypt->encrypted(protocol.toLatin1(), &ok).toBase64()); + + if(ok) + query.bindValue + (3, m_crypt->encrypted(scopeId.toLatin1(), &ok).toBase64()); + + query.bindValue(4, status); + + if(ok) + query.bindValue + (5, m_crypt->keyedHash((ip + port).toLatin1(), &ok). + toBase64()); + + if(ok) + ok = query.exec(); + } + + db.close(); + } + + QSqlDatabase::removeDatabase("spoton"); + + if(ok) + m_ui.listenerIP->selectAll(); +} + +void spoton::slotAddNeighbor(void) +{ + if(!m_crypt) + return; + + bool ok = true; + + { + QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", "spoton"); + + db.setDatabaseName(spoton_misc::homePath() + QDir::separator() + + "neighbors.db"); + + if(db.open()) + { + spoton_misc::prepareDatabases(); + + QString ip(m_ui.neighborIP->text().trimmed()); + QString port(QString::number(m_ui.neighborPort->value())); + QString protocol(""); + QString proxyHostname(""); + QString proxyPassword(""); + QString proxyPort(""); + QString proxyType(""); + QString proxyUsername(""); + QString scopeId(m_ui.neighborScopeId->text().trimmed()); + QString status("connected"); + QSqlQuery query(db); + + if(m_ui.ipv4Neighbor->isChecked()) + protocol = "IPv4"; + else if(m_ui.ipv6Neighbor->isChecked()) + protocol = "IPv6"; + else + protocol = "Dynamic DNS"; + + query.prepare("INSERT INTO neighbors " + "(local_ip_address, " + "local_port, " + "protocol, " + "remote_ip_address, " + "remote_port, " + "sticky, " + "scope_id, " + "hash, " + "status_control, " + "country, " + "remote_ip_address_hash, " + "qt_country_hash, " + "proxy_hostname, " + "proxy_password, " + "proxy_port, " + "proxy_type, " + "proxy_username) " + "VALUES " + "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"); + + query.bindValue(0, QVariant(QVariant::String)); + query.bindValue(1, QVariant(QVariant::String)); + query.bindValue(2, protocol); + + if(ip.isEmpty()) + query.bindValue + (3, m_crypt->encrypted(QByteArray(), &ok).toBase64()); + else + { + if(protocol == "IPv4" || protocol == "IPv6") + { + QList<int> numbers; + QStringList list; + + if(protocol == "IPv4") + list = ip.split(".", QString::KeepEmptyParts); + else + list = ip.split(":", QString::KeepEmptyParts); + + for(int i = 0; i < list.size(); i++) + numbers.append(list.at(i).toInt()); + + ip.clear(); + + if(protocol == "IPv4") + { + ip = QString::number(numbers.value(0)) + "." + + QString::number(numbers.value(1)) + "." + + QString::number(numbers.value(2)) + "." + + QString::number(numbers.value(3)); + ip.remove("..."); + } + else + { + ip = QString::number(numbers.value(0)) + ":" + + QString::number(numbers.value(1)) + ":" + + QString::number(numbers.value(2)) + ":" + + QString::number(numbers.value(3)) + ":" + + QString::number(numbers.value(4)) + ":" + + QString::number(numbers.value(5)) + ":" + + QString::number(numbers.value(6)) + ":" + + QString::number(numbers.value(7)); + ip.remove(":::::::"); + + /* + ** Special exception. + */ + + if(ip == "0:0:0:0:0:0:0:0") + ip = "::"; + } + } + + if(ok) + query.bindValue + (3, m_crypt->encrypted(ip.toLatin1(), &ok).toBase64()); + } + + query.bindValue(5, 1); // Sticky. + + if(ok) + query.bindValue + (4, m_crypt->encrypted(port.toLatin1(), &ok).toBase64()); + + if(ok) + query.bindValue + (6, m_crypt->encrypted(scopeId.toLatin1(), &ok).toBase64()); + + if(ok) + query.bindValue + (7, m_crypt->keyedHash((ip + port).toLatin1(), &ok). + toBase64()); + + query.bindValue(8, status); + + QString country(spoton_misc::countryNameFromIPAddress(ip)); + + if(ok) + query.bindValue + (9, m_crypt->encrypted(country.toLatin1(), &ok).toBase64()); + + if(ok) + query.bindValue + (10, m_crypt->keyedHash(ip.toLatin1(), &ok). + toBase64()); + + if(ok) + query.bindValue + (11, m_crypt->keyedHash(country.remove(" ").toLatin1(), &ok). + toBase64()); + + proxyHostname = m_ui.proxyHostname->text().trimmed(); + proxyPassword = m_ui.proxyPassword->text(); + proxyPort = QString::number(m_ui.proxyPort->value()); + + if(m_ui.proxy->isChecked()) + proxyType = m_ui.proxyType->currentText(); + else + proxyType = "NoProxy"; + + proxyUsername = m_ui.proxyUsername->text(); + + if(ok) + query.bindValue + (12, m_crypt->encrypted(proxyHostname.toLatin1(), &ok). + toBase64()); + + if(ok) + query.bindValue + (13, m_crypt->encrypted(proxyPassword.toUtf8(), &ok). + toBase64()); + + if(ok) + query.bindValue + (14, m_crypt->encrypted(proxyPort.toLatin1(), + &ok).toBase64()); + + if(ok) + query.bindValue + (15, m_crypt->encrypted(proxyType.toLatin1(), &ok). + toBase64()); + + if(ok) + query.bindValue + (16, m_crypt->encrypted(proxyUsername.toUtf8(), &ok). + toBase64()); + + if(ok) + ok = query.exec(); + } + + db.close(); + } + + QSqlDatabase::removeDatabase("spoton"); + + if(ok) + m_ui.neighborIP->selectAll(); +} + +void spoton::slotProtocolRadioToggled(bool state) +{ + Q_UNUSED(state); + + QRadioButton *radio = qobject_cast<QRadioButton *> (sender()); + + if(!radio) + return; + + if(radio == m_ui.dynamicdns) + { + m_ui.neighborIP->clear(); + m_ui.neighborIP->setInputMask(""); + m_ui.neighborScopeId->setEnabled(true); + m_ui.neighborScopeIdLabel->setEnabled(true); + } + else if(radio == m_ui.ipv4Listener || radio == m_ui.ipv4Neighbor) + { + if(radio == m_ui.ipv4Listener) + { + m_ui.listenerIP->setInputMask("000.000.000.000; "); + m_ui.listenerScopeId->setEnabled(false); + m_ui.listenerScopeIdLabel->setEnabled(false); + } + else + { + m_ui.neighborIP->clear(); + m_ui.neighborIP->setInputMask("000.000.000.000; "); + m_ui.neighborScopeId->setEnabled(false); + m_ui.neighborScopeIdLabel->setEnabled(false); + } + } + else + { + if(radio == m_ui.ipv6Listener) + { + m_ui.listenerIP->setInputMask + ("HHHH:HHHH:HHHH:HHHH:HHHH:HHHH:HHHH:HHHH; "); + m_ui.listenerScopeId->setEnabled(true); + m_ui.listenerScopeIdLabel->setEnabled(true); + } + else + { + m_ui.neighborIP->clear(); + m_ui.neighborIP->setInputMask + ("HHHH:HHHH:HHHH:HHHH:HHHH:HHHH:HHHH:HHHH; "); + m_ui.neighborScopeId->setEnabled(true); + m_ui.neighborScopeIdLabel->setEnabled(true); + } + } + + prepareListenerIPCombo(); +} + +void spoton::slotScramble(bool state) +{ + m_settings["gui/scramblerEnabled"] = state; + + QSettings settings; + + settings.setValue("gui/scramblerEnabled", state); +} + +void spoton::slotPopulateListeners(void) +{ + if(!m_crypt) + return; + + QFileInfo fileInfo(spoton_misc::homePath() + QDir::separator() + + "listeners.db"); + + if(fileInfo.exists()) + { + if(fileInfo.lastModified() <= m_listenersLastModificationTime) + return; + else + m_listenersLastModificationTime = fileInfo.lastModified(); + } + else + m_listenersLastModificationTime = QDateTime(); + + int active = 0; + + { + QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", "spoton"); + + db.setDatabaseName(fileInfo.absoluteFilePath()); + + if(db.open()) + { + updateListenersTable(db); + + QModelIndexList list; + QString ip(""); + QString port(""); + int columnIP = 2; + int columnPORT = 3; + int hval = m_ui.listeners->horizontalScrollBar()->value(); + int row = -1; + int vval = m_ui.listeners->verticalScrollBar()->value(); + + list = m_ui.listeners->selectionModel()->selectedRows + (columnIP); + + if(!list.isEmpty()) + ip = list.at(0).data().toString(); + + list = m_ui.listeners->selectionModel()->selectedRows + (columnPORT); + + if(!list.isEmpty()) + port = list.at(0).data().toString(); + + m_ui.listeners->setSortingEnabled(false); + m_ui.listeners->clearContents(); + m_ui.listeners->setRowCount(0); + + QSqlQuery query(db); + + query.setForwardOnly(true); + + if(query.exec("SELECT " + "status_control, status, " + "ip_address, port, scope_id, protocol, " + "external_ip_address, external_port, " + "connections, maximum_clients, OID " + "FROM listeners")) + { + row = 0; + + while(query.next()) + { + QCheckBox *check = 0; + QComboBox *box = 0; + QTableWidgetItem *item = 0; + + m_ui.listeners->setRowCount(row + 1); + + for(int i = 0; i < query.record().count(); i++) + { + if(i == 0) + { + check = new QCheckBox(); + + if(query.value(0) == "online") + check->setChecked(true); + + if(query.value(1) == "online") + active += 1; + + check->setProperty("oid", query.value(10)); + check->setProperty("table_row", row); + connect(check, + SIGNAL(stateChanged(int)), + this, + SLOT(slotListenerCheckChange(int))); + m_ui.listeners->setCellWidget(row, i, check); + } + else if(i == 9) + { + box = new QComboBox(); + box->setProperty("oid", query.value(10)); + box->setProperty("table_row", row); + + for(int j = 1; j <= 10; j++) + box->addItem(QString::number(5 * j)); + + box->addItem(tr("Unlimited")); + box->setMaximumWidth + (box->fontMetrics().width(tr("Unlimited")) + 50); + m_ui.listeners->setCellWidget(row, i, box); + + if(std::numeric_limits<int>::max() == + query.value(i).toInt()) + box->setCurrentIndex(box->count() - 1); + else if(box->findText(QString::number(query. + value(i). + toInt()))) + box->setCurrentIndex + (box->findText(QString::number(query. + value(i). + toInt()))); + else + box->setCurrentIndex(box->count() - 2); + + connect(box, + SIGNAL(currentIndexChanged(int)), + this, + SLOT(slotMaximumClientsChanged(int))); + } + else + { + bool ok = true; + + if(i >= 2 && i <= 6) + { + if(query.isNull(i)) + item = new QTableWidgetItem(); + else + item = new QTableWidgetItem + (m_crypt->decrypted(QByteArray:: + fromBase64(query. + value(i). + toByteArray()), + &ok). + constData()); + } + else + item = new QTableWidgetItem(query. + value(i).toString()); + + item->setFlags + (Qt::ItemIsSelectable | Qt::ItemIsEnabled); + m_ui.listeners->setItem(row, i, item); + + if(i == 1) + { + if(query.value(i).toString() == "online") + item->setBackground + (QBrush(QColor("lightgreen"))); + else + item->setBackground(QBrush()); + } + } + } + + QByteArray bytes1; + QByteArray bytes2; + QWidget *focusWidget = QApplication::focusWidget(); + bool ok = true; + + bytes1 = m_crypt->decrypted + (QByteArray::fromBase64(query.value(2).toByteArray()), + &ok); + bytes2 = m_crypt->decrypted + (QByteArray::fromBase64(query.value(3).toByteArray()), + &ok); + + if(ip == bytes1 && port == bytes2) + m_ui.listeners->selectRow(row); + + if(focusWidget) + focusWidget->setFocus(); + + row += 1; + } + } + + m_ui.listeners->setSortingEnabled(true); + + for(int i = 0; i < m_ui.listeners->columnCount() - 1; i++) + /* + ** Ignore the OID column. + */ + + m_ui.listeners->resizeColumnToContents(i); + + m_ui.listeners->horizontalHeader()->setStretchLastSection(true); + m_ui.listeners->horizontalScrollBar()->setValue(hval); + m_ui.listeners->verticalScrollBar()->setValue(vval); + } + + db.close(); + } + + QSqlDatabase::removeDatabase("spoton"); + + if(active > 0) + { + m_sb.listeners->setIcon + (QIcon(QString(":/%1/status-online.png"). + arg(m_settings.value("gui/iconSet", "nouve").toString()))); + m_sb.listeners->setToolTip + (tr("There is (are) %1 active listener(s).").arg(active)); + } + else + { + m_sb.listeners->setIcon + (QIcon(QString(":/%1/status-offline.png"). + arg(m_settings.value("gui/iconSet", "nouve").toString()))); + m_sb.listeners->setToolTip(tr("Listeners are offline.")); + } +} + +void spoton::slotPopulateNeighbors(void) +{ + if(!m_crypt) + return; + + QFileInfo fileInfo(spoton_misc::homePath() + QDir::separator() + + "neighbors.db"); + + if(fileInfo.exists()) + { + if(fileInfo.lastModified() <= m_neighborsLastModificationTime) + return; + else + m_neighborsLastModificationTime = fileInfo.lastModified(); + } + else + m_neighborsLastModificationTime = QDateTime(); + + int active = 0; + + { + QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", "spoton"); + + db.setDatabaseName(fileInfo.absoluteFilePath()); + + if(db.open()) + { + updateNeighborsTable(db); + + QModelIndexList list; + QString remoteIp(""); + QString remotePort(""); + int columnCOUNTRY = 8; + int columnREMOTE_IP = 9; + int columnREMOTE_PORT = 10; + int hval = m_ui.neighbors->horizontalScrollBar()->value(); + int row = -1; + int vval = m_ui.neighbors->verticalScrollBar()->value(); + + list = m_ui.neighbors->selectionModel()->selectedRows + (columnREMOTE_IP); + + if(!list.isEmpty()) + remoteIp = list.at(0).data().toString(); + + list = m_ui.neighbors->selectionModel()->selectedRows + (columnREMOTE_PORT); + + if(!list.isEmpty()) + remotePort = list.at(0).data().toString(); + + m_ui.neighbors->setSortingEnabled(false); + m_ui.neighbors->clearContents(); + m_ui.neighbors->setRowCount(0); + + QSqlQuery query(db); + + query.setForwardOnly(true); + + if(query.exec("SELECT sticky, UPPER(uuid), status, " + "status_control, " + "local_ip_address, local_port, " + "external_ip_address, external_port, " + "country, " + "remote_ip_address, " + "remote_port, scope_id, protocol, " + "proxy_hostname, proxy_port, OID " + "FROM neighbors")) + { + QString localIp(""); + QString localPort(""); + + row = 0; + + while(query.next()) + { + m_ui.neighbors->setRowCount(row + 1); + + QCheckBox *check = 0; + + check = new QCheckBox(); + check->setToolTip(tr("The sticky feature enables an " + "indefinite lifetime for a neighbor.\n" + "If " + "not checked, the neighbor will be " + "terminated after some internal " + "timer expires.")); + + if(query.value(0).toInt() == 1) + check->setChecked(true); + else + check->setChecked(false); + + check->setProperty + ("oid", query.value(query.record().count() - 1)); + check->setProperty("table_row", row); + connect(check, + SIGNAL(stateChanged(int)), + this, + SLOT(slotNeighborCheckChange(int))); + m_ui.neighbors->setCellWidget(row, 0, check); + + for(int i = 1; i < query.record().count(); i++) + { + QTableWidgetItem *item = 0; + + if(i == 2) + { + if(query.value(i).toString() == "connected") + active += 1; + } + + if(i == 6 || (i >= 8 && i <= 11) || (i >= 13 && i <= 14)) + { + if(query.value(i).isNull()) + item = new QTableWidgetItem(); + else + { + bool ok = true; + + item = new QTableWidgetItem + (m_crypt->decrypted(QByteArray:: + fromBase64(query. + value(i). + toByteArray()), + &ok).constData()); + } + } + else + item = new QTableWidgetItem + (query.value(i).toString()); + + item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); + + if(i == 2) + { + if(query.value(i).toString() == "connected") + item->setBackground(QBrush(QColor("lightgreen"))); + else + item->setBackground(QBrush()); + } + + m_ui.neighbors->setItem(row, i, item); + } + + QTableWidgetItem *item1 = m_ui.neighbors->item + (row, columnCOUNTRY); + + if(item1) + { + QIcon icon; + QTableWidgetItem *item2 = m_ui.neighbors->item + (row, columnREMOTE_IP); + + if(item2) + icon = + QIcon(QString(":/Flags/%1.png"). + arg(spoton_misc:: + countryCodeFromIPAddress(item2->text()). + toLower())); + else + icon = QIcon(":/Flags/unknown.png"); + + if(!icon.isNull()) + item1->setIcon(icon); + } + + QByteArray bytes1; + QByteArray bytes2; + QWidget *focusWidget = QApplication::focusWidget(); + bool ok = true; + + bytes1 = m_crypt->decrypted + (QByteArray::fromBase64(query.value(columnREMOTE_IP). + toByteArray()), &ok); + bytes2 = m_crypt->decrypted + (QByteArray::fromBase64(query.value(columnREMOTE_PORT). + toByteArray()), &ok); + + if(remoteIp == bytes1 && remotePort == bytes2) + m_ui.neighbors->selectRow(row); + + if(focusWidget) + focusWidget->setFocus(); + + row += 1; + } + } + + m_ui.neighbors->setSortingEnabled(true); + m_ui.neighbors->horizontalHeader()->setStretchLastSection(true); + m_ui.neighbors->horizontalScrollBar()->setValue(hval); + m_ui.neighbors->verticalScrollBar()->setValue(vval); + } + + db.close(); + } + + QSqlDatabase::removeDatabase("spoton"); + + if(active > 0) + { + m_sb.neighbors->setIcon + (QIcon(QString(":/%1/status-online.png"). + arg(m_settings.value("gui/iconSet", "nouve").toString()))); + m_sb.neighbors->setToolTip + (tr("There is (are) %1 connected neighbor(s)."). + arg(active)); + } + else + { + m_sb.neighbors->setIcon + (QIcon(QString(":/%1/status-offline.png"). + arg(m_settings.value("gui/iconSet", "nouve").toString()))); + m_sb.neighbors->setToolTip(tr("Neighbors are offline.")); + } +} + +void spoton::slotActivateKernel(void) +{ + QString program(m_ui.kernelPath->text()); + +#ifdef Q_OS_MAC + if(QFileInfo(program).isBundle()) + QProcess::startDetached + ("open", QStringList("-a") << program); + else + QProcess::startDetached(program); +#elif defined(Q_OS_WIN32) + /* + ** Must surround the executable's name with quotations. + */ + + QProcess::startDetached(QString("\"%1\"").arg(program)); +#else + QProcess::startDetached(program); +#endif +} + +void spoton::slotDeactivateKernel(void) +{ + QString sharedPath(spoton_misc::homePath() + QDir::separator() + + "shared.db"); + libspoton_handle_t libspotonHandle; + + if(libspoton_init(sharedPath.toStdString().c_str(), + &libspotonHandle) == LIBSPOTON_ERROR_NONE) + libspoton_deregister_kernel + (libspoton_registered_kernel_pid(&libspotonHandle), &libspotonHandle); + + libspoton_close(&libspotonHandle); + m_kernelSocket.close(); + m_messagingCache.clear(); +} + +void spoton::slotGeneralTimerTimeout(void) +{ + QColor color(240, 128, 128); // Light coral! + QPalette pidPalette(m_ui.pid->palette()); + QString sharedPath(spoton_misc::homePath() + QDir::separator() + + "shared.db"); + QString text(m_ui.pid->text()); + libspoton_handle_t libspotonHandle; + + pidPalette.setColor(m_ui.pid->backgroundRole(), color); + + if(libspoton_init(sharedPath.toStdString().c_str(), + &libspotonHandle) == LIBSPOTON_ERROR_NONE) + { + m_ui.pid->setText + (QString::number(libspoton_registered_kernel_pid(&libspotonHandle))); + + if(isKernelActive()) + { + QColor color(144, 238, 144); // Light green! + QPalette palette(m_ui.pid->palette()); + + palette.setColor(m_ui.pid->backgroundRole(), color); + m_ui.pid->setPalette(palette); + } + else + m_ui.pid->setPalette(pidPalette); + } + else + m_ui.pid->setPalette(pidPalette); + + libspoton_close(&libspotonHandle); + highlightKernelPath(); + + if(text != m_ui.pid->text()) + { + m_countriesLastModificationTime = QDateTime(); + m_listenersLastModificationTime = QDateTime(); + m_neighborsLastModificationTime = QDateTime(); + m_participantsLastModificationTime = QDateTime(); + } + + if(text != "0") + if(m_kernelSocket.state() == QAbstractSocket::UnconnectedState) + { + { + QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", "spoton"); + + db.setDatabaseName(spoton_misc::homePath() + QDir::separator() + + "kernel.db"); + + if(db.open()) + { + QSqlQuery query(db); + + query.setForwardOnly(true); + + if(query.exec("SELECT port FROM kernel_gui_server")) + if(query.next()) + { + m_kernelSocket.connectToHost("127.0.0.1", + query.value(0).toInt()); + + /* + ** If the kernel is not responsive, terminate it. + */ + + if(!m_kernelSocket.waitForConnected(10000)) + slotDeactivateKernel(); + } + } + + db.close(); + } + + QSqlDatabase::removeDatabase("spoton"); + } + + slotKernelSocketState(); +} + +void spoton::slotSelectKernelPath(void) +{ + QFileDialog dialog(this); + + dialog.setFilter(QDir::AllDirs | QDir::Files +#if defined Q_OS_LINUX || defined Q_OS_MAC || defined Q_OS_UNIX + | QDir::Readable | QDir::Executable); +#else + ); +#endif + dialog.setWindowTitle + (tr("Spot-On: Select Kernel Path")); + dialog.setFileMode(QFileDialog::ExistingFile); + dialog.setDirectory(QDir::homePath()); + dialog.setLabelText(QFileDialog::Accept, tr("&Select")); + dialog.setAcceptMode(QFileDialog::AcceptOpen); +#ifdef Q_OS_MAC +#if QT_VERSION < 0x050000 + dialog.setAttribute(Qt::WA_MacMetalStyle, false); +#endif +#endif + + if(dialog.exec() == QDialog::Accepted) + saveKernelPath(dialog.selectedFiles().value(0).trimmed()); +} + +void spoton::slotSaveKernelPath(void) +{ + saveKernelPath(m_ui.kernelPath->text().trimmed()); +} + +void spoton::saveKernelPath(const QString &path) +{ + if(!path.isEmpty()) + { + m_settings["gui/kernelPath"] = path; + + QSettings settings; + + settings.setValue("gui/kernelPath", path); + m_ui.kernelPath->setText(path); + m_ui.kernelPath->setToolTip(path); + m_ui.kernelPath->selectAll(); + } +} + +void spoton::saveSettings(void) +{ + QSettings settings; + + if(spoton_misc::isGnome()) + settings.setValue("gui/geometry", geometry()); + else + settings.setValue("gui/geometry", saveGeometry()); + + settings.setValue("gui/chatHorizontalSplitter", + m_ui.chatHorizontalSplitter->saveState()); + settings.setValue("gui/currentTabIndex", m_ui.tab->currentIndex()); + settings.setValue("gui/listenersHorizontalSplitter", + m_ui.listenersHorizontalSplitter->saveState()); + settings.setValue("gui/neighborsVerticalSplitter", + m_ui.neighborsVerticalSplitter->saveState()); + settings.setValue("gui/readVerticalSplitter", + m_ui.readVerticalSplitter->saveState()); + settings.setValue("gui/urlsVerticalSplitter", + m_ui.urlsVerticalSplitter->saveState()); +} + +void spoton::closeEvent(QCloseEvent *event) +{ + saveSettings(); + QMainWindow::closeEvent(event); + QApplication::instance()->quit(); +} + +void spoton::slotDeleteListener(void) +{ + QString oid(""); + int row = -1; + + if((row = m_ui.listeners->currentRow()) >= 0) + { + QTableWidgetItem *item = m_ui.listeners->item + (row, m_ui.listeners->columnCount() - 1); // OID + + if(item) + oid = item->text(); + } + + { + QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", "spoton"); + + db.setDatabaseName(spoton_misc::homePath() + QDir::separator() + + "listeners.db"); + + if(db.open()) + { + QSqlQuery query(db); + + if(!isKernelActive()) + query.prepare("DELETE FROM listeners WHERE " + "OID = ?"); + else + query.prepare("UPDATE listeners SET status_control = 'deleted' " + "WHERE " + "OID = ?"); + + query.bindValue(0, oid); + query.exec(); + } + + db.close(); + } + + QSqlDatabase::removeDatabase("spoton"); + + if(row > -1) + m_ui.listeners->removeRow(row); +} + +void spoton::slotDeleteNeighbor(void) +{ + QString oid(""); + int row = -1; + + if((row = m_ui.neighbors->currentRow()) >= 0) + { + QTableWidgetItem *item = m_ui.neighbors->item + (row, m_ui.neighbors->columnCount() - 1); // OID + + if(item) + oid = item->text(); + } + + { + QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", "spoton"); + + db.setDatabaseName(spoton_misc::homePath() + QDir::separator() + + "neighbors.db"); + + if(db.open()) + { + QSqlQuery query(db); + + if(!isKernelActive()) + query.prepare("DELETE FROM neighbors WHERE " + "OID = ?"); + else + query.prepare("UPDATE neighbors SET status_control = 'deleted' " + "WHERE OID = ?"); + + query.bindValue(0, oid); + query.exec(); + } + + db.close(); + } + + QSqlDatabase::removeDatabase("spoton"); + + if(row > -1) + m_ui.neighbors->removeRow(row); +} + +void spoton::slotListenerCheckChange(int state) +{ + QCheckBox *checkBox = qobject_cast<QCheckBox *> (sender()); + + if(checkBox) + { + { + QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", "spoton"); + + db.setDatabaseName(spoton_misc::homePath() + QDir::separator() + + "listeners.db"); + + if(db.open()) + { + QSqlQuery query(db); + + query.prepare("UPDATE listeners SET " + "status_control = ? " + "WHERE OID = ?"); + + if(state) + query.bindValue(0, "online"); + else + query.bindValue(0, "offline"); + + query.bindValue(1, checkBox->property("oid")); + query.exec(); + } + + db.close(); + } + + QSqlDatabase::removeDatabase("spoton"); + } +} + +void spoton::updateListenersTable(QSqlDatabase &db) +{ + if(!isKernelActive()) + if(db.isOpen()) + { + QSqlQuery query(db); + + /* + ** OK, so the kernel is inactive. Discover the + ** listeners that have not been deleted and update some of their + ** information. + */ + + query.exec("PRAGMA synchronous = OFF"); + query.exec("DELETE FROM listeners WHERE " + "status_control = 'deleted'"); + query.exec("UPDATE listeners SET connections = 0, " + "external_ip_address = NULL, " + "status = 'offline' WHERE " + "(status = 'online' OR connections > 0) AND " + "status_control <> 'deleted'"); + } +} + +void spoton::updateNeighborsTable(QSqlDatabase &db) +{ + if(m_ui.keepOnlyUserDefinedNeighbors->isChecked()) + if(db.isOpen()) + { + /* + ** Delete random, disconnected peers. + */ + + QSqlQuery query(db); + + query.exec("PRAGMA synchronous = OFF"); + query.exec("DELETE FROM neighbors WHERE " + "status <> 'connected' AND " + "status_control <> 'blocked' AND " + "user_defined = 0"); + } + + if(!isKernelActive()) + if(db.isOpen()) + { + QSqlQuery query(db); + + /* + ** OK, so the kernel is inactive. Discover the + ** neighbors that have not been deleted and not disconnected + ** and update some of their information. + */ + + query.exec("PRAGMA synchronous = OFF"); + query.exec("DELETE FROM neighbors WHERE " + "status_control = 'deleted'"); + query.exec("UPDATE neighbors SET external_ip_address = NULL, " + "local_ip_address = NULL, " + "local_port = NULL, status = 'disconnected' WHERE " + "(local_ip_address IS NOT NULL OR local_port IS NOT NULL " + "OR status <> 'disconnected') AND " + "status_control <> 'deleted'"); + } +} + +void spoton::updateParticipantsTable(QSqlDatabase &db) +{ + if(!isKernelActive()) + if(db.isOpen()) + { + QSqlQuery query(db); + + /* + ** OK, so the kernel is inactive. All participants are offline. + */ + + query.exec("PRAGMA synchronous = OFF"); + query.exec("UPDATE symmetric_keys SET status = 'offline' WHERE " + "status <> 'offline'"); + } +} + +void spoton::slotSetPassphrase(void) +{ + bool reencode = false; + QString str1(m_ui.passphrase1->text()); + QString str2(m_ui.passphrase2->text()); + + if(str1.length() < 16 || str2.length() < 16) + { + QMessageBox::critical(this, tr("Spot-On: Error"), + tr("The passphrases must contain at least " + "sixteen characters each.")); + m_ui.passphrase1->selectAll(); + m_ui.passphrase1->setFocus(); + return; + } + else if(str1 != str2) + { + QMessageBox::critical(this, tr("Spot-On: Error"), + tr("The passphrases are not equal.")); + m_ui.passphrase1->selectAll(); + m_ui.passphrase1->setFocus(); + return; + } + + if(spoton_gcrypt::passphraseSet()) + { + QMessageBox mb(this); + +#ifdef Q_OS_MAC +#if QT_VERSION < 0x050000 + mb.setAttribute(Qt::WA_MacMetalStyle, true); +#endif +#endif + mb.setIcon(QMessageBox::Question); + mb.setWindowTitle(tr("Spot-On: Confirmation")); + mb.setWindowModality(Qt::WindowModal); + mb.setStandardButtons(QMessageBox::No | QMessageBox::Yes); + mb.setText(tr("Are you sure that you wish to replace the " + "existing passphrase? Please note that URL data must " + "be re-encoded via a separate tool. Please see " + "the Tools folder.")); + + if(mb.exec() != QMessageBox::Yes) + { + m_ui.passphrase1->setText("0000000000"); + m_ui.passphrase2->setText("0000000000"); + return; + } + else + reencode = true; + } + + /* + ** Create the RSA public and private keys. + */ + + m_sb.status->setText + (tr("Generating a derived key. Please be patient.")); + QApplication::processEvents(); + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + + /* + ** Generate a key and use the key to encrypt the private RSA key. + */ + + QByteArray salt; + QByteArray saltedPassphraseHash; + QString error1(""); + QString error2(""); + QString error3(""); + + salt.resize(m_ui.saltLength->value()); + salt = spoton_gcrypt::strongRandomBytes(salt.length()); + + QByteArray derivedKey + (spoton_gcrypt::derivedKey(m_ui.cipherType->currentText(), + m_ui.hashType->currentText(), + static_cast<unsigned long> (m_ui. + iterationCount-> + value()), + str1, + salt, + error1)); + + m_sb.status->clear(); + + if(error1.isEmpty()) + { + slotDeactivateKernel(); + + if(!m_ui.newRSAKeys->isChecked() && reencode) + { + m_sb.status->setText + (tr("Re-encoding RSA key pair 1 of 2. Please be patient.")); + m_sb.status->repaint(); + spoton_gcrypt::reencodeRSAKeys + (m_ui.cipherType->currentText(), + derivedKey, + m_settings.value("gui/cipherType", "aes256"). + toString().trimmed(), + m_crypt->symmetricKey(), + "messaging", + error2); + m_sb.status->clear(); + + if(error2.isEmpty()) + { + m_sb.status->setText + (tr("Re-encoding RSA key pair 2 of 2. Please be patient.")); + m_sb.status->repaint(); + spoton_gcrypt::reencodeRSAKeys + (m_ui.cipherType->currentText(), + derivedKey, + m_settings.value("gui/cipherType", "aes256"). + toString().trimmed(), + m_crypt->symmetricKey(), + "url", + error2); + m_sb.status->clear(); + } + } + else + { + QStringList list; + + list << "messaging" + << "url"; + + for(int i = 0; i < list.size(); i++) + { + m_sb.status->setText + (tr("Generating RSA key pair %1 of %2. Please be patient."). + arg(i + 1).arg(list.size())); + m_sb.status->repaint(); + + spoton_gcrypt crypt + (m_ui.cipherType->currentText(), + m_ui.hashType->currentText(), + str1.toUtf8(), + derivedKey, + m_ui.saltLength->value(), + m_ui.iterationCount->value(), + list.at(i)); + + crypt.generatePrivatePublicKeys + (m_ui.rsaKeySize->currentText().toInt(), error2); + m_sb.status->clear(); + + if(!error2.isEmpty()) + break; + } + } + } + + if(error1.isEmpty() && error2.isEmpty()) + saltedPassphraseHash = spoton_gcrypt::saltedPassphraseHash + (m_ui.hashType->currentText(), str1, salt, error3); + + QApplication::restoreOverrideCursor(); + + if(!error1.isEmpty()) + QMessageBox::critical(this, tr("Spot-On: Error"), + tr("An error (%1) occurred with spoton_gcrypt::" + "derivedKey().").arg(error1.remove("."))); + else if(!error2.isEmpty()) + QMessageBox::critical(this, tr("Spot-On: Error"), + tr("An error (%1) occurred with " + "spoton_gcrypt::" + "generatePrivatePublicKeys() or " + "spoton_gcrypt::" + "reencodeRSAKeys()."). + arg(error2.remove("."))); + else if(!error3.isEmpty()) + QMessageBox::critical(this, tr("Spot-On: Error"), + tr("An error (%1) occurred with spoton_gcrypt::" + "saltedPassphraseHash()."). + arg(error3.remove("."))); + else + { + if(!m_crypt || reencode) + { + if(reencode) + { + spoton_gcrypt *crypt = new spoton_gcrypt + (m_ui.cipherType->currentText(), + m_ui.hashType->currentText(), + str1.toUtf8(), + derivedKey, + m_ui.saltLength->value(), + m_ui.iterationCount->value(), + "messaging"); + + spoton_reencode reencode; + + m_tableTimer.stop(); + reencode.reencode(m_sb, crypt, m_crypt); + delete crypt; + m_tableTimer.start(); + } + + delete m_crypt; + m_crypt = new spoton_gcrypt + (m_ui.cipherType->currentText(), + m_ui.hashType->currentText(), + str1.toUtf8(), + derivedKey, + m_ui.saltLength->value(), + m_ui.iterationCount->value(), + "messaging"); + + if(!reencode) + { + m_sb.status->setText + (tr("Initializing country_inclusion.db.")); + m_sb.status->repaint(); + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + spoton_misc::populateCountryDatabase(m_crypt); + QApplication::restoreOverrideCursor(); + m_sb.status->clear(); + } + + if(!m_tableTimer.isActive()) + m_tableTimer.start(); + + sendKeysToKernel(); + } + + m_sb.kernelstatus->setEnabled(true); + m_sb.listeners->setEnabled(true); + m_sb.neighbors->setEnabled(true); + m_ui.kernelBox->setEnabled(true); + m_ui.listenersBox->setEnabled(true); + m_ui.newRSAKeys->setChecked(false); + m_ui.newRSAKeys->setEnabled(true); + m_ui.passphrase1->setText("0000000000"); + m_ui.passphrase2->setText("0000000000"); + m_ui.rsaKeySize->setEnabled(false); + + for(int i = 0; i < m_ui.tab->count(); i++) + m_ui.tab->setTabEnabled(i, true); + + /* + ** Save the various entities. + */ + + m_settings["gui/cipherType"] = m_ui.cipherType->currentText(); + m_settings["gui/hashType"] = m_ui.hashType->currentText(); + m_settings["gui/iterationCount"] = m_ui.iterationCount->value(); + m_settings["gui/rsaKeySize"] = m_ui.rsaKeySize->currentText().toInt(); + m_settings["gui/salt"] = salt.toHex(); + m_settings["gui/saltLength"] = m_ui.saltLength->value(); + m_settings["gui/saltedPassphraseHash"] = saltedPassphraseHash.toHex(); + + QSettings settings; + + settings.setValue("gui/cipherType", m_settings["gui/cipherType"]); + settings.setValue("gui/hashType", m_settings["gui/hashType"]); + settings.setValue("gui/iterationCount", + m_settings["gui/iterationCount"]); + settings.setValue("gui/rsaKeySize", m_settings["gui/rsaKeySize"]); + settings.setValue("gui/salt", m_settings["gui/salt"]); + settings.setValue("gui/saltLength", m_settings["gui/saltLength"]); + settings.setValue + ("gui/saltedPassphraseHash", m_settings["gui/saltedPassphraseHash"]); + + QMessageBox::information + (this, tr("Spot-On: Information"), + tr("Your RSA keys and the passphrase have been recorded. " + "You are now ready to use the full power of Spot-On. Enjoy!")); + + QMessageBox mb(this); + +#ifdef Q_OS_MAC +#if QT_VERSION < 0x050000 + mb.setAttribute(Qt::WA_MacMetalStyle, true); +#endif +#endif + mb.setIcon(QM... [truncated message content] |
From: <tex...@us...> - 2013-06-17 00:05:45
|
Revision: 1310 http://sourceforge.net/p/spot-on/code/1310 Author: textfield Date: 2013-06-17 00:05:40 +0000 (Mon, 17 Jun 2013) Log Message: ----------- Separated spot-on.cc into two files. Modified Paths: -------------- branches/0.x/GUI/spot-on.h branches/0.x/spot-on-gui.freebsd.pro branches/0.x/spot-on-gui.freebsd.qt5.pro branches/0.x/spot-on-gui.osx.pro branches/0.x/spot-on-gui.osx.qt5.pro branches/0.x/spot-on-gui.pro branches/0.x/spot-on-gui.qt5.pro branches/0.x/spot-on-gui.win.pro branches/0.x/spot-on-gui.win.qt5.pro Added Paths: ----------- branches/0.x/GUI/spot-on-a.cc branches/0.x/GUI/spot-on-b.cc Removed Paths: ------------- branches/0.x/GUI/spot-on.cc Copied: branches/0.x/GUI/spot-on-a.cc (from rev 1309, branches/0.x/GUI/spot-on.cc) =================================================================== --- branches/0.x/GUI/spot-on-a.cc (rev 0) +++ branches/0.x/GUI/spot-on-a.cc 2013-06-17 00:05:40 UTC (rev 1310) @@ -0,0 +1,3004 @@ +/* +** Copyright (c) 2012, 2013 Alexis Megas +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from Spot-On without specific prior written permission. +** +** SPOT-ON IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** SPOT-ON, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "spot-on.h" + +int main(int argc, char *argv[]) +{ +#ifdef Q_OS_MAC +#if QT_VERSION < 0x050000 + QApplication::setStyle(new QMacStyle()); +#else + QApplication::setStyle("fusion"); +#endif +#endif + + QApplication qapplication(argc, argv); + + /* + ** Configure translations. + */ + + QTranslator qtTranslator; + + qtTranslator.load("qt_" + QLocale::system().name(), "Translations"); + qapplication.installTranslator(&qtTranslator); + + QTranslator myappTranslator; + + myappTranslator.load("spot-on_" + QLocale::system().name(), + "Translations"); + qapplication.installTranslator(&myappTranslator); + QCoreApplication::setApplicationName("Spot-On"); + QCoreApplication::setOrganizationName("Spot-On"); + QCoreApplication::setOrganizationDomain("spot-on.sf.net"); + QCoreApplication::setApplicationVersion(SPOTON_VERSION_STR); + QSettings::setPath(QSettings::IniFormat, QSettings::UserScope, + spoton_misc::homePath()); + QSettings::setDefaultFormat(QSettings::IniFormat); + Q_UNUSED(new spoton()); + return qapplication.exec(); +} + +spoton::spoton(void):QMainWindow() +{ + qsrand(QTime(0, 0, 0).secsTo(QTime::currentTime())); + QDir().mkdir(spoton_misc::homePath()); + m_crypt = 0; + m_countriesLastModificationTime = QDateTime(); + m_listenersLastModificationTime = QDateTime(); + m_neighborsLastModificationTime = QDateTime(); + m_participantsLastModificationTime = QDateTime(); + m_ui.setupUi(this); +#ifdef Q_OS_MAC +#if QT_VERSION < 0x050000 + setAttribute(Qt::WA_MacMetalStyle, true); +#endif +#endif + m_sbWidget = new QWidget(this); + m_sb.setupUi(m_sbWidget); + m_sb.chat->setVisible(false); + m_sb.email->setVisible(false); +#ifdef Q_OS_MAC + foreach(QToolButton *toolButton, m_sbWidget->findChildren<QToolButton *> ()) + toolButton->setStyleSheet + ("QToolButton {border: none;}" + "QToolButton::menu-button {border: none;}"); +#endif + connect(this, + SIGNAL(iconsChanged(void)), + &m_logViewer, + SLOT(slotSetIcons(void))); + connect(m_sb.chat, + SIGNAL(clicked(void)), + this, + SLOT(slotStatusButtonClicked(void))); + connect(m_sb.email, + SIGNAL(clicked(void)), + this, + SLOT(slotStatusButtonClicked(void))); + connect(m_sb.listeners, + SIGNAL(clicked(void)), + this, + SLOT(slotStatusButtonClicked(void))); + connect(m_sb.neighbors, + SIGNAL(clicked(void)), + this, + SLOT(slotStatusButtonClicked(void))); + connect(m_sb.errorlog, + SIGNAL(clicked(void)), + this, + SLOT(slotViewLog(void))); + connect(m_sb.kernelstatus, + SIGNAL(clicked(void)), + this, + SLOT(slotKernelStatus(void))); + statusBar()->addPermanentWidget(m_sbWidget, 100); + statusBar()->setStyleSheet("QStatusBar::item {" + "border: none; " + "}"); + statusBar()->setMaximumHeight(m_sbWidget->height()); + connect(m_ui.action_Quit, + SIGNAL(triggered(void)), + this, + SLOT(slotQuit(void))); + connect(m_ui.action_Log_Viewer, + SIGNAL(triggered(void)), + this, + SLOT(slotViewLog(void))); + connect(m_ui.addListener, + SIGNAL(clicked(void)), + this, + SLOT(slotAddListener(void))); + connect(m_ui.addNeighbor, + SIGNAL(clicked(void)), + this, + SLOT(slotAddNeighbor(void))); + connect(m_ui.dynamicdns, + SIGNAL(toggled(bool)), + this, + SLOT(slotProtocolRadioToggled(bool))); + connect(m_ui.ipv4Listener, + SIGNAL(toggled(bool)), + this, + SLOT(slotProtocolRadioToggled(bool))); + connect(m_ui.ipv4Neighbor, + SIGNAL(toggled(bool)), + this, + SLOT(slotProtocolRadioToggled(bool))); + connect(m_ui.ipv6Listener, + SIGNAL(toggled(bool)), + this, + SLOT(slotProtocolRadioToggled(bool))); + connect(m_ui.ipv6Neighbor, + SIGNAL(toggled(bool)), + this, + SLOT(slotProtocolRadioToggled(bool))); + connect(m_ui.activateKernel, + SIGNAL(clicked(void)), + this, + SLOT(slotActivateKernel(void))); + connect(m_ui.deactivateKernel, + SIGNAL(clicked(void)), + this, + SLOT(slotDeactivateKernel(void))); + connect(m_ui.selectKernelPath, + SIGNAL(clicked(void)), + this, + SLOT(slotSelectKernelPath(void))); + connect(m_ui.setPassphrase, + SIGNAL(clicked(void)), + this, + SLOT(slotSetPassphrase(void))); + connect(m_ui.kernelPath, + SIGNAL(returnPressed(void)), + this, + SLOT(slotSaveKernelPath(void))); + connect(m_ui.passphrase, + SIGNAL(returnPressed(void)), + this, + SLOT(slotValidatePassphrase(void))); + connect(m_ui.passphraseButton, + SIGNAL(clicked(void)), + this, + SLOT(slotValidatePassphrase(void))); + connect(m_ui.tab, + SIGNAL(currentChanged(int)), + this, + SLOT(slotTabChanged(int))); + connect(m_ui.sendMessage, + SIGNAL(clicked(void)), + this, + SLOT(slotSendMessage(void))); + connect(m_ui.message, + SIGNAL(returnPressed(void)), + this, + SLOT(slotSendMessage(void))); + connect(m_ui.clearMessages, + SIGNAL(clicked(void)), + m_ui.messages, + SLOT(clear(void))); + connect(m_ui.saveNodeName, + SIGNAL(clicked(void)), + this, + SLOT(slotSaveNodeName(void))); + connect(m_ui.nodeName, + SIGNAL(returnPressed(void)), + this, + SLOT(slotSaveNodeName(void))); + connect(m_ui.scrambler, + SIGNAL(toggled(bool)), + this, + SLOT(slotScramble(bool))); + connect(m_ui.action_Documentation, + SIGNAL(triggered(void)), + this, + SLOT(slotViewDocumentation(void))); + connect(m_ui.listenerIP, + SIGNAL(returnPressed(void)), + this, + SLOT(slotAddListener(void))); + connect(m_ui.neighborIP, + SIGNAL(returnPressed(void)), + this, + SLOT(slotAddNeighbor(void))); + connect(m_ui.listenerIPCombo, + SIGNAL(currentIndexChanged(int)), + this, + SLOT(slotListenerIPComboChanged(int))); + connect(m_ui.folder, + SIGNAL(currentIndexChanged(int)), + this, + SLOT(slotRefreshMail(void))); + connect(m_ui.chatSendMethod, + SIGNAL(currentIndexChanged(int)), + this, + SLOT(slotChatSendMethodChanged(int))); + connect(m_ui.status, + SIGNAL(currentIndexChanged(int)), + this, + SLOT(slotStatusChanged(int))); + connect(m_ui.addFriend, + SIGNAL(clicked(void)), + this, + SLOT(slotAddFriendsKey(void))); + connect(m_ui.clearFriend, + SIGNAL(clicked(void)), + m_ui.friendInformation, + SLOT(clear(void))); + connect(m_ui.resetSpotOn, + SIGNAL(clicked(void)), + this, + SLOT(slotResetAll(void))); + connect(m_ui.sendMail, + SIGNAL(clicked(void)), + this, + SLOT(slotSendMail(void))); + connect(m_ui.participants, + SIGNAL(itemChanged(QTableWidgetItem *)), + this, + SLOT(slotGeminiChanged(QTableWidgetItem *))); + connect(m_ui.generateGoldBug, + SIGNAL(clicked(void)), + this, + SLOT(slotGenerateGoldBug(void))); + connect(m_ui.keepOnlyUserDefinedNeighbors, + SIGNAL(toggled(bool)), + this, + SLOT(slotKeepOnlyUserDefinedNeighbors(bool))); + connect(m_ui.pushButtonClearMail, + SIGNAL(clicked(void)), + this, + SLOT(slotClearOutgoingMessage(void))); + connect(m_ui.pushButtonClearMail, + SIGNAL(clicked(void)), + this, + SLOT(slotDeleteMail(void))); + connect(m_ui.refreshMail, + SIGNAL(clicked(void)), + this, + SLOT(slotRefreshMail(void))); + connect(m_ui.refreshMail, + SIGNAL(clicked(void)), + this, + SLOT(slotRefreshPostOffice(void))); + connect(m_ui.mail, + SIGNAL(itemClicked(QTableWidgetItem *)), + this, + SLOT(slotMailSelected(QTableWidgetItem *))); + connect(m_ui.emptyTrash, + SIGNAL(clicked(void)), + this, + SLOT(slotEmptyTrash(void))); + connect(m_ui.retrieveMail, + SIGNAL(clicked(void)), + this, + SLOT(slotRetrieveMail(void))); + connect(m_ui.mailTab, + SIGNAL(currentChanged(int)), + this, + SLOT(slotMailTabChanged(int))); + connect(m_ui.postofficeCheckBox, + SIGNAL(toggled(bool)), + this, + SLOT(slotEnabledPostOffice(bool))); + connect(m_ui.saveCopy, + SIGNAL(toggled(bool)), + this, + SLOT(slotKeepCopy(bool))); + connect(m_ui.actionNouve, + SIGNAL(triggered(void)), + this, + SLOT(slotSetIcons(void))); + connect(m_ui.actionNuvola, + SIGNAL(triggered(void)), + this, + SLOT(slotSetIcons(void))); + connect(m_ui.newRSAKeys, + SIGNAL(toggled(bool)), + m_ui.rsaKeySize, + SLOT(setEnabled(bool))); + connect(m_ui.days, + SIGNAL(valueChanged(int)), + this, + SLOT(slotDaysChanged(int))); + connect(m_ui.reply, + SIGNAL(clicked(void)), + this, + SLOT(slotReply(void))); + connect(&m_generalTimer, + SIGNAL(timeout(void)), + this, + SLOT(slotGeneralTimerTimeout(void))); + connect(&m_tableTimer, + SIGNAL(timeout(void)), + this, + SLOT(slotPopulateCountries(void))); + connect(&m_tableTimer, + SIGNAL(timeout(void)), + this, + SLOT(slotPopulateListeners(void))); + connect(&m_tableTimer, + SIGNAL(timeout(void)), + this, + SLOT(slotPopulateNeighbors(void))); + connect(&m_tableTimer, + SIGNAL(timeout(void)), + this, + SLOT(slotPopulateParticipants(void))); + connect(&m_kernelSocket, + SIGNAL(connected(void)), + this, + SLOT(slotKernelSocketState(void))); + connect(&m_kernelSocket, + SIGNAL(disconnected(void)), + this, + SLOT(slotKernelSocketState(void))); + connect(&m_kernelSocket, + SIGNAL(readyRead(void)), + this, + SLOT(slotReceivedKernelMessage(void))); + m_sb.kernelstatus->setToolTip + (tr("Not connected to the kernel. Is the kernel " + "active?")); + m_sb.listeners->setToolTip(tr("Listeners are offline.")); + m_sb.neighbors->setToolTip(tr("Neighbors are offline.")); + + QMenu *menu = new QMenu(this); + + connect(menu->addAction(tr("Copy &Messaging Public Key")), + SIGNAL(triggered(void)), this, SLOT(slotCopyMyPublicKey(void))); + connect(menu->addAction(tr("Copy &URL Public Key")), + SIGNAL(triggered(void)), this, SLOT(slotCopyMyURLPublicKey(void))); + m_ui.toolButtonCopytoClipboard->setMenu(menu); + menu = new QMenu(this); + connect(menu->addAction(tr("Share &Messaging Public Key")), + SIGNAL(triggered(void)), this, SLOT(slotSharePublicKey(void))); + connect(menu->addAction(tr("Share &URL Public Key")), + SIGNAL(triggered(void)), this, SLOT(slotShareURLPublicKey(void))); + m_ui.toolButtonMakeFriends->setMenu(menu); + m_generalTimer.start(2500); + m_tableTimer.setInterval(2500); + m_ui.ipv4Listener->setChecked(true); + m_ui.listenerIP->setInputMask("000.000.000.000; "); + m_ui.listenerScopeId->setEnabled(false); + m_ui.listenerScopeIdLabel->setEnabled(false); + m_ui.neighborIP->setInputMask("000.000.000.000; "); + m_ui.neighborScopeId->setEnabled(false); + m_ui.neighborScopeIdLabel->setEnabled(false); + m_ui.participants->setStyleSheet + ("QTableView {selection-background-color: lightgreen}"); + + QSettings settings; + + if(!settings.contains("gui/saveCopy")) + settings.setValue("gui/saveCopy", true); + + if(!settings.contains("gui/uuid")) + { + QUuid uuid(QUuid::createUuid()); + + settings.setValue("gui/uuid", uuid.toString()); + } + + for(int i = 0; i < settings.allKeys().size(); i++) + m_settings[settings.allKeys().at(i)] = settings.value + (settings.allKeys().at(i)); + + if(m_settings.value("gui/iconSet", "nouve").toString() == "nouve") + { + m_ui.menu_Icons->actions().at(0)->setChecked(true); + m_ui.menu_Icons->actions().at(0)->trigger(); + } + else + { + m_ui.menu_Icons->actions().at(1)->setChecked(true); + m_ui.menu_Icons->actions().at(1)->trigger(); + } + + m_sb.kernelstatus->setIcon + (QIcon(QString(":/%1/deactivate.png"). + arg(m_settings.value("gui/iconSet", "nouve").toString()))); + m_sb.listeners->setIcon + (QIcon(QString(":/%1/status-offline.png"). + arg(m_settings.value("gui/iconSet", "nouve").toString()))); + m_sb.neighbors->setIcon + (QIcon(QString(":/%1/status-offline.png"). + arg(m_settings.value("gui/iconSet", "nouve").toString()))); + + if(spoton_misc::isGnome()) + setGeometry(m_settings.value("gui/geometry").toRect()); + else + restoreGeometry(m_settings.value("gui/geometry").toByteArray()); + + if(m_settings.contains("gui/kernelPath") && + QFileInfo(m_settings.value("gui/kernelPath").toString().trimmed()). + isExecutable()) + m_ui.kernelPath->setText(m_settings.value("gui/kernelPath").toString(). + trimmed()); + else + { + QString path(QCoreApplication::applicationDirPath() + + QDir::separator() + +#ifdef Q_OS_MAC + "Spot-On-Kernel.app" +#elif defined(Q_OS_WIN32) + "Spot-On-Kernel.exe" +#else + "Spot-On-Kernel" +#endif + ); + +#ifdef Q_OS_MAC + if(!QFileInfo(path).exists()) + path = QCoreApplication::applicationDirPath() + + QDir::separator() + "Spot-On-Kernel"; +#endif + + m_ui.kernelPath->setText(path); + } + + if(m_settings.value("gui/chatSendMethod", "Artificial_GET"). + toString() == "Artificial_GET") + m_ui.chatSendMethod->setCurrentIndex(0); + else + m_ui.chatSendMethod->setCurrentIndex(1); + + QByteArray status + (m_settings.value("gui/my_status", "Online").toByteArray()); + + if(status == "Away") + m_ui.status->setCurrentIndex(0); + else if(status == "Busy") + m_ui.status->setCurrentIndex(1); + else if(status == "Offline") + m_ui.status->setCurrentIndex(2); + else + m_ui.status->setCurrentIndex(3); + + m_ui.kernelPath->setToolTip(m_ui.kernelPath->text()); + m_ui.nodeName->setMaxLength(NAME_MAXIMUM_LENGTH); + m_ui.nodeName->setText + (QString::fromUtf8(m_settings.value("gui/nodeName", "unknown"). + toByteArray()).trimmed()); + m_ui.goldbug->setMaxLength + (spoton_gcrypt::cipherKeyLength("aes256")); + m_ui.cipherType->clear(); + m_ui.cipherType->addItems(spoton_gcrypt::cipherTypes()); + m_ui.days->setValue(m_settings.value("gui/postofficeDays", 1).toInt()); + m_ui.keepOnlyUserDefinedNeighbors->setChecked + (m_settings.value("gui/keepOnlyUserDefinedNeighbors", false).toBool()); + m_ui.postofficeCheckBox->setChecked + (m_settings.value("gui/postoffice_enabled", false).toBool()); + m_ui.saveCopy->setChecked + (m_settings.value("gui/saveCopy", true).toBool()); + m_ui.scrambler->setChecked + (m_settings.value("gui/scramblerEnabled", false).toBool()); + + /* + ** Please don't translate n/a. + */ + + if(m_ui.cipherType->count() == 0) + m_ui.cipherType->addItem("n/a"); + + m_ui.hashType->clear(); + m_ui.hashType->addItems(spoton_gcrypt::hashTypes()); + + if(m_ui.cipherType->count() == 0) + m_ui.cipherType->addItem("n/a"); + + QString str(""); + + str = m_settings.value("gui/cipherType", "aes256"). + toString().toLower().trimmed(); + + if(m_ui.cipherType->findText(str) > -1) + m_ui.cipherType->setCurrentIndex(m_ui.cipherType->findText(str)); + + str = m_settings.value("gui/hashType", "sha512"). + toString().toLower().trimmed(); + + if(m_ui.hashType->findText(str) > -1) + m_ui.hashType->setCurrentIndex(m_ui.hashType->findText(str)); + + m_ui.iterationCount->setValue(m_settings.value("gui/iterationCount", + 10000).toInt()); + str = m_settings.value("gui/rsaKeySize", "3072"). + toString().toLower().trimmed(); + + if(m_ui.rsaKeySize->findText(str) > -1) + m_ui.rsaKeySize->setCurrentIndex(m_ui.rsaKeySize->findText(str)); + + m_ui.saltLength->setValue(m_settings.value("gui/saltLength", 256).toInt()); + + if(spoton_gcrypt::passphraseSet()) + { + m_sb.kernelstatus->setEnabled(false); + m_sb.listeners->setEnabled(false); + m_sb.neighbors->setEnabled(false); + m_ui.passphrase1->setText("0000000000"); + m_ui.passphrase2->setText("0000000000"); + m_ui.rsaKeySize->setEnabled(false); + + for(int i = 0; i < m_ui.tab->count(); i++) + if(i == m_ui.tab->count() - 1) + { + m_ui.tab->blockSignals(true); + m_ui.tab->setCurrentIndex(i); + m_ui.tab->blockSignals(false); + m_ui.tab->setTabEnabled(i, true); + } + else + m_ui.tab->setTabEnabled(i, false); + + m_ui.passphrase->setFocus(); + } + else + { + m_sb.kernelstatus->setEnabled(false); + m_sb.listeners->setEnabled(false); + m_sb.neighbors->setEnabled(false); + m_ui.newRSAKeys->setChecked(true); + m_ui.newRSAKeys->setEnabled(false); + m_ui.passphrase->setEnabled(false); + m_ui.passphraseButton->setEnabled(false); + m_ui.passphraseLabel->setEnabled(false); + m_ui.kernelBox->setEnabled(false); + m_ui.listenersBox->setEnabled(false); + + for(int i = 0; i < m_ui.tab->count(); i++) + if(i == 5) // Settings + { + m_ui.tab->blockSignals(true); + m_ui.tab->setCurrentIndex(i); + m_ui.tab->blockSignals(false); + m_ui.tab->setTabEnabled(i, true); + } + else + m_ui.tab->setTabEnabled(i, false); + + m_ui.passphrase1->setFocus(); + } + + if(m_settings.contains("gui/chatHorizontalSplitter")) + m_ui.chatHorizontalSplitter->restoreState + (m_settings.value("gui/chatHorizontalSplitter").toByteArray()); + + if(m_settings.contains("gui/listenersHorizontalSplitter")) + m_ui.listenersHorizontalSplitter->restoreState + (m_settings.value("gui/listenersHorizontalSplitter").toByteArray()); + + if(m_settings.contains("gui/neighborsVerticalSplitter")) + m_ui.neighborsVerticalSplitter->restoreState + (m_settings.value("gui/neighborsVerticalSplitter").toByteArray()); + + if(m_settings.contains("gui/readVerticalSplitter")) + m_ui.readVerticalSplitter->restoreState + (m_settings.value("gui/readVerticalSplitter").toByteArray()); + + if(m_settings.contains("gui/urlsVerticalSplitter")) + m_ui.urlsVerticalSplitter->restoreState + (m_settings.value("gui/urlsVerticalSplitter").toByteArray()); + + m_ui.listeners->setContextMenuPolicy(Qt::CustomContextMenu); + m_ui.neighbors->setContextMenuPolicy(Qt::CustomContextMenu); + m_ui.participants->setContextMenuPolicy(Qt::CustomContextMenu); + connect(m_ui.listeners, + SIGNAL(customContextMenuRequested(const QPoint &)), + this, + SLOT(slotShowContextMenu(const QPoint &))); + connect(m_ui.neighbors, + SIGNAL(customContextMenuRequested(const QPoint &)), + this, + SLOT(slotShowContextMenu(const QPoint &))); + connect(m_ui.participants, + SIGNAL(customContextMenuRequested(const QPoint &)), + this, + SLOT(slotShowContextMenu(const QPoint &))); + m_ui.mail->setColumnHidden(4, true); // goldbug + m_ui.mail->setColumnHidden(5, true); // message + m_ui.mail->setColumnHidden(6, true); // message_digest + m_ui.mail->setColumnHidden(7, true); // receiver_sender_hash + m_ui.mail->setColumnHidden(8, true); // OID + m_ui.listeners->setColumnHidden(m_ui.listeners->columnCount() - 1, + true); // OID + m_ui.neighbors->setColumnHidden + (m_ui.neighbors->columnCount() - 1, true); // OID + m_ui.participants->setColumnHidden(1, true); // OID + m_ui.participants->setColumnHidden(2, true); // neighbor_oid + m_ui.participants->setColumnHidden(3, true); // public_key_hash + m_ui.participants->resizeColumnsToContents(); + m_ui.postoffice->setColumnHidden(2, true); // Recipient Hash + m_ui.mail->horizontalHeader()->setSortIndicator + (0, Qt::AscendingOrder); + m_ui.listeners->horizontalHeader()->setSortIndicator + (2, Qt::AscendingOrder); + m_ui.neighbors->horizontalHeader()->setSortIndicator + (1, Qt::AscendingOrder); + m_ui.participants->horizontalHeader()->setSortIndicator + (0, Qt::AscendingOrder); + m_ui.postoffice->horizontalHeader()->setSortIndicator + (0, Qt::AscendingOrder); + m_ui.listenersHorizontalSplitter->setStretchFactor(0, 1); + m_ui.listenersHorizontalSplitter->setStretchFactor(1, 0); + m_ui.neighborsVerticalSplitter->setStretchFactor(0, 1); + m_ui.neighborsVerticalSplitter->setStretchFactor(1, 0); + m_ui.readVerticalSplitter->setStretchFactor(0, 1); + m_ui.readVerticalSplitter->setStretchFactor(1, 0); + m_ui.urlsVerticalSplitter->setStretchFactor(0, 1); + m_ui.urlsVerticalSplitter->setStretchFactor(1, 0); + prepareListenerIPCombo(); + spoton_misc::prepareDatabases(); + + /* + ** Not wise! We may find things we're not prepared for. + */ + + foreach(QAbstractButton *button, + m_ui.participants->findChildren<QAbstractButton *> ()) + button->setToolTip(tr("Broadcast")); + + show(); +} + +void spoton::slotQuit(void) +{ + close(); +} + +void spoton::slotAddListener(void) +{ + if(!m_crypt) + return; + + bool ok = true; + + { + QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", "spoton"); + + db.setDatabaseName(spoton_misc::homePath() + QDir::separator() + + "listeners.db"); + + if(db.open()) + { + spoton_misc::prepareDatabases(); + + QString ip(""); + + if(m_ui.listenerIPCombo->currentIndex() == 0) + ip = m_ui.listenerIP->text().trimmed(); + else + ip = m_ui.listenerIPCombo->currentText(); + + QString port(QString::number(m_ui.listenerPort->value())); + QString protocol(""); + QString scopeId(m_ui.listenerScopeId->text().trimmed()); + QString status("online"); + QSqlQuery query(db); + + if(m_ui.ipv4Listener->isChecked()) + protocol = "IPv4"; + else + protocol = "IPv6"; + + query.prepare("INSERT INTO listeners " + "(ip_address, " + "port, " + "protocol, " + "scope_id, " + "status_control, " + "hash) " + "VALUES " + "(?, ?, ?, ?, ?, ?)"); + + if(ip.isEmpty()) + query.bindValue + (0, m_crypt->encrypted(QByteArray(), &ok).toBase64()); + else + { + QList<int> numbers; + QStringList list; + + if(protocol == "IPv4") + list = ip.split(".", QString::KeepEmptyParts); + else + list = ip.split(":", QString::KeepEmptyParts); + + for(int i = 0; i < list.size(); i++) + numbers.append(list.at(i).toInt()); + + if(protocol == "IPv4") + { + ip = QString::number(numbers.value(0)) + "." + + QString::number(numbers.value(1)) + "." + + QString::number(numbers.value(2)) + "." + + QString::number(numbers.value(3)); + ip.remove("..."); + } + else + { + if(m_ui.listenerIPCombo->currentIndex() == 0) + { + ip = QString::number(numbers.value(0)) + ":" + + QString::number(numbers.value(1)) + ":" + + QString::number(numbers.value(2)) + ":" + + QString::number(numbers.value(3)) + ":" + + QString::number(numbers.value(4)) + ":" + + QString::number(numbers.value(5)) + ":" + + QString::number(numbers.value(6)) + ":" + + QString::number(numbers.value(7)); + ip.remove(":::::::"); + + /* + ** Special exception. + */ + + if(ip == "0:0:0:0:0:0:0:0") + ip = "::"; + } + } + + if(ok) + query.bindValue + (0, m_crypt->encrypted(ip.toLatin1(), &ok).toBase64()); + } + + if(ok) + query.bindValue + (1, m_crypt->encrypted(port.toLatin1(), &ok).toBase64()); + + if(ok) + query.bindValue + (2, m_crypt->encrypted(protocol.toLatin1(), &ok).toBase64()); + + if(ok) + query.bindValue + (3, m_crypt->encrypted(scopeId.toLatin1(), &ok).toBase64()); + + query.bindValue(4, status); + + if(ok) + query.bindValue + (5, m_crypt->keyedHash((ip + port).toLatin1(), &ok). + toBase64()); + + if(ok) + ok = query.exec(); + } + + db.close(); + } + + QSqlDatabase::removeDatabase("spoton"); + + if(ok) + m_ui.listenerIP->selectAll(); +} + +void spoton::slotAddNeighbor(void) +{ + if(!m_crypt) + return; + + bool ok = true; + + { + QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", "spoton"); + + db.setDatabaseName(spoton_misc::homePath() + QDir::separator() + + "neighbors.db"); + + if(db.open()) + { + spoton_misc::prepareDatabases(); + + QString ip(m_ui.neighborIP->text().trimmed()); + QString port(QString::number(m_ui.neighborPort->value())); + QString protocol(""); + QString proxyHostname(""); + QString proxyPassword(""); + QString proxyPort(""); + QString proxyType(""); + QString proxyUsername(""); + QString scopeId(m_ui.neighborScopeId->text().trimmed()); + QString status("connected"); + QSqlQuery query(db); + + if(m_ui.ipv4Neighbor->isChecked()) + protocol = "IPv4"; + else if(m_ui.ipv6Neighbor->isChecked()) + protocol = "IPv6"; + else + protocol = "Dynamic DNS"; + + query.prepare("INSERT INTO neighbors " + "(local_ip_address, " + "local_port, " + "protocol, " + "remote_ip_address, " + "remote_port, " + "sticky, " + "scope_id, " + "hash, " + "status_control, " + "country, " + "remote_ip_address_hash, " + "qt_country_hash, " + "proxy_hostname, " + "proxy_password, " + "proxy_port, " + "proxy_type, " + "proxy_username) " + "VALUES " + "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"); + + query.bindValue(0, QVariant(QVariant::String)); + query.bindValue(1, QVariant(QVariant::String)); + query.bindValue(2, protocol); + + if(ip.isEmpty()) + query.bindValue + (3, m_crypt->encrypted(QByteArray(), &ok).toBase64()); + else + { + if(protocol == "IPv4" || protocol == "IPv6") + { + QList<int> numbers; + QStringList list; + + if(protocol == "IPv4") + list = ip.split(".", QString::KeepEmptyParts); + else + list = ip.split(":", QString::KeepEmptyParts); + + for(int i = 0; i < list.size(); i++) + numbers.append(list.at(i).toInt()); + + ip.clear(); + + if(protocol == "IPv4") + { + ip = QString::number(numbers.value(0)) + "." + + QString::number(numbers.value(1)) + "." + + QString::number(numbers.value(2)) + "." + + QString::number(numbers.value(3)); + ip.remove("..."); + } + else + { + ip = QString::number(numbers.value(0)) + ":" + + QString::number(numbers.value(1)) + ":" + + QString::number(numbers.value(2)) + ":" + + QString::number(numbers.value(3)) + ":" + + QString::number(numbers.value(4)) + ":" + + QString::number(numbers.value(5)) + ":" + + QString::number(numbers.value(6)) + ":" + + QString::number(numbers.value(7)); + ip.remove(":::::::"); + + /* + ** Special exception. + */ + + if(ip == "0:0:0:0:0:0:0:0") + ip = "::"; + } + } + + if(ok) + query.bindValue + (3, m_crypt->encrypted(ip.toLatin1(), &ok).toBase64()); + } + + query.bindValue(5, 1); // Sticky. + + if(ok) + query.bindValue + (4, m_crypt->encrypted(port.toLatin1(), &ok).toBase64()); + + if(ok) + query.bindValue + (6, m_crypt->encrypted(scopeId.toLatin1(), &ok).toBase64()); + + if(ok) + query.bindValue + (7, m_crypt->keyedHash((ip + port).toLatin1(), &ok). + toBase64()); + + query.bindValue(8, status); + + QString country(spoton_misc::countryNameFromIPAddress(ip)); + + if(ok) + query.bindValue + (9, m_crypt->encrypted(country.toLatin1(), &ok).toBase64()); + + if(ok) + query.bindValue + (10, m_crypt->keyedHash(ip.toLatin1(), &ok). + toBase64()); + + if(ok) + query.bindValue + (11, m_crypt->keyedHash(country.remove(" ").toLatin1(), &ok). + toBase64()); + + proxyHostname = m_ui.proxyHostname->text().trimmed(); + proxyPassword = m_ui.proxyPassword->text(); + proxyPort = QString::number(m_ui.proxyPort->value()); + + if(m_ui.proxy->isChecked()) + proxyType = m_ui.proxyType->currentText(); + else + proxyType = "NoProxy"; + + proxyUsername = m_ui.proxyUsername->text(); + + if(ok) + query.bindValue + (12, m_crypt->encrypted(proxyHostname.toLatin1(), &ok). + toBase64()); + + if(ok) + query.bindValue + (13, m_crypt->encrypted(proxyPassword.toUtf8(), &ok). + toBase64()); + + if(ok) + query.bindValue + (14, m_crypt->encrypted(proxyPort.toLatin1(), + &ok).toBase64()); + + if(ok) + query.bindValue + (15, m_crypt->encrypted(proxyType.toLatin1(), &ok). + toBase64()); + + if(ok) + query.bindValue + (16, m_crypt->encrypted(proxyUsername.toUtf8(), &ok). + toBase64()); + + if(ok) + ok = query.exec(); + } + + db.close(); + } + + QSqlDatabase::removeDatabase("spoton"); + + if(ok) + m_ui.neighborIP->selectAll(); +} + +void spoton::slotProtocolRadioToggled(bool state) +{ + Q_UNUSED(state); + + QRadioButton *radio = qobject_cast<QRadioButton *> (sender()); + + if(!radio) + return; + + if(radio == m_ui.dynamicdns) + { + m_ui.neighborIP->clear(); + m_ui.neighborIP->setInputMask(""); + m_ui.neighborScopeId->setEnabled(true); + m_ui.neighborScopeIdLabel->setEnabled(true); + } + else if(radio == m_ui.ipv4Listener || radio == m_ui.ipv4Neighbor) + { + if(radio == m_ui.ipv4Listener) + { + m_ui.listenerIP->setInputMask("000.000.000.000; "); + m_ui.listenerScopeId->setEnabled(false); + m_ui.listenerScopeIdLabel->setEnabled(false); + } + else + { + m_ui.neighborIP->clear(); + m_ui.neighborIP->setInputMask("000.000.000.000; "); + m_ui.neighborScopeId->setEnabled(false); + m_ui.neighborScopeIdLabel->setEnabled(false); + } + } + else + { + if(radio == m_ui.ipv6Listener) + { + m_ui.listenerIP->setInputMask + ("HHHH:HHHH:HHHH:HHHH:HHHH:HHHH:HHHH:HHHH; "); + m_ui.listenerScopeId->setEnabled(true); + m_ui.listenerScopeIdLabel->setEnabled(true); + } + else + { + m_ui.neighborIP->clear(); + m_ui.neighborIP->setInputMask + ("HHHH:HHHH:HHHH:HHHH:HHHH:HHHH:HHHH:HHHH; "); + m_ui.neighborScopeId->setEnabled(true); + m_ui.neighborScopeIdLabel->setEnabled(true); + } + } + + prepareListenerIPCombo(); +} + +void spoton::slotScramble(bool state) +{ + m_settings["gui/scramblerEnabled"] = state; + + QSettings settings; + + settings.setValue("gui/scramblerEnabled", state); +} + +void spoton::slotPopulateListeners(void) +{ + if(!m_crypt) + return; + + QFileInfo fileInfo(spoton_misc::homePath() + QDir::separator() + + "listeners.db"); + + if(fileInfo.exists()) + { + if(fileInfo.lastModified() <= m_listenersLastModificationTime) + return; + else + m_listenersLastModificationTime = fileInfo.lastModified(); + } + else + m_listenersLastModificationTime = QDateTime(); + + int active = 0; + + { + QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", "spoton"); + + db.setDatabaseName(fileInfo.absoluteFilePath()); + + if(db.open()) + { + updateListenersTable(db); + + QModelIndexList list; + QString ip(""); + QString port(""); + int columnIP = 2; + int columnPORT = 3; + int hval = m_ui.listeners->horizontalScrollBar()->value(); + int row = -1; + int vval = m_ui.listeners->verticalScrollBar()->value(); + + list = m_ui.listeners->selectionModel()->selectedRows + (columnIP); + + if(!list.isEmpty()) + ip = list.at(0).data().toString(); + + list = m_ui.listeners->selectionModel()->selectedRows + (columnPORT); + + if(!list.isEmpty()) + port = list.at(0).data().toString(); + + m_ui.listeners->setSortingEnabled(false); + m_ui.listeners->clearContents(); + m_ui.listeners->setRowCount(0); + + QSqlQuery query(db); + + query.setForwardOnly(true); + + if(query.exec("SELECT " + "status_control, status, " + "ip_address, port, scope_id, protocol, " + "external_ip_address, external_port, " + "connections, maximum_clients, OID " + "FROM listeners")) + { + row = 0; + + while(query.next()) + { + QCheckBox *check = 0; + QComboBox *box = 0; + QTableWidgetItem *item = 0; + + m_ui.listeners->setRowCount(row + 1); + + for(int i = 0; i < query.record().count(); i++) + { + if(i == 0) + { + check = new QCheckBox(); + + if(query.value(0) == "online") + check->setChecked(true); + + if(query.value(1) == "online") + active += 1; + + check->setProperty("oid", query.value(10)); + check->setProperty("table_row", row); + connect(check, + SIGNAL(stateChanged(int)), + this, + SLOT(slotListenerCheckChange(int))); + m_ui.listeners->setCellWidget(row, i, check); + } + else if(i == 9) + { + box = new QComboBox(); + box->setProperty("oid", query.value(10)); + box->setProperty("table_row", row); + + for(int j = 1; j <= 10; j++) + box->addItem(QString::number(5 * j)); + + box->addItem(tr("Unlimited")); + box->setMaximumWidth + (box->fontMetrics().width(tr("Unlimited")) + 50); + m_ui.listeners->setCellWidget(row, i, box); + + if(std::numeric_limits<int>::max() == + query.value(i).toInt()) + box->setCurrentIndex(box->count() - 1); + else if(box->findText(QString::number(query. + value(i). + toInt()))) + box->setCurrentIndex + (box->findText(QString::number(query. + value(i). + toInt()))); + else + box->setCurrentIndex(box->count() - 2); + + connect(box, + SIGNAL(currentIndexChanged(int)), + this, + SLOT(slotMaximumClientsChanged(int))); + } + else + { + bool ok = true; + + if(i >= 2 && i <= 6) + { + if(query.isNull(i)) + item = new QTableWidgetItem(); + else + item = new QTableWidgetItem + (m_crypt->decrypted(QByteArray:: + fromBase64(query. + value(i). + toByteArray()), + &ok). + constData()); + } + else + item = new QTableWidgetItem(query. + value(i).toString()); + + item->setFlags + (Qt::ItemIsSelectable | Qt::ItemIsEnabled); + m_ui.listeners->setItem(row, i, item); + + if(i == 1) + { + if(query.value(i).toString() == "online") + item->setBackground + (QBrush(QColor("lightgreen"))); + else + item->setBackground(QBrush()); + } + } + } + + QByteArray bytes1; + QByteArray bytes2; + QWidget *focusWidget = QApplication::focusWidget(); + bool ok = true; + + bytes1 = m_crypt->decrypted + (QByteArray::fromBase64(query.value(2).toByteArray()), + &ok); + bytes2 = m_crypt->decrypted + (QByteArray::fromBase64(query.value(3).toByteArray()), + &ok); + + if(ip == bytes1 && port == bytes2) + m_ui.listeners->selectRow(row); + + if(focusWidget) + focusWidget->setFocus(); + + row += 1; + } + } + + m_ui.listeners->setSortingEnabled(true); + + for(int i = 0; i < m_ui.listeners->columnCount() - 1; i++) + /* + ** Ignore the OID column. + */ + + m_ui.listeners->resizeColumnToContents(i); + + m_ui.listeners->horizontalHeader()->setStretchLastSection(true); + m_ui.listeners->horizontalScrollBar()->setValue(hval); + m_ui.listeners->verticalScrollBar()->setValue(vval); + } + + db.close(); + } + + QSqlDatabase::removeDatabase("spoton"); + + if(active > 0) + { + m_sb.listeners->setIcon + (QIcon(QString(":/%1/status-online.png"). + arg(m_settings.value("gui/iconSet", "nouve").toString()))); + m_sb.listeners->setToolTip + (tr("There is (are) %1 active listener(s).").arg(active)); + } + else + { + m_sb.listeners->setIcon + (QIcon(QString(":/%1/status-offline.png"). + arg(m_settings.value("gui/iconSet", "nouve").toString()))); + m_sb.listeners->setToolTip(tr("Listeners are offline.")); + } +} + +void spoton::slotPopulateNeighbors(void) +{ + if(!m_crypt) + return; + + QFileInfo fileInfo(spoton_misc::homePath() + QDir::separator() + + "neighbors.db"); + + if(fileInfo.exists()) + { + if(fileInfo.lastModified() <= m_neighborsLastModificationTime) + return; + else + m_neighborsLastModificationTime = fileInfo.lastModified(); + } + else + m_neighborsLastModificationTime = QDateTime(); + + int active = 0; + + { + QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", "spoton"); + + db.setDatabaseName(fileInfo.absoluteFilePath()); + + if(db.open()) + { + updateNeighborsTable(db); + + QModelIndexList list; + QString remoteIp(""); + QString remotePort(""); + int columnCOUNTRY = 8; + int columnREMOTE_IP = 9; + int columnREMOTE_PORT = 10; + int hval = m_ui.neighbors->horizontalScrollBar()->value(); + int row = -1; + int vval = m_ui.neighbors->verticalScrollBar()->value(); + + list = m_ui.neighbors->selectionModel()->selectedRows + (columnREMOTE_IP); + + if(!list.isEmpty()) + remoteIp = list.at(0).data().toString(); + + list = m_ui.neighbors->selectionModel()->selectedRows + (columnREMOTE_PORT); + + if(!list.isEmpty()) + remotePort = list.at(0).data().toString(); + + m_ui.neighbors->setSortingEnabled(false); + m_ui.neighbors->clearContents(); + m_ui.neighbors->setRowCount(0); + + QSqlQuery query(db); + + query.setForwardOnly(true); + + if(query.exec("SELECT sticky, UPPER(uuid), status, " + "status_control, " + "local_ip_address, local_port, " + "external_ip_address, external_port, " + "country, " + "remote_ip_address, " + "remote_port, scope_id, protocol, " + "proxy_hostname, proxy_port, OID " + "FROM neighbors")) + { + QString localIp(""); + QString localPort(""); + + row = 0; + + while(query.next()) + { + m_ui.neighbors->setRowCount(row + 1); + + QCheckBox *check = 0; + + check = new QCheckBox(); + check->setToolTip(tr("The sticky feature enables an " + "indefinite lifetime for a neighbor.\n" + "If " + "not checked, the neighbor will be " + "terminated after some internal " + "timer expires.")); + + if(query.value(0).toInt() == 1) + check->setChecked(true); + else + check->setChecked(false); + + check->setProperty + ("oid", query.value(query.record().count() - 1)); + check->setProperty("table_row", row); + connect(check, + SIGNAL(stateChanged(int)), + this, + SLOT(slotNeighborCheckChange(int))); + m_ui.neighbors->setCellWidget(row, 0, check); + + for(int i = 1; i < query.record().count(); i++) + { + QTableWidgetItem *item = 0; + + if(i == 2) + { + if(query.value(i).toString() == "connected") + active += 1; + } + + if(i == 6 || (i >= 8 && i <= 11) || (i >= 13 && i <= 14)) + { + if(query.value(i).isNull()) + item = new QTableWidgetItem(); + else + { + bool ok = true; + + item = new QTableWidgetItem + (m_crypt->decrypted(QByteArray:: + fromBase64(query. + value(i). + toByteArray()), + &ok).constData()); + } + } + else + item = new QTableWidgetItem + (query.value(i).toString()); + + item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); + + if(i == 2) + { + if(query.value(i).toString() == "connected") + item->setBackground(QBrush(QColor("lightgreen"))); + else + item->setBackground(QBrush()); + } + + m_ui.neighbors->setItem(row, i, item); + } + + QTableWidgetItem *item1 = m_ui.neighbors->item + (row, columnCOUNTRY); + + if(item1) + { + QIcon icon; + QTableWidgetItem *item2 = m_ui.neighbors->item + (row, columnREMOTE_IP); + + if(item2) + icon = + QIcon(QString(":/Flags/%1.png"). + arg(spoton_misc:: + countryCodeFromIPAddress(item2->text()). + toLower())); + else + icon = QIcon(":/Flags/unknown.png"); + + if(!icon.isNull()) + item1->setIcon(icon); + } + + QByteArray bytes1; + QByteArray bytes2; + QWidget *focusWidget = QApplication::focusWidget(); + bool ok = true; + + bytes1 = m_crypt->decrypted + (QByteArray::fromBase64(query.value(columnREMOTE_IP). + toByteArray()), &ok); + bytes2 = m_crypt->decrypted + (QByteArray::fromBase64(query.value(columnREMOTE_PORT). + toByteArray()), &ok); + + if(remoteIp == bytes1 && remotePort == bytes2) + m_ui.neighbors->selectRow(row); + + if(focusWidget) + focusWidget->setFocus(); + + row += 1; + } + } + + m_ui.neighbors->setSortingEnabled(true); + m_ui.neighbors->horizontalHeader()->setStretchLastSection(true); + m_ui.neighbors->horizontalScrollBar()->setValue(hval); + m_ui.neighbors->verticalScrollBar()->setValue(vval); + } + + db.close(); + } + + QSqlDatabase::removeDatabase("spoton"); + + if(active > 0) + { + m_sb.neighbors->setIcon + (QIcon(QString(":/%1/status-online.png"). + arg(m_settings.value("gui/iconSet", "nouve").toString()))); + m_sb.neighbors->setToolTip + (tr("There is (are) %1 connected neighbor(s)."). + arg(active)); + } + else + { + m_sb.neighbors->setIcon + (QIcon(QString(":/%1/status-offline.png"). + arg(m_settings.value("gui/iconSet", "nouve").toString()))); + m_sb.neighbors->setToolTip(tr("Neighbors are offline.")); + } +} + +void spoton::slotActivateKernel(void) +{ + QString program(m_ui.kernelPath->text()); + +#ifdef Q_OS_MAC + if(QFileInfo(program).isBundle()) + QProcess::startDetached + ("open", QStringList("-a") << program); + else + QProcess::startDetached(program); +#elif defined(Q_OS_WIN32) + /* + ** Must surround the executable's name with quotations. + */ + + QProcess::startDetached(QString("\"%1\"").arg(program)); +#else + QProcess::startDetached(program); +#endif +} + +void spoton::slotDeactivateKernel(void) +{ + QString sharedPath(spoton_misc::homePath() + QDir::separator() + + "shared.db"); + libspoton_handle_t libspotonHandle; + + if(libspoton_init(sharedPath.toStdString().c_str(), + &libspotonHandle) == LIBSPOTON_ERROR_NONE) + libspoton_deregister_kernel + (libspoton_registered_kernel_pid(&libspotonHandle), &libspotonHandle); + + libspoton_close(&libspotonHandle); + m_kernelSocket.close(); + m_messagingCache.clear(); +} + +void spoton::slotGeneralTimerTimeout(void) +{ + QColor color(240, 128, 128); // Light coral! + QPalette pidPalette(m_ui.pid->palette()); + QString sharedPath(spoton_misc::homePath() + QDir::separator() + + "shared.db"); + QString text(m_ui.pid->text()); + libspoton_handle_t libspotonHandle; + + pidPalette.setColor(m_ui.pid->backgroundRole(), color); + + if(libspoton_init(sharedPath.toStdString().c_str(), + &libspotonHandle) == LIBSPOTON_ERROR_NONE) + { + m_ui.pid->setText + (QString::number(libspoton_registered_kernel_pid(&libspotonHandle))); + + if(isKernelActive()) + { + QColor color(144, 238, 144); // Light green! + QPalette palette(m_ui.pid->palette()); + + palette.setColor(m_ui.pid->backgroundRole(), color); + m_ui.pid->setPalette(palette); + } + else + m_ui.pid->setPalette(pidPalette); + } + else + m_ui.pid->setPalette(pidPalette); + + libspoton_close(&libspotonHandle); + highlightKernelPath(); + + if(text != m_ui.pid->text()) + { + m_countriesLastModificationTime = QDateTime(); + m_listenersLastModificationTime = QDateTime(); + m_neighborsLastModificationTime = QDateTime(); + m_participantsLastModificationTime = QDateTime(); + } + + if(text != "0") + if(m_kernelSocket.state() == QAbstractSocket::UnconnectedState) + { + { + QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", "spoton"); + + db.setDatabaseName(spoton_misc::homePath() + QDir::separator() + + "kernel.db"); + + if(db.open()) + { + QSqlQuery query(db); + + query.setForwardOnly(true); + + if(query.exec("SELECT port FROM kernel_gui_server")) + if(query.next()) + { + m_kernelSocket.connectToHost("127.0.0.1", + query.value(0).toInt()); + + /* + ** If the kernel is not responsive, terminate it. + */ + + if(!m_kernelSocket.waitForConnected(10000)) + slotDeactivateKernel(); + } + } + + db.close(); + } + + QSqlDatabase::removeDatabase("spoton"); + } + + slotKernelSocketState(); +} + +void spoton::slotSelectKernelPath(void) +{ + QFileDialog dialog(this); + + dialog.setFilter(QDir::AllDirs | QDir::Files +#if defined Q_OS_LINUX || defined Q_OS_MAC || defined Q_OS_UNIX + | QDir::Readable | QDir::Executable); +#else + ); +#endif + dialog.setWindowTitle + (tr("Spot-On: Select Kernel Path")); + dialog.setFileMode(QFileDialog::ExistingFile); + dialog.setDirectory(QDir::homePath()); + dialog.setLabelText(QFileDialog::Accept, tr("&Select")); + dialog.setAcceptMode(QFileDialog::AcceptOpen); +#ifdef Q_OS_MAC +#if QT_VERSION < 0x050000 + dialog.setAttribute(Qt::WA_MacMetalStyle, false); +#endif +#endif + + if(dialog.exec() == QDialog::Accepted) + saveKernelPath(dialog.selectedFiles().value(0).trimmed()); +} + +void spoton::slotSaveKernelPath(void) +{ + saveKernelPath(m_ui.kernelPath->text().trimmed()); +} + +void spoton::saveKernelPath(const QString &path) +{ + if(!path.isEmpty()) + { + m_settings["gui/kernelPath"] = path; + + QSettings settings; + + settings.setValue("gui/kernelPath", path); + m_ui.kernelPath->setText(path); + m_ui.kernelPath->setToolTip(path); + m_ui.kernelPath->selectAll(); + } +} + +void spoton::saveSettings(void) +{ + QSettings settings; + + if(spoton_misc::isGnome()) + settings.setValue("gui/geometry", geometry()); + else + settings.setValue("gui/geometry", saveGeometry()); + + settings.setValue("gui/chatHorizontalSplitter", + m_ui.chatHorizontalSplitter->saveState()); + settings.setValue("gui/currentTabIndex", m_ui.tab->currentIndex()); + settings.setValue("gui/listenersHorizontalSplitter", + m_ui.listenersHorizontalSplitter->saveState()); + settings.setValue("gui/neighborsVerticalSplitter", + m_ui.neighborsVerticalSplitter->saveState()); + settings.setValue("gui/readVerticalSplitter", + m_ui.readVerticalSplitter->saveState()); + settings.setValue("gui/urlsVerticalSplitter", + m_ui.urlsVerticalSplitter->saveState()); +} + +void spoton::closeEvent(QCloseEvent *event) +{ + saveSettings(); + QMainWindow::closeEvent(event); + QApplication::instance()->quit(); +} + +void spoton::slotDeleteListener(void) +{ + QString oid(""); + int row = -1; + + if((row = m_ui.listeners->currentRow()) >= 0) + { + QTableWidgetItem *item = m_ui.listeners->item + (row, m_ui.listeners->columnCount() - 1); // OID + + if(item) + oid = item->text(); + } + + { + QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", "spoton"); + + db.setDatabaseName(spoton_misc::homePath() + QDir::separator() + + "listeners.db"); + + if(db.open()) + { + QSqlQuery query(db); + + if(!isKernelActive()) + query.prepare("DELETE FROM listeners WHERE " + "OID = ?"); + else + query.prepare("UPDATE listeners SET status_control = 'deleted' " + "WHERE " + "OID = ?"); + + query.bindValue(0, oid); + query.exec(); + } + + db.close(); + } + + QSqlDatabase::removeDatabase("spoton"); + + if(row > -1) + m_ui.listeners->removeRow(row); +} + +void spoton::slotDeleteNeighbor(void) +{ + QString oid(""); + int row = -1; + + if((row = m_ui.neighbors->currentRow()) >= 0) + { + QTableWidgetItem *item = m_ui.neighbors->item + (row, m_ui.neighbors->columnCount() - 1); // OID + + if(item) + oid = item->text(); + } + + { + QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", "spoton"); + + db.setDatabaseName(spoton_misc::homePath() + QDir::separator() + + "neighbors.db"); + + if(db.open()) + { + QSqlQuery query(db); + + if(!isKernelActive()) + query.prepare("DELETE FROM neighbors WHERE " + "OID = ?"); + else + query.prepare("UPDATE neighbors SET status_control = 'deleted' " + "WHERE OID = ?"); + + query.bindValue(0, oid); + query.exec(); + } + + db.close(); + } + + QSqlDatabase::removeDatabase("spoton"); + + if(row > -1) + m_ui.neighbors->removeRow(row); +} + +void spoton::slotListenerCheckChange(int state) +{ + QCheckBox *checkBox = qobject_cast<QCheckBox *> (sender()); + + if(checkBox) + { + { + QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", "spoton"); + + db.setDatabaseName(spoton_misc::homePath() + QDir::separator() + + "listeners.db"); + + if(db.open()) + { + QSqlQuery query(db); + + query.prepare("UPDATE listeners SET " + "status_control = ? " + "WHERE OID = ?"); + + if(state) + query.bindValue(0, "online"); + else + query.bindValue(0, "offline"); + + query.bindValue(1, checkBox->property("oid")); + query.exec(); + } + + db.close(); + } + + QSqlDatabase::removeDatabase("spoton"); + } +} + +void spoton::updateListenersTable(QSqlDatabase &db) +{ + if(!isKernelActive()) + if(db.isOpen()) + { + QSqlQuery query(db); + + /* + ** OK, so the kernel is inactive. Discover the + ** listeners that have not been deleted and update some of their + ** information. + */ + + query.exec("PRAGMA synchronous = OFF"); + query.exec("DELETE FROM listeners WHERE " + "status_control = 'deleted'"); + query.exec("UPDATE listeners SET connections = 0, " + "external_ip_address = NULL, " + "status = 'offline' WHERE " + "(status = 'online' OR connections > 0) AND " + "status_control <> 'deleted'"); + } +} + +void spoton::updateNeighborsTable(QSqlDatabase &db) +{ + if(m_ui.keepOnlyUserDefinedNeighbors->isChecked()) + if(db.isOpen()) + { + /* + ** Delete random, disconnected peers. + */ + + QSqlQuery query(db); + + query.exec("PRAGMA synchronous = OFF"); + query.exec("DELETE FROM neighbors WHERE " + "status <> 'connected' AND " + "status_control <> 'blocked' AND " + "user_defined = 0"); + } + + if(!isKernelActive()) + if(db.isOpen()) + { + QSqlQuery query(db); + + /* + ** OK, so the kernel is inactive. Discover the + ** neighbors that have not been deleted and not disconnected + ** and update some of their information. + */ + + query.exec("PRAGMA synchronous = OFF"); + query.exec("DELETE FROM neighbors WHERE " + "status_control = 'deleted'"); + query.exec("UPDATE neighbors SET external_ip_address = NULL, " + "local_ip_address = NULL, " + "local_port = NULL, status = 'disconnected' WHERE " + "(local_ip_address IS NOT NULL OR local_port IS NOT NULL " + "OR status <> 'disconnected') AND " + "status_control <> 'deleted'"); + } +} + +void spoton::updateParticipantsTable(QSqlDatabase &db) +{ + if(!isKernelActive()) + if(db.isOpen()) + { + QSqlQuery query(db); + + /* + ** OK, so the kernel is inactive. All participants are offline. + */ + + query.exec("PRAGMA synchronous = OFF"); + query.exec("UPDATE symmetric_keys SET status = 'offline' WHERE " + "status <> 'offline'"); + } +} + +void spoton::slotSetPassphrase(void) +{ + bool reencode = false; + QString str1(m_ui.passphrase1->text()); + QString str2(m_ui.passphrase2->text()); + + if(str1.length() < 16 || str2.length() < 16) + { + QMessageBox::critical(this, tr("Spot-On: Error"), + tr("The passphrases must contain at least " + "sixteen characters each.")); + m_ui.passphrase1->selectAll(); + m_ui.passphrase1->setFocus(); + return; + } + else if(str1 != str2) + { + QMessageBox::critical(this, tr("Spot-On: Error"), + tr("The passphrases are not equal.")); + m_ui.passphrase1->selectAll(); + m_ui.passphrase1->setFocus(); + return; + } + + if(spoton_gcrypt::passphraseSet()) + { + QMessageBox mb(this); + +#ifdef Q_OS_MAC +#if QT_VERSION < 0x050000 + mb.setAttribute(Qt::WA_MacMetalStyle, true); +#endif +#endif + mb.setIcon(QMessageBox::Question); + mb.setWindowTitle(tr("Spot-On: Confirmation")); + mb.setWindowModality(Qt::WindowModal); + mb.setStandardButtons(QMessageBox::No | QMessageBox::Yes); + mb.setText(tr("Are you sure that you wish to replace the " + "existing passphrase? Please note that URL data must " + "be re-encoded via a separate tool. Please see " + "the Tools folder.")); + + if(mb.exec() != QMessageBox::Yes) + { + m_ui.passphrase1->setText("0000000000"); + m_ui.passphrase2->setText("0000000000"); + return; + } + else + reencode = true; + } + + /* + ** Create the RSA public and private keys. + */ + + m_sb.status->setText + (tr("Generating a derived key. Please be patient.")); + QApplication::processEvents(); + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + + /* + ** Generate a key and use the key to encrypt the private RSA key. + */ + + QByteArray salt; + QByteArray saltedPassphraseHash; + QString error1(""); + QString error2(""); + QString error3(""); + + salt.resize(m_ui.saltLength->value()); + salt = spoton_gcrypt::strongRandomBytes(salt.length()); + + QByteArray derivedKey + (spoton_gcrypt::derivedKey(m_ui.cipherType->currentText(), + m_ui.hashType->currentText(), + static_cast<unsigned long> (m_ui. + iterationCount-> + value()), + str1, + salt, + error1)); + + m_sb.status->clear(); + + if(error1.isEmpty()) + { + slotDeactivateKernel(); + + if(!m_ui.newRSAKeys->isChecked() && reencode) + { + m_sb.status->setText + (tr("Re-encoding RSA key pair 1 of 2. Please be patient.")); + m_sb.status->repaint(); + spoton_gcrypt::reencodeRSAKeys + (m_ui.cipherType->currentText(), + derivedKey, + m_settings.value("gui/cipherType", "aes256"). + toString().trimmed(), + m_crypt->symmetricKey(), + "messaging", + error2); + m_sb.status->clear(); + + if(error2.isEmpty()) + { + m_sb.status->setText + (tr("Re-encoding RSA key pair 2 of 2. Please be patient.")); + m_sb.status->repaint(); + spoton_gcrypt::reencodeRSAKeys + (m_ui.cipherType->currentText(), + derivedKey, + m_settings.value("gui/cipherType", "aes256"). + toString().trimmed(), + m_crypt->symmetricKey(), + "url", + error2); + m_sb.status->clear(); + } + } + else + { + QStringList list; + + list << "messaging" + << "url"; + + for(int i = 0; i < list.size(); i++) + { + m_sb.status->setText + (tr("Generating RSA key pair %1 of %2. Please be patient."). + arg(i + 1).arg(list.size())); + m_sb.status->repaint(); + + spoton_gcrypt crypt + (m_ui.cipherType->currentText(), + m_ui.hashType->currentText(), + str1.toUtf8(), + derivedKey, + m_ui.saltLength->value(), + m_ui.iterationCount->value(), + list.at(i)); + + crypt.generatePrivatePublicKeys + (m_ui.rsaKeySize->currentText().toInt(), error2); + m_sb.status->clear(); + + if(!error2.isEmpty()) + break; + } + } + } + + if(error1.isEmpty() && error2.isEmpty()) + saltedPassphraseHash = spoton_gcrypt::saltedPassphraseHash + (m_ui.hashType->currentText(), str1, salt, error3); + + QApplication::restoreOverrideCursor(); + + if(!error1.isEmpty()) + QMessageBox::critical(this, tr("Spot-On: Error"), + tr("An error (%1) occurred with spoton_gcrypt::" + "derivedKey().").arg(error1.remove("."))); + else if(!error2.isEmpty()) + QMessageBox::critical(this, tr("Spot-On: Error"), + tr("An error (%1) occurred with " + "spoton_gcrypt::" + "generatePrivatePublicKeys() or " + "spoton_gcrypt::" + "reencodeRSAKeys()."). + arg(error2.remove("."))); + else if(!error3.isEmpty()) + QMessageBox::critical(this, tr("Spot-On: Error"), + tr("An error (%1) occurred with spoton_gcrypt::" + "saltedPassphraseHash()."). + arg(error3.remove("."))); + else + { + if(!m_crypt || reencode) + { + if(reencode) + { + spoton_gcrypt *crypt = new spoton_gcrypt + (m_ui.cipherType->currentText(), + m_ui.hashType->currentText(), + str1.toUtf8(), + derivedKey, + m_ui.saltLength->value(), + m_ui.iterationCount->value(), + "messaging"); + + spoton_reencode reencode; + + m_tableTimer.stop(); + reencode.reencode(m_sb, crypt, m_crypt); + delete crypt; + m_tableTimer.start(); + } + + delete m_crypt; + m_crypt = new spoton_gcrypt + (m_ui.cipherType->currentText(), + m_ui.hashType->currentText(), + str1.toUtf8(), + derivedKey, + m_ui.saltLength->value(), + m_ui.iterationCount->value(), + "messaging"); + + if(!reencode) + { + m_sb.status->setText + (tr("Initializing country_inclusion.db.")); + m_sb.status->repaint(); + QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + spoton_misc::populateCountryDatabase(m_crypt); + QApplication::restoreOverrideCursor(); + m_sb.status->clear(); + } + + if(!m_tableTimer.isActive()) + m_tableTimer.start(); + + sendKeysToKernel(); + } + + m_sb.kernelstatus->setEnabled(true); + m_sb.listeners->setEnabled(true); + m_sb.neighbors->setEnabled(true); + m_ui.kernelBox->setEnabled(true); + m_ui.listenersBox->setEnabled(true); + m_ui.newRSAKeys->setChecked(false); + m_ui.newRSAKeys->setEnabled(true); + m_ui.passphrase1->setText("0000000000"); + m_ui.passphrase2->setText("0000000000"); + m_ui.rsaKeySize->setEnabled(false); + + for(int i = 0; i < m_ui.tab->count(); i++) + m_ui.tab->setTabEnabled(i, true); + + /* + ** Save the various entities. + */ + + m_settings["gui/cipherType"] = m_ui.cipherType->currentText(); + m_settings["gui/hashType"] = m_ui.hashType->currentText(); + m_settings["gui/iterationCount"] = m_ui.iterationCount->value(); + m_settings["gui/rsaKeySize"] = m_ui.rsaKeySize->currentText().toInt(); + m_settings["gui/salt"] = salt.toHex(); + m_settings["gui/saltLength"] = m_ui.saltLength->value(); + m_settings["gui/saltedPassphraseHash"] = saltedPassphraseHash.toHex(); + + QSettings settings; + + settings.setValue("gui/cipherType", m_settings["gui/cipherType"]); + settings.setValue("gui/hashType", m_settings["gui/hashType"]); + settings.setValue("gui/iterationCount", + m_settings["gui/iterationCount"]); + settings.setValue("gui/rsaKeySize", m_settings["gui/rsaKeySize"]); + settings.setValue("gui/salt", m_settings["gui/salt"]); + settings.setValue("gui/saltLength", m_settings["gui/saltLength"]); + settings.setValue + ("gui/saltedPassphraseHash", m_settings["gui/saltedPassphraseHash"]); + + QMessageBox::information + (this, tr("Spot-On: Information"), + tr("Your RSA keys and the passphrase have been recorded. " + "You are now ready to use the full power of Spot-On. Enjoy!")); + + QMessageBox mb(this); + +#ifdef Q_OS_MAC +#if QT_VERSION < 0x050000 + mb.setAttribute(Qt::WA_MacMetalStyle, true); +#endif +#endif + mb.setIcon(QM... [truncated message content] |
From: <tex...@us...> - 2013-06-16 23:39:34
|
Revision: 1309 http://sourceforge.net/p/spot-on/code/1309 Author: textfield Date: 2013-06-16 23:39:28 +0000 (Sun, 16 Jun 2013) Log Message: ----------- Some UTF-8 corrections. Modified Paths: -------------- branches/0.x/GUI/spot-on.cc Modified: branches/0.x/GUI/spot-on.cc =================================================================== --- branches/0.x/GUI/spot-on.cc 2013-06-16 16:51:24 UTC (rev 1308) +++ branches/0.x/GUI/spot-on.cc 2013-06-16 23:39:28 UTC (rev 1309) @@ -4396,6 +4396,7 @@ { m_ui.participantsCombo->setCurrentIndex(0); m_ui.outgoingMessage->clear(); + m_ui.outgoingMessage->setCurrentCharFormat(QTextCharFormat()); m_ui.outgoingSubject->clear(); m_ui.goldbug->clear(); m_ui.outgoingSubject->setFocus(); @@ -4947,7 +4948,7 @@ if(i == 0 || i == 1 || i == 2 || i == 3 || i == 5 || i == 6) { - if(i == 2) + if(i == 1 || i == 2 || i == 3 || i == 5) item = new QTableWidgetItem (QString:: fromUtf8(m_crypt-> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <tex...@us...> - 2013-06-16 23:39:33
|
Revision: 1309 http://sourceforge.net/p/spot-on/code/1309 Author: textfield Date: 2013-06-16 23:39:28 +0000 (Sun, 16 Jun 2013) Log Message: ----------- Some UTF-8 corrections. Modified Paths: -------------- branches/0.x/GUI/spot-on.cc Modified: branches/0.x/GUI/spot-on.cc =================================================================== --- branches/0.x/GUI/spot-on.cc 2013-06-16 16:51:24 UTC (rev 1308) +++ branches/0.x/GUI/spot-on.cc 2013-06-16 23:39:28 UTC (rev 1309) @@ -4396,6 +4396,7 @@ { m_ui.participantsCombo->setCurrentIndex(0); m_ui.outgoingMessage->clear(); + m_ui.outgoingMessage->setCurrentCharFormat(QTextCharFormat()); m_ui.outgoingSubject->clear(); m_ui.goldbug->clear(); m_ui.outgoingSubject->setFocus(); @@ -4947,7 +4948,7 @@ if(i == 0 || i == 1 || i == 2 || i == 3 || i == 5 || i == 6) { - if(i == 2) + if(i == 1 || i == 2 || i == 3 || i == 5) item = new QTableWidgetItem (QString:: fromUtf8(m_crypt-> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <tex...@us...> - 2013-06-16 16:51:29
|
Revision: 1308 http://sourceforge.net/p/spot-on/code/1308 Author: textfield Date: 2013-06-16 16:51:24 +0000 (Sun, 16 Jun 2013) Log Message: ----------- Include Windows file for Qt 5. Modified Paths: -------------- branches/0.x/Kernel/spot-on-kernel.cc Modified: branches/0.x/Kernel/spot-on-kernel.cc =================================================================== --- branches/0.x/Kernel/spot-on-kernel.cc 2013-06-16 16:47:59 UTC (rev 1307) +++ branches/0.x/Kernel/spot-on-kernel.cc 2013-06-16 16:51:24 UTC (rev 1308) @@ -50,7 +50,9 @@ #include <termios.h> #include <unistd.h> #else +#if QT_VERSION >= 0x050000 #include <winsock2.h> +#endif #include <windows.h> #endif } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <tex...@us...> - 2013-06-16 16:51:27
|
Revision: 1308 http://sourceforge.net/p/spot-on/code/1308 Author: textfield Date: 2013-06-16 16:51:24 +0000 (Sun, 16 Jun 2013) Log Message: ----------- Include Windows file for Qt 5. Modified Paths: -------------- branches/0.x/Kernel/spot-on-kernel.cc Modified: branches/0.x/Kernel/spot-on-kernel.cc =================================================================== --- branches/0.x/Kernel/spot-on-kernel.cc 2013-06-16 16:47:59 UTC (rev 1307) +++ branches/0.x/Kernel/spot-on-kernel.cc 2013-06-16 16:51:24 UTC (rev 1308) @@ -50,7 +50,9 @@ #include <termios.h> #include <unistd.h> #else +#if QT_VERSION >= 0x050000 #include <winsock2.h> +#endif #include <windows.h> #endif } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <tex...@us...> - 2013-06-16 16:48:06
|
Revision: 1307 http://sourceforge.net/p/spot-on/code/1307 Author: textfield Date: 2013-06-16 16:47:59 +0000 (Sun, 16 Jun 2013) Log Message: ----------- A workaround for proxies. Modified Paths: -------------- branches/0.x/Kernel/spot-on-neighbor.cc branches/0.x/Kernel/spot-on-neighbor.h Modified: branches/0.x/Kernel/spot-on-neighbor.cc =================================================================== --- branches/0.x/Kernel/spot-on-neighbor.cc 2013-06-16 15:11:03 UTC (rev 1306) +++ branches/0.x/Kernel/spot-on-neighbor.cc 2013-06-16 16:47:59 UTC (rev 1307) @@ -48,6 +48,7 @@ s_dbId += 1; setSocketDescriptor(socketDescriptor); m_address = peerAddress(); + m_ipAddress = m_address.toString(); m_externalAddress = new spoton_external_address(this); m_id = std::numeric_limits<qint64>::min(); m_lastReadTime = QDateTime::currentDateTime(); @@ -104,10 +105,11 @@ s_dbId += 1; setProxy(proxy); m_address = QHostAddress(ipAddress); + m_ipAddress = ipAddress; if(m_address.isNull()) - if(!ipAddress.isEmpty()) - QHostInfo::lookupHost(ipAddress, + if(!m_ipAddress.isEmpty()) + QHostInfo::lookupHost(m_ipAddress, this, SLOT(slotHostFound(const QHostInfo &))); m_address.setScopeId(scopeId); @@ -470,6 +472,22 @@ void spoton_neighbor::slotConnected(void) { + if(proxy().type() != QNetworkProxy::NoProxy) + { + /* + ** The local address is the address of the proxy. Unfortunately, + ** we do not have network interfaces that have such an address. Hence, + ** m_networkInterface will always be zero. + */ + + QHostAddress address(m_ipAddress); + + if(address.protocol() == QAbstractSocket::IPv4Protocol) + setLocalAddress(QHostAddress("127.0.0.1")); + else + setLocalAddress(QHostAddress("::1")); + } + m_keepAliveTimer.start(); m_lastReadTime = QDateTime::currentDateTime(); @@ -2298,6 +2316,7 @@ if(!address.isNull()) { m_address = address; + m_ipAddress = m_address.toString(); break; } } Modified: branches/0.x/Kernel/spot-on-neighbor.h =================================================================== --- branches/0.x/Kernel/spot-on-neighbor.h 2013-06-16 15:11:03 UTC (rev 1306) +++ branches/0.x/Kernel/spot-on-neighbor.h 2013-06-16 16:47:59 UTC (rev 1307) @@ -69,6 +69,7 @@ QDateTime m_lastReadTime; QHostAddress m_address; QNetworkInterface *m_networkInterface; + QString m_ipAddress; QTimer m_externalAddressDiscovererTimer; QTimer m_keepAliveTimer; QTimer m_lifetime; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <tex...@us...> - 2013-06-16 16:48:03
|
Revision: 1307 http://sourceforge.net/p/spot-on/code/1307 Author: textfield Date: 2013-06-16 16:47:59 +0000 (Sun, 16 Jun 2013) Log Message: ----------- A workaround for proxies. Modified Paths: -------------- branches/0.x/Kernel/spot-on-neighbor.cc branches/0.x/Kernel/spot-on-neighbor.h Modified: branches/0.x/Kernel/spot-on-neighbor.cc =================================================================== --- branches/0.x/Kernel/spot-on-neighbor.cc 2013-06-16 15:11:03 UTC (rev 1306) +++ branches/0.x/Kernel/spot-on-neighbor.cc 2013-06-16 16:47:59 UTC (rev 1307) @@ -48,6 +48,7 @@ s_dbId += 1; setSocketDescriptor(socketDescriptor); m_address = peerAddress(); + m_ipAddress = m_address.toString(); m_externalAddress = new spoton_external_address(this); m_id = std::numeric_limits<qint64>::min(); m_lastReadTime = QDateTime::currentDateTime(); @@ -104,10 +105,11 @@ s_dbId += 1; setProxy(proxy); m_address = QHostAddress(ipAddress); + m_ipAddress = ipAddress; if(m_address.isNull()) - if(!ipAddress.isEmpty()) - QHostInfo::lookupHost(ipAddress, + if(!m_ipAddress.isEmpty()) + QHostInfo::lookupHost(m_ipAddress, this, SLOT(slotHostFound(const QHostInfo &))); m_address.setScopeId(scopeId); @@ -470,6 +472,22 @@ void spoton_neighbor::slotConnected(void) { + if(proxy().type() != QNetworkProxy::NoProxy) + { + /* + ** The local address is the address of the proxy. Unfortunately, + ** we do not have network interfaces that have such an address. Hence, + ** m_networkInterface will always be zero. + */ + + QHostAddress address(m_ipAddress); + + if(address.protocol() == QAbstractSocket::IPv4Protocol) + setLocalAddress(QHostAddress("127.0.0.1")); + else + setLocalAddress(QHostAddress("::1")); + } + m_keepAliveTimer.start(); m_lastReadTime = QDateTime::currentDateTime(); @@ -2298,6 +2316,7 @@ if(!address.isNull()) { m_address = address; + m_ipAddress = m_address.toString(); break; } } Modified: branches/0.x/Kernel/spot-on-neighbor.h =================================================================== --- branches/0.x/Kernel/spot-on-neighbor.h 2013-06-16 15:11:03 UTC (rev 1306) +++ branches/0.x/Kernel/spot-on-neighbor.h 2013-06-16 16:47:59 UTC (rev 1307) @@ -69,6 +69,7 @@ QDateTime m_lastReadTime; QHostAddress m_address; QNetworkInterface *m_networkInterface; + QString m_ipAddress; QTimer m_externalAddressDiscovererTimer; QTimer m_keepAliveTimer; QTimer m_lifetime; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <tex...@us...> - 2013-06-16 15:11:08
|
Revision: 1306 http://sourceforge.net/p/spot-on/code/1306 Author: textfield Date: 2013-06-16 15:11:03 +0000 (Sun, 16 Jun 2013) Log Message: ----------- A Windows include. Set the proxy before attempting to find the address. Modified Paths: -------------- branches/0.x/Kernel/spot-on-kernel.cc branches/0.x/Kernel/spot-on-neighbor.cc Modified: branches/0.x/Kernel/spot-on-kernel.cc =================================================================== --- branches/0.x/Kernel/spot-on-kernel.cc 2013-06-16 14:34:30 UTC (rev 1305) +++ branches/0.x/Kernel/spot-on-kernel.cc 2013-06-16 15:11:03 UTC (rev 1306) @@ -50,6 +50,7 @@ #include <termios.h> #include <unistd.h> #else +#include <winsock2.h> #include <windows.h> #endif } Modified: branches/0.x/Kernel/spot-on-neighbor.cc =================================================================== --- branches/0.x/Kernel/spot-on-neighbor.cc 2013-06-16 14:34:30 UTC (rev 1305) +++ branches/0.x/Kernel/spot-on-neighbor.cc 2013-06-16 15:11:03 UTC (rev 1306) @@ -102,6 +102,7 @@ QObject *parent):QTcpSocket(parent) { s_dbId += 1; + setProxy(proxy); m_address = QHostAddress(ipAddress); if(m_address.isNull()) @@ -115,7 +116,6 @@ m_lastReadTime = QDateTime::currentDateTime(); m_networkInterface = 0; m_port = quint16(port.toInt()); - setProxy(proxy); setReadBufferSize(8192); setSocketOption(QAbstractSocket::KeepAliveOption, 1); connect(this, This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <tex...@us...> - 2013-06-16 15:11:06
|
Revision: 1306 http://sourceforge.net/p/spot-on/code/1306 Author: textfield Date: 2013-06-16 15:11:03 +0000 (Sun, 16 Jun 2013) Log Message: ----------- A Windows include. Set the proxy before attempting to find the address. Modified Paths: -------------- branches/0.x/Kernel/spot-on-kernel.cc branches/0.x/Kernel/spot-on-neighbor.cc Modified: branches/0.x/Kernel/spot-on-kernel.cc =================================================================== --- branches/0.x/Kernel/spot-on-kernel.cc 2013-06-16 14:34:30 UTC (rev 1305) +++ branches/0.x/Kernel/spot-on-kernel.cc 2013-06-16 15:11:03 UTC (rev 1306) @@ -50,6 +50,7 @@ #include <termios.h> #include <unistd.h> #else +#include <winsock2.h> #include <windows.h> #endif } Modified: branches/0.x/Kernel/spot-on-neighbor.cc =================================================================== --- branches/0.x/Kernel/spot-on-neighbor.cc 2013-06-16 14:34:30 UTC (rev 1305) +++ branches/0.x/Kernel/spot-on-neighbor.cc 2013-06-16 15:11:03 UTC (rev 1306) @@ -102,6 +102,7 @@ QObject *parent):QTcpSocket(parent) { s_dbId += 1; + setProxy(proxy); m_address = QHostAddress(ipAddress); if(m_address.isNull()) @@ -115,7 +116,6 @@ m_lastReadTime = QDateTime::currentDateTime(); m_networkInterface = 0; m_port = quint16(port.toInt()); - setProxy(proxy); setReadBufferSize(8192); setSocketOption(QAbstractSocket::KeepAliveOption, 1); connect(this, This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <tex...@us...> - 2013-06-16 14:34:35
|
Revision: 1305 http://sourceforge.net/p/spot-on/code/1305 Author: textfield Date: 2013-06-16 14:34:30 +0000 (Sun, 16 Jun 2013) Log Message: ----------- Select the correct sender. Set a default font on the reply letter. Modified Paths: -------------- branches/0.x/GUI/spot-on.cc Modified: branches/0.x/GUI/spot-on.cc =================================================================== --- branches/0.x/GUI/spot-on.cc 2013-06-16 14:21:54 UTC (rev 1304) +++ branches/0.x/GUI/spot-on.cc 2013-06-16 14:34:30 UTC (rev 1305) @@ -5956,8 +5956,8 @@ QString subject(item->text()); - m_ui.outgoingMessage->append("<br>"); - m_ui.outgoingMessage->append(message); + message = "<br><span style=\"font-size:large;\">" + message + "</span>"; + m_ui.outgoingMessage->setHtml(message); m_ui.outgoingSubject->setText(tr("Re: ") + subject); m_ui.mailTab->setCurrentIndex(1); @@ -5969,7 +5969,7 @@ for(int i = 2; i < m_ui.participantsCombo->count(); i++) if(m_ui.participantsCombo-> - itemData(i, Qt::UserRole).toString() == receiverSenderHash) + itemData(i, Qt::UserRole + 1).toString() == receiverSenderHash) { m_ui.participantsCombo->setCurrentIndex(i); break; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <tex...@us...> - 2013-06-16 14:34:33
|
Revision: 1305 http://sourceforge.net/p/spot-on/code/1305 Author: textfield Date: 2013-06-16 14:34:30 +0000 (Sun, 16 Jun 2013) Log Message: ----------- Select the correct sender. Set a default font on the reply letter. Modified Paths: -------------- branches/0.x/GUI/spot-on.cc Modified: branches/0.x/GUI/spot-on.cc =================================================================== --- branches/0.x/GUI/spot-on.cc 2013-06-16 14:21:54 UTC (rev 1304) +++ branches/0.x/GUI/spot-on.cc 2013-06-16 14:34:30 UTC (rev 1305) @@ -5956,8 +5956,8 @@ QString subject(item->text()); - m_ui.outgoingMessage->append("<br>"); - m_ui.outgoingMessage->append(message); + message = "<br><span style=\"font-size:large;\">" + message + "</span>"; + m_ui.outgoingMessage->setHtml(message); m_ui.outgoingSubject->setText(tr("Re: ") + subject); m_ui.mailTab->setCurrentIndex(1); @@ -5969,7 +5969,7 @@ for(int i = 2; i < m_ui.participantsCombo->count(); i++) if(m_ui.participantsCombo-> - itemData(i, Qt::UserRole).toString() == receiverSenderHash) + itemData(i, Qt::UserRole + 1).toString() == receiverSenderHash) { m_ui.participantsCombo->setCurrentIndex(i); break; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <tex...@us...> - 2013-06-16 14:21:59
|
Revision: 1304 http://sourceforge.net/p/spot-on/code/1304 Author: textfield Date: 2013-06-16 14:21:54 +0000 (Sun, 16 Jun 2013) Log Message: ----------- Comments. Use a keyed hash to determine if incoming messages are duplicates if m_crypt is available. Modified Paths: -------------- branches/0.x/Common/spot-on-misc.cc branches/0.x/Documentation/PROTOCOLS branches/0.x/GUI/spot-on.cc Modified: branches/0.x/Common/spot-on-misc.cc =================================================================== --- branches/0.x/Common/spot-on-misc.cc 2013-06-16 03:14:18 UTC (rev 1303) +++ branches/0.x/Common/spot-on-misc.cc 2013-06-16 14:21:54 UTC (rev 1304) @@ -163,7 +163,12 @@ "key_type TEXT NOT NULL DEFAULT 'messaging', " "name TEXT NOT NULL DEFAULT 'unknown', " "public_key TEXT NOT NULL, " - "public_key_hash TEXT PRIMARY KEY NOT NULL, " + "public_key_hash TEXT PRIMARY KEY NOT NULL, " /* + ** Sha-512 + ** hash of + ** the public + ** key. + */ /* ** Why do we need the neighbor's OID? ** When a neighbor shares a public key, we need Modified: branches/0.x/Documentation/PROTOCOLS =================================================================== --- branches/0.x/Documentation/PROTOCOLS 2013-06-16 03:14:18 UTC (rev 1303) +++ branches/0.x/Documentation/PROTOCOLS 2013-06-16 14:21:54 UTC (rev 1304) @@ -7,7 +7,7 @@ TTL (Plaintext) 0 - Message (Base-64) (Gemini) EOL -1 - Message Digest (Base-64) (Gemini) +1 - Keyed Sha-512 Message Digest (Base-64) (Gemini) Message Type ("0000") (Plaintext) TTL (Plaintext) @@ -21,7 +21,7 @@ EOL 4 - Message (Ciphertext, SK) EOL -5 - Message Digest (Base-64) (Ciphertext, SK) +5 - Keyed Sha-512 Message Digest (Base-64) (Ciphertext, SK) Echo Mail Echoed? Yes @@ -48,7 +48,7 @@ EOL 9 - Message (Base-64) (Ciphertext, SK) EOL -10 - Message Digest (Base-64) (Ciphertext, SK) +10 - Keyed Sha-512 Message Digest (Base-64) (Ciphertext, SK) Message Type ("0001b") (Plaintext) TTL (Plaintext) @@ -64,7 +64,7 @@ EOL 5 - Message (Base-64) (Ciphertext, SK) EOL -6 - Message Digest (Base-64) (Ciphertext, SK) +6 - Keyed Sha-512 Message Digest (Base-64) (Ciphertext, SK) Retrieve Mail Echoed? Yes @@ -79,7 +79,7 @@ EOL 3 - Requester's Signature (Base-64) (Ciphertext, SK) EOL -4 - Message Digest (Base-64) (Ciphertext, SK) +4 - Keyed Sha-512 Message Digest (Base-64) (Ciphertext, SK) Key Exchange Echoed? No @@ -101,7 +101,7 @@ TTL (Plaintext) 0 - Message (Base-64) (Gemini) EOL -1 - Message Digest (Base-64) (Gemini) +1 - Keyed Sha-512 Message Digest (Base-64) (Gemini) Message Type ("0013") (Plaintext) TTL (Plaintext) @@ -115,7 +115,7 @@ EOL 4 - Status (Base-64) (Ciphertext, SK) EOL -5 - Message Digest (Base-64) (Ciphertext, SK) +5 - Keyed Sha-512 Message Digest (Base-64) (Ciphertext, SK) UUID Exchange Echoed? No @@ -144,4 +144,4 @@ EOL 11 - URL-10 (Base-64) (Ciphertext, SK) EOL -12 - Message Digest (Base-64) (Ciphertext, SK) +12 - Keyed Sha-512 Message Digest (Base-64) (Ciphertext, SK) Modified: branches/0.x/GUI/spot-on.cc =================================================================== --- branches/0.x/GUI/spot-on.cc 2013-06-16 03:14:18 UTC (rev 1303) +++ branches/0.x/GUI/spot-on.cc 2013-06-16 14:21:54 UTC (rev 1304) @@ -3144,7 +3144,14 @@ bool duplicate = false; bool ok = true; - hash = spoton_gcrypt::sha512Hash(list.at(0), &ok); + if(m_crypt) + hash = spoton_gcrypt::keyedHash + (list.at(0), + QByteArray(m_crypt->symmetricKey(), + m_crypt->symmetricKeyLength()), + "sha512", &ok); + else + hash = spoton_gcrypt::sha512Hash(list.at(0), &ok); if(m_messagingCache.contains(hash)) duplicate = true; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <tex...@us...> - 2013-06-16 14:21:56
|
Revision: 1304 http://sourceforge.net/p/spot-on/code/1304 Author: textfield Date: 2013-06-16 14:21:54 +0000 (Sun, 16 Jun 2013) Log Message: ----------- Comments. Use a keyed hash to determine if incoming messages are duplicates if m_crypt is available. Modified Paths: -------------- branches/0.x/Common/spot-on-misc.cc branches/0.x/Documentation/PROTOCOLS branches/0.x/GUI/spot-on.cc Modified: branches/0.x/Common/spot-on-misc.cc =================================================================== --- branches/0.x/Common/spot-on-misc.cc 2013-06-16 03:14:18 UTC (rev 1303) +++ branches/0.x/Common/spot-on-misc.cc 2013-06-16 14:21:54 UTC (rev 1304) @@ -163,7 +163,12 @@ "key_type TEXT NOT NULL DEFAULT 'messaging', " "name TEXT NOT NULL DEFAULT 'unknown', " "public_key TEXT NOT NULL, " - "public_key_hash TEXT PRIMARY KEY NOT NULL, " + "public_key_hash TEXT PRIMARY KEY NOT NULL, " /* + ** Sha-512 + ** hash of + ** the public + ** key. + */ /* ** Why do we need the neighbor's OID? ** When a neighbor shares a public key, we need Modified: branches/0.x/Documentation/PROTOCOLS =================================================================== --- branches/0.x/Documentation/PROTOCOLS 2013-06-16 03:14:18 UTC (rev 1303) +++ branches/0.x/Documentation/PROTOCOLS 2013-06-16 14:21:54 UTC (rev 1304) @@ -7,7 +7,7 @@ TTL (Plaintext) 0 - Message (Base-64) (Gemini) EOL -1 - Message Digest (Base-64) (Gemini) +1 - Keyed Sha-512 Message Digest (Base-64) (Gemini) Message Type ("0000") (Plaintext) TTL (Plaintext) @@ -21,7 +21,7 @@ EOL 4 - Message (Ciphertext, SK) EOL -5 - Message Digest (Base-64) (Ciphertext, SK) +5 - Keyed Sha-512 Message Digest (Base-64) (Ciphertext, SK) Echo Mail Echoed? Yes @@ -48,7 +48,7 @@ EOL 9 - Message (Base-64) (Ciphertext, SK) EOL -10 - Message Digest (Base-64) (Ciphertext, SK) +10 - Keyed Sha-512 Message Digest (Base-64) (Ciphertext, SK) Message Type ("0001b") (Plaintext) TTL (Plaintext) @@ -64,7 +64,7 @@ EOL 5 - Message (Base-64) (Ciphertext, SK) EOL -6 - Message Digest (Base-64) (Ciphertext, SK) +6 - Keyed Sha-512 Message Digest (Base-64) (Ciphertext, SK) Retrieve Mail Echoed? Yes @@ -79,7 +79,7 @@ EOL 3 - Requester's Signature (Base-64) (Ciphertext, SK) EOL -4 - Message Digest (Base-64) (Ciphertext, SK) +4 - Keyed Sha-512 Message Digest (Base-64) (Ciphertext, SK) Key Exchange Echoed? No @@ -101,7 +101,7 @@ TTL (Plaintext) 0 - Message (Base-64) (Gemini) EOL -1 - Message Digest (Base-64) (Gemini) +1 - Keyed Sha-512 Message Digest (Base-64) (Gemini) Message Type ("0013") (Plaintext) TTL (Plaintext) @@ -115,7 +115,7 @@ EOL 4 - Status (Base-64) (Ciphertext, SK) EOL -5 - Message Digest (Base-64) (Ciphertext, SK) +5 - Keyed Sha-512 Message Digest (Base-64) (Ciphertext, SK) UUID Exchange Echoed? No @@ -144,4 +144,4 @@ EOL 11 - URL-10 (Base-64) (Ciphertext, SK) EOL -12 - Message Digest (Base-64) (Ciphertext, SK) +12 - Keyed Sha-512 Message Digest (Base-64) (Ciphertext, SK) Modified: branches/0.x/GUI/spot-on.cc =================================================================== --- branches/0.x/GUI/spot-on.cc 2013-06-16 03:14:18 UTC (rev 1303) +++ branches/0.x/GUI/spot-on.cc 2013-06-16 14:21:54 UTC (rev 1304) @@ -3144,7 +3144,14 @@ bool duplicate = false; bool ok = true; - hash = spoton_gcrypt::sha512Hash(list.at(0), &ok); + if(m_crypt) + hash = spoton_gcrypt::keyedHash + (list.at(0), + QByteArray(m_crypt->symmetricKey(), + m_crypt->symmetricKeyLength()), + "sha512", &ok); + else + hash = spoton_gcrypt::sha512Hash(list.at(0), &ok); if(m_messagingCache.contains(hash)) duplicate = true; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <tex...@us...> - 2013-06-16 03:14:23
|
Revision: 1303 http://sourceforge.net/p/spot-on/code/1303 Author: textfield Date: 2013-06-16 03:14:18 +0000 (Sun, 16 Jun 2013) Log Message: ----------- Reply support. Comments. Modified Paths: -------------- branches/0.x/Common/spot-on-misc.cc branches/0.x/GUI/spot-on.cc branches/0.x/GUI/spot-on.h branches/0.x/UI/controlcenter.ui Modified: branches/0.x/Common/spot-on-misc.cc =================================================================== --- branches/0.x/Common/spot-on-misc.cc 2013-06-15 01:50:23 UTC (rev 1302) +++ branches/0.x/Common/spot-on-misc.cc 2013-06-16 03:14:18 UTC (rev 1303) @@ -111,7 +111,10 @@ ** "0" or "1" for inbound. ** Symmetric key for outbound. */ - "hash TEXT NOT NULL, " + "hash TEXT NOT NULL, " /* + ** Hash of the message and + ** the subject. + */ "message BLOB NOT NULL, " "message_digest BLOB, " /* ** Should only be used when @@ -119,14 +122,25 @@ */ "participant_oid TEXT NOT NULL, " "receiver_sender TEXT NOT NULL, " - "receiver_sender_hash TEXT NOT NULL, " - "status TEXT NOT NULL, " + "receiver_sender_hash TEXT NOT NULL, " /* + ** Hash of the + ** receiver's or + ** the sender's + ** public key. + */ + "status TEXT NOT NULL, " /* + ** Deleted, read, etc. + */ "subject BLOB NOT NULL, " "PRIMARY KEY (folder_index, hash, receiver_sender_hash))"); query.exec("CREATE TABLE IF NOT EXISTS post_office (" "date_received TEXT NOT NULL, " "message_bundle BLOB NOT NULL, " - "recipient_hash TEXT NOT NULL)"); + "recipient_hash TEXT NOT NULL)"); /* + ** Hash of the + ** recipient's public + ** key. + */ } db.close(); @@ -233,7 +247,11 @@ "maximum_clients INTEGER NOT NULL DEFAULT 5, " "external_ip_address TEXT, " "external_port TEXT, " - "hash TEXT PRIMARY KEY NOT NULL)"); + "hash TEXT PRIMARY KEY NOT NULL)"); /* + ** The hash of the + ** IP address and + ** the port. + */ } db.close(); @@ -267,7 +285,11 @@ "uuid TEXT NOT NULL DEFAULT " "'{00000000-0000-0000-0000-000000000000}', " "country TEXT, " - "hash TEXT PRIMARY KEY NOT NULL, " + "hash TEXT PRIMARY KEY NOT NULL, " /* + ** Hash of the remote IP + ** address and the remote + ** port. + */ "remote_ip_address_hash TEXT NOT NULL, " "qt_country_hash TEXT, " "user_defined INTEGER NOT NULL DEFAULT 1, " Modified: branches/0.x/GUI/spot-on.cc =================================================================== --- branches/0.x/GUI/spot-on.cc 2013-06-15 01:50:23 UTC (rev 1302) +++ branches/0.x/GUI/spot-on.cc 2013-06-16 03:14:18 UTC (rev 1303) @@ -369,6 +369,10 @@ SIGNAL(valueChanged(int)), this, SLOT(slotDaysChanged(int))); + connect(m_ui.reply, + SIGNAL(clicked(void)), + this, + SLOT(slotReply(void))); connect(&m_generalTimer, SIGNAL(timeout(void)), this, @@ -662,7 +666,8 @@ m_ui.mail->setColumnHidden(4, true); // goldbug m_ui.mail->setColumnHidden(5, true); // message m_ui.mail->setColumnHidden(6, true); // message_digest - m_ui.mail->setColumnHidden(7, true); // OID + m_ui.mail->setColumnHidden(7, true); // receiver_sender_hash + m_ui.mail->setColumnHidden(8, true); // OID m_ui.listeners->setColumnHidden(m_ui.listeners->columnCount() - 1, true); // OID m_ui.neighbors->setColumnHidden @@ -4144,8 +4149,8 @@ if(!(key.startsWith("K") || key.startsWith("k"))) { - QMessageBox::warning - (this, tr("Spot-On: Warning"), + QMessageBox::critical + (this, tr("Spot-On: Error"), tr("Invalid key. The key must start with either the letter " "K or the letter k.")); return; @@ -4170,8 +4175,8 @@ if(!(keyType == "messaging" || keyType == "url")) { - QMessageBox::warning - (this, tr("Spot-On: Warning"), + QMessageBox::critical + (this, tr("Spot-On: Error"), tr("Invalid key type. Expecting 'messaging' or 'url'.")); return; } @@ -4185,8 +4190,8 @@ if(!spoton_gcrypt::isValidSignature(publicKey, publicKey, signature)) { - QMessageBox::warning - (this, tr("Spot-On: Warning"), + QMessageBox::critical + (this, tr("Spot-On: Error"), tr("Invalid signature.")); return; } @@ -4235,8 +4240,8 @@ if(!(repleo.startsWith("R") || repleo.startsWith("r"))) { - QMessageBox::warning - (this, tr("Spot-On: Warning"), + QMessageBox::critical + (this, tr("Spot-On: Error"), tr("Invalid repleo. The repleo must start with " "either the letter R or the letter r.")); return; @@ -4295,8 +4300,8 @@ if(!(keyType == "messaging" || keyType == "url")) { - QMessageBox::warning - (this, tr("Spot-On: Warning"), + QMessageBox::critical + (this, tr("Spot-On: Error"), tr("Invalid key type. Expecting 'messaging' or 'url'.")); return; } @@ -4319,8 +4324,8 @@ if(!spoton_gcrypt::isValidSignature(publicKey, publicKey, signature)) { - QMessageBox::warning - (this, tr("Spot-On: Warning"), + QMessageBox::critical + (this, tr("Spot-On: Error"), tr("Invalid signature.")); return; } @@ -4386,6 +4391,7 @@ m_ui.outgoingMessage->clear(); m_ui.outgoingSubject->clear(); m_ui.goldbug->clear(); + m_ui.outgoingSubject->setFocus(); } } @@ -4633,8 +4639,8 @@ if(message.isEmpty()) { - QMessageBox::warning - (this, tr("Spot-On: Warning"), + QMessageBox::critical + (this, tr("Spot-On: Error"), tr("Please compose an actual letter.")); m_ui.outgoingMessage->setFocus(); return; @@ -4901,6 +4907,7 @@ if(query.exec(QString("SELECT date, receiver_sender, status, " "subject, goldbug, " "message, message_digest, " + "receiver_sender_hash, " "OID FROM folders WHERE " "folder_index = %1"). arg(m_ui.folder->currentIndex()))) @@ -5161,7 +5168,8 @@ { QTableWidgetItem *item = 0; - if((item = m_ui.mail->item(row, 7))) // OID + if((item = m_ui.mail-> + item(row, m_ui.mail->columnCount() - 1))) // OID if(updateMailStatus(item->text(), tr("Read"))) if((item = m_ui.mail->item(row, 2))) // Status item->setText(tr("Read")); @@ -5211,7 +5219,8 @@ return; QModelIndexList list - (m_ui.mail->selectionModel()->selectedRows(7)); // OID + (m_ui.mail->selectionModel()-> + selectedRows(m_ui.mail->columnCount() - 1)); // OID if(list.isEmpty()) return; @@ -5693,7 +5702,8 @@ if(!m_crypt) return APPLY_GOLDBUG_TO_INBOX_ERROR_MEMORY; - QTableWidgetItem *item = m_ui.mail->item(row, 7); // OID + QTableWidgetItem *item = m_ui.mail->item + (row, m_ui.mail->columnCount() - 1); // OID if(!item) return APPLY_GOLDBUG_TO_INBOX_ERROR_MEMORY; @@ -5898,3 +5908,66 @@ settings.setValue("gui/postofficeDays", value); } + +void spoton::slotReply(void) +{ + int row = m_ui.mail->currentRow(); + + if(row < 0) + return; + + QTableWidgetItem *item = m_ui.mail->item(row, 4); // Goldbug + + if(!item) + return; + + if(item->text() != "0") + /* + ** How can we reply to an encrypted message? + */ + + return; + + item = m_ui.mail->item(row, 5); // Message + + if(!item) + return; + + QString message(item->text()); + + item = m_ui.mail->item(row, 7); // receiver_sender_hash + + if(!item) + return; + + QString receiverSenderHash(item->text()); + + item = m_ui.mail->item(row, 3); // Subject + + if(!item) + return; + + QString subject(item->text()); + + m_ui.outgoingMessage->append("<br>"); + m_ui.outgoingMessage->append(message); + m_ui.outgoingSubject->setText(tr("Re: ") + subject); + m_ui.mailTab->setCurrentIndex(1); + + /* + ** The original author may have vanished. + */ + + m_ui.participantsCombo->setCurrentIndex(0); + + for(int i = 2; i < m_ui.participantsCombo->count(); i++) + if(m_ui.participantsCombo-> + itemData(i, Qt::UserRole).toString() == receiverSenderHash) + { + m_ui.participantsCombo->setCurrentIndex(i); + break; + } + + m_ui.outgoingMessage->moveCursor(QTextCursor::Start); + m_ui.outgoingMessage->setFocus(); +} Modified: branches/0.x/GUI/spot-on.h =================================================================== --- branches/0.x/GUI/spot-on.h 2013-06-15 01:50:23 UTC (rev 1302) +++ branches/0.x/GUI/spot-on.h 2013-06-16 03:14:18 UTC (rev 1303) @@ -146,6 +146,7 @@ void slotRefreshMail(void); void slotRefreshPostOffice(void); void slotRemoveParticipants(void); + void slotReply(void); void slotResetAll(void); void slotRetrieveMail(void); void slotSaveKernelPath(void); Modified: branches/0.x/UI/controlcenter.ui =================================================================== --- branches/0.x/UI/controlcenter.ui 2013-06-15 01:50:23 UTC (rev 1302) +++ branches/0.x/UI/controlcenter.ui 2013-06-16 03:14:18 UTC (rev 1303) @@ -72,8 +72,8 @@ <rect> <x>0</x> <y>0</y> - <width>973</width> - <height>573</height> + <width>965</width> + <height>584</height> </rect> </property> <layout class="QHBoxLayout" name="horizontalLayout_25"> @@ -576,6 +576,11 @@ </column> <column> <property name="text"> + <string>receiver_sender_hash</string> + </property> + </column> + <column> + <property name="text"> <string>OID</string> </property> </column> @@ -1795,8 +1800,8 @@ <rect> <x>0</x> <y>0</y> - <width>973</width> - <height>573</height> + <width>993</width> + <height>569</height> </rect> </property> <layout class="QVBoxLayout" name="verticalLayout_35"> @@ -2697,7 +2702,7 @@ <x>0</x> <y>0</y> <width>995</width> - <height>25</height> + <height>22</height> </rect> </property> <widget class="QMenu" name="menu_File"> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <tex...@us...> - 2013-06-16 03:14:21
|
Revision: 1303 http://sourceforge.net/p/spot-on/code/1303 Author: textfield Date: 2013-06-16 03:14:18 +0000 (Sun, 16 Jun 2013) Log Message: ----------- Reply support. Comments. Modified Paths: -------------- branches/0.x/Common/spot-on-misc.cc branches/0.x/GUI/spot-on.cc branches/0.x/GUI/spot-on.h branches/0.x/UI/controlcenter.ui Modified: branches/0.x/Common/spot-on-misc.cc =================================================================== --- branches/0.x/Common/spot-on-misc.cc 2013-06-15 01:50:23 UTC (rev 1302) +++ branches/0.x/Common/spot-on-misc.cc 2013-06-16 03:14:18 UTC (rev 1303) @@ -111,7 +111,10 @@ ** "0" or "1" for inbound. ** Symmetric key for outbound. */ - "hash TEXT NOT NULL, " + "hash TEXT NOT NULL, " /* + ** Hash of the message and + ** the subject. + */ "message BLOB NOT NULL, " "message_digest BLOB, " /* ** Should only be used when @@ -119,14 +122,25 @@ */ "participant_oid TEXT NOT NULL, " "receiver_sender TEXT NOT NULL, " - "receiver_sender_hash TEXT NOT NULL, " - "status TEXT NOT NULL, " + "receiver_sender_hash TEXT NOT NULL, " /* + ** Hash of the + ** receiver's or + ** the sender's + ** public key. + */ + "status TEXT NOT NULL, " /* + ** Deleted, read, etc. + */ "subject BLOB NOT NULL, " "PRIMARY KEY (folder_index, hash, receiver_sender_hash))"); query.exec("CREATE TABLE IF NOT EXISTS post_office (" "date_received TEXT NOT NULL, " "message_bundle BLOB NOT NULL, " - "recipient_hash TEXT NOT NULL)"); + "recipient_hash TEXT NOT NULL)"); /* + ** Hash of the + ** recipient's public + ** key. + */ } db.close(); @@ -233,7 +247,11 @@ "maximum_clients INTEGER NOT NULL DEFAULT 5, " "external_ip_address TEXT, " "external_port TEXT, " - "hash TEXT PRIMARY KEY NOT NULL)"); + "hash TEXT PRIMARY KEY NOT NULL)"); /* + ** The hash of the + ** IP address and + ** the port. + */ } db.close(); @@ -267,7 +285,11 @@ "uuid TEXT NOT NULL DEFAULT " "'{00000000-0000-0000-0000-000000000000}', " "country TEXT, " - "hash TEXT PRIMARY KEY NOT NULL, " + "hash TEXT PRIMARY KEY NOT NULL, " /* + ** Hash of the remote IP + ** address and the remote + ** port. + */ "remote_ip_address_hash TEXT NOT NULL, " "qt_country_hash TEXT, " "user_defined INTEGER NOT NULL DEFAULT 1, " Modified: branches/0.x/GUI/spot-on.cc =================================================================== --- branches/0.x/GUI/spot-on.cc 2013-06-15 01:50:23 UTC (rev 1302) +++ branches/0.x/GUI/spot-on.cc 2013-06-16 03:14:18 UTC (rev 1303) @@ -369,6 +369,10 @@ SIGNAL(valueChanged(int)), this, SLOT(slotDaysChanged(int))); + connect(m_ui.reply, + SIGNAL(clicked(void)), + this, + SLOT(slotReply(void))); connect(&m_generalTimer, SIGNAL(timeout(void)), this, @@ -662,7 +666,8 @@ m_ui.mail->setColumnHidden(4, true); // goldbug m_ui.mail->setColumnHidden(5, true); // message m_ui.mail->setColumnHidden(6, true); // message_digest - m_ui.mail->setColumnHidden(7, true); // OID + m_ui.mail->setColumnHidden(7, true); // receiver_sender_hash + m_ui.mail->setColumnHidden(8, true); // OID m_ui.listeners->setColumnHidden(m_ui.listeners->columnCount() - 1, true); // OID m_ui.neighbors->setColumnHidden @@ -4144,8 +4149,8 @@ if(!(key.startsWith("K") || key.startsWith("k"))) { - QMessageBox::warning - (this, tr("Spot-On: Warning"), + QMessageBox::critical + (this, tr("Spot-On: Error"), tr("Invalid key. The key must start with either the letter " "K or the letter k.")); return; @@ -4170,8 +4175,8 @@ if(!(keyType == "messaging" || keyType == "url")) { - QMessageBox::warning - (this, tr("Spot-On: Warning"), + QMessageBox::critical + (this, tr("Spot-On: Error"), tr("Invalid key type. Expecting 'messaging' or 'url'.")); return; } @@ -4185,8 +4190,8 @@ if(!spoton_gcrypt::isValidSignature(publicKey, publicKey, signature)) { - QMessageBox::warning - (this, tr("Spot-On: Warning"), + QMessageBox::critical + (this, tr("Spot-On: Error"), tr("Invalid signature.")); return; } @@ -4235,8 +4240,8 @@ if(!(repleo.startsWith("R") || repleo.startsWith("r"))) { - QMessageBox::warning - (this, tr("Spot-On: Warning"), + QMessageBox::critical + (this, tr("Spot-On: Error"), tr("Invalid repleo. The repleo must start with " "either the letter R or the letter r.")); return; @@ -4295,8 +4300,8 @@ if(!(keyType == "messaging" || keyType == "url")) { - QMessageBox::warning - (this, tr("Spot-On: Warning"), + QMessageBox::critical + (this, tr("Spot-On: Error"), tr("Invalid key type. Expecting 'messaging' or 'url'.")); return; } @@ -4319,8 +4324,8 @@ if(!spoton_gcrypt::isValidSignature(publicKey, publicKey, signature)) { - QMessageBox::warning - (this, tr("Spot-On: Warning"), + QMessageBox::critical + (this, tr("Spot-On: Error"), tr("Invalid signature.")); return; } @@ -4386,6 +4391,7 @@ m_ui.outgoingMessage->clear(); m_ui.outgoingSubject->clear(); m_ui.goldbug->clear(); + m_ui.outgoingSubject->setFocus(); } } @@ -4633,8 +4639,8 @@ if(message.isEmpty()) { - QMessageBox::warning - (this, tr("Spot-On: Warning"), + QMessageBox::critical + (this, tr("Spot-On: Error"), tr("Please compose an actual letter.")); m_ui.outgoingMessage->setFocus(); return; @@ -4901,6 +4907,7 @@ if(query.exec(QString("SELECT date, receiver_sender, status, " "subject, goldbug, " "message, message_digest, " + "receiver_sender_hash, " "OID FROM folders WHERE " "folder_index = %1"). arg(m_ui.folder->currentIndex()))) @@ -5161,7 +5168,8 @@ { QTableWidgetItem *item = 0; - if((item = m_ui.mail->item(row, 7))) // OID + if((item = m_ui.mail-> + item(row, m_ui.mail->columnCount() - 1))) // OID if(updateMailStatus(item->text(), tr("Read"))) if((item = m_ui.mail->item(row, 2))) // Status item->setText(tr("Read")); @@ -5211,7 +5219,8 @@ return; QModelIndexList list - (m_ui.mail->selectionModel()->selectedRows(7)); // OID + (m_ui.mail->selectionModel()-> + selectedRows(m_ui.mail->columnCount() - 1)); // OID if(list.isEmpty()) return; @@ -5693,7 +5702,8 @@ if(!m_crypt) return APPLY_GOLDBUG_TO_INBOX_ERROR_MEMORY; - QTableWidgetItem *item = m_ui.mail->item(row, 7); // OID + QTableWidgetItem *item = m_ui.mail->item + (row, m_ui.mail->columnCount() - 1); // OID if(!item) return APPLY_GOLDBUG_TO_INBOX_ERROR_MEMORY; @@ -5898,3 +5908,66 @@ settings.setValue("gui/postofficeDays", value); } + +void spoton::slotReply(void) +{ + int row = m_ui.mail->currentRow(); + + if(row < 0) + return; + + QTableWidgetItem *item = m_ui.mail->item(row, 4); // Goldbug + + if(!item) + return; + + if(item->text() != "0") + /* + ** How can we reply to an encrypted message? + */ + + return; + + item = m_ui.mail->item(row, 5); // Message + + if(!item) + return; + + QString message(item->text()); + + item = m_ui.mail->item(row, 7); // receiver_sender_hash + + if(!item) + return; + + QString receiverSenderHash(item->text()); + + item = m_ui.mail->item(row, 3); // Subject + + if(!item) + return; + + QString subject(item->text()); + + m_ui.outgoingMessage->append("<br>"); + m_ui.outgoingMessage->append(message); + m_ui.outgoingSubject->setText(tr("Re: ") + subject); + m_ui.mailTab->setCurrentIndex(1); + + /* + ** The original author may have vanished. + */ + + m_ui.participantsCombo->setCurrentIndex(0); + + for(int i = 2; i < m_ui.participantsCombo->count(); i++) + if(m_ui.participantsCombo-> + itemData(i, Qt::UserRole).toString() == receiverSenderHash) + { + m_ui.participantsCombo->setCurrentIndex(i); + break; + } + + m_ui.outgoingMessage->moveCursor(QTextCursor::Start); + m_ui.outgoingMessage->setFocus(); +} Modified: branches/0.x/GUI/spot-on.h =================================================================== --- branches/0.x/GUI/spot-on.h 2013-06-15 01:50:23 UTC (rev 1302) +++ branches/0.x/GUI/spot-on.h 2013-06-16 03:14:18 UTC (rev 1303) @@ -146,6 +146,7 @@ void slotRefreshMail(void); void slotRefreshPostOffice(void); void slotRemoveParticipants(void); + void slotReply(void); void slotResetAll(void); void slotRetrieveMail(void); void slotSaveKernelPath(void); Modified: branches/0.x/UI/controlcenter.ui =================================================================== --- branches/0.x/UI/controlcenter.ui 2013-06-15 01:50:23 UTC (rev 1302) +++ branches/0.x/UI/controlcenter.ui 2013-06-16 03:14:18 UTC (rev 1303) @@ -72,8 +72,8 @@ <rect> <x>0</x> <y>0</y> - <width>973</width> - <height>573</height> + <width>965</width> + <height>584</height> </rect> </property> <layout class="QHBoxLayout" name="horizontalLayout_25"> @@ -576,6 +576,11 @@ </column> <column> <property name="text"> + <string>receiver_sender_hash</string> + </property> + </column> + <column> + <property name="text"> <string>OID</string> </property> </column> @@ -1795,8 +1800,8 @@ <rect> <x>0</x> <y>0</y> - <width>973</width> - <height>573</height> + <width>993</width> + <height>569</height> </rect> </property> <layout class="QVBoxLayout" name="verticalLayout_35"> @@ -2697,7 +2702,7 @@ <x>0</x> <y>0</y> <width>995</width> - <height>25</height> + <height>22</height> </rect> </property> <widget class="QMenu" name="menu_File"> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <tex...@us...> - 2013-06-15 01:50:28
|
Revision: 1302 http://sourceforge.net/p/spot-on/code/1302 Author: textfield Date: 2013-06-15 01:50:23 +0000 (Sat, 15 Jun 2013) Log Message: ----------- New file. Modified Paths: -------------- branches/0.x/Icons/icons.qrc Added Paths: ----------- branches/0.x/Icons/nuvola/reply.png Modified: branches/0.x/Icons/icons.qrc =================================================================== --- branches/0.x/Icons/icons.qrc 2013-06-15 01:43:50 UTC (rev 1301) +++ branches/0.x/Icons/icons.qrc 2013-06-15 01:50:23 UTC (rev 1302) @@ -275,6 +275,7 @@ <file>nuvola/outbox.png</file> <file>nuvola/read.png</file> <file>nuvola/refresh.png</file> + <file>nuvola/reply.png</file> <file>nuvola/search.png</file> <file>nuvola/settings.png</file> <file>nuvola/share.png</file> Added: branches/0.x/Icons/nuvola/reply.png =================================================================== (Binary files differ) Index: branches/0.x/Icons/nuvola/reply.png =================================================================== --- branches/0.x/Icons/nuvola/reply.png 2013-06-15 01:43:50 UTC (rev 1301) +++ branches/0.x/Icons/nuvola/reply.png 2013-06-15 01:50:23 UTC (rev 1302) Property changes on: branches/0.x/Icons/nuvola/reply.png ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |