not yet compiling, but code is complete

This commit is contained in:
overflowerror 2019-03-10 23:15:12 +01:00
parent b246687b2e
commit 4399dd9001
7 changed files with 239 additions and 3 deletions

View file

@ -10,6 +10,11 @@ DEPS = $(OBJS:%.o=%.d)
all: $(BIN_NAME)
ssl: CFLAGS += -DSSL_SUPPORT -Icrypto
ssl: LDFLAGS += -lcrypto
ssl: OBJS += obj/ssl.o
ssl: $(BIN_NAME)
$(BIN_NAME): obj/main.o $(OBJS)
$(LD) $(LDFLAGS) -o $@ $^

View file

@ -10,6 +10,10 @@
#include "cgi.h"
#include "util.h"
#ifdef SSL_SUPPORT
#include "ssl.h"
#endif
struct handlerSettings {
struct fileSettings fileSettings;
struct cgiSettings cgiSettings;
@ -78,7 +82,11 @@ int main(int argc, char** argv) {
{
.address = "0.0.0.0",
.port = "1337",
.settings = settingsData
.settings = settingsData,
#ifdef SSL_SUPPORT
.ssl_settings = NULL
#endif
}
}
},

View file

@ -7,6 +7,10 @@
#include <arpa/inet.h>
#ifdef SSL_SUPPORT
#include "ssl.h"
#endif
#define PTHREAD_NULL ((pthread_t) 0)
enum method {
@ -46,6 +50,11 @@ struct bind {
const char* port;
bool tls;
union userData settings;
#ifdef SSL_SUPPORT
struct ssl_settings* ssl_settings;
#endif
struct bind_private _private;
};

View file

@ -19,6 +19,10 @@
#include "status.h"
#include "util.h"
#ifdef SSL_SUPPORT
#include "ssl.h"
#endif
struct networkingConfig networkingConfig;
static inline long timespecDiffMs(struct timespec start, struct timespec end) {
@ -92,6 +96,12 @@ void cleanup() {
struct connection* connection = link->data;
if (connection->inUse == 0) {
freed++;
#ifdef SSL_SUPPORT
if (connection->sslConnection != NULL)
ssl_closeConnection(connection->sslConnection);
#endif
if (connection->metaData.path != NULL)
free(connection->metaData.path);
if (connection->metaData.queryString != NULL)
@ -647,6 +657,7 @@ void* listenThread(void* _bind) {
}
if (inet_ntop(family, addrPtr, &(peer.addr[0]), INET6_ADDRSTRLEN + 1) == NULL) {
free(connection);
error("networking: Couldn't set peer addr string: %s", strerror(errno));
return NULL;
}
@ -671,11 +682,28 @@ void* listenThread(void* _bind) {
snprintf(&(peer.portStr[0]), 5 + 1, "%d", peer.port);
#ifdef SSL_SUPPORT
if (bindObj->ssl_settings != NULL) {
struct ssl_connection* sslConnection = ssl_initConnection(bindObj->ssl_settings, tmp);
if (sslConnection == NULL) {
free(connection);
error("networking: failed to open ssl connection");
continue;
}
connection->sslConnection = sslConnection;
connection->readfd = sslConnection->readfd;
connection->writefd = sslConnection->writefd;
} else {
connection->sslConnection = NULL;
connection->readfd = tmp;
connection->writefd = tmp;
}
#endif
connection->state = OPENED;
connection->peer = peer;
connection->bind = bindObj;
connection->readfd = tmp;
connection->writefd = tmp;
connection->metaData = (struct metaData) {
.path = NULL,
.queryString = NULL

View file

@ -12,6 +12,10 @@
#include "headers.h"
#include "misc.h"
#ifdef SSL_SUPPORT
#include "ssl.h"
#endif
#define NR_CONNECTION_STATE (5)
enum connectionState {
OPENED = 0,
@ -52,6 +56,9 @@ struct connection {
char* currentHeader;
struct timing timing;
struct threads threads;
#ifdef SSL_SUPPORT
struct ssl_connection* sslConnection;
#endif
};
struct binds {

147
src/ssl.c Normal file
View file

@ -0,0 +1,147 @@
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
#include <openssl/applink.c>
#include <openssl/bio.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include "ssl.h"
#include "logging.h"
void ssl_init() {
SSL_load_error_strings();
SSL_library_init();
OpenSSL_add_all_algorithms();
}
void ssl_destroy() {
ERR_free_strings();
EVP_cleanup();
}
int ssl_initSettings(struct ssl_settings* settings) {
SSL_CTX* ctx = SSL_CTX_new( SSLv23_server_method());
SSL_CTX_set_options(ctx, SSL_OP_SINGLE_DH_USE);
if (!SSL_CTX_use_certificate_file(sslctx, settings->certificate, SSL_FILETYPE_PEM)) {
error("ssl: failed to set cert file for ctx: %s", ERR_error_string(ERR_get_error(), NULL));
return -1;
}
if (!SSL_CTX_use_PrivateKey_file(ctx, settings->privateKey, SSL_FILETYPE_PEM)) {
error("ssl: failed to set key file for ctx: %s", ERR_error_string(ERR_get_error(), NULL));
return -1;
}
_private.ctx = ctx;
return 0;
}
void* copyFromSslToFd(void* data) {
struct ssl_connection* connection = (struct ssl_connection*) data;
char b;
while(SSL_read(connection->instance, &b, 1) == 1) {
write(connection->_readfd, &b, 1);
}
close(connection->_writefd);
}
void* copyFromFdToSsl(void* data) {
struct ssl_connection* connection = (struct ssl_connection*) data;
char b;
while(read(connection->_writefd, &b, 1) == 1) {
SSL_write(connection->instance, &b, 1);
}
}
struct ssl_connection* ssl_initConnection(struct ssl_settings* settings, int socket) {
struct ssl_connection* connection = malloc(sizeof(struct ssl_connection));
if (connection == NULL) {
error("ssl: couldn't allocate for ssl connection: %s", strerror(errno));
return NULL;
}
connection->writefd = -1;
connection->readfd = -1;
connection->_writefd = -1;
connection->_readfd = -1;
connection->_threads[0] = PTHREAD_NULL;
connection->_threads[1] = PTHREAD_NULL;
connection->instance = SSL_new(settings->_private.ctx);
if (connection->instance == NULL) {
free(connection);
error("ssl: failed to create new connection: %s", ERR_error_string(ERR_get_error(), NULL));
return NULL;
}
SSL_set_fd(connection->instance, socket);
if (SSL_accept(connection->instance) < 0) {
ssl_closeConnection(connection);
error("ssl: couldn't accept ssl connection: %s", ERR_error_string(ERR_get_error(), NULL));
return NULL;
}
int pipefd[2];
if (pipe(&(pipefd[0])) < 0) {
ssl_closeConnection(connection);
error("ssl: couldn't create pipe: %s", strerror(errno));
return NULL;
}
connection->writefd = pipefd[1];
connection->_writefd = pipefd[0];
if (pipe(&(pipefd[0])) < 0) {
ssl_closeConnection(connection);
error("ssl: couldn't create pipe: %s", strerror(errno));
return NULL;
}
connection->_readfd = pipefd[1];
connection->readfd = pipefd[0];
if (pthread_create(&(connection->_threads[0]), NULL, &copyFromSslToFd, connection) < 0) {
ssl_closeConnection(connection);
error("ssl: couldn't create copyToFd-thread");
return NULL;
}
if (pthread_create(&(connection->_threads[1]), NULL, &copyFromFdToSsl, connection) < 0) {
ssl_closeConnection(connection);
error("ssl: couldn't create copyToSsl-thread");
return NULL;
}
return connection;
}
int ssl_closeConnection(struct ssl_connection* connection) {
close(connection->writefd);
close(connection->readfd);
close(connection->_writefd);
close(connection->_readfd);
if (connection->_threads[0] != PTHREAD_NULL) {
pthread_cancel(connection->_threads[0]);
pthread_join(connection->_threads[0]);
}
if (connection->_threads[1] != PTHREAD_NULL) {
pthread_cancel(connection->_threads[1]);
pthread_join(connection->_threads[1]);
}
SSL_shutdown(connection->instance);
SSL_free(connection->instance);
free(connection);
}

32
src/ssl.h Normal file
View file

@ -0,0 +1,32 @@
#ifndef SSL_H
#define SSL_H
#include <pthread.h>
#include <openssl/ssl.h>
struct ssl_connection {
SSL* instance;
int readfd;
int writefd;
int _readfd;
int _writefd;
pthread_t _threads[2];
};
struct ssl_settings {
const char* privateKey;
const char* certificate;
struct {
SSL_CTX* ctx;
} _private;
};
void ssl_init();
void ssl_destroy();
int ssl_initSettings(struct ssl_settings* settings);
struct ssl_connection* ssl_initConnection(struct ssl_settings* settings, int socket);
int ssl_closeConnection(struct ssl_connection* connection);
#endif