Merge branch 'authd-framework' of github.com:charybdis-ircd/charybdis into authd-framework

This commit is contained in:
Elizabeth Myers 2016-03-27 11:50:19 -05:00
commit 66e1914beb
230 changed files with 5098 additions and 12141 deletions

9
.appveyor-build.sh Normal file
View file

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

15
.appveyor.yml Normal file
View file

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

30
.gitignore vendored
View file

@ -12,31 +12,48 @@ Makefile
.dirstamp .dirstamp
.libs .libs
authd/authd authd/authd
autom4te.cache
bandb/bandb bandb/bandb
bandb/bantool bandb/bantool
autom4te.cache
aclocal.m4
compile
config.guess
config.sub
depcomp
ltmain.sh
missing
config.log config.log
config.status config.status
configure configure
stamp-h1 stamp-h1
include/setup.h
libltdl/ libltdl/
librb/configure librb/configure
librb/include/libratbox_config.h librb/compile
librb/depcomp
librb/aclocal.m4
librb/include/librb_config.h
librb/include/librb_config.h.in
librb/include/librb-config.h librb/include/librb-config.h
librb/include/serno.h
librb/librb.pc
librb/ltmain.sh
librb/missing
librb/libratbox.pc librb/libratbox.pc
librb/libtool librb/libtool
librb/src/version.c librb/src/version.c
librb/src/version.c.last librb/src/version.c.last
scripts/*.tar.bz2 scripts/*.tar.bz2
scripts/*.tar.gz scripts/*.tar.gz
include/setup.h
include/setup.h.in
ircd/charybdis ircd/charybdis
ircd/lex.yy.c ircd/ircd_parser.c
ircd/ircd_parser.h
ircd/ircd_lexer.c
ircd/version.c ircd/version.c
ircd/version.c.last ircd/version.c.last
ircd/y.tab.h
ircd/y.tab.c
ssld/ssld ssld/ssld
wsockd/wsockd
tools/charybdis-mkpasswd tools/charybdis-mkpasswd
tools/genssl tools/genssl
tools/mkpasswd tools/mkpasswd
@ -47,6 +64,7 @@ ircd/version.c
ircd/version.c.last ircd/version.c.last
/libtool /libtool
Makefile.in Makefile.in
m4/argz.m4
m4/libtool.m4 m4/libtool.m4
m4/ltargz.m4 m4/ltargz.m4
m4/ltdl.m4 m4/ltdl.m4

View file

@ -17,5 +17,5 @@ Valeriy Yatsko <dwr@shadowircd.net> <darkwire@sellcenter.ru>
Valeriy Yatsko <dwr@shadowircd.net> <dwr@it-penza.org> Valeriy Yatsko <dwr@shadowircd.net> <dwr@it-penza.org>
William Pitcock <nenolod@dereferenced.org> <nenolod@atheme.org> William Pitcock <nenolod@dereferenced.org> <nenolod@atheme.org>
William Pitcock <nenolod@dereferenced.org> nenolod <devnull@localhost> William Pitcock <nenolod@dereferenced.org> nenolod <devnull@localhost>
Sam Dodrill <shadow.h511@gmail.com> <quora@lavabit.com> Christine Dodrill <shadow.h511@gmail.com> <quora@lavabit.com>
Sam Dodrill <shadow.h511@gmail.com> <quorawings@gmail.com> Christine Dodrill <shadow.h511@gmail.com> <quorawings@gmail.com>

View file

@ -44,9 +44,6 @@ matrix:
compiler: clang compiler: clang
env: COMPILER=clang LIBTOOLIZE=glibtoolize env: COMPILER=clang LIBTOOLIZE=glibtoolize
branches:
except:
- authd-framework
osx_image: xcode7.3 osx_image: xcode7.3

13
CREDITS
View file

@ -9,9 +9,9 @@ jilles, Jilles Tjoelker <jilles -at- stack.nl>
mr_flea, Keith Buck <mr_flea -at- esper.net> mr_flea, Keith Buck <mr_flea -at- esper.net>
kaniini, William Pitcock <nenolod -at- dereferenced.org> kaniini, William Pitcock <nenolod -at- dereferenced.org>
spb, Stephen Bennett <spb -at- attenuate.org> spb, Stephen Bennett <spb -at- attenuate.org>
The following people are also project members: The following people are also project members:
amdj, Aaron Jones <aaronmdjones -at- gmail.com> amdj, Aaron Jones <aaronmdjones -at- gmail.com>
Elizafox, Elizabeth Myers <elizabeth -at- interlinked.me> Elizafox, Elizabeth Myers <elizabeth -at- interlinked.me>
grawity, Mantas Mikulėnas <grawity -at- gmail.com> grawity, Mantas Mikulėnas <grawity -at- gmail.com>
@ -19,23 +19,24 @@ jdhore, JD Horelick <jdhore1 -at- gmail.com>
lp0, Simon Arlott <simon -at- arlott.org> lp0, Simon Arlott <simon -at- arlott.org>
mniip <mniip -at- mniip.com> mniip <mniip -at- mniip.com>
viatsko, Valerii Iatsko <dwr -at- codingbox.io> viatsko, Valerii Iatsko <dwr -at- codingbox.io>
The following people have made contributions to the Charybdis releases, The following people have made contributions to the Charybdis releases,
in nick-alphabetical order: in nick-alphabetical order:
AndroSyn, Aaron Sethman <androsyn -at- ratbox.org> AndroSyn, Aaron Sethman <androsyn -at- ratbox.org>
anfl, Lee Hardy <lee -at- leeh.co.uk> anfl, Lee Hardy <lee -at- leeh.co.uk>
beu, Elfyn McBratney <elfyn.mcbratney -at- gmail.com> beu, Elfyn McBratney <elfyn.mcbratney -at- gmail.com>
BlindSight, Matt Ullman <matt -at- airraidsirens.com>
Entrope, Michael Poole <mdpoole -at- trolius.org> Entrope, Michael Poole <mdpoole -at- trolius.org>
gxti, Michael Tharp <gxti -at- partiallystapled.com> gxti, Michael Tharp <gxti -at- partiallystapled.com>
Taros, Brett Greenham <taros -at- shadowircd.net> Taros, Brett Greenham <taros -at- shadowircd.net>
ThaPrince, Jon Christopherson <jon -at- vile.com> ThaPrince, Jon Christopherson <jon -at- vile.com>
twincest, River Tarnell <river -at- attenuate.org> twincest, River Tarnell <river -at- attenuate.org>
w00t, Robin Burchell <surreal.w00t -at- gmail.com> w00t, Robin Burchell <surreal.w00t -at- gmail.com>
For a list of contributors to ircd-ratbox, ircd-hyrbid, and ircd2.8 (the For a list of contributors to ircd-ratbox, ircd-hybrid, and ircd2.8 (the
predecessors to Charybdis), see the doc/credits-past.txt file in the Charybdis predecessors to Charybdis), see the doc/credits-past.txt file in the Charybdis
distribution. distribution.
Visit the Charybdis website at: http://www.charybdis.io Visit the Charybdis website at: http://www.charybdis.io
Visit us on IRC at: irc.freenode.net #charybdis Visit us on IRC at: irc.freenode.net #charybdis

View file

@ -9,6 +9,7 @@ endif
SUBDIRS += ircd \ SUBDIRS += ircd \
ssld \ ssld \
wsockd \
authd \ authd \
bandb \ bandb \
tools \ tools \
@ -37,3 +38,14 @@ include/serno.h:
install-data-hook: install-data-hook:
test -d ${DESTDIR}${logdir} || mkdir -p ${DESTDIR}${logdir} test -d ${DESTDIR}${logdir} || mkdir -p ${DESTDIR}${logdir}
install-exec-hook:
rm -f ${DESTDIR}${moduledir}/*.la
rm -f ${DESTDIR}${moduledir}/autoload/*.la
rm -f ${DESTDIR}${moduledir}/extensions/*.la
rm -f ${DESTDIR}${moduledir}/*.dll.a
rm -f ${DESTDIR}${moduledir}/autoload/*.dll.a
rm -f ${DESTDIR}${moduledir}/extensions/*.dll.a
clean-local:
rm -f include/serno.h

View file

@ -42,6 +42,11 @@ See LICENSE for licensing details (GPL v2).
stuff has been renamed and shuffled around to be more consistent. stuff has been renamed and shuffled around to be more consistent.
### code ### code
- irc_dictionary and irc_radixtree stuff is now in librb, prefixed accordingly.
Typedefs have been added for consistency reasons. For example, now you would
write `rb_dictionary *foo` and `RB_DICTIONARY_FOREACH`.
- C99 bools have been added. Don't use ints as simple true/false flags anymore.
Accordingly, the `YES`/`NO` and `TRUE`/`FALSE` macros have been removed.
- libratbox has been renamed to librb, as we have diverged from upstream long - libratbox has been renamed to librb, as we have diverged from upstream long
ago. ago.
- Almost all 2.8-style hashtable structures have been moved to dictionaries or - Almost all 2.8-style hashtable structures have been moved to dictionaries or

View file

@ -1,4 +1,4 @@
# charybdis [![Build Status](https://travis-ci.org/charybdis-ircd/charybdis.svg?branch=master)](https://travis-ci.org/charybdis-ircd/charybdis) # charybdis [![POSIX Build Status](https://travis-ci.org/charybdis-ircd/charybdis.svg?branch=master)](https://travis-ci.org/charybdis-ircd/charybdis) [![Windows Build Status](https://ci.appveyor.com/api/projects/status/is0obsml8xyq2qk7/branch/master?svg=true)](https://ci.appveyor.com/project/kaniini/charybdis/branch/master)
Charybdis is an IRCv3 server designed to be highly scalable. It implements IRCv3.1 and some parts of IRCv3.2. Charybdis is an IRCv3 server designed to be highly scalable. It implements IRCv3.1 and some parts of IRCv3.2.
@ -10,8 +10,52 @@ It is meant to be used with an IRCv3-capable services implementation such as [At
# necessary requirements # necessary requirements
* A supported platform * A supported platform
* A working dynamic load library. * A working dynamic library system
* A working lex. Solaris /usr/ccs/bin/lex appears to be broken, on this system flex should be used. * A working lex and yacc - flex and bison should work
# platforms
Charybdis is designed with portability in mind, but does not target older systems nor those of solely academic
interest.
Do note that operating systems are only supported if they are supported by their vendor.
## Tier 1
These platforms are the best supported, and should always work. They are actively tested. If you encounter
problems, please file a bug.
* FreeBSD 10.x and above (i386 and amd64)
* Linux 2.6.x and above with glibc or musl (i386, x86_64, and ARM)
* Mac OS X 10.7 and above
* Windows Vista/Server 2008 and above (x86 or x64)
## Tier 2
These platforms are supported and occasionally tested, and most features should work, but this is not
guaranteed. If you find any problems, file a bug, but as these are not regularly tested platforms, a timely
resolution may not be possible.
* DragonflyBSD 4.4 and above (i386)
* Linux with uClibc (i386 or x86_64)
* NetBSD 6.1.x and above (i386, amd64)
* OpenBSD 5.6 and above (i386, amd64)
* Solaris 10 and above (i386)
## Tier 3
Anything else that hasn't been tested. Charybdis may or may not work on it; patches welcome if they don't.
# platform specific errata
These are known issues and workarounds for supported platforms.
* **FreeBSD**: if you are compiling with ipv6 you may experience
problems with ipv4 due to the way the socket code is written. To
fix this you must: "sysctl net.inet6.ip6.v6only=0"
* **Solaris**: you may have to set your PATH to include /usr/gnu/bin and /usr/gnu/sbin before /usr/bin
and /usr/sbin. Solaris's default tools don't seem to play nicely with the configure script.
# building from git # building from git
@ -31,9 +75,8 @@ You will need to run `autogen.sh` to build the autotools files prior to building
(Using CHALLENGE is not recommended for new deployments, so if you want to use a different TLS library, (Using CHALLENGE is not recommended for new deployments, so if you want to use a different TLS library,
feel free.) feel free.)
* For ECDHE, OpenSSL 1.0.0 or newer is required. RHEL/Fedora and derivatives like CentOS * For ECDHE, OpenSSL 1.0.0 or newer is required. Solaris; and RHEL/Fedora and its derivatives such as CentOS
will need to compile OpenSSL from source, as ECC/ECDHE-functionality is removed from have removed support for ECC/ECDHE. You will need to compile your own OpenSSL on these systems.
the OpenSSL package in these distributions.
# tips # tips
@ -41,31 +84,10 @@ You will need to run `autogen.sh` to build the autotools files prior to building
* Please read doc/index.txt to get an overview of the current documentation. * Please read doc/index.txt to get an overview of the current documentation.
* Read the NEWS file for what's new in this release.
* The files, /etc/services, /etc/protocols, and /etc/resolv.conf, SHOULD be * The files, /etc/services, /etc/protocols, and /etc/resolv.conf, SHOULD be
readable by the user running the server in order for ircd to start with readable by the user running the server in order for ircd to start with
the correct settings. If these files are wrong, charybdis will try to use the correct settings. If these files are wrong, charybdis will try to use
127.0.0.1 for a resolver as a last-ditch effort. 127.0.0.1 for a resolver as a last-ditch effort.
* FREEBSD USERS: if you are compiling with ipv6 you may experience
problems with ipv4 due to the way the socket code is written. To
fix this you must: "sysctl net.inet6.ip6.v6only=0"
* SOLARIS USERS: this code appears to tickle a bug in older gcc and
egcs ONLY on 64-bit Solaris7. gcc-2.95 and SunPro C on 64bit should
work fine, and any gcc or SunPro compiled on 32bit.
* SUPPORTED PLATFORMS: this code should compile without any warnings on:
* FreeBSD 10
* Gentoo & Gentoo Hardened ~x86/~amd64/~fbsd
* RHEL 6 / 7
* Debian Jessie
* OpenSuSE 11/12
* OpenSolaris 2008.x?
* Solaris 10 sparc.
Please let us know if you find otherwise. It may work on other platforms, but this is not guaranteed.
* Please read NEWS for information about what is in this release.
* Other files recommended for reading: BUGS, INSTALL

1221
aclocal.m4 vendored

File diff suppressed because it is too large Load diff

View file

@ -2,13 +2,18 @@ pkglibexec_PROGRAMS = authd
AM_CFLAGS=$(WARNFLAGS) AM_CFLAGS=$(WARNFLAGS)
AM_CPPFLAGS = -I../include -I../librb/include AM_CPPFLAGS = -I../include -I../librb/include
authd_SOURCES = \
authd_SOURCES = provider.c \ authd.c \
authd.c \ dns.c \
res.c \ getaddrinfo.c \
reslib.c \ getnameinfo.c \
dns.c \ notice.c \
providers/rdns.c \ provider.c \
providers/ident.c res.c \
reslib.c \
reslist.c \
providers/blacklist.c \
providers/ident.c \
providers/rdns.c
authd_LDADD = ../librb/src/librb.la authd_LDADD = ../librb/src/librb.la

View file

@ -21,17 +21,21 @@
#include "authd.h" #include "authd.h"
#include "dns.h" #include "dns.h"
#include "provider.h" #include "provider.h"
#include "notice.h"
#define MAXPARA 10 #define MAXPARA 10
static void handle_reload(int parc, char *parv[]); static void handle_reload(int parc, char *parv[]);
static void handle_stat(int parc, char *parv[]); static void handle_stat(int parc, char *parv[]);
static void handle_options(int parc, char *parv[]);
rb_helper *authd_helper = NULL; rb_helper *authd_helper = NULL;
authd_cmd_handler authd_cmd_handlers[256] = { authd_cmd_handler authd_cmd_handlers[256] = {
['C'] = handle_new_connection, ['C'] = handle_new_connection,
['D'] = resolve_dns, ['D'] = handle_resolve_dns,
['H'] = handle_reload, ['E'] = handle_cancel_connection,
['O'] = handle_options,
['R'] = handle_reload,
['S'] = handle_stat, ['S'] = handle_stat,
}; };
@ -43,31 +47,69 @@ authd_reload_handler authd_reload_handlers[256] = {
['D'] = reload_nameservers, ['D'] = reload_nameservers,
}; };
rb_dictionary *authd_option_handlers;
static void static void
handle_stat(int parc, char *parv[]) handle_stat(int parc, char *parv[])
{ {
authd_stat_handler handler; authd_stat_handler handler;
if(parc < 3) if(parc < 3)
/* XXX Should log this somehow */ {
warn_opers(L_CRIT, "BUG: handle_stat received too few parameters (at least 3 expected, got %d)", parc);
return; return;
}
if (!(handler = authd_stat_handlers[parv[2][0]])) if (!(handler = authd_stat_handlers[(unsigned char)parv[2][0]]))
return; return;
handler(parv[1], parv[2][0]); handler(parv[1], parv[2][0]);
} }
static void
handle_options(int parc, char *parv[])
{
struct auth_opts_handler *handler;
if(parc < 4)
{
warn_opers(L_CRIT, "BUG: handle_options received too few parameters (at least 4 expected, got %d)", parc);
return;
}
if((handler = rb_dictionary_retrieve(authd_option_handlers, parv[1])) == NULL)
{
warn_opers(L_CRIT, "BUG: handle_options got a bad option type %s", parv[1]);
return;
}
if((parc - 2) < handler->min_parc)
{
warn_opers(L_CRIT, "BUG: handle_options received too few parameters (at least %d expected, got %d)", handler->min_parc, parc);
return;
}
handler->handler(parv[1], parc - 2, (const char **)&parv[2]);
}
static void static void
handle_reload(int parc, char *parv[]) handle_reload(int parc, char *parv[])
{ {
authd_reload_handler handler; authd_reload_handler handler;
if(parc < 2) if(parc < 2)
/* XXX Should log this somehow */ {
return; /* Reload all handlers */
for(size_t i = 0; i < 256; i++)
{
if ((handler = authd_reload_handlers[(unsigned char) i]) != NULL)
handler(parv[1][0]);
}
if (!(handler = authd_reload_handlers[parv[1][0]])) return;
}
if (!(handler = authd_reload_handlers[(unsigned char)parv[1][0]]))
return; return;
handler(parv[1][0]); handler(parv[1][0]);
@ -89,7 +131,7 @@ parse_request(rb_helper *helper)
if(parc < 1) if(parc < 1)
continue; continue;
handler = authd_cmd_handlers[parv[0][0]]; handler = authd_cmd_handlers[(unsigned char)parv[0][0]];
if (handler != NULL) if (handler != NULL)
handler(parc, parv); handler(parc, parv);
} }
@ -101,7 +143,7 @@ error_cb(rb_helper *helper)
exit(1); exit(1);
} }
#ifndef WINDOWS #ifndef _WIN32
static void static void
dummy_handler(int sig) dummy_handler(int sig)
{ {
@ -112,7 +154,7 @@ dummy_handler(int sig)
static void static void
setup_signals(void) setup_signals(void)
{ {
#ifndef WINDOWS #ifndef _WIN32
struct sigaction act; struct sigaction act;
act.sa_flags = 0; act.sa_flags = 0;
@ -152,11 +194,16 @@ main(int argc, char *argv[])
rb_set_time(); rb_set_time();
setup_signals(); setup_signals();
authd_option_handlers = rb_dictionary_create("authd options handlers", strcasecmp);
init_resolver(); init_resolver();
init_providers(); init_providers();
rb_init_prng(NULL, RB_PRNG_DEFAULT); rb_init_prng(NULL, RB_PRNG_DEFAULT);
rb_helper_loop(authd_helper, 0); rb_helper_loop(authd_helper, 0);
destroy_providers();
return 0; return 0;
} }

View file

@ -21,11 +21,21 @@
#ifndef _AUTHD_H #ifndef _AUTHD_H
#define _AUTHD_H #define _AUTHD_H
#include <rb_lib.h> #include "stdinc.h"
#include <stdio.h> #include "rb_lib.h"
#include "rb_dictionary.h"
#include "setup.h" #include "setup.h"
#include "common.h" #include "ircd_defs.h"
typedef void (*provider_opts_handler_t)(const char *, int, const char **);
struct auth_opts_handler
{
const char *option;
int min_parc;
provider_opts_handler_t handler;
};
extern rb_helper *authd_helper; extern rb_helper *authd_helper;
@ -37,4 +47,6 @@ extern authd_cmd_handler authd_cmd_handlers[256];
extern authd_stat_handler authd_stat_handlers[256]; extern authd_stat_handler authd_stat_handlers[256];
extern authd_reload_handler authd_reload_handlers[256]; extern authd_reload_handler authd_reload_handlers[256];
extern rb_dictionary *authd_option_handlers;
#endif #endif

View file

@ -1,4 +1,4 @@
/* authd/dns.h - header for authd DNS functions /* authd/dns.c - authd DNS functions
* Copyright (c) 2016 William Pitcock <nenolod@dereferenced.org> * Copyright (c) 2016 William Pitcock <nenolod@dereferenced.org>
* *
* Permission to use, copy, modify, and/or distribute this software for any * Permission to use, copy, modify, and/or distribute this software for any
@ -22,140 +22,238 @@
#include "dns.h" #include "dns.h"
#include "res.h" #include "res.h"
void static void handle_lookup_ip_reply(void *data, struct DNSReply *reply);
format_address(struct rb_sockaddr_storage *addr, char *buffer, size_t length) static void handle_lookup_hostname_reply(void *data, struct DNSReply *reply);
uint64_t query_count = 0;
/* A bit different from ircd... you just get a dns_query object.
*
* It gets freed whenever the res code gets back to us.
*/
struct dns_query *
lookup_ip(const char *host, int aftype, DNSCB callback, void *data)
{ {
if(GET_SS_FAMILY(addr) == AF_INET) struct dns_query *query = rb_malloc(sizeof(struct dns_query));
int g_type;
if(aftype == AF_INET)
{ {
rb_inet_ntop_sock((struct sockaddr *)addr, buffer, length); query->type = QUERY_A;
g_type = T_A;
} }
#ifdef RB_IPV6 #ifdef RB_IPV6
else if(GET_SS_FAMILY(addr) == AF_INET6) else if(aftype == AF_INET6)
{ {
char tmpbuf[length]; query->type = QUERY_AAAA;
g_type = T_AAAA;
rb_inet_ntop_sock((struct sockaddr *)addr, tmpbuf, length);
if(*tmpbuf == ':')
{
rb_strlcpy(buffer, "0", length);
rb_strlcat(buffer, tmpbuf, length);
}
else
rb_strlcpy(buffer, tmpbuf, length);
} }
#endif #endif
else
{
rb_free(query);
return NULL;
}
query->id = query_count++;
query->callback = callback;
query->data = data;
query->query.ptr = query;
query->query.callback = handle_lookup_ip_reply;
gethost_byname_type(host, &query->query, g_type);
return query;
} }
bool /* See lookup_ip's comment */
sockcmp(struct rb_sockaddr_storage *addr, struct rb_sockaddr_storage *addr2, int family) struct dns_query *
lookup_hostname(const char *ip, DNSCB callback, void *data)
{ {
if(family == AF_INET) struct dns_query *query = rb_malloc(sizeof(struct dns_query));
{ int aftype;
struct sockaddr_in *ip, *ip2;
ip = (struct sockaddr_in *)addr;
ip2 = (struct sockaddr_in *)addr2;
return ip->sin_addr.s_addr == ip2->sin_addr.s_addr; if(!rb_inet_pton_sock(ip, (struct sockaddr *)&query->addr))
{
rb_free(query);
return NULL;
}
aftype = GET_SS_FAMILY(&query->addr);
if(aftype == AF_INET)
query->type = QUERY_PTR_A;
#ifdef RB_IPV6
else if(aftype == AF_INET6)
query->type = QUERY_PTR_AAAA;
#endif
else
{
rb_free(query);
return NULL;
}
query->id = query_count++;
query->callback = callback;
query->data = data;
query->query.ptr = query;
query->query.callback = handle_lookup_hostname_reply;
gethost_byaddr(&query->addr, &query->query);
return query;
}
/* Cancel a pending query */
void
cancel_query(struct dns_query *query)
{
query->callback = query->data = NULL;
}
/* Callback from gethost_byname_type */
static void
handle_lookup_ip_reply(void *data, struct DNSReply *reply)
{
struct dns_query *query = data;
char ip[64] = "*";
if(query == NULL)
/* Shouldn't happen */
exit(2);
if(reply == NULL)
goto end;
switch(query->type)
{
case QUERY_A:
if(GET_SS_FAMILY(&reply->addr) == AF_INET)
rb_inet_ntop_sock((struct sockaddr *)&reply->addr, ip, sizeof(ip));
break;
#ifdef RB_IPV6
case QUERY_AAAA:
if(GET_SS_FAMILY(&reply->addr) == AF_INET6)
{
rb_inet_ntop_sock((struct sockaddr *)&reply->addr, ip, sizeof(ip));
if(ip[0] == ':')
{
memmove(&ip[1], ip, strlen(ip));
ip[0] = '0';
}
}
break;
#endif
default:
exit(3);
}
end:
if(query->callback)
query->callback(ip, ip[0] != '*', query->type, query->data);
rb_free(query);
}
/* Callback from gethost_byaddr */
static void
handle_lookup_hostname_reply(void *data, struct DNSReply *reply)
{
struct dns_query *query = data;
char *hostname = NULL;
if(query == NULL)
/* Shouldn't happen */
exit(4);
if(reply == NULL)
goto end;
if(query->type == QUERY_PTR_A)
{
struct sockaddr_in *ip, *ip_fwd;
ip = (struct sockaddr_in *) &query->addr;
ip_fwd = (struct sockaddr_in *) &reply->addr;
if(ip->sin_addr.s_addr == ip_fwd->sin_addr.s_addr)
hostname = reply->h_name;
} }
#ifdef RB_IPV6 #ifdef RB_IPV6
else if(family == AF_INET6) else if(query->type == QUERY_PTR_AAAA)
{ {
struct sockaddr_in6 *ip, *ip2; struct sockaddr_in6 *ip, *ip_fwd;
ip = (struct sockaddr_in6 *) addr; ip = (struct sockaddr_in6 *) &query->addr;
ip2 = (struct sockaddr_in6 *) addr2; ip_fwd = (struct sockaddr_in6 *) &reply->addr;
return(memcmp(&ip->sin6_addr, &ip2->sin6_addr, sizeof(struct in6_addr)) == 0); if(memcmp(&ip->sin6_addr, &ip_fwd->sin6_addr, sizeof(struct in6_addr)) == 0)
hostname = reply->h_name;
} }
#endif #endif
else
/* Shouldn't happen */
exit(5);
end:
if(query->callback)
query->callback(hostname, hostname != NULL, query->type, query->data);
return false; rb_free(query);
} }
static void static void
submit_dns_answer(void *userdata, struct DNSReply *reply) submit_dns_answer(const char *reply, bool status, query_type type, void *data)
{ {
struct dns_request *req = userdata; char *id = data;
char response[64] = "*";
char status = 'E';
int family = AF_INET;
if (reply == NULL) if(!id || type == QUERY_INVALID)
exit(6);
if(reply == NULL || status == false)
{ {
rb_helper_write(authd_helper, "E %s E %c *", req->reqid, req->type); rb_helper_write(authd_helper, "E %s E %c *", id, type);
goto cleanup; rb_free(id);
return;
} }
switch (req->type) rb_helper_write(authd_helper, "E %s O %c %s", id, type, reply);
rb_free(id);
}
void
handle_resolve_dns(int parc, char *parv[])
{
char *id = rb_strdup(parv[1]);
char qtype = *parv[2];
char *record = parv[3];
int aftype = AF_INET;
switch(qtype)
{ {
case '4':
#ifdef RB_IPV6 #ifdef RB_IPV6
case '6': case '6':
format_address(&reply->addr, response, sizeof(response)); aftype = AF_INET6;
break;
#endif #endif
case '4':
if(!lookup_ip(record, aftype, submit_dns_answer, id))
submit_dns_answer(NULL, false, qtype, NULL);
break;
#ifdef RB_IPV6 #ifdef RB_IPV6
case 'S': case 'S':
family = AF_INET6;
#endif #endif
case 'R': case 'R':
if(sockcmp(&req->addr, &reply->addr, family) && strlen(reply->h_name) < 63) if(!lookup_hostname(record, submit_dns_answer, id))
{ submit_dns_answer(NULL, false, qtype, NULL);
rb_strlcpy(response, reply->h_name, sizeof(response));
status = 'O';
}
break; break;
default: default:
exit(7); exit(7);
} }
rb_helper_write(authd_helper, "E %s %c %c %s", req->reqid, status, req->type, response);
cleanup:
rb_free(req);
}
void
resolve_dns(int parc, char *parv[])
{
struct dns_request *req;
char *requestid = parv[1];
char *qtype = parv[2];
char *rec = parv[3];
int type;
req = rb_malloc(sizeof(*req));
rb_strlcpy(req->reqid, requestid, sizeof(req->reqid));
req->type = *qtype;
switch (req->type)
{
case '4':
type = T_A;
break;
case '6':
type = T_AAAA;
break;
case 'R':
case 'S':
if(!rb_inet_pton_sock(rec, (struct sockaddr *) &req->addr))
exit(6);
type = T_PTR;
break;
}
req->query.ptr = req;
req->query.callback = submit_dns_answer;
if (type != T_PTR)
gethost_byname_type(rec, &req->query, type);
else
gethost_byaddr(&req->addr, &req->query);
} }
void void
enumerate_nameservers(const char *rid, const char letter) enumerate_nameservers(const char *rid, const char letter)
{ {
char buf[40 * IRCD_MAXNS]; /* Plenty */ char buf[(HOSTIPLEN + 1) * IRCD_MAXNS];
char *c = buf; char *c = buf;
int i; int i;
@ -168,8 +266,7 @@ enumerate_nameservers(const char *rid, const char letter)
for(i = 0; i < irc_nscount; i++) for(i = 0; i < irc_nscount; i++)
{ {
char addr[40]; char addr[HOSTIPLEN];
int ret;
rb_inet_ntop_sock((struct sockaddr *)&irc_nsaddr_list[i], addr, sizeof(addr)); rb_inet_ntop_sock((struct sockaddr *)&irc_nsaddr_list[i], addr, sizeof(addr));
@ -180,8 +277,8 @@ enumerate_nameservers(const char *rid, const char letter)
return; return;
} }
ret = snprintf(c, 40, "%s ", addr); (void)snprintf(c, HOSTIPLEN + 1, "%s ", addr);
c += (size_t)ret; c += strlen(addr) + 1;
} }
*(--c) = '\0'; *(--c) = '\0';

View file

@ -27,17 +27,34 @@
#include "res.h" #include "res.h"
#include "reslib.h" #include "reslib.h"
struct dns_request typedef enum
{
QUERY_INVALID = 0,
QUERY_A = '4',
QUERY_AAAA = '6',
QUERY_PTR_A = 'R',
QUERY_PTR_AAAA = 'S',
} query_type;
/* Similar to that in ircd */
typedef void (*DNSCB)(const char *res, bool status, query_type type, void *data);
struct dns_query
{ {
struct DNSQuery query; struct DNSQuery query;
char reqid[DNS_REQ_IDLEN]; query_type type;
struct rb_sockaddr_storage addr; struct rb_sockaddr_storage addr;
char type; uint64_t id;
DNSCB callback;
void *data;
}; };
extern void format_address(struct rb_sockaddr_storage *addr, char *buffer, size_t length); extern struct dns_query *lookup_hostname(const char *ip, DNSCB callback, void *data);
extern bool sockcmp(struct rb_sockaddr_storage *addr, struct rb_sockaddr_storage *addr2, int family); extern struct dns_query *lookup_ip(const char *host, int aftype, DNSCB callback, void *data);
extern void resolve_dns(int parc, char *parv[]); extern void cancel_query(struct dns_query *query);
extern void handle_resolve_dns(int parc, char *parv[]);
extern void enumerate_nameservers(const char *rid, const char letter); extern void enumerate_nameservers(const char *rid, const char letter);
extern void reload_nameservers(const char letter); extern void reload_nameservers(const char letter);

617
authd/getaddrinfo.c Normal file
View file

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

127
authd/getaddrinfo.h Normal file
View file

@ -0,0 +1,127 @@
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
struct rb_addrinfo {
int ai_flags;
int ai_family;
int ai_socktype;
int ai_protocol;
size_t ai_addrlen;
char *ai_canonname;
struct sockaddr *ai_addr;
struct rb_addrinfo *ai_next;
};
#ifndef AI_PASSIVE
#define AI_PASSIVE 0x00000001 /* get address to use bind() */
#endif /* AI_PASSIVE */
#ifndef AI_NUMERICHOST
#define AI_NUMERICHOST 0x00000004 /* prevent name resolution */
#endif /* AI_NUMERICHOST */
#ifndef EAI_FAIL
#define EAI_FAIL 4 /* non-recoverable failure in name resolution */
#endif /* EAI_FAIL */
#ifndef EAI_FAMILY
#define EAI_FAMILY 5 /* ai_family not supported */
#endif /* EAI_FAMILY */
#ifndef EAI_MEMORY
#define EAI_MEMORY 6 /* memory allocation failure */
#endif /* EAI_MEMORY */
#ifndef EAI_NONAME
#define EAI_NONAME 8 /* hostname nor servname provided, or not known */
#endif /* EAI_NONAME */
#ifndef EAI_SYSTEM
#define EAI_SYSTEM 11 /* system error returned in errno */
#endif /* EAI_SYSTEM */
#ifndef NI_NUMERICHOST
#define NI_NUMERICHOST 0x00000002
#endif /* NI_NUMERICHOST */
#ifndef NI_NAMEREQD
#define NI_NAMEREQD 0x00000004
#endif /* NI_NAMEREQD */
#ifndef NI_NUMERICSERV
#define NI_NUMERICSERV 0x00000008
#endif /* NI_NUMERICSERV */
#ifndef NI_DGRAM
#define NI_DGRAM 0x00000010
#endif /* NI_DGRAM */
#ifndef INADDR_NONE
#define INADDR_NONE ((unsigned int) 0xffffffff)
#endif /* INADDR_NONE */
int rb_getaddrinfo(const char *hostname, const char *servname,
const struct rb_addrinfo *hints, struct rb_addrinfo **res);
void rb_freeaddrinfo(struct rb_addrinfo *ai);
#define SUCCESS 0
#define ANY 0
#undef EAI_ADDRFAMILY
#undef EAI_AGAIN
#undef EAI_BADFLAGS
#undef EAI_FAIL
#undef EAI_FAMILY
#undef EAI_MEMORY
#undef EAI_NODATA
#undef EAI_NONAME
#undef EAI_SERVICE
#undef EAI_SOCKTYPE
#undef EAI_SYSTEM
#undef EAI_BADHINTS
#undef EAI_PROTOCOL
#undef EAI_MAX
#undef AI_MASK
#define EAI_ADDRFAMILY 1 /* address family for hostname not supported */
#define EAI_AGAIN 2 /* temporary failure in name resolution */
#define EAI_BADFLAGS 3 /* invalid value for ai_flags */
#define EAI_FAIL 4 /* non-recoverable failure in name resolution */
#define EAI_FAMILY 5 /* ai_family not supported */
#define EAI_MEMORY 6 /* memory allocation failure */
#define EAI_NODATA 7 /* no address associated with hostname */
#define EAI_NONAME 8 /* hostname nor servname provided, or not known */
#define EAI_SERVICE 9 /* servname not supported for ai_socktype */
#define EAI_SOCKTYPE 10 /* ai_socktype not supported */
#define EAI_SYSTEM 11 /* system error returned in errno */
#define EAI_BADHINTS 12
#define EAI_PROTOCOL 13
#define EAI_MAX 14
#define AI_MASK (AI_PASSIVE | AI_NUMERICHOST)

240
authd/getnameinfo.c Normal file
View file

@ -0,0 +1,240 @@
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* Issues to be discussed:
* - Thread safe-ness must be checked
* - RFC2553 says that we should raise error on short buffer. X/Open says
* we need to truncate the result. We obey RFC2553 (and X/Open should be
* modified). ipngwg rough consensus seems to follow RFC2553.
* - What is "local" in NI_FQDN?
* - NI_NAMEREQD and NI_NUMERICHOST conflict with each other.
* - (KAME extension) always attach textual scopeid (fe80::1%lo0), if
* sin6_scope_id is filled - standardization status?
* XXX breaks backward compat for code that expects no scopeid.
* beware on merge.
*/
#ifdef _WIN32
#include <rb_lib.h>
#include "getaddrinfo.h"
#include "getnameinfo.h"
static const struct afd {
int a_af;
int a_addrlen;
rb_socklen_t a_socklen;
int a_off;
} afdl [] = {
#ifdef IPV6
{PF_INET6, sizeof(struct in6_addr), sizeof(struct sockaddr_in6),
offsetof(struct sockaddr_in6, sin6_addr)},
#endif
{PF_INET, sizeof(struct in_addr), sizeof(struct sockaddr_in),
offsetof(struct sockaddr_in, sin_addr)},
{0, 0, 0, 0},
};
struct sockinet
{
unsigned char si_len;
unsigned char si_family;
unsigned short si_port;
};
#ifdef IPV6
static int ip6_parsenumeric(const struct sockaddr *, const char *, char *,
size_t, int);
#endif
int
rb_getnameinfo(const struct sockaddr *sa, rb_socklen_t salen, char *host,
size_t hostlen, char *serv, size_t servlen, int flags)
{
const struct afd *afd;
struct servent *sp;
unsigned short port;
int family, i;
const char *addr;
uint32_t v4a;
char numserv[512];
char numaddr[512];
if (sa == NULL)
return EAI_FAIL;
/* if (sa->sa_len != salen)
return EAI_FAIL;
*/
family = sa->sa_family;
for (i = 0; afdl[i].a_af; i++)
if (afdl[i].a_af == family) {
afd = &afdl[i];
goto found;
}
return EAI_FAMILY;
found:
if (salen != afd->a_socklen)
return EAI_FAIL;
/* network byte order */
port = ((const struct sockinet *)sa)->si_port;
addr = (const char *)sa + afd->a_off;
if (serv == NULL || servlen == 0) {
/*
* do nothing in this case.
* in case you are wondering if "&&" is more correct than
* "||" here: rfc2553bis-03 says that serv == NULL OR
* servlen == 0 means that the caller does not want the result.
*/
} else {
if (flags & NI_NUMERICSERV)
sp = NULL;
else {
sp = getservbyport(port,
(flags & NI_DGRAM) ? "udp" : "tcp");
}
if (sp) {
if (strlen(sp->s_name) + 1 > servlen)
return EAI_MEMORY;
rb_strlcpy(serv, sp->s_name, servlen);
} else {
snprintf(numserv, sizeof(numserv), "%u", ntohs(port));
if (strlen(numserv) + 1 > servlen)
return EAI_MEMORY;
rb_strlcpy(serv, numserv, servlen);
}
}
switch (sa->sa_family) {
case AF_INET:
v4a = (uint32_t)
ntohl(((const struct sockaddr_in *)sa)->sin_addr.s_addr);
if (IN_MULTICAST(v4a) || IN_EXPERIMENTAL(v4a))
flags |= NI_NUMERICHOST;
v4a >>= IN_CLASSA_NSHIFT;
if (v4a == 0)
flags |= NI_NUMERICHOST;
break;
#ifdef IPV6
case AF_INET6:
{
const struct sockaddr_in6 *sin6;
sin6 = (const struct sockaddr_in6 *)sa;
switch (sin6->sin6_addr.s6_addr[0]) {
case 0x00:
if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr))
;
else if (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr))
;
else
flags |= NI_NUMERICHOST;
break;
default:
if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
flags |= NI_NUMERICHOST;
}
else if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr))
flags |= NI_NUMERICHOST;
break;
}
}
break;
#endif
}
if (host == NULL || hostlen == 0) {
/*
* do nothing in this case.
* in case you are wondering if "&&" is more correct than
* "||" here: rfc2553bis-03 says that host == NULL or
* hostlen == 0 means that the caller does not want the result.
*/
} else if (flags & NI_NUMERICHOST) {
size_t numaddrlen;
/* NUMERICHOST and NAMEREQD conflicts with each other */
if (flags & NI_NAMEREQD)
return EAI_NONAME;
switch(afd->a_af) {
#ifdef IPV6
case AF_INET6:
{
int error;
if ((error = ip6_parsenumeric(sa, addr, host,
hostlen, flags)) != 0)
return(error);
break;
}
#endif
default:
if (rb_inet_ntop(afd->a_af, addr, numaddr, sizeof(numaddr))
== NULL)
return EAI_SYSTEM;
numaddrlen = strlen(numaddr);
if (numaddrlen + 1 > hostlen) /* don't forget terminator */
return EAI_MEMORY;
rb_strlcpy(host, numaddr, hostlen);
break;
}
}
return(0);
}
#ifdef IPV6
static int
ip6_parsenumeric(const struct sockaddr *sa, const char *addr,
char *host, size_t hostlen, int flags)
{
size_t numaddrlen;
char numaddr[512];
if (rb_inet_ntop(AF_INET6, addr, numaddr, sizeof(numaddr)) == NULL)
return(EAI_SYSTEM);
numaddrlen = strlen(numaddr);
if (numaddrlen + 1 > hostlen) /* don't forget terminator */
return(EAI_MEMORY);
if (*numaddr == ':')
{
*host = '0';
rb_strlcpy(host+1, numaddr, hostlen-1);
}
else
rb_strlcpy(host, numaddr, hostlen);
return(0);
}
#endif
#endif

