| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738 |
- #include "Server.h"
- #include <openssl/err.h>
- #include <openssl/ssl.h>
- #ifndef WIN32
- # include <string.h>
- #endif
- #include <iostream>
- #include <Key.h>
- #include <Logging.h>
- #include <Text.h>
- using namespace Network;
- // Content of the Server class from Server.h
- // Constructor
- Server::Server()
- : ReferenceCounter()
- {
- sock = 0;
- memset(&address, 0, sizeof(address)); // Set address
- address.sin_family = AF_INET;
- address.sin_addr.s_addr = ADDR_ANY;
- clients = 0;
- }
- // Destructor
- Server::~Server()
- {
- disconnect();
- }
- // non-constant
- bool Server::connect(unsigned short port, int queueLength) // Opens the socket
- {
- sock = socket(AF_INET, SOCK_STREAM, 0); // Create socket
- address.sin_port = htons(port); // set port
- if (sock < 0)
- {
- sock = 0;
- return 0;
- }
- #ifdef WIN32
- char reuseSocket = 1;
- setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &reuseSocket, sizeof(char));
- #else
- int reuseSocket = 1;
- setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &reuseSocket, sizeof(int));
- #endif
- if (bind(sock, (struct sockaddr*)&address, sizeof(address))
- == -1) // open socket
- {
- disconnect();
- return 0; // Error
- }
- if (listen(sock, queueLength) == -1) // accept clients
- {
- disconnect();
- return 0; // Error
- }
- return 1;
- }
- SClient* Server::getClient() // accepts a client
- {
- if (!sock) return 0;
- sockaddr_in client;
- int len = sizeof(address);
- 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) return 0;
- }
- if (!sock) return 0;
- #ifdef WIN32
- SOCKET cls = accept(sock, (sockaddr*)&client, &len); // receive client
- if (cls == INVALID_SOCKET)
- {
- disconnect();
- return 0;
- }
- #else
- SOCKET cls
- = accept(sock, (sockaddr*)&client, (socklen_t*)&len); // receive client
- if (!cls)
- {
- if (errno == ECONNABORTED || errno == EBADF) disconnect();
- return 0;
- }
- #endif
- client.sin_port = address.sin_port;
- clients++;
- return new SClient(client, cls); // return client handle class
- }
- int Server::getClients(bool reset) // returns the number of clients
- {
- int ret = clients;
- if (reset) clients = 0;
- return ret;
- }
- bool Server::disconnect() // stops the server
- {
- if (!sock) return 1;
- if (closesocket(sock) < 0) // close socket
- return 0;
- sock = 0;
- return 1;
- }
- // constant
- unsigned short Server::getPort() const // returns the port
- {
- return htons(address.sin_port);
- }
- bool Server::isConnected() const // returns 1 if the server is connected
- {
- return sock != 0;
- }
- // Content of the SClient class from Server.h
- // Constructor
- SClient::SClient(sockaddr_in address, SOCKET sock)
- : ReferenceCounter()
- {
- clientAddr = address;
- this->sock = sock;
- downStreamBytes = 0;
- upStreamBytes = 0;
- sendKey = 0;
- receiveKey = 0;
- }
- // Destructor
- SClient::~SClient()
- {
- disconnect();
- if (sendKey) sendKey->release();
- if (receiveKey) receiveKey->release();
- }
- // non-constant
- void SClient::setReceiveTimeout(
- int miliseconds) // Sets a timeout for receiving data
- {
- #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 SClient::setSendKeyZ(Encryption::Key* key) // Sets the key for sending
- {
- if (sendKey) sendKey->release();
- sendKey = key;
- }
- void SClient::setReceiveKeyZ(Encryption::Key* key) // Sets the key for receiving
- {
- if (receiveKey) receiveKey->release();
- receiveKey = key;
- }
- void SClient::setSendKey(const char* key, int len) // Sets the key for sending
- {
- if (!sendKey) sendKey = new Encryption::Key();
- sendKey->setKey(key, len);
- }
- void SClient::setReceiveKey(
- const char* key, int len) // Sets the key for receiving
- {
- if (!receiveKey) receiveKey = new Encryption::Key();
- receiveKey->setKey(key, len);
- }
- bool SClient::send(const char* message, int len) // sends to client
- {
- if (!sock) return 0;
- int ll = 0;
- while (len > 0)
- {
- #ifdef WIN32
- int l = ::send(sock, message + ll, len, 0);
- #else
- int l = (int)::send(sock, message + ll, len, MSG_NOSIGNAL);
- #endif
- if (l <= 0)
- {
- #ifdef WIN32
- # ifdef _DEBUG
- Framework::Logging::warning()
- << "send: " << l << " Error: " << WSAGetLastError();
- # endif
- #endif
- return 0; // Error
- }
- len -= l;
- ll += l;
- }
- upStreamBytes += ll;
- return 1;
- }
- bool SClient::getMessage(char* message, int len) // receives message from client
- {
- if (!sock) return 0;
- int ll = 0;
- while (len > 0)
- {
- int l = (int)recv(sock, message + ll, len, MSG_WAITALL);
- if (l <= 0)
- {
- #ifdef WIN32
- # ifdef _DEBUG
- Framework::Logging::warning()
- << "recv: " << l << " Error: " << WSAGetLastError();
- # endif
- #endif
- return 0; // Error
- }
- len -= l;
- ll += l;
- }
- downStreamBytes += ll;
- return 1;
- }
- bool SClient::sendEncrypted(const char* message, int len) // sends to server
- {
- if (!sendKey) return send(message, len);
- Encryption::Bytes* n = new Encryption::Bytes(message, len);
- sendKey->encode(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)
- {
- #ifdef WIN32
- # ifdef _DEBUG
- Framework::Logging::warning()
- << "send: " << l << " Error: " << WSAGetLastError();
- # endif
- #endif
- n->release();
- return 0; // Error
- }
- len -= l;
- ll += l;
- }
- upStreamBytes += ll;
- n->release();
- return 1;
- }
- bool SClient::getMessageEncrypted(char* message, int len) // receives message
- {
- if (!receiveKey) return getMessage(message, len);
- int ll = 0;
- while (len > 0)
- {
- int l = (int)recv(sock, message + ll, len, MSG_WAITALL);
- if (l <= 0)
- {
- #ifdef WIN32
- # ifdef _DEBUG
- Framework::Logging::warning()
- << "recv: " << l << " Error: " << WSAGetLastError();
- # endif
- #endif
- return 0; // Error
- }
- len -= l;
- ll += l;
- }
- Encryption::Bytes* n = new Encryption::Bytes();
- n->setBytesZ(message, ll);
- receiveKey->decode(n);
- downStreamBytes += ll;
- return 1;
- }
- int SClient::getDownloadBytes(
- bool reset) // returns the number of received bytes
- {
- int ret = downStreamBytes;
- if (reset) downStreamBytes = 0;
- return ret;
- }
- int SClient::getUploadBytes(bool reset) // returns the number of sent bytes
- {
- int ret = upStreamBytes;
- if (reset) upStreamBytes = 0;
- return ret;
- }
- bool SClient::disconnect() // disconnects from client
- {
- if (!sock) return 0;
- if (closesocket(sock) < 0) // disconnect
- return 0;
- sock = 0;
- return 1;
- }
- // constant
- bool SClient::hasMessage(
- int waitTime) const // Waits for a message for a given time
- {
- fd_set set;
- FD_ZERO(&set);
- FD_SET(sock, &set);
- timeval time = {waitTime / 1000, waitTime};
- 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 SClient::getPort() const // returns the port
- {
- return htons(clientAddr.sin_port);
- }
- const char* SClient::getIp() const // returns the client's IP
- {
- return inet_ntoa(clientAddr.sin_addr);
- }
- int pem_passwd_cb(char* buf, int size, int rwflag, void* userdata)
- {
- const char* pw = ((Text*)userdata)->getText();
- memcpy(buf, pw, MIN((unsigned int)size, strlen(pw) + 1));
- return (int)strlen(buf);
- }
- bool SSLErrorCheck(int result, SSL* ssl, const char* action)
- {
- if (result <= 0)
- {
- Framework::Logging::error()
- << "'" << action
- << "' returned error code: " << SSL_get_error(ssl, result);
- return 0;
- }
- return 1;
- }
- bool SSLErrorCheck(__int64 result, const char* action)
- {
- if (result <= 0)
- {
- unsigned long error = ERR_get_error();
- Framework::Logging::error() << "'" << action << "' returned " << result
- << " error code: " << error << "("
- << ERR_reason_error_string(error) << ")";
- return 0;
- }
- return 1;
- }
- bool SClient::waitForNextMessage()
- const // waits until there is something to receive
- {
- 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; // Error
- }
- return 1;
- }
- // Content of the SSLServer class
- // Constructor
- 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);
- password = new Text();
- SSL_CTX_set_default_passwd_cb_userdata(ctx, password);
- addr.sin_family = AF_INET;
- addr.sin_addr.s_addr = htonl(INADDR_ANY);
- clients = 0;
- }
- // Destructor
- SSLServer::~SSLServer()
- {
- disconnect();
- SSL_CTX_free(ctx);
- password->release();
- #ifdef WIN32
- OPENSSL_thread_stop();
- #endif
- }
- // non-constant
- // Sets the path to the file where the certificate is stored
- bool SSLServer::setCertificateFile(const char* file)
- {
- return SSLErrorCheck(
- SSL_CTX_use_certificate_file(ctx, file, SSL_FILETYPE_PEM),
- "SSL_CTX_use_certificate_file");
- }
- // Sets the path to the file where the private key is stored
- bool SSLServer::setPrivateKeyFile(const char* file)
- {
- return SSLErrorCheck(
- SSL_CTX_use_PrivateKey_file(ctx, file, SSL_FILETYPE_PEM),
- "SSL_CTX_use_PrivateKey_file");
- }
- // sets the password of the private key (must be called before
- // setPrivateKeyFile)
- void SSLServer::setPrivateKeyPassword(const char* password)
- {
- this->password->setText(password);
- }
- // Opens the socket
- bool SSLServer::connect(unsigned short port, int queueLength)
- {
- addr.sin_port = htons(port);
- s = socket(AF_INET, SOCK_STREAM, 0);
- if (s < 0)
- {
- s = 0;
- return 0;
- }
- #ifdef WIN32
- char reuseSocket = 1;
- setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &reuseSocket, sizeof(char));
- #else
- int reuseSocket = 1;
- setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &reuseSocket, sizeof(int));
- #endif
- if (bind(s, (struct sockaddr*)&addr, sizeof(addr)) < 0)
- {
- disconnect();
- return 0;
- }
- if (listen(s, queueLength) < 0)
- {
- disconnect();
- return 0;
- }
- return 1;
- }
- // accepts a client
- SSLSClient* SSLServer::getClient()
- {
- if (!s) return 0;
- int len = sizeof(addr);
- struct sockaddr_in addr;
- fd_set set;
- int rv = 0;
- struct timeval timeout;
- while (rv == 0 && s)
- {
- FD_ZERO(&set); /* clear the set */
- FD_SET(s, &set); /* add our file descriptor to the set */
- timeout.tv_sec = 10;
- timeout.tv_usec = 0;
- rv = select((int)s + 1, &set, NULL, NULL, &timeout);
- if (rv == -1) return 0;
- }
- if (!s) return 0;
- #ifdef WIN32
- SOCKET client = accept(s, (struct sockaddr*)&addr, &len);
- if (client == INVALID_SOCKET)
- {
- disconnect();
- return 0;
- }
- #else
- SOCKET client
- = accept(s, (sockaddr*)&addr, (socklen_t*)&len); // receive client
- if (!client)
- {
- if (errno == ECONNABORTED || errno == EBADF) disconnect();
- 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;
- }
- clients++;
- return new SSLSClient(addr, ssl, client);
- }
- // returns the number of clients
- int SSLServer::getClients(bool reset)
- {
- int ret = clients;
- if (reset) clients = 0;
- return ret;
- }
- // stops the server
- bool SSLServer::disconnect()
- {
- if (!s) return 1;
- if (closesocket(s) < 0) // close socket
- return 0;
- s = 0;
- return 1;
- }
- // constant
- // returns the port
- unsigned short SSLServer::getPort() const
- {
- return htons(addr.sin_port);
- }
- // returns 1 if the server is connected
- bool SSLServer::isConnected() const
- {
- return s != 0;
- }
- // Content of the SSLSClient class
- // Constructor
- SSLSClient::SSLSClient(sockaddr_in client, SSL* ssl, SOCKET s)
- : ReferenceCounter()
- {
- this->s = s;
- clientAddr = client;
- this->ssl = ssl;
- downStreamBytes = 0;
- upStreamBytes = 0;
- }
- // Destructor
- SSLSClient::~SSLSClient()
- {
- disconnect();
- #ifdef WIN32
- OPENSSL_thread_stop();
- #endif
- }
- // non-constant
- void SSLSClient::setReceiveTimeout(
- int miliseconds) // Sets a timeout for receiving data
- {
- #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 SSLSClient::send(const char* message, int len) // sends to client
- {
- if (!ssl) return 0;
- int ll = 0;
- while (len > 0)
- {
- int l = SSL_write(ssl, message + ll, len);
- if (l <= 0)
- {
- #ifdef _DEBUG
- Framework::Logging::warning()
- << "SSL_write: " << l << " Error: " << SSL_get_error(ssl, l);
- #endif
- return 0; // Error
- }
- len -= l;
- ll += l;
- }
- upStreamBytes += ll;
- return 1;
- }
- bool SSLSClient::getMessage(
- char* message, int len) // receives message from client
- {
- if (!ssl) return 0;
- int ll = 0;
- while (len > 0)
- {
- int l = (int)SSL_read(ssl, message + ll, len);
- if (l <= 0)
- {
- #ifdef _DEBUG
- Framework::Logging::warning()
- << "SSL_read: " << l << " Error: " << SSL_get_error(ssl, l);
- #endif
- return 0; // Error
- }
- len -= l;
- ll += l;
- }
- downStreamBytes += ll;
- return 1;
- }
- int SSLSClient::getDownloadBytes(
- bool reset) // returns the number of received bytes
- {
- int ret = downStreamBytes;
- if (reset) downStreamBytes = 0;
- return ret;
- }
- int SSLSClient::getUploadBytes(bool reset) // returns the number of sent bytes
- {
- int ret = upStreamBytes;
- if (reset) upStreamBytes = 0;
- return ret;
- }
- bool SSLSClient::disconnect() // disconnects from client
- {
- if (!ssl) return 0;
- SSL_free(ssl);
- if (closesocket(s) < 0) // disconnect
- return 0;
- ssl = 0;
- s = 0;
- return 1;
- }
- // constant
- bool SSLSClient::hasMessage(
- int waitTime) const // Waits for a message for a given time
- {
- fd_set set;
- FD_ZERO(&set);
- FD_SET(SSL_get_rfd(ssl), &set);
- timeval time = {waitTime / 1000, waitTime};
- return SSL_pending(ssl) > 0 || select(0, &set, 0, 0, &time) == 1;
- }
- unsigned short SSLSClient::getPort() const // returns the port
- {
- return htons(clientAddr.sin_port);
- }
- const char* SSLSClient::getIp() const // returns the client's IP
- {
- return inet_ntoa(clientAddr.sin_addr);
- }
|