mirror of
https://github.com/sigmasternchen/CFloor
synced 2025-03-15 04:18:55 +00:00
not yet compiling, but code is complete
This commit is contained in:
parent
b246687b2e
commit
4399dd9001
7 changed files with 239 additions and 3 deletions
5
Makefile
5
Makefile
|
@ -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 $@ $^
|
||||
|
||||
|
|
10
src/main.c
10
src/main.c
|
@ -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
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
147
src/ssl.c
Normal 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, ©FromSslToFd, connection) < 0) {
|
||||
ssl_closeConnection(connection);
|
||||
error("ssl: couldn't create copyToFd-thread");
|
||||
return NULL;
|
||||
}
|
||||
if (pthread_create(&(connection->_threads[1]), NULL, ©FromFdToSsl, 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
32
src/ssl.h
Normal 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
|
Loading…
Reference in a new issue