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.
|