diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index 8df9836f32..e96323c658 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -139,7 +139,7 @@ var/main_irc = "" var/admin_irc = "" var/python_path = "" //Path to the python executable. Defaults to "python" on windows and "/usr/bin/env python2" on unix - + var/use_lib_nudge = 0 //Use the C library nudge instead of the python nudge. /datum/configuration/New() var/list/L = typesof(/datum/game_mode) - /datum/game_mode @@ -474,6 +474,9 @@ else //probably windows, if not this should work anyway config.python_path = "python" + if("use_lib_nudge") + config.use_lib_nudge = 1 + if("allow_cult_ghostwriter") config.cult_ghostwriter = 1 diff --git a/code/modules/ext_scripts/irc.dm b/code/modules/ext_scripts/irc.dm index 3976904efb..fc8910d79f 100644 --- a/code/modules/ext_scripts/irc.dm +++ b/code/modules/ext_scripts/irc.dm @@ -1,6 +1,15 @@ /proc/send2irc(var/channel, var/msg) if(config.use_irc_bot && config.irc_bot_host) - ext_python("ircbot_message.py", "[config.comms_password] [config.irc_bot_host] [channel] [msg]") + if(config.use_lib_nudge) + var/nudge_lib + if(world.system_type == MS_WINDOWS) + nudge_lib = "lib\\nudge.dll" + else + nudge_lib = "lib/nudge.so" + + call(nudge_lib, "nudge")("[config.comms_password]","[config.irc_bot_host]","[channel]","[msg]") + else + ext_python("ircbot_message.py", "[config.comms_password] [config.irc_bot_host] [channel] [msg]") return /proc/send2mainirc(var/msg) diff --git a/config/example/config.txt b/config/example/config.txt index 28a803d8e7..300c23d34f 100644 --- a/config/example/config.txt +++ b/config/example/config.txt @@ -242,6 +242,10 @@ USEALIENWHITELIST ## Default is "python" on Windows, "/usr/bin/env python2" on UNIX. #PYTHON_PATH +## Uncomment to use the C library nudge instead of the python script. +## This helps security and stability on Linux, but you need to compile the library first. +#USE_LIB_NUDGE + ## Uncommen to allow ghosts to write in blood during Cult rounds. ALLOW_CULT_GHOSTWRITER diff --git a/DLLSocket/DLLSocket.cbp b/lib/DLLSocket/DLLSocket.cbp similarity index 100% rename from DLLSocket/DLLSocket.cbp rename to lib/DLLSocket/DLLSocket.cbp diff --git a/DLLSocket/compile.sh b/lib/DLLSocket/compile.sh similarity index 100% rename from DLLSocket/compile.sh rename to lib/DLLSocket/compile.sh diff --git a/DLLSocket/main.cpp b/lib/DLLSocket/main.cpp similarity index 100% rename from DLLSocket/main.cpp rename to lib/DLLSocket/main.cpp diff --git a/DLLSocket/server_controller.py b/lib/DLLSocket/server_controller.py similarity index 100% rename from DLLSocket/server_controller.py rename to lib/DLLSocket/server_controller.py diff --git a/lib/src/netutil.c b/lib/src/netutil.c new file mode 100644 index 0000000000..4028e89b5e --- /dev/null +++ b/lib/src/netutil.c @@ -0,0 +1,109 @@ +#include "netutil.h" +#include "string.h" + +int net_ready = 0; +void net_init() +{ + #ifdef _WIN32 + WSADATA wsa; + WSAStartup(MAKEWORD(2,0),&wsa); + #endif + net_ready = 1; +} + +socket_t connect_sock(char * host, char * port) +{ + if(!net_ready) + { + net_init(); + } + + socket_t out_sock = -1; + struct addrinfo addr_in; + struct addrinfo * addr_proc; + int gai_status; + + memset(&addr_in, 0, sizeof(addr_in)); + + addr_in.ai_family = AF_UNSPEC; + addr_in.ai_socktype = SOCK_STREAM; + addr_in.ai_flags = AI_PASSIVE; + + gai_status = getaddrinfo(host, port, &addr_in, &addr_proc); + + if(gai_status) + { + return -1; + } + + struct addrinfo * ai_p; + for(ai_p = addr_proc; ai_p != 0; ai_p = ai_p->ai_next) + { + out_sock = socket(ai_p->ai_family, ai_p->ai_socktype, + ai_p->ai_protocol); + + if((int)out_sock == -1) + { + continue; + } + else if(connect(out_sock, ai_p->ai_addr, ai_p->ai_addrlen) == -1) + { + close_socket(out_sock); + continue; + } + else + { + break; + } + } + + if(!out_sock) + { + freeaddrinfo(addr_proc); + return -1; + } + + freeaddrinfo(addr_proc); + return out_sock; +} + +void send_n(socket_t sock, const char * buf, size_t n) +{ + size_t to_send = n; + const char * buf_i = buf; + while(to_send) + { + int sent = send(sock, buf_i, to_send, 0); + if(sent != -1) + { + to_send -= sent; + buf_i += sent; + } + else + { + return; + } + } + return; +} + +void recv_n(socket_t sock, char * buf, size_t n) +{ + size_t total = 0; + char * buf_i = buf; + while(total < n) + { + int recved = recv(sock, buf_i, n - total, 0); + if(recved > 0) + { + total += recved; + buf_i += recved; + } + else + { + return; + } + } + return; +} + diff --git a/lib/src/netutil.h b/lib/src/netutil.h new file mode 100644 index 0000000000..6e97b1e3fa --- /dev/null +++ b/lib/src/netutil.h @@ -0,0 +1,33 @@ +#ifndef NETUTIL_H +#define NETUTIL_H + +#ifdef _WIN32 + +#include +#include +typedef SOCKET socket_t; + +#define close_socket(sock) closesocket(sock) + +#else + +#include +#include +#include +#include +typedef int socket_t; + +#define close_socket(sock) close(sock) + +#endif + +extern int net_ready; +void init_net(); + +socket_t connect_sock(char * host, char * port); + +void send_n(socket_t sock, const char * buf, size_t n); +void recv_n(socket_t sock, char * buf, size_t n); + +#endif + diff --git a/lib/src/nudge.c b/lib/src/nudge.c new file mode 100644 index 0000000000..90aa85fb5e --- /dev/null +++ b/lib/src/nudge.c @@ -0,0 +1,73 @@ +#include +#include +#include + +#include "netutil.h" + +#ifdef _WIN32 + #define DLL_EXPORT __declspec(dllexport) +#else + #define DLL_EXPORT __attribute__ ((visibility ("default"))) +#endif + +size_t san_c(const char * input) +{ + unsigned int count = strlen(input); + + const char * i; + for(i = input; *i; i++) + { + if(*i == '\\' || *i == '\'') + { + count++; + } + } + + return count; +} + +char * san_cpy(char * out_buf, const char * in_buf) +{ + const char * i_in = in_buf; + char * i_out = out_buf; + while(*i_in) + { + if(*i_in == '\\' || *i_in == '\'') + { + *(i_out++) = '\\'; + } + *(i_out++) = *(i_in++); + } + return i_out; +} + +DLL_EXPORT const char * nudge(int n, char *v[]) +{ + if(n != 4) + { + return ""; + } + + size_t out_c = san_c(v[0]) + san_c(v[2]) + san_c(v[3]); + + char * san_out = malloc(out_c + 56); + + char * san_i = san_out; + strcpy(san_i, "(dp1\nS'ip'\np2\nS'"); + san_i += 16; + san_i = san_cpy(san_i, v[2]); + strcpy(san_i, "'\np3\nsS'data'\np4\n(lp5\nS'"); + san_i += 24; + san_i = san_cpy(san_i, v[0]); + strcpy(san_i, "'\np6\naS'"); + san_i += 8; + san_i = san_cpy(san_i, v[3]); + strcpy(san_i, "'\np7\nas."); + + socket_t nudge_sock = connect_sock(v[1], "45678"); + send_n(nudge_sock, san_out, out_c + 56); + close_socket(nudge_sock); + + return "1"; +} +