commit 66046d1bf1b0b4c2f421389510bed001e142993a
parent db981a13c3bc35f7114644bbc785a9b62a68f762
Author: Remy Noulin <loader2x@gmail.com>
Date: Fri, 19 Aug 2022 02:51:10 -0400
use tls encryption when transfering data
genCert.sh | 2 +-
netFrame.c | 50 +++++++++-----------------
netFrame.h | 9 ++---
package.yml | 6 ++--
sclient.c | 54 ++++++++++++++++++++--------
serverPackage.yml | 6 ++--
sserver.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++--------
7 files changed, 156 insertions(+), 74 deletions(-)
Diffstat:
7 files changed, 156 insertions(+), 74 deletions(-)
diff --git a/genCert.sh b/genCert.sh
@@ -1 +1 @@
-LD_LIBRARY_PATH=/usr/local/lib64/ openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -sha256 -days 365 -nodes -subj '/CN=localhost'
+openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -sha256 -days 365 -nodes -subj '/CN=localhost'
diff --git a/netFrame.c b/netFrame.c
@@ -2,7 +2,6 @@
/* Libsheepy documentation: https://spartatek.se/libsheepy/ */
-#include "libsheepyObject.h"
#include "netFrame.h"
#include "netFrameInternal.h"
@@ -23,10 +22,10 @@ local void smashNetFrame(netFramet **self);
local void finishNetFrame(netFramet **self);
local const char* helpNetFrame(netFramet *self);
local void setCallbackNetFrame(netFramet *self, callBackNetFramet callback, void* context);
-local bool sendNetFrame(netFramet *self, int sock, void* buf, size_t size);
-local bool receiveNetFrame(netFramet *self, int sock);
-local bool receiveOneNetFrame(netFramet *self, int sock);
-local bool endNetFrame(netFramet *self, int sock);
+local bool sendNetFrame(netFramet *self, SSL *ssl, void* buf, size_t size);
+local bool receiveNetFrame(netFramet *self, SSL *ssl);
+local bool receiveOneNetFrame(netFramet *self, SSL *ssl);
+local bool endNetFrame(netFramet *self, SSL *ssl);
/* enable/disable logging */
/* #undef pLog */
@@ -161,25 +160,15 @@ local void setCallbackNetFrame(netFramet *self, callBackNetFramet callback, void
}
-local bool sendNetFrame(netFramet *self UNUSED, int sock, void* buf, size_t size) {
+local bool sendNetFrame(netFramet *self UNUSED, SSL *ssl, void* buf, size_t size) {
ssize_t status; // for netsend
#define netsend(B,SZ,FLGS) procbegin\
UNIQVAR(retry):\
- if ((status = send(sock, B, SZ, (FLGS) | MSG_NOSIGNAL)) < 0) {\
- if (errno == EAGAIN or errno == EINTR) {\
- /* TODO this happens when the socket is in nonblocking mode */\
- /* in my tests, there are data losses when size is larger than 1MBytes */\
- /* this is a simple solution equivalent to blocking */\
- /* a better solution is to keep running in the event loop */\
- /* for large transfers */\
- /* When EINTR is received, the send call was interrupted by a signal */\
- /* restart the send call when it happens */\
- goto UNIQVAR(retry);\
- }\
- shPrintError;\
- shperror("Netframe send socket error");\
+ if ((status = SSL_write(ssl, B, SZ)) < 0) {\
+ /* TODO SSL_get_error() */\
+ shperror("Netframe send ssl error");\
ret no;\
}\
procend
@@ -203,7 +192,7 @@ local bool sendNetFrame(netFramet *self UNUSED, int sock, void* buf, size_t size
}
-local bool receiveNetFrame(netFramet *self, int sock) {
+local bool receiveNetFrame(netFramet *self, SSL *ssl) {
if (!self->callback) ret no;
size_t size;
@@ -212,17 +201,8 @@ local bool receiveNetFrame(netFramet *self, int sock) {
#define netrecv(B, SZ, FLGS, CHECK, ENOUGH, ERROR) procbegin\
UNIQVAR(retry):\
- if ((status = recv(sock, B, SZ, FLGS)) < 0) {\
- if (errno == EAGAIN or errno == EINTR) {\
- /* TODO this happens when the socket is in nonblocking mode */\
- /* this is a simple solution equivalent to blocking */\
- /* a better solution is to keep running in the event loop */\
- /* for large transfers */\
- /* When EINTR is received, the recv call was interrupted by a signal */\
- /* restart the recv call when it happens */\
- goto UNIQVAR(retry);\
- }\
- shPrintError;\
+ if ((status = SSL_read(ssl, B, SZ)) < 0) {\
+ /* TODO SSL_get_error() */\
shperror("Netframe recv socket error");\
ERROR;\
ret no;\
@@ -241,6 +221,7 @@ local bool receiveNetFrame(netFramet *self, int sock) {
if (isFirstFrame) {
/* the first frame has size 0, this is a request to close the connection */
logD("close socket");
+ int sock = SSL_get_fd(ssl);
close(sock);
}
break;
@@ -268,7 +249,7 @@ local bool receiveNetFrame(netFramet *self, int sock) {
ret yes;
}
-local bool receiveOneNetFrame(netFramet *self, int sock) {
+local bool receiveOneNetFrame(netFramet *self, SSL *ssl) {
if (!self->callback) ret no;
size_t size;
@@ -281,6 +262,7 @@ local bool receiveOneNetFrame(netFramet *self, int sock) {
if (!size) {
// a frame size 0 is a request to close the connection
logD("close socket");
+ int sock = SSL_get_fd(ssl);
close(sock);
ret yes;
}
@@ -302,8 +284,8 @@ local bool receiveOneNetFrame(netFramet *self, int sock) {
ret yes;
}
-local bool endNetFrame(netFramet *self, int sock) {
- ret sendNetFrame(self, sock, null, 0);
+local bool endNetFrame(netFramet *self, SSL *ssl) {
+ ret sendNetFrame(self, ssl, null, 0);
}
diff --git a/netFrame.h b/netFrame.h
@@ -42,6 +42,7 @@
* receive waits for frames until a frame size 0 is received
*/
+#include <openssl/ssl.h>
#include "libsheepyObject.h"
/* Class netFrame */
@@ -87,17 +88,17 @@ typ void (*setCallbackNetFrameFt)(netFramet *self, callBackNetFramet callback, v
/**
* send buf, size 0 means end of transaction
*/
-typ bool (*sendNetFrameFt)(netFramet *self, int sock, void* buf, size_t size);
+typ bool (*sendNetFrameFt)(netFramet *self, SSL *ssl, void* buf, size_t size);
/**
* receive frames until the socket is closed by the client
*/
-typ bool (*receiveNetFrameFt)(netFramet *self, int sock);
+typ bool (*receiveNetFrameFt)(netFramet *self, SSL *ssl);
/**
* receive one frame and return
*/
-typ bool (*receiveOneNetFrameFt)(netFramet *self, int sock);
+typ bool (*receiveOneNetFrameFt)(netFramet *self, SSL *ssl);
/**
* end transaction or inform the server that the connection is going to be closed
@@ -110,7 +111,7 @@ typ bool (*receiveOneNetFrameFt)(netFramet *self, int sock);
* - when finished send a frame size 0 meaning end of transaction
* - to close the connection, send a frame size 0 again
*/
-typ bool (*endNetFrameFt)(netFramet *self, int sock);
+typ bool (*endNetFrameFt)(netFramet *self, SSL *ssl);
/**
* class functions
diff --git a/package.yml b/package.yml
@@ -1,10 +1,10 @@
---
name: tuyau
- version: 0.0.3
+ version: 0.0.4
description: "Client for copying files to tuyauServer"
bin: ./tuyau.c
#cflags: -DA -g3 -std=gnu11 -fPIC -pipe
- #lflags: -lpcre
+ lflags: -L/usr/lib -lssl -lcrypto
repository:
type: git
url: git+https://github.com/USER/tuyau.git
@@ -16,7 +16,7 @@
bugs:
url: https://github.com/USER/tuyau/issues
homepage: https://github.com/USER/tuyau#readme
- #compileHelp: # text displayed when there is a compilation error
+ compileHelp: libssl-dev has to be installed in the system
dependencies:
short:
# Test configuration:
diff --git a/sclient.c b/sclient.c
@@ -22,7 +22,6 @@ Downdload files:
*/
-#include "libsheepyObject.h"
#include <netdb.h>
#include <netinet/in.h>
#include <string.h>
@@ -34,7 +33,16 @@ Downdload files:
#include <sys/stat.h>
#include <fcntl.h>
+// basename
+#include <libgen.h>
+
+#include <openssl/err.h>
+//#include <openssl/pem.h>
+#include <openssl/ssl.h>
+//#include <openssl/x509v3.h>
+
#include "netFrame.h"
+#include "libsheepyObject.h"
#include "shpPackages/short/short.h"
#include "makeHeader.h"
@@ -158,6 +166,7 @@ int main(int ARGC, char** ARGV) {
struct hostent *hp;
int rval;
+
cleanAllocateNetFrame(netframe);
@@ -184,6 +193,20 @@ int main(int ARGC, char** ARGV) {
XFailure;
}
+ SSL_CTX *ssl_ctx;
+ SSL *ssl;
+ ssl_ctx = SSL_CTX_new(TLS_method());
+ BIO *sbio = BIO_new(BIO_f_ssl());
+ ssl = SSL_new(ssl_ctx);
+ // attach the socket descriptor
+ SSL_set_fd(ssl, sock);
+
+ // perform the connection
+ if (SSL_connect(ssl) == -1) {
+ logE("Couldn't establish the TLS connection");
+ ret 1;
+ }
+
// buffer for network packets
u8 buf[1024*1024] = init0Var;
@@ -193,11 +216,11 @@ int main(int ARGC, char** ARGV) {
u32 bufi = 0;
makeHeader(buf, &bufi, 2 /* command */, svrInfo, null /*sendFile*/, destPath, null /*filesize*/);
- o(netframe,send , sock, buf, bufi);
+ o(netframe,send , ssl, buf, bufi);
o(netframe, setCallback, saveReceivedData, receivePath /*context*/);
- var r = o(netframe,receive, sock);
+ var r = o(netframe,receive, ssl);
logVarG(r);
}
@@ -235,7 +258,7 @@ int main(int ARGC, char** ARGV) {
u64 *filesize = null;
makeHeader(buf, &bufi, 1 /* command */, svrInfo, ssGet(p), dest, &filesize);
- o(netframe,send , sock, buf, bufi);
+ o(netframe,send , ssl, buf, bufi);
var dir = readDirAllG(rtSmallArrayt, p);
//lv(dir);
@@ -256,7 +279,7 @@ int main(int ARGC, char** ARGV) {
if (*filesize < (sizeof(buf) - bufi)) {
// the file is smaller than the network buffer, send all in one go
pError0(bReadFile(sendFile, buf + bufi));
- o(netframe,send , sock, buf, bufi + *filesize);
+ o(netframe,send , ssl, buf, bufi + *filesize);
}
else {
logD("big file");
@@ -268,16 +291,16 @@ int main(int ARGC, char** ARGV) {
do {
if (szToSend <= bSz) {
read(fd, b, szToSend);
- o(netframe,send , sock, b, szToSend);
+ o(netframe,send , ssl, b, szToSend);
szToSend = 0;
}
else {
read(fd, b, bSz);
if (szToSend == *filesize) {
- o(netframe,send , sock, buf, bufi + bSz);
+ o(netframe,send , ssl, buf, bufi + bSz);
}
else {
- o(netframe,send , sock, b, bSz);
+ o(netframe,send , ssl, b, bSz);
}
szToSend -= bSz;
}
@@ -312,7 +335,7 @@ int main(int ARGC, char** ARGV) {
u64 *filesize = null;
makeHeader(buf, &bufi, 1 /* command */, svrInfo, localp, dest, &filesize);
- o(netframe,send , sock, buf, bufi);
+ o(netframe,send , ssl, buf, bufi);
var dir = readDirAllG(rtSmallArrayt, localp);
lv(dir);
@@ -335,7 +358,7 @@ int main(int ARGC, char** ARGV) {
if (*filesize < (sizeof(buf) - bufi)) {
// the file is smaller than the network buffer, send all in one go
pError0(bReadFile(localp, buf + bufi));
- o(netframe,send , sock, buf, bufi + *filesize);
+ o(netframe,send , ssl, buf, bufi + *filesize);
}
else {
logD("big file");
@@ -347,16 +370,16 @@ int main(int ARGC, char** ARGV) {
do {
if (szToSend <= bSz) {
read(fd, b, szToSend);
- o(netframe,send , sock, b, szToSend);
+ o(netframe,send , ssl, b, szToSend);
szToSend = 0;
}
else {
read(fd, b, bSz);
if (szToSend == *filesize) {
- o(netframe,send , sock, buf, bufi + bSz);
+ o(netframe,send , ssl, buf, bufi + bSz);
}
else {
- o(netframe,send , sock, b, bSz);
+ o(netframe,send , ssl, b, bSz);
}
szToSend -= bSz;
}
@@ -369,11 +392,14 @@ int main(int ARGC, char** ARGV) {
lv(recusive);
// last frame size 0
- o(netframe,end, sock);
+ o(netframe,end, ssl);
} // isReceive
close(sock);
+ // release SSL state
+ SSL_free(ssl);
+ SSL_CTX_free(ssl_ctx);
}
diff --git a/serverPackage.yml b/serverPackage.yml
@@ -1,10 +1,10 @@
---
name: tuyauServer
- version: 0.0.2
+ version: 0.0.3
description: "Server for copying files with tuyau"
bin: ./tuyauServer.c
#cflags: -DA -g3 -std=gnu11 -fPIC -pipe
- #lflags: -lpcre
+ lflags: -L/usr/lib -lssl -lcrypto
repository:
type: git
url: git+https://github.com/USER/tuyau.git
@@ -16,7 +16,7 @@
bugs:
url: https://github.com/USER/tuyau/issues
homepage: https://github.com/USER/tuyau#readme
- #compileHelp: # text displayed when there is a compilation error
+ compileHelp: libssl-dev has to be installed in the system
dependencies:
short:
# Test configuration:
diff --git a/sserver.c b/sserver.c
@@ -2,7 +2,6 @@
/* or direct path to sheepy: #! /usr/local/bin/sheepy */
/* Libsheepy documentation: https://spartatek.se/libsheepy/ */
-#include "libsheepyObject.h"
#include <netinet/in.h>
#include <string.h>
#include <stdlib.h>
@@ -15,6 +14,20 @@
#include <glob.h>
+#include <openssl/err.h>
+//#include <openssl/pem.h>
+#include <openssl/ssl.h>
+//#include <openssl/x509v3.h>
+
+// inet_ntoa
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+// basename
+#include <libgen.h>
+
+#include "libsheepyObject.h"
#include "netFrame.h"
#include "shpPackages/short/short.h"
#include "makeHeader.h"
@@ -26,6 +39,7 @@ int fd = -1;
u64 transferSz = 0;
// client socket
int mysock = 0;
+SSL *ssl;
smallJsont *tokens = null;
@@ -40,11 +54,53 @@ bool cb(void *buf, size_t size, void *context) {
ret yes;
}
+void loadCertificates(SSL_CTX* ctx, char* certFilename, char* keyFilename)
+{
+ // set the local certificate
+ if (SSL_CTX_use_certificate_file(ctx, certFilename, SSL_FILETYPE_PEM) <= 0) {
+ logC("Error loadind cert file %s", certFilename);
+ XFailure;
+ }
+ // set the private key
+ if (SSL_CTX_use_PrivateKey_file(ctx, keyFilename, SSL_FILETYPE_PEM) <= 0) {
+ logC("Error loadind key file %s", keyFilename);
+ XFailure;
+ }
+ /* verify private key */
+ if (!SSL_CTX_check_private_key(ctx)) {
+ logC("Private key does not match the public certificate", keyFilename);
+ XFailure;
+ }
+}
+
int main(int ARGC, char** ARGV) {
initLibsheepy(ARGV[0]);
setLogMode(LOG_FUNC);
+ SSL_CTX *ctx;
+ ctx = SSL_CTX_new(TLS_server_method());
+ int r = SSL_CTX_set_min_proto_version(ctx, TLS1_3_VERSION);
+ if (!SSL_CTX_set_min_proto_version(ctx, TLS1_3_VERSION)) {
+ logE("Can't force minimum TLS 1.3");
+ ret 1;
+ }
+ if (!SSL_CTX_set_cipher_list(ctx,
+ "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:"
+ "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:"
+ "ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:"
+ "DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:"
+ "TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:"
+ "TLS_CHACHA20_POLY1305_SHA256")) {
+ logE("Can't set cipher list");
+ ret 1;
+ }
+
+ SSL_CTX_set_options(ctx, SSL_OP_NO_RENEGOTIATION);
+
+ loadCertificates(ctx, "cert.pem", "key.pem");
+
+
// Steps
// load configuration
// create tokens dict
@@ -93,15 +149,32 @@ int main(int ARGC, char** ARGV) {
// start event loop
listen(sock, 5);
forever {
- mysock = accept(sock, (struct sockaddr *)0, 0);
+ struct sockaddr_in addr;
+ socklen_t len = sizeof(addr);
+ mysock = accept(sock, (struct sockaddr *)&addr, &len);
if (mysock == 1)
perror("accept failed");
else {
- var r = o(netframe,receive, mysock);
- logVarG(r);
+ logI("Connection: %s:%d",inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
+ // get new SSL state with context
+ ssl = SSL_new(ctx);
+ // set connection socket to SSL state
+ SSL_set_fd(ssl, mysock);
+ // do SSL-protocol accept
+ if (SSL_accept(ssl) == -1) {
+ logE("Accept SSL connection");
+ }
+ else {
+ var r = o(netframe,receive, ssl);
+ logVarG(r);
+ }
+ // release SSL state
+ SSL_free(ssl);
}
}
+ SSL_CTX_free(ctx);
+
terminateG(tokens);
}
@@ -278,7 +351,7 @@ void saveReceivedData(void *receiveB, size_t sz) {
u64 *filesize = null;
makeHeader(buf, &bufi, 1 /* command */, null/*svrInfo no need to authenticate the client*/, ssGet(P), dirname/*dest*/, &filesize);
- o(netframe,send , mysock, buf, bufi);
+ o(netframe,send , ssl, buf, bufi);
var dir = readDirAllG(rtSmallArrayt, p);
//lv(dir);
@@ -299,7 +372,7 @@ void saveReceivedData(void *receiveB, size_t sz) {
if (*filesize < (sizeof(buf) - bufi)) {
// the file is smaller than the network buffer, send all in one go
pError0(bReadFile(sendFile, buf + bufi));
- o(netframe,send , mysock, buf, bufi + *filesize);
+ o(netframe,send , ssl, buf, bufi + *filesize);
}
else {
logD("big file");
@@ -311,16 +384,16 @@ void saveReceivedData(void *receiveB, size_t sz) {
do {
if (szToSend <= bSz) {
read(fd, b, szToSend);
- o(netframe,send , mysock, b, szToSend);
+ o(netframe,send , ssl, b, szToSend);
szToSend = 0;
}
else {
read(fd, b, bSz);
if (szToSend == *filesize) {
- o(netframe,send , mysock, buf, bufi + bSz);
+ o(netframe,send , ssl, buf, bufi + bSz);
}
else {
- o(netframe,send , mysock, b, bSz);
+ o(netframe,send , ssl, b, bSz);
}
szToSend -= bSz;
}
@@ -353,7 +426,7 @@ void saveReceivedData(void *receiveB, size_t sz) {
u64 *filesize = null;
makeHeader(buf, &bufi, 1 /* command */, null/*svrInfo no need to authenticate the client*/, localp, dirname, &filesize);
- o(netframe,send , mysock, buf, bufi);
+ o(netframe,send , ssl, buf, bufi);
var dir = readDirAllG(rtSmallArrayt, localp);
lv(dir);
@@ -375,7 +448,7 @@ void saveReceivedData(void *receiveB, size_t sz) {
if (*filesize < (sizeof(buf) - bufi)) {
// the file is smaller than the network buffer, send all in one go
pError0(bReadFile(localp, buf + bufi));
- o(netframe,send , mysock, buf, bufi + *filesize);
+ o(netframe,send , ssl, buf, bufi + *filesize);
}
else {
logD("big file");
@@ -387,16 +460,16 @@ void saveReceivedData(void *receiveB, size_t sz) {
do {
if (szToSend <= bSz) {
read(fd, b, szToSend);
- o(netframe,send , mysock, b, szToSend);
+ o(netframe,send , ssl, b, szToSend);
szToSend = 0;
}
else {
read(fd, b, bSz);
if (szToSend == *filesize) {
- o(netframe,send , mysock, buf, bufi + bSz);
+ o(netframe,send , ssl, buf, bufi + bSz);
}
else {
- o(netframe,send , mysock, b, bSz);
+ o(netframe,send , ssl, b, bSz);
}
szToSend -= bSz;
}
@@ -410,7 +483,7 @@ void saveReceivedData(void *receiveB, size_t sz) {
// last frame size 0
// close connection
- o(netframe,end, mysock);
+ o(netframe,end, ssl);
}
}
else {