Implement SSL, enabled timeout

dev
marcelb 2 years ago
parent 16028a0d30
commit 3bbfef613a
  1. 46
      .vscode/settings.json
  2. 21
      example/cert.pem
  3. 28
      example/privkey.pem
  4. 20
      lib/tcp_socket.hpp
  5. 141
      src/tcp_socket.cpp
  6. 6
      test/client.cpp
  7. BIN
      test/client.o
  8. 2
      test/compile-client.sh
  9. 2
      test/compile-server.sh
  10. 32
      test/server.cpp
  11. BIN
      test/server.o

@ -1,5 +1,49 @@
{ {
"files.associations": { "files.associations": {
"functional": "cpp" "functional": "cpp",
"array": "cpp",
"atomic": "cpp",
"bit": "cpp",
"*.tcc": "cpp",
"cctype": "cpp",
"clocale": "cpp",
"cmath": "cpp",
"compare": "cpp",
"concepts": "cpp",
"cstdarg": "cpp",
"cstddef": "cpp",
"cstdint": "cpp",
"cstdio": "cpp",
"cstdlib": "cpp",
"cwchar": "cpp",
"cwctype": "cpp",
"deque": "cpp",
"string": "cpp",
"unordered_map": "cpp",
"vector": "cpp",
"exception": "cpp",
"algorithm": "cpp",
"iterator": "cpp",
"memory": "cpp",
"memory_resource": "cpp",
"numeric": "cpp",
"random": "cpp",
"string_view": "cpp",
"system_error": "cpp",
"tuple": "cpp",
"type_traits": "cpp",
"utility": "cpp",
"initializer_list": "cpp",
"iosfwd": "cpp",
"iostream": "cpp",
"istream": "cpp",
"limits": "cpp",
"new": "cpp",
"numbers": "cpp",
"ostream": "cpp",
"stdexcept": "cpp",
"streambuf": "cpp",
"cinttypes": "cpp",
"typeinfo": "cpp"
} }
} }

@ -0,0 +1,21 @@
-----BEGIN CERTIFICATE-----
MIIDazCCAlOgAwIBAgIUcmzC65mt2XxhXwskSJT7io+uesIwDQYJKoZIhvcNAQEL
BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM
GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yMzA1MjMxNjQzMDNaFw0yNDA1
MjIxNjQzMDNaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw
HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggEiMA0GCSqGSIb3DQEB
AQUAA4IBDwAwggEKAoIBAQCykD9egLZJuJ+4vWScFZJye4MGkAI0JEBjirLd5wmU
lMVp5gNdQy5OlyEu0YY5HfYj15fXu3bdjBIdMvR5b64SvNpomej5G2BctvB4iFfi
9r440MARGzckKoUve7M3q9lKQDYIGT4uuF3YVrXocNXPPViTsQDQPkmGzSY2O1Ay
gbBcvBDR034K+Yu2dS8AQ84/yBUIQnbpg1myAAXp5PQxHW2fQrQbGY/vy+orx1hE
eHE62+0h4dgpmQFUFXT8tTwolvEm6kCkOmj9LoHSkXAcJwBnybN43vInyhyRuteM
PfaYLBE8gov+CKQiAcpUSnLzj/j5H47hfifRgudUuLORAgMBAAGjUzBRMB0GA1Ud
DgQWBBRCJrbSSAB7K4nKtLZ5hFLiPjdLQTAfBgNVHSMEGDAWgBRCJrbSSAB7K4nK
tLZ5hFLiPjdLQTAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAi
CBwLMSqlB5uTlyjJMSbWw5qY1GKJtCGUAzHXlr6LnmqFgNl+BX4IDu8YaNilPqHZ
F4NhFwMZN9+FJZcyCG8lJ7sqIFge+KVG8jmP2SsA8qY/HyvzmDH0ZTDYxRGymzEH
ryVm8QXLR6ndqb75yK3CnN4tafuEz0ThObdzN1wIKRSUb+CjeuY2DFRqvrdmqnhg
tv3ZCW720yNOpaHTIzdObEM4BlqRBEXVXLJVWmY9vHWnZZMoiRnliv+y28Bh0pNH
JcMUvZfkJGPWBb50HucDziZLeGnEQjBMUW97OCSu6hx0nCDhK44ClmU6Eit+1xmu
MRoDLJeh59UFEvWylyXW
-----END CERTIFICATE-----

