This repository has been archived on 2021-12-16. You can view files and clone it, but cannot push or open issues or pull requests.
lemonbbs/src/oslib.c
2021-12-15 18:52:53 +01:00

118 lines
3.5 KiB
C

#include "oslib.h"
#define SOCKET_TCP 0
#define SOCKET_SSL 1
// SSL section
SSL_CTX* sslContext;
int lolib_enableSsl(const char* certfilePath, const char* keyfilePath, char* keyfilePassword) {
SSL_library_init();
const SSL_METHOD *method = TLS_server_method();
sslContext = SSL_CTX_new(method);
if (sslContext == NULL) return 1;
if (SSL_CTX_use_certificate_file(sslContext, certfilePath, SSL_FILETYPE_PEM) <= 0) return 2;
SSL_CTX_set_default_passwd_cb_userdata(sslContext, keyfilePassword);
if (SSL_CTX_use_PrivateKey_file(sslContext, keyfilePath, SSL_FILETYPE_PEM) <= 0) return 3;
if (!SSL_CTX_check_private_key(sslContext)) return 4;
return 0;
}
int lolib_acceptSslSocket(LemonServerSocket serverSocket, struct LemonClientSocket *dst) {
SOCKET connFd = accept(serverSocket, 0, 0);
if (connFd == -1) return 1;
SSL* newSSL = SSL_new(sslContext);
SSL_set_fd(newSSL, connFd);
if (SSL_accept(newSSL) != 1) {
SSL_shutdown(newSSL);
SSL_free(newSSL);
return 2;
}
dst->type = SOCKET_SSL;
dst->descriptor.sslDescriptor = newSSL;
return 0;
}
// OS Abstraction section
int lolib_init()
{
#ifdef _WIN32
WSADATA wsa_data;
return WSAStartup(MAKEWORD(1,1), &wsa_data);
#else
return 0;
#endif
}
int lolib_finalize(struct LemonClientSocket *socket)
{
int status;
switch (socket->type) {
case SOCKET_TCP:
#ifdef _WIN32
status = shutdown(socket->descriptor.tcpDescriptor, SD_BOTH);
if (status == 0) { status = closesocket(socket->descriptor.tcpDescriptor); }
#else
status = shutdown(socket->descriptor.tcpDescriptor, SHUT_RDWR);
if (status == 0) { status = close(socket->descriptor.tcpDescriptor); }
#endif
break;
case SOCKET_SSL:
SSL_shutdown(socket->descriptor.sslDescriptor);
SSL_free(socket->descriptor.sslDescriptor);
}
return status;
}
int lolib_quit()
{
if (sslContext != NULL) SSL_CTX_free(sslContext);
#ifdef _WIN32
return WSACleanup();
#else
return 0;
#endif
}
// Wrapper section
int lolib_createServerSocket(const char* bindAddress, unsigned short port, LemonServerSocket *dst) {
struct sockaddr_in serverAddr;
SOCKET serverFd;
if ((serverFd = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) return 1;
serverAddr.sin_family = AF_INET;
inet_pton(AF_INET, bindAddress, &serverAddr.sin_addr);
serverAddr.sin_port = htons(port);
if (bind(serverFd, (const struct sockaddr *) &serverAddr, sizeof(serverAddr)) != 0) return 2;
if (listen(serverFd, 5) != 0) return 3;
*dst = serverFd;
return 0;
}
int lolib_acceptTcpSocket(LemonServerSocket serverSocket, struct LemonClientSocket *dst) {
SOCKET connFd = accept(serverSocket, 0, 0);
if (connFd == -1) return 1;
dst->type = SOCKET_TCP;
dst->descriptor.tcpDescriptor = connFd;
return 0;
}
int lolib_writeSocket(struct LemonClientSocket *socket, const char* data, unsigned int dataLength) {
switch (socket->type) {
case SOCKET_TCP:
return send(socket->descriptor.tcpDescriptor, data, dataLength, 0);
default:
return -2;
}
}
int lolib_readSocket(struct LemonClientSocket *socket, char *data, unsigned int bytesToRead) {
switch (socket->type) {
case SOCKET_TCP:
return recv(socket->descriptor.tcpDescriptor, data, bytesToRead, 0);
default:
return -2;
}
}