diff --git a/autoconf/m4/unreal.m4 b/autoconf/m4/unreal.m4
@@ -252,3 +252,23 @@ else
AC_MSG_RESULT([no])
fi
])
+
+AC_DEFUN([CHECK_SSL_CTX_SET_SECURITY_LEVEL],
+[
+AC_MSG_CHECKING([for SSL_CTX_set_security_level in SSL library])
+AC_LANG_PUSH(C)
+SAVE_LIBS="$LIBS"
+LIBS="$LIBS $CRYPTOLIB"
+AC_TRY_LINK([#include <openssl/ssl.h>],
+ [SSL_CTX *ctx = NULL; SSL_CTX_set_security_level(ctx, 1);],
+ has_function=1,
+ has_function=0)
+LIBS="$SAVE_LIBS"
+AC_LANG_POP(C)
+if test $has_function = 1; then
+ AC_MSG_RESULT([yes])
+ AC_DEFINE([HAS_SSL_CTX_SET_SECURITY_LEVEL], [], [Define if ssl library has SSL_CTX_set_security_level])
+else
+ AC_MSG_RESULT([no])
+fi
+])
diff --git a/configure b/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for unrealircd 5.0.3.1.
+# Generated by GNU Autoconf 2.69 for unrealircd 5.0.4.
#
# Report bugs to <https://bugs.unrealircd.org/>.
#
@@ -580,8 +580,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='unrealircd'
PACKAGE_TARNAME='unrealircd'
-PACKAGE_VERSION='5.0.3.1'
-PACKAGE_STRING='unrealircd 5.0.3.1'
+PACKAGE_VERSION='5.0.4'
+PACKAGE_STRING='unrealircd 5.0.4'
PACKAGE_BUGREPORT='https://bugs.unrealircd.org/'
PACKAGE_URL='https://unrealircd.org/'
@@ -670,6 +670,8 @@ HARDEN_BINLDFLAGS
HARDEN_BINCFLAGS
HARDEN_LDFLAGS
HARDEN_CFLAGS
+GMAKE
+MAKER
OBJEXT
EXEEXT
ac_ct_CC
@@ -679,8 +681,6 @@ CFLAGS
CC
PKGCONFIG
GUNZIP
-GMAKE
-MAKER
INSTALL
OPENSSLPATH
TOUCH
@@ -1325,7 +1325,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 5.0.3.1 to adapt to many kinds of systems.
+\`configure' configures unrealircd 5.0.4 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1391,7 +1391,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of unrealircd 5.0.3.1:";;
+ short | recursive ) echo "Configuration of unrealircd 5.0.4:";;
esac
cat <<\_ACEOF
@@ -1544,7 +1544,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-unrealircd configure 5.0.3.1
+unrealircd configure 5.0.4
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1913,7 +1913,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 5.0.3.1, which was
+It was created by unrealircd $as_me 5.0.4, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -2321,7 +2321,7 @@ _ACEOF
# Minor version number (e.g.: Z in X.Y.Z)
-UNREAL_VERSION_MINOR="3"
+UNREAL_VERSION_MINOR="4"
cat >>confdefs.h <<_ACEOF
#define UNREAL_VERSION_MINOR $UNREAL_VERSION_MINOR
@@ -2331,7 +2331,7 @@ _ACEOF
# 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=".1"
+UNREAL_VERSION_SUFFIX=""
cat >>confdefs.h <<_ACEOF
#define UNREAL_VERSION_SUFFIX "$UNREAL_VERSION_SUFFIX"
@@ -2551,91 +2551,6 @@ $as_echo "no" >&6; }
fi
-# Extract the first word of "gmake", so it can be a program name with args.
-set dummy gmake; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_MAKER+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- if test -n "$MAKER"; then
- ac_cv_prog_MAKER="$MAKER" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_prog_MAKER="gmake"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
- test -z "$ac_cv_prog_MAKER" && ac_cv_prog_MAKER="make"
-fi
-fi
-MAKER=$ac_cv_prog_MAKER
-if test -n "$MAKER"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAKER" >&5
-$as_echo "$MAKER" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-# Extract the first word of "gmake", so it can be a program name with args.
-set dummy gmake; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_GMAKE+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- case $GMAKE in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_GMAKE="$GMAKE" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_path_GMAKE="$as_dir/$ac_word$ac_exec_ext"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
- ;;
-esac
-fi
-GMAKE=$ac_cv_path_GMAKE
-if test -n "$GMAKE"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GMAKE" >&5
-$as_echo "$GMAKE" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-
-if $MAKER --version | grep -q "GNU Make"; then :
- GNUMAKE="0"
-else
- as_fn_error $? "It seems your system does not have gmake installed. Please install gmake." "$LINENO" 5
-fi
-
# Extract the first word of "gunzip", so it can be a program name with args.
set dummy gunzip; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
@@ -3687,6 +3602,90 @@ if test "$ac_cv_prog_cc_c99" = "no"; then :
as_fn_error $? "No C99 compiler was found. Please install gcc or clang and other build tools. Eg, on Debian/Ubuntu you probably want to run the following as root: apt-get install build-essential " "$LINENO" 5
fi
+# Extract the first word of "gmake", so it can be a program name with args.
+set dummy gmake; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_MAKER+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$MAKER"; then
+ ac_cv_prog_MAKER="$MAKER" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_MAKER="gmake"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ test -z "$ac_cv_prog_MAKER" && ac_cv_prog_MAKER="make"
+fi
+fi
+MAKER=$ac_cv_prog_MAKER
+if test -n "$MAKER"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAKER" >&5
+$as_echo "$MAKER" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+# Extract the first word of "gmake", so it can be a program name with args.
+set dummy gmake; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_GMAKE+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $GMAKE in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_GMAKE="$GMAKE" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_GMAKE="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+GMAKE=$ac_cv_path_GMAKE
+if test -n "$GMAKE"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GMAKE" >&5
+$as_echo "$GMAKE" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+if $MAKER --version | grep -q "GNU Make"; then :
+ GNUMAKE="0"
+else
+ as_fn_error $? "It seems your system does not have make/gmake installed. If you are on Linux then install make, otherwise install gmake." "$LINENO" 5
+fi
+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for crypt in -ldescrypt" >&5
$as_echo_n "checking for crypt in -ldescrypt... " >&6; }
@@ -6384,6 +6383,53 @@ else
$as_echo "no" >&6; }
fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SSL_CTX_set_security_level in SSL library" >&5
+$as_echo_n "checking for SSL_CTX_set_security_level in SSL library... " >&6; }
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+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
+
+SAVE_LIBS="$LIBS"
+LIBS="$LIBS $CRYPTOLIB"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <openssl/ssl.h>
+int
+main ()
+{
+SSL_CTX *ctx = NULL; SSL_CTX_set_security_level(ctx, 1);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ has_function=1
+else
+ has_function=0
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS="$SAVE_LIBS"
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+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
+
+if test $has_function = 1; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAS_SSL_CTX_SET_SECURITY_LEVEL /**/" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
# Check whether --enable-dynamic-linking was given.
if test "${enable_dynamic_linking+set}" = set; then :
enableval=$enable_dynamic_linking; enable_dynamic_linking=$enableval
@@ -6948,6 +6994,11 @@ $as_echo "installing Argon2 library" >&6; }
$ac_cv_prog_MAKER install PREFIX=$cur_dir/extras/argon2 || exit 1
# We need to manually copy the libs to PRIVATELIBDIR because
# there is no way to tell make install in libargon2 to do so.
+# BUT FIRST, delete the old library so it becomes an unlink+create
+# operation rather than overwriting the existing file which would
+# lead to a crash of the currently running IRCd.
+rm -f "$PRIVATELIBDIR/"libargon2*
+# Now copy the new library files:
cp -av $cur_dir/extras/argon2/lib/* $PRIVATELIBDIR/
ARGON2_CFLAGS="-I$cur_dir/extras/argon2/include"
@@ -8249,7 +8300,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 5.0.3.1, which was
+This file was extended by unrealircd $as_me 5.0.4, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -8312,7 +8363,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-unrealircd config.status 5.0.3.1
+unrealircd config.status 5.0.4
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
diff --git a/configure.ac b/configure.ac
@@ -7,7 +7,7 @@ dnl src/windows/unrealinst.iss
dnl doc/Config.header
dnl src/version.c.SH
-AC_INIT([unrealircd], [5.0.3.1], [https://bugs.unrealircd.org/], [], [https://unrealircd.org/])
+AC_INIT([unrealircd], [5.0.4], [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=["0"]
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=["3"]
+UNREAL_VERSION_MINOR=["4"]
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=[".1"]
+UNREAL_VERSION_SUFFIX=[""]
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)
@@ -60,13 +60,6 @@ exit 1
])
AC_PATH_PROG(INSTALL,install)
-AC_CHECK_PROG(MAKER, gmake, gmake, make)
-AC_PATH_PROG(GMAKE,gmake)
-
-AS_IF([$MAKER --version | grep -q "GNU Make"],
- [GNUMAKE="0"],
- [AC_MSG_ERROR([It seems your system does not have gmake installed. Please install gmake.])])
-
AC_PATH_PROG(GUNZIP, gunzip)
AC_PATH_PROG(PKGCONFIG, pkg-config)
@@ -75,6 +68,13 @@ AC_PROG_CC_C99
AS_IF([test "$ac_cv_prog_cc_c99" = "no"],
[AC_MSG_ERROR([No C99 compiler was found. Please install gcc or clang and other build tools. Eg, on Debian/Ubuntu you probably want to run the following as root: apt-get install build-essential ])])
+dnl Check for make moved down, so the above compiler check takes precedence.
+AC_CHECK_PROG(MAKER, gmake, gmake, make)
+AC_PATH_PROG(GMAKE,gmake)
+AS_IF([$MAKER --version | grep -q "GNU Make"],
+ [GNUMAKE="0"],
+ [AC_MSG_ERROR([It seems your system does not have make/gmake installed. If you are on Linux then install make, otherwise install gmake.])])
+
dnl Checks for libraries.
AC_CHECK_LIB(descrypt, crypt,
[AC_DEFINE([HAVE_CRYPT], [], [Define if you have crypt])
@@ -497,6 +497,7 @@ AC_ARG_WITH(system-cares, [AS_HELP_STRING([--without-system-cares], [Use bundled
CHECK_SSL
CHECK_SSL_CTX_SET1_CURVES_LIST
CHECK_SSL_CTX_SET_MIN_PROTO_VERSION
+CHECK_SSL_CTX_SET_SECURITY_LEVEL
AC_ARG_ENABLE(dynamic-linking, [AS_HELP_STRING([--disable-dynamic-linking], [Make the IRCd statically link with shared objects rather than dynamically (noone knows if disabling dynamic linking actually does anything or not)])],
[enable_dynamic_linking=$enableval], [enable_dynamic_linking="yes"])
AS_IF([test $enable_dynamic_linking = "yes"],
@@ -603,6 +604,11 @@ AC_MSG_RESULT(installing Argon2 library)
$ac_cv_prog_MAKER install PREFIX=$cur_dir/extras/argon2 || exit 1
# We need to manually copy the libs to PRIVATELIBDIR because
# there is no way to tell make install in libargon2 to do so.
+# BUT FIRST, delete the old library so it becomes an unlink+create
+# operation rather than overwriting the existing file which would
+# lead to a crash of the currently running IRCd.
+rm -f "$PRIVATELIBDIR/"libargon2*
+# Now copy the new library files:
cp -av $cur_dir/extras/argon2/lib/* $PRIVATELIBDIR/
ARGON2_CFLAGS="-I$cur_dir/extras/argon2/include"
AC_SUBST(ARGON2_CFLAGS)
diff --git a/doc/Config.header b/doc/Config.header
@@ -7,11 +7,10 @@
\___/|_| |_|_| \___|\__,_|_|\___/\_| \_| \____/\__,_|
Configuration Program
- for UnrealIRCd 5.0.3.1
+ for UnrealIRCd 5.0.4
This program will help you to compile your IRC server, and ask you
questions regarding the compile-time settings of it during the process.
-regarding the setup of it, during the process.
A short installation guide is available online at:
https://www.unrealircd.org/docs/Installing_from_source
diff --git a/doc/RELEASE-NOTES.md b/doc/RELEASE-NOTES.md
@@ -1,5 +1,46 @@
-UnrealIRCd 5.0.3.1 Release Notes
-=================================
+UnrealIRCd 5.0.4 Release Notes
+===============================
+
+This new 5.0.4 version fixes quite a number of bugs. It contains only two small feature improvements.
+
+Fixes:
+* When placing a SHUN on an online user it was not always effective.
+* Channeldb was not properly restoring all channel modes, such as +P.
+* When upgrading UnrealIRCd it could sometimes crash the currently
+ running IRC server (rare), or trigger a crash report on
+ ```./unrealircd restart``` (quite common).
+* UnrealIRCd was giving up too easily on ident lookups.
+* Crash when unloading a module with moddata.
+* Crash if an authenticated server sends wrong information (rare).
+* Removing a TEMPSHUN did not work if the user was on another server.
+* SAJOIN to 0 (part all channels) resulted in a desync when used on remote users.
+* Forced nick change from services was not showing up if the user
+ was not in any channels.
+
+Enhancements:
+* New option [set::hide-idle-time::policy](https://www.unrealircd.org/docs/Set_block#set%3A%3Ahide-idle-time)
+ by which you can change usermode +I (hide idle time in WHOIS) from
+ oper-only to settable by users. More options will follow in a future
+ release.
+* In WHOIS you can now see if a user is currently (temp)shunned.
+ This only works for locally connected users for technical reasons,
+ so use ```/WHOIS Nick Nick``` to see it for remote users.
+
+Changes:
+* The oper notices and logging with regards to server linking have changed
+ a little. They are more consistent and log more now.
+* When an IRCOp tries to oper up from an insecure connection we will now
+ mention the https://www.unrealircd.org/docs/FAQ#oper-requires-tls page.
+ This message is customizable through
+ [set::plaintext-policy::oper-message](https://www.unrealircd.org/docs/Set_block#set::plaintext-policy).
+* The French HELPOP text was updated.
+
+Upgrading from UnrealIRCd 4?
+-----------------------------
+
+Are you upgrading from UnrealIRCd 4.x to UnrealIRCd 5?
+Then check out the *UnrealIRCd 5* release notes [further down](#unrealircd-5). At the
+very least, check out [Upgrading from 4.x](https://www.unrealircd.org/docs/Upgrading_from_4.x).
UnrealIRCd 5.0.3.1
-------------------
diff --git a/doc/conf/except.conf b/doc/conf/except.conf
@@ -33,3 +33,4 @@ except ban { mask *@2600:3c03::f03c:91ff:fe96:c1fa; } # bot.search.mibbit.com
# Netsplit
except ban { mask *@85.25.137.63; } # eagle.netsplit.de
+except ban { mask *@85.25.10.40; } # anaconda.netsplit.de
+\ No newline at end of file
diff --git a/doc/conf/ircd.motd b/doc/conf/ircd.motd
@@ -36,12 +36,9 @@
0,0 0║ ╚0,0 0║ 0,0 0╗ 0,0 0║ ╚0,0 0╔╝
0╚═╝ ╚════╝ ╚══════╝ ╚═╝ ╚════╝
+4─────────┤ 0THE WILD WILD WEST OF IRC4├─────────
+14• 7Do not disrupt the orderly operation of the network
+14• 7No distribution of child pornography
-4──────────────────┤ 0RULES 4├───────────────────
-
-14• 7Do not disrupt or compromise our security.
-14• 7No malicious abuse of network services.
-14• 7No distribution of child pornography.
-
-4──────────────────────────────────────────────
-\ No newline at end of file
+8,4 E N T E R T H E V O I D
+\ No newline at end of file
diff --git a/doc/conf/unrealircd.remote.conf b/doc/conf/unrealircd.remote.conf
@@ -1,185 +0,0 @@
-admin { ""; }
-
-alias botserv { type services; }
-alias bs { target botserv; type services; }
-alias chanserv { type services; }
-alias cs { target chanserv; type services; }
-alias hostserv { type services; }
-alias hs { target hostserv; type services; }
-alias nickserv { type services; }
-alias ns { target nickserv; type services; }
-alias operserv { type services; }
-alias os { target operserv; type services; }
-
-class clients { pingfreq 120; maxclients 100; sendq 1M; options { nofakelag; } }
-class servers { pingfreq 120; maxclients 10; sendq 1M; connfreq 30; }
-
-allow { ip *; class clients; maxperip 2; }
-
-listen { ip *; port 6667; options { clientsonly; } }
-listen { ip *; port 6697; options { clientsonly; tls; } }
-listen { ip *; port REDACTED; options { serversonly; tls; } }
-
-link irc.supernets.org {
- incoming { mask REDACTED; }
- outgoing {
- bind-ip *;
- hostname REDACTED;
- port REDACTED;
- options { tls; autoconnect; }
- }
- password "REDACTED" { spkifp; }
- class servers;
-}
-
-log "errors.log" { flags { errors; } maxsize 10K; }
-
-tld { mask *@*; motd remote.motd; rules remote.motd; options { remote; } }
-
-ulines { services.supernets.org; }
-
-blacklist dronebl {
- dns {
- name dnsbl.dronebl.org;
- type record;
- reply { 3; 5; 6; 7; 8; 9; 10; 11; 12; 13; 14; 15; 16; }
- }
- action gzline;
- ban-time 1d;
- reason "8,4 E N T E R T H E V O I D ";
-}
-
-blacklist efnetrbl {
- dns {
- name rbl.efnetrbl.org;
- type record;
- reply { 1; 4; 5; }
- }
- action gzline;
- ban-time 1d;
- reason "8,4 E N T E R T H E V O I D ";
-}
-
-blacklist torbl {
- dns {
- name torexit.dan.me.uk;
- type record;
- reply { 100; }
- }
- action gzline;
- ban-time 1d;
- reason "8,4 E N T E R T H E V O I D ";
-}
-
-webirc { mask 107.161.19.53; password "REDACTED"; } # KiwiIRC
-webirc { mask 107.161.19.109; password "REDACTED"; }
-webirc { mask 107.161.31.4; password "REDACTED"; }
-
-webirc { mask 207.192.75.252; password "REDACTED"; } # Mibbit
-webirc { mask 64.62.228.82; password "REDACTED"; }
-webirc { mask 78.129.202.38; password "REDACTED"; }
-webirc { mask 109.169.29.95 ; password "REDACTED"; }
-
-set {
- kline-address "banned@supernets.org";
- gline-address "banned@supernets.org";
- modes-on-connect "+ipTx";
- modes-on-oper "+HIq";
- snomask-on-oper "+bcFfkGsSo";
- modes-on-join "+ns";
- level-on-join "op";
- restrict-channelmodes "CnLpPs";
- restrict-commands {
- invite { connect-delay 3600; exempt-identified yes; }
- list { connect-delay 120; exempt-identified yes; }
- private-message { connect-delay 300; exempt-identified yes; }
- private-notice { connect-delay 3600; exempt-identified yes; }
- }
- auto-join "#superbowl";
- oper-auto-join "#help";
- static-quit "EMO-QUIT";
- static-part "EMO-PART";
- who-limit 100;
- nick-length 20;
- maxchannelsperuser 10;
- channel-command-prefix "`!@$.";
- options { hide-ulines; flat-map; identd-check; }
- network-name "SuperNETs";
- default-server "irc.supernets.org";
- services-server "services.supernets.org";
- sasl-server "services.supernets.org";
- help-channel "#help";
- cloak-method ip;
- cloak-keys {
- "REDACTED";
- "REDACTED";
- "REDACTED";
- }
- hiddenhost-prefix "SUPER";
- plaintext-policy {
- user warn;
- oper deny;
- server deny;
- user-message "4WARNING: You are not using a secure connection with SSL/TLS";
- oper-message "Network operators must connect using SSL/TLS";
- }
- outdated-tls-policy {
- user warn;
- oper deny;
- server deny;
- user-message "4WARNING: You are using an outdated SSL/TLS protocol or cipher";
- oper-message "Network operators must connect using an up-to-date SSL/TLS protocol or cipher";
- }
- anti-flood {
- away-flood 3:300;
- connect-flood 3:300;
- invite-flood 3:300;
- join-flood 3:300;
- knock-flood 3:300;
- max-concurrent-conversations { users 5; new-user-every 60s; }
- nick-flood 3:300;
- unknown-flood-amount 2048;
- unknown-flood-bantime 1h;
- }
- default-bantime 1d;
- spamfilter {
- ban-time 1d;
- ban-reason "8,4 E N T E R T H E V O I D ";
- except "#anythinggoes";
- }
- max-targets-per-command { kick 1; part 1; privmsg 1; }
- hide-ban-reason yes;
- reject-message {
- gline "8,4 E N T E R T H E V O I D ";
- kline "8,4 E N T E R T H E V O I D ";
- password-mismatch "8,4 E N T E R T H E V O I D ";
- server-full "8,4 E N T E R T H E V O I D ";
- too-many-connections "8,4 E N T E R T H E V O I D ";
- unauthorized "8,4 E N T E R T H E V O I D ";
- }
- antimixedutf8 {
- score 10;
- ban-action block;
- ban-reason "8,4 E N T E R T H E V O I D ";
- ban-time 1h;
- }
- connthrottle {
- known-users { minimum-reputation-score 24; sasl-bypass yes; }
- new-users { local-throttle 20:60; global-throttle 30:60; }
- disabled-when { reputation-gathering 1w; start-delay 3m; }
- }
- history {
- channel {
- playback-on-join { lines 100; time 1d; }
- max-storage-per-channel { lines 100; time 1d; }
- }
- }
- manual-ban-target ip;
-}
-
-hideserver {
- disable-map yes;
- disable-links yes;
- map-deny-message "Denied";
- links-deny-message "Denied";
-}
-\ No newline at end of file
diff --git a/extras/doxygen/Doxyfile b/extras/doxygen/Doxyfile
@@ -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 = 5.0.3
+PROJECT_NUMBER = 5.0.4
# 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
diff --git a/extras/tests/tls/cipherscan_profiles/openssl-102-ubuntu16.txt b/extras/tests/tls/cipherscan_profiles/openssl-102-ubuntu16.txt
@@ -0,0 +1,27 @@
+Target: 127.0.0.1:5901
+
+prio ciphersuite protocols pfs curves
+1 ECDHE-ECDSA-AES256-GCM-SHA384 TLSv1.2 ECDH,P-521,521bits secp521r1,secp384r1
+2 ECDHE-ECDSA-AES128-GCM-SHA256 TLSv1.2 ECDH,P-521,521bits secp521r1,secp384r1
+3 ECDHE-ECDSA-AES256-SHA384 TLSv1.2 ECDH,P-521,521bits secp521r1,secp384r1
+4 ECDHE-ECDSA-AES256-SHA TLSv1,TLSv1.1,TLSv1.2 ECDH,P-521,521bits secp521r1,secp384r1
+5 ECDHE-ECDSA-AES128-SHA256 TLSv1.2 ECDH,P-521,521bits secp521r1,secp384r1
+6 ECDHE-ECDSA-AES128-SHA TLSv1,TLSv1.1,TLSv1.2 ECDH,P-521,521bits secp521r1,secp384r1
+
+Certificate: untrusted, 384 bits, ecdsa-with-SHA256 signature
+TLS ticket lifetime hint: None
+NPN protocols: None
+OCSP stapling: not supported
+Cipher ordering: server
+Curves ordering: server - fallback: no
+Server supports secure renegotiation
+Server supported compression methods: NONE
+TLS Tolerance: yes
+
+Intolerance to:
+ SSL 3.254 : absent
+ TLS 1.0 : absent
+ TLS 1.1 : absent
+ TLS 1.2 : absent
+ TLS 1.3 : absent
+ TLS 1.4 : absent
diff --git a/extras/tls.cnf b/extras/tls.cnf
@@ -18,7 +18,7 @@ stateOrProvinceName_default = New York
localityName = Locality Name (eg, city)
0.organizationName = Organization Name (eg, company)
-0.organizationName_default = SuperNETs
+0.organizationName_default = IRC geeks
organizationalUnitName = Organizational Unit Name (eg, section)
organizationalUnitName_default = IRCd
diff --git a/include/dynconf.h b/include/dynconf.h
@@ -55,6 +55,8 @@ typedef enum AllowedChannelChars { ALLOWED_CHANNELCHARS_ANY=1, ALLOWED_CHANNELCH
typedef enum BanTarget { BAN_TARGET_IP=1, BAN_TARGET_USERIP=2, BAN_TARGET_HOST=3, BAN_TARGET_USERHOST=4, BAN_TARGET_ACCOUNT=5, BAN_TARGET_CERTFP=6 } BanTarget;
+typedef enum HideIdleTimePolicy { HIDE_IDLE_TIME_NEVER=1, HIDE_IDLE_TIME_ALWAYS=2, HIDE_IDLE_TIME_USERMODE=3, HIDE_IDLE_TIME_OPER_USERMODE=4 } HideIdleTimePolicy;
+
/** The set { } block configuration */
typedef struct Configuration Configuration;
struct Configuration {
@@ -97,9 +99,9 @@ struct Configuration {
char *static_part;
TLSOptions *tls_options;
Policy plaintext_policy_user;
- char *plaintext_policy_user_message;
+ MultiLine *plaintext_policy_user_message;
Policy plaintext_policy_oper;
- char *plaintext_policy_oper_message;
+ MultiLine *plaintext_policy_oper_message;
Policy plaintext_policy_server;
Policy outdated_tls_policy_user;
char *outdated_tls_policy_user_message;
@@ -171,6 +173,7 @@ struct Configuration {
int part_instead_of_quit_on_comment_change;
BroadcastChannelMessagesOption broadcast_channel_messages;
AllowedChannelChars allowed_channelchars;
+ HideIdleTimePolicy hide_idle_time;
};
extern MODVAR Configuration iConf;
diff --git a/include/h.h b/include/h.h
@@ -911,6 +911,8 @@ extern void badword_config_free(ConfigItem_badword *ca);
extern char *badword_config_check_regex(char *s, int fastsupport, int check_broadness);
extern AllowedChannelChars allowed_channelchars_strtoval(char *str);
extern char *allowed_channelchars_valtostr(AllowedChannelChars v);
+extern HideIdleTimePolicy hideidletime_strtoval(char *str);
+extern char *hideidletime_valtostr(HideIdleTimePolicy v);
extern long ClientCapabilityBit(const char *token);
extern int is_handshake_finished(Client *client);
extern void SetCapability(Client *acptr, const char *token);
@@ -958,6 +960,7 @@ extern char *filename_add_suffix(const char *fname, const char *suffix);
extern int filename_has_suffix(const char *fname, const char *suffix);
extern void addmultiline(MultiLine **l, char *line);
extern void freemultiline(MultiLine *l);
+#define safe_free_multiline(x) do { if (x) freemultiline(x); x = NULL; } while(0)
extern void sendnotice_multiline(Client *client, MultiLine *m);
extern void unreal_del_quotes(char *i);
extern char *unreal_add_quotes(char *str);
@@ -965,3 +968,5 @@ extern int unreal_add_quotes_r(char *i, char *o, size_t len);
extern void user_account_login(MessageTag *recv_mtags, Client *client);
extern void link_generator(void);
extern void update_throttling_timer_settings(void);
+extern int hide_idle_time(Client *client, Client *target);
+extern void lost_server_link(Client *serv, FORMAT_STRING(const char *fmt), ...);
diff --git a/include/modules.h b/include/modules.h
@@ -650,6 +650,7 @@ struct Event {
vFP event; /**< Actual function to call */
void *data; /**< The data to pass in the function call */
struct timeval last_run; /**< Last time this event ran */
+ char deleted; /**< Set to 1 if this event is marked for deletion */
Module *owner; /**< To which module this event belongs */
};
@@ -676,7 +677,7 @@ extern MODVAR Callback *Callbacks[MAXCALLBACKS], *RCallbacks[MAXCALLBACKS];
extern MODVAR ClientCapability *clicaps;
extern Event *EventAdd(Module *module, char *name, vFP event, void *data, long every_msec, int count);
-extern Event *EventDel(Event *event);
+extern void EventDel(Event *event);
extern Event *EventMarkDel(Event *event);
extern Event *EventFind(char *name);
extern int EventMod(Event *event, EventInfo *mods);
diff --git a/include/setup.h.in b/include/setup.h.in
@@ -34,6 +34,9 @@
/* Define if ssl library has SSL_CTX_set_min_proto_version */
#undef HAS_SSL_CTX_SET_MIN_PROTO_VERSION
+/* Define if ssl library has SSL_CTX_set_security_level */
+#undef HAS_SSL_CTX_SET_SECURITY_LEVEL
+
/* Define if you have crypt */
#undef HAVE_CRYPT
diff --git a/include/windows/setup.h b/include/windows/setup.h
@@ -63,10 +63,10 @@
#define UNREAL_VERSION_MAJOR 0
/* Minor version number (e.g.: 1 for Unreal3.2.1) */
-#define UNREAL_VERSION_MINOR 3
+#define UNREAL_VERSION_MINOR 4
/* Version suffix such as a beta marker or release candidate marker. (e.g.:
-rcX for unrealircd-3.2.9-rcX) */
-#define UNREAL_VERSION_SUFFIX ".1"
+#define UNREAL_VERSION_SUFFIX ""
#endif
diff --git a/src/api-event.c b/src/api-event.c
@@ -87,40 +87,69 @@ Event *EventAdd(Module *module, char *name, vFP event, void *data, long every_ms
}
-Event *EventMarkDel(Event *event)
+/** Mark the Event for deletion.
+ * The actual deletion of the event happens later on
+ * (which is of no concern to the caller).
+ */
+void EventDel(Event *e)
{
- event->count = -1;
- return event;
-}
+ char buf[128];
-Event *EventDel(Event *event)
-{
- Event *p, *q;
- for (p = events; p; p = p->next)
+ /* Mark for deletion */
+ e->deleted = 1;
+
+ /* Replace the name so deleted events are clearly labeled */
+ if (e->name)
{
- if (p == event)
+ snprintf(buf, sizeof(buf), "deleted:%s", e->name);
+ safe_strdup(e->name, buf);
+ }
+
+ /* Remove the event from the module, that is something we can safely do straight away */
+ if (e->owner)
+ {
+ ModuleObject *eventobjs;
+ for (eventobjs = e->owner->objects; eventobjs; eventobjs = eventobjs->next)
{
- q = p->next;
- safe_free(p->name);
- DelListItem(p, events);
- if (p->owner)
+ if (eventobjs->type == MOBJ_EVENT && eventobjs->object.event == e)
{
- ModuleObject *eventobjs;
- for (eventobjs = p->owner->objects; eventobjs; eventobjs = eventobjs->next)
- {
- if (eventobjs->type == MOBJ_EVENT && eventobjs->object.event == p)
- {
- DelListItem(eventobjs, p->owner->objects);
- safe_free(eventobjs);
- break;
- }
- }
+ DelListItem(eventobjs, e->owner->objects);
+ safe_free(eventobjs);
+ break;
}
- safe_free(p);
- return q;
}
+ e->owner = NULL;
+ }
+}
+
+/** Remove the event for real, used only via CleanupEvents(), not for end-users. */
+static void EventDelReal(Event *e)
+{
+ if (!e->deleted)
+ {
+ ircd_log(LOG_ERROR, "EventDelReal called while e->deleted is 0. This cannot happen. Event name: %s.", e->name);
+ abort();
+ }
+ if (e->owner)
+ {
+ ircd_log(LOG_ERROR, "EventDelReal called while e->owner is non-NULL. This cannot happen. Event name: %s.", e->name);
+ abort();
+ }
+ safe_free(e->name);
+ DelListItem(e, events);
+ safe_free(e);
+}
+
+/** Remove any events that were previously marked for deletion */
+static void CleanupEvents(void)
+{
+ Event *e, *e_next;
+ for (e = events; e; e = e_next)
+ {
+ e_next = e->next;
+ if (e->deleted)
+ EventDelReal(e);
}
- return NULL;
}
Event *EventFind(char *name)
@@ -171,11 +200,12 @@ int EventMod(Event *event, EventInfo *mods)
void DoEvents(void)
{
- Event *e, *e_next;
+ Event *e;
- for (e = events; e; e = e_next)
+ for (e = events; e; e = e->next)
{
- e_next = e->next;
+ if (e->deleted)
+ continue;
if (e->count == -1)
{
EventDel(e);
@@ -195,6 +225,8 @@ void DoEvents(void)
}
}
}
+
+ CleanupEvents();
}
void SetupEvents(void)
diff --git a/src/api-usermode.c b/src/api-usermode.c
@@ -61,6 +61,9 @@ long SNO_OPER = 0L;
long AllUmodes; /* All umodes */
long SendUmodes; /* All umodes which are sent to other servers (global umodes) */
+/* Forward declarations */
+int umode_hidle_allow(Client *client, int what);
+
void umode_init(void)
{
long val = 1;
@@ -93,7 +96,7 @@ void umode_init(void)
UmodeAdd(NULL, 'd', UMODE_GLOBAL, 0, umode_allow_all, &UMODE_DEAF);
UmodeAdd(NULL, 'H', UMODE_GLOBAL, 1, umode_allow_opers, &UMODE_HIDEOPER);
UmodeAdd(NULL, 't', UMODE_GLOBAL, 0, umode_allow_unset, &UMODE_SETHOST);
- UmodeAdd(NULL, 'I', UMODE_GLOBAL, 1, umode_allow_opers, &UMODE_HIDLE);
+ UmodeAdd(NULL, 'I', UMODE_GLOBAL, 0, umode_hidle_allow, &UMODE_HIDLE);
SnomaskAdd(NULL, 'k', umode_allow_opers, &SNO_KILLS);
SnomaskAdd(NULL, 'c', umode_allow_opers, &SNO_CLIENT);
SnomaskAdd(NULL, 'f', umode_allow_opers, &SNO_FLOOD);
@@ -378,6 +381,17 @@ int umode_allow_opers(Client *client, int what)
return 1;
}
+int umode_hidle_allow(Client *client, int what)
+{
+ if (!MyUser(client))
+ return 1;
+ if (iConf.hide_idle_time == HIDE_IDLE_TIME_OPER_USERMODE)
+ return IsOper(client) ? 1 : 0;
+ if (iConf.hide_idle_time == HIDE_IDLE_TIME_USERMODE)
+ return 1;
+ return 0; /* if set::hide-idle-time is 'never' or 'always' then +I makes no sense */
+}
+
void unload_all_unused_umodes(void)
{
long removed_umode = 0;
@@ -469,6 +483,10 @@ int i;
if (Usermode_Table[i].unset_on_deoper)
client->umodes &= ~Usermode_Table[i].mode;
}
+
+ /* Bit of a hack, since this is a dynamic permission umode */
+ if (iConf.hide_idle_time == HIDE_IDLE_TIME_OPER_USERMODE)
+ client->umodes &= ~UMODE_HIDLE;
}
void remove_oper_privileges(Client *client, int broadcast_mode_change)
diff --git a/src/conf.c b/src/conf.c
@@ -787,6 +787,36 @@ char *ban_target_valtostr(BanTarget v)
}
}
+HideIdleTimePolicy hideidletime_strtoval(char *str)
+{
+ if (!strcmp(str, "never"))
+ return HIDE_IDLE_TIME_NEVER;
+ else if (!strcmp(str, "always"))
+ return HIDE_IDLE_TIME_ALWAYS;
+ else if (!strcmp(str, "usermode"))
+ return HIDE_IDLE_TIME_USERMODE;
+ else if (!strcmp(str, "oper-usermode"))
+ return HIDE_IDLE_TIME_OPER_USERMODE;
+ return 0;
+}
+
+char *hideidletime_valtostr(HideIdleTimePolicy v)
+{
+ switch(v)
+ {
+ case HIDE_IDLE_TIME_NEVER:
+ return "never";
+ case HIDE_IDLE_TIME_ALWAYS:
+ return "always";
+ case HIDE_IDLE_TIME_USERMODE:
+ return "usermode";
+ case HIDE_IDLE_TIME_OPER_USERMODE:
+ return "oper-usermode";
+ default:
+ return "INVALID";
+ }
+}
+
ConfigFile *config_load(char *filename, char *displayname)
{
struct stat sb;
@@ -1586,8 +1616,8 @@ void free_iConf(Configuration *i)
free_tls_options(i->tls_options);
i->tls_options = NULL;
safe_free(i->tls_options);
- safe_free(i->plaintext_policy_user_message);
- safe_free(i->plaintext_policy_oper_message);
+ safe_free_multiline(i->plaintext_policy_user_message);
+ safe_free_multiline(i->plaintext_policy_oper_message);
safe_free(i->outdated_tls_policy_user_message);
safe_free(i->outdated_tls_policy_oper_message);
safe_free(i->restrict_usermodes);
@@ -1714,6 +1744,8 @@ void config_setdefaultsettings(Configuration *i)
i->automatic_ban_target = BAN_TARGET_IP;
i->manual_ban_target = BAN_TARGET_HOST;
+
+ i->hide_idle_time = HIDE_IDLE_TIME_OPER_USERMODE;
}
static void make_default_logblock(void)
@@ -1742,18 +1774,21 @@ void postconf_defaults(void)
{
/* The message depends on whether it's reject or warn.. */
if (iConf.plaintext_policy_user == POLICY_DENY)
- safe_strdup(iConf.plaintext_policy_user_message, "Insecure connection. Please reconnect using SSL/TLS.");
+ addmultiline(&iConf.plaintext_policy_user_message, "Insecure connection. Please reconnect using SSL/TLS.");
else if (iConf.plaintext_policy_user == POLICY_WARN)
- safe_strdup(iConf.plaintext_policy_user_message, "WARNING: Insecure connection. Please consider using SSL/TLS.");
+ addmultiline(&iConf.plaintext_policy_user_message, "WARNING: Insecure connection. Please consider using SSL/TLS.");
}
if (!iConf.plaintext_policy_oper_message)
{
/* The message depends on whether it's reject or warn.. */
if (iConf.plaintext_policy_oper == POLICY_DENY)
- safe_strdup(iConf.plaintext_policy_oper_message, "You need to use a secure connection (SSL/TLS) in order to /OPER.");
+ {
+ addmultiline(&iConf.plaintext_policy_oper_message, "You need to use a secure connection (SSL/TLS) in order to /OPER.");
+ addmultiline(&iConf.plaintext_policy_oper_message, "See https://www.unrealircd.org/docs/FAQ#oper-requires-tls");
+ }
else if (iConf.plaintext_policy_oper == POLICY_WARN)
- safe_strdup(iConf.plaintext_policy_oper_message, "WARNING: You /OPER'ed up from an insecure connection. Please consider using SSL/TLS.");
+ addmultiline(&iConf.plaintext_policy_oper_message, "WARNING: You /OPER'ed up from an insecure connection. Please consider using SSL/TLS.");
}
if (!iConf.outdated_tls_policy_user_message)
@@ -7674,9 +7709,9 @@ int _conf_set(ConfigFile *conf, ConfigEntry *ce)
else if (!strcmp(cepp->ce_varname, "server"))
tempiConf.plaintext_policy_server = policy_strtoval(cepp->ce_vardata);
else if (!strcmp(cepp->ce_varname, "user-message"))
- safe_strdup(tempiConf.plaintext_policy_user_message, cepp->ce_vardata);
+ addmultiline(&tempiConf.plaintext_policy_user_message, cepp->ce_vardata);
else if (!strcmp(cepp->ce_varname, "oper-message"))
- safe_strdup(tempiConf.plaintext_policy_oper_message, cepp->ce_vardata);
+ addmultiline(&tempiConf.plaintext_policy_oper_message, cepp->ce_vardata);
}
}
else if (!strcmp(cep->ce_varname, "outdated-tls-policy"))
@@ -7782,12 +7817,15 @@ int _conf_set(ConfigFile *conf, ConfigEntry *ce)
}
else if (!strcmp(cep->ce_varname, "allowed-channelchars"))
{
- if (!strcmp(cep->ce_vardata, "ascii"))
- tempiConf.allowed_channelchars = ALLOWED_CHANNELCHARS_ASCII;
- else if (!strcmp(cep->ce_vardata, "utf8"))
- tempiConf.allowed_channelchars = ALLOWED_CHANNELCHARS_UTF8;
- else if (!strcmp(cep->ce_vardata, "any"))
- tempiConf.allowed_channelchars = ALLOWED_CHANNELCHARS_ANY;
+ tempiConf.allowed_channelchars = allowed_channelchars_strtoval(cep->ce_vardata);
+ }
+ else if (!strcmp(cep->ce_varname, "hide-idle-time"))
+ {
+ for (cepp = cep->ce_entries; cepp; cepp = cepp->ce_next)
+ {
+ if (!strcmp(cepp->ce_varname, "policy"))
+ tempiConf.hide_idle_time = hideidletime_strtoval(cepp->ce_vardata);
+ }
}
else
{
@@ -8976,15 +9014,37 @@ int _test_set(ConfigFile *conf, ConfigEntry *ce)
else if (!strcmp(cep->ce_varname, "allowed-channelchars"))
{
CheckNull(cep);
- if (strcmp(cep->ce_vardata, "ascii") &&
- strcmp(cep->ce_vardata, "utf8") &&
- strcmp(cep->ce_vardata, "any"))
+ if (!allowed_channelchars_strtoval(cep->ce_vardata))
{
config_error("%s:%i: set::allowed-channelchars: value should be one of: 'ascii', 'utf8' or 'any'",
cep->ce_fileptr->cf_filename, cep->ce_varlinenum);
errors++;
}
}
+ else if (!strcmp(cep->ce_varname, "hide-idle-time"))
+ {
+ for (cepp = cep->ce_entries; cepp; cepp = cepp->ce_next)
+ {
+ CheckNull(cepp);
+ if (!strcmp(cepp->ce_varname, "policy"))
+ {
+ if (!hideidletime_strtoval(cepp->ce_vardata))
+ {
+ config_error("%s:%i: set::hide-idle-time::policy: value should be one of: 'never', 'always', 'usermode' or 'oper-usermode'",
+ cepp->ce_fileptr->cf_filename, cepp->ce_varlinenum);
+ errors++;
+ }
+ }
+ else
+ {
+ config_error_unknown(cepp->ce_fileptr->cf_filename,
+ cepp->ce_varlinenum, "set::hide-idle-time",
+ cepp->ce_varname);
+ errors++;
+ continue;
+ }
+ }
+ }
else
{
int used = 0;
diff --git a/src/dns.c b/src/dns.c
@@ -420,7 +420,7 @@ void unrealdns_cb_nametoip_link(void *arg, int status, int timeouts, struct host
switch ((n = connect_server(r->linkblock, r->client, he2)))
{
case 0:
- sendto_ops_and_log("Connecting to server %s[%s].", r->linkblock->servername, ip);
+ sendto_ops_and_log("Trying to activate link with server %s[%s]...", r->linkblock->servername, ip);
break;
case -1:
sendto_ops_and_log("Couldn't connect to server %s[%s].", r->linkblock->servername, ip);
diff --git a/src/ircd.c b/src/ircd.c
@@ -312,7 +312,7 @@ EVENT(try_connections)
break;
if (!deny && connect_server(aconf, NULL, NULL) == 0)
- sendto_realops("Connection to %s[%s] activated.",
+ sendto_ops_and_log("Trying to activate link with server %s[%s]...",
aconf->servername, aconf->outgoing.hostname);
}
@@ -393,7 +393,7 @@ EVENT(handshake_timeout)
if (client->serv && *client->serv->by)
{
/* If this is a handshake timeout to an outgoing server then notify ops & log it */
- sendto_ops_and_log("Connection handshake timeout while connecting to server '%s' (%s)",
+ sendto_ops_and_log("Connection handshake timeout while trying to link to server '%s' (%s)",
client->name, client->ip?client->ip:"<unknown ip>");
}
@@ -534,9 +534,6 @@ EVENT(check_deadsockets)
{
if (!IsDead(client))
abort(); /* impossible */
-#ifdef DEBUGMODE
- ircd_log(LOG_ERROR, "Closing deadsock2: %s", client->name);
-#endif
list_del(&client->client_node);
free_client(client);
}
diff --git a/src/modules/channeldb.c b/src/modules/channeldb.c
@@ -84,6 +84,12 @@ MOD_INIT()
setcfg();
+ HookAdd(modinfo->handle, HOOKTYPE_CONFIGRUN, 0, channeldb_configrun);
+ return MOD_SUCCESS;
+}
+
+MOD_LOAD()
+{
if (!channeldb_loaded)
{
/* If this is the first time that our module is loaded, then read the database. */
@@ -98,12 +104,6 @@ MOD_INIT()
}
channeldb_loaded = 1;
}
- HookAdd(modinfo->handle, HOOKTYPE_CONFIGRUN, 0, channeldb_configrun);
- return MOD_SUCCESS;
-}
-
-MOD_LOAD()
-{
EventAdd(modinfo->handle, "channeldb_write_channeldb", write_channeldb_evt, NULL, CHANNELDB_SAVE_EVERY*1000, 0);
if (ModuleGetError(modinfo->handle) != MODERR_NOERROR)
{
diff --git a/src/modules/connect.c b/src/modules/connect.c
@@ -137,7 +137,7 @@ CMD_FUNC(cmd_connect)
switch (retval = connect_server(aconf, client, NULL))
{
case 0:
- sendnotice(client, "*** Connecting to %s[%s].",
+ sendnotice(client, "*** Trying to activate link with server %s[%s]...",
aconf->servername, aconf->outgoing.hostname);
break;
case -1:
diff --git a/src/modules/ident_lookup.c b/src/modules/ident_lookup.c
@@ -63,8 +63,20 @@ static EVENT(check_ident_timeout)
list_for_each_entry_safe(client, next, &unknown_list, lclient_node)
{
- if (IsIdentLookup(client) && ((TStime() - client->local->firsttime) > IDENT_CONNECT_TIMEOUT))
- ident_lookup_failed(client);
+ if (IsIdentLookup(client))
+ {
+ if (IsIdentLookupSent(client))
+ {
+ /* set::ident::connect-timeout */
+ if ((TStime() - client->local->firsttime) > IDENT_CONNECT_TIMEOUT)
+ ident_lookup_failed(client);
+ } else
+ {
+ /* set::ident::read-timeout */
+ if ((TStime() - client->local->firsttime) > IDENT_READ_TIMEOUT)
+ ident_lookup_failed(client);
+ }
+ }
}
}
diff --git a/src/modules/join.c b/src/modules/join.c
@@ -441,7 +441,7 @@ void _do_join(Client *client, int parc, char *parv[])
new_message(client, NULL, &mtags);
- sendto_channel(channel, client, NULL, 0, 0, SEND_LOCAL, NULL,
+ sendto_channel(channel, client, NULL, 0, 0, SEND_LOCAL, mtags,
":%s PART %s :%s",
client->name, channel->chname, "Left all channels");
sendto_server(client, 0, 0, mtags, ":%s PART %s :Left all channels", client->name, channel->chname);
diff --git a/src/modules/nick.c b/src/modules/nick.c
@@ -1085,7 +1085,7 @@ int _register_user(Client *client, char *nick, char *username, char *umode, char
sendnumeric(client, RPL_SNOMASK, get_snomask_string_raw(user->snomask));
if (!IsSecure(client) && !IsLocalhost(client) && (iConf.plaintext_policy_user == POLICY_WARN))
- sendnotice(client, "%s", iConf.plaintext_policy_user_message);
+ sendnotice_multiline(client, iConf.plaintext_policy_user_message);
if (IsSecure(client) && (iConf.outdated_tls_policy_user == POLICY_WARN) && outdated_tls_client(client))
sendnotice(client, "%s", outdated_tls_client_build_string(iConf.outdated_tls_policy_user_message, client));
@@ -1300,7 +1300,7 @@ int AllowClient(Client *client, char *username)
if (!IsSecure(client) && !IsLocalhost(client) && (iConf.plaintext_policy_user == POLICY_DENY))
{
- exit_client(client, NULL, iConf.plaintext_policy_user_message);
+ exit_client(client, NULL, iConf.plaintext_policy_user_message->line);
return 0;
}
diff --git a/src/modules/oper.c b/src/modules/oper.c
@@ -114,7 +114,7 @@ CMD_FUNC(cmd_oper)
/* set::plaintext-policy::oper 'deny' */
if (!IsSecure(client) && !IsLocalhost(client) && (iConf.plaintext_policy_oper == POLICY_DENY))
{
- sendnotice(client, "%s", iConf.plaintext_policy_oper_message);
+ sendnotice_multiline(client, iConf.plaintext_policy_oper_message);
sendto_snomask_global
(SNO_OPER, "Failed OPER attempt by %s (%s@%s) [not using SSL/TLS]",
client->name, client->user->username, client->local->sockhost);
@@ -315,7 +315,7 @@ CMD_FUNC(cmd_oper)
/* set::plaintext-policy::oper 'warn' */
if (!IsSecure(client) && !IsLocalhost(client) && (iConf.plaintext_policy_oper == POLICY_WARN))
{
- sendnotice(client, "%s", iConf.plaintext_policy_oper_message);
+ sendnotice_multiline(client, iConf.plaintext_policy_oper_message);
sendto_snomask_global
(SNO_OPER, "OPER %s [%s] used an insecure (non-SSL/TLS) connection to /OPER.",
client->name, name);
diff --git a/src/modules/sajoin.c b/src/modules/sajoin.c
@@ -221,10 +221,10 @@ CMD_FUNC(cmd_sajoin)
channel = lp->channel;
new_message(target, NULL, &mtags);
- sendto_channel(channel, target, NULL, 0, 0, SEND_LOCAL, NULL,
+ sendto_channel(channel, target, NULL, 0, 0, SEND_LOCAL, mtags,
":%s PART %s :%s",
target->name, channel->chname, "Left all channels");
- sendto_server(client, 0, 0, mtags, ":%s PART %s :Left all channels", target->name, channel->chname);
+ sendto_server(NULL, 0, 0, mtags, ":%s PART %s :Left all channels", target->name, channel->chname);
if (MyConnect(target))
RunHook4(HOOKTYPE_LOCAL_PART, target, channel, mtags, "Left all channels");
free_message_tags(mtags);
@@ -275,5 +275,22 @@ CMD_FUNC(cmd_sajoin)
strlcat(jbuf, ",", sizeof jbuf);
strlcat(jbuf, name, sizeof jbuf);
}
+ if (did_anything)
+ {
+ if (!sjmode)
+ {
+ //sendnotice(target, "*** You were forced to join %s", jbuf);
+ sendto_umode_global(UMODE_OPER, "%s used SAJOIN to make %s join %s", client->name, target->name, jbuf);
+ ircd_log(LOG_SACMDS,"SAJOIN: %s used SAJOIN to make %s join %s",
+ client->name, target->name, jbuf);
+ }
+ else
+ {
+ //sendnotice(target, "*** You were forced to join %s with '%c'", jbuf, sjmode);
+ sendto_umode_global(UMODE_OPER, "%s used SAJOIN to make %s join %c%s", client->name, target->name, sjmode, jbuf);
+ ircd_log(LOG_SACMDS,"SAJOIN: %s used SAJOIN to make %s join %c%s",
+ client->name, target->name, sjmode, jbuf);
+ }
+ }
}
}
diff --git a/src/modules/sapart.c b/src/modules/sapart.c
@@ -159,6 +159,22 @@ CMD_FUNC(cmd_sapart)
parv[0] = target->name; // nick
parv[1] = parv[2]; // chan
parv[2] = comment ? commentx : NULL; // comment
+ if (comment)
+ {
+ //sendnotice(target, "*** You were forced to part %s (%s)", parv[1], commentx);
+ sendto_umode_global(UMODE_OPER, "%s used SAPART to make %s part %s (%s)",
+ client->name, target->name, parv[1], comment);
+ ircd_log(LOG_SACMDS,"SAPART: %s used SAPART to make %s part %s (%s)",
+ client->name, target->name, parv[1], comment);
+ }
+ else
+ {
+ //sendnotice(target, "*** You were forced to part %s", parv[1]);
+ sendto_umode_global(UMODE_OPER, "%s used SAPART to make %s part %s",
+ client->name, target->name, parv[1]);
+ ircd_log(LOG_SACMDS,"SAPART: %s used SAPART to make %s part %s",
+ client->name, target->name, parv[1]);
+ }
do_cmd(target, NULL, "PART", comment ? 3 : 2, parv);
/* target may be killed now due to the part reason @ spamfilter */
}
diff --git a/src/modules/server.c b/src/modules/server.c
@@ -547,6 +547,7 @@ CMD_FUNC(cmd_server)
sendto_umode_global(UMODE_OPER, "Directly linked server %s provided a hopcount of %d, while 1 was expected",
servername, hop);
exit_client(client, NULL, "Invalid SERVER message, hop count must be 1");
+ return;
}
client->hopcount = hop;
diff --git a/src/modules/svsmode.c b/src/modules/svsmode.c
@@ -407,6 +407,13 @@ void do_svsmode(Client *client, MessageTag *recv_mtags, int parc, char *parv[],
if (parv[3])
{
strlcpy(target->user->svid, parv[3], sizeof(target->user->svid));
+ if(MyConnect(target))
+ /* Notify user */
+ sendnumeric(target, RPL_LOGGEDIN,
+ BadPtr(target->name) ? "*" : target->name,
+ BadPtr(target->user->username) ? "*" : target->user->username,
+ BadPtr(target->user->realhost) ? "*" : target->user->realhost,
+ target->user->svid, target->user->svid);
user_account_login(recv_mtags, target);
}
else
diff --git a/src/modules/tkl.c b/src/modules/tkl.c
@@ -1028,8 +1028,8 @@ CMD_FUNC(cmd_tempshun)
}
if (!MyUser(target))
{
- sendto_one(target->direction, NULL, ":%s TEMPSHUN %s :%s",
- client->id, target->id, comment);
+ sendto_one(target, NULL, ":%s TEMPSHUN %c%s :%s",
+ client->id, remove ? '-' : '+', target->id, comment);
} else {
char buf[1024];
if (!remove)
@@ -1747,7 +1747,7 @@ CMD_FUNC(cmd_eline)
/** Helper function for cmd_spamfilter, explaining usage. */
void spamfilter_usage(Client *client)
{
- sendnotice(client, "Use: /spamfilter [add|del|remove|+|-] [-simple|-regex|-posix] [type] [action] [tkltime] [tklreason] [regex]");
+ sendnotice(client, "Use: /spamfilter [add|del|remove|+|-] [-simple|-regex] [type] [action] [tkltime] [tklreason] [regex]");
sendnotice(client, "See '/helpop ?spamfilter' for more information.");
sendnotice(client, "For an easy way to remove an existing spamfilter, use '/spamfilter del' without additional parameters");
}
@@ -1755,13 +1755,12 @@ void spamfilter_usage(Client *client)
/** Helper function for cmd_spamfilter, explaining usage has changed. */
void spamfilter_new_usage(Client *client, char *parv[])
{
- sendnotice(client, "Unknown match-type '%s'. Must be one of: -regex (new fast PCRE regexes), "
- "-posix (old unreal 3.2.x posix regexes) or "
+ sendnotice(client, "Unknown match-type '%s'. Must be one of: -regex (new fast PCRE regexes) or "
"-simple (simple text with ? and * wildcards)",
parv[2]);
if (*parv[2] != '-')
- sendnotice(client, "Using the old 3.2.x /SPAMFILTER syntax? Note the new -regex/-posix/-simple field!!");
+ sendnotice(client, "Using the old 3.2.x /SPAMFILTER syntax? Note the new -regex/-simple field!!");
spamfilter_usage(client);
}
@@ -4209,8 +4208,11 @@ CMD_FUNC(cmd_tkl_del)
RunHook2(HOOKTYPE_TKL_DEL, client, tkl);
if (type & TKL_GLOBAL)
+ {
+ /* This is a bit of a hack for #5629. Will consider real fix post-release. */
+ safe_strdup(tkl->set_by, removed_by);
tkl_broadcast_entry(0, client, client, tkl);
-
+ }
if (TKLIsBanException(tkl))
{
@@ -4252,7 +4254,7 @@ CMD_FUNC(cmd_tkl_del)
*
* [A] tkl reason field must be escaped by caller [eg: use unreal_encodespace()
* if cmd_tkl is called internally].
- * [B] match-type must be one of: regex, simple, posix.
+ * [B] match-type must be one of: regex, simple.
* [C] Could be a regex or a regular string with wildcards, depending on [B]
*/
CMD_FUNC(_cmd_tkl)
diff --git a/src/modules/whois.c b/src/modules/whois.c
@@ -315,6 +315,12 @@ CMD_FUNC(cmd_whois)
RunHook2(HOOKTYPE_WHOIS, client, target);
+ if (IsOper(client) && MyUser(target) && IsShunned(target))
+ {
+ sendto_one(client, NULL, ":%s %d %s %s :is shunned",
+ me.name, RPL_WHOISSPECIAL, client->name, target->name);
+ }
+
if (target->user->swhois && !hideoper)
{
SWhois *s;
@@ -336,7 +342,7 @@ CMD_FUNC(cmd_whois)
* Umode +I hides an oper's idle time from regular users.
* -Nath.
*/
- if (MyConnect(target) && (IsOper(client) || !(target->umodes & UMODE_HIDLE)))
+ if (MyConnect(target) && !hide_idle_time(client, target))
{
sendnumeric(client, RPL_WHOISIDLE, name,
TStime() - target->local->last, target->local->firsttime);
diff --git a/src/modules/whox.c b/src/modules/whox.c
@@ -8,10 +8,18 @@
#include "unrealircd.h"
-#define MSG_WHO "WHO"
+/* Module header */
+ModuleHeader MOD_HEADER
+ = {
+ "whox",
+ "5.0",
+ "command /who",
+ "UnrealIRCd Team",
+ "unrealircd-5",
+ };
-#define FLAGS_MARK 0x400000 /* marked client (was hybnotice) */
+/* Defines */
#define FIELD_CHANNEL 0x0001
#define FIELD_HOP 0x0002
#define FIELD_FLAGS 0x0004
@@ -43,13 +51,14 @@
#define WHO_ADD 1
#define WHO_DEL 0
-#define SetMark(x) ((x)->flags |= FLAGS_MARK)
-#define ClearMark(x) ((x)->flags &= ~FLAGS_MARK)
-#define IsMarked(x) ((x)->flags & FLAGS_MARK)
-
#define HasField(x, y) ((x)->fields & (y))
#define IsMatch(x, y) ((x)->matchsel & (y))
+#define IsMarked(x) (moddata_client(x, whox_md).l)
+#define SetMark(x) do { moddata_client(x, whox_md).l = 1; } while(0)
+#define ClearMark(x) do { moddata_client(x, whox_md).l = 0; } while(0)
+
+/* Structs */
struct who_format
{
int fields;
@@ -61,30 +70,46 @@ struct who_format
int show_ip;
};
+/* Global variables */
+ModDataInfo *whox_md = NULL;
+
+/* Forward declarations */
CMD_FUNC(cmd_whox);
static void who_global(Client *client, char *mask, int operspy, struct who_format *fmt);
static void do_who(Client *client, Client *acptr, Channel *channel, struct who_format *fmt);
static void do_who_on_channel(Client *client, Channel *channel,
int member, int operspy, struct who_format *fmt);
static int convert_classical_who_request(Client *client, int *parc, char *parv[], char **orig_mask, struct who_format *fmt);
-
-ModuleHeader MOD_HEADER
- = {
- "whox",
- "5.0",
- "command /who",
- "UnrealIRCd Team",
- "unrealircd-5",
- };
+char *whox_md_serialize(ModData *m);
+void whox_md_unserialize(char *str, ModData *m);
+void whox_md_free(ModData *md);
MOD_INIT()
{
+ ModDataInfo mreq;
+
MARK_AS_OFFICIAL_MODULE(modinfo);
- if (!CommandAdd(modinfo->handle, MSG_WHO, cmd_whox, MAXPARA, CMD_USER))
+
+ if (!CommandAdd(modinfo->handle, "WHO", cmd_whox, MAXPARA, CMD_USER))
{
config_warn("You cannot load both cmd_whox and cmd_who. You should ONLY load the cmd_whox module.");
return MOD_FAILED;
}
+
+ memset(&mreq, 0, sizeof(mreq));
+ mreq.name = "whox";
+ mreq.type = MODDATATYPE_CLIENT;
+ mreq.serialize = whox_md_serialize;
+ mreq.unserialize = whox_md_unserialize;
+ mreq.free = whox_md_free;
+ mreq.sync = 0;
+ whox_md = ModDataAdd(modinfo->handle, mreq);
+ if (!whox_md)
+ {
+ config_error("could not register whox moddata");
+ return MOD_FAILED;
+ }
+
ISupportAdd(modinfo->handle, "WHOX", NULL);
return MOD_SUCCESS;
}
@@ -99,6 +124,29 @@ MOD_UNLOAD()
return MOD_SUCCESS;
}
+/** whox module data operations: serialize (rare) */
+char *whox_md_serialize(ModData *m)
+{
+ static char buf[32];
+ if (m->i == 0)
+ return NULL; /* not set */
+ snprintf(buf, sizeof(buf), "%d", m->i);
+ return buf;
+}
+
+/** whox module data operations: unserialize (rare) */
+void whox_md_unserialize(char *str, ModData *m)
+{
+ m->i = atoi(str);
+}
+
+/** whox module data operations: free */
+void whox_md_free(ModData *md)
+{
+ /* we have nothing to free actually, but we must set to zero */
+ md->l = 0;
+}
+
/** cmd_whox: standardized "extended" version of WHO.
* The good thing about WHOX is that it allows the client to define what
* output they want to see. Another good thing is that it is standardized
@@ -792,9 +840,10 @@ static void do_who(Client *client, Client *acptr, Channel *channel, struct who_f
if (HasField(fmt, FIELD_HOP))
append_format(str, sizeof str, &pos, " %d", hide ? 0 : acptr->hopcount);
if (HasField(fmt, FIELD_IDLE))
- append_format(str, sizeof str, &pos, " %d", (int)(MyUser(acptr) &&
- (!(acptr->umodes & UMODE_HIDLE) || IsOper(client) ||
- (client == acptr)) ? TStime() - acptr->local->last : 0));
+ {
+ append_format(str, sizeof str, &pos, " %d",
+ (int)((MyUser(acptr) && !hide_idle_time(client, acptr)) ? (TStime() - acptr->local->last) : 0));
+ }
if (HasField(fmt, FIELD_ACCOUNT))
append_format(str, sizeof str, &pos, " %s", (!isdigit(*acptr->user->svid)) ? acptr->user->svid : "0");
if (HasField(fmt, FIELD_OPLEVEL))
diff --git a/src/random.c b/src/random.c
@@ -438,18 +438,16 @@ void init_random()
{
struct {
#ifndef _WIN32
- struct timeval nowt; /* time */
+ struct timeval nowt; /* time */
char rnd[32]; /* /dev/urandom */
#else
- MEMORYSTATUS mstat; /* memory status */
struct _timeb nowt; /* time */
+ MEMORYSTATUS mstat; /* memory status */
#endif
} rdat;
#ifndef _WIN32
int fd;
-#else
- MEMORYSTATUS mstat;
#endif
_rs_stir();
diff --git a/src/serv.c b/src/serv.c
@@ -405,9 +405,6 @@ CMD_FUNC(cmd_error)
para = (parc > 1 && *parv[1] != '\0') ? parv[1] : "<>";
- Debug((DEBUG_ERROR, "Received ERROR message from %s: %s",
- client->name, para));
-
/* Errors from untrusted sources only go to the junk snomask
* (which is only for debugging issues and such).
* This to prevent flooding and confusing IRCOps by
@@ -415,13 +412,15 @@ CMD_FUNC(cmd_error)
*/
if (!IsServer(client) && !client->serv)
{
- sendto_snomask(SNO_JUNK, "ERROR from %s -- %s",
+ sendto_snomask(SNO_JUNK, "ERROR from server %s: %s",
get_client_name(client, FALSE), para);
return;
}
- sendto_umode_global(UMODE_OPER, "ERROR from %s -- %s",
- get_client_name(client, FALSE), para);
+ sendto_umode_global(UMODE_OPER, "ERROR from server %s: %s",
+ get_client_name(client, FALSE), para);
+ ircd_log(LOG_ERROR, "ERROR from server %s: %s",
+ get_client_name(client, FALSE), para);
}
/** Save the tunefile (such as: highest seen connection count) */
@@ -1279,3 +1278,32 @@ void tkl_init(void)
memset(tklines, 0, sizeof(tklines));
memset(tklines_ip_hash, 0, sizeof(tklines_ip_hash));
}
+
+/** Called when a server link is lost.
+ * Used for logging only, API users can use the HOOKTYPE_SERVER_QUIT hook.
+ */
+void lost_server_link(Client *serv, FORMAT_STRING(const char *fmt), ...)
+{
+ va_list vl;
+ static char buf[1024], buf2[512];
+
+ va_start(vl, fmt);
+ vsnprintf(buf2, sizeof(buf2), fmt, vl);
+ va_end(vl);
+
+ if (IsServer(serv))
+ {
+ /* An already established link is now lost. Broadcast this to all opers. */
+ snprintf(buf, sizeof(buf), "Lost server link to %s: %s",
+ get_client_name(serv, FALSE), buf2);
+ sendto_umode_global(UMODE_OPER, "%s", buf);
+ } else {
+ /* A link attempt failed. Only send this to local opers (can be noisy every xx seconds). */
+ snprintf(buf, sizeof(buf), "Unable to link with server %s: %s",
+ get_client_name(serv, FALSE), buf2);
+ sendto_umode(UMODE_OPER, "%s", buf);
+ }
+
+ /* Always log! */
+ ircd_log(LOG_ERROR, "%s", buf);
+}
diff --git a/src/socket.c b/src/socket.c
@@ -1086,12 +1086,7 @@ void read_packet(int fd, int revents, void *data)
return;
if (IsServer(client) || client->serv) /* server or outgoing connection */
- {
- sendto_umode_global(UMODE_OPER, "Lost connection to %s: Read error",
- get_client_name(client, FALSE));
- ircd_log(LOG_ERROR, "Lost connection to %s: Read error",
- get_client_name(client, FALSE));
- }
+ lost_server_link(client, "Read error or connection closed.");
exit_client(client, NULL, "Read error");
return;
diff --git a/src/tls.c b/src/tls.c
@@ -270,8 +270,25 @@ static int setup_dh_params(SSL_CTX *ctx)
/** Disable SSL/TLS protocols as set by config */
void disable_ssl_protocols(SSL_CTX *ctx, TLSOptions *tlsoptions)
{
- /* OpenSSL has two mechanisms for protocol version control:
- *
+ /* OpenSSL has three mechanisms for protocol version control... */
+
+#ifdef HAS_SSL_CTX_SET_SECURITY_LEVEL
+ /* The first one is setting a "security level" as introduced
+ * by OpenSSL 1.1.0. Some Linux distro's like Ubuntu 20.04
+ * seemingly compile with -DOPENSSL_TLS_SECURITY_LEVEL=2.
+ * This means the application (UnrealIRCd) is unable to allow
+ * TLSv1.0/1.1 even if the application is configured to do so.
+ * So here we set the level to 1, but -again- ONLY if we are
+ * configured to allow TLSv1.0 or v1.1, of course.
+ */
+ if ((tlsoptions->protocols & TLS_PROTOCOL_TLSV1) ||
+ (tlsoptions->protocols & TLS_PROTOCOL_TLSV1_1))
+ {
+ SSL_CTX_set_security_level(ctx, 1);
+ }
+#endif
+
+ /* The remaining two mechanisms are:
* The old way, which is most flexible, is to use:
* SSL_CTX_set_options(... SSL_OP_NO_<version>) which allows
* you to disable each and every specific SSL/TLS version.
@@ -937,18 +954,12 @@ static int fatal_ssl_error(int ssl_error, int where, int my_errno, Client *clien
(client->serv && client->serv->conf) ? client->serv->conf->outgoing.port : -1,
client->name);
}
- sendto_umode(UMODE_OPER, "Lost connection to %s: %s: %s%s%s",
- get_client_name(client, FALSE), ssl_func, ssl_errstr, additional_info, extra);
- /* This is a connect() that fails, we don't broadcast that for non-SSL either (noisy) */
+ lost_server_link(client, "%s: %s%s%s", ssl_func, ssl_errstr, additional_info, extra);
} else
- if ((IsServer(client) || (client->serv && client->serv->conf)) && (where != SAFE_SSL_WRITE))
+ if (IsServer(client) || (client->serv && client->serv->conf))
{
- /* if server (either judged by IsServer() or clearly an outgoing connect),
- * and not writing (since otherwise deliver_it will take care of the error), THEN
- * send a closing link error...
- */
- sendto_umode_global(UMODE_OPER, "Lost connection to %s: %s: %d (%s%s)",
- get_client_name(client, FALSE), ssl_func, ssl_error, ssl_errstr, additional_info);
+ /* Either a trusted fully established server (incoming) or an outgoing server link (established or not) */
+ lost_server_link(client, "%s: %s%s", ssl_func, ssl_errstr, additional_info);
}
if (errtmp)
diff --git a/src/user.c b/src/user.c
@@ -699,3 +699,29 @@ void user_account_login(MessageTag *recv_mtags, Client *client)
{
RunHook2(HOOKTYPE_ACCOUNT_LOGIN, client, recv_mtags);
}
+
+/** Should we hide the idle time of 'target' to user 'client'?
+ * This depends on the set::hide-idle-time policy.
+ */
+int hide_idle_time(Client *client, Client *target)
+{
+ /* First of all, IRCOps bypass the restriction */
+ if (IsOper(client))
+ return 0;
+
+ /* Other than that, it depends on the settings: */
+ switch (iConf.hide_idle_time)
+ {
+ case HIDE_IDLE_TIME_NEVER:
+ return 0;
+ case HIDE_IDLE_TIME_ALWAYS:
+ return 1;
+ case HIDE_IDLE_TIME_USERMODE:
+ case HIDE_IDLE_TIME_OPER_USERMODE:
+ if (target->umodes & UMODE_HIDLE)
+ return 1;
+ return 0;
+ default:
+ return 0;
+ }
+}
diff --git a/src/version.c.SH b/src/version.c.SH
@@ -4,7 +4,7 @@ echo "Extracting src/version.c..."
#id=`grep '$Id: Changes,v' ../Changes`
#id=`echo $id |sed 's/.* Changes\,v \(.*\) .* Exp .*/\1/'`
-id="5.0.3.1"
+id="5.0.4"
echo "$id"
if test -r version.c
diff --git a/src/windows/UnrealIRCd.exe.manifest b/src/windows/UnrealIRCd.exe.manifest
@@ -3,7 +3,7 @@
<assemblyIdentity
processorArchitecture="amd64"
name="UnrealIRCd.UnrealIRCd.5"
- version="5.0.3.1"
+ version="5.0.4.0"
type="win32"
/>
<description>Internet Relay Chat Daemon</description>
diff --git a/src/windows/unrealinst.iss b/src/windows/unrealinst.iss
@@ -6,7 +6,7 @@
[Setup]
AppName=UnrealIRCd 5
-AppVerName=UnrealIRCd 5.0.3.1
+AppVerName=UnrealIRCd 5.0.4
AppPublisher=UnrealIRCd Team
AppPublisherURL=https://www.unrealircd.org
AppSupportURL=https://www.unrealircd.org
diff --git a/unrealircd.in b/unrealircd.in
@@ -33,11 +33,8 @@ if [ "$1" = "start" ] ; then
if [ ! -f @CONFDIR@/unrealircd.conf ]; then
echo ""
echo "The configuration file does not exist (@CONFDIR@/unrealircd.conf)."
- echo "* Create one by following:"
- echo " https://www.unrealircd.org/docs/Installing_from_source#Creating_a_configuration_file"
- echo "* Or if you are upgrading from version 3.2.x then read:"
- echo " https://www.unrealircd.org/docs/Upgrading_from_3.2.x and"
- echo " https://www.unrealircd.org/docs/UnrealIRCd_files_and_directories"
+ echo "Create one using the example configuration file, see the documentation:"
+ echo "https://www.unrealircd.org/docs/Installing_from_source#Creating_a_configuration_file"
exit 1
fi
@BINDIR@/unrealircd
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |