Merge branch 'solanum' into merging-solanum-into-hackint
This commit is contained in:
commit
c7da812303
540 changed files with 78646 additions and 130219 deletions
82
.github/workflows/ci.yml
vendored
Normal file
82
.github/workflows/ci.yml
vendored
Normal file
|
@ -0,0 +1,82 @@
|
|||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths-ignore:
|
||||
- 'doc/oper-guide/**'
|
||||
- 'CREDITS'
|
||||
- 'LICENSE'
|
||||
- 'NEWS.md'
|
||||
- 'README.md'
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
paths-ignore:
|
||||
- 'doc/oper-guide/**'
|
||||
- 'CREDITS'
|
||||
- 'LICENSE'
|
||||
- 'NEWS.md'
|
||||
- 'README.md'
|
||||
|
||||
jobs:
|
||||
linux:
|
||||
name: Linux
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
# Debian 10 Buster
|
||||
- os: ubuntu-20.04
|
||||
compiler: gcc-8
|
||||
- os: ubuntu-20.04
|
||||
compiler: clang-7
|
||||
# Ubuntu 20.04 Focal
|
||||
- os: ubuntu-20.04
|
||||
compiler: gcc-9
|
||||
- os: ubuntu-20.04
|
||||
compiler: clang-10
|
||||
# Debian 11 Bullseye
|
||||
- os: ubuntu-22.04
|
||||
compiler: gcc-10
|
||||
- os: ubuntu-22.04
|
||||
compiler: clang-11
|
||||
# Ubuntu 22.04 Jammy
|
||||
- os: ubuntu-22.04
|
||||
compiler: gcc-11
|
||||
- os: ubuntu-22.04
|
||||
compiler: clang-14
|
||||
# next
|
||||
- os: ubuntu-22.04
|
||||
compiler: gcc-12
|
||||
|
||||
env:
|
||||
CC: ${{ matrix.compiler }}
|
||||
|
||||
steps:
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y --no-install-recommends \
|
||||
${CC} \
|
||||
automake \
|
||||
autoconf \
|
||||
libtool \
|
||||
libsqlite3-dev \
|
||||
libhyperscan-dev \
|
||||
# EOF
|
||||
- uses: actions/checkout@v2
|
||||
- name: autogen.sh
|
||||
run: bash autogen.sh
|
||||
- name: configure
|
||||
run: CFLAGS="-Werror -Wno-unused-value -Wno-unused-parameter" ./configure --enable-assert=hard --enable-warnings
|
||||
- name: make
|
||||
run: make -j2
|
||||
- name: make check
|
||||
run: make check
|
||||
- name: make install
|
||||
run: make install
|
29
.github/workflows/docs.yaml
vendored
Normal file
29
.github/workflows/docs.yaml
vendored
Normal file
|
@ -0,0 +1,29 @@
|
|||
name: Oper Guide
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- 'doc/oper-guide/**'
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- 'doc/oper-guide/**'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-18.04
|
||||
|
||||
steps:
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y --no-install-recommends \
|
||||
python-sphinx \
|
||||
texinfo \
|
||||
# EOF
|
||||
- uses: actions/checkout@v2
|
||||
- name: Build
|
||||
run: make -C doc/oper-guide html man info
|
77
.gitignore
vendored
77
.gitignore
vendored
|
@ -1,6 +1,7 @@
|
|||
tags
|
||||
Makefile
|
||||
*~
|
||||
*.a
|
||||
*.o
|
||||
*.so
|
||||
*.lo
|
||||
|
@ -9,31 +10,71 @@ Makefile
|
|||
*.log
|
||||
*.sw?
|
||||
.deps
|
||||
.dirstamp
|
||||
.libs
|
||||
autom4te.cache
|
||||
authd/authd
|
||||
bandb/bandb
|
||||
bandb/bantool
|
||||
bandb/solanum-bantool
|
||||
autom4te.cache
|
||||
aclocal.m4
|
||||
compile
|
||||
confdefs.h
|
||||
config.guess
|
||||
config.sub
|
||||
depcomp
|
||||
ltmain.sh
|
||||
missing
|
||||
config.log
|
||||
config.status
|
||||
configure
|
||||
stamp-h1
|
||||
libltdl/
|
||||
librb/configure
|
||||
librb/compile
|
||||
librb/depcomp
|
||||
librb/aclocal.m4
|
||||
librb/include/librb_config.h
|
||||
librb/include/librb_config.h.in
|
||||
librb/include/librb-config.h
|
||||
librb/include/serno.h
|
||||
librb/librb.pc
|
||||
librb/ltmain.sh
|
||||
librb/missing
|
||||
librb/libratbox.pc
|
||||
librb/libtool
|
||||
librb/src/version.c
|
||||
librb/src/version.c.last
|
||||
scripts/*.tar.bz2
|
||||
scripts/*.tar.gz
|
||||
include/setup.h
|
||||
libratbox/include/libratbox_config.h
|
||||
libratbox/include/librb-config.h
|
||||
libratbox/include/stamp-h1
|
||||
libratbox/libratbox.pc
|
||||
libratbox/libtool
|
||||
libratbox/src/version.c
|
||||
libratbox/src/version.c.last
|
||||
scripts/*.tbz2
|
||||
scripts/*.tgz
|
||||
servlink/servlink
|
||||
src/ircd
|
||||
src/lex.yy.c
|
||||
src/version.c
|
||||
src/version.c.last
|
||||
src/y.tab.h
|
||||
src/y.tab.c
|
||||
include/setup.h.in
|
||||
ircd/solanum
|
||||
ircd/ircd_parser.c
|
||||
ircd/ircd_parser.h
|
||||
ircd/ircd_lexer.c
|
||||
ircd/version.c
|
||||
ircd/version.c.last
|
||||
ssld/ssld
|
||||
wsockd/wsockd
|
||||
testsuite/ircd.pid.*
|
||||
tools/solanum-mkpasswd
|
||||
tools/solanum-mkfingerprint
|
||||
tools/genssl
|
||||
tools/mkpasswd
|
||||
tools/viconf
|
||||
include/serno.h
|
||||
ircd/solanum
|
||||
ircd/version.c
|
||||
ircd/version.c.last
|
||||
/libtool
|
||||
Makefile.in
|
||||
m4/argz.m4
|
||||
m4/libtool.m4
|
||||
m4/ltargz.m4
|
||||
m4/ltdl.m4
|
||||
m4/ltoptions.m4
|
||||
m4/ltsugar.m4
|
||||
m4/ltversion.m4
|
||||
m4/lt~obsolete.m4
|
||||
*.dSYM/
|
||||
*.exe
|
||||
|
|
49
.indent.pro
vendored
49
.indent.pro
vendored
|
@ -1,49 +0,0 @@
|
|||
/* $Id: .indent.pro 238 2005-09-21 05:26:03Z nenolod $ */
|
||||
|
||||
/* copy this file to the source dir then run indent file.c */
|
||||
|
||||
--gnu-style
|
||||
|
||||
/* This is the indent before the brace not inside the block. */
|
||||
--brace-indent0
|
||||
|
||||
/* Indent case: by 2 and braces inside case by 0(then by 0)... */
|
||||
--case-brace-indentation0
|
||||
--case-indentation2
|
||||
|
||||
--indent-level8
|
||||
|
||||
/* Put while() on the brace from do... */
|
||||
--cuddle-do-while
|
||||
|
||||
/* Disable an annoying format... */
|
||||
--no-space-after-function-call-names
|
||||
|
||||
/* Disable an annoying format... */
|
||||
--dont-break-procedure-type
|
||||
|
||||
/* Disable an annoying format... */
|
||||
--no-space-after-casts
|
||||
|
||||
--line-length200
|
||||
|
||||
/* typedefs */
|
||||
-T boolean_t
|
||||
-T node_t
|
||||
-T list_t
|
||||
-T tld_t
|
||||
-T kline_t
|
||||
-T EVH
|
||||
-T sra_t
|
||||
-T server_t
|
||||
-T user_t
|
||||
-T channel_t
|
||||
-T chanuser_t
|
||||
-T myuser_t
|
||||
-T mychan_t
|
||||
-T chanacs_t
|
||||
-T CONFIGENTRY
|
||||
-T CONFIGFILE
|
||||
-T Block
|
||||
-T MemBlock
|
||||
-T BlockHeap
|
11
.mailmap
11
.mailmap
|
@ -1,9 +1,14 @@
|
|||
Aaron Sethman <androsyn@ratbox.org> androsyn <devnull@localhost>
|
||||
Alexander Færøy <ahf@0x90.dk> Alexander F?r?y <ahf@0x90.dk>
|
||||
Ariadne Conill <ariadne@dereferenced.org> <nenolod@atheme.org>
|
||||
Ariadne Conill <ariadne@dereferenced.org> <nenolod@dereferenced.org>
|
||||
Ariadne Conill <ariadne@dereferenced.org> nenolod <devnull@localhost>
|
||||
Brett Greenham <taros@shadowircd.net> B.Greenham <taros@shadowircd.net>
|
||||
Chris Mills <chris@chrisam.net> TheChrisAM <chris@chrisam.net>
|
||||
Chris Mills <chris@chrisam.net> freenode!ChrisAM <chris@chrisam.net>
|
||||
Elizabeth Jennifer Myers <elizabeth@sporksmoo.net> <elizabeth@sporksirc.net>
|
||||
Elizabeth Myers <elizabeth@interlinked.me> <elizabeth@sporksirc.net>
|
||||
Elizabeth Myers <elizabeth@interlinked.me> <elizabeth@sporksmoo.net>
|
||||
Elizabeth Myers <elizabeth@interlinked.me> <spaz@whotookspaz.org>
|
||||
Elly Fong-Jones <elly@leptoquark.net> Elly <elly@leptoquark.net>
|
||||
Jilles Tjoelker <jilles@stack.nl> jilles <devnull@localhost>
|
||||
Nathan Phillip Brink <binki@gentoo.org> <ohnobinki@ohnopublishing.net>
|
||||
|
@ -13,5 +18,5 @@ Valeriy Yatsko <dwr@shadowircd.net> <darkwire@darkwire.ru>
|
|||
Valeriy Yatsko <dwr@shadowircd.net> <darkwire@ircd-charybdis.ru>
|
||||
Valeriy Yatsko <dwr@shadowircd.net> <darkwire@sellcenter.ru>
|
||||
Valeriy Yatsko <dwr@shadowircd.net> <dwr@it-penza.org>
|
||||
William Pitcock <nenolod@dereferenced.org> <nenolod@atheme.org>
|
||||
William Pitcock <nenolod@dereferenced.org> nenolod <devnull@localhost>
|
||||
Christine Dodrill <shadow.h511@gmail.com> <quora@lavabit.com>
|
||||
Christine Dodrill <shadow.h511@gmail.com> <quorawings@gmail.com>
|
||||
|
|
31
CREDITS
31
CREDITS
|
@ -1,3 +1,4 @@
|
|||
<<<<<<< .merge_file_qEvahK
|
||||
Charybdis started as an evolution from ircd-ratbox. Its development
|
||||
is led by a team of dedicated developers who have put a lot of time
|
||||
into the project, and it has seen use on a variety of different
|
||||
|
@ -38,3 +39,33 @@ w00t, Robin Burchell <surreal.w00t -at- gmail.com>
|
|||
|
||||
Visit the Charybdis website at: http://www.charybdis.io/
|
||||
Visit us on IRC at: irc.charybdis.io #charybdis
|
||||
=======
|
||||
Solanum is based on Charybdis, which was based on ircd-ratbox.
|
||||
|
||||
Development is led by a group of representatives from Libera Chat
|
||||
and OFTC:
|
||||
|
||||
amdj, Aaron Jones <amdj@libera.chat>
|
||||
dwfreed, Doug Freed <dwfreed@mtu.edu>
|
||||
ilbelkyr, Nicole Kleinhoff <ilbelkyr@libera.chat>
|
||||
mcintosh, Richie McIntosh <richiemcintosh@gmail.com>
|
||||
Myon, Christoph Berg <myon@oftc.net>
|
||||
spb, Stephen Bennet <spb@libera.chat>
|
||||
tomaw, Tom Wesley <tom@tomaw.net>
|
||||
|
||||
The Charybdis team was:
|
||||
|
||||
amdj, Aaron Jones <aaronmdjones -at- gmail.com>
|
||||
Ariadne, Ariadne Conill <ariadne -at- dereferenced.org>
|
||||
Elizafox, Elizabeth Myers <elizabeth -at- interlinked.me>
|
||||
jdhore, JD Horelick <jdhore1 -at- gmail.com>
|
||||
jilles, Jilles Tjoelker <jilles -at- stack.nl>
|
||||
mr_flea, Keith Buck <mr_flea -at- esper.net>
|
||||
viatsko, Valerii Iatsko <dwr -at- codingbox.io>
|
||||
|
||||
A full list of contributors to Charybdis and its predecessors
|
||||
is in doc/credits-past.txt.
|
||||
|
||||
Visit the Solanum website at: https://solanum.chat/
|
||||
Visit us on IRC at: irc.libera.chat #solanum
|
||||
>>>>>>> .merge_file_gXRYUC
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
The Charybdis GIT repository can be checked out using the following command:
|
||||
git clone git://github.com/charybdis-ircd/charybdis.git charybdis-devel
|
||||
|
||||
Charybdis's GIT repository depot can be browsed over the internet at
|
||||
the following address:
|
||||
http://github.com/charybdis-ircd/charybdis
|
186
INSTALL
186
INSTALL
|
@ -1,186 +0,0 @@
|
|||
Charybdis INSTALL Document
|
||||
|
||||
$Id: INSTALL 3384 2007-04-03 22:45:04Z jilles $
|
||||
|
||||
Copyright (c) 2001 by ircd-hybrid team
|
||||
Copyright (c) 2002-2004 ircd-ratbox development team
|
||||
Copyright (c) 2005-2008 charybdis development team
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
HOW TO BUILD
|
||||
|
||||
As of hybrid-4, the distribution uses GNU autoconf instead of the old
|
||||
Config script. The Makefile has also been updated to include CFLAGS
|
||||
defines for popular modern OSes.
|
||||
|
||||
1.
|
||||
|
||||
Read the NEWS file to find out about the exciting new features in
|
||||
this version. Other good reads are BUGS, doc/ircd.conf.example, and
|
||||
README.FIRST.
|
||||
|
||||
2.
|
||||
|
||||
Run the configure script. It will create include/setup.h and the
|
||||
Makefiles to match your system. In ircd-ratbox, the paths are now handled
|
||||
with the --prefix option to configure, not in config.h.
|
||||
/usr/local/ircd is the default if no prefix is specified.
|
||||
|
||||
./configure --prefix="/usr/local/ircd"
|
||||
|
||||
Note: There are some special optional parameters to the configure
|
||||
script that some admins may wish to use.
|
||||
|
||||
*
|
||||
|
||||
--enable-kqueue - Use the superior kqueue(2) system call as
|
||||
opposed to the default poll(2). This is currently only available
|
||||
on FreeBSD 4.1 or higher.
|
||||
|
||||
*
|
||||
|
||||
--enable-devpoll - Enable the superior /dev/poll support on
|
||||
Solaris. Linux /dev/poll is broken and will not work with this
|
||||
option.
|
||||
|
||||
*
|
||||
|
||||
--enable-epoll - Enable the superior Linux Edge-Triggered Polling
|
||||
system. This is currently only available on 2.5 Linux kernel
|
||||
versions or later.
|
||||
|
||||
*
|
||||
|
||||
--enable-openssl - Enable the openssl dependent crypto functions.
|
||||
This will allow CHALLENGE to work and encrypted links. On systems
|
||||
where the configure script can automatically detect OpenSSL, this
|
||||
option is not necessary. If configure cannot find OpenSSL, you
|
||||
must specify a path with this option
|
||||
(--enable-openssl=/path/to/openssl)
|
||||
|
||||
*
|
||||
|
||||
--enable-ipv6 - Enable IPv6 support.
|
||||
|
||||
*
|
||||
|
||||
--enable-assert[=OPTION] - Enable some debugging code. OPTION is
|
||||
either 'soft' or 'hard' (default: hard). 'hard' should never be
|
||||
used on production servers as it may generate unnecessary cores.
|
||||
'soft' prevents cores from being generated but still imposes some
|
||||
additional load.
|
||||
|
||||
*
|
||||
|
||||
--enable-small-net - Tunes the server for smaller networks by
|
||||
reducing the startup memory footprint. This should really only be
|
||||
used for *small* networks, as this tends to be a performance hit
|
||||
on larger networks.
|
||||
|
||||
*
|
||||
|
||||
--with-nicklen=LENGTH - Sets the maximum NICK length. Note that
|
||||
this must be consistent across your entire network.
|
||||
3.
|
||||
|
||||
make should build ircd.
|
||||
|
||||
4.
|
||||
|
||||
make install will install the server, modules, and tools in the
|
||||
the prefix specified when configure was run.
|
||||
|
||||
5.
|
||||
|
||||
If you wish to enable the user log, oper log, and failed oper log,
|
||||
issue these commands at the shell prompt (in the prefix directory)
|
||||
|
||||
$ touch logs/userlog
|
||||
$ touch logs/operlog
|
||||
$ touch logs/foperlog
|
||||
|
||||
Note: If you use different names in ircd.conf, you must 'touch' the
|
||||
specific names.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
HOW TO GET HELP
|
||||
|
||||
Send Check or Money Order to... just kidding! You're on your own for
|
||||
support. Try asking other ircd-ratbox admins on EFnet if you can't fix it
|
||||
yourself. If you do fix anything, however, please send context or unified
|
||||
diffs to ircd-ratbox@lists.ratbox.org so the fixes can be incorporated into
|
||||
the next release of ircd-hybrid. If ratbox crashes on you, PLEASE contact
|
||||
ircd-ratbox@lists.ratbox.org ASAP with a backtrace of the core.
|
||||
|
||||
DISCUSSION: There is a mailing list for discussion of ratbox issues,
|
||||
To subscribe, visit:
|
||||
http://lists.ratbox.org/cgi-bin/mailman/listinfo/ircd-ratbox
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
NOTES
|
||||
|
||||
The best way to get a backtrace of the core is to follow this sequence of
|
||||
instructions:
|
||||
|
||||
1.
|
||||
|
||||
Change to the directory containing the core file
|
||||
|
||||
2.
|
||||
|
||||
Run gdb on the binary and the core file. With an unmodified ircd-ratbox
|
||||
installation, an example command line is below (in the /usr/local/ircd
|
||||
directory)
|
||||
|
||||
$ gdb bin/ircd ircd.core
|
||||
|
||||
3.
|
||||
|
||||
At the "(gdb)" prompt, enter the command "bt"
|
||||
|
||||
4.
|
||||
|
||||
Save the output of the backtrace command and send it to
|
||||
ircd-ratbox@lists.ratbox.org
|
||||
|
||||
5.
|
||||
|
||||
Be sure to save the ircd binary, the modules, and the core file in a
|
||||
safe place in case the developers need to look deeper than a backtrace
|
||||
provides.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
OPENSSL NOTES
|
||||
|
||||
Older FreeBSD machines sometimes have the obsolete ports version of
|
||||
OpenSSL libcrypto in /usr/local/lib. When configure is used with
|
||||
--enable-openssl, and libintl is detected in /usr/local/lib, the
|
||||
/usr/local/lib directory will be searched BEFORE the system /usr/lib for
|
||||
libraries by the linker. The linker may try to link to the old
|
||||
/usr/local/lib libcrypto instead of the system /usr/lib libcrypto. Some
|
||||
older versions may cause error messages similar to the following:
|
||||
|
||||
gcc -g -O2 -DIRCD_PREFIX=\"/home/wcampbel/ircd\" -Wl,-export-dynamic
|
||||
-L/usr/local/lib -o ircd blalloc.o channel.o vchannel.o class.o client.o
|
||||
dline_conf.o event.o fdlist.o fileio.o hash.o irc_string.o ircd.o ircdauth.o
|
||||
ircd_signal.o linebuf.o list.o listener.o m_error.o match.o memdebug.o
|
||||
modules.o motd.o mtrie_conf.o oldparse.o numeric.o packet.o parse.o res.o rsa.o
|
||||
restart.o s_auth.o s_bsd.o s_bsd_kqueue.o s_conf.o s_debug.o s_gline.o s_log.o
|
||||
s_misc.o s_serv.o s_stats.o s_user.o scache.o send.o sprintf_irc.o tools.o
|
||||
whowas.o lex.yy.o y.tab.o version.o -lintl -ldescrypt -lcrypto -lfl
|
||||
rsa.o: In function `get_randomness':
|
||||
/home/wcampbel/dev/ircd-ratbox/src/rsa.c(.text+0x60): undefined reference to
|
||||
`RAND_pseudo_bytes'
|
||||
/usr/local/lib/libcrypto.so: undefined reference to `ERR_load_RSAREF_strings'
|
||||
/usr/local/lib/libcrypto.so: undefined reference to `RSA_PKCS1_RSAref'
|
||||
*** Error code 1
|
||||
|
||||
If this is the case, you may need to rerun configure without the
|
||||
--enable-openssl option, manually edit src/Makefile and modules/Makefile
|
||||
to put -L/usr/lib before the -L/usr/local/lib in LDFLAGS, or remove the
|
||||
old OpenSSL from /usr/local, and recompile all applications that use
|
||||
libcrypto to use the system one.
|
1
LICENSE
1
LICENSE
|
@ -1,4 +1,3 @@
|
|||
# $Id: LICENSE 6 2005-09-10 01:02:21Z nenolod $
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
|
|
60
Makefile.am
Normal file
60
Makefile.am
Normal file
|
@ -0,0 +1,60 @@
|
|||
AUTOMAKE_OPTIONS = foreign
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
|
||||
SUBDIRS = librb
|
||||
|
||||
if BUILD_LTDL
|
||||
SUBDIRS += libltdl
|
||||
endif
|
||||
|
||||
SUBDIRS += ircd \
|
||||
ssld \
|
||||
wsockd \
|
||||
authd \
|
||||
bandb \
|
||||
tests \
|
||||
tools \
|
||||
modules \
|
||||
extensions \
|
||||
help \
|
||||
doc
|
||||
|
||||
BUILT_SOURCES = include/serno.h
|
||||
|
||||
include/serno.h:
|
||||
@if [ -d .git ]; then \
|
||||
revh=`git log -1 --date=format:%Y%m%d --pretty=format:%cd-%h`; \
|
||||
datecode=`git log -1 --pretty=format:%ct`; \
|
||||
if [ -n "$$revh" ]; then \
|
||||
echo '#define SERNO "'$$revh'"' >include/serno.h ; \
|
||||
echo "#define DATECODE $${datecode}UL" >>include/serno.h; \
|
||||
fi \
|
||||
fi
|
||||
@if [ ! -f include/serno.h ]; then \
|
||||
echo '#define SERNO "unknown"' >include/serno.h; \
|
||||
echo '#define DATECODE 0UL' >>include/serno.h; \
|
||||
fi
|
||||
|
||||
install-data-hook:
|
||||
test -d ${DESTDIR}${logdir} || mkdir -p ${DESTDIR}${logdir}
|
||||
|
||||
install-exec-hook:
|
||||
rm -f ${DESTDIR}${libdir}/*.la
|
||||
rm -f ${DESTDIR}${moduledir}/*.la
|
||||
rm -f ${DESTDIR}${moduledir}/autoload/*.la
|
||||
rm -f ${DESTDIR}${moduledir}/extensions/*.la
|
||||
rm -f ${DESTDIR}${libdir}/*.dll.a
|
||||
rm -f ${DESTDIR}${moduledir}/*.dll.a
|
||||
rm -f ${DESTDIR}${moduledir}/autoload/*.dll.a
|
||||
rm -f ${DESTDIR}${moduledir}/extensions/*.dll.a
|
||||
|
||||
distclean-local:
|
||||
rm -f librb/include/librb-config.h
|
||||
|
||||
clean-local:
|
||||
rm -f include/serno.h
|
||||
rm -f ircd/ircd_lexer.c
|
||||
rm -f ircd/ircd_parser.c
|
||||
rm -f ircd/ircd_parser.h
|
||||
rm -f ircd/version.c
|
||||
rm -f ircd/version.c.last
|
162
Makefile.in
162
Makefile.in
|
@ -1,162 +0,0 @@
|
|||
#************************************************************************
|
||||
#* IRC - Internet Relay Chat, Makefile
|
||||
#* Copyright (C) 1990, Jarkko Oikarinen
|
||||
#*
|
||||
#* 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.
|
||||
#*
|
||||
#* $Id: Makefile.in 1347 2006-05-17 14:49:13Z nenolod $
|
||||
#*/
|
||||
|
||||
RM=@RM@
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
bindir = @bindir@
|
||||
mandir = @mandir@
|
||||
libdir = @libdir@
|
||||
pkglibdir = @pkglibdir@
|
||||
moduledir = @moduledir@
|
||||
helpdir = @helpdir@
|
||||
sysconfdir = @sysconfdir@
|
||||
logdir = @logdir@
|
||||
rundir = @rundir@
|
||||
pkgrundir = @pkgrundir@
|
||||
localstatedir = @localstatedir@
|
||||
pkglocalstatedir= @pkglocalstatedir@
|
||||
PACKAGE_TARNAME = @PACKAGE_TARNAME@
|
||||
|
||||
# Default CFLAGS
|
||||
# CFLAGS = -g -O2 -DNDEBUG
|
||||
CFLAGS = @CFLAGS@
|
||||
# Developers CFLAGS
|
||||
#CFLAGS= -g -O2 -Wunused -Wall -ggdb -pedantic -Wshadow -Wmissing-declarations
|
||||
|
||||
# Default make flags - you may want to uncomment this on a multicpu machine
|
||||
#MFLAGS = -j 4
|
||||
|
||||
#
|
||||
# For developers
|
||||
#CFLAGS= -g -O2 -Wall
|
||||
|
||||
# You may need to define the FD_SETSIZE in order to overrule
|
||||
# the system one.
|
||||
#CFLAGS= -DNDEBUG -g -O2 -D"FD_SETSIZE=1024"
|
||||
SHELL=/bin/sh
|
||||
# `extensions' must be after `modules' for proper creation of $(moduledir).
|
||||
SUBDIRS=libratbox modules extensions src tools ssld bandb doc help
|
||||
CLEANDIRS = ${SUBDIRS}
|
||||
RSA_FILES=rsa_respond/README rsa_respond/respond.c rsa_respond/Makefile
|
||||
|
||||
all: build
|
||||
|
||||
|
||||
autoconf: configure.ac
|
||||
autoconf
|
||||
autoheader
|
||||
${RM} -f config.cache
|
||||
|
||||
build:
|
||||
-@if [ ! -f include/setup.h ] ; then \
|
||||
echo "Hmm...doesn't look like you've run configure..."; \
|
||||
echo "Doing so now."; \
|
||||
sh configure; \
|
||||
fi
|
||||
@if [ -d .git ] ; then \
|
||||
revh=`git log -1 --date=short --pretty=format:%cd_%h 2>/dev/null | sed -e s/-//g -e s/_/-/`;\
|
||||
[ -z "$$revh" ] || echo '#define SERNO "'$$revh'"' >include/serno.h ; \
|
||||
elif [ -d .hg ] ; then \
|
||||
revh=`hg parents --template '{date|shortdate}_{node|short}' 2>/dev/null | sed -e s/-//g -e s/_/-/`;\
|
||||
[ -z "$$revh" ] || echo '#define SERNO "'$$revh'"' >include/serno.h ; \
|
||||
fi
|
||||
@[ -f include/serno.h ] || echo '#define SERNO "unknown"' >include/serno.h
|
||||
@for i in $(SUBDIRS); do \
|
||||
echo "build ==> $$i";\
|
||||
cd $$i;\
|
||||
${MAKE} || exit; cd ..;\
|
||||
done
|
||||
|
||||
clean:
|
||||
${RM} -f *~ core rsa_respond.tar rsa_respond.tar.gz
|
||||
@for i in $(CLEANDIRS); do \
|
||||
echo "clean ==> $$i";\
|
||||
cd $$i;\
|
||||
${MAKE} clean; cd ..;\
|
||||
done
|
||||
-@if [ -f include/setup.h ] ; then \
|
||||
echo "To really restart installation, make distclean" ; \
|
||||
fi
|
||||
|
||||
distclean:
|
||||
${RM} -f Makefile *~ *.rej *.orig core ircd.core
|
||||
${RM} -f config.status config.cache config.log
|
||||
cd include; ${RM} -f setup.h *~ *.rej *.orig ; cd ..
|
||||
@for i in $(CLEANDIRS); do \
|
||||
echo "distclean ==> $$i";\
|
||||
cd $$i;\
|
||||
${MAKE} distclean; cd ..;\
|
||||
done
|
||||
|
||||
depend:
|
||||
@[ -f include/serno.h ] || echo '#define SERNO "unknown"' >include/serno.h
|
||||
@for i in $(SUBDIRS); do \
|
||||
echo "depend ==> $$i";\
|
||||
cd $$i;\
|
||||
${MAKE} depend; cd ..;\
|
||||
done
|
||||
|
||||
lint:
|
||||
@for i in $(SUBDIRS); do \
|
||||
echo "lint ==> $$i";\
|
||||
cd $$i;\
|
||||
${MAKE} lint; cd ..;\
|
||||
done
|
||||
|
||||
install-mkdirs:
|
||||
@echo "ircd: setting up ircd directory structure"
|
||||
-@if test ! -d $(DESTDIR)$(prefix); then \
|
||||
mkdir -p -m 755 $(DESTDIR)$(prefix); \
|
||||
fi
|
||||
-@if test ! -d $(DESTDIR)$(bindir); then \
|
||||
mkdir -p -m 755 $(DESTDIR)$(bindir); \
|
||||
fi
|
||||
-@if test ! -d $(DESTDIR)$(sysconfdir); then \
|
||||
mkdir -p -m 755 $(DESTDIR)$(sysconfdir); \
|
||||
fi
|
||||
-@if test ! -d $(DESTDIR)$(mandir); then \
|
||||
mkdir -p -m 755 $(DESTDIR)$(mandir); \
|
||||
fi
|
||||
-@if test ! -d $(DESTDIR)$(logdir); then \
|
||||
mkdir -p -m 755 $(DESTDIR)$(logdir); \
|
||||
fi
|
||||
-@if test ! -d '$(DESTDIR)$(pkgrundir)'; then \
|
||||
mkdir -p -m 755 '$(DESTDIR)$(pkgrundir)'; \
|
||||
fi
|
||||
-@if test ! -d '$(DESTDIR)$(pkglocalstatedir)'; then \
|
||||
mkdir -p -m 755 '$(DESTDIR)$(pkglocalstatedir)'; \
|
||||
fi
|
||||
|
||||
install: install-mkdirs all
|
||||
@for i in $(SUBDIRS); do \
|
||||
echo "install ==> $$i";\
|
||||
cd $$i;\
|
||||
${MAKE} install; \
|
||||
cd ..; \
|
||||
done
|
||||
|
||||
rsa_respond:
|
||||
@cd tools;\
|
||||
echo "Creating rsa_respond.tar.gz";\
|
||||
tar cf ../rsa_respond.tar $(RSA_FILES);\
|
||||
cd ..;\
|
||||
gzip rsa_respond.tar
|
200
NEWS.md
200
NEWS.md
|
@ -1,5 +1,6 @@
|
|||
# News
|
||||
|
||||
<<<<<<< .merge_file_h36DbE
|
||||
This is charybdis 3.5.7, Copyright (c) 2005-2019 Charybdis team.
|
||||
See LICENSE for licensing details (GPL v2).
|
||||
|
||||
|
@ -107,6 +108,205 @@ This is a minor bugfix release only
|
|||
|
||||
### misc
|
||||
- Backport various ssld IPC improvements from master.
|
||||
=======
|
||||
This is solanum 1.0-dev.
|
||||
See LICENSE for licensing details (GPL v2).
|
||||
|
||||
## solanum-1.0
|
||||
|
||||
Includes changes from charybdis-4.1.3-dev.
|
||||
|
||||
**This release includes breaking changes from charybdis 4.x.** Please pay close attention to
|
||||
bolded warnings in the full release notes below.
|
||||
|
||||
### build
|
||||
- Add `--with-asan` to configure to produce an ASan instrumented build
|
||||
|
||||
### server protocol
|
||||
- **Breaking:** Don't implicitly abort SASL when connection registration handshake completes;
|
||||
requires updating atheme to include https://github.com/atheme/atheme/pull/833.
|
||||
- OPER is now propagated globally, as :operator OPER opername privset
|
||||
|
||||
### user
|
||||
- **Breaking:** invite-notify is now enabled by loading the invite-notify extension
|
||||
- Prioritise older, more important client capabilities for clients that can only accept
|
||||
one line of CAP LS
|
||||
- Add the solanum.chat/realhost vendor capability (provided by extensions/cap\_realhost)
|
||||
- Add the solanum.chat/identify-msg vendor capability (provided by extensions/identify\_msg)
|
||||
- Server-side aliases preserve protocol framing characters
|
||||
- Add the +G user mode for soft callerid (implicitly allow users with a common channel)
|
||||
- /invite no longer punches through callerid
|
||||
- invite-notify now works
|
||||
- Rejectcached users are now sent the reason of the ban that caused their reject in most cases
|
||||
- Rejectcache entries expire when their corresponding K-lines do
|
||||
- One-argument /stats and zero-argument /motd are no longer ratelimited
|
||||
- Channel bans don't see through IP spoofs
|
||||
- Global /names now respects userhost-in-names
|
||||
- The `$j` extban is no longer usable inside ban exceptions
|
||||
- TLSv1 connections are accepted. They can still be disabled using OpenSSL config if you don't
|
||||
want them. TLSv1 existing is not thought to be a threat to up-to-date clients.
|
||||
|
||||
### oper
|
||||
- **Breaking:** Kick immunity for override is now its own extension, override\_kick\_immunity
|
||||
- **Breaking:** /stats A output now follows the same format as other stats letters
|
||||
- **Breaking:** helpops now uses +h instead of +H
|
||||
- **Breaking:** sno\_whois and the spy\_ extensions have been removed
|
||||
- **Breaking:** Using /wallops now requires the oper:wallops privilege instead of oper:massnotice
|
||||
- Opers now have their privset (identified by name) on remote servers
|
||||
- Oper-only umodes are refreshed after rehash and /grant
|
||||
- Extension modules can be reloaded
|
||||
- Override no longer spams about being enabled/disabled. It continues to spam on each use.
|
||||
- Add /testkline, which has the same syntax as /testline but doesn't check if the mask is ilined
|
||||
- /privs is now remote-capable and can respond with more than one line
|
||||
- Most commands now respect oper hiding
|
||||
- Massnotice (notice/privmsg to $$.../$#...) now alerts opers
|
||||
- Massnotice no longer imposes any restrictions on the target mask
|
||||
- /kline and /dline are hardened to invalid inputs
|
||||
- K/D-lines are more consistent about checking for encoded ipv4-in-ipv6 addresses
|
||||
- Add extensions/drain to reject new connections
|
||||
- Add extensions/filter to filter messages, parts and quits with a Hyperscan database
|
||||
- Add extensions/sasl\_usercloak to interpolate SASL account names into I-line spoofs
|
||||
|
||||
### conf
|
||||
- **Breaking:** Completely overhaul oper privs. All privset configs will need to be rewritten.
|
||||
See reference.conf for details.
|
||||
- Add the `kline_spoof_ip` I-line flag to make any spoof opaque to K-line matching
|
||||
- Add general::hide\_tkline\_duration to remove durations from user-visible ban reasons
|
||||
- Add general::hide\_opers, which behaves as if all opers have oper:hidden
|
||||
- Add general::post\_registration\_delay
|
||||
- Add general::tls\_ciphers\_oper\_only to hide TLS cipher details in /whois
|
||||
- Add channel::opmod\_send\_statusmsg to send messages allowed by +z to @#channel
|
||||
- Add class::max\_autoconn, with the behaviour of class::max\_number for servers prior to
|
||||
charybdis 4
|
||||
- Add `secure {}` blocks. Networks listed in a secure block gain +Z and can match `need_ssl` I-
|
||||
and O-lines.
|
||||
- Remove general::kline\_delay
|
||||
- If m\_webirc is loaded, connections that try to use a webirc auth block as their I-line will
|
||||
be disconnected on registration
|
||||
|
||||
### misc
|
||||
- **Breaking:** WEBIRC now processes the "secure" option as specified by IRCv3. Web gateways that
|
||||
do not set this option will need to be updated or their connections will show as insecure.
|
||||
- Successfully changing IP with WEBIRC now drops an identd username
|
||||
|
||||
### code
|
||||
- Channel lists are now kept sorted. A for-loop macro, `ITER_COMM_CHANNELS`, is introduced to
|
||||
efficiently compare two such lists.
|
||||
|
||||
|
||||
## charybdis-4.1.2
|
||||
|
||||
### user
|
||||
- src/s\_user.c: don't corrupt usermodes on module unload/reload
|
||||
|
||||
## charybdis-4.1.1
|
||||
|
||||
### security
|
||||
- Fix an issue with the PASS command and duplicate server instances.
|
||||
|
||||
### misc
|
||||
- Fix connection hang with blacklist/opm when ident is disabled.
|
||||
- Improve SASL CAP notification when the services server disconnects.
|
||||
- MbedTLS: Support ChaCha20-Poly1305 in default cipher suites.
|
||||
|
||||
## charybdis-4.1
|
||||
|
||||
### misc
|
||||
- SCTP is now supported for server connections (and optionally, user connections)
|
||||
|
||||
## charybdis-4.0.1
|
||||
|
||||
### server protocol
|
||||
- SJOIN messages were being constructed in a 1024 byte buffer and truncated to 512 bytes
|
||||
when sending. This caused channels with more than 50 users to fail to propagate all of
|
||||
them during a net join.
|
||||
|
||||
## charybdis-4.0
|
||||
|
||||
### build
|
||||
- Build system has been converted to libtool + automake for sanity reasons.
|
||||
- The compile date is now set at configure time rather than build time, allowing for
|
||||
reproducible builds. (#148, #149)
|
||||
- Support for GNUTLS 3.4 has been added.
|
||||
|
||||
### user
|
||||
- Import the ability to exceed MAXCHANNELS from ircd-seven.
|
||||
- Implement IRCv3.2 enhanced capability negotiation (`CAP LS 302`).
|
||||
- Implement support for receiving and sending IRCv3 message tags.
|
||||
- Implement IRCv3.2 capabilities: (#141)
|
||||
- account-tag
|
||||
- echo-message
|
||||
- invite-notify
|
||||
- sasl
|
||||
- server-time
|
||||
- SASL: certificate fingerprints are now always sent to the SASL agent, allowing for
|
||||
the certificate to be used as a second authentication factor.
|
||||
|
||||
### oper
|
||||
- Merge several features from ircd-seven:
|
||||
- Implement support for remote DIE/RESTART.
|
||||
- Implement support for remote MODLOAD et al commands.
|
||||
- Add the GRANT command which allows for temporarily opering a client.
|
||||
- Implement the hidden oper-only channel modes framework.
|
||||
- Implement a channel mode that disallows kicking IRC operators (+M).
|
||||
- Enhance the oper override system, allowing more flexibility and detail
|
||||
in network-wide notices.
|
||||
- DNS, ident, and blacklist lookups have been moved to a dedicated daemon known
|
||||
as authd. Some cosmetic changes to blacklist statistics and rejection notices
|
||||
have resulted.
|
||||
- An experimental OPM scanner has been added to authd. Plaintext SOCKS4,
|
||||
SOCKS5, and HTTP CONNECT proxies can be checked for.
|
||||
- The LOCOPS command has been moved from core to an extension.
|
||||
- All core modules in charybdis have descriptions, which are shown in MODLIST.
|
||||
- Suffixes should not be used when doing /MODLOAD, /MODUNLOAD, /MODRELOAD, etc.
|
||||
|
||||
### misc
|
||||
- Support for WebSocket has been added, use the listen::wsock option to switch
|
||||
a listener into websocket mode.
|
||||
|
||||
### conf
|
||||
- Add the ability to strip color codes from topics unconditionally.
|
||||
- The obsolete hub option from server info has been removed.
|
||||
|
||||
### docs
|
||||
- The documentation has been cleaned up; obsolete files have been purged, and
|
||||
files have been renamed and shuffled around to be more consistent.
|
||||
|
||||
### code
|
||||
- `common.h` is gone. Everything useful in it was moved to `ircd_defs.h`.
|
||||
- `config.h` is gone; the few remaining knobs in it were not for configuration
|
||||
by mere mortals, and mostly existed as a 2.8 relic. Most of the knobs live in
|
||||
`defaults.h`, but one is well-advised to stay away unless they know exactly
|
||||
what they are doing.
|
||||
- A new module API has been introduced, known as AV2. It includes things such as
|
||||
module datecodes (to ensure modules don't fall out of sync with the code),
|
||||
module descriptions, and other fun things.
|
||||
- Alias and module commands are now in m_alias and m_modules, respectively, and
|
||||
can be reloaded if need be. For sanity reasons, m_modules is a core module,
|
||||
and cannot be unloaded.
|
||||
- irc_dictionary and irc_radixtree related functions are now in librb, and
|
||||
prefixed accordingly. Typedefs have been added for consistency with existing
|
||||
data structures. For example, now you would write `rb_dictionary *foo` and
|
||||
`RB_DICTIONARY_FOREACH`.
|
||||
- C99 bools are now included and used in the code. Don't use ints as simple true
|
||||
or false flags anymore. In accordance with this change, the `YES`/`NO` and
|
||||
`TRUE`/`FALSE` macros have been removed.
|
||||
- Return types from command handlers have been axed, as they have been useless
|
||||
for years.
|
||||
- libratbox has been renamed to librb, as we have diverged from upstream long
|
||||
ago.
|
||||
- Almost all 2.8-style hashtable structures have been moved to dictionaries or
|
||||
radix trees, resulting in significant memory savings.
|
||||
- The block allocator has been disabled and is no longer used.
|
||||
- The ratbox client capabilities have been ported to use the ircd capabilities
|
||||
framework, allowing for modules to provide capabilities.
|
||||
- Support for restarting ssld has been added. ssld processes which are still
|
||||
servicing clients will remain in use, but not service new connections, and
|
||||
are garbage collected when they are no longer servicing connections.
|
||||
- Support for ratbox-style 'iodebug' hooks has been removed.
|
||||
- New channel types may be added by modules, see `extensions/chantype_dummy.c`
|
||||
for a very simple example.
|
||||
>>>>>>> .merge_file_4c8glm
|
||||
|
||||
## charybdis-3.5.0
|
||||
|
||||
|
|
109
README.md
109
README.md
|
@ -1,30 +1,82 @@
|
|||
# charybdis
|
||||
# solanum ![Build Status](https://github.com/solanum-ircd/solanum/workflows/CI/badge.svg)
|
||||
|
||||
Charybdis is a reference implementation of the IRCv3.1 server component. It is meant to be
|
||||
used with an IRCv3-capable services implementation such as [Atheme][atheme] or [Anope][anope].
|
||||
Solanum is an IRCv3 server designed to be highly scalable. It implements IRCv3.1 and some parts of IRCv3.2.
|
||||
|
||||
[atheme]: http://www.atheme.net/
|
||||
It is meant to be used with an IRCv3-capable services implementation such as [Atheme][atheme] or [Anope][anope].
|
||||
|
||||
[atheme]: https://atheme.github.io/
|
||||
[anope]: http://www.anope.org/
|
||||
|
||||
# necessary requirements
|
||||
|
||||
* A supported platform
|
||||
* A working dynamic load library.
|
||||
* A working lex. Solaris /usr/ccs/bin/lex appears to be broken, on this system flex should be used.
|
||||
* A working dynamic library system
|
||||
* A working lex and yacc - flex and bison should work
|
||||
|
||||
# platforms
|
||||
|
||||
Solanum is developed on Linux with glibc, but is currently portable to most POSIX-compatible operating systems.
|
||||
However, this portability is likely to be removed unless someone is willing to maintain it. If you'd like to be that
|
||||
person, please let us know on IRC.
|
||||
|
||||
# platform specific errata
|
||||
|
||||
These are known issues and workarounds for various platforms.
|
||||
|
||||
* **macOS**: you must set the `LIBTOOLIZE` environment variable to point to glibtoolize before running autogen.sh:
|
||||
|
||||
```bash
|
||||
brew install libtool
|
||||
export LIBTOOLIZE="/usr/local/bin/glibtoolize"
|
||||
./autogen.sh
|
||||
```
|
||||
|
||||
* **FreeBSD**: if you are compiling with ipv6 you may experience
|
||||
problems with ipv4 due to the way the socket code is written. To
|
||||
fix this you must: `sysctl net.inet6.ip6.v6only=0`
|
||||
|
||||
* **Solaris**: you may have to set your `PATH` to include `/usr/gnu/bin` and `/usr/gnu/sbin` before `/usr/bin`
|
||||
and `/usr/sbin`. Solaris's default tools don't seem to play nicely with the configure script. When running
|
||||
as a 32-bit binary, it should be started as:
|
||||
|
||||
```bash
|
||||
ulimit -n 4095 ; LD_PRELOAD_32=/usr/lib/extendedFILE.so.1 ./solanum
|
||||
```
|
||||
|
||||
# building
|
||||
|
||||
```bash
|
||||
sudo apt install build-essential pkg-config automake libtool libsqlite3-dev # or equivalent for your distribution
|
||||
./autogen.sh
|
||||
./configure --prefix=/path/to/installation
|
||||
make
|
||||
make check # run tests
|
||||
make install
|
||||
```
|
||||
|
||||
See `./configure --help` for build options.
|
||||
|
||||
# feature specific requirements
|
||||
|
||||
* For SSL/TLS client and server connections, one of:
|
||||
|
||||
<<<<<<< .merge_file_7Huc5m
|
||||
* OpenSSL 1.0.0 or newer (--enable-openssl)
|
||||
* LibreSSL (--enable-openssl)
|
||||
* MbedTLS (--enable-mbedtls)
|
||||
* GnuTLS (--enable-gnutls)
|
||||
=======
|
||||
* OpenSSL 1.0.0 or newer (`--enable-openssl`)
|
||||
* LibreSSL (`--enable-openssl`)
|
||||
* mbedTLS (`--enable-mbedtls`)
|
||||
* GnuTLS (`--enable-gnutls`)
|
||||
>>>>>>> .merge_file_dqpn0B
|
||||
|
||||
* For certificate-based oper CHALLENGE, OpenSSL 1.0.0 or newer.
|
||||
(Using CHALLENGE is not recommended for new deployments, so if you want to use a different TLS library,
|
||||
feel free.)
|
||||
|
||||
<<<<<<< .merge_file_7Huc5m
|
||||
* For ECDHE under OpenSSL, on Solaris and RHEL/Fedora (and its derivatives such as CentOS) you will
|
||||
need to compile your own OpenSSL on these systems, as they have removed support for ECC/ECDHE.
|
||||
Alternatively, consider using another library (see above).
|
||||
|
@ -32,35 +84,28 @@ used with an IRCv3-capable services implementation such as [Atheme][atheme] or [
|
|||
# tips
|
||||
|
||||
* To report bugs in charybdis, visit us on IRC at chat.freenode.net #charybdis
|
||||
=======
|
||||
* For ECDHE under OpenSSL, on Solaris you will need to compile your own OpenSSL on these systems, as they
|
||||
have removed support for ECC/ECDHE. Alternatively, consider using another library (see above).
|
||||
|
||||
* Please read doc/index.txt to get an overview of the current documentation.
|
||||
# tips
|
||||
|
||||
* The files, /etc/services, /etc/protocols, and /etc/resolv.conf, SHOULD be
|
||||
* To report bugs in Solanum, visit us at `#solanum` on [Libera Chat](https://libera.chat)
|
||||
>>>>>>> .merge_file_dqpn0B
|
||||
|
||||
* Please read [doc/readme.txt](doc/readme.txt) to get an overview of the current documentation.
|
||||
|
||||
* Read the [NEWS.md](NEWS.md) file for what's new in this release.
|
||||
|
||||
* The files, `/etc/services`, `/etc/protocols`, and `/etc/resolv.conf`, SHOULD be
|
||||
readable by the user running the server in order for ircd to start with
|
||||
the correct settings. If these files are wrong, charybdis will try to use
|
||||
127.0.0.1 for a resolver as a last-ditch effort.
|
||||
the correct settings. If these files are wrong, Solanum will try to use
|
||||
`127.0.0.1` for a resolver as a last-ditch effort.
|
||||
|
||||
* FREEBSD USERS: if you are compiling with ipv6 you may experience
|
||||
problems with ipv4 due to the way the socket code is written. To
|
||||
fix this you must: "sysctl net.inet6.ip6.v6only=0"
|
||||
# git access
|
||||
|
||||
* SOLARIS USERS: this code appears to tickle a bug in older gcc and
|
||||
egcs ONLY on 64-bit Solaris7. gcc-2.95 and SunPro C on 64bit should
|
||||
work fine, and any gcc or SunPro compiled on 32bit.
|
||||
* The Solanum git repository can be checked out using the following command:
|
||||
`git clone https://github.com/solanum-ircd/solanum`
|
||||
|
||||
* SUPPORTED PLATFORMS: this code should compile without any warnings on:
|
||||
|
||||
* FreeBSD 10
|
||||
* Gentoo & Gentoo Hardened ~x86/~amd64/~fbsd
|
||||
* RHEL 6 / 7
|
||||
* Debian Jessie
|
||||
* OpenSuSE 11/12
|
||||
* OpenSolaris 2008.x?
|
||||
* Solaris 10 sparc.
|
||||
|
||||
Please let us know if you find otherwise.
|
||||
It probably does not compile on AIX, IRIX or libc5 Linux.
|
||||
|
||||
* Please read NEWS for information about what is in this release.
|
||||
|
||||
* Other files recommended for reading: BUGS, INSTALL
|
||||
* Solanum's git repository can be browsed over the Internet at the following address:
|
||||
https://github.com/solanum-ircd/solanum
|
||||
|
|
61
TODO
61
TODO
|
@ -1,61 +0,0 @@
|
|||
/ = in progress, x = done, ? = to be discussed, F = charybdis3.1 or next releases
|
||||
|
||||
[/] finish legacy code removal
|
||||
[x] remove 2.8 report_error() in ratbox imported stuff
|
||||
[F] client.c, channel.c is very 2.8 style still. it'd be nice to pack them into their own
|
||||
namespace and such. moreover, the other 2.8 code needs similar rewriting/reworking too...
|
||||
[x] merge m_join.c and m_sjoin.c in one module (same functions, done in ratbox3)
|
||||
[ ] rewrite s_auth.c
|
||||
[ ] authentication state/lock manager
|
||||
[ ] move resolver/auth checker code into separated modules
|
||||
[x] port to libratbox
|
||||
[x] get it running
|
||||
[x] clean up maxconnections kludges &c
|
||||
[x] in-process SSL
|
||||
[x] port and use ratbox ssld for server links
|
||||
[x] merge with libratbox SVN
|
||||
[x] ssl stuff
|
||||
[x] client-to-client ssl
|
||||
[x] server-to-server ssl
|
||||
[x] ssl usermode (+Z)
|
||||
[x] ssl channelmode (done by extban and chm_compat)
|
||||
[x] tool for generating ssl certificates and other stuff
|
||||
[x] gnutls backend for at least SSL connections (replacing libcrypto use in m_challenge would be nice too)
|
||||
[x] merge some stuff from ircd-seven directly (to be determined what)
|
||||
[x] remote d:lines support
|
||||
[x] PASS selector:password for auth{} (useful for dynamic IPs)
|
||||
[ ] kline/xline/resv sync (what about spb's extension?)
|
||||
[x] drop non-TS6 (legacy protocol) support
|
||||
[?] Patch or core-feature - libguess on-fly any-charset-to-utf8 translation
|
||||
[x] module engine rework
|
||||
[?] MODULE_DEPEND and MODULE_CONFLICT for building extension dependencies (backport from shadowircd)
|
||||
[x] more beautiful way of adding new channel modes by module
|
||||
[x] basic functionality
|
||||
[x] some example modules
|
||||
[x] another idea is too make that work with privilege groups, like "serveradmins" or "ircops"
|
||||
[ ] make nick/user/host validation functions/match tables able to work in separated modules,
|
||||
this will help us making support for native characters sets/slashes in host etc
|
||||
[ ] auth checker module
|
||||
[ ] resolver module
|
||||
[x] privilege system for privilege groups, something like
|
||||
in .conf: helper { kill_global, rehash, kline_local }
|
||||
in modules: privilege_add("kill_global"), has_privilege(source_p, "kill_global") etc, should work the way dynamic cflags/umodes done
|
||||
-- this is done kinda like this, but not really. See HasPrivilege() calls. privilege_add() was not needed ~nenolod
|
||||
[x] Remove glines entirely
|
||||
[/] test suite as in ircu
|
||||
[?] win32
|
||||
[?] mingw support
|
||||
[R] win32 native support - VS doesn't follow C99, this will require us switching back to C89 with libratbox and (future) core
|
||||
[x] Bug fixes
|
||||
[x] Compilation without zlib headers fails - fixed
|
||||
[x] Compilation date and time in server welcome message is in OS locale - looks ugly 'cause often it's not match user's codepage
|
||||
[ ] Improvments
|
||||
[ ] ircd shouldn't need bison/byacc/yacc or flex for compilation
|
||||
--- other stuff
|
||||
[?] internally split out +o/+v "ranks" into a series of permissions. this could allow for configure-defined
|
||||
special access levels, halfops, etc. (would need to match globally, somehow. extra SVINFO param?)
|
||||
might be backported from shadowircd in future (chanroles planned)
|
||||
[?] somehow hide channel operators like ircnet can do?
|
||||
couldn't be done via extension currently - compilation-time option acceptable?
|
||||
[x] create chmode.h and put there all declarations of chm_* - this will make some modules clean
|
||||
[?] Move oper override server WALLOPS to global server notices?
|
17
authd/Makefile.am
Normal file
17
authd/Makefile.am
Normal file
|
@ -0,0 +1,17 @@
|
|||
pkglibexec_PROGRAMS = authd
|
||||
AM_CFLAGS=$(WARNFLAGS)
|
||||
AM_CPPFLAGS = -I../include -I../librb/include
|
||||
|
||||
authd_SOURCES = \
|
||||
authd.c \
|
||||
dns.c \
|
||||
notice.c \
|
||||
provider.c \
|
||||
res.c \
|
||||
reslib.c \
|
||||
providers/dnsbl.c \
|
||||
providers/ident.c \
|
||||
providers/rdns.c \
|
||||
providers/opm.c
|
||||
|
||||
authd_LDADD = ../librb/src/librb.la
|
216
authd/authd.c
Normal file
216
authd/authd.c
Normal file
|
@ -0,0 +1,216 @@
|
|||
/* authd/authd.c - main code for authd
|
||||
* Copyright (c) 2016 Ariadne Conill <ariadne@dereferenced.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice is present in all copies.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "authd.h"
|
||||
#include "dns.h"
|
||||
#include "provider.h"
|
||||
#include "notice.h"
|
||||
|
||||
#define MAXPARA 10
|
||||
|
||||
static void error_cb(rb_helper *helper) __attribute__((noreturn));
|
||||
static void handle_reload(int parc, char *parv[]);
|
||||
static void handle_stat(int parc, char *parv[]);
|
||||
static void handle_options(int parc, char *parv[]);
|
||||
|
||||
rb_helper *authd_helper = NULL;
|
||||
authd_cmd_handler authd_cmd_handlers[256] = {
|
||||
['C'] = handle_new_connection,
|
||||
['D'] = handle_resolve_dns,
|
||||
['E'] = handle_cancel_connection,
|
||||
['O'] = handle_options,
|
||||
['R'] = handle_reload,
|
||||
['S'] = handle_stat,
|
||||
};
|
||||
|
||||
authd_stat_handler authd_stat_handlers[256] = {
|
||||
['D'] = enumerate_nameservers,
|
||||
};
|
||||
|
||||
authd_reload_handler authd_reload_handlers[256] = {
|
||||
['D'] = reload_nameservers,
|
||||
};
|
||||
|
||||
rb_dictionary *authd_option_handlers;
|
||||
|
||||
static void
|
||||
handle_stat(int parc, char *parv[])
|
||||
{
|
||||
authd_stat_handler handler;
|
||||
unsigned long long rid;
|
||||
|
||||
if(parc < 3)
|
||||
{
|
||||
warn_opers(L_CRIT, "BUG: handle_stat received too few parameters (at least 3 expected, got %d)", parc);
|
||||
return;
|
||||
}
|
||||
|
||||
if((rid = strtoull(parv[1], NULL, 16)) > UINT32_MAX)
|
||||
{
|
||||
warn_opers(L_CRIT, "BUG: handle_stat got a rid that was too large: %s", parv[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(handler = authd_stat_handlers[(unsigned char)parv[2][0]]))
|
||||
return;
|
||||
|
||||
handler((uint32_t)rid, parv[2][0]);
|
||||
}
|
||||
|
||||
static void
|
||||
handle_options(int parc, char *parv[])
|
||||
{
|
||||
struct auth_opts_handler *handler;
|
||||
|
||||
if(parc < 2)
|
||||
{
|
||||
warn_opers(L_CRIT, "BUG: handle_options received too few parameters (at least 2 expected, got %d)", parc);
|
||||
return;
|
||||
}
|
||||
|
||||
if((handler = rb_dictionary_retrieve(authd_option_handlers, parv[1])) == NULL)
|
||||
{
|
||||
warn_opers(L_CRIT, "BUG: handle_options got a bad option type %s", parv[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
if((parc - 2) < handler->min_parc)
|
||||
{
|
||||
warn_opers(L_CRIT, "BUG: handle_options received too few parameters (at least %d expected, got %d)", handler->min_parc, parc);
|
||||
return;
|
||||
}
|
||||
|
||||
handler->handler(parv[1], parc - 2, (const char **)&parv[2]);
|
||||
}
|
||||
|
||||
static void
|
||||
handle_reload(int parc, char *parv[])
|
||||
{
|
||||
authd_reload_handler handler;
|
||||
|
||||
if(parc <= 2)
|
||||
{
|
||||
/* Reload all handlers */
|
||||
for(size_t i = 0; i < 256; i++)
|
||||
{
|
||||
if ((handler = authd_reload_handlers[(unsigned char) i]) != NULL)
|
||||
handler('\0');
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(handler = authd_reload_handlers[(unsigned char)parv[1][0]]))
|
||||
return;
|
||||
|
||||
handler(parv[1][0]);
|
||||
}
|
||||
|
||||
static void
|
||||
parse_request(rb_helper *helper)
|
||||
{
|
||||
static char *parv[MAXPARA + 1];
|
||||
static char readbuf[READBUF_SIZE];
|
||||
int parc;
|
||||
int len;
|
||||
authd_cmd_handler handler;
|
||||
|
||||
while((len = rb_helper_read(helper, readbuf, sizeof(readbuf))) > 0)
|
||||
{
|
||||
parc = rb_string_to_array(readbuf, parv, MAXPARA);
|
||||
|
||||
if(parc < 1)
|
||||
continue;
|
||||
|
||||
handler = authd_cmd_handlers[(unsigned char)parv[0][0]];
|
||||
if (handler != NULL)
|
||||
handler(parc, parv);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
error_cb(rb_helper *helper)
|
||||
{
|
||||
exit(EX_ERROR);
|
||||
}
|
||||
|
||||
static void
|
||||
dummy_handler(int sig)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
setup_signals(void)
|
||||
{
|
||||
struct sigaction act;
|
||||
|
||||
act.sa_flags = 0;
|
||||
act.sa_handler = SIG_IGN;
|
||||
sigemptyset(&act.sa_mask);
|
||||
sigaddset(&act.sa_mask, SIGPIPE);
|
||||
sigaddset(&act.sa_mask, SIGALRM);
|
||||
#ifdef SIGTRAP
|
||||
sigaddset(&act.sa_mask, SIGTRAP);
|
||||
#endif
|
||||
|
||||
#ifdef SIGWINCH
|
||||
sigaddset(&act.sa_mask, SIGWINCH);
|
||||
sigaction(SIGWINCH, &act, 0);
|
||||
#endif
|
||||
sigaction(SIGPIPE, &act, 0);
|
||||
#ifdef SIGTRAP
|
||||
sigaction(SIGTRAP, &act, 0);
|
||||
#endif
|
||||
|
||||
act.sa_handler = dummy_handler;
|
||||
sigaction(SIGALRM, &act, 0);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
setup_signals();
|
||||
|
||||
authd_helper = rb_helper_child(parse_request, error_cb, NULL, NULL, NULL, 256, 256, 256); /* XXX fix me */
|
||||
if(authd_helper == NULL)
|
||||
{
|
||||
fprintf(stderr, "authd is not meant to be invoked by end users\n");
|
||||
exit(EX_ERROR);
|
||||
}
|
||||
|
||||
rb_set_time();
|
||||
setup_signals();
|
||||
|
||||
authd_option_handlers = rb_dictionary_create("authd options handlers", rb_strcasecmp);
|
||||
|
||||
init_resolver();
|
||||
init_providers();
|
||||
rb_init_prng(NULL, RB_PRNG_DEFAULT);
|
||||
|
||||
rb_helper_loop(authd_helper, 0);
|
||||
|
||||
/*
|
||||
* XXX this function will never be called from here -- is it necessary?
|
||||
*/
|
||||
destroy_providers();
|
||||
|
||||
return 0;
|
||||
}
|
59
authd/authd.h
Normal file
59
authd/authd.h
Normal file
|
@ -0,0 +1,59 @@
|
|||
/* authd/dns.h - header for authd DNS functions
|
||||
* Copyright (c) 2016 Ariadne Conill <ariadne@dereferenced.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice is present in all copies.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _AUTHD_H
|
||||
#define _AUTHD_H
|
||||
|
||||
#include "stdinc.h"
|
||||
#include "rb_lib.h"
|
||||
#include "rb_dictionary.h"
|
||||
|
||||
#include "setup.h"
|
||||
#include "ircd_defs.h"
|
||||
|
||||
typedef enum exit_reasons
|
||||
{
|
||||
EX_ERROR = 1,
|
||||
EX_DNS_ERROR = 2,
|
||||
EX_PROVIDER_ERROR = 3,
|
||||
} exit_reasons;
|
||||
|
||||
typedef void (*provider_opts_handler_t)(const char *, int, const char **);
|
||||
|
||||
struct auth_opts_handler
|
||||
{
|
||||
const char *option;
|
||||
int min_parc;
|
||||
provider_opts_handler_t handler;
|
||||
};
|
||||
|
||||
extern rb_helper *authd_helper;
|
||||
|
||||
typedef void (*authd_cmd_handler)(int parc, char *parv[]);
|
||||
typedef void (*authd_stat_handler)(uint32_t rid, const char letter);
|
||||
typedef void (*authd_reload_handler)(const char letter);
|
||||
|
||||
extern authd_cmd_handler authd_cmd_handlers[256];
|
||||
extern authd_stat_handler authd_stat_handlers[256];
|
||||
extern authd_reload_handler authd_reload_handlers[256];
|
||||
|
||||
extern rb_dictionary *authd_option_handlers;
|
||||
|
||||
#endif
|
303
authd/dns.c
Normal file
303
authd/dns.c
Normal file
|
@ -0,0 +1,303 @@
|
|||
/* authd/dns.c - authd DNS functions
|
||||
* Copyright (c) 2016 Ariadne Conill <ariadne@dereferenced.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice is present in all copies.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "authd.h"
|
||||
#include "dns.h"
|
||||
#include "notice.h"
|
||||
#include "res.h"
|
||||
|
||||
static void handle_lookup_ip_reply(void *data, struct DNSReply *reply);
|
||||
static void handle_lookup_hostname_reply(void *data, struct DNSReply *reply);
|
||||
|
||||
uint64_t query_count = 0;
|
||||
|
||||
/* A bit different from ircd... you just get a dns_query object.
|
||||
*
|
||||
* It gets freed whenever the res code gets back to us.
|
||||
*/
|
||||
struct dns_query *
|
||||
lookup_ip(const char *host, int aftype, DNSCB callback, void *data)
|
||||
{
|
||||
struct dns_query *query = rb_malloc(sizeof(struct dns_query));
|
||||
int g_type;
|
||||
|
||||
if(aftype == AF_INET)
|
||||
{
|
||||
query->type = QUERY_A;
|
||||
g_type = T_A;
|
||||
}
|
||||
else if(aftype == AF_INET6)
|
||||
{
|
||||
query->type = QUERY_AAAA;
|
||||
g_type = T_AAAA;
|
||||
}
|
||||
else
|
||||
{
|
||||
rb_free(query);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
query->id = query_count++;
|
||||
query->callback = callback;
|
||||
query->data = data;
|
||||
|
||||
query->query.ptr = query;
|
||||
query->query.callback = handle_lookup_ip_reply;
|
||||
|
||||
gethost_byname_type(host, &query->query, g_type);
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
/* See lookup_ip's comment */
|
||||
struct dns_query *
|
||||
lookup_hostname(const char *ip, DNSCB callback, void *data)
|
||||
{
|
||||
struct dns_query *query = rb_malloc(sizeof(struct dns_query));
|
||||
int aftype;
|
||||
|
||||
if(!rb_inet_pton_sock(ip, &query->addr))
|
||||
{
|
||||
rb_free(query);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
aftype = GET_SS_FAMILY(&query->addr);
|
||||
|
||||
if(aftype == AF_INET)
|
||||
query->type = QUERY_PTR_A;
|
||||
else if(aftype == AF_INET6)
|
||||
query->type = QUERY_PTR_AAAA;
|
||||
else
|
||||
{
|
||||
rb_free(query);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
query->id = query_count++;
|
||||
query->callback = callback;
|
||||
query->data = data;
|
||||
|
||||
query->query.ptr = query;
|
||||
query->query.callback = handle_lookup_hostname_reply;
|
||||
|
||||
gethost_byaddr(&query->addr, &query->query);
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
/* Cancel a pending query */
|
||||
void
|
||||
cancel_query(struct dns_query *query)
|
||||
{
|
||||
query->callback = query->data = NULL;
|
||||
}
|
||||
|
||||
/* Callback from gethost_byname_type */
|
||||
static void
|
||||
handle_lookup_ip_reply(void *data, struct DNSReply *reply)
|
||||
{
|
||||
struct dns_query *query = data;
|
||||
char ip[HOSTIPLEN] = "*";
|
||||
|
||||
if(query == NULL)
|
||||
{
|
||||
/* Shouldn't happen */
|
||||
warn_opers(L_CRIT, "DNS: handle_lookup_ip_reply: query == NULL!");
|
||||
exit(EX_DNS_ERROR);
|
||||
}
|
||||
|
||||
if(reply == NULL)
|
||||
goto end;
|
||||
|
||||
switch(query->type)
|
||||
{
|
||||
case QUERY_A:
|
||||
if(GET_SS_FAMILY(&reply->addr) == AF_INET)
|
||||
rb_inet_ntop_sock((struct sockaddr *)&reply->addr, ip, sizeof(ip));
|
||||
break;
|
||||
case QUERY_AAAA:
|
||||
if(GET_SS_FAMILY(&reply->addr) == AF_INET6)
|
||||
{
|
||||
rb_inet_ntop_sock((struct sockaddr *)&reply->addr, ip, sizeof(ip));
|
||||
if(ip[0] == ':')
|
||||
{
|
||||
memmove(&ip[1], ip, strlen(ip));
|
||||
ip[0] = '0';
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
warn_opers(L_CRIT, "DNS: handle_lookup_ip_reply: unknown query type %d",
|
||||
query->type);
|
||||
exit(EX_DNS_ERROR);
|
||||
}
|
||||
|
||||
end:
|
||||
if(query->callback)
|
||||
query->callback(ip, ip[0] != '*', query->type, query->data);
|
||||
|
||||
rb_free(query);
|
||||
}
|
||||
|
||||
/* Callback from gethost_byaddr */
|
||||
static void
|
||||
handle_lookup_hostname_reply(void *data, struct DNSReply *reply)
|
||||
{
|
||||
struct dns_query *query = data;
|
||||
char *hostname = NULL;
|
||||
|
||||
if(query == NULL)
|
||||
{
|
||||
/* Shouldn't happen */
|
||||
warn_opers(L_CRIT, "DNS: handle_lookup_hostname_reply: query == NULL!");
|
||||
exit(EX_DNS_ERROR);
|
||||
}
|
||||
|
||||
if(reply == NULL)
|
||||
goto end;
|
||||
|
||||
if(query->type == QUERY_PTR_A)
|
||||
{
|
||||
struct sockaddr_in *ip, *ip_fwd;
|
||||
ip = (struct sockaddr_in *) &query->addr;
|
||||
ip_fwd = (struct sockaddr_in *) &reply->addr;
|
||||
|
||||
if(ip->sin_addr.s_addr == ip_fwd->sin_addr.s_addr)
|
||||
hostname = reply->h_name;
|
||||
}
|
||||
else if(query->type == QUERY_PTR_AAAA)
|
||||
{
|
||||
struct sockaddr_in6 *ip, *ip_fwd;
|
||||
ip = (struct sockaddr_in6 *) &query->addr;
|
||||
ip_fwd = (struct sockaddr_in6 *) &reply->addr;
|
||||
|
||||
if(memcmp(&ip->sin6_addr, &ip_fwd->sin6_addr, sizeof(struct in6_addr)) == 0)
|
||||
hostname = reply->h_name;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Shouldn't happen */
|
||||
warn_opers(L_CRIT, "DNS: handle_lookup_hostname_reply: unknown query type %d",
|
||||
query->type);
|
||||
exit(EX_DNS_ERROR);
|
||||
}
|
||||
end:
|
||||
if(query->callback)
|
||||
query->callback(hostname, hostname != NULL, query->type, query->data);
|
||||
|
||||
rb_free(query);
|
||||
}
|
||||
|
||||
static void
|
||||
submit_dns_answer(const char *reply, bool status, query_type type, void *data)
|
||||
{
|
||||
char *id = data;
|
||||
|
||||
if(!id || type == QUERY_INVALID)
|
||||
{
|
||||
warn_opers(L_CRIT, "DNS: submit_dns_answer gave us a bad query");
|
||||
exit(EX_DNS_ERROR);
|
||||
}
|
||||
|
||||
if(reply == NULL || status == false)
|
||||
{
|
||||
rb_helper_write(authd_helper, "E %s E %c *", id, type);
|
||||
rb_free(id);
|
||||
return;
|
||||
}
|
||||
|
||||
rb_helper_write(authd_helper, "E %s O %c %s", id, type, reply);
|
||||
rb_free(id);
|
||||
}
|
||||
|
||||
void
|
||||
handle_resolve_dns(int parc, char *parv[])
|
||||
{
|
||||
char *id = rb_strdup(parv[1]);
|
||||
char qtype = *parv[2];
|
||||
char *record = parv[3];
|
||||
int aftype = AF_INET;
|
||||
|
||||
switch(qtype)
|
||||
{
|
||||
case '6':
|
||||
aftype = AF_INET6;
|
||||
case '4':
|
||||
if(!lookup_ip(record, aftype, submit_dns_answer, id))
|
||||
submit_dns_answer(NULL, false, qtype, NULL);
|
||||
break;
|
||||
case 'S':
|
||||
case 'R':
|
||||
if(!lookup_hostname(record, submit_dns_answer, id))
|
||||
submit_dns_answer(NULL, false, qtype, NULL);
|
||||
break;
|
||||
default:
|
||||
warn_opers(L_CRIT, "DNS: handle_resolve_dns got an unknown query: %c", qtype);
|
||||
exit(EX_DNS_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
enumerate_nameservers(uint32_t rid, const char letter)
|
||||
{
|
||||
char buf[(HOSTIPLEN + 1) * IRCD_MAXNS];
|
||||
size_t s = 0;
|
||||
|
||||
if (!irc_nscount)
|
||||
{
|
||||
/* Shouldn't happen */
|
||||
warn_opers(L_CRIT, "DNS: no name servers!");
|
||||
stats_error(rid, letter, "NONAMESERVERS");
|
||||
exit(EX_DNS_ERROR);
|
||||
}
|
||||
|
||||
for(int i = 0; i < irc_nscount; i++)
|
||||
{
|
||||
char addr[HOSTIPLEN];
|
||||
size_t addrlen;
|
||||
|
||||
rb_inet_ntop_sock((struct sockaddr *)&irc_nsaddr_list[i], addr, sizeof(addr));
|
||||
|
||||
if (!addr[0])
|
||||
{
|
||||
/* Shouldn't happen */
|
||||
warn_opers(L_CRIT, "DNS: bad nameserver!");
|
||||
stats_error(rid, letter, "INVALIDNAMESERVER");
|
||||
exit(EX_DNS_ERROR);
|
||||
}
|
||||
|
||||
addrlen = strlen(addr) + 1;
|
||||
(void)snprintf(&buf[s], sizeof(buf) - s, "%s ", addr);
|
||||
s += addrlen;
|
||||
}
|
||||
|
||||
if(s > 0)
|
||||
buf[--s] = '\0';
|
||||
|
||||
stats_result(rid, letter, "%s", buf);
|
||||
}
|
||||
|
||||
void
|
||||
reload_nameservers(const char letter)
|
||||
{
|
||||
/* Not a whole lot to it */
|
||||
restart_resolver();
|
||||
}
|
61
authd/dns.h
Normal file
61
authd/dns.h
Normal file
|
@ -0,0 +1,61 @@
|
|||
/* authd/dns.h - header for authd DNS functions
|
||||
* Copyright (c) 2016 Ariadne Conill <ariadne@dereferenced.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice is present in all copies.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _AUTHD_DNS_H
|
||||
#define _AUTHD_DNS_H
|
||||
|
||||
#define DNS_REQ_IDLEN 10
|
||||
|
||||
#include "stdinc.h"
|
||||
#include "res.h"
|
||||
#include "reslib.h"
|
||||
|
||||
typedef enum
|
||||
{
|
||||
QUERY_INVALID = 0,
|
||||
QUERY_A = '4',
|
||||
QUERY_AAAA = '6',
|
||||
QUERY_PTR_A = 'R',
|
||||
QUERY_PTR_AAAA = 'S',
|
||||
} query_type;
|
||||
|
||||
/* Similar to that in ircd */
|
||||
typedef void (*DNSCB)(const char *res, bool status, query_type type, void *data);
|
||||
|
||||
struct dns_query
|
||||
{
|
||||
struct DNSQuery query;
|
||||
query_type type;
|
||||
struct rb_sockaddr_storage addr;
|
||||
uint64_t id;
|
||||
|
||||
DNSCB callback;
|
||||
void *data;
|
||||
};
|
||||
|
||||
extern struct dns_query *lookup_hostname(const char *ip, DNSCB callback, void *data);
|
||||
extern struct dns_query *lookup_ip(const char *host, int aftype, DNSCB callback, void *data);
|
||||
extern void cancel_query(struct dns_query *query);
|
||||
|
||||
extern void handle_resolve_dns(int parc, char *parv[]);
|
||||
extern void enumerate_nameservers(uint32_t rid, const char letter);
|
||||
extern void reload_nameservers(const char letter);
|
||||
|
||||
#endif
|
84
authd/notice.c
Normal file
84
authd/notice.c
Normal file
|
@ -0,0 +1,84 @@
|
|||
/* authd/notice.c - send notices back to the ircd and to clients
|
||||
* Copyright (c) 2016 Elizabeth Myers <elizabeth@interlinked.me>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice is present in all copies.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "authd.h"
|
||||
#include "notice.h"
|
||||
|
||||
/* Send a notice to a client */
|
||||
void
|
||||
notice_client(uint32_t cid, const char *fmt, ...)
|
||||
{
|
||||
char buf[BUFSIZE];
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
vsnprintf(buf, sizeof(buf), fmt, args);
|
||||
va_end(args);
|
||||
|
||||
rb_helper_write(authd_helper, "N %x :%s", cid, buf);
|
||||
}
|
||||
|
||||
/* Send a warning to the IRC daemon for logging, etc. */
|
||||
void
|
||||
warn_opers(notice_level_t level, const char *fmt, ...)
|
||||
{
|
||||
char buf[BUFSIZE];
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
vsnprintf(buf, sizeof(buf), fmt, args);
|
||||
va_end(args);
|
||||
|
||||
rb_helper_write(authd_helper, "W %c :%s", level, buf);
|
||||
}
|
||||
|
||||
/* Send a stats result */
|
||||
void
|
||||
stats_result(uint32_t cid, char letter, const char *fmt, ...)
|
||||
{
|
||||
char buf[BUFSIZE];
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
vsnprintf(buf, sizeof(buf), fmt, args);
|
||||
va_end(args);
|
||||
|
||||
rb_helper_write(authd_helper, "Y %x %c %s", cid, letter, buf);
|
||||
}
|
||||
|
||||
/* Send a stats error */
|
||||
void
|
||||
stats_error(uint32_t cid, char letter, const char *fmt, ...)
|
||||
{
|
||||
char buf[BUFSIZE];
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
vsnprintf(buf, sizeof(buf), fmt, args);
|
||||
va_end(args);
|
||||
|
||||
rb_helper_write(authd_helper, "X %x %c %s", cid, letter, buf);
|
||||
}
|
||||
|
||||
void
|
||||
stats_done(uint32_t cid, char letter)
|
||||
{
|
||||
rb_helper_write(authd_helper, "Z %x %c", cid, letter);
|
||||
}
|
38
authd/notice.h
Normal file
38
authd/notice.h
Normal file
|
@ -0,0 +1,38 @@
|
|||
/* authd/notice.h - send notices back to the ircd and to clients
|
||||
* Copyright (c) 2016 Elizabeth Myers <elizabeth@interlinked.me>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice is present in all copies.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __SOLANUM_AUTHD_NOTICE_H__
|
||||
#define __SOLANUM_AUTHD_NOTICE_H__
|
||||
|
||||
typedef enum
|
||||
{
|
||||
L_DEBUG = 'D',
|
||||
L_INFO = 'I',
|
||||
L_WARN = 'W',
|
||||
L_CRIT ='C',
|
||||
} notice_level_t;
|
||||
|
||||
void notice_client(uint32_t cid, const char *fmt, ...);
|
||||
void warn_opers(notice_level_t level, const char *fmt, ...);
|
||||
void stats_result(uint32_t cid, char letter, const char *fmt, ...);
|
||||
void stats_error(uint32_t cid, char letter, const char *fmt, ...);
|
||||
void stats_done(uint32_t cid, char letter);
|
||||
|
||||
#endif /* __SOLANUM_AUTHD_NOTICE_H__ */
|
433
authd/provider.c
Normal file
433
authd/provider.c
Normal file
|
@ -0,0 +1,433 @@
|
|||
/* authd/provider.c - authentication provider framework
|
||||
* Copyright (c) 2016 Elizabeth Myers <elizabeth@interlinked.me>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice is present in all copies.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* The basic design here is to have "authentication providers" that do things
|
||||
* like query ident and DNSBLs and even open proxies.
|
||||
*
|
||||
* Providers are registered in the auth_providers linked list. It is planned to
|
||||
* use a bitmap to store provider ID's later.
|
||||
*
|
||||
* Providers can either return failure immediately, immediate acceptance, or do
|
||||
* work in the background (calling set_provider to signal this).
|
||||
*
|
||||
* Provider-specific data for each client can be kept in an index of the data
|
||||
* struct member (using the provider's ID).
|
||||
*
|
||||
* All providers must implement at a minimum a perform_provider function. You
|
||||
* don't have to implement the others if you don't need them.
|
||||
*
|
||||
* Providers may kick clients off by rejecting them. Upon rejection, all
|
||||
* providers are cancelled. They can also unconditionally accept them.
|
||||
*
|
||||
* When a provider is done and is neutral on accepting/rejecting a client, it
|
||||
* should call provider_done. Do NOT call this if you have accepted or rejected
|
||||
* the client.
|
||||
*
|
||||
* Eventually, stuff like *:line handling will be moved here, but that means we
|
||||
* have to talk to bandb directly first.
|
||||
*
|
||||
* --Elizafox, 9 March 2016
|
||||
*/
|
||||
|
||||
#include "stdinc.h"
|
||||
#include "rb_dictionary.h"
|
||||
#include "rb_lib.h"
|
||||
#include "authd.h"
|
||||
#include "provider.h"
|
||||
#include "notice.h"
|
||||
|
||||
static EVH provider_timeout_event;
|
||||
|
||||
rb_dictionary *auth_clients;
|
||||
rb_dlink_list auth_providers;
|
||||
|
||||
static rb_dlink_list free_pids;
|
||||
static uint32_t allocated_pids;
|
||||
static struct ev_entry *timeout_ev;
|
||||
|
||||
/* Set a provider's raw status */
|
||||
static inline void
|
||||
set_provider_status(struct auth_client *auth, uint32_t provider, provider_status_t status)
|
||||
{
|
||||
auth->data[provider].status = status;
|
||||
}
|
||||
|
||||
/* Set the provider as running */
|
||||
static inline void
|
||||
set_provider_running(struct auth_client *auth, uint32_t provider)
|
||||
{
|
||||
auth->providers_active++;
|
||||
set_provider_status(auth, provider, PROVIDER_STATUS_RUNNING);
|
||||
}
|
||||
|
||||
/* Provider is no longer operating on this auth client */
|
||||
static inline void
|
||||
set_provider_done(struct auth_client *auth, uint32_t provider)
|
||||
{
|
||||
set_provider_status(auth, provider, PROVIDER_STATUS_DONE);
|
||||
auth->providers_active--;
|
||||
}
|
||||
|
||||
/* Initalise all providers */
|
||||
void
|
||||
init_providers(void)
|
||||
{
|
||||
auth_clients = rb_dictionary_create("pending auth clients", rb_uint32cmp);
|
||||
timeout_ev = rb_event_addish("provider_timeout_event", provider_timeout_event, NULL, 1);
|
||||
|
||||
/* FIXME must be started before rdns/ident to receive completion notification from them */
|
||||
load_provider(&dnsbl_provider);
|
||||
load_provider(&opm_provider);
|
||||
|
||||
/* FIXME must be started after dnsbl/opm in case of early completion notifications */
|
||||
load_provider(&rdns_provider);
|
||||
load_provider(&ident_provider);
|
||||
}
|
||||
|
||||
/* Terminate all providers */
|
||||
void
|
||||
destroy_providers(void)
|
||||
{
|
||||
rb_dlink_node *ptr, *nptr;
|
||||
rb_dictionary_iter iter;
|
||||
struct auth_client *auth;
|
||||
|
||||
/* Cancel outstanding connections */
|
||||
RB_DICTIONARY_FOREACH(auth, &iter, auth_clients)
|
||||
{
|
||||
auth_client_ref(auth);
|
||||
|
||||
/* TBD - is this the right thing? */
|
||||
reject_client(auth, UINT32_MAX, "destroy",
|
||||
"Authentication system is down... try reconnecting in a few seconds");
|
||||
|
||||
auth_client_unref(auth);
|
||||
}
|
||||
|
||||
RB_DLINK_FOREACH_SAFE(ptr, nptr, auth_providers.head)
|
||||
{
|
||||
struct auth_provider *provider = ptr->data;
|
||||
|
||||
if(provider->destroy)
|
||||
provider->destroy();
|
||||
|
||||
rb_dlinkDelete(ptr, &auth_providers);
|
||||
}
|
||||
|
||||
rb_dictionary_destroy(auth_clients, NULL, NULL);
|
||||
rb_event_delete(timeout_ev);
|
||||
}
|
||||
|
||||
/* Load a provider */
|
||||
void
|
||||
load_provider(struct auth_provider *provider)
|
||||
{
|
||||
/* Assign a PID */
|
||||
if(rb_dlink_list_length(&free_pids) > 0)
|
||||
{
|
||||
/* use the free list */
|
||||
provider->id = RB_POINTER_TO_UINT(free_pids.head->data);
|
||||
rb_dlinkDestroy(free_pids.head, &free_pids);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(allocated_pids == MAX_PROVIDERS || allocated_pids == UINT32_MAX)
|
||||
{
|
||||
warn_opers(L_WARN, "Cannot load additional provider, max reached!");
|
||||
return;
|
||||
}
|
||||
|
||||
provider->id = allocated_pids++;
|
||||
}
|
||||
|
||||
if(provider->opt_handlers != NULL)
|
||||
{
|
||||
struct auth_opts_handler *handler;
|
||||
|
||||
for(handler = provider->opt_handlers; handler->option != NULL; handler++)
|
||||
rb_dictionary_add(authd_option_handlers, handler->option, handler);
|
||||
}
|
||||
|
||||
if(provider->stats_handler.letter != '\0')
|
||||
authd_stat_handlers[(unsigned char)provider->stats_handler.letter] = provider->stats_handler.handler;
|
||||
|
||||
if(provider->init != NULL)
|
||||
provider->init();
|
||||
|
||||
rb_dlinkAdd(provider, &provider->node, &auth_providers);
|
||||
}
|
||||
|
||||
void
|
||||
unload_provider(struct auth_provider *provider)
|
||||
{
|
||||
if(provider->opt_handlers != NULL)
|
||||
{
|
||||
struct auth_opts_handler *handler;
|
||||
|
||||
for(handler = provider->opt_handlers; handler->option != NULL; handler++)
|
||||
rb_dictionary_delete(authd_option_handlers, handler->option);
|
||||
}
|
||||
|
||||
if(provider->stats_handler.letter != '\0')
|
||||
authd_stat_handlers[(unsigned char)provider->stats_handler.letter] = NULL;
|
||||
|
||||
if(provider->destroy != NULL)
|
||||
provider->destroy();
|
||||
|
||||
rb_dlinkDelete(&provider->node, &auth_providers);
|
||||
|
||||
/* Reclaim ID */
|
||||
rb_dlinkAddAlloc(RB_UINT_TO_POINTER(provider->id), &free_pids);
|
||||
}
|
||||
|
||||
void
|
||||
auth_client_free(struct auth_client *auth)
|
||||
{
|
||||
rb_dictionary_delete(auth_clients, RB_UINT_TO_POINTER(auth->cid));
|
||||
rb_free(auth->data);
|
||||
rb_free(auth);
|
||||
}
|
||||
|
||||
/* Cancel outstanding providers for a client (if any). */
|
||||
void
|
||||
cancel_providers(struct auth_client *auth)
|
||||
{
|
||||
if(auth->providers_cancelled)
|
||||
return;
|
||||
|
||||
auth->providers_cancelled = true;
|
||||
|
||||
if(auth->providers_active > 0)
|
||||
{
|
||||
rb_dlink_node *ptr;
|
||||
|
||||
RB_DLINK_FOREACH(ptr, auth_providers.head)
|
||||
{
|
||||
struct auth_provider *provider = ptr->data;
|
||||
|
||||
if(provider->cancel != NULL && is_provider_running(auth, provider->id))
|
||||
/* Cancel if required */
|
||||
provider->cancel(auth);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Provider is done */
|
||||
void
|
||||
provider_done(struct auth_client *auth, uint32_t id)
|
||||
{
|
||||
rb_dlink_node *ptr;
|
||||
|
||||
lrb_assert(is_provider_running(auth, id));
|
||||
lrb_assert(id != UINT32_MAX);
|
||||
lrb_assert(id < allocated_pids);
|
||||
|
||||
set_provider_done(auth, id);
|
||||
|
||||
if(auth->providers_active == 0 && !auth->providers_starting)
|
||||
{
|
||||
/* All done */
|
||||
accept_client(auth);
|
||||
return;
|
||||
}
|
||||
|
||||
RB_DLINK_FOREACH(ptr, auth_providers.head)
|
||||
{
|
||||
struct auth_provider *provider = ptr->data;
|
||||
|
||||
if(provider->completed != NULL && is_provider_running(auth, provider->id))
|
||||
/* Notify pending clients who asked for it */
|
||||
provider->completed(auth, id);
|
||||
}
|
||||
}
|
||||
|
||||
/* Reject a client and cancel any outstanding providers */
|
||||
void
|
||||
reject_client(struct auth_client *auth, uint32_t id, const char *data, const char *fmt, ...)
|
||||
{
|
||||
char buf[BUFSIZE];
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
vsnprintf(buf, sizeof(buf), fmt, args);
|
||||
va_end(args);
|
||||
|
||||
/* We send back username and hostname in case ircd wants to overrule our decision.
|
||||
* In the future this may not be the case.
|
||||
* --Elizafox
|
||||
*/
|
||||
rb_helper_write(authd_helper, "R %x %c %s %s %s :%s",
|
||||
auth->cid, id != UINT32_MAX ? auth->data[id].provider->letter : '*',
|
||||
auth->username, auth->hostname,
|
||||
data == NULL ? "*" : data, buf);
|
||||
|
||||
if(id != UINT32_MAX)
|
||||
set_provider_done(auth, id);
|
||||
|
||||
cancel_providers(auth);
|
||||
}
|
||||
|
||||
/* Accept a client and cancel outstanding providers if any */
|
||||
void
|
||||
accept_client(struct auth_client *auth)
|
||||
{
|
||||
rb_helper_write(authd_helper, "A %x %s %s", auth->cid, auth->username, auth->hostname);
|
||||
cancel_providers(auth);
|
||||
}
|
||||
|
||||
/* Begin authenticating user */
|
||||
static void
|
||||
start_auth(const char *cid, const char *l_ip, const char *l_port, const char *c_ip, const char *c_port, const char *protocol)
|
||||
{
|
||||
struct auth_client *auth;
|
||||
unsigned long long lcid = strtoull(cid, NULL, 16);
|
||||
rb_dlink_node *ptr;
|
||||
|
||||
if(lcid == 0 || lcid > UINT32_MAX)
|
||||
return;
|
||||
|
||||
auth = rb_malloc(sizeof(struct auth_client));
|
||||
auth_client_ref(auth);
|
||||
auth->cid = (uint32_t)lcid;
|
||||
|
||||
if(rb_dictionary_find(auth_clients, RB_UINT_TO_POINTER(auth->cid)) == NULL)
|
||||
rb_dictionary_add(auth_clients, RB_UINT_TO_POINTER(auth->cid), auth);
|
||||
else
|
||||
{
|
||||
warn_opers(L_CRIT, "provider: duplicate client added via start_auth: %s", cid);
|
||||
exit(EX_PROVIDER_ERROR);
|
||||
}
|
||||
|
||||
auth->protocol = strtoull(protocol, NULL, 16);
|
||||
|
||||
rb_strlcpy(auth->l_ip, l_ip, sizeof(auth->l_ip));
|
||||
auth->l_port = (uint16_t)atoi(l_port); /* should be safe */
|
||||
(void) rb_inet_pton_sock(l_ip, &auth->l_addr);
|
||||
SET_SS_PORT(&auth->l_addr, htons(auth->l_port));
|
||||
|
||||
rb_strlcpy(auth->c_ip, c_ip, sizeof(auth->c_ip));
|
||||
auth->c_port = (uint16_t)atoi(c_port);
|
||||
(void) rb_inet_pton_sock(c_ip, &auth->c_addr);
|
||||
SET_SS_PORT(&auth->c_addr, htons(auth->c_port));
|
||||
|
||||
rb_strlcpy(auth->hostname, "*", sizeof(auth->hostname));
|
||||
rb_strlcpy(auth->username, "*", sizeof(auth->username));
|
||||
|
||||
auth->data = rb_malloc(allocated_pids * sizeof(struct auth_client_data));
|
||||
|
||||
auth->providers_starting = true;
|
||||
RB_DLINK_FOREACH(ptr, auth_providers.head)
|
||||
{
|
||||
struct auth_provider *provider = ptr->data;
|
||||
|
||||
auth->data[provider->id].provider = provider;
|
||||
|
||||
lrb_assert(provider->start != NULL);
|
||||
|
||||
/* Execute providers */
|
||||
set_provider_running(auth, provider->id);
|
||||
if(!provider->start(auth))
|
||||
/* Rejected immediately */
|
||||
goto done;
|
||||
|
||||
if(auth->providers_cancelled)
|
||||
break;
|
||||
}
|
||||
auth->providers_starting = false;
|
||||
|
||||
/* If no providers are running, accept the client */
|
||||
if(auth->providers_active == 0)
|
||||
accept_client(auth);
|
||||
|
||||
done:
|
||||
auth_client_unref(auth);
|
||||
}
|
||||
|
||||
/* Callback for the initiation */
|
||||
void
|
||||
handle_new_connection(int parc, char *parv[])
|
||||
{
|
||||
if (parc < 6) {
|
||||
warn_opers(L_CRIT, "provider: received too few params for new connection (6 expected, got %d)", parc);
|
||||
exit(EX_PROVIDER_ERROR);
|
||||
}
|
||||
|
||||
start_auth(parv[1], parv[2], parv[3], parv[4], parv[5], parc > 6 ? parv[6] : "0");
|
||||
}
|
||||
|
||||
void
|
||||
handle_cancel_connection(int parc, char *parv[])
|
||||
{
|
||||
struct auth_client *auth;
|
||||
unsigned long long lcid;
|
||||
|
||||
if(parc < 2)
|
||||
{
|
||||
warn_opers(L_CRIT, "provider: received too few params for new connection (2 expected, got %d)", parc);
|
||||
exit(EX_PROVIDER_ERROR);
|
||||
}
|
||||
|
||||
lcid = strtoull(parv[1], NULL, 16);
|
||||
if(lcid == 0 || lcid > UINT32_MAX)
|
||||
{
|
||||
warn_opers(L_CRIT, "provider: got a request to cancel a connection that can't exist: %s", parv[1]);
|
||||
exit(EX_PROVIDER_ERROR);
|
||||
}
|
||||
|
||||
if((auth = rb_dictionary_retrieve(auth_clients, RB_UINT_TO_POINTER((uint32_t)lcid))) == NULL)
|
||||
{
|
||||
/* This could happen as a race if we've accepted/rejected but they cancel, so don't die here.
|
||||
* --Elizafox */
|
||||
return;
|
||||
}
|
||||
|
||||
auth_client_ref(auth);
|
||||
cancel_providers(auth);
|
||||
auth_client_unref(auth);
|
||||
}
|
||||
|
||||
static void
|
||||
provider_timeout_event(void *notused __unused)
|
||||
{
|
||||
struct auth_client *auth;
|
||||
rb_dictionary_iter iter;
|
||||
const time_t curtime = rb_current_time();
|
||||
|
||||
RB_DICTIONARY_FOREACH(auth, &iter, auth_clients)
|
||||
{
|
||||
rb_dlink_node *ptr;
|
||||
|
||||
auth_client_ref(auth);
|
||||
|
||||
RB_DLINK_FOREACH(ptr, auth_providers.head)
|
||||
{
|
||||
struct auth_provider *provider = ptr->data;
|
||||
const time_t timeout = get_provider_timeout(auth, provider->id);
|
||||
|
||||
if(is_provider_running(auth, provider->id) && provider->timeout != NULL &&
|
||||
timeout > 0 && timeout < curtime)
|
||||
{
|
||||
provider->timeout(auth);
|
||||
}
|
||||
}
|
||||
|
||||
auth_client_unref(auth);
|
||||
}
|
||||
}
|
246
authd/provider.h
Normal file
246
authd/provider.h
Normal file
|
@ -0,0 +1,246 @@
|
|||
/* authd/provider.h - authentication provider framework
|
||||
* Copyright (c) 2016 Elizabeth Myers <elizabeth@interlinked.me>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice is present in all copies.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __SOLANUM_AUTHD_PROVIDER_H__
|
||||
#define __SOLANUM_AUTHD_PROVIDER_H__
|
||||
|
||||
#include "stdinc.h"
|
||||
#include "authd.h"
|
||||
#include "rb_dictionary.h"
|
||||
|
||||
#define MAX_PROVIDERS 32 /* This should be enough */
|
||||
|
||||
typedef enum
|
||||
{
|
||||
PROVIDER_STATUS_NOTRUN = 0,
|
||||
PROVIDER_STATUS_RUNNING,
|
||||
PROVIDER_STATUS_DONE,
|
||||
} provider_status_t;
|
||||
|
||||
struct auth_client_data
|
||||
{
|
||||
struct auth_provider *provider; /* Pointer back */
|
||||
time_t timeout; /* Provider timeout */
|
||||
void *data; /* Provider data */
|
||||
provider_status_t status; /* Provider status */
|
||||
};
|
||||
|
||||
struct auth_client
|
||||
{
|
||||
uint32_t cid; /* Client ID */
|
||||
|
||||
int protocol; /* IP protocol (TCP/SCTP) */
|
||||
|
||||
char l_ip[HOSTIPLEN + 1]; /* Listener IP address */
|
||||
uint16_t l_port; /* Listener port */
|
||||
struct rb_sockaddr_storage l_addr; /* Listener address/port */
|
||||
|
||||
char c_ip[HOSTIPLEN + 1]; /* Client IP address */
|
||||
uint16_t c_port; /* Client port */
|
||||
struct rb_sockaddr_storage c_addr; /* Client address/port */
|
||||
|
||||
char hostname[HOSTLEN + 1]; /* Used for DNS lookup */
|
||||
char username[USERLEN + 1]; /* Used for ident lookup */
|
||||
|
||||
bool providers_starting; /* Providers are still warming up */
|
||||
bool providers_cancelled; /* Providers are being cancelled */
|
||||
unsigned int providers_active; /* Number of active providers */
|
||||
unsigned int refcount; /* Held references */
|
||||
|
||||
struct auth_client_data *data; /* Provider-specific data */
|
||||
};
|
||||
|
||||
typedef bool (*provider_init_t)(void);
|
||||
typedef void (*provider_destroy_t)(void);
|
||||
|
||||
typedef bool (*provider_start_t)(struct auth_client *);
|
||||
typedef void (*provider_cancel_t)(struct auth_client *);
|
||||
typedef void (*uint32_timeout_t)(struct auth_client *);
|
||||
typedef void (*provider_complete_t)(struct auth_client *, uint32_t);
|
||||
|
||||
struct auth_stats_handler
|
||||
{
|
||||
const char letter;
|
||||
authd_stat_handler handler;
|
||||
};
|
||||
|
||||
struct auth_provider
|
||||
{
|
||||
rb_dlink_node node;
|
||||
|
||||
uint32_t id; /* Provider ID */
|
||||
|
||||
const char *name; /* Name of the provider */
|
||||
char letter; /* Letter used on reject, etc. */
|
||||
|
||||
provider_init_t init; /* Initalise the provider */
|
||||
provider_destroy_t destroy; /* Terminate the provider */
|
||||
|
||||
provider_start_t start; /* Perform authentication */
|
||||
provider_cancel_t cancel; /* Authentication cancelled */
|
||||
uint32_timeout_t timeout; /* Timeout callback */
|
||||
provider_complete_t completed; /* Callback for when other performers complete (think dependency chains) */
|
||||
|
||||
struct auth_stats_handler stats_handler;
|
||||
|
||||
struct auth_opts_handler *opt_handlers;
|
||||
};
|
||||
|
||||
extern struct auth_provider rdns_provider;
|
||||
extern struct auth_provider ident_provider;
|
||||
extern struct auth_provider dnsbl_provider;
|
||||
extern struct auth_provider opm_provider;
|
||||
|
||||
extern rb_dlink_list auth_providers;
|
||||
extern rb_dictionary *auth_clients;
|
||||
|
||||
void load_provider(struct auth_provider *provider);
|
||||
void unload_provider(struct auth_provider *provider);
|
||||
|
||||
void init_providers(void);
|
||||
void destroy_providers(void);
|
||||
void cancel_providers(struct auth_client *auth);
|
||||
|
||||
void provider_done(struct auth_client *auth, uint32_t id);
|
||||
void accept_client(struct auth_client *auth);
|
||||
void reject_client(struct auth_client *auth, uint32_t id, const char *data, const char *fmt, ...);
|
||||
|
||||
void handle_new_connection(int parc, char *parv[]);
|
||||
void handle_cancel_connection(int parc, char *parv[]);
|
||||
void auth_client_free(struct auth_client *auth);
|
||||
|
||||
static inline void
|
||||
auth_client_ref(struct auth_client *auth)
|
||||
{
|
||||
auth->refcount++;
|
||||
}
|
||||
|
||||
static inline void
|
||||
auth_client_unref(struct auth_client *auth)
|
||||
{
|
||||
auth->refcount--;
|
||||
if (auth->refcount == 0)
|
||||
auth_client_free(auth);
|
||||
}
|
||||
|
||||
/* Get a provider by name */
|
||||
static inline struct auth_provider *
|
||||
find_provider(const char *name)
|
||||
{
|
||||
rb_dlink_node *ptr;
|
||||
|
||||
RB_DLINK_FOREACH(ptr, auth_providers.head)
|
||||
{
|
||||
struct auth_provider *provider = ptr->data;
|
||||
|
||||
if(strcasecmp(provider->name, name) == 0)
|
||||
return provider;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Get a provider's id by name */
|
||||
static inline bool
|
||||
get_provider_id(const char *name, uint32_t *id)
|
||||
{
|
||||
struct auth_provider *provider = find_provider(name);
|
||||
|
||||
if(provider != NULL)
|
||||
{
|
||||
*id = provider->id;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Get a provider's raw status */
|
||||
static inline provider_status_t
|
||||
get_provider_status(struct auth_client *auth, uint32_t provider)
|
||||
{
|
||||
return auth->data[provider].status;
|
||||
}
|
||||
|
||||
/* Check if provider is operating on this auth client */
|
||||
static inline bool
|
||||
is_provider_running(struct auth_client *auth, uint32_t provider)
|
||||
{
|
||||
return get_provider_status(auth, provider) == PROVIDER_STATUS_RUNNING;
|
||||
}
|
||||
|
||||
/* Check if provider has finished on this client */
|
||||
static inline bool
|
||||
is_provider_done(struct auth_client *auth, uint32_t provider)
|
||||
{
|
||||
return get_provider_status(auth, provider) == PROVIDER_STATUS_DONE;
|
||||
}
|
||||
|
||||
/* Check if provider doesn't exist or has finished on this client */
|
||||
static inline bool
|
||||
run_after_provider(struct auth_client *auth, const char *name)
|
||||
{
|
||||
uint32_t id;
|
||||
|
||||
if (get_provider_id(name, &id)) {
|
||||
return get_provider_status(auth, id) == PROVIDER_STATUS_DONE;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get provider auth client data */
|
||||
static inline void *
|
||||
get_provider_data(struct auth_client *auth, uint32_t id)
|
||||
{
|
||||
return auth->data[id].data;
|
||||
}
|
||||
|
||||
/* Set provider auth client data */
|
||||
static inline void
|
||||
set_provider_data(struct auth_client *auth, uint32_t id, void *data)
|
||||
{
|
||||
auth->data[id].data = data;
|
||||
}
|
||||
|
||||
/* Set timeout relative to current time on provider
|
||||
* When the timeout lapses, the provider's timeout call will execute */
|
||||
static inline void
|
||||
set_provider_timeout_relative(struct auth_client *auth, uint32_t id, time_t timeout)
|
||||
{
|
||||
auth->data[id].timeout = timeout + rb_current_time();
|
||||
}
|
||||
|
||||
/* Set timeout value in absolute time (Unix timestamp)
|
||||
* When the timeout lapses, the provider's timeout call will execute */
|
||||
static inline void
|
||||
set_provider_timeout_absolute(struct auth_client *auth, uint32_t id, time_t timeout)
|
||||
{
|
||||
auth->data[id].timeout = timeout;
|
||||
}
|
||||
|
||||
/* Get the timeout value for the provider */
|
||||
static inline time_t
|
||||
get_provider_timeout(struct auth_client *auth, uint32_t id)
|
||||
{
|
||||
return auth->data[id].timeout;
|
||||
}
|
||||
|
||||
#endif /* __SOLANUM_AUTHD_PROVIDER_H__ */
|
608
authd/providers/dnsbl.c
Normal file
608
authd/providers/dnsbl.c
Normal file
|
@ -0,0 +1,608 @@
|
|||
/*
|
||||
* Solanum: a slightly advanced ircd
|
||||
* dnsbl.c: Manages DNSBL entries and lookups
|
||||
*
|
||||
* Copyright (C) 2006-2011 charybdis development team
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* Originally written for charybdis circa 2006 (by nenolod?).
|
||||
* Tweaked for authd. Some functions and structs renamed. Public/private
|
||||
* interfaces have been shifted around. Some code has been cleaned up too.
|
||||
* -- Elizafox 24 March 2016
|
||||
*/
|
||||
|
||||
#include "authd.h"
|
||||
#include "defaults.h"
|
||||
#include "provider.h"
|
||||
#include "notice.h"
|
||||
#include "stdinc.h"
|
||||
#include "dns.h"
|
||||
|
||||
#define SELF_PID (dnsbl_provider.id)
|
||||
|
||||
typedef enum filter_t
|
||||
{
|
||||
FILTER_ALL = 1,
|
||||
FILTER_LAST = 2,
|
||||
} filter_t;
|
||||
|
||||
/* dnsbl accepted IP types */
|
||||
#define IPTYPE_IPV4 1
|
||||
#define IPTYPE_IPV6 2
|
||||
|
||||
/* A configured DNSBL */
|
||||
struct dnsbl
|
||||
{
|
||||
char host[IRCD_RES_HOSTLEN + 1];
|
||||
char reason[BUFSIZE]; /* Reason template (ircd fills in the blanks) */
|
||||
uint8_t iptype; /* IP types supported */
|
||||
rb_dlink_list filters; /* Filters for queries */
|
||||
|
||||
bool delete; /* If true delete when no clients */
|
||||
int refcount; /* When 0 and delete is set, remove this dnsbl */
|
||||
unsigned int hits;
|
||||
|
||||
time_t lastwarning; /* Last warning about garbage replies sent */
|
||||
};
|
||||
|
||||
/* A lookup in progress for a particular DNSBL for a particular client */
|
||||
struct dnsbl_lookup
|
||||
{
|
||||
struct dnsbl *bl; /* dnsbl we're checking */
|
||||
struct auth_client *auth; /* Client */
|
||||
struct dns_query *query; /* DNS query pointer */
|
||||
|
||||
rb_dlink_node node;
|
||||
};
|
||||
|
||||
/* A dnsbl filter */
|
||||
struct dnsbl_filter
|
||||
{
|
||||
filter_t type; /* Type of filter */
|
||||
char filter[HOSTIPLEN]; /* The filter itself */
|
||||
|
||||
rb_dlink_node node;
|
||||
};
|
||||
|
||||
/* dnsbl user data attached to auth_client instance */
|
||||
struct dnsbl_user
|
||||
{
|
||||
bool started;
|
||||
rb_dlink_list queries; /* dnsbl queries in flight */
|
||||
};
|
||||
|
||||
/* public interfaces */
|
||||
static void dnsbls_destroy(void);
|
||||
|
||||
static bool dnsbls_start(struct auth_client *);
|
||||
static inline void dnsbls_generic_cancel(struct auth_client *, const char *);
|
||||
static void dnsbls_timeout(struct auth_client *);
|
||||
static void dnsbls_cancel(struct auth_client *);
|
||||
static void dnsbls_cancel_none(struct auth_client *);
|
||||
|
||||
/* private interfaces */
|
||||
static void unref_dnsbl(struct dnsbl *);
|
||||
static struct dnsbl *new_dnsbl(const char *, const char *, uint8_t, rb_dlink_list *);
|
||||
static struct dnsbl *find_dnsbl(const char *);
|
||||
static bool dnsbl_check_reply(struct dnsbl_lookup *, const char *);
|
||||
static void dnsbl_dns_callback(const char *, bool, query_type, void *);
|
||||
static void initiate_dnsbl_dnsquery(struct dnsbl *, struct auth_client *);
|
||||
|
||||
/* Variables */
|
||||
static rb_dlink_list dnsbl_list = { NULL, NULL, 0 };
|
||||
static int dnsbl_timeout = DNSBL_TIMEOUT_DEFAULT;
|
||||
|
||||
/* private interfaces */
|
||||
|
||||
static void
|
||||
unref_dnsbl(struct dnsbl *bl)
|
||||
{
|
||||
rb_dlink_node *ptr, *nptr;
|
||||
|
||||
bl->refcount--;
|
||||
if (bl->delete && bl->refcount <= 0)
|
||||
{
|
||||
RB_DLINK_FOREACH_SAFE(ptr, nptr, bl->filters.head)
|
||||
{
|
||||
rb_dlinkDelete(ptr, &bl->filters);
|
||||
rb_free(ptr);
|
||||
}
|
||||
|
||||
rb_dlinkFindDestroy(bl, &dnsbl_list);
|
||||
rb_free(bl);
|
||||
}
|
||||
}
|
||||
|
||||
static struct dnsbl *
|
||||
new_dnsbl(const char *name, const char *reason, uint8_t iptype, rb_dlink_list *filters)
|
||||
{
|
||||
struct dnsbl *bl;
|
||||
|
||||
if (name == NULL || reason == NULL || iptype == 0)
|
||||
return NULL;
|
||||
|
||||
if((bl = find_dnsbl(name)) == NULL)
|
||||
{
|
||||
bl = rb_malloc(sizeof(struct dnsbl));
|
||||
rb_dlinkAddAlloc(bl, &dnsbl_list);
|
||||
}
|
||||
else
|
||||
bl->delete = false;
|
||||
|
||||
rb_strlcpy(bl->host, name, IRCD_RES_HOSTLEN + 1);
|
||||
rb_strlcpy(bl->reason, reason, BUFSIZE);
|
||||
bl->iptype = iptype;
|
||||
|
||||
rb_dlinkMoveList(filters, &bl->filters);
|
||||
|
||||
bl->lastwarning = 0;
|
||||
|
||||
return bl;
|
||||
}
|
||||
|
||||
static struct dnsbl *
|
||||
find_dnsbl(const char *name)
|
||||
{
|
||||
rb_dlink_node *ptr;
|
||||
|
||||
RB_DLINK_FOREACH(ptr, dnsbl_list.head)
|
||||
{
|
||||
struct dnsbl *bl = (struct dnsbl *)ptr->data;
|
||||
|
||||
if (!strcasecmp(bl->host, name))
|
||||
return bl;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
dnsbl_check_reply(struct dnsbl_lookup *bllookup, const char *ipaddr)
|
||||
{
|
||||
struct dnsbl *bl = bllookup->bl;
|
||||
const char *lastoctet;
|
||||
rb_dlink_node *ptr;
|
||||
|
||||
/* No filters and entry found - thus positive match */
|
||||
if (!rb_dlink_list_length(&bl->filters))
|
||||
return true;
|
||||
|
||||
/* Below will prolly have to change if IPv6 address replies are sent back */
|
||||
if ((lastoctet = strrchr(ipaddr, '.')) == NULL || *(++lastoctet) == '\0')
|
||||
goto blwarn;
|
||||
|
||||
RB_DLINK_FOREACH(ptr, bl->filters.head)
|
||||
{
|
||||
struct dnsbl_filter *filter = ptr->data;
|
||||
const char *cmpstr;
|
||||
|
||||
if (filter->type == FILTER_ALL)
|
||||
cmpstr = ipaddr;
|
||||
else if (filter->type == FILTER_LAST)
|
||||
cmpstr = lastoctet;
|
||||
else
|
||||
{
|
||||
warn_opers(L_CRIT, "dnsbl: Unknown dnsbl filter type (host %s): %d",
|
||||
bl->host, filter->type);
|
||||
exit(EX_PROVIDER_ERROR);
|
||||
}
|
||||
|
||||
if (strcmp(cmpstr, filter->filter) == 0)
|
||||
/* Match! */
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
blwarn:
|
||||
if (bl->lastwarning + 3600 < rb_current_time())
|
||||
{
|
||||
warn_opers(L_WARN, "Garbage/undecipherable reply received from dnsbl %s (reply %s)",
|
||||
bl->host, ipaddr);
|
||||
bl->lastwarning = rb_current_time();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void
|
||||
dnsbl_dns_callback(const char *result, bool status, query_type type, void *data)
|
||||
{
|
||||
struct dnsbl_lookup *bllookup = (struct dnsbl_lookup *)data;
|
||||
struct dnsbl_user *bluser;
|
||||
struct dnsbl *bl;
|
||||
struct auth_client *auth;
|
||||
|
||||
lrb_assert(bllookup != NULL);
|
||||
lrb_assert(bllookup->auth != NULL);
|
||||
|
||||
bl = bllookup->bl;
|
||||
auth = bllookup->auth;
|
||||
|
||||
if((bluser = get_provider_data(auth, SELF_PID)) == NULL)
|
||||
return;
|
||||
|
||||
if (result != NULL && status && dnsbl_check_reply(bllookup, result))
|
||||
{
|
||||
/* Match found, so proceed no further */
|
||||
bl->hits++;
|
||||
reject_client(auth, SELF_PID, bl->host, bl->reason);
|
||||
dnsbls_cancel(auth);
|
||||
return;
|
||||
}
|
||||
|
||||
unref_dnsbl(bl);
|
||||
cancel_query(bllookup->query); /* Ignore future responses */
|
||||
rb_dlinkDelete(&bllookup->node, &bluser->queries);
|
||||
rb_free(bllookup);
|
||||
|
||||
if(!rb_dlink_list_length(&bluser->queries))
|
||||
{
|
||||
/* Done here */
|
||||
notice_client(auth->cid, "*** No DNSBL entry found for this IP");
|
||||
rb_free(bluser);
|
||||
set_provider_data(auth, SELF_PID, NULL);
|
||||
set_provider_timeout_absolute(auth, SELF_PID, 0);
|
||||
provider_done(auth, SELF_PID);
|
||||
|
||||
auth_client_unref(auth);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
initiate_dnsbl_dnsquery(struct dnsbl *bl, struct auth_client *auth)
|
||||
{
|
||||
struct dnsbl_lookup *bllookup = rb_malloc(sizeof(struct dnsbl_lookup));
|
||||
struct dnsbl_user *bluser = get_provider_data(auth, SELF_PID);
|
||||
char buf[IRCD_RES_HOSTLEN + 1];
|
||||
int aftype;
|
||||
|
||||
bllookup->bl = bl;
|
||||
bllookup->auth = auth;
|
||||
|
||||
aftype = GET_SS_FAMILY(&auth->c_addr);
|
||||
if((aftype == AF_INET && (bl->iptype & IPTYPE_IPV4) == 0) ||
|
||||
(aftype == AF_INET6 && (bl->iptype & IPTYPE_IPV6) == 0))
|
||||
/* Incorrect dnsbl type for this IP... */
|
||||
{
|
||||
rb_free(bllookup);
|
||||
return;
|
||||
}
|
||||
|
||||
build_rdns(buf, sizeof(buf), &auth->c_addr, bl->host);
|
||||
bllookup->query = lookup_ip(buf, AF_INET, dnsbl_dns_callback, bllookup);
|
||||
|
||||
rb_dlinkAdd(bllookup, &bllookup->node, &bluser->queries);
|
||||
bl->refcount++;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
lookup_all_dnsbls(struct auth_client *auth)
|
||||
{
|
||||
struct dnsbl_user *bluser = get_provider_data(auth, SELF_PID);
|
||||
rb_dlink_node *ptr;
|
||||
int iptype;
|
||||
|
||||
if(GET_SS_FAMILY(&auth->c_addr) == AF_INET)
|
||||
iptype = IPTYPE_IPV4;
|
||||
else if(GET_SS_FAMILY(&auth->c_addr) == AF_INET6)
|
||||
iptype = IPTYPE_IPV6;
|
||||
else
|
||||
return false;
|
||||
|
||||
bluser->started = true;
|
||||
notice_client(auth->cid, "*** Checking your IP against DNSBLs");
|
||||
|
||||
RB_DLINK_FOREACH(ptr, dnsbl_list.head)
|
||||
{
|
||||
struct dnsbl *bl = (struct dnsbl *)ptr->data;
|
||||
|
||||
if (!bl->delete && (bl->iptype & iptype))
|
||||
initiate_dnsbl_dnsquery(bl, auth);
|
||||
}
|
||||
|
||||
if(!rb_dlink_list_length(&bluser->queries))
|
||||
/* None checked. */
|
||||
return false;
|
||||
|
||||
set_provider_timeout_relative(auth, SELF_PID, dnsbl_timeout);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline void
|
||||
delete_dnsbl(struct dnsbl *bl)
|
||||
{
|
||||
if (bl->refcount > 0)
|
||||
bl->delete = true;
|
||||
else
|
||||
{
|
||||
rb_dlinkFindDestroy(bl, &dnsbl_list);
|
||||
rb_free(bl);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
delete_all_dnsbls(void)
|
||||
{
|
||||
rb_dlink_node *ptr, *nptr;
|
||||
|
||||
RB_DLINK_FOREACH_SAFE(ptr, nptr, dnsbl_list.head)
|
||||
{
|
||||
delete_dnsbl(ptr->data);
|
||||
}
|
||||
}
|
||||
|
||||
/* public interfaces */
|
||||
static bool
|
||||
dnsbls_start(struct auth_client *auth)
|
||||
{
|
||||
lrb_assert(get_provider_data(auth, SELF_PID) == NULL);
|
||||
|
||||
if (!rb_dlink_list_length(&dnsbl_list)) {
|
||||
/* Nothing to do... */
|
||||
provider_done(auth, SELF_PID);
|
||||
return true;
|
||||
}
|
||||
|
||||
auth_client_ref(auth);
|
||||
|
||||
set_provider_data(auth, SELF_PID, rb_malloc(sizeof(struct dnsbl_user)));
|
||||
|
||||
if (run_after_provider(auth, "rdns") && run_after_provider(auth, "ident")) {
|
||||
/* Start the lookup if ident and rdns are finished, or not loaded. */
|
||||
if (!lookup_all_dnsbls(auth)) {
|
||||
dnsbls_cancel_none(auth);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* This is called every time a provider is completed as long as we are marked not done */
|
||||
static void
|
||||
dnsbls_initiate(struct auth_client *auth, uint32_t provider)
|
||||
{
|
||||
struct dnsbl_user *bluser = get_provider_data(auth, SELF_PID);
|
||||
|
||||
lrb_assert(provider != SELF_PID);
|
||||
lrb_assert(!is_provider_done(auth, SELF_PID));
|
||||
lrb_assert(rb_dlink_list_length(&dnsbl_list) > 0);
|
||||
|
||||
if (bluser == NULL || bluser->started) {
|
||||
/* Nothing to do */
|
||||
return;
|
||||
} else if (run_after_provider(auth, "rdns") && run_after_provider(auth, "ident")) {
|
||||
/* Start the lookup if ident and rdns are finished, or not loaded. */
|
||||
if (!lookup_all_dnsbls(auth)) {
|
||||
dnsbls_cancel_none(auth);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
dnsbls_generic_cancel(struct auth_client *auth, const char *message)
|
||||
{
|
||||
rb_dlink_node *ptr, *nptr;
|
||||
struct dnsbl_user *bluser = get_provider_data(auth, SELF_PID);
|
||||
|
||||
if(bluser == NULL)
|
||||
return;
|
||||
|
||||
if(rb_dlink_list_length(&bluser->queries))
|
||||
{
|
||||
notice_client(auth->cid, message);
|
||||
|
||||
RB_DLINK_FOREACH_SAFE(ptr, nptr, bluser->queries.head)
|
||||
{
|
||||
struct dnsbl_lookup *bllookup = ptr->data;
|
||||
|
||||
cancel_query(bllookup->query);
|
||||
unref_dnsbl(bllookup->bl);
|
||||
|
||||
rb_dlinkDelete(&bllookup->node, &bluser->queries);
|
||||
rb_free(bllookup);
|
||||
}
|
||||
}
|
||||
|
||||
rb_free(bluser);
|
||||
set_provider_data(auth, SELF_PID, NULL);
|
||||
set_provider_timeout_absolute(auth, SELF_PID, 0);
|
||||
provider_done(auth, SELF_PID);
|
||||
|
||||
auth_client_unref(auth);
|
||||
}
|
||||
|
||||
static void
|
||||
dnsbls_timeout(struct auth_client *auth)
|
||||
{
|
||||
dnsbls_generic_cancel(auth, "*** No response from DNSBLs");
|
||||
}
|
||||
|
||||
static void
|
||||
dnsbls_cancel(struct auth_client *auth)
|
||||
{
|
||||
dnsbls_generic_cancel(auth, "*** Aborting DNSBL checks");
|
||||
}
|
||||
|
||||
static void
|
||||
dnsbls_cancel_none(struct auth_client *auth)
|
||||
{
|
||||
dnsbls_generic_cancel(auth, "*** Could not check DNSBLs");
|
||||
}
|
||||
|
||||
static void
|
||||
dnsbls_destroy(void)
|
||||
{
|
||||
rb_dictionary_iter iter;
|
||||
struct auth_client *auth;
|
||||
|
||||
RB_DICTIONARY_FOREACH(auth, &iter, auth_clients)
|
||||
{
|
||||
dnsbls_cancel(auth);
|
||||
/* auth is now invalid as we have no reference */
|
||||
}
|
||||
|
||||
delete_all_dnsbls();
|
||||
}
|
||||
|
||||
static void
|
||||
add_conf_dnsbl(const char *key, int parc, const char **parv)
|
||||
{
|
||||
rb_dlink_list filters = { NULL, NULL, 0 };
|
||||
char *tmp, *elemlist = rb_strdup(parv[2]);
|
||||
uint8_t iptype;
|
||||
|
||||
if(*elemlist == '*')
|
||||
goto end;
|
||||
|
||||
for(char *elem = rb_strtok_r(elemlist, ",", &tmp); elem; elem = rb_strtok_r(NULL, ",", &tmp))
|
||||
{
|
||||
struct dnsbl_filter *filter = rb_malloc(sizeof(struct dnsbl_filter));
|
||||
int dot_c = 0;
|
||||
filter_t type = FILTER_LAST;
|
||||
|
||||
/* Check dnsbl filter type and for validity */
|
||||
for(char *c = elem; *c != '\0'; c++)
|
||||
{
|
||||
if(*c == '.')
|
||||
{
|
||||
if(++dot_c > 3)
|
||||
{
|
||||
warn_opers(L_CRIT, "dnsbl: addr_conf_dnsbl got a bad filter (too many octets)");
|
||||
exit(EX_PROVIDER_ERROR);
|
||||
}
|
||||
|
||||
type = FILTER_ALL;
|
||||
}
|
||||
else if(!isdigit(*c))
|
||||
{
|
||||
warn_opers(L_CRIT, "dnsbl: addr_conf_dnsbl got a bad filter (invalid character in dnsbl filter: %c)",
|
||||
*c);
|
||||
exit(EX_PROVIDER_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
if(dot_c > 0 && dot_c < 3)
|
||||
{
|
||||
warn_opers(L_CRIT, "dnsbl: addr_conf_dnsbl got a bad filter (insufficient octets)");
|
||||
exit(EX_PROVIDER_ERROR);
|
||||
}
|
||||
|
||||
filter->type = type;
|
||||
rb_strlcpy(filter->filter, elem, sizeof(filter->filter));
|
||||
rb_dlinkAdd(filter, &filter->node, &filters);
|
||||
}
|
||||
|
||||
end:
|
||||
rb_free(elemlist);
|
||||
|
||||
iptype = atoi(parv[1]) & 0x3;
|
||||
if(new_dnsbl(parv[0], parv[3], iptype, &filters) == NULL)
|
||||
{
|
||||
warn_opers(L_CRIT, "dnsbl: addr_conf_dnsbl got a malformed dnsbl");
|
||||
exit(EX_PROVIDER_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
del_conf_dnsbl(const char *key, int parc, const char **parv)
|
||||
{
|
||||
struct dnsbl *bl = find_dnsbl(parv[0]);
|
||||
if(bl == NULL)
|
||||
{
|
||||
/* Not fatal for now... */
|
||||
warn_opers(L_WARN, "dnsbl: tried to remove nonexistent dnsbl %s", parv[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
delete_dnsbl(bl);
|
||||
}
|
||||
|
||||
static void
|
||||
del_conf_dnsbl_all(const char *key, int parc, const char **parv)
|
||||
{
|
||||
delete_all_dnsbls();
|
||||
}
|
||||
|
||||
static void
|
||||
add_conf_dnsbl_timeout(const char *key, int parc, const char **parv)
|
||||
{
|
||||
int timeout = atoi(parv[0]);
|
||||
|
||||
if(timeout < 0)
|
||||
{
|
||||
warn_opers(L_CRIT, "dnsbl: dnsbl timeout < 0 (value: %d)", timeout);
|
||||
exit(EX_PROVIDER_ERROR);
|
||||
}
|
||||
|
||||
dnsbl_timeout = timeout;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void
|
||||
dnsbl_stats(uint32_t rid, char letter)
|
||||
{
|
||||
rb_dlink_node *ptr;
|
||||
|
||||
RB_DLINK_FOREACH(ptr, dnsbl_list.head)
|
||||
{
|
||||
struct dnsbl *bl = ptr->data;
|
||||
|
||||
if(bl->delete)
|
||||
continue;
|
||||
|
||||
stats_result(rid, letter, "%s %hhu %u", bl->host, bl->iptype, bl->hits);
|
||||
}
|
||||
|
||||
stats_done(rid, letter);
|
||||
}
|
||||
#endif
|
||||
|
||||
struct auth_opts_handler dnsbl_options[] =
|
||||
{
|
||||
{ "rbl", 4, add_conf_dnsbl },
|
||||
{ "rbl_del", 1, del_conf_dnsbl },
|
||||
{ "rbl_del_all", 0, del_conf_dnsbl_all },
|
||||
{ "rbl_timeout", 1, add_conf_dnsbl_timeout },
|
||||
{ NULL, 0, NULL },
|
||||
};
|
||||
|
||||
struct auth_provider dnsbl_provider =
|
||||
{
|
||||
.name = "dnsbl",
|
||||
.letter = 'B',
|
||||
.destroy = dnsbls_destroy,
|
||||
.start = dnsbls_start,
|
||||
.cancel = dnsbls_cancel,
|
||||
.timeout = dnsbls_timeout,
|
||||
.completed = dnsbls_initiate,
|
||||
.opt_handlers = dnsbl_options,
|
||||
/* .stats_handler = { 'B', dnsbl_stats }, */
|
||||
};
|
387
authd/providers/ident.c
Normal file
387
authd/providers/ident.c
Normal file
|
@ -0,0 +1,387 @@
|
|||
/* authd/providers/ident.c - ident lookup provider for authd
|
||||
* Copyright (c) 2016 Elizabeth Myers <elizabeth@interlinked.me>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice is present in all copies.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* Largely adapted from old s_auth.c, but reworked for authd. rDNS code
|
||||
* moved to its own provider.
|
||||
*
|
||||
* --Elizafox 13 March 2016
|
||||
*/
|
||||
|
||||
#include "stdinc.h"
|
||||
#include "defaults.h"
|
||||
#include "match.h"
|
||||
#include "authd.h"
|
||||
#include "notice.h"
|
||||
#include "provider.h"
|
||||
#include "res.h"
|
||||
|
||||
#define SELF_PID (ident_provider.id)
|
||||
|
||||
#define IDENT_BUFSIZE 128
|
||||
|
||||
struct ident_query
|
||||
{
|
||||
rb_fde_t *F; /* Our FD */
|
||||
};
|
||||
|
||||
/* Goinked from old s_auth.c --Elizafox */
|
||||
static const char *messages[] =
|
||||
{
|
||||
"*** Checking Ident",
|
||||
"*** Got Ident response",
|
||||
"*** No Ident response",
|
||||
"*** Cannot verify ident validity, ignoring ident",
|
||||
"*** Ident disabled, not checking ident",
|
||||
};
|
||||
|
||||
typedef enum
|
||||
{
|
||||
REPORT_LOOKUP,
|
||||
REPORT_FOUND,
|
||||
REPORT_FAIL,
|
||||
REPORT_INVALID,
|
||||
REPORT_DISABLED,
|
||||
} ident_message;
|
||||
|
||||
static CNCB ident_connected;
|
||||
static PF read_ident_reply;
|
||||
|
||||
static void client_fail(struct auth_client *auth, ident_message message);
|
||||
static void client_success(struct auth_client *auth);
|
||||
static char * get_valid_ident(char *buf);
|
||||
|
||||
static int ident_timeout = IDENT_TIMEOUT_DEFAULT;
|
||||
static bool ident_enable = true;
|
||||
|
||||
|
||||
/*
|
||||
* ident_connected() - deal with the result of rb_connect_tcp()
|
||||
*
|
||||
* If the connection failed, we simply close the auth fd and report
|
||||
* a failure. If the connection suceeded send the ident server a query
|
||||
* giving "theirport , ourport". The write is only attempted *once* so
|
||||
* it is deemed to be a fail if the entire write doesn't write all the
|
||||
* data given. This shouldnt be a problem since the socket should have
|
||||
* a write buffer far greater than this message to store it in should
|
||||
* problems arise. -avalon
|
||||
*/
|
||||
static void
|
||||
ident_connected(rb_fde_t *F __unused, int error, void *data)
|
||||
{
|
||||
struct auth_client *auth = data;
|
||||
struct ident_query *query;
|
||||
char authbuf[32];
|
||||
int authlen;
|
||||
|
||||
lrb_assert(auth != NULL);
|
||||
query = get_provider_data(auth, SELF_PID);
|
||||
lrb_assert(query != NULL);
|
||||
|
||||
/* Check the error */
|
||||
if(error != RB_OK)
|
||||
{
|
||||
/* We had an error during connection :( */
|
||||
client_fail(auth, REPORT_FAIL);
|
||||
return;
|
||||
}
|
||||
|
||||
snprintf(authbuf, sizeof(authbuf), "%u , %u\r\n",
|
||||
auth->c_port, auth->l_port);
|
||||
authlen = strlen(authbuf);
|
||||
|
||||
if(rb_write(query->F, authbuf, authlen) != authlen)
|
||||
{
|
||||
client_fail(auth, REPORT_FAIL);
|
||||
return;
|
||||
}
|
||||
|
||||
read_ident_reply(query->F, auth);
|
||||
}
|
||||
|
||||
static void
|
||||
read_ident_reply(rb_fde_t *F, void *data)
|
||||
{
|
||||
struct auth_client *auth = data;
|
||||
char buf[IDENT_BUFSIZE + 1] = { 0 }; /* buffer to read auth reply into */
|
||||
ident_message message = REPORT_FAIL;
|
||||
char *s = NULL;
|
||||
char *t = NULL;
|
||||
ssize_t len;
|
||||
int count;
|
||||
|
||||
len = rb_read(F, buf, IDENT_BUFSIZE);
|
||||
if(len < 0 && rb_ignore_errno(errno))
|
||||
{
|
||||
rb_setselect(F, RB_SELECT_READ, read_ident_reply, auth);
|
||||
return;
|
||||
}
|
||||
|
||||
if(len > 0)
|
||||
{
|
||||
if((s = get_valid_ident(buf)) != NULL)
|
||||
{
|
||||
t = auth->username;
|
||||
|
||||
while (*s == '~' || *s == '^')
|
||||
s++;
|
||||
|
||||
for (count = USERLEN; *s && count; s++)
|
||||
{
|
||||
if(*s == '@' || *s == '\r' || *s == '\n')
|
||||
break;
|
||||
|
||||
if(*s != ' ' && *s != ':' && *s != '[')
|
||||
{
|
||||
*t++ = *s;
|
||||
count--;
|
||||
}
|
||||
}
|
||||
*t = '\0';
|
||||
}
|
||||
else
|
||||
message = REPORT_INVALID;
|
||||
}
|
||||
|
||||
if (*auth->username == '\0')
|
||||
{
|
||||
auth->username[0] = '*';
|
||||
auth->username[1] = '\0';
|
||||
}
|
||||
|
||||
if(s == NULL)
|
||||
client_fail(auth, message);
|
||||
else
|
||||
client_success(auth);
|
||||
}
|
||||
|
||||
static void
|
||||
client_fail(struct auth_client *auth, ident_message report)
|
||||
{
|
||||
struct ident_query *query = get_provider_data(auth, SELF_PID);
|
||||
|
||||
lrb_assert(query != NULL);
|
||||
|
||||
rb_strlcpy(auth->username, "*", sizeof(auth->username));
|
||||
|
||||
if(query->F != NULL)
|
||||
rb_close(query->F);
|
||||
|
||||
rb_free(query);
|
||||
set_provider_data(auth, SELF_PID, NULL);
|
||||
set_provider_timeout_absolute(auth, SELF_PID, 0);
|
||||
|
||||
notice_client(auth->cid, messages[report]);
|
||||
provider_done(auth, SELF_PID);
|
||||
|
||||
auth_client_unref(auth);
|
||||
}
|
||||
|
||||
static void
|
||||
client_success(struct auth_client *auth)
|
||||
{
|
||||
struct ident_query *query = get_provider_data(auth, SELF_PID);
|
||||
|
||||
lrb_assert(query != NULL);
|
||||
|
||||
if(query->F != NULL)
|
||||
rb_close(query->F);
|
||||
|
||||
rb_free(query);
|
||||
set_provider_data(auth, SELF_PID, NULL);
|
||||
set_provider_timeout_absolute(auth, SELF_PID, 0);
|
||||
|
||||
notice_client(auth->cid, messages[REPORT_FOUND]);
|
||||
provider_done(auth, SELF_PID);
|
||||
|
||||
auth_client_unref(auth);
|
||||
}
|
||||
|
||||
/* get_valid_ident
|
||||
* parse ident query reply from identd server
|
||||
*
|
||||
* Taken from old s_auth.c --Elizafox
|
||||
*
|
||||
* Inputs - pointer to ident buf
|
||||
* Outputs - NULL if no valid ident found, otherwise pointer to name
|
||||
* Side effects - None
|
||||
*/
|
||||
static char *
|
||||
get_valid_ident(char *buf)
|
||||
{
|
||||
int remp = 0;
|
||||
int locp = 0;
|
||||
char *colon1Ptr;
|
||||
char *colon2Ptr;
|
||||
char *colon3Ptr;
|
||||
char *commaPtr;
|
||||
char *remotePortString;
|
||||
|
||||
/* All this to get rid of a sscanf() fun. */
|
||||
remotePortString = buf;
|
||||
|
||||
colon1Ptr = strchr(remotePortString, ':');
|
||||
if(!colon1Ptr)
|
||||
return NULL;
|
||||
|
||||
*colon1Ptr = '\0';
|
||||
colon1Ptr++;
|
||||
colon2Ptr = strchr(colon1Ptr, ':');
|
||||
if(!colon2Ptr)
|
||||
return NULL;
|
||||
|
||||
*colon2Ptr = '\0';
|
||||
colon2Ptr++;
|
||||
commaPtr = strchr(remotePortString, ',');
|
||||
|
||||
if(!commaPtr)
|
||||
return NULL;
|
||||
|
||||
*commaPtr = '\0';
|
||||
commaPtr++;
|
||||
|
||||
remp = atoi(remotePortString);
|
||||
if(!remp)
|
||||
return NULL;
|
||||
|
||||
locp = atoi(commaPtr);
|
||||
if(!locp)
|
||||
return NULL;
|
||||
|
||||
/* look for USERID bordered by first pair of colons */
|
||||
if(!strstr(colon1Ptr, "USERID"))
|
||||
return NULL;
|
||||
|
||||
colon3Ptr = strchr(colon2Ptr, ':');
|
||||
if(!colon3Ptr)
|
||||
return NULL;
|
||||
|
||||
*colon3Ptr = '\0';
|
||||
colon3Ptr++;
|
||||
return (colon3Ptr);
|
||||
}
|
||||
|
||||
static void
|
||||
ident_destroy(void)
|
||||
{
|
||||
struct auth_client *auth;
|
||||
rb_dictionary_iter iter;
|
||||
|
||||
/* Nuke all ident queries */
|
||||
RB_DICTIONARY_FOREACH(auth, &iter, auth_clients)
|
||||
{
|
||||
if(get_provider_data(auth, SELF_PID) != NULL)
|
||||
client_fail(auth, REPORT_FAIL);
|
||||
/* auth is now invalid as we have no reference */
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
ident_start(struct auth_client *auth)
|
||||
{
|
||||
struct ident_query *query = rb_malloc(sizeof(struct ident_query));
|
||||
struct rb_sockaddr_storage l_addr, c_addr;
|
||||
int family = GET_SS_FAMILY(&auth->c_addr);
|
||||
|
||||
lrb_assert(get_provider_data(auth, SELF_PID) == NULL);
|
||||
|
||||
if(!ident_enable)
|
||||
{
|
||||
rb_free(query);
|
||||
notice_client(auth->cid, messages[REPORT_DISABLED]);
|
||||
provider_done(auth, SELF_PID);
|
||||
return true;
|
||||
}
|
||||
|
||||
auth_client_ref(auth);
|
||||
|
||||
notice_client(auth->cid, messages[REPORT_LOOKUP]);
|
||||
|
||||
set_provider_data(auth, SELF_PID, query);
|
||||
set_provider_timeout_relative(auth, SELF_PID, ident_timeout);
|
||||
|
||||
if((query->F = rb_socket(family, SOCK_STREAM, auth->protocol, "ident")) == NULL)
|
||||
{
|
||||
warn_opers(L_WARN, "Could not create ident socket: %s", strerror(errno));
|
||||
client_fail(auth, REPORT_FAIL);
|
||||
return true; /* Not a fatal error */
|
||||
}
|
||||
|
||||
/* Build sockaddr_storages for rb_connect_tcp below */
|
||||
l_addr = auth->l_addr;
|
||||
c_addr = auth->c_addr;
|
||||
|
||||
SET_SS_PORT(&l_addr, 0);
|
||||
SET_SS_PORT(&c_addr, htons(113));
|
||||
|
||||
rb_connect_tcp(query->F, (struct sockaddr *)&c_addr,
|
||||
(struct sockaddr *)&l_addr,
|
||||
ident_connected,
|
||||
auth, ident_timeout);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
ident_cancel(struct auth_client *auth)
|
||||
{
|
||||
struct ident_query *query = get_provider_data(auth, SELF_PID);
|
||||
|
||||
if(query != NULL)
|
||||
client_fail(auth, REPORT_FAIL);
|
||||
}
|
||||
|
||||
static void
|
||||
add_conf_ident_timeout(const char *key __unused, int parc __unused, const char **parv)
|
||||
{
|
||||
int timeout = atoi(parv[0]);
|
||||
|
||||
if(timeout < 0)
|
||||
{
|
||||
warn_opers(L_CRIT, "Ident: ident timeout < 0 (value: %d)", timeout);
|
||||
exit(EX_PROVIDER_ERROR);
|
||||
}
|
||||
|
||||
ident_timeout = timeout;
|
||||
}
|
||||
|
||||
static void
|
||||
set_ident_enabled(const char *key __unused, int parc __unused, const char **parv)
|
||||
{
|
||||
ident_enable = (*parv[0] == '1');
|
||||
}
|
||||
|
||||
struct auth_opts_handler ident_options[] =
|
||||
{
|
||||
{ "ident_timeout", 1, add_conf_ident_timeout },
|
||||
{ "ident_enabled", 1, set_ident_enabled },
|
||||
{ NULL, 0, NULL },
|
||||
};
|
||||
|
||||
|
||||
struct auth_provider ident_provider =
|
||||
{
|
||||
.name = "ident",
|
||||
.letter = 'I',
|
||||
.start = ident_start,
|
||||
.destroy = ident_destroy,
|
||||
.cancel = ident_cancel,
|
||||
.timeout = ident_cancel,
|
||||
.opt_handlers = ident_options,
|
||||
};
|
921
authd/providers/opm.c
Normal file
921
authd/providers/opm.c
Normal file
|
@ -0,0 +1,921 @@
|
|||
/* authd/providers/opm.c - small open proxy monitor
|
||||
* Copyright (c) 2016 Elizabeth Myers <elizabeth@interlinked.me>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice is present in all copies.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "stdinc.h"
|
||||
#include "rb_lib.h"
|
||||
#include "defaults.h"
|
||||
#include "setup.h"
|
||||
#include "authd.h"
|
||||
#include "notice.h"
|
||||
#include "provider.h"
|
||||
|
||||
#include <netinet/tcp.h> // TCP_NODELAY
|
||||
|
||||
#define SELF_PID (opm_provider.id)
|
||||
|
||||
#define OPM_READSIZE 128
|
||||
|
||||
typedef enum protocol_t
|
||||
{
|
||||
PROTO_NONE,
|
||||
PROTO_SOCKS4,
|
||||
PROTO_SOCKS5,
|
||||
PROTO_HTTP_CONNECT,
|
||||
PROTO_HTTPS_CONNECT,
|
||||
} protocol_t;
|
||||
|
||||
/* Lookup data associated with auth client */
|
||||
struct opm_lookup
|
||||
{
|
||||
rb_dlink_list scans; /* List of scans */
|
||||
bool in_progress;
|
||||
};
|
||||
|
||||
struct opm_scan;
|
||||
typedef void (*opm_callback_t)(struct opm_scan *);
|
||||
|
||||
/* A proxy scanner */
|
||||
struct opm_proxy
|
||||
{
|
||||
char note[16];
|
||||
protocol_t proto;
|
||||
uint16_t port;
|
||||
bool ssl; /* Connect to proxy with SSL */
|
||||
bool ipv6; /* Proxy supports IPv6 */
|
||||
|
||||
opm_callback_t callback;
|
||||
|
||||
rb_dlink_node node;
|
||||
};
|
||||
|
||||
/* A listener for proxy replies */
|
||||
struct opm_listener
|
||||
{
|
||||
char ip[HOSTIPLEN];
|
||||
uint16_t port;
|
||||
struct rb_sockaddr_storage addr;
|
||||
rb_fde_t *F;
|
||||
};
|
||||
|
||||
/* An individual proxy scan */
|
||||
struct opm_scan
|
||||
{
|
||||
struct auth_client *auth;
|
||||
rb_fde_t *F; /* fd for scan */
|
||||
|
||||
struct opm_proxy *proxy; /* Associated proxy */
|
||||
struct opm_listener *listener; /* Associated listener */
|
||||
|
||||
rb_dlink_node node;
|
||||
};
|
||||
|
||||
/* Proxies that we scan for */
|
||||
static rb_dlink_list proxy_scanners;
|
||||
|
||||
static ACCB accept_opm;
|
||||
static PF read_opm_reply;
|
||||
|
||||
static CNCB opm_connected;
|
||||
|
||||
static void opm_cancel(struct auth_client *auth);
|
||||
static bool create_listener(const char *ip, uint16_t port);
|
||||
|
||||
static int opm_timeout = OPM_TIMEOUT_DEFAULT;
|
||||
static bool opm_enable = false;
|
||||
|
||||
enum
|
||||
{
|
||||
LISTEN_IPV4,
|
||||
LISTEN_IPV6,
|
||||
LISTEN_LAST,
|
||||
};
|
||||
|
||||
/* IPv4 and IPv6 */
|
||||
static struct opm_listener listeners[LISTEN_LAST];
|
||||
|
||||
static inline protocol_t
|
||||
get_protocol_from_string(const char *str)
|
||||
{
|
||||
if(strcasecmp(str, "socks4") == 0)
|
||||
return PROTO_SOCKS4;
|
||||
else if(strcasecmp(str, "socks5") == 0)
|
||||
return PROTO_SOCKS5;
|
||||
else if(strcasecmp(str, "httpconnect") == 0)
|
||||
return PROTO_HTTP_CONNECT;
|
||||
else if(strcasecmp(str, "httpsconnect") == 0)
|
||||
return PROTO_HTTPS_CONNECT;
|
||||
else
|
||||
return PROTO_NONE;
|
||||
}
|
||||
|
||||
static inline struct opm_proxy *
|
||||
find_proxy_scanner(protocol_t proto, uint16_t port)
|
||||
{
|
||||
rb_dlink_node *ptr;
|
||||
|
||||
RB_DLINK_FOREACH(ptr, proxy_scanners.head)
|
||||
{
|
||||
struct opm_proxy *proxy = ptr->data;
|
||||
|
||||
if(proxy->proto == proto && proxy->port == port)
|
||||
return proxy;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* This is called when an open proxy connects to us */
|
||||
static void
|
||||
read_opm_reply(rb_fde_t *F, void *data)
|
||||
{
|
||||
rb_dlink_node *ptr;
|
||||
struct auth_client *auth = data;
|
||||
struct opm_lookup *lookup;
|
||||
char readbuf[OPM_READSIZE];
|
||||
ssize_t len;
|
||||
|
||||
lrb_assert(auth != NULL);
|
||||
lookup = get_provider_data(auth, SELF_PID);
|
||||
lrb_assert(lookup != NULL);
|
||||
|
||||
if((len = rb_read(F, readbuf, sizeof(readbuf))) < 0 && rb_ignore_errno(errno))
|
||||
{
|
||||
rb_setselect(F, RB_SELECT_READ, read_opm_reply, auth);
|
||||
return;
|
||||
}
|
||||
else if(len <= 0)
|
||||
{
|
||||
/* Dead */
|
||||
rb_close(F);
|
||||
return;
|
||||
}
|
||||
|
||||
RB_DLINK_FOREACH(ptr, proxy_scanners.head)
|
||||
{
|
||||
struct opm_proxy *proxy = ptr->data;
|
||||
|
||||
if(strncmp(proxy->note, readbuf, strlen(proxy->note)) == 0)
|
||||
{
|
||||
rb_dlink_node *ptr, *nptr;
|
||||
|
||||
/* Cancel outstanding lookups */
|
||||
RB_DLINK_FOREACH_SAFE(ptr, nptr, lookup->scans.head)
|
||||
{
|
||||
struct opm_scan *scan = ptr->data;
|
||||
|
||||
rb_close(scan->F);
|
||||
rb_free(scan);
|
||||
}
|
||||
|
||||
/* No longer needed, client is going away */
|
||||
rb_free(lookup);
|
||||
|
||||
reject_client(auth, SELF_PID, readbuf, "Open proxy detected");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
rb_close(F);
|
||||
}
|
||||
|
||||
static void
|
||||
accept_opm(rb_fde_t *F, int status, struct sockaddr *addr, rb_socklen_t len, void *data)
|
||||
{
|
||||
struct auth_client *auth = NULL;
|
||||
struct opm_listener *listener = data;
|
||||
struct rb_sockaddr_storage localaddr;
|
||||
unsigned int llen = sizeof(struct rb_sockaddr_storage);
|
||||
rb_dictionary_iter iter;
|
||||
|
||||
if(status != 0 || listener == NULL)
|
||||
{
|
||||
rb_close(F);
|
||||
return;
|
||||
}
|
||||
|
||||
if(getsockname(rb_get_fd(F), (struct sockaddr *)&localaddr, &llen))
|
||||
{
|
||||
/* This can happen if the client goes away after accept */
|
||||
rb_close(F);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Correlate connection with client(s) */
|
||||
RB_DICTIONARY_FOREACH(auth, &iter, auth_clients)
|
||||
{
|
||||
if(GET_SS_FAMILY(&auth->c_addr) != GET_SS_FAMILY(&localaddr))
|
||||
continue;
|
||||
|
||||
/* Compare the addresses */
|
||||
switch(GET_SS_FAMILY(&localaddr))
|
||||
{
|
||||
case AF_INET:
|
||||
{
|
||||
struct sockaddr_in *s = (struct sockaddr_in *)&localaddr, *c = (struct sockaddr_in *)&auth->c_addr;
|
||||
|
||||
if(s->sin_addr.s_addr == c->sin_addr.s_addr)
|
||||
{
|
||||
/* Match... check if it's real */
|
||||
rb_setselect(F, RB_SELECT_READ, read_opm_reply, auth);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case AF_INET6:
|
||||
{
|
||||
struct sockaddr_in6 *s = (struct sockaddr_in6 *)&localaddr, *c = (struct sockaddr_in6 *)&auth->c_addr;
|
||||
|
||||
if(IN6_ARE_ADDR_EQUAL(&s->sin6_addr, &c->sin6_addr))
|
||||
{
|
||||
rb_setselect(F, RB_SELECT_READ, read_opm_reply, auth);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
warn_opers(L_CRIT, "OPM: unknown address type in listen function");
|
||||
exit(EX_PROVIDER_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
/* We don't care about the socket if we get here */
|
||||
rb_close(F);
|
||||
}
|
||||
|
||||
/* Scanners */
|
||||
|
||||
static void
|
||||
opm_connected(rb_fde_t *F, int error, void *data)
|
||||
{
|
||||
struct opm_scan *scan = data;
|
||||
struct opm_proxy *proxy = scan->proxy;
|
||||
struct auth_client *auth = scan->auth;
|
||||
struct opm_lookup *lookup = get_provider_data(auth, SELF_PID);
|
||||
|
||||
if(error || !opm_enable)
|
||||
{
|
||||
//notice_client(scan->auth->cid, "*** Scan not connected: %s", proxy->note);
|
||||
goto end;
|
||||
}
|
||||
|
||||
switch(GET_SS_FAMILY(&auth->c_addr))
|
||||
{
|
||||
case AF_INET:
|
||||
if(listeners[LISTEN_IPV4].F == NULL)
|
||||
/* They cannot respond to us */
|
||||
goto end;
|
||||
|
||||
break;
|
||||
case AF_INET6:
|
||||
if(!proxy->ipv6)
|
||||
/* Welp, too bad */
|
||||
goto end;
|
||||
|
||||
if(listeners[LISTEN_IPV6].F == NULL)
|
||||
/* They cannot respond to us */
|
||||
goto end;
|
||||
|
||||
break;
|
||||
default:
|
||||
goto end;
|
||||
}
|
||||
|
||||
proxy->callback(scan);
|
||||
|
||||
end:
|
||||
rb_close(scan->F);
|
||||
rb_dlinkDelete(&scan->node, &lookup->scans);
|
||||
rb_free(scan);
|
||||
}
|
||||
|
||||
static void
|
||||
socks4_connected(struct opm_scan *scan)
|
||||
{
|
||||
uint8_t sendbuf[9]; /* Size we're building */
|
||||
uint8_t *c = sendbuf;
|
||||
|
||||
memcpy(c, "\x04\x01", 2); c += 2; /* Socks version 4, connect command */
|
||||
memcpy(c, &(((struct sockaddr_in *)&scan->listener->addr)->sin_port), 2); c += 2; /* Port */
|
||||
memcpy(c, &(((struct sockaddr_in *)&scan->listener->addr)->sin_addr.s_addr), 4); c += 4; /* Address */
|
||||
*c = '\x00'; /* No userid */
|
||||
|
||||
/* Send header */
|
||||
if(rb_write(scan->F, sendbuf, sizeof(sendbuf)) < 0)
|
||||
return;
|
||||
|
||||
/* Send note */
|
||||
if(rb_write(scan->F, scan->proxy->note, strlen(scan->proxy->note) + 1) < 0)
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
socks5_connected(struct opm_scan *scan)
|
||||
{
|
||||
struct auth_client *auth = scan->auth;
|
||||
uint8_t sendbuf[25]; /* Size we're building */
|
||||
uint8_t *c = sendbuf;
|
||||
|
||||
/* Build the version header and socks request
|
||||
* version header (3 bytes): version, number of auth methods, auth type (0 for none)
|
||||
* connect req (3 bytes): version, command (1 = connect), reserved (0)
|
||||
*/
|
||||
memcpy(c, "\x05\x01\x00\x05\x01\x00", 6); c += 6;
|
||||
|
||||
switch(GET_SS_FAMILY(&auth->c_addr))
|
||||
{
|
||||
case AF_INET:
|
||||
*(c++) = '\x01'; /* Address type (1 = IPv4) */
|
||||
memcpy(c, &(((struct sockaddr_in *)&scan->listener->addr)->sin_addr.s_addr), 4); c += 4; /* Address */
|
||||
memcpy(c, &(((struct sockaddr_in *)&scan->listener->addr)->sin_port), 2); c += 2; /* Port */
|
||||
break;
|
||||
case AF_INET6:
|
||||
*(c++) = '\x04'; /* Address type (4 = IPv6) */
|
||||
memcpy(c, ((struct sockaddr_in6 *)&scan->listener->addr)->sin6_addr.s6_addr, 16); c += 16; /* Address */
|
||||
memcpy(c, &(((struct sockaddr_in6 *)&scan->listener->addr)->sin6_port), 2); c += 2; /* Port */
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
/* Send header */
|
||||
if(rb_write(scan->F, sendbuf, (size_t)(sendbuf - c)) <= 0)
|
||||
return;
|
||||
|
||||
/* Now the note in a separate write */
|
||||
if(rb_write(scan->F, scan->proxy->note, strlen(scan->proxy->note) + 1) <= 0)
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
http_connect_connected(struct opm_scan *scan)
|
||||
{
|
||||
char sendbuf[128]; /* A bit bigger than we need but better safe than sorry */
|
||||
|
||||
/* Simple enough to build */
|
||||
snprintf(sendbuf, sizeof(sendbuf), "CONNECT %s:%hu HTTP/1.0\r\n\r\n", scan->listener->ip, scan->listener->port);
|
||||
|
||||
/* Send request */
|
||||
if(rb_write(scan->F, sendbuf, strlen(sendbuf)) <= 0)
|
||||
return;
|
||||
|
||||
/* Now the note in a separate write */
|
||||
if(rb_write(scan->F, scan->proxy->note, strlen(scan->proxy->note) + 1) <= 0)
|
||||
return;
|
||||
|
||||
/* MiroTik needs this, and as a separate write */
|
||||
if(rb_write(scan->F, "\r\n", 2) <= 0)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Establish connections */
|
||||
static inline void
|
||||
establish_connection(struct auth_client *auth, struct opm_proxy *proxy)
|
||||
{
|
||||
struct opm_lookup *lookup = get_provider_data(auth, SELF_PID);
|
||||
struct opm_scan *scan = rb_malloc(sizeof(struct opm_scan));
|
||||
struct opm_listener *listener;
|
||||
struct rb_sockaddr_storage c_a, l_a;
|
||||
int opt = 1;
|
||||
|
||||
lrb_assert(lookup != NULL);
|
||||
|
||||
if(GET_SS_FAMILY(&auth->c_addr) == AF_INET6)
|
||||
{
|
||||
if(proxy->proto == PROTO_SOCKS4)
|
||||
{
|
||||
/* SOCKS4 doesn't support IPv6 */
|
||||
rb_free(scan);
|
||||
return;
|
||||
}
|
||||
listener = &listeners[LISTEN_IPV6];
|
||||
}
|
||||
else
|
||||
listener = &listeners[LISTEN_IPV4];
|
||||
|
||||
if(listener->F == NULL)
|
||||
{
|
||||
/* We can't respond */
|
||||
rb_free(scan);
|
||||
return;
|
||||
}
|
||||
|
||||
c_a = auth->c_addr; /* Client */
|
||||
l_a = listener->addr; /* Listener (connect using its IP) */
|
||||
|
||||
scan->auth = auth;
|
||||
scan->proxy = proxy;
|
||||
scan->listener = listener;
|
||||
if((scan->F = rb_socket(GET_SS_FAMILY(&auth->c_addr), SOCK_STREAM, 0, proxy->note)) == NULL)
|
||||
{
|
||||
warn_opers(L_WARN, "OPM: could not create OPM socket (proto %s): %s", proxy->note, strerror(errno));
|
||||
rb_free(scan);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Disable Nagle's algorithim - buffering could affect scans */
|
||||
(void)setsockopt(rb_get_fd(scan->F), IPPROTO_TCP, TCP_NODELAY, (char *)&opt, sizeof(opt));
|
||||
|
||||
SET_SS_PORT(&l_a, 0);
|
||||
SET_SS_PORT(&c_a, htons(proxy->port));
|
||||
|
||||
rb_dlinkAdd(scan, &scan->node, &lookup->scans);
|
||||
|
||||
if(!proxy->ssl)
|
||||
rb_connect_tcp(scan->F,
|
||||
(struct sockaddr *)&c_a,
|
||||
(struct sockaddr *)&l_a,
|
||||
opm_connected, scan, opm_timeout);
|
||||
else
|
||||
rb_connect_tcp_ssl(scan->F,
|
||||
(struct sockaddr *)&c_a,
|
||||
(struct sockaddr *)&l_a,
|
||||
opm_connected, scan, opm_timeout);
|
||||
}
|
||||
|
||||
static bool
|
||||
create_listener(const char *ip, uint16_t port)
|
||||
{
|
||||
struct auth_client *auth;
|
||||
struct opm_listener *listener;
|
||||
struct rb_sockaddr_storage addr;
|
||||
rb_dictionary_iter iter;
|
||||
rb_fde_t *F;
|
||||
int opt = 1;
|
||||
|
||||
if(!rb_inet_pton_sock(ip, &addr))
|
||||
{
|
||||
warn_opers(L_CRIT, "OPM: got a bad listener: %s:%hu", ip, port);
|
||||
exit(EX_PROVIDER_ERROR);
|
||||
}
|
||||
|
||||
SET_SS_PORT(&addr, htons(port));
|
||||
|
||||
if(GET_SS_FAMILY(&addr) == AF_INET6)
|
||||
{
|
||||
struct sockaddr_in6 *a1, *a2;
|
||||
|
||||
listener = &listeners[LISTEN_IPV6];
|
||||
|
||||
a1 = (struct sockaddr_in6 *)&addr;
|
||||
a2 = (struct sockaddr_in6 *)&listener->addr;
|
||||
|
||||
if(IN6_ARE_ADDR_EQUAL(&a1->sin6_addr, &a2->sin6_addr) &&
|
||||
GET_SS_PORT(&addr) == GET_SS_PORT(&listener->addr) &&
|
||||
listener->F != NULL)
|
||||
{
|
||||
/* Listener already exists */
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
struct sockaddr_in *a1, *a2;
|
||||
|
||||
listener = &listeners[LISTEN_IPV4];
|
||||
|
||||
a1 = (struct sockaddr_in *)&addr;
|
||||
a2 = (struct sockaddr_in *)&listener->addr;
|
||||
|
||||
if(a1->sin_addr.s_addr == a2->sin_addr.s_addr &&
|
||||
GET_SS_PORT(&addr) == GET_SS_PORT(&listener->addr) &&
|
||||
listener->F != NULL)
|
||||
{
|
||||
/* Listener already exists */
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if((F = rb_socket(GET_SS_FAMILY(&addr), SOCK_STREAM, 0, "OPM listener socket")) == NULL)
|
||||
{
|
||||
/* This shouldn't fail, or we have big problems... */
|
||||
warn_opers(L_CRIT, "OPM: cannot create socket: %s", strerror(errno));
|
||||
exit(EX_PROVIDER_ERROR);
|
||||
}
|
||||
|
||||
if(setsockopt(rb_get_fd(F), SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt)))
|
||||
{
|
||||
/* This shouldn't fail either... */
|
||||
warn_opers(L_CRIT, "OPM: cannot set options on socket: %s", strerror(errno));
|
||||
exit(EX_PROVIDER_ERROR);
|
||||
}
|
||||
|
||||
if(bind(rb_get_fd(F), (struct sockaddr *)&addr, GET_SS_LEN(&addr)))
|
||||
{
|
||||
/* Shit happens, let's not cripple authd over /this/ since it could be user error */
|
||||
warn_opers(L_WARN, "OPM: cannot bind on socket: %s", strerror(errno));
|
||||
rb_close(F);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(rb_listen(F, SOMAXCONN, false)) /* deferred accept could interfere with detection */
|
||||
{
|
||||
/* Again, could be user error */
|
||||
warn_opers(L_WARN, "OPM: cannot listen on socket: %s", strerror(errno));
|
||||
rb_close(F);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* From this point forward we assume we have a listener */
|
||||
|
||||
if(listener->F != NULL)
|
||||
/* Close old listener */
|
||||
rb_close(listener->F);
|
||||
|
||||
listener->F = F;
|
||||
|
||||
/* Cancel clients that may be on old listener
|
||||
* XXX - should rescan clients that need it
|
||||
*/
|
||||
RB_DICTIONARY_FOREACH(auth, &iter, auth_clients)
|
||||
{
|
||||
opm_cancel(auth);
|
||||
/* auth is now invalid as we have no reference */
|
||||
}
|
||||
|
||||
/* Copy data */
|
||||
rb_strlcpy(listener->ip, ip, sizeof(listener->ip));
|
||||
listener->port = port;
|
||||
listener->addr = addr;
|
||||
|
||||
opm_enable = true; /* Implicitly set this to true for now if we have a listener */
|
||||
rb_accept_tcp(listener->F, NULL, accept_opm, listener);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
opm_scan(struct auth_client *auth)
|
||||
{
|
||||
rb_dlink_node *ptr;
|
||||
struct opm_lookup *lookup;
|
||||
|
||||
lrb_assert(auth != NULL);
|
||||
|
||||
lookup = get_provider_data(auth, SELF_PID);
|
||||
set_provider_timeout_relative(auth, SELF_PID, opm_timeout);
|
||||
|
||||
lookup->in_progress = true;
|
||||
|
||||
RB_DLINK_FOREACH(ptr, proxy_scanners.head)
|
||||
{
|
||||
struct opm_proxy *proxy = ptr->data;
|
||||
//notice_client(auth->cid, "*** Scanning for proxy type %s", proxy->note);
|
||||
establish_connection(auth, proxy);
|
||||
}
|
||||
|
||||
notice_client(auth->cid, "*** Scanning for open proxies...");
|
||||
}
|
||||
|
||||
/* This is called every time a provider is completed as long as we are marked not done */
|
||||
static void
|
||||
opm_initiate(struct auth_client *auth, uint32_t provider)
|
||||
{
|
||||
struct opm_lookup *lookup = get_provider_data(auth, SELF_PID);
|
||||
|
||||
lrb_assert(provider != SELF_PID);
|
||||
lrb_assert(!is_provider_done(auth, SELF_PID));
|
||||
lrb_assert(rb_dlink_list_length(&proxy_scanners) > 0);
|
||||
|
||||
if (lookup == NULL || lookup->in_progress) {
|
||||
/* Nothing to do */
|
||||
return;
|
||||
} else if (run_after_provider(auth, "rdns") && run_after_provider(auth,"ident")) {
|
||||
/* Start scanning if ident and rdns are finished, or not loaded. */
|
||||
opm_scan(auth);
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
opm_start(struct auth_client *auth)
|
||||
{
|
||||
lrb_assert(get_provider_data(auth, SELF_PID) == NULL);
|
||||
|
||||
if (!opm_enable || rb_dlink_list_length(&proxy_scanners) == 0) {
|
||||
/* Nothing to do... */
|
||||
provider_done(auth, SELF_PID);
|
||||
return true;
|
||||
}
|
||||
|
||||
auth_client_ref(auth);
|
||||
|
||||
set_provider_data(auth, SELF_PID, rb_malloc(sizeof(struct opm_lookup)));
|
||||
|
||||
if (run_after_provider(auth, "rdns") && run_after_provider(auth, "ident")) {
|
||||
/* Start scanning if ident and rdns are finished, or not loaded. */
|
||||
opm_scan(auth);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
opm_cancel(struct auth_client *auth)
|
||||
{
|
||||
struct opm_lookup *lookup = get_provider_data(auth, SELF_PID);
|
||||
|
||||
if(lookup != NULL)
|
||||
{
|
||||
rb_dlink_node *ptr, *nptr;
|
||||
|
||||
notice_client(auth->cid, "*** Did not detect open proxies");
|
||||
|
||||
RB_DLINK_FOREACH_SAFE(ptr, nptr, lookup->scans.head)
|
||||
{
|
||||
struct opm_scan *scan = ptr->data;
|
||||
|
||||
rb_close(scan->F);
|
||||
rb_free(scan);
|
||||
}
|
||||
|
||||
rb_free(lookup);
|
||||
|
||||
set_provider_data(auth, SELF_PID, NULL);
|
||||
set_provider_timeout_absolute(auth, SELF_PID, 0);
|
||||
provider_done(auth, SELF_PID);
|
||||
|
||||
auth_client_unref(auth);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
opm_destroy(void)
|
||||
{
|
||||
struct auth_client *auth;
|
||||
rb_dictionary_iter iter;
|
||||
|
||||
/* Nuke all opm lookups */
|
||||
RB_DICTIONARY_FOREACH(auth, &iter, auth_clients)
|
||||
{
|
||||
opm_cancel(auth);
|
||||
/* auth is now invalid as we have no reference */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
add_conf_opm_timeout(const char *key __unused, int parc __unused, const char **parv)
|
||||
{
|
||||
int timeout = atoi(parv[0]);
|
||||
|
||||
if(timeout < 0)
|
||||
{
|
||||
warn_opers(L_CRIT, "opm: opm timeout < 0 (value: %d)", timeout);
|
||||
return;
|
||||
}
|
||||
|
||||
opm_timeout = timeout;
|
||||
}
|
||||
|
||||
static void
|
||||
set_opm_enabled(const char *key __unused, int parc __unused, const char **parv)
|
||||
{
|
||||
bool enable = (*parv[0] == '1');
|
||||
|
||||
if(!enable)
|
||||
{
|
||||
if(listeners[LISTEN_IPV4].F != NULL || listeners[LISTEN_IPV6].F != NULL)
|
||||
{
|
||||
struct auth_client *auth;
|
||||
rb_dictionary_iter iter;
|
||||
|
||||
/* Close the listening socket */
|
||||
if(listeners[LISTEN_IPV4].F != NULL)
|
||||
rb_close(listeners[LISTEN_IPV4].F);
|
||||
|
||||
if(listeners[LISTEN_IPV6].F != NULL)
|
||||
rb_close(listeners[LISTEN_IPV6].F);
|
||||
|
||||
listeners[LISTEN_IPV4].F = listeners[LISTEN_IPV6].F = NULL;
|
||||
|
||||
RB_DICTIONARY_FOREACH(auth, &iter, auth_clients)
|
||||
{
|
||||
opm_cancel(auth);
|
||||
/* auth is now invalid as we have no reference */
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(listeners[LISTEN_IPV4].ip[0] != '\0' && listeners[LISTEN_IPV4].port != 0)
|
||||
{
|
||||
if(listeners[LISTEN_IPV4].F == NULL)
|
||||
/* Pre-configured IP/port, just re-establish */
|
||||
create_listener(listeners[LISTEN_IPV4].ip, listeners[LISTEN_IPV4].port);
|
||||
}
|
||||
|
||||
if(listeners[LISTEN_IPV6].ip[0] != '\0' && listeners[LISTEN_IPV6].port != 0)
|
||||
{
|
||||
if(listeners[LISTEN_IPV6].F == NULL)
|
||||
/* Pre-configured IP/port, just re-establish */
|
||||
create_listener(listeners[LISTEN_IPV6].ip, listeners[LISTEN_IPV6].port);
|
||||
}
|
||||
}
|
||||
|
||||
opm_enable = enable;
|
||||
}
|
||||
|
||||
static void
|
||||
set_opm_listener(const char *key __unused, int parc __unused, const char **parv)
|
||||
{
|
||||
const char *ip = parv[0];
|
||||
int iport = atoi(parv[1]);
|
||||
|
||||
if(iport > 65535 || iport <= 0)
|
||||
{
|
||||
warn_opers(L_CRIT, "OPM: got a bad listener: %s:%s", parv[0], parv[1]);
|
||||
exit(EX_PROVIDER_ERROR);
|
||||
}
|
||||
|
||||
create_listener(ip, (uint16_t)iport);
|
||||
}
|
||||
|
||||
static void
|
||||
create_opm_scanner(const char *key __unused, int parc __unused, const char **parv)
|
||||
{
|
||||
int iport = atoi(parv[1]);
|
||||
struct opm_proxy *proxy = rb_malloc(sizeof(struct opm_proxy));
|
||||
|
||||
if(iport <= 0 || iport > 65535)
|
||||
{
|
||||
warn_opers(L_CRIT, "OPM: got a bad scanner: %s (port %s)", parv[0], parv[1]);
|
||||
exit(EX_PROVIDER_ERROR);
|
||||
}
|
||||
|
||||
proxy->port = (uint16_t)iport;
|
||||
|
||||
switch((proxy->proto = get_protocol_from_string(parv[0])))
|
||||
{
|
||||
case PROTO_SOCKS4:
|
||||
snprintf(proxy->note, sizeof(proxy->note), "socks4:%hu", proxy->port);
|
||||
proxy->ssl = false;
|
||||
proxy->callback = socks4_connected;
|
||||
break;
|
||||
case PROTO_SOCKS5:
|
||||
snprintf(proxy->note, sizeof(proxy->note), "socks5:%hu", proxy->port);
|
||||
proxy->ssl = false;
|
||||
proxy->callback = socks5_connected;
|
||||
break;
|
||||
case PROTO_HTTP_CONNECT:
|
||||
snprintf(proxy->note, sizeof(proxy->note), "httpconnect:%hu", proxy->port);
|
||||
proxy->ssl = false;
|
||||
proxy->callback = http_connect_connected;
|
||||
break;
|
||||
case PROTO_HTTPS_CONNECT:
|
||||
snprintf(proxy->note, sizeof(proxy->note), "httpsconnect:%hu", proxy->port);
|
||||
proxy->callback = http_connect_connected;
|
||||
proxy->ssl = true;
|
||||
break;
|
||||
default:
|
||||
warn_opers(L_CRIT, "OPM: got an unknown proxy type: %s (port %hu)", parv[0], proxy->port);
|
||||
exit(EX_PROVIDER_ERROR);
|
||||
}
|
||||
|
||||
if(find_proxy_scanner(proxy->proto, proxy->port) != NULL)
|
||||
{
|
||||
warn_opers(L_CRIT, "OPM: got a duplicate scanner: %s (port %hu)", parv[0], proxy->port);
|
||||
rb_free(proxy);
|
||||
return;
|
||||
}
|
||||
|
||||
rb_dlinkAdd(proxy, &proxy->node, &proxy_scanners);
|
||||
}
|
||||
|
||||
static void
|
||||
delete_opm_scanner(const char *key __unused, int parc __unused, const char **parv)
|
||||
{
|
||||
struct auth_client *auth;
|
||||
struct opm_proxy *proxy;
|
||||
protocol_t proto = get_protocol_from_string(parv[0]);
|
||||
int iport = atoi(parv[1]);
|
||||
rb_dictionary_iter iter;
|
||||
|
||||
if(iport <= 0 || iport > 65535)
|
||||
{
|
||||
warn_opers(L_CRIT, "OPM: got a bad scanner to delete: %s (port %s)", parv[0], parv[1]);
|
||||
exit(EX_PROVIDER_ERROR);
|
||||
}
|
||||
|
||||
if(proto == PROTO_NONE)
|
||||
{
|
||||
warn_opers(L_CRIT, "OPM: got an unknown proxy type to delete: %s (port %d)", parv[0], iport);
|
||||
exit(EX_PROVIDER_ERROR);
|
||||
}
|
||||
|
||||
if((proxy = find_proxy_scanner(proto, (uint16_t)iport)) == NULL)
|
||||
{
|
||||
warn_opers(L_CRIT, "OPM: cannot find proxy to delete: %s (port %d)", parv[0], iport);
|
||||
exit(EX_PROVIDER_ERROR);
|
||||
}
|
||||
|
||||
/* Abort remaining clients on this scanner */
|
||||
RB_DICTIONARY_FOREACH(auth, &iter, auth_clients)
|
||||
{
|
||||
rb_dlink_node *ptr;
|
||||
struct opm_lookup *lookup = get_provider_data(auth, SELF_PID);
|
||||
|
||||
if(lookup == NULL)
|
||||
continue;
|
||||
|
||||
auth_client_ref(auth);
|
||||
|
||||
RB_DLINK_FOREACH(ptr, lookup->scans.head)
|
||||
{
|
||||
struct opm_scan *scan = ptr->data;
|
||||
|
||||
if(scan->proxy->port == proxy->port && scan->proxy->proto == proxy->proto)
|
||||
{
|
||||
/* Match */
|
||||
rb_dlinkDelete(&scan->node, &lookup->scans);
|
||||
rb_free(scan);
|
||||
|
||||
if(rb_dlink_list_length(&lookup->scans) == 0)
|
||||
opm_cancel(auth);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
auth_client_unref(auth);
|
||||
}
|
||||
|
||||
rb_dlinkDelete(&proxy->node, &proxy_scanners);
|
||||
rb_free(proxy);
|
||||
|
||||
if(rb_dlink_list_length(&proxy_scanners) == 0)
|
||||
opm_enable = false;
|
||||
}
|
||||
|
||||
static void
|
||||
delete_opm_scanner_all(const char *key __unused, int parc __unused, const char **parv __unused)
|
||||
{
|
||||
struct auth_client *auth;
|
||||
rb_dlink_node *ptr, *nptr;
|
||||
rb_dictionary_iter iter;
|
||||
|
||||
RB_DLINK_FOREACH_SAFE(ptr, nptr, proxy_scanners.head)
|
||||
{
|
||||
rb_free(ptr->data);
|
||||
rb_dlinkDelete(ptr, &proxy_scanners);
|
||||
}
|
||||
|
||||
RB_DICTIONARY_FOREACH(auth, &iter, auth_clients)
|
||||
{
|
||||
opm_cancel(auth);
|
||||
/* auth is now invalid as we have no reference */
|
||||
}
|
||||
|
||||
opm_enable = false;
|
||||
}
|
||||
|
||||
static void
|
||||
delete_opm_listener_all(const char *key __unused, int parc __unused, const char **parv __unused)
|
||||
{
|
||||
if(listeners[LISTEN_IPV4].F != NULL)
|
||||
rb_close(listeners[LISTEN_IPV4].F);
|
||||
|
||||
if(listeners[LISTEN_IPV6].F != NULL)
|
||||
rb_close(listeners[LISTEN_IPV6].F);
|
||||
|
||||
memset(&listeners, 0, sizeof(listeners));
|
||||
}
|
||||
|
||||
|
||||
struct auth_opts_handler opm_options[] =
|
||||
{
|
||||
{ "opm_timeout", 1, add_conf_opm_timeout },
|
||||
{ "opm_enabled", 1, set_opm_enabled },
|
||||
{ "opm_listener", 2, set_opm_listener },
|
||||
{ "opm_listener_del_all", 0, delete_opm_listener_all },
|
||||
{ "opm_scanner", 2, create_opm_scanner },
|
||||
{ "opm_scanner_del", 2, delete_opm_scanner },
|
||||
{ "opm_scanner_del_all", 0, delete_opm_scanner_all },
|
||||
{ NULL, 0, NULL },
|
||||
};
|
||||
|
||||
struct auth_provider opm_provider =
|
||||
{
|
||||
.name = "opm",
|
||||
.letter = 'O',
|
||||
.destroy = opm_destroy,
|
||||
.start = opm_start,
|
||||
.cancel = opm_cancel,
|
||||
.timeout = opm_cancel,
|
||||
.completed = opm_initiate,
|
||||
.opt_handlers = opm_options,
|
||||
};
|
181
authd/providers/rdns.c
Normal file
181
authd/providers/rdns.c
Normal file
|
@ -0,0 +1,181 @@
|
|||
/* authd/providers/rdns.c - rDNS lookup provider for authd
|
||||
* Copyright (c) 2016 Elizabeth Myers <elizabeth@interlinked.me>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice is present in all copies.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "stdinc.h"
|
||||
#include "rb_commio.h"
|
||||
#include "authd.h"
|
||||
#include "provider.h"
|
||||
#include "notice.h"
|
||||
#include "res.h"
|
||||
#include "dns.h"
|
||||
|
||||
#define SELF_PID (rdns_provider.id)
|
||||
|
||||
struct user_query
|
||||
{
|
||||
struct dns_query *query; /* Pending DNS query */
|
||||
};
|
||||
|
||||
/* Goinked from old s_auth.c --Elizabeth */
|
||||
static const char *messages[] =
|
||||
{
|
||||
"*** Looking up your hostname...",
|
||||
"*** Couldn't look up your hostname",
|
||||
"*** Your hostname is too long, ignoring hostname",
|
||||
};
|
||||
|
||||
typedef enum
|
||||
{
|
||||
REPORT_LOOKUP,
|
||||
REPORT_FAIL,
|
||||
REPORT_TOOLONG,
|
||||
} dns_message;
|
||||
|
||||
static void client_fail(struct auth_client *auth, dns_message message);
|
||||
static void client_success(struct auth_client *auth);
|
||||
static void dns_answer_callback(const char *res, bool status, query_type type, void *data);
|
||||
|
||||
static int rdns_timeout = RDNS_TIMEOUT_DEFAULT;
|
||||
|
||||
static void
|
||||
dns_answer_callback(const char *res, bool status, query_type type, void *data)
|
||||
{
|
||||
struct auth_client *auth = data;
|
||||
|
||||
if(res == NULL || status == false)
|
||||
client_fail(auth, REPORT_FAIL);
|
||||
else if(strlen(res) > HOSTLEN)
|
||||
client_fail(auth, REPORT_TOOLONG);
|
||||
else
|
||||
{
|
||||
rb_strlcpy(auth->hostname, res, HOSTLEN + 1);
|
||||
client_success(auth);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
client_fail(struct auth_client *auth, dns_message report)
|
||||
{
|
||||
struct user_query *query = get_provider_data(auth, SELF_PID);
|
||||
|
||||
lrb_assert(query != NULL);
|
||||
|
||||
rb_strlcpy(auth->hostname, "*", sizeof(auth->hostname));
|
||||
|
||||
notice_client(auth->cid, messages[report]);
|
||||
cancel_query(query->query);
|
||||
|
||||
rb_free(query);
|
||||
|
||||
set_provider_data(auth, SELF_PID, NULL);
|
||||
set_provider_timeout_absolute(auth, SELF_PID, 0);
|
||||
provider_done(auth, SELF_PID);
|
||||
|
||||
auth_client_unref(auth);
|
||||
}
|
||||
|
||||
static void
|
||||
client_success(struct auth_client *auth)
|
||||
{
|
||||
struct user_query *query = get_provider_data(auth, SELF_PID);
|
||||
|
||||
lrb_assert(query != NULL);
|
||||
|
||||
notice_client(auth->cid, "*** Found your hostname: %s", auth->hostname);
|
||||
cancel_query(query->query);
|
||||
|
||||
rb_free(query);
|
||||
|
||||
set_provider_data(auth, SELF_PID, NULL);
|
||||
set_provider_timeout_absolute(auth, SELF_PID, 0);
|
||||
provider_done(auth, SELF_PID);
|
||||
|
||||
auth_client_unref(auth);
|
||||
}
|
||||
|
||||
static void
|
||||
rdns_destroy(void)
|
||||
{
|
||||
struct auth_client *auth;
|
||||
rb_dictionary_iter iter;
|
||||
|
||||
RB_DICTIONARY_FOREACH(auth, &iter, auth_clients)
|
||||
{
|
||||
if(get_provider_data(auth, SELF_PID) != NULL)
|
||||
client_fail(auth, REPORT_FAIL);
|
||||
/* auth is now invalid as we have no reference */
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
rdns_start(struct auth_client *auth)
|
||||
{
|
||||
struct user_query *query = rb_malloc(sizeof(struct user_query));
|
||||
|
||||
auth_client_ref(auth);
|
||||
|
||||
set_provider_data(auth, SELF_PID, query);
|
||||
set_provider_timeout_relative(auth, SELF_PID, rdns_timeout);
|
||||
|
||||
query->query = lookup_hostname(auth->c_ip, dns_answer_callback, auth);
|
||||
|
||||
notice_client(auth->cid, messages[REPORT_LOOKUP]);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
rdns_cancel(struct auth_client *auth)
|
||||
{
|
||||
struct user_query *query = get_provider_data(auth, SELF_PID);
|
||||
|
||||
if(query != NULL)
|
||||
client_fail(auth, REPORT_FAIL);
|
||||
}
|
||||
|
||||
static void
|
||||
add_conf_dns_timeout(const char *key, int parc, const char **parv)
|
||||
{
|
||||
int timeout = atoi(parv[0]);
|
||||
|
||||
if(timeout < 0)
|
||||
{
|
||||
warn_opers(L_CRIT, "rDNS: DNS timeout < 0 (value: %d)", timeout);
|
||||
exit(EX_PROVIDER_ERROR);
|
||||
}
|
||||
|
||||
rdns_timeout = timeout;
|
||||
}
|
||||
|
||||
struct auth_opts_handler rdns_options[] =
|
||||
{
|
||||
{ "rdns_timeout", 1, add_conf_dns_timeout },
|
||||
{ NULL, 0, NULL },
|
||||
};
|
||||
|
||||
struct auth_provider rdns_provider =
|
||||
{
|
||||
.name = "rdns",
|
||||
.letter = 'R',
|
||||
.destroy = rdns_destroy,
|
||||
.start = rdns_start,
|
||||
.cancel = rdns_cancel,
|
||||
.timeout = rdns_cancel,
|
||||
.opt_handlers = rdns_options,
|
||||
};
|
885
authd/res.c
Normal file
885
authd/res.c
Normal file
|
@ -0,0 +1,885 @@
|
|||
/*
|
||||
* A rewrite of Darren Reeds original res.c As there is nothing
|
||||
* left of Darrens original code, this is now licensed by the hybrid group.
|
||||
* (Well, some of the function names are the same, and bits of the structs..)
|
||||
* You can use it where it is useful, free even. Buy us a beer and stuff.
|
||||
*
|
||||
* The authors takes no responsibility for any damage or loss
|
||||
* of property which results from the use of this software.
|
||||
*
|
||||
* July 1999 - Rewrote a bunch of stuff here. Change hostent builder code,
|
||||
* added callbacks and reference counting of returned hostents.
|
||||
* --Bleep (Thomas Helvey <tomh@inxpress.net>)
|
||||
*
|
||||
* This was all needlessly complicated for irc. Simplified. No more hostent
|
||||
* All we really care about is the IP -> hostname mappings. Thats all.
|
||||
*
|
||||
* Apr 28, 2003 --cryogen and Dianora
|
||||
*
|
||||
* DNS server flooding lessened, AAAA-or-A lookup removed, ip6.int support
|
||||
* removed, various robustness fixes
|
||||
*
|
||||
* 2006 --jilles and nenolod
|
||||
*
|
||||
* Resend queries to other servers if the DNS server replies with an error or
|
||||
* an invalid response. Also, avoid servers that return errors or invalid
|
||||
* responses.
|
||||
*
|
||||
* October 2012 --mr_flea
|
||||
*
|
||||
* ircd-ratbox changes for random IDs merged back in.
|
||||
*
|
||||
* January 2016 --kaniini
|
||||
*/
|
||||
|
||||
#include <rb_lib.h>
|
||||
#include "setup.h"
|
||||
#include "res.h"
|
||||
#include "reslib.h"
|
||||
|
||||
#if (CHAR_BIT != 8)
|
||||
#error this code needs to be able to address individual octets
|
||||
#endif
|
||||
|
||||
static PF res_readreply;
|
||||
|
||||
#define MAXPACKET 1024 /* rfc sez 512 but we expand names so ... */
|
||||
#define AR_TTL 600 /* TTL in seconds for dns cache entries */
|
||||
|
||||
/* RFC 1104/1105 wasn't very helpful about what these fields
|
||||
* should be named, so for now, we'll just name them this way.
|
||||
* we probably should look at what named calls them or something.
|
||||
*/
|
||||
#define TYPE_SIZE (size_t)2
|
||||
#define CLASS_SIZE (size_t)2
|
||||
#define TTL_SIZE (size_t)4
|
||||
#define RDLENGTH_SIZE (size_t)2
|
||||
#define ANSWER_FIXED_SIZE (TYPE_SIZE + CLASS_SIZE + TTL_SIZE + RDLENGTH_SIZE)
|
||||
|
||||
struct in6_addr ipv6_addr;
|
||||
struct in_addr ipv4_addr;
|
||||
|
||||
struct reslist
|
||||
{
|
||||
rb_dlink_node node;
|
||||
int id;
|
||||
time_t ttl;
|
||||
char type;
|
||||
char queryname[IRCD_RES_HOSTLEN + 1]; /* name currently being queried */
|
||||
char retries; /* retry counter */
|
||||
char sends; /* number of sends (>1 means resent) */
|
||||
time_t sentat;
|
||||
time_t timeout;
|
||||
int lastns; /* index of last server sent to */
|
||||
struct rb_sockaddr_storage addr;
|
||||
char *name;
|
||||
struct DNSQuery *query; /* query callback for this request */
|
||||
};
|
||||
|
||||
static rb_fde_t *res_fd;
|
||||
static rb_dlink_list request_list = { NULL, NULL, 0 };
|
||||
static int ns_failure_count[IRCD_MAXNS]; /* timeouts and invalid/failed replies */
|
||||
|
||||
static void rem_request(struct reslist *request);
|
||||
static struct reslist *make_request(struct DNSQuery *query);
|
||||
static void gethost_byname_type_fqdn(const char *name, struct DNSQuery *query,
|
||||
int type);
|
||||
static void do_query_name(struct DNSQuery *query, const char *name, struct reslist *request, int);
|
||||
static void do_query_number(struct DNSQuery *query, const struct rb_sockaddr_storage *,
|
||||
struct reslist *request);
|
||||
static void query_name(struct reslist *request);
|
||||
static int send_res_msg(const char *buf, int len, int count);
|
||||
static void resend_query(struct reslist *request);
|
||||
static int check_question(struct reslist *request, HEADER * header, char *buf, char *eob);
|
||||
static int proc_answer(struct reslist *request, HEADER * header, char *, char *);
|
||||
static struct reslist *find_id(int id);
|
||||
static struct DNSReply *make_dnsreply(struct reslist *request);
|
||||
static uint16_t generate_random_id(void);
|
||||
|
||||
/*
|
||||
* int
|
||||
* res_ourserver(inp)
|
||||
* looks up "inp" in irc_nsaddr_list[]
|
||||
* returns:
|
||||
* server ID or -1 for not found
|
||||
* author:
|
||||
* paul vixie, 29may94
|
||||
* revised for ircd, cryogen(stu) may03
|
||||
* slightly modified for charybdis, mr_flea oct12
|
||||
*/
|
||||
static int
|
||||
res_ourserver(const struct rb_sockaddr_storage *inp)
|
||||
{
|
||||
const struct sockaddr_in6 *v6;
|
||||
const struct sockaddr_in6 *v6in = (const struct sockaddr_in6 *)inp;
|
||||
const struct sockaddr_in *v4;
|
||||
const struct sockaddr_in *v4in = (const struct sockaddr_in *)inp;
|
||||
int ns;
|
||||
|
||||
for(ns = 0; ns < irc_nscount; ns++)
|
||||
{
|
||||
const struct rb_sockaddr_storage *srv = &irc_nsaddr_list[ns];
|
||||
v6 = (const struct sockaddr_in6 *)srv;
|
||||
v4 = (const struct sockaddr_in *)srv;
|
||||
|
||||
/* could probably just memcmp(srv, inp, srv.ss_len) here
|
||||
* but we'll air on the side of caution - stu
|
||||
*/
|
||||
switch (GET_SS_FAMILY(srv))
|
||||
{
|
||||
case AF_INET6:
|
||||
if(GET_SS_FAMILY(srv) == GET_SS_FAMILY(inp))
|
||||
if(v6->sin6_port == v6in->sin6_port)
|
||||
if((memcmp(&v6->sin6_addr.s6_addr, &v6in->sin6_addr.s6_addr,
|
||||
sizeof(struct in6_addr)) == 0) ||
|
||||
(memcmp(&v6->sin6_addr.s6_addr, &in6addr_any,
|
||||
sizeof(struct in6_addr)) == 0))
|
||||
return 1;
|
||||
break;
|
||||
case AF_INET:
|
||||
if(GET_SS_FAMILY(srv) == GET_SS_FAMILY(inp))
|
||||
if(v4->sin_port == v4in->sin_port)
|
||||
if((v4->sin_addr.s_addr == INADDR_ANY)
|
||||
|| (v4->sin_addr.s_addr == v4in->sin_addr.s_addr))
|
||||
return 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* timeout_query_list - Remove queries from the list which have been
|
||||
* there too long without being resolved.
|
||||
*/
|
||||
static time_t timeout_query_list(time_t now)
|
||||
{
|
||||
rb_dlink_node *ptr;
|
||||
rb_dlink_node *next_ptr;
|
||||
struct reslist *request;
|
||||
time_t next_time = 0;
|
||||
time_t timeout = 0;
|
||||
|
||||
RB_DLINK_FOREACH_SAFE(ptr, next_ptr, request_list.head)
|
||||
{
|
||||
request = ptr->data;
|
||||
timeout = request->sentat + request->timeout;
|
||||
|
||||
if (now >= timeout)
|
||||
{
|
||||
ns_failure_count[request->lastns]++;
|
||||
request->sentat = now;
|
||||
request->timeout += request->timeout;
|
||||
resend_query(request);
|
||||
}
|
||||
|
||||
if ((next_time == 0) || timeout < next_time)
|
||||
{
|
||||
next_time = timeout;
|
||||
}
|
||||
}
|
||||
|
||||
return (next_time > now) ? next_time : (now + AR_TTL);
|
||||
}
|
||||
|
||||
/*
|
||||
* timeout_resolver - check request list
|
||||
*/
|
||||
static void timeout_resolver(void *notused)
|
||||
{
|
||||
timeout_query_list(rb_current_time());
|
||||
}
|
||||
|
||||
static struct ev_entry *timeout_resolver_ev = NULL;
|
||||
|
||||
/*
|
||||
* start_resolver - do everything we need to read the resolv.conf file
|
||||
* and initialize the resolver file descriptor if needed
|
||||
*/
|
||||
static void start_resolver(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
irc_res_init();
|
||||
for (i = 0; i < irc_nscount; i++)
|
||||
ns_failure_count[i] = 0;
|
||||
|
||||
if (res_fd == NULL)
|
||||
{
|
||||
if ((res_fd = rb_socket(GET_SS_FAMILY(&irc_nsaddr_list[0]), SOCK_DGRAM, 0,
|
||||
"UDP resolver socket")) == NULL)
|
||||
return;
|
||||
|
||||
/* At the moment, the resolver FD data is global .. */
|
||||
rb_setselect(res_fd, RB_SELECT_READ, res_readreply, NULL);
|
||||
timeout_resolver_ev = rb_event_add("timeout_resolver", timeout_resolver, NULL, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* init_resolver - initialize resolver and resolver library
|
||||
*/
|
||||
void init_resolver(void)
|
||||
{
|
||||
#ifdef HAVE_SRAND48
|
||||
srand48(rb_current_time());
|
||||
#endif
|
||||
start_resolver();
|
||||
}
|
||||
|
||||
/*
|
||||
* restart_resolver - reread resolv.conf, reopen socket
|
||||
*/
|
||||
void restart_resolver(void)
|
||||
{
|
||||
rb_close(res_fd);
|
||||
res_fd = NULL;
|
||||
rb_event_delete(timeout_resolver_ev); /* -ddosen */
|
||||
start_resolver();
|
||||
}
|
||||
|
||||
/*
|
||||
* add_local_domain - Add the domain to hostname, if it is missing
|
||||
* (as suggested by eps@TOASTER.SFSU.EDU)
|
||||
*/
|
||||
static void add_local_domain(char *hname, size_t size)
|
||||
{
|
||||
/* try to fix up unqualified names */
|
||||
if (strchr(hname, '.') == NULL)
|
||||
{
|
||||
if (irc_domain[0])
|
||||
{
|
||||
size_t len = strlen(hname);
|
||||
|
||||
if ((strlen(irc_domain) + len + 2) < size)
|
||||
{
|
||||
hname[len++] = '.';
|
||||
strcpy(hname + len, irc_domain);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* rem_request - remove a request from the list.
|
||||
* This must also free any memory that has been allocated for
|
||||
* temporary storage of DNS results.
|
||||
*/
|
||||
static void rem_request(struct reslist *request)
|
||||
{
|
||||
rb_dlinkDelete(&request->node, &request_list);
|
||||
rb_free(request->name);
|
||||
rb_free(request);
|
||||
}
|
||||
|
||||
/*
|
||||
* make_request - Create a DNS request record for the server.
|
||||
*/
|
||||
static struct reslist *make_request(struct DNSQuery *query)
|
||||
{
|
||||
struct reslist *request = rb_malloc(sizeof(struct reslist));
|
||||
|
||||
request->sentat = rb_current_time();
|
||||
request->retries = 3;
|
||||
request->timeout = 4; /* start at 4 and exponential inc. */
|
||||
request->query = query;
|
||||
|
||||
/*
|
||||
* generate a unique id
|
||||
* NOTE: we don't have to worry about converting this to and from
|
||||
* network byte order, the nameserver does not interpret this value
|
||||
* and returns it unchanged
|
||||
*
|
||||
* we generate an id per request now (instead of per send) to allow
|
||||
* late replies to be used.
|
||||
*/
|
||||
request->id = generate_random_id();
|
||||
|
||||
rb_dlinkAdd(request, &request->node, &request_list);
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
/*
|
||||
* retryfreq - determine how many queries to wait before resending
|
||||
* if there have been that many consecutive timeouts
|
||||
*
|
||||
* This is a cubic backoff btw, if anyone didn't pick up on it. --Elizafox
|
||||
*/
|
||||
static int retryfreq(int timeouts)
|
||||
{
|
||||
switch (timeouts)
|
||||
{
|
||||
case 1:
|
||||
return 3;
|
||||
case 2:
|
||||
return 9;
|
||||
case 3:
|
||||
return 27;
|
||||
case 4:
|
||||
return 81;
|
||||
default:
|
||||
return 243;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* send_res_msg - sends msg to a nameserver.
|
||||
* This should reflect /etc/resolv.conf.
|
||||
* Returns number of nameserver successfully sent to
|
||||
* or -1 if no successful sends.
|
||||
*/
|
||||
static int send_res_msg(const char *msg, int len, int rcount)
|
||||
{
|
||||
int i;
|
||||
int ns;
|
||||
static int retrycnt;
|
||||
|
||||
retrycnt++;
|
||||
/* First try a nameserver that seems to work.
|
||||
* Every once in a while, try a possibly broken one to check
|
||||
* if it is working again.
|
||||
*/
|
||||
for (i = 0; i < irc_nscount; i++)
|
||||
{
|
||||
ns = (i + rcount - 1) % irc_nscount;
|
||||
if (ns_failure_count[ns] && retrycnt % retryfreq(ns_failure_count[ns]))
|
||||
continue;
|
||||
if (sendto(rb_get_fd(res_fd), msg, len, 0,
|
||||
(struct sockaddr *)&(irc_nsaddr_list[ns]),
|
||||
GET_SS_LEN(&irc_nsaddr_list[ns])) == len)
|
||||
return ns;
|
||||
}
|
||||
|
||||
/* No known working nameservers, try some broken one. */
|
||||
for (i = 0; i < irc_nscount; i++)
|
||||
{
|
||||
ns = (i + rcount - 1) % irc_nscount;
|
||||
if (!ns_failure_count[ns])
|
||||
continue;
|
||||
if (sendto(rb_get_fd(res_fd), msg, len, 0,
|
||||
(struct sockaddr *)&(irc_nsaddr_list[ns]),
|
||||
GET_SS_LEN(&irc_nsaddr_list[ns])) == len)
|
||||
return ns;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* find_id - find a dns request id (id is determined by dn_mkquery)
|
||||
*/
|
||||
static struct reslist *find_id(int id)
|
||||
{
|
||||
rb_dlink_node *ptr;
|
||||
struct reslist *request;
|
||||
|
||||
RB_DLINK_FOREACH(ptr, request_list.head)
|
||||
{
|
||||
request = ptr->data;
|
||||
|
||||
if (request->id == id)
|
||||
return (request);
|
||||
}
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static uint16_t
|
||||
generate_random_id(void)
|
||||
{
|
||||
uint16_t id;
|
||||
|
||||
do
|
||||
{
|
||||
rb_get_random(&id, sizeof(id));
|
||||
if(id == 0xffff)
|
||||
continue;
|
||||
}
|
||||
while(find_id(id));
|
||||
return id;
|
||||
}
|
||||
|
||||
/*
|
||||
* gethost_byname_type - get host address from name, adding domain if needed
|
||||
*/
|
||||
void gethost_byname_type(const char *name, struct DNSQuery *query, int type)
|
||||
{
|
||||
char fqdn[IRCD_RES_HOSTLEN + 1];
|
||||
assert(name != 0);
|
||||
|
||||
rb_strlcpy(fqdn, name, sizeof fqdn);
|
||||
add_local_domain(fqdn, IRCD_RES_HOSTLEN);
|
||||
gethost_byname_type_fqdn(fqdn, query, type);
|
||||
}
|
||||
|
||||
/*
|
||||
* gethost_byname_type_fqdn - get host address from fqdn
|
||||
*/
|
||||
static void gethost_byname_type_fqdn(const char *name, struct DNSQuery *query,
|
||||
int type)
|
||||
{
|
||||
assert(name != 0);
|
||||
do_query_name(query, name, NULL, type);
|
||||
}
|
||||
|
||||
/*
|
||||
* gethost_byaddr - get host name from address
|
||||
*/
|
||||
void gethost_byaddr(const struct rb_sockaddr_storage *addr, struct DNSQuery *query)
|
||||
{
|
||||
do_query_number(query, addr, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* do_query_name - nameserver lookup name
|
||||
*/
|
||||
static void do_query_name(struct DNSQuery *query, const char *name, struct reslist *request,
|
||||
int type)
|
||||
{
|
||||
if (request == NULL)
|
||||
{
|
||||
request = make_request(query);
|
||||
request->name = rb_strdup(name);
|
||||
}
|
||||
|
||||
rb_strlcpy(request->queryname, name, sizeof(request->queryname));
|
||||
request->type = type;
|
||||
query_name(request);
|
||||
}
|
||||
|
||||
/* Build an rDNS style query - if suffix is NULL, use the appropriate .arpa zone */
|
||||
void build_rdns(char *buf, size_t size, const struct rb_sockaddr_storage *addr, const char *suffix)
|
||||
{
|
||||
const unsigned char *cp;
|
||||
|
||||
if (GET_SS_FAMILY(addr) == AF_INET)
|
||||
{
|
||||
const struct sockaddr_in *v4 = (const struct sockaddr_in *)addr;
|
||||
cp = (const unsigned char *)&v4->sin_addr.s_addr;
|
||||
|
||||
(void) snprintf(buf, size, "%u.%u.%u.%u.%s",
|
||||
(unsigned int)(cp[3]),
|
||||
(unsigned int)(cp[2]),
|
||||
(unsigned int)(cp[1]),
|
||||
(unsigned int)(cp[0]),
|
||||
suffix == NULL ? "in-addr.arpa" : suffix);
|
||||
}
|
||||
else if (GET_SS_FAMILY(addr) == AF_INET6)
|
||||
{
|
||||
const struct sockaddr_in6 *v6 = (const struct sockaddr_in6 *)addr;
|
||||
cp = (const unsigned char *)&v6->sin6_addr.s6_addr;
|
||||
|
||||
#define HI_NIBBLE(x) (unsigned int)((x) >> 4)
|
||||
#define LO_NIBBLE(x) (unsigned int)((x) & 0xf)
|
||||
|
||||
(void) snprintf(buf, size,
|
||||
"%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%s",
|
||||
LO_NIBBLE(cp[15]), HI_NIBBLE(cp[15]),
|
||||
LO_NIBBLE(cp[14]), HI_NIBBLE(cp[14]),
|
||||
LO_NIBBLE(cp[13]), HI_NIBBLE(cp[13]),
|
||||
LO_NIBBLE(cp[12]), HI_NIBBLE(cp[12]),
|
||||
LO_NIBBLE(cp[11]), HI_NIBBLE(cp[11]),
|
||||
LO_NIBBLE(cp[10]), HI_NIBBLE(cp[10]),
|
||||
LO_NIBBLE(cp[9]), HI_NIBBLE(cp[9]),
|
||||
LO_NIBBLE(cp[8]), HI_NIBBLE(cp[8]),
|
||||
LO_NIBBLE(cp[7]), HI_NIBBLE(cp[7]),
|
||||
LO_NIBBLE(cp[6]), HI_NIBBLE(cp[6]),
|
||||
LO_NIBBLE(cp[5]), HI_NIBBLE(cp[5]),
|
||||
LO_NIBBLE(cp[4]), HI_NIBBLE(cp[4]),
|
||||
LO_NIBBLE(cp[3]), HI_NIBBLE(cp[3]),
|
||||
LO_NIBBLE(cp[2]), HI_NIBBLE(cp[2]),
|
||||
LO_NIBBLE(cp[1]), HI_NIBBLE(cp[1]),
|
||||
LO_NIBBLE(cp[0]), HI_NIBBLE(cp[0]),
|
||||
suffix == NULL ? "ip6.arpa" : suffix);
|
||||
}
|
||||
|
||||
#undef HI_NIBBLE
|
||||
#undef LO_NIBBLE
|
||||
}
|
||||
|
||||
/*
|
||||
* do_query_number - Use this to do reverse IP# lookups.
|
||||
*/
|
||||
static void do_query_number(struct DNSQuery *query, const struct rb_sockaddr_storage *addr,
|
||||
struct reslist *request)
|
||||
{
|
||||
if (request == NULL)
|
||||
{
|
||||
request = make_request(query);
|
||||
memcpy(&request->addr, addr, sizeof(struct rb_sockaddr_storage));
|
||||
request->name = (char *)rb_malloc(IRCD_RES_HOSTLEN + 1);
|
||||
}
|
||||
|
||||
build_rdns(request->queryname, sizeof request->queryname, addr, NULL);
|
||||
|
||||
request->type = T_PTR;
|
||||
query_name(request);
|
||||
}
|
||||
|
||||
/*
|
||||
* query_name - generate a query based on class, type and name.
|
||||
*/
|
||||
static void query_name(struct reslist *request)
|
||||
{
|
||||
char buf[MAXPACKET];
|
||||
int request_len = 0;
|
||||
int ns;
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
|
||||
if ((request_len =
|
||||
irc_res_mkquery(request->queryname, C_IN, request->type, (unsigned char *)buf, sizeof(buf))) > 0)
|
||||
{
|
||||
HEADER *header = (HEADER *)(void *)buf;
|
||||
header->id = request->id;
|
||||
++request->sends;
|
||||
|
||||
ns = send_res_msg(buf, request_len, request->sends);
|
||||
if (ns != -1)
|
||||
request->lastns = ns;
|
||||
}
|
||||
}
|
||||
|
||||
static void resend_query(struct reslist *request)
|
||||
{
|
||||
if (--request->retries <= 0)
|
||||
{
|
||||
(*request->query->callback) (request->query->ptr, NULL);
|
||||
rem_request(request);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (request->type)
|
||||
{
|
||||
case T_PTR:
|
||||
do_query_number(NULL, &request->addr, request);
|
||||
break;
|
||||
case T_A:
|
||||
case T_AAAA:
|
||||
do_query_name(NULL, request->name, request, request->type);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* check_question - check if the reply really belongs to the
|
||||
* name we queried (to guard against late replies from previous
|
||||
* queries with the same id).
|
||||
*/
|
||||
static int check_question(struct reslist *request, HEADER * header, char *buf, char *eob)
|
||||
{
|
||||
char hostbuf[IRCD_RES_HOSTLEN + 1]; /* working buffer */
|
||||
unsigned char *current; /* current position in buf */
|
||||
int n; /* temp count */
|
||||
|
||||
current = (unsigned char *)buf + sizeof(HEADER);
|
||||
if (header->qdcount != 1)
|
||||
return 0;
|
||||
n = irc_dn_expand((unsigned char *)buf, (unsigned char *)eob, current, hostbuf,
|
||||
sizeof(hostbuf));
|
||||
if (n <= 0)
|
||||
return 0;
|
||||
if (rb_strcasecmp(hostbuf, request->queryname))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* proc_answer - process name server reply
|
||||
*/
|
||||
static int proc_answer(struct reslist *request, HEADER * header, char *buf, char *eob)
|
||||
{
|
||||
char hostbuf[IRCD_RES_HOSTLEN + 100]; /* working buffer */
|
||||
unsigned char *current; /* current position in buf */
|
||||
int type; /* answer type */
|
||||
int n; /* temp count */
|
||||
int rd_length;
|
||||
struct sockaddr_in *v4; /* conversion */
|
||||
struct sockaddr_in6 *v6;
|
||||
current = (unsigned char *)buf + sizeof(HEADER);
|
||||
|
||||
for (; header->qdcount > 0; --header->qdcount)
|
||||
{
|
||||
if ((n = irc_dn_skipname(current, (unsigned char *)eob)) < 0)
|
||||
return 0;
|
||||
|
||||
current += (size_t) n + QFIXEDSZ;
|
||||
}
|
||||
|
||||
/*
|
||||
* process each answer sent to us blech.
|
||||
*/
|
||||
while (header->ancount > 0 && (char *)current < eob)
|
||||
{
|
||||
header->ancount--;
|
||||
|
||||
n = irc_dn_expand((unsigned char *)buf, (unsigned char *)eob, current, hostbuf,
|
||||
sizeof(hostbuf));
|
||||
|
||||
if (n < 0)
|
||||
{
|
||||
/*
|
||||
* broken message
|
||||
*/
|
||||
return (0);
|
||||
}
|
||||
else if (n == 0)
|
||||
{
|
||||
/*
|
||||
* no more answers left
|
||||
*/
|
||||
return (0);
|
||||
}
|
||||
|
||||
hostbuf[IRCD_RES_HOSTLEN] = '\0';
|
||||
|
||||
/* With Address arithmetic you have to be very anal
|
||||
* this code was not working on alpha due to that
|
||||
* (spotted by rodder/jailbird/dianora)
|
||||
*/
|
||||
current += (size_t) n;
|
||||
|
||||
if (!(((char *)current + ANSWER_FIXED_SIZE) < eob))
|
||||
break;
|
||||
|
||||
type = irc_ns_get16(current);
|
||||
current += TYPE_SIZE;
|
||||
|
||||
(void) irc_ns_get16(current);
|
||||
current += CLASS_SIZE;
|
||||
|
||||
request->ttl = irc_ns_get32(current);
|
||||
current += TTL_SIZE;
|
||||
|
||||
rd_length = irc_ns_get16(current);
|
||||
current += RDLENGTH_SIZE;
|
||||
|
||||
/*
|
||||
* Wait to set request->type until we verify this structure
|
||||
*/
|
||||
switch (type)
|
||||
{
|
||||
case T_A:
|
||||
if (request->type != T_A)
|
||||
return (0);
|
||||
|
||||
/*
|
||||
* check for invalid rd_length or too many addresses
|
||||
*/
|
||||
if (rd_length != sizeof(struct in_addr))
|
||||
return (0);
|
||||
v4 = (struct sockaddr_in *)&request->addr;
|
||||
SET_SS_LEN(&request->addr, sizeof(struct sockaddr_in));
|
||||
v4->sin_family = AF_INET;
|
||||
memcpy(&v4->sin_addr, current, sizeof(struct in_addr));
|
||||
return (1);
|
||||
case T_AAAA:
|
||||
if (request->type != T_AAAA)
|
||||
return (0);
|
||||
if (rd_length != sizeof(struct in6_addr))
|
||||
return (0);
|
||||
SET_SS_LEN(&request->addr, sizeof(struct sockaddr_in6));
|
||||
v6 = (struct sockaddr_in6 *)&request->addr;
|
||||
v6->sin6_family = AF_INET6;
|
||||
memcpy(&v6->sin6_addr, current, sizeof(struct in6_addr));
|
||||
return (1);
|
||||
case T_PTR:
|
||||
if (request->type != T_PTR)
|
||||
return (0);
|
||||
n = irc_dn_expand((unsigned char *)buf, (unsigned char *)eob, current,
|
||||
hostbuf, sizeof(hostbuf));
|
||||
if (n < 0)
|
||||
return (0); /* broken message */
|
||||
else if (n == 0)
|
||||
return (0); /* no more answers left */
|
||||
|
||||
rb_strlcpy(request->name, hostbuf, IRCD_RES_HOSTLEN + 1);
|
||||
|
||||
return (1);
|
||||
}
|
||||
/* skip any other record type e.g. CNAME, DNAME; real answer should follow */
|
||||
current += rd_length;
|
||||
}
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* res_read_single_reply - read a dns reply from the nameserver and process it.
|
||||
* Return value: 1 if a packet was read, 0 otherwise
|
||||
*/
|
||||
static int res_read_single_reply(rb_fde_t *F, void *data)
|
||||
{
|
||||
char buf[sizeof(HEADER) + MAXPACKET]
|
||||
/* Sparc and alpha need 16bit-alignment for accessing header->id
|
||||
* (which is uint16_t). Because of the header = (HEADER*) buf;
|
||||
* lateron, this is neeeded. --FaUl
|
||||
*/
|
||||
#if defined(__sparc__) || defined(__alpha__)
|
||||
__attribute__ ((aligned(16)))
|
||||
#endif
|
||||
;
|
||||
HEADER *header;
|
||||
struct reslist *request = NULL;
|
||||
struct DNSReply *reply = NULL;
|
||||
int rc;
|
||||
int answer_count;
|
||||
socklen_t len = sizeof(struct rb_sockaddr_storage);
|
||||
struct rb_sockaddr_storage lsin;
|
||||
int ns;
|
||||
|
||||
rc = recvfrom(rb_get_fd(F), buf, sizeof(buf), 0, (struct sockaddr *)&lsin, &len);
|
||||
|
||||
/* No packet */
|
||||
if (rc == 0 || rc == -1)
|
||||
return 0;
|
||||
|
||||
/* Too small */
|
||||
if (rc <= (int)(sizeof(HEADER)))
|
||||
return 1;
|
||||
|
||||
/*
|
||||
* convert DNS reply reader from Network byte order to CPU byte order.
|
||||
*/
|
||||
header = (HEADER *)(void *)buf;
|
||||
header->ancount = ntohs(header->ancount);
|
||||
header->qdcount = ntohs(header->qdcount);
|
||||
header->nscount = ntohs(header->nscount);
|
||||
header->arcount = ntohs(header->arcount);
|
||||
|
||||
/*
|
||||
* response for an id which we have already received an answer for
|
||||
* just ignore this response.
|
||||
*/
|
||||
if (0 == (request = find_id(header->id)))
|
||||
return 1;
|
||||
|
||||
/*
|
||||
* check against possibly fake replies
|
||||
*/
|
||||
ns = res_ourserver(&lsin);
|
||||
if (ns == -1)
|
||||
return 1;
|
||||
|
||||
if (ns != request->lastns)
|
||||
{
|
||||
/*
|
||||
* We'll accept the late reply, but penalize it a little more to make
|
||||
* sure a laggy server doesn't end up favored.
|
||||
*/
|
||||
ns_failure_count[ns] += 3;
|
||||
}
|
||||
|
||||
|
||||
if (!check_question(request, header, buf, buf + rc))
|
||||
return 1;
|
||||
|
||||
if ((header->rcode != NO_ERRORS) || (header->ancount == 0))
|
||||
{
|
||||
/*
|
||||
* RFC 2136 states that in the event of a server returning SERVFAIL
|
||||
* or NOTIMP, the request should be resent to the next server.
|
||||
* Additionally, if the server refuses our query, resend it as well.
|
||||
* -- mr_flea
|
||||
*/
|
||||
if (SERVFAIL == header->rcode || NOTIMP == header->rcode ||
|
||||
REFUSED == header->rcode)
|
||||
{
|
||||
ns_failure_count[ns]++;
|
||||
resend_query(request);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Either a fatal error was returned or no answer. Cancel the
|
||||
* request.
|
||||
*/
|
||||
if (NXDOMAIN == header->rcode)
|
||||
{
|
||||
/* If the rcode is NXDOMAIN, treat it as a good response. */
|
||||
ns_failure_count[ns] /= 4;
|
||||
}
|
||||
(*request->query->callback) (request->query->ptr, NULL);
|
||||
rem_request(request);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/*
|
||||
* If this fails there was an error decoding the received packet.
|
||||
* -- jilles
|
||||
*/
|
||||
answer_count = proc_answer(request, header, buf, buf + rc);
|
||||
|
||||
if (answer_count)
|
||||
{
|
||||
if (request->type == T_PTR)
|
||||
{
|
||||
if (request->name == NULL)
|
||||
{
|
||||
/*
|
||||
* Got a PTR response with no name, something strange is
|
||||
* happening. Try another DNS server.
|
||||
*/
|
||||
ns_failure_count[ns]++;
|
||||
resend_query(request);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Lookup the 'authoritative' name that we were given for the
|
||||
* ip#.
|
||||
*/
|
||||
if (GET_SS_FAMILY(&request->addr) == AF_INET6)
|
||||
gethost_byname_type_fqdn(request->name, request->query, T_AAAA);
|
||||
else
|
||||
gethost_byname_type_fqdn(request->name, request->query, T_A);
|
||||
rem_request(request);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* got a name and address response, client resolved
|
||||
*/
|
||||
reply = make_dnsreply(request);
|
||||
(*request->query->callback) (request->query->ptr, reply);
|
||||
rb_free(reply);
|
||||
rem_request(request);
|
||||
}
|
||||
|
||||
ns_failure_count[ns] /= 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Invalid or corrupt reply - try another resolver. */
|
||||
ns_failure_count[ns]++;
|
||||
resend_query(request);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
res_readreply(rb_fde_t *F, void *data)
|
||||
{
|
||||
while (res_read_single_reply(F, data))
|
||||
;
|
||||
rb_setselect(F, RB_SELECT_READ, res_readreply, NULL);
|
||||
}
|
||||
|
||||
static struct DNSReply *
|
||||
make_dnsreply(struct reslist *request)
|
||||
{
|
||||
struct DNSReply *cp;
|
||||
lrb_assert(request != 0);
|
||||
|
||||
cp = (struct DNSReply *)rb_malloc(sizeof(struct DNSReply));
|
||||
|
||||
cp->h_name = request->name;
|
||||
memcpy(&cp->addr, &request->addr, sizeof(cp->addr));
|
||||
return (cp);
|
||||
}
|
|
@ -1,23 +1,17 @@
|
|||
/*
|
||||
* res.h for referencing functions in res.c, reslib.c
|
||||
*
|
||||
* $Id: res.h 2023 2006-09-02 23:47:27Z jilles $
|
||||
*/
|
||||
|
||||
#ifndef _CHARYBDIS_RES_H
|
||||
#define _CHARYBDIS_RES_H
|
||||
|
||||
#include "ircd_defs.h"
|
||||
#include "common.h"
|
||||
#include "reslib.h"
|
||||
#include "match.h"
|
||||
#include "ircd.h"
|
||||
#ifndef _SOLANUM_RES_H
|
||||
#define _SOLANUM_RES_H
|
||||
|
||||
/* Maximum number of nameservers in /etc/resolv.conf we care about
|
||||
* In hybrid, this was 2 -- but in Charybdis, we want to track
|
||||
* In hybrid, this was 2 -- but in Solanum, we want to track
|
||||
* a few more than that ;) --nenolod
|
||||
*/
|
||||
#define IRCD_MAXNS 10
|
||||
#define RESOLVER_HOSTLEN 255
|
||||
|
||||
struct DNSReply
|
||||
{
|
||||
|
@ -36,10 +30,8 @@ extern int irc_nscount;
|
|||
|
||||
extern void init_resolver(void);
|
||||
extern void restart_resolver(void);
|
||||
extern void delete_resolver_queries(const struct DNSQuery *);
|
||||
extern void gethost_byname_type(const char *, struct DNSQuery *, int);
|
||||
extern void gethost_byaddr(const struct rb_sockaddr_storage *, struct DNSQuery *);
|
||||
extern void add_local_domain(char *, size_t);
|
||||
extern void report_dns_servers(struct Client *);
|
||||
extern void build_rdns(char *, size_t, const struct rb_sockaddr_storage *, const char *);
|
||||
|
||||
#endif
|
|
@ -76,9 +76,10 @@
|
|||
* - Dianora
|
||||
*/
|
||||
|
||||
#include <rb_lib.h>
|
||||
#include <netdb.h>
|
||||
#include "stdinc.h"
|
||||
#include "ircd_defs.h"
|
||||
#include "common.h"
|
||||
#include "ircd.h"
|
||||
#include "res.h"
|
||||
#include "reslib.h"
|
||||
|
@ -89,9 +90,6 @@
|
|||
#define DNS_LABELTYPE_BITSTRING 0x41
|
||||
#define DNS_MAXLINE 128
|
||||
|
||||
/* $Id: reslib.c 1695 2006-06-27 15:11:23Z jilles $ */
|
||||
/* from Hybrid Id: reslib.c 177 2005-10-22 09:05:05Z michael $ */
|
||||
|
||||
struct rb_sockaddr_storage irc_nsaddr_list[IRCD_MAXNS];
|
||||
int irc_nscount = 0;
|
||||
char irc_domain[IRCD_RES_HOSTLEN + 1];
|
||||
|
@ -115,10 +113,10 @@ static const char digitvalue[256] = {
|
|||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*256*/
|
||||
};
|
||||
|
||||
static const char digits[] = "0123456789";
|
||||
|
||||
static int parse_resvconf(void);
|
||||
static void add_nameserver(const char *);
|
||||
|
||||
static const char digits[] = "0123456789";
|
||||
static int labellen(const unsigned char *lp);
|
||||
static int special(int ch);
|
||||
static int printable(int ch);
|
||||
|
@ -163,9 +161,6 @@ parse_resvconf(void)
|
|||
char input[DNS_MAXLINE];
|
||||
FILE *file;
|
||||
|
||||
/* XXX "/etc/resolv.conf" should be from a define in setup.h perhaps
|
||||
* for cygwin support etc. this hardcodes it to unix for now -db
|
||||
*/
|
||||
if ((file = fopen("/etc/resolv.conf", "r")) == NULL)
|
||||
return -1;
|
||||
|
||||
|
@ -177,7 +172,7 @@ parse_resvconf(void)
|
|||
|
||||
p = input;
|
||||
/* skip until something thats not a space is seen */
|
||||
while (IsSpace(*p))
|
||||
while (isspace(*p))
|
||||
p++;
|
||||
/* if at this point, have a '\0' then continue */
|
||||
if (*p == '\0')
|
||||
|
@ -189,7 +184,7 @@ parse_resvconf(void)
|
|||
|
||||
/* skip until a space is found */
|
||||
opt = p;
|
||||
while (!IsSpace(*p) && *p != '\0')
|
||||
while (!isspace(*p) && *p != '\0')
|
||||
p++;
|
||||
if (*p == '\0')
|
||||
continue; /* no arguments?.. ignore this line */
|
||||
|
@ -197,16 +192,16 @@ parse_resvconf(void)
|
|||
*p++ = '\0';
|
||||
|
||||
/* skip these spaces that are before the argument */
|
||||
while (IsSpace(*p))
|
||||
while (isspace(*p))
|
||||
p++;
|
||||
/* Now arg should be right where p is pointing */
|
||||
arg = p;
|
||||
if ((p = strpbrk(arg, " \t")) != NULL)
|
||||
*p = '\0'; /* take the first word */
|
||||
|
||||
if (irccmp(opt, "domain") == 0)
|
||||
if (rb_strcasecmp(opt, "domain") == 0)
|
||||
rb_strlcpy(irc_domain, arg, sizeof(irc_domain));
|
||||
else if (irccmp(opt, "nameserver") == 0)
|
||||
else if (rb_strcasecmp(opt, "nameserver") == 0)
|
||||
add_nameserver(arg);
|
||||
}
|
||||
|
||||
|
@ -228,10 +223,7 @@ add_nameserver(const char *arg)
|
|||
|
||||
/* Done max number of nameservers? */
|
||||
if (irc_nscount >= IRCD_MAXNS)
|
||||
{
|
||||
ilog (L_MAIN, "Too many nameservers, ignoring %s", arg);
|
||||
return;
|
||||
}
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = PF_UNSPEC;
|
||||
|
@ -1117,9 +1109,9 @@ irc_dn_find(const unsigned char *domain, const unsigned char *msg,
|
|||
}
|
||||
|
||||
/*
|
||||
* * Thinking in noninternationalized USASCII (per the DNS spec),
|
||||
* * convert this character to lower case if it's upper case.
|
||||
* */
|
||||
* Thinking in noninternationalized USASCII (per the DNS spec),
|
||||
* convert this character to lower case if it's upper case.
|
||||
*/
|
||||
static int
|
||||
mklower(int ch)
|
||||
{
|
|
@ -1,11 +1,10 @@
|
|||
/*
|
||||
* include/irc_reslib.h
|
||||
*
|
||||
* $Id: reslib.h 446 2006-02-12 02:46:54Z db $
|
||||
*/
|
||||
|
||||
#ifndef _CHARYBDIS_RESLIB_H
|
||||
#define _CHARYBDIS_RESLIB_H
|
||||
#ifndef _SOLANUM_RESLIB_H
|
||||
#define _SOLANUM_RESLIB_H
|
||||
|
||||
/* Longest hostname we're willing to work with.
|
||||
* Due to DNSBLs this is more than HOSTLEN.
|
||||
|
@ -79,24 +78,24 @@ typedef struct
|
|||
*/
|
||||
#define IRC_NS_GET16(s, cp) { \
|
||||
const unsigned char *t_cp = (const unsigned char *)(cp); \
|
||||
(s) = ((u_int16_t)t_cp[0] << 8) \
|
||||
| ((u_int16_t)t_cp[1]) \
|
||||
(s) = ((uint16_t)t_cp[0] << 8) \
|
||||
| ((uint16_t)t_cp[1]) \
|
||||
; \
|
||||
(cp) += NS_INT16SZ; \
|
||||
}
|
||||
|
||||
#define IRC_NS_GET32(l, cp) { \
|
||||
const unsigned char *t_cp = (const unsigned char *)(cp); \
|
||||
(l) = ((u_int32_t)t_cp[0] << 24) \
|
||||
| ((u_int32_t)t_cp[1] << 16) \
|
||||
| ((u_int32_t)t_cp[2] << 8) \
|
||||
| ((u_int32_t)t_cp[3]) \
|
||||
(l) = ((uint32_t)t_cp[0] << 24) \
|
||||
| ((uint32_t)t_cp[1] << 16) \
|
||||
| ((uint32_t)t_cp[2] << 8) \
|
||||
| ((uint32_t)t_cp[3]) \
|
||||
; \
|
||||
(cp) += NS_INT32SZ; \
|
||||
}
|
||||
|
||||
#define IRC_NS_PUT16(s, cp) { \
|
||||
u_int16_t t_s = (u_int16_t)(s); \
|
||||
uint16_t t_s = (uint16_t)(s); \
|
||||
unsigned char *t_cp = (unsigned char *)(cp); \
|
||||
*t_cp++ = t_s >> 8; \
|
||||
*t_cp = t_s; \
|
||||
|
@ -104,7 +103,7 @@ typedef struct
|
|||
}
|
||||
|
||||
#define IRC_NS_PUT32(l, cp) { \
|
||||
u_int32_t t_l = (u_int32_t)(l); \
|
||||
uint32_t t_l = (uint32_t)(l); \
|
||||
unsigned char *t_cp = (unsigned char *)(cp); \
|
||||
*t_cp++ = t_l >> 24; \
|
||||
*t_cp++ = t_l >> 16; \
|
96
autogen.sh
Executable file
96
autogen.sh
Executable file
|
@ -0,0 +1,96 @@
|
|||
#! /bin/sh
|
||||
|
||||
TOP_DIR=$(dirname $0)
|
||||
LAST_DIR=$PWD
|
||||
|
||||
if test ! -f $TOP_DIR/configure.ac ; then
|
||||
echo "You must execute this script from the top level directory."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
AUTOCONF=${AUTOCONF:-autoconf}
|
||||
ACLOCAL=${ACLOCAL:-aclocal}
|
||||
AUTOMAKE=${AUTOMAKE:-automake}
|
||||
AUTOHEADER=${AUTOHEADER:-autoheader}
|
||||
LIBTOOLIZE=${LIBTOOLIZE:-libtoolize}
|
||||
#SHTOOLIZE=${SHTOOLIZE:-shtoolize}
|
||||
|
||||
dump_help_screen ()
|
||||
{
|
||||
echo "Usage: $0 [options]"
|
||||
echo
|
||||
echo "options:"
|
||||
echo " -n skip CVS changelog creation"
|
||||
echo " -h,--help show this help screen"
|
||||
echo
|
||||
exit 0
|
||||
}
|
||||
|
||||
parse_options ()
|
||||
{
|
||||
while test "$1" != "" ; do
|
||||
case $1 in
|
||||
-h|--help)
|
||||
dump_help_screen
|
||||
;;
|
||||
-n)
|
||||
SKIP_CVS_CHANGELOG=yes
|
||||
;;
|
||||
*)
|
||||
echo Invalid argument - $1
|
||||
dump_help_screen
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
}
|
||||
|
||||
run_or_die ()
|
||||
{
|
||||
COMMAND=$1
|
||||
|
||||
# check for empty commands
|
||||
if test -z "$COMMAND" ; then
|
||||
echo "*warning* no command specified"
|
||||
return 1
|
||||
fi
|
||||
|
||||
shift;
|
||||
|
||||
OPTIONS="$@"
|
||||
|
||||
# print a message
|
||||
echo -n "*info* running $COMMAND"
|
||||
if test -n "$OPTIONS" ; then
|
||||
echo " ($OPTIONS)"
|
||||
else
|
||||
echo
|
||||
fi
|
||||
|
||||
# run or die
|
||||
$COMMAND $OPTIONS ; RESULT=$?
|
||||
if test $RESULT -ne 0 ; then
|
||||
echo "*error* $COMMAND failed. (exit code = $RESULT)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
parse_options "$@"
|
||||
|
||||
echo "Building librb autotools files."
|
||||
|
||||
cd "$TOP_DIR"/librb
|
||||
sh autogen.sh
|
||||
|
||||
echo "Building main autotools files."
|
||||
|
||||
cd "$LAST_DIR"
|
||||
|
||||
run_or_die $ACLOCAL -I m4
|
||||
run_or_die $LIBTOOLIZE --force --copy
|
||||
run_or_die $AUTOHEADER
|
||||
run_or_die $AUTOCONF
|
||||
run_or_die $AUTOMAKE --add-missing --copy
|
||||
#run_or_die $SHTOOLIZE all
|
11
bandb/Makefile.am
Normal file
11
bandb/Makefile.am
Normal file
|
@ -0,0 +1,11 @@
|
|||
pkglibexec_PROGRAMS = bandb
|
||||
bin_PROGRAMS = solanum-bantool
|
||||
AM_CFLAGS=$(WARNFLAGS)
|
||||
|
||||
AM_CPPFLAGS = -I../include -I../librb/include @SQLITE_INCLUDES@
|
||||
|
||||
bandb_SOURCES = bandb.c rsdb_sqlite3.c rsdb_snprintf.c
|
||||
bandb_LDADD = ../librb/src/librb.la @SQLITE_LD@
|
||||
|
||||
solanum_bantool_SOURCES = bantool.c rsdb_sqlite3.c rsdb_snprintf.c
|
||||
solanum_bantool_LDADD = ../librb/src/librb.la @SQLITE_LD@
|
|
@ -1,110 +0,0 @@
|
|||
#
|
||||
# Makefile.in for bandb/src
|
||||
#
|
||||
# $Id: Makefile.in 1285 2006-05-05 15:03:53Z nenolod $
|
||||
#
|
||||
|
||||
CC = @CC@
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_BIN = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
INSTALL_SUID = @INSTALL_PROGRAM@ -o root -m 4755
|
||||
RM = @RM@
|
||||
LEX = @LEX@
|
||||
LEXLIB = @LEXLIB@
|
||||
CFLAGS = @IRC_CFLAGS@ -DIRCD_PREFIX=\"@prefix@\"
|
||||
LDFLAGS = @LDFLAGS@
|
||||
MKDEP = @MKDEP@ -DIRCD_PREFIX=\"@prefix@\"
|
||||
MV = @MV@
|
||||
RM = @RM@
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
bindir = @bindir@
|
||||
libdir = @libdir@
|
||||
libexecdir = @libexecdir@
|
||||
pkglibexecdir = @pkglibexecdir@
|
||||
sysconfdir = @sysconfdir@
|
||||
localstatedir = @localstatedir@
|
||||
PACKAGE_TARNAME = @PACKAGE_TARNAME@
|
||||
|
||||
PROGRAM_PREFIX = @PROGRAM_PREFIX@
|
||||
|
||||
SQLITE_LIBS = @SQLITE_LD@
|
||||
SQLITE_INCLUDES = @SQLITE_INCLUDES@
|
||||
ZIP_LIB = @ZLIB_LD@
|
||||
|
||||
IRCDLIBS = @MODULES_LIBS@ -L../libratbox/src/.libs -lratbox @LIBS@ $(SSL_LIBS) $(ZIP_LIB) $(SQLITE_LIBS)
|
||||
|
||||
INCLUDES = -I. -I../include -I../libratbox/include $(SSL_INCLUDES) $(SQLITE_INCLUDES)
|
||||
CPPFLAGS = ${INCLUDES} @CPPFLAGS@
|
||||
|
||||
CFLAGS += -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION=1
|
||||
|
||||
pkglibexec_PROGS = bandb
|
||||
bin_PROGS = bantool
|
||||
PROGS = $(pkglibexec_PROGS) $(bin_PROGS)
|
||||
|
||||
BANDB_SOURCES = \
|
||||
bandb.c \
|
||||
rsdb_snprintf.c \
|
||||
rsdb_sqlite3.c \
|
||||
@SQLITE_SRC@
|
||||
|
||||
BANDB_OBJECTS = ${BANDB_SOURCES:.c=.o}
|
||||
|
||||
BANTOOL_SOURCES = \
|
||||
bantool.c \
|
||||
rsdb_snprintf.c \
|
||||
rsdb_sqlite3.c \
|
||||
@SQLITE_SRC@
|
||||
|
||||
BANTOOL_OBJECTS = ${BANTOOL_SOURCES:.c=.o}
|
||||
|
||||
all: bandb bantool
|
||||
|
||||
build: all
|
||||
|
||||
bandb: ${BANDB_OBJECTS}
|
||||
${CC} ${CFLAGS} ${LDFLAGS} -o $@ ${BANDB_OBJECTS} ${IRCDLIBS}
|
||||
|
||||
bantool: ${BANTOOL_OBJECTS}
|
||||
${CC} ${CFLAGS} ${LDFLAGS} -o $@ ${BANTOOL_OBJECTS} ${IRCDLIBS}
|
||||
|
||||
install: build
|
||||
@echo "ircd: installing bandb ($(PROGS))"
|
||||
@for i in $(bin_PROGS); do \
|
||||
if test -f $(DESTDIR)$(bindir)/$(PROGRAM_PREFIX)$$i; then \
|
||||
$(MV) $(DESTDIR)$(bindir)/$(PROGRAM_PREFIX)$$i $(DESTDIR)$(bindir)/$(PROGRAM_PREFIX)$$i.old; \
|
||||
fi; \
|
||||
$(INSTALL_BIN) $$i $(DESTDIR)$(bindir)/$(PROGRAM_PREFIX)$$i; \
|
||||
done
|
||||
@for i in $(pkglibexec_PROGS); do \
|
||||
if test -f '$(DESTDIR)$(pkglibexecdir)/'$$i; then \
|
||||
$(MV) '$(DESTDIR)$(pkglibexecdir)/'$$i '$(DESTDIR)$(pkglibexecdir)/'$$i.old; \
|
||||
fi; \
|
||||
$(INSTALL_BIN) $$i '$(DESTDIR)$(pkglibexecdir)/'$$i; \
|
||||
done
|
||||
|
||||
.c.o:
|
||||
${CC} ${CPPFLAGS} ${CFLAGS} -c $<
|
||||
|
||||
.PHONY: depend clean distclean
|
||||
depend:
|
||||
@${MKDEP} ${CPPFLAGS} ${SOURCES} > .depend.tmp
|
||||
@sed -e '/^# DO NOT DELETE THIS LINE/,$$d' <Makefile >Makefile.depend
|
||||
@echo '# DO NOT DELETE THIS LINE!!!' >>Makefile.depend
|
||||
@echo '# make depend needs it.' >>Makefile.depend
|
||||
@cat .depend.tmp >>Makefile.depend
|
||||
@mv Makefile.depend Makefile
|
||||
@rm -f .depend.tmp
|
||||
|
||||
clean:
|
||||
${RM} -f *.o *~ *.core core bandb bantool
|
||||
|
||||
lint:
|
||||
lint -aacgprxhH $(CPPFLAGS) -DIRCD_PREFIX=\"@prefix@\" $(SOURCES) >>../lint.out
|
||||
|
||||
distclean: clean
|
||||
${RM} -f Makefile
|
||||
|
||||
# End of Makefile
|
|
@ -26,14 +26,12 @@
|
|||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id: bandb.c 26094 2008-09-19 15:33:46Z androsyn $
|
||||
*/
|
||||
#include "setup.h"
|
||||
#include <ratbox_lib.h>
|
||||
#include <rb_lib.h>
|
||||
#include <stdio.h>
|
||||
#include "rsdb.h"
|
||||
#include "common.h"
|
||||
#include "ircd_defs.h"
|
||||
|
||||
|
||||
#define MAXPARA 10
|
||||
|
@ -161,11 +159,11 @@ list_bans(void)
|
|||
for(j = 0; j < table.row_count; j++)
|
||||
{
|
||||
if(i == BANDB_KLINE)
|
||||
rb_snprintf(buf, sizeof(buf), "%c %s %s %s :%s",
|
||||
snprintf(buf, sizeof(buf), "%c %s %s %s :%s",
|
||||
bandb_letter[i], table.row[j][0],
|
||||
table.row[j][1], table.row[j][2], table.row[j][3]);
|
||||
else
|
||||
rb_snprintf(buf, sizeof(buf), "%c %s %s :%s",
|
||||
snprintf(buf, sizeof(buf), "%c %s %s :%s",
|
||||
bandb_letter[i], table.row[j][0],
|
||||
table.row[j][2], table.row[j][3]);
|
||||
|
||||
|
@ -238,7 +236,14 @@ parse_request(rb_helper *helper)
|
|||
}
|
||||
|
||||
|
||||
<<<<<<< .merge_file_OcfD4C
|
||||
static void __attribute__((noreturn))
|
||||
=======
|
||||
static void
|
||||
error_cb(rb_helper *helper) __attribute__((noreturn));
|
||||
|
||||
static void
|
||||
>>>>>>> .merge_file_OF4zx2
|
||||
error_cb(rb_helper *helper)
|
||||
{
|
||||
if(in_transaction)
|
||||
|
@ -246,18 +251,15 @@ error_cb(rb_helper *helper)
|
|||
exit(1);
|
||||
}
|
||||
|
||||
#ifndef WINDOWS
|
||||
static void
|
||||
dummy_handler(int sig)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
setup_signals(void)
|
||||
{
|
||||
#ifndef WINDOWS
|
||||
struct sigaction act;
|
||||
|
||||
act.sa_flags = 0;
|
||||
|
@ -280,15 +282,21 @@ setup_signals(void)
|
|||
|
||||
act.sa_handler = dummy_handler;
|
||||
sigaction(SIGALRM, &act, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
<<<<<<< .merge_file_OcfD4C
|
||||
static void __attribute__((noreturn))
|
||||
=======
|
||||
static void
|
||||
db_error_cb(const char *errstr) __attribute__((noreturn));
|
||||
|
||||
static void
|
||||
>>>>>>> .merge_file_OF4zx2
|
||||
db_error_cb(const char *errstr)
|
||||
{
|
||||
char buf[256];
|
||||
rb_snprintf(buf, sizeof(buf), "! :%s", errstr);
|
||||
snprintf(buf, sizeof(buf), "! :%s", errstr);
|
||||
rb_helper_write(bandb_helper, "%s", buf);
|
||||
rb_sleep(1 << 30, 0);
|
||||
exit(1);
|
||||
|
@ -302,10 +310,9 @@ main(int argc, char *argv[])
|
|||
if(bandb_helper == NULL)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"This is ircd-ratbox bandb. You aren't supposed to run me directly. Maybe you want bantool?\n");
|
||||
"This is the solanum bandb for internal ircd use.\n");
|
||||
fprintf(stderr,
|
||||
"However I will print my Id tag $Id: bandb.c 26094 2008-09-19 15:33:46Z androsyn $\n");
|
||||
fprintf(stderr, "Have a nice day\n");
|
||||
"You aren't supposed to run me directly (did you want solanum-bantool?). Exiting.\n");
|
||||
exit(1);
|
||||
}
|
||||
rsdb_init(db_error_cb);
|
||||
|
|
109
bandb/bantool.c
109
bandb/bantool.c
|
@ -22,9 +22,6 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA
|
||||
*
|
||||
* $Id: bantool.c 26164 2008-10-26 19:52:43Z androsyn $
|
||||
*
|
||||
*
|
||||
* The following server admins have either contributed various configs to test against,
|
||||
* or helped with debugging and feature requests. Many thanks to them.
|
||||
* stevoo / efnet.port80.se
|
||||
|
@ -43,11 +40,9 @@
|
|||
#include <time.h>
|
||||
|
||||
#include "stdinc.h"
|
||||
#include "common.h"
|
||||
#include "rsdb.h"
|
||||
|
||||
#define EmptyString(x) ((x == NULL) || (*(x) == '\0'))
|
||||
#define CheckEmpty(x) EmptyString(x) ? "" : x
|
||||
|
||||
#define BT_VERSION "0.4.1"
|
||||
|
||||
|
@ -96,16 +91,16 @@ struct counter
|
|||
/* flags set by command line options */
|
||||
struct flags
|
||||
{
|
||||
int none;
|
||||
int export;
|
||||
int import;
|
||||
int verify;
|
||||
int vacuum;
|
||||
int pretend;
|
||||
int verbose;
|
||||
int wipe;
|
||||
int dupes_ok;
|
||||
} flag = {YES, NO, NO, NO, NO, NO, NO, NO, NO};
|
||||
bool none;
|
||||
bool export;
|
||||
bool import;
|
||||
bool verify;
|
||||
bool vacuum;
|
||||
bool pretend;
|
||||
bool verbose;
|
||||
bool wipe;
|
||||
bool dupes_ok;
|
||||
} flag = {true, false, false, false, false, false, false, false, false};
|
||||
/* *INDENT-ON* */
|
||||
|
||||
static int table_has_rows(const char *table);
|
||||
|
@ -148,32 +143,32 @@ main(int argc, char *argv[])
|
|||
print_help(EXIT_SUCCESS);
|
||||
/* noreturn call above, this is unreachable */
|
||||
case 'i':
|
||||
flag.none = NO;
|
||||
flag.import = YES;
|
||||
flag.none = false;
|
||||
flag.import = true;
|
||||
break;
|
||||
case 'e':
|
||||
flag.none = NO;
|
||||
flag.export = YES;
|
||||
flag.none = false;
|
||||
flag.export = true;
|
||||
break;
|
||||
case 'u':
|
||||
flag.none = NO;
|
||||
flag.verify = YES;
|
||||
flag.none = false;
|
||||
flag.verify = true;
|
||||
break;
|
||||
case 's':
|
||||
flag.none = NO;
|
||||
flag.vacuum = YES;
|
||||
flag.none = false;
|
||||
flag.vacuum = true;
|
||||
break;
|
||||
case 'p':
|
||||
flag.pretend = YES;
|
||||
flag.pretend = true;
|
||||
break;
|
||||
case 'v':
|
||||
flag.verbose = YES;
|
||||
flag.verbose = true;
|
||||
break;
|
||||
case 'w':
|
||||
flag.wipe = YES;
|
||||
flag.wipe = true;
|
||||
break;
|
||||
case 'd':
|
||||
flag.dupes_ok = YES;
|
||||
flag.dupes_ok = true;
|
||||
break;
|
||||
default: /* '?' */
|
||||
print_help(EXIT_FAILURE);
|
||||
|
@ -201,10 +196,9 @@ main(int argc, char *argv[])
|
|||
rb_strlcpy(etc, ETCPATH, sizeof(ETCPATH));
|
||||
|
||||
fprintf(stdout,
|
||||
"* ircd-ratbox bantool v.%s ($Id: bantool.c 26164 2008-10-26 19:52:43Z androsyn $)\n",
|
||||
BT_VERSION);
|
||||
"* solanum bantool v.%s\n", BT_VERSION);
|
||||
|
||||
if(flag.pretend == NO)
|
||||
if(flag.pretend == false)
|
||||
{
|
||||
if(rsdb_init(db_error_cb) == -1)
|
||||
{
|
||||
|
@ -218,7 +212,7 @@ main(int argc, char *argv[])
|
|||
|
||||
if(flag.import && flag.wipe)
|
||||
{
|
||||
flag.dupes_ok = YES; /* dont check for dupes if we are wiping the db clean */
|
||||
flag.dupes_ok = true; /* dont check for dupes if we are wiping the db clean */
|
||||
for(i = 0; i < 3; i++)
|
||||
fprintf(stdout,
|
||||
"* WARNING: YOU ARE ABOUT TO WIPE YOUR DATABASE!\n");
|
||||
|
@ -230,16 +224,19 @@ main(int argc, char *argv[])
|
|||
wipe_schema();
|
||||
}
|
||||
}
|
||||
if(flag.verbose && flag.dupes_ok == YES)
|
||||
if(flag.verbose && flag.dupes_ok == true)
|
||||
fprintf(stdout, "* Allowing duplicate bans...\n");
|
||||
|
||||
/* checking for our files to import or export */
|
||||
for(i = 0; i < LAST_BANDB_TYPE; i++)
|
||||
{
|
||||
rb_snprintf(conf, sizeof(conf), "%s/%s.conf%s",
|
||||
etc, bandb_table[i], bandb_suffix[i]);
|
||||
if (snprintf(conf, sizeof(conf), "%s/%s.conf%s",
|
||||
etc, bandb_table[i], bandb_suffix[i]) >= sizeof(conf)) {
|
||||
fprintf(stderr, "* Error: Config filename too long\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if(flag.import && flag.pretend == NO)
|
||||
if(flag.import && flag.pretend == false)
|
||||
rsdb_transaction(RSDB_TRANS_START);
|
||||
|
||||
if(flag.import)
|
||||
|
@ -248,7 +245,7 @@ main(int argc, char *argv[])
|
|||
if(flag.export)
|
||||
export_config(conf, i);
|
||||
|
||||
if(flag.import && flag.pretend == NO)
|
||||
if(flag.import && flag.pretend == false)
|
||||
rsdb_transaction(RSDB_TRANS_END);
|
||||
}
|
||||
|
||||
|
@ -297,11 +294,11 @@ export_config(const char *conf, int id)
|
|||
return;
|
||||
|
||||
if(strstr(conf, ".perm") != 0)
|
||||
rb_snprintf(sql, sizeof(sql),
|
||||
snprintf(sql, sizeof(sql),
|
||||
"SELECT DISTINCT mask1,mask2,reason,oper,time FROM %s WHERE perm = 1 ORDER BY time",
|
||||
bandb_table[id]);
|
||||
else
|
||||
rb_snprintf(sql, sizeof(sql),
|
||||
snprintf(sql, sizeof(sql),
|
||||
"SELECT DISTINCT mask1,mask2,reason,oper,time FROM %s WHERE perm = 0 ORDER BY time",
|
||||
bandb_table[id]);
|
||||
|
||||
|
@ -330,7 +327,7 @@ export_config(const char *conf, int id)
|
|||
{
|
||||
case BANDB_DLINE:
|
||||
case BANDB_DLINE_PERM:
|
||||
rb_snprintf(buf, sizeof(buf),
|
||||
snprintf(buf, sizeof(buf),
|
||||
"\"%s\",\"%s\",\"\",\"%s\",\"%s\",%s\n",
|
||||
table.row[j][mask1],
|
||||
mangle_reason(table.row[j][reason]),
|
||||
|
@ -340,7 +337,7 @@ export_config(const char *conf, int id)
|
|||
|
||||
case BANDB_XLINE:
|
||||
case BANDB_XLINE_PERM:
|
||||
rb_snprintf(buf, sizeof(buf),
|
||||
snprintf(buf, sizeof(buf),
|
||||
"\"%s\",\"0\",\"%s\",\"%s\",%s\n",
|
||||
escape_quotes(table.row[j][mask1]),
|
||||
mangle_reason(table.row[j][reason]),
|
||||
|
@ -349,7 +346,7 @@ export_config(const char *conf, int id)
|
|||
|
||||
case BANDB_RESV:
|
||||
case BANDB_RESV_PERM:
|
||||
rb_snprintf(buf, sizeof(buf),
|
||||
snprintf(buf, sizeof(buf),
|
||||
"\"%s\",\"%s\",\"%s\",%s\n",
|
||||
table.row[j][mask1],
|
||||
mangle_reason(table.row[j][reason]),
|
||||
|
@ -358,7 +355,7 @@ export_config(const char *conf, int id)
|
|||
|
||||
|
||||
default: /* Klines */
|
||||
rb_snprintf(buf, sizeof(buf),
|
||||
snprintf(buf, sizeof(buf),
|
||||
"\"%s\",\"%s\",\"%s\",\"\",\"%s\",\"%s\",%s\n",
|
||||
table.row[j][mask1], table.row[j][mask2],
|
||||
mangle_reason(table.row[j][reason]),
|
||||
|
@ -497,13 +494,13 @@ import_config(const char *conf, int id)
|
|||
|
||||
/* append operreason_field to reason_field */
|
||||
if(!EmptyString(f_oreason))
|
||||
rb_snprintf(newreason, sizeof(newreason), "%s | %s", f_reason, f_oreason);
|
||||
snprintf(newreason, sizeof(newreason), "%s | %s", f_reason, f_oreason);
|
||||
else
|
||||
rb_snprintf(newreason, sizeof(newreason), "%s", f_reason);
|
||||
snprintf(newreason, sizeof(newreason), "%s", f_reason);
|
||||
|
||||
if(flag.pretend == NO)
|
||||
if(flag.pretend == false)
|
||||
{
|
||||
if(flag.dupes_ok == NO)
|
||||
if(flag.dupes_ok == false)
|
||||
drop_dupes(f_mask1, f_mask2, bandb_table[id]);
|
||||
|
||||
rsdb_exec(NULL,
|
||||
|
@ -746,7 +743,7 @@ check_schema(void)
|
|||
NULL
|
||||
};
|
||||
|
||||
for(i = 0; i < LAST_BANDB_TYPE; i++)
|
||||
for(i = 0; i < LAST_BANDB_TYPE; i += 2 /* skip over _PERM */)
|
||||
{
|
||||
if(!table_exists(bandb_table[i]))
|
||||
{
|
||||
|
@ -773,8 +770,6 @@ check_schema(void)
|
|||
columns[j], type);
|
||||
}
|
||||
}
|
||||
|
||||
i++; /* skip over .perm */
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -812,17 +807,16 @@ table_has_rows(const char *dbtab)
|
|||
}
|
||||
|
||||
/**
|
||||
* completly wipes out an existing ban.db of all entries.
|
||||
* completely wipes out an existing ban.db of all entries.
|
||||
*/
|
||||
static void
|
||||
wipe_schema(void)
|
||||
{
|
||||
int i;
|
||||
rsdb_transaction(RSDB_TRANS_START);
|
||||
for(i = 0; i < LAST_BANDB_TYPE; i++)
|
||||
for(i = 0; i < LAST_BANDB_TYPE; i += 2 /* double increment to skip over _PERM */)
|
||||
{
|
||||
rsdb_exec(NULL, "DROP TABLE %s", bandb_table[i]);
|
||||
i++; /* double increment to skip over .perm */
|
||||
}
|
||||
rsdb_transaction(RSDB_TRANS_END);
|
||||
|
||||
|
@ -859,7 +853,7 @@ bt_smalldate(const char *string)
|
|||
lt = gmtime(&t);
|
||||
if(lt == NULL)
|
||||
return NULL;
|
||||
rb_snprintf(buf, sizeof(buf), "%d/%d/%d %02d.%02d",
|
||||
snprintf(buf, sizeof(buf), "%d/%d/%d %02d.%02d",
|
||||
lt->tm_year + 1900, lt->tm_mon + 1, lt->tm_mday, lt->tm_hour, lt->tm_min);
|
||||
return buf;
|
||||
}
|
||||
|
@ -870,9 +864,8 @@ bt_smalldate(const char *string)
|
|||
static void
|
||||
print_help(const int i_exit)
|
||||
{
|
||||
fprintf(stderr, "bantool v.%s - the ircd-ratbox database tool.\n", BT_VERSION);
|
||||
fprintf(stderr, "bantool v.%s - the solanum database tool.\n", BT_VERSION);
|
||||
fprintf(stderr, "Copyright (C) 2008 Daniel J Reidy <dubkat@gmail.com>\n");
|
||||
fprintf(stderr, "$Id: bantool.c 26164 2008-10-26 19:52:43Z androsyn $\n\n");
|
||||
fprintf(stderr, "This program is distributed in the hope that it will be useful,\n"
|
||||
"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
|
||||
"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
|
||||
|
@ -887,15 +880,15 @@ print_help(const int i_exit)
|
|||
fprintf(stderr, " -s : Reclaim empty slack space the database may be taking up.\n");
|
||||
fprintf(stderr, " -u : Update the database tables to support any new features.\n");
|
||||
fprintf(stderr,
|
||||
" This is automaticlly done if you are importing or exporting\n");
|
||||
" This is automatically done if you are importing or exporting\n");
|
||||
fprintf(stderr, " but should be run whenever you upgrade the ircd.\n");
|
||||
fprintf(stderr,
|
||||
" -p : pretend, checks for the configs, and parses them, then tells you some data...\n");
|
||||
fprintf(stderr, " but does not touch your database.\n");
|
||||
fprintf(stderr,
|
||||
" -v : Be verbose... and it *is* very verbose! (intended for debugging)\n");
|
||||
fprintf(stderr, " -d : Enable checking for redunant entries.\n");
|
||||
fprintf(stderr, " -w : Completly wipe your database clean. May be used with -i \n");
|
||||
fprintf(stderr, " -d : Enable checking for redundant entries.\n");
|
||||
fprintf(stderr, " -w : Completely wipe your database clean. May be used with -i \n");
|
||||
fprintf(stderr,
|
||||
" path : An optional directory containing old ratbox configs for import, or export.\n");
|
||||
fprintf(stderr, " If not specified, it looks in PREFIX/etc.\n");
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
/* $Id: rsdb.h 26164 2008-10-26 19:52:43Z androsyn $ */
|
||||
#ifndef INCLUDED_rsdb_h
|
||||
#define INCLUDED_rsdb_h
|
||||
|
||||
|
|
|
@ -5,8 +5,6 @@
|
|||
* Should you choose to use and/or modify this source code, please
|
||||
* do so under the terms of the GNU General Public License under which
|
||||
* this library is distributed.
|
||||
*
|
||||
* $Id: rsdb_snprintf.c 26094 2008-09-19 15:33:46Z androsyn $
|
||||
*/
|
||||
#include "stdinc.h"
|
||||
#include "rsdb.h"
|
||||
|
|
|
@ -27,8 +27,6 @@
|
|||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id: rsdb_sqlite3.c 26182 2008-11-11 02:52:41Z androsyn $
|
||||
*/
|
||||
#include "stdinc.h"
|
||||
#include "rsdb.h"
|
||||
|
@ -47,7 +45,7 @@ mlog(const char *errstr, ...)
|
|||
char buf[256];
|
||||
va_list ap;
|
||||
va_start(ap, errstr);
|
||||
rb_vsnprintf(buf, sizeof(buf), errstr, ap);
|
||||
vsnprintf(buf, sizeof(buf), errstr, ap);
|
||||
va_end(ap);
|
||||
error_cb(buf);
|
||||
}
|
||||
|
@ -73,14 +71,14 @@ rsdb_init(rsdb_error_cb * ecb)
|
|||
|
||||
if(sqlite3_open(dbpath, &rb_bandb) != SQLITE_OK)
|
||||
{
|
||||
rb_snprintf(errbuf, sizeof(errbuf), "Unable to open sqlite database: %s",
|
||||
snprintf(errbuf, sizeof(errbuf), "Unable to open sqlite database: %s",
|
||||
sqlite3_errmsg(rb_bandb));
|
||||
mlog(errbuf);
|
||||
return -1;
|
||||
}
|
||||
if(access(dbpath, W_OK))
|
||||
{
|
||||
rb_snprintf(errbuf, sizeof(errbuf), "Unable to open sqlite database for write: %s", strerror(errno));
|
||||
snprintf(errbuf, sizeof(errbuf), "Unable to open sqlite database for write: %s", strerror(errno));
|
||||
mlog(errbuf);
|
||||
return -1;
|
||||
}
|
||||
|
|
99274
bandb/sqlite3.c
99274
bandb/sqlite3.c
File diff suppressed because it is too large
Load diff
5638
bandb/sqlite3.h
5638
bandb/sqlite3.h
File diff suppressed because it is too large
Load diff
748
configure.ac
748
configure.ac
|
@ -1,176 +1,51 @@
|
|||
dnl $Id: configure.ac 3516 2007-06-10 16:14:03Z jilles $
|
||||
dnl Process this file with autoconf to produce a configure script.
|
||||
|
||||
dnl TODO: clean up all the OpenSSL and shared module checking stuff;
|
||||
dnl the most major changes have already been made and it looks like
|
||||
dnl said functions need to be just about as complex as they already are.
|
||||
|
||||
AC_PREREQ(2.57)
|
||||
AC_PREREQ(2.60)
|
||||
|
||||
dnl Sneaky way to get an Id tag into the configure script
|
||||
AC_COPYRIGHT([$Id: configure.ac 3516 2007-06-10 16:14:03Z jilles $])
|
||||
AC_INIT([solanum], [1.0-dev])
|
||||
|
||||
AC_LANG(C)
|
||||
AC_USE_SYSTEM_EXTENSIONS
|
||||
AC_GNU_SOURCE
|
||||
|
||||
AC_PROG_CC_C99
|
||||
|
||||
<<<<<<< .merge_file_E9kQwr
|
||||
AC_INIT([charybdis], [3.5.7])
|
||||
=======
|
||||
if test x"$ac_cv_prog_cc_c99" = "xno"; then
|
||||
AC_ERROR([solanum requires a C99 capable compiler])
|
||||
fi
|
||||
>>>>>>> .merge_file_knjbyY
|
||||
|
||||
AC_PREFIX_DEFAULT($HOME/ircd)
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
AC_CONFIG_HEADER(include/setup.h)
|
||||
|
||||
AC_PREFIX_DEFAULT($HOME/ircd)
|
||||
AC_CONFIG_SUBDIRS([librb])
|
||||
AC_CONFIG_AUX_DIR([libltdl/config])
|
||||
|
||||
AC_GNU_SOURCE
|
||||
AM_INIT_AUTOMAKE([subdir-objects])
|
||||
AM_SILENT_RULES([yes])
|
||||
AM_PROG_AR
|
||||
|
||||
OLD_CFLAGS="$CFLAGS"
|
||||
dnl Checks for programs.
|
||||
AC_PROG_CC
|
||||
AC_LANG(C)
|
||||
LT_INIT([dlopen disable-static])
|
||||
LT_CONFIG_LTDL_DIR([libltdl])
|
||||
LTDL_INIT
|
||||
|
||||
dnl Make sure autoconf doesn't interfere with cflags -jmallett
|
||||
CFLAGS="$OLD_CFLAGS"
|
||||
|
||||
AC_CONFIG_SUBDIRS(libratbox)
|
||||
|
||||
dnl Check for various compilers. -jmallett
|
||||
dnl But if $CC turns out to be gcc, sure as hell it's, well, gcc. -joshk
|
||||
|
||||
if test "$ac_cv_c_compiler_gnu" != yes; then
|
||||
|
||||
SGS=no
|
||||
AC_MSG_CHECKING($CC -version for TenDRA or MIPSpro)
|
||||
case `$CC -version 2>&1` in
|
||||
*TenDRA*)
|
||||
AC_MSG_RESULT([yes, TenDRA])
|
||||
IRC_CFLAGS=""
|
||||
CPPFLAGS="$CPPFLAGS -Ylonglong -Yansi -I/usr/include"
|
||||
SGS=yes
|
||||
TenDRA=yes
|
||||
;;
|
||||
*MIPSpro*)
|
||||
AC_MSG_RESULT([yes, MIPSpro])
|
||||
MIPSpro=yes
|
||||
SGS=yes
|
||||
;;
|
||||
*)
|
||||
AC_MSG_RESULT(no)
|
||||
TenDRA=no
|
||||
MIPSpro=no
|
||||
;;
|
||||
esac
|
||||
|
||||
AC_MSG_CHECKING([$CC -V for Sun Workshop, Forte, HPUX or Tru64 cc])
|
||||
case `$CC -V 2>&1` in
|
||||
*Sun*WorkShop* | *Forte*Developer*)
|
||||
AC_MSG_RESULT(Sun Workshop/Forte)
|
||||
IRC_CFLAGS="-fast -xinline=dlinkAdd,dlinkAddBefore,dlinkAddTail,dlinkDelete,dlink_list_length,dlink_node,dlinkMoveList,_MyMalloc,_MyRealloc,_MyFree,_DupString"
|
||||
SunWorkShop=yes
|
||||
SGS=yes
|
||||
;;
|
||||
*Tru64*)
|
||||
AC_MSG_RESULT(Tru64 cc)
|
||||
IRC_CFLAGS="-O2"
|
||||
CPPFLAGS="-I/usr/local/include"
|
||||
Tru=yes
|
||||
;;
|
||||
*HP*ANSI*)
|
||||
AC_MSG_RESULT(HPUX cc)
|
||||
HPUX=yes
|
||||
IRC_CFLAGS="+e"
|
||||
;;
|
||||
*)
|
||||
AC_MSG_RESULT(no)
|
||||
;;
|
||||
esac
|
||||
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING([uname -s for Solaris, AIX, HPUX or Darwin])
|
||||
OSNAME=`uname -s`
|
||||
case "$OSNAME" in
|
||||
HP-UX*)
|
||||
dnl only do this if we haven't already detected the newer one
|
||||
dnl and we're not already using gcc
|
||||
|
||||
if test "$HPUX" != yes -a "$ac_cv_c_compiler_gnu" = no; then
|
||||
AC_MSG_RESULT(assuming old HPUX with its own cc)
|
||||
IRC_CFLAGS="$IRC_CFLAGS +e"
|
||||
HPUX=yes
|
||||
else
|
||||
AC_MSG_RESULT(already using newer HPUX)
|
||||
fi
|
||||
;;
|
||||
SunOS*)
|
||||
AC_MSG_RESULT(SunOS or Solaris)
|
||||
AC_DEFINE(__EXTENSIONS__, 1, [This is needed to use strtok_r on Solaris.])
|
||||
SUN=yes
|
||||
;;
|
||||
AIX*)
|
||||
AC_MSG_RESULT(AIX - Sorry you poor bastard..really we are)
|
||||
IRC_CFLAGS="$IRC_CFLAGS -Wl,-brtl -Wl,-G"
|
||||
;;
|
||||
Darwin*)
|
||||
AC_MSG_RESULT(Darwin)
|
||||
AppleGCC=yes
|
||||
;;
|
||||
*)
|
||||
AC_MSG_RESULT(no)
|
||||
;;
|
||||
esac
|
||||
build_ltdl=$with_included_ltdl
|
||||
AM_CONDITIONAL([BUILD_LTDL], [test x"$build_ltdl" = x"yes"])
|
||||
|
||||
if test "$ac_cv_c_compiler_gnu" = yes; then
|
||||
IRC_CFLAGS="$IRC_CFLAGS -O0 -Wall -std=gnu99"
|
||||
IRC_CFLAGS="$IRC_CFLAGS -O0 -Wall"
|
||||
fi
|
||||
|
||||
dnl If we support -g, use it!
|
||||
if test "$ac_cv_prog_cc_g" = yes; then
|
||||
dnl Tru64 needs -g3 for -O2
|
||||
if test "$Tru" = yes; then
|
||||
IRC_CFLAGS="$IRC_CFLAGS -g3"
|
||||
else
|
||||
IRC_CFLAGS="$IRC_CFLAGS -g"
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl SVR4 SGS based on what we know about the compiler -jmallett
|
||||
AC_MSG_CHECKING(if $CC supports the SVR4 SGS interfaces)
|
||||
if test "$SGS" = "yes"; then
|
||||
AC_MSG_RESULT(yes)
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
|
||||
dnl We prefer gcc -MM because it's a lot less bloated
|
||||
AC_PATH_PROG(MKDEP, mkdep)
|
||||
AC_PATH_PROG(MAKEDEPEND, makedepend)
|
||||
|
||||
AC_MSG_CHECKING(how to generate dependency info)
|
||||
|
||||
STDOUT="> .depend"
|
||||
|
||||
if test "$ac_cv_c_compiler_gnu" = yes; then
|
||||
AC_MSG_RESULT(gcc -MM)
|
||||
MKDEP="$CC -MM"
|
||||
elif test ! -z "$MKDEP"; then
|
||||
AC_MSG_RESULT(mkdep)
|
||||
|
||||
dnl Tru64's mkdep is very loud
|
||||
if test -z "$Tru"; then
|
||||
STDOUT=""
|
||||
else
|
||||
STDOUT=" 2> /dev/null"
|
||||
fi
|
||||
elif test "$SunWorkShop" = yes; then
|
||||
AC_MSG_RESULT($CC -xM)
|
||||
MKDEP="$CC -xM"
|
||||
STDOUT="> .depend 2> /dev/null"
|
||||
elif test ! -z "$MAKEDEPEND"; then
|
||||
AC_MSG_RESULT(makedepend)
|
||||
MKDEP="$MAKEDEPEND -f-"
|
||||
else
|
||||
AC_MSG_RESULT([nothing suitable.. forget it!])
|
||||
MKDEP=":"
|
||||
fi
|
||||
|
||||
AC_SUBST(MKDEP)
|
||||
AC_SUBST(STDOUT)
|
||||
|
||||
dnl check for /dev/null so we can use it to hold evil fd's
|
||||
AC_MSG_CHECKING([for /dev/null])
|
||||
|
@ -191,7 +66,6 @@ fi
|
|||
|
||||
AC_ISC_POSIX
|
||||
AC_C_INLINE
|
||||
AC_PROG_GCC_TRADITIONAL
|
||||
AC_PROG_MAKE_SET
|
||||
AC_PROG_INSTALL
|
||||
AC_PATH_PROG(RM, rm)
|
||||
|
@ -233,7 +107,8 @@ AS_IF([test "x$enable_fhs_paths" = "xyes"],
|
|||
pkglibexecdir='${libexecdir}/${PACKAGE_TARNAME}'
|
||||
rundir=${rundir-'${prefix}/run'}
|
||||
pkgrundir='${rundir}/${PACKAGE_TARNAME}'
|
||||
pkglocalstatedir='${localstatedir}/${PACKAGE_TARNAME}'],
|
||||
pkglocalstatedir='${localstatedir}/${PACKAGE_TARNAME}'
|
||||
AC_DEFINE([ENABLE_FHS_PATHS], [1], [Uncomment if FHS pathnames are enabled])],
|
||||
[libexecdir='${bindir}'
|
||||
pkglibexecdir='${libexecdir}'
|
||||
rundir='${sysconfdir}'
|
||||
|
@ -250,8 +125,9 @@ AC_DEFINE_DIR([PKGLIBEXECDIR], [pkglibexecdir], [Directory where binaries the IR
|
|||
|
||||
dnl Checks for header files.
|
||||
AC_HEADER_STDC
|
||||
AC_HEADER_STDBOOL
|
||||
|
||||
AC_CHECK_HEADERS([crypt.h sys/resource.h sys/param.h errno.h sys/syslog.h stddef.h sys/wait.h wait.h sys/epoll.h sys/uio.h machine/endian.h])
|
||||
AC_CHECK_HEADERS([crypt.h sys/param.h sys/syslog.h sys/epoll.h machine/endian.h])
|
||||
|
||||
dnl Stuff that the memory manager (imalloc) depends on
|
||||
dnl ==================================================
|
||||
|
@ -277,15 +153,6 @@ if test x"$SUN" = xyes; then
|
|||
AC_SEARCH_LIBS(inet_ntoa, nsl,, [AC_MSG_ERROR([libnsl not found! Aborting.])])
|
||||
fi
|
||||
|
||||
AC_CHECK_TYPE(socklen_t, ,
|
||||
[AC_DEFINE([socklen_t], [unsigned int],
|
||||
[If we don't have a real socklen_t, unsigned int is good enough.])],
|
||||
[#include <sys/types.h>
|
||||
#include <sys/socket.h>])
|
||||
|
||||
AC_ARG_ENABLE(ipv6,
|
||||
AC_HELP_STRING([--enable-ipv6],[Enable IPv6 support]),[ipv6=$enableval],[ipv6=no])
|
||||
|
||||
AC_SEARCH_LIBS(crypt, [crypt descrypt],,)
|
||||
|
||||
CRYPT_LIB=$ac_cv_search_crypt
|
||||
|
@ -298,139 +165,21 @@ fi
|
|||
|
||||
AC_SUBST(CRYPT_LIB)
|
||||
|
||||
if test "$ac_cv_header_sys_wait_h" = yes -o "$ac_cv_header_wait_h" = yes; then
|
||||
VICONF=viconf
|
||||
dnl We need one of the above to build viconf. Just a sanity check,
|
||||
dnl we don't want to stop people from building the rest of ircd
|
||||
dnl just because they can't build viconf.
|
||||
else
|
||||
VICONF=""
|
||||
fi
|
||||
|
||||
AC_SUBST(VICONF)
|
||||
|
||||
dnl See whether we can include both string.h and strings.h.
|
||||
AC_CACHE_CHECK([whether string.h and strings.h may both be included],
|
||||
gcc_cv_header_string,
|
||||
[
|
||||
AC_COMPILE_IFELSE(
|
||||
[#include <string.h>
|
||||
#include <strings.h>],
|
||||
[gcc_cv_header_string=yes],
|
||||
[gcc_cv_header_string=no])
|
||||
])
|
||||
|
||||
if test "$gcc_cv_header_string" = "yes"; then
|
||||
AC_DEFINE(STRING_WITH_STRINGS, 1, [Define to 1 if string.h may be included along with strings.h])
|
||||
fi
|
||||
|
||||
AC_C_BIGENDIAN
|
||||
|
||||
dnl Check for stdarg.h - if we can't find it, halt configure
|
||||
AC_CHECK_HEADER(stdarg.h, , [AC_MSG_ERROR([** stdarg.h could not be found - charybdis will not compile without it **])])
|
||||
|
||||
dnl Checks for the existence of strlcat, strlcpy, basename...
|
||||
dnl This more reliable test only works with gcc though.
|
||||
|
||||
if test "$ac_cv_c_compiler_gnu" = yes; then
|
||||
|
||||
AC_MSG_CHECKING(for strlcpy)
|
||||
save_CFLAGS=$CFLAGS
|
||||
CFLAGS="$CFLAGS -Wimplicit -Werror"
|
||||
|
||||
AC_LINK_IFELSE(
|
||||
[AC_LANG_PROGRAM(
|
||||
[[#include <string.h>
|
||||
#include <stdlib.h>]],
|
||||
[[char *a = malloc(6);
|
||||
strlcpy(a, "hello", 6);]]
|
||||
)],
|
||||
[AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_STRLCPY, 1, [Define if strlcpy is available (most BSDs.)])],
|
||||
[AC_MSG_RESULT(no)]
|
||||
)
|
||||
|
||||
AC_MSG_CHECKING(for strlcat)
|
||||
AC_LINK_IFELSE(
|
||||
[AC_LANG_PROGRAM(
|
||||
[[#include <string.h>
|
||||
#include <stdlib.h>]],
|
||||
[[char *a = malloc(6);
|
||||
a[0] = '\0';
|
||||
strlcat(a, "hello", 6);]]
|
||||
)],
|
||||
[AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_STRLCAT, 1, [Define if strlcat is available (most BSDs.)])],
|
||||
[AC_MSG_RESULT(no)]
|
||||
)
|
||||
|
||||
CFLAGS=$save_CFLAGS
|
||||
|
||||
else
|
||||
|
||||
dnl Better than nothing. The more complicated test above probably fixes powerpc,
|
||||
dnl so who cares.
|
||||
|
||||
AC_CHECK_HEADER(stdarg.h, , [AC_MSG_ERROR([** stdarg.h could not be found - solanum will not compile without it **])])
|
||||
AC_CHECK_FUNCS([strlcat strlcpy])
|
||||
|
||||
fi
|
||||
|
||||
AC_CHECK_TYPE([u_int32_t], [],
|
||||
[
|
||||
AC_CHECK_TYPE([uint32_t],
|
||||
[
|
||||
AC_DEFINE(u_int32_t, [uint32_t], [If system does not define u_int32_t, define a reasonable substitute.])
|
||||
],
|
||||
[
|
||||
AC_MSG_WARN([system has no u_int32_t or uint32_t, default to unsigned long int])
|
||||
AC_DEFINE(u_int32_t, [unsigned long int], [If system does not define u_int32_t, define to unsigned long int here.])
|
||||
])
|
||||
])
|
||||
|
||||
AC_CHECK_TYPE([u_int16_t], [],
|
||||
[
|
||||
AC_CHECK_TYPE([uint16_t],
|
||||
[
|
||||
AC_DEFINE(u_int16_t, [uint16_t], [If system does not define u_int16_t, define a usable substitute])
|
||||
],
|
||||
[
|
||||
AC_MSG_WARN([system has no u_int16_t or uint16_t, default to unsigned short int])
|
||||
AC_DEFINE(u_int16_t, [unsigned short int], [If system does not define u_int16_t, define a usable substitute.])
|
||||
])
|
||||
])
|
||||
|
||||
AC_CHECK_TYPE([in_port_t], [],
|
||||
[AC_DEFINE(in_port_t, [u_int16_t], [If system does not define in_port_t, define it to what it should be.])],
|
||||
[[#include <sys/types.h>
|
||||
#include <netinet/in.h>]])
|
||||
|
||||
AC_CHECK_TYPE([sa_family_t], [],
|
||||
[AC_DEFINE(sa_family_t, [u_int16_t], [If system does not define sa_family_t, define it here.])],
|
||||
[[#include <sys/types.h>
|
||||
#include <sys/socket.h>]])
|
||||
AC_TYPE_INT16_T
|
||||
AC_TYPE_INT32_T
|
||||
|
||||
AC_CHECK_TYPES([uintptr_t])
|
||||
|
||||
dnl check for various functions...
|
||||
AC_CHECK_FUNCS([socketpair vsnprintf mmap gettimeofday strdup strndup ])
|
||||
|
||||
AC_FUNC_ALLOCA
|
||||
|
||||
dnl Specialized functions checks
|
||||
dnl ============================
|
||||
|
||||
dnl check for nanosleep
|
||||
AC_CHECK_FUNC(nanosleep,,[AC_CHECK_LIB(rt,nanosleep,
|
||||
LIBS="${LIBS} -lrt",
|
||||
[AC_CHECK_LIB(posix4,nanosleep, LIBS="${LIBS} -lposix4"
|
||||
)])])
|
||||
if test x$ac_cv_func_nanosleep = xno && test x$ac_cv_lib_posix4_nanosleep = xno && test x$ac_cv_lib_rt_nanosleep = xno
|
||||
then
|
||||
AC_MSG_RESULT("nanosleep not found..using select for delay")
|
||||
else
|
||||
AC_DEFINE([HAVE_NANOSLEEP], 1, [Define if nanosleep exists])
|
||||
fi
|
||||
|
||||
dnl OpenSSL support
|
||||
AC_MSG_CHECKING(for OpenSSL)
|
||||
AC_ARG_ENABLE(openssl,
|
||||
|
@ -501,11 +250,11 @@ if test "$cf_enable_openssl" != no; then
|
|||
dnl Check OpenSSL version (must be 0.9.6 or above!)
|
||||
AC_MSG_CHECKING(for OpenSSL 0.9.6 or above)
|
||||
AC_RUN_IFELSE(
|
||||
AC_LANG_PROGRAM(
|
||||
[AC_LANG_PROGRAM(
|
||||
[#include <openssl/opensslv.h>
|
||||
#include <stdlib.h>],
|
||||
[[if ( OPENSSL_VERSION_NUMBER >= 0x00906000)
|
||||
exit(0); else exit(1);]]),
|
||||
exit(0); else exit(1);]])],
|
||||
cf_openssl_version_ok=yes,
|
||||
cf_openssl_version_ok=no,
|
||||
cf_openssl_version_ok=no)
|
||||
|
@ -535,90 +284,53 @@ dnl End OpenSSL detection
|
|||
dnl Specialized functions and libraries
|
||||
dnl ===================================
|
||||
|
||||
AC_ARG_WITH(zlib-path,
|
||||
AC_HELP_STRING([--with-zlib-path=DIR],[Path to libz.so for ziplinks support.]),
|
||||
AC_ARG_ENABLE(hyperscan,
|
||||
AC_HELP_STRING([--disable-hyperscan],[Disable hyperscan support]),
|
||||
[hyperscan=$enableval],[hyperscan=yes])
|
||||
|
||||
AS_IF([test "$hyperscan" = yes], [
|
||||
save_CPPFLAGS="$CPPFLAGS"
|
||||
save_LIBS="$LIBS"
|
||||
PKG_CHECK_MODULES([HS], [libhs >= 4], [], [hyperscan=no])
|
||||
CPPFLAGS="$CPPFLAGS $HS_CFLAGS"
|
||||
LIBS="$LIBS $HS_LIBS"
|
||||
AC_CHECK_HEADER([hs_common.h], [], [hyperscan=no])
|
||||
AC_CHECK_FUNC([hs_scan], [], [hyperscan=no])
|
||||
])
|
||||
|
||||
AS_IF([test "$hyperscan" = no], [
|
||||
CPPFLAGS="$save_CPPFLAGS"
|
||||
LIBS="$save_LIBS"
|
||||
])
|
||||
|
||||
AM_CONDITIONAL([HAVE_HYPERSCAN], [test "$hyperscan" = "yes"])
|
||||
|
||||
|
||||
AC_ARG_WITH(sctp-path,
|
||||
AC_HELP_STRING([--with-sctp-path=DIR],[Path to libsctp.so for SCTP support.]),
|
||||
[LIBS="$LIBS -L$withval"],)
|
||||
|
||||
AC_ARG_ENABLE(zlib,
|
||||
AC_HELP_STRING([--disable-zlib],[Disable ziplinks support]),
|
||||
[zlib=$enableval],[zlib=yes])
|
||||
AC_ARG_ENABLE(sctp,
|
||||
AC_HELP_STRING([--disable-sctp],[Disable SCTP support]),
|
||||
[sctp=$enableval],[sctp=yes])
|
||||
|
||||
if test "$zlib" = yes; then
|
||||
if test "$sctp" = yes; then
|
||||
|
||||
AC_CHECK_HEADER(zlib.h, [
|
||||
AC_CHECK_LIB(z, zlibVersion,
|
||||
AC_CHECK_HEADER(netinet/sctp.h, [
|
||||
AC_SEARCH_LIBS(sctp_bindx, sctp,
|
||||
[
|
||||
AC_SUBST(ZLIB_LD, -lz)
|
||||
AC_DEFINE(HAVE_LIBZ, 1, [Define to 1 if zlib (-lz) is available.])
|
||||
], zlib=no)
|
||||
], zlib=no)
|
||||
AC_DEFINE(HAVE_LIBSCTP, 1, [Define to 1 if libsctp (-lsctp) is available.])
|
||||
], sctp=no)
|
||||
], sctp=no)
|
||||
|
||||
fi
|
||||
|
||||
dnl Check for shared sqlite
|
||||
dnl ======================
|
||||
AC_ARG_WITH(shared-sqlite,
|
||||
AC_HELP_STRING([--with-shared-sqlite],[Use shared sqlite]),
|
||||
[shared_sqlite=$withval],[shared_sqlite=no])
|
||||
|
||||
if test "$shared_sqlite" = yes; then
|
||||
PKG_CHECK_MODULES(SQLITE, [sqlite3],
|
||||
[
|
||||
shared_sqlite=yes
|
||||
], shared_sqlite=no)
|
||||
fi
|
||||
|
||||
if test "$shared_sqlite" = no; then
|
||||
SQLITE_SRC="sqlite3.c"
|
||||
fi
|
||||
PKG_CHECK_MODULES(SQLITE, [sqlite3], [], AC_ERROR([sqlite3 is required]))
|
||||
|
||||
AC_SUBST(SQLITE_LD, "$SQLITE_LIBS")
|
||||
AC_SUBST(SQLITE_INCLUDES, "$SQLITE_CFLAGS")
|
||||
AC_SUBST(SQLITE_SRC)
|
||||
|
||||
dnl IO Loop Selection
|
||||
dnl =================
|
||||
|
||||
AC_ARG_ENABLE(ports, AC_HELP_STRING([--enable-ports],[Force solaris I/O ports subsystem usage.]),
|
||||
[ if test $enableval = yes; then
|
||||
SELECT_TYPE_EXPLICIT="ports"
|
||||
else
|
||||
use_ports=no
|
||||
fi
|
||||
],)
|
||||
|
||||
AC_ARG_ENABLE(poll, AC_HELP_STRING([--enable-poll],[Force poll() usage.]),
|
||||
[ if test $enableval = yes; then
|
||||
SELECT_TYPE_EXPLICIT="poll"
|
||||
else
|
||||
use_poll=no
|
||||
fi
|
||||
],)
|
||||
|
||||
AC_ARG_ENABLE(select, AC_HELP_STRING([--enable-select],[Force select() usage.]),
|
||||
[ if test $enableval = yes; then
|
||||
SELECT_TYPE_EXPLICIT="select"
|
||||
else
|
||||
use_select=no
|
||||
fi
|
||||
],)
|
||||
|
||||
AC_ARG_ENABLE(kqueue, AC_HELP_STRING([--enable-kqueue],[Force kqueue() usage.]),
|
||||
[ if test $enableval = yes; then
|
||||
SELECT_TYPE_EXPLICIT="kqueue"
|
||||
else
|
||||
use_kqueue=no
|
||||
fi
|
||||
],)
|
||||
|
||||
AC_ARG_ENABLE(epoll, AC_HELP_STRING([--enable-epoll],[Force sys_epoll usage (Linux only).]),
|
||||
[ if test $enableval = yes; then
|
||||
SELECT_TYPE_EXPLICIT="epoll"
|
||||
AC_CHECK_FUNCS(epoll_ctl, [haveepoll=yes], [haveepoll=no])
|
||||
else
|
||||
use_epoll=no
|
||||
fi
|
||||
],)
|
||||
|
||||
dnl **********************************************************************
|
||||
dnl Check for --with-confdir [deprecated, use --sysconfdir instead]
|
||||
|
@ -768,114 +480,17 @@ if test "x$BRANDING_NAME" != "x$PACKAGE_NAME"; then
|
|||
AC_DEFINE(CUSTOM_BRANDING, 1, [Define if custom branding is enabled.])
|
||||
fi
|
||||
|
||||
if test ! -z "$SELECT_TYPE_EXPLICIT"; then
|
||||
SELECT_TYPE="$SELECT_TYPE_EXPLICIT";
|
||||
echo "Forcing $SELECT_TYPE to be enabled"
|
||||
else
|
||||
dnl **********************************************************************
|
||||
dnl Enable oper chghost
|
||||
dnl **********************************************************************
|
||||
|
||||
if test ! "x$use_ports" = "xno"; then
|
||||
AC_CHECK_FUNCS(port_getn, [haveports=yes], [haveports=no])
|
||||
if test "x$haveports" = "xyes" ; then
|
||||
SELECT_TYPE="ports"
|
||||
AC_ARG_ENABLE(oper-chghost,
|
||||
AC_HELP_STRING([--enable-oper-chghost],[Enable opers to use the CHGHOST command]),
|
||||
[operchghost=$enableval],[operchghost=no])
|
||||
|
||||
if test "$operchghost" = yes; then
|
||||
AC_DEFINE(ENABLE_OPER_CHGHOST, 1, [Define this to enable opers to use the CHGHOST command.])
|
||||
fi
|
||||
fi
|
||||
|
||||
if test ! "x$use_select" = "xno"; then
|
||||
AC_CHECK_FUNCS(select, [haveselect=yes], [haveselect=no])
|
||||
if test "x$haveselect" = "xyes" ; then
|
||||
SELECT_TYPE="select"
|
||||
fi
|
||||
fi
|
||||
|
||||
if test ! "x$use_poll" = "xno"; then
|
||||
AC_CHECK_FUNCS(poll, [havepoll=yes], [havepoll=no])
|
||||
if test "x$havepoll" = "xyes" ; then
|
||||
SELECT_TYPE="poll"
|
||||
fi
|
||||
fi
|
||||
|
||||
if test ! "x$use_kqueue" = "xno"; then
|
||||
AC_CHECK_FUNCS(kevent, [havekqueue=yes], [havekqueue=no])
|
||||
if test "x$havekqueue" = "xyes" ; then
|
||||
SELECT_TYPE="kqueue"
|
||||
fi
|
||||
fi
|
||||
|
||||
if test ! "x$use_epoll" = "xno"; then
|
||||
AC_CHECK_FUNCS(epoll_ctl, [haveepoll=yes], [haveepoll=no])
|
||||
if test "x$ac_cv_header_sys_epoll_h" = "xyes"; then
|
||||
if test "x$haveepoll" = "xyes" ; then
|
||||
AC_MSG_CHECKING(for epoll support in kernel)
|
||||
AC_TRY_RUN(
|
||||
#include <stdint.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/epoll.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int epfd;
|
||||
|
||||
epfd = epoll_create(256);
|
||||
return (epfd == -1 ? 1 : 0);
|
||||
}, [AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_EPOLL, 1,
|
||||
[Define if your system supports the epoll system calls])
|
||||
SELECT_TYPE="epoll"],
|
||||
AC_MSG_RESULT(no), AC_MSG_RESULT(no))
|
||||
fi
|
||||
fi
|
||||
|
||||
haveepollsyscall=no
|
||||
|
||||
if test "x$ac_cv_header_sys_epoll_h" = "xyes"; then
|
||||
if test "x$haveepoll" = "xno" ; then
|
||||
AC_MSG_CHECKING(for epoll system call)
|
||||
AC_TRY_RUN(
|
||||
#include <stdint.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/epoll.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int
|
||||
epoll_create(int size)
|
||||
{
|
||||
return (syscall(__NR_epoll_create, size));
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int epfd;
|
||||
|
||||
epfd = epoll_create(256);
|
||||
exit (epfd == -1 ? 1 : 0);
|
||||
}, [AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_EPOLL, 1,
|
||||
[Define if your system supports the epoll system calls])
|
||||
SELECT_TYPE="epoll"],
|
||||
AC_MSG_RESULT(no), AC_MSG_RESULT(no))
|
||||
fi
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
if test -z "$SELECT_TYPE"; then
|
||||
AC_MSG_ERROR([Unable to find a usable IO interface],)
|
||||
fi
|
||||
|
||||
echo "Using $SELECT_TYPE for select loop."
|
||||
|
||||
AC_DEFINE_UNQUOTED(SELECT_TYPE, "$SELECT_TYPE", [This is the type of IO loop we are using])
|
||||
AC_SUBST(SELECT_TYPE)
|
||||
|
||||
|
||||
dnl Debug-related options
|
||||
dnl =====================
|
||||
|
@ -890,22 +505,9 @@ elif test "$assert" = soft; then
|
|||
AC_DEFINE(SOFT_ASSERT, 1, [Define this to enable soft asserts.])
|
||||
AC_DEFINE(NDEBUG, 1, [Define this to disable debugging support.])
|
||||
elif test "$assert" = yes; then
|
||||
assert = "hard";
|
||||
assert="hard"
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING(if you want IO Debugging hooks)
|
||||
AC_ARG_ENABLE(iodebug,
|
||||
AC_HELP_STRING([--enable-iodebug],[Enable IO Debugging hooks]),
|
||||
[iodebug=$enableval], [iodebug=no])
|
||||
|
||||
if test "$iodebug" = yes; then
|
||||
AC_DEFINE(USE_IODEBUG_HOOKS, 1, [Define this to enable IO Debug hooks.])
|
||||
AC_MSG_RESULT(yes)
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
|
||||
|
||||
AC_MSG_CHECKING(if you want to do a profile build)
|
||||
AC_ARG_ENABLE(profile,
|
||||
AC_HELP_STRING([--enable-profile],[Enable profiling]),
|
||||
|
@ -915,7 +517,7 @@ if test "$profile" = yes; then
|
|||
if test "$ac_cv_c_compiler_gnu" = yes; then
|
||||
IRC_CFLAGS="$IRC_CFLAGS -pg"
|
||||
AC_MSG_RESULT([yes, adding -pg])
|
||||
AC_DEFINE(CHARYBDIS_PROFILE, 1, [Define this if you are profiling.])
|
||||
AC_DEFINE(SOLANUM_PROFILE, 1, [Define this if you are profiling.])
|
||||
else
|
||||
AC_MSG_RESULT([no, profile builds only work with gcc])
|
||||
fi
|
||||
|
@ -923,39 +525,6 @@ else
|
|||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(balloc,
|
||||
AC_HELP_STRING([--disable-balloc],[Disable the block allocator.]),
|
||||
[balloc=$enableval], [balloc=yes])
|
||||
|
||||
if test "$balloc" = no; then
|
||||
AC_DEFINE([NOBALLOC], 1, [Define to 1 if you wish to disable the block allocator.])
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(small-net,
|
||||
AC_HELP_STRING([--enable-small-net],[Enable small network support.]),
|
||||
[small_net=$enableval], [small_net=no])
|
||||
|
||||
if test "$small_net" = yes; then
|
||||
dnl AC_DEFINE([HASHSIZE], 4096, [Max number of buckets in hash tables.])
|
||||
AC_DEFINE([NICKNAMEHISTORYLENGTH], 1500, [Size of the WHOWAS array.])
|
||||
AC_DEFINE([CHANNEL_HEAP_SIZE], 256, [Size of the channel heap.])
|
||||
AC_DEFINE([BAN_HEAP_SIZE], 128, [Size of the ban heap.])
|
||||
AC_DEFINE([CLIENT_HEAP_SIZE], 256, [Size of the client heap.])
|
||||
AC_DEFINE([LCLIENT_HEAP_SIZE], 128, [Size of the local client heap.])
|
||||
AC_DEFINE([PCLIENT_HEAP_SIZE], 32, [Size of the pre-client heap.])
|
||||
AC_DEFINE([USER_HEAP_SIZE], 128, [Size of the user heap.])
|
||||
AC_DEFINE([DNODE_HEAP_SIZE], 256, [Size of the dlink_node heap.])
|
||||
AC_DEFINE([TOPIC_HEAP_SIZE], 256, [Size of the topic heap.])
|
||||
AC_DEFINE([LINEBUF_HEAP_SIZE], 128, [Size of the linebuf heap.])
|
||||
AC_DEFINE([MEMBER_HEAP_SIZE], 256, [Sizeof member heap.])
|
||||
AC_DEFINE([ND_HEAP_SIZE], 128, [Size of the nick delay heap.])
|
||||
AC_DEFINE([CONFITEM_HEAP_SIZE], 128, [Size of the confitem heap.])
|
||||
AC_DEFINE([MONITOR_HEAP_SIZE], 128, [Size of the monitor heap.])
|
||||
AC_DEFINE([FD_HEAP_SIZE], 128, [Size of fd heap.])
|
||||
AC_DEFINE([AWAY_HEAP_SIZE], 128, [Size of away heap.])
|
||||
else
|
||||
dnl These settings are for a large network like efnet..they will use lots of memory
|
||||
dnl so enable small net unless you really need this much support
|
||||
AC_DEFINE([NICKNAMEHISTORYLENGTH], 15000, [Size of the WHOWAS array.])
|
||||
AC_DEFINE([CHANNEL_HEAP_SIZE], 8192, [Size of the channel heap.])
|
||||
AC_DEFINE([BAN_HEAP_SIZE], 4096, [Size of the ban heap.])
|
||||
|
@ -972,7 +541,6 @@ dnl so enable small net unless you really need this much support
|
|||
AC_DEFINE([MONITOR_HEAP_SIZE], 1024, [Size of the monitor heap.])
|
||||
AC_DEFINE([FD_HEAP_SIZE], 1024, [Size of fd heap.])
|
||||
AC_DEFINE([AWAY_HEAP_SIZE], 512, [Size of away heap.])
|
||||
fi
|
||||
|
||||
AC_ARG_WITH(nicklen,
|
||||
AC_HELP_STRING([--with-nicklen=LENGTH],[Set the upper-bound nick length to LENGTH (default 31, max 50)]),
|
||||
|
@ -994,7 +562,7 @@ AC_HELP_STRING([--with-nicklen=LENGTH],[Set the upper-bound nick length to LENGT
|
|||
AC_ARG_WITH(topiclen,
|
||||
AC_HELP_STRING([--with-topiclen=NUMBER],[Set the max topic length to NUMBER (default 390, max 390)]),
|
||||
[
|
||||
if test $withval -ge 390; then
|
||||
if test $withval -gt 390; then
|
||||
TOPICLEN=390
|
||||
AC_MSG_WARN([TOPICLEN has a hard limit of 390. Setting TOPICLEN=390])
|
||||
else
|
||||
|
@ -1005,16 +573,8 @@ AC_HELP_STRING([--with-topiclen=NUMBER],[Set the max topic length to NUMBER (def
|
|||
AC_DEFINE_UNQUOTED(TOPICLEN, ${TOPICLEN}, [Maximum topic length (<=390)])
|
||||
AC_DEFINE_UNQUOTED(NICKLEN, (${NICKLEN}+1), [Nickname length])
|
||||
|
||||
shared_modules="yes"
|
||||
dnl Some first-stage sanity checks.
|
||||
if test "$shared_modules" = yes; then
|
||||
dnl TenDRA's cc is called tcc too.
|
||||
if test "$CC" = tcc -a "$TenDRA" = "no"; then
|
||||
AC_MSG_WARN([disabling shared modules: Tiny C Compiler can't create PIC])
|
||||
shared_modules="no"
|
||||
fi
|
||||
fi
|
||||
|
||||
<<<<<<< .merge_file_E9kQwr
|
||||
dnl Second stage: check for functions and headers.
|
||||
if test "$shared_modules" = yes; then
|
||||
DYNLINK_C=dynlink.c
|
||||
|
@ -1135,12 +695,20 @@ if test "$shared_modules" = yes; then
|
|||
fi
|
||||
fi
|
||||
fi
|
||||
=======
|
||||
AC_ARG_WITH(asan,
|
||||
AC_HELP_STRING([--with-asan],[Build with Address Sanitizer]),
|
||||
[
|
||||
CFLAGS="$CFLAGS -fsanitize=address"
|
||||
LDFLAGS="$LDFLAGS -fsanitize=address"
|
||||
])
|
||||
>>>>>>> .merge_file_knjbyY
|
||||
|
||||
# rpath, for finding libratbox.so at run time
|
||||
# rpath, for finding librb.so at run time
|
||||
hold_ldflags=$LDFLAGS
|
||||
AC_MSG_CHECKING(for the ld -rpath flag)
|
||||
LDFLAGS="${LDFLAGS} -Wl,-rpath=${libdir}"
|
||||
AC_LINK_IFELSE(AC_LANG_PROGRAM([],[int i;]), found=yes, found=no)
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([],[int i;])], found=yes, found=no)
|
||||
LDFLAGS=$hold_ldflags
|
||||
AC_MSG_RESULT($found)
|
||||
if test "$found" = yes; then
|
||||
|
@ -1157,99 +725,30 @@ AC_HELP_STRING([--enable-warnings],[Enable all sorts of warnings for debugging.]
|
|||
IRC_CFLAGS="$IRC_CFLAGS -O0"
|
||||
CFLAGS="$IRC_CFLAGS"
|
||||
|
||||
CHARYBDIS_C_GCC_TRY_FLAGS([-Wall], charybdis_cv_c_gcc_w_all)
|
||||
CHARYBDIS_C_GCC_TRY_FLAGS([-Wpointer-arith], charybdis_cv_c_gcc_w_pointer_arith)
|
||||
CHARYBDIS_C_GCC_TRY_FLAGS([-Wimplicit -Wnested-externs], charybdis_cv_c_gcc_w_implicit)
|
||||
CHARYBDIS_C_GCC_TRY_FLAGS([-Wcast-align], charybdis_cv_c_gcc_w_cast_align)
|
||||
CHARYBDIS_C_GCC_TRY_FLAGS([-Wcast-qual], charybdis_cv_c_gcc_w_cast_qual)
|
||||
CHARYBDIS_C_GCC_TRY_FLAGS([-Wwrite-strings], charybdis_cv_c_gcc_w_write_strings)
|
||||
CHARYBDIS_C_GCC_TRY_FLAGS([-Werror-implicit-function-declaration], charybdis_cv_c_gcc_w_error_implicit_function_declaration)
|
||||
CHARYBDIS_C_GCC_TRY_FLAGS([-Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations], charybdis_cv_c_gcc_prototypes)
|
||||
CHARYBDIS_C_GCC_TRY_FLAGS([-Wparenthesis], charybdis_cv_c_gcc_parenthesis)
|
||||
CHARYBDIS_C_GCC_TRY_FLAGS([-W -Wno-unused], charybdis_cv_c_gcc_w)
|
||||
CHARYBDIS_C_GCC_TRY_FLAGS([-Wextra], charybdis_cv_c_gcc_w_extra)
|
||||
CHARYBDIS_C_GCC_TRY_FLAGS([-Wshadow], charybdis_cv_c_gcc_w_shadow)
|
||||
CHARYBDIS_C_GCC_TRY_FLAGS([-Wmissing-noreturn], charybdis_cv_c_gcc_w_missing_noreturn)
|
||||
CHARYBDIS_C_GCC_TRY_FLAGS([-Wundef], charybdis_cv_c_gcc_w_undef)
|
||||
CHARYBDIS_C_GCC_TRY_FLAGS([-Wpacked], charybdis_cv_c_gcc_w_packed)
|
||||
CHARYBDIS_C_GCC_TRY_FLAGS([-Wnested-externs], charybdis_cv_c_gcc_w_nested_externs)
|
||||
CHARYBDIS_C_GCC_TRY_FLAGS([-Wunused-function -Wunused-label -Wunused-value -Wunused-variable], charybdis_cv_c_gcc_w_unused)
|
||||
CHARYBDIS_C_GCC_TRY_FLAGS([-Wredundant-decls], charybdis_cv_c_gcc_w_redundant_decls)
|
||||
CHARYBDIS_C_GCC_TRY_FLAGS([-Wfloat-equal], charybdis_cv_c_gcc_w_float_equal)
|
||||
CHARYBDIS_C_GCC_TRY_FLAGS([-Wformat -Wformat-y2k -Wno-format-security], charybdis_cv_c_gcc_w_format)
|
||||
SOLANUM_C_GCC_TRY_FLAGS([-Wall], solanum_cv_c_gcc_w_all)
|
||||
SOLANUM_C_GCC_TRY_FLAGS([-Wpointer-arith], solanum_cv_c_gcc_w_pointer_arith)
|
||||
SOLANUM_C_GCC_TRY_FLAGS([-Wimplicit -Wnested-externs], solanum_cv_c_gcc_w_implicit)
|
||||
SOLANUM_C_GCC_TRY_FLAGS([-Wcast-align], solanum_cv_c_gcc_w_cast_align)
|
||||
SOLANUM_C_GCC_TRY_FLAGS([-Wcast-qual], solanum_cv_c_gcc_w_cast_qual)
|
||||
SOLANUM_C_GCC_TRY_FLAGS([-Wwrite-strings], solanum_cv_c_gcc_w_write_strings)
|
||||
SOLANUM_C_GCC_TRY_FLAGS([-Werror-implicit-function-declaration], solanum_cv_c_gcc_w_error_implicit_function_declaration)
|
||||
SOLANUM_C_GCC_TRY_FLAGS([-Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations], solanum_cv_c_gcc_prototypes)
|
||||
SOLANUM_C_GCC_TRY_FLAGS([-Wparentheses], solanum_cv_c_gcc_parentheses)
|
||||
SOLANUM_C_GCC_TRY_FLAGS([-W -Wno-unused], solanum_cv_c_gcc_w)
|
||||
SOLANUM_C_GCC_TRY_FLAGS([-Wextra], solanum_cv_c_gcc_w_extra)
|
||||
SOLANUM_C_GCC_TRY_FLAGS([-Wshadow], solanum_cv_c_gcc_w_shadow)
|
||||
SOLANUM_C_GCC_TRY_FLAGS([-Wmissing-noreturn], solanum_cv_c_gcc_w_missing_noreturn)
|
||||
SOLANUM_C_GCC_TRY_FLAGS([-Wundef], solanum_cv_c_gcc_w_undef)
|
||||
SOLANUM_C_GCC_TRY_FLAGS([-Wpacked], solanum_cv_c_gcc_w_packed)
|
||||
SOLANUM_C_GCC_TRY_FLAGS([-Wnested-externs], solanum_cv_c_gcc_w_nested_externs)
|
||||
SOLANUM_C_GCC_TRY_FLAGS([-Wunused-function -Wunused-label -Wunused-value -Wunused-variable], solanum_cv_c_gcc_w_unused)
|
||||
SOLANUM_C_GCC_TRY_FLAGS([-Wredundant-decls], solanum_cv_c_gcc_w_redundant_decls)
|
||||
SOLANUM_C_GCC_TRY_FLAGS([-Wfloat-equal], solanum_cv_c_gcc_w_float_equal)
|
||||
SOLANUM_C_GCC_TRY_FLAGS([-Wformat -Wformat-y2k -Wno-format-security], solanum_cv_c_gcc_w_format)
|
||||
|
||||
IRC_CFLAGS="$CFLAGS"
|
||||
],[])
|
||||
|
||||
if test "$shared_modules" = no; then
|
||||
DYNLINK_C=""
|
||||
MOD_TARGET="libmodules.a"
|
||||
MODULES_LIBS="../modules/libmodules.a"
|
||||
SEDOBJ=""
|
||||
AC_DEFINE(STATIC_MODULES, 1, [Define to 1 if dynamic modules can't be used.])
|
||||
AC_MSG_WARN([shared module support has been disabled!])
|
||||
fi
|
||||
|
||||
dnl Stage 5 - underscores in front of symbol names.
|
||||
if test "$shared_modules" = yes; then
|
||||
|
||||
AC_CHECK_FUNC(nlist,,
|
||||
AC_CHECK_LIB(dl, nlist, nlist_lib="-ldl",
|
||||
AC_CHECK_LIB(elf, nlist, nlist_lib="-lelf",)
|
||||
)
|
||||
)
|
||||
|
||||
dnl We need to find out whether underscores are appended to symbol
|
||||
dnl names in executable files. First, though, we need to see
|
||||
dnl where nlist.h is hiding.
|
||||
AC_CHECK_HEADER(libelf/nlist.h, [ nlist_h="libelf/nlist.h" ], )
|
||||
AC_CHECK_HEADER(elf/nlist.h, [ nlist_h="elf/nlist.h" ], )
|
||||
AC_CHECK_HEADER(nlist.h, [ nlist_h="nlist.h" ], )
|
||||
if test x"$nlist_h" = "x"; then
|
||||
AC_DEFINE_UNQUOTED(SYMBOL_PREFIX, "", [String containing extra underscores prepended to symbols loaded from modules.])
|
||||
else
|
||||
AC_MSG_CHECKING(for extra underscores prepended to symbol names)
|
||||
AC_CACHE_VAL(symbol_underscores,
|
||||
[
|
||||
cat << EOF > conftest.c
|
||||
#include <$nlist_h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
void _modinit(void);
|
||||
int main(int argc, char *argv[[]]) {
|
||||
int i;
|
||||
struct nlist nl[[5]];
|
||||
|
||||
/* fill the names in this way, so it'll work almost everywhere */
|
||||
nl[[0]].n_name = "_modinit";
|
||||
nl[[1]].n_name = "__modinit";
|
||||
nl[[2]].n_name = "___modinit";
|
||||
nl[[3]].n_name = "____modinit";
|
||||
nl[[0]].n_value = nl[[1]].n_value = nl[[2]].n_value = nl[[3]].n_value = nl[[4]].n_name = NULL;
|
||||
|
||||
if(argc < 2 || (nlist(argv[[1]], nl)) == -1) exit(-1);
|
||||
for(i = 0; i < 4; i++) {
|
||||
if(nl[[i]].n_value != NULL)
|
||||
{
|
||||
int j;
|
||||
for(j = 0; j < i; j++)
|
||||
printf("_");
|
||||
exit(i);
|
||||
}
|
||||
}
|
||||
exit(-1);
|
||||
}
|
||||
void _modinit(void) { return; }
|
||||
EOF
|
||||
$CC $CPPFLAGS $IRC_CFLAGS -o conftest conftest.c $nlist_lib >/dev/null 2>&1
|
||||
symbol_underscores=`./conftest conftest`
|
||||
AC_MSG_RESULT($symbol_underscores)
|
||||
$RM -f conftest conftest.c
|
||||
])
|
||||
AC_DEFINE_UNQUOTED(SYMBOL_PREFIX, "${symbol_underscores}", [String containing extra underscores prepended to symbols loaded from modules.])
|
||||
fi
|
||||
fi
|
||||
|
||||
IRC_CFLAGS="$IRC_CFLAGS $CWARNS"
|
||||
|
||||
AC_SUBST(MODULES_LIBS)
|
||||
|
@ -1267,24 +766,22 @@ AC_SUBST(SEDOBJ)
|
|||
|
||||
if test "$prefix" = "NONE"; then
|
||||
AC_DEFINE_UNQUOTED(IRCD_PREFIX, "$ac_default_prefix", [Prefix where the ircd is installed.])
|
||||
|
||||
else
|
||||
|
||||
dnl Don't get bitten by Cygwin's stupidity if the user specified
|
||||
dnl a custom prefix with a trailing slash
|
||||
|
||||
dnl Strip trailing slashes to prevent a path of '//'
|
||||
prefix=`echo $prefix | sed 's/\/$//'`
|
||||
AC_DEFINE_UNQUOTED(IRCD_PREFIX, "$prefix", [Prefix where the ircd is installed.])
|
||||
|
||||
fi
|
||||
|
||||
AC_CONFIG_FILES( \
|
||||
Makefile \
|
||||
authd/Makefile \
|
||||
bandb/Makefile \
|
||||
ssld/Makefile \
|
||||
wsockd/Makefile \
|
||||
extensions/Makefile \
|
||||
src/Makefile \
|
||||
ircd/Makefile \
|
||||
modules/Makefile \
|
||||
tests/Makefile \
|
||||
tools/Makefile \
|
||||
tools/genssl \
|
||||
doc/Makefile \
|
||||
|
@ -1300,21 +797,12 @@ else
|
|||
openssl="no"
|
||||
fi
|
||||
|
||||
if test "$shared_modules" = yes; then
|
||||
modules=shared
|
||||
else
|
||||
modules=static
|
||||
fi
|
||||
|
||||
echo "
|
||||
Configuration of ${BRANDING_NAME}-${BRANDING_VERSION}:
|
||||
Install directory : $prefix
|
||||
|
||||
Ziplinks : $zlib
|
||||
OpenSSL : $openssl
|
||||
Socket Engine : $SELECT_TYPE
|
||||
Small network : $small_net
|
||||
Block allocator : $balloc
|
||||
SCTP : $sctp
|
||||
|
||||
Nickname length : $NICKLEN
|
||||
Topic length : $TOPICLEN
|
||||
|
|
316
doc/CIDR.txt
316
doc/CIDR.txt
|
@ -1,316 +0,0 @@
|
|||
$Id: CIDR.txt 6 2005-09-10 01:02:21Z nenolod $
|
||||
|
||||
CIDR Information
|
||||
----------------
|
||||
Presently, we all use IPv4. The format of IPv4 is the following:
|
||||
|
||||
A.B.C.D
|
||||
|
||||
Where letters 'A' through 'D' are 8-bit values. In English, this
|
||||
means each digit can have a value of 0 to 255. Example:
|
||||
|
||||
129.56.4.234
|
||||
|
||||
Digits are called octets. Oct meaning 8, hence 8-bit values. An
|
||||
octet cannot be greater than 255, and cannot be less than 0 (eg. a
|
||||
negative number).
|
||||
|
||||
CIDR stands for "classless inter domain routing", details covered
|
||||
in RFC's 1518 and 1519. It was introduced mainly due to waste within
|
||||
A and B classes space. The goal was to make it possible to use
|
||||
smaller nets than it would seem from (above) IP classes, for instance
|
||||
by dividing one B class into 256 "C like" classes. The other goal was
|
||||
to allow aggregation of routing information, so that routers could use
|
||||
one aggregated route (like 194.145.96.0/20) instead of
|
||||
advertising 16 C classes.
|
||||
|
||||
Class A are all these addresses which first bit is "0",
|
||||
bitmap: 0nnnnnnn.hhhhhhhh.hhhhhhhh.hhhhhhhh (n=net, h=host)
|
||||
IP range is 0.0.0.0 - 127.255.255.255
|
||||
|
||||
Class B are all these addresses which first two bits are "10",
|
||||
bitmap: 10nnnnnn.nnnnnnnn.hhhhhhhh.hhhhhhhh (n=net, h=host)
|
||||
IP range is 128.0.0.0 - 191.255.255.255
|
||||
|
||||
Class C are all these addresses which first three bits are "110",
|
||||
bitmap: 110nnnnn.nnnnnnnn.nnnnnnnn.hhhhhhhh (n=net, h=host)
|
||||
IP range is 192.0.0.0 - 223.255.255.255
|
||||
|
||||
Class D are all these addresses which first four bits are "1110",
|
||||
this is multicast class and net/host bitmap doesn't apply here
|
||||
IP range is 224.0.0.0 - 239.255.255.255
|
||||
I bet they will never IRC, unless someone creates multicast IRC :)
|
||||
|
||||
Class E are all these addresses which first five bits are "11110",
|
||||
this class is reserved for future use
|
||||
IP range is 240.0.0.0 - 247.255.255.255
|
||||
|
||||
So, here is how CIDR notation comes into play.
|
||||
|
||||
For those of you who have real basic exposure to how networks are
|
||||
set up, you should be aware of the term "netmask." Basically, this
|
||||
is a IPv4 value which specifies the "size" of a network. You can
|
||||
assume the word "size" means "range" if you want.
|
||||
|
||||
A chart describing the different classes in CIDR format and their
|
||||
wildcard equivalents would probably help at this point:
|
||||
|
||||
CIDR version dot notation (netmask) Wildcard equivalent
|
||||
-----------------------------------------------------------------
|
||||
A.0.0.0/8 A.0.0.0/255.0.0.0 A.*.*.* or A.*
|
||||
A.B.0.0/16 A.B.0.0/255.255.0.0 A.B.*.* or A.B.*
|
||||
A.B.C.0/24 A.B.C.0/255.255.255.0 A.B.C.* or A.B.C.*
|
||||
A.B.C.D/32 A.B.C.D/255.255.255.255 A.B.C.D
|
||||
|
||||
|
||||
The question on any newbies mind at this point is "So what do all
|
||||
of those values & numbers actually mean?"
|
||||
|
||||
Everything relating to computers is based on binary values (1s and
|
||||
zeros). Binary plays a *tremendous* role in CIDR notation. Let's
|
||||
break it down to the following table:
|
||||
|
||||
A B C D
|
||||
-------- -------- -------- --------
|
||||
/8 == 11111111 . 00000000 . 00000000 . 00000000 == 255.0.0.0
|
||||
/16 == 11111111 . 11111111 . 00000000 . 00000000 == 255.255.0.0
|
||||
/24 == 11111111 . 11111111 . 11111111 . 00000000 == 255.255.255.0
|
||||
/32 == 11111111 . 11111111 . 11111111 . 11111111 == 255.255.255.255
|
||||
|
||||
The above is basically a binary table for the most common netblock
|
||||
sizes. The "1"s you see above are the 8-bit values for each octet.
|
||||
If you split an 8-bit value into each of it's bits, you find the
|
||||
following:
|
||||
|
||||
00000000
|
||||
^^^^^^^^_ 1sts place (1)
|
||||
|||||||__ 2nds place (2)
|
||||
||||||___ 3rds place (4)
|
||||
|||||____ 4ths place (8)
|
||||
||||_____ 5ths place (16)
|
||||
|||______ 6ths place (32)
|
||||
||_______ 7ths place (64)
|
||||
|________ 8ths place (128)
|
||||
|
||||
Now, since computers consider zero a number, you pretty much have
|
||||
to subtract one (so-to-speak; this is not really how its done, but
|
||||
just assume it's -1 :-) ) from all the values possible. Some
|
||||
examples of decimal values in binary:
|
||||
|
||||
15 == 00001111 (from left to right: 8+4+2+1)
|
||||
16 == 00010000 (from left to right: 16)
|
||||
53 == 00110101 (from left to right: 32+16+4+1)
|
||||
79 == 01001111 (from left to right: 64+8+4+1)
|
||||
254 == 11111110 (from left to right: 128+64+32+16+8+4+2)
|
||||
|
||||
So, with 8 bits, the range (as I said before) is zero to 255.
|
||||
|
||||
If none of this is making sense to you at this point, you should
|
||||
back up and re-read all of the above. I realize it's a lot, but
|
||||
it'll do you some good to re-read it until you understand :-).
|
||||
|
||||
So, let's modify the original table a bit by providing CIDR info
|
||||
for /1 through /8:
|
||||
|
||||
A B C D
|
||||
-------- -------- -------- --------
|
||||
/1 == 10000000 . 00000000 . 00000000 . 00000000 == 128.0.0.0
|
||||
/2 == 11000000 . 00000000 . 00000000 . 00000000 == 192.0.0.0
|
||||
/3 == 11100000 . 00000000 . 00000000 . 00000000 == 224.0.0.0
|
||||
/4 == 11110000 . 00000000 . 00000000 . 00000000 == 240.0.0.0
|
||||
/5 == 11111000 . 00000000 . 00000000 . 00000000 == 248.0.0.0
|
||||
/6 == 11111100 . 00000000 . 00000000 . 00000000 == 252.0.0.0
|
||||
/7 == 11111110 . 00000000 . 00000000 . 00000000 == 254.0.0.0
|
||||
/8 == 11111111 . 00000000 . 00000000 . 00000000 == 255.0.0.0
|
||||
|
||||
At this point, all of this should making a lot of sense, and you
|
||||
should be able to see the precision that you can get by using CIDR
|
||||
at this point. If not, well, I guess the best way to put it would
|
||||
be that wildcards always assume /8, /16, or /24 (yes hello Piotr,
|
||||
we can argue this later: I am referring to IPs *ONLY*, not domains
|
||||
or FQDNs :-) ).
|
||||
|
||||
This table will provide a reference to all of the IPv4 CIDR values
|
||||
|
||||
cidr|netmask (dot notation)
|
||||
----+---------------------
|
||||
/1 | 128.0.0.0
|
||||
/2 | 192.0.0.0
|
||||
/3 | 224.0.0.0
|
||||
/4 | 240.0.0.0
|
||||
/5 | 248.0.0.0
|
||||
/6 | 252.0.0.0
|
||||
/7 | 254.0.0.0
|
||||
/8 | 255.0.0.0
|
||||
/9 | 255.128.0.0
|
||||
/10 | 255.192.0.0
|
||||
/11 | 255.224.0.0
|
||||
/12 | 255.240.0.0
|
||||
/13 | 255.248.0.0
|
||||
/14 | 255.252.0.0
|
||||
/15 | 255.254.0.0
|
||||
/16 | 255.255.0.0
|
||||
/17 | 255.255.128.0
|
||||
/18 | 255.255.192.0
|
||||
/19 | 255.255.224.0
|
||||
/20 | 255.255.240.0
|
||||
/21 | 255.255.248.0
|
||||
/22 | 255.255.252.0
|
||||
/23 | 255.255.254.0
|
||||
/24 | 255.255.255.0
|
||||
/25 | 255.255.255.128
|
||||
/26 | 255.255.255.192
|
||||
/27 | 255.255.255.224
|
||||
/28 | 255.255.255.240
|
||||
/29 | 255.255.255.248
|
||||
/30 | 255.255.255.252
|
||||
/31 | 255.255.255.254
|
||||
/32 | 255.255.255.255
|
||||
|
||||
So, let's take all of the information above, and apply it to a
|
||||
present-day situation on IRC.
|
||||
|
||||
Let's say you have a set of flooding clients who all show up from
|
||||
the following hosts. For lack-of a better example, I'll use a
|
||||
subnet here at Best:
|
||||
|
||||
nick1 (xyz@shell9.ba.best.com) [206.184.139.140]
|
||||
nick2 (abc@shell8.ba.best.com) [206.184.139.139]
|
||||
nick3 (foo@shell12.ba.best.com) [206.184.139.143]
|
||||
|
||||
Most people will assume the they were all in the same class C
|
||||
(206.184.139.0/24 or 206.184.139.*).
|
||||
|
||||
This, as a matter of fact, is not true. Now, the reason *I* know
|
||||
this is solely because I work on the network here; those IPs are
|
||||
not delegated to a class C, but two portions of a class C (128 IPs
|
||||
each). That means the class C is actually split into these two
|
||||
portions:
|
||||
|
||||
Netblock IP range
|
||||
-------- --------
|
||||
206.184.139.0/25 206.184.139.0 to 206.184.139.127
|
||||
206.184.139.128/25 206.184.139.128 to 206.184.139.255
|
||||
|
||||
For the record, 206.184.139.0 and 206.184.139.128 are both known as
|
||||
"network addresses" (not to be confused with "netblocks" or "Ethernet
|
||||
hardware addresses" or "MAC addresses"). Network addresses are
|
||||
*ALWAYS EVEN*.
|
||||
|
||||
206.184.139.127 and 206.184.139.255 are what are known as broadcast
|
||||
addresses. Broadcast addresses are *ALWAYS ODD*.
|
||||
|
||||
Now, the aforementioned list of clients are in the 2nd subnet shown
|
||||
above, not the first. The reason for this should be obvious.
|
||||
|
||||
The remaining question is, "Well that's nice, you know what the netblock
|
||||
is for Best. What about us? We don't know that!"
|
||||
|
||||
Believe it or not, you can find out the network block size by using
|
||||
whois -h WHOIS.ARIN.NET on the IP in question. ARIN keeps a list of
|
||||
all network blocks and who owns them -- quite useful, trust me. I
|
||||
think I use ARIN 5 or 6 times a day, especially when dealing with
|
||||
D-lines. Example:
|
||||
|
||||
$ whois -h whois.arin.net 206.184.139.140
|
||||
Best Internet Communications, Inc. (NETBLK-NBN-206-184-BEST)
|
||||
345 East Middlefield Road
|
||||
Mountain View, CA 94043
|
||||
|
||||
Netname: NBN-206-184-BEST
|
||||
Netblock: 206.184.0.0 - 206.184.255.255
|
||||
Maintainer: BEST
|
||||
|
||||
Does this mean you should D-line 206.184.0.0/16? Probably not.
|
||||
That's an entire class B-sized block, while you're only trying
|
||||
to deny access to a subnetted class C.
|
||||
|
||||
So then how do you get the *real* info? Well, truth is, you don't.
|
||||
You have to pretty much take a guess at what it is, if ARIN reports
|
||||
something that's overly vague. Best, for example, was assigned the
|
||||
above class B-sized block. We can subnet it however we want without
|
||||
reporting back to ARIN how we have it subnetted. We own the block,
|
||||
and that's all that matters (to ARIN).
|
||||
|
||||
Not all subnets are like this, however. Smaller subnets you may
|
||||
find partitioned and listed on ARIN; I've seen /29 blocks for DSL
|
||||
customers show up in ARIN before.
|
||||
|
||||
So, use ARIN any chance you get. The more precision the better!
|
||||
|
||||
Now, there is a small issue I want to address regarding use of CIDR
|
||||
notation. Let's say you D-line the following in CIDR format (hi
|
||||
sion ;-) ):
|
||||
|
||||
205.100.132.18/24
|
||||
|
||||
Entries like this really makes my blood boil, solely because it adds
|
||||
excessive confusion and is just basically pointless. If you
|
||||
examine the above, you'll see the /24 is specifying an entire
|
||||
class C -- so then what's the purpose of using .18 versus .0?
|
||||
|
||||
There IS no purpose. The netmask itself will mask out the .18 and
|
||||
continue to successfully use 205.100.132.0/24.
|
||||
|
||||
Doing things this way just adds confusion, especially on non-octet-
|
||||
aligned subnets (such as /8, /16, /24, or /32). Seeing that on a
|
||||
/27 or a /19 might make people go "wtf?"
|
||||
|
||||
I know for a fact this doc lacks a lot of necessary information,
|
||||
like how the actual netmask/CIDR value play a role in "masking out"
|
||||
the correct size, and what to do is WHOIS.ARIN.NET returns no
|
||||
netblock information but instead a few different company names with
|
||||
NIC handles. I'm sure you can figure this stuff out on your own,
|
||||
or just ask an administrator friend of yours who DOES know. A lot
|
||||
of us admins are BOFH types, but if you ask us the right questions,
|
||||
you'll benefit from the answer quite thoroughly.
|
||||
|
||||
Oh, I almost forgot. Most Linux systems use a different version of
|
||||
"whois" than FreeBSD does. The syntax for whois on Linux is
|
||||
"whois <INFO>@whois.arin.net", while under FreeBSD it is
|
||||
"whois -h whois.arin.net <INFO>" Debian uses yet another version
|
||||
of whois that is incompatible with the above syntax options.
|
||||
|
||||
Note that the FreeBSD whois client has shortcuts for the most commonly
|
||||
used whois servers. "whois -a <INFO>" is the shortcut for ARIN.
|
||||
|
||||
Also note that ARIN is not authoritative for all IP blocks on the
|
||||
Internet. Take for example 212.158.123.66. A whois query to ARIN
|
||||
will return the following information:
|
||||
|
||||
$ whois -h whois.arin.net 212.158.123.66
|
||||
European Regional Internet Registry/RIPE NCC (NET-RIPE-NCC-)
|
||||
These addresses have been further assigned to European users.
|
||||
Contact information can be found in the RIPE database, via the
|
||||
WHOIS and TELNET servers at whois.ripe.net, and at
|
||||
http://www.ripe.net/db/whois.html
|
||||
|
||||
Netname: RIPE-NCC-212
|
||||
Netblock: 212.0.0.0 - 212.255.255.255
|
||||
Maintainer: RIPE
|
||||
|
||||
This query tells us that it is a European IP block, and is further
|
||||
handled by RIPE's whois server. We must then query whois.ripe.net
|
||||
to get more information.
|
||||
|
||||
$ whois -h whois.ripe.net 212.158.123.66
|
||||
|
||||
% Rights restricted by copyright. See
|
||||
http://www.ripe.net/ripencc/pub-services/db/copyright.html
|
||||
|
||||
inetnum: 212.158.120.0 - 212.158.123.255
|
||||
netname: INSNET-P2P
|
||||
descr: Point to Point Links for for London Nodes
|
||||
country: GB
|
||||
--snip--
|
||||
|
||||
This tells us the actual IP block that the query was a part of.
|
||||
|
||||
Other whois servers that you may see blocks referred to are:
|
||||
whois.ripn.net for Russia, whois.apnic.net for Asia, Australia, and
|
||||
the Pacific, and whois.6bone.net for IPv6 blocks.
|
||||
|
||||
Contributed by Jeremy Chadwick <jdc@best.net>
|
||||
Piotr Kucharski <chopin@sgh.waw.pl>
|
||||
W. Campbell <wcampbel@botbay.net> and
|
||||
Ariel Biener <ariel@fireball.tau.ac.il>
|
|
@ -1,61 +0,0 @@
|
|||
$Id: Hybrid-team 54 2005-09-10 05:12:55Z nenolod $
|
||||
|
||||
The hybrid team is a group of ircd coders who were frustrated
|
||||
with the instability and all-out "dirtiness" of the EFnet ircd's
|
||||
available. "hybrid" is the name for the collective efforts of a group
|
||||
of people, all of us.
|
||||
|
||||
Anyone is welcome to contribute to this effort. You are encouraged
|
||||
to participate in the Hybrid mailing list. To subscribe to the
|
||||
Hybrid List, use this link:
|
||||
https://lists.ircd-hybrid.org/mailman/listinfo/hybrid
|
||||
|
||||
The core team as, of this major release:
|
||||
|
||||
adx, Piotr Nizynski <adx@irc7.pl>
|
||||
billy-jon, William Bierman III <bill@mu.org>
|
||||
cryogen, Stuart Walsh <stu@ipng.org.uk>
|
||||
Dianora, Diane Bruce <db@db.net>
|
||||
joshk, Joshua Kwan <joshk@triplehelix.org>
|
||||
kire, Erik Small <smalle@hawaii.edu>
|
||||
knight, Alan LeVee <alan.levee@prometheus-designs.net>
|
||||
metalrock, Jack Low <jclow@csupomona.edu>
|
||||
Michael, Michael Wobst <michael.wobst@gmail.com>
|
||||
Rodder, Jon Lusky <lusky@blown.net>
|
||||
Wohali, Joan Touzet <joant@ieee.org>
|
||||
|
||||
The following people have contributed blood, sweat, and/or code to
|
||||
recent releases of Hybrid, in nick alphabetical order:
|
||||
|
||||
A1kmm, Andrew Miller <a1kmm@mware.virtualave.net>
|
||||
AndroSyn, Aaron Sethman <androsyn@ratbox.org>
|
||||
bane, Dragan Dosen <bane@idolnet.org>
|
||||
bysin, Ben Kittridge <bkittridge@cfl.rr.com>
|
||||
cosine, Patrick Alken <wnder@uwns.underworld.net>
|
||||
David-T, David Taylor <davidt@yadt.co.uk>
|
||||
fl, Lee Hardy <lee@leeh.co.uk>
|
||||
Garion, Joost Vunderink <garion@efnet.nl>
|
||||
Habeeb, David Supuran <habeeb@cfl.rr.com>
|
||||
Hwy101, W. Campbell <wcampbel@botbay.net>
|
||||
jmallett, Juli Mallett <jmallett@FreeBSD.org>
|
||||
jv, Jakub Vlasek <jv@pilsedu.cz>
|
||||
k9, Jeremy Chadwick <ircd@jdc.parodius.com>
|
||||
kre, Dinko Korunic <kreator@fly.srk.fer.hr>
|
||||
madmax, Paul Lomax <madmax@efnet.org>
|
||||
nenolod, William Pitcock <nenolod@nenolod.net>
|
||||
Riedel, Dennis Vink, <riedel@chaotic.nl>
|
||||
scuzzy, David Todd <scuzzy@aniverse.net>
|
||||
spookey, David Colburn <spookey@spookey.org>
|
||||
TimeMr14C, Yusuf Iskenderoglu <uhc0@stud.uni-karlsruhe.de>
|
||||
toot, Toby Verrall <to7@antipope.fsnet.co.uk>
|
||||
vx0, Mark Miller <mark@oc768.net>
|
||||
wiz, Jason Dambrosio <jason@wiz.cx>
|
||||
Xride, Søren Straarup <xride@x12.dk>
|
||||
zb^3, Alfred Perlstein <alfred@freebsd.org>
|
||||
|
||||
Others are welcome. Always. And if we left anyone off the above list,
|
||||
be sure to let us know that too. Many others have contributed to
|
||||
previous versions of this ircd and its ancestors, too many to list
|
||||
here.
|
||||
|
||||
Send bug fixes/complaints/rotten tomatoes to bugs@ircd-hybrid.org.
|
36
doc/Makefile.am
Normal file
36
doc/Makefile.am
Normal file
|
@ -0,0 +1,36 @@
|
|||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
exec_suffix = @exec_suffix@
|
||||
bindir = @bindir@
|
||||
libexecdir = @libexecdir@
|
||||
sysconfdir = @sysconfdir@
|
||||
localstatedir = @localstatedir@
|
||||
|
||||
# Local to the etc Makefile
|
||||
|
||||
CONFS = ircd.conf.example reference.conf
|
||||
|
||||
install-mkdirs:
|
||||
-@if test ! -d $(DESTDIR)$(sysconfdir); then \
|
||||
echo "mkdir -p $(sysconfdir)"; \
|
||||
mkdir -p $(DESTDIR)$(sysconfdir); \
|
||||
fi
|
||||
|
||||
install: install-mkdirs
|
||||
@echo "ircd: installing example config files ($(CONFS))"
|
||||
@for i in $(CONFS); do \
|
||||
if test -f $(DESTDIR)$(sysconfdir)/$$i; then \
|
||||
$(MV) $(DESTDIR)$(sysconfdir)/$$i $(DESTDIR)$(sysconfdir)/$$i.old; \
|
||||
fi; \
|
||||
$(INSTALL_DATA) $$i $(DESTDIR)$(sysconfdir); \
|
||||
done
|
||||
|
||||
-@if test ! -f $(DESTDIR)$(sysconfdir)/ircd.motd; then \
|
||||
echo "ircd: installing motd file (ircd.motd)"; \
|
||||
$(INSTALL_DATA) ircd.motd $(DESTDIR)$(sysconfdir); \
|
||||
fi
|
||||
|
||||
-@if test -f $(DESTDIR)$(sysconfdir)/links.txt; then \
|
||||
$(RM) $(DESTDIR)$(sysconfdir)/links.txt; \
|
||||
fi
|
||||
|
|
@ -1,92 +0,0 @@
|
|||
# $Id: Makefile.in 3376 2007-04-03 11:37:39Z nenolod $
|
||||
CC = @CC@
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_BIN = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
INSTALL_SUID = @INSTALL_PROGRAM@ -o root -m 4755
|
||||
RM = @RM@
|
||||
LEX = @LEX@
|
||||
LEXLIB = @LEXLIB@
|
||||
CFLAGS = @IRC_CFLAGS@ -DIRCD_PREFIX=\"@prefix@\"
|
||||
LDFLAGS = @LDFLAGS@
|
||||
MKDEP = ${CC} -MM
|
||||
MV = @MV@
|
||||
RM = @RM@
|
||||
CP = @CP@
|
||||
TOUCH = @TOUCH@
|
||||
|
||||
PROGRAM_PREFIX = @PROGRAM_PREFIX@
|
||||
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
exec_suffix = @exec_suffix@
|
||||
bindir = @bindir@
|
||||
libexecdir = @libexecdir@
|
||||
sysconfdir = @sysconfdir@
|
||||
localstatedir = @localstatedir@
|
||||
# Change this later! -- adrian
|
||||
moduledir = @moduledir@
|
||||
automoduledir = @moduledir@/autoload
|
||||
|
||||
# Local to the etc Makefile
|
||||
mandir = @mandir@/man8
|
||||
MANPAGES = ircd.8
|
||||
|
||||
CONFS = ircd.conf.example reference.conf
|
||||
|
||||
SSL_LIBS = @SSL_LIBS@
|
||||
SSL_INCLUDES = @SSL_INCLUDES@
|
||||
|
||||
IRCDLIBS = @LIBS@ $(SSL_LIBS)
|
||||
|
||||
INCLUDES = -I../include $(SSL_INCLUDES)
|
||||
CPPFLAGS = ${INCLUDES} @CPPFLAGS@
|
||||
|
||||
all: build
|
||||
|
||||
install-mkdirs:
|
||||
-@if test ! -d $(DESTDIR)$(sysconfdir); then \
|
||||
echo "mkdir -p $(sysconfdir)"; \
|
||||
mkdir -p $(DESTDIR)$(sysconfdir); \
|
||||
fi
|
||||
|
||||
-@if test ! -d $(DESTDIR)$(mandir); then \
|
||||
echo "mkdir -p $(mandir)"; \
|
||||
mkdir -p $(DESTDIR)$(mandir); \
|
||||
fi
|
||||
|
||||
install: install-mkdirs build
|
||||
@echo "ircd: installing example config files ($(CONFS))"
|
||||
@for i in $(CONFS); do \
|
||||
if test -f $(DESTDIR)$(sysconfdir)/$$i; then \
|
||||
$(MV) $(DESTDIR)$(sysconfdir)/$$i $(DESTDIR)$(sysconfdir)/$$i.old; \
|
||||
fi; \
|
||||
$(INSTALL_DATA) $$i $(DESTDIR)$(sysconfdir); \
|
||||
done
|
||||
|
||||
-@if test ! -f $(DESTDIR)$(sysconfdir)/ircd.motd; then \
|
||||
echo "ircd: installing motd file (ircd.motd)"; \
|
||||
$(INSTALL_DATA) ircd.motd $(DESTDIR)$(sysconfdir); \
|
||||
fi
|
||||
|
||||
-@if test -f $(DESTDIR)$(sysconfdir)/links.txt; then \
|
||||
$(RM) $(DESTDIR)$(sysconfdir)/links.txt; \
|
||||
fi
|
||||
|
||||
@echo "ircd: installing manpage"
|
||||
@for i in $(MANPAGES); do \
|
||||
if test ! -f $(DESTDIR)$(mandir)/$(PROGRAM_PREFIX)$$i; then \
|
||||
$(INSTALL_DATA) $$i $(DESTDIR)$(mandir)/$(PROGRAM_PREFIX)$$i; \
|
||||
fi; \
|
||||
done
|
||||
|
||||
build:
|
||||
|
||||
clean:
|
||||
|
||||
depend:
|
||||
|
||||
lint:
|
||||
|
||||
distclean:
|
||||
${RM} -f Makefile
|
|
@ -1,17 +0,0 @@
|
|||
$Id: README.cidr_bans 6 2005-09-10 01:02:21Z nenolod $
|
||||
|
||||
|
||||
Basically what this patch does is allow for users to use cidr masks when
|
||||
setting bans, exceptions, and invite invex(modes beI respectively). This
|
||||
works for both IPv4 and IPv6 addresses.
|
||||
|
||||
I won't go into details of how cidr works here, but to use them, you could
|
||||
do something like:
|
||||
|
||||
/mode #foo +b *!*@10.0.0.0/8
|
||||
/mode #foo +e *!*@10.0.10.0/24
|
||||
|
||||
Aaron Sethman <androsyn@ratbox.org>
|
||||
August 06, 2002
|
||||
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
$Id: Ratbox-team 1640 2006-06-05 00:02:19Z jilles $
|
||||
|
||||
ircd-ratbox is an evolution where ircd-hybrid left off around version 7-rc1.
|
||||
Currently the ircd-ratbox team consists of the following developers:
|
||||
|
||||
AndroSyn, Aaron Sethman <androsyn -at- ratbox.org>
|
||||
anfl, Lee Hardy <lee -at- leeh.co.uk>
|
||||
|
||||
Special thanks for support, code and ideas to:
|
||||
|
||||
Hwy, W. Campbell <wcampbel -at- botbay.net>
|
||||
jilles, Jilles Tjoelker <jilles -at- stack.nl>
|
||||
larne, Edward Brocklesby <ejb -at- sdf.lonestar.org>
|
||||
|
||||
Of course our work is based on the work of many, many others over the past
|
||||
10 or so years since irc has existed, including the work done by the Hybrid
|
||||
team, our thanks goes to them.
|
||||
|
|
@ -1,272 +0,0 @@
|
|||
|
||||
The Tao of Internet Relay Chat
|
||||
Copyright (C) Ove Ruben R Olsen 1994
|
||||
Version of 940110
|
||||
Contributing masters: Master ScottM
|
||||
|
||||
-----
|
||||
Something is formed by the electrons, born in the silent cable. Shaping
|
||||
and growing and ungrowing. It is there yet not there. It is the source of
|
||||
Internet Relay Chat. I do not know the name, thus I will call it the Tao
|
||||
of Internet Relay Chat.
|
||||
|
||||
If the Tao is great, then the IRC is running ceaselessly. If the IRC is
|
||||
great then the server is running without ever stoping. If the server is
|
||||
great then the client will always be the server. The luser is then pleased
|
||||
and there is Chat in the world.
|
||||
|
||||
The Tao of IRC squits far away and connects on returning.
|
||||
|
||||
|
||||
-----
|
||||
The genetic potential of birth, a lot to know, yet unknown.
|
||||
|
||||
In the begining there was nothing.
|
||||
|
||||
Out of nothing the Tao gave birth to tolsun.oulu.fi. tolsun gave birth to
|
||||
OuluBox.
|
||||
|
||||
OuluBox gave birth to rmsg.
|
||||
|
||||
rmsg was not Tao, so MUT gave birth to IRC.
|
||||
|
||||
No one knows when IRC came into existance, the mighty master WiZ have it
|
||||
to be at the end of the eight month in the year of the Dragon.
|
||||
|
||||
|
||||
-----
|
||||
Each channel has its purpose, however humble. Each channel is the Yin and
|
||||
Yang of IRC. Each channels has it's place within the IRC.
|
||||
|
||||
In the beginning there was only channel 0, thus channel 0 is the soil of
|
||||
IRC.
|
||||
|
||||
Channel 1 to channel 10 then was open as the sea. Channel 11 to 999 was the
|
||||
trees and forests of IRC. Channels above 999 should not be mentioned, and
|
||||
channels below 0 were unborn and contained many secrets.
|
||||
|
||||
This was not the right Tao, so IRC gave birth to +channels.
|
||||
|
||||
+channels had the yin and yang. Mode does not.
|
||||
|
||||
This was not the right Tao still, so IRC gave birth to #channels.
|
||||
|
||||
#channels have the yin and yang.
|
||||
|
||||
Only channel 0 is the right path to Tao, but avoid speaking on channel 0.
|
||||
|
||||
|
||||
-----
|
||||
There was a great dispute among the Broom-Walkers of the Relay. Some of them
|
||||
wanted neither yin nor yang. Out of this Eris came into existance. Some of the
|
||||
Broom-Walkers then created Eris Free-net.
|
||||
|
||||
This was the right Tao.
|
||||
|
||||
Kind Gentle and Boring Net was another wrong path to the Tao of Internet Relay
|
||||
Chat.
|
||||
|
||||
Some time later there was a quantity of some lusers who wanted to be
|
||||
Broom-Walkers also. The Eris Free Broom-Walkers did not agree with them,
|
||||
thus a new IRC was born. This IRC is called the Undernet.
|
||||
|
||||
But this is not the right Tao, either.
|
||||
|
||||
|
||||
-----
|
||||
There will always be disputes among the Broom-Walkers of Internet Relay Chat.
|
||||
|
||||
This is the very nature of the IRC.
|
||||
|
||||
|
||||
-----
|
||||
Lusers that do not understand the Tao is always using the yang of Mode on
|
||||
their channels. Lusers that do understand the Tao are always using Ignore
|
||||
on their channels.
|
||||
|
||||
How could this not be so ?
|
||||
|
||||
|
||||
-----
|
||||
The wise sage luser is told about the Chat and uses it. The luser is told
|
||||
about the IRC and is looking for it. The flock are told about the Tao and
|
||||
make a fool of the IRC.
|
||||
|
||||
If there was no laughter, there would be no Tao.
|
||||
|
||||
|
||||
-----
|
||||
The master says:
|
||||
"Without the Tao of Internet Relay Chat, life becomes meaningless."
|
||||
|
||||
The Relay of the old time was mysterious and sacred. We can neither imagine
|
||||
its thoughts nor path; we are left but to describe.
|
||||
|
||||
|
||||
-----
|
||||
The sage luser must be aware like a frog crossing the highway.
|
||||
|
||||
|
||||
-----
|
||||
The great master Wumpus once dreamed that he was an automaton. When he awoke
|
||||
he exclaimed:
|
||||
"I don't know whether I am Wumpus dreaming that I am a client,
|
||||
or a client dreaming that I am Wumpus!"
|
||||
|
||||
So was the first Automata born.
|
||||
|
||||
The master Nap then said:
|
||||
"Any automata should not speak unless spoken to.
|
||||
Any automata shall only whisper when spoken to."
|
||||
|
||||
Thus replied the master Gnarfer:
|
||||
"The lusers shall keep in mind that a automata can be either good or
|
||||
bad. Create good automata, and the IRC will hail you and you will
|
||||
gain fame and fortune. Create bad automata and people will start to
|
||||
hate you, and finaly you will be /KILLed to ethernal damnation"
|
||||
|
||||
Many lusers have fallen into the clutches of ethernal damnation. They where
|
||||
not following the Tao.
|
||||
|
||||
|
||||
-----
|
||||
There once was a luser who went to #BotSex. Each day he saw the automatons.
|
||||
The luser decided that he also would have such a automata.
|
||||
He asked another luser for his automata. The other luser gave his automata
|
||||
away.
|
||||
|
||||
The luser was not within the Tao, so he just started the automata. The automata
|
||||
had only Yang inside so all the lusers files where deleted.
|
||||
|
||||
Some moons laither the same luser then had become a sage luser, and did create
|
||||
his automata from the very grounds with materials found inside the IRC.
|
||||
The luser was now within the Tao and his automata lived happily ever after.
|
||||
|
||||
|
||||
-----
|
||||
There once was a master who wrote automatons without the help of master Phone.
|
||||
A novice luser, seeking to imitate him, began with the help of master Phone.
|
||||
When the novice luser asked the master to evaluate his automata the master
|
||||
replied: "What is a working automata for the master is not for the luser.
|
||||
You must must BE the IRC before automating."
|
||||
|
||||
|
||||
-----
|
||||
Master BigCheese gave birth to master Troy; his duty clear. Master Troy gave
|
||||
birth to master Phone, for the Tao of Irc must be eternal and must flow as the
|
||||
ceaseless river of Time itself.
|
||||
|
||||
|
||||
-----
|
||||
Master Phone once said about the ircII client:
|
||||
"public_msg is for a message from someone NOT on the channel
|
||||
public_other is for a message on a channel that doesn't belong to
|
||||
a window. public is for a message on a channel that belongs to a
|
||||
window!"
|
||||
|
||||
Out of this raised the mighty chaos.
|
||||
|
||||
|
||||
-----
|
||||
The sage luser came to the master who wrote automata without the help of
|
||||
master Phone. The sage luser asked the master who wrote automata: "Which is
|
||||
easiest to make. A automata with the help of master Phone or an automata
|
||||
made with the help of a language ?"
|
||||
|
||||
The master who wrote automata then replied:
|
||||
"With the help of a language."
|
||||
|
||||
The sage luser was disapointed and exclaimed: "But, with master Phone you
|
||||
do not need to know anything about the soil of IRC. Is not that the easiet
|
||||
way ?"
|
||||
|
||||
"Not really" said the master who wrote automata, "when using master Phone
|
||||
you are closed inside a box. For sure, it is a great box for the lusers,
|
||||
but the master will need more power, thus a language is the only path to go.
|
||||
With the language the master will never have to limit himself. When using
|
||||
such a language the master will seek the best between the need and the
|
||||
availibility."
|
||||
|
||||
"I see", said the sage luser.
|
||||
|
||||
This is the essence of Tao of IRC automatas.
|
||||
|
||||
|
||||
-----
|
||||
A client should be light and be used for communication. The spirit of a good
|
||||
client is that it should be very convinient for the luser to use, but hard
|
||||
for the luser who want to create automata.
|
||||
There should never ever be too many functions or too few functions.
|
||||
|
||||
There should always be a ignore.
|
||||
|
||||
Without ignore the client is not within the Tao of Chating.
|
||||
|
||||
The client should always respond the luser with messages that will not
|
||||
astnonish him too much. The server likewise. If the server does not, then it
|
||||
is the clients job to explain what the server says.
|
||||
|
||||
A client which fails this, will be useless and cause confusion for the lusers.
|
||||
The only way to correct this is to use another client or to write a new one.
|
||||
|
||||
|
||||
-----
|
||||
A luser asked the masters on #IrcHelp: "My client does not work".
|
||||
The masters replied: "Upgrade your client".
|
||||
The luser then wondered why the master knew. The master then told him about
|
||||
the Protocol.
|
||||
|
||||
"Your client does not work beaucse it does not understand the server. Why
|
||||
should it always work ? Only a fool would expect such. But, clients are made
|
||||
by humans, and humans are not perfect. Only Tao is.
|
||||
|
||||
The IRC is solid. The IRC is floating, and will always be dynamic. Live with
|
||||
that or /quit."
|
||||
|
||||
|
||||
-----
|
||||
The luser came to the masters of #IrcHelp, asking about the Tao of IRC within
|
||||
the client.
|
||||
The masters then said that the Tao of IRC always lies inside the client
|
||||
regardless of how the client connects to the server.
|
||||
|
||||
"Is the Tao in irc ?" asked the luser.
|
||||
"It so is" replied the masters of #IrcHelp.
|
||||
"Is the Tao in the ircII, Kiwi, rxirc, vms, rockers and msa ?" asked the
|
||||
luser.
|
||||
"In all of them and in the TPC, irchat, zenirc, zircon X11-irc and even the
|
||||
dos irc has the Tao" said the master quietly.
|
||||
"Is the Tao in a telnet connection directly to the server ?"
|
||||
|
||||
The master then was quiet for a long time and said. "Please leave, such
|
||||
questions are not within the Tao of IRC".
|
||||
|
||||
|
||||
-----
|
||||
The master says: "Without the Protocol of TCP the messages will not travel.
|
||||
Without the client, the server is useless."
|
||||
|
||||
|
||||
-----
|
||||
There once was a luser who used the ircII client. "ircII can do anything I
|
||||
ever need for using IRC" said the emacs client user, "I have /ON's, I have
|
||||
assignments, I have aliasing. Why don't you use this instead of the huge
|
||||
emacs client, which also has a messy screen?"
|
||||
The emacs client user then replied by saying that "it is better to have a
|
||||
scripting language that is the client instead of have a client that has
|
||||
a scripting language." Upon hearing this, the ircII client luser fell silent.
|
||||
|
||||
|
||||
-----
|
||||
The master Wumpus said: "Time for you to leave. I did, now I'm happy."
|
||||
The master Gnarfer replied: "Use, but never overuse IRC, then you will also
|
||||
be happy within IRC"
|
||||
|
||||
|
||||
-----
|
||||
A luser came unto the masters of #EU-Opers and asked, "How can I be, yet not
|
||||
be, a user@host within the IRC?"
|
||||
The masters of #EU-Opers replied: "To be Tao is to be ones true self. To hide
|
||||
ones self is not Tao, and is not IRC, you have much to learn before you shall
|
||||
be at rest within the Flow of Irc. Please leave"
|
||||
|
129
doc/connecting-servers.rst
Normal file
129
doc/connecting-servers.rst
Normal file
|
@ -0,0 +1,129 @@
|
|||
Connecting servers
|
||||
==================
|
||||
|
||||
Servers can be connected together to improve redundancy, distribute bandwidth,
|
||||
lower latency, and connect network services.
|
||||
|
||||
This document is an introduction to connecting servers. It assumes you are
|
||||
already somewhat familiar with Solanum's configuration (if not, read
|
||||
:file:`ircd.conf.example`, and set up your own server by editing it
|
||||
and running Solanum).
|
||||
|
||||
Solanum uses the TS6 protocol, and can only be connected with other servers
|
||||
using this protocol. We recommend you only connect Solanum with other Solanum
|
||||
instances.
|
||||
|
||||
Unlike some other IRCd implementations, all connections are reciprocal in
|
||||
Solanum, which means a single configuration block is used for both incoming
|
||||
and outgoing connections.
|
||||
Additionally, the same ports are used for server and client connections.
|
||||
|
||||
Creating servers
|
||||
----------------
|
||||
|
||||
If you already have a server running, copy its configuration to a new machine,
|
||||
and edit ``serverinfo`` for the new server. In particular, you must change the
|
||||
``name`` and ``sid``, but keep the same ``network_name``.
|
||||
We recommend you keep both configurations in sync using some external
|
||||
configuration management systems, so server configurations do not drift apart
|
||||
over time, as you change them.
|
||||
|
||||
For each of the two servers, you must create a ``connect`` block to represent
|
||||
the connection with the other server. For example, if you have servers A and B
|
||||
respectively at a.example.org and b.example.org, use respectively::
|
||||
|
||||
serverinfo {
|
||||
name = "a.example.org";
|
||||
// ...
|
||||
};
|
||||
|
||||
connect "b.example.org" {
|
||||
host = "203.0.113.2";
|
||||
port = 6666;
|
||||
|
||||
send_password = "password";
|
||||
accept_password = "anotherpassword";
|
||||
|
||||
flags = topicburst, autoconn;
|
||||
|
||||
class = "server";
|
||||
};
|
||||
|
||||
and::
|
||||
|
||||
serverinfo {
|
||||
name = "b.example.org";
|
||||
// ...
|
||||
};
|
||||
|
||||
connect "a.example.org" {
|
||||
host = "203.0.113.1";
|
||||
port = 6666;
|
||||
|
||||
send_password = "anotherpassword";
|
||||
accept_password = "password";
|
||||
|
||||
flags = topicburst, autoconn;
|
||||
|
||||
class = "server";
|
||||
};
|
||||
|
||||
Note the reversed passwords.
|
||||
|
||||
The ports should be any of the ports defined in a ``listen {}`` block of the
|
||||
other server.
|
||||
|
||||
The ``autoconn`` flag indicates a server should automatically connect using
|
||||
this ``connect {}`` block. At least one of the two servers should have it,
|
||||
or the servers won't try to connect.
|
||||
|
||||
If you are connecting servers over an unencrypted link, you should use SSL/TLS
|
||||
for the connection; see :file:`reference.conf`.
|
||||
|
||||
|
||||
Connecting services
|
||||
-------------------
|
||||
|
||||
In addition to regular servers, you can also connect service packages such
|
||||
as atheme-services.
|
||||
|
||||
These services typically do not accept incoming connections, and connect to
|
||||
one of the existing servers of the network.
|
||||
|
||||
To allow connections from such a service server, you should create
|
||||
a new ``connect {}`` block for this package, on the server the services
|
||||
will connect to::
|
||||
|
||||
connect "services.example.org" {
|
||||
host = "localhost";
|
||||
port = 6666;
|
||||
|
||||
send_password = "password";
|
||||
accept_password = "anotherpassword";
|
||||
|
||||
flags = topicburst; // No autoconn, services don't accept incoming connections
|
||||
|
||||
class = "server";
|
||||
};
|
||||
|
||||
And create the appropriate config in your services' configuration so that
|
||||
they connect to your server on the configured port, and from the configured
|
||||
hostname.
|
||||
|
||||
For example, with atheme::
|
||||
|
||||
loadmodule "modules/protocol/solanum";
|
||||
|
||||
uplink "a.example.org" {
|
||||
host = "localhost";
|
||||
port = 6666;
|
||||
send_password = "anotherpassword";
|
||||
receive_password = "password"
|
||||
};
|
||||
|
||||
Finally, you must configure all servers in your network to recognize the
|
||||
services server::
|
||||
|
||||
service {
|
||||
name = "services.example.org";
|
||||
};
|
276
doc/credits-past.txt
Normal file
276
doc/credits-past.txt
Normal file
|
@ -0,0 +1,276 @@
|
|||
===============================================================================
|
||||
IRCD 2.8 CREDITS
|
||||
===============================================================================
|
||||
|
||||
/************************************************************************
|
||||
* IRC - Internet Relay Chat, doc/AUTHORS
|
||||
* Copyright (C) 1990
|
||||
*
|
||||
* AUTHORS FILE:
|
||||
* This file attempts to remember all contributors to the IRC
|
||||
* developement. Names can be only added this file, no name
|
||||
* should never be removed. This file must be included into all
|
||||
* distributions of IRC and derived works.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
IRC was conceived of and written by Jarkko Oikarinen <jto@tolsun.oulu.fi>.
|
||||
IRC was originally written in University of Oulu, Computing Center.
|
||||
Jan 1991 - IRC 2.6 jto@tolsun.oulu.fi
|
||||
- Multiple Channels and protocol changes
|
||||
|
||||
Contributions were made by a cast of dozens, including the following:
|
||||
|
||||
Markku Jarvinen <mta@tut.fi>: Emacs-like editing facility for the client
|
||||
|
||||
Kimmo Suominen <kim@kannel.lut.fi>: HP-UX port
|
||||
|
||||
Jeff Trim <jtrim@orion.cair.du.edu>: enhancements and advice
|
||||
|
||||
Vijay Subramaniam <vijay@lll-winken.llnl.gov>: advice and ruthless publicity
|
||||
|
||||
Karl Kleinpaste <karl@cis.ohio-state.edu>: user's manual
|
||||
|
||||
Greg Lindahl <gl8f@virginia.edu>: AUTOMATON code, the Wumpus GM automaton,
|
||||
myriad bug fixes
|
||||
|
||||
Bill Wisner <wisner@hayes.fai.alaska.edu>: numerous bug fixes and code
|
||||
enhancements
|
||||
|
||||
Tom Davis <conslt16@zeus.unl.edu> and Tim Russell <russell@zeus.unl.edu>:
|
||||
VMS modifications
|
||||
|
||||
Markku Savela <msa@tel4.tel.vtt.fi>: advice, support, and being the
|
||||
incentive to do some of our *own* coding. :)
|
||||
|
||||
Tom Hopkins <hoppie@buengf.bu.edu>: bug fixes, quarantine lines,
|
||||
consolidation of various patches.
|
||||
|
||||
Christopher Davis <ckd@cs.bu.edu>: EFnet/Anet gateway coding,
|
||||
many automata ;), documentation fixing.
|
||||
|
||||
Helen Rose <hrose@cs.bu.edu>: documentation updating, and fixing.
|
||||
|
||||
Tom Hinds <rocker@bucsf.bu.edu>: emacs client updating.
|
||||
|
||||
Tim Miller <cerebus@bu-pub.bu.edu>: various server and client-breaking
|
||||
features.
|
||||
|
||||
Darren Reed <avalon@coombs.anu.edu.au>: various bug fixes and enhancements.
|
||||
Introduced nickname and channelname hash tables into the server.
|
||||
|
||||
The version 2.2 release was coordinated by Mike Bolotski
|
||||
<mikeb@salmon.ee.ubc.ca>.
|
||||
|
||||
The version 2.4 release was coordinated by Markku Savela and
|
||||
Chelsea Ashley Dyerman
|
||||
|
||||
The version 2.5.2 release was coordinated by Christopher Davis, Helen Rose,
|
||||
and Tom Hopkins.
|
||||
|
||||
The versions 2.6.2, 2.7 and 2.8 releases were coordinated by Darren Reed.
|
||||
|
||||
Contributions for the 2.8 release from the following people:
|
||||
Matthew Green <phone@coombs.anu.edu.au>
|
||||
Chuck Kane <ckane@ece.uiuc.edu>
|
||||
Matt Lyle <matt@oc.com>
|
||||
Vesa Ruokonen <ruokonen@lut.fi>
|
||||
|
||||
Markku Savela <Markku.Savela@vtt.fi> / April 1990
|
||||
Fixed various bugs in 2.2PL1 release server (2.2msa.4) and changed
|
||||
sockets to use non-blocking mode (2.2msa.9). [I have absolutely
|
||||
nothing to do with clients :-]
|
||||
|
||||
Chelsea Ashley Dyerman <chelsea@earth.cchem.berkeley.edu> / April 1990
|
||||
Rewrote the Makefiles, restructuring of source tree. Added libIrcd.a to
|
||||
the Makefile macros, numerous reformatting of server text messages, and
|
||||
added mkversion.sh to keep track of compilation statistics. Numerous
|
||||
bug fixes and enhancements, and co-coordinator of the 2.4 release.
|
||||
|
||||
jarlek@ifi.uio.no added mail functions to irc.
|
||||
|
||||
Armin Gruner <gruner@informatik.tu-muenchen.de> / May, June 1990:
|
||||
* Patched KILL-line feature for ircd.conf, works now.
|
||||
Enhancement: Time intervals can be specified in passwd-field.
|
||||
Result: KILL-Line is only active during these intervals
|
||||
* Patched PRIVMSG handling, now OPER can specify masks for sending
|
||||
private messages, advantage: msg to all at a specified server or host.
|
||||
* Little tests on irc 2.5 alpha, fixed some little typos in client code.
|
||||
Change: common/debug.c has been moved to ircd/s_debug.c, and a
|
||||
irc/c_debug.c has been created, for the benefit that wrong server msg
|
||||
are displayed if client does not recognize them. (strange, if a server
|
||||
sends an 'unknown command', isn't it?)
|
||||
|
||||
Tom Hopkins <hoppie@buengf.bu.edu> / September, October 1990:
|
||||
* Patched msa's K lines for servers (Q lines).
|
||||
* Consolidated several patches, including Stealth's logging patch.
|
||||
* Fixed several minor bugs.
|
||||
* Has done lots of other stuff that I can't seem to remember, but he
|
||||
always works on code, so he has to have done alot more than three
|
||||
lines worth. :)
|
||||
|
||||
Thanks go to those persons not mentioned here who have added their advice,
|
||||
opinions, and code to IRC.
|
||||
|
||||
Various modifications, bugreports, cleanups and testing by:
|
||||
|
||||
Hugo Calendar <hugo@ucscb.ucsc.edu>
|
||||
Bo Adler <adler@csvax.cs.caltech.edu>
|
||||
Michael Sandrof <ms5n+@andrew.cmu.edu>
|
||||
Jon Solomon <jsol@cs.bu.edu>
|
||||
Jan Peterson <jlp@hamblin.math.byu.edu>
|
||||
Nathan Glasser <nathan@brokaw.lcs.mit.edu>
|
||||
Helen Rose <hrose@eff.org>
|
||||
Mike Pelletier <stealth@caen.engin.umich.edu>
|
||||
Basalat Ali Raja <gwydion@tavi.rice.edu>
|
||||
Eric P. Scott <eps@toaster.sfsu.edu>
|
||||
Dan Goodwin <fornax@wpi.wpi.edu>
|
||||
Noah Friedman <friedman@ai.mit.edu>
|
||||
|
||||
|
||||
===============================================================================
|
||||
IRCD-HYBRID CREDITS
|
||||
===============================================================================
|
||||
|
||||
The hybrid team is a group of ircd coders who were frustrated
|
||||
with the instability and all-out "dirtiness" of the EFnet ircd's
|
||||
available. "hybrid" is the name for the collective efforts of a group
|
||||
of people, all of us.
|
||||
|
||||
Anyone is welcome to contribute to this effort. You are encouraged
|
||||
to participate in the Hybrid mailing list. To subscribe to the
|
||||
Hybrid List, use this link:
|
||||
https://lists.ircd-hybrid.org/mailman/listinfo/hybrid
|
||||
|
||||
The core team as, of this major release:
|
||||
|
||||
adx, Piotr Nizynski <adx@irc7.pl>
|
||||
billy-jon, William Bierman III <bill@mu.org>
|
||||
cryogen, Stuart Walsh <stu@ipng.org.uk>
|
||||
Dianora, Diane Bruce <db@db.net>
|
||||
joshk, Joshua Kwan <joshk@triplehelix.org>
|
||||
kire, Erik Small <smalle@hawaii.edu>
|
||||
knight, Alan LeVee <alan.levee@prometheus-designs.net>
|
||||
metalrock, Jack Low <jclow@csupomona.edu>
|
||||
Michael, Michael Wobst <michael.wobst@gmail.com>
|
||||
Rodder, Jon Lusky <lusky@blown.net>
|
||||
Wohali, Joan Touzet <joant@ieee.org>
|
||||
|
||||
The following people have contributed blood, sweat, and/or code to
|
||||
recent releases of Hybrid, in nick alphabetical order:
|
||||
|
||||
A1kmm, Andrew Miller <a1kmm@mware.virtualave.net>
|
||||
AndroSyn, Aaron Sethman <androsyn@ratbox.org>
|
||||
Ariadne, Ariadne Conill <ariadne@dereferenced.org>
|
||||
bane, Dragan Dosen <bane@idolnet.org>
|
||||
bysin, Ben Kittridge <bkittridge@cfl.rr.com>
|
||||
cosine, Patrick Alken <wnder@uwns.underworld.net>
|
||||
David-T, David Taylor <davidt@yadt.co.uk>
|
||||
fl, Lee Hardy <lee@leeh.co.uk>
|
||||
Garion, Joost Vunderink <garion@efnet.nl>
|
||||
Habeeb, David Supuran <habeeb@cfl.rr.com>
|
||||
Hwy101, W. Campbell <wcampbel@botbay.net>
|
||||
jmallett, Juli Mallett <jmallett@FreeBSD.org>
|
||||
jv, Jakub Vlasek <jv@pilsedu.cz>
|
||||
k9, Jeremy Chadwick <ircd@jdc.parodius.com>
|
||||
kre, Dinko Korunic <kreator@fly.srk.fer.hr>
|
||||
madmax, Paul Lomax <madmax@efnet.org>
|
||||
Riedel, Dennis Vink, <riedel@chaotic.nl>
|
||||
scuzzy, David Todd <scuzzy@aniverse.net>
|
||||
spookey, David Colburn <spookey@spookey.org>
|
||||
TimeMr14C, Yusuf Iskenderoglu <uhc0@stud.uni-karlsruhe.de>
|
||||
toot, Toby Verrall <to7@antipope.fsnet.co.uk>
|
||||
vx0, Mark Miller <mark@oc768.net>
|
||||
wiz, Jason Dambrosio <jason@wiz.cx>
|
||||
Xride, Søren Straarup <xride@x12.dk>
|
||||
zb^3, Alfred Perlstein <alfred@freebsd.org>
|
||||
|
||||
Others are welcome. Always. And if we left anyone off the above list,
|
||||
be sure to let us know that too. Many others have contributed to
|
||||
previous versions of this ircd and its ancestors, too many to list
|
||||
here.
|
||||
|
||||
Send bug fixes/complaints/rotten tomatoes to bugs@ircd-hybrid.org.
|
||||
|
||||
|
||||
===============================================================================
|
||||
IRCD-RATBOX CREDITS
|
||||
===============================================================================
|
||||
|
||||
ircd-ratbox is an evolution where ircd-hybrid left off around version 7-rc1.
|
||||
Currently the ircd-ratbox team consists of the following developers:
|
||||
|
||||
AndroSyn, Aaron Sethman <androsyn -at- ratbox.org>
|
||||
anfl, Lee Hardy <lee -at- leeh.co.uk>
|
||||
|
||||
Special thanks for support, code and ideas to:
|
||||
|
||||
Hwy, W. Campbell <wcampbel -at- botbay.net>
|
||||
jilles, Jilles Tjoelker <jilles -at- stack.nl>
|
||||
larne, Edward Brocklesby <ejb -at- sdf.lonestar.org>
|
||||
|
||||
Of course our work is based on the work of many, many others over the past
|
||||
10 or so years since irc has existed, including the work done by the Hybrid
|
||||
team, our thanks goes to them.
|
||||
|
||||
|
||||
===============================================================================
|
||||
CHARYBDIS CREDITS
|
||||
===============================================================================
|
||||
|
||||
Charybdis started as an evolution from ircd-ratbox. Its development
|
||||
is led by a team of dedicated developers who have put a lot of time
|
||||
into the project and it has seen use on a variety of different
|
||||
network configurations.
|
||||
|
||||
The Charybdis core team, listed in nick-alphabetical order:
|
||||
|
||||
amdj, Aaron Jones <aaronmdjones -at- gmail.com>
|
||||
Ariadne, Ariadne Conill <ariadne -at- dereferenced.org>
|
||||
Elizafox, Elizabeth Myers <elizabeth -at- interlinked.me>
|
||||
jilles, Jilles Tjoelker <jilles -at- stack.nl>
|
||||
mr_flea, Keith Buck <mr_flea -at- esper.net>
|
||||
|
||||
The following people are also project members, listed in nick-alphabetical
|
||||
order:
|
||||
|
||||
jdhore, JD Horelick <jdhore1 -at- gmail.com>
|
||||
viatsko, Valerii Iatsko <dwr -at- codingbox.io>
|
||||
|
||||
The following people have made contributions to the Charybdis releases,
|
||||
in nick-alphabetical order:
|
||||
|
||||
AndroSyn, Aaron Sethman <androsyn -at- ratbox.org>
|
||||
anfl, Lee Hardy <lee -at- leeh.co.uk>
|
||||
beu, Elfyn McBratney <elfyn.mcbratney -at- gmail.com>
|
||||
BlindSight, Matt Ullman <matt -at- airraidsirens.com>
|
||||
Entrope, Michael Poole <mdpoole -at- trolius.org>
|
||||
grawity, Mantas Mikulėnas <grawity -at- gmail.com>
|
||||
gxti, Michael Tharp <gxti -at- partiallystapled.com>
|
||||
mniip <mniip -at- mniip.com>
|
||||
Simon, Simon Arlott
|
||||
spb, Stephen Bennett <spb -at- attenuate.org>
|
||||
Taros, Brett Greenham <taros -at- shadowircd.net>
|
||||
ThaPrince, Jon Christopherson <jon -at- vile.com>
|
||||
twincest, River Tarnell <river -at- attenuate.org>
|
||||
w00t, Robin Burchell <surreal.w00t -at- gmail.com>
|
||||
|
||||
For a list of contributors to ircd-ratbox, ircd-hybrid, and ircd2.8 (the
|
||||
predecessors to Charybdis), see the doc/credits-past.txt file in the Charybdis
|
||||
distribution.
|
||||
|
||||
Visit the Charybdis website at: http://www.charybdis.io/
|
||||
Visit us on IRC at: irc.charybdis.io #charybdis
|
|
@ -1,7 +1,7 @@
|
|||
account-notify client capability specification
|
||||
----------------------------------------------
|
||||
|
||||
Copyright (c) 2010 William Pitcock <nenolod@atheme.org>.
|
||||
Copyright (c) 2010 Ariadne Conill <ariadne@dereferenced.org>.
|
||||
|
||||
Unlimited redistribution and modification of this document is allowed
|
||||
provided that the above copyright notice and this permission notice
|
|
@ -51,9 +51,6 @@ If aes256 is not available, the following is used instead:
|
|||
|
||||
- Building ratbox-respond -
|
||||
---------------------------
|
||||
If you are using the unix based ratbox-respond this must be built. For the
|
||||
windows version, ratbox-winrespond, please see http://respond.ircd-ratbox.org
|
||||
|
||||
ratbox-respond takes the challenge from the server, and together with your
|
||||
private key file generates a response to be sent back. ratbox-respond
|
||||
requires the openssl headers (ie, development files) and openssl libraries
|
||||
|
@ -82,5 +79,3 @@ ratbox-respond/README for more information.
|
|||
A number of scripts for clients have already been written to automate this
|
||||
process, see client-scripts/README for more information.
|
||||
|
||||
--
|
||||
$Id: challenge.txt 678 2006-02-03 20:25:01Z jilles $
|
|
@ -43,5 +43,3 @@ the same on all servers for each nick-user pair, also if a user with a UID
|
|||
nick changes their nick but is collided again (the server detecting the
|
||||
collision will not propagate the nick change further).
|
||||
|
||||
--
|
||||
$Id: collision_fnc.txt 3422 2007-04-22 14:35:28Z jilles $
|
|
@ -42,6 +42,10 @@ exists and is not +s or +p. (The ops of the channel the ban is on cannot
|
|||
necessarily see whether the user is in the target channel, so it should not
|
||||
influence whether they can join either.)
|
||||
|
||||
extb_canjoin.so
|
||||
$j:<channel>
|
||||
matches users who are or are not banned from a specified channel
|
||||
|
||||
extb_oper.so
|
||||
$o
|
||||
matches opers (most useful with +I)
|
||||
|
@ -56,6 +60,14 @@ extb_server.so
|
|||
matches users connected to a server matching the mask (* and ? wildcards);
|
||||
this can only be used with +b and +q
|
||||
|
||||
extb_extgecos.so
|
||||
$x:<mask>
|
||||
bans all users with matching nick!user@host#gecos
|
||||
|
||||
extb_ssl.so
|
||||
$z
|
||||
matches all SSL users
|
||||
|
||||
Comparisons:
|
||||
|
||||
+b $~a is similar to +r but also prevents not logged in users talking or
|
||||
|
@ -88,5 +100,3 @@ The function is called whenever a (local) client needs to be checked against
|
|||
a +bqeI entry of the given extban type, and whenever a local client tries to
|
||||
add such an entry. (Clients are allowed to add bans matching themselves.)
|
||||
|
||||
--
|
||||
$Id: extban.txt 1639 2006-06-04 23:26:47Z jilles $
|
59
doc/features/filter.txt
Normal file
59
doc/features/filter.txt
Normal file
|
@ -0,0 +1,59 @@
|
|||
extensions/filter module documentation
|
||||
--------------------------------------
|
||||
|
||||
The filter extension implements message content filtering using
|
||||
solanum's hook framework and Intel's Hyperscan regular expression
|
||||
matching library.
|
||||
|
||||
It requires an x86_64 processor with SSSE3 extensions.
|
||||
|
||||
To operate, the filter requires a database of regular expessions
|
||||
that have been compiled using the Hyperscan library's
|
||||
hs_compile_multi() or hs_compile_ext_multi() functions.
|
||||
|
||||
The command SETFILTER is used to manage operation of the filter and to
|
||||
load compiled Hyperscan databases.
|
||||
|
||||
General documenation of SETFILTER is available using the 'HELP SETFILTER'
|
||||
command.
|
||||
|
||||
For each expression in the database, the three least significant bits
|
||||
of the expression ID are used to indicate which action the ircd should
|
||||
take in the event of a match:
|
||||
|
||||
001 (1) DROP - The message will be dropped and the client will be sent
|
||||
an ERR_CANNOTSENDTOCHAN message.
|
||||
010 (2) KILL - The connection from which the message was recevied will
|
||||
be closed.
|
||||
100 (4) ALARM - A Server Notice will be generated indicating that an
|
||||
expression was matched. The nick, user, hostname and
|
||||
IP address will be reported. For privacy, the expression
|
||||
that has been matched will not be disclosed.
|
||||
|
||||
Messages are passed to the filter module in a format similar to an
|
||||
IRC messages:
|
||||
|
||||
0:nick!user@host#1 PRIVMSG #help :hello!
|
||||
|
||||
The number at the start of the line indicates the scanning pass:
|
||||
Messages are scanned twice, once as they were received (0), and once
|
||||
with any formatting or unprintable characters stripped (1).
|
||||
|
||||
By default, 'nick', 'user' and 'host' will contain *. This behaviour
|
||||
can be changed at build time if filtering on these fields is required.
|
||||
|
||||
The number after the # will be 0 or 1 depending on whether the sending
|
||||
client was identified to a NickServ account.
|
||||
|
||||
The process for loading filters is as follows:
|
||||
|
||||
1. The Hyperscan database is serialized using hs_serialize_database().
|
||||
2. A 'SETFILTER NEW' command is sent.
|
||||
3. The serialized data is split into chunks and base64 encoded.
|
||||
The chunk size needs to be chosen to ensure that the resuliting
|
||||
strings are short enough to fit into a 510 byte IRC line, taking
|
||||
into account space needed for the 'SETFILTER +' command, check field,
|
||||
server mask, and base64 overhead.
|
||||
4. The encoded chunks are sent using 'SETFILTER +' commands
|
||||
5. Once the entire database has been sent, a 'SETFILTER APPLY' command
|
||||
is sent to commit it.
|
15
doc/features/index.txt
Normal file
15
doc/features/index.txt
Normal file
|
@ -0,0 +1,15 @@
|
|||
Here is an overview of the docs in the doc/features directory.
|
||||
|
||||
account-notify.txt - Description of the account-notify system
|
||||
away-notify.txt - Description of the away-notify system
|
||||
challenge.txt - Overview of the challenge/response system for
|
||||
obtaining operator status
|
||||
collision_fnc.txt - Overview of the SAVE nick collision method
|
||||
extban.txt - Description of extended bans
|
||||
extended-join.txt - Description of the extended-join system
|
||||
modeg.txt - Description of UMODE +g, the caller ID system
|
||||
monitor.txt - Description of the MONITOR system
|
||||
sasl.txt - Description of the SASL services authentication
|
||||
system
|
||||
services.txt - Overview of features added by services
|
||||
tgchange.txt - Overview of the target change system
|
|
@ -78,7 +78,7 @@ Note that some clients may have to use /quote ACCEPT instead of /accept.
|
|||
--
|
||||
|
||||
Client Hwy101: /msg Hwy-LL hi
|
||||
Hwy101 will see: -!- Hwy-LL is in +g mode (server-side ignore.)
|
||||
Hwy101 will see: -!- Hwy-LL is in +g mode and must manually allow you to message them.
|
||||
-!- Hwy-LL has been informed that you messaged them.
|
||||
|
||||
Hwy-LL will see: -!- Hwy101 wcampbel@admin.irc.monkie.org is messaging you, and you have umode +g.
|
||||
|
@ -86,7 +86,7 @@ Hwy-LL will see: -!- Hwy101 wcampbel@admin.irc.monkie.org is messaging you, and
|
|||
--
|
||||
|
||||
If Hwy101 sends another message to Hwy-LL (before the minute expires), he will
|
||||
see: -!- Hwy-LL is in +g mode (server-side ignore.)
|
||||
see: -!- Hwy-LL is in +g mode and must manually allow you to message them.
|
||||
and will not receive the second notice
|
||||
|
||||
Hwy-LL will NOT see any notice. This also applies if the second message comes
|
||||
|
@ -189,7 +189,7 @@ their accept list.
|
|||
|
||||
716 - ERR_TARGUMODEG
|
||||
--------------------
|
||||
:<server> 716 <nick> <target> :is in +g mode (server-side ignore.)
|
||||
:<server> 716 <nick> <target> :is in +g mode and must manually allow you to message them.
|
||||
|
||||
This numeric is used to indicate that a message (PRIVMSG) the client sent
|
||||
could not be delivered because of CallerID restrictions. The <target>
|
||||
|
@ -215,4 +215,3 @@ which is ambiguous if the user may contain a [ and in the author's opinion ugly.
|
|||
--
|
||||
W. Campbell
|
||||
updated by J. Tjoelker
|
||||
$Id: modeg.txt 3556 2007-08-18 14:45:10Z jilles $
|
|
@ -1,6 +1,5 @@
|
|||
MONITOR - Protocol for notification of when clients become online/offline
|
||||
Lee Hardy <lee -at- leeh.co.uk>
|
||||
$Id: monitor.txt 3520 2007-06-30 22:15:35Z jilles $
|
||||
-------------------------------------------------------------------------
|
||||
|
||||
Currently, ISON requests by clients use a large amount of bandwidth. It is
|
|
@ -127,4 +127,3 @@ Kucharski (IRCnet), IRC Client Capabilities Extension. March 2005.
|
|||
This internet-draft has expired; it can still be found on
|
||||
http://www.leeh.co.uk/draft-mitchell-irc-capabilities-02.html
|
||||
|
||||
$Id: sasl.txt 3169 2007-01-28 22:13:18Z jilles $
|
|
@ -1,9 +1,12 @@
|
|||
ratbox-services compatibility documentation - Lee H <lee -at- leeh.co.uk>
|
||||
-------------------------------------------------------------------------
|
||||
Services compatibility documentation
|
||||
------------------------------------
|
||||
|
||||
Compatibility with ratbox-services is always enabled. Note that some or
|
||||
all of this is also used by atheme-services and anope. It will add the
|
||||
following features to ircd:
|
||||
Originally written by Lee Hardy for ircd-ratbox. Minor changes by Elizabeth
|
||||
Myers for modern services.
|
||||
|
||||
|
||||
Compatibility with services is always enabled. Supported services include
|
||||
atheme and anope. They add the following features to Charybdis:
|
||||
|
||||
1. Channel mode +r
|
||||
|
||||
|
@ -17,8 +20,8 @@ following features to ircd:
|
|||
|
||||
Ability to specify the names of services servers in ircd.conf:
|
||||
service {
|
||||
name = "services.ircd-ratbox.org";
|
||||
name = "backup-services.ircd-ratbox.org";
|
||||
name = "services.charybdis.io";
|
||||
name = "backup-services.charybdis.io";
|
||||
};
|
||||
|
||||
These must be specified for certain features to work. You may specify as
|
||||
|
@ -60,4 +63,3 @@ following features to ircd:
|
|||
Gives numeric 486 to users sending a PRIVMSG who are not logged in:
|
||||
:<server> 486 <nick> <targetnick> :You must log in with services to message this user
|
||||
|
||||
# $Id: services.txt 6 2005-09-10 01:02:21Z nenolod $
|
|
@ -41,6 +41,3 @@ you are messaging that channel or a client within that channel. The latter
|
|||
can be done explicitly using the CNOTICE and CPRIVMSG commands, see
|
||||
/quote help cnotice and /quote help cprivmsg, but is also implicit in a
|
||||
normal /msg, /notice or /invite.
|
||||
|
||||
--
|
||||
$Id: tgchange.txt 6 2005-09-10 01:02:21Z nenolod $
|
|
@ -1,29 +0,0 @@
|
|||
|
||||
# $Id: index.txt 6 2005-09-10 01:02:21Z nenolod $
|
||||
Here is the overview of the documents in the doc/ directory.
|
||||
|
||||
CIDR.txt - Description of CIDR in IPv4
|
||||
Tao-of-IRC.940110 - No comment...
|
||||
challenge.txt - Overview of the challenge/response system for
|
||||
obtaining operator status
|
||||
ircd.conf.example - An example ircd.conf file describing most of the
|
||||
user settable options
|
||||
guidelines.txt - Documentation guidelines
|
||||
hooks.txt - Overview of the hooks available
|
||||
index.txt - This file
|
||||
ircd.8 - The new revised manpage, read with the following
|
||||
commands in the prefix directory:
|
||||
man -M . ircd
|
||||
ircd.motd - A default ircd.motd used by make install
|
||||
logfiles.txt - Description of formatting of some logfiles
|
||||
modeg.txt - An in depth description of the server side silence
|
||||
user mode (+g)
|
||||
modes.txt - A list of all user and channel modes
|
||||
operguide.txt - EFnet operator's guide
|
||||
opermyth.txt - Oper myth's, describes what opers can and cannot do
|
||||
server-version-info - Overview of the flags shown in /version
|
||||
whats-new.txt - What new features are available
|
||||
|
||||
Also in the contrib/ directory you will find:
|
||||
example_module.c - An example module, detailing what the code in a module
|
||||
does. Useful for building your own modules.
|
120
doc/ircd.8
120
doc/ircd.8
|
@ -1,120 +0,0 @@
|
|||
.\" @(#)ircd.8 2.0 22 April 2004
|
||||
.\" $Id: ircd.8 6 2005-09-10 01:02:21Z nenolod $
|
||||
.TH IRCD 8 "ircd-ratbox" 22 April 2004
|
||||
.SH NAME
|
||||
ircd \- The Internet Relay Chat Program Server
|
||||
.SH SYNOPSIS
|
||||
.hy 0
|
||||
.IP \fBircd\fP
|
||||
[-dlinefile filename] [-configfile filename] [-klinefile filename]
|
||||
[-logfile filename] [-pidfile filename] [-resvfile filename]
|
||||
[-xlinefile filename] [-conftest] [-foreground] [-version]
|
||||
.SH DESCRIPTION
|
||||
.LP
|
||||
\fIircd\fP is the server (daemon) program for the Internet Relay Chat
|
||||
Program. The \fIircd\fP is a server in that its function is to "serve"
|
||||
the client program \fIirc(1)\fP with messages and commands. All commands
|
||||
and user messages are passed directly to the \fIircd\fP for processing
|
||||
and relaying to other ircd sites.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B \-dlinefile filename
|
||||
Specifies the D-line file to be used. This file is used for both reading
|
||||
D-lines at startup, and writing to while \fIircd\fP is running.
|
||||
.TP
|
||||
.B \-configfile filename
|
||||
Specifies the ircd.conf file to be used for this ircdaemon. The option
|
||||
is used to override the default ircd.conf given at compile time.
|
||||
.TP
|
||||
.B \-klinefile filename
|
||||
Specifies the K-line file to be used. This file is used for both reading
|
||||
K-lines at startup, and writing to while \fIircd\fP is running.
|
||||
.TP
|
||||
.B \-logfile filename
|
||||
Specifies an alternative logfile to be used than that specified in config.h
|
||||
.TP
|
||||
.B \-pidfile filename
|
||||
Specifies the ircd.pid used. The option is used to override the default
|
||||
ircd.pid given at compile time.
|
||||
.TP
|
||||
.B \-resvfile filename
|
||||
Specifies the resv.conf file to be used for this ircdaemon. The option
|
||||
is used to override the default resv.conf given at compile time.
|
||||
.TP
|
||||
.B \-xlinefile filename
|
||||
Specifies the xline.conf file to be used for this ircdaemon. The option
|
||||
is used to override the default xline.conf given at compile time.
|
||||
.TP
|
||||
.B \-conftest
|
||||
Makes \fIircd\fP check the ircd.conf for errors
|
||||
.TP
|
||||
.B \-foreground
|
||||
Makes \fIircd\fP run in the foreground
|
||||
.TP
|
||||
.B \-version
|
||||
Makes \fIircd\fP print its version, and exit.
|
||||
.SH USAGE
|
||||
If you plan to connect your \fIircd\fP server to an existing Irc-Network,
|
||||
you will need to alter your local IRC configuration file (typically named
|
||||
"ircd.conf") so that it will accept and make connections to other \fIircd\fP
|
||||
servers. This file contains the hostnames, Network Addresses, and sometimes
|
||||
passwords for connections to other ircds around the world. Because
|
||||
description of the actual file format of the "ircd.conf" file is beyond the
|
||||
scope of this document, please refer to the file INSTALL in the IRC source
|
||||
files documentation directory.
|
||||
.LP
|
||||
.SH BOOTING THE SERVER
|
||||
The \fIircd\fP server can be started as part of the
|
||||
Unix boot procedure or just by placing the server into Unix Background.
|
||||
Keep in mind that if it is \fBnot\fP part of your Unix's boot-up procedure
|
||||
then you will have to manually start the \fIircd\fP server each time your
|
||||
Unix is rebooted. This means if your Unix is prone to crashing
|
||||
or going for for repairs a lot it would make sense to start the \fIircd\fP
|
||||
server as part of your UNIX bootup procedure.
|
||||
.SH EXAMPLE
|
||||
.RS
|
||||
.nf
|
||||
tolsun% \fBbin/ircd\fP
|
||||
.fi
|
||||
.RE
|
||||
.LP
|
||||
Places \fIircd\fP into Unix background and starts up the server for use.
|
||||
Note: You do not have to add the "&" to this command, the program will
|
||||
automatically detach itself from tty.
|
||||
.RS
|
||||
.nf
|
||||
leguin% \fBbin/ircd -foreground\fP
|
||||
.fi
|
||||
.RE
|
||||
.LP
|
||||
Runs ircd in the foreground.
|
||||
.RS
|
||||
.nf
|
||||
.SH COPYRIGHT
|
||||
(c) 1988,1989 University of Oulu, Computing Center, Finland,
|
||||
.LP
|
||||
(c) 1988,1989 Department of Information Processing Science,
|
||||
University of Oulu, Finland
|
||||
.LP
|
||||
(c) 1988,1989,1990,1991 Jarkko Oikarinen
|
||||
.LP
|
||||
(c) 1997,1998,1999,2000,2001 The IRCD-Hybrid project.
|
||||
.LP
|
||||
For full COPYRIGHT see LICENSE file with IRC package.
|
||||
.LP
|
||||
.RE
|
||||
.SH FILES
|
||||
"ircd.conf"
|
||||
.SH BUGS
|
||||
None... ;-) if somebody finds one, please inform author
|
||||
.SH AUTHOR
|
||||
irc2.8 and earlier: Jarkko Oikarinen, currently jto@tolsun.oulu.fi.
|
||||
.LP
|
||||
ircd-hybrid-7: IRCD-Hybrid Project, ircd-hybrid@the-project.org.
|
||||
.LP
|
||||
manual page written by Jeff Trim, jtrim@orion.cair.du.edu,
|
||||
later modified by jto@tolsun.oulu.fi.
|
||||
.LP
|
||||
modified for ircd-hybrid-7 by Edward Brocklesby, ejb@klamath.uucp.leguin.org.uk.
|
||||
.LP
|
||||
updated by W. Campbell, wcampbel@botbay.net
|
|
@ -4,12 +4,11 @@
|
|||
* Copyright (C) 2002-2005 ircd-ratbox development team
|
||||
* Copyright (C) 2005-2006 charybdis development team
|
||||
*
|
||||
* $Id: example.conf 3582 2007-11-17 21:55:48Z jilles $
|
||||
*
|
||||
* See reference.conf for more information.
|
||||
*/
|
||||
|
||||
/* Extensions */
|
||||
<<<<<<< .merge_file_MAZNsP
|
||||
#loadmodule "extensions/chm_operonly_compat.so";
|
||||
#loadmodule "extensions/chm_quietunreg_compat.so";
|
||||
#loadmodule "extensions/chm_sslonly_compat.so";
|
||||
|
@ -35,23 +34,49 @@
|
|||
#loadmodule "extensions/sno_whois.so";
|
||||
#loadmodule "extensions/override.so";
|
||||
#loadmodule "extensions/no_kill_services.so";
|
||||
=======
|
||||
#loadmodule "extensions/chm_nonotice";
|
||||
#loadmodule "extensions/chm_operpeace";
|
||||
#loadmodule "extensions/createauthonly";
|
||||
#loadmodule "extensions/extb_account";
|
||||
#loadmodule "extensions/extb_canjoin";
|
||||
#loadmodule "extensions/extb_channel";
|
||||
#loadmodule "extensions/extb_combi";
|
||||
#loadmodule "extensions/extb_extgecos";
|
||||
#loadmodule "extensions/extb_hostmask";
|
||||
#loadmodule "extensions/extb_oper";
|
||||
#loadmodule "extensions/extb_realname";
|
||||
#loadmodule "extensions/extb_server";
|
||||
#loadmodule "extensions/extb_ssl";
|
||||
#loadmodule "extensions/extb_usermode";
|
||||
#loadmodule "extensions/hurt";
|
||||
#loadmodule "extensions/m_extendchans";
|
||||
#loadmodule "extensions/m_findforwards";
|
||||
#loadmodule "extensions/m_identify";
|
||||
#loadmodule "extensions/m_locops";
|
||||
#loadmodule "extensions/no_oper_invis";
|
||||
#loadmodule "extensions/sno_farconnect";
|
||||
#loadmodule "extensions/sno_globalnickchange";
|
||||
#loadmodule "extensions/sno_globaloper";
|
||||
#loadmodule "extensions/override";
|
||||
#loadmodule "extensions/no_kill_services";
|
||||
>>>>>>> .merge_file_DV7Blq
|
||||
|
||||
/*
|
||||
* IP cloaking extensions: use ip_cloaking_4.0
|
||||
* if you're linking 3.2 and later, otherwise use
|
||||
* ip_cloaking.so, for compatibility with older 3.x
|
||||
* ip_cloaking, for compatibility with older 3.x
|
||||
* releases.
|
||||
*/
|
||||
|
||||
#loadmodule "extensions/ip_cloaking_4.0.so";
|
||||
#loadmodule "extensions/ip_cloaking.so";
|
||||
#loadmodule "extensions/ip_cloaking_4.0";
|
||||
#loadmodule "extensions/ip_cloaking";
|
||||
|
||||
serverinfo {
|
||||
name = "hades.arpa";
|
||||
sid = "42X";
|
||||
description = "charybdis test server";
|
||||
description = "solanum test server";
|
||||
network_name = "StaticBox";
|
||||
hub = yes;
|
||||
|
||||
/* On multi-homed hosts you may need the following. These define
|
||||
* the addresses we connect from to other servers. */
|
||||
|
@ -60,18 +85,20 @@ serverinfo {
|
|||
/* for IPv6 */
|
||||
#vhost6 = "2001:db8:2::6";
|
||||
|
||||
/* ssl_private_key: our ssl private key */
|
||||
ssl_private_key = "etc/ssl.key";
|
||||
|
||||
/* ssl_cert: certificate for our ssl server */
|
||||
/* ssl_cert: certificate (and optionally key) for our ssl server */
|
||||
ssl_cert = "etc/ssl.pem";
|
||||
|
||||
/* ssl_private_key: our ssl private key (if not contained in ssl_cert file) */
|
||||
#ssl_private_key = "etc/ssl.key";
|
||||
|
||||
/* ssl_dh_params: DH parameters, generate with openssl dhparam -out dh.pem 2048
|
||||
* In general, the DH parameters size should be the same as your key's size.
|
||||
* However it has been reported that some clients have broken TLS implementations which may
|
||||
* choke on keysizes larger than 2048-bit, so we would recommend using 2048-bit DH parameters
|
||||
* for now if your keys are larger than 2048-bit.
|
||||
*/
|
||||
*
|
||||
* If you do not provide parameters, some TLS backends will fail on DHE- ciphers,
|
||||
* and some will succeed but use weak, common DH groups! */
|
||||
ssl_dh_params = "etc/dh.pem";
|
||||
|
||||
/* ssld_count: number of ssld processes you want to start, if you
|
||||
|
@ -160,7 +187,13 @@ listen {
|
|||
/* Listen on IPv6 (if you used host= above). */
|
||||
#host = "2001:db8:2::6";
|
||||
#port = 5000, 6665 .. 6669;
|
||||
#sslport = 9999;
|
||||
#sslport = 6697;
|
||||
|
||||
/* wsock: listeners defined with this option enabled will be websocket listeners,
|
||||
* and will not accept normal clients.
|
||||
*/
|
||||
wsock = yes;
|
||||
sslport = 9999;
|
||||
};
|
||||
|
||||
/* auth {}: allow users to connect to the ircd (OLD I:)
|
||||
|
@ -195,7 +228,9 @@ auth {
|
|||
* encrypted | password is encrypted with mkpasswd
|
||||
* spoof_notice | give a notice when spoofing hosts
|
||||
* exceed_limit (old > flag) | allow user to exceed class user limits
|
||||
* kline_exempt (old ^ flag) | exempt this user from k/g/xlines&dnsbls
|
||||
* kline_exempt (old ^ flag) | exempt this user from k/g/xlines,
|
||||
* | dnsbls, and proxies
|
||||
* proxy_exempt | exempt this user from proxies
|
||||
* dnsbl_exempt | exempt this user from dnsbls
|
||||
* spambot_exempt | exempt this user from spambot checks
|
||||
* shide_exempt | exempt this user from serverhiding
|
||||
|
@ -224,7 +259,8 @@ auth {
|
|||
* means they must be defined before operator {}.
|
||||
*/
|
||||
privset "local_op" {
|
||||
privs = oper:local_kill, oper:operwall;
|
||||
privs = oper:general, oper:privs, oper:testline, oper:kill, oper:operwall, oper:message,
|
||||
usermode:servnotice, auspex:oper, auspex:hostname, auspex:umodes, auspex:cmodes;
|
||||
};
|
||||
|
||||
privset "server_bot" {
|
||||
|
@ -234,13 +270,14 @@ privset "server_bot" {
|
|||
|
||||
privset "global_op" {
|
||||
extends = "local_op";
|
||||
privs = oper:global_kill, oper:routing, oper:kline, oper:unkline, oper:xline,
|
||||
oper:resv, oper:mass_notice, oper:remoteban;
|
||||
privs = oper:routing, oper:kline, oper:unkline, oper:xline,
|
||||
oper:resv, oper:cmodes, oper:mass_notice, oper:wallops,
|
||||
oper:remoteban;
|
||||
};
|
||||
|
||||
privset "admin" {
|
||||
extends = "global_op";
|
||||
privs = oper:admin, oper:die, oper:rehash, oper:spy;
|
||||
privs = oper:admin, oper:die, oper:rehash, oper:spy, oper:grant;
|
||||
};
|
||||
|
||||
operator "god" {
|
||||
|
@ -297,20 +334,17 @@ operator "god" {
|
|||
privset = "admin";
|
||||
};
|
||||
|
||||
/* See connecting-servers.rst for an introduction to using these files. */
|
||||
|
||||
connect "irc.uplink.com" {
|
||||
host = "203.0.113.3";
|
||||
send_password = "password";
|
||||
accept_password = "anotherpassword";
|
||||
port = 6666;
|
||||
hub_mask = "*";
|
||||
class = "server";
|
||||
flags = compressed, topicburst;
|
||||
flags = topicburst;
|
||||
|
||||
#fingerprint = "c77106576abf7f9f90cca0f63874a60f2e40a64b";
|
||||
|
||||
/* If the connection is IPv6, uncomment below.
|
||||
* Use 0::1, not ::1, for IPv6 localhost. */
|
||||
#aftype = ipv6;
|
||||
};
|
||||
|
||||
connect "ssl.uplink.com" {
|
||||
|
@ -318,7 +352,6 @@ connect "ssl.uplink.com" {
|
|||
send_password = "password";
|
||||
accept_password = "anotherpassword";
|
||||
port = 9999;
|
||||
hub_mask = "*";
|
||||
class = "server";
|
||||
flags = ssl, topicburst;
|
||||
};
|
||||
|
@ -332,9 +365,8 @@ cluster {
|
|||
flags = kline, tkline, unkline, xline, txline, unxline, resv, tresv, unresv;
|
||||
};
|
||||
|
||||
shared {
|
||||
oper = "*@*", "*";
|
||||
flags = all, rehash;
|
||||
secure {
|
||||
ip = "127.0.0.1";
|
||||
};
|
||||
|
||||
/* exempt {}: IPs that are exempt from Dlines and rejectcache. (OLD d:) */
|
||||
|
@ -350,6 +382,7 @@ channel {
|
|||
knock_delay = 5 minutes;
|
||||
knock_delay_channel = 1 minute;
|
||||
max_chans_per_user = 15;
|
||||
max_chans_per_user_large = 60;
|
||||
max_bans = 100;
|
||||
max_bans_large = 500;
|
||||
default_split_user_count = 0;
|
||||
|
@ -364,6 +397,9 @@ channel {
|
|||
disable_local_channels = no;
|
||||
autochanmodes = "+nt";
|
||||
displayed_usercount = 3;
|
||||
strip_topic_colors = no;
|
||||
opmod_send_statusmsg = no;
|
||||
invite_notify_notice = yes;
|
||||
};
|
||||
|
||||
serverhide {
|
||||
|
@ -373,15 +409,14 @@ serverhide {
|
|||
disable_hidden = no;
|
||||
};
|
||||
|
||||
/* These are the blacklist settings.
|
||||
/* These are the DNSBL settings.
|
||||
* You can have multiple combinations of host and rejection reasons.
|
||||
* They are used in pairs of one host/rejection reason.
|
||||
*
|
||||
* These settings should be adequate for most networks, and are (presently)
|
||||
* required for use on StaticBox.
|
||||
* The default settings should be adequate for most networks.
|
||||
*
|
||||
* Word to the wise: Do not use blacklists like SPEWS for blocking IRC
|
||||
* connections.
|
||||
* It is not recommended to use DNSBL services designed for e-mail spam
|
||||
* prevention, such as SPEWS for blocking IRC connections.
|
||||
*
|
||||
* As of charybdis 2.2, you can do some keyword substitution on the rejection
|
||||
* reason. The available keyword substitutions are:
|
||||
|
@ -401,13 +436,13 @@ serverhide {
|
|||
* is considered a match. If included, a comma-separated list of *quoted*
|
||||
* strings is allowed to match queries. They may be of the format "0" to "255"
|
||||
* to match the final octet (e.g. 127.0.0.1) or "127.x.y.z" to explicitly match
|
||||
* an A record. The blacklist is only applied if it matches anything in the
|
||||
* an A record. The DNSBL match is only applied if it matches anything in the
|
||||
* list. You may freely mix full IP's and final octets.
|
||||
*
|
||||
* Consult your blacklist provider for the meaning of these parameters; they
|
||||
* are usually used to denote different ban types.
|
||||
* Consult your DNSBL provider for the meaning of these parameters; they
|
||||
* are usually used to denote different block reasons.
|
||||
*/
|
||||
blacklist {
|
||||
dnsbl {
|
||||
host = "rbl.efnetrbl.org";
|
||||
type = ipv4;
|
||||
reject_reason = "${nick}, your IP (${ip}) is listed in EFnet's RBL. For assistance, see http://efnetrbl.org/?i=${ip}";
|
||||
|
@ -419,6 +454,78 @@ blacklist {
|
|||
# reject_reason = "${nick}, your IP (${ip}) is listed in ${dnsbl-host} for some reason. In order to protect ${network-name} from abuse, we are not allowing connections listed in ${dnsbl-host} to connect";
|
||||
};
|
||||
|
||||
/* These are the OPM settings.
|
||||
* This is similar to the functionality provided by BOPM. It will scan incoming
|
||||
* connections for open proxies by connecting to clients and attempting several
|
||||
* different open proxy handshakes. If they connect back to us (via a dedicated
|
||||
* listening port), and send back the data we send them, they are considered
|
||||
* an open proxy. For politeness reasons (users may be confused by the incoming
|
||||
* connection attempts if they are logging incoming connections), the user is
|
||||
* notified upon connect if they are being scanned.
|
||||
*
|
||||
* WARNING:
|
||||
* These settings are considered experimental. Only the most common proxy types
|
||||
* are checked for (Charybdis is immune from POST and GET proxies). If you are
|
||||
* not comfortable with experimental code, do not use this feature.
|
||||
*/
|
||||
#opm {
|
||||
/* IPv4 address to listen on. This must be a publicly facing IP address
|
||||
* to be effective.
|
||||
* If omitted, it defaults to serverinfo::vhost.
|
||||
*/
|
||||
#listen_ipv4 = "127.0.0.1";
|
||||
|
||||
/* IPv4 port to listen on.
|
||||
* This should not be the same as any existing listeners.
|
||||
*/
|
||||
#port_v4 = 32000;
|
||||
|
||||
/* IPv6 address to listen on. This must be a publicly facing IP address
|
||||
* to be effective.
|
||||
* If omitted, it defaults to serverinfo::vhost6.
|
||||
*/
|
||||
#listen_ipv6 = "::1";
|
||||
|
||||
/* IPv6 port to listen on.
|
||||
* This should not be the same as any existing listeners.
|
||||
*/
|
||||
#port_v6 = 32000;
|
||||
|
||||
/* You can also set the listen_port directive which will set both the
|
||||
* IPv4 and IPv6 ports at once.
|
||||
*/
|
||||
#listen_port = 32000;
|
||||
|
||||
/* This sets the timeout in seconds before ending open proxy scans.
|
||||
* Values less than 1 or greater than 60 are ignored.
|
||||
* It is advisable to keep it as short as feasible, so clients do not
|
||||
* get held up by excessively long scan times.
|
||||
*/
|
||||
#timeout = 5;
|
||||
|
||||
/* These are the ports to scan for SOCKS4 proxies on. They may overlap
|
||||
* with other scan types. Sensible defaults are given below.
|
||||
*/
|
||||
#socks4_ports = 1080, 10800, 443, 80, 8080, 8000;
|
||||
|
||||
/* These are the ports to scan for SOCKS5 proxies on. They may overlap
|
||||
* with other scan types. Sensible defaults are given below.
|
||||
*/
|
||||
#socks5_ports = 1080, 10800, 443, 80, 8080, 8000;
|
||||
|
||||
/* These are the ports to scan for HTTP connect proxies on (plaintext).
|
||||
* They may overlap with other scan types. Sensible defaults are given
|
||||
* below.
|
||||
*/
|
||||
#httpconnect_ports = 80, 8080, 8000;
|
||||
|
||||
/* These are the ports to scan for HTTPS CONNECT proxies on (SSL).
|
||||
* They may overlap with other scan types. Sensible defaults are given
|
||||
* below.
|
||||
*/
|
||||
#httpsconnect_ports = 443, 4443;
|
||||
#};
|
||||
|
||||
alias "NickServ" {
|
||||
target = "NickServ";
|
||||
};
|
||||
|
@ -506,9 +613,18 @@ general {
|
|||
resv_fnc = yes;
|
||||
global_snotices = yes;
|
||||
dline_with_reason = yes;
|
||||
kline_delay = 0 seconds;
|
||||
kline_with_reason = yes;
|
||||
hide_tkdline_duration = no;
|
||||
kline_reason = "K-Lined";
|
||||
sasl_only_client_message = "You need to identify via SASL to use this server.";
|
||||
identd_only_client_message = "You need to install identd to use this server.";
|
||||
sctp_forbidden_client_message = "You are not allowed to use SCTP on this server.";
|
||||
ssltls_only_client_message = "You need to use SSL/TLS to use this server.";
|
||||
not_authorised_client_message = "You are not authorised to access this server.";
|
||||
illegal_hostname_client_message = "You have an illegal character in your hostname.";
|
||||
server_full_client_message = "Sorry, server is full - try later";
|
||||
illegal_name_long_client_message = "Your username is invalid. Please make sure that your username contains only alphanumeric characters.";
|
||||
illegal_name_short_client_message = "Invalid username";
|
||||
identify_service = "NickServ@services.int";
|
||||
identify_command = "IDENTIFY";
|
||||
non_redundant_klines = yes;
|
||||
|
@ -516,7 +632,6 @@ general {
|
|||
use_propagated_bans = yes;
|
||||
stats_e_disabled = no;
|
||||
stats_c_oper_only = no;
|
||||
stats_h_oper_only=no;
|
||||
stats_y_oper_only = no;
|
||||
stats_o_oper_only = yes;
|
||||
stats_P_oper_only = no;
|
||||
|
@ -537,6 +652,7 @@ general {
|
|||
no_oper_flood = yes;
|
||||
max_targets = 4;
|
||||
client_flood_max_lines = 20;
|
||||
post_registration_delay = 0 seconds;
|
||||
use_whois_actually = no;
|
||||
oper_only_umodes = operwall, locops, servnotice;
|
||||
oper_umodes = locops, servnotice, operwall, wallop;
|
||||
|
@ -550,7 +666,9 @@ general {
|
|||
throttle_count = 4;
|
||||
max_ratelimit_tokens = 30;
|
||||
away_interval = 30;
|
||||
certfp_method = sha1;
|
||||
certfp_method = spki_sha256;
|
||||
hide_opers_in_whois = no;
|
||||
tls_ciphers_oper_only = no;
|
||||
};
|
||||
|
||||
modules {
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
This is charybdis MOTD you might replace it, but if not your friends will
|
||||
This is solanum MOTD you might replace it, but if not your friends will
|
||||
laugh at you.
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
ircd-ratbox logfiles - Lee H <lee -at- leeh.co.uk>
|
||||
$Id: logfiles.txt 6 2005-09-10 01:02:21Z nenolod $
|
||||
Charybdis logfiles - Lee H <lee -at- leeh.co.uk>
|
||||
---------------------------
|
||||
|
||||
fname_killlog
|
||||
|
|
|
@ -4,7 +4,6 @@ Standard channel modes are listed in help/opers/cmode
|
|||
|
||||
The sgml docs have more detailed descriptions.
|
||||
|
||||
User mode +h (hide hostname) is provided by contrib/ip_cloaking.so
|
||||
User mode +x (hide hostname) is provided by contrib/ip_cloaking.so
|
||||
Server notice mask +F (far connects) is provided by contrib/sno_farconnect.so
|
||||
|
||||
# $Id: modes.txt 996 2006-03-09 01:14:34Z jilles $
|
||||
Information on the caller ID system can be found in doc/features/modeg.txt
|
||||
|
|
137
doc/old/Authors
137
doc/old/Authors
|
@ -1,137 +0,0 @@
|
|||
/************************************************************************
|
||||
* IRC - Internet Relay Chat, doc/AUTHORS
|
||||
* Copyright (C) 1990
|
||||
*
|
||||
* AUTHORS FILE:
|
||||
* This file attempts to remember all contributors to the IRC
|
||||
* developement. Names can be only added this file, no name
|
||||
* should never be removed. This file must be included into all
|
||||
* distributions of IRC and derived works.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
IRC was conceived of and written by Jarkko Oikarinen <jto@tolsun.oulu.fi>.
|
||||
IRC was originally written in University of Oulu, Computing Center.
|
||||
Jan 1991 - IRC 2.6 jto@tolsun.oulu.fi
|
||||
- Multiple Channels and protocol changes
|
||||
|
||||
Contributions were made by a cast of dozens, including the following:
|
||||
|
||||
Markku Jarvinen <mta@tut.fi>: Emacs-like editing facility for the client
|
||||
|
||||
Kimmo Suominen <kim@kannel.lut.fi>: HP-UX port
|
||||
|
||||
Jeff Trim <jtrim@orion.cair.du.edu>: enhancements and advice
|
||||
|
||||
Vijay Subramaniam <vijay@lll-winken.llnl.gov>: advice and ruthless publicity
|
||||
|
||||
Karl Kleinpaste <karl@cis.ohio-state.edu>: user's manual
|
||||
|
||||
Greg Lindahl <gl8f@virginia.edu>: AUTOMATON code, the Wumpus GM automaton,
|
||||
myriad bug fixes
|
||||
|
||||
Bill Wisner <wisner@hayes.fai.alaska.edu>: numerous bug fixes and code
|
||||
enhancements
|
||||
|
||||
Tom Davis <conslt16@zeus.unl.edu> and Tim Russell <russell@zeus.unl.edu>:
|
||||
VMS modifications
|
||||
|
||||
Markku Savela <msa@tel4.tel.vtt.fi>: advice, support, and being the
|
||||
incentive to do some of our *own* coding. :)
|
||||
|
||||
Tom Hopkins <hoppie@buengf.bu.edu>: bug fixes, quarantine lines,
|
||||
consolidation of various patches.
|
||||
|
||||
Christopher Davis <ckd@cs.bu.edu>: EFnet/Anet gateway coding,
|
||||
many automata ;), documentation fixing.
|
||||
|
||||
Helen Rose <hrose@cs.bu.edu>: documentation updating, and fixing.
|
||||
|
||||
Tom Hinds <rocker@bucsf.bu.edu>: emacs client updating.
|
||||
|
||||
Tim Miller <cerebus@bu-pub.bu.edu>: various server and client-breaking
|
||||
features.
|
||||
|
||||
Darren Reed <avalon@coombs.anu.edu.au>: various bug fixes and enhancements.
|
||||
Introduced nickname and channelname hash tables into the server.
|
||||
|
||||
The version 2.2 release was coordinated by Mike Bolotski
|
||||
<mikeb@salmon.ee.ubc.ca>.
|
||||
|
||||
The version 2.4 release was coordinated by Markku Savela and
|
||||
Chelsea Ashley Dyerman
|
||||
|
||||
The version 2.5.2 release was coordinated by Christopher Davis, Helen Rose,
|
||||
and Tom Hopkins.
|
||||
|
||||
The versions 2.6.2, 2.7 and 2.8 releases were coordinated by Darren Reed.
|
||||
|
||||
Contributions for the 2.8 release from the following people:
|
||||
Matthew Green <phone@coombs.anu.edu.au>
|
||||
Chuck Kane <ckane@ece.uiuc.edu>
|
||||
Matt Lyle <matt@oc.com>
|
||||
Vesa Ruokonen <ruokonen@lut.fi>
|
||||
|
||||
Markku Savela <Markku.Savela@vtt.fi> / April 1990
|
||||
Fixed various bugs in 2.2PL1 release server (2.2msa.4) and changed
|
||||
sockets to use non-blocking mode (2.2msa.9). [I have absolutely
|
||||
nothing to do with clients :-]
|
||||
|
||||
Chelsea Ashley Dyerman <chelsea@earth.cchem.berkeley.edu> / April 1990
|
||||
Rewrote the Makefiles, restructuring of source tree. Added libIrcd.a to
|
||||
the Makefile macros, numerous reformatting of server text messages, and
|
||||
added mkversion.sh to keep track of compilation statistics. Numerous
|
||||
bug fixes and enhancements, and co-coordinator of the 2.4 release.
|
||||
|
||||
jarlek@ifi.uio.no added mail functions to irc.
|
||||
|
||||
Armin Gruner <gruner@informatik.tu-muenchen.de> / May, June 1990:
|
||||
* Patched KILL-line feature for ircd.conf, works now.
|
||||
Enhancement: Time intervals can be specified in passwd-field.
|
||||
Result: KILL-Line is only active during these intervals
|
||||
* Patched PRIVMSG handling, now OPER can specify masks for sending
|
||||
private messages, advantage: msg to all at a specified server or host.
|
||||
* Little tests on irc 2.5 alpha, fixed some little typos in client code.
|
||||
Change: common/debug.c has been moved to ircd/s_debug.c, and a
|
||||
irc/c_debug.c has been created, for the benefit that wrong server msg
|
||||
are displayed if client does not recognize them. (strange, if a server
|
||||
sends an 'unknown command', isn't it?)
|
||||
|
||||
Tom Hopkins <hoppie@buengf.bu.edu> / September, October 1990:
|
||||
* Patched msa's K lines for servers (Q lines).
|
||||
* Consolidated several patches, including Stealth's logging patch.
|
||||
* Fixed several minor bugs.
|
||||
* Has done lots of other stuff that I can't seem to remember, but he
|
||||
always works on code, so he has to have done alot more than three
|
||||
lines worth. :)
|
||||
|
||||
Thanks go to those persons not mentioned here who have added their advice,
|
||||
opinions, and code to IRC.
|
||||
|
||||
Various modifications, bugreports, cleanups and testing by:
|
||||
|
||||
Hugo Calendar <hugo@ucscb.ucsc.edu>
|
||||
Bo Adler <adler@csvax.cs.caltech.edu>
|
||||
Michael Sandrof <ms5n+@andrew.cmu.edu>
|
||||
Jon Solomon <jsol@cs.bu.edu>
|
||||
Jan Peterson <jlp@hamblin.math.byu.edu>
|
||||
Nathan Glasser <nathan@brokaw.lcs.mit.edu>
|
||||
Helen Rose <hrose@eff.org>
|
||||
Mike Pelletier <stealth@caen.engin.umich.edu>
|
||||
Basalat Ali Raja <gwydion@tavi.rice.edu>
|
||||
Eric P. Scott <eps@toaster.sfsu.edu>
|
||||
Dan Goodwin <fornax@wpi.wpi.edu>
|
||||
Noah Friedman <friedman@ai.mit.edu>
|
|
@ -87,12 +87,21 @@ hub
|
|||
serving as a hub, i.e. have multiple servers connected to it.
|
||||
|
||||
vhost
|
||||
<<<<<<< .merge_file_cTfvge
|
||||
An optional text field which defines an IP from which to connect
|
||||
outward to other IRC servers.
|
||||
|
||||
vhost6
|
||||
An optional text field which defines an IPv6 IP from which to
|
||||
connect outward to other IRC servers.
|
||||
=======
|
||||
An optional text field which defines an IPv4 address from which
|
||||
to connect outward to other IRC servers.
|
||||
|
||||
vhost6
|
||||
An optional text field which defines an IPv6 address from which
|
||||
to connect outward to other IRC servers.
|
||||
>>>>>>> .merge_file_3UzJEV
|
||||
|
||||
admin {} block
|
||||
--------------
|
||||
|
@ -255,6 +264,12 @@ flags
|
|||
class
|
||||
A name of a class to put users matching this auth{} block into.
|
||||
|
||||
<<<<<<< .merge_file_cTfvge
|
||||
=======
|
||||
umodes
|
||||
Additional umodes to apply to the default_umodes upon connect.
|
||||
|
||||
>>>>>>> .merge_file_3UzJEV
|
||||
auth {} flags
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
|
@ -446,10 +461,13 @@ host
|
|||
``A`` or ``AAAA`` record (no ``CNAME``) and it must be
|
||||
the primary hostname for inbound connections to work.
|
||||
|
||||
<<<<<<< .merge_file_cTfvge
|
||||
IPv6 addresses must be in ``::`` shortened form; addresses which
|
||||
then start with a colon must be prepended with a zero, for
|
||||
example ``0::1``.
|
||||
|
||||
=======
|
||||
>>>>>>> .merge_file_3UzJEV
|
||||
send\_password
|
||||
The password to send to the other server.
|
||||
|
||||
|
@ -478,7 +496,12 @@ flags
|
|||
|
||||
aftype
|
||||
The protocol that should be used to connect with, either ipv4 or
|
||||
<<<<<<< .merge_file_cTfvge
|
||||
ipv6. This defaults to ipv4 unless host is a numeric IPv6 address.
|
||||
=======
|
||||
ipv6. This defaults to neither, allowing connection using either
|
||||
address family.
|
||||
>>>>>>> .merge_file_3UzJEV
|
||||
|
||||
**connect {} flags**
|
||||
|
||||
|
|
|
@ -1,368 +0,0 @@
|
|||
|
||||
EFnet Oper Guide
|
||||
Last update: 02-21-2002
|
||||
Written and maintained by Riedel
|
||||
E-Mail: dennisv@vuurwerk.nl
|
||||
|
||||
1. Commands you should know about
|
||||
2. The client of your choice
|
||||
3. Your primary responsibilities
|
||||
4. Re-routing
|
||||
4.1 Re-routing other servers and remote connects
|
||||
5. Kills and klines
|
||||
6. Kill and K-Line requests
|
||||
7. Happy birthday!
|
||||
8. Security
|
||||
9. Know who your friends are
|
||||
10. The TCM bot
|
||||
11. Services
|
||||
12. G-Lines
|
||||
|
||||
|
||||
1. Commands you should know about
|
||||
|
||||
This is no longer covered here. IRCD-hybrid is changing too rapidly, so
|
||||
this section would be outdated in no time ;) For an up-to-date version,
|
||||
please download the latest hybrid at www.ircd-hybrid.org.
|
||||
|
||||
|
||||
2. The client of your choice
|
||||
|
||||
There are many IRC clients around for a wide variety of operating systems.
|
||||
Being an IRC Operator doesn't *require* you to use a UNIX client, however
|
||||
I personally prefer UNIX-based clients. If you're familiar with UNIX and
|
||||
use UNIX for opering, I suggest ircII / epic. There are a lot of scripts
|
||||
available for those two clients, and it's not that hard to write scripts
|
||||
yourself to suite your needs. It is important that you know how to operate
|
||||
your client, and familiarize yourself with the options and features. For
|
||||
whatever client you chose this goes for any of them: You should be in
|
||||
control of your client, instead of the client being in control of you.
|
||||
|
||||
Resources :
|
||||
|
||||
www.mirc.co.uk - mIRC (MS-Windows)
|
||||
www.irchelp.org - a variety of clients and scripts
|
||||
ftp.blackened.com - several UNIX based clients available
|
||||
|
||||
|
||||
3. Your primary responsibilities
|
||||
|
||||
As an IRC Operator, you're responsible for maintaining the server on a
|
||||
real-time basis. You represent your server, and you represent the network.
|
||||
Irresponsible / rude / offensive / stupid behavior may discredit your server
|
||||
and the network. You should focus on the task you were chosen for...
|
||||
maintainance. Sounds simple, no? It means getting rid of users that abuse
|
||||
the service, enforcing the server's policy and keeping the server linked.
|
||||
Users will ask you questions, and expect you to know all the answers.. after
|
||||
all, you're the oper!
|
||||
|
||||
Be prepared for users trying to fool you, sweet talk you into things you
|
||||
don't want, lie and deceive. Most users are handling in good faith...
|
||||
however, the abusers have learned how to manipulate opers. They have studied
|
||||
the alien creature 'oper' for ages like biologists study animals. Be
|
||||
paranoid, be curious and be suspicious. I can't stress the importancy of that
|
||||
often enough.
|
||||
|
||||
Second priority has the network. You were not chosen to maintain the network
|
||||
but you were chosen to maintain the server. However, you may want to be able
|
||||
to reroute servers. If you see something broken, don't be afraid to fix it.
|
||||
If you do, be sure you fix things and don't make it worse. Before you
|
||||
step into routing, be sure you've familiarized yourself with the network's
|
||||
topology, and be confident enough to perform such actions. (re)routing is
|
||||
covered in the next chapter.
|
||||
|
||||
Opers on the network depend on a trusting relationship. You can usually take
|
||||
the word from an oper. Other opers are considered -trusted-, however, there
|
||||
are exceptions. Sometimes even opers lie to opers to get things done. Don't
|
||||
be afraid to ask for proof of a certain statement, such as logs.
|
||||
This doesn't mean you distrust the oper in question, but -you- and you alone
|
||||
are responsible for your actions. You call the shots on your server, unless
|
||||
your admin says otherwise.
|
||||
|
||||
|
||||
4. Re-routing
|
||||
|
||||
Re-routing is not hard, and it's not scary but it is important that you do it
|
||||
right. The commands you'll use are SQUIT and CONNECT. First, a very simple
|
||||
example. Let's say your server, irc.yourserver.com is lagged to it's uplink,
|
||||
irc.uplink.com and you want to reroute your server. You have to think about
|
||||
where you want your server to be linked, and you have to time your reroute.
|
||||
An example topology :
|
||||
|
||||
irc.yourserver.com ---- irc.uplink.com
|
||||
| | \
|
||||
B C D
|
||||
/ \
|
||||
E F
|
||||
/ \
|
||||
G H --- O
|
||||
/ | \ | \
|
||||
I J K L M
|
||||
\
|
||||
N
|
||||
|
||||
In this case, you're uplinked by irc.uplink.com
|
||||
irc.uplink.com also hubs B, C and D. Server B functions as hub for E and F;
|
||||
F hubs G and H; H hubs L, M and O. G hubs I, J and K. M hubs N.
|
||||
Your server is allowed to connect to server B, F and G. So you consider the
|
||||
servers you're able to connect to. Is the lag caused by a server that uplinks
|
||||
irc.uplink.com ? Use /stats ? irc.uplink.com to determine lag to the other
|
||||
servers. If irc.uplink.com does not respond, the lag is to your uplink. If
|
||||
so, you cannot be sure about the state of the other uplinks, so you'd have to
|
||||
get on a remote server and determine lag by using /stats ? and /trace. For
|
||||
example, you could connect to server N, and /trace yournick. Yournick, being
|
||||
the nick on your server. You'll see which route it takes, and what the
|
||||
problem server is. Example /trace output :
|
||||
|
||||
S:[SERVER-N ] V:[2.8/hybrid] U:[SERVER-M ]
|
||||
S:[SERVER-M ] V:[2.8/hybrid] U:[SERVER-H ]
|
||||
S:[SERVER-H ] V:[2.8/hybrid] U:[SERVER-F ]
|
||||
S:[SERVER-F ] V:[2.8/hybrid] U:[SERVER-B ]
|
||||
S:[SERVER-B ] V:[2.8/hybrid] U:[irc.uplink.com ]
|
||||
S:[irc.uplink.com ] V:[2.8/hybrid] U:[irc.yourserver.com ]
|
||||
|
||||
The trace doesn't complete... server-b announces irc.uplink.com, and
|
||||
irc.uplink.com announces your server. Your server should return something
|
||||
like :
|
||||
|
||||
S:[irc.yourserver.] OPER [yournick!user@yourhost]
|
||||
|
||||
If it doesn't, we know the lag is only between yourserver and uplink.
|
||||
Usually if there is lag between your server and your uplink, the send-queue
|
||||
rises. This is not always the case. Sometimes your server can write perfectly
|
||||
to your uplink, but not reverse. That is called one sided lag.
|
||||
|
||||
We pick server B to link to. It means we have to SQUIT and CONNECT.
|
||||
To unlink from irc.uplink.com and connect to SERVER_B we'd type:
|
||||
/quote SQUIT irc.uplink.com :reroute
|
||||
/connect SERVER_B
|
||||
|
||||
we *DON'T* SQUIT irc.yourserver.com... and I'll try to explain why:
|
||||
If we wanted to remove hub M from the network, and with it N, we'd issue
|
||||
a SQUIT M. An SQUIT follows a path, relays the SQUIT request to each server
|
||||
in that path. Finally it reaches server H, which is the hub for M. Server H
|
||||
sees the SQUIT and drops the link to M.
|
||||
|
||||
Now a different situation, we want to separate yourserver, uplink, C and D
|
||||
from the rest of the network, in order to reroute. We'd have to SQUIT server
|
||||
B, since we want the -uplink- of server B (being irc.uplink.com) to drop the
|
||||
link to server B.
|
||||
|
||||
If you'd SQUIT irc.yourserver.com, you ask yourserver.com to drop the link to
|
||||
itself, which is impossible. If you SQUIT irc.uplink.com, you ask yourserver
|
||||
to drop the link to uplink, which is what we want to do.
|
||||
|
||||
After the SQUIT and CONNECT, the new situation looks like this :
|
||||
|
||||
irc.uplink.com
|
||||
| | \
|
||||
irc.yourserver.com -- B C D
|
||||
/ \
|
||||
E F
|
||||
/ \
|
||||
G H --- O
|
||||
/ | \ | \
|
||||
I J K L M
|
||||
\
|
||||
N
|
||||
|
||||
If yourserver is a Hub, it makes the situation more complex, since your
|
||||
actions have more impact.
|
||||
|
||||
|
||||
4.1 - Re-routing other servers and remote connects
|
||||
|
||||
Example topology :
|
||||
|
||||
irc.uplink.com
|
||||
| | \
|
||||
irc.yourserver.com -- B C D
|
||||
/ \
|
||||
E F
|
||||
/ \
|
||||
G H --- O
|
||||
/ | \ | \
|
||||
I J K L M
|
||||
\
|
||||
N
|
||||
|
||||
Let's say, hub H is way lagged to F, but G to F is fine... we want to reroute
|
||||
H, and stick H to G.
|
||||
|
||||
We'd do :
|
||||
|
||||
/quote SQUIT serverh :re-routing you babe
|
||||
/connect serverh 6667 serverg
|
||||
|
||||
A global wallops will be sent :
|
||||
!serverg! Remote CONNECT serverh 6667 from ItsMe
|
||||
|
||||
When re-routing, always give the server some time to prevent nick collides.
|
||||
When there is lag, people will connect to another server. When you SQUIT and
|
||||
CONNECT to fast, a lot of those clients will be collided. Also, stick to your
|
||||
territory. How enthusiastic you may be, you cannot route the world. If you're
|
||||
an oper on the US side, stick to the US side when re-routing. Needless to
|
||||
say, if you're EU, keep it to EU ;)
|
||||
|
||||
|
||||
5. Kills and klines
|
||||
|
||||
As an oper, you're given the incredible power *cough* of KILL and KLINE.
|
||||
/kill nick reason disconnects a client from IRC with the specified reason.
|
||||
A /quote kline *evil@*.dude.org :reason here bans the user from your server.
|
||||
Abusive kills and klines may draw attacks to your server, so always consider
|
||||
if a kline or kill is deserved. If the server gets attacked after a valid
|
||||
kill or kline, well.. tough luck. You should never be 'afraid' to kline
|
||||
anyone on your server. If it's a good reason, make it so. Even if you know
|
||||
it may cause the server to be attacked. Maybe good to think about is this:
|
||||
- if /ignore solves the problem rather than a kick, /ignore
|
||||
- kick if a ban is unneeded
|
||||
- ban if a /kill is unwarranted for
|
||||
- kill rather than kline if that solves the problem
|
||||
- kline when a server ban is really needed.
|
||||
|
||||
You kline a user when you absolutely don't want this user to use the service
|
||||
your server is providing.
|
||||
|
||||
Crosskills (killing users on another server) are another issue. Some admins
|
||||
don't care if users get /kill'ed off their server, for any reason or no
|
||||
reason at all... and other admins are very anal about it. A good way to go
|
||||
(IMO) is to issue a KILL if there is an absolute need for the target user to
|
||||
be disconnected. If there are active opers on that server, let them handle
|
||||
it. They'll be upset if you /kill a user off their server, without
|
||||
contacting them. /stats p irc.server.here shows the active opers on a
|
||||
particular server. Some opers have multiple o-lines and are not watching all
|
||||
sessions. If you can't find an active oper on a server, you can
|
||||
/quote operwall a request for opers from that server.
|
||||
|
||||
Ghost KILLs are another story, an often misunderstood one.
|
||||
When you see a /KILL from an oper with the reason 'ghosted' they usually
|
||||
KILL a client that's about to ping timeout. That is not what a ghost is!
|
||||
To quote Dianora: "a ghost happens because a client misses being killed when
|
||||
it should be. Its a race condition due to nick chasing". In other words,
|
||||
Server X thinks client A has been KILLed, while server Y missed the KILL
|
||||
for that client.
|
||||
|
||||
|
||||
6. Kill and K-Line requests
|
||||
|
||||
As previously mentioned, if an oper from another server contacts you and
|
||||
requests a kill or a kline for a local client with a good reason, you can
|
||||
usually trust this request. Opers depend on a trusting relationship. However,
|
||||
since you're responsible for the kill or kline, it is not rude to ask for
|
||||
proof. It depends on the oper making the request how thats interpreted, but
|
||||
the way they respond to asking for proof tells more about them than about
|
||||
you.
|
||||
|
||||
The more and longer you oper, how better you get to know the other opers.
|
||||
You know who is honest, you'll know who are lying and deceiving. Before
|
||||
you acquire this knowledge, you can merely rely on common sense and
|
||||
instincts. You'll probably make mistakes occasionally, and thats nothing to
|
||||
be ashamed of. Opers are - despite contrary believes - human.
|
||||
|
||||
Users occasionally will ask you to kill or kline a user/bot too. Some
|
||||
requests are straight-forward and clear, others require you to be cautious. I
|
||||
recommend to always investigate such requests, and when you're confident the
|
||||
request is valid, issue the kill or kline.
|
||||
|
||||
|
||||
7. Happy birthday!
|
||||
|
||||
It is a custom on EFnet to birthday /kill opers of whom it is his/her
|
||||
birthday. Not all opers like this, but typically those opers don't let
|
||||
others know about their birthday. You'll notice that the KILLS say a lot
|
||||
about who likes who and who is friends with who. Whether you want to
|
||||
participate, is entirely up to you.
|
||||
|
||||
|
||||
8. Security
|
||||
|
||||
As with any privilege, you have to handle it cautiously and responsibly.
|
||||
Be sure that your o/O line doesn't get compromised! Oper only from secure
|
||||
hosts. You and only you should know your password. Don't share your oper
|
||||
account, and make your oper password a UNIQUE one. If your o/O line gets
|
||||
compromised, nasty things may/will happen. Imagine an oper with crosskill
|
||||
capabilities who's operline gets 'hacked'... the results are often
|
||||
disastrous and you will lose respect and trust from others. It can cause
|
||||
your oper privileges to be revoked, or even the server to be (temporarily)
|
||||
delinked.
|
||||
|
||||
|
||||
9. Know who your friends are
|
||||
|
||||
As an oper you will get a lot of users that want to be 'friends' with you.
|
||||
Users offer you free* access to their *nix servers, ops in channels,
|
||||
unlimited leech access to the biggest and fastest warez sites *gasp* and
|
||||
more. They want favors in return. They say they don't but they truly want
|
||||
something in return. They -expect- something in return. You could either
|
||||
don't respond to such offers, or use them. The last option creates an even
|
||||
more distorted image of opers and doesn't do any good for the user <-> oper
|
||||
relationship. Your *real* friends are usually the persons who were your
|
||||
friends _before_ you acquired the extra privileges.
|
||||
|
||||
|
||||
10. The TCM Bot
|
||||
|
||||
A TCM bot can be a valuable tool for opers. It keeps record of all connected
|
||||
clients, flags clients with multiple connections and has all sorts of other
|
||||
useful commands. There are three different kind of TCM's in use on EFnet,
|
||||
being OOMon, TCM-Dianora and TCM-Hybrid. Every one of them requires you to
|
||||
log in to be able to access the privileged commands. On OOMon you DCC chat
|
||||
the TCM bot and do '.auth yournick yourpass' where yournick is your oper
|
||||
name in your o/O line. In TCM-Dianora and TCM-Hybrid you register with:
|
||||
'.register yourpass', where yourpass is your password ;)
|
||||
All TCM commands start with a period. If you forget the period, the text goes
|
||||
into the 'partyline', where it is echoed to all connected opers.
|
||||
|
||||
Resources : http://toast.blackened.com/oomon/help
|
||||
http://www.db.net/~db/tcm.html
|
||||
|
||||
|
||||
11. Services
|
||||
|
||||
A recent addition to EFNet is Channel Fixer, aka ChanFix. This is an
|
||||
automated service that re-ops clients on opless channels. There are a few
|
||||
restrictions. First, the channel has to be of significant size for ChanFix
|
||||
to store it in its database. Second, it only logs static addresses.
|
||||
|
||||
How does it work? Periodically it stores information about the channel state
|
||||
in its database, for every channel in there. On every 'run', a channel
|
||||
operator gets one point. These scores make a top-5 of 'most frequent opped
|
||||
clients'. When a channel becomes opless, ChanFix will join and op the top-5
|
||||
opped clients CURRENTLY IN THE CHANNEL.
|
||||
|
||||
Chanfix can be invoked manually by server administrators. /msg ChanFix
|
||||
chanfix #channel is the command to do it. ChanFix will join, and treat the
|
||||
channel as if it were opless. It lowers TS by one (resulting in a deop of
|
||||
the entire channel) and re-ops the top-5 clients currently in the channel.
|
||||
The Channel Fixer won't log or actively fix channels when there's a split of
|
||||
significant size. Needless to say, the chanfix command must be used with
|
||||
caution.
|
||||
|
||||
|
||||
12. G-Lines
|
||||
|
||||
Oh yes! A G-Line section. Currently, a part of EFNet (EU-EFnet) has G-Lines
|
||||
enabled. This was decided by the EU admin community and is now mandatory
|
||||
within EU-EFnet. In order for a G-Line to be activated, three opers from
|
||||
three different servers need to issue the _exact_ same G-Line. The reason
|
||||
is not counted.
|
||||
|
||||
G-Lines work best when the EU side of EFNet is not fragmented. G-Lines
|
||||
will, however, propogate through a Hybrid 6 hub (but not a CSr hub) even
|
||||
if the hub server has G-Lines disabled. This propogation allows two halves
|
||||
of EU-EFnet to have concurrent G-Lines set even when split by US hub servers.
|
||||
|
||||
|
||||
Questions / Comments / Suggestions are welcome.
|
||||
You can e-mail me: dennisv@vuurwerk.nl
|
||||
|
||||
Best regards,
|
||||
--
|
||||
Dennis "Riedel" Vink ___~___ Email - dennisv@vuurwerk.nl
|
||||
Unix System Administrator \ | / Phone - +31 23 5111111
|
||||
Vuurwerk Internet '|.|' PGP - 0xD68A7AAB
|
||||
|
||||
And on the seventh day, He exited from append mode.
|
||||
|
||||
# $Id: operguide.txt 6 2005-09-10 01:02:21Z nenolod $
|
137
doc/opermyth.txt
137
doc/opermyth.txt
|
@ -1,137 +0,0 @@
|
|||
|
||||
Date: Thu, 30 Jul 1998 16:21:40-0700 (MST)
|
||||
To: operlist@the-project.org
|
||||
From: rayp@primenet.com (Ray Powers)
|
||||
Subject: The myths of opers....
|
||||
|
||||
I've always wanted to write something like this.. Its half rant, half
|
||||
fact, so bear with it. Hopefully it will be worth reading.
|
||||
|
||||
There's a lot of hate for opers for a lot of reasons. Some are directly
|
||||
oper related (i.e. 99% of us are colossal assholes), some are directly
|
||||
user related (i.e. 99% of you are raving lunatics), and some is just plain
|
||||
misconceptions. I'd like to take a minute to talk about part three in
|
||||
hopes of clearing a few things up. This will kind of be in a FAQ form,
|
||||
maybe you'll like it, maybe not, but its worth a shot.
|
||||
|
||||
Q: What can an oper on EFnet do.
|
||||
A: This is an EXACT list of what we can do:
|
||||
1) /squit a server, separating it from the rest of the net
|
||||
2) /die our server
|
||||
3) /kill a user, this disconnects them from the server they are on
|
||||
4) /kline a hostmask, this bans them from our server
|
||||
5) /dline an ip, this bans them from our server, regardless of
|
||||
hostmask
|
||||
6) See all invisible users on our server
|
||||
7) Mass Msg/CTCP/notice a hostmask
|
||||
8) Mass Msg/CTCP/notice a server
|
||||
9) See and send Operwall/wallops notices
|
||||
|
||||
That's it. We can see more server messages than you, but that's not the
|
||||
point.. The point to be shown here is very simple, *none* of these things
|
||||
have anything to do with channels. Which leads us to our next question.
|
||||
|
||||
Q: What can opers *NOT* do, but keep being asked to anyways?
|
||||
A: We can *NOT*:
|
||||
1) Enter a channel that is +i or +k without being invited or
|
||||
having the key
|
||||
2) See who is inside a +s channel
|
||||
3) Op ourselves or op you on a channel (unless of course we are a
|
||||
channel op for that channel)
|
||||
4) Tell you what XXXX's new nick is since they changed it to hide
|
||||
from you.
|
||||
5) Deop someone for you on a channel (unless of course we are a
|
||||
channel op for that channel)
|
||||
|
||||
Notice a trend, with the exception of 4, all of these are 100% channel
|
||||
related. EFnet is made so that opers have *NO* power of channels, for
|
||||
better or worse. If we don't help you with these requests, its not because
|
||||
we won't, its because we are completely incapable doing so. On the other
|
||||
hand....
|
||||
|
||||
Q: What can opers do, but won't?
|
||||
A: This will be a bit differently done, because I figure I should explain
|
||||
why opers don't do these things, when they may normally make sense.
|
||||
1) Why won't they kill somebody who has stolen your nick.
|
||||
EFnet has gone on the basis of nicks not being owned, which is
|
||||
why there is no nickserv on EFnet. Of course we see opers kill
|
||||
all the time for nicks, though, so it seems rather hypocrital,
|
||||
doesn't it?
|
||||
An oper who kills for his nick will tell you its because the
|
||||
other person was a bot, was juping his nick, or was imitating an
|
||||
oper. It may be true, but it really comes down to the same
|
||||
feeling you get when your nick is taken "Hey! that's my name! I
|
||||
don't want that person using my name!"
|
||||
I personally, do not kill for nicks. If someone takes my nick,
|
||||
they can have it. Let them get my several hundred messages a day.
|
||||
:P But the problem with the oper is this: How does an oper know
|
||||
that you are really the person that uses that nick, or are you
|
||||
the guy that wants to nick jupe that nick out from the real guy?
|
||||
Unless the oper knows you well, they don't.. And saying that
|
||||
people generally tell the truth means you haven't been on EFnet
|
||||
very long.
|
||||
I would prefer to think I am one of the more well respected
|
||||
people on the net and people still lie to me on a regular basis.
|
||||
So, the oper is stuck refusing to help because he can't tell who
|
||||
is who. Remember this line of reasoning, its going to be coming
|
||||
up a lot. :P
|
||||
2) Why won't they kill that guy nuking/smurfing/ping -f'ing me?
|
||||
This one is simple. There is no way to prove that somebody is
|
||||
doing any of these things to you from an opers point of view. All
|
||||
logs are fakeable, and the oper has no way to firsthand prove its
|
||||
happening. Your best bet in this situation is to log what you can
|
||||
and complain loud and long to their ISPs.
|
||||
3) Why won't they help me take my channel back?
|
||||
There's a bunch of answers to this. First, it is popular
|
||||
opinion at EFnet that channels are not owned, and therefore, if
|
||||
you lose a channel, you should go make another one. Notice I
|
||||
say popular instead of official, because EFnet has never had an
|
||||
"official" policy on much of anything.
|
||||
But more and more you see opers killing for takeovers, so why
|
||||
are they helping their channels and not yours.
|
||||
Well, first, let's say your channel was taken over, and is now
|
||||
+smtinlk. How exactly is the oper supposed to find out who is
|
||||
oped in the channel right now to mass kill them? Even if they do get
|
||||
all the nicks, they have to somehow manage to kill them all in
|
||||
one hit, or they'll all just op each other again and it will be
|
||||
fruitless. Or worse, they could have it all set up, and some
|
||||
other oper could kill them halfway through because they don't
|
||||
like mass-kills and it would be all ruined.
|
||||
Or, let's say the mass-kill goes off, then the channel is
|
||||
opless and generally speaking, chaos begins. People start
|
||||
mass-nuking or flooding the channel to clear it out, or just to
|
||||
be annoying. And there's still a 50/50 chance that takeover
|
||||
people will get the channel back on a split and we'll have to try
|
||||
to do it all over again.
|
||||
If you're about to ask why they don't split their server,
|
||||
the answer is very simple: We are not about to screw up roughly
|
||||
30,000 peoples chatting for your channel. Its rude. This of
|
||||
course is all based on the fact that we can prove its taken over,
|
||||
as per the conversation about nicks, we often can't.
|
||||
4) But.. its obvious they took it from me! The topic says
|
||||
"Ha ha, we took your channel Rick!" for Pete's sake! And
|
||||
there's only One op, so you can kill him and get the channel
|
||||
back immediately!
|
||||
This one is a bit more complex, but its really a personal
|
||||
call. That one op could be a rampant smurfpup with a penis so
|
||||
tiny he has no choice but to rampantly smurf and synflood anyone
|
||||
that gets in his way. This is popularly known on irc as SPS, or
|
||||
Small Penis Syndrome. In this case, if the oper does help you
|
||||
out, they could end up with their server being downed for a day
|
||||
or two, and it really isn't worth it for your channel, no
|
||||
offense.
|
||||
|
||||
Keep in mind that this is all spoken from the perspective of someone who
|
||||
*DOES* help with channels when possible, but understands greatly the
|
||||
reasons not to, and judges each situation very carefully.
|
||||
|
||||
That's the gist of the information I was trying to get across. If you
|
||||
were cluefull enough to get on operlist, a lot of this may be common
|
||||
knowledge to you, but sometimes its good to step back and see why opers do
|
||||
what they do a lot of the time.
|
||||
|
||||
Hoping this is of value to SOMEONE....
|
||||
|
||||
Ray Powers
|
||||
Monkster/MimePunk/PrimeMonk/PacMonk/MtgMonk/Ihavefartoomanynickstonickjupe
|
||||
|
23
doc/readme.txt
Normal file
23
doc/readme.txt
Normal file
|
@ -0,0 +1,23 @@
|
|||
Here is the overview of the documents in the doc/ directory.
|
||||
|
||||
Subdirectories:
|
||||
|
||||
features/ - Documents about features and standards
|
||||
technical/ - Technical documents about ircd internals and
|
||||
protocol information
|
||||
sgml/ - SGML documentation
|
||||
|
||||
Files:
|
||||
|
||||
ircd.conf.example - An example ircd.conf file describing most of the
|
||||
user settable options
|
||||
ircd.motd - A default ircd.motd used by make install
|
||||
reference.conf - A complete example showing all possible config
|
||||
options
|
||||
credits-past.txt - Credits for the predecessors to Charybdis
|
||||
logfiles.txt - Description of formatting of some logfiles
|
||||
server-version-info.txt - Overview of the flags shown in /version
|
||||
|
||||
Also in the contrib/ directory you will find:
|
||||
example_module.c - An example module, detailing what the code in a module
|
||||
does. Useful for building your own modules.
|
|
@ -1,4 +1,4 @@
|
|||
/* doc/reference.conf - charybdis Example configuration file
|
||||
/* doc/reference.conf - solanum example configuration file
|
||||
*
|
||||
* Copyright (C) 2000-2002 Hybrid Development Team
|
||||
* Copyright (C) 2002-2005 ircd-ratbox development team
|
||||
|
@ -6,7 +6,6 @@
|
|||
*
|
||||
* Written by ejb, wcampbel, db, leeh and others
|
||||
*
|
||||
* $Id: reference.conf 3582 2007-11-17 21:55:48Z jilles $
|
||||
*/
|
||||
|
||||
/* IMPORTANT NOTES:
|
||||
|
@ -27,6 +26,10 @@
|
|||
* .include "filename"
|
||||
* .include <filename>
|
||||
*
|
||||
* Flags variables are comma-separated sets of predefined values,
|
||||
* specific to each block. For example in operator {} blocks:
|
||||
* flags = encrypted, encrypted;
|
||||
*
|
||||
* Times/durations are written as:
|
||||
* 12 hours 30 minutes 1 second
|
||||
*
|
||||
|
@ -44,6 +47,7 @@
|
|||
* Charybdis contains several extensions that are not enabled by default.
|
||||
* To use them, uncomment the lines below.
|
||||
*
|
||||
<<<<<<< .merge_file_UmjhEh
|
||||
* Channel mode +-A (admin only) -- chm_adminonly.so
|
||||
* Channel mode +-O (oper only) -- chm_operonly.so
|
||||
* Channel mode +-S (ssl only) -- chm_sslonly.so
|
||||
|
@ -105,6 +109,73 @@
|
|||
#loadmodule "extensions/sno_whois.so";
|
||||
#loadmodule "extensions/override.so";
|
||||
#loadmodule "extensions/no_kill_services.so";
|
||||
=======
|
||||
* Channel mode +-A (admin only) -- chm_adminonly
|
||||
* Channel mode +-T (blocks notices) -- chm_nonotice
|
||||
* Channel mode +-O (oper only) -- chm_operonly
|
||||
* Channel mode +-S (ssl only) -- chm_sslonly
|
||||
* Channel mode +-M (disallow KICK on IRC ops) -- chm_operpeace
|
||||
* Restrict channel creation to logged in users -- createauthonly
|
||||
* Account bans (+b $a[:mask]) -- extb_account
|
||||
* Banned from another channel (+b $j:mask) -- extb_canjoin
|
||||
* Other-channel bans (+b $c:mask) -- extb_channel
|
||||
* Combination extbans -- extb_combi
|
||||
* Extended ban (+b $x:mask) -- extb_extgecos
|
||||
* Hostmask bans (for combination extbans) -- extb_hostmask
|
||||
* Oper bans (+b $o) -- extb_oper
|
||||
* Realname (gecos) bans (+b $r:mask) -- extb_realname
|
||||
* Server bans (+b $s:mask) -- extb_server
|
||||
* SSL bans (+b $z) -- extb_ssl
|
||||
* User mode bans (+b $u:modes) -- extb_usermode
|
||||
* Helpops system (umode +h) -- helpops
|
||||
* HURT system -- hurt
|
||||
* New host mangling (umode +x) -- ip_cloaking_4.0
|
||||
* Old host mangling (umode +h) -- ip_cloaking
|
||||
* Dynamically extend channel limits -- m_extendchans
|
||||
* Find channel forwards -- m_findforwards
|
||||
* /identify support -- m_identify
|
||||
* /locops support -- m_locops
|
||||
* Opers cannot be invisible (umode +i) -- no_oper_invis
|
||||
* Far connection notices (snomask +F) -- sno_farconnect
|
||||
* Remote oper up notices -- sno_globaloper
|
||||
* Global nick-change notices -- sno_globalnickchange
|
||||
* Oper-override (modehacking only) -- override
|
||||
* Stop services kills -- no_kill_services
|
||||
* Allows you to hide your idle time (umode +I) -- umode_hide_idle_time
|
||||
*/
|
||||
#loadmodule "extensions/chm_adminonly";
|
||||
#loadmodule "extensions/chm_nonotice";
|
||||
#loadmodule "extensions/chm_operonly";
|
||||
#loadmodule "extensions/chm_sslonly";
|
||||
#loadmodule "extensions/chm_operpeace";
|
||||
#loadmodule "extensions/createauthonly";
|
||||
#loadmodule "extensions/extb_account";
|
||||
#loadmodule "extensions/extb_canjoin";
|
||||
#loadmodule "extensions/extb_channel";
|
||||
#loadmodule "extensions/extb_combi";
|
||||
#loadmodule "extensions/extb_extgecos";
|
||||
#loadmodule "extensions/extb_hostmask";
|
||||
#loadmodule "extensions/extb_oper";
|
||||
#loadmodule "extensions/extb_realname";
|
||||
#loadmodule "extensions/extb_server";
|
||||
#loadmodule "extensions/extb_ssl";
|
||||
#loadmodule "extensions/extb_usermode";
|
||||
#loadmodule "extensions/helpops";
|
||||
#loadmodule "extensions/hurt";
|
||||
#loadmodule "extensions/ip_cloaking_4.0";
|
||||
#loadmodule "extensions/ip_cloaking";
|
||||
#loadmodule "extensions/m_extendchans";
|
||||
#loadmodule "extensions/m_findforwards";
|
||||
#loadmodule "extensions/m_identify";
|
||||
#loadmodule "extensions/m_locops";
|
||||
#loadmodule "extensions/no_oper_invis";
|
||||
#loadmodule "extensions/sno_farconnect";
|
||||
#loadmodule "extensions/sno_globalnickchange";
|
||||
#loadmodule "extensions/sno_globaloper";
|
||||
#loadmodule "extensions/override";
|
||||
#loadmodule "extensions/no_kill_services";
|
||||
#loadmodule "extensions/umode_hide_idle_time";
|
||||
>>>>>>> .merge_file_Mh5Whq
|
||||
|
||||
/* serverinfo {}: Contains information about the server. (OLD M:) */
|
||||
serverinfo {
|
||||
|
@ -129,11 +200,6 @@ serverinfo {
|
|||
*/
|
||||
network_name = "MyNet";
|
||||
|
||||
/* hub: allow this server to act as a hub and have multiple servers
|
||||
* connected to it.
|
||||
*/
|
||||
hub = no;
|
||||
|
||||
/* vhost: the IP to bind to when we connect outward to ipv4 servers.
|
||||
* This should be an ipv4 IP only.
|
||||
*/
|
||||
|
@ -143,18 +209,26 @@ serverinfo {
|
|||
* This should be an ipv6 IP only.
|
||||
*/
|
||||
#vhost6 = "2001:db8:2::6";
|
||||
<<<<<<< .merge_file_UmjhEh
|
||||
|
||||
/* ssl_private_key: our ssl private key */
|
||||
ssl_private_key = "etc/ssl.key";
|
||||
=======
|
||||
>>>>>>> .merge_file_Mh5Whq
|
||||
|
||||
/* ssl_cert: certificate for our ssl server */
|
||||
/* ssl_cert: certificate (and optionally key) for our ssl server */
|
||||
ssl_cert = "etc/ssl.pem";
|
||||
|
||||
/* ssl_dh_params: DH parameters, generate with openssl dhparam -out dh.pem 1024 */
|
||||
/* ssl_private_key: our ssl private key (if not contained in ssl_cert file) */
|
||||
#ssl_private_key = "etc/ssl.key";
|
||||
|
||||
/* ssl_dh_params: DH parameters, generate with openssl dhparam -out dh.pem 2048 */
|
||||
/* If you do not provide parameters, some TLS backends will fail on DHE- ciphers,
|
||||
and some will succeed but use weak, common DH groups! */
|
||||
ssl_dh_params = "etc/dh.pem";
|
||||
|
||||
/* ssl_cipher_list: A list of ciphers, dependent on your TLS backend */
|
||||
#ssl_cipher_list = "EECDH+HIGH:EDH+HIGH:HIGH:!aNULL";
|
||||
#ssl_cipher_list = "TLS_CHACHA20_POLY1305_SHA256:EECDH+HIGH:EDH+HIGH:HIGH:!aNULL";
|
||||
|
||||
/* ssld_count: number of ssld processes you want to start, if you
|
||||
* have a really busy server, using N-1 where N is the number of
|
||||
|
@ -282,14 +356,17 @@ class "server" {
|
|||
*/
|
||||
connectfreq = 5 minutes;
|
||||
|
||||
/* max number: the amount of servers to autoconnect to. if the number
|
||||
/* max_autoconn: the amount of servers to autoconnect to. if the number
|
||||
* of servers in the class is or exceeds this, no more servers in the
|
||||
* class are autoconnected. oper initiated connects are unaffected.
|
||||
* this should usually be set to either 0 or 1. (autoconnecting from
|
||||
* hubs to leaves may cause leaves to function as hubs by having
|
||||
* multiple servers connected to them.)
|
||||
*/
|
||||
max_number = 1;
|
||||
max_autoconn = 1;
|
||||
|
||||
/* max_number: the maximum number of servers allowed in this class */
|
||||
max_number = 100;
|
||||
|
||||
/* sendq: servers need a higher sendq as they are sent more data */
|
||||
sendq = 2 megabytes;
|
||||
|
@ -316,8 +393,8 @@ listen {
|
|||
/* port: listen on all available IPs, ports 5000 and 6665 to 6669 */
|
||||
port = 5000, 6665 .. 6669;
|
||||
|
||||
/* sslport: listen for ssl connections on all available IPs, port 9999 */
|
||||
sslport = 9999;
|
||||
/* sslport: listen for ssl connections on all available IPs, port 6697 */
|
||||
sslport = 6697;
|
||||
|
||||
/* host: set a specific IP/host the ports after the line will listen
|
||||
* on. This may be ipv4 or ipv6.
|
||||
|
@ -329,10 +406,21 @@ listen {
|
|||
host = "2001:db8:2::6";
|
||||
port = 7002;
|
||||
sslport = 9002;
|
||||
|
||||
/* wsock: listeners defined with this option enabled will be websocket listeners,
|
||||
* and will not accept normal clients.
|
||||
*/
|
||||
wsock = yes;
|
||||
sslport = 9999;
|
||||
};
|
||||
|
||||
/* auth {}: allow users to connect to the ircd (OLD I:) */
|
||||
auth {
|
||||
/* description: descriptive text to help recognize this auth block in
|
||||
* stats i output.
|
||||
*/
|
||||
description = "example oper";
|
||||
|
||||
/* user: the user@host allowed to connect. Multiple IPv4/IPv6 user
|
||||
* lines are permitted per auth block. This is matched against the
|
||||
* hostname and IP address (using :: shortening for IPv6 and
|
||||
|
@ -342,6 +430,11 @@ auth {
|
|||
user = "*@198.51.100.0/24";
|
||||
user = "*test@2001:db8:1:*";
|
||||
|
||||
/* umodes; the user mode character string to apply to users
|
||||
* when they get placed into this auth block.
|
||||
*/
|
||||
#umodes = "+w";
|
||||
|
||||
/* auth_user: This allows specifying a username:password instead of
|
||||
* just a password in PASS, so that a fixed user@host is not
|
||||
* necessary for a specific auth{} block.
|
||||
|
@ -365,8 +458,10 @@ auth {
|
|||
* encrypted | password is encrypted with mkpasswd
|
||||
* spoof_notice | give a notice when spoofing hosts
|
||||
* exceed_limit (old > flag) | allow user to exceed class user limits
|
||||
* kline_exempt (old ^ flag) | exempt this user from k/g/xlines&dnsbls
|
||||
* kline_exempt (old ^ flag) | exempt this user from k/g/xlines,
|
||||
* | dnsbls, and proxies
|
||||
* dnsbl_exempt | exempt this user from dnsbls
|
||||
* proxy_exempt | exempt this user from proxies
|
||||
* spambot_exempt | exempt this user from spambot checks
|
||||
* shide_exempt | exempt this user from serverhiding
|
||||
* jupe_exempt | exempt this user from generating
|
||||
|
@ -378,6 +473,9 @@ auth {
|
|||
* need_ident (old + flag) | require ident for user in this class
|
||||
* need_ssl | require SSL/TLS for user in this class
|
||||
* need_sasl | require SASL id for user in this class
|
||||
* extend_chans | allow this user to join more channels than normal
|
||||
* kline_spoof_ip | if this block has a spoof host, klines match only
|
||||
* | the spoof and not the underlying IP
|
||||
*/
|
||||
flags = kline_exempt, exceed_limit;
|
||||
|
||||
|
@ -411,8 +509,15 @@ privset "local_op" {
|
|||
*
|
||||
* Available options:
|
||||
*
|
||||
* oper:local_kill: allows local users to be /KILL'd
|
||||
* oper:global_kill: allows local and remote users to be /KILL'd
|
||||
* oper:general: enable most general oper privileges that came
|
||||
* with +o in older releases
|
||||
* auspex:oper: allows the oper to see through oper hiding
|
||||
* auspex:umodes: allows viewing other users' modes
|
||||
* auspex:cmodes: shows privileged cmodes
|
||||
* auspex:hostname: shows hidden hostnames/ips
|
||||
* oper:privs: allows /stats o/O and seeing privset in /whois
|
||||
* oper:testline: allows /testline and /testgecos
|
||||
* oper:kill: allows local and remote users to be /KILL'd
|
||||
* oper:routing: allows remote SQUIT and CONNECT
|
||||
* oper:kline: allows KLINE and DLINE
|
||||
* oper:unkline: allows UNKLINE and UNDLINE
|
||||
|
@ -426,15 +531,33 @@ privset "local_op" {
|
|||
* will not have the admin lines in
|
||||
* whois.
|
||||
* oper:xline: allows use of /quote xline/unxline
|
||||
* oper:resv: allows /quote resv/unresv and cmode +LP
|
||||
* oper:resv: allows /quote resv/unresv
|
||||
* oper:cmodes: allows cmode +LP
|
||||
* oper:operwall: allows the oper to send/receive operwalls
|
||||
* oper:spy: allows 'operspy' features to see through +s
|
||||
* channels etc. see /quote help operspy
|
||||
* oper:hidden: hides the oper from /stats p
|
||||
* oper:remoteban: allows remote kline etc
|
||||
* oper:mass_notice: allows sending wallops and mass notices
|
||||
* oper:mass_notice: allows sending mass notices
|
||||
* oper:wallops: allows sending wallops messages
|
||||
* oper:grant: allows using the GRANT command
|
||||
* usermode:servnotice: allows setting +s
|
||||
* oper:message: allows opers to bypass CALLERID (usermode +g)
|
||||
* oper:free_target: messages to the oper bypass flood controls
|
||||
*
|
||||
* Privileges provided by extensions include:
|
||||
*
|
||||
* oper:dehelper: allows the DEHELPER command (from extensions/helpops)
|
||||
* oper:override: enables oper override via umode +p (from extensions/override)
|
||||
* oper:receive_immunity:
|
||||
* confers the benefits of chmode +M (operpeace) (from extensions/chm_operpeace)
|
||||
* usermode:helpops allows setting +h (from extensions/helpops)
|
||||
* auspex:usertimes:
|
||||
* allows viewing user idle/connect times even when +I is set (from extensions/umode_hide_idle_time)
|
||||
* oper:shedding: allows the SHEDDING command (from extensions/m_shedding)
|
||||
*/
|
||||
privs = oper:local_kill, oper:operwall;
|
||||
privs = oper:general, oper:privs, oper:testline, oper:kill, oper:operwall, oper:message,
|
||||
usermode:servnotice, auspex:oper, auspex:hostname, auspex:umodes, auspex:cmodes;
|
||||
};
|
||||
|
||||
privset "server_bot" {
|
||||
|
@ -445,13 +568,14 @@ privset "server_bot" {
|
|||
|
||||
privset "global_op" {
|
||||
extends = "local_op";
|
||||
privs = oper:global_kill, oper:routing, oper:kline, oper:unkline, oper:xline,
|
||||
oper:resv, oper:mass_notice, oper:remoteban;
|
||||
privs = oper:routing, oper:kline, oper:unkline, oper:xline,
|
||||
oper:resv, oper:cmodes, oper:mass_notice, oper:wallops,
|
||||
oper:remoteban;
|
||||
};
|
||||
|
||||
privset "admin" {
|
||||
extends = "global_op";
|
||||
privs = oper:admin, oper:die, oper:rehash, oper:spy;
|
||||
privs = oper:admin, oper:die, oper:rehash, oper:spy, oper:grant;
|
||||
};
|
||||
|
||||
/* operator {}: defines ircd operators. (OLD O:) */
|
||||
|
@ -510,12 +634,21 @@ operator "god" {
|
|||
privset = "admin";
|
||||
};
|
||||
|
||||
/* connect {}: controls servers we connect to (OLD C:, N:, H:, L:) */
|
||||
/* connect {}: controls servers we connect with (OLD C:, N:, H:, L:).
|
||||
*
|
||||
* This configuration is used whether connections are incoming or
|
||||
* outgoing.
|
||||
*/
|
||||
connect "irc.uplink.com" {
|
||||
/* the name must go above */
|
||||
/* the name of the other server must go above. It should match the
|
||||
* other server's name in its serverinfo {} block, and does not
|
||||
* need to be an actual hostname.
|
||||
*/
|
||||
|
||||
/* host: the host or IP to connect to. If a hostname is used it
|
||||
* must match the reverse dns of the server.
|
||||
/* host: the host or IP to connect to.
|
||||
*
|
||||
* It is also used to validate incoming connections. If a hostname
|
||||
* is used, it must match the reverse dns of the server.
|
||||
*/
|
||||
host = "203.0.113.3";
|
||||
|
||||
|
@ -539,65 +672,44 @@ connect "irc.uplink.com" {
|
|||
/* port: the port to connect to this server on */
|
||||
port = 6666;
|
||||
|
||||
/* hub mask: the mask of servers that this server may hub. Multiple
|
||||
* entries are permitted
|
||||
*/
|
||||
hub_mask = "*";
|
||||
|
||||
/* leaf mask: the mask of servers this server may not hub. Multiple
|
||||
* entries are permitted. Useful for forbidding EU -> US -> EU routes.
|
||||
*/
|
||||
#leaf_mask = "*.uk";
|
||||
|
||||
/* class: the class this server is in */
|
||||
class = "server";
|
||||
|
||||
/* flags: controls special options for this server
|
||||
* encrypted - marks the accept_password as being crypt()'d
|
||||
* autoconn - automatically connect to this server
|
||||
* compressed - compress traffic via ziplinks
|
||||
* topicburst - burst topics between servers
|
||||
* ssl - ssl/tls encrypted server connections
|
||||
* sctp - use SCTP instead of TCP to connect to the server
|
||||
* no-export - marks the link as a no-export link (not exported to other links)
|
||||
*/
|
||||
flags = compressed, topicburst;
|
||||
flags = topicburst;
|
||||
};
|
||||
|
||||
connect "ipv6.some.server" {
|
||||
/* Hosts that are IPv6 addresses must be in :: shortened form
|
||||
* if applicable. Addresses starting with a colon get an extra
|
||||
* zero prepended, for example: 0::1
|
||||
*/
|
||||
connect "ipv6.lame.server" {
|
||||
host = "192.0.2.1";
|
||||
host = "2001:db8:3::8";
|
||||
send_password = "password";
|
||||
accept_password = "password";
|
||||
port = 6666;
|
||||
|
||||
/* aftype: controls whether the connection uses "ipv4" or "ipv6".
|
||||
* Default is ipv4.
|
||||
/* aftype: controls whether the outgoing connection uses "ipv4" or "ipv6".
|
||||
* Default is to try either at random.
|
||||
*/
|
||||
aftype = ipv6;
|
||||
class = "server";
|
||||
};
|
||||
|
||||
connect "ssl.uplink.com" {
|
||||
/* Example of ssl server-to-server connection, ssl flag doesn't need
|
||||
* compressed flag, 'cause it uses own compression
|
||||
*/
|
||||
host = "203.0.113.129";
|
||||
send_password = "password";
|
||||
accept_password = "anotherpassword";
|
||||
port = 9999;
|
||||
hub_mask = "*";
|
||||
class = "server";
|
||||
flags = ssl, topicburst;
|
||||
};
|
||||
|
||||
/* cluster {}; servers that we propagate things to automatically.
|
||||
* NOTE: This does NOT grant them privileges to apply anything locally,
|
||||
* you must add a seperate shared block for that. Clustering will
|
||||
* only be done for actions by LOCAL opers, that arent directed
|
||||
* remotely.
|
||||
*/
|
||||
/* cluster {}; servers that we propagate things to automatically. */
|
||||
cluster {
|
||||
/* name: the server to share with, this can be a wildcard and may be
|
||||
* stacked.
|
||||
|
@ -630,8 +742,7 @@ cluster {
|
|||
|
||||
/* service{}: privileged servers (services). These servers have extra
|
||||
* privileges such as setting login names on users and introducing clients
|
||||
* with umode +S (unkickable, hide channels, etc). This does not allow them
|
||||
* to set bans, you need a separate shared{} for that.
|
||||
* with umode +S (unkickable, hide channels, etc).
|
||||
* Do not place normal servers here.
|
||||
* There may be only one service{} block.
|
||||
*/
|
||||
|
@ -640,56 +751,6 @@ service {
|
|||
name = "services.int";
|
||||
};
|
||||
|
||||
/* shared {}: users that are allowed to place remote bans on our server.
|
||||
* NOTE: These are ordered top down. The first one the user@host and server
|
||||
* matches will be used. Their access will then be decided on that
|
||||
* block and will not fall back to another block that matches.
|
||||
*/
|
||||
shared {
|
||||
/* oper: the user@host and server the user must be on to set klines.
|
||||
* The first field must be a user@host, the second field is an
|
||||
* optional server. These may be stacked.
|
||||
*/
|
||||
/* flags: list of what to allow them to place, all the oper lines
|
||||
* above this (up until another flags entry) will receive these
|
||||
* flags. This *must* be present.
|
||||
*
|
||||
* kline - allow setting perm/temp klines
|
||||
* tkline - allow setting temp klines
|
||||
* unkline - allow removing klines
|
||||
* xline - allow setting perm/temp xlines
|
||||
* txline - allow setting temp xlines
|
||||
* unxline - allow removing xlines
|
||||
* resv - allow setting perm/temp resvs
|
||||
* tresv - allow setting temp resvs
|
||||
* unresv - allow removing xlines
|
||||
* all - allow oper/server to do all of above.
|
||||
* locops - allow locops - only used for servers who cluster
|
||||
* rehash - allow rehashing
|
||||
* dline - allow setting perm/temp dlines
|
||||
* tdline - allow setting temp dlines
|
||||
* undline - allow removing dlines
|
||||
* none - disallow everything
|
||||
*/
|
||||
|
||||
/* allow flame@*.leeh.co.uk on server irc.ircd-ratbox.org and
|
||||
* allow leeh@*.leeh.co.uk on server ircd.ircd-ratbox.org to kline
|
||||
*/
|
||||
oper = "flame@*.leeh.co.uk", "irc.ircd-ratbox.org";
|
||||
oper = "leeh@*.leeh.co.uk", "ircd.ircd-ratbox.org";
|
||||
flags = kline;
|
||||
|
||||
/* you may forbid certain opers/servers from doing anything */
|
||||
oper = "irc@vanity.oper", "*";
|
||||
oper = "*@*", "irc.vanity.server";
|
||||
oper = "irc@another.vanity.oper", "bigger.vanity.server";
|
||||
flags = none;
|
||||
|
||||
/* or allow everyone to place temp klines */
|
||||
oper = "*@*";
|
||||
flags = tkline;
|
||||
};
|
||||
|
||||
/* exempt {}: IPs that are exempt from Dlines and rejectcache. (OLD d:) */
|
||||
exempt {
|
||||
ip = "192.0.2.0/24";
|
||||
|
@ -698,6 +759,12 @@ exempt {
|
|||
ip = "127.0.0.1";
|
||||
};
|
||||
|
||||
/* secure {}: IPs that are considered to be secure networks, and get
|
||||
* +Z without using TLS */
|
||||
secure {
|
||||
ip = "127.0.0.1";
|
||||
};
|
||||
|
||||
/* The channel block contains options pertaining to channels */
|
||||
channel {
|
||||
/* invex: Enable/disable channel mode +I, a n!u@h list of masks
|
||||
|
@ -735,6 +802,9 @@ channel {
|
|||
/* max chans: The maximum number of channels a user can join/be on. */
|
||||
max_chans_per_user = 15;
|
||||
|
||||
/* max chans (large): The extended maximum number of channels a user can join. */
|
||||
max_chans_per_user_large = 60;
|
||||
|
||||
/* max bans: maximum number of +b/e/I/q modes in a channel */
|
||||
max_bans = 100;
|
||||
|
||||
|
@ -810,6 +880,22 @@ channel {
|
|||
* such as LIST >0.
|
||||
*/
|
||||
displayed_usercount = 3;
|
||||
|
||||
/* strip_topic_colors: whether or not color codes in TOPIC should be stripped. */
|
||||
strip_topic_colors = no;
|
||||
|
||||
/* opmod_send_statusmsg: format messages sent to ops due to +z
|
||||
* as PRIVMSG @#channel when sent to clients.
|
||||
*/
|
||||
opmod_send_statusmsg = no;
|
||||
|
||||
/* ip_bans_through_vhost: should channel IP bans see through dynamic spoofed hosts? */
|
||||
ip_bans_through_vhost = yes;
|
||||
|
||||
/* invite_notify_notice: when using extensions/invite_notify, should
|
||||
* we send a NOTICE to clients that don't support IRCv3 invite-notify
|
||||
*/
|
||||
invite_notify_notice = yes;
|
||||
};
|
||||
|
||||
|
||||
|
@ -841,8 +927,7 @@ serverhide {
|
|||
* You can have multiple combinations of host and rejection reasons.
|
||||
* They are used in pairs of one host/rejection reason.
|
||||
*
|
||||
* These settings should be adequate for most networks, and are (presently)
|
||||
* required for use on StaticBox.
|
||||
* These settings should be adequate for most networks.
|
||||
*
|
||||
* Word to the wise: Do not use blacklists like SPEWS for blocking IRC
|
||||
* connections.
|
||||
|
@ -883,6 +968,78 @@ blacklist {
|
|||
# reject_reason = "${nick}, your IP (${ip}) is listed in ${dnsbl-host} for some reason. In order to protect ${network-name} from abuse, we are not allowing connections listed in ${dnsbl-host} to connect";
|
||||
};
|
||||
|
||||
/* These are the OPM settings.
|
||||
* This is similar to the functionality provided by BOPM. It will scan incoming
|
||||
* connections for open proxies by connecting to clients and attempting several
|
||||
* different open proxy handshakes. If they connect back to us (via a dedicated
|
||||
* listening port), and send back the data we send them, they are considered
|
||||
* an open proxy. For politeness reasons (users may be confused by the incoming
|
||||
* connection attempts if they are logging incoming connections), the user is
|
||||
* notified upon connect if they are being scanned.
|
||||
*
|
||||
* WARNING:
|
||||
* These settings are considered experimental. Only the most common proxy types
|
||||
* are checked for (Charybdis is immune from POST and GET proxies). If you are
|
||||
* not comfortable with experimental code, do not use this feature.
|
||||
*/
|
||||
#opm {
|
||||
/* IPv4 address to listen on. This must be a publicly facing IP address
|
||||
* to be effective.
|
||||
* If omitted, it defaults to serverinfo::vhost.
|
||||
*/
|
||||
#listen_ipv4 = "127.0.0.1";
|
||||
|
||||
/* IPv4 port to listen on.
|
||||
* This should not be the same as any existing listeners.
|
||||
*/
|
||||
#port_v4 = 32000;
|
||||
|
||||
/* IPv6 address to listen on. This must be a publicly facing IP address
|
||||
* to be effective.
|
||||
* If omitted, it defaults to serverinfo::vhost6.
|
||||
*/
|
||||
#listen_ipv6 = "::1";
|
||||
|
||||
/* IPv6 port to listen on.
|
||||
* This should not be the same as any existing listeners.
|
||||
*/
|
||||
#port_v6 = 32000;
|
||||
|
||||
/* You can also set the listen_port directive which will set both the
|
||||
* IPv4 and IPv6 ports at once.
|
||||
*/
|
||||
#listen_port = 32000;
|
||||
|
||||
/* This sets the timeout in seconds before ending open proxy scans.
|
||||
* Values less than 1 or greater than 60 are ignored.
|
||||
* It is advisable to keep it as short as feasible, so clients do not
|
||||
* get held up by excessively long scan times.
|
||||
*/
|
||||
#timeout = 5;
|
||||
|
||||
/* These are the ports to scan for SOCKS4 proxies on. They may overlap
|
||||
* with other scan types. Sensible defaults are given below.
|
||||
*/
|
||||
#socks4_ports = 80, 443, 1080, 8000, 8080, 10800;
|
||||
|
||||
/* These are the ports to scan for SOCKS5 proxies on. They may overlap
|
||||
* with other scan types. Sensible defaults are given below.
|
||||
*/
|
||||
#socks5_ports = 80, 443, 1080, 8000, 8080, 10800;
|
||||
|
||||
/* These are the ports to scan for HTTP CONNECT proxies on (plaintext).
|
||||
* They may overlap with other scan types. Sensible defaults are given
|
||||
* below.
|
||||
*/
|
||||
#httpconnect_ports = 80, 8080, 8000;
|
||||
|
||||
/* These are the ports to scan for HTTPS CONNECT proxies on (SSL).
|
||||
* They may overlap with other scan types. Sensible defaults are given
|
||||
* below.
|
||||
*/
|
||||
#httpsconnect_ports = 443, 4443;
|
||||
#};
|
||||
|
||||
/*
|
||||
* Alias blocks allow you to define custom commands. (Old m_sshortcut.c)
|
||||
* They send PRIVMSG to the given target. A real command takes
|
||||
|
@ -1085,22 +1242,66 @@ general {
|
|||
*/
|
||||
dline_with_reason = yes;
|
||||
|
||||
/* kline delay: delay the checking of klines until a specified time.
|
||||
* Useful if large kline lists are applied often to prevent the
|
||||
* server eating CPU.
|
||||
*/
|
||||
kline_delay = 0 seconds;
|
||||
|
||||
/* kline reason: show the user the reason why they are k/dlined
|
||||
* on exit. may give away who set k/dline when set via tcm.
|
||||
*/
|
||||
kline_with_reason = yes;
|
||||
|
||||
/* tkline duration: when showing users their k/dline reason (see
|
||||
* kline_with_reason), don't add "Temporary K-line 123 min."
|
||||
*/
|
||||
hide_tkdline_duration = no;
|
||||
|
||||
/* kline reason: make the users quit message on channels this
|
||||
* reason instead of the oper's reason.
|
||||
*/
|
||||
kline_reason = "Connection closed";
|
||||
|
||||
/* SASL access only client message: give users a message that
|
||||
* informs them
|
||||
*/
|
||||
sasl_only_client_message = "You need to identify via SASL to use this server.";
|
||||
|
||||
/* Identd access only client message: give users a message that
|
||||
* informs them
|
||||
*/
|
||||
identd_only_client_message = "You need to install identd to use this server.";
|
||||
|
||||
/* SCTP forbidden client message: give users a message that
|
||||
* informs them
|
||||
*/
|
||||
sctp_forbidden_client_message = "You are not allowed to use SCTP on this server.";
|
||||
|
||||
/* SSL/TLS access only client message: give users a message that
|
||||
* informs them
|
||||
*/
|
||||
ssltls_only_client_message = "You need to use SSL/TLS to use this server.";
|
||||
|
||||
/* Not authorised client message: tell users that they are not
|
||||
* authorised
|
||||
*/
|
||||
not_authorised_client_message = "You are not authorised to access this server.";
|
||||
|
||||
/* Illegal hostname client message: tell users that they have illegal
|
||||
* chars in their hostname
|
||||
*/
|
||||
illegal_hostname_client_message = "You have an illegal character in your hostname.";
|
||||
|
||||
/* Server full client message: tell users that the server they're connecting
|
||||
* to is full
|
||||
*/
|
||||
server_full_client_message = "Sorry, server is full - try later";
|
||||
|
||||
/* illegal name long client message: long-form explanation that their username
|
||||
* contains illegal characters
|
||||
*/
|
||||
illegal_name_long_client_message = "Your username is invalid. Please make sure that your username contains only alphanumeric characters.";
|
||||
|
||||
/* illegal name short client message: short-form notification that their username
|
||||
* contains illegal characters; will be followed by ": their_username"
|
||||
*/
|
||||
illegal_name_short_client_message = "Invalid username";
|
||||
|
||||
/* identify to services via server password
|
||||
* if auth{} block had no password but the user specified a
|
||||
* server password anyway, send a PRIVMSG to <identify_service>
|
||||
|
@ -1133,9 +1334,6 @@ general {
|
|||
/* stats c oper only: make stats c (connect {}) oper only */
|
||||
stats_c_oper_only = no;
|
||||
|
||||
/* stats h oper only: make stats h (hub_mask/leaf_mask) oper only */
|
||||
stats_h_oper_only=no;
|
||||
|
||||
/* stats y oper only: make stats y (class {}) oper only */
|
||||
stats_y_oper_only = no;
|
||||
|
||||
|
@ -1162,6 +1360,13 @@ general {
|
|||
*/
|
||||
stats_k_oper_only = masked;
|
||||
|
||||
/* stats l/L oper only:
|
||||
* yes: non-opers can't use this at all
|
||||
* self: non-opers see only themselves
|
||||
* no: show targeted users or non-hidden opers to everyone
|
||||
*/
|
||||
stats_l_oper_only = self;
|
||||
|
||||
/* map oper only: make /map oper only */
|
||||
map_oper_only = no;
|
||||
|
||||
|
@ -1202,6 +1407,13 @@ general {
|
|||
*/
|
||||
ping_cookie = no;
|
||||
|
||||
/* ping warn time: how long to wait after pinging a server before starting
|
||||
* to complain it is unresponsive. Note that the ping check interval is 30
|
||||
* seconds, so the first complaint will come at the next check after this
|
||||
* time has passed.
|
||||
*/
|
||||
ping_warn_time = 15 seconds;
|
||||
|
||||
/* connect timeout: sets how long we should wait for a connection
|
||||
* request to succeed
|
||||
*/
|
||||
|
@ -1226,6 +1438,12 @@ general {
|
|||
*/
|
||||
max_targets = 4;
|
||||
|
||||
/* post-registration delay: wait this long before processing commands from a newly
|
||||
* registered user. Used to allow network utility bots to perform any actions
|
||||
* (such as host changes or proxy scanning) before the user can join channels.
|
||||
*/
|
||||
post_registration_delay = 2 seconds;
|
||||
|
||||
/* use_whois_actually: send clients requesting a whois a numeric
|
||||
* giving the real IP of non-spoofed clients to prevent DNS abuse.
|
||||
*/
|
||||
|
@ -1233,7 +1451,7 @@ general {
|
|||
|
||||
/* usermodes configurable: a list of usermodes for the options below
|
||||
*
|
||||
* +g - callerid - Server Side Ignore
|
||||
* +g - callerid - Server-side private message allow list
|
||||
* +D - deaf - Don't see channel messages
|
||||
* +i - invisible - Not shown in NAMES or WHO unless you share a
|
||||
* a channel
|
||||
|
@ -1255,14 +1473,6 @@ general {
|
|||
* provided they have umode +s set */
|
||||
oper_snomask = "+s";
|
||||
|
||||
/* compression level: level of compression for compressed links between
|
||||
* servers.
|
||||
*
|
||||
* values are between: 1 (least compression, fastest)
|
||||
* and: 9 (most compression, slowest).
|
||||
*/
|
||||
#compression_level = 6;
|
||||
|
||||
/* burst_away: This enables bursting away messages to servers.
|
||||
* With this disabled, we will only propogate AWAY messages
|
||||
* as users send them, but never burst them. Be warned though
|
||||
|
@ -1336,6 +1546,7 @@ general {
|
|||
* "SPKI:SHA2-256:" or "SPKI:SHA2-512:" depending on the hash type. These fingerprints
|
||||
* are not supported on servers running charybdis 3.5.3 or earlier.
|
||||
*
|
||||
<<<<<<< .merge_file_UmjhEh
|
||||
* To generate a fingerprint from a certificate file, run the following:
|
||||
* $ openssl x509 -outform DER -in your.crt | sha1sum (or sha256sum, or sha512sum)
|
||||
*
|
||||
|
@ -1348,6 +1559,33 @@ general {
|
|||
* sha512sum | sed -r -e 's/^/SPKI:SHA2-512:/'
|
||||
*/
|
||||
certfp_method = sha256;
|
||||
=======
|
||||
* To generate a fingerprint from a certificate file, please use the mkfingerprint utility
|
||||
* program located in the bin/ subdirectory of your IRCd installation. Running it with no
|
||||
* arguments will give you a brief usage message; it takes method and filename arguments.
|
||||
*/
|
||||
certfp_method = spki_sha256;
|
||||
|
||||
/* hide_opers_in_whois: if set to YES, then oper status will be hidden in /WHOIS output. */
|
||||
hide_opers_in_whois = no;
|
||||
|
||||
/* hide_opers: Hide all opers from unprivileged users */
|
||||
hide_opers = no;
|
||||
|
||||
/* tls_ciphers_oper_only: show the TLS cipher string in /WHOIS only to opers and self */
|
||||
tls_ciphers_oper_only = no;
|
||||
|
||||
/* hidden_caps: client capabilities we'll pretend we don't support until they're requested */
|
||||
#hidden_caps = "userhost-in-names";
|
||||
|
||||
/* oper_secure_only: require TLS on any connection trying to oper up */
|
||||
oper_secure_only = no;
|
||||
|
||||
/* drain_reason: Message shown to users when they are rejected from a draining server.
|
||||
* requires extensions/drain to be loaded.
|
||||
*/
|
||||
drain_reason = "This server is not accepting connections.";
|
||||
>>>>>>> .merge_file_Mh5Whq
|
||||
};
|
||||
|
||||
modules {
|
||||
|
@ -1358,7 +1596,7 @@ modules {
|
|||
path = "/usr/local/ircd/modules/autoload";
|
||||
|
||||
/* module: the name of a module to load on startup/rehash */
|
||||
#module = "some_module.so";
|
||||
#module = "some_module";
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
Server VERSION Info
|
||||
|
||||
$Id: server-version-info 1851 2006-08-24 17:16:53Z jilles $
|
||||
|
||||
Copyright (c) 2001 by ircd-hybrid team
|
||||
Copyright (c) 2002 ircd-ratbox development team
|
||||
Copyright (c) 2016 Charybdis development team
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
When you type /version, you will often see something like this:
|
||||
|
||||
ircd-ratbox-1.0rc7(20021120_0). embers.lan egGHIKMpZ6 TS5ow
|
||||
charybdis-3.5.0-rc1(20151011-d09bde1). joestar.interlinked.me :eIKMpSZ6 TS6ow 1US
|
||||
|
||||
Ever wondered what those funny chars mean after the version number? Well
|
||||
here they are:
|
||||
|
@ -17,12 +17,6 @@
|
|||
+----------------------------+
|
||||
| 'e' | USE_EXCEPT |
|
||||
|------+---------------------|
|
||||
| 'g' | NO_FAKE_GLINES |
|
||||
|------+---------------------|
|
||||
| 'G' | GLINES |
|
||||
|------+---------------------|
|
||||
| 'H' | HUB |
|
||||
|------+---------------------|
|
||||
| 'I' | USE_INVEX |
|
||||
|------+---------------------|
|
||||
| 'K' | USE_KNOCK |
|
||||
|
@ -33,8 +27,6 @@
|
|||
|------+---------------------|
|
||||
| 'S' | OPERS_SEE_ALL_USERS |
|
||||
|------+---------------------|
|
||||
| 'T' | IGNORE_BOGUS_TS |
|
||||
|------+---------------------|
|
||||
| 'Z' | ZIPLINKS |
|
||||
|------+---------------------|
|
||||
| '6' | IPv6 |
|
||||
|
@ -43,7 +35,7 @@
|
|||
|------+---------------------|
|
||||
| 'TS' | Supports TS |
|
||||
|------+---------------------|
|
||||
| '5' | TS Version 5 |
|
||||
| '6' | TS Version 6 |
|
||||
|------+---------------------|
|
||||
| 'o' | TS Only |
|
||||
|------+---------------------|
|
|
@ -1,330 +0,0 @@
|
|||
Protocol changes for +TSora
|
||||
---------------------------
|
||||
|
||||
|
||||
Note:
|
||||
|
||||
The protocols described here implement TimeStamps on IRC channels and
|
||||
nicks. The idea of IRC TimeStamps was started on Undernet, and first
|
||||
implemented by Run <carlo@runaway.xs4all.nl>. The protocols used here
|
||||
are not exactly the same as the ones used on Undernet; the nick-kill
|
||||
handling is very similar and must be credited to Run, while the
|
||||
"TimeStamped channel description" protocol is quite different.
|
||||
|
||||
|
||||
|
||||
TSora servers keep track of which version of the TS protocol (if any)
|
||||
their neighboring servers are using, and take it into account when
|
||||
sending messages to them. This allows for seamless integration of TS
|
||||
servers into a non-TS net, and for upgrades of the protocol.
|
||||
|
||||
Each server knows which is the lowest and the highest version of the
|
||||
TS protocol it can interact with; currently both of these are set to 1:
|
||||
|
||||
#define TS_CURRENT 1 /* the highest TS ver we can do */
|
||||
#define TS_MIN 1 /* the lowest TS ver we can do */
|
||||
|
||||
|
||||
Timings and TS versions:
|
||||
========================
|
||||
|
||||
. Keep a 'delta' value to be added to the result of all calls to time(),
|
||||
initially 0.
|
||||
|
||||
. Send a second argument to the PASS command, ending in the 'TS' string.
|
||||
|
||||
. Send a
|
||||
|
||||
SVINFO <TS_CURRENT> <TS_MIN> <STANDALONE> :<UTC-TIME>
|
||||
|
||||
just after "SERVER", where <STANDALONE> is 1 if we're connected to
|
||||
more TSora servers, and 0 if not, and <UTC-TIME> is our idea of the
|
||||
current UTC time, fixed with the delta.
|
||||
|
||||
. When we receive a "SVINFO <x> <y> <z> :<t>" line from a connecting
|
||||
server, we ignore it if TS_CURRENT<y or x<TS_MIN, otherwise we
|
||||
set a flag remembering that that server is TS-aware, remember the TS
|
||||
version to use with it (min(TS_CURRENT, x)). Additionally, if this is
|
||||
our first connected TS server, we set our delta to t-<OUR_UTC> if
|
||||
z==0, and to (t-<OUR_UTC>)/2 if z!=0. The SVINFO data is kept around
|
||||
until the server has effectively registered with SERVER, and used
|
||||
*after* sending our own SVINFO to that server.
|
||||
|
||||
|
||||
Explanations:
|
||||
|
||||
Servers will always know which of their directly-linked servers can do
|
||||
TS, and will use the TS protocol only with servers that do understand
|
||||
it. This makes it possible to switch to full TS in just one
|
||||
code-replacement step, without incompatibilities.
|
||||
|
||||
As long as not all servers are TS-aware, the net will be divided into
|
||||
"zones" of linked TS-aware servers. Channel modes will be kept
|
||||
synchronized at least within the zone in which the channel was
|
||||
created, and nick collisions between servers in the same zone will
|
||||
result in only one client being killed.
|
||||
|
||||
Time synchronization ensures that servers have the same idea of the
|
||||
current time, and achieves this purpose as long as TS servers are
|
||||
introduced one by one within the same 'zone'. The merging of two zones
|
||||
cannot synchronize them completely, but it is to be expected that
|
||||
within each zone the effective time will be very close to the real
|
||||
time.
|
||||
|
||||
By sending TSINFO after SERVER rather than before, we avoid the extra
|
||||
lag created by the identd check on the server. To be able to send
|
||||
immediately a connect burst of either type (TS or not), we need to
|
||||
know before that if the server does TS or not, so we send that
|
||||
information with PASS as an extra argument. And to avoid being
|
||||
incompatible with 2.9 servers, which check that this second argument
|
||||
begins with "2.9", we check that it *ends* with "TS".
|
||||
|
||||
The current time is only used when setting a TS on a new channel or
|
||||
nick, and once such a TS is set, it is never modified because of
|
||||
synchronization, as it is much more important that the TS for a
|
||||
channel or nick stays the same across all servers than that it is
|
||||
accurate to the second.
|
||||
|
||||
Note that Undernet's 2.8.x servers have no time synchronization at
|
||||
all, and have had no problems because of it - all of this is more to
|
||||
catch the occasional server with a way-off clock than anything.
|
||||
|
||||
|
||||
NICK handling patches (anti-nick-collide + shorter connect burst):
|
||||
==================================================================
|
||||
|
||||
. For each nick, store a TS value = the TS value received if any, or our
|
||||
UTC+delta at the time we first heard of the nick. TS's are propagated
|
||||
to TS-aware servers whenever sending a NICK command.
|
||||
|
||||
. Nick changes reset the TS to the current time.
|
||||
|
||||
. When sending a connect burst to another TS server, replace the
|
||||
NICK/USER pair with only one NICK command containing the nick, the
|
||||
hopcount, the TS, the umode, and all the USER information.
|
||||
|
||||
The format for a full NICK line is:
|
||||
NICK <nick> <hops> <TS> <umode> <user> <host> <server> :<ircname>
|
||||
|
||||
The umode is a + followed by any applying usermodes.
|
||||
|
||||
The format for a nick-change NICK line is:
|
||||
:<oldnick> NICK <newnick> :<TS>
|
||||
|
||||
. When a NICK is received from a TS server, that conflicts with an
|
||||
existing nick:
|
||||
+ if the userhosts differ or one is not known:
|
||||
* if the timestamps are equal, kill ours and the old one if it
|
||||
was a nick change
|
||||
* if the incoming timestamp is older than ours, kill ours and
|
||||
propagate the new one
|
||||
* if the incoming timestamp is younger, ignore the line, but kill
|
||||
the old nick if it was a nick change
|
||||
+ if the userhosts are the same:
|
||||
* if the timestamps are equal, kill ours and the old one if it
|
||||
was a nick change
|
||||
* if the incoming timestamp is younger, kill ours and propagate
|
||||
the new one
|
||||
* if the incoming timestamp is older, ignore the line but kill
|
||||
the old nick if it was a nick change
|
||||
|
||||
. When a NICK is received from a non-TS server that conflicts with
|
||||
an existing nick, kill both.
|
||||
|
||||
. Do not send "Fake Prefix" kills in response to lines coming from TS
|
||||
servers; the sanitization works anyway, and this allows the "newer
|
||||
nick overruled" case to work.
|
||||
|
||||
Explanations:
|
||||
|
||||
The modified nick-introduction syntax allows for a slightly shorter
|
||||
connect-burst, and most importantly lets the server compare
|
||||
user@host's when determining which nick to kill: if the user@host
|
||||
is the same, then the older nick must be killed rather than the
|
||||
newer.
|
||||
|
||||
When talking to a non-TS server, we need to behave exactly like one
|
||||
because it expects us to. When talkign to a TS server, we don't kill
|
||||
the nicks it's introducing, as we know it'll be smart enough to do it
|
||||
itself when seeing our own introduced nick.
|
||||
|
||||
When we see a nick arriving from a non-TS server, it won't have a TS,
|
||||
but it's safe enough to give it the current time rather than keeping
|
||||
it 0; such TS's won't be the same all across the network (as long as
|
||||
there is more than one TS zone), and when there's a collision, the TS
|
||||
used will be the one in the zone the collision occurs in.
|
||||
|
||||
Also, it is important to note that by the time a server sees (and
|
||||
chooses to ignore) a nick introduction, the introducing server has
|
||||
also had the time to put umode changes for that nick on its queue, so
|
||||
we must ignore them too... so we need to ignore fake-prefix lines
|
||||
rather than sending kills for them. This is safe enough, as the rest
|
||||
of the protocol ensures that they'll get killed anyway (and the
|
||||
Undernet does it too, so it's been more than enough tested). Just for
|
||||
an extra bit of compatibility, we still kill fake prefixes coming from
|
||||
non-TS servers.
|
||||
|
||||
This part of the TS protocol is almost exactly the same as the
|
||||
Undernet's .anc (anti-nick-collide) patches, except that Undernet
|
||||
servers don't add usermodes to the NICK line.
|
||||
|
||||
|
||||
TimeStamped channel descriptions (avoiding hacked ops and desynchs):
|
||||
====================================================================
|
||||
|
||||
. For each channel, keep a timestamp, set to the current time when the
|
||||
channel is created by a client on the local server, or to the received
|
||||
value if the channel has been propagated from a TS server, or to 0
|
||||
otherwise. This value will have the semantics of "the time of creation
|
||||
of the current ops on the channel", and 0 will mean that the channel
|
||||
is in non-TS mode.
|
||||
|
||||
A new server protocol command is introduced, SJOIN, which introduces
|
||||
a full channel description: a timestamp, all the modes (except bans),
|
||||
and the list of channel members with their ops and voices. This
|
||||
command will be used instead of JOIN and of (most) MODEs both in
|
||||
connect bursts and when propagating channel creations among TS
|
||||
servers. SJOIN will never be accepted from or sent to users.
|
||||
|
||||
The syntax for the command is:
|
||||
|
||||
SJOIN <TS> #<channel> <modes> :[@][+]<nick_1> ... [@][+]<nick_n>
|
||||
|
||||
The fields have the following meanings:
|
||||
|
||||
* <TS> is the timestamp for the channel
|
||||
|
||||
* <modes> is the list of global channel modes, starting with a +
|
||||
and a letter for each of the active modes (spmntkil), followed
|
||||
by an argument for +l if there is a limit, and an argument for
|
||||
+k if there's a key (in the same order they were mentioned in
|
||||
the string of letters).
|
||||
|
||||
A channel with no modes will have a "+" in that field.
|
||||
|
||||
A special value of "0" means that the server does not specify the
|
||||
modes, and will be used when more than one SJOIN line is needed
|
||||
to completely describe a channel, or when propagating a SJOIN
|
||||
the modes of which were rejected.
|
||||
|
||||
* Each nick is preceded by a "@" if the user has ops, and a "+" if
|
||||
the user has a voice. For mode +ov, both flags are used.
|
||||
|
||||
SJOINs will be propagated (when appropriate) to neighboring TS
|
||||
servers, and converted to JOINs and MODEs for neighboring non-TS
|
||||
servers.
|
||||
|
||||
To propagate channels for which not all users fit in one
|
||||
SJOIN line, several SJOINs will be sent consecutively, only the first
|
||||
one including actual information in the <mode> field.
|
||||
|
||||
An extra ad-hoc restriction is imposed on SJOIN messages, to simplify
|
||||
processing: if a channel has ops, then the first <nick> of the first
|
||||
SJOIN sent to propagate that channel must be one of the ops.
|
||||
|
||||
Servers will never attempt to reconstruct a SJOIN from JOIN/MODE
|
||||
information being received at the moment from other servers.
|
||||
|
||||
. For each user on a channel, keep an extra flag (like ops and voice)
|
||||
that is set when the user has received channel ops from another
|
||||
server (in a SJOIN channel description), which we rejected (ignored).
|
||||
Mode changes (but NOT kicks) coming from a TS server and from someone
|
||||
with this flag set will be ignored. The flag will be reset when the
|
||||
user gets ops from another user or server.
|
||||
|
||||
. On deops done by non-local users, coming from TS servers, on channels
|
||||
with a non-zero TS, do not check that the user has ops but check that
|
||||
their 'deopped' flag is not set. For kicks coming from a TS server, do
|
||||
not check either. This will avoid desynchs, and 'bad' modechanges are
|
||||
avoided anyway. Other mode changes will still only be taken into
|
||||
account and propagated when done by users that are seen as having ops.
|
||||
|
||||
. When a MODE change that ops someone is received from a server for a
|
||||
channel, that channel's TS is set to 0, and the mode change is
|
||||
propagated.
|
||||
|
||||
. When a SJOIN is received for a channel, deal with it in this way:
|
||||
* received-TS = 0:
|
||||
+ if we have ops or the SJOIN doesn't op anyone, SJOIN propagated
|
||||
with our own TS.
|
||||
+ otherwise, TS set to 0 and SJOIN propagated with 0.
|
||||
* received-TS > 0, own-TS = 0:
|
||||
+ if the SJOIN ops someone or we don't have ops, set our TS to the
|
||||
received TS and propagate.
|
||||
+ otherwise, propagate with TS = 0.
|
||||
* received-TS = own-TS: propagate.
|
||||
* received-TS < own-TS:
|
||||
+ if the SJOIN ops someone, remove *all* modes (except bans) from
|
||||
the channel and propagate these mode changes to all neighboring
|
||||
non-TS servers, and copy the received TS and propagate the SJOIN.
|
||||
+ if the SJOIN does not op anyone and we have ops, propagate
|
||||
with our own TS.
|
||||
+ otherwise, copy the received TS and propagate the SJOIN.
|
||||
* received-TS > own-TS:
|
||||
+ if the SJOIN does not introduce any ops, process and propagate
|
||||
with our own TS.
|
||||
+ if we have ops: for each person the mode change would op, set the
|
||||
'deopped' flag; process all the JOINs ignoring the '@' and '+'
|
||||
flags; propagate without the flags and with our TS.
|
||||
+ if we don't have ops: set our TS to the received one, propagate
|
||||
with the flags.
|
||||
|
||||
|
||||
Explanations:
|
||||
|
||||
This part of the protocol is the one that is most different (and
|
||||
incompatible) with the Undernet's: we never timestamp MODE changes,
|
||||
but instead we introduce the concept of time-stamped channel
|
||||
descriptions. This way each server can determine, based on its state
|
||||
and the received description, what the correct modes for a channel
|
||||
are, and deop its own users if necessary. With this protocol, there is
|
||||
*never* the need to reverse and bounce back a mode change. This is
|
||||
both faster and more bandwith-effective.
|
||||
|
||||
The end goal is to have a protocol will eventually protect channels
|
||||
against hacked ops, while minimizing the impact on a mixed-server net.
|
||||
In order to do this, whenever there is a conflict between a TS server
|
||||
and a non-TS one, the non-TS one's idea of the whole situation
|
||||
prevails. This means that channels will only have a TS when they have
|
||||
been created on a TS-aware server, and will lose it whenever a server
|
||||
op comes from a non-TS server. Also, at most one 'zone' will have a TS
|
||||
for any given channel at any given time, ensuring that there won't be
|
||||
any deops when zones are merged. However, when TS zones are merged, if
|
||||
the side that has a TS also has ops, then the TS is kept across the
|
||||
whole new zone. Effective protection will only be ensured once all
|
||||
servers run TS patches and channels have been re-created, as there is
|
||||
no way servers can assign a TS to a channel they are not creating
|
||||
(like they do with nicks) without having unwanted deops later.
|
||||
|
||||
The visible effects of this timestamped channel-description protocol
|
||||
are that when a split rejoins, and one side has hacked ops, the other
|
||||
side doesn't see any server mode changes (just like with Undernet's
|
||||
TS), but the side that has hacked ops sees:
|
||||
|
||||
* first the first server on the other side deopping and devoicing
|
||||
everyone, and fixing the +spmntkli modes
|
||||
* then other users joining, and getting server ops and voices
|
||||
|
||||
The less obvious part of this protocol is its behavior in the case
|
||||
that the younger side of a rejoin has servers that are lagged with
|
||||
each other. In such a situation, a SJOIN that clears all modes and
|
||||
sets the legitimate ones is being propagated from one server, and
|
||||
lagged illegitimate mode changes and kicks are being propagated in the
|
||||
opposite direction. In this case, a kick done by someone who is being
|
||||
deopped by the SJOIN must be taken into account to keep the name list
|
||||
in sync (and since it can only be kicking someone who also was on the
|
||||
younger side), while a deop does not matter (and will be ignored by
|
||||
the first server on the other side), and an opping *needs* to be
|
||||
discareded to avoid hacked ops.
|
||||
|
||||
The main property of timestamped channel descriptions that makes them
|
||||
a very stable protocol even with lag and splits, is that they leave a
|
||||
server in the same final state, independently of the order in which
|
||||
channel descriptions coming from different servers are received. Even
|
||||
when SJOINs and MODEs for the same channel are being propagated in
|
||||
different direction because of several splits rejoining, the final
|
||||
state will be the same, independently of the exact order in which each
|
||||
server received the SJOINs, and will be the same across all the
|
||||
servers in the same zone.
|
||||
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
Server capabilities
|
||||
William Pitcock <nenolod -at- nenolod.net>
|
||||
Ariadne Conill <ariadne -at- dereferenced.org>
|
||||
-------------------
|
||||
|
||||
Not all TSora IRCd's support these.
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
$Id: cluster.txt 6 2005-09-10 01:02:21Z nenolod $
|
||||
|
||||
Short description of how remote kline and friends are propagated under
|
||||
the old hyb7 style (CAP_KLN etc) and under the new style over ENCAP.
|
||||
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
$Id: euid.txt 1863 2006-08-27 13:40:37Z jilles $
|
||||
|
||||
Extended UID command proposal
|
||||
Jilles Tjoelker <jilles@stack.nl>
|
||||
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
Overview of the event subsystem
|
||||
Adrian Chadd <adrian@creative.net.au>
|
||||
|
||||
$Id: event.txt 6 2005-09-10 01:02:21Z nenolod $
|
||||
|
||||
|
||||
One of the things that immediately struck me whilst first looking at the
|
||||
code was that the ircd periodically scheduled things in io_loop() but
|
||||
|
|
|
@ -1,47 +0,0 @@
|
|||
Overview of the filedescriptor subsystem
|
||||
Adrian Chadd <adrian@creative.net.au>
|
||||
|
||||
$Id: fd-management.txt 6 2005-09-10 01:02:21Z nenolod $
|
||||
|
||||
|
||||
Filedescriptor lists
|
||||
--------------------
|
||||
|
||||
The filedescriptor list is managed through the routines in fdlist.c .
|
||||
These include:
|
||||
|
||||
fd_open() - tag an FD as "open" and active
|
||||
fd_close() - tag an FD as "closed" and close() the filedescriptor
|
||||
fd_note() - update the filedescriptor tag
|
||||
|
||||
You can get the current list of open filedescriptors through /stats F as
|
||||
an oper.
|
||||
|
||||
|
||||
|
||||
FD lists
|
||||
--------
|
||||
|
||||
The FD list support is very alpha. There are a few lists defined:
|
||||
|
||||
typedef enum fdlist_t {
|
||||
FDLIST_NONE,
|
||||
FDLIST_SERVICE,
|
||||
FDLIST_SERVER,
|
||||
FDLIST_IDLECLIENT,
|
||||
FDLIST_BUSYCLIENT,
|
||||
FDLIST_MAX
|
||||
} fdlist_t;
|
||||
|
||||
FDLIST_NONE Not on any list (ie close()d)
|
||||
FDLIST_SERVICE A service - listen() sockets, resolver, etc
|
||||
FDLIST_SERVER Server connections
|
||||
FDLIST_IDLECLIENT An idle client
|
||||
FDLIST_BUSYCLIENT A busy client
|
||||
FDLIST_MAX Used for bounds checking
|
||||
|
||||
The idea is that the SERVICE sockets need polling frequently, the SERVER
|
||||
sockets also need polling frequently, BUSYCLIENT is for busy clients
|
||||
which need frequent polling (eg we're trying to write to them), and
|
||||
IDLECLIENT is for clients which we don't need to poll frequently.
|
||||
THIS hasn't been decided upon yet.
|
|
@ -114,6 +114,23 @@ The following hooks are called during various events related to clients.
|
|||
oldsnomask = new snomask field
|
||||
|
||||
|
||||
Channel Hooks
|
||||
-------------
|
||||
|
||||
"can_invite" - Called before deciding whether to allow the
|
||||
/invite command
|
||||
hdata->chptr = channel being invited to
|
||||
hdata->msptr = membership of inviter
|
||||
hdata->client = inviter
|
||||
hdata->target = invite target
|
||||
hdata->approved = zero to allow
|
||||
hdata->error = NULL, or error message
|
||||
if non-null, `approved` is the numeric
|
||||
"invite" - Called just before effecting an invite on the
|
||||
target's server
|
||||
hdata = as above
|
||||
|
||||
|
||||
The following are for debugging and take struct hook_io_data for arguments.
|
||||
These can be used for a variety of purposes, but are aimed at the developer
|
||||
community.
|
||||
|
@ -121,4 +138,3 @@ community.
|
|||
"iorecv"
|
||||
"iorecvctrl"
|
||||
|
||||
$Id: hooks.txt 3414 2007-04-15 16:54:50Z jilles $
|
|
@ -1,6 +1,5 @@
|
|||
The hostmask/netmask system.
|
||||
Copyright(C) 2001 by Andrew Miller(A1kmm)<a1kmm@mware.virtualave.net>
|
||||
$Id: hostmask.txt 6 2005-09-10 01:02:21Z nenolod $
|
||||
|
||||
Contents
|
||||
========
|
||||
|
|
|
@ -1,19 +1,10 @@
|
|||
Technical Documentation for ircd-hybrid-7
|
||||
Technical Documentation for Charybdis
|
||||
|
||||
Persistent_Clients.txt - A global UID and Persistent client (with cookies)
|
||||
proposal
|
||||
README.TSora - Description of the TS3 protocol
|
||||
README.openssl - Information for users who have problems with
|
||||
Hybrid, OpenSSL, and their operating system
|
||||
cryptlink.txt - Outline of CRYPTLINK protocol
|
||||
capab.txt - Description of server capabilities
|
||||
cluster.txt - Technical description of the cluster system
|
||||
euid.txt - Description of TS6 EUIDs
|
||||
event.txt - Outline of the event system
|
||||
fd-management.txt - Outline of the file descriptor management system
|
||||
file-management.txt - Outline of the disk file management system
|
||||
hooks.txt - Internal IRC daemon hoks
|
||||
hostmask.txt - Outline of hostmask handling
|
||||
linebuf.txt - Outline of the linebuf system (dbuf replacement)
|
||||
network.txt - Outline of the network traffic subsystem
|
||||
rfc1459.txt - The IRC RFC
|
||||
send.txt - Document on all of the send_to functions
|
||||
whats-new-code.txt - Whats changed in the code
|
||||
|
||||
# $Id: index.txt 6 2005-09-10 01:02:21Z nenolod $
|
||||
ts6-protocol.txt - Description of the TS6 protocol
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
|
||||
linebuf - a dbuf replacement for the New World Order(tm)
|
||||
|
||||
By Adrian Chadd <adrian@creative.net.au>
|
||||
|
||||
$Id: linebuf.txt 6 2005-09-10 01:02:21Z nenolod $
|
||||
|
||||
|
||||
History
|
||||
-------
|
||||
|
|
|
@ -1,105 +0,0 @@
|
|||
Overview of the network subsystem
|
||||
Adrian Chadd <adrian@creative.net.au>
|
||||
|
||||
$Id: network.txt 6 2005-09-10 01:02:21Z nenolod $
|
||||
|
||||
|
||||
This document is an overview of the new and hopefully improved network
|
||||
subsystem.
|
||||
|
||||
The code is based loosely upon the network core found in the Squid web cache
|
||||
server, with some optimizations for ircd-specific IO patterns.
|
||||
|
||||
|
||||
|
||||
Filedescriptor IO
|
||||
-----------------
|
||||
|
||||
Filedescriptor IO is initiated using comm_setselect(). comm_setselect()
|
||||
registers interest in reading from or writing to a file descriptor.
|
||||
When a filedescriptor is ready for the required IO a callback is called
|
||||
from the IO loop.
|
||||
|
||||
The comm_setselect() usage is:
|
||||
|
||||
void
|
||||
comm_setselect(int fd, fdlist_t list, int type, PF *callback, void *cbdata,
|
||||
int timeout)
|
||||
|
||||
where:
|
||||
fd filedescriptor
|
||||
list Which list the FD should be put on
|
||||
type IO type. Can currently include:
|
||||
COMM_SELECT_READ - register for read
|
||||
COMM_SELECT_WRITE - register for write
|
||||
callback Function to call when the FD is ready
|
||||
cbdata Data to be passed to above function
|
||||
timeout Update the timeout value. 0 is "don't update".
|
||||
|
||||
|
||||
A typical use is:
|
||||
|
||||
..
|
||||
|
||||
/* Register interest in the FD for a read event */
|
||||
comm_setselect(fd, FDLIST_SERVICE, COMM_SELECT_READ, read_callback, read_data,
|
||||
0);
|
||||
|
||||
..
|
||||
|
||||
(FD becomes ready for read in the IO loop)
|
||||
|
||||
void
|
||||
read_callback(int fd, void *data)
|
||||
{
|
||||
/* called when the FD becomes ready for read */
|
||||
retval = read(fd, buf, len);
|
||||
|
||||
..
|
||||
/* Ok, we need to read some more when its ready */
|
||||
comm_setselect(fd, FDLIST_SERVICE, COMM_SELECT_READ, read_callback, data,
|
||||
0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Socket timeouts
|
||||
---------------
|
||||
|
||||
A "socket timeout" is a callback registered to be called when a certain
|
||||
amount of time has elapsed. Think of it as an event, but against a FD.
|
||||
|
||||
A good example of socket timeouts is in the comm_connect_tcp() code.
|
||||
When the connect() begins, comm_settimeout() is called to call
|
||||
comm_connect_timeout() if the timeout occurs. Once the connect() completes,
|
||||
comm_settimeout() is called with a timeout of 0 and callback of NULL
|
||||
to deregister the timeout. If the timeout occurs, comm_connect_timeout()
|
||||
is called and the connection attempt is aborted.
|
||||
|
||||
|
||||
|
||||
|
||||
Functions
|
||||
---------
|
||||
|
||||
comm_open() - a socket() wrapper, enforcing fd limitations and tagging the
|
||||
file descriptor with a note
|
||||
|
||||
comm_accept() - an accept() wrapper, enforcing fd limitations and tagging
|
||||
the file descriptor with a note
|
||||
|
||||
comm_connect_tcp() - attempt an async connect(). Handles DNS lookups if
|
||||
required, and will call the given callback at completion or error
|
||||
|
||||
comm_settimeout() - set a callback to be called after a given time period.
|
||||
This is good to implement things like PING checks and connect() timeouts.
|
||||
|
||||
Notes:
|
||||
|
||||
* All socket creation should go through comm_open() / comm_accept().
|
||||
* All socket closing should go through fd_close(). comm_close() isn't
|
||||
implemented yet.
|
||||
* comm_connect_tcp() is your best friend. :-)
|
||||
* *ALL* network sockets should be non-blocking. If your OS doesn't support
|
||||
non-blocking sockets, you shouldn't be here.
|
|
@ -1,253 +0,0 @@
|
|||
|
||||
send.c re-work
|
||||
|
||||
PREFIXES
|
||||
========
|
||||
|
||||
Server prefixes are the ":%s" strings at the beginning of messages.
|
||||
They are used by servers to route the message properly and by servers to
|
||||
local clients to update their idea of who is whom.
|
||||
|
||||
":nick!user@host" is a prefix ":name" where name is either a nick
|
||||
or name of a server is another valid prefix.
|
||||
|
||||
Typical prefix for a local client to a channel:
|
||||
|
||||
":Dianora!db@irc.db.net"
|
||||
|
||||
for a prefix to a remote server:
|
||||
":Dianora"
|
||||
|
||||
e.g. as seen locally on a channel:
|
||||
|
||||
":Dianora!db@irc.db.net PRIVMSG #us-opers :ON TOP OF ...\r\n"
|
||||
|
||||
e.g. as seen sent to a remote server:
|
||||
":Dianora PRIVMSG #us-opers :ON TOP OF ...\r\n"
|
||||
|
||||
It has been argued that full prefixes sent locally are a waste of bandwidth
|
||||
(Isomer from Undernet has argued this). i.e. instead of sending:
|
||||
":nick!user@host" for a local prefix, one could just send ":nick"..
|
||||
Unfortunately, this breaks many clients badly. Personally I feel that
|
||||
until clients are updated to understand that a full prefix isn't always
|
||||
going to be sent, that this should be held off on.
|
||||
|
||||
As much as possible, prefix generation is now moved "upstairs" as
|
||||
much as possible. i.e. if its known its a local client only, then the
|
||||
onus of the prefix generation, is the users, not hidden in send.c
|
||||
This allows somewhat faster code to be written, as the prefix doesn't
|
||||
have to be regenerated over and over again.
|
||||
|
||||
Prefixes aren't sent in all cases, such as a new user using NICK
|
||||
A prefix is needed when it must be routed.
|
||||
|
||||
i.e.
|
||||
|
||||
NICK newnick
|
||||
|
||||
There is obviously no prefix needed from a locally connected client.
|
||||
|
||||
|
||||
|
||||
FUNCTIONS
|
||||
=========
|
||||
|
||||
sendto_one() - Should be used for _local_ clients only
|
||||
it expects the prefix to be pre-built by user.
|
||||
|
||||
usage - sendto_one(struct Client *to, char *pattern, ...);
|
||||
|
||||
typical use:
|
||||
|
||||
sendto_one(acptr,":%s NOTICE %s :I'm tired", me.name,
|
||||
acptr->name);
|
||||
Note: This was from a server "me" hence only one
|
||||
name in prefix.
|
||||
|
||||
This would be an example of a client sptr, noticing
|
||||
acptr IF acptr is known to be a local client:
|
||||
|
||||
sendto_one(acptr,":%s!%s@%s NOTICE %s :You there?",
|
||||
sptr->name,
|
||||
sptr->username,
|
||||
sptr->host,
|
||||
acptr->name);
|
||||
|
||||
sendto_one_prefix()
|
||||
- Sends a message to a remote client, with proper
|
||||
prefix and target (name or UID).
|
||||
usage - sendto_one_prefix(struct Client *target_p,
|
||||
struct Client *source_p,
|
||||
const char *command,
|
||||
const char *pattern, ...)
|
||||
|
||||
typical use:
|
||||
|
||||
sendto_one_prefix(target_p, source_p, "INVITE", ":%s",
|
||||
chptr->chname);
|
||||
|
||||
|
||||
sendto_one_notice()
|
||||
- Sends a notice from this server to target. Target may
|
||||
be a local or remote client.
|
||||
Prefix and target are chosen based on TS6 capability.
|
||||
|
||||
typical use:
|
||||
|
||||
sendto_one_notice(source_p, ":You suck. Yes, really.");
|
||||
|
||||
sendto_one_numeric()
|
||||
- Sends a numeric from this server to target. Target may
|
||||
be a local or remote client.
|
||||
Prefix and target are chosen based on TS6 capability.
|
||||
|
||||
typical use:
|
||||
|
||||
sendto_one_numeric(source_p, RPL_STATSDEBUG,
|
||||
"p :%u staff members", count);
|
||||
|
||||
sendto_channel_flags()
|
||||
- This function sends a var args message to a channel globally,
|
||||
except to the client specified as "one", the prefix
|
||||
is built by this function on the fly as it has to
|
||||
be sent both to local clients on this server and to
|
||||
remote servers.
|
||||
For type use one of:
|
||||
ONLY_SERVERS ALL_MEMBERS ONLY_CHANOPS ONLY_CHANOPSVOICED
|
||||
If type is not ALL_MEMBERS it's not sent to not-CHW-capable
|
||||
servers.
|
||||
Deaf (umode +D) clients are always skipped.
|
||||
|
||||
usage - sendto_channel_flags(struct Client *one,
|
||||
int type,
|
||||
struct Client *from,
|
||||
struct Channel *chptr,
|
||||
const char *pattern, ... );
|
||||
|
||||
sendto_channel_butone(cptr, ALL_MEMBERS, sptr, chptr
|
||||
"PRIVMSG %s :HI!",
|
||||
chptr->chname);
|
||||
|
||||
e.g. if channel message is coming from "cptr"
|
||||
it must not be sent back to cptr.
|
||||
|
||||
|
||||
sendto_server()
|
||||
- This function sends specified var args message
|
||||
to all connected servers except the client "one"
|
||||
which have all of "caps" capabilities but none
|
||||
of "nocaps" capabilities.
|
||||
|
||||
If "chptr" is not NULL and is a local channel,
|
||||
nothing is sent.
|
||||
|
||||
usage - sendto_server(struct Client *one,
|
||||
struct Channel *chptr,
|
||||
unsigned long caps,
|
||||
unsigned long nocaps,
|
||||
const char *format, ... );
|
||||
|
||||
sendto_common_channels_local()
|
||||
- This function is used only by m_nick and exit_one_client
|
||||
its used to propagate nick changes to all channels user
|
||||
is in, and QUIT messages to all channels user is in.
|
||||
As it only sends to local clients, prefix generation
|
||||
is left to the user. It also sends the message to the
|
||||
user if the user isn't on any channels.
|
||||
|
||||
usage - sendto_common_channels_local(struct Client *user,
|
||||
const char *pattern,
|
||||
...);
|
||||
|
||||
sendto_channel_local()
|
||||
- This function is used to send only locally, never
|
||||
to remote servers. This is useful when removing
|
||||
local chanops, or adding a local chanop. MODE/SJOIN
|
||||
sent to remote server allows that server to propagate
|
||||
mode changes to its clients locally.
|
||||
The message is also sent to deaf (umode +D) clients.
|
||||
|
||||
usage - sendto_channel_local(int type,
|
||||
struct Channel *chptr,
|
||||
const char *pattern, ... );
|
||||
|
||||
prefix must be pre-built. type is a flag
|
||||
denoting ONE of
|
||||
ALL_MEMBERS - all members locally are sent to
|
||||
ONLY_CHANOPS_VOICED - only chanops and voiced see this
|
||||
ONLY_CHANOPS - only chanops see this
|
||||
|
||||
|
||||
sendto_match_butone()
|
||||
- only used for the old style oper masking
|
||||
i.e. /msg #hostmask which in hyb7 is /msg $#hostmask
|
||||
or /msg $servermask in hyb7 /msg $$servermask
|
||||
|
||||
usage - sendto_match_butone(struct Client *one,
|
||||
struct Client *source_p,
|
||||
char *mask,
|
||||
int what,
|
||||
const char *pattern, ... );
|
||||
|
||||
one is the client not to send to
|
||||
mask is the actual mask
|
||||
what is either MATCH_HOST or MATCH_SERVER
|
||||
|
||||
sendto_match_servs()
|
||||
- Allows sending a message to servers whose names match
|
||||
the given mask. A message is also sent to non-matching
|
||||
servers which have matching servers behind them.
|
||||
Used for ENCAP, remote kline, etc.
|
||||
No message is sent to source_p->from.
|
||||
|
||||
usage - sendto_match_servs(struct Client *source_p,
|
||||
const char *mask,
|
||||
int cap, int nocap,
|
||||
const char *pattern, ...);
|
||||
|
||||
sendto_anywhere()
|
||||
- Allows the sending of a message to any client on the net
|
||||
without knowing whether its local or remote. The penalty
|
||||
is the calculation of a run-time prefix.
|
||||
It is less efficient then sendto_one()
|
||||
|
||||
usage - sendto_anywhere(struct Client *to,
|
||||
struct Client *from,
|
||||
const char *command,
|
||||
const char *pattern, ...);
|
||||
|
||||
e.g.
|
||||
sendto_anywhere(target_p, source_p,
|
||||
"PRIVMSG", ":Hi, Where ever you are");
|
||||
|
||||
sendto_realops_flags()
|
||||
- combines old sendto_realops and sendto_realops_flags
|
||||
sends specified message to opers locally only
|
||||
depending on umodes. UMODE_ALL is UMODE_SERVNOTICE.
|
||||
the message is sent as a server notice, prefixed with
|
||||
"*** Notice -- ".
|
||||
|
||||
usage - sendto_realops_flags(int flags,
|
||||
const char *pattern, ... );
|
||||
|
||||
e.g.
|
||||
sendto_realops_flags(UMODE_ALL,
|
||||
"Don't eat the yellow snow");
|
||||
|
||||
sendto_wallops_flags()
|
||||
- sends specified message to opers/users locally,
|
||||
depending on umodes. used for messages that need
|
||||
to be in wallops form
|
||||
- some policy decisions about who gets what live in here
|
||||
|
||||
usage - sendto_wallops_flags(int flags,
|
||||
struct Client *, const char *patterm ...);
|
||||
|
||||
e.g.
|
||||
sendto_wallops_flags(UMODE_LOCOPS,
|
||||
sptr, "Message");
|
||||
|
||||
-- Diane Bruce
|
||||
Updated Jan 2006 by jilles with ratbox and late hybrid7 changes
|
||||
|
||||
$Id: send.txt 587 2006-01-27 19:45:11Z jilles $
|
|
@ -1,5 +1,6 @@
|
|||
TS6 protocol description
|
||||
Written by Jilles Tjoelker
|
||||
Edits by Elizabeth Myers to add TS rules described by Lee Harvey.
|
||||
|
||||
General format: much like rfc1459
|
||||
Maximum parameters for a command: 15 (this does not include the prefix
|
||||
|
@ -18,6 +19,7 @@ nicknames and server names are accepted, possibly with wildcards; from servers,
|
|||
UIDs/SIDs (sending names or even wildcards is deprecated). This is done with
|
||||
the function hunt_server(). Any rate limiting should be done locally.
|
||||
|
||||
|
||||
duration: a parameter type used for ban durations. It is a duration in seconds.
|
||||
A value of 0 means a permanent ban.
|
||||
|
||||
|
@ -112,6 +114,75 @@ type D
|
|||
+g (allow any member to /invite)
|
||||
+z (send messages blocked by +m to chanops)
|
||||
|
||||
Nick TS rules:
|
||||
A server receiving a command that requires nick TS rules must check for a
|
||||
collision between an existing user, and the nick in the received message.
|
||||
(the "new user"). The collisions must obey the rules specified in Nick TS
|
||||
collisions.
|
||||
|
||||
If the TS received is lower than the TS of the existing user the server will
|
||||
collide the existing user if the clients user@host are different, if the
|
||||
clients user@hosts are identical it will collide the new user.
|
||||
|
||||
If the TS received is equal to the TS of the existing user both clients are
|
||||
collided.
|
||||
|
||||
If the TS received is higher than the TS of the existing user, the server
|
||||
will collide the existing user if the user@hosts are identical, if the
|
||||
clients user@host are different it will collide the new user and drop the
|
||||
message.
|
||||
|
||||
Nick TS collisions:
|
||||
If both users are to be collided, we must issue a KILL for the existing
|
||||
user to all servers. If the new user has a UID then we must also issue a
|
||||
KILL for that UID back to the server sending us data causing the collision.
|
||||
|
||||
If only the existing user is being collided, we must issue a KILL for the
|
||||
existing user to all servers except the server sending us data. If the
|
||||
existing user has a UID and the server sending us data supports TS6 then
|
||||
we must also issue a KILL for the existing users UID to the server sending
|
||||
us data.
|
||||
|
||||
If only the new user is being collided, we must issue a KILL for the new user
|
||||
back to the server sending us data if the new user has a UID.
|
||||
|
||||
Channel TS rules:
|
||||
A server receiving a command that requires normal channel TS rules must
|
||||
apply the following rules to the command.
|
||||
|
||||
If the TS received is lower than our TS of the channel a TS6 server must
|
||||
remove status modes (+ov etc) and channel modes (+nt etc). If the
|
||||
originating server is TS6 capable (ie, it has a SID), the server must
|
||||
also remove any ban modes (+b etc). The new modes and statuses are then
|
||||
accepted.
|
||||
|
||||
If any bans are removed, the server must send to non-TS6, directly connected
|
||||
servers mode changes removing the bans after the command is propagated.
|
||||
This prevents desync with banlists, and has to be sent after as clients are
|
||||
still able to send mode changes before the triggering command arrives.
|
||||
|
||||
If the TS received is equal to our TS of the channel the server should keep
|
||||
its current modes and accept the received modes and statuses.
|
||||
|
||||
If the TS received is higher than our TS of the channel the server should keep
|
||||
its current modes and ignore the received modes and statuses. Any statuses
|
||||
given in the received message will be removed. A server must mark clients
|
||||
losing their op (+o) status who do not have a UID as 'deopped'. A server must
|
||||
ignore any "MODE" commands from a user marked as 'deopped'.
|
||||
|
||||
Simple channel TS rules:
|
||||
|
||||
A server receiving a command that requires simple channel TS rules must
|
||||
apply the following rules to the command.
|
||||
|
||||
If the TS received is lower, or equal to our TS of the channel the modes are
|
||||
accepted. If the TS received is higher than our TS of the channel the modes
|
||||
are ignored and dropped.
|
||||
|
||||
Simple channel TS rules do not affect current modes in the channel except
|
||||
for the modes we are accepting.
|
||||
|
||||
|
||||
<numeric>
|
||||
source: server
|
||||
parameters: target, any...
|
||||
|
@ -248,6 +319,28 @@ Sets a D:line (IP ban checked directly after accepting connection).
|
|||
|
||||
The mask must be an IP address or CIDR mask.
|
||||
|
||||
EBMASK
|
||||
source: server
|
||||
propagation: broadcast
|
||||
parameters: channelTS, channel, type, space separated "masks ts hostmask" chunks
|
||||
|
||||
If the channelTS in the message is greater (newer) than the current TS of
|
||||
the channel, drop the message and do not propagate it.
|
||||
|
||||
Type is the mode letter of a ban-like mode. In efnet TS6 this is 'b', 'e' or
|
||||
'I'. In charybdis TS6 additionally 'q' is possible.
|
||||
|
||||
Add all the masks and their set at/by to the given list of the channel.
|
||||
|
||||
All ban-like modes must be bursted using this command, not using MODE or TMODE.
|
||||
|
||||
ECHO
|
||||
source: user
|
||||
parameters: "P"/"N", target, text
|
||||
|
||||
As PRIVMSG, but delivers an echo-message echo to the target; they will see
|
||||
a PRIVMSG or NOTICE from themselves to the source.
|
||||
|
||||
ENCAP
|
||||
source: any
|
||||
parameters: target server mask, subcommand, opt. parameters...
|
||||
|
@ -599,6 +692,13 @@ and most error messages are suppressed.
|
|||
Servers may not send '$$', '$#' and opers@server notices. Older servers may
|
||||
not allow servers to send to specific statuses on a channel.
|
||||
|
||||
OPER
|
||||
source: user
|
||||
parameters: opername, privset
|
||||
|
||||
Sets the source user's oper name and privset. Sent after the +o mode change, or
|
||||
during burst, to inform other servers of an oper's privileges.
|
||||
|
||||
OPERSPY
|
||||
encap only
|
||||
encap target: *
|
||||
|
@ -1137,8 +1237,6 @@ CAP
|
|||
CHALLENGE
|
||||
CHANTRACE
|
||||
CLOSE
|
||||
CNOTICE
|
||||
CPRIVMSG
|
||||
DIE
|
||||
GET
|
||||
HELP
|
||||
|
@ -1153,7 +1251,6 @@ MODRESTART
|
|||
MODUNLOAD
|
||||
MONITOR
|
||||
NAMES
|
||||
OPER
|
||||
POST
|
||||
PUT
|
||||
RESTART
|
||||
|
|
|
@ -1,299 +0,0 @@
|
|||
$Id: ts6.txt 3211 2007-02-20 00:34:28Z jilles $
|
||||
|
||||
TS6 Proposal (v8)
|
||||
Written by Lee H <lee@leeh.co.uk>
|
||||
Ideas borrowed heavily from ircnet (Beeth, jv, Q)
|
||||
|
||||
- Changes between v7 and v8 -
|
||||
-----------------------------
|
||||
|
||||
In the v7 specification, the JOIN command included the channel modes of a
|
||||
channel, and acted on them following TS rules. In the v8 specification,
|
||||
JOIN will never send modes.
|
||||
|
||||
Desyncs can occur both when they are sent and when they are not. If they
|
||||
are sent, then you can have a situation where a user on one side of the
|
||||
network issues "MODE #channel -l", and a user on another side of the network
|
||||
issues "JOIN #channel" whilst the +l still exists. As the JOIN string sent
|
||||
server<->server includes the full modes at the time of the user joining,
|
||||
this will propagate the +l, but there is a -l crossing in the other
|
||||
direction. Desync will occur beyond where they intersect.
|
||||
|
||||
If the modes are not sent, then a lower TS JOIN command, or a JOIN command
|
||||
that creates a channel will cause a desync.
|
||||
|
||||
It is judged that the desync with sending the modes is worse than the desync
|
||||
by not sending them, as such the v8 specification dictates modes are not
|
||||
sent with a JOIN command server<->server.
|
||||
|
||||
The v8 specification also clarifies that servers may issue TMODE.
|
||||
|
||||
- Introduction -
|
||||
----------------
|
||||
|
||||
This document aims to fix some of the flaws that are still present in the
|
||||
current TS system.
|
||||
|
||||
Whilst only one person may use a nickname at any one time, they are not
|
||||
a reliable method of directing commands between servers. Clients can change
|
||||
their nicknames, which can create desyncs. A reliable method of directing
|
||||
messages between servers is required so that a message will always reach the
|
||||
intended destination, even if the client changes nicks in between.
|
||||
|
||||
UID solves this problem by ensuring that a client has a unique ID for the
|
||||
duration of his connection.
|
||||
|
||||
This document also aims to solve the lack of TS rules to channel 'bans' on
|
||||
a netburst. Bans from both sides of a TS war (losing/winning) are kept.
|
||||
Bursting the bans with a TS solves this problem.
|
||||
|
||||
There is also a race condition in the current TS system, where a user can
|
||||
issue a mode during a netburst and the mode will be set on the server
|
||||
we are bursting to.
|
||||
|
||||
|
||||
- Definitions -
|
||||
---------------
|
||||
|
||||
Throughout this document, the following terms are used:
|
||||
|
||||
SID - A servers unique ID. This is three characters long and must be in
|
||||
the form [0-9][A-Z0-9][A-Z0-9]
|
||||
ID - A clients unique ID. This is six characters long and must be in
|
||||
the form [A-Z][A-Z0-9][A-Z0-9][A-Z0-9][A-Z0-9][A-Z0-9]. The
|
||||
numbers [0-9] at the beginning of an ID are legal characters, but
|
||||
reserved for future use.
|
||||
UID - An ID concateneted to a SID. This forms the clients UID.
|
||||
TS6 - The TS version 6.
|
||||
|
||||
|
||||
- Support -
|
||||
-----------
|
||||
|
||||
Support for this document is given by the TS version 6.
|
||||
|
||||
Wherever a destination parameter or source parameter is used, it must use
|
||||
the SID or UID if the server/client has one. A TS6 capable server must
|
||||
translate any SIDs/UIDs back into the server/clients name when communicating
|
||||
with a server that does not support TS6.
|
||||
|
||||
A TS6 server must also support the QS (quitstorm) system, and the encap
|
||||
specification found here:
|
||||
http://www.leeh.co.uk/ircd/encap.txt
|
||||
|
||||
The TS6 protocol does not supports masked entities.
|
||||
|
||||
|
||||
- Nick TS rules -
|
||||
-----------------
|
||||
|
||||
A server receiving a command that requires nick TS rules must check for a
|
||||
collision between an existing user, and the nick in the received message.
|
||||
(the "new user"). The collisions must obey the rules specified in Nick TS
|
||||
collisions.
|
||||
|
||||
If the TS received is lower than the TS of the existing user the server will
|
||||
collide the existing user if the clients user@host are different, if the
|
||||
clients user@hosts are identical it will collide the new user.
|
||||
|
||||
If the TS received is equal to the TS of the existing user both clients are
|
||||
collided.
|
||||
|
||||
If the TS received is higher than the TS of the existing user, the server
|
||||
will collide the existing user if the user@hosts are identical, if the
|
||||
clients user@host are different it will collide the new user and drop the
|
||||
message.
|
||||
|
||||
|
||||
- Nick TS collisions -
|
||||
----------------------
|
||||
|
||||
If both users are to be collided, we must issue a KILL for the existing
|
||||
user to all servers. If the new user has a UID then we must also issue a
|
||||
KILL for that UID back to the server sending us data causing the collision.
|
||||
|
||||
If only the existing user is being collided, we must issue a KILL for the
|
||||
existing user to all servers except the server sending us data. If the
|
||||
existing user has a UID and the server sending us data supports TS6 then
|
||||
we must also issue a KILL for the existing users UID to the server sending
|
||||
us data.
|
||||
|
||||
If only the new user is being collided, we must issue a KILL for the new user
|
||||
back to the server sending us data if the new user has a UID.
|
||||
|
||||
|
||||
- Channel TS rules -
|
||||
--------------------
|
||||
|
||||
A server receiving a command that requires normal channel TS rules must
|
||||
apply the following rules to the command.
|
||||
|
||||
If the TS received is lower than our TS of the channel a TS6 server must
|
||||
remove status modes (+ov etc) and channel modes (+nt etc). If the
|
||||
originating server is TS6 capable (ie, it has a SID), the server must
|
||||
also remove any ban modes (+b etc). The new modes and statuses are then
|
||||
accepted.
|
||||
|
||||
If any bans are removed, the server must send to non-TS6, directly connected
|
||||
servers mode changes removing the bans after the command is propagated.
|
||||
This prevents desync with banlists, and has to be sent after as clients are
|
||||
still able to send mode changes before the triggering command arrives.
|
||||
|
||||
If the TS received is equal to our TS of the channel the server should keep
|
||||
its current modes and accept the received modes and statuses.
|
||||
|
||||
If the TS received is higher than our TS of the channel the server should keep
|
||||
its current modes and ignore the received modes and statuses. Any statuses
|
||||
given in the received message will be removed. A server must mark clients
|
||||
losing their op (+o) status who do not have a UID as 'deopped'. A server must
|
||||
ignore any "MODE" commands from a user marked as 'deopped'.
|
||||
|
||||
|
||||
- Simple channel TS rules -
|
||||
---------------------------
|
||||
|
||||
A server receiving a command that requires simple channel TS rules must
|
||||
apply the following rules to the command.
|
||||
|
||||
If the TS received is lower, or equal to our TS of the channel the modes are
|
||||
accepted. If the TS received is higher than our TS of the channel the modes
|
||||
are ignored and dropped.
|
||||
|
||||
Simple channel TS rules do not affect current modes in the channel except
|
||||
for the modes we are accepting.
|
||||
|
||||
|
||||
- The following commands are defined here as the TS6 protocol -
|
||||
---------------------------------------------------------------
|
||||
|
||||
- PASS -
|
||||
PASS <PASSWORD> TS <TS_CURRENT> :<SID>
|
||||
|
||||
This command is used for password verification with the server we are
|
||||
connecting to.
|
||||
|
||||
Due to the burst being sent on verification of the "SERVER" command, and
|
||||
"SVINFO" being sent after "SERVER", we need to be aware of the TS version
|
||||
earlier to decide whether to send a TS6 burst or not.
|
||||
|
||||
The <PASSWORD> field is the password we have stored for this server,
|
||||
<TS_CURRENT> is our current TS version. If this field is not present then
|
||||
the server does not support TS6. <SID> is the SID of the server.
|
||||
|
||||
- UID -
|
||||
:<SID> UID <NICK> <HOPS> <TS> +<UMODE> <USERNAME> <HOSTNAME> <IP> <UID> :<GECOS>
|
||||
|
||||
This command is used for introducing clients to the network.
|
||||
|
||||
The <SID> field is the SID of the server the client is connected to.
|
||||
The <NICK> field is the nick of the client being introduced. The <HOPS>
|
||||
field is the amount of server hops between the server being burst to and
|
||||
the server the client is on. The <TS> field is the TS of the client, either
|
||||
the time they connected or the time they last changed nick. The <UMODE>
|
||||
field contains the clients usermodes that need to be transmitted between
|
||||
servers. The <USERNAME> field contains the clients username/ident. The
|
||||
<HOSTNAME> field contains the clients host.
|
||||
|
||||
The <IP> field contains the clients IP. If the IP is not to be sent
|
||||
(due to a spoof etc), the field must be sent as "0". The <UID> field is the
|
||||
clients UID. The <GECOS> field is the clients gecos.
|
||||
|
||||
A server receiving a UID command must apply nick TS rules to the nick.
|
||||
|
||||
- SID -
|
||||
:<SID> SID <SERVERNAME> <HOPS> <SID> :<GECOS>
|
||||
|
||||
This command is used for introducing servers to the network.
|
||||
|
||||
The first <SID> field is the SID of the new servers uplink. The
|
||||
<SERVERNAME> field is the new servers name. The <HOPS> field is the hops
|
||||
between the server being introduced nd the server being burst to.
|
||||
|
||||
The second <SID> field is the SID of the new server. The <GECOS> field i
|
||||
is the new servers gecos.
|
||||
|
||||
Upon receiving the SID command servers must check for a SID collision.
|
||||
Two servers must not be allowed to link to the network with the same SID.
|
||||
If a server detects a SID collision it must drop the link to the directly
|
||||
connected server through which the command was received.
|
||||
|
||||
Client and servers which do not have a UID/SID must be introduced by old
|
||||
methods.
|
||||
|
||||
- SJOIN -
|
||||
:<SID> SJOIN <TS> <CHANNAME> +<CHANMODES> :<UIDS>
|
||||
|
||||
This command is used for introducing users to channels.
|
||||
|
||||
The <SID> field is the SID of the server introducing users to the channel.
|
||||
The <TS> field is the channels current TS, <CHANNAME> is the channels
|
||||
current name, <CHANMODES> are the channels current modes. <UIDS> is a
|
||||
space delimited list of clients UIDs to join to the channel. Each clients
|
||||
UID is prefixed with their status on the channel, ie "@UID" for an opped
|
||||
user. Multiple prefixes are allowed, "peons" (clients without a status) are
|
||||
not prefixed.
|
||||
|
||||
A server receiving an SJOIN must apply normal channel TS rules to the SJOIN.
|
||||
|
||||
A TS6 server must not use the SJOIN command outside of a netburst
|
||||
to introduce a single user to an existing channel. It must instead
|
||||
use the "JOIN" command defined in this specification. A TS6 server must
|
||||
still use SJOIN for creating channels.
|
||||
|
||||
- JOIN -
|
||||
:<UID> JOIN <TS> <CHANNAME> +
|
||||
|
||||
This command is used for introducing one user unopped to an existing channel.
|
||||
|
||||
The <UID> field is the UID of the client joining the channel. The
|
||||
<TS> field is the channels current TS, <CHANNAME> is the channels
|
||||
current name.
|
||||
|
||||
A server receiving a JOIN must apply normal channel TS rules to the JOIN.
|
||||
|
||||
No channel modes are sent with the JOIN command. In previous versions of
|
||||
this specification, the "+" parameter contained the channels current modes.
|
||||
A server following this version of the specification must not interpret this
|
||||
argument and must not propagate any value other than "+" for this parameter.
|
||||
|
||||
It should be noted that whilst JOIN would not normally create a
|
||||
channel or lower the timestamp, during specific conditions it can. This
|
||||
can create a desync that this specification does not rectify.
|
||||
|
||||
- BMASK -
|
||||
:<SID> BMASK <TS> <CHANNAME> <TYPE> :<MASKS>
|
||||
|
||||
This command is used for bursting channel bans to a network.
|
||||
|
||||
The <SID> field is the SID of the server bursting the bans. The
|
||||
<TS> field is the channels current TS, <CHANNAME> is the channels
|
||||
name. <TYPE> is a single character identifying the mode type (ie,
|
||||
for a ban 'b'). <MASKS> is a space delimited list of masks of the
|
||||
given mode,limited only in length to the size of the buffer as defined
|
||||
by RFC1459.
|
||||
|
||||
A server receiving a BMASK must apply simple channel TS rules to the BMASK.
|
||||
|
||||
A TS6 server must translate BMASKs into raw modes for non-TS6
|
||||
capable servers. This command must be used only after SJOIN has
|
||||
been sent for the given channel.
|
||||
|
||||
It should be noted however, that a BMASK with a lower TS should
|
||||
not be possible without a desync, due to it being sent after
|
||||
SJOIN.
|
||||
|
||||
- TMODE -
|
||||
:<SID|UID> TMODE <TS> <CHANNAME> <MODESTRING>
|
||||
|
||||
This command is used for clients issuing modes on a channel.
|
||||
|
||||
<SID|UID> is either the UID of the client setting the mode, or the SID of
|
||||
the server setting the mode. <TS> is the current TS of the channel,
|
||||
<CHANNAME> is the channels name. <MODESTRING> is the raw mode the client is
|
||||
setting.
|
||||
|
||||
A server receiving a TMODE must apply simple channel TS rules to the TMODE.
|
||||
|
||||
A TS6 server must translate MODEs issued by a local client, or received from
|
||||
a server into TMODE to send to other TS6 capable servers.
|
||||
|
1
extensions/.indent.pro
vendored
1
extensions/.indent.pro
vendored
|
@ -1 +0,0 @@
|
|||
-i8 -bli0 -cs -ut -nsai -nsaw -nsaf -npcs -nprs -l100
|
77
extensions/Makefile.am
Normal file
77
extensions/Makefile.am
Normal file
|
@ -0,0 +1,77 @@
|
|||
AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/librb/include $(LTDLINCL)
|
||||
AM_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined -shared
|
||||
AM_LDFLAGS += -export-symbols-regex _mheader
|
||||
LIBS += $(top_srcdir)/ircd/libircd.la
|
||||
|
||||
extensiondir=@moduledir@/extensions
|
||||
|
||||
extension_LTLIBRARIES = \
|
||||
chantype_dummy.la \
|
||||
chm_adminonly.la \
|
||||
chm_operonly.la \
|
||||
chm_insecure.la \
|
||||
chm_nonotice.la \
|
||||
chm_operpeace.la \
|
||||
chm_regmsg.la \
|
||||
chm_sslonly.la \
|
||||
createauthonly.la \
|
||||
createoperonly.la \
|
||||
extb_account.la \
|
||||
extb_canjoin.la \
|
||||
extb_channel.la \
|
||||
extb_guest.la \
|
||||
extb_hostmask.la \
|
||||
extb_oper.la \
|
||||
extb_server.la \
|
||||
extb_ssl.la \
|
||||
extb_realname.la \
|
||||
extb_usermode.la \
|
||||
extb_extgecos.la \
|
||||
extb_combi.la \
|
||||
force_user_invis.la \
|
||||
helpops.la \
|
||||
hurt.la \
|
||||
invite_notify.la \
|
||||
ip_cloaking.la \
|
||||
ip_cloaking_old.la \
|
||||
ip_cloaking_3.0.la \
|
||||
ip_cloaking_4.0.la \
|
||||
override.la \
|
||||
override_kick_immunity.la \
|
||||
restrict-unauthenticated.la \
|
||||
sno_channelcreate.la \
|
||||
sno_farconnect.la \
|
||||
sno_globalnickchange.la \
|
||||
sno_globaloper.la \
|
||||
umode_noctcp.la \
|
||||
m_adminwall.la \
|
||||
m_echotags.la \
|
||||
m_extendchans.la \
|
||||
m_findforwards.la \
|
||||
m_identify.la \
|
||||
m_locops.la \
|
||||
m_mkpasswd.la \
|
||||
m_ojoin.la \
|
||||
m_okick.la \
|
||||
m_omode.la \
|
||||
m_opme.la \
|
||||
m_sendbans.la \
|
||||
m_shedding.la \
|
||||
m_webirc.la \
|
||||
m_remove.la \
|
||||
hide_uncommon_channels.la \
|
||||
no_kill_services.la \
|
||||
no_locops.la \
|
||||
no_oper_invis.la \
|
||||
sasl_usercloak.la \
|
||||
drain.la \
|
||||
identify_msg.la \
|
||||
cap_realhost.la \
|
||||
invex_regonly.la \
|
||||
umode_hide_idle_time.la \
|
||||
cap_oper.la \
|
||||
example_module.la
|
||||
|
||||
if HAVE_HYPERSCAN
|
||||
extension_LTLIBRARIES += filter.la
|
||||
endif
|
|
@ -1,131 +0,0 @@
|
|||
#
|
||||
# Makefile.in for ircd/contrib
|
||||
#
|
||||
# $Id: Makefile.in 3522 2007-07-06 07:48:28Z nenolod $
|
||||
#
|
||||
CC = @CC@
|
||||
RM = @RM@
|
||||
SED = @SED@
|
||||
LEX = @LEX@
|
||||
LEXLIB = @LEXLIB@
|
||||
CFLAGS = @IRC_CFLAGS@ -DIRCD_PREFIX=\"@prefix@\"
|
||||
PICFLAGS = @PICFLAGS@
|
||||
MKDEP = @MKDEP@
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
INSTALL_SUID = @INSTALL_PROGRAM@ -o root -m 4755
|
||||
SHELL = /bin/sh
|
||||
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
libdir = @libdir@
|
||||
pkglibdir = @pkglibdir@
|
||||
moduledir = @moduledir@
|
||||
PACKAGE_TARNAME = @PACKAGE_TARNAME@
|
||||
AUTOMODULEDIR = $(moduledir)/extensions
|
||||
|
||||
SSL_LIBS = @SSL_LIBS@
|
||||
SSL_INCLUDES = @SSL_INCLUDES@
|
||||
|
||||
IRCDLIBS = @LIBS@ $(SSL_LIBS)
|
||||
|
||||
INCLUDES = -I. -I../include -I../libratbox/include $(SSL_INCLUDES)
|
||||
CPPFLAGS = ${INCLUDES} @CPPFLAGS@
|
||||
|
||||
SRCS = \
|
||||
chm_adminonly.c \
|
||||
chm_operonly.c \
|
||||
chm_operonly_compat.c \
|
||||
chm_nonotice.c \
|
||||
chm_quietunreg_compat.c \
|
||||
chm_sslonly.c \
|
||||
chm_sslonly_compat.c \
|
||||
createauthonly.c \
|
||||
createoperonly.c \
|
||||
extb_account.c \
|
||||
extb_canjoin.c \
|
||||
extb_channel.c \
|
||||
extb_hostmask.c \
|
||||
extb_oper.c \
|
||||
extb_server.c \
|
||||
extb_ssl.c \
|
||||
extb_realname.c \
|
||||
extb_usermode.c \
|
||||
extb_extgecos.c \
|
||||
extb_combi.c \
|
||||
force_user_invis.c \
|
||||
hurt.c \
|
||||
ip_cloaking.c \
|
||||
ip_cloaking_old.c \
|
||||
ip_cloaking_3.0.c \
|
||||
ip_cloaking_4.0.c \
|
||||
override.c \
|
||||
restrict-unauthenticated.c \
|
||||
sno_farconnect.c \
|
||||
sno_globalkline.c \
|
||||
sno_globaloper.c \
|
||||
sno_whois.c \
|
||||
m_42.c \
|
||||
m_adminwall.c \
|
||||
m_findforwards.c \
|
||||
m_identify.c \
|
||||
m_mkpasswd.c \
|
||||
m_ojoin.c \
|
||||
m_okick.c \
|
||||
m_omode.c \
|
||||
m_opme.c \
|
||||
m_sendbans.c \
|
||||
m_webirc.c \
|
||||
m_remove.c \
|
||||
m_roleplay.c \
|
||||
hide_uncommon_channels.c \
|
||||
no_kill_services.c \
|
||||
no_locops.c \
|
||||
no_oper_invis.c \
|
||||
spy_admin_notice.c \
|
||||
spy_info_notice.c \
|
||||
spy_links_notice.c \
|
||||
spy_motd_notice.c \
|
||||
spy_stats_notice.c \
|
||||
spy_stats_p_notice.c \
|
||||
spy_trace_notice.c \
|
||||
example_module.c
|
||||
|
||||
OBJS = ${SRCS:.c=.so}
|
||||
|
||||
default: build
|
||||
build: all
|
||||
all: $(OBJS)
|
||||
|
||||
install: all
|
||||
-@if test ! -d $(DESTDIR)$(AUTOMODULEDIR); then \
|
||||
mkdir $(DESTDIR)$(AUTOMODULEDIR); \
|
||||
fi
|
||||
@echo "Installing modules into $(DESTDIR)$(AUTOMODULEDIR) .."
|
||||
@for file in $(OBJS); do \
|
||||
$(INSTALL_DATA) $$file $(DESTDIR)$(AUTOMODULEDIR); \
|
||||
done
|
||||
|
||||
.SUFFIXES: .so
|
||||
|
||||
.c.so:
|
||||
${CC} ${PICFLAGS} ${CPPFLAGS} ${CFLAGS} ${LDFLAGS} $< -o $@
|
||||
|
||||
.PHONY: depend clean distclean
|
||||
depend:
|
||||
@${MKDEP} ${CPPFLAGS} ${SRCS} > .depend
|
||||
@sed s/\\\.o/\\\.so/ < .depend > .depend.tmp
|
||||
@sed -e '/^# DO NOT DELETE THIS LINE/,$$d' <Makefile >Makefile.depend
|
||||
@echo '# DO NOT DELETE THIS LINE!!!' >>Makefile.depend
|
||||
@echo '# make depend needs it.' >>Makefile.depend
|
||||
@cat .depend.tmp >>Makefile.depend
|
||||
@mv Makefile.depend Makefile
|
||||
@rm -f .depend.tmp .depend
|
||||
|
||||
clean:
|
||||
${RM} -f *.so *~
|
||||
|
||||
distclean: clean
|
||||
${RM} -f Makefile
|
||||
|
|
@ -1,8 +1,6 @@
|
|||
$Id: README 1622 2006-06-04 03:01:05Z beu $
|
||||
|
||||
This directory contains extensions (modules) to charybdis ircd that
|
||||
This directory contains extensions (modules) to solanum ircd that
|
||||
have been contributed by other people, or written by our development
|
||||
team. Unsupported extensions live under unsupported/.
|
||||
team.
|
||||
|
||||
|
||||
Modules
|
||||
|
@ -13,9 +11,6 @@ createauthonly.c - Only allow authenticated (identified) users to create
|
|||
|
||||
ip_cloaking.c - Cloak (spoof) the host for users that have umode +h.
|
||||
|
||||
m_42.c - The Answer to Life, the Universe, and Everything.
|
||||
Syntax: 42
|
||||
|
||||
m_adminwall.c - Sends a message to all admins network-wide (umode +a)
|
||||
Syntax: ADMINWALL :<message>
|
||||
|
||||
|
@ -84,6 +79,7 @@ extb_account.so - Account bans (+b $a[:mask])
|
|||
extb_canjoin.so - Banned from another channel (+b $j:mask)
|
||||
extb_channel.so - Other-channel bans (+b $c:mask)
|
||||
extb_extgecos.so - Extended ban (+b $x:mask)
|
||||
extb_guest.so - Unidentified bans (+b $g:mask)
|
||||
extb_oper.so - Oper bans (+b $o)
|
||||
extb_realname.so - Realname (gecos) bans (+b $r:mask)
|
||||
extb_server.so - Server bans (+b $s:mask)
|
||||
|
|
147
extensions/cap_oper.c
Normal file
147
extensions/cap_oper.c
Normal file
|
@ -0,0 +1,147 @@
|
|||
/*
|
||||
* Copyright (C) 2021 David Schultz <me@zpld.me>
|
||||
*
|
||||
* 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 2 of the License, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA
|
||||
*/
|
||||
|
||||
#include <stdinc.h>
|
||||
#include <modules.h>
|
||||
#include <capability.h>
|
||||
#include <s_conf.h>
|
||||
#include <s_serv.h>
|
||||
#include <s_newconf.h>
|
||||
#include <client.h>
|
||||
#include <msgbuf.h>
|
||||
|
||||
static char cap_oper_desc[] = "Provides the solanum.chat/oper capability";
|
||||
|
||||
static bool cap_oper_oper_visible(struct Client *);
|
||||
static void cap_oper_outbound_msgbuf(void *);
|
||||
static void cap_oper_umode_changed(void *);
|
||||
static void cap_oper_cap_change(void *);
|
||||
|
||||
static unsigned CLICAP_OPER;
|
||||
static unsigned CLICAP_OPER_AUSPEX;
|
||||
static unsigned CLICAP_OPER_JUSTOPER;
|
||||
static unsigned CLICAP_OPER_NORMAL;
|
||||
|
||||
static struct ClientCapability capdata_oper_oper = {
|
||||
.visible = cap_oper_oper_visible,
|
||||
};
|
||||
|
||||
mapi_cap_list_av2 cap_oper_caps[] = {
|
||||
{ MAPI_CAP_CLIENT, "solanum.chat/oper", NULL, &CLICAP_OPER },
|
||||
{ MAPI_CAP_CLIENT, "?oper_auspex", &capdata_oper_oper, &CLICAP_OPER_AUSPEX },
|
||||
{ MAPI_CAP_CLIENT, "?oper_justoper", &capdata_oper_oper, &CLICAP_OPER_JUSTOPER },
|
||||
{ MAPI_CAP_CLIENT, "?oper_normal", &capdata_oper_oper, &CLICAP_OPER_NORMAL },
|
||||
{ 0, NULL, NULL, NULL },
|
||||
};
|
||||
|
||||
mapi_hfn_list_av1 cap_oper_hfnlist[] = {
|
||||
{ "outbound_msgbuf", cap_oper_outbound_msgbuf, HOOK_NORMAL },
|
||||
{ "umode_changed", cap_oper_umode_changed, HOOK_MONITOR },
|
||||
{ "cap_change", cap_oper_cap_change, HOOK_MONITOR },
|
||||
{ NULL, NULL, 0 },
|
||||
};
|
||||
|
||||
static bool
|
||||
cap_oper_oper_visible(struct Client *client)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static void
|
||||
cap_oper_outbound_msgbuf(void *data_)
|
||||
{
|
||||
hook_data *data = data_;
|
||||
struct MsgBuf *msgbuf = data->arg1;
|
||||
|
||||
if (data->client == NULL || !IsPerson(data->client))
|
||||
return;
|
||||
|
||||
if (IsOper(data->client))
|
||||
{
|
||||
/* send all oper data to auspex */
|
||||
msgbuf_append_tag(msgbuf, "solanum.chat/oper", data->client->user->opername, CLICAP_OPER_AUSPEX);
|
||||
if (HasPrivilege(data->client, "oper:hidden") || ConfigFileEntry.hide_opers)
|
||||
/* these people aren't allowed to see hidden opers */
|
||||
return;
|
||||
msgbuf_append_tag(msgbuf, "solanum.chat/oper", data->client->user->opername, CLICAP_OPER_JUSTOPER);
|
||||
msgbuf_append_tag(msgbuf, "solanum.chat/oper", NULL, CLICAP_OPER_NORMAL);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
update_clicap_oper(struct Client *client)
|
||||
{
|
||||
/* clear out old caps */
|
||||
client->localClient->caps &= ~CLICAP_OPER_AUSPEX;
|
||||
client->localClient->caps &= ~CLICAP_OPER_JUSTOPER;
|
||||
client->localClient->caps &= ~CLICAP_OPER_NORMAL;
|
||||
|
||||
if (client->localClient->caps & CLICAP_OPER && HasPrivilege(client, "auspex:oper"))
|
||||
{
|
||||
/* if the client is an oper with auspex, let them see everything */
|
||||
client->localClient->caps |= CLICAP_OPER_AUSPEX;
|
||||
}
|
||||
else if (client->localClient->caps & CLICAP_OPER && IsOper(client))
|
||||
{
|
||||
/* if the client is an oper, let them see other opers */
|
||||
client->localClient->caps |= CLICAP_OPER_JUSTOPER;
|
||||
}
|
||||
else if (client->localClient->caps & CLICAP_OPER)
|
||||
{
|
||||
/* if the client is a normal user, let them see opers
|
||||
provided that server wide oper hiding is not enabled */
|
||||
client->localClient->caps |= CLICAP_OPER_NORMAL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
cap_oper_umode_changed(void *data_)
|
||||
{
|
||||
hook_data_umode_changed *data = data_;
|
||||
|
||||
if (!MyClient(data->client))
|
||||
return;
|
||||
|
||||
update_clicap_oper(data->client);
|
||||
}
|
||||
|
||||
static void
|
||||
cap_oper_cap_change(void *data_)
|
||||
{
|
||||
hook_data_cap_change *data = data_;
|
||||
|
||||
update_clicap_oper(data->client);
|
||||
}
|
||||
|
||||
static int
|
||||
modinit(void)
|
||||
{
|
||||
rb_dlink_node *ptr;
|
||||
|
||||
RB_DLINK_FOREACH(ptr, lclient_list.head)
|
||||
{
|
||||
struct Client *client = ptr->data;
|
||||
|
||||
update_clicap_oper(client);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DECLARE_MODULE_AV2(cap_oper, modinit, NULL, NULL, NULL, cap_oper_hfnlist, cap_oper_caps, NULL, cap_oper_desc);
|
124
extensions/cap_realhost.c
Normal file
124
extensions/cap_realhost.c
Normal file
|
@ -0,0 +1,124 @@
|
|||
/*
|
||||
* Copyright (C) 2020 Ed Kellett
|
||||
*
|
||||
* 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 2 of the License, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA
|
||||
*/
|
||||
|
||||
#include <stdinc.h>
|
||||
#include <modules.h>
|
||||
#include <capability.h>
|
||||
#include <s_serv.h>
|
||||
#include <s_newconf.h>
|
||||
#include <client.h>
|
||||
#include <msgbuf.h>
|
||||
|
||||
static char cap_realhost_desc[] = "Provides the solanum.chat/realhost oper-only capability";
|
||||
|
||||
static bool cap_oper_realhost_visible(struct Client *);
|
||||
static void cap_realhost_outbound_msgbuf(void *);
|
||||
static void cap_realhost_umode_changed(void *);
|
||||
static void cap_realhost_cap_change(void *);
|
||||
|
||||
static unsigned CLICAP_REALHOST;
|
||||
static unsigned CLICAP_OPER_REALHOST;
|
||||
|
||||
static struct ClientCapability capdata_oper_realhost = {
|
||||
.visible = cap_oper_realhost_visible,
|
||||
};
|
||||
|
||||
mapi_cap_list_av2 cap_realhost_caps[] = {
|
||||
{ MAPI_CAP_CLIENT, "solanum.chat/realhost", NULL, &CLICAP_REALHOST },
|
||||
{ MAPI_CAP_CLIENT, "?oper_realhost", &capdata_oper_realhost, &CLICAP_OPER_REALHOST },
|
||||
{ 0, NULL, NULL, NULL },
|
||||
};
|
||||
|
||||
mapi_hfn_list_av1 cap_realhost_hfnlist[] = {
|
||||
{ "outbound_msgbuf", cap_realhost_outbound_msgbuf, HOOK_NORMAL },
|
||||
{ "umode_changed", cap_realhost_umode_changed, HOOK_MONITOR },
|
||||
{ "cap_change", cap_realhost_cap_change, HOOK_MONITOR },
|
||||
{ NULL, NULL, 0 },
|
||||
};
|
||||
|
||||
static bool
|
||||
cap_oper_realhost_visible(struct Client *client)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static void
|
||||
cap_realhost_outbound_msgbuf(void *data_)
|
||||
{
|
||||
hook_data *data = data_;
|
||||
struct MsgBuf *msgbuf = data->arg1;
|
||||
|
||||
if (data->client == NULL || !IsPerson(data->client))
|
||||
return;
|
||||
|
||||
if (!IsIPSpoof(data->client) && !EmptyString(data->client->sockhost) && strcmp(data->client->sockhost, "0"))
|
||||
{
|
||||
msgbuf_append_tag(msgbuf, "solanum.chat/ip", data->client->sockhost,
|
||||
IsDynSpoof(data->client) ? CLICAP_OPER_REALHOST : CLICAP_REALHOST);
|
||||
}
|
||||
|
||||
if (!EmptyString(data->client->orighost))
|
||||
msgbuf_append_tag(msgbuf, "solanum.chat/realhost", data->client->orighost, CLICAP_OPER_REALHOST);
|
||||
}
|
||||
|
||||
static inline void
|
||||
update_clicap_oper_realhost(struct Client *client)
|
||||
{
|
||||
client->localClient->caps &= ~CLICAP_OPER_REALHOST;
|
||||
if (client->localClient->caps & CLICAP_REALHOST && HasPrivilege(client, "auspex:hostname"))
|
||||
{
|
||||
client->localClient->caps |= CLICAP_OPER_REALHOST;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
cap_realhost_umode_changed(void *data_)
|
||||
{
|
||||
hook_data_umode_changed *data = data_;
|
||||
|
||||
if (!MyClient(data->client))
|
||||
return;
|
||||
|
||||
update_clicap_oper_realhost(data->client);
|
||||
}
|
||||
|
||||
static void
|
||||
cap_realhost_cap_change(void *data_)
|
||||
{
|
||||
hook_data_cap_change *data = data_;
|
||||
|
||||
update_clicap_oper_realhost(data->client);
|
||||
}
|
||||
|
||||
static int
|
||||
modinit(void)
|
||||
{
|
||||
rb_dlink_node *ptr;
|
||||
|
||||
RB_DLINK_FOREACH(ptr, lclient_list.head)
|
||||
{
|
||||
struct Client *client = ptr->data;
|
||||
|
||||
update_clicap_oper_realhost(client);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DECLARE_MODULE_AV2(cap_realhost, modinit, NULL, NULL, NULL, cap_realhost_hfnlist, cap_realhost_caps, NULL, cap_realhost_desc);
|
30
extensions/chantype_dummy.c
Normal file
30
extensions/chantype_dummy.c
Normal file
|
@ -0,0 +1,30 @@
|
|||
/* dummy channel type (>): just a global channel type */
|
||||
|
||||
#include "stdinc.h"
|
||||
#include "modules.h"
|
||||
#include "client.h"
|
||||
#include "ircd.h"
|
||||
#include "supported.h"
|
||||
|
||||
static const char chantype_desc[] = "Secondary global channel type (>)";
|
||||
|
||||
static int _modinit(void);
|
||||
static void _moddeinit(void);
|
||||
|
||||
DECLARE_MODULE_AV2(chantype_dummy, _modinit, _moddeinit, NULL, NULL, NULL, NULL, NULL, chantype_desc);
|
||||
|
||||
static int
|
||||
_modinit(void)
|
||||
{
|
||||
CharAttrs['>'] |= CHANPFX_C;
|
||||
chantypes_update();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
_moddeinit(void)
|
||||
{
|
||||
CharAttrs['>'] &= ~CHANPFX_C;
|
||||
chantypes_update();
|
||||
}
|
|
@ -10,10 +10,13 @@
|
|||
#include "numeric.h"
|
||||
#include "chmode.h"
|
||||
|
||||
static void h_can_join(hook_data_channel *);
|
||||
static const char chm_adminonly_desc[] =
|
||||
"Enables channel mode +A that blocks non-admins from joining a channel";
|
||||
|
||||
static void h_can_join(void *);
|
||||
|
||||
mapi_hfn_list_av1 adminonly_hfnlist[] = {
|
||||
{ "can_join", (hookfn) h_can_join },
|
||||
{ "can_join", h_can_join },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
|
@ -35,11 +38,12 @@ _moddeinit(void)
|
|||
cflag_orphan('A');
|
||||
}
|
||||
|
||||
DECLARE_MODULE_AV1(chm_adminonly, _modinit, _moddeinit, NULL, NULL, adminonly_hfnlist, "$Revision$");
|
||||
DECLARE_MODULE_AV2(chm_adminonly, _modinit, _moddeinit, NULL, NULL, adminonly_hfnlist, NULL, NULL, chm_adminonly_desc);
|
||||
|
||||
static void
|
||||
h_can_join(hook_data_channel *data)
|
||||
h_can_join(void *data_)
|
||||
{
|
||||
hook_data_channel *data = data_;
|
||||
struct Client *source_p = data->client;
|
||||
struct Channel *chptr = data->chptr;
|
||||
|
||||
|
|
58
extensions/chm_insecure.c
Normal file
58
extensions/chm_insecure.c
Normal file
|
@ -0,0 +1,58 @@
|
|||
#include "stdinc.h"
|
||||
#include "modules.h"
|
||||
#include "hook.h"
|
||||
#include "client.h"
|
||||
#include "ircd.h"
|
||||
#include "send.h"
|
||||
#include "s_conf.h"
|
||||
#include "s_user.h"
|
||||
#include "s_serv.h"
|
||||
#include "numeric.h"
|
||||
#include "chmode.h"
|
||||
|
||||
static const char chm_insecure_desc[] =
|
||||
"Adds channel mode +U that allows non-SSL users to join a channel, "
|
||||
"disallowing them by default";
|
||||
|
||||
static void h_can_join(void *);
|
||||
|
||||
mapi_hfn_list_av1 sslonly_hfnlist[] = {
|
||||
{ "can_join", h_can_join },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static unsigned int mymode;
|
||||
|
||||
static int
|
||||
_modinit(void)
|
||||
{
|
||||
mymode = cflag_add('U', chm_simple);
|
||||
if (mymode == 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
_moddeinit(void)
|
||||
{
|
||||
cflag_orphan('U');
|
||||
}
|
||||
|
||||
DECLARE_MODULE_AV2(chm_insecure, _modinit, _moddeinit, NULL, NULL, sslonly_hfnlist, NULL, NULL, chm_insecure_desc);
|
||||
|
||||
static void
|
||||
h_can_join(void *data_)
|
||||
{
|
||||
hook_data_channel *data = data_;
|
||||
struct Client *source_p = data->client;
|
||||
struct Channel *chptr = data->chptr;
|
||||
|
||||
if(!(chptr->mode.mode & mymode) && !IsSecureClient(source_p)) {
|
||||
/* XXX This is equal to ERR_THROTTLE */
|
||||
sendto_one_numeric(source_p, 480, "%s :Cannot join channel (-U) - SSL/TLS required", chptr->chname);
|
||||
data->approved = ERR_CUSTOM;
|
||||
}
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue