mirror of
git://git.acid.vegas/unrealircd.git
synced 2024-12-26 16:26:38 +00:00
Updated to 5.0.8
This commit is contained in:
parent
b351238d42
commit
88a904d7f7
48
Config
48
Config
@ -104,17 +104,19 @@ fi
|
|||||||
echo $CONF
|
echo $CONF
|
||||||
$CONF || exit 1
|
$CONF || exit 1
|
||||||
cd "$UNREALCWD"
|
cd "$UNREALCWD"
|
||||||
|
|
||||||
if [ "$QUICK" != "1" ] ; then
|
if [ "$QUICK" != "1" ] ; then
|
||||||
if [ ! -f $CONFDIR/tls/server.cert.pem -a ! -f $CONFDIR/ssl/server.cert.pem ]; then
|
if [ ! -f $CONFDIR/tls/server.cert.pem -a ! -f $CONFDIR/ssl/server.cert.pem ]; then
|
||||||
export OPENSSLPATH
|
export OPENSSLPATH
|
||||||
TEST=""
|
TEST=""
|
||||||
while [ -z "$TEST" ] ; do
|
while [ -z "$TEST" ] ; do
|
||||||
if [ "$GENCERTIFICATE" = "1" ] ; then
|
if [ "$GENCERTIFICATE" = "1" ] ; then
|
||||||
TEST="Yes"
|
TEST="Yes"
|
||||||
else
|
else
|
||||||
TEST="No"
|
TEST="No"
|
||||||
fi
|
fi
|
||||||
echo ""
|
echo ""
|
||||||
|
echo "UnrealIRCd requires an SSL certificate in order to work."
|
||||||
echo "Do you want to generate an SSL certificate for the IRCd?"
|
echo "Do you want to generate an SSL certificate for the IRCd?"
|
||||||
echo "Only answer No if you already have one."
|
echo "Only answer No if you already have one."
|
||||||
echo $n "[$TEST] -> $c"
|
echo $n "[$TEST] -> $c"
|
||||||
@ -135,18 +137,26 @@ while [ -z "$TEST" ] ; do
|
|||||||
TEST=""
|
TEST=""
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
if [ "$GENCERTIFICATE" = 1 ]; then
|
if [ "$GENCERTIFICATE" = 1 ]; then
|
||||||
|
echo
|
||||||
|
echo "*******************************************************************************"
|
||||||
|
echo "Next you will be asked some questions in order to generate the SSL certificate."
|
||||||
|
echo "IMPORTANT: If you don't own a domain or don't know what to answer, then you can"
|
||||||
|
echo " simply press ENTER or use fictional names for each question!"
|
||||||
|
echo "*******************************************************************************"
|
||||||
|
echo "Press ENTER to continue"
|
||||||
|
read cc
|
||||||
make pem
|
make pem
|
||||||
echo "Certificate created successfully."
|
echo "Certificate created successfully."
|
||||||
sleep 1
|
sleep 1
|
||||||
else
|
else
|
||||||
echo "Ok, not generating SSL certificate. Make sure that the certificate and key"
|
echo "Ok, not generating SSL certificate. Make sure that the certificate and key"
|
||||||
echo "are installed in conf/tls/server.crt.pem and conf/tls/server.key.pem prior to starting the IRCd."
|
echo "are installed in conf/tls/server.cert.pem and conf/tls/server.key.pem prior to starting the IRCd."
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
echo "SSL certificate already exists in configuration directory, no need to regenerate."
|
echo "SSL certificate already exists in configuration directory, no need to regenerate."
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Silently force a 'make clean' as otherwise part (or whole) of the
|
# Silently force a 'make clean' as otherwise part (or whole) of the
|
||||||
@ -250,7 +260,7 @@ UNREALCWD="`pwd`"
|
|||||||
BASEPATH="$HOME/unrealircd"
|
BASEPATH="$HOME/unrealircd"
|
||||||
DEFPERM="0600"
|
DEFPERM="0600"
|
||||||
SSLDIR=""
|
SSLDIR=""
|
||||||
NICKNAMEHISTORYLENGTH="100"
|
NICKNAMEHISTORYLENGTH="2000"
|
||||||
MAXCONNECTIONS_REQUEST="auto"
|
MAXCONNECTIONS_REQUEST="auto"
|
||||||
REMOTEINC="1"
|
REMOTEINC="1"
|
||||||
CURLDIR=""
|
CURLDIR=""
|
||||||
@ -314,19 +324,19 @@ fi
|
|||||||
|
|
||||||
clear
|
clear
|
||||||
|
|
||||||
if [ -f "doc/Config.header" -a -z "$NOINTRO" ] ; then
|
if [ -f "doc/Config.header" -a -z "$NOINTRO" ] ; then
|
||||||
more doc/Config.header
|
more doc/Config.header
|
||||||
echo ""
|
echo ""
|
||||||
echo $n "[Press Enter to continue]"
|
echo $n "[Press Enter to continue]"
|
||||||
read cc
|
read cc
|
||||||
clear
|
clear
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "We will now ask you a number of questions. You can just press ENTER to accept the defaults!"
|
echo "We will now ask you a number of questions. You can just press ENTER to accept the defaults!"
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
# This needs to be updated each release so auto-upgrading works for settings, modules, etc!!:
|
# This needs to be updated each release so auto-upgrading works for settings, modules, etc!!:
|
||||||
UNREALRELEASES="unrealircd-5.0.7-rc1 unrealircd-5.0.6 unrealircd-5.0.5.1 unrealircd-5.0.5 unrealircd-5.0.4 unrealircd-5.0.3.1 unrealircd-5.0.3 unrealircd-5.0.2 unrealircd-5.0.1 unrealircd-5.0.0 unrealircd-5.0.0-rc2 unrealircd-5.0.0-rc1"
|
UNREALRELEASES="unrealircd-5.0.8-rc1 unrealircd-5.0.7 unrealircd-5.0.7-rc1 unrealircd-5.0.6 unrealircd-5.0.5.1 unrealircd-5.0.5 unrealircd-5.0.4 unrealircd-5.0.3.1 unrealircd-5.0.3 unrealircd-5.0.2 unrealircd-5.0.1 unrealircd-5.0.0"
|
||||||
if [ -f "config.settings" ]; then
|
if [ -f "config.settings" ]; then
|
||||||
. ./config.settings
|
. ./config.settings
|
||||||
else
|
else
|
||||||
@ -451,12 +461,8 @@ while [ -z "$TEST" ] ; do
|
|||||||
TEST=""
|
TEST=""
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
done
|
done
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "If you want, you can manually enter the path to OpenSSL/LibreSSL here."
|
echo "If you want, you can manually enter the path to OpenSSL/LibreSSL here."
|
||||||
echo "In most cases you can leave this blank and it will be detected automatically."
|
echo "In most cases you can leave this blank and it will be detected automatically."
|
||||||
@ -475,7 +481,7 @@ fi
|
|||||||
|
|
||||||
TEST="$SSLDIR"
|
TEST="$SSLDIR"
|
||||||
echo $n "[$TEST] -> $c"
|
echo $n "[$TEST] -> $c"
|
||||||
read cc
|
read cc
|
||||||
if [ -z "$cc" ] ; then
|
if [ -z "$cc" ] ; then
|
||||||
SSLDIR="$TEST"
|
SSLDIR="$TEST"
|
||||||
else
|
else
|
||||||
|
84
Makefile.in
84
Makefile.in
@ -164,54 +164,56 @@ depend:
|
|||||||
done
|
done
|
||||||
|
|
||||||
install: all
|
install: all
|
||||||
$(INSTALL) -m 0700 -d @BINDIR@
|
$(INSTALL) -m 0700 -d $(DESTDIR)@BINDIR@
|
||||||
$(INSTALL) -m 0700 src/ircd @BINDIR@/unrealircd
|
$(INSTALL) -m 0700 src/ircd $(DESTDIR)@BINDIR@/unrealircd
|
||||||
$(INSTALL) -m 0700 -d @DOCDIR@
|
$(INSTALL) -m 0700 -d $(DESTDIR)@DOCDIR@
|
||||||
$(INSTALL) -m 0600 doc/Authors doc/coding-guidelines doc/tao.of.irc @DOCDIR@
|
$(INSTALL) -m 0600 doc/Authors doc/coding-guidelines doc/tao.of.irc $(DESTDIR)@DOCDIR@
|
||||||
$(INSTALL) -m 0700 -d @CONFDIR@
|
$(INSTALL) -m 0700 -d $(DESTDIR)@CONFDIR@
|
||||||
$(INSTALL) -m 0600 doc/conf/*.conf @CONFDIR@
|
$(INSTALL) -m 0600 doc/conf/*.conf $(DESTDIR)@CONFDIR@
|
||||||
$(INSTALL) -m 0600 doc/conf/*.motd @CONFDIR@
|
$(INSTALL) -m 0600 doc/conf/*.motd $(DESTDIR)@CONFDIR@
|
||||||
$(INSTALL) -m 0600 doc/conf/modules.sources.list @CONFDIR@ ; \
|
$(INSTALL) -m 0600 doc/conf/modules.sources.list $(DESTDIR)@CONFDIR@ ; \
|
||||||
$(INSTALL) -m 0700 unrealircd @SCRIPTDIR@
|
$(INSTALL) -m 0700 unrealircd $(DESTDIR)@SCRIPTDIR@
|
||||||
$(INSTALL) -m 0700 -d @MODULESDIR@
|
$(INSTALL) -m 0700 -d $(DESTDIR)@MODULESDIR@
|
||||||
@rm -f @MODULESDIR@/*.so 1>/dev/null 2>&1
|
@rm -f $(DESTDIR)@MODULESDIR@/*.so 1>/dev/null 2>&1
|
||||||
$(INSTALL) -m 0700 src/modules/*.so @MODULESDIR@
|
$(INSTALL) -m 0700 src/modules/*.so $(DESTDIR)@MODULESDIR@
|
||||||
$(INSTALL) -m 0700 -d @MODULESDIR@/usermodes
|
$(INSTALL) -m 0700 -d $(DESTDIR)@MODULESDIR@/usermodes
|
||||||
@rm -f @MODULESDIR@/usermodes/*.so 1>/dev/null 2>&1
|
@rm -f $(DESTDIR)@MODULESDIR@/usermodes/*.so 1>/dev/null 2>&1
|
||||||
$(INSTALL) -m 0700 src/modules/usermodes/*.so @MODULESDIR@/usermodes
|
$(INSTALL) -m 0700 src/modules/usermodes/*.so $(DESTDIR)@MODULESDIR@/usermodes
|
||||||
$(INSTALL) -m 0700 -d @MODULESDIR@/chanmodes
|
$(INSTALL) -m 0700 -d $(DESTDIR)@MODULESDIR@/chanmodes
|
||||||
@rm -f @MODULESDIR@/chanmodes/*.so 1>/dev/null 2>&1
|
@rm -f $(DESTDIR)@MODULESDIR@/chanmodes/*.so 1>/dev/null 2>&1
|
||||||
$(INSTALL) -m 0700 src/modules/chanmodes/*.so @MODULESDIR@/chanmodes
|
$(INSTALL) -m 0700 src/modules/chanmodes/*.so $(DESTDIR)@MODULESDIR@/chanmodes
|
||||||
$(INSTALL) -m 0700 -d @MODULESDIR@/snomasks
|
$(INSTALL) -m 0700 -d $(DESTDIR)@MODULESDIR@/snomasks
|
||||||
@rm -f @MODULESDIR@/snomasks/*.so 1>/dev/null 2>&1
|
@rm -f $(DESTDIR)@MODULESDIR@/snomasks/*.so 1>/dev/null 2>&1
|
||||||
$(INSTALL) -m 0700 src/modules/snomasks/*.so @MODULESDIR@/snomasks
|
$(INSTALL) -m 0700 src/modules/snomasks/*.so $(DESTDIR)@MODULESDIR@/snomasks
|
||||||
$(INSTALL) -m 0700 -d @MODULESDIR@/extbans
|
$(INSTALL) -m 0700 -d $(DESTDIR)@MODULESDIR@/extbans
|
||||||
@rm -f @MODULESDIR@/extbans/*.so 1>/dev/null 2>&1
|
@rm -f $(DESTDIR)@MODULESDIR@/extbans/*.so 1>/dev/null 2>&1
|
||||||
$(INSTALL) -m 0700 src/modules/extbans/*.so @MODULESDIR@/extbans
|
$(INSTALL) -m 0700 src/modules/extbans/*.so $(DESTDIR)@MODULESDIR@/extbans
|
||||||
@#If the conf/ssl directory exists then rename it here to conf/tls
|
@#If the conf/ssl directory exists then rename it here to conf/tls
|
||||||
@#and add a symlink for backwards compatibility (so that f.e. certbot
|
@#and add a symlink for backwards compatibility (so that f.e. certbot
|
||||||
@#doesn't randomly fail after an upgrade to U5).
|
@#doesn't randomly fail after an upgrade to U5).
|
||||||
-@if [ -d "@CONFDIR@/ssl" ] ; then \
|
-@if [ -d "$(DESTDIR)@CONFDIR@/ssl" ] ; then \
|
||||||
mv "@CONFDIR@/ssl" "@CONFDIR@/tls" ; \
|
mv "$(DESTDIR)@CONFDIR@/ssl" "$(DESTDIR)@CONFDIR@/tls" ; \
|
||||||
ln -s "@CONFDIR@/tls" "@CONFDIR@/ssl" ; \
|
ln -s "$(DESTDIR)@CONFDIR@/tls" "$(DESTDIR)@CONFDIR@/ssl" ; \
|
||||||
fi
|
fi
|
||||||
$(INSTALL) -m 0700 -d @CONFDIR@/tls
|
$(INSTALL) -m 0700 -d $(DESTDIR)@CONFDIR@/tls
|
||||||
$(INSTALL) -m 0600 doc/conf/tls/curl-ca-bundle.crt @CONFDIR@/tls
|
$(INSTALL) -m 0600 doc/conf/tls/curl-ca-bundle.crt $(DESTDIR)@CONFDIR@/tls
|
||||||
@# delete modules/cap directory, to avoid confusing with U4 to U5 upgrades:
|
@# delete modules/cap directory, to avoid confusing with U4 to U5 upgrades:
|
||||||
rm -rf @MODULESDIR@/cap
|
rm -rf $(DESTDIR)@MODULESDIR@/cap
|
||||||
$(INSTALL) -m 0700 -d @MODULESDIR@/third
|
$(INSTALL) -m 0700 -d $(DESTDIR)@MODULESDIR@/third
|
||||||
@rm -f @MODULESDIR@/third/*.so 1>/dev/null 2>&1
|
@rm -f $(DESTDIR)@MODULESDIR@/third/*.so 1>/dev/null 2>&1
|
||||||
@#This step can fail with zero files, so we ignore exit status:
|
@#This step can fail with zero files, so we ignore exit status:
|
||||||
-$(INSTALL) -m 0700 src/modules/third/*.so @MODULESDIR@/third
|
-$(INSTALL) -m 0700 src/modules/third/*.so $(DESTDIR)@MODULESDIR@/third
|
||||||
$(INSTALL) -m 0700 -d @TMPDIR@
|
$(INSTALL) -m 0700 -d $(DESTDIR)@TMPDIR@
|
||||||
$(INSTALL) -m 0700 -d @CACHEDIR@
|
$(INSTALL) -m 0700 -d $(DESTDIR)@CACHEDIR@
|
||||||
$(INSTALL) -m 0700 -d @PERMDATADIR@
|
$(INSTALL) -m 0700 -d $(DESTDIR)@PERMDATADIR@
|
||||||
$(INSTALL) -m 0700 -d @LOGDIR@
|
$(INSTALL) -m 0700 -d $(DESTDIR)@LOGDIR@
|
||||||
-@if [ ! -f "@CONFDIR@/tls/server.cert.pem" ] ; then \
|
-@if [ ! -f "$(DESTDIR)@CONFDIR@/tls/server.cert.pem" ] ; then \
|
||||||
$(INSTALL) -m 0600 server.req.pem @CONFDIR@/tls ; \
|
$(INSTALL) -m 0600 server.req.pem $(DESTDIR)@CONFDIR@/tls ; \
|
||||||
$(INSTALL) -m 0600 server.key.pem @CONFDIR@/tls ; \
|
$(INSTALL) -m 0600 server.key.pem $(DESTDIR)@CONFDIR@/tls ; \
|
||||||
$(INSTALL) -m 0600 server.cert.pem @CONFDIR@/tls ; \
|
$(INSTALL) -m 0600 server.cert.pem $(DESTDIR)@CONFDIR@/tls ; \
|
||||||
fi
|
fi
|
||||||
|
@rm -f $(DESTDIR)@SCRIPTDIR@/source
|
||||||
|
ln -s @BUILDDIR@ $(DESTDIR)@SCRIPTDIR@/source
|
||||||
@echo ''
|
@echo ''
|
||||||
@echo '* UnrealIRCd is now installed.'
|
@echo '* UnrealIRCd is now installed.'
|
||||||
|
|
||||||
|
@ -269,6 +269,7 @@ DLL_FILES=SRC/MODULES/CLOAK.DLL \
|
|||||||
SRC/MODULES/EXTBANS/MSGBYPASS.DLL \
|
SRC/MODULES/EXTBANS/MSGBYPASS.DLL \
|
||||||
SRC/MODULES/EXTBANS/TIMEDBAN.DLL \
|
SRC/MODULES/EXTBANS/TIMEDBAN.DLL \
|
||||||
SRC/MODULES/EXTBANS/PARTMSG.DLL \
|
SRC/MODULES/EXTBANS/PARTMSG.DLL \
|
||||||
|
SRC/MODULES/EXTBANS/SECURITYGROUP.DLL \
|
||||||
SRC/MODULES/ACCOUNT-NOTIFY.DLL \
|
SRC/MODULES/ACCOUNT-NOTIFY.DLL \
|
||||||
SRC/MODULES/MESSAGE-TAGS.DLL \
|
SRC/MODULES/MESSAGE-TAGS.DLL \
|
||||||
SRC/MODULES/BATCH.DLL \
|
SRC/MODULES/BATCH.DLL \
|
||||||
@ -1018,6 +1019,9 @@ src/modules/extbans/timedban.dll: src/modules/extbans/timedban.c $(INCLUDES)
|
|||||||
src/modules/extbans/partmsg.dll: src/modules/extbans/partmsg.c $(INCLUDES)
|
src/modules/extbans/partmsg.dll: src/modules/extbans/partmsg.c $(INCLUDES)
|
||||||
$(CC) $(MODCFLAGS) /Fosrc/modules/extbans/ /Fesrc/modules/extbans/ src/modules/extbans/partmsg.c $(MODLFLAGS)
|
$(CC) $(MODCFLAGS) /Fosrc/modules/extbans/ /Fesrc/modules/extbans/ src/modules/extbans/partmsg.c $(MODLFLAGS)
|
||||||
|
|
||||||
|
src/modules/extbans/securitygroup.dll: src/modules/extbans/securitygroup.c $(INCLUDES)
|
||||||
|
$(CC) $(MODCFLAGS) /Fosrc/modules/extbans/ /Fesrc/modules/extbans/ src/modules/extbans/securitygroup.c $(MODLFLAGS)
|
||||||
|
|
||||||
src/modules/account-notify.dll: src/modules/account-notify.c $(INCLUDES)
|
src/modules/account-notify.dll: src/modules/account-notify.c $(INCLUDES)
|
||||||
$(CC) $(MODCFLAGS) /Fosrc/modules/ /Fesrc/modules/ src/modules/account-notify.c $(MODLFLAGS)
|
$(CC) $(MODCFLAGS) /Fosrc/modules/ /Fesrc/modules/ src/modules/account-notify.c $(MODLFLAGS)
|
||||||
|
|
||||||
|
21
SECURITY.md
Normal file
21
SECURITY.md
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
# Security Policy
|
||||||
|
|
||||||
|
## Supported Versions
|
||||||
|
* The latest *stable* release of the 5.x branch
|
||||||
|
|
||||||
|
See [UnrealIRCd releases](https://www.unrealircd.org/docs/UnrealIRCd_releases) for information on older versions and End Of Life dates.
|
||||||
|
|
||||||
|
## Reporting a Vulnerability
|
||||||
|
|
||||||
|
Please report issues on the [bug tracker](https://bugs.unrealircd.org) and in the bug submit form **set the 'View Status' to 'private'**.
|
||||||
|
|
||||||
|
Do not report security issues on the forums or in a public IRC channel such as #unreal-support.
|
||||||
|
If you insist on e-mail then you can use syzop@unrealircd.org or security@unrealircd.org. Again, the bug tracker is preferred.
|
||||||
|
|
||||||
|
If you are *unsure* if something is a security issue, then report it at the bug tracker as a 'private' bug anyway. Better safe than sorry.
|
||||||
|
Do not ask around in public channels or forums.
|
||||||
|
|
||||||
|
You should get a response or at least an acknowledgement soon. If you don't hear back within 24 hours, then please try to contact us again.
|
||||||
|
|
||||||
|
## Full policy
|
||||||
|
See https://www.unrealircd.org/docs/Policy:_Handling_of_security_issues for full information.
|
@ -272,3 +272,43 @@ else
|
|||||||
AC_MSG_RESULT([no])
|
AC_MSG_RESULT([no])
|
||||||
fi
|
fi
|
||||||
])
|
])
|
||||||
|
|
||||||
|
AC_DEFUN([CHECK_ASN1_TIME_diff],
|
||||||
|
[
|
||||||
|
AC_MSG_CHECKING([for ASN1_TIME_diff in SSL library])
|
||||||
|
AC_LANG_PUSH(C)
|
||||||
|
SAVE_LIBS="$LIBS"
|
||||||
|
LIBS="$LIBS $CRYPTOLIB"
|
||||||
|
AC_TRY_LINK([#include <openssl/ssl.h>],
|
||||||
|
[int one, two; ASN1_TIME_diff(&one, &two, NULL, NULL);],
|
||||||
|
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_ASN1_TIME_diff], [], [Define if ssl library has ASN1_TIME_diff])
|
||||||
|
else
|
||||||
|
AC_MSG_RESULT([no])
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_DEFUN([CHECK_X509_get0_notAfter],
|
||||||
|
[
|
||||||
|
AC_MSG_CHECKING([for X509_get0_notAfter in SSL library])
|
||||||
|
AC_LANG_PUSH(C)
|
||||||
|
SAVE_LIBS="$LIBS"
|
||||||
|
LIBS="$LIBS $CRYPTOLIB"
|
||||||
|
AC_TRY_LINK([#include <openssl/ssl.h>],
|
||||||
|
[X509_get0_notAfter(NULL);],
|
||||||
|
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_X509_get0_notAfter], [], [Define if ssl library has X509_get0_notAfter])
|
||||||
|
else
|
||||||
|
AC_MSG_RESULT([no])
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
114
configure
vendored
114
configure
vendored
@ -1,6 +1,6 @@
|
|||||||
#! /bin/sh
|
#! /bin/sh
|
||||||
# Guess values for system-dependent variables and create Makefiles.
|
# Guess values for system-dependent variables and create Makefiles.
|
||||||
# Generated by GNU Autoconf 2.69 for unrealircd 5.0.7.
|
# Generated by GNU Autoconf 2.69 for unrealircd 5.0.8.
|
||||||
#
|
#
|
||||||
# Report bugs to <https://bugs.unrealircd.org/>.
|
# Report bugs to <https://bugs.unrealircd.org/>.
|
||||||
#
|
#
|
||||||
@ -580,8 +580,8 @@ MAKEFLAGS=
|
|||||||
# Identity of this package.
|
# Identity of this package.
|
||||||
PACKAGE_NAME='unrealircd'
|
PACKAGE_NAME='unrealircd'
|
||||||
PACKAGE_TARNAME='unrealircd'
|
PACKAGE_TARNAME='unrealircd'
|
||||||
PACKAGE_VERSION='5.0.7'
|
PACKAGE_VERSION='5.0.8'
|
||||||
PACKAGE_STRING='unrealircd 5.0.7'
|
PACKAGE_STRING='unrealircd 5.0.8'
|
||||||
PACKAGE_BUGREPORT='https://bugs.unrealircd.org/'
|
PACKAGE_BUGREPORT='https://bugs.unrealircd.org/'
|
||||||
PACKAGE_URL='https://unrealircd.org/'
|
PACKAGE_URL='https://unrealircd.org/'
|
||||||
|
|
||||||
@ -1325,7 +1325,7 @@ if test "$ac_init_help" = "long"; then
|
|||||||
# Omit some internal or obsolete options to make the list less imposing.
|
# Omit some internal or obsolete options to make the list less imposing.
|
||||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||||
cat <<_ACEOF
|
cat <<_ACEOF
|
||||||
\`configure' configures unrealircd 5.0.7 to adapt to many kinds of systems.
|
\`configure' configures unrealircd 5.0.8 to adapt to many kinds of systems.
|
||||||
|
|
||||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||||
|
|
||||||
@ -1391,7 +1391,7 @@ fi
|
|||||||
|
|
||||||
if test -n "$ac_init_help"; then
|
if test -n "$ac_init_help"; then
|
||||||
case $ac_init_help in
|
case $ac_init_help in
|
||||||
short | recursive ) echo "Configuration of unrealircd 5.0.7:";;
|
short | recursive ) echo "Configuration of unrealircd 5.0.8:";;
|
||||||
esac
|
esac
|
||||||
cat <<\_ACEOF
|
cat <<\_ACEOF
|
||||||
|
|
||||||
@ -1544,7 +1544,7 @@ fi
|
|||||||
test -n "$ac_init_help" && exit $ac_status
|
test -n "$ac_init_help" && exit $ac_status
|
||||||
if $ac_init_version; then
|
if $ac_init_version; then
|
||||||
cat <<\_ACEOF
|
cat <<\_ACEOF
|
||||||
unrealircd configure 5.0.7
|
unrealircd configure 5.0.8
|
||||||
generated by GNU Autoconf 2.69
|
generated by GNU Autoconf 2.69
|
||||||
|
|
||||||
Copyright (C) 2012 Free Software Foundation, Inc.
|
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||||
@ -1913,7 +1913,7 @@ cat >config.log <<_ACEOF
|
|||||||
This file contains any messages produced by compilers while
|
This file contains any messages produced by compilers while
|
||||||
running configure, to aid debugging if configure makes a mistake.
|
running configure, to aid debugging if configure makes a mistake.
|
||||||
|
|
||||||
It was created by unrealircd $as_me 5.0.7, which was
|
It was created by unrealircd $as_me 5.0.8, which was
|
||||||
generated by GNU Autoconf 2.69. Invocation command line was
|
generated by GNU Autoconf 2.69. Invocation command line was
|
||||||
|
|
||||||
$ $0 $@
|
$ $0 $@
|
||||||
@ -2321,7 +2321,7 @@ _ACEOF
|
|||||||
|
|
||||||
|
|
||||||
# Minor version number (e.g.: Z in X.Y.Z)
|
# Minor version number (e.g.: Z in X.Y.Z)
|
||||||
UNREAL_VERSION_MINOR="7"
|
UNREAL_VERSION_MINOR="8"
|
||||||
|
|
||||||
cat >>confdefs.h <<_ACEOF
|
cat >>confdefs.h <<_ACEOF
|
||||||
#define UNREAL_VERSION_MINOR $UNREAL_VERSION_MINOR
|
#define UNREAL_VERSION_MINOR $UNREAL_VERSION_MINOR
|
||||||
@ -6528,6 +6528,100 @@ else
|
|||||||
$as_echo "no" >&6; }
|
$as_echo "no" >&6; }
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ASN1_TIME_diff in SSL library" >&5
|
||||||
|
$as_echo_n "checking for ASN1_TIME_diff 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 ()
|
||||||
|
{
|
||||||
|
int one, two; ASN1_TIME_diff(&one, &two, NULL, NULL);
|
||||||
|
;
|
||||||
|
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_ASN1_TIME_diff /**/" >>confdefs.h
|
||||||
|
|
||||||
|
else
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||||
|
$as_echo "no" >&6; }
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for X509_get0_notAfter in SSL library" >&5
|
||||||
|
$as_echo_n "checking for X509_get0_notAfter 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 ()
|
||||||
|
{
|
||||||
|
X509_get0_notAfter(NULL);
|
||||||
|
;
|
||||||
|
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_X509_get0_notAfter /**/" >>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.
|
# Check whether --enable-dynamic-linking was given.
|
||||||
if test "${enable_dynamic_linking+set}" = set; then :
|
if test "${enable_dynamic_linking+set}" = set; then :
|
||||||
enableval=$enable_dynamic_linking; enable_dynamic_linking=$enableval
|
enableval=$enable_dynamic_linking; enable_dynamic_linking=$enableval
|
||||||
@ -8398,7 +8492,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
|
|||||||
# report actual input values of CONFIG_FILES etc. instead of their
|
# report actual input values of CONFIG_FILES etc. instead of their
|
||||||
# values after options handling.
|
# values after options handling.
|
||||||
ac_log="
|
ac_log="
|
||||||
This file was extended by unrealircd $as_me 5.0.7, which was
|
This file was extended by unrealircd $as_me 5.0.8, which was
|
||||||
generated by GNU Autoconf 2.69. Invocation command line was
|
generated by GNU Autoconf 2.69. Invocation command line was
|
||||||
|
|
||||||
CONFIG_FILES = $CONFIG_FILES
|
CONFIG_FILES = $CONFIG_FILES
|
||||||
@ -8461,7 +8555,7 @@ _ACEOF
|
|||||||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||||
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
|
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
|
||||||
ac_cs_version="\\
|
ac_cs_version="\\
|
||||||
unrealircd config.status 5.0.7
|
unrealircd config.status 5.0.8
|
||||||
configured by $0, generated by GNU Autoconf 2.69,
|
configured by $0, generated by GNU Autoconf 2.69,
|
||||||
with options \\"\$ac_cs_config\\"
|
with options \\"\$ac_cs_config\\"
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ dnl src/windows/unrealinst.iss
|
|||||||
dnl doc/Config.header
|
dnl doc/Config.header
|
||||||
dnl src/version.c.SH
|
dnl src/version.c.SH
|
||||||
|
|
||||||
AC_INIT([unrealircd], [5.0.7], [https://bugs.unrealircd.org/], [], [https://unrealircd.org/])
|
AC_INIT([unrealircd], [5.0.8], [https://bugs.unrealircd.org/], [], [https://unrealircd.org/])
|
||||||
AC_CONFIG_SRCDIR([src/ircd.c])
|
AC_CONFIG_SRCDIR([src/ircd.c])
|
||||||
AC_CONFIG_HEADER([include/setup.h])
|
AC_CONFIG_HEADER([include/setup.h])
|
||||||
AC_CONFIG_AUX_DIR([autoconf])
|
AC_CONFIG_AUX_DIR([autoconf])
|
||||||
@ -34,7 +34,7 @@ UNREAL_VERSION_MAJOR=["0"]
|
|||||||
AC_DEFINE_UNQUOTED([UNREAL_VERSION_MAJOR], [$UNREAL_VERSION_MAJOR], [Major version number (e.g.: Y for X.Y.Z)])
|
AC_DEFINE_UNQUOTED([UNREAL_VERSION_MAJOR], [$UNREAL_VERSION_MAJOR], [Major version number (e.g.: Y for X.Y.Z)])
|
||||||
|
|
||||||
# Minor version number (e.g.: Z in X.Y.Z)
|
# Minor version number (e.g.: Z in X.Y.Z)
|
||||||
UNREAL_VERSION_MINOR=["7"]
|
UNREAL_VERSION_MINOR=["8"]
|
||||||
AC_DEFINE_UNQUOTED([UNREAL_VERSION_MINOR], [$UNREAL_VERSION_MINOR], [Minor version number (e.g.: Z for X.Y.Z)])
|
AC_DEFINE_UNQUOTED([UNREAL_VERSION_MINOR], [$UNREAL_VERSION_MINOR], [Minor version number (e.g.: Z for X.Y.Z)])
|
||||||
|
|
||||||
# The version suffix such as a beta marker or release candidate
|
# The version suffix such as a beta marker or release candidate
|
||||||
@ -504,6 +504,8 @@ CHECK_SSL
|
|||||||
CHECK_SSL_CTX_SET1_CURVES_LIST
|
CHECK_SSL_CTX_SET1_CURVES_LIST
|
||||||
CHECK_SSL_CTX_SET_MIN_PROTO_VERSION
|
CHECK_SSL_CTX_SET_MIN_PROTO_VERSION
|
||||||
CHECK_SSL_CTX_SET_SECURITY_LEVEL
|
CHECK_SSL_CTX_SET_SECURITY_LEVEL
|
||||||
|
CHECK_ASN1_TIME_diff
|
||||||
|
CHECK_X509_get0_notAfter
|
||||||
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)])],
|
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"])
|
[enable_dynamic_linking=$enableval], [enable_dynamic_linking="yes"])
|
||||||
AS_IF([test $enable_dynamic_linking = "yes"],
|
AS_IF([test $enable_dynamic_linking = "yes"],
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
\___/|_| |_|_| \___|\__,_|_|\___/\_| \_| \____/\__,_|
|
\___/|_| |_|_| \___|\__,_|_|\___/\_| \_| \____/\__,_|
|
||||||
|
|
||||||
Configuration Program
|
Configuration Program
|
||||||
for UnrealIRCd 5.0.7
|
for UnrealIRCd 5.0.8
|
||||||
|
|
||||||
This program will help you to compile your IRC server, and ask you
|
This program will help you to compile your IRC server, and ask you
|
||||||
questions regarding the compile-time settings of it during the process.
|
questions regarding the compile-time settings of it during the process.
|
||||||
|
@ -1,6 +1,72 @@
|
|||||||
UnrealIRCd 5.0.7 Release Notes
|
UnrealIRCd 5.0.8 Release Notes
|
||||||
===============================
|
===============================
|
||||||
|
|
||||||
|
The main purpose of this release is to enhance the
|
||||||
|
[reputation](https://www.unrealircd.org/docs/Reputation_score)
|
||||||
|
functionality. There have also been some other changes and minor
|
||||||
|
bug fixes. For more information, see below.
|
||||||
|
|
||||||
|
Enhancements:
|
||||||
|
* Support for [security groups](https://www.unrealircd.org/docs/Security-group_block),
|
||||||
|
of which four groups always exist by default: known-users, unknown-users,
|
||||||
|
tls-users and tls-and-known-users.
|
||||||
|
* New extended ban ```~G:securitygroupname```. Typical usage would be
|
||||||
|
```MODE #chan +b ~G:unknown-users``` which will ban all users from the
|
||||||
|
channel that are not identified to services and have a reputation
|
||||||
|
score below 25 (by default). The exact settings can be tweaked in the
|
||||||
|
[security group block](https://www.unrealircd.org/docs/Security-group_block).
|
||||||
|
* The reputation command (IRCOp-only) has been extended to make it
|
||||||
|
easier to look for potential troublemakers:
|
||||||
|
* ```REPUTATION Nick``` shows reputation about the nick name
|
||||||
|
* ```REPUTATION IP``` shows reputation about the IP address
|
||||||
|
* ```REPUTATION #channel``` lists users in channel with their reputation score
|
||||||
|
* ```REPUTATION <NN``` lists users with reputation scores below value NN
|
||||||
|
* Only send the first 1000 matches on ```STATS gline``` or a
|
||||||
|
similar command. This to prevent the IRCOp from being flooded off.
|
||||||
|
This value can be changed via
|
||||||
|
[set::max-stats-matches](https://www.unrealircd.org/docs/Set_block#set::max-stats-matches)
|
||||||
|
* Warn when the SSL/TLS server certificate is expired or expires soon
|
||||||
|
(within 7 days).
|
||||||
|
* New option allow::options::reject-on-auth-failure if you want to
|
||||||
|
stop matching on a passworded allow block, see the
|
||||||
|
[allow password documentation](https://www.unrealircd.org/docs/Allow_block#password)
|
||||||
|
for more information. Note that most people won't use this.
|
||||||
|
|
||||||
|
Fixes:
|
||||||
|
* The ```WHO``` command searched on nick name even if it was told
|
||||||
|
to search on a specific account name via WHOX options.
|
||||||
|
* Some typos in the Config script and a warning
|
||||||
|
* Counting clients twice in some circumstances
|
||||||
|
|
||||||
|
Changes:
|
||||||
|
* Support for $(DESTDIR) in 'make install' if packaging for a distro
|
||||||
|
* Mention the ban reason in Q-line server notices
|
||||||
|
* Add self-test to module manager and improve the error message in case
|
||||||
|
the IRCd source directory does not exist.
|
||||||
|
* Print out a more helpful error if you run the unrealircd binary
|
||||||
|
rather than the unrealircd script with an argument like 'mkpasswd' etc.
|
||||||
|
* On *NIX create a symlink 'source' to the UnrealIRCd source
|
||||||
|
|
||||||
|
Module coders / Developers:
|
||||||
|
* The [Doxygen module API docs](https://www.unrealircd.org/api/5/index.html)
|
||||||
|
have been improved, in particular the
|
||||||
|
[Hook API](https://www.unrealircd.org/api/5/group__HookAPI.html)
|
||||||
|
is now 100% documented.
|
||||||
|
|
||||||
|
Reminder: UnrealIRCd 4 is no longer supported
|
||||||
|
----------------------------------------------
|
||||||
|
|
||||||
|
UnrealIRCd 4.x is [no longer supported](https://www.unrealircd.org/docs/UnrealIRCd_4_EOL).
|
||||||
|
Admins must upgrade to UnrealIRCd 5.
|
||||||
|
|
||||||
|
Upgrading from 4.x to 5.x?
|
||||||
|
Then check out the *UnrealIRCd 5* release notes [further down](#unrealircd-5).
|
||||||
|
Or, at the very least, check out
|
||||||
|
[Upgrading from 4.x](https://www.unrealircd.org/docs/Upgrading_from_4.x).
|
||||||
|
|
||||||
|
UnrealIRCd 5.0.7
|
||||||
|
-----------------
|
||||||
|
|
||||||
UnrealIRCd 5.0.7 consists mainly of fixes for the 5.x stable series,
|
UnrealIRCd 5.0.7 consists mainly of fixes for the 5.x stable series,
|
||||||
with some minor enhancements.
|
with some minor enhancements.
|
||||||
|
|
||||||
@ -34,17 +100,6 @@ Module coders / Developers:
|
|||||||
* No changes, only some small additions to the
|
* No changes, only some small additions to the
|
||||||
[Doxygen module API docs](https://www.unrealircd.org/api/5/index.html)
|
[Doxygen module API docs](https://www.unrealircd.org/api/5/index.html)
|
||||||
|
|
||||||
Reminder: UnrealIRCd 4 is End Of Life
|
|
||||||
---------------------------------------
|
|
||||||
|
|
||||||
All support for the previous series, UnrealIRCd 4.x, will stop after
|
|
||||||
[December 31, 2020](https://www.unrealircd.org/docs/UnrealIRCd_4_EOL).
|
|
||||||
If you haven't upgraded yet, do so soon!
|
|
||||||
|
|
||||||
Upgrading from 4.x to 5.x?
|
|
||||||
Then check out the *UnrealIRCd 5* release notes [further down](#unrealircd-5). At the
|
|
||||||
very least, check out [Upgrading from 4.x](https://www.unrealircd.org/docs/Upgrading_from_4.x).
|
|
||||||
|
|
||||||
UnrealIRCd 5.0.6
|
UnrealIRCd 5.0.6
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
@ -37,6 +37,11 @@ rem And we re-run the exact same command:
|
|||||||
call extras\build-tests\windows\compilecmd\%SHORTNAME%.bat
|
call extras\build-tests\windows\compilecmd\%SHORTNAME%.bat
|
||||||
if %ERRORLEVEL% NEQ 0 EXIT /B 1
|
if %ERRORLEVEL% NEQ 0 EXIT /B 1
|
||||||
|
|
||||||
|
rem Compile dependencies for unrealircd-tests -- this doesn't belong here though..
|
||||||
|
curl -fsS -o src\modules\third\fakereputation.c https://raw.githubusercontent.com/unrealircd/unrealircd-tests/master/serverconfig/unrealircd/modules/fakereputation.c
|
||||||
|
call extras\build-tests\windows\compilecmd\%SHORTNAME%.bat CUSTOMMODULE MODULEFILE=fakereputation
|
||||||
|
if %ERRORLEVEL% NEQ 0 EXIT /B 1
|
||||||
|
|
||||||
rem Convert c:\dev to c:\projects\unrealircd-5-libs
|
rem Convert c:\dev to c:\projects\unrealircd-5-libs
|
||||||
rem TODO: should use environment variable in innosetup script?
|
rem TODO: should use environment variable in innosetup script?
|
||||||
sed -i "s/c:\\dev\\unrealircd-5-libs/c:\\projects\\unrealircd-5-libs/gi" src\windows\unrealinst.iss
|
sed -i "s/c:\\dev\\unrealircd-5-libs/c:\\projects\\unrealircd-5-libs/gi" src\windows\unrealinst.iss
|
||||||
|
@ -8,10 +8,11 @@ Here you should be able to find a lot of information on the data structures
|
|||||||
and functions available to you when coding for UnrealIRCd.
|
and functions available to you when coding for UnrealIRCd.
|
||||||
|
|
||||||
## Wiki documentation ##
|
## Wiki documentation ##
|
||||||
* Be sure to check the [Module API](https://www.unrealircd.org/docs/Dev:Module_API) article on the wiki, which currently provides a better overview of the module API.
|
* Be sure to check the [Module API](https://www.unrealircd.org/docs/Dev:Module_API) article on the wiki
|
||||||
|
as well, which provides a better *overview* of the module API
|
||||||
|
|
||||||
## Doxygen docs ##
|
## Doxygen docs ##
|
||||||
|
* [Functions and structs ordered by purpose](modules.html) - **this contains most of the module API!**
|
||||||
* [The most common structs](group__CommonStructs.html) - like Client, User, Server, Channel, etc.
|
* [The most common structs](group__CommonStructs.html) - like Client, User, Server, Channel, etc.
|
||||||
* [All structs](classes.html) - in a simple alphabetical index
|
* [All structs](classes.html) - in a simple alphabetical index
|
||||||
* [Functions and structs ordered by purpose](modules.html) - this is work in progress and still needs expansion!
|
|
||||||
* [Browse by source file](dir_68267d1309a1af8e8297ef4c3efbcdba.html) - see all src/*.c files and their (documented) functions.
|
* [Browse by source file](dir_68267d1309a1af8e8297ef4c3efbcdba.html) - see all src/*.c files and their (documented) functions.
|
||||||
|
@ -38,7 +38,7 @@ PROJECT_NAME = "UnrealIRCd"
|
|||||||
# could be handy for archiving the generated documentation or if some version
|
# could be handy for archiving the generated documentation or if some version
|
||||||
# control system is used.
|
# control system is used.
|
||||||
|
|
||||||
PROJECT_NUMBER = 5.0.7
|
PROJECT_NUMBER = 5.0.8
|
||||||
|
|
||||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||||
# for a project that appears at the top of each page and should give viewer a
|
# for a project that appears at the top of each page and should give viewer a
|
||||||
|
42
include/h.h
42
include/h.h
@ -90,6 +90,7 @@ extern MODVAR ConfigItem_alias *conf_alias;
|
|||||||
extern MODVAR ConfigItem_include *conf_include;
|
extern MODVAR ConfigItem_include *conf_include;
|
||||||
extern MODVAR ConfigItem_help *conf_help;
|
extern MODVAR ConfigItem_help *conf_help;
|
||||||
extern MODVAR ConfigItem_offchans *conf_offchans;
|
extern MODVAR ConfigItem_offchans *conf_offchans;
|
||||||
|
extern MODVAR SecurityGroup *securitygroups;
|
||||||
extern void completed_connection(int, int, void *);
|
extern void completed_connection(int, int, void *);
|
||||||
extern void clear_unknown();
|
extern void clear_unknown();
|
||||||
extern EVENT(e_unload_module_delayed);
|
extern EVENT(e_unload_module_delayed);
|
||||||
@ -163,7 +164,6 @@ extern MODVAR struct list_head global_server_list;
|
|||||||
extern MODVAR struct list_head dead_list;
|
extern MODVAR struct list_head dead_list;
|
||||||
extern RealCommand *find_command(char *cmd, int flags);
|
extern RealCommand *find_command(char *cmd, int flags);
|
||||||
extern RealCommand *find_command_simple(char *cmd);
|
extern RealCommand *find_command_simple(char *cmd);
|
||||||
extern Channel *find_channel(char *, Channel *);
|
|
||||||
extern Membership *find_membership_link(Membership *lp, Channel *ptr);
|
extern Membership *find_membership_link(Membership *lp, Channel *ptr);
|
||||||
extern Member *find_member_link(Member *, Client *);
|
extern Member *find_member_link(Member *, Client *);
|
||||||
extern int remove_user_from_channel(Client *, Channel *);
|
extern int remove_user_from_channel(Client *, Channel *);
|
||||||
@ -336,7 +336,7 @@ extern void del_queries(char *);
|
|||||||
#define WATCH_HASH_TABLE_SIZE 32768
|
#define WATCH_HASH_TABLE_SIZE 32768
|
||||||
#define WHOWAS_HASH_TABLE_SIZE 32768
|
#define WHOWAS_HASH_TABLE_SIZE 32768
|
||||||
#define THROTTLING_HASH_TABLE_SIZE 8192
|
#define THROTTLING_HASH_TABLE_SIZE 8192
|
||||||
#define find_channel hash_find_channel
|
#define hash_find_channel find_channel
|
||||||
extern uint64_t siphash(const char *in, const char *k);
|
extern uint64_t siphash(const char *in, const char *k);
|
||||||
extern uint64_t siphash_raw(const char *in, size_t len, const char *k);
|
extern uint64_t siphash_raw(const char *in, size_t len, const char *k);
|
||||||
extern uint64_t siphash_nocase(const char *in, const char *k);
|
extern uint64_t siphash_nocase(const char *in, const char *k);
|
||||||
@ -359,7 +359,7 @@ extern Channel *hash_get_chan_bucket(uint64_t);
|
|||||||
extern Client *hash_find_client(const char *, Client *);
|
extern Client *hash_find_client(const char *, Client *);
|
||||||
extern Client *hash_find_id(const char *, Client *);
|
extern Client *hash_find_id(const char *, Client *);
|
||||||
extern Client *hash_find_nickatserver(const char *, Client *);
|
extern Client *hash_find_nickatserver(const char *, Client *);
|
||||||
extern Channel *hash_find_channel(char *name, Channel *channel);
|
extern Channel *find_channel(char *name, Channel *channel);
|
||||||
extern Client *hash_find_server(const char *, Client *);
|
extern Client *hash_find_server(const char *, Client *);
|
||||||
extern struct MODVAR ThrottlingBucket *ThrottlingHash[THROTTLING_HASH_TABLE_SIZE];
|
extern struct MODVAR ThrottlingBucket *ThrottlingHash[THROTTLING_HASH_TABLE_SIZE];
|
||||||
|
|
||||||
@ -460,6 +460,7 @@ extern void count_memory(Client *cptr, char *nick);
|
|||||||
extern void list_scache(Client *client);
|
extern void list_scache(Client *client);
|
||||||
extern char *oflagstr(long oflag);
|
extern char *oflagstr(long oflag);
|
||||||
extern int rehash(Client *client, int sig);
|
extern int rehash(Client *client, int sig);
|
||||||
|
extern void s_die();
|
||||||
extern int match_simple(const char *mask, const char *name);
|
extern int match_simple(const char *mask, const char *name);
|
||||||
extern int match_esc(const char *mask, const char *name);
|
extern int match_esc(const char *mask, const char *name);
|
||||||
extern int add_listener(ConfigItem_listen *conf);
|
extern int add_listener(ConfigItem_listen *conf);
|
||||||
@ -549,10 +550,6 @@ extern void *safe_alloc(size_t size);
|
|||||||
extern char *our_strdup(const char *str);
|
extern char *our_strdup(const char *str);
|
||||||
extern char *our_strldup(const char *str, size_t max);
|
extern char *our_strldup(const char *str, size_t max);
|
||||||
|
|
||||||
extern MODFUNC char *tls_get_cipher(SSL *ssl);
|
|
||||||
extern TLSOptions *get_tls_options_for_client(Client *acptr);
|
|
||||||
extern int outdated_tls_client(Client *acptr);
|
|
||||||
extern char *outdated_tls_client_build_string(char *pattern, Client *acptr);
|
|
||||||
extern long config_checkval(char *value, unsigned short flags);
|
extern long config_checkval(char *value, unsigned short flags);
|
||||||
extern void config_status(FORMAT_STRING(const char *format), ...) __attribute__((format(printf,1,2)));
|
extern void config_status(FORMAT_STRING(const char *format), ...) __attribute__((format(printf,1,2)));
|
||||||
extern void init_random();
|
extern void init_random();
|
||||||
@ -701,7 +698,7 @@ extern MODVAR int (*find_shun)(Client *cptr);
|
|||||||
extern MODVAR int (*find_spamfilter_user)(Client *client, int flags);
|
extern MODVAR int (*find_spamfilter_user)(Client *client, int flags);
|
||||||
extern MODVAR TKL *(*find_qline)(Client *cptr, char *nick, int *ishold);
|
extern MODVAR TKL *(*find_qline)(Client *cptr, char *nick, int *ishold);
|
||||||
extern MODVAR TKL *(*find_tkline_match_zap)(Client *cptr);
|
extern MODVAR TKL *(*find_tkline_match_zap)(Client *cptr);
|
||||||
extern MODVAR void (*tkl_stats)(Client *cptr, int type, char *para);
|
extern MODVAR void (*tkl_stats)(Client *cptr, int type, char *para, int *cnt);
|
||||||
extern MODVAR void (*tkl_sync)(Client *client);
|
extern MODVAR void (*tkl_sync)(Client *client);
|
||||||
extern MODVAR void (*cmd_tkl)(Client *client, MessageTag *recv_mtags, int parc, char *parv[]);
|
extern MODVAR void (*cmd_tkl)(Client *client, MessageTag *recv_mtags, int parc, char *parv[]);
|
||||||
extern MODVAR int (*place_host_ban)(Client *client, BanAction action, char *reason, long duration);
|
extern MODVAR int (*place_host_ban)(Client *client, BanAction action, char *reason, long duration);
|
||||||
@ -753,6 +750,25 @@ extern MODVAR void (*labeled_response_force_end)(void);
|
|||||||
extern MODVAR void (*kick_user)(MessageTag *mtags, Channel *channel, Client *client, Client *victim, char *comment);
|
extern MODVAR void (*kick_user)(MessageTag *mtags, Channel *channel, Client *client, Client *victim, char *comment);
|
||||||
/* /Efuncs */
|
/* /Efuncs */
|
||||||
|
|
||||||
|
/* SSL/TLS functions */
|
||||||
|
extern int early_init_ssl();
|
||||||
|
extern int init_ssl();
|
||||||
|
extern int ssl_handshake(Client *); /* Handshake the accpeted con.*/
|
||||||
|
extern int ssl_client_handshake(Client *, ConfigItem_link *); /* and the initiated con.*/
|
||||||
|
extern int ircd_SSL_accept(Client *acptr, int fd);
|
||||||
|
extern int ircd_SSL_connect(Client *acptr, int fd);
|
||||||
|
extern int SSL_smart_shutdown(SSL *ssl);
|
||||||
|
extern void ircd_SSL_client_handshake(int, int, void *);
|
||||||
|
extern void SSL_set_nonblocking(SSL *s);
|
||||||
|
extern SSL_CTX *init_ctx(TLSOptions *tlsoptions, int server);
|
||||||
|
extern MODFUNC char *tls_get_cipher(SSL *ssl);
|
||||||
|
extern TLSOptions *get_tls_options_for_client(Client *acptr);
|
||||||
|
extern int outdated_tls_client(Client *acptr);
|
||||||
|
extern char *outdated_tls_client_build_string(char *pattern, Client *acptr);
|
||||||
|
extern int check_certificate_expiry_ctx(SSL_CTX *ctx, char **errstr);
|
||||||
|
extern EVENT(tls_check_expiry);
|
||||||
|
/* End of SSL/TLS functions */
|
||||||
|
|
||||||
extern void parse_message_tags_default_handler(Client *client, char **str, MessageTag **mtag_list);
|
extern void parse_message_tags_default_handler(Client *client, char **str, MessageTag **mtag_list);
|
||||||
extern char *mtags_to_string_default_handler(MessageTag *m, Client *client);
|
extern char *mtags_to_string_default_handler(MessageTag *m, Client *client);
|
||||||
extern void *labeled_response_save_context_default_handler(void);
|
extern void *labeled_response_save_context_default_handler(void);
|
||||||
@ -793,6 +809,8 @@ extern char *cm_getparameter_ex(void **p, char mode);
|
|||||||
extern void cm_putparameter_ex(void **p, char mode, char *str);
|
extern void cm_putparameter_ex(void **p, char mode, char *str);
|
||||||
extern void cm_freeparameter_ex(void **p, char mode, char *str);
|
extern void cm_freeparameter_ex(void **p, char mode, char *str);
|
||||||
extern int file_exists(char *file);
|
extern int file_exists(char *file);
|
||||||
|
extern time_t get_file_time(char *fname);
|
||||||
|
extern long get_file_size(char *fname);
|
||||||
extern void free_motd(MOTDFile *motd); /* s_serv.c */
|
extern void free_motd(MOTDFile *motd); /* s_serv.c */
|
||||||
extern void fix_timers(void);
|
extern void fix_timers(void);
|
||||||
extern char *chfl_to_sjoin_symbol(int s);
|
extern char *chfl_to_sjoin_symbol(int s);
|
||||||
@ -974,3 +992,11 @@ extern int hide_idle_time(Client *client, Client *target);
|
|||||||
extern void lost_server_link(Client *serv, FORMAT_STRING(const char *fmt), ...);
|
extern void lost_server_link(Client *serv, FORMAT_STRING(const char *fmt), ...);
|
||||||
extern char *sendtype_to_cmd(SendType sendtype);
|
extern char *sendtype_to_cmd(SendType sendtype);
|
||||||
extern MODVAR MessageTagHandler *mtaghandlers;
|
extern MODVAR MessageTagHandler *mtaghandlers;
|
||||||
|
extern int security_group_valid_name(char *name);
|
||||||
|
extern int security_group_exists(char *name);
|
||||||
|
extern SecurityGroup *add_security_group(char *name, int order);
|
||||||
|
extern SecurityGroup *find_security_group(char *name);
|
||||||
|
extern void free_security_group(SecurityGroup *s);
|
||||||
|
extern void set_security_group_defaults(void);
|
||||||
|
extern int user_allowed_by_security_group(Client *client, SecurityGroup *s);
|
||||||
|
extern int user_allowed_by_security_group_name(Client *client, char *secgroupname);
|
||||||
|
@ -430,11 +430,62 @@ SINLINE void list_splice_tail_init(struct list_head *list,
|
|||||||
pos != (head); \
|
pos != (head); \
|
||||||
pos = n, n = pos->prev)
|
pos = n, n = pos->prev)
|
||||||
|
|
||||||
/**
|
/** Walk through client lists (with examples).
|
||||||
* list_for_each_entry - iterate over list of given type
|
* @param pos The variable to use as a loop cursor
|
||||||
* @pos: the type * to use as a loop cursor.
|
* @param head The head of your list
|
||||||
* @head: the head for your list.
|
* @param member The name of the list_struct within the struct.
|
||||||
* @member: the name of the list_struct within the struct.
|
* @ingroup ListFunctions
|
||||||
|
* @section Examples
|
||||||
|
* @subsection client_list List all clients
|
||||||
|
* @code
|
||||||
|
* CMD_FUNC(cmd_listallclients)
|
||||||
|
* {
|
||||||
|
* Client *acptr;
|
||||||
|
* sendnotice(client, "List of all clients:");
|
||||||
|
* list_for_each_entry(acptr, &client_list, client_node)
|
||||||
|
* sendnotice(client, "Client %s", acptr->name);
|
||||||
|
* }
|
||||||
|
* @endcode
|
||||||
|
* @subsection lclient_list List all LOCAL clients
|
||||||
|
* @code
|
||||||
|
* CMD_FUNC(cmd_listalllocalclients)
|
||||||
|
* {
|
||||||
|
* Client *acptr;
|
||||||
|
* sendnotice(client, "List of all local clients:");
|
||||||
|
* list_for_each_entry(acptr, &lclient_list, lclient_node)
|
||||||
|
* sendnotice(client, "Client %s", acptr->name);
|
||||||
|
* }
|
||||||
|
* @endcode
|
||||||
|
* @subsection global_server_list List all servers
|
||||||
|
* @code
|
||||||
|
* CMD_FUNC(cmd_listallservers)
|
||||||
|
* {
|
||||||
|
* Client *acptr;
|
||||||
|
* sendnotice(client, "List of all servers:");
|
||||||
|
* list_for_each_entry(acptr, &global_server_list, client_node)
|
||||||
|
* sendnotice(client, "Server %s", acptr->name);
|
||||||
|
* }
|
||||||
|
* @endcode
|
||||||
|
* @subsection server_list List all LOCALLY connected servers
|
||||||
|
* @code
|
||||||
|
* CMD_FUNC(cmd_listallservers)
|
||||||
|
* {
|
||||||
|
* Client *acptr;
|
||||||
|
* sendnotice(client, "List of all LOCAL servers:");
|
||||||
|
* list_for_each_entry(acptr, &server_list, special_node)
|
||||||
|
* sendnotice(client, "Server %s", acptr->name);
|
||||||
|
* }
|
||||||
|
* @endcode
|
||||||
|
* @subsection oper_list List all LOCALLY connected IRCOps
|
||||||
|
* @code
|
||||||
|
* CMD_FUNC(cmd_listlocalircops)
|
||||||
|
* {
|
||||||
|
* Client *acptr;
|
||||||
|
* sendnotice(client, "List of all LOCAL IRCOps:");
|
||||||
|
* list_for_each_entry(acptr, &oper_list, special_node)
|
||||||
|
* sendnotice(client, "User %s", acptr->name);
|
||||||
|
* }
|
||||||
|
* @endcode
|
||||||
*/
|
*/
|
||||||
#define list_for_each_entry(pos, head, member) \
|
#define list_for_each_entry(pos, head, member) \
|
||||||
for (pos = list_entry((head)->next, typeof(*pos), member); \
|
for (pos = list_entry((head)->next, typeof(*pos), member); \
|
||||||
@ -514,12 +565,16 @@ SINLINE void list_splice_tail_init(struct list_head *list,
|
|||||||
for (; &pos->member != (head); \
|
for (; &pos->member != (head); \
|
||||||
pos = list_entry(pos->member.next, typeof(*pos), member))
|
pos = list_entry(pos->member.next, typeof(*pos), member))
|
||||||
|
|
||||||
/**
|
/** Walk through client lists - special 'safe' version.
|
||||||
* list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
|
* This is a special version, in case clients are removed from the list
|
||||||
* @pos: the type * to use as a loop cursor.
|
* while the list is iterated. It is unlikely that you need to use this
|
||||||
* @n: another type * to use as temporary storage
|
* from modules, so use list_for_each_entry() instead.
|
||||||
* @head: the head for your list.
|
* Examples are also in list_for_each_entry().
|
||||||
* @member: the name of the list_struct within the struct.
|
* @param pos The variable to use as a loop cursor
|
||||||
|
* @param n Variable to be used for temporary storage
|
||||||
|
* @param head The head of your list
|
||||||
|
* @param member The name of the list_struct within the struct.
|
||||||
|
* @ingroup ListFunctions
|
||||||
*/
|
*/
|
||||||
#define list_for_each_entry_safe(pos, n, head, member) \
|
#define list_for_each_entry_safe(pos, n, head, member) \
|
||||||
for (pos = list_entry((head)->next, typeof(*pos), member), \
|
for (pos = list_entry((head)->next, typeof(*pos), member), \
|
||||||
|
1312
include/modules.h
1312
include/modules.h
File diff suppressed because it is too large
Load Diff
@ -28,6 +28,9 @@
|
|||||||
/* Define if you have the <glob.h> header file. */
|
/* Define if you have the <glob.h> header file. */
|
||||||
#undef GLOBH
|
#undef GLOBH
|
||||||
|
|
||||||
|
/* Define if ssl library has ASN1_TIME_diff */
|
||||||
|
#undef HAS_ASN1_TIME_diff
|
||||||
|
|
||||||
/* Define if ssl library has SSL_CTX_set1_curves_list */
|
/* Define if ssl library has SSL_CTX_set1_curves_list */
|
||||||
#undef HAS_SSL_CTX_SET1_CURVES_LIST
|
#undef HAS_SSL_CTX_SET1_CURVES_LIST
|
||||||
|
|
||||||
@ -37,6 +40,9 @@
|
|||||||
/* Define if ssl library has SSL_CTX_set_security_level */
|
/* Define if ssl library has SSL_CTX_set_security_level */
|
||||||
#undef HAS_SSL_CTX_SET_SECURITY_LEVEL
|
#undef HAS_SSL_CTX_SET_SECURITY_LEVEL
|
||||||
|
|
||||||
|
/* Define if ssl library has X509_get0_notAfter */
|
||||||
|
#undef HAS_X509_get0_notAfter
|
||||||
|
|
||||||
/* Define if you have crypt */
|
/* Define if you have crypt */
|
||||||
#undef HAVE_CRYPT
|
#undef HAVE_CRYPT
|
||||||
|
|
||||||
|
@ -108,6 +108,7 @@ typedef struct ConfigItem_include ConfigItem_include;
|
|||||||
typedef struct ConfigItem_blacklist_module ConfigItem_blacklist_module;
|
typedef struct ConfigItem_blacklist_module ConfigItem_blacklist_module;
|
||||||
typedef struct ConfigItem_help ConfigItem_help;
|
typedef struct ConfigItem_help ConfigItem_help;
|
||||||
typedef struct ConfigItem_offchans ConfigItem_offchans;
|
typedef struct ConfigItem_offchans ConfigItem_offchans;
|
||||||
|
typedef struct SecurityGroup SecurityGroup;
|
||||||
typedef struct ListStruct ListStruct;
|
typedef struct ListStruct ListStruct;
|
||||||
typedef struct ListStructPrio ListStructPrio;
|
typedef struct ListStructPrio ListStructPrio;
|
||||||
|
|
||||||
@ -285,7 +286,7 @@ typedef enum ClientStatus {
|
|||||||
#define SetUser(x) ((x)->status = CLIENT_STATUS_USER)
|
#define SetUser(x) ((x)->status = CLIENT_STATUS_USER)
|
||||||
#define SetLog(x) ((x)->status = CLIENT_STATUS_LOG)
|
#define SetLog(x) ((x)->status = CLIENT_STATUS_LOG)
|
||||||
|
|
||||||
/* @} */
|
/** @} */
|
||||||
|
|
||||||
/** Used for checking certain properties of clients, such as IsSecure() and IsULine().
|
/** Used for checking certain properties of clients, such as IsSecure() and IsULine().
|
||||||
* @defgroup ClientFlags Client flags
|
* @defgroup ClientFlags Client flags
|
||||||
@ -487,7 +488,7 @@ typedef enum ClientStatus {
|
|||||||
#define ClearULine(x) do { (x)->flags &= ~CLIENT_FLAG_ULINE; } while(0)
|
#define ClearULine(x) do { (x)->flags &= ~CLIENT_FLAG_ULINE; } while(0)
|
||||||
#define ClearVirus(x) do { (x)->flags &= ~CLIENT_FLAG_VIRUS; } while(0)
|
#define ClearVirus(x) do { (x)->flags &= ~CLIENT_FLAG_VIRUS; } while(0)
|
||||||
#define ClearIdentLookupSent(x) do { (x)->flags &= ~CLIENT_FLAG_IDENTLOOKUPSENT; } while(0)
|
#define ClearIdentLookupSent(x) do { (x)->flags &= ~CLIENT_FLAG_IDENTLOOKUPSENT; } while(0)
|
||||||
/* @} */
|
/** @} */
|
||||||
|
|
||||||
|
|
||||||
/* Others that access client structs: */
|
/* Others that access client structs: */
|
||||||
@ -498,6 +499,9 @@ typedef enum ClientStatus {
|
|||||||
#define IsSynched(x) (x->serv->flags.synced)
|
#define IsSynched(x) (x->serv->flags.synced)
|
||||||
#define IsServerSent(x) (x->serv && x->serv->flags.server_sent)
|
#define IsServerSent(x) (x->serv && x->serv->flags.server_sent)
|
||||||
|
|
||||||
|
/* And more that access client stuff - but actually modularized */
|
||||||
|
#define GetReputation(client) (moddata_client_get(client, "reputation") ? atoi(moddata_client_get(client, "reputation")) : 0) /**< Get reputation value for a client */
|
||||||
|
|
||||||
/* PROTOCTL (Server protocol) stuff */
|
/* PROTOCTL (Server protocol) stuff */
|
||||||
#ifndef DEBUGMODE
|
#ifndef DEBUGMODE
|
||||||
#define CHECKSERVERPROTO(x,y) (((x)->local->proto & y) == y)
|
#define CHECKSERVERPROTO(x,y) (((x)->local->proto & y) == y)
|
||||||
@ -792,7 +796,8 @@ struct SWhois {
|
|||||||
char *setby;
|
char *setby;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** The command API - used by modules and the core.
|
/** The command API - used by modules and the core to add commands, overrides, etc.
|
||||||
|
* See also https://www.unrealircd.org/docs/Dev:Command_API for a higher level overview and example.
|
||||||
* @defgroup CommandAPI Command API
|
* @defgroup CommandAPI Command API
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
@ -829,7 +834,7 @@ struct SWhois {
|
|||||||
* E.g. parv[3] in the above example is out of bounds.
|
* E.g. parv[3] in the above example is out of bounds.
|
||||||
*/
|
*/
|
||||||
#define CMD_FUNC(x) void (x) (Client *client, MessageTag *recv_mtags, int parc, char *parv[])
|
#define CMD_FUNC(x) void (x) (Client *client, MessageTag *recv_mtags, int parc, char *parv[])
|
||||||
/* @} */
|
/** @} */
|
||||||
|
|
||||||
/** Command override function - used by all command override handlers.
|
/** Command override function - used by all command override handlers.
|
||||||
* This is used in the code like <pre>CMD_OVERRIDE_FUNC(ovr_somecmd)</pre> as a function definition.
|
* This is used in the code like <pre>CMD_OVERRIDE_FUNC(ovr_somecmd)</pre> as a function definition.
|
||||||
@ -1217,7 +1222,7 @@ struct Server {
|
|||||||
} features;
|
} features;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* @} */
|
/** @} */
|
||||||
|
|
||||||
struct MessageTag {
|
struct MessageTag {
|
||||||
MessageTag *prev, *next;
|
MessageTag *prev, *next;
|
||||||
@ -1379,6 +1384,7 @@ struct ConfigFlag_allow {
|
|||||||
unsigned noident :1;
|
unsigned noident :1;
|
||||||
unsigned useip :1;
|
unsigned useip :1;
|
||||||
unsigned tls :1;
|
unsigned tls :1;
|
||||||
|
unsigned reject_on_auth_failure :1;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ConfigItem_allow {
|
struct ConfigItem_allow {
|
||||||
@ -1715,6 +1721,16 @@ struct ConfigItem_offchans {
|
|||||||
char *topic;
|
char *topic;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define SECURITYGROUPLEN 48
|
||||||
|
struct SecurityGroup {
|
||||||
|
SecurityGroup *prev, *next;
|
||||||
|
int priority;
|
||||||
|
char name[SECURITYGROUPLEN+1];
|
||||||
|
int identified;
|
||||||
|
int reputation_score;
|
||||||
|
int webirc;
|
||||||
|
int tls;
|
||||||
|
};
|
||||||
|
|
||||||
#define HM_HOST 1
|
#define HM_HOST 1
|
||||||
#define HM_IPV4 2
|
#define HM_IPV4 2
|
||||||
@ -2010,18 +2026,6 @@ extern MODVAR SSL_CTX *ctx;
|
|||||||
extern MODVAR SSL_CTX *ctx_server;
|
extern MODVAR SSL_CTX *ctx_server;
|
||||||
extern MODVAR SSL_CTX *ctx_client;
|
extern MODVAR SSL_CTX *ctx_client;
|
||||||
|
|
||||||
extern SSL_METHOD *meth;
|
|
||||||
extern int early_init_ssl();
|
|
||||||
extern int init_ssl();
|
|
||||||
extern int ssl_handshake(Client *); /* Handshake the accpeted con.*/
|
|
||||||
extern int ssl_client_handshake(Client *, ConfigItem_link *); /* and the initiated con.*/
|
|
||||||
extern int ircd_SSL_accept(Client *acptr, int fd);
|
|
||||||
extern int ircd_SSL_connect(Client *acptr, int fd);
|
|
||||||
extern int SSL_smart_shutdown(SSL *ssl);
|
|
||||||
extern void ircd_SSL_client_handshake(int, int, void *);
|
|
||||||
extern void SSL_set_nonblocking(SSL *s);
|
|
||||||
extern SSL_CTX *init_ctx(TLSOptions *tlsoptions, int server);
|
|
||||||
|
|
||||||
#define TLS_PROTOCOL_TLSV1 0x0001
|
#define TLS_PROTOCOL_TLSV1 0x0001
|
||||||
#define TLS_PROTOCOL_TLSV1_1 0x0002
|
#define TLS_PROTOCOL_TLSV1_1 0x0002
|
||||||
#define TLS_PROTOCOL_TLSV1_2 0x0004
|
#define TLS_PROTOCOL_TLSV1_2 0x0004
|
||||||
|
@ -63,7 +63,7 @@
|
|||||||
#define UNREAL_VERSION_MAJOR 0
|
#define UNREAL_VERSION_MAJOR 0
|
||||||
|
|
||||||
/* Minor version number (e.g.: 1 for Unreal3.2.1) */
|
/* Minor version number (e.g.: 1 for Unreal3.2.1) */
|
||||||
#define UNREAL_VERSION_MINOR 7
|
#define UNREAL_VERSION_MINOR 8
|
||||||
|
|
||||||
/* Version suffix such as a beta marker or release candidate marker. (e.g.:
|
/* Version suffix such as a beta marker or release candidate marker. (e.g.:
|
||||||
-rcX for unrealircd-3.2.9-rcX) */
|
-rcX for unrealircd-3.2.9-rcX) */
|
||||||
|
@ -26,7 +26,9 @@
|
|||||||
|
|
||||||
#include "unrealircd.h"
|
#include "unrealircd.h"
|
||||||
|
|
||||||
/** This is the extended channel mode API
|
/** This is the extended channel mode API,
|
||||||
|
* see also https://www.unrealircd.org/docs/Dev:Channel_Mode_API
|
||||||
|
* for more information.
|
||||||
* @defgroup ChannelModeAPI Channel mode API
|
* @defgroup ChannelModeAPI Channel mode API
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
@ -63,7 +63,7 @@ int (*find_shun)(Client *client);
|
|||||||
int(*find_spamfilter_user)(Client *client, int flags);
|
int(*find_spamfilter_user)(Client *client, int flags);
|
||||||
TKL *(*find_qline)(Client *client, char *nick, int *ishold);
|
TKL *(*find_qline)(Client *client, char *nick, int *ishold);
|
||||||
TKL *(*find_tkline_match_zap)(Client *client);
|
TKL *(*find_tkline_match_zap)(Client *client);
|
||||||
void (*tkl_stats)(Client *client, int type, char *para);
|
void (*tkl_stats)(Client *client, int type, char *para, int *cnt);
|
||||||
void (*tkl_sync)(Client *client);
|
void (*tkl_sync)(Client *client);
|
||||||
void (*cmd_tkl)(Client *client, MessageTag *mtags, int parc, char *parv[]);
|
void (*cmd_tkl)(Client *client, MessageTag *mtags, int parc, char *parv[]);
|
||||||
int (*place_host_ban)(Client *client, BanAction action, char *reason, long duration);
|
int (*place_host_ban)(Client *client, BanAction action, char *reason, long duration);
|
||||||
|
@ -240,4 +240,5 @@ void SetupEvents(void)
|
|||||||
EventAdd(NULL, "check_deadsockets", check_deadsockets, NULL, 1000, 0);
|
EventAdd(NULL, "check_deadsockets", check_deadsockets, NULL, 1000, 0);
|
||||||
EventAdd(NULL, "handshake_timeout", handshake_timeout, NULL, 1000, 0);
|
EventAdd(NULL, "handshake_timeout", handshake_timeout, NULL, 1000, 0);
|
||||||
EventAdd(NULL, "try_connections", try_connections, NULL, 2000, 0);
|
EventAdd(NULL, "try_connections", try_connections, NULL, 2000, 0);
|
||||||
|
EventAdd(NULL, "tls_check_expiry", tls_check_expiry, NULL, (86400/2)*1000, 0);
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,9 @@
|
|||||||
*/
|
*/
|
||||||
#include "unrealircd.h"
|
#include "unrealircd.h"
|
||||||
|
|
||||||
/** This is the message tags API (message-tags)
|
/** This is the message tags API (message-tags).
|
||||||
|
* For an overview of message tags in general (not the API)
|
||||||
|
* see https://www.unrealircd.org/docs/Message_tags
|
||||||
* @defgroup MessagetagAPI Message tag API
|
* @defgroup MessagetagAPI Message tag API
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
@ -28,7 +28,16 @@
|
|||||||
long opermode = 0;
|
long opermode = 0;
|
||||||
/** Lazy way to signal an SAJOIN MODE */
|
/** Lazy way to signal an SAJOIN MODE */
|
||||||
long sajoinmode = 0;
|
long sajoinmode = 0;
|
||||||
/** List of all channels on the server */
|
/** List of all channels on the server.
|
||||||
|
* @ingroup ListFunctions
|
||||||
|
* @section channels_example Example
|
||||||
|
* This code will list all channels on the network.
|
||||||
|
* @code
|
||||||
|
* sendnotice(client, "List of all channels:");
|
||||||
|
* for (channel = channels; channel; channel=channel->nextch)
|
||||||
|
* sendnotice(client, "Channel %s", channel->name);
|
||||||
|
* @endcode
|
||||||
|
*/
|
||||||
Channel *channels = NULL;
|
Channel *channels = NULL;
|
||||||
|
|
||||||
/* some buffers for rebuilding channel/nick lists with comma's */
|
/* some buffers for rebuilding channel/nick lists with comma's */
|
||||||
@ -1144,7 +1153,7 @@ void set_channel_mlock(Client *client, Channel *channel, const char *newmlock, i
|
|||||||
* @in modebuf_in Buffer pointing to mode characters (eg: +snk-l)
|
* @in modebuf_in Buffer pointing to mode characters (eg: +snk-l)
|
||||||
* @in parabuf_in Buffer pointing to all parameters (eg: key 123)
|
* @in parabuf_in Buffer pointing to all parameters (eg: key 123)
|
||||||
* @retval Returns 1 if we have valid data to return, 0 if at end of mode line.
|
* @retval Returns 1 if we have valid data to return, 0 if at end of mode line.
|
||||||
* @section ex1 Example:
|
* @section parse_chanmode_example Example:
|
||||||
* @code
|
* @code
|
||||||
* ParseMode pm;
|
* ParseMode pm;
|
||||||
* int ret;
|
* int ret;
|
||||||
|
98
src/conf.c
98
src/conf.c
@ -70,6 +70,7 @@ static int _conf_alias (ConfigFile *conf, ConfigEntry *ce);
|
|||||||
static int _conf_help (ConfigFile *conf, ConfigEntry *ce);
|
static int _conf_help (ConfigFile *conf, ConfigEntry *ce);
|
||||||
static int _conf_offchans (ConfigFile *conf, ConfigEntry *ce);
|
static int _conf_offchans (ConfigFile *conf, ConfigEntry *ce);
|
||||||
static int _conf_sni (ConfigFile *conf, ConfigEntry *ce);
|
static int _conf_sni (ConfigFile *conf, ConfigEntry *ce);
|
||||||
|
static int _conf_security_group (ConfigFile *conf, ConfigEntry *ce);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Validation commands
|
* Validation commands
|
||||||
@ -102,6 +103,7 @@ static int _test_alias (ConfigFile *conf, ConfigEntry *ce);
|
|||||||
static int _test_help (ConfigFile *conf, ConfigEntry *ce);
|
static int _test_help (ConfigFile *conf, ConfigEntry *ce);
|
||||||
static int _test_offchans (ConfigFile *conf, ConfigEntry *ce);
|
static int _test_offchans (ConfigFile *conf, ConfigEntry *ce);
|
||||||
static int _test_sni (ConfigFile *conf, ConfigEntry *ce);
|
static int _test_sni (ConfigFile *conf, ConfigEntry *ce);
|
||||||
|
static int _test_security_group (ConfigFile *conf, ConfigEntry *ce);
|
||||||
|
|
||||||
/* This MUST be alphabetized */
|
/* This MUST be alphabetized */
|
||||||
static ConfigCommand _ConfigCommands[] = {
|
static ConfigCommand _ConfigCommands[] = {
|
||||||
@ -126,6 +128,7 @@ static ConfigCommand _ConfigCommands[] = {
|
|||||||
{ "oper", _conf_oper, _test_oper },
|
{ "oper", _conf_oper, _test_oper },
|
||||||
{ "operclass", _conf_operclass, _test_operclass },
|
{ "operclass", _conf_operclass, _test_operclass },
|
||||||
{ "require", _conf_require, _test_require },
|
{ "require", _conf_require, _test_require },
|
||||||
|
{ "security-group", _conf_security_group, _test_security_group },
|
||||||
{ "set", _conf_set, _test_set },
|
{ "set", _conf_set, _test_set },
|
||||||
{ "sni", _conf_sni, _test_sni },
|
{ "sni", _conf_sni, _test_sni },
|
||||||
{ "tld", _conf_tld, _test_tld },
|
{ "tld", _conf_tld, _test_tld },
|
||||||
@ -254,6 +257,7 @@ ConfigItem_include *conf_include = NULL;
|
|||||||
ConfigItem_blacklist_module *conf_blacklist_module = NULL;
|
ConfigItem_blacklist_module *conf_blacklist_module = NULL;
|
||||||
ConfigItem_help *conf_help = NULL;
|
ConfigItem_help *conf_help = NULL;
|
||||||
ConfigItem_offchans *conf_offchans = NULL;
|
ConfigItem_offchans *conf_offchans = NULL;
|
||||||
|
SecurityGroup *securitygroups = NULL;
|
||||||
|
|
||||||
MODVAR Configuration iConf;
|
MODVAR Configuration iConf;
|
||||||
MODVAR Configuration tempiConf;
|
MODVAR Configuration tempiConf;
|
||||||
@ -1902,6 +1906,7 @@ void postconf(void)
|
|||||||
postconf_fixes();
|
postconf_fixes();
|
||||||
do_weird_shun_stuff();
|
do_weird_shun_stuff();
|
||||||
isupport_init(); /* for all the 005 values that changed.. */
|
isupport_init(); /* for all the 005 values that changed.. */
|
||||||
|
tls_check_expiry(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
int isanyserverlinked(void)
|
int isanyserverlinked(void)
|
||||||
@ -2072,6 +2077,7 @@ int init_conf(char *rootconf, int rehash)
|
|||||||
callbacks_switchover();
|
callbacks_switchover();
|
||||||
efunctions_switchover();
|
efunctions_switchover();
|
||||||
set_targmax_defaults();
|
set_targmax_defaults();
|
||||||
|
set_security_group_defaults();
|
||||||
if (rehash)
|
if (rehash)
|
||||||
{
|
{
|
||||||
Hook *h;
|
Hook *h;
|
||||||
@ -5350,6 +5356,8 @@ int _conf_allow(ConfigFile *conf, ConfigEntry *ce)
|
|||||||
allow->flags.useip = 1;
|
allow->flags.useip = 1;
|
||||||
else if (!strcmp(cepp->ce_varname, "ssl") || !strcmp(cepp->ce_varname, "tls"))
|
else if (!strcmp(cepp->ce_varname, "ssl") || !strcmp(cepp->ce_varname, "tls"))
|
||||||
allow->flags.tls = 1;
|
allow->flags.tls = 1;
|
||||||
|
else if (!strcmp(cepp->ce_varname, "reject-on-auth-failure"))
|
||||||
|
allow->flags.reject_on_auth_failure = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5545,6 +5553,8 @@ int _test_allow(ConfigFile *conf, ConfigEntry *ce)
|
|||||||
{}
|
{}
|
||||||
else if (!strcmp(cepp->ce_varname, "ssl") || !strcmp(cepp->ce_varname, "tls"))
|
else if (!strcmp(cepp->ce_varname, "ssl") || !strcmp(cepp->ce_varname, "tls"))
|
||||||
{}
|
{}
|
||||||
|
else if (!strcmp(cepp->ce_varname, "reject-on-auth-failure"))
|
||||||
|
{}
|
||||||
else if (!strcmp(cepp->ce_varname, "sasl"))
|
else if (!strcmp(cepp->ce_varname, "sasl"))
|
||||||
{
|
{
|
||||||
config_error("%s:%d: The option allow::options::sasl no longer exists. "
|
config_error("%s:%d: The option allow::options::sasl no longer exists. "
|
||||||
@ -9317,7 +9327,7 @@ int _test_offchans(ConfigFile *conf, ConfigEntry *ce)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
config_warn("set::oficial-channels is deprecated. It often does not do what you want. "
|
config_warn("set::official-channels is deprecated. It often does not do what you want. "
|
||||||
"You're better of creating a channel, setting all modes, topic, etc. to your liking "
|
"You're better of creating a channel, setting all modes, topic, etc. to your liking "
|
||||||
"and then making the channel permanent (MODE #channel +P). "
|
"and then making the channel permanent (MODE #channel +P). "
|
||||||
"The channel will then be stored in a database to preserve it between restarts.");
|
"The channel will then be stored in a database to preserve it between restarts.");
|
||||||
@ -10044,6 +10054,91 @@ int _test_deny(ConfigFile *conf, ConfigEntry *ce)
|
|||||||
return errors;
|
return errors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int _test_security_group(ConfigFile *conf, ConfigEntry *ce)
|
||||||
|
{
|
||||||
|
int errors = 0;
|
||||||
|
ConfigEntry *cep;
|
||||||
|
|
||||||
|
if (!ce->ce_vardata)
|
||||||
|
{
|
||||||
|
config_error("%s:%i: security-group block needs a name, eg: security-group web-users {",
|
||||||
|
ce->ce_fileptr->cf_filename, ce->ce_varlinenum);
|
||||||
|
errors++;
|
||||||
|
} else {
|
||||||
|
if (!strcasecmp(ce->ce_vardata, "unknown-users"))
|
||||||
|
{
|
||||||
|
config_error("%s:%i: The 'unknown-users' group is a special group that is the "
|
||||||
|
"inverse of 'known-users', you cannot create or adjust it in the "
|
||||||
|
"config file, as it is created automatically by UnrealIRCd.",
|
||||||
|
ce->ce_fileptr->cf_filename, ce->ce_varlinenum);
|
||||||
|
errors++;
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
if (!security_group_valid_name(ce->ce_vardata))
|
||||||
|
{
|
||||||
|
config_error("%s:%i: security-group block name '%s' contains invalid characters or is too long. "
|
||||||
|
"Only letters, numbers, underscore and hyphen are allowed.",
|
||||||
|
ce->ce_fileptr->cf_filename, ce->ce_varlinenum, ce->ce_vardata);
|
||||||
|
errors++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (cep = ce->ce_entries; cep; cep = cep->ce_next)
|
||||||
|
{
|
||||||
|
if (!strcmp(cep->ce_varname, "webirc"))
|
||||||
|
{
|
||||||
|
CheckNull(cep);
|
||||||
|
} else
|
||||||
|
if (!strcmp(cep->ce_varname, "identified"))
|
||||||
|
{
|
||||||
|
CheckNull(cep);
|
||||||
|
} else
|
||||||
|
if (!strcmp(cep->ce_varname, "reputation-score"))
|
||||||
|
{
|
||||||
|
int v;
|
||||||
|
CheckNull(cep);
|
||||||
|
v = atoi(cep->ce_vardata);
|
||||||
|
if ((v < 1) || (v > 10000))
|
||||||
|
{
|
||||||
|
config_error("%s:%i: security-group::reputation-score needs to be a value of 1-10000",
|
||||||
|
cep->ce_fileptr->cf_filename, cep->ce_varlinenum);
|
||||||
|
errors++;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
config_error_unknown(cep->ce_fileptr->cf_filename, cep->ce_varlinenum,
|
||||||
|
"security-group", cep->ce_varname);
|
||||||
|
errors++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _conf_security_group(ConfigFile *conf, ConfigEntry *ce)
|
||||||
|
{
|
||||||
|
ConfigEntry *cep;
|
||||||
|
SecurityGroup *s = add_security_group(ce->ce_vardata, 1);
|
||||||
|
|
||||||
|
for (cep = ce->ce_entries; cep; cep = cep->ce_next)
|
||||||
|
{
|
||||||
|
if (!strcmp(cep->ce_varname, "webirc"))
|
||||||
|
s->webirc = config_checkval(cep->ce_vardata, CFG_YESNO);
|
||||||
|
else if (!strcmp(cep->ce_varname, "identified"))
|
||||||
|
s->identified = config_checkval(cep->ce_vardata, CFG_YESNO);
|
||||||
|
else if (!strcmp(cep->ce_varname, "reputation-score"))
|
||||||
|
s->reputation_score = atoi(cep->ce_vardata);
|
||||||
|
else if (!strcmp(cep->ce_varname, "priority"))
|
||||||
|
{
|
||||||
|
s->priority = atoi(cep->ce_vardata);
|
||||||
|
DelListItem(s, securitygroups);
|
||||||
|
AddListItemPrio(s, securitygroups, s->priority);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef USE_LIBCURL
|
#ifdef USE_LIBCURL
|
||||||
static void conf_download_complete(const char *url, const char *file, const char *errorbuf, int cached, void *inc_key)
|
static void conf_download_complete(const char *url, const char *file, const char *errorbuf, int cached, void *inc_key)
|
||||||
{
|
{
|
||||||
@ -10641,6 +10736,7 @@ void link_generator(void)
|
|||||||
" outgoing {\n"
|
" outgoing {\n"
|
||||||
" hostname %s;\n"
|
" hostname %s;\n"
|
||||||
" port %d;\n"
|
" port %d;\n"
|
||||||
|
" options { tls; autoconnect; }\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
" password \"%s\" { spkifp; }\n"
|
" password \"%s\" { spkifp; }\n"
|
||||||
" class servers;\n"
|
" class servers;\n"
|
||||||
|
@ -13,17 +13,6 @@ extern void StartUnrealAgain(void);
|
|||||||
|
|
||||||
extern char *getosname(void);
|
extern char *getosname(void);
|
||||||
|
|
||||||
|
|
||||||
time_t get_file_time(char *fname)
|
|
||||||
{
|
|
||||||
struct stat st;
|
|
||||||
|
|
||||||
if (stat(fname, &st) != 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return (time_t)st.st_ctime;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *find_best_coredump(void)
|
char *find_best_coredump(void)
|
||||||
{
|
{
|
||||||
static char best_fname[512];
|
static char best_fname[512];
|
||||||
@ -560,17 +549,6 @@ int running_interactive(void)
|
|||||||
#define REPORT_ASK 0
|
#define REPORT_ASK 0
|
||||||
#define REPORT_AUTO 1
|
#define REPORT_AUTO 1
|
||||||
|
|
||||||
|
|
||||||
int getfilesize(char *fname)
|
|
||||||
{
|
|
||||||
struct stat st;
|
|
||||||
|
|
||||||
if (stat(fname, &st) != 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return (int)st.st_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define CRASH_REPORT_HOST "crash.unrealircd.org"
|
#define CRASH_REPORT_HOST "crash.unrealircd.org"
|
||||||
|
|
||||||
SSL_CTX *crashreport_init_ssl(void)
|
SSL_CTX *crashreport_init_ssl(void)
|
||||||
@ -614,7 +592,7 @@ int crashreport_send(char *fname)
|
|||||||
int xfr = 0;
|
int xfr = 0;
|
||||||
char *errstr = NULL;
|
char *errstr = NULL;
|
||||||
|
|
||||||
filesize = getfilesize(fname);
|
filesize = get_file_size(fname);
|
||||||
if (filesize < 0)
|
if (filesize < 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
40
src/hash.c
40
src/hash.c
@ -500,11 +500,21 @@ Client *hash_find_server(const char *server, Client *def)
|
|||||||
return def;
|
return def;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Find a client, user (person), server or channel by name.
|
||||||
|
* If you are looking for "other find functions", then the alphabetical index of functions
|
||||||
|
* at 'f' is your best bet: https://www.unrealircd.org/api/5/globals_func_f.html#index_f
|
||||||
|
* @defgroup FindFunctions Find functions
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
/** Find a client by name.
|
/** Find a client by name.
|
||||||
|
* This searches in the list of all types of clients, user/person, servers or an unregistered clients.
|
||||||
|
* If you know what type of client to search for, then use find_server() or find_person() instead!
|
||||||
* @param name The name to search for (eg: "nick" or "irc.example.net")
|
* @param name The name to search for (eg: "nick" or "irc.example.net")
|
||||||
* @param requester The client that is searching for this name
|
* @param requester The client that is searching for this name
|
||||||
* @note If 'requester' is a server or NULL, then we also check
|
* @note If 'requester' is a server or NULL, then we also check
|
||||||
* the ID table, otherwise not.
|
* the ID table, otherwise not.
|
||||||
|
* @returns If the client is found then the Client is returned, otherwise NULL.
|
||||||
*/
|
*/
|
||||||
Client *find_client(char *name, Client *requester)
|
Client *find_client(char *name, Client *requester)
|
||||||
{
|
{
|
||||||
@ -525,6 +535,7 @@ Client *find_client(char *name, Client *requester)
|
|||||||
* @param requester The client searching for the name.
|
* @param requester The client searching for the name.
|
||||||
* @note If 'requester' is a server or NULL, then we also check
|
* @note If 'requester' is a server or NULL, then we also check
|
||||||
* the ID table, otherwise not.
|
* the ID table, otherwise not.
|
||||||
|
* @returns If the server is found then the Client is returned, otherwise NULL.
|
||||||
*/
|
*/
|
||||||
Client *find_server(char *name, Client *requester)
|
Client *find_server(char *name, Client *requester)
|
||||||
{
|
{
|
||||||
@ -539,13 +550,14 @@ Client *find_server(char *name, Client *requester)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Find a person.
|
/** Find a person (a user).
|
||||||
* @param name The name to search for (eg: "nick" or "001ABCDEFG")
|
* @param name The name to search for (eg: "nick" or "001ABCDEFG")
|
||||||
* @param requester The client that is searching for this name
|
* @param requester The client that is searching for this name
|
||||||
* @note If 'requester' is a server or NULL, then we also check
|
* @note If 'requester' is a server or NULL, then we also check
|
||||||
* the ID table, otherwise not.
|
* the ID table, otherwise not.
|
||||||
|
* @returns If the user is found then the Client is returned, otherwise NULL.
|
||||||
*/
|
*/
|
||||||
Client *find_person(char *name, Client *requester)
|
Client *find_person(char *name, Client *requester) /* TODO: this should have been called find_user() to be consistent */
|
||||||
{
|
{
|
||||||
Client *c2ptr;
|
Client *c2ptr;
|
||||||
|
|
||||||
@ -558,10 +570,12 @@ Client *find_person(char *name, Client *requester)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/** Find a channel by name.
|
||||||
* hash_find_channel
|
* @param name The channel name to search for
|
||||||
|
* @param default_result If the channel is not found, this value is returned.
|
||||||
|
* @returns If the channel exists then the Channel is returned, otherwise default_result is returned.
|
||||||
*/
|
*/
|
||||||
Channel *hash_find_channel(char *name, Channel *channel)
|
Channel *find_channel(char *name, Channel *default_result)
|
||||||
{
|
{
|
||||||
unsigned int hashv;
|
unsigned int hashv;
|
||||||
Channel *tmp;
|
Channel *tmp;
|
||||||
@ -573,9 +587,11 @@ Channel *hash_find_channel(char *name, Channel *channel)
|
|||||||
if (smycmp(name, tmp->chname) == 0)
|
if (smycmp(name, tmp->chname) == 0)
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
return channel;
|
return default_result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @} */
|
||||||
|
|
||||||
Channel *hash_get_chan_bucket(uint64_t hashv)
|
Channel *hash_get_chan_bucket(uint64_t hashv)
|
||||||
{
|
{
|
||||||
if (hashv > CHAN_HASH_TABLE_SIZE)
|
if (hashv > CHAN_HASH_TABLE_SIZE)
|
||||||
@ -963,18 +979,14 @@ EVENT(throttling_check_expire)
|
|||||||
char *p = serveropts + strlen(serveropts);
|
char *p = serveropts + strlen(serveropts);
|
||||||
Module *mi;
|
Module *mi;
|
||||||
t = TStime();
|
t = TStime();
|
||||||
if (!Hooks[17] && strchr(serveropts, 'm'))
|
if (!Hooks[HOOKTYPE_USERMSG] && strchr(serveropts, 'm'))
|
||||||
{ p = strchr(serveropts, 'm'); *p = '\0'; }
|
{ p = strchr(serveropts, 'm'); *p = '\0'; }
|
||||||
if (!Hooks[18] && strchr(serveropts, 'M'))
|
if (!Hooks[HOOKTYPE_CHANMSG] && strchr(serveropts, 'M'))
|
||||||
{ p = strchr(serveropts, 'M'); *p = '\0'; }
|
{ p = strchr(serveropts, 'M'); *p = '\0'; }
|
||||||
if (!Hooks[49] && !Hooks[51] && strchr(serveropts, 'R'))
|
if (Hooks[HOOKTYPE_USERMSG] && !strchr(serveropts, 'm'))
|
||||||
{ p = strchr(serveropts, 'R'); *p = '\0'; }
|
|
||||||
if (Hooks[17] && !strchr(serveropts, 'm'))
|
|
||||||
*p++ = 'm';
|
*p++ = 'm';
|
||||||
if (Hooks[18] && !strchr(serveropts, 'M'))
|
if (Hooks[HOOKTYPE_CHANMSG] && !strchr(serveropts, 'M'))
|
||||||
*p++ = 'M';
|
*p++ = 'M';
|
||||||
if ((Hooks[49] || Hooks[51]) && !strchr(serveropts, 'R'))
|
|
||||||
*p++ = 'R';
|
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
for (mi = Modules; mi; mi = mi->next)
|
for (mi = Modules; mi; mi = mi->next)
|
||||||
if (!(mi->options & MOD_OPT_OFFICIAL))
|
if (!(mi->options & MOD_OPT_OFFICIAL))
|
||||||
|
42
src/ircd.c
42
src/ircd.c
@ -96,7 +96,7 @@ void s_die()
|
|||||||
#else
|
#else
|
||||||
unload_all_modules();
|
unload_all_modules();
|
||||||
unlink(conf_files ? conf_files->pid_file : IRCD_PIDFILE);
|
unlink(conf_files ? conf_files->pid_file : IRCD_PIDFILE);
|
||||||
exit(-1);
|
exit(0);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -269,14 +269,7 @@ EVENT(garbage_collect)
|
|||||||
loop.do_garbage_collect = 0;
|
loop.do_garbage_collect = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/** Perform autoconnect to servers that are not linked yet. */
|
||||||
** try_connections
|
|
||||||
**
|
|
||||||
** Scan through configuration and try new connections.
|
|
||||||
** Returns the calendar time when the next call to this
|
|
||||||
** function should be made latest. (No harm done if this
|
|
||||||
** is called earlier or later...)
|
|
||||||
*/
|
|
||||||
EVENT(try_connections)
|
EVENT(try_connections)
|
||||||
{
|
{
|
||||||
ConfigItem_link *aconf;
|
ConfigItem_link *aconf;
|
||||||
@ -287,7 +280,7 @@ EVENT(try_connections)
|
|||||||
|
|
||||||
for (aconf = conf_link; aconf; aconf = aconf->next)
|
for (aconf = conf_link; aconf; aconf = aconf->next)
|
||||||
{
|
{
|
||||||
/* We're only interested in autoconnect blocks that are valid (and ignore temporary link blocks) */
|
/* We're only interested in autoconnect blocks that are valid. Also, we ignore temporary link blocks. */
|
||||||
if (!(aconf->outgoing.options & CONNECT_AUTO) || !aconf->outgoing.hostname || (aconf->flag.temporary == 1))
|
if (!(aconf->outgoing.options & CONNECT_AUTO) || !aconf->outgoing.hostname || (aconf->flag.temporary == 1))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -296,6 +289,7 @@ EVENT(try_connections)
|
|||||||
/* Only do one connection attempt per <connfreq> seconds (for the same server) */
|
/* Only do one connection attempt per <connfreq> seconds (for the same server) */
|
||||||
if ((aconf->hold > TStime()))
|
if ((aconf->hold > TStime()))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
confrq = class->connfreq;
|
confrq = class->connfreq;
|
||||||
aconf->hold = TStime() + confrq;
|
aconf->hold = TStime() + confrq;
|
||||||
|
|
||||||
@ -380,8 +374,7 @@ int match_tkls(Client *client)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Time out connections that are still in handshake.
|
/** Time out connections that are still in handshake. */
|
||||||
*/
|
|
||||||
EVENT(handshake_timeout)
|
EVENT(handshake_timeout)
|
||||||
{
|
{
|
||||||
Client *client, *next;
|
Client *client, *next;
|
||||||
@ -466,11 +459,7 @@ void check_ping(Client *client)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/** Check registered connections for ping timeout. Also, check for server bans. */
|
||||||
* Check registered connections for PING timeout.
|
|
||||||
* XXX: also does some other stuff still, need to sort this. --nenolod
|
|
||||||
* Perhaps it would be wise to ping servers as well mr nenolod, just an idea -- Syzop
|
|
||||||
*/
|
|
||||||
EVENT(check_pings)
|
EVENT(check_pings)
|
||||||
{
|
{
|
||||||
Client *client, *next;
|
Client *client, *next;
|
||||||
@ -493,6 +482,7 @@ EVENT(check_pings)
|
|||||||
/* done */
|
/* done */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Check for clients that are pending to be terminated */
|
||||||
EVENT(check_deadsockets)
|
EVENT(check_deadsockets)
|
||||||
{
|
{
|
||||||
Client *client, *next;
|
Client *client, *next;
|
||||||
@ -550,18 +540,10 @@ static int bad_command(const char *argv0)
|
|||||||
if (!argv0)
|
if (!argv0)
|
||||||
argv0 = "unrealircd";
|
argv0 = "unrealircd";
|
||||||
|
|
||||||
(void)printf
|
printf("ERROR: Incorrect command line argument encountered.\n"
|
||||||
("Usage: %s [-f <config>] [-F]\n"
|
"This is the unrealircd BINARY. End-users should NOT call this binary directly.\n"
|
||||||
"\n"
|
"Please run the SCRIPT instead: %s/unrealircd\n", SCRIPTDIR);
|
||||||
"UnrealIRCd\n"
|
printf("Server not started\n\n");
|
||||||
" -f <config> Load configuration from <config> instead of the default\n"
|
|
||||||
" (%s).\n"
|
|
||||||
" -F Don't fork() when starting up. Use this when running\n"
|
|
||||||
" UnrealIRCd under gdb or when playing around with settings\n"
|
|
||||||
" on a non-production setup.\n"
|
|
||||||
"\n",
|
|
||||||
argv0, CONFIGFILE);
|
|
||||||
(void)printf("Server not started\n\n");
|
|
||||||
#else
|
#else
|
||||||
if (!IsService) {
|
if (!IsService) {
|
||||||
MessageBox(NULL,
|
MessageBox(NULL,
|
||||||
@ -1098,7 +1080,7 @@ int InitUnrealIRCd(int argc, char *argv[])
|
|||||||
bootopt |= BOOT_TTY;
|
bootopt |= BOOT_TTY;
|
||||||
break;
|
break;
|
||||||
case 'v':
|
case 'v':
|
||||||
(void)printf("%s build %s\n", version, buildid);
|
(void)printf("%s\n", version);
|
||||||
#else
|
#else
|
||||||
case 'v':
|
case 'v':
|
||||||
if (!IsService) {
|
if (!IsService) {
|
||||||
|
36
src/misc.c
36
src/misc.c
@ -810,7 +810,6 @@ void exit_client(Client *client, MessageTag *recv_mtags, char *comment)
|
|||||||
exit_one_client(client, recv_mtags, comment);
|
exit_one_client(client, recv_mtags, comment);
|
||||||
|
|
||||||
free_message_tags(mtags_generated);
|
free_message_tags(mtags_generated);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Initialize the (quite useless) IRC statistics */
|
/** Initialize the (quite useless) IRC statistics */
|
||||||
@ -1893,6 +1892,41 @@ int filename_has_suffix(const char *fname, const char *suffix)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Check if the specified file exists */
|
||||||
|
int file_exists(char *file)
|
||||||
|
{
|
||||||
|
FILE *fd;
|
||||||
|
|
||||||
|
fd = fopen(file, "r");
|
||||||
|
if (!fd)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
fclose(fd);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Get the file creation time */
|
||||||
|
time_t get_file_time(char *fname)
|
||||||
|
{
|
||||||
|
struct stat st;
|
||||||
|
|
||||||
|
if (stat(fname, &st) != 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return (time_t)st.st_ctime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Get the size of a file */
|
||||||
|
long get_file_size(char *fname)
|
||||||
|
{
|
||||||
|
struct stat st;
|
||||||
|
|
||||||
|
if (stat(fname, &st) != 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return (long)st.st_size;
|
||||||
|
}
|
||||||
|
|
||||||
/** Add a line to a MultiLine list */
|
/** Add a line to a MultiLine list */
|
||||||
void addmultiline(MultiLine **l, char *line)
|
void addmultiline(MultiLine **l, char *line)
|
||||||
{
|
{
|
||||||
|
@ -1643,11 +1643,33 @@ void mm_parse_c_file(int argc, char *args[])
|
|||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void mm_self_test(void)
|
||||||
|
{
|
||||||
|
char name[512];
|
||||||
|
snprintf(name, sizeof(name), "%s/src/modules/third", BUILDDIR);
|
||||||
|
if (file_exists(name))
|
||||||
|
return;
|
||||||
|
if (!file_exists(BUILDDIR))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "ERROR: Directory %s does not exist.\n"
|
||||||
|
"The UnrealIRCd source is required for the module manager to work!\n",
|
||||||
|
BUILDDIR);
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "ERROR: Directory %s exists, but %s does not.\n"
|
||||||
|
"The UnrealIRCd source is required for the module manager to work.\n"
|
||||||
|
"It seems you only have a partial build directory??\n",
|
||||||
|
BUILDDIR, name);
|
||||||
|
}
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
void modulemanager(int argc, char *args[])
|
void modulemanager(int argc, char *args[])
|
||||||
{
|
{
|
||||||
if (!args[0])
|
if (!args[0])
|
||||||
mm_usage();
|
mm_usage();
|
||||||
|
|
||||||
|
mm_self_test();
|
||||||
|
|
||||||
/* The following operations do not require reading
|
/* The following operations do not require reading
|
||||||
* of the repository list and are always available:
|
* of the repository list and are always available:
|
||||||
*/
|
*/
|
||||||
|
@ -34,7 +34,6 @@ Cmode_t EXTCMODE_SECUREONLY;
|
|||||||
|
|
||||||
int secureonly_check_join(Client *client, Channel *channel, char *key, char *parv[]);
|
int secureonly_check_join(Client *client, Channel *channel, char *key, char *parv[]);
|
||||||
int secureonly_channel_sync (Channel *channel, int merge, int removetheirs, int nomode);
|
int secureonly_channel_sync (Channel *channel, int merge, int removetheirs, int nomode);
|
||||||
int secureonly_send_channel(Client *client, Channel *channel);
|
|
||||||
int secureonly_check_secure(Channel *channel);
|
int secureonly_check_secure(Channel *channel);
|
||||||
int secureonly_check_sajoin(Client *target, Channel *channel, Client *requester);
|
int secureonly_check_sajoin(Client *target, Channel *channel, Client *requester);
|
||||||
int secureonly_specialcheck(Client *client, Channel *channel, char *parv[]);
|
int secureonly_specialcheck(Client *client, Channel *channel, char *parv[]);
|
||||||
@ -58,7 +57,6 @@ MOD_INIT()
|
|||||||
HookAdd(modinfo->handle, HOOKTYPE_CAN_JOIN, 0, secureonly_check_join);
|
HookAdd(modinfo->handle, HOOKTYPE_CAN_JOIN, 0, secureonly_check_join);
|
||||||
HookAdd(modinfo->handle, HOOKTYPE_CHANNEL_SYNCED, 0, secureonly_channel_sync);
|
HookAdd(modinfo->handle, HOOKTYPE_CHANNEL_SYNCED, 0, secureonly_channel_sync);
|
||||||
HookAdd(modinfo->handle, HOOKTYPE_IS_CHANNEL_SECURE, 0, secureonly_check_secure);
|
HookAdd(modinfo->handle, HOOKTYPE_IS_CHANNEL_SECURE, 0, secureonly_check_secure);
|
||||||
HookAdd(modinfo->handle, HOOKTYPE_SEND_CHANNEL, 0, secureonly_send_channel);
|
|
||||||
HookAdd(modinfo->handle, HOOKTYPE_CAN_SAJOIN, 0, secureonly_check_sajoin);
|
HookAdd(modinfo->handle, HOOKTYPE_CAN_SAJOIN, 0, secureonly_check_sajoin);
|
||||||
|
|
||||||
|
|
||||||
@ -165,15 +163,6 @@ int secureonly_channel_sync(Channel *channel, int merge, int removetheirs, int n
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int secureonly_send_channel(Client *client, Channel *channel)
|
|
||||||
{
|
|
||||||
if (IsSecureOnly(channel))
|
|
||||||
if (!IsSecure(client))
|
|
||||||
return HOOK_DENY;
|
|
||||||
|
|
||||||
return HOOK_CONTINUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
int secureonly_check_sajoin(Client *target, Channel *channel, Client *requester)
|
int secureonly_check_sajoin(Client *target, Channel *channel, Client *requester)
|
||||||
{
|
{
|
||||||
if (IsSecureOnly(channel) && !IsSecure(target))
|
if (IsSecureOnly(channel) && !IsSecure(target))
|
||||||
|
@ -67,8 +67,6 @@ UCounter *ucounter = NULL;
|
|||||||
|
|
||||||
#define MSG_THROTTLE "THROTTLE"
|
#define MSG_THROTTLE "THROTTLE"
|
||||||
|
|
||||||
#define GetReputation(client) (moddata_client_get(client, "reputation") ? atoi(moddata_client_get(client, "reputation")) : 0)
|
|
||||||
|
|
||||||
/* Forward declarations */
|
/* Forward declarations */
|
||||||
int ct_config_test(ConfigFile *cf, ConfigEntry *ce, int type, int *errs);
|
int ct_config_test(ConfigFile *cf, ConfigEntry *ce, int type, int *errs);
|
||||||
int ct_config_posttest(int *errs);
|
int ct_config_posttest(int *errs);
|
||||||
|
@ -34,7 +34,7 @@ INCLUDES = ../../include/channel.h \
|
|||||||
R_MODULES= \
|
R_MODULES= \
|
||||||
join.so quiet.so nickchange.so inchannel.so realname.so \
|
join.so quiet.so nickchange.so inchannel.so realname.so \
|
||||||
account.so operclass.so certfp.so textban.so msgbypass.so \
|
account.so operclass.so certfp.so textban.so msgbypass.so \
|
||||||
timedban.so partmsg.so
|
timedban.so partmsg.so securitygroup.so
|
||||||
|
|
||||||
MODULES=$(R_MODULES)
|
MODULES=$(R_MODULES)
|
||||||
MODULEFLAGS=@MODULEFLAGS@
|
MODULEFLAGS=@MODULEFLAGS@
|
||||||
@ -102,3 +102,7 @@ timedban.so: timedban.c $(INCLUDES)
|
|||||||
partmsg.so: partmsg.c $(INCLUDES)
|
partmsg.so: partmsg.c $(INCLUDES)
|
||||||
$(CC) $(CFLAGS) $(MODULEFLAGS) -DDYNAMIC_LINKING \
|
$(CC) $(CFLAGS) $(MODULEFLAGS) -DDYNAMIC_LINKING \
|
||||||
-o partmsg.so partmsg.c
|
-o partmsg.so partmsg.c
|
||||||
|
|
||||||
|
securitygroup.so: securitygroup.c $(INCLUDES)
|
||||||
|
$(CC) $(CFLAGS) $(MODULEFLAGS) -DDYNAMIC_LINKING \
|
||||||
|
-o securitygroup.so securitygroup.c
|
||||||
|
141
src/modules/extbans/securitygroup.c
Normal file
141
src/modules/extbans/securitygroup.c
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
/*
|
||||||
|
* Extended ban to ban based on security groups such as "unknown-users"
|
||||||
|
* (C) Copyright 2020 Bram Matthys (Syzop) and the UnrealIRCd team
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 1, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
#include "unrealircd.h"
|
||||||
|
|
||||||
|
ModuleHeader MOD_HEADER
|
||||||
|
= {
|
||||||
|
"extbans/securitygroup",
|
||||||
|
"4.2",
|
||||||
|
"ExtBan ~G - Ban based on security-group",
|
||||||
|
"UnrealIRCd Team",
|
||||||
|
"unrealircd-5",
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Forward declarations */
|
||||||
|
char *extban_securitygroup_conv_param(char *para);
|
||||||
|
int extban_securitygroup_is_ok(Client *client, Channel *channel, char *para, int checkt, int what, int what2);
|
||||||
|
int extban_securitygroup_is_banned(Client *client, Channel *channel, char *banin, int type, char **msg, char **errmsg);
|
||||||
|
|
||||||
|
/** Called upon module init */
|
||||||
|
MOD_INIT()
|
||||||
|
{
|
||||||
|
ExtbanInfo req;
|
||||||
|
|
||||||
|
req.flag = 'G';
|
||||||
|
req.conv_param = extban_securitygroup_conv_param;
|
||||||
|
req.is_ok = extban_securitygroup_is_ok;
|
||||||
|
req.is_banned = extban_securitygroup_is_banned;
|
||||||
|
req.options = EXTBOPT_INVEX|EXTBOPT_TKL;
|
||||||
|
if (!ExtbanAdd(modinfo->handle, req))
|
||||||
|
{
|
||||||
|
config_error("could not register extended ban type ~G");
|
||||||
|
return MOD_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
MARK_AS_OFFICIAL_MODULE(modinfo);
|
||||||
|
|
||||||
|
return MOD_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Called upon module load */
|
||||||
|
MOD_LOAD()
|
||||||
|
{
|
||||||
|
return MOD_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Called upon unload */
|
||||||
|
MOD_UNLOAD()
|
||||||
|
{
|
||||||
|
return MOD_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Helper function for extban_securitygroup_is_ok() and extban_securitygroup_conv_param()
|
||||||
|
* to do ban validation.
|
||||||
|
*/
|
||||||
|
int extban_securitygroup_generic(char *para, int strict)
|
||||||
|
{
|
||||||
|
char *mask;
|
||||||
|
|
||||||
|
mask = para+3;
|
||||||
|
|
||||||
|
/* ! at the start means negative match */
|
||||||
|
if (*mask == '!')
|
||||||
|
mask++;
|
||||||
|
|
||||||
|
/* Check if the rest of the security group name is valid */
|
||||||
|
if (strict)
|
||||||
|
{
|
||||||
|
if (!security_group_exists(mask))
|
||||||
|
return 0; /* security group does not exist */
|
||||||
|
} else {
|
||||||
|
if (!security_group_valid_name(mask))
|
||||||
|
return 0; /* invalid characters or too long */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!*mask)
|
||||||
|
return 0; /* don't allow "~G:" nor "~G:!" */
|
||||||
|
|
||||||
|
if (strlen(mask) > SECURITYGROUPLEN + 3)
|
||||||
|
mask[SECURITYGROUPLEN + 3] = '\0';
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int extban_securitygroup_is_ok(Client *client, Channel *channel, char *para, int checkt, int what, int what2)
|
||||||
|
{
|
||||||
|
if (MyUser(client) && (what == MODE_ADD) && (checkt == EXBCHK_PARAM))
|
||||||
|
{
|
||||||
|
char banbuf[SECURITYGROUPLEN+8];
|
||||||
|
strlcpy(banbuf, para, sizeof(banbuf));
|
||||||
|
if (!extban_securitygroup_generic(banbuf, 1))
|
||||||
|
{
|
||||||
|
SecurityGroup *s;
|
||||||
|
sendnotice(client, "ERROR: Unknown security-group '%s'. Syntax: +b ~G:securitygroup or +b ~G:!securitygroup", para+3);
|
||||||
|
sendnotice(client, "Available security groups:");
|
||||||
|
for (s = securitygroups; s; s = s->next)
|
||||||
|
sendnotice(client, "%s", s->name);
|
||||||
|
sendnotice(client, "unknown-users");
|
||||||
|
sendnotice(client, "End of security group list.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Security group extban - conv_param */
|
||||||
|
char *extban_securitygroup_conv_param(char *para)
|
||||||
|
{
|
||||||
|
static char retbuf[SECURITYGROUPLEN + 8];
|
||||||
|
|
||||||
|
strlcpy(retbuf, para, sizeof(retbuf));
|
||||||
|
if (!extban_securitygroup_generic(retbuf, 0))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return retbuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Is the user banned by ~G:something ? */
|
||||||
|
int extban_securitygroup_is_banned(Client *client, Channel *channel, char *banin, int type, char **msg, char **errmsg)
|
||||||
|
{
|
||||||
|
char *ban = banin+3;
|
||||||
|
|
||||||
|
if (*ban == '!')
|
||||||
|
return !user_allowed_by_security_group_name(client, ban+1);
|
||||||
|
return user_allowed_by_security_group_name(client, ban);
|
||||||
|
}
|
@ -1367,6 +1367,9 @@ int paracount_for_chanmode_from_server(Client *client, u_int what, char mode)
|
|||||||
if (mode == '&')
|
if (mode == '&')
|
||||||
return 0; /* & indicates bounce, it is not an actual mode character */
|
return 0; /* & indicates bounce, it is not an actual mode character */
|
||||||
|
|
||||||
|
if (mode == 'F')
|
||||||
|
return (what == MODE_ADD) ? 1 : 0; /* Future compatibility */
|
||||||
|
|
||||||
/* If we end up here it means we have no idea if it is a parameter-eating or paramless
|
/* If we end up here it means we have no idea if it is a parameter-eating or paramless
|
||||||
* channel mode. That's actually pretty bad. This shouldn't happen since CHANMODES=
|
* channel mode. That's actually pretty bad. This shouldn't happen since CHANMODES=
|
||||||
* is sent since 2003 and the (often also required) EAUTH PROTOCTL is in there since 2010.
|
* is sent since 2003 and the (often also required) EAUTH PROTOCTL is in there since 2010.
|
||||||
|
@ -315,8 +315,8 @@ CMD_FUNC(cmd_nick_local)
|
|||||||
{
|
{
|
||||||
client->local->since += 4; /* lag them up */
|
client->local->since += 4; /* lag them up */
|
||||||
sendnumeric(client, ERR_ERRONEUSNICKNAME, nick, tklban->ptr.nameban->reason);
|
sendnumeric(client, ERR_ERRONEUSNICKNAME, nick, tklban->ptr.nameban->reason);
|
||||||
sendto_snomask(SNO_QLINE, "Forbidding Q-lined nick %s from %s.",
|
sendto_snomask(SNO_QLINE, "Forbidding Q-lined nick %s from %s (%s)",
|
||||||
nick, get_client_name(cptr, FALSE));
|
nick, get_client_name(cptr, FALSE), tklban->ptr.nameban->reason);
|
||||||
return; /* NICK message ignored */
|
return; /* NICK message ignored */
|
||||||
}
|
}
|
||||||
/* fallthrough for ircops that have sufficient privileges */
|
/* fallthrough for ircops that have sufficient privileges */
|
||||||
@ -866,6 +866,12 @@ int _register_user(Client *client, char *nick, char *username, char *umode, char
|
|||||||
/* Check G/Z lines before shuns -- kill before quite -- codemastr */
|
/* Check G/Z lines before shuns -- kill before quite -- codemastr */
|
||||||
if (find_tkline_match(client, 0))
|
if (find_tkline_match(client, 0))
|
||||||
{
|
{
|
||||||
|
if (!IsDead(client) && client->local->class)
|
||||||
|
{
|
||||||
|
/* Fix client count bug, in case that it was a hold such as via authprompt */
|
||||||
|
client->local->class->clients--;
|
||||||
|
client->local->class = NULL;
|
||||||
|
}
|
||||||
ircstats.is_ref++;
|
ircstats.is_ref++;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -892,7 +898,17 @@ int _register_user(Client *client, char *nick, char *username, char *umode, char
|
|||||||
{
|
{
|
||||||
i = (*(h->func.intfunc))(client);
|
i = (*(h->func.intfunc))(client);
|
||||||
if (i == HOOK_DENY)
|
if (i == HOOK_DENY)
|
||||||
|
{
|
||||||
|
if (!IsDead(client) && client->local->class)
|
||||||
|
{
|
||||||
|
/* Fix client count bug, in case that
|
||||||
|
* the HOOK_DENY was only meant temporarily.
|
||||||
|
*/
|
||||||
|
client->local->class->clients--;
|
||||||
|
client->local->class = NULL;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
if (i == HOOK_ALLOW)
|
if (i == HOOK_ALLOW)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1316,12 +1332,9 @@ int AllowClient(Client *client, char *username)
|
|||||||
|
|
||||||
for (aconf = conf_allow; aconf; aconf = aconf->next)
|
for (aconf = conf_allow; aconf; aconf = aconf->next)
|
||||||
{
|
{
|
||||||
if (!aconf->hostname || !aconf->ip)
|
|
||||||
goto attach;
|
|
||||||
if (aconf->auth && !client->local->passwd && !moddata_client_get(client, "certfp"))
|
|
||||||
continue;
|
|
||||||
if (aconf->flags.tls && !IsSecure(client))
|
if (aconf->flags.tls && !IsSecure(client))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (hp && hp->h_name)
|
if (hp && hp->h_name)
|
||||||
{
|
{
|
||||||
hname = hp->h_name;
|
hname = hp->h_name;
|
||||||
@ -1376,8 +1389,21 @@ int AllowClient(Client *client, char *username)
|
|||||||
goto attach;
|
goto attach;
|
||||||
}
|
}
|
||||||
|
|
||||||
continue;
|
continue; /* No match */
|
||||||
attach:
|
attach:
|
||||||
|
/* Check authentication */
|
||||||
|
if (aconf->auth && !Auth_Check(client, aconf->auth, client->local->passwd))
|
||||||
|
{
|
||||||
|
/* Incorrect password/authentication - but was is it required? */
|
||||||
|
if (aconf->flags.reject_on_auth_failure)
|
||||||
|
{
|
||||||
|
exit_client(client, NULL, iConf.reject_message_unauthorized);
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
continue; /* Continue (this is the default behavior) */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!aconf->flags.noident)
|
if (!aconf->flags.noident)
|
||||||
SetUseIdent(client);
|
SetUseIdent(client);
|
||||||
if (!aconf->flags.useip && hp)
|
if (!aconf->flags.useip && hp)
|
||||||
@ -1393,12 +1419,6 @@ int AllowClient(Client *client, char *username)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aconf->auth && !Auth_Check(client, aconf->auth, client->local->passwd))
|
|
||||||
{
|
|
||||||
/* Always continue if password was wrong. */
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!((aconf->class->clients + 1) > aconf->class->maxclients))
|
if (!((aconf->class->clients + 1) > aconf->class->maxclients))
|
||||||
{
|
{
|
||||||
client->local->class = aconf->class;
|
client->local->class = aconf->class;
|
||||||
|
@ -343,9 +343,9 @@ CMD_FUNC(cmd_protoctl)
|
|||||||
(long long)(TStime() - t));
|
(long long)(TStime() - t));
|
||||||
snprintf(msg, sizeof(msg),
|
snprintf(msg, sizeof(msg),
|
||||||
"Rejecting link %s: our clock is %lld seconds ahead. "
|
"Rejecting link %s: our clock is %lld seconds ahead. "
|
||||||
"Correct time is very important in IRC. Please "
|
"Please verify the clock on both %s (them) and %s (us). "
|
||||||
"verify the clock on both %s (them) and %s (us), "
|
"Correct time is very important for IRC servers, "
|
||||||
"fix it and then try linking again",
|
"see https://www.unrealircd.org/docs/FAQ#fix-your-clock",
|
||||||
get_client_name(client, TRUE),
|
get_client_name(client, TRUE),
|
||||||
(long long)(TStime() - t),
|
(long long)(TStime() - t),
|
||||||
client->name, me.name);
|
client->name, me.name);
|
||||||
@ -359,9 +359,9 @@ CMD_FUNC(cmd_protoctl)
|
|||||||
(long long)(t - TStime()));
|
(long long)(t - TStime()));
|
||||||
snprintf(msg, sizeof(msg),
|
snprintf(msg, sizeof(msg),
|
||||||
"Rejecting link %s: our clock is %lld seconds behind. "
|
"Rejecting link %s: our clock is %lld seconds behind. "
|
||||||
"Correct time is very important in IRC. Please "
|
"Please verify the clock on both %s (them) and %s (us). "
|
||||||
"verify the clock on both %s (them) and %s (us), "
|
"Correct time is very important for IRC servers, "
|
||||||
"fix it and then try linking again",
|
"see https://www.unrealircd.org/docs/FAQ#fix-your-clock",
|
||||||
get_client_name(client, TRUE),
|
get_client_name(client, TRUE),
|
||||||
(long long)(t - TStime()),
|
(long long)(t - TStime()),
|
||||||
client->name, me.name);
|
client->name, me.name);
|
||||||
|
@ -682,6 +682,107 @@ int count_reputation_records(void)
|
|||||||
return total;
|
return total;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void reputation_channel_query(Client *client, Channel *channel)
|
||||||
|
{
|
||||||
|
Member *m;
|
||||||
|
char buf[512];
|
||||||
|
char tbuf[256];
|
||||||
|
char **nicks;
|
||||||
|
int *scores;
|
||||||
|
int cnt = 0, i, j;
|
||||||
|
ReputationEntry *e;
|
||||||
|
|
||||||
|
sendtxtnumeric(client, "Users and reputation scores for %s:", channel->chname);
|
||||||
|
|
||||||
|
/* Step 1: build a list of nicks and their reputation */
|
||||||
|
nicks = safe_alloc((channel->users+1) * sizeof(char *));
|
||||||
|
scores = safe_alloc((channel->users+1) * sizeof(int));
|
||||||
|
for (m = channel->members; m; m = m->next)
|
||||||
|
{
|
||||||
|
nicks[cnt] = m->client->name;
|
||||||
|
if (m->client->ip)
|
||||||
|
{
|
||||||
|
e = find_reputation_entry(m->client->ip);
|
||||||
|
if (e)
|
||||||
|
scores[cnt] = e->score;
|
||||||
|
}
|
||||||
|
if (++cnt > channel->users)
|
||||||
|
{
|
||||||
|
sendto_ops("[BUG] reputation_channel_query() expected %d users but %d (or more) were present in %s",
|
||||||
|
channel->users, cnt, channel->chname);
|
||||||
|
#ifdef DEBUGMODE
|
||||||
|
abort();
|
||||||
|
#endif
|
||||||
|
break; /* safety net */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Step 2: lazy selection sort */
|
||||||
|
for (i = 0; i < cnt && nicks[i]; i++)
|
||||||
|
{
|
||||||
|
for (j = i+1; j < cnt && nicks[j]; j++)
|
||||||
|
{
|
||||||
|
if (scores[i] < scores[j])
|
||||||
|
{
|
||||||
|
char *nick_tmp;
|
||||||
|
int score_tmp;
|
||||||
|
nick_tmp = nicks[i];
|
||||||
|
score_tmp = scores[i];
|
||||||
|
nicks[i] = nicks[j];
|
||||||
|
scores[i] = scores[j];
|
||||||
|
nicks[j] = nick_tmp;
|
||||||
|
scores[j] = score_tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Step 3: send the (ordered) list to the user */
|
||||||
|
*buf = '\0';
|
||||||
|
for (i = 0; i < cnt && nicks[i]; i++)
|
||||||
|
{
|
||||||
|
snprintf(tbuf, sizeof(tbuf), "%s\00314(%d)\003 ", nicks[i], scores[i]);
|
||||||
|
if ((strlen(tbuf)+strlen(buf) > 400) || !nicks[i+1])
|
||||||
|
{
|
||||||
|
sendtxtnumeric(client, "%s%s", buf, tbuf);
|
||||||
|
*buf = '\0';
|
||||||
|
} else {
|
||||||
|
strlcat(buf, tbuf, sizeof(buf));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sendtxtnumeric(client, "End of list.");
|
||||||
|
safe_free(nicks);
|
||||||
|
safe_free(scores);
|
||||||
|
}
|
||||||
|
|
||||||
|
void reputation_list_query(Client *client, int maxscore)
|
||||||
|
{
|
||||||
|
Client *target;
|
||||||
|
ReputationEntry *e;
|
||||||
|
|
||||||
|
sendtxtnumeric(client, "Users and reputation scores <%d:", maxscore);
|
||||||
|
|
||||||
|
list_for_each_entry(target, &client_list, client_node)
|
||||||
|
{
|
||||||
|
int score = 0;
|
||||||
|
|
||||||
|
if (!IsUser(target) || IsULine(target) || !target->ip)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
e = find_reputation_entry(target->ip);
|
||||||
|
if (e)
|
||||||
|
score = e->score;
|
||||||
|
if (score >= maxscore)
|
||||||
|
continue;
|
||||||
|
sendtxtnumeric(client, "%s!%s@%s [%s] \017(score: %d)",
|
||||||
|
target->name,
|
||||||
|
target->user->username,
|
||||||
|
target->user->realhost,
|
||||||
|
target->ip,
|
||||||
|
score);
|
||||||
|
}
|
||||||
|
sendtxtnumeric(client, "End of list.");
|
||||||
|
}
|
||||||
|
|
||||||
CMD_FUNC(reputation_user_cmd)
|
CMD_FUNC(reputation_user_cmd)
|
||||||
{
|
{
|
||||||
ReputationEntry *e;
|
ReputationEntry *e;
|
||||||
@ -709,13 +810,45 @@ CMD_FUNC(reputation_user_cmd)
|
|||||||
}
|
}
|
||||||
sendnotice(client, "Current number of records (IP's): %d", count_reputation_records());
|
sendnotice(client, "Current number of records (IP's): %d", count_reputation_records());
|
||||||
sendnotice(client, "-");
|
sendnotice(client, "-");
|
||||||
sendnotice(client, "For more specific information, use: /REPUTATION [nick|IP-address]");
|
sendnotice(client, "Available commands:");
|
||||||
|
sendnotice(client, "/REPUTATION [nick] Show reputation info about nick name");
|
||||||
|
sendnotice(client, "/REPUTATION [ip] Show reputation info about IP address");
|
||||||
|
sendnotice(client, "/REPUTATION [channel] List users in channel along with their reputation score");
|
||||||
|
sendnotice(client, "/REPUTATION <NN List users with reputation score below value NN");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strchr(parv[1], '.') || strchr(parv[1], ':'))
|
if (strchr(parv[1], '.') || strchr(parv[1], ':'))
|
||||||
{
|
{
|
||||||
ip = parv[1];
|
ip = parv[1];
|
||||||
|
} else
|
||||||
|
if (parv[1][0] == '#')
|
||||||
|
{
|
||||||
|
Channel *channel = find_channel(parv[1], NULL);
|
||||||
|
if (!channel)
|
||||||
|
{
|
||||||
|
sendnumeric(client, ERR_NOSUCHCHANNEL, parv[1]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* corner case: ircop without proper permissions and not in channel */
|
||||||
|
if (!ValidatePermissionsForPath("channel:see:names:invisible",client,NULL,NULL,NULL) && !get_access(client,channel))
|
||||||
|
{
|
||||||
|
sendnumeric(client, ERR_NOTONCHANNEL, channel->chname);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
reputation_channel_query(client, channel);
|
||||||
|
return;
|
||||||
|
} else
|
||||||
|
if (parv[1][0] == '<')
|
||||||
|
{
|
||||||
|
int max = atoi(parv[1] + 1);
|
||||||
|
if (max < 1)
|
||||||
|
{
|
||||||
|
sendnotice(client, "REPUTATION: Invalid search value specified. Use for example '/REPUTATION <5' to search on less-than-five");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
reputation_list_query(client, max);
|
||||||
|
return;
|
||||||
} else {
|
} else {
|
||||||
Client *target = find_person(parv[1], NULL);
|
Client *target = find_person(parv[1], NULL);
|
||||||
if (!target)
|
if (!target)
|
||||||
|
@ -27,8 +27,6 @@ ModuleHeader MOD_HEADER = {
|
|||||||
"unrealircd-5",
|
"unrealircd-5",
|
||||||
};
|
};
|
||||||
|
|
||||||
#define GetReputation(client) (moddata_client_get(client, "reputation") ? atoi(moddata_client_get(client, "reputation")) : 0)
|
|
||||||
|
|
||||||
typedef struct RestrictedCommand RestrictedCommand;
|
typedef struct RestrictedCommand RestrictedCommand;
|
||||||
struct RestrictedCommand {
|
struct RestrictedCommand {
|
||||||
RestrictedCommand *prev, *next;
|
RestrictedCommand *prev, *next;
|
||||||
|
@ -462,22 +462,25 @@ int stats_denylinkall(Client *client, char *para)
|
|||||||
|
|
||||||
int stats_gline(Client *client, char *para)
|
int stats_gline(Client *client, char *para)
|
||||||
{
|
{
|
||||||
tkl_stats(client, TKL_GLOBAL|TKL_KILL, para);
|
int cnt = 0;
|
||||||
tkl_stats(client, TKL_GLOBAL|TKL_ZAP, para);
|
tkl_stats(client, TKL_GLOBAL|TKL_KILL, para, &cnt);
|
||||||
|
tkl_stats(client, TKL_GLOBAL|TKL_ZAP, para, &cnt);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int stats_spamfilter(Client *client, char *para)
|
int stats_spamfilter(Client *client, char *para)
|
||||||
{
|
{
|
||||||
tkl_stats(client, TKL_SPAMF, para);
|
int cnt = 0;
|
||||||
tkl_stats(client, TKL_GLOBAL|TKL_SPAMF, para);
|
tkl_stats(client, TKL_SPAMF, para, &cnt);
|
||||||
|
tkl_stats(client, TKL_GLOBAL|TKL_SPAMF, para, &cnt);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int stats_except(Client *client, char *para)
|
int stats_except(Client *client, char *para)
|
||||||
{
|
{
|
||||||
tkl_stats(client, TKL_EXCEPTION, para);
|
int cnt = 0;
|
||||||
tkl_stats(client, TKL_EXCEPTION|TKL_GLOBAL, para);
|
tkl_stats(client, TKL_EXCEPTION, para, &cnt);
|
||||||
|
tkl_stats(client, TKL_EXCEPTION|TKL_GLOBAL, para, &cnt);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -564,8 +567,9 @@ int stats_port(Client *client, char *para)
|
|||||||
|
|
||||||
int stats_bannick(Client *client, char *para)
|
int stats_bannick(Client *client, char *para)
|
||||||
{
|
{
|
||||||
tkl_stats(client, TKL_NAME, para);
|
int cnt = 0;
|
||||||
tkl_stats(client, TKL_GLOBAL|TKL_NAME, para);
|
tkl_stats(client, TKL_NAME, para, &cnt);
|
||||||
|
tkl_stats(client, TKL_GLOBAL|TKL_NAME, para, &cnt);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -699,8 +703,9 @@ int stats_denylinkauto(Client *client, char *para)
|
|||||||
|
|
||||||
int stats_kline(Client *client, char *para)
|
int stats_kline(Client *client, char *para)
|
||||||
{
|
{
|
||||||
tkl_stats(client, TKL_KILL, NULL);
|
int cnt = 0;
|
||||||
tkl_stats(client, TKL_ZAP, NULL);
|
tkl_stats(client, TKL_KILL, NULL, &cnt);
|
||||||
|
tkl_stats(client, TKL_ZAP, NULL, &cnt);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -720,7 +725,8 @@ int stats_banrealname(Client *client, char *para)
|
|||||||
|
|
||||||
int stats_sqline(Client *client, char *para)
|
int stats_sqline(Client *client, char *para)
|
||||||
{
|
{
|
||||||
tkl_stats(client, TKL_NAME|TKL_GLOBAL, para);
|
int cnt = 0;
|
||||||
|
tkl_stats(client, TKL_NAME|TKL_GLOBAL, para, &cnt);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -741,7 +747,8 @@ int stats_chanrestrict(Client *client, char *para)
|
|||||||
|
|
||||||
int stats_shun(Client *client, char *para)
|
int stats_shun(Client *client, char *para)
|
||||||
{
|
{
|
||||||
tkl_stats(client, TKL_GLOBAL|TKL_SHUN, para);
|
int cnt = 0;
|
||||||
|
tkl_stats(client, TKL_GLOBAL|TKL_SHUN, para, &cnt);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -234,8 +234,8 @@ int targetfloodprot_can_send_to_channel(Client *client, Channel *channel, Member
|
|||||||
if (!MyUser(client))
|
if (!MyUser(client))
|
||||||
return HOOK_CONTINUE;
|
return HOOK_CONTINUE;
|
||||||
|
|
||||||
/* Really, only IRCOps override */
|
/* IRCOps and U-Lines override */
|
||||||
if (IsOper(client) && ValidatePermissionsForPath("immune:target-flood",client,NULL,channel,NULL))
|
if (IsULine(client) || (IsOper(client) && ValidatePermissionsForPath("immune:target-flood",client,NULL,channel,NULL)))
|
||||||
return HOOK_CONTINUE;
|
return HOOK_CONTINUE;
|
||||||
|
|
||||||
what = sendtypetowhat(sendtype);
|
what = sendtypetowhat(sendtype);
|
||||||
@ -280,8 +280,8 @@ int targetfloodprot_can_send_to_user(Client *client, Client *target, char **text
|
|||||||
if (!MyUser(target))
|
if (!MyUser(target))
|
||||||
return HOOK_CONTINUE;
|
return HOOK_CONTINUE;
|
||||||
|
|
||||||
/* Really, only IRCOps override */
|
/* IRCOps and U-Lines override */
|
||||||
if (IsOper(client) && ValidatePermissionsForPath("immune:target-flood",client,target,NULL,NULL))
|
if (IsULine(client) || (IsOper(client) && ValidatePermissionsForPath("immune:target-flood",client,target,NULL,NULL)))
|
||||||
return HOOK_CONTINUE;
|
return HOOK_CONTINUE;
|
||||||
|
|
||||||
what = sendtypetowhat(sendtype);
|
what = sendtypetowhat(sendtype);
|
||||||
|
@ -39,6 +39,8 @@ int tkl_config_test_ban(ConfigFile *, ConfigEntry *, int, int *);
|
|||||||
int tkl_config_run_ban(ConfigFile *, ConfigEntry *, int);
|
int tkl_config_run_ban(ConfigFile *, ConfigEntry *, int);
|
||||||
int tkl_config_test_except(ConfigFile *, ConfigEntry *, int, int *);
|
int tkl_config_test_except(ConfigFile *, ConfigEntry *, int, int *);
|
||||||
int tkl_config_run_except(ConfigFile *, ConfigEntry *, int);
|
int tkl_config_run_except(ConfigFile *, ConfigEntry *, int);
|
||||||
|
int tkl_config_test_set(ConfigFile *, ConfigEntry *, int, int *);
|
||||||
|
int tkl_config_run_set(ConfigFile *, ConfigEntry *, int);
|
||||||
CMD_FUNC(cmd_gline);
|
CMD_FUNC(cmd_gline);
|
||||||
CMD_FUNC(cmd_shun);
|
CMD_FUNC(cmd_shun);
|
||||||
CMD_FUNC(cmd_tempshun);
|
CMD_FUNC(cmd_tempshun);
|
||||||
@ -76,7 +78,7 @@ int _find_shun(Client *client);
|
|||||||
int _find_spamfilter_user(Client *client, int flags);
|
int _find_spamfilter_user(Client *client, int flags);
|
||||||
TKL *_find_qline(Client *client, char *nick, int *ishold);
|
TKL *_find_qline(Client *client, char *nick, int *ishold);
|
||||||
TKL *_find_tkline_match_zap(Client *client);
|
TKL *_find_tkline_match_zap(Client *client);
|
||||||
void _tkl_stats(Client *client, int type, char *para);
|
void _tkl_stats(Client *client, int type, char *para, int *cnt);
|
||||||
void _tkl_sync(Client *client);
|
void _tkl_sync(Client *client);
|
||||||
CMD_FUNC(_cmd_tkl);
|
CMD_FUNC(_cmd_tkl);
|
||||||
int _place_host_ban(Client *client, BanAction action, char *reason, long duration);
|
int _place_host_ban(Client *client, BanAction action, char *reason, long duration);
|
||||||
@ -142,12 +144,15 @@ TKLTypeTable tkl_types[] = {
|
|||||||
};
|
};
|
||||||
#define ALL_VALID_EXCEPTION_TYPES "kline, gline, zline, gzline, spamfilter, shun, qline, blacklist, connect-flood, unknown-data-flood, antirandom, antimixedutf8, ban-version"
|
#define ALL_VALID_EXCEPTION_TYPES "kline, gline, zline, gzline, spamfilter, shun, qline, blacklist, connect-flood, unknown-data-flood, antirandom, antimixedutf8, ban-version"
|
||||||
|
|
||||||
|
int max_stats_matches = 1000;
|
||||||
|
|
||||||
MOD_TEST()
|
MOD_TEST()
|
||||||
{
|
{
|
||||||
MARK_AS_OFFICIAL_MODULE(modinfo);
|
MARK_AS_OFFICIAL_MODULE(modinfo);
|
||||||
HookAdd(modinfo->handle, HOOKTYPE_CONFIGTEST, 0, tkl_config_test_spamfilter);
|
HookAdd(modinfo->handle, HOOKTYPE_CONFIGTEST, 0, tkl_config_test_spamfilter);
|
||||||
HookAdd(modinfo->handle, HOOKTYPE_CONFIGTEST, 0, tkl_config_test_ban);
|
HookAdd(modinfo->handle, HOOKTYPE_CONFIGTEST, 0, tkl_config_test_ban);
|
||||||
HookAdd(modinfo->handle, HOOKTYPE_CONFIGTEST, 0, tkl_config_test_except);
|
HookAdd(modinfo->handle, HOOKTYPE_CONFIGTEST, 0, tkl_config_test_except);
|
||||||
|
HookAdd(modinfo->handle, HOOKTYPE_CONFIGTEST, 0, tkl_config_test_set);
|
||||||
EfunctionAdd(modinfo->handle, EFUNC_TKL_HASH, _tkl_hash);
|
EfunctionAdd(modinfo->handle, EFUNC_TKL_HASH, _tkl_hash);
|
||||||
EfunctionAdd(modinfo->handle, EFUNC_TKL_TYPETOCHAR, TO_INTFUNC(_tkl_typetochar));
|
EfunctionAdd(modinfo->handle, EFUNC_TKL_TYPETOCHAR, TO_INTFUNC(_tkl_typetochar));
|
||||||
EfunctionAdd(modinfo->handle, EFUNC_TKL_CHARTOTYPE, TO_INTFUNC(_tkl_chartotype));
|
EfunctionAdd(modinfo->handle, EFUNC_TKL_CHARTOTYPE, TO_INTFUNC(_tkl_chartotype));
|
||||||
@ -190,6 +195,7 @@ MOD_INIT()
|
|||||||
HookAdd(modinfo->handle, HOOKTYPE_CONFIGRUN, 0, tkl_config_match_spamfilter);
|
HookAdd(modinfo->handle, HOOKTYPE_CONFIGRUN, 0, tkl_config_match_spamfilter);
|
||||||
HookAdd(modinfo->handle, HOOKTYPE_CONFIGRUN, 0, tkl_config_run_ban);
|
HookAdd(modinfo->handle, HOOKTYPE_CONFIGRUN, 0, tkl_config_run_ban);
|
||||||
HookAdd(modinfo->handle, HOOKTYPE_CONFIGRUN, 0, tkl_config_run_except);
|
HookAdd(modinfo->handle, HOOKTYPE_CONFIGRUN, 0, tkl_config_run_except);
|
||||||
|
HookAdd(modinfo->handle, HOOKTYPE_CONFIGRUN, 0, tkl_config_run_set);
|
||||||
CommandAdd(modinfo->handle, "GLINE", cmd_gline, 3, CMD_OPER);
|
CommandAdd(modinfo->handle, "GLINE", cmd_gline, 3, CMD_OPER);
|
||||||
CommandAdd(modinfo->handle, "SHUN", cmd_shun, 3, CMD_OPER);
|
CommandAdd(modinfo->handle, "SHUN", cmd_shun, 3, CMD_OPER);
|
||||||
CommandAdd(modinfo->handle, "TEMPSHUN", cmd_tempshun, 2, CMD_OPER);
|
CommandAdd(modinfo->handle, "TEMPSHUN", cmd_tempshun, 2, CMD_OPER);
|
||||||
@ -902,6 +908,44 @@ int tkl_config_run_except(ConfigFile *cf, ConfigEntry *ce, int configtype)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int tkl_config_test_set(ConfigFile *cf, ConfigEntry *ce, int configtype, int *errs)
|
||||||
|
{
|
||||||
|
int errors = 0;
|
||||||
|
|
||||||
|
/* We are only interested in set { } blocks */
|
||||||
|
if (configtype != CONFIG_SET)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!strcmp(ce->ce_varname, "max-stats-matches"))
|
||||||
|
{
|
||||||
|
if (!ce->ce_vardata)
|
||||||
|
{
|
||||||
|
config_error("%s:%i: set::max-stats-matches: no value specified",
|
||||||
|
ce->ce_fileptr->cf_filename, ce->ce_varlinenum);
|
||||||
|
errors++;
|
||||||
|
}
|
||||||
|
// allow any other value, including 0 and negative.
|
||||||
|
*errs = errors;
|
||||||
|
return errors ? -1 : 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int tkl_config_run_set(ConfigFile *cf, ConfigEntry *ce, int configtype)
|
||||||
|
{
|
||||||
|
/* We are only interested in set { } blocks */
|
||||||
|
if (configtype != CONFIG_SET)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!strcmp(ce->ce_varname, "max-stats-matches"))
|
||||||
|
{
|
||||||
|
max_stats_matches = atoi(ce->ce_vardata);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/** Return unique spamfilter id for TKL */
|
/** Return unique spamfilter id for TKL */
|
||||||
char *spamfilter_id(TKL *tk)
|
char *spamfilter_id(TKL *tk)
|
||||||
{
|
{
|
||||||
@ -1269,7 +1313,7 @@ void cmd_tkl_line(Client *client, int parc, char *parv[], char *type)
|
|||||||
mask++;
|
mask++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strchr(mask, '!'))
|
if ((*mask != '~') && strchr(mask, '!'))
|
||||||
{
|
{
|
||||||
sendnotice(client, "[error] Cannot have '!' in masks.");
|
sendnotice(client, "[error] Cannot have '!' in masks.");
|
||||||
return;
|
return;
|
||||||
@ -1590,7 +1634,7 @@ CMD_FUNC(cmd_eline)
|
|||||||
reason = parv[4];
|
reason = parv[4];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strchr(mask, '!'))
|
if ((*mask != '~') && strchr(mask, '!'))
|
||||||
{
|
{
|
||||||
sendnotice(client, "[error] Cannot have '!' in masks.");
|
sendnotice(client, "[error] Cannot have '!' in masks.");
|
||||||
return;
|
return;
|
||||||
@ -3298,7 +3342,7 @@ static void parse_stats_params(char *para, TKLFlag *flag)
|
|||||||
/** Does this TKL entry match the search terms?
|
/** Does this TKL entry match the search terms?
|
||||||
* This is a helper function for tkl_stats().
|
* This is a helper function for tkl_stats().
|
||||||
*/
|
*/
|
||||||
void tkl_stats_matcher(Client *client, int type, char *para, TKLFlag *tklflags, TKL *tkl)
|
int tkl_stats_matcher(Client *client, int type, char *para, TKLFlag *tklflags, TKL *tkl)
|
||||||
{
|
{
|
||||||
/***** First, handle the selection ******/
|
/***** First, handle the selection ******/
|
||||||
|
|
||||||
@ -3306,66 +3350,66 @@ void tkl_stats_matcher(Client *client, int type, char *para, TKLFlag *tklflags,
|
|||||||
{
|
{
|
||||||
if (tklflags->flags & BY_SETBY)
|
if (tklflags->flags & BY_SETBY)
|
||||||
if (!match_simple(tklflags->set_by, tkl->set_by))
|
if (!match_simple(tklflags->set_by, tkl->set_by))
|
||||||
return;
|
return 0;
|
||||||
if (tklflags->flags & NOT_BY_SETBY)
|
if (tklflags->flags & NOT_BY_SETBY)
|
||||||
if (match_simple(tklflags->set_by, tkl->set_by))
|
if (match_simple(tklflags->set_by, tkl->set_by))
|
||||||
return;
|
return 0;
|
||||||
if (TKLIsServerBan(tkl))
|
if (TKLIsServerBan(tkl))
|
||||||
{
|
{
|
||||||
if (tklflags->flags & BY_MASK)
|
if (tklflags->flags & BY_MASK)
|
||||||
{
|
{
|
||||||
if (!match_simple(tklflags->mask, make_user_host(tkl->ptr.serverban->usermask, tkl->ptr.serverban->hostmask)))
|
if (!match_simple(tklflags->mask, make_user_host(tkl->ptr.serverban->usermask, tkl->ptr.serverban->hostmask)))
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
if (tklflags->flags & NOT_BY_MASK)
|
if (tklflags->flags & NOT_BY_MASK)
|
||||||
{
|
{
|
||||||
if (match_simple(tklflags->mask, make_user_host(tkl->ptr.serverban->usermask, tkl->ptr.serverban->hostmask)))
|
if (match_simple(tklflags->mask, make_user_host(tkl->ptr.serverban->usermask, tkl->ptr.serverban->hostmask)))
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
if (tklflags->flags & BY_REASON)
|
if (tklflags->flags & BY_REASON)
|
||||||
if (!match_simple(tklflags->reason, tkl->ptr.serverban->reason))
|
if (!match_simple(tklflags->reason, tkl->ptr.serverban->reason))
|
||||||
return;
|
return 0;
|
||||||
if (tklflags->flags & NOT_BY_REASON)
|
if (tklflags->flags & NOT_BY_REASON)
|
||||||
if (match_simple(tklflags->reason, tkl->ptr.serverban->reason))
|
if (match_simple(tklflags->reason, tkl->ptr.serverban->reason))
|
||||||
return;
|
return 0;
|
||||||
} else
|
} else
|
||||||
if (TKLIsNameBan(tkl))
|
if (TKLIsNameBan(tkl))
|
||||||
{
|
{
|
||||||
if (tklflags->flags & BY_MASK)
|
if (tklflags->flags & BY_MASK)
|
||||||
{
|
{
|
||||||
if (!match_simple(tklflags->mask, tkl->ptr.nameban->name))
|
if (!match_simple(tklflags->mask, tkl->ptr.nameban->name))
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
if (tklflags->flags & NOT_BY_MASK)
|
if (tklflags->flags & NOT_BY_MASK)
|
||||||
{
|
{
|
||||||
if (match_simple(tklflags->mask, tkl->ptr.nameban->name))
|
if (match_simple(tklflags->mask, tkl->ptr.nameban->name))
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
if (tklflags->flags & BY_REASON)
|
if (tklflags->flags & BY_REASON)
|
||||||
if (!match_simple(tklflags->reason, tkl->ptr.nameban->reason))
|
if (!match_simple(tklflags->reason, tkl->ptr.nameban->reason))
|
||||||
return;
|
return 0;
|
||||||
if (tklflags->flags & NOT_BY_REASON)
|
if (tklflags->flags & NOT_BY_REASON)
|
||||||
if (match_simple(tklflags->reason, tkl->ptr.nameban->reason))
|
if (match_simple(tklflags->reason, tkl->ptr.nameban->reason))
|
||||||
return;
|
return 0;
|
||||||
} else
|
} else
|
||||||
if (TKLIsBanException(tkl))
|
if (TKLIsBanException(tkl))
|
||||||
{
|
{
|
||||||
if (tklflags->flags & BY_MASK)
|
if (tklflags->flags & BY_MASK)
|
||||||
{
|
{
|
||||||
if (!match_simple(tklflags->mask, make_user_host(tkl->ptr.banexception->usermask, tkl->ptr.banexception->hostmask)))
|
if (!match_simple(tklflags->mask, make_user_host(tkl->ptr.banexception->usermask, tkl->ptr.banexception->hostmask)))
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
if (tklflags->flags & NOT_BY_MASK)
|
if (tklflags->flags & NOT_BY_MASK)
|
||||||
{
|
{
|
||||||
if (match_simple(tklflags->mask, make_user_host(tkl->ptr.banexception->usermask, tkl->ptr.banexception->hostmask)))
|
if (match_simple(tklflags->mask, make_user_host(tkl->ptr.banexception->usermask, tkl->ptr.banexception->hostmask)))
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
if (tklflags->flags & BY_REASON)
|
if (tklflags->flags & BY_REASON)
|
||||||
if (!match_simple(tklflags->reason, tkl->ptr.banexception->reason))
|
if (!match_simple(tklflags->reason, tkl->ptr.banexception->reason))
|
||||||
return;
|
return 0;
|
||||||
if (tklflags->flags & NOT_BY_REASON)
|
if (tklflags->flags & NOT_BY_REASON)
|
||||||
if (match_simple(tklflags->reason, tkl->ptr.banexception->reason))
|
if (match_simple(tklflags->reason, tkl->ptr.banexception->reason))
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3444,16 +3488,24 @@ void tkl_stats_matcher(Client *client, int type, char *para, TKLFlag *tklflags,
|
|||||||
tkl->ptr.banexception->bantypes,
|
tkl->ptr.banexception->bantypes,
|
||||||
(tkl->expire_at != 0) ? (tkl->expire_at - TStime()) : 0,
|
(tkl->expire_at != 0) ? (tkl->expire_at - TStime()) : 0,
|
||||||
(TStime() - tkl->set_at), tkl->set_by, tkl->ptr.banexception->reason);
|
(TStime() - tkl->set_at), tkl->set_by, tkl->ptr.banexception->reason);
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
/* That's weird, unknown TKL type */
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TKL Stats. This is used by /STATS gline and all the others */
|
/* TKL Stats. This is used by /STATS gline and all the others */
|
||||||
void _tkl_stats(Client *client, int type, char *para)
|
void _tkl_stats(Client *client, int type, char *para, int *cnt)
|
||||||
{
|
{
|
||||||
TKL *tk;
|
TKL *tk;
|
||||||
TKLFlag tklflags;
|
TKLFlag tklflags;
|
||||||
int index, index2;
|
int index, index2;
|
||||||
|
|
||||||
|
if ((max_stats_matches > 0) && (*cnt >= max_stats_matches))
|
||||||
|
return;
|
||||||
|
|
||||||
if (!BadPtr(para))
|
if (!BadPtr(para))
|
||||||
parse_stats_params(para, &tklflags);
|
parse_stats_params(para, &tklflags);
|
||||||
|
|
||||||
@ -3467,7 +3519,16 @@ void _tkl_stats(Client *client, int type, char *para)
|
|||||||
{
|
{
|
||||||
if (type && tk->type != type)
|
if (type && tk->type != type)
|
||||||
continue;
|
continue;
|
||||||
tkl_stats_matcher(client, type, para, &tklflags, tk);
|
if (tkl_stats_matcher(client, type, para, &tklflags, tk))
|
||||||
|
{
|
||||||
|
*cnt += 1;
|
||||||
|
if ((max_stats_matches > 0) && (*cnt >= max_stats_matches))
|
||||||
|
{
|
||||||
|
sendnumeric(client, ERR_TOOMANYMATCHES, "STATS", "too many matches (set::max-stats-matches)");
|
||||||
|
sendnotice(client, "Consider searching on something more specific, eg '/STATS gline +m *.nl'. See '/STATS' (without parameters) for help.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3479,7 +3540,16 @@ void _tkl_stats(Client *client, int type, char *para)
|
|||||||
{
|
{
|
||||||
if (type && tk->type != type)
|
if (type && tk->type != type)
|
||||||
continue;
|
continue;
|
||||||
tkl_stats_matcher(client, type, para, &tklflags, tk);
|
if (tkl_stats_matcher(client, type, para, &tklflags, tk))
|
||||||
|
{
|
||||||
|
*cnt += 1;
|
||||||
|
if ((max_stats_matches > 0) && (*cnt >= max_stats_matches))
|
||||||
|
{
|
||||||
|
sendnumeric(client, ERR_TOOMANYMATCHES, "STATS", "too many matches (set::max-stats-matches)");
|
||||||
|
sendnotice(client, "Consider searching on something more specific, eg '/STATS gline +m *.nl'. See '/STATS' (without parameters) for help.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -351,45 +351,6 @@ CMD_FUNC(cmd_whox)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* '/who nick' */
|
|
||||||
if (((acptr = find_person(mask, NULL)) != NULL) &&
|
|
||||||
(!(fmt.matchsel & WMATCH_MODES)) &&
|
|
||||||
(!(fmt.matchsel & WMATCH_OPER) || IsOper(acptr)))
|
|
||||||
{
|
|
||||||
int isinvis = 0;
|
|
||||||
int i = 0;
|
|
||||||
Hook *h;
|
|
||||||
|
|
||||||
isinvis = IsInvisible(acptr);
|
|
||||||
for (lp = acptr->user->channel; lp; lp = lp->next)
|
|
||||||
{
|
|
||||||
member = IsMember(client, lp->channel);
|
|
||||||
|
|
||||||
if (isinvis && !member)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
for (h = Hooks[HOOKTYPE_VISIBLE_IN_CHANNEL]; h; h = h->next)
|
|
||||||
{
|
|
||||||
i = (*(h->func.intfunc))(acptr,lp->channel);
|
|
||||||
if (i != 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i != 0 && !(is_skochanop(client, lp->channel)) && !(is_skochanop(acptr, lp->channel) || has_voice(acptr,lp->channel)))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (member || (!isinvis && PubChannel(lp->channel)))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (lp != NULL)
|
|
||||||
do_who(client, acptr, lp->channel, &fmt);
|
|
||||||
else
|
|
||||||
do_who(client, acptr, NULL, &fmt);
|
|
||||||
|
|
||||||
sendnumeric(client, RPL_ENDOFWHO, orig_mask);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ValidatePermissionsForPath("channel:see:who:secret",client,NULL,NULL,NULL) ||
|
if (ValidatePermissionsForPath("channel:see:who:secret",client,NULL,NULL,NULL) ||
|
||||||
ValidatePermissionsForPath("channel:see:whois",client,NULL,NULL,NULL))
|
ValidatePermissionsForPath("channel:see:whois",client,NULL,NULL,NULL))
|
||||||
{
|
{
|
||||||
@ -561,9 +522,14 @@ static void who_common_channel(Client *client, Channel *channel,
|
|||||||
|
|
||||||
static void who_global(Client *client, char *mask, int operspy, struct who_format *fmt)
|
static void who_global(Client *client, char *mask, int operspy, struct who_format *fmt)
|
||||||
{
|
{
|
||||||
|
Client *hunted = NULL;
|
||||||
Client *acptr;
|
Client *acptr;
|
||||||
int maxmatches = IsOper(client) ? INT_MAX : WHOLIMIT;
|
int maxmatches = IsOper(client) ? INT_MAX : WHOLIMIT;
|
||||||
|
|
||||||
|
/* If searching for a nick explicitly, then include it later on in the result: */
|
||||||
|
if (mask && ((fmt->matchsel & WMATCH_NICK) || (fmt->matchsel == 0)))
|
||||||
|
hunted = find_person(mask, NULL);
|
||||||
|
|
||||||
/* Initialize the markers to zero */
|
/* Initialize the markers to zero */
|
||||||
list_for_each_entry(acptr, &client_list, client_node)
|
list_for_each_entry(acptr, &client_list, client_node)
|
||||||
ClearMark(acptr);
|
ClearMark(acptr);
|
||||||
@ -583,7 +549,7 @@ static void who_global(Client *client, char *mask, int operspy, struct who_forma
|
|||||||
if (!IsUser(acptr))
|
if (!IsUser(acptr))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (IsInvisible(acptr) && !operspy && (client != acptr))
|
if (IsInvisible(acptr) && !operspy && (client != acptr) && (acptr != hunted))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (IsMarked(acptr))
|
if (IsMarked(acptr))
|
||||||
|
@ -417,7 +417,10 @@ static void parse2(Client *cptr, Client **fromptr, MessageTag *mtags, char *ch)
|
|||||||
/* If you're a user, and this command does not permit users or opers, deny */
|
/* If you're a user, and this command does not permit users or opers, deny */
|
||||||
if ((flags & CMD_USER) && !(cmptr->flags & CMD_USER) && !(cmptr->flags & CMD_OPER))
|
if ((flags & CMD_USER) && !(cmptr->flags & CMD_USER) && !(cmptr->flags & CMD_OPER))
|
||||||
{
|
{
|
||||||
sendnumeric(cptr, ERR_NOTFORUSERS, cmptr->cmd);
|
if (cmptr->flags & CMD_UNREGISTERED)
|
||||||
|
sendnumeric(cptr, ERR_ALREADYREGISTRED); /* only for unregistered phase */
|
||||||
|
else
|
||||||
|
sendnumeric(cptr, ERR_NOTFORUSERS, cmptr->cmd); /* really never for users */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
399
src/send.c
399
src/send.c
@ -164,11 +164,29 @@ void mark_data_to_send(Client *to)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Send data to clients, servers, channels, IRCOps, etc.
|
||||||
|
* There are a lot of send functions. The most commonly functions
|
||||||
|
* are: sendto_one() to send to an individual user,
|
||||||
|
* sendnumeric() to send a numeric to an individual user
|
||||||
|
* and sendto_channel() to send a message to a channel.
|
||||||
|
* @defgroup SendFunctions Send functions
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
/** Send a message to a single client.
|
/** Send a message to a single client.
|
||||||
|
* This function is used quite a lot, after sendnumeric() it is the most-used send function.
|
||||||
* @param to The client to send to
|
* @param to The client to send to
|
||||||
* @param mtags Any message tags associated with this message (can be NULL)
|
* @param mtags Any message tags associated with this message (can be NULL)
|
||||||
* @param pattern The format string / pattern to use.
|
* @param pattern The format string / pattern to use.
|
||||||
* @param ... Format string parameters.
|
* @param ... Format string parameters.
|
||||||
|
* @section sendto_one_examples Examples
|
||||||
|
* @subsection sendto_one_mode_r Send "MODE -r"
|
||||||
|
* This will send the `:serv.er.name MODE yournick -r` message.
|
||||||
|
* Note that it will send only this message to illustrate the sendto_one() function.
|
||||||
|
* It does *not* set anyone actually -r.
|
||||||
|
* @code
|
||||||
|
* sendto_one(client, NULL, ":%s MODE %s :-r", me.name, client->name);
|
||||||
|
* @endcode
|
||||||
*/
|
*/
|
||||||
void sendto_one(Client *to, MessageTag *mtags, FORMAT_STRING(const char *pattern), ...)
|
void sendto_one(Client *to, MessageTag *mtags, FORMAT_STRING(const char *pattern), ...)
|
||||||
{
|
{
|
||||||
@ -180,8 +198,8 @@ void sendto_one(Client *to, MessageTag *mtags, FORMAT_STRING(const char *pattern
|
|||||||
|
|
||||||
/** Send a message to a single client - va_list variant.
|
/** Send a message to a single client - va_list variant.
|
||||||
* This function is similar to sendto_one() except that it
|
* This function is similar to sendto_one() except that it
|
||||||
* doesn't use varargs but a va_list instead.
|
* doesn't use varargs but uses a va_list instead.
|
||||||
* Generally this is NOT used outside send.c, so not by modules.
|
* Generally this function is NOT used outside send.c, so not by modules.
|
||||||
* @param to The client to send to
|
* @param to The client to send to
|
||||||
* @param mtags Any message tags associated with this message (can be NULL)
|
* @param mtags Any message tags associated with this message (can be NULL)
|
||||||
* @param pattern The format string / pattern to use.
|
* @param pattern The format string / pattern to use.
|
||||||
@ -363,9 +381,9 @@ void sendbufto_one(Client *to, char *msg, unsigned int quick)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** A single function to send data to a channel.
|
/** A single function to send data to a channel.
|
||||||
* Previously there were 6, now there is 1. This means there
|
* Previously there were 6 different functions to send channel data,
|
||||||
* are likely some parameters that you will pass as NULL or 0
|
* now there is 1 single function. This also means that you most
|
||||||
* but at least we can all use one single function.
|
* likely will pass NULL or 0 as some parameters.
|
||||||
* @param channel The channel to send to
|
* @param channel The channel to send to
|
||||||
* @param from The source of the message
|
* @param from The source of the message
|
||||||
* @param skip The client to skip (can be NULL).
|
* @param skip The client to skip (can be NULL).
|
||||||
@ -380,6 +398,36 @@ void sendbufto_one(Client *to, char *msg, unsigned int quick)
|
|||||||
* @param mtags The message tags to attach to this message
|
* @param mtags The message tags to attach to this message
|
||||||
* @param pattern The pattern (eg: ":%s PRIVMSG %s :%s")
|
* @param pattern The pattern (eg: ":%s PRIVMSG %s :%s")
|
||||||
* @param ... The parameters for the pattern.
|
* @param ... The parameters for the pattern.
|
||||||
|
* @note For all channel messages, it is important to attach the correct
|
||||||
|
* message tags (mtags) via a new_message() call, as can be seen
|
||||||
|
* in the example.
|
||||||
|
* @section sendto_channel_examples Examples
|
||||||
|
* @subsection sendto_channel_privmsg Send a PRIVMSG to a channel
|
||||||
|
* This command will send the message "Hello everyone!!!" to the channel when executed.
|
||||||
|
* @code
|
||||||
|
* CMD_FUNC(cmd_sayhello)
|
||||||
|
* {
|
||||||
|
* MessageTag *mtags = NULL;
|
||||||
|
* Channel *channel = NULL;
|
||||||
|
* if ((parc < 2) || BadPtr(parv[1]))
|
||||||
|
* {
|
||||||
|
* sendnumeric(client, ERR_NEEDMOREPARAMS, "SAYHELLO");
|
||||||
|
* return;
|
||||||
|
* }
|
||||||
|
* channel = find_channel(parv[1], NULL);
|
||||||
|
* if (!channel)
|
||||||
|
* {
|
||||||
|
* sendnumeric(client, ERR_NOSUCHCHANNEL, parv[1]);
|
||||||
|
* return;
|
||||||
|
* }
|
||||||
|
* new_message(client, recv_mtags, &mtags);
|
||||||
|
* sendto_channel(channel, client, client->direction, 0, 0,
|
||||||
|
* SEND_LOCAL|SEND_REMOTE, mtags,
|
||||||
|
* ":%s PRIVMSG %s :Hello everyone!!!",
|
||||||
|
* client->name, channel->name);
|
||||||
|
* free_message_tags(mtags);
|
||||||
|
* }
|
||||||
|
* @endcode
|
||||||
*/
|
*/
|
||||||
void sendto_channel(Channel *channel, Client *from, Client *skip,
|
void sendto_channel(Channel *channel, Client *from, Client *skip,
|
||||||
int prefix, long clicap, int sendflags,
|
int prefix, long clicap, int sendflags,
|
||||||
@ -593,11 +641,15 @@ static int match_it(Client *one, char *mask, int what)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/** Send to all clients which match the mask.
|
||||||
* sendto_match_butone
|
* This function is rarely used.
|
||||||
*
|
* @param one The client to skip
|
||||||
* Send to all clients which match the mask in a way defined on 'what';
|
* @param from The sender
|
||||||
* either by user hostname or user servername.
|
* @param mask The mask
|
||||||
|
* @param what One of MATCH_HOST or MATCH_SERVER
|
||||||
|
* @param mtags Message tags associated with the message
|
||||||
|
* @param pattern Format string
|
||||||
|
* @param ... Parameters to the format string
|
||||||
*/
|
*/
|
||||||
void sendto_match_butone(Client *one, Client *from, char *mask, int what,
|
void sendto_match_butone(Client *one, Client *from, char *mask, int what,
|
||||||
MessageTag *mtags, FORMAT_STRING(const char *pattern), ...)
|
MessageTag *mtags, FORMAT_STRING(const char *pattern), ...)
|
||||||
@ -641,10 +693,9 @@ void sendto_match_butone(Client *one, Client *from, char *mask, int what,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/** Send a message to all locally connected IRCOps
|
||||||
* sendto_ops
|
* @param pattern The format string / pattern to use.
|
||||||
*
|
* @param ... Format string parameters.
|
||||||
* Send to *local* ops only.
|
|
||||||
*/
|
*/
|
||||||
void sendto_ops(FORMAT_STRING(const char *pattern), ...)
|
void sendto_ops(FORMAT_STRING(const char *pattern), ...)
|
||||||
{
|
{
|
||||||
@ -664,10 +715,98 @@ void sendto_ops(FORMAT_STRING(const char *pattern), ...)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* Hmm.. so local sending is called sendto_ops() and local+remote is sendto_ops_butone(),
|
||||||
* sendto_umode
|
* that is weird naming... (TODO fix some day in a new major series)
|
||||||
*
|
*/
|
||||||
* Send to specified umode
|
|
||||||
|
/** Send a message to all IRCOps (local and remote), except one.
|
||||||
|
* @param one Skip sending the message to this client/direction
|
||||||
|
* @param from The sender (can not be NULL)
|
||||||
|
* @param pattern The format string / pattern to use.
|
||||||
|
* @param ... Format string parameters.
|
||||||
|
*/
|
||||||
|
void sendto_ops_butone(Client *one, Client *from, FORMAT_STRING(const char *pattern), ...)
|
||||||
|
{
|
||||||
|
va_list vl;
|
||||||
|
Client *acptr;
|
||||||
|
|
||||||
|
++current_serial;
|
||||||
|
list_for_each_entry(acptr, &client_list, client_node)
|
||||||
|
{
|
||||||
|
if (!SendWallops(acptr))
|
||||||
|
continue;
|
||||||
|
if (acptr->direction->local->serial == current_serial) /* sent message along it already ? */
|
||||||
|
continue;
|
||||||
|
if (acptr->direction == one)
|
||||||
|
continue; /* ...was the one I should skip */
|
||||||
|
acptr->direction->local->serial = current_serial;
|
||||||
|
|
||||||
|
va_start(vl, pattern);
|
||||||
|
vsendto_prefix_one(acptr->direction, from, NULL, pattern, vl);
|
||||||
|
va_end(vl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** This function does exactly the same as sendto_ops() in practice in 5.x.
|
||||||
|
* There used to be a difference between sendto_ops() and sendto_realops()
|
||||||
|
* with regards to user-settable snomasks, but this is no longer the case.
|
||||||
|
* TODO: remove this function in some future cleanup
|
||||||
|
*/
|
||||||
|
void sendto_realops(FORMAT_STRING(const char *pattern), ...)
|
||||||
|
{
|
||||||
|
va_list vl;
|
||||||
|
Client *acptr;
|
||||||
|
char nbuf[1024];
|
||||||
|
|
||||||
|
list_for_each_entry(acptr, &oper_list, special_node)
|
||||||
|
{
|
||||||
|
ircsnprintf(nbuf, sizeof(nbuf), ":%s NOTICE %s :*** ", me.name, acptr->name);
|
||||||
|
strlcat(nbuf, pattern, sizeof nbuf);
|
||||||
|
|
||||||
|
va_start(vl, pattern);
|
||||||
|
vsendto_one(acptr, NULL, nbuf, vl);
|
||||||
|
va_end(vl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Send a message to all locally connected IRCOps and also log the error.
|
||||||
|
* @param pattern The format string / pattern to use.
|
||||||
|
* @param ... Format string parameters.
|
||||||
|
*/
|
||||||
|
void sendto_ops_and_log(FORMAT_STRING(const char *pattern), ...)
|
||||||
|
{
|
||||||
|
va_list vl;
|
||||||
|
char buf[1024];
|
||||||
|
|
||||||
|
va_start(vl, pattern);
|
||||||
|
ircvsnprintf(buf, sizeof(buf), pattern, vl);
|
||||||
|
va_end(vl);
|
||||||
|
|
||||||
|
ircd_log(LOG_ERROR, "%s", buf);
|
||||||
|
sendto_umode(UMODE_OPER, "%s", buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** This function does exactly the same as sendto_ops_and_log()
|
||||||
|
* TODO: remove this function in some future cleanup
|
||||||
|
*/
|
||||||
|
void sendto_realops_and_log(FORMAT_STRING(const char *fmt), ...)
|
||||||
|
{
|
||||||
|
va_list vl;
|
||||||
|
static char buf[2048];
|
||||||
|
|
||||||
|
va_start(vl, fmt);
|
||||||
|
vsnprintf(buf, sizeof(buf), fmt, vl);
|
||||||
|
va_end(vl);
|
||||||
|
|
||||||
|
sendto_realops("%s", buf);
|
||||||
|
ircd_log(LOG_ERROR, "%s", buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Send a message to all locally connected users with specified user mode.
|
||||||
|
* @param umodes The umode that the recipient should have set (one of UMODE_)
|
||||||
|
* @param pattern The format string / pattern to use.
|
||||||
|
* @param ... Format string parameters.
|
||||||
*/
|
*/
|
||||||
void sendto_umode(int umodes, FORMAT_STRING(const char *pattern), ...)
|
void sendto_umode(int umodes, FORMAT_STRING(const char *pattern), ...)
|
||||||
{
|
{
|
||||||
@ -687,10 +826,10 @@ void sendto_umode(int umodes, FORMAT_STRING(const char *pattern), ...)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/** Send a message to all users with specified user mode (local & remote users).
|
||||||
* sendto_umode_global
|
* @param umodes The umode that the recipient should have set (one of UMODE_*)
|
||||||
*
|
* @param pattern The format string / pattern to use.
|
||||||
* Send to specified umode *GLOBALLY* (on all servers)
|
* @param ... Format string parameters.
|
||||||
*/
|
*/
|
||||||
void sendto_umode_global(int umodes, FORMAT_STRING(const char *pattern), ...)
|
void sendto_umode_global(int umodes, FORMAT_STRING(const char *pattern), ...)
|
||||||
{
|
{
|
||||||
@ -734,10 +873,10 @@ void sendto_umode_global(int umodes, FORMAT_STRING(const char *pattern), ...)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Send to specified snomask - local / operonly.
|
/** Send a message to all locally connected users with specified snomask.
|
||||||
* @param snomask Snomask to send to (can be a bitmask [AND])
|
* @param snomask The snomask that the recipient should have set (one of SNO_*)
|
||||||
* @param pattern printf-style pattern, followed by parameters.
|
* @param pattern The format string / pattern to use.
|
||||||
* This function does not send snomasks to non-opers.
|
* @param ... Format string parameters.
|
||||||
*/
|
*/
|
||||||
void sendto_snomask(int snomask, FORMAT_STRING(const char *pattern), ...)
|
void sendto_snomask(int snomask, FORMAT_STRING(const char *pattern), ...)
|
||||||
{
|
{
|
||||||
@ -756,10 +895,10 @@ void sendto_snomask(int snomask, FORMAT_STRING(const char *pattern), ...)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Send to specified snomask - global / operonly.
|
/** Send a message to all users with specified snomask (local and remote users).
|
||||||
* @param snomask Snomask to send to (can be a bitmask [AND])
|
* @param snomask The snomask that the recipient should have set (one of SNO_*)
|
||||||
* @param pattern printf-style pattern, followed by parameters
|
* @param pattern The format string / pattern to use.
|
||||||
* This function does not send snomasks to non-opers.
|
* @param ... Format string parameters.
|
||||||
*/
|
*/
|
||||||
void sendto_snomask_global(int snomask, FORMAT_STRING(const char *pattern), ...)
|
void sendto_snomask_global(int snomask, FORMAT_STRING(const char *pattern), ...)
|
||||||
{
|
{
|
||||||
@ -788,10 +927,10 @@ void sendto_snomask_global(int snomask, FORMAT_STRING(const char *pattern), ...)
|
|||||||
sendto_server(NULL, 0, 0, NULL, ":%s SENDSNO %s :%s", me.id, snobuf, nbuf);
|
sendto_server(NULL, 0, 0, NULL, ":%s SENDSNO %s :%s", me.id, snobuf, nbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/** Send CAP DEL and CAP NEW notification to clients supporting it.
|
||||||
* send_cap_notify
|
* This function is mostly meant to be used by the CAP and SASL modules.
|
||||||
*
|
* @param add Whether the CAP token is added (1) or removed (0)
|
||||||
* Send CAP DEL or CAP NEW to clients supporting this.
|
* @param token The CAP token
|
||||||
*/
|
*/
|
||||||
void send_cap_notify(int add, char *token)
|
void send_cap_notify(int add, char *token)
|
||||||
{
|
{
|
||||||
@ -829,33 +968,6 @@ void send_cap_notify(int add, char *token)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ** sendto_ops_butone
|
|
||||||
** Send message to all operators.
|
|
||||||
** one - client not to send message to
|
|
||||||
** from- client which message is from *NEVER* NULL!!
|
|
||||||
*/
|
|
||||||
void sendto_ops_butone(Client *one, Client *from, FORMAT_STRING(const char *pattern), ...)
|
|
||||||
{
|
|
||||||
va_list vl;
|
|
||||||
Client *acptr;
|
|
||||||
|
|
||||||
++current_serial;
|
|
||||||
list_for_each_entry(acptr, &client_list, client_node)
|
|
||||||
{
|
|
||||||
if (!SendWallops(acptr))
|
|
||||||
continue;
|
|
||||||
if (acptr->direction->local->serial == current_serial) /* sent message along it already ? */
|
|
||||||
continue;
|
|
||||||
if (acptr->direction == one)
|
|
||||||
continue; /* ...was the one I should skip */
|
|
||||||
acptr->direction->local->serial = current_serial;
|
|
||||||
|
|
||||||
va_start(vl, pattern);
|
|
||||||
vsendto_prefix_one(acptr->direction, from, NULL, pattern, vl);
|
|
||||||
va_end(vl);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Prepare buffer based on format string and 'from' for LOCAL delivery.
|
/* Prepare buffer based on format string and 'from' for LOCAL delivery.
|
||||||
* The prefix (:<something>) will be expanded to :nick!user@host if 'from'
|
* The prefix (:<something>) will be expanded to :nick!user@host if 'from'
|
||||||
* is a person, taking into account the rules for hidden/cloaked host.
|
* is a person, taking into account the rules for hidden/cloaked host.
|
||||||
@ -908,6 +1020,32 @@ static int vmakebuf_local_withprefix(char *buf, size_t buflen, Client *from, con
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Send a message to a client, expand the sender prefix.
|
||||||
|
* This is similar to sendto_one() except that it will expand the source part :%s
|
||||||
|
* to :nick!user@host if needed, while with sendto_one() it will be :nick.
|
||||||
|
* @param to The client to send to
|
||||||
|
* @param mtags Any message tags associated with this message (can be NULL)
|
||||||
|
* @param pattern The format string / pattern to use.
|
||||||
|
* @param ... Format string parameters.
|
||||||
|
*/
|
||||||
|
void sendto_prefix_one(Client *to, Client *from, MessageTag *mtags, FORMAT_STRING(const char *pattern), ...)
|
||||||
|
{
|
||||||
|
va_list vl;
|
||||||
|
va_start(vl, pattern);
|
||||||
|
vsendto_prefix_one(to, from, mtags, pattern, vl);
|
||||||
|
va_end(vl);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Send a message to a single client, expand the sender prefix - va_list variant.
|
||||||
|
* This is similar to vsendto_one() except that it will expand the source part :%s
|
||||||
|
* to :nick!user@host if needed, while with sendto_one() it will be :nick.
|
||||||
|
* This function is also similar to sendto_prefix_one(), but this is the va_list
|
||||||
|
* variant.
|
||||||
|
* @param to The client to send to
|
||||||
|
* @param mtags Any message tags associated with this message (can be NULL)
|
||||||
|
* @param pattern The format string / pattern to use.
|
||||||
|
* @param ... Format string parameters.
|
||||||
|
*/
|
||||||
void vsendto_prefix_one(Client *to, Client *from, MessageTag *mtags, const char *pattern, va_list vl)
|
void vsendto_prefix_one(Client *to, Client *from, MessageTag *mtags, const char *pattern, va_list vl)
|
||||||
{
|
{
|
||||||
char *mtags_str = mtags ? mtags_to_string(mtags, to) : NULL;
|
char *mtags_str = mtags ? mtags_to_string(mtags, to) : NULL;
|
||||||
@ -928,60 +1066,6 @@ void vsendto_prefix_one(Client *to, Client *from, MessageTag *mtags, const char
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* sendto_prefix_one
|
|
||||||
*
|
|
||||||
* to - destination client
|
|
||||||
* from - client which message is from
|
|
||||||
*
|
|
||||||
* NOTE: NEITHER OF THESE SHOULD *EVER* BE NULL!!
|
|
||||||
* -avalon
|
|
||||||
*/
|
|
||||||
|
|
||||||
void sendto_prefix_one(Client *to, Client *from, MessageTag *mtags, FORMAT_STRING(const char *pattern), ...)
|
|
||||||
{
|
|
||||||
va_list vl;
|
|
||||||
va_start(vl, pattern);
|
|
||||||
vsendto_prefix_one(to, from, mtags, pattern, vl);
|
|
||||||
va_end(vl);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* sendto_realops
|
|
||||||
*
|
|
||||||
* Send to *local* ops only but NOT +s nonopers.
|
|
||||||
*/
|
|
||||||
void sendto_realops(FORMAT_STRING(const char *pattern), ...)
|
|
||||||
{
|
|
||||||
va_list vl;
|
|
||||||
Client *acptr;
|
|
||||||
char nbuf[1024];
|
|
||||||
|
|
||||||
list_for_each_entry(acptr, &oper_list, special_node)
|
|
||||||
{
|
|
||||||
ircsnprintf(nbuf, sizeof(nbuf), ":%s NOTICE %s :*** ", me.name, acptr->name);
|
|
||||||
strlcat(nbuf, pattern, sizeof nbuf);
|
|
||||||
|
|
||||||
va_start(vl, pattern);
|
|
||||||
vsendto_one(acptr, NULL, nbuf, vl);
|
|
||||||
va_end(vl);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Sends a message to all (local) opers AND logs to the ircdlog (as LOG_ERROR) */
|
|
||||||
void sendto_realops_and_log(FORMAT_STRING(const char *fmt), ...)
|
|
||||||
{
|
|
||||||
va_list vl;
|
|
||||||
static char buf[2048];
|
|
||||||
|
|
||||||
va_start(vl, fmt);
|
|
||||||
vsnprintf(buf, sizeof(buf), fmt, vl);
|
|
||||||
va_end(vl);
|
|
||||||
|
|
||||||
sendto_realops("%s", buf);
|
|
||||||
ircd_log(LOG_ERROR, "%s", buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sendto_connectnotice(Client *newuser, int disconnect, char *comment)
|
void sendto_connectnotice(Client *newuser, int disconnect, char *comment)
|
||||||
{
|
{
|
||||||
Client *acptr;
|
Client *acptr;
|
||||||
@ -1102,6 +1186,11 @@ void sendto_one_nickcmd(Client *server, Client *client, char *umodes)
|
|||||||
* has a % in their nick, which is a safe assumption since % is illegal.
|
* has a % in their nick, which is a safe assumption since % is illegal.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/** Send a server notice to a client.
|
||||||
|
* @param to The client to send to
|
||||||
|
* @param pattern The format string / pattern to use.
|
||||||
|
* @param ... Format string parameters.
|
||||||
|
*/
|
||||||
void sendnotice(Client *to, FORMAT_STRING(const char *pattern), ...)
|
void sendnotice(Client *to, FORMAT_STRING(const char *pattern), ...)
|
||||||
{
|
{
|
||||||
static char realpattern[1024];
|
static char realpattern[1024];
|
||||||
@ -1115,25 +1204,34 @@ void sendnotice(Client *to, FORMAT_STRING(const char *pattern), ...)
|
|||||||
va_end(vl);
|
va_end(vl);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Send MultiLine list as a notice, one for each line */
|
/** Send MultiLine list as a notice, one for each line.
|
||||||
|
* @param client The client to send to
|
||||||
|
* @param m The MultiLine list.
|
||||||
|
*/
|
||||||
void sendnotice_multiline(Client *client, MultiLine *m)
|
void sendnotice_multiline(Client *client, MultiLine *m)
|
||||||
{
|
{
|
||||||
for (; m; m = m->next)
|
for (; m; m = m->next)
|
||||||
sendnotice(client, "%s", m->line);
|
sendnotice(client, "%s", m->line);
|
||||||
}
|
}
|
||||||
void sendtxtnumeric(Client *to, FORMAT_STRING(const char *pattern), ...)
|
|
||||||
{
|
|
||||||
static char realpattern[1024];
|
|
||||||
va_list vl;
|
|
||||||
|
|
||||||
ircsnprintf(realpattern, sizeof(realpattern), ":%s %d %s :%s", me.name, RPL_TEXT, to->name, pattern);
|
|
||||||
|
|
||||||
va_start(vl, pattern);
|
/** Send numeric message to a client.
|
||||||
vsendto_one(to, NULL, realpattern, vl);
|
* @param to The recipient
|
||||||
va_end(vl);
|
* @param numeric The numeric, one of RPL_* or ERR_*, see src/numeric.c
|
||||||
}
|
* @param ... The parameters for the numeric
|
||||||
|
* @note Be sure to provide the correct number and type of parameters that belong to the numeric. Check src/numeric.c when in doubt!
|
||||||
/** Send numeric to IRC client */
|
* @section sendnumeric_examples Examples
|
||||||
|
* @subsection sendnumeric_permission_denied Send "Permission Denied" numeric
|
||||||
|
* This numeric has no parameter, so is simple:
|
||||||
|
* @code
|
||||||
|
* sendnumeric(client, ERR_NOPRIVILEGES);
|
||||||
|
* @endcode
|
||||||
|
* @subsection sendnumeric_notenoughparameters Send "Not enough parameters" numeric
|
||||||
|
* This numeric requires 1 parameter: the name of the command.
|
||||||
|
* @code
|
||||||
|
* sendnumeric(client, ERR_NEEDMOREPARAMS, "SOMECOMMAND");
|
||||||
|
* @endcode
|
||||||
|
*/
|
||||||
void sendnumeric(Client *to, int numeric, ...)
|
void sendnumeric(Client *to, int numeric, ...)
|
||||||
{
|
{
|
||||||
va_list vl;
|
va_list vl;
|
||||||
@ -1146,7 +1244,15 @@ void sendnumeric(Client *to, int numeric, ...)
|
|||||||
va_end(vl);
|
va_end(vl);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Send numeric to IRC client */
|
/** Send numeric message to a client - format to user specific needs.
|
||||||
|
* This will ignore the numeric definition of src/numeric.c and always send ":me.name numeric clientname "
|
||||||
|
* followed by the pattern and format string you choose.
|
||||||
|
* @param to The recipient
|
||||||
|
* @param numeric The numeric, one of RPL_* or ERR_*, see src/numeric.c
|
||||||
|
* @param pattern The format string / pattern to use.
|
||||||
|
* @param ... Format string parameters.
|
||||||
|
* @note Don't forget to add a colon if you need it (eg `:%%s`), this is a common mistake.
|
||||||
|
*/
|
||||||
void sendnumericfmt(Client *to, int numeric, FORMAT_STRING(const char *pattern), ...)
|
void sendnumericfmt(Client *to, int numeric, FORMAT_STRING(const char *pattern), ...)
|
||||||
{
|
{
|
||||||
va_list vl;
|
va_list vl;
|
||||||
@ -1159,7 +1265,27 @@ void sendnumericfmt(Client *to, int numeric, FORMAT_STRING(const char *pattern),
|
|||||||
va_end(vl);
|
va_end(vl);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Send raw data directly to socket, bypassing everything.
|
/** Send text numeric message to a client (RPL_TEXT).
|
||||||
|
* Because this generic output numeric is commonly used it got a special function for it.
|
||||||
|
* @param to The recipient
|
||||||
|
* @param numeric The numeric, one of RPL_* or ERR_*, see src/numeric.c
|
||||||
|
* @param pattern The format string / pattern to use.
|
||||||
|
* @param ... Format string parameters.
|
||||||
|
* @note Don't forget to add a colon if you need it (eg `:%%s`), this is a common mistake.
|
||||||
|
*/
|
||||||
|
void sendtxtnumeric(Client *to, FORMAT_STRING(const char *pattern), ...)
|
||||||
|
{
|
||||||
|
static char realpattern[1024];
|
||||||
|
va_list vl;
|
||||||
|
|
||||||
|
ircsnprintf(realpattern, sizeof(realpattern), ":%s %d %s :%s", me.name, RPL_TEXT, to->name, pattern);
|
||||||
|
|
||||||
|
va_start(vl, pattern);
|
||||||
|
vsendto_one(to, NULL, realpattern, vl);
|
||||||
|
va_end(vl);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Send raw data directly to socket, bypassing everything.
|
||||||
* Looks like an interesting function to call? NO! STOP!
|
* Looks like an interesting function to call? NO! STOP!
|
||||||
* Don't use this function. It may only be used by the initial
|
* Don't use this function. It may only be used by the initial
|
||||||
* Z-Line check via the codepath to banned_client().
|
* Z-Line check via the codepath to banned_client().
|
||||||
@ -1186,17 +1312,4 @@ void send_raw_direct(Client *user, FORMAT_STRING(FORMAT_STRING(const char *patte
|
|||||||
(void)send(user->local->fd, sendbuf, sendlen, 0);
|
(void)send(user->local->fd, sendbuf, sendlen, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Send a message to all locally connected IRCOps and log the error.
|
/** @} */
|
||||||
*/
|
|
||||||
void sendto_ops_and_log(FORMAT_STRING(const char *pattern), ...)
|
|
||||||
{
|
|
||||||
va_list vl;
|
|
||||||
char buf[1024];
|
|
||||||
|
|
||||||
va_start(vl, pattern);
|
|
||||||
ircvsnprintf(buf, sizeof(buf), pattern, vl);
|
|
||||||
va_end(vl);
|
|
||||||
|
|
||||||
ircd_log(LOG_ERROR, "%s", buf);
|
|
||||||
sendto_umode(UMODE_OPER, "%s", buf);
|
|
||||||
}
|
|
||||||
|
@ -32,7 +32,6 @@
|
|||||||
/* for uname(), is POSIX so should be OK... */
|
/* for uname(), is POSIX so should be OK... */
|
||||||
#include <sys/utsname.h>
|
#include <sys/utsname.h>
|
||||||
#endif
|
#endif
|
||||||
extern void s_die();
|
|
||||||
|
|
||||||
MODVAR int max_connection_count = 1, max_client_count = 1;
|
MODVAR int max_connection_count = 1, max_client_count = 1;
|
||||||
extern int do_garbage_collect;
|
extern int do_garbage_collect;
|
||||||
|
@ -724,17 +724,6 @@ void outofmemory(size_t bytes)
|
|||||||
exit(7);
|
exit(7);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Check if the specified file exists */
|
|
||||||
int file_exists(char *file)
|
|
||||||
{
|
|
||||||
FILE *fd;
|
|
||||||
fd = fopen(file, "r");
|
|
||||||
if (!fd)
|
|
||||||
return 0;
|
|
||||||
fclose(fd);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns a unique filename in the specified directory
|
/** Returns a unique filename in the specified directory
|
||||||
* using the specified suffix. The returned value will
|
* using the specified suffix. The returned value will
|
||||||
* be of the form <dir>/<random-hex>.<suffix>
|
* be of the form <dir>/<random-hex>.<suffix>
|
||||||
|
104
src/tls.c
104
src/tls.c
@ -36,9 +36,10 @@ extern HWND hwIRCDWnd;
|
|||||||
#define SAFE_SSL_ACCEPT 3
|
#define SAFE_SSL_ACCEPT 3
|
||||||
#define SAFE_SSL_CONNECT 4
|
#define SAFE_SSL_CONNECT 4
|
||||||
|
|
||||||
|
/* Forward declarations */
|
||||||
static int fatal_ssl_error(int ssl_error, int where, int my_errno, Client *client);
|
static int fatal_ssl_error(int ssl_error, int where, int my_errno, Client *client);
|
||||||
extern int cipher_check(SSL_CTX *ctx, char **errstr);
|
int cipher_check(SSL_CTX *ctx, char **errstr);
|
||||||
extern int certificate_quality_check(SSL_CTX *ctx, char **errstr);
|
int certificate_quality_check(SSL_CTX *ctx, char **errstr);
|
||||||
|
|
||||||
/* The SSL structures */
|
/* The SSL structures */
|
||||||
SSL_CTX *ctx_server;
|
SSL_CTX *ctx_server;
|
||||||
@ -1040,6 +1041,8 @@ int verify_certificate(SSL *ssl, char *hostname, char **errstr)
|
|||||||
|
|
||||||
if (SSL_get_verify_result(ssl) != X509_V_OK)
|
if (SSL_get_verify_result(ssl) != X509_V_OK)
|
||||||
{
|
{
|
||||||
|
// FIXME: there are actually about 25+ different possible errors,
|
||||||
|
// this is only the most common one:
|
||||||
strlcpy(buf, "Certificate is not issued by a trusted Certificate Authority", sizeof(buf));
|
strlcpy(buf, "Certificate is not issued by a trusted Certificate Authority", sizeof(buf));
|
||||||
if (errstr)
|
if (errstr)
|
||||||
*errstr = buf;
|
*errstr = buf;
|
||||||
@ -1333,3 +1336,100 @@ char *outdated_tls_client_build_string(char *pattern, Client *client)
|
|||||||
buildvarstring(pattern, buf, sizeof(buf), name, value);
|
buildvarstring(pattern, buf, sizeof(buf), name, value);
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int check_certificate_expiry_ctx(SSL_CTX *ctx, char **errstr)
|
||||||
|
{
|
||||||
|
#if !defined(HAS_ASN1_TIME_diff) || !defined(HAS_X509_get0_notAfter)
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
|
static char errbuf[512];
|
||||||
|
SSL *ssl;
|
||||||
|
X509 *cert;
|
||||||
|
const ASN1_TIME *cert_expiry_time;
|
||||||
|
int days_expiry = 0, seconds_expiry = 0;
|
||||||
|
long duration;
|
||||||
|
|
||||||
|
*errstr = NULL;
|
||||||
|
|
||||||
|
ssl = SSL_new(ctx);
|
||||||
|
if (!ssl)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
cert = SSL_get_certificate(ssl);
|
||||||
|
if (!cert)
|
||||||
|
{
|
||||||
|
SSL_free(ssl);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get certificate time */
|
||||||
|
cert_expiry_time = X509_get0_notAfter(cert);
|
||||||
|
|
||||||
|
/* calculate difference */
|
||||||
|
ASN1_TIME_diff(&days_expiry, &seconds_expiry, cert_expiry_time, NULL);
|
||||||
|
duration = (days_expiry * 86400) + seconds_expiry;
|
||||||
|
|
||||||
|
/* certificate expiry? */
|
||||||
|
if ((days_expiry > 0) || (seconds_expiry > 0))
|
||||||
|
{
|
||||||
|
snprintf(errbuf, sizeof(errbuf), "certificate expired %s ago", pretty_time_val(duration));
|
||||||
|
SSL_free(ssl);
|
||||||
|
*errstr = errbuf;
|
||||||
|
return 1;
|
||||||
|
} else
|
||||||
|
/* or near-expiry? */
|
||||||
|
if (((days_expiry < 0) || (seconds_expiry < 0)) && (days_expiry > -7))
|
||||||
|
{
|
||||||
|
snprintf(errbuf, sizeof(errbuf), "certificate will expire in %s", pretty_time_val(0 - duration));
|
||||||
|
SSL_free(ssl);
|
||||||
|
*errstr = errbuf;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* All good */
|
||||||
|
SSL_free(ssl);
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void check_certificate_expiry_tlsoptions_and_warn(TLSOptions *tlsoptions)
|
||||||
|
{
|
||||||
|
SSL_CTX *ctx;
|
||||||
|
int ret;
|
||||||
|
char *errstr = NULL;
|
||||||
|
|
||||||
|
ctx = init_ctx(tlsoptions, 1);
|
||||||
|
if (!ctx)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (check_certificate_expiry_ctx(ctx, &errstr))
|
||||||
|
{
|
||||||
|
sendto_umode_global(UMODE_OPER, "Warning: TLS certificate '%s': %s", tlsoptions->certificate_file, errstr);
|
||||||
|
ircd_log(LOG_ERROR, "[warning] TLS certificate '%s': %s", tlsoptions->certificate_file, errstr);
|
||||||
|
}
|
||||||
|
SSL_CTX_free(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
EVENT(tls_check_expiry)
|
||||||
|
{
|
||||||
|
ConfigItem_listen *listen;
|
||||||
|
ConfigItem_sni *sni;
|
||||||
|
ConfigItem_link *link;
|
||||||
|
|
||||||
|
/* set block */
|
||||||
|
check_certificate_expiry_tlsoptions_and_warn(iConf.tls_options);
|
||||||
|
|
||||||
|
for (listen = conf_listen; listen; listen = listen->next)
|
||||||
|
if (listen->tls_options)
|
||||||
|
check_certificate_expiry_tlsoptions_and_warn(listen->tls_options);
|
||||||
|
|
||||||
|
/* sni::tls-options.... */
|
||||||
|
for (sni = conf_sni; sni; sni = sni->next)
|
||||||
|
if (sni->tls_options)
|
||||||
|
check_certificate_expiry_tlsoptions_and_warn(sni->tls_options);
|
||||||
|
|
||||||
|
/* link::outgoing::tls-options.... */
|
||||||
|
for (link = conf_link; link; link = link->next)
|
||||||
|
if (link->tls_options)
|
||||||
|
check_certificate_expiry_tlsoptions_and_warn(link->tls_options);
|
||||||
|
}
|
||||||
|
146
src/user.c
146
src/user.c
@ -726,3 +726,149 @@ int hide_idle_time(Client *client, Client *target)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Check if the name of the security-group contains only valid characters.
|
||||||
|
* @param name The name of the group
|
||||||
|
* @returns 1 if name is valid, 0 if not (eg: illegal characters)
|
||||||
|
*/
|
||||||
|
int security_group_valid_name(char *name)
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
if (strlen(name) > SECURITYGROUPLEN)
|
||||||
|
return 0; /* Too long */
|
||||||
|
for (p = name; *p; p++)
|
||||||
|
{
|
||||||
|
if (!isalnum(*p) && !strchr("_-", *p))
|
||||||
|
return 0; /* Character not allowed */
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Find a security-group.
|
||||||
|
* @param name The name of the security group
|
||||||
|
* @returns A SecurityGroup struct, or NULL if not found.
|
||||||
|
*/
|
||||||
|
SecurityGroup *find_security_group(char *name)
|
||||||
|
{
|
||||||
|
SecurityGroup *s;
|
||||||
|
for (s = securitygroups; s; s = s->next)
|
||||||
|
if (!strcasecmp(name, s->name))
|
||||||
|
return s;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Checks if a security-group exists.
|
||||||
|
* This function takes the 'unknown-users' magic group into account as well.
|
||||||
|
* @param name The name of the security group
|
||||||
|
* @returns 1 if it exists, 0 if not
|
||||||
|
*/
|
||||||
|
int security_group_exists(char *name)
|
||||||
|
{
|
||||||
|
if (!strcmp(name, "unknown-users") || find_security_group(name))
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Add a new security-group and add it to the list, but search for existing one first.
|
||||||
|
* @param name The name of the security group
|
||||||
|
* @returns A SecurityGroup struct (already added to the 'securitygroups' linked list)
|
||||||
|
*/
|
||||||
|
SecurityGroup *add_security_group(char *name, int priority)
|
||||||
|
{
|
||||||
|
SecurityGroup *s = find_security_group(name);
|
||||||
|
|
||||||
|
/* Existing? */
|
||||||
|
if (s)
|
||||||
|
return s;
|
||||||
|
|
||||||
|
/* Otherwise, create a new entry */
|
||||||
|
s = safe_alloc(sizeof(SecurityGroup));
|
||||||
|
strlcpy(s->name, name, sizeof(s->name));
|
||||||
|
s->priority = priority;
|
||||||
|
AddListItemPrio(s, securitygroups, priority);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Free a SecurityGroup struct */
|
||||||
|
void free_security_group(SecurityGroup *s)
|
||||||
|
{
|
||||||
|
/* atm there is nothing else to free,
|
||||||
|
* but who knows this may change in the future
|
||||||
|
*/
|
||||||
|
safe_free(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Initialize the default security-group blocks */
|
||||||
|
void set_security_group_defaults(void)
|
||||||
|
{
|
||||||
|
SecurityGroup *s, *s_next;
|
||||||
|
|
||||||
|
/* First free all security groups */
|
||||||
|
for (s = securitygroups; s; s = s_next)
|
||||||
|
{
|
||||||
|
s_next = s->next;
|
||||||
|
free_security_group(s);
|
||||||
|
}
|
||||||
|
securitygroups = NULL;
|
||||||
|
|
||||||
|
/* Default group: known-users */
|
||||||
|
s = add_security_group("known-users", 100);
|
||||||
|
s->identified = 1;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns 1 if the user is OK as far as the security-group is concerned.
|
||||||
|
* @param client The client to check
|
||||||
|
* @param s The security-group to check against
|
||||||
|
* @retval 1 if user is allowed by security-group, 0 if not.
|
||||||
|
*/
|
||||||
|
int user_allowed_by_security_group(Client *client, SecurityGroup *s)
|
||||||
|
{
|
||||||
|
if (s->identified && IsLoggedIn(client))
|
||||||
|
return 1;
|
||||||
|
if (s->webirc && moddata_client_get(client, "webirc"))
|
||||||
|
return 1;
|
||||||
|
if (s->reputation_score && (GetReputation(client) >= s->reputation_score))
|
||||||
|
return 1;
|
||||||
|
if (s->tls && (IsSecureConnect(client) || IsSecure(client)))
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns 1 if the user is OK as far as the security-group is concerned - "by name" version.
|
||||||
|
* @param client The client to check
|
||||||
|
* @param secgroupname The name of the security-group to check against
|
||||||
|
* @retval 1 if user is allowed by security-group, 0 if not.
|
||||||
|
*/
|
||||||
|
int user_allowed_by_security_group_name(Client *client, char *secgroupname)
|
||||||
|
{
|
||||||
|
SecurityGroup *s;
|
||||||
|
|
||||||
|
/* Handle the magical 'unknown-users' case. */
|
||||||
|
if (!strcmp(secgroupname, "unknown-users"))
|
||||||
|
{
|
||||||
|
/* This is simply the inverse of 'known-users' */
|
||||||
|
s = find_security_group("known-users");
|
||||||
|
if (!s)
|
||||||
|
return 0; /* that's weird!? pretty impossible. */
|
||||||
|
return !user_allowed_by_security_group(client, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Find the group and evaluate it */
|
||||||
|
s = find_security_group(secgroupname);
|
||||||
|
if (!s)
|
||||||
|
return 0; /* security group not found: no match */
|
||||||
|
return user_allowed_by_security_group(client, s);
|
||||||
|
}
|
||||||
|
@ -4,7 +4,7 @@ echo "Extracting src/version.c..."
|
|||||||
|
|
||||||
#id=`grep '$Id: Changes,v' ../Changes`
|
#id=`grep '$Id: Changes,v' ../Changes`
|
||||||
#id=`echo $id |sed 's/.* Changes\,v \(.*\) .* Exp .*/\1/'`
|
#id=`echo $id |sed 's/.* Changes\,v \(.*\) .* Exp .*/\1/'`
|
||||||
id="5.0.7"
|
id="5.0.8"
|
||||||
echo "$id"
|
echo "$id"
|
||||||
|
|
||||||
if test -r version.c
|
if test -r version.c
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
<assemblyIdentity
|
<assemblyIdentity
|
||||||
processorArchitecture="amd64"
|
processorArchitecture="amd64"
|
||||||
name="UnrealIRCd.UnrealIRCd.5"
|
name="UnrealIRCd.UnrealIRCd.5"
|
||||||
version="5.0.7.0"
|
version="5.0.8.0"
|
||||||
type="win32"
|
type="win32"
|
||||||
/>
|
/>
|
||||||
<description>Internet Relay Chat Daemon</description>
|
<description>Internet Relay Chat Daemon</description>
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
[Setup]
|
[Setup]
|
||||||
AppName=UnrealIRCd 5
|
AppName=UnrealIRCd 5
|
||||||
AppVerName=UnrealIRCd 5.0.7
|
AppVerName=UnrealIRCd 5.0.8
|
||||||
AppPublisher=UnrealIRCd Team
|
AppPublisher=UnrealIRCd Team
|
||||||
AppPublisherURL=https://www.unrealircd.org
|
AppPublisherURL=https://www.unrealircd.org
|
||||||
AppSupportURL=https://www.unrealircd.org
|
AppSupportURL=https://www.unrealircd.org
|
||||||
@ -68,6 +68,7 @@ Source: "src\modules\chanmodes\*.dll"; DestDir: "{app}\modules\chanmodes"; Flags
|
|||||||
Source: "src\modules\usermodes\*.dll"; DestDir: "{app}\modules\usermodes"; Flags: ignoreversion
|
Source: "src\modules\usermodes\*.dll"; DestDir: "{app}\modules\usermodes"; Flags: ignoreversion
|
||||||
Source: "src\modules\snomasks\*.dll"; DestDir: "{app}\modules\snomasks"; Flags: ignoreversion
|
Source: "src\modules\snomasks\*.dll"; DestDir: "{app}\modules\snomasks"; Flags: ignoreversion
|
||||||
Source: "src\modules\extbans\*.dll"; DestDir: "{app}\modules\extbans"; Flags: ignoreversion
|
Source: "src\modules\extbans\*.dll"; DestDir: "{app}\modules\extbans"; Flags: ignoreversion
|
||||||
|
Source: "src\modules\third\*.dll"; DestDir: "{app}\modules\third"; Flags: ignoreversion skipifsourcedoesntexist
|
||||||
|
|
||||||
Source: "c:\dev\unrealircd-5-libs\pcre2\bin\pcre*.dll"; DestDir: "{app}\bin"; Flags: ignoreversion
|
Source: "c:\dev\unrealircd-5-libs\pcre2\bin\pcre*.dll"; DestDir: "{app}\bin"; Flags: ignoreversion
|
||||||
Source: "c:\dev\unrealircd-5-libs\argon2\vs2015\build\*.dll"; DestDir: "{app}\bin"; Flags: ignoreversion
|
Source: "c:\dev\unrealircd-5-libs\argon2\vs2015\build\*.dll"; DestDir: "{app}\bin"; Flags: ignoreversion
|
||||||
|
Loading…
Reference in New Issue
Block a user