From 08cb0fc05db4dc3fa03cf4c3e1e66310bf1aca7a Mon Sep 17 00:00:00 2001 From: Bram Matthys Date: Sun, 16 Jul 2023 10:30:57 +0200 Subject: [PATCH] Move crule to a module, so we can hot-patch if needed in the future. This is a mandatory module to load, and included in modules.default.conf. This also meant that the crule_test() etc efunctions are available before running config test routines, so we now have a flag for early efuncs. I guess we could consider doing that for all efuncs though, so not sure if this flag is really needed. --- Makefile.windows | 9 +- doc/conf/modules.default.conf | 1 + include/h.h | 12 +- include/modules.h | 7 +- src/Makefile.in | 2 +- src/api-efunctions.c | 268 +++++++++++++++++++--------------- src/conf.c | 2 +- src/modules/Makefile.in | 2 +- src/{ => modules}/crule.c | 144 +++++++++--------- 9 files changed, 239 insertions(+), 208 deletions(-) rename src/{ => modules}/crule.c (91%) diff --git a/Makefile.windows b/Makefile.windows index 98048eca3..24dfe7a32 100644 --- a/Makefile.windows +++ b/Makefile.windows @@ -178,7 +178,7 @@ EXP_OBJ_FILES=src/ircd_vars.obj src/channel.obj src/send.obj src/socket.obj \ src/fdlist.obj src/dbuf.obj \ src/hash.obj src/parse.obj \ src/whowas.obj \ - src/securitygroup.obj src/misc.obj src/match.obj src/crule.obj \ + src/securitygroup.obj src/misc.obj src/match.obj \ src/debug.obj src/support.obj src/list.obj \ src/serv.obj src/user.obj \ src/version.obj src/ircsprintf.obj \ @@ -256,6 +256,7 @@ DLL_FILES=\ src/modules/connect-flood.dll \ src/modules/connthrottle.dll \ src/modules/creationtime.dll \ + src/modules/crule.dll \ src/modules/cycle.dll \ src/modules/dccallow.dll \ src/modules/dccdeny.dll \ @@ -558,9 +559,6 @@ src/whowas.obj: src/whowas.c $(INCLUDES) ./include/dbuf.h ./include/whowas.h src/hash.obj: src/hash.c $(INCLUDES) $(CC) $(CFLAGS) src/hash.c -src/crule.obj: src/crule.c $(INCLUDES) - $(CC) $(CFLAGS) src/crule.c - src/gui.obj: src/windows/gui.c $(INCLUDES) ./include/resource.h $(CC) $(CFLAGS) src/windows/gui.c @@ -871,6 +869,9 @@ src/modules/connthrottle.dll: src/modules/connthrottle.c $(INCLUDES) src/modules/creationtime.dll: src/modules/creationtime.c $(INCLUDES) $(CC) $(MODCFLAGS) src/modules/creationtime.c /Fesrc/modules/ /Fosrc/modules/ /Fdsrc/modules/creationtime.pdb $(MODLFLAGS) +src/modules/crule.dll: src/modules/crule.c $(INCLUDES) + $(CC) $(MODCFLAGS) src/modules/crule.c /Fesrc/modules/ /Fosrc/modules/ /Fdsrc/modules/crule.pdb $(MODLFLAGS) + src/modules/cycle.dll: src/modules/cycle.c $(INCLUDES) $(CC) $(MODCFLAGS) src/modules/cycle.c /Fesrc/modules/ /Fosrc/modules/ /Fdsrc/modules/cycle.pdb $(MODLFLAGS) diff --git a/doc/conf/modules.default.conf b/doc/conf/modules.default.conf index 06c05a930..4adba7976 100644 --- a/doc/conf/modules.default.conf +++ b/doc/conf/modules.default.conf @@ -294,6 +294,7 @@ loadmodule "watch-backend"; /* used by watch and other modules */ loadmodule "geoip_base"; /* needed for ALL geoip functions */ loadmodule "websocket_common"; /* helper functions for websocket (internal) */ loadmodule "spamreport"; /* Spam reporting to a blacklist */ +loadmodule "crule"; /* Rules in spamfilter::rule and deny link::rule */ loadmodule "geoip_classic"; @if module-loaded("geoip_classic") diff --git a/include/h.h b/include/h.h index 3b350a120..688426152 100644 --- a/include/h.h +++ b/include/h.h @@ -531,13 +531,6 @@ extern int sort_character_lowercase_before_uppercase(char x, char y); extern MODVAR RealCommand *CommandHash[256]; extern void init_CommandHash(void); -/* CRULE */ -extern struct CRuleNode* crule_parse(const char*); -extern void crule_free(struct CRuleNode**); -extern int crule_eval(crule_context *context, CRuleNode *rule); -extern int crule_test(const char *rule); -extern const char *crule_errstring(int errcode); - /* * Close all local socket connections, invalidate client fd's * WIN32 cleanup winsock lib @@ -925,6 +918,11 @@ extern MODVAR const char *(*check_deny_link)(ConfigItem_link *link, int auto_con extern MODVAR void (*mtag_add_issued_by)(MessageTag **mtags, Client *client, MessageTag *recv_mtags); extern MODVAR void (*cancel_ident_lookup)(Client *client); extern MODVAR int (*spamreport)(Client *client, const char *ip, NameValuePrioList *details, const char *spamreport_block); +extern MODVAR int (*crule_test)(const char *rule); +extern MODVAR struct CRuleNode *(*crule_parse)(const char *rule); +extern int (*crule_eval)(crule_context *context, CRuleNode *rule); +extern void (*crule_free)(struct CRuleNode**); +extern const char *(*crule_errstring)(int errcode); /* /Efuncs */ /* TLS functions */ diff --git a/include/modules.h b/include/modules.h index 2a0637c80..c67fd6d38 100644 --- a/include/modules.h +++ b/include/modules.h @@ -24,7 +24,7 @@ #define MAXCUSTOMHOOKS 30 #define MAXHOOKTYPES 200 #define MAXCALLBACKS 30 -#define MAXEFUNCTIONS 128 +#define MAXEFUNCTIONS 192 #if defined(_WIN32) #define MOD_EXTENSION "dll" #define DLLFUNC _declspec(dllexport) @@ -2606,6 +2606,11 @@ enum EfunctionType { EFUNC_MTAG_GENERATE_ISSUED_BY_IRC, EFUNC_CANCEL_IDENT_LOOKUP, EFUNC_SPAMREPORT, + EFUNC_CRULE_TEST, + EFUNC_CRULE_PARSE, + EFUNC_CRULE_EVAL, + EFUNC_CRULE_FREE, + EFUNC_CRULE_ERRSTRING, }; /* Module flags */ diff --git a/src/Makefile.in b/src/Makefile.in index 5308cffa5..26674ece9 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -21,7 +21,7 @@ CC = "==== DO NOT RUN MAKE FROM THIS DIRECTORY ====" -OBJS=ircd_vars.o dns.o auth.o channel.o crule.o dbuf.o \ +OBJS=ircd_vars.o dns.o auth.o channel.o dbuf.o \ fdlist.o hash.o ircsprintf.o list.o \ match.o modules.o parse.o mempool.o operclass.o \ conf_preprocessor.o conf.o proc_io_server.o debug.o dispatch.o \ diff --git a/src/api-efunctions.c b/src/api-efunctions.c index ecd8c95f7..f630265a8 100644 --- a/src/api-efunctions.c +++ b/src/api-efunctions.c @@ -22,11 +22,14 @@ #include "unrealircd.h" +#define EFUNC_FLAG_EARLY 0x1 + /* Types */ typedef struct { char *name; void **funcptr; void *deffunc; + int flags; } EfunctionsList; /* Variables */ @@ -162,6 +165,11 @@ const char *(*check_deny_link)(ConfigItem_link *link, int auto_connect); void (*mtag_add_issued_by)(MessageTag **mtags, Client *client, MessageTag *recv_mtags); void (*cancel_ident_lookup)(Client *client); int (*spamreport)(Client *client, const char *ip, NameValuePrioList *details, const char *spamreport_block); +int (*crule_test)(const char *rule); +struct CRuleNode *(*crule_parse)(const char *rule); +int (*crule_eval)(crule_context *context, CRuleNode *rule); +void (*crule_free)(struct CRuleNode**); +const char *(*crule_errstring)(int errcode); Efunction *EfunctionAddMain(Module *module, EfunctionType eftype, int (*func)(), void (*vfunc)(), void *(*pvfunc)(), char *(*stringfunc)(), const char *(*conststringfunc)()) { @@ -255,6 +263,7 @@ int efunctions_check(void) int i, n, errors=0; for (i=0; i < MAXEFUNCTIONS; i++) + { if (efunction_table[i].name) { n = num_efunctions(i); @@ -277,7 +286,20 @@ int efunctions_check(void) efunction_table[i].name, n); errors++; } + + if ((efunction_table[i].flags & EFUNC_FLAG_EARLY) && !*efunction_table[i].funcptr) + { + Efunction *e; + for (e = Efunctions[i]; e; e = e->next) + { + if (e->willberemoved) + continue; + *efunction_table[i].funcptr = e->func.voidfunc; /* This is the new one. */ + break; + } + } } + } return errors ? -1 : 0; } @@ -318,9 +340,9 @@ void efunctions_switchover(void) } } -#define efunc_init_function(what, func, default_func) efunc_init_function_(what, #func, (void *)&func, (void *)default_func) +#define efunc_init_function(what, func, default_func, flags) efunc_init_function_(what, #func, (void *)&func, (void *)default_func, flags) -void efunc_init_function_(EfunctionType what, char *name, void *func, void *default_func) +void efunc_init_function_(EfunctionType what, char *name, void *func, void *default_func, int flags) { if (what >= MAXEFUNCTIONS) { @@ -334,127 +356,133 @@ void efunc_init_function_(EfunctionType what, char *name, void *func, void *defa safe_strdup(efunction_table[what].name, name); efunction_table[what].funcptr = func; efunction_table[what].deffunc = default_func; + efunction_table[what].flags = flags; } void efunctions_init(void) { memset(&efunction_table, 0, sizeof(efunction_table)); - efunc_init_function(EFUNC_DO_JOIN, do_join, NULL); - efunc_init_function(EFUNC_JOIN_CHANNEL, join_channel, NULL); - efunc_init_function(EFUNC_CAN_JOIN, can_join, NULL); - efunc_init_function(EFUNC_DO_MODE, do_mode, NULL); - efunc_init_function(EFUNC_SET_MODE, set_mode, NULL); - efunc_init_function(EFUNC_SET_CHANNEL_MODE, set_channel_mode, NULL); - efunc_init_function(EFUNC_SET_CHANNEL_TOPIC, set_channel_topic, NULL); - efunc_init_function(EFUNC_CMD_UMODE, cmd_umode, NULL); - efunc_init_function(EFUNC_REGISTER_USER, register_user, NULL); - efunc_init_function(EFUNC_TKL_HASH, tkl_hash, NULL); - efunc_init_function(EFUNC_TKL_TYPETOCHAR, tkl_typetochar, NULL); - efunc_init_function(EFUNC_TKL_ADD_SERVERBAN, tkl_add_serverban, NULL); - efunc_init_function(EFUNC_TKL_ADD_BANEXCEPTION, tkl_add_banexception, NULL); - efunc_init_function(EFUNC_TKL_DEL_LINE, tkl_del_line, NULL); - efunc_init_function(EFUNC_TKL_CHECK_LOCAL_REMOVE_SHUN, tkl_check_local_remove_shun, NULL); - efunc_init_function(EFUNC_FIND_TKLINE_MATCH, find_tkline_match, NULL); - efunc_init_function(EFUNC_FIND_SHUN, find_shun, NULL); - efunc_init_function(EFUNC_FIND_SPAMFILTER_USER, find_spamfilter_user, NULL); - efunc_init_function(EFUNC_FIND_QLINE, find_qline, NULL); - efunc_init_function(EFUNC_FIND_TKLINE_MATCH_ZAP, find_tkline_match_zap, NULL); - efunc_init_function(EFUNC_TKL_STATS, tkl_stats, NULL); - efunc_init_function(EFUNC_TKL_SYNCH, tkl_sync, NULL); - efunc_init_function(EFUNC_CMD_TKL, cmd_tkl, NULL); - efunc_init_function(EFUNC_TAKE_ACTION, take_action, NULL); - efunc_init_function(EFUNC_MATCH_SPAMFILTER, match_spamfilter, NULL); - efunc_init_function(EFUNC_MATCH_SPAMFILTER_MTAGS, match_spamfilter_mtags, NULL); - efunc_init_function(EFUNC_JOIN_VIRUSCHAN, join_viruschan, NULL); - efunc_init_function(EFUNC_STRIPCOLORS, StripColors, NULL); - efunc_init_function(EFUNC_SPAMFILTER_BUILD_USER_STRING, spamfilter_build_user_string, NULL); - efunc_init_function(EFUNC_SEND_PROTOCTL_SERVERS, send_protoctl_servers, NULL); - efunc_init_function(EFUNC_VERIFY_LINK, verify_link, NULL); - efunc_init_function(EFUNC_SEND_SERVER_MESSAGE, send_server_message, NULL); - efunc_init_function(EFUNC_BROADCAST_MD_CLIENT, broadcast_md_client, NULL); - efunc_init_function(EFUNC_BROADCAST_MD_CHANNEL, broadcast_md_channel, NULL); - efunc_init_function(EFUNC_BROADCAST_MD_MEMBER, broadcast_md_member, NULL); - efunc_init_function(EFUNC_BROADCAST_MD_MEMBERSHIP, broadcast_md_membership, NULL); - efunc_init_function(EFUNC_INTRODUCE_USER, introduce_user, NULL); - efunc_init_function(EFUNC_CHECK_DENY_VERSION, check_deny_version, NULL); - efunc_init_function(EFUNC_BROADCAST_MD_CLIENT_CMD, broadcast_md_client_cmd, NULL); - efunc_init_function(EFUNC_BROADCAST_MD_CHANNEL_CMD, broadcast_md_channel_cmd, NULL); - efunc_init_function(EFUNC_BROADCAST_MD_MEMBER_CMD, broadcast_md_member_cmd, NULL); - efunc_init_function(EFUNC_BROADCAST_MD_MEMBERSHIP_CMD, broadcast_md_membership_cmd, NULL); - efunc_init_function(EFUNC_MODDATA_ADD_S2S_MTAGS, moddata_add_s2s_mtags, NULL); - efunc_init_function(EFUNC_MODDATA_EXTRACT_S2S_MTAGS, moddata_extract_s2s_mtags, NULL); - efunc_init_function(EFUNC_SEND_MODDATA_CLIENT, send_moddata_client, NULL); - efunc_init_function(EFUNC_SEND_MODDATA_CHANNEL, send_moddata_channel, NULL); - efunc_init_function(EFUNC_SEND_MODDATA_MEMBERS, send_moddata_members, NULL); - efunc_init_function(EFUNC_BROADCAST_MODDATA_CLIENT, broadcast_moddata_client, NULL); - efunc_init_function(EFUNC_MATCH_USER, match_user, NULL); - efunc_init_function(EFUNC_USERHOST_SAVE_CURRENT, userhost_save_current, NULL); - efunc_init_function(EFUNC_USERHOST_CHANGED, userhost_changed, NULL); - efunc_init_function(EFUNC_SEND_JOIN_TO_LOCAL_USERS, send_join_to_local_users, NULL); - efunc_init_function(EFUNC_DO_NICK_NAME, do_nick_name, NULL); - efunc_init_function(EFUNC_DO_REMOTE_NICK_NAME, do_remote_nick_name, NULL); - efunc_init_function(EFUNC_CHARSYS_GET_CURRENT_LANGUAGES, charsys_get_current_languages, NULL); - efunc_init_function(EFUNC_BROADCAST_SINFO, broadcast_sinfo, NULL); - efunc_init_function(EFUNC_CONNECT_SERVER, connect_server, NULL); - efunc_init_function(EFUNC_IS_SERVICES_BUT_NOT_ULINED, is_services_but_not_ulined, NULL); - efunc_init_function(EFUNC_PARSE_MESSAGE_TAGS, parse_message_tags, &parse_message_tags_default_handler); - efunc_init_function(EFUNC_MTAGS_TO_STRING, mtags_to_string, &mtags_to_string_default_handler); - efunc_init_function(EFUNC_TKL_CHARTOTYPE, tkl_chartotype, NULL); - efunc_init_function(EFUNC_TKL_CONFIGTYPETOCHAR, tkl_configtypetochar, NULL); - efunc_init_function(EFUNC_TKL_TYPE_STRING, tkl_type_string, NULL); - efunc_init_function(EFUNC_TKL_TYPE_CONFIG_STRING, tkl_type_config_string, NULL); - efunc_init_function(EFUNC_CAN_SEND_TO_CHANNEL, can_send_to_channel, NULL); - efunc_init_function(EFUNC_BROADCAST_MD_GLOBALVAR, broadcast_md_globalvar, NULL); - efunc_init_function(EFUNC_BROADCAST_MD_GLOBALVAR_CMD, broadcast_md_globalvar_cmd, NULL); - efunc_init_function(EFUNC_TKL_IP_HASH, tkl_ip_hash, NULL); - efunc_init_function(EFUNC_TKL_IP_HASH_TYPE, tkl_ip_hash_type, NULL); - efunc_init_function(EFUNC_TKL_ADD_NAMEBAN, tkl_add_nameban, NULL); - efunc_init_function(EFUNC_TKL_ADD_SPAMFILTER, tkl_add_spamfilter, NULL); - efunc_init_function(EFUNC_SENDNOTICE_TKL_ADD, sendnotice_tkl_add, NULL); - efunc_init_function(EFUNC_SENDNOTICE_TKL_DEL, sendnotice_tkl_del, NULL); - efunc_init_function(EFUNC_FREE_TKL, free_tkl, NULL); - efunc_init_function(EFUNC_FIND_TKL_SERVERBAN, find_tkl_serverban, NULL); - efunc_init_function(EFUNC_FIND_TKL_BANEXCEPTION, find_tkl_banexception, NULL); - efunc_init_function(EFUNC_FIND_TKL_NAMEBAN, find_tkl_nameban, NULL); - efunc_init_function(EFUNC_FIND_TKL_SPAMFILTER, find_tkl_spamfilter, NULL); - efunc_init_function(EFUNC_FIND_TKL_EXCEPTION, find_tkl_exception, NULL); - efunc_init_function(EFUNC_SERVER_BAN_PARSE_MASK, server_ban_parse_mask, NULL); - efunc_init_function(EFUNC_SERVER_BAN_EXCEPTION_PARSE_MASK, server_ban_exception_parse_mask, NULL); - efunc_init_function(EFUNC_TKL_ADDED, tkl_added, NULL); - efunc_init_function(EFUNC_ADD_SILENCE, add_silence, add_silence_default_handler); - efunc_init_function(EFUNC_DEL_SILENCE, del_silence, del_silence_default_handler); - efunc_init_function(EFUNC_IS_SILENCED, is_silenced, is_silenced_default_handler); - efunc_init_function(EFUNC_LABELED_RESPONSE_SAVE_CONTEXT, labeled_response_save_context, labeled_response_save_context_default_handler); - efunc_init_function(EFUNC_LABELED_RESPONSE_SET_CONTEXT, labeled_response_set_context, labeled_response_set_context_default_handler); - efunc_init_function(EFUNC_LABELED_RESPONSE_FORCE_END, labeled_response_force_end, labeled_response_force_end_default_handler); - efunc_init_function(EFUNC_KICK_USER, kick_user, NULL); - efunc_init_function(EFUNC_WATCH_ADD, watch_add, NULL); - efunc_init_function(EFUNC_WATCH_DEL, watch_del, NULL); - efunc_init_function(EFUNC_WATCH_DEL_LIST, watch_del_list, NULL); - efunc_init_function(EFUNC_WATCH_GET, watch_get, NULL); - efunc_init_function(EFUNC_WATCH_CHECK, watch_check, NULL); - efunc_init_function(EFUNC_TKL_UHOST, tkl_uhost, NULL); - efunc_init_function(EFUNC_DO_UNREAL_LOG_REMOTE_DELIVER, do_unreal_log_remote_deliver, do_unreal_log_remote_deliver_default_handler); - efunc_init_function(EFUNC_GET_CHMODES_FOR_USER, get_chmodes_for_user, NULL); - efunc_init_function(EFUNC_WHOIS_GET_POLICY, whois_get_policy, NULL); - efunc_init_function(EFUNC_MAKE_OPER, make_oper, make_oper_default_handler); - efunc_init_function(EFUNC_UNREAL_MATCH_IPLIST, unreal_match_iplist, NULL); - efunc_init_function(EFUNC_WEBSERVER_SEND_RESPONSE, webserver_send_response, webserver_send_response_default_handler); - efunc_init_function(EFUNC_WEBSERVER_CLOSE_CLIENT, webserver_close_client, webserver_close_client_default_handler); - efunc_init_function(EFUNC_WEBSERVER_HANDLE_BODY, webserver_handle_body, webserver_handle_body_default_handler); - efunc_init_function(EFUNC_RPC_RESPONSE, rpc_response, rpc_response_default_handler); - efunc_init_function(EFUNC_RPC_ERROR, rpc_error, rpc_error_default_handler); - efunc_init_function(EFUNC_RPC_ERROR_FMT, rpc_error_fmt, rpc_error_fmt_default_handler); - efunc_init_function(EFUNC_RPC_SEND_REQUEST_TO_REMOTE, rpc_send_request_to_remote, rpc_send_request_to_remote_default_handler); - efunc_init_function(EFUNC_RPC_SEND_RESPONSE_TO_REMOTE, rpc_send_response_to_remote, rpc_send_response_to_remote_default_handler); - efunc_init_function(EFUNC_RRPC_SUPPORTED, rrpc_supported, rrpc_supported_default_handler); - efunc_init_function(EFUNC_RRPC_SUPPORTED_SIMPLE, rrpc_supported_simple, rrpc_supported_simple_default_handler); - efunc_init_function(EFUNC_WEBSOCKET_HANDLE_WEBSOCKET, websocket_handle_websocket, websocket_handle_websocket_default_handler); - efunc_init_function(EFUNC_WEBSOCKET_CREATE_PACKET, websocket_create_packet, websocket_create_packet_default_handler); - efunc_init_function(EFUNC_WEBSOCKET_CREATE_PACKET_EX, websocket_create_packet_ex, websocket_create_packet_ex_default_handler); - efunc_init_function(EFUNC_WEBSOCKET_CREATE_PACKET_SIMPLE, websocket_create_packet_simple, websocket_create_packet_simple_default_handler); - efunc_init_function(EFUNC_CHECK_DENY_LINK, check_deny_link, NULL); - efunc_init_function(EFUNC_MTAG_GENERATE_ISSUED_BY_IRC, mtag_add_issued_by, mtag_add_issued_by_default_handler); - efunc_init_function(EFUNC_CANCEL_IDENT_LOOKUP, cancel_ident_lookup, cancel_ident_lookup_default_handler); - efunc_init_function(EFUNC_SPAMREPORT, spamreport, spamreport_default_handler); + efunc_init_function(EFUNC_DO_JOIN, do_join, NULL, 0); + efunc_init_function(EFUNC_JOIN_CHANNEL, join_channel, NULL, 0); + efunc_init_function(EFUNC_CAN_JOIN, can_join, NULL, 0); + efunc_init_function(EFUNC_DO_MODE, do_mode, NULL, 0); + efunc_init_function(EFUNC_SET_MODE, set_mode, NULL, 0); + efunc_init_function(EFUNC_SET_CHANNEL_MODE, set_channel_mode, NULL, 0); + efunc_init_function(EFUNC_SET_CHANNEL_TOPIC, set_channel_topic, NULL, 0); + efunc_init_function(EFUNC_CMD_UMODE, cmd_umode, NULL, 0); + efunc_init_function(EFUNC_REGISTER_USER, register_user, NULL, 0); + efunc_init_function(EFUNC_TKL_HASH, tkl_hash, NULL, 0); + efunc_init_function(EFUNC_TKL_TYPETOCHAR, tkl_typetochar, NULL, 0); + efunc_init_function(EFUNC_TKL_ADD_SERVERBAN, tkl_add_serverban, NULL, 0); + efunc_init_function(EFUNC_TKL_ADD_BANEXCEPTION, tkl_add_banexception, NULL, 0); + efunc_init_function(EFUNC_TKL_DEL_LINE, tkl_del_line, NULL, 0); + efunc_init_function(EFUNC_TKL_CHECK_LOCAL_REMOVE_SHUN, tkl_check_local_remove_shun, NULL, 0); + efunc_init_function(EFUNC_FIND_TKLINE_MATCH, find_tkline_match, NULL, 0); + efunc_init_function(EFUNC_FIND_SHUN, find_shun, NULL, 0); + efunc_init_function(EFUNC_FIND_SPAMFILTER_USER, find_spamfilter_user, NULL, 0); + efunc_init_function(EFUNC_FIND_QLINE, find_qline, NULL, 0); + efunc_init_function(EFUNC_FIND_TKLINE_MATCH_ZAP, find_tkline_match_zap, NULL, 0); + efunc_init_function(EFUNC_TKL_STATS, tkl_stats, NULL, 0); + efunc_init_function(EFUNC_TKL_SYNCH, tkl_sync, NULL, 0); + efunc_init_function(EFUNC_CMD_TKL, cmd_tkl, NULL, 0); + efunc_init_function(EFUNC_TAKE_ACTION, take_action, NULL, 0); + efunc_init_function(EFUNC_MATCH_SPAMFILTER, match_spamfilter, NULL, 0); + efunc_init_function(EFUNC_MATCH_SPAMFILTER_MTAGS, match_spamfilter_mtags, NULL, 0); + efunc_init_function(EFUNC_JOIN_VIRUSCHAN, join_viruschan, NULL, 0); + efunc_init_function(EFUNC_STRIPCOLORS, StripColors, NULL, 0); + efunc_init_function(EFUNC_SPAMFILTER_BUILD_USER_STRING, spamfilter_build_user_string, NULL, 0); + efunc_init_function(EFUNC_SEND_PROTOCTL_SERVERS, send_protoctl_servers, NULL, 0); + efunc_init_function(EFUNC_VERIFY_LINK, verify_link, NULL, 0); + efunc_init_function(EFUNC_SEND_SERVER_MESSAGE, send_server_message, NULL, 0); + efunc_init_function(EFUNC_BROADCAST_MD_CLIENT, broadcast_md_client, NULL, 0); + efunc_init_function(EFUNC_BROADCAST_MD_CHANNEL, broadcast_md_channel, NULL, 0); + efunc_init_function(EFUNC_BROADCAST_MD_MEMBER, broadcast_md_member, NULL, 0); + efunc_init_function(EFUNC_BROADCAST_MD_MEMBERSHIP, broadcast_md_membership, NULL, 0); + efunc_init_function(EFUNC_INTRODUCE_USER, introduce_user, NULL, 0); + efunc_init_function(EFUNC_CHECK_DENY_VERSION, check_deny_version, NULL, 0); + efunc_init_function(EFUNC_BROADCAST_MD_CLIENT_CMD, broadcast_md_client_cmd, NULL, 0); + efunc_init_function(EFUNC_BROADCAST_MD_CHANNEL_CMD, broadcast_md_channel_cmd, NULL, 0); + efunc_init_function(EFUNC_BROADCAST_MD_MEMBER_CMD, broadcast_md_member_cmd, NULL, 0); + efunc_init_function(EFUNC_BROADCAST_MD_MEMBERSHIP_CMD, broadcast_md_membership_cmd, NULL, 0); + efunc_init_function(EFUNC_MODDATA_ADD_S2S_MTAGS, moddata_add_s2s_mtags, NULL, 0); + efunc_init_function(EFUNC_MODDATA_EXTRACT_S2S_MTAGS, moddata_extract_s2s_mtags, NULL, 0); + efunc_init_function(EFUNC_SEND_MODDATA_CLIENT, send_moddata_client, NULL, 0); + efunc_init_function(EFUNC_SEND_MODDATA_CHANNEL, send_moddata_channel, NULL, 0); + efunc_init_function(EFUNC_SEND_MODDATA_MEMBERS, send_moddata_members, NULL, 0); + efunc_init_function(EFUNC_BROADCAST_MODDATA_CLIENT, broadcast_moddata_client, NULL, 0); + efunc_init_function(EFUNC_MATCH_USER, match_user, NULL, 0); + efunc_init_function(EFUNC_USERHOST_SAVE_CURRENT, userhost_save_current, NULL, 0); + efunc_init_function(EFUNC_USERHOST_CHANGED, userhost_changed, NULL, 0); + efunc_init_function(EFUNC_SEND_JOIN_TO_LOCAL_USERS, send_join_to_local_users, NULL, 0); + efunc_init_function(EFUNC_DO_NICK_NAME, do_nick_name, NULL, 0); + efunc_init_function(EFUNC_DO_REMOTE_NICK_NAME, do_remote_nick_name, NULL, 0); + efunc_init_function(EFUNC_CHARSYS_GET_CURRENT_LANGUAGES, charsys_get_current_languages, NULL, 0); + efunc_init_function(EFUNC_BROADCAST_SINFO, broadcast_sinfo, NULL, 0); + efunc_init_function(EFUNC_CONNECT_SERVER, connect_server, NULL, 0); + efunc_init_function(EFUNC_IS_SERVICES_BUT_NOT_ULINED, is_services_but_not_ulined, NULL, 0); + efunc_init_function(EFUNC_PARSE_MESSAGE_TAGS, parse_message_tags, &parse_message_tags_default_handler, 0); + efunc_init_function(EFUNC_MTAGS_TO_STRING, mtags_to_string, &mtags_to_string_default_handler, 0); + efunc_init_function(EFUNC_TKL_CHARTOTYPE, tkl_chartotype, NULL, 0); + efunc_init_function(EFUNC_TKL_CONFIGTYPETOCHAR, tkl_configtypetochar, NULL, 0); + efunc_init_function(EFUNC_TKL_TYPE_STRING, tkl_type_string, NULL, 0); + efunc_init_function(EFUNC_TKL_TYPE_CONFIG_STRING, tkl_type_config_string, NULL, 0); + efunc_init_function(EFUNC_CAN_SEND_TO_CHANNEL, can_send_to_channel, NULL, 0); + efunc_init_function(EFUNC_BROADCAST_MD_GLOBALVAR, broadcast_md_globalvar, NULL, 0); + efunc_init_function(EFUNC_BROADCAST_MD_GLOBALVAR_CMD, broadcast_md_globalvar_cmd, NULL, 0); + efunc_init_function(EFUNC_TKL_IP_HASH, tkl_ip_hash, NULL, 0); + efunc_init_function(EFUNC_TKL_IP_HASH_TYPE, tkl_ip_hash_type, NULL, 0); + efunc_init_function(EFUNC_TKL_ADD_NAMEBAN, tkl_add_nameban, NULL, 0); + efunc_init_function(EFUNC_TKL_ADD_SPAMFILTER, tkl_add_spamfilter, NULL, 0); + efunc_init_function(EFUNC_SENDNOTICE_TKL_ADD, sendnotice_tkl_add, NULL, 0); + efunc_init_function(EFUNC_SENDNOTICE_TKL_DEL, sendnotice_tkl_del, NULL, 0); + efunc_init_function(EFUNC_FREE_TKL, free_tkl, NULL, 0); + efunc_init_function(EFUNC_FIND_TKL_SERVERBAN, find_tkl_serverban, NULL, 0); + efunc_init_function(EFUNC_FIND_TKL_BANEXCEPTION, find_tkl_banexception, NULL, 0); + efunc_init_function(EFUNC_FIND_TKL_NAMEBAN, find_tkl_nameban, NULL, 0); + efunc_init_function(EFUNC_FIND_TKL_SPAMFILTER, find_tkl_spamfilter, NULL, 0); + efunc_init_function(EFUNC_FIND_TKL_EXCEPTION, find_tkl_exception, NULL, 0); + efunc_init_function(EFUNC_SERVER_BAN_PARSE_MASK, server_ban_parse_mask, NULL, 0); + efunc_init_function(EFUNC_SERVER_BAN_EXCEPTION_PARSE_MASK, server_ban_exception_parse_mask, NULL, 0); + efunc_init_function(EFUNC_TKL_ADDED, tkl_added, NULL, 0); + efunc_init_function(EFUNC_ADD_SILENCE, add_silence, add_silence_default_handler, 0); + efunc_init_function(EFUNC_DEL_SILENCE, del_silence, del_silence_default_handler, 0); + efunc_init_function(EFUNC_IS_SILENCED, is_silenced, is_silenced_default_handler, 0); + efunc_init_function(EFUNC_LABELED_RESPONSE_SAVE_CONTEXT, labeled_response_save_context, labeled_response_save_context_default_handler, 0); + efunc_init_function(EFUNC_LABELED_RESPONSE_SET_CONTEXT, labeled_response_set_context, labeled_response_set_context_default_handler, 0); + efunc_init_function(EFUNC_LABELED_RESPONSE_FORCE_END, labeled_response_force_end, labeled_response_force_end_default_handler, 0); + efunc_init_function(EFUNC_KICK_USER, kick_user, NULL, 0); + efunc_init_function(EFUNC_WATCH_ADD, watch_add, NULL, 0); + efunc_init_function(EFUNC_WATCH_DEL, watch_del, NULL, 0); + efunc_init_function(EFUNC_WATCH_DEL_LIST, watch_del_list, NULL, 0); + efunc_init_function(EFUNC_WATCH_GET, watch_get, NULL, 0); + efunc_init_function(EFUNC_WATCH_CHECK, watch_check, NULL, 0); + efunc_init_function(EFUNC_TKL_UHOST, tkl_uhost, NULL, 0); + efunc_init_function(EFUNC_DO_UNREAL_LOG_REMOTE_DELIVER, do_unreal_log_remote_deliver, do_unreal_log_remote_deliver_default_handler, 0); + efunc_init_function(EFUNC_GET_CHMODES_FOR_USER, get_chmodes_for_user, NULL, 0); + efunc_init_function(EFUNC_WHOIS_GET_POLICY, whois_get_policy, NULL, 0); + efunc_init_function(EFUNC_MAKE_OPER, make_oper, make_oper_default_handler, 0); + efunc_init_function(EFUNC_UNREAL_MATCH_IPLIST, unreal_match_iplist, NULL, 0); + efunc_init_function(EFUNC_WEBSERVER_SEND_RESPONSE, webserver_send_response, webserver_send_response_default_handler, 0); + efunc_init_function(EFUNC_WEBSERVER_CLOSE_CLIENT, webserver_close_client, webserver_close_client_default_handler, 0); + efunc_init_function(EFUNC_WEBSERVER_HANDLE_BODY, webserver_handle_body, webserver_handle_body_default_handler, 0); + efunc_init_function(EFUNC_RPC_RESPONSE, rpc_response, rpc_response_default_handler, 0); + efunc_init_function(EFUNC_RPC_ERROR, rpc_error, rpc_error_default_handler, 0); + efunc_init_function(EFUNC_RPC_ERROR_FMT, rpc_error_fmt, rpc_error_fmt_default_handler, 0); + efunc_init_function(EFUNC_RPC_SEND_REQUEST_TO_REMOTE, rpc_send_request_to_remote, rpc_send_request_to_remote_default_handler, 0); + efunc_init_function(EFUNC_RPC_SEND_RESPONSE_TO_REMOTE, rpc_send_response_to_remote, rpc_send_response_to_remote_default_handler, 0); + efunc_init_function(EFUNC_RRPC_SUPPORTED, rrpc_supported, rrpc_supported_default_handler, 0); + efunc_init_function(EFUNC_RRPC_SUPPORTED_SIMPLE, rrpc_supported_simple, rrpc_supported_simple_default_handler, 0); + efunc_init_function(EFUNC_WEBSOCKET_HANDLE_WEBSOCKET, websocket_handle_websocket, websocket_handle_websocket_default_handler, 0); + efunc_init_function(EFUNC_WEBSOCKET_CREATE_PACKET, websocket_create_packet, websocket_create_packet_default_handler, 0); + efunc_init_function(EFUNC_WEBSOCKET_CREATE_PACKET_EX, websocket_create_packet_ex, websocket_create_packet_ex_default_handler, 0); + efunc_init_function(EFUNC_WEBSOCKET_CREATE_PACKET_SIMPLE, websocket_create_packet_simple, websocket_create_packet_simple_default_handler, 0); + efunc_init_function(EFUNC_CHECK_DENY_LINK, check_deny_link, NULL, 0); + efunc_init_function(EFUNC_MTAG_GENERATE_ISSUED_BY_IRC, mtag_add_issued_by, mtag_add_issued_by_default_handler, 0); + efunc_init_function(EFUNC_CANCEL_IDENT_LOOKUP, cancel_ident_lookup, cancel_ident_lookup_default_handler, 0); + efunc_init_function(EFUNC_SPAMREPORT, spamreport, spamreport_default_handler, 0); + efunc_init_function(EFUNC_CRULE_TEST, crule_test, NULL, EFUNC_FLAG_EARLY);; + efunc_init_function(EFUNC_CRULE_PARSE, crule_parse, NULL, EFUNC_FLAG_EARLY);; + efunc_init_function(EFUNC_CRULE_EVAL, crule_eval, NULL, EFUNC_FLAG_EARLY);; + efunc_init_function(EFUNC_CRULE_FREE, crule_free, NULL, EFUNC_FLAG_EARLY);; + efunc_init_function(EFUNC_CRULE_ERRSTRING, crule_errstring, NULL, EFUNC_FLAG_EARLY);; } diff --git a/src/conf.c b/src/conf.c index 0dcd46a61..f982ac072 100644 --- a/src/conf.c +++ b/src/conf.c @@ -1954,7 +1954,7 @@ void applymeblock(void) /** Run config test and all post config tests. */ int config_test_all(void) { - if ((config_test_blocks() < 0) || (callbacks_check() < 0) || (efunctions_check() < 0) || + if ((efunctions_check() < 0) || (config_test_blocks() < 0) || (callbacks_check() < 0) || reloadable_perm_module_unloaded() || !tls_tests() || !log_tests()) { return 0; diff --git a/src/modules/Makefile.in b/src/modules/Makefile.in index f366be9ce..1d82d1cc3 100644 --- a/src/modules/Makefile.in +++ b/src/modules/Makefile.in @@ -83,7 +83,7 @@ MODULES= \ geoip_base.so extjwt.so tline.so \ standard-replies.so issued-by-tag.so \ real-quit-reason.so \ - spamreport.so \ + spamreport.so crule.so \ $(GEOIP_CLASSIC_OBJECTS) $(GEOIP_MAXMIND_OBJECTS) MODULEFLAGS=@MODULEFLAGS@ diff --git a/src/crule.c b/src/modules/crule.c similarity index 91% rename from src/crule.c rename to src/modules/crule.c index 44a84bdca..f100cc055 100644 --- a/src/crule.c +++ b/src/modules/crule.c @@ -1,9 +1,36 @@ -/** - * @file - * @brief Connection rule parser and checker - * @version $Id$ +/* + * Unreal Internet Relay Chat Daemon, src/modules/crule.c + * crule parser and checker. + * (C) Tony Vencill (Tonto on IRC) + * (C) 2023- Bram Matthys and the UnrealIRCd Team * - * by Tony Vencill (Tonto on IRC) + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 1, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "unrealircd.h" + +ModuleHeader MOD_HEADER += { + "crule", + "1.0.0", + "Crule support for and deny link::rule and spamfilter::rule", + "UnrealIRCd Team", + "unrealircd-6", +}; + +/* Originally by Tony Vencill (Tonto on IRC) * * The majority of this file is a recursive descent parser used to convert * connection rules into expression trees when the conf file is read. @@ -14,24 +41,6 @@ * crule_free, and crule_eval. Prototypes for these functions can be * found in h.h. * - * Please direct any connection rule or SmartRoute questions to Tonto on - * IRC or by email to vencill@bga.com. - * - * For parser testing, defining CR_DEBUG generates a stand-alone parser - * that takes rules from stdin and prints out memory allocation - * information and the parsed rule. This stand alone parser is ignorant - * of the irc server and thus cannot do rule evaluation. Do not define - * this flag when compiling the server! If you wish to generate the - * test parser, compile from the ircd directory with a line similar to - * cc -o parser -DCR_DEBUG crule.c - * - * The define CR_CHKCONF is provided to generate routines needed in - * chkconf. These consist of the parser, a different crule_parse that - * prints errors to stderr, and crule_free (just for good style and to - * more closely simulate the actual ircd environment). crule_eval and - * the rule functions are made empty functions as in the stand-alone - * test parser. - * * The production rules for the grammar are as follows ("rule" is the * starting production): * @@ -62,36 +71,6 @@ * our own and not re-feteched (but were based on older versions). */ -#ifndef CR_DEBUG -/* ircd functions and types we need */ -#include "struct.h" -#include "common.h" -#include "sys.h" -#include "h.h" -#include - -char *collapse(char *pattern); -extern Client *client; - -ID_Copyright("(C) Tony Vincell"); - -#else -/* includes and defines to make the stand-alone test parser */ -#include -#include -#define BadPtr(x) (!(x) || (*(x) == '\0')) -#endif - -#if defined(CR_DEBUG) || defined(CR_CHKCONF) -#undef safe_free -#undef free -#define safe_free free -#endif - -/* - * Some symbols for easy reading - */ - /** Input scanner tokens. */ typedef enum crule_token crule_token; enum crule_token { @@ -127,9 +106,13 @@ enum crule_errcode { CR_EXPCTVALUE, /**< Missing value in a comparisson */ }; -/* - * Expression tree structure, function pointer, and tree pointer local! - */ +/* NOTE: Expression tree structure, function pointer, and tree pointer local! */ + +int _crule_test(const char *rule); +struct CRuleNode *_crule_parse(const char *rule); +void _crule_free(struct CRuleNode**); +int _crule_eval(crule_context *context, CRuleNode *rule); +const char *_crule_errstring(int errcode); /* rule function prototypes - local! */ static int crule_connected(crule_context *, int, void **); @@ -154,18 +137,6 @@ static int crule_parseprimary(CRuleNodePtr *, crule_token *, const char **); static int crule_parsefunction(CRuleNodePtr *, crule_token *, const char **); static int crule_parsearglist(CRuleNodePtr, crule_token *, const char **); -#if defined(CR_DEBUG) || defined(CR_CHKCONF) -/* - * Prototypes for the test parser; if not debugging, - * these are defined in h.h - */ -struct CRuleNode* crule_parse(const char *); -void crule_free(struct CRuleNode**); -#ifdef CR_DEBUG -void print_tree(CRuleNodePtr); -#endif -#endif - /* error messages */ char *crule_errstr[] = { "Unknown error", /* NOERR? - for completeness */ @@ -202,6 +173,33 @@ struct crule_funclistent crule_funclist[] = { {"", 0, NULL} /* this must be here to mark end of list */ }; + +MOD_TEST() +{ + MARK_AS_OFFICIAL_MODULE(modinfo); + EfunctionAdd(modinfo->handle, EFUNC_CRULE_TEST, _crule_test); + EfunctionAddPVoid(modinfo->handle, EFUNC_CRULE_PARSE, TO_PVOIDFUNC(_crule_parse)); + EfunctionAddVoid(modinfo->handle, EFUNC_CRULE_FREE, _crule_free); + EfunctionAdd(modinfo->handle, EFUNC_CRULE_EVAL, _crule_eval); + EfunctionAddConstString(modinfo->handle, EFUNC_CRULE_ERRSTRING, _crule_errstring); + return MOD_SUCCESS; +} + +MOD_INIT() +{ + return MOD_SUCCESS; +} + +MOD_LOAD() +{ + return MOD_SUCCESS; +} + +MOD_UNLOAD() +{ + return MOD_SUCCESS; +} + static int crule_connected(crule_context *context, int numargs, void *crulearg[]) { #if !defined(CR_DEBUG) && !defined(CR_CHKCONF) @@ -324,7 +322,7 @@ static int crule_cap_set(crule_context *context, int numargs, void *crulearg[]) * @param[in] rule Rule to evalute. * @return Non-zero if the rule allows the connection, zero otherwise. */ -int crule_eval(crule_context *context, struct CRuleNode* rule) +int _crule_eval(crule_context *context, struct CRuleNode* rule) { int ret = rule->funcptr(context, rule->numargs, rule->arg); switch (rule->func_test_type) @@ -492,7 +490,7 @@ static void crule_getword(char *word, int *wordlenp, size_t maxlen, const char * * @param[in] rule Text form of rule. * @return CRuleNode for rule, or NULL if there was a parse error. */ -struct CRuleNode* crule_parse(const char *rule) +struct CRuleNode *_crule_parse(const char *rule) { const char *ruleptr = rule; crule_token next_tok; @@ -523,7 +521,7 @@ struct CRuleNode* crule_parse(const char *rule) * @param[in] rule Text form of rule. * @return error code, or 0 for no failure */ -int crule_test(const char *rule) +int _crule_test(const char *rule) { const char *ruleptr = rule; crule_token next_tok; @@ -554,7 +552,7 @@ int crule_test(const char *rule) return errcode + 1; } -const char *crule_errstring(int errcode) +const char *_crule_errstring(int errcode) { if (errcode == 0) return "No error"; @@ -877,7 +875,7 @@ static int crule_parsearglist(CRuleNodePtr argrootp, crule_token *next_tokp, con /** Free a connection rule and all its children. * @param[in,out] elem Pointer to pointer to element to free. MUST NOT BE NULL. */ -void crule_free(struct CRuleNode** elem) +void _crule_free(struct CRuleNode** elem) { int arg, numargs;