Compare commits

..

No commits in common. "merging-solanum-into-hackint" and "solanum" have entirely different histories.

98 changed files with 34 additions and 93264 deletions

View file

@ -1,58 +0,0 @@
# Travis-CI Build for charybdis-3.5
# see travis-ci.org for details
language: c
# Use the faster container-based infrastructure.
sudo: false
matrix:
include:
- os: linux
compiler: gcc
addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['gcc-4.8', 'automake', 'autoconf', 'libtool', 'shtool', 'libsqlite3-dev', 'python-sphinx', 'texinfo']
env: COMPILER=gcc-4.8
- os: linux
compiler: gcc
addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['gcc-4.9', 'automake', 'autoconf', 'libtool', 'shtool', 'libsqlite3-dev', 'python-sphinx', 'texinfo']
env: COMPILER=gcc-4.9
- os: linux
compiler: gcc
addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['gcc-5', 'automake', 'autoconf', 'libtool', 'shtool', 'libsqlite3-dev', 'python-sphinx', 'texinfo']
env: COMPILER=gcc-5
- os: linux
compiler: clang
addons:
apt:
sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-precise-3.7']
packages: ['clang-3.7', 'automake', 'autoconf', 'libtool', 'shtool', 'libsqlite3-dev', 'python-sphinx', 'texinfo']
env: COMPILER=clang-3.7
- os: osx
compiler: clang
env: COMPILER=clang LIBTOOLIZE=glibtoolize
osx_image: xcode7.3
cache:
apt:
ccache:
script:
- CC=$COMPILER ./configure --with-shared-sqlite
- make -j4
- make install
- "if [ ${TRAVIS_OS_NAME} != 'osx' ]; then make -C doc/oper-guide html man info; fi"

43
CREDITS
View file

@ -1,45 +1,3 @@
<<<<<<< .merge_file_qEvahK
Charybdis started as an evolution from ircd-ratbox. Its development
is led by a team of dedicated developers who have put a lot of time
into the project, and it has seen use on a variety of different
network configurations.
The Charybdis core team, listed in nick-alphabetical order:
amdj, Aaron Jones <aaronmdjones -at- gmail.com>
Elizafox, Elizabeth Myers <elizabeth -at- interlinked.me>
jilles, Jilles Tjoelker <jilles -at- stack.nl>
kaniini, William Pitcock <nenolod -at- dereferenced.org>
mr_flea, Keith Buck <mr_flea -at- esper.net>
Simon, Simon Arlott <charybdis -at- uuid.uk>
The following people are also project members, listed in nick-alphabetical
order:
grawity, Mantas Mikulėnas <grawity -at- gmail.com>
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>
dwr, Valery Yatsko <dwr -at- shadowircd.net>
Elizacat, Elizabeth Myers <elizabeth -at- interlinked.me>
Entrope, Michael Poole <mdpoole -at- trolius.org>
gxti, Michael Tharp <gxti -at- partiallystapled.com>
mniip <mniip -at- mniip.com>
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>
Visit the Charybdis website at: http://www.charybdis.io/
Visit us on IRC at: irc.charybdis.io #charybdis
=======
Solanum is based on Charybdis, which was based on ircd-ratbox.
Development is led by a group of representatives from Libera Chat
@ -68,4 +26,3 @@ is in doc/credits-past.txt.
Visit the Solanum website at: https://solanum.chat/
Visit us on IRC at: irc.libera.chat #solanum
>>>>>>> .merge_file_gXRYUC

110
NEWS.md
View file

@ -1,114 +1,5 @@
# News
<<<<<<< .merge_file_h36DbE
This is charybdis 3.5.7, Copyright (c) 2005-2019 Charybdis team.
See LICENSE for licensing details (GPL v2).
## charybdis-3.5.7
This is primarily a bugfix release.
### user
- modules/m_sasl.c: don't process messages if SASL has been aborted
- src/s_user.c: don't corrupt usermodes on module unload/reload
### misc
- modules/m_list.c: add fake /LIST reply output to help fight spambots
## charybdis-3.5.6
This is primarily a bugfix release.
### security
- doc/reference.conf: clarify: TLS server fingerprints are not optional
- extensions/extb_ssl.c: add support for matching fingerprints
- libratbox/src/mbedtls.c: check public/private keys match
- libratbox/src/mbedtls.c: support ChaCha20-Poly1305 by default
### user
- libratbox/src/commio.c: fix accept() for IPv6 after dropping IPv4
- src/client.c: don't delete servers from the client hash table
- src/s_user.c: don't send fake MODE for clients with CHGHOST support
- modules/m_sasl.c: abort session if we receive '*' as data
- modules/m_sasl.c: check agent is present after every client exit
### misc
- configure: adjust dlopen/dlsym checks to work under libasan
- configure: allow exact PID file prefix to be specified
- doc/: convert SGML oper guide to RST
- doc/: point users to HELP EXTBAN for inline help
- extensions/m_webirc.c: set sockhost before using it to set host
## charybdis-3.5.5
This is a minor bugfix release only
### misc
- GNUTLS: Initialise a variable before trying to load server certificates
- GNUTLS: Log why certificate fingerprint generation fails
- GNUTLS: Avoid using new tokens in the default priority string
## charybdis-3.5.4
### security
- Disable TLSv1.0 in all backends
- Fix possible NULL dereference in mkpasswd
- Backport SubjectPublicKeyInfo certificate digest methods from version 4
- Backport REHASH SSLD functionality from version 4
- This allows new ssld processes to be started (to inherit a new or upgraded TLS backend
library) without dropping any existing clients or active server links
### misc
- Various memory leak fixes in newconf, sslproc, zlib
- Fix crash bug when performing /whois on someone half-way through a CHALLENGE
- Fix crash bug when performing remote MODRESTART command
- Allow extban matching presence in secret (+s) channels
## charybdis-3.5.3
### security
- incorporate all relevant security patches for charybdis through 6th September 2016:
- fix issue allowing EXTERNAL authentications to be spoofed using a certificate not actually
held by the authenticating user
### misc
- mbedtls TLS backend improvements from charybdis 4 and 5:
- add support for configurable ciphersuites
- disable legacy (SSLv2) renegotiation support if possible
- disable session tickets if possible
- general robustness improvements
- gnutls TLS backend improvements from charybdis 4:
- make certfp support more reliable on newer gnutls versions
- avoid possible null dereference when constructing ciphersuites
- openssl TLS backend improvements from charybdis 4:
- avoid a possible use-after-free issue when newer openssl versions cannot load keypairs in a rehash
- improve compatibility with libressl
- more robustly load DH parameters files
- daemonization improvements from charybdis 4
## charybdis-3.5.2
### user
- Allow IRCv3.1 STARTTLS to work with other SSL backends besides OpenSSL.
- Fix an edge case regression involving channel ban cache that was introduced in 3.5.0.
### misc
- Ensure ssld does not crash when DH parameters are not provided.
- mbedtls TLS backend improvements from charybdis 4:
- add support for CertFP
- provide personalization data for the PRNG
- fix library linking order
- openssl TLS backend improvements from charybdis 4:
- do not manually initialise openssl when running with OpenSSL 1.1.0 or later
- support ECDHE on more than one curve on OpenSSL 1.0.2 and above
- fix DH parameters memory leak
- free the old TLS context before constructing a new one (#186)
## charybdis-3.5.1
### misc
- Backport various ssld IPC improvements from master.
=======
This is solanum 1.0-dev.
See LICENSE for licensing details (GPL v2).
@ -306,7 +197,6 @@ bolded warnings in the full release notes below.
- Support for ratbox-style 'iodebug' hooks has been removed.
- New channel types may be added by modules, see `extensions/chantype_dummy.c`
for a very simple example.
>>>>>>> .merge_file_4c8glm
## charybdis-3.5.0

View file

@ -60,38 +60,21 @@ See `./configure --help` for build options.
* For SSL/TLS client and server connections, one of:
<<<<<<< .merge_file_7Huc5m
* OpenSSL 1.0.0 or newer (--enable-openssl)
* LibreSSL (--enable-openssl)
* MbedTLS (--enable-mbedtls)
* GnuTLS (--enable-gnutls)
=======
* OpenSSL 1.0.0 or newer (`--enable-openssl`)
* LibreSSL (`--enable-openssl`)
* mbedTLS (`--enable-mbedtls`)
* GnuTLS (`--enable-gnutls`)
>>>>>>> .merge_file_dqpn0B
* For certificate-based oper CHALLENGE, OpenSSL 1.0.0 or newer.
(Using CHALLENGE is not recommended for new deployments, so if you want to use a different TLS library,
feel free.)
<<<<<<< .merge_file_7Huc5m
* For ECDHE under OpenSSL, on Solaris and RHEL/Fedora (and its derivatives such as CentOS) you will
need to compile your own OpenSSL on these systems, as they have removed support for ECC/ECDHE.
Alternatively, consider using another library (see above).
# tips
* To report bugs in charybdis, visit us on IRC at chat.freenode.net #charybdis
=======
* For ECDHE under OpenSSL, on Solaris you will need to compile your own OpenSSL on these systems, as they
have removed support for ECC/ECDHE. Alternatively, consider using another library (see above).
# tips
* To report bugs in Solanum, visit us at `#solanum` on [Libera Chat](https://libera.chat)
>>>>>>> .merge_file_dqpn0B
* Please read [doc/readme.txt](doc/readme.txt) to get an overview of the current documentation.

16
aclocal.m4 vendored
View file

@ -1,16 +0,0 @@
# generated automatically by aclocal 1.15.1 -*- Autoconf -*-
# Copyright (C) 1996-2017 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
m4_include([m4/charybdis.m4])
m4_include([m4/pkg.m4])

View file

@ -1,2 +0,0 @@
except:
- release/3.5

View file

@ -236,14 +236,10 @@ parse_request(rb_helper *helper)
}
<<<<<<< .merge_file_OcfD4C
static void __attribute__((noreturn))
=======
static void
error_cb(rb_helper *helper) __attribute__((noreturn));
static void
>>>>>>> .merge_file_OF4zx2
error_cb(rb_helper *helper)
{
if(in_transaction)
@ -285,14 +281,10 @@ setup_signals(void)
}
<<<<<<< .merge_file_OcfD4C
static void __attribute__((noreturn))
=======
static void
db_error_cb(const char *errstr) __attribute__((noreturn));
static void
>>>>>>> .merge_file_OF4zx2
db_error_cb(const char *errstr)
{
char buf[256];
@ -318,7 +310,8 @@ main(int argc, char *argv[])
rsdb_init(db_error_cb);
check_schema();
rb_helper_loop(bandb_helper, 0);
/* UNREACHABLE */
return 0;
}
static void

View file

@ -141,7 +141,7 @@ main(int argc, char *argv[])
{
case 'h':
print_help(EXIT_SUCCESS);
/* noreturn call above, this is unreachable */
break;
case 'i':
flag.none = false;
flag.import = true;
@ -861,8 +861,8 @@ bt_smalldate(const char *string)
/**
* you are here ->.
*/
static void
print_help(const int i_exit)
void
print_help(int i_exit)
{
fprintf(stderr, "bantool v.%s - the solanum database tool.\n", BT_VERSION);
fprintf(stderr, "Copyright (C) 2008 Daniel J Reidy <dubkat@gmail.com>\n");
@ -892,6 +892,5 @@ print_help(const int i_exit)
fprintf(stderr,
" path : An optional directory containing old ratbox configs for import, or export.\n");
fprintf(stderr, " If not specified, it looks in PREFIX/etc.\n");
exit(i_exit);
}

11453
configure vendored

File diff suppressed because it is too large Load diff

View file

@ -12,13 +12,9 @@ AC_GNU_SOURCE
AC_PROG_CC_C99
<<<<<<< .merge_file_E9kQwr
AC_INIT([charybdis], [3.5.7])
=======
if test x"$ac_cv_prog_cc_c99" = "xno"; then
AC_ERROR([solanum requires a C99 capable compiler])
fi
>>>>>>> .merge_file_knjbyY
AC_PREFIX_DEFAULT($HOME/ircd)
AC_CONFIG_MACRO_DIR([m4])
@ -118,6 +114,7 @@ AS_IF([test "x$enable_fhs_paths" = "xyes"],
pkglibdir='${libdir}/${PACKAGE_TARNAME}'
AC_SUBST([pkglibdir])
AC_SUBST([rundir])
AC_SUBST([pkgrundir])
AC_SUBST([pkglocalstatedir])
AC_DEFINE_DIR([PKGLOCALSTATEDIR], [pkglocalstatedir], [[Directory in which to store state, such as ban database]])
AC_SUBST([pkglibexecdir])
@ -395,40 +392,21 @@ AC_ARG_WITH(moduledir,
AC_DEFINE_DIR(MODULE_DIR, moduledir, [Prefix where modules are installed.])
AC_SUBST_DIR([moduledir])
dnl **********************************************************************
dnl Check for --with-rundir
dnl **********************************************************************
AC_MSG_CHECKING([whether to modify rundir])
AC_MSG_CHECKING([whether or modify rundir])
AC_ARG_WITH([rundir],
[AC_HELP_STRING([--with-rundir=DIR],
[Directory to use as prefix for pidfile.])],
[Directory in which to store pidfile.])],
[AC_MSG_RESULT([yes])
rundir=`echo $withval | sed 's/\/$//'`],
[AC_MSG_RESULT([no])
AS_IF([test "x$enable_fhs_paths" = "xyes"],
[rundir='${prefix}/run'],
[rundir='${sysconfdir}'])])
dnl **********************************************************************
dnl Check for --with-pkgrundir
dnl **********************************************************************
AC_MSG_CHECKING([whether to modify pkgrundir])
AC_ARG_WITH([pkgrundir],
[AC_HELP_STRING([--with-pkgrundir=DIR],
[Directory in which to store pidfile.])],
[AC_MSG_RESULT([yes])
pkgrundir=`echo $withval | sed 's/\/$//'`],
[AC_MSG_RESULT([no])])
AC_SUBST([pkgrundir])
AC_SUBST([rundir])
AC_DEFINE_DIR([PKGRUNDIR], [pkgrundir], [Directory to store pidfile in.])
dnl **********************************************************************
dnl Check for --with-program-prefix
dnl **********************************************************************
dnl Installed utility program prefixes (does not affect binaries
dnl installed into pkglibexecdir)
AC_MSG_CHECKING([for program prefix])
@ -465,16 +443,8 @@ AC_HELP_STRING([--with-custom-version=NAME],
AC_MSG_RESULT([no])]
)
if git rev-parse --git-dir > /dev/null 2>&1; then
GITSHA=$(git rev-parse --short HEAD)
else
GITSHA="unknown"
fi
AC_DEFINE_UNQUOTED(BRANDING_NAME, ["$BRANDING_NAME"], [Custom branding name.])
AC_DEFINE_UNQUOTED(BRANDING_VERSION, ["${BRANDING_VERSION}-${GITSHA}"], [Custom branding name.])
AC_DEFINE_UNQUOTED(BRANDING_VERSION, ["$BRANDING_VERSION"], [Custom branding name.])
if test "x$BRANDING_NAME" != "x$PACKAGE_NAME"; then
AC_DEFINE(CUSTOM_BRANDING, 1, [Define if custom branding is enabled.])
@ -574,135 +544,12 @@ AC_DEFINE_UNQUOTED(TOPICLEN, ${TOPICLEN}, [Maximum topic length (<=390)])
AC_DEFINE_UNQUOTED(NICKLEN, (${NICKLEN}+1), [Nickname length])
<<<<<<< .merge_file_E9kQwr
dnl Second stage: check for functions and headers.
if test "$shared_modules" = yes; then
DYNLINK_C=dynlink.c
AC_CHECK_HEADERS(dlfcn.h)
AC_SEARCH_LIBS(shl_load, dld,
[
AC_DEFINE(HAVE_SHL_LOAD, 1, [Define if the shl_load function is available.])
SUFFIX=".sl"
MOD_TARGET=hpux_shared
SEDOBJ="s/\.o/.sl/g"
],
dnl !shl_load:
[
dnl standard dlopen
AC_SEARCH_LIBS(dlopen, [dl c_r],
[
AC_SEARCH_LIBS(dlsym, [dl c_r],
[
if
test "$ac_cv_search_dlopen" != "none required" &&
test "$ac_cv_search_dlsym" != "none required" &&
test "$ac_cv_search_dlopen" != "$ac_cv_search_dlsym"; then
AC_MSG_WARN([dlopen and dlsym from different sources])
fi
AC_DEFINE(HAVE_DLOPEN, 1, [Define if the dlopen function is available.])
SUFFIX=".so"
MOD_TARGET=shared_modules
SEDOBJ="s/\.o/.so/g"
if test "$AppleGCC" = yes; then
AC_CHECK_HEADERS([mach-o/dyld.h])
fi
AC_CHECK_FUNCS(dlfunc)
],
[
shared_modules=no
])
],
[
shared_modules=no
])
])
fi
AC_DEFINE_UNQUOTED(SHARED_SUFFIX, "$SUFFIX", [Suffix for shared libraries on this platform.])
dnl Third stage - wrangling the linker.
if test "$shared_modules" = yes; then
# The GNU linker requires the -export-dynamic option to make
# all symbols visible in the dynamic symbol table.
hold_ldflags=$LDFLAGS
AC_MSG_CHECKING(for the ld -export-dynamic flag)
LDFLAGS="${LDFLAGS} -Wl,-export-dynamic -Werror"
AC_LINK_IFELSE(AC_LANG_PROGRAM([],[int i;]), found=yes, found=no)
LDFLAGS=$hold_ldflags
if expr "`uname -s`" : ^IRIX >/dev/null 2>&1; then
found="no, IRIX ld uses -B,dynamic"
LDFLAGS="${LDFLAGS} -Wl,-B,dynamic"
fi
if expr "`uname -s`" : ^AIX >/dev/null 2>&1; then
found="no, AIX ld uses -G -brtl"
LDFLAGS="${LDFLAGS} -Wl,-G,-brtl"
fi
AC_MSG_RESULT($found)
if test "$found" = yes; then
LDFLAGS="${LDFLAGS} -Wl,-export-dynamic"
fi
AC_MSG_CHECKING(for compiler option to produce PIC)
dnl The order should be here to check for groups of compilers,
dnl then for odd compilers, then if no PICFLAGS were set up,
dnl check for GCC and set defaults, or else error. -jmallett
if test "$SGS" = "yes"; then
AC_MSG_RESULT([SVR4 SGS interfaces: -KPIC -DPIC -G])
PICFLAGS="-KPIC -DPIC -G"
fi
if test "$AppleGCC" = "yes"; then
AC_MSG_RESULT([Darwin Mach-O bundles: -fno-common -bundle -flat_namespace -undefined suppress])
PICFLAGS="-fno-common -bundle -flat_namespace -undefined suppress"
fi
dnl Please note, that on HPUX two different stages of module compilation occurs, since
dnl while compiling modules, the compiler does not allow you to give arguments
dnl to the linker. (I did not design this)
dnl So we need -c in the first stage of module compilation.
dnl In the second stage, we link the modules via ld -b.
dnl Additionally, HPUX does not like -export-dynamic, it likes -E instead.
dnl -TimeMr14C
if test "$HPUX" = "yes" -a "$CC" != gcc; then
AC_MSG_RESULT(HP-UX cc: +z -r -q -n)
PICFLAGS="+z -r -q -n -c"
AC_MSG_CHECKING([if +ESfic is required on this platform])
if expr "`$CC +ESfic 2>&1`" : ".*neither supported.*" >/dev/null; then
AC_MSG_RESULT(no)
else
AC_MSG_RESULT(yes)
PICFLAGS="$PICFLAGS +ESfic"
fi
LDFLAGS="${LDFLAGS} -Wl,-E"
fi
if test "$Tru" = yes -a "$CC" != gcc; then
AC_MSG_RESULT([Tru64: -shared -expect_unresolved '*'])
PICFLAGS="-shared -expect_unresolved '*' "
LDFLAGS="-call_shared"
fi
if test -z "$PICFLAGS"; then
if test "$ac_cv_c_compiler_gnu" = "yes"; then
AC_MSG_RESULT(gcc: -fPIC -DPIC -shared)
PICFLAGS="-fPIC -DPIC -shared"
else
AC_MSG_RESULT(no)
shared_modules=no
fi
fi
fi
=======
AC_ARG_WITH(asan,
AC_HELP_STRING([--with-asan],[Build with Address Sanitizer]),
[
CFLAGS="$CFLAGS -fsanitize=address"
LDFLAGS="$LDFLAGS -fsanitize=address"
])
>>>>>>> .merge_file_knjbyY
# rpath, for finding librb.so at run time
hold_ldflags=$LDFLAGS

View file

@ -1,26 +0,0 @@
{ stdenv, bash
, flex, bison
, openssl, gnutls, zlib }:
stdenv.mkDerivation {
pname = "charybdis";
version = "3.5.7";
src = ./.;
patches = [
./patches/bandb-remove-setenv.patch
];
configureFlags = [
"--enable-epoll"
"--enable-ipv6"
"--with-zlib-path=${zlib.dev}/lib"
"--enable-openssl=${openssl.dev}"
"--with-program-prefix=charybdis-"
"--sysconfdir=/etc/charybdis"
];
nativeBuildInputs = [ bison flex ];
buildInputs = [ openssl gnutls zlib ];
}

51
doc/ircd.conf.example Executable file → Normal file
View file

@ -8,33 +8,6 @@
*/
/* Extensions */
<<<<<<< .merge_file_MAZNsP
#loadmodule "extensions/chm_operonly_compat.so";
#loadmodule "extensions/chm_quietunreg_compat.so";
#loadmodule "extensions/chm_sslonly_compat.so";
#loadmodule "extensions/createauthonly.so";
#loadmodule "extensions/extb_account.so";
#loadmodule "extensions/extb_canjoin.so";
#loadmodule "extensions/extb_channel.so";
#loadmodule "extensions/extb_combi.so";
#loadmodule "extensions/extb_extgecos.so";
#loadmodule "extensions/extb_hostmask.so";
#loadmodule "extensions/extb_oper.so";
#loadmodule "extensions/extb_realname.so";
#loadmodule "extensions/extb_server.so";
#loadmodule "extensions/extb_ssl.so";
#loadmodule "extensions/extb_usermode.so";
#loadmodule "extensions/hurt.so";
#loadmodule "extensions/m_findforwards.so";
#loadmodule "extensions/m_identify.so";
#loadmodule "extensions/no_oper_invis.so";
#loadmodule "extensions/sno_farconnect.so";
#loadmodule "extensions/sno_globalkline.so";
#loadmodule "extensions/sno_globaloper.so";
#loadmodule "extensions/sno_whois.so";
#loadmodule "extensions/override.so";
#loadmodule "extensions/no_kill_services.so";
=======
#loadmodule "extensions/chm_nonotice";
#loadmodule "extensions/chm_operpeace";
#loadmodule "extensions/createauthonly";
@ -60,7 +33,6 @@
#loadmodule "extensions/sno_globaloper";
#loadmodule "extensions/override";
#loadmodule "extensions/no_kill_services";
>>>>>>> .merge_file_DV7Blq
/*
* IP cloaking extensions: use ip_cloaking_4.0
@ -558,14 +530,6 @@ alias "MS" {
target = "MemoServ";
};
/*
fakechannel "#honeypot" {
topic = "Come in";
users_min = 50;
users_max = 300;
};
*/
general {
hide_error_messages = opers;
hide_spoof_ips = yes;
@ -643,7 +607,6 @@ general {
caller_id_wait = 1 minute;
pace_wait_simple = 1 second;
pace_wait = 10 seconds;
listfake_wait = 180 seconds;
short_motd = no;
ping_cookie = no;
connect_timeout = 30 seconds;
@ -675,17 +638,3 @@ modules {
path = "modules";
path = "modules/autoload";
};
/*
vhost "selfsigned.hades.arpa" {
ssl_private_key = "etc/selfssl.key";
ssl_cert = "etc/selfssl.pem";
};
vhost "oldca.hades.arpa" {
ssl_private_key = "etc/oldssl.key";
ssl_cert = "etc/oldssl2.pem";
ssl_dh_params = "etc/olddh.pem";
ssl_cipher_list = "kEECDH+HIGH:kEDH+HIGH:HIGH:!RC4:!aNULL";;
};
*/

View file

@ -87,21 +87,12 @@ hub
serving as a hub, i.e. have multiple servers connected to it.
vhost
<<<<<<< .merge_file_cTfvge
An optional text field which defines an IP from which to connect
outward to other IRC servers.
vhost6
An optional text field which defines an IPv6 IP from which to
connect outward to other IRC servers.
=======
An optional text field which defines an IPv4 address from which
to connect outward to other IRC servers.
vhost6
An optional text field which defines an IPv6 address from which
to connect outward to other IRC servers.
>>>>>>> .merge_file_3UzJEV
admin {} block
--------------
@ -264,12 +255,9 @@ flags
class
A name of a class to put users matching this auth{} block into.
<<<<<<< .merge_file_cTfvge
=======
umodes
Additional umodes to apply to the default_umodes upon connect.
>>>>>>> .merge_file_3UzJEV
auth {} flags
~~~~~~~~~~~~~
@ -461,13 +449,6 @@ host
``A`` or ``AAAA`` record (no ``CNAME``) and it must be
the primary hostname for inbound connections to work.
<<<<<<< .merge_file_cTfvge
IPv6 addresses must be in ``::`` shortened form; addresses which
then start with a colon must be prepended with a zero, for
example ``0::1``.
=======
>>>>>>> .merge_file_3UzJEV
send\_password
The password to send to the other server.
@ -496,12 +477,8 @@ flags
aftype
The protocol that should be used to connect with, either ipv4 or
<<<<<<< .merge_file_cTfvge
ipv6. This defaults to ipv4 unless host is a numeric IPv6 address.
=======
ipv6. This defaults to neither, allowing connection using either
address family.
>>>>>>> .merge_file_3UzJEV
**connect {} flags**

110
doc/reference.conf Executable file → Normal file
View file

@ -47,69 +47,6 @@
* Charybdis contains several extensions that are not enabled by default.
* To use them, uncomment the lines below.
*
<<<<<<< .merge_file_UmjhEh
* Channel mode +-A (admin only) -- chm_adminonly.so
* Channel mode +-O (oper only) -- chm_operonly.so
* Channel mode +-S (ssl only) -- chm_sslonly.so
* Emulates channel mode +-O (oper only) (+-iI $o) -- chm_operonly_compat.so
* Emulates channel mode +-R (quiet unreg) (+-q $~a) -- chm_quietunreg_compat.so
* Emulates channel mode +-S (ssl only) (+-b $~z) -- chm_sslonly_compat.so
* Restrict channel creation to logged in users -- createauthonly.so
* Account bans (+b $a[:mask]) -- extb_account.so
* Banned from another channel (+b $j:mask) -- extb_canjoin.so
* Other-channel bans (+b $c:mask) -- extb_channel.so
* Combination extbans -- extb_combi.so
* Extended ban (+b $x:mask) -- extb_extgecos.so
* Hostmask bans (for combination extbans) -- extb_hostmask.so
* Oper bans (+b $o) -- extb_oper.so
* Realname (gecos) bans (+b $r:mask) -- extb_realname.so
* Server bans (+b $s:mask) -- extb_server.so
* SSL bans (+b $z) -- extb_ssl.so
* User mode bans (+b $u:modes) -- extb_usermode.so
* HURT system -- hurt.so
* New host mangling (umode +x) -- ip_cloaking_4.0.so
* Old host mangling (umode +h) -- ip_cloaking.so
* Find channel forwards -- m_findforwards.so
* /identify support -- m_identify.so
* Opers cannot be invisible (umode +i) -- no_oper_invis.so
* Far connection notices (snomask +F) -- sno_farconnect.so
* Remote k/d/x line active notices -- sno_globalkline.so
* Remote oper up notices -- sno_globaloper.so
* /whois notifications (snomask +W) -- sno_whois.so
* Oper-override (modehacking only) -- override.so
* Stop services kills -- no_kill_services.so
*/
#loadmodule "extensions/chm_adminonly.so";
#loadmodule "extensions/chm_operonly.so";
#loadmodule "extensions/chm_sslonly.so";
#loadmodule "extensions/chm_operonly_compat.so";
#loadmodule "extensions/chm_quietunreg_compat.so";
#loadmodule "extensions/chm_sslonly_compat.so";
#loadmodule "extensions/createauthonly.so";
#loadmodule "extensions/extb_account.so";
#loadmodule "extensions/extb_canjoin.so";
#loadmodule "extensions/extb_channel.so";
#loadmodule "extensions/extb_combi.so";
#loadmodule "extensions/extb_extgecos.so";
#loadmodule "extensions/extb_hostmask.so";
#loadmodule "extensions/extb_oper.so";
#loadmodule "extensions/extb_realname.so";
#loadmodule "extensions/extb_server.so";
#loadmodule "extensions/extb_ssl.so";
#loadmodule "extensions/extb_usermode.so";
#loadmodule "extensions/hurt.so";
#loadmodule "extensions/ip_cloaking_4.0.so";
#loadmodule "extensions/ip_cloaking.so";
#loadmodule "extensions/m_findforwards.so";
#loadmodule "extensions/m_identify.so";
#loadmodule "extensions/no_oper_invis.so";
#loadmodule "extensions/sno_farconnect.so";
#loadmodule "extensions/sno_globalkline.so";
#loadmodule "extensions/sno_globaloper.so";
#loadmodule "extensions/sno_whois.so";
#loadmodule "extensions/override.so";
#loadmodule "extensions/no_kill_services.so";
=======
* Channel mode +-A (admin only) -- chm_adminonly
* Channel mode +-T (blocks notices) -- chm_nonotice
* Channel mode +-O (oper only) -- chm_operonly
@ -175,7 +112,6 @@
#loadmodule "extensions/override";
#loadmodule "extensions/no_kill_services";
#loadmodule "extensions/umode_hide_idle_time";
>>>>>>> .merge_file_Mh5Whq
/* serverinfo {}: Contains information about the server. (OLD M:) */
serverinfo {
@ -209,12 +145,6 @@ serverinfo {
* This should be an ipv6 IP only.
*/
#vhost6 = "2001:db8:2::6";
<<<<<<< .merge_file_UmjhEh
/* ssl_private_key: our ssl private key */
ssl_private_key = "etc/ssl.key";
=======
>>>>>>> .merge_file_Mh5Whq
/* ssl_cert: certificate (and optionally key) for our ssl server */
ssl_cert = "etc/ssl.pem";
@ -1084,14 +1014,6 @@ alias "MS" {
target = "MemoServ";
};
/*
fakechannel "#honeypot" {
topic = "Come in";
users_min = 50;
users_max = 300;
};
*/
/* The general block contains many of the options that were once compiled
* in options in config.h. The general block is read at start time.
*/
@ -1394,9 +1316,6 @@ general {
*/
pace_wait = 10 seconds;
/* listfake_wait: time until real list command can be used */
listfake_wait = 180 seconds;
/* short motd: send clients a notice telling them to read the motd
* instead of forcing a motd to clients who may simply ignore it.
*/
@ -1546,20 +1465,6 @@ general {
* "SPKI:SHA2-256:" or "SPKI:SHA2-512:" depending on the hash type. These fingerprints
* are not supported on servers running charybdis 3.5.3 or earlier.
*
<<<<<<< .merge_file_UmjhEh
* To generate a fingerprint from a certificate file, run the following:
* $ openssl x509 -outform DER -in your.crt | sha1sum (or sha256sum, or sha512sum)
*
* To generate a SPKI SHA-256 fingerprint, run the following:
* $ openssl x509 -pubkey -noout -in your.crt | openssl pkey -pubin -outform DER | \
* sha256sum | sed -r -e 's/^/SPKI:SHA2-256:/'
*
* To generate a SPKI SHA-512 fingerprint, run the following:
* $ openssl x509 -pubkey -noout -in your.crt | openssl pkey -pubin -outform DER | \
* sha512sum | sed -r -e 's/^/SPKI:SHA2-512:/'
*/
certfp_method = sha256;
=======
* To generate a fingerprint from a certificate file, please use the mkfingerprint utility
* program located in the bin/ subdirectory of your IRCd installation. Running it with no
* arguments will give you a brief usage message; it takes method and filename arguments.
@ -1585,7 +1490,6 @@ general {
* requires extensions/drain to be loaded.
*/
drain_reason = "This server is not accepting connections.";
>>>>>>> .merge_file_Mh5Whq
};
modules {
@ -1598,17 +1502,3 @@ modules {
/* module: the name of a module to load on startup/rehash */
#module = "some_module";
};
/*
vhost "selfsigned.hades.arpa" {
ssl_private_key = "etc/selfssl.key";
ssl_cert = "etc/selfssl.pem";
};
vhost "oldca.hades.arpa" {
ssl_private_key = "etc/oldssl.key";
ssl_cert = "etc/oldssl2.pem";
ssl_dh_params = "etc/olddh.pem";
ssl_cipher_list = "kEECDH+HIGH:kEDH+HIGH:HIGH:!RC4:!aNULL";
};
*/

View file

@ -1,9 +1,5 @@
/* SSL extban type: matches ssl users */
/* This file is available under the same conditions as the rest of
https://github.com/asterIRC/ircd-chatd, and by extension, the rest
of Charybdis. */
#include "stdinc.h"
#include "modules.h"
#include "client.h"
@ -15,11 +11,7 @@ static int _modinit(void);
static void _moddeinit(void);
static int eb_ssl(const char *data, struct Client *client_p, struct Channel *chptr, long mode_type);
<<<<<<< .merge_file_utDAI3
DECLARE_MODULE_AV1(extb_ssl, _modinit, _moddeinit, NULL, NULL, NULL, "1.05");
=======
DECLARE_MODULE_AV2(extb_ssl, _modinit, _moddeinit, NULL, NULL, NULL, NULL, NULL, extb_desc);
>>>>>>> .merge_file_lvPLfm
static int
_modinit(void)
@ -42,11 +34,7 @@ static int eb_ssl(const char *data, struct Client *client_p,
(void)chptr;
(void)mode_type;
<<<<<<< .merge_file_utDAI3
if (! IsSSLClient(client_p))
=======
if (!IsSecureClient(client_p))
>>>>>>> .merge_file_lvPLfm
return EXTBAN_NOMATCH;
if (data != NULL)

View file

@ -197,17 +197,9 @@ mo_hurt(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_
}
if (parc == 3)
{
expire = NULL;
ip = parv[1];
reason = parv[2];
}
expire = NULL, ip = parv[1], reason = parv[2];
else
{
expire = parv[1];
ip = parv[2];
reason = parv[3];
}
expire = parv[1], ip = parv[2], reason = parv[3];
if (!expire)
expire_time = HURT_DEFAULT_EXPIRE;

View file

@ -76,10 +76,7 @@ static const char *expand_xline(const char *mask)
while (*p != '\0')
{
if (*p == ' ')
{
*q++ = '\\';
*q++ = 's';
}
*q++ = '\\', *q++ = 's';
else
*q++ = *p;
p++;

View file

@ -87,8 +87,6 @@ mr_webirc(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *sourc
const char *encr;
struct rb_sockaddr_storage addr;
<<<<<<< .merge_file_65X4Nj
=======
int secure = 0;
if (source_p->flags & FLAGS_SENTUSER || !EmptyString(source_p->name))
@ -96,7 +94,6 @@ mr_webirc(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *sourc
exit_client(client_p, source_p, &me, "WEBIRC may not follow NICK/USER");
}
>>>>>>> .merge_file_ryG7XZ
aconf = find_address_conf(client_p->host, client_p->sockhost,
IsGotId(client_p) ? client_p->username : "webirc",
IsGotId(client_p) ? client_p->username : "webirc",
@ -143,8 +140,6 @@ mr_webirc(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *sourc
}
source_p->localClient->ip = addr;
<<<<<<< .merge_file_65X4Nj
=======
source_p->username[0] = '\0';
ClearGotId(source_p);
@ -168,7 +163,6 @@ mr_webirc(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *sourc
{
ClearSecure(source_p);
}
>>>>>>> .merge_file_ryG7XZ
rb_inet_ntop_sock((struct sockaddr *)&source_p->localClient->ip, source_p->sockhost, sizeof(source_p->sockhost));

View file

@ -19,10 +19,7 @@ Unless noted below, all types can be used with +b, +q, +e and +I.
$a:<mask> - Matches users logged in with a username matching the mask
(* and ? wildcards)
$c:<chan> - Matches users who are on the given channel
<<<<<<< .merge_file_IbT0MO
=======
$g:<mask> - Matches as a normal ban but excludes logged in users
>>>>>>> .merge_file_pGDMRH
$o - Matches opers (most useful with +I)
$r:<mask> - Matches users with a realname (gecos) matching the mask
(* and ? wildcards); this can only be used with +b and +q
@ -32,5 +29,4 @@ Unless noted below, all types can be used with +b, +q, +e and +I.
channel
$x:<mask> - Bans all users with matching nick!user@host#gecos
$z - Matches all SSL users
$z:<data> - Matches all SSL users with a fingerprint matching the data

View file

@ -31,10 +31,7 @@ X f - Shows File Descriptors
* q - Shows temporary and global resv'd nicks and channels
* Q - Shows resv'd nicks and channels
* r - Shows resource usage by ircd
<<<<<<< .merge_file_9l1jJa
=======
* s - Shows secure blocks
>>>>>>> .merge_file_OEoqTz
X S - Shows ssld processes
* t - Shows generic server stats
u - Shows server uptime

View file

@ -99,18 +99,10 @@ extern int testing_conf;
extern struct ev_entry *check_splitmode_ev;
<<<<<<< .merge_file_iW7mBk
extern int ircd_ssl_ok;
extern int ircd_zlib_ok;
extern int maxconnections;
extern void rehash_ulimit();
=======
extern bool ircd_ssl_ok;
extern bool ircd_zlib_ok;
extern int maxconnections;
>>>>>>> .merge_file_fQC2Ek
void ircd_shutdown(const char *reason) __attribute__((noreturn));
#endif

View file

@ -37,11 +37,7 @@ struct lgetopt
extern struct lgetopt myopts[];
<<<<<<< .merge_file_v0j8Uc
void parseargs(int *, char ***, struct lgetopt *);
=======
void usage(const char *) __attribute__((noreturn));
void parseargs(int *, char * const **, struct lgetopt *);
>>>>>>> .merge_file_OM6tzi
#endif /* __GETOPT_H_INCLUDED__ */

View file

@ -39,12 +39,7 @@ extern void mod_add_cmd(struct Message *msg);
extern void mod_del_cmd(struct Message *msg);
extern char *reconstruct_parv(int parc, const char *parv[]);
<<<<<<< .merge_file_8Ju36V
extern struct Dictionary *alias_dict;
extern struct Dictionary *fakechannel_dict;
=======
extern rb_dictionary *alias_dict;
extern rb_dictionary *cmd_dict;
>>>>>>> .merge_file_g15suK
#endif /* INCLUDED_parse_h_h */

View file

@ -204,11 +204,7 @@ struct config_file_entry
int operspy_admin_only;
int pace_wait;
int pace_wait_simple;
<<<<<<< .merge_file_Ey8dam
int listfake_wait;
=======
int ping_warn_time;
>>>>>>> .merge_file_WzePKN
int short_motd;
int no_oper_flood;
int hide_server;
@ -344,16 +340,6 @@ struct alias_entry
int flags; /* reserved for later use */
};
struct fakechannel_entry
{
char *name;
char *topic;
int users_min;
int users_max;
};
/* All variables are GLOBAL */
extern struct config_file_entry ConfigFileEntry; /* defined in ircd.c */
extern struct config_channel_entry ConfigChannel; /* defined in channel.c */

View file

@ -52,7 +52,6 @@ extern rb_dlink_list xline_conf_list;
extern rb_dlink_list resv_conf_list;
extern rb_dlink_list nd_list;
extern rb_dlink_list tgchange_list;
extern rb_dlink_list vhost_conf_list;
extern struct _rb_patricia_tree_t *tgchange_tree;
@ -256,16 +255,5 @@ extern void add_nd_entry(const char *name);
extern void free_nd_entry(struct nd_entry *);
extern unsigned long get_nd_count(void);
struct vhost_conf
{
char *hostname;
char *ssl_private_key;
char *ssl_cert;
char *ssl_dh_params;
char *ssl_cipher_list;
rb_dlink_node node;
};
extern struct vhost_conf *make_vhost_conf(void);
extern void free_vhost_conf(struct vhost_conf *);
#endif

View file

@ -25,12 +25,7 @@
#ifndef INCLUDED_s_user_h
#define INCLUDED_s_user_h
<<<<<<< .merge_file_TICs6q
#include "config.h"
#include "ircd_defs.h"
=======
#include "defaults.h"
>>>>>>> .merge_file_R44nIw
struct Client;
struct User;
@ -50,8 +45,7 @@ extern void introduce_client(struct Client *client_p, struct Client *source_p,
struct User *user, const char *nick, int use_euid);
extern void change_nick_user_host(struct Client *target_p, const char *nick, const char *user,
const char *host, int newts, const char *format, ...)
AFP(6, 7);
const char *host, int newts, const char *format, ...);
extern int user_modes[256];
extern unsigned int find_umode_slot(void);

View file

@ -33,17 +33,6 @@ enum ssld_status {
void init_ssld(void);
void restart_ssld(void);
<<<<<<< .merge_file_CConFf
int start_ssldaemon(int count, const char *ssl_cert, const char *ssl_private_key, const char *ssl_dh_params, const char *ssl_cipher_list);
ssl_ctl_t *start_ssld_accept(rb_fde_t *sslF, rb_fde_t *plainF, uint32_t id);
ssl_ctl_t *start_ssld_connect(rb_fde_t *sslF, rb_fde_t *plainF, uint32_t id);
void start_zlib_session(void *data);
void send_new_ssl_certs(const char *ssl_cert, const char *ssl_private_key, const char *ssl_dh_params, const char *ssl_cipher_list, const int method, const char *hostname);
void send_remove_ssl_vhost(const char *hostname);
void ssld_decrement_clicount(ssl_ctl_t *ctl);
int get_ssld_count(void);
void ssld_foreach_info(void (*func)(void *data, pid_t pid, int cli_count, enum ssld_status status), void *data);
=======
int start_ssldaemon(int count);
ssl_ctl_t *start_ssld_accept(rb_fde_t *sslF, rb_fde_t *plainF, uint32_t id);
ssl_ctl_t *start_ssld_connect(rb_fde_t *sslF, rb_fde_t *plainF, uint32_t id);
@ -52,6 +41,6 @@ void ssld_update_config(void);
void ssld_decrement_clicount(ssl_ctl_t *ctl);
int get_ssld_count(void);
void ssld_foreach_info(void (*func)(void *data, pid_t pid, int cli_count, enum ssld_status status, const char *version), void *data);
>>>>>>> .merge_file_pjqFeX
#endif

View file

@ -1,886 +0,0 @@
# Makefile.in generated by automake 1.15.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2017 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
VPATH = @srcdir@
am__is_gnu_make = { \
if test -z '$(MAKELEVEL)'; then \
false; \
elif test -n '$(MAKE_HOST)'; then \
true; \
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
true; \
else \
false; \
fi; \
}
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
*) echo "am__make_running_with_option: internal error: invalid" \
"target option '$${target_option-}' specified" >&2; \
exit 1;; \
esac; \
has_opt=no; \
sane_makeflags=$$MAKEFLAGS; \
if $(am__is_gnu_make); then \
sane_makeflags=$$MFLAGS; \
else \
case $$MAKEFLAGS in \
*\\[\ \ ]*) \
bs=\\; \
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
esac; \
fi; \
skip_next=no; \
strip_trailopt () \
{ \
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
}; \
for flg in $$sane_makeflags; do \
test $$skip_next = yes && { skip_next=no; continue; }; \
case $$flg in \
*=*|--*) continue;; \
-*I) strip_trailopt 'I'; skip_next=yes;; \
-*I?*) strip_trailopt 'I';; \
-*O) strip_trailopt 'O'; skip_next=yes;; \
-*O?*) strip_trailopt 'O';; \
-*l) strip_trailopt 'l'; skip_next=yes;; \
-*l?*) strip_trailopt 'l';; \
-[dEDm]) skip_next=yes;; \
-[JT]) skip_next=yes;; \
esac; \
case $$flg in \
*$$target_option*) has_opt=yes; break;; \
esac; \
done; \
test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = .
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \
$(am__configure_deps) $(am__DIST_COMMON)
am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
configure.lineno config.status.lineno
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/include/libratbox_config.h
CONFIG_CLEAN_FILES = libratbox.pc
CONFIG_CLEAN_VPATH_FILES =
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo " GEN " $@;
am__v_GEN_1 =
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 =
SOURCES =
DIST_SOURCES =
RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
ctags-recursive dvi-recursive html-recursive info-recursive \
install-data-recursive install-dvi-recursive \
install-exec-recursive install-html-recursive \
install-info-recursive install-pdf-recursive \
install-ps-recursive install-recursive installcheck-recursive \
installdirs-recursive pdf-recursive ps-recursive \
tags-recursive uninstall-recursive
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
*) f=$$p;; \
esac;
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
am__install_max = 40
am__nobase_strip_setup = \
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
am__nobase_strip = \
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
am__nobase_list = $(am__nobase_strip_setup); \
for p in $$list; do echo "$$p $$p"; done | \
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
if (++n[$$2] == $(am__install_max)) \
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
END { for (dir in files) print dir, files[dir] }'
am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__uninstall_files_from_dir = { \
test -z "$$files" \
|| { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \
$(am__cd) "$$dir" && rm -f $$files; }; \
}
am__installdirs = "$(DESTDIR)$(pkgconfigdir)"
DATA = $(pkgconfig_DATA)
RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
distclean-recursive maintainer-clean-recursive
am__recursive_targets = \
$(RECURSIVE_TARGETS) \
$(RECURSIVE_CLEAN_TARGETS) \
$(am__extra_recursive_targets)
AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
cscope distdir dist dist-all distcheck
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
# Read a list of newline-separated strings from the standard input,
# and print each of them once, without duplicates. Input order is
# *not* preserved.
am__uniquify_input = $(AWK) '\
BEGIN { nonempty = 0; } \
{ items[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in items) print i; }; } \
'
# Make sure the list of sources is unique. This is necessary because,
# e.g., the same source file might be shared among _SOURCES variables
# for different programs/libraries.
am__define_uniq_tagged_files = \
list='$(am__tagged_files)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
CSCOPE = cscope
DIST_SUBDIRS = $(SUBDIRS)
am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/libratbox.pc.in \
$(top_srcdir)/include/libratbox_config.h.in COPYING ChangeLog \
INSTALL README TODO compile config.guess config.sub install-sh \
ltmain.sh missing
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
distdir = $(PACKAGE)-$(VERSION)
top_distdir = $(distdir)
am__remove_distdir = \
if test -d "$(distdir)"; then \
find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
&& rm -rf "$(distdir)" \
|| { sleep 5 && rm -rf "$(distdir)"; }; \
else :; fi
am__post_remove_distdir = $(am__remove_distdir)
am__relativize = \
dir0=`pwd`; \
sed_first='s,^\([^/]*\)/.*$$,\1,'; \
sed_rest='s,^[^/]*/*,,'; \
sed_last='s,^.*/\([^/]*\)$$,\1,'; \
sed_butlast='s,/*[^/]*$$,,'; \
while test -n "$$dir1"; do \
first=`echo "$$dir1" | sed -e "$$sed_first"`; \
if test "$$first" != "."; then \
if test "$$first" = ".."; then \
dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
else \
first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
if test "$$first2" = "$$first"; then \
dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
else \
dir2="../$$dir2"; \
fi; \
dir0="$$dir0"/"$$first"; \
fi; \
fi; \
dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
done; \
reldir="$$dir2"
DIST_ARCHIVES = $(distdir).tar.gz
GZIP_ENV = --best
DIST_TARGETS = dist-gzip
distuninstallcheck_listfiles = find . -type f -print
am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
| sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$'
distcleancheck_listfiles = find . -type f -print
ACLOCAL = @ACLOCAL@
ALLOCA = @ALLOCA@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AR = @AR@
AS = @AS@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CP = @CP@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GNUTLS_CFLAGS = @GNUTLS_CFLAGS@
GNUTLS_LIBS = @GNUTLS_LIBS@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN = @LN@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MBEDTLS_CFLAGS = @MBEDTLS_CFLAGS@
MBEDTLS_LIBS = @MBEDTLS_LIBS@
MKDIR_P = @MKDIR_P@
MV = @MV@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PICFLAGS = @PICFLAGS@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
RANLIB = @RANLIB@
RB_PREFIX = @RB_PREFIX@
RM = @RM@
SED = @SED@
SEDOBJ = @SEDOBJ@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
SSL_CFLAGS = @SSL_CFLAGS@
SSL_LIBS = @SSL_LIBS@
STRIP = @STRIP@
TOUCH = @TOUCH@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
AUTOMAKE_OPTIONS = foreign
SUBDIRS = src
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libratbox.pc
all: all-recursive
.SUFFIXES:
am--refresh: Makefile
@:
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \
$(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
echo ' $(SHELL) ./config.status'; \
$(SHELL) ./config.status;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
$(SHELL) ./config.status --recheck
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
$(am__cd) $(srcdir) && $(AUTOCONF)
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
$(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
$(am__aclocal_m4_deps):
include/libratbox_config.h: include/stamp-h1
@test -f $@ || rm -f include/stamp-h1
@test -f $@ || $(MAKE) $(AM_MAKEFLAGS) include/stamp-h1
include/stamp-h1: $(top_srcdir)/include/libratbox_config.h.in $(top_builddir)/config.status
@rm -f include/stamp-h1
cd $(top_builddir) && $(SHELL) ./config.status include/libratbox_config.h
$(top_srcdir)/include/libratbox_config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
($(am__cd) $(top_srcdir) && $(AUTOHEADER))
rm -f include/stamp-h1
touch $@
distclean-hdr:
-rm -f include/libratbox_config.h include/stamp-h1
libratbox.pc: $(top_builddir)/config.status $(srcdir)/libratbox.pc.in
cd $(top_builddir) && $(SHELL) ./config.status $@
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
distclean-libtool:
-rm -f libtool config.lt
install-pkgconfigDATA: $(pkgconfig_DATA)
@$(NORMAL_INSTALL)
@list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \
if test -n "$$list"; then \
echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfigdir)'"; \
$(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" || exit 1; \
fi; \
for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; \
done | $(am__base_list) | \
while read files; do \
echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \
$(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \
done
uninstall-pkgconfigDATA:
@$(NORMAL_UNINSTALL)
@list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir)
# This directory's subdirectories are mostly independent; you can cd
# into them and run 'make' without going through this Makefile.
# To change the values of 'make' variables: instead of editing Makefiles,
# (1) if the variable is set in 'config.status', edit 'config.status'
# (which will cause the Makefiles to be regenerated when you run 'make');
# (2) otherwise, pass the desired values on the 'make' command line.
$(am__recursive_targets):
@fail=; \
if $(am__make_keepgoing); then \
failcom='fail=yes'; \
else \
failcom='exit 1'; \
fi; \
dot_seen=no; \
target=`echo $@ | sed s/-recursive//`; \
case "$@" in \
distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
*) list='$(SUBDIRS)' ;; \
esac; \
for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
dot_seen=yes; \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| eval $$failcom; \
done; \
if test "$$dot_seen" = "no"; then \
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
fi; test -z "$$fail"
ID: $(am__tagged_files)
$(am__define_uniq_tagged_files); mkid -fID $$unique
tags: tags-recursive
TAGS: tags
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
set x; \
here=`pwd`; \
if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
include_option=--etags-include; \
empty_fix=.; \
else \
include_option=--include; \
empty_fix=; \
fi; \
list='$(SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test ! -f $$subdir/TAGS || \
set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
fi; \
done; \
$(am__define_uniq_tagged_files); \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: ctags-recursive
CTAGS: ctags
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
$(am__define_uniq_tagged_files); \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
cscope: cscope.files
test ! -s cscope.files \
|| $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS)
clean-cscope:
-rm -f cscope.files
cscope.files: clean-cscope cscopelist
cscopelist: cscopelist-recursive
cscopelist-am: $(am__tagged_files)
list='$(am__tagged_files)'; \
case "$(srcdir)" in \
[\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
*) sdir=$(subdir)/$(srcdir) ;; \
esac; \
for i in $$list; do \
if test -f "$$i"; then \
echo "$(subdir)/$$i"; \
else \
echo "$$sdir/$$i"; \
fi; \
done >> $(top_builddir)/cscope.files
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
-rm -f cscope.out cscope.in.out cscope.po.out cscope.files
distdir: $(DISTFILES)
$(am__remove_distdir)
test -d "$(distdir)" || mkdir "$(distdir)"
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
$(am__make_dryrun) \
|| test -d "$(distdir)/$$subdir" \
|| $(MKDIR_P) "$(distdir)/$$subdir" \
|| exit 1; \
dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
$(am__relativize); \
new_distdir=$$reldir; \
dir1=$$subdir; dir2="$(top_distdir)"; \
$(am__relativize); \
new_top_distdir=$$reldir; \
echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
($(am__cd) $$subdir && \
$(MAKE) $(AM_MAKEFLAGS) \
top_distdir="$$new_top_distdir" \
distdir="$$new_distdir" \
am__remove_distdir=: \
am__skip_length_check=: \
am__skip_mode_fix=: \
distdir) \
|| exit 1; \
fi; \
done
-test -n "$(am__skip_mode_fix)" \
|| find "$(distdir)" -type d ! -perm -755 \
-exec chmod u+rwx,go+rx {} \; -o \
! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
! -type d ! -perm -400 -exec chmod a+r {} \; -o \
! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
|| chmod -R a+r "$(distdir)"
dist-gzip: distdir
tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz
$(am__post_remove_distdir)
dist-bzip2: distdir
tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2
$(am__post_remove_distdir)
dist-lzip: distdir
tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz
$(am__post_remove_distdir)
dist-xz: distdir
tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz
$(am__post_remove_distdir)
dist-tarZ: distdir
@echo WARNING: "Support for distribution archives compressed with" \
"legacy program 'compress' is deprecated." >&2
@echo WARNING: "It will be removed altogether in Automake 2.0" >&2
tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
$(am__post_remove_distdir)
dist-shar: distdir
@echo WARNING: "Support for shar distribution archives is" \
"deprecated." >&2
@echo WARNING: "It will be removed altogether in Automake 2.0" >&2
shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz
$(am__post_remove_distdir)
dist-zip: distdir
-rm -f $(distdir).zip
zip -rq $(distdir).zip $(distdir)
$(am__post_remove_distdir)
dist dist-all:
$(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:'
$(am__post_remove_distdir)
# This target untars the dist file and tries a VPATH configuration. Then
# it guarantees that the distribution is self-contained by making another
# tarfile.
distcheck: dist
case '$(DIST_ARCHIVES)' in \
*.tar.gz*) \
eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\
*.tar.bz2*) \
bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
*.tar.lz*) \
lzip -dc $(distdir).tar.lz | $(am__untar) ;;\
*.tar.xz*) \
xz -dc $(distdir).tar.xz | $(am__untar) ;;\
*.tar.Z*) \
uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
*.shar.gz*) \
eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\
*.zip*) \
unzip $(distdir).zip ;;\
esac
chmod -R a-w $(distdir)
chmod u+w $(distdir)
mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst
chmod a-w $(distdir)
test -d $(distdir)/_build || exit 0; \
dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
&& dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
&& am__cwd=`pwd` \
&& $(am__cd) $(distdir)/_build/sub \
&& ../../configure \
$(AM_DISTCHECK_CONFIGURE_FLAGS) \
$(DISTCHECK_CONFIGURE_FLAGS) \
--srcdir=../.. --prefix="$$dc_install_base" \
&& $(MAKE) $(AM_MAKEFLAGS) \
&& $(MAKE) $(AM_MAKEFLAGS) dvi \
&& $(MAKE) $(AM_MAKEFLAGS) check \
&& $(MAKE) $(AM_MAKEFLAGS) install \
&& $(MAKE) $(AM_MAKEFLAGS) installcheck \
&& $(MAKE) $(AM_MAKEFLAGS) uninstall \
&& $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
distuninstallcheck \
&& chmod -R a-w "$$dc_install_base" \
&& ({ \
(cd ../.. && umask 077 && mkdir "$$dc_destdir") \
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
} || { rm -rf "$$dc_destdir"; exit 1; }) \
&& rm -rf "$$dc_destdir" \
&& $(MAKE) $(AM_MAKEFLAGS) dist \
&& rm -rf $(DIST_ARCHIVES) \
&& $(MAKE) $(AM_MAKEFLAGS) distcleancheck \
&& cd "$$am__cwd" \
|| exit 1
$(am__post_remove_distdir)
@(echo "$(distdir) archives ready for distribution: "; \
list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'
distuninstallcheck:
@test -n '$(distuninstallcheck_dir)' || { \
echo 'ERROR: trying to run $@ with an empty' \
'$$(distuninstallcheck_dir)' >&2; \
exit 1; \
}; \
$(am__cd) '$(distuninstallcheck_dir)' || { \
echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \
exit 1; \
}; \
test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \
|| { echo "ERROR: files left after uninstall:" ; \
if test -n "$(DESTDIR)"; then \
echo " (check DESTDIR support)"; \
fi ; \
$(distuninstallcheck_listfiles) ; \
exit 1; } >&2
distcleancheck: distclean
@if test '$(srcdir)' = . ; then \
echo "ERROR: distcleancheck can only run from a VPATH build" ; \
exit 1 ; \
fi
@test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
|| { echo "ERROR: files left in build directory after distclean:" ; \
$(distcleancheck_listfiles) ; \
exit 1; } >&2
check-am: all-am
check: check-recursive
all-am: Makefile $(DATA)
installdirs: installdirs-recursive
installdirs-am:
for dir in "$(DESTDIR)$(pkgconfigdir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-recursive
install-exec: install-exec-recursive
install-data: install-data-recursive
uninstall: uninstall-recursive
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-recursive
install-strip:
if test -z '$(STRIP)'; then \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
install; \
else \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
fi
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-recursive
clean-am: clean-generic clean-libtool mostlyclean-am
distclean: distclean-recursive
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
-rm -f Makefile
distclean-am: clean-am distclean-generic distclean-hdr \
distclean-libtool distclean-tags
dvi: dvi-recursive
dvi-am:
html: html-recursive
html-am:
info: info-recursive
info-am:
install-data-am: install-pkgconfigDATA
install-dvi: install-dvi-recursive
install-dvi-am:
install-exec-am:
install-html: install-html-recursive
install-html-am:
install-info: install-info-recursive
install-info-am:
install-man:
install-pdf: install-pdf-recursive
install-pdf-am:
install-ps: install-ps-recursive
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-recursive
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
-rm -rf $(top_srcdir)/autom4te.cache
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-recursive
mostlyclean-am: mostlyclean-generic mostlyclean-libtool
pdf: pdf-recursive
pdf-am:
ps: ps-recursive
ps-am:
uninstall-am: uninstall-pkgconfigDATA
.MAKE: $(am__recursive_targets) install-am install-strip
.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \
am--refresh check check-am clean clean-cscope clean-generic \
clean-libtool cscope cscopelist-am ctags ctags-am dist \
dist-all dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ \
dist-xz dist-zip distcheck distclean distclean-generic \
distclean-hdr distclean-libtool distclean-tags distcleancheck \
distdir distuninstallcheck dvi dvi-am html html-am info \
info-am install install-am install-data install-data-am \
install-dvi install-dvi-am install-exec install-exec-am \
install-html install-html-am install-info install-info-am \
install-man install-pdf install-pdf-am install-pkgconfigDATA \
install-ps install-ps-am install-strip installcheck \
installcheck-am installdirs installdirs-am maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-generic \
mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \
uninstall-am uninstall-pkgconfigDATA
.PRECIOUS: Makefile
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

10541
libratbox/aclocal.m4 vendored

File diff suppressed because it is too large Load diff

1480
libratbox/config.guess vendored

File diff suppressed because it is too large Load diff

1801
libratbox/config.sub vendored

File diff suppressed because it is too large Load diff

17916
libratbox/configure vendored

File diff suppressed because it is too large Load diff

View file

@ -1,698 +0,0 @@
dnl $Id: configure.ac 26260 2008-12-10 04:08:39Z androsyn $
dnl Process this file with autoconf to produce a configure script.
dnl TODO: clean up all the OpenSSL and shared module checking stuff;
dnl the most major changes have already been made and it looks like
dnl said functions need to be just about as complex as they already are.
AC_PREREQ(2.63)
AUTOMAKE_OPTIONS = 1.10
dnl Sneaky way to get an Id tag into the configure script
AC_COPYRIGHT([$Id: configure.ac 26260 2008-12-10 04:08:39Z androsyn $])
AC_INIT([libratbox],[devel])
AM_INIT_AUTOMAKE(AC_PACKAGE_TARNAME, AC_PACKAGE_VERSION, -)
AM_CONFIG_HEADER(include/libratbox_config.h)
AC_PREFIX_DEFAULT(/usr/local/libratbox)
AC_GNU_SOURCE
dnl Checks for programs.
AC_PROG_CC_C99
if test x"$ac_cv_prog_cc_c99" = "xno"; then
AC_ERROR([ircd-ratbox requires a C99 capable compiler])
fi
AC_PROG_INSTALL
AC_PROG_EGREP
AC_PROG_SED
F77=no
CXX=no
GCJ=no
AM_DISABLE_STATIC
AM_ENABLE_SHARED
AM_MAINTAINER_MODE
AC_ISC_POSIX
AC_C_INLINE
AC_C_CONST
AC_C_BIGENDIAN
AC_PROG_MAKE_SET
AC_PROG_INSTALL
AC_PATH_PROG(AUTOMAKE, automake)
AC_PATH_PROG(ACLOCAL, aclocal)
AC_PATH_PROG(AUTOHEADER, autoheader)
AC_PATH_PROG(AS, as)
AC_PATH_PROG(RM, rm)
AC_PATH_PROG(CP, cp)
AC_PATH_PROG(MV, mv)
AC_PATH_PROG(LN, ln)
AC_PATH_PROG(TOUCH, touch)
AC_LANG(C)
AC_PROG_LIBTOOL
LIBTOOL="$LIBTOOL --silent"
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*)
AC_DEFINE_UNQUOTED(MINGW,1,[This is a MinGW system])
AC_DEFINE_UNQUOTED(WINDOWS,1,[This is a Windows system])
AC_CHECK_HEADER(windows.h, , [AC_MSG_ERROR([** MinGW and no windows.h. I give up.])])
AC_CHECK_HEADER(winsock2.h, , [AC_MSG_ERROR([** MinGW and no winsock2.h. I give up.])])
AC_DEFINE_UNQUOTED(HAVE_WINSOCK2_H, 1, [Have WINSOCK2_H])
AC_DEFINE_UNQUOTED(HAVE_WINSOCK_H, 1, [Have WINSOCK_H])
LIBS="$LIBS -lws2_32 -liphlpapi"
is_mingw="yes"
;;
*interix*)
CPPFLAGS="$CFLAGS -D_ALL_SOURCE -D_XOPEN_SOURCE=500"
;;
*solaris*)
CPPFLAGS="$CFLAGS -D_POSIX_PTHREAD_SEMANTICS -D_XPG4_2"
;;
*)
;;
esac
AM_CONDITIONAL([MINGW], [test "$is_mingw" = "yes"])
# backwards support for IRC_CFLAGS
CFLAGS="$IRC_CFLAGS $CFLAGS -Wall"
dnl use directory structure of cached as default (hack)
if test "$libexecdir" = '${exec_prefix}/libexec' &&
test "$localstatedir" = '${prefix}/var'; then
libexecdir='${bindir}'
localstatedir='${prefix}'
fi
AC_TYPE_PID_T
AC_TYPE_SIZE_T
AC_TYPE_SSIZE_T
AC_TYPE_UID_T
dnl Checks for header files.
AC_HEADER_STDC
AC_CHECK_HEADERS([crypt.h unistd.h sys/socket.h sys/stat.h sys/time.h time.h netinet/in.h arpa/inet.h errno.h sys/uio.h spawn.h sys/poll.h sys/epoll.h sys/select.h sys/devpoll.h sys/event.h port.h signal.h sys/signalfd.h sys/timerfd.h linux/tcp.h])
AC_HEADER_TIME
dnl Networking Functions
dnl ====================
AC_SEARCH_LIBS(socket, [socket],,)
AC_CHECK_MEMBER([struct sockaddr.sa_len], [AC_DEFINE(SOCKADDR_IN_HAS_LEN, 1, [Define to 1 if sockaddr has a 'sa_len'
member.])],,[[
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_WINSOCK2_H
#include <winsock2.h>
#endif
]])
AC_CHECK_TYPE([socklen_t], rb_cv_socklen_t=socklen_t,[
AC_MSG_CHECKING([for socklen_t equivalent])
AC_CACHE_VAL([rb_cv_socklen_t],
[
# Systems have either "struct sockaddr *" or
# "void *" as the second argument to getpeername
rb_cv_socklen_t=
for arg2 in "struct sockaddr" void; do
for t in int size_t unsigned long "unsigned long"; do
AC_TRY_COMPILE([
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_WINSOCK2_H
#include <winsock2.h>
#endif
int getpeername (int, $arg2 *, $t *);
],[
$t len;
getpeername(0,0,&len);
],[
rb_cv_socklen_t="$t"
break
])
done
done
if test "x$rb_cv_socklen_t" = x; then
AC_MSG_WARN([Cannot find a type to use in place of socklen_t using int])
rb_cv_socklen_t=int
fi
])
AC_MSG_RESULT($rb_cv_socklen_t)],
[#include <sys/types.h>
#include <sys/socket.h>])
rb_socklen_t=$rb_cv_socklen_t
AC_ARG_ENABLE(ipv6,AC_HELP_STRING([--disable-ipv6],[Disable IPv6 support]),[ipv6=$enableval],[ipv6=yes])
if test x$ipv6 != xyes; then
have_v6="no"
else
have_v6=yes
RB_PROTO_INET6([], [
AC_MSG_NOTICE([Disabling IPv6 support: PF_INET6 not found])
have_v6=no
])
if test "X$have_v6" = "Xyes"; then
RB_TYPE_STRUCT_SOCKADDR_IN6([], [
AC_MSG_NOTICE([Disabling IPv6 support: struct sockaddr_in6 not found])
have_v6=no
])
fi
fi
AC_CHECK_TYPES([struct sockaddr_storage],[
rb_have_sockaddr_storage=yes
],[], [
#include <sys/types.h>
#include <sys/socket.h>
])
dnl Check for stdarg.h - if we cant find it, halt configure
AC_CHECK_HEADER(stdarg.h, , [AC_MSG_ERROR([** stdarg.h could not be found - libratbox will not compile without it **])])
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>]])
dnl check for various functions...
AC_CHECK_FUNCS([socketpair gettimeofday writev sendmsg gmtime_r strtok_r usleep posix_spawn strlcpy strlcat strnlen fstat signalfd select poll kevent port_create epoll_ctl arc4random getrusage timerfd_create])
AC_SEARCH_LIBS(nanosleep, rt posix4, AC_DEFINE(HAVE_NANOSLEEP, 1, [Define if you have nanosleep]))
AC_SEARCH_LIBS(timer_create, rt, AC_DEFINE(HAVE_TIMER_CREATE, 1, [Define if you have timer_create]))
RB_CHECK_TIMER_CREATE
RB_CHECK_TIMERFD_CREATE
AC_FUNC_ALLOCA
AC_FUNC_VFORK
AC_FUNC_MMAP
AC_MSG_CHECKING(for /dev/poll)
if test -c "/dev/poll"; then
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_DEVPOLL, [1], [Define to 1 if you have devpoll])
else
AC_MSG_RESULT(no)
fi
if test "$is_mingw" = "yes"; then
AC_DEFINE(HAVE_WIN32, [1], [Define to 1 if you are on windows])
fi
dnl OpenSSL support
AC_MSG_CHECKING(for OpenSSL)
AC_ARG_ENABLE(openssl,
[AC_HELP_STRING([--enable-openssl[=DIR]],[Enable OpenSSL support (DIR optional).])
AC_HELP_STRING([--disable-openssl],[Disable OpenSSL support.])],
[cf_enable_openssl=$enableval],
[cf_enable_openssl="auto"])
if test "$cf_enable_openssl" != "no" ; then
cf_openssl_basedir=""
if test "$cf_enable_openssl" != "auto" &&
test "$cf_enable_openssl" != "yes" ; then
dnl Support for --enable-openssl=/some/place
cf_openssl_basedir="`echo ${cf_enable_openssl} | sed 's/\/$//'`"
else
dnl Do the auto-probe here. Check some common directory paths.
for dirs in /usr/local/ssl /usr/pkg /usr/local \
/usr/local/openssl ; do
if test -f "${dirs}/include/openssl/opensslv.h" ; then
cf_openssl_basedir="${dirs}"
break
fi
done
unset dirs
fi
dnl Now check cf_openssl_found to see if we found anything.
if test ! -z "$cf_openssl_basedir"; then
if test -f "${cf_openssl_basedir}/include/openssl/opensslv.h" ; then
SSL_CFLAGS="-I${cf_openssl_basedir}/include"
SSL_LIBS="-L${cf_openssl_basedir}/lib"
else
dnl OpenSSL wasn't found in the directory specified. Naughty
dnl administrator...
cf_openssl_basedir=""
fi
else
dnl Check for stock FreeBSD 4.x and 5.x systems, since their files
dnl are in /usr/include and /usr/lib. In this case, we don't want to
dnl change INCLUDES or LIBS, but still want to enable OpenSSL.
dnl We can't do this check above, because some people want two versions
dnl of OpenSSL installed (stock FreeBSD 4.x/5.x and /usr/local/ssl)
dnl and they want /usr/local/ssl to have preference.
if test -f "/usr/include/openssl/opensslv.h" ; then
cf_openssl_basedir="/usr"
fi
fi
dnl If we have a basedir defined, then everything is okay. Otherwise,
dnl we have a problem.
if test ! -z "$cf_openssl_basedir"; then
AC_MSG_RESULT($cf_openssl_basedir)
cf_enable_openssl="yes"
else
AC_MSG_RESULT([not found. Specify a correct path?])
cf_enable_openssl="no"
fi
unset cf_openssl_basedir
else
dnl If --disable-openssl was specified
AC_MSG_RESULT(disabled)
fi
save_CPPFLAGS="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS $SSL_CFLAGS"
save_LIBS="$LIBS"
LIBS="$LIBS $SSL_LIBS"
if test "$cf_enable_openssl" != no; then
dnl Check OpenSSL version (must be 0.9.7 or above!)
AC_MSG_CHECKING(for OpenSSL 0.9.7 or above)
AC_RUN_IFELSE(
AC_LANG_PROGRAM(
[#include <openssl/opensslv.h>
#include <stdlib.h>],
[[if (OPENSSL_VERSION_NUMBER >= 0x00907000)
exit(0); else exit(1);]]),
cf_enable_openssl=yes,
cf_enable_openssl=no,
cf_enable_openssl=no)
if test "$cf_enable_openssl" != no; then
AC_MSG_RESULT(found)
else
AC_MSG_RESULT(no - OpenSSL support disabled)
fi
fi
if test "$cf_enable_openssl" != no; then
CPPFLAGS="$CPPFLAGS $SSL_LIBS"
AC_CHECK_LIB(crypto, RAND_status,
[cf_enable_openssl=yes],
[cf_enable_openssl=no])
fi
if test "$cf_enable_openssl" != no; then
CPPFLAGS="$CPPFLAGS $SSL_LIBS"
AC_CHECK_LIB(ssl, SSL_read,
[SSL_LIBS="$SSL_LIBS -lssl -lcrypto"],
[cf_enable_openssl=no], [-lcrypto])
fi
dnl mbedTLS support
AC_ARG_ENABLE(mbedtls,
[AC_HELP_STRING([--enable-mbedtls], [Enable mbedTLS support.])
AC_HELP_STRING([--disable-mbedtls], [Disable mbedTLS support.])],
[cf_enable_mbedtls=$enableval],
[cf_enable_mbedtls="auto"])
if test "$cf_enable_mbedtls" != no; then
save_CPPFLAGS="$CPPFLAGS"
save_LIBS="$LIBS"
LIBS="$LIBS $MBEDTLS_LIBS"
AC_CHECK_LIB(mbedtls, mbedtls_ssl_init, [
MBEDTLS_LIBS="$MBEDTLS_LIBS -lmbedtls -lmbedx509 -lmbedcrypto"
cf_enable_mbedtls=yes
], [cf_enable_mbedtls=no], [-lmbedx509 -lmbedcrypto])
fi
dnl GnuTLS support
AC_MSG_CHECKING(for GnuTLS)
AC_ARG_ENABLE(gnutls,
[AC_HELP_STRING([--enable-gnutls],[Enable GnuTLS support.])
AC_HELP_STRING([--disable-gnutls],[Disable GnuTLS support.])],
[cf_enable_gnutls=$enableval],
[cf_enable_gnutls="auto"])
if test "$cf_enable_gnutls" != no; then
PKG_CHECK_MODULES(GNUTLS, [gnutls], [
cf_enable_gnutls="yes"
], [cf_enable_gnutls="no"])
fi
dnl mbed TLS is given highest preference when no specified TLS library is provided
if test "$cf_enable_openssl" = "auto" -a "$cf_enable_mbedtls" = "yes"; then
cf_enable_openssl="no"
fi
if test "$cf_enable_gnutls" = "auto" -a "$cf_enable_openssl" = "yes" -a "$cf_enable_mbedtls" = "yes"; then
cf_enable_gnutls="no"
fi
if test x"$cf_enable_openssl" != xno; then
AC_DEFINE(HAVE_OPENSSL,1,[Has OpenSSL])
GNUTLS_CFLAGS=""
GNUTLS_LIBS=""
MBEDTLS_LIBS=""
MBEDTLS_CFLAGS=""
SSL_TYPE="openssl"
elif test x"$cf_enable_mbedtls" != xno; then
AC_DEFINE(HAVE_MBEDTLS, 1, [Has mbedTLS])
SSL_LIBS=""
SSL_CFLAGS=""
GNUTLS_CFLAGS=""
GNUTLS_LIBS=""
SSL_TYPE="mbedtls"
elif test x"$cf_enable_gnutls" != xno; then
AC_DEFINE(HAVE_GNUTLS, 1, [Has GnuTLS])
SSL_LIBS=""
SSL_CFLAGS=""
MBEDTLS_LIBS=""
MBEDTLS_CFLAGS=""
SSL_TYPE="gnutls"
fi
CPPFLAGS="$save_CPPFLAGS"
LIBS="$save_LIBS"
dnl End OpenSSL detection
dnl Debug-related options
dnl =====================
AC_ARG_ENABLE(assert,
AC_HELP_STRING([--enable-assert],[Enable assert(). Choose between soft(warnings) and hard(aborts the daemon)]),
[assert=$enableval], [assert=no])
if test "$assert" = no; then
AC_DEFINE(NDEBUG, 1, [Define this to disable debugging support.])
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";
fi
AC_MSG_CHECKING(if you want to do a profile build)
AC_ARG_ENABLE(profile,
AC_HELP_STRING([--enable-profile],[Enable profiling]),
[profile=$enableval], [profile=no])
if test "$profile" = yes; then
if test "$ac_cv_c_compiler_gnu" = yes; then
CFLAGS="$CFLAGS -pg -static"
AC_MSG_RESULT([yes, adding -pg -static])
AC_DEFINE(RATBOX_PROFILE, 1, [Defined to mark profiling is enabled])
else
AC_MSG_RESULT([no, profile builds only work with gcc])
fi
else
AC_MSG_RESULT(no)
fi
AC_ARG_ENABLE(balloc,
AC_HELP_STRING([--disable-balloc],[Disable the block allocator.]),
[balloc=$enableval], [balloc=yes])
if test "$balloc" = no; then
AC_DEFINE([NOBALLOC], 1, [Define to 1 if you wish to disable the block allocator.])
fi
AC_ARG_ENABLE(warnings,
AC_HELP_STRING([--enable-warnings],[Enable all sorts of warnings for debugging.]),
[CFLAGS="$CFLAGS -Wall -Werror -Wcast-qual -Wmissing-declarations -Wmissing-prototypes -Wnested-externs -Wshadow -Wwrite-strings -W -Wno-unused -Wunused-function -Wunused-variable"],[])
AC_SUBST(LDFLAGS)
AC_SUBST(PICFLAGS)
AC_SUBST(CFLAGS)
AC_SUBST(SEDOBJ)
AC_SUBST(SSL_CFLAGS)
AC_SUBST(SSL_LIBS)
AC_SUBST(GNUTLS_CFLAGS)
AC_SUBST(GNUTLS_LIBS)
AC_SUBST(MBEDTLS_CFLAGS)
AC_SUBST(MBEDTLS_LIBS)
if test "$prefix" = "NONE"; then
AC_DEFINE_UNQUOTED(RB_PREFIX, "$ac_default_prefix", [Prefix where libratbox is installed.])
else
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(RB_PREFIX, "$prefix", [Prefix where libratbox is installed.])
fi
AC_SUBST(RB_PREFIX)
AC_CONFIG_COMMANDS([include/librb-config.h],
[
outfile=include/librb-config.h.tmp
cat > $outfile <<\_______EOF
/*
* librb-config.h: libratbox config file. Please modify configure.ac
*/
#ifndef __LIBRB_CONFIG_H
#define __LIBRB_CONFIG_H
_______EOF
if test "x$rb_have_ipv6" = "xyes"; then
echo "#define RB_IPV6 1" >> $outfile
fi
if test "x$rb_windows_h" = "xyes"; then
echo '#define WIN32_LEAN_AND_MEAN 1' >> $outfile
echo '#include <windows.h>' >> $outfile
echo '#include <winsock2.h>' >> $outfile
echo '#include <iphlpapi.h>' >> $outfile
fi
if test "x$rb_alloca_h" = "xyes"; then
echo '#define RB_HAVE_ALLOCA_H 1' >> $outfile
fi
if test "x$rb_header_stdc" = "xyes"; then
echo '#include <stdlib.h>' >> $outfile
echo '#include <stddef.h>' >> $outfile
elif test "x$rb_header_stdlib" = "xyes"; then
echo '#include <stdlib.h>' >> $outfile
fi
if test "x$rb_header_string_h" = "xyes"; then
echo '#include <string.h>' >> $outfile
fi
if test "x$rb_stdint_h" = "xyes"; then
echo '#include <stdint.h>' >> $outfile
fi
if test "x$rb_inttypes_h" = "xyes"; then
echo '#include <inttypes.h>' >> $outfile
fi
if test "x$rb_sys_types_h" = "xyes"; then
echo '#include <sys/types.h>' >> $outfile
fi
if test "x$rb_sys_time_h" = "xyes"; then
echo '#include <sys/time.h>' >> $outfile
fi
if test "x$rb_sys_stat_h" = "xyes"; then
echo '#include <sys/stat.h>' >> $outfile
fi
if test "x$rb_time_h" = "xyes"; then
echo '#include <time.h>' >> $outfile
fi
if test "x$rb_sys_socket_h" = "xyes"; then
echo '#include <sys/socket.h>' >> $outfile
fi
if test "x$rb_netinet_in_h" = "xyes"; then
echo '#include <netinet/in.h>' >> $outfile
fi
if test "x$rb_arpa_inet_h" = "xyes"; then
echo '#include <arpa/inet.h>' >> $outfile
fi
if test "x$rb_unistd_h" = "xyes"; then
echo '#include <unistd.h>' >> $outfile
fi
if test "x$rb_crypt_h" = "xyes"; then
echo '#include <crypt.h>' >> $outfile
fi
if test "x$rb_errno_h" = "xyes"; then
echo '#include <errno.h>' >> $outfile
fi
echo "typedef $rb_socklen_t rb_socklen_t;" >> $outfile
if test "x$rb_sockaddr_sa_len" = "xyes"; then
echo '#define RB_SOCKADDR_HAS_SA_LEN 1' >> $outfile
fi
if test "x$rb_sockaddr_storage" = "xyes"; then
echo '#define rb_sockaddr_storage sockaddr_storage' >> $outfile
else
echo 'struct rb_sockaddr_storage { uint8_t _padding[[128]]; };' >> $outfile
fi
cat >> $outfile <<\_______EOF
#endif /* __LIBRB_CONFIG_H */
_______EOF
if cmp -s $outfile include/librb-config.h; then
AC_MSG_NOTICE([include/librb-config.h is unchanged])
${rb_rm} -f $outfile
else
${rb_mv} $outfile include/librb-config.h
fi
],[
if test x$ac_cv_header_stdc = xyes; then
rb_header_stdc=yes
fi
if test x$ac_cv_header_stdlib_h = xyes; then
rb_header_stdlib_h=yes
fi
if test x$ac_cv_header_string_h = xyes; then
rb_header_string_h=yes
fi
if test x$ac_cv_header_memory_h = xyes; then
rb_header_memory_h=yes
fi
if test "x${ac_cv_working_alloca_h+set}" = xset ; then
rb_alloca_h="$ac_cv_working_alloca_h"
else
rb_alloc_h="$ac_cv_header_alloca_h"
fi
if test x$ac_cv_member_struct_sockaddr_sa_len = xyes; then
rb_sockaddr_sa_len=yes
fi
if test x$ac_cv_header_sys_socket_h = xyes; then
rb_sys_socket_h=yes
fi
if test x$ac_cv_header_sys_types_h = xyes; then
rb_sys_types_h=yes
fi
if test x$ac_cv_header_sys_stat_h = xyes; then
rb_sys_stat_h=yes
fi
if test x$ac_cv_header_sys_time_h = xyes; then
rb_sys_time_h=yes
fi
if test x$ac_cv_header_time = xyes; then
rb_time_h=yes
fi
if test x$ac_cv_header_stdint_h = xyes; then
rb_stdint_h=yes
fi
if test x$ac_cv_header_inttypes_h = xyes; then
rb_inttypes_h=yes
fi
if test x$ac_cv_header_netinet_in_h = xyes; then
rb_netinet_in_h=yes
fi
if test x$ac_cv_header_crypt_h = xyes; then
rb_crypt_h=yes
fi
if test x$ac_cv_header_errno_h = xyes; then
rb_errno_h=yes
fi
if test x$ac_cv_header_unistd_h = xyes; then
rb_unistd_h=yes
fi
if test x$ac_cv_header_windows_h = xyes; then
rb_windows_h=yes
fi
if test x$ac_cv_header_winsock2_h = xyes; then
rb_winsock2_h=yes
fi
rb_socklen_t=$rb_socklen_t
if test "x$rb_have_sockaddr_storage" = "xyes"; then
rb_sockaddr_storage="yes"
else
rb_sockaddr_storage="no"
fi
rb_have_ipv6="$have_v6"
rb_mv="$MV"
rb_rm="$RM"
]
)
AC_CONFIG_FILES( \
src/Makefile \
Makefile \
libratbox.pc
)
AC_OUTPUT
dnl Make it look sexay!
echo
echo "Compiling $PACKAGE_NAME $PACKAGE_VERSION"
echo
echo "Installing into: $prefix"
echo "IPv6 support ................... $have_v6"
echo "Assert debugging ............... $assert"
echo "Block allocator ................ $balloc"
echo "SSL Type........................ $SSL_TYPE"
echo

View file

@ -1,791 +0,0 @@
#! /bin/sh
# depcomp - compile a program generating dependencies as side-effects
scriptversion=2016-01-11.22; # UTC
# Copyright (C) 1999-2017 Free Software Foundation, Inc.
# 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, 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, see <http://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
case $1 in
'')
echo "$0: No command. Try '$0 --help' for more information." 1>&2
exit 1;
;;
-h | --h*)
cat <<\EOF
Usage: depcomp [--help] [--version] PROGRAM [ARGS]
Run PROGRAMS ARGS to compile a file, generating dependencies
as side-effects.
Environment variables:
depmode Dependency tracking mode.
source Source file read by 'PROGRAMS ARGS'.
object Object file output by 'PROGRAMS ARGS'.
DEPDIR directory where to store dependencies.
depfile Dependency file to output.
tmpdepfile Temporary file to use when outputting dependencies.
libtool Whether libtool is used (yes/no).
Report bugs to <bug-automake@gnu.org>.
EOF
exit $?
;;
-v | --v*)
echo "depcomp $scriptversion"
exit $?
;;
esac
# Get the directory component of the given path, and save it in the
# global variables '$dir'. Note that this directory component will
# be either empty or ending with a '/' character. This is deliberate.
set_dir_from ()
{
case $1 in
*/*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;;
*) dir=;;
esac
}
# Get the suffix-stripped basename of the given path, and save it the
# global variable '$base'.
set_base_from ()
{
base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'`
}
# If no dependency file was actually created by the compiler invocation,
# we still have to create a dummy depfile, to avoid errors with the
# Makefile "include basename.Plo" scheme.
make_dummy_depfile ()
{
echo "#dummy" > "$depfile"
}
# Factor out some common post-processing of the generated depfile.
# Requires the auxiliary global variable '$tmpdepfile' to be set.
aix_post_process_depfile ()
{
# If the compiler actually managed to produce a dependency file,
# post-process it.
if test -f "$tmpdepfile"; then
# Each line is of the form 'foo.o: dependency.h'.
# Do two passes, one to just change these to
# $object: dependency.h
# and one to simply output
# dependency.h:
# which is needed to avoid the deleted-header problem.
{ sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile"
sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile"
} > "$depfile"
rm -f "$tmpdepfile"
else
make_dummy_depfile
fi
}
# A tabulation character.
tab=' '
# A newline character.
nl='
'
# Character ranges might be problematic outside the C locale.
# These definitions help.
upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ
lower=abcdefghijklmnopqrstuvwxyz
digits=0123456789
alpha=${upper}${lower}
if test -z "$depmode" || test -z "$source" || test -z "$object"; then
echo "depcomp: Variables source, object and depmode must be set" 1>&2
exit 1
fi
# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
depfile=${depfile-`echo "$object" |
sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
rm -f "$tmpdepfile"
# Avoid interferences from the environment.
gccflag= dashmflag=
# Some modes work just like other modes, but use different flags. We
# parameterize here, but still list the modes in the big case below,
# to make depend.m4 easier to write. Note that we *cannot* use a case
# here, because this file can only contain one case statement.
if test "$depmode" = hp; then
# HP compiler uses -M and no extra arg.
gccflag=-M
depmode=gcc
fi
if test "$depmode" = dashXmstdout; then
# This is just like dashmstdout with a different argument.
dashmflag=-xM
depmode=dashmstdout
fi
cygpath_u="cygpath -u -f -"
if test "$depmode" = msvcmsys; then
# This is just like msvisualcpp but w/o cygpath translation.
# Just convert the backslash-escaped backslashes to single forward
# slashes to satisfy depend.m4
cygpath_u='sed s,\\\\,/,g'
depmode=msvisualcpp
fi
if test "$depmode" = msvc7msys; then
# This is just like msvc7 but w/o cygpath translation.
# Just convert the backslash-escaped backslashes to single forward
# slashes to satisfy depend.m4
cygpath_u='sed s,\\\\,/,g'
depmode=msvc7
fi
if test "$depmode" = xlc; then
# IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information.
gccflag=-qmakedep=gcc,-MF
depmode=gcc
fi
case "$depmode" in
gcc3)
## gcc 3 implements dependency tracking that does exactly what
## we want. Yay! Note: for some reason libtool 1.4 doesn't like
## it if -MD -MP comes after the -MF stuff. Hmm.
## Unfortunately, FreeBSD c89 acceptance of flags depends upon
## the command line argument order; so add the flags where they
## appear in depend2.am. Note that the slowdown incurred here
## affects only configure: in makefiles, %FASTDEP% shortcuts this.
for arg
do
case $arg in
-c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
*) set fnord "$@" "$arg" ;;
esac
shift # fnord
shift # $arg
done
"$@"
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
mv "$tmpdepfile" "$depfile"
;;
gcc)
## Note that this doesn't just cater to obsosete pre-3.x GCC compilers.
## but also to in-use compilers like IMB xlc/xlC and the HP C compiler.
## (see the conditional assignment to $gccflag above).
## There are various ways to get dependency output from gcc. Here's
## why we pick this rather obscure method:
## - Don't want to use -MD because we'd like the dependencies to end
## up in a subdir. Having to rename by hand is ugly.
## (We might end up doing this anyway to support other compilers.)
## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
## -MM, not -M (despite what the docs say). Also, it might not be
## supported by the other compilers which use the 'gcc' depmode.
## - Using -M directly means running the compiler twice (even worse
## than renaming).
if test -z "$gccflag"; then
gccflag=-MD,
fi
"$@" -Wp,"$gccflag$tmpdepfile"
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
echo "$object : \\" > "$depfile"
# The second -e expression handles DOS-style file names with drive
# letters.
sed -e 's/^[^:]*: / /' \
-e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
## This next piece of magic avoids the "deleted header file" problem.
## The problem is that when a header file which appears in a .P file
## is deleted, the dependency causes make to die (because there is
## typically no way to rebuild the header). We avoid this by adding
## dummy dependencies for each header file. Too bad gcc doesn't do
## this for us directly.
## Some versions of gcc put a space before the ':'. On the theory
## that the space means something, we add a space to the output as
## well. hp depmode also adds that space, but also prefixes the VPATH
## to the object. Take care to not repeat it in the output.
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
tr ' ' "$nl" < "$tmpdepfile" \
| sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \
| sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
hp)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
sgi)
if test "$libtool" = yes; then
"$@" "-Wp,-MDupdate,$tmpdepfile"
else
"$@" -MDupdate "$tmpdepfile"
fi
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
echo "$object : \\" > "$depfile"
# Clip off the initial element (the dependent). Don't try to be
# clever and replace this with sed code, as IRIX sed won't handle
# lines with more than a fixed number of characters (4096 in
# IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
# the IRIX cc adds comments like '#:fec' to the end of the
# dependency line.
tr ' ' "$nl" < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \
| tr "$nl" ' ' >> "$depfile"
echo >> "$depfile"
# The second pass generates a dummy entry for each header file.
tr ' ' "$nl" < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
>> "$depfile"
else
make_dummy_depfile
fi
rm -f "$tmpdepfile"
;;
xlc)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
aix)
# The C for AIX Compiler uses -M and outputs the dependencies
# in a .u file. In older versions, this file always lives in the
# current directory. Also, the AIX compiler puts '$object:' at the
# start of each line; $object doesn't have directory information.
# Version 6 uses the directory in both cases.
set_dir_from "$object"
set_base_from "$object"
if test "$libtool" = yes; then
tmpdepfile1=$dir$base.u
tmpdepfile2=$base.u
tmpdepfile3=$dir.libs/$base.u
"$@" -Wc,-M
else
tmpdepfile1=$dir$base.u
tmpdepfile2=$dir$base.u
tmpdepfile3=$dir$base.u
"$@" -M
fi
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
do
test -f "$tmpdepfile" && break
done
aix_post_process_depfile
;;
tcc)
# tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26
# FIXME: That version still under development at the moment of writing.
# Make that this statement remains true also for stable, released
# versions.
# It will wrap lines (doesn't matter whether long or short) with a
# trailing '\', as in:
#
# foo.o : \
# foo.c \
# foo.h \
#
# It will put a trailing '\' even on the last line, and will use leading
# spaces rather than leading tabs (at least since its commit 0394caf7
# "Emit spaces for -MD").
"$@" -MD -MF "$tmpdepfile"
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
# Each non-empty line is of the form 'foo.o : \' or ' dep.h \'.
# We have to change lines of the first kind to '$object: \'.
sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile"
# And for each line of the second kind, we have to emit a 'dep.h:'
# dummy dependency, to avoid the deleted-header problem.
sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile"
rm -f "$tmpdepfile"
;;
## The order of this option in the case statement is important, since the
## shell code in configure will try each of these formats in the order
## listed in this file. A plain '-MD' option would be understood by many
## compilers, so we must ensure this comes after the gcc and icc options.
pgcc)
# Portland's C compiler understands '-MD'.
# Will always output deps to 'file.d' where file is the root name of the
# source file under compilation, even if file resides in a subdirectory.
# The object file name does not affect the name of the '.d' file.
# pgcc 10.2 will output
# foo.o: sub/foo.c sub/foo.h
# and will wrap long lines using '\' :
# foo.o: sub/foo.c ... \
# sub/foo.h ... \
# ...
set_dir_from "$object"
# Use the source, not the object, to determine the base name, since
# that's sadly what pgcc will do too.
set_base_from "$source"
tmpdepfile=$base.d
# For projects that build the same source file twice into different object
# files, the pgcc approach of using the *source* file root name can cause
# problems in parallel builds. Use a locking strategy to avoid stomping on
# the same $tmpdepfile.
lockdir=$base.d-lock
trap "
echo '$0: caught signal, cleaning up...' >&2
rmdir '$lockdir'
exit 1
" 1 2 13 15
numtries=100
i=$numtries
while test $i -gt 0; do
# mkdir is a portable test-and-set.
if mkdir "$lockdir" 2>/dev/null; then
# This process acquired the lock.
"$@" -MD
stat=$?
# Release the lock.
rmdir "$lockdir"
break
else
# If the lock is being held by a different process, wait
# until the winning process is done or we timeout.
while test -d "$lockdir" && test $i -gt 0; do
sleep 1
i=`expr $i - 1`
done
fi
i=`expr $i - 1`
done
trap - 1 2 13 15
if test $i -le 0; then
echo "$0: failed to acquire lock after $numtries attempts" >&2
echo "$0: check lockdir '$lockdir'" >&2
exit 1
fi
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
# Each line is of the form `foo.o: dependent.h',
# or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
# Do two passes, one to just change these to
# `$object: dependent.h' and one to simply `dependent.h:'.
sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
# Some versions of the HPUX 10.20 sed can't process this invocation
# correctly. Breaking it into two sed invocations is a workaround.
sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \
| sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
hp2)
# The "hp" stanza above does not work with aCC (C++) and HP's ia64
# compilers, which have integrated preprocessors. The correct option
# to use with these is +Maked; it writes dependencies to a file named
# 'foo.d', which lands next to the object file, wherever that
# happens to be.
# Much of this is similar to the tru64 case; see comments there.
set_dir_from "$object"
set_base_from "$object"
if test "$libtool" = yes; then
tmpdepfile1=$dir$base.d
tmpdepfile2=$dir.libs/$base.d
"$@" -Wc,+Maked
else
tmpdepfile1=$dir$base.d
tmpdepfile2=$dir$base.d
"$@" +Maked
fi
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile1" "$tmpdepfile2"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
do
test -f "$tmpdepfile" && break
done
if test -f "$tmpdepfile"; then
sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile"
# Add 'dependent.h:' lines.
sed -ne '2,${
s/^ *//
s/ \\*$//
s/$/:/
p
}' "$tmpdepfile" >> "$depfile"
else
make_dummy_depfile
fi
rm -f "$tmpdepfile" "$tmpdepfile2"
;;
tru64)
# The Tru64 compiler uses -MD to generate dependencies as a side
# effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'.
# At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
# dependencies in 'foo.d' instead, so we check for that too.
# Subdirectories are respected.
set_dir_from "$object"
set_base_from "$object"
if test "$libtool" = yes; then
# Libtool generates 2 separate objects for the 2 libraries. These
# two compilations output dependencies in $dir.libs/$base.o.d and
# in $dir$base.o.d. We have to check for both files, because
# one of the two compilations can be disabled. We should prefer
# $dir$base.o.d over $dir.libs/$base.o.d because the latter is
# automatically cleaned when .libs/ is deleted, while ignoring
# the former would cause a distcleancheck panic.
tmpdepfile1=$dir$base.o.d # libtool 1.5
tmpdepfile2=$dir.libs/$base.o.d # Likewise.
tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504
"$@" -Wc,-MD
else
tmpdepfile1=$dir$base.d
tmpdepfile2=$dir$base.d
tmpdepfile3=$dir$base.d
"$@" -MD
fi
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
do
test -f "$tmpdepfile" && break
done
# Same post-processing that is required for AIX mode.
aix_post_process_depfile
;;
msvc7)
if test "$libtool" = yes; then
showIncludes=-Wc,-showIncludes
else
showIncludes=-showIncludes
fi
"$@" $showIncludes > "$tmpdepfile"
stat=$?
grep -v '^Note: including file: ' "$tmpdepfile"
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
echo "$object : \\" > "$depfile"
# The first sed program below extracts the file names and escapes
# backslashes for cygpath. The second sed program outputs the file
# name when reading, but also accumulates all include files in the
# hold buffer in order to output them again at the end. This only
# works with sed implementations that can handle large buffers.
sed < "$tmpdepfile" -n '
/^Note: including file: *\(.*\)/ {
s//\1/
s/\\/\\\\/g
p
}' | $cygpath_u | sort -u | sed -n '
s/ /\\ /g
s/\(.*\)/'"$tab"'\1 \\/p
s/.\(.*\) \\/\1:/
H
$ {
s/.*/'"$tab"'/
G
p
}' >> "$depfile"
echo >> "$depfile" # make sure the fragment doesn't end with a backslash
rm -f "$tmpdepfile"
;;
msvc7msys)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
#nosideeffect)
# This comment above is used by automake to tell side-effect
# dependency tracking mechanisms from slower ones.
dashmstdout)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout, regardless of -o.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
# Remove '-o $object'.
IFS=" "
for arg
do
case $arg in
-o)
shift
;;
$object)
shift
;;
*)
set fnord "$@" "$arg"
shift # fnord
shift # $arg
;;
esac
done
test -z "$dashmflag" && dashmflag=-M
# Require at least two characters before searching for ':'
# in the target name. This is to cope with DOS-style filenames:
# a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise.
"$@" $dashmflag |
sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile"
rm -f "$depfile"
cat < "$tmpdepfile" > "$depfile"
# Some versions of the HPUX 10.20 sed can't process this sed invocation
# correctly. Breaking it into two sed invocations is a workaround.
tr ' ' "$nl" < "$tmpdepfile" \
| sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
| sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
dashXmstdout)
# This case only exists to satisfy depend.m4. It is never actually
# run, as this mode is specially recognized in the preamble.
exit 1
;;
makedepend)
"$@" || exit $?
# Remove any Libtool call
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
# X makedepend
shift
cleared=no eat=no
for arg
do
case $cleared in
no)
set ""; shift
cleared=yes ;;
esac
if test $eat = yes; then
eat=no
continue
fi
case "$arg" in
-D*|-I*)
set fnord "$@" "$arg"; shift ;;
# Strip any option that makedepend may not understand. Remove
# the object too, otherwise makedepend will parse it as a source file.
-arch)
eat=yes ;;
-*|$object)
;;
*)
set fnord "$@" "$arg"; shift ;;
esac
done
obj_suffix=`echo "$object" | sed 's/^.*\././'`
touch "$tmpdepfile"
${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
rm -f "$depfile"
# makedepend may prepend the VPATH from the source file name to the object.
# No need to regex-escape $object, excess matching of '.' is harmless.
sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile"
# Some versions of the HPUX 10.20 sed can't process the last invocation
# correctly. Breaking it into two sed invocations is a workaround.
sed '1,2d' "$tmpdepfile" \
| tr ' ' "$nl" \
| sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
| sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile" "$tmpdepfile".bak
;;
cpp)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
# Remove '-o $object'.
IFS=" "
for arg
do
case $arg in
-o)
shift
;;
$object)
shift
;;
*)
set fnord "$@" "$arg"
shift # fnord
shift # $arg
;;
esac
done
"$@" -E \
| sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
-e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
| sed '$ s: \\$::' > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
cat < "$tmpdepfile" >> "$depfile"
sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
msvisualcpp)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
IFS=" "
for arg
do
case "$arg" in
-o)
shift
;;
$object)
shift
;;
"-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
set fnord "$@"
shift
shift
;;
*)
set fnord "$@" "$arg"
shift
shift
;;
esac
done
"$@" -E 2>/dev/null |
sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile"
echo "$tab" >> "$depfile"
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
rm -f "$tmpdepfile"
;;
msvcmsys)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
none)
exec "$@"
;;
*)
echo "Unknown depmode $depmode" 1>&2
exit 1
;;
esac
exit 0
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC0"
# time-stamp-end: "; # UTC"
# End:

View file

@ -1,46 +0,0 @@
/*
* ircd-ratbox: A slightly useful ircd.
* commio-ssl.h: A header for the ssl code
*
* Copyright (C) 2008 ircd-ratbox development team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*
* $Id: commio-ssl.h 26280 2008-12-10 20:25:29Z androsyn $
*/
#ifndef _COMMIO_SSL_H
#define _COMMIO_SSL_H
int rb_setup_ssl_server(const char *cert, const char *keyfile, const char *dhfile, const char *cipher_list, const char *hostname);
int rb_init_ssl(void);
int rb_ssl_listen(rb_fde_t *F, int backlog, int defer_accept);
int rb_init_prng(const char *path, prng_seed_t seed_type);
int rb_get_random(void *buf, size_t length);
const char *rb_get_ssl_strerror(rb_fde_t *F);
void rb_ssl_start_accepted(rb_fde_t *new_F, ACCB * cb, void *data, int timeout);
void rb_ssl_start_connected(rb_fde_t *F, CNCB * callback, void *data, int timeout);
void rb_connect_tcp_ssl(rb_fde_t *F, struct sockaddr *dest, struct sockaddr *clocal, int socklen,
CNCB * callback, void *data, int timeout);
void rb_ssl_accept_setup(rb_fde_t *F, rb_fde_t *new_F, struct sockaddr *st, int addrlen);
void rb_ssl_shutdown(rb_fde_t *F);
ssize_t rb_ssl_read(rb_fde_t *F, void *buf, size_t count);
ssize_t rb_ssl_write(rb_fde_t *F, const void *buf, size_t count);
void rb_get_ssl_info(char *buf, size_t length);
#endif

View file

@ -1,225 +0,0 @@
/*
* $Id: ratbox_lib.h 26256 2008-12-10 04:05:26Z androsyn $
*/
#ifndef RB_LIB_H
#define RB_LIB_H 1
#include <librb-config.h>
#include <stdio.h>
#include <limits.h>
#include <stdarg.h>
#include <assert.h>
#include <fcntl.h>
#include <signal.h>
#include <ctype.h>
#ifdef HAVE_LINUX_TCP_H
# include <linux/tcp.h>
#endif
#ifdef __GNUC__
#undef alloca
#define alloca __builtin_alloca
#else
# ifdef _MSC_VER
# include <malloc.h>
# define alloca _alloca
# else
# if RB_HAVE_ALLOCA_H
# include <alloca.h>
# else
# ifdef _AIX
#pragma alloca
# else
# ifndef alloca /* predefined by HP cc +Olibcalls */
char *alloca();
# endif
# endif
# endif
# endif
#endif /* __GNUC__ */
#ifdef __GNUC__
#ifdef rb_likely
#undef rb_likely
#endif
#ifdef rb_unlikely
#undef rb_unlikely
#endif
#if __GNUC__ == 2 && __GNUC_MINOR__ < 96
# define __builtin_expect(x, expected_value) (x)
#endif
#define rb_likely(x) __builtin_expect(!!(x), 1)
#define rb_unlikely(x) __builtin_expect(!!(x), 0)
#else /* !__GNUC__ */
#define UNUSED(x) x
#ifdef rb_likely
#undef rb_likely
#endif
#ifdef rb_unlikely
#undef rb_unlikely
#endif
#define rb_likely(x) (x)
#define rb_unlikely(x) (x)
#endif
#ifdef _WIN32
#include <process.h>
#ifndef PATH_MAX
#define PATH_MAX 128
#endif
#ifdef strerror
#undef strerror
#endif
#define strerror(x) rb_strerror(x)
char *rb_strerror(int error);
#define ENOBUFS WSAENOBUFS
#define EINPROGRESS WSAEINPROGRESS
#define EWOULDBLOCK WSAEWOULDBLOCK
#define EMSGSIZE WSAEMSGSIZE
#define EALREADY WSAEALREADY
#define EISCONN WSAEISCONN
#define EADDRINUSE WSAEADDRINUSE
#define EAFNOSUPPORT WSAEAFNOSUPPORT
#define pipe(x) _pipe(x, 1024, O_BINARY)
#define ioctl(x,y,z) ioctlsocket(x,y, (u_long *)z)
#define WNOHANG 1
#ifndef SIGKILL
#define SIGKILL SIGTERM
#endif
#endif /* _WIN32 */
#ifndef HOSTIPLEN
#define HOSTIPLEN 53
#endif
#ifdef __GNUC__
#define slrb_assert(expr) do \
if(rb_unlikely(!(expr))) { \
rb_lib_log( \
"file: %s line: %d (%s): Assertion failed: (%s)", \
__FILE__, __LINE__, __PRETTY_FUNCTION__, #expr); \
} \
while(0)
#else
#define slrb_assert(expr) do \
if(rb_unlikely(!(expr))) { \
rb_lib_log( \
"file: %s line: %d: Assertion failed: (%s)", \
__FILE__, __LINE__, #expr); \
} \
while(0)
#endif
#ifdef SOFT_ASSERT
#define lrb_assert(expr) slrb_assert(expr)
#else
#define lrb_assert(expr) do { slrb_assert(expr); assert(expr); } while(0)
#endif
#ifdef RB_SOCKADDR_HAS_SA_LEN
#define ss_len sa_len
#endif
#define GET_SS_FAMILY(x) (((const struct sockaddr *)(x))->sa_family)
#define SET_SS_FAMILY(x, y) ((((struct sockaddr *)(x))->sa_family) = y)
#ifdef RB_SOCKADDR_HAS_SA_LEN
#define SET_SS_LEN(x, y) do { \
struct sockaddr *storage; \
storage = ((struct sockaddr *)(x));\
storage->sa_len = (y); \
} while (0)
#define GET_SS_LEN(x) (((struct sockaddr *)(x))->sa_len)
#else /* !RB_SOCKADDR_HAS_SA_LEN */
#define SET_SS_LEN(x, y) (((struct sockaddr *)(x))->sa_family = ((struct sockaddr *)(x))->sa_family)
#ifdef RB_IPV6
#define GET_SS_LEN(x) (((struct sockaddr *)(x))->sa_family == AF_INET ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6))
#else
#define GET_SS_LEN(x) (((struct sockaddr *)(x))->sa_family == AF_INET ? sizeof(struct sockaddr_in) : 0)
#endif
#endif
#ifndef INADDRSZ
#define INADDRSZ 4
#endif
#ifndef IN6ADDRSZ
#define IN6ADDRSZ 16
#endif
#ifndef INT16SZ
#define INT16SZ 2
#endif
typedef void log_cb(const char *buffer);
typedef void restart_cb(const char *buffer);
typedef void die_cb(const char *buffer);
char *rb_ctime(const time_t, char *, size_t);
char *rb_date(const time_t, char *, size_t);
void rb_lib_log(const char *, ...);
void rb_lib_restart(const char *, ...) __attribute__((noreturn));
void rb_lib_die(const char *, ...);
void rb_set_time(void);
const char *rb_lib_version(void);
void rb_lib_init(log_cb * xilog, restart_cb * irestart, die_cb * idie, int closeall, int maxfds,
size_t dh_size, size_t fd_heap_size);
void rb_lib_loop(long delay) __attribute__((noreturn));
time_t rb_current_time(void);
const struct timeval *rb_current_time_tv(void);
pid_t rb_spawn_process(const char *, const char **);
char *rb_strtok_r(char *, const char *, char **);
int rb_gettimeofday(struct timeval *, void *);
void rb_sleep(unsigned int seconds, unsigned int useconds);
char *rb_crypt(const char *, const char *);
unsigned char *rb_base64_encode(const unsigned char *str, int length);
unsigned char *rb_base64_decode(const unsigned char *str, int length, int *ret);
int rb_kill(pid_t, int);
char *rb_strerror(int);
int rb_setenv(const char *, const char *, int);
pid_t rb_waitpid(pid_t pid, int *status, int options);
pid_t rb_getpid(void);
//unsigned int rb_geteuid(void);
#include <rb_tools.h>
#include <rb_memory.h>
#include <rb_commio.h>
#include <rb_balloc.h>
#include <rb_linebuf.h>
#include <rb_snprintf.h>
#include <rb_event.h>
#include <rb_helper.h>
#include <rb_rawbuf.h>
#include <rb_patricia.h>
#endif

View file

@ -1,210 +0,0 @@
/*
* ircd-ratbox: A slightly useful ircd.
* commio.h: A header for the network subsystem.
*
* Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
* Copyright (C) 1996-2002 Hybrid Development Team
* Copyright (C) 2002-2005 ircd-ratbox development team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*
* $Id: rb_commio.h 26092 2008-09-19 15:13:52Z androsyn $
*/
#ifndef RB_LIB_H
# error "Do not use commio.h directly"
#endif
#ifndef INCLUDED_commio_h
#define INCLUDED_commio_h
struct sockaddr;
struct _fde;
typedef struct _fde rb_fde_t;
/* Callback for completed IO events */
typedef void PF(rb_fde_t *, void *);
/* Callback for completed connections */
/* int fd, int status, void * */
typedef void CNCB(rb_fde_t *, int, void *);
/* callback for fd table dumps */
typedef void DUMPCB(int, const char *desc, void *);
/* callback for accept callbacks */
typedef void ACCB(rb_fde_t *, int status, struct sockaddr *addr, rb_socklen_t len, void *);
/* callback for pre-accept callback */
typedef int ACPRE(rb_fde_t *, struct sockaddr *addr, rb_socklen_t len, void *);
enum
{
RB_OK,
RB_ERR_BIND,
RB_ERR_DNS,
RB_ERR_TIMEOUT,
RB_ERR_CONNECT,
RB_ERROR,
RB_ERROR_SSL,
RB_ERR_MAX
};
#define RB_FD_NONE 0x01
#define RB_FD_FILE 0x02
#define RB_FD_SOCKET 0x04
#ifndef _WIN32
#define RB_FD_PIPE 0x08
#else
#define RB_FD_PIPE RB_FD_SOCKET
#endif
#define RB_FD_LISTEN 0x10
#define RB_FD_SSL 0x20
#define RB_FD_UNKNOWN 0x40
#define RB_RW_IO_ERROR -1 /* System call error */
#define RB_RW_SSL_ERROR -2 /* SSL Error */
#define RB_RW_SSL_NEED_READ -3 /* SSL Needs read */
#define RB_RW_SSL_NEED_WRITE -4 /* SSL Needs write */
struct rb_iovec
{
void *iov_base;
size_t iov_len;
};
void rb_fdlist_init(int closeall, int maxfds, size_t heapsize);
rb_fde_t *rb_open(int, uint8_t, const char *);
void rb_close(rb_fde_t *);
void rb_dump_fd(DUMPCB *, void *xdata);
void rb_note(rb_fde_t *, const char *);
/* Type of IO */
#define RB_SELECT_READ 0x1
#define RB_SELECT_WRITE 0x2
#define RB_SELECT_ACCEPT RB_SELECT_READ
#define RB_SELECT_CONNECT RB_SELECT_WRITE
#define RB_SSL_CERTFP_LEN 64
/* Methods for certfp */
/* Digest of full X.509 certificate */
#define RB_SSL_CERTFP_METH_CERT_SHA1 0x0000
#define RB_SSL_CERTFP_METH_CERT_SHA256 0x0001
#define RB_SSL_CERTFP_METH_CERT_SHA512 0x0002
/* Digest of SubjectPublicKeyInfo (RFC 5280), used by DANE (RFC 6698) */
#define RB_SSL_CERTFP_METH_SPKI_SHA256 0x1001
#define RB_SSL_CERTFP_METH_SPKI_SHA512 0x1002
/* Names for certfp */
#define CERTFP_NAME_CERT_SHA1 "sha1"
#define CERTFP_PREFIX_CERT_SHA1 ""
#define CERTFP_NAME_CERT_SHA256 "sha256"
#define CERTFP_PREFIX_CERT_SHA256 ""
#define CERTFP_NAME_CERT_SHA512 "sha512"
#define CERTFP_PREFIX_CERT_SHA512 ""
/* These prefixes are copied from RFC 7218 */
#define CERTFP_NAME_SPKI_SHA256 "spki_sha256"
#define CERTFP_PREFIX_SPKI_SHA256 "SPKI:SHA2-256:"
#define CERTFP_NAME_SPKI_SHA512 "spki_sha512"
#define CERTFP_PREFIX_SPKI_SHA512 "SPKI:SHA2-512:"
#define RB_SSL_CERTFP_LEN_SHA1 20
#define RB_SSL_CERTFP_LEN_SHA256 32
#define RB_SSL_CERTFP_LEN_SHA512 64
int rb_set_nb(rb_fde_t *);
int rb_set_buffers(rb_fde_t *, int);
int rb_get_sockerr(rb_fde_t *);
void rb_settimeout(rb_fde_t *, time_t, PF *, void *);
void rb_checktimeouts(void *);
void rb_connect_tcp(rb_fde_t *, struct sockaddr *, struct sockaddr *, int, CNCB *, void *, int);
void rb_connect_tcp_ssl(rb_fde_t *, struct sockaddr *, struct sockaddr *, int, CNCB *, void *, int);
int rb_connect_sockaddr(rb_fde_t *, struct sockaddr *addr, int len);
const char *rb_errstr(int status);
rb_fde_t *rb_socket(int family, int sock_type, int proto, const char *note);
int rb_socketpair(int family, int sock_type, int proto, rb_fde_t **F1, rb_fde_t **F2,
const char *note);
void rb_accept_tcp(rb_fde_t *, ACPRE * precb, ACCB * callback, void *data);
ssize_t rb_write(rb_fde_t *, const void *buf, int count);
ssize_t rb_writev(rb_fde_t *, struct rb_iovec *vector, int count);
ssize_t rb_read(rb_fde_t *, void *buf, int count);
int rb_pipe(rb_fde_t **, rb_fde_t **, const char *desc);
int rb_setup_ssl_server(const char *cert, const char *keyfile, const char *dhfile, const char *cipher_list, const char *hostname);
int rb_ssl_listen(rb_fde_t *, int backlog, int defer_accept);
int rb_listen(rb_fde_t *, int backlog, int defer_accept);
int rb_remove_ssl_vserver(const char *hostname);
const char *rb_inet_ntop(int af, const void *src, char *dst, unsigned int size);
int rb_inet_pton(int af, const char *src, void *dst);
const char *rb_inet_ntop_sock(struct sockaddr *src, char *dst, unsigned int size);
int rb_inet_pton_sock(const char *src, struct sockaddr *dst);
int rb_getmaxconnect(void);
int rb_ignore_errno(int);
/* Generic wrappers */
void rb_setselect(rb_fde_t *, unsigned int type, PF * handler, void *client_data);
void rb_init_netio(void);
int rb_select(unsigned long);
int rb_fd_ssl(rb_fde_t *F);
int rb_get_fd(rb_fde_t *F);
const char *rb_get_ssl_strerror(rb_fde_t *F);
int rb_get_ssl_certfp(rb_fde_t *F, uint8_t certfp[RB_SSL_CERTFP_LEN], int method);
rb_fde_t *rb_get_fde(int fd);
int rb_send_fd_buf(rb_fde_t *xF, rb_fde_t **F, int count, void *data, size_t datasize, pid_t pid);
int rb_recv_fd_buf(rb_fde_t *F, void *data, size_t datasize, rb_fde_t **xF, int count);
void rb_set_type(rb_fde_t *F, uint8_t type);
uint8_t rb_get_type(rb_fde_t *F);
const char *rb_get_iotype(void);
typedef enum
{
RB_PRNG_FILE,
#ifdef _WIN32
RB_PRNGWIN32,
#endif
RB_PRNG_DEFAULT,
} prng_seed_t;
int rb_init_prng(const char *path, prng_seed_t seed_type);
int rb_get_random(void *buf, size_t len);
void rb_ssl_start_accepted(rb_fde_t *new_F, ACCB * cb, void *data, int timeout);
void rb_ssl_start_connected(rb_fde_t *F, CNCB * callback, void *data, int timeout);
int rb_supports_ssl(void);
unsigned int rb_ssl_handshake_count(rb_fde_t *F);
void rb_ssl_clear_handshake_count(rb_fde_t *F);
int rb_pass_fd_to_process(rb_fde_t *, pid_t, rb_fde_t *);
rb_fde_t *rb_recv_fd(rb_fde_t *);
const char *rb_ssl_get_cipher(rb_fde_t *F);
#endif /* INCLUDED_commio_h */

View file

@ -1,63 +0,0 @@
/*
* ircd-ratbox: A slightly useful ircd
* helper.h: Starts and deals with ircd helpers
*
* Copyright (C) 2006 Aaron Sethman <androsyn@ratbox.org>
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*
* $Id: rb_helper.h 26092 2008-09-19 15:13:52Z androsyn $
*/
#ifndef RB_LIB_H
# error "Do not use helper.h directly"
#endif
#ifndef INCLUDED_helper_h
#define INCLUDED_helper_h
struct _rb_helper;
typedef struct _rb_helper rb_helper;
typedef void rb_helper_cb(rb_helper *);
rb_helper *rb_helper_start(const char *name, const char *fullpath, rb_helper_cb * read_cb,
rb_helper_cb * error_cb);
rb_helper *rb_helper_child(rb_helper_cb * read_cb, rb_helper_cb * error_cb,
log_cb * ilog, restart_cb * irestart, die_cb * idie,
size_t lb_heap_size, size_t dh_size, size_t fd_heap_size);
void rb_helper_restart(rb_helper *helper);
#ifdef __GNUC__
void
rb_helper_write(rb_helper *helper, const char *format, ...)
__attribute((format(printf, 2, 3)));
void rb_helper_write_queue(rb_helper *helper, const char *format, ...)
__attribute((format(printf, 2, 3)));
#else
void rb_helper_write(rb_helper *helper, const char *format, ...);
void rb_helper_write_queue(rb_helper *helper, const char *format, ...);
#endif
void rb_helper_write_flush(rb_helper *helper);
void rb_helper_run(rb_helper *helper);
void rb_helper_close(rb_helper *helper);
int rb_helper_read(rb_helper *helper, void *buf, size_t bufsize);
void rb_helper_loop(rb_helper *helper, long delay) __attribute__((noreturn));
#endif

View file

@ -1,86 +0,0 @@
/*
* ircd-ratbox: A slightly useful ircd.
* memory.h: A header for the memory functions.
*
* Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
* Copyright (C) 1996-2002 Hybrid Development Team
* Copyright (C) 2002-2005 ircd-ratbox development team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*
* $Id: rb_memory.h 26092 2008-09-19 15:13:52Z androsyn $
*/
#ifndef RB_LIB_H
#error "Do not use rb_memory.h directly"
#endif
#ifndef _RB_MEMORY_H
#define _RB_MEMORY_H
#include <stdlib.h>
void rb_outofmemory(void) __attribute__((noreturn));
static inline void *
rb_malloc(size_t size)
{
void *ret = calloc(1, size);
if(rb_unlikely(ret == NULL))
rb_outofmemory();
return (ret);
}
static inline void *
rb_realloc(void *x, size_t y)
{
void *ret = realloc(x, y);
if(rb_unlikely(ret == NULL))
rb_outofmemory();
return (ret);
}
static inline char *
rb_strndup(const char *x, size_t y)
{
char *ret = malloc(y);
if(rb_unlikely(ret == NULL))
rb_outofmemory();
rb_strlcpy(ret, x, y);
return (ret);
}
static inline char *
rb_strdup(const char *x)
{
char *ret = malloc(strlen(x) + 1);
if(rb_unlikely(ret == NULL))
rb_outofmemory();
strcpy(ret, x);
return (ret);
}
static inline void
rb_free(void *ptr)
{
if(rb_likely(ptr != NULL))
free(ptr);
}
#endif /* _I_MEMORY_H */

View file

@ -1,508 +0,0 @@
#!/bin/sh
# install - install a program, script, or datafile
scriptversion=2014-09-12.12; # UTC
# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
# following copyright and license.
#
# Copyright (C) 1994 X Consortium
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name of the X Consortium shall not
# be used in advertising or otherwise to promote the sale, use or other deal-
# ings in this Software without prior written authorization from the X Consor-
# tium.
#
#
# FSF changes to this file are in the public domain.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# 'make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch.
tab=' '
nl='
'
IFS=" $tab$nl"
# Set DOITPROG to "echo" to test this script.
doit=${DOITPROG-}
doit_exec=${doit:-exec}
# Put in absolute file names if you don't have them in your path;
# or use environment vars.
chgrpprog=${CHGRPPROG-chgrp}
chmodprog=${CHMODPROG-chmod}
chownprog=${CHOWNPROG-chown}
cmpprog=${CMPPROG-cmp}
cpprog=${CPPROG-cp}
mkdirprog=${MKDIRPROG-mkdir}
mvprog=${MVPROG-mv}
rmprog=${RMPROG-rm}
stripprog=${STRIPPROG-strip}
posix_mkdir=
# Desired mode of installed file.
mode=0755
chgrpcmd=
chmodcmd=$chmodprog
chowncmd=
mvcmd=$mvprog
rmcmd="$rmprog -f"
stripcmd=
src=
dst=
dir_arg=
dst_arg=
copy_on_change=false
is_target_a_directory=possibly
usage="\
Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
or: $0 [OPTION]... SRCFILES... DIRECTORY
or: $0 [OPTION]... -t DIRECTORY SRCFILES...
or: $0 [OPTION]... -d DIRECTORIES...
In the 1st form, copy SRCFILE to DSTFILE.
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
In the 4th, create DIRECTORIES.
Options:
--help display this help and exit.
--version display version info and exit.
-c (ignored)
-C install only if different (preserve the last data modification time)
-d create directories instead of installing files.
-g GROUP $chgrpprog installed files to GROUP.
-m MODE $chmodprog installed files to MODE.
-o USER $chownprog installed files to USER.
-s $stripprog installed files.
-t DIRECTORY install into DIRECTORY.
-T report an error if DSTFILE is a directory.
Environment variables override the default commands:
CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
RMPROG STRIPPROG
"
while test $# -ne 0; do
case $1 in
-c) ;;
-C) copy_on_change=true;;
-d) dir_arg=true;;
-g) chgrpcmd="$chgrpprog $2"
shift;;
--help) echo "$usage"; exit $?;;
-m) mode=$2
case $mode in
*' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
echo "$0: invalid mode: $mode" >&2
exit 1;;
esac
shift;;
-o) chowncmd="$chownprog $2"
shift;;
-s) stripcmd=$stripprog;;
-t)
is_target_a_directory=always
dst_arg=$2
# Protect names problematic for 'test' and other utilities.
case $dst_arg in
-* | [=\(\)!]) dst_arg=./$dst_arg;;
esac
shift;;
-T) is_target_a_directory=never;;
--version) echo "$0 $scriptversion"; exit $?;;
--) shift
break;;
-*) echo "$0: invalid option: $1" >&2
exit 1;;
*) break;;
esac
shift
done
# We allow the use of options -d and -T together, by making -d
# take the precedence; this is for compatibility with GNU install.
if test -n "$dir_arg"; then
if test -n "$dst_arg"; then
echo "$0: target directory not allowed when installing a directory." >&2
exit 1
fi
fi
if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
# When -d is used, all remaining arguments are directories to create.
# When -t is used, the destination is already specified.
# Otherwise, the last argument is the destination. Remove it from $@.
for arg
do
if test -n "$dst_arg"; then
# $@ is not empty: it contains at least $arg.
set fnord "$@" "$dst_arg"
shift # fnord
fi
shift # arg
dst_arg=$arg
# Protect names problematic for 'test' and other utilities.
case $dst_arg in
-* | [=\(\)!]) dst_arg=./$dst_arg;;
esac
done
fi
if test $# -eq 0; then
if test -z "$dir_arg"; then
echo "$0: no input file specified." >&2
exit 1
fi
# It's OK to call 'install-sh -d' without argument.
# This can happen when creating conditional directories.
exit 0
fi
if test -z "$dir_arg"; then
if test $# -gt 1 || test "$is_target_a_directory" = always; then
if test ! -d "$dst_arg"; then
echo "$0: $dst_arg: Is not a directory." >&2
exit 1
fi
fi
fi
if test -z "$dir_arg"; then
do_exit='(exit $ret); exit $ret'
trap "ret=129; $do_exit" 1
trap "ret=130; $do_exit" 2
trap "ret=141; $do_exit" 13
trap "ret=143; $do_exit" 15
# Set umask so as not to create temps with too-generous modes.
# However, 'strip' requires both read and write access to temps.
case $mode in
# Optimize common cases.
*644) cp_umask=133;;
*755) cp_umask=22;;
*[0-7])
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw='% 200'
fi
cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
*)
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw=,u+rw
fi
cp_umask=$mode$u_plus_rw;;
esac
fi
for src
do
# Protect names problematic for 'test' and other utilities.
case $src in
-* | [=\(\)!]) src=./$src;;
esac
if test -n "$dir_arg"; then
dst=$src
dstdir=$dst
test -d "$dstdir"
dstdir_status=$?
else
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if test ! -f "$src" && test ! -d "$src"; then
echo "$0: $src does not exist." >&2
exit 1
fi
if test -z "$dst_arg"; then
echo "$0: no destination specified." >&2
exit 1
fi
dst=$dst_arg
# If destination is a directory, append the input filename; won't work
# if double slashes aren't ignored.
if test -d "$dst"; then
if test "$is_target_a_directory" = never; then
echo "$0: $dst_arg: Is a directory" >&2
exit 1
fi
dstdir=$dst
dst=$dstdir/`basename "$src"`
dstdir_status=0
else
dstdir=`dirname "$dst"`
test -d "$dstdir"
dstdir_status=$?
fi
fi
obsolete_mkdir_used=false
if test $dstdir_status != 0; then
case $posix_mkdir in
'')
# Create intermediate dirs using mode 755 as modified by the umask.
# This is like FreeBSD 'install' as of 1997-10-28.
umask=`umask`
case $stripcmd.$umask in
# Optimize common cases.
*[2367][2367]) mkdir_umask=$umask;;
.*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
*[0-7])
mkdir_umask=`expr $umask + 22 \
- $umask % 100 % 40 + $umask % 20 \
- $umask % 10 % 4 + $umask % 2
`;;
*) mkdir_umask=$umask,go-w;;
esac
# With -d, create the new directory with the user-specified mode.
# Otherwise, rely on $mkdir_umask.
if test -n "$dir_arg"; then
mkdir_mode=-m$mode
else
mkdir_mode=
fi
posix_mkdir=false
case $umask in
*[123567][0-7][0-7])
# POSIX mkdir -p sets u+wx bits regardless of umask, which
# is incompatible with FreeBSD 'install' when (umask & 300) != 0.
;;
*)
# $RANDOM is not portable (e.g. dash); use it when possible to
# lower collision chance
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0
# As "mkdir -p" follows symlinks and we work in /tmp possibly; so
# create the $tmpdir first (and fail if unsuccessful) to make sure
# that nobody tries to guess the $tmpdir name.
if (umask $mkdir_umask &&
$mkdirprog $mkdir_mode "$tmpdir" &&
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
then
if test -z "$dir_arg" || {
# Check for POSIX incompatibilities with -m.
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
# other-writable bit of parent directory when it shouldn't.
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
test_tmpdir="$tmpdir/a"
ls_ld_tmpdir=`ls -ld "$test_tmpdir"`
case $ls_ld_tmpdir in
d????-?r-*) different_mode=700;;
d????-?--*) different_mode=755;;
*) false;;
esac &&
$mkdirprog -m$different_mode -p -- "$test_tmpdir" && {
ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`
test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
}
}
then posix_mkdir=:
fi
rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"
else
# Remove any dirs left behind by ancient mkdir implementations.
rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null
fi
trap '' 0;;
esac;;
esac
if
$posix_mkdir && (
umask $mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
)
then :
else
# The umask is ridiculous, or mkdir does not conform to POSIX,
# or it failed possibly due to a race condition. Create the
# directory the slow way, step by step, checking for races as we go.
case $dstdir in
/*) prefix='/';;
[-=\(\)!]*) prefix='./';;
*) prefix='';;
esac
oIFS=$IFS
IFS=/
set -f
set fnord $dstdir
shift
set +f
IFS=$oIFS
prefixes=
for d
do
test X"$d" = X && continue
prefix=$prefix$d
if test -d "$prefix"; then
prefixes=
else
if $posix_mkdir; then
(umask=$mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
# Don't fail if two instances are running concurrently.
test -d "$prefix" || exit 1
else
case $prefix in
*\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
*) qprefix=$prefix;;
esac
prefixes="$prefixes '$qprefix'"
fi
fi
prefix=$prefix/
done
if test -n "$prefixes"; then
# Don't fail if two instances are running concurrently.
(umask $mkdir_umask &&
eval "\$doit_exec \$mkdirprog $prefixes") ||
test -d "$dstdir" || exit 1
obsolete_mkdir_used=true
fi
fi
fi
if test -n "$dir_arg"; then
{ test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
{ test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
else
# Make a couple of temp file names in the proper directory.
dsttmp=$dstdir/_inst.$$_
rmtmp=$dstdir/_rm.$$_
# Trap to clean up those temp files at exit.
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
# Copy the file name to the temp name.
(umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
# and set any options; do chmod last to preserve setuid bits.
#
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $cpprog $src $dsttmp" command.
#
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
{ test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
{ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
# If -C, don't bother to copy if it wouldn't change the file.
if $copy_on_change &&
old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
set -f &&
set X $old && old=:$2:$4:$5:$6 &&
set X $new && new=:$2:$4:$5:$6 &&
set +f &&
test "$old" = "$new" &&
$cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
then
rm -f "$dsttmp"
else
# Rename the file to the real destination.
$doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
# The rename failed, perhaps because mv can't rename something else
# to itself, or perhaps because mv is so ancient that it does not
# support -f.
{
# Now remove or move aside any old file at destination location.
# We try this two ways since rm can't unlink itself on some
# systems and the destination file might be busy for other
# reasons. In this case, the final cleanup might fail but the new
# file should still install successfully.
{
test ! -f "$dst" ||
$doit $rmcmd -f "$dst" 2>/dev/null ||
{ $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
{ $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
} ||
{ echo "$0: cannot unlink or rename $dst" >&2
(exit 1); exit 1
}
} &&
# Now rename the file to the real destination.
$doit $mvcmd "$dsttmp" "$dst"
}
fi || exit 1
trap '' 0
fi
done
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:

File diff suppressed because it is too large Load diff

View file

@ -1,215 +0,0 @@
#! /bin/sh
# Common wrapper for a few potentially missing GNU programs.
scriptversion=2013-10-28.13; # UTC
# Copyright (C) 1996-2014 Free Software Foundation, Inc.
# Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
# 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, 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, see <http://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
if test $# -eq 0; then
echo 1>&2 "Try '$0 --help' for more information"
exit 1
fi
case $1 in
--is-lightweight)
# Used by our autoconf macros to check whether the available missing
# script is modern enough.
exit 0
;;
--run)
# Back-compat with the calling convention used by older automake.
shift
;;
-h|--h|--he|--hel|--help)
echo "\
$0 [OPTION]... PROGRAM [ARGUMENT]...
Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due
to PROGRAM being missing or too old.
Options:
-h, --help display this help and exit
-v, --version output version information and exit
Supported PROGRAM values:
aclocal autoconf autoheader autom4te automake makeinfo
bison yacc flex lex help2man
Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and
'g' are ignored when checking the name.
Send bug reports to <bug-automake@gnu.org>."
exit $?
;;
-v|--v|--ve|--ver|--vers|--versi|--versio|--version)
echo "missing $scriptversion (GNU Automake)"
exit $?
;;
-*)
echo 1>&2 "$0: unknown '$1' option"
echo 1>&2 "Try '$0 --help' for more information"
exit 1
;;
esac
# Run the given program, remember its exit status.
"$@"; st=$?
# If it succeeded, we are done.
test $st -eq 0 && exit 0
# Also exit now if we it failed (or wasn't found), and '--version' was
# passed; such an option is passed most likely to detect whether the
# program is present and works.
case $2 in --version|--help) exit $st;; esac
# Exit code 63 means version mismatch. This often happens when the user
# tries to use an ancient version of a tool on a file that requires a
# minimum version.
if test $st -eq 63; then
msg="probably too old"
elif test $st -eq 127; then
# Program was missing.
msg="missing on your system"
else
# Program was found and executed, but failed. Give up.
exit $st
fi
perl_URL=http://www.perl.org/
flex_URL=http://flex.sourceforge.net/
gnu_software_URL=http://www.gnu.org/software
program_details ()
{
case $1 in
aclocal|automake)
echo "The '$1' program is part of the GNU Automake package:"
echo "<$gnu_software_URL/automake>"
echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:"
echo "<$gnu_software_URL/autoconf>"
echo "<$gnu_software_URL/m4/>"
echo "<$perl_URL>"
;;
autoconf|autom4te|autoheader)
echo "The '$1' program is part of the GNU Autoconf package:"
echo "<$gnu_software_URL/autoconf/>"
echo "It also requires GNU m4 and Perl in order to run:"
echo "<$gnu_software_URL/m4/>"
echo "<$perl_URL>"
;;
esac
}
give_advice ()
{
# Normalize program name to check for.
normalized_program=`echo "$1" | sed '
s/^gnu-//; t
s/^gnu//; t
s/^g//; t'`
printf '%s\n' "'$1' is $msg."
configure_deps="'configure.ac' or m4 files included by 'configure.ac'"
case $normalized_program in
autoconf*)
echo "You should only need it if you modified 'configure.ac',"
echo "or m4 files included by it."
program_details 'autoconf'
;;
autoheader*)
echo "You should only need it if you modified 'acconfig.h' or"
echo "$configure_deps."
program_details 'autoheader'
;;
automake*)
echo "You should only need it if you modified 'Makefile.am' or"
echo "$configure_deps."
program_details 'automake'
;;
aclocal*)
echo "You should only need it if you modified 'acinclude.m4' or"
echo "$configure_deps."
program_details 'aclocal'
;;
autom4te*)
echo "You might have modified some maintainer files that require"
echo "the 'autom4te' program to be rebuilt."
program_details 'autom4te'
;;
bison*|yacc*)
echo "You should only need it if you modified a '.y' file."
echo "You may want to install the GNU Bison package:"
echo "<$gnu_software_URL/bison/>"
;;
lex*|flex*)
echo "You should only need it if you modified a '.l' file."
echo "You may want to install the Fast Lexical Analyzer package:"
echo "<$flex_URL>"
;;
help2man*)
echo "You should only need it if you modified a dependency" \
"of a man page."
echo "You may want to install the GNU Help2man package:"
echo "<$gnu_software_URL/help2man/>"
;;
makeinfo*)
echo "You should only need it if you modified a '.texi' file, or"
echo "any other file indirectly affecting the aspect of the manual."
echo "You might want to install the Texinfo package:"
echo "<$gnu_software_URL/texinfo/>"
echo "The spurious makeinfo call might also be the consequence of"
echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might"
echo "want to install GNU make:"
echo "<$gnu_software_URL/make/>"
;;
*)
echo "You might have modified some files without having the proper"
echo "tools for further handling them. Check the 'README' file, it"
echo "often tells you about the needed prerequisites for installing"
echo "this package. You may also peek at any GNU archive site, in"
echo "case some other package contains this missing '$1' program."
;;
esac
}
give_advice "$1" | sed -e '1s/^/WARNING: /' \
-e '2,$s/^/ /' >&2
# Propagate the correct exit status (expected to be 127 for a program
# not found, 63 for a program that failed due to version mismatch).
exit $st
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:

View file

@ -1,736 +0,0 @@
# Makefile.in generated by automake 1.15.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2017 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
# $Id: Makefile.am 26046 2008-09-09 16:37:30Z androsyn $
VPATH = @srcdir@
am__is_gnu_make = { \
if test -z '$(MAKELEVEL)'; then \
false; \
elif test -n '$(MAKE_HOST)'; then \
true; \
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
true; \
else \
false; \
fi; \
}
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
*) echo "am__make_running_with_option: internal error: invalid" \
"target option '$${target_option-}' specified" >&2; \
exit 1;; \
esac; \
has_opt=no; \
sane_makeflags=$$MAKEFLAGS; \
if $(am__is_gnu_make); then \
sane_makeflags=$$MFLAGS; \
else \
case $$MAKEFLAGS in \
*\\[\ \ ]*) \
bs=\\; \
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
esac; \
fi; \
skip_next=no; \
strip_trailopt () \
{ \
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
}; \
for flg in $$sane_makeflags; do \
test $$skip_next = yes && { skip_next=no; continue; }; \
case $$flg in \
*=*|--*) continue;; \
-*I) strip_trailopt 'I'; skip_next=yes;; \
-*I?*) strip_trailopt 'I';; \
-*O) strip_trailopt 'O'; skip_next=yes;; \
-*O?*) strip_trailopt 'O';; \
-*l) strip_trailopt 'l'; skip_next=yes;; \
-*l?*) strip_trailopt 'l';; \
-[dEDm]) skip_next=yes;; \
-[JT]) skip_next=yes;; \
esac; \
case $$flg in \
*$$target_option*) has_opt=yes; break;; \
esac; \
done; \
test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = src
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/include/libratbox_config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
*) f=$$p;; \
esac;
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
am__install_max = 40
am__nobase_strip_setup = \
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
am__nobase_strip = \
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
am__nobase_list = $(am__nobase_strip_setup); \
for p in $$list; do echo "$$p $$p"; done | \
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
if (++n[$$2] == $(am__install_max)) \
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
END { for (dir in files) print dir, files[dir] }'
am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__uninstall_files_from_dir = { \
test -z "$$files" \
|| { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \
$(am__cd) "$$dir" && rm -f $$files; }; \
}
am__installdirs = "$(DESTDIR)$(libdir)"
LTLIBRARIES = $(lib_LTLIBRARIES)
libratbox_la_DEPENDENCIES =
am_libratbox_la_OBJECTS = unix.lo win32.lo crypt.lo balloc.lo \
commio.lo mbedtls.lo openssl.lo gnutls.lo nossl.lo event.lo \
ratbox_lib.lo rb_memory.lo linebuf.lo snprintf.lo tools.lo \
helper.lo devpoll.lo epoll.lo poll.lo ports.lo sigio.lo \
select.lo kqueue.lo rawbuf.lo patricia.lo arc4random.lo \
version.lo
libratbox_la_OBJECTS = $(am_libratbox_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
am__v_lt_0 = --silent
am__v_lt_1 =
libratbox_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(libratbox_la_LDFLAGS) $(LDFLAGS) -o $@
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo " GEN " $@;
am__v_GEN_1 =
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 =
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CFLAGS) $(CFLAGS)
AM_V_CC = $(am__v_CC_@AM_V@)
am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
am__v_CC_0 = @echo " CC " $@;
am__v_CC_1 =
CCLD = $(CC)
LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
AM_V_CCLD = $(am__v_CCLD_@AM_V@)
am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
am__v_CCLD_0 = @echo " CCLD " $@;
am__v_CCLD_1 =
SOURCES = $(libratbox_la_SOURCES)
DIST_SOURCES = $(libratbox_la_SOURCES)
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
# Read a list of newline-separated strings from the standard input,
# and print each of them once, without duplicates. Input order is
# *not* preserved.
am__uniquify_input = $(AWK) '\
BEGIN { nonempty = 0; } \
{ items[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in items) print i; }; } \
'
# Make sure the list of sources is unique. This is necessary because,
# e.g., the same source file might be shared among _SOURCES variables
# for different programs/libraries.
am__define_uniq_tagged_files = \
list='$(am__tagged_files)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
ALLOCA = @ALLOCA@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AR = @AR@
AS = @AS@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CP = @CP@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GNUTLS_CFLAGS = @GNUTLS_CFLAGS@
GNUTLS_LIBS = @GNUTLS_LIBS@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN = @LN@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MBEDTLS_CFLAGS = @MBEDTLS_CFLAGS@
MBEDTLS_LIBS = @MBEDTLS_LIBS@
MKDIR_P = @MKDIR_P@
MV = @MV@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PICFLAGS = @PICFLAGS@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
RANLIB = @RANLIB@
RB_PREFIX = @RB_PREFIX@
RM = @RM@
SED = @SED@
SEDOBJ = @SEDOBJ@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
SSL_CFLAGS = @SSL_CFLAGS@
SSL_LIBS = @SSL_LIBS@
STRIP = @STRIP@
TOUCH = @TOUCH@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
AUTOMAKE_OPTIONS = foreign
INCLUDES = -I. -I../include @SSL_CFLAGS@ @GNUTLS_CFLAGS@ @MBEDTLS_CFLAGS@
BUILT_SOURCES = version.c
libratbox_la_SOURCES = \
unix.c \
win32.c \
crypt.c \
balloc.c \
commio.c \
mbedtls.c \
openssl.c \
gnutls.c \
nossl.c \
event.c \
ratbox_lib.c \
rb_memory.c \
linebuf.c \
snprintf.c \
tools.c \
helper.c \
devpoll.c \
epoll.c \
poll.c \
ports.c \
sigio.c \
select.c \
kqueue.c \
rawbuf.c \
patricia.c \
arc4random.c \
version.c
libratbox_la_LDFLAGS = @SSL_LIBS@ @GNUTLS_LIBS@ @MBEDTLS_LIBS@ -avoid-version -no-undefined -export-symbols export-syms.txt
libratbox_la_LIBADD = @SSL_LIBS@ @GNUTLS_LIBS@ @MBEDTLS_LIBS@
lib_LTLIBRARIES = libratbox.la
all: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) all-am
.SUFFIXES:
.SUFFIXES: .c .lo .o .obj
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign src/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
install-libLTLIBRARIES: $(lib_LTLIBRARIES)
@$(NORMAL_INSTALL)
@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
list2=; for p in $$list; do \
if test -f $$p; then \
list2="$$list2 $$p"; \
else :; fi; \
done; \
test -z "$$list2" || { \
echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \
$(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
}
uninstall-libLTLIBRARIES:
@$(NORMAL_UNINSTALL)
@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
for p in $$list; do \
$(am__strip_dir) \
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
done
clean-libLTLIBRARIES:
-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
@list='$(lib_LTLIBRARIES)'; \
locs=`for p in $$list; do echo $$p; done | \
sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
sort -u`; \
test -z "$$locs" || { \
echo rm -f $${locs}; \
rm -f $${locs}; \
}
libratbox.la: $(libratbox_la_OBJECTS) $(libratbox_la_DEPENDENCIES) $(EXTRA_libratbox_la_DEPENDENCIES)
$(AM_V_CCLD)$(libratbox_la_LINK) -rpath $(libdir) $(libratbox_la_OBJECTS) $(libratbox_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/arc4random.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/balloc.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/commio.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crypt.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/devpoll.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/epoll.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/event.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnutls.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/helper.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kqueue.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/linebuf.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mbedtls.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nossl.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openssl.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/patricia.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/poll.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ports.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ratbox_lib.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rawbuf.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rb_memory.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/select.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sigio.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/snprintf.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tools.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unix.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/version.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/win32.Plo@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
.c.obj:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
.c.lo:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
ID: $(am__tagged_files)
$(am__define_uniq_tagged_files); mkid -fID $$unique
tags: tags-am
TAGS: tags
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
set x; \
here=`pwd`; \
$(am__define_uniq_tagged_files); \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: ctags-am
CTAGS: ctags
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
$(am__define_uniq_tagged_files); \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
cscopelist: cscopelist-am
cscopelist-am: $(am__tagged_files)
list='$(am__tagged_files)'; \
case "$(srcdir)" in \
[\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
*) sdir=$(subdir)/$(srcdir) ;; \
esac; \
for i in $$list; do \
if test -f "$$i"; then \
echo "$(subdir)/$$i"; \
else \
echo "$$sdir/$$i"; \
fi; \
done >> $(top_builddir)/cscope.files
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
check-am: all-am
check: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) check-am
all-am: Makefile $(LTLIBRARIES)
installdirs:
for dir in "$(DESTDIR)$(libdir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
if test -z '$(STRIP)'; then \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
install; \
else \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
fi
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
-test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
clean: clean-am
clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am:
install-dvi: install-dvi-am
install-dvi-am:
install-exec-am: install-libLTLIBRARIES
install-html: install-html-am
install-html-am:
install-info: install-info-am
install-info-am:
install-man:
install-pdf: install-pdf-am
install-pdf-am:
install-ps: install-ps-am
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-libLTLIBRARIES
.MAKE: all check install install-am install-strip
.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
clean-libLTLIBRARIES clean-libtool cscopelist-am ctags \
ctags-am distclean distclean-compile distclean-generic \
distclean-libtool distclean-tags distdir dvi dvi-am html \
html-am info info-am install install-am install-data \
install-data-am install-dvi install-dvi-am install-exec \
install-exec-am install-html install-html-am install-info \
install-info-am install-libLTLIBRARIES install-man install-pdf \
install-pdf-am install-ps install-ps-am install-strip \
installcheck installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags tags-am uninstall uninstall-am uninstall-libLTLIBRARIES
.PRECIOUS: Makefile
version.c: version.c.SH ../CREDITS
$(SHELL) ./version.c.SH
$(CP) version.c version.c.last
version.lo: version.c ../include/serno.h
$(LIBTOOL) --mode=compile $(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

View file

@ -1,601 +0,0 @@
/*
* ircd-ratbox: A slightly useful ircd.
* balloc.c: A block allocator.
*
* Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
* Copyright (C) 1996-2002 Hybrid Development Team
* Copyright (C) 2002-2006 ircd-ratbox development team
*
* Below are the orignal headers from the old blalloc.c
*
* File: blalloc.c
* Owner: Wohali (Joan Touzet)
*
* Modified 2001/11/29 for mmap() support by Aaron Sethman <androsyn@ratbox.org>
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*
* $Id: balloc.c 26100 2008-09-20 01:27:19Z androsyn $
*/
/*
* About the block allocator
*
* Basically we have three ways of getting memory off of the operating
* system. Below are this list of methods and the order of preference.
*
* 1. mmap() anonymous pages with the MMAP_ANON flag.
* 2. mmap() via the /dev/zero trick.
* 3. HeapCreate/HeapAlloc (on win32)
* 4. malloc()
*
* The advantages of 1 and 2 are this. We can munmap() the pages which will
* return the pages back to the operating system, thus reducing the size
* of the process as the memory is unused. malloc() on many systems just keeps
* a heap of memory to itself, which never gets given back to the OS, except on
* exit. This of course is bad, if say we have an event that causes us to allocate
* say, 200MB of memory, while our normal memory consumption would be 15MB. In the
* malloc() case, the amount of memory allocated to our process never goes down, as
* malloc() has it locked up in its heap. With the mmap() method, we can munmap()
* the block and return it back to the OS, thus causing our memory consumption to go
* down after we no longer need it.
*
*
*
*/
#include <libratbox_config.h>
#include <ratbox_lib.h>
#ifndef NOBALLOC
#ifdef HAVE_MMAP /* We've got mmap() that is good */
#include <sys/mman.h>
/* HP-UX sucks */
#ifdef MAP_ANONYMOUS
#ifndef MAP_ANON
#define MAP_ANON MAP_ANONYMOUS
#endif
#endif
#endif
#endif
static uintptr_t offset_pad;
/* status information for an allocated block in heap */
struct rb_heap_block
{
size_t alloc_size;
rb_dlink_node node;
unsigned long free_count;
void *elems; /* Points to allocated memory */
};
typedef struct rb_heap_block rb_heap_block;
/* information for the root node of the heap */
struct rb_bh
{
rb_dlink_node hlist;
size_t elemSize; /* Size of each element to be stored */
unsigned long elemsPerBlock; /* Number of elements per block */
rb_dlink_list block_list;
rb_dlink_list free_list;
char *desc;
};
#ifndef NOBALLOC
static int newblock(rb_bh *bh);
static void rb_bh_gc_event(void *unused);
#endif /* !NOBALLOC */
static rb_dlink_list *heap_lists;
#if defined(WIN32)
static HANDLE block_heap;
#endif
#define rb_bh_fail(x) _rb_bh_fail(x, __FILE__, __LINE__)
static void __attribute__((noreturn))
_rb_bh_fail(const char *reason, const char *file, int line)
{
rb_lib_log("rb_heap_blockheap failure: %s (%s:%d)", reason, file, line);
abort();
}
#ifndef NOBALLOC
/*
* static inline void free_block(void *ptr, size_t size)
*
* Inputs: The block and its size
* Output: None
* Side Effects: Returns memory for the block back to the OS
*/
static inline void
free_block(void *ptr, size_t size)
{
#ifdef HAVE_MMAP
munmap(ptr, size);
#else
#ifdef _WIN32
HeapFree(block_heap, 0, ptr);
#else
free(ptr);
#endif
#endif
}
#endif /* !NOBALLOC */
/*
* void rb_init_bh(void)
*
* Inputs: None
* Outputs: None
* Side Effects: Initializes the block heap
*/
void
rb_init_bh(void)
{
heap_lists = rb_malloc(sizeof(rb_dlink_list));
offset_pad = sizeof(void *);
/* XXX if you get SIGBUS when trying to use a long long..here is where you need to
* fix your shit
*/
#ifdef __sparc__
if((offset_pad % __alignof__(long long)) != 0)
{
offset_pad += __alignof__(long long);
offset_pad &= ~(__alignof__(long long) - 1);
}
#endif
#ifndef NOBALLOC
#ifdef _WIN32
block_heap = HeapCreate(HEAP_NO_SERIALIZE, 0, 0);
#endif
rb_event_addish("rb_bh_gc_event", rb_bh_gc_event, NULL, 300);
#endif /* !NOBALLOC */
}
#ifndef NOBALLOC
/*
* static inline void *get_block(size_t size)
*
* Input: Size of block to allocate
* Output: Pointer to new block
* Side Effects: None
*/
static inline void *
get_block(size_t size)
{
void *ptr;
#ifdef HAVE_MMAP
#ifdef MAP_ANON
ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
#else
int zero_fd;
zero_fd = open("/dev/zero", O_RDWR);
if(zero_fd < 0)
rb_bh_fail("Failed opening /dev/zero");
ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE, zero_fd, 0);
close(zero_fd);
#endif /* MAP_ANON */
if(ptr == MAP_FAILED)
ptr = NULL;
#else
#ifdef _WIN32
ptr = HeapAlloc(block_heap, 0, size);
#else
ptr = malloc(size);
#endif
#endif
return (ptr);
}
static void
rb_bh_gc_event(void *unused)
{
rb_dlink_node *ptr;
RB_DLINK_FOREACH(ptr, heap_lists->head)
{
rb_bh_gc(ptr->data);
}
}
/* ************************************************************************ */
/* FUNCTION DOCUMENTATION: */
/* newblock */
/* Description: */
/* Allocates a new block for addition to a blockheap */
/* Parameters: */
/* bh (IN): Pointer to parent blockheap. */
/* Returns: */
/* 0 if successful, 1 if not */
/* ************************************************************************ */
static int
newblock(rb_bh *bh)
{
rb_heap_block *b;
unsigned long i;
uintptr_t offset;
rb_dlink_node *node;
/* Setup the initial data structure. */
b = rb_malloc(sizeof(rb_heap_block));
b->alloc_size = bh->elemsPerBlock * bh->elemSize;
b->elems = get_block(b->alloc_size);
if(rb_unlikely(b->elems == NULL))
{
rb_free(b);
return (1);
}
offset = (uintptr_t)b->elems;
/* Setup our blocks now */
for(i = 0; i < bh->elemsPerBlock; i++, offset += bh->elemSize)
{
*((void **)offset) = b;
node = (void *)(offset + offset_pad);
rb_dlinkAdd((void *)offset, node, &bh->free_list);
}
rb_dlinkAdd(b, &b->node, &bh->block_list);
b->free_count = bh->elemsPerBlock;
return (0);
}
#endif /* !NOBALLOC */
/* ************************************************************************ */
/* FUNCTION DOCUMENTATION: */
/* rb_bh_create */
/* Description: */
/* Creates a new blockheap from which smaller blocks can be allocated. */
/* Intended to be used instead of multiple calls to malloc() when */
/* performance is an issue. */
/* Parameters: */
/* elemsize (IN): Size of the basic element to be stored */
/* elemsperblock (IN): Number of elements to be stored in a single block */
/* of memory. When the blockheap runs out of free memory, it will */
/* allocate elemsize * elemsperblock more. */
/* Returns: */
/* Pointer to new rb_bh, or NULL if unsuccessful */
/* ************************************************************************ */
rb_bh *
rb_bh_create(size_t elemsize, int elemsperblock, const char *desc)
{
rb_bh *bh;
lrb_assert(elemsize > 0 && elemsperblock > 0);
lrb_assert(elemsize >= sizeof(rb_dlink_node));
/* Catch idiotic requests up front */
if((elemsize == 0) || (elemsperblock <= 0))
{
rb_bh_fail("Attempting to rb_bh_create idiotic sizes");
}
if(elemsize < sizeof(rb_dlink_node))
rb_bh_fail("Attempt to rb_bh_create smaller than sizeof(rb_dlink_node)");
/* Allocate our new rb_bh */
bh = rb_malloc(sizeof(rb_bh));
#ifndef NOBALLOC
elemsize += offset_pad;
if((elemsize % sizeof(void *)) != 0)
{
/* Pad to even pointer boundary */
elemsize += sizeof(void *);
elemsize &= ~(sizeof(void *) - 1);
}
#endif
bh->elemSize = elemsize;
bh->elemsPerBlock = elemsperblock;
if(desc != NULL)
bh->desc = rb_strdup(desc);
#ifndef NOBALLOC
/* Be sure our malloc was successful */
if(newblock(bh))
{
if(bh != NULL)
free(bh);
rb_lib_log("newblock() failed");
rb_outofmemory(); /* die.. out of memory */
}
#endif /* !NOBALLOC */
if(bh == NULL)
{
rb_bh_fail("bh == NULL when it shouldn't be");
}
rb_dlinkAdd(bh, &bh->hlist, heap_lists);
return (bh);
}
/* ************************************************************************ */
/* FUNCTION DOCUMENTATION: */
/* rb_bh_alloc */
/* Description: */
/* Returns a pointer to a struct within our rb_bh that's free for */
/* the taking. */
/* Parameters: */
/* bh (IN): Pointer to the Blockheap. */
/* Returns: */
/* Pointer to a structure (void *), or NULL if unsuccessful. */
/* ************************************************************************ */
void *
rb_bh_alloc(rb_bh *bh)
{
#ifndef NOBALLOC
rb_dlink_node *new_node;
rb_heap_block **block;
void *ptr;
#endif
lrb_assert(bh != NULL);
if(rb_unlikely(bh == NULL))
{
rb_bh_fail("Cannot allocate if bh == NULL");
}
#ifdef NOBALLOC
return (rb_malloc(bh->elemSize));
#else
if(bh->free_list.head == NULL)
{
/* Allocate new block and assign */
/* newblock returns 1 if unsuccessful, 0 if not */
if(rb_unlikely(newblock(bh)))
{
rb_lib_log("newblock() failed");
rb_outofmemory(); /* Well that didn't work either...bail */
}
if(bh->free_list.head == NULL)
{
rb_lib_log("out of memory after newblock()...");
rb_outofmemory();
}
}
new_node = bh->free_list.head;
block = (rb_heap_block **) new_node->data;
ptr = (void *)((uintptr_t)new_node->data + (uintptr_t)offset_pad);
rb_dlinkDelete(new_node, &bh->free_list);
(*block)->free_count--;
memset(ptr, 0, bh->elemSize - offset_pad);
return (ptr);
#endif
}
/* ************************************************************************ */
/* FUNCTION DOCUMENTATION: */
/* rb_bh_free */
/* Description: */
/* Returns an element to the free pool, does not free() */
/* Parameters: */
/* bh (IN): Pointer to rb_bh containing element */
/* ptr (in): Pointer to element to be "freed" */
/* Returns: */
/* 0 if successful, 1 if element not contained within rb_bh. */
/* ************************************************************************ */
int
rb_bh_free(rb_bh *bh, void *ptr)
{
#ifndef NOBALLOC
rb_heap_block *block;
void *data;
#endif
lrb_assert(bh != NULL);
lrb_assert(ptr != NULL);
if(rb_unlikely(bh == NULL))
{
rb_lib_log("balloc.c:rb_bhFree() bh == NULL");
return (1);
}
if(rb_unlikely(ptr == NULL))
{
rb_lib_log("balloc.rb_bhFree() ptr == NULL");
return (1);
}
#ifdef NOBALLOC
rb_free(ptr);
#else
data = (void *)((uintptr_t)ptr - (uintptr_t)offset_pad);
block = *(rb_heap_block **) data;
/* XXX */
if(rb_unlikely
(!((uintptr_t)ptr >= (uintptr_t)block->elems
&& (uintptr_t)ptr < (uintptr_t)block->elems + (uintptr_t)block->alloc_size)))
{
rb_bh_fail("rb_bh_free() bogus pointer");
}
block->free_count++;
rb_dlinkAdd(data, (rb_dlink_node *)ptr, &bh->free_list);
#endif /* !NOBALLOC */
return (0);
}
/* ************************************************************************ */
/* FUNCTION DOCUMENTATION: */
/* rb_bhDestroy */
/* Description: */
/* Completely free()s a rb_bh. Use for cleanup. */
/* Parameters: */
/* bh (IN): Pointer to the rb_bh to be destroyed. */
/* Returns: */
/* 0 if successful, 1 if bh == NULL */
/* ************************************************************************ */
int
rb_bh_destroy(rb_bh *bh)
{
#ifndef NOBALLOC
rb_dlink_node *ptr, *next;
rb_heap_block *b;
#endif
if(bh == NULL)
return (1);
#ifndef NOBALLOC
RB_DLINK_FOREACH_SAFE(ptr, next, bh->block_list.head)
{
b = ptr->data;
free_block(b->elems, b->alloc_size);
rb_free(b);
}
#endif /* !NOBALLOC */
rb_dlinkDelete(&bh->hlist, heap_lists);
rb_free(bh->desc);
rb_free(bh);
return (0);
}
void
rb_bh_usage(rb_bh *bh, size_t *bused, size_t *bfree, size_t *bmemusage, const char **desc)
{
#ifndef NOBALLOC
size_t used, freem, memusage;
if(bh == NULL)
{
return;
}
freem = rb_dlink_list_length(&bh->free_list);
used = (rb_dlink_list_length(&bh->block_list) * bh->elemsPerBlock) - freem;
memusage = used * bh->elemSize;
if(bused != NULL)
*bused = used;
if(bfree != NULL)
*bfree = freem;
if(bmemusage != NULL)
*bmemusage = memusage;
if(desc != NULL)
*desc = bh->desc;
#else
if(bused != NULL)
*bused = 0;
if(bfree != NULL)
*bfree = 0;
if(bmemusage != NULL)
*bmemusage = 0;
if(desc != NULL)
*desc = "no blockheap";
#endif
}
void
rb_bh_usage_all(rb_bh_usage_cb *cb, void *data)
{
rb_dlink_node *ptr;
rb_bh *bh;
size_t used, freem, memusage, heapalloc;
static const char *unnamed = "(unnamed_heap)";
const char *desc = unnamed;
if(cb == NULL)
return;
RB_DLINK_FOREACH(ptr, heap_lists->head)
{
bh = (rb_bh *)ptr->data;
freem = rb_dlink_list_length(&bh->free_list);
used = (rb_dlink_list_length(&bh->block_list) * bh->elemsPerBlock) - freem;
memusage = used * bh->elemSize;
heapalloc = (freem + used) * bh->elemSize;
if(bh->desc != NULL)
desc = bh->desc;
cb(used, freem, memusage, heapalloc, desc, data);
}
return;
}
void
rb_bh_total_usage(size_t *total_alloc, size_t *total_used)
{
rb_dlink_node *ptr;
size_t total_memory = 0, used_memory = 0, used, freem;
rb_bh *bh;
RB_DLINK_FOREACH(ptr, heap_lists->head)
{
bh = (rb_bh *)ptr->data;
freem = rb_dlink_list_length(&bh->free_list);
used = (rb_dlink_list_length(&bh->block_list) * bh->elemsPerBlock) - freem;
used_memory += used * bh->elemSize;
total_memory += (freem + used) * bh->elemSize;
}
if(total_alloc != NULL)
*total_alloc = total_memory;
if(total_used != NULL)
*total_used = used_memory;
}
#ifndef NOBALLOC
int
rb_bh_gc(rb_bh *bh)
{
rb_heap_block *b;
rb_dlink_node *ptr, *next;
unsigned long i;
uintptr_t offset;
if(bh == NULL)
{
/* somebody is smoking some craq..(probably lee, but don't tell him that) */
return (1);
}
if((rb_dlink_list_length(&bh->free_list) < bh->elemsPerBlock)
|| rb_dlink_list_length(&bh->block_list) == 1)
{
/* There couldn't possibly be an entire free block. Return. */
return (0);
}
RB_DLINK_FOREACH_SAFE(ptr, next, bh->block_list.head)
{
b = ptr->data;
if(rb_dlink_list_length(&bh->block_list) == 1)
return (0);
if(b->free_count == bh->elemsPerBlock)
{
/* i'm seriously going to hell for this.. */
offset = (uintptr_t)b->elems;
for(i = 0; i < bh->elemsPerBlock; i++, offset += (uintptr_t)bh->elemSize)
{
rb_dlinkDelete((rb_dlink_node *)(offset + offset_pad),
&bh->free_list);
}
rb_dlinkDelete(&b->node, &bh->block_list);
free_block(b->elems, b->alloc_size);
rb_free(b);
}
}
return (0);
}
#endif /* !NOBALLOC */

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,170 +0,0 @@
rb_bh_alloc
rb_bh_create
rb_bh_destroy
rb_bh_free
rb_bh_gc
rb_bh_total_usage
rb_bh_usage
rb_bh_usage_all
rb_init_bh
rb_accept_tcp
rb_checktimeouts
rb_close
rb_connect_sockaddr
rb_connect_tcp
rb_connect_tcp_ssl
rb_dump_fd
rb_errstr
rb_fd_ssl
rb_fdlist_init
rb_get_fd
rb_get_fde
rb_get_iotype
rb_get_random
rb_get_sockerr
rb_get_ssl_certfp
rb_get_ssl_strerror
rb_get_type
rb_getmaxconnect
rb_ignore_errno
rb_inet_ntop
rb_inet_ntop_sock
rb_inet_pton
rb_inet_pton_sock
rb_init_netio
rb_init_prng
rb_listen
rb_note
rb_open
rb_pipe
rb_read
rb_recv_fd_buf
rb_select
rb_send_fd_buf
rb_set_buffers
rb_set_nb
rb_set_type
rb_setselect
rb_settimeout
rb_setup_fd
rb_setup_ssl_server
rb_setup_ssl_server_hostname
rb_remove_ssl_vserver
rb_socket
rb_socketpair
rb_ssl_listen
rb_ssl_start_accepted
rb_ssl_start_connected
rb_write
rb_writev
rb_crypt
rb_dump_events
rb_event_add
rb_event_addish
rb_event_addonce
rb_event_delete
rb_event_find_delete
rb_event_init
rb_event_next
rb_event_run
rb_event_update
rb_run_event
rb_helper_child
rb_helper_close
rb_helper_loop
rb_helper_read
rb_helper_restart
rb_helper_run
rb_helper_start
rb_helper_write
rb_helper_write_queue
rb_count_rb_linebuf_memory
rb_linebuf_attach
rb_linebuf_donebuf
rb_linebuf_flush
rb_linebuf_get
rb_linebuf_init
rb_linebuf_newbuf
rb_linebuf_parse
rb_linebuf_put
rb_linebuf_putbuf
rb_linebuf_putmsg
make_and_lookup
make_and_lookup_ip
rb_clear_patricia
rb_destroy_patricia
rb_init_patricia
rb_match_exact_string
rb_match_ip
rb_match_ip_exact
rb_match_string
rb_new_patricia
rb_patricia_lookup
rb_patricia_process
rb_patricia_remove
rb_patricia_search_best
rb_patricia_search_best2
rb_patricia_search_exact
rb_base64_decode
rb_base64_encode
rb_ctime
rb_current_time
rb_current_time_tv
rb_date
rb_lib_die
rb_lib_init
rb_lib_log
rb_lib_loop
rb_lib_restart
rb_lib_version
rb_set_time
rb_strtok_r
rb_free_rawbuffer
rb_init_rawbuffers
rb_new_rawbuffer
rb_rawbuf_append
rb_rawbuf_flush
rb_rawbuf_get
rb_rawbuf_length
rb_outofmemory
rb_snprintf
rb_snprintf_append
rb_sprintf
rb_sprintf_append
rb_vsnprintf
rb_vsnprintf_append
rb_vsprintf
rb_vsprintf_append
rb_free_rb_dlink_node
rb_init_rb_dlink_nodes
rb_make_rb_dlink_node
rb_string_to_array
rb_strlcat
rb_strlcpy
rb_strnlen
rb_gettimeofday
rb_sleep
rb_spawn_process
rb_supports_ssl
rb_ssl_handshake_count
rb_ssl_clear_handshake_count
rb_strerror
rb_kill
rb_setenv
rb_getpid
rb_waitpid
rb_basename
rb_dirname
rb_ssl_get_cipher
rb_zstring_alloc
rb_zstring_append_from_c
rb_zstring_append_from_zstring
rb_zstring_deserialize
rb_zstring_free
rb_zstring_from_c
rb_zstring_from_c_len
rb_zstring_len
rb_zstring_serialized
rb_zstring_to_c
rb_zstring_to_c_alloc
rb_zstring_to_ptr

View file

@ -1,917 +0,0 @@
/*
* libratbox: a library used by ircd-ratbox and other things
* gnutls.c: gnutls related code
*
* Copyright (C) 2007-2008 ircd-ratbox development team
* Copyright (C) 2007-2008 Aaron Sethman <androsyn@ratbox.org>
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*
*/
#include <libratbox_config.h>
#include <ratbox_lib.h>
#ifdef HAVE_GNUTLS
#include <commio-int.h>
#include <commio-ssl.h>
#include <gnutls/gnutls.h>
#include <gnutls/abstract.h>
#include <gnutls/x509.h>
#if (GNUTLS_VERSION_MAJOR < 3)
# include <gcrypt.h>
#else
# include <gnutls/crypto.h>
#endif
#include "gnutls_ratbox.h"
typedef enum
{
RB_FD_TLS_DIRECTION_IN = 0,
RB_FD_TLS_DIRECTION_OUT = 1
} rb_fd_tls_direction;
#define SSL_P(x) *((gnutls_session_t *) ((x)->ssl))
// Server side variables
static gnutls_certificate_credentials_t server_cert_key;
static gnutls_dh_params_t server_dhp;
// Client side variables
#define MAX_CERTS 6
static gnutls_x509_crt_t client_cert[MAX_CERTS];
static gnutls_x509_privkey_t client_key;
static unsigned int client_cert_count;
// Shared variables
static gnutls_priority_t default_priority;
struct ssl_connect
{
CNCB *callback;
void *data;
int timeout;
};
static const char *rb_ssl_strerror(int);
static void rb_ssl_connect_realcb(rb_fde_t *, int, struct ssl_connect *);
/*
* Internal GNUTLS-specific code
*/
/*
* We only have one certificate to authenticate with, as both a client and server.
*
* Unfortunately, GNUTLS tries to be clever, and as client, will attempt to use a certificate that the server will
* trust. We usually use self-signed certs, though, so the result of this search is always nothing. Therefore, it
* uses no certificate to authenticate as a client. This is undesirable, as it breaks fingerprint authentication;
* e.g. the connect::fingerprint on the remote ircd will not match.
*
* Thus, we use this callback to force GNUTLS to authenticate with our (server) certificate as a client.
*/
static int
rb_ssl_cert_auth_cb(gnutls_session_t session,
const gnutls_datum_t *const req_ca_rdn, const int req_ca_rdn_len,
const gnutls_pk_algorithm_t *const sign_algos, const int sign_algos_len,
#if (GNUTLS_VERSION_MAJOR < 3)
gnutls_retr_st *const st)
#else
gnutls_retr2_st *const st)
#endif
{
#if (GNUTLS_VERSION_MAJOR < 3)
st->type = GNUTLS_CRT_X509;
#else
st->cert_type = GNUTLS_CRT_X509;
st->key_type = GNUTLS_PRIVKEY_X509;
#endif
st->ncerts = client_cert_count;
st->cert.x509 = client_cert;
st->key.x509 = client_key;
st->deinit_all = 0;
return 0;
}
static ssize_t
rb_sock_net_recv(gnutls_transport_ptr_t context_ptr, void *const buf, const size_t count)
{
const int fd = rb_get_fd((rb_fde_t *)context_ptr);
return recv(fd, buf, count, 0);
}
static ssize_t
rb_sock_net_xmit(gnutls_transport_ptr_t context_ptr, const void *const buf, const size_t count)
{
const int fd = rb_get_fd((rb_fde_t *)context_ptr);
return send(fd, buf, count, 0);
}
static void
rb_ssl_init_fd(rb_fde_t *const F, const rb_fd_tls_direction dir)
{
F->ssl = rb_malloc(sizeof(gnutls_session_t));
if(F->ssl == NULL)
{
rb_lib_log("%s: rb_malloc: allocation failure", __func__);
rb_close(F);
return;
}
unsigned int init_flags = 0;
switch(dir)
{
case RB_FD_TLS_DIRECTION_IN:
init_flags |= GNUTLS_SERVER;
break;
case RB_FD_TLS_DIRECTION_OUT:
init_flags |= GNUTLS_CLIENT;
break;
}
gnutls_init((gnutls_session_t *) F->ssl, init_flags);
gnutls_credentials_set(SSL_P(F), GNUTLS_CRD_CERTIFICATE, server_cert_key);
gnutls_dh_set_prime_bits(SSL_P(F), 2048);
gnutls_transport_set_ptr(SSL_P(F), (gnutls_transport_ptr_t) F);
gnutls_transport_set_pull_function(SSL_P(F), rb_sock_net_recv);
gnutls_transport_set_push_function(SSL_P(F), rb_sock_net_xmit);
if (gnutls_priority_set(SSL_P(F), default_priority) != GNUTLS_E_SUCCESS)
gnutls_set_default_priority(SSL_P(F));
if(dir == RB_FD_TLS_DIRECTION_IN)
gnutls_certificate_server_set_request(SSL_P(F), GNUTLS_CERT_REQUEST);
}
static void
rb_ssl_accept_common(rb_fde_t *const F, void *const data)
{
lrb_assert(F != NULL);
lrb_assert(F->accept != NULL);
lrb_assert(F->accept->callback != NULL);
lrb_assert(F->ssl != NULL);
errno = 0;
const int ret = gnutls_handshake(SSL_P(F));
const int err = errno;
if(ret == GNUTLS_E_AGAIN || (ret == GNUTLS_E_INTERRUPTED && (err == 0 || rb_ignore_errno(err))))
{
unsigned int flags = (gnutls_record_get_direction(SSL_P(F)) == 0) ? RB_SELECT_READ : RB_SELECT_WRITE;
rb_setselect(F, flags, rb_ssl_accept_common, data);
return;
}
// These 2 calls may affect errno, which is why we save it above and restore it below
rb_settimeout(F, 0, NULL, NULL);
rb_setselect(F, RB_SELECT_READ | RB_SELECT_WRITE, NULL, NULL);
struct acceptdata *const ad = F->accept;
F->accept = NULL;
if(ret == GNUTLS_E_SUCCESS)
{
F->handshake_count++;
ad->callback(F, RB_OK, (struct sockaddr *)&ad->S, ad->addrlen, ad->data);
}
else if(ret == GNUTLS_E_INTERRUPTED && err != 0)
{
errno = err;
ad->callback(F, RB_ERROR, NULL, 0, ad->data);
}
else
{
errno = EIO;
F->ssl_errno = (unsigned long) -ret;
ad->callback(F, RB_ERROR_SSL, NULL, 0, ad->data);
}
rb_free(ad);
}
static void
rb_ssl_connect_common(rb_fde_t *const F, void *const data)
{
lrb_assert(F != NULL);
lrb_assert(F->ssl != NULL);
errno = 0;
const int ret = gnutls_handshake(SSL_P(F));
const int err = errno;
if(ret == GNUTLS_E_AGAIN || (ret == GNUTLS_E_INTERRUPTED && (err == 0 || rb_ignore_errno(err))))
{
unsigned int flags = (gnutls_record_get_direction(SSL_P(F)) == 0) ? RB_SELECT_READ : RB_SELECT_WRITE;
rb_setselect(F, flags, rb_ssl_connect_common, data);
return;
}
// These 2 calls may affect errno, which is why we save it above and restore it below
rb_settimeout(F, 0, NULL, NULL);
rb_setselect(F, RB_SELECT_READ | RB_SELECT_WRITE, NULL, NULL);
struct ssl_connect *const sconn = data;
if(ret == GNUTLS_E_SUCCESS)
{
F->handshake_count++;
rb_ssl_connect_realcb(F, RB_OK, sconn);
}
else if(ret == GNUTLS_E_INTERRUPTED && err != 0)
{
errno = err;
rb_ssl_connect_realcb(F, RB_ERROR, sconn);
}
else
{
errno = EIO;
F->ssl_errno = (unsigned long) -ret;
rb_ssl_connect_realcb(F, RB_ERROR_SSL, sconn);
}
}
static const char *
rb_ssl_strerror(const int err)
{
return gnutls_strerror(err);
}
static ssize_t
rb_ssl_read_or_write(const int r_or_w, rb_fde_t *const F, void *const rbuf, const void *const wbuf, const size_t count)
{
ssize_t ret;
errno = 0;
if(r_or_w == 0)
ret = gnutls_record_recv(SSL_P(F), rbuf, count);
else
ret = gnutls_record_send(SSL_P(F), wbuf, count);
if(ret >= 0)
return ret;
if(ret == GNUTLS_E_AGAIN || (ret == GNUTLS_E_INTERRUPTED && (errno == 0 || rb_ignore_errno(errno))))
{
if(gnutls_record_get_direction(SSL_P(F)) == 0)
return RB_RW_SSL_NEED_READ;
else
return RB_RW_SSL_NEED_WRITE;
}
if(ret == GNUTLS_E_INTERRUPTED && errno != 0)
return RB_RW_IO_ERROR;
errno = EIO;
F->ssl_errno = (unsigned long) -ret;
return RB_RW_SSL_ERROR;
}
#if (GNUTLS_VERSION_MAJOR < 3)
static void
rb_gcry_random_seed(void *const unused)
{
gcry_fast_random_poll();
}
#endif
static void
rb_free_datum_t(gnutls_datum_t *const datum)
{
if(datum == NULL)
return;
rb_free(datum->data);
rb_free(datum);
}
static gnutls_datum_t *
rb_load_file_into_datum_t(const char *const file)
{
const int datum_fd = open(file, O_RDONLY);
if(datum_fd < 0)
return NULL;
struct stat fileinfo;
if(fstat(datum_fd, &fileinfo) != 0)
{
(void) close(datum_fd);
return NULL;
}
const size_t datum_size = (fileinfo.st_size < 131072) ? (size_t) fileinfo.st_size : 131072;
if(datum_size == 0)
{
(void) close(datum_fd);
return NULL;
}
gnutls_datum_t *datum;
if((datum = rb_malloc(sizeof *datum)) == NULL)
{
(void) close(datum_fd);
return NULL;
}
if((datum->data = rb_malloc(datum_size + 1)) == NULL)
{
rb_free(datum);
(void) close(datum_fd);
return NULL;
}
for(size_t data_read = 0; data_read < datum_size; )
{
ssize_t ret = read(datum_fd, ((unsigned char *)datum->data) + data_read, datum_size - data_read);
if(ret <= 0)
{
rb_free_datum_t(datum);
(void) close(datum_fd);
return NULL;
}
data_read += (size_t) ret;
}
(void) close(datum_fd);
datum->data[datum_size] = '\0';
datum->size = (unsigned int) datum_size;
return datum;
}
static int
make_certfp(gnutls_x509_crt_t cert, uint8_t certfp[const RB_SSL_CERTFP_LEN], const int method)
{
int ret;
int hashlen;
gnutls_digest_algorithm_t md_type;
int spki = 0;
switch(method)
{
case RB_SSL_CERTFP_METH_CERT_SHA1:
hashlen = RB_SSL_CERTFP_LEN_SHA1;
md_type = GNUTLS_DIG_SHA1;
break;
case RB_SSL_CERTFP_METH_SPKI_SHA256:
spki = 1;
case RB_SSL_CERTFP_METH_CERT_SHA256:
hashlen = RB_SSL_CERTFP_LEN_SHA256;
md_type = GNUTLS_DIG_SHA256;
break;
case RB_SSL_CERTFP_METH_SPKI_SHA512:
spki = 1;
case RB_SSL_CERTFP_METH_CERT_SHA512:
hashlen = RB_SSL_CERTFP_LEN_SHA512;
md_type = GNUTLS_DIG_SHA512;
break;
default:
rb_lib_log("%s: invalid method %d", __func__, method);
return 0;
}
if(! spki)
{
size_t digest_size = (size_t) hashlen;
if((ret = gnutls_x509_crt_get_fingerprint(cert, md_type, certfp, &digest_size)) != 0)
{
rb_lib_log("%s: gnutls_x509_crt_get_fingerprint: %d", __func__, ret);
return 0;
}
return hashlen;
}
gnutls_pubkey_t pubkey;
if((ret = gnutls_pubkey_init(&pubkey)) != 0)
{
rb_lib_log("%s: gnutls_pubkey_init: %d", __func__, ret);
return 0;
}
if((ret = gnutls_pubkey_import_x509(pubkey, cert, 0)) != 0)
{
rb_lib_log("%s: gnutls_pubkey_import_x509: %d", __func__, ret);
gnutls_pubkey_deinit(pubkey);
return 0;
}
unsigned char derkey[262144]; // Should be big enough to hold any SubjectPublicKeyInfo structure
size_t derkey_len = sizeof derkey;
if((ret = gnutls_pubkey_export(pubkey, GNUTLS_X509_FMT_DER, derkey, &derkey_len)) != 0)
{
rb_lib_log("%s: gnutls_pubkey_export: %d", __func__, ret);
gnutls_pubkey_deinit(pubkey);
return 0;
}
gnutls_pubkey_deinit(pubkey);
if((ret = gnutls_hash_fast(md_type, derkey, derkey_len, certfp)) != 0)
{
rb_lib_log("%s: gnutls_hash_fast: %d", __func__, ret);
return 0;
}
return hashlen;
}
/*
* External GNUTLS-specific code
*/
void
rb_ssl_shutdown(rb_fde_t *const F)
{
if(F == NULL || F->ssl == NULL)
return;
for(int i = 0; i < 4; i++)
{
int ret = gnutls_bye(SSL_P(F), GNUTLS_SHUT_RDWR);
if(ret != GNUTLS_E_INTERRUPTED && ret != GNUTLS_E_AGAIN)
break;
}
gnutls_deinit(SSL_P(F));
rb_free(F->ssl);
F->ssl = NULL;
}
int
rb_init_ssl(void)
{
int ret;
if((ret = gnutls_global_init()) != GNUTLS_E_SUCCESS)
{
rb_lib_log("%s: gnutls_global_init: %s", __func__, rb_ssl_strerror(ret));
return 0;
}
#if (GNUTLS_VERSION_MAJOR < 3)
rb_event_addish("rb_gcry_random_seed", rb_gcry_random_seed, NULL, 300);
#endif
return 1;
}
int
rb_setup_ssl_server(const char *const certfile, const char *keyfile,
const char *const dhfile, const char *cipherlist, char *hostname)
{
if(certfile == NULL)
{
rb_lib_log("%s: no certificate file specified", __func__);
return 0;
}
if(keyfile == NULL)
keyfile = certfile;
if(cipherlist == NULL)
cipherlist = rb_gnutls_default_priority_str;
gnutls_datum_t *const d_cert = rb_load_file_into_datum_t(certfile);
if(d_cert == NULL)
{
rb_lib_log("%s: Error loading certificate: %s", __func__, strerror(errno));
return 0;
}
gnutls_datum_t *const d_key = rb_load_file_into_datum_t(keyfile);
if(d_key == NULL)
{
rb_lib_log("%s: Error loading key: %s", __func__, strerror(errno));
rb_free_datum_t(d_cert);
return 0;
}
int ret;
if((ret = gnutls_certificate_allocate_credentials(&server_cert_key)) != GNUTLS_E_SUCCESS)
{
rb_lib_log("%s: gnutls_certificate_allocate_credentials: %s", __func__, rb_ssl_strerror(ret));
rb_free_datum_t(d_cert);
rb_free_datum_t(d_key);
return 0;
}
#if (GNUTLS_VERSION_MAJOR < 3)
gnutls_certificate_client_set_retrieve_function(server_cert_key, rb_ssl_cert_auth_cb);
#else
gnutls_certificate_set_retrieve_function(server_cert_key, rb_ssl_cert_auth_cb);
#endif
if((ret = gnutls_certificate_set_x509_key_mem(server_cert_key, d_cert, d_key,
GNUTLS_X509_FMT_PEM)) != GNUTLS_E_SUCCESS)
{
rb_lib_log("%s: gnutls_certificate_set_x509_key_mem: %s", __func__, rb_ssl_strerror(ret));
gnutls_certificate_free_credentials(server_cert_key);
rb_free_datum_t(d_cert);
rb_free_datum_t(d_key);
return 0;
}
client_cert_count = MAX_CERTS;
if((ret = gnutls_x509_crt_list_import(client_cert, &client_cert_count, d_cert, GNUTLS_X509_FMT_PEM,
GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED)) < 1)
{
rb_lib_log("%s: gnutls_x509_crt_list_import: %s", __func__, rb_ssl_strerror(ret));
gnutls_certificate_free_credentials(server_cert_key);
rb_free_datum_t(d_cert);
rb_free_datum_t(d_key);
return 0;
}
client_cert_count = (unsigned int) ret;
if((ret = gnutls_x509_privkey_init(&client_key)) != GNUTLS_E_SUCCESS)
{
rb_lib_log("%s: gnutls_x509_privkey_init: %s", __func__, rb_ssl_strerror(ret));
gnutls_certificate_free_credentials(server_cert_key);
for(unsigned int i = 0; i < client_cert_count; i++)
gnutls_x509_crt_deinit(client_cert[i]);
rb_free_datum_t(d_cert);
rb_free_datum_t(d_key);
return 0;
}
if((ret = gnutls_x509_privkey_import(client_key, d_key, GNUTLS_X509_FMT_PEM)) != GNUTLS_E_SUCCESS)
{
rb_lib_log("%s: gnutls_x509_privkey_import: %s", __func__, rb_ssl_strerror(ret));
gnutls_certificate_free_credentials(server_cert_key);
for(unsigned int i = 0; i < client_cert_count; i++)
gnutls_x509_crt_deinit(client_cert[i]);
gnutls_x509_privkey_deinit(client_key);
rb_free_datum_t(d_cert);
rb_free_datum_t(d_key);
return 0;
}
rb_free_datum_t(d_cert);
rb_free_datum_t(d_key);
if(dhfile != NULL)
{
gnutls_datum_t *const d_dhp = rb_load_file_into_datum_t(dhfile);
if(d_dhp == NULL)
{
rb_lib_log("%s: Error parsing DH parameters: %s", __func__, strerror(errno));
gnutls_certificate_free_credentials(server_cert_key);
for(unsigned int i = 0; i < client_cert_count; i++)
gnutls_x509_crt_deinit(client_cert[i]);
gnutls_x509_privkey_deinit(client_key);
return 0;
}
if((ret = gnutls_dh_params_init(&server_dhp)) != GNUTLS_E_SUCCESS)
{
rb_lib_log("%s: Error parsing DH parameters: %s", __func__, rb_ssl_strerror(ret));
gnutls_certificate_free_credentials(server_cert_key);
for(unsigned int i = 0; i < client_cert_count; i++)
gnutls_x509_crt_deinit(client_cert[i]);
gnutls_x509_privkey_deinit(client_key);
rb_free_datum_t(d_dhp);
return 0;
}
if((ret = gnutls_dh_params_import_pkcs3(server_dhp, d_dhp, GNUTLS_X509_FMT_PEM)) != GNUTLS_E_SUCCESS)
{
rb_lib_log("%s: Error parsing DH parameters: %s", __func__, rb_ssl_strerror(ret));
gnutls_certificate_free_credentials(server_cert_key);
for(unsigned int i = 0; i < client_cert_count; i++)
gnutls_x509_crt_deinit(client_cert[i]);
gnutls_x509_privkey_deinit(client_key);
gnutls_dh_params_deinit(server_dhp);
rb_free_datum_t(d_dhp);
return 0;
}
gnutls_certificate_set_dh_params(server_cert_key, server_dhp);
rb_free_datum_t(d_dhp);
}
const char *err = NULL;
if((ret = gnutls_priority_init(&default_priority, cipherlist, &err)) != GNUTLS_E_SUCCESS)
{
rb_lib_log("%s: gnutls_priority_init: %s, error begins at '%s'? -- using defaults instead",
__func__, rb_ssl_strerror(ret), err ? err : "<unknown>");
(void) gnutls_priority_init(&default_priority, NULL, &err);
}
rb_lib_log("%s: TLS configuration successful", __func__);
return 1;
}
int
rb_init_prng(const char *const path, prng_seed_t seed_type)
{
#if (GNUTLS_VERSION_MAJOR < 3)
gcry_fast_random_poll();
rb_lib_log("%s: PRNG initialised", __func__);
#else
rb_lib_log("%s: Skipping PRNG initialisation; not required by GNUTLS v3+ backend", __func__);
#endif
return 1;
}
int
rb_get_random(void *const buf, const size_t length)
{
#if (GNUTLS_VERSION_MAJOR < 3)
gcry_randomize(buf, length, GCRY_STRONG_RANDOM);
#else
gnutls_rnd(GNUTLS_RND_KEY, buf, length);
#endif
return 1;
}
const char *
rb_get_ssl_strerror(rb_fde_t *const F)
{
const int err = (int) F->ssl_errno;
return rb_ssl_strerror(-err);
}
int
rb_get_ssl_certfp(rb_fde_t *const F, uint8_t certfp[const RB_SSL_CERTFP_LEN], const int method)
{
int ret;
if(F == NULL || F->ssl == NULL)
{
rb_lib_log("%s: no GNUTLS context", __func__);
return 0;
}
if(gnutls_certificate_type_get(SSL_P(F)) != GNUTLS_CRT_X509)
{
rb_lib_log("%s: not an X.509 certificate", __func__);
return 0;
}
unsigned int cert_list_size = 0;
const gnutls_datum_t *const cert_list = gnutls_certificate_get_peers(SSL_P(F), &cert_list_size);
if(cert_list == NULL || cert_list_size < 1)
{
rb_lib_log("%s: no peer certificate chain returned", __func__);
return 0;
}
gnutls_x509_crt_t peer_cert;
if((ret = gnutls_x509_crt_init(&peer_cert)) != 0)
{
rb_lib_log("%s: gnutls_x509_crt_init: %d", __func__, ret);
return 0;
}
if((ret = gnutls_x509_crt_import(peer_cert, &cert_list[0], GNUTLS_X509_FMT_DER)) < 0)
{
rb_lib_log("%s: gnutls_x509_crt_import: %d", __func__, ret);
gnutls_x509_crt_deinit(peer_cert);
return 0;
}
const int len = make_certfp(peer_cert, certfp, method);
gnutls_x509_crt_deinit(peer_cert);
return len;
}
void
rb_get_ssl_info(char *const buf, const size_t len)
{
(void) rb_snprintf(buf, len, "GNUTLS: compiled (v%s), library (v%s)",
LIBGNUTLS_VERSION, gnutls_check_version(NULL));
}
const char *
rb_ssl_get_cipher(rb_fde_t *const F)
{
if(F == NULL || F->ssl == NULL)
return NULL;
static char buf[512];
gnutls_protocol_t version_ptr = gnutls_protocol_get_version(SSL_P(F));
gnutls_cipher_algorithm_t cipher_ptr = gnutls_cipher_get(SSL_P(F));
const char *const version = gnutls_protocol_get_name(version_ptr);
const char *const cipher = gnutls_cipher_get_name(cipher_ptr);
(void) rb_snprintf(buf, sizeof buf, "%s, %s", version, cipher);
return buf;
}
ssize_t
rb_ssl_read(rb_fde_t *const F, void *const buf, const size_t count)
{
return rb_ssl_read_or_write(0, F, buf, NULL, count);
}
ssize_t
rb_ssl_write(rb_fde_t *const F, const void *const buf, const size_t count)
{
return rb_ssl_read_or_write(1, F, NULL, buf, count);
}
/*
* Internal library-agnostic code
*/
static void
rb_ssl_connect_realcb(rb_fde_t *const F, const int status, struct ssl_connect *const sconn)
{
lrb_assert(F != NULL);
lrb_assert(F->connect != NULL);
F->connect->callback = sconn->callback;
F->connect->data = sconn->data;
rb_connect_callback(F, status);
rb_free(sconn);
}
static void
rb_ssl_timeout_cb(rb_fde_t *const F, void *const data)
{
lrb_assert(F->accept != NULL);
lrb_assert(F->accept->callback != NULL);
F->accept->callback(F, RB_ERR_TIMEOUT, NULL, 0, F->accept->data);
}
static void
rb_ssl_tryconn_timeout_cb(rb_fde_t *const F, void *const data)
{
rb_ssl_connect_realcb(F, RB_ERR_TIMEOUT, data);
}
static void
rb_ssl_tryconn(rb_fde_t *const F, const int status, void *const data)
{
lrb_assert(F != NULL);
struct ssl_connect *const sconn = data;
if(status != RB_OK)
{
rb_ssl_connect_realcb(F, status, sconn);
return;
}
F->type |= RB_FD_SSL;
rb_settimeout(F, sconn->timeout, rb_ssl_tryconn_timeout_cb, sconn);
rb_ssl_init_fd(F, RB_FD_TLS_DIRECTION_OUT);
rb_ssl_connect_common(F, sconn);
}
/*
* External library-agnostic code
*/
int
rb_supports_ssl(void)
{
return 1;
}
unsigned int
rb_ssl_handshake_count(rb_fde_t *const F)
{
return F->handshake_count;
}
void
rb_ssl_clear_handshake_count(rb_fde_t *const F)
{
F->handshake_count = 0;
}
void
rb_ssl_start_accepted(rb_fde_t *const F, ACCB *const cb, void *const data, const int timeout)
{
F->type |= RB_FD_SSL;
F->accept = rb_malloc(sizeof(struct acceptdata));
F->accept->callback = cb;
F->accept->data = data;
F->accept->addrlen = 0;
(void) memset(&F->accept->S, 0x00, sizeof F->accept->S);
rb_settimeout(F, timeout, rb_ssl_timeout_cb, NULL);
rb_ssl_init_fd(F, RB_FD_TLS_DIRECTION_IN);
rb_ssl_accept_common(F, NULL);
}
void
rb_ssl_accept_setup(rb_fde_t *const srv_F, rb_fde_t *const cli_F, struct sockaddr *const st, const int addrlen)
{
cli_F->type |= RB_FD_SSL;
cli_F->accept = rb_malloc(sizeof(struct acceptdata));
cli_F->accept->callback = srv_F->accept->callback;
cli_F->accept->data = srv_F->accept->data;
cli_F->accept->addrlen = (rb_socklen_t) addrlen;
(void) memset(&cli_F->accept->S, 0x00, sizeof cli_F->accept->S);
(void) memcpy(&cli_F->accept->S, st, (size_t) addrlen);
rb_settimeout(cli_F, 10, rb_ssl_timeout_cb, NULL);
rb_ssl_init_fd(cli_F, RB_FD_TLS_DIRECTION_IN);
rb_ssl_accept_common(cli_F, NULL);
}
int
rb_ssl_listen(rb_fde_t *const F, const int backlog, const int defer_accept)
{
int result = rb_listen(F, backlog, defer_accept);
F->type = RB_FD_SOCKET | RB_FD_LISTEN | RB_FD_SSL;
return result;
}
void
rb_connect_tcp_ssl(rb_fde_t *const F, struct sockaddr *const dest, struct sockaddr *const clocal,
const int socklen, CNCB *const callback, void *const data, const int timeout)
{
if(F == NULL)
return;
struct ssl_connect *const sconn = rb_malloc(sizeof *sconn);
sconn->data = data;
sconn->callback = callback;
sconn->timeout = timeout;
rb_connect_tcp(F, dest, clocal, socklen, rb_ssl_tryconn, sconn, timeout);
}
void
rb_ssl_start_connected(rb_fde_t *const F, CNCB *const callback, void *const data, const int timeout)
{
if(F == NULL)
return;
struct ssl_connect *const sconn = rb_malloc(sizeof *sconn);
sconn->data = data;
sconn->callback = callback;
sconn->timeout = timeout;
F->connect = rb_malloc(sizeof(struct conndata));
F->connect->callback = callback;
F->connect->data = data;
F->type |= RB_FD_SSL;
rb_settimeout(F, sconn->timeout, rb_ssl_tryconn_timeout_cb, sconn);
rb_ssl_init_fd(F, RB_FD_TLS_DIRECTION_OUT);
rb_ssl_connect_common(F, sconn);
}
#endif /* HAVE_GNUTLS */

View file

@ -1,37 +0,0 @@
/*
* libratbox: a library used by ircd-ratbox and other things
* gnutls_ratbox.h: embedded data for GNUTLS backend
*
* Copyright (C) 2007-2008 ircd-ratbox development team
* Copyright (C) 2007-2008 Aaron Sethman <androsyn@ratbox.org>
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*
*/
static const char rb_gnutls_default_priority_str[] = ""
"+SECURE256:"
"+SECURE128:"
"!RSA:"
"+NORMAL:"
"!ARCFOUR-128:"
"!3DES-CBC:"
"!MD5:"
"+VERS-TLS1.2:"
"+VERS-TLS1.1:"
"!VERS-TLS1.0:"
"!VERS-SSL3.0:"
"%SAFE_RENEGOTIATION";

View file

@ -1,839 +0,0 @@
/*
* ircd-ratbox: A slightly useful ircd.
* linebuf.c: Maintains linebuffers.
*
* Copyright (C) 2001-2002 Adrian Chadd <adrian@creative.net.au>
* Copyright (C) 2002 Hybrid Development Team
* Copyright (C) 2002-2005 ircd-ratbox development team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*
* $Id: linebuf.c 26092 2008-09-19 15:13:52Z androsyn $
*/
#include <libratbox_config.h>
#include <ratbox_lib.h>
#include <commio-int.h>
static rb_bh *rb_linebuf_heap;
static int bufline_count = 0;
#ifndef LINEBUF_HEAP_SIZE
#define LINEBUF_HEAP_SIZE 2048
#endif
/*
* rb_linebuf_init
*
* Initialise the linebuf mechanism
*/
void
rb_linebuf_init(size_t heap_size)
{
rb_linebuf_heap = rb_bh_create(sizeof(buf_line_t), heap_size, "librb_linebuf_heap");
}
static buf_line_t *
rb_linebuf_allocate(void)
{
buf_line_t *t;
t = rb_bh_alloc(rb_linebuf_heap);
return (t);
}
static void
rb_linebuf_free(buf_line_t * p)
{
rb_bh_free(rb_linebuf_heap, p);
}
/*
* rb_linebuf_new_line
*
* Create a new line, and link it to the given linebuf.
* It will be initially empty.
*/
static buf_line_t *
rb_linebuf_new_line(buf_head_t * bufhead)
{
buf_line_t *bufline;
rb_dlink_node *node;
bufline = rb_linebuf_allocate();
if(bufline == NULL)
return NULL;
++bufline_count;
node = rb_make_rb_dlink_node();
/* Stick it at the end of the buf list */
rb_dlinkAddTail(bufline, node, &bufhead->list);
bufline->refcount++;
/* And finally, update the allocated size */
bufhead->alloclen++;
bufhead->numlines++;
return bufline;
}
/*
* rb_linebuf_done_line
*
* We've finished with the given line, so deallocate it
*/
static void
rb_linebuf_done_line(buf_head_t * bufhead, buf_line_t * bufline, rb_dlink_node *node)
{
/* Remove it from the linked list */
rb_dlinkDestroy(node, &bufhead->list);
/* Update the allocated size */
bufhead->alloclen--;
bufhead->len -= bufline->len;
lrb_assert(bufhead->len >= 0);
bufhead->numlines--;
bufline->refcount--;
lrb_assert(bufline->refcount >= 0);
if(bufline->refcount == 0)
{
/* and finally, deallocate the buf */
--bufline_count;
lrb_assert(bufline_count >= 0);
rb_linebuf_free(bufline);
}
}
/*
* skip to end of line or the crlfs, return the number of bytes ..
*/
static inline int
rb_linebuf_skip_crlf(char *ch, int len)
{
int orig_len = len;
/* First, skip until the first non-CRLF */
for(; len; len--, ch++)
{
if(*ch == '\r')
break;
else if(*ch == '\n')
break;
}
/* Then, skip until the last CRLF */
for(; len; len--, ch++)
{
if((*ch != '\r') && (*ch != '\n'))
break;
}
lrb_assert(orig_len > len);
return (orig_len - len);
}
/*
* rb_linebuf_newbuf
*
* Initialise the new buffer
*/
void
rb_linebuf_newbuf(buf_head_t * bufhead)
{
/* not much to do right now :) */
memset(bufhead, 0, sizeof(buf_head_t));
}
/*
* rb_linebuf_donebuf
*
* Flush all the lines associated with this buffer
*/
void
rb_linebuf_donebuf(buf_head_t * bufhead)
{
while(bufhead->list.head != NULL)
{
rb_linebuf_done_line(bufhead, (buf_line_t *) bufhead->list.head->data,
bufhead->list.head);
}
}
/*
* rb_linebuf_copy_line
*
* Okay..this functions comments made absolutely no sense.
*
* Basically what we do is this. Find the first chunk of text
* and then scan for a CRLF. If we didn't find it, but we didn't
* overflow our buffer..we wait for some more data.
* If we found a CRLF, we replace them with a \0 character.
* If we overflowed, we copy the most our buffer can handle, terminate
* it with a \0 and return.
*
* The return value is the amount of data we consumed. This could
* be different than the size of the linebuffer, as when we discard
* the overflow, we don't want to process it again.
*
* This still sucks in my opinion, but it seems to work.
*
* -Aaron
*/
static int
rb_linebuf_copy_line(buf_head_t * bufhead, buf_line_t * bufline, char *data, int len)
{
int cpylen = 0; /* how many bytes we've copied */
char *ch = data; /* Pointer to where we are in the read data */
char *bufch = bufline->buf + bufline->len;
int clen = 0; /* how many bytes we've processed,
and don't ever want to see again.. */
/* If its full or terminated, ignore it */
bufline->raw = 0;
lrb_assert(bufline->len < BUF_DATA_SIZE);
if(bufline->terminated == 1)
return 0;
clen = cpylen = rb_linebuf_skip_crlf(ch, len);
if(clen == -1)
return -1;
/* This is the ~overflow case..This doesn't happen often.. */
if(cpylen > (BUF_DATA_SIZE - bufline->len - 1))
{
cpylen = BUF_DATA_SIZE - bufline->len - 1;
memcpy(bufch, ch, cpylen);
bufline->buf[BUF_DATA_SIZE - 1] = '\0';
bufch = bufline->buf + BUF_DATA_SIZE - 2;
while(cpylen && (*bufch == '\r' || *bufch == '\n'))
{
*bufch = '\0';
cpylen--;
bufch--;
}
bufline->terminated = 1;
bufline->len = BUF_DATA_SIZE - 1;
bufhead->len += BUF_DATA_SIZE - 1;
return clen;
}
memcpy(bufch, ch, cpylen);
bufch += cpylen;
*bufch = '\0';
bufch--;
if(*bufch != '\r' && *bufch != '\n')
{
/* No linefeed, bail for the next time */
bufhead->len += cpylen;
bufline->len += cpylen;
bufline->terminated = 0;
return clen;
}
/* Yank the CRLF off this, replace with a \0 */
while(cpylen && (*bufch == '\r' || *bufch == '\n'))
{
*bufch = '\0';
cpylen--;
bufch--;
}
bufline->terminated = 1;
bufhead->len += cpylen;
bufline->len += cpylen;
return clen;
}
/*
* rb_linebuf_copy_raw
*
* Copy as much data as possible directly into a linebuf,
* splitting at \r\n, but without altering any data.
*
*/
static int
rb_linebuf_copy_raw(buf_head_t * bufhead, buf_line_t * bufline, char *data, int len)
{
int cpylen = 0; /* how many bytes we've copied */
char *ch = data; /* Pointer to where we are in the read data */
char *bufch = bufline->buf + bufline->len;
int clen = 0; /* how many bytes we've processed,
and don't ever want to see again.. */
/* If its full or terminated, ignore it */
bufline->raw = 1;
lrb_assert(bufline->len < BUF_DATA_SIZE);
if(bufline->terminated == 1)
return 0;
clen = cpylen = rb_linebuf_skip_crlf(ch, len);
if(clen == -1)
return -1;
/* This is the overflow case..This doesn't happen often.. */
if(cpylen > (BUF_DATA_SIZE - bufline->len - 1))
{
clen = BUF_DATA_SIZE - bufline->len - 1;
memcpy(bufch, ch, clen);
bufline->buf[BUF_DATA_SIZE - 1] = '\0';
bufline->terminated = 1;
bufline->len = BUF_DATA_SIZE - 1;
bufhead->len += BUF_DATA_SIZE - 1;
return clen;
}
memcpy(bufch, ch, cpylen);
bufch += cpylen;
*bufch = '\0';
bufch--;
if(*bufch != '\r' && *bufch != '\n')
{
/* No linefeed, bail for the next time */
bufhead->len += cpylen;
bufline->len += cpylen;
bufline->terminated = 0;
return clen;
}
bufline->terminated = 1;
bufhead->len += cpylen;
bufline->len += cpylen;
return clen;
}
/*
* rb_linebuf_parse
*
* Take a given buffer and break out as many buffers as we can.
* If we find a CRLF, we terminate that buffer and create a new one.
* If we don't find a CRLF whilst parsing a buffer, we don't mark it
* 'finished', so the next loop through we can continue appending ..
*
* A few notes here, which you'll need to understand before continuing.
*
* - right now I'm only dealing with single sized buffers. Later on,
* I might consider chaining buffers together to get longer "lines"
* but seriously, I don't see the advantage right now.
*
* - This *is* designed to turn into a reference-counter-protected setup
* to dodge copious copies.
*/
int
rb_linebuf_parse(buf_head_t * bufhead, char *data, int len, int raw)
{
buf_line_t *bufline;
int cpylen;
int linecnt = 0;
/* First, if we have a partial buffer, try to squeze data into it */
if(bufhead->list.tail != NULL)
{
/* Check we're doing the partial buffer thing */
bufline = bufhead->list.tail->data;
/* just try, the worst it could do is *reject* us .. */
if(!raw)
cpylen = rb_linebuf_copy_line(bufhead, bufline, data, len);
else
cpylen = rb_linebuf_copy_raw(bufhead, bufline, data, len);
if(cpylen == -1)
return -1;
linecnt++;
/* If we've copied the same as what we've got, quit now */
if(cpylen == len)
return linecnt; /* all the data done so soon? */
/* Skip the data and update len .. */
len -= cpylen;
lrb_assert(len >= 0);
data += cpylen;
}
/* Next, the loop */
while(len > 0)
{
/* We obviously need a new buffer, so .. */
bufline = rb_linebuf_new_line(bufhead);
/* And parse */
if(!raw)
cpylen = rb_linebuf_copy_line(bufhead, bufline, data, len);
else
cpylen = rb_linebuf_copy_raw(bufhead, bufline, data, len);
if(cpylen == -1)
return -1;
len -= cpylen;
lrb_assert(len >= 0);
data += cpylen;
linecnt++;
}
return linecnt;
}
/*
* rb_linebuf_get
*
* get the next buffer from our line. For the time being it will copy
* data into the given buffer and free the underlying linebuf.
*/
int
rb_linebuf_get(buf_head_t * bufhead, char *buf, int buflen, int partial, int raw)
{
buf_line_t *bufline;
int cpylen;
char *start, *ch;
/* make sure we have a line */
if(bufhead->list.head == NULL)
return 0; /* Obviously not.. hrm. */
bufline = bufhead->list.head->data;
/* make sure that the buffer was actually *terminated */
if(!(partial || bufline->terminated))
return 0; /* Wait for more data! */
if(buflen < bufline->len)
cpylen = buflen - 1;
else
cpylen = bufline->len;
/* Copy it */
start = bufline->buf;
/* if we left extraneous '\r\n' characters in the string,
* and we don't want to read the raw data, clean up the string.
*/
if(bufline->raw && !raw)
{
/* skip leading EOL characters */
while(cpylen && (*start == '\r' || *start == '\n'))
{
start++;
cpylen--;
}
/* skip trailing EOL characters */
ch = &start[cpylen - 1];
while(cpylen && (*ch == '\r' || *ch == '\n'))
{
ch--;
cpylen--;
}
}
memcpy(buf, start, cpylen);
/* convert CR/LF to NULL */
if(!raw)
buf[cpylen] = '\0';
lrb_assert(cpylen >= 0);
/* Deallocate the line */
rb_linebuf_done_line(bufhead, bufline, bufhead->list.head);
/* return how much we copied */
return cpylen;
}
/*
* rb_linebuf_attach
*
* attach the lines in a buf_head_t to another buf_head_t
* without copying the data (using refcounts).
*/
void
rb_linebuf_attach(buf_head_t * bufhead, buf_head_t * new)
{
rb_dlink_node *ptr;
buf_line_t *line;
RB_DLINK_FOREACH(ptr, new->list.head)
{
line = ptr->data;
rb_dlinkAddTailAlloc(line, &bufhead->list);
/* Update the allocated size */
bufhead->alloclen++;
bufhead->len += line->len;
bufhead->numlines++;
line->refcount++;
}
}
/*
* rb_linebuf_putmsg
*
* Similar to rb_linebuf_put, but designed for use by send.c.
*
* prefixfmt is used as a format for the varargs, and is inserted first.
* Then format/va_args is appended to the buffer.
*/
void
rb_linebuf_putmsg(buf_head_t * bufhead, const char *format, va_list * va_args,
const char *prefixfmt, ...)
{
buf_line_t *bufline;
int len = 0;
va_list prefix_args;
/* make sure the previous line is terminated */
#ifndef NDEBUG
if(bufhead->list.tail)
{
bufline = bufhead->list.tail->data;
lrb_assert(bufline->terminated);
}
#endif
/* Create a new line */
bufline = rb_linebuf_new_line(bufhead);
if(prefixfmt != NULL)
{
va_start(prefix_args, prefixfmt);
len = rb_vsnprintf(bufline->buf, BUF_DATA_SIZE, prefixfmt, prefix_args);
va_end(prefix_args);
}
if(va_args != NULL)
{
len += rb_vsnprintf((bufline->buf + len), (BUF_DATA_SIZE - len), format, *va_args);
}
bufline->terminated = 1;
/* Truncate the data if required */
if(rb_unlikely(len > 510))
{
len = 510;
bufline->buf[len++] = '\r';
bufline->buf[len++] = '\n';
}
else if(rb_unlikely(len == 0))
{
bufline->buf[len++] = '\r';
bufline->buf[len++] = '\n';
bufline->buf[len] = '\0';
}
else
{
/* Chop trailing CRLF's .. */
while((bufline->buf[len] == '\r') || (bufline->buf[len] == '\n')
|| (bufline->buf[len] == '\0'))
{
len--;
}
bufline->buf[++len] = '\r';
bufline->buf[++len] = '\n';
bufline->buf[++len] = '\0';
}
bufline->len = len;
bufhead->len += len;
}
void
rb_linebuf_putbuf(buf_head_t * bufhead, const char *buffer)
{
buf_line_t *bufline;
int len = 0;
/* make sure the previous line is terminated */
#ifndef NDEBUG
if(bufhead->list.tail)
{
bufline = bufhead->list.tail->data;
lrb_assert(bufline->terminated);
}
#endif
/* Create a new line */
bufline = rb_linebuf_new_line(bufhead);
if(rb_unlikely(buffer != NULL))
len = rb_strlcpy(bufline->buf, buffer, BUF_DATA_SIZE);
bufline->terminated = 1;
/* Truncate the data if required */
if(rb_unlikely(len > 510))
{
len = 510;
bufline->buf[len++] = '\r';
bufline->buf[len++] = '\n';
}
else if(rb_unlikely(len == 0))
{
bufline->buf[len++] = '\r';
bufline->buf[len++] = '\n';
bufline->buf[len] = '\0';
}
else
{
/* Chop trailing CRLF's .. */
while((bufline->buf[len] == '\r') || (bufline->buf[len] == '\n')
|| (bufline->buf[len] == '\0'))
{
len--;
}
bufline->buf[++len] = '\r';
bufline->buf[++len] = '\n';
bufline->buf[++len] = '\0';
}
bufline->len = len;
bufhead->len += len;
}
void
rb_linebuf_put(buf_head_t * bufhead, const char *format, ...)
{
buf_line_t *bufline;
int len = 0;
va_list args;
/* make sure the previous line is terminated */
#ifndef NDEBUG
if(bufhead->list.tail)
{
bufline = bufhead->list.tail->data;
lrb_assert(bufline->terminated);
}
#endif
/* Create a new line */
bufline = rb_linebuf_new_line(bufhead);
if(rb_unlikely(format != NULL))
{
va_start(args, format);
len = rb_vsnprintf(bufline->buf, BUF_DATA_SIZE, format, args);
va_end(args);
}
bufline->terminated = 1;
/* Truncate the data if required */
if(rb_unlikely(len > 510))
{
len = 510;
bufline->buf[len++] = '\r';
bufline->buf[len++] = '\n';
}
else if(rb_unlikely(len == 0))
{
bufline->buf[len++] = '\r';
bufline->buf[len++] = '\n';
bufline->buf[len] = '\0';
}
else
{
/* Chop trailing CRLF's .. */
while((bufline->buf[len] == '\r') || (bufline->buf[len] == '\n')
|| (bufline->buf[len] == '\0'))
{
len--;
}
bufline->buf[++len] = '\r';
bufline->buf[++len] = '\n';
bufline->buf[++len] = '\0';
}
bufline->len = len;
bufhead->len += len;
}
/*
* rb_linebuf_flush
*
* Flush data to the buffer. It tries to write as much data as possible
* to the given socket. Any return values are passed straight through.
* If there is no data in the socket, EWOULDBLOCK is set as an errno
* rather than returning 0 (which would map to an EOF..)
*
* Notes: XXX We *should* have a clue here when a non-full buffer is arrived.
* and tag it so that we don't re-schedule another write until
* we have a CRLF.
*/
int
rb_linebuf_flush(rb_fde_t *F, buf_head_t * bufhead)
{
buf_line_t *bufline;
int retval;
/*
* autoconf checks for this..but really just want to use it if we have a
* native version even if libircd provides a fake version...
*/
#ifdef HAVE_WRITEV
if(!rb_fd_ssl(F))
{
rb_dlink_node *ptr;
int x = 0, y;
int xret;
static struct rb_iovec vec[RB_UIO_MAXIOV];
memset(vec, 0, sizeof(vec));
/* Check we actually have a first buffer */
if(bufhead->list.head == NULL)
{
/* nope, so we return none .. */
errno = EWOULDBLOCK;
return -1;
}
ptr = bufhead->list.head;
bufline = ptr->data;
if(!bufline->terminated)
{
errno = EWOULDBLOCK;
return -1;
}
vec[x].iov_base = bufline->buf + bufhead->writeofs;
vec[x++].iov_len = bufline->len - bufhead->writeofs;
ptr = ptr->next;
do
{
if(ptr == NULL)
break;
bufline = ptr->data;
if(!bufline->terminated)
break;
vec[x].iov_base = bufline->buf;
vec[x].iov_len = bufline->len;
ptr = ptr->next;
}
while(++x < RB_UIO_MAXIOV);
if(x == 0)
{
errno = EWOULDBLOCK;
return -1;
}
xret = retval = rb_writev(F, vec, x);
if(retval <= 0)
return retval;
ptr = bufhead->list.head;
for(y = 0; y < x; y++)
{
bufline = ptr->data;
if(xret >= bufline->len - bufhead->writeofs)
{
xret -= bufline->len - bufhead->writeofs;
ptr = ptr->next;
rb_linebuf_done_line(bufhead, bufline, bufhead->list.head);
bufhead->writeofs = 0;
}
else
{
bufhead->writeofs += xret;
break;
}
}
return retval;
}
#endif
/* this is the non-writev case */
/* Check we actually have a first buffer */
if(bufhead->list.head == NULL)
{
/* nope, so we return none .. */
errno = EWOULDBLOCK;
return -1;
}
bufline = bufhead->list.head->data;
/* And that its actually full .. */
if(!bufline->terminated)
{
errno = EWOULDBLOCK;
return -1;
}
/* Now, try writing data */
retval = rb_write(F, bufline->buf + bufhead->writeofs, bufline->len - bufhead->writeofs);
if(retval <= 0)
return retval;
/* we've got data, so update the write offset */
bufhead->writeofs += retval;
/* if we've written everything *and* the CRLF, deallocate and update
bufhead */
if(bufhead->writeofs == bufline->len)
{
bufhead->writeofs = 0;
lrb_assert(bufhead->len >= 0);
rb_linebuf_done_line(bufhead, bufline, bufhead->list.head);
}
/* Return line length */
return retval;
}
/*
* count linebufs for stats z
*/
void
rb_count_rb_linebuf_memory(size_t *count, size_t *rb_linebuf_memory_used)
{
rb_bh_usage(rb_linebuf_heap, count, NULL, rb_linebuf_memory_used, NULL);
}

View file

@ -1,896 +0,0 @@
/*
* libratbox: a library used by ircd-ratbox and other things
* mbedtls.c: ARM MbedTLS backend
*
* Copyright (C) 2007-2008 ircd-ratbox development team
* Copyright (C) 2007-2008 Aaron Sethman <androsyn@ratbox.org>
* Copyright (C) 2015 William Pitcock <nenolod@dereferenced.org>
* Copyright (C) 2016 Aaron Jones <aaronmdjones@gmail.com>
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*
*/
#include <libratbox_config.h>
#include <ratbox_lib.h>
#ifdef HAVE_MBEDTLS
#include <commio-int.h>
#include <commio-ssl.h>
#include "mbedtls_ratbox.h"
typedef enum
{
RB_FD_TLS_DIRECTION_IN = 0,
RB_FD_TLS_DIRECTION_OUT = 1
} rb_fd_tls_direction;
#define RB_MAX_CIPHERSUITES 512
typedef struct
{
mbedtls_x509_crt crt;
mbedtls_pk_context key;
mbedtls_dhm_context dhp;
mbedtls_ssl_config server_cfg;
mbedtls_ssl_config client_cfg;
size_t refcount;
int suites[RB_MAX_CIPHERSUITES + 1];
} rb_mbedtls_cfg_context;
typedef struct
{
rb_mbedtls_cfg_context *cfg;
mbedtls_ssl_context ssl;
} rb_mbedtls_ssl_context;
#define SSL_C(x) ((rb_mbedtls_ssl_context *) (x)->ssl)->cfg
#define SSL_P(x) &((rb_mbedtls_ssl_context *) (x)->ssl)->ssl
static mbedtls_ctr_drbg_context ctr_drbg_ctx;
static mbedtls_entropy_context entropy_ctx;
static rb_mbedtls_cfg_context *rb_mbedtls_cfg = NULL;
#if (MBEDTLS_VERSION_NUMBER < 0x02050100)
static mbedtls_x509_crt dummy_ca_ctx;
#endif
struct ssl_connect
{
CNCB *callback;
void *data;
int timeout;
};
static const char *rb_ssl_strerror(int);
static void rb_ssl_connect_realcb(rb_fde_t *, int, struct ssl_connect *);
/*
* Internal MbedTLS-specific code
*/
static void
rb_mbedtls_cfg_incref(rb_mbedtls_cfg_context *const cfg)
{
lrb_assert(cfg->refcount > 0);
cfg->refcount++;
}
static void
rb_mbedtls_cfg_decref(rb_mbedtls_cfg_context *const cfg)
{
if(cfg == NULL)
return;
lrb_assert(cfg->refcount > 0);
if((--cfg->refcount) > 0)
return;
mbedtls_ssl_config_free(&cfg->client_cfg);
mbedtls_ssl_config_free(&cfg->server_cfg);
mbedtls_dhm_free(&cfg->dhp);
mbedtls_pk_free(&cfg->key);
mbedtls_x509_crt_free(&cfg->crt);
rb_free(cfg);
}
static int
rb_sock_net_recv(void *const context_ptr, unsigned char *const buf, const size_t count)
{
const int fd = rb_get_fd((rb_fde_t *)context_ptr);
const int ret = (int) read(fd, buf, count);
if(ret < 0 && rb_ignore_errno(errno))
return MBEDTLS_ERR_SSL_WANT_READ;
return ret;
}
static int
rb_sock_net_xmit(void *const context_ptr, const unsigned char *const buf, const size_t count)
{
const int fd = rb_get_fd((rb_fde_t *)context_ptr);
const int ret = (int) write(fd, buf, count);
if(ret < 0 && rb_ignore_errno(errno))
return MBEDTLS_ERR_SSL_WANT_WRITE;
return ret;
}
static void
rb_ssl_init_fd(rb_fde_t *const F, const rb_fd_tls_direction dir)
{
rb_mbedtls_ssl_context *const mbed_ssl_ctx = rb_malloc(sizeof *mbed_ssl_ctx);
if(mbed_ssl_ctx == NULL)
{
rb_lib_log("%s: rb_malloc: allocation failure", __func__);
rb_close(F);
return;
}
mbedtls_ssl_config *mbed_config = NULL;
switch(dir)
{
case RB_FD_TLS_DIRECTION_IN:
mbed_config = &rb_mbedtls_cfg->server_cfg;
break;
case RB_FD_TLS_DIRECTION_OUT:
mbed_config = &rb_mbedtls_cfg->client_cfg;
break;
}
mbedtls_ssl_init(&mbed_ssl_ctx->ssl);
int ret;
if((ret = mbedtls_ssl_setup(&mbed_ssl_ctx->ssl, mbed_config)) != 0)
{
rb_lib_log("%s: ssl_setup: %s", __func__, rb_ssl_strerror(ret));
mbedtls_ssl_free(&mbed_ssl_ctx->ssl);
rb_free(mbed_ssl_ctx);
rb_close(F);
return;
}
mbedtls_ssl_set_bio(&mbed_ssl_ctx->ssl, F, rb_sock_net_xmit, rb_sock_net_recv, NULL);
rb_mbedtls_cfg_incref(rb_mbedtls_cfg);
mbed_ssl_ctx->cfg = rb_mbedtls_cfg;
F->ssl = mbed_ssl_ctx;
}
static rb_mbedtls_cfg_context *
rb_mbedtls_cfg_new(void)
{
rb_mbedtls_cfg_context *const cfg = rb_malloc(sizeof *cfg);
if(cfg == NULL)
return NULL;
mbedtls_x509_crt_init(&cfg->crt);
mbedtls_pk_init(&cfg->key);
mbedtls_dhm_init(&cfg->dhp);
mbedtls_ssl_config_init(&cfg->server_cfg);
mbedtls_ssl_config_init(&cfg->client_cfg);
(void) memset(cfg->suites, 0x00, sizeof cfg->suites);
cfg->refcount = 1;
int ret;
if((ret = mbedtls_ssl_config_defaults(&cfg->server_cfg,
MBEDTLS_SSL_IS_SERVER, MBEDTLS_SSL_TRANSPORT_STREAM,
MBEDTLS_SSL_PRESET_DEFAULT)) != 0)
{
rb_lib_log("%s: ssl_config_defaults (server): %s", __func__, rb_ssl_strerror(ret));
rb_mbedtls_cfg_decref(cfg);
return NULL;
}
if((ret = mbedtls_ssl_config_defaults(&cfg->client_cfg,
MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM,
MBEDTLS_SSL_PRESET_DEFAULT)) != 0)
{
rb_lib_log("%s: ssl_config_defaults (client): %s", __func__, rb_ssl_strerror(ret));
rb_mbedtls_cfg_decref(cfg);
return NULL;
}
mbedtls_ssl_conf_rng(&cfg->server_cfg, mbedtls_ctr_drbg_random, &ctr_drbg_ctx);
mbedtls_ssl_conf_rng(&cfg->client_cfg, mbedtls_ctr_drbg_random, &ctr_drbg_ctx);
#if (MBEDTLS_VERSION_NUMBER < 0x02050100)
mbedtls_ssl_conf_ca_chain(&cfg->server_cfg, &dummy_ca_ctx, NULL);
mbedtls_ssl_conf_ca_chain(&cfg->client_cfg, &dummy_ca_ctx, NULL);
#endif
mbedtls_ssl_conf_authmode(&cfg->server_cfg, MBEDTLS_SSL_VERIFY_OPTIONAL);
mbedtls_ssl_conf_authmode(&cfg->client_cfg, MBEDTLS_SSL_VERIFY_NONE);
mbedtls_ssl_conf_min_version(&cfg->server_cfg, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_2);
mbedtls_ssl_conf_min_version(&cfg->client_cfg, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_2);
#ifdef MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE
mbedtls_ssl_conf_legacy_renegotiation(&cfg->client_cfg, MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE);
#endif
#ifdef MBEDTLS_SSL_SESSION_TICKETS_DISABLED
mbedtls_ssl_conf_session_tickets(&cfg->client_cfg, MBEDTLS_SSL_SESSION_TICKETS_DISABLED);
#endif
return cfg;
}
static void
rb_ssl_accept_common(rb_fde_t *const F, void *const data)
{
lrb_assert(F != NULL);
lrb_assert(F->accept != NULL);
lrb_assert(F->accept->callback != NULL);
lrb_assert(F->ssl != NULL);
(void) data;
const int ret = mbedtls_ssl_handshake(SSL_P(F));
switch(ret)
{
case 0:
F->handshake_count++;
break;
case MBEDTLS_ERR_SSL_WANT_READ:
rb_setselect(F, RB_SELECT_READ, rb_ssl_accept_common, NULL);
return;
case MBEDTLS_ERR_SSL_WANT_WRITE:
rb_setselect(F, RB_SELECT_WRITE, rb_ssl_accept_common, NULL);
return;
default:
errno = EIO;
F->ssl_errno = (unsigned long) -ret;
F->accept->callback(F, RB_ERROR_SSL, NULL, 0, F->accept->data);
return;
}
rb_settimeout(F, 0, NULL, NULL);
rb_setselect(F, RB_SELECT_READ | RB_SELECT_WRITE, NULL, NULL);
struct acceptdata *const ad = F->accept;
F->accept = NULL;
ad->callback(F, RB_OK, (struct sockaddr *)&ad->S, ad->addrlen, ad->data);
rb_free(ad);
}
static void
rb_ssl_connect_common(rb_fde_t *const F, void *const data)
{
lrb_assert(F != NULL);
lrb_assert(F->ssl != NULL);
const int ret = mbedtls_ssl_handshake(SSL_P(F));
switch(ret)
{
case 0:
F->handshake_count++;
break;
case MBEDTLS_ERR_SSL_WANT_READ:
rb_setselect(F, RB_SELECT_READ, rb_ssl_connect_common, data);
return;
case MBEDTLS_ERR_SSL_WANT_WRITE:
rb_setselect(F, RB_SELECT_WRITE, rb_ssl_connect_common, data);
return;
default:
errno = EIO;
F->ssl_errno = (unsigned long) -ret;
rb_ssl_connect_realcb(F, RB_ERROR_SSL, data);
return;
}
rb_ssl_connect_realcb(F, RB_OK, data);
}
static const char *
rb_ssl_strerror(int err)
{
static char errbuf[512];
if (err < 0)
err = -err;
#ifdef MBEDTLS_ERROR_C
char mbed_errbuf[512];
mbedtls_strerror(err, mbed_errbuf, sizeof mbed_errbuf);
(void) rb_snprintf(errbuf, sizeof errbuf, "-0x%X: %s", (unsigned int) err, mbed_errbuf);
#else
(void) rb_snprintf(errbuf, sizeof errbuf, "-0x%X", (unsigned int) err);
#endif
return errbuf;
}
static int
rb_make_certfp(const mbedtls_x509_crt *const peer_cert, uint8_t certfp[const RB_SSL_CERTFP_LEN], const int method)
{
size_t hashlen = 0;
mbedtls_md_type_t md_type;
int spki = 0;
switch(method)
{
case RB_SSL_CERTFP_METH_CERT_SHA1:
md_type = MBEDTLS_MD_SHA1;
hashlen = RB_SSL_CERTFP_LEN_SHA1;
break;
case RB_SSL_CERTFP_METH_SPKI_SHA256:
spki = 1;
case RB_SSL_CERTFP_METH_CERT_SHA256:
md_type = MBEDTLS_MD_SHA256;
hashlen = RB_SSL_CERTFP_LEN_SHA256;
break;
case RB_SSL_CERTFP_METH_SPKI_SHA512:
spki = 1;
case RB_SSL_CERTFP_METH_CERT_SHA512:
md_type = MBEDTLS_MD_SHA512;
hashlen = RB_SSL_CERTFP_LEN_SHA512;
break;
default:
return 0;
}
const mbedtls_md_info_t *const md_info = mbedtls_md_info_from_type(md_type);
if(md_info == NULL)
return 0;
int ret;
void* data = peer_cert->raw.p;
size_t datalen = peer_cert->raw.len;
if(spki)
{
// Compiler may complain about dropping const qualifier on the cast below
// See <https://github.com/ARMmbed/mbedtls/issues/396> -- this is okay
unsigned char der_pubkey[8192];
if((ret = mbedtls_pk_write_pubkey_der((mbedtls_pk_context *)&peer_cert->pk,
der_pubkey, sizeof der_pubkey)) < 0)
{
rb_lib_log("%s: pk_write_pubkey_der: %s", __func__, rb_ssl_strerror(ret));
return 0;
}
data = der_pubkey + (sizeof(der_pubkey) - (size_t)ret);
datalen = (size_t)ret;
}
if((ret = mbedtls_md(md_info, data, datalen, certfp)) != 0)
{
rb_lib_log("%s: mbedtls_md: %s", __func__, rb_ssl_strerror(ret));
return 0;
}
return (int) hashlen;
}
/*
* External MbedTLS-specific code
*/
void
rb_ssl_shutdown(rb_fde_t *const F)
{
if(F == NULL || F->ssl == NULL)
return;
for(int i = 0; i < 4; i++)
{
int ret = mbedtls_ssl_close_notify(SSL_P(F));
if(ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE)
break;
}
mbedtls_ssl_free(SSL_P(F));
rb_mbedtls_cfg_decref(SSL_C(F));
rb_free(F->ssl);
F->ssl = NULL;
}
int
rb_init_ssl(void)
{
mbedtls_ctr_drbg_init(&ctr_drbg_ctx);
mbedtls_entropy_init(&entropy_ctx);
int ret;
if((ret = mbedtls_ctr_drbg_seed(&ctr_drbg_ctx, mbedtls_entropy_func, &entropy_ctx,
(const unsigned char *)rb_mbedtls_personal_str, sizeof(rb_mbedtls_personal_str))) != 0)
{
rb_lib_log("%s: ctr_drbg_seed: %s", __func__, rb_ssl_strerror(ret));
return 0;
}
#if (MBEDTLS_VERSION_NUMBER < 0x02050100)
if((ret = mbedtls_x509_crt_parse_der(&dummy_ca_ctx, rb_mbedtls_dummy_ca_certificate,
sizeof(rb_mbedtls_dummy_ca_certificate))) != 0)
{
rb_lib_log("%s: x509_crt_parse_der (Dummy CA): %s", __func__, rb_ssl_strerror(ret));
return 0;
}
#endif
rb_lib_log("%s: MbedTLS backend initialised", __func__);
return 1;
}
int
rb_setup_ssl_server(const char *const certfile, const char *keyfile,
const char *const dhfile, const char *const cipherlist, const char *hostname)
{
if(certfile == NULL)
{
rb_lib_log("%s: no certificate file specified", __func__);
return 0;
}
if(keyfile == NULL)
keyfile = certfile;
rb_mbedtls_cfg_context *const newcfg = rb_mbedtls_cfg_new();
if(newcfg == NULL)
{
rb_lib_log("%s: rb_mbedtls_cfg_new: allocation failed", __func__);
return 0;
}
int ret;
if((ret = mbedtls_x509_crt_parse_file(&newcfg->crt, certfile)) != 0)
{
rb_lib_log("%s: x509_crt_parse_file ('%s'): %s", __func__, certfile, rb_ssl_strerror(ret));
rb_mbedtls_cfg_decref(newcfg);
return 0;
}
if((ret = mbedtls_pk_parse_keyfile(&newcfg->key, keyfile, NULL)) != 0)
{
rb_lib_log("%s: pk_parse_keyfile ('%s'): %s", __func__, keyfile, rb_ssl_strerror(ret));
rb_mbedtls_cfg_decref(newcfg);
return 0;
}
if((ret = mbedtls_pk_check_pair(&newcfg->crt.pk, &newcfg->key)) != 0)
{
rb_lib_log("%s: pk_check_pair: public/private key mismatch", __func__);
rb_mbedtls_cfg_decref(newcfg);
return 0;
}
if((ret = mbedtls_ssl_conf_own_cert(&newcfg->server_cfg, &newcfg->crt, &newcfg->key)) != 0)
{
rb_lib_log("%s: ssl_conf_own_cert (server): %s", __func__, rb_ssl_strerror(ret));
rb_mbedtls_cfg_decref(newcfg);
return 0;
}
if((ret = mbedtls_ssl_conf_own_cert(&newcfg->client_cfg, &newcfg->crt, &newcfg->key)) != 0)
{
rb_lib_log("%s: ssl_conf_own_cert (client): %s", __func__, rb_ssl_strerror(ret));
rb_mbedtls_cfg_decref(newcfg);
return 0;
}
/* Absense of DH parameters does not matter with mbedTLS, as it comes with its own defaults
Thus, clients can still use DHE- ciphersuites, just over a weaker, common DH group
So, we do not consider failure to parse DH parameters as fatal */
if(dhfile == NULL)
{
rb_lib_log("%s: no DH parameters file specified", __func__);
}
else
{
if((ret = mbedtls_dhm_parse_dhmfile(&newcfg->dhp, dhfile)) != 0)
{
rb_lib_log("%s: dhm_parse_dhmfile ('%s'): %s", __func__, dhfile, rb_ssl_strerror(ret));
}
else if((ret = mbedtls_ssl_conf_dh_param_ctx(&newcfg->server_cfg, &newcfg->dhp)) != 0)
{
rb_lib_log("%s: ssl_conf_dh_param_ctx: %s", __func__, rb_ssl_strerror(ret));
}
}
const int *rb_ciphersuites = newcfg->suites;
size_t suites_count = 0;
if(cipherlist != NULL)
{
// The cipherlist is (const char *) -- we should not modify it
char *const cipherlist_dup = strdup(cipherlist);
if(cipherlist_dup != NULL)
{
char *cipher_str = cipherlist_dup;
char *cipher_idx;
do
{
// Arbitrary, but the same separator as OpenSSL uses
cipher_idx = strchr(cipher_str, ':');
// This could legitimately be NULL (last ciphersuite in the list)
if(cipher_idx != NULL)
*cipher_idx = '\0';
size_t cipher_len = strlen(cipher_str);
int cipher_idn = 0;
// All MbedTLS ciphersuite names begin with these 4 characters
if(cipher_len > 4 && strncmp(cipher_str, "TLS-", 4) == 0)
cipher_idn = mbedtls_ssl_get_ciphersuite_id(cipher_str);
// Prevent the same ciphersuite being added multiple times
for(size_t x = 0; cipher_idn != 0 && newcfg->suites[x] != 0; x++)
if(newcfg->suites[x] == cipher_idn)
cipher_idn = 0;
// Add the suite to the list
if(cipher_idn != 0)
newcfg->suites[suites_count++] = cipher_idn;
// Advance the string to the next entry
if(cipher_idx)
cipher_str = cipher_idx + 1;
} while(cipher_idx && suites_count < RB_MAX_CIPHERSUITES);
if(suites_count == 0)
rb_lib_log("%s: Ciphersuites provided, but could not parse any", __func__);
free(cipherlist_dup);
}
else
{
rb_lib_log("%s: strdup: %s", __func__, strerror(errno));
}
}
else
{
rb_lib_log("%s: No ciphersuite list provided", __func__);
}
if(suites_count == 0)
{
rb_lib_log("%s: Using default ciphersuites", __func__);
rb_ciphersuites = rb_mbedtls_ciphersuites;
suites_count = (sizeof(rb_mbedtls_ciphersuites) / sizeof(rb_mbedtls_ciphersuites[0])) - 1;
}
mbedtls_ssl_conf_ciphersuites(&newcfg->server_cfg, rb_ciphersuites);
mbedtls_ssl_conf_ciphersuites(&newcfg->client_cfg, rb_ciphersuites);
rb_lib_log("%s: Configured %zu ciphersuites", __func__, suites_count);
rb_mbedtls_cfg_decref(rb_mbedtls_cfg);
rb_mbedtls_cfg = newcfg;
rb_lib_log("%s: TLS configuration successful", __func__);
return 1;
}
int
rb_init_prng(const char *const path, prng_seed_t seed_type)
{
(void) path;
(void) seed_type;
rb_lib_log("%s: Skipping PRNG initialisation; not required by MbedTLS backend", __func__);
return 1;
}
int
rb_get_random(void *const buf, const size_t length)
{
int ret;
if((ret = mbedtls_ctr_drbg_random(&ctr_drbg_ctx, buf, length)) != 0)
{
rb_lib_log("%s: ctr_drbg_random: %s", __func__, rb_ssl_strerror(ret));
return 0;
}
return 1;
}
const char *
rb_get_ssl_strerror(rb_fde_t *const F)
{
const int err = (int) F->ssl_errno;
return rb_ssl_strerror(err);
}
int
rb_get_ssl_certfp(rb_fde_t *const F, uint8_t certfp[const RB_SSL_CERTFP_LEN], const int method)
{
if(F == NULL || F->ssl == NULL)
return 0;
const mbedtls_x509_crt *const peer_cert = mbedtls_ssl_get_peer_cert(SSL_P(F));
if(peer_cert == NULL)
return 0;
return rb_make_certfp(peer_cert, certfp, method);
}
void
rb_get_ssl_info(char *const buf, const size_t len)
{
char version_str[512];
mbedtls_version_get_string(version_str);
(void) rb_snprintf(buf, len, "ARM mbedTLS: compiled (v%s), library (v%s)",
MBEDTLS_VERSION_STRING, version_str);
}
const char *
rb_ssl_get_cipher(rb_fde_t *const F)
{
if(F == NULL || F->ssl == NULL)
return NULL;
static char buf[512];
const char *const version = mbedtls_ssl_get_version(SSL_P(F));
const char *const cipher = mbedtls_ssl_get_ciphersuite(SSL_P(F));
(void) rb_snprintf(buf, sizeof buf, "%s, %s", version, cipher);
return buf;
}
ssize_t
rb_ssl_read(rb_fde_t *const F, void *const buf, const size_t count)
{
lrb_assert(F != NULL);
lrb_assert(F->ssl != NULL);
const int ret = mbedtls_ssl_read(SSL_P(F), buf, count);
if(ret >= 0)
return (ssize_t) ret;
switch(ret)
{
case MBEDTLS_ERR_SSL_WANT_READ:
errno = EAGAIN;
return RB_RW_SSL_NEED_READ;
case MBEDTLS_ERR_SSL_WANT_WRITE:
errno = EAGAIN;
return RB_RW_SSL_NEED_WRITE;
default:
errno = EIO;
F->ssl_errno = (unsigned long) -ret;
return RB_RW_SSL_ERROR;
}
}
ssize_t
rb_ssl_write(rb_fde_t *const F, const void *const buf, const size_t count)
{
lrb_assert(F != NULL);
lrb_assert(F->ssl != NULL);
const int ret = mbedtls_ssl_write(SSL_P(F), buf, count);
if(ret >= 0)
return (ssize_t) ret;
switch(ret)
{
case MBEDTLS_ERR_SSL_WANT_READ:
errno = EAGAIN;
return RB_RW_SSL_NEED_READ;
case MBEDTLS_ERR_SSL_WANT_WRITE:
errno = EAGAIN;
return RB_RW_SSL_NEED_WRITE;
default:
errno = EIO;
F->ssl_errno = (unsigned long) -ret;
return RB_RW_SSL_ERROR;
}
}
/*
* Internal library-agnostic code
*/
static void
rb_ssl_connect_realcb(rb_fde_t *const F, const int status, struct ssl_connect *const sconn)
{
lrb_assert(F != NULL);
lrb_assert(F->connect != NULL);
F->connect->callback = sconn->callback;
F->connect->data = sconn->data;
rb_connect_callback(F, status);
rb_free(sconn);
}
static void
rb_ssl_timeout_cb(rb_fde_t *const F, void *const data)
{
(void) data;
lrb_assert(F->accept != NULL);
lrb_assert(F->accept->callback != NULL);
F->accept->callback(F, RB_ERR_TIMEOUT, NULL, 0, F->accept->data);
}
static void
rb_ssl_tryconn_timeout_cb(rb_fde_t *const F, void *const data)
{
rb_ssl_connect_realcb(F, RB_ERR_TIMEOUT, data);
}
static void
rb_ssl_tryconn(rb_fde_t *const F, const int status, void *const data)
{
lrb_assert(F != NULL);
struct ssl_connect *const sconn = data;
if(status != RB_OK)
{
rb_ssl_connect_realcb(F, status, sconn);
return;
}
F->type |= RB_FD_SSL;
rb_settimeout(F, sconn->timeout, rb_ssl_tryconn_timeout_cb, sconn);
rb_ssl_init_fd(F, RB_FD_TLS_DIRECTION_OUT);
rb_ssl_connect_common(F, sconn);
}
/*
* External library-agnostic code
*/
int
rb_supports_ssl(void)
{
return 1;
}
unsigned int
rb_ssl_handshake_count(rb_fde_t *const F)
{
return F->handshake_count;
}
void
rb_ssl_clear_handshake_count(rb_fde_t *const F)
{
F->handshake_count = 0;
}
void
rb_ssl_start_accepted(rb_fde_t *const F, ACCB *const cb, void *const data, const int timeout)
{
F->type |= RB_FD_SSL;
F->accept = rb_malloc(sizeof(struct acceptdata));
F->accept->callback = cb;
F->accept->data = data;
F->accept->addrlen = 0;
(void) memset(&F->accept->S, 0x00, sizeof F->accept->S);
rb_settimeout(F, timeout, rb_ssl_timeout_cb, NULL);
rb_ssl_init_fd(F, RB_FD_TLS_DIRECTION_IN);
rb_ssl_accept_common(F, NULL);
}
void
rb_ssl_accept_setup(rb_fde_t *const srv_F, rb_fde_t *const cli_F, struct sockaddr *const st, const int addrlen)
{
cli_F->type |= RB_FD_SSL;
cli_F->accept = rb_malloc(sizeof(struct acceptdata));
cli_F->accept->callback = srv_F->accept->callback;
cli_F->accept->data = srv_F->accept->data;
cli_F->accept->addrlen = (rb_socklen_t) addrlen;
(void) memset(&cli_F->accept->S, 0x00, sizeof cli_F->accept->S);
(void) memcpy(&cli_F->accept->S, st, (size_t) addrlen);
rb_settimeout(cli_F, 10, rb_ssl_timeout_cb, NULL);
rb_ssl_init_fd(cli_F, RB_FD_TLS_DIRECTION_IN);
rb_ssl_accept_common(cli_F, NULL);
}
int
rb_ssl_listen(rb_fde_t *const F, const int backlog, const int defer_accept)
{
int result = rb_listen(F, backlog, defer_accept);
F->type = RB_FD_SOCKET | RB_FD_LISTEN | RB_FD_SSL;
return result;
}
void
rb_connect_tcp_ssl(rb_fde_t *const F, struct sockaddr *const dest, struct sockaddr *const clocal,
const int socklen, CNCB *const callback, void *const data, const int timeout)
{
if(F == NULL)
return;
struct ssl_connect *const sconn = rb_malloc(sizeof *sconn);
sconn->data = data;
sconn->callback = callback;
sconn->timeout = timeout;
rb_connect_tcp(F, dest, clocal, socklen, rb_ssl_tryconn, sconn, timeout);
}
void
rb_ssl_start_connected(rb_fde_t *const F, CNCB *const callback, void *const data, const int timeout)
{
if(F == NULL)
return;
struct ssl_connect *const sconn = rb_malloc(sizeof *sconn);
sconn->data = data;
sconn->callback = callback;
sconn->timeout = timeout;
F->connect = rb_malloc(sizeof(struct conndata));
F->connect->callback = callback;
F->connect->data = data;
F->type |= RB_FD_SSL;
rb_settimeout(F, sconn->timeout, rb_ssl_tryconn_timeout_cb, sconn);
rb_ssl_init_fd(F, RB_FD_TLS_DIRECTION_OUT);
rb_ssl_connect_common(F, sconn);
}
#endif /* HAVE_MBEDTLS */

View file

@ -1,237 +0,0 @@
/*
* libratbox: a library used by ircd-ratbox and other things
* mbedtls_ratbox.h: embedded data for ARM MbedTLS backend
*
* Copyright (C) 2016 Aaron Jones <aaronmdjones@gmail.com>
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*
* $Id$
*/
#ifndef RB_MBEDTLS_EMBEDDED_DATA_H
#define RB_MBEDTLS_EMBEDDED_DATA_H
#include "mbedtls/entropy.h"
#include "mbedtls/ctr_drbg.h"
#include "mbedtls/certs.h"
#include "mbedtls/x509.h"
#include "mbedtls/ssl.h"
#include "mbedtls/ssl_ciphersuites.h"
#include "mbedtls/error.h"
#include "mbedtls/debug.h"
#include "mbedtls/dhm.h"
#include "mbedtls/version.h"
/*
* Personalization string for CTR-DRBG initialization
*/
static const char rb_mbedtls_personal_str[] = "charybdis/librb personalization string";
/*
* Default list of supported ciphersuites
* The user can override this with the ssl_cipher_list option in ircd.conf
*
* The format for this option is the same as the macro names below, but
* with underscores replaced with hyphens, and without the initial MBEDTLS_
*
* For example;
* ssl_cipher_list = "TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384"
*
* Multiple ciphersuites can be separated by colons (:)
*
* ************************************************************************
*
* The ordering of the following list should be intuitive. Within the list;
*
* * All AEAD forward-secret ciphersuites are located first [1]
* * All SHA2 forward-secret ciphersuites are located second
* * All remaining forward-secret ciphersuites are located third
* * All non-forward-secret ciphersuites are located last, in the same order
*
* [1] Because in practice, they are the only secure ciphersuites available;
* the ETM extension for CBC ciphersuites has not seen wide adoption.
*
* In practice, all clients SHOULD support an AEAD forward-secret cipher,
* which the server will then negotiate as they are preferred.
*
* This choice can be revisited in future; please consult me first. -- amdj
*/
static const int rb_mbedtls_ciphersuites[] = {
// AEAD forward-secret ciphersuites
#ifdef MBEDTLS_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
MBEDTLS_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
MBEDTLS_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
MBEDTLS_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
#endif
MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384,
MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384,
MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384,
MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM,
MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM,
MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256,
MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256,
MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256,
MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM,
MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM,
// SHA2 forward-secret ciphersuites
MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384,
MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384,
MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,
MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256,
MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256,
MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256,
MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256,
// Remaining forward-secret ciphersuites
MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA,
MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA,
// Non-forward-secret ciphersuites
MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384,
MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384,
MBEDTLS_TLS_RSA_WITH_AES_256_CCM,
MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256,
MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256,
MBEDTLS_TLS_RSA_WITH_AES_128_CCM,
MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256,
MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256,
MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256,
MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256,
MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA,
MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA,
MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA,
MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA,
// The end of list sentinel
0
};
/*
* YES, this is a hardcoded CA certificate.
*
* BEFORE YOU THROW YOUR ARMS UP IN A PANIC ABOUT A BACKDOOR, READ THIS TEXT!
*
* ARM mbedTLS required a CA certificate to be set in its configuration before it will
* process a client certificate from peers. Since we want to do that, and not all
* installations will have a CA certificate to hand, we have this.
*
* Its key was securely destroyed after being generated, but even if it wasn't, that
* doesn't matter; the IRCd will accept ALL certificates, whether signed by this CA
* certificate or not!
*
* After all, it only cares about certificates in as far as to generate a fingerprint
* for them.
*
* Yes, this is a massive hack, but there is no alternative for older versions.
*
* This issue was fixed in commit 39ae8cd2077d on the MbedTLS 2.5 development branch,
* released in version 2.5.1 on 19 June 2017. This certificate will not be used if
* that version (or greater) is installed.
*/
#if (MBEDTLS_VERSION_NUMBER < 0x02050100)
static const unsigned char rb_mbedtls_dummy_ca_certificate[825] = {
0x30, 0x82, 0x03, 0x35, 0x30, 0x82, 0x02, 0x1D, 0xA0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x09, 0x00,
0x86, 0xC5, 0x1F, 0x62, 0xBE, 0xFC, 0x0B, 0xA8, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86,
0xF7, 0x0D, 0x01, 0x01, 0x0B, 0x05, 0x00, 0x30, 0x31, 0x31, 0x2F, 0x30, 0x2D, 0x06, 0x03, 0x55,
0x04, 0x03, 0x0C, 0x26, 0x43, 0x68, 0x61, 0x72, 0x79, 0x62, 0x64, 0x69, 0x73, 0x20, 0x6D, 0x62,
0x65, 0x64, 0x54, 0x4C, 0x53, 0x20, 0x44, 0x75, 0x6D, 0x6D, 0x79, 0x20, 0x43, 0x41, 0x20, 0x43,
0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x30, 0x1E, 0x17, 0x0D, 0x31, 0x36,
0x30, 0x35, 0x30, 0x34, 0x30, 0x38, 0x35, 0x32, 0x35, 0x33, 0x5A, 0x17, 0x0D, 0x34, 0x33, 0x30,
0x39, 0x32, 0x30, 0x30, 0x38, 0x35, 0x32, 0x35, 0x33, 0x5A, 0x30, 0x31, 0x31, 0x2F, 0x30, 0x2D,
0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x26, 0x43, 0x68, 0x61, 0x72, 0x79, 0x62, 0x64, 0x69, 0x73,
0x20, 0x6D, 0x62, 0x65, 0x64, 0x54, 0x4C, 0x53, 0x20, 0x44, 0x75, 0x6D, 0x6D, 0x79, 0x20, 0x43,
0x41, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x30, 0x82, 0x01,
0x22, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00,
0x03, 0x82, 0x01, 0x0F, 0x00, 0x30, 0x82, 0x01, 0x0A, 0x02, 0x82, 0x01, 0x01, 0x00, 0xCA, 0x4B,
0xA6, 0xA1, 0x82, 0x5B, 0x06, 0xC6, 0x82, 0x76, 0x8E, 0xB2, 0x22, 0x37, 0x83, 0x91, 0x4B, 0xD0,
0xAE, 0x2F, 0xEE, 0x8E, 0x60, 0x04, 0xBA, 0x77, 0x8C, 0xD0, 0xCF, 0x5E, 0xA4, 0xFD, 0x80, 0xA1,
0x2E, 0xDC, 0x1F, 0xD9, 0x72, 0x2C, 0x28, 0x03, 0x27, 0x48, 0x23, 0x6E, 0x41, 0x49, 0x62, 0x09,
0x2D, 0xCF, 0x87, 0xA1, 0x45, 0x9D, 0x2B, 0x43, 0x6F, 0xBB, 0xDB, 0x23, 0xD8, 0xD9, 0x6D, 0x36,
0x4E, 0xA3, 0x85, 0x40, 0x4D, 0x72, 0xEC, 0x7B, 0xEF, 0x2B, 0x13, 0xE4, 0x6F, 0xDA, 0x23, 0x4F,
0x1C, 0xE7, 0xEA, 0xD9, 0x17, 0x2B, 0xD6, 0x67, 0x79, 0x42, 0xC3, 0x81, 0x9A, 0x77, 0x64, 0xC7,
0xC5, 0x44, 0xE1, 0xA4, 0xA3, 0x50, 0x8C, 0x1F, 0xCA, 0xD3, 0x6F, 0xC7, 0xFF, 0x2C, 0xBA, 0x7B,
0x21, 0x0C, 0xF3, 0xA9, 0x6A, 0x89, 0x74, 0x33, 0x60, 0xA1, 0xF8, 0x9F, 0xAA, 0x39, 0xA9, 0x45,
0x7E, 0x3D, 0x41, 0x67, 0x04, 0xF5, 0x9F, 0x47, 0x62, 0xAC, 0x65, 0xE0, 0x8D, 0x46, 0x9E, 0xD9,
0xE5, 0x77, 0xD5, 0x8C, 0x47, 0xA2, 0xFB, 0x7D, 0x94, 0x27, 0xC9, 0xB9, 0x3F, 0x4D, 0xF4, 0xFD,
0x19, 0x3C, 0xF6, 0x24, 0xAE, 0x70, 0xD7, 0x23, 0xE4, 0x64, 0x0A, 0xFC, 0x63, 0x89, 0x8A, 0xFE,
0xD0, 0x8E, 0x48, 0x1A, 0xD8, 0xC3, 0xA9, 0xEC, 0x9D, 0x0F, 0xC7, 0xC5, 0x22, 0xBC, 0x45, 0x4A,
0x2F, 0x4D, 0xF5, 0x0E, 0x4F, 0xFF, 0xAC, 0xE0, 0x55, 0xF4, 0x86, 0x04, 0x1B, 0x60, 0xDF, 0x4C,
0x25, 0xB9, 0xEC, 0x10, 0x0C, 0x54, 0x16, 0xDF, 0x42, 0xF0, 0x07, 0x00, 0x28, 0x81, 0x7C, 0x95,
0xAA, 0xC1, 0x01, 0xA3, 0xB8, 0xDF, 0x68, 0xCB, 0x55, 0xA7, 0x80, 0xCC, 0xE5, 0x3D, 0xE1, 0x68,
0x10, 0x27, 0x56, 0x94, 0x67, 0xEC, 0x82, 0x66, 0x3D, 0x96, 0x76, 0xC3, 0xEE, 0x23, 0x02, 0x03,
0x01, 0x00, 0x01, 0xA3, 0x50, 0x30, 0x4E, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x1D, 0x0E, 0x04, 0x16,
0x04, 0x14, 0xFF, 0xC8, 0xBA, 0x56, 0x74, 0xB1, 0x03, 0xA9, 0x79, 0x55, 0xFA, 0x58, 0x86, 0x13,
0xDE, 0xC0, 0xFA, 0xF2, 0x94, 0x62, 0x30, 0x1F, 0x06, 0x03, 0x55, 0x1D, 0x23, 0x04, 0x18, 0x30,
0x16, 0x80, 0x14, 0xFF, 0xC8, 0xBA, 0x56, 0x74, 0xB1, 0x03, 0xA9, 0x79, 0x55, 0xFA, 0x58, 0x86,
0x13, 0xDE, 0xC0, 0xFA, 0xF2, 0x94, 0x62, 0x30, 0x0C, 0x06, 0x03, 0x55, 0x1D, 0x13, 0x04, 0x05,
0x30, 0x03, 0x01, 0x01, 0xFF, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01,
0x01, 0x0B, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x3D, 0x35, 0x69, 0x87, 0xEB, 0x41, 0xA9,
0x2A, 0x51, 0xF3, 0x28, 0x71, 0xB4, 0x06, 0x7F, 0x15, 0x5A, 0x6D, 0x88, 0x5B, 0xC8, 0x4C, 0xE1,
0x6C, 0xC7, 0xCB, 0x93, 0x63, 0x69, 0xFB, 0xA6, 0x6D, 0xC7, 0x44, 0x6B, 0xD6, 0x39, 0x46, 0x34,
0xFC, 0x45, 0x23, 0xD2, 0x29, 0x1B, 0xCC, 0x1C, 0x13, 0xD7, 0x63, 0x10, 0x81, 0xF5, 0x82, 0x45,
0xEC, 0xDC, 0x20, 0x5F, 0xBB, 0xC3, 0xE6, 0x4A, 0x07, 0xA7, 0xBD, 0x9E, 0xFC, 0x5D, 0xFE, 0xC5,
0x43, 0x3A, 0xC6, 0xA4, 0x6C, 0x5B, 0xF9, 0x63, 0x8F, 0xF9, 0xEB, 0xC2, 0xF4, 0xA7, 0xE4, 0x1B,
0x23, 0xFA, 0xE1, 0x5A, 0x79, 0xC5, 0x1D, 0x1D, 0xFC, 0xAA, 0x81, 0xF7, 0x21, 0x52, 0xC9, 0x46,
0x17, 0x1B, 0x24, 0x4B, 0x14, 0x5C, 0xF9, 0xB5, 0x86, 0x04, 0x80, 0x51, 0x95, 0xCF, 0x4E, 0x47,
0x32, 0x8A, 0x1E, 0x52, 0x2E, 0xBF, 0x08, 0x8E, 0x9E, 0xE3, 0x88, 0x45, 0xC3, 0x75, 0xD7, 0xAE,
0xC3, 0x7E, 0x7E, 0xE9, 0xC9, 0x5B, 0xD8, 0x58, 0x3B, 0x25, 0x53, 0x0C, 0x00, 0x21, 0x1A, 0x71,
0x12, 0x23, 0xA0, 0x35, 0x6E, 0xC9, 0x7D, 0x83, 0x5C, 0x19, 0xE4, 0x05, 0x84, 0x46, 0x4E, 0x50,
0xE2, 0x9E, 0x70, 0x2E, 0x74, 0x05, 0xEA, 0x31, 0x04, 0x55, 0xA7, 0xF4, 0x67, 0x95, 0xDC, 0x86,
0x1F, 0x9D, 0xA0, 0x5D, 0x7F, 0x29, 0x48, 0x84, 0xEF, 0x13, 0xB8, 0xB3, 0xBF, 0x65, 0xD4, 0x52,
0x98, 0x06, 0xE6, 0x8A, 0xB1, 0x36, 0xEA, 0x39, 0xB3, 0x04, 0x2B, 0x6E, 0x64, 0x6E, 0xF3, 0x20,
0x74, 0xB6, 0x6E, 0x21, 0x3B, 0x99, 0xFE, 0x6E, 0x70, 0x48, 0x78, 0xEA, 0x31, 0x95, 0xB3, 0xB0,
0x0E, 0x48, 0x83, 0x35, 0xA9, 0x74, 0xBF, 0x45, 0x07, 0xC8, 0x5A, 0x12, 0xA2, 0x4D, 0x16, 0xDB,
0xB3, 0x1F, 0x72, 0xDE, 0x2A, 0x28, 0xFE, 0x7C, 0x2D
};
#endif /* MBEDTLS_VERSION_NUMBER */
#endif /* RB_MBEDTLS_EMBEDDED_DATA_H */

View file

@ -1,185 +0,0 @@
/*
* libratbox: a library used by ircd-ratbox and other things
* nossl.c: ssl stub code
*
* Copyright (C) 2007-2008 ircd-ratbox development team
* Copyright (C) 2007-2008 Aaron Sethman <androsyn@ratbox.org>
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*
* $Id: commio.c 24808 2008-01-02 08:17:05Z androsyn $
*/
#include <libratbox_config.h>
#include <ratbox_lib.h>
#if !defined(HAVE_OPENSSL) && !defined(HAVE_GNUTLS) && !defined(HAVE_MBEDTLS)
#include "arc4random.h"
#include <commio-int.h>
#include <commio-ssl.h>
int
rb_setup_ssl_server(const char *cert, const char *keyfile, const char *dhfile, const char *cipher_list, const char *hostname)
{
errno = ENOSYS;
return 0;
}
int
rb_init_ssl(void)
{
errno = ENOSYS;
return -1;
}
int
rb_ssl_listen(rb_fde_t *F, int backlog, int defer_accept)
{
errno = ENOSYS;
return -1;
}
static void
rb_stir_arc4random(void *unused)
{
arc4random_stir();
}
int
rb_init_prng(const char *path, prng_seed_t seed_type)
{
/* xxx this ignores the parameters above */
arc4random_stir();
rb_event_addish("rb_stir_arc4random", rb_stir_arc4random, NULL, 300);
return 1;
}
int
rb_get_random(void *buf, size_t length)
{
uint32_t rnd = 0, i;
uint8_t *xbuf = buf;
for(i = 0; i < length; i++)
{
if(i % 4 == 0)
rnd = arc4random();
xbuf[i] = rnd;
rnd >>= 8;
}
return 1;
}
const char *
rb_get_ssl_strerror(rb_fde_t *F)
{
static const char *nosupport = "SSL/TLS not supported";
return nosupport;
}
int
rb_get_ssl_certfp(rb_fde_t *F, uint8_t certfp[RB_SSL_CERTFP_LEN], int method)
{
return 0;
}
void
rb_ssl_start_accepted(rb_fde_t *new_F, ACCB * cb, void *data, int timeout)
{
return;
}
void
rb_ssl_start_connected(rb_fde_t *F, CNCB * callback, void *data, int timeout)
{
return;
}
void
rb_connect_tcp_ssl(rb_fde_t *F, struct sockaddr *dest,
struct sockaddr *clocal, int socklen, CNCB * callback, void *data, int timeout)
{
return;
}
int
rb_supports_ssl(void)
{
return 0;
}
void
rb_ssl_shutdown(rb_fde_t *F)
{
return;
}
void
rb_ssl_accept_setup(rb_fde_t *F, rb_fde_t *new_F, struct sockaddr *st, int addrlen)
{
return;
}
ssize_t
rb_ssl_read(rb_fde_t *F, void *buf, size_t count)
{
errno = ENOSYS;
return -1;
}
ssize_t
rb_ssl_write(rb_fde_t *F, const void *buf, size_t count)
{
errno = ENOSYS;
return -1;
}
unsigned int
rb_ssl_handshake_count(rb_fde_t *F)
{
return 0;
}
void
rb_ssl_clear_handshake_count(rb_fde_t *F)
{
return;
}
void
rb_get_ssl_info(char *buf, size_t len)
{
rb_snprintf(buf, len, "Not compiled with SSL support");
}
int
rb_ssl_get_certfp(rb_fde_t *F, uint8_t certfp[RB_SSL_CERTFP_LEN])
{
errno = ENOSYS;
return -1;
}
const char *
rb_ssl_get_cipher(rb_fde_t *F)
{
errno = ENOSYS;
return NULL;
}
#endif /* !HAVE_OPENSSL */

View file

@ -1,850 +0,0 @@
/*
* libratbox: a library used by ircd-ratbox and other things
* openssl.c: OpenSSL backend
*
* Copyright (C) 2007-2008 ircd-ratbox development team
* Copyright (C) 2007-2008 Aaron Sethman <androsyn@ratbox.org>
* Copyright (C) 2015-2016 Aaron Jones <aaronmdjones@gmail.com>
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*
*/
#include <libratbox_config.h>
#include <ratbox_lib.h>
#ifdef HAVE_OPENSSL
#include <commio-int.h>
#include <commio-ssl.h>
#include "openssl_ratbox.h"
typedef enum
{
RB_FD_TLS_DIRECTION_IN = 0,
RB_FD_TLS_DIRECTION_OUT = 1
} rb_fd_tls_direction;
#define SSL_P(x) ((SSL *)((x)->ssl))
typedef struct ssl_vhost_s
{
char *hostname;
SSL_CTX *ctx;
rb_dlink_node node;
} ssl_vhost;
static SSL_CTX *ssl_ctx = NULL;
rb_dlink_list ssl_vhosts;
rb_dlink_node *
find_ssl_vhost(const char *hostname)
{
ssl_vhost *vhost_p;
rb_dlink_node *ptr;
RB_DLINK_FOREACH(ptr, ssl_vhosts.head)
{
vhost_p = ptr->data;
if(!strcmp(hostname,vhost_p->hostname))
return ptr;
}
return NULL;
}
struct ssl_connect
{
CNCB *callback;
void *data;
int timeout;
};
static const char *rb_ssl_strerror(unsigned long);
static void rb_ssl_connect_realcb(rb_fde_t *, int, struct ssl_connect *);
/*
* Internal OpenSSL-specific code
*/
static unsigned long
rb_ssl_last_err(void)
{
unsigned long err_saved, err = 0;
while((err_saved = ERR_get_error()) != 0)
err = err_saved;
return err;
}
static void
rb_ssl_init_fd(rb_fde_t *const F, const rb_fd_tls_direction dir)
{
(void) rb_ssl_last_err();
F->ssl = SSL_new(ssl_ctx);
if(F->ssl == NULL)
{
rb_lib_log("%s: SSL_new: %s", __func__, rb_ssl_strerror(rb_ssl_last_err()));
rb_close(F);
return;
}
switch(dir)
{
case RB_FD_TLS_DIRECTION_IN:
SSL_set_accept_state(SSL_P(F));
break;
case RB_FD_TLS_DIRECTION_OUT:
SSL_set_connect_state(SSL_P(F));
break;
}
SSL_set_fd(SSL_P(F), rb_get_fd(F));
}
static void
rb_ssl_accept_common(rb_fde_t *const F, void *const data)
{
lrb_assert(F != NULL);
lrb_assert(F->accept != NULL);
lrb_assert(F->accept->callback != NULL);
lrb_assert(F->ssl != NULL);
(void) rb_ssl_last_err();
int ret = SSL_do_handshake(SSL_P(F));
int err = SSL_get_error(SSL_P(F), ret);
if(ret == 1)
{
F->handshake_count++;
rb_settimeout(F, 0, NULL, NULL);
rb_setselect(F, RB_SELECT_READ | RB_SELECT_WRITE, NULL, NULL);
struct acceptdata *const ad = F->accept;
F->accept = NULL;
ad->callback(F, RB_OK, (struct sockaddr *)&ad->S, ad->addrlen, ad->data);
rb_free(ad);
return;
}
if(ret == -1 && err == SSL_ERROR_WANT_READ)
{
rb_setselect(F, RB_SELECT_READ, rb_ssl_accept_common, NULL);
return;
}
if(ret == -1 && err == SSL_ERROR_WANT_WRITE)
{
rb_setselect(F, RB_SELECT_WRITE, rb_ssl_accept_common, NULL);
return;
}
errno = EIO;
F->ssl_errno = (unsigned long) err;
F->accept->callback(F, RB_ERROR_SSL, NULL, 0, F->accept->data);
}
static void
rb_ssl_connect_common(rb_fde_t *const F, void *const data)
{
lrb_assert(F != NULL);
lrb_assert(F->ssl != NULL);
(void) rb_ssl_last_err();
int ret = SSL_do_handshake(SSL_P(F));
int err = SSL_get_error(SSL_P(F), ret);
if(ret == 1)
{
F->handshake_count++;
rb_settimeout(F, 0, NULL, NULL);
rb_setselect(F, RB_SELECT_READ | RB_SELECT_WRITE, NULL, NULL);
rb_ssl_connect_realcb(F, RB_OK, data);
return;
}
if(ret == -1 && err == SSL_ERROR_WANT_READ)
{
rb_setselect(F, RB_SELECT_READ, rb_ssl_connect_common, data);
return;
}
if(ret == -1 && err == SSL_ERROR_WANT_WRITE)
{
rb_setselect(F, RB_SELECT_WRITE, rb_ssl_connect_common, data);
return;
}
errno = EIO;
F->ssl_errno = (unsigned long) err;
rb_ssl_connect_realcb(F, RB_ERROR_SSL, data);
}
static const char *
rb_ssl_strerror(const unsigned long err)
{
static char errbuf[512];
ERR_error_string_n(err, errbuf, sizeof errbuf);
return errbuf;
}
static int
verify_accept_all_cb(const int preverify_ok, X509_STORE_CTX *const x509_ctx)
{
return 1;
}
static ssize_t
rb_ssl_read_or_write(const int r_or_w, rb_fde_t *const F, void *const rbuf, const void *const wbuf, const size_t count)
{
ssize_t ret;
unsigned long err;
(void) rb_ssl_last_err();
if(r_or_w == 0)
ret = (ssize_t) SSL_read(SSL_P(F), rbuf, (int)count);
else
ret = (ssize_t) SSL_write(SSL_P(F), wbuf, (int)count);
if(ret < 0)
{
switch(SSL_get_error(SSL_P(F), ret))
{
case SSL_ERROR_WANT_READ:
errno = EAGAIN;
return RB_RW_SSL_NEED_READ;
case SSL_ERROR_WANT_WRITE:
errno = EAGAIN;
return RB_RW_SSL_NEED_WRITE;
case SSL_ERROR_ZERO_RETURN:
return 0;
case SSL_ERROR_SYSCALL:
err = rb_ssl_last_err();
if(err == 0)
{
F->ssl_errno = 0;
return RB_RW_IO_ERROR;
}
break;
default:
err = rb_ssl_last_err();
break;
}
F->ssl_errno = err;
if(err > 0)
{
errno = EIO; /* not great but... */
return RB_RW_SSL_ERROR;
}
return RB_RW_IO_ERROR;
}
return ret;
}
static int
make_certfp(X509 *const cert, uint8_t certfp[const RB_SSL_CERTFP_LEN], const int method)
{
unsigned int hashlen = 0;
const EVP_MD *md_type = NULL;
const ASN1_ITEM *item = NULL;
void *data = NULL;
switch(method)
{
case RB_SSL_CERTFP_METH_CERT_SHA1:
hashlen = RB_SSL_CERTFP_LEN_SHA1;
md_type = EVP_sha1();
item = ASN1_ITEM_rptr(X509);
data = cert;
break;
case RB_SSL_CERTFP_METH_CERT_SHA256:
hashlen = RB_SSL_CERTFP_LEN_SHA256;
md_type = EVP_sha256();
item = ASN1_ITEM_rptr(X509);
data = cert;
break;
case RB_SSL_CERTFP_METH_CERT_SHA512:
hashlen = RB_SSL_CERTFP_LEN_SHA512;
md_type = EVP_sha512();
item = ASN1_ITEM_rptr(X509);
data = cert;
break;
case RB_SSL_CERTFP_METH_SPKI_SHA256:
hashlen = RB_SSL_CERTFP_LEN_SHA256;
md_type = EVP_sha256();
item = ASN1_ITEM_rptr(X509_PUBKEY);
data = X509_get_X509_PUBKEY(cert);
break;
case RB_SSL_CERTFP_METH_SPKI_SHA512:
hashlen = RB_SSL_CERTFP_LEN_SHA512;
md_type = EVP_sha512();
item = ASN1_ITEM_rptr(X509_PUBKEY);
data = X509_get_X509_PUBKEY(cert);
break;
default:
return 0;
}
if(ASN1_item_digest(item, md_type, data, certfp, &hashlen) != 1)
{
rb_lib_log("%s: ASN1_item_digest: %s", __func__, rb_ssl_strerror(rb_ssl_last_err()));
return 0;
}
return (int) hashlen;
}
/*
* External OpenSSL-specific code
*/
void
rb_ssl_shutdown(rb_fde_t *const F)
{
if(F == NULL || F->ssl == NULL)
return;
(void) rb_ssl_last_err();
for(int i = 0; i < 4; i++)
{
int ret = SSL_shutdown(SSL_P(F));
int err = SSL_get_error(SSL_P(F), ret);
if(ret >= 0 || (err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE))
break;
}
SSL_free(SSL_P(F));
F->ssl = NULL;
}
int
rb_init_ssl(void)
{
#ifndef LRB_SSL_NO_EXPLICIT_INIT
(void) SSL_library_init();
SSL_load_error_strings();
#endif
rb_lib_log("%s: OpenSSL backend initialised", __func__);
return 1;
}
static int rb_ssl_servername_cb(SSL *s, int *ad, void *arg)
{
ssl_vhost *vhost_p;
rb_dlink_node *ptr;
rb_dlink_node *next_ptr;
const char * servername = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name);
rb_lib_log("Hostname in TLS extension?");
if (servername)
{
rb_lib_log("Hostname in TLS extension %s", servername);
RB_DLINK_FOREACH_SAFE(ptr, next_ptr, ssl_vhosts.head)
{
vhost_p = ptr->data;
if (strcmp(servername, vhost_p->hostname) != 0)
continue;
if (vhost_p->ctx)
{
rb_lib_log("Switching server context %s", servername);
SSL_set_SSL_CTX(s,vhost_p->ctx);
}
}
}
return SSL_TLSEXT_ERR_OK;
}
void
free_ssl_vhost(ssl_vhost *vhost_p)
{
if(vhost_p == NULL)
return;
rb_free(vhost_p->hostname);
SSL_CTX_free(vhost_p->ctx);
rb_free(vhost_p);
}
int
rb_remove_ssl_vserver(const char *hostname)
{
rb_dlink_node *ptr = find_ssl_vhost(hostname);
if(ptr != NULL && ptr) {
rb_dlinkDelete(ptr, &ssl_vhosts);
free_ssl_vhost(ptr->data);
return 1;
}
return 0;
}
int
rb_setup_ssl_server(const char *const certfile, const char *keyfile,
const char *const dhfile, const char *cipherlist,
const char *hostname)
{
if(certfile == NULL)
{
rb_lib_log("%s: no certificate file specified", __func__);
return 0;
}
if(keyfile == NULL)
keyfile = certfile;
if(cipherlist == NULL)
cipherlist = rb_default_ciphers;
(void) rb_ssl_last_err();
#ifdef LRB_HAVE_TLS_METHOD_API
SSL_CTX *const ssl_ctx_new = SSL_CTX_new(TLS_method());
#else
SSL_CTX *const ssl_ctx_new = SSL_CTX_new(SSLv23_method());
#endif
if(ssl_ctx_new == NULL)
{
rb_lib_log("%s: SSL_CTX_new: %s", __func__, rb_ssl_strerror(rb_ssl_last_err()));
return 0;
}
if(SSL_CTX_use_certificate_chain_file(ssl_ctx_new, certfile) != 1)
{
rb_lib_log("%s: SSL_CTX_use_certificate_chain_file ('%s'): %s", __func__, certfile,
rb_ssl_strerror(rb_ssl_last_err()));
SSL_CTX_free(ssl_ctx_new);
return 0;
}
if(SSL_CTX_use_PrivateKey_file(ssl_ctx_new, keyfile, SSL_FILETYPE_PEM) != 1)
{
rb_lib_log("%s: SSL_CTX_use_PrivateKey_file ('%s'): %s", __func__, keyfile,
rb_ssl_strerror(rb_ssl_last_err()));
SSL_CTX_free(ssl_ctx_new);
return 0;
}
if(dhfile == NULL)
{
rb_lib_log("%s: no DH parameters file specified", __func__);
}
else
{
FILE *const dhf = fopen(dhfile, "r");
DH *dhp = NULL;
if(dhf == NULL)
{
rb_lib_log("%s: fopen ('%s'): %s", __func__, dhfile, strerror(errno));
}
else if(PEM_read_DHparams(dhf, &dhp, NULL, NULL) == NULL)
{
rb_lib_log("%s: PEM_read_DHparams ('%s'): %s", __func__, dhfile,
rb_ssl_strerror(rb_ssl_last_err()));
fclose(dhf);
}
else
{
SSL_CTX_set_tmp_dh(ssl_ctx_new, dhp);
DH_free(dhp);
fclose(dhf);
}
}
if(SSL_CTX_set_cipher_list(ssl_ctx_new, cipherlist) != 1)
{
rb_lib_log("%s: SSL_CTX_set_cipher_list: could not configure any ciphers", __func__);
SSL_CTX_free(ssl_ctx_new);
return 0;
}
SSL_CTX_set_tlsext_servername_callback(ssl_ctx_new, rb_ssl_servername_cb);
SSL_CTX_set_session_cache_mode(ssl_ctx_new, SSL_SESS_CACHE_OFF);
SSL_CTX_set_verify(ssl_ctx_new, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, verify_accept_all_cb);
#ifdef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
(void) SSL_CTX_clear_options(ssl_ctx_new, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS);
#endif
#ifndef LRB_HAVE_TLS_METHOD_API
(void) SSL_CTX_set_options(ssl_ctx_new, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
#endif
#ifdef SSL_OP_NO_TLSv1
(void) SSL_CTX_set_options(ssl_ctx_new, SSL_OP_NO_TLSv1);
#endif
#ifdef SSL_OP_NO_TICKET
(void) SSL_CTX_set_options(ssl_ctx_new, SSL_OP_NO_TICKET);
#endif
#ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
(void) SSL_CTX_set_options(ssl_ctx_new, SSL_OP_CIPHER_SERVER_PREFERENCE);
#endif
#ifdef SSL_OP_SINGLE_DH_USE
(void) SSL_CTX_set_options(ssl_ctx_new, SSL_OP_SINGLE_DH_USE);
#endif
#ifdef SSL_OP_SINGLE_ECDH_USE
(void) SSL_CTX_set_options(ssl_ctx_new, SSL_OP_SINGLE_ECDH_USE);
#endif
#ifdef LRB_HAVE_TLS_ECDH_AUTO
(void) SSL_CTX_set_ecdh_auto(ssl_ctx_new, 1);
#endif
#ifdef LRB_HAVE_TLS_SET_CURVES
(void) SSL_CTX_set1_curves_list(ssl_ctx_new, rb_default_curves);
#else
# if (OPENSSL_VERSION_NUMBER >= 0x10000000L) && !defined(OPENSSL_NO_ECDH) && defined(NID_secp384r1)
EC_KEY *const ec_key = EC_KEY_new_by_curve_name(NID_secp384r1);
if(ec_key != NULL)
{
SSL_CTX_set_tmp_ecdh(ssl_ctx_new, ec_key);
EC_KEY_free(ec_key);
}
else
rb_lib_log("%s: EC_KEY_new_by_curve_name failed; will not enable ECDHE- ciphers", __func__);
# else
rb_lib_log("%s: OpenSSL built without ECDH support; will not enable ECDHE- ciphers", __func__);
# endif
#endif
rb_lib_log("%s: TLS configuration successful", __func__);
if(hostname == NULL) {
if(ssl_ctx)
SSL_CTX_free(ssl_ctx);
ssl_ctx = ssl_ctx_new;
} else {
ssl_vhost *vhost_p = NULL;
rb_lib_log("rb_setup_ssl_server: SETUP [%s]", hostname);
rb_dlink_node *ptr = find_ssl_vhost(hostname);
if(ptr != NULL && ptr)
vhost_p = ptr->data;
if(vhost_p == NULL) {
vhost_p = rb_malloc(sizeof(ssl_vhost));
vhost_p->hostname = rb_strdup(hostname);
rb_dlinkAdd(vhost_p, &vhost_p->node, &ssl_vhosts);
}
if(vhost_p->ctx)
SSL_CTX_free(vhost_p->ctx);
vhost_p->ctx = ssl_ctx_new;
}
return 1;
}
int
rb_init_prng(const char *const path, prng_seed_t seed_type)
{
(void) rb_ssl_last_err();
if(seed_type == RB_PRNG_FILE && RAND_load_file(path, -1) < 0)
rb_lib_log("%s: RAND_load_file: %s", __func__, rb_ssl_strerror(rb_ssl_last_err()));
if(RAND_status() != 1)
{
rb_lib_log("%s: RAND_status: %s", __func__, rb_ssl_strerror(rb_ssl_last_err()));
return 0;
}
rb_lib_log("%s: PRNG initialised", __func__);
return 1;
}
int
rb_get_random(void *const buf, const size_t length)
{
(void) rb_ssl_last_err();
if(RAND_bytes(buf, (int) length) != 1)
{
rb_lib_log("%s: RAND_bytes: %s", __func__, rb_ssl_strerror(rb_ssl_last_err()));
return 0;
}
return 1;
}
const char *
rb_get_ssl_strerror(rb_fde_t *const F)
{
return rb_ssl_strerror(F->ssl_errno);
}
int
rb_get_ssl_certfp(rb_fde_t *const F, uint8_t certfp[const RB_SSL_CERTFP_LEN], const int method)
{
if(F == NULL || F->ssl == NULL)
return 0;
X509 *const peer_cert = SSL_get_peer_certificate(SSL_P(F));
if(peer_cert == NULL)
return 0;
int len = 0;
switch(SSL_get_verify_result(SSL_P(F)))
{
case X509_V_OK:
case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
case X509_V_ERR_CERT_UNTRUSTED:
len = make_certfp(peer_cert, certfp, method);
default:
X509_free(peer_cert);
return len;
}
}
void
rb_get_ssl_info(char *const buf, const size_t len)
{
#ifdef LRB_SSL_FULL_VERSION_INFO
if(LRB_SSL_VNUM_RUNTIME == LRB_SSL_VNUM_COMPILETIME)
(void) rb_snprintf(buf, len, "OpenSSL: compiled 0x%lx, library %s",
LRB_SSL_VNUM_COMPILETIME, LRB_SSL_VTEXT_COMPILETIME);
else
(void) rb_snprintf(buf, len, "OpenSSL: compiled (0x%lx, %s), library (0x%lx, %s)",
LRB_SSL_VNUM_COMPILETIME, LRB_SSL_VTEXT_COMPILETIME,
LRB_SSL_VNUM_RUNTIME, LRB_SSL_VTEXT_RUNTIME);
#else
(void) rb_snprintf(buf, len, "OpenSSL: compiled 0x%lx, library %s",
LRB_SSL_VNUM_COMPILETIME, LRB_SSL_VTEXT_RUNTIME);
#endif
}
const char *
rb_ssl_get_cipher(rb_fde_t *const F)
{
if(F == NULL || F->ssl == NULL)
return NULL;
static char buf[512];
const char *const version = SSL_get_version(SSL_P(F));
const char *const cipher = SSL_get_cipher_name(SSL_P(F));
(void) rb_snprintf(buf, sizeof buf, "%s, %s", version, cipher);
return buf;
}
ssize_t
rb_ssl_read(rb_fde_t *const F, void *const buf, const size_t count)
{
return rb_ssl_read_or_write(0, F, buf, NULL, count);
}
ssize_t
rb_ssl_write(rb_fde_t *const F, const void *const buf, const size_t count)
{
return rb_ssl_read_or_write(1, F, NULL, buf, count);
}
/*
* Internal library-agnostic code
*/
static void
rb_ssl_connect_realcb(rb_fde_t *const F, const int status, struct ssl_connect *const sconn)
{
lrb_assert(F->connect != NULL);
F->connect->callback = sconn->callback;
F->connect->data = sconn->data;
rb_connect_callback(F, status);
rb_free(sconn);
}
static void
rb_ssl_timeout_cb(rb_fde_t *const F, void *const data)
{
lrb_assert(F->accept != NULL);
lrb_assert(F->accept->callback != NULL);
F->accept->callback(F, RB_ERR_TIMEOUT, NULL, 0, F->accept->data);
}
static void
rb_ssl_tryconn_timeout_cb(rb_fde_t *const F, void *const data)
{
rb_ssl_connect_realcb(F, RB_ERR_TIMEOUT, data);
}
static void
rb_ssl_tryconn(rb_fde_t *const F, const int status, void *const data)
{
lrb_assert(F != NULL);
struct ssl_connect *const sconn = data;
if(status != RB_OK)
{
rb_ssl_connect_realcb(F, status, sconn);
return;
}
F->type |= RB_FD_SSL;
rb_settimeout(F, sconn->timeout, rb_ssl_tryconn_timeout_cb, sconn);
rb_ssl_init_fd(F, RB_FD_TLS_DIRECTION_OUT);
rb_ssl_connect_common(F, sconn);
}
/*
* External library-agnostic code
*/
int
rb_supports_ssl(void)
{
return 1;
}
unsigned int
rb_ssl_handshake_count(rb_fde_t *const F)
{
return F->handshake_count;
}
void
rb_ssl_clear_handshake_count(rb_fde_t *const F)
{
F->handshake_count = 0;
}
void
rb_ssl_start_accepted(rb_fde_t *const F, ACCB *const cb, void *const data, const int timeout)
{
F->type |= RB_FD_SSL;
F->accept = rb_malloc(sizeof(struct acceptdata));
F->accept->callback = cb;
F->accept->data = data;
F->accept->addrlen = 0;
(void) memset(&F->accept->S, 0x00, sizeof F->accept->S);
rb_settimeout(F, timeout, rb_ssl_timeout_cb, NULL);
rb_ssl_init_fd(F, RB_FD_TLS_DIRECTION_IN);
rb_ssl_accept_common(F, NULL);
}
void
rb_ssl_accept_setup(rb_fde_t *const srv_F, rb_fde_t *const cli_F, struct sockaddr *const st, const int addrlen)
{
cli_F->type |= RB_FD_SSL;
cli_F->accept = rb_malloc(sizeof(struct acceptdata));
cli_F->accept->callback = srv_F->accept->callback;
cli_F->accept->data = srv_F->accept->data;
cli_F->accept->addrlen = (rb_socklen_t) addrlen;
(void) memset(&cli_F->accept->S, 0x00, sizeof cli_F->accept->S);
(void) memcpy(&cli_F->accept->S, st, (size_t) addrlen);
rb_settimeout(cli_F, 10, rb_ssl_timeout_cb, NULL);
rb_ssl_init_fd(cli_F, RB_FD_TLS_DIRECTION_IN);
rb_ssl_accept_common(cli_F, NULL);
}
int
rb_ssl_listen(rb_fde_t *const F, const int backlog, const int defer_accept)
{
int result = rb_listen(F, backlog, defer_accept);
F->type = RB_FD_SOCKET | RB_FD_LISTEN | RB_FD_SSL;
return result;
}
void
rb_connect_tcp_ssl(rb_fde_t *const F, struct sockaddr *const dest, struct sockaddr *const clocal,
const int socklen, CNCB *const callback, void *const data, const int timeout)
{
if(F == NULL)
return;
struct ssl_connect *const sconn = rb_malloc(sizeof *sconn);
sconn->data = data;
sconn->callback = callback;
sconn->timeout = timeout;
rb_connect_tcp(F, dest, clocal, socklen, rb_ssl_tryconn, sconn, timeout);
}
void
rb_ssl_start_connected(rb_fde_t *const F, CNCB *const callback, void *const data, const int timeout)
{
if(F == NULL)
return;
struct ssl_connect *const sconn = rb_malloc(sizeof *sconn);
sconn->data = data;
sconn->callback = callback;
sconn->timeout = timeout;
F->connect = rb_malloc(sizeof(struct conndata));
F->connect->callback = callback;
F->connect->data = data;
F->type |= RB_FD_SSL;
rb_settimeout(F, sconn->timeout, rb_ssl_tryconn_timeout_cb, sconn);
rb_ssl_init_fd(F, RB_FD_TLS_DIRECTION_OUT);
rb_ssl_connect_common(F, sconn);
}
#endif /* HAVE_OPENSSL */

View file

@ -1,141 +0,0 @@
/*
* libratbox: a library used by ircd-ratbox and other things
* openssl_ratbox.h: OpenSSL backend data
*
* Copyright (C) 2015-2016 Aaron Jones <aaronmdjones@gmail.com>
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*
*/
#ifndef LRB_OPENSSL_H_INC
#define LRB_OPENSSL_H_INC 1
#include <openssl/dh.h>
#include <openssl/ec.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/rand.h>
#include <openssl/ssl.h>
#include <openssl/opensslv.h>
/*
* A long time ago, in a world far away, OpenSSL had a well-established mechanism for ensuring compatibility with
* regards to added, changed, and removed functions, by having an SSLEAY_VERSION_NUMBER macro. This was then
* renamed to OPENSSL_VERSION_NUMBER, but the old macro was kept around for compatibility until OpenSSL version
* 1.1.0.
*
* Then the OpenBSD developers decided that having OpenSSL in their codebase was a bad idea. They forked it to
* create LibreSSL, gutted all of the functionality they didn't want or need, and generally improved the library
* a lot. Then, as the OpenBSD developers are want to do, they packaged up LibreSSL for release to other
* operating systems, as LibreSSL Portable. Think along the lines of OpenSSH where they have also done this.
*
* The fun part of this story ends there. LibreSSL has an OPENSSL_VERSION_NUMBER macro, but they have set it to a
* stupidly high value, version 2.0. OpenSSL version 2.0 does not exist, and LibreSSL 2.2 does not implement
* everything OpenSSL 1.0.2 or 1.1.0 do. This completely breaks the entire purpose of the macro.
*
* The ifdef soup below is for LibreSSL compatibility. Please find whoever thought setting OPENSSL_VERSION_NUMBER
* to a version that does not exist was a good idea. Encourage them to realise that it is not. -- amdj
*/
#if !defined(LIBRESSL_VERSION_NUMBER) && (OPENSSL_VERSION_NUMBER >= 0x10100000L)
# define LRB_SSL_NO_EXPLICIT_INIT 1
#endif
#if !defined(LIBRESSL_VERSION_NUMBER) && (OPENSSL_VERSION_NUMBER >= 0x10002000L)
# define LRB_HAVE_TLS_SET_CURVES 1
# if (OPENSSL_VERSION_NUMBER < 0x10100000L)
# define LRB_HAVE_TLS_ECDH_AUTO 1
# endif
#endif
#if defined(LIBRESSL_VERSION_NUMBER) && (LIBRESSL_VERSION_NUMBER >= 0x20020002L)
# define LRB_HAVE_TLS_METHOD_API 1
#else
# if !defined(LIBRESSL_VERSION_NUMBER) && (OPENSSL_VERSION_NUMBER >= 0x10100000L)
# define LRB_HAVE_TLS_METHOD_API 1
# endif
#endif
#if !defined(LIBRESSL_VERSION_NUMBER) && (OPENSSL_VERSION_NUMBER >= 0x10100000L)
# define LRB_SSL_VTEXT_COMPILETIME OPENSSL_VERSION_TEXT
# define LRB_SSL_VTEXT_RUNTIME OpenSSL_version(OPENSSL_VERSION)
# define LRB_SSL_VNUM_COMPILETIME OPENSSL_VERSION_NUMBER
# define LRB_SSL_VNUM_RUNTIME OpenSSL_version_num()
# define LRB_SSL_FULL_VERSION_INFO 1
#else
# if defined(LIBRESSL_VERSION_NUMBER) && (LIBRESSL_VERSION_NUMBER >= 0x20200000L)
# define LRB_SSL_VTEXT_RUNTIME SSLeay_version(SSLEAY_VERSION)
# define LRB_SSL_VNUM_COMPILETIME LIBRESSL_VERSION_NUMBER
# else
# define LRB_SSL_VTEXT_RUNTIME SSLeay_version(SSLEAY_VERSION)
# define LRB_SSL_VNUM_COMPILETIME SSLEAY_VERSION_NUMBER
# endif
#endif
#if !defined(LIBRESSL_VERSION_NUMBER) && (OPENSSL_VERSION_NUMBER > 0x10101000L)
# define LRB_HAVE_TLS_ECDH_X25519 1
#else
# if defined(LIBRESSL_VERSION_NUMBER) && (LIBRESSL_VERSION_NUMBER > 0x2050100fL)
# define LRB_HAVE_TLS_ECDH_X25519 1
# endif
#endif
/*
* Default supported ciphersuites (if the user does not provide any) and
* curves (OpenSSL 1.0.2+). Hardcoded secp384r1 (NIST P-384) is used on
* OpenSSL 1.0.0 and 1.0.1 (if available).
*
* We prefer AEAD ciphersuites first in order of strength, then SHA2
* ciphersuites, then remaining suites.
*/
static const char rb_default_ciphers[] = ""
"aECDSA+kEECDH+CHACHA20:"
"aRSA+kEECDH+CHACHA20:"
"aRSA+kEDH+CHACHA20:"
"aECDSA+kEECDH+AESGCM:"
"aRSA+kEECDH+AESGCM:"
"aRSA+kEDH+AESGCM:"
"aECDSA+kEECDH+AESCCM:"
"aRSA+kEECDH+AESCCM:"
"aRSA+kEDH+AESCCM:"
"@STRENGTH:"
"aECDSA+kEECDH+HIGH+SHA384:"
"aRSA+kEECDH+HIGH+SHA384:"
"aRSA+kEDH+HIGH+SHA384:"
"aECDSA+kEECDH+HIGH+SHA256:"
"aRSA+kEECDH+HIGH+SHA256:"
"aRSA+kEDH+HIGH+SHA256:"
"aECDSA+kEECDH+HIGH:"
"aRSA+kEECDH+HIGH:"
"aRSA+kEDH+HIGH:"
"HIGH:"
"!3DES:"
"!aNULL";
#ifdef LRB_HAVE_TLS_SET_CURVES
# ifdef LRB_HAVE_TLS_ECDH_X25519
static char rb_default_curves[] = "X25519:P-521:P-384:P-256";
# else
static char rb_default_curves[] = "P-521:P-384:P-256";
# endif
#endif
#endif /* LRB_OPENSSL_H_INC */

View file

@ -1,424 +0,0 @@
/*
* ircd-ratbox: A slightly useful ircd.
* ratbox_lib.c: libircd initialization functions at the like
*
* Copyright (C) 2005,2006 ircd-ratbox development team
* Copyright (C) 2005,2006 Aaron Sethman <androsyn@ratbox.org>
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*
* $Id: ratbox_lib.c 26282 2008-12-10 20:33:21Z androsyn $
*/
#include <libratbox_config.h>
#include <ratbox_lib.h>
#include <commio-int.h>
#include <commio-ssl.h>
static log_cb *rb_log;
static restart_cb *rb_restart;
static die_cb *rb_die;
static struct timeval rb_time;
static char errbuf[512];
/* this doesn't do locales...oh well i guess */
static const char *months[] = {
"January", "February", "March", "April",
"May", "June", "July", "August",
"September", "October", "November", "December"
};
static const char *weekdays[] = {
"Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday"
};
static const char *s_month[] = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul",
"Aug", "Sep", "Oct", "Nov", "Dec"
};
static const char *s_weekdays[] = {
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
};
char *
rb_ctime(const time_t t, char *buf, size_t len)
{
char *p;
struct tm *tp;
static char timex[128];
size_t tlen;
#if defined(HAVE_GMTIME_R)
struct tm tmr;
tp = gmtime_r(&t, &tmr);
#else
tp = gmtime(&t);
#endif
if(buf == NULL)
{
p = timex;
tlen = sizeof(timex);
}
else
{
p = buf;
tlen = len;
}
if(rb_unlikely(tp == NULL))
{
rb_strlcpy(p, "", tlen);
return (p);
}
rb_snprintf(p, tlen, "%s %s %d %02u:%02u:%02u %d",
s_weekdays[tp->tm_wday], s_month[tp->tm_mon],
tp->tm_mday, tp->tm_hour, tp->tm_min, tp->tm_sec, tp->tm_year + 1900);
return (p);
}
/* I hate this..but its sort of ircd standard now.. */
char *
rb_date(const time_t t, char *buf, size_t len)
{
struct tm *gm;
#if defined(HAVE_GMTIME_R)
struct tm gmbuf;
gm = gmtime_r(&t, &gmbuf);
#else
gm = gmtime(&t);
#endif
if(rb_unlikely(gm == NULL))
{
rb_strlcpy(buf, "", len);
return (buf);
}
rb_snprintf(buf, len, "%s %s %d %d -- %02u:%02u:%02u +00:00",
weekdays[gm->tm_wday], months[gm->tm_mon], gm->tm_mday,
gm->tm_year + 1900, gm->tm_hour, gm->tm_min, gm->tm_sec);
return (buf);
}
time_t
rb_current_time(void)
{
return rb_time.tv_sec;
}
const struct timeval *
rb_current_time_tv(void)
{
return &rb_time;
}
void
rb_lib_log(const char *format, ...)
{
va_list args;
if(rb_log == NULL)
return;
va_start(args, format);
rb_vsnprintf(errbuf, sizeof(errbuf), format, args);
va_end(args);
rb_log(errbuf);
}
void
rb_lib_die(const char *format, ...)
{
va_list args;
if(rb_die == NULL)
abort();
va_start(args, format);
rb_vsnprintf(errbuf, sizeof(errbuf), format, args);
va_end(args);
rb_die(errbuf);
}
void
rb_lib_restart(const char *format, ...)
{
va_list args;
if(rb_restart == NULL)
abort();
va_start(args, format);
rb_vsnprintf(errbuf, sizeof(errbuf), format, args);
va_end(args);
rb_restart(errbuf);
abort();
}
void
rb_set_time(void)
{
struct timeval newtime;
if(rb_unlikely(rb_gettimeofday(&newtime, NULL) == -1))
{
rb_lib_log("Clock Failure (%s)", strerror(errno));
rb_lib_restart("Clock Failure");
}
if(newtime.tv_sec < rb_time.tv_sec)
rb_set_back_events(rb_time.tv_sec - newtime.tv_sec);
memcpy(&rb_time, &newtime, sizeof(struct timeval));
}
extern const char *libratbox_serno;
const char *
rb_lib_version(void)
{
static char version_info[512];
char ssl_info[512];
rb_get_ssl_info(ssl_info, sizeof(ssl_info));
rb_snprintf(version_info, sizeof(version_info), "libratbox version: %s - %s", libratbox_serno, ssl_info);
return version_info;
}
void
rb_lib_init(log_cb * ilog, restart_cb * irestart, die_cb * idie, int closeall, int maxcon,
size_t dh_size, size_t fd_heap_size)
{
rb_set_time();
rb_log = ilog;
rb_restart = irestart;
rb_die = idie;
rb_event_init();
rb_init_bh();
rb_fdlist_init(closeall, maxcon, fd_heap_size);
rb_init_netio();
rb_init_rb_dlink_nodes(dh_size);
if(rb_io_supports_event())
{
rb_io_init_event();
}
}
void
rb_lib_loop(long delay)
{
time_t next;
rb_set_time();
if(rb_io_supports_event())
{
while(1)
rb_select(-1);
}
while(1)
{
if(delay == 0)
{
if((next = rb_event_next()) > 0)
{
next -= rb_current_time();
if(next <= 0)
next = 1000;
else
next *= 1000;
}
else
next = -1;
rb_select(next);
}
else
rb_select(delay);
rb_event_run();
}
}
#ifndef HAVE_STRTOK_R
char *
rb_strtok_r(char *s, const char *delim, char **save)
{
char *token;
if(s == NULL)
s = *save;
/* Scan leading delimiters. */
s += strspn(s, delim);
if(*s == '\0')
{
*save = s;
return NULL;
}
token = s;
s = strpbrk(token, delim);
if(s == NULL)
*save = (token + strlen(token));
else
{
*s = '\0';
*save = s + 1;
}
return token;
}
#else
char *
rb_strtok_r(char *s, const char *delim, char **save)
{
return strtok_r(s, delim, save);
}
#endif
static const char base64_table[] =
{ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/', '\0'
};
static const char base64_pad = '=';
static const short base64_reverse_table[256] = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
-1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
};
unsigned char *
rb_base64_encode(const unsigned char *str, int length)
{
const unsigned char *current = str;
unsigned char *p;
unsigned char *result;
if((length + 2) < 0 || ((length + 2) / 3) >= (1 << (sizeof(int) * 8 - 2)))
{
return NULL;
}
result = rb_malloc(((length + 2) / 3) * 5);
p = result;
while(length > 2)
{
*p++ = base64_table[current[0] >> 2];
*p++ = base64_table[((current[0] & 0x03) << 4) + (current[1] >> 4)];
*p++ = base64_table[((current[1] & 0x0f) << 2) + (current[2] >> 6)];
*p++ = base64_table[current[2] & 0x3f];
current += 3;
length -= 3;
}
if(length != 0)
{
*p++ = base64_table[current[0] >> 2];
if(length > 1)
{
*p++ = base64_table[((current[0] & 0x03) << 4) + (current[1] >> 4)];
*p++ = base64_table[(current[1] & 0x0f) << 2];
*p++ = base64_pad;
}
else
{
*p++ = base64_table[(current[0] & 0x03) << 4];
*p++ = base64_pad;
*p++ = base64_pad;
}
}
*p = '\0';
return result;
}
unsigned char *
rb_base64_decode(const unsigned char *str, int length, int *ret)
{
const unsigned char *current = str;
int ch, i = 0, j = 0, k;
unsigned char *result;
result = rb_malloc(length + 1);
while((ch = *current++) != '\0' && length-- > 0)
{
if(ch == base64_pad)
break;
ch = base64_reverse_table[ch];
if(ch < 0)
continue;
switch (i % 4)
{
case 0:
result[j] = ch << 2;
break;
case 1:
result[j++] |= ch >> 4;
result[j] = (ch & 0x0f) << 4;
break;
case 2:
result[j++] |= ch >> 2;
result[j] = (ch & 0x03) << 6;
break;
case 3:
result[j++] |= ch;
break;
}
i++;
}
k = j;
if(ch == base64_pad)
{
switch (i % 4)
{
case 1:
free(result);
return NULL;
case 2:
k++;
/* FALLTHROUGH */
case 3:
result[k++] = 0;
}
}
result[j] = '\0';
*ret = j;
return result;
}

View file

@ -105,8 +105,4 @@ do_die(struct Client *source_p, const char *servername)
}
ircd_shutdown(get_client_name(source_p, HIDE_IP));
<<<<<<< .merge_file_0nztsK
/* UNREACHABLE */
=======
>>>>>>> .merge_file_F0prEH
}

View file

@ -424,7 +424,7 @@ ms_join(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_
if(parv[2][0] == '&')
return;
char *mbuf = modebuf;
mbuf = modebuf;
mode.key[0] = mode.forward[0] = '\0';
mode.mode = mode.limit = mode.join_num = mode.join_time = 0;
@ -539,11 +539,8 @@ ms_sjoin(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source
int i, joinc = 0, timeslice = 0;
static char empty[] = "";
rb_dlink_node *ptr, *next_ptr;
<<<<<<< .merge_file_gR6TZa
=======
char *mbuf;
int pargs;
>>>>>>> .merge_file_qhnxdu
const char *para[MAXMODEPARAMS];
if(parc < 5)
@ -557,7 +554,7 @@ ms_sjoin(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source
return;
modebuf[0] = parabuf[0] = mode.key[0] = mode.forward[0] = '\0';
mode.mode = mode.limit = mode.join_num = mode.join_time = 0;
pargs = mode.mode = mode.limit = mode.join_num = mode.join_time = 0;
/* Hide connecting server on netburst -- jilles */
if (ConfigServerHide.flatten_links && !HasSentEob(source_p))
@ -565,7 +562,7 @@ ms_sjoin(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source
else
fakesource_p = source_p;
char *mbuf = modebuf;
mbuf = modebuf;
newts = atol(parv[1]);
s = parv[3];
@ -772,10 +769,9 @@ ms_sjoin(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source
mbuf = modebuf;
para[0] = para[1] = para[2] = para[3] = empty;
pargs = 0;
len_uid = 0;
int pargs = 0;
/* if theres a space, theres going to be more than one nick, change the
* first space to \0, so s is just the first nick, and point p to the
* second nick
@ -1175,12 +1171,8 @@ set_final_mode(char *mbuf, char *parabuf, struct Mode *mode, struct Mode *oldmod
len = sprintf(pbuf, "%s ", mode->forward);
pbuf += len;
}
*mbuf = '\0';
<<<<<<< .merge_file_gR6TZa
=======
>>>>>>> .merge_file_qhnxdu
return mbuf;
}
@ -1202,10 +1194,6 @@ remove_our_modes(struct Channel *chptr, struct Client *source_p)
int i;
char *mbuf = lmodebuf;
<<<<<<< .merge_file_gR6TZa
char *mbuf = lmodebuf;
=======
>>>>>>> .merge_file_qhnxdu
*mbuf++ = '-';
for(i = 0; i < MAXMODEPARAMS; i++)
@ -1308,13 +1296,8 @@ remove_ban_list(struct Channel *chptr, struct Client *source_p,
pbuf = lparabuf;
<<<<<<< .merge_file_gR6TZa
cur_len = mlen = rb_sprintf(lmodebuf, ":%s MODE %s -", source_p->name, chptr->chname);
char *mbuf = lmodebuf + mlen;
=======
cur_len = mlen = sprintf(lmodebuf, ":%s MODE %s -", source_p->name, chptr->chname);
mbuf = lmodebuf + mlen;
>>>>>>> .merge_file_qhnxdu
RB_DLINK_FOREACH_SAFE(ptr, next_ptr, list->head)
{

View file

@ -370,10 +370,7 @@ do_bmask(bool extended, struct MsgBuf *msgbuf_p, struct Client *client_p, struct
{
*forward++ = '\0';
if(*forward == '\0')
{
tlen--;
forward = NULL;
}
tlen--, forward = NULL;
else
possibly_remove_lower_forward(fakesource_p,
mems, chptr, banlist,

View file

@ -133,13 +133,9 @@ mr_server(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *sourc
}
exit_client(client_p, client_p, client_p, "Invalid servername.");
<<<<<<< .merge_file_pjgqgl
return 0;
=======
return;
/* NOT REACHED */
break;
>>>>>>> .merge_file_QmFPuY
case -2:
sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
@ -152,13 +148,9 @@ mr_server(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *sourc
log_client_name(client_p, SHOW_IP));
exit_client(client_p, client_p, client_p, "Invalid credentials.");
<<<<<<< .merge_file_pjgqgl
return 0;
=======
return;
/* NOT REACHED */
break;
>>>>>>> .merge_file_QmFPuY
case -3:
sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
@ -171,13 +163,9 @@ mr_server(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *sourc
log_client_name(client_p, SHOW_IP));
exit_client(client_p, client_p, client_p, "Invalid host.");
<<<<<<< .merge_file_pjgqgl
return 0;
=======
return;
/* NOT REACHED */
break;
>>>>>>> .merge_file_QmFPuY
/* servername is > HOSTLEN */
case -4:
@ -188,14 +176,9 @@ mr_server(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *sourc
log_client_name(client_p, SHOW_IP));
exit_client(client_p, client_p, client_p, "Invalid servername.");
<<<<<<< .merge_file_pjgqgl
return 0;
=======
return;
/* NOT REACHED */
break;
>>>>>>> .merge_file_QmFPuY
case -5:
sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
"Connection from servername %s requires SSL/TLS but is plaintext",
@ -204,20 +187,11 @@ mr_server(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *sourc
log_client_name(client_p, SHOW_IP));
exit_client(client_p, client_p, client_p, "Access denied, requires SSL/TLS but is plaintext");
<<<<<<< .merge_file_pjgqgl
return 0;
case -6:
if (client_p->certfp)
{
sendto_realops_snomask(SNO_GENERAL, L_ALL,
=======
return;
case -6:
if (client_p->certfp)
{
sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
>>>>>>> .merge_file_QmFPuY
"Connection from servername %s has invalid certificate fingerprint %s",
name, client_p->certfp);
ilog(L_SERVER, "Access denied, invalid certificate fingerprint %s from %s",
@ -226,11 +200,7 @@ mr_server(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *sourc
}
else
{
<<<<<<< .merge_file_pjgqgl
sendto_realops_snomask(SNO_GENERAL, L_ALL,
=======
sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
>>>>>>> .merge_file_QmFPuY
"Connection from servername %s failed certificate validation",
name);
ilog(L_SERVER, "Access denied; certificate validation failed for certificate from %s",
@ -238,12 +208,6 @@ mr_server(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *sourc
exit_client(client_p, client_p, client_p, "Invalid certificate.");
}
<<<<<<< .merge_file_pjgqgl
return 0;
default:
sendto_realops_snomask(SNO_GENERAL, L_ALL,
=======
return;
case -7:
sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
@ -256,7 +220,6 @@ mr_server(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *sourc
return;
default:
sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
>>>>>>> .merge_file_QmFPuY
"Connection from servername %s rejected, unknown error %d",
name, ret);
ilog(L_SERVER, "Access denied, unknown error %d for server %s%s", ret,
@ -264,11 +227,7 @@ mr_server(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *sourc
log_client_name(client_p, SHOW_IP));
exit_client(client_p, client_p, client_p, "Unknown error.");
<<<<<<< .merge_file_pjgqgl
return 0;
=======
return;
>>>>>>> .merge_file_QmFPuY
}
/* require TS6 for direct links */
@ -339,11 +298,7 @@ mr_server(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *sourc
if (client_p->preClient && !EmptyString(client_p->preClient->id)) {
if ((target_p = find_id(client_p->preClient->id)) != NULL) {
<<<<<<< .merge_file_pjgqgl
sendto_realops_snomask(SNO_GENERAL, is_remote_connect(client_p) ? L_NETWIDE : L_ALL,
=======
sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
>>>>>>> .merge_file_QmFPuY
"Attempt to re-introduce SID %s from %s%s (already in use by %s)",
client_p->preClient->id,
EmptyString(client_p->name) ? name : "",
@ -356,11 +311,7 @@ mr_server(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *sourc
sendto_one(client_p, "ERROR :SID already exists.");
exit_client(client_p, client_p, client_p, "SID Exists");
<<<<<<< .merge_file_pjgqgl
return 0;
=======
return;
>>>>>>> .merge_file_QmFPuY
} else {
rb_strlcpy(client_p->id, client_p->preClient->id, sizeof(client_p->id));
}

View file

@ -152,16 +152,6 @@ clicap_find(const char *data, int *negate, int *finished)
static void
clicap_generate(struct Client *source_p, const char *subcmd, int flags)
{
<<<<<<< .merge_file_FIhLV9
char buf[BUFSIZE] = { 0 };
char capbuf[BUFSIZE] = { 0 };
char *p;
int buflen = 0;
int curlen, mlen;
size_t i;
mlen = rb_sprintf(buf, ":%s CAP %s %s",
=======
const char *str_cont = "* :";
const char *str_final = ":";
struct CapabilityEntry *entry;
@ -170,7 +160,6 @@ clicap_generate(struct Client *source_p, const char *subcmd, int flags)
enum multiline_item_result multiline_item_ret;
multiline_ret = send_multiline_init(source_p, " ", ":%s CAP %s %s %s",
>>>>>>> .merge_file_J3fUTs
me.name,
EmptyString(source_p->name) ? "*" : source_p->name,
subcmd,
@ -218,30 +207,10 @@ clicap_generate(struct Client *source_p, const char *subcmd, int flags)
if (!flags && clicap != NULL && clicap->data != NULL)
data = clicap->data(source_p);
<<<<<<< .merge_file_FIhLV9
/* \r\n\0, possible "-~=", space, " *" */
if(buflen + clicap_list[i].namelen >= BUFSIZE - 10)
{
/* remove our trailing space -- if buflen == mlen
* here, we didnt even succeed in adding one.
*/
if(buflen != mlen)
*(p - 1) = '\0';
else
*p = '\0';
sendto_one(source_p, "%s * :%s", buf, capbuf);
p = capbuf;
buflen = mlen;
memset(capbuf, 0, sizeof(capbuf));
}
=======
multiline_item_ret = send_multiline_item(source_p, "%s%s%s",
entry->cap,
data != NULL ? "=" : "",
data != NULL ? data : "");
>>>>>>> .merge_file_J3fUTs
if (multiline_item_ret == MULTILINE_FAILURE)
return;

View file

@ -416,12 +416,6 @@ static struct InfoStruct info_table[] = {
"Minimum delay between less intensive commands",
INFO_DECIMAL(&ConfigFileEntry.pace_wait_simple),
},
{
"listfake_wait",
OUTPUT_DECIMAL,
&ConfigFileEntry.listfake_wait,
"Time until real list command can be used"
},
{
"ping_cookie",
"Require ping cookies to connect",

View file

@ -156,37 +156,7 @@ m_list(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p
last_used = rb_current_time();
}
<<<<<<< .merge_file_PyqEuU
/* Disable LIST for a configured timespan after connect and send configured fake
* channels instead.
* Exempts: Opers, identifed users and users with spambot_exempt flag
*/
if (((source_p->localClient->firsttime + ConfigFileEntry.listfake_wait) > rb_current_time())
&& !IsOper(source_p) && !IsExemptSpambot(source_p) &&
!(source_p->user != NULL && !EmptyString(source_p->user->suser)))
{
struct fakechannel_entry *fakechannel;
struct DictionaryIter iter;
sendto_one(source_p, form_str(RPL_LISTSTART), me.name, source_p->name);
DICTIONARY_FOREACH(fakechannel, &iter, fakechannel_dict)
{
sendto_one(source_p, form_str(RPL_LIST), me.name, source_p->name,
"",
fakechannel->name,
(rand() % fakechannel->users_max + fakechannel->users_min),
fakechannel->topic);
}
sendto_one(source_p, form_str(RPL_LISTEND), me.name, source_p->name);
return 0;
}
return mo_list(client_p, source_p, parc, parv);
=======
mo_list(msgbuf_p, client_p, source_p, parc, parv);
>>>>>>> .merge_file_yv6CiZ
}
/* mo_list()

View file

@ -40,15 +40,11 @@
#include "reject.h"
#include "hash.h"
#include "cache.h"
<<<<<<< .merge_file_Kl8bB5
#include "sslproc.h"
=======
#include "rb_radixtree.h"
#include "sslproc.h"
static const char rehash_desc[] =
"Provides the REHASH command to reload configuration and other files";
>>>>>>> .merge_file_4WlQOU
static void mo_rehash(struct MsgBuf *, struct Client *, struct Client *, int, const char **);
static void me_rehash(struct MsgBuf *, struct Client *, struct Client *, int, const char **);
@ -106,22 +102,6 @@ rehash_ssld(struct Client *source_p)
restart_ssld();
}
static void
rehash_ssld(struct Client *source_p)
{
if (!IsOperAdmin(source_p))
{
sendto_one(source_p, form_str(ERR_NOPRIVS),
me.name, source_p->name, "admin");
return;
}
sendto_realops_snomask(SNO_GENERAL, L_ALL, "%s is restarting ssld",
get_oper_name(source_p));
restart_ssld();
}
static void
rehash_motd(struct Client *source_p)
{
@ -370,12 +350,7 @@ do_rehash(struct Client *source_p, const char *type)
remote_rehash_oper_p = source_p;
ilog(L_MAIN, "REHASH From %s[%s]", get_oper_name(source_p),
source_p->sockhost);
<<<<<<< .merge_file_Kl8bB5
rehash(0);
rehash_ulimit();
=======
rehash(false);
>>>>>>> .merge_file_4WlQOU
remote_rehash_oper_p = NULL;
}
}
@ -399,25 +374,13 @@ mo_rehash(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *sourc
}
if (parc > 2)
{
type = parv[1];
target_server = parv[2];
}
type = parv[1], target_server = parv[2];
else if (parc > 1 && (strchr(parv[1], '.') || strchr(parv[1], '?') || strchr(parv[1], '*')))
{
type = NULL;
target_server = parv[1];
}
type = NULL, target_server = parv[1];
else if (parc > 1)
{
type = parv[1];
target_server = NULL;
}
type = parv[1], target_server = NULL;
else
{
type = NULL;
target_server = NULL;
}
type = NULL, target_server = NULL;
if (target_server != NULL)
{

View file

@ -127,8 +127,4 @@ do_restart(struct Client *source_p, const char *servername)
sprintf(buf, "Server RESTART by %s", get_client_name(source_p, HIDE_IP));
restart(buf);
<<<<<<< .merge_file_Q6Imwg
/* UNREACHABLE */
=======
>>>>>>> .merge_file_lKBA0a
}

View file

@ -52,17 +52,8 @@ static void me_mechlist(struct MsgBuf *, struct Client *, struct Client *, int,
static void abort_sasl(void *);
static void abort_sasl_exit(void *);
<<<<<<< .merge_file_j0yiRK
static void advertise_sasl_cap(int);
static void advertise_sasl_new(struct Client *);
static void advertise_sasl_exit(void *);
static void advertise_sasl_config(void *);
static int sasl_agent_present = 0;
=======
static unsigned int CLICAP_SASL = 0;
static char mechlist_buf[BUFSIZE];
>>>>>>> .merge_file_hyMtKJ
struct Message authenticate_msgtab = {
"AUTHENTICATE", 0, 0, 0, 0,
@ -81,42 +72,6 @@ mapi_clist_av1 sasl_clist[] = {
&authenticate_msgtab, &sasl_msgtab, &mechlist_msgtab, NULL
};
mapi_hfn_list_av1 sasl_hfnlist[] = {
<<<<<<< .merge_file_j0yiRK
{ "new_local_user", (hookfn) abort_sasl },
{ "client_exit", (hookfn) abort_sasl_exit },
{ "new_remote_user", (hookfn) advertise_sasl_new },
{ "after_client_exit", (hookfn) advertise_sasl_exit },
{ "conf_read_end", (hookfn) advertise_sasl_config },
{ NULL, NULL }
};
static int
sasl_visible(void)
{
struct Client *agent_p = NULL;
if (ConfigFileEntry.sasl_service)
agent_p = find_named_client(ConfigFileEntry.sasl_service);
return agent_p != NULL && IsService(agent_p);
}
static int
_modinit(void)
{
sasl_agent_present = 0;
advertise_sasl_config(NULL);
return 0;
}
static void
_moddeinit(void)
{
advertise_sasl_cap(0);
}
DECLARE_MODULE_AV1(sasl, _modinit, _moddeinit, sasl_clist, NULL, sasl_hfnlist, "$Revision: 1409 $");
=======
{ "client_exit", abort_sasl_exit },
{ NULL, NULL }
};
@ -136,7 +91,6 @@ mapi_cap_list_av2 sasl_cap_list[] = {
{ MAPI_CAP_CLIENT, "sasl", &capdata_sasl, &CLICAP_SASL },
{ 0, NULL, NULL, NULL },
};
>>>>>>> .merge_file_hyMtKJ
static int
_modinit(void)
@ -176,12 +130,6 @@ m_authenticate(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *
return;
}
if (*parv[1] == ':' || strchr(parv[1], ' '))
{
exit_client(client_p, client_p, client_p, "Malformed AUTHENTICATE");
return 0;
}
saslserv_p = find_named_client(ConfigFileEntry.sasl_service);
if(saslserv_p == NULL || !IsService(saslserv_p))
{
@ -217,21 +165,13 @@ m_authenticate(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *
{
sendto_one(source_p, form_str(ERR_SASLABORTED), me.name, EmptyString(source_p->name) ? "*" : source_p->name);
source_p->localClient->sasl_out = 0;
<<<<<<< .merge_file_j0yiRK
return 0;
=======
return;
>>>>>>> .merge_file_hyMtKJ
}
sendto_one(saslserv_p, ":%s ENCAP %s SASL %s %s H %s %s %c",
me.id, saslserv_p->servptr->name, source_p->id, saslserv_p->id,
source_p->host, source_p->sockhost,
<<<<<<< .merge_file_j0yiRK
IsSSL(source_p) ? 'S' : 'P');
=======
IsSecure(source_p) ? 'S' : 'P');
>>>>>>> .merge_file_hyMtKJ
if (source_p->certfp != NULL)
sendto_one(saslserv_p, ":%s ENCAP %s SASL %s %s S %s %s",
@ -251,22 +191,13 @@ m_authenticate(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *
sendto_one(source_p, form_str(ERR_SASLABORTED), me.name, EmptyString(source_p->name) ? "*" : source_p->name);
sendto_one(agent_p, ":%s ENCAP %s SASL %s %s D A", me.id, agent_p->servptr->name, source_p->id, agent_p->id);
source_p->localClient->sasl_out = 0;
<<<<<<< .merge_file_j0yiRK
return 0;
=======
return;
>>>>>>> .merge_file_hyMtKJ
}
sendto_one(agent_p, ":%s ENCAP %s SASL %s %s C %s",
me.id, agent_p->servptr->name, source_p->id, agent_p->id,
parv[1]);
}
<<<<<<< .merge_file_j0yiRK
source_p->localClient->sasl_out++;
=======
>>>>>>> .merge_file_hyMtKJ
source_p->localClient->sasl_out++;
}
@ -302,10 +233,6 @@ me_sasl(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_
/* If SASL has been aborted, we only want to track authentication failures. */
in_progress = target_p->localClient->sasl_out != 0;
/* If SASL has been aborted, do nothing. */
if (target_p->localClient->sasl_out == 0)
return 0;
/* Reject if someone has already answered. */
if(*target_p->localClient->sasl_agent && strncmp(parv[1], target_p->localClient->sasl_agent, IDLEN))
return;
@ -407,48 +334,3 @@ abort_sasl_exit(void *data_)
if (data->target->localClient)
abort_sasl(data->target);
}
<<<<<<< .merge_file_j0yiRK
static void
advertise_sasl_cap(int available)
{
if (sasl_agent_present != available) {
if (available) {
sendto_local_clients_with_capability(CLICAP_CAP_NOTIFY, ":%s CAP * NEW :sasl", me.name);
} else {
sendto_local_clients_with_capability(CLICAP_CAP_NOTIFY, ":%s CAP * DEL :sasl", me.name);
}
sasl_agent_present = available;
}
}
static void
advertise_sasl_new(struct Client *client_p)
{
if (!ConfigFileEntry.sasl_service)
return;
if (irccmp(client_p->name, ConfigFileEntry.sasl_service))
return;
advertise_sasl_cap(IsService(client_p));
}
static void
advertise_sasl_exit(void *ignored)
{
if (!ConfigFileEntry.sasl_service)
return;
if (sasl_agent_present) {
advertise_sasl_cap(sasl_visible());
}
}
static void
advertise_sasl_config(void *ignored)
{
advertise_sasl_cap(sasl_visible());
}
=======
>>>>>>> .merge_file_hyMtKJ

View file

@ -99,13 +99,9 @@ mr_starttls(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *sou
sendto_one_numeric(client_p, RPL_STARTTLS, form_str(RPL_STARTTLS));
send_queued(client_p);
<<<<<<< .merge_file_2ab79i
ctl = start_ssld_accept(client_p->localClient->F, F[1], client_p->localClient->connid);
=======
/* TODO: set localClient->ssl_callback and handle success/failure */
ctl = start_ssld_accept(client_p->localClient->F, F[1], connid_get(client_p));
>>>>>>> .merge_file_h35QVt
if (ctl != NULL)
{
client_p->localClient->F = F[0];
@ -113,11 +109,4 @@ mr_starttls(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *sou
SetSSL(client_p);
SetSecure(client_p);
}
<<<<<<< .merge_file_2ab79i
else
return 1;
return 0;
=======
>>>>>>> .merge_file_h35QVt
}

View file

@ -44,19 +44,12 @@
#include "hash.h"
#include "reject.h"
#include "whowas.h"
<<<<<<< .merge_file_voAp55
#include "sslproc.h"
#define Lformat "%s %u %u %u %u %u :%ld %ld %s"
#define Sformat ":%s %d %s %s %u %u %u %u %u :%ld %ld %s"
=======
#include "rb_radixtree.h"
#include "sslproc.h"
#include "s_assert.h"
static const char stats_desc[] =
"Provides the STATS command to inspect various server/network information";
>>>>>>> .merge_file_gExsVy
static void m_stats (struct MsgBuf *, struct Client *, struct Client *, int, const char **);
@ -79,15 +72,10 @@ mapi_hlist_av1 stats_hlist[] = {
DECLARE_MODULE_AV2(stats, NULL, NULL, stats_clist, stats_hlist, NULL, NULL, NULL, stats_desc);
<<<<<<< .merge_file_voAp55
static void stats_l_list(struct Client *s, const char *, int, int, rb_dlink_list *, char,
int (*check_fn)(struct Client *target_p));
=======
const char *Lformat = "%s %u %u %u %u %u :%u %u %s";
static void stats_l_list(struct Client *s, const char *, bool, bool, rb_dlink_list *, char,
bool (*check_fn)(struct Client *source_p, struct Client *target_p));
>>>>>>> .merge_file_gExsVy
static void stats_l_client(struct Client *source_p, struct Client *target_p,
char statchar);
@ -129,10 +117,7 @@ static void stats_operedup(struct Client *);
static void stats_ports(struct Client *);
static void stats_tresv(struct Client *);
static void stats_resv(struct Client *);
<<<<<<< .merge_file_voAp55
=======
static void stats_secure(struct Client *);
>>>>>>> .merge_file_gExsVy
static void stats_ssld(struct Client *);
static void stats_usage(struct Client *);
static void stats_tstats(struct Client *);
@ -159,58 +144,6 @@ static void stats_capability(struct Client *);
* C initalisers so we don't have to iterate anymore
* --Elizafox
*/
<<<<<<< .merge_file_voAp55
static struct StatsStruct stats_cmd_table[] = {
/* letter function need_oper need_admin */
{'a', stats_dns_servers, 1, 1, },
{'A', stats_dns_servers, 1, 1, },
{'b', stats_delay, 1, 1, },
{'B', stats_hash, 1, 1, },
{'c', stats_connect, 0, 0, },
{'C', stats_capability, 1, 0, },
{'d', stats_tdeny, 1, 0, },
{'D', stats_deny, 1, 0, },
{'e', stats_exempt, 1, 0, },
{'E', stats_events, 1, 1, },
{'f', stats_comm, 1, 1, },
{'F', stats_comm, 1, 1, },
{'g', stats_prop_klines, 1, 0, },
{'h', stats_hubleaf, 0, 0, },
{'H', stats_hubleaf, 0, 0, },
{'i', stats_auth, 0, 0, },
{'I', stats_auth, 0, 0, },
{'k', stats_tklines, 0, 0, },
{'K', stats_klines, 0, 0, },
{'l', NULL /* special */, 0, 0, },
{'L', NULL /* special */, 0, 0, },
{'m', stats_messages, 0, 0, },
{'M', stats_messages, 0, 0, },
{'n', stats_dnsbl, 0, 0, },
{'o', stats_oper, 0, 0, },
{'O', stats_privset, 1, 0, },
{'p', stats_operedup, 0, 0, },
{'P', stats_ports, 0, 0, },
{'q', stats_tresv, 1, 0, },
{'Q', stats_resv, 1, 0, },
{'r', stats_usage, 1, 0, },
{'R', stats_usage, 1, 0, },
{'s', stats_ssld, 1, 1, },
{'S', stats_ssld, 1, 1, },
{'t', stats_tstats, 1, 0, },
{'T', stats_tstats, 1, 0, },
{'u', stats_uptime, 0, 0, },
{'U', stats_shared, 1, 0, },
{'v', stats_servers, 0, 0, },
{'V', stats_servers, 0, 0, },
{'x', stats_tgecos, 1, 0, },
{'X', stats_gecos, 1, 0, },
{'y', stats_class, 0, 0, },
{'Y', stats_class, 0, 0, },
{'z', stats_memory, 1, 0, },
{'Z', stats_ziplinks, 1, 0, },
{'?', stats_servlinks, 0, 0, },
{(char) 0, (void (*)(struct Client *)) 0, 0, 0, }
=======
static struct stats_cmd stats_cmd_table[256] = {
/* letter handler admin priv */
['a'] = HANDLER_NORM(stats_dns_servers, true, NULL),
@ -256,7 +189,6 @@ static struct stats_cmd stats_cmd_table[256] = {
['Y'] = HANDLER_NORM(stats_class, false, NULL),
['z'] = HANDLER_NORM(stats_memory, false, "oper:general"),
['?'] = HANDLER_NORM(stats_servlinks, false, NULL),
>>>>>>> .merge_file_gExsVy
};
/*
@ -989,24 +921,6 @@ stats_ssld(struct Client *source_p)
ssld_foreach_info(stats_ssld_foreach, source_p);
}
static void
stats_ssld_foreach(void *data, pid_t pid, int cli_count, enum ssld_status status)
{
struct Client *source_p = data;
sendto_one_numeric(source_p, RPL_STATSDEBUG,
"S :%u %c %u",
pid,
status == SSLD_DEAD ? 'D' : (status == SSLD_SHUTDOWN ? 'S' : 'A'),
cli_count);
}
static void
stats_ssld(struct Client *source_p)
{
ssld_foreach_info(stats_ssld_foreach, source_p);
}
static void
stats_usage (struct Client *source_p)
{
@ -1485,6 +1399,7 @@ stats_memory (struct Client *source_p)
static void
stats_servlinks (struct Client *source_p)
{
static char Sformat[] = ":%s %d %s %s %u %u %u %u %u :%u %u %s";
long uptime, sendK, receiveK;
struct Client *target_p;
rb_dlink_node *ptr;
@ -1519,13 +1434,8 @@ stats_servlinks (struct Client *source_p)
(int) target_p->localClient->receiveK,
rb_current_time() - target_p->localClient->firsttime,
(rb_current_time() > target_p->localClient->lasttime) ?
<<<<<<< .merge_file_voAp55
(rb_current_time() - target_p->localClient->lasttime) : (long) 0,
IsOper (source_p) ? show_capabilities (target_p) : "TS");
=======
(rb_current_time() - target_p->localClient->lasttime) : 0,
IsOperGeneral (source_p) ? show_capabilities (target_p) : "TS");
>>>>>>> .merge_file_gExsVy
}
sendto_one_numeric(source_p, RPL_STATSDEBUG,
@ -1705,13 +1615,8 @@ stats_l_client(struct Client *source_p, struct Client *target_p,
(int) target_p->localClient->receiveK,
rb_current_time() - target_p->localClient->firsttime,
(rb_current_time() > target_p->localClient->lasttime) ?
<<<<<<< .merge_file_voAp55
(rb_current_time() - target_p->localClient->lasttime) : (long) 0,
IsOper(source_p) ? show_capabilities(target_p) : "-");
=======
(rb_current_time() - target_p->localClient->lasttime) : 0,
IsOperGeneral(source_p) ? show_capabilities(target_p) : "-");
>>>>>>> .merge_file_gExsVy
}
else
@ -1736,13 +1641,8 @@ stats_l_client(struct Client *source_p, struct Client *target_p,
hdata_showidle.approved ? (int) target_p->localClient->receiveM : 0,
hdata_showidle.approved ? (int) target_p->localClient->receiveK : 0,
rb_current_time() - target_p->localClient->firsttime,
<<<<<<< .merge_file_voAp55
(rb_current_time() > target_p->localClient->lasttime) ?
(rb_current_time() - target_p->localClient->lasttime) : (long) 0,
=======
(rb_current_time() > target_p->localClient->lasttime) && hdata_showidle.approved ?
(rb_current_time() - target_p->localClient->lasttime) : 0,
>>>>>>> .merge_file_gExsVy
"-");
}
}

View file

@ -300,16 +300,6 @@ single_whois(struct Client *source_p, struct Client *target_p, int operspy)
{
s = ConfigFileEntry.servicestring;
}
<<<<<<< .merge_file_zYZ429
if(MyClient(target_p) && !EmptyString(target_p->localClient->opername) && IsOper(target_p) && IsOper(source_p))
{
char obuf[512];
rb_snprintf(obuf, sizeof(obuf), "is opered as %s, privset %s",
target_p->localClient->opername, target_p->localClient->privset->name);
sendto_one_numeric(source_p, RPL_WHOISSPECIAL, form_str(RPL_WHOISSPECIAL),
target_p->name, obuf);
=======
if (!EmptyString(target_p->user->opername) && IsOper(target_p))
{
if (target_p == source_p || HasPrivilege(source_p, "oper:privs"))
@ -335,7 +325,6 @@ single_whois(struct Client *source_p, struct Client *target_p, int operspy)
{
sendto_one_numeric(source_p, RPL_WHOISOPERATOR, form_str(RPL_WHOISOPERATOR),
target_p->name, s);
>>>>>>> .merge_file_AQS60w
}
if(IsSecureClient(target_p))

View file

@ -1,106 +0,0 @@
#!/bin/sh
# static_modules.c.SH: Generates our static module list
# $Id: static_modules.c.SH 6 2005-09-10 01:02:21Z nenolod $
#
SYMS=`for x in $*; do basename $x .o|sed -es/^m_//; done`
cat > static_modules.c <<EOF
/*
* This file is automatically generated: do not modify
* ircd-ratbox: A slightly useful ircd
*
* Copyright (C) 2003 Aaron Sethman <androsyn@ratbox.org>
* Copyright (C) 2003-2005 ircd-ratbox development team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 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 "hash.h"
#include "logger.h"
EOF
for x in $SYMS; do
echo extern struct mapi_header_av1 "$x"_mheader\;
done >> static_modules.c
echo static const struct mapi_header_av1 *mapi_headers[] = { >> static_modules.c
for x in $SYMS; do
echo \&"$x"_mheader,
done >> static_modules.c
echo NULL }\; >> static_modules.c
cat >> static_modules.c <<EOF
void load_static_modules(void)
{
int x;
int *mapi_version;
for(x = 0; mapi_headers[x] != NULL; x++)
{
mapi_version = (int *)mapi_headers[x];
if(MAPI_MAGIC(*mapi_version) != MAPI_MAGIC_HDR)
{
ilog(L_MAIN, "Error: linked in module without a MAPI header..giving up");
exit(70);
}
switch(MAPI_VERSION(*mapi_version))
{
case 1:
{
struct mapi_mheader_av1 *mheader = (struct mapi_mheader_av1*)mapi_version;
if (mheader->mapi_register && (mheader->mapi_register() == -1))
{
ilog(L_MAIN, "Error: linked in module failed loading..giving up");
exit(70);
}
if(mheader->mapi_command_list)
{
struct Message **m;
for(m = mheader->mapi_command_list; *m; ++m)
mod_add_cmd(*m);
}
if(mheader->mapi_hook_list)
{
mapi_hlist_av1 *m;
for(m = mheader->mapi_hook_list; m->hapi_name; ++m)
*m->hapi_id = register_hook(m->hapi_name);
}
if(mheader->mapi_hfn_list)
{
mapi_hfn_list_av1 *m;
for(m = mheader->mapi_hfn_list; m->hapi_name; ++m)
add_hook(m->hapi_name, m->fn);
}
break;
}
default:
{
ilog(L_MAIN, "Error: Unknown MAPI version in linked in module..giving up");
exit(70);
}
}
}
}
EOF

View file

@ -1,12 +0,0 @@
diff --git a/src/bandbi.c b/src/bandbi.c
index 96f65b4..0a85a92 100644
--- a/src/bandbi.c
+++ b/src/bandbi.c
@@ -82,7 +82,6 @@ start_bandb(void)
const char *suffix = "";
#endif
- rb_setenv("BANDB_DBPATH", PKGLOCALSTATEDIR "/ban.db", 1);
if(bandb_path == NULL)
{
rb_snprintf(fullpath, sizeof(fullpath), "%s/bandb%s", PKGLIBEXECDIR, suffix);

View file

@ -1,454 +0,0 @@
/* src/bandbi.c
* An interface to the ban db.
*
* Copyright (C) 2006 Lee Hardy <lee -at- leeh.co.uk>
* Copyright (C) 2006 ircd-ratbox development team
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1.Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2.Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3.The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* $Id$
*/
#include "stdinc.h"
#include "ratbox_lib.h"
#include "client.h"
#include "s_conf.h"
#include "logger.h"
#include "match.h"
#include "bandbi.h"
#include "parse.h"
#include "channel.h"
#include "hostmask.h"
#include "hash.h"
#include "s_newconf.h"
#include "reject.h"
#include "send.h"
#include "ircd.h"
#include "msg.h" /* XXX: MAXPARA */
#include "operhash.h"
static char bandb_add_letter[LAST_BANDB_TYPE] = {
'K', 'D', 'X', 'R'
};
rb_dlink_list bandb_pending;
static rb_helper *bandb_helper;
static int start_bandb(void);
static void bandb_parse(rb_helper *);
static void bandb_restart_cb(rb_helper *);
static char *bandb_path;
void
init_bandb(void)
{
if(start_bandb())
{
ilog(L_MAIN, "Unable to start bandb helper: %s", strerror(errno));
exit(0);
}
}
static int
start_bandb(void)
{
char fullpath[PATH_MAX + 1];
#ifdef _WIN32
const char *suffix = ".exe";
#else
const char *suffix = "";
#endif
rb_setenv("BANDB_DBPATH", PKGLOCALSTATEDIR "/ban.db", 1);
if(bandb_path == NULL)
{
rb_snprintf(fullpath, sizeof(fullpath), "%s/bandb%s", PKGLIBEXECDIR, suffix);
if(access(fullpath, X_OK) == -1)
{
rb_snprintf(fullpath, sizeof(fullpath), "%s/bin/bandb%s",
ConfigFileEntry.dpath, suffix);
if(access(fullpath, X_OK) == -1)
{
ilog(L_MAIN,
"Unable to execute bandb%s in %s or %s/bin",
suffix, PKGLIBEXECDIR, ConfigFileEntry.dpath);
return 0;
}
}
bandb_path = rb_strdup(fullpath);
}
bandb_helper = rb_helper_start("bandb", bandb_path, bandb_parse, bandb_restart_cb);
if(bandb_helper == NULL)
{
ilog(L_MAIN, "Unable to start bandb: %s", strerror(errno));
sendto_realops_snomask(SNO_GENERAL, L_ALL, "Unable to start bandb: %s",
strerror(errno));
return 1;
}
rb_helper_run(bandb_helper);
return 0;
}
void
bandb_add(bandb_type type, struct Client *source_p, const char *mask1,
const char *mask2, const char *reason, const char *oper_reason, int perm)
{
if(bandb_helper == NULL)
return;
static char buf[BUFSIZE];
rb_snprintf(buf, sizeof(buf), "%c %s ", bandb_add_letter[type], mask1);
if(!EmptyString(mask2))
rb_snprintf_append(buf, sizeof(buf), "%s ", mask2);
rb_snprintf_append(buf, sizeof(buf), "%s %ld %d :%s",
get_oper_name(source_p), (long int)rb_current_time(), perm, reason);
if(!EmptyString(oper_reason))
rb_snprintf_append(buf, sizeof(buf), "|%s", oper_reason);
rb_helper_write(bandb_helper, "%s", buf);
}
static char bandb_del_letter[LAST_BANDB_TYPE] = {
'k', 'd', 'x', 'r'
};
void
bandb_del(bandb_type type, const char *mask1, const char *mask2)
{
if(bandb_helper == NULL)
return;
static char buf[BUFSIZE];
buf[0] = '\0';
rb_snprintf_append(buf, sizeof(buf), "%c %s", bandb_del_letter[type], mask1);
if(!EmptyString(mask2))
rb_snprintf_append(buf, sizeof(buf), " %s", mask2);
rb_helper_write(bandb_helper, "%s", buf);
}
static void
bandb_handle_ban(char *parv[], int parc)
{
struct ConfItem *aconf;
char *p;
int para = 1;
aconf = make_conf();
aconf->port = 0;
if(parv[0][0] == 'K')
aconf->user = rb_strdup(parv[para++]);
aconf->host = rb_strdup(parv[para++]);
aconf->info.oper = operhash_add(parv[para++]);
switch (parv[0][0])
{
case 'K':
aconf->status = CONF_KILL;
break;
case 'D':
aconf->status = CONF_DLINE;
break;
case 'X':
aconf->status = CONF_XLINE;
break;
case 'R':
if(IsChannelName(aconf->host))
aconf->status = CONF_RESV_CHANNEL;
else
aconf->status = CONF_RESV_NICK;
break;
}
if((p = strchr(parv[para], '|')))
{
*p++ = '\0';
aconf->spasswd = rb_strdup(p);
}
aconf->passwd = rb_strdup(parv[para]);
rb_dlinkAddAlloc(aconf, &bandb_pending);
}
static int
bandb_check_kline(struct ConfItem *aconf)
{
struct rb_sockaddr_storage daddr;
struct ConfItem *kconf = NULL;
int aftype;
const char *p;
aftype = parse_netmask(aconf->host, &daddr, NULL);
if(aftype != HM_HOST)
{
#ifdef RB_IPV6
if(aftype == HM_IPV6)
aftype = AF_INET6;
else
#endif
aftype = AF_INET;
kconf = find_conf_by_address(aconf->host, NULL, NULL, (struct sockaddr *)&daddr,
CONF_KILL, aftype, aconf->user, NULL);
}
else
kconf = find_conf_by_address(aconf->host, NULL, NULL, NULL, CONF_KILL, 0, aconf->user, NULL);
if(kconf && ((kconf->flags & CONF_FLAGS_TEMPORARY) == 0))
return 0;
for(p = aconf->user; *p; p++)
{
if(!IsUserChar(*p) && !IsKWildChar(*p))
return 0;
}
for(p = aconf->host; *p; p++)
{
if(!IsHostChar(*p) && !IsKWildChar(*p))
return 0;
}
return 1;
}
static int
bandb_check_dline(struct ConfItem *aconf)
{
struct rb_sockaddr_storage daddr;
int bits;
if(!parse_netmask(aconf->host, &daddr, &bits))
return 0;
return 1;
}
static int
bandb_check_xline(struct ConfItem *aconf)
{
struct ConfItem *xconf;
/* XXX perhaps convert spaces to \s? -- jilles */
xconf = find_xline_mask(aconf->host);
if(xconf != NULL && !(xconf->flags & CONF_FLAGS_TEMPORARY))
return 0;
return 1;
}
static int
bandb_check_resv_channel(struct ConfItem *aconf)
{
const char *p;
if(hash_find_resv(aconf->host) || strlen(aconf->host) > CHANNELLEN)
return 0;
for(p = aconf->host; *p; p++)
{
if(!IsChanChar(*p))
return 0;
}
return 1;
}
static int
bandb_check_resv_nick(struct ConfItem *aconf)
{
if(!clean_resv_nick(aconf->host))
return 0;
if(find_nick_resv(aconf->host))
return 0;
return 1;
}
static void
bandb_handle_clear(void)
{
rb_dlink_node *ptr, *next_ptr;
RB_DLINK_FOREACH_SAFE(ptr, next_ptr, bandb_pending.head)
{
free_conf(ptr->data);
rb_dlinkDestroy(ptr, &bandb_pending);
}
}
static void
bandb_handle_finish(void)
{
struct ConfItem *aconf;
rb_dlink_node *ptr, *next_ptr;
clear_out_address_conf_bans();
clear_s_newconf_bans();
RB_DLINK_FOREACH_SAFE(ptr, next_ptr, bandb_pending.head)
{
aconf = ptr->data;
rb_dlinkDestroy(ptr, &bandb_pending);
switch (aconf->status)
{
case CONF_KILL:
if(bandb_check_kline(aconf))
add_conf_by_address(aconf->host, CONF_KILL, aconf->user, NULL, aconf);
else
free_conf(aconf);
break;
case CONF_DLINE:
if(bandb_check_dline(aconf))
add_conf_by_address(aconf->host, CONF_DLINE, aconf->user, NULL, aconf);
else
free_conf(aconf);
break;
case CONF_XLINE:
if(bandb_check_xline(aconf))
rb_dlinkAddAlloc(aconf, &xline_conf_list);
else
free_conf(aconf);
break;
case CONF_RESV_CHANNEL:
if(bandb_check_resv_channel(aconf))
add_to_resv_hash(aconf->host, aconf);
else
free_conf(aconf);
break;
case CONF_RESV_NICK:
if(bandb_check_resv_nick(aconf))
rb_dlinkAddAlloc(aconf, &resv_conf_list);
else
free_conf(aconf);
break;
}
}
check_banned_lines();
}
static void __attribute__((noreturn))
bandb_handle_failure(rb_helper *helper, char **parv, int parc)
{
if(server_state_foreground)
fprintf(stderr, "bandb - bandb failure: %s\n", parv[1]);
ilog(L_MAIN, "bandb - bandb failure: %s", parv[1]);
sendto_realops_snomask(SNO_GENERAL, L_ALL, "bandb - bandb failure: %s", parv[1]);
exit(1);
}
static void
bandb_parse(rb_helper *helper)
{
static char buf[READBUF_SIZE];
char *parv[MAXPARA + 1];
int len, parc;
while((len = rb_helper_read(helper, buf, sizeof(buf))))
{
parc = rb_string_to_array(buf, parv, MAXPARA);
if(parc < 1)
continue;
switch (parv[0][0])
{
case '!':
bandb_handle_failure(helper, parv, parc);
/* UNREACHABLE */
case 'K':
case 'D':
case 'X':
case 'R':
bandb_handle_ban(parv, parc);
break;
case 'C':
bandb_handle_clear();
break;
case 'F':
bandb_handle_finish();
break;
}
}
}
void
bandb_rehash_bans(void)
{
if(bandb_helper != NULL)
rb_helper_write(bandb_helper, "L");
}
static void
bandb_restart_cb(rb_helper *helper)
{
ilog(L_MAIN, "bandb - bandb_restart_cb called, bandb helper died?");
sendto_realops_snomask(SNO_GENERAL, L_ALL,
"bandb - bandb_restart_cb called, bandb helper died?");
if(helper != NULL)
{
rb_helper_close(helper);
bandb_helper = NULL;
}
start_bandb();
return;
}

View file

@ -1,396 +0,0 @@
/*
* ircd-ratbox: an advanced Internet Relay Chat Daemon(ircd).
* cache.c - code for caching files
*
* Copyright (C) 2003 Lee Hardy <lee@leeh.co.uk>
* Copyright (C) 2003-2005 ircd-ratbox development team
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1.Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2.Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3.The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* $Id: cache.c 25119 2008-03-13 16:57:05Z androsyn $
*/
#include "stdinc.h"
#include "ircd_defs.h"
#include "common.h"
#include "s_conf.h"
#include "client.h"
#include "hash.h"
#include "cache.h"
#include "irc_dictionary.h"
#include "numeric.h"
#include "send.h"
struct cachefile *user_motd = NULL;
struct cachefile *oper_motd = NULL;
struct cacheline *emptyline = NULL;
rb_dlink_list links_cache_list;
char user_motd_changed[MAX_DATE_STRING];
struct Dictionary *help_dict_oper = NULL;
struct Dictionary *help_dict_user = NULL;
/* init_cache()
*
* inputs -
* outputs -
* side effects - inits the file/line cache blockheaps, loads motds
*/
void
init_cache(void)
{
/* allocate the emptyline */
emptyline = rb_malloc(sizeof(struct cacheline));
emptyline->data = rb_strdup(" ");
user_motd_changed[0] = '\0';
user_motd = cache_file(MPATH, "ircd.motd", 0);
oper_motd = cache_file(OPATH, "opers.motd", 0);
memset(&links_cache_list, 0, sizeof(links_cache_list));
help_dict_oper = irc_dictionary_create(strcasecmp);
help_dict_user = irc_dictionary_create(strcasecmp);
}
/*
* removes tabs from src, replaces with 8 spaces, and returns the length
* of the new string. if the new string would be greater than destlen,
* it is truncated to destlen - 1
*/
static size_t
untabify(char *dest, const char *src, size_t destlen)
{
size_t x = 0, i;
const char *s = src;
char *d = dest;
while(*s != '\0' && x < destlen - 1)
{
if(*s == '\t')
{
for(i = 0; i < 8 && x < destlen - 1; i++, x++, d++)
*d = ' ';
s++;
} else
{
*d++ = *s++;
x++;
}
}
*d = '\0';
return x;
}
/* cache_file()
*
* inputs - file to cache, files "shortname", flags to set
* outputs - pointer to file cached, else NULL
* side effects -
*/
struct cachefile *
cache_file(const char *filename, const char *shortname, int flags)
{
FILE *in;
struct cachefile *cacheptr;
struct cacheline *lineptr;
char line[BUFSIZE];
char *p;
if((in = fopen(filename, "r")) == NULL)
return NULL;
cacheptr = rb_malloc(sizeof(struct cachefile));
rb_strlcpy(cacheptr->name, shortname, sizeof(cacheptr->name));
cacheptr->flags = flags;
/* cache the file... */
while(fgets(line, sizeof(line), in) != NULL)
{
if((p = strpbrk(line, "\r\n")) != NULL)
*p = '\0';
if(!EmptyString(line))
{
char untabline[BUFSIZE];
lineptr = rb_malloc(sizeof(struct cacheline));
untabify(untabline, line, sizeof(untabline));
lineptr->data = rb_strdup(untabline);
rb_dlinkAddTail(lineptr, &lineptr->linenode, &cacheptr->contents);
}
else
rb_dlinkAddTailAlloc(emptyline, &cacheptr->contents);
}
if (0 == rb_dlink_list_length(&cacheptr->contents))
{
/* No contents. Don't cache it after all. */
rb_free(cacheptr);
cacheptr = NULL;
}
fclose(in);
return cacheptr;
}
void
cache_links(void *unused)
{
struct Client *target_p;
rb_dlink_node *ptr;
rb_dlink_node *next_ptr;
char *links_line;
RB_DLINK_FOREACH_SAFE(ptr, next_ptr, links_cache_list.head)
{
rb_free(ptr->data);
rb_free_rb_dlink_node(ptr);
}
links_cache_list.head = links_cache_list.tail = NULL;
links_cache_list.length = 0;
RB_DLINK_FOREACH(ptr, global_serv_list.head)
{
target_p = ptr->data;
/* skip ourselves (done in /links) and hidden servers */
if(IsMe(target_p) ||
(IsHidden(target_p) && !ConfigServerHide.disable_hidden))
continue;
/* if the below is ever modified, change LINKSLINELEN */
links_line = rb_malloc(LINKSLINELEN);
rb_snprintf(links_line, LINKSLINELEN, "%s %s :1 %s",
target_p->name, me.name,
target_p->info[0] ? target_p->info :
"(Unknown Location)");
rb_dlinkAddTailAlloc(links_line, &links_cache_list);
}
}
/* free_cachefile()
*
* inputs - cachefile to free
* outputs -
* side effects - cachefile and its data is free'd
*/
void
free_cachefile(struct cachefile *cacheptr)
{
rb_dlink_node *ptr;
rb_dlink_node *next_ptr;
if(cacheptr == NULL)
return;
RB_DLINK_FOREACH_SAFE(ptr, next_ptr, cacheptr->contents.head)
{
if(ptr->data != emptyline)
{
struct cacheline *line = ptr->data;
rb_free(line->data);
rb_free(line);
}
else
{
rb_free_rb_dlink_node(ptr);
}
}
rb_free(cacheptr);
}
/* load_help()
*
* inputs -
* outputs -
* side effects - old help cache deleted
* - contents of help directories are loaded.
*/
void
load_help(void)
{
DIR *helpfile_dir = NULL;
struct dirent *ldirent= NULL;
char filename[PATH_MAX];
struct cachefile *cacheptr;
struct DictionaryIter iter;
#if defined(S_ISLNK) && defined(HAVE_LSTAT)
struct stat sb;
#endif
DICTIONARY_FOREACH(cacheptr, &iter, help_dict_oper)
{
irc_dictionary_delete(help_dict_oper, cacheptr->name);
free_cachefile(cacheptr);
}
DICTIONARY_FOREACH(cacheptr, &iter, help_dict_user)
{
irc_dictionary_delete(help_dict_user, cacheptr->name);
free_cachefile(cacheptr);
}
helpfile_dir = opendir(HPATH);
if(helpfile_dir == NULL)
return;
while((ldirent = readdir(helpfile_dir)) != NULL)
{
if(ldirent->d_name[0] == '.')
continue;
rb_snprintf(filename, sizeof(filename), "%s/%s", HPATH, ldirent->d_name);
cacheptr = cache_file(filename, ldirent->d_name, HELP_OPER);
irc_dictionary_add(help_dict_oper, cacheptr->name, cacheptr);
}
closedir(helpfile_dir);
helpfile_dir = opendir(UHPATH);
if(helpfile_dir == NULL)
return;
while((ldirent = readdir(helpfile_dir)) != NULL)
{
if(ldirent->d_name[0] == '.')
continue;
rb_snprintf(filename, sizeof(filename), "%s/%s", UHPATH, ldirent->d_name);
#if defined(S_ISLNK) && defined(HAVE_LSTAT)
if(lstat(filename, &sb) < 0)
continue;
/* ok, if its a symlink, we work on the presumption if an
* oper help exists of that name, its a symlink to that --fl
*/
if(S_ISLNK(sb.st_mode))
{
cacheptr = irc_dictionary_retrieve(help_dict_oper, ldirent->d_name);
if(cacheptr != NULL)
{
cacheptr->flags |= HELP_USER;
continue;
}
}
#endif
cacheptr = cache_file(filename, ldirent->d_name, HELP_USER);
irc_dictionary_add(help_dict_user, cacheptr->name, cacheptr);
}
closedir(helpfile_dir);
}
/* send_user_motd()
*
* inputs - client to send motd to
* outputs - client is sent motd if exists, else ERR_NOMOTD
* side effects -
*/
void
send_user_motd(struct Client *source_p)
{
struct cacheline *lineptr;
rb_dlink_node *ptr;
const char *myname = get_id(&me, source_p);
const char *nick = get_id(source_p, source_p);
if(user_motd == NULL || rb_dlink_list_length(&user_motd->contents) == 0)
{
sendto_one(source_p, form_str(ERR_NOMOTD), myname, nick);
return;
}
sendto_one(source_p, form_str(RPL_MOTDSTART), myname, nick, me.name);
RB_DLINK_FOREACH(ptr, user_motd->contents.head)
{
lineptr = ptr->data;
sendto_one(source_p, form_str(RPL_MOTD), myname, nick, lineptr->data);
}
sendto_one(source_p, form_str(RPL_ENDOFMOTD), myname, nick);
}
void
cache_user_motd(void)
{
struct stat sb;
struct tm *local_tm;
if(stat(MPATH, &sb) == 0)
{
local_tm = localtime(&sb.st_mtime);
if(local_tm != NULL)
{
rb_snprintf(user_motd_changed, sizeof(user_motd_changed),
"%d/%d/%d %d:%d",
local_tm->tm_mday, local_tm->tm_mon + 1,
1900 + local_tm->tm_year, local_tm->tm_hour,
local_tm->tm_min);
}
}
free_cachefile(user_motd);
user_motd = cache_file(MPATH, "ircd.motd", 0);
}
/* send_oper_motd()
*
* inputs - client to send motd to
* outputs - client is sent oper motd if exists
* side effects -
*/
void
send_oper_motd(struct Client *source_p)
{
struct cacheline *lineptr;
rb_dlink_node *ptr;
if(oper_motd == NULL || rb_dlink_list_length(&oper_motd->contents) == 0)
return;
sendto_one(source_p, form_str(RPL_OMOTDSTART),
me.name, source_p->name);
RB_DLINK_FOREACH(ptr, oper_motd->contents.head)
{
lineptr = ptr->data;
sendto_one(source_p, form_str(RPL_OMOTD),
me.name, source_p->name, lineptr->data);
}
sendto_one(source_p, form_str(RPL_ENDOFOMOTD),
me.name, source_p->name);
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,142 +0,0 @@
/*
* ircd-ratbox: A slightly useful ircd.
* getopt.c: Uses getopt to fetch the command line options.
*
* Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
* Copyright (C) 1996-2002 Hybrid Development Team
* Copyright (C) 2002-2005 ircd-ratbox development team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 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
*
* $Id: getopt.c 6 2005-09-10 01:02:21Z nenolod $
*/
#include "stdinc.h"
#include "ircd_getopt.h"
# define OPTCHAR '-'
static void usage(char *name) __attribute__((noreturn));
void
parseargs(int *argc, char ***argv, struct lgetopt *opts)
{
int i;
char *progname = (*argv)[0];
/* loop through each argument */
for (;;)
{
int found = 0;
(*argc)--;
(*argv)++;
if(*argc < 1)
{
return;
}
/* check if it *is* an arg.. */
if((*argv)[0][0] != OPTCHAR)
{
return;
}
(*argv)[0]++;
/* search through our argument list, and see if it matches */
for (i = 0; opts[i].opt; i++)
{
if(!strcmp(opts[i].opt, (*argv)[0]))
{
/* found our argument */
found = 1;
switch (opts[i].argtype)
{
case YESNO:
*((int *) opts[i].argloc) = 1;
break;
case INTEGER:
if(*argc < 2)
{
fprintf(stderr,
"Error: option '%c%s' requires an argument\n",
OPTCHAR, opts[i].opt);
usage((*argv)[0]);
}
*((int *) opts[i].argloc) = atoi((*argv)[1]);
(*argc)--;
(*argv)++;
break;
case STRING:
if(*argc < 2)
{
fprintf(stderr,
"error: option '%c%s' requires an argument\n",
OPTCHAR, opts[i].opt);
usage(progname);
}
*((char **) opts[i].argloc) =
malloc(strlen((*argv)[1]) + 1);
strcpy(*((char **) opts[i].argloc), (*argv)[1]);
(*argc)--;
(*argv)++;
break;
case USAGE:
usage(progname);
/*NOTREACHED*/ default:
fprintf(stderr,
"Error: internal error in parseargs() at %s:%d\n",
__FILE__, __LINE__);
exit(EXIT_FAILURE);
}
}
}
if(!found)
{
fprintf(stderr, "error: unknown argument '%c%s'\n", OPTCHAR, (*argv)[0]);
usage(progname);
}
}
}
static void
usage(char *name)
{
int i = 0;
fprintf(stderr, "Usage: %s [options]\n", name);
fprintf(stderr, "Where valid options are:\n");
for (i = 0; myopts[i].opt; i++)
{
fprintf(stderr, "\t%c%-10s %-20s%s\n", OPTCHAR,
myopts[i].opt, (myopts[i].argtype == YESNO
|| myopts[i].argtype ==
USAGE) ? "" : myopts[i].argtype ==
INTEGER ? "<number>" : "<string>", myopts[i].desc);
}
exit(EXIT_FAILURE);
}

View file

@ -1,805 +0,0 @@
/*
* ircd-ratbox: A slightly useful ircd.
* hash.c: Maintains hashtables.
*
* Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
* Copyright (C) 1996-2002 Hybrid Development Team
* Copyright (C) 2002-2005 ircd-ratbox development team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 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
*
* $Id: hash.c 3177 2007-02-01 00:19:14Z jilles $
*/
#include "stdinc.h"
#include "ircd_defs.h"
#include "s_conf.h"
#include "channel.h"
#include "client.h"
#include "common.h"
#include "hash.h"
#include "match.h"
#include "ircd.h"
#include "numeric.h"
#include "send.h"
#include "msg.h"
#include "cache.h"
#include "s_newconf.h"
#include "s_assert.h"
#define ZCONNID_MAX 64 /* i doubt we'll have this many ziplinks ;) */
#define hash_cli_connid(x) (x % CLI_CONNID_MAX)
#define hash_zconnid(x) (x % ZCONNID_MAX)
static rb_dlink_list clientbyconnidTable[CLI_CONNID_MAX];
static rb_dlink_list clientbyzconnidTable[ZCONNID_MAX];
rb_dlink_list *clientTable;
rb_dlink_list *channelTable;
rb_dlink_list *idTable;
rb_dlink_list *resvTable;
rb_dlink_list *hostTable;
/*
* look in whowas.c for the missing ...[WW_MAX]; entry
*/
/*
* Hashing.
*
* The server uses a chained hash table to provide quick and efficient
* hash table maintenance (providing the hash function works evenly over
* the input range). The hash table is thus not susceptible to problems
* of filling all the buckets or the need to rehash.
* It is expected that the hash table would look something like this
* during use:
* +-----+ +-----+ +-----+ +-----+
* ---| 224 |----| 225 |----| 226 |---| 227 |---
* +-----+ +-----+ +-----+ +-----+
* | | |
* +-----+ +-----+ +-----+
* | A | | C | | D |
* +-----+ +-----+ +-----+
* |
* +-----+
* | B |
* +-----+
*
* A - GOPbot, B - chang, C - hanuaway, D - *.mu.OZ.AU
*
* The order shown above is just one instant of the server.
*
*
* The hash functions currently used are based Fowler/Noll/Vo hashes
* which work amazingly well and have a extremely low collision rate
* For more info see http://www.isthe.com/chongo/tech/comp/fnv/index.html
*
*
*/
/* init_hash()
*
* clears the various hashtables
*/
void
init_hash(void)
{
clientTable = rb_malloc(sizeof(rb_dlink_list) * U_MAX);
idTable = rb_malloc(sizeof(rb_dlink_list) * U_MAX);
channelTable = rb_malloc(sizeof(rb_dlink_list) * CH_MAX);
hostTable = rb_malloc(sizeof(rb_dlink_list) * HOST_MAX);
resvTable = rb_malloc(sizeof(rb_dlink_list) * R_MAX);
}
#ifndef RICER_HASHING
u_int32_t
fnv_hash_upper(const unsigned char *s, int bits)
{
u_int32_t h = FNV1_32_INIT;
while (*s)
{
h ^= ToUpper(*s++);
h += (h<<1) + (h<<4) + (h<<7) + (h << 8) + (h << 24);
}
if (bits < 32)
h = ((h >> bits) ^ h) & ((1<<bits)-1);
return h;
}
u_int32_t
fnv_hash(const unsigned char *s, int bits)
{
u_int32_t h = FNV1_32_INIT;
while (*s)
{
h ^= *s++;
h += (h<<1) + (h<<4) + (h<<7) + (h << 8) + (h << 24);
}
if (bits < 32)
h = ((h >> bits) ^ h) & ((1<<bits)-1);
return h;
}
u_int32_t
fnv_hash_len(const unsigned char *s, int bits, int len)
{
u_int32_t h = FNV1_32_INIT;
const unsigned char *x = s + len;
while (*s && s < x)
{
h ^= *s++;
h += (h<<1) + (h<<4) + (h<<7) + (h << 8) + (h << 24);
}
if (bits < 32)
h = ((h >> bits) ^ h) & ((1<<bits)-1);
return h;
}
u_int32_t
fnv_hash_upper_len(const unsigned char *s, int bits, int len)
{
u_int32_t h = FNV1_32_INIT;
const unsigned char *x = s + len;
while (*s && s < x)
{
h ^= ToUpper(*s++);
h += (h<<1) + (h<<4) + (h<<7) + (h << 8) + (h << 24);
}
if (bits < 32)
h = ((h >> bits) ^ h) & ((1<<bits)-1);
return h;
}
#endif
/* hash_nick()
*
* hashes a nickname, first converting to lowercase
*/
static u_int32_t
hash_nick(const char *name)
{
return fnv_hash_upper((const unsigned char *) name, U_MAX_BITS);
}
/* hash_id()
*
* hashes an id, case is kept
*/
static u_int32_t
hash_id(const char *name)
{
return fnv_hash((const unsigned char *) name, U_MAX_BITS);
}
/* hash_channel()
*
* hashes a channel name, based on first 30 chars only for efficiency
*/
static u_int32_t
hash_channel(const char *name)
{
return fnv_hash_upper_len((const unsigned char *) name, CH_MAX_BITS, 30);
}
/* hash_hostname()
*
* hashes a hostname, based on first 30 chars only, as thats likely to
* be more dynamic than rest.
*/
static u_int32_t
hash_hostname(const char *name)
{
return fnv_hash_upper_len((const unsigned char *) name, HOST_MAX_BITS, 30);
}
/* hash_resv()
*
* hashes a resv channel name, based on first 30 chars only
*/
static u_int32_t
hash_resv(const char *name)
{
return fnv_hash_upper_len((const unsigned char *) name, R_MAX_BITS, 30);
}
/* add_to_id_hash()
*
* adds an entry to the id hash table
*/
void
add_to_id_hash(const char *name, struct Client *client_p)
{
unsigned int hashv;
if(EmptyString(name) || (client_p == NULL))
return;
hashv = hash_id(name);
rb_dlinkAddAlloc(client_p, &idTable[hashv]);
}
/* add_to_client_hash()
*
* adds an entry (client/server) to the client hash table
*/
void
add_to_client_hash(const char *name, struct Client *client_p)
{
unsigned int hashv;
s_assert(name != NULL);
s_assert(client_p != NULL);
if(EmptyString(name) || (client_p == NULL))
return;
hashv = hash_nick(name);
rb_dlinkAddAlloc(client_p, &clientTable[hashv]);
}
/* add_to_hostname_hash()
*
* adds a client entry to the hostname hash table
*/
void
add_to_hostname_hash(const char *hostname, struct Client *client_p)
{
unsigned int hashv;
s_assert(hostname != NULL);
s_assert(client_p != NULL);
if(EmptyString(hostname) || (client_p == NULL))
return;
hashv = hash_hostname(hostname);
rb_dlinkAddAlloc(client_p, &hostTable[hashv]);
}
/* add_to_resv_hash()
*
* adds a resv channel entry to the resv hash table
*/
void
add_to_resv_hash(const char *name, struct ConfItem *aconf)
{
unsigned int hashv;
s_assert(!EmptyString(name));
s_assert(aconf != NULL);
if(EmptyString(name) || aconf == NULL)
return;
hashv = hash_resv(name);
rb_dlinkAddAlloc(aconf, &resvTable[hashv]);
}
/* del_from_id_hash()
*
* removes an id from the id hash table
*/
void
del_from_id_hash(const char *id, struct Client *client_p)
{
unsigned int hashv;
s_assert(id != NULL);
s_assert(client_p != NULL);
if(EmptyString(id) || client_p == NULL)
return;
hashv = hash_id(id);
rb_dlinkFindDestroy(client_p, &idTable[hashv]);
}
/* del_from_client_hash()
*
* removes a client/server from the client hash table
*/
void
del_from_client_hash(const char *name, struct Client *client_p)
{
unsigned int hashv;
/* no s_asserts, this can happen when removing a client that
* is unregistered.
*/
if(EmptyString(name) || client_p == NULL)
return;
hashv = hash_nick(name);
rb_dlinkFindDestroy(client_p, &clientTable[hashv]);
}
/* del_from_channel_hash()
*
* removes a channel from the channel hash table
*/
void
del_from_channel_hash(const char *name, struct Channel *chptr)
{
unsigned int hashv;
s_assert(name != NULL);
s_assert(chptr != NULL);
if(EmptyString(name) || chptr == NULL)
return;
hashv = hash_channel(name);
rb_dlinkFindDestroy(chptr, &channelTable[hashv]);
}
/* del_from_hostname_hash()
*
* removes a client entry from the hostname hash table
*/
void
del_from_hostname_hash(const char *hostname, struct Client *client_p)
{
unsigned int hashv;
if(hostname == NULL || client_p == NULL)
return;
hashv = hash_hostname(hostname);
rb_dlinkFindDestroy(client_p, &hostTable[hashv]);
}
/* del_from_resv_hash()
*
* removes a resv entry from the resv hash table
*/
void
del_from_resv_hash(const char *name, struct ConfItem *aconf)
{
unsigned int hashv;
s_assert(name != NULL);
s_assert(aconf != NULL);
if(EmptyString(name) || aconf == NULL)
return;
hashv = hash_resv(name);
rb_dlinkFindDestroy(aconf, &resvTable[hashv]);
}
/* find_id()
*
* finds a client entry from the id hash table
*/
struct Client *
find_id(const char *name)
{
struct Client *target_p;
rb_dlink_node *ptr;
unsigned int hashv;
if(EmptyString(name))
return NULL;
hashv = hash_id(name);
RB_DLINK_FOREACH(ptr, idTable[hashv].head)
{
target_p = ptr->data;
if(strcmp(name, target_p->id) == 0)
return target_p;
}
return NULL;
}
/* find_client()
*
* finds a client/server entry from the client hash table
*/
struct Client *
find_client(const char *name)
{
struct Client *target_p;
rb_dlink_node *ptr;
unsigned int hashv;
s_assert(name != NULL);
if(EmptyString(name))
return NULL;
/* hunting for an id, not a nick */
if(IsDigit(*name))
return (find_id(name));
hashv = hash_nick(name);
RB_DLINK_FOREACH(ptr, clientTable[hashv].head)
{
target_p = ptr->data;
if(irccmp(name, target_p->name) == 0)
return target_p;
}
return NULL;
}
/* find_named_client()
*
* finds a client/server entry from the client hash table
*/
struct Client *
find_named_client(const char *name)
{
struct Client *target_p;
rb_dlink_node *ptr;
unsigned int hashv;
s_assert(name != NULL);
if(EmptyString(name))
return NULL;
hashv = hash_nick(name);
RB_DLINK_FOREACH(ptr, clientTable[hashv].head)
{
target_p = ptr->data;
if(irccmp(name, target_p->name) == 0)
return target_p;
}
return NULL;
}
/* find_server()
*
* finds a server from the client hash table
*/
struct Client *
find_server(struct Client *source_p, const char *name)
{
struct Client *target_p;
rb_dlink_node *ptr;
unsigned int hashv;
if(EmptyString(name))
return NULL;
if((source_p == NULL || !MyClient(source_p)) &&
IsDigit(*name) && strlen(name) == 3)
{
target_p = find_id(name);
return(target_p);
}
hashv = hash_nick(name);
RB_DLINK_FOREACH(ptr, clientTable[hashv].head)
{
target_p = ptr->data;
if((IsServer(target_p) || IsMe(target_p)) &&
irccmp(name, target_p->name) == 0)
return target_p;
}
return NULL;
}
/* find_hostname()
*
* finds a hostname rb_dlink list from the hostname hash table.
* we return the full rb_dlink list, because you can have multiple
* entries with the same hostname
*/
rb_dlink_node *
find_hostname(const char *hostname)
{
unsigned int hashv;
if(EmptyString(hostname))
return NULL;
hashv = hash_hostname(hostname);
return hostTable[hashv].head;
}
/* find_channel()
*
* finds a channel from the channel hash table
*/
struct Channel *
find_channel(const char *name)
{
struct Channel *chptr;
rb_dlink_node *ptr;
unsigned int hashv;
s_assert(name != NULL);
if(EmptyString(name))
return NULL;
hashv = hash_channel(name);
RB_DLINK_FOREACH(ptr, channelTable[hashv].head)
{
chptr = ptr->data;
if(irccmp(name, chptr->chname) == 0)
return chptr;
}
return NULL;
}
/*
* get_or_create_channel
* inputs - client pointer
* - channel name
* - pointer to int flag whether channel was newly created or not
* output - returns channel block or NULL if illegal name
* - also modifies *isnew
*
* Get Channel block for chname (and allocate a new channel
* block, if it didn't exist before).
*/
struct Channel *
get_or_create_channel(struct Client *client_p, const char *chname, int *isnew)
{
struct Channel *chptr;
rb_dlink_node *ptr;
unsigned int hashv;
int len;
const char *s = chname;
if(EmptyString(s))
return NULL;
len = strlen(s);
if(len > CHANNELLEN)
{
char *t;
if(IsServer(client_p))
{
sendto_realops_snomask(SNO_DEBUG, L_ALL,
"*** Long channel name from %s (%d > %d): %s",
client_p->name, len, CHANNELLEN, s);
}
len = CHANNELLEN;
t = LOCAL_COPY(s);
*(t + CHANNELLEN) = '\0';
s = t;
}
hashv = hash_channel(s);
RB_DLINK_FOREACH(ptr, channelTable[hashv].head)
{
chptr = ptr->data;
if(irccmp(s, chptr->chname) == 0)
{
if(isnew != NULL)
*isnew = 0;
return chptr;
}
}
if(isnew != NULL)
*isnew = 1;
chptr = allocate_channel(s);
rb_dlinkAdd(chptr, &chptr->node, &global_channel_list);
chptr->channelts = rb_current_time(); /* doesn't hurt to set it here */
rb_dlinkAddAlloc(chptr, &channelTable[hashv]);
return chptr;
}
/* hash_find_resv()
*
* hunts for a resv entry in the resv hash table
*/
struct ConfItem *
hash_find_resv(const char *name)
{
struct ConfItem *aconf;
rb_dlink_node *ptr;
unsigned int hashv;
s_assert(name != NULL);
if(EmptyString(name))
return NULL;
hashv = hash_resv(name);
RB_DLINK_FOREACH(ptr, resvTable[hashv].head)
{
aconf = ptr->data;
if(!irccmp(name, aconf->host))
{
aconf->port++;
return aconf;
}
}
return NULL;
}
void
clear_resv_hash(void)
{
struct ConfItem *aconf;
rb_dlink_node *ptr;
rb_dlink_node *next_ptr;
int i;
HASH_WALK_SAFE(i, R_MAX, ptr, next_ptr, resvTable)
{
aconf = ptr->data;
/* skip temp resvs */
if(aconf->hold)
continue;
free_conf(ptr->data);
rb_dlinkDestroy(ptr, &resvTable[i]);
}
HASH_WALK_END
}
void
add_to_zconnid_hash(struct Client *client_p)
{
unsigned int hashv;
hashv = hash_zconnid(client_p->localClient->zconnid);
rb_dlinkAddAlloc(client_p, &clientbyzconnidTable[hashv]);
}
void
del_from_zconnid_hash(struct Client *client_p)
{
unsigned int hashv;
hashv = hash_zconnid(client_p->localClient->zconnid);
rb_dlinkFindDestroy(client_p, &clientbyzconnidTable[hashv]);
}
void
add_to_cli_connid_hash(struct Client *client_p)
{
unsigned int hashv;
hashv = hash_cli_connid(client_p->localClient->connid);
rb_dlinkAddAlloc(client_p, &clientbyconnidTable[hashv]);
}
void
del_from_cli_connid_hash(struct Client *client_p)
{
unsigned int hashv;
hashv = hash_cli_connid(client_p->localClient->connid);
rb_dlinkFindDestroy(client_p, &clientbyconnidTable[hashv]);
}
struct Client *
find_cli_connid_hash(int connid)
{
struct Client *target_p;
rb_dlink_node *ptr;
unsigned int hashv;
hashv = hash_cli_connid(connid);
RB_DLINK_FOREACH(ptr, clientbyconnidTable[hashv].head)
{
target_p = ptr->data;
if(target_p->localClient->connid == (uint32_t)connid)
return target_p;
}
hashv = hash_zconnid(connid);
RB_DLINK_FOREACH(ptr, clientbyzconnidTable[hashv].head)
{
target_p = ptr->data;
if(target_p->localClient->zconnid == (uint32_t)connid)
return target_p;
}
return NULL;
}
static void
output_hash(struct Client *source_p, const char *name, int length, int *counts, unsigned long deepest)
{
unsigned long total = 0;
int i;
char buf[128];
sendto_one_numeric(source_p, RPL_STATSDEBUG,
"B :%s Hash Statistics", name);
snprintf(buf, sizeof buf, "%.3f%%",
(float) ((counts[0]*100) / (float) length));
sendto_one_numeric(source_p, RPL_STATSDEBUG,
"B :Size: %d Empty: %d (%s)",
length, counts[0], buf);
for(i = 1; i < 11; i++)
{
total += (counts[i] * i);
}
/* dont want to divide by 0! --fl */
if(counts[0] != length)
{
snprintf(buf, sizeof buf, "%.3f/%.3f",
(float) (total / (length - counts[0])),
(float) (total / length));
sendto_one_numeric(source_p, RPL_STATSDEBUG,
"B :Average depth: %s Highest depth: %lu",
buf, deepest);
}
for(i = 0; i < 11; i++)
{
sendto_one_numeric(source_p, RPL_STATSDEBUG,
"B :Nodes with %d entries: %d",
i, counts[i]);
}
}
static void
count_hash(struct Client *source_p, rb_dlink_list *table, int length, const char *name)
{
int counts[11];
unsigned long deepest = 0;
int i;
memset(counts, 0, sizeof(counts));
for(i = 0; i < length; i++)
{
if(rb_dlink_list_length(&table[i]) >= 10)
counts[10]++;
else
counts[rb_dlink_list_length(&table[i])]++;
if(rb_dlink_list_length(&table[i]) > deepest)
deepest = rb_dlink_list_length(&table[i]);
}
output_hash(source_p, name, length, counts, deepest);
}
void
hash_stats(struct Client *source_p)
{
count_hash(source_p, channelTable, CH_MAX, "Channel");
sendto_one_numeric(source_p, RPL_STATSDEBUG, "B :--");
count_hash(source_p, clientTable, U_MAX, "Client");
sendto_one_numeric(source_p, RPL_STATSDEBUG, "B :--");
count_hash(source_p, idTable, U_MAX, "ID");
sendto_one_numeric(source_p, RPL_STATSDEBUG, "B :--");
count_hash(source_p, hostTable, HOST_MAX, "Hostname");
sendto_one_numeric(source_p, RPL_STATSDEBUG, "B :--");
count_hash(source_p, clientbyconnidTable, CLI_CONNID_MAX, "Client by connection id");
}

View file

@ -1,225 +0,0 @@
/*
* ircd-ratbox: an advanced Internet Relay Chat Daemon(ircd).
* hook.c - code for dealing with the hook system
*
* This code is basically a slow leaking array. Events are simply just a
* position in this array. When hooks are added, events will be created if
* they dont exist - this means modules with hooks can be loaded in any
* order, and events are preserved through module reloads.
*
* Copyright (C) 2004-2005 Lee Hardy <lee -at- leeh.co.uk>
* Copyright (C) 2004-2005 ircd-ratbox development team
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1.Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2.Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3.The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* $Id: hook.c 712 2006-02-06 04:42:14Z gxti $
*/
#include "stdinc.h"
#include "hook.h"
#include "match.h"
hook *hooks;
#define HOOK_INCREMENT 1000
int num_hooks = 0;
int last_hook = 0;
int max_hooks = HOOK_INCREMENT;
#ifdef USE_IODEBUG_HOOKS
int h_iosend_id;
int h_iorecv_id;
int h_iorecvctrl_id;
#endif
int h_burst_client;
int h_burst_channel;
int h_burst_finished;
int h_server_introduced;
int h_server_eob;
int h_client_exit;
int h_after_client_exit;
int h_umode_changed;
int h_new_local_user;
int h_new_remote_user;
int h_introduce_client;
int h_can_kick;
int h_privmsg_user;
int h_privmsg_channel;
int h_conf_read_start;
int h_conf_read_end;
void
init_hook(void)
{
hooks = rb_malloc(sizeof(hook) * HOOK_INCREMENT);
#ifdef USE_IODEBUG_HOOKS
h_iosend_id = register_hook("iosend");
h_iorecv_id = register_hook("iorecv");
h_iorecvctrl_id = register_hook("iorecvctrl");
#endif
h_burst_client = register_hook("burst_client");
h_burst_channel = register_hook("burst_channel");
h_burst_finished = register_hook("burst_finished");
h_server_introduced = register_hook("server_introduced");
h_server_eob = register_hook("server_eob");
h_client_exit = register_hook("client_exit");
h_after_client_exit = register_hook("after_client_exit");
h_umode_changed = register_hook("umode_changed");
h_new_local_user = register_hook("new_local_user");
h_new_remote_user = register_hook("new_remote_user");
h_introduce_client = register_hook("introduce_client");
h_can_kick = register_hook("can_kick");
h_privmsg_user = register_hook("privmsg_user");
h_privmsg_channel = register_hook("privmsg_channel");
h_conf_read_start = register_hook("conf_read_start");
h_conf_read_end = register_hook("conf_read_end");
}
/* grow_hooktable()
* Enlarges the hook table by HOOK_INCREMENT
*/
static void
grow_hooktable(void)
{
hook *newhooks;
newhooks = rb_malloc(sizeof(hook) * (max_hooks + HOOK_INCREMENT));
memcpy(newhooks, hooks, sizeof(hook) * num_hooks);
rb_free(hooks);
hooks = newhooks;
max_hooks += HOOK_INCREMENT;
}
/* find_freehookslot()
* Finds the next free slot in the hook table, given by an entry with
* h->name being NULL.
*/
static int
find_freehookslot(void)
{
int i;
if((num_hooks + 1) > max_hooks)
grow_hooktable();
for(i = 0; i < max_hooks; i++)
{
if(!hooks[i].name)
return i;
}
/* shouldnt ever get here */
return(max_hooks - 1);
}
/* find_hook()
* Finds an event in the hook table.
*/
static int
find_hook(const char *name)
{
int i;
for(i = 0; i < max_hooks; i++)
{
if(!hooks[i].name)
continue;
if(!irccmp(hooks[i].name, name))
return i;
}
return -1;
}
/* register_hook()
* Finds an events position in the hook table, creating it if it doesnt
* exist.
*/
int
register_hook(const char *name)
{
int i;
if((i = find_hook(name)) < 0)
{
i = find_freehookslot();
hooks[i].name = rb_strdup(name);
num_hooks++;
}
return i;
}
/* add_hook()
* Adds a hook to an event in the hook table, creating event first if
* needed.
*/
void
add_hook(const char *name, hookfn fn)
{
int i;
i = register_hook(name);
rb_dlinkAddAlloc(fn, &hooks[i].hooks);
}
/* remove_hook()
* Removes a hook from an event in the hook table.
*/
void
remove_hook(const char *name, hookfn fn)
{
int i;
if((i = find_hook(name)) < 0)
return;
rb_dlinkFindDestroy(fn, &hooks[i].hooks);
}
/* call_hook()
* Calls functions from a given event in the hook table.
*/
void
call_hook(int id, void *arg)
{
hookfn fn;
rb_dlink_node *ptr;
/* The ID we were passed is the position in the hook table of this
* hook
*/
RB_DLINK_FOREACH(ptr, hooks[id].hooks.head)
{
fn = ptr->data;
fn(arg);
}
}

View file

@ -1,774 +0,0 @@
/*
* charybdis: an advanced internet relay chat daemon (ircd).
* hostmask.c: Code to efficiently find IP & hostmask based configs.
*
* Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
* Copyright (C) 1996-2002 Hybrid Development Team
* Copyright (C) 2002-2005 ircd-ratbox development team
* Copyright (C) 2005-2008 charybdis development team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 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
*
* $Id: hostmask.c 2757 2006-11-10 22:58:15Z jilles $
*/
#include "stdinc.h"
#include "ircd_defs.h"
#include "s_conf.h"
#include "hostmask.h"
#include "numeric.h"
#include "send.h"
#include "match.h"
#include "ipv4_from_ipv6.h"
#ifdef RB_IPV6
static unsigned long hash_ipv6(struct sockaddr *, int);
#endif
static unsigned long hash_ipv4(struct sockaddr *, int);
/* int parse_netmask(const char *, struct rb_sockaddr_storage *, int *);
* Input: A hostmask, or an IPV4/6 address.
* Output: An integer describing whether it is an IPV4, IPV6 address or a
* hostmask, an address(if it is an IP mask),
* a bitlength(if it is IP mask).
* Side effects: None
*/
int
parse_netmask(const char *text, struct rb_sockaddr_storage *naddr, int *nb)
{
char *ip = LOCAL_COPY(text);
char *ptr;
struct rb_sockaddr_storage *addr, xaddr;
int *b, xb;
if(nb == NULL)
b = &xb;
else
b = nb;
if(naddr == NULL)
addr = &xaddr;
else
addr = naddr;
if(strpbrk(ip, "*?") != NULL)
{
return HM_HOST;
}
#ifdef RB_IPV6
if(strchr(ip, ':'))
{
if((ptr = strchr(ip, '/')))
{
*ptr = '\0';
ptr++;
*b = atoi(ptr);
if(*b > 128)
*b = 128;
else if(*b < 0)
return HM_HOST;
} else
*b = 128;
if(rb_inet_pton_sock(ip, (struct sockaddr *)addr) > 0)
return HM_IPV6;
else
return HM_HOST;
} else
#endif
if(strchr(text, '.'))
{
if((ptr = strchr(ip, '/')))
{
*ptr = '\0';
ptr++;
*b = atoi(ptr);
if(*b > 32)
*b = 32;
else if(*b < 0)
return HM_HOST;
} else
*b = 32;
if(rb_inet_pton_sock(ip, (struct sockaddr *)addr) > 0)
return HM_IPV4;
else
return HM_HOST;
}
return HM_HOST;
}
/* Hashtable stuff...now external as its used in m_stats.c */
struct AddressRec *atable[ATABLE_SIZE];
void
init_host_hash(void)
{
memset(&atable, 0, sizeof(atable));
}
/* unsigned long hash_ipv4(struct rb_sockaddr_storage*)
* Input: An IP address.
* Output: A hash value of the IP address.
* Side effects: None
*/
static unsigned long
hash_ipv4(struct sockaddr *saddr, int bits)
{
struct sockaddr_in *addr = (struct sockaddr_in *)(void *)saddr;
if(bits != 0)
{
unsigned long av = ntohl(addr->sin_addr.s_addr) & ~((1 << (32 - bits)) - 1);
return (av ^ (av >> 12) ^ (av >> 24)) & (ATABLE_SIZE - 1);
}
return 0;
}
/* unsigned long hash_ipv6(struct rb_sockaddr_storage*)
* Input: An IP address.
* Output: A hash value of the IP address.
* Side effects: None
*/
#ifdef RB_IPV6
static unsigned long
hash_ipv6(struct sockaddr *saddr, int bits)
{
struct sockaddr_in6 *addr = (struct sockaddr_in6 *)(void *)saddr;
unsigned long v = 0, n;
for (n = 0; n < 16; n++)
{
if(bits >= 8)
{
v ^= addr->sin6_addr.s6_addr[n];
bits -= 8;
}
else if(bits)
{
v ^= addr->sin6_addr.s6_addr[n] & ~((1 << (8 - bits)) - 1);
return v & (ATABLE_SIZE - 1);
}
else
return v & (ATABLE_SIZE - 1);
}
return v & (ATABLE_SIZE - 1);
}
#endif
/* int hash_text(const char *start)
* Input: The start of the text to hash.
* Output: The hash of the string between 1 and (TH_MAX-1)
* Side-effects: None.
*/
static int
hash_text(const char *start)
{
const char *p = start;
unsigned long h = 0;
while(*p)
{
h = (h << 4) - (h + (unsigned char) ToLower(*p++));
}
return (h & (ATABLE_SIZE - 1));
}
/* unsigned long get_hash_mask(const char *)
* Input: The text to hash.
* Output: The hash of the string right of the first '.' past the last
* wildcard in the string.
* Side-effects: None.
*/
static unsigned long
get_mask_hash(const char *text)
{
const char *hp = "", *p;
for (p = text + strlen(text) - 1; p >= text; p--)
if(*p == '*' || *p == '?')
return hash_text(hp);
else if(*p == '.')
hp = p + 1;
return hash_text(text);
}
/* struct ConfItem* find_conf_by_address(const char*, struct rb_sockaddr_storage*,
* int type, int fam, const char *username)
* Input: The hostname, the address, the type of mask to find, the address
* family, the username.
* Output: The matching value with the highest precedence.
* Side-effects: None
* Note: Setting bit 0 of the type means that the username is ignored.
*/
struct ConfItem *
find_conf_by_address(const char *name, const char *sockhost,
const char *orighost,
struct sockaddr *addr, int type, int fam,
const char *username, const char *auth_user)
{
unsigned long hprecv = 0;
struct ConfItem *hprec = NULL;
struct AddressRec *arec;
int b;
if(username == NULL)
username = "";
if(addr)
{
/* Check for IPV6 matches... */
#ifdef RB_IPV6
if(fam == AF_INET6)
{
for (b = 128; b >= 0; b -= 16)
{
for (arec = atable[hash_ipv6(addr, b)]; arec; arec = arec->next)
if(arec->type == (type & ~0x1) &&
arec->masktype == HM_IPV6 &&
comp_with_mask_sock(addr, (struct sockaddr *)&arec->Mask.ipa.addr,
arec->Mask.ipa.bits) &&
(type & 0x1 || match(arec-> username, username)) &&
(type != CONF_CLIENT || !arec->auth_user ||
(auth_user && match(arec->auth_user, auth_user))) &&
arec->precedence > hprecv)
{
hprecv = arec->precedence;
hprec = arec->aconf;
}
}
}
else
#endif
if(fam == AF_INET)
{
for (b = 32; b >= 0; b -= 8)
{
for (arec = atable[hash_ipv4(addr, b)]; arec; arec = arec->next)
if(arec->type == (type & ~0x1) &&
arec->masktype == HM_IPV4 &&
comp_with_mask_sock(addr, (struct sockaddr *)&arec->Mask.ipa.addr,
arec->Mask.ipa.bits) &&
(type & 0x1 || match(arec->username, username)) &&
(type != CONF_CLIENT || !arec->auth_user ||
(auth_user && match(arec->auth_user, auth_user))) &&
arec->precedence > hprecv)
{
hprecv = arec->precedence;
hprec = arec->aconf;
}
}
}
}
if(orighost != NULL)
{
const char *p;
for (p = orighost; p != NULL;)
{
for (arec = atable[hash_text(p)]; arec; arec = arec->next)
if((arec->type == (type & ~0x1)) &&
(arec->masktype == HM_HOST) &&
arec->precedence > hprecv &&
match(arec->Mask.hostname, orighost) &&
(type != CONF_CLIENT || !arec->auth_user ||
(auth_user && match(arec->auth_user, auth_user))) &&
(type & 0x1 || match(arec->username, username)))
{
hprecv = arec->precedence;
hprec = arec->aconf;
}
p = strchr(p, '.');
if(p != NULL)
p++;
else
break;
}
for (arec = atable[0]; arec; arec = arec->next)
{
if(arec->type == (type & ~0x1) &&
arec->masktype == HM_HOST &&
arec->precedence > hprecv &&
(match(arec->Mask.hostname, orighost) ||
(sockhost && match(arec->Mask.hostname, sockhost))) &&
(type != CONF_CLIENT || !arec->auth_user ||
(auth_user && match(arec->auth_user, auth_user))) &&
(type & 0x1 || match(arec->username, username)))
{
hprecv = arec->precedence;
hprec = arec->aconf;
}
}
}
if(name != NULL)
{
const char *p;
/* And yes - we have to check p after strchr and p after increment for
* NULL -kre */
for (p = name; p != NULL;)
{
for (arec = atable[hash_text(p)]; arec; arec = arec->next)
if((arec->type == (type & ~0x1)) &&
(arec->masktype == HM_HOST) &&
arec->precedence > hprecv &&
match(arec->Mask.hostname, name) &&
(type != CONF_CLIENT || !arec->auth_user ||
(auth_user && match(arec->auth_user, auth_user))) &&
(type & 0x1 || match(arec->username, username)))
{
hprecv = arec->precedence;
hprec = arec->aconf;
}
p = strchr(p, '.');
if(p != NULL)
p++;
else
break;
}
for (arec = atable[0]; arec; arec = arec->next)
{
if(arec->type == (type & ~0x1) &&
arec->masktype == HM_HOST &&
arec->precedence > hprecv &&
(match(arec->Mask.hostname, name) ||
(sockhost && match(arec->Mask.hostname, sockhost))) &&
(type != CONF_CLIENT || !arec->auth_user ||
(auth_user && match(arec->auth_user, auth_user))) &&
(type & 0x1 || match(arec->username, username)))
{
hprecv = arec->precedence;
hprec = arec->aconf;
}
}
}
return hprec;
}
/* struct ConfItem* find_address_conf(const char*, const char*,
* struct rb_sockaddr_storage*, int);
* Input: The hostname, username, address, address family.
* Output: The applicable ConfItem.
* Side-effects: None
*/
struct ConfItem *
find_address_conf(const char *host, const char *sockhost, const char *user,
const char *notildeuser, struct sockaddr *ip, int aftype, char *auth_user)
{
struct ConfItem *iconf, *kconf;
const char *vuser;
#ifdef RB_IPV6
struct sockaddr_in ip4;
#endif
/* Find the best I-line... If none, return NULL -A1kmm */
if(!(iconf = find_conf_by_address(host, sockhost, NULL, ip, CONF_CLIENT, aftype, user, auth_user)))
return NULL;
/* Find what their visible username will be.
* Note that the username without tilde may contain one char more.
* -- jilles */
vuser = IsNoTilde(iconf) ? notildeuser : user;
/* If they are exempt from K-lines, return the best I-line. -A1kmm */
if(IsConfExemptKline(iconf))
return iconf;
/* Find the best K-line... -A1kmm */
kconf = find_conf_by_address(host, sockhost, NULL, ip, CONF_KILL, aftype, user, NULL);
/* If they are K-lined, return the K-line */
if(kconf)
return kconf;
/* if theres a spoof, check it against klines.. */
if(IsConfDoSpoofIp(iconf))
{
char *p = strchr(iconf->info.name, '@');
/* note, we dont need to pass sockhost here, as its
* guaranteed to not match by whats above.. --anfl
*/
if(p)
{
*p = '\0';
kconf = find_conf_by_address(p+1, NULL, NULL, ip, CONF_KILL, aftype, iconf->info.name, NULL);
*p = '@';
}
else
kconf = find_conf_by_address(iconf->info.name, NULL, NULL, ip, CONF_KILL, aftype, vuser, NULL);
if(kconf)
return kconf;
}
/* if no_tilde, check the username without tilde against klines too
* -- jilles */
if(user != vuser)
{
kconf = find_conf_by_address(host, sockhost, NULL, ip, CONF_KILL, aftype, vuser, NULL);
if(kconf)
return kconf;
}
#ifdef RB_IPV6
if(ip != NULL && ip->sa_family == AF_INET6 &&
ipv4_from_ipv6((const struct sockaddr_in6 *)(const void *)ip, &ip4))
{
kconf = find_conf_by_address(NULL, NULL, NULL, (struct sockaddr *)&ip4, CONF_KILL, AF_INET, vuser, NULL);
if(kconf)
return kconf;
}
#endif /* RB_IPV6 */
return iconf;
}
/* struct ConfItem* find_dline(struct rb_sockaddr_storage*, int)
* Input: An address, an address family.
* Output: The best matching D-line or exempt line.
* Side effects: None.
*/
struct ConfItem *
find_dline(struct sockaddr *addr, int aftype)
{
struct ConfItem *aconf;
#ifdef RB_IPV6
struct sockaddr_in addr2;
#endif
aconf = find_conf_by_address(NULL, NULL, NULL, addr, CONF_EXEMPTDLINE | 1, aftype, NULL, NULL);
if(aconf)
return aconf;
aconf = find_conf_by_address(NULL, NULL, NULL, addr, CONF_DLINE | 1, aftype, NULL, NULL);
if(aconf)
return aconf;
#ifdef RB_IPV6
if(addr->sa_family == AF_INET6 &&
ipv4_from_ipv6((const struct sockaddr_in6 *)(const void *)addr, &addr2))
{
aconf = find_conf_by_address(NULL, NULL, NULL, (struct sockaddr *)&addr2, CONF_DLINE | 1, AF_INET, NULL, NULL);
if(aconf)
return aconf;
}
#endif
return NULL;
}
/* void find_exact_conf_by_address(const char*, int, const char *)
* Input:
* Output: ConfItem if found
* Side-effects: None
*/
struct ConfItem *
find_exact_conf_by_address(const char *address, int type, const char *username)
{
int masktype, bits;
unsigned long hv;
struct AddressRec *arec;
struct rb_sockaddr_storage addr;
if(address == NULL)
address = "/NOMATCH!/";
masktype = parse_netmask(address, &addr, &bits);
#ifdef RB_IPV6
if(masktype == HM_IPV6)
{
/* We have to do this, since we do not re-hash for every bit -A1kmm. */
hv = hash_ipv6((struct sockaddr *)&addr, bits - bits % 16);
}
else
#endif
if(masktype == HM_IPV4)
{
/* We have to do this, since we do not re-hash for every bit -A1kmm. */
hv = hash_ipv4((struct sockaddr *)&addr, bits - bits % 8);
}
else
{
hv = get_mask_hash(address);
}
for (arec = atable[hv]; arec; arec = arec->next)
{
if (arec->type == type &&
arec->masktype == masktype &&
(arec->username == NULL || username == NULL ? arec->username == username : !irccmp(arec->username, username)))
{
if (masktype == HM_HOST)
{
if (!irccmp(arec->Mask.hostname, address))
return arec->aconf;
}
else
{
if (arec->Mask.ipa.bits == bits &&
comp_with_mask_sock((struct sockaddr *)&arec->Mask.ipa.addr, (struct sockaddr *)&addr, bits))
return arec->aconf;
}
}
}
return NULL;
}
/* void add_conf_by_address(const char*, int, const char *,
* struct ConfItem *aconf)
* Input:
* Output: None
* Side-effects: Adds this entry to the hash table.
*/
void
add_conf_by_address(const char *address, int type, const char *username, const char *auth_user, struct ConfItem *aconf)
{
static unsigned long prec_value = 0xFFFFFFFF;
int bits;
unsigned long hv;
struct AddressRec *arec;
if(address == NULL)
address = "/NOMATCH!/";
arec = rb_malloc(sizeof(struct AddressRec));
arec->masktype = parse_netmask(address, &arec->Mask.ipa.addr, &bits);
#ifdef RB_IPV6
if(arec->masktype == HM_IPV6)
{
arec->Mask.ipa.bits = bits;
/* We have to do this, since we do not re-hash for every bit -A1kmm. */
bits -= bits % 16;
arec->next = atable[(hv = hash_ipv6((struct sockaddr *)&arec->Mask.ipa.addr, bits))];
atable[hv] = arec;
}
else
#endif
if(arec->masktype == HM_IPV4)
{
arec->Mask.ipa.bits = bits;
/* We have to do this, since we do not re-hash for every bit -A1kmm. */
bits -= bits % 8;
arec->next = atable[(hv = hash_ipv4((struct sockaddr *)&arec->Mask.ipa.addr, bits))];
atable[hv] = arec;
}
else
{
arec->Mask.hostname = address;
arec->next = atable[(hv = get_mask_hash(address))];
atable[hv] = arec;
}
arec->username = username;
arec->auth_user = auth_user;
arec->aconf = aconf;
arec->precedence = prec_value--;
arec->type = type;
}
/* void delete_one_address(const char*, struct ConfItem*)
* Input: An address string, the associated ConfItem.
* Output: None
* Side effects: Deletes an address record. Frees the ConfItem if there
* is nothing referencing it, sets it as illegal otherwise.
*/
void
delete_one_address_conf(const char *address, struct ConfItem *aconf)
{
int masktype, bits;
unsigned long hv;
struct AddressRec *arec, *arecl = NULL;
struct rb_sockaddr_storage addr;
masktype = parse_netmask(address, &addr, &bits);
#ifdef RB_IPV6
if(masktype == HM_IPV6)
{
/* We have to do this, since we do not re-hash for every bit -A1kmm. */
bits -= bits % 16;
hv = hash_ipv6((struct sockaddr *)&addr, bits);
}
else
#endif
if(masktype == HM_IPV4)
{
/* We have to do this, since we do not re-hash for every bit -A1kmm. */
bits -= bits % 8;
hv = hash_ipv4((struct sockaddr *)&addr, bits);
}
else
hv = get_mask_hash(address);
for (arec = atable[hv]; arec; arec = arec->next)
{
if(arec->aconf == aconf)
{
if(arecl)
arecl->next = arec->next;
else
atable[hv] = arec->next;
aconf->status |= CONF_ILLEGAL;
if(!aconf->clients)
free_conf(aconf);
rb_free(arec);
return;
}
arecl = arec;
}
}
/* void clear_out_address_conf(void)
* Input: None
* Output: None
* Side effects: Clears out all address records in the hash table,
* frees them, and frees the ConfItems if nothing references
* them, otherwise sets them as illegal.
*/
void
clear_out_address_conf(void)
{
int i;
struct AddressRec **store_next;
struct AddressRec *arec, *arecn;
for (i = 0; i < ATABLE_SIZE; i++)
{
store_next = &atable[i];
for (arec = atable[i]; arec; arec = arecn)
{
arecn = arec->next;
/* We keep the temporary K-lines and destroy the
* permanent ones, just to be confusing :) -A1kmm */
if(arec->aconf->flags & CONF_FLAGS_TEMPORARY ||
(arec->type != CONF_CLIENT && arec->type != CONF_EXEMPTDLINE))
{
*store_next = arec;
store_next = &arec->next;
}
else
{
arec->aconf->status |= CONF_ILLEGAL;
if(!arec->aconf->clients)
free_conf(arec->aconf);
rb_free(arec);
}
}
*store_next = NULL;
}
}
void
clear_out_address_conf_bans(void)
{
int i;
struct AddressRec **store_next;
struct AddressRec *arec, *arecn;
for (i = 0; i < ATABLE_SIZE; i++)
{
store_next = &atable[i];
for (arec = atable[i]; arec; arec = arecn)
{
arecn = arec->next;
/* We keep the temporary K-lines and destroy the
* permanent ones, just to be confusing :) -A1kmm */
if(arec->aconf->flags & CONF_FLAGS_TEMPORARY ||
(arec->type == CONF_CLIENT || arec->type == CONF_EXEMPTDLINE))
{
*store_next = arec;
store_next = &arec->next;
}
else
{
arec->aconf->status |= CONF_ILLEGAL;
if(!arec->aconf->clients)
free_conf(arec->aconf);
rb_free(arec);
}
}
*store_next = NULL;
}
}
/*
* show_iline_prefix()
*
* inputs - pointer to struct Client requesting output
* - pointer to struct ConfItem
* - name to which iline prefix will be prefixed to
* output - pointer to static string with prefixes listed in ascii form
* side effects - NONE
*/
char *
show_iline_prefix(struct Client *sptr, struct ConfItem *aconf, char *name)
{
static char prefix_of_host[USERLEN + 15];
char *prefix_ptr;
prefix_ptr = prefix_of_host;
if(IsNoTilde(aconf))
*prefix_ptr++ = '-';
if(IsNeedIdentd(aconf))
*prefix_ptr++ = '+';
if(IsConfDoSpoofIp(aconf))
*prefix_ptr++ = '=';
if(IsOper(sptr) && IsConfExemptFlood(aconf))
*prefix_ptr++ = '|';
if(IsOper(sptr) && IsConfExemptDNSBL(aconf) && !IsConfExemptKline(aconf))
*prefix_ptr++ = '$';
if(IsOper(sptr) && IsConfExemptKline(aconf))
*prefix_ptr++ = '^';
if(IsOper(sptr) && IsConfExemptLimits(aconf))
*prefix_ptr++ = '>';
*prefix_ptr = '\0';
strncpy(prefix_ptr, name, USERLEN);
return (prefix_of_host);
}
/* report_auth()
*
* Inputs: pointer to client to report to
* Output: None
* Side effects: Reports configured auth{} blocks to client_p
*/
void
report_auth(struct Client *client_p)
{
char *name, *host, *user, *classname;
const char *pass;
struct AddressRec *arec;
struct ConfItem *aconf;
int i, port;
for (i = 0; i < ATABLE_SIZE; i++)
for (arec = atable[i]; arec; arec = arec->next)
if(arec->type == CONF_CLIENT)
{
aconf = arec->aconf;
if(!IsOper(client_p) && IsConfDoSpoofIp(aconf))
continue;
get_printable_conf(aconf, &name, &host, &pass, &user, &port,
&classname);
if(!EmptyString(aconf->spasswd))
pass = aconf->spasswd;
sendto_one_numeric(client_p, RPL_STATSILINE,
form_str(RPL_STATSILINE),
name, pass, show_iline_prefix(client_p, aconf, user),
show_ip_conf(aconf, client_p) ? host : "255.255.255.255",
port, classname);
}
}

View file

@ -1,785 +0,0 @@
/*
* charybdis: A slightly useful ircd.
* ircd.c: Starts up and runs the ircd.
*
* Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
* Copyright (C) 1996-2002 Hybrid Development Team
* Copyright (C) 2002-2008 ircd-ratbox development team
* Copyright (C) 2005-2013 charybdis development team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 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
*
* $Id$
*/
#include "ratbox_lib.h"
#include "stdinc.h"
#include "setup.h"
#include "config.h"
#include "ircd.h"
#include "channel.h"
#include "class.h"
#include "client.h"
#include "common.h"
#include "hash.h"
#include "match.h"
#include "ircd_signal.h"
#include "msg.h" /* msgtab */
#include "hostmask.h"
#include "numeric.h"
#include "parse.h"
#include "res.h"
#include "restart.h"
#include "s_auth.h"
#include "s_conf.h"
#include "logger.h"
#include "s_serv.h" /* try_connections */
#include "s_user.h"
#include "s_stats.h"
#include "scache.h"
#include "send.h"
#include "supported.h"
#include "whowas.h"
#include "modules.h"
#include "hook.h"
#include "ircd_getopt.h"
#include "newconf.h"
#include "reject.h"
#include "s_conf.h"
#include "s_newconf.h"
#include "cache.h"
#include "monitor.h"
#include "patchlevel.h"
#include "serno.h"
#include "sslproc.h"
#include "chmode.h"
#include "privilege.h"
#include "bandbi.h"
/* /quote set variables */
struct SetOptions GlobalSetOptions;
/* configuration set from ircd.conf */
struct config_file_entry ConfigFileEntry;
/* server info set from ircd.conf */
struct server_info ServerInfo;
/* admin info set from ircd.conf */
struct admin_info AdminInfo;
struct Counter Count;
struct ServerStatistics ServerStats;
int maxconnections;
struct Client me; /* That's me */
struct LocalUser meLocalUser; /* That's also part of me */
rb_dlink_list global_client_list;
/* unknown/client pointer lists */
rb_dlink_list unknown_list; /* unknown clients ON this server only */
rb_dlink_list lclient_list; /* local clients only ON this server */
rb_dlink_list serv_list; /* local servers to this server ONLY */
rb_dlink_list global_serv_list; /* global servers on the network */
rb_dlink_list local_oper_list; /* our opers, duplicated in lclient_list */
rb_dlink_list oper_list; /* network opers */
const char *logFileName = LPATH;
const char *pidFileName = PPATH;
char **myargv;
int dorehash = 0;
int dorehashbans = 0;
int doremotd = 0;
int kline_queued = 0;
int server_state_foreground = 0;
int opers_see_all_users = 0;
int ircd_ssl_ok = 0;
int ircd_zlib_ok = 1;
int testing_conf = 0;
time_t startup_time;
int default_server_capabs;
int splitmode;
int splitchecking;
int split_users;
int split_servers;
int eob_count;
void
ircd_shutdown(const char *reason)
{
struct Client *target_p;
rb_dlink_node *ptr;
RB_DLINK_FOREACH(ptr, lclient_list.head)
{
target_p = ptr->data;
sendto_one(target_p, ":%s NOTICE %s :Server Terminating. %s",
me.name, target_p->name, reason);
}
RB_DLINK_FOREACH(ptr, serv_list.head)
{
target_p = ptr->data;
sendto_one(target_p, ":%s ERROR :Terminated by %s",
me.name, reason);
}
ilog(L_MAIN, "Server Terminating. %s", reason);
close_logfiles();
unlink(pidFileName);
exit(0);
}
/*
* init_sys
*
* inputs - boot_daemon flag
* output - none
* side effects - if boot_daemon flag is not set, don't daemonize
*/
static void
init_sys(void)
{
#if defined(RLIMIT_NOFILE) && defined(HAVE_SYS_RESOURCE_H)
struct rlimit limit;
if(!getrlimit(RLIMIT_NOFILE, &limit))
{
maxconnections = limit.rlim_cur;
if(maxconnections <= MAX_BUFFER)
{
fprintf(stderr, "ERROR: Shell FD limits are too low.\n");
fprintf(stderr, "ERROR: charybdis reserves %d FDs, shell limits must be above this\n", MAX_BUFFER);
exit(EXIT_FAILURE);
}
return;
}
#endif /* RLIMIT_FD_MAX */
maxconnections = MAXCONNECTIONS;
}
void rehash_ulimit(void)
{
#if defined(RLIMIT_NOFILE) && defined(HAVE_SYS_RESOURCE_H)
struct rlimit limit;
if(!getrlimit(RLIMIT_NOFILE, &limit) && limit.rlim_cur != maxconnections)
{
if(limit.rlim_cur <= MAX_BUFFER)
{
fprintf(stderr, "ERROR: Shell FD limits are too low.\n");
fprintf(stderr, "ERROR: charybdis reserves %d FDs, shell limits must be above this\n", MAX_BUFFER);
fprintf(stderr, "ERROR: keeping old limits\n");
return;
} else if(limit.rlim_cur < maxconnections)
{
fprintf(stderr, "ERROR: ulimit decreased\n");
fprintf(stderr, "ERROR: keeping old limits\n");
return;
}
maxconnections = limit.rlim_cur;
sendto_realops_snomask(SNO_GENERAL, L_ALL,
"Setting maxconnections to %d", maxconnections);
return;
}
#endif /* RLIMIT_FD_MAX */
}
static int
make_daemon(void)
{
int pid, nullfd, fdx;
/* The below is approximately what daemon(1, 0) does, but
we need control over the parent after forking to print
the startup message -- Aaron */
if((nullfd = open("/dev/null", O_RDWR)) < 0)
{
perror("open /dev/null");
exit(EXIT_FAILURE);
}
if((pid = fork()) < 0)
{
perror("fork");
exit(EXIT_FAILURE);
}
else if(pid > 0)
{
inotice("now running in background mode from %s as pid %d ...",
ConfigFileEntry.dpath, pid);
exit(EXIT_SUCCESS);
}
for(fdx = 0; fdx <= 2; fdx++)
if (fdx != nullfd)
(void) dup2(nullfd, fdx);
if(nullfd > 2)
(void) close(nullfd);
(void) setsid();
return 0;
}
static int printVersion = 0;
struct lgetopt myopts[] = {
{"configfile", &ConfigFileEntry.configfile,
STRING, "File to use for ircd.conf"},
{"logfile", &logFileName,
STRING, "File to use for ircd.log"},
{"pidfile", &pidFileName,
STRING, "File to use for process ID"},
{"foreground", &server_state_foreground,
YESNO, "Run in foreground (don't detach)"},
{"version", &printVersion,
YESNO, "Print version and exit"},
{"conftest", &testing_conf,
YESNO, "Test the configuration files and exit"},
{"help", NULL, USAGE, "Print this text"},
{NULL, NULL, STRING, NULL},
};
static void
check_rehash(void *unused)
{
/*
* Check to see whether we have to rehash the configuration ..
*/
if(dorehash)
{
rehash(1);
rehash_ulimit();
dorehash = 0;
}
if(dorehashbans)
{
rehash_bans(1);
dorehashbans = 0;
}
if(doremotd)
{
sendto_realops_snomask(SNO_GENERAL, L_ALL,
"Got signal SIGUSR1, reloading ircd motd file");
cache_user_motd();
doremotd = 0;
}
}
/*
* initalialize_global_set_options
*
* inputs - none
* output - none
* side effects - This sets all global set options needed
*/
static void
initialize_global_set_options(void)
{
memset(&GlobalSetOptions, 0, sizeof(GlobalSetOptions));
/* memset( &ConfigFileEntry, 0, sizeof(ConfigFileEntry)); */
GlobalSetOptions.maxclients = ServerInfo.default_max_clients;
if(GlobalSetOptions.maxclients > (maxconnections - MAX_BUFFER) || (GlobalSetOptions.maxclients <= 0))
GlobalSetOptions.maxclients = maxconnections - MAX_BUFFER;
GlobalSetOptions.autoconn = 1;
GlobalSetOptions.spam_time = MIN_JOIN_LEAVE_TIME;
GlobalSetOptions.spam_num = MAX_JOIN_LEAVE_COUNT;
GlobalSetOptions.floodcount = ConfigFileEntry.default_floodcount;
split_servers = ConfigChannel.default_split_server_count;
split_users = ConfigChannel.default_split_user_count;
if(split_users && split_servers
&& (ConfigChannel.no_create_on_split || ConfigChannel.no_join_on_split))
{
splitmode = 1;
splitchecking = 1;
}
GlobalSetOptions.ident_timeout = ConfigFileEntry.default_ident_timeout;
rb_strlcpy(GlobalSetOptions.operstring,
ConfigFileEntry.default_operstring,
sizeof(GlobalSetOptions.operstring));
rb_strlcpy(GlobalSetOptions.adminstring,
ConfigFileEntry.default_adminstring,
sizeof(GlobalSetOptions.adminstring));
/* memset( &ConfigChannel, 0, sizeof(ConfigChannel)); */
/* End of global set options */
}
/*
* initialize_server_capabs
*
* inputs - none
* output - none
*/
static void
initialize_server_capabs(void)
{
default_server_capabs &= ~CAP_ZIP;
}
/*
* write_pidfile
*
* inputs - filename+path of pid file
* output - none
* side effects - write the pid of the ircd to filename
*/
static void
write_pidfile(const char *filename)
{
FILE *fb;
char buff[32];
if((fb = fopen(filename, "w")))
{
unsigned int pid = (unsigned int) getpid();
rb_snprintf(buff, sizeof(buff), "%u\n", pid);
if((fputs(buff, fb) == -1))
{
ilog(L_MAIN, "Error writing %u to pid file %s (%s)",
pid, filename, strerror(errno));
}
fclose(fb);
return;
}
else
{
ilog(L_MAIN, "Error opening pid file %s", filename);
}
}
/*
* check_pidfile
*
* inputs - filename+path of pid file
* output - none
* side effects - reads pid from pidfile and checks if ircd is in process
* list. if it is, gracefully exits
* -kre
*/
static void
check_pidfile(const char *filename)
{
FILE *fb;
char buff[32];
pid_t pidfromfile;
/* Don't do logging here, since we don't have log() initialised */
if((fb = fopen(filename, "r")))
{
if(fgets(buff, 20, fb) != NULL)
{
pidfromfile = atoi(buff);
if(!kill(pidfromfile, 0))
{
printf("ircd: daemon is already running\n");
exit(-1);
}
}
fclose(fb);
}
}
/*
* setup_corefile
*
* inputs - nothing
* output - nothing
* side effects - setups corefile to system limits.
* -kre
*/
static void
setup_corefile(void)
{
#ifdef HAVE_SYS_RESOURCE_H
struct rlimit rlim; /* resource limits */
/* Set corefilesize to maximum */
if(!getrlimit(RLIMIT_CORE, &rlim))
{
rlim.rlim_cur = rlim.rlim_max;
setrlimit(RLIMIT_CORE, &rlim);
}
#endif
}
static void
ircd_log_cb(const char *str)
{
ilog(L_MAIN, "libratbox reports: %s", str);
}
static void __attribute__((noreturn))
ircd_restart_cb(const char *str)
{
inotice("libratbox has called the restart callback: %s", str);
restart(str);
}
/*
* Why EXIT_FAILURE here?
* Because if ircd_die_cb() is called it's because of a fatal
* error inside libcharybdis, and we don't know how to handle the
* exception, so it is logical to return a FAILURE exit code here.
* --nenolod
*/
static void __attribute__((noreturn))
ircd_die_cb(const char *str)
{
if(str != NULL)
{
/* Try to get the message out to currently logged in operators. */
sendto_realops_snomask(SNO_GENERAL, L_NETWIDE, "libratbox has called the die callback..aborting: %s", str);
inotice("libratbox has called the die callback..aborting: %s", str);
}
else
inotice("libratbox has called the die callback..aborting");
unlink(pidFileName);
exit(EXIT_FAILURE);
}
struct ev_entry *check_splitmode_ev = NULL;
static int
seed_with_urandom(void)
{
unsigned int seed;
int fd;
fd = open("/dev/urandom", O_RDONLY);
if(fd >= 0)
{
if(read(fd, &seed, sizeof(seed)) == sizeof(seed))
{
close(fd);
srand(seed);
return 1;
}
close(fd);
}
return 0;
}
static void
seed_with_clock(void)
{
const struct timeval *tv;
rb_set_time();
tv = rb_current_time_tv();
srand(tv->tv_sec ^ (tv->tv_usec | (getpid() << 20)));
}
static void
seed_random(void *unused)
{
unsigned int seed;
if(rb_get_random(&seed, sizeof(seed)) == -1)
{
if(!seed_with_urandom())
seed_with_clock();
return;
}
srand(seed);
}
/*
* main
*
* Initializes the IRCd.
*
* Inputs - number of commandline args, args themselves
* Outputs - none
* Side Effects - this is where the ircd gets going right now
*/
int
main(int argc, char *argv[])
{
int fd;
struct vhost_conf *vhost_p;
rb_dlink_node *ptr;
rb_dlink_node *next_ptr;
/* Check to see if the user is running us as root, which is a nono */
if(geteuid() == 0)
{
fprintf(stderr, "Don't run ircd as root!!!\n");
return -1;
}
init_sys();
ConfigFileEntry.dpath = DPATH;
ConfigFileEntry.configfile = CPATH; /* Server configuration file */
ConfigFileEntry.connect_timeout = 30; /* Default to 30 */
umask(077); /* better safe than sorry --SRB */
myargv = argv;
parseargs(&argc, &argv, myopts);
if(chdir(ConfigFileEntry.dpath))
{
fprintf(stderr, "Unable to chdir to %s: %s\n", ConfigFileEntry.dpath, strerror(errno));
exit(EXIT_FAILURE);
}
rb_set_time();
/*
* Setup corefile size immediately after boot -kre
*/
setup_corefile();
memset(&me, 0, sizeof(me));
memset(&meLocalUser, 0, sizeof(meLocalUser));
me.localClient = &meLocalUser;
/* Make sure all lists are zeroed */
memset(&unknown_list, 0, sizeof(unknown_list));
memset(&lclient_list, 0, sizeof(lclient_list));
memset(&serv_list, 0, sizeof(serv_list));
memset(&global_serv_list, 0, sizeof(global_serv_list));
memset(&local_oper_list, 0, sizeof(local_oper_list));
memset(&oper_list, 0, sizeof(oper_list));
rb_dlinkAddTail(&me, &me.node, &global_client_list);
memset(&Count, 0, sizeof(Count));
memset(&ServerInfo, 0, sizeof(ServerInfo));
memset(&AdminInfo, 0, sizeof(AdminInfo));
memset(&ServerStats, 0, sizeof(struct ServerStatistics));
if(printVersion)
{
printf("ircd: version %s(%s)\n", ircd_version, serno);
#ifdef CUSTOM_BRANDING
printf("ircd: based on %s-%s\n", PACKAGE_NAME, PACKAGE_VERSION);
#endif
printf("ircd: %s\n", rb_lib_version());
exit(EXIT_SUCCESS);
}
setup_signals();
if (testing_conf)
server_state_foreground = 1;
/* Make sure fd 0, 1 and 2 are in use -- jilles */
do
{
fd = open("/dev/null", O_RDWR);
} while (fd < 2 && fd != -1);
if (fd > 2)
close(fd);
else if (fd == -1)
exit(1);
/* Check if there is pidfile and daemon already running */
if(!testing_conf)
{
check_pidfile(pidFileName);
inotice("starting %s ...", ircd_version);
inotice("%s", rb_lib_version());
if(!server_state_foreground)
make_daemon();
}
/* Init the event subsystem */
rb_lib_init(ircd_log_cb, ircd_restart_cb, ircd_die_cb, !server_state_foreground, maxconnections, DNODE_HEAP_SIZE, FD_HEAP_SIZE);
rb_linebuf_init(LINEBUF_HEAP_SIZE);
rb_init_prng(NULL, RB_PRNG_DEFAULT);
seed_random(NULL);
init_builtin_capabs();
default_server_capabs = CAP_MASK;
init_main_logfile();
newconf_init();
init_s_conf();
init_s_newconf();
init_hash();
clear_scache_hash_table(); /* server cache name table */
init_host_hash();
clear_hash_parse();
init_client();
init_hook();
init_channels();
initclass();
initwhowas();
init_reject();
init_cache();
init_monitor();
construct_cflags_strings();
load_all_modules(1);
#ifndef STATIC_MODULES
load_core_modules(1);
#endif
init_auth(); /* Initialise the auth code */
init_resolver(); /* Needs to be setup before the io loop */
privilegeset_set_new("default", "", 0);
if (testing_conf)
fprintf(stderr, "\nBeginning config test\n");
read_conf_files(YES); /* cold start init conf files */
#ifndef STATIC_MODULES
mod_add_path(MODULE_DIR);
mod_add_path(MODULE_DIR "/autoload");
#endif
init_isupport();
init_bandb();
init_ssld();
rehash_bans(0);
initialize_server_capabs(); /* Set up default_server_capabs */
initialize_global_set_options();
if(ServerInfo.name == NULL)
{
ierror("no server name specified in serverinfo block.");
return -1;
}
rb_strlcpy(me.name, ServerInfo.name, sizeof(me.name));
if(ServerInfo.sid[0] == '\0')
{
ierror("no server sid specified in serverinfo block.");
return -2;
}
strcpy(me.id, ServerInfo.sid);
init_uid();
/* serverinfo{} description must exist. If not, error out. */
if(ServerInfo.description == NULL)
{
ierror("no server description specified in serverinfo block.");
return -3;
}
rb_strlcpy(me.info, ServerInfo.description, sizeof(me.info));
if(ServerInfo.ssl_cert != NULL && ServerInfo.ssl_private_key != NULL)
{
if(ServerInfo.ssl_cipher_list == NULL)
{
ierror("no ssl cipher list specified in serverinfo block.");
return -4;
}
/* just do the rb_setup_ssl_server to validate the config */
if(!rb_setup_ssl_server(ServerInfo.ssl_cert, ServerInfo.ssl_private_key, ServerInfo.ssl_dh_params, ServerInfo.ssl_cipher_list, NULL))
{
ilog(L_MAIN, "WARNING: Unable to setup SSL.");
ircd_ssl_ok = 0;
}
else
ircd_ssl_ok = 1;
RB_DLINK_FOREACH_SAFE(ptr, next_ptr, vhost_conf_list.head)
{
vhost_p = ptr->data;
ilog(L_MAIN, "WARNING: h:%s c:%s k:%s d:%s ci:%s", vhost_p->hostname, vhost_p->ssl_cert, vhost_p->ssl_private_key, ServerInfo.ssl_dh_params, ServerInfo.ssl_cipher_list);
if(rb_setup_ssl_server(vhost_p->ssl_cert, vhost_p->ssl_private_key,
vhost_p->ssl_dh_params ? vhost_p->ssl_dh_params : ServerInfo.ssl_dh_params,
vhost_p->ssl_cipher_list ? vhost_p->ssl_cipher_list : ServerInfo.ssl_cipher_list, vhost_p->hostname))
{
ircd_ssl_ok = 1;
}
}
}
if (testing_conf)
{
fprintf(stderr, "\nConfig testing complete.\n");
fflush(stderr);
return 0; /* Why? We want the launcher to exit out. */
}
me.from = &me;
me.servptr = &me;
SetMe(&me);
make_server(&me);
startup_time = rb_current_time();
add_to_client_hash(me.name, &me);
add_to_id_hash(me.id, &me);
me.serv->nameinfo = scache_connect(me.name, me.info, 0);
rb_dlinkAddAlloc(&me, &global_serv_list);
construct_umodebuf();
check_class();
write_pidfile(pidFileName);
load_help();
open_logfiles();
ilog(L_MAIN, "Server Ready");
/* We want try_connections to be called as soon as possible now! -- adrian */
/* No, 'cause after a restart it would cause all sorts of nick collides */
/* um. by waiting even longer, that just means we have even *more*
* nick collisions. what a stupid idea. set an event for the IO loop --fl
*/
rb_event_addish("try_connections", try_connections, NULL, STARTUP_CONNECTIONS_TIME);
rb_event_addonce("try_connections_startup", try_connections, NULL, 2);
rb_event_add("check_rehash", check_rehash, NULL, 3);
rb_event_addish("reseed_srand", seed_random, NULL, 300); /* reseed every 10 minutes */
if(splitmode)
check_splitmode_ev = rb_event_add("check_splitmode", check_splitmode, NULL, 5);
if(server_state_foreground)
inotice("now running in foreground mode from %s as pid %d ...",
ConfigFileEntry.dpath, getpid());
rb_lib_loop(0);
/* UNREACHABLE */
}

View file

@ -1,260 +0,0 @@
/* src/ircd_lexer.l
*
* 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
*
* $Id: ircd_lexer.l 3540 2007-07-30 17:26:00Z jilles $
*/
%option case-insensitive
%option noyywrap
%option nounput
%{
#include <sys/types.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include <string.h>
#include <errno.h>
#include <limits.h>
#define WE_ARE_MEMORY_C
#include "stdinc.h"
#include "ircd_defs.h"
#include "common.h"
#include "config.h"
#include "logger.h"
#include "s_conf.h"
#include "newconf.h"
#include "y.tab.h"
int yylex(void);
#define MAX_INCLUDE_DEPTH 10
YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH];
int include_stack_ptr=0;
int lineno = 1;
void ccomment(void);
void cinclude(void);
void hashcomment(void);
int ieof(void);
int lineno_stack[MAX_INCLUDE_DEPTH];
char conffile_stack[MAX_INCLUDE_DEPTH][IRCD_BUFSIZE];
char conffilebuf[IRCD_BUFSIZE+1];
char *current_file = conffilebuf;
FILE *inc_fbfile_in[MAX_INCLUDE_DEPTH];
char yy_linebuf[16384];
#undef YY_INPUT
#define YY_FATAL_ERROR(msg) conf_yy_fatal_error(msg)
#define YY_INPUT(buf,result,max_size) \
if (!(result = conf_fgets(buf, max_size, conf_fbfile_in))) \
YY_FATAL_ERROR("input in flex scanner failed");
%}
ws [ \t]*
digit [0-9]
comment #.*
qstring \"[^\"\n]*[\"\n]
string [a-zA-Z_\~\:][a-zA-Z0-9_\:]*
include \.include{ws}(\<.*\>|\".*\")
%%
{include} { cinclude(); }
"/*" { ccomment(); }
\n.* { rb_strlcpy(yy_linebuf, yytext+1, sizeof(yy_linebuf)); lineno++; yyless(1); }
{ws} ;
{comment} { hashcomment(); }
{digit}+ { yylval.number = atoi(yytext); return NUMBER; }
{qstring} {
if(yytext[yyleng-2] == '\\')
{
yyless(yyleng-1); /* return last quote */
yymore(); /* append next string */
}
else
{
rb_strlcpy(yylval.string, yytext + 1, 1024);
if(yylval.string[yyleng-2] != '"')
ilog(L_MAIN, "Unterminated character string");
else
{
int i,j;
yylval.string[yyleng-2] = '\0'; /* remove close
* quote
*/
for (j=i=0 ;yylval.string[i] != '\0'; i++,j++)
{
if (yylval.string[i] != '\\')
{
yylval.string[j] = yylval.string[i];
}
else
{
i++;
if (yylval.string[i] == '\0') /* XXX
* should not
* happen
*/
{
ilog(L_MAIN,
"Unterminated character string");
break;
}
yylval.string[j] = yylval.string[i];
}
}
yylval.string[j] = '\0';
return QSTRING;
}
}
}
loadmodule { return LOADMODULE; }
{string} {
rb_strlcpy(yylval.string, yytext, 1024);
yylval.string[yyleng] = '\0';
return STRING;
}
\.\. { return TWODOTS; }
. { return yytext[0]; }
<<EOF>> { if (ieof()) yyterminate(); }
%%
/* C-comment ignoring routine -kre*/
void ccomment()
{
int c;
/* log(L_NOTICE, "got comment"); */
while (1)
{
while ((c = input()) != '*' && c != EOF)
if (c == '\n') ++lineno;
if (c == '*')
{
while ((c = input()) == '*');
if (c == '/')
break;
if (c == '\n') ++lineno;
}
if (c == EOF)
{
YY_FATAL_ERROR("EOF in comment");
/* XXX hack alert this disables
* the stupid unused function warning
* gcc generates
*/
yy_fatal_error("EOF in comment");
break;
}
}
}
void cinclude(void)
{
char *c;
if ((c = strchr(yytext, '<')) == NULL)
*strchr(c = strchr(yytext, '"') + 1, '"') = 0;
else
*strchr(++c, '>') = 0;
/* do stacking and co. */
if (include_stack_ptr >= MAX_INCLUDE_DEPTH)
conf_report_error("Includes nested too deep (max is %d)", MAX_INCLUDE_DEPTH);
else
{
FILE *tmp_fbfile_in;
tmp_fbfile_in = fopen(c, "r");
if (tmp_fbfile_in == NULL)
{
/* if its not found in PREFIX, look in ETCPATH */
char fnamebuf[IRCD_BUFSIZE];
snprintf(fnamebuf, sizeof(fnamebuf), "%s/%s", ETCPATH, c);
tmp_fbfile_in = fopen(fnamebuf, "r");
/* wasnt found there either.. error. */
if(tmp_fbfile_in == NULL)
{
conf_report_error("Include %s: %s.", c, strerror(errno));
return;
}
}
lineno_stack[include_stack_ptr] = lineno;
lineno = 1;
inc_fbfile_in[include_stack_ptr] = conf_fbfile_in;
strcpy(conffile_stack[include_stack_ptr], c);
current_file = conffile_stack[include_stack_ptr];
include_stack[include_stack_ptr++] = YY_CURRENT_BUFFER;
conf_fbfile_in = tmp_fbfile_in;
yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
}
}
int ieof(void)
{
if (include_stack_ptr)
fclose(conf_fbfile_in);
if (--include_stack_ptr < 0)
{
/* We will now exit the lexer - restore init values if we get /rehash
* later and reenter lexer -kre */
include_stack_ptr = 0;
lineno = 1;
return 1;
}
/* switch buffer */
yy_delete_buffer(YY_CURRENT_BUFFER);
lineno = lineno_stack[include_stack_ptr];
conf_fbfile_in = inc_fbfile_in[include_stack_ptr];
if(include_stack_ptr)
current_file = conffile_stack[include_stack_ptr];
else
current_file = conffilebuf;
yy_switch_to_buffer(include_stack[include_stack_ptr]);
return 0;
}
/* #-comment style, look for #include */
#define INCLUDE "#include"
void hashcomment(void)
{
if (strlen(yytext) < sizeof(INCLUDE) - 1)
return;
if (!strncasecmp(yytext, INCLUDE, sizeof(INCLUDE) - 1))
yyerror("You probably meant '.include', skipping");
}

View file

@ -1,333 +0,0 @@
/* This code is in the public domain.
* $Nightmare: nightmare/src/main/parser.y,v 1.2.2.1.2.1 2002/07/02 03:42:10 ejb Exp $
* $Id: ircd_parser.y 871 2006-02-18 21:56:00Z nenolod $
*/
%{
#include <sys/types.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#define WE_ARE_MEMORY_C
#include "stdinc.h"
#include "setup.h"
#include "common.h"
#include "ircd_defs.h"
#include "config.h"
#include "client.h"
#include "modules.h"
#include "newconf.h"
#define YY_NO_UNPUT
int yyparse(void);
void yyerror(const char *);
int yylex(void);
static time_t conf_find_time(char*);
static struct {
const char * name;
const char * plural;
time_t val;
} ircd_times[] = {
{"second", "seconds", 1},
{"minute", "minutes", 60},
{"hour", "hours", 60 * 60},
{"day", "days", 60 * 60 * 24},
{"week", "weeks", 60 * 60 * 24 * 7},
{"fortnight", "fortnights", 60 * 60 * 24 * 14},
{"month", "months", 60 * 60 * 24 * 7 * 4},
{"year", "years", 60 * 60 * 24 * 365},
/* ok-- we now do sizes here too. they aren't times, but
it's close enough */
{"byte", "bytes", 1},
{"kb", NULL, 1024},
{"kbyte", "kbytes", 1024},
{"kilobyte", "kilebytes", 1024},
{"mb", NULL, 1024 * 1024},
{"mbyte", "mbytes", 1024 * 1024},
{"megabyte", "megabytes", 1024 * 1024},
{NULL, NULL, 0},
};
time_t conf_find_time(char *name)
{
int i;
for (i = 0; ircd_times[i].name; i++)
{
if (strcasecmp(ircd_times[i].name, name) == 0 ||
(ircd_times[i].plural && strcasecmp(ircd_times[i].plural, name) == 0))
return ircd_times[i].val;
}
return 0;
}
static struct
{
const char *word;
int yesno;
} yesno[] = {
{"yes", 1},
{"no", 0},
{"true", 1},
{"false", 0},
{"on", 1},
{"off", 0},
{NULL, 0}
};
static int conf_get_yesno_value(char *str)
{
int i;
for (i = 0; yesno[i].word; i++)
{
if (strcasecmp(str, yesno[i].word) == 0)
{
return yesno[i].yesno;
}
}
return -1;
}
static void free_cur_list(conf_parm_t* list)
{
if (list->type == CF_STRING || list->type == CF_QSTRING) {
rb_free(list->v.string);
} else if (list->type == CF_FLIST) {
/* Even though CF_FLIST is a flag, comparing with == is valid
* because conf_parm_t.type must be either a type or one flag.
*/
free_cur_list(list->v.list);
}
if (list->next) {
free_cur_list(list->next);
}
rb_free(list);
}
conf_parm_t * cur_list = NULL;
static void add_cur_list_cpt(conf_parm_t *new)
{
if (cur_list == NULL)
{
cur_list = rb_malloc(sizeof(conf_parm_t));
cur_list->type = CF_FLIST;
cur_list->v.list = new;
}
else
{
new->next = cur_list->v.list;
cur_list->v.list = new;
}
}
static void add_cur_list(int type, char *str, int number)
{
conf_parm_t *new;
new = rb_malloc(sizeof(conf_parm_t));
new->next = NULL;
new->type = type;
switch(type)
{
case CF_INT:
case CF_TIME:
case CF_YESNO:
new->v.number = number;
break;
case CF_STRING:
case CF_QSTRING:
new->v.string = rb_strdup(str);
break;
}
add_cur_list_cpt(new);
}
%}
%union {
int number;
char string[1024];
conf_parm_t * conf_parm;
}
%token LOADMODULE TWODOTS
%token <string> QSTRING STRING
%token <number> NUMBER
%type <string> qstring string
%type <number> number timespec
%type <conf_parm> oneitem single itemlist
%start conf
%%
conf:
| conf conf_item
| error
;
conf_item: block
| loadmodule
;
block: string
{
conf_start_block($1, NULL);
}
'{' block_items '}' ';'
{
if (conf_cur_block)
conf_end_block(conf_cur_block);
}
| string qstring
{
conf_start_block($1, $2);
}
'{' block_items '}' ';'
{
if (conf_cur_block)
conf_end_block(conf_cur_block);
}
;
block_items: block_items block_item
| block_item
;
block_item: string '=' itemlist ';'
{
conf_call_set(conf_cur_block, $1, cur_list);
free_cur_list(cur_list);
cur_list = NULL;
}
;
itemlist: itemlist ',' single
| single
;
single: oneitem
{
add_cur_list_cpt($1);
}
| oneitem TWODOTS oneitem
{
/* "1 .. 5" meaning 1,2,3,4,5 - only valid for integers */
if ($1->type != CF_INT || $3->type != CF_INT)
{
conf_report_error("Both arguments in '..' notation must be integers.");
break;
}
else
{
int i;
for (i = $1->v.number; i <= $3->v.number; i++)
{
add_cur_list(CF_INT, 0, i);
}
}
}
;
oneitem: qstring
{
$$ = rb_malloc(sizeof(conf_parm_t));
$$->type = CF_QSTRING;
$$->v.string = rb_strdup($1);
}
| timespec
{
$$ = rb_malloc(sizeof(conf_parm_t));
$$->type = CF_TIME;
$$->v.number = $1;
}
| number
{
$$ = rb_malloc(sizeof(conf_parm_t));
$$->type = CF_INT;
$$->v.number = $1;
}
| string
{
/* a 'string' could also be a yes/no value ..
so pass it as that, if so */
int val = conf_get_yesno_value($1);
$$ = rb_malloc(sizeof(conf_parm_t));
if (val != -1)
{
$$->type = CF_YESNO;
$$->v.number = val;
}
else
{
$$->type = CF_STRING;
$$->v.string = rb_strdup($1);
}
}
;
loadmodule:
LOADMODULE QSTRING
{
#ifndef STATIC_MODULES
char *m_bn;
m_bn = rb_basename((char *) $2);
if (findmodule_byname(m_bn) == -1)
load_one_module($2, 0);
rb_free(m_bn);
#endif
}
';'
;
qstring: QSTRING { strcpy($$, $1); } ;
string: STRING { strcpy($$, $1); } ;
number: NUMBER { $$ = $1; } ;
timespec: number string
{
time_t t;
if ((t = conf_find_time($2)) == 0)
{
conf_report_error("Unrecognised time type/size '%s'", $2);
t = 1;
}
$$ = $1 * t;
}
| timespec timespec
{
$$ = $1 + $2;
}
| timespec number
{
$$ = $1 + $2;
}
;

View file

@ -1,175 +0,0 @@
/************************************************************************
* IRC - Internet Relay Chat, src/ircd_signal.c
* Copyright (C) 1990 Jarkko Oikarinen and
* University of Oulu, Computing Center
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 1, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id: ircd_signal.c 6 2005-09-10 01:02:21Z nenolod $
*/
#include "stdinc.h"
#include "ircd_signal.h"
#include "ircd.h" /* dorehash */
#include "restart.h" /* server_reboot */
#include "logger.h"
#include "s_conf.h"
#include "client.h"
#include "send.h"
/*
* dummy_handler - don't know if this is really needed but if alarm is still
* being used we probably will
*/
static void
dummy_handler(int sig)
{
/* Empty */
}
static void
sigchld_handler(int sig)
{
int status, olderrno;
olderrno = errno;
while (waitpid(-1, &status, WNOHANG) > 0)
;
errno = olderrno;
}
/*
* sigterm_handler - exit the server
*/
static void __attribute__((noreturn))
sigterm_handler(int sig)
{
ircd_shutdown("Received SIGTERM");
}
/*
* sighup_handler - reread the server configuration
*/
static void
sighup_handler(int sig)
{
dorehash = 1;
}
/*
* sigusr1_handler - reread the motd file
*/
static void
sigusr1_handler(int sig)
{
doremotd = 1;
}
static void
sigusr2_handler(int sig)
{
dorehashbans = 1;
}
/*
* sigint_handler - restart the server
*/
static void
sigint_handler(int sig)
{
static int restarting = 0;
if(server_state_foreground)
{
ilog(L_MAIN, "Server exiting on SIGINT");
exit(0);
}
else
{
ilog(L_MAIN, "Server Restarting on SIGINT");
if(restarting == 0)
{
restarting = 1;
server_reboot();
}
}
}
/*
* setup_signals - initialize signal handlers for server
*/
void
setup_signals()
{
sigset_t sigs;
struct sigaction act;
sigemptyset(&sigs);
act.sa_flags = 0;
act.sa_handler = SIG_IGN;
sigemptyset(&act.sa_mask);
sigaddset(&act.sa_mask, SIGPIPE);
sigaddset(&act.sa_mask, SIGALRM);
#ifdef SIGTRAP
sigaddset(&act.sa_mask, SIGTRAP);
#endif
# ifdef SIGWINCH
sigaddset(&act.sa_mask, SIGWINCH);
sigaction(SIGWINCH, &act, 0);
# endif
sigaction(SIGPIPE, &act, 0);
#ifdef SIGTRAP
sigaction(SIGTRAP, &act, 0);
#endif
act.sa_handler = dummy_handler;
sigaction(SIGALRM, &act, 0);
sigaddset(&sigs, SIGALRM);
act.sa_handler = sighup_handler;
sigemptyset(&act.sa_mask);
sigaddset(&act.sa_mask, SIGHUP);
sigaction(SIGHUP, &act, 0);
sigaddset(&sigs, SIGHUP);
act.sa_handler = sigint_handler;
sigaddset(&act.sa_mask, SIGINT);
sigaction(SIGINT, &act, 0);
sigaddset(&sigs, SIGINT);
act.sa_handler = sigterm_handler;
sigaddset(&act.sa_mask, SIGTERM);
sigaction(SIGTERM, &act, 0);
sigaddset(&sigs, SIGTERM);
act.sa_handler = sigusr1_handler;
sigaddset(&act.sa_mask, SIGUSR1);
sigaction(SIGUSR1, &act, 0);
sigaddset(&sigs, SIGUSR1);
act.sa_handler = sigusr2_handler;
sigaddset(&act.sa_mask, SIGUSR2);
sigaction(SIGUSR2, &act, 0);
sigaddset(&sigs, SIGUSR2);
act.sa_handler = sigchld_handler;
sigaddset(&act.sa_mask, SIGCHLD);
sigaction(SIGCHLD, &act, 0);
sigaddset(&sigs, SIGCHLD);
sigprocmask(SIG_UNBLOCK, &sigs, NULL);
}

View file

@ -1,613 +0,0 @@
/*
* ircd-ratbox: A slightly useful ircd.
* listener.c: Listens on a port.
*
* Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
* Copyright (C) 1996-2002 Hybrid Development Team
* Copyright (C) 2002-2005 ircd-ratbox development team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 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
*
* $Id: listener.c 3460 2007-05-18 20:31:33Z jilles $
*/
#include "stdinc.h"
#include "setup.h"
#include "listener.h"
#include "client.h"
#include "match.h"
#include "ircd.h"
#include "ircd_defs.h"
#include "numeric.h"
#include "s_conf.h"
#include "s_newconf.h"
#include "s_stats.h"
#include "send.h"
#include "s_auth.h"
#include "reject.h"
#include "s_conf.h"
#include "hostmask.h"
#include "sslproc.h"
#include "hash.h"
#include "s_assert.h"
#include "logger.h"
#ifndef INADDR_NONE
#define INADDR_NONE ((unsigned int) 0xffffffff)
#endif
#if defined(NO_IN6ADDR_ANY) && defined(RB_IPV6)
static const struct in6_addr in6addr_any =
{ { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } };
#endif
static struct Listener *ListenerPollList = NULL;
static int accept_precallback(rb_fde_t *F, struct sockaddr *addr, rb_socklen_t addrlen, void *data);
static void accept_callback(rb_fde_t *F, int status, struct sockaddr *addr, rb_socklen_t addrlen, void *data);
static struct Listener *
make_listener(struct rb_sockaddr_storage *addr)
{
struct Listener *listener = (struct Listener *) rb_malloc(sizeof(struct Listener));
s_assert(0 != listener);
listener->name = me.name;
listener->F = NULL;
memcpy(&listener->addr, addr, sizeof(struct rb_sockaddr_storage));
listener->next = NULL;
return listener;
}
void
free_listener(struct Listener *listener)
{
s_assert(NULL != listener);
if(listener == NULL)
return;
/*
* remove from listener list
*/
if(listener == ListenerPollList)
ListenerPollList = listener->next;
else
{
struct Listener *prev = ListenerPollList;
for (; prev; prev = prev->next)
{
if(listener == prev->next)
{
prev->next = listener->next;
break;
}
}
}
/* free */
rb_free(listener);
}
#define PORTNAMELEN 6 /* ":31337" */
/*
* get_listener_port - return displayable listener port
*/
static uint16_t
get_listener_port(const struct Listener *listener)
{
#ifdef RB_IPV6
if(listener->addr.ss_family == AF_INET6)
return ntohs(((const struct sockaddr_in6 *)&listener->addr)->sin6_port);
else
#endif
return ntohs(((const struct sockaddr_in *)&listener->addr)->sin_port);
}
/*
* get_listener_name - return displayable listener name and port
* returns "host.foo.org:6667" for a given listener
*/
const char *
get_listener_name(const struct Listener *listener)
{
static char buf[HOSTLEN + HOSTLEN + PORTNAMELEN + 4];
s_assert(NULL != listener);
if(listener == NULL)
return NULL;
rb_snprintf(buf, sizeof(buf), "%s[%s/%u]",
me.name, listener->name, get_listener_port(listener));
return buf;
}
/*
* show_ports - send port listing to a client
* inputs - pointer to client to show ports to
* output - none
* side effects - show ports
*/
void
show_ports(struct Client *source_p)
{
struct Listener *listener = 0;
for (listener = ListenerPollList; listener; listener = listener->next)
{
sendto_one_numeric(source_p, RPL_STATSPLINE,
form_str(RPL_STATSPLINE), 'P',
get_listener_port(listener),
IsOperAdmin(source_p) ? listener->name : me.name,
listener->ref_count, (listener->active) ? "active" : "disabled",
listener->ssl ? " ssl" : "");
}
}
/*
* inetport - create a listener socket in the AF_INET or AF_INET6 domain,
* bind it to the port given in 'port' and listen to it
* returns true (1) if successful false (0) on error.
*
* If the operating system has a define for SOMAXCONN, use it, otherwise
* use RATBOX_SOMAXCONN
*/
#ifdef SOMAXCONN
#undef RATBOX_SOMAXCONN
#define RATBOX_SOMAXCONN SOMAXCONN
#endif
static int
inetport(struct Listener *listener)
{
rb_fde_t *F;
int opt = 1;
const char *errstr;
/*
* At first, open a new socket
*/
F = rb_socket(GET_SS_FAMILY(&listener->addr), SOCK_STREAM, 0, "Listener socket");
#ifdef RB_IPV6
if(listener->addr.ss_family == AF_INET6)
{
struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)&listener->addr;
if(!IN6_ARE_ADDR_EQUAL(&in6->sin6_addr, &in6addr_any))
{
rb_inet_ntop(AF_INET6, &in6->sin6_addr, listener->vhost, sizeof(listener->vhost));
listener->name = listener->vhost;
}
} else
#endif
{
struct sockaddr_in *in = (struct sockaddr_in *)&listener->addr;
if(in->sin_addr.s_addr != INADDR_ANY)
{
rb_inet_ntop(AF_INET, &in->sin_addr, listener->vhost, sizeof(listener->vhost));
listener->name = listener->vhost;
}
}
if(F == NULL)
{
sendto_realops_snomask(SNO_GENERAL, L_ALL,
"Cannot open socket for listener on port %d",
get_listener_port(listener));
ilog(L_MAIN, "Cannot open socket for listener %s",
get_listener_name(listener));
return 0;
}
else if((maxconnections - 10) < rb_get_fd(F)) /* XXX this is kinda bogus*/
{
ilog_error("no more connections left for listener");
sendto_realops_snomask(SNO_GENERAL, L_ALL,
"No more connections left for listener on port %d",
get_listener_port(listener));
ilog(L_MAIN, "No more connections left for listener %s",
get_listener_name(listener));
rb_close(F);
return 0;
}
/*
* XXX - we don't want to do all this crap for a listener
* set_sock_opts(listener);
*/
if(setsockopt(rb_get_fd(F), SOL_SOCKET, SO_REUSEADDR, (char *) &opt, sizeof(opt)))
{
errstr = strerror(rb_get_sockerr(F));
sendto_realops_snomask(SNO_GENERAL, L_ALL,
"Cannot set SO_REUSEADDR for listener on port %d: %s",
get_listener_port(listener), errstr);
ilog(L_MAIN, "Cannot set SO_REUSEADDR for listener %s: %s",
get_listener_name(listener), errstr);
rb_close(F);
return 0;
}
/*
* Bind a port to listen for new connections if port is non-null,
* else assume it is already open and try get something from it.
*/
if(bind(rb_get_fd(F), (struct sockaddr *) &listener->addr, GET_SS_LEN(&listener->addr)))
{
errstr = strerror(rb_get_sockerr(F));
sendto_realops_snomask(SNO_GENERAL, L_ALL,
"Cannot bind for listener on port %d: %s",
get_listener_port(listener), errstr);
ilog(L_MAIN, "Cannot bind for listener %s: %s",
get_listener_name(listener), errstr);
rb_close(F);
return 0;
}
if(rb_listen(F, RATBOX_SOMAXCONN, listener->defer_accept))
{
errstr = strerror(rb_get_sockerr(F));
sendto_realops_snomask(SNO_GENERAL, L_ALL,
"Cannot listen() for listener on port %d: %s",
get_listener_port(listener), errstr);
ilog(L_MAIN, "Cannot listen() for listener %s: %s",
get_listener_name(listener), errstr);
rb_close(F);
return 0;
}
listener->F = F;
rb_accept_tcp(listener->F, accept_precallback, accept_callback, listener);
return 1;
}
static struct Listener *
find_listener(struct rb_sockaddr_storage *addr)
{
struct Listener *listener = NULL;
struct Listener *last_closed = NULL;
for (listener = ListenerPollList; listener; listener = listener->next)
{
if(addr->ss_family != listener->addr.ss_family)
continue;
switch(addr->ss_family)
{
case AF_INET:
{
struct sockaddr_in *in4 = (struct sockaddr_in *)addr;
struct sockaddr_in *lin4 = (struct sockaddr_in *)&listener->addr;
if(in4->sin_addr.s_addr == lin4->sin_addr.s_addr &&
in4->sin_port == lin4->sin_port )
{
if(listener->F == NULL)
last_closed = listener;
else
return(listener);
}
break;
}
#ifdef RB_IPV6
case AF_INET6:
{
struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)addr;
struct sockaddr_in6 *lin6 =(struct sockaddr_in6 *)&listener->addr;
if(IN6_ARE_ADDR_EQUAL(&in6->sin6_addr, &lin6->sin6_addr) &&
in6->sin6_port == lin6->sin6_port)
{
if(listener->F == NULL)
last_closed = listener;
else
return(listener);
}
break;
}
#endif
default:
break;
}
}
return last_closed;
}
/*
* add_listener- create a new listener
* port - the port number to listen on
* vhost_ip - if non-null must contain a valid IP address string in
* the format "255.255.255.255"
*/
void
add_listener(int port, const char *vhost_ip, int family, int ssl, int defer_accept)
{
struct Listener *listener;
struct rb_sockaddr_storage vaddr;
/*
* if no port in conf line, don't bother
*/
if(port == 0)
return;
memset(&vaddr, 0, sizeof(vaddr));
vaddr.ss_family = family;
if(vhost_ip != NULL)
{
if(family == AF_INET)
{
if(rb_inet_pton(family, vhost_ip, &((struct sockaddr_in *)&vaddr)->sin_addr) <= 0)
return;
}
#ifdef RB_IPV6
else
{
if(rb_inet_pton(family, vhost_ip, &((struct sockaddr_in6 *)&vaddr)->sin6_addr) <= 0)
return;
}
#endif
} else
{
switch(family)
{
case AF_INET:
((struct sockaddr_in *)&vaddr)->sin_addr.s_addr = INADDR_ANY;
break;
#ifdef RB_IPV6
case AF_INET6:
memcpy(&((struct sockaddr_in6 *)&vaddr)->sin6_addr, &in6addr_any, sizeof(struct in6_addr));
break;
default:
return;
#endif
}
}
switch(family)
{
case AF_INET:
SET_SS_LEN(&vaddr, sizeof(struct sockaddr_in));
((struct sockaddr_in *)&vaddr)->sin_port = htons(port);
break;
#ifdef RB_IPV6
case AF_INET6:
SET_SS_LEN(&vaddr, sizeof(struct sockaddr_in6));
((struct sockaddr_in6 *)&vaddr)->sin6_port = htons(port);
break;
#endif
default:
break;
}
if((listener = find_listener(&vaddr)))
{
if(listener->F != NULL)
return;
}
else
{
listener = make_listener(&vaddr);
listener->next = ListenerPollList;
ListenerPollList = listener;
}
listener->F = NULL;
listener->ssl = ssl;
listener->defer_accept = defer_accept;
if(inetport(listener))
listener->active = 1;
else
close_listener(listener);
}
/*
* close_listener - close a single listener
*/
void
close_listener(struct Listener *listener)
{
s_assert(listener != NULL);
if(listener == NULL)
return;
if(listener->F != NULL)
{
rb_close(listener->F);
listener->F = NULL;
}
listener->active = 0;
if(listener->ref_count)
return;
free_listener(listener);
}
/*
* close_listeners - close and free all listeners that are not being used
*/
void
close_listeners()
{
struct Listener *listener;
struct Listener *listener_next = 0;
/*
* close all 'extra' listening ports we have
*/
for (listener = ListenerPollList; listener; listener = listener_next)
{
listener_next = listener->next;
close_listener(listener);
}
}
#define DLINE_WARNING "ERROR :You have been D-lined.\r\n"
/*
* add_connection - creates a client which has just connected to us on
* the given fd. The sockhost field is initialized with the ip# of the host.
* The client is sent to the auth module for verification, and not put in
* any client list yet.
*/
static void
add_connection(struct Listener *listener, rb_fde_t *F, struct sockaddr *sai, struct sockaddr *lai)
{
struct Client *new_client;
s_assert(NULL != listener);
/*
* get the client socket name from the socket
* the client has already been checked out in accept_connection
*/
new_client = make_client(NULL);
new_client->localClient->F = F;
memcpy(&new_client->localClient->ip, sai, sizeof(struct rb_sockaddr_storage));
memcpy(&new_client->preClient->lip, lai, sizeof(struct rb_sockaddr_storage));
/*
* copy address to 'sockhost' as a string, copy it to host too
* so we have something valid to put into error messages...
*/
rb_inet_ntop_sock((struct sockaddr *)&new_client->localClient->ip, new_client->sockhost,
sizeof(new_client->sockhost));
rb_strlcpy(new_client->host, new_client->sockhost, sizeof(new_client->host));
if (listener->ssl)
{
rb_fde_t *xF[2];
if(rb_socketpair(AF_UNIX, SOCK_STREAM, 0, &xF[0], &xF[1], "Incoming ssld Connection") == -1)
{
SetIOError(new_client);
exit_client(new_client, new_client, new_client, "Fatal Error");
return;
}
new_client->localClient->ssl_ctl = start_ssld_accept(F, xF[1], new_client->localClient->connid); /* this will close F for us */
if(new_client->localClient->ssl_ctl == NULL)
{
SetIOError(new_client);
exit_client(new_client, new_client, new_client, "Service Unavailable");
return;
}
F = xF[0];
new_client->localClient->F = F;
SetSSL(new_client);
}
new_client->localClient->listener = listener;
++listener->ref_count;
start_auth(new_client);
}
static const char *toofast = "ERROR :Reconnecting too fast, throttled.\r\n";
static int
accept_precallback(rb_fde_t *F, struct sockaddr *addr, rb_socklen_t addrlen, void *data)
{
struct Listener *listener = (struct Listener *)data;
char buf[BUFSIZE];
struct ConfItem *aconf;
static time_t last_oper_notice = 0;
int len;
if(listener->ssl && (!ircd_ssl_ok || !get_ssld_count()))
{
rb_close(F);
return 0;
}
if((maxconnections - 10) < rb_get_fd(F)) /* XXX this is kinda bogus */
{
++ServerStats.is_ref;
/*
* slow down the whining to opers bit
*/
if((last_oper_notice + 20) <= rb_current_time())
{
sendto_realops_snomask(SNO_GENERAL, L_ALL,
"All connections in use. (%s)",
get_listener_name(listener));
last_oper_notice = rb_current_time();
}
rb_write(F, "ERROR :All connections in use\r\n", 31);
rb_close(F);
return 0;
}
aconf = find_dline(addr, addr->sa_family);
if(aconf != NULL && (aconf->status & CONF_EXEMPTDLINE))
return 1;
/* Do an initial check we aren't connecting too fast or with too many
* from this IP... */
if(aconf != NULL)
{
ServerStats.is_ref++;
if(ConfigFileEntry.dline_with_reason)
{
len = rb_snprintf(buf, sizeof(buf), "ERROR :*** Banned: %s\r\n", get_user_ban_reason(aconf));
if (len >= (int)(sizeof(buf)-1))
{
buf[sizeof(buf) - 3] = '\r';
buf[sizeof(buf) - 2] = '\n';
buf[sizeof(buf) - 1] = '\0';
}
}
else
strcpy(buf, "ERROR :You have been D-lined.\r\n");
rb_write(F, buf, strlen(buf));
rb_close(F);
return 0;
}
if(check_reject(F, addr))
return 0;
if(throttle_add(addr))
{
rb_write(F, toofast, strlen(toofast));
rb_close(F);
return 0;
}
return 1;
}
static void
accept_callback(rb_fde_t *F, int status, struct sockaddr *addr, rb_socklen_t addrlen, void *data)
{
struct Listener *listener = data;
struct rb_sockaddr_storage lip;
unsigned int locallen = sizeof(struct rb_sockaddr_storage);
ServerStats.is_ac++;
if(getsockname(rb_get_fd(F), (struct sockaddr *) &lip, &locallen) < 0)
{
/* this can fail if the connection disappeared in the meantime */
rb_close(F);
return;
}
add_connection(listener, F, addr, (struct sockaddr *)&lip);
}

View file

@ -1,930 +0,0 @@
/*
* ircd-ratbox: A slightly useful ircd.
* modules.c: A module loader.
*
* Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
* Copyright (C) 1996-2002 Hybrid Development Team
* Copyright (C) 2002-2005 ircd-ratbox development team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 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
*
* $Id: modules.c 3161 2007-01-25 07:23:01Z nenolod $
*/
#include "stdinc.h"
#include "modules.h"
#include "logger.h"
#include "ircd.h"
#include "client.h"
#include "send.h"
#include "s_conf.h"
#include "s_newconf.h"
#include "numeric.h"
#include "parse.h"
#include "ircd_defs.h"
#include "match.h"
#ifndef STATIC_MODULES
struct module **modlist = NULL;
static const char *core_module_table[] = {
"m_ban",
"m_die",
"m_error",
"m_join",
"m_kick",
"m_kill",
"m_message",
"m_mode",
"m_nick",
"m_part",
"m_quit",
"m_server",
"m_squit",
NULL
};
#define MODS_INCREMENT 10
int num_mods = 0;
int max_mods = MODS_INCREMENT;
static rb_dlink_list mod_paths;
static int mo_modload(struct Client *, struct Client *, int, const char **);
static int mo_modlist(struct Client *, struct Client *, int, const char **);
static int mo_modreload(struct Client *, struct Client *, int, const char **);
static int mo_modunload(struct Client *, struct Client *, int, const char **);
static int mo_modrestart(struct Client *, struct Client *, int, const char **);
struct Message modload_msgtab = {
"MODLOAD", 0, 0, 0, MFLG_SLOW,
{mg_unreg, mg_not_oper, mg_ignore, mg_ignore, mg_ignore, {mo_modload, 2}}
};
struct Message modunload_msgtab = {
"MODUNLOAD", 0, 0, 0, MFLG_SLOW,
{mg_unreg, mg_not_oper, mg_ignore, mg_ignore, mg_ignore, {mo_modunload, 2}}
};
struct Message modreload_msgtab = {
"MODRELOAD", 0, 0, 0, MFLG_SLOW,
{mg_unreg, mg_not_oper, mg_ignore, mg_ignore, mg_ignore, {mo_modreload, 2}}
};
struct Message modlist_msgtab = {
"MODLIST", 0, 0, 0, MFLG_SLOW,
{mg_unreg, mg_not_oper, mg_ignore, mg_ignore, mg_ignore, {mo_modlist, 0}}
};
struct Message modrestart_msgtab = {
"MODRESTART", 0, 0, 0, MFLG_SLOW,
{mg_unreg, mg_not_oper, mg_ignore, mg_ignore, mg_ignore, {mo_modrestart, 0}}
};
void
modules_init(void)
{
mod_add_cmd(&modload_msgtab);
mod_add_cmd(&modunload_msgtab);
mod_add_cmd(&modreload_msgtab);
mod_add_cmd(&modlist_msgtab);
mod_add_cmd(&modrestart_msgtab);
/* Add the default paths we look in to the module system --nenolod */
mod_add_path(MODPATH);
mod_add_path(AUTOMODPATH);
}
/* mod_find_path()
*
* input - path
* output - none
* side effects - returns a module path from path
*/
static char *
mod_find_path(const char *path)
{
rb_dlink_node *ptr;
char *mpath;
RB_DLINK_FOREACH(ptr, mod_paths.head)
{
mpath = ptr->data;
if(!strcmp(path, mpath))
return mpath;
}
return NULL;
}
/* mod_add_path
*
* input - path
* ouput -
* side effects - adds path to list
*/
void
mod_add_path(const char *path)
{
char *pathst;
if(mod_find_path(path))
return;
pathst = rb_strdup(path);
rb_dlinkAddAlloc(pathst, &mod_paths);
}
/* mod_clear_paths()
*
* input -
* output -
* side effects - clear the lists of paths
*/
void
mod_clear_paths(void)
{
rb_dlink_node *ptr, *next_ptr;
RB_DLINK_FOREACH_SAFE(ptr, next_ptr, mod_paths.head)
{
rb_free(ptr->data);
rb_free_rb_dlink_node(ptr);
}
mod_paths.head = mod_paths.tail = NULL;
mod_paths.length = 0;
}
/* findmodule_byname
*
* input -
* output -
* side effects -
*/
int
findmodule_byname(const char *name)
{
int i;
for (i = 0; i < num_mods; i++)
{
if(!irccmp(modlist[i]->name, name))
return i;
}
return -1;
}
/* load_all_modules()
*
* input -
* output -
* side effects -
*/
void
load_all_modules(int warn)
{
DIR *system_module_dir = NULL;
struct dirent *ldirent = NULL;
char module_fq_name[PATH_MAX + 1];
int len;
modules_init();
modlist = (struct module **) rb_malloc(sizeof(struct module *) * (MODS_INCREMENT));
max_mods = MODS_INCREMENT;
system_module_dir = opendir(AUTOMODPATH);
if(system_module_dir == NULL)
{
ilog(L_MAIN, "Could not load modules from %s: %s", AUTOMODPATH, strerror(errno));
return;
}
while ((ldirent = readdir(system_module_dir)) != NULL)
{
len = strlen(ldirent->d_name);
if((len > 3) && !strcmp(ldirent->d_name+len-3, SHARED_SUFFIX))
{
(void) rb_snprintf(module_fq_name, sizeof(module_fq_name), "%s/%s", AUTOMODPATH, ldirent->d_name);
(void) load_a_module(module_fq_name, warn, 0);
}
}
(void) closedir(system_module_dir);
}
/* load_core_modules()
*
* input -
* output -
* side effects - core modules are loaded, if any fail, kill ircd
*/
void
load_core_modules(int warn)
{
char module_name[PATH_MAX];
int i;
for (i = 0; core_module_table[i]; i++)
{
rb_snprintf(module_name, sizeof(module_name), "%s/%s%s", MODPATH,
core_module_table[i], SHARED_SUFFIX);
if(load_a_module(module_name, warn, 1) == -1)
{
ilog(L_MAIN,
"Error loading core module %s%s: terminating ircd",
core_module_table[i], SHARED_SUFFIX);
exit(0);
}
}
}
/* load_one_module()
*
* input -
* output -
* side effects -
*/
int
load_one_module(const char *path, int coremodule)
{
char modpath[PATH_MAX];
rb_dlink_node *pathst;
const char *mpath;
struct stat statbuf;
if (server_state_foreground == 1)
inotice("loading module %s ...", path);
RB_DLINK_FOREACH(pathst, mod_paths.head)
{
mpath = pathst->data;
rb_snprintf(modpath, sizeof(modpath), "%s/%s", mpath, path);
if((strstr(modpath, "../") == NULL) && (strstr(modpath, "/..") == NULL))
{
if(stat(modpath, &statbuf) == 0)
{
if(S_ISREG(statbuf.st_mode))
{
/* Regular files only please */
if(coremodule)
return load_a_module(modpath, 1, 1);
else
return load_a_module(modpath, 1, 0);
}
}
}
}
sendto_realops_snomask(SNO_GENERAL, L_ALL, "Cannot locate module %s", path);
return -1;
}
/* load a module .. */
static int
mo_modload(struct Client *client_p, struct Client *source_p, int parc, const char **parv)
{
char *m_bn;
if(!IsOperAdmin(source_p))
{
sendto_one(source_p, form_str(ERR_NOPRIVS),
me.name, source_p->name, "admin");
return 0;
}
m_bn = rb_basename(parv[1]);
if(findmodule_byname(m_bn) != -1)
{
sendto_one_notice(source_p, ":Module %s is already loaded", m_bn);
rb_free(m_bn);
return 0;
}
load_one_module(parv[1], 0);
rb_free(m_bn);
return 0;
}
/* unload a module .. */
static int
mo_modunload(struct Client *client_p, struct Client *source_p, int parc, const char **parv)
{
char *m_bn;
int modindex;
if(!IsOperAdmin(source_p))
{
sendto_one(source_p, form_str(ERR_NOPRIVS),
me.name, source_p->name, "admin");
return 0;
}
m_bn = rb_basename(parv[1]);
if((modindex = findmodule_byname(m_bn)) == -1)
{
sendto_one_notice(source_p, ":Module %s is not loaded", m_bn);
rb_free(m_bn);
return 0;
}
if(modlist[modindex]->core == 1)
{
sendto_one_notice(source_p, ":Module %s is a core module and may not be unloaded", m_bn);
rb_free(m_bn);
return 0;
}
if(unload_one_module(m_bn, 1) == -1)
{
sendto_one_notice(source_p, ":Module %s is not loaded", m_bn);
}
rb_free(m_bn);
return 0;
}
/* unload and load in one! */
static int
mo_modreload(struct Client *client_p, struct Client *source_p, int parc, const char **parv)
{
char *m_bn;
int modindex;
int check_core;
if(!IsOperAdmin(source_p))
{
sendto_one(source_p, form_str(ERR_NOPRIVS),
me.name, source_p->name, "admin");
return 0;
}
m_bn = rb_basename(parv[1]);
if((modindex = findmodule_byname(m_bn)) == -1)
{
sendto_one_notice(source_p, ":Module %s is not loaded", m_bn);
rb_free(m_bn);
return 0;
}
check_core = modlist[modindex]->core;
if(unload_one_module(m_bn, 1) == -1)
{
sendto_one_notice(source_p, ":Module %s is not loaded", m_bn);
rb_free(m_bn);
return 0;
}
if((load_one_module(m_bn, check_core) == -1) && check_core)
{
sendto_realops_snomask(SNO_GENERAL, L_ALL,
"Error reloading core module: %s: terminating ircd", m_bn);
ilog(L_MAIN, "Error loading core module %s: terminating ircd", m_bn);
exit(0);
}
rb_free(m_bn);
return 0;
}
/* list modules .. */
static int
mo_modlist(struct Client *client_p, struct Client *source_p, int parc, const char **parv)
{
int i;
if(!IsOperAdmin(source_p))
{
sendto_one(source_p, form_str(ERR_NOPRIVS),
me.name, source_p->name, "admin");
return 0;
}
for (i = 0; i < num_mods; i++)
{
if(parc > 1)
{
if(match(parv[1], modlist[i]->name))
{
sendto_one(source_p, form_str(RPL_MODLIST),
me.name, source_p->name,
modlist[i]->name,
(unsigned long)(uintptr_t)modlist[i]->address,
modlist[i]->version, modlist[i]->core ? "(core)" : "");
}
}
else
{
sendto_one(source_p, form_str(RPL_MODLIST),
me.name, source_p->name, modlist[i]->name,
(unsigned long)(uintptr_t)modlist[i]->address,
modlist[i]->version,
modlist[i]->core ? "(core)" : "");
}
}
sendto_one(source_p, form_str(RPL_ENDOFMODLIST), me.name, source_p->name);
return 0;
}
/* unload and reload all modules */
static void
modules_do_restart(void *unused)
{
int modnum = num_mods;
while (num_mods)
unload_one_module(modlist[0]->name, 0);
load_all_modules(0);
load_core_modules(0);
rehash(0);
sendto_realops_snomask(SNO_GENERAL, L_ALL,
"Module Restart: %d modules unloaded, %d modules loaded",
modnum, num_mods);
ilog(L_MAIN, "Module Restart: %d modules unloaded, %d modules loaded", modnum, num_mods);
}
static int
mo_modrestart(struct Client *client_p, struct Client *source_p, int parc, const char **parv)
{
if(!IsOperAdmin(source_p))
{
sendto_one(source_p, form_str(ERR_NOPRIVS),
me.name, source_p->name, "admin");
return 0;
}
sendto_one_notice(source_p, ":Reloading all modules");
/*
* If a remote MODRESTART is received, m_encap.so will be reloaded,
* but ms_encap is in the call stack (it indirectly calls this
* function). This will go horribly wrong if m_encap is reloaded to
* a different address.
*
* So, defer the restart to the event loop (above) and return now.
*/
rb_event_addonce("modules_do_restart", modules_do_restart, NULL, 1);
return 0;
}
#ifndef RTLD_NOW
#define RTLD_NOW RTLD_LAZY /* openbsd deficiency */
#endif
#ifndef RTLD_LOCAL
#define RTLD_LOCAL 0
#endif
#ifdef CHARYBDIS_PROFILE
# ifndef RTLD_PROFILE
# warning libdl may not support profiling, sucks. :(
# define RTLD_PROFILE 0
# endif
#endif
static void increase_modlist(void);
#define MODS_INCREMENT 10
static char unknown_ver[] = "<unknown>";
/* This file contains the core functions to use dynamic libraries.
* -TimeMr14C
*/
#ifdef HAVE_MACH_O_DYLD_H
/*
** jmallett's dl*(3) shims for NSModule(3) systems.
*/
#include <mach-o/dyld.h>
#ifndef HAVE_DLOPEN
#ifndef RTLD_LAZY
#define RTLD_LAZY 2185 /* built-in dl*(3) don't care */
#endif
void undefinedErrorHandler(const char *);
NSModule multipleErrorHandler(NSSymbol, NSModule, NSModule);
void linkEditErrorHandler(NSLinkEditErrors, int, const char *, const char *);
char *dlerror(void);
void *dlopen(char *, int);
int dlclose(void *);
void *dlsym(void *, char *);
static int firstLoad = TRUE;
static int myDlError;
static char *myErrorTable[] = { "Loading file as object failed\n",
"Loading file as object succeeded\n",
"Not a valid shared object\n",
"Architecture of object invalid on this architecture\n",
"Invalid or corrupt image\n",
"Could not access object\n",
"NSCreateObjectFileImageFromFile failed\n",
NULL
};
void
undefinedErrorHandler(const char *symbolName)
{
sendto_realops_snomask(SNO_GENERAL, L_ALL, "Undefined symbol: %s", symbolName);
ilog(L_MAIN, "Undefined symbol: %s", symbolName);
return;
}
NSModule
multipleErrorHandler(NSSymbol s, NSModule old, NSModule new)
{
/* XXX
** This results in substantial leaking of memory... Should free one
** module, maybe?
*/
sendto_realops_snomask(SNO_GENERAL, L_ALL,
"Symbol `%s' found in `%s' and `%s'",
NSNameOfSymbol(s), NSNameOfModule(old), NSNameOfModule(new));
ilog(L_MAIN, "Symbol `%s' found in `%s' and `%s'",
NSNameOfSymbol(s), NSNameOfModule(old), NSNameOfModule(new));
/* We return which module should be considered valid, I believe */
return new;
}
void
linkEditErrorHandler(NSLinkEditErrors errorClass, int errnum,
const char *fileName, const char *errorString)
{
sendto_realops_snomask(SNO_GENERAL, L_ALL,
"Link editor error: %s for %s", errorString, fileName);
ilog(L_MAIN, "Link editor error: %s for %s", errorString, fileName);
return;
}
char *
dlerror(void)
{
return myDlError == NSObjectFileImageSuccess ? NULL : myErrorTable[myDlError % 7];
}
void *
dlopen(char *filename, int unused)
{
NSObjectFileImage myImage;
NSModule myModule;
if(firstLoad)
{
/*
** If we are loading our first symbol (huzzah!) we should go ahead
** and install link editor error handling!
*/
NSLinkEditErrorHandlers linkEditorErrorHandlers;
linkEditorErrorHandlers.undefined = undefinedErrorHandler;
linkEditorErrorHandlers.multiple = multipleErrorHandler;
linkEditorErrorHandlers.linkEdit = linkEditErrorHandler;
NSInstallLinkEditErrorHandlers(&linkEditorErrorHandlers);
firstLoad = FALSE;
}
myDlError = NSCreateObjectFileImageFromFile(filename, &myImage);
if(myDlError != NSObjectFileImageSuccess)
{
return NULL;
}
myModule = NSLinkModule(myImage, filename, NSLINKMODULE_OPTION_PRIVATE);
return (void *) myModule;
}
int
dlclose(void *myModule)
{
NSUnLinkModule(myModule, FALSE);
return 0;
}
void *
dlsym(void *myModule, char *mySymbolName)
{
NSSymbol mySymbol;
mySymbol = NSLookupSymbolInModule((NSModule) myModule, mySymbolName);
return NSAddressOfSymbol(mySymbol);
}
#endif
#endif
/*
* HPUX dl compat functions
*/
#if defined(HAVE_SHL_LOAD) && !defined(HAVE_DLOPEN)
#define RTLD_LAZY BIND_DEFERRED
#define RTLD_GLOBAL DYNAMIC_PATH
#define dlopen(file,mode) (void *)shl_load((file), (mode), (long) 0)
#define dlclose(handle) shl_unload((shl_t)(handle))
#define dlsym(handle,name) hpux_dlsym(handle,name)
#define dlerror() strerror(errno)
static void *
hpux_dlsym(void *handle, char *name)
{
void *sym_addr;
if(!shl_findsym((shl_t *) & handle, name, TYPE_UNDEFINED, &sym_addr))
return sym_addr;
return NULL;
}
#endif
/* unload_one_module()
*
* inputs - name of module to unload
* - 1 to say modules unloaded, 0 to not
* output - 0 if successful, -1 if error
* side effects - module is unloaded
*/
int
unload_one_module(const char *name, int warn)
{
int modindex;
if((modindex = findmodule_byname(name)) == -1)
return -1;
/*
** XXX - The type system in C does not allow direct conversion between
** data and function pointers, but as it happens, most C compilers will
** safely do this, however it is a theoretical overlow to cast as we
** must do here. I have library functions to take care of this, but
** despite being more "correct" for the C language, this is more
** practical. Removing the abuse of the ability to cast ANY pointer
** to and from an integer value here will break some compilers.
** -jmallett
*/
/* Left the comment in but the code isn't here any more -larne */
switch (modlist[modindex]->mapi_version)
{
case 1:
{
struct mapi_mheader_av1 *mheader = modlist[modindex]->mapi_header;
if(mheader->mapi_command_list)
{
struct Message **m;
for (m = mheader->mapi_command_list; *m; ++m)
mod_del_cmd(*m);
}
/* hook events are never removed, we simply lose the
* ability to call them --fl
*/
if(mheader->mapi_hfn_list)
{
mapi_hfn_list_av1 *m;
for (m = mheader->mapi_hfn_list; m->hapi_name; ++m)
remove_hook(m->hapi_name, m->fn);
}
if(mheader->mapi_unregister)
mheader->mapi_unregister();
break;
}
default:
sendto_realops_snomask(SNO_GENERAL, L_ALL,
"Unknown/unsupported MAPI version %d when unloading %s!",
modlist[modindex]->mapi_version, modlist[modindex]->name);
ilog(L_MAIN, "Unknown/unsupported MAPI version %d when unloading %s!",
modlist[modindex]->mapi_version, modlist[modindex]->name);
break;
}
dlclose(modlist[modindex]->address);
rb_free(modlist[modindex]->name);
memmove(&modlist[modindex], &modlist[modindex + 1],
sizeof(struct module *) * ((num_mods - 1) - modindex));
if(num_mods != 0)
num_mods--;
if(warn == 1)
{
ilog(L_MAIN, "Module %s unloaded", name);
sendto_realops_snomask(SNO_GENERAL, L_ALL, "Module %s unloaded", name);
}
return 0;
}
/*
* load_a_module()
*
* inputs - path name of module, int to notice, int of core
* output - -1 if error 0 if success
* side effects - loads a module if successful
*/
int
load_a_module(const char *path, int warn, int core)
{
void *tmpptr = NULL;
char *mod_basename;
const char *ver;
int *mapi_version;
mod_basename = rb_basename(path);
#ifdef CHARYBDIS_PROFILE
tmpptr = dlopen(path, RTLD_NOW | RTLD_LOCAL | RTLD_PROFILE);
#else
tmpptr = dlopen(path, RTLD_NOW | RTLD_LOCAL);
#endif
if(tmpptr == NULL)
{
const char *err = dlerror();
sendto_realops_snomask(SNO_GENERAL, L_ALL,
"Error loading module %s: %s", mod_basename, err);
ilog(L_MAIN, "Error loading module %s: %s", mod_basename, err);
rb_free(mod_basename);
return -1;
}
/*
* _mheader is actually a struct mapi_mheader_*, but mapi_version
* is always the first member of this structure, so we treate it
* as a single int in order to determine the API version.
* -larne.
*/
mapi_version = (int *) dlsym(tmpptr, "_mheader");
if((mapi_version == NULL
&& (mapi_version = (int *) dlsym(tmpptr, "__mheader")) == NULL)
|| MAPI_MAGIC(*mapi_version) != MAPI_MAGIC_HDR)
{
sendto_realops_snomask(SNO_GENERAL, L_ALL,
"Data format error: module %s has no MAPI header.",
mod_basename);
ilog(L_MAIN, "Data format error: module %s has no MAPI header.", mod_basename);
(void) dlclose(tmpptr);
rb_free(mod_basename);
return -1;
}
switch (MAPI_VERSION(*mapi_version))
{
case 1:
{
struct mapi_mheader_av1 *mheader = (struct mapi_mheader_av1 *)(void *)mapi_version; /* see above */
if(mheader->mapi_register && (mheader->mapi_register() == -1))
{
ilog(L_MAIN, "Module %s indicated failure during load.",
mod_basename);
sendto_realops_snomask(SNO_GENERAL, L_ALL,
"Module %s indicated failure during load.",
mod_basename);
dlclose(tmpptr);
rb_free(mod_basename);
return -1;
}
if(mheader->mapi_command_list)
{
struct Message **m;
for (m = mheader->mapi_command_list; *m; ++m)
mod_add_cmd(*m);
}
if(mheader->mapi_hook_list)
{
mapi_hlist_av1 *m;
for (m = mheader->mapi_hook_list; m->hapi_name; ++m)
*m->hapi_id = register_hook(m->hapi_name);
}
if(mheader->mapi_hfn_list)
{
mapi_hfn_list_av1 *m;
for (m = mheader->mapi_hfn_list; m->hapi_name; ++m)
add_hook(m->hapi_name, m->fn);
}
ver = mheader->mapi_module_version;
break;
}
default:
ilog(L_MAIN, "Module %s has unknown/unsupported MAPI version %d.",
mod_basename, MAPI_VERSION(*mapi_version));
sendto_realops_snomask(SNO_GENERAL, L_ALL,
"Module %s has unknown/unsupported MAPI version %d.",
mod_basename, *mapi_version);
dlclose(tmpptr);
rb_free(mod_basename);
return -1;
}
if(ver == NULL)
ver = unknown_ver;
increase_modlist();
modlist[num_mods] = rb_malloc(sizeof(struct module));
modlist[num_mods]->address = tmpptr;
modlist[num_mods]->version = ver;
modlist[num_mods]->core = core;
modlist[num_mods]->name = rb_strdup(mod_basename);
modlist[num_mods]->mapi_header = mapi_version;
modlist[num_mods]->mapi_version = MAPI_VERSION(*mapi_version);
num_mods++;
if(warn == 1)
{
sendto_realops_snomask(SNO_GENERAL, L_ALL,
"Module %s [version: %s; MAPI version: %d] loaded at 0x%lx",
mod_basename, ver, MAPI_VERSION(*mapi_version),
(unsigned long) tmpptr);
ilog(L_MAIN, "Module %s [version: %s; MAPI version: %d] loaded at 0x%lx",
mod_basename, ver, MAPI_VERSION(*mapi_version), (unsigned long) tmpptr);
}
rb_free(mod_basename);
return 0;
}
/*
* increase_modlist
*
* inputs - NONE
* output - NONE
* side effects - expand the size of modlist if necessary
*/
static void
increase_modlist(void)
{
struct module **new_modlist = NULL;
if((num_mods + 1) < max_mods)
return;
new_modlist = (struct module **) rb_malloc(sizeof(struct module *) *
(max_mods + MODS_INCREMENT));
memcpy((void *) new_modlist, (void *) modlist, sizeof(struct module *) * num_mods);
rb_free(modlist);
modlist = new_modlist;
max_mods += MODS_INCREMENT;
}
#else /* STATIC_MODULES */
/* load_all_modules()
*
* input -
* output -
* side effects - all the msgtabs are added for static modules
*/
void
load_all_modules(int warn)
{
load_static_modules();
}
#endif /* STATIC_MODULES */

File diff suppressed because it is too large Load diff

View file

@ -1,755 +0,0 @@
/*
* charybdis: an advanced ircd.
* parse.c: The message parser.
*
* Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
* Copyright (C) 1996-2002 Hybrid Development Team
* Copyright (C) 2002-2005 ircd-ratbox development team
* Copyright (C) 2007 William Pitcock
*
* 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
*
* $Id: parse.c 3177 2007-02-01 00:19:14Z jilles $
*/
#include "stdinc.h"
#include "parse.h"
#include "client.h"
#include "channel.h"
#include "common.h"
#include "hash.h"
#include "match.h"
#include "ircd.h"
#include "numeric.h"
#include "logger.h"
#include "s_stats.h"
#include "send.h"
#include "msg.h"
#include "s_conf.h"
#include "s_serv.h"
#include "packet.h"
#include "s_assert.h"
static struct Dictionary *cmd_dict = NULL;
struct Dictionary *alias_dict = NULL;
struct Dictionary *fakechannel_dict = NULL;
/* parv[0] is not used, and parv[LAST] == NULL */
static char *para[MAXPARA + 2];
static void cancel_clients(struct Client *, struct Client *);
static void remove_unknown(struct Client *, char *, char *);
static void do_numeric(char[], struct Client *, struct Client *, int, char **);
static void do_alias(struct alias_entry *, struct Client *, char *);
static int handle_command(struct Message *, struct Client *, struct Client *, int, const char**);
static char buffer[1024];
/* turn a string into a parc/parv pair */
static inline int
string_to_array(char *string, char **parv)
{
char *p, *buf = string;
int x = 1;
parv[x] = NULL;
while (*buf == ' ') /* skip leading spaces */
buf++;
if(*buf == '\0') /* ignore all-space args */
return x;
do
{
if(*buf == ':') /* Last parameter */
{
buf++;
parv[x++] = buf;
parv[x] = NULL;
return x;
}
else
{
parv[x++] = buf;
parv[x] = NULL;
if((p = strchr(buf, ' ')) != NULL)
{
*p++ = '\0';
buf = p;
}
else
return x;
}
while (*buf == ' ')
buf++;
if(*buf == '\0')
return x;
}
/* we can go upto parv[MAXPARA], as parv[0] is skipped */
while (x < MAXPARA);
if(*p == ':')
p++;
parv[x++] = p;
parv[x] = NULL;
return x;
}
/* parse()
*
* given a raw buffer, parses it and generates parv and parc
*/
void
parse(struct Client *client_p, char *pbuffer, char *bufend)
{
struct Client *from = client_p;
char *sender;
char *ch;
char *s;
char *end;
int i = 1;
char *numeric = 0;
struct Message *mptr;
s_assert(MyConnect(client_p));
s_assert(client_p->localClient->F != NULL);
if(IsAnyDead(client_p))
return;
for (ch = pbuffer; *ch == ' '; ch++) /* skip spaces */
/* null statement */ ;
para[0] = from->name;
if(*ch == ':')
{
ch++;
/* point sender to the sender param */
sender = ch;
if((s = strchr(ch, ' ')))
{
*s = '\0';
s++;
ch = s;
}
if(*sender && IsServer(client_p))
{
from = find_client(sender);
/* didnt find any matching client, issue a kill */
if(from == NULL)
{
ServerStats.is_unpf++;
remove_unknown(client_p, sender, pbuffer);
return;
}
para[0] = from->name;
/* fake direction, hmm. */
if(from->from != client_p)
{
ServerStats.is_wrdi++;
cancel_clients(client_p, from);
return;
}
}
while (*ch == ' ')
ch++;
}
if(*ch == '\0')
{
ServerStats.is_empt++;
return;
}
/* at this point there must be some sort of command parameter */
/*
* Extract the command code from the packet. Point s to the end
* of the command code and calculate the length using pointer
* arithmetic. Note: only need length for numerics and *all*
* numerics must have parameters and thus a space after the command
* code. -avalon
*/
/* EOB is 3 chars long but is not a numeric */
if(*(ch + 3) == ' ' && /* ok, lets see if its a possible numeric.. */
IsDigit(*ch) && IsDigit(*(ch + 1)) && IsDigit(*(ch + 2)))
{
mptr = NULL;
numeric = ch;
ServerStats.is_num++;
s = ch + 3; /* I know this is ' ' from above if */
*s++ = '\0'; /* blow away the ' ', and point s to next part */
}
else
{
int ii = 0;
if((s = strchr(ch, ' ')))
*s++ = '\0';
mptr = irc_dictionary_retrieve(cmd_dict, ch);
/* no command or its encap only, error */
if(!mptr || !mptr->cmd)
{
/*
* Note: Give error message *only* to recognized
* persons. It's a nightmare situation to have
* two programs sending "Unknown command"'s or
* equivalent to each other at full blast....
* If it has got to person state, it at least
* seems to be well behaving. Perhaps this message
* should never be generated, though... --msa
* Hm, when is the buffer empty -- if a command
* code has been found ?? -Armin
*/
if(pbuffer[0] != '\0')
{
if (IsPerson(client_p))
{
struct alias_entry *aptr = irc_dictionary_retrieve(alias_dict, ch);
if (aptr != NULL)
{
do_alias(aptr, client_p, s);
return;
}
}
if(IsPerson(from))
{
sendto_one(from, form_str(ERR_UNKNOWNCOMMAND),
me.name, from->name, ch);
}
}
ServerStats.is_unco++;
return;
}
ii = bufend - ((s) ? s : ch);
mptr->bytes += ii;
}
end = bufend - 1;
/* XXX this should be done before parse() is called */
if(*end == '\n')
*end-- = '\0';
if(*end == '\r')
*end = '\0';
if(s != NULL)
i = string_to_array(s, para);
if(mptr == NULL)
{
do_numeric(numeric, client_p, from, i, para);
return;
}
if(handle_command(mptr, client_p, from, i, /* XXX discards const!!! */ (const char **)(void *)para) < -1)
{
char *p;
for (p = pbuffer; p <= end; p += 8)
{
/* HACK HACK */
/* Its expected this nasty code can be removed
* or rewritten later if still needed.
*/
if((unsigned long) (p + 8) > (unsigned long) end)
{
for (; p <= end; p++)
{
ilog(L_MAIN, "%02x |%c", p[0], p[0]);
}
}
else
ilog(L_MAIN,
"%02x %02x %02x %02x %02x %02x %02x %02x |%c%c%c%c%c%c%c%c",
p[0], p[1], p[2], p[3], p[4], p[5],
p[6], p[7], p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
}
}
}
/*
* handle_command
*
* inputs - pointer to message block
* - pointer to client
* - pointer to client message is from
* - count of number of args
* - pointer to argv[] array
* output - -1 if error from server
* side effects -
*/
static int
handle_command(struct Message *mptr, struct Client *client_p,
struct Client *from, int i, const char** hpara)
{
struct MessageEntry ehandler;
MessageHandler handler = 0;
char squitreason[80];
if(IsAnyDead(client_p))
return -1;
if(IsServer(client_p))
mptr->rcount++;
mptr->count++;
/* New patch to avoid server flooding from unregistered connects
- Pie-Man 07/27/2000 */
if(!IsRegistered(client_p))
{
/* if its from a possible server connection
* ignore it.. more than likely its a header thats sneaked through
*/
if(IsAnyServer(client_p) && !(mptr->flags & MFLG_UNREG))
return (1);
}
ehandler = mptr->handlers[from->handler];
handler = ehandler.handler;
/* check right amount of params is passed... --is */
if(i < ehandler.min_para ||
(ehandler.min_para && EmptyString(hpara[ehandler.min_para - 1])))
{
if(!IsServer(client_p))
{
sendto_one(client_p, form_str(ERR_NEEDMOREPARAMS),
me.name,
EmptyString(client_p->name) ? "*" : client_p->name,
mptr->cmd);
if(MyClient(client_p))
return (1);
else
return (-1);
}
sendto_realops_snomask(SNO_GENERAL, L_ALL,
"Dropping server %s due to (invalid) command '%s'"
" with only %d arguments (expecting %d).",
client_p->name, mptr->cmd, i, ehandler.min_para);
ilog(L_SERVER,
"Insufficient parameters (%d < %d) for command '%s' from %s.",
i, ehandler.min_para, mptr->cmd, client_p->name);
rb_snprintf(squitreason, sizeof squitreason,
"Insufficient parameters (%d < %d) for command '%s'",
i, ehandler.min_para, mptr->cmd);
exit_client(client_p, client_p, client_p, squitreason);
return (-1);
}
(*handler) (client_p, from, i, hpara);
return (1);
}
void
handle_encap(struct Client *client_p, struct Client *source_p,
const char *command, int parc, const char *parv[])
{
struct Message *mptr;
struct MessageEntry ehandler;
MessageHandler handler = 0;
mptr = irc_dictionary_retrieve(cmd_dict, command);
if(mptr == NULL || mptr->cmd == NULL)
return;
ehandler = mptr->handlers[ENCAP_HANDLER];
handler = ehandler.handler;
if(parc < ehandler.min_para ||
(ehandler.min_para && EmptyString(parv[ehandler.min_para - 1])))
return;
(*handler) (client_p, source_p, parc, parv);
}
/*
* clear_hash_parse()
*
* inputs -
* output - NONE
* side effects - MUST MUST be called at startup ONCE before
* any other keyword hash routine is used.
*
*/
void
clear_hash_parse()
{
cmd_dict = irc_dictionary_create(strcasecmp);
}
/* mod_add_cmd
*
* inputs - command name
* - pointer to struct Message
* output - none
* side effects - load this one command name
* msg->count msg->bytes is modified in place, in
* modules address space. Might not want to do that...
*/
void
mod_add_cmd(struct Message *msg)
{
s_assert(msg != NULL);
if(msg == NULL)
return;
if (irc_dictionary_find(cmd_dict, msg->cmd) != NULL)
return;
msg->count = 0;
msg->rcount = 0;
msg->bytes = 0;
irc_dictionary_add(cmd_dict, msg->cmd, msg);
}
/* mod_del_cmd
*
* inputs - command name
* output - none
* side effects - unload this one command name
*/
void
mod_del_cmd(struct Message *msg)
{
s_assert(msg != NULL);
if(msg == NULL)
return;
irc_dictionary_delete(cmd_dict, msg->cmd);
}
/*
* report_messages
*
* inputs - pointer to client to report to
* output - NONE
* side effects - NONE
*/
void
report_messages(struct Client *source_p)
{
struct DictionaryIter iter;
struct Message *msg;
struct alias_entry *amsg;
DICTIONARY_FOREACH(msg, &iter, cmd_dict)
{
s_assert(msg->cmd != NULL);
sendto_one_numeric(source_p, RPL_STATSCOMMANDS,
form_str(RPL_STATSCOMMANDS),
msg->cmd, msg->count,
msg->bytes, msg->rcount);
}
DICTIONARY_FOREACH(amsg, &iter, alias_dict)
{
s_assert(amsg->name != NULL);
sendto_one_numeric(source_p, RPL_STATSCOMMANDS,
form_str(RPL_STATSCOMMANDS),
amsg->name, amsg->hits, 0L, 0);
}
}
/* cancel_clients()
*
* inputs - client who sent us the message, client with fake
* direction
* outputs - a given warning about the fake direction
* side effects -
*/
static void
cancel_clients(struct Client *client_p, struct Client *source_p)
{
/* ok, fake prefix happens naturally during a burst on a nick
* collision with TS5, we cant kill them because one client has to
* survive, so we just send an error.
*/
if(IsServer(source_p) || IsMe(source_p))
{
sendto_realops_snomask(SNO_DEBUG, L_ALL,
"Message for %s[%s] from %s",
source_p->name, source_p->from->name,
client_p->name);
}
else
{
sendto_realops_snomask(SNO_DEBUG, L_ALL,
"Message for %s[%s@%s!%s] from %s (TS, ignored)",
source_p->name,
source_p->username,
source_p->host,
source_p->from->name,
client_p->name);
}
}
/* remove_unknown()
*
* inputs - client who gave us message, supposed sender, buffer
* output -
* side effects - kills issued for clients, squits for servers
*/
static void
remove_unknown(struct Client *client_p, char *lsender, char *lbuffer)
{
int slen = strlen(lsender);
char sid[4];
struct Client *server;
/* meepfoo is a nickname (ignore)
* #XXXXXXXX is a UID (KILL)
* #XX is a SID (SQUIT)
* meep.foo is a server (SQUIT)
*/
if((IsDigit(lsender[0]) && slen == 3) ||
(strchr(lsender, '.') != NULL))
{
sendto_realops_snomask(SNO_DEBUG, L_ALL,
"Unknown prefix (%s) from %s, Squitting %s",
lbuffer, client_p->name, lsender);
sendto_one(client_p,
":%s SQUIT %s :(Unknown prefix (%s) from %s)",
get_id(&me, client_p), lsender,
lbuffer, client_p->name);
}
else if(!IsDigit(lsender[0]))
;
else if(slen != 9)
sendto_realops_snomask(SNO_DEBUG, L_ALL,
"Invalid prefix (%s) from %s",
lbuffer, client_p->name);
else
{
memcpy(sid, lsender, 3);
sid[3] = '\0';
server = find_server(NULL, sid);
if (server != NULL && server->from == client_p)
sendto_one(client_p, ":%s KILL %s :%s (Unknown Client)",
get_id(&me, client_p), lsender, me.name);
}
}
/*
*
* parc number of arguments ('sender' counted as one!)
* parv[1]..parv[parc-1]
* pointers to additional parameters, this is a NULL
* terminated list (parv[parc] == NULL).
*
* *WARNING*
* Numerics are mostly error reports. If there is something
* wrong with the message, just *DROP* it! Don't even think of
* sending back a neat error message -- big danger of creating
* a ping pong error message...
*/
static void
do_numeric(char numeric[], struct Client *client_p, struct Client *source_p, int parc, char *parv[])
{
struct Client *target_p;
struct Channel *chptr;
if(parc < 2 || !IsServer(source_p))
return;
/* Remap low number numerics. */
if(numeric[0] == '0')
numeric[0] = '1';
/*
* Prepare the parameter portion of the message into 'buffer'.
* (Because the buffer is twice as large as the message buffer
* for the socket, no overflow can occur here... ...on current
* assumptions--bets are off, if these are changed --msa)
* Note: if buffer is non-empty, it will begin with SPACE.
*/
if(parc > 1)
{
char *t = buffer; /* Current position within the buffer */
int i;
int tl; /* current length of presently being built string in t */
for (i = 2; i < (parc - 1); i++)
{
tl = rb_sprintf(t, " %s", parv[i]);
t += tl;
}
rb_sprintf(t, " :%s", parv[parc - 1]);
}
if((target_p = find_client(parv[1])) != NULL)
{
if(IsMe(target_p))
{
/*
* We shouldn't get numerics sent to us,
* any numerics we do get indicate a bug somewhere..
*/
/* ugh. this is here because of nick collisions. when two servers
* relink, they burst each other their nicks, then perform collides.
* if there is a nick collision, BOTH servers will kill their own
* nicks, and BOTH will kill the other servers nick, which wont exist,
* because it will have been already killed by the local server.
*
* unfortunately, as we cant guarantee other servers will do the
* "right thing" on a nick collision, we have to keep both kills.
* ergo we need to ignore ERR_NOSUCHNICK. --fl_
*/
/* quick comment. This _was_ tried. i.e. assume the other servers
* will do the "right thing" and kill a nick that is colliding.
* unfortunately, it did not work. --Dianora
*/
/* note, now we send PING on server connect, we can
* also get ERR_NOSUCHSERVER..
*/
if(atoi(numeric) != ERR_NOSUCHNICK &&
atoi(numeric) != ERR_NOSUCHSERVER)
sendto_realops_snomask(SNO_GENERAL, L_ADMIN,
"*** %s(via %s) sent a %s numeric to me: %s",
source_p->name,
client_p->name, numeric, buffer);
return;
}
else if(target_p->from == client_p)
{
/* This message changed direction (nick collision?)
* ignore it.
*/
return;
}
/* csircd will send out unknown umode flag for +a (admin), drop it here. */
if((atoi(numeric) == ERR_UMODEUNKNOWNFLAG) && MyClient(target_p))
return;
/* Fake it for server hiding, if its our client */
sendto_one(target_p, ":%s %s %s%s",
get_id(source_p, target_p), numeric,
get_id(target_p, target_p), buffer);
return;
}
else if((chptr = find_channel(parv[1])) != NULL)
sendto_channel_flags(client_p, ALL_MEMBERS, source_p, chptr,
"%s %s%s",
numeric, chptr->chname, buffer);
}
static void do_alias(struct alias_entry *aptr, struct Client *source_p, char *text)
{
char *p;
struct Client *target_p;
if (!IsFloodDone(source_p) && source_p->localClient->receiveM > 20)
flood_endgrace(source_p);
p = strchr(aptr->target, '@');
if (p != NULL)
{
/* user@server */
target_p = find_server(NULL, p + 1);
if (target_p != NULL && IsMe(target_p))
target_p = NULL;
}
else
{
/* nick, must be +S */
target_p = find_named_person(aptr->target);
if (target_p != NULL && !IsService(target_p))
target_p = NULL;
}
if (target_p == NULL)
{
sendto_one_numeric(source_p, ERR_SERVICESDOWN, form_str(ERR_SERVICESDOWN), aptr->target);
return;
}
if (text != NULL && *text == ':')
text++;
if (text == NULL || *text == '\0')
{
sendto_one(source_p, form_str(ERR_NOTEXTTOSEND), me.name, source_p->name);
return;
}
/* increment the hitcounter on this alias */
aptr->hits++;
sendto_one(target_p, ":%s PRIVMSG %s :%s",
get_id(source_p, target_p),
p != NULL ? aptr->target : get_id(target_p, target_p),
text);
}
int
m_not_oper(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
sendto_one_numeric(source_p, ERR_NOPRIVILEGES, form_str(ERR_NOPRIVILEGES));
return 0;
}
int
m_unregistered(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
/* bit of a hack.
* I don't =really= want to waste a bit in a flag
* number_of_nick_changes is only really valid after the client
* is fully registered..
*/
if(client_p->localClient->number_of_nick_changes == 0)
{
sendto_one(client_p, form_str(ERR_NOTREGISTERED), me.name);
client_p->localClient->number_of_nick_changes++;
}
return 0;
}
int
m_registered(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
sendto_one(client_p, form_str(ERR_ALREADYREGISTRED), me.name, source_p->name);
return 0;
}
int
m_ignore(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
return 0;
}

934
src/res.c
View file

@ -1,934 +0,0 @@
/*
* A rewrite of Darren Reeds original res.c As there is nothing
* left of Darrens original code, this is now licensed by the hybrid group.
* (Well, some of the function names are the same, and bits of the structs..)
* You can use it where it is useful, free even. Buy us a beer and stuff.
*
* The authors takes no responsibility for any damage or loss
* of property which results from the use of this software.
*
* $Id: res.c 3301 2007-03-28 15:04:06Z jilles $
* from Hybrid Id: res.c 459 2006-02-12 22:21:37Z db $
*
* July 1999 - Rewrote a bunch of stuff here. Change hostent builder code,
* added callbacks and reference counting of returned hostents.
* --Bleep (Thomas Helvey <tomh@inxpress.net>)
*
* This was all needlessly complicated for irc. Simplified. No more hostent
* All we really care about is the IP -> hostname mappings. Thats all.
*
* Apr 28, 2003 --cryogen and Dianora
*
* DNS server flooding lessened, AAAA-or-A lookup removed, ip6.int support
* removed, various robustness fixes
*
* 2006 --jilles and nenolod
*
* Resend queries to other servers if the DNS server replies with an error or
* an invalid response. Also, avoid servers that return errors or invalid
* responses.
*
* October 2012 --mr_flea
*/
#include "stdinc.h"
#include "ircd_defs.h"
#include "common.h"
#include "ircd.h"
#include "res.h"
#include "reslib.h"
#include "match.h"
#include "numeric.h"
#include "client.h" /* SNO_* */
#include "s_assert.h"
#include "logger.h"
#include "send.h"
#if (CHAR_BIT != 8)
#error this code needs to be able to address individual octets
#endif
static PF res_readreply;
#define MAXPACKET 1024 /* rfc sez 512 but we expand names so ... */
#define RES_MAXALIASES 35 /* maximum aliases allowed */
#define RES_MAXADDRS 35 /* maximum addresses allowed */
#define AR_TTL 600 /* TTL in seconds for dns cache entries */
/* RFC 1104/1105 wasn't very helpful about what these fields
* should be named, so for now, we'll just name them this way.
* we probably should look at what named calls them or something.
*/
#define TYPE_SIZE (size_t)2
#define CLASS_SIZE (size_t)2
#define TTL_SIZE (size_t)4
#define RDLENGTH_SIZE (size_t)2
#define ANSWER_FIXED_SIZE (TYPE_SIZE + CLASS_SIZE + TTL_SIZE + RDLENGTH_SIZE)
struct reslist
{
rb_dlink_node node;
int id;
time_t ttl;
char type;
char queryname[IRCD_RES_HOSTLEN + 1]; /* name currently being queried */
char retries; /* retry counter */
char sends; /* number of sends (>1 means resent) */
time_t sentat;
time_t timeout;
int lastns; /* index of last server sent to */
struct rb_sockaddr_storage addr;
char *name;
struct DNSQuery *query; /* query callback for this request */
};
static rb_fde_t *res_fd;
static rb_dlink_list request_list = { NULL, NULL, 0 };
static int ns_failure_count[IRCD_MAXNS]; /* timeouts and invalid/failed replies */
static void rem_request(struct reslist *request);
static struct reslist *make_request(struct DNSQuery *query);
static void gethost_byname_type_fqdn(const char *name, struct DNSQuery *query,
int type);
static void do_query_name(struct DNSQuery *query, const char *name, struct reslist *request, int);
static void do_query_number(struct DNSQuery *query, const struct rb_sockaddr_storage *,
struct reslist *request);
static void query_name(struct reslist *request);
static int send_res_msg(const char *buf, int len, int count);
static void resend_query(struct reslist *request);
static int check_question(struct reslist *request, HEADER * header, char *buf, char *eob);
static int proc_answer(struct reslist *request, HEADER * header, char *, char *);
static struct reslist *find_id(int id);
static struct DNSReply *make_dnsreply(struct reslist *request);
/*
* int
* res_ourserver(inp)
* looks up "inp" in irc_nsaddr_list[]
* returns:
* server ID or -1 for not found
* author:
* paul vixie, 29may94
* revised for ircd, cryogen(stu) may03
* slightly modified for charybdis, mr_flea oct12
*/
static int res_ourserver(const struct rb_sockaddr_storage *inp)
{
#ifdef RB_IPV6
const struct sockaddr_in6 *v6;
const struct sockaddr_in6 *v6in = (const struct sockaddr_in6 *)inp;
#endif
const struct sockaddr_in *v4;
const struct sockaddr_in *v4in = (const struct sockaddr_in *)inp;
int ns;
for (ns = 0; ns < irc_nscount; ns++)
{
const struct rb_sockaddr_storage *srv = &irc_nsaddr_list[ns];
if (srv->ss_family != inp->ss_family)
continue;
#ifdef RB_IPV6
v6 = (const struct sockaddr_in6 *)srv;
#endif
v4 = (const struct sockaddr_in *)srv;
/* could probably just memcmp(srv, inp, srv.ss_len) here
* but we'll err on the side of caution - stu
*/
switch (srv->ss_family)
{
#ifdef RB_IPV6
case AF_INET6:
if (v6->sin6_port == v6in->sin6_port)
if ((memcmp(&v6->sin6_addr.s6_addr, &v6in->sin6_addr.s6_addr,
sizeof(struct in6_addr)) == 0) ||
(memcmp(&v6->sin6_addr.s6_addr, &in6addr_any,
sizeof(struct in6_addr)) == 0))
{
return ns;
}
break;
#endif
case AF_INET:
if (v4->sin_port == v4in->sin_port)
if ((v4->sin_addr.s_addr == INADDR_ANY)
|| (v4->sin_addr.s_addr == v4in->sin_addr.s_addr))
{
return ns;
}
break;
default:
break;
}
}
return -1;
}
/*
* timeout_query_list - Remove queries from the list which have been
* there too long without being resolved.
*/
static time_t timeout_query_list(time_t now)
{
rb_dlink_node *ptr;
rb_dlink_node *next_ptr;
struct reslist *request;
time_t next_time = 0;
time_t timeout = 0;
RB_DLINK_FOREACH_SAFE(ptr, next_ptr, request_list.head)
{
request = ptr->data;
timeout = request->sentat + request->timeout;
if (now >= timeout)
{
ns_failure_count[request->lastns]++;
request->sentat = now;
request->timeout += request->timeout;
resend_query(request);
}
if ((next_time == 0) || timeout < next_time)
{
next_time = timeout;
}
}
return (next_time > now) ? next_time : (now + AR_TTL);
}
/*
* timeout_resolver - check request list
*/
static void timeout_resolver(void *notused)
{
timeout_query_list(rb_current_time());
}
static struct ev_entry *timeout_resolver_ev = NULL;
/*
* start_resolver - do everything we need to read the resolv.conf file
* and initialize the resolver file descriptor if needed
*/
static void start_resolver(void)
{
int i;
irc_res_init();
for (i = 0; i < irc_nscount; i++)
ns_failure_count[i] = 0;
if (res_fd == NULL)
{
if ((res_fd = rb_socket(irc_nsaddr_list[0].ss_family, SOCK_DGRAM, 0,
"UDP resolver socket")) == NULL)
return;
/* At the moment, the resolver FD data is global .. */
rb_setselect(res_fd, RB_SELECT_READ, res_readreply, NULL);
timeout_resolver_ev = rb_event_add("timeout_resolver", timeout_resolver, NULL, 1);
}
}
/*
* init_resolver - initialize resolver and resolver library
*/
void init_resolver(void)
{
#ifdef HAVE_SRAND48
srand48(rb_current_time());
#endif
start_resolver();
}
/*
* restart_resolver - reread resolv.conf, reopen socket
*/
void restart_resolver(void)
{
rb_close(res_fd);
res_fd = NULL;
rb_event_delete(timeout_resolver_ev); /* -ddosen */
start_resolver();
}
/*
* add_local_domain - Add the domain to hostname, if it is missing
* (as suggested by eps@TOASTER.SFSU.EDU)
*/
void add_local_domain(char *hname, size_t size)
{
/* try to fix up unqualified names */
if (strchr(hname, '.') == NULL)
{
if (irc_domain[0])
{
size_t len = strlen(hname);
if ((strlen(irc_domain) + len + 2) < size)
{
hname[len++] = '.';
strcpy(hname + len, irc_domain);
}
}
}
}
/*
* rem_request - remove a request from the list.
* This must also free any memory that has been allocated for
* temporary storage of DNS results.
*/
static void rem_request(struct reslist *request)
{
rb_dlinkDelete(&request->node, &request_list);
rb_free(request->name);
rb_free(request);
}
/*
* make_request - Create a DNS request record for the server.
*/
static struct reslist *make_request(struct DNSQuery *query)
{
struct reslist *request = rb_malloc(sizeof(struct reslist));
request->sentat = rb_current_time();
request->retries = 3;
request->timeout = 4; /* start at 4 and exponential inc. */
request->query = query;
/*
* generate a unique id
* NOTE: we don't have to worry about converting this to and from
* network byte order, the nameserver does not interpret this value
* and returns it unchanged
*
* we generate an id per request now (instead of per send) to allow
* late replies to be used.
*/
#ifdef HAVE_LRAND48
do
{
request->id = (request->id + lrand48()) & 0xffff;
} while (find_id(request->id));
#else
int k = 0;
struct timeval tv;
gettimeofday(&tv, NULL);
do
{
request->id = (request->id + k + tv.tv_usec) & 0xffff;
k++;
} while (find_id(request->id));
#endif /* HAVE_LRAND48 */
rb_dlinkAdd(request, &request->node, &request_list);
return request;
}
/*
* delete_resolver_queries - cleanup outstanding queries
* for which there no longer exist clients or conf lines.
*/
void delete_resolver_queries(const struct DNSQuery *query)
{
rb_dlink_node *ptr;
rb_dlink_node *next_ptr;
struct reslist *request;
RB_DLINK_FOREACH_SAFE(ptr, next_ptr, request_list.head)
{
if ((request = ptr->data) != NULL)
{
if (query == request->query)
rem_request(request);
}
}
}
/*
* retryfreq - determine how many queries to wait before resending
* if there have been that many consecutive timeouts
*/
static int retryfreq(int timeouts)
{
switch (timeouts)
{
case 1:
return 3;
case 2:
return 9;
case 3:
return 27;
case 4:
return 81;
default:
return 243;
}
}
/*
* send_res_msg - sends msg to a nameserver.
* This should reflect /etc/resolv.conf.
* Returns number of nameserver successfully sent to
* or -1 if no successful sends.
*/
static int send_res_msg(const char *msg, int len, int rcount)
{
int i;
int ns;
static int retrycnt;
retrycnt++;
/* First try a nameserver that seems to work.
* Every once in a while, try a possibly broken one to check
* if it is working again.
*/
for (i = 0; i < irc_nscount; i++)
{
ns = (i + rcount - 1) % irc_nscount;
if (ns_failure_count[ns] && retrycnt % retryfreq(ns_failure_count[ns]))
continue;
if (sendto(rb_get_fd(res_fd), msg, len, 0,
(struct sockaddr *)&(irc_nsaddr_list[ns]),
GET_SS_LEN(&irc_nsaddr_list[ns])) == len)
return ns;
}
/* No known working nameservers, try some broken one. */
for (i = 0; i < irc_nscount; i++)
{
ns = (i + rcount - 1) % irc_nscount;
if (!ns_failure_count[ns])
continue;
if (sendto(rb_get_fd(res_fd), msg, len, 0,
(struct sockaddr *)&(irc_nsaddr_list[ns]),
GET_SS_LEN(&irc_nsaddr_list[ns])) == len)
return ns;
}
return -1;
}
/*
* find_id - find a dns request id (id is determined by dn_mkquery)
*/
static struct reslist *find_id(int id)
{
rb_dlink_node *ptr;
struct reslist *request;
RB_DLINK_FOREACH(ptr, request_list.head)
{
request = ptr->data;
if (request->id == id)
return (request);
}
return (NULL);
}
/*
* gethost_byname_type - get host address from name, adding domain if needed
*/
void gethost_byname_type(const char *name, struct DNSQuery *query, int type)
{
char fqdn[IRCD_RES_HOSTLEN + 1];
assert(name != 0);
rb_strlcpy(fqdn, name, sizeof fqdn);
add_local_domain(fqdn, IRCD_RES_HOSTLEN);
gethost_byname_type_fqdn(fqdn, query, type);
}
/*
* gethost_byname_type_fqdn - get host address from fqdn
*/
static void gethost_byname_type_fqdn(const char *name, struct DNSQuery *query,
int type)
{
assert(name != 0);
do_query_name(query, name, NULL, type);
}
/*
* gethost_byaddr - get host name from address
*/
void gethost_byaddr(const struct rb_sockaddr_storage *addr, struct DNSQuery *query)
{
do_query_number(query, addr, NULL);
}
/*
* do_query_name - nameserver lookup name
*/
static void do_query_name(struct DNSQuery *query, const char *name, struct reslist *request,
int type)
{
if (request == NULL)
{
request = make_request(query);
request->name = rb_strdup(name);
}
rb_strlcpy(request->queryname, name, sizeof(request->queryname));
request->type = type;
query_name(request);
}
/*
* do_query_number - Use this to do reverse IP# lookups.
*/
static void do_query_number(struct DNSQuery *query, const struct rb_sockaddr_storage *addr,
struct reslist *request)
{
const unsigned char *cp;
if (request == NULL)
{
request = make_request(query);
memcpy(&request->addr, addr, sizeof(struct rb_sockaddr_storage));
request->name = (char *)rb_malloc(IRCD_RES_HOSTLEN + 1);
}
if (addr->ss_family == AF_INET)
{
const struct sockaddr_in *v4 = (const struct sockaddr_in *)addr;
cp = (const unsigned char *)&v4->sin_addr.s_addr;
rb_sprintf(request->queryname, "%u.%u.%u.%u.in-addr.arpa", (unsigned int)(cp[3]),
(unsigned int)(cp[2]), (unsigned int)(cp[1]), (unsigned int)(cp[0]));
}
#ifdef RB_IPV6
else if (addr->ss_family == AF_INET6)
{
const struct sockaddr_in6 *v6 = (const struct sockaddr_in6 *)addr;
cp = (const unsigned char *)&v6->sin6_addr.s6_addr;
(void)sprintf(request->queryname, "%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x."
"%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.ip6.arpa",
(unsigned int)(cp[15] & 0xf), (unsigned int)(cp[15] >> 4),
(unsigned int)(cp[14] & 0xf), (unsigned int)(cp[14] >> 4),
(unsigned int)(cp[13] & 0xf), (unsigned int)(cp[13] >> 4),
(unsigned int)(cp[12] & 0xf), (unsigned int)(cp[12] >> 4),
(unsigned int)(cp[11] & 0xf), (unsigned int)(cp[11] >> 4),
(unsigned int)(cp[10] & 0xf), (unsigned int)(cp[10] >> 4),
(unsigned int)(cp[9] & 0xf), (unsigned int)(cp[9] >> 4),
(unsigned int)(cp[8] & 0xf), (unsigned int)(cp[8] >> 4),
(unsigned int)(cp[7] & 0xf), (unsigned int)(cp[7] >> 4),
(unsigned int)(cp[6] & 0xf), (unsigned int)(cp[6] >> 4),
(unsigned int)(cp[5] & 0xf), (unsigned int)(cp[5] >> 4),
(unsigned int)(cp[4] & 0xf), (unsigned int)(cp[4] >> 4),
(unsigned int)(cp[3] & 0xf), (unsigned int)(cp[3] >> 4),
(unsigned int)(cp[2] & 0xf), (unsigned int)(cp[2] >> 4),
(unsigned int)(cp[1] & 0xf), (unsigned int)(cp[1] >> 4),
(unsigned int)(cp[0] & 0xf), (unsigned int)(cp[0] >> 4));
}
#endif
request->type = T_PTR;
query_name(request);
}
/*
* query_name - generate a query based on class, type and name.
*/
static void query_name(struct reslist *request)
{
char buf[MAXPACKET];
int request_len = 0;
int ns;
memset(buf, 0, sizeof(buf));
if ((request_len =
irc_res_mkquery(request->queryname, C_IN, request->type, (unsigned char *)buf, sizeof(buf))) > 0)
{
HEADER *header = (HEADER *)(void *)buf;
header->id = request->id;
++request->sends;
ns = send_res_msg(buf, request_len, request->sends);
if (ns != -1)
request->lastns = ns;
}
}
static void resend_query(struct reslist *request)
{
if (--request->retries <= 0)
{
(*request->query->callback) (request->query->ptr, NULL);
rem_request(request);
return;
}
switch (request->type)
{
case T_PTR:
do_query_number(NULL, &request->addr, request);
break;
case T_A:
#ifdef RB_IPV6
case T_AAAA:
#endif
do_query_name(NULL, request->name, request, request->type);
break;
default:
break;
}
}
/*
* check_question - check if the reply really belongs to the
* name we queried (to guard against late replies from previous
* queries with the same id).
*/
static int check_question(struct reslist *request, HEADER * header, char *buf, char *eob)
{
char hostbuf[IRCD_RES_HOSTLEN + 1]; /* working buffer */
unsigned char *current; /* current position in buf */
int n; /* temp count */
current = (unsigned char *)buf + sizeof(HEADER);
if (header->qdcount != 1)
return 0;
n = irc_dn_expand((unsigned char *)buf, (unsigned char *)eob, current, hostbuf,
sizeof(hostbuf));
if (n <= 0)
return 0;
if (strcasecmp(hostbuf, request->queryname))
return 0;
return 1;
}
/*
* proc_answer - process name server reply
*/
static int proc_answer(struct reslist *request, HEADER * header, char *buf, char *eob)
{
char hostbuf[IRCD_RES_HOSTLEN + 100]; /* working buffer */
unsigned char *current; /* current position in buf */
int type; /* answer type */
int n; /* temp count */
int rd_length;
struct sockaddr_in *v4; /* conversion */
#ifdef RB_IPV6
struct sockaddr_in6 *v6;
#endif
current = (unsigned char *)buf + sizeof(HEADER);
for (; header->qdcount > 0; --header->qdcount)
{
if ((n = irc_dn_skipname(current, (unsigned char *)eob)) < 0)
return 0;
current += (size_t) n + QFIXEDSZ;
}
/*
* process each answer sent to us blech.
*/
while (header->ancount > 0 && (char *)current < eob)
{
header->ancount--;
n = irc_dn_expand((unsigned char *)buf, (unsigned char *)eob, current, hostbuf,
sizeof(hostbuf));
if (n < 0)
{
/*
* broken message
*/
return (0);
}
else if (n == 0)
{
/*
* no more answers left
*/
return (0);
}
hostbuf[IRCD_RES_HOSTLEN] = '\0';
/* With Address arithmetic you have to be very anal
* this code was not working on alpha due to that
* (spotted by rodder/jailbird/dianora)
*/
current += (size_t) n;
if (!(((char *)current + ANSWER_FIXED_SIZE) < eob))
break;
type = irc_ns_get16(current);
current += TYPE_SIZE;
(void) irc_ns_get16(current);
current += CLASS_SIZE;
request->ttl = irc_ns_get32(current);
current += TTL_SIZE;
rd_length = irc_ns_get16(current);
current += RDLENGTH_SIZE;
/*
* Wait to set request->type until we verify this structure
*/
switch (type)
{
case T_A:
if (request->type != T_A)
return (0);
/*
* check for invalid rd_length or too many addresses
*/
if (rd_length != sizeof(struct in_addr))
return (0);
v4 = (struct sockaddr_in *)&request->addr;
SET_SS_LEN(&request->addr, sizeof(struct sockaddr_in));
v4->sin_family = AF_INET;
memcpy(&v4->sin_addr, current, sizeof(struct in_addr));
return (1);
#ifdef RB_IPV6
case T_AAAA:
if (request->type != T_AAAA)
return (0);
if (rd_length != sizeof(struct in6_addr))
return (0);
SET_SS_LEN(&request->addr, sizeof(struct sockaddr_in6));
v6 = (struct sockaddr_in6 *)&request->addr;
v6->sin6_family = AF_INET6;
memcpy(&v6->sin6_addr, current, sizeof(struct in6_addr));
return (1);
#endif
case T_PTR:
if (request->type != T_PTR)
return (0);
n = irc_dn_expand((unsigned char *)buf, (unsigned char *)eob, current,
hostbuf, sizeof(hostbuf));
if (n < 0)
return (0); /* broken message */
else if (n == 0)
return (0); /* no more answers left */
rb_strlcpy(request->name, hostbuf, IRCD_RES_HOSTLEN + 1);
return (1);
case T_CNAME:
/* real answer will follow */
current += rd_length;
break;
default:
/* XXX I'd rather just throw away the entire bogus thing
* but its possible its just a broken nameserver with still
* valid answers. But lets do some rudimentary logging for now...
*/
ilog(L_MAIN, "irc_res.c bogus type %d", type);
break;
}
}
return (1);
}
/*
* res_read_single_reply - read a dns reply from the nameserver and process it.
* Return value: 1 if a packet was read, 0 otherwise
*/
static int res_read_single_reply(rb_fde_t *F, void *data)
{
char buf[sizeof(HEADER) + MAXPACKET]
/* Sparc and alpha need 16bit-alignment for accessing header->id
* (which is uint16_t). Because of the header = (HEADER*) buf;
* lateron, this is neeeded. --FaUl
*/
#if defined(__sparc__) || defined(__alpha__)
__attribute__ ((aligned(16)))
#endif
;
HEADER *header;
struct reslist *request = NULL;
struct DNSReply *reply = NULL;
int rc;
int answer_count;
socklen_t len = sizeof(struct rb_sockaddr_storage);
struct rb_sockaddr_storage lsin;
int ns;
rc = recvfrom(rb_get_fd(F), buf, sizeof(buf), 0, (struct sockaddr *)&lsin, &len);
/* No packet */
if (rc == 0 || rc == -1)
return 0;
/* Too small */
if (rc <= (int)(sizeof(HEADER)))
return 1;
/*
* convert DNS reply reader from Network byte order to CPU byte order.
*/
header = (HEADER *)(void *)buf;
header->ancount = ntohs(header->ancount);
header->qdcount = ntohs(header->qdcount);
header->nscount = ntohs(header->nscount);
header->arcount = ntohs(header->arcount);
/*
* response for an id which we have already received an answer for
* just ignore this response.
*/
if (0 == (request = find_id(header->id)))
return 1;
/*
* check against possibly fake replies
*/
ns = res_ourserver(&lsin);
if (ns == -1)
return 1;
if (ns != request->lastns)
{
/*
* We'll accept the late reply, but penalize it a little more to make
* sure a laggy server doesn't end up favored.
*/
ns_failure_count[ns] += 3;
}
if (!check_question(request, header, buf, buf + rc))
return 1;
if ((header->rcode != NO_ERRORS) || (header->ancount == 0))
{
/*
* RFC 2136 states that in the event of a server returning SERVFAIL
* or NOTIMP, the request should be resent to the next server.
* Additionally, if the server refuses our query, resend it as well.
* -- mr_flea
*/
if (SERVFAIL == header->rcode || NOTIMP == header->rcode ||
REFUSED == header->rcode)
{
ns_failure_count[ns]++;
resend_query(request);
}
else
{
/*
* Either a fatal error was returned or no answer. Cancel the
* request.
*/
if (NXDOMAIN == header->rcode)
{
/* If the rcode is NXDOMAIN, treat it as a good response. */
ns_failure_count[ns] /= 4;
}
(*request->query->callback) (request->query->ptr, NULL);
rem_request(request);
}
return 1;
}
/*
* If this fails there was an error decoding the received packet.
* -- jilles
*/
answer_count = proc_answer(request, header, buf, buf + rc);
if (answer_count)
{
if (request->type == T_PTR)
{
if (request->name == NULL)
{
/*
* Got a PTR response with no name, something strange is
* happening. Try another DNS server.
*/
ns_failure_count[ns]++;
resend_query(request);
return 1;
}
/*
* Lookup the 'authoritative' name that we were given for the
* ip#.
*/
#ifdef RB_IPV6
if (request->addr.ss_family == AF_INET6)
gethost_byname_type_fqdn(request->name, request->query, T_AAAA);
else
#endif
gethost_byname_type_fqdn(request->name, request->query, T_A);
rem_request(request);
}
else
{
/*
* got a name and address response, client resolved
*/
reply = make_dnsreply(request);
(*request->query->callback) (request->query->ptr, reply);
rb_free(reply);
rem_request(request);
}
ns_failure_count[ns] /= 4;
}
else
{
/* Invalid or corrupt reply - try another resolver. */
ns_failure_count[ns]++;
resend_query(request);
}
return 1;
}
static void res_readreply(rb_fde_t *F, void *data)
{
while (res_read_single_reply(F, data))
;
rb_setselect(F, RB_SELECT_READ, res_readreply, NULL);
}
static struct DNSReply *make_dnsreply(struct reslist *request)
{
struct DNSReply *cp;
s_assert(request != 0);
cp = (struct DNSReply *)rb_malloc(sizeof(struct DNSReply));
cp->h_name = request->name;
memcpy(&cp->addr, &request->addr, sizeof(cp->addr));
return (cp);
}
void report_dns_servers(struct Client *source_p)
{
int i;
char ipaddr[128];
for (i = 0; i < irc_nscount; i++)
{
if (!rb_inet_ntop_sock((struct sockaddr *)&(irc_nsaddr_list[i]),
ipaddr, sizeof ipaddr))
rb_strlcpy(ipaddr, "?", sizeof ipaddr);
sendto_one_numeric(source_p, RPL_STATSDEBUG,
"A %s %d", ipaddr, ns_failure_count[i]);
}
}

View file

@ -1,646 +0,0 @@
/*
* ircd-ratbox: A slightly useful ircd.
* s_auth.c: Functions for querying a users ident.
*
* Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
* Copyright (C) 1996-2002 Hybrid Development Team
* Copyright (C) 2002-2005 ircd-ratbox development team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 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
*
* $Id: s_auth.c 3354 2007-04-03 09:21:31Z nenolod $ */
/*
* Changes:
* July 6, 1999 - Rewrote most of the code here. When a client connects
* to the server and passes initial socket validation checks, it
* is owned by this module (auth) which returns it to the rest of the
* server when dns and auth queries are finished. Until the client is
* released, the server does not know it exists and does not process
* any messages from it.
* --Bleep Thomas Helvey <tomh@inxpress.net>
*/
#include "stdinc.h"
#include "config.h"
#include "s_auth.h"
#include "s_conf.h"
#include "client.h"
#include "common.h"
#include "match.h"
#include "ircd.h"
#include "numeric.h"
#include "packet.h"
#include "res.h"
#include "logger.h"
#include "s_stats.h"
#include "send.h"
#include "hook.h"
#include "blacklist.h"
#include "s_assert.h"
struct AuthRequest
{
rb_dlink_node node;
struct Client *client; /* pointer to client struct for request */
struct DNSQuery dns_query; /* DNS Query */
unsigned int flags; /* current state of request */
rb_fde_t *F; /* file descriptor for auth queries */
time_t timeout; /* time when query expires */
uint16_t lport;
uint16_t rport;
};
/*
* flag values for AuthRequest
* NAMESPACE: AM_xxx - Authentication Module
*/
#define AM_AUTH_CONNECTING (1 << 0)
#define AM_AUTH_PENDING (1 << 1)
#define AM_DNS_PENDING (1 << 2)
#define SetDNSPending(x) ((x)->flags |= AM_DNS_PENDING)
#define ClearDNSPending(x) ((x)->flags &= ~AM_DNS_PENDING)
#define IsDNSPending(x) ((x)->flags & AM_DNS_PENDING)
#define SetAuthConnect(x) ((x)->flags |= AM_AUTH_CONNECTING)
#define ClearAuthConnect(x) ((x)->flags &= ~AM_AUTH_CONNECTING)
#define IsAuthConnect(x) ((x)->flags & AM_AUTH_CONNECTING)
#define SetAuthPending(x) ((x)->flags |= AM_AUTH_PENDING)
#define ClearAuthPending(x) ((x)->flags &= AM_AUTH_PENDING)
#define IsAuthPending(x) ((x)->flags & AM_AUTH_PENDING)
#define ClearAuth(x) ((x)->flags &= ~(AM_AUTH_PENDING | AM_AUTH_CONNECTING))
#define IsDoingAuth(x) ((x)->flags & (AM_AUTH_PENDING | AM_AUTH_CONNECTING))
/*
* a bit different approach
* this replaces the original sendheader macros
*/
static const char *HeaderMessages[] =
{
":*** Looking up your hostname...",
":*** Found your hostname",
":*** Couldn't look up your hostname",
":*** Checking Ident",
":*** Got Ident response",
":*** No Ident response",
":*** Your hostname is too long, ignoring hostname",
":*** Your forward and reverse DNS do not match, ignoring hostname",
":*** Cannot verify hostname validity, ignoring hostname",
};
typedef enum
{
REPORT_DO_DNS,
REPORT_FIN_DNS,
REPORT_FAIL_DNS,
REPORT_DO_ID,
REPORT_FIN_ID,
REPORT_FAIL_ID,
REPORT_HOST_TOOLONG,
REPORT_HOST_MISMATCH,
REPORT_HOST_UNKNOWN
}
ReportType;
#define sendheader(c, r) sendto_one_notice(c, "%s", HeaderMessages[(r)])
static rb_dlink_list auth_poll_list;
static rb_bh *auth_heap;
static EVH timeout_auth_queries_event;
static PF read_auth_reply;
static CNCB auth_connect_callback;
/*
* init_auth()
*
* Initialise the auth code
*/
void
init_auth(void)
{
/* This hook takes a struct Client for its argument */
memset(&auth_poll_list, 0, sizeof(auth_poll_list));
rb_event_addish("timeout_auth_queries_event", timeout_auth_queries_event, NULL, 1);
auth_heap = rb_bh_create(sizeof(struct AuthRequest), LCLIENT_HEAP_SIZE, "auth_heap");
}
/*
* make_auth_request - allocate a new auth request
*/
static struct AuthRequest *
make_auth_request(struct Client *client)
{
struct AuthRequest *request = rb_bh_alloc(auth_heap);
client->localClient->auth_request = request;
request->F = NULL;
request->client = client;
request->timeout = rb_current_time() + ConfigFileEntry.connect_timeout;
return request;
}
/*
* free_auth_request - cleanup auth request allocations
*/
static void
free_auth_request(struct AuthRequest *request)
{
rb_bh_free(auth_heap, request);
}
/*
* release_auth_client - release auth client from auth system
* this adds the client into the local client lists so it can be read by
* the main io processing loop
*/
static void
release_auth_client(struct AuthRequest *auth)
{
struct Client *client = auth->client;
if(IsDNSPending(auth) || IsDoingAuth(auth))
return;
client->localClient->auth_request = NULL;
rb_dlinkDelete(&auth->node, &auth_poll_list);
free_auth_request(auth);
/*
* When a client has auth'ed, we want to start reading what it sends
* us. This is what read_packet() does.
* -- adrian
*/
rb_dlinkAddTail(client, &client->node, &global_client_list);
read_packet(client->localClient->F, client);
}
/*
* auth_dns_callback - called when resolver query finishes
* if the query resulted in a successful search, hp will contain
* a non-null pointer, otherwise hp will be null.
* set the client on it's way to a connection completion, regardless
* of success of failure
*/
static void
auth_dns_callback(void *vptr, struct DNSReply *reply)
{
struct AuthRequest *auth = (struct AuthRequest *) vptr;
ClearDNSPending(auth);
/* XXX: this shouldn't happen, but it does. -nenolod */
if(auth->client->localClient == NULL)
{
sendto_realops_snomask(SNO_GENERAL, L_ALL,
"auth_dns_callback(): auth->client->localClient (%s) is NULL", get_client_name(auth->client, HIDE_IP));
rb_dlinkDelete(&auth->node, &auth_poll_list);
free_auth_request(auth);
/* and they will silently drop through and all will hopefully be ok... -nenolod */
return;
}
if(reply)
{
int good = 1;
if(auth->client->localClient->ip.ss_family == AF_INET)
{
struct sockaddr_in *ip, *ip_fwd;
ip = (struct sockaddr_in *) &auth->client->localClient->ip;
ip_fwd = (struct sockaddr_in *) &reply->addr;
if(ip->sin_addr.s_addr != ip_fwd->sin_addr.s_addr)
{
sendheader(auth->client, REPORT_HOST_MISMATCH);
good = 0;
}
}
#ifdef RB_IPV6
else if(auth->client->localClient->ip.ss_family == AF_INET6)
{
struct sockaddr_in6 *ip, *ip_fwd;
ip = (struct sockaddr_in6 *) &auth->client->localClient->ip;
ip_fwd = (struct sockaddr_in6 *) &reply->addr;
if(memcmp(&ip->sin6_addr, &ip_fwd->sin6_addr, sizeof(struct in6_addr)) != 0)
{
sendheader(auth->client, REPORT_HOST_MISMATCH);
good = 0;
}
}
#endif
else /* can't verify it, don't know how. reject it. */
{
sendheader(auth->client, REPORT_HOST_UNKNOWN);
good = 0;
}
if(good && strlen(reply->h_name) <= HOSTLEN)
{
rb_strlcpy(auth->client->host, reply->h_name, sizeof(auth->client->host));
sendheader(auth->client, REPORT_FIN_DNS);
}
else if (strlen(reply->h_name) > HOSTLEN)
sendheader(auth->client, REPORT_HOST_TOOLONG);
}
else
sendheader(auth->client, REPORT_FAIL_DNS);
release_auth_client(auth);
}
/*
* authsenderr - handle auth send errors
*/
static void
auth_error(struct AuthRequest *auth)
{
++ServerStats.is_abad;
rb_close(auth->F);
auth->F = NULL;
ClearAuth(auth);
sendheader(auth->client, REPORT_FAIL_ID);
release_auth_client(auth);
}
/*
* start_auth_query - Flag the client to show that an attempt to
* contact the ident server on
* the client's host. The connect and subsequently the socket are all put
* into 'non-blocking' mode. Should the connect or any later phase of the
* identifing process fail, it is aborted and the user is given a username
* of "unknown".
*/
static int
start_auth_query(struct AuthRequest *auth)
{
struct rb_sockaddr_storage localaddr, destaddr;
rb_fde_t *F;
int family;
if(IsAnyDead(auth->client))
return 0;
family = auth->client->localClient->ip.ss_family;
if((F = rb_socket(family, SOCK_STREAM, 0, "ident")) == NULL)
{
ilog_error("creating auth stream socket");
++ServerStats.is_abad;
return 0;
}
/*
* TBD: this is a pointless arbitrary limit .. we either have a socket or not. -nenolod
*/
if((maxconnections - 10) < rb_get_fd(F))
{
sendto_realops_snomask(SNO_GENERAL, L_ALL,
"Can't allocate fd for auth on %s",
get_client_name(auth->client, SHOW_IP));
rb_close(F);
return 0;
}
sendheader(auth->client, REPORT_DO_ID);
/*
* get the local address of the client and bind to that to
* make the auth request. This used to be done only for
* ifdef VIRTUAL_HOST, but needs to be done for all clients
* since the ident request must originate from that same address--
* and machines with multiple IP addresses are common now
*/
localaddr = auth->client->preClient->lip;
/* XXX mangle_mapped_sockaddr((struct sockaddr *)&localaddr); */
#ifdef RB_IPV6
if(localaddr.ss_family == AF_INET6)
{
auth->lport = ntohs(((struct sockaddr_in6 *)&localaddr)->sin6_port);
((struct sockaddr_in6 *)&localaddr)->sin6_port = 0;
}
else
#endif
{
auth->lport = ntohs(((struct sockaddr_in *)&localaddr)->sin_port);
((struct sockaddr_in *)&localaddr)->sin_port = 0;
}
destaddr = auth->client->localClient->ip;
#ifdef RB_IPV6
if(localaddr.ss_family == AF_INET6)
{
auth->rport = ntohs(((struct sockaddr_in6 *)&destaddr)->sin6_port);
((struct sockaddr_in6 *)&destaddr)->sin6_port = htons(113);
}
else
#endif
{
auth->rport = ntohs(((struct sockaddr_in *)&destaddr)->sin_port);
((struct sockaddr_in *)&destaddr)->sin_port = htons(113);
}
auth->F = F;
SetAuthConnect(auth);
rb_connect_tcp(F, (struct sockaddr *)&destaddr,
(struct sockaddr *) &localaddr, GET_SS_LEN(&localaddr),
auth_connect_callback, auth,
GlobalSetOptions.ident_timeout);
return 1; /* We suceed here for now */
}
/*
* GetValidIdent - parse ident query reply from identd server
*
* Inputs - pointer to ident buf
* Output - NULL if no valid ident found, otherwise pointer to name
* Side effects -
*/
static char *
GetValidIdent(char *buf)
{
int remp = 0;
int locp = 0;
char *colon1Ptr;
char *colon2Ptr;
char *colon3Ptr;
char *commaPtr;
char *remotePortString;
/* All this to get rid of a sscanf() fun. */
remotePortString = buf;
colon1Ptr = strchr(remotePortString, ':');
if(!colon1Ptr)
return 0;
*colon1Ptr = '\0';
colon1Ptr++;
colon2Ptr = strchr(colon1Ptr, ':');
if(!colon2Ptr)
return 0;
*colon2Ptr = '\0';
colon2Ptr++;
commaPtr = strchr(remotePortString, ',');
if(!commaPtr)
return 0;
*commaPtr = '\0';
commaPtr++;
remp = atoi(remotePortString);
if(!remp)
return 0;
locp = atoi(commaPtr);
if(!locp)
return 0;
/* look for USERID bordered by first pair of colons */
if(!strstr(colon1Ptr, "USERID"))
return 0;
colon3Ptr = strchr(colon2Ptr, ':');
if(!colon3Ptr)
return 0;
*colon3Ptr = '\0';
colon3Ptr++;
return (colon3Ptr);
}
/*
* start_auth - starts auth (identd) and dns queries for a client
*/
void
start_auth(struct Client *client)
{
struct AuthRequest *auth = 0;
s_assert(0 != client);
if(client == NULL)
return;
auth = make_auth_request(client);
auth->dns_query.ptr = auth;
auth->dns_query.callback = auth_dns_callback;
sendheader(client, REPORT_DO_DNS);
/* No DNS cache now, remember? -- adrian */
gethost_byaddr(&client->localClient->ip, &auth->dns_query);
SetDNSPending(auth);
if(ConfigFileEntry.disable_auth == 0)
start_auth_query(auth);
rb_dlinkAdd(auth, &auth->node, &auth_poll_list);
}
/*
* timeout_auth_queries - timeout resolver and identd requests
* allow clients through if requests failed
*/
static void
timeout_auth_queries_event(void *notused)
{
rb_dlink_node *ptr;
rb_dlink_node *next_ptr;
struct AuthRequest *auth;
RB_DLINK_FOREACH_SAFE(ptr, next_ptr, auth_poll_list.head)
{
auth = ptr->data;
if(auth->timeout < rb_current_time())
{
if(auth->F != NULL)
rb_close(auth->F);
if(IsDoingAuth(auth))
{
ClearAuth(auth);
++ServerStats.is_abad;
sendheader(auth->client, REPORT_FAIL_ID);
auth->client->localClient->auth_request = NULL;
}
if(IsDNSPending(auth))
{
ClearDNSPending(auth);
delete_resolver_queries(&auth->dns_query);
sendheader(auth->client, REPORT_FAIL_DNS);
}
auth->client->localClient->lasttime = rb_current_time();
release_auth_client(auth);
}
}
}
/*
* auth_connect_callback() - deal with the result of rb_connect_tcp()
*
* If the connection failed, we simply close the auth fd and report
* a failure. If the connection suceeded send the ident server a query
* giving "theirport , ourport". The write is only attempted *once* so
* it is deemed to be a fail if the entire write doesn't write all the
* data given. This shouldnt be a problem since the socket should have
* a write buffer far greater than this message to store it in should
* problems arise. -avalon
*/
static void
auth_connect_callback(rb_fde_t *F, int error, void *data)
{
struct AuthRequest *auth = data;
char authbuf[32];
int authlen;
/* Check the error */
if(error != RB_OK)
{
/* We had an error during connection :( */
auth_error(auth);
return;
}
rb_snprintf(authbuf, sizeof(authbuf), "%u , %u\r\n",
auth->rport, auth->lport);
authlen = strlen(authbuf);
if(rb_write(auth->F, authbuf, authlen) != authlen)
{
auth_error(auth);
return;
}
ClearAuthConnect(auth);
SetAuthPending(auth);
read_auth_reply(auth->F, auth);
}
/*
* read_auth_reply - read the reply (if any) from the ident server
* we connected to.
* We only give it one shot, if the reply isn't good the first time
* fail the authentication entirely. --Bleep
*/
#define AUTH_BUFSIZ 128
static void
read_auth_reply(rb_fde_t *F, void *data)
{
struct AuthRequest *auth = data;
char *s = NULL;
char *t = NULL;
int len;
int count;
char buf[AUTH_BUFSIZ + 1] = { 0 }; /* buffer to read auth reply into */
len = rb_read(F, buf, AUTH_BUFSIZ);
if(len < 0 && rb_ignore_errno(errno))
{
rb_setselect(F, RB_SELECT_READ, read_auth_reply, auth);
return;
}
if(len > 0)
{
buf[len] = '\0';
if((s = GetValidIdent(buf)))
{
t = auth->client->username;
while (*s == '~' || *s == '^')
s++;
for (count = USERLEN; *s && count; s++)
{
if(*s == '@')
{
break;
}
if(!IsSpace(*s) && *s != ':' && *s != '[')
{
*t++ = *s;
count--;
}
}
*t = '\0';
}
}
rb_close(auth->F);
auth->F = NULL;
ClearAuth(auth);
if(s == NULL)
{
++ServerStats.is_abad;
strcpy(auth->client->username, "unknown");
sendheader(auth->client, REPORT_FAIL_ID);
}
else
{
sendheader(auth->client, REPORT_FIN_ID);
++ServerStats.is_asuc;
SetGotId(auth->client);
}
release_auth_client(auth);
}
/*
* delete_auth_queries()
*
*/
void
delete_auth_queries(struct Client *target_p)
{
struct AuthRequest *auth;
if(target_p == NULL || target_p->localClient == NULL ||
target_p->localClient->auth_request == NULL)
return;
auth = target_p->localClient->auth_request;
target_p->localClient->auth_request = NULL;
if(IsDNSPending(auth))
delete_resolver_queries(&auth->dns_query);
if(auth->F != NULL)
rb_close(auth->F);
rb_dlinkDelete(&auth->node, &auth_poll_list);
free_auth_request(auth);
}

File diff suppressed because it is too large Load diff

View file

@ -1,847 +0,0 @@
/*
* ircd-ratbox: an advanced Internet Relay Chat Daemon(ircd).
* s_newconf.c - code for dealing with conf stuff
*
* Copyright (C) 2004 Lee Hardy <lee@leeh.co.uk>
* Copyright (C) 2004-2005 ircd-ratbox development team
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1.Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2.Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3.The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* $Id: s_newconf.c 3508 2007-06-04 16:04:49Z jilles $
*/
#include "stdinc.h"
#include "ircd_defs.h"
#include "common.h"
#include "s_conf.h"
#include "s_newconf.h"
#include "client.h"
#include "s_serv.h"
#include "send.h"
#include "hostmask.h"
#include "newconf.h"
#include "hash.h"
#include "irc_dictionary.h"
#include "s_assert.h"
#include "logger.h"
rb_dlink_list shared_conf_list;
rb_dlink_list cluster_conf_list;
rb_dlink_list oper_conf_list;
rb_dlink_list hubleaf_conf_list;
rb_dlink_list server_conf_list;
rb_dlink_list xline_conf_list;
rb_dlink_list resv_conf_list; /* nicks only! */
rb_dlink_list nd_list; /* nick delay */
rb_dlink_list tgchange_list;
rb_dlink_list vhost_conf_list;
rb_patricia_tree_t *tgchange_tree;
static rb_bh *nd_heap = NULL;
static void expire_temp_rxlines(void *unused);
static void expire_nd_entries(void *unused);
struct ev_entry *expire_nd_entries_ev = NULL;
struct ev_entry *expire_temp_rxlines_ev = NULL;
void
init_s_newconf(void)
{
tgchange_tree = rb_new_patricia(PATRICIA_BITS);
nd_heap = rb_bh_create(sizeof(struct nd_entry), ND_HEAP_SIZE, "nd_heap");
expire_nd_entries_ev = rb_event_addish("expire_nd_entries", expire_nd_entries, NULL, 30);
expire_temp_rxlines_ev = rb_event_addish("expire_temp_rxlines", expire_temp_rxlines, NULL, 60);
}
void
clear_s_newconf(void)
{
struct server_conf *server_p;
rb_dlink_node *ptr;
rb_dlink_node *next_ptr;
RB_DLINK_FOREACH_SAFE(ptr, next_ptr, shared_conf_list.head)
{
/* ptr here is ptr->data->node */
rb_dlinkDelete(ptr, &shared_conf_list);
free_remote_conf(ptr->data);
}
RB_DLINK_FOREACH_SAFE(ptr, next_ptr, cluster_conf_list.head)
{
rb_dlinkDelete(ptr, &cluster_conf_list);
free_remote_conf(ptr->data);
}
RB_DLINK_FOREACH_SAFE(ptr, next_ptr, hubleaf_conf_list.head)
{
rb_dlinkDelete(ptr, &hubleaf_conf_list);
free_remote_conf(ptr->data);
}
RB_DLINK_FOREACH_SAFE(ptr, next_ptr, oper_conf_list.head)
{
free_oper_conf(ptr->data);
rb_dlinkDestroy(ptr, &oper_conf_list);
}
RB_DLINK_FOREACH_SAFE(ptr, next_ptr, server_conf_list.head)
{
server_p = ptr->data;
if(!server_p->servers)
{
rb_dlinkDelete(ptr, &server_conf_list);
free_server_conf(ptr->data);
}
else
server_p->flags |= SERVER_ILLEGAL;
}
}
void
clear_s_newconf_bans(void)
{
struct ConfItem *aconf;
rb_dlink_node *ptr, *next_ptr;
RB_DLINK_FOREACH_SAFE(ptr, next_ptr, xline_conf_list.head)
{
aconf = ptr->data;
if(aconf->hold)
continue;
free_conf(aconf);
rb_dlinkDestroy(ptr, &xline_conf_list);
}
RB_DLINK_FOREACH_SAFE(ptr, next_ptr, resv_conf_list.head)
{
aconf = ptr->data;
/* temporary resv */
if(aconf->hold)
continue;
free_conf(aconf);
rb_dlinkDestroy(ptr, &resv_conf_list);
}
clear_resv_hash();
}
struct remote_conf *
make_remote_conf(void)
{
struct remote_conf *remote_p = rb_malloc(sizeof(struct remote_conf));
return remote_p;
}
void
free_remote_conf(struct remote_conf *remote_p)
{
s_assert(remote_p != NULL);
if(remote_p == NULL)
return;
rb_free(remote_p->username);
rb_free(remote_p->host);
rb_free(remote_p->server);
rb_free(remote_p);
}
int
find_shared_conf(const char *username, const char *host,
const char *server, int flags)
{
struct remote_conf *shared_p;
rb_dlink_node *ptr;
RB_DLINK_FOREACH(ptr, shared_conf_list.head)
{
shared_p = ptr->data;
if(match(shared_p->username, username) &&
match(shared_p->host, host) &&
match(shared_p->server, server))
{
if(shared_p->flags & flags)
return YES;
else
return NO;
}
}
return NO;
}
void
propagate_generic(struct Client *source_p, const char *command,
const char *target, int cap, const char *format, ...)
{
char buffer[BUFSIZE];
va_list args;
va_start(args, format);
rb_vsnprintf(buffer, sizeof(buffer), format, args);
va_end(args);
sendto_match_servs(source_p, target, cap, NOCAPS,
"%s %s %s",
command, target, buffer);
sendto_match_servs(source_p, target, CAP_ENCAP, cap,
"ENCAP %s %s %s",
target, command, buffer);
}
void
cluster_generic(struct Client *source_p, const char *command,
int cltype, int cap, const char *format, ...)
{
char buffer[BUFSIZE];
struct remote_conf *shared_p;
va_list args;
rb_dlink_node *ptr;
va_start(args, format);
rb_vsnprintf(buffer, sizeof(buffer), format, args);
va_end(args);
RB_DLINK_FOREACH(ptr, cluster_conf_list.head)
{
shared_p = ptr->data;
if(!(shared_p->flags & cltype))
continue;
sendto_match_servs(source_p, shared_p->server, cap, NOCAPS,
"%s %s %s",
command, shared_p->server, buffer);
sendto_match_servs(source_p, shared_p->server, CAP_ENCAP, cap,
"ENCAP %s %s %s",
shared_p->server, command, buffer);
}
}
struct oper_conf *
make_oper_conf(void)
{
struct oper_conf *oper_p = rb_malloc(sizeof(struct oper_conf));
return oper_p;
}
void
free_oper_conf(struct oper_conf *oper_p)
{
s_assert(oper_p != NULL);
if(oper_p == NULL)
return;
rb_free(oper_p->username);
rb_free(oper_p->host);
rb_free(oper_p->name);
rb_free(oper_p->certfp);
if(oper_p->passwd)
{
memset(oper_p->passwd, 0, strlen(oper_p->passwd));
rb_free(oper_p->passwd);
}
#ifdef HAVE_LIBCRYPTO
rb_free(oper_p->rsa_pubkey_file);
if(oper_p->rsa_pubkey)
RSA_free(oper_p->rsa_pubkey);
#endif
rb_free(oper_p);
}
struct oper_conf *
find_oper_conf(const char *username, const char *host, const char *locip, const char *name)
{
struct oper_conf *oper_p;
struct rb_sockaddr_storage ip, cip;
char addr[HOSTLEN+1];
int bits, cbits;
rb_dlink_node *ptr;
parse_netmask(locip, &cip, &cbits);
RB_DLINK_FOREACH(ptr, oper_conf_list.head)
{
oper_p = ptr->data;
/* name/username doesnt match.. */
if(irccmp(oper_p->name, name) || !match(oper_p->username, username))
continue;
rb_strlcpy(addr, oper_p->host, sizeof(addr));
if(parse_netmask(addr, &ip, &bits) != HM_HOST)
{
if(ip.ss_family == cip.ss_family &&
comp_with_mask_sock((struct sockaddr *)&ip, (struct sockaddr *)&cip, bits))
return oper_p;
}
/* we have to compare against the host as well, because its
* valid to set a spoof to an IP, which if we only compare
* in ip form to sockhost will not necessarily match --anfl
*/
if(match(oper_p->host, host))
return oper_p;
}
return NULL;
}
struct server_conf *
make_server_conf(void)
{
struct server_conf *server_p = rb_malloc(sizeof(struct server_conf));
server_p->aftype = AF_INET;
return server_p;
}
void
free_server_conf(struct server_conf *server_p)
{
s_assert(server_p != NULL);
if(server_p == NULL)
return;
if(!EmptyString(server_p->passwd))
{
memset(server_p->passwd, 0, strlen(server_p->passwd));
rb_free(server_p->passwd);
}
if(!EmptyString(server_p->spasswd))
{
memset(server_p->spasswd, 0, strlen(server_p->spasswd));
rb_free(server_p->spasswd);
}
rb_free(server_p->name);
rb_free(server_p->host);
rb_free(server_p->class_name);
rb_free(server_p->certfp);
rb_free(server_p);
}
void
add_server_conf(struct server_conf *server_p)
{
if(EmptyString(server_p->class_name))
{
server_p->class_name = rb_strdup("default");
server_p->class = default_class;
return;
}
server_p->class = find_class(server_p->class_name);
if(server_p->class == default_class)
{
conf_report_error("Warning connect::class invalid for %s",
server_p->name);
rb_free(server_p->class_name);
server_p->class_name = rb_strdup("default");
}
if(strchr(server_p->host, '*') || strchr(server_p->host, '?'))
return;
}
struct server_conf *
find_server_conf(const char *name)
{
struct server_conf *server_p;
rb_dlink_node *ptr;
RB_DLINK_FOREACH(ptr, server_conf_list.head)
{
server_p = ptr->data;
if(ServerConfIllegal(server_p))
continue;
if(match(name, server_p->name))
return server_p;
}
return NULL;
}
void
attach_server_conf(struct Client *client_p, struct server_conf *server_p)
{
/* already have an attached conf */
if(client_p->localClient->att_sconf)
{
/* short circuit this special case :) */
if(client_p->localClient->att_sconf == server_p)
return;
detach_server_conf(client_p);
}
CurrUsers(server_p->class)++;
client_p->localClient->att_sconf = server_p;
server_p->servers++;
}
void
detach_server_conf(struct Client *client_p)
{
struct server_conf *server_p = client_p->localClient->att_sconf;
if(server_p == NULL)
return;
client_p->localClient->att_sconf = NULL;
server_p->servers--;
CurrUsers(server_p->class)--;
if(ServerConfIllegal(server_p) && !server_p->servers)
{
/* the class this one is using may need destroying too */
if(MaxUsers(server_p->class) < 0 && CurrUsers(server_p->class) <= 0)
free_class(server_p->class);
rb_dlinkDelete(&server_p->node, &server_conf_list);
free_server_conf(server_p);
}
}
void
set_server_conf_autoconn(struct Client *source_p, const char *name, int newval)
{
struct server_conf *server_p;
if((server_p = find_server_conf(name)) != NULL)
{
if(newval)
server_p->flags |= SERVER_AUTOCONN;
else
server_p->flags &= ~SERVER_AUTOCONN;
sendto_realops_snomask(SNO_GENERAL, L_ALL,
"%s has changed AUTOCONN for %s to %i",
get_oper_name(source_p), name, newval);
}
else
sendto_one_notice(source_p, ":Can't find %s", name);
}
void
disable_server_conf_autoconn(const char *name)
{
struct server_conf *server_p;
server_p = find_server_conf(name);
if(server_p != NULL && server_p->flags & SERVER_AUTOCONN)
{
server_p->flags &= ~SERVER_AUTOCONN;
sendto_realops_snomask(SNO_GENERAL, L_ALL,
"Disabling AUTOCONN for %s because of error",
name);
ilog(L_SERVER, "Disabling AUTOCONN for %s because of error",
name);
}
}
struct ConfItem *
find_xline(const char *gecos, int counter)
{
struct ConfItem *aconf;
rb_dlink_node *ptr;
RB_DLINK_FOREACH(ptr, xline_conf_list.head)
{
aconf = ptr->data;
if(match_esc(aconf->host, gecos))
{
if(counter)
aconf->port++;
return aconf;
}
}
return NULL;
}
struct ConfItem *
find_xline_mask(const char *gecos)
{
struct ConfItem *aconf;
rb_dlink_node *ptr;
RB_DLINK_FOREACH(ptr, xline_conf_list.head)
{
aconf = ptr->data;
if(!irccmp(aconf->host, gecos))
return aconf;
}
return NULL;
}
struct ConfItem *
find_nick_resv(const char *name)
{
struct ConfItem *aconf;
rb_dlink_node *ptr;
RB_DLINK_FOREACH(ptr, resv_conf_list.head)
{
aconf = ptr->data;
if(match_esc(aconf->host, name))
{
aconf->port++;
return aconf;
}
}
return NULL;
}
struct ConfItem *
find_nick_resv_mask(const char *name)
{
struct ConfItem *aconf;
rb_dlink_node *ptr;
RB_DLINK_FOREACH(ptr, resv_conf_list.head)
{
aconf = ptr->data;
if(!irccmp(aconf->host, name))
return aconf;
}
return NULL;
}
/* clean_resv_nick()
*
* inputs - nick
* outputs - 1 if nick is vaild resv, 0 otherwise
* side effects -
*/
int
clean_resv_nick(const char *nick)
{
char tmpch;
int as = 0;
int q = 0;
int ch = 0;
if(*nick == '-' || IsDigit(*nick))
return 0;
while ((tmpch = *nick++))
{
if(tmpch == '?' || tmpch == '@' || tmpch == '#')
q++;
else if(tmpch == '*')
as++;
else if(IsNickChar(tmpch))
ch++;
else
return 0;
}
if(!ch && as)
return 0;
return 1;
}
/* valid_wild_card_simple()
*
* inputs - "thing" to test
* outputs - 1 if enough wildcards, else 0
* side effects -
*/
int
valid_wild_card_simple(const char *data)
{
const char *p;
char tmpch;
int nonwild = 0;
int wild = 0;
/* check the string for minimum number of nonwildcard chars */
p = data;
while((tmpch = *p++))
{
/* found an escape, p points to the char after it, so skip
* that and move on.
*/
if(tmpch == '\\' && *p)
{
p++;
if(++nonwild >= ConfigFileEntry.min_nonwildcard_simple)
return 1;
}
else if(!IsMWildChar(tmpch))
{
/* if we have enough nonwildchars, return */
if(++nonwild >= ConfigFileEntry.min_nonwildcard_simple)
return 1;
}
else
wild++;
}
/* strings without wilds are also ok */
return wild == 0;
}
time_t
valid_temp_time(const char *p)
{
time_t result = 0;
while(*p)
{
if(IsDigit(*p))
{
result *= 10;
result += ((*p) & 0xF);
p++;
}
else
return -1;
}
if(result > (60 * 24 * 7 * 52))
result = (60 * 24 * 7 * 52);
return(result * 60);
}
/* Propagated bans are expired elsewhere. */
static void
expire_temp_rxlines(void *unused)
{
struct ConfItem *aconf;
rb_dlink_node *ptr;
rb_dlink_node *next_ptr;
int i;
HASH_WALK_SAFE(i, R_MAX, ptr, next_ptr, resvTable)
{
aconf = ptr->data;
if(aconf->lifetime != 0)
continue;
if(aconf->hold && aconf->hold <= rb_current_time())
{
if(ConfigFileEntry.tkline_expire_notices)
sendto_realops_snomask(SNO_GENERAL, L_ALL,
"Temporary RESV for [%s] expired",
aconf->host);
free_conf(aconf);
rb_dlinkDestroy(ptr, &resvTable[i]);
}
}
HASH_WALK_END
RB_DLINK_FOREACH_SAFE(ptr, next_ptr, resv_conf_list.head)
{
aconf = ptr->data;
if(aconf->lifetime != 0)
continue;
if(aconf->hold && aconf->hold <= rb_current_time())
{
if(ConfigFileEntry.tkline_expire_notices)
sendto_realops_snomask(SNO_GENERAL, L_ALL,
"Temporary RESV for [%s] expired",
aconf->host);
free_conf(aconf);
rb_dlinkDestroy(ptr, &resv_conf_list);
}
}
RB_DLINK_FOREACH_SAFE(ptr, next_ptr, xline_conf_list.head)
{
aconf = ptr->data;
if(aconf->lifetime != 0)
continue;
if(aconf->hold && aconf->hold <= rb_current_time())
{
if(ConfigFileEntry.tkline_expire_notices)
sendto_realops_snomask(SNO_GENERAL, L_ALL,
"Temporary X-line for [%s] expired",
aconf->host);
free_conf(aconf);
rb_dlinkDestroy(ptr, &xline_conf_list);
}
}
}
unsigned long
get_nd_count(void)
{
return(rb_dlink_list_length(&nd_list));
}
void
add_nd_entry(const char *name)
{
struct nd_entry *nd;
if(irc_dictionary_find(nd_dict, name) != NULL)
return;
nd = rb_bh_alloc(nd_heap);
rb_strlcpy(nd->name, name, sizeof(nd->name));
nd->expire = rb_current_time() + ConfigFileEntry.nick_delay;
/* this list is ordered */
rb_dlinkAddTail(nd, &nd->lnode, &nd_list);
irc_dictionary_add(nd_dict, nd->name, nd);
}
void
free_nd_entry(struct nd_entry *nd)
{
irc_dictionary_delete(nd_dict, nd->name);
rb_dlinkDelete(&nd->lnode, &nd_list);
rb_bh_free(nd_heap, nd);
}
void
expire_nd_entries(void *unused)
{
struct nd_entry *nd;
rb_dlink_node *ptr;
rb_dlink_node *next_ptr;
RB_DLINK_FOREACH_SAFE(ptr, next_ptr, nd_list.head)
{
nd = ptr->data;
/* this list is ordered - we can stop when we hit the first
* entry that doesnt expire..
*/
if(nd->expire > rb_current_time())
return;
free_nd_entry(nd);
}
}
void
add_tgchange(const char *host)
{
tgchange *target;
rb_patricia_node_t *pnode;
if(find_tgchange(host))
return;
target = rb_malloc(sizeof(tgchange));
pnode = make_and_lookup(tgchange_tree, host);
pnode->data = target;
target->pnode = pnode;
target->ip = rb_strdup(host);
target->expiry = rb_current_time() + (60*60*12);
rb_dlinkAdd(target, &target->node, &tgchange_list);
}
tgchange *
find_tgchange(const char *host)
{
rb_patricia_node_t *pnode;
if((pnode = rb_match_exact_string(tgchange_tree, host)))
return pnode->data;
return NULL;
}
struct vhost_conf *
find_ssl_vhost(const char *hostname)
{
struct vhost_conf *vhost_p;
rb_dlink_node *ptr;
RB_DLINK_FOREACH(ptr, vhost_conf_list.head)
{
vhost_p = ptr->data;
if(!strcmp(hostname,vhost_p->hostname))
return vhost_p;
}
return NULL;
}
struct vhost_conf *
make_vhost_conf(void)
{
struct vhost_conf *vhost_p = rb_malloc(sizeof(struct vhost_conf));
return vhost_p;
}
void
free_vhost_conf(struct vhost_conf *vhost_p)
{
s_assert(vhost_p != NULL);
if(vhost_p == NULL)
return;
rb_free(vhost_p->hostname);
rb_free(vhost_p->ssl_private_key);
rb_free(vhost_p->ssl_cert);
rb_free(vhost_p->ssl_dh_params);
rb_free(vhost_p->ssl_cipher_list);
rb_free(vhost_p);
}
// TODO: Free vhost_conf_list

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,348 +0,0 @@
/*
* charybdis: A slightly useful ircd.
* supported.c: isupport (005) numeric
*
* Copyright (C) 2006 Jilles Tjoelker
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1.Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2.Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3.The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* $Id: supported.c 3568 2007-09-09 18:59:08Z jilles $
*/
/* From the old supported.h which is
* Copyright (C) 1996-2002 Hybrid Development Team
* Copyright (C) 2002-2004 ircd-ratbox development team
*/
/*
* - from mirc's versions.txt
*
* mIRC now supports the numeric 005 tokens: CHANTYPES=# and
* PREFIX=(ohv)@%+ and can handle a dynamic set of channel and
* nick prefixes.
*
* mIRC assumes that @ is supported on all networks, any mode
* left of @ is assumed to have at least equal power to @, and
* any mode right of @ has less power.
*
* mIRC has internal support for @%+ modes.
*
* $nick() can now handle all mode letters listed in PREFIX.
*
* Also added support for CHANMODES=A,B,C,D token (not currently
* supported by any servers), which lists all modes supported
* by a channel, where:
*
* A = modes that take a parameter, and add or remove nicks
* or addresses to a list, such as +bIe for the ban,
* invite, and exception lists.
*
* B = modes that change channel settings, but which take
* a parameter when they are set and unset, such as
* +k key, and -k key.
*
* C = modes that change channel settings, but which take
* a parameter only when they are set, such as +l N,
* and -l.
*
* D = modes that change channel settings, such as +imnpst
* and take no parameters.
*
* All unknown/unlisted modes are treated as type D.
*/
#include "stdinc.h"
#include "client.h"
#include "common.h"
#include "numeric.h"
#include "ircd.h"
#include "s_conf.h"
#include "s_user.h"
#include "supported.h"
#include "chmode.h"
#include "send.h"
rb_dlink_list isupportlist;
struct isupportitem
{
const char *name;
const char *(*func)(const void *);
const void *param;
rb_dlink_node node;
};
void
add_isupport(const char *name, const char *(*func)(const void *), const void *param)
{
struct isupportitem *item;
item = rb_malloc(sizeof(struct isupportitem));
item->name = name;
item->func = func;
item->param = param;
rb_dlinkAddTail(item, &item->node, &isupportlist);
}
const void *
change_isupport(const char *name, const char *(*func)(const void *), const void *param)
{
rb_dlink_node *ptr;
struct isupportitem *item;
const void *oldvalue = NULL;
RB_DLINK_FOREACH(ptr, isupportlist.head)
{
item = ptr->data;
if (!strcmp(item->name, name))
{
oldvalue = item->param;
// item->name = name;
item->func = func;
item->param = param;
break;
}
}
return oldvalue;
}
void
delete_isupport(const char *name)
{
rb_dlink_node *ptr, *next_ptr;
struct isupportitem *item;
RB_DLINK_FOREACH_SAFE(ptr, next_ptr, isupportlist.head)
{
item = ptr->data;
if (!strcmp(item->name, name))
{
rb_dlinkDelete(ptr, &isupportlist);
rb_free(item);
}
}
}
/* XXX caching? */
void
show_isupport(struct Client *client_p)
{
rb_dlink_node *ptr;
struct isupportitem *item;
const char *value;
char buf[512];
int extra_space;
unsigned int nchars, nparams;
int l;
extra_space = strlen(client_p->name);
/* UID */
if (!MyClient(client_p) && extra_space < 9)
extra_space = 9;
/* :<me.name> 005 <nick> <params> :are supported by this server */
/* form_str(RPL_ISUPPORT) is %s :are supported by this server */
extra_space += strlen(me.name) + 1 + strlen(form_str(RPL_ISUPPORT));
nchars = extra_space;
nparams = 0;
buf[0] = '\0';
RB_DLINK_FOREACH(ptr, isupportlist.head)
{
item = ptr->data;
value = (*item->func)(item->param);
if (value == NULL)
continue;
l = strlen(item->name) + (EmptyString(value) ? 0 : 1 + strlen(value));
if (nchars + l + (nparams > 0) >= sizeof buf || nparams + 1 > 12)
{
sendto_one_numeric(client_p, RPL_ISUPPORT, form_str(RPL_ISUPPORT), buf);
nchars = extra_space;
nparams = 0;
buf[0] = '\0';
}
if (nparams > 0)
{
rb_strlcat(buf, " ", sizeof buf);
nchars++;
}
rb_strlcat(buf, item->name, sizeof buf);
if (!EmptyString(value))
{
rb_strlcat(buf, "=", sizeof buf);
rb_strlcat(buf, value, sizeof buf);
}
nchars += l;
nparams++;
}
if (nparams > 0)
sendto_one_numeric(client_p, RPL_ISUPPORT, form_str(RPL_ISUPPORT), buf);
}
const char *
isupport_intptr(const void *ptr)
{
static char buf[15];
rb_snprintf(buf, sizeof buf, "%d", *(const int *)ptr);
return buf;
}
const char *
isupport_boolean(const void *ptr)
{
return *(const int *)ptr ? "" : NULL;
}
const char *
isupport_string(const void *ptr)
{
return (const char *)ptr;
}
const char *
isupport_stringptr(const void *ptr)
{
return *(char * const *)ptr;
}
static const char *
isupport_umode(const void *ptr)
{
const char *str;
str = ptr;
return ConfigFileEntry.oper_only_umodes &
user_modes[(unsigned char)*str] ? NULL : str;
}
static const char *
isupport_chanmodes(const void *ptr)
{
static char result[80];
rb_snprintf(result, sizeof result, "%s%sbq,k,%slj,%s",
ConfigChannel.use_except ? "e" : "",
ConfigChannel.use_invex ? "I" : "",
ConfigChannel.use_forward ? "f" : "",
cflagsbuf);
return result;
}
static const char *
isupport_chantypes(const void *ptr)
{
return ConfigChannel.disable_local_channels ? "#" : "&#";
}
static const char *
isupport_chanlimit(const void *ptr)
{
static char result[30];
rb_snprintf(result, sizeof result, "%s:%i",
ConfigChannel.disable_local_channels ? "#" : "&#", ConfigChannel.max_chans_per_user);
return result;
}
static const char *
isupport_maxlist(const void *ptr)
{
static char result[30];
rb_snprintf(result, sizeof result, "bq%s%s:%i",
ConfigChannel.use_except ? "e" : "",
ConfigChannel.use_invex ? "I" : "",
ConfigChannel.max_bans);
return result;
}
static const char *
isupport_targmax(const void *ptr)
{
static char result[200];
rb_snprintf(result, sizeof result, "NAMES:1,LIST:1,KICK:1,WHOIS:1,PRIVMSG:%d,NOTICE:%d,ACCEPT:,MONITOR:",
ConfigFileEntry.max_targets,
ConfigFileEntry.max_targets);
return result;
}
static const char *
isupport_extban(const void *ptr)
{
const char *p;
static char result[200];
p = get_extban_string();
if (EmptyString(p))
return NULL;
rb_snprintf(result, sizeof result, "$,%s", p);
return result;
}
static const char *
isupport_nicklen(const void *ptr)
{
static char result[200];
rb_snprintf(result, sizeof result, "%u", ConfigFileEntry.nicklen - 1);
return result;
}
void
init_isupport(void)
{
static int maxmodes = MAXMODEPARAMS;
static int channellen = LOC_CHANNELLEN;
static int topiclen = TOPICLEN;
static int maxnicklen = NICKLEN - 1;
add_isupport("CHANTYPES", isupport_chantypes, NULL);
add_isupport("EXCEPTS", isupport_boolean, &ConfigChannel.use_except);
add_isupport("INVEX", isupport_boolean, &ConfigChannel.use_invex);
add_isupport("CHANMODES", isupport_chanmodes, NULL);
add_isupport("CHANLIMIT", isupport_chanlimit, NULL);
add_isupport("PREFIX", isupport_string, "(ov)@+");
add_isupport("MAXLIST", isupport_maxlist, NULL);
add_isupport("MODES", isupport_intptr, &maxmodes);
add_isupport("NETWORK", isupport_stringptr, &ServerInfo.network_name);
add_isupport("STATUSMSG", isupport_string, "@+");
add_isupport("CALLERID", isupport_umode, "g");
add_isupport("CASEMAPPING", isupport_string, "rfc1459");
add_isupport("NICKLEN", isupport_nicklen, NULL);
add_isupport("MAXNICKLEN", isupport_intptr, &maxnicklen);
add_isupport("CHANNELLEN", isupport_intptr, &channellen);
add_isupport("TOPICLEN", isupport_intptr, &topiclen);
add_isupport("DEAF", isupport_umode, "D");
add_isupport("TARGMAX", isupport_targmax, NULL);
add_isupport("EXTBAN", isupport_extban, NULL);
add_isupport("CLIENTVER", isupport_string, "3.0");
}

View file

@ -133,19 +133,8 @@ static void conn_plain_read_cb(rb_fde_t *fd, void *data);
static void conn_plain_read_shutdown_cb(rb_fde_t *fd, void *data);
static void mod_cmd_write_queue(mod_ctl_t * ctl, const void *data, size_t len);
static const char *remote_closed = "Remote host closed the connection";
<<<<<<< .merge_file_7dGMbH
static int ssld_ssl_ok;
static int certfp_method = RB_SSL_CERTFP_METH_CERT_SHA1;
#ifdef HAVE_LIBZ
static int ssld_zlib_ok = 1;
#else
static int ssld_zlib_ok = 0;
#endif
=======
static bool ssld_ssl_ok;
static int certfp_method = RB_SSL_CERTFP_METH_CERT_SHA1;
>>>>>>> .merge_file_Ch5lvI
static conn_t *
@ -175,18 +164,6 @@ free_conn(conn_t * conn)
{
rb_free_rawbuffer(conn->modbuf_out);
rb_free_rawbuffer(conn->plainbuf_out);
<<<<<<< .merge_file_7dGMbH
#ifdef HAVE_LIBZ
if(IsZip(conn))
{
zlib_stream_t *stream = conn->stream;
inflateEnd(&stream->instream);
deflateEnd(&stream->outstream);
rb_free(stream);
}
#endif
=======
>>>>>>> .merge_file_Ch5lvI
rb_free(conn);
}
@ -588,8 +565,6 @@ ssl_send_certfp(conn_t *conn)
uint32_to_buf(&buf[5], certfp_method);
uint32_to_buf(&buf[9], len);
mod_cmd_write_queue(conn->ctl, buf, 13 + len);
<<<<<<< .merge_file_7dGMbH
=======
}
static void
@ -600,7 +575,6 @@ ssl_send_open(conn_t *conn)
buf[0] = 'O';
uint32_to_buf(&buf[1], conn->id);
mod_cmd_write_queue(conn->ctl, buf, 5);
>>>>>>> .merge_file_Ch5lvI
}
static void
@ -612,10 +586,7 @@ ssl_process_accept_cb(rb_fde_t *F, int status, struct sockaddr *addr, rb_socklen
{
ssl_send_cipher(conn);
ssl_send_certfp(conn);
<<<<<<< .merge_file_7dGMbH
=======
ssl_send_open(conn);
>>>>>>> .merge_file_Ch5lvI
conn_mod_read_cb(conn->mod_fd, conn);
conn_plain_read_cb(conn->plain_fd, conn);
return;
@ -634,10 +605,7 @@ ssl_process_connect_cb(rb_fde_t *F, int status, void *data)
{
ssl_send_cipher(conn);
ssl_send_certfp(conn);
<<<<<<< .merge_file_7dGMbH
=======
ssl_send_open(conn);
>>>>>>> .merge_file_Ch5lvI
conn_mod_read_cb(conn->mod_fd, conn);
conn_plain_read_cb(conn->plain_fd, conn);
}
@ -724,17 +692,11 @@ process_stats(mod_ctl_t * ctl, mod_ctl_buf_t * ctlb)
if(conn == NULL)
return;
<<<<<<< .merge_file_7dGMbH
rb_snprintf(outstat, sizeof(outstat), "S %s %llu %llu %llu %llu", odata,
(unsigned long long) conn->plain_out, (unsigned long long) conn->mod_in,
(unsigned long long) conn->plain_in, (unsigned long long) conn->mod_out);
=======
snprintf(outstat, sizeof(outstat), "S %s %llu %llu %llu %llu", odata,
(unsigned long long)conn->plain_out,
(unsigned long long)conn->mod_in,
(unsigned long long)conn->plain_in,
(unsigned long long)conn->mod_out);
>>>>>>> .merge_file_Ch5lvI
conn->plain_out = 0;
conn->plain_in = 0;
conn->mod_in = 0;
@ -743,109 +705,10 @@ process_stats(mod_ctl_t * ctl, mod_ctl_buf_t * ctlb)
}
static void
<<<<<<< .merge_file_7dGMbH
change_connid(mod_ctl_t *ctl, mod_ctl_buf_t *ctlb)
{
uint32_t id = buf_to_uint32(&ctlb->buf[1]);
uint32_t newid = buf_to_uint32(&ctlb->buf[5]);
conn_t *conn = conn_find_by_id(id);
lrb_assert(conn != NULL);
if(conn == NULL)
{
uint8_t buf[256];
int len;
buf[0] = 'D';
uint32_to_buf(&buf[1], newid);
sprintf((char *) &buf[5], "connid %d does not exist", id);
len = (strlen((char *) &buf[5]) + 1) + 5;
mod_cmd_write_queue(ctl, buf, len);
return;
}
rb_dlinkDelete(&conn->node, connid_hash(conn->id));
SetZipSSL(conn);
conn->id = newid;
}
#ifdef HAVE_LIBZ
static void
zlib_process(mod_ctl_t * ctl, mod_ctl_buf_t * ctlb)
{
uint8_t level;
size_t recvqlen;
size_t hdr = (sizeof(uint8_t) * 2) + sizeof(uint32_t);
void *recvq_start;
z_stream *instream, *outstream;
conn_t *conn;
uint32_t id;
conn = make_conn(ctl, ctlb->F[0], ctlb->F[1]);
if(rb_get_type(conn->mod_fd) == RB_FD_UNKNOWN)
rb_set_type(conn->mod_fd, RB_FD_SOCKET);
if(rb_get_type(conn->plain_fd) == RB_FD_UNKNOWN)
rb_set_type(conn->plain_fd, RB_FD_SOCKET);
id = buf_to_uint32(&ctlb->buf[1]);
conn_add_id_hash(conn, id);
level = (uint8_t)ctlb->buf[5];
recvqlen = ctlb->buflen - hdr;
recvq_start = &ctlb->buf[6];
SetZip(conn);
conn->stream = rb_malloc(sizeof(zlib_stream_t));
instream = &((zlib_stream_t *) conn->stream)->instream;
outstream = &((zlib_stream_t *) conn->stream)->outstream;
instream->total_in = 0;
instream->total_out = 0;
instream->zalloc = (alloc_func) ssld_alloc;
instream->zfree = (free_func) ssld_free;
instream->data_type = Z_ASCII;
inflateInit(&((zlib_stream_t *) conn->stream)->instream);
outstream->total_in = 0;
outstream->total_out = 0;
outstream->zalloc = (alloc_func) ssld_alloc;
outstream->zfree = (free_func) ssld_free;
outstream->data_type = Z_ASCII;
if(level > 9)
level = (uint8_t) Z_DEFAULT_COMPRESSION;
deflateInit(&((zlib_stream_t *) conn->stream)->outstream, level);
if(recvqlen > 0)
common_zlib_inflate(conn, recvq_start, recvqlen);
conn_mod_read_cb(conn->mod_fd, conn);
conn_plain_read_cb(conn->plain_fd, conn);
return;
}
#endif
static void
init_prng(mod_ctl_t * ctl, mod_ctl_buf_t * ctl_buf)
{
char *path;
prng_seed_t seed_type;
seed_type = (prng_seed_t) ctl_buf->buf[1];
path = (char *) &ctl_buf->buf[2];
rb_init_prng(path, seed_type);
}
static void
=======
>>>>>>> .merge_file_Ch5lvI
ssl_new_keys(mod_ctl_t * ctl, mod_ctl_buf_t * ctl_buf)
{
char *buf;
char *cert, *key, *dhparam, *cipher_list, *hostname;
char *cert, *key, *dhparam, *cipher_list;
buf = (char *) &ctl_buf->buf[2];
cert = buf;
@ -855,11 +718,6 @@ ssl_new_keys(mod_ctl_t * ctl, mod_ctl_buf_t * ctl_buf)
dhparam = buf;
buf += strlen(dhparam) + 1;
cipher_list = buf;
<<<<<<< .merge_file_7dGMbH
buf += strlen(cipher_list) + 1;
hostname = buf;
=======
>>>>>>> .merge_file_Ch5lvI
if(strlen(key) == 0)
key = cert;
if(strlen(dhparam) == 0)
@ -867,15 +725,7 @@ ssl_new_keys(mod_ctl_t * ctl, mod_ctl_buf_t * ctl_buf)
if(strlen(cipher_list) == 0)
cipher_list = NULL;
int ret;
if(strlen(hostname) == 0) {
ret = rb_setup_ssl_server(cert, key, dhparam, cipher_list, NULL);
} else {
ret = rb_setup_ssl_server(cert, key, dhparam, cipher_list, hostname);
return;
}
if(!ret)
if(!rb_setup_ssl_server(cert, key, dhparam, cipher_list))
{
const char *invalid = "I";
mod_cmd_write_queue(ctl, invalid, strlen(invalid));
@ -883,24 +733,6 @@ ssl_new_keys(mod_ctl_t * ctl, mod_ctl_buf_t * ctl_buf)
}
}
static void
ssl_remove_ssl_vhost(mod_ctl_t * ctl, mod_ctl_buf_t * ctl_buf)
{
char *buf;
char *hostname;
buf = (char *) &ctl_buf->buf[2];
hostname = buf;
if(!rb_remove_ssl_vserver(hostname))
{
const char *invalid = "I";
mod_cmd_write_queue(ctl, invalid, strlen(invalid));
return;
}
}
static void
send_nossl_support(mod_ctl_t * ctl, mod_ctl_buf_t * ctlb)
{
@ -1013,22 +845,6 @@ mod_process_cmd_recv(mod_ctl_t * ctl)
ssl_new_keys(ctl, ctl_buf);
break;
}
<<<<<<< .merge_file_7dGMbH
case 'D':
{
if(!ssld_ssl_ok)
{
send_nossl_support(ctl, ctl_buf);
break;
}
ssl_remove_ssl_vhost(ctl, ctl_buf);
break;
}
case 'I':
init_prng(ctl, ctl_buf);
break;
=======
>>>>>>> .merge_file_Ch5lvI
case 'S':
{
process_stats(ctl, ctl_buf);
@ -1140,11 +956,7 @@ int
main(int argc, char **argv)
{
const char *s_ctlfd, *s_pipe, *s_pid;
<<<<<<< .merge_file_7dGMbH
int ctlfd, pipefd, maxfd;
=======
int ctlfd, pipefd, maxfd, x;
>>>>>>> .merge_file_Ch5lvI
maxfd = maxconn();
s_ctlfd = getenv("CTL_FD");
@ -1164,12 +976,6 @@ main(int argc, char **argv)
pipefd = atoi(s_pipe);
ppid = atoi(s_pid);
<<<<<<< .merge_file_7dGMbH
#ifndef _WIN32
int x;
=======
>>>>>>> .merge_file_Ch5lvI
for(x = 3; x < maxfd; x++)
{
if(x != ctlfd && x != pipefd)
@ -1189,18 +995,11 @@ main(int argc, char **argv)
if(x > 2)
close(x);
}
<<<<<<< .merge_file_7dGMbH
#endif
=======
>>>>>>> .merge_file_Ch5lvI
setup_signals();
rb_lib_init(NULL, NULL, NULL, 0, maxfd, 1024, 4096);
rb_init_rawbuffers(1024);
<<<<<<< .merge_file_7dGMbH
=======
rb_init_prng(NULL, RB_PRNG_DEFAULT);
>>>>>>> .merge_file_Ch5lvI
ssld_ssl_ok = rb_supports_ssl();
mod_ctl = rb_malloc(sizeof(mod_ctl_t));
mod_ctl->F = rb_open(ctlfd, RB_FD_SOCKET, "ircd control socket");
@ -1211,12 +1010,8 @@ main(int argc, char **argv)
rb_event_add("check_handshake_flood", check_handshake_flood, NULL, 10);
read_pipe_ctl(mod_ctl->F_pipe, NULL);
mod_read_ctl(mod_ctl->F, mod_ctl);
<<<<<<< .merge_file_7dGMbH
if(!ssld_zlib_ok && !ssld_ssl_ok)
=======
send_version(mod_ctl);
if(!ssld_ssl_ok)
>>>>>>> .merge_file_Ch5lvI
{
/* this is really useless... */
send_i_am_useless(mod_ctl);
@ -1225,16 +1020,11 @@ main(int argc, char **argv)
exit(1);
}
<<<<<<< .merge_file_7dGMbH
if(!ssld_zlib_ok)
send_nozlib_support(mod_ctl, NULL);
=======
send_nozlib_support(mod_ctl, NULL);
>>>>>>> .merge_file_Ch5lvI
if(!ssld_ssl_ok)
send_nossl_support(mod_ctl, NULL);
rb_lib_loop(0);
/* UNREACHABLE */
return 0;
}

View file

@ -96,9 +96,11 @@ main(int argc, char *argv[])
case 'h':
full_usage();
/* NOT REACHED */
break;
case '?':
brief_usage();
/* NOT REACHED */
break;
default:
printf("Invalid Option: -%c\n", c);
break;
@ -369,7 +371,7 @@ generate_random_salt(char *salt, int length)
return (salt);
}
static void
void
full_usage()
{
printf("mkpasswd [-m|-b|-x|-y] [-l saltlength] [-r rounds] [-s salt] [-p plaintext]\n");
@ -387,7 +389,7 @@ full_usage()
exit(0);
}
static void
void
brief_usage()
{
printf("mkpasswd - password hash generator\n");