OAuth2Lib/server.c

142 lines
3.3 KiB
C

#include "server.h"
#include <stdatomic.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <openssl/err.h>
#include "log.h"
#include "ssl.h"
#include "util/thread_queue.h"
#define MODULE_NAME "login_server"
#define SERVER_PORT 443
static const char message[] = "<html><body><h1>Hello World!</h1></body></html>";
static SSL_CTX* _ssl_server_ctx = NULL;
static struct logger_s _logger;
static pthread_t *_server_thread = NULL;
static struct threadqueue _server_thread_queue;
_Atomic enum server_state _server_state = SERVER_NOT_STARTED;
static enum server_start_return _server_thread_func(void* data) {
atomic_store(&_server_state, SERVER_STARTING);
struct sockaddr_in sockaddr = {
.sin_family = AF_INET,
.sin_port = htons(SERVER_PORT),
.sin_addr = {
.s_addr = htonl(INADDR_ANY)
}
};
int sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0) {
log_log(MODULE_NAME, LOG_ERR, "Failed to create socket: %s", strerror(errno));
atomic_store(&_server_state, SERVER_FAILED);
return SERVER_FAIL;
}
if (bind(sock, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) < 0) {
log_log(MODULE_NAME, LOG_ERR, "Failed to bind socket: %s", strerror(errno));
atomic_store(&_server_state, SERVER_FAILED);
close(sock);
return SERVER_FAIL;
}
if (listen(sock, 1) != 0) {
log_log(MODULE_NAME, LOG_ERR, "Failed to start listening on socket: %s", strerror(errno));
atomic_store(&_server_state, SERVER_FAILED);
close(sock);
return SERVER_FAIL;
}
log_log(MODULE_NAME, LOG_INFO, "Waiting for incoming connections...");
atomic_store(&_server_state, SERVER_RUNNING);
while(1) {
struct sockaddr addr;
socklen_t addr_len = sizeof(addr);
int client_fd = accept(sock, &addr, &addr_len);
if (client_fd < 0) {
log_log(MODULE_NAME, LOG_ERR, "Failed to accept an incoming connection: %s", strerror(errno));
continue;
}
SSL* ssl_conn = SSL_new(_ssl_server_ctx);
SSL_set_fd(ssl_conn, client_fd);
if (SSL_accept(ssl_conn) <= 0) {
log_log_ssl_err(MODULE_NAME, LOG_ERR, "SSL Handshake failed.");
} else {
size_t bufsize = 1024;
char* buf = malloc(bufsize);
if (SSL_read(ssl_conn, buf, bufsize) > 0) {
log_log(MODULE_NAME, LOG_INFO, "Received message: %s", buf);
}
SSL_write(ssl_conn, message, sizeof(message));
}
SSL_shutdown(ssl_conn);
SSL_free(ssl_conn);
close(client_fd);
}
_server_thread_shutdown:
close(sock);
}
enum server_start_return server_start() {
initialize_ssl();
if (!_ssl_server_ctx) {
_ssl_server_ctx = SSL_CTX_new(TLS_server_method());
if (!_ssl_server_ctx) {
log_log(MODULE_NAME, LOG_ERR, "Failed to create SSL CTX");
return SERVER_FAIL;
}
if (!ssl_use_ppcerts(_ssl_server_ctx)) {
log_log(MODULE_NAME, LOG_ERR, "Failed to set certificates.");
SSL_CTX_free(_ssl_server_ctx);
_ssl_server_ctx = NULL;
return SERVER_FAIL;
}
}
if (!_server_thread) {
_server_thread = malloc(sizeof(pthread_t));
if (!_server_thread) {
log_log(MODULE_NAME, LOG_ERR, "Failed to allocate resources for server_thread");
return SERVER_FAIL;
}
thread_queue_init(&_server_thread_queue);
pthread_create(_server_thread, NULL, (void* (*)(void*))_server_thread_func, NULL);
pthread_join(*_server_thread, NULL);
free(_server_thread);
_server_thread = NULL;
}
return SERVER_OK;
}