4
mirror of git://git.acid.vegas/unrealircd.git synced 2024-12-29 01:36:37 +00:00

Updated to 5.0.7

This commit is contained in:
Dionysus 2020-11-26 11:02:01 -05:00
parent 1143363444
commit b351238d42
Signed by: acidvegas
GPG Key ID: EF4B922DB85DC9DE
28 changed files with 416 additions and 188 deletions

2
Config
View File

@ -326,7 +326,7 @@ echo "We will now ask you a number of questions. You can just press ENTER to acc
echo "" echo ""
# This needs to be updated each release so auto-upgrading works for settings, modules, etc!!: # This needs to be updated each release so auto-upgrading works for settings, modules, etc!!:
UNREALRELEASES="unrealircd-5.0.5.1 unrealircd-5.0.5 unrealircd-5.0.4 unrealircd-5.0.3.1 unrealircd-5.0.3 unrealircd-5.0.2 unrealircd-5.0.1 unrealircd-5.0.0 unrealircd-5.0.0-rc2 unrealircd-5.0.0-rc1" UNREALRELEASES="unrealircd-5.0.7-rc1 unrealircd-5.0.6 unrealircd-5.0.5.1 unrealircd-5.0.5 unrealircd-5.0.4 unrealircd-5.0.3.1 unrealircd-5.0.3 unrealircd-5.0.2 unrealircd-5.0.1 unrealircd-5.0.0 unrealircd-5.0.0-rc2 unrealircd-5.0.0-rc1"
if [ -f "config.settings" ]; then if [ -f "config.settings" ]; then
. ./config.settings . ./config.settings
else else

View File