@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCykD9egLZJuJ+4
vWScFZJye4MGkAI0JEBjirLd5wmUlMVp5gNdQy5OlyEu0YY5HfYj15fXu3bdjBId
MvR5b64SvNpomej5G2BctvB4iFfi9r440MARGzckKoUve7M3q9lKQDYIGT4uuF3Y
VrXocNXPPViTsQDQPkmGzSY2O1AygbBcvBDR034K+Yu2dS8AQ84/yBUIQnbpg1my
AAXp5PQxHW2fQrQbGY/vy+orx1hEeHE62+0h4dgpmQFUFXT8tTwolvEm6kCkOmj9
LoHSkXAcJwBnybN43vInyhyRuteMPfaYLBE8gov+CKQiAcpUSnLzj/j5H47hfifR
gudUuLORAgMBAAECggEAS8QpH1A+CMnt+9Vg+1mr6ie+UOqKBNXc/F+9xapixkjZ
+zU9+DSpUW+PBO6ipVmxN0QjicZhiWAFz53vXhelJQ49HmUwFYMoQC7fmkVABW3t
CO6KkLebjhz8pkk2okioyni0dHtBh1FzgHhKd3ZpQqYlD4XrcnD7gddKf3hrbwIg
5pnr/QkPxeyli7hMUJJv2qWvaBtvqfhMqhjRH7T484CV6hEtURzuVAMgUB2hM4XP
Opjlp5pZAw/4eS2fXK7R4DypaiklOWo7K7u+twSvWTxNDqYRvmcKZ37zWuoKKAD0
/rTl5VjtF3yRRv43cxu/6wxF/KGjbkJ5hszeQAMQgQKBgQC3mkGqh0tW7zEf8s5n
iotLznjIpY6VpEJ4ehTiVz1IJc7URxyn2H7/cRok19rbg904uQJhrPCOyLWnmMxb
tdKTNaR/LczMe/rgTlBRyN577VxriEXHuU1fSzig5wvZIo3ZCbIJ13T5EvPbcVIi
/VEIk4zyEroU9OSNKT4m/Stj8wKBgQD4+VHekVWo4qpEW/mh9w7SKA2DDXdFFlcP
cn3jtyDRFa1e6so29HFTpy/2pF2+4Kb6o6cq04GhfDPQqY3Opn8/pChEP6Vp0qyj
SegbidCmIpsYKPyzJUTmGN+Y40Tk6XA3e9OK1eR0uAcm7Tq3FpObNvONJtd7i6AD
ckyop/afawKBgCWF/zms4Pbpd67B3vFGXWWm0wSe4V8v7O3WdYI0ti+SmozD49Vh
58KpCODSxMXsU0AOf7AauidUWdvg3JM5u8meQvpDEAISrJk/KCcu2FmXjzXi6fAB
rRB2vSIVVlSQPVFIK/za7eshtnj41gKUpwULstiefy1dR4CaFzu8riuFAoGAIua4
Xk3bRzB3E9wc02KRtk4dDsj9djbaf3TaRuit9gFm605YiHmdxU9Dfvytk4tkfPAi
B/PcUSnbDZ4nHdfjMKWva1nMs1fwEXfTzMB1+kQRn8JnIinQTb0g4wrA5qH+tBhs
oCK5ws7lWcSZnX7RtElwvNG8FTqOdM06B8572P8CgYBEZpdWLPKlS7cHnw506CaT
bZMgsI0RnXTgqlrlQR029/9zS3ocrmcOov+tOYDGLQnZjRJ1LxWUIIqPaJ5RvUua
pZu8tbvYNnyuI+Ugby6pUQIzFr6flQ2sJWVwoGEAX1f5LiffcXrkZ2F37c9ORCnA
g9V/U/i/RkSgH0cbouMPvg==
-----END PRIVATE KEY-----

