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
|
tags
|
||||||
Makefile
|
Makefile
|
||||||
*~
|
*~
|
||||||
|
*.a
|
||||||
*.o
|
*.o
|
||||||
*.so
|
*.so
|
||||||
*.lo
|
*.lo
|
||||||
|
@ -9,31 +10,71 @@ Makefile
|
||||||
*.log
|
*.log
|
||||||
*.sw?
|
*.sw?
|
||||||
.deps
|
.deps
|
||||||
|
.dirstamp
|
||||||
.libs
|
.libs
|
||||||
autom4te.cache
|
authd/authd
|
||||||
bandb/bandb
|
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.log
|
||||||
config.status
|
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
|
include/setup.h
|
||||||
libratbox/include/libratbox_config.h
|
include/setup.h.in
|
||||||
libratbox/include/librb-config.h
|
ircd/solanum
|
||||||
libratbox/include/stamp-h1
|
ircd/ircd_parser.c
|
||||||
libratbox/libratbox.pc
|
ircd/ircd_parser.h
|
||||||
libratbox/libtool
|
ircd/ircd_lexer.c
|
||||||
libratbox/src/version.c
|
ircd/version.c
|
||||||
libratbox/src/version.c.last
|
ircd/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
|
|
||||||
ssld/ssld
|
ssld/ssld
|
||||||
|
wsockd/wsockd
|
||||||
|
testsuite/ircd.pid.*
|
||||||
|
tools/solanum-mkpasswd
|
||||||
|
tools/solanum-mkfingerprint
|
||||||
tools/genssl
|
tools/genssl
|
||||||
tools/mkpasswd
|
tools/mkpasswd
|
||||||
tools/viconf
|
tools/viconf
|
||||||
include/serno.h
|
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>
|
Aaron Sethman <androsyn@ratbox.org> androsyn <devnull@localhost>
|
||||||
Alexander Færøy <ahf@0x90.dk> Alexander F?r?y <ahf@0x90.dk>
|
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>
|
Brett Greenham <taros@shadowircd.net> B.Greenham <taros@shadowircd.net>
|
||||||
Chris Mills <chris@chrisam.net> TheChrisAM <chris@chrisam.net>
|
Chris Mills <chris@chrisam.net> TheChrisAM <chris@chrisam.net>
|
||||||
Chris Mills <chris@chrisam.net> freenode!ChrisAM <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>
|
Elly Fong-Jones <elly@leptoquark.net> Elly <elly@leptoquark.net>
|
||||||
Jilles Tjoelker <jilles@stack.nl> jilles <devnull@localhost>
|
Jilles Tjoelker <jilles@stack.nl> jilles <devnull@localhost>
|
||||||
Nathan Phillip Brink <binki@gentoo.org> <ohnobinki@ohnopublishing.net>
|
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@ircd-charybdis.ru>
|
||||||
Valeriy Yatsko <dwr@shadowircd.net> <darkwire@sellcenter.ru>
|
Valeriy Yatsko <dwr@shadowircd.net> <darkwire@sellcenter.ru>
|
||||||
Valeriy Yatsko <dwr@shadowircd.net> <dwr@it-penza.org>
|
Valeriy Yatsko <dwr@shadowircd.net> <dwr@it-penza.org>
|
||||||
William Pitcock <nenolod@dereferenced.org> <nenolod@atheme.org>
|
Christine Dodrill <shadow.h511@gmail.com> <quora@lavabit.com>
|
||||||
William Pitcock <nenolod@dereferenced.org> nenolod <devnull@localhost>
|
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
|
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
|
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
|
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 the Charybdis website at: http://www.charybdis.io/
|
||||||
Visit us on IRC at: irc.charybdis.io #charybdis
|
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
|
GNU GENERAL PUBLIC LICENSE
|
||||||
Version 2, June 1991
|
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
|
|
202
NEWS.md
202
NEWS.md
|
@ -1,5 +1,6 @@
|
||||||
# News
|
# News
|
||||||
|
|
||||||
|
<<<<<<< .merge_file_h36DbE
|
||||||
This is charybdis 3.5.7, Copyright (c) 2005-2019 Charybdis team.
|
This is charybdis 3.5.7, Copyright (c) 2005-2019 Charybdis team.
|
||||||
See LICENSE for licensing details (GPL v2).
|
See LICENSE for licensing details (GPL v2).
|
||||||
|
|
||||||
|
@ -107,6 +108,205 @@ This is a minor bugfix release only
|
||||||
|
|
||||||
### misc
|
### misc
|
||||||
- Backport various ssld IPC improvements from master.
|
- 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
|
## charybdis-3.5.0
|
||||||
|
|
||||||
|
@ -757,7 +957,7 @@ This is a minor bugfix release only
|
||||||
## charybdis-1.0
|
## charybdis-1.0
|
||||||
|
|
||||||
- Implement channel mode +L for channel list limit exemptions.
|
- Implement channel mode +L for channel list limit exemptions.
|
||||||
- Implement channel mode +P primarily as a status mode, permanant
|
- Implement channel mode +P primarily as a status mode, permanant
|
||||||
channel -- this is usually enforced via services registrations.
|
channel -- this is usually enforced via services registrations.
|
||||||
- Change behaviour of /stats p: now displays all staff members instead
|
- Change behaviour of /stats p: now displays all staff members instead
|
||||||
of local ones only.
|
of local ones only.
|
||||||
|
|
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
|
Solanum is an IRCv3 server designed to be highly scalable. It implements IRCv3.1 and some parts of IRCv3.2.
|
||||||
used with an IRCv3-capable services implementation such as [Atheme][atheme] or [Anope][anope].
|
|
||||||
|
|
||||||
[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/
|
[anope]: http://www.anope.org/
|
||||||
|
|
||||||
# necessary requirements
|
# necessary requirements
|
||||||
|
|
||||||
* A supported platform
|
* A supported platform
|
||||||
* A working dynamic load library.
|
* A working dynamic library system
|
||||||
* A working lex. Solaris /usr/ccs/bin/lex appears to be broken, on this system flex should be used.
|
* 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
|
# feature specific requirements
|
||||||
|
|
||||||
* For SSL/TLS client and server connections, one of:
|
* For SSL/TLS client and server connections, one of:
|
||||||
|
|
||||||
|
<<<<<<< .merge_file_7Huc5m
|
||||||
* OpenSSL 1.0.0 or newer (--enable-openssl)
|
* OpenSSL 1.0.0 or newer (--enable-openssl)
|
||||||
* LibreSSL (--enable-openssl)
|
* LibreSSL (--enable-openssl)
|
||||||
* MbedTLS (--enable-mbedtls)
|
* MbedTLS (--enable-mbedtls)
|
||||||
* GnuTLS (--enable-gnutls)
|
* 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.
|
* 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,
|
(Using CHALLENGE is not recommended for new deployments, so if you want to use a different TLS library,
|
||||||
feel free.)
|
feel free.)
|
||||||
|
|
||||||
|
<<<<<<< .merge_file_7Huc5m
|
||||||
* For ECDHE under OpenSSL, on Solaris and RHEL/Fedora (and its derivatives such as CentOS) you will
|
* 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.
|
need to compile your own OpenSSL on these systems, as they have removed support for ECC/ECDHE.
|
||||||
Alternatively, consider using another library (see above).
|
Alternatively, consider using another library (see above).
|
||||||
|
@ -32,35 +84,28 @@ used with an IRCv3-capable services implementation such as [Atheme][atheme] or [
|
||||||
# tips
|
# tips
|
||||||
|
|
||||||
* To report bugs in charybdis, visit us on IRC at chat.freenode.net #charybdis
|
* 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
|
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
|
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.
|
`127.0.0.1` for a resolver as a last-ditch effort.
|
||||||
|
|
||||||
* FREEBSD USERS: if you are compiling with ipv6 you may experience
|
# git access
|
||||||
problems with ipv4 due to the way the socket code is written. To
|
|
||||||
fix this you must: "sysctl net.inet6.ip6.v6only=0"
|
|
||||||
|
|
||||||
* SOLARIS USERS: this code appears to tickle a bug in older gcc and
|
* The Solanum git repository can be checked out using the following command:
|
||||||
egcs ONLY on 64-bit Solaris7. gcc-2.95 and SunPro C on 64bit should
|
`git clone https://github.com/solanum-ircd/solanum`
|
||||||
work fine, and any gcc or SunPro compiled on 32bit.
|
|
||||||
|
|
||||||
* SUPPORTED PLATFORMS: this code should compile without any warnings on:
|
* Solanum's git repository can be browsed over the Internet at the following address:
|
||||||
|
https://github.com/solanum-ircd/solanum
|
||||||
* 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
|
|
||||||
|
|
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
|
* 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
|
#ifndef _SOLANUM_RES_H
|
||||||
#define _CHARYBDIS_RES_H
|
#define _SOLANUM_RES_H
|
||||||
|
|
||||||
#include "ircd_defs.h"
|
|
||||||
#include "common.h"
|
|
||||||
#include "reslib.h"
|
|
||||||
#include "match.h"
|
|
||||||
#include "ircd.h"
|
|
||||||
|
|
||||||
/* Maximum number of nameservers in /etc/resolv.conf we care about
|
/* 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
|
* a few more than that ;) --nenolod
|
||||||
*/
|
*/
|
||||||
#define IRCD_MAXNS 10
|
#define IRCD_MAXNS 10
|
||||||
|
#define RESOLVER_HOSTLEN 255
|
||||||
|
|
||||||
struct DNSReply
|
struct DNSReply
|
||||||
{
|
{
|
||||||
|
@ -36,10 +30,8 @@ extern int irc_nscount;
|
||||||
|
|
||||||
extern void init_resolver(void);
|
extern void init_resolver(void);
|
||||||
extern void restart_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_byname_type(const char *, struct DNSQuery *, int);
|
||||||
extern void gethost_byaddr(const struct rb_sockaddr_storage *, struct DNSQuery *);
|
extern void gethost_byaddr(const struct rb_sockaddr_storage *, struct DNSQuery *);
|
||||||
extern void add_local_domain(char *, size_t);
|
extern void build_rdns(char *, size_t, const struct rb_sockaddr_storage *, const char *);
|
||||||
extern void report_dns_servers(struct Client *);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -76,9 +76,10 @@
|
||||||
* - Dianora
|
* - Dianora
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <rb_lib.h>
|
||||||
|
#include <netdb.h>
|
||||||
#include "stdinc.h"
|
#include "stdinc.h"
|
||||||
#include "ircd_defs.h"
|
#include "ircd_defs.h"
|
||||||
#include "common.h"
|
|
||||||
#include "ircd.h"
|
#include "ircd.h"
|
||||||
#include "res.h"
|
#include "res.h"
|
||||||
#include "reslib.h"
|
#include "reslib.h"
|
||||||
|
@ -89,9 +90,6 @@
|
||||||
#define DNS_LABELTYPE_BITSTRING 0x41
|
#define DNS_LABELTYPE_BITSTRING 0x41
|
||||||
#define DNS_MAXLINE 128
|
#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];
|
struct rb_sockaddr_storage irc_nsaddr_list[IRCD_MAXNS];
|
||||||
int irc_nscount = 0;
|
int irc_nscount = 0;
|
||||||
char irc_domain[IRCD_RES_HOSTLEN + 1];
|
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*/
|
-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 int parse_resvconf(void);
|
||||||
static void add_nameserver(const char *);
|
static void add_nameserver(const char *);
|
||||||
|
|
||||||
static const char digits[] = "0123456789";
|
|
||||||
static int labellen(const unsigned char *lp);
|
static int labellen(const unsigned char *lp);
|
||||||
static int special(int ch);
|
static int special(int ch);
|
||||||
static int printable(int ch);
|
static int printable(int ch);
|
||||||
|
@ -163,9 +161,6 @@ parse_resvconf(void)
|
||||||
char input[DNS_MAXLINE];
|
char input[DNS_MAXLINE];
|
||||||
FILE *file;
|
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)
|
if ((file = fopen("/etc/resolv.conf", "r")) == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
@ -177,7 +172,7 @@ parse_resvconf(void)
|
||||||
|
|
||||||
p = input;
|
p = input;
|
||||||
/* skip until something thats not a space is seen */
|
/* skip until something thats not a space is seen */
|
||||||
while (IsSpace(*p))
|
while (isspace(*p))
|
||||||
p++;
|
p++;
|
||||||
/* if at this point, have a '\0' then continue */
|
/* if at this point, have a '\0' then continue */
|
||||||
if (*p == '\0')
|
if (*p == '\0')
|
||||||
|
@ -189,7 +184,7 @@ parse_resvconf(void)
|
||||||
|
|
||||||
/* skip until a space is found */
|
/* skip until a space is found */
|
||||||
opt = p;
|
opt = p;
|
||||||
while (!IsSpace(*p) && *p != '\0')
|
while (!isspace(*p) && *p != '\0')
|
||||||
p++;
|
p++;
|
||||||
if (*p == '\0')
|
if (*p == '\0')
|
||||||
continue; /* no arguments?.. ignore this line */
|
continue; /* no arguments?.. ignore this line */
|
||||||
|
@ -197,16 +192,16 @@ parse_resvconf(void)
|
||||||
*p++ = '\0';
|
*p++ = '\0';
|
||||||
|
|
||||||
/* skip these spaces that are before the argument */
|
/* skip these spaces that are before the argument */
|
||||||
while (IsSpace(*p))
|
while (isspace(*p))
|
||||||
p++;
|
p++;
|
||||||
/* Now arg should be right where p is pointing */
|
/* Now arg should be right where p is pointing */
|
||||||
arg = p;
|
arg = p;
|
||||||
if ((p = strpbrk(arg, " \t")) != NULL)
|
if ((p = strpbrk(arg, " \t")) != NULL)
|
||||||
*p = '\0'; /* take the first word */
|
*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));
|
rb_strlcpy(irc_domain, arg, sizeof(irc_domain));
|
||||||
else if (irccmp(opt, "nameserver") == 0)
|
else if (rb_strcasecmp(opt, "nameserver") == 0)
|
||||||
add_nameserver(arg);
|
add_nameserver(arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -228,10 +223,7 @@ add_nameserver(const char *arg)
|
||||||
|
|
||||||
/* Done max number of nameservers? */
|
/* Done max number of nameservers? */
|
||||||
if (irc_nscount >= IRCD_MAXNS)
|
if (irc_nscount >= IRCD_MAXNS)
|
||||||
{
|
|
||||||
ilog (L_MAIN, "Too many nameservers, ignoring %s", arg);
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
memset(&hints, 0, sizeof(hints));
|
memset(&hints, 0, sizeof(hints));
|
||||||
hints.ai_family = PF_UNSPEC;
|
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),
|
* Thinking in noninternationalized USASCII (per the DNS spec),
|
||||||
* * convert this character to lower case if it's upper case.
|
* convert this character to lower case if it's upper case.
|
||||||
* */
|
*/
|
||||||
static int
|
static int
|
||||||
mklower(int ch)
|
mklower(int ch)
|
||||||
{
|
{
|
|
@ -1,11 +1,10 @@
|
||||||
/*
|
/*
|
||||||
* include/irc_reslib.h
|
* include/irc_reslib.h
|
||||||
*
|
*
|
||||||
* $Id: reslib.h 446 2006-02-12 02:46:54Z db $
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _CHARYBDIS_RESLIB_H
|
#ifndef _SOLANUM_RESLIB_H
|
||||||
#define _CHARYBDIS_RESLIB_H
|
#define _SOLANUM_RESLIB_H
|
||||||
|
|
||||||
/* Longest hostname we're willing to work with.
|
/* Longest hostname we're willing to work with.
|
||||||
* Due to DNSBLs this is more than HOSTLEN.
|
* Due to DNSBLs this is more than HOSTLEN.
|
||||||
|
@ -79,24 +78,24 @@ typedef struct
|
||||||
*/
|
*/
|
||||||
#define IRC_NS_GET16(s, cp) { \
|
#define IRC_NS_GET16(s, cp) { \
|
||||||
const unsigned char *t_cp = (const unsigned char *)(cp); \
|
const unsigned char *t_cp = (const unsigned char *)(cp); \
|
||||||
(s) = ((u_int16_t)t_cp[0] << 8) \
|
(s) = ((uint16_t)t_cp[0] << 8) \
|
||||||
| ((u_int16_t)t_cp[1]) \
|
| ((uint16_t)t_cp[1]) \
|
||||||
; \
|
; \
|
||||||
(cp) += NS_INT16SZ; \
|
(cp) += NS_INT16SZ; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define IRC_NS_GET32(l, cp) { \
|
#define IRC_NS_GET32(l, cp) { \
|
||||||
const unsigned char *t_cp = (const unsigned char *)(cp); \
|
const unsigned char *t_cp = (const unsigned char *)(cp); \
|
||||||
(l) = ((u_int32_t)t_cp[0] << 24) \
|
(l) = ((uint32_t)t_cp[0] << 24) \
|
||||||
| ((u_int32_t)t_cp[1] << 16) \
|
| ((uint32_t)t_cp[1] << 16) \
|
||||||
| ((u_int32_t)t_cp[2] << 8) \
|
| ((uint32_t)t_cp[2] << 8) \
|
||||||
| ((u_int32_t)t_cp[3]) \
|
| ((uint32_t)t_cp[3]) \
|
||||||
; \
|
; \
|
||||||
(cp) += NS_INT32SZ; \
|
(cp) += NS_INT32SZ; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define IRC_NS_PUT16(s, cp) { \
|
#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); \
|
unsigned char *t_cp = (unsigned char *)(cp); \
|
||||||
*t_cp++ = t_s >> 8; \
|
*t_cp++ = t_s >> 8; \
|
||||||
*t_cp = t_s; \
|
*t_cp = t_s; \
|
||||||
|
@ -104,7 +103,7 @@ typedef struct
|
||||||
}
|
}
|
||||||
|
|
||||||
#define IRC_NS_PUT32(l, cp) { \
|
#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); \
|
unsigned char *t_cp = (unsigned char *)(cp); \
|
||||||
*t_cp++ = t_l >> 24; \
|
*t_cp++ = t_l >> 24; \
|
||||||
*t_cp++ = t_l >> 16; \
|
*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
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
* POSSIBILITY OF SUCH DAMAGE.
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
|
||||||
* $Id: bandb.c 26094 2008-09-19 15:33:46Z androsyn $
|
|
||||||
*/
|
*/
|
||||||
#include "setup.h"
|
#include "setup.h"
|
||||||
#include <ratbox_lib.h>
|
#include <rb_lib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "rsdb.h"
|
#include "rsdb.h"
|
||||||
#include "common.h"
|
#include "ircd_defs.h"
|
||||||
|
|
||||||
|
|
||||||
#define MAXPARA 10
|
#define MAXPARA 10
|
||||||
|
@ -161,11 +159,11 @@ list_bans(void)
|
||||||
for(j = 0; j < table.row_count; j++)
|
for(j = 0; j < table.row_count; j++)
|
||||||
{
|
{
|
||||||
if(i == BANDB_KLINE)
|
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],
|
bandb_letter[i], table.row[j][0],
|
||||||
table.row[j][1], table.row[j][2], table.row[j][3]);
|
table.row[j][1], table.row[j][2], table.row[j][3]);
|
||||||
else
|
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],
|
bandb_letter[i], table.row[j][0],
|
||||||
table.row[j][2], table.row[j][3]);
|
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 __attribute__((noreturn))
|
||||||
|
=======
|
||||||
|
static void
|
||||||
|
error_cb(rb_helper *helper) __attribute__((noreturn));
|
||||||
|
|
||||||
|
static void
|
||||||
|
>>>>>>> .merge_file_OF4zx2
|
||||||
error_cb(rb_helper *helper)
|
error_cb(rb_helper *helper)
|
||||||
{
|
{
|
||||||
if(in_transaction)
|
if(in_transaction)
|
||||||
|
@ -246,18 +251,15 @@ error_cb(rb_helper *helper)
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef WINDOWS
|
|
||||||
static void
|
static void
|
||||||
dummy_handler(int sig)
|
dummy_handler(int sig)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
setup_signals(void)
|
setup_signals(void)
|
||||||
{
|
{
|
||||||
#ifndef WINDOWS
|
|
||||||
struct sigaction act;
|
struct sigaction act;
|
||||||
|
|
||||||
act.sa_flags = 0;
|
act.sa_flags = 0;
|
||||||
|
@ -280,15 +282,21 @@ setup_signals(void)
|
||||||
|
|
||||||
act.sa_handler = dummy_handler;
|
act.sa_handler = dummy_handler;
|
||||||
sigaction(SIGALRM, &act, 0);
|
sigaction(SIGALRM, &act, 0);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
<<<<<<< .merge_file_OcfD4C
|
||||||
static void __attribute__((noreturn))
|
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)
|
db_error_cb(const char *errstr)
|
||||||
{
|
{
|
||||||
char buf[256];
|
char buf[256];
|
||||||
rb_snprintf(buf, sizeof(buf), "! :%s", errstr);
|
snprintf(buf, sizeof(buf), "! :%s", errstr);
|
||||||
rb_helper_write(bandb_helper, "%s", buf);
|
rb_helper_write(bandb_helper, "%s", buf);
|
||||||
rb_sleep(1 << 30, 0);
|
rb_sleep(1 << 30, 0);
|
||||||
exit(1);
|
exit(1);
|
||||||
|
@ -302,10 +310,9 @@ main(int argc, char *argv[])
|
||||||
if(bandb_helper == NULL)
|
if(bandb_helper == NULL)
|
||||||
{
|
{
|
||||||
fprintf(stderr,
|
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,
|
fprintf(stderr,
|
||||||
"However I will print my Id tag $Id: bandb.c 26094 2008-09-19 15:33:46Z androsyn $\n");
|
"You aren't supposed to run me directly (did you want solanum-bantool?). Exiting.\n");
|
||||||
fprintf(stderr, "Have a nice day\n");
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
rsdb_init(db_error_cb);
|
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
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||||
* USA
|
* USA
|
||||||
*
|
*
|
||||||
* $Id: bantool.c 26164 2008-10-26 19:52:43Z androsyn $
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* The following server admins have either contributed various configs to test against,
|
* The following server admins have either contributed various configs to test against,
|
||||||
* or helped with debugging and feature requests. Many thanks to them.
|
* or helped with debugging and feature requests. Many thanks to them.
|
||||||
* stevoo / efnet.port80.se
|
* stevoo / efnet.port80.se
|
||||||
|
@ -43,11 +40,9 @@
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#include "stdinc.h"
|
#include "stdinc.h"
|
||||||
#include "common.h"
|
|
||||||
#include "rsdb.h"
|
#include "rsdb.h"
|
||||||
|
|
||||||
#define EmptyString(x) ((x == NULL) || (*(x) == '\0'))
|
#define EmptyString(x) ((x == NULL) || (*(x) == '\0'))
|
||||||
#define CheckEmpty(x) EmptyString(x) ? "" : x
|
|
||||||
|
|
||||||
#define BT_VERSION "0.4.1"
|
#define BT_VERSION "0.4.1"
|
||||||
|
|
||||||
|
@ -96,16 +91,16 @@ struct counter
|
||||||
/* flags set by command line options */
|
/* flags set by command line options */
|
||||||
struct flags
|
struct flags
|
||||||
{
|
{
|
||||||
int none;
|
bool none;
|
||||||
int export;
|
bool export;
|
||||||
int import;
|
bool import;
|
||||||
int verify;
|
bool verify;
|
||||||
int vacuum;
|
bool vacuum;
|
||||||
int pretend;
|
bool pretend;
|
||||||
int verbose;
|
bool verbose;
|
||||||
int wipe;
|
bool wipe;
|
||||||
int dupes_ok;
|
bool dupes_ok;
|
||||||
} flag = {YES, NO, NO, NO, NO, NO, NO, NO, NO};
|
} flag = {true, false, false, false, false, false, false, false, false};
|
||||||
/* *INDENT-ON* */
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
static int table_has_rows(const char *table);
|
static int table_has_rows(const char *table);
|
||||||
|
@ -148,32 +143,32 @@ main(int argc, char *argv[])
|
||||||
print_help(EXIT_SUCCESS);
|
print_help(EXIT_SUCCESS);
|
||||||
/* noreturn call above, this is unreachable */
|
/* noreturn call above, this is unreachable */
|
||||||
case 'i':
|
case 'i':
|
||||||
flag.none = NO;
|
flag.none = false;
|
||||||
flag.import = YES;
|
flag.import = true;
|
||||||
break;
|
break;
|
||||||
case 'e':
|
case 'e':
|
||||||
flag.none = NO;
|
flag.none = false;
|
||||||
flag.export = YES;
|
flag.export = true;
|
||||||
break;
|
break;
|
||||||
case 'u':
|
case 'u':
|
||||||
flag.none = NO;
|
flag.none = false;
|
||||||
flag.verify = YES;
|
flag.verify = true;
|
||||||
break;
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
flag.none = NO;
|
flag.none = false;
|
||||||
flag.vacuum = YES;
|
flag.vacuum = true;
|
||||||
break;
|
break;
|
||||||
case 'p':
|
case 'p':
|
||||||
flag.pretend = YES;
|
flag.pretend = true;
|
||||||
break;
|
break;
|
||||||
case 'v':
|
case 'v':
|
||||||
flag.verbose = YES;
|
flag.verbose = true;
|
||||||
break;
|
break;
|
||||||
case 'w':
|
case 'w':
|
||||||
flag.wipe = YES;
|
flag.wipe = true;
|
||||||
break;
|
break;
|
||||||
case 'd':
|
case 'd':
|
||||||
flag.dupes_ok = YES;
|
flag.dupes_ok = true;
|
||||||
break;
|
break;
|
||||||
default: /* '?' */
|
default: /* '?' */
|
||||||
print_help(EXIT_FAILURE);
|
print_help(EXIT_FAILURE);
|
||||||
|
@ -201,10 +196,9 @@ main(int argc, char *argv[])
|
||||||
rb_strlcpy(etc, ETCPATH, sizeof(ETCPATH));
|
rb_strlcpy(etc, ETCPATH, sizeof(ETCPATH));
|
||||||
|
|
||||||
fprintf(stdout,
|
fprintf(stdout,
|
||||||
"* ircd-ratbox bantool v.%s ($Id: bantool.c 26164 2008-10-26 19:52:43Z androsyn $)\n",
|
"* solanum bantool v.%s\n", BT_VERSION);
|
||||||
BT_VERSION);
|
|
||||||
|
|
||||||
if(flag.pretend == NO)
|
if(flag.pretend == false)
|
||||||
{
|
{
|
||||||
if(rsdb_init(db_error_cb) == -1)
|
if(rsdb_init(db_error_cb) == -1)
|
||||||
{
|
{
|
||||||
|
@ -218,7 +212,7 @@ main(int argc, char *argv[])
|
||||||
|
|
||||||
if(flag.import && flag.wipe)
|
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++)
|
for(i = 0; i < 3; i++)
|
||||||
fprintf(stdout,
|
fprintf(stdout,
|
||||||
"* WARNING: YOU ARE ABOUT TO WIPE YOUR DATABASE!\n");
|
"* WARNING: YOU ARE ABOUT TO WIPE YOUR DATABASE!\n");
|
||||||
|
@ -230,16 +224,19 @@ main(int argc, char *argv[])
|
||||||
wipe_schema();
|
wipe_schema();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(flag.verbose && flag.dupes_ok == YES)
|
if(flag.verbose && flag.dupes_ok == true)
|
||||||
fprintf(stdout, "* Allowing duplicate bans...\n");
|
fprintf(stdout, "* Allowing duplicate bans...\n");
|
||||||
|
|
||||||
/* checking for our files to import or export */
|
/* checking for our files to import or export */
|
||||||
for(i = 0; i < LAST_BANDB_TYPE; i++)
|
for(i = 0; i < LAST_BANDB_TYPE; i++)
|
||||||
{
|
{
|
||||||
rb_snprintf(conf, sizeof(conf), "%s/%s.conf%s",
|
if (snprintf(conf, sizeof(conf), "%s/%s.conf%s",
|
||||||
etc, bandb_table[i], bandb_suffix[i]);
|
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);
|
rsdb_transaction(RSDB_TRANS_START);
|
||||||
|
|
||||||
if(flag.import)
|
if(flag.import)
|
||||||
|
@ -248,7 +245,7 @@ main(int argc, char *argv[])
|
||||||
if(flag.export)
|
if(flag.export)
|
||||||
export_config(conf, i);
|
export_config(conf, i);
|
||||||
|
|
||||||
if(flag.import && flag.pretend == NO)
|
if(flag.import && flag.pretend == false)
|
||||||
rsdb_transaction(RSDB_TRANS_END);
|
rsdb_transaction(RSDB_TRANS_END);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -297,11 +294,11 @@ export_config(const char *conf, int id)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(strstr(conf, ".perm") != 0)
|
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",
|
"SELECT DISTINCT mask1,mask2,reason,oper,time FROM %s WHERE perm = 1 ORDER BY time",
|
||||||
bandb_table[id]);
|
bandb_table[id]);
|
||||||
else
|
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",
|
"SELECT DISTINCT mask1,mask2,reason,oper,time FROM %s WHERE perm = 0 ORDER BY time",
|
||||||
bandb_table[id]);
|
bandb_table[id]);
|
||||||
|
|
||||||
|
@ -330,7 +327,7 @@ export_config(const char *conf, int id)
|
||||||
{
|
{
|
||||||
case BANDB_DLINE:
|
case BANDB_DLINE:
|
||||||
case BANDB_DLINE_PERM:
|
case BANDB_DLINE_PERM:
|
||||||
rb_snprintf(buf, sizeof(buf),
|
snprintf(buf, sizeof(buf),
|
||||||
"\"%s\",\"%s\",\"\",\"%s\",\"%s\",%s\n",
|
"\"%s\",\"%s\",\"\",\"%s\",\"%s\",%s\n",
|
||||||
table.row[j][mask1],
|
table.row[j][mask1],
|
||||||
mangle_reason(table.row[j][reason]),
|
mangle_reason(table.row[j][reason]),
|
||||||
|
@ -340,7 +337,7 @@ export_config(const char *conf, int id)
|
||||||
|
|
||||||
case BANDB_XLINE:
|
case BANDB_XLINE:
|
||||||
case BANDB_XLINE_PERM:
|
case BANDB_XLINE_PERM:
|
||||||
rb_snprintf(buf, sizeof(buf),
|
snprintf(buf, sizeof(buf),
|
||||||
"\"%s\",\"0\",\"%s\",\"%s\",%s\n",
|
"\"%s\",\"0\",\"%s\",\"%s\",%s\n",
|
||||||
escape_quotes(table.row[j][mask1]),
|
escape_quotes(table.row[j][mask1]),
|
||||||
mangle_reason(table.row[j][reason]),
|
mangle_reason(table.row[j][reason]),
|
||||||
|
@ -349,7 +346,7 @@ export_config(const char *conf, int id)
|
||||||
|
|
||||||
case BANDB_RESV:
|
case BANDB_RESV:
|
||||||
case BANDB_RESV_PERM:
|
case BANDB_RESV_PERM:
|
||||||
rb_snprintf(buf, sizeof(buf),
|
snprintf(buf, sizeof(buf),
|
||||||
"\"%s\",\"%s\",\"%s\",%s\n",
|
"\"%s\",\"%s\",\"%s\",%s\n",
|
||||||
table.row[j][mask1],
|
table.row[j][mask1],
|
||||||
mangle_reason(table.row[j][reason]),
|
mangle_reason(table.row[j][reason]),
|
||||||
|
@ -358,7 +355,7 @@ export_config(const char *conf, int id)
|
||||||
|
|
||||||
|
|
||||||
default: /* Klines */
|
default: /* Klines */
|
||||||
rb_snprintf(buf, sizeof(buf),
|
snprintf(buf, sizeof(buf),
|
||||||
"\"%s\",\"%s\",\"%s\",\"\",\"%s\",\"%s\",%s\n",
|
"\"%s\",\"%s\",\"%s\",\"\",\"%s\",\"%s\",%s\n",
|
||||||
table.row[j][mask1], table.row[j][mask2],
|
table.row[j][mask1], table.row[j][mask2],
|
||||||
mangle_reason(table.row[j][reason]),
|
mangle_reason(table.row[j][reason]),
|
||||||
|
@ -497,13 +494,13 @@ import_config(const char *conf, int id)
|
||||||
|
|
||||||
/* append operreason_field to reason_field */
|
/* append operreason_field to reason_field */
|
||||||
if(!EmptyString(f_oreason))
|
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
|
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]);
|
drop_dupes(f_mask1, f_mask2, bandb_table[id]);
|
||||||
|
|
||||||
rsdb_exec(NULL,
|
rsdb_exec(NULL,
|
||||||
|
@ -746,7 +743,7 @@ check_schema(void)
|
||||||
NULL
|
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]))
|
if(!table_exists(bandb_table[i]))
|
||||||
{
|
{
|
||||||
|
@ -773,8 +770,6 @@ check_schema(void)
|
||||||
columns[j], type);
|
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
|
static void
|
||||||
wipe_schema(void)
|
wipe_schema(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
rsdb_transaction(RSDB_TRANS_START);
|
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]);
|
rsdb_exec(NULL, "DROP TABLE %s", bandb_table[i]);
|
||||||
i++; /* double increment to skip over .perm */
|
|
||||||
}
|
}
|
||||||
rsdb_transaction(RSDB_TRANS_END);
|
rsdb_transaction(RSDB_TRANS_END);
|
||||||
|
|
||||||
|
@ -859,7 +853,7 @@ bt_smalldate(const char *string)
|
||||||
lt = gmtime(&t);
|
lt = gmtime(&t);
|
||||||
if(lt == NULL)
|
if(lt == NULL)
|
||||||
return 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);
|
lt->tm_year + 1900, lt->tm_mon + 1, lt->tm_mday, lt->tm_hour, lt->tm_min);
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
@ -870,9 +864,8 @@ bt_smalldate(const char *string)
|
||||||
static void
|
static void
|
||||||
print_help(const int i_exit)
|
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, "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"
|
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"
|
"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
|
||||||
"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\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, " -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, " -u : Update the database tables to support any new features.\n");
|
||||||
fprintf(stderr,
|
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, " but should be run whenever you upgrade the ircd.\n");
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
" -p : pretend, checks for the configs, and parses them, then tells you some data...\n");
|
" -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, " but does not touch your database.\n");
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
" -v : Be verbose... and it *is* very verbose! (intended for debugging)\n");
|
" -v : Be verbose... and it *is* very verbose! (intended for debugging)\n");
|
||||||
fprintf(stderr, " -d : Enable checking for redunant entries.\n");
|
fprintf(stderr, " -d : Enable checking for redundant entries.\n");
|
||||||
fprintf(stderr, " -w : Completly wipe your database clean. May be used with -i \n");
|
fprintf(stderr, " -w : Completely wipe your database clean. May be used with -i \n");
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
" path : An optional directory containing old ratbox configs for import, or export.\n");
|
" path : An optional directory containing old ratbox configs for import, or export.\n");
|
||||||
fprintf(stderr, " If not specified, it looks in PREFIX/etc.\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
|
#ifndef INCLUDED_rsdb_h
|
||||||
#define INCLUDED_rsdb_h
|
#define INCLUDED_rsdb_h
|
||||||
|
|
||||||
|
|
|
@ -5,8 +5,6 @@
|
||||||
* Should you choose to use and/or modify this source code, please
|
* 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
|
* do so under the terms of the GNU General Public License under which
|
||||||
* this library is distributed.
|
* this library is distributed.
|
||||||
*
|
|
||||||
* $Id: rsdb_snprintf.c 26094 2008-09-19 15:33:46Z androsyn $
|
|
||||||
*/
|
*/
|
||||||
#include "stdinc.h"
|
#include "stdinc.h"
|
||||||
#include "rsdb.h"
|
#include "rsdb.h"
|
||||||
|
|
|
@ -27,8 +27,6 @@
|
||||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
* POSSIBILITY OF SUCH DAMAGE.
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
|
||||||
* $Id: rsdb_sqlite3.c 26182 2008-11-11 02:52:41Z androsyn $
|
|
||||||
*/
|
*/
|
||||||
#include "stdinc.h"
|
#include "stdinc.h"
|
||||||
#include "rsdb.h"
|
#include "rsdb.h"
|
||||||
|
@ -47,7 +45,7 @@ mlog(const char *errstr, ...)
|
||||||
char buf[256];
|
char buf[256];
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start(ap, errstr);
|
va_start(ap, errstr);
|
||||||
rb_vsnprintf(buf, sizeof(buf), errstr, ap);
|
vsnprintf(buf, sizeof(buf), errstr, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
error_cb(buf);
|
error_cb(buf);
|
||||||
}
|
}
|
||||||
|
@ -73,14 +71,14 @@ rsdb_init(rsdb_error_cb * ecb)
|
||||||
|
|
||||||
if(sqlite3_open(dbpath, &rb_bandb) != SQLITE_OK)
|
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));
|
sqlite3_errmsg(rb_bandb));
|
||||||
mlog(errbuf);
|
mlog(errbuf);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if(access(dbpath, W_OK))
|
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);
|
mlog(errbuf);
|
||||||
return -1;
|
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
800
configure.ac
800
configure.ac
File diff suppressed because it is too large
Load diff
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
|
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
|
Unlimited redistribution and modification of this document is allowed
|
||||||
provided that the above copyright notice and this permission notice
|
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 -
|
- 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
|
ratbox-respond takes the challenge from the server, and together with your
|
||||||
private key file generates a response to be sent back. ratbox-respond
|
private key file generates a response to be sent back. ratbox-respond
|
||||||
requires the openssl headers (ie, development files) and openssl libraries
|
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
|
A number of scripts for clients have already been written to automate this
|
||||||
process, see client-scripts/README for more information.
|
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
|
nick changes their nick but is collided again (the server detecting the
|
||||||
collision will not propagate the nick change further).
|
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
|
necessarily see whether the user is in the target channel, so it should not
|
||||||
influence whether they can join either.)
|
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
|
extb_oper.so
|
||||||
$o
|
$o
|
||||||
matches opers (most useful with +I)
|
matches opers (most useful with +I)
|
||||||
|
@ -56,6 +60,14 @@ extb_server.so
|
||||||
matches users connected to a server matching the mask (* and ? wildcards);
|
matches users connected to a server matching the mask (* and ? wildcards);
|
||||||
this can only be used with +b and +q
|
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:
|
Comparisons:
|
||||||
|
|
||||||
+b $~a is similar to +r but also prevents not logged in users talking or
|
+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
|
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.)
|
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
|
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 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.
|
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
|
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
|
and will not receive the second notice
|
||||||
|
|
||||||
Hwy-LL will NOT see any notice. This also applies if the second message comes
|
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
|
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
|
This numeric is used to indicate that a message (PRIVMSG) the client sent
|
||||||
could not be delivered because of CallerID restrictions. The <target>
|
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
|
W. Campbell
|
||||||
updated by J. Tjoelker
|
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
|
MONITOR - Protocol for notification of when clients become online/offline
|
||||||
Lee Hardy <lee -at- leeh.co.uk>
|
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
|
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
|
This internet-draft has expired; it can still be found on
|
||||||
http://www.leeh.co.uk/draft-mitchell-irc-capabilities-02.html
|
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
|
Originally written by Lee Hardy for ircd-ratbox. Minor changes by Elizabeth
|
||||||
all of this is also used by atheme-services and anope. It will add the
|
Myers for modern services.
|
||||||
following features to ircd:
|
|
||||||
|
|
||||||
|
Compatibility with services is always enabled. Supported services include
|
||||||
|
atheme and anope. They add the following features to Charybdis:
|
||||||
|
|
||||||
1. Channel mode +r
|
1. Channel mode +r
|
||||||
|
|
||||||
|
@ -17,8 +20,8 @@ following features to ircd:
|
||||||
|
|
||||||
Ability to specify the names of services servers in ircd.conf:
|
Ability to specify the names of services servers in ircd.conf:
|
||||||
service {
|
service {
|
||||||
name = "services.ircd-ratbox.org";
|
name = "services.charybdis.io";
|
||||||
name = "backup-services.ircd-ratbox.org";
|
name = "backup-services.charybdis.io";
|
||||||
};
|
};
|
||||||
|
|
||||||
These must be specified for certain features to work. You may specify as
|
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:
|
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
|
:<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
|
can be done explicitly using the CNOTICE and CPRIVMSG commands, see
|
||||||
/quote help cnotice and /quote help cprivmsg, but is also implicit in a
|
/quote help cnotice and /quote help cprivmsg, but is also implicit in a
|
||||||
normal /msg, /notice or /invite.
|
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) 2002-2005 ircd-ratbox development team
|
||||||
* Copyright (C) 2005-2006 charybdis 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.
|
* See reference.conf for more information.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Extensions */
|
/* Extensions */
|
||||||
|
<<<<<<< .merge_file_MAZNsP
|
||||||
#loadmodule "extensions/chm_operonly_compat.so";
|
#loadmodule "extensions/chm_operonly_compat.so";
|
||||||
#loadmodule "extensions/chm_quietunreg_compat.so";
|
#loadmodule "extensions/chm_quietunreg_compat.so";
|
||||||
#loadmodule "extensions/chm_sslonly_compat.so";
|
#loadmodule "extensions/chm_sslonly_compat.so";
|
||||||
|
@ -35,23 +34,49 @@
|
||||||
#loadmodule "extensions/sno_whois.so";
|
#loadmodule "extensions/sno_whois.so";
|
||||||
#loadmodule "extensions/override.so";
|
#loadmodule "extensions/override.so";
|
||||||
#loadmodule "extensions/no_kill_services.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
|
* IP cloaking extensions: use ip_cloaking_4.0
|
||||||
* if you're linking 3.2 and later, otherwise use
|
* 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.
|
* releases.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#loadmodule "extensions/ip_cloaking_4.0.so";
|
#loadmodule "extensions/ip_cloaking_4.0";
|
||||||
#loadmodule "extensions/ip_cloaking.so";
|
#loadmodule "extensions/ip_cloaking";
|
||||||
|
|
||||||
serverinfo {
|
serverinfo {
|
||||||
name = "hades.arpa";
|
name = "hades.arpa";
|
||||||
sid = "42X";
|
sid = "42X";
|
||||||
description = "charybdis test server";
|
description = "solanum test server";
|
||||||
network_name = "StaticBox";
|
network_name = "StaticBox";
|
||||||
hub = yes;
|
|
||||||
|
|
||||||
/* On multi-homed hosts you may need the following. These define
|
/* On multi-homed hosts you may need the following. These define
|
||||||
* the addresses we connect from to other servers. */
|
* the addresses we connect from to other servers. */
|
||||||
|
@ -59,19 +84,21 @@ serverinfo {
|
||||||
#vhost = "192.0.2.6";
|
#vhost = "192.0.2.6";
|
||||||
/* for IPv6 */
|
/* for IPv6 */
|
||||||
#vhost6 = "2001:db8:2::6";
|
#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_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
|
/* 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.
|
* 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
|
* 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
|
* 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.
|
* 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";
|
ssl_dh_params = "etc/dh.pem";
|
||||||
|
|
||||||
/* ssld_count: number of ssld processes you want to start, if you
|
/* 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). */
|
/* Listen on IPv6 (if you used host= above). */
|
||||||
#host = "2001:db8:2::6";
|
#host = "2001:db8:2::6";
|
||||||
#port = 5000, 6665 .. 6669;
|
#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:)
|
/* auth {}: allow users to connect to the ircd (OLD I:)
|
||||||
|
@ -183,7 +216,7 @@ auth {
|
||||||
* flags = ...; below if it is.
|
* flags = ...; below if it is.
|
||||||
*/
|
*/
|
||||||
password = "letmein";
|
password = "letmein";
|
||||||
|
|
||||||
/* spoof: fake the users user@host to be be this. You may either
|
/* spoof: fake the users user@host to be be this. You may either
|
||||||
* specify a host or a user@host to spoof to. This is free-form,
|
* specify a host or a user@host to spoof to. This is free-form,
|
||||||
* just do everyone a favour and dont abuse it. (OLD I: = flag)
|
* just do everyone a favour and dont abuse it. (OLD I: = flag)
|
||||||
|
@ -191,26 +224,28 @@ auth {
|
||||||
spoof = "I.still.hate.packets";
|
spoof = "I.still.hate.packets";
|
||||||
|
|
||||||
/* Possible flags in auth:
|
/* Possible flags in auth:
|
||||||
*
|
*
|
||||||
* encrypted | password is encrypted with mkpasswd
|
* encrypted | password is encrypted with mkpasswd
|
||||||
* spoof_notice | give a notice when spoofing hosts
|
* spoof_notice | give a notice when spoofing hosts
|
||||||
* exceed_limit (old > flag) | allow user to exceed class user limits
|
* 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,
|
||||||
* dnsbl_exempt | exempt this user from dnsbls
|
* | dnsbls, and proxies
|
||||||
* spambot_exempt | exempt this user from spambot checks
|
* proxy_exempt | exempt this user from proxies
|
||||||
* shide_exempt | exempt this user from serverhiding
|
* dnsbl_exempt | exempt this user from dnsbls
|
||||||
|
* spambot_exempt | exempt this user from spambot checks
|
||||||
|
* shide_exempt | exempt this user from serverhiding
|
||||||
* jupe_exempt | exempt this user from generating
|
* jupe_exempt | exempt this user from generating
|
||||||
* warnings joining juped channels
|
* warnings joining juped channels
|
||||||
* resv_exempt | exempt this user from resvs
|
* resv_exempt | exempt this user from resvs
|
||||||
* flood_exempt | exempt this user from flood limits
|
* flood_exempt | exempt this user from flood limits
|
||||||
* USE WITH CAUTION.
|
* USE WITH CAUTION.
|
||||||
* no_tilde (old - flag) | don't prefix ~ to username if no ident
|
* no_tilde (old - flag) | don't prefix ~ to username if no ident
|
||||||
* need_ident (old + flag) | require ident for user in this class
|
* need_ident (old + flag) | require ident for user in this class
|
||||||
* need_ssl | require SSL/TLS 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
|
* need_sasl | require SASL id for user in this class
|
||||||
*/
|
*/
|
||||||
flags = kline_exempt, exceed_limit;
|
flags = kline_exempt, exceed_limit;
|
||||||
|
|
||||||
/* class: the class the user is placed in */
|
/* class: the class the user is placed in */
|
||||||
class = "opers";
|
class = "opers";
|
||||||
};
|
};
|
||||||
|
@ -224,7 +259,8 @@ auth {
|
||||||
* means they must be defined before operator {}.
|
* means they must be defined before operator {}.
|
||||||
*/
|
*/
|
||||||
privset "local_op" {
|
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" {
|
privset "server_bot" {
|
||||||
|
@ -234,13 +270,14 @@ privset "server_bot" {
|
||||||
|
|
||||||
privset "global_op" {
|
privset "global_op" {
|
||||||
extends = "local_op";
|
extends = "local_op";
|
||||||
privs = oper:global_kill, oper:routing, oper:kline, oper:unkline, oper:xline,
|
privs = oper:routing, oper:kline, oper:unkline, oper:xline,
|
||||||
oper:resv, oper:mass_notice, oper:remoteban;
|
oper:resv, oper:cmodes, oper:mass_notice, oper:wallops,
|
||||||
|
oper:remoteban;
|
||||||
};
|
};
|
||||||
|
|
||||||
privset "admin" {
|
privset "admin" {
|
||||||
extends = "global_op";
|
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" {
|
operator "god" {
|
||||||
|
@ -253,13 +290,13 @@ operator "god" {
|
||||||
user = "*god@127.0.0.1";
|
user = "*god@127.0.0.1";
|
||||||
|
|
||||||
/* password: the password required to oper. Unless ~encrypted is
|
/* password: the password required to oper. Unless ~encrypted is
|
||||||
* contained in flags = ...; this will need to be encrypted using
|
* contained in flags = ...; this will need to be encrypted using
|
||||||
* mkpasswd, MD5 is supported
|
* mkpasswd, MD5 is supported
|
||||||
*/
|
*/
|
||||||
password = "etcnjl8juSU1E";
|
password = "etcnjl8juSU1E";
|
||||||
|
|
||||||
/* rsa key: the public key for this oper when using Challenge.
|
/* rsa key: the public key for this oper when using Challenge.
|
||||||
* A password should not be defined when this is used, see
|
* A password should not be defined when this is used, see
|
||||||
* doc/challenge.txt for more information.
|
* doc/challenge.txt for more information.
|
||||||
*/
|
*/
|
||||||
#rsa_public_key_file = "/usr/local/ircd/etc/oper.pub";
|
#rsa_public_key_file = "/usr/local/ircd/etc/oper.pub";
|
||||||
|
@ -297,20 +334,17 @@ operator "god" {
|
||||||
privset = "admin";
|
privset = "admin";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* See connecting-servers.rst for an introduction to using these files. */
|
||||||
|
|
||||||
connect "irc.uplink.com" {
|
connect "irc.uplink.com" {
|
||||||
host = "203.0.113.3";
|
host = "203.0.113.3";
|
||||||
send_password = "password";
|
send_password = "password";
|
||||||
accept_password = "anotherpassword";
|
accept_password = "anotherpassword";
|
||||||
port = 6666;
|
port = 6666;
|
||||||
hub_mask = "*";
|
|
||||||
class = "server";
|
class = "server";
|
||||||
flags = compressed, topicburst;
|
flags = topicburst;
|
||||||
|
|
||||||
#fingerprint = "c77106576abf7f9f90cca0f63874a60f2e40a64b";
|
#fingerprint = "c77106576abf7f9f90cca0f63874a60f2e40a64b";
|
||||||
|
|
||||||
/* If the connection is IPv6, uncomment below.
|
|
||||||
* Use 0::1, not ::1, for IPv6 localhost. */
|
|
||||||
#aftype = ipv6;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
connect "ssl.uplink.com" {
|
connect "ssl.uplink.com" {
|
||||||
|
@ -318,7 +352,6 @@ connect "ssl.uplink.com" {
|
||||||
send_password = "password";
|
send_password = "password";
|
||||||
accept_password = "anotherpassword";
|
accept_password = "anotherpassword";
|
||||||
port = 9999;
|
port = 9999;
|
||||||
hub_mask = "*";
|
|
||||||
class = "server";
|
class = "server";
|
||||||
flags = ssl, topicburst;
|
flags = ssl, topicburst;
|
||||||
};
|
};
|
||||||
|
@ -332,9 +365,8 @@ cluster {
|
||||||
flags = kline, tkline, unkline, xline, txline, unxline, resv, tresv, unresv;
|
flags = kline, tkline, unkline, xline, txline, unxline, resv, tresv, unresv;
|
||||||
};
|
};
|
||||||
|
|
||||||
shared {
|
secure {
|
||||||
oper = "*@*", "*";
|
ip = "127.0.0.1";
|
||||||
flags = all, rehash;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* exempt {}: IPs that are exempt from Dlines and rejectcache. (OLD d:) */
|
/* exempt {}: IPs that are exempt from Dlines and rejectcache. (OLD d:) */
|
||||||
|
@ -350,6 +382,7 @@ channel {
|
||||||
knock_delay = 5 minutes;
|
knock_delay = 5 minutes;
|
||||||
knock_delay_channel = 1 minute;
|
knock_delay_channel = 1 minute;
|
||||||
max_chans_per_user = 15;
|
max_chans_per_user = 15;
|
||||||
|
max_chans_per_user_large = 60;
|
||||||
max_bans = 100;
|
max_bans = 100;
|
||||||
max_bans_large = 500;
|
max_bans_large = 500;
|
||||||
default_split_user_count = 0;
|
default_split_user_count = 0;
|
||||||
|
@ -364,6 +397,9 @@ channel {
|
||||||
disable_local_channels = no;
|
disable_local_channels = no;
|
||||||
autochanmodes = "+nt";
|
autochanmodes = "+nt";
|
||||||
displayed_usercount = 3;
|
displayed_usercount = 3;
|
||||||
|
strip_topic_colors = no;
|
||||||
|
opmod_send_statusmsg = no;
|
||||||
|
invite_notify_notice = yes;
|
||||||
};
|
};
|
||||||
|
|
||||||
serverhide {
|
serverhide {
|
||||||
|
@ -373,15 +409,14 @@ serverhide {
|
||||||
disable_hidden = no;
|
disable_hidden = no;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* These are the blacklist settings.
|
/* These are the DNSBL settings.
|
||||||
* You can have multiple combinations of host and rejection reasons.
|
* You can have multiple combinations of host and rejection reasons.
|
||||||
* They are used in pairs of one host/rejection reason.
|
* They are used in pairs of one host/rejection reason.
|
||||||
*
|
*
|
||||||
* These settings should be adequate for most networks, and are (presently)
|
* The default settings should be adequate for most networks.
|
||||||
* required for use on StaticBox.
|
|
||||||
*
|
*
|
||||||
* Word to the wise: Do not use blacklists like SPEWS for blocking IRC
|
* It is not recommended to use DNSBL services designed for e-mail spam
|
||||||
* connections.
|
* prevention, such as SPEWS for blocking IRC connections.
|
||||||
*
|
*
|
||||||
* As of charybdis 2.2, you can do some keyword substitution on the rejection
|
* As of charybdis 2.2, you can do some keyword substitution on the rejection
|
||||||
* reason. The available keyword substitutions are:
|
* reason. The available keyword substitutions are:
|
||||||
|
@ -398,16 +433,16 @@ serverhide {
|
||||||
* as of this writing.
|
* as of this writing.
|
||||||
*
|
*
|
||||||
* As of charybdis 3.5, a matches parameter is allowed; if omitted, any result
|
* As of charybdis 3.5, a matches parameter is allowed; if omitted, any result
|
||||||
* is considered a match. If included, a comma-separated list of *quoted*
|
* 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"
|
* 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
|
* 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.
|
* list. You may freely mix full IP's and final octets.
|
||||||
*
|
*
|
||||||
* Consult your blacklist provider for the meaning of these parameters; they
|
* Consult your DNSBL provider for the meaning of these parameters; they
|
||||||
* are usually used to denote different ban types.
|
* are usually used to denote different block reasons.
|
||||||
*/
|
*/
|
||||||
blacklist {
|
dnsbl {
|
||||||
host = "rbl.efnetrbl.org";
|
host = "rbl.efnetrbl.org";
|
||||||
type = ipv4;
|
type = ipv4;
|
||||||
reject_reason = "${nick}, your IP (${ip}) is listed in EFnet's RBL. For assistance, see http://efnetrbl.org/?i=${ip}";
|
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";
|
# 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" {
|
alias "NickServ" {
|
||||||
target = "NickServ";
|
target = "NickServ";
|
||||||
};
|
};
|
||||||
|
@ -490,7 +597,7 @@ general {
|
||||||
tkline_expire_notices = no;
|
tkline_expire_notices = no;
|
||||||
default_floodcount = 10;
|
default_floodcount = 10;
|
||||||
failed_oper_notice = yes;
|
failed_oper_notice = yes;
|
||||||
dots_in_ident=2;
|
dots_in_ident = 2;
|
||||||
min_nonwildcard = 4;
|
min_nonwildcard = 4;
|
||||||
min_nonwildcard_simple = 3;
|
min_nonwildcard_simple = 3;
|
||||||
max_accept = 100;
|
max_accept = 100;
|
||||||
|
@ -506,22 +613,30 @@ general {
|
||||||
resv_fnc = yes;
|
resv_fnc = yes;
|
||||||
global_snotices = yes;
|
global_snotices = yes;
|
||||||
dline_with_reason = yes;
|
dline_with_reason = yes;
|
||||||
kline_delay = 0 seconds;
|
|
||||||
kline_with_reason = yes;
|
kline_with_reason = yes;
|
||||||
|
hide_tkdline_duration = no;
|
||||||
kline_reason = "K-Lined";
|
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_service = "NickServ@services.int";
|
||||||
identify_command = "IDENTIFY";
|
identify_command = "IDENTIFY";
|
||||||
non_redundant_klines = yes;
|
non_redundant_klines = yes;
|
||||||
warn_no_nline = yes;
|
warn_no_nline = yes;
|
||||||
use_propagated_bans = yes;
|
use_propagated_bans = yes;
|
||||||
stats_e_disabled = no;
|
stats_e_disabled = no;
|
||||||
stats_c_oper_only=no;
|
stats_c_oper_only = no;
|
||||||
stats_h_oper_only=no;
|
stats_y_oper_only = no;
|
||||||
stats_y_oper_only=no;
|
stats_o_oper_only = yes;
|
||||||
stats_o_oper_only=yes;
|
stats_P_oper_only = no;
|
||||||
stats_P_oper_only=no;
|
stats_i_oper_only = masked;
|
||||||
stats_i_oper_only=masked;
|
stats_k_oper_only = masked;
|
||||||
stats_k_oper_only=masked;
|
|
||||||
map_oper_only = no;
|
map_oper_only = no;
|
||||||
operspy_admin_only = no;
|
operspy_admin_only = no;
|
||||||
operspy_dont_care_user_info = no;
|
operspy_dont_care_user_info = no;
|
||||||
|
@ -537,6 +652,7 @@ general {
|
||||||
no_oper_flood = yes;
|
no_oper_flood = yes;
|
||||||
max_targets = 4;
|
max_targets = 4;
|
||||||
client_flood_max_lines = 20;
|
client_flood_max_lines = 20;
|
||||||
|
post_registration_delay = 0 seconds;
|
||||||
use_whois_actually = no;
|
use_whois_actually = no;
|
||||||
oper_only_umodes = operwall, locops, servnotice;
|
oper_only_umodes = operwall, locops, servnotice;
|
||||||
oper_umodes = locops, servnotice, operwall, wallop;
|
oper_umodes = locops, servnotice, operwall, wallop;
|
||||||
|
@ -550,7 +666,9 @@ general {
|
||||||
throttle_count = 4;
|
throttle_count = 4;
|
||||||
max_ratelimit_tokens = 30;
|
max_ratelimit_tokens = 30;
|
||||||
away_interval = 30;
|
away_interval = 30;
|
||||||
certfp_method = sha1;
|
certfp_method = spki_sha256;
|
||||||
|
hide_opers_in_whois = no;
|
||||||
|
tls_ciphers_oper_only = no;
|
||||||
};
|
};
|
||||||
|
|
||||||
modules {
|
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.
|
laugh at you.
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
ircd-ratbox logfiles - Lee H <lee -at- leeh.co.uk>
|
Charybdis logfiles - Lee H <lee -at- leeh.co.uk>
|
||||||
$Id: logfiles.txt 6 2005-09-10 01:02:21Z nenolod $
|
|
||||||
---------------------------
|
---------------------------
|
||||||
|
|
||||||
fname_killlog
|
fname_killlog
|
||||||
|
|
|
@ -4,7 +4,6 @@ Standard channel modes are listed in help/opers/cmode
|
||||||
|
|
||||||
The sgml docs have more detailed descriptions.
|
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
|
Server notice mask +F (far connects) is provided by contrib/sno_farconnect.so
|
||||||
|
Information on the caller ID system can be found in doc/features/modeg.txt
|
||||||
# $Id: modes.txt 996 2006-03-09 01:14:34Z jilles $
|
|
||||||
|
|
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.
|
serving as a hub, i.e. have multiple servers connected to it.
|
||||||
|
|
||||||
vhost
|
vhost
|
||||||
|
<<<<<<< .merge_file_cTfvge
|
||||||
An optional text field which defines an IP from which to connect
|
An optional text field which defines an IP from which to connect
|
||||||
outward to other IRC servers.
|
outward to other IRC servers.
|
||||||
|
|
||||||
vhost6
|
vhost6
|
||||||
An optional text field which defines an IPv6 IP from which to
|
An optional text field which defines an IPv6 IP from which to
|
||||||
connect outward to other IRC servers.
|
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
|
admin {} block
|
||||||
--------------
|
--------------
|
||||||
|
@ -255,6 +264,12 @@ flags
|
||||||
class
|
class
|
||||||
A name of a class to put users matching this auth{} block into.
|
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
|
auth {} flags
|
||||||
~~~~~~~~~~~~~
|
~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
@ -446,10 +461,13 @@ host
|
||||||
``A`` or ``AAAA`` record (no ``CNAME``) and it must be
|
``A`` or ``AAAA`` record (no ``CNAME``) and it must be
|
||||||
the primary hostname for inbound connections to work.
|
the primary hostname for inbound connections to work.
|
||||||
|
|
||||||
|
<<<<<<< .merge_file_cTfvge
|
||||||
IPv6 addresses must be in ``::`` shortened form; addresses which
|
IPv6 addresses must be in ``::`` shortened form; addresses which
|
||||||
then start with a colon must be prepended with a zero, for
|
then start with a colon must be prepended with a zero, for
|
||||||
example ``0::1``.
|
example ``0::1``.
|
||||||
|
|
||||||
|
=======
|
||||||
|
>>>>>>> .merge_file_3UzJEV
|
||||||
send\_password
|
send\_password
|
||||||
The password to send to the other server.
|
The password to send to the other server.
|
||||||
|
|
||||||
|
@ -478,7 +496,12 @@ flags
|
||||||
|
|
||||||
aftype
|
aftype
|
||||||
The protocol that should be used to connect with, either ipv4 or
|
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 ipv4 unless host is a numeric IPv6 address.
|
||||||
|
=======
|
||||||
|
ipv6. This defaults to neither, allowing connection using either
|
||||||
|
address family.
|
||||||
|
>>>>>>> .merge_file_3UzJEV
|
||||||
|
|
||||||
**connect {} flags**
|
**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) 2000-2002 Hybrid Development Team
|
||||||
* Copyright (C) 2002-2005 ircd-ratbox development team
|
* Copyright (C) 2002-2005 ircd-ratbox development team
|
||||||
|
@ -6,7 +6,6 @@
|
||||||
*
|
*
|
||||||
* Written by ejb, wcampbel, db, leeh and others
|
* Written by ejb, wcampbel, db, leeh and others
|
||||||
*
|
*
|
||||||
* $Id: reference.conf 3582 2007-11-17 21:55:48Z jilles $
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* IMPORTANT NOTES:
|
/* IMPORTANT NOTES:
|
||||||
|
@ -27,23 +26,28 @@
|
||||||
* .include "filename"
|
* .include "filename"
|
||||||
* .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:
|
* Times/durations are written as:
|
||||||
* 12 hours 30 minutes 1 second
|
* 12 hours 30 minutes 1 second
|
||||||
*
|
*
|
||||||
* Valid units of time:
|
* Valid units of time:
|
||||||
* month, week, day, hour, minute, second
|
* month, week, day, hour, minute, second
|
||||||
*
|
*
|
||||||
* Valid units of size:
|
* Valid units of size:
|
||||||
* megabyte/mbyte/mb, kilobyte/kbyte/kb, byte
|
* megabyte/mbyte/mb, kilobyte/kbyte/kb, byte
|
||||||
*
|
*
|
||||||
* Sizes and times may be singular or plural.
|
* Sizes and times may be singular or plural.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Extensions:
|
/* Extensions:
|
||||||
*
|
*
|
||||||
* Charybdis contains several extensions that are not enabled by default.
|
* Charybdis contains several extensions that are not enabled by default.
|
||||||
* To use them, uncomment the lines below.
|
* To use them, uncomment the lines below.
|
||||||
*
|
*
|
||||||
|
<<<<<<< .merge_file_UmjhEh
|
||||||
* Channel mode +-A (admin only) -- chm_adminonly.so
|
* Channel mode +-A (admin only) -- chm_adminonly.so
|
||||||
* Channel mode +-O (oper only) -- chm_operonly.so
|
* Channel mode +-O (oper only) -- chm_operonly.so
|
||||||
* Channel mode +-S (ssl only) -- chm_sslonly.so
|
* Channel mode +-S (ssl only) -- chm_sslonly.so
|
||||||
|
@ -105,6 +109,73 @@
|
||||||
#loadmodule "extensions/sno_whois.so";
|
#loadmodule "extensions/sno_whois.so";
|
||||||
#loadmodule "extensions/override.so";
|
#loadmodule "extensions/override.so";
|
||||||
#loadmodule "extensions/no_kill_services.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 {}: Contains information about the server. (OLD M:) */
|
||||||
serverinfo {
|
serverinfo {
|
||||||
|
@ -129,11 +200,6 @@ serverinfo {
|
||||||
*/
|
*/
|
||||||
network_name = "MyNet";
|
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.
|
/* vhost: the IP to bind to when we connect outward to ipv4 servers.
|
||||||
* This should be an ipv4 IP only.
|
* This should be an ipv4 IP only.
|
||||||
*/
|
*/
|
||||||
|
@ -143,18 +209,26 @@ serverinfo {
|
||||||
* This should be an ipv6 IP only.
|
* This should be an ipv6 IP only.
|
||||||
*/
|
*/
|
||||||
#vhost6 = "2001:db8:2::6";
|
#vhost6 = "2001:db8:2::6";
|
||||||
|
<<<<<<< .merge_file_UmjhEh
|
||||||
|
|
||||||
/* ssl_private_key: our ssl private key */
|
/* ssl_private_key: our ssl private key */
|
||||||
ssl_private_key = "etc/ssl.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_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_dh_params = "etc/dh.pem";
|
||||||
|
|
||||||
/* ssl_cipher_list: A list of ciphers, dependent on your TLS backend */
|
/* 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
|
/* 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
|
* have a really busy server, using N-1 where N is the number of
|
||||||
|
@ -245,7 +319,7 @@ class "users" {
|
||||||
*/
|
*/
|
||||||
cidr_ipv6_bitlen = 64;
|
cidr_ipv6_bitlen = 64;
|
||||||
|
|
||||||
/* number_per_cidr: Number of connections to allow from a subnet of the
|
/* number_per_cidr: Number of connections to allow from a subnet of the
|
||||||
* size given in cidr_ipv4_bitlen/cidr_ipv6_bitlen.
|
* size given in cidr_ipv4_bitlen/cidr_ipv6_bitlen.
|
||||||
* 4 seems to be a good default to me.
|
* 4 seems to be a good default to me.
|
||||||
*/
|
*/
|
||||||
|
@ -282,17 +356,20 @@ class "server" {
|
||||||
*/
|
*/
|
||||||
connectfreq = 5 minutes;
|
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
|
* of servers in the class is or exceeds this, no more servers in the
|
||||||
* class are autoconnected. oper initiated connects are unaffected.
|
* class are autoconnected. oper initiated connects are unaffected.
|
||||||
* this should usually be set to either 0 or 1. (autoconnecting from
|
* this should usually be set to either 0 or 1. (autoconnecting from
|
||||||
* hubs to leaves may cause leaves to function as hubs by having
|
* hubs to leaves may cause leaves to function as hubs by having
|
||||||
* multiple servers connected to them.)
|
* 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: servers need a higher sendq as they are sent more data */
|
||||||
sendq=2 megabytes;
|
sendq = 2 megabytes;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* listen {}: contain information about the ports ircd listens on (OLD P:) */
|
/* listen {}: contain information about the ports ircd listens on (OLD P:) */
|
||||||
|
@ -307,19 +384,19 @@ listen {
|
||||||
/* port: the specific port to listen on. if no host is specified
|
/* port: the specific port to listen on. if no host is specified
|
||||||
* before, it will listen on all available IPs.
|
* before, it will listen on all available IPs.
|
||||||
*
|
*
|
||||||
* sslport: the specific port to listen ssl connections on. if no
|
* sslport: the specific port to listen ssl connections on. if no
|
||||||
* host is specified before, it will listen on all available IPs.
|
* host is specified before, it will listen on all available IPs.
|
||||||
*
|
*
|
||||||
* ports are seperated via a comma, a range may be specified using ".."
|
* ports are seperated via a comma, a range may be specified using ".."
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* port: listen on all available IPs, ports 5000 and 6665 to 6669 */
|
/* port: listen on all available IPs, ports 5000 and 6665 to 6669 */
|
||||||
port = 5000, 6665 .. 6669;
|
port = 5000, 6665 .. 6669;
|
||||||
|
|
||||||
/* sslport: listen for ssl connections on all available IPs, port 9999 */
|
|
||||||
sslport = 9999;
|
|
||||||
|
|
||||||
/* host: set a specific IP/host the ports after the line will listen
|
/* 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.
|
* on. This may be ipv4 or ipv6.
|
||||||
*/
|
*/
|
||||||
host = "192.0.2.6";
|
host = "192.0.2.6";
|
||||||
|
@ -329,10 +406,21 @@ listen {
|
||||||
host = "2001:db8:2::6";
|
host = "2001:db8:2::6";
|
||||||
port = 7002;
|
port = 7002;
|
||||||
sslport = 9002;
|
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 {}: allow users to connect to the ircd (OLD I:) */
|
||||||
auth {
|
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
|
/* user: the user@host allowed to connect. Multiple IPv4/IPv6 user
|
||||||
* lines are permitted per auth block. This is matched against the
|
* lines are permitted per auth block. This is matched against the
|
||||||
* hostname and IP address (using :: shortening for IPv6 and
|
* hostname and IP address (using :: shortening for IPv6 and
|
||||||
|
@ -342,6 +430,11 @@ auth {
|
||||||
user = "*@198.51.100.0/24";
|
user = "*@198.51.100.0/24";
|
||||||
user = "*test@2001:db8:1:*";
|
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
|
/* auth_user: This allows specifying a username:password instead of
|
||||||
* just a password in PASS, so that a fixed user@host is not
|
* just a password in PASS, so that a fixed user@host is not
|
||||||
* necessary for a specific auth{} block.
|
* necessary for a specific auth{} block.
|
||||||
|
@ -353,7 +446,7 @@ auth {
|
||||||
* flags = ...; below if it is.
|
* flags = ...; below if it is.
|
||||||
*/
|
*/
|
||||||
password = "letmein";
|
password = "letmein";
|
||||||
|
|
||||||
/* spoof: fake the users user@host to be be this. You may either
|
/* spoof: fake the users user@host to be be this. You may either
|
||||||
* specify a host or a user@host to spoof to. This is free-form,
|
* specify a host or a user@host to spoof to. This is free-form,
|
||||||
* just do everyone a favour and dont abuse it. (OLD I: = flag)
|
* just do everyone a favour and dont abuse it. (OLD I: = flag)
|
||||||
|
@ -361,26 +454,31 @@ auth {
|
||||||
spoof = "I.still.hate.packets";
|
spoof = "I.still.hate.packets";
|
||||||
|
|
||||||
/* Possible flags in auth:
|
/* Possible flags in auth:
|
||||||
*
|
*
|
||||||
* encrypted | password is encrypted with mkpasswd
|
* encrypted | password is encrypted with mkpasswd
|
||||||
* spoof_notice | give a notice when spoofing hosts
|
* spoof_notice | give a notice when spoofing hosts
|
||||||
* exceed_limit (old > flag) | allow user to exceed class user limits
|
* 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,
|
||||||
* dnsbl_exempt | exempt this user from dnsbls
|
* | dnsbls, and proxies
|
||||||
* spambot_exempt | exempt this user from spambot checks
|
* dnsbl_exempt | exempt this user from dnsbls
|
||||||
* shide_exempt | exempt this user from serverhiding
|
* 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
|
* jupe_exempt | exempt this user from generating
|
||||||
* warnings joining juped channels
|
* warnings joining juped channels
|
||||||
* resv_exempt | exempt this user from resvs
|
* resv_exempt | exempt this user from resvs
|
||||||
* flood_exempt | exempt this user from flood limits
|
* flood_exempt | exempt this user from flood limits
|
||||||
* USE WITH CAUTION.
|
* USE WITH CAUTION.
|
||||||
* no_tilde (old - flag) | don't prefix ~ to username if no ident
|
* no_tilde (old - flag) | don't prefix ~ to username if no ident
|
||||||
* need_ident (old + flag) | require ident for user in this class
|
* need_ident (old + flag) | require ident for user in this class
|
||||||
* need_ssl | require SSL/TLS 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
|
* 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;
|
flags = kline_exempt, exceed_limit;
|
||||||
|
|
||||||
/* class: the class the user is placed in */
|
/* class: the class the user is placed in */
|
||||||
class = "opers";
|
class = "opers";
|
||||||
};
|
};
|
||||||
|
@ -392,7 +490,7 @@ auth {
|
||||||
*/
|
*/
|
||||||
redirserv = "irc.example.net";
|
redirserv = "irc.example.net";
|
||||||
redirport = 6667;
|
redirport = 6667;
|
||||||
|
|
||||||
user = "*.example.com";
|
user = "*.example.com";
|
||||||
|
|
||||||
/* class: a class is required even though it is not used */
|
/* class: a class is required even though it is not used */
|
||||||
|
@ -411,8 +509,15 @@ privset "local_op" {
|
||||||
*
|
*
|
||||||
* Available options:
|
* Available options:
|
||||||
*
|
*
|
||||||
* oper:local_kill: allows local users to be /KILL'd
|
* oper:general: enable most general oper privileges that came
|
||||||
* oper:global_kill: allows local and remote users to be /KILL'd
|
* 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:routing: allows remote SQUIT and CONNECT
|
||||||
* oper:kline: allows KLINE and DLINE
|
* oper:kline: allows KLINE and DLINE
|
||||||
* oper:unkline: allows UNKLINE and UNDLINE
|
* oper:unkline: allows UNKLINE and UNDLINE
|
||||||
|
@ -423,18 +528,36 @@ privset "local_op" {
|
||||||
* may (un)load modules and see various
|
* may (un)load modules and see various
|
||||||
* additional information.
|
* additional information.
|
||||||
* oper:hidden_admin: gives admin privileges except
|
* oper:hidden_admin: gives admin privileges except
|
||||||
* will not have the admin lines in
|
* will not have the admin lines in
|
||||||
* whois.
|
* whois.
|
||||||
* oper:xline: allows use of /quote xline/unxline
|
* 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:operwall: allows the oper to send/receive operwalls
|
||||||
* oper:spy: allows 'operspy' features to see through +s
|
* oper:spy: allows 'operspy' features to see through +s
|
||||||
* channels etc. see /quote help operspy
|
* channels etc. see /quote help operspy
|
||||||
* oper:hidden: hides the oper from /stats p
|
* oper:hidden: hides the oper from /stats p
|
||||||
* oper:remoteban: allows remote kline etc
|
* 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" {
|
privset "server_bot" {
|
||||||
|
@ -445,13 +568,14 @@ privset "server_bot" {
|
||||||
|
|
||||||
privset "global_op" {
|
privset "global_op" {
|
||||||
extends = "local_op";
|
extends = "local_op";
|
||||||
privs = oper:global_kill, oper:routing, oper:kline, oper:unkline, oper:xline,
|
privs = oper:routing, oper:kline, oper:unkline, oper:xline,
|
||||||
oper:resv, oper:mass_notice, oper:remoteban;
|
oper:resv, oper:cmodes, oper:mass_notice, oper:wallops,
|
||||||
|
oper:remoteban;
|
||||||
};
|
};
|
||||||
|
|
||||||
privset "admin" {
|
privset "admin" {
|
||||||
extends = "global_op";
|
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:) */
|
/* operator {}: defines ircd operators. (OLD O:) */
|
||||||
|
@ -466,13 +590,13 @@ operator "god" {
|
||||||
user = "*@127.0.0.1";
|
user = "*@127.0.0.1";
|
||||||
|
|
||||||
/* password: the password required to oper. Unless ~encrypted is
|
/* password: the password required to oper. Unless ~encrypted is
|
||||||
* contained in flags = ...; this will need to be encrypted using
|
* contained in flags = ...; this will need to be encrypted using
|
||||||
* mkpasswd, MD5 is supported
|
* mkpasswd, MD5 is supported
|
||||||
*/
|
*/
|
||||||
password = "etcnjl8juSU1E";
|
password = "etcnjl8juSU1E";
|
||||||
|
|
||||||
/* rsa key: the public key for this oper when using Challenge.
|
/* rsa key: the public key for this oper when using Challenge.
|
||||||
* A password should not be defined when this is used, see
|
* A password should not be defined when this is used, see
|
||||||
* doc/challenge.txt for more information.
|
* doc/challenge.txt for more information.
|
||||||
*/
|
*/
|
||||||
#rsa_public_key_file = "/usr/local/ircd/etc/oper.pub";
|
#rsa_public_key_file = "/usr/local/ircd/etc/oper.pub";
|
||||||
|
@ -510,12 +634,21 @@ operator "god" {
|
||||||
privset = "admin";
|
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" {
|
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
|
/* host: the host or IP to connect to.
|
||||||
* must match the reverse dns of the server.
|
*
|
||||||
|
* 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";
|
host = "203.0.113.3";
|
||||||
|
|
||||||
|
@ -539,65 +672,44 @@ connect "irc.uplink.com" {
|
||||||
/* port: the port to connect to this server on */
|
/* port: the port to connect to this server on */
|
||||||
port = 6666;
|
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: the class this server is in */
|
||||||
class = "server";
|
class = "server";
|
||||||
|
|
||||||
/* flags: controls special options for this server
|
/* flags: controls special options for this server
|
||||||
* encrypted - marks the accept_password as being crypt()'d
|
* encrypted - marks the accept_password as being crypt()'d
|
||||||
* autoconn - automatically connect to this server
|
* autoconn - automatically connect to this server
|
||||||
* compressed - compress traffic via ziplinks
|
* topicburst - burst topics between servers
|
||||||
* topicburst - burst topics between servers
|
* ssl - ssl/tls encrypted server connections
|
||||||
* 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" {
|
connect "ipv6.lame.server" {
|
||||||
/* Hosts that are IPv6 addresses must be in :: shortened form
|
host = "192.0.2.1";
|
||||||
* if applicable. Addresses starting with a colon get an extra
|
|
||||||
* zero prepended, for example: 0::1
|
|
||||||
*/
|
|
||||||
host = "2001:db8:3::8";
|
host = "2001:db8:3::8";
|
||||||
send_password = "password";
|
send_password = "password";
|
||||||
accept_password = "password";
|
accept_password = "password";
|
||||||
port = 6666;
|
port = 6666;
|
||||||
|
|
||||||
/* aftype: controls whether the connection uses "ipv4" or "ipv6".
|
/* aftype: controls whether the outgoing connection uses "ipv4" or "ipv6".
|
||||||
* Default is ipv4.
|
* Default is to try either at random.
|
||||||
*/
|
*/
|
||||||
aftype = ipv6;
|
aftype = ipv6;
|
||||||
class = "server";
|
class = "server";
|
||||||
};
|
};
|
||||||
|
|
||||||
connect "ssl.uplink.com" {
|
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";
|
host = "203.0.113.129";
|
||||||
send_password = "password";
|
send_password = "password";
|
||||||
accept_password = "anotherpassword";
|
accept_password = "anotherpassword";
|
||||||
port = 9999;
|
port = 9999;
|
||||||
hub_mask = "*";
|
|
||||||
class = "server";
|
class = "server";
|
||||||
flags = ssl, topicburst;
|
flags = ssl, topicburst;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* cluster {}; servers that we propagate things to automatically.
|
/* 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 {
|
cluster {
|
||||||
/* name: the server to share with, this can be a wildcard and may be
|
/* name: the server to share with, this can be a wildcard and may be
|
||||||
* stacked.
|
* stacked.
|
||||||
|
@ -630,8 +742,7 @@ cluster {
|
||||||
|
|
||||||
/* service{}: privileged servers (services). These servers have extra
|
/* service{}: privileged servers (services). These servers have extra
|
||||||
* privileges such as setting login names on users and introducing clients
|
* privileges such as setting login names on users and introducing clients
|
||||||
* with umode +S (unkickable, hide channels, etc). This does not allow them
|
* with umode +S (unkickable, hide channels, etc).
|
||||||
* to set bans, you need a separate shared{} for that.
|
|
||||||
* Do not place normal servers here.
|
* Do not place normal servers here.
|
||||||
* There may be only one service{} block.
|
* There may be only one service{} block.
|
||||||
*/
|
*/
|
||||||
|
@ -640,56 +751,6 @@ service {
|
||||||
name = "services.int";
|
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 {}: IPs that are exempt from Dlines and rejectcache. (OLD d:) */
|
||||||
exempt {
|
exempt {
|
||||||
ip = "192.0.2.0/24";
|
ip = "192.0.2.0/24";
|
||||||
|
@ -698,6 +759,12 @@ exempt {
|
||||||
ip = "127.0.0.1";
|
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 */
|
/* The channel block contains options pertaining to channels */
|
||||||
channel {
|
channel {
|
||||||
/* invex: Enable/disable channel mode +I, a n!u@h list of masks
|
/* 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: The maximum number of channels a user can join/be on. */
|
||||||
max_chans_per_user = 15;
|
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: maximum number of +b/e/I/q modes in a channel */
|
||||||
max_bans = 100;
|
max_bans = 100;
|
||||||
|
|
||||||
|
@ -755,7 +825,7 @@ channel {
|
||||||
default_split_user_count = 0;
|
default_split_user_count = 0;
|
||||||
|
|
||||||
/* split servers: when the amount of servers that have acknowledged
|
/* split servers: when the amount of servers that have acknowledged
|
||||||
* theyve finished bursting is lower than this, consider ourselves
|
* theyve finished bursting is lower than this, consider ourselves
|
||||||
* split. this must be set for automatic splitmode
|
* split. this must be set for automatic splitmode
|
||||||
*/
|
*/
|
||||||
default_split_server_count = 0;
|
default_split_server_count = 0;
|
||||||
|
@ -810,6 +880,22 @@ channel {
|
||||||
* such as LIST >0.
|
* such as LIST >0.
|
||||||
*/
|
*/
|
||||||
displayed_usercount = 3;
|
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.
|
* You can have multiple combinations of host and rejection reasons.
|
||||||
* They are used in pairs of one host/rejection reason.
|
* They are used in pairs of one host/rejection reason.
|
||||||
*
|
*
|
||||||
* These settings should be adequate for most networks, and are (presently)
|
* These settings should be adequate for most networks.
|
||||||
* required for use on StaticBox.
|
|
||||||
*
|
*
|
||||||
* Word to the wise: Do not use blacklists like SPEWS for blocking IRC
|
* Word to the wise: Do not use blacklists like SPEWS for blocking IRC
|
||||||
* connections.
|
* connections.
|
||||||
|
@ -867,7 +952,7 @@ serverhide {
|
||||||
* to match the final octet (e.g. 127.0.0.1) or "127.x.y.z" to explicitly match
|
* 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 blacklist is only applied if it matches anything in the
|
||||||
* list. You may freely mix full IP's and final octets.
|
* list. You may freely mix full IP's and final octets.
|
||||||
*
|
*
|
||||||
* Consult your blacklist provider for the meaning of these parameters; they
|
* Consult your blacklist provider for the meaning of these parameters; they
|
||||||
* are usually used to denote different ban types.
|
* are usually used to denote different ban types.
|
||||||
*/
|
*/
|
||||||
|
@ -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";
|
# 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)
|
* Alias blocks allow you to define custom commands. (Old m_sshortcut.c)
|
||||||
* They send PRIVMSG to the given target. A real command takes
|
* They send PRIVMSG to the given target. A real command takes
|
||||||
|
@ -1007,7 +1164,7 @@ general {
|
||||||
*/
|
*/
|
||||||
default_floodcount = 10;
|
default_floodcount = 10;
|
||||||
|
|
||||||
/* failed oper notice: send a notice to all opers on the server when
|
/* failed oper notice: send a notice to all opers on the server when
|
||||||
* someone tries to OPER and uses the wrong password, host or ident.
|
* someone tries to OPER and uses the wrong password, host or ident.
|
||||||
*/
|
*/
|
||||||
failed_oper_notice = yes;
|
failed_oper_notice = yes;
|
||||||
|
@ -1015,7 +1172,7 @@ general {
|
||||||
/* dots in ident: the amount of '.' characters permitted in an ident
|
/* dots in ident: the amount of '.' characters permitted in an ident
|
||||||
* reply before the user is rejected.
|
* reply before the user is rejected.
|
||||||
*/
|
*/
|
||||||
dots_in_ident=2;
|
dots_in_ident = 2;
|
||||||
|
|
||||||
/* min nonwildcard: the minimum non wildcard characters in k/d/g lines
|
/* min nonwildcard: the minimum non wildcard characters in k/d/g lines
|
||||||
* placed via the server. klines hand placed are exempt from limits.
|
* placed via the server. klines hand placed are exempt from limits.
|
||||||
|
@ -1079,28 +1236,72 @@ general {
|
||||||
* displayed unconditionally.
|
* displayed unconditionally.
|
||||||
*/
|
*/
|
||||||
global_snotices = yes;
|
global_snotices = yes;
|
||||||
|
|
||||||
/* dline reason: show the user the dline reason when they connect
|
/* dline reason: show the user the dline reason when they connect
|
||||||
* and are dlined.
|
* and are dlined.
|
||||||
*/
|
*/
|
||||||
dline_with_reason = yes;
|
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
|
/* 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.
|
* on exit. may give away who set k/dline when set via tcm.
|
||||||
*/
|
*/
|
||||||
kline_with_reason = yes;
|
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
|
/* kline reason: make the users quit message on channels this
|
||||||
* reason instead of the oper's reason.
|
* reason instead of the oper's reason.
|
||||||
*/
|
*/
|
||||||
kline_reason = "Connection closed";
|
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
|
/* identify to services via server password
|
||||||
* if auth{} block had no password but the user specified a
|
* if auth{} block had no password but the user specified a
|
||||||
* server password anyway, send a PRIVMSG to <identify_service>
|
* server password anyway, send a PRIVMSG to <identify_service>
|
||||||
|
@ -1113,7 +1314,7 @@ general {
|
||||||
non_redundant_klines = yes;
|
non_redundant_klines = yes;
|
||||||
|
|
||||||
/* warn no nline: warn opers about servers that try to connect but
|
/* warn no nline: warn opers about servers that try to connect but
|
||||||
* we dont have a connect {} block for. Twits with misconfigured
|
* we dont have a connect {} block for. Twits with misconfigured
|
||||||
* servers can get really annoying with this enabled.
|
* servers can get really annoying with this enabled.
|
||||||
*/
|
*/
|
||||||
warn_no_nline = yes;
|
warn_no_nline = yes;
|
||||||
|
@ -1131,36 +1332,40 @@ general {
|
||||||
stats_e_disabled = no;
|
stats_e_disabled = no;
|
||||||
|
|
||||||
/* stats c oper only: make stats c (connect {}) oper only */
|
/* stats c oper only: make stats c (connect {}) oper only */
|
||||||
stats_c_oper_only=no;
|
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: make stats y (class {}) oper only */
|
||||||
stats_y_oper_only=no;
|
stats_y_oper_only = no;
|
||||||
|
|
||||||
/* stats o oper only: make stats o (opers) oper only */
|
/* stats o oper only: make stats o (opers) oper only */
|
||||||
stats_o_oper_only=yes;
|
stats_o_oper_only = yes;
|
||||||
|
|
||||||
/* stats P oper only: make stats P (ports) oper only
|
/* stats P oper only: make stats P (ports) oper only
|
||||||
* NOTE: users doing stats P will never be given the ips that the
|
* NOTE: users doing stats P will never be given the ips that the
|
||||||
* server listens on, simply the ports.
|
* server listens on, simply the ports.
|
||||||
*/
|
*/
|
||||||
stats_P_oper_only=no;
|
stats_P_oper_only = no;
|
||||||
|
|
||||||
/* stats i oper only: make stats i (auth {}) oper only. set to:
|
/* stats i oper only: make stats i (auth {}) oper only. set to:
|
||||||
* yes: show users no auth blocks, made oper only.
|
* yes: show users no auth blocks, made oper only.
|
||||||
* masked: show users first matching auth block
|
* masked: show users first matching auth block
|
||||||
* no: show users all auth blocks.
|
* no: show users all auth blocks.
|
||||||
*/
|
*/
|
||||||
stats_i_oper_only=masked;
|
stats_i_oper_only = masked;
|
||||||
|
|
||||||
/* stats k/K oper only: make stats k/K (klines) oper only. set to:
|
/* stats k/K oper only: make stats k/K (klines) oper only. set to:
|
||||||
* yes: show users no auth blocks, made oper only
|
* yes: show users no auth blocks, made oper only
|
||||||
* masked: show users first matching auth block
|
* masked: show users first matching auth block
|
||||||
* no: show users all auth blocks.
|
* no: show users all auth blocks.
|
||||||
*/
|
*/
|
||||||
stats_k_oper_only=masked;
|
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: make /map oper only */
|
||||||
map_oper_only = no;
|
map_oper_only = no;
|
||||||
|
@ -1202,6 +1407,13 @@ general {
|
||||||
*/
|
*/
|
||||||
ping_cookie = no;
|
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
|
/* connect timeout: sets how long we should wait for a connection
|
||||||
* request to succeed
|
* request to succeed
|
||||||
*/
|
*/
|
||||||
|
@ -1220,12 +1432,18 @@ general {
|
||||||
|
|
||||||
/* REMOVE ME. The following line checks you've been reading. */
|
/* REMOVE ME. The following line checks you've been reading. */
|
||||||
havent_read_conf = yes;
|
havent_read_conf = yes;
|
||||||
|
|
||||||
/* max targets: the maximum amount of targets in a single
|
/* max targets: the maximum amount of targets in a single
|
||||||
* PRIVMSG/NOTICE. set to 999 NOT 0 for unlimited.
|
* PRIVMSG/NOTICE. set to 999 NOT 0 for unlimited.
|
||||||
*/
|
*/
|
||||||
max_targets = 4;
|
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
|
/* use_whois_actually: send clients requesting a whois a numeric
|
||||||
* giving the real IP of non-spoofed clients to prevent DNS abuse.
|
* giving the real IP of non-spoofed clients to prevent DNS abuse.
|
||||||
*/
|
*/
|
||||||
|
@ -1233,9 +1451,9 @@ general {
|
||||||
|
|
||||||
/* usermodes configurable: a list of usermodes for the options below
|
/* 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
|
* +D - deaf - Don't see channel messages
|
||||||
* +i - invisible - Not shown in NAMES or WHO unless you share a
|
* +i - invisible - Not shown in NAMES or WHO unless you share a
|
||||||
* a channel
|
* a channel
|
||||||
* +l - locops - See LOCOPS messages
|
* +l - locops - See LOCOPS messages
|
||||||
* +Q - noforward - Unaffected by channel forwarding
|
* +Q - noforward - Unaffected by channel forwarding
|
||||||
|
@ -1244,7 +1462,7 @@ general {
|
||||||
* +w - wallop - See oper and server generated WALLOPS
|
* +w - wallop - See oper and server generated WALLOPS
|
||||||
* +z - operwall - See operwalls
|
* +z - operwall - See operwalls
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* oper only umodes: usermodes only opers may set */
|
/* oper only umodes: usermodes only opers may set */
|
||||||
oper_only_umodes = operwall, locops, servnotice;
|
oper_only_umodes = operwall, locops, servnotice;
|
||||||
|
|
||||||
|
@ -1255,14 +1473,6 @@ general {
|
||||||
* provided they have umode +s set */
|
* provided they have umode +s set */
|
||||||
oper_snomask = "+s";
|
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.
|
/* burst_away: This enables bursting away messages to servers.
|
||||||
* With this disabled, we will only propogate AWAY messages
|
* With this disabled, we will only propogate AWAY messages
|
||||||
* as users send them, but never burst them. Be warned though
|
* 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
|
* "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.
|
* 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:
|
* To generate a fingerprint from a certificate file, run the following:
|
||||||
* $ openssl x509 -outform DER -in your.crt | sha1sum (or sha256sum, or sha512sum)
|
* $ openssl x509 -outform DER -in your.crt | sha1sum (or sha256sum, or sha512sum)
|
||||||
*
|
*
|
||||||
|
@ -1348,17 +1559,44 @@ general {
|
||||||
* sha512sum | sed -r -e 's/^/SPKI:SHA2-512:/'
|
* sha512sum | sed -r -e 's/^/SPKI:SHA2-512:/'
|
||||||
*/
|
*/
|
||||||
certfp_method = sha256;
|
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 {
|
modules {
|
||||||
/* module path: paths to search for modules specified below and
|
/* module path: paths to search for modules specified below and
|
||||||
* in /modload.
|
* in /modload.
|
||||||
*/
|
*/
|
||||||
path = "/usr/local/ircd/modules";
|
path = "/usr/local/ircd/modules";
|
||||||
path = "/usr/local/ircd/modules/autoload";
|
path = "/usr/local/ircd/modules/autoload";
|
||||||
|
|
||||||
/* module: the name of a module to load on startup/rehash */
|
/* 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
|
Server VERSION Info
|
||||||
|
|
||||||
$Id: server-version-info 1851 2006-08-24 17:16:53Z jilles $
|
|
||||||
|
|
||||||
Copyright (c) 2001 by ircd-hybrid team
|
Copyright (c) 2001 by ircd-hybrid team
|
||||||
Copyright (c) 2002 ircd-ratbox development 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:
|
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
|
Ever wondered what those funny chars mean after the version number? Well
|
||||||
here they are:
|
here they are:
|
||||||
|
@ -17,12 +17,6 @@
|
||||||
+----------------------------+
|
+----------------------------+
|
||||||
| 'e' | USE_EXCEPT |
|
| 'e' | USE_EXCEPT |
|
||||||
|------+---------------------|
|
|------+---------------------|
|
||||||
| 'g' | NO_FAKE_GLINES |
|
|
||||||
|------+---------------------|
|
|
||||||
| 'G' | GLINES |
|
|
||||||
|------+---------------------|
|
|
||||||
| 'H' | HUB |
|
|
||||||
|------+---------------------|
|
|
||||||
| 'I' | USE_INVEX |
|
| 'I' | USE_INVEX |
|
||||||
|------+---------------------|
|
|------+---------------------|
|
||||||
| 'K' | USE_KNOCK |
|
| 'K' | USE_KNOCK |
|
||||||
|
@ -33,8 +27,6 @@
|
||||||
|------+---------------------|
|
|------+---------------------|
|
||||||
| 'S' | OPERS_SEE_ALL_USERS |
|
| 'S' | OPERS_SEE_ALL_USERS |
|
||||||
|------+---------------------|
|
|------+---------------------|
|
||||||
| 'T' | IGNORE_BOGUS_TS |
|
|
||||||
|------+---------------------|
|
|
||||||
| 'Z' | ZIPLINKS |
|
| 'Z' | ZIPLINKS |
|
||||||
|------+---------------------|
|
|------+---------------------|
|
||||||
| '6' | IPv6 |
|
| '6' | IPv6 |
|
||||||
|
@ -43,7 +35,7 @@
|
||||||
|------+---------------------|
|
|------+---------------------|
|
||||||
| 'TS' | Supports TS |
|
| 'TS' | Supports TS |
|
||||||
|------+---------------------|
|
|------+---------------------|
|
||||||
| '5' | TS Version 5 |
|
| '6' | TS Version 6 |
|
||||||
|------+---------------------|
|
|------+---------------------|
|
||||||
| 'o' | TS Only |
|
| '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
|
Server capabilities
|
||||||
William Pitcock <nenolod -at- nenolod.net>
|
Ariadne Conill <ariadne -at- dereferenced.org>
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
Not all TSora IRCd's support these.
|
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
|
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.
|
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
|
Extended UID command proposal
|
||||||
Jilles Tjoelker <jilles@stack.nl>
|
Jilles Tjoelker <jilles@stack.nl>
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
Overview of the event subsystem
|
Overview of the event subsystem
|
||||||
Adrian Chadd <adrian@creative.net.au>
|
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
|
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
|
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.
|
|
|
@ -6,7 +6,7 @@ contrib/example_module.c, this document simply describes which hooks are
|
||||||
available.
|
available.
|
||||||
|
|
||||||
There are various hook structures available that may be passed to hooks:
|
There are various hook structures available that may be passed to hooks:
|
||||||
hook_data - struct Client *client; const void *arg1;
|
hook_data - struct Client *client; const void *arg1;
|
||||||
const void *arg2;
|
const void *arg2;
|
||||||
hook_data_int - struct Client *client; const void *arg1; int arg2;
|
hook_data_int - struct Client *client; const void *arg1; int arg2;
|
||||||
hook_data_client - struct Client *client; struct Client *target;
|
hook_data_client - struct Client *client; struct Client *target;
|
||||||
|
@ -114,11 +114,27 @@ The following hooks are called during various events related to clients.
|
||||||
oldsnomask = new snomask field
|
oldsnomask = new snomask field
|
||||||
|
|
||||||
|
|
||||||
The following are for debugging and take struct hook_io_data for arguments.
|
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
|
These can be used for a variety of purposes, but are aimed at the developer
|
||||||
community.
|
community.
|
||||||
"iosend"
|
"iosend"
|
||||||
"iorecv"
|
"iorecv"
|
||||||
"iorecvctrl"
|
"iorecvctrl"
|
||||||
|
|
||||||
$Id: hooks.txt 3414 2007-04-15 16:54:50Z jilles $
|
|
|
@ -1,6 +1,5 @@
|
||||||
The hostmask/netmask system.
|
The hostmask/netmask system.
|
||||||
Copyright(C) 2001 by Andrew Miller(A1kmm)<a1kmm@mware.virtualave.net>
|
Copyright(C) 2001 by Andrew Miller(A1kmm)<a1kmm@mware.virtualave.net>
|
||||||
$Id: hostmask.txt 6 2005-09-10 01:02:21Z nenolod $
|
|
||||||
|
|
||||||
Contents
|
Contents
|
||||||
========
|
========
|
||||||
|
@ -95,7 +94,7 @@ Section 3.3: Initialising and rehashing
|
||||||
To initialise, call init_host_hash(). This only needs to be done once on
|
To initialise, call init_host_hash(). This only needs to be done once on
|
||||||
startup.
|
startup.
|
||||||
On rehash, to wipe out the old unwanted conf, and free them if there are
|
On rehash, to wipe out the old unwanted conf, and free them if there are
|
||||||
no references to them, call clear_out_address_conf().
|
no references to them, call clear_out_address_conf().
|
||||||
|
|
||||||
Section 3.4: Finding IP/host confs
|
Section 3.4: Finding IP/host confs
|
||||||
----------------------------------
|
----------------------------------
|
||||||
|
|
|
@ -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)
|
capab.txt - Description of server capabilities
|
||||||
proposal
|
cluster.txt - Technical description of the cluster system
|
||||||
README.TSora - Description of the TS3 protocol
|
euid.txt - Description of TS6 EUIDs
|
||||||
README.openssl - Information for users who have problems with
|
|
||||||
Hybrid, OpenSSL, and their operating system
|
|
||||||
cryptlink.txt - Outline of CRYPTLINK protocol
|
|
||||||
event.txt - Outline of the event system
|
event.txt - Outline of the event system
|
||||||
fd-management.txt - Outline of the file descriptor management system
|
hooks.txt - Internal IRC daemon hoks
|
||||||
file-management.txt - Outline of the disk file management system
|
|
||||||
hostmask.txt - Outline of hostmask handling
|
hostmask.txt - Outline of hostmask handling
|
||||||
linebuf.txt - Outline of the linebuf system (dbuf replacement)
|
linebuf.txt - Outline of the linebuf system (dbuf replacement)
|
||||||
network.txt - Outline of the network traffic subsystem
|
ts6-protocol.txt - Description of the TS6 protocol
|
||||||
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 $
|
|
||||||
|
|
|
@ -1,10 +1,7 @@
|
||||||
|
|
||||||
linebuf - a dbuf replacement for the New World Order(tm)
|
linebuf - a dbuf replacement for the New World Order(tm)
|
||||||
|
|
||||||
By Adrian Chadd <adrian@creative.net.au>
|
By Adrian Chadd <adrian@creative.net.au>
|
||||||
|
|
||||||
$Id: linebuf.txt 6 2005-09-10 01:02:21Z nenolod $
|
|
||||||
|
|
||||||
|
|
||||||
History
|
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
|
TS6 protocol description
|
||||||
Written by Jilles Tjoelker
|
Written by Jilles Tjoelker
|
||||||
|
Edits by Elizabeth Myers to add TS rules described by Lee Harvey.
|
||||||
|
|
||||||
General format: much like rfc1459
|
General format: much like rfc1459
|
||||||
Maximum parameters for a command: 15 (this does not include the prefix
|
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
|
UIDs/SIDs (sending names or even wildcards is deprecated). This is done with
|
||||||
the function hunt_server(). Any rate limiting should be done locally.
|
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.
|
duration: a parameter type used for ban durations. It is a duration in seconds.
|
||||||
A value of 0 means a permanent ban.
|
A value of 0 means a permanent ban.
|
||||||
|
|
||||||
|
@ -112,6 +114,75 @@ type D
|
||||||
+g (allow any member to /invite)
|
+g (allow any member to /invite)
|
||||||
+z (send messages blocked by +m to chanops)
|
+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>
|
<numeric>
|
||||||
source: server
|
source: server
|
||||||
parameters: target, any...
|
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.
|
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
|
ENCAP
|
||||||
source: any
|
source: any
|
||||||
parameters: target server mask, subcommand, opt. parameters...
|
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
|
Servers may not send '$$', '$#' and opers@server notices. Older servers may
|
||||||
not allow servers to send to specific statuses on a channel.
|
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
|
OPERSPY
|
||||||
encap only
|
encap only
|
||||||
encap target: *
|
encap target: *
|
||||||
|
@ -1137,8 +1237,6 @@ CAP
|
||||||
CHALLENGE
|
CHALLENGE
|
||||||
CHANTRACE
|
CHANTRACE
|
||||||
CLOSE
|
CLOSE
|
||||||
CNOTICE
|
|
||||||
CPRIVMSG
|
|
||||||
DIE
|
DIE
|
||||||
GET
|
GET
|
||||||
HELP
|
HELP
|
||||||
|
@ -1153,7 +1251,6 @@ MODRESTART
|
||||||
MODUNLOAD
|
MODUNLOAD
|
||||||
MONITOR
|
MONITOR
|
||||||
NAMES
|
NAMES
|
||||||
OPER
|
|
||||||
POST
|
POST
|
||||||
PUT
|
PUT
|
||||||
RESTART
|
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 solanum ircd that
|
||||||
|
|
||||||
This directory contains extensions (modules) to charybdis ircd that
|
|
||||||
have been contributed by other people, or written by our development
|
have been contributed by other people, or written by our development
|
||||||
team. Unsupported extensions live under unsupported/.
|
team.
|
||||||
|
|
||||||
|
|
||||||
Modules
|
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.
|
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)
|
m_adminwall.c - Sends a message to all admins network-wide (umode +a)
|
||||||
Syntax: ADMINWALL :<message>
|
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_canjoin.so - Banned from another channel (+b $j:mask)
|
||||||
extb_channel.so - Other-channel bans (+b $c:mask)
|
extb_channel.so - Other-channel bans (+b $c:mask)
|
||||||
extb_extgecos.so - Extended ban (+b $x: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_oper.so - Oper bans (+b $o)
|
||||||
extb_realname.so - Realname (gecos) bans (+b $r:mask)
|
extb_realname.so - Realname (gecos) bans (+b $r:mask)
|
||||||
extb_server.so - Server bans (+b $s: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 "numeric.h"
|
||||||
#include "chmode.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[] = {
|
mapi_hfn_list_av1 adminonly_hfnlist[] = {
|
||||||
{ "can_join", (hookfn) h_can_join },
|
{ "can_join", h_can_join },
|
||||||
{ NULL, NULL }
|
{ NULL, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -35,11 +38,12 @@ _moddeinit(void)
|
||||||
cflag_orphan('A');
|
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
|
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 Client *source_p = data->client;
|
||||||
struct Channel *chptr = data->chptr;
|
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