@ -171,7 +171,7 @@ install: all
$(INSTALL) -m 0700 -d @CONFDIR@ $(INSTALL) -m 0700 -d @CONFDIR@
$(INSTALL) -m 0600 doc/conf/*.conf @CONFDIR@ $(INSTALL) -m 0600 doc/conf/*.conf @CONFDIR@
$(INSTALL) -m 0600 doc/conf/*.motd @CONFDIR@ $(INSTALL) -m 0600 doc/conf/*.motd @CONFDIR@
$(INSTALL) -m 0600 doc/conf/modules.sources.list @CONFDIR@ $(INSTALL) -m 0600 doc/conf/modules.sources.list @CONFDIR@ ; \
$(INSTALL) -m 0700 unrealircd @SCRIPTDIR@ $(INSTALL) -m 0700 unrealircd @SCRIPTDIR@
$(INSTALL) -m 0700 -d @MODULESDIR@ $(INSTALL) -m 0700 -d @MODULESDIR@
@rm -f @MODULESDIR@/*.so 1>/dev/null 2>&1 @rm -f @MODULESDIR@/*.so 1>/dev/null 2>&1

20
configure vendored
View File

@ -1,6 +1,6 @@
#! /bin/sh #! /bin/sh
# Guess values for system-dependent variables and create Makefiles. # Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.69 for unrealircd 5.0.6. # Generated by GNU Autoconf 2.69 for unrealircd 5.0.7.
# #
# Report bugs to <https://bugs.unrealircd.org/>. # Report bugs to <https://bugs.unrealircd.org/>.
# #
@ -580,8 +580,8 @@ MAKEFLAGS=
# Identity of this package. # Identity of this package.
PACKAGE_NAME='unrealircd' PACKAGE_NAME='unrealircd'
PACKAGE_TARNAME='unrealircd' PACKAGE_TARNAME='unrealircd'
PACKAGE_VERSION='5.0.6' PACKAGE_VERSION='5.0.7'
PACKAGE_STRING='unrealircd 5.0.6' PACKAGE_STRING='unrealircd 5.0.7'
PACKAGE_BUGREPORT='https://bugs.unrealircd.org/' PACKAGE_BUGREPORT='https://bugs.unrealircd.org/'
PACKAGE_URL='https://unrealircd.org/' PACKAGE_URL='https://unrealircd.org/'
@ -1325,7 +1325,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing. # Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh. # This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF cat <<_ACEOF
\`configure' configures unrealircd 5.0.6 to adapt to many kinds of systems. \`configure' configures unrealircd 5.0.7 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]... Usage: $0 [OPTION]... [VAR=VALUE]...
@ -1391,7 +1391,7 @@ fi
if test -n "$ac_init_help"; then if test -n "$ac_init_help"; then
case $ac_init_help in case $ac_init_help in
short | recursive ) echo "Configuration of unrealircd 5.0.6:";; short | recursive ) echo "Configuration of unrealircd 5.0.7:";;
esac esac
cat <<\_ACEOF cat <<\_ACEOF
@ -1544,7 +1544,7 @@ fi
test -n "$ac_init_help" && exit $ac_status test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then if $ac_init_version; then
cat <<\_ACEOF cat <<\_ACEOF
unrealircd configure 5.0.6 unrealircd configure 5.0.7
generated by GNU Autoconf 2.69 generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc. Copyright (C) 2012 Free Software Foundation, Inc.
@ -1913,7 +1913,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake. running configure, to aid debugging if configure makes a mistake.
It was created by unrealircd $as_me 5.0.6, which was It was created by unrealircd $as_me 5.0.7, which was
generated by GNU Autoconf 2.69. Invocation command line was generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@ $ $0 $@
@ -2321,7 +2321,7 @@ _ACEOF
# Minor version number (e.g.: Z in X.Y.Z) # Minor version number (e.g.: Z in X.Y.Z)
UNREAL_VERSION_MINOR="6" UNREAL_VERSION_MINOR="7"
cat >>confdefs.h <<_ACEOF cat >>confdefs.h <<_ACEOF
#define UNREAL_VERSION_MINOR $UNREAL_VERSION_MINOR #define UNREAL_VERSION_MINOR $UNREAL_VERSION_MINOR
@ -8398,7 +8398,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their # report actual input values of CONFIG_FILES etc. instead of their
# values after options handling. # values after options handling.
ac_log=" ac_log="
This file was extended by unrealircd $as_me 5.0.6, which was This file was extended by unrealircd $as_me 5.0.7, which was
generated by GNU Autoconf 2.69. Invocation command line was generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES CONFIG_FILES = $CONFIG_FILES
@ -8461,7 +8461,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\ ac_cs_version="\\
unrealircd config.status 5.0.6 unrealircd config.status 5.0.7
configured by $0, generated by GNU Autoconf 2.69, configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\" with options \\"\$ac_cs_config\\"

View File

@ -7,7 +7,7 @@ dnl src/windows/unrealinst.iss
dnl doc/Config.header dnl doc/Config.header
dnl src/version.c.SH dnl src/version.c.SH
AC_INIT([unrealircd], [5.0.6], [https://bugs.unrealircd.org/], [], [https://unrealircd.org/]) AC_INIT([unrealircd], [5.0.7], [https://bugs.unrealircd.org/], [], [https://unrealircd.org/])
AC_CONFIG_SRCDIR([src/ircd.c]) AC_CONFIG_SRCDIR([src/ircd.c])
AC_CONFIG_HEADER([include/setup.h]) AC_CONFIG_HEADER([include/setup.h])
AC_CONFIG_AUX_DIR([autoconf]) AC_CONFIG_AUX_DIR([autoconf])
@ -34,7 +34,7 @@ UNREAL_VERSION_MAJOR=["0"]
AC_DEFINE_UNQUOTED([UNREAL_VERSION_MAJOR], [$UNREAL_VERSION_MAJOR], [Major version number (e.g.: Y for X.Y.Z)]) AC_DEFINE_UNQUOTED([UNREAL_VERSION_MAJOR], [$UNREAL_VERSION_MAJOR], [Major version number (e.g.: Y for X.Y.Z)])
# Minor version number (e.g.: Z in X.Y.Z) # Minor version number (e.g.: Z in X.Y.Z)
UNREAL_VERSION_MINOR=["6"] UNREAL_VERSION_MINOR=["7"]
AC_DEFINE_UNQUOTED([UNREAL_VERSION_MINOR], [$UNREAL_VERSION_MINOR], [Minor version number (e.g.: Z for X.Y.Z)]) AC_DEFINE_UNQUOTED([UNREAL_VERSION_MINOR], [$UNREAL_VERSION_MINOR], [Minor version number (e.g.: Z for X.Y.Z)])
# The version suffix such as a beta marker or release candidate # The version suffix such as a beta marker or release candidate

View File

@ -7,7 +7,7 @@
\___/|_| |_|_| \___|\__,_|_|\___/\_| \_| \____/\__,_| \___/|_| |_|_| \___|\__,_|_|\___/\_| \_| \____/\__,_|
Configuration Program Configuration Program
for UnrealIRCd 5.0.6 for UnrealIRCd 5.0.7
This program will help you to compile your IRC server, and ask you This program will help you to compile your IRC server, and ask you
questions regarding the compile-time settings of it during the process. questions regarding the compile-time settings of it during the process.

View File

@ -1,6 +1,53 @@
UnrealIRCd 5.0.6 Release Notes UnrealIRCd 5.0.7 Release Notes
=============================== ===============================
UnrealIRCd 5.0.7 consists mainly of fixes for the 5.x stable series,
with some minor enhancements.
Enhancements:
* Add support for ```estonian-utf8```, ```latvian-utf8``` and
```lithuanian-utf8``` in
[set::allowed-nickchars](https://www.unrealircd.org/docs/Nick_Character_Sets)
* Add [message tags](https://www.unrealircd.org/docs/Message_tags)
to ```PONG``` to help fix timestamp issues in KiwiIRC.
* Dutch helpop file (conf/help/help.nl.conf)
Fixes:
* When having multiple text bans (```+b ~T:censor```), these caused an empty
message.
* Text bans are now no longer bypassed by voiced users (```+v```).
* [Websockets](https://www.unrealircd.org/docs/WebSocket_support) that used
```labeled-response``` sometimes received multiple IRC messages in one
websocket packet.
* The reputation score of [WEBIRC users](https://www.unrealircd.org/docs/WebIRC_block)
was previously the score of the WEBIRC IP rather than the end-user IP.
* ```STATS badword``` was not working.
* When setting a very high channel limit, it showed a weird MODE ```+l``` value.
* The ```LINKS``` command worked, even when disabled via
```hideserver::disable-links``` in the optional hideserver module.
* In some cases ```WHO``` did not show your own entry, such as when
searching on account name, which was confusing.
* Memory leak when repeatedly using ```./unrealircd reloadtls``` or
```/REHASH -tls```.
Module coders / Developers:
* No changes, only some small additions to the
[Doxygen module API docs](https://www.unrealircd.org/api/5/index.html)
Reminder: UnrealIRCd 4 is End Of Life
---------------------------------------
All support for the previous series, UnrealIRCd 4.x, will stop after
[December 31, 2020](https://www.unrealircd.org/docs/UnrealIRCd_4_EOL).
If you haven't upgraded yet, do so soon!
Upgrading from 4.x to 5.x?
Then check out the *UnrealIRCd 5* release notes [further down](#unrealircd-5). At the
very least, check out [Upgrading from 4.x](https://www.unrealircd.org/docs/Upgrading_from_4.x).
UnrealIRCd 5.0.6
-----------------
UnrealIRCd 5.0.6 is a small maintenance release for the stable 5.x series. UnrealIRCd 5.0.6 is a small maintenance release for the stable 5.x series.
For existing 5.x users there is probably little reason to upgrade. For existing 5.x users there is probably little reason to upgrade.
@ -29,14 +76,6 @@ Module coders / Developers:
* Fix double batch in message tags when using both labeled-response * Fix double batch in message tags when using both labeled-response
and the ```HISTORY``` command and the ```HISTORY``` command
Upgrading from UnrealIRCd 4?
-----------------------------
Are you upgrading from UnrealIRCd 4.x to UnrealIRCd 5?
Then check out the *UnrealIRCd 5* release notes [further down](#unrealircd-5). At the
very least, check out [Upgrading from 4.x](https://www.unrealircd.org/docs/Upgrading_from_4.x).
UnrealIRCd 5.0.5.1 UnrealIRCd 5.0.5.1
------------------- -------------------

View File

@ -38,7 +38,7 @@ PROJECT_NAME = "UnrealIRCd"
# could be handy for archiving the generated documentation or if some version # could be handy for archiving the generated documentation or if some version
# control system is used. # control system is used.
PROJECT_NUMBER = 5.0.6 PROJECT_NUMBER = 5.0.7
# Using the PROJECT_BRIEF tag one can provide an optional one line description # Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a # for a project that appears at the top of each page and should give viewer a

View File

@ -353,7 +353,13 @@ typedef struct {
#define EXTBANTABLESZ 32 #define EXTBANTABLESZ 32
typedef enum ExtbanOptions { EXTBOPT_CHSVSMODE=0x1, EXTBOPT_ACTMODIFIER=0x2, EXTBOPT_NOSTACKCHILD=0x4, EXTBOPT_INVEX=0x8, EXTBOPT_TKL=0x10 } ExtbanOptions; typedef enum ExtbanOptions {
EXTBOPT_CHSVSMODE=0x1, /**< SVSMODE -b/-e/-I will clear this ban */
EXTBOPT_ACTMODIFIER=0x2, /**< Action modifier (not a matcher). These are extended bans like ~q/~n/~j. */
EXTBOPT_NOSTACKCHILD=0x4, /**< Disallow prefixing with another extban. Eg disallow ~n:~T:censor:xyz */
EXTBOPT_INVEX=0x8, /**< Available for use with +I too */
EXTBOPT_TKL=0x10 /**< Available for use in TKL's too (eg: /GLINE ~a:account) */
} ExtbanOptions;
typedef struct { typedef struct {
/** extbans module */ /** extbans module */

View File

@ -1464,7 +1464,6 @@ typedef struct TLSOptions TLSOptions;
struct TLSOptions { struct TLSOptions {
char *certificate_file; char *certificate_file;
char *key_file; char *key_file;
char *dh_file;
char *trusted_ca_file; char *trusted_ca_file;
unsigned int protocols; unsigned int protocols;
char *ciphers; char *ciphers;

View File

@ -63,7 +63,7 @@
#define UNREAL_VERSION_MAJOR 0 #define UNREAL_VERSION_MAJOR 0
/* Minor version number (e.g.: 1 for Unreal3.2.1) */ /* Minor version number (e.g.: 1 for Unreal3.2.1) */
#define UNREAL_VERSION_MINOR 6 #define UNREAL_VERSION_MINOR 7
/* Version suffix such as a beta marker or release candidate marker. (e.g.: /* Version suffix such as a beta marker or release candidate marker. (e.g.:
-rcX for unrealircd-3.2.9-rcX) */ -rcX for unrealircd-3.2.9-rcX) */

View File

@ -1672,6 +1672,7 @@ void config_setdefaultsettings(Configuration *i)
i->maxdccallow = 10; i->maxdccallow = 10;
safe_strdup(i->channel_command_prefix, "`!."); safe_strdup(i->channel_command_prefix, "`!.");
conf_channelmodes("+nt", &i->modes_on_join, 0); conf_channelmodes("+nt", &i->modes_on_join, 0);
i->conn_modes = set_usermode("+ixw");
i->check_target_nick_bans = 1; i->check_target_nick_bans = 1;
i->maxbans = 60; i->maxbans = 60;
i->maxbanlength = 2048; i->maxbanlength = 2048;
@ -6994,7 +6995,6 @@ void test_tlsblock(ConfigFile *conf, ConfigEntry *cep, int *totalerrors)
} }
} }
else if (!strcmp(cepp->ce_varname, "certificate") || else if (!strcmp(cepp->ce_varname, "certificate") ||
!strcmp(cepp->ce_varname, "dh") ||
!strcmp(cepp->ce_varname, "key") || !strcmp(cepp->ce_varname, "key") ||
!strcmp(cepp->ce_varname, "trusted-ca-file")) !strcmp(cepp->ce_varname, "trusted-ca-file"))
{ {
@ -7011,6 +7011,17 @@ void test_tlsblock(ConfigFile *conf, ConfigEntry *cep, int *totalerrors)
} }
safe_free(path); safe_free(path);
} }
else if (!strcmp(cepp->ce_varname, "dh"))
{
/* Support for this undocumented option was silently dropped in 5.0.0.
* Since 5.0.7 we print a warning about it, since you never know
* someone may still have it configured. -- Syzop
*/
config_warn("%s:%d: Not reading DH file '%s'. UnrealIRCd does not support old DH(E), we use modern ECDHE/EECDH. "
"Just remove the 'dh' directive from your config file to get rid of this warning.",
cepp->ce_fileptr->cf_filename, cepp->ce_varlinenum,
cepp->ce_vardata ? cepp->ce_vardata : "");
}
else if (!strcmp(cepp->ce_varname, "outdated-protocols")) else if (!strcmp(cepp->ce_varname, "outdated-protocols"))
{ {
char copy[512], *p, *name; char copy[512], *p, *name;
@ -7131,7 +7142,6 @@ void free_tls_options(TLSOptions *tlsoptions)
safe_free(tlsoptions->certificate_file); safe_free(tlsoptions->certificate_file);
safe_free(tlsoptions->key_file); safe_free(tlsoptions->key_file);
safe_free(tlsoptions->dh_file);
safe_free(tlsoptions->trusted_ca_file); safe_free(tlsoptions->trusted_ca_file);
safe_free(tlsoptions->ciphers); safe_free(tlsoptions->ciphers);
safe_free(tlsoptions->ciphersuites); safe_free(tlsoptions->ciphersuites);
@ -7152,7 +7162,6 @@ void conf_tlsblock(ConfigFile *conf, ConfigEntry *cep, TLSOptions *tlsoptions)
{ {
safe_strdup(tlsoptions->certificate_file, tempiConf.tls_options->certificate_file); safe_strdup(tlsoptions->certificate_file, tempiConf.tls_options->certificate_file);
safe_strdup(tlsoptions->key_file, tempiConf.tls_options->key_file); safe_strdup(tlsoptions->key_file, tempiConf.tls_options->key_file);
safe_strdup(tlsoptions->dh_file, tempiConf.tls_options->dh_file);
safe_strdup(tlsoptions->trusted_ca_file, tempiConf.tls_options->trusted_ca_file); safe_strdup(tlsoptions->trusted_ca_file, tempiConf.tls_options->trusted_ca_file);
tlsoptions->protocols = tempiConf.tls_options->protocols; tlsoptions->protocols = tempiConf.tls_options->protocols;
safe_strdup(tlsoptions->ciphers, tempiConf.tls_options->ciphers); safe_strdup(tlsoptions->ciphers, tempiConf.tls_options->ciphers);
@ -7224,10 +7233,6 @@ void conf_tlsblock(ConfigFile *conf, ConfigEntry *cep, TLSOptions *tlsoptions)
} }
} }
} }
else if (!strcmp(cepp->ce_varname, "dh"))
{
convert_to_absolute_path(&cepp->ce_vardata, CONFDIR);
}
else if (!strcmp(cepp->ce_varname, "certificate")) else if (!strcmp(cepp->ce_varname, "certificate"))
{ {
convert_to_absolute_path(&cepp->ce_vardata, CONFDIR); convert_to_absolute_path(&cepp->ce_vardata, CONFDIR);

View File

@ -67,23 +67,27 @@ char *ircvsnprintf(char *str, size_t size, const char *format, va_list vl)
int v = va_arg(vl, int); int v = va_arg(vl, int);
int i = 0; int i = 0;
size_t len; size_t len;
if (v<0)
{
v*=-1;
*str++ = '-';
if (str==end) break;
}
if (v==0) if (v==0)
{ {
*str++ = '0'; *str++ = '0';
continue; continue;
} }
t = scratch_buffer + sizeof(scratch_buffer); t = scratch_buffer + sizeof(scratch_buffer);
while (v) if (v<0)
{ {
*--t = (v%10) + '0'; *str++ = '-';
v/=10; if (str==end) break;
while (v)
{
*--t = '0' - (v%10);
v/=10;
}
} else {
while (v)
{
*--t = (v%10) + '0';
v/=10;
}
} }
len = sizeof(scratch_buffer)-(t-scratch_buffer); len = sizeof(scratch_buffer)-(t-scratch_buffer);
@ -103,23 +107,28 @@ char *ircvsnprintf(char *str, size_t size, const char *format, va_list vl)
size_t len; size_t len;
format += 2; format += 2;
if (v<0)
{
v*=-1;
*str++ = '-';
if (str==end) break;
}
if (v==0) if (v==0)
{ {
*str++ = '0'; *str++ = '0';
continue; continue;
} }
t = scratch_buffer + sizeof(scratch_buffer); t = scratch_buffer + sizeof(scratch_buffer);
while (v) if (v<0)
{ {
*--t = (v%10) + '0'; *str++ = '-';
v/=10; if (str==end) break;
while (v)
{
*--t = '0' - (v%10);
v/=10;
}
} else {
while (v)
{
*--t = (v%10) + '0';
v/=10;
}
} }
len = sizeof(scratch_buffer)-(t-scratch_buffer); len = sizeof(scratch_buffer)-(t-scratch_buffer);

View File

@ -23,7 +23,7 @@ Cmode_t EXTMODE_CENSOR = 0L;
int censor_can_send_to_channel(Client *client, Channel *channel, Membership *lp, char **msg, char **errmsg, SendType sendtype); int censor_can_send_to_channel(Client *client, Channel *channel, Membership *lp, char **msg, char **errmsg, SendType sendtype);
char *censor_pre_local_part(Client *client, Channel *channel, char *text); char *censor_pre_local_part(Client *client, Channel *channel, char *text);
char *censor_pre_local_quit(Client *client, char *text); char *censor_pre_local_quit(Client *client, char *text);
int censor_stats_badwords_channel(Client *client, char *para);
int censor_config_test(ConfigFile *, ConfigEntry *, int, int *); int censor_config_test(ConfigFile *, ConfigEntry *, int, int *);
int censor_config_run(ConfigFile *, ConfigEntry *, int); int censor_config_run(ConfigFile *, ConfigEntry *, int);
@ -55,7 +55,7 @@ MOD_INIT()
HookAdd(modinfo->handle, HOOKTYPE_CAN_SEND_TO_CHANNEL, 0, censor_can_send_to_channel); HookAdd(modinfo->handle, HOOKTYPE_CAN_SEND_TO_CHANNEL, 0, censor_can_send_to_channel);
HookAddPChar(modinfo->handle, HOOKTYPE_PRE_LOCAL_PART, 0, censor_pre_local_part); HookAddPChar(modinfo->handle, HOOKTYPE_PRE_LOCAL_PART, 0, censor_pre_local_part);
HookAddPChar(modinfo->handle, HOOKTYPE_PRE_LOCAL_QUIT, 0, censor_pre_local_quit); HookAddPChar(modinfo->handle, HOOKTYPE_PRE_LOCAL_QUIT, 0, censor_pre_local_quit);
HookAdd(modinfo->handle, HOOKTYPE_STATS, 0, censor_stats_badwords_channel);
HookAdd(modinfo->handle, HOOKTYPE_CONFIGRUN, 0, censor_config_run); HookAdd(modinfo->handle, HOOKTYPE_CONFIGRUN, 0, censor_config_run);
return MOD_SUCCESS; return MOD_SUCCESS;
} }
@ -319,11 +319,13 @@ char *censor_pre_local_quit(Client *client, char *text)
return blocked ? NULL : text; return blocked ? NULL : text;
} }
// TODO: when stats is modular, make it call this for badwords int censor_stats_badwords_channel(Client *client, char *para)
int stats_badwords(Client *client, char *para)
{ {
ConfigItem_badword *words; ConfigItem_badword *words;
if (!para || !(!strcmp(para, "b") || !strcasecmp(para, "badword")))
return 0;
for (words = conf_badword_channel; words; words = words->next) for (words = conf_badword_channel; words; words = words->next)
{ {
sendtxtnumeric(client, "c %c %s%s%s %s", words->type & BADW_TYPE_REGEX ? 'R' : 'F', sendtxtnumeric(client, "c %c %s%s%s %s", words->type & BADW_TYPE_REGEX ? 'R' : 'F',
@ -331,5 +333,5 @@ int stats_badwords(Client *client, char *para)
(words->type & BADW_TYPE_FAST_R) ? "*" : "", (words->type & BADW_TYPE_FAST_R) ? "*" : "",
words->action == BADWORD_REPLACE ? (words->replace ? words->replace : "<censored>") : ""); words->action == BADWORD_REPLACE ? (words->replace ? words->replace : "<censored>") : "");
} }
return 0; return 1;
} }