@ -7,6 +7,8 @@
#include <arpa/inet.h> #include <arpa/inet.h>
#include <netdb.h> #include <netdb.h>
#include <unistd.h> #include <unistd.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include "ip.hpp" #include "ip.hpp"
@ -20,16 +22,25 @@ class server {
server (const ushort port, const uint limit = 1000); server (const ushort port, const uint limit = 1000);
~server (); ~server ();
}; };
class secure {
public:
SSL_CTX* fds;
secure(); // client
secure(const string cert, const string priv); //server
~secure();
};
class client { class client {
public: public:
int sock; int sock;
struct sockaddr_in addr; struct sockaddr_in addr;
SSL* ssl = NULL;
client (const string address, const ushort port); client (const string address, const ushort port, const uint timeout = 500, SSL_CTX* securefds = NULL);
~client (); ~client ();
bool tell (const string msg); bool tell (const string msg);
string obey (size_t byte_limit = 1024); string obey (size_t byte_limit = 1024);
@ -39,15 +50,18 @@ class client {
class comming { class comming {
public: public:
const server *srv; const server *srv;
struct sockaddr_in addr;
int conn; int conn;
string ipv4; string ipv4;
string ipv6; string ipv6;
SSL* ssl = NULL;
comming(const server *_srv, const uint timeout); comming(const server *_srv, const uint timeout = 100, SSL_CTX* securefds = NULL);
~comming(); ~comming();
bool tell (const string msg); bool tell (const string msg);
string obey (size_t byte_limit = 1024); string obey (size_t byte_limit = 1024);
}; };

@ -40,7 +40,47 @@ server::~server () {
} }
client::client(const string address, const ushort port) { secure::secure() {
fds = SSL_CTX_new(SSLv23_client_method());
if (!fds) {
//throw "[ERROR] Creating SSL context ";
cout << endl << "[ERROR] Creating SSL context ";
}
}
secure::secure(const string cert, const string priv) {
SSL_library_init();
SSL_load_error_strings();
OpenSSL_add_all_algorithms();
// Create an SSL context
fds = SSL_CTX_new(SSLv23_server_method());
if (!fds) {
// throw "[ERROR] Creating SSL context ";
cout << endl << "[ERROR] Creating SSL context ";
}
// Load the server's certificate and private key files
if (SSL_CTX_use_certificate_file(fds, cert.c_str(), SSL_FILETYPE_PEM) <= 0) {
// throw "[ERROR] Loading certificate file.";
cout << endl << "[ERROR] Loading certificate file.";
}
if (SSL_CTX_use_PrivateKey_file(fds, priv.c_str(), SSL_FILETYPE_PEM) <= 0) {
//throw "[ERROR] Loading private key file.";
cout << endl << "[ERROR] Loading private key file.";
}
}
secure::~secure () {
SSL_CTX_free(fds);
}
client::client(const string address, const ushort port, const uint timeout, SSL_CTX* securefds) {
sock = socket(AF_INET, SOCK_STREAM, 0); sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0) { if (sock < 0) {
@ -57,11 +97,41 @@ client::client(const string address, const ushort port) {
printf("[EROR] Ne mogu se povezati s poslužiteljem!"); printf("[EROR] Ne mogu se povezati s poslužiteljem!");
} }
struct timeval tv;
tv.tv_sec = 0; // za sad 2 sekunde timeout, harkodirano
tv.tv_usec = timeout*1000;
if (setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(struct timeval))) {
printf ("[ERROR] 503 Ne mogu postaviti timeout!");
sock = -1;
}
if (securefds) {
ssl = SSL_new(securefds);
if (!ssl) {
//throw "[ERROR] Creating SSL object.";
cout << endl << "[ERROR] Creating SSL object.";
}
SSL_set_fd(ssl, sock);
}
// Perform the SSL handshake
if (SSL_connect(ssl) <= 0) {
SSL_free(ssl);
// throw "[ERROR] Performing SSL handshake.";
cout << endl << "[ERROR] Performing SSL handshake.";
}
} }
client::~client () { client::~client () {
if (ssl) {
SSL_shutdown(ssl);
SSL_free(ssl);
}
if (sock <= 0) { if (sock <= 0) {
printf ("[ERROR] Soket destruktor: već zatvoren soket!"); printf ("[ERROR] Soket destruktor: već zatvoren soket!");
} }
@ -74,19 +144,32 @@ client::~client () {
bool client::tell (const string msg) { bool client::tell (const string msg) {
ssize_t sended = send(sock, msg.c_str(), msg.length(),0); size_t sended = 0;
if (ssl) {
sended = SSL_write(ssl, msg.c_str(), msg.length());
}
else {
sended = write(sock, msg.c_str(), msg.length());
}
return sended == msg.length(); return sended == msg.length();
} }
string client::obey (size_t byte_limit) { string client::obey (size_t byte_limit) {
char res[byte_limit] = {0}; char res[byte_limit] = {0};
ssize_t n = read ( sock , res, byte_limit);
if (ssl) {
SSL_read(ssl, res, byte_limit);
}
else {
read(sock , res, byte_limit);
}
return (string) res; return (string) res;
} }
comming::comming(const server *_srv, const uint timeout) { comming::comming(const server *_srv, const uint timeout, SSL_CTX* securefds) {
srv = _srv; srv = _srv;
socklen_t len = sizeof(struct sockaddr_in); socklen_t len = sizeof(struct sockaddr_in);
@ -94,6 +177,31 @@ comming::comming(const server *_srv, const uint timeout) {
printf("[ERROR] Ne mogu preuzeti vezu klijenta!"); printf("[ERROR] Ne mogu preuzeti vezu klijenta!");
} }
struct timeval tv;
tv.tv_sec = 1; // za sad 2 sekunde timeout, harkodirano
tv.tv_usec = 0;
if (setsockopt(conn, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(struct timeval))) {
printf("[ERROR] 503 Ne mogu postaviti timeout!");
conn = -1;
}
if (securefds) {
ssl = SSL_new(securefds);
if (!ssl) {
// throw "[ERROR] Creating SSL object.";
cout << endl << "[ERROR] Creating SSL object.";
}
SSL_set_fd(ssl, conn);
// Perform SSL handshake
if (SSL_accept(ssl) <= 0) {
SSL_free(ssl);
// throw "[ERROR] Performing SSL handshake.";
cout << endl << "[ERROR] Performing SSL handshake.";
}
}
char ipv4_buff[INET_ADDRSTRLEN]; char ipv4_buff[INET_ADDRSTRLEN];
char ipv6_buff[INET6_ADDRSTRLEN]; char ipv6_buff[INET6_ADDRSTRLEN];
@ -106,6 +214,12 @@ comming::comming(const server *_srv, const uint timeout) {
} }
comming::~comming() { comming::~comming() {
if (ssl) {
SSL_shutdown(ssl);
SSL_free(ssl);
}
if (conn <= 0) { if (conn <= 0) {
printf ("[ERROR] Comming destruktor: već zatvoren soket!"); printf ("[ERROR] Comming destruktor: već zatvoren soket!");
} }
@ -116,12 +230,25 @@ comming::~comming() {
} }
bool comming::tell (const string msg) { bool comming::tell (const string msg) {
ssize_t sended = send(conn, msg.c_str(), msg.length(),0); ssize_t sended = 0;
if (ssl) {
sended = SSL_write(ssl, msg.c_str(), msg.length());
}
else {
sended = write(conn, msg.c_str(), msg.length());
}
return sended == msg.length(); return sended == msg.length();
} }
string comming::obey (size_t byte_limit) { string comming::obey (size_t byte_limit) {
char res[byte_limit] = {0}; char res[byte_limit] = {0};
ssize_t n = read ( conn , res, byte_limit);
if (ssl) {
SSL_read(ssl, res, byte_limit);
}
else {
read(conn , res, byte_limit);
}
return (string) res; return (string) res;
} }

@ -6,10 +6,12 @@ using namespace std;
int main() { int main() {
client myserver("localhost", 5000); secure crypto;
string sends = "Hello wld!"; client myserver("localhost", 5000, 500, crypto.fds);
string sends = "Hello world!";
cout << myserver.tell(sends) << " " << sends.length() << endl; cout << myserver.tell(sends) << " " << sends.length() << endl;
cout << myserver.obey(); cout << myserver.obey();
return 0; return 0;
} }

Binary file not shown.

@ -1 +1 @@
g++ client.cpp ../src/* -o client.o g++ client.cpp ../src/* -o client.o -lssl -lcrypto

@ -1 +1 @@
g++ server.cpp ../src/* -o server.o g++ server.cpp ../src/* -o server.o -lssl -lcrypto

@ -6,21 +6,31 @@ using namespace std;
int main() { int main() {
cout << "init server " << endl;
server myserver(5000, 10); server myserver(5000, 10);
comming myclient(&myserver, 1000); cout << "init cert " << endl;
secure crypto ("../example/cert.pem", "../example/privkey.pem");
cout << "init client " << endl;
comming myclient(&myserver, 1000, crypto.fds);
cout << "wait client " << myclient.ipv4 << endl;
string fromclient = myclient.obey(); string fromclient = myclient.obey();
cout << "tell client " << fromclient << endl;
sleep(5);
myclient.tell(fromclient); myclient.tell(fromclient);
myclient.~comming(); // myclient.~comming();
while (true) { // while (true) {
comming myclient(&myserver, 1000); // comming myclient(&myserver, 1000);
string fromclient = myclient.obey(); // string fromclient = myclient.obey();
cout << fromclient << " " << myclient.conn << endl; // cout << fromclient << " " << myclient.conn << endl;
cout << "Poslano: " << myclient.tell(fromclient) << "Veličin: " << fromclient.length() << endl; // cout << "Poslano: " << myclient.tell(fromclient) << "Veličin: " << fromclient.length() << endl;
// myclient.~comming(); // // myclient.~comming();
cout << "IPv4 " << myclient.ipv4 << " ipv6 " << myclient.ipv6; // cout << "IPv4 " << myclient.ipv4 << " ipv6 " << myclient.ipv6;
} // }
// sleep(80);
return 0; return 0;

Binary file not shown.
Loading…
Cancel
Save