123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607 |
- #include <openssl/ssl.h>
- #include <openssl/err.h>
- #include "Server.h"
- #ifndef WIN32
- #include <string.h>
- #endif
- #include <Key.h>
- #include <Text.h>
- #include <iostream>
- using namespace Network;
- // Inhalt der Server Klasse aus Server.h
- // Konstruktor
- Server::Server()
- : ReferenceCounter()
- {
- sock = 0;
- memset( &addresse, 0, sizeof( addresse ) ); // Adresse setzen
- addresse.sin_family = AF_INET;
- addresse.sin_addr.s_addr = ADDR_ANY;
- klients = 0;
- }
- // Destruktor
- Server::~Server()
- {
- trenne();
- }
- // nicht constant
- bool Server::verbinde( unsigned short port, int warteschlangenLen ) // Öffnet das Socket
- {
- sock = socket( AF_INET, SOCK_STREAM, 0 ); // Socket erstellen
- addresse.sin_port = htons( port ); // port setzen
- if( bind( sock, (struct sockaddr*)&addresse, sizeof( addresse ) ) == -1 ) // socket öffnen
- {
- trenne();
- return 0; // Fehler
- }
- if( listen( sock, warteschlangenLen ) == -1 ) // Klients annehmen
- {
- trenne();
- return 0; // Fehler
- }
- return 1;
- }
- SKlient* Server::getKlient() // nimmt Klient an
- {
- if( !sock )
- return 0;
- sockaddr_in client;
- int len = sizeof( addresse );
- #ifdef WIN32
- SOCKET cls = accept( sock, (sockaddr*)&client, &len ); // Klient empfangen
- if( cls == INVALID_SOCKET )
- {
- trenne();
- return 0;
- }
- #else
- SOCKET cls = accept( sock, (sockaddr*)&client, (socklen_t*)&len ); // Klient empfangen
- if( !cls )
- {
- if( errno == ECONNABORTED || errno == EBADF )
- trenne();
- return 0;
- }
- #endif
- client.sin_port = addresse.sin_port;
- klients++;
- return new SKlient( client, cls ); // Klient Handle Klasse zurückgeben
- }
- int Server::getKlients( bool reset ) // gibt die Anzahl der Klients zurück
- {
- int ret = klients;
- if( reset )
- klients = 0;
- return ret;
- }
- bool Server::trenne() // beendet den Server
- {
- if( !sock )
- return 1;
- if( closesocket( sock ) < 0 ) // socket schließen
- return 0;
- sock = 0;
- return 1;
- }
- // constant
- unsigned short Server::getPort() const // gibt den Port zurück
- {
- return htons( addresse.sin_port );
- }
- bool Server::isConnected() const // giebt 1 zurück, falls der Server verbunden ist
- {
- return sock != 0;
- }
- // Inhalt der SKlient Klasse aus Server.h
- // Konstruktor
- SKlient::SKlient( sockaddr_in addresse, SOCKET sock )
- : ReferenceCounter()
- {
- clientAddr = addresse;
- this->sock = sock;
- downStreamBytes = 0;
- upStreamBytes = 0;
- sendeKey = 0;
- empfangKey = 0;
- }
- // Destruktor
- SKlient::~SKlient()
- {
- trenne();
- if( sendeKey )
- sendeKey->release();
- if( empfangKey )
- empfangKey->release();
- }
- // nicht constant
- void SKlient::setEmpfangTimeout( int miliseconds ) // Setzt ein timeout fürs empfangen von daten
- {
- #ifdef WIN32
- DWORD timeout = miliseconds;
- setsockopt( sock, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout, sizeof timeout );
- #else
- struct timeval tv;
- tv.tv_sec = miliseconds / 1000;
- tv.tv_usec = (miliseconds % 1000) * 1000;
- setsockopt( sock, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv, sizeof tv );
- #endif
- }
- void SKlient::setSendeKeyZ( Encryption::Key* key ) // Setzt den Key fürs Senden
- {
- if( sendeKey )
- sendeKey->release();
- sendeKey = key;
- }
- void SKlient::setEmpfangKeyZ( Encryption::Key* key ) // Setzt den Key fürs Empfangen
- {
- if( empfangKey )
- empfangKey->release();
- empfangKey = key;
- }
- void SKlient::setSendeKey( char* key, int len ) // Setzt den Key fürs Senden
- {
- if( !sendeKey )
- sendeKey = new Encryption::Key();
- sendeKey->setKey( key, len );
- }
- void SKlient::setEmpfangKey( char* key, int len ) // Setzt den Key fürs Empfangen
- {
- if( !empfangKey )
- empfangKey = new Encryption::Key();
- empfangKey->setKey( key, len );
- }
- bool SKlient::sende( const char* nachricht, int len ) // sendet zum Klient
- {
- if( !sock )
- return 0;
- 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 )
- return 0; // Fehler
- len -= l;
- ll += l;
- }
- upStreamBytes += ll;
- return 1;
- }
- bool SKlient::getNachricht( char* nachricht, int len ) // empfängt Nachricht von Klient
- {
- if( !sock )
- return 0;
- int ll = 0;
- while( len > 0 )
- {
- int l = (int)recv( sock, nachricht + ll, len, MSG_WAITALL );
- if( l <= 0 )
- return 0; // Fehler
- len -= l;
- ll += l;
- }
- downStreamBytes += ll;
- return 1;
- }
- bool SKlient::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<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 )
- {
- n->release();
- return 0; // Fehler
- }
- len -= l;
- ll += l;
- }
- upStreamBytes += ll;
- n->release();
- return 1;
- }
- bool SKlient::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 )
- 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 SKlient::getDownloadBytes( bool reset ) // gibt die anzahl von empfangen bytes zurück
- {
- int ret = downStreamBytes;
- if( reset )
- downStreamBytes = 0;
- return ret;
- }
- int SKlient::getUploadBytes( bool reset ) // gibt die anzahl von versendeter bytes zurück
- {
- int ret = upStreamBytes;
- if( reset )
- upStreamBytes = 0;
- return ret;
- }
- bool SKlient::trenne() // trennt die Verbindung zum Klient
- {
- if( !sock )
- return 0;
- if( closesocket( sock ) < 0 ) // trennen
- return 0;
- sock = 0;
- return 1;
- }
- // constant
- bool SKlient::hatNachricht( int zeit ) const // Wartet eine Zeit Lang auf eine Nachricht
- {
- fd_set set;
- FD_ZERO( &set );
- FD_SET( sock, &set );
- timeval time = { zeit / 1000, zeit };
- return select( 0, &set, 0, 0, &time ) == 1;
- }
- unsigned short SKlient::getPort() const // gibt den Port zurück
- {
- return htons( clientAddr.sin_port );
- }
- const char* SKlient::getIp() const // gibt die Ip des Klients zurück
- {
- return inet_ntoa( clientAddr.sin_addr );
- }
- int pem_passwd_cb( char* buf, int size, int rwflag, void* userdata )
- {
- const char* passw = ((Text*)userdata)->getText();
- memcpy( buf, passw, MIN( (unsigned int)size, strlen( passw ) + 1 ) );
- return (int)strlen( buf );
- }
- bool SSLErrorCheck( int result, SSL* ssl, const char* action )
- {
- if( result <= 0 )
- {
- std::cout << "ERROR: '" << action << "' returned error code: " << SSL_get_error( ssl, result ) << "\n";
- std::cout.flush();
- return 0;
- }
- return 1;
- }
- bool SSLErrorCheck( __int64 result, const char* action )
- {
- if( result <= 0 )
- {
- unsigned long error = ERR_get_error();
- std::cout << "ERROR: '" << action << "' returned " << result << " error code: " << error << "(" << ERR_reason_error_string( error ) << ")\n";
- std::cout.flush();
- return 0;
- }
- return 1;
- }
- bool SKlient::waitForNextMessage() const // wartet bis es etwas zu empfangen gibt
- {
- char c;
- int l = (int)recv( sock, &c, 1, MSG_WAITALL | MSG_PEEK );
- if( l <= 0 )
- return 0; // Fehler
- return 1;
- }
- // Inhalt der SSLServer Klasse
- // Konstruktor
- SSLServer::SSLServer()
- : ReferenceCounter()
- {
- s = 0;
- const SSL_METHOD* method = TLS_server_method();
- ctx = SSL_CTX_new( method );
- SSLErrorCheck( SSL_CTX_set_min_proto_version( ctx, TLS1_2_VERSION ), "SSL_CTX_set_min_proto_version" );
- SSLErrorCheck( SSL_CTX_set_max_proto_version( ctx, TLS1_3_VERSION ), "SSL_CTX_set_max_proto_version" );
- SSL_CTX_set_verify( ctx, SSL_VERIFY_NONE, 0 );
- SSL_CTX_set_default_passwd_cb( ctx, pem_passwd_cb );
- passw = new Text();
- SSL_CTX_set_default_passwd_cb_userdata( ctx, passw );
- addr.sin_family = AF_INET;
- addr.sin_addr.s_addr = htonl( INADDR_ANY );
- klients = 0;
- }
- // Destruktor
- SSLServer::~SSLServer()
- {
- trenne();
- SSL_CTX_free( ctx );
- passw->release();
- #ifdef WIN32
- OPENSSL_thread_stop();
- #endif
- }
- // nicht constant
- // Setzt den Pfad zur Datei, in dem das Certifikat gespeichert ist
- bool SSLServer::setCertificateFile( const char* file )
- {
- return SSLErrorCheck( SSL_CTX_use_certificate_file( ctx, file, SSL_FILETYPE_PEM ), "SSL_CTX_use_certificate_file" );
- }
- // Setzt den Pfad zur Datei, in dem der private Schlüssel gespeichert ist
- bool SSLServer::setPrivateKeyFile( const char* file )
- {
- return SSLErrorCheck( SSL_CTX_use_PrivateKey_file( ctx, file, SSL_FILETYPE_PEM ), "SSL_CTX_use_PrivateKey_file" );
- }
- // setzt das passwort des private keys (muss vor setPrivateKeyFile aufgerufen werden)
- void SSLServer::setPrivateKeyPassword( const char* password )
- {
- passw->setText( password );
- }
- // Öffnet das Socket
- bool SSLServer::verbinde( unsigned short port, int warteschlangenLen )
- {
- addr.sin_port = htons( port );
- s = socket( AF_INET, SOCK_STREAM, 0 );
- if( s < 0 )
- {
- s = 0;
- return 0;
- }
- if( bind( s, (struct sockaddr*)&addr, sizeof( addr ) ) < 0 )
- {
- trenne();
- return 0;
- }
- if( listen( s, warteschlangenLen ) < 0 )
- {
- trenne();
- return 0;
- }
- return 1;
- }
- // nimmt Klient an
- SSLSKlient* SSLServer::getKlient()
- {
- if( !s )
- return 0;
- int len = sizeof( addr );
- struct sockaddr_in addr;
- #ifdef WIN32
- SOCKET client = accept( s, (struct sockaddr*)&addr, &len );
- if( client == INVALID_SOCKET )
- {
- trenne();
- return 0;
- }
- #else
- SOCKET client = accept( s, (sockaddr*)&addr, (socklen_t*)&len ); // Klient empfangen
- if( !client )
- {
- if( errno == ECONNABORTED || errno == EBADF )
- trenne();
- return 0;
- }
- #endif
- addr.sin_port = this->addr.sin_port;
- SSL* ssl = SSL_new( ctx );
- if( ssl == 0 && !SSLErrorCheck( 0, "SSL_new" ) )
- {
- closesocket( client );
- return 0;
- }
- if( !SSLErrorCheck( SSL_set_fd( ssl, (int)client ), ssl, "SSL_set_fd" ) )
- {
- SSL_free( ssl );
- closesocket( client );
- return 0;
- }
- if( !SSLErrorCheck( SSL_accept( ssl ), ssl, "SSL_accept" ) )
- {
- SSL_free( ssl );
- closesocket( client );
- return 0;
- }
- klients++;
- return new SSLSKlient( addr, ssl, client );
- }
- // gibt die Anzahl der Klients zurück
- int SSLServer::getKlients( bool reset )
- {
- int ret = klients;
- if( reset )
- klients = 0;
- return ret;
- }
- // beendet den Server
- bool SSLServer::trenne()
- {
- if( !s )
- return 1;
- if( closesocket( s ) < 0 ) // socket schließen
- return 0;
- s = 0;
- return 1;
- }
- // constant
- // gibt den Port zurück
- unsigned short SSLServer::getPort() const
- {
- return htons( addr.sin_port );
- }
- // giebt 1 zurück, falls der Server verbunden ist
- bool SSLServer::isConnected() const
- {
- return s != 0;
- }
- // Inhalt der SSLSKlient Klasse
- // Konstruktor
- SSLSKlient::SSLSKlient( sockaddr_in client, SSL* ssl, SOCKET s )
- : ReferenceCounter()
- {
- this->s = s;
- clientAddr = client;
- this->ssl = ssl;
- downStreamBytes = 0;
- upStreamBytes = 0;
- }
- // Destruktor
- SSLSKlient::~SSLSKlient()
- {
- trenne();
- #ifdef WIN32
- OPENSSL_thread_stop();
- #endif
- }
- // nicht constant
- void SSLSKlient::setEmpfangTimeout( int miliseconds ) // Setzt ein timeout fürs empfangen von daten
- {
- #ifdef WIN32
- DWORD timeout = miliseconds;
- setsockopt( s, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout, sizeof timeout );
- #else
- struct timeval tv;
- tv.tv_sec = miliseconds / 1000;
- tv.tv_usec = (miliseconds % 1000) * 1000;
- setsockopt( s, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv, sizeof tv );
- #endif
- }
- bool SSLSKlient::sende( const char* nachricht, int len ) // sendet zum Klient
- {
- if( !ssl )
- return 0;
- int ll = 0;
- while( len > 0 )
- {
- int l = SSL_write( ssl, nachricht + ll, len );
- if( l <= 0 )
- return 0; // Fehler
- len -= l;
- ll += l;
- }
- upStreamBytes += ll;
- return 1;
- }
- bool SSLSKlient::getNachricht( char* nachricht, int len ) // empfängt Nachricht von Klient
- {
- if( !ssl )
- return 0;
- int ll = 0;
- while( len > 0 )
- {
- int l = (int)SSL_read( ssl, nachricht + ll, len );
- if( l <= 0 )
- return 0; // Fehler
- len -= l;
- ll += l;
- }
- downStreamBytes += ll;
- return 1;
- }
- int SSLSKlient::getDownloadBytes( bool reset ) // gibt die anzahl von empfangen bytes zurück
- {
- int ret = downStreamBytes;
- if( reset )
- downStreamBytes = 0;
- return ret;
- }
- int SSLSKlient::getUploadBytes( bool reset ) // gibt die anzahl von versendeter bytes zurück
- {
- int ret = upStreamBytes;
- if( reset )
- upStreamBytes = 0;
- return ret;
- }
- bool SSLSKlient::trenne() // trennt die Verbindung zum Klient
- {
- if( !ssl )
- return 0;
- SSL_free( ssl );
- if( closesocket( s ) < 0 ) // trennen
- return 0;
- ssl = 0;
- s = 0;
- return 1;
- }
- // constant
- bool SSLSKlient::hatNachricht( int zeit ) const // 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 SSLSKlient::getPort() const // gibt den Port zurück
- {
- return htons( clientAddr.sin_port );
- }
- const char* SSLSKlient::getIp() const // gibt die Ip des Klients zurück
- {
- return inet_ntoa( clientAddr.sin_addr );
- }
|