diff --git a/doc/conf/modules.default.conf b/doc/conf/modules.default.conf index f4e9bdc0e..0e2452ca6 100644 --- a/doc/conf/modules.default.conf +++ b/doc/conf/modules.default.conf @@ -103,7 +103,6 @@ loadmodule "stats"; loadmodule "tkl"; /* also server-to-server */ loadmodule "trace"; loadmodule "tsctl"; -loadmodule "undccdeny"; loadmodule "unsqline"; loadmodule "wallops"; loadmodule "jumpserver"; @@ -126,7 +125,6 @@ loadmodule "require-module"; // https://www.unrealircd.org/docs/Services loadmodule "sendsno"; loadmodule "sendumode"; -loadmodule "svsfline"; loadmodule "svsjoin"; loadmodule "svskill"; loadmodule "svslusers"; diff --git a/include/h.h b/include/h.h index 6b2af9d11..d0b91dc8d 100644 --- a/include/h.h +++ b/include/h.h @@ -276,8 +276,6 @@ extern MODVAR int writecalls, writeb[]; extern int deliver_it(Client *cptr, char *str, int len, int *want_read); extern int target_limit_exceeded(Client *client, void *target, const char *name); extern char *canonize(char *buffer); -extern ConfigItem_deny_dcc *dcc_isforbidden(Client *client, char *filename); -extern ConfigItem_deny_dcc *dcc_isdiscouraged(Client *client, char *filename); extern int check_registered(Client *); extern int check_registered_user(Client *); extern char *get_client_name(Client *, int); @@ -637,9 +635,6 @@ extern MODVAR CoreChannelModeTable corechannelmodetable[]; extern char *unreal_encodespace(char *s); extern char *unreal_decodespace(char *s); extern MODVAR Link *helpign; -extern void DCCdeny_add(char *filename, char *reason, int type, int type2); -extern void DCCdeny_del(ConfigItem_deny_dcc *deny); -extern void dcc_wipe_services(void); extern void reread_motdsandrules(); extern MODVAR int SVSNOOP; extern int callbacks_check(void); diff --git a/include/modules.h b/include/modules.h index 9bfb01835..cf58538a3 100644 --- a/include/modules.h +++ b/include/modules.h @@ -973,6 +973,7 @@ extern void SavePersistentLongX(ModuleInfo *modinfo, char *varshortname, long va #define HOOKTYPE_IDENT_LOOKUP 103 #define HOOKTYPE_CONFIGRUN_EX 104 #define HOOKTYPE_CAN_SEND_TO_USER 105 +#define HOOKTYPE_SERVER_SYNC 106 /* Adding a new hook here? * 1) Add the #define HOOKTYPE_.... with a new number @@ -985,6 +986,7 @@ extern void SavePersistentLongX(ModuleInfo *modinfo, char *varshortname, long va int hooktype_local_connect(Client *client); int hooktype_remote_connect(Client *client); int hooktype_server_connect(Client *client); +int hooktype_server_sync(Client *client); int hooktype_post_server_connect(Client *client); char *hooktype_pre_local_quit(Client *client, char *comment); int hooktype_local_quit(Client *client, MessageTag *mtags, char *comment); @@ -1067,7 +1069,7 @@ int hooktype_can_sajoin(Client *target, Channel *channel, Client *client); int hooktype_check_init(Client *cptr, char *sockname, size_t size); int hooktype_mode_deop(Client *client, Client *victim, Channel *channel, u_int what, int modechar, long my_access, char **badmode); int hooktype_see_channel_in_whois(Client *client, Client *target, Channel *channel); -int hooktype_dcc_denied(Client *client, Client *target, char *realfile, char *displayfile, ConfigItem_deny_dcc *denydcc); +int hooktype_dcc_denied(Client *client, char *target, char *realfile, char *displayfile, ConfigItem_deny_dcc *denydcc); int hooktype_server_handshake_out(Client *client); int hooktype_server_synched(Client *client); int hooktype_secure_connect(Client *client); @@ -1101,6 +1103,7 @@ _UNREAL_ERROR(_hook_error_incompatible, "Incompatible hook function. Check argum ((hooktype == HOOKTYPE_PRE_LOCAL_CONNECT) && !ValidateHook(hooktype_pre_local_connect, func)) || \ ((hooktype == HOOKTYPE_PRE_LOCAL_QUIT) && !ValidateHook(hooktype_pre_local_quit, func)) || \ ((hooktype == HOOKTYPE_SERVER_CONNECT) && !ValidateHook(hooktype_server_connect, func)) || \ + ((hooktype == HOOKTYPE_SERVER_SYNC) && !ValidateHook(hooktype_server_sync, func)) || \ ((hooktype == HOOKTYPE_SERVER_QUIT) && !ValidateHook(hooktype_server_quit, func)) || \ ((hooktype == HOOKTYPE_STATS) && !ValidateHook(hooktype_stats, func)) || \ ((hooktype == HOOKTYPE_LOCAL_JOIN) && !ValidateHook(hooktype_local_join, func)) || \ diff --git a/src/conf.c b/src/conf.c index e3f198426..46d3c6011 100644 --- a/src/conf.c +++ b/src/conf.c @@ -59,13 +59,11 @@ static int _conf_link (ConfigFile *conf, ConfigEntry *ce); static int _conf_ban (ConfigFile *conf, ConfigEntry *ce); static int _conf_set (ConfigFile *conf, ConfigEntry *ce); static int _conf_deny (ConfigFile *conf, ConfigEntry *ce); -static int _conf_deny_dcc (ConfigFile *conf, ConfigEntry *ce); static int _conf_deny_link (ConfigFile *conf, ConfigEntry *ce); static int _conf_deny_channel (ConfigFile *conf, ConfigEntry *ce); static int _conf_deny_version (ConfigFile *conf, ConfigEntry *ce); static int _conf_require (ConfigFile *conf, ConfigEntry *ce); static int _conf_allow_channel (ConfigFile *conf, ConfigEntry *ce); -static int _conf_allow_dcc (ConfigFile *conf, ConfigEntry *ce); static int _conf_loadmodule (ConfigFile *conf, ConfigEntry *ce); static int _conf_log (ConfigFile *conf, ConfigEntry *ce); static int _conf_alias (ConfigFile *conf, ConfigEntry *ce); @@ -97,7 +95,6 @@ static int _test_require (ConfigFile *conf, ConfigEntry *ce); static int _test_set (ConfigFile *conf, ConfigEntry *ce); static int _test_deny (ConfigFile *conf, ConfigEntry *ce); static int _test_allow_channel (ConfigFile *conf, ConfigEntry *ce); -static int _test_allow_dcc (ConfigFile *conf, ConfigEntry *ce); static int _test_loadmodule (ConfigFile *conf, ConfigEntry *ce); static int _test_blacklist_module (ConfigFile *conf, ConfigEntry *ce); static int _test_log (ConfigFile *conf, ConfigEntry *ce); @@ -246,10 +243,8 @@ ConfigItem_except *conf_except = NULL; ConfigItem_vhost *conf_vhost = NULL; ConfigItem_link *conf_link = NULL; ConfigItem_ban *conf_ban = NULL; -ConfigItem_deny_dcc *conf_deny_dcc = NULL; ConfigItem_deny_channel *conf_deny_channel = NULL; ConfigItem_allow_channel *conf_allow_channel = NULL; -ConfigItem_allow_dcc *conf_allow_dcc = NULL; ConfigItem_deny_link *conf_deny_link = NULL; ConfigItem_deny_version *conf_deny_version = NULL; ConfigItem_log *conf_log = NULL; @@ -2157,8 +2152,6 @@ void config_rehash() ConfigItem_listen *listen_ptr; ConfigItem_tld *tld_ptr; ConfigItem_vhost *vhost_ptr; - ConfigItem_deny_dcc *deny_dcc_ptr; - ConfigItem_allow_dcc *allow_dcc_ptr; ConfigItem_deny_link *deny_link_ptr; ConfigItem_deny_channel *deny_channel_ptr; ConfigItem_allow_channel *allow_channel_ptr; @@ -2313,17 +2306,6 @@ void config_rehash() remove_config_tkls(); - for (deny_dcc_ptr = conf_deny_dcc; deny_dcc_ptr; deny_dcc_ptr = (ConfigItem_deny_dcc *)next) - { - next = (ListStruct *)deny_dcc_ptr->next; - if (deny_dcc_ptr->flag.type2 == CONF_BAN_TYPE_CONF) - { - safe_free(deny_dcc_ptr->filename); - safe_free(deny_dcc_ptr->reason); - DelListItem(deny_dcc_ptr, conf_deny_dcc); - safe_free(deny_dcc_ptr); - } - } for (deny_link_ptr = conf_deny_link; deny_link_ptr; deny_link_ptr = (ConfigItem_deny_link *) next) { next = (ListStruct *)deny_link_ptr->next; safe_free(deny_link_ptr->prettyrule); @@ -2361,16 +2343,6 @@ void config_rehash() unreal_delete_masks(allow_channel_ptr->mask); safe_free(allow_channel_ptr); } - for (allow_dcc_ptr = conf_allow_dcc; allow_dcc_ptr; allow_dcc_ptr = (ConfigItem_allow_dcc *)next) - { - next = (ListStruct *)allow_dcc_ptr->next; - if (allow_dcc_ptr->flag.type2 == CONF_BAN_TYPE_CONF) - { - safe_free(allow_dcc_ptr->filename); - DelListItem(allow_dcc_ptr, conf_allow_dcc); - safe_free(allow_dcc_ptr); - } - } if (conf_drpass) { @@ -2754,21 +2726,6 @@ int config_test() * Service functions */ -ConfigItem_deny_dcc *Find_deny_dcc(char *name) -{ - ConfigItem_deny_dcc *e; - - if (!name) - return NULL; - - for (e = conf_deny_dcc; e; e = e->next) - { - if (match_simple(name, e->filename)) - return e; - } - return NULL; -} - ConfigItem_alias *Find_alias(char *name) { ConfigItem_alias *e; @@ -5146,8 +5103,6 @@ int _conf_allow(ConfigFile *conf, ConfigEntry *ce) { if (!strcmp(ce->ce_vardata, "channel")) return (_conf_allow_channel(conf, ce)); - else if (!strcmp(ce->ce_vardata, "dcc")) - return (_conf_allow_dcc(conf, ce)); else { int value; @@ -5236,8 +5191,6 @@ int _test_allow(ConfigFile *conf, ConfigEntry *ce) { if (!strcmp(ce->ce_vardata, "channel")) return (_test_allow_channel(conf, ce)); - else if (!strcmp(ce->ce_vardata, "dcc")) - return (_test_allow_dcc(conf, ce)); else { int used = 0; @@ -5549,76 +5502,6 @@ int _test_allow_channel(ConfigFile *conf, ConfigEntry *ce) return errors; } -int _conf_allow_dcc(ConfigFile *conf, ConfigEntry *ce) -{ - ConfigItem_allow_dcc *allow = NULL; - ConfigEntry *cep; - - allow = safe_alloc(sizeof(ConfigItem_allow_dcc)); - - for (cep = ce->ce_entries; cep; cep = cep->ce_next) - { - if (!strcmp(cep->ce_varname, "filename")) - safe_strdup(allow->filename, cep->ce_vardata); - else if (!strcmp(cep->ce_varname, "soft")) - { - int x = config_checkval(cep->ce_vardata,CFG_YESNO); - if (x) - allow->flag.type = DCCDENY_SOFT; - } - } - AddListItem(allow, conf_allow_dcc); - return 1; -} - -int _test_allow_dcc(ConfigFile *conf, ConfigEntry *ce) -{ - ConfigEntry *cep; - int errors = 0, has_filename = 0, has_soft = 0; - - for (cep = ce->ce_entries; cep; cep = cep->ce_next) - { - if (config_is_blankorempty(cep, "allow dcc")) - { - errors++; - continue; - } - if (!strcmp(cep->ce_varname, "filename")) - { - if (has_filename) - { - config_warn_duplicate(cep->ce_fileptr->cf_filename, - cep->ce_varlinenum, "allow dcc::filename"); - continue; - } - has_filename = 1; - } - else if (!strcmp(cep->ce_varname, "soft")) - { - if (has_soft) - { - config_warn_duplicate(cep->ce_fileptr->cf_filename, - cep->ce_varlinenum, "allow dcc::soft"); - continue; - } - has_soft = 1; - } - else - { - config_error_unknown(cep->ce_fileptr->cf_filename, cep->ce_varlinenum, - "allow dcc", cep->ce_varname); - errors++; - } - } - if (!has_filename) - { - config_error_missing(ce->ce_fileptr->cf_filename, ce->ce_varlinenum, - "allow dcc::filename"); - errors++; - } - return errors; -} - int _conf_except(ConfigFile *conf, ConfigEntry *ce) { Hook *h; @@ -9454,9 +9337,7 @@ int _conf_deny(ConfigFile *conf, ConfigEntry *ce) { Hook *h; - if (!strcmp(ce->ce_vardata, "dcc")) - _conf_deny_dcc(conf, ce); - else if (!strcmp(ce->ce_vardata, "channel")) + if (!strcmp(ce->ce_vardata, "channel")) _conf_deny_channel(conf, ce); else if (!strcmp(ce->ce_vardata, "link")) _conf_deny_link(conf, ce); @@ -9476,40 +9357,6 @@ Hook *h; return 0; } -int _conf_deny_dcc(ConfigFile *conf, ConfigEntry *ce) -{ - ConfigItem_deny_dcc *deny = NULL; - ConfigEntry *cep; - - deny = safe_alloc(sizeof(ConfigItem_deny_dcc)); - for (cep = ce->ce_entries; cep; cep = cep->ce_next) - { - if (!strcmp(cep->ce_varname, "filename")) - { - safe_strdup(deny->filename, cep->ce_vardata); - } - else if (!strcmp(cep->ce_varname, "reason")) - { - safe_strdup(deny->reason, cep->ce_vardata); - } - else if (!strcmp(cep->ce_varname, "soft")) - { - int x = config_checkval(cep->ce_vardata,CFG_YESNO); - if (x == 1) - deny->flag.type = DCCDENY_SOFT; - } - } - if (!deny->reason) - { - if (deny->flag.type == DCCDENY_HARD) - safe_strdup(deny->reason, "Possible infected virus file"); - else - safe_strdup(deny->reason, "Possible executable content"); - } - AddListItem(deny, conf_deny_dcc); - return 0; -} - int _conf_deny_channel(ConfigFile *conf, ConfigEntry *ce) { ConfigItem_deny_channel *deny = NULL; @@ -9611,67 +9458,7 @@ int _test_deny(ConfigFile *conf, ConfigEntry *ce) ce->ce_fileptr->cf_filename, ce->ce_varlinenum); return 1; } - if (!strcmp(ce->ce_vardata, "dcc")) - { - char has_filename = 0, has_reason = 0, has_soft = 0; - for (cep = ce->ce_entries; cep; cep = cep->ce_next) - { - if (config_is_blankorempty(cep, "deny dcc")) - { - errors++; - continue; - } - if (!strcmp(cep->ce_varname, "filename")) - { - if (has_filename) - { - config_warn_duplicate(cep->ce_fileptr->cf_filename, - cep->ce_varlinenum, "deny dcc::filename"); - continue; - } - has_filename = 1; - } - else if (!strcmp(cep->ce_varname, "reason")) - { - if (has_reason) - { - config_warn_duplicate(cep->ce_fileptr->cf_filename, - cep->ce_varlinenum, "deny dcc::reason"); - continue; - } - has_reason = 1; - } - else if (!strcmp(cep->ce_varname, "soft")) - { - if (has_soft) - { - config_warn_duplicate(cep->ce_fileptr->cf_filename, - cep->ce_varlinenum, "deny dcc::soft"); - continue; - } - has_soft = 1; - } - else - { - config_error_unknown(cep->ce_fileptr->cf_filename, - cep->ce_varlinenum, "deny dcc", cep->ce_varname); - errors++; - } - } - if (!has_filename) - { - config_error_missing(ce->ce_fileptr->cf_filename, ce->ce_varlinenum, - "deny dcc::filename"); - errors++; - } - if (!has_reason) - { - config_error_missing(ce->ce_fileptr->cf_filename, ce->ce_varlinenum, - "deny dcc::reason"); - errors++; - } - } - else if (!strcmp(ce->ce_vardata, "channel")) + if (!strcmp(ce->ce_vardata, "channel")) { char has_channel = 0, has_warn = 0, has_reason = 0, has_redirect = 0, has_class = 0; for (cep = ce->ce_entries; cep; cep = cep->ce_next) diff --git a/src/extra.c b/src/extra.c index 72120cc52..632e4a7f8 100644 --- a/src/extra.c +++ b/src/extra.c @@ -24,116 +24,6 @@ ID_Copyright("(C) Carsten Munk 1999"); -/* e->flag.type2: - * CONF_BAN_TYPE_AKILL banned by SVSFLINE ('global') - * CONF_BAN_TYPE_CONF banned by conf - * CONF_BAN_TYPE_TEMPORARY banned by /DCCDENY ('temporary') - * e->flag.type: - * DCCDENY_HARD Fully denied - * DCCDENY_SOFT Denied, but allowed to override via /DCCALLOW - */ - -/* checks if the dcc is blacklisted. - */ -ConfigItem_deny_dcc *dcc_isforbidden(Client *client, char *filename) -{ -ConfigItem_deny_dcc *d; -ConfigItem_allow_dcc *a; - - if (!conf_deny_dcc || !filename) - return NULL; - - for (d = conf_deny_dcc; d; d = d->next) - { - if ((d->flag.type == DCCDENY_HARD) && match_simple(d->filename, filename)) - { - for (a = conf_allow_dcc; a; a = a->next) - { - if ((a->flag.type == DCCDENY_HARD) && match_simple(a->filename, filename)) - return NULL; - } - return d; - } - } - - return NULL; -} - -/* checks if the dcc is discouraged ('soft bans'). - */ -ConfigItem_deny_dcc *dcc_isdiscouraged(Client *client, char *filename) -{ -ConfigItem_deny_dcc *d; -ConfigItem_allow_dcc *a; - - if (!conf_deny_dcc || !filename) - return NULL; - - for (d = conf_deny_dcc; d; d = d->next) - { - if ((d->flag.type == DCCDENY_SOFT) && match_simple(d->filename, filename)) - { - for (a = conf_allow_dcc; a; a = a->next) - { - if ((a->flag.type == DCCDENY_SOFT) && match_simple(a->filename, filename)) - return NULL; - } - return d; - } - } - - return NULL; -} - -void dcc_sync(Client *client) -{ - ConfigItem_deny_dcc *p; - for (p = conf_deny_dcc; p; p = p->next) - { - if (p->flag.type2 == CONF_BAN_TYPE_AKILL) - sendto_one(client, NULL, ":%s SVSFLINE + %s :%s", me.id, - p->filename, p->reason); - } -} - -void DCCdeny_add(char *filename, char *reason, int type, int type2) -{ - ConfigItem_deny_dcc *deny = NULL; - - deny = safe_alloc(sizeof(ConfigItem_deny_dcc)); - safe_strdup(deny->filename, filename); - safe_strdup(deny->reason, reason); - deny->flag.type = type; - deny->flag.type2 = type2; - AddListItem(deny, conf_deny_dcc); -} - -void DCCdeny_del(ConfigItem_deny_dcc *deny) -{ - DelListItem(deny, conf_deny_dcc); - safe_free(deny->filename); - safe_free(deny->reason); - safe_free(deny); -} - -void dcc_wipe_services(void) -{ - ConfigItem_deny_dcc *dconf, *next; - - for (dconf = conf_deny_dcc; dconf; dconf = next) - { - next = dconf->next; - if (dconf->flag.type2 == CONF_BAN_TYPE_AKILL) - { - DelListItem(dconf, conf_deny_dcc); - safe_free(dconf->filename); - safe_free(dconf->reason); - safe_free(dconf); - } - } - -} - /* The dccallow functions below are all taken from bahamut (1.8.1). * Well, with some small modifications of course. -- Syzop */ diff --git a/src/modules/Makefile.in b/src/modules/Makefile.in index bf46aa498..fe1857009 100644 --- a/src/modules/Makefile.in +++ b/src/modules/Makefile.in @@ -52,7 +52,7 @@ R_MODULES= \ wallops.so admin.so globops.so locops.so \ trace.so netinfo.so links.so help.so rules.so \ close.so map.so eos.so server.so stats.so \ - svsfline.so dccdeny.so undccdeny.so whowas.so \ + dccdeny.so whowas.so \ connect.so dccallow.so userip.so nick.so user.so \ mode.so watch.so part.so join.so motd.so opermotd.so \ botmotd.so lusers.so names.so svsnolag.so addmotd.so \ @@ -376,18 +376,10 @@ stats.so: stats.c $(INCLUDES) $(CC) $(CFLAGS) $(MODULEFLAGS) -DDYNAMIC_LINKING \ -o stats.so stats.c -svsfline.so: svsfline.c $(INCLUDES) - $(CC) $(CFLAGS) $(MODULEFLAGS) -DDYNAMIC_LINKING \ - -o svsfline.so svsfline.c - dccdeny.so: dccdeny.c $(INCLUDES) $(CC) $(CFLAGS) $(MODULEFLAGS) -DDYNAMIC_LINKING \ -o dccdeny.so dccdeny.c -undccdeny.so: undccdeny.c $(INCLUDES) - $(CC) $(CFLAGS) $(MODULEFLAGS) -DDYNAMIC_LINKING \ - -o undccdeny.so undccdeny.c - whowas.so: whowas.c $(INCLUDES) $(CC) $(CFLAGS) $(MODULEFLAGS) -DDYNAMIC_LINKING \ -o whowas.so whowas.c diff --git a/src/modules/dccdeny.c b/src/modules/dccdeny.c index a24865a6d..43f70e870 100644 --- a/src/modules/dccdeny.c +++ b/src/modules/dccdeny.c @@ -1,6 +1,6 @@ /* - * IRC - Internet Relay Chat, src/modules/out.c - * (C) 2004 The UnrealIRCd Team + * IRC - Internet Relay Chat, src/modules/dccdeny.c + * (C) 2004-2019 The UnrealIRCd Team * * See file AUTHORS in IRC package for additional names of * the programmers. @@ -22,10 +22,6 @@ #include "unrealircd.h" -CMD_FUNC(cmd_dccdeny); - -#define MSG_DCCDENY "DCCDENY" - ModuleHeader MOD_HEADER = { "dccdeny", @@ -35,10 +31,53 @@ ModuleHeader MOD_HEADER "unrealircd-5", }; +/* Variables */ +ConfigItem_deny_dcc *conf_deny_dcc = NULL; +ConfigItem_allow_dcc *conf_allow_dcc = NULL; + +/* Forward declarions */ +int dccdeny_configtest_deny_dcc(ConfigFile *cf, ConfigEntry *ce, int type, int *errs); +int dccdeny_configtest_allow_dcc(ConfigFile *cf, ConfigEntry *ce, int type, int *errs); +int dccdeny_configrun_deny_dcc(ConfigFile *cf, ConfigEntry *ce, int type); +int dccdeny_configrun_allow_dcc(ConfigFile *cf, ConfigEntry *ce, int type); +CMD_FUNC(cmd_dccdeny); +CMD_FUNC(cmd_undccdeny); +CMD_FUNC(cmd_svsfline); +int dccdeny_can_send_to_user(Client *client, Client *target, char **text, char **errmsg, int notice); +int dccdeny_can_send_to_channel(Client *client, Channel *channel, Membership *lp, char **msg, char **errmsg, int notice); +int dccdeny_server_sync(Client *client); +static ConfigItem_deny_dcc *dcc_isforbidden(Client *client, char *filename); +static ConfigItem_deny_dcc *dcc_isdiscouraged(Client *client, char *filename); +static void DCCdeny_add(char *filename, char *reason, int type, int type2); +static void DCCdeny_del(ConfigItem_deny_dcc *deny); +static void dcc_wipe_services(void); +static char *get_dcc_filename(const char *text); +static int can_dcc(Client *client, char *target, Client *targetcli, char *filename, char **errmsg); +static int can_dcc_soft(Client *from, Client *to, char *filename, char **errmsg); +static void free_dcc_config_blocks(void); +void dccdeny_unload_free_all_conf_deny_dcc(ModData *m); +void dccdeny_unload_free_all_conf_allow_dcc(ModData *m); + +MOD_TEST() +{ + HookAdd(modinfo->handle, HOOKTYPE_CONFIGTEST, 0, dccdeny_configtest_deny_dcc); + HookAdd(modinfo->handle, HOOKTYPE_CONFIGTEST, 0, dccdeny_configtest_allow_dcc); + return MOD_SUCCESS; +} + MOD_INIT() { - CommandAdd(modinfo->handle, MSG_DCCDENY, cmd_dccdeny, 2, CMD_USER); MARK_AS_OFFICIAL_MODULE(modinfo); + LoadPersistentPointer(modinfo, conf_deny_dcc, dccdeny_unload_free_all_conf_deny_dcc); + LoadPersistentPointer(modinfo, conf_allow_dcc, dccdeny_unload_free_all_conf_allow_dcc); + HookAdd(modinfo->handle, HOOKTYPE_CONFIGRUN, 0, dccdeny_configrun_deny_dcc); + HookAdd(modinfo->handle, HOOKTYPE_CONFIGRUN, 0, dccdeny_configrun_allow_dcc); + CommandAdd(modinfo->handle, "DCCDENY", cmd_dccdeny, 2, CMD_USER); + CommandAdd(modinfo->handle, "UNDCCDENY", cmd_undccdeny, MAXPARA, CMD_USER); + CommandAdd(modinfo->handle, "SVSFLINE", cmd_svsfline, MAXPARA, CMD_SERVER); + HookAdd(modinfo->handle, HOOKTYPE_CAN_SEND_TO_USER, 0, dccdeny_can_send_to_user); + HookAdd(modinfo->handle, HOOKTYPE_CAN_SEND_TO_CHANNEL, 0, dccdeny_can_send_to_channel); + HookAdd(modinfo->handle, HOOKTYPE_SERVER_SYNC, 0, dccdeny_server_sync); return MOD_SUCCESS; } @@ -49,9 +88,263 @@ MOD_LOAD() MOD_UNLOAD() { + free_dcc_config_blocks(); + SavePersistentPointer(modinfo, conf_deny_dcc); + SavePersistentPointer(modinfo, conf_allow_dcc); + return MOD_SUCCESS; } +int dccdeny_configtest_deny_dcc(ConfigFile *cf, ConfigEntry *ce, int type, int *errs) +{ + ConfigEntry *cep; + int errors = 0; + char has_filename = 0, has_reason = 0, has_soft = 0; + + /* We are only interested in deny dcc { } */ + if ((type != CONFIG_DENY) || strcmp(ce->ce_vardata, "dcc")) + return 0; + + for (cep = ce->ce_entries; cep; cep = cep->ce_next) + { + if (config_is_blankorempty(cep, "deny dcc")) + { + errors++; + continue; + } + if (!strcmp(cep->ce_varname, "filename")) + { + if (has_filename) + { + config_warn_duplicate(cep->ce_fileptr->cf_filename, + cep->ce_varlinenum, "deny dcc::filename"); + continue; + } + has_filename = 1; + } + else if (!strcmp(cep->ce_varname, "reason")) + { + if (has_reason) + { + config_warn_duplicate(cep->ce_fileptr->cf_filename, + cep->ce_varlinenum, "deny dcc::reason"); + continue; + } + has_reason = 1; + } + else if (!strcmp(cep->ce_varname, "soft")) + { + if (has_soft) + { + config_warn_duplicate(cep->ce_fileptr->cf_filename, + cep->ce_varlinenum, "deny dcc::soft"); + continue; + } + has_soft = 1; + } + else + { + config_error_unknown(cep->ce_fileptr->cf_filename, + cep->ce_varlinenum, "deny dcc", cep->ce_varname); + errors++; + } + } + if (!has_filename) + { + config_error_missing(ce->ce_fileptr->cf_filename, ce->ce_varlinenum, + "deny dcc::filename"); + errors++; + } + if (!has_reason) + { + config_error_missing(ce->ce_fileptr->cf_filename, ce->ce_varlinenum, + "deny dcc::reason"); + errors++; + } + + *errs = errors; + return errors ? -1 : 1; +} + +int dccdeny_configtest_allow_dcc(ConfigFile *cf, ConfigEntry *ce, int type, int *errs) +{ + ConfigEntry *cep; + int errors = 0, has_filename = 0, has_soft = 0; + + /* We are only interested in allow dcc { } */ + if ((type != CONFIG_ALLOW) || strcmp(ce->ce_vardata, "dcc")) + return 0; + + for (cep = ce->ce_entries; cep; cep = cep->ce_next) + { + if (config_is_blankorempty(cep, "allow dcc")) + { + errors++; + continue; + } + if (!strcmp(cep->ce_varname, "filename")) + { + if (has_filename) + { + config_warn_duplicate(cep->ce_fileptr->cf_filename, + cep->ce_varlinenum, "allow dcc::filename"); + continue; + } + has_filename = 1; + } + else if (!strcmp(cep->ce_varname, "soft")) + { + if (has_soft) + { + config_warn_duplicate(cep->ce_fileptr->cf_filename, + cep->ce_varlinenum, "allow dcc::soft"); + continue; + } + has_soft = 1; + } + else + { + config_error_unknown(cep->ce_fileptr->cf_filename, cep->ce_varlinenum, + "allow dcc", cep->ce_varname); + errors++; + } + } + if (!has_filename) + { + config_error_missing(ce->ce_fileptr->cf_filename, ce->ce_varlinenum, + "allow dcc::filename"); + errors++; + } + + *errs = errors; + return errors ? -1 : 1; +} + +int dccdeny_configrun_deny_dcc(ConfigFile *cf, ConfigEntry *ce, int type) +{ + ConfigItem_deny_dcc *deny = NULL; + ConfigEntry *cep; + + /* We are only interested in deny dcc { } */ + if ((type != CONFIG_DENY) || strcmp(ce->ce_vardata, "dcc")) + return 0; + + deny = safe_alloc(sizeof(ConfigItem_deny_dcc)); + for (cep = ce->ce_entries; cep; cep = cep->ce_next) + { + if (!strcmp(cep->ce_varname, "filename")) + { + safe_strdup(deny->filename, cep->ce_vardata); + } + else if (!strcmp(cep->ce_varname, "reason")) + { + safe_strdup(deny->reason, cep->ce_vardata); + } + else if (!strcmp(cep->ce_varname, "soft")) + { + int x = config_checkval(cep->ce_vardata,CFG_YESNO); + if (x == 1) + deny->flag.type = DCCDENY_SOFT; + } + } + if (!deny->reason) + { + if (deny->flag.type == DCCDENY_HARD) + safe_strdup(deny->reason, "Possible infected virus file"); + else + safe_strdup(deny->reason, "Possible executable content"); + } + AddListItem(deny, conf_deny_dcc); + return 0; +} + +int dccdeny_configrun_allow_dcc(ConfigFile *cf, ConfigEntry *ce, int type) +{ + ConfigItem_allow_dcc *allow = NULL; + ConfigEntry *cep; + + /* We are only interested in allow dcc { } */ + if ((type != CONFIG_ALLOW) || strcmp(ce->ce_vardata, "dcc")) + return 0; + + allow = safe_alloc(sizeof(ConfigItem_allow_dcc)); + + for (cep = ce->ce_entries; cep; cep = cep->ce_next) + { + if (!strcmp(cep->ce_varname, "filename")) + safe_strdup(allow->filename, cep->ce_vardata); + else if (!strcmp(cep->ce_varname, "soft")) + { + int x = config_checkval(cep->ce_vardata,CFG_YESNO); + if (x) + allow->flag.type = DCCDENY_SOFT; + } + } + AddListItem(allow, conf_allow_dcc); + return 1; +} + +/** Free allow dcc { } and deny dcc { } blocks, called on REHASH */ +void free_dcc_config_blocks(void) +{ + ConfigItem_deny_dcc *d, *d_next; + ConfigItem_allow_dcc *a, *a_next; + + for (d = conf_deny_dcc; d; d = d_next) + { + d_next = d->next; + if (d->flag.type2 == CONF_BAN_TYPE_CONF) + { + safe_free(d->filename); + safe_free(d->reason); + DelListItem(d, conf_deny_dcc); + safe_free(d); + } + } + for (a = conf_allow_dcc; a; a = a_next) + { + a_next = a->next; + if (a->flag.type2 == CONF_BAN_TYPE_CONF) + { + safe_free(a->filename); + DelListItem(a, conf_allow_dcc); + safe_free(a); + } + } +} + +/** Free all deny dcc { } blocks - only called on permanent module unload (rare) */ +void dccdeny_unload_free_all_conf_deny_dcc(ModData *m) +{ + ConfigItem_deny_dcc *d, *d_next; + + for (d = conf_deny_dcc; d; d = d_next) + { + d_next = d->next; + safe_free(d->filename); + safe_free(d->reason); + DelListItem(d, conf_deny_dcc); + safe_free(d); + } + conf_deny_dcc = NULL; +} + +/** Free all allow dcc { } blocks - only called on permanent module unload (rare) */ +void dccdeny_unload_free_all_conf_allow_dcc(ModData *m) +{ + ConfigItem_allow_dcc *a, *a_next; + + for (a = conf_allow_dcc; a; a = a_next) + { + a_next = a->next; + safe_free(a->filename); + DelListItem(a, conf_allow_dcc); + safe_free(a); + } + conf_allow_dcc = NULL; +} + + /* Add a temporary dccdeny line * * parv[1] - file @@ -85,3 +378,483 @@ CMD_FUNC(cmd_dccdeny) sendnotice(client, "*** %s already has a dccdeny", parv[1]); } } + +/* Remove a temporary dccdeny line + * parv[1] - file/mask + */ +CMD_FUNC(cmd_undccdeny) +{ + ConfigItem_deny_dcc *d; + + if (!MyUser(client)) + return; + + if (!ValidatePermissionsForPath("server-ban:dccdeny",client,NULL,NULL,NULL)) + { + sendnumeric(client, ERR_NOPRIVILEGES); + return; + } + + if ((parc < 2) || BadPtr(parv[1])) + { + sendnumeric(client, ERR_NEEDMOREPARAMS, "UNDCCDENY"); + return; + } + + if ((d = Find_deny_dcc(parv[1])) && d->flag.type2 == CONF_BAN_TYPE_TEMPORARY) + { + sendto_ops("%s removed a temp dccdeny for %s", client->name, parv[1]); + DCCdeny_del(d); + return; + } else + { + sendnotice(client, "*** Unable to find a temp dccdeny matching %s", parv[1]); + } +} + +CMD_FUNC(cmd_svsfline) +{ + if (parc < 2) + return; + + switch (*parv[1]) + { + /* Allow non-U-Lines to send ONLY SVSFLINE +, but don't send it out + * unless it is from a U-Line -- codemastr + */ + case '+': + { + if (parc < 4) + return; + + if (!Find_deny_dcc(parv[2])) + DCCdeny_add(parv[2], parv[3], DCCDENY_HARD, CONF_BAN_TYPE_AKILL); + + if (IsULine(client)) + { + sendto_server(client, 0, 0, NULL, ":%s SVSFLINE + %s :%s", + client->id, parv[2], parv[3]); + } + + break; + } + + case '-': + { + ConfigItem_deny_dcc *deny; + + if (!IsULine(client)) + return; + + if (parc < 3) + return; + + if (!(deny = Find_deny_dcc(parv[2]))) + break; + + DCCdeny_del(deny); + + sendto_server(client, 0, 0, NULL, ":%s SVSFLINE %s", client->id, parv[2]); + + break; + } + + case '*': + { + if (!IsULine(client)) + return; + + dcc_wipe_services(); + + sendto_server(client, 0, 0, NULL, ":%s SVSFLINE *", client->id); + + break; + } + } +} + +/** Sync the DCC entries on server connect */ +int dccdeny_server_sync(Client *client) +{ + ConfigItem_deny_dcc *p; + for (p = conf_deny_dcc; p; p = p->next) + { + if (p->flag.type2 == CONF_BAN_TYPE_AKILL) + sendto_one(client, NULL, ":%s SVSFLINE + %s :%s", me.id, + p->filename, p->reason); + } + return 0; +} + +/** Check if a DCC should be blocked (user-to-user) */ +int dccdeny_can_send_to_user(Client *client, Client *target, char **text, char **errmsg, int notice) +{ + if (**text == '\001') + { + char *filename = get_dcc_filename(*text); + if (filename) + { + if (MyUser(client) && !can_dcc(client, target->name, target, filename, errmsg)) + return HOOK_DENY; + if (MyUser(target) && !can_dcc_soft(client, target, filename, errmsg)) + return HOOK_DENY; + } + } + + return HOOK_CONTINUE; +} + +/** Check if a DCC should be blocked (user-to-channel, unusual) */ +int dccdeny_can_send_to_channel(Client *client, Channel *channel, Membership *lp, char **msg, char **errmsg, int notice) +{ + static char errbuf[512]; + + if (MyUser(client) && (**msg == '\001')) + { + char *err = NULL; + char *filename = get_dcc_filename(*msg); + if (filename && !can_dcc(client, channel->chname, NULL, filename, &err)) + { + if (!IsDead(client) && !notice) + { + strlcpy(errbuf, err, sizeof(errbuf)); + *errmsg = errbuf; + } + return HOOK_DENY; + } + } + return HOOK_CONTINUE; +} + +/* e->flag.type2: + * CONF_BAN_TYPE_AKILL banned by SVSFLINE ('global') + * CONF_BAN_TYPE_CONF banned by conf + * CONF_BAN_TYPE_TEMPORARY banned by /DCCDENY ('temporary') + * e->flag.type: + * DCCDENY_HARD Fully denied + * DCCDENY_SOFT Denied, but allowed to override via /DCCALLOW + */ + +/** Make a viewable dcc filename. + * This is to protect a bit against tricks like 'flood-it-off-the-buffer' + * and color 1,1 etc... + */ +static char *dcc_displayfile(char *f) +{ + static char buf[512]; + char *i, *o = buf; + size_t n = strlen(f); + + if (n < 300) + { + for (i = f; *i; i++) + if (*i < 32) + *o++ = '?'; + else + *o++ = *i; + *o = '\0'; + return buf; + } + + /* Else, we show it as: [first 256 chars]+"[..TRUNCATED..]"+[last 20 chars] */ + for (i = f; i < f+256; i++) + if (*i < 32) + *o++ = '?'; + else + *o++ = *i; + strcpy(o, "[..TRUNCATED..]"); + o += sizeof("[..TRUNCATED..]"); + for (i = f+n-20; *i; i++) + if (*i < 32) + *o++ = '?'; + else + *o++ = *i; + *o = '\0'; + return buf; +} + +static char *get_dcc_filename(const char *text) +{ + static char filename[BUFSIZE+1]; + char *end; + int size_string; + + if (*text != '\001') + return 0; + + if (!strncasecmp(text+1, "DCC SEND ", 9)) + text = text + 10; + else if (!strncasecmp(text+1, "DCC RESUME ", 11)) + text = text + 12; + else + return 0; + + for (; *text == ' '; text++); /* skip leading spaces */ + + if (*text == '"' && *(text+1)) + end = strchr(text+1, '"'); + else + end = strchr(text, ' '); + + if (!end || (end < text)) + return 0; + + size_string = (int)(end - text); + + if (!size_string || (size_string > (BUFSIZE - 1))) + return 0; + + strlcpy(filename, text, size_string+1); + return filename; +} + +/** Checks if a DCC SEND is allowed. + * @param client Sending client + * @param target Target name (user or channel) + * @param targetcli Target client (NULL in case of channel!) + * @param text The entire message + * @returns 1 if DCC SEND allowed, 0 if rejected + */ +static int can_dcc(Client *client, char *target, Client *targetcli, char *filename, char **errmsg) +{ + ConfigItem_deny_dcc *fl; + static char errbuf[256]; + int size_string, ret; + + /* User (IRCOp) may bypass send restrictions */ + if (ValidatePermissionsForPath("immune:dcc",client,targetcli,NULL,NULL)) + return 1; + + /* User (IRCOp) likes to receive bad dcc's */ + if (targetcli && ValidatePermissionsForPath("self:getbaddcc",targetcli,NULL,NULL,NULL)) + return 1; + + /* Check if user is already blocked (from the past) */ + if (IsDCCBlock(client)) + { + *errmsg = "*** You are blocked from sending files as you have tried to " + "send a forbidden file - reconnect to regain ability to send"; + return 0; + } + + if (match_spamfilter(client, filename, SPAMF_DCC, target, 0, NULL)) + return 0; + + if ((fl = dcc_isforbidden(client, filename))) + { + char *displayfile = dcc_displayfile(filename); + + RunHook5(HOOKTYPE_DCC_DENIED, client, target, filename, displayfile, fl); + + ircsnprintf(errbuf, sizeof(errbuf), "Cannot DCC SEND file: %s", fl->reason); + *errmsg = errbuf; + SetDCCBlock(client); + return 0; + } + + /* Channel dcc (???) and discouraged? just block */ + if (!targetcli && ((fl = dcc_isdiscouraged(client, filename)))) + { + ircsnprintf(errbuf, sizeof(errbuf), "Cannot DCC SEND file: %s", fl->reason); + *errmsg = errbuf; + return 0; + } + + /* If we get here, the file is allowed */ + return 1; +} + +/** Checks if a DCC is allowed by DCCALLOW rules (only SOFT bans are checked). + * PARAMETERS: + * from: the sender client (possibly remote) + * to: the target client (always local) + * text: the whole msg + * RETURNS: + * 1: allowed + * 0: block + */ +static int can_dcc_soft(Client *from, Client *to, char *filename, char **errmsg) +{ + ConfigItem_deny_dcc *fl; + char *displayfile; + static char errbuf[256]; + + /* User (IRCOp) may bypass send restrictions */ + if (ValidatePermissionsForPath("immune:dcc",from,to,NULL,NULL)) + return 1; + + /* User (IRCOp) likes to receive bad dcc's */ + if (ValidatePermissionsForPath("self:getbaddcc",to,NULL,NULL,NULL)) + return 1; + + /* On the 'soft' blocklist ? */ + if (!(fl = dcc_isdiscouraged(from, filename))) + return 1; /* No, so is OK */ + + /* If on DCCALLOW list then the user is OK with it */ + if (on_dccallow_list(to, from)) + return 1; + + /* Soft-blocked */ + displayfile = dcc_displayfile(filename); + + ircsnprintf(errbuf, sizeof(errbuf), "Cannot DCC SEND file: %s", fl->reason); + *errmsg = errbuf; + + /* Inform target ('to') about the /DCCALLOW functionality */ + sendnotice(to, "%s (%s@%s) tried to DCC SEND you a file named '%s', the request has been blocked.", + from->name, from->user->username, GetHost(from), displayfile); + if (!IsDCCNotice(to)) + { + SetDCCNotice(to); + sendnotice(to, "Files like these might contain malicious content (viruses, trojans). " + "Therefore, you must explicitly allow anyone that tries to send you such files."); + sendnotice(to, "If you trust %s, and want him/her to send you this file, you may obtain " + "more information on using the dccallow system by typing '/DCCALLOW HELP'", from->name); + } + return 0; +} + +/** Checks if the dcc is blacklisted. */ +static ConfigItem_deny_dcc *dcc_isforbidden(Client *client, char *filename) +{ + ConfigItem_deny_dcc *d; + ConfigItem_allow_dcc *a; + + if (!conf_deny_dcc || !filename) + return NULL; + + for (d = conf_deny_dcc; d; d = d->next) + { + if ((d->flag.type == DCCDENY_HARD) && match_simple(d->filename, filename)) + { + for (a = conf_allow_dcc; a; a = a->next) + { + if ((a->flag.type == DCCDENY_HARD) && match_simple(a->filename, filename)) + return NULL; + } + return d; + } + } + + return NULL; +} + +/** checks if the dcc is discouraged ('soft bans'). */ +static ConfigItem_deny_dcc *dcc_isdiscouraged(Client *client, char *filename) +{ + ConfigItem_deny_dcc *d; + ConfigItem_allow_dcc *a; + + if (!conf_deny_dcc || !filename) + return NULL; + + for (d = conf_deny_dcc; d; d = d->next) + { + if ((d->flag.type == DCCDENY_SOFT) && match_simple(d->filename, filename)) + { + for (a = conf_allow_dcc; a; a = a->next) + { + if ((a->flag.type == DCCDENY_SOFT) && match_simple(a->filename, filename)) + return NULL; + } + return d; + } + } + + return NULL; +} + +static void DCCdeny_add(char *filename, char *reason, int type, int type2) +{ + ConfigItem_deny_dcc *deny = NULL; + + deny = safe_alloc(sizeof(ConfigItem_deny_dcc)); + safe_strdup(deny->filename, filename); + safe_strdup(deny->reason, reason); + deny->flag.type = type; + deny->flag.type2 = type2; + AddListItem(deny, conf_deny_dcc); +} + +static void DCCdeny_del(ConfigItem_deny_dcc *deny) +{ + DelListItem(deny, conf_deny_dcc); + safe_free(deny->filename); + safe_free(deny->reason); + safe_free(deny); +} + +ConfigItem_deny_dcc *Find_deny_dcc(char *name) +{ + ConfigItem_deny_dcc *e; + + if (!name) + return NULL; + + for (e = conf_deny_dcc; e; e = e->next) + { + if (match_simple(name, e->filename)) + return e; + } + return NULL; +} + +static void dcc_wipe_services(void) +{ + ConfigItem_deny_dcc *dconf, *next; + + for (dconf = conf_deny_dcc; dconf; dconf = next) + { + next = dconf->next; + if (dconf->flag.type2 == CONF_BAN_TYPE_AKILL) + { + DelListItem(dconf, conf_deny_dcc); + safe_free(dconf->filename); + safe_free(dconf->reason); + safe_free(dconf); + } + } + +} + +// FIXME: hook into HOOKTYPE_STATS +int stats_denydcc(Client *client, char *para) +{ + ConfigItem_deny_dcc *denytmp; + ConfigItem_allow_dcc *allowtmp; + char *filemask, *reason; + char a = 0; + + for (denytmp = conf_deny_dcc; denytmp; denytmp = denytmp->next) + { + filemask = BadPtr(denytmp->filename) ? "" : denytmp->filename; + reason = BadPtr(denytmp->reason) ? "" : denytmp->reason; + if (denytmp->flag.type2 == CONF_BAN_TYPE_CONF) + a = 'c'; + if (denytmp->flag.type2 == CONF_BAN_TYPE_AKILL) + a = 's'; + if (denytmp->flag.type2 == CONF_BAN_TYPE_TEMPORARY) + a = 'o'; + /* */ + sendtxtnumeric(client, "d %c %c %s %s", (denytmp->flag.type == DCCDENY_SOFT) ? 's' : 'h', + a, filemask, reason); + } + for (allowtmp = conf_allow_dcc; allowtmp; allowtmp = allowtmp->next) + { + filemask = BadPtr(allowtmp->filename) ? "" : allowtmp->filename; + if (allowtmp->flag.type2 == CONF_BAN_TYPE_CONF) + a = 'c'; + if (allowtmp->flag.type2 == CONF_BAN_TYPE_AKILL) + a = 's'; + if (allowtmp->flag.type2 == CONF_BAN_TYPE_TEMPORARY) + a = 'o'; + /* */ + sendtxtnumeric(client, "a %c %c %s", (allowtmp->flag.type == DCCDENY_SOFT) ? 's' : 'h', + a, filemask); + } + return 0; +} + +// { 'F', "denydcc", stats_denydcc, 0 }, + diff --git a/src/modules/message.c b/src/modules/message.c index 2123c94a6..eb902ea3a 100644 --- a/src/modules/message.c +++ b/src/modules/message.c @@ -74,10 +74,6 @@ MOD_UNLOAD() return MOD_SUCCESS; } -char *get_dcc_filename(const char *text); -static int can_dcc(Client *client, char *target, Client *targetcli, char *filename, char **errmsg); -static int can_dcc_soft(Client *from, Client *to, char *filename, char **errmsg); - #define CANPRIVMSG_CONTINUE 100 #define CANPRIVMSG_SEND 101 /** Check if PRIVMSG's are permitted from a person to another person. @@ -103,18 +99,6 @@ int can_send_to_user(Client *client, Client *target, char **msgtext, char **errm return 0; } - if (**msgtext == '\001') - { - char *filename = get_dcc_filename(*msgtext); - if (filename) - { - if (MyUser(client) && !can_dcc(client, target->name, target, filename, errmsg)) - return 0; - if (MyUser(target) && !can_dcc_soft(client, target, filename, errmsg)) - return 0; - } - } - if (MyUser(client) && target_limit_exceeded(client, target, target->name)) { /* target_limit_exceeded() is an exception, in the sense that @@ -358,20 +342,6 @@ void cmd_message(Client *client, MessageTag *recv_mtags, int parc, char *parv[], targetstr = pfixchan; } - if (MyUser(client) && (*parv[2] == '\001')) - { - char *errmsg = NULL; - char *filename = get_dcc_filename(parv[2]); - if (filename && !can_dcc(client, channel->chname, NULL, filename, &errmsg)) - { - if (IsDead(client)) - return; - if (!IsDead(client) && !notice) - sendnumeric(client, ERR_CANNOTSENDTOCHAN, channel->chname, errmsg, p2); - continue; - } - } - if (IsVirus(client) && strcasecmp(channel->chname, SPAMFILTER_VIRUSCHAN)) { sendnotice(client, "You are only allowed to talk in '%s'", SPAMFILTER_VIRUSCHAN); @@ -540,186 +510,6 @@ CMD_FUNC(cmd_notice) cmd_message(client, recv_mtags, parc, parv, 1); } -/** Make a viewable dcc filename. - * This is to protect a bit against tricks like 'flood-it-off-the-buffer' - * and color 1,1 etc... - */ -char *dcc_displayfile(char *f) -{ - static char buf[512]; - char *i, *o = buf; - size_t n = strlen(f); - - if (n < 300) - { - for (i = f; *i; i++) - if (*i < 32) - *o++ = '?'; - else - *o++ = *i; - *o = '\0'; - return buf; - } - - /* Else, we show it as: [first 256 chars]+"[..TRUNCATED..]"+[last 20 chars] */ - for (i = f; i < f+256; i++) - if (*i < 32) - *o++ = '?'; - else - *o++ = *i; - strcpy(o, "[..TRUNCATED..]"); - o += sizeof("[..TRUNCATED..]"); - for (i = f+n-20; *i; i++) - if (*i < 32) - *o++ = '?'; - else - *o++ = *i; - *o = '\0'; - return buf; -} - -char *get_dcc_filename(const char *text) -{ - static char filename[BUFSIZE+1]; - char *end; - int size_string; - - if (*text != '\001') - return 0; - - if (!strncasecmp(text+1, "DCC SEND ", 9)) - text = text + 10; - else if (!strncasecmp(text+1, "DCC RESUME ", 11)) - text = text + 12; - else - return 0; - - for (; *text == ' '; text++); /* skip leading spaces */ - - if (*text == '"' && *(text+1)) - end = strchr(text+1, '"'); - else - end = strchr(text, ' '); - - if (!end || (end < text)) - return 0; - - size_string = (int)(end - text); - - if (!size_string || (size_string > (BUFSIZE - 1))) - return 0; - - strlcpy(filename, text, size_string+1); - return filename; -} - -/** Checks if a DCC SEND is allowed. - * @param client Sending client - * @param target Target name (user or channel) - * @param targetcli Target client (NULL in case of channel!) - * @param text The entire message - * @returns 1 if DCC SEND allowed, 0 if rejected - */ -static int can_dcc(Client *client, char *target, Client *targetcli, char *filename, char **errmsg) -{ - ConfigItem_deny_dcc *fl; - static char errbuf[256]; - int size_string, ret; - - /* User (IRCOp) may bypass send restrictions */ - if (ValidatePermissionsForPath("immune:dcc",client,targetcli,NULL,NULL)) - return 1; - - /* User (IRCOp) likes to receive bad dcc's */ - if (targetcli && ValidatePermissionsForPath("self:getbaddcc",targetcli,NULL,NULL,NULL)) - return 1; - - /* Check if user is already blocked (from the past) */ - if (IsDCCBlock(client)) - { - *errmsg = "*** You are blocked from sending files as you have tried to " - "send a forbidden file - reconnect to regain ability to send"; - return 0; - } - - if (match_spamfilter(client, filename, SPAMF_DCC, target, 0, NULL)) - return 0; - - if ((fl = dcc_isforbidden(client, filename))) - { - char *displayfile = dcc_displayfile(filename); - - RunHook5(HOOKTYPE_DCC_DENIED, client, target, filename, displayfile, fl); - - ircsnprintf(errbuf, sizeof(errbuf), "Cannot DCC SEND file: %s", fl->reason); - *errmsg = errbuf; - SetDCCBlock(client); - return 0; - } - - /* Channel dcc (???) and discouraged? just block */ - if (!targetcli && ((fl = dcc_isdiscouraged(client, filename)))) - { - ircsnprintf(errbuf, sizeof(errbuf), "Cannot DCC SEND file: %s", fl->reason); - *errmsg = errbuf; - return 0; - } - - /* If we get here, the file is allowed */ - return 1; -} - -/** Checks if a DCC is allowed by DCCALLOW rules (only SOFT bans are checked). - * PARAMETERS: - * from: the sender client (possibly remote) - * to: the target client (always local) - * text: the whole msg - * RETURNS: - * 1: allowed - * 0: block - */ -static int can_dcc_soft(Client *from, Client *to, char *filename, char **errmsg) -{ - ConfigItem_deny_dcc *fl; - char *displayfile; - static char errbuf[256]; - - /* User (IRCOp) may bypass send restrictions */ - if (ValidatePermissionsForPath("immune:dcc",from,to,NULL,NULL)) - return 1; - - /* User (IRCOp) likes to receive bad dcc's */ - if (ValidatePermissionsForPath("self:getbaddcc",to,NULL,NULL,NULL)) - return 1; - - /* On the 'soft' blocklist ? */ - if (!(fl = dcc_isdiscouraged(from, filename))) - return 1; /* No, so is OK */ - - /* If on DCCALLOW list then the user is OK with it */ - if (on_dccallow_list(to, from)) - return 1; - - /* Soft-blocked */ - displayfile = dcc_displayfile(filename); - - ircsnprintf(errbuf, sizeof(errbuf), "Cannot DCC SEND file: %s", fl->reason); - *errmsg = errbuf; - - /* Inform target ('to') about the /DCCALLOW functionality */ - sendnotice(to, "%s (%s@%s) tried to DCC SEND you a file named '%s', the request has been blocked.", - from->name, from->user->username, GetHost(from), displayfile); - if (!IsDCCNotice(to)) - { - SetDCCNotice(to); - sendnotice(to, "Files like these might contain malicious content (viruses, trojans). " - "Therefore, you must explicitly allow anyone that tries to send you such files."); - sendnotice(to, "If you trust %s, and want him/her to send you this file, you may obtain " - "more information on using the dccallow system by typing '/DCCALLOW HELP'", from->name); - } - return 0; -} - /* Taken from xchat by Peter Zelezny * changed very slightly by codemastr * RGB color stripping support added -- codemastr diff --git a/src/modules/server.c b/src/modules/server.c index f7e680e17..7e2c1f5b1 100644 --- a/src/modules/server.c +++ b/src/modules/server.c @@ -1072,8 +1072,7 @@ int server_sync(Client *cptr, ConfigItem_link *aconf) /* pass on TKLs */ tkl_synch(cptr); - /* send out SVSFLINEs */ - dcc_sync(cptr); + RunHook(HOOKTYPE_SERVER_SYNC, cptr); sendto_one(cptr, NULL, "NETINFO %i %lld %i %s 0 0 0 :%s", irccounts.global_max, (long long)TStime(), UnrealProtocol, diff --git a/src/modules/snomasks/dccreject.c b/src/modules/snomasks/dccreject.c index eac915360..50bccdd8d 100644 --- a/src/modules/snomasks/dccreject.c +++ b/src/modules/snomasks/dccreject.c @@ -33,7 +33,7 @@ ModuleHeader MOD_HEADER long SNO_DCCREJECT = 0L; /* Forward declarations */ -int dccreject_dcc_denied(Client *client, Client *target, char *realfile, char *displayfile, ConfigItem_deny_dcc *dccdeny); +int dccreject_dcc_denied(Client *client, char *target, char *realfile, char *displayfile, ConfigItem_deny_dcc *dccdeny); MOD_TEST() { @@ -60,11 +60,11 @@ MOD_UNLOAD() return MOD_SUCCESS; } -int dccreject_dcc_denied(Client *client, Client *target, char *realfile, char *displayfile, ConfigItem_deny_dcc *dccdeny) +int dccreject_dcc_denied(Client *client, char *target, char *realfile, char *displayfile, ConfigItem_deny_dcc *dccdeny) { sendto_snomask_global(SNO_DCCREJECT, "%s tried to send forbidden file %s (%s) to %s (is blocked now)", - client->name, displayfile, dccdeny->reason, target->name); + client->name, displayfile, dccdeny->reason, target); return 0; } diff --git a/src/modules/stats.c b/src/modules/stats.c index 1b62bb8f7..530d81d19 100644 --- a/src/modules/stats.c +++ b/src/modules/stats.c @@ -69,7 +69,6 @@ int stats_traffic(Client *, char *); int stats_uline(Client *, char *); int stats_vhost(Client *, char *); int stats_denylinkauto(Client *, char *); -int stats_denydcc(Client *, char *); int stats_kline(Client *, char *); int stats_banrealname(Client *, char *); int stats_sqline(Client *, char *); @@ -104,7 +103,6 @@ struct statstab StatsTable[] = { { 'B', "banversion", stats_banversion, 0 }, { 'C', "link", stats_links, 0 }, { 'D', "denylinkall", stats_denylinkall, 0 }, - { 'F', "denydcc", stats_denydcc, 0 }, { 'G', "gline", stats_gline, FLAGS_AS_PARA }, { 'H', "link", stats_links, 0 }, { 'I', "allow", stats_allow, 0 }, @@ -681,43 +679,6 @@ int stats_denylinkauto(Client *client, char *para) return 0; } -int stats_denydcc(Client *client, char *para) -{ - ConfigItem_deny_dcc *denytmp; - ConfigItem_allow_dcc *allowtmp; - char *filemask, *reason; - char a = 0; - - for (denytmp = conf_deny_dcc; denytmp; denytmp = denytmp->next) - { - filemask = BadPtr(denytmp->filename) ? "" : denytmp->filename; - reason = BadPtr(denytmp->reason) ? "" : denytmp->reason; - if (denytmp->flag.type2 == CONF_BAN_TYPE_CONF) - a = 'c'; - if (denytmp->flag.type2 == CONF_BAN_TYPE_AKILL) - a = 's'; - if (denytmp->flag.type2 == CONF_BAN_TYPE_TEMPORARY) - a = 'o'; - /* */ - sendtxtnumeric(client, "d %c %c %s %s", (denytmp->flag.type == DCCDENY_SOFT) ? 's' : 'h', - a, filemask, reason); - } - for (allowtmp = conf_allow_dcc; allowtmp; allowtmp = allowtmp->next) - { - filemask = BadPtr(allowtmp->filename) ? "" : allowtmp->filename; - if (allowtmp->flag.type2 == CONF_BAN_TYPE_CONF) - a = 'c'; - if (allowtmp->flag.type2 == CONF_BAN_TYPE_AKILL) - a = 's'; - if (allowtmp->flag.type2 == CONF_BAN_TYPE_TEMPORARY) - a = 'o'; - /* */ - sendtxtnumeric(client, "a %c %c %s", (allowtmp->flag.type == DCCDENY_SOFT) ? 's' : 'h', - a, filemask); - } - return 0; -} - int stats_kline(Client *client, char *para) { tkl_stats(client, TKL_KILL, NULL); diff --git a/src/modules/svsfline.c b/src/modules/svsfline.c deleted file mode 100644 index 3a31abff6..000000000 --- a/src/modules/svsfline.c +++ /dev/null @@ -1,114 +0,0 @@ -/* - * IRC - Internet Relay Chat, src/modules/svsfline.c - * (C) 2004-present The UnrealIRCd Team - * - * See file AUTHORS in IRC package for additional names of - * the programmers. - * - * 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" - -CMD_FUNC(cmd_svsfline); - -#define MSG_SVSFLINE "SVSFLINE" - -ModuleHeader MOD_HEADER - = { - "svsfline", - "5.0", - "command /svsfline", - "UnrealIRCd Team", - "unrealircd-5", - }; - -MOD_INIT() -{ - CommandAdd(modinfo->handle, MSG_SVSFLINE, cmd_svsfline, MAXPARA, CMD_SERVER); - MARK_AS_OFFICIAL_MODULE(modinfo); - return MOD_SUCCESS; -} - -MOD_LOAD() -{ - return MOD_SUCCESS; -} - -MOD_UNLOAD() -{ - return MOD_SUCCESS; -} - -CMD_FUNC(cmd_svsfline) -{ - if (parc < 2) - return; - - switch (*parv[1]) - { - /* Allow non-U-Lines to send ONLY SVSFLINE +, but don't send it out - * unless it is from a U-Line -- codemastr - */ - case '+': - { - if (parc < 4) - return; - - if (!Find_deny_dcc(parv[2])) - DCCdeny_add(parv[2], parv[3], DCCDENY_HARD, CONF_BAN_TYPE_AKILL); - - if (IsULine(client)) - { - sendto_server(client, 0, 0, NULL, ":%s SVSFLINE + %s :%s", - client->id, parv[2], parv[3]); - } - - break; - } - - case '-': - { - ConfigItem_deny_dcc *deny; - - if (!IsULine(client)) - return; - - if (parc < 3) - return; - - if (!(deny = Find_deny_dcc(parv[2]))) - break; - - DCCdeny_del(deny); - - sendto_server(client, 0, 0, NULL, ":%s SVSFLINE %s", client->id, parv[2]); - - break; - } - - case '*': - { - if (!IsULine(client)) - return; - - dcc_wipe_services(); - - sendto_server(client, 0, 0, NULL, ":%s SVSFLINE *", client->id); - - break; - } - } -} diff --git a/src/modules/undccdeny.c b/src/modules/undccdeny.c deleted file mode 100644 index 391c83194..000000000 --- a/src/modules/undccdeny.c +++ /dev/null @@ -1,86 +0,0 @@ -/* - * IRC - Internet Relay Chat, src/modules/undccdeny.c - * (C) 2004 The UnrealIRCd Team - * - * See file AUTHORS in IRC package for additional names of - * the programmers. - * - * 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" - -CMD_FUNC(cmd_undccdeny); - -#define MSG_UNDCCDENY "UNDCCDENY" - -ModuleHeader MOD_HEADER - = { - "undccdeny", - "5.0", - "command /undccdeny", - "UnrealIRCd Team", - "unrealircd-5", - }; - -MOD_INIT() -{ - CommandAdd(modinfo->handle, MSG_UNDCCDENY, cmd_undccdeny, MAXPARA, CMD_USER); - MARK_AS_OFFICIAL_MODULE(modinfo); - return MOD_SUCCESS; -} - -MOD_LOAD() -{ - return MOD_SUCCESS; -} - -MOD_UNLOAD() -{ - return MOD_SUCCESS; -} - -/* Remove a temporary dccdeny line - * parv[1] - file/mask - */ -CMD_FUNC(cmd_undccdeny) -{ - ConfigItem_deny_dcc *d; - - if (!MyUser(client)) - return; - - if (!ValidatePermissionsForPath("server-ban:dccdeny",client,NULL,NULL,NULL)) - { - sendnumeric(client, ERR_NOPRIVILEGES); - return; - } - - if ((parc < 2) || BadPtr(parv[1])) - { - sendnumeric(client, ERR_NEEDMOREPARAMS, "UNDCCDENY"); - return; - } - - if ((d = Find_deny_dcc(parv[1])) && d->flag.type2 == CONF_BAN_TYPE_TEMPORARY) - { - sendto_ops("%s removed a temp dccdeny for %s", client->name, parv[1]); - DCCdeny_del(d); - return; - } else - { - sendnotice(client, "*** Unable to find a temp dccdeny matching %s", parv[1]); - } -}