mirror of
https://github.com/pissnet/pissircd.git
synced 2025-08-11 12:41:37 +01:00
Merge remote-tracking branch 'upstream/unreal60_dev' into piss60
This commit is contained in:
commit
a6bc1c9a9b
27 changed files with 563 additions and 116 deletions
2
.github/FUNDING.yml
vendored
Normal file
2
.github/FUNDING.yml
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
github: [syzop]
|
||||
patreon: UnrealIRCd
|
44
configure
vendored
44
configure
vendored
|
@ -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\\"
|
||||
|
||||
|
|
10
configure.ac
10
configure.ac
|
@ -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
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
25
include/h.h
25
include/h.h
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
57
src/conf.c
57
src/conf.c
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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())
|
||||
|
|
14
src/misc.c
14
src/misc.c
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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() =]
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
17
src/serv.c
17
src/serv.c
|
@ -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. */
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue