Compare commits

..

1 commit

Author SHA1 Message Date
Ariadne Conill
56d5e9f341 charybdis is officially discontinued 2021-06-24 10:19:05 -06:00
483 changed files with 207265 additions and 7395 deletions

9
.appveyor-build.sh Normal file
View file

@ -0,0 +1,9 @@
set -v
export MSYSTEM=MINGW64
export PATH=/mingw64/bin:/usr/local/bin:/usr/bin:/bin:/c/Windows/system32:/c/Windows:/c/Windows/System32/Wbem:/c/Windows/System32/WindowsPowerShell/v1.0:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl
sh ./autogen.sh
./configure --prefix=c:/projects/charybdis/build --enable-openssl=/mingw64
make -j2
make install

18
.appveyor.yml Normal file
View file

@ -0,0 +1,18 @@
version: 4_{build}
clone_depth: 10
install:
- c:\msys64\usr\bin\sh.exe -lc "pacman -Sy --noconfirm git"
- c:\msys64\usr\bin\sh.exe -lc "uname -a"
- c:\msys64\usr\bin\sh.exe -lc "cat /proc/cpuinfo"
- c:\msys64\usr\bin\sh.exe -lc "cat /proc/meminfo"
- c:\msys64\usr\bin\sh.exe -lc "cygcheck -s -v > $APPVEYOR_BUILD_FOLDER/cygcheck.log 2>&1"
- ps: Push-AppveyorArtifact cygcheck.log
build_script:
- c:\msys64\usr\bin\sh.exe -lc "cd $APPVEYOR_BUILD_FOLDER; sh .appveyor-build.sh"
# - c:\msys64\usr\bin\sh.exe -lc "cd $APPVEYOR_BUILD_FOLDER/build/bin; ./charybdis -version"
on_failure:
- ps: Push-AppveyorArtifact config.log
- ps: Push-AppveyorArtifact librb\include\librb-config.h
branches:
except:
- release/3.5

View file

@ -1,82 +0,0 @@
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

View file

@ -1,29 +0,0 @@
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

27
.gitignore vendored
View file

@ -14,7 +14,7 @@ Makefile
.libs
authd/authd
bandb/bandb
bandb/solanum-bantool
bandb/bantool
autom4te.cache
aclocal.m4
compile
@ -48,7 +48,7 @@ scripts/*.tar.bz2
scripts/*.tar.gz
include/setup.h
include/setup.h.in
ircd/solanum
ircd/charybdis
ircd/ircd_parser.c
ircd/ircd_parser.h
ircd/ircd_lexer.c
@ -56,14 +56,31 @@ ircd/version.c
ircd/version.c.last
ssld/ssld
wsockd/wsockd
tests/core
tests/msgbuf_parse1
tests/msgbuf_unparse1
tests/rb_dictionary1
tests/rb_snprintf_append1
tests/rb_snprintf_try_append1
tests/sasl_abort1
tests/send1
tests/serv_connect1
tests/substitution1
tests/runtests
tests/*.c.ban.db
tests/*.c.ban.db-journal
tests/*.c.log
tests/*.c.pid
!tests/runtime/modules/*.so
!tests/runtime/modules/autoload/*.so
testsuite/ircd.pid.*
tools/solanum-mkpasswd
tools/solanum-mkfingerprint
tools/charybdis-mkpasswd
tools/charybdis-mkfingerprint
tools/genssl
tools/mkpasswd
tools/viconf
include/serno.h
ircd/solanum
ircd/charybdis
ircd/version.c
ircd/version.c.last
/libtool

View file

@ -1,8 +1,5 @@
Aaron Sethman <androsyn@ratbox.org> androsyn <devnull@localhost>
Alexander Færøy <ahf@0x90.dk> Alexander F?r?y <ahf@0x90.dk>
Ariadne Conill <ariadne@dereferenced.org> <nenolod@atheme.org>
Ariadne Conill <ariadne@dereferenced.org> <nenolod@dereferenced.org>
Ariadne Conill <ariadne@dereferenced.org> nenolod <devnull@localhost>
Brett Greenham <taros@shadowircd.net> B.Greenham <taros@shadowircd.net>
Chris Mills <chris@chrisam.net> TheChrisAM <chris@chrisam.net>
Chris Mills <chris@chrisam.net> freenode!ChrisAM <chris@chrisam.net>
@ -18,5 +15,7 @@ Valeriy Yatsko <dwr@shadowircd.net> <darkwire@darkwire.ru>
Valeriy Yatsko <dwr@shadowircd.net> <darkwire@ircd-charybdis.ru>
Valeriy Yatsko <dwr@shadowircd.net> <darkwire@sellcenter.ru>
Valeriy Yatsko <dwr@shadowircd.net> <dwr@it-penza.org>
William Pitcock <nenolod@dereferenced.org> <nenolod@atheme.org>
William Pitcock <nenolod@dereferenced.org> nenolod <devnull@localhost>
Christine Dodrill <shadow.h511@gmail.com> <quora@lavabit.com>
Christine Dodrill <shadow.h511@gmail.com> <quorawings@gmail.com>

57
.travis.yml Normal file
View file

@ -0,0 +1,57 @@
# Travis-CI Build for charybdis
# see travis-ci.org for details
language: c
# Use the faster container-based infrastructure.
dist: bionic
sudo: false
notifications:
irc:
channels:
- "chat.freenode.net#charybdis"
matrix:
include:
- os: linux
compiler: gcc-7
addons:
apt:
packages: ['gcc-7', 'automake', 'autoconf', 'libtool', 'shtool', 'libsqlite3-dev', 'python-sphinx', 'texinfo', 'libhyperscan-dev']
- os: linux
compiler: gcc-8
addons:
apt:
packages: ['gcc-8', 'automake', 'autoconf', 'libtool', 'shtool', 'libsqlite3-dev', 'python-sphinx', 'texinfo', 'libhyperscan-dev']
- os: linux
compiler: clang-7
addons:
apt:
packages: ['clang-7', 'automake', 'autoconf', 'libtool', 'shtool', 'libsqlite3-dev', 'python-sphinx', 'texinfo', 'libhyperscan-dev']
- os: linux
compiler: clang-8
addons:
apt:
packages: ['clang-8', 'automake', 'autoconf', 'libtool', 'shtool', 'libsqlite3-dev', 'python-sphinx', 'texinfo', 'libhyperscan-dev']
- os: osx
osx_image: xcode7.3
compiler: clang
env: LIBTOOLIZE=glibtoolize
cache:
apt:
ccache:
script:
- bash autogen.sh
- "if [ ${TRAVIS_OS_NAME} != 'osx' ]; then CFLAGS=\"-Werror -Wno-unused-value -Wno-unused-parameter\" ./configure --with-shared-sqlite --with-assert=hard --enable-warnings; fi"
- "if [ ${TRAVIS_OS_NAME} = 'osx' ]; then ./configure --with-shared-sqlite; fi"
- make -j4
- "if [ ${TRAVIS_OS_NAME} != 'osx' ]; then make check; fi"
- make install
- "if [ ${TRAVIS_OS_NAME} != 'osx' ]; then make -C doc/oper-guide html man info; fi"

53
CREDITS
View file

@ -1,28 +1,43 @@
Solanum is based on Charybdis, which was based on ircd-ratbox.
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.
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:
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>
jdhore, JD Horelick <jdhore1 -at- gmail.com>
jilles, Jilles Tjoelker <jilles -at- stack.nl>
kaniini, William Pitcock <nenolod -at- dereferenced.org>
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>
A full list of contributors to Charybdis and its predecessors
is in doc/credits-past.txt.
The following people have made contributions to the Charybdis releases,
in nick-alphabetical order:
Visit the Solanum website at: https://solanum.chat/
Visit us on IRC at: irc.libera.chat #solanum
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

View file

@ -19,6 +19,8 @@ SUBDIRS += ircd \
help \
doc
logdir = @prefix@/logs
BUILT_SOURCES = include/serno.h
include/serno.h:
@ -39,11 +41,9 @@ 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

88
NEWS.md
View file

@ -1,94 +1,12 @@
# News
This is solanum 1.0-dev.
This is charybdis 4.1.3-dev, Copyright (c) 2005-2018 Charybdis team.
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
- src/s_user.c: don't corrupt usermodes on module unload/reload
## charybdis-4.1.1
@ -847,7 +765,7 @@ bolded warnings in the full release notes below.
## charybdis-1.0
- 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.
- Change behaviour of /stats p: now displays all staff members instead
of local ones only.

View file

@ -1,94 +1,15 @@
# solanum ![Build Status](https://github.com/solanum-ircd/solanum/workflows/CI/badge.svg)
# charybdis
Solanum is an IRCv3 server designed to be highly scalable. It implements IRCv3.1 and some parts of IRCv3.2.
Charybdis was an IRCv3 server designed to be highly scalable. It implements IRCv3.1 and some parts of IRCv3.2.
It is meant to be used with an IRCv3-capable services implementation such as [Atheme][atheme] or [Anope][anope].
It was meant to be used with an IRCv3-capable services implementation such as [Atheme][atheme] or [Anope][anope].
[atheme]: https://atheme.github.io/
[atheme]: http://www.atheme.net/
[anope]: http://www.anope.org/
# necessary requirements
It is no longer maintained due to the scope of refactoring needed to support modern IRCv3 features.
* A supported platform
* A working dynamic library system
* A working lex and yacc - flex and bison should work
These days, you should use [Solanum][solanum] instead. For almost all real-world deployments of Charybdis,
it is better.
# platforms
Solanum is developed on Linux with glibc, but is currently portable to most POSIX-compatible operating systems.
However, this portability is likely to be removed unless someone is willing to maintain it. If you'd like to be that
person, please let us know on IRC.
# platform specific errata
These are known issues and workarounds for various platforms.
* **macOS**: you must set the `LIBTOOLIZE` environment variable to point to glibtoolize before running autogen.sh:
```bash
brew install libtool
export LIBTOOLIZE="/usr/local/bin/glibtoolize"
./autogen.sh
```
* **FreeBSD**: if you are compiling with ipv6 you may experience
problems with ipv4 due to the way the socket code is written. To
fix this you must: `sysctl net.inet6.ip6.v6only=0`
* **Solaris**: you may have to set your `PATH` to include `/usr/gnu/bin` and `/usr/gnu/sbin` before `/usr/bin`
and `/usr/sbin`. Solaris's default tools don't seem to play nicely with the configure script. When running
as a 32-bit binary, it should be started as:
```bash
ulimit -n 4095 ; LD_PRELOAD_32=/usr/lib/extendedFILE.so.1 ./solanum
```
# building
```bash
sudo apt install build-essential pkg-config automake libtool libsqlite3-dev # or equivalent for your distribution
./autogen.sh
./configure --prefix=/path/to/installation
make
make check # run tests
make install
```
See `./configure --help` for build options.
# feature specific requirements
* For SSL/TLS client and server connections, one of:
* OpenSSL 1.0.0 or newer (`--enable-openssl`)
* LibreSSL (`--enable-openssl`)
* mbedTLS (`--enable-mbedtls`)
* GnuTLS (`--enable-gnutls`)
* For certificate-based oper CHALLENGE, OpenSSL 1.0.0 or newer.
(Using CHALLENGE is not recommended for new deployments, so if you want to use a different TLS library,
feel free.)
* 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).
# tips
* To report bugs in Solanum, visit us at `#solanum` on [Libera Chat](https://libera.chat)
* Please read [doc/readme.txt](doc/readme.txt) to get an overview of the current documentation.
* Read the [NEWS.md](NEWS.md) file for what's new in this release.
* The files, `/etc/services`, `/etc/protocols`, and `/etc/resolv.conf`, SHOULD be
readable by the user running the server in order for ircd to start with
the correct settings. If these files are wrong, Solanum will try to use
`127.0.0.1` for a resolver as a last-ditch effort.
# git access
* The Solanum git repository can be checked out using the following command:
`git clone https://github.com/solanum-ircd/solanum`
* Solanum's git repository can be browsed over the Internet at the following address:
https://github.com/solanum-ircd/solanum
[solanum]: https://github.com/solanum-ircd/solanum

View file

@ -5,10 +5,13 @@ AM_CPPFLAGS = -I../include -I../librb/include
authd_SOURCES = \
authd.c \
dns.c \
getaddrinfo.c \
getnameinfo.c \
notice.c \
provider.c \
res.c \
reslib.c \
reslist.c \
providers/dnsbl.c \
providers/ident.c \
providers/rdns.c \

View file

@ -1,5 +1,5 @@
/* authd/authd.c - main code for authd
* Copyright (c) 2016 Ariadne Conill <ariadne@dereferenced.org>
* Copyright (c) 2016 William Pitcock <nenolod@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
@ -151,15 +151,18 @@ error_cb(rb_helper *helper)
exit(EX_ERROR);
}
#ifndef _WIN32
static void
dummy_handler(int sig)
{
return;
}
#endif
static void
setup_signals(void)
{
#ifndef _WIN32
struct sigaction act;
act.sa_flags = 0;
@ -182,6 +185,7 @@ setup_signals(void)
act.sa_handler = dummy_handler;
sigaction(SIGALRM, &act, 0);
#endif
}
int

View file

@ -1,5 +1,5 @@
/* authd/dns.h - header for authd DNS functions
* Copyright (c) 2016 Ariadne Conill <ariadne@dereferenced.org>
* Copyright (c) 2016 William Pitcock <nenolod@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

View file

@ -1,5 +1,5 @@
/* authd/dns.c - authd DNS functions
* Copyright (c) 2016 Ariadne Conill <ariadne@dereferenced.org>
* Copyright (c) 2016 William Pitcock <nenolod@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

View file

@ -1,5 +1,5 @@
/* authd/dns.h - header for authd DNS functions
* Copyright (c) 2016 Ariadne Conill <ariadne@dereferenced.org>
* Copyright (c) 2016 William Pitcock <nenolod@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

617
authd/getaddrinfo.c Normal file
View file

@ -0,0 +1,617 @@
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* All rights reserved.
*
* 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. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``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 PROJECT OR CONTRIBUTORS 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.
*/
#ifdef _WIN32
#include <rb_lib.h>
#include "getaddrinfo.h"
#include "stdinc.h"
static const char in_addrany[] = { 0, 0, 0, 0 };
static const char in_loopback[] = { 127, 0, 0, 1 };
static const char in6_addrany[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
static const char in6_loopback[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1
};
static const struct afd {
int a_af;
int a_addrlen;
int a_socklen;
int a_off;
const char *a_addrany;
const char *a_loopback;
int a_scoped;
} afdl [] = {
#define N_INET6 0
#ifdef IPV6
{PF_INET6, sizeof(struct in6_addr),
sizeof(struct sockaddr_in6),
offsetof(struct sockaddr_in6, sin6_addr),
in6_addrany, in6_loopback, 1},
#endif
#define N_INET 1
{PF_INET, sizeof(struct in_addr),
sizeof(struct sockaddr_in),
offsetof(struct sockaddr_in, sin_addr),
in_addrany, in_loopback, 0},
{0, 0, 0, 0, NULL, NULL, 0},
};
struct explore {
int e_af;
int e_socktype;
int e_protocol;
const char *e_protostr;
int e_wild;
#define WILD_AF(ex) ((ex)->e_wild & 0x01)
#define WILD_SOCKTYPE(ex) ((ex)->e_wild & 0x02)
#define WILD_PROTOCOL(ex) ((ex)->e_wild & 0x04)
};
static const struct explore explore[] = {
#ifdef IPV6
{ PF_INET6, SOCK_DGRAM, IPPROTO_UDP, "udp", 0x07 },
{ PF_INET6, SOCK_STREAM, IPPROTO_TCP, "tcp", 0x07 },
{ PF_INET6, SOCK_RAW, ANY, NULL, 0x05 },
#endif
{ PF_INET, SOCK_DGRAM, IPPROTO_UDP, "udp", 0x07 },
{ PF_INET, SOCK_STREAM, IPPROTO_TCP, "tcp", 0x07 },
{ PF_INET, SOCK_RAW, ANY, NULL, 0x05 },
{ PF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP, "udp", 0x07 },
{ PF_UNSPEC, SOCK_STREAM, IPPROTO_TCP, "tcp", 0x07 },
{ PF_UNSPEC, SOCK_RAW, ANY, NULL, 0x05 },
{ -1, 0, 0, NULL, 0 },
};
#define PTON_MAX 16
static bool str_isnumber(const char *);
static int explore_null(const struct rb_addrinfo *,
const char *, struct rb_addrinfo **);
static int explore_numeric(const struct rb_addrinfo *, const char *,
const char *, struct rb_addrinfo **);
static struct rb_addrinfo *get_ai(const struct rb_addrinfo *,
const struct afd *, const char *);
static int get_portmatch(const struct rb_addrinfo *, const char *);
static int get_port(struct rb_addrinfo *, const char *, int);
static const struct afd *find_afd(int);
#if 0
/* We will need this should we ever want gai_strerror() */
static char *ai_errlist[] = {
"Success",
"Address family for hostname not supported", /* EAI_ADDRFAMILY */
"Temporary failure in name resolution", /* EAI_AGAIN */
"Invalid value for ai_flags", /* EAI_BADFLAGS */
"Non-recoverable failure in name resolution", /* EAI_FAIL */
"ai_family not supported", /* EAI_FAMILY */
"Memory allocation failure", /* EAI_MEMORY */
"No address associated with hostname", /* EAI_NODATA */
"hostname nor servname provided, or not known", /* EAI_NONAME */
"servname not supported for ai_socktype", /* EAI_SERVICE */
"ai_socktype not supported", /* EAI_SOCKTYPE */
"System error returned in errno", /* EAI_SYSTEM */
"Invalid value for hints", /* EAI_BADHINTS */
"Resolved protocol is unknown", /* EAI_PROTOCOL */
"Unknown error", /* EAI_MAX */
};
#endif
/* XXX macros that make external reference is BAD. */
#define GET_AI(ai, afd, addr) \
do { \
/* external reference: pai, error, and label free */ \
(ai) = get_ai(pai, (afd), (addr)); \
if ((ai) == NULL) { \
error = EAI_MEMORY; \
goto free; \
} \
} while (/*CONSTCOND*/0)
#define GET_PORT(ai, serv) \
do { \
/* external reference: error and label free */ \
error = get_port((ai), (serv), 0); \
if (error != 0) \
goto free; \
} while (/*CONSTCOND*/0)
#define ERR(err) \
do { \
/* external reference: error, and label bad */ \
error = (err); \
goto bad; \
/*NOTREACHED*/ \
} while (/*CONSTCOND*/0)
#define MATCH_FAMILY(x, y, w) \
((x) == (y) || (/*CONSTCOND*/(w) && ((x) == PF_UNSPEC || (y) == PF_UNSPEC)))
#define MATCH(x, y, w) \
((x) == (y) || (/*CONSTCOND*/(w) && ((x) == ANY || (y) == ANY)))
#if 0
/* We will need this should we ever want gai_strerror() */
char *
gai_strerror(int ecode)
{
if (ecode < 0 || ecode > EAI_MAX)
ecode = EAI_MAX;
return ai_errlist[ecode];
}
#endif
void
rb_freeaddrinfo(struct rb_addrinfo *ai)
{
struct rb_addrinfo *next;
do {
next = ai->ai_next;
if (ai->ai_canonname)
rb_free(ai->ai_canonname);
/* no need to free(ai->ai_addr) */
rb_free(ai);
ai = next;
} while (ai);
}
static bool
str_isnumber(const char *p)
{
char *ep;
if (*p == '\0')
return false;
ep = NULL;
errno = 0;
(void)strtoul(p, &ep, 10);
if (errno == 0 && ep && *ep == '\0')
return true;
else
return false;
}
int
rb_getaddrinfo(const char *hostname, const char *servname,
const struct rb_addrinfo *hints, struct rb_addrinfo **res)
{
struct rb_addrinfo sentinel;
struct rb_addrinfo *cur;
int error = 0;
struct rb_addrinfo ai;
struct rb_addrinfo ai0;
struct rb_addrinfo *pai;
const struct explore *ex;
memset(&sentinel, 0, sizeof(sentinel));
cur = &sentinel;
pai = &ai;
pai->ai_flags = 0;
pai->ai_family = PF_UNSPEC;
pai->ai_socktype = ANY;
pai->ai_protocol = ANY;
pai->ai_addrlen = 0;
pai->ai_canonname = NULL;
pai->ai_addr = NULL;
pai->ai_next = NULL;
if (hostname == NULL && servname == NULL)
return EAI_NONAME;
if (hints) {
/* error check for hints */
if (hints->ai_addrlen || hints->ai_canonname ||
hints->ai_addr || hints->ai_next)
ERR(EAI_BADHINTS); /* xxx */
if (hints->ai_flags & ~AI_MASK)
ERR(EAI_BADFLAGS);
switch (hints->ai_family) {
case PF_UNSPEC:
case PF_INET:
#ifdef IPV6
case PF_INET6:
#endif
break;
default:
ERR(EAI_FAMILY);
}
memcpy(pai, hints, sizeof(*pai));
/*
* if both socktype/protocol are specified, check if they
* are meaningful combination.
*/
if (pai->ai_socktype != ANY && pai->ai_protocol != ANY) {
for (ex = explore; ex->e_af >= 0; ex++) {
if (pai->ai_family != ex->e_af)
continue;
if (ex->e_socktype == ANY)
continue;
if (ex->e_protocol == ANY)
continue;
if (pai->ai_socktype == ex->e_socktype &&
pai->ai_protocol != ex->e_protocol) {
ERR(EAI_BADHINTS);
}
}
}
}
/*
* check for special cases. (1) numeric servname is disallowed if
* socktype/protocol are left unspecified. (2) servname is disallowed
* for raw and other inet{,6} sockets.
*/
if (MATCH_FAMILY(pai->ai_family, PF_INET, 1)
#ifdef IPV6
|| MATCH_FAMILY(pai->ai_family, PF_INET6, 1)
#endif
) {
ai0 = *pai; /* backup *pai */
if (pai->ai_family == PF_UNSPEC) {
#ifdef IPV6
pai->ai_family = PF_INET6;
#else
pai->ai_family = PF_INET;
#endif
}
error = get_portmatch(pai, servname);
if (error)
ERR(error);
*pai = ai0;
}
ai0 = *pai;
/* NULL hostname, or numeric hostname */
for (ex = explore; ex->e_af >= 0; ex++) {
*pai = ai0;
/* PF_UNSPEC entries are prepared for DNS queries only */
if (ex->e_af == PF_UNSPEC)
continue;
if (!MATCH_FAMILY(pai->ai_family, ex->e_af, WILD_AF(ex)))
continue;
if (!MATCH(pai->ai_socktype, ex->e_socktype, WILD_SOCKTYPE(ex)))
continue;
if (!MATCH(pai->ai_protocol, ex->e_protocol, WILD_PROTOCOL(ex)))
continue;
if (pai->ai_family == PF_UNSPEC)
pai->ai_family = ex->e_af;
if (pai->ai_socktype == ANY && ex->e_socktype != ANY)
pai->ai_socktype = ex->e_socktype;
if (pai->ai_protocol == ANY && ex->e_protocol != ANY)
pai->ai_protocol = ex->e_protocol;
if (hostname == NULL)
error = explore_null(pai, servname, &cur->ai_next);
else
error = explore_numeric(pai, hostname, servname, &cur->ai_next);
if (error)
goto free;
while (cur && cur->ai_next)
cur = cur->ai_next;
}
/*
* XXX
* If numreic representation of AF1 can be interpreted as FQDN
* representation of AF2, we need to think again about the code below.
*/
if (sentinel.ai_next)
goto good;
if (pai->ai_flags & AI_NUMERICHOST)
ERR(EAI_NONAME);
if (hostname == NULL)
ERR(EAI_NODATA);
/* XXX */
if (sentinel.ai_next)
error = 0;
if (error)
goto free;
if (error == 0) {
if (sentinel.ai_next) {
good:
*res = sentinel.ai_next;
return SUCCESS;
} else
error = EAI_FAIL;
}
free:
bad:
if (sentinel.ai_next)
rb_freeaddrinfo(sentinel.ai_next);
*res = NULL;
return error;
}
/*
* hostname == NULL.
* passive socket -> anyaddr (0.0.0.0 or ::)
* non-passive socket -> localhost (127.0.0.1 or ::1)
*/
static int
explore_null(const struct rb_addrinfo *pai, const char *servname, struct rb_addrinfo **res)
{
int s;
const struct afd *afd;
struct rb_addrinfo *cur;
struct rb_addrinfo sentinel;
int error;
*res = NULL;
sentinel.ai_next = NULL;
cur = &sentinel;
/*
* filter out AFs that are not supported by the kernel
* XXX errno?
*/
s = socket(pai->ai_family, SOCK_DGRAM, 0);
if (s < 0) {
#ifdef _WIN32
errno = WSAGetLastError();
#endif
if (errno != EMFILE)
return 0;
} else
#ifdef _WIN32
closesocket(s);
#else
close(s);
#endif
/*
* if the servname does not match socktype/protocol, ignore it.
*/
if (get_portmatch(pai, servname) != 0)
return 0;
afd = find_afd(pai->ai_family);
if (afd == NULL)
return 0;
if (pai->ai_flags & AI_PASSIVE) {
GET_AI(cur->ai_next, afd, afd->a_addrany);
GET_PORT(cur->ai_next, servname);
} else {
GET_AI(cur->ai_next, afd, afd->a_loopback);
GET_PORT(cur->ai_next, servname);
}
cur = cur->ai_next;
*res = sentinel.ai_next;
return 0;
free:
if (sentinel.ai_next)
rb_freeaddrinfo(sentinel.ai_next);
return error;
}
/*
* numeric hostname
*/
static int
explore_numeric(const struct rb_addrinfo *pai, const char *hostname,
const char *servname, struct rb_addrinfo **res)
{
const struct afd *afd;
struct rb_addrinfo *cur;
struct rb_addrinfo sentinel;
int error;
char pton[PTON_MAX];
*res = NULL;
sentinel.ai_next = NULL;
cur = &sentinel;
/*
* if the servname does not match socktype/protocol, ignore it.
*/
if (get_portmatch(pai, servname) != 0)
return 0;
afd = find_afd(pai->ai_family);
if (afd == NULL)
return 0;
switch (afd->a_af) {
#if 0 /*X/Open spec*/
case AF_INET:
if (rb_inet_pton
if (inet_aton(hostname, (struct in_addr *)pton) == 1) {
if (pai->ai_family == afd->a_af ||
pai->ai_family == PF_UNSPEC /*?*/) {
GET_AI(cur->ai_next, afd, pton);
GET_PORT(cur->ai_next, servname);
while (cur && cur->ai_next)
cur = cur->ai_next;
} else
ERR(EAI_FAMILY); /*xxx*/
}
break;
#endif
default:
if (rb_inet_pton(afd->a_af, hostname, pton) == 1) {
if (pai->ai_family == afd->a_af ||
pai->ai_family == PF_UNSPEC /*?*/) {
GET_AI(cur->ai_next, afd, pton);
GET_PORT(cur->ai_next, servname);
while (cur && cur->ai_next)
cur = cur->ai_next;
} else
ERR(EAI_FAMILY); /* XXX */
}
break;
}
*res = sentinel.ai_next;
return 0;
free:
bad:
if (sentinel.ai_next)
rb_freeaddrinfo(sentinel.ai_next);
return error;
}
static struct rb_addrinfo *
get_ai(const struct rb_addrinfo *pai, const struct afd *afd, const char *addr)
{
char *p;
struct rb_addrinfo *ai;
ai = (struct rb_addrinfo *)rb_malloc(sizeof(struct rb_addrinfo)
+ (afd->a_socklen));
if (ai == NULL)
return NULL;
memcpy(ai, pai, sizeof(struct rb_addrinfo));
ai->ai_addr = (struct sockaddr *)(void *)(ai + 1);
memset(ai->ai_addr, 0, (size_t)afd->a_socklen);
ai->ai_addrlen = afd->a_socklen;
ai->ai_addr->sa_family = ai->ai_family = afd->a_af;
p = (char *)(void *)(ai->ai_addr);
memcpy(p + afd->a_off, addr, (size_t)afd->a_addrlen);
return ai;
}
static int
get_portmatch(const struct rb_addrinfo *ai, const char *servname)
{
struct rb_addrinfo xai;
memcpy(&xai, ai, sizeof(struct rb_addrinfo));
return(get_port(&xai, servname, 1));
}
static int
get_port(struct rb_addrinfo *ai, const char *servname, int matchonly)
{
const char *proto;
struct servent *sp;
int port;
int allownumeric;
if (servname == NULL)
return 0;
switch (ai->ai_family) {
case AF_INET:
#ifdef AF_INET6
case AF_INET6:
#endif
break;
default:
return 0;
}
switch (ai->ai_socktype) {
case SOCK_RAW:
return EAI_SERVICE;
case SOCK_DGRAM:
case SOCK_STREAM:
allownumeric = 1;
break;
case ANY:
allownumeric = 0;
break;
default:
return EAI_SOCKTYPE;
}
if (str_isnumber(servname)) {
if (!allownumeric)
return EAI_SERVICE;
port = atoi(servname);
if (port < 0 || port > 65535)
return EAI_SERVICE;
port = htons(port);
} else {
switch (ai->ai_socktype) {
case SOCK_DGRAM:
proto = "udp";
break;
case SOCK_STREAM:
proto = "tcp";
break;
default:
proto = NULL;
break;
}
if ((sp = getservbyname(servname, proto)) == NULL)
return EAI_SERVICE;
port = sp->s_port;
}
if (!matchonly) {
switch (ai->ai_family) {
case AF_INET:
((struct sockaddr_in *)(void *)
ai->ai_addr)->sin_port = port;
break;
#ifdef IPV6
case AF_INET6:
((struct sockaddr_in6 *)(void *)
ai->ai_addr)->sin6_port = port;
break;
#endif
}
}
return 0;
}
static const struct afd *
find_afd(int af)
{
const struct afd *afd;
if (af == PF_UNSPEC)
return(NULL);
for (afd = afdl; afd->a_af; afd++)
{
if (afd->a_af == af)
return(afd);
}
return(NULL);
}
#endif

123
authd/getaddrinfo.h Normal file
View file

@ -0,0 +1,123 @@
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* All rights reserved.
*
* 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. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``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 PROJECT OR CONTRIBUTORS 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.
*
*/
struct rb_addrinfo {
int ai_flags;
int ai_family;
int ai_socktype;
int ai_protocol;
size_t ai_addrlen;
char *ai_canonname;
struct sockaddr *ai_addr;
struct rb_addrinfo *ai_next;
};
#ifndef AI_PASSIVE
#define AI_PASSIVE 0x00000001 /* get address to use bind() */
#endif /* AI_PASSIVE */
#ifndef AI_NUMERICHOST
#define AI_NUMERICHOST 0x00000004 /* prevent name resolution */
#endif /* AI_NUMERICHOST */
#ifndef EAI_FAIL
#define EAI_FAIL 4 /* non-recoverable failure in name resolution */
#endif /* EAI_FAIL */
#ifndef EAI_FAMILY
#define EAI_FAMILY 5 /* ai_family not supported */
#endif /* EAI_FAMILY */
#ifndef EAI_MEMORY
#define EAI_MEMORY 6 /* memory allocation failure */
#endif /* EAI_MEMORY */
#ifndef EAI_NONAME
#define EAI_NONAME 8 /* hostname nor servname provided, or not known */
#endif /* EAI_NONAME */
#ifndef EAI_SYSTEM
#define EAI_SYSTEM 11 /* system error returned in errno */
#endif /* EAI_SYSTEM */
#ifndef NI_NUMERICHOST
#define NI_NUMERICHOST 0x00000002
#endif /* NI_NUMERICHOST */
#ifndef NI_NAMEREQD
#define NI_NAMEREQD 0x00000004
#endif /* NI_NAMEREQD */
#ifndef NI_NUMERICSERV
#define NI_NUMERICSERV 0x00000008
#endif /* NI_NUMERICSERV */
#ifndef NI_DGRAM
#define NI_DGRAM 0x00000010
#endif /* NI_DGRAM */
int rb_getaddrinfo(const char *hostname, const char *servname,
const struct rb_addrinfo *hints, struct rb_addrinfo **res);
void rb_freeaddrinfo(struct rb_addrinfo *ai);
#define SUCCESS 0
#define ANY 0
#undef EAI_ADDRFAMILY
#undef EAI_AGAIN
#undef EAI_BADFLAGS
#undef EAI_FAIL
#undef EAI_FAMILY
#undef EAI_MEMORY
#undef EAI_NODATA
#undef EAI_NONAME
#undef EAI_SERVICE
#undef EAI_SOCKTYPE
#undef EAI_SYSTEM
#undef EAI_BADHINTS
#undef EAI_PROTOCOL
#undef EAI_MAX
#undef AI_MASK
#define EAI_ADDRFAMILY 1 /* address family for hostname not supported */
#define EAI_AGAIN 2 /* temporary failure in name resolution */
#define EAI_BADFLAGS 3 /* invalid value for ai_flags */
#define EAI_FAIL 4 /* non-recoverable failure in name resolution */
#define EAI_FAMILY 5 /* ai_family not supported */
#define EAI_MEMORY 6 /* memory allocation failure */
#define EAI_NODATA 7 /* no address associated with hostname */
#define EAI_NONAME 8 /* hostname nor servname provided, or not known */
#define EAI_SERVICE 9 /* servname not supported for ai_socktype */
#define EAI_SOCKTYPE 10 /* ai_socktype not supported */
#define EAI_SYSTEM 11 /* system error returned in errno */
#define EAI_BADHINTS 12
#define EAI_PROTOCOL 13
#define EAI_MAX 14
#define AI_MASK (AI_PASSIVE | AI_NUMERICHOST)

240
authd/getnameinfo.c Normal file
View file

@ -0,0 +1,240 @@
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* All rights reserved.
*
* 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. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``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 PROJECT OR CONTRIBUTORS 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.
*/
/*
* Issues to be discussed:
* - Thread safe-ness must be checked
* - RFC2553 says that we should raise error on short buffer. X/Open says
* we need to truncate the result. We obey RFC2553 (and X/Open should be
* modified). ipngwg rough consensus seems to follow RFC2553.
* - What is "local" in NI_FQDN?
* - NI_NAMEREQD and NI_NUMERICHOST conflict with each other.
* - (KAME extension) always attach textual scopeid (fe80::1%lo0), if
* sin6_scope_id is filled - standardization status?
* XXX breaks backward compat for code that expects no scopeid.
* beware on merge.
*/
#ifdef _WIN32
#include <rb_lib.h>
#include "getaddrinfo.h"
#include "getnameinfo.h"
static const struct afd {
int a_af;
int a_addrlen;
rb_socklen_t a_socklen;
int a_off;
} afdl [] = {
#ifdef IPV6
{PF_INET6, sizeof(struct in6_addr), sizeof(struct sockaddr_in6),
offsetof(struct sockaddr_in6, sin6_addr)},
#endif
{PF_INET, sizeof(struct in_addr), sizeof(struct sockaddr_in),
offsetof(struct sockaddr_in, sin_addr)},
{0, 0, 0, 0},
};
struct sockinet
{
unsigned char si_len;
unsigned char si_family;
unsigned short si_port;
};
#ifdef IPV6
static int ip6_parsenumeric(const struct sockaddr *, const char *, char *,
size_t, int);
#endif
int
rb_getnameinfo(const struct sockaddr *sa, rb_socklen_t salen, char *host,
size_t hostlen, char *serv, size_t servlen, int flags)
{
const struct afd *afd;
struct servent *sp;
unsigned short port;
int family, i;
const char *addr;
uint32_t v4a;
char numserv[512];
char numaddr[512];
if (sa == NULL)
return EAI_FAIL;
/* if (sa->sa_len != salen)
return EAI_FAIL;
*/
family = sa->sa_family;
for (i = 0; afdl[i].a_af; i++)
if (afdl[i].a_af == family) {
afd = &afdl[i];
goto found;
}
return EAI_FAMILY;
found:
if (salen != afd->a_socklen)
return EAI_FAIL;
/* network byte order */
port = ((const struct sockinet *)sa)->si_port;
addr = (const char *)sa + afd->a_off;
if (serv == NULL || servlen == 0) {
/*
* do nothing in this case.
* in case you are wondering if "&&" is more correct than
* "||" here: rfc2553bis-03 says that serv == NULL OR
* servlen == 0 means that the caller does not want the result.
*/
} else {
if (flags & NI_NUMERICSERV)
sp = NULL;
else {
sp = getservbyport(port,
(flags & NI_DGRAM) ? "udp" : "tcp");
}
if (sp) {
if (strlen(sp->s_name) + 1 > servlen)
return EAI_MEMORY;
rb_strlcpy(serv, sp->s_name, servlen);
} else {
snprintf(numserv, sizeof(numserv), "%u", ntohs(port));
if (strlen(numserv) + 1 > servlen)
return EAI_MEMORY;
rb_strlcpy(serv, numserv, servlen);
}
}
switch (sa->sa_family) {
case AF_INET:
v4a = (uint32_t)
ntohl(((const struct sockaddr_in *)sa)->sin_addr.s_addr);
if (IN_MULTICAST(v4a) || IN_EXPERIMENTAL(v4a))
flags |= NI_NUMERICHOST;
v4a >>= IN_CLASSA_NSHIFT;
if (v4a == 0)
flags |= NI_NUMERICHOST;
break;
#ifdef IPV6
case AF_INET6:
{
const struct sockaddr_in6 *sin6;
sin6 = (const struct sockaddr_in6 *)sa;
switch (sin6->sin6_addr.s6_addr[0]) {
case 0x00:
if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr))
;
else if (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr))
;
else
flags |= NI_NUMERICHOST;
break;
default:
if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
flags |= NI_NUMERICHOST;
}
else if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr))
flags |= NI_NUMERICHOST;
break;
}
}
break;
#endif
}
if (host == NULL || hostlen == 0) {
/*
* do nothing in this case.
* in case you are wondering if "&&" is more correct than
* "||" here: rfc2553bis-03 says that host == NULL or
* hostlen == 0 means that the caller does not want the result.
*/
} else if (flags & NI_NUMERICHOST) {
size_t numaddrlen;
/* NUMERICHOST and NAMEREQD conflicts with each other */
if (flags & NI_NAMEREQD)
return EAI_NONAME;
switch(afd->a_af) {
#ifdef IPV6
case AF_INET6:
{
int error;
if ((error = ip6_parsenumeric(sa, addr, host,
hostlen, flags)) != 0)
return(error);
break;
}
#endif
default:
if (rb_inet_ntop(afd->a_af, addr, numaddr, sizeof(numaddr))
== NULL)
return EAI_SYSTEM;
numaddrlen = strlen(numaddr);
if (numaddrlen + 1 > hostlen) /* don't forget terminator */
return EAI_MEMORY;
rb_strlcpy(host, numaddr, hostlen);
break;
}
}
return(0);
}
#ifdef IPV6
static int
ip6_parsenumeric(const struct sockaddr *sa, const char *addr,
char *host, size_t hostlen, int flags)
{
size_t numaddrlen;
char numaddr[512];
if (rb_inet_ntop(AF_INET6, addr, numaddr, sizeof(numaddr)) == NULL)
return(EAI_SYSTEM);
numaddrlen = strlen(numaddr);
if (numaddrlen + 1 > hostlen) /* don't forget terminator */
return(EAI_MEMORY);
if (*numaddr == ':')
{
*host = '0';
rb_strlcpy(host+1, numaddr, hostlen-1);
}
else
rb_strlcpy(host, numaddr, hostlen);
return(0);
}
#endif
#endif

40
authd/getnameinfo.h Normal file
View file

@ -0,0 +1,40 @@
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* All rights reserved.
*
* 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. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``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 PROJECT OR CONTRIBUTORS 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.
*
*/
int rb_getnameinfo(const struct sockaddr *sa, rb_socklen_t salen, char *host,
size_t hostlen, char *serv, size_t servlen, int flags);
#ifndef IN_MULTICAST
#define IN_MULTICAST(a) ((((long int) (a)) & 0xf0000000) == 0xe0000000)
#endif
#ifndef IN_EXPERIMENTAL
#define IN_EXPERIMENTAL(a) ((((long int) (a)) & 0xe0000000) == 0xe0000000)
#endif

View file

@ -18,8 +18,8 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __SOLANUM_AUTHD_NOTICE_H__
#define __SOLANUM_AUTHD_NOTICE_H__
#ifndef __CHARYBDIS_AUTHD_NOTICE_H__
#define __CHARYBDIS_AUTHD_NOTICE_H__
typedef enum
{
@ -35,4 +35,4 @@ 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__ */
#endif /* __CHARYBDIS_AUTHD_NOTICE_H__ */

View file

@ -18,8 +18,8 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __SOLANUM_AUTHD_PROVIDER_H__
#define __SOLANUM_AUTHD_PROVIDER_H__
#ifndef __CHARYBDIS_AUTHD_PROVIDER_H__
#define __CHARYBDIS_AUTHD_PROVIDER_H__
#include "stdinc.h"
#include "authd.h"
@ -243,4 +243,4 @@ get_provider_timeout(struct auth_client *auth, uint32_t id)
return auth->data[id].timeout;
}
#endif /* __SOLANUM_AUTHD_PROVIDER_H__ */
#endif /* __CHARYBDIS_AUTHD_PROVIDER_H__ */

View file

@ -1,5 +1,5 @@
/*
* Solanum: a slightly advanced ircd
* charybdis: A slightly useful ircd.
* dnsbl.c: Manages DNSBL entries and lookups
*
* Copyright (C) 2006-2011 charybdis development team

View file

@ -159,12 +159,6 @@ read_ident_reply(rb_fde_t *F, void *data)
message = REPORT_INVALID;
}
if (*auth->username == '\0')
{
auth->username[0] = '*';
auth->username[1] = '\0';
}
if(s == NULL)
client_fail(auth, message);
else
@ -318,7 +312,7 @@ ident_start(struct auth_client *auth)
if((query->F = rb_socket(family, SOCK_STREAM, auth->protocol, "ident")) == NULL)
{
warn_opers(L_WARN, "Could not create ident socket: %s", strerror(errno));
warn_opers(L_DEBUG, "Could not create ident socket: %s", strerror(errno));
client_fail(auth, REPORT_FAIL);
return true; /* Not a fatal error */
}

View file

@ -26,8 +26,6 @@
#include "notice.h"
#include "provider.h"
#include <netinet/tcp.h> // TCP_NODELAY
#define SELF_PID (opm_provider.id)
#define OPM_READSIZE 128

View file

@ -514,7 +514,7 @@ static void do_query_number(struct DNSQuery *query, const struct rb_sockaddr_sto
request->name = (char *)rb_malloc(IRCD_RES_HOSTLEN + 1);
}
build_rdns(request->queryname, sizeof request->queryname, addr, NULL);
build_rdns(request->queryname, IRCD_RES_HOSTLEN + 1, addr, NULL);
request->type = T_PTR;
query_name(request);

View file

@ -3,11 +3,11 @@
*
*/
#ifndef _SOLANUM_RES_H
#define _SOLANUM_RES_H
#ifndef _CHARYBDIS_RES_H
#define _CHARYBDIS_RES_H
/* Maximum number of nameservers in /etc/resolv.conf we care about
* In hybrid, this was 2 -- but in Solanum, we want to track
* In hybrid, this was 2 -- but in Charybdis, we want to track
* a few more than that ;) --nenolod
*/
#define IRCD_MAXNS 10

View file

@ -77,7 +77,24 @@
*/
#include <rb_lib.h>
#ifndef _WIN32
#include <netdb.h>
typedef struct addrinfo rb_addrinfo;
#else
#include "getaddrinfo.h"
#include "getnameinfo.h"
#define getaddrinfo rb_getaddrinfo
#define getnameinfo rb_getnameinfo
#define freeaddrinfo rb_freeaddrinfo
extern const char * get_windows_nameservers(void);
typedef struct rb_addrinfo rb_addrinfo;
#endif
#include "stdinc.h"
#include "ircd_defs.h"
#include "ircd.h"
@ -113,10 +130,15 @@ static const char digitvalue[256] = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*256*/
};
static const char digits[] = "0123456789";
#ifndef _WIN32
static int parse_resvconf(void);
#else
static void parse_windows_resolvers(void);
#endif
static void add_nameserver(const char *);
static const char digits[] = "0123456789";
static int labellen(const unsigned char *lp);
static int special(int ch);
static int printable(int ch);
@ -140,12 +162,31 @@ int
irc_res_init(void)
{
irc_nscount = 0;
#ifndef _WIN32
parse_resvconf();
#else
parse_windows_resolvers();
#endif
if (irc_nscount == 0)
add_nameserver("127.0.0.1");
return 0;
}
#ifdef _WIN32
static void
parse_windows_resolvers(void)
{
const char *ns = get_windows_nameservers();
char *server;
char *p;
char *buf = rb_strdup(ns);
for(server = rb_strtok_r(buf, " ", &p); server != NULL;server = rb_strtok_r(NULL, " ", &p))
{
add_nameserver(server);
}
rb_free(buf);
}
#else
/* parse_resvconf()
*
* inputs - NONE
@ -161,6 +202,9 @@ parse_resvconf(void)
char input[DNS_MAXLINE];
FILE *file;
/* XXX "/etc/resolv.conf" should be from a define in setup.h perhaps
* for cygwin support etc. this hardcodes it to unix for now -db
*/
if ((file = fopen("/etc/resolv.conf", "r")) == NULL)
return -1;
@ -208,6 +252,7 @@ parse_resvconf(void)
fclose(file);
return 0;
}
#endif
/* add_nameserver()
*
@ -219,7 +264,7 @@ parse_resvconf(void)
static void
add_nameserver(const char *arg)
{
struct addrinfo hints, *res;
rb_addrinfo hints, *res;
/* Done max number of nameservers? */
if (irc_nscount >= IRCD_MAXNS)

View file

@ -3,8 +3,8 @@
*
*/
#ifndef _SOLANUM_RESLIB_H
#define _SOLANUM_RESLIB_H
#ifndef _CHARYBDIS_RESLIB_H
#define _CHARYBDIS_RESLIB_H
/* Longest hostname we're willing to work with.
* Due to DNSBLs this is more than HOSTLEN.

279
authd/reslist.c Normal file
View file

@ -0,0 +1,279 @@
/*
* reslist.c - get nameservers from windows *
*
* ircd-ratbox related changes are as follows
*
* Copyright (C) 2008 Aaron Sethman <androsyn@ratbox.org>
* Copyright (C) 2008-2012 ircd-ratbox development team
*
* pretty much all of this was yanked from c-ares ares_init.c here is the original
* header from there --
*
* Id: ares_init.c,v 1.72 2008-05-15 00:00:19 yangtse Exp $
* Copyright 1998 by the Massachusetts Institute of Technology.
* Copyright (C) 2007-2008 by Daniel Stenberg
*
* Permission to use, copy, modify, and distribute this
* software and its documentation for any purpose and without
* fee is hereby granted, provided that the above copyright
* notice appear in all copies and that both that copyright
* notice and this permission notice appear in supporting
* documentation, and that the name of M.I.T. not be used in
* advertising or publicity pertaining to distribution of the
* software without specific, written prior permission.
* M.I.T. makes no representations about the suitability of
* this software for any purpose. It is provided "as is"
* without express or implied warranty.
*
*
*/
#ifdef _WIN32
#include <rb_lib.h>
#include <windows.h>
#include <iphlpapi.h>
const char *get_windows_nameservers(void);
#ifndef INADDR_NONE
#define INADDR_NONE ((unsigned int) 0xffffffff)
#endif /* INADDR_NONE */
#define IS_NT() ((int)GetVersion() > 0)
#define WIN_NS_9X "System\\CurrentControlSet\\Services\\VxD\\MSTCP"
#define WIN_NS_NT_KEY "System\\CurrentControlSet\\Services\\Tcpip\\Parameters"
#define NAMESERVER "NameServer"
#define DHCPNAMESERVER "DhcpNameServer"
#define DATABASEPATH "DatabasePath"
#define WIN_PATH_HOSTS "\\hosts"
static int
get_iphlpapi_dns_info(char *ret_buf, size_t ret_size)
{
FIXED_INFO *fi = alloca(sizeof(*fi));
DWORD size = sizeof(*fi);
typedef DWORD(WINAPI * get_net_param_func) (FIXED_INFO *, DWORD *);
get_net_param_func xxGetNetworkParams; /* available only on Win-98/2000+ */
HMODULE handle;
IP_ADDR_STRING *ipAddr;
int i, count = 0;
int debug = 0;
size_t ip_size = sizeof("255.255.255.255,") - 1;
size_t left = ret_size;
char *ret = ret_buf;
HRESULT res;
if(!fi)
return (0);
handle = LoadLibrary("iphlpapi.dll");
if(!handle)
return (0);
xxGetNetworkParams = (get_net_param_func) GetProcAddress(handle, "GetNetworkParams");
if(!xxGetNetworkParams)
goto quit;
res = (*xxGetNetworkParams) (fi, &size);
if((res != ERROR_BUFFER_OVERFLOW) && (res != ERROR_SUCCESS))
goto quit;
fi = alloca(size);
if(!fi || (*xxGetNetworkParams) (fi, &size) != ERROR_SUCCESS)
goto quit;
if(debug)
{
printf("Host Name: %s\n", fi->HostName);
printf("Domain Name: %s\n", fi->DomainName);
printf("DNS Servers:\n" " %s (primary)\n", fi->DnsServerList.IpAddress.String);
}
if(strlen(fi->DnsServerList.IpAddress.String) > 0 &&
inet_addr(fi->DnsServerList.IpAddress.String) != INADDR_NONE && left > ip_size)
{
ret += sprintf(ret, "%s,", fi->DnsServerList.IpAddress.String);
left -= ret - ret_buf;
count++;
}
for(i = 0, ipAddr = fi->DnsServerList.Next; ipAddr && left > ip_size;
ipAddr = ipAddr->Next, i++)
{
if(inet_addr(ipAddr->IpAddress.String) != INADDR_NONE)
{
ret += sprintf(ret, "%s,", ipAddr->IpAddress.String);
left -= ret - ret_buf;
count++;
}
if(debug)
printf(" %s (secondary %d)\n", ipAddr->IpAddress.String, i + 1);
}
quit:
if(handle)
FreeLibrary(handle);
if(debug && left <= ip_size)
printf("Too many nameservers. Truncating to %d addressess", count);
if(ret > ret_buf)
ret[-1] = '\0';
return (count);
}
/*
* Warning: returns a dynamically allocated buffer, the user MUST
* use free() / rb_free() if the function returns 1
*/
static int
get_res_nt(HKEY hKey, const char *subkey, char **obuf)
{
/* Test for the size we need */
DWORD size = 0;
int result;
result = RegQueryValueEx(hKey, subkey, 0, NULL, NULL, &size);
if((result != ERROR_SUCCESS && result != ERROR_MORE_DATA) || !size)
return 0;
*obuf = rb_malloc(size + 1);
if(!*obuf)
return 0;
if(RegQueryValueEx(hKey, subkey, 0, NULL, (LPBYTE) * obuf, &size) != ERROR_SUCCESS)
{
rb_free(*obuf);
return 0;
}
if(size == 1)
{
rb_free(*obuf);
return 0;
}
return 1;
}
static int
get_res_interfaces_nt(HKEY hKey, const char *subkey, char **obuf)
{
char enumbuf[39]; /* GUIDs are 38 chars + 1 for NULL */
DWORD enum_size = 39;
int idx = 0;
HKEY hVal;
while(RegEnumKeyEx(hKey, idx++, enumbuf, &enum_size, 0,
NULL, NULL, NULL) != ERROR_NO_MORE_ITEMS)
{
int rc;
enum_size = 39;
if(RegOpenKeyEx(hKey, enumbuf, 0, KEY_QUERY_VALUE, &hVal) != ERROR_SUCCESS)
continue;
rc = get_res_nt(hVal, subkey, obuf);
RegCloseKey(hVal);
if(rc)
return 1;
}
return 0;
}
const char *
get_windows_nameservers(void)
{
/*
NameServer info via IPHLPAPI (IP helper API):
GetNetworkParams() should be the trusted source for this.
Available in Win-98/2000 and later. If that fail, fall-back to
registry information.
NameServer Registry:
On Windows 9X, the DNS server can be found in:
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\VxD\MSTCP\NameServer
On Windows NT/2000/XP/2003:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\NameServer
or
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\DhcpNameServer
or
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\{AdapterID}\
NameServer
or
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\{AdapterID}\
DhcpNameServer
*/
static char namelist[512];
HKEY mykey;
HKEY subkey;
DWORD data_type;
DWORD bytes;
DWORD result;
char *line = NULL;
memset(&namelist, 0, sizeof(namelist));
if(get_iphlpapi_dns_info(namelist, sizeof(namelist)) > 0)
{
return namelist;
}
if(IS_NT())
{
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0,
KEY_READ, &mykey) == ERROR_SUCCESS)
{
RegOpenKeyEx(mykey, "Interfaces", 0,
KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS, &subkey);
if(get_res_nt(mykey, NAMESERVER, &line))
{
rb_strlcpy(namelist, line, sizeof(namelist));
return namelist;
}
else if(get_res_nt(mykey, DHCPNAMESERVER, &line))
{
rb_strlcpy(namelist, line, sizeof(namelist));
rb_free(line);
}
/* Try the interfaces */
else if(get_res_interfaces_nt(subkey, NAMESERVER, &line))
{
rb_strlcpy(namelist, line, sizeof(namelist));
rb_free(line);
}
else if(get_res_interfaces_nt(subkey, DHCPNAMESERVER, &line))
{
rb_strlcpy(namelist, line, sizeof(namelist));
rb_free(line);
}
RegCloseKey(subkey);
RegCloseKey(mykey);
}
}
else
{
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_NS_9X, 0,
KEY_READ, &mykey) == ERROR_SUCCESS)
{
if((result = RegQueryValueEx(mykey, NAMESERVER, NULL, &data_type,
NULL, &bytes)) == ERROR_SUCCESS ||
result == ERROR_MORE_DATA)
{
if(bytes)
{
line = (char *)rb_malloc(bytes + 1);
if(RegQueryValueEx(mykey, NAMESERVER, NULL, &data_type,
(unsigned char *)line, &bytes) ==
ERROR_SUCCESS)
{
rb_strlcpy(namelist, line, sizeof(namelist));
}
free(line);
}
}
}
RegCloseKey(mykey);
}
if(strlen(namelist) > 0)
return namelist;
return NULL;
}
#endif

View file

@ -1,11 +1,16 @@
pkglibexec_PROGRAMS = bandb
bin_PROGRAMS = solanum-bantool
bin_PROGRAMS = bantool
AM_CFLAGS=$(WARNFLAGS)
AM_CPPFLAGS = -I../include -I../librb/include @SQLITE_INCLUDES@
AM_CPPFLAGS += -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION
bandb_SOURCES = bandb.c rsdb_sqlite3.c rsdb_snprintf.c
bandb_LDADD = ../librb/src/librb.la @SQLITE_LD@
EXTRA_bandb_SOURCES = sqlite3.c
bandb_LDADD = ../librb/src/librb.la @SQLITE_LD@ @SQLITE_OBJ@
bandb_DEPENDENCIES = @SQLITE_OBJ@
solanum_bantool_SOURCES = bantool.c rsdb_sqlite3.c rsdb_snprintf.c
solanum_bantool_LDADD = ../librb/src/librb.la @SQLITE_LD@
bantool_SOURCES = bantool.c rsdb_sqlite3.c rsdb_snprintf.c
EXTRA_bantool_SOURCES = sqlite3.c
bantool_LDADD = ../librb/src/librb.la @SQLITE_LD@ @SQLITE_OBJ@
bantool_DEPENDENCIES = @SQLITE_OBJ@

View file

@ -247,15 +247,18 @@ error_cb(rb_helper *helper)
exit(1);
}
#ifndef WINDOWS
static void
dummy_handler(int sig)
{
return;
}
#endif
static void
setup_signals(void)
{
#ifndef _WIN32
struct sigaction act;
act.sa_flags = 0;
@ -278,6 +281,7 @@ setup_signals(void)
act.sa_handler = dummy_handler;
sigaction(SIGALRM, &act, 0);
#endif
}
@ -302,9 +306,9 @@ main(int argc, char *argv[])
if(bandb_helper == NULL)
{
fprintf(stderr,
"This is the solanum bandb for internal ircd use.\n");
"This is the charybdis bandb for internal ircd use.\n");
fprintf(stderr,
"You aren't supposed to run me directly (did you want solanum-bantool?). Exiting.\n");
"You aren't supposed to run me directly (did you want bantool?). Exiting.\n");
exit(1);
}
rsdb_init(db_error_cb);

View file

@ -196,7 +196,7 @@ main(int argc, char *argv[])
rb_strlcpy(etc, ETCPATH, sizeof(ETCPATH));
fprintf(stdout,
"* solanum bantool v.%s\n", BT_VERSION);
"* charybdis bantool v.%s\n", BT_VERSION);
if(flag.pretend == false)
{
@ -864,7 +864,7 @@ bt_smalldate(const char *string)
void
print_help(int i_exit)
{
fprintf(stderr, "bantool v.%s - the solanum database tool.\n", BT_VERSION);
fprintf(stderr, "bantool v.%s - the charybdis database tool.\n", BT_VERSION);
fprintf(stderr, "Copyright (C) 2008 Daniel J Reidy <dubkat@gmail.com>\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"

189270
bandb/sqlite3.c Normal file

File diff suppressed because it is too large Load diff

8733
bandb/sqlite3.h Normal file

File diff suppressed because it is too large Load diff

View file

@ -4,7 +4,7 @@ dnl said functions need to be just about as complex as they already are.
AC_PREREQ(2.60)
AC_INIT([solanum], [1.0-dev])
AC_INIT([charybdis], [4.1.3-dev])
AC_LANG(C)
AC_USE_SYSTEM_EXTENSIONS
@ -13,7 +13,7 @@ AC_GNU_SOURCE
AC_PROG_CC_C99
if test x"$ac_cv_prog_cc_c99" = "xno"; then
AC_ERROR([solanum requires a C99 capable compiler])
AC_ERROR([charybdis requires a C99 capable compiler])
fi
AC_PREFIX_DEFAULT($HOME/ircd)
@ -34,6 +34,24 @@ LTDL_INIT
build_ltdl=$with_included_ltdl
AM_CONDITIONAL([BUILD_LTDL], [test x"$build_ltdl" = x"yes"])
case "$host_os" in
*cygwin*)
AC_DEFINE_UNQUOTED(CYGWIN,1,[This is a Cygwin system])
AC_DEFINE_UNQUOTED(WINDOWS,1,[This is a Windows system])
;;
*mingw* | *msys*)
AC_DEFINE_UNQUOTED(MINGW,1,[This is a MinGW system])
AC_DEFINE_UNQUOTED(WINDOWS,1,[This is a Windows system])
AC_CHECK_HEADER(winsock2.h, , [AC_MSG_ERROR([** MinGW and no winsock2.h. I give up.])])
LIBS="$LIBS -lws2_32 -liphlpapi"
is_mingw="yes"
;;
*)
;;
esac
AM_CONDITIONAL([MINGW], [test "$is_mingw" = "yes"])
if test "$ac_cv_c_compiler_gnu" = yes; then
IRC_CFLAGS="$IRC_CFLAGS -O0 -Wall"
fi
@ -124,7 +142,7 @@ dnl Checks for header files.
AC_HEADER_STDC
AC_HEADER_STDBOOL
AC_CHECK_HEADERS([crypt.h sys/param.h sys/syslog.h sys/epoll.h machine/endian.h])
AC_CHECK_HEADERS([crypt.h sys/resource.h sys/param.h errno.h sys/syslog.h stddef.h sys/wait.h wait.h sys/epoll.h sys/uio.h machine/endian.h])
dnl Stuff that the memory manager (imalloc) depends on
dnl ==================================================
@ -143,7 +161,7 @@ AC_CHECK_SIZEOF(long long)
dnl Networking Functions
dnl ====================
AC_SEARCH_LIBS(socket, socket,, [AC_MSG_ERROR([You have no socket()! Aborting.])])
AC_SEARCH_LIBS(socket, [socket ws2_32], , [AC_MSG_ERROR([You have no socket()! Aborting.])])
dnl SunOS/Solaris required libnsl for inet_ntoa()
if test x"$SUN" = xyes; then
@ -165,18 +183,39 @@ AC_SUBST(CRYPT_LIB)
AC_C_BIGENDIAN
dnl Check for stdarg.h - if we can't find it, halt configure
AC_CHECK_HEADER(stdarg.h, , [AC_MSG_ERROR([** stdarg.h could not be found - solanum will not compile without it **])])
AC_CHECK_HEADER(stdarg.h, , [AC_MSG_ERROR([** stdarg.h could not be found - charybdis will not compile without it **])])
AC_CHECK_FUNCS([strlcat strlcpy])
AC_TYPE_INT16_T
AC_TYPE_INT32_T
AC_CHECK_TYPE([sa_family_t], [],
[AC_DEFINE(sa_family_t, [u_int16_t], [If system does not define sa_family_t, define it here.])],
[[#include <sys/types.h>
#include <sys/socket.h>]])
AC_CHECK_TYPES([uintptr_t])
dnl check for various functions...
AC_CHECK_FUNCS([snprintf vsnprintf socketpair mmap gettimeofday strdup strndup ])
AC_FUNC_ALLOCA
dnl Specialized functions checks
dnl ============================
dnl check for nanosleep
AC_CHECK_FUNC(nanosleep,,[AC_CHECK_LIB(rt,nanosleep,
LIBS="${LIBS} -lrt",
[AC_CHECK_LIB(posix4,nanosleep, LIBS="${LIBS} -lposix4"
)])])
if test x$ac_cv_func_nanosleep = xno && test x$ac_cv_lib_posix4_nanosleep = xno && test x$ac_cv_lib_rt_nanosleep = xno
then
AC_MSG_RESULT("nanosleep not found..using select for delay")
else
AC_DEFINE([HAVE_NANOSLEEP], 1, [Define if nanosleep exists])
fi
dnl OpenSSL support
AC_MSG_CHECKING(for OpenSSL)
AC_ARG_ENABLE(openssl,
@ -303,6 +342,26 @@ AS_IF([test "$hyperscan" = no], [
AM_CONDITIONAL([HAVE_HYPERSCAN], [test "$hyperscan" = "yes"])
AC_ARG_WITH(zlib-path,
AC_HELP_STRING([--with-zlib-path=DIR],[Path to libz.so for ziplinks support.]),
[LIBS="$LIBS -L$withval"],)
AC_ARG_ENABLE(zlib,
AC_HELP_STRING([--disable-zlib],[Disable ziplinks support]),
[zlib=$enableval],[zlib=yes])
if test "$zlib" = yes; then
AC_CHECK_HEADER(zlib.h, [
AC_CHECK_LIB(z, zlibVersion,
[
AC_SUBST(ZLIB_LD, -lz)
AC_DEFINE(HAVE_LIBZ, 1, [Define to 1 if zlib (-lz) is available.])
], zlib=no)
], zlib=no)
fi
AC_ARG_WITH(sctp-path,
AC_HELP_STRING([--with-sctp-path=DIR],[Path to libsctp.so for SCTP support.]),
[LIBS="$LIBS -L$withval"],)
@ -314,8 +373,9 @@ AC_HELP_STRING([--disable-sctp],[Disable SCTP support]),
if test "$sctp" = yes; then
AC_CHECK_HEADER(netinet/sctp.h, [
AC_SEARCH_LIBS(sctp_bindx, sctp,
AC_CHECK_LIB(sctp, sctp_bindx,
[
AC_SUBST(LIBSCTP_LD, -lsctp)
AC_DEFINE(HAVE_LIBSCTP, 1, [Define to 1 if libsctp (-lsctp) is available.])
], sctp=no)
], sctp=no)
@ -324,10 +384,24 @@ fi
dnl Check for shared sqlite
dnl ======================
PKG_CHECK_MODULES(SQLITE, [sqlite3], [], AC_ERROR([sqlite3 is required]))
AC_ARG_WITH(shared-sqlite,
AC_HELP_STRING([--with-shared-sqlite],[Use shared sqlite]),
[shared_sqlite=$withval],[shared_sqlite=no])
if test "$shared_sqlite" = yes; then
PKG_CHECK_MODULES(SQLITE, [sqlite3],
[
shared_sqlite=yes
], shared_sqlite=no)
fi
if test "$shared_sqlite" = no; then
SQLITE_OBJ='sqlite3.$(OBJEXT)'
fi
AC_SUBST(SQLITE_LD, "$SQLITE_LIBS")
AC_SUBST(SQLITE_INCLUDES, "$SQLITE_CFLAGS")
AC_SUBST(SQLITE_OBJ)
dnl **********************************************************************
dnl Check for --with-confdir [deprecated, use --sysconfdir instead]
@ -475,7 +549,7 @@ elif test "$assert" = soft; then
AC_DEFINE(SOFT_ASSERT, 1, [Define this to enable soft asserts.])
AC_DEFINE(NDEBUG, 1, [Define this to disable debugging support.])
elif test "$assert" = yes; then
assert="hard"
assert = "hard";
fi
AC_MSG_CHECKING(if you want to do a profile build)
@ -487,7 +561,7 @@ if test "$profile" = yes; then
if test "$ac_cv_c_compiler_gnu" = yes; then
IRC_CFLAGS="$IRC_CFLAGS -pg"
AC_MSG_RESULT([yes, adding -pg])
AC_DEFINE(SOLANUM_PROFILE, 1, [Define this if you are profiling.])
AC_DEFINE(CHARYBDIS_PROFILE, 1, [Define this if you are profiling.])
else
AC_MSG_RESULT([no, profile builds only work with gcc])
fi
@ -572,26 +646,26 @@ AC_HELP_STRING([--enable-warnings],[Enable all sorts of warnings for debugging.]
IRC_CFLAGS="$IRC_CFLAGS -O0"
CFLAGS="$IRC_CFLAGS"
SOLANUM_C_GCC_TRY_FLAGS([-Wall], solanum_cv_c_gcc_w_all)
SOLANUM_C_GCC_TRY_FLAGS([-Wpointer-arith], solanum_cv_c_gcc_w_pointer_arith)
SOLANUM_C_GCC_TRY_FLAGS([-Wimplicit -Wnested-externs], solanum_cv_c_gcc_w_implicit)
SOLANUM_C_GCC_TRY_FLAGS([-Wcast-align], solanum_cv_c_gcc_w_cast_align)
SOLANUM_C_GCC_TRY_FLAGS([-Wcast-qual], solanum_cv_c_gcc_w_cast_qual)
SOLANUM_C_GCC_TRY_FLAGS([-Wwrite-strings], solanum_cv_c_gcc_w_write_strings)
SOLANUM_C_GCC_TRY_FLAGS([-Werror-implicit-function-declaration], solanum_cv_c_gcc_w_error_implicit_function_declaration)
SOLANUM_C_GCC_TRY_FLAGS([-Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations], solanum_cv_c_gcc_prototypes)
SOLANUM_C_GCC_TRY_FLAGS([-Wparentheses], solanum_cv_c_gcc_parentheses)
SOLANUM_C_GCC_TRY_FLAGS([-W -Wno-unused], solanum_cv_c_gcc_w)
SOLANUM_C_GCC_TRY_FLAGS([-Wextra], solanum_cv_c_gcc_w_extra)
SOLANUM_C_GCC_TRY_FLAGS([-Wshadow], solanum_cv_c_gcc_w_shadow)
SOLANUM_C_GCC_TRY_FLAGS([-Wmissing-noreturn], solanum_cv_c_gcc_w_missing_noreturn)
SOLANUM_C_GCC_TRY_FLAGS([-Wundef], solanum_cv_c_gcc_w_undef)
SOLANUM_C_GCC_TRY_FLAGS([-Wpacked], solanum_cv_c_gcc_w_packed)
SOLANUM_C_GCC_TRY_FLAGS([-Wnested-externs], solanum_cv_c_gcc_w_nested_externs)
SOLANUM_C_GCC_TRY_FLAGS([-Wunused-function -Wunused-label -Wunused-value -Wunused-variable], solanum_cv_c_gcc_w_unused)
SOLANUM_C_GCC_TRY_FLAGS([-Wredundant-decls], solanum_cv_c_gcc_w_redundant_decls)
SOLANUM_C_GCC_TRY_FLAGS([-Wfloat-equal], solanum_cv_c_gcc_w_float_equal)
SOLANUM_C_GCC_TRY_FLAGS([-Wformat -Wformat-y2k -Wno-format-security], solanum_cv_c_gcc_w_format)
CHARYBDIS_C_GCC_TRY_FLAGS([-Wall], charybdis_cv_c_gcc_w_all)
CHARYBDIS_C_GCC_TRY_FLAGS([-Wpointer-arith], charybdis_cv_c_gcc_w_pointer_arith)
CHARYBDIS_C_GCC_TRY_FLAGS([-Wimplicit -Wnested-externs], charybdis_cv_c_gcc_w_implicit)
CHARYBDIS_C_GCC_TRY_FLAGS([-Wcast-align], charybdis_cv_c_gcc_w_cast_align)
CHARYBDIS_C_GCC_TRY_FLAGS([-Wcast-qual], charybdis_cv_c_gcc_w_cast_qual)
CHARYBDIS_C_GCC_TRY_FLAGS([-Wwrite-strings], charybdis_cv_c_gcc_w_write_strings)
CHARYBDIS_C_GCC_TRY_FLAGS([-Werror-implicit-function-declaration], charybdis_cv_c_gcc_w_error_implicit_function_declaration)
CHARYBDIS_C_GCC_TRY_FLAGS([-Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations], charybdis_cv_c_gcc_prototypes)
CHARYBDIS_C_GCC_TRY_FLAGS([-Wparentheses], charybdis_cv_c_gcc_parentheses)
CHARYBDIS_C_GCC_TRY_FLAGS([-W -Wno-unused], charybdis_cv_c_gcc_w)
CHARYBDIS_C_GCC_TRY_FLAGS([-Wextra], charybdis_cv_c_gcc_w_extra)
CHARYBDIS_C_GCC_TRY_FLAGS([-Wshadow], charybdis_cv_c_gcc_w_shadow)
CHARYBDIS_C_GCC_TRY_FLAGS([-Wmissing-noreturn], charybdis_cv_c_gcc_w_missing_noreturn)
CHARYBDIS_C_GCC_TRY_FLAGS([-Wundef], charybdis_cv_c_gcc_w_undef)
CHARYBDIS_C_GCC_TRY_FLAGS([-Wpacked], charybdis_cv_c_gcc_w_packed)
CHARYBDIS_C_GCC_TRY_FLAGS([-Wnested-externs], charybdis_cv_c_gcc_w_nested_externs)
CHARYBDIS_C_GCC_TRY_FLAGS([-Wunused-function -Wunused-label -Wunused-value -Wunused-variable], charybdis_cv_c_gcc_w_unused)
CHARYBDIS_C_GCC_TRY_FLAGS([-Wredundant-decls], charybdis_cv_c_gcc_w_redundant_decls)
CHARYBDIS_C_GCC_TRY_FLAGS([-Wfloat-equal], charybdis_cv_c_gcc_w_float_equal)
CHARYBDIS_C_GCC_TRY_FLAGS([-Wformat -Wformat-y2k -Wno-format-security], charybdis_cv_c_gcc_w_format)
IRC_CFLAGS="$CFLAGS"
],[])
@ -613,10 +687,15 @@ AC_SUBST(SEDOBJ)
if test "$prefix" = "NONE"; then
AC_DEFINE_UNQUOTED(IRCD_PREFIX, "$ac_default_prefix", [Prefix where the ircd is installed.])
else
dnl Strip trailing slashes to prevent a path of '//'
dnl Don't get bitten by Cygwin's stupidity if the user specified
dnl a custom prefix with a trailing slash
prefix=`echo $prefix | sed 's/\/$//'`
AC_DEFINE_UNQUOTED(IRCD_PREFIX, "$prefix", [Prefix where the ircd is installed.])
fi
AC_CONFIG_FILES( \
@ -648,6 +727,7 @@ echo "
Configuration of ${BRANDING_NAME}-${BRANDING_VERSION}:
Install directory : $prefix
Ziplinks : $zlib
OpenSSL : $openssl
SCTP : $sctp

View file

@ -1,129 +0,0 @@
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";
};

View file

@ -116,11 +116,11 @@ Armin Gruner <gruner@informatik.tu-muenchen.de> / May, June 1990:
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.
* 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. :)
lines worth. :)
Thanks go to those persons not mentioned here who have added their advice,
opinions, and code to IRC.
@ -174,7 +174,6 @@ 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>
@ -188,6 +187,7 @@ 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>
@ -195,7 +195,7 @@ 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>
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,
@ -210,9 +210,9 @@ 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.
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>
@ -221,56 +221,8 @@ 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

View file

@ -1,7 +1,7 @@
account-notify client capability specification
----------------------------------------------
Copyright (c) 2010 Ariadne Conill <ariadne@dereferenced.org>.
Copyright (c) 2010 William Pitcock <nenolod@atheme.org>.
Unlimited redistribution and modification of this document is allowed
provided that the above copyright notice and this permission notice

View file

@ -51,6 +51,9 @@ If aes256 is not available, the following is used instead:
- Building ratbox-respond -
---------------------------
If you are using the unix based ratbox-respond this must be built. For the
windows version, ratbox-winrespond, please see http://respond.ircd-ratbox.org
ratbox-respond takes the challenge from the server, and together with your
private key file generates a response to be sent back. ratbox-respond
requires the openssl headers (ie, development files) and openssl libraries

View file

@ -42,10 +42,6 @@ exists and is not +s or +p. (The ops of the channel the ban is on cannot
necessarily see whether the user is in the target channel, so it should not
influence whether they can join either.)
extb_canjoin.so
$j:<channel>
matches users who are or are not banned from a specified channel
extb_oper.so
$o
matches opers (most useful with +I)
@ -60,14 +56,6 @@ extb_server.so
matches users connected to a server matching the mask (* and ? wildcards);
this can only be used with +b and +q
extb_extgecos.so
$x:<mask>
bans all users with matching nick!user@host#gecos
extb_ssl.so
$z
matches all SSL users
Comparisons:
+b $~a is similar to +r but also prevents not logged in users talking or

View file

@ -1,59 +0,0 @@
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.

View file

@ -78,7 +78,7 @@ Note that some clients may have to use /quote ACCEPT instead of /accept.
--
Client Hwy101: /msg Hwy-LL hi
Hwy101 will see: -!- Hwy-LL is in +g mode and must manually allow you to message them.
Hwy101 will see: -!- Hwy-LL is in +g mode (server-side ignore.)
-!- Hwy-LL has been informed that you messaged them.
Hwy-LL will see: -!- Hwy101 wcampbel@admin.irc.monkie.org is messaging you, and you have umode +g.
@ -86,7 +86,7 @@ Hwy-LL will see: -!- Hwy101 wcampbel@admin.irc.monkie.org is messaging you, and
--
If Hwy101 sends another message to Hwy-LL (before the minute expires), he will
see: -!- Hwy-LL is in +g mode and must manually allow you to message them.
see: -!- Hwy-LL is in +g mode (server-side ignore.)
and will not receive the second notice
Hwy-LL will NOT see any notice. This also applies if the second message comes
@ -189,7 +189,7 @@ their accept list.
716 - ERR_TARGUMODEG
--------------------
:<server> 716 <nick> <target> :is in +g mode and must manually allow you to message them.
:<server> 716 <nick> <target> :is in +g mode (server-side ignore.)
This numeric is used to indicate that a message (PRIVMSG) the client sent
could not be delivered because of CallerID restrictions. The <target>

View file

@ -12,10 +12,8 @@ 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
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:

View file

@ -9,6 +9,9 @@
/* Extensions */
#loadmodule "extensions/chm_nonotice";
#loadmodule "extensions/chm_operonly_compat";
#loadmodule "extensions/chm_quietunreg_compat";
#loadmodule "extensions/chm_sslonly_compat";
#loadmodule "extensions/chm_operpeace";
#loadmodule "extensions/createauthonly";
#loadmodule "extensions/extb_account";
@ -29,8 +32,10 @@
#loadmodule "extensions/m_locops";
#loadmodule "extensions/no_oper_invis";
#loadmodule "extensions/sno_farconnect";
#loadmodule "extensions/sno_globalkline";
#loadmodule "extensions/sno_globalnickchange";
#loadmodule "extensions/sno_globaloper";
#loadmodule "extensions/sno_whois";
#loadmodule "extensions/override";
#loadmodule "extensions/no_kill_services";
@ -47,7 +52,7 @@
serverinfo {
name = "hades.arpa";
sid = "42X";
description = "solanum test server";
description = "charybdis test server";
network_name = "StaticBox";
/* On multi-homed hosts you may need the following. These define
@ -231,8 +236,8 @@ auth {
* means they must be defined before operator {}.
*/
privset "local_op" {
privs = oper:general, oper:privs, oper:testline, oper:kill, oper:operwall, oper:message,
usermode:servnotice, auspex:oper, auspex:hostname, auspex:umodes, auspex:cmodes;
privs = oper:general, oper:privs, oper:testline, oper:local_kill, oper:operwall, usermode:servnotice,
auspex:oper, auspex:hostname, auspex:umodes, auspex:cmodes;
};
privset "server_bot" {
@ -242,9 +247,8 @@ privset "server_bot" {
privset "global_op" {
extends = "local_op";
privs = oper:routing, oper:kline, oper:unkline, oper:xline,
oper:resv, oper:cmodes, oper:mass_notice, oper:wallops,
oper:remoteban;
privs = oper:global_kill, oper:routing, oper:kline, oper:unkline, oper:xline,
oper:resv, oper:cmodes, oper:mass_notice, oper:remoteban;
};
privset "admin" {
@ -306,15 +310,14 @@ operator "god" {
privset = "admin";
};
/* See connecting-servers.rst for an introduction to using these files. */
connect "irc.uplink.com" {
host = "203.0.113.3";
send_password = "password";
accept_password = "anotherpassword";
port = 6666;
hub_mask = "*";
class = "server";
flags = topicburst;
flags = compressed, topicburst;
#fingerprint = "c77106576abf7f9f90cca0f63874a60f2e40a64b";
};
@ -324,6 +327,7 @@ connect "ssl.uplink.com" {
send_password = "password";
accept_password = "anotherpassword";
port = 9999;
hub_mask = "*";
class = "server";
flags = ssl, topicburst;
};
@ -337,8 +341,9 @@ cluster {
flags = kline, tkline, unkline, xline, txline, unxline, resv, tresv, unresv;
};
secure {
ip = "127.0.0.1";
shared {
oper = "*@*", "*";
flags = all, rehash;
};
/* exempt {}: IPs that are exempt from Dlines and rejectcache. (OLD d:) */
@ -371,7 +376,6 @@ channel {
displayed_usercount = 3;
strip_topic_colors = no;
opmod_send_statusmsg = no;
invite_notify_notice = yes;
};
serverhide {
@ -580,15 +584,6 @@ general {
kline_with_reason = yes;
hide_tkdline_duration = no;
kline_reason = "K-Lined";
sasl_only_client_message = "You need to identify via SASL to use this server.";
identd_only_client_message = "You need to install identd to use this server.";
sctp_forbidden_client_message = "You are not allowed to use SCTP on this server.";
ssltls_only_client_message = "You need to use SSL/TLS to use this server.";
not_authorised_client_message = "You are not authorised to access this server.";
illegal_hostname_client_message = "You have an illegal character in your hostname.";
server_full_client_message = "Sorry, server is full - try later";
illegal_name_long_client_message = "Your username is invalid. Please make sure that your username contains only alphanumeric characters.";
illegal_name_short_client_message = "Invalid username";
identify_service = "NickServ@services.int";
identify_command = "IDENTIFY";
non_redundant_klines = yes;
@ -596,6 +591,7 @@ general {
use_propagated_bans = yes;
stats_e_disabled = no;
stats_c_oper_only = no;
stats_h_oper_only = no;
stats_y_oper_only = no;
stats_o_oper_only = yes;
stats_P_oper_only = no;

View file

@ -1,2 +1,2 @@
This is solanum MOTD you might replace it, but if not your friends will
This is charybdis MOTD you might replace it, but if not your friends will
laugh at you.

View file

@ -255,9 +255,6 @@ flags
class
A name of a class to put users matching this auth{} block into.
umodes
Additional umodes to apply to the default_umodes upon connect.
auth {} flags
~~~~~~~~~~~~~

View file

@ -1,4 +1,4 @@
/* doc/reference.conf - solanum example configuration file
/* doc/reference.conf - charybdis Example configuration file
*
* Copyright (C) 2000-2002 Hybrid Development Team
* Copyright (C) 2002-2005 ircd-ratbox development team
@ -26,10 +26,6 @@
* .include "filename"
* .include <filename>
*
* Flags variables are comma-separated sets of predefined values,
* specific to each block. For example in operator {} blocks:
* flags = encrypted, encrypted;
*
* Times/durations are written as:
* 12 hours 30 minutes 1 second
*
@ -51,6 +47,9 @@
* Channel mode +-T (blocks notices) -- chm_nonotice
* Channel mode +-O (oper only) -- chm_operonly
* Channel mode +-S (ssl only) -- chm_sslonly
* Emulates channel mode +-O (oper only) (+-iI $o) -- chm_operonly_compat
* Emulates channel mode +-R (quiet unreg) (+-q $~a) -- chm_quietunreg_compat
* Emulates channel mode +-S (ssl only) (+-b $~z) -- chm_sslonly_compat
* 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
@ -64,7 +63,7 @@
* 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
* Helpops system (umode +H) -- helpops
* HURT system -- hurt
* New host mangling (umode +x) -- ip_cloaking_4.0
* Old host mangling (umode +h) -- ip_cloaking
@ -74,16 +73,20 @@
* /locops support -- m_locops
* Opers cannot be invisible (umode +i) -- no_oper_invis
* Far connection notices (snomask +F) -- sno_farconnect
* Remote k/d/x line active notices -- sno_globalkline
* Remote oper up notices -- sno_globaloper
* Global nick-change notices -- sno_globalnickchange
* /whois notifications (snomask +W) -- sno_whois
* 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_operonly_compat";
#loadmodule "extensions/chm_quietunreg_compat";
#loadmodule "extensions/chm_sslonly_compat";
#loadmodule "extensions/chm_operpeace";
#loadmodule "extensions/createauthonly";
#loadmodule "extensions/extb_account";
@ -107,11 +110,12 @@
#loadmodule "extensions/m_locops";
#loadmodule "extensions/no_oper_invis";
#loadmodule "extensions/sno_farconnect";
#loadmodule "extensions/sno_globalkline";
#loadmodule "extensions/sno_globalnickchange";
#loadmodule "extensions/sno_globaloper";
#loadmodule "extensions/sno_whois";
#loadmodule "extensions/override";
#loadmodule "extensions/no_kill_services";
#loadmodule "extensions/umode_hide_idle_time";
/* serverinfo {}: Contains information about the server. (OLD M:) */
serverinfo {
@ -158,7 +162,7 @@ serverinfo {
ssl_dh_params = "etc/dh.pem";
/* ssl_cipher_list: A list of ciphers, dependent on your TLS backend */
#ssl_cipher_list = "TLS_CHACHA20_POLY1305_SHA256:EECDH+HIGH:EDH+HIGH:HIGH:!aNULL";
#ssl_cipher_list = "EECDH+HIGH:EDH+HIGH:HIGH:!aNULL";
/* ssld_count: number of ssld processes you want to start, if you
* have a really busy server, using N-1 where N is the number of
@ -286,17 +290,14 @@ class "server" {
*/
connectfreq = 5 minutes;
/* max_autoconn: the amount of servers to autoconnect to. if the number
/* max number: the amount of servers to autoconnect to. if the number
* of servers in the class is or exceeds this, no more servers in the
* class are autoconnected. oper initiated connects are unaffected.
* this should usually be set to either 0 or 1. (autoconnecting from
* hubs to leaves may cause leaves to function as hubs by having
* multiple servers connected to them.)
*/
max_autoconn = 1;
/* max_number: the maximum number of servers allowed in this class */
max_number = 100;
max_number = 1;
/* sendq: servers need a higher sendq as they are sent more data */
sendq = 2 megabytes;
@ -346,11 +347,6 @@ listen {
/* auth {}: allow users to connect to the ircd (OLD I:) */
auth {
/* description: descriptive text to help recognize this auth block in
* stats i output.
*/
description = "example oper";
/* user: the user@host allowed to connect. Multiple IPv4/IPv6 user
* lines are permitted per auth block. This is matched against the
* hostname and IP address (using :: shortening for IPv6 and
@ -360,11 +356,6 @@ auth {
user = "*@198.51.100.0/24";
user = "*test@2001:db8:1:*";
/* umodes; the user mode character string to apply to users
* when they get placed into this auth block.
*/
#umodes = "+w";
/* auth_user: This allows specifying a username:password instead of
* just a password in PASS, so that a fixed user@host is not
* necessary for a specific auth{} block.
@ -390,13 +381,13 @@ auth {
* exceed_limit (old > flag) | allow user to exceed class user limits
* kline_exempt (old ^ flag) | exempt this user from k/g/xlines,
* | dnsbls, and proxies
* dnsbl_exempt | exempt this user from dnsbls
* dnsbl_exempt | exempt this user from dnsbls
* proxy_exempt | exempt this user from proxies
* spambot_exempt | exempt this user from spambot checks
* shide_exempt | exempt this user from serverhiding
* spambot_exempt | exempt this user from spambot checks
* shide_exempt | exempt this user from serverhiding
* jupe_exempt | exempt this user from generating
* 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
* USE WITH CAUTION.
* no_tilde (old - flag) | don't prefix ~ to username if no ident
@ -447,7 +438,8 @@ privset "local_op" {
* 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:local_kill: allows local users to be /KILL'd
* oper:global_kill: allows local and remote users to be /KILL'd
* oper:routing: allows remote SQUIT and CONNECT
* oper:kline: allows KLINE and DLINE
* oper:unkline: allows UNKLINE and UNDLINE
@ -468,12 +460,9 @@ privset "local_op" {
* channels etc. see /quote help operspy
* oper:hidden: hides the oper from /stats p
* oper:remoteban: allows remote kline etc
* oper:mass_notice: allows sending mass notices
* oper:wallops: allows sending wallops messages
* oper:mass_notice: allows sending wallops and mass notices
* 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:
*
@ -481,13 +470,10 @@ privset "local_op" {
* 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)
* usermode:helpops allows setting +H (from extensions/helpops)
*/
privs = oper:general, oper:privs, oper:testline, oper:kill, oper:operwall, oper:message,
usermode:servnotice, auspex:oper, auspex:hostname, auspex:umodes, auspex:cmodes;
privs = oper:general, oper:privs, oper:testline, oper:local_kill, oper:operwall, usermode:servnotice,
auspex:oper, auspex:hostname, auspex:umodes, auspex:cmodes;
};
privset "server_bot" {
@ -498,9 +484,8 @@ privset "server_bot" {
privset "global_op" {
extends = "local_op";
privs = oper:routing, oper:kline, oper:unkline, oper:xline,
oper:resv, oper:cmodes, oper:mass_notice, oper:wallops,
oper:remoteban;
privs = oper:global_kill, oper:routing, oper:kline, oper:unkline, oper:xline,
oper:resv, oper:cmodes, oper:mass_notice, oper:remoteban;
};
privset "admin" {
@ -564,21 +549,12 @@ operator "god" {
privset = "admin";
};
/* connect {}: controls servers we connect with (OLD C:, N:, H:, L:).
*
* This configuration is used whether connections are incoming or
* outgoing.
*/
/* connect {}: controls servers we connect to (OLD C:, N:, H:, L:) */
connect "irc.uplink.com" {
/* 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.
*/
/* the name must go above */
/* host: the host or IP to connect to.
*
* It is also used to validate incoming connections. If a hostname
* is used, it must match the reverse dns of the server.
/* host: the host or IP to connect to. If a hostname is used it
* must match the reverse dns of the server.
*/
host = "203.0.113.3";
@ -602,18 +578,28 @@ connect "irc.uplink.com" {
/* port: the port to connect to this server on */
port = 6666;
/* hub mask: the mask of servers that this server may hub. Multiple
* entries are permitted
*/
hub_mask = "*";
/* leaf mask: the mask of servers this server may not hub. Multiple
* entries are permitted. Useful for forbidding EU -> US -> EU routes.
*/
#leaf_mask = "*.uk";
/* class: the class this server is in */
class = "server";
/* flags: controls special options for this server
* encrypted - marks the accept_password as being crypt()'d
* autoconn - automatically connect to this server
* topicburst - burst topics between servers
* ssl - ssl/tls encrypted server connections
* sctp - use SCTP instead of TCP to connect to the server
* encrypted - marks the accept_password as being crypt()'d
* autoconn - automatically connect to this server
* compressed - compress traffic via ziplinks
* topicburst - burst topics between servers
* ssl - ssl/tls encrypted server connections
* no-export - marks the link as a no-export link (not exported to other links)
*/
flags = topicburst;
flags = compressed, topicburst;
};
connect "ipv6.lame.server" {
@ -631,15 +617,24 @@ connect "ipv6.lame.server" {
};
connect "ssl.uplink.com" {
/* Example of ssl server-to-server connection, ssl flag doesn't need
* compressed flag, 'cause it uses own compression
*/
host = "203.0.113.129";
send_password = "password";
accept_password = "anotherpassword";
port = 9999;
hub_mask = "*";
class = "server";
flags = ssl, topicburst;
};
/* cluster {}; servers that we propagate things to automatically. */
/* 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 {
/* name: the server to share with, this can be a wildcard and may be
* stacked.
@ -672,7 +667,8 @@ cluster {
/* service{}: privileged servers (services). These servers have extra
* privileges such as setting login names on users and introducing clients
* with umode +S (unkickable, hide channels, etc).
* with umode +S (unkickable, hide channels, etc). This does not allow them
* to set bans, you need a separate shared{} for that.
* Do not place normal servers here.
* There may be only one service{} block.
*/
@ -681,6 +677,59 @@ service {
name = "services.int";
};
/* shared {}: users that are allowed to place remote bans on our server.
* NOTE: These are ordered top down. The first one the user@host and server
* matches will be used. Their access will then be decided on that
* block and will not fall back to another block that matches.
*/
shared {
/* oper: the user@host and server the user must be on to set klines.
* The first field must be a user@host, the second field is an
* optional server. These may be stacked.
*/
/* flags: list of what to allow them to place, all the oper lines
* above this (up until another flags entry) will receive these
* flags. This *must* be present.
*
* kline - allow setting perm/temp klines
* tkline - allow setting temp klines
* unkline - allow removing klines
* xline - allow setting perm/temp xlines
* txline - allow setting temp xlines
* unxline - allow removing xlines
* resv - allow setting perm/temp resvs
* tresv - allow setting temp resvs
* unresv - allow removing xlines
* all - allow oper/server to do all of above.
* locops - allow locops - only used for servers who cluster
* rehash - allow rehashing
* dline - allow setting perm/temp dlines
* tdline - allow setting temp dlines
* undline - allow removing dlines
* grant - allow granting operator status
* die - allow remote DIE/RESTART
* module - allow remote module commands
* none - disallow everything
*/
/* allow flame@*.leeh.co.uk on server irc.ircd-ratbox.org and
* allow leeh@*.leeh.co.uk on server ircd.ircd-ratbox.org to kline
*/
oper = "flame@*.leeh.co.uk", "irc.ircd-ratbox.org";
oper = "leeh@*.leeh.co.uk", "ircd.ircd-ratbox.org";
flags = kline;
/* you may forbid certain opers/servers from doing anything */
oper = "irc@vanity.oper", "*";
oper = "*@*", "irc.vanity.server";
oper = "irc@another.vanity.oper", "bigger.vanity.server";
flags = none;
/* or allow everyone to place temp klines */
oper = "*@*";
flags = tkline;
};
/* exempt {}: IPs that are exempt from Dlines and rejectcache. (OLD d:) */
exempt {
ip = "192.0.2.0/24";
@ -689,12 +738,6 @@ exempt {
ip = "127.0.0.1";
};
/* secure {}: IPs that are considered to be secure networks, and get
* +Z without using TLS */
secure {
ip = "127.0.0.1";
};
/* The channel block contains options pertaining to channels */
channel {
/* invex: Enable/disable channel mode +I, a n!u@h list of masks
@ -818,14 +861,6 @@ channel {
* 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;
};
@ -1179,51 +1214,6 @@ general {
*/
kline_reason = "Connection closed";
/* SASL access only client message: give users a message that
* informs them
*/
sasl_only_client_message = "You need to identify via SASL to use this server.";
/* Identd access only client message: give users a message that
* informs them
*/
identd_only_client_message = "You need to install identd to use this server.";
/* SCTP forbidden client message: give users a message that
* informs them
*/
sctp_forbidden_client_message = "You are not allowed to use SCTP on this server.";
/* SSL/TLS access only client message: give users a message that
* informs them
*/
ssltls_only_client_message = "You need to use SSL/TLS to use this server.";
/* Not authorised client message: tell users that they are not
* authorised
*/
not_authorised_client_message = "You are not authorised to access this server.";
/* Illegal hostname client message: tell users that they have illegal
* chars in their hostname
*/
illegal_hostname_client_message = "You have an illegal character in your hostname.";
/* Server full client message: tell users that the server they're connecting
* to is full
*/
server_full_client_message = "Sorry, server is full - try later";
/* illegal name long client message: long-form explanation that their username
* contains illegal characters
*/
illegal_name_long_client_message = "Your username is invalid. Please make sure that your username contains only alphanumeric characters.";
/* illegal name short client message: short-form notification that their username
* contains illegal characters; will be followed by ": their_username"
*/
illegal_name_short_client_message = "Invalid username";
/* identify to services via server password
* if auth{} block had no password but the user specified a
* server password anyway, send a PRIVMSG to <identify_service>
@ -1256,6 +1246,9 @@ general {
/* stats c oper only: make stats c (connect {}) oper only */
stats_c_oper_only = no;
/* stats h oper only: make stats h (hub_mask/leaf_mask) oper only */
stats_h_oper_only = no;
/* stats y oper only: make stats y (class {}) oper only */
stats_y_oper_only = no;
@ -1282,13 +1275,6 @@ general {
*/
stats_k_oper_only = masked;
/* stats l/L oper only:
* yes: non-opers can't use this at all
* self: non-opers see only themselves
* no: show targeted users or non-hidden opers to everyone
*/
stats_l_oper_only = self;
/* map oper only: make /map oper only */
map_oper_only = no;
@ -1326,13 +1312,6 @@ general {
*/
ping_cookie = no;
/* ping warn time: how long to wait after pinging a server before starting
* to complain it is unresponsive. Note that the ping check interval is 30
* seconds, so the first complaint will come at the next check after this
* time has passed.
*/
ping_warn_time = 15 seconds;
/* connect timeout: sets how long we should wait for a connection
* request to succeed
*/
@ -1370,7 +1349,7 @@ general {
/* usermodes configurable: a list of usermodes for the options below
*
* +g - callerid - Server-side private message allow list
* +g - callerid - Server Side Ignore
* +D - deaf - Don't see channel messages
* +i - invisible - Not shown in NAMES or WHO unless you share a
* a channel
@ -1392,6 +1371,14 @@ general {
* provided they have umode +s set */
oper_snomask = "+s";
/* compression level: level of compression for compressed links between
* servers.
*
* values are between: 1 (least compression, fastest)
* and: 9 (most compression, slowest).
*/
#compression_level = 6;
/* burst_away: This enables bursting away messages to servers.
* With this disabled, we will only propogate AWAY messages
* as users send them, but never burst them. Be warned though
@ -1473,23 +1460,9 @@ general {
/* 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.";
};
modules {

View file

@ -1,5 +1,5 @@
Server capabilities
Ariadne Conill <ariadne -at- dereferenced.org>
William Pitcock <nenolod -at- nenolod.net>
-------------------
Not all TSora IRCd's support these.

View file

@ -319,28 +319,6 @@ Sets a D:line (IP ban checked directly after accepting connection).
The mask must be an IP address or CIDR mask.
EBMASK
source: server
propagation: broadcast
parameters: channelTS, channel, type, space separated "masks ts hostmask" chunks
If the channelTS in the message is greater (newer) than the current TS of
the channel, drop the message and do not propagate it.
Type is the mode letter of a ban-like mode. In efnet TS6 this is 'b', 'e' or
'I'. In charybdis TS6 additionally 'q' is possible.
Add all the masks and their set at/by to the given list of the channel.
All ban-like modes must be bursted using this command, not using MODE or TMODE.
ECHO
source: user
parameters: "P"/"N", target, text
As PRIVMSG, but delivers an echo-message echo to the target; they will see
a PRIVMSG or NOTICE from themselves to the source.
ENCAP
source: any
parameters: target server mask, subcommand, opt. parameters...

View file

@ -2,6 +2,9 @@ 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
if MINGW
LIBS += $(top_srcdir)/librb/src/librb.la
endif
extensiondir=@moduledir@/extensions
@ -9,17 +12,18 @@ extension_LTLIBRARIES = \
chantype_dummy.la \
chm_adminonly.la \
chm_operonly.la \
chm_operonly_compat.la \
chm_insecure.la \
chm_nonotice.la \
chm_operpeace.la \
chm_regmsg.la \
chm_quietunreg_compat.la \
chm_sslonly.la \
chm_sslonly_compat.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 \
@ -41,8 +45,10 @@ extension_LTLIBRARIES = \
restrict-unauthenticated.la \
sno_channelcreate.la \
sno_farconnect.la \
sno_globalkline.la \
sno_globalnickchange.la \
sno_globaloper.la \
sno_whois.la \
umode_noctcp.la \
m_adminwall.la \
m_echotags.la \
@ -56,20 +62,22 @@ extension_LTLIBRARIES = \
m_omode.la \
m_opme.la \
m_sendbans.la \
m_shedding.la \
m_webirc.la \
m_remove.la \
m_roleplay.la \
hide_uncommon_channels.la \
no_kill_services.la \
no_locops.la \
no_oper_invis.la \
sasl_usercloak.la \
spy_admin_notice.la \
spy_info_notice.la \
spy_links_notice.la \
spy_motd_notice.la \
spy_stats_notice.la \
spy_stats_p_notice.la \
spy_trace_notice.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

View file

@ -1,6 +1,6 @@
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
team.
team. Unsupported extensions live under unsupported/.
Modules
@ -79,7 +79,6 @@ extb_account.so - Account bans (+b $a[:mask])
extb_canjoin.so - Banned from another channel (+b $j:mask)
extb_channel.so - Other-channel bans (+b $c:mask)
extb_extgecos.so - Extended ban (+b $x:mask)
extb_guest.so - Unidentified bans (+b $g:mask)
extb_oper.so - Oper bans (+b $o)
extb_realname.so - Realname (gecos) bans (+b $r:mask)
extb_server.so - Server bans (+b $s:mask)

View file

@ -1,147 +0,0 @@
/*
* 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);

View file

@ -1,124 +0,0 @@
/*
* 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);

View file

@ -13,10 +13,10 @@
static const char chm_adminonly_desc[] =
"Enables channel mode +A that blocks non-admins from joining a channel";
static void h_can_join(void *);
static void h_can_join(hook_data_channel *);
mapi_hfn_list_av1 adminonly_hfnlist[] = {
{ "can_join", h_can_join },
{ "can_join", (hookfn) h_can_join },
{ NULL, NULL }
};
@ -41,9 +41,8 @@ _moddeinit(void)
DECLARE_MODULE_AV2(chm_adminonly, _modinit, _moddeinit, NULL, NULL, adminonly_hfnlist, NULL, NULL, chm_adminonly_desc);
static void
h_can_join(void *data_)
h_can_join(hook_data_channel *data)
{
hook_data_channel *data = data_;
struct Client *source_p = data->client;
struct Channel *chptr = data->chptr;

View file

@ -14,10 +14,10 @@ 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 *);
static void h_can_join(hook_data_channel *);
mapi_hfn_list_av1 sslonly_hfnlist[] = {
{ "can_join", h_can_join },
{ "can_join", (hookfn) h_can_join },
{ NULL, NULL }
};
@ -43,13 +43,12 @@ _moddeinit(void)
DECLARE_MODULE_AV2(chm_insecure, _modinit, _moddeinit, NULL, NULL, sslonly_hfnlist, NULL, NULL, chm_insecure_desc);
static void
h_can_join(void *data_)
h_can_join(hook_data_channel *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)) {
if(!(chptr->mode.mode & mymode) && !IsSSLClient(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;

View file

@ -1,8 +1,8 @@
/*
* Solanum: a slightly advanced ircd
* charybdis: an advanced ircd.
* chm_nonotice: block NOTICEs (+T mode).
*
* Copyright (c) 2012 Ariadne Conill <ariadne@dereferenced.org>
* Copyright (c) 2012 William Pitcock <nenolod@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
@ -40,23 +40,18 @@ static const char chm_nonotice_desc[] =
static unsigned int mode_nonotice;
static void chm_nonotice_process(void *);
static void chm_nonotice_process(hook_data_privmsg_channel *);
mapi_hfn_list_av1 chm_nonotice_hfnlist[] = {
{ "privmsg_channel", chm_nonotice_process },
{ "privmsg_channel", (hookfn) chm_nonotice_process },
{ NULL, NULL }
};
static void
chm_nonotice_process(void *data_)
chm_nonotice_process(hook_data_privmsg_channel *data)
{
hook_data_privmsg_channel *data = data_;
/*
* don't waste CPU if message is already blocked, only block notices,
* only check messages sourced from local clients (so we don't block services notices)
*/
if (data->approved || data->msgtype != MESSAGE_TYPE_NOTICE || !MyClient(data->source_p))
/* don't waste CPU if message is already blocked */
if (data->approved || data->msgtype != MESSAGE_TYPE_NOTICE)
return;
/* block all notices except CTCPs; use chm_noctcp to block CTCPs. */

View file

@ -13,10 +13,10 @@
static const char chm_operonly_desc[] =
"Adds channel mode +O which makes a channel operator-only";
static void h_can_join(void *);
static void h_can_join(hook_data_channel *);
mapi_hfn_list_av1 operonly_hfnlist[] = {
{ "can_join", h_can_join },
{ "can_join", (hookfn) h_can_join },
{ NULL, NULL }
};
@ -42,9 +42,8 @@ _moddeinit(void)
DECLARE_MODULE_AV2(chm_operonly, _modinit, _moddeinit, NULL, NULL, operonly_hfnlist, NULL, NULL, chm_operonly_desc);
static void
h_can_join(void *data_)
h_can_join(hook_data_channel *data)
{
hook_data_channel *data = data_;
struct Client *source_p = data->client;
struct Channel *chptr = data->chptr;

View file

@ -0,0 +1,55 @@
/*
* Treat cmode +-O as +-iI $o.
*/
#include "stdinc.h"
#include "modules.h"
#include "client.h"
#include "hook.h"
#include "ircd.h"
#include "chmode.h"
static const char chm_operonly_compat[] =
"Adds an emulated channel mode +O which is converted into mode +i and +I $o";
static int _modinit(void);
static void _moddeinit(void);
static void chm_operonly(struct Client *source_p, struct Channel *chptr,
int alevel, int parc, int *parn,
const char **parv, int *errors, int dir, char c, long mode_type);
DECLARE_MODULE_AV2(chm_operonly_compat, _modinit, _moddeinit, NULL, NULL, NULL, NULL, NULL, chm_operonly_compat);
static int
_modinit(void)
{
chmode_table['O'].set_func = chm_operonly;
chmode_table['O'].mode_type = 0;
return 0;
}
static void
_moddeinit(void)
{
chmode_table['O'].set_func = chm_nosuch;
chmode_table['O'].mode_type = 0;
}
static void
chm_operonly(struct Client *source_p, struct Channel *chptr,
int alevel, int parc, int *parn,
const char **parv, int *errors, int dir, char c, long mode_type)
{
int newparn = 0;
const char *newparv[] = { "$o" };
if (MyClient(source_p)) {
chm_simple(source_p, chptr, alevel, parc, parn, parv,
errors, dir, 'i', MODE_INVITEONLY);
chm_ban(source_p, chptr, alevel, 1, &newparn, newparv,
errors, dir, 'I', CHFL_INVEX);
} else
chm_nosuch(source_p, chptr, alevel, parc, parn, parv,
errors, dir, c, mode_type);
}

View file

@ -21,10 +21,10 @@
static const char chm_operpeace_desc[] =
"Adds channel mode +M which prohibits operators from being kicked";
static void hdl_can_kick(void *);
static void hdl_can_kick(hook_data_channel_approval *);
mapi_hfn_list_av1 chm_operpeace_hfnlist[] = {
{ "can_kick", hdl_can_kick },
{ "can_kick", (hookfn) hdl_can_kick },
{ NULL, NULL }
};
@ -49,9 +49,8 @@ _moddeinit(void)
DECLARE_MODULE_AV2(chm_operpeace, _modinit, _moddeinit, NULL, NULL, chm_operpeace_hfnlist, NULL, NULL, chm_operpeace_desc);
static void
hdl_can_kick(void *data_)
hdl_can_kick(hook_data_channel_approval *data)
{
hook_data_channel_approval *data = data_;
struct Client *source_p = data->client;
struct Client *who = data->target;
struct Channel *chptr = data->chptr;

View file

@ -0,0 +1,54 @@
/*
* Treat cmode +-R as +-q $~a.
* -- jilles
*/
#include "stdinc.h"
#include "modules.h"
#include "client.h"
#include "hook.h"
#include "ircd.h"
#include "chmode.h"
static const char chm_quietunreg_compat_desc[] =
"Adds an emulated channel mode +R which is converted into mode +q $~a";
static int _modinit(void);
static void _moddeinit(void);
static void chm_quietunreg(struct Client *source_p, struct Channel *chptr,
int alevel, int parc, int *parn,
const char **parv, int *errors, int dir, char c, long mode_type);
DECLARE_MODULE_AV2(chm_quietunreg_compat, _modinit, _moddeinit, NULL, NULL, NULL, NULL, NULL, chm_quietunreg_compat_desc);
static int
_modinit(void)
{
chmode_table['R'].set_func = chm_quietunreg;
chmode_table['R'].mode_type = 0;
return 0;
}
static void
_moddeinit(void)
{
chmode_table['R'].set_func = chm_nosuch;
chmode_table['R'].mode_type = 0;
}
static void
chm_quietunreg(struct Client *source_p, struct Channel *chptr,
int alevel, int parc, int *parn,
const char **parv, int *errors, int dir, char c, long mode_type)
{
int newparn = 0;
const char *newparv[] = { "$~a" };
if (MyClient(source_p))
chm_ban(source_p, chptr, alevel, 1, &newparn, newparv,
errors, dir, 'q', CHFL_QUIET);
else
chm_nosuch(source_p, chptr, alevel, parc, parn, parv,
errors, dir, c, mode_type);
}

View file

@ -1,131 +0,0 @@
/*
* Solanum: a slightly advanced ircd
* chm_regmsg: require identification to chat (+R mode).
*
* Copyright (c) 2020 Eric Mertens <emertens@gmail.com>
*
* 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 "modules.h"
#include "hook.h"
#include "client.h"
#include "ircd.h"
#include "logger.h"
#include "send.h"
#include "s_conf.h"
#include "s_user.h"
#include "s_serv.h"
#include "numeric.h"
#include "chmode.h"
#include "inline/stringops.h"
static const char chm_regmsg_desc[] =
"Adds channel mode +R, which blocks messages from unregistered users";
static unsigned int mode_regmsg;
static void hook_privmsg_channel(void *);
static void hook_can_send(void *);
mapi_hfn_list_av1 chm_regmsg_hfnlist[] = {
{ "privmsg_channel", hook_privmsg_channel },
{ "can_send", hook_can_send },
{ NULL, NULL }
};
static bool
chm_regmsg_test(struct Client *source_p, struct Channel *chptr)
{
struct membership *msptr;
/* mode is unset, accept */
if (!(chptr->mode.mode & mode_regmsg))
return true;
/* user is identified, accept */
if (!EmptyString(source_p->user->suser))
return true;
/* voice and op override identification requirement, accept */
msptr = find_channel_membership(chptr, source_p);
if (is_chanop_voiced(msptr))
return true;
return false;
}
static void
hook_privmsg_channel(void *data_)
{
hook_data_privmsg_channel *data = data_;
/* Only apply this hook if the channel isn't +z - if it is +z, then the can_send
* hook should be used to enable +z to do its job, as an error numeric won't be sent in that case */
if (data->chptr->mode.mode & MODE_OPMODERATE)
return;
/* message is already blocked, defer */
if (data->approved)
return;
if (chm_regmsg_test(data->source_p, data->chptr))
return;
sendto_one_numeric(data->source_p, ERR_MSGNEEDREGGEDNICK, form_str(ERR_MSGNEEDREGGEDNICK), data->chptr->chname);
data->approved = ERR_MSGNEEDREGGEDNICK;
}
static void hook_can_send(void *data_)
{
hook_data_channel_approval *data = data_;
/* Only apply this hook if the channel is +z - if it isn't +z, then the privmsg_channel
* hook should be used to enable a custom error numeric to be sent */
if (!(data->chptr->mode.mode & MODE_OPMODERATE))
return;
/* message is already blocked, defer */
if (data->approved == CAN_SEND_NO)
return;
if (chm_regmsg_test(data->client, data->chptr))
return;
data->approved = CAN_SEND_NO;
}
static int
_modinit(void)
{
mode_regmsg = cflag_add('R', chm_simple);
if (mode_regmsg == 0) {
ierror("chm_regmsg: unable to allocate cmode slot for +R, unloading module");
return -1;
}
return 0;
}
static void
_moddeinit(void)
{
cflag_orphan('R');
}
DECLARE_MODULE_AV2(chm_regmsg, _modinit, _moddeinit, NULL, NULL, chm_regmsg_hfnlist, NULL, NULL, chm_regmsg_desc);

View file

@ -13,10 +13,10 @@
static const char chm_sslonly_desc[] =
"Adds channel mode +S that bans non-SSL users from joing a channel";
static void h_can_join(void *);
static void h_can_join(hook_data_channel *);
mapi_hfn_list_av1 sslonly_hfnlist[] = {
{ "can_join", h_can_join },
{ "can_join", (hookfn) h_can_join },
{ NULL, NULL }
};
@ -41,13 +41,12 @@ _moddeinit(void)
DECLARE_MODULE_AV2(chm_sslonly, _modinit, _moddeinit, NULL, NULL, sslonly_hfnlist, NULL, NULL, chm_sslonly_desc);
static void
h_can_join(void *data_)
h_can_join(hook_data_channel *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)) {
if((chptr->mode.mode & mymode) && !IsSSLClient(source_p)) {
/* XXX This is equal to ERR_THROTTLE */
sendto_one_numeric(source_p, 480, "%s :Cannot join channel (+S) - SSL/TLS required", chptr->chname);
data->approved = ERR_CUSTOM;

View file

@ -0,0 +1,53 @@
/*
* Treat cmode +-S as +-b $~z.
*/
#include "stdinc.h"
#include "modules.h"
#include "client.h"
#include "hook.h"
#include "ircd.h"
#include "chmode.h"
static const char chm_sslonly_compat_desc[] =
"Adds an emulated channel mode +S which is converted into mode +b $~z";
static int _modinit(void);
static void _moddeinit(void);
static void chm_sslonly(struct Client *source_p, struct Channel *chptr,
int alevel, int parc, int *parn,
const char **parv, int *errors, int dir, char c, long mode_type);
DECLARE_MODULE_AV2(chm_sslonly_compat, _modinit, _moddeinit, NULL, NULL, NULL, NULL, NULL, chm_sslonly_compat_desc);
static int
_modinit(void)
{
chmode_table['S'].set_func = chm_sslonly;
chmode_table['S'].mode_type = 0;
return 0;
}
static void
_moddeinit(void)
{
chmode_table['S'].set_func = chm_nosuch;
chmode_table['S'].mode_type = 0;
}
static void
chm_sslonly(struct Client *source_p, struct Channel *chptr,
int alevel, int parc, int *parn,
const char **parv, int *errors, int dir, char c, long mode_type)
{
int newparn = 0;
const char *newparv[] = { "$~z" };
if (MyClient(source_p))
chm_ban(source_p, chptr, alevel, 1, &newparn, newparv,
errors, dir, 'b', CHFL_BAN);
else
chm_nosuch(source_p, chptr, alevel, parc, parn, parv,
errors, dir, c, mode_type);
}

View file

@ -19,19 +19,18 @@
static const char restrict_desc[] = "Restricts channel creation to authenticated users and IRC operators only";
static void h_can_create_channel_authenticated(void *);
static void h_can_create_channel_authenticated(hook_data_client_approval *);
mapi_hfn_list_av1 restrict_hfnlist[] = {
{ "can_create_channel", h_can_create_channel_authenticated },
{ "can_create_channel", (hookfn) h_can_create_channel_authenticated },
{ NULL, NULL }
};
DECLARE_MODULE_AV2(createauthonly, NULL, NULL, NULL, NULL, restrict_hfnlist, NULL, NULL, restrict_desc);
static void
h_can_create_channel_authenticated(void *data_)
h_can_create_channel_authenticated(hook_data_client_approval *data)
{
hook_data_client_approval *data = data_;
struct Client *source_p = data->client;
if (*source_p->user->suser == '\0' && !IsOperGeneral(source_p))

View file

@ -19,19 +19,18 @@
static const char restrict_desc[] = "Restricts channel creation to IRC operators";
static void h_can_create_channel_authenticated(void *);
static void h_can_create_channel_authenticated(hook_data_client_approval *);
mapi_hfn_list_av1 restrict_hfnlist[] = {
{ "can_create_channel", h_can_create_channel_authenticated },
{ "can_create_channel", (hookfn) h_can_create_channel_authenticated },
{ NULL, NULL }
};
DECLARE_MODULE_AV2(createoperonly, NULL, NULL, NULL, NULL, restrict_hfnlist, NULL, NULL, restrict_desc);
static void
h_can_create_channel_authenticated(void *data_)
h_can_create_channel_authenticated(hook_data_client_approval *data)
{
hook_data_client_approval *data = data_;
struct Client *source_p = data->client;
if (!IsOperGeneral(source_p))

View file

@ -6,7 +6,7 @@
static void check_new_user(void *data);
mapi_hfn_list_av1 drain_hfnlist[] = {
{ "new_local_user", check_new_user },
{ "new_local_user", (hookfn) check_new_user },
{ NULL, NULL }
};
@ -22,13 +22,10 @@ check_new_user(void *vdata)
struct Client *source_p = vdata;
const char *drain_reason = ConfigFileEntry.drain_reason;
if (IsAnyDead(source_p))
return;
if (drain_reason == NULL)
drain_reason = "This server is not accepting connections.";
if (IsExemptKline(source_p))
if(IsExemptKline(source_p))
return;
exit_client(source_p, source_p, &me, drain_reason);

View file

@ -30,7 +30,7 @@
*
* Make it short, sweet, and to the point.
*/
static const char example_desc[] = "This is an example Solanum module.";
static const char example_desc[] = "This is an example Charybdis module.";
/* Declare the void's initially up here, as modules dont have an
* include file, we will normally have client_p, source_p, parc
@ -112,7 +112,7 @@ mapi_hlist_av1 test_hlist[] = {
static void show_example_hook(void *unused);
mapi_hfn_list_av1 test_hfnlist[] = {
{ "doing_example_hook", show_example_hook },
{ "doing_example_hook", (hookfn) show_example_hook },
{ NULL, NULL }
};

View file

@ -7,7 +7,6 @@
#include "modules.h"
#include "client.h"
#include "ircd.h"
#include "supported.h"
static const char extb_desc[] = "Account ($a) extban type";
@ -21,7 +20,6 @@ static int
_modinit(void)
{
extban_table['a'] = eb_account;
add_isupport("ACCOUNTEXTBAN", isupport_string, "a");
return 0;
}
@ -30,7 +28,6 @@ static void
_moddeinit(void)
{
extban_table['a'] = NULL;
delete_isupport("ACCOUNTEXTBAN");
}
static int eb_account(const char *data, struct Client *client_p,

View file

@ -46,8 +46,6 @@ static int eb_canjoin(const char *data, struct Client *client_p,
return EXTBAN_INVALID;
if (data == NULL)
return EXTBAN_INVALID;
if (mode_type == CHFL_EXCEPTION)
return EXTBAN_INVALID;
chptr2 = find_channel(data);
/* must exist, and no point doing this with the same channel */
if (chptr2 == NULL || chptr2 == chptr)
@ -63,7 +61,7 @@ static int eb_canjoin(const char *data, struct Client *client_p,
return EXTBAN_INVALID;
#endif
recurse = 1;
ret = is_banned(chptr2, client_p, NULL, NULL, NULL) != 0 ? EXTBAN_MATCH : EXTBAN_NOMATCH;
ret = is_banned(chptr2, client_p, NULL, NULL, NULL) == CHFL_BAN ? EXTBAN_MATCH : EXTBAN_NOMATCH;
recurse = 0;
return ret;
}

View file

@ -34,42 +34,26 @@ _moddeinit(void)
static int eb_extended(const char *data, struct Client *client_p,
struct Channel *chptr, long mode_type)
{
char buf[BUFSIZE];
int ret;
(void)chptr;
if (data == NULL)
return EXTBAN_INVALID;
const char *idx = strchr(data, '#');
snprintf(buf, BUFSIZE, "%s!%s@%s#%s",
client_p->name, client_p->username, client_p->host, client_p->info);
if (idx != NULL && idx[1] == '\0')
/* Users cannot have empty realnames,
* so don't let a ban be set matching one
*/
return EXTBAN_INVALID;
ret = match(data, buf) ? EXTBAN_MATCH : EXTBAN_NOMATCH;
char buf[BUFSIZE];
if (idx != NULL)
if (ret == EXTBAN_NOMATCH && IsDynSpoof(client_p))
{
// Copy the nick!user@host part of the ban
memcpy(buf, data, (idx - data));
buf[(idx - data)] = '\0';
snprintf(buf, BUFSIZE, "%s!%s@%s#%s",
client_p->name, client_p->username, client_p->orighost, client_p->info);
// Advance to the realname part of the ban
idx++;
if (client_matches_mask(client_p, buf) && match(idx, client_p->info))
return EXTBAN_MATCH;
}
else
{
// Treat data as a pattern to match against the full nick!user@host#gecos.
snprintf(buf, sizeof buf, "%s!%s@%s#%s",
client_p->name, client_p->username, client_p->host, client_p->info);
if (match(data, buf))
return EXTBAN_MATCH;
ret = match(data, buf) ? EXTBAN_MATCH : EXTBAN_NOMATCH;
}
return EXTBAN_NOMATCH;
return ret;
}

View file

@ -1,73 +0,0 @@
/*
* Guest extban type: bans unidentified users matching nick!user@host.
* -- TheDaemoness
*/
#include "stdinc.h"
#include "modules.h"
#include "client.h"
#include "ircd.h"
static const char extb_desc[] = "Guest ($g) extban type - bans unidentified users matching nick!user@host";
static int _modinit(void);
static void _moddeinit(void);
static int eb_guest(const char *data, struct Client *client_p, struct Channel *chptr, long mode_type);
DECLARE_MODULE_AV2(extb_guest, _modinit, _moddeinit, NULL, NULL, NULL, NULL, NULL, extb_desc);
static int
_modinit(void)
{
extban_table['g'] = eb_guest;
return 0;
}
static void
_moddeinit(void)
{
extban_table['g'] = NULL;
}
static int eb_guest(const char *data, struct Client *client_p,
struct Channel *chptr, long mode_type)
{
(void)chptr;
if (data == NULL)
return EXTBAN_INVALID;
const char *idx = strchr(data, '#');
if (idx != NULL && idx[1] == '\0')
/* Users cannot have empty realnames,
* so don't let a ban be set matching one
*/
return EXTBAN_INVALID;
if (!EmptyString(client_p->user->suser))
return EXTBAN_NOMATCH;
if (idx != NULL)
{
char buf[BUFSIZE];
// Copy the nick!user@host part of the ban
memcpy(buf, data, (idx - data));
buf[(idx - data)] = '\0';
// Advance to the realname part of the ban
idx++;
if (client_matches_mask(client_p, buf) && match(idx, client_p->info))
return EXTBAN_MATCH;
return EXTBAN_NOMATCH;
}
if (client_matches_mask(client_p, data))
return EXTBAN_MATCH;
return EXTBAN_NOMATCH;
}

View file

@ -32,7 +32,5 @@ _moddeinit(void)
static int
eb_hostmask(const char *banstr, struct Client *client_p, struct Channel *chptr, long mode_type)
{
if (banstr == NULL)
return EXTBAN_INVALID;
return client_matches_mask(client_p, banstr) ? EXTBAN_MATCH : EXTBAN_NOMATCH;
}

View file

@ -34,7 +34,7 @@ static int eb_ssl(const char *data, struct Client *client_p,
(void)chptr;
(void)mode_type;
if (!IsSecureClient(client_p))
if (! IsSSLClient(client_p))
return EXTBAN_NOMATCH;
if (data != NULL)

View file

@ -90,10 +90,10 @@ static char check_str[21] = "";
static unsigned filter_chmode, filter_umode;
mapi_hfn_list_av1 filter_hfnlist[] = {
{ "privmsg_user", filter_msg_user },
{ "privmsg_channel", filter_msg_channel },
{ "client_quit", filter_client_quit },
{ "client_exit", on_client_exit },
{ "privmsg_user", (hookfn) filter_msg_user },
{ "privmsg_channel", (hookfn) filter_msg_channel },
{ "client_quit", (hookfn) filter_client_quit },
{ "client_exit", (hookfn) on_client_exit },
{ NULL, NULL }
};
@ -141,13 +141,13 @@ setfilter(const char *check, const char *data, const char **error)
if (!strcasecmp(data, "disable")) {
filter_enable = 0;
sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
sendto_realops_snomask(SNO_GENERAL, L_ALL | L_NETWIDE,
"Filtering disabled.");
return 0;
}
if (!strcasecmp(data, "enable")) {
filter_enable = 1;
sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
sendto_realops_snomask(SNO_GENERAL, L_ALL | L_NETWIDE,
"Filtering enabled.");
return 0;
}
@ -217,7 +217,7 @@ setfilter(const char *check, const char *data, const char **error)
}
state = FILTER_LOADED;
filter_db = db;
sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
sendto_realops_snomask(SNO_GENERAL, L_ALL | L_NETWIDE,
"New filters loaded.");
rb_free(filter_data);
filter_data = 0;
@ -408,7 +408,7 @@ filter_msg_user(void *data_)
data->approved = 1;
}
if (r & ACT_ALARM) {
sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
sendto_realops_snomask(SNO_GENERAL, L_ALL | L_NETWIDE,
"FILTER: %s!%s@%s [%s]",
s->name, s->username, s->host, s->sockhost);
}
@ -449,7 +449,7 @@ filter_msg_channel(void *data_)
data->approved = 1;
}
if (r & ACT_ALARM) {
sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
sendto_realops_snomask(SNO_GENERAL, L_ALL | L_NETWIDE,
"FILTER: %s!%s@%s [%s]",
s->name, s->username, s->host, s->sockhost);
}

View file

@ -18,19 +18,18 @@
static const char noi_desc[] =
"Do not allow users to remove user mode +i unless they are operators";
static void h_noi_umode_changed(void *);
static void h_noi_umode_changed(hook_data_umode_changed *);
mapi_hfn_list_av1 noi_hfnlist[] = {
{ "umode_changed", h_noi_umode_changed },
{ "umode_changed", (hookfn) h_noi_umode_changed },
{ NULL, NULL }
};
DECLARE_MODULE_AV2(force_user_invis, NULL, NULL, NULL, NULL, noi_hfnlist, NULL, NULL, noi_desc);
static void
h_noi_umode_changed(void *data)
h_noi_umode_changed(hook_data_umode_changed *hdata)
{
hook_data_umode_changed *hdata = data;
struct Client *source_p = hdata->client;
if (MyClient(source_p) && !IsOperGeneral(source_p) && !IsInvisible(source_p)) {

View file

@ -17,11 +17,11 @@
static const char helpops_desc[] = "The helpops system as used by freenode";
static rb_dlink_list helper_list = { NULL, NULL, 0 };
static void h_hdl_stats_request(void *hdata);
static void h_hdl_new_remote_user(void *client_p);
static void h_hdl_client_exit(void *hdata);
static void h_hdl_umode_changed(void *hdata);
static void h_hdl_whois(void *hdata);
static void h_hdl_stats_request(hook_data_int *hdata);
static void h_hdl_new_remote_user(struct Client *client_p);
static void h_hdl_client_exit(hook_data_client_exit *hdata);
static void h_hdl_umode_changed(hook_data_umode_changed *hdata);
static void h_hdl_whois(hook_data_client *hdata);
static void recurse_client_exit(struct Client *client_p);
static void helper_add(struct Client *client_p);
static void helper_delete(struct Client *client_p);
@ -30,16 +30,16 @@ static void me_dehelper(struct MsgBuf *, struct Client *, struct Client *, int,
static void do_dehelper(struct Client *source_p, struct Client *target_p);
mapi_hfn_list_av1 helpops_hfnlist[] = {
{ "doing_stats", h_hdl_stats_request },
{ "new_remote_user", h_hdl_new_remote_user },
{ "client_exit", h_hdl_client_exit },
{ "umode_changed", h_hdl_umode_changed },
{ "doing_whois", h_hdl_whois },
{ "doing_whois_global", h_hdl_whois },
{ "doing_stats", (hookfn) h_hdl_stats_request },
{ "new_remote_user", (hookfn) h_hdl_new_remote_user },
{ "client_exit", (hookfn) h_hdl_client_exit },
{ "umode_changed", (hookfn) h_hdl_umode_changed },
{ "doing_whois", (hookfn) h_hdl_whois },
{ "doing_whois_global", (hookfn) h_hdl_whois },
{ NULL, NULL }
};
#define UMODECHAR_HELPOPS 'h'
#define UMODECHAR_HELPOPS 'H'
struct Message dehelper_msgtab = {
"DEHELPER", 0, 0, 0, 0,
@ -91,7 +91,6 @@ static void
do_dehelper(struct Client *source_p, struct Client *target_p)
{
const char *fakeparv[4];
static const char minus_helpops[3] = {'-', UMODECHAR_HELPOPS, '\0'};
if(!(target_p->umodes & user_modes[UMODECHAR_HELPOPS]))
return;
@ -101,7 +100,7 @@ do_dehelper(struct Client *source_p, struct Client *target_p)
sendto_one_notice(target_p, ":*** %s is using DEHELPER on you", source_p->name);
fakeparv[0] = fakeparv[1] = target_p->name;
fakeparv[2] = minus_helpops;
fakeparv[2] = "-H";
fakeparv[3] = NULL;
user_mode(target_p, target_p, 3, fakeparv);
}
@ -137,9 +136,8 @@ _moddeinit(void)
}
static void
h_hdl_stats_request(void *data)
h_hdl_stats_request(hook_data_int *hdata)
{
hook_data_int *hdata = data;
struct Client *target_p;
rb_dlink_node *helper_ptr;
unsigned int count = 0;
@ -156,16 +154,10 @@ h_hdl_stats_request(void *data)
count++;
if (IsOper(hdata->client) && SeesOper(target_p, hdata->client)
&& !EmptyString(target_p->user->opername))
sendto_one_numeric(hdata->client, RPL_STATSDEBUG,
"p :%s (%s@%s) {%s}",
target_p->name, target_p->username, target_p->host,
target_p->user->opername);
else
sendto_one_numeric(hdata->client, RPL_STATSDEBUG,
"p :%s (%s@%s)",
target_p->name, target_p->username, target_p->host);
sendto_one_numeric(hdata->client, RPL_STATSDEBUG,
"p :%s (%s@%s)",
target_p->name, target_p->username,
target_p->host);
}
sendto_one_numeric(hdata->client, RPL_STATSDEBUG,
@ -190,9 +182,8 @@ helper_delete(struct Client *client_p)
}
static void
h_hdl_new_remote_user(void *data)
h_hdl_new_remote_user(struct Client *client_p)
{
struct Client *client_p = data;
if (client_p->umodes & user_modes[UMODECHAR_HELPOPS])
helper_add(client_p);
}
@ -218,19 +209,17 @@ recurse_client_exit(struct Client *client_p)
}
static void
h_hdl_client_exit(void *data)
h_hdl_client_exit(hook_data_client_exit *hdata)
{
hook_data_client_exit *hdata = data;
recurse_client_exit(hdata->target);
}
static void
h_hdl_umode_changed(void *data)
h_hdl_umode_changed(hook_data_umode_changed *hdata)
{
hook_data_umode_changed *hdata = data;
struct Client *source_p = hdata->client;
/* didn't change +h umode, we don't need to do anything */
/* didn't change +H umode, we don't need to do anything */
bool changed = (hdata->oldumodes ^ source_p->umodes) & user_modes[UMODECHAR_HELPOPS];
if (source_p->umodes & user_modes[UMODECHAR_HELPOPS])
@ -239,7 +228,7 @@ h_hdl_umode_changed(void *data)
{
source_p->umodes &= ~user_modes[UMODECHAR_HELPOPS];
sendto_one(source_p, form_str(ERR_NOPRIVS), me.name, source_p->name, "usermode:helpops");
/* they didn't ask for +h so we must be removing it */
/* they didn't ask for +H so we must be removing it */
if (!changed)
helper_delete(source_p);
return;
@ -255,9 +244,8 @@ h_hdl_umode_changed(void *data)
}
static void
h_hdl_whois(void *data)
h_hdl_whois(hook_data_client *hdata)
{
hook_data_client *hdata = data;
struct Client *source_p = hdata->client;
struct Client *target_p = hdata->target;

View file

@ -14,18 +14,17 @@
static const char hide_desc[] = "Hides channel memberships not shared";
static void h_huc_doing_whois_channel_visibility(void *);
static void h_huc_doing_whois_channel_visibility(hook_data_client *);
mapi_hfn_list_av1 huc_hfnlist[] = {
{ "doing_whois_channel_visibility", h_huc_doing_whois_channel_visibility },
{ "doing_whois_channel_visibility", (hookfn) h_huc_doing_whois_channel_visibility },
{ NULL, NULL }
};
DECLARE_MODULE_AV2(hide_uncommon_channels, NULL, NULL, NULL, NULL, huc_hfnlist, NULL, NULL, hide_desc);
static void
h_huc_doing_whois_channel_visibility(void *data_)
h_huc_doing_whois_channel_visibility(hook_data_client *hdata)
{
hook_data_channel_visibility *data = data_;
data->approved = data->approved && (!IsInvisible(data->target) || data->clientms != NULL);
hdata->approved = ((PubChannel(hdata->chptr) && !IsInvisible(hdata->target)) || IsMember((hdata->client), (hdata->chptr)));
}

View file

@ -1,5 +1,5 @@
/*
* Solanum: a slightly advanced ircd
* charybdis: an advanced Internet Relay Chat Daemon(ircd).
*
* Copyright (C) 2006 charybdis development team
* All rights reserved
@ -55,9 +55,9 @@ static void me_heal(struct MsgBuf *msgbuf_p, struct Client *, struct Client *, i
static int modinit(void);
static void modfini(void);
static void client_exit_hook(void *);
static void new_local_user_hook(void *);
static void doing_stats_hook(void *);
static void client_exit_hook(hook_data_client_exit *);
static void new_local_user_hook(struct Client *);
static void doing_stats_hook(hook_data_int *hdata);
static void hurt_check_event(void *);
static void hurt_expire_event(void *);
@ -98,9 +98,9 @@ struct Message heal_msgtab = {
/* {{{ Misc module stuff */
mapi_hfn_list_av1 hurt_hfnlist[] = {
{"client_exit", client_exit_hook},
{"new_local_user", new_local_user_hook},
{"doing_stats", doing_stats_hook},
{"client_exit", (hookfn) client_exit_hook},
{"new_local_user", (hookfn) new_local_user_hook},
{"doing_stats", (hookfn) doing_stats_hook},
{NULL, NULL},
};
@ -429,9 +429,8 @@ hurt_expire_event(void *unused)
/* {{{ static void client_exit_hook() */
static void
client_exit_hook(void *data_)
client_exit_hook(hook_data_client_exit *data)
{
hook_data_client_exit *data = data_;
s_assert(data != NULL);
s_assert(data->target != NULL);
@ -441,9 +440,8 @@ client_exit_hook(void *data_)
/* {{{ static void new_local_user_hook() */
static void
new_local_user_hook(void *data)
new_local_user_hook(struct Client *source_p)
{
struct Client *source_p = data;
if (IsAnyDead(source_p) || !EmptyString(source_p->user->suser) ||
IsExemptKline(source_p))
return;
@ -460,9 +458,8 @@ new_local_user_hook(void *data)
/* {{{ static void doing_stats_hook() */
static void
doing_stats_hook(void *data)
doing_stats_hook(hook_data_int *hdata)
{
hook_data_int *hdata = data;
rb_dlink_node *ptr;
hurt_t *hurt;
struct Client *source_p;
@ -618,7 +615,7 @@ heal_nick(struct Client *source_p, struct Client *target_p)
{
if (rb_dlinkFindDestroy(target_p, &hurt_state.hurt_clients))
{
sendto_realops_snomask(SNO_GENERAL, L_NETWIDE, "%s used HEAL on %s",
sendto_realops_snomask(SNO_GENERAL, L_ALL, "%s used HEAL on %s",
get_oper_name(source_p), get_client_name(target_p, HIDE_IP));
sendto_one_notice(target_p, ":HURT restriction temporarily removed by operator");
sendto_one_notice(source_p, ":HURT restriction on %s temporarily removed", target_p->name);

View file

@ -1,29 +0,0 @@
#include <stdinc.h>
#include <modules.h>
#include <msgbuf.h>
static const char identify_msg_desc[] = "Provides the solanum.chat/identify-msg client capability";
static void identmsg_outbound(void *);
unsigned int CLICAP_IDENTIFY_MSG = 0;
mapi_cap_list_av2 identmsg_cap_list[] = {
{ MAPI_CAP_CLIENT, "solanum.chat/identify-msg", NULL, &CLICAP_IDENTIFY_MSG },
{ 0, NULL, NULL, NULL }
};
static mapi_hfn_list_av1 identmsg_hfnlist[] = {
{ "outbound_msgbuf", identmsg_outbound },
{ NULL, NULL }
};
static void identmsg_outbound(void *data_)
{
hook_data *data = data_;
struct MsgBuf *msgbuf = data->arg1;
if (IsIdentified(data->client))
msgbuf_append_tag(msgbuf, "solanum.chat/identified", NULL, CLICAP_IDENTIFY_MSG);
}
DECLARE_MODULE_AV2(identify_msg, NULL, NULL, NULL, NULL, identmsg_hfnlist, identmsg_cap_list, NULL, identify_msg_desc);

View file

@ -1,47 +0,0 @@
/*
* invex_regonly.c Allow invite exemptions to bypass registered-only (+r)
*/
#include "stdinc.h"
#include "modules.h"
#include "hook.h"
#include "channel.h"
#include "s_conf.h"
#include "numeric.h"
static void h_can_join(void *);
mapi_hfn_list_av1 invex_regonly_hfnlist[] = {
{ "can_join", h_can_join },
{ NULL, NULL }
};
DECLARE_MODULE_AV1(invex_regonly, NULL, NULL, NULL, NULL, invex_regonly_hfnlist, "$Revision$");
static void
h_can_join(void *data_)
{
hook_data_channel *data = data_;
struct Client *source_p = data->client;
struct Channel *chptr = data->chptr;
struct Ban *invex = NULL;
struct matchset ms;
rb_dlink_node *ptr;
if(data->approved != ERR_NEEDREGGEDNICK)
return;
if(!ConfigChannel.use_invex)
return;
matchset_for_client(source_p, &ms);
RB_DLINK_FOREACH(ptr, chptr->invexlist.head)
{
invex = ptr->data;
if (matches_mask(&ms, invex->banstr) ||
match_extban(invex->banstr, source_p, chptr, CHFL_INVEX))
{
data->approved = 0;
break;
}
}
}

View file

@ -4,7 +4,6 @@
#include <client.h>
#include <hash.h>
#include <send.h>
#include <s_conf.h>
#include <s_serv.h>
static const char inv_notify_desc[] = "Notifies channel on /invite and provides the invite-notify client capability";
@ -33,16 +32,12 @@ mapi_clist_av1 inv_notify_clist[] = { &invited_msgtab, NULL };
static void
invite_notify(struct Client *source, struct Client *target, struct Channel *channel)
{
sendto_channel_local_with_capability(source, CHFL_CHANOP, CAP_INVITE_NOTIFY, 0, channel,
":%s!%s@%s INVITE %s %s", source->name, source->username,
source->host, target->name, channel->chname);
if (!ConfigChannel.invite_notify_notice)
return;
sendto_channel_local_with_capability(source, CHFL_CHANOP, 0, CAP_INVITE_NOTIFY, channel,
":%s NOTICE %s :%s is inviting %s to %s.",
me.name, channel->chname, source->name, target->name, channel->chname);
sendto_channel_local_with_capability(source, CHFL_CHANOP, CAP_INVITE_NOTIFY, 0, channel,
":%s!%s@%s INVITE %s %s", source->name, source->username,
source->host, target->name, channel->chname);
}
static void

View file

@ -1,5 +1,5 @@
/*
* Solanum: a slightly advanced ircd
* Charybdis: an advanced ircd
* ip_cloaking.c: provide user hostname cloaking
*
* Written originally by nenolod, altered to use FNV by Elizabeth in 2008
@ -40,8 +40,8 @@ _moddeinit(void)
static void check_umode_change(void *data);
static void check_new_user(void *data);
mapi_hfn_list_av1 ip_cloaking_hfnlist[] = {
{ "umode_changed", check_umode_change },
{ "new_local_user", check_new_user },
{ "umode_changed", (hookfn) check_umode_change },
{ "new_local_user", (hookfn) check_new_user },
{ NULL, NULL }
};

View file

@ -36,8 +36,8 @@ _moddeinit(void)
static void check_umode_change(void *data);
static void check_new_user(void *data);
mapi_hfn_list_av1 ip_cloaking_hfnlist[] = {
{ "umode_changed", check_umode_change },
{ "new_local_user", check_new_user },
{ "umode_changed", (hookfn) check_umode_change },
{ "new_local_user", (hookfn) check_new_user },
{ NULL, NULL }
};

View file

@ -1,5 +1,5 @@
/*
* Solanum: a slightly advanced ircd
* Charybdis: an advanced ircd
* ip_cloaking.c: provide user hostname cloaking
*
* Written originally by nenolod, altered to use FNV by Elizabeth in 2008
@ -40,8 +40,8 @@ _moddeinit(void)
static void check_umode_change(void *data);
static void check_new_user(void *data);
mapi_hfn_list_av1 ip_cloaking_hfnlist[] = {
{ "umode_changed", check_umode_change },
{ "new_local_user", check_new_user },
{ "umode_changed", (hookfn) check_umode_change },
{ "new_local_user", (hookfn) check_new_user },
{ NULL, NULL }
};

View file

@ -36,8 +36,8 @@ _moddeinit(void)
static void check_umode_change(void *data);
static void check_new_user(void *data);
mapi_hfn_list_av1 ip_cloaking_hfnlist[] = {
{ "umode_changed", check_umode_change },
{ "new_local_user", check_new_user },
{ "umode_changed", (hookfn) check_umode_change },
{ "new_local_user", (hookfn) check_new_user },
{ NULL, NULL }
};

View file

@ -1,5 +1,5 @@
/*
* solanum
* charybdis
* m_extendchans.c: Allow an oper or service to let a given user join more channels.
*
* Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center

View file

@ -59,6 +59,9 @@ m_findforwards(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *
struct Channel *chptr;
struct membership *msptr;
rb_dlink_node *ptr;
char buf[414];
char *p = buf, *end = buf + sizeof buf - 1;
*p = '\0';
/* Allow ircops to search for forwards to nonexistent channels */
if(!IsOperGeneral(source_p))
@ -87,19 +90,25 @@ m_findforwards(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *
last_used = rb_current_time();
}
send_multiline_init(source_p, " ", ":%s NOTICE %s :Forwards for %s: ",
me.name,
source_p->name,
parv[1]);
RB_DLINK_FOREACH(ptr, global_channel_list.head)
{
chptr = ptr->data;
if(!irccmp(chptr->mode.forward, parv[1]))
{
send_multiline_item(source_p, "%s", chptr->chname);
if(p + strlen(chptr->chname) >= end - 13)
{
strcpy(p, "<truncated> ");
p += 12;
break;
}
strcpy(p, chptr->chname);
p += strlen(chptr->chname);
*p++ = ' ';
}
}
send_multiline_fini(source_p, NULL);
if(buf[0])
*(--p) = '\0';
sendto_one_notice(source_p, ":Forwards for %s: %s", parv[1], buf);
}

View file

@ -80,7 +80,8 @@ ms_locops(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *sourc
if(!match(parv[1], me.name))
return;
sendto_wallops_flags(UMODE_LOCOPS, source_p, "SLOCOPS - %s", parv[2]);
if(find_shared_conf("*", "*", source_p->servptr->name, SHARED_LOCOPS))
sendto_wallops_flags(UMODE_LOCOPS, source_p, "SLOCOPS - %s", parv[2]);
}
static void
@ -90,6 +91,7 @@ me_locops(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *sourc
if(!IsPerson(source_p))
return;
sendto_wallops_flags(UMODE_LOCOPS, source_p, "SLOCOPS - %s", parv[1]);
if(find_shared_conf("*", "*", source_p->servptr->name, SHARED_LOCOPS))
sendto_wallops_flags(UMODE_LOCOPS, source_p, "SLOCOPS - %s", parv[1]);
}

View file

@ -134,7 +134,7 @@ mo_ojoin(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source
sendto_one(source_p, form_str(RPL_TOPIC), me.name,
source_p->name, chptr->chname, chptr->topic);
sendto_one(source_p, form_str(RPL_TOPICWHOTIME), me.name,
source_p->name, chptr->chname, chptr->topic_info, (long long)chptr->topic_time);
source_p->name, chptr->chname, chptr->topic_info, chptr->topic_time);
}
source_p->localClient->last_join_time = rb_current_time();

View file

@ -1,5 +1,5 @@
/*
* Solanum: a slightly advanced ircd
* Charybdis: an advanced Internet Relay Chat Daemon(ircd).
* m_omode.c: allows oper mode hacking
*
* Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center

View file

@ -42,7 +42,7 @@
static const char description[] = "Provides the REMOVE command, an alternative to KICK";
static void m_remove(struct MsgBuf *, struct Client *, struct Client *, int, const char **);
static void remove_quote_part(void *);
static void remove_quote_part(hook_data_privmsg_channel *);
unsigned int CAP_REMOVE;
static char part_buf[REASONLEN + 1];
@ -54,7 +54,7 @@ struct Message remove_msgtab = {
mapi_clist_av1 remove_clist[] = { &remove_msgtab, NULL };
mapi_hfn_list_av1 remove_hfnlist[] = {
{ "privmsg_channel", remove_quote_part },
{ "privmsg_channel", (hookfn) remove_quote_part },
{ NULL, NULL }
};
mapi_cap_list_av2 remove_cap_list[] = {
@ -67,7 +67,7 @@ DECLARE_MODULE_AV2(remove, NULL, NULL, remove_clist, NULL, remove_hfnlist, remov
static void
m_remove(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
struct membership *sourcems, *targetms;
struct membership *msptr;
struct Client *who;
struct Channel *chptr;
int chasing = 0;
@ -95,16 +95,16 @@ m_remove(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source
if(!IsServer(source_p))
{
sourcems = find_channel_membership(chptr, source_p);
msptr = find_channel_membership(chptr, source_p);
if((sourcems == NULL) && MyConnect(source_p))
if((msptr == NULL) && MyConnect(source_p))
{
sendto_one_numeric(source_p, ERR_NOTONCHANNEL,
form_str(ERR_NOTONCHANNEL), name);
return;
}
if(get_channel_access(source_p, chptr, sourcems, MODE_ADD, NULL) < CHFL_CHANOP)
if(get_channel_access(source_p, chptr, msptr, MODE_ADD, NULL) < CHFL_CHANOP)
{
if(MyConnect(source_p))
{
@ -154,9 +154,9 @@ m_remove(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source
return;
}
targetms = find_channel_membership(chptr, who);
msptr = find_channel_membership(chptr, who);
if(targetms != NULL)
if(msptr != NULL)
{
if(MyClient(source_p) && IsService(who))
{
@ -171,7 +171,7 @@ m_remove(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source
hookdata.client = source_p;
hookdata.chptr = chptr;
hookdata.msptr = sourcems;
hookdata.msptr = msptr;
hookdata.target = who;
hookdata.approved = 1;
hookdata.dir = MODE_ADD; /* ensure modules like override speak up */
@ -205,7 +205,7 @@ m_remove(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source
":%s KICK %s %s :%s",
use_id(source_p), chptr->chname, use_id(who), comment);
remove_user_from_channel(targetms);
remove_user_from_channel(msptr);
}
else if (MyClient(source_p))
sendto_one_numeric(source_p, ERR_USERNOTINCHANNEL,
@ -213,9 +213,8 @@ m_remove(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source
}
static void
remove_quote_part(void *data_)
remove_quote_part(hook_data_privmsg_channel *data)
{
hook_data_privmsg_channel *data = data_;
if (data->approved || EmptyString(data->text) || data->msgtype != MESSAGE_TYPE_PART)
return;

222
extensions/m_roleplay.c Normal file
View file

@ -0,0 +1,222 @@
/*
* roleplay commands for charybdis.
*
* adds NPC, NPCA, and SCENE which allow users to send messages from 'fake'
* nicknames. in the case of NPC and NPCA, the nickname will be underlined
* to clearly show that it is fake. SCENE is a special case and not underlined.
* these commands only work on channels set +N
*
* also adds oper commands FSAY and FACTION, which are like NPC and NPCA
* except without the underline.
*
* all of these messages have the hostmask npc.fakeuser.invalid, and their ident
* is the nickname of the user running the commands.
*/
#include "stdinc.h"
#include "ircd.h"
#include "client.h"
#include "modules.h"
#include "send.h"
#include "numeric.h"
#include "hash.h"
#include "s_serv.h"
#include "inline/stringops.h"
#include "chmode.h"
#include "tgchange.h"
#include "channel.h"
#include "packet.h"
#include "messages.h"
static const char roleplay_desc[] =
"Adds a roleplaying system that allows faked nicknames to talk in a channel set +N";
static void m_scene(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char *parv[]);
static void m_fsay(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char *parv[]);
static void m_faction(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char *parv[]);
static void m_npc(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char *parv[]);
static void m_npca(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char *parv[]);
static void m_displaymsg(struct MsgBuf *msgbuf_p, struct Client *source_p, const char *channel, int underline, int action, const char *nick, const char *text);
static void me_roleplay(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char *parv[]);
static unsigned int mymode;
static int
_modinit(void)
{
/* initalize the +N cmode */
mymode = cflag_add('N', chm_simple);
if (mymode == 0)
return -1;
return 0;
}
static void
_moddeinit(void)
{
/* orphan the +N cmode on modunload */
cflag_orphan('N');
}
struct Message scene_msgtab = {
"SCENE", 0, 0, 0, 0,
{mg_unreg, {m_scene, 3}, mg_ignore, mg_ignore, mg_ignore, {m_scene, 3}}
};
/* this serves as an alias for people who are used to inspircd/unreal m_roleplay */
struct Message ambiance_msgtab = {
"AMBIANCE", 0, 0, 0, 0,
{mg_unreg, {m_scene, 3}, mg_ignore, mg_ignore, mg_ignore, {m_scene, 3}}
};
struct Message fsay_msgtab = {
"FSAY", 0, 0, 0, 0,
{mg_unreg, {m_npc, 4}, mg_ignore, mg_ignore, mg_ignore, {m_fsay, 4}}
};
struct Message faction_msgtab = {
"FACTION", 0, 0, 0, 0,
{mg_unreg, {m_npca, 4}, mg_ignore, mg_ignore, mg_ignore, {m_faction, 4}}
};
struct Message npc_msgtab = {
"NPC", 0, 0, 0, 0,
{mg_unreg, {m_npc, 4}, mg_ignore, mg_ignore, mg_ignore, {m_npc, 4}}
};
struct Message npca_msgtab = {
"NPCA", 0, 0, 0, 0,
{mg_unreg, {m_npca, 4}, mg_ignore, mg_ignore, mg_ignore, {m_npca, 4}}
};
struct Message roleplay_msgtab = {
"ROLEPLAY", 0, 0, 0, 0,
{mg_ignore, mg_ignore, mg_ignore, mg_ignore, {me_roleplay, 4}, mg_ignore}
};
mapi_clist_av1 roleplay_clist[] = { &scene_msgtab, &ambiance_msgtab, &fsay_msgtab, &faction_msgtab, &npc_msgtab, &npca_msgtab, &roleplay_msgtab, NULL };
DECLARE_MODULE_AV2(roleplay, _modinit, _moddeinit, roleplay_clist, NULL, NULL, NULL, NULL, roleplay_desc);
static void
m_scene(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
m_displaymsg(msgbuf_p, source_p, parv[1], 0, 0, "=Scene=", parv[2]);
}
static void
m_fsay(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
m_displaymsg(msgbuf_p, source_p, parv[1], 0, 0, parv[2], parv[3]);
}
static void
m_faction(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
m_displaymsg(msgbuf_p, source_p, parv[1], 0, 1, parv[2], parv[3]);
}
static void
m_npc(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
m_displaymsg(msgbuf_p, source_p, parv[1], 1, 0, parv[2], parv[3]);
}
static void
m_npca(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
m_displaymsg(msgbuf_p, source_p, parv[1], 1, 1, parv[2], parv[3]);
}
static void
m_displaymsg(struct MsgBuf *msgbuf_p, struct Client *source_p, const char *channel, int underline, int action, const char *nick, const char *text)
{
struct Channel *chptr;
struct membership *msptr;
char nick2[NICKLEN+1];
char nick3[NICKLEN+1];
char text3[BUFSIZE];
char text2[BUFSIZE];
rb_strlcpy(nick3, nick, sizeof nick3);
if(!IsFloodDone(source_p))
flood_endgrace(source_p);
if((chptr = find_channel(channel)) == NULL)
{
sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL,
form_str(ERR_NOSUCHCHANNEL), channel);
return;
}
if(!(msptr = find_channel_membership(chptr, source_p)))
{
sendto_one_numeric(source_p, ERR_NOTONCHANNEL,
form_str(ERR_NOTONCHANNEL), chptr->chname);
return;
}
if(!(chptr->mode.mode & chmode_flags['N']))
{
sendto_one_numeric(source_p, 573, "%s :Roleplay commands are not enabled on this channel.", chptr->chname);
return;
}
if(!can_send(chptr, source_p, msptr))
{
sendto_one_numeric(source_p, 573, "%s :Cannot send to channel.", chptr->chname);
return;
}
/* enforce flood stuff on roleplay commands */
if(flood_attack_channel(0, source_p, chptr, chptr->chname))
return;
/* enforce target change on roleplay commands */
if(!is_chanop_voiced(msptr) && !IsOper(source_p) && !add_channel_target(source_p, chptr))
{
sendto_one(source_p, form_str(ERR_TARGCHANGE),
me.name, source_p->name, chptr->chname);
return;
}
if(underline)
snprintf(nick2, sizeof(nick2), "\x1F%s\x1F", strip_unprintable(nick3));
else
snprintf(nick2, sizeof(nick2), "%s", strip_unprintable(nick3));
/* don't allow nicks to be empty after stripping
* this prevents nastiness like fake factions, etc. */
if(EmptyString(nick3))
{
sendto_one_numeric(source_p, 573, "%s :No visible non-stripped characters in nick.", chptr->chname);
return;
}
snprintf(text3, sizeof(text3), "%s (%s)", text, source_p->name);
if(action)
snprintf(text2, sizeof(text2), "\1ACTION %.500s\1", text3);
else
snprintf(text2, sizeof(text2), "%s", text3);
sendto_channel_local(source_p, ALL_MEMBERS, chptr, ":%s!%s@npc.fakeuser.invalid PRIVMSG %s :%s", nick2, source_p->name, channel, text2);
sendto_match_servs(source_p, "*", CAP_ENCAP, NOCAPS, "ENCAP * ROLEPLAY %s %s :%s",
channel, nick2, text2);
}
static void
me_roleplay(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
struct Channel *chptr;
/* Don't segfault if we get ROLEPLAY with an invalid channel.
* This shouldn't happen but it's best to be on the safe side. */
if((chptr = find_channel(parv[1])) == NULL)
return;
sendto_channel_local(source_p, ALL_MEMBERS, chptr, ":%s!%s@npc.fakeuser.invalid PRIVMSG %s :%s", parv[2], source_p->name, parv[1], parv[3]);
}

View file

@ -1,176 +0,0 @@
/*
* Solanum: a slightly advanced ircd
* shedding.c: Enables/disables user shedding.
*
* Based on oftc-hybrid's m_shedding.c
*
* Copyright (C) 2021 David Schultz <me@zpld.me>
* Copyright (C) 2002 by the past and present ircd coders, and others.
*
* 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 "hook.h"
#include "client.h"
#include "ircd.h"
#include "send.h"
#include "s_conf.h"
#include "s_serv.h"
#include "s_newconf.h"
#include "messages.h"
#include "numeric.h"
#define SHED_RATE_MIN 5
static struct ev_entry *user_shedding_ev = NULL;
static const char shed_desc[] = "Enables/disables user shedding.";
static void mo_shedding(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char *parv[]);
static void me_shedding(struct MsgBuf *msgbuf, struct Client *client_p, struct Client *source_p, int parc, const char *parv[]);
static void do_user_shedding(void *unused);
static struct Message shedding_msgtab = {
"SHEDDING", 0, 0, 0, 0,
{mg_unreg, mg_not_oper, mg_ignore, mg_ignore, {me_shedding, 2}, {mo_shedding, 3}}
};
mapi_clist_av1 shedding_clist[] = { &shedding_msgtab, NULL };
static void
moddeinit(void)
{
rb_event_delete(user_shedding_ev);
}
DECLARE_MODULE_AV2(shed, NULL, moddeinit, shedding_clist, NULL, NULL, NULL, NULL, shed_desc);
static void
set_shedding_state(struct Client *source_p, const char *chr, const char *reason)
{
int rate;
if (irccmp(chr, "OFF") == 0)
{
// disable shedding
sendto_realops_snomask(SNO_GENERAL, L_ALL | L_NETWIDE, "%s disabled user shedding", get_oper_name(source_p));
rb_event_delete(user_shedding_ev);
user_shedding_ev = NULL;
return;
}
rate = atoi(chr);
if(rate < SHED_RATE_MIN)
{
sendto_one_notice(source_p, "Shedding rate must be at least %d", SHED_RATE_MIN);
return;
}
sendto_realops_snomask(SNO_GENERAL, L_ALL | L_NETWIDE, "%s enabled user shedding (interval: %d seconds, reason: %s)",
get_oper_name(source_p), rate, reason);
rb_event_delete(user_shedding_ev);
user_shedding_ev = NULL;
user_shedding_ev = rb_event_add("user shedding event", do_user_shedding, NULL, rate);
}
/*
* mo_shedding
*
* inputs - pointer to server
* - pointer to client
* - parameter count
* - parameter list
* output -
* side effects - user shedding is enabled or disabled
*
* SHEDDING <server> OFF - disable shedding
* SHEDDING <server> <approx_seconds_per_userdrop> :<reason>
* (parv[#] 1 2 3)
*
*/
static void
mo_shedding(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
if (!HasPrivilege(source_p, "oper:shedding"))
{
sendto_one(source_p, form_str(ERR_NOPRIVS), me.name, source_p->name, "SHEDDING");
return;
}
/* I can think of a thousand ways this could go wrong... */
if (strchr(parv[1], '*') != NULL)
{
sendto_one_notice(source_p, "Wildcards are not permitted for shedding targets");
return;
}
if (parc != 4 && !(parc == 3 && irccmp(parv[2], "OFF") == 0))
{
sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
me.name, source_p->name, "SHEDDING");
return;
}
if (irccmp(parv[1], me.name) != 0) {
/* it's not for us, pass it around */
if (irccmp(parv[2], "OFF") == 0)
sendto_match_servs(source_p, parv[1],
CAP_ENCAP, NOCAPS,
"ENCAP %s SHEDDING OFF", parv[1]);
else
sendto_match_servs(source_p, parv[1],
CAP_ENCAP, NOCAPS,
"ENCAP %s SHEDDING %s :%s",
parv[1], parv[2], parv[3]);
return;
}
set_shedding_state(source_p, parv[2], parv[3]);
}
static void
me_shedding(struct MsgBuf *msgbuf, struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
if(!IsPerson(source_p))
return;
set_shedding_state(source_p, parv[1], parv[2]);
}
static void
do_user_shedding(void *unused)
{
rb_dlink_node *ptr;
struct Client *client_p;
RB_DLINK_FOREACH_PREV(ptr, lclient_list.tail)
{
client_p = ptr->data;
if (!IsClient(client_p)) /* It could be servers */
continue;
if (IsExemptKline(client_p))
continue;
exit_client(client_p, client_p, &me, "Server closed connection");
break;
}
}

View file

@ -67,7 +67,7 @@ mapi_clist_av1 webirc_clist[] = { &webirc_msgtab, NULL };
static void new_local_user(void *data);
mapi_hfn_list_av1 webirc_hfnlist[] = {
/* unintuitive but correct--we want to be called first */
{ "new_local_user", new_local_user, HOOK_LOWEST },
{ "new_local_user", (hookfn) new_local_user, HOOK_LOWEST },
{ NULL, NULL }
};
@ -75,8 +75,8 @@ DECLARE_MODULE_AV2(webirc, NULL, NULL, webirc_clist, NULL, webirc_hfnlist, NULL,
/*
* mr_webirc - webirc message handler
* parv[1] = password
* parv[2] = fake username (we ignore this)
* parv[1] = password
* parv[2] = fake username (we ignore this)
* parv[3] = fake hostname
* parv[4] = fake ip
*/
@ -89,34 +89,27 @@ mr_webirc(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *sourc
int secure = 0;
if (source_p->flags & FLAGS_SENTUSER || !EmptyString(source_p->name))
{
exit_client(client_p, source_p, &me, "WEBIRC may not follow NICK/USER");
}
aconf = find_address_conf(client_p->host, client_p->sockhost,
IsGotId(client_p) ? client_p->username : "webirc",
IsGotId(client_p) ? client_p->username : "webirc",
(struct sockaddr *) &client_p->localClient->ip,
GET_SS_FAMILY(&client_p->localClient->ip), NULL);
if (aconf == NULL || !(aconf->status & CONF_CLIENT))
return;
if (!IsConfDoSpoofIp(aconf) || irccmp(aconf->info.name, "webirc."))
{
/* XXX */
exit_client(client_p, source_p, &me, "Not a CGI:IRC auth block");
sendto_one(source_p, "NOTICE * :Not a CGI:IRC auth block");
return;
}
if (EmptyString(aconf->passwd))
{
exit_client(client_p, source_p, &me, "CGI:IRC auth blocks must have a password");
sendto_one(source_p, "NOTICE * :CGI:IRC auth blocks must have a password");
return;
}
if (!IsSecure(source_p) && aconf->flags & CONF_FLAGS_NEED_SSL)
if (!IsSSL(source_p) && aconf->flags & CONF_FLAGS_NEED_SSL)
{
exit_client(client_p, source_p, &me, "Your CGI:IRC block requires TLS");
sendto_one(source_p, "NOTICE * :Your CGI:IRC block requires TLS");
return;
}
@ -129,19 +122,17 @@ mr_webirc(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *sourc
if (encr == NULL || strcmp(encr, aconf->passwd))
{
exit_client(client_p, source_p, &me, "CGI:IRC password incorrect");
sendto_one(source_p, "NOTICE * :CGI:IRC password incorrect");
return;
}
if (rb_inet_pton_sock(parv[4], &addr) <= 0)
{
exit_client(client_p, source_p, &me, "Invalid IP");
sendto_one(source_p, "NOTICE * :Invalid IP");
return;
}
source_p->localClient->ip = addr;
source_p->username[0] = '\0';
ClearGotId(source_p);
if (parc >= 6)
{
@ -153,7 +144,7 @@ mr_webirc(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *sourc
}
}
if (secure && !IsSecure(source_p))
if (secure && !IsSSL(source_p))
{
sendto_one(source_p, "NOTICE * :CGI:IRC is not connected securely; marking you as insecure");
secure = 0;
@ -161,7 +152,7 @@ mr_webirc(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *sourc
if (!secure)
{
ClearSecure(source_p);
SetInsecure(source_p);
}
rb_inet_ntop_sock((struct sockaddr *)&source_p->localClient->ip, source_p->sockhost, sizeof(source_p->sockhost));
@ -191,9 +182,6 @@ new_local_user(void *data)
struct Client *source_p = data;
struct ConfItem *aconf = source_p->localClient->att_conf;
if (aconf == NULL)
return;
if (!irccmp(aconf->info.name, "webirc."))
exit_client(source_p, source_p, &me, "Cannot log in using a WEBIRC block");
}

View file

@ -25,7 +25,7 @@ static const char nokill_desc[] = "Prevents operators from killing services";
static void block_services_kill(void *data);
mapi_hfn_list_av1 no_kill_services_hfnlist[] = {
{ "can_kill", block_services_kill },
{ "can_kill", (hookfn) block_services_kill },
{ NULL, NULL }
};

View file

@ -14,19 +14,18 @@
static const char no_locops_desc[] = "Disables local operators";
static void h_nl_umode_changed(void *);
static void h_nl_umode_changed(hook_data_umode_changed *);
mapi_hfn_list_av1 nl_hfnlist[] = {
{ "umode_changed", h_nl_umode_changed },
{ "umode_changed", (hookfn) h_nl_umode_changed },
{ NULL, NULL }
};
DECLARE_MODULE_AV2(no_locops, NULL, NULL, NULL, NULL, nl_hfnlist, NULL, NULL, no_locops_desc);
static void
h_nl_umode_changed(void *data)
h_nl_umode_changed(hook_data_umode_changed *hdata)
{
hook_data_umode_changed *hdata = data;
struct Client *source_p = hdata->client;
if (MyClient(source_p) && source_p->umodes & UMODE_LOCOPS)

View file

@ -16,19 +16,18 @@
static const char noi_desc[] =
"Disallow operators from setting user mode +i on themselves";
static void h_noi_umode_changed(void *);
static void h_noi_umode_changed(hook_data_umode_changed *);
mapi_hfn_list_av1 noi_hfnlist[] = {
{ "umode_changed", h_noi_umode_changed },
{ "umode_changed", (hookfn) h_noi_umode_changed },
{ NULL, NULL }
};
DECLARE_MODULE_AV2(no_oper_invis, NULL, NULL, NULL, NULL, noi_hfnlist, NULL, NULL, noi_desc);
static void
h_noi_umode_changed(void *data)
h_noi_umode_changed(hook_data_umode_changed *hdata)
{
hook_data_umode_changed *hdata = data;
struct Client *source_p = hdata->client;
if (MyClient(source_p) && IsOper(source_p) && !IsOperInvis(source_p) &&

View file

@ -1,5 +1,5 @@
/*
* oper-override for solanum.
* oper-override for charybdis.
*
* adds usermode +p and has a timer event that is iterated over to disable
* usermode +p after a while...
@ -30,17 +30,15 @@ static void hack_channel_access(void *data);
static void hack_can_join(void *data);
static void hack_can_kick(void *data);
static void hack_can_send(void *data);
static void hack_can_invite(void *data);
static void handle_client_exit(void *data);
mapi_hfn_list_av1 override_hfnlist[] = {
{ "umode_changed", check_umode_change },
{ "get_channel_access", hack_channel_access, HOOK_HIGHEST },
{ "can_join", hack_can_join, HOOK_HIGHEST },
{ "can_kick", hack_can_kick, HOOK_HIGHEST },
{ "can_send", hack_can_send, HOOK_HIGHEST },
{ "can_invite", hack_can_invite, HOOK_HIGHEST },
{ "client_exit", handle_client_exit },
{ "umode_changed", (hookfn) check_umode_change },
{ "get_channel_access", (hookfn) hack_channel_access, HOOK_HIGHEST },
{ "can_join", (hookfn) hack_can_join, HOOK_HIGHEST },
{ "can_kick", (hookfn) hack_can_kick, HOOK_HIGHEST },
{ "can_send", (hookfn) hack_can_send, HOOK_HIGHEST },
{ "client_exit", (hookfn) handle_client_exit },
{ NULL, NULL }
};
@ -57,27 +55,25 @@ struct OverrideSession {
rb_dlink_list overriding_opers = { NULL, NULL, 0 };
static void
update_session_deadline(struct Client *source_p)
update_session_deadline(struct Client *source_p, struct OverrideSession *session_p)
{
struct OverrideSession *session_p = NULL;
rb_dlink_node *n;
RB_DLINK_FOREACH(n, overriding_opers.head)
if (session_p == NULL)
{
struct OverrideSession *s = n->data;
rb_dlink_node *n;
if (s->client == source_p)
RB_DLINK_FOREACH(n, overriding_opers.head)
{
session_p = s;
break;
struct OverrideSession *s = n->data;
if (s->client == source_p)
{
session_p = s;
break;
}
}
}
if (session_p != NULL)
{
rb_dlinkDelete(&session_p->node, &overriding_opers);
}
else
if (session_p == NULL)
{
session_p = rb_malloc(sizeof(struct OverrideSession));
session_p->client = source_p;
@ -85,7 +81,8 @@ update_session_deadline(struct Client *source_p)
session_p->deadline = rb_current_time() + 1800;
rb_dlinkAddTail(session_p, &session_p->node, &overriding_opers);
rb_dlinkDelete(&session_p->node, &overriding_opers);
rb_dlinkAdd(session_p, &session_p->node, &overriding_opers);
}
static void
@ -97,11 +94,9 @@ expire_override_deadlines(void *unused)
{
struct OverrideSession *session_p = n->data;
if (session_p->deadline >= rb_current_time())
{
if (session_p->deadline > rb_current_time())
break;
}
else
else if (session_p->deadline < rb_current_time())
{
const char *parv[4] = {session_p->client->name, session_p->client->name, "-p", NULL};
user_mode(session_p->client, session_p->client, 3, parv);
@ -135,7 +130,7 @@ check_umode_change(void *vdata)
if (changed)
{
update_session_deadline(source_p);
update_session_deadline(source_p, NULL);
}
}
else if (changed && !(source_p->umodes & user_modes['p']))
@ -168,7 +163,7 @@ hack_channel_access(void *vdata)
if (data->client->umodes & user_modes['p'])
{
update_session_deadline(data->client);
update_session_deadline(data->client, NULL);
data->approved = CHFL_OVERRIDE;
/* we only want to report modehacks, which are always non-NULL */
@ -188,7 +183,7 @@ hack_can_join(void *vdata)
if (data->client->umodes & user_modes['p'])
{
update_session_deadline(data->client);
update_session_deadline(data->client, NULL);
data->approved = 0;
sendto_realops_snomask(SNO_GENERAL, L_NETWIDE, "%s is using oper-override on %s (banwalking)",
@ -208,7 +203,7 @@ hack_can_kick(void *vdata)
if (data->client->umodes & user_modes['p'])
{
update_session_deadline(data->client);
update_session_deadline(data->client, NULL);
sendto_realops_snomask(SNO_GENERAL, L_NETWIDE, "%s is using oper-override on %s (KICK %s)",
get_oper_name(data->client), data->chptr->chname, data->target->name);
}
@ -231,30 +226,13 @@ hack_can_send(void *vdata)
if (MyClient(data->client))
{
update_session_deadline(data->client);
update_session_deadline(data->client, NULL);
sendto_realops_snomask(SNO_GENERAL, L_NETWIDE, "%s is using oper-override on %s (forcing message)",
get_oper_name(data->client), data->chptr->chname);
}
}
}
static void
hack_can_invite(void *vdata)
{
hook_data_channel_approval *data = vdata;
if (data->approved == 0)
return;
if (data->client->umodes & user_modes['p'])
{
data->approved = 0;
update_session_deadline(data->client);
sendto_realops_snomask(SNO_GENERAL, L_NETWIDE, "%s is using oper-override on %s (invite: %s)",
get_oper_name(data->client), data->chptr->chname, data->target->name);
}
}
static void
handle_client_exit(void *vdata)
{
@ -289,7 +267,7 @@ _modinit(void)
{
struct Client *client_p = ptr->data;
if (IsPerson(client_p) && (client_p->umodes & user_modes['p']))
update_session_deadline(client_p);
update_session_deadline(client_p, NULL);
}
expire_override_deadlines_ev = rb_event_add("expire_override_deadlines", expire_override_deadlines, NULL, 60);

View file

@ -14,7 +14,7 @@ static const char override_kick_immunity_desc[] =
static void can_kick(void *data);
mapi_hfn_list_av1 override_kick_immunity_hfnlist[] = {
{ "can_kick", can_kick, HOOK_HIGHEST },
{ "can_kick", (hookfn) can_kick, HOOK_HIGHEST },
{ NULL, NULL }
};

Some files were not shown because too many files have changed in this diff Show more