diff --git a/Makefile b/Makefile index d095d14..eff4582 100755 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ CC=gcc CFLAGS=-g -std=gnu99 -c -lconfig -ldl -I./lib -BINFLAGS=-g -rdynamic -ldl -lconfig -lssl -lcrypto +BINFLAGS=-g -rdynamic -ldl -lconfig SRC=./src OBJ=./build OBJECTS=$(OBJ)/*.o diff --git a/lib/irc.h b/lib/irc.h index d5ee148..2540b99 100755 --- a/lib/irc.h +++ b/lib/irc.h @@ -17,9 +17,6 @@ #define OUTBUF_SIZE 1200000 #define INBUF_SIZE 1200000 -#include -#include - #ifdef _WIN32 #include #else @@ -29,16 +26,16 @@ struct irc_conn { + int ssl_fd; + + int ssl_fdi; + int srv_fdi; + #ifdef _WIN32 SOCKET srv_fd; #else FILE *srv_fd; #endif - - int ssl_fd; - SSL *ssl; - SSL_CTX *ctx; - char nick[50]; char user[50]; char admin[256]; @@ -49,15 +46,24 @@ struct irc_conn #ifdef _WIN32 BOOL use_ssl; BOOL verify_ssl; + + FARPROC sslmod_init; + FARPROC sslmod_connect; + FARPROC sslmod_read; + FARPROC sslmod_write; + FARPROC sslmod_cleanup; + FARPROC sslmod_get_fd; #else bool use_ssl; bool verify_ssl; bool sslmod_loaded; + void (*sslmod_init)(); void (*sslmod_connect)(); int (*sslmod_read)(); int (*sslmod_write)(); void (*sslmod_cleanup)(); + int (*sslmod_get_fd)(); #endif @@ -74,9 +80,20 @@ typedef struct handler event_handler; void irc_connect(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); -void set_ssl_write(struct irc_conn *bot, void *func); + +MY_API void set_ssl_init(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_privmsg(struct irc_conn *bot, char *to, char *fmt, ...); diff --git a/lib/module.h b/lib/module.h index 4f1c9e1..9f1343b 100755 --- a/lib/module.h +++ b/lib/module.h @@ -4,6 +4,11 @@ #include "irc.h" #include "events.h" +enum module_flags +{ + MOD_FLAG_NO_UNLOAD = 1, + MOD_FLAG_NO_RELOAD = 2 +}; struct module { char name[25]; @@ -12,6 +17,7 @@ struct module { char description[256]; char fname[256]; + int flags; #ifdef _WIN32 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 set_bot(struct irc_conn *b); 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 struct mods *get_mods(); MY_API struct irc_conn *get_bot(); diff --git a/lib/util.h b/lib/util.h index 79774d9..8c7dc11 100755 --- a/lib/util.h +++ b/lib/util.h @@ -34,7 +34,7 @@ #define MY_API #endif -void eprint(char *fmt, ...); +MY_API void eprint(char *fmt, ...); #if defined(__GLIBC__) && (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 38)) || defined(_WIN32) MY_API void strlcpy(char *to, const char *from, int len); diff --git a/mods/openssl.dll b/mods/openssl.dll new file mode 100755 index 0000000..6b88717 Binary files /dev/null and b/mods/openssl.dll differ diff --git a/mods/openssl.lib b/mods/openssl.lib new file mode 100755 index 0000000..3055209 Binary files /dev/null and b/mods/openssl.lib differ diff --git a/mods/openssl/Makefile b/mods/openssl/Makefile new file mode 100755 index 0000000..f5d7a50 --- /dev/null +++ b/mods/openssl/Makefile @@ -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!" diff --git a/mods/openssl/make.bat b/mods/openssl/make.bat new file mode 100755 index 0000000..291be5a --- /dev/null +++ b/mods/openssl/make.bat @@ -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 + + diff --git a/mods/openssl/openssl.c b/mods/openssl/openssl.c old mode 100644 new mode 100755 index e873dc2..5302e8b --- a/mods/openssl/openssl.c +++ b/mods/openssl/openssl.c @@ -2,9 +2,7 @@ #include "util.h" #include "irc.h" -#include "events.h" #include "module.h" -#include "timers.h" #include #include @@ -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"); } @@ -54,18 +64,66 @@ MY_API void sslmod_connect(struct irc_conn *bot) 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() { - 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 } diff --git a/src/irc.c b/src/irc.c index d158df7..ce2b6fb 100755 --- a/src/irc.c +++ b/src/irc.c @@ -11,6 +11,7 @@ #include "irc.h" #include "util.h" #include "events.h" +#include "module.h" #include "channel.h" #include @@ -44,29 +45,7 @@ void irc_connect(struct irc_conn *bot) SetConsoleTitle(titlebuf); if (bot->use_ssl) - { - 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"); - } - } + ssl_init(); if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) { eprint("WSAStartup failed.\n"); @@ -115,52 +94,16 @@ void irc_connect(struct irc_conn *bot) if (bot->use_ssl) - { - 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; - } + ssl_connect(); sprintf(titlebuf, "xbot [connected]: %s:%s", bot->host, bot->port); SetConsoleTitle(titlebuf); #else - int srv_fd; struct addrinfo hints; struct addrinfo *res, *r; if (bot->use_ssl) - { - 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"); - } - } - + ssl_init(); memset(&hints, 0, sizeof hints); hints.ai_family = AF_UNSPEC; @@ -173,17 +116,17 @@ void irc_connect(struct irc_conn *bot) 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; } - if (connect(srv_fd, r->ai_addr, r->ai_addrlen) == 0) + if (connect(bot->srv_fdi, r->ai_addr, r->ai_addrlen) == 0) { break; } - close(srv_fd); + close(bot->srv_fdi); } freeaddrinfo(res); @@ -194,21 +137,9 @@ void irc_connect(struct irc_conn *bot) if (bot->use_ssl) - { - if (SSL_set_fd(bot->ssl, srv_fd) == 0) - { - eprint("Error: Cannot set SSL file descriptor\n"); - } + ssl_connect(); - if (SSL_connect(bot->ssl) != 1) - { - eprint("Error: Cannot connect to SSL server\n"); - } - - bot->ssl_fd = srv_fd; - } - - bot->srv_fd = FDOPEN(srv_fd, "r+"); + bot->srv_fd = FDOPEN(bot->srv_fdi, "r+"); xlog("[IRC] Connected!\n"); #endif } @@ -227,6 +158,84 @@ void irc_auth(struct irc_conn *bot) #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, ...) { char msg_[4096]; @@ -266,7 +275,7 @@ void irc_raw(struct irc_conn *bot, char *fmt, ...) if (bot->use_ssl) { 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"); } diff --git a/src/main.c b/src/main.c index 1b34ee1..74d808c 100755 --- a/src/main.c +++ b/src/main.c @@ -149,7 +149,7 @@ int main(int argc, char **argv) if (bot.use_ssl) { - FD_SET(SSL_get_fd(bot.ssl), &rd); + FD_SET(bot.ssl_fd, &rd); } else { @@ -210,20 +210,10 @@ int main(int argc, char **argv) { if (bot.use_ssl) { - bytesRecv = SSL_read(bot.ssl, bot.in, INBUF_SIZE); + bytesRecv = ssl_read(bot.in, INBUF_SIZE); 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; - } bot.in[bytesRecv] = '\0'; diff --git a/src/module.c b/src/module.c index c245d43..8cc49d2 100755 --- a/src/module.c +++ b/src/module.c @@ -5,6 +5,7 @@ #include #include #include +#include #ifdef _WIN32 #include @@ -222,10 +223,23 @@ void unload_module(struct irc_conn *bot, char *where, char *file) int i; for (i = 0; i < mods->count; i++) { - (*mods->modules[i].unload)(); - 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 FreeLibrary(mods->modules[i].handle); #else @@ -270,8 +284,10 @@ void list_modules(struct irc_conn *bot, char *where) 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) { 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].version, version, 10); 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) diff --git a/xbot.cfg b/xbot.cfg index 0c57e62..d16b2c9 100755 --- a/xbot.cfg +++ b/xbot.cfg @@ -20,9 +20,9 @@ bot: server: { host = "memphis.ephasic.org"; - port = "6697"; + port = "6667"; - ssl = true; + ssl = false; ssl_verify = false; }; diff --git a/xbot.vcxproj b/xbot.vcxproj index 5e7348a..41b44ee 100755 --- a/xbot.vcxproj +++ b/xbot.vcxproj @@ -62,7 +62,7 @@ Disabled - .;lib;include\openssl-3.2.1\include;include\libconfig-1.7.3\lib;%(AdditionalIncludeDirectories) + .;lib;include\libconfig-1.7.3\lib;%(AdditionalIncludeDirectories) WIN32;_DEBUG;_CONSOLE;MY_DLL_EXPORTS;%(PreprocessorDefinitions) true EnableFastChecks @@ -73,8 +73,8 @@ EditAndContinue - libcrypto.lib;libssl.lib;libconfig.lib;ws2_32.lib;%(AdditionalDependencies) - include;include\openssl-3.2.1\lib;%(AdditionalLibraryDirectories) + libconfig.lib;ws2_32.lib;%(AdditionalDependencies) + include;%(AdditionalLibraryDirectories) true Console MachineX86