123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445 |
- #define INCLUDE_SSL
- #include "Klient.h"
- #ifndef WIN32
- # include <netdb.h>
- # include <string.h>
- # include <sys/select.h>
- #endif
- #include <Datei.h>
- #include <Key.h>
- #include <Logging.h>
- using namespace Network;
- // inhalt der Klient Klasse aus Klient.h
- // Konstruktor
- Klient::Klient()
- : ReferenceCounter(),
- errorOccured(0)
- {
- memset(&server, 0, sizeof(server));
- server.sin_family = AF_INET;
- downStreamBytes = 0;
- upStreamBytes = 0;
- sock = 0;
- sendeKey = 0;
- empfangKey = 0;
- }
- // Destruktoe
- Klient::~Klient()
- {
- if (sock) trenne();
- if (sendeKey) sendeKey->release();
- if (empfangKey) empfangKey->release();
- }
- // nicht constant
- void Klient::setSendeKeyZ(Encryption::Key* key) // Setzt den Key fürs Senden
- {
- if (sendeKey) sendeKey->release();
- sendeKey = key;
- }
- void Klient::setEmpfangKeyZ(
- Encryption::Key* key) // Setzt den Key fürs Empfangen
- {
- if (empfangKey) empfangKey->release();
- empfangKey = key;
- }
- void Klient::setSendeKey(const char* key, int len) // Setzt den Key fürs Senden
- {
- if (!sendeKey) sendeKey = new Encryption::Key();
- sendeKey->setKey(key, len);
- }
- void Klient::setEmpfangKey(
- const char* key, int len) // Setzt den Key fürs Empfangen
- {
- if (!empfangKey) empfangKey = new Encryption::Key();
- empfangKey->setKey(key, len);
- }
- bool Klient::verbinde(
- unsigned short port, const char* ip) // verbindet mit Server
- {
- if (sendeKey) sendeKey->setPos(0);
- if (empfangKey) empfangKey->setPos(0);
- if (sock) closesocket(sock);
- sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
- long sIp = inet_addr(ip); // ip addresse
- if (sIp == INADDR_NONE)
- {
- struct hostent* pHostInfo = gethostbyname(ip);
- if (pHostInfo == 0) return 0;
- sIp = *(long*)pHostInfo->h_addr_list[0];
- }
- memcpy((char*)&server.sin_addr, &sIp, sizeof(sIp));
- server.sin_port = htons(port); // port
- if (connect(sock, (struct sockaddr*)&server, sizeof(server))
- < 0) // verbinden
- {
- errorOccured = 1;
- return 0; // Fehler
- }
- errorOccured = 0;
- return 1;
- }
- bool Klient::sende(const char* nachricht, int len) // sendet zum Server
- {
- int ll = 0;
- while (len > 0)
- {
- #ifdef WIN32
- int l = send(sock, nachricht + ll, len, 0);
- #else
- int l = (int)send(sock, nachricht + ll, len, MSG_NOSIGNAL);
- #endif
- if (l <= 0)
- {
- #ifdef WIN32
- # ifdef _DEBUG
- Framework::Logging::warning()
- << "send: " << l << " Error: " << WSAGetLastError();
- # endif
- #endif
- errorOccured = 1;
- return 0; // Fehler
- }
- len -= l;
- ll += l;
- }
- upStreamBytes += ll;
- return 1;
- }
- bool Klient::getNachricht(char* nachricht, int len) // empfängt Nachricht
- {
- int ll = 0;
- while (len > 0)
- {
- int l = (int)recv(sock, nachricht + ll, len, MSG_WAITALL);
- if (l <= 0)
- {
- #ifdef WIN32
- # ifdef _DEBUG
- Framework::Logging::warning()
- << "recv: " << l << " Error: " << WSAGetLastError();
- # endif
- #endif
- errorOccured = 1;
- return 0; // Fehler
- }
- len -= l;
- ll += l;
- }
- downStreamBytes += ll;
- return 1;
- }
- bool Klient::sendeEncrypted(const char* nachricht, int len) // sendet zum Server
- {
- if (!sendeKey) return sende(nachricht, len);
- Encryption::Bytes* n = new Encryption::Bytes(nachricht, len);
- sendeKey->codieren(
- dynamic_cast<Framework::Encryption::Bytes*>(n->getThis()));
- int ll = 0;
- while (len > 0)
- {
- #ifdef WIN32
- int l = send(sock, n->getBytes() + ll, len, 0);
- #else
- int l = (int)send(sock, n->getBytes() + ll, len, MSG_NOSIGNAL);
- #endif
- if (l <= 0)
- {
- #ifdef WIN32
- # ifdef _DEBUG
- Framework::Logging::warning()
- << "send: " << l << " Error: " << WSAGetLastError();
- # endif
- #endif
- n->release();
- errorOccured = 1;
- return 0; // Fehler
- }
- len -= l;
- ll += l;
- }
- upStreamBytes += ll;
- n->release();
- return 1;
- }
- bool Klient::getNachrichtEncrypted(
- char* nachricht, int len) // empfängt Nachricht
- {
- if (!empfangKey) return getNachricht(nachricht, len);
- int ll = 0;
- while (len > 0)
- {
- int l = (int)recv(sock, nachricht + ll, len, MSG_WAITALL);
- if (l <= 0)
- {
- #ifdef WIN32
- # ifdef _DEBUG
- Framework::Logging::warning()
- << "recv: " << l << " Error: " << WSAGetLastError();
- # endif
- #endif
- errorOccured = 1;
- return 0; // Fehler
- }
- len -= l;
- ll += l;
- }
- Encryption::Bytes* n = new Encryption::Bytes();
- n->setBytesZ(nachricht, ll);
- empfangKey->decodieren(n);
- downStreamBytes += ll;
- return 1;
- }
- int Klient::getDownloadBytes(
- bool reset) // gibt die anzahl von empfangen bytes zurück
- {
- int ret = downStreamBytes;
- if (reset) downStreamBytes = 0;
- return ret;
- }
- int Klient::getUploadBytes(
- bool reset) // gibt die anzahl von versendeter bytes zurück
- {
- int ret = upStreamBytes;
- if (reset) upStreamBytes = 0;
- return ret;
- }
- bool Klient::trenne() // Trennt die Verbindung zum Server
- {
- if (!sock) return 1;
- if (sendeKey) sendeKey->setPos(0);
- if (empfangKey) empfangKey->setPos(0);
- if (closesocket(sock) < 0) // verbindung Trennen
- {
- errorOccured = 1;
- return 0; // Fehler
- }
- sock = 0;
- return 1;
- }
- // constant
- bool Klient::hatNachricht(int zeit) // Wartet eine Zeit Lang auf eine Nachricht
- {
- fd_set set;
- FD_ZERO(&set);
- FD_SET(sock, &set);
- timeval time = {zeit / 1000, zeit};
- int result = select(0, &set, 0, 0, &time);
- if (result < 0)
- {
- #ifdef WIN32
- # ifdef _DEBUG
- Framework::Logging::warning()
- << "select: " << result << " Error: " << WSAGetLastError();
- # endif
- #endif
- }
- return result > 0;
- }
- unsigned short Klient::getServerPort() const // gibt den Port zurück
- {
- return htons(server.sin_port);
- }
- const char* Klient::getServerIp() const // gibt die Ip zurück
- {
- return inet_ntoa(server.sin_addr);
- }
- bool Klient::waitForNextMessage() const // wartet bis es etwas zu empfangen gibt
- {
- fd_set set;
- int rv = 0;
- struct timeval timeout;
- while (rv == 0 && sock)
- {
- FD_ZERO(&set); /* clear the set */
- FD_SET(sock, &set); /* add our file descriptor to the set */
- timeout.tv_sec = 10;
- timeout.tv_usec = 0;
- rv = select((int)sock + 1, &set, NULL, NULL, &timeout);
- if (rv == -1)
- {
- #ifdef WIN32
- # ifdef _DEBUG
- Framework::Logging::warning()
- << "select: " << rv << " Error: " << WSAGetLastError();
- # endif
- #endif
- return 0;
- }
- }
- if (!sock) return 0;
- char c;
- #ifdef WIN32
- int l = (int)recv(sock, &c, 1, MSG_PEEK);
- #else
- int l = (int)recv(sock, &c, 1, MSG_WAITALL | MSG_PEEK);
- #endif
- if (l <= 0)
- {
- #ifdef WIN32
- # ifdef _DEBUG
- Framework::Logging::warning()
- << "recv: " << l << " Error: " << WSAGetLastError();
- # endif
- #endif
- return 0; // Fehler
- }
- return 1;
- }
- bool Klient::isConnected()
- const // gibt true zurück, wenn eine Verbindung besteht
- {
- return sock != 0 && !errorOccured;
- }
- // Inhalt der SSLKlient Klasse aus Klient.h
- // Konstruktor
- SSLKlient::SSLKlient()
- : ReferenceCounter()
- {
- ctx = SSL_CTX_new(TLS_client_method());
- SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION);
- SSL_CTX_set_max_proto_version(ctx, TLS1_3_VERSION);
- ip = 0;
- port = 0;
- bio = BIO_new_ssl_connect(ctx);
- BIO_get_ssl(bio, &ssl);
- downStreamBytes = 0;
- upStreamBytes = 0;
- connected = 0;
- }
- // Destruktor
- SSLKlient::~SSLKlient()
- {
- if (this->ip) this->ip->release();
- if (connected) trenne();
- BIO_free_all(bio);
- SSL_CTX_free(ctx);
- #ifdef WIN32
- OPENSSL_thread_stop();
- #endif
- }
- bool SSLKlient::verbinde(
- unsigned short port, const char* ip) // verbindet mit Server
- {
- this->port = port;
- if (this->ip) this->ip->release();
- this->ip = new Text(ip);
- Text adr = ip;
- adr += ":";
- adr += port;
- BIO_set_conn_hostname(bio, (const char*)adr);
- connected = BIO_do_connect(bio) > 0;
- if (connected && BIO_do_handshake(bio) <= 0) trenne();
- return connected;
- }
- bool SSLKlient::sende(const char* nachricht, int len) // sendet zum Server
- {
- int ll = 0;
- while (len > 0)
- {
- int l = SSL_write(ssl, nachricht + ll, len);
- if (l <= 0)
- {
- #ifdef _DEBUG
- Framework::Logging::warning()
- << "SSL_write: " << l << " Error: " << SSL_get_error(ssl, l);
- #endif
- return 0; // Fehler
- }
- len -= l;
- ll += l;
- }
- upStreamBytes += ll;
- return 1;
- }
- bool SSLKlient::getNachricht(char* nachricht, int len) // empfängt Nachricht
- {
- if (!connected) return 0;
- int ll = 0;
- while (len > 0)
- {
- int l = SSL_read(ssl, nachricht + ll, len);
- if (l <= 0)
- {
- #ifdef _DEBUG
- Framework::Logging::warning()
- << "SSL_read: " << l << " Error: " << SSL_get_error(ssl, l);
- #endif
- return 0; // Fehler
- }
- len -= l;
- ll += l;
- }
- downStreamBytes += ll;
- return 1;
- }
- int SSLKlient::getDownloadBytes(
- bool reset) // gibt die anzahl von empfangen bytes zurück
- {
- int ret = downStreamBytes;
- if (reset) downStreamBytes = 0;
- return ret;
- }
- int SSLKlient::getUploadBytes(
- bool reset) // gibt die anzahl von versendeter bytes zurück
- {
- int ret = upStreamBytes;
- if (reset) upStreamBytes = 0;
- return ret;
- }
- bool SSLKlient::trenne() // Trennt die Verbindung zum Server
- {
- BIO_ssl_shutdown(bio);
- connected = 0;
- return 1;
- }
- // constant
- bool SSLKlient::hatNachricht(
- int zeit) // Wartet eine Zeit Lang auf eine Nachricht
- {
- fd_set set;
- FD_ZERO(&set);
- FD_SET(SSL_get_rfd(ssl), &set);
- timeval time = {zeit / 1000, zeit};
- return SSL_pending(ssl) > 0 || select(0, &set, 0, 0, &time) == 1;
- }
- unsigned short
- SSLKlient::getServerPort() const // gibt den Port des Servers zurück
- {
- return port;
- }
- const char* SSLKlient::getServerIp() const // gibt die Ip des Servers zurück
- {
- return ip->getText();
- }
|