moved openssl code into a module

This commit is contained in:
Aaron Blakely 2024-03-14 03:20:38 -05:00
parent fa4fdbb663
commit 50affd176a
14 changed files with 244 additions and 122 deletions

View File

@ -1,6 +1,6 @@
CC=gcc CC=gcc
CFLAGS=-g -std=gnu99 -c -lconfig -ldl -I./lib CFLAGS=-g -std=gnu99 -c -lconfig -ldl -I./lib
BINFLAGS=-g -rdynamic -ldl -lconfig -lssl -lcrypto BINFLAGS=-g -rdynamic -ldl -lconfig
SRC=./src SRC=./src
OBJ=./build OBJ=./build
OBJECTS=$(OBJ)/*.o OBJECTS=$(OBJ)/*.o

View File

@ -17,9 +17,6 @@
#define OUTBUF_SIZE 1200000 #define OUTBUF_SIZE 1200000
#define INBUF_SIZE 1200000 #define INBUF_SIZE 1200000
#include <openssl/ssl.h>
#include <openssl/err.h>
#ifdef _WIN32 #ifdef _WIN32
#include <winsock2.h> #include <winsock2.h>
#else #else
@ -29,16 +26,16 @@
struct irc_conn struct irc_conn
{ {
int ssl_fd;
int ssl_fdi;
int srv_fdi;
#ifdef _WIN32 #ifdef _WIN32
SOCKET srv_fd; SOCKET srv_fd;
#else #else
FILE *srv_fd; FILE *srv_fd;
#endif #endif
int ssl_fd;
SSL *ssl;
SSL_CTX *ctx;
char nick[50]; char nick[50];
char user[50]; char user[50];
char admin[256]; char admin[256];
@ -49,15 +46,24 @@ struct irc_conn
#ifdef _WIN32 #ifdef _WIN32
BOOL use_ssl; BOOL use_ssl;
BOOL verify_ssl; BOOL verify_ssl;
FARPROC sslmod_init;
FARPROC sslmod_connect;
FARPROC sslmod_read;
FARPROC sslmod_write;
FARPROC sslmod_cleanup;
FARPROC sslmod_get_fd;
#else #else
bool use_ssl; bool use_ssl;
bool verify_ssl; bool verify_ssl;
bool sslmod_loaded; bool sslmod_loaded;
void (*sslmod_init)();
void (*sslmod_connect)(); void (*sslmod_connect)();
int (*sslmod_read)(); int (*sslmod_read)();
int (*sslmod_write)(); int (*sslmod_write)();
void (*sslmod_cleanup)(); void (*sslmod_cleanup)();
int (*sslmod_get_fd)();
#endif #endif
@ -74,9 +80,20 @@ typedef struct handler event_handler;
void irc_connect(struct irc_conn *bot); void irc_connect(struct irc_conn *bot);
void irc_auth(struct irc_conn *bot); void irc_auth(struct irc_conn *bot);
void set_ssl_connect(struct irc_conn *bot, void *func);
void set_ssl_read(struct irc_conn *bot, void *func); MY_API void set_ssl_init(struct irc_conn *bot, void *func);
void set_ssl_write(struct irc_conn *bot, void *func); MY_API void set_ssl_connect(struct irc_conn *bot, void *func);
MY_API void set_ssl_read(struct irc_conn *bot, void *func);
MY_API void set_ssl_write(struct irc_conn *bot, void *func);
MY_API void set_ssl_cleanup(struct irc_conn *bot, void *func);
MY_API void set_ssl_get_fd(struct irc_conn *bot, void *func);
MY_API void ssl_init();
MY_API void ssl_connect();
MY_API int ssl_read(char *buf, int len);
MY_API int ssl_write(char *buf, int len);
MY_API void ssl_cleanup();
MY_API int ssl_get_fd();
MY_API void irc_notice(struct irc_conn *bot, char *to, char *fmt, ...); MY_API void irc_notice(struct irc_conn *bot, char *to, char *fmt, ...);
MY_API void irc_privmsg(struct irc_conn *bot, char *to, char *fmt, ...); MY_API void irc_privmsg(struct irc_conn *bot, char *to, char *fmt, ...);

View File

@ -4,6 +4,11 @@
#include "irc.h" #include "irc.h"
#include "events.h" #include "events.h"
enum module_flags
{
MOD_FLAG_NO_UNLOAD = 1,
MOD_FLAG_NO_RELOAD = 2
};
struct module { struct module {
char name[25]; char name[25];
@ -12,6 +17,7 @@ struct module {
char description[256]; char description[256];
char fname[256]; char fname[256];
int flags;
#ifdef _WIN32 #ifdef _WIN32
HMODULE handle; HMODULE handle;
@ -37,7 +43,8 @@ void unload_module(struct irc_conn *bot, char *where, char *file);
void list_modules(struct irc_conn *bot, char *where); void list_modules(struct irc_conn *bot, char *where);
void set_bot(struct irc_conn *b); void set_bot(struct irc_conn *b);
void set_bot_db(struct db_table *db); void set_bot_db(struct db_table *db);
MY_API void register_module(char *name, char *author, char *version, char *description);
MY_API void register_module(char *name, char *author, char *version, char *description, ...);
MY_API void unregister_module(char *name); MY_API void unregister_module(char *name);
MY_API struct mods *get_mods(); MY_API struct mods *get_mods();
MY_API struct irc_conn *get_bot(); MY_API struct irc_conn *get_bot();

View File

@ -34,7 +34,7 @@
#define MY_API #define MY_API
#endif #endif
void eprint(char *fmt, ...); MY_API void eprint(char *fmt, ...);
#if defined(__GLIBC__) && (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 38)) || defined(_WIN32) #if defined(__GLIBC__) && (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 38)) || defined(_WIN32)
MY_API void strlcpy(char *to, const char *from, int len); MY_API void strlcpy(char *to, const char *from, int len);

BIN
mods/openssl.dll Executable file

Binary file not shown.

BIN
mods/openssl.lib Executable file

Binary file not shown.

7
mods/openssl/Makefile Executable file
View File

@ -0,0 +1,7 @@
CC=gcc
CFLAGS=-g -fPIC -I../../lib -lcrypto -lssl
OBJ=../openssl.so
main:
$(CC) -shared -o $(OBJ) $(CFLAGS) ./openssl.c
@echo "All Done!"

7
mods/openssl/make.bat Executable file
View File

@ -0,0 +1,7 @@
"%PROGRAMFILES%\Microsoft Visual Studio 2010\VC\vcvarsall.bat"
cl /I "..\..\lib" /I "..\..\include\openssl-3.2.1\include" /c openssl.c
link /DLL /out:..\openssl.dll openssl.obj ..\..\Debug\xbot.lib ..\..\include\openssl-3.2.1\lib\libssl.lib ..\..\include\openssl-3.2.1\lib\libcrypto.lib
del *.obj

76
mods/openssl/openssl.c Normal file → Executable file
View File

@ -2,9 +2,7 @@
#include "util.h" #include "util.h"
#include "irc.h" #include "irc.h"
#include "events.h"
#include "module.h" #include "module.h"
#include "timers.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -42,9 +40,21 @@ MY_API void sslmod_init(struct irc_conn *bot)
} }
} }
MY_API void sslmod_connect(struct irc_conn *bot) MY_API int get_ssl_fd()
{ {
if (SSL_set_fd(ssl, fileno(bot->srv_fd)) == 0) printf("ssl_fd: %d\n", ssl_fd);
return ssl_fd;
}
MY_API void sslmod_connect()
{
struct irc_conn *bot = get_bot();
#ifdef _WIN32
if (SSL_set_fd(ssl, bot->srv_fd) == 0)
#else
if (SSL_set_fd(ssl, bot->srv_fdi) == 0)
#endif
{ {
eprint("Error: Cannot set SSL file descriptor\n"); eprint("Error: Cannot set SSL file descriptor\n");
} }
@ -54,18 +64,66 @@ MY_API void sslmod_connect(struct irc_conn *bot)
eprint("Error: Cannot connect to SSL server\n"); eprint("Error: Cannot connect to SSL server\n");
} }
ssl_fd = fileno(bot->srv_fd); #ifdef _WIN32
bot->ssl_fd = bot->srv_fd;
#else
bot->ssl_fd = bot->srv_fdi;
#endif
}
MY_API void sslmod_write(char *buf, int len)
{
int n;
if ((n = SSL_write(ssl, buf, len)) <= 0)
{
eprint("Error: Cannot write to SSL server\n");
}
}
MY_API int sslmod_read(char *buf, int len)
{
int n;
unsigned long ssl_err;
if ((n = SSL_read(ssl, buf, len)) <= 0)
{
eprint("xbot: error on SSL_read()\n");
ssl_err = ERR_get_error();
if (ssl_err)
{
eprint("SSL error: %s\n", ERR_error_string(ssl_err, NULL));
}
return -1;
}
return n;
}
MY_API void sslmod_cleanup()
{
SSL_shutdown(ssl);
SSL_free(ssl);
SSL_CTX_free(ctx);
ERR_free_strings();
EVP_cleanup();
} }
MY_API void mod_init() MY_API void mod_init()
{ {
register_module("openssl", "Aaron Blakely", "1.0", "SSL/TLS support using OpenSSL"); struct irc_conn *bot = get_bot();
register_module("openssl", "Aaron Blakely", "1.0", "SSL/TLS support using OpenSSL", MOD_FLAG_NO_UNLOAD);
set_ssl_init(bot, sslmod_init);
set_ssl_connect(bot, sslmod_connect);
set_ssl_write(bot, sslmod_write);
set_ssl_read(bot, sslmod_read);
set_ssl_cleanup(bot, sslmod_cleanup);
printf("OpenSSL module loaded\n");
} }
MY_API void mod_unlaod() MY_API void mod_unload()
{ {
unregister_module("openssl"); // should never be called because of MOD_FLAG_NO_UNLOAD
} }

167
src/irc.c
View File

@ -11,6 +11,7 @@
#include "irc.h" #include "irc.h"
#include "util.h" #include "util.h"
#include "events.h" #include "events.h"
#include "module.h"
#include "channel.h" #include "channel.h"
#include <string.h> #include <string.h>
@ -44,29 +45,7 @@ void irc_connect(struct irc_conn *bot)
SetConsoleTitle(titlebuf); SetConsoleTitle(titlebuf);
if (bot->use_ssl) if (bot->use_ssl)
{ ssl_init();
SSL_library_init();
SSL_load_error_strings();
bot->ctx = SSL_CTX_new(SSLv23_client_method());
if (bot->ctx == NULL)
{
eprint("Error: Cannot create SSL context\n");
}
if (bot->verify_ssl)
{
SSL_CTX_set_verify(bot->ctx, SSL_VERIFY_PEER, NULL);
}
else
{
SSL_CTX_set_verify(bot->ctx, SSL_VERIFY_NONE, NULL);
}
if ((bot->ssl = SSL_new(bot->ctx)) == NULL)
{
eprint("Error: Cannot create SSL object\n");
}
}
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) { if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
eprint("WSAStartup failed.\n"); eprint("WSAStartup failed.\n");
@ -115,52 +94,16 @@ void irc_connect(struct irc_conn *bot)
if (bot->use_ssl) if (bot->use_ssl)
{ ssl_connect();
if (SSL_set_fd(bot->ssl, bot->srv_fd) == 0)
{
eprint("Error: Cannot set SSL file descriptor\n");
}
if (SSL_connect(bot->ssl) != 1)
{
eprint("Error: Cannot connect to SSL server\n");
}
bot->ssl_fd = bot->srv_fd;
}
sprintf(titlebuf, "xbot [connected]: %s:%s", bot->host, bot->port); sprintf(titlebuf, "xbot [connected]: %s:%s", bot->host, bot->port);
SetConsoleTitle(titlebuf); SetConsoleTitle(titlebuf);
#else #else
int srv_fd;
struct addrinfo hints; struct addrinfo hints;
struct addrinfo *res, *r; struct addrinfo *res, *r;
if (bot->use_ssl) if (bot->use_ssl)
{ ssl_init();
SSL_library_init();
SSL_load_error_strings();
bot->ctx = SSL_CTX_new(SSLv23_client_method());
if (bot->ctx == NULL)
{
eprint("Error: Cannot create SSL context\n");
}
if (bot->verify_ssl)
{
SSL_CTX_set_verify(bot->ctx, SSL_VERIFY_PEER, NULL);
}
else
{
SSL_CTX_set_verify(bot->ctx, SSL_VERIFY_NONE, NULL);
}
if ((bot->ssl = SSL_new(bot->ctx)) == NULL)
{
eprint("Error: Cannot create SSL object\n");
}
}
memset(&hints, 0, sizeof hints); memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC; hints.ai_family = AF_UNSPEC;
@ -173,17 +116,17 @@ void irc_connect(struct irc_conn *bot)
for (r = res; r; r->ai_next) for (r = res; r; r->ai_next)
{ {
if ((srv_fd = socket(r->ai_family, r->ai_socktype, r->ai_protocol)) == -1) if ((bot->srv_fdi = socket(r->ai_family, r->ai_socktype, r->ai_protocol)) == -1)
{ {
continue; continue;
} }
if (connect(srv_fd, r->ai_addr, r->ai_addrlen) == 0) if (connect(bot->srv_fdi, r->ai_addr, r->ai_addrlen) == 0)
{ {
break; break;
} }
close(srv_fd); close(bot->srv_fdi);
} }
freeaddrinfo(res); freeaddrinfo(res);
@ -194,21 +137,9 @@ void irc_connect(struct irc_conn *bot)
if (bot->use_ssl) if (bot->use_ssl)
{ ssl_connect();
if (SSL_set_fd(bot->ssl, srv_fd) == 0)
{
eprint("Error: Cannot set SSL file descriptor\n");
}
if (SSL_connect(bot->ssl) != 1) bot->srv_fd = FDOPEN(bot->srv_fdi, "r+");
{
eprint("Error: Cannot connect to SSL server\n");
}
bot->ssl_fd = srv_fd;
}
bot->srv_fd = FDOPEN(srv_fd, "r+");
xlog("[IRC] Connected!\n"); xlog("[IRC] Connected!\n");
#endif #endif
} }
@ -227,6 +158,84 @@ void irc_auth(struct irc_conn *bot)
#endif #endif
} }
void set_ssl_init(struct irc_conn *bot, void *func)
{
bot->sslmod_init = func;
}
void set_ssl_connect(struct irc_conn *bot, void *func)
{
bot->sslmod_connect = func;
}
void set_ssl_write(struct irc_conn *bot, void *func)
{
bot->sslmod_write = func;
}
void set_ssl_read(struct irc_conn *bot, void *func)
{
bot->sslmod_read = func;
}
void set_ssl_cleanup(struct irc_conn *bot, void *func)
{
bot->sslmod_cleanup = func;
}
void set_ssl_get_fd(struct irc_conn *bot, void *func)
{
bot->sslmod_get_fd = func;
}
void ssl_init()
{
struct irc_conn *bot = get_bot();
void *sslinit = bot->sslmod_init;
((void (*)())sslinit)();
}
void ssl_connect()
{
struct irc_conn *bot = get_bot();
void *sslconnect = bot->sslmod_connect;
((void (*)())sslconnect)();
}
int ssl_read(char *buf, int len)
{
struct irc_conn *bot = get_bot();
void *sslread = bot->sslmod_read;
return ((int (*)(char *, int))sslread)(buf, len);
}
int ssl_write(char *buf, int len)
{
struct irc_conn *bot = get_bot();
void *sslwrite = bot->sslmod_write;
return ((int (*)(char *, int))sslwrite)(buf, len);
}
void ssl_cleanup()
{
struct irc_conn *bot = get_bot();
void *sslcleanup = bot->sslmod_cleanup;
((void (*)())sslcleanup)();
}
int ssl_get_fd()
{
struct irc_conn *bot = get_bot();
void *sslgetfd = bot->sslmod_get_fd;
return ((int (*)())sslgetfd)();
}
void irc_notice(struct irc_conn *bot, char *to, char *fmt, ...) void irc_notice(struct irc_conn *bot, char *to, char *fmt, ...)
{ {
char msg_[4096]; char msg_[4096];
@ -266,7 +275,7 @@ void irc_raw(struct irc_conn *bot, char *fmt, ...)
if (bot->use_ssl) if (bot->use_ssl)
{ {
sprintf(outbuf, "%s\r\n", bot->out); sprintf(outbuf, "%s\r\n", bot->out);
if (SSL_write(bot->ssl, outbuf, strlen(outbuf)) <= 0) if (ssl_write(outbuf, strlen(outbuf)) <= 0)
{ {
eprint("Error: Cannot write to SSL server\n"); eprint("Error: Cannot write to SSL server\n");
} }

View File

@ -149,7 +149,7 @@ int main(int argc, char **argv)
if (bot.use_ssl) if (bot.use_ssl)
{ {
FD_SET(SSL_get_fd(bot.ssl), &rd); FD_SET(bot.ssl_fd, &rd);
} }
else else
{ {
@ -210,20 +210,10 @@ int main(int argc, char **argv)
{ {
if (bot.use_ssl) if (bot.use_ssl)
{ {
bytesRecv = SSL_read(bot.ssl, bot.in, INBUF_SIZE); bytesRecv = ssl_read(bot.in, INBUF_SIZE);
if (bytesRecv <= 0) if (bytesRecv <= 0)
{ {
eprint("xbot: error on SSL_read()\n");
ssl_err = ERR_get_error();
if (ssl_err)
{
eprint("SSL error: %s\n", ERR_error_string(ssl_err, NULL));
}
return -1; return -1;
} }
bot.in[bytesRecv] = '\0'; bot.in[bytesRecv] = '\0';

View File

@ -5,6 +5,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <stdarg.h>
#ifdef _WIN32 #ifdef _WIN32
#include <windows.h> #include <windows.h>
@ -222,10 +223,23 @@ void unload_module(struct irc_conn *bot, char *where, char *file)
int i; int i;
for (i = 0; i < mods->count; i++) for (i = 0; i < mods->count; i++)
{ {
(*mods->modules[i].unload)();
if (strcmp(mods->modules[i].fname, file) == 0) if (strcmp(mods->modules[i].fname, file) == 0)
{ {
if (mods->modules[i].flags & MOD_FLAG_NO_UNLOAD)
{
if (strcmp(PRIVMSG_CHAN, where))
{
irc_notice(bot, where, "Module '%s' cannot be unloaded.", file);
}
else
{
xlog("[module] Module '%s' cannot be unloaded.\n", file);
}
return;
}
(*mods->modules[i].unload)();
#ifdef _WIN32 #ifdef _WIN32
FreeLibrary(mods->modules[i].handle); FreeLibrary(mods->modules[i].handle);
#else #else
@ -270,8 +284,10 @@ void list_modules(struct irc_conn *bot, char *where)
free(tmp); free(tmp);
} }
MY_API void register_module(char *name, char *author, char *version, char *description) MY_API void register_module(char *name, char *author, char *version, char *description, ...)
{ {
va_list args;
if (mods->count >= 512) if (mods->count >= 512)
{ {
eprint("Error: Too many modules loaded.\n"); eprint("Error: Too many modules loaded.\n");
@ -282,6 +298,17 @@ MY_API void register_module(char *name, char *author, char *version, char *descr
strlcpy(mods->modules[mods->count].author, author, 50); strlcpy(mods->modules[mods->count].author, author, 50);
strlcpy(mods->modules[mods->count].version, version, 10); strlcpy(mods->modules[mods->count].version, version, 10);
strlcpy(mods->modules[mods->count].description, description, 256); strlcpy(mods->modules[mods->count].description, description, 256);
va_start(args, description);
mods->modules[mods->count].flags = va_arg(args, int);
if (mods->modules[mods->count].flags & MOD_FLAG_NO_UNLOAD)
{
xlog("[module] Module '%s' cannot be unloaded.\n", name);
}
va_end(args);
} }
MY_API void unregister_module(char *name) MY_API void unregister_module(char *name)

View File

@ -20,9 +20,9 @@ bot:
server: server:
{ {
host = "memphis.ephasic.org"; host = "memphis.ephasic.org";
port = "6697"; port = "6667";
ssl = true; ssl = false;
ssl_verify = false; ssl_verify = false;
}; };

View File

@ -62,7 +62,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile> <ClCompile>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>.;lib;include\openssl-3.2.1\include;include\libconfig-1.7.3\lib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>.;lib;include\libconfig-1.7.3\lib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;MY_DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;MY_DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild> <MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
@ -73,8 +73,8 @@
<DebugInformationFormat>EditAndContinue</DebugInformationFormat> <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
</ClCompile> </ClCompile>
<Link> <Link>
<AdditionalDependencies>libcrypto.lib;libssl.lib;libconfig.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>libconfig.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>include;include\openssl-3.2.1\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>include;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<TargetMachine>MachineX86</TargetMachine> <TargetMachine>MachineX86</TargetMachine>