40
authd/getnameinfo.h Normal file
View file

@ -0,0 +1,40 @@
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
int rb_getnameinfo(const struct sockaddr *sa, rb_socklen_t salen, char *host,
size_t hostlen, char *serv, size_t servlen, int flags);
#ifndef IN_MULTICAST
#define IN_MULTICAST(a) ((((long int) (a)) & 0xf0000000) == 0xe0000000)
#endif
#ifndef IN_EXPERIMENTAL
#define IN_EXPERIMENTAL(a) ((((long int) (a)) & 0xe0000000) == 0xe0000000)
#endif

48
authd/notice.c Normal file
View file

@ -0,0 +1,48 @@
/* authd/notice.c - send notices back to the ircd and to clients
* Copyright (c) 2016 Elizabeth Myers <elizabeth@interlinked.me>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice is present in all copies.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "authd.h"
#include "notice.h"
/* Send a notice to a client */
void notice_client(uint32_t cid, const char *fmt, ...)
{
char buf[BUFSIZE];
va_list args;
va_start(args, fmt);
vsnprintf(buf, sizeof(buf), fmt, args);
va_end(args);
rb_helper_write(authd_helper, "N %x :%s", cid, buf);
}
/* Send a warning to the IRC daemon for logging, etc. */
void warn_opers(notice_level_t level, const char *fmt, ...)
{
char buf[BUFSIZE];
va_list args;
va_start(args, fmt);
vsnprintf(buf, sizeof(buf), fmt, args);
va_end(args);
rb_helper_write(authd_helper, "W %c :%s", level, buf);
}

35
authd/notice.h Normal file
View file

@ -0,0 +1,35 @@
/* authd/notice.h - send notices back to the ircd and to clients
* Copyright (c) 2016 Elizabeth Myers <elizabeth@interlinked.me>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice is present in all copies.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __CHARYBDIS_AUTHD_NOTICE_H__
#define __CHARYBDIS_AUTHD_NOTICE_H__
typedef enum
{
L_DEBUG = 'D',
L_INFO = 'I',
L_WARN = 'W',
L_CRIT ='C',
} notice_level_t;
void notice_client(uint32_t cid, const char *fmt, ...);
void warn_opers(notice_level_t level, const char *fmt, ...);
#endif /* __CHARYBDIS_AUTHD_NOTICE_H__ */

View file

@ -18,16 +18,17 @@
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
*/ */
/* So the basic design here is to have "authentication providers" that do /* The basic design here is to have "authentication providers" that do things
* things like query ident and blacklists and even open proxies. * like query ident and blacklists and even open proxies.
* *
* Providers are registered statically in the struct auth_providers array. You will * Providers are registered in the auth_providers linked list. It is planned to
* probably want to add an item to the provider_t enum also. * use a bitmap to store provider ID's later.
* *
* Providers can either return failure immediately, immediate acceptance, or * Providers can either return failure immediately, immediate acceptance, or do
* do work in the background (calling set_provider to signal this). * work in the background (calling set_provider to signal this).
* *
* It is up to providers to keep their own state on clients if they need to. * Provider-specific data for each client can be kept in an index of the data
* struct member (using the provider's ID).
* *
* All providers must implement at a minimum a perform_provider function. You * All providers must implement at a minimum a perform_provider function. You
* don't have to implement the others if you don't need them. * don't have to implement the others if you don't need them.
@ -39,53 +40,82 @@
* should call provider_done. Do NOT call this if you have accepted or rejected * should call provider_done. Do NOT call this if you have accepted or rejected
* the client. * the client.
* *
* Eventually, stuff like *:line handling will be moved here, but that means we
* have to talk to bandb directly first.
*
* --Elizafox, 9 March 2016 * --Elizafox, 9 March 2016
*/ */
#include "rb_dictionary.h"
#include "authd.h" #include "authd.h"
#include "provider.h" #include "provider.h"
#include "notice.h"
rb_dlink_list auth_providers; rb_dlink_list auth_providers;
/* Clients waiting */ /* Clients waiting */
struct auth_client auth_clients[MAX_CLIENTS]; rb_dictionary *auth_clients;
/* Load a provider */ /* Load a provider */
void load_provider(struct auth_provider *provider) void
load_provider(struct auth_provider *provider)
{ {
if(rb_dlink_list_length(&auth_providers) >= MAX_PROVIDERS)
{
warn_opers(L_CRIT, "Exceeded maximum level of authd providers (%d max)", MAX_PROVIDERS);
return;
}
if(provider->opt_handlers != NULL)
{
struct auth_opts_handler *handler;
for(handler = provider->opt_handlers; handler->option != NULL; handler++)
rb_dictionary_add(authd_option_handlers, handler->option, handler);
}
provider->init(); provider->init();
rb_dlinkAdd(provider, &provider->node, &auth_providers); rb_dlinkAdd(provider, &provider->node, &auth_providers);
} }
void unload_provider(struct auth_provider *provider) void
unload_provider(struct auth_provider *provider)
{ {
if(provider->opt_handlers != NULL)
{
struct auth_opts_handler *handler;
for(handler = provider->opt_handlers; handler->option != NULL; handler++)
rb_dictionary_delete(authd_option_handlers, handler->option);
}
provider->destroy(); provider->destroy();
rb_dlinkDelete(&provider->node, &auth_providers); rb_dlinkDelete(&provider->node, &auth_providers);
} }
/* Initalise all providers */ /* Initalise all providers */
void init_providers(void) void
init_providers(void)
{ {
auth_clients = rb_dictionary_create("pending auth clients", rb_uint32cmp);
load_provider(&rdns_provider); load_provider(&rdns_provider);
load_provider(&ident_provider); load_provider(&ident_provider);
load_provider(&blacklist_provider);
} }
/* Terminate all providers */ /* Terminate all providers */
void destroy_providers(void) void
destroy_providers(void)
{ {
rb_dlink_node *ptr; rb_dlink_node *ptr;
rb_dictionary_iter iter;
struct auth_client *auth;
struct auth_provider *provider; struct auth_provider *provider;
/* Cancel outstanding connections */ /* Cancel outstanding connections */
for (size_t i = 0; i < MAX_CLIENTS; i++) RB_DICTIONARY_FOREACH(auth, &iter, auth_clients)
{ {
if(auth_clients[i].cid) /* TBD - is this the right thing? */
{ reject_client(auth, 0, "Authentication system is down... try reconnecting in a few seconds");
/* TBD - is this the right thing?
* (NOTE - this error message is designed for morons) */
reject_client(&auth_clients[i], 0, true,
"IRC server reloading... try reconnecting in a few seconds");
}
} }
RB_DLINK_FOREACH(ptr, auth_providers.head) RB_DLINK_FOREACH(ptr, auth_providers.head)
@ -98,7 +128,8 @@ void destroy_providers(void)
} }
/* Cancel outstanding providers for a client */ /* Cancel outstanding providers for a client */
void cancel_providers(struct auth_client *auth) void
cancel_providers(struct auth_client *auth)
{ {
rb_dlink_node *ptr; rb_dlink_node *ptr;
struct auth_provider *provider; struct auth_provider *provider;
@ -107,24 +138,30 @@ void cancel_providers(struct auth_client *auth)
{ {
provider = ptr->data; provider = ptr->data;
if(provider->cancel && is_provider(auth, provider->id)) if(provider->cancel && is_provider_on(auth, provider->id))
/* Cancel if required */ /* Cancel if required */
provider->cancel(auth); provider->cancel(auth);
} }
rb_dictionary_delete(auth_clients, RB_UINT_TO_POINTER(auth->cid));
rb_free(auth);
} }
/* Provider is done */ /* Provider is done - WARNING: do not use auth instance after calling! */
void provider_done(struct auth_client *auth, provider_t id) void
provider_done(struct auth_client *auth, provider_t id)
{ {
rb_dlink_node *ptr; rb_dlink_node *ptr;
struct auth_provider *provider; struct auth_provider *provider;
unset_provider(auth, id); set_provider_off(auth, id);
set_provider_done(auth, id);
if(!auth->providers) if(!auth->providers)
{ {
/* No more providers, done */ if(!auth->providers_starting)
accept_client(auth, 0); /* Only do this when there are no providers left */
accept_client(auth, 0);
return; return;
} }
@ -132,16 +169,16 @@ void provider_done(struct auth_client *auth, provider_t id)
{ {
provider = ptr->data; provider = ptr->data;
if(provider->completed && is_provider(auth, provider->id)) if(provider->completed && is_provider_on(auth, provider->id))
/* Notify pending clients who asked for it */ /* Notify pending clients who asked for it */
provider->completed(auth, id); provider->completed(auth, id);
} }
} }
/* Reject a client, cancel outstanding providers if any if hard set to true */ /* Reject a client - WARNING: do not use auth instance after calling! */
void reject_client(struct auth_client *auth, provider_t id, bool hard, const char *reason) void
reject_client(struct auth_client *auth, provider_t id, const char *reason)
{ {
uint16_t cid = auth->cid;
char reject; char reject;
switch(id) switch(id)
@ -155,83 +192,87 @@ void reject_client(struct auth_client *auth, provider_t id, bool hard, const cha
case PROVIDER_BLACKLIST: case PROVIDER_BLACKLIST:
reject = 'B'; reject = 'B';
break; break;
case PROVIDER_NULL:
default: default:
reject = 'N'; reject = 'N';
break; break;
} }
rb_helper_write(authd_helper, "R %x %c :%s", auth->cid, reject, reason); /* We send back username and hostname in case ircd wants to overrule our decision.
* In the future this may not be the case.
* --Elizafox
*/
rb_helper_write(authd_helper, "R %x %c %s %s :%s", auth->cid, reject, auth->username, auth->hostname, reason);
unset_provider(auth, id); set_provider_off(auth, id);
cancel_providers(auth);
if(hard && auth->providers)
{
cancel_providers(auth);
memset(&auth_clients[cid], 0, sizeof(struct auth_client));
}
} }
/* Accept a client, cancel outstanding providers if any */ /* Accept a client, cancel outstanding providers if any - WARNING: do nto use auth instance after calling! */
void accept_client(struct auth_client *auth, provider_t id) void
accept_client(struct auth_client *auth, provider_t id)
{ {
uint16_t cid = auth->cid; uint32_t cid = auth->cid;
rb_helper_write(authd_helper, "A %x %s %s", auth->cid, auth->username, auth->hostname); rb_helper_write(authd_helper, "A %x %s %s", auth->cid, auth->username, auth->hostname);
unset_provider(auth, id); set_provider_off(auth, id);
cancel_providers(auth);
if(auth->providers)
cancel_providers(auth);
memset(&auth_clients[cid], 0, sizeof(struct auth_client));
}
/* Send a notice to a client */
void notice_client(struct auth_client *auth, const char *notice)
{
rb_helper_write(authd_helper, "N %x :%s", auth->cid, notice);
} }
/* Begin authenticating user */ /* Begin authenticating user */
static void start_auth(const char *cid, const char *l_ip, const char *l_port, const char *c_ip, const char *c_port) static void
start_auth(const char *cid, const char *l_ip, const char *l_port, const char *c_ip, const char *c_port)
{ {
rb_dlink_node *ptr;
struct auth_provider *provider; struct auth_provider *provider;
struct auth_client *auth; struct auth_client *auth = rb_malloc(sizeof(struct auth_client));
long lcid = strtol(cid, NULL, 16); long lcid = strtol(cid, NULL, 16);
rb_dlink_node *ptr;
if(lcid >= MAX_CLIENTS) if(lcid >= UINT32_MAX)
return; return;
auth = &auth_clients[lcid]; auth->cid = (uint32_t)lcid;
if(auth->cid != 0)
/* Shouldn't get here */ if(rb_dictionary_find(auth_clients, RB_UINT_TO_POINTER(auth->cid)) == NULL)
rb_dictionary_add(auth_clients, RB_UINT_TO_POINTER(auth->cid), auth);
else
{
warn_opers(L_CRIT, "BUG: duplicate client added via start_auth: %x", auth->cid);
rb_free(auth);
return; return;
}
auth->cid = (uint16_t)lcid; rb_strlcpy(auth->l_ip, l_ip, sizeof(auth->l_ip));
auth->l_port = (uint16_t)atoi(l_port); /* should be safe */
(void) rb_inet_pton_sock(l_ip, (struct sockaddr *)&auth->l_addr);
rb_strlcpy(auth->c_ip, c_ip, sizeof(auth->c_ip));
auth->c_port = (uint16_t)atoi(c_port);
(void) rb_inet_pton_sock(c_ip, (struct sockaddr *)&auth->c_addr);
(void)rb_inet_pton_sock(l_ip, (struct sockaddr *)&auth->l_addr);
#ifdef RB_IPV6 #ifdef RB_IPV6
if(GET_SS_FAMILY(&auth->l_addr) == AF_INET6) if(GET_SS_FAMILY(&auth->l_addr) == AF_INET6)
((struct sockaddr_in6 *)&auth->l_addr)->sin6_port = htons(atoi(l_ip)); ((struct sockaddr_in6 *)&auth->l_addr)->sin6_port = htons(auth->l_port);
else else
#endif #endif
((struct sockaddr_in *)&auth->l_addr)->sin_port = htons(atoi(l_ip)); ((struct sockaddr_in *)&auth->l_addr)->sin_port = htons(auth->l_port);
(void)rb_inet_pton_sock(c_ip, (struct sockaddr *)&auth->c_addr);
#ifdef RB_IPV6 #ifdef RB_IPV6
if(GET_SS_FAMILY(&auth->c_addr) == AF_INET6) if(GET_SS_FAMILY(&auth->c_addr) == AF_INET6)
((struct sockaddr_in6 *)&auth->c_addr)->sin6_port = htons(atoi(c_ip)); ((struct sockaddr_in6 *)&auth->c_addr)->sin6_port = htons(auth->c_port);
else else
#endif #endif
((struct sockaddr_in *)&auth->c_addr)->sin_port = htons(atoi(c_ip)); ((struct sockaddr_in *)&auth->c_addr)->sin_port = htons(auth->c_port);
memset(auth->data, 0, sizeof(auth->data));
auth->providers_starting = true;
RB_DLINK_FOREACH(ptr, auth_providers.head) RB_DLINK_FOREACH(ptr, auth_providers.head)
{ {
provider = ptr->data; provider = ptr->data;
lrb_assert(provider->start != NULL);
/* Execute providers */ /* Execute providers */
if(!provider->start(auth)) if(!provider->start(auth))
{ {
@ -240,6 +281,7 @@ static void start_auth(const char *cid, const char *l_ip, const char *l_port, co
return; return;
} }
} }
auth->providers_starting = false;
/* If no providers are running, accept the client */ /* If no providers are running, accept the client */
if(!auth->providers) if(!auth->providers)
@ -247,10 +289,41 @@ static void start_auth(const char *cid, const char *l_ip, const char *l_port, co
} }
/* Callback for the initiation */ /* Callback for the initiation */
void handle_new_connection(int parc, char *parv[]) void
handle_new_connection(int parc, char *parv[])
{ {
if(parc < 7) if(parc < 6)
{
warn_opers(L_CRIT, "BUG: received too few params for new connection (6 expected, got %d)", parc);
return; return;
}
start_auth(parv[1], parv[2], parv[3], parv[4], parv[5]); start_auth(parv[1], parv[2], parv[3], parv[4], parv[5]);
} }
void
handle_cancel_connection(int parc, char *parv[])
{
struct auth_client *auth;
long lcid;
if(parc < 2)
{
warn_opers(L_CRIT, "BUG: received too few params for new connection (2 expected, got %d)", parc);
return;
}
if((lcid = strtol(parv[1], NULL, 16)) > UINT32_MAX)
{
warn_opers(L_CRIT, "BUG: got a request to cancel a connection that can't exist: %lx", lcid);
return;
}
if((auth = rb_dictionary_retrieve(auth_clients, RB_UINT_TO_POINTER((uint32_t)lcid))) == NULL)
{
warn_opers(L_CRIT, "BUG: tried to cancel nonexistent connection %lx", lcid);
return;
}
cancel_providers(auth);
}

View file

@ -22,39 +22,49 @@
#define __CHARYBDIS_AUTHD_PROVIDER_H__ #define __CHARYBDIS_AUTHD_PROVIDER_H__
#include "stdinc.h" #include "stdinc.h"
#include "authd.h"
#include "rb_dictionary.h"
/* Arbitrary limit */ #define MAX_PROVIDERS 32 /* This should be enough */
#define MAX_CLIENTS 4096
/* Registered providers */ /* Registered providers */
typedef enum typedef enum
{ {
PROVIDER_NULL = 0x0, /* Dummy value */ PROVIDER_RDNS,
PROVIDER_RDNS = 0x1, PROVIDER_IDENT,
PROVIDER_IDENT = 0x2, PROVIDER_BLACKLIST,
PROVIDER_BLACKLIST = 0x4,
} provider_t; } provider_t;
struct auth_client struct auth_client
{ {
uint16_t cid; /* Client ID */ uint16_t cid; /* Client ID */
struct rb_sockaddr_storage l_addr; /* Listener IP address */ char l_ip[HOSTIPLEN + 1]; /* Listener IP address */
struct rb_sockaddr_storage c_addr; /* Client IP address */ uint16_t l_port; /* Listener port */
struct rb_sockaddr_storage l_addr; /* Listener address/port */
char c_ip[HOSTIPLEN + 1]; /* Client IP address */
uint16_t c_port; /* Client port */
struct rb_sockaddr_storage c_addr; /* Client address/port */
char hostname[HOSTLEN + 1]; /* Used for DNS lookup */ char hostname[HOSTLEN + 1]; /* Used for DNS lookup */
char username[USERLEN + 1]; /* Used for ident lookup */ char username[USERLEN + 1]; /* Used for ident lookup */
unsigned int providers; /* Providers at work, uint32_t providers; /* Providers at work,
* none left when set to 0 */ * none left when set to 0 */
uint32_t providers_done; /* Providers completed */
bool providers_starting; /* Providers are still warming up */
void *data[MAX_PROVIDERS]; /* Provider-specific data slots */
}; };
typedef bool (*provider_init_t)(void); typedef bool (*provider_init_t)(void);
typedef bool (*provider_perform_t)(struct auth_client *);
typedef void (*provider_complete_t)(struct auth_client *, provider_t provider);
typedef void (*provider_cancel_t)(struct auth_client *);
typedef void (*provider_destroy_t)(void); typedef void (*provider_destroy_t)(void);
typedef bool (*provider_start_t)(struct auth_client *);
typedef void (*provider_cancel_t)(struct auth_client *);
typedef void (*provider_complete_t)(struct auth_client *, provider_t);
struct auth_provider struct auth_provider
{ {
rb_dlink_node node; rb_dlink_node node;
@ -64,16 +74,19 @@ struct auth_provider
provider_init_t init; /* Initalise the provider */ provider_init_t init; /* Initalise the provider */
provider_destroy_t destroy; /* Terminate the provider */ provider_destroy_t destroy; /* Terminate the provider */
provider_perform_t start; /* Perform authentication */ provider_start_t start; /* Perform authentication */
provider_cancel_t cancel; /* Authentication cancelled */ provider_cancel_t cancel; /* Authentication cancelled */
provider_complete_t completed; /* Callback for when other performers complete (think dependency chains) */ provider_complete_t completed; /* Callback for when other performers complete (think dependency chains) */
struct auth_opts_handler *opt_handlers;
}; };
extern rb_dlink_list auth_providers; extern rb_dlink_list auth_providers;
extern rb_dictionary *auth_clients;
extern struct auth_provider rdns_provider; extern struct auth_provider rdns_provider;
extern struct auth_provider ident_provider; extern struct auth_provider ident_provider;
extern struct auth_provider blacklist_provider;
extern struct auth_client auth_clients[MAX_CLIENTS];
void load_provider(struct auth_provider *provider); void load_provider(struct auth_provider *provider);
void unload_provider(struct auth_provider *provider); void unload_provider(struct auth_provider *provider);
@ -84,28 +97,43 @@ void cancel_providers(struct auth_client *auth);
void provider_done(struct auth_client *auth, provider_t id); void provider_done(struct auth_client *auth, provider_t id);
void accept_client(struct auth_client *auth, provider_t id); void accept_client(struct auth_client *auth, provider_t id);
void reject_client(struct auth_client *auth, provider_t id, bool hard, const char *reason); void reject_client(struct auth_client *auth, provider_t id, const char *reason);
void notice_client(struct auth_client *auth, const char *notice);
void handle_new_connection(int parc, char *parv[]); void handle_new_connection(int parc, char *parv[]);
void handle_cancel_connection(int parc, char *parv[]);
/* Provider is operating on this auth_client (set this if you have async work to do) */ /* Provider is operating on this auth_client (set this if you have async work to do) */
static inline void set_provider(struct auth_client *auth, provider_t provider) static inline void
set_provider_on(struct auth_client *auth, provider_t provider)
{ {
auth->providers |= provider; auth->providers |= (1 << provider);
} }
/* Provider is no longer operating on this auth client (you should use provider_done) */ /* Provider is no longer operating on this auth client (you should use provider_done) */
static inline void unset_provider(struct auth_client *auth, provider_t provider) static inline void
set_provider_off(struct auth_client *auth, provider_t provider)
{ {
auth->providers &= ~provider; auth->providers &= ~(1 << provider);
}
/* Set the provider to done (you should use provider_done) */
static inline void
set_provider_done(struct auth_client *auth, provider_t provider)
{
auth->providers_done |= (1 << provider);
} }
/* Check if provider is operating on this auth client */ /* Check if provider is operating on this auth client */
static inline bool is_provider(struct auth_client *auth, provider_t provider) static inline bool
is_provider_on(struct auth_client *auth, provider_t provider)
{ {
return auth->providers & provider; return auth->providers & (1 << provider);
}
static inline bool
is_provider_done(struct auth_client *auth, provider_t provider)
{
return auth->providers_done & (1 << provider);
} }
#endif /* __CHARYBDIS_AUTHD_PROVIDER_H__ */ #endif /* __CHARYBDIS_AUTHD_PROVIDER_H__ */

565
authd/providers/blacklist.c Normal file
View file

@ -0,0 +1,565 @@
/*
* charybdis: A slightly useful ircd.
* blacklist.c: Manages DNS blacklist entries and lookups
*
* Copyright (C) 2006-2011 charybdis development team
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/* Originally written for charybdis circa 2006 (by nenolod?).
* Tweaked for authd. Some functions and structs renamed. Public/private
* interfaces have been shifted around. Some code has been cleaned up too.
* -- Elizafox 24 March 2016
*/
#include "authd.h"
#include "provider.h"
#include "notice.h"
#include "stdinc.h"
#include "dns.h"
typedef enum filter_t
{
FILTER_ALL = 1,
FILTER_LAST = 2,
} filter_t;
/* Blacklist accepted IP types */
#define IPTYPE_IPV4 1
#define IPTYPE_IPV6 2
/* A configured DNSBL */
struct blacklist
{
char host[IRCD_RES_HOSTLEN + 1];
char reason[BUFSIZE]; /* Reason template (ircd fills in the blanks) */
unsigned char iptype; /* IP types supported */
rb_dlink_list filters; /* Filters for queries */
bool delete; /* If true delete when no clients */
int refcount; /* When 0 and delete is set, remove this blacklist */
time_t lastwarning; /* Last warning about garbage replies sent */
};
/* A lookup in progress for a particular DNSBL for a particular client */
struct blacklist_lookup
{
struct blacklist *bl; /* Blacklist we're checking */
struct auth_client *auth; /* Client */
struct dns_query *query; /* DNS query pointer */
rb_dlink_node node;
};
/* A blacklist filter */
struct blacklist_filter
{
filter_t type; /* Type of filter */
char filter[HOSTIPLEN]; /* The filter itself */
rb_dlink_node node;
};
/* Blacklist user data attached to auth_client instance */
struct blacklist_user
{
rb_dlink_list queries; /* Blacklist queries in flight */
time_t timeout; /* When this times out */
};
/* public interfaces */
static bool blacklists_init(void);
static void blacklists_destroy(void);
static bool blacklists_start(struct auth_client *);
static void blacklists_cancel(struct auth_client *);
/* private interfaces */
static void unref_blacklist(struct blacklist *);
static struct blacklist *new_blacklist(const char *, const char *, unsigned char, rb_dlink_list *);
static struct blacklist *find_blacklist(const char *);
static bool blacklist_check_reply(struct blacklist_lookup *, const char *);
static void blacklist_dns_callback(const char *, bool, query_type, void *);
static void initiate_blacklist_dnsquery(struct blacklist *, struct auth_client *);
static void timeout_blacklist_queries_event(void *);
/* Variables */
static rb_dlink_list blacklist_list = { NULL, NULL, 0 };
static struct ev_entry *timeout_ev;
static int blacklist_timeout = 15;
/* private interfaces */
static void
unref_blacklist(struct blacklist *bl)
{
rb_dlink_node *ptr, *nptr;
bl->refcount--;
if (bl->delete && bl->refcount <= 0)
{
RB_DLINK_FOREACH_SAFE(ptr, nptr, bl->filters.head)
{
rb_dlinkDelete(ptr, &bl->filters);
rb_free(ptr);
}
rb_dlinkFindDestroy(bl, &blacklist_list);
rb_free(bl);
}
}
static struct blacklist *
new_blacklist(const char *name, const char *reason, unsigned char iptype, rb_dlink_list *filters)
{
struct blacklist *bl;
if (name == NULL || reason == NULL || iptype == 0)
return NULL;
if((bl = find_blacklist(name)) == NULL)
{
bl = rb_malloc(sizeof(struct blacklist));
rb_dlinkAddAlloc(bl, &blacklist_list);
}
else
bl->delete = false;
rb_strlcpy(bl->host, name, IRCD_RES_HOSTLEN + 1);
rb_strlcpy(bl->reason, reason, BUFSIZE);
bl->iptype = iptype;
rb_dlinkMoveList(filters, &bl->filters);
bl->lastwarning = 0;
return bl;
}
static struct blacklist *
find_blacklist(const char *name)
{
rb_dlink_node *ptr;
RB_DLINK_FOREACH(ptr, blacklist_list.head)
{
struct blacklist *bl = (struct blacklist *)ptr->data;
if (!strcasecmp(bl->host, name))
return bl;
}
return NULL;
}
static inline bool
blacklist_check_reply(struct blacklist_lookup *bllookup, const char *ipaddr)
{
struct blacklist *bl = bllookup->bl;
const char *lastoctet;
rb_dlink_node *ptr;
/* No filters and entry found - thus positive match */
if (!rb_dlink_list_length(&bl->filters))
return true;
/* Below will prolly have to change if IPv6 address replies are sent back */
if ((lastoctet = strrchr(ipaddr, '.')) == NULL || *(++lastoctet) == '\0')
goto blwarn;
RB_DLINK_FOREACH(ptr, bl->filters.head)
{
struct blacklist_filter *filter = ptr->data;
const char *cmpstr;
if (filter->type == FILTER_ALL)
cmpstr = ipaddr;
else if (filter->type == FILTER_LAST)
cmpstr = lastoctet;
else
{
warn_opers(L_CRIT, "BUG: Unknown blacklist filter type on blacklist %s: %d",
bl->host, filter->type);
continue;
}
if (strcmp(cmpstr, filter->filter) == 0)
/* Match! */
return true;
}
return false;
blwarn:
if (bl->lastwarning + 3600 < rb_current_time())
{
warn_opers(L_WARN, "Garbage/undecipherable reply received from blacklist %s (reply %s)",
bl->host, ipaddr);
bl->lastwarning = rb_current_time();
}
return false;
}
static void
blacklist_dns_callback(const char *result, bool status, query_type type, void *data)
{
struct blacklist_lookup *bllookup = (struct blacklist_lookup *)data;
struct blacklist_user *bluser;
struct blacklist *bl;
struct auth_client *auth;
if (bllookup == NULL || bllookup->auth == NULL)
return;
bl = bllookup->bl;
auth = bllookup->auth;
bluser = auth->data[PROVIDER_BLACKLIST];
if(bluser == NULL)
return;
if (result != NULL && status && blacklist_check_reply(bllookup, result))
{
/* Match found, so proceed no further */
blacklists_cancel(auth);
reject_client(auth, PROVIDER_BLACKLIST, bl->reason);
return;
}
unref_blacklist(bl);
cancel_query(bllookup->query); /* Ignore future responses */
rb_dlinkDelete(&bllookup->node, &bluser->queries);
rb_free(bllookup);
if(!rb_dlink_list_length(&bluser->queries))
{
/* Done here */
rb_free(bluser);
auth->data[PROVIDER_BLACKLIST] = NULL;
provider_done(auth, PROVIDER_BLACKLIST);
}
}
static void
initiate_blacklist_dnsquery(struct blacklist *bl, struct auth_client *auth)
{
struct blacklist_lookup *bllookup = rb_malloc(sizeof(struct blacklist_lookup));
struct blacklist_user *bluser = auth->data[PROVIDER_BLACKLIST];
char buf[IRCD_RES_HOSTLEN + 1];
int aftype;
bllookup->bl = bl;
bllookup->auth = auth;
aftype = GET_SS_FAMILY(&auth->c_addr);
if((aftype == AF_INET && (bl->iptype & IPTYPE_IPV4) == 0) ||
(aftype == AF_INET6 && (bl->iptype & IPTYPE_IPV6) == 0))
/* Incorrect blacklist type for this IP... */
return;
build_rdns(buf, sizeof(buf), &auth->c_addr, bl->host);
bllookup->query = lookup_ip(buf, AF_INET, blacklist_dns_callback, bllookup);
rb_dlinkAdd(bllookup, &bllookup->node, &bluser->queries);
bl->refcount++;
}
/* Timeout outstanding queries */
static void
timeout_blacklist_queries_event(void *notused)
{
struct auth_client *auth;
rb_dictionary_iter iter;
RB_DICTIONARY_FOREACH(auth, &iter, auth_clients)
{
struct blacklist_user *bluser = auth->data[PROVIDER_BLACKLIST];
if(bluser != NULL && bluser->timeout < rb_current_time())
{
blacklists_cancel(auth);
provider_done(auth, PROVIDER_BLACKLIST);
}
}
}
static inline void
lookup_all_blacklists(struct auth_client *auth)
{
struct blacklist_user *bluser = auth->data[PROVIDER_BLACKLIST];
rb_dlink_node *ptr;
RB_DLINK_FOREACH(ptr, blacklist_list.head)
{
struct blacklist *bl = (struct blacklist *)ptr->data;
if (!bl->delete)
initiate_blacklist_dnsquery(bl, auth);
}
bluser->timeout = rb_current_time() + blacklist_timeout;
}
static inline void
delete_blacklist(struct blacklist *bl)
{
if (bl->refcount > 0)
bl->delete = true;
else
{
rb_dlinkFindDestroy(bl, &blacklist_list);
rb_free(bl);
}
}
static void
delete_all_blacklists(void)
{
rb_dlink_node *ptr, *nptr;
RB_DLINK_FOREACH_SAFE(ptr, nptr, blacklist_list.head)
{
delete_blacklist(ptr->data);
}
}
/* public interfaces */
static bool
blacklists_start(struct auth_client *auth)
{
if(auth->data[PROVIDER_BLACKLIST] != NULL)
return true;
if(!rb_dlink_list_length(&blacklist_list))
/* Nothing to do... */
return true;
auth->data[PROVIDER_BLACKLIST] = rb_malloc(sizeof(struct blacklist_user));
if(is_provider_done(auth, PROVIDER_RDNS) && is_provider_done(auth, PROVIDER_IDENT))
/* This probably can't happen but let's handle this case anyway */
lookup_all_blacklists(auth);
set_provider_on(auth, PROVIDER_BLACKLIST);
return true;
}
/* This is called every time a provider is completed as long as we are marked not done */
static void
blacklists_initiate(struct auth_client *auth, provider_t provider)
{
struct blacklist_user *bluser = auth->data[PROVIDER_BLACKLIST];
lrb_assert(provider != PROVIDER_BLACKLIST);
lrb_assert(!is_provider_done(auth, PROVIDER_BLACKLIST));
lrb_assert(rb_dlink_list_length(&blacklist_list) > 0);
if(bluser == NULL || rb_dlink_list_length(&bluser->queries))
/* Nothing to do */
return;
else if(!(is_provider_done(auth, PROVIDER_RDNS) && is_provider_done(auth, PROVIDER_IDENT)))
/* Don't start until we've completed these */
return;
else
lookup_all_blacklists(auth);
}
static void
blacklists_cancel(struct auth_client *auth)
{
rb_dlink_node *ptr, *nptr;
struct blacklist_user *bluser = auth->data[PROVIDER_BLACKLIST];
if(bluser == NULL)
return;
RB_DLINK_FOREACH_SAFE(ptr, nptr, bluser->queries.head)
{
struct blacklist_lookup *bllookup = ptr->data;
cancel_query(bllookup->query);
unref_blacklist(bllookup->bl);
rb_dlinkDelete(&bllookup->node, &bluser->queries);
rb_free(bllookup);
}
rb_free(bluser);
auth->data[PROVIDER_BLACKLIST] = NULL;
}
static bool
blacklists_init(void)
{
timeout_ev = rb_event_addish("timeout_blacklist_queries_event", timeout_blacklist_queries_event, NULL, 1);
return (timeout_ev != NULL);
}
static void
blacklists_destroy(void)
{
rb_dlink_node *ptr, *nptr;
rb_dictionary_iter iter;
struct blacklist *bl;
struct auth_client *auth;
RB_DICTIONARY_FOREACH(auth, &iter, auth_clients)
{
blacklists_cancel(auth);
}
delete_all_blacklists();
rb_event_delete(timeout_ev);
}
static void
add_conf_blacklist(const char *key, int parc, const char **parv)
{
rb_dlink_list filters = { NULL, NULL, 0 };
char *tmp, *elemlist = rb_strdup(parv[2]);
unsigned char iptype;
if(*elemlist == '*')
goto end;
for(char *elem = rb_strtok_r(elemlist, ",", &tmp); elem; elem = rb_strtok_r(NULL, ",", &tmp))
{
struct blacklist_filter *filter = rb_malloc(sizeof(struct blacklist_filter));
int dot_c = 0;
filter_t type = FILTER_LAST;
bool valid = true;
/* Check blacklist filter type and for validity */
for(char *c = elem; *c != '\0'; c++)
{
if(*c == '.')
{
if(++dot_c > 3)
{
warn_opers(L_CRIT, "addr_conf_blacklist got a bad filter (too many octets)");
valid = false;
break;
}
type = FILTER_ALL;
}
else if(!isdigit(*c))
{
warn_opers(L_CRIT, "addr_conf_blacklist got a bad filter (invalid character in blacklist filter: %c)", *c);
valid = false;
break;
}
}
if(valid && dot_c > 0 && dot_c < 3)
{
warn_opers(L_CRIT, "addr_conf_blacklist got a bad filter (insufficient octets)");
valid = false;
}
if(!valid)
{
rb_free(filter);
continue;
}
filter->type = type;
rb_strlcpy(filter->filter, elem, sizeof(filter->filter));
rb_dlinkAdd(filter, &filter->node, &filters);
}
end:
rb_free(elemlist);
iptype = atoi(parv[1]) & 0x3;
if(new_blacklist(parv[0], parv[3], iptype, &filters) == NULL)
{
rb_dlink_node *ptr, *nptr;
warn_opers(L_CRIT, "addr_conf_blacklist got a malformed blacklist");
RB_DLINK_FOREACH_SAFE(ptr, nptr, filters.head)
{
rb_free(ptr->data);
rb_dlinkDelete(ptr, &filters);
}
}
}
static void
del_conf_blacklist(const char *key, int parc, const char **parv)
{
struct blacklist *bl = find_blacklist(parv[0]);
if(bl == NULL)
{
warn_opers(L_CRIT, "BUG: tried to remove nonexistent blacklist %s", parv[0]);
return;
}
delete_blacklist(bl);
}
static void
del_conf_blacklist_all(const char *key, int parc, const char **parv)
{
delete_all_blacklists();
}
static void
add_conf_blacklist_timeout(const char *key, int parc, const char **parv)
{
int timeout = atoi(parv[0]);
if(timeout < 0)
{
warn_opers(L_CRIT, "BUG: blacklist timeout < 0 (value: %d)", timeout);
return;
}
blacklist_timeout = timeout;
}
struct auth_opts_handler blacklist_options[] =
{
{ "rbl", 4, add_conf_blacklist },
{ "rbl_del", 1, del_conf_blacklist },
{ "rbl_del_all", 0, del_conf_blacklist_all },
{ "rbl_timeout", 1, add_conf_blacklist_timeout },
{ NULL, 0, NULL },
};
struct auth_provider blacklist_provider =
{
.id = PROVIDER_BLACKLIST,
.init = blacklists_init,
.destroy = blacklists_destroy,
.start = blacklists_start,
.cancel = blacklists_cancel,
.completed = blacklists_initiate,
.opt_handlers = blacklist_options,
};

View file

@ -18,9 +18,16 @@
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
*/ */
/* Largely adapted from old s_auth.c, but reworked for authd. rDNS code
* moved to its own provider.
*
* --Elizafox 13 March 2016
*/
#include "stdinc.h" #include "stdinc.h"
#include "match.h" #include "match.h"
#include "authd.h" #include "authd.h"
#include "notice.h"
#include "provider.h" #include "provider.h"
#include "res.h" #include "res.h"
@ -28,19 +35,17 @@
struct ident_query struct ident_query
{ {
rb_dlink_node node; time_t timeout; /* Timeout interval */
rb_fde_t *F; /* Our FD */
struct auth_client *auth; /* Our client */
time_t timeout; /* Timeout interval */
rb_fde_t *F; /* Our FD */
}; };
/* Goinked from old s_auth.c --Elizafox */ /* Goinked from old s_auth.c --Elizafox */
static const char *messages[] = static const char *messages[] =
{ {
":*** Checking Ident", "*** Checking Ident",
":*** Got Ident response", "*** Got Ident response",
":*** No Ident response", "*** No Ident response",
"*** Cannot verify ident validity, ignoring ident",
}; };
typedef enum typedef enum
@ -48,134 +53,34 @@ typedef enum
REPORT_LOOKUP, REPORT_LOOKUP,
REPORT_FOUND, REPORT_FOUND,
REPORT_FAIL, REPORT_FAIL,
REPORT_INVALID,
} ident_message; } ident_message;
static EVH timeout_ident_queries_event; static EVH timeout_ident_queries_event;
static CNCB ident_connected; static CNCB ident_connected;
static PF read_ident_reply; static PF read_ident_reply;
static void client_fail(struct ident_query *query, ident_message message); static void client_fail(struct auth_client *auth, ident_message message);
static void client_success(struct ident_query *query); static void client_success(struct auth_client *auth);
static void cleanup_query(struct ident_query *query);
static char * get_valid_ident(char *buf); static char * get_valid_ident(char *buf);
static rb_dlink_list queries;
static struct ev_entry *timeout_ev; static struct ev_entry *timeout_ev;
static int ident_timeout = 5; static int ident_timeout = 5;
bool ident_init(void)
{
timeout_ev = rb_event_addish("timeout_ident_queries_event", timeout_ident_queries_event, NULL, 1);
return (timeout_ev != NULL);
}
void ident_destroy(void)
{
rb_dlink_node *ptr, *nptr;
/* Nuke all ident queries */
RB_DLINK_FOREACH_SAFE(ptr, nptr, queries.head)
{
struct ident_query *query = ptr->data;
notice_client(query->auth, messages[REPORT_FAIL]);
rb_close(query->F);
rb_free(query);
rb_dlinkDelete(ptr, &queries);
}
}
bool ident_start(struct auth_client *auth)
{
struct ident_query *query = rb_malloc(sizeof(struct ident_query));
struct rb_sockaddr_storage localaddr, clientaddr;
int family;
rb_fde_t *F;
query->auth = auth;
query->timeout = rb_current_time() + ident_timeout;
if((F = rb_socket(family, SOCK_STREAM, 0, "ident")) == NULL)
{
client_fail(query, REPORT_FAIL);
return true; /* Not a fatal error */
}
query->F = F;
/* Build sockaddr_storages for rb_connect_tcp below */
memcpy(&localaddr, &auth->l_addr, sizeof(struct rb_sockaddr_storage));
memcpy(&clientaddr, &auth->c_addr, sizeof(struct rb_sockaddr_storage));
/* Set the ports correctly */
#ifdef RB_IPV6
if(GET_SS_FAMILY(&localaddr) == AF_INET6)
((struct sockaddr_in6 *)&localaddr)->sin6_port = 0;
else
#endif
((struct sockaddr_in *)&localaddr)->sin_port = 0;
#ifdef RB_IPV6
if(GET_SS_FAMILY(&clientaddr) == AF_INET6)
((struct sockaddr_in6 *)&clientaddr)->sin6_port = htons(113);
else
#endif
((struct sockaddr_in *)&clientaddr)->sin_port = htons(113);
rb_connect_tcp(F, (struct sockaddr *)&auth->c_addr,
(struct sockaddr *)&auth->l_addr,
GET_SS_LEN(&auth->l_addr), ident_connected,
query, ident_timeout);
set_provider(auth, PROVIDER_IDENT);
rb_dlinkAdd(query, &query->node, &queries);
notice_client(auth, messages[REPORT_LOOKUP]);
return true;
}
void ident_cancel(struct auth_client *auth)
{
rb_dlink_node *ptr, *nptr;
RB_DLINK_FOREACH_SAFE(ptr, nptr, queries.head)
{
struct ident_query *query = ptr->data;
if(query->auth == auth)
{
client_fail(query, REPORT_FAIL);
rb_close(query->F);
rb_free(query);
rb_dlinkDelete(ptr, &queries);
return;
}
}
}
/* Timeout outstanding queries */ /* Timeout outstanding queries */
static void timeout_ident_queries_event(void *notused) static void
timeout_ident_queries_event(void *notused __unused)
{ {
rb_dlink_node *ptr, *nptr; struct auth_client *auth;
rb_dictionary_iter iter;
RB_DLINK_FOREACH_SAFE(ptr, nptr, queries.head) RB_DICTIONARY_FOREACH(auth, &iter, auth_clients)
{ {
struct ident_query *query = ptr->data; struct ident_query *query = auth->data[PROVIDER_IDENT];
if(query->timeout < rb_current_time()) if(query != NULL && query->timeout < rb_current_time())
{ client_fail(auth, REPORT_FAIL);
client_fail(query, REPORT_FAIL);
rb_close(query->F);
rb_free(query);
rb_dlinkDelete(ptr, &queries);
}
} }
} }
@ -190,74 +95,73 @@ static void timeout_ident_queries_event(void *notused)
* a write buffer far greater than this message to store it in should * a write buffer far greater than this message to store it in should
* problems arise. -avalon * problems arise. -avalon
*/ */
static void ident_connected(rb_fde_t *F, int error, void *data) static void
ident_connected(rb_fde_t *F __unused, int error, void *data)
{ {
struct ident_query *query = data; struct auth_client *auth = data;
struct auth_client *auth = query->auth; struct ident_query *query;
uint16_t c_port, l_port;
char authbuf[32]; char authbuf[32];
int authlen; int authlen;
if(auth == NULL)
return;
query = auth->data[PROVIDER_IDENT];
if(query == NULL)
return;
/* Check the error */ /* Check the error */
if(error != RB_OK) if(error != RB_OK)
{ {
/* We had an error during connection :( */ /* We had an error during connection :( */
client_fail(query, REPORT_FAIL); client_fail(auth, REPORT_FAIL);
cleanup_query(query);
return; return;
} }
#ifdef RB_IPV6
if(GET_SS_FAMILY(&auth->c_addr) == AF_INET6)
c_port = ntohs(((struct sockaddr_in6 *)&auth->c_addr)->sin6_port);
else
#endif
c_port = ntohs(((struct sockaddr_in *)&auth->c_addr)->sin_port);
#ifdef RB_IPV6
if(GET_SS_FAMILY(&auth->l_addr) == AF_INET6)
l_port = ntohs(((struct sockaddr_in6 *)&auth->l_addr)->sin6_port);
else
#endif
l_port = ntohs(((struct sockaddr_in *)&auth->l_addr)->sin_port);
snprintf(authbuf, sizeof(authbuf), "%u , %u\r\n", snprintf(authbuf, sizeof(authbuf), "%u , %u\r\n",
c_port, l_port); auth->c_port, auth->l_port);
authlen = strlen(authbuf); authlen = strlen(authbuf);
if(rb_write(query->F, authbuf, authlen) != authlen) if(rb_write(query->F, authbuf, authlen) != authlen)
{ {
client_fail(query, REPORT_FAIL); client_fail(auth, REPORT_FAIL);
return; return;
} }
read_ident_reply(query->F, query); read_ident_reply(query->F, auth);
} }
static void static void
read_ident_reply(rb_fde_t *F, void *data) read_ident_reply(rb_fde_t *F, void *data)
{ {
struct ident_query *query = data; struct auth_client *auth = data;
struct auth_client *auth = query->auth; struct ident_query *query;
char buf[IDENT_BUFSIZE + 1]; /* buffer to read auth reply into */
ident_message message = REPORT_FAIL;
char *s = NULL; char *s = NULL;
char *t = NULL; char *t = NULL;
int len; ssize_t len;
int count; int count;
char buf[IDENT_BUFSIZE + 1]; /* buffer to read auth reply into */
if(auth == NULL)
return;
query = auth->data[PROVIDER_IDENT];
if(query == NULL)
return;
len = rb_read(F, buf, IDENT_BUFSIZE); len = rb_read(F, buf, IDENT_BUFSIZE);
if(len < 0 && rb_ignore_errno(errno)) if(len < 0 && rb_ignore_errno(errno))
{ {
rb_setselect(F, RB_SELECT_READ, read_ident_reply, query); rb_setselect(F, RB_SELECT_READ, read_ident_reply, auth);
return; return;
} }
if(len > 0) if(len > 0)
{ {
buf[len] = '\0'; if((s = get_valid_ident(buf)) != NULL)
if((s = get_valid_ident(buf)))
{ {
t = auth->username; t = auth->username;
@ -266,10 +170,9 @@ read_ident_reply(rb_fde_t *F, void *data)
for (count = USERLEN; *s && count; s++) for (count = USERLEN; *s && count; s++)
{ {
if(*s == '@') if(*s == '@' || *s == '\r' || *s == '\n')
{
break; break;
}
if(*s != ' ' && *s != ':' && *s != '[') if(*s != ' ' && *s != ':' && *s != '[')
{ {
*t++ = *s; *t++ = *s;
@ -278,61 +181,58 @@ read_ident_reply(rb_fde_t *F, void *data)
} }
*t = '\0'; *t = '\0';
} }
else
message = REPORT_INVALID;
} }
if(s == NULL) if(s == NULL)
client_fail(query, REPORT_FAIL); client_fail(auth, message);
else else
client_success(query); client_success(auth);
cleanup_query(query);
} }
static void client_fail(struct ident_query *query, ident_message report) static void
client_fail(struct auth_client *auth, ident_message report)
{ {
struct auth_client *auth = query->auth; struct ident_query *query = auth->data[PROVIDER_IDENT];
if(auth) if(query == NULL)
{ return;
rb_strlcpy(auth->username, "*", sizeof(auth->username));
notice_client(auth, messages[report]); rb_strlcpy(auth->username, "*", sizeof(auth->username));
provider_done(auth, PROVIDER_IDENT);
} if(query->F != NULL)
rb_close(query->F);
rb_free(query);
auth->data[PROVIDER_IDENT] = NULL;
notice_client(auth->cid, messages[report]);
provider_done(auth, PROVIDER_IDENT);
} }
static void client_success(struct ident_query *query) static void
client_success(struct auth_client *auth)
{ {
struct auth_client *auth = query->auth; struct ident_query *query = auth->data[PROVIDER_IDENT];
if(auth) if(query == NULL)
{ return;
notice_client(auth, messages[REPORT_FOUND]);
provider_done(auth, PROVIDER_IDENT);
}
}
static void cleanup_query(struct ident_query *query) if(query->F != NULL)
{ rb_close(query->F);
rb_dlink_node *ptr, *nptr;
RB_DLINK_FOREACH_SAFE(ptr, nptr, queries.head) rb_free(query);
{ auth->data[PROVIDER_IDENT] = NULL;
struct ident_query *query_l = ptr->data;
if(query_l == query) notice_client(auth->cid, messages[REPORT_FOUND]);
{ provider_done(auth, PROVIDER_IDENT);
rb_close(query->F);
rb_free(query);
rb_dlinkDelete(ptr, &queries);
}
}
} }
/* get_valid_ident /* get_valid_ident
* parse ident query reply from identd server * parse ident query reply from identd server
* *
* Torn out of old s_auth.c because there was nothing wrong with it * Taken from old s_auth.c --Elizafox
* --Elizafox
* *
* Inputs - pointer to ident buf * Inputs - pointer to ident buf
* Outputs - NULL if no valid ident found, otherwise pointer to name * Outputs - NULL if no valid ident found, otherwise pointer to name
@ -354,45 +254,145 @@ get_valid_ident(char *buf)
colon1Ptr = strchr(remotePortString, ':'); colon1Ptr = strchr(remotePortString, ':');
if(!colon1Ptr) if(!colon1Ptr)
return 0; return NULL;
*colon1Ptr = '\0'; *colon1Ptr = '\0';
colon1Ptr++; colon1Ptr++;
colon2Ptr = strchr(colon1Ptr, ':'); colon2Ptr = strchr(colon1Ptr, ':');
if(!colon2Ptr) if(!colon2Ptr)
return 0; return NULL;
*colon2Ptr = '\0'; *colon2Ptr = '\0';
colon2Ptr++; colon2Ptr++;
commaPtr = strchr(remotePortString, ','); commaPtr = strchr(remotePortString, ',');
if(!commaPtr) if(!commaPtr)
return 0; return NULL;
*commaPtr = '\0'; *commaPtr = '\0';
commaPtr++; commaPtr++;
remp = atoi(remotePortString); remp = atoi(remotePortString);
if(!remp) if(!remp)
return 0; return NULL;
locp = atoi(commaPtr); locp = atoi(commaPtr);
if(!locp) if(!locp)
return 0; return NULL;
/* look for USERID bordered by first pair of colons */ /* look for USERID bordered by first pair of colons */
if(!strstr(colon1Ptr, "USERID")) if(!strstr(colon1Ptr, "USERID"))
return 0; return NULL;
colon3Ptr = strchr(colon2Ptr, ':'); colon3Ptr = strchr(colon2Ptr, ':');
if(!colon3Ptr) if(!colon3Ptr)
return 0; return NULL;
*colon3Ptr = '\0'; *colon3Ptr = '\0';
colon3Ptr++; colon3Ptr++;
return (colon3Ptr); return (colon3Ptr);
} }
static bool
ident_init(void)
{
timeout_ev = rb_event_addish("timeout_ident_queries_event", timeout_ident_queries_event, NULL, 1);
return (timeout_ev != NULL);
}
static void
ident_destroy(void)
{
struct auth_client *auth;
rb_dictionary_iter iter;
/* Nuke all ident queries */
RB_DICTIONARY_FOREACH(auth, &iter, auth_clients)
{
if(auth->data[PROVIDER_IDENT] != NULL)
client_fail(auth, REPORT_FAIL);
}
}
static bool ident_start(struct auth_client *auth)
{
struct ident_query *query = rb_malloc(sizeof(struct ident_query));
struct rb_sockaddr_storage l_addr, c_addr;
int family = GET_SS_FAMILY(&auth->c_addr);
if(auth->data[PROVIDER_IDENT] != NULL)
return true;
notice_client(auth->cid, messages[REPORT_LOOKUP]);
auth->data[PROVIDER_IDENT] = query;
query->timeout = rb_current_time() + ident_timeout;
if((query->F = rb_socket(family, SOCK_STREAM, 0, "ident")) == NULL)
{
warn_opers(L_DEBUG, "Could not create ident socket: %s", strerror(errno));
client_fail(auth, REPORT_FAIL);
return true; /* Not a fatal error */
}
/* Build sockaddr_storages for rb_connect_tcp below */
memcpy(&l_addr, &auth->l_addr, sizeof(l_addr));
memcpy(&c_addr, &auth->c_addr, sizeof(c_addr));
/* Set the ports correctly */
#ifdef RB_IPV6
if(GET_SS_FAMILY(&l_addr) == AF_INET6)
((struct sockaddr_in6 *)&l_addr)->sin6_port = 0;
else
#endif
((struct sockaddr_in *)&l_addr)->sin_port = 0;
#ifdef RB_IPV6
if(GET_SS_FAMILY(&c_addr) == AF_INET6)
((struct sockaddr_in6 *)&c_addr)->sin6_port = htons(113);
else
#endif
((struct sockaddr_in *)&c_addr)->sin_port = htons(113);
rb_connect_tcp(query->F, (struct sockaddr *)&c_addr,
(struct sockaddr *)&l_addr,
GET_SS_LEN(&l_addr), ident_connected,
auth, ident_timeout);
set_provider_on(auth, PROVIDER_IDENT);
return true;
}
static void
ident_cancel(struct auth_client *auth)
{
struct ident_query *query = auth->data[PROVIDER_IDENT];
if(query != NULL)
client_fail(auth, REPORT_FAIL);
}
static void
add_conf_ident_timeout(const char *key __unused, int parc __unused, const char **parv)
{
int timeout = atoi(parv[0]);
if(timeout < 0)
{
warn_opers(L_CRIT, "BUG: ident timeout < 0 (value: %d)", timeout);
return;
}
ident_timeout = timeout;
}
struct auth_opts_handler ident_options[] =
{
{ "ident_timeout", 1, add_conf_ident_timeout },
{ NULL, 0, NULL },
};
struct auth_provider ident_provider = struct auth_provider ident_provider =
{ {
@ -402,4 +402,5 @@ struct auth_provider ident_provider =
.start = ident_start, .start = ident_start,
.cancel = ident_cancel, .cancel = ident_cancel,
.completed = NULL, .completed = NULL,
.opt_handlers = ident_options,
}; };

