Merge remote-tracking branch 'upstream/unreal60_dev' into piss60

This commit is contained in:
alice 2024-05-30 00:44:40 +01:00
commit a6bc1c9a9b
27 changed files with 563 additions and 116 deletions

2
.github/FUNDING.yml vendored Normal file
View file

@ -0,0 +1,2 @@
github: [syzop]
patreon: UnrealIRCd

44
configure vendored
View file

@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.71 for unrealircd 6.1.5.
# Generated by GNU Autoconf 2.71 for unrealircd 6.1.6-git.
#
# Report bugs to <https://bugs.unrealircd.org/>.
#
@ -611,8 +611,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='unrealircd'
PACKAGE_TARNAME='unrealircd'
PACKAGE_VERSION='6.1.5'
PACKAGE_STRING='unrealircd 6.1.5'
PACKAGE_VERSION='6.1.6-git'
PACKAGE_STRING='unrealircd 6.1.6-git'
PACKAGE_BUGREPORT='https://bugs.unrealircd.org/'
PACKAGE_URL='https://unrealircd.org/'
@ -1372,7 +1372,7 @@ if test "$ac_init_help" = "long"; then
# 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.
cat <<_ACEOF
\`configure' configures unrealircd 6.1.5 to adapt to many kinds of systems.
\`configure' configures unrealircd 6.1.6-git to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@ -1438,7 +1438,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of unrealircd 6.1.5:";;
short | recursive ) echo "Configuration of unrealircd 6.1.6-git:";;
esac
cat <<\_ACEOF
@ -1616,7 +1616,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
unrealircd configure 6.1.5
unrealircd configure 6.1.6-git
generated by GNU Autoconf 2.71
Copyright (C) 2021 Free Software Foundation, Inc.
@ -1915,7 +1915,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
It was created by unrealircd $as_me 6.1.5, which was
It was created by unrealircd $as_me 6.1.6-git, which was
generated by GNU Autoconf 2.71. Invocation command line was
$ $0$ac_configure_args_raw
@ -2698,7 +2698,7 @@ printf "%s\n" "#define UNREAL_VERSION_MAJOR $UNREAL_VERSION_MAJOR" >>confdefs.h
# Minor version number (e.g.: Z in X.Y.Z)
UNREAL_VERSION_MINOR="5"
UNREAL_VERSION_MINOR="6"
printf "%s\n" "#define UNREAL_VERSION_MINOR $UNREAL_VERSION_MINOR" >>confdefs.h
@ -2706,7 +2706,7 @@ printf "%s\n" "#define UNREAL_VERSION_MINOR $UNREAL_VERSION_MINOR" >>confdefs.h
# The version suffix such as a beta marker or release candidate
# marker. (e.g.: -rcX for unrealircd-3.2.9-rcX). This macro is a
# string instead of an integer because it contains arbitrary data.
UNREAL_VERSION_SUFFIX=""
UNREAL_VERSION_SUFFIX="-git"
printf "%s\n" "#define UNREAL_VERSION_SUFFIX \"$UNREAL_VERSION_SUFFIX\"" >>confdefs.h
@ -4586,15 +4586,15 @@ ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -D_FORTIFY_SOURCE=2" >&5
printf %s "checking whether C compiler accepts -D_FORTIFY_SOURCE=2... " >&6; }
if test ${ax_cv_check_cflags__Werror___D_FORTIFY_SOURCE_2+y}
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -D_FORTIFY_SOURCE=3" >&5
printf %s "checking whether C compiler accepts -D_FORTIFY_SOURCE=3... " >&6; }
if test ${ax_cv_check_cflags__Werror___D_FORTIFY_SOURCE_3+y}
then :
printf %s "(cached) " >&6
else $as_nop
ax_check_save_flags=$CFLAGS
CFLAGS="$CFLAGS -Werror -D_FORTIFY_SOURCE=2"
CFLAGS="$CFLAGS -Werror -D_FORTIFY_SOURCE=3"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
@ -4608,18 +4608,18 @@ main (void)
_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
ax_cv_check_cflags__Werror___D_FORTIFY_SOURCE_2=yes
ax_cv_check_cflags__Werror___D_FORTIFY_SOURCE_3=yes
else $as_nop
ax_cv_check_cflags__Werror___D_FORTIFY_SOURCE_2=no
ax_cv_check_cflags__Werror___D_FORTIFY_SOURCE_3=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
CFLAGS=$ax_check_save_flags
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags__Werror___D_FORTIFY_SOURCE_2" >&5
printf "%s\n" "$ax_cv_check_cflags__Werror___D_FORTIFY_SOURCE_2" >&6; }
if test x"$ax_cv_check_cflags__Werror___D_FORTIFY_SOURCE_2" = xyes
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags__Werror___D_FORTIFY_SOURCE_3" >&5
printf "%s\n" "$ax_cv_check_cflags__Werror___D_FORTIFY_SOURCE_3" >&6; }
if test x"$ax_cv_check_cflags__Werror___D_FORTIFY_SOURCE_3" = xyes
then :
HARDEN_CFLAGS="$HARDEN_CFLAGS -D_FORTIFY_SOURCE=2"
HARDEN_CFLAGS="$HARDEN_CFLAGS -D_FORTIFY_SOURCE=3"
else $as_nop
:
fi
@ -9600,7 +9600,7 @@ if test "$ac_cv_werror" = "yes" ; then
fi
if test "$ac_cv_asan" = "yes" ; then
CFLAGS="$CFLAGS -O1 -fno-inline -fsanitize=address -fno-omit-frame-pointer -DNOCLOSEFD"
CFLAGS="$CFLAGS -O2 -fno-inline -fsanitize=address -fno-omit-frame-pointer -DNOCLOSEFD"
IRCDLIBS="-fsanitize=address $IRCDLIBS"
fi
@ -10109,7 +10109,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
This file was extended by unrealircd $as_me 6.1.5, which was
This file was extended by unrealircd $as_me 6.1.6-git, which was
generated by GNU Autoconf 2.71. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@ -10174,7 +10174,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config='$ac_cs_config_escaped'
ac_cs_version="\\
unrealircd config.status 6.1.5
unrealircd config.status 6.1.6-git
configured by $0, generated by GNU Autoconf 2.71,
with options \\"\$ac_cs_config\\"

View file

@ -7,7 +7,7 @@ dnl src/windows/unrealinst.iss
dnl doc/Config.header
dnl src/version.c.SH
AC_INIT([unrealircd], [6.1.5], [https://bugs.unrealircd.org/], [], [https://unrealircd.org/])
AC_INIT([unrealircd], [6.1.6-git], [https://bugs.unrealircd.org/], [], [https://unrealircd.org/])
AC_CONFIG_SRCDIR([src/ircd.c])
AC_CONFIG_HEADER([include/setup.h])
AC_CONFIG_AUX_DIR([autoconf])
@ -34,13 +34,13 @@ UNREAL_VERSION_MAJOR=["1"]
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)
UNREAL_VERSION_MINOR=["5"]
UNREAL_VERSION_MINOR=["6"]
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
# marker. (e.g.: -rcX for unrealircd-3.2.9-rcX). This macro is a
# string instead of an integer because it contains arbitrary data.
UNREAL_VERSION_SUFFIX=[""]
UNREAL_VERSION_SUFFIX=["-git"]
AC_DEFINE_UNQUOTED([UNREAL_VERSION_SUFFIX], ["$UNREAL_VERSION_SUFFIX"], [Version suffix such as a beta marker or release candidate marker. (e.g.: -rcX for unrealircd-3.2.9-rcX)])
AC_PATH_PROG(RM,rm)
@ -131,7 +131,7 @@ AS_IF([test x"$hardening" != x"no"], [
check_cc_flag([-fno-strict-overflow], [HARDEN_CFLAGS="$HARDEN_CFLAGS -fno-strict-overflow"])
# This one will likely succeed, even on platforms where it does nothing.
check_cc_flag([-D_FORTIFY_SOURCE=2], [HARDEN_CFLAGS="$HARDEN_CFLAGS -D_FORTIFY_SOURCE=2"])
check_cc_flag([-D_FORTIFY_SOURCE=3], [HARDEN_CFLAGS="$HARDEN_CFLAGS -D_FORTIFY_SOURCE=3"])
check_cc_flag([-fstack-protector-all],
[check_link_flag([-fstack-protector-all],
@ -896,7 +896,7 @@ fi
dnl Address sanitizer build
if test "$ac_cv_asan" = "yes" ; then
CFLAGS="$CFLAGS -O1 -fno-inline -fsanitize=address -fno-omit-frame-pointer -DNOCLOSEFD"
CFLAGS="$CFLAGS -O2 -fno-inline -fsanitize=address -fno-omit-frame-pointer -DNOCLOSEFD"
IRCDLIBS="-fsanitize=address $IRCDLIBS"
fi

View file

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

View file

@ -1,6 +1,77 @@
UnrealIRCd 6.1.5
UnrealIRCd 6.1.6-git
=================
This is the git version (development version) for future 6.1.6. This is work
in progress and may not always be a stable version.
### Enhancements:
* [Crule](https://www.unrealircd.org/docs/Crule) functions can now do everything
that [security group blocks](https://www.unrealircd.org/docs/Security-group_block)
can do.
In practice, this means the following functions were added in this release:
* `is_tls()` returns true if the client is using SSL/TLS
* `in_security_group('known-users')` returns true if the user is in the
specified [security group](https://www.unrealircd.org/docs/Security-group_block).
* `match_mask('*@*.example.org')` or `match_mask('*.example.org')`
returns true if client matches mask.
* `match_ip('192.168.*')` or with CIDR like `match_ip('192.168.0.0/16')`
returns true if IP address of client matches.
* `is_identified()` which returns true if the client is identified to a services account.
* `is_webirc()` which returns true if the client is connected using WEBIRC.
* `is_websocket()` which returns true if the client is connected using WebSockets.
* `match_realname('*xyz*')` which returns true if the real name (gecos)
contains xyz.
* `match_account('xyz')` which returns true if the services account name is xyz.
* `match_country('NL')` which returns true if
[GeoIP](https://www.unrealircd.org/docs/GeoIP) determined the
country to be NL.
* `match_certfp('abc')` which returns true if the
[Certificate fingerprint](https://www.unrealircd.org/docs/Certificate_fingerprint)
is abc.
### Changes:
* For many years `REHASH -all` is the same as `REHASH` so we now reject
the former.
* The [Crule](https://www.unrealircd.org/docs/Crule) function `inchannel('#xyz')`
is now called `in_channel('#xyz')` to match the naming style of the other
functions. The old name will keep working for the entire UnrealIRCd 6 series too.
### Fixes:
* Crash if you first REHASH and have a parse error (failed rehash 1) and then
REHASH again but a remote include fails to load (failed rehash 2).
* Crash on Windows when using
[Crule](https://www.unrealircd.org/docs/Crule) functions,
[Central Spamreport](https://www.unrealircd.org/docs/Central_spamreport) or
[Central Spamfilter](https://www.unrealircd.org/docs/Central_Spamfilter).
* [Conditional config](https://www.unrealircd.org/docs/Defines_and_conditional_config):
using @if with a variable like `@if $VAR == "something"` always evaluated to false.
* A [`~forward`](https://www.unrealircd.org/docs/Extended_bans#Group_2:_actions)
ban did not check ban exemptions (+e), always forwarding the user.
* When booting for the first time (without any cached files) the IRCd
downloads GeoIP.dat. If that fails, e.g. due to lack of internet connectivity,
we now show a warning and continue booting instead of it being a hard error.
Note that we already dealt with this properly after the file has been cached
(so after first download), see "What if your web server is down" in
[Remote includes](https://www.unrealircd.org/docs/Remote_includes#What_if_your_web_server_is_down).
### Removed:
* The `tls-and-known-users` [security group](https://www.unrealircd.org/docs/Security-group_block)
was confusing, in the sense that this group consisted of tls-users
and of known-users (in an OR fashion, not AND).
Since this group is rarely used it has now been removed altogether.
If you used it in your configuration then you can still manually
(re)create the security group with:
```
security-group tls-and-known-users { identified yes; reputation-score 25; tls yes; }
```
### Developers and protocol:
* Modules can now provide SASL locally, see
[Dev:Authentication module](https://www.unrealircd.org/docs/Dev:Authentication_module).
UnrealIRCd 6.1.5
-----------------
This is just a regular release with various enhancements and bug fixes.
### Enhancements:

View file

@ -1,4 +1,4 @@
/* [6.1.5]
/* [6.1.6-git]
* This file will load (nearly) all modules available on UnrealIRCd.
* So all commands, channel modes, user modes, etc..
*
@ -301,8 +301,8 @@ loadmodule "geoip_classic";
@if module-loaded("geoip_classic")
set {
geoip-classic {
ipv4-database "https://www.unrealircd.org/files/geo/classic/GeoIP.dat" { url-refresh 14d; }
ipv6-database "https://www.unrealircd.org/files/geo/classic/GeoIPv6.dat" { url-refresh 14d; }
ipv4-database "https://www.unrealircd.org/files/geo/classic/GeoIP.dat" { url-refresh 14d; url-fail warn; }
ipv6-database "https://www.unrealircd.org/files/geo/classic/GeoIPv6.dat" { url-refresh 14d; url-fail warn; }
}
}
@endif

View file

@ -38,7 +38,7 @@ PROJECT_NAME = "UnrealIRCd"
# could be handy for archiving the generated documentation or if some version
# control system is used.
PROJECT_NUMBER = 6.1.5
PROJECT_NUMBER = 6.1.6-git
# 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

View file

@ -82,7 +82,7 @@ extern void preprocessor_cc_free_level(ConditionalConfig **cc_list, int level);
extern void preprocessor_cc_free_list(ConditionalConfig *cc);
extern void preprocessor_resolve_conditionals_ce(ConfigEntry **ce_list, PreprocessorPhase phase);
extern void preprocessor_resolve_conditionals_all(PreprocessorPhase phase);
extern void free_config_defines(void);
extern void init_config_defines(void);
extern void preprocessor_replace_defines(char **item, ConfigEntry *ce);
/*
@ -717,6 +717,7 @@ extern int unreal_copyfile(const char *src, const char *dest);
extern int unreal_copyfileex(const char *src, const char *dest, int tryhardlink);
extern time_t unreal_getfilemodtime(const char *filename);
extern void unreal_setfilemodtime(const char *filename, time_t mtime);
extern int unreal_touch(const char *filename, time_t mtime);
extern void DeleteTempModules(void);
extern MODVAR Extban *extbaninfo;
extern Extban *findmod_by_bantype(const char *str, const char **remainder);
@ -922,14 +923,17 @@ extern MODVAR void (*cancel_ident_lookup)(Client *client);
extern MODVAR int (*spamreport)(Client *client, const char *ip, NameValuePrioList *details, const char *spamreport_block, Client *by);
extern MODVAR int (*crule_test)(const char *rule);
extern MODVAR CRuleNode *(*crule_parse)(const char *rule);
extern int (*crule_eval)(crule_context *context, CRuleNode *rule);
extern MODVAR int (*crule_eval)(crule_context *context, CRuleNode *rule);
#define safe_crule_free(x) do { if (x) crule_free(&x); } while(0)
extern void (*crule_free)(CRuleNode **);
extern const char *(*crule_errstring)(int errcode);
extern void (*ban_act_set_reputation)(Client *client, BanAction *action);
extern const char *(*get_central_api_key)(void);
extern int (*central_spamreport)(Client *target, Client *by);
extern int (*central_spamreport_enabled)(void);
extern MODVAR void (*crule_free)(CRuleNode **);
extern MODVAR const char *(*crule_errstring)(int errcode);
extern MODVAR void (*ban_act_set_reputation)(Client *client, BanAction *action);
extern MODVAR const char *(*get_central_api_key)(void);
extern MODVAR int (*central_spamreport)(Client *target, Client *by);
extern MODVAR int (*central_spamreport_enabled)(void);
extern MODVAR void (*sasl_succeeded)(Client *client);
extern MODVAR void (*sasl_failed)(Client *client);
extern MODVAR int (*decode_authenticate_plain)(const char *param, char **authorization_id, char **authentication_id, char **passwd);
/* /Efuncs */
/* TLS functions */
@ -987,6 +991,9 @@ extern void ban_act_set_reputation_default_handler(Client *client, BanAction *ac
extern const char *get_central_api_key_default_handler(void);
extern int central_spamreport_default_handler(Client *target, Client *by);
extern int central_spamreport_enabled_default_handler(void);
extern void sasl_succeeded_default_handler(Client *client);
extern void sasl_failed_default_handler(Client *client);
extern int decode_authenticate_plain_default_handler(const char *param, char **authorization_id, char **authentication_id, char **passwd);
/* End of default handlers for efunctions */
extern MODVAR MOTDFile opermotd, svsmotd, motd, botmotd, smotd, rules;
@ -1300,6 +1307,8 @@ extern int conf_match_block(ConfigFile *conf, ConfigEntry *ce, SecurityGroup **b
extern int test_extended_list(Extban *extban, ConfigEntry *cep, int *errors);
extern int test_set_security_group(ConfigFile *conf, ConfigEntry *ce);
extern int config_set_security_group(ConfigFile *conf, ConfigEntry *ce);
extern int user_matches_extended_server_ban(Client *client, const char *name, const char *value);
extern int user_matches_extended_list(Client *client, NameValuePrioList *e);
/* securitygroup.c end */
/* src/unrealdb.c start */
extern UnrealDB *unrealdb_open(const char *filename, UnrealDBMode mode, char *secret_block);

View file

@ -1304,6 +1304,10 @@ extern APICallback *APICallbackAdd(Module *module, APICallback *mreq);
#define HOOKTYPE_WATCH_DEL 122
/** See hooktype_monitor_notification */
#define HOOKTYPE_MONITOR_NOTIFICATION 123
/** See hooktype_sasl_authenticate */
#define HOOKTYPE_SASL_AUTHENTICATE 124
/** See hooktype_sasl_mechs */
#define HOOKTYPE_SASL_MECHS 125
/** Used by third/centralblocklist; defined to avoid conflicts with pissnet-specific hook */
#define HOOKTYPE_GET_CENTRAL_API_KEY 198
@ -2422,6 +2426,20 @@ int hooktype_watch_del(char *nick, Client *client, int flags);
*/
int hooktype_monitor_notification(Client *watcher, Client *client, int online);
/** Called when an AUTHENTICATE command is sent by the client, for SASL authentication.
* This can be used by authentication modules.
* @param client The client (user)
* @param first Set to 1 if this is the first AUTHENTICATE, set to 0 if it is a continuation.
* @param param The AUTHENTICATE parameter (max 400 chars)
* @return The return value is ignored (use return 0)
*/
int hooktype_sasl_authenticate(Client *client, int first, const char *param);
/** Called for showing SASL mechanisms eg in sasl=xxx via "CAP LS 302"
* @param client The client
* @return The saslmechlist
*/
const char *hooktype_sasl_mechs(Client *client);
/** @} */
#ifdef GCC_TYPECHECKING
@ -2548,7 +2566,9 @@ _UNREAL_ERROR(_hook_error_incompatible, "Incompatible hook function. Check argum
((hooktype == HOOKTYPE_CONFIG_LISTENER) && !ValidateHook(hooktype_config_listener, func)) || \
((hooktype == HOOKTYPE_WATCH_ADD) && !ValidateHook(hooktype_watch_add, func)) || \
((hooktype == HOOKTYPE_WATCH_DEL) && !ValidateHook(hooktype_watch_del, func)) || \
((hooktype == HOOKTYPE_MONITOR_NOTIFICATION) && !ValidateHook(hooktype_monitor_notification, func))) \
((hooktype == HOOKTYPE_MONITOR_NOTIFICATION) && !ValidateHook(hooktype_monitor_notification, func)) || \
((hooktype == HOOKTYPE_SASL_AUTHENTICATE) && !ValidateHook(hooktype_sasl_authenticate, func)) || \
((hooktype == HOOKTYPE_SASL_MECHS) && !ValidateHook(hooktype_sasl_mechs, func))) \
_hook_error_incompatible();
#endif /* GCC_TYPECHECKING */
@ -2706,6 +2726,9 @@ enum EfunctionType {
EFUNC_GET_CENTRAL_API_KEY,
EFUNC_CENTRAL_SPAMREPORT,
EFUNC_CENTRAL_SPAMREPORT_ENABLED,
EFUNC_SASL_SUCCEEDED,
EFUNC_SASL_FAILED,
EFUNC_DECODE_AUTHENTICATE_PLAIN,
};
/* Module flags */

View file

@ -2130,14 +2130,14 @@ struct ConfigResource {
char *url; /**< URL, if it is an URL */
char *cache_file; /**< Set to filename of local cached copy, if it is available */
NameList *restrict_config; /**< If non-NULL: list of permitted config items */
int warn_only_on_fail; /**< Set to 1 if we should ignore failed download attempts (and only warn) */
};
/* When doing a HTTP request and it is requested to store the
* response to memory (rather than file), we enlarge the buffer
* in this chunk size.
* XXX: 128 bytes for testing chunks, should be 8k or so in production.
*/
#define URL_MEMORY_BACKED_CHUNK_SIZE 128
#define URL_MEMORY_BACKED_CHUNK_SIZE 8192
struct ConfigItem_blacklist_module {
ConfigItem_blacklist_module *prev, *next;

View file

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

View file

@ -174,6 +174,9 @@ void (*ban_act_set_reputation)(Client *client, BanAction *action);
const char *(*get_central_api_key)(void);
int (*central_spamreport)(Client *target, Client *by);
int (*central_spamreport_enabled)(void);
void (*sasl_succeeded)(Client *client);
void (*sasl_failed)(Client *client);
int (*decode_authenticate_plain)(const char *param, char **authorization_id, char **authentication_id, char **passwd);
Efunction *EfunctionAddMain(Module *module, EfunctionType eftype, int (*func)(), void (*vfunc)(), void *(*pvfunc)(), char *(*stringfunc)(), const char *(*conststringfunc)())
{
@ -493,4 +496,7 @@ void efunctions_init(void)
efunc_init_function(EFUNC_GET_CENTRAL_API_KEY, get_central_api_key, get_central_api_key_default_handler, 0);
efunc_init_function(EFUNC_CENTRAL_SPAMREPORT, central_spamreport, central_spamreport_default_handler, 0);
efunc_init_function(EFUNC_CENTRAL_SPAMREPORT_ENABLED, central_spamreport_enabled, central_spamreport_enabled_default_handler, 0);
efunc_init_function(EFUNC_SASL_SUCCEEDED, sasl_succeeded, sasl_succeeded_default_handler, 0);
efunc_init_function(EFUNC_SASL_FAILED, sasl_failed, sasl_failed_default_handler, 0);
efunc_init_function(EFUNC_DECODE_AUTHENTICATE_PLAIN, decode_authenticate_plain, decode_authenticate_plain_default_handler, 0);
}

View file

@ -1700,6 +1700,9 @@ void free_iConf(Configuration *i)
free_floodsettings(f);
}
i->floodsettings = NULL;
/* And zero out everything, too easy to make a mistake above. */
memset(i, 0, sizeof(Configuration));
}
/** Set default set { } block settings. Note that some of these settings
@ -2071,6 +2074,8 @@ int config_read_start(void)
return -1;
}
init_config_defines();
/* We set this to 1 because otherwise we may call rehash_internal()
* already from config_read_file() which is too soon (race).
*/
@ -2129,7 +2134,6 @@ int config_test(void)
config_setdefaultsettings(&tempiConf);
clicap_pre_rehash();
log_pre_rehash();
free_config_defines();
if (!config_loadmodules())
{
@ -11094,7 +11098,22 @@ void resource_download_complete(OutgoingWebRequest *request, OutgoingWebResponse
log_data_string("url", displayurl(request->url)),
log_data_string("error_message", response->errorbuf));
safe_strdup(rs->file, rs->cache_file);
} else {
} else
if (rs->warn_only_on_fail)
{
const char *cache_file;
unreal_log(ULOG_WARNING, "config", "DOWNLOAD_FAILED_WARN", NULL,
"$file:$line_number: Failed to download '$url': $error_message\n"
"Continuing anyway...",
log_data_string("file", rs->wce->ce->file->filename),
log_data_integer("line_number", rs->wce->ce->line_number),
log_data_string("url", displayurl(request->url)),
log_data_string("error_message", response->errorbuf));
cache_file = unreal_mkcache(request->url);
unreal_touch(cache_file, 1577880000); /* 2020-01-01 12:00 GMT */
safe_strdup(rs->file, cache_file);
} else
{
unreal_log(ULOG_ERROR, "config", "DOWNLOAD_FAILED_HARD", NULL,
"$file:$line_number: Failed to download '$url': $error_message",
log_data_string("file", rs->wce->ce->file->filename),
@ -11410,11 +11429,15 @@ int add_config_resource(const char *resource, int type, ConfigEntry *ce)
cache_file = unreal_mkcache(rs->url);
modtime = unreal_getfilemodtime(cache_file);
if (modtime > 0)
{
/* CACHED COPY IS AVAILABLE */
ConfigEntry *cep, *prev;
safe_strdup(rs->cache_file, cache_file); /* Cached copy is available */
/* Check if there is an "url-refresh" argument */
ConfigEntry *cep, *prev = NULL;
prev = NULL;
for (cep = ce->items; cep; cep = cep->next)
{
if (!strcmp(cep->name, "url-refresh"))
@ -11447,6 +11470,34 @@ int add_config_resource(const char *resource, int type, ConfigEntry *ce)
}
prev = cep;
}
} else {
/* CACHED COPY IS NOT AVAILABLE */
ConfigEntry *cep, *prev;
/* Check if there is an "url-fail" argument */
prev = NULL;
for (cep = ce->items; cep; cep = cep->next)
{
if (!strcmp(cep->name, "url-fail"))
{
if (cep->value)
{
if (!strcmp(cep->value, "warn"))
rs->warn_only_on_fail = 1;
}
/* Then remove the config item so it is not seen by the rest of unrealircd.
* Can't use DelListItem() here as ConfigEntry has no ->prev, only ->next.
*/
if (prev)
prev->next = cep->next; /* (skip over us) */
else
ce->items = cep->next; /* (new head) */
/* ..and free it */
config_entry_free(cep);
break; // MUST break now as we touched the linked list.
}
prev = cep;
}
}
download_file_async(rs->url, modtime, resource_download_complete, (void *)rs, DOWNLOAD_MAX_REDIRECTS);
}

View file

@ -417,8 +417,10 @@ void preprocessor_resolve_conditionals_all(PreprocessorPhase phase)
preprocessor_resolve_conditionals_ce(&cfptr->items, phase);
}
/** Frees the list of config_defines, so all @defines, and add the build-in ones */
void free_config_defines(void)
/** Frees the list of config_defines, so all @defines and then initialize the
* build-in ones.
*/
void init_config_defines(void)
{
safe_free_nvplist(config_defines);
add_nvplist(&config_defines, 0, "UNREALIRCD_VERSION", VERSIONONLY);

View file

@ -824,7 +824,6 @@ int InitUnrealIRCd(int argc, char *argv[])
default_class->sendq = DEFAULT_RECVQ;
default_class->name = "default";
AddListItem(default_class, conf_class);
free_config_defines();
if (config_read_start() < 0)
exit(-1);
while (!is_config_read_finished())

View file

@ -1909,6 +1909,20 @@ int central_spamreport_enabled_default_handler(void)
return 0;
}
void sasl_succeeded_default_handler(Client *client)
{
}
void sasl_failed_default_handler(Client *client)
{
}
int decode_authenticate_plain_default_handler(const char *param, char **authorization_id, char **authentication_id, char **passwd)
{
return 0;
}
/** my_timegm: mktime()-like function which will use GMT/UTC.
* Strangely enough there is no standard function for this.
* On some *NIX OS's timegm() may be available, sometimes only

View file

@ -1293,7 +1293,7 @@ int i;
if (!Callbacks[CALLBACKTYPE_CLOAK_KEY_CHECKSUM])
{
unreal_log(ULOG_ERROR, "config", "NO_CLOAKING_MODULE", NULL,
"No cloaking module loaded, you must load 1 of these modulese:\n"
"No cloaking module loaded, you must load 1 of these modules:\n"
"1) cloak_sha256 - if you are a new network starting with UnrealIRCd 6\n"
"2) cloak_md5 - the old one if migrating an existing network from UnrealIRCd 3.2/4/5\n"
"3) cloak_none - if you don't want to use cloaking at all\n"

View file

@ -421,8 +421,30 @@ int link_pre_localjoin_cb(Client *client, Channel *channel, const char *key)
b->banstr = banmask;
if (ban_check_mask(b))
{
safe_free(b);
return link_doforward(client, channel, banchan, LINKTYPE_BAN);
/* Forward ban matched, now check for +e */
Ban *ex = NULL;
for (ex = channel->exlist; ex; ex = ex->next)
{
b->banstr = ex->banstr;
if (ban_check_mask(b))
{
/* except matched, break inner loop */
break;
}
}
if (ex == NULL)
{
/* A ~forward ban matched, go for it.. */
safe_free(b);
return link_doforward(client, channel, banchan, LINKTYPE_BAN);
} else {
/* Break the outer loop as well: the user is exempt,
* so it makes no sense to check other bans anymore.
* no "safe_free(b);" here because that is taken
* care of further down.
*/
break;
}
}
}
@ -446,7 +468,7 @@ int link_pre_localjoin_cb(Client *client, Channel *channel, const char *key)
return link_doforward(client, channel, linked, LINKTYPE_SECURE);
// Registered/identified users only
if (has_channel_mode(channel, 'R') && !IsRegNick(client))
if (has_channel_mode(channel, 'R') && !IsLoggedIn(client))
return link_doforward(client, channel, linked, LINKTYPE_REG);
// For a couple of conditions we can use the return value from can_join() =]

View file

@ -125,13 +125,24 @@ static int crule__not(crule_context *, int, void **);
static int crule_online_time(crule_context *, int, void **);
static int crule_reputation(crule_context *, int, void **);
static int crule_tag(crule_context *, int, void **);
static int crule_inchannel(crule_context *, int, void **);
static int crule_in_channel(crule_context *, int, void **);
static int crule_destination(crule_context *, int, void **);
static int crule_cap_version(crule_context *, int, void **);
static int crule_cap_set(crule_context *, int, void **);
static int crule_has_user_mode(crule_context *, int, void **);
static int crule_has_channel_mode(crule_context *, int, void **);
static int crule_away(crule_context *, int, void **);
static int crule_is_identified(crule_context *, int, void **);
static int crule_is_webirc(crule_context *, int, void **);
static int crule_is_websocket(crule_context *, int, void **);
static int crule_tls(crule_context *, int, void **);
static int crule_in_security_group(crule_context *, int, void **);
static int crule_match_mask(crule_context *, int, void **);
static int crule_match_ip(crule_context *, int, void **);
static int crule_match_account(crule_context *, int, void **);
static int crule_match_country(crule_context *, int, void **);
static int crule_match_certfp(crule_context *, int, void **);
static int crule_match_realname(crule_context *, int, void **);
/* parsing function prototypes - local! */
static int crule_gettoken(crule_token *next_tokp, const char **str);
@ -169,7 +180,8 @@ struct crule_funclistent crule_funclist[] = {
{"online_time", 0, crule_online_time},
{"reputation", 0, crule_reputation},
{"tag", 1, crule_tag},
{"inchannel", 1, crule_inchannel},
{"inchannel", 1, crule_in_channel}, // old name, keep it around for now..
{"in_channel", 1, crule_in_channel}, // new name (6.1.6+)
{"destination", 1, crule_destination},
{"cap_version", 0, crule_cap_version},
{"cap_set", 1, crule_cap_set},
@ -179,6 +191,17 @@ struct crule_funclistent crule_funclist[] = {
{"has_user_mode", 1, crule_has_user_mode},
{"has_channel_mode", 1, crule_has_channel_mode},
{"is_away", 0, crule_away},
{"is_identified", 0, crule_is_identified},
{"is_tls", 0, crule_tls},
{"is_webirc", 0, crule_is_webirc},
{"is_websocket", 0, crule_is_websocket},
{"in_security_group", 1, crule_in_security_group},
{"match_mask", 1, crule_match_mask},
{"match_ip", 1, crule_match_ip},
{"match_account", 1, crule_match_account},
{"match_country", 1, crule_match_country},
{"match_certfp", 1, crule_match_certfp},
{"match_realname", 1, crule_match_realname},
{"", 0, NULL} /* this must be here to mark end of list */
};
@ -216,6 +239,38 @@ static int crule_away(crule_context *context, int numargs, void *crulearg[])
return (!BadPtr(context->client->user->away)) ? 1 : 0;
}
static int crule_is_identified(crule_context *context, int numargs, void *crulearg[])
{
if (!context || !context->client)
return 0;
return (IsLoggedIn(context->client)) ? 1 : 0;
}
static int crule_is_websocket(crule_context *context, int numargs, void *crulearg[])
{
if (!context || !context->client)
return 0;
return (moddata_client_get(context->client, "websocket")) ? 1 : 0;
}
static int crule_is_webirc(crule_context *context, int numargs, void *crulearg[])
{
if (!context || !context->client)
return 0;
return (moddata_client_get(context->client, "webirc")) ? 1 : 0;
}
static int crule_tls(crule_context *context, int numargs, void *crulearg[])
{
if (!context || !context->client)
return 0;
return (IsSecure(context->client) || IsSecureConnect(context->client)) ? 1 : 0;
}
static int crule_has_user_mode(crule_context *context, int numargs, void *crulearg[])
{
const char *modes = (char *)crulearg[0];
@ -339,7 +394,7 @@ static int crule_tag(crule_context *context, int numargs, void *crulearg[])
return 0;
}
static int crule_inchannel(crule_context *context, int numargs, void *crulearg[])
static int crule_in_channel(crule_context *context, int numargs, void *crulearg[])
{
Membership *lp;
const char *channelname = (char *)crulearg[0];
@ -404,6 +459,85 @@ static int crule_cap_set(crule_context *context, int numargs, void *crulearg[])
return 0;
}
static int crule_in_security_group(crule_context *context, int numargs, void *crulearg[])
{
const char *arg = (char *)crulearg[0];
if (!context || !context->client)
return 0;
if (user_allowed_by_security_group_name(context->client, arg))
return 1;
return 0;
}
static int crule_match_mask(crule_context *context, int numargs, void *crulearg[])
{
const char *arg = (char *)crulearg[0];
if (!context || !context->client)
return 0;
if (match_user(arg, context->client, MATCH_CHECK_REAL_HOST|MATCH_CHECK_IP|MATCH_CHECK_EXTENDED))
return 1;
return 0;
}
static int crule_match_ip(crule_context *context, int numargs, void *crulearg[])
{
const char *arg = (char *)crulearg[0];
if (!context || !context->client)
return 0;
if (match_user(arg, context->client, MATCH_CHECK_IP|MATCH_MASK_IS_HOST))
return 1;
return 0;
}
static int crule_match_account(crule_context *context, int numargs, void *crulearg[])
{
const char *arg = (char *)crulearg[0];
if (context && context->client && user_matches_extended_server_ban(context->client, "account", arg))
return 1;
return 0;
}
static int crule_match_country(crule_context *context, int numargs, void *crulearg[])
{
const char *arg = (char *)crulearg[0];
if (context && context->client && user_matches_extended_server_ban(context->client, "country", arg))
return 1;
return 0;
}
static int crule_match_certfp(crule_context *context, int numargs, void *crulearg[])
{
const char *arg = (char *)crulearg[0];
if (context && context->client && user_matches_extended_server_ban(context->client, "certfp", arg))
return 1;
return 0;
}
static int crule_match_realname(crule_context *context, int numargs, void *crulearg[])
{
const char *arg = (char *)crulearg[0];
if (context && context->client && match_simple(arg, context->client->info))
return 1;
return 0;
}
/** Evaluate a connection rule.
* @param[in] rule Rule to evalute.
* @return Non-zero if the rule allows the connection, zero otherwise.

View file

@ -88,6 +88,65 @@ int sasl_account_login(Client *client, MessageTag *mtags)
return 0;
}
void _sasl_succeeded(Client *client)
{
client->local->sasl_sent_time = 0;
client->local->sasl_complete++;
RunHookReturn(HOOKTYPE_SASL_RESULT, !=0, client, 1);
sendnumeric(client, RPL_SASLSUCCESS);
}
void _sasl_failed(Client *client)
{
client->local->sasl_sent_time = 0;
add_fake_lag(client, 7000); /* bump fakelag due to failed authentication attempt */
RunHookReturn(HOOKTYPE_SASL_RESULT, !=0, client, 0);
sendnumeric(client, ERR_SASLFAIL);
}
int _decode_authenticate_plain(const char *param, char **authorization_id, char **authentication_id, char **passwd)
{
static char authorization_id_buffer[256];
static char authentication_id_buffer[256];
static char passwd_buffer[256];
char decoded[512];
int n;
char *p, *p2;
/* First decode the thing */
n = b64_decode(param, decoded, 512);
if (n < 0)
return 0; // base64 decoding failed
p = memchr(decoded, '\0', n);
if (!p)
return 0; // missing first NUL
if (p - decoded > 255)
return 0; // oversized authorization_id
strlcpy(authorization_id_buffer, decoded, sizeof(authorization_id_buffer));
p++;
n -= (p - decoded);
if (n <= 0)
return 0; // no room left
p2 = memchr(p, '\0', n);
if (!p2)
return 0; // missing second NUL
if (p2 - p > 255)
return 0; // oversized authentication_id
strlcpy(authentication_id_buffer, p, sizeof(authentication_id_buffer));
p2++;
n -= (p2 - p);
if (n <= 0)
return 0; // no room left
strlcpy(passwd_buffer, p2, sizeof(passwd_buffer));
*authorization_id = authorization_id_buffer;
*authentication_id = authentication_id_buffer;
*passwd = passwd_buffer;
return 1;
}
/*
* SASL message
@ -129,19 +188,9 @@ CMD_FUNC(cmd_sasl)
{
*target->local->sasl_agent = '\0';
if (*parv[4] == 'F')
{
target->local->sasl_sent_time = 0;
add_fake_lag(target, 7000); /* bump fakelag due to failed authentication attempt */
RunHookReturn(HOOKTYPE_SASL_RESULT, !=0, target, 0);
sendnumeric(target, ERR_SASLFAIL);
}
sasl_failed(target);
else if (*parv[4] == 'S')
{
target->local->sasl_sent_time = 0;
target->local->sasl_complete++;
RunHookReturn(HOOKTYPE_SASL_RESULT, !=0, target, 1);
sendnumeric(target, RPL_SASLSUCCESS);
}
sasl_succeeded(target);
}
else if (*parv[3] == 'M')
sendnumeric(target, RPL_SASLMECHS, parv[4]);
@ -185,27 +234,40 @@ CMD_FUNC(cmd_authenticate)
if (*client->local->sasl_agent)
agent_p = find_client(client->local->sasl_agent, NULL);
client->local->sasl_out++;
client->local->sasl_sent_time = TStime();
if (agent_p == NULL)
{
char *addr = BadPtr(client->ip) ? "0" : client->ip;
const char *certfp = moddata_client_get(client, "certfp");
sendto_server(NULL, 0, 0, NULL, ":%s SASL %s %s H %s %s",
me.name, SASL_SERVER, client->id, addr, addr);
if (Hooks[HOOKTYPE_SASL_AUTHENTICATE] && (find_client(SASL_SERVER, NULL) == &me))
{
/* We are the SASL server (some module handling auth) */
RunHook(HOOKTYPE_SASL_AUTHENTICATE, client, 1, parv[1]);
} else {
sendto_server(NULL, 0, 0, NULL, ":%s SASL %s %s H %s %s",
me.name, SASL_SERVER, client->id, addr, addr);
if (certfp)
sendto_server(NULL, 0, 0, NULL, ":%s SASL %s %s S %s %s",
me.name, SASL_SERVER, client->id, parv[1], certfp);
else
sendto_server(NULL, 0, 0, NULL, ":%s SASL %s %s S %s",
me.name, SASL_SERVER, client->id, parv[1]);
if (certfp)
sendto_server(NULL, 0, 0, NULL, ":%s SASL %s %s S %s %s",
me.name, SASL_SERVER, client->id, parv[1], certfp);
else
sendto_server(NULL, 0, 0, NULL, ":%s SASL %s %s S %s",
me.name, SASL_SERVER, client->id, parv[1]);
}
} else
{
if (agent_p == &me)
{
/* We are the SASL server (some module handling auth) */
RunHook(HOOKTYPE_SASL_AUTHENTICATE, client, 0, parv[1]);
} else {
sendto_server(NULL, 0, 0, NULL, ":%s SASL %s %s C %s",
me.name, AGENT_SID(agent_p), client->id, parv[1]);
}
}
else
sendto_server(NULL, 0, 0, NULL, ":%s SASL %s %s C %s",
me.name, AGENT_SID(agent_p), client->id, parv[1]);
client->local->sasl_out++;
client->local->sasl_sent_time = TStime();
}
static int abort_sasl(Client *client)
@ -317,6 +379,15 @@ int sasl_server_synced(Client *client)
return 0;
}
MOD_TEST()
{
MARK_AS_OFFICIAL_MODULE(modinfo);
EfunctionAddVoid(modinfo->handle, EFUNC_SASL_SUCCEEDED, _sasl_succeeded);
EfunctionAddVoid(modinfo->handle, EFUNC_SASL_FAILED, _sasl_failed);
EfunctionAdd(modinfo->handle, EFUNC_DECODE_AUTHENTICATE_PLAIN, _decode_authenticate_plain);
return MOD_SUCCESS;
}
MOD_INIT()
{
ClientCapabilityInfo cap;
@ -386,6 +457,9 @@ const char *sasl_capability_parameter(Client *client)
{
Client *server;
if (Hooks[HOOKTYPE_SASL_MECHS])
return Hooks[HOOKTYPE_SASL_MECHS]->func.conststringfunc(client);
if (SASL_SERVER)
{
server = find_server(SASL_SERVER, NULL);

View file

@ -692,40 +692,44 @@ void set_security_group_defaults(void)
s->reputation_score = 25;
s->webirc = 0;
/* Default group: tls-and-known-users */
s = add_security_group("tls-and-known-users", 200);
s->identified = 1;
s->reputation_score = 25;
s->webirc = 0;
s->tls = 1;
/* Default group: tls-users */
s = add_security_group("tls-users", 300);
s->tls = 1;
}
/* Next function looks similar to _match_user_extended_server_ban in tkl.c,
* but the one in tkl.c works on a single string, has an extra 'is extended ban?'
* check and splits it into name/value etc.
*/
int user_matches_extended_server_ban(Client *client, const char *name, const char *value)
{
Extban *extban;
BanContext b;
extban = findmod_by_bantype_raw(name, strlen(name));
if (!extban ||
!(extban->options & EXTBOPT_TKL) ||
!(extban->is_banned_events & BANCHK_TKL))
{
return 0; /* extban not found or of incorrect type */
}
memset(&b, 0, sizeof(BanContext));
b.client = client;
b.banstr = value;
b.ban_check_types = BANCHK_TKL;
return extban->is_banned(&b);
}
int user_matches_extended_list(Client *client, NameValuePrioList *e)
{
Extban *extban;
BanContext b;
for (; e; e = e->next)
{
extban = findmod_by_bantype_raw(e->name, strlen(e->name));
if (!extban ||
!(extban->options & EXTBOPT_TKL) ||
!(extban->is_banned_events & BANCHK_TKL))
{
continue; /* extban not found or of incorrect type */
}
memset(&b, 0, sizeof(BanContext));
b.client = client;
b.banstr = e->value;
b.ban_check_types = BANCHK_TKL;
if (extban->is_banned(&b))
if (user_matches_extended_server_ban(client, e->name, e->value))
return 1;
}
return 0;
}
@ -872,7 +876,22 @@ int user_allowed_by_security_group(Client *client, SecurityGroup *s)
if ((s->connect_time < 0) && (connect_time < 0 - s->connect_time))
goto user_allowed;
}
if (s->tls && (IsSecureConnect(client) || (MyConnect(client) && IsSecure(client))))
/* The following check for 'tls' means:
* - If the user has user mode +z
* - Or, if the user is local but NOT a user, e.g. the user is in
* pre-connect-stage, then check if the underlying connection
* is using SSL/TLS.
* The reason for this is that:
* - We want this security group / match to work in both pre-connect
* and post-connect stage.
* - In post-connect stage we should only check for +z.
* This because it may be a situation of: user--proxy--us where
* the proxy--us connection is SSL/TLS so IsSecure() returns true
* but the user--proxy connection is not on SSL/TLS. We deal with
* that situation elsewhere by stripping the +z in such a case
* and we should behave the same way here, seeing it as non-TLS.
*/
if (s->tls && (IsSecureConnect(client) || (MyConnect(client) && !IsUser(client) && IsSecure(client))))
goto user_allowed;
if (s->mask && unreal_mask_match(client, s->mask))
goto user_allowed;

View file

@ -556,7 +556,7 @@ CMD_FUNC(cmd_rehash)
if (x != HUNTED_ISME)
return; /* Now forwarded or server didnt exist */
if (!MyConnect(client))
if (!MyUser(client))
{
#ifndef REMOTE_REHASH
sendnumeric(client, ERR_NOPRIVILEGES);
@ -577,7 +577,18 @@ CMD_FUNC(cmd_rehash)
/* Ok this is in an 'else' because it should be only executed for local clients,
* but it's totally unrelated to the above ;).
*/
if (parv[1] && match_simple("-glob*", parv[1]))
if (parv[1] && !strcasecmp(parv[1], "-all"))
{
sendnumeric(client, ERR_CANNOTDOCOMMAND, "REHASH",
"The command 'REHASH -all' does not exist. "
"Did you mean just 'REHASH'? "
"Or did you mean 'REHASH -global' which rehashes all IRC servers on the network?");
/* In a future version we may make 'REHASH -all' to mean 'REHASH -global', but not yet.. */
return;
}
if (parv[1] &&
(match_simple("-glob*", parv[1])
/* || (MyUser(client) && !strcasecmp(parv[1], "-all"))*/ ))
{
/* /REHASH -global [options] */
Client *acptr;
@ -599,7 +610,7 @@ CMD_FUNC(cmd_rehash)
sendto_one(acptr, NULL, ":%s REHASH %s %s",
client->name,
acptr->name,
parv[1] ? parv[1] : "-all");
parv[1] ? parv[1] : "");
}
/* Don't return, continue, because we need to REHASH ourselves as well. */
}

View file

@ -468,7 +468,6 @@ int b64_encode(unsigned char const *src, size_t srclength, char *target, size_t
/** Base64 decode a string.
* @param src The data to decode (input)
* @param srclength The length of the data to decode (input length)
* @param target The output buffer to use (output)
* @param targetsize The length of the output buffer to use (maximum output length)
* @returns length of the targetsize, or -1 in case of error.
@ -1169,6 +1168,17 @@ time_t unreal_getfilemodtime(const char *filename)
#endif
}
/** Touch a file (create if needed) and set timestamp. */
int unreal_touch(const char *filename, time_t mtime)
{
FILE *fd = fopen(filename, "a");
if (!fd)
return 0;
fclose(fd);
unreal_setfilemodtime(filename, mtime);
return 1;
}
#ifndef AF_INET6
#define AF_INET6 AF_MAX+1 /* just to let this compile */
#endif

View file

@ -7,7 +7,7 @@ echo "Extracting src/version.c..."
if [ -d ../.git ]; then
SUFFIX="-$(git rev-parse --short HEAD)"
fi
id="6.1.5$SUFFIX"
id="6.1.6-git$SUFFIX"
echo "$id"
if test -r version.c

View file

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

View file

@ -6,7 +6,7 @@
[Setup]
AppName=PissIRCd 6
AppVerName=PissIRCd 6.1.5
AppVerName=PissIRCd 6.1.6-git
AppPublisher=PissIRCd Team
AppPublisherURL=https://piss.network
AppSupportURL=https://wiki.letspiss.net

View file

@ -3,7 +3,7 @@
<assemblyIdentity
processorArchitecture="amd64"
name="UnrealIRCd.UnrealIRCd.6"
version="6.1.5.0"
version="6.1.6.0"
type="win32"
/>
<description>UnrealIRCd - Control utility</description>