View File

@ -99,6 +99,7 @@ static LangList langlist[] = {
{ "danish-utf8", "dan-utf8", LANGAV_ASCII|LANGAV_UTF8|LANGAV_LATIN_UTF8 }, { "danish-utf8", "dan-utf8", LANGAV_ASCII|LANGAV_UTF8|LANGAV_LATIN_UTF8 },
{ "dutch", "dut", LANGAV_ASCII|LANGAV_LATIN1 }, { "dutch", "dut", LANGAV_ASCII|LANGAV_LATIN1 },
{ "dutch-utf8", "dut-utf8", LANGAV_ASCII|LANGAV_UTF8|LANGAV_LATIN_UTF8 }, { "dutch-utf8", "dut-utf8", LANGAV_ASCII|LANGAV_UTF8|LANGAV_LATIN_UTF8 },
{ "estonian-utf8","est-utf8", LANGAV_ASCII|LANGAV_UTF8|LANGAV_LATIN_UTF8 },
{ "french", "fre", LANGAV_ASCII|LANGAV_LATIN1 }, { "french", "fre", LANGAV_ASCII|LANGAV_LATIN1 },
{ "french-utf8", "fre-utf8", LANGAV_ASCII|LANGAV_UTF8|LANGAV_LATIN_UTF8 }, { "french-utf8", "fre-utf8", LANGAV_ASCII|LANGAV_UTF8|LANGAV_LATIN_UTF8 },
{ "gbk", "chi-s,chi-t,chi-j", LANGAV_GBK }, { "gbk", "chi-s,chi-t,chi-j", LANGAV_GBK },
@ -117,6 +118,8 @@ static LangList langlist[] = {
{ "latin-utf8", "cat-utf8,cze-utf8,dan-utf8,dut-utf8,fre-utf8,ger-utf8,hun-utf8,ice-utf8,ita-utf8,pol-utf8,rum-utf8,slo-utf8,spa-utf8,swe-utf8,tur-utf8", LANGAV_ASCII|LANGAV_UTF8|LANGAV_LATIN_UTF8 }, { "latin-utf8", "cat-utf8,cze-utf8,dan-utf8,dut-utf8,fre-utf8,ger-utf8,hun-utf8,ice-utf8,ita-utf8,pol-utf8,rum-utf8,slo-utf8,spa-utf8,swe-utf8,tur-utf8", LANGAV_ASCII|LANGAV_UTF8|LANGAV_LATIN_UTF8 },
{ "latin1", "cat,dut,fre,ger,ita,spa,swe", LANGAV_ASCII|LANGAV_LATIN1 }, { "latin1", "cat,dut,fre,ger,ita,spa,swe", LANGAV_ASCII|LANGAV_LATIN1 },
{ "latin2", "hun,pol,rum", LANGAV_ASCII|LANGAV_LATIN2 }, { "latin2", "hun,pol,rum", LANGAV_ASCII|LANGAV_LATIN2 },
{ "latvian-utf8", "lav-utf8", LANGAV_ASCII|LANGAV_UTF8|LANGAV_LATIN_UTF8 },
{ "lithuanian-utf8","lit-utf8", LANGAV_ASCII|LANGAV_UTF8|LANGAV_LATIN_UTF8 },
{ "polish", "pol", LANGAV_ASCII|LANGAV_LATIN2 }, { "polish", "pol", LANGAV_ASCII|LANGAV_LATIN2 },
{ "polish-utf8", "pol-utf8", LANGAV_ASCII|LANGAV_UTF8|LANGAV_LATIN_UTF8 }, { "polish-utf8", "pol-utf8", LANGAV_ASCII|LANGAV_UTF8|LANGAV_LATIN_UTF8 },
{ "polish-w1250", "pol-m", LANGAV_ASCII|LANGAV_W1250 }, { "polish-w1250", "pol-m", LANGAV_ASCII|LANGAV_W1250 },
@ -257,7 +260,7 @@ int charsys_config_run(ConfigFile *cf, ConfigEntry *ce, int type)
if (type != CONFIG_SET) if (type != CONFIG_SET)
return 0; return 0;
/* We are only interrested in set::allowed-nickchars... */ /* We are only interrested in set::allowed-nickchars... */
if (!ce || !ce->ce_varname || strcmp(ce->ce_varname, "allowed-nickchars")) if (!ce || !ce->ce_varname || strcmp(ce->ce_varname, "allowed-nickchars"))
return 0; return 0;
@ -408,7 +411,7 @@ void charsys_finish(void)
if (e->next) if (e->next)
strlcat(langsinuse, ",", sizeof(langsinuse)); strlcat(langsinuse, ",", sizeof(langsinuse));
} }
/* Free everything */ /* Free everything */
for (e=ilanglist; e; e=e_next) for (e=ilanglist; e; e=e_next)
{ {
@ -683,7 +686,7 @@ void charsys_add_language(char *name)
w1251 = 1; w1251 = 1;
else if (!strcmp(name, "chinese") || !strcmp(name, "gbk")) else if (!strcmp(name, "chinese") || !strcmp(name, "gbk"))
chinese = 1; chinese = 1;
/* INDIVIDUAL CHARSETS */ /* INDIVIDUAL CHARSETS */
/* [LATIN1] and [LATIN-UTF8] */ /* [LATIN1] and [LATIN-UTF8] */
@ -840,7 +843,7 @@ void charsys_add_language(char *name)
if (latin1 || !strcmp(name, "swedish")) if (latin1 || !strcmp(name, "swedish"))
{ {
/* supplied by Tank */ /* supplied by Tank */
/* ao, Ao, a", A", o", O" */ /* ao, Ao, a", A", o", O" */
charsys_addallowed("åÅäÄöÖ"); charsys_addallowed("åÅäÄöÖ");
} }
if (latin_utf8 || !strcmp(name, "swedish-utf8")) if (latin_utf8 || !strcmp(name, "swedish-utf8"))
@ -926,7 +929,7 @@ void charsys_add_language(char *name)
charsys_addmultibyterange(0xc5, 0xc5, 0x9e, 0x9f); charsys_addmultibyterange(0xc5, 0xc5, 0x9e, 0x9f);
charsys_addmultibyterange(0xc5, 0xc5, 0xa2, 0xa3); charsys_addmultibyterange(0xc5, 0xc5, 0xa2, 0xa3);
} }
if (latin2 || !strcmp(name, "polish")) if (latin2 || !strcmp(name, "polish"))
{ {
/* supplied by k4be */ /* supplied by k4be */
@ -1019,7 +1022,7 @@ void charsys_add_language(char *name)
charsys_addmultibyterange(0xd1, 0xd1, 0x80, 0x8f); charsys_addmultibyterange(0xd1, 0xd1, 0x80, 0x8f);
charsys_addmultibyterange(0xd1, 0xd1, 0x91, 0x91); charsys_addmultibyterange(0xd1, 0xd1, 0x91, 0x91);
} }
if (w1251 || !strcmp(name, "belarussian-w1251")) if (w1251 || !strcmp(name, "belarussian-w1251"))
{ {
/* supplied by Bock (Samets Anton) & ss: /* supplied by Bock (Samets Anton) & ss:
@ -1043,7 +1046,7 @@ void charsys_add_language(char *name)
charsys_addmultibyterange(0xd1, 0xd1, 0x96, 0x96); charsys_addmultibyterange(0xd1, 0xd1, 0x96, 0x96);
charsys_addmultibyterange(0xd1, 0xd1, 0x9e, 0x9e); charsys_addmultibyterange(0xd1, 0xd1, 0x9e, 0x9e);
} }
if (w1251 || !strcmp(name, "ukrainian-w1251")) if (w1251 || !strcmp(name, "ukrainian-w1251"))
{ {
/* supplied by Anton Samets & ss: /* supplied by Anton Samets & ss:
@ -1067,7 +1070,7 @@ void charsys_add_language(char *name)
charsys_addmultibyterange(0xd2, 0xd2, 0x90, 0x91); charsys_addmultibyterange(0xd2, 0xd2, 0x90, 0x91);
} }
/* [GREEK] */ /* [GREEK] */
if (!strcmp(name, "greek")) if (!strcmp(name, "greek"))
{ {
/* supplied by GSF */ /* supplied by GSF */
@ -1135,6 +1138,49 @@ void charsys_add_language(char *name)
charsys_addmultibyterange(0xaa, 0xfe, 0x40, 0x7e); /* GBK/4 - lower half */ charsys_addmultibyterange(0xaa, 0xfe, 0x40, 0x7e); /* GBK/4 - lower half */
charsys_addmultibyterange(0xaa, 0xfe, 0x80, 0xa0); /* GBK/4 - upper half */ charsys_addmultibyterange(0xaa, 0xfe, 0x80, 0xa0); /* GBK/4 - upper half */
} }
/* [LATVIAN] */
if (latin_utf8 || !strcmp(name, "latvian-utf8"))
{
/* A a, C c, E e, G g, I i, K k, Š š, U u, Ž ž */
charsys_addmultibyterange(0xc4, 0xc4, 0x80, 0x81);
charsys_addmultibyterange(0xc4, 0xc4, 0x92, 0x93);
charsys_addmultibyterange(0xc4, 0xc4, 0x8c, 0x8d);
charsys_addmultibyterange(0xc4, 0xc4, 0x92, 0x93);
charsys_addmultibyterange(0xc4, 0xc4, 0xa2, 0xa3);
charsys_addmultibyterange(0xc4, 0xc4, 0xaa, 0xab);
charsys_addmultibyterange(0xc4, 0xc4, 0xb6, 0xb7);
charsys_addmultibyterange(0xc5, 0xc5, 0xa0, 0xa1);
charsys_addmultibyterange(0xc5, 0xc5, 0xaa, 0xab);
charsys_addmultibyterange(0xc5, 0xc5, 0xbd, 0xbe);
}
/* [ESTONIAN] */
if (latin_utf8 || !strcmp(name, "estonian-utf8"))
{
/* õ, ä, ö, ü, Õ, Ä, Ö, Ü */
charsys_addmultibyterange(0xc3, 0xc3, 0xb5, 0xb6);
charsys_addmultibyterange(0xc3, 0xc3, 0xa4, 0xa4);
charsys_addmultibyterange(0xc3, 0xc3, 0xbc, 0xbc);
charsys_addmultibyterange(0xc3, 0xc3, 0x95, 0x96);
charsys_addmultibyterange(0xc3, 0xc3, 0x84, 0x84);
charsys_addmultibyterange(0xc3, 0xc3, 0x9c, 0x9c);
}
/* [LITHUANIAN] */
if (latin_utf8 || !strcmp(name, "lithuanian-utf8"))
{
/* a, c, e, e, i, š, u, u, ž, A, C, E, E, I, Š, U, U, Ž */
charsys_addmultibyterange(0xc4, 0xc4, 0x84, 0x85);
charsys_addmultibyterange(0xc4, 0xc4, 0x8c, 0x8d);
charsys_addmultibyterange(0xc4, 0xc4, 0x96, 0x99);
charsys_addmultibyterange(0xc4, 0xc4, 0xae, 0xaf);
charsys_addmultibyterange(0xc4, 0xc4, 0xae, 0xaf);
charsys_addmultibyterange(0xc5, 0xc5, 0xa0, 0xa1);
charsys_addmultibyterange(0xc5, 0xc5, 0xb2, 0xb3);
charsys_addmultibyterange(0xc5, 0xc5, 0xaa, 0xab);
charsys_addmultibyterange(0xc5, 0xc5, 0xbd, 0xbe);
}
} }
/** This displays all the nick characters that are permitted */ /** This displays all the nick characters that are permitted */
@ -1190,7 +1236,7 @@ char *charsys_displaychars(void)
} }
buf[n] = '\0'; /* there's always room for a NUL */ buf[n] = '\0'; /* there's always room for a NUL */
return buf; return buf;
} }
@ -1204,7 +1250,7 @@ char *charsys_group(int v)
return "Greek script"; return "Greek script";
if (v & LANGAV_HEBREW_UTF8) if (v & LANGAV_HEBREW_UTF8)
return "Hebrew script"; return "Hebrew script";
return "Other"; return "Other";
} }
@ -1215,7 +1261,7 @@ void charsys_dump_table(char *filter)
for (i = 0; langlist[i].directive; i++) for (i = 0; langlist[i].directive; i++)
{ {
char *charset = langlist[i].directive; char *charset = langlist[i].directive;
if (!match_simple(filter, charset)) if (!match_simple(filter, charset))
continue; /* skip */ continue; /* skip */

View File

@ -81,6 +81,8 @@ ModuleHeader MOD_HEADER
/* Forward declarations */ /* Forward declarations */
char *extban_modeT_conv_param(char *para_in); char *extban_modeT_conv_param(char *para_in);
int textban_check_ban(Client *client, Channel *channel, char *ban, char **msg, char **errmsg);
int textban_can_send_to_channel(Client *client, Channel *channel, Membership *lp, char **msg, char **errmsg, SendType sendtype);
int extban_modeT_is_banned(Client *client, Channel *channel, char *ban, int type, char **msg, char **errmsg); int extban_modeT_is_banned(Client *client, Channel *channel, char *ban, int type, char **msg, char **errmsg);
int extban_modeT_is_ok(Client *client, Channel *channel, char *para, int checkt, int what, int what2); int extban_modeT_is_ok(Client *client, Channel *channel, char *para, int checkt, int what, int what2);
void parse_word(const char *s, char **word, int *type); void parse_word(const char *s, char **word, int *type);
@ -93,6 +95,7 @@ MOD_INIT()
memset(&req, 0, sizeof(ExtbanInfo)); memset(&req, 0, sizeof(ExtbanInfo));
req.flag = 'T'; req.flag = 'T';
req.options = EXTBOPT_NOSTACKCHILD; /* disallow things like ~n:~T, as we only affect text. */
req.conv_param = extban_modeT_conv_param; req.conv_param = extban_modeT_conv_param;
req.is_banned = extban_modeT_is_banned; req.is_banned = extban_modeT_is_banned;
req.is_ok = extban_modeT_is_ok; req.is_ok = extban_modeT_is_ok;
@ -103,6 +106,8 @@ MOD_INIT()
return MOD_FAILED; return MOD_FAILED;
} }
HookAdd(modinfo->handle, HOOKTYPE_CAN_SEND_TO_CHANNEL, 0, textban_can_send_to_channel);
return MOD_SUCCESS; return MOD_SUCCESS;
} }
@ -382,9 +387,54 @@ char *extban_modeT_conv_param(char *para_in)
return retbuf; return retbuf;
} }
/** This is the regular "is banned?" routine. We can't use this as we need to be called for voiced users as well */
int extban_modeT_is_banned(Client *client, Channel *channel, char *ban, int checktype, char **msg, char **errmsg) int extban_modeT_is_banned(Client *client, Channel *channel, char *ban, int checktype, char **msg, char **errmsg)
{ {
static char filtered[512]; /* temp buffer */ return 0;
}
/** Check for text bans (censor and block) */
int textban_can_send_to_channel(Client *client, Channel *channel, Membership *lp, char **msg, char **errmsg, SendType sendtype)
{
Ban *ban;
/* +h/+o/+a/+q users bypass textbans */
if (is_skochanop(client, channel))
return HOOK_CONTINUE;
/* IRCOps with these privileges bypass textbans too */
if (op_can_override("channel:override:message:ban", client, channel, NULL))
return HOOK_CONTINUE;
/* Now we have to manually walk the banlist and check if things match */
for (ban = channel->banlist; ban; ban=ban->next)
{
if (!strncmp(ban->banstr, "~T:", 3))
{
/* ~T ban */
if (textban_check_ban(client, channel, ban->banstr, msg, errmsg))
return HOOK_DENY;
} else
if (!strncmp(ban->banstr, "~t:", 3))
{
/* Stacked ~t:xx:~T ban (timed text ban) */
char *p = strchr(ban->banstr+3, ':');
if (p && !strncmp(p+1, "~T:", 3))
{
if (textban_check_ban(client, channel, p+1, msg, errmsg))
return HOOK_DENY;
}
}
}
return HOOK_CONTINUE;
}
int textban_check_ban(Client *client, Channel *channel, char *ban, char **msg, char **errmsg)
{
static char retbuf[512];
char filtered[512]; /* temp input buffer */
long fl; long fl;
int cleaned=0; int cleaned=0;
char *p; char *p;
@ -399,8 +449,8 @@ int extban_modeT_is_banned(Client *client, Channel *channel, char *ban, int chec
gettimeofday(&tv_alpha, NULL); gettimeofday(&tv_alpha, NULL);
#endif #endif
/* We only filter on BANCHK_MSG, and we can only filter on non-NULL text of course */ /* We can only filter on non-NULL text of course */
if ((checktype != BANCHK_MSG) || (msg == NULL) || (*msg == NULL)) if ((msg == NULL) || (*msg == NULL))
return 0; return 0;
filtered[0] = '\0'; /* NOT needed, but... :P */ filtered[0] = '\0'; /* NOT needed, but... :P */
@ -461,7 +511,8 @@ int extban_modeT_is_banned(Client *client, Channel *channel, char *ban, int chec
{ {
if (*p != ' ') if (*p != ' ')
{ {
*msg = filtered; strlcpy(retbuf, filtered, sizeof(retbuf));
*msg = retbuf;
return 0; /* allow through, but filtered */ return 0; /* allow through, but filtered */
} }
} }

View File

@ -374,6 +374,7 @@ CMD_OVERRIDE_FUNC(override_links)
sendnotice(client, "%s", Settings.links_deny_message); sendnotice(client, "%s", Settings.links_deny_message);
else else
sendnumeric(client, RPL_ENDOFLINKS, "*"); sendnumeric(client, RPL_ENDOFLINKS, "*");
return;
} }
list_for_each_entry(acptr, &global_server_list, client_node) list_for_each_entry(acptr, &global_server_list, client_node)

View File

@ -986,11 +986,16 @@ process_listmode:
case MODE_LIMIT: case MODE_LIMIT:
if (what == MODE_ADD) if (what == MODE_ADD)
{ {
int v;
REQUIRE_PARAMETER() REQUIRE_PARAMETER()
tmp = atoi(param); v = atoi(param);
if (channel->mode.limit == tmp) if (v < 0)
v = 1; /* setting +l with a negative number makes no sense */
if (v > 1000000000)
v = 1000000000; /* some kind of limit, 1 billion (mrah...) */
if (channel->mode.limit == v)
break; break;
channel->mode.limit = tmp; channel->mode.limit = v;
} }
else else
{ {

View File

@ -88,5 +88,5 @@ CMD_FUNC(cmd_opermotd)
motdline->line); motdline->line);
motdline = motdline->next; motdline = motdline->next;
} }
sendnumeric(client, RPL_ENDOFMOTD); sendnumericfmt(client, RPL_ENDOFMOTD, ":End of /OPERMOTD command.");
} }

View File

@ -93,8 +93,13 @@ CMD_FUNC(cmd_ping)
} }
} }
else else
sendto_one(client, NULL, ":%s PONG %s :%s", me.name, {
MessageTag *mtags = NULL;
new_message(&me, recv_mtags, &mtags);
sendto_one(client, mtags, ":%s PONG %s :%s", me.name,
(destination) ? destination : me.name, origin); (destination) ? destination : me.name, origin);
free_message_tags(mtags);
}
} }
/* /*
@ -188,7 +193,10 @@ CMD_FUNC(cmd_pong)
return; return;
} else } else
{ {
sendto_one(target, NULL, ":%s PONG %s %s", client->name, origin, destination); MessageTag *mtags = NULL;
new_message(client, recv_mtags, &mtags);
sendto_one(target, mtags, ":%s PONG %s %s", client->name, origin, destination);
free_message_tags(mtags);
} }
} }
else else

View File

@ -480,16 +480,12 @@ ReputationEntry *find_reputation_entry(char *ip)
return NULL; return NULL;
} }
/** Called when the user connects. int reputation_lookup_score_and_set(Client *client)
* Locally: very early, just after the TCP/IP connection has
* been established, before any data.
* Remote user: early in the HOOKTYPE_REMOTE_CONNECT hook.
*/
int reputation_set_on_connect(Client *client)
{ {
char *ip = client->ip; char *ip = client->ip;
ReputationEntry *e; ReputationEntry *e;
Reputation(client) = 0; /* (re-)set to zero (yes, important!) */
if (ip) if (ip)
{ {
e = find_reputation_entry(ip); e = find_reputation_entry(ip);
@ -498,7 +494,17 @@ int reputation_set_on_connect(Client *client)
Reputation(client) = e->score; /* SET MODDATA */ Reputation(client) = e->score; /* SET MODDATA */
} }
} }
return Reputation(client);
}
/** Called when the user connects.
* Locally: very early, just after the TCP/IP connection has
* been established, before any data.
* Remote user: early in the HOOKTYPE_REMOTE_CONNECT hook.
*/
int reputation_set_on_connect(Client *client)
{
reputation_lookup_score_and_set(client);
return 0; return 0;
} }
@ -507,9 +513,17 @@ int reputation_pre_lconnect(Client *client)
/* User will likely be accepted. Inform other servers about the score /* User will likely be accepted. Inform other servers about the score
* we have for this user. For more information about this type of * we have for this user. For more information about this type of
* server to server traffic, see the reputation_server_cmd function. * server to server traffic, see the reputation_server_cmd function.
*
* Note that we use reputation_lookup_score_and_set() here
* and not Reputation(client) because we want to RE-LOOKUP
* the score for the IP in the database. We do this because
* between reputation_set_on_connect() and reputation_pre_lconnect()
* the IP of the user may have been changed due to IP-spoofing
* (WEBIRC).
*/ */
ReputationEntry *e = find_reputation_entry(GetIP(client)); int score = reputation_lookup_score_and_set(client);
sendto_server(NULL, 0, 0, NULL, ":%s REPUTATION %s %d", me.id, GetIP(client), e ? (int)e->score : 0);
sendto_server(NULL, 0, 0, NULL, ":%s REPUTATION %s %d", me.id, GetIP(client), score);
return 0; return 0;
} }