View file

@ -22,15 +22,13 @@
#include "rb_commio.h" #include "rb_commio.h"
#include "authd.h" #include "authd.h"
#include "provider.h" #include "provider.h"
#include "notice.h"
#include "res.h" #include "res.h"
#include "dns.h" #include "dns.h"
struct dns_query struct user_query
{ {
rb_dlink_node node; struct dns_query *query; /* Pending DNS query */
struct auth_client *auth; /* Our client */
struct DNSQuery query; /* DNS query */
time_t timeout; /* When the request times out */ time_t timeout; /* When the request times out */
}; };
@ -51,176 +49,157 @@ typedef enum
REPORT_TOOLONG, REPORT_TOOLONG,
} dns_message; } dns_message;
static EVH timeout_dns_queries_event; static void client_fail(struct auth_client *auth, dns_message message);
static void client_fail(struct dns_query *query, dns_message message); static void client_success(struct auth_client *auth);
static void client_success(struct dns_query *query); static void dns_answer_callback(const char *res, bool status, query_type type, void *data);
static void get_dns_answer(void *userdata, struct DNSReply *reply);
static rb_dlink_list queries;
static struct ev_entry *timeout_ev; static struct ev_entry *timeout_ev;
static int rdns_timeout = 30; static EVH timeout_dns_queries_event;
static int rdns_timeout = 15;
static void
bool client_dns_init(void) dns_answer_callback(const char *res, bool status, query_type type, void *data)
{ {
timeout_ev = rb_event_addish("timeout_dns_queries_event", timeout_dns_queries_event, NULL, 5); struct auth_client *auth = data;
return (timeout_ev != NULL); struct user_query *query = auth->data[PROVIDER_RDNS];
}
void client_dns_destroy(void) if(query == NULL || res == NULL || status == false)
{ client_fail(auth, REPORT_FAIL);
rb_dlink_node *ptr, *nptr; else if(strlen(res) > HOSTLEN)
struct dns_query *query; client_fail(auth, REPORT_TOOLONG);
else
RB_DLINK_FOREACH_SAFE(ptr, nptr, queries.head)
{ {
client_fail(ptr->data, REPORT_FAIL); rb_strlcpy(auth->hostname, res, HOSTLEN + 1);
rb_dlinkDelete(ptr, &queries); client_success(auth);
rb_free(ptr);
} }
rb_event_delete(timeout_ev);
} }
bool client_dns_start(struct auth_client *auth) /* Timeout outstanding queries */
static void
timeout_dns_queries_event(void *notused)
{ {
struct dns_query *query = rb_malloc(sizeof(struct dns_query)); struct auth_client *auth;
rb_dictionary_iter iter;
query->auth = auth; RB_DICTIONARY_FOREACH(auth, &iter, auth_clients)
query->timeout = rb_current_time() + rdns_timeout;
query->query.ptr = query;
query->query.callback = get_dns_answer;
gethost_byaddr(&auth->c_addr, &query->query);
notice_client(auth, messages[REPORT_LOOKUP]);
set_provider(auth, PROVIDER_RDNS);
return true;
}
void client_dns_cancel(struct auth_client *auth)
{
rb_dlink_node *ptr;
/* Bah, the stupid DNS resolver code doesn't have a cancellation
* func... */
RB_DLINK_FOREACH(ptr, queries.head)
{ {
struct dns_query *query = ptr->data; struct user_query *query = auth->data[PROVIDER_RDNS];
if(query->auth == auth) if(query != NULL && query->timeout < rb_current_time())
{ {
/* This will get cleaned up later by the DNS stuff */ client_fail(auth, REPORT_FAIL);
client_fail(query, REPORT_FAIL);
return; return;
} }
} }
} }
static void static void
get_dns_answer(void *userdata, struct DNSReply *reply) client_fail(struct auth_client *auth, dns_message report)
{ {
struct dns_query *query = userdata; struct user_query *query = auth->data[PROVIDER_RDNS];
struct auth_client *auth = query->auth;
rb_dlink_node *ptr, *nptr;
bool fail = false;
dns_message response;
if(reply == NULL || auth == NULL) if(query == NULL)
{ return;
response = REPORT_FAIL;
fail = true;
goto cleanup;
}
if(!sockcmp(&auth->c_addr, &reply->addr, GET_SS_FAMILY(&auth->c_addr))) rb_strlcpy(auth->hostname, "*", sizeof(auth->hostname));
{
response = REPORT_FAIL;
fail = true;
goto cleanup;
}
if(strlen(reply->h_name) > HOSTLEN) notice_client(auth->cid, messages[report]);
{ cancel_query(query->query);
/* Ah well. */
response = REPORT_TOOLONG;
fail = true;
goto cleanup;
}
rb_strlcpy(auth->hostname, reply->h_name, HOSTLEN + 1); rb_free(query);
auth->data[PROVIDER_RDNS] = NULL;
cleanup: provider_done(auth, PROVIDER_RDNS);
/* Clean us up off the pending queries list */
RB_DLINK_FOREACH_SAFE(ptr, nptr, queries.head)
{
struct dns_query *query_l = ptr->data;
if(query == query_l)
{
/* Found */
if(fail)
client_fail(query, response);
else
client_success(query);
rb_dlinkDelete(ptr, &queries);
rb_free(query);
return;
}
}
} }
/* Timeout outstanding queries */ static void
static void timeout_dns_queries_event(void *notused) client_success(struct auth_client *auth)
{ {
rb_dlink_node *ptr; struct user_query *query = auth->data[PROVIDER_RDNS];
/* NOTE - we do not delete queries from the list from a timeout, when notice_client(auth->cid, messages[REPORT_FOUND]);
* the query times out later it will be deleted. cancel_query(query->query);
*/
RB_DLINK_FOREACH(ptr, queries.head)
{
struct dns_query *query = ptr->data;
if(query->auth && query->timeout < rb_current_time()) rb_free(query);
{ auth->data[PROVIDER_RDNS] = NULL;
client_fail(query, REPORT_FAIL);
} provider_done(auth, PROVIDER_RDNS);
}
} }
static void client_fail(struct dns_query *query, dns_message report) static bool
rdns_init(void)
{ {
struct auth_client *auth = query->auth; timeout_ev = rb_event_addish("timeout_dns_queries_event", timeout_dns_queries_event, NULL, 1);
return (timeout_ev != NULL);
if(auth)
{
rb_strlcpy(auth->hostname, "*", sizeof(auth->hostname));
notice_client(auth, messages[report]);
provider_done(auth, PROVIDER_RDNS);
query->auth = NULL;
}
} }
static void client_success(struct dns_query *query) static void
rdns_destroy(void)
{ {
struct auth_client *auth = query->auth; struct auth_client *auth;
rb_dictionary_iter iter;
if(auth) RB_DICTIONARY_FOREACH(auth, &iter, auth_clients)
{ {
notice_client(auth, messages[REPORT_FOUND]); if(auth->data[PROVIDER_RDNS] != NULL)
provider_done(auth, PROVIDER_RDNS); client_fail(auth, REPORT_FAIL);
query->auth = NULL;
} }
rb_event_delete(timeout_ev);
} }
static bool
rdns_start(struct auth_client *auth)
{
struct user_query *query = rb_malloc(sizeof(struct user_query));
query->timeout = rb_current_time() + rdns_timeout;
auth->data[PROVIDER_RDNS] = query;
query->query = lookup_hostname(auth->c_ip, dns_answer_callback, auth);
notice_client(auth->cid, messages[REPORT_LOOKUP]);
set_provider_on(auth, PROVIDER_RDNS);
return true;
}
static void
rdns_cancel(struct auth_client *auth)
{
struct user_query *query = auth->data[PROVIDER_RDNS];
if(query != NULL)
client_fail(auth, REPORT_FAIL);
}
static void
add_conf_dns_timeout(const char *key, int parc, const char **parv)
{
int timeout = atoi(parv[0]);
if(timeout < 0)
{
warn_opers(L_CRIT, "BUG: DNS timeout < 0 (value: %d)", timeout);
return;
}
rdns_timeout = timeout;
}
struct auth_opts_handler rdns_options[] =
{
{ "dns_timeout", 1, add_conf_dns_timeout },
{ NULL, 0, NULL },
};
struct auth_provider rdns_provider = struct auth_provider rdns_provider =
{ {
.id = PROVIDER_RDNS, .id = PROVIDER_RDNS,
.init = client_dns_init, .init = rdns_init,
.destroy = client_dns_destroy, .destroy = rdns_destroy,
.start = client_dns_start, .start = rdns_start,
.cancel = client_dns_cancel, .cancel = rdns_cancel,
.completed = NULL, .completed = NULL,
.opt_handlers = rdns_options,
}; };

View file

@ -98,7 +98,6 @@ static int check_question(struct reslist *request, HEADER * header, char *buf, c
static int proc_answer(struct reslist *request, HEADER * header, char *, char *); static int proc_answer(struct reslist *request, HEADER * header, char *, char *);
static struct reslist *find_id(int id); static struct reslist *find_id(int id);
static struct DNSReply *make_dnsreply(struct reslist *request); static struct DNSReply *make_dnsreply(struct reslist *request);
static int generate_random_port(void);
static uint16_t generate_random_id(void); static uint16_t generate_random_id(void);
#ifdef RES_MIN #ifdef RES_MIN
@ -107,55 +106,6 @@ static uint16_t generate_random_id(void);
#define RES_MIN(a, b) ((a) < (b) ? (a) : (b)) #define RES_MIN(a, b) ((a) < (b) ? (a) : (b))
static rb_fde_t *
random_socket(int family)
{
rb_fde_t *F;
int nport;
int i;
rb_socklen_t len;
struct rb_sockaddr_storage sockaddr;
F = rb_socket(family, SOCK_DGRAM, 0, "UDP resolver socket");
if(F == NULL)
return NULL;
memset(&sockaddr, 0, sizeof(sockaddr));
SET_SS_FAMILY(&sockaddr, family);
#ifdef RB_IPV6
if(family == AF_INET6)
{
struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)&sockaddr;
memcpy(&in6->sin6_addr, &ipv6_addr, sizeof(struct in6_addr));
len = (rb_socklen_t) sizeof(struct sockaddr_in6);
}
else
#endif
{
struct sockaddr_in *in = (struct sockaddr_in *)&sockaddr;
in->sin_addr.s_addr = ipv4_addr.s_addr;
len = (rb_socklen_t) sizeof(struct sockaddr_in);
}
for(i = 0; i < 10; i++)
{
nport = htons(generate_random_port());
if(family == AF_INET)
((struct sockaddr_in *)&sockaddr)->sin_port = nport;
#ifdef RB_IPV6
else
((struct sockaddr_in6 *)&sockaddr)->sin6_port = nport;
#endif
if(bind(rb_get_fd(F), (struct sockaddr *)&sockaddr, len) == 0)
return F;
}
rb_close(F);
return NULL;
}
/* /*
* int * int
* res_ourserver(inp) * res_ourserver(inp)
@ -167,7 +117,8 @@ random_socket(int family)
* revised for ircd, cryogen(stu) may03 * revised for ircd, cryogen(stu) may03
* slightly modified for charybdis, mr_flea oct12 * slightly modified for charybdis, mr_flea oct12
*/ */
static int res_ourserver(const struct rb_sockaddr_storage *inp) static int
res_ourserver(const struct rb_sockaddr_storage *inp)
{ {
#ifdef RB_IPV6 #ifdef RB_IPV6
const struct sockaddr_in6 *v6; const struct sockaddr_in6 *v6;
@ -177,49 +128,43 @@ static int res_ourserver(const struct rb_sockaddr_storage *inp)
const struct sockaddr_in *v4in = (const struct sockaddr_in *)inp; const struct sockaddr_in *v4in = (const struct sockaddr_in *)inp;
int ns; int ns;
for (ns = 0; ns < irc_nscount; ns++) for(ns = 0; ns < irc_nscount; ns++)
{ {
const struct rb_sockaddr_storage *srv = &irc_nsaddr_list[ns]; const struct rb_sockaddr_storage *srv = &irc_nsaddr_list[ns];
if (srv->ss_family != inp->ss_family)
continue;
#ifdef RB_IPV6 #ifdef RB_IPV6
v6 = (const struct sockaddr_in6 *)srv; v6 = (const struct sockaddr_in6 *)srv;
#endif #endif
v4 = (const struct sockaddr_in *)srv; v4 = (const struct sockaddr_in *)srv;
/* could probably just memcmp(srv, inp, srv.ss_len) here /* could probably just memcmp(srv, inp, srv.ss_len) here
* but we'll err on the side of caution - stu * but we'll air on the side of caution - stu
*/ */
switch (srv->ss_family) switch (GET_SS_FAMILY(srv))
{ {
#ifdef RB_IPV6 #ifdef RB_IPV6
case AF_INET6: case AF_INET6:
if (v6->sin6_port == v6in->sin6_port) if(GET_SS_FAMILY(srv) == GET_SS_FAMILY(inp))
if ((memcmp(&v6->sin6_addr.s6_addr, &v6in->sin6_addr.s6_addr, if(v6->sin6_port == v6in->sin6_port)
sizeof(struct in6_addr)) == 0) || if((memcmp(&v6->sin6_addr.s6_addr, &v6in->sin6_addr.s6_addr,
(memcmp(&v6->sin6_addr.s6_addr, &in6addr_any, sizeof(struct in6_addr)) == 0) ||
sizeof(struct in6_addr)) == 0)) (memcmp(&v6->sin6_addr.s6_addr, &in6addr_any,
{ sizeof(struct in6_addr)) == 0))
return ns; return 1;
} break;
break;
#endif #endif
case AF_INET: case AF_INET:
if (v4->sin_port == v4in->sin_port) if(GET_SS_FAMILY(srv) == GET_SS_FAMILY(inp))
if ((v4->sin_addr.s_addr == INADDR_ANY) if(v4->sin_port == v4in->sin_port)
|| (v4->sin_addr.s_addr == v4in->sin_addr.s_addr)) if((v4->sin_addr.s_addr == INADDR_ANY)
{ || (v4->sin_addr.s_addr == v4in->sin_addr.s_addr))
return ns; return 1;
} break;
break; default:
default: break;
break;
} }
} }
return -1; return 0;
} }
/* /*
@ -280,7 +225,7 @@ static void start_resolver(void)
if (res_fd == NULL) if (res_fd == NULL)
{ {
if ((res_fd = rb_socket(irc_nsaddr_list[0].ss_family, SOCK_DGRAM, 0, if ((res_fd = rb_socket(GET_SS_FAMILY(&irc_nsaddr_list[0]), SOCK_DGRAM, 0,
"UDP resolver socket")) == NULL) "UDP resolver socket")) == NULL)
return; return;
@ -472,20 +417,6 @@ generate_random_id(void)
return id; return id;
} }
static int
generate_random_port(void)
{
uint16_t port;
while(1)
{
rb_get_random(&port, sizeof(port));
if(port > 1024)
break;
}
return (int)port;
}
/* /*
* gethost_byname_type - get host address from name, adding domain if needed * gethost_byname_type - get host address from name, adding domain if needed
*/ */
@ -534,6 +465,52 @@ static void do_query_name(struct DNSQuery *query, const char *name, struct resli
query_name(request); query_name(request);
} }
/* Build an rDNS style query - if suffix is NULL, use the appropriate .arpa zone */
void build_rdns(char *buf, size_t size, const struct rb_sockaddr_storage *addr, const char *suffix)
{
const unsigned char *cp;
if (GET_SS_FAMILY(addr) == AF_INET)
{
const struct sockaddr_in *v4 = (const struct sockaddr_in *)addr;
cp = (const unsigned char *)&v4->sin_addr.s_addr;
(void) snprintf(buf, size, "%u.%u.%u.%u.%s",
(unsigned int)(cp[3]),
(unsigned int)(cp[2]),
(unsigned int)(cp[1]),
(unsigned int)(cp[0]),
suffix == NULL ? "in-addr.arpa" : suffix);
}
#ifdef RB_IPV6
else if (GET_SS_FAMILY(addr) == AF_INET6)
{
const struct sockaddr_in6 *v6 = (const struct sockaddr_in6 *)addr;
cp = (const unsigned char *)&v6->sin6_addr.s6_addr;
(void) snprintf(buf, size,
"%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%s",
(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),
suffix == NULL ? "ip6.arpa" : suffix);
}
#endif
}
/* /*
* do_query_number - Use this to do reverse IP# lookups. * do_query_number - Use this to do reverse IP# lookups.
*/ */
@ -549,40 +526,7 @@ static void do_query_number(struct DNSQuery *query, const struct rb_sockaddr_sto
request->name = (char *)rb_malloc(IRCD_RES_HOSTLEN + 1); request->name = (char *)rb_malloc(IRCD_RES_HOSTLEN + 1);
} }
if (addr->ss_family == AF_INET) build_rdns(request->queryname, IRCD_RES_HOSTLEN + 1, addr, NULL);
{
const struct sockaddr_in *v4 = (const struct sockaddr_in *)addr;
cp = (const unsigned char *)&v4->sin_addr.s_addr;
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; request->type = T_PTR;
query_name(request); query_name(request);
@ -918,7 +862,7 @@ static int res_read_single_reply(rb_fde_t *F, void *data)
* ip#. * ip#.
*/ */
#ifdef RB_IPV6 #ifdef RB_IPV6
if (request->addr.ss_family == AF_INET6) if (GET_SS_FAMILY(&request->addr) == AF_INET6)
gethost_byname_type_fqdn(request->name, request->query, T_AAAA); gethost_byname_type_fqdn(request->name, request->query, T_AAAA);
else else
#endif #endif

View file

@ -32,5 +32,6 @@ extern void init_resolver(void);
extern void restart_resolver(void); extern void restart_resolver(void);
extern void gethost_byname_type(const char *, struct DNSQuery *, int); extern void gethost_byname_type(const char *, struct DNSQuery *, int);
extern void gethost_byaddr(const struct rb_sockaddr_storage *, struct DNSQuery *); extern void gethost_byaddr(const struct rb_sockaddr_storage *, struct DNSQuery *);
extern void build_rdns(char *, size_t, const struct rb_sockaddr_storage *, const char *);
#endif #endif

View file

@ -76,9 +76,27 @@
* - Dianora * - Dianora
*/ */
#include <rb_lib.h>
#ifndef _WIN32
#include <netdb.h>
typedef struct addrinfo rb_addrinfo;
#else
#include "getaddrinfo.h"
#include "getnameinfo.h"
#define getaddrinfo rb_getaddrinfo
#define getnameinfo rb_getnameinfo
#define freeaddrinfo rb_freeaddrinfo
extern const char * get_windows_nameservers(void);
typedef struct rb_addrinfo rb_addrinfo;
#endif
#include "stdinc.h" #include "stdinc.h"
#include "ircd_defs.h" #include "ircd_defs.h"
#include "common.h"
#include "ircd.h" #include "ircd.h"
#include "res.h" #include "res.h"
#include "reslib.h" #include "reslib.h"
@ -112,7 +130,12 @@ static const char digitvalue[256] = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*256*/ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*256*/
}; };
#ifndef _WIN32
static int parse_resvconf(void); static int parse_resvconf(void);
#else
static void parse_windows_resolvers(void);
#endif
static void add_nameserver(const char *); static void add_nameserver(const char *);
static const char digits[] = "0123456789"; static const char digits[] = "0123456789";
@ -139,12 +162,31 @@ int
irc_res_init(void) irc_res_init(void)
{ {
irc_nscount = 0; irc_nscount = 0;
#ifndef _WIN32
parse_resvconf(); parse_resvconf();
#else
parse_windows_resolvers();
#endif
if (irc_nscount == 0) if (irc_nscount == 0)
add_nameserver("127.0.0.1"); add_nameserver("127.0.0.1");
return 0; return 0;
} }
#ifdef _WIN32
static void
parse_windows_resolvers(void)
{
const char *ns = get_windows_nameservers();
char *server;
char *p;
char *buf = rb_strdup(ns);
for(server = rb_strtok_r(buf, " ", &p); server != NULL;server = rb_strtok_r(NULL, " ", &p))
{
add_nameserver(server);
}
rb_free(buf);
}
#else
/* parse_resvconf() /* parse_resvconf()
* *
* inputs - NONE * inputs - NONE
@ -210,6 +252,7 @@ parse_resvconf(void)
fclose(file); fclose(file);
return 0; return 0;
} }
#endif
/* add_nameserver() /* add_nameserver()
* *
@ -221,7 +264,7 @@ parse_resvconf(void)
static void static void
add_nameserver(const char *arg) add_nameserver(const char *arg)
{ {
struct addrinfo hints, *res; rb_addrinfo hints, *res;
/* Done max number of nameservers? */ /* Done max number of nameservers? */
if (irc_nscount >= IRCD_MAXNS) if (irc_nscount >= IRCD_MAXNS)

View file

@ -78,24 +78,24 @@ typedef struct
*/ */
#define IRC_NS_GET16(s, cp) { \ #define IRC_NS_GET16(s, cp) { \
const unsigned char *t_cp = (const unsigned char *)(cp); \ const unsigned char *t_cp = (const unsigned char *)(cp); \
(s) = ((u_int16_t)t_cp[0] << 8) \ (s) = ((uint16_t)t_cp[0] << 8) \
| ((u_int16_t)t_cp[1]) \ | ((uint16_t)t_cp[1]) \
; \ ; \
(cp) += NS_INT16SZ; \ (cp) += NS_INT16SZ; \
} }
#define IRC_NS_GET32(l, cp) { \ #define IRC_NS_GET32(l, cp) { \
const unsigned char *t_cp = (const unsigned char *)(cp); \ const unsigned char *t_cp = (const unsigned char *)(cp); \
(l) = ((u_int32_t)t_cp[0] << 24) \ (l) = ((uint32_t)t_cp[0] << 24) \
| ((u_int32_t)t_cp[1] << 16) \ | ((uint32_t)t_cp[1] << 16) \
| ((u_int32_t)t_cp[2] << 8) \ | ((uint32_t)t_cp[2] << 8) \
| ((u_int32_t)t_cp[3]) \ | ((uint32_t)t_cp[3]) \
; \ ; \
(cp) += NS_INT32SZ; \ (cp) += NS_INT32SZ; \
} }
#define IRC_NS_PUT16(s, cp) { \ #define IRC_NS_PUT16(s, cp) { \
u_int16_t t_s = (u_int16_t)(s); \ uint16_t t_s = (uint16_t)(s); \
unsigned char *t_cp = (unsigned char *)(cp); \ unsigned char *t_cp = (unsigned char *)(cp); \
*t_cp++ = t_s >> 8; \ *t_cp++ = t_s >> 8; \
*t_cp = t_s; \ *t_cp = t_s; \
@ -103,7 +103,7 @@ typedef struct
} }
#define IRC_NS_PUT32(l, cp) { \ #define IRC_NS_PUT32(l, cp) { \
u_int32_t t_l = (u_int32_t)(l); \ uint32_t t_l = (uint32_t)(l); \
unsigned char *t_cp = (unsigned char *)(cp); \ unsigned char *t_cp = (unsigned char *)(cp); \
*t_cp++ = t_l >> 24; \ *t_cp++ = t_l >> 24; \
*t_cp++ = t_l >> 16; \ *t_cp++ = t_l >> 16; \

276
authd/reslist.c Normal file
View file

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

View file

@ -81,7 +81,7 @@ parse_options "$@"
echo "Building librb autotools files." echo "Building librb autotools files."
cd "$TOP_DIR"/librb cd "$TOP_DIR"/librb
bash autogen.sh sh autogen.sh
echo "Building main autotools files." echo "Building main autotools files."

View file

@ -31,7 +31,7 @@
#include <rb_lib.h> #include <rb_lib.h>
#include <stdio.h> #include <stdio.h>
#include "rsdb.h" #include "rsdb.h"
#include "common.h" #include "ircd_defs.h"
#define MAXPARA 10 #define MAXPARA 10
@ -255,7 +255,7 @@ dummy_handler(int sig)
static void static void
setup_signals(void) setup_signals(void)
{ {
#ifndef WINDOWS #ifndef _WIN32
struct sigaction act; struct sigaction act;
act.sa_flags = 0; act.sa_flags = 0;

View file

@ -40,7 +40,6 @@
#include <time.h> #include <time.h>
#include "stdinc.h" #include "stdinc.h"
#include "common.h"
#include "rsdb.h" #include "rsdb.h"
#define EmptyString(x) ((x == NULL) || (*(x) == '\0')) #define EmptyString(x) ((x == NULL) || (*(x) == '\0'))
@ -93,16 +92,16 @@ struct counter
/* flags set by command line options */ /* flags set by command line options */
struct flags struct flags
{ {
int none; bool none;
int export; bool export;
int import; bool import;
int verify; bool verify;
int vacuum; bool vacuum;
int pretend; bool pretend;
int verbose; bool verbose;
int wipe; bool wipe;
int dupes_ok; bool dupes_ok;
} flag = {YES, NO, NO, NO, NO, NO, NO, NO, NO}; } flag = {true, false, false, false, false, false, false, false, false};
/* *INDENT-ON* */ /* *INDENT-ON* */
static int table_has_rows(const char *table); static int table_has_rows(const char *table);
@ -145,32 +144,32 @@ main(int argc, char *argv[])
print_help(EXIT_SUCCESS); print_help(EXIT_SUCCESS);
break; break;
case 'i': case 'i':
flag.none = NO; flag.none = false;
flag.import = YES; flag.import = true;
break; break;
case 'e': case 'e':
flag.none = NO; flag.none = false;
flag.export = YES; flag.export = true;
break; break;
case 'u': case 'u':
flag.none = NO; flag.none = false;
flag.verify = YES; flag.verify = true;
break; break;
case 's': case 's':
flag.none = NO; flag.none = false;
flag.vacuum = YES; flag.vacuum = true;
break; break;
case 'p': case 'p':
flag.pretend = YES; flag.pretend = true;
break; break;
case 'v': case 'v':
flag.verbose = YES; flag.verbose = true;
break; break;
case 'w': case 'w':
flag.wipe = YES; flag.wipe = true;
break; break;
case 'd': case 'd':
flag.dupes_ok = YES; flag.dupes_ok = true;
break; break;
default: /* '?' */ default: /* '?' */
print_help(EXIT_FAILURE); print_help(EXIT_FAILURE);
@ -200,7 +199,7 @@ main(int argc, char *argv[])
fprintf(stdout, fprintf(stdout,
"* charybdis bantool v.%s\n", BT_VERSION); "* charybdis bantool v.%s\n", BT_VERSION);
if(flag.pretend == NO) if(flag.pretend == false)
{ {
if(rsdb_init(db_error_cb) == -1) if(rsdb_init(db_error_cb) == -1)
{ {
@ -214,7 +213,7 @@ main(int argc, char *argv[])
if(flag.import && flag.wipe) if(flag.import && flag.wipe)
{ {
flag.dupes_ok = YES; /* dont check for dupes if we are wiping the db clean */ flag.dupes_ok = true; /* dont check for dupes if we are wiping the db clean */
for(i = 0; i < 3; i++) for(i = 0; i < 3; i++)
fprintf(stdout, fprintf(stdout,
"* WARNING: YOU ARE ABOUT TO WIPE YOUR DATABASE!\n"); "* WARNING: YOU ARE ABOUT TO WIPE YOUR DATABASE!\n");
@ -226,7 +225,7 @@ main(int argc, char *argv[])
wipe_schema(); wipe_schema();
} }
} }
if(flag.verbose && flag.dupes_ok == YES) if(flag.verbose && flag.dupes_ok == true)
fprintf(stdout, "* Allowing duplicate bans...\n"); fprintf(stdout, "* Allowing duplicate bans...\n");
/* checking for our files to import or export */ /* checking for our files to import or export */
@ -235,7 +234,7 @@ main(int argc, char *argv[])
snprintf(conf, sizeof(conf), "%s/%s.conf%s", snprintf(conf, sizeof(conf), "%s/%s.conf%s",
etc, bandb_table[i], bandb_suffix[i]); etc, bandb_table[i], bandb_suffix[i]);
if(flag.import && flag.pretend == NO) if(flag.import && flag.pretend == false)
rsdb_transaction(RSDB_TRANS_START); rsdb_transaction(RSDB_TRANS_START);
if(flag.import) if(flag.import)
@ -244,7 +243,7 @@ main(int argc, char *argv[])
if(flag.export) if(flag.export)
export_config(conf, i); export_config(conf, i);
if(flag.import && flag.pretend == NO) if(flag.import && flag.pretend == false)
rsdb_transaction(RSDB_TRANS_END); rsdb_transaction(RSDB_TRANS_END);
} }
@ -497,9 +496,9 @@ import_config(const char *conf, int id)
else else
snprintf(newreason, sizeof(newreason), "%s", f_reason); snprintf(newreason, sizeof(newreason), "%s", f_reason);
if(flag.pretend == NO) if(flag.pretend == false)
{ {
if(flag.dupes_ok == NO) if(flag.dupes_ok == false)
drop_dupes(f_mask1, f_mask2, bandb_table[id]); drop_dupes(f_mask1, f_mask2, bandb_table[id]);
rsdb_exec(NULL, rsdb_exec(NULL,

View file

@ -25168,7 +25168,7 @@ winFullPathname(sqlite3_vfs * pVfs, /* Pointer to vfs object */
{ {
#if defined(__CYGWIN__) #if defined(__CYGWIN__)
cygwin_conv_to_full_win32_path(zRelative, zFull); cygwin_conv_path(CCP_POSIX_TO_WIN_A, zRelative, zFull, nFull);
return SQLITE_OK; return SQLITE_OK;
#endif #endif

View file

@ -19,6 +19,7 @@ fi
AC_PREFIX_DEFAULT($HOME/ircd) AC_PREFIX_DEFAULT($HOME/ircd)
AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_HEADER(include/setup.h) AC_CONFIG_HEADER(include/setup.h)
AC_CONFIG_SUBDIRS([librb]) AC_CONFIG_SUBDIRS([librb])
AC_CONFIG_AUX_DIR([libltdl/config]) AC_CONFIG_AUX_DIR([libltdl/config])
@ -33,6 +34,24 @@ LTDL_INIT
build_ltdl=$with_included_ltdl build_ltdl=$with_included_ltdl
AM_CONDITIONAL([BUILD_LTDL], [test x"$build_ltdl" = x"yes"]) AM_CONDITIONAL([BUILD_LTDL], [test x"$build_ltdl" = x"yes"])
case "$host_os" in
*cygwin*)
AC_DEFINE_UNQUOTED(CYGWIN,1,[This is a Cygwin system])
AC_DEFINE_UNQUOTED(WINDOWS,1,[This is a Windows system])
;;
*mingw* | *msys*)
AC_DEFINE_UNQUOTED(MINGW,1,[This is a MinGW system])
AC_DEFINE_UNQUOTED(WINDOWS,1,[This is a Windows system])
AC_CHECK_HEADER(winsock2.h, , [AC_MSG_ERROR([** MinGW and no winsock2.h. I give up.])])
LIBS="$LIBS -lws2_32 -liphlpapi"
is_mingw="yes"
;;
*)
;;
esac
AM_CONDITIONAL([MINGW], [test "$is_mingw" = "yes"])
if test "$ac_cv_c_compiler_gnu" = yes; then if test "$ac_cv_c_compiler_gnu" = yes; then
IRC_CFLAGS="$IRC_CFLAGS -O0 -Wall" IRC_CFLAGS="$IRC_CFLAGS -O0 -Wall"
fi fi
@ -102,7 +121,8 @@ AS_IF([test "x$enable_fhs_paths" = "xyes"],
pkglibexecdir='${libexecdir}/${PACKAGE_TARNAME}' pkglibexecdir='${libexecdir}/${PACKAGE_TARNAME}'
rundir=${rundir-'${prefix}/run'} rundir=${rundir-'${prefix}/run'}
pkgrundir='${rundir}/${PACKAGE_TARNAME}' pkgrundir='${rundir}/${PACKAGE_TARNAME}'
pkglocalstatedir='${localstatedir}/${PACKAGE_TARNAME}'], pkglocalstatedir='${localstatedir}/${PACKAGE_TARNAME}'
AC_DEFINE([ENABLE_FHS_PATHS], [1], [Uncomment if FHS pathnames are enabled])],
[libexecdir='${bindir}' [libexecdir='${bindir}'
pkglibexecdir='${libexecdir}' pkglibexecdir='${libexecdir}'
rundir='${sysconfdir}' rundir='${sysconfdir}'
@ -141,19 +161,13 @@ AC_CHECK_SIZEOF(long long)
dnl Networking Functions dnl Networking Functions
dnl ==================== dnl ====================
AC_SEARCH_LIBS(socket, socket, , [AC_MSG_ERROR([You have no socket()! Aborting.])]) AC_SEARCH_LIBS(socket, [socket ws2_32], , [AC_MSG_ERROR([You have no socket()! Aborting.])])
dnl SunOS/Solaris required libnsl for inet_ntoa() dnl SunOS/Solaris required libnsl for inet_ntoa()
if test x"$SUN" = xyes; then if test x"$SUN" = xyes; then
AC_SEARCH_LIBS(inet_ntoa, nsl,, [AC_MSG_ERROR([libnsl not found! Aborting.])]) AC_SEARCH_LIBS(inet_ntoa, nsl,, [AC_MSG_ERROR([libnsl not found! Aborting.])])
fi fi
AC_CHECK_TYPE(socklen_t, ,
[AC_DEFINE([socklen_t], [unsigned int],
[If we don't have a real socklen_t, unsigned int is good enough.])],
[#include <sys/types.h>
#include <sys/socket.h>])
AC_ARG_ENABLE(ipv6, AC_ARG_ENABLE(ipv6,
AC_HELP_STRING([--enable-ipv6],[Enable IPv6 support]),[ipv6=$enableval],[ipv6=no]) AC_HELP_STRING([--enable-ipv6],[Enable IPv6 support]),[ipv6=$enableval],[ipv6=no])
@ -175,34 +189,8 @@ dnl Check for stdarg.h - if we can't find it, halt configure
AC_CHECK_HEADER(stdarg.h, , [AC_MSG_ERROR([** stdarg.h could not be found - charybdis will not compile without it **])]) AC_CHECK_HEADER(stdarg.h, , [AC_MSG_ERROR([** stdarg.h could not be found - charybdis will not compile without it **])])
AC_CHECK_FUNCS([strlcat strlcpy]) AC_CHECK_FUNCS([strlcat strlcpy])
AC_CHECK_TYPE([u_int32_t], [], AC_TYPE_INT16_T
[ AC_TYPE_INT32_T
AC_CHECK_TYPE([uint32_t],
[
AC_DEFINE(u_int32_t, [uint32_t], [If system does not define u_int32_t, define a reasonable substitute.])
],
[
AC_MSG_WARN([system has no u_int32_t or uint32_t, default to unsigned long int])
AC_DEFINE(u_int32_t, [unsigned long int], [If system does not define u_int32_t, define to unsigned long int here.])
])
])
AC_CHECK_TYPE([u_int16_t], [],
[
AC_CHECK_TYPE([uint16_t],
[
AC_DEFINE(u_int16_t, [uint16_t], [If system does not define u_int16_t, define a usable substitute])
],
[
AC_MSG_WARN([system has no u_int16_t or uint16_t, default to unsigned short int])
AC_DEFINE(u_int16_t, [unsigned short int], [If system does not define u_int16_t, define a usable substitute.])
])
])
AC_CHECK_TYPE([in_port_t], [],
[AC_DEFINE(in_port_t, [u_int16_t], [If system does not define in_port_t, define it to what it should be.])],
[[#include <sys/types.h>
#include <netinet/in.h>]])
AC_CHECK_TYPE([sa_family_t], [], AC_CHECK_TYPE([sa_family_t], [],
[AC_DEFINE(sa_family_t, [u_int16_t], [If system does not define sa_family_t, define it here.])], [AC_DEFINE(sa_family_t, [u_int16_t], [If system does not define sa_family_t, define it here.])],
@ -497,6 +485,18 @@ if test "x$BRANDING_NAME" != "x$PACKAGE_NAME"; then
AC_DEFINE(CUSTOM_BRANDING, 1, [Define if custom branding is enabled.]) AC_DEFINE(CUSTOM_BRANDING, 1, [Define if custom branding is enabled.])
fi fi
dnl **********************************************************************
dnl Enable oper chghost
dnl **********************************************************************
AC_ARG_ENABLE(oper-chghost,
AC_HELP_STRING([--enable-oper-chghost],[Enable opers to use the CHGHOST command]),
[operchghost=$enableval],[operchghost=no])
if test "$operchghost" = yes; then
AC_DEFINE(ENABLE_OPER_CHGHOST, 1, [Define this to enable opers to use the CHGHOST command.])
fi
dnl Debug-related options dnl Debug-related options
dnl ===================== dnl =====================
@ -607,7 +607,7 @@ CHARYBDIS_C_GCC_TRY_FLAGS([-Wcast-qual], charybdis_cv_c_gcc_w_cast_qual)
CHARYBDIS_C_GCC_TRY_FLAGS([-Wwrite-strings], charybdis_cv_c_gcc_w_write_strings) CHARYBDIS_C_GCC_TRY_FLAGS([-Wwrite-strings], charybdis_cv_c_gcc_w_write_strings)
CHARYBDIS_C_GCC_TRY_FLAGS([-Werror-implicit-function-declaration], charybdis_cv_c_gcc_w_error_implicit_function_declaration) CHARYBDIS_C_GCC_TRY_FLAGS([-Werror-implicit-function-declaration], charybdis_cv_c_gcc_w_error_implicit_function_declaration)
CHARYBDIS_C_GCC_TRY_FLAGS([-Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations], charybdis_cv_c_gcc_prototypes) CHARYBDIS_C_GCC_TRY_FLAGS([-Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations], charybdis_cv_c_gcc_prototypes)
CHARYBDIS_C_GCC_TRY_FLAGS([-Wparenthesis], charybdis_cv_c_gcc_parenthesis) CHARYBDIS_C_GCC_TRY_FLAGS([-Wparentheses], charybdis_cv_c_gcc_parentheses)
CHARYBDIS_C_GCC_TRY_FLAGS([-W -Wno-unused], charybdis_cv_c_gcc_w) CHARYBDIS_C_GCC_TRY_FLAGS([-W -Wno-unused], charybdis_cv_c_gcc_w)
CHARYBDIS_C_GCC_TRY_FLAGS([-Wextra], charybdis_cv_c_gcc_w_extra) CHARYBDIS_C_GCC_TRY_FLAGS([-Wextra], charybdis_cv_c_gcc_w_extra)
CHARYBDIS_C_GCC_TRY_FLAGS([-Wshadow], charybdis_cv_c_gcc_w_shadow) CHARYBDIS_C_GCC_TRY_FLAGS([-Wshadow], charybdis_cv_c_gcc_w_shadow)
@ -656,6 +656,7 @@ AC_CONFIG_FILES( \
authd/Makefile \ authd/Makefile \
bandb/Makefile \ bandb/Makefile \
ssld/Makefile \ ssld/Makefile \
wsockd/Makefile \
extensions/Makefile \ extensions/Makefile \
ircd/Makefile \ ircd/Makefile \
modules/Makefile \ modules/Makefile \

View file

@ -8,33 +8,33 @@
*/ */
/* Extensions */ /* Extensions */
#loadmodule "extensions/chm_operonly_compat.la"; #loadmodule "extensions/chm_operonly_compat";
#loadmodule "extensions/chm_quietunreg_compat.la"; #loadmodule "extensions/chm_quietunreg_compat";
#loadmodule "extensions/chm_sslonly_compat.la"; #loadmodule "extensions/chm_sslonly_compat";
#loadmodule "extensions/chm_operpeace.la"; #loadmodule "extensions/chm_operpeace";
#loadmodule "extensions/createauthonly.la"; #loadmodule "extensions/createauthonly";
#loadmodule "extensions/extb_account.la"; #loadmodule "extensions/extb_account";
#loadmodule "extensions/extb_canjoin.la"; #loadmodule "extensions/extb_canjoin";
#loadmodule "extensions/extb_channel.la"; #loadmodule "extensions/extb_channel";
#loadmodule "extensions/extb_combi.la"; #loadmodule "extensions/extb_combi";
#loadmodule "extensions/extb_extgecos.la"; #loadmodule "extensions/extb_extgecos";
#loadmodule "extensions/extb_hostmask.la"; #loadmodule "extensions/extb_hostmask";
#loadmodule "extensions/extb_oper.la"; #loadmodule "extensions/extb_oper";
#loadmodule "extensions/extb_realname.la"; #loadmodule "extensions/extb_realname";
#loadmodule "extensions/extb_server.la"; #loadmodule "extensions/extb_server";
#loadmodule "extensions/extb_ssl.la"; #loadmodule "extensions/extb_ssl";
#loadmodule "extensions/hurt.la"; #loadmodule "extensions/hurt";
#loadmodule "extensions/m_extendchans.la"; #loadmodule "extensions/m_extendchans";
#loadmodule "extensions/m_findforwards.la"; #loadmodule "extensions/m_findforwards";
#loadmodule "extensions/m_identify.la"; #loadmodule "extensions/m_identify";
#loadmodule "extensions/no_oper_invis.la"; #loadmodule "extensions/no_oper_invis";
#loadmodule "extensions/sno_farconnect.la"; #loadmodule "extensions/sno_farconnect";
#loadmodule "extensions/sno_globalkline.la"; #loadmodule "extensions/sno_globalkline";
#loadmodule "extensions/sno_globalnickchange.la"; #loadmodule "extensions/sno_globalnickchange";
#loadmodule "extensions/sno_globaloper.la"; #loadmodule "extensions/sno_globaloper";
#loadmodule "extensions/sno_whois.la"; #loadmodule "extensions/sno_whois";
#loadmodule "extensions/override.la"; #loadmodule "extensions/override";
#loadmodule "extensions/no_kill_services.la"; #loadmodule "extensions/no_kill_services";
/* /*
* IP cloaking extensions: use ip_cloaking_4.0 * IP cloaking extensions: use ip_cloaking_4.0
@ -43,15 +43,14 @@
* releases. * releases.
*/ */
#loadmodule "extensions/ip_cloaking_4.0.la"; #loadmodule "extensions/ip_cloaking_4.0";
#loadmodule "extensions/ip_cloaking.la"; #loadmodule "extensions/ip_cloaking";
serverinfo { serverinfo {
name = "hades.arpa"; name = "hades.arpa";
sid = "42X"; sid = "42X";
description = "charybdis test server"; description = "charybdis test server";
network_name = "StaticBox"; network_name = "StaticBox";
hub = yes;
/* On multi-homed hosts you may need the following. These define /* On multi-homed hosts you may need the following. These define
* the addresses we connect from to other servers. */ * the addresses we connect from to other servers. */

View file

@ -43,73 +43,73 @@
* Charybdis contains several extensions that are not enabled by default. * Charybdis contains several extensions that are not enabled by default.
* To use them, uncomment the lines below. * To use them, uncomment the lines below.
* *
* Channel mode +-A (admin only) -- chm_adminonly.la * Channel mode +-A (admin only) -- chm_adminonly
* Channel mode +-O (oper only) -- chm_operonly.la * Channel mode +-O (oper only) -- chm_operonly
* Channel mode +-S (ssl only) -- chm_sslonly.la * Channel mode +-S (ssl only) -- chm_sslonly
* Emulates channel mode +-O (oper only) (+-iI $o) -- chm_operonly_compat.la * Emulates channel mode +-O (oper only) (+-iI $o) -- chm_operonly_compat
* Emulates channel mode +-R (quiet unreg) (+-q $~a) -- chm_quietunreg_compat.la * Emulates channel mode +-R (quiet unreg) (+-q $~a) -- chm_quietunreg_compat
* Emulates channel mode +-S (ssl only) (+-b $~z) -- chm_sslonly_compat.la * Emulates channel mode +-S (ssl only) (+-b $~z) -- chm_sslonly_compat
* Channel mode +-M (disallow KICK on IRC ops) -- chm_operpeace.la * Channel mode +-M (disallow KICK on IRC ops) -- chm_operpeace
* Restrict channel creation to logged in users -- createauthonly.la * Restrict channel creation to logged in users -- createauthonly
* Account bans (+b $a[:mask]) -- extb_account.la * Account bans (+b $a[:mask]) -- extb_account
* Banned from another channel (+b $j:mask) -- extb_canjoin.la * Banned from another channel (+b $j:mask) -- extb_canjoin
* Other-channel bans (+b $c:mask) -- extb_channel.la * Other-channel bans (+b $c:mask) -- extb_channel
* Combination extbans -- extb_combi.la * Combination extbans -- extb_combi
* Extended ban (+b $x:mask) -- extb_extgecos.la * Extended ban (+b $x:mask) -- extb_extgecos
* Hostmask bans (for combination extbans) -- extb_hostmask.la * Hostmask bans (for combination extbans) -- extb_hostmask
* Oper bans (+b $o) -- extb_oper.la * Oper bans (+b $o) -- extb_oper
* Realname (gecos) bans (+b $r:mask) -- extb_realname.la * Realname (gecos) bans (+b $r:mask) -- extb_realname
* Server bans (+b $s:mask) -- extb_server.la * Server bans (+b $s:mask) -- extb_server
* SSL bans (+b $z) -- extb_ssl.la * SSL bans (+b $z) -- extb_ssl
* Helpops system (umode +H) -- helpops.la * Helpops system (umode +H) -- helpops
* HURT system -- hurt.la * HURT system -- hurt
* New host mangling (umode +x) -- ip_cloaking_4.0.la * New host mangling (umode +x) -- ip_cloaking_4.0
* Old host mangling (umode +h) -- ip_cloaking.la * Old host mangling (umode +h) -- ip_cloaking
* Dynamically extend channel limits -- m_extendchans.la * Dynamically extend channel limits -- m_extendchans
* Find channel forwards -- m_findforwards.la * Find channel forwards -- m_findforwards
* /identify support -- m_identify.la * /identify support -- m_identify
* Opers cannot be invisible (umode +i) -- no_oper_invis.la * Opers cannot be invisible (umode +i) -- no_oper_invis
* Far connection notices (snomask +F) -- sno_farconnect.la * Far connection notices (snomask +F) -- sno_farconnect
* Remote k/d/x line active notices -- sno_globalkline.la * Remote k/d/x line active notices -- sno_globalkline
* Remote oper up notices -- sno_globaloper.la * Remote oper up notices -- sno_globaloper
* Global nick-change notices -- sno_globalnickchange.la * Global nick-change notices -- sno_globalnickchange
* /whois notifications (snomask +W) -- sno_whois.la * /whois notifications (snomask +W) -- sno_whois
* Oper-override (modehacking only) -- override.la * Oper-override (modehacking only) -- override
* Stop services kills -- no_kill_services.la * Stop services kills -- no_kill_services
*/ */
#loadmodule "extensions/chm_adminonly.la"; #loadmodule "extensions/chm_adminonly";
#loadmodule "extensions/chm_operonly.la"; #loadmodule "extensions/chm_operonly";
#loadmodule "extensions/chm_sslonly.la"; #loadmodule "extensions/chm_sslonly";
#loadmodule "extensions/chm_operonly_compat.la"; #loadmodule "extensions/chm_operonly_compat";
#loadmodule "extensions/chm_quietunreg_compat.la"; #loadmodule "extensions/chm_quietunreg_compat";
#loadmodule "extensions/chm_sslonly_compat.la"; #loadmodule "extensions/chm_sslonly_compat";
#loadmodule "extensions/chm_operpeace.la"; #loadmodule "extensions/chm_operpeace";
#loadmodule "extensions/createauthonly.la"; #loadmodule "extensions/createauthonly";
#loadmodule "extensions/extb_account.la"; #loadmodule "extensions/extb_account";
#loadmodule "extensions/extb_canjoin.la"; #loadmodule "extensions/extb_canjoin";
#loadmodule "extensions/extb_channel.la"; #loadmodule "extensions/extb_channel";
#loadmodule "extensions/extb_combi.la"; #loadmodule "extensions/extb_combi";
#loadmodule "extensions/extb_extgecos.la"; #loadmodule "extensions/extb_extgecos";
#loadmodule "extensions/extb_hostmask.la"; #loadmodule "extensions/extb_hostmask";
#loadmodule "extensions/extb_oper.la"; #loadmodule "extensions/extb_oper";
#loadmodule "extensions/extb_realname.la"; #loadmodule "extensions/extb_realname";
#loadmodule "extensions/extb_server.la"; #loadmodule "extensions/extb_server";
#loadmodule "extensions/extb_ssl.la"; #loadmodule "extensions/extb_ssl";
#loadmodule "extensions/helpops.la"; #loadmodule "extensions/helpops";
#loadmodule "extensions/hurt.la"; #loadmodule "extensions/hurt";
#loadmodule "extensions/ip_cloaking_4.0.la"; #loadmodule "extensions/ip_cloaking_4.0";
#loadmodule "extensions/ip_cloaking.la"; #loadmodule "extensions/ip_cloaking";
#loadmodule "extensions/m_extendchans.la"; #loadmodule "extensions/m_extendchans";
#loadmodule "extensions/m_findforwards.la"; #loadmodule "extensions/m_findforwards";
#loadmodule "extensions/m_identify.la"; #loadmodule "extensions/m_identify";
#loadmodule "extensions/no_oper_invis.la"; #loadmodule "extensions/no_oper_invis";
#loadmodule "extensions/sno_farconnect.la"; #loadmodule "extensions/sno_farconnect";
#loadmodule "extensions/sno_globalkline.la"; #loadmodule "extensions/sno_globalkline";
#loadmodule "extensions/sno_globalnickchange.la"; #loadmodule "extensions/sno_globalnickchange";
#loadmodule "extensions/sno_globaloper.la"; #loadmodule "extensions/sno_globaloper";
#loadmodule "extensions/sno_whois.la"; #loadmodule "extensions/sno_whois";
#loadmodule "extensions/override.la"; #loadmodule "extensions/override";
#loadmodule "extensions/no_kill_services.la"; #loadmodule "extensions/no_kill_services";
/* serverinfo {}: Contains information about the server. (OLD M:) */ /* serverinfo {}: Contains information about the server. (OLD M:) */
serverinfo { serverinfo {
@ -134,11 +134,6 @@ serverinfo {
*/ */
network_name = "MyNet"; network_name = "MyNet";
/* hub: allow this server to act as a hub and have multiple servers
* connected to it.
*/
hub = no;
/* vhost: the IP to bind to when we connect outward to ipv4 servers. /* vhost: the IP to bind to when we connect outward to ipv4 servers.
* This should be an ipv4 IP only. * This should be an ipv4 IP only.
*/ */
@ -1349,5 +1344,5 @@ modules {
path = "/usr/local/ircd/modules/autoload"; path = "/usr/local/ircd/modules/autoload";
/* module: the name of a module to load on startup/rehash */ /* module: the name of a module to load on startup/rehash */
#module = "some_module.la"; #module = "some_module";
}; };

View file

@ -17,8 +17,6 @@
+----------------------------+ +----------------------------+
| 'e' | USE_EXCEPT | | 'e' | USE_EXCEPT |
|------+---------------------| |------+---------------------|
| 'H' | HUB |
|------+---------------------|
| 'I' | USE_INVEX | | 'I' | USE_INVEX |
|------+---------------------| |------+---------------------|
| 'K' | USE_KNOCK | | 'K' | USE_KNOCK |
@ -29,8 +27,6 @@
|------+---------------------| |------+---------------------|
| 'S' | OPERS_SEE_ALL_USERS | | 'S' | OPERS_SEE_ALL_USERS |
|------+---------------------| |------+---------------------|
| 'T' | IGNORE_BOGUS_TS |
|------+---------------------|
| 'Z' | ZIPLINKS | | 'Z' | ZIPLINKS |
|------+---------------------| |------+---------------------|
| '6' | IPv6 | | '6' | IPv6 |

View file

@ -1198,8 +1198,6 @@ CAP
CHALLENGE CHALLENGE
CHANTRACE CHANTRACE
CLOSE CLOSE
CNOTICE
CPRIVMSG
DIE DIE
GET GET
HELP HELP

View file

@ -1,7 +1,7 @@
AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/librb/include $(LTDLINCL) AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/librb/include $(LTDLINCL)
AM_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined -shared AM_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined -shared
AM_LDFLAGS += -export-symbols-regex _mheader AM_LDFLAGS += -export-symbols-regex _mheader
LIBS += $(top_srcdir)/librb/src/librb.la $(top_srcdir)/ircd/libircd.la LIBS += $(top_srcdir)/ircd/libircd.la
extensiondir=@moduledir@/extensions extensiondir=@moduledir@/extensions

View file

@ -52,7 +52,7 @@ static int _modinit(void);
static void _moddeinit(void); static void _moddeinit(void);
static int eb_or(const char *data, struct Client *client_p, struct Channel *chptr, long mode_type); static int eb_or(const char *data, struct Client *client_p, struct Channel *chptr, long mode_type);
static int eb_and(const char *data, struct Client *client_p, struct Channel *chptr, long mode_type); static int eb_and(const char *data, struct Client *client_p, struct Channel *chptr, long mode_type);
static int eb_combi(const char *data, struct Client *client_p, struct Channel *chptr, long mode_type, int is_and); static int eb_combi(const char *data, struct Client *client_p, struct Channel *chptr, long mode_type, bool is_and);
static int recursion_depth = 0; static int recursion_depth = 0;
DECLARE_MODULE_AV2(extb_extended, _modinit, _moddeinit, NULL, NULL, NULL, NULL, NULL, extb_desc); DECLARE_MODULE_AV2(extb_extended, _modinit, _moddeinit, NULL, NULL, NULL, NULL, NULL, extb_desc);
@ -76,20 +76,20 @@ _moddeinit(void)
static int eb_or(const char *data, struct Client *client_p, static int eb_or(const char *data, struct Client *client_p,
struct Channel *chptr, long mode_type) struct Channel *chptr, long mode_type)
{ {
return eb_combi(data, client_p, chptr, mode_type, FALSE); return eb_combi(data, client_p, chptr, mode_type, false);
} }
static int eb_and(const char *data, struct Client *client_p, static int eb_and(const char *data, struct Client *client_p,
struct Channel *chptr, long mode_type) struct Channel *chptr, long mode_type)
{ {
return eb_combi(data, client_p, chptr, mode_type, TRUE); return eb_combi(data, client_p, chptr, mode_type, true);
} }
static int eb_combi(const char *data, struct Client *client_p, static int eb_combi(const char *data, struct Client *client_p,
struct Channel *chptr, long mode_type, int is_and) struct Channel *chptr, long mode_type, bool is_and)
{ {
const char *p, *banend; const char *p, *banend;
int have_result = FALSE; bool have_result = false;
int allowed_nodes = 11; int allowed_nodes = 11;
size_t datalen; size_t datalen;
@ -143,12 +143,12 @@ static int eb_combi(const char *data, struct Client *client_p,
recursion_depth++; recursion_depth++;
while (--allowed_nodes) { while (--allowed_nodes) {
int invert = FALSE; bool invert = false;
char *child_data, child_data_buf[BANLEN]; char *child_data, child_data_buf[BANLEN];
ExtbanFunc f; ExtbanFunc f;
if (*p == '~') { if (*p == '~') {
invert = TRUE; invert = true;
p++; p++;
if (p == banend) { if (p == banend) {
MOD_DEBUG("combo invalid: no data after ~"); MOD_DEBUG("combo invalid: no data after ~");
@ -164,7 +164,7 @@ static int eb_combi(const char *data, struct Client *client_p,
if (*p == ':') { if (*p == ':') {
unsigned int parencount = 0; unsigned int parencount = 0;
int escaped = FALSE, done = FALSE; bool escaped = false, done = false;
char *o; char *o;
p++; p++;
@ -173,7 +173,7 @@ static int eb_combi(const char *data, struct Client *client_p,
* we already have_result. * we already have_result.
*/ */
o = child_data = child_data_buf; o = child_data = child_data_buf;
while (TRUE) { while (true) {
if (p == banend) { if (p == banend) {
if (parencount) { if (parencount) {
MOD_DEBUG("combo invalid: EOD while in parens"); MOD_DEBUG("combo invalid: EOD while in parens");
@ -186,11 +186,11 @@ static int eb_combi(const char *data, struct Client *client_p,
if (*p != '(' && *p != ')' && *p != '\\' && *p != ',') if (*p != '(' && *p != ')' && *p != '\\' && *p != ',')
*o++ = '\\'; *o++ = '\\';
*o++ = *p++; *o++ = *p++;
escaped = FALSE; escaped = false;
} else { } else {
switch (*p) { switch (*p) {
case '\\': case '\\':
escaped = TRUE; escaped = true;
break; break;
case '(': case '(':
parencount++; parencount++;
@ -208,7 +208,7 @@ static int eb_combi(const char *data, struct Client *client_p,
if (parencount) if (parencount)
*o++ = *p; *o++ = *p;
else else
done = TRUE; done = true;
break; break;
default: default:
*o++ = *p; *o++ = *p;
@ -239,7 +239,7 @@ static int eb_combi(const char *data, struct Client *client_p,
child_result = child_result == EXTBAN_MATCH; child_result = child_result == EXTBAN_MATCH;
if (is_and ? !child_result : child_result) if (is_and ? !child_result : child_result)
have_result = TRUE; have_result = true;
} }
if (p == banend) if (p == banend)

View file

@ -56,7 +56,7 @@ eb_hostmask(const char *banstr, struct Client *client_p, struct Channel *chptr,
#ifdef RB_IPV6 #ifdef RB_IPV6
/* handle Teredo if necessary */ /* handle Teredo if necessary */
if (client_p->localClient->ip.ss_family == AF_INET6 && ipv4_from_ipv6((const struct sockaddr_in6 *) &client_p->localClient->ip, &ip4)) if (GET_SS_FAMILY(&client_p->localClient->ip) == AF_INET6 && ipv4_from_ipv6((const struct sockaddr_in6 *) &client_p->localClient->ip, &ip4))
{ {
sprintf(src_ip4host, "%s!%s@", client_p->name, client_p->username); sprintf(src_ip4host, "%s!%s@", client_p->name, client_p->username);
s4 = src_ip4host + strlen(src_ip4host); s4 = src_ip4host + strlen(src_ip4host);

View file

@ -20,18 +20,16 @@ DECLARE_MODULE_AV2(echotags, NULL, NULL, echotags_clist, NULL, NULL, NULL, NULL,
static void static void
m_echotags(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char *parv[]) m_echotags(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{ {
int i;
sendto_one_notice(source_p, ":*** You sent %zu tags.", msgbuf_p->n_tags); sendto_one_notice(source_p, ":*** You sent %zu tags.", msgbuf_p->n_tags);
for (i = 0; i < msgbuf_p->n_tags; i++) for (size_t i = 0; i < msgbuf_p->n_tags; i++)
{ {
struct MsgTag *tag = &msgbuf_p->tags[i]; struct MsgTag *tag = &msgbuf_p->tags[i];
if (tag->value) if (tag->value)
sendto_one_notice(source_p, ":*** %d: %s => %s", i, tag->key, tag->value); sendto_one_notice(source_p, ":*** %zu: %s => %s", i, tag->key, tag->value);
else else
sendto_one_notice(source_p, ":*** %d: %s", i, tag->key); sendto_one_notice(source_p, ":*** %zu: %s", i, tag->key);
} }
} }

View file

@ -31,7 +31,6 @@
#include "stdinc.h" #include "stdinc.h"
#include "client.h" #include "client.h"
#include "common.h"
#include "ircd.h" #include "ircd.h"
#include "match.h" #include "match.h"
#include "numeric.h" #include "numeric.h"

View file

@ -31,7 +31,6 @@
#include "stdinc.h" #include "stdinc.h"
#include "client.h" #include "client.h"
#include "common.h"
#include "ircd.h" #include "ircd.h"
#include "match.h" #include "match.h"
#include "numeric.h" #include "numeric.h"
@ -91,7 +90,7 @@ mo_sendbans(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *sou
{ {
struct ConfItem *aconf; struct ConfItem *aconf;
rb_dlink_node *ptr; rb_dlink_node *ptr;
int i, count; int count;
const char *target, *mask2; const char *target, *mask2;
struct Client *server_p; struct Client *server_p;
struct rb_radixtree_iteration_state state; struct rb_radixtree_iteration_state state;

View file

@ -92,7 +92,7 @@ mr_webirc(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *sourc
IsGotId(client_p) ? client_p->username : "webirc", IsGotId(client_p) ? client_p->username : "webirc",
IsGotId(client_p) ? client_p->username : "webirc", IsGotId(client_p) ? client_p->username : "webirc",
(struct sockaddr *) &client_p->localClient->ip, (struct sockaddr *) &client_p->localClient->ip,
client_p->localClient->ip.ss_family, NULL); GET_SS_FAMILY(&client_p->localClient->ip), NULL);
if (aconf == NULL || !(aconf->status & CONF_CLIENT)) if (aconf == NULL || !(aconf->status & CONF_CLIENT))
return; return;
if (!IsConfDoSpoofIp(aconf) || irccmp(aconf->info.name, "webirc.")) if (!IsConfDoSpoofIp(aconf) || irccmp(aconf->info.name, "webirc."))
@ -145,7 +145,7 @@ mr_webirc(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *sourc
/* Check dlines now, klines will be checked on registration */ /* Check dlines now, klines will be checked on registration */
if((aconf = find_dline((struct sockaddr *)&source_p->localClient->ip, if((aconf = find_dline((struct sockaddr *)&source_p->localClient->ip,
source_p->localClient->ip.ss_family))) GET_SS_FAMILY(&source_p->localClient->ip))))
{ {
if(!(aconf->status & CONF_EXEMPTDLINE)) if(!(aconf->status & CONF_EXEMPTDLINE))
{ {

View file

@ -13,7 +13,7 @@ SYMLINKS= topic accept cmode admin names links away whowas \
version kick who invite quit join list nick oper part \ version kick who invite quit join list nick oper part \
time credits motd userhost users whois ison lusers \ time credits motd userhost users whois ison lusers \
user help pass error challenge knock ping pong \ user help pass error challenge knock ping pong \
cprivmsg cnotice map trace chantrace extban monitor map trace chantrace extban monitor
all: all:
build: build:

View file

@ -1,5 +0,0 @@
CNOTICE <nick> <channel> :<text>
Providing you are opped (+o) or voiced (+v) in <channel>, and <nick>
is a member of <channel>, CNOTICE generates a NOTICE towards
<nick>. CNOTICE bypasses any anti-spam measures in place.

View file

@ -1,5 +0,0 @@
CPRIVMSG <nick> <channel> :<text>
Providing you are opped (+o) or voiced (+v) in <channel>, and <nick>
is a member of <channel>, CPRIVMSG generates a PRIVMSG towards
<nick>. CPRIVMSG bypasses any anti-spam measures in place.

View file

@ -2,23 +2,23 @@ Help topics available to opers:
ACCEPT ADMIN AWAY CAPAB ACCEPT ADMIN AWAY CAPAB
CHALLENGE CHANTRACE CLOSE CMODE CHALLENGE CHANTRACE CLOSE CMODE
CNOTICE CONNECT CPRIVMSG CREDITS CONNECT CREDITS DIE DLINE
DIE DLINE ERROR ETRACE ERROR ETRACE EXTBAN HELP
EXTBAN HELP INDEX INFO INDEX INFO INVITE ISON
INVITE ISON JOIN KICK JOIN KICK KILL KLINE
KILL KLINE KNOCK LINKS KNOCK LINKS LIST LOCOPS
LIST LOCOPS LUSERS MAP LUSERS MAP MASKTRACE MODLIST
MASKTRACE MODLIST MODLOAD MODRELOAD MODLOAD MODRELOAD MODRESTART MODUNLOAD
MODRESTART MODUNLOAD MONITOR MOTD MONITOR MOTD NAMES NICK
NAMES NICK NOTICE OPER NOTICE OPER OPERSPY OPERWALL
OPERSPY OPERWALL PART PASS PART PASS PING PONG
PING PONG POST PRIVMSG POST PRIVMSG PRIVS QUIT
PRIVS QUIT REHASH RESTART REHASH RESTART RESV SCAN
RESV SCAN SERVER SET SERVER SET SJOIN SNOMASK
SJOIN SNOMASK SQUIT STATS SQUIT STATS SVINFO TESTGECOS
SVINFO TESTGECOS TESTLINE TESTMASK TESTLINE TESTMASK TIME TOPIC
TIME TOPIC TRACE UHELP TRACE UHELP UMODE UNDLINE
UMODE UNDLINE UNKLINE UNREJECT UNKLINE UNREJECT UNRESV UNXLINE
UNRESV UNXLINE USER USERHOST USER USERHOST USERS VERSION
USERS VERSION WALLOPS WHO WALLOPS WHO WHOIS WHOWAS
WHOIS WHOWAS XLINE XLINE

View file

@ -1,14 +1,14 @@
Help topics available to users: Help topics available to users:
ACCEPT ADMIN AWAY CHALLENGE ACCEPT ADMIN AWAY CHALLENGE
CHANTRACE CMODE CNOTICE CPRIVMSG CHANTRACE CMODE CREDITS ERROR
CREDITS ERROR EXTBAN HELP EXTBAN HELP INDEX INFO
INDEX INFO INVITE ISON INVITE ISON JOIN KICK
JOIN KICK KNOCK LINKS KNOCK LINKS LIST LUSERS
LIST LUSERS MAP MONITOR MAP MONITOR MOTD NAMES
MOTD NAMES NICK NOTICE NICK NOTICE OPER PART
OPER PART PASS PING PASS PING PONG PRIVMSG
PONG PRIVMSG QUIT STATS QUIT STATS TIME TOPIC
TIME TOPIC TRACE UMODE TRACE UMODE USER USERHOST
USER USERHOST USERS VERSION USERS VERSION WHO WHOIS
WHO WHOIS WHOWAS WHOWAS

View file

@ -36,7 +36,7 @@ struct Blacklist {
int ipv6; /* Does this blacklist support IPv6 lookups? */ int ipv6; /* Does this blacklist support IPv6 lookups? */
char host[IRCD_RES_HOSTLEN + 1]; char host[IRCD_RES_HOSTLEN + 1];
rb_dlink_list filters; /* Filters for queries */ rb_dlink_list filters; /* Filters for queries */
char reject_reason[IRCD_BUFSIZE]; char reject_reason[BUFSIZE];
unsigned int hits; unsigned int hits;
time_t lastwarning; time_t lastwarning;
}; };

View file

@ -1,6 +1,8 @@
#ifndef INCLUDED_CACHE_H #ifndef INCLUDED_CACHE_H
#define INCLUDED_CACHE_H #define INCLUDED_CACHE_H
#include "rb_dictionary.h"
#define HELP_MAX 100 #define HELP_MAX 100
#define CACHEFILELEN 30 #define CACHEFILELEN 30
@ -43,8 +45,7 @@ void send_user_motd(struct Client *);
void send_oper_motd(struct Client *); void send_oper_motd(struct Client *);
void cache_user_motd(void); void cache_user_motd(void);
struct Dictionary; extern rb_dictionary *help_dict_oper;
extern struct Dictionary *help_dict_oper; extern rb_dictionary *help_dict_user;
extern struct Dictionary *help_dict_user;
#endif #endif

View file

@ -21,9 +21,12 @@
#ifndef __CAPABILITY_H__ #ifndef __CAPABILITY_H__
#define __CAPABILITY_H__ #define __CAPABILITY_H__
#include "stdinc.h"
#include "rb_dictionary.h"
struct CapabilityIndex { struct CapabilityIndex {
const char *name; const char *name;
struct Dictionary *cap_dict; rb_dictionary *cap_dict;
unsigned int highest_bit; unsigned int highest_bit;
rb_dlink_node node; rb_dlink_node node;
}; };

View file

@ -73,7 +73,7 @@ struct Channel
unsigned int join_count; /* joins within delta */ unsigned int join_count; /* joins within delta */
unsigned int join_delta; /* last ts of join */ unsigned int join_delta; /* last ts of join */
unsigned long bants; time_t bants;
time_t channelts; time_t channelts;
char *chname; char *chname;
@ -93,7 +93,7 @@ struct membership
struct Client *client_p; struct Client *client_p;
unsigned int flags; unsigned int flags;
unsigned long bants; time_t bants;
}; };
#define BANLEN 195 #define BANLEN 195
@ -213,7 +213,7 @@ extern void destroy_channel(struct Channel *);
extern int can_send(struct Channel *chptr, struct Client *who, extern int can_send(struct Channel *chptr, struct Client *who,
struct membership *); struct membership *);
extern int flood_attack_channel(int p_or_n, struct Client *source_p, extern bool flood_attack_channel(int p_or_n, struct Client *source_p,
struct Channel *chptr, char *chname); struct Channel *chptr, char *chname);
extern int is_banned(struct Channel *chptr, struct Client *who, extern int is_banned(struct Channel *chptr, struct Client *who,
struct membership *msptr, const char *, const char *, const char **); struct membership *msptr, const char *, const char *, const char **);
@ -231,7 +231,7 @@ extern void invalidate_bancache_user(struct Client *);
extern void free_channel_list(rb_dlink_list *); extern void free_channel_list(rb_dlink_list *);
extern int check_channel_name(const char *name); extern bool check_channel_name(const char *name);
extern void channel_member_names(struct Channel *chptr, struct Client *, extern void channel_member_names(struct Channel *chptr, struct Client *,
int show_eon); int show_eon);
@ -264,7 +264,7 @@ extern void set_channel_mlock(struct Client *client_p, struct Client *source_p,
extern struct ChannelMode chmode_table[256]; extern struct ChannelMode chmode_table[256];
extern int add_id(struct Client *source_p, struct Channel *chptr, const char *banid, extern bool add_id(struct Client *source_p, struct Channel *chptr, const char *banid,
const char *forward, rb_dlink_list * list, long mode_type); const char *forward, rb_dlink_list * list, long mode_type);
extern struct Ban * del_id(struct Channel *chptr, const char *banid, rb_dlink_list * list, extern struct Ban * del_id(struct Channel *chptr, const char *banid, rb_dlink_list * list,

View file

@ -26,11 +26,7 @@
#ifndef INCLUDED_client_h #ifndef INCLUDED_client_h
#define INCLUDED_client_h #define INCLUDED_client_h
#include "config.h" #include "defaults.h"
#if !defined(CONFIG_CHARYBDIS_LEVEL_1)
#error Incorrect config.h for this revision of ircd.
#endif
#include "ircd_defs.h" #include "ircd_defs.h"
#include "channel.h" #include "channel.h"
@ -170,7 +166,9 @@ struct Client
struct LocalUser struct LocalUser
{ {
rb_dlink_node tnode; /* This is the node for the local list type the client is on*/ rb_dlink_node tnode; /* This is the node for the local list type the client is on */
rb_dlink_list connids; /* This is the list of connids to free */
/* /*
* The following fields are allocated only for local clients * The following fields are allocated only for local clients
* (directly connected to *this* server with a socket. * (directly connected to *this* server with a socket.
@ -237,7 +235,6 @@ struct LocalUser
time_t next_away; /* Don't allow next away before... */ time_t next_away; /* Don't allow next away before... */
time_t last; time_t last;
uint32_t connid;
/* clients allowed to talk through +g */ /* clients allowed to talk through +g */
rb_dlink_list allow_list; rb_dlink_list allow_list;
@ -276,7 +273,6 @@ struct LocalUser
struct _ssl_ctl *ssl_ctl; /* which ssl daemon we're associate with */ struct _ssl_ctl *ssl_ctl; /* which ssl daemon we're associate with */
struct _ssl_ctl *z_ctl; /* second ctl for ssl+zlib */ struct _ssl_ctl *z_ctl; /* second ctl for ssl+zlib */
uint32_t zconnid;
uint32_t localflags; uint32_t localflags;
struct ZipStats *zipstats; /* zipstats */ struct ZipStats *zipstats; /* zipstats */
uint16_t cork_count; /* used for corking/uncorking connections */ uint16_t cork_count; /* used for corking/uncorking connections */
@ -609,4 +605,8 @@ extern char *generate_uid(void);
void allocate_away(struct Client *); void allocate_away(struct Client *);
void free_away(struct Client *); void free_away(struct Client *);
uint32_t connid_get(struct Client *client_p);
void connid_put(uint32_t id);
void client_release_connids(struct Client *client_p);
#endif /* INCLUDED_client_h */ #endif /* INCLUDED_client_h */

View file

@ -1,58 +0,0 @@
/*
* ircd-ratbox: A slightly useful ircd.
* common.h: An ircd header common to most code.
*
* Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
* Copyright (C) 1996-2002 Hybrid Development Team
* Copyright (C) 2002-2004 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
*/
#ifndef INCLUDED_common_h
#define INCLUDED_common_h
#ifndef NULL
#define NULL 0
#endif
/* Blah. I use these a lot. -Dianora */
#ifdef YES
#undef YES
#endif
#define YES 1
#ifdef NO
#undef NO
#endif
#define NO 0
/* Just blindly define our own MIN/MAX macro */
#define IRCD_MAX(a, b) ((a) > (b) ? (a) : (b))
#define IRCD_MIN(a, b) ((a) < (b) ? (a) : (b))
/* Right out of the RFC */
#define IRCD_BUFSIZE 512
/* readbuf size */
#define READBUF_SIZE 16384
#endif /* INCLUDED_common_h */

View file

@ -1,116 +0,0 @@
/*
* ircd-ratbox: A slightly useful ircd.
* config.h: The ircd compile-time-configurable header.
*
* Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
* Copyright (C) 1996-2002 Hybrid Development Team
* Copyright (C) 2002-2004 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
*/
#ifndef INCLUDED_config_h
#define INCLUDED_config_h
#include "setup.h"
/*
* Directory paths and filenames for UNIX systems.
* IRCD_PREFIX is set using ./configure --prefix, see INSTALL.
* The other defaults should be fine.
*
* NOTE: CHANGING THESE WILL NOT ALTER THE DIRECTORY THAT FILES WILL
* BE INSTALLED TO. IF YOU CHANGE THESE, DO NOT USE MAKE INSTALL,
* BUT COPY THE FILES MANUALLY TO WHERE YOU WANT THEM.
*
* IRCD_PREFIX = prefix for all directories,
* DPATH = root directory of installation,
* BINPATH = directory for binary files,
* ETCPATH = directory for configuration files,
* LOGPATH = directory for logfiles,
* MODPATH = directory for modules,
* AUTOMODPATH = directory for autoloaded modules
*/
/* dirs */
#define DPATH IRCD_PREFIX
#define BINPATH IRCD_PREFIX "/bin/"
#define MODPATH MODULE_DIR
#define AUTOMODPATH MODULE_DIR "/autoload/"
#define ETCPATH ETC_DIR
#define LOGPATH LOG_DIR
#define UHPATH HELP_DIR "/users"
#define HPATH HELP_DIR "/opers"
/* files */
#define SPATH BINPATH "/" PROGRAM_PREFIX "charybdis" /* ircd executable */
#define CPATH ETCPATH "/ircd.conf" /* ircd.conf file */
#define MPATH ETCPATH "/ircd.motd" /* MOTD file */
#define LPATH LOGPATH "/ircd.log" /* ircd logfile */
#define PPATH PKGRUNDIR "/ircd.pid" /* pid file */
#define OPATH ETCPATH "/opers.motd" /* oper MOTD file */
#define DBPATH PKGLOCALSTATEDIR "/ban.db" /* bandb file */
/* IGNORE_BOGUS_TS
* Ignore bogus timestamps from other servers. Yes this will desync
* the network, but it will allow chanops to resync with a valid non TS 0
*
* This should be enabled network wide, or not at all.
*/
#undef IGNORE_BOGUS_TS
/* HANGONGOODLINK and HANGONRETRYDELAY
* Often net breaks for a short time and it's useful to try to
* establishing the same connection again faster than CONNECTFREQUENCY
* would allow. But, to keep trying on bad connection, we require
* that connection has been open for certain minimum time
* (HANGONGOODLINK) and we give the net few seconds to steady
* (HANGONRETRYDELAY). This latter has to be long enough that the
* other end of the connection has time to notice it broke too.
* 1997/09/18 recommended values by ThemBones for modern EFnet
*/
#define HANGONRETRYDELAY 60 /* Recommended value: 30-60 seconds */
#define HANGONGOODLINK 3600 /* Recommended value: 30-60 minutes */
/* KILLCHASETIMELIMIT -
* Max time from the nickname change that still causes KILL
* automatically to switch for the current nick of that user. (seconds)
*/
#define KILLCHASETIMELIMIT 90 /* Recommended value: 90 */
/* CHARYBDIS_SOMAXCONN
* Use SOMAXCONN if OS has it, otherwise use this value for the
* listen(); backlog. 5 for AIX/SUNOS, 25 for other OSs.
*/
#define CHARYBDIS_SOMAXCONN 25
/* MAX_BUFFER
* The amount of fds to reserve for clients exempt from limits
* and dns lookups.
*/
#define MAX_BUFFER 60
/* ----------------------------------------------------------------
* STOPSTOPSTOPSTOPSTOPSTOPSTOPSTOPSTOPSTOPSTOPSTOPSTOPSTOPSTOPSTOP
* ----------------------------------------------------------------
* The options below this line should NOT be modified.
* ----------------------------------------------------------------
*/
#define CONFIG_CHARYBDIS_LEVEL_2
#include "defaults.h"
#endif /* INCLUDED_config_h */

View file

@ -1,116 +0,0 @@
/*
* ircd-ratbox: A slightly useful ircd.
* config.h: The ircd compile-time-configurable header.
*
* Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
* Copyright (C) 1996-2002 Hybrid Development Team
* Copyright (C) 2002-2004 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
*/
#ifndef INCLUDED_config_h
#define INCLUDED_config_h
#include "setup.h"
/*
* Directory paths and filenames for UNIX systems.
* IRCD_PREFIX is set using ./configure --prefix, see INSTALL.
* The other defaults should be fine.
*
* NOTE: CHANGING THESE WILL NOT ALTER THE DIRECTORY THAT FILES WILL
* BE INSTALLED TO. IF YOU CHANGE THESE, DO NOT USE MAKE INSTALL,
* BUT COPY THE FILES MANUALLY TO WHERE YOU WANT THEM.
*
* IRCD_PREFIX = prefix for all directories,
* DPATH = root directory of installation,
* BINPATH = directory for binary files,
* ETCPATH = directory for configuration files,
* LOGPATH = directory for logfiles,
* MODPATH = directory for modules,
* AUTOMODPATH = directory for autoloaded modules
*/
/* dirs */
#define DPATH IRCD_PREFIX
#define BINPATH IRCD_PREFIX "/bin/"
#define MODPATH MODULE_DIR
#define AUTOMODPATH MODULE_DIR "/autoload/"
#define ETCPATH ETC_DIR
#define LOGPATH LOG_DIR
#define UHPATH HELP_DIR "/users"
#define HPATH HELP_DIR "/opers"
/* files */
#define SPATH BINPATH "/" PROGRAM_PREFIX "charybdis" /* ircd executable */
#define CPATH ETCPATH "/ircd.conf" /* ircd.conf file */
#define MPATH ETCPATH "/ircd.motd" /* MOTD file */
#define LPATH LOGPATH "/ircd.log" /* ircd logfile */
#define PPATH PKGRUNDIR "/ircd.pid" /* pid file */
#define OPATH ETCPATH "/opers.motd" /* oper MOTD file */
#define DBPATH PKGLOCALSTATEDIR "/ban.db" /* bandb file */
/* IGNORE_BOGUS_TS
* Ignore bogus timestamps from other servers. Yes this will desync
* the network, but it will allow chanops to resync with a valid non TS 0
*
* This should be enabled network wide, or not at all.
*/
#undef IGNORE_BOGUS_TS
/* HANGONGOODLINK and HANGONRETRYDELAY
* Often net breaks for a short time and it's useful to try to
* establishing the same connection again faster than CONNECTFREQUENCY
* would allow. But, to keep trying on bad connection, we require
* that connection has been open for certain minimum time
* (HANGONGOODLINK) and we give the net few seconds to steady
* (HANGONRETRYDELAY). This latter has to be long enough that the
* other end of the connection has time to notice it broke too.
* 1997/09/18 recommended values by ThemBones for modern EFnet
*/
#define HANGONRETRYDELAY 60 /* Recommended value: 30-60 seconds */
#define HANGONGOODLINK 3600 /* Recommended value: 30-60 minutes */
/* KILLCHASETIMELIMIT -
* Max time from the nickname change that still causes KILL
* automatically to switch for the current nick of that user. (seconds)
*/
#define KILLCHASETIMELIMIT 90 /* Recommended value: 90 */
/* CHARYBDIS_SOMAXCONN
* Use SOMAXCONN if OS has it, otherwise use this value for the
* listen(); backlog. 5 for AIX/SUNOS, 25 for other OSs.
*/
#define CHARYBDIS_SOMAXCONN 25
/* MAX_BUFFER
* The amount of fds to reserve for clients exempt from limits
* and dns lookups.
*/
#define MAX_BUFFER 60
/* ----------------------------------------------------------------
* STOPSTOPSTOPSTOPSTOPSTOPSTOPSTOPSTOPSTOPSTOPSTOPSTOPSTOPSTOPSTOP
* ----------------------------------------------------------------
* The options below this line should NOT be modified.
* ----------------------------------------------------------------
*/
#define CONFIG_CHARYBDIS_LEVEL_2
#include "defaults.h"
#endif /* INCLUDED_config_h */

View file

@ -25,14 +25,38 @@
#ifndef INCLUDED_defaults_h #ifndef INCLUDED_defaults_h
#define INCLUDED_defaults_h #define INCLUDED_defaults_h
/* this file is included (only) at the end of config.h, to supply default /* /!\ DANGER WILL ROBINSON! DANGER! /!\
* values for things which are now configurable at runtime. *
* Do not mess with these values unless you know what you are doing!
*/ */
#include "setup.h"
/* /*
* First, set other fd limits based on values from user * First, set other fd limits based on values from user
*/ */
typedef enum {
IRCD_PATH_PREFIX,
IRCD_PATH_MODULES,
IRCD_PATH_AUTOLOAD_MODULES,
IRCD_PATH_ETC,
IRCD_PATH_LOG,
IRCD_PATH_USERHELP,
IRCD_PATH_OPERHELP,
IRCD_PATH_IRCD_EXEC,
IRCD_PATH_IRCD_CONF,
IRCD_PATH_IRCD_MOTD,
IRCD_PATH_IRCD_LOG,
IRCD_PATH_IRCD_PID,
IRCD_PATH_IRCD_OMOTD,
IRCD_PATH_BANDB,
IRCD_PATH_BIN,
IRCD_PATH_LIBEXEC,
IRCD_PATH_COUNT
} ircd_path_t;
extern const char *ircd_paths[IRCD_PATH_COUNT];
#define MAXCONNECTIONS 65535 /* default max connections if getrlimit doesn't work */ #define MAXCONNECTIONS 65535 /* default max connections if getrlimit doesn't work */
/* class {} default values */ /* class {} default values */
@ -59,5 +83,64 @@
#define JOIN_LEAVE_COUNT_EXPIRE_TIME 120 #define JOIN_LEAVE_COUNT_EXPIRE_TIME 120
#define MIN_SPAM_NUM 5 #define MIN_SPAM_NUM 5
#define MIN_SPAM_TIME 60 #define MIN_SPAM_TIME 60
#define CONFIG_CHARYBDIS_LEVEL_1
/*
* Directory paths and filenames for UNIX systems.
* IRCD_PREFIX is set using ./configure --prefix, see INSTALL.
*
* IRCD_PREFIX = prefix for all directories,
* DPATH = root directory of installation,
* BINPATH = directory for binary files,
* ETCPATH = directory for configuration files,
* LOGPATH = directory for logfiles,
* MODPATH = directory for modules,
* AUTOMODPATH = directory for autoloaded modules
*/
#define DPATH IRCD_PREFIX
#define BINPATH IRCD_PREFIX "/bin/"
#define MODPATH MODULE_DIR
#define AUTOMODPATH MODULE_DIR "/autoload/"
#define ETCPATH ETC_DIR
#define LOGPATH LOG_DIR
#define UHPATH HELP_DIR "/users"
#define HPATH HELP_DIR "/opers"
#define SPATH BINPATH "/" PROGRAM_PREFIX "charybdis" /* ircd executable */
#define CPATH ETCPATH "/ircd.conf" /* ircd.conf file */
#define MPATH ETCPATH "/ircd.motd" /* MOTD file */
#define LPATH LOGPATH "/ircd.log" /* ircd logfile */
#define PPATH PKGRUNDIR "/ircd.pid" /* pid file */
#define OPATH ETCPATH "/opers.motd" /* oper MOTD file */
#define DBPATH PKGLOCALSTATEDIR "/ban.db" /* bandb file */
/* HANGONGOODLINK and HANGONRETRYDELAY
* Often net breaks for a short time and it's useful to try to
* establishing the same connection again faster than CONNECTFREQUENCY
* would allow. But, to keep trying on bad connection, we require
* that connection has been open for certain minimum time
* (HANGONGOODLINK) and we give the net few seconds to steady
* (HANGONRETRYDELAY). This latter has to be long enough that the
* other end of the connection has time to notice it broke too.
*/
#define HANGONRETRYDELAY 60 /* Recommended value: 30-60 seconds */
#define HANGONGOODLINK 3600 /* Recommended value: 30-60 minutes */
/* KILLCHASETIMELIMIT -
* Max time from the nickname change that still causes KILL
* automatically to switch for the current nick of that user. (seconds)
*/
#define KILLCHASETIMELIMIT 90 /* Recommended value: 90 */
/* MAX_BUFFER
* The amount of fds to reserve for clients exempt from limits
* and dns lookups.
*/
#define MAX_BUFFER 60
/* CHARYBDIS_SOMAXCONN
* Use SOMAXCONN if OS has it, otherwise use this value for the
* listen(); backlog. 5 for AIX/SUNOS, 25 for other OSs.
*/
#define CHARYBDIS_SOMAXCONN 25
#endif /* INCLUDED_defaults_h */ #endif /* INCLUDED_defaults_h */

View file

@ -34,12 +34,15 @@ extern rb_dlink_list nameservers;
typedef void (*DNSCB)(const char *res, int status, int aftype, void *data); typedef void (*DNSCB)(const char *res, int status, int aftype, void *data);
typedef void (*DNSLISTCB)(int resc, const char *resv[], int status, void *data); typedef void (*DNSLISTCB)(int resc, const char *resv[], int status, void *data);
uint16_t lookup_hostname(const char *hostname, int aftype, DNSCB callback, void *data); uint32_t lookup_hostname(const char *hostname, int aftype, DNSCB callback, void *data);
uint16_t lookup_ip(const char *hostname, int aftype, DNSCB callback, void *data); uint32_t lookup_ip(const char *hostname, int aftype, DNSCB callback, void *data);
void cancel_lookup(uint16_t xid); void cancel_lookup(uint32_t xid);
void cancel_dns_stats(uint32_t xid);
void dns_results_callback(const char *callid, const char *status, const char *aftype, const char *results); void dns_results_callback(const char *callid, const char *status, const char *aftype, const char *results);
void dns_stats_results_callback(const char *callid, const char *status, int resc, const char *resv[]); void dns_stats_results_callback(const char *callid, const char *status, int resc, const char *resv[]);
void init_nameserver_cache(void);
bool reload_nameservers(void); void init_dns(void);
void reload_nameservers(void);
#endif #endif

View file

@ -25,12 +25,12 @@
#ifndef INCLUDED_hash_h #ifndef INCLUDED_hash_h
#define INCLUDED_hash_h #define INCLUDED_hash_h
struct Dictionary; #include "rb_dictionary.h"
struct rb_radixtree; #include "rb_radixtree.h"
extern struct Dictionary *nd_dict; extern rb_dictionary *nd_dict;
extern struct rb_radixtree *resv_tree; extern rb_radixtree *resv_tree;
extern struct rb_radixtree *channel_tree; extern rb_radixtree *channel_tree;
/* Magic value for FNV hash functions */ /* Magic value for FNV hash functions */
#define FNV1_32_INIT 0x811c9dc5UL #define FNV1_32_INIT 0x811c9dc5UL
@ -65,10 +65,10 @@ struct ConfItem;
struct cachefile; struct cachefile;
struct nd_entry; struct nd_entry;
extern u_int32_t fnv_hash_upper(const unsigned char *s, int bits); extern uint32_t fnv_hash_upper(const unsigned char *s, int bits);
extern u_int32_t fnv_hash(const unsigned char *s, int bits); extern uint32_t fnv_hash(const unsigned char *s, int bits);
extern u_int32_t fnv_hash_len(const unsigned char *s, int bits, int len); extern uint32_t fnv_hash_len(const unsigned char *s, int bits, int len);
extern u_int32_t fnv_hash_upper_len(const unsigned char *s, int bits, int len); extern uint32_t fnv_hash_upper_len(const unsigned char *s, int bits, int len);
extern void init_hash(void); extern void init_hash(void);
@ -95,11 +95,8 @@ extern void del_from_resv_hash(const char *name, struct ConfItem *aconf);
extern struct ConfItem *hash_find_resv(const char *name); extern struct ConfItem *hash_find_resv(const char *name);
extern void clear_resv_hash(void); extern void clear_resv_hash(void);
void add_to_cli_connid_hash(struct Client *client_p); void add_to_cli_connid_hash(struct Client *client_p, uint32_t id);
void del_from_cli_connid_hash(struct Client *client_p); void del_from_cli_connid_hash(uint32_t id);
struct Client *find_cli_connid_hash(uint32_t connid); struct Client *find_cli_connid_hash(uint32_t connid);
void add_to_zconnid_hash(struct Client *client_p);
void del_from_zconnid_hash(struct Client *client_p);
#endif /* INCLUDED_hash_h */ #endif /* INCLUDED_hash_h */

View file

@ -54,7 +54,7 @@ struct ConfItem *find_dline(struct sockaddr *, int);
#define find_kline(x) (find_conf_by_address((x)->host, (x)->sockhost, \ #define find_kline(x) (find_conf_by_address((x)->host, (x)->sockhost, \
(x)->orighost, \ (x)->orighost, \
(struct sockaddr *)&(x)->localClient->ip, CONF_KILL,\ (struct sockaddr *)&(x)->localClient->ip, CONF_KILL,\
(x)->localClient->ip.ss_family, (x)->username, NULL)) GET_SS_FAMILY(&(x)->localClient->ip), (x)->username, NULL))
void report_auth(struct Client *); void report_auth(struct Client *);
#ifdef RB_IPV6 #ifdef RB_IPV6

View file

@ -25,7 +25,7 @@
#ifndef INCLUDED_ircd_h #ifndef INCLUDED_ircd_h
#define INCLUDED_ircd_h #define INCLUDED_ircd_h
#include "config.h" #include "defaults.h"
struct Client; struct Client;
struct rb_dlink_list; struct rb_dlink_list;
@ -99,8 +99,8 @@ extern int testing_conf;
extern struct ev_entry *check_splitmode_ev; extern struct ev_entry *check_splitmode_ev;
extern bool ssl_ok; extern bool ircd_ssl_ok;
extern bool zlib_ok; extern bool ircd_zlib_ok;
extern int maxconnections; extern int maxconnections;
void ircd_shutdown(const char *reason); void ircd_shutdown(const char *reason);

View file

@ -35,7 +35,7 @@
#ifndef INCLUDED_ircd_defs_h #ifndef INCLUDED_ircd_defs_h
#define INCLUDED_ircd_defs_h #define INCLUDED_ircd_defs_h
#include "config.h" #include "defaults.h"
/* For those unfamiliar with GNU format attributes, a is the 1 based /* For those unfamiliar with GNU format attributes, a is the 1 based
* argument number of the format string, and b is the 1 based argument * argument number of the format string, and b is the 1 based argument
@ -56,8 +56,12 @@
#define IRC_DEPRECATED #define IRC_DEPRECATED
#endif #endif
#if !defined(CONFIG_CHARYBDIS_LEVEL_1) #ifndef MAX
# error Incorrect config.h for this revision of ircd. #define MAX(a, b) ((a) > (b) ? (a) : (b))
#endif
#ifndef MIN
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#endif #endif
#define HOSTLEN 63 /* Length of hostname. Updated to */ #define HOSTLEN 63 /* Length of hostname. Updated to */
@ -119,4 +123,7 @@
#define PATRICIA_BITS 32 #define PATRICIA_BITS 32
#endif #endif
/* Read buffer size */
#define READBUF_SIZE 16384
#endif /* INCLUDED_ircd_defs_h */ #endif /* INCLUDED_ircd_defs_h */

View file

@ -25,7 +25,7 @@
#ifndef INCLUDED_m_info_h #ifndef INCLUDED_m_info_h
#define INCLUDED_m_info_h #define INCLUDED_m_info_h
#include "config.h" #include "defaults.h"
typedef struct Information typedef struct Information
{ {

View file

@ -46,8 +46,8 @@ extern int match_ips(const char *mask, const char *name);
/* /*
* comp_with_mask - compares to IP address * comp_with_mask - compares to IP address
*/ */
int comp_with_mask(void *addr, void *dest, u_int mask); int comp_with_mask(void *addr, void *dest, unsigned int mask);
int comp_with_mask_sock(struct sockaddr *addr, struct sockaddr *dest, u_int mask); int comp_with_mask_sock(struct sockaddr *addr, struct sockaddr *dest, unsigned int mask);
/* /*
* collapse - collapse a string in place, converts multiple adjacent *'s * collapse - collapse a string in place, converts multiple adjacent *'s

View file

@ -25,7 +25,7 @@
#ifndef INCLUDED_modules_h #ifndef INCLUDED_modules_h
#define INCLUDED_modules_h #define INCLUDED_modules_h
#include "serno.h" #include "serno.h"
#include "config.h" #include "defaults.h"
#include "setup.h" #include "setup.h"
#include "parse.h" #include "parse.h"

View file

@ -25,7 +25,7 @@
#ifndef INCLUDED_msg_h #ifndef INCLUDED_msg_h
#define INCLUDED_msg_h #define INCLUDED_msg_h
#include "config.h" #include "defaults.h"
#include "msgbuf.h" #include "msgbuf.h"
struct Client; struct Client;
@ -54,7 +54,7 @@ typedef void (*MessageHandler) (struct MsgBuf *, struct Client *, struct Client
struct MessageEntry struct MessageEntry
{ {
MessageHandler handler; MessageHandler handler;
int min_para; size_t min_para;
}; };
/* Message table structure */ /* Message table structure */

View file

@ -1,5 +1,4 @@
/* This code is in the public domain. /* This code is in the public domain.
* $Nightmare: nightmare/include/config.h,v 1.32.2.2.2.2 2002/07/02 03:41:28 ejb Exp $
*/ */
#ifndef _NEWCONF_H_INCLUDED #ifndef _NEWCONF_H_INCLUDED

View file

@ -25,7 +25,7 @@
#ifndef INCLUDED_numeric_h #ifndef INCLUDED_numeric_h
#define INCLUDED_numeric_h #define INCLUDED_numeric_h
#include "config.h" #include "defaults.h"
#include "messages.h" #include "messages.h"
/* /*

View file

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

View file

@ -26,7 +26,7 @@
#ifndef INCLUDED_s_assert_h #ifndef INCLUDED_s_assert_h
#define INCLUDED_s_assert_h #define INCLUDED_s_assert_h
#include "config.h" #include "defaults.h"
#ifdef SOFT_ASSERT #ifdef SOFT_ASSERT

View file

@ -33,7 +33,6 @@
#include "ircd_defs.h" #include "ircd_defs.h"
#include "class.h" #include "class.h"
#include "client.h" #include "client.h"
#include "common.h"
struct Client; struct Client;
struct DNSReply; struct DNSReply;
@ -373,8 +372,8 @@ extern void add_temp_dline(struct ConfItem *);
extern void report_temp_klines(struct Client *); extern void report_temp_klines(struct Client *);
extern void show_temp_klines(struct Client *, rb_dlink_list *); extern void show_temp_klines(struct Client *, rb_dlink_list *);
extern int rehash(int); extern bool rehash(bool);
extern void rehash_bans(int); extern void rehash_bans(void);
extern int conf_add_server(struct ConfItem *, int); extern int conf_add_server(struct ConfItem *, int);
extern void conf_add_class_to_conf(struct ConfItem *); extern void conf_add_class_to_conf(struct ConfItem *);
@ -389,11 +388,11 @@ extern int yylex(void);
extern unsigned long cidr_to_bitmask[]; extern unsigned long cidr_to_bitmask[];
extern char conffilebuf[IRCD_BUFSIZE + 1]; extern char conffilebuf[BUFSIZE + 1];
extern int lineno; extern int lineno;
#define NOT_AUTHORISED (-1) #define NOT_AUTHORISED (-1)
#define SOCKET_ERROR (-2) #define I_SOCKET_ERROR (-2)
#define I_LINE_FULL (-3) #define I_LINE_FULL (-3)
#define BANNED_CLIENT (-4) #define BANNED_CLIENT (-4)
#define TOO_MANY_LOCAL (-6) #define TOO_MANY_LOCAL (-6)

View file

@ -131,7 +131,7 @@ struct oper_conf
extern struct remote_conf *make_remote_conf(void); extern struct remote_conf *make_remote_conf(void);
extern void free_remote_conf(struct remote_conf *); extern void free_remote_conf(struct remote_conf *);
extern int find_shared_conf(const char *username, const char *host, extern bool find_shared_conf(const char *username, const char *host,
const char *server, int flags); const char *server, int flags);
extern void propagate_generic(struct Client *source_p, const char *command, extern void propagate_generic(struct Client *source_p, const char *command,
const char *target, int cap, const char *format, ...); const char *target, int cap, const char *format, ...);

View file

@ -25,7 +25,7 @@
#ifndef INCLUDED_serv_h #ifndef INCLUDED_serv_h
#define INCLUDED_serv_h #define INCLUDED_serv_h
#include "config.h" #include "defaults.h"
#include "capability.h" #include "capability.h"
/* /*

View file

@ -25,7 +25,7 @@
#ifndef INCLUDED_s_user_h #ifndef INCLUDED_s_user_h
#define INCLUDED_s_user_h #define INCLUDED_s_user_h
#include "config.h" #include "defaults.h"
struct Client; struct Client;
struct User; struct User;

View file

@ -27,7 +27,6 @@
#include "rb_lib.h" #include "rb_lib.h"
#include "ircd_defs.h" #include "ircd_defs.h"
#include "config.h" /* HAVE_STDARG_H */
struct Client; struct Client;
struct Channel; struct Channel;

View file

@ -1,473 +0,0 @@
/* include/setup.h.in. Generated from configure.ac by autoheader. */
/* Define if building universal (internal helper macro) */
#undef AC_APPLE_UNIVERSAL_BUILD
/* Size of away heap. */
#undef AWAY_HEAP_SIZE
/* Size of the ban heap. */
#undef BAN_HEAP_SIZE
/* Custom branding name. */
#undef BRANDING_NAME
/* Custom branding name. */
#undef BRANDING_VERSION
/* Size of the channel heap. */
#undef CHANNEL_HEAP_SIZE
/* Define this if you are profiling. */
#undef CHARYBDIS_PROFILE
/* Size of the client heap. */
#undef CLIENT_HEAP_SIZE
/* Size of the confitem heap. */
#undef CONFITEM_HEAP_SIZE
/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
systems. This function is required for `alloca.c' support on those systems.
*/
#undef CRAY_STACKSEG_END
/* Define if custom branding is enabled. */
#undef CUSTOM_BRANDING
/* Define to 1 if using `alloca.c'. */
#undef C_ALLOCA
/* Size of the dlink_node heap. */
#undef DNODE_HEAP_SIZE
/* Prefix where config files are installed. */
#undef ETC_DIR
/* Size of fd heap. */
#undef FD_HEAP_SIZE
/* Define to 1 if you have `alloca', as a function or macro. */
#undef HAVE_ALLOCA
/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
*/
#undef HAVE_ALLOCA_H
/* Define to 1 if you have the `argz_add' function. */
#undef HAVE_ARGZ_ADD
/* Define to 1 if you have the `argz_append' function. */
#undef HAVE_ARGZ_APPEND
/* Define to 1 if you have the `argz_count' function. */
#undef HAVE_ARGZ_COUNT
/* Define to 1 if you have the `argz_create_sep' function. */
#undef HAVE_ARGZ_CREATE_SEP
/* Define to 1 if you have the <argz.h> header file. */
#undef HAVE_ARGZ_H
/* Define to 1 if you have the `argz_insert' function. */
#undef HAVE_ARGZ_INSERT
/* Define to 1 if you have the `argz_next' function. */
#undef HAVE_ARGZ_NEXT
/* Define to 1 if you have the `argz_stringify' function. */
#undef HAVE_ARGZ_STRINGIFY
/* Define to 1 if you have the `closedir' function. */
#undef HAVE_CLOSEDIR
/* Define to 1 if you have the <crypt.h> header file. */
#undef HAVE_CRYPT_H
/* Define to 1 if you have the declaration of `cygwin_conv_path', and to 0 if
you don't. */
#undef HAVE_DECL_CYGWIN_CONV_PATH
/* Define to 1 if you have the <dirent.h> header file. */
#undef HAVE_DIRENT_H
/* Define if you have the GNU dld library. */
#undef HAVE_DLD
/* Define to 1 if you have the <dld.h> header file. */
#undef HAVE_DLD_H
/* Define to 1 if you have the `dlerror' function. */
#undef HAVE_DLERROR
/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H
/* Define to 1 if you have the <dl.h> header file. */
#undef HAVE_DL_H
/* Define if you have the _dyld_func_lookup function. */
#undef HAVE_DYLD
/* Define to 1 if you have the <errno.h> header file. */
#undef HAVE_ERRNO_H
/* Define to 1 if the system has the type `error_t'. */
#undef HAVE_ERROR_T
/* Define to 1 if you have the `gettimeofday' function. */
#undef HAVE_GETTIMEOFDAY
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if you have the `crypto' library (-lcrypto). */
#undef HAVE_LIBCRYPTO
/* Define if you have the libdl library or equivalent. */
#undef HAVE_LIBDL
/* Define if libdlloader will be built on this platform */
#undef HAVE_LIBDLLOADER
/* Define to 1 if zlib (-lz) is available. */
#undef HAVE_LIBZ
/* Define this if a modern libltdl is already installed */
#undef HAVE_LTDL
/* Define to 1 if you have the <machine/endian.h> header file. */
#undef HAVE_MACHINE_ENDIAN_H
/* Define to 1 if you have the <mach-o/dyld.h> header file. */
#undef HAVE_MACH_O_DYLD_H
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define to 1 if you have the `mmap' function. */
#undef HAVE_MMAP
/* Define if nanosleep exists */
#undef HAVE_NANOSLEEP
/* Define to 1 if you have the `opendir' function. */
#undef HAVE_OPENDIR
/* Define if libtool can extract symbol lists from object files. */
#undef HAVE_PRELOADED_SYMBOLS
/* Define to 1 if you have the `readdir' function. */
#undef HAVE_READDIR
/* Define if you have the shl_load function. */
#undef HAVE_SHL_LOAD
/* Define to 1 if you have the `snprintf' function. */
#undef HAVE_SNPRINTF
/* Define to 1 if you have the `socketpair' function. */
#undef HAVE_SOCKETPAIR
/* Define to 1 if stdbool.h conforms to C99. */
#undef HAVE_STDBOOL_H
/* Define to 1 if you have the <stddef.h> header file. */
#undef HAVE_STDDEF_H
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define to 1 if you have the `strdup' function. */
#undef HAVE_STRDUP
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define to 1 if you have the `strlcat' function. */
#undef HAVE_STRLCAT
/* Define to 1 if you have the `strlcpy' function. */
#undef HAVE_STRLCPY
/* Define to 1 if you have the `strndup' function. */
#undef HAVE_STRNDUP
/* Define to 1 if you have the <sys/dl.h> header file. */
#undef HAVE_SYS_DL_H
/* Define to 1 if you have the <sys/epoll.h> header file. */
#undef HAVE_SYS_EPOLL_H
/* Define to 1 if you have the <sys/param.h> header file. */
#undef HAVE_SYS_PARAM_H
/* Define to 1 if you have the <sys/resource.h> header file. */
#undef HAVE_SYS_RESOURCE_H
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/syslog.h> header file. */
#undef HAVE_SYS_SYSLOG_H
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* Define to 1 if you have the <sys/uio.h> header file. */
#undef HAVE_SYS_UIO_H
/* Define to 1 if you have the <sys/wait.h> header file. */
#undef HAVE_SYS_WAIT_H
/* Define to 1 if the system has the type `uintptr_t'. */
#undef HAVE_UINTPTR_T
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define to 1 if you have the `vsnprintf' function. */
#undef HAVE_VSNPRINTF
/* Define to 1 if you have the <wait.h> header file. */
#undef HAVE_WAIT_H
/* This value is set to 1 to indicate that the system argz facility works */
#undef HAVE_WORKING_ARGZ
/* Define to 1 if the system has the type `_Bool'. */
#undef HAVE__BOOL
/* Prefix where help files are installed. */
#undef HELP_DIR
/* Prefix where the ircd is installed. */
#undef IRCD_PREFIX
/* Size of the local client heap. */
#undef LCLIENT_HEAP_SIZE
/* Size of the linebuf heap. */
#undef LINEBUF_HEAP_SIZE
/* Prefix where to write logfiles. */
#undef LOG_DIR
/* Define if the OS needs help to load dependent libraries for dlopen(). */
#undef LTDL_DLOPEN_DEPLIBS
/* Define to the system default library search path. */
#undef LT_DLSEARCH_PATH
/* The archive extension */
#undef LT_LIBEXT
/* The archive prefix */
#undef LT_LIBPREFIX
/* Define to the extension used for runtime loadable modules, say, ".so". */
#undef LT_MODULE_EXT
/* Define to the name of the environment variable that determines the run-time
module search path. */
#undef LT_MODULE_PATH_VAR
/* Define to the sub-directory where libtool stores uninstalled libraries. */
#undef LT_OBJDIR
/* Define to the shared library suffix, say, ".dylib". */
#undef LT_SHARED_EXT
/* Define to the shared archive member specification, say "(shr.o)". */
#undef LT_SHARED_LIB_MEMBER
/* Sizeof member heap. */
#undef MEMBER_HEAP_SIZE
/* Prefix where modules are installed. */
#undef MODULE_DIR
/* Size of the monitor heap. */
#undef MONITOR_HEAP_SIZE
/* Define this to disable debugging support. */
#undef NDEBUG
/* Size of the nick delay heap. */
#undef ND_HEAP_SIZE
/* Define if dlsym() requires a leading underscore in symbol names. */
#undef NEED_USCORE
/* Nickname length */
#undef NICKLEN
/* Size of the WHOWAS array. */
#undef NICKNAMEHISTORYLENGTH
/* Name of package */
#undef PACKAGE
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#undef PACKAGE_NAME
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the home page for this package. */
#undef PACKAGE_URL
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* Path to /dev/null */
#undef PATH_DEVNULL
/* Size of the pre-client heap. */
#undef PCLIENT_HEAP_SIZE
/* Directory where binaries the IRCd itself spawns live */
#undef PKGLIBEXECDIR
/* Directory in which to store state, such as ban database */
#undef PKGLOCALSTATEDIR
/* Directory to store pidfile in. */
#undef PKGRUNDIR
/* String with which all programs intended to be in PATH are prefixed. */
#undef PROGRAM_PREFIX
/* The size of `int', as computed by sizeof. */
#undef SIZEOF_INT
/* The size of `long', as computed by sizeof. */
#undef SIZEOF_LONG
/* The size of `long long', as computed by sizeof. */
#undef SIZEOF_LONG_LONG
/* The size of `short', as computed by sizeof. */
#undef SIZEOF_SHORT
/* Define this to enable soft asserts. */
#undef SOFT_ASSERT
/* If using the C implementation of alloca, define if you know the
direction of stack growth for your system; otherwise it will be
automatically deduced at runtime.
STACK_DIRECTION > 0 => grows toward higher addresses
STACK_DIRECTION < 0 => grows toward lower addresses
STACK_DIRECTION = 0 => direction of growth unknown */
#undef STACK_DIRECTION
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Maximum topic length (<=390) */
#undef TOPICLEN
/* Size of the topic heap. */
#undef TOPIC_HEAP_SIZE
/* Size of the user heap. */
#undef USER_HEAP_SIZE
/* Enable extensions on AIX 3, Interix. */
#ifndef _ALL_SOURCE
# undef _ALL_SOURCE
#endif
/* Enable GNU extensions on systems that have them. */
#ifndef _GNU_SOURCE
# undef _GNU_SOURCE
#endif
/* Enable threading extensions on Solaris. */
#ifndef _POSIX_PTHREAD_SEMANTICS
# undef _POSIX_PTHREAD_SEMANTICS
#endif
/* Enable extensions on HP NonStop. */
#ifndef _TANDEM_SOURCE
# undef _TANDEM_SOURCE
#endif
/* Enable general extensions on Solaris. */
#ifndef __EXTENSIONS__
# undef __EXTENSIONS__
#endif
/* Version number of package */
#undef VERSION
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
significant byte first (like Motorola and SPARC, unlike Intel). */
#if defined AC_APPLE_UNIVERSAL_BUILD
# if defined __BIG_ENDIAN__
# define WORDS_BIGENDIAN 1
# endif
#else
# ifndef WORDS_BIGENDIAN
# undef WORDS_BIGENDIAN
# endif
#endif
/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a
`char[]'. */
#undef YYTEXT_POINTER
/* Define to 1 if on MINIX. */
#undef _MINIX
/* Define to 2 if the system does not provide POSIX.1 features except with
this defined. */
#undef _POSIX_1_SOURCE
/* Define to 1 if you need to in order for `stat' and other things to work. */
#undef _POSIX_SOURCE
/* Define so that glibc/gnulib argp.h does not typedef error_t. */
#undef __error_t_defined
/* Define to empty if `const' does not conform to ANSI C. */
#undef const
/* Define to a type to use for 'error_t' if it is not otherwise available. */
#undef error_t
/* If system does not define in_port_t, define it to what it should be. */
#undef in_port_t
/* Define to `__inline__' or `__inline' if that's what the C compiler
calls it, or to nothing if 'inline' is not supported under any name. */
#ifndef __cplusplus
#undef inline
#endif
/* Define to `int' if <sys/types.h> does not define. */
#undef pid_t
/* If system does not define sa_family_t, define it here. */
#undef sa_family_t
/* Define to `unsigned int' if <sys/types.h> does not define. */
#undef size_t
/* If we don't have a real socklen_t, unsigned int is good enough. */
#undef socklen_t
/* If system does not define u_int16_t, define a usable substitute. */
#undef u_int16_t
/* If system does not define u_int32_t, define to unsigned long int here. */
#undef u_int32_t

View file

@ -22,7 +22,6 @@
*/ */
#include "rb_lib.h" #include "rb_lib.h"
#include "config.h" /* Gotta pull in the autoconf stuff */
#include "ircd_defs.h" /* Needed for some reasons here -- dwr */ #include "ircd_defs.h" /* Needed for some reasons here -- dwr */
/* AIX requires this to be the first thing in the file. */ /* AIX requires this to be the first thing in the file. */
@ -93,7 +92,6 @@ typedef bool _Bool;
#include <stdio.h> #include <stdio.h>
#include <time.h> #include <time.h>
#include <fcntl.h> #include <fcntl.h>
#include <netdb.h>
#include <stdarg.h> #include <stdarg.h>
#include <signal.h> #include <signal.h>
#include <dirent.h> #include <dirent.h>
@ -113,16 +111,11 @@ typedef bool _Bool;
#endif #endif
#include <sys/socket.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/wait.h>
#ifdef HAVE_SYS_PARAM_H #ifdef HAVE_SYS_PARAM_H
#include <sys/param.h> #include <sys/param.h>
#endif #endif
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#ifdef HAVE_ERRNO_H #ifdef HAVE_ERRNO_H
#include <errno.h> #include <errno.h>

0
install-sh Normal file → Executable file
View file

View file

@ -14,6 +14,10 @@ version.c: version.c.SH ../CREDITS ../include/patchlevel.h ../include/serno.h
$(CP) version.c version.c.last $(CP) version.c version.c.last
touch version.c.SH touch version.c.SH
if MINGW
EXTRA_FLAGS = -Wl,--enable-runtime-pseudo-reloc -export-symbols-regex '*'
endif
libircd_la_SOURCES = \ libircd_la_SOURCES = \
authd.c \ authd.c \
bandbi.c \ bandbi.c \
@ -63,7 +67,7 @@ libircd_la_SOURCES = \
tgchange.c \ tgchange.c \
version.c \ version.c \
whowas.c whowas.c
libircd_la_LDFLAGS = $(EXTRA_FLAGS) -avoid-version libircd_la_LDFLAGS = $(EXTRA_FLAGS) -avoid-version -no-undefined
libircd_la_LIBADD = @LIBLTDL@ -L$(top_srcdir)/librb/src -lrb libircd_la_LIBADD = @LIBLTDL@ -L$(top_srcdir)/librb/src -lrb
libircd_LTLIBRARIES = libircd.la libircd_LTLIBRARIES = libircd.la

View file

@ -55,20 +55,20 @@ start_authd(void)
#endif #endif
if(authd_path == NULL) if(authd_path == NULL)
{ {
snprintf(fullpath, sizeof(fullpath), "%s/authd%s", PKGLIBEXECDIR, suffix); snprintf(fullpath, sizeof(fullpath), "%s%cauthd%s", ircd_paths[IRCD_PATH_LIBEXEC], RB_PATH_SEPARATOR, suffix);
if(access(fullpath, X_OK) == -1) if(access(fullpath, X_OK) == -1)
{ {
snprintf(fullpath, sizeof(fullpath), "%s/libexec/charybdis/authd%s", snprintf(fullpath, sizeof(fullpath), "%s%cbin%cauthd%s",
ConfigFileEntry.dpath, suffix); ConfigFileEntry.dpath, RB_PATH_SEPARATOR, RB_PATH_SEPARATOR, suffix);
if(access(fullpath, X_OK) == -1) if(access(fullpath, X_OK) == -1)
{ {
ilog(L_MAIN, ilog(L_MAIN,
"Unable to execute authd in %s or %s/libexec/charybdis", "Unable to execute authd in %s or %s/bin",
PKGLIBEXECDIR, ConfigFileEntry.dpath); ircd_paths[IRCD_PATH_LIBEXEC], ConfigFileEntry.dpath);
sendto_realops_snomask(SNO_GENERAL, L_ALL, sendto_realops_snomask(SNO_GENERAL, L_ALL,
"Unable to execute authd in %s or %s/libexec/charybdis", "Unable to execute authd in %s or %s/bin",
PKGLIBEXECDIR, ConfigFileEntry.dpath); ircd_paths[IRCD_PATH_LIBEXEC], ConfigFileEntry.dpath);
return 1; return 1;
} }
@ -114,6 +114,39 @@ parse_authd_reply(rb_helper * helper)
} }
dns_results_callback(parv[1], parv[2], parv[3], parv[4]); dns_results_callback(parv[1], parv[2], parv[3], parv[4]);
break; break;
case 'W':
if(parc != 3)
{
ilog(L_MAIN, "authd sent a result with wrong number of arguments: got %d", parc);
restart_authd();
return;
}
switch(*parv[2])
{
case 'D': /* debug */
sendto_realops_snomask(SNO_DEBUG, L_ALL, "authd debug: %s", parv[3]);
break;
case 'I': /* Info */
sendto_realops_snomask(SNO_GENERAL, L_ALL, "authd info: %s", parv[3]);
inotice("authd info: %s", parv[3]);
break;
case 'W': /* Warning */
sendto_realops_snomask(SNO_GENERAL, L_ALL, "authd WARNING: %s", parv[3]);
iwarn("authd warning: %s", parv[3]);
break;
case 'C': /* Critical (error) */
sendto_realops_snomask(SNO_GENERAL, L_ALL, "authd CRITICAL: %s", parv[3]);
ierror("authd critical: %s", parv[3]);
break;
default: /* idk */
sendto_realops_snomask(SNO_GENERAL, L_ALL, "authd sent us an unknown oper notice type (%s): %s", parv[2], parv[3]);
ilog(L_MAIN, "authd unknown oper notice type (%s): %s", parv[2], parv[3]);
break;
}
/* NOTREACHED */
break;
case 'X': case 'X':
case 'Y': case 'Y':
case 'Z': case 'Z':

View file

@ -80,21 +80,21 @@ start_bandb(void)
const char *suffix = ""; const char *suffix = "";
#endif #endif
rb_setenv("BANDB_DBPATH", PKGLOCALSTATEDIR "/ban.db", 1); rb_setenv("BANDB_DBPATH", ircd_paths[IRCD_PATH_BANDB], 1);
if(bandb_path == NULL) if(bandb_path == NULL)
{ {
snprintf(fullpath, sizeof(fullpath), "%s/bandb%s", PKGLIBEXECDIR, suffix); snprintf(fullpath, sizeof(fullpath), "%s%cbandb%s", ircd_paths[IRCD_PATH_LIBEXEC], RB_PATH_SEPARATOR, suffix);
if(access(fullpath, X_OK) == -1) if(access(fullpath, X_OK) == -1)
{ {
snprintf(fullpath, sizeof(fullpath), "%s/bin/bandb%s", snprintf(fullpath, sizeof(fullpath), "%s%cbin%cbandb%s",
ConfigFileEntry.dpath, suffix); ConfigFileEntry.dpath, RB_PATH_SEPARATOR, RB_PATH_SEPARATOR, suffix);
if(access(fullpath, X_OK) == -1) if(access(fullpath, X_OK) == -1)
{ {
ilog(L_MAIN, ilog(L_MAIN,
"Unable to execute bandb%s in %s or %s/bin", "Unable to execute bandb%s in %s or %s/bin",
suffix, PKGLIBEXECDIR, ConfigFileEntry.dpath); suffix, ircd_paths[IRCD_PATH_LIBEXEC], ConfigFileEntry.dpath);
return 0; return 0;
} }
} }

View file

@ -156,7 +156,7 @@ static void initiate_blacklist_dnsquery(struct Blacklist *blptr, struct Client *
blcptr->client_p = client_p; blcptr->client_p = client_p;
/* IPv4 */ /* IPv4 */
if ((client_p->localClient->ip.ss_family == AF_INET) && blptr->ipv4) if ((GET_SS_FAMILY(&client_p->localClient->ip) == AF_INET) && blptr->ipv4)
{ {
ip = (uint8_t *)&((struct sockaddr_in *)&client_p->localClient->ip)->sin_addr.s_addr; ip = (uint8_t *)&((struct sockaddr_in *)&client_p->localClient->ip)->sin_addr.s_addr;
@ -168,8 +168,9 @@ static void initiate_blacklist_dnsquery(struct Blacklist *blptr, struct Client *
(unsigned int) ip[0], (unsigned int) ip[0],
blptr->host); blptr->host);
} }
#ifdef RB_IPV6
/* IPv6 */ /* IPv6 */
else if ((client_p->localClient->ip.ss_family == AF_INET6) && blptr->ipv6) else if ((GET_SS_FAMILY(&client_p->localClient->ip) == AF_INET6) && blptr->ipv6)
{ {
/* Split up for rDNS lookup /* Split up for rDNS lookup
* ex: ip[0] = 0x00, ip[1] = 0x00... ip[16] = 0x01 for localhost * ex: ip[0] = 0x00, ip[1] = 0x00... ip[16] = 0x01 for localhost
@ -197,6 +198,7 @@ static void initiate_blacklist_dnsquery(struct Blacklist *blptr, struct Client *
/* Tack host on */ /* Tack host on */
strcpy(bufptr, blptr->host); strcpy(bufptr, blptr->host);
} }
#endif
/* This shouldn't happen... */ /* This shouldn't happen... */
else else
return; return;
@ -225,7 +227,7 @@ struct Blacklist *new_blacklist(char *name, char *reject_reason, int ipv4, int i
blptr->status &= ~CONF_ILLEGAL; blptr->status &= ~CONF_ILLEGAL;
rb_strlcpy(blptr->host, name, IRCD_RES_HOSTLEN + 1); rb_strlcpy(blptr->host, name, IRCD_RES_HOSTLEN + 1);
rb_strlcpy(blptr->reject_reason, reject_reason, IRCD_BUFSIZE); rb_strlcpy(blptr->reject_reason, reject_reason, BUFSIZE);
blptr->ipv4 = ipv4; blptr->ipv4 = ipv4;
blptr->ipv6 = ipv6; blptr->ipv6 = ipv6;

View file

@ -32,7 +32,6 @@
#include "stdinc.h" #include "stdinc.h"
#include "ircd_defs.h" #include "ircd_defs.h"
#include "common.h"
#include "s_conf.h" #include "s_conf.h"
#include "client.h" #include "client.h"
#include "hash.h" #include "hash.h"
@ -47,8 +46,8 @@ struct cacheline *emptyline = NULL;
rb_dlink_list links_cache_list; rb_dlink_list links_cache_list;
char user_motd_changed[MAX_DATE_STRING]; char user_motd_changed[MAX_DATE_STRING];
struct Dictionary *help_dict_oper = NULL; rb_dictionary *help_dict_oper = NULL;
struct Dictionary *help_dict_user = NULL; rb_dictionary *help_dict_user = NULL;
/* init_cache() /* init_cache()
* *
@ -65,8 +64,8 @@ init_cache(void)
user_motd_changed[0] = '\0'; user_motd_changed[0] = '\0';
user_motd = cache_file(MPATH, "ircd.motd", 0); user_motd = cache_file(ircd_paths[IRCD_PATH_IRCD_MOTD], "ircd.motd", 0);
oper_motd = cache_file(OPATH, "opers.motd", 0); oper_motd = cache_file(ircd_paths[IRCD_PATH_IRCD_OMOTD], "opers.motd", 0);
memset(&links_cache_list, 0, sizeof(links_cache_list)); memset(&links_cache_list, 0, sizeof(links_cache_list));
help_dict_oper = rb_dictionary_create("oper help", strcasecmp); help_dict_oper = rb_dictionary_create("oper help", strcasecmp);
@ -237,24 +236,24 @@ load_help(void)
struct dirent *ldirent= NULL; struct dirent *ldirent= NULL;
char filename[PATH_MAX]; char filename[PATH_MAX];
struct cachefile *cacheptr; struct cachefile *cacheptr;
struct DictionaryIter iter; rb_dictionary_iter iter;
#if defined(S_ISLNK) && defined(HAVE_LSTAT) #if defined(S_ISLNK) && defined(HAVE_LSTAT)
struct stat sb; struct stat sb;
#endif #endif
DICTIONARY_FOREACH(cacheptr, &iter, help_dict_oper) RB_DICTIONARY_FOREACH(cacheptr, &iter, help_dict_oper)
{ {
rb_dictionary_delete(help_dict_oper, cacheptr->name); rb_dictionary_delete(help_dict_oper, cacheptr->name);
free_cachefile(cacheptr); free_cachefile(cacheptr);
} }
DICTIONARY_FOREACH(cacheptr, &iter, help_dict_user) RB_DICTIONARY_FOREACH(cacheptr, &iter, help_dict_user)
{ {
rb_dictionary_delete(help_dict_user, cacheptr->name); rb_dictionary_delete(help_dict_user, cacheptr->name);
free_cachefile(cacheptr); free_cachefile(cacheptr);
} }
helpfile_dir = opendir(HPATH); helpfile_dir = opendir(ircd_paths[IRCD_PATH_OPERHELP]);
if(helpfile_dir == NULL) if(helpfile_dir == NULL)
return; return;
@ -263,13 +262,13 @@ load_help(void)
{ {
if(ldirent->d_name[0] == '.') if(ldirent->d_name[0] == '.')
continue; continue;
snprintf(filename, sizeof(filename), "%s/%s", HPATH, ldirent->d_name); snprintf(filename, sizeof(filename), "%s%c%s", ircd_paths[IRCD_PATH_OPERHELP], RB_PATH_SEPARATOR, ldirent->d_name);
cacheptr = cache_file(filename, ldirent->d_name, HELP_OPER); cacheptr = cache_file(filename, ldirent->d_name, HELP_OPER);
rb_dictionary_add(help_dict_oper, cacheptr->name, cacheptr); rb_dictionary_add(help_dict_oper, cacheptr->name, cacheptr);
} }
closedir(helpfile_dir); closedir(helpfile_dir);
helpfile_dir = opendir(UHPATH); helpfile_dir = opendir(ircd_paths[IRCD_PATH_USERHELP]);
if(helpfile_dir == NULL) if(helpfile_dir == NULL)
return; return;
@ -278,7 +277,7 @@ load_help(void)
{ {
if(ldirent->d_name[0] == '.') if(ldirent->d_name[0] == '.')
continue; continue;
snprintf(filename, sizeof(filename), "%s/%s", UHPATH, ldirent->d_name); snprintf(filename, sizeof(filename), "%s%c%s", ircd_paths[IRCD_PATH_USERHELP], RB_PATH_SEPARATOR, ldirent->d_name);
#if defined(S_ISLNK) && defined(HAVE_LSTAT) #if defined(S_ISLNK) && defined(HAVE_LSTAT)
if(lstat(filename, &sb) < 0) if(lstat(filename, &sb) < 0)
@ -342,7 +341,7 @@ cache_user_motd(void)
struct stat sb; struct stat sb;
struct tm *local_tm; struct tm *local_tm;
if(stat(MPATH, &sb) == 0) if(stat(ircd_paths[IRCD_PATH_IRCD_MOTD], &sb) == 0)
{ {
local_tm = localtime(&sb.st_mtime); local_tm = localtime(&sb.st_mtime);
@ -356,7 +355,7 @@ cache_user_motd(void)
} }
} }
free_cachefile(user_motd); free_cachefile(user_motd);
user_motd = cache_file(MPATH, "ircd.motd", 0); user_motd = cache_file(ircd_paths[IRCD_PATH_IRCD_MOTD], "ircd.motd", 0);
} }

View file

@ -129,7 +129,7 @@ capability_require(struct CapabilityIndex *idx, const char *cap)
} }
static void static void
capability_destroy(struct DictionaryElement *delem, void *privdata) capability_destroy(rb_dictionary_element *delem, void *privdata)
{ {
s_assert(delem != NULL); s_assert(delem != NULL);
@ -165,7 +165,7 @@ capability_index_destroy(struct CapabilityIndex *idx)
const char * const char *
capability_index_list(struct CapabilityIndex *idx, unsigned int cap_mask) capability_index_list(struct CapabilityIndex *idx, unsigned int cap_mask)
{ {
struct DictionaryIter iter; rb_dictionary_iter iter;
struct CapabilityEntry *entry; struct CapabilityEntry *entry;
static char buf[BUFSIZE]; static char buf[BUFSIZE];
char *t = buf; char *t = buf;
@ -175,7 +175,7 @@ capability_index_list(struct CapabilityIndex *idx, unsigned int cap_mask)
*t = '\0'; *t = '\0';
DICTIONARY_FOREACH(entry, &iter, idx->cap_dict) RB_DICTIONARY_FOREACH(entry, &iter, idx->cap_dict)
{ {
if ((1 << entry->value) & cap_mask) if ((1 << entry->value) & cap_mask)
{ {
@ -193,13 +193,13 @@ capability_index_list(struct CapabilityIndex *idx, unsigned int cap_mask)
unsigned int unsigned int
capability_index_mask(struct CapabilityIndex *idx) capability_index_mask(struct CapabilityIndex *idx)
{ {
struct DictionaryIter iter; rb_dictionary_iter iter;
struct CapabilityEntry *entry; struct CapabilityEntry *entry;
unsigned int mask = 0; unsigned int mask = 0;
s_assert(idx != NULL); s_assert(idx != NULL);
DICTIONARY_FOREACH(entry, &iter, idx->cap_dict) RB_DICTIONARY_FOREACH(entry, &iter, idx->cap_dict)
{ {
if (!(entry->flags & CAP_ORPHANED)) if (!(entry->flags & CAP_ORPHANED))
mask |= (1 << entry->value); mask |= (1 << entry->value);
@ -211,13 +211,13 @@ capability_index_mask(struct CapabilityIndex *idx)
unsigned int unsigned int
capability_index_get_required(struct CapabilityIndex *idx) capability_index_get_required(struct CapabilityIndex *idx)
{ {
struct DictionaryIter iter; rb_dictionary_iter iter;
struct CapabilityEntry *entry; struct CapabilityEntry *entry;
unsigned int mask = 0; unsigned int mask = 0;
s_assert(idx != NULL); s_assert(idx != NULL);
DICTIONARY_FOREACH(entry, &iter, idx->cap_dict) RB_DICTIONARY_FOREACH(entry, &iter, idx->cap_dict)
{ {
if (!(entry->flags & CAP_ORPHANED) && (entry->flags & CAP_REQUIRED)) if (!(entry->flags & CAP_ORPHANED) && (entry->flags & CAP_REQUIRED))
mask |= (1 << entry->value); mask |= (1 << entry->value);
@ -235,13 +235,13 @@ capability_index_stats(void (*cb)(const char *line, void *privdata), void *privd
RB_DLINK_FOREACH(node, capability_indexes.head) RB_DLINK_FOREACH(node, capability_indexes.head)
{ {
struct CapabilityIndex *idx = node->data; struct CapabilityIndex *idx = node->data;
struct DictionaryIter iter; rb_dictionary_iter iter;
struct CapabilityEntry *entry; struct CapabilityEntry *entry;
snprintf(buf, sizeof buf, "'%s': allocated bits - %d", idx->name, (idx->highest_bit - 1)); snprintf(buf, sizeof buf, "'%s': allocated bits - %d", idx->name, (idx->highest_bit - 1));
cb(buf, privdata); cb(buf, privdata);
DICTIONARY_FOREACH(entry, &iter, idx->cap_dict) RB_DICTIONARY_FOREACH(entry, &iter, idx->cap_dict)
{ {
snprintf(buf, sizeof buf, "bit %d: '%s'", entry->value, entry->cap); snprintf(buf, sizeof buf, "bit %d: '%s'", entry->value, entry->cap);
cb(buf, privdata); cb(buf, privdata);

View file

@ -26,7 +26,6 @@
#include "channel.h" #include "channel.h"
#include "chmode.h" #include "chmode.h"
#include "client.h" #include "client.h"
#include "common.h"
#include "hash.h" #include "hash.h"
#include "hook.h" #include "hook.h"
#include "match.h" #include "match.h"
@ -337,23 +336,23 @@ invalidate_bancache_user(struct Client *client_p)
/* check_channel_name() /* check_channel_name()
* *
* input - channel name * input - channel name
* output - 1 if valid channel name, else 0 * output - true if valid channel name, else false
* side effects - * side effects -
*/ */
int bool
check_channel_name(const char *name) check_channel_name(const char *name)
{ {
s_assert(name != NULL); s_assert(name != NULL);
if(name == NULL) if(name == NULL)
return 0; return false;
for (; *name; ++name) for (; *name; ++name)
{ {
if(!IsChanChar(*name)) if(!IsChanChar(*name))
return 0; return false;
} }
return 1; return true;
} }
/* free_channel_list() /* free_channel_list()
@ -581,7 +580,7 @@ is_banned_list(struct Channel *chptr, rb_dlink_list *list,
} }
} }
#ifdef RB_IPV6 #ifdef RB_IPV6
if(who->localClient->ip.ss_family == AF_INET6 && if(GET_SS_FAMILY(&who->localClient->ip) == AF_INET6 &&
ipv4_from_ipv6((const struct sockaddr_in6 *)&who->localClient->ip, &ip4)) ipv4_from_ipv6((const struct sockaddr_in6 *)&who->localClient->ip, &ip4))
{ {
sprintf(src_ip4host, "%s!%s@", who->name, who->username); sprintf(src_ip4host, "%s!%s@", who->name, who->username);
@ -902,11 +901,11 @@ can_send(struct Channel *chptr, struct Client *source_p, struct membership *mspt
* inputs - flag 0 if PRIVMSG 1 if NOTICE. RFC * inputs - flag 0 if PRIVMSG 1 if NOTICE. RFC
* says NOTICE must not auto reply * says NOTICE must not auto reply
* - pointer to source Client * - pointer to source Client
* - pointer to target channel * - pointer to target channel
* output - 1 if target is under flood attack * output - true if target is under flood attack
* side effects - check for flood attack on target chptr * side effects - check for flood attack on target chptr
*/ */
int bool
flood_attack_channel(int p_or_n, struct Client *source_p, struct Channel *chptr, char *chname) flood_attack_channel(int p_or_n, struct Client *source_p, struct Channel *chptr, char *chname)
{ {
int delta; int delta;
@ -944,13 +943,13 @@ flood_attack_channel(int p_or_n, struct Client *source_p, struct Channel *chptr,
sendto_one(source_p, sendto_one(source_p,
":%s NOTICE %s :*** Message to %s throttled due to flooding", ":%s NOTICE %s :*** Message to %s throttled due to flooding",
me.name, source_p->name, chptr->chname); me.name, source_p->name, chptr->chname);
return 1; return true;
} }
else else
chptr->received_number_of_privmsgs++; chptr->received_number_of_privmsgs++;
} }
return 0; return false;
} }
/* find_bannickchange_channel() /* find_bannickchange_channel()

View file

@ -26,7 +26,6 @@
#include "stdinc.h" #include "stdinc.h"
#include "channel.h" #include "channel.h"
#include "client.h" #include "client.h"
#include "common.h"
#include "hash.h" #include "hash.h"
#include "hook.h" #include "hook.h"
#include "match.h" #include "match.h"
@ -203,10 +202,10 @@ get_channel_access(struct Client *source_p, struct Channel *chptr, struct member
* Checks if mlock and chanops permit a mode change. * Checks if mlock and chanops permit a mode change.
* *
* inputs - client, channel, access level, errors pointer, mode char * inputs - client, channel, access level, errors pointer, mode char
* outputs - 0 on failure, 1 on success * outputs - false on failure, true on success
* side effects - error message sent on failure * side effects - error message sent on failure
*/ */
static int static bool
allow_mode_change(struct Client *source_p, struct Channel *chptr, int alevel, allow_mode_change(struct Client *source_p, struct Channel *chptr, int alevel,
int *errors, char c) int *errors, char c)
{ {
@ -221,7 +220,7 @@ allow_mode_change(struct Client *source_p, struct Channel *chptr, int alevel,
c, c,
chptr->mode_lock); chptr->mode_lock);
*errors |= SM_ERR_MLOCK; *errors |= SM_ERR_MLOCK;
return 0; return false;
} }
if(alevel < CHFL_CHANOP) if(alevel < CHFL_CHANOP)
{ {
@ -229,18 +228,18 @@ allow_mode_change(struct Client *source_p, struct Channel *chptr, int alevel,
sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED), sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
me.name, source_p->name, chptr->chname); me.name, source_p->name, chptr->chname);
*errors |= SM_ERR_NOOPS; *errors |= SM_ERR_NOOPS;
return 0; return false;
} }
return 1; return true;
} }
/* add_id() /* add_id()
* *
* inputs - client, channel, id to add, type, forward * inputs - client, channel, id to add, type, forward
* outputs - 0 on failure, 1 on success * outputs - false on failure, true on success
* side effects - given id is added to the appropriate list * side effects - given id is added to the appropriate list
*/ */
int bool
add_id(struct Client *source_p, struct Channel *chptr, const char *banid, const char *forward, add_id(struct Client *source_p, struct Channel *chptr, const char *banid, const char *forward,
rb_dlink_list * list, long mode_type) rb_dlink_list * list, long mode_type)
{ {
@ -258,14 +257,14 @@ add_id(struct Client *source_p, struct Channel *chptr, const char *banid, const
{ {
sendto_one(source_p, form_str(ERR_BANLISTFULL), sendto_one(source_p, form_str(ERR_BANLISTFULL),
me.name, source_p->name, chptr->chname, realban); me.name, source_p->name, chptr->chname, realban);
return 0; return false;
} }
RB_DLINK_FOREACH(ptr, list->head) RB_DLINK_FOREACH(ptr, list->head)
{ {
actualBan = ptr->data; actualBan = ptr->data;
if(mask_match(actualBan->banstr, realban)) if(mask_match(actualBan->banstr, realban))
return 0; return false;
} }
} }
/* dont let remotes set duplicates */ /* dont let remotes set duplicates */
@ -275,7 +274,7 @@ add_id(struct Client *source_p, struct Channel *chptr, const char *banid, const
{ {
actualBan = ptr->data; actualBan = ptr->data;
if(!irccmp(actualBan->banstr, realban)) if(!irccmp(actualBan->banstr, realban))
return 0; return false;
} }
} }
@ -294,7 +293,7 @@ add_id(struct Client *source_p, struct Channel *chptr, const char *banid, const
if(mode_type == CHFL_BAN || mode_type == CHFL_QUIET || mode_type == CHFL_EXCEPTION) if(mode_type == CHFL_BAN || mode_type == CHFL_QUIET || mode_type == CHFL_EXCEPTION)
chptr->bants++; chptr->bants++;
return 1; return true;
} }
/* del_id() /* del_id()
@ -487,7 +486,7 @@ pretty_mask(const char *idmask)
* output - true if forwarding should be allowed * output - true if forwarding should be allowed
* side effects - numeric sent if not allowed * side effects - numeric sent if not allowed
*/ */
static int static bool
check_forward(struct Client *source_p, struct Channel *chptr, check_forward(struct Client *source_p, struct Channel *chptr,
const char *forward) const char *forward)
{ {
@ -498,20 +497,20 @@ check_forward(struct Client *source_p, struct Channel *chptr,
(MyClient(source_p) && (strlen(forward) > LOC_CHANNELLEN || hash_find_resv(forward)))) (MyClient(source_p) && (strlen(forward) > LOC_CHANNELLEN || hash_find_resv(forward))))
{ {
sendto_one_numeric(source_p, ERR_BADCHANNAME, form_str(ERR_BADCHANNAME), forward); sendto_one_numeric(source_p, ERR_BADCHANNAME, form_str(ERR_BADCHANNAME), forward);
return 0; return false;
} }
/* don't forward to inconsistent target -- jilles */ /* don't forward to inconsistent target -- jilles */
if(chptr->chname[0] == '#' && forward[0] == '&') if(chptr->chname[0] == '#' && forward[0] == '&')
{ {
sendto_one_numeric(source_p, ERR_BADCHANNAME, sendto_one_numeric(source_p, ERR_BADCHANNAME,
form_str(ERR_BADCHANNAME), forward); form_str(ERR_BADCHANNAME), forward);
return 0; return false;
} }
if(MyClient(source_p) && (targptr = find_channel(forward)) == NULL) if(MyClient(source_p) && (targptr = find_channel(forward)) == NULL)
{ {
sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL, sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL,
form_str(ERR_NOSUCHCHANNEL), forward); form_str(ERR_NOSUCHCHANNEL), forward);
return 0; return false;
} }
if(MyClient(source_p) && !(targptr->mode.mode & MODE_FREETARGET)) if(MyClient(source_p) && !(targptr->mode.mode & MODE_FREETARGET))
{ {
@ -520,10 +519,10 @@ check_forward(struct Client *source_p, struct Channel *chptr,
{ {
sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED), sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
me.name, source_p->name, targptr->chname); me.name, source_p->name, targptr->chname);
return 0; return false;
} }
} }
return 1; return true;
} }
/* fix_key() /* fix_key()
@ -536,9 +535,9 @@ check_forward(struct Client *source_p, struct Channel *chptr,
static char * static char *
fix_key(char *arg) fix_key(char *arg)
{ {
u_char *s, *t, c; unsigned char *s, *t, c;
for(s = t = (u_char *) arg; (c = *s); s++) for(s = t = (unsigned char *) arg; (c = *s); s++)
{ {
c &= 0x7f; c &= 0x7f;
if(c != ':' && c != ',' && c > ' ') if(c != ':' && c != ',' && c > ' ')
@ -559,9 +558,9 @@ fix_key(char *arg)
static char * static char *
fix_key_remote(char *arg) fix_key_remote(char *arg)
{ {
u_char *s, *t, c; unsigned char *s, *t, c;
for(s = t = (u_char *) arg; (c = *s); s++) for(s = t = (unsigned char *) arg; (c = *s); s++)
{ {
c &= 0x7f; c &= 0x7f;
if((c != 0x0a) && (c != ':') && (c != ',') && (c != 0x0d) && (c != ' ')) if((c != 0x0a) && (c != ':') && (c != ',') && (c != 0x0d) && (c != ' '))
@ -889,7 +888,7 @@ chm_ban(struct Client *source_p, struct Channel *chptr,
* also make sure it will always fit on a line with channel * also make sure it will always fit on a line with channel
* name etc. * name etc.
*/ */
if(strlen(mask) > IRCD_MIN(BANLEN, MODEBUFLEN - 5)) if(strlen(mask) > MIN(BANLEN, MODEBUFLEN - 5))
{ {
sendto_one_numeric(source_p, ERR_INVALIDBAN, sendto_one_numeric(source_p, ERR_INVALIDBAN,
form_str(ERR_INVALIDBAN), form_str(ERR_INVALIDBAN),

View file

@ -23,11 +23,10 @@
*/ */
#include "stdinc.h" #include "stdinc.h"
#include "config.h" #include "defaults.h"
#include "class.h" #include "class.h"
#include "client.h" #include "client.h"
#include "common.h"
#include "ircd.h" #include "ircd.h"
#include "numeric.h" #include "numeric.h"
#include "s_conf.h" #include "s_conf.h"

View file

@ -23,11 +23,10 @@
* USA * USA
*/ */
#include "stdinc.h" #include "stdinc.h"
#include "config.h" #include "defaults.h"
#include "client.h" #include "client.h"
#include "class.h" #include "class.h"
#include "common.h"
#include "hash.h" #include "hash.h"
#include "match.h" #include "match.h"
#include "ircd.h" #include "ircd.h"
@ -77,9 +76,9 @@ static rb_bh *pclient_heap = NULL;
static rb_bh *user_heap = NULL; static rb_bh *user_heap = NULL;
static rb_bh *away_heap = NULL; static rb_bh *away_heap = NULL;
static char current_uid[IDLEN]; static char current_uid[IDLEN];
static int32_t current_connid = 0; static uint32_t current_connid = 0;
struct Dictionary *nd_dict = NULL; rb_dictionary *nd_dict = NULL;
enum enum
{ {
@ -130,6 +129,78 @@ init_client(void)
nd_dict = rb_dictionary_create("nickdelay", irccmp); nd_dict = rb_dictionary_create("nickdelay", irccmp);
} }
/*
* connid_get - allocate a connid
*
* inputs - none
* outputs - a connid token which is used to represent a logical circuit
* side effects - current_connid is incremented, possibly multiple times.
* the association of the connid to it's client is committed.
*/
uint32_t
connid_get(struct Client *client_p)
{
s_assert(MyClient(client_p));
if (!MyClient(client_p))
return 0;
/* find a connid that is available */
while (find_cli_connid_hash(++current_connid) != NULL)
{
/* handle wraparound, current_connid must NEVER be 0 */
if (current_connid == 0)
++current_connid;
}
add_to_cli_connid_hash(client_p, current_connid);
rb_dlinkAddAlloc(RB_UINT_TO_POINTER(current_connid), &client_p->localClient->connids);
return current_connid;
}
/*
* connid_put - free a connid
*
* inputs - connid to free
* outputs - nothing
* side effects - connid bookkeeping structures are freed
*/
void
connid_put(uint32_t id)
{
struct Client *client_p;
s_assert(id != 0);
if (id == 0)
return;
client_p = find_cli_connid_hash(id);
if (client_p == NULL)
return;
del_from_cli_connid_hash(id);
rb_dlinkFindDestroy(RB_UINT_TO_POINTER(id), &client_p->localClient->connids);
}
/*
* client_release_connids - release any connids still attached to a client
*
* inputs - client to garbage collect
* outputs - none
* side effects - client's connids are garbage collected
*/
void
client_release_connids(struct Client *client_p)
{
rb_dlink_node *ptr, *ptr2;
s_assert(MyClient(client_p));
if (!MyClient(client_p))
return;
RB_DLINK_FOREACH_SAFE(ptr, ptr2, client_p->localClient->connids.head)
connid_put(RB_POINTER_TO_UINT(ptr->data));
}
/* /*
* make_client - create a new Client struct and set it to initial state. * make_client - create a new Client struct and set it to initial state.
@ -161,17 +232,6 @@ make_client(struct Client *from)
client_p->localClient->F = NULL; client_p->localClient->F = NULL;
if(current_connid+1 == 0)
current_connid++;
client_p->localClient->connid = ++current_connid;
if(current_connid+1 == 0)
current_connid++;
client_p->localClient->zconnid = ++current_connid;
add_to_cli_connid_hash(client_p);
client_p->preClient = rb_bh_alloc(pclient_heap); client_p->preClient = rb_bh_alloc(pclient_heap);
/* as good a place as any... */ /* as good a place as any... */
@ -230,7 +290,7 @@ free_local_client(struct Client *client_p)
client_p->localClient->listener = 0; client_p->localClient->listener = 0;
} }
del_from_cli_connid_hash(client_p); client_release_connids(client_p);
if(client_p->localClient->F != NULL) if(client_p->localClient->F != NULL)
{ {
rb_close(client_p->localClient->F); rb_close(client_p->localClient->F);
@ -542,7 +602,7 @@ check_dlines(void)
if(IsMe(client_p)) if(IsMe(client_p))
continue; continue;
if((aconf = find_dline((struct sockaddr *)&client_p->localClient->ip,client_p->localClient->ip.ss_family)) != NULL) if((aconf = find_dline((struct sockaddr *)&client_p->localClient->ip, GET_SS_FAMILY(&client_p->localClient->ip))) != NULL)
{ {
if(aconf->status & CONF_EXEMPTDLINE) if(aconf->status & CONF_EXEMPTDLINE)
continue; continue;
@ -561,7 +621,7 @@ check_dlines(void)
{ {
client_p = ptr->data; client_p = ptr->data;
if((aconf = find_dline((struct sockaddr *)&client_p->localClient->ip,client_p->localClient->ip.ss_family)) != NULL) if((aconf = find_dline((struct sockaddr *)&client_p->localClient->ip, GET_SS_FAMILY(&client_p->localClient->ip))) != NULL)
{ {
if(aconf->status & CONF_EXEMPTDLINE) if(aconf->status & CONF_EXEMPTDLINE)
continue; continue;
@ -1802,15 +1862,15 @@ free_user(struct User *user, struct Client *client_p)
if(user->refcnt < 0 || user->invited.head || user->channel.head) if(user->refcnt < 0 || user->invited.head || user->channel.head)
{ {
sendto_realops_snomask(SNO_GENERAL, L_ALL, sendto_realops_snomask(SNO_GENERAL, L_ALL,
"* %#lx user (%s!%s@%s) %#lx %#lx %#lx %lu %d *", "* %p user (%s!%s@%s) %p %p %p %lu %d *",
(unsigned long) client_p, client_p,
client_p ? client_p-> client_p ? client_p->
name : "<noname>", name : "<noname>",
client_p->username, client_p->username,
client_p->host, client_p->host,
(unsigned long) user, user,
(unsigned long) user->invited.head, user->invited.head,
(unsigned long) user->channel.head, user->channel.head,
rb_dlink_list_length(&user->channel), rb_dlink_list_length(&user->channel),
user->refcnt); user->refcnt);
s_assert(!user->refcnt); s_assert(!user->refcnt);
@ -1950,7 +2010,7 @@ close_connection(struct Client *client_p)
else else
ServerStats.is_ni++; ServerStats.is_ni++;
del_from_cli_connid_hash(client_p); client_release_connids(client_p);
if(client_p->localClient->F != NULL) if(client_p->localClient->F != NULL)
{ {

View file

@ -37,16 +37,13 @@
#include "msg.h" #include "msg.h"
#include "hash.h" #include "hash.h"
#define DNS_IDTABLE_SIZE 0x2000
#define DNS_STATTABLE_SIZE 0x10
#define DNS_HOST_IPV4 ((char)'4') #define DNS_HOST_IPV4 ((char)'4')
#define DNS_HOST_IPV6 ((char)'6') #define DNS_HOST_IPV6 ((char)'6')
#define DNS_REVERSE_IPV4 ((char)'R') #define DNS_REVERSE_IPV4 ((char)'R')
#define DNS_REVERSE_IPV6 ((char)'S') #define DNS_REVERSE_IPV6 ((char)'S')
static void submit_dns(uint16_t uid, char type, const char *addr); static void submit_dns(uint32_t uid, char type, const char *addr);
static void submit_dns_stat(uint16_t uid); static void submit_dns_stat(uint32_t uid);
struct dnsreq struct dnsreq
{ {
@ -60,55 +57,24 @@ struct dnsstatreq
void *data; void *data;
}; };
static struct dnsreq querytable[DNS_IDTABLE_SIZE]; /* These serve as a form of sparse array */
static struct dnsstatreq stattable[DNS_STATTABLE_SIZE]; static rb_dictionary *query_dict;
static rb_dictionary *stat_dict;
rb_dlink_list nameservers; rb_dlink_list nameservers;
static uint32_t query_id = 0;
static uint32_t stat_id = 0;
static uint16_t #define ASSIGN_ID(id) (id++)
assign_dns_id(void)
{
static uint16_t id = 1;
int loopcnt = 0;
while(1)
{
if(++loopcnt > DNS_IDTABLE_SIZE)
return 0;
if(id < DNS_IDTABLE_SIZE - 1 || id == 0)
id++;
else
id = 1;
if(querytable[id].callback == NULL)
break;
}
return (id);
}
static uint8_t
assign_dns_stat_id(void)
{
static uint8_t id = 1;
int loopcnt = 0;
while(1)
{
if(++loopcnt > DNS_STATTABLE_SIZE)
return 0;
if(id < DNS_STATTABLE_SIZE - 1 || id == 0)
id++;
else
id = 1;
if(stattable[id].callback == NULL)
break;
}
return (id);
}
static void static void
handle_dns_failure(uint16_t xid) handle_dns_failure(uint32_t xid)
{ {
struct dnsreq *req; struct dnsreq *req = rb_dictionary_retrieve(query_dict, RB_UINT_TO_POINTER(xid));
s_assert(req);
req = &querytable[xid];
if(req->callback == NULL) if(req->callback == NULL)
return; return;
@ -118,47 +84,49 @@ handle_dns_failure(uint16_t xid)
} }
static void static void
handle_dns_stat_failure(uint8_t xid) handle_dns_stat_failure(uint32_t xid)
{ {
struct dnsstatreq *req; struct dnsstatreq *req = rb_dictionary_retrieve(stat_dict, RB_UINT_TO_POINTER(xid));
const char *err[] = { "Unknown failure" }; s_assert(req);
req = &stattable[xid];
if(req->callback == NULL) if(req->callback == NULL)
return; return;
req->callback(1, err, 2, req->data); req->callback(1, NULL, 2, req->data);
req->callback = NULL;
req->data = NULL;
}
void
cancel_lookup(uint32_t xid)
{
struct dnsreq *req = rb_dictionary_retrieve(query_dict, RB_UINT_TO_POINTER(xid));
s_assert(req);
req->callback = NULL; req->callback = NULL;
req->data = NULL; req->data = NULL;
} }
void void
cancel_lookup(uint16_t xid) cancel_dns_stats(uint32_t xid)
{ {
querytable[xid].callback = NULL; struct dnsstatreq *req = rb_dictionary_retrieve(stat_dict, RB_UINT_TO_POINTER(xid));
querytable[xid].data = NULL; s_assert(req);
req->callback = NULL;
req->data = NULL;
} }
void
cancel_dns_stats(uint16_t xid)
{
stattable[xid].callback = NULL;
stattable[xid].data = NULL;
}
uint16_t uint32_t
lookup_hostname(const char *hostname, int aftype, DNSCB callback, void *data) lookup_hostname(const char *hostname, int aftype, DNSCB callback, void *data)
{ {
struct dnsreq *req; struct dnsreq *req = rb_malloc(sizeof(struct dnsreq));
int aft; int aft;
uint16_t nid; uint32_t rid = ASSIGN_ID(query_id);
check_authd();
nid = assign_dns_id();
if((nid = assign_dns_id()) == 0)
return 0;
req = &querytable[nid]; check_authd();
rb_dictionary_add(query_dict, RB_UINT_TO_POINTER(rid), req);
req->callback = callback; req->callback = callback;
req->data = data; req->data = data;
@ -170,22 +138,20 @@ lookup_hostname(const char *hostname, int aftype, DNSCB callback, void *data)
#endif #endif
aft = 4; aft = 4;
submit_dns(nid, aft == 4 ? DNS_HOST_IPV4 : DNS_HOST_IPV6, hostname); submit_dns(rid, aft == 4 ? DNS_HOST_IPV4 : DNS_HOST_IPV6, hostname);
return (nid); return (rid);
} }
uint16_t uint32_t
lookup_ip(const char *addr, int aftype, DNSCB callback, void *data) lookup_ip(const char *addr, int aftype, DNSCB callback, void *data)
{ {
struct dnsreq *req; struct dnsreq *req = rb_malloc(sizeof(struct dnsreq));
int aft; int aft;
uint16_t nid; uint32_t rid = ASSIGN_ID(query_id);
check_authd(); check_authd();
if((nid = assign_dns_id()) == 0) rb_dictionary_add(query_dict, RB_UINT_TO_POINTER(rid), req);
return 0;
req = &querytable[nid];
req->callback = callback; req->callback = callback;
req->data = data; req->data = data;
@ -197,41 +163,45 @@ lookup_ip(const char *addr, int aftype, DNSCB callback, void *data)
#endif #endif
aft = 4; aft = 4;
submit_dns(nid, aft == 4 ? DNS_REVERSE_IPV4 : DNS_REVERSE_IPV6, addr); submit_dns(rid, aft == 4 ? DNS_REVERSE_IPV4 : DNS_REVERSE_IPV6, addr);
return (nid); return (rid);
} }
uint8_t uint32_t
get_nameservers(DNSLISTCB callback, void *data) get_nameservers(DNSLISTCB callback, void *data)
{ {
struct dnsstatreq *req; struct dnsstatreq *req = rb_malloc(sizeof(struct dnsstatreq));
uint8_t nid; uint32_t qid = ASSIGN_ID(stat_id);
check_authd(); check_authd();
if((nid = assign_dns_stat_id()) == 0) rb_dictionary_add(stat_dict, RB_UINT_TO_POINTER(qid), req);
return 0;
req = &stattable[nid];
req->callback = callback; req->callback = callback;
req->data = data; req->data = data;
submit_dns_stat(nid); submit_dns_stat(qid);
return (nid); return (qid);
} }
void void
dns_results_callback(const char *callid, const char *status, const char *type, const char *results) dns_results_callback(const char *callid, const char *status, const char *type, const char *results)
{ {
struct dnsreq *req; struct dnsreq *req;
uint16_t nid; uint32_t rid;
int st; int st;
int aft; int aft;
long lnid = strtol(callid, NULL, 16); long lrid = strtol(callid, NULL, 16);
if(lnid > DNS_IDTABLE_SIZE || lnid == 0) if(lrid > UINT32_MAX)
return; return;
nid = (uint16_t)lnid;
req = &querytable[nid]; rid = (uint32_t)lrid;
req = rb_dictionary_retrieve(query_dict, RB_UINT_TO_POINTER(rid));
if(req == NULL)
return;
st = (*status == 'O'); st = (*status == 'O');
aft = *type == '6' || *type == 'S' ? 6 : 4; aft = *type == '6' || *type == 'S' ? 6 : 4;
if(req->callback == NULL) if(req->callback == NULL)
@ -248,22 +218,26 @@ dns_results_callback(const char *callid, const char *status, const char *type, c
aft = AF_INET; aft = AF_INET;
req->callback(results, st, aft, req->data); req->callback(results, st, aft, req->data);
req->callback = NULL;
req->data = NULL; rb_free(req);
rb_dictionary_delete(query_dict, RB_UINT_TO_POINTER(rid));
} }
void void
dns_stats_results_callback(const char *callid, const char *status, int resc, const char *resv[]) dns_stats_results_callback(const char *callid, const char *status, int resc, const char *resv[])
{ {
struct dnsstatreq *req; struct dnsstatreq *req;
uint8_t nid; uint32_t qid;
int st, i; int st;
long lnid = strtol(callid, NULL, 16); long lqid = strtol(callid, NULL, 16);
if(lnid > DNS_STATTABLE_SIZE || lnid == 0) if(lqid > UINT32_MAX)
return; return;
nid = (uint8_t)lnid;
req = &stattable[nid]; qid = (uint32_t)lqid;
req = rb_dictionary_retrieve(stat_dict, RB_UINT_TO_POINTER(qid));
s_assert(req);
if(req->callback == NULL) if(req->callback == NULL)
{ {
@ -286,14 +260,14 @@ dns_stats_results_callback(const char *callid, const char *status, int resc, con
} }
/* Query complete */ /* Query complete */
req->callback(resc, resv, st, stattable[nid].data); req->callback(resc, resv, st, req->data);
req->data = NULL; rb_free(req);
req->callback = NULL; rb_dictionary_delete(stat_dict, RB_UINT_TO_POINTER(qid));
} }
static void static void
get_nameservers_cb(int resc, const char *resv[], int status, void *data) stats_results_callback(int resc, const char *resv[], int status, void *data)
{ {
if(status == 0) if(status == 0)
{ {
@ -316,28 +290,26 @@ get_nameservers_cb(int resc, const char *resv[], int status, void *data)
} }
} }
void void
init_nameserver_cache(void) init_dns(void)
{ {
(void)get_nameservers(get_nameservers_cb, NULL); query_dict = rb_dictionary_create("dns queries", rb_uint32cmp);
stat_dict = rb_dictionary_create("dns stat queries", rb_uint32cmp);
(void)get_nameservers(stats_results_callback, NULL);
} }
bool void
reload_nameservers(void) reload_nameservers(void)
{ {
if(authd_helper == NULL) check_authd();
{ rb_helper_write(authd_helper, "R D");
/* Shit */ (void)get_nameservers(stats_results_callback, NULL);
return false;
}
rb_helper_write(authd_helper, "H D");
init_nameserver_cache();
return true;
} }
static void static void
submit_dns(uint16_t nid, char type, const char *addr) submit_dns(uint32_t nid, char type, const char *addr)
{ {
if(authd_helper == NULL) if(authd_helper == NULL)
{ {
@ -348,7 +320,7 @@ submit_dns(uint16_t nid, char type, const char *addr)
} }
static void static void
submit_dns_stat(uint16_t nid) submit_dns_stat(uint32_t nid)
{ {
if(authd_helper == NULL) if(authd_helper == NULL)
{ {

View file

@ -23,7 +23,6 @@
#include "stdinc.h" #include "stdinc.h"
#include "channel.h" #include "channel.h"
#include "client.h" #include "client.h"
#include "common.h"
ExtbanFunc extban_table[256] = { NULL }; ExtbanFunc extban_table[256] = { NULL };

View file

@ -27,7 +27,6 @@
#include "s_conf.h" #include "s_conf.h"
#include "channel.h" #include "channel.h"
#include "client.h" #include "client.h"
#include "common.h"
#include "hash.h" #include "hash.h"
#include "match.h" #include "match.h"
#include "ircd.h" #include "ircd.h"
@ -40,14 +39,13 @@
#include "rb_dictionary.h" #include "rb_dictionary.h"
#include "rb_radixtree.h" #include "rb_radixtree.h"
struct Dictionary *client_connid_tree = NULL; rb_dictionary *client_connid_tree = NULL;
struct Dictionary *client_zconnid_tree = NULL; rb_radixtree *client_id_tree = NULL;
struct rb_radixtree *client_id_tree = NULL; rb_radixtree *client_name_tree = NULL;
struct rb_radixtree *client_name_tree = NULL;
struct rb_radixtree *channel_tree = NULL; rb_radixtree *channel_tree = NULL;
struct rb_radixtree *resv_tree = NULL; rb_radixtree *resv_tree = NULL;
struct rb_radixtree *hostname_tree = NULL; rb_radixtree *hostname_tree = NULL;
/* /*
* look in whowas.c for the missing ...[WW_MAX]; entry * look in whowas.c for the missing ...[WW_MAX]; entry
@ -61,7 +59,6 @@ void
init_hash(void) init_hash(void)
{ {
client_connid_tree = rb_dictionary_create("client connid", rb_uint32cmp); client_connid_tree = rb_dictionary_create("client connid", rb_uint32cmp);
client_zconnid_tree = rb_dictionary_create("client zconnid", rb_uint32cmp);
client_id_tree = rb_radixtree_create("client id", NULL); client_id_tree = rb_radixtree_create("client id", NULL);
client_name_tree = rb_radixtree_create("client name", irccasecanon); client_name_tree = rb_radixtree_create("client name", irccasecanon);
@ -71,10 +68,10 @@ init_hash(void)
hostname_tree = rb_radixtree_create("hostname", irccasecanon); hostname_tree = rb_radixtree_create("hostname", irccasecanon);
} }
u_int32_t uint32_t
fnv_hash_upper(const unsigned char *s, int bits) fnv_hash_upper(const unsigned char *s, int bits)
{ {
u_int32_t h = FNV1_32_INIT; uint32_t h = FNV1_32_INIT;
while (*s) while (*s)
{ {
@ -86,10 +83,10 @@ fnv_hash_upper(const unsigned char *s, int bits)
return h; return h;
} }
u_int32_t uint32_t
fnv_hash(const unsigned char *s, int bits) fnv_hash(const unsigned char *s, int bits)
{ {
u_int32_t h = FNV1_32_INIT; uint32_t h = FNV1_32_INIT;
while (*s) while (*s)
{ {
@ -101,10 +98,10 @@ fnv_hash(const unsigned char *s, int bits)
return h; return h;
} }
u_int32_t uint32_t
fnv_hash_len(const unsigned char *s, int bits, int len) fnv_hash_len(const unsigned char *s, int bits, int len)
{ {
u_int32_t h = FNV1_32_INIT; uint32_t h = FNV1_32_INIT;
const unsigned char *x = s + len; const unsigned char *x = s + len;
while (*s && s < x) while (*s && s < x)
{ {
@ -116,10 +113,10 @@ fnv_hash_len(const unsigned char *s, int bits, int len)
return h; return h;
} }
u_int32_t uint32_t
fnv_hash_upper_len(const unsigned char *s, int bits, int len) fnv_hash_upper_len(const unsigned char *s, int bits, int len)
{ {
u_int32_t h = FNV1_32_INIT; uint32_t h = FNV1_32_INIT;
const unsigned char *x = s + len; const unsigned char *x = s + len;
while (*s && s < x) while (*s && s < x)
{ {
@ -480,7 +477,7 @@ void
clear_resv_hash(void) clear_resv_hash(void)
{ {
struct ConfItem *aconf; struct ConfItem *aconf;
struct rb_radixtree_iteration_state iter; rb_radixtree_iteration_state iter;
RB_RADIXTREE_FOREACH(aconf, &iter, resv_tree) RB_RADIXTREE_FOREACH(aconf, &iter, resv_tree)
{ {
@ -494,41 +491,19 @@ clear_resv_hash(void)
} }
void void
add_to_zconnid_hash(struct Client *client_p) add_to_cli_connid_hash(struct Client *client_p, uint32_t id)
{ {
rb_dictionary_add(client_zconnid_tree, RB_UINT_TO_POINTER(client_p->localClient->zconnid), client_p); rb_dictionary_add(client_connid_tree, RB_UINT_TO_POINTER(id), client_p);
} }
void void
del_from_zconnid_hash(struct Client *client_p) del_from_cli_connid_hash(uint32_t id)
{ {
rb_dictionary_delete(client_zconnid_tree, RB_UINT_TO_POINTER(client_p->localClient->zconnid)); rb_dictionary_delete(client_connid_tree, RB_UINT_TO_POINTER(id));
}
void
add_to_cli_connid_hash(struct Client *client_p)
{
rb_dictionary_add(client_connid_tree, RB_UINT_TO_POINTER(client_p->localClient->connid), client_p);
}
void
del_from_cli_connid_hash(struct Client *client_p)
{
rb_dictionary_delete(client_connid_tree, RB_UINT_TO_POINTER(client_p->localClient->connid));
} }
struct Client * struct Client *
find_cli_connid_hash(uint32_t connid) find_cli_connid_hash(uint32_t connid)
{ {
struct Client *target_p; return rb_dictionary_retrieve(client_connid_tree, RB_UINT_TO_POINTER(connid));
target_p = rb_dictionary_retrieve(client_connid_tree, RB_UINT_TO_POINTER(connid));
if (target_p != NULL)
return target_p;
target_p = rb_dictionary_retrieve(client_zconnid_tree, RB_UINT_TO_POINTER(connid));
if (target_p != NULL)
return target_p;
return NULL;
} }

View file

@ -26,12 +26,11 @@
#include "rb_lib.h" #include "rb_lib.h"
#include "stdinc.h" #include "stdinc.h"
#include "setup.h" #include "setup.h"
#include "config.h" #include "defaults.h"
#include "ircd.h" #include "ircd.h"
#include "channel.h" #include "channel.h"
#include "class.h" #include "class.h"
#include "client.h" #include "client.h"
#include "common.h"
#include "hash.h" #include "hash.h"
#include "match.h" #include "match.h"
#include "ircd_signal.h" #include "ircd_signal.h"
@ -95,9 +94,6 @@ 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 local_oper_list; /* our opers, duplicated in lclient_list */
rb_dlink_list oper_list; /* network opers */ rb_dlink_list oper_list; /* network opers */
const char *logFileName = LPATH;
const char *pidFileName = PPATH;
char **myargv; char **myargv;
bool dorehash = false; bool dorehash = false;
bool dorehashbans = false; bool dorehashbans = false;
@ -105,8 +101,8 @@ bool doremotd = false;
bool kline_queued = false; bool kline_queued = false;
bool server_state_foreground = false; bool server_state_foreground = false;
bool opers_see_all_users = false; bool opers_see_all_users = false;
bool ssl_ok = false; bool ircd_ssl_ok = false;
bool zlib_ok = true; bool ircd_zlib_ok = true;
int testing_conf = 0; int testing_conf = 0;
time_t startup_time; time_t startup_time;
@ -119,6 +115,28 @@ int split_users;
int split_servers; int split_servers;
int eob_count; int eob_count;
const char *ircd_paths[IRCD_PATH_COUNT] = {
[IRCD_PATH_PREFIX] = DPATH,
[IRCD_PATH_MODULES] = MODPATH,
[IRCD_PATH_AUTOLOAD_MODULES] = AUTOMODPATH,
[IRCD_PATH_ETC] = ETCPATH,
[IRCD_PATH_LOG] = LOGPATH,
[IRCD_PATH_USERHELP] = UHPATH,
[IRCD_PATH_OPERHELP] = HPATH,
[IRCD_PATH_IRCD_EXEC] = SPATH,
[IRCD_PATH_IRCD_CONF] = CPATH,
[IRCD_PATH_IRCD_MOTD] = MPATH,
[IRCD_PATH_IRCD_LOG] = LPATH,
[IRCD_PATH_IRCD_PID] = PPATH,
[IRCD_PATH_IRCD_OMOTD] = OPATH,
[IRCD_PATH_BANDB] = DBPATH,
[IRCD_PATH_BIN] = BINPATH,
[IRCD_PATH_LIBEXEC] = PKGLIBEXECDIR,
};
const char *logFileName = NULL;
const char *pidFileName = NULL;
void void
ircd_shutdown(const char *reason) ircd_shutdown(const char *reason)
{ {
@ -156,6 +174,7 @@ print_startup(int pid)
{ {
int fd; int fd;
#ifndef _WIN32
close(1); close(1);
fd = open("/dev/null", O_RDWR); fd = open("/dev/null", O_RDWR);
if (fd == -1) { if (fd == -1) {
@ -166,19 +185,30 @@ print_startup(int pid)
fd = dup(fd); fd = dup(fd);
if (fd != 1) if (fd != 1)
abort(); abort();
#endif
inotice("runtime path: %s", rb_path_to_self());
inotice("now running in %s mode from %s as pid %d ...", inotice("now running in %s mode from %s as pid %d ...",
!server_state_foreground ? "background" : "foreground", !server_state_foreground ? "background" : "foreground",
ConfigFileEntry.dpath, pid); ConfigFileEntry.dpath, pid);
#ifndef _WIN32
/* let the parent process know the initialization was successful /* let the parent process know the initialization was successful
* -- jilles */ * -- jilles */
if (!server_state_foreground) if (!server_state_foreground)
write(0, ".", 1); {
/* GCC complains on Linux if we don't check the value of write pedantically.
* Technically you're supposed to check the value, yes, but it probably can't fail.
* No, casting to void is of no use to shut the warning up. You HAVE to use the value.
* --Elizfaox
*/
if(write(0, ".", 1) < 1)
abort();
}
if (dup2(1, 0) == -1) if (dup2(1, 0) == -1)
abort(); abort();
if (dup2(1, 2) == -1) if (dup2(1, 2) == -1)
abort(); abort();
#endif
} }
/* /*
@ -191,7 +221,7 @@ print_startup(int pid)
static void static void
init_sys(void) init_sys(void)
{ {
#if defined(RLIMIT_NOFILE) && defined(HAVE_SYS_RESOURCE_H) #if !defined(_WIN32) && defined(RLIMIT_NOFILE) && defined(HAVE_SYS_RESOURCE_H)
struct rlimit limit; struct rlimit limit;
if(!getrlimit(RLIMIT_NOFILE, &limit)) if(!getrlimit(RLIMIT_NOFILE, &limit))
@ -212,6 +242,7 @@ init_sys(void)
static int static int
make_daemon(void) make_daemon(void)
{ {
#ifndef _WIN32
int pid; int pid;
int pip[2]; int pip[2];
char c; char c;
@ -246,7 +277,7 @@ make_daemon(void)
/* fclose(stdin); /* fclose(stdin);
fclose(stdout); fclose(stdout);
fclose(stderr); */ fclose(stderr); */
#endif
return 0; return 0;
} }
@ -277,13 +308,13 @@ check_rehash(void *unused)
*/ */
if(dorehash) if(dorehash)
{ {
rehash(1); rehash(true);
dorehash = false; dorehash = false;
} }
if(dorehashbans) if(dorehashbans)
{ {
rehash_bans(1); rehash_bans();
dorehashbans = false; dorehashbans = false;
} }
@ -358,6 +389,85 @@ initialize_server_capabs(void)
default_server_capabs &= ~CAP_ZIP; default_server_capabs &= ~CAP_ZIP;
} }
/*
* relocate_paths
*
* inputs - none
* output - none
* side effects - items in ircd_paths[] array are relocated
*/
#ifdef _WIN32
static void
relocate_paths(void)
{
char prefix[PATH_MAX], workbuf[PATH_MAX];
char *p;
rb_strlcpy(prefix, rb_path_to_self(), sizeof prefix);
ircd_paths[IRCD_PATH_IRCD_EXEC] = rb_strdup(prefix);
/* if we're running from inside the source tree, we probably do not want to relocate any other paths */
if (strstr(prefix, ".libs") != NULL)
return;
/* prefix = /home/kaniini/ircd/bin/ircd */
p = strrchr(prefix, RB_PATH_SEPARATOR);
if (rb_unlikely(p == NULL))
return;
*p = 0;
/* prefix = /home/kaniini/ircd/bin */
p = strrchr(prefix, RB_PATH_SEPARATOR);
if (rb_unlikely(p == NULL))
return;
*p = 0;
/* prefix = /home/kaniini/ircd */
ircd_paths[IRCD_PATH_PREFIX] = rb_strdup(prefix);
/* now that we have our prefix, we can relocate the other paths... */
snprintf(workbuf, sizeof workbuf, "%s%cmodules", prefix, RB_PATH_SEPARATOR);
ircd_paths[IRCD_PATH_MODULES] = rb_strdup(workbuf);
snprintf(workbuf, sizeof workbuf, "%s%cmodules%cautoload", prefix, RB_PATH_SEPARATOR, RB_PATH_SEPARATOR);
ircd_paths[IRCD_PATH_AUTOLOAD_MODULES] = rb_strdup(workbuf);
snprintf(workbuf, sizeof workbuf, "%s%cetc", prefix, RB_PATH_SEPARATOR);
ircd_paths[IRCD_PATH_ETC] = rb_strdup(workbuf);
snprintf(workbuf, sizeof workbuf, "%s%clog", prefix, RB_PATH_SEPARATOR);
ircd_paths[IRCD_PATH_LOG] = rb_strdup(workbuf);
snprintf(workbuf, sizeof workbuf, "%s%chelp%cusers", prefix, RB_PATH_SEPARATOR, RB_PATH_SEPARATOR);
ircd_paths[IRCD_PATH_USERHELP] = rb_strdup(workbuf);
snprintf(workbuf, sizeof workbuf, "%s%chelp%copers", prefix, RB_PATH_SEPARATOR, RB_PATH_SEPARATOR);
ircd_paths[IRCD_PATH_OPERHELP] = rb_strdup(workbuf);
snprintf(workbuf, sizeof workbuf, "%s%cetc%circd.conf", prefix, RB_PATH_SEPARATOR, RB_PATH_SEPARATOR);
ircd_paths[IRCD_PATH_IRCD_CONF] = rb_strdup(workbuf);
snprintf(workbuf, sizeof workbuf, "%s%cetc%circd.motd", prefix, RB_PATH_SEPARATOR, RB_PATH_SEPARATOR);
ircd_paths[IRCD_PATH_IRCD_MOTD] = rb_strdup(workbuf);
snprintf(workbuf, sizeof workbuf, "%s%cetc%copers.motd", prefix, RB_PATH_SEPARATOR, RB_PATH_SEPARATOR);
ircd_paths[IRCD_PATH_IRCD_OMOTD] = rb_strdup(workbuf);
snprintf(workbuf, sizeof workbuf, "%s%cetc%cban.db", prefix, RB_PATH_SEPARATOR, RB_PATH_SEPARATOR);
ircd_paths[IRCD_PATH_BANDB] = rb_strdup(workbuf);
snprintf(workbuf, sizeof workbuf, "%s%cetc%circd.pid", prefix, RB_PATH_SEPARATOR, RB_PATH_SEPARATOR);
ircd_paths[IRCD_PATH_IRCD_PID] = rb_strdup(workbuf);
snprintf(workbuf, sizeof workbuf, "%s%clogs%circd.log", prefix, RB_PATH_SEPARATOR, RB_PATH_SEPARATOR);
ircd_paths[IRCD_PATH_IRCD_LOG] = rb_strdup(workbuf);
snprintf(workbuf, sizeof workbuf, "%s%cbin", prefix, RB_PATH_SEPARATOR);
ircd_paths[IRCD_PATH_BIN] = rb_strdup(workbuf);
ircd_paths[IRCD_PATH_LIBEXEC] = rb_strdup(workbuf);
}
#endif
/* /*
* write_pidfile * write_pidfile
@ -412,7 +522,7 @@ check_pidfile(const char *filename)
if(fgets(buff, 20, fb) != NULL) if(fgets(buff, 20, fb) != NULL)
{ {
pidfromfile = atoi(buff); pidfromfile = atoi(buff);
if(!kill(pidfromfile, 0)) if(!rb_kill(pidfromfile, 0))
{ {
printf("ircd: daemon is already running\n"); printf("ircd: daemon is already running\n");
exit(-1); exit(-1);
@ -539,19 +649,28 @@ charybdis_main(int argc, char *argv[])
{ {
int fd; int fd;
#ifndef _WIN32
/* Check to see if the user is running us as root, which is a nono */ /* Check to see if the user is running us as root, which is a nono */
if(geteuid() == 0) if(geteuid() == 0)
{ {
fprintf(stderr, "Don't run ircd as root!!!\n"); fprintf(stderr, "Don't run ircd as root!!!\n");
return -1; return -1;
} }
#endif
#ifdef _WIN32
relocate_paths();
#endif
logFileName = ircd_paths[IRCD_PATH_IRCD_LOG];
pidFileName = ircd_paths[IRCD_PATH_IRCD_PID];
ConfigFileEntry.dpath = ircd_paths[IRCD_PATH_PREFIX];
ConfigFileEntry.configfile = ircd_paths[IRCD_PATH_IRCD_CONF]; /* Server configuration file */
ConfigFileEntry.connect_timeout = 30; /* Default to 30 */
init_sys(); 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 */ umask(077); /* better safe than sorry --SRB */
myargv = argv; myargv = argv;
@ -607,6 +726,7 @@ charybdis_main(int argc, char *argv[])
if (testing_conf) if (testing_conf)
server_state_foreground = true; server_state_foreground = true;
#ifndef _WIN32
/* Make sure fd 0, 1 and 2 are in use -- jilles */ /* Make sure fd 0, 1 and 2 are in use -- jilles */
do do
{ {
@ -616,6 +736,7 @@ charybdis_main(int argc, char *argv[])
close(fd); close(fd);
else if (fd == -1) else if (fd == -1)
exit(1); exit(1);
#endif
/* Check if there is pidfile and daemon already running */ /* Check if there is pidfile and daemon already running */
if(!testing_conf) if(!testing_conf)
@ -663,7 +784,7 @@ charybdis_main(int argc, char *argv[])
init_auth(); /* Initialise the auth code */ init_auth(); /* Initialise the auth code */
init_authd(); /* Start up authd. */ init_authd(); /* Start up authd. */
init_nameserver_cache(); /* Get our nameserver cache for STATS a/A */ init_dns(); /* Start up DNS query system */
privilegeset_set_new("default", "", 0); privilegeset_set_new("default", "", 0);
@ -679,7 +800,7 @@ charybdis_main(int argc, char *argv[])
init_bandb(); init_bandb();
init_ssld(); init_ssld();
rehash_bans(0); rehash_bans();
initialize_server_capabs(); /* Set up default_server_capabs */ initialize_server_capabs(); /* Set up default_server_capabs */
initialize_global_set_options(); initialize_global_set_options();
@ -713,10 +834,10 @@ charybdis_main(int argc, char *argv[])
if(!rb_setup_ssl_server(ServerInfo.ssl_cert, ServerInfo.ssl_private_key, ServerInfo.ssl_dh_params, ServerInfo.ssl_cipher_list)) if(!rb_setup_ssl_server(ServerInfo.ssl_cert, ServerInfo.ssl_private_key, ServerInfo.ssl_dh_params, ServerInfo.ssl_cipher_list))
{ {
ilog(L_MAIN, "WARNING: Unable to setup SSL."); ilog(L_MAIN, "WARNING: Unable to setup SSL.");
ssl_ok = false; ircd_ssl_ok = false;
} }
else else
ssl_ok = true; ircd_ssl_ok = true;
} }
if (testing_conf) if (testing_conf)

File diff suppressed because it is too large Load diff

View file

@ -25,8 +25,6 @@
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <netinet/in.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <limits.h> #include <limits.h>
@ -35,8 +33,7 @@
#include "stdinc.h" #include "stdinc.h"
#include "ircd_defs.h" #include "ircd_defs.h"
#include "common.h" #include "defaults.h"
#include "config.h"
#include "logger.h" #include "logger.h"
#include "s_conf.h" #include "s_conf.h"
#include "newconf.h" #include "newconf.h"
@ -55,8 +52,8 @@ void cinclude(void);
void hashcomment(void); void hashcomment(void);
int ieof(void); int ieof(void);
int lineno_stack[MAX_INCLUDE_DEPTH]; int lineno_stack[MAX_INCLUDE_DEPTH];
char conffile_stack[MAX_INCLUDE_DEPTH][IRCD_BUFSIZE]; char conffile_stack[MAX_INCLUDE_DEPTH][BUFSIZE];
char conffilebuf[IRCD_BUFSIZE+1]; char conffilebuf[BUFSIZE+1];
char *current_file = conffilebuf; char *current_file = conffilebuf;
FILE *inc_fbfile_in[MAX_INCLUDE_DEPTH]; FILE *inc_fbfile_in[MAX_INCLUDE_DEPTH];
@ -69,7 +66,7 @@ char linebuf[512];
#define YY_INPUT(buf,result,max_size) \ #define YY_INPUT(buf,result,max_size) \
if (!(result = conf_fgets(buf, max_size, conf_fbfile_in))) \ if (!(result = conf_fgets(buf, max_size, conf_fbfile_in))) \
YY_FATAL_ERROR("input in flex scanner failed"); YY_FATAL_ERROR("input in flex scanner failed");
%} %}
ws [ \t]* ws [ \t]*
@ -104,9 +101,9 @@ include \.include{ws}(\<.*\>|\".*\")
{ {
int i,j; int i,j;
yylval.string[yyleng-2] = '\0'; /* remove close yylval.string[yyleng-2] = '\0'; /* remove close
* quote * quote
*/ */
for (j=i=0 ;yylval.string[i] != '\0'; i++,j++) for (j=i=0 ;yylval.string[i] != '\0'; i++,j++)
{ {
if (yylval.string[i] != '\\') if (yylval.string[i] != '\\')
@ -116,7 +113,7 @@ include \.include{ws}(\<.*\>|\".*\")
else else
{ {
i++; i++;
if (yylval.string[i] == '\0') /* XXX if (yylval.string[i] == '\0') /* XXX
* should not * should not
* happen * happen
*/ */
@ -136,7 +133,7 @@ include \.include{ws}(\<.*\>|\".*\")
loadmodule { return LOADMODULE; } loadmodule { return LOADMODULE; }
{string} { {string} {
strcpy(yylval.string, yytext); strcpy(yylval.string, yytext);
yylval.string[yyleng] = '\0'; yylval.string[yyleng] = '\0';
return STRING; return STRING;
@ -151,7 +148,7 @@ loadmodule { return LOADMODULE; }
void ccomment() void ccomment()
{ {
int c; int c;
/* log(L_NOTICE, "got comment"); */ /* log(L_NOTICE, "got comment"); */
while (1) while (1)
{ {
@ -160,7 +157,7 @@ void ccomment()
if (c == '*') if (c == '*')
{ {
while ((c = input()) == '*'); while ((c = input()) == '*');
if (c == '/') if (c == '/')
break; break;
if (c == '\n') ++lineno; if (c == '\n') ++lineno;
} }
@ -185,21 +182,21 @@ void cinclude(void)
else else
*strchr(++c, '>') = 0; *strchr(++c, '>') = 0;
/* do stacking and co. */ /* do stacking and co. */
if (include_stack_ptr >= MAX_INCLUDE_DEPTH) if (include_stack_ptr >= MAX_INCLUDE_DEPTH)
conf_report_error("Includes nested too deep (max is %d)", MAX_INCLUDE_DEPTH); conf_report_error("Includes nested too deep (max is %d)", MAX_INCLUDE_DEPTH);
else else
{ {
FILE *tmp_fbfile_in; FILE *tmp_fbfile_in;
tmp_fbfile_in = fopen(c, "r"); tmp_fbfile_in = fopen(c, "r");
if (tmp_fbfile_in == NULL) if (tmp_fbfile_in == NULL)
{ {
/* if its not found in PREFIX, look in ETCPATH */ /* if its not found in PREFIX, look in IRCD_PATH_ETC */
char fnamebuf[IRCD_BUFSIZE]; char fnamebuf[BUFSIZE];
snprintf(fnamebuf, sizeof(fnamebuf), "%s/%s", ETCPATH, c); snprintf(fnamebuf, sizeof(fnamebuf), "%s%c%s", IRCD_PATH_ETC, RB_PATH_SEPARATOR, c);
tmp_fbfile_in = fopen(fnamebuf, "r"); tmp_fbfile_in = fopen(fnamebuf, "r");
/* wasnt found there either.. error. */ /* wasnt found there either.. error. */

File diff suppressed because it is too large Load diff

View file

@ -1,86 +0,0 @@
/* A Bison parser, made by GNU Bison 3.0.4. */
/* Bison interface for Yacc-like parsers in C
Copyright (C) 1984, 1989-1990, 2000-2015 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 3 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, see <http://www.gnu.org/licenses/>. */
/* As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work
under terms of your choice, so long as that work isn't itself a
parser generator using the skeleton or a modified version thereof
as a parser skeleton. Alternatively, if you modify or redistribute
the parser skeleton itself, you may (at your option) remove this
special exception, which will cause the skeleton and the resulting
Bison output files to be licensed under the GNU General Public
License without this special exception.
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
#ifndef YY_YY_IRCD_PARSER_H_INCLUDED
# define YY_YY_IRCD_PARSER_H_INCLUDED
/* Debug traces. */
#ifndef YYDEBUG
# define YYDEBUG 0
#endif
#if YYDEBUG
extern int yydebug;
#endif
/* Token type. */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
enum yytokentype
{
LOADMODULE = 258,
TWODOTS = 259,
QSTRING = 260,
STRING = 261,
NUMBER = 262
};
#endif
/* Tokens. */
#define LOADMODULE 258
#define TWODOTS 259
#define QSTRING 260
#define STRING 261
#define NUMBER 262
/* Value type. */
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
union YYSTYPE
{
#line 164 "ircd_parser.y" /* yacc.c:1909 */
int number;
char string[IRCD_BUFSIZE + 1];
conf_parm_t * conf_parm;
#line 74 "ircd_parser.h" /* yacc.c:1909 */
};
typedef union YYSTYPE YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define YYSTYPE_IS_DECLARED 1
#endif
extern YYSTYPE yylval;
int yyparse (void);
#endif /* !YY_YY_IRCD_PARSER_H_INCLUDED */

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