summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex <b0ris@b0ris-satellite.localdomain>2011-11-03 03:03:34 +0200
committerAlex <b0ris@b0ris-satellite.localdomain>2011-11-03 03:03:34 +0200
commitc0c86b6cab64186e97285e1b5b1ef13062926d87 (patch)
treeed36333b7a1fa009356daabea6f63235297729ea
parent19b9a0e1b46399c91872288eba25e1502231df06 (diff)
Initial SslClient implementation
-rw-r--r--client/Dialog.h1
-rw-r--r--client/SslClient.cpp148
-rw-r--r--client/SslClient.h91
-rw-r--r--client/client.pro9
4 files changed, 243 insertions, 6 deletions
diff --git a/client/Dialog.h b/client/Dialog.h
index 7155673..d7d7b5e 100644
--- a/client/Dialog.h
+++ b/client/Dialog.h
@@ -15,7 +15,6 @@ class ProxyEntryStatic;
class ProxyDialog: public QDialog
{
Q_OBJECT
-
public:
ProxyDialog(QWidget *parent = 0);
diff --git a/client/SslClient.cpp b/client/SslClient.cpp
new file mode 100644
index 0000000..25a3839
--- /dev/null
+++ b/client/SslClient.cpp
@@ -0,0 +1,148 @@
+
+#include <QtCore>
+#include <QtNetwork>
+#include "client.h"
+#include "SslClient.h"
+
+SslClient::SslClient(): port(13666)
+{
+ SslClient("127.0.0.1");
+}
+
+SslClient::SslClient(char* addr): port(13666)
+{
+ server = addr;
+
+ /* read certificates */
+ QFile ca_cert_file(":/ca.crt");
+ ca_cert_file.open(QIODevice::ReadOnly);
+ QByteArray ca_cert_arr = ca_cert_file.readAll();
+ ca_cert_file.close();
+ QSslCertificate ca_cert(ca_cert_arr);
+ QList<QSslCertificate> ca_certs;
+ ca_certs.push_back(ca_cert);
+
+ QFile key_file(":/client.key");
+ key_file.open(QIODevice::ReadOnly);
+ QByteArray key_arr = key_file.readAll();
+ key_file.close();
+ QSslKey key(key_arr, QSsl::Rsa);
+
+ QFile cert_file(":/client.crt");
+ cert_file.open(QIODevice::ReadOnly);
+ QByteArray cert_arr = cert_file.readAll();
+ cert_file.close();
+ QSslCertificate cert(cert_arr);
+
+ /* create ssl socket */
+ sslSocket = new QSslSocket;
+ sslSocket->setLocalCertificate(cert);
+ sslSocket->setPrivateKey(key);
+ sslSocket->setCaCertificates(ca_certs);
+ sslSocket->setPeerVerifyMode(QSslSocket::VerifyPeer);
+ sslSocket->setProtocol(QSsl::SslV3);
+
+ /* setup signal handlers */
+ connect(sslSocket, SIGNAL(encrypted()),
+ this, SLOT(Connected()));
+ connect(sslSocket, SIGNAL(disconnected()),
+ this, SLOT(Disconnected()));
+ connect(sslSocket, SIGNAL(readyRead()),
+ this, SLOT(DataRecieved()));
+ connect(sslSocket, SIGNAL(error(QAbstractSocket::SocketError)),
+ this, SLOT(Error(QAbstractSocket::SocketError)));
+ connect(sslSocket, SIGNAL(peerVerifyError(const QSslError &)),
+ this, SLOT(PeerVerifyError(const QsslError)));
+ connect(sslSocket, SIGNAL(sslErrors(const QList<QSslError> &)),
+ this, SLOT(SslErrors(const QList<QSslError> &)));
+}
+
+void SslClient::SetServerAddr(char* addr)
+{
+ server = addr;
+}
+
+void SslClient::SendRequest(RequestType type)
+{
+ if (sslSocket->state() == QAbstractSocket::ConnectedState)
+ sslSocket->connectToHostEncrypted(server, port);
+
+ unsigned char rcode = 0x00;
+ switch (type)
+ {
+ case Config:
+ rcode = 0x01;
+ break;
+ case GenericProxyList:
+ rcode = 0x02;
+ break;
+ case StaticProxyList:
+ rcode = 0x03;
+ break;
+ case FirewallList:
+ rcode = 0x04;
+ break;
+ default:
+ Logger::Error("Invalid server request type");
+ break;
+ }
+
+ char data[5] = {0x13, 0x13, rcode, 0x14, 0x14};
+ QByteArray pkt(data);
+ sslSocket->write(pkt);
+}
+
+/*
+ * Signal handlers
+ */
+void SslClient::Connected()
+{
+ Logger::Info("Connected to server\n");
+}
+
+void SslClient::Disconnected()
+{
+ Logger::Info("Disconnected from server\n");
+}
+
+void SslClient::DataRecieved()
+{
+ Logger::Trace("Reply recieved\n");
+ QByteArray data = sslSocket->readAll();
+ qDebug() << data;
+}
+
+void SslClient::Error(QAbstractSocket::SocketError socketError)
+{
+ Logger::Fatal("Socket error!");
+}
+
+void SslClient::PeerVerifyError(const QSslError &error)
+{
+ switch(error.error())
+ {
+ case QSslError::InvalidCaCertificate:
+ case QSslError::NoPeerCertificate:
+ case QSslError::UnspecifiedError:
+ case QSslError::AuthorityIssuerSerialNumberMismatch:
+ Logger::Fatal("Critical peer verify error!, Aborting connection\n"
+ "Error description: %s",
+ error.errorString().toStdString().c_str());
+ sslSocket->abort();
+ break;
+ default:
+ Logger::Fatal("Can't verify peer: %s", error.errorString().toStdString().c_str());
+ break;
+ }
+}
+
+void SslClient::SslErrors(const QList<QSslError> &errors)
+{
+ if (!errors.empty())
+ {
+ for (int i = 0; i < errors.size(); i++)
+ {
+ Logger::Fatal("%s", errors[i].errorString().toStdString().c_str());
+ }
+ }
+} \ No newline at end of file
diff --git a/client/SslClient.h b/client/SslClient.h
new file mode 100644
index 0000000..77c3ff3
--- /dev/null
+++ b/client/SslClient.h
@@ -0,0 +1,91 @@
+
+#ifndef SSL_CLIENT_H
+#define SSL_CLIENT_H
+
+#include <QAbstractSocket>
+#include <QObject>
+
+class QSslSocket;
+class QSslError;
+class QString;
+
+/**
+ * @brief Client-server communication class<br/>
+ * - Uses SSL protocol to communicate with server
+ * - Requests config/static or generic proxy lists/firewall list
+ * - Server port - 13666
+ * - Request format: [0x13 0x13 code 0x14 0x14]
+ * - Reply format: [0x13 0x13 code [data] 0x14 0x14]
+ * - Request codes:
+ */
+class SslClient: QObject
+{
+ Q_OBJECT
+public:
+ /**
+ * @enum RequestType Enumerate all possible request types
+ */
+ enum RequestType
+ {
+ /**
+ * @brief Request generic config
+ */
+ Config = 0x01,
+ /**
+ * @brief Request generic proxy list
+ */
+ GenericProxyList = 0x02,
+ /**
+ * @brief Request static proxy list
+ */
+ StaticProxyList = 0x04,
+ /**
+ * @brief Request list of firewalled hosts
+ */
+ FirewallList = 0x08
+ };
+
+ /**
+ * @brief setup ssl socket ans it's type, certificates and key<br/>
+ * Default server address will be used: 127.0.0.1
+ */
+ SslClient();
+
+ /**
+ * @brief setup ssl socket ans it's type, certificates and key
+ * @param addr server address or hostname to connect to
+ */
+ SslClient(char* addr);
+
+ /**
+ * @brief set server address to connect to
+ * @param addr server address or hostname to connect to
+ */
+ void SetServerAddr(char* addr);
+
+ /**
+ * @brief Request generic proxy list
+ * @param type type of request to send
+ */
+ void SendRequest(RequestType type);
+signals:
+ /**
+ * @brief This signal is emited when data is recieved as a reply to
+ * particular request
+ * @param type of request this reply corresponds to
+ */
+ void ReplyRecieved(RequestType type);
+private slots:
+ void Connected();
+ void Disconnected();
+ void DataRecieved();
+ void Error(QAbstractSocket::SocketError socketError);
+ void PeerVerifyError(const QSslError &error);
+ void SslErrors(const QList<QSslError> &errors);
+private:
+ QSslSocket *sslSocket;
+ QString server;
+ unsigned short port;
+};
+
+#endif \ No newline at end of file
diff --git a/client/client.pro b/client/client.pro
index cf5547e..403b581 100644
--- a/client/client.pro
+++ b/client/client.pro
@@ -8,19 +8,18 @@ QMAKE_CXXFLAGS_DEBUG += -DDEBUG -g3 -ggdb -O0
CONFIG -= release
CONFIG += debug console
+QT += network
+
TEMPLATE = app
TARGET =
DEPENDPATH += .
INCLUDEPATH += .
# Input
-HEADERS += client.h Proxy.h Dialog.h ProxyClientApp.h Logger.h Config.h
-SOURCES += Dialog.cpp main.cpp Proxy.cpp ProxyClientApp.cpp Logger.cpp Config.cpp
+HEADERS += client.h Proxy.h Dialog.h ProxyClientApp.h Logger.h Config.h SslClient.h
+SOURCES += Dialog.cpp main.cpp Proxy.cpp ProxyClientApp.cpp Logger.cpp Config.cpp SslClient.cpp
OTHER_FILES +=
RESOURCES += \
client.qrc
-
-
-