View File

@ -161,7 +161,7 @@ CMD_FUNC(cmd_sapart)
parv[2] = comment ? commentx : NULL; // comment parv[2] = comment ? commentx : NULL; // comment
if (comment) if (comment)
{ {
sendnotice(target, "*** You were forced to part %s (%s)", parv[1], commentx); //sendnotice(target, "*** You were forced to part %s (%s)", parv[1], commentx);
sendto_umode_global(UMODE_OPER, "%s used SAPART to make %s part %s (%s)", sendto_umode_global(UMODE_OPER, "%s used SAPART to make %s part %s (%s)",
client->name, target->name, parv[1], comment); client->name, target->name, parv[1], comment);
ircd_log(LOG_SACMDS,"SAPART: %s used SAPART to make %s part %s (%s)", ircd_log(LOG_SACMDS,"SAPART: %s used SAPART to make %s part %s (%s)",
@ -169,7 +169,7 @@ CMD_FUNC(cmd_sapart)
} }
else else
{ {
sendnotice(target, "*** You were forced to part %s", parv[1]); //sendnotice(target, "*** You were forced to part %s", parv[1]);
sendto_umode_global(UMODE_OPER, "%s used SAPART to make %s part %s", sendto_umode_global(UMODE_OPER, "%s used SAPART to make %s part %s",
client->name, target->name, parv[1]); client->name, target->name, parv[1]);
ircd_log(LOG_SACMDS,"SAPART: %s used SAPART to make %s part %s", ircd_log(LOG_SACMDS,"SAPART: %s used SAPART to make %s part %s",

View File

@ -31,6 +31,7 @@ ConfigItem_badword *conf_badword_message = NULL;
static ConfigItem_badword *copy_badword_struct(ConfigItem_badword *ca, int regex, int regflags); static ConfigItem_badword *copy_badword_struct(ConfigItem_badword *ca, int regex, int regflags);
int censor_stats_badwords_user(Client *client, char *para);
MOD_TEST() MOD_TEST()
{ {
@ -43,11 +44,9 @@ MOD_INIT()
ModInfo = modinfo; ModInfo = modinfo;
MARK_AS_OFFICIAL_MODULE(modinfo); MARK_AS_OFFICIAL_MODULE(modinfo);
UmodeAdd(modinfo->handle, 'G', UMODE_GLOBAL, 0, NULL, &UMODE_CENSOR); UmodeAdd(modinfo->handle, 'G', UMODE_GLOBAL, 0, NULL, &UMODE_CENSOR);
HookAdd(modinfo->handle, HOOKTYPE_CAN_SEND_TO_USER, 0, censor_can_send_to_user); HookAdd(modinfo->handle, HOOKTYPE_CAN_SEND_TO_USER, 0, censor_can_send_to_user);
HookAdd(modinfo->handle, HOOKTYPE_STATS, 0, censor_stats_badwords_user);
HookAdd(modinfo->handle, HOOKTYPE_CONFIGRUN, 0, censor_config_run); HookAdd(modinfo->handle, HOOKTYPE_CONFIGRUN, 0, censor_config_run);
return MOD_SUCCESS; return MOD_SUCCESS;
} }
@ -254,11 +253,13 @@ int censor_can_send_to_user(Client *client, Client *target, char **text, char **
return HOOK_CONTINUE; return HOOK_CONTINUE;
} }
// TODO: when stats is modular, make it call this for badwords int censor_stats_badwords_user(Client *client, char *para)
int stats_badwords(Client *client, char *para)
{ {
ConfigItem_badword *words; ConfigItem_badword *words;
if (!para || !(!strcmp(para, "b") || !strcasecmp(para, "badword")))
return 0;
for (words = conf_badword_message; words; words = words->next) for (words = conf_badword_message; words; words = words->next)
{ {
sendtxtnumeric(client, "m %c %s%s%s %s", words->type & BADW_TYPE_REGEX ? 'R' : 'F', sendtxtnumeric(client, "m %c %s%s%s %s", words->type & BADW_TYPE_REGEX ? 'R' : 'F',
@ -266,5 +267,5 @@ int stats_badwords(Client *client, char *para)
(words->type & BADW_TYPE_FAST_R) ? "*" : "", (words->type & BADW_TYPE_FAST_R) ? "*" : "",
words->action == BADWORD_REPLACE ? (words->replace ? words->replace : "<censored>") : ""); words->action == BADWORD_REPLACE ? (words->replace ? words->replace : "<censored>") : "");
} }
return 0; return 1;
} }

View File

@ -8,7 +8,7 @@
#include "unrealircd.h" #include "unrealircd.h"
#include <limits.h> #include <limits.h>
#define WEBSOCKET_VERSION "1.0.0" #define WEBSOCKET_VERSION "1.1.0"
ModuleHeader MOD_HEADER ModuleHeader MOD_HEADER
= { = {
@ -23,10 +23,14 @@ ModuleHeader MOD_HEADER
#error "In UnrealIRCd char should always be unsigned. Check your compiler" #error "In UnrealIRCd char should always be unsigned. Check your compiler"
#endif #endif
#ifndef WEBSOCKET_SEND_BUFFER_SIZE
#define WEBSOCKET_SEND_BUFFER_SIZE 16384
#endif
typedef struct WebSocketUser WebSocketUser; typedef struct WebSocketUser WebSocketUser;
struct WebSocketUser { struct WebSocketUser {
char get; /**< GET initiated */ char get; /**< GET initiated */
char handshake_completed; /**< Handshake completed, use data frames */ char handshake_completed; /**< Handshake completed, use websocket frames */
char *handshake_key; /**< Handshake key (used during handshake) */ char *handshake_key; /**< Handshake key (used during handshake) */
char *lefttoparse; /**< Leftover buffer to parse */ char *lefttoparse; /**< Leftover buffer to parse */
int lefttoparselen; /**< Length of lefttoparse buffer */ int lefttoparselen; /**< Length of lefttoparse buffer */
@ -59,8 +63,8 @@ int websocket_handle_handshake(Client *client, char *readbuf, int *length);
int websocket_complete_handshake(Client *client); int websocket_complete_handshake(Client *client);
int websocket_handle_packet_ping(Client *client, char *buf, int len); int websocket_handle_packet_ping(Client *client, char *buf, int len);
int websocket_handle_packet_pong(Client *client, char *buf, int len); int websocket_handle_packet_pong(Client *client, char *buf, int len);
int websocket_create_frame(int opcode, char **buf, int *len); int websocket_create_packet(int opcode, char **buf, int *len);
int websocket_send_frame(Client *client, int opcode, char *buf, int len); int websocket_send_pong(Client *client, char *buf, int len);
/* Global variables */ /* Global variables */
ModDataInfo *websocket_md; ModDataInfo *websocket_md;
@ -231,14 +235,14 @@ int websocket_packet_out(Client *from, Client *to, Client *intended_to, char **m
if (MyConnect(to) && WSU(to) && WSU(to)->handshake_completed) if (MyConnect(to) && WSU(to) && WSU(to)->handshake_completed)
{ {
if (WEBSOCKET_TYPE(to) == WEBSOCKET_TYPE_BINARY) if (WEBSOCKET_TYPE(to) == WEBSOCKET_TYPE_BINARY)
websocket_create_frame(WSOP_BINARY, msg, length); websocket_create_packet(WSOP_BINARY, msg, length);
else if (WEBSOCKET_TYPE(to) == WEBSOCKET_TYPE_TEXT) else if (WEBSOCKET_TYPE(to) == WEBSOCKET_TYPE_TEXT)
{ {
/* Some more conversions are needed */ /* Some more conversions are needed */
char *safe_msg = unrl_utf8_make_valid(*msg); char *safe_msg = unrl_utf8_make_valid(*msg);
*msg = safe_msg; *msg = safe_msg;
*length = *msg ? strlen(safe_msg) : 0; *length = *msg ? strlen(safe_msg) : 0;
websocket_create_frame(WSOP_TEXT, msg, length); websocket_create_packet(WSOP_TEXT, msg, length);
} }
return 0; return 0;
} }
@ -291,7 +295,7 @@ int websocket_handle_websocket(Client *client, char *readbuf2, int length2)
} }
/** Incoming packet hook. /** Incoming packet hook.
* This processes Websocket frames, if this is a websocket connection. * This processes websocket frames, if this is a websocket connection.
* NOTE The different return values: * NOTE The different return values:
* -1 means: don't touch this client anymore, it has or might have been killed! * -1 means: don't touch this client anymore, it has or might have been killed!
* 0 means: don't process this data, but you can read another packet if you want * 0 means: don't process this data, but you can read another packet if you want
@ -712,7 +716,7 @@ int websocket_handle_packet_ping(Client *client, char *buf, int len)
dead_socket(client, "WebSocket: oversized PING request"); dead_socket(client, "WebSocket: oversized PING request");
return -1; return -1;
} }
websocket_send_frame(client, WSOP_PONG, buf, len); websocket_send_pong(client, buf, len);
client->local->since++; /* lag penalty of 1 second */ client->local->since++; /* lag penalty of 1 second */
return 0; return 0;
} }
@ -723,28 +727,18 @@ int websocket_handle_packet_pong(Client *client, char *buf, int len)
return 0; return 0;
} }
/** Create a frame. Used for OUTGOING data. */ /** Create a simple websocket packet that is ready to be send.
int websocket_create_frame(int opcode, char **buf, int *len) * This is the simple version that is used ONLY for WSOP_PONG,
* as it does not take \r\n into account.
*/
int websocket_create_packet_simple(int opcode, char **buf, int *len)
{ {
static char sendbuf[8192]; static char sendbuf[8192];
sendbuf[0] = opcode | 0x80; /* opcode & final */ sendbuf[0] = opcode | 0x80; /* opcode & final */
if (*len > sizeof(sendbuf) - 8) if (*len > sizeof(sendbuf) - 8)
abort(); /* should never happen (safety) */ return -1; /* should never happen (safety) */
/* strip LF */
if (*len > 0)
{
if (*(*buf + *len - 1) == '\n')
*len = *len - 1;
}
/* strip CR */
if (*len > 0)
{
if (*(*buf + *len - 1) == '\r')
*len = *len - 1;
}
if (*len < 126) if (*len < 126)
{ {
@ -765,13 +759,91 @@ int websocket_create_frame(int opcode, char **buf, int *len)
return 0; return 0;
} }
/** Create and send a frame */ /** Create a websocket packet that is ready to be send.
int websocket_send_frame(Client *client, int opcode, char *buf, int len) * This is the more complex version that takes into account
* stripping off \r and \n, and possibly multi line due to
* labeled-response. It is used for WSOP_TEXT and WSOP_BINARY.
* The end result is one or more websocket frames,
* all in a single packet *buf with size *len.
*/
int websocket_create_packet(int opcode, char **buf, int *len)
{
static char sendbuf[WEBSOCKET_SEND_BUFFER_SIZE];
char *s = *buf; /* points to start of current line */
char *s2; /* used for searching of end of current line */
char *lastbyte = *buf + *len - 1; /* points to last byte in *buf that can be safely read */
int bytes_to_copy;
char newline;
char *o = sendbuf; /* points to current byte within 'sendbuf' of output buffer */
int bytes_in_sendbuf = 0;
int bytes_single_frame;
/* Sending 0 bytes makes no sense, and the code below may assume >0, so reject this. */
if (*len == 0)
return -1;
do {
/* Find next \r or \n */
for (s2 = s; *s2 && (s2 <= lastbyte); s2++)
{
if ((*s2 == '\n') || (*s2 == '\r'))
break;
}
/* Now 's' points to start of line and 's2' points to beyond end of the line
* (either at \r, \n or beyond the buffer).
*/
bytes_to_copy = s2 - s;
if (bytes_to_copy < 126)
bytes_single_frame = 2 + bytes_to_copy;
else
bytes_single_frame = 4 + bytes_to_copy;
if (bytes_in_sendbuf + bytes_single_frame > sizeof(sendbuf))
{
/* Overflow. This should never happen. */
sendto_ops("[websocket] [BUG] Overflow prevented: %d + %d > %d",
bytes_in_sendbuf, bytes_single_frame, (int)sizeof(sendbuf));
return -1;
}
/* Create the new frame */
o[0] = opcode | 0x80; /* opcode & final */
if (bytes_to_copy < 126)
{
/* Short payload */
o[1] = (char)bytes_to_copy;
memcpy(&o[2], s, bytes_to_copy);
} else {
/* Long payload */
o[1] = 126;
o[2] = (char)((bytes_to_copy >> 8) & 0xFF);
o[3] = (char)(bytes_to_copy & 0xFF);
memcpy(&o[4], s, bytes_to_copy);
}
/* Advance destination pointer and counter */
o += bytes_single_frame;
bytes_in_sendbuf += bytes_single_frame;
/* Advance source pointer and skip all trailing \n and \r */
for (s = s2; *s && (s <= lastbyte) && ((*s == '\n') || (*s == '\r')); s++);
} while(s <= lastbyte);
*buf = sendbuf;
*len = bytes_in_sendbuf;
return 0;
}
/** Create and send a WSOP_PONG frame */
int websocket_send_pong(Client *client, char *buf, int len)
{ {
char *b = buf; char *b = buf;
int l = len; int l = len;
if (websocket_create_frame(opcode, &b, &l) < 0) if (websocket_create_packet_simple(WSOP_PONG, &b, &l) < 0)
return -1; return -1;
if (DBufLength(&client->local->sendQ) > get_sendq(client)) if (DBufLength(&client->local->sendQ) > get_sendq(client))

View File

@ -497,8 +497,10 @@ static int do_match(Client *client, Client *acptr, char *mask, struct who_format
* - pointer to int maxmatches * - pointer to int maxmatches
* - format options * - format options
* output - NONE * output - NONE
* side effects - lists matching invisible clients on specified channel, * side effects - lists matching clients on specified channel,
* marks matched clients. * marks matched clients.
*
* NOTE: only call this from who_global() due to client marking!
*/ */
static void who_common_channel(Client *client, Channel *channel, static void who_common_channel(Client *client, Channel *channel,
@ -513,10 +515,10 @@ static void who_common_channel(Client *client, Channel *channel,
{ {
acptr = cm->client; acptr = cm->client;
if (!IsInvisible(acptr) || IsMarked(acptr)) if (IsMarked(acptr))
continue; continue;
if(IsMatch(fmt, WMATCH_OPER) && !IsOper(acptr)) if (IsMatch(fmt, WMATCH_OPER) && !IsOper(acptr))
continue; continue;
for (h = Hooks[HOOKTYPE_VISIBLE_IN_CHANNEL]; h; h = h->next) for (h = Hooks[HOOKTYPE_VISIBLE_IN_CHANNEL]; h; h = h->next)
@ -562,10 +564,12 @@ static void who_global(Client *client, char *mask, int operspy, struct who_forma
Client *acptr; Client *acptr;
int maxmatches = IsOper(client) ? INT_MAX : WHOLIMIT; int maxmatches = IsOper(client) ? INT_MAX : WHOLIMIT;
/* first, list all matching INvisible clients on common channels /* Initialize the markers to zero */
* if this is not an operspy who list_for_each_entry(acptr, &client_list, client_node)
*/ ClearMark(acptr);
if(!operspy)
/* First, if not operspy, then list all matching clients on common channels */
if (!operspy)
{ {
Membership *lp; Membership *lp;
@ -573,26 +577,22 @@ static void who_global(Client *client, char *mask, int operspy, struct who_forma
who_common_channel(client, lp->channel, mask, &maxmatches, fmt); who_common_channel(client, lp->channel, mask, &maxmatches, fmt);
} }
/* second, list all matching visible clients and clear all marks /* Second, list all matching visible clients. */
* on invisible clients
* if this is an operspy who, list all matching clients, no need
* to clear marks
*/
list_for_each_entry(acptr, &client_list, client_node) list_for_each_entry(acptr, &client_list, client_node)
{ {
if(!IsUser(acptr)) if (!IsUser(acptr))
continue; continue;
if(IsInvisible(acptr) && !operspy) if (IsInvisible(acptr) && !operspy && (client != acptr))
{
ClearMark(acptr);
continue;
}
if(IsMatch(fmt, WMATCH_OPER) && !IsOper(acptr))
continue; continue;
if(maxmatches > 0) if (IsMarked(acptr))
continue;
if (IsMatch(fmt, WMATCH_OPER) && !IsOper(acptr))
continue;
if (maxmatches > 0)
{ {
if (do_match(client, acptr, mask, fmt)) if (do_match(client, acptr, mask, fmt))
{ {

View File

@ -230,43 +230,6 @@ static void mylog(char *fmt, ...)
ircd_log(LOG_ERROR, "%s", buf); ircd_log(LOG_ERROR, "%s", buf);
} }
/** Set DH (Diffie-Hellman) parameters.
* We don't use this anymore, unless explicitly instructed,
* as we use the more secure ECDHE/EECDH instead
* (Ephemeral Elliptic-Curve Diffie-Hellman)
*/
static int setup_dh_params(SSL_CTX *ctx)
{
DH *dh;
BIO *bio;
char *dh_file = iConf.tls_options ? iConf.tls_options->dh_file : tempiConf.tls_options->dh_file;
/* ^^ because we can be called both before config file initalization or after */
if (dh_file == NULL)
return 1;
bio = BIO_new_file(dh_file, "r");
if (bio == NULL)
{
config_error("Failed to load DH parameters %s", dh_file);
config_report_ssl_error();
return 0;
}
dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
if (dh == NULL)
{
config_error("Failed to use DH parameters %s", dh_file);
config_report_ssl_error();
BIO_free(bio);
return 0;
}
BIO_free(bio);
SSL_CTX_set_tmp_dh(ctx, dh);
return 1;
}
/** Disable SSL/TLS protocols as set by config */ /** Disable SSL/TLS protocols as set by config */
void disable_ssl_protocols(SSL_CTX *ctx, TLSOptions *tlsoptions) void disable_ssl_protocols(SSL_CTX *ctx, TLSOptions *tlsoptions)
{ {
@ -382,9 +345,6 @@ SSL_CTX *init_ctx(TLSOptions *tlsoptions, int server)
#endif #endif
SSL_CTX_set_options(ctx, SSL_OP_NO_TICKET); SSL_CTX_set_options(ctx, SSL_OP_NO_TICKET);
if (!setup_dh_params(ctx))
goto fail;
if (!tlsoptions->certificate_file) if (!tlsoptions->certificate_file)
{ {
config_error("No SSL certificate configured (set::options::ssl::certificate or in a listen block)"); config_error("No SSL certificate configured (set::options::ssl::certificate or in a listen block)");
@ -577,6 +537,8 @@ void reinit_ssl(Client *client)
config_report_ssl_error(); config_report_ssl_error();
return; return;
} }
if (ctx_server)
SSL_CTX_free(ctx_server);
ctx_server = tmp; /* activate */ ctx_server = tmp; /* activate */
tmp = init_ctx(iConf.tls_options, 0); tmp = init_ctx(iConf.tls_options, 0);
@ -586,6 +548,8 @@ void reinit_ssl(Client *client)
config_report_ssl_error(); config_report_ssl_error();
return; return;
} }
if (ctx_client)
SSL_CTX_free(ctx_client);
ctx_client = tmp; /* activate */ ctx_client = tmp; /* activate */
/* listen::tls-options.... */ /* listen::tls-options.... */
@ -600,6 +564,8 @@ void reinit_ssl(Client *client)
config_report_ssl_error(); config_report_ssl_error();
return; return;
} }
if (listen->ssl_ctx)
SSL_CTX_free(listen->ssl_ctx);
listen->ssl_ctx = tmp; /* activate */ listen->ssl_ctx = tmp; /* activate */
} }
} }
@ -616,6 +582,8 @@ void reinit_ssl(Client *client)
config_report_ssl_error(); config_report_ssl_error();
return; return;
} }
if (sni->ssl_ctx)
SSL_CTX_free(sni->ssl_ctx);
sni->ssl_ctx = tmp; /* activate */ sni->ssl_ctx = tmp; /* activate */
} }
} }
@ -633,6 +601,8 @@ void reinit_ssl(Client *client)
config_report_ssl_error(); config_report_ssl_error();
return; return;
} }
if (link->ssl_ctx)
SSL_CTX_free(link->ssl_ctx);
link->ssl_ctx = tmp; /* activate */ link->ssl_ctx = tmp; /* activate */
} }
} }

View File

@ -4,7 +4,7 @@ echo "Extracting src/version.c..."
#id=`grep '$Id: Changes,v' ../Changes` #id=`grep '$Id: Changes,v' ../Changes`
#id=`echo $id |sed 's/.* Changes\,v \(.*\) .* Exp .*/\1/'` #id=`echo $id |sed 's/.* Changes\,v \(.*\) .* Exp .*/\1/'`
id="5.0.6" id="5.0.7"
echo "$id" echo "$id"
if test -r version.c if test -r version.c

View File

@ -3,7 +3,7 @@
<assemblyIdentity <assemblyIdentity
processorArchitecture="amd64" processorArchitecture="amd64"
name="UnrealIRCd.UnrealIRCd.5" name="UnrealIRCd.UnrealIRCd.5"
version="5.0.6.0" version="5.0.7.0"
type="win32" type="win32"
/> />
<description>Internet Relay Chat Daemon</description> <description>Internet Relay Chat Daemon</description>

View File

@ -6,7 +6,7 @@
[Setup] [Setup]
AppName=UnrealIRCd 5 AppName=UnrealIRCd 5
AppVerName=UnrealIRCd 5.0.6 AppVerName=UnrealIRCd 5.0.7
AppPublisher=UnrealIRCd Team AppPublisher=UnrealIRCd Team
AppPublisherURL=https://www.unrealircd.org AppPublisherURL=https://www.unrealircd.org
AppSupportURL=https://www.unrealircd.org AppSupportURL=https://www.unrealircd.org