1
0
mirror of https://github.com/osmarks/ngircd.git synced 2025-09-23 20:54:02 +00:00

Compare commits

..

11 Commits

Author SHA1 Message Date
Alexander Barton
bb6e277963 ngIRCd Release 20.3 2013-08-23 21:54:40 +02:00
Alexander Barton
d24df64397 Correctly handle return code of Handle_Write()
There have been code paths that ignored the return code of Handle_Write()
when sending "notice auth" messages to new clients connecting to the
server. But because Handle_Write() would have closed the client connection
again if an error occurred, this would have resulted in new errors and
assert()'s later on that could have crashed the server (denial of service).

Only setups having the configuration option "NoticeAuth" enabled are
affected, which is not the default.

CVE-2013-5580.

(cherry picked from commit 309122017e)
2013-08-23 21:43:37 +02:00
Alexander Barton
c45d9dd1f0 ngIRCd Release 20.2 2013-02-15 12:18:02 +01:00
Sebastian Köhler
b3d4cf9081 KICK: Fix denial of service bug
Test if the user that it is to be kicked is on the channel before user
channel modes are tested. Otherwise assert( cl2chan != NULL ); in
line 742 would fail and stop the service.
(cherry picked from commit 0e63fb3fa7)
2013-02-15 11:56:24 +01:00
Alexander Barton
1265eb15b8 "WHO <hostmask>": use displayed hostname for matching
Use the currently "displayed hostname" (which can be cloaked!) for
hostname matching, not the real one. In other words: don't display
all the cloaked users on a specific real hostname!

Thanks to DNS <dns@rbose.org> for reporting this issue.
(cherry picked from commit 1e8b775a7a)
2013-02-13 22:12:09 +01:00
Alexander Barton
84612fe773 autogen.sh: Don't use "egrep -o", use "sed"
"egrep -o" isn't portable and not available on OpenBSD, for example. So
let's use sed instead to get the automake version. The expression used
now is less specific but should work as well ...
(cherry picked from commit 419ff38a07)
2013-02-13 22:11:49 +01:00
Alexander Barton
84f5839c17 configure: "netinet/in_systm.h" is optional
The header file "netinet/in_systm.h" already is optional in ngIRCd, so
don't require it in the configure script. Now ngIRCd can be built on
Minix 3 again :-)
(cherry picked from commit fd260404ca)
2013-02-13 22:11:39 +01:00
Alexander Barton
cb3b411166 Return better "Connection not registered as server link" errors
Now ngIRCd returns a more specific error message for numeric
ERR_NOTREGISTERED(451) when a regular user tries to use a command that
isn't allowed for users but for servers: ERR_NOTREGISTEREDSERVER(451).
(cherry picked from commit 508ca3044d)
2013-02-13 22:11:23 +01:00
Alexander Barton
121bcacb98 MODE: don't report error on "more modes than parameters"
Don't report ERR_NEEDMOREPARAMS(461) when a MDOE command with more modes
than nicknames is handled, as well as for channel limit and key changes
without specifying the limit or key parameters.

This is how a lot (all?) other IRC servers behave, including ircd2.11,
InspIRCd, and ircd-seven. And because of clients (tested with Textual and
mIRC) sending bogus MODE commands like "MODE -ooo nick", end-users got the
expected result as well as correct but misleading error messages ...

If ngIRCd is compiled using "strict mode", these errors are still reported.

Reported-by: Tim <tim@stackwatch.net>
(cherry picked from commit d8f2964710)
2013-02-13 22:11:14 +01:00
Alexander Barton
4105635566 Correctly detect when SSL subsystem must be initialized
This patch introduces the new function Conf_SSLInUse() to check when the
current server configuration requires the SSL subsystem to be initialized
and accounts incoming as well as outgoing connections -- so this fixes
commit bb20aeb9 ("Initialize SSL when needed only, and disable SSL on
errors") which only handled the inbound case  ...

Tested-by: Brett Smith <brett@w3.org>
(cherry picked from commit ab00997698)
2013-02-13 22:11:05 +01:00
Alexander Barton
90fce2ed16 autogen.sh: Enforce serial test harness on automake >=1.13
(cherry picked from commit 0703fcd719)
2013-02-13 22:10:49 +01:00
98 changed files with 3328 additions and 5736 deletions

1
.gitignore vendored
View File

@@ -7,7 +7,6 @@ ansi2knr.h
ar-lib
autom4te.cache
build-stamp-ngircd*
compile
config.log
config.status
configure

View File

@@ -1,8 +0,0 @@
language: c
before_install:
- sudo apt-get update -qq
- sudo apt-get install -qq libident-dev libpam0g-dev libssl-dev libwrap0-dev zlib1g-dev expect telnet
compiler:
- gcc
- clang
script: ./autogen.sh && ./configure --enable-ipv6 --with-iconv --with-ident --with-openssl --with-pam --with-tcp-wrappers --with-zlib && make check

46
AUTHORS
View File

@@ -2,7 +2,7 @@
ngIRCd - Next Generation IRC Server
http://ngircd.barton.de/
(c)2001-2014 Alexander Barton and Contributors.
(c)2001-2013 Alexander Barton and Contributors.
ngIRCd is free software and published under the
terms of the GNU General Public License.
@@ -18,41 +18,29 @@ Don't mail the people listed here directly, if possible!
Main Authors
~~~~~~~~~~~~
Alexander Barton <alex@barton.de>
Florian Westphal <fw@strlen.de>
Alexander Barton, <alex@barton.de> (alex)
Florian Westphal, <fw@strlen.de>
Contributors
~~~~~~~~~~~~
Ali Shemiran <ashemira@ucsd.edu>
Ask Bjørn Hansen <ask@develooper.com>
Benjamin Pineau <ben@zouh.org>
Brandon Beresini <beresini@google.com>
Brett Smith <brett@w3.org>
Brian Collins <bricollins@gmail.com>
Bryan Caldwell <bcaldwel@ucsd.edu>
Christoph Biedl <ngircd.anoy@manchmal.in-ulm.de>
DNS <dns@rbose.org>
Dana Dahlstrom <dana+ngIRCd@cs.ucsd.edu>
David Kingston <deathking1337@aim.com>
Eric Grunow <egrunow@ucsd.edu>
Federico G. Schwindt <fgsch@lodoss.net>
Gabor Adam Toth <tg@tgbit.net>
Goetz Hoffart <goetz@hoffart.de>
Ilja Osthoff <i.osthoff@gmx.net>
Jari Aalto <jari.aalto@cante.net>
Neale Pickett <neale@woozle.org>
Rolf Eike Beer <eike@sf-mail.de>
Scott Perry <scperry@ucsd.edu>
Sean Reifschneider <jafo-rpms@tummy.com>
Sebastian Köhler <sebkoehler@whoami.org.uk>
Tassilo Schweyer <dev@welterde.de>
William Pitcock <nenolod@dereferenced.org>
xor <xorboy@gmail.com>
Ali Shemiran, <ashemira@ucsd.edu>
Ask Bjørn Hansen, <ask@develooper.com>
Benjamin Pineau, <ben@zouh.org>
Brandon Beresini, <beresini@google.com>
Bryan Caldwell, <bcaldwel@ucsd.edu>
Dana Dahlstrom, <dana+ngIRCd@cs.ucsd.edu>
Eric Grunow, <egrunow@ucsd.edu>
Goetz Hoffart, <goetz@hoffart.de>
Ilja Osthoff, <i.osthoff@gmx.net>
Jari Aalto, <jari.aalto@cante.net>
Rolf Eike Beer, <eike@sf-mail.de>
Scott Perry, <scperry@ucsd.edu>
Sean Reifschneider, <jafo-rpms@tummy.com>
Code snippets
~~~~~~~~~~~~~
J. Kercheval: pattern matching functions
Patrick Powell <papowell@astart.com>: snprintf()-function
Patrick Powell, <papowell@astart.com>: snprintf()-function
Andrew Tridgell & Martin Pool: strl{cpy|cat}()-functions

207
ChangeLog
View File

@@ -2,214 +2,13 @@
ngIRCd - Next Generation IRC Server
http://ngircd.barton.de/
(c)2001-2014 Alexander Barton and Contributors.
(c)2001-2013 Alexander Barton and Contributors.
ngIRCd is free software and published under the
terms of the GNU General Public License.
-- ChangeLog --
ngIRCd 21.1 (2014-03-25)
- Don't ignore but use the server password when PAM is compiled in but
disabled. Thanks to Roy Sindre Norangshol <roy.sindre@norangshol.no>!
- doc/Platforms.txt: Update from master branch.
- Really kill connections that send "spoofed prefixes" on non-server links.
This fixes commit 6cbe1308 which only killed the connection when the
spoofed prefix itself belonged to a non-server client.
- CHARCONV command: Fix handling conversion errors, don't overwrite already
converted text!
- doc/Services.txt: Update information for Anope 2.x.
- Correctly use cloaked IRC masks on "INVITE nickname": The cloaked IRC mask
of a user is his visible mask, so the daemon has to use it for generating
the "one time" entries for the invite list of the given channel, and not
the "real" mask which will never match while the target client is "+x", and
even worse, will disclose the real mask on "MODE #channel +I" commands :-/
Bug reported by Cahata on #ngircd, thanks!
- configure: Only link "contrib/Debian" if it exists. This isn't the case on
"VPATH builds", for example.
- Use $(MKDIR_P) instead of $(mkinstalldirs) in Makefile's and test for
"mkdir -p" using AC_PROG_MKDIR_P in "configure".
- Fix configure script and "make check" for TCP Wrappers (problems spotted on
OpenBSD): add missing #include's and static variables, and add libwrap at
the end of the configure run because if libwrap becomes added earlier,
other tests may fail.
- configure: add support for the LDFLAGS_END and LIBS_END variables to add
linker flags and libraries at the end of the configure run (CFLAGS_END has
been implemented already).
- platformtest.sh and Makefile.am: Don't use "test -e", it isn't portable.
- Update Copyright notices for 2014 :-)
- Fix permanent {G|K}LINES (with a timeout of 0 seconds).
- WEBIRC: Don't set the hostname received by the WEBIRC command when DNS
lookups are disabled, but use the IP address instead.
Reported by Toni Spets <toni.spets@iki.fi>, thanks!
- Check for working getaddrinfo() function: At least AIX 4.3.3 and 5.1 have a
broken implementation of getaddrinfo() which doesn't handle "0" as numeric
service correctly. This patch adds a configure check for this case and
changes all calling functions to only use getaddrinfo() if it "works".
See <http://www.stacken.kth.se/lists/heimdal-discuss/2004-05/msg00059.html>
- Only use the unsetenv() function when it is available (AIX 4.3 doesn't
support it, for example).
- Make sure that the source code is still compatible with the "ansi2knr" tool
and builds using non-ANSI K&R C compilers. Tested with Apple C on A/UX.
- Fix building ngIRCd without support for ZLIB compression. Reported by
"der_baer" on #ngircd, thanks!
ngIRCd 21 (2013-10-30)
- ./contrib/Debian/ngircd.init: Make sure no stale PID file is left over
when (re-)starting ngIRCd.
- Change ./contrib/platformtest.sh and update ./doc/Platforms.txt to
allow user names up to 8 characters.
- Call arc4random_stir() in forked subprocesses, when available. This
is required by FreeBSD <10 and current NetBSD at least to correctly
initialize the "arc4" random number generator on these platforms.
- Update our own Debian package configuration and fix the default path
of the "HelpFile" of the "full" package variants.
ngIRCd 21~rc2 (2013-10-20)
- Report the correct configuration file name on configuration errors,
support longer configuration lines, and warn when lines are truncated.
- Use arc4random() function to generate "random" numbers, when available.
- platformtest.sh: Detect clang compiler, and clean up GIT source tree
before building (when possible).
- Update (date of) manual pages.
- Update "Upgrade Information" in INSTALL file, add more systems to
doc/Platforms.txt, and fix spelling in NEWS and ChangeLog files =:)
- Fix remaining compiler warnings on OpenBSD.
ngIRCd 21~rc1 (2013-10-05)
- Actually KILL clients on GLINE/KLINE. (Closes bug #156)
- Adjust log messages for invalid and spoofed prefixes, which cleans up
logging of commands related to already KILL'ed clients. And don't
forward KILL commands for (already) unknown clients any more to prevent
unnecessary duplicates.
- Add support to show all user links using the "STATS L" (uppercase)
command (restricted to IRC Operators).
- Fixed blocking of server reconnects in some error configurations.
- Don't ignore SSL-related errors during startup any more: abort startup
when SSL is requested by the configuration but can't be initialized and
don't continue only listening on plain text communication ports.
(Closes bug #163)
- Implement configurable SSL cipher list selection for GnuTLS and OpenSSL
using the new configuration option "CipherList". In addition, this
changes the defaults to more secure values: "HIGH:!aNULL:@STRENGTH" for
OpenSSL, and "SECURE128" for GnuTLS.
- Fix "TRACE": Correctly return ERR_NEEDMOREPARAMS(461) (which basically
is "syntax error") when there are too many parameters.
- Clean up lots of permission and parameter checks in functions handling
IRC commands; and more consistently add penalty times on errors.
- Fix error numeric of WHOIS when no nick name has been provided:
as per RFC it should be ERR_NONICKNAMEGIVEN(431).
- Only log "IDENT ... no result" messages when an IDENT looked took place
and didn't return any data, not when IDENT has been disabled.
- Show connection flag "s" (SSL) in RPL_TRACE{LINK|SERVER} messages: now
you can check if a server-to-server link is SSL-encrypted or not using
the IRC "TRACE" command.
- Correctly discard supplementary groups on server startup.
- Save client IP address text for "WebIRC" users and correctly display
it on WHOIS, for example. (Closes bug #159)
- Implement the new configuration option "DefaultUserModes" which lists
user modes that become automatically set on new local clients right
after login. Please note that only modes can be set that the client
could set on itself, so you can't set "a" (away) or "o" (IRC Op),
for example! User modes "i" (invisible) or "x" (cloaked) etc. are
"interesting", though. (Closes bug #160)
- Add support for the new METADATA "account" property, which allows
services to automatically identify users after netsplits and across
service restarts.
- Enforce "penalty times" on error conditions more consistently and in
more places. Now most error codes sent back from the IRC server to the
client should result in a 2 second "penalty".
- Implement a new configuration option "AllowedChannelTypes" that lists
all allowed channel types (channel prefixes) for newly created channels
on the local server. By default, all supported channel types are allowed.
If set to the empty string, local clients can't create new channels at
all, which equals the old "PredefChannelsOnly = yes" setting.
This change deprecates the "PredefChannelsOnly" variable, too, but it is
still supported and translated to the appropriate "AllowedChannelTypes"
setting. When the old "PredefChannelsOnly" variable is processed, a
warning message is logged. (Closes bug #152)
- Add support for "client certificate fingerprinting". When a client
passes an SSL certificate to the server, the "fingerprint" will be
forwarded in the network which enables IRC services to identify the
user using this certificate and not using passwords.
- IRC Operator names, as defined in ngircd.conf, are logged now when
handling successful OPER commands.
- Some error conditions while handling IRC commands, like "permission
denied" or "need more parameters", result in more penalty times.
- The numeric replies of some commands became split too early which
resulted in more numeric reply lines than necessary.
- Implement a new configuration option "IncludeDir" in the "[Options]"
section that can be used to specify a directory which can contain
further configuration files and configuration file snippets matching
the pattern "*.conf". These files are read in after the main server
configuration file ("ngircd.conf" by default) has been read in and
parsed. The default is "$SYSCONFDIR/ngircd.conf.d", so that it is
possible to adjust the configuration only by placing additional files
into this directory. (Closes bug #157)
- Fix use-after-free in the Lists_CheckReason() function, which is used
to check if a client is a member of a particular ban/invite/... list.
- Xcode: fix detection of host OS, vendor, and CPU type, and update
project settings for Xcode 5.
- OS X PackageMaker: use relative path names in project files and package
with correct file permissions (requires root privileges on "make").
- Add Travis-CI configuration file (".travis.yml") to project.
- Look for possible cloaked Masks in Lists. Users with +x user mode can
be banned with their cloaked hostname now.
- Don't read SSL client data before DNS resolver is finished which could
have resulted in discarding the resolved client hostname and IDENT
reply afterwards, because in some situations (timing dependent) the
NICK and USER commands could have already been read in from the client,
stored in the buffer, and been processed.
Thanks to Julian Brost for reporting the issue and testing, and to
Federico G. Schwindt <fgsch@lodoss.net> for helping to debug it!
- Increase password length limit to 64 characters. (Closes bug #154)
- doc/Services.txt: Update Anope status and URL.
- Clean up Xcode project file, remove outdated files, add missing ones.
- Update Doxygen configuration file.
- configure: search for iconv_open as well as libiconv_open, because
on some installations iconv_open() is actually libiconv_open().
iconv_open() is the glibc version while libiconv_open() is the
libiconv version, now both variants are supported. (Closes bug #151)
- ngIRCd now accepts user names including "@" characters, saves the
unmodified name for authentication but stores only the part in front
of the "@" character as "IRC user name". And the latter is how
ircd2.11, Bahamut, and irc-seven behave as well. (Closes bug #155)
- Lots of IRC "information functions" like ADMIN, INFO, ... now accept
server masks and names of connected users (in addition to server names)
for specifying the target server of the command. (Closes bug #153)
- Implement a new configuration option "IdleTimeout" in the "[Limits]"
section of the configuration file which can be used to set a timeout
in seconds after which the whole daemon will shutdown when no more
connections are left active after handling at least one client.
The default is 0, "never".
This can be useful for testing or when ngIRCd is started using "socket
activation" with systemd(8), for example.
- Implement support for systemd(8) "socket activation".
- contrib/README: add description for more files.
- Enable WHOIS to display information about IRC Services using the new
numeric 310(RPL_WHOISSERVICE) This numeric is used for this purpose by
InspIRCd, for example -- but as usual, other numerics are in use, too,
like 613 in UltimateIRCd ...
Please note that neither the Operator (+o) not the "bot status" (+B)
of an IRC service is displayed in the output.
- Exit message: use singular & plural :-)
- autogen.sh: Check for autoconf/automake wrapper scripts
- Add missing punctuation marks in log messages, adjust some severity
levels, and make SSL-related messages more readable.
- AUTHORS file: Update list of contributors.
- Update systemd(8) example configuration files in ./contrib/ directory:
the "ngircd.service" file now uses the "forking" service type which
enhances the log messages shown by "systemctl status ngircd.service",
and the new "ngircd.socket" file configures a systemd socket that
configures a socket for ngIRCd and launches the daemon on demand.
- Enhance help system and the HELP command: now a "help text file" can be
set using the new configuration option "HelpFile" ("global" section),
which is read in and parsed on server startup and configuration reload,
and then is used to output individual help texts to specific topics.
Please see the file ./doc/Commands.txt for details.
ngIRCd 20.3 (2013-08-23)
- Security: Fix a denial of service bug (server crash) which could happen
@@ -244,7 +43,7 @@ ngIRCd 20.2 (2013-02-15)
- autogen.sh: Enforce serial test harness on GNU automake >=1.13. The
new parallel test harness which is enabled by default starting with
automake 1.13 isn't compatible with our test suite.
And don't use "egrep -o", instead use "sed", because it isn't portable
And don't use "egrep -o", insetead use "sed", because it isn't portable
and not available on OpenBSD, for example.
ngIRCd 20.1 (2013-01-02)
@@ -265,7 +64,7 @@ ngIRCd 20 (2012-12-17)
- Allow user names ("INDENT") up to 20 characters when ngIRCd has not
been configured for "strict RFC mode". This is useful if you are using
external (PAM) authentication mechanisms that require longer user names.
external (PAM) authenticaion mechanisms that require longer user names.
Patch suggested by Brett Smith <brett@w3.org>, see
<http://arthur.barton.de/pipermail/ngircd-ml/2012-October/000579.html>.

15
INSTALL
View File

@@ -2,7 +2,7 @@
ngIRCd - Next Generation IRC Server
http://ngircd.barton.de/
(c)2001-2014 Alexander Barton and Contributors.
(c)2001-2013 Alexander Barton and Contributors.
ngIRCd is free software and published under the
terms of the GNU General Public License.
@@ -12,22 +12,11 @@
I. Upgrade Information
~~~~~~~~~~~~~~~~~~~~~~
Differences to version 20.x
- Starting with ngIRCd 21, the ciphers used by SSL are configurable and
default to HIGH:!aNULL:@STRENGTH (OpenSSL) or SECURE128 (GnuTLS).
Previous version were using the OpenSSL or GnuTLS defaults, DEFAULT
and NORMAL respectively.
- When adding GLINE's or KLINE's to ngIRCd 21 (or newer), all clients matching
the new mask will be KILL'ed. This was not the case with earlier versions
that only added the mask but didn't kill already connected users.
Differences to version 19.x
- Starting with ngIRCd 20, users can "cloak" their hostname only when the
configuration variable "CloakHostModeX" (introduced in 19.2) is set.
Otherwise, only IRC operators, other servers, and services are allowed to
Otherwise, only IRC opertators, other servers, and services are allowed to
set mode +x. This prevents regular users from changing their hostmask to
the name of the IRC server itself, which confused quite a few people ;-)

View File

@@ -1,6 +1,6 @@
#
# ngIRCd -- The Next Generation IRC Daemon
# Copyright (c)2001-2013 Alexander Barton (alex@barton.de) and Contributors
# Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors
#
# 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
@@ -15,8 +15,9 @@ SUBDIRS = doc src man contrib
EXTRA_DIST = autogen.sh configure.ng .mailmap
clean-local: osxpkg-clean
clean-local:
rm -f build-stamp*
rm -rf ngircd.dest
maintainer-clean-local:
rm -rf autom4te.cache
@@ -61,18 +62,14 @@ deb:
dpkg-buildpackage -rfakeroot -i
osxpkg: have-packagemaker osxpkg-dest
cd contrib/MacOSX && packagemaker --no-recommend \
cd contrib/MacOSX && packagemaker \
--doc ngIRCd.pmdoc \
--out ../../$(distdir).mpkg
rm -f $(distdir).mpkg.zip
zip -ro9 $(distdir).mpkg.zip $(distdir).mpkg
make osxpkg-clean
osxpkg-clean:
[ ! -r ngircd.dest ] || sudo -n rm -rf ngircd.dest
rm -rf ngircd.dest $(distdir).mpkg
osxpkg-dest: have-xcodebuild osxpkg-clean clean
osxpkg-dest: have-xcodebuild clean
./configure --prefix=/opt/ngircd
make xcode
make -C contrib/MacOSX de.barton.ngircd.plist
@@ -85,9 +82,8 @@ osxpkg-dest: have-xcodebuild osxpkg-clean clean
rm ngircd.dest/opt/ngircd/etc/ngircd.conf
echo "Have a nice day IRCing!" >ngircd.dest/opt/ngircd/etc/ngircd.motd
chmod -R a-s,og-w,a+rX ngircd.dest
sudo chown -R root:wheel ngircd.dest
.PHONY: deb have-packagemaker have-xcodebuild lint osxpkg osxpkg-clean \
osxpkg-dest rpm srcdoc testsuite xcode xcode-clean
.PHONY: deb have-packagemaker have-xcodebuild lint osxpkg osxpkg-dest rpm \
srcdoc testsuite xcode xcode-clean
# -eof-

99
NEWS
View File

@@ -2,108 +2,13 @@
ngIRCd - Next Generation IRC Server
http://ngircd.barton.de/
(c)2001-2014 Alexander Barton and Contributors.
(c)2001-2013 Alexander Barton and Contributors.
ngIRCd is free software and published under the
terms of the GNU General Public License.
-- NEWS --
ngIRCd 21.1 (2014-03-25)
- Don't ignore but use the server password when PAM is compiled in but
disabled. Thanks to Roy Sindre Norangshol <roy.sindre@norangshol.no>!
- doc/Platforms.txt: Update from master branch.
- doc/Services.txt: Update information for Anope 2.x.
- configure: add support for the LDFLAGS_END and LIBS_END variables to add
linker flags and libraries at the end of the configure run (CFLAGS_END has
been implemented already).
- Update Copyright notices for 2014 :-)
ngIRCd 21 (2013-10-30)
- Call arc4random_stir() in forked subprocesses, when available. This
is required by FreeBSD <10 and current NetBSD at least to correctly
initialize the "arc4" random number generator on these platforms.
ngIRCd 21~rc2 (2013-10-20)
- Report the correct configuration file name on configuration errors,
support longer configuration lines, and warn when lines are truncated.
ngIRCd 21~rc1 (2013-10-05)
- Actually KILL clients on GLINE/KLINE. (Closes bug #156)
- Add support to show all user links using the "STATS L" (uppercase)
command (restricted to IRC Operators).
- Implement configurable SSL cipher list selection for GnuTLS and OpenSSL
using the new configuration option "CipherList". In addition, this
changes the defaults to more secure values: "HIGH:!aNULL:@STRENGTH" for
OpenSSL, and "SECURE128" for GnuTLS.
- Show connection flag "s" (SSL) in RPL_TRACE{LINK|SERVER} messages: now
you can check if a server-to-server link is SSL-encrypted or not using
the IRC "TRACE" command.
- Implement the new configuration option "DefaultUserModes" which lists
user modes that become automatically set on new local clients right
after login. Please note that only modes can be set that the client
could set on itself, so you can't set "a" (away) or "o" (IRC Op),
for example! User modes "i" (invisible) or "x" (cloaked) etc. are
"interesting", though. (Closes bug #160)
- Add support for the new METADATA "account" property, which allows
services to automatically identify users after netsplits and across
service restarts.
- Implement a new configuration option "AllowedChannelTypes" that lists
all allowed channel types (channel prefixes) for newly created channels
on the local server. By default, all supported channel types are allowed.
If set to the empty string, local clients can't create new channels at
all, which equals the old "PredefChannelsOnly = yes" setting.
This change deprecates the "PredefChannelsOnly" variable, too, but it is
still supported and translated to the appropriate "AllowedChannelTypes"
setting. When the old "PredefChannelsOnly" variable is processed, a
warning message is logged. (Closes bug #152)
- Add support for "client certificate fingerprinting". When a client
passes an SSL certificate to the server, the "fingerprint" will be
forwarded in the network which enables IRC services to identify the
user using this certificate and not using passwords.
- Implement a new configuration option "IncludeDir" in the "[Options]"
section that can be used to specify a directory which can contain
further configuration files and configuration file snippets matching
the pattern "*.conf". These files are read in after the main server
configuration file ("ngircd.conf" by default) has been read in and
parsed. The default is "$SYSCONFDIR/ngircd.conf.d", so that it is
possible to adjust the configuration only by placing additional files
into this directory. (Closes bug #157)
- Add Travis-CI configuration file (".travis.yml") to project.
- ngIRCd now accepts user names including "@" characters, saves the
unmodified name for authentication but stores only the part in front
of the "@" character as "IRC user name". And the latter is how
ircd2.11, Bahamut, and irc-seven behave as well. (Closes bug #155)
- Lots of IRC "information functions" like ADMIN, INFO, ... now accept
server masks and names of connected users (in addition to server names)
for specifying the target server of the command. (Closes bug #153)
- Implement a new configuration option "IdleTimeout" in the "[Limits]"
section of the configuration file which can be used to set a timeout
in seconds after which the whole daemon will shutdown when no more
connections are left active after handling at least one client.
The default is 0, "never".
This can be useful for testing or when ngIRCd is started using "socket
activation" with systemd(8), for example.
- Implement support for systemd(8) "socket activation".
- Enable WHOIS to display information about IRC Services using the new
numeric 310(RPL_WHOISSERVICE) This numeric is used for this purpose by
InspIRCd, for example -- but as usual, other numerics are in use, too,
like 613 in UltimateIRCd ...
Please note that neither the Operator (+o) not the "bot status" (+B)
of an IRC service is displayed in the output.
- Update systemd(8) example configuration files in ./contrib/ directory:
the "ngircd.service" file now uses the "forking" service type which
enhances the log messages shown by "systemctl status ngircd.service",
and the new "ngircd.socket" file configures a systemd socket that
configures a socket for ngIRCd and launches the daemon on demand.
- Enhance help system and the HELP command: now a "help text file" can be
set using the new configuration option "HelpFile" ("global" section),
which is read in and parsed on server startup and configuration reload,
and then is used to output individual help texts to specific topics.
Please see the file ./doc/Commands.txt for details.
ngIRCd 20.3 (2013-08-23)
- This release is a bugfix release only, without new features.
@@ -127,7 +32,7 @@ ngIRCd 20 (2012-12-17)
- Allow user names ("INDENT") up to 20 characters when ngIRCd has not
been configured for "strict RFC mode". This is useful if you are using
external (PAM) authentication mechanisms that require longer user names.
external (PAM) authenticaion mechanisms that require longer user names.
Patch suggested by Brett Smith <brett@w3.org>, see
<http://arthur.barton.de/pipermail/ngircd-ml/2012-October/000579.html>.

2
README
View File

@@ -2,7 +2,7 @@
ngIRCd - Next Generation IRC Server
http://ngircd.barton.de/
(c)2001-2014 Alexander Barton and Contributors.
(c)2001-2013 Alexander Barton and Contributors.
ngIRCd is free software and published under the
terms of the GNU General Public License.

View File

@@ -1,7 +1,7 @@
#!/bin/sh
#
# ngIRCd -- The Next Generation IRC Daemon
# Copyright (c)2001-2013 Alexander Barton (alex@barton.de) and Contributors
# Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors
#
# 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
@@ -73,12 +73,8 @@ Search()
for name in $searchlist; do
$EXIST "${name}" >/dev/null 2>&1
if [ $? -eq 0 ]; then
"${name}" --version 2>&1 \
| grep -v "environment variable" >/dev/null 2>&1
if [ $? -eq 0 ]; then
echo "${name}"
return 0
fi
echo "${name}"
return 0
fi
done
@@ -148,15 +144,6 @@ echo "Searching for required tools ..."
[ -z "$AUTOCONF" ] && AUTOCONF=`Search autoconf 2`
[ "$VERBOSE" = "1" ] && echo " - AUTOCONF=$AUTOCONF"
AUTOCONF_VERSION=`echo $AUTOCONF | cut -d'-' -f2-`
[ -n "$AUTOCONF_VERSION" -a "$AUTOCONF_VERSION" != "autoconf" ] \
&& export AUTOCONF_VERSION || unset AUTOCONF_VERSION
[ "$VERBOSE" = "1" ] && echo " - AUTOCONF_VERSION=$AUTOCONF_VERSION"
AUTOMAKE_VERSION=`echo $AUTOMAKE | cut -d'-' -f2-`
[ -n "$AUTOMAKE_VERSION" -a "$AUTOMAKE_VERSION" != "automake" ] \
&& export AUTOMAKE_VERSION || unset AUTOMAKE_VERSION
[ "$VERBOSE" = "1" ] && echo " - AUTOMAKE_VERSION=$AUTOMAKE_VERSION"
[ $# -gt 0 ] && CONFIGURE_ARGS=" $@" || CONFIGURE_ARGS=""
[ -z "$GO" -a -n "$CONFIGURE_ARGS" ] && GO=1
@@ -169,23 +156,21 @@ AUTOMAKE_VERSION=`echo $AUTOMAKE | cut -d'-' -f2-`
AM_VERSION=`$AUTOMAKE --version | head -n 1 | sed -e 's/.* //g'`
ifs=$IFS; IFS="."; set $AM_VERSION; IFS=$ifs
AM_MAJOR="$1"; AM_MINOR="$2"; AM_PATCHLEVEL="$3"
echo "Detected automake $AM_VERSION ..."
AM_MAKEFILES="src/ipaddr/Makefile.ng src/ngircd/Makefile.ng src/testsuite/Makefile.ng src/tool/Makefile.ng"
# De-ANSI-fication?
if [ "$AM_MAJOR" -eq "1" -a "$AM_MINOR" -lt "12" ]; then
# automake < 1.12 => automatic de-ANSI-fication support available
echo " - Enabling de-ANSI-fication support."
echo "Enabling de-ANSI-fication support (automake $AM_VERSION) ..."
sed -e "s|^__ng_PROTOTYPES__|AM_C_PROTOTYPES|g" configure.ng >configure.ac
DEANSI_START=""
DEANSI_END=""
else
# automake >= 1.12 => no de-ANSI-fication support available
echo " - Disabling de-ANSI-fication support."
echo "Disabling de-ANSI-fication support (automake $AM_VERSION) ..."
sed -e "s|^__ng_PROTOTYPES__|AC_C_PROTOTYPES|g" configure.ng >configure.ac
DEANSI_START="#"
DEANSI_END=" (disabled by ./autogen.sh script)"
DEANSI_END=" # disabled by ./autogen.sh script"
fi
# Serial test harness?
if [ "$AM_MAJOR" -eq "1" -a "$AM_MINOR" -ge "13" ]; then
@@ -208,7 +193,7 @@ done
export ACLOCAL AUTOHEADER AUTOMAKE AUTOCONF
# Generate files
echo "Generating files using \"$AUTOCONF\" and \"$AUTOMAKE\" ..."
echo "Generating files using GNU $AUTOCONF and $AUTOMAKE ..."
Run $ACLOCAL && \
Run $AUTOCONF && \
Run $AUTOHEADER && \

View File

@@ -1,6 +1,6 @@
#
# ngIRCd -- The Next Generation IRC Daemon
# Copyright (c)2001-2013 Alexander Barton (alex@barton.de) and Contributors
# Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors
#
# 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
@@ -67,7 +67,6 @@ AC_PROG_AWK
AC_PROG_INSTALL
AC_PROG_LN_S
AC_PROG_MAKE_SET
AC_PROG_MKDIR_P
AC_PROG_RANLIB
# -- Compiler Features --
@@ -93,35 +92,6 @@ AC_DEFUN([GCC_STACK_PROTECT_CC],[
fi
])
AC_DEFUN([WORKING_GETADDRINFO],[
AC_CHECK_FUNCS([getaddrinfo],[
AC_MSG_CHECKING([whether getaddrinfo() works])
AC_TRY_RUN([
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
int
main(int argc, char **argv)
{
struct addrinfo hints, *ai;
memset(&hints, 0, sizeof(hints));
hints.ai_flags = AI_PASSIVE;
hints.ai_socktype = SOCK_STREAM;
hints.ai_family = PF_UNSPEC;
if(getaddrinfo(NULL, "0", &hints, &ai) != 0)
return 1;
return 0;
}
],[
AC_DEFINE([HAVE_WORKING_GETADDRINFO], 1, [getaddrinfo(0)])
AC_MSG_RESULT(yes)
],[
AC_MSG_RESULT(no)
])
])
])
if test "$GCC" = "yes"; then
# We are using the GNU C compiler. Good!
CFLAGS="$CFLAGS -pipe -W -Wall -Wpointer-arith -Wstrict-prototypes"
@@ -140,7 +110,7 @@ esac
# Add additional CFLAGS, eventually specified on the command line:
test -n "$CFLAGS_ADD" && CFLAGS="$CFLAGS $CFLAGS_ADD"
CFLAGS="$CFLAGS -DSYSCONFDIR='\"\$(sysconfdir)\"' -DDOCDIR='\"\$(docdir)\"'"
CFLAGS="$CFLAGS -DSYSCONFDIR='\"\$(sysconfdir)\"'"
# -- Headers --
@@ -216,12 +186,9 @@ AC_CHECK_FUNCS([ \
AC_MSG_ERROR([required function missing!]))
# Optional functions
AC_CHECK_FUNCS_ONCE([
arc4random arc4random_stir gai_strerror getnameinfo inet_aton \
sigaction sigprocmask snprintf vsnprintf strdup strndup strlcpy strlcat \
strtok_r unsetenv waitpid])
WORKING_GETADDRINFO
AC_CHECK_FUNCS_ONCE([ \
gai_strerror getaddrinfo getnameinfo inet_aton sigaction sigprocmask \
snprintf vsnprintf strdup strlcpy strlcat strtok_r waitpid])
# -- Configuration options --
@@ -464,12 +431,8 @@ AC_ARG_WITH(tcp-wrappers,
LDFLAGS="-L$withval/lib $LDFLAGS"
fi
AC_MSG_CHECKING(for hosts_access)
saved_LIBS="$LIBS"
LIBS="-lwrap $LIBS"
LIBS_END="-lwrap $LIBS_END"
AC_TRY_LINK([
#include <sys/types.h>
#include <sys/socket.h>
#include <tcpd.h>
int allow_severity = 0;
int deny_severity = 0;
@@ -483,7 +446,6 @@ int deny_severity = 0;
AC_MSG_RESULT(no)
AC_MSG_ERROR([Can't enable TCP wrappers!])
])
LIBS="$saved_LIBS"
fi
]
)
@@ -556,8 +518,7 @@ if test "$x_ircplus_on" = "yes"; then
# CHARCONV is the only function depending on it.
x_iconv_on=no
AC_ARG_WITH(iconv,
AS_HELP_STRING([--with-iconv],
[enable character conversion using libiconv]),
[ --with-iconv enable character conversation using libiconv],
[ if test "$withval" != "no"; then
if test "$withval" != "yes"; then
CFLAGS="-I$withval/include $CFLAGS"
@@ -565,15 +526,11 @@ if test "$x_ircplus_on" = "yes"; then
LDFLAGS="-L$withval/lib $LDFLAGS"
fi
AC_CHECK_LIB(iconv, iconv_open)
AC_CHECK_FUNCS(iconv_open, x_iconv_on=yes)
if test "$x_iconv_on" != "yes"; then
AC_CHECK_LIB(iconv, libiconv_open)
AC_CHECK_FUNCS(libiconv_open, x_iconv_on=yes)
fi
if test "$x_iconv_on" != "yes"; then
AC_CHECK_FUNCS(iconv_open, x_iconv_on=yes,
AC_MSG_ERROR([Can't enable libiconv support!])
fi
fi ]
)
fi
]
)
if test "$x_iconv_on" = "yes"; then
AC_DEFINE(ICONV, 1)
@@ -639,12 +596,9 @@ AC_DEFINE_UNQUOTED(HOST_CPU, "$host_cpu" )
AC_DEFINE_UNQUOTED(HOST_VENDOR, "$host_vendor" )
AC_DEFINE_UNQUOTED(HOST_OS, "$host_os" )
# Add additional CFLAGS, LDFLAGS and LIBS which were specified on the command
# line or by some tests from above, but after running this script. Useful for
# adding "-Werror", for example:
# Add additional CFLAGS, eventually specified on the command line, but after
# running this configure script. Useful for "-Werror" for example.
test -n "$CFLAGS_END" && CFLAGS="$CFLAGS $CFLAGS_END"
test -n "$LDFLAGS_END" && LDFLAGS="$LDFLAGS $LDFLAGS_END"
test -n "$LIBS_END" && LIBS="$LIBS $LIBS_END"
# -- Generate files --
@@ -673,9 +627,7 @@ if test $? -eq 0; then
# Generate debian/ link if the dpkg command exists
# (read: if we are running on a debian compatible system)
echo "creating Debian-specific links ..."
if test ! -f debian/rules -a -f contrib/Debian/rules; then
ln -s contrib/Debian debian
fi
test -f debian/rules || ln -s contrib/Debian debian
fi
# -- Result --
@@ -745,7 +697,7 @@ test "$x_ipv6_on" = "yes" \
&& echo $ECHO_N "yes $ECHO_C" \
|| echo $ECHO_N "no $ECHO_C"
echo $ECHO_N " I/O backend: $ECHO_C"
echo "$x_io_backend"
echo "\"$x_io_backend\""
echo $ECHO_N " PAM support: $ECHO_C"
test "$x_pam_on" = "yes" \

View File

@@ -1,48 +1,3 @@
ngircd (21.1-0ab2) unstable; urgency=low
* Use correct package name in pathname to "HelpFile" (Command.txt)
in "ngircd-full" and "ngircd-full-dbg" packages.
* Don't adjust path names that are correct by default.
-- Alexander Barton <alex@barton.de> Mon, 14 Jul 2014 11:20:17 +0200
ngircd (21.1-0ab1) unstable; urgency=low
* New "upstream" release: ngIRCd 21.1.
-- Alexander Barton <alex@barton.de> Tue, 25 Mar 2014 14:44:59 +0100
ngircd (21-0ab1) unstable; urgency=low
* New "upstream" release: ngIRCd 21.
-- Alexander Barton <alex@barton.de> Wed, 30 Oct 2013 22:13:55 +0100
ngircd (21~rc2-0ab3) unstable; urgency=low
* Fix sed(1) rules adjusting "ngircd-full" package, error introduced
by last commit :-/
-- Alexander Barton <alex@barton.de> Sun, 20 Oct 2013 18:31:16 +0200
ngircd (21~rc2-0ab2) unstable; urgency=low
* Fix default "HelpFile" file name in ngircd.conf for "full" packages.
-- Alexander Barton <alex@barton.de> Sun, 20 Oct 2013 17:18:28 +0200
ngircd (21~rc2-0ab1) unstable; urgency=low
* New "upstream" release candidate 2 for ngIRCd Release 21.
-- Alexander Barton <alex@barton.de> Sun, 20 Oct 2013 15:50:03 +0200
ngircd (21~rc1-0ab1) unstable; urgency=low
* New "upstream" release candidate 1 for ngIRCd Release 21.
-- Alexander Barton <alex@barton.de> Sat, 05 Oct 2013 23:24:09 +0200
ngircd (20.3-0ab1) unstable; urgency=high
* New "upstream" release, fixing a security related bug: ngIRCd 20.3.

View File

@@ -1,6 +1,8 @@
#
# Defaults for ngIRCd start and stop script
#
# $Id: ngircd.default,v 1.1 2003/12/31 17:20:11 alex Exp $
#
# Parameters to pass to the ngircd daemon on startup, see ngircd(8) for
# possible options (default: empty).

View File

@@ -1,7 +1,7 @@
#!/bin/sh
#
# ngIRCd start and stop script for Debian-based systems
# Copyright 2008-2013 Alexander Barton <alex@barton.de>
# Copyright 2008-2010 Alexander Barton <alex@barton.de>
#
### BEGIN INIT INFO
@@ -24,13 +24,13 @@ PARAMS=""
STARTTIME=1
DIETIME=10
test -x $DAEMON || exit 5
test -h "$0" && me=`readlink $0` || me="$0"
BASENAME=`basename $me`
test -r /etc/default/$BASENAME && . /etc/default/$BASENAME
test -x $DAEMON || exit 5
# LSB compatibility functions that become used if there is no local
# include file available.
log_daemon_msg() {
@@ -84,7 +84,6 @@ Do_Start() {
log_warning_msg "$NAME seems to be already running, nothing to do."
exit 0
fi
rm -f "$PIDFILE"
start-stop-daemon --start \
--quiet --exec $DAEMON -- $PARAMS
sleep $STARTTIME

View File

@@ -1,7 +1,7 @@
#!/usr/bin/make -f
#
# ngIRCd -- The Next Generation IRC Daemon
# Copyright (c)2001-2014 Alexander Barton (alex@barton.de) and Contributors
# Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors
#
# 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
@@ -42,7 +42,6 @@ configure-ngircd: configure
--prefix=/usr \
--sysconfdir=/etc/ngircd \
--mandir=\$${prefix}/share/man \
--docdir=\$${prefix}/share/doc/ngircd \
--with-syslog --with-zlib
configure-ngircd-full: configure
@@ -53,7 +52,6 @@ configure-ngircd-full: configure
--prefix=/usr \
--sysconfdir=/etc/ngircd \
--mandir=\$${prefix}/share/man \
--docdir=\$${prefix}/share/doc/ngircd-full \
--with-syslog --with-zlib \
--with-gnutls --with-iconv --with-ident --with-tcp-wrappers \
--with-pam \
@@ -67,7 +65,6 @@ configure-ngircd-full-dbg: configure
--prefix=/usr \
--sysconfdir=/etc/ngircd \
--mandir=\$${prefix}/share/man \
--docdir=\$${prefix}/share/doc/ngircd-full-dbg \
--enable-debug --enable-sniffer \
--with-syslog --with-zlib \
--with-gnutls --with-iconv --with-ident --with-tcp-wrappers \
@@ -142,9 +139,10 @@ install-ngircd: build-ngircd
rm $(CURDIR)/debian/ngircd/usr/share/doc/ngircd/COPYING*
mkdir -p $(CURDIR)/debian/ngircd/var/run/ircd
cat $(CURDIR)/debian/ngircd/usr/share/doc/ngircd/sample-ngircd.conf | \
sed -e "s|;ServerUID = 65534|ServerUID = irc|g" | \
sed -e "s|;ServerGID = 65534|ServerGID = irc|g" | \
sed -e "s|;PidFile = /var/run/ngircd/ngircd.pid|PidFile = /var/run/ircd/ngircd.pid|g" \
sed -e "s/;ServerUID = 65534/ServerUID = irc/g" | \
sed -e "s/;ServerGID = 65534/ServerGID = irc/g" | \
sed -e "s/;MotdFile = \/usr\/local\/etc\/ngircd.motd/MotdFile = \/etc\/ngircd\/ngircd.motd/g" | \
sed -e "s/;PidFile = \/var\/run\/ngircd\/ngircd.pid/PidFile = \/var\/run\/ircd\/ngircd.pid/g" \
>$(CURDIR)/debian/ngircd/etc/ngircd/ngircd.conf
touch $(CURDIR)/debian/ngircd/etc/ngircd/ngircd.motd
@@ -155,13 +153,16 @@ install-ngircd-full: build-ngircd-full
# Add here commands to install the "full" package into debian/ngircd-full:
$(MAKE) install DESTDIR=$(CURDIR)/debian/ngircd-full
rm $(CURDIR)/debian/ngircd-full/usr/share/doc/ngircd-full/INSTALL*
rm $(CURDIR)/debian/ngircd-full/usr/share/doc/ngircd-full/COPYING*
rm $(CURDIR)/debian/ngircd-full/usr/share/doc/ngircd/INSTALL*
rm $(CURDIR)/debian/ngircd-full/usr/share/doc/ngircd/COPYING*
mv $(CURDIR)/debian/ngircd-full/usr/share/doc/ngircd \
$(CURDIR)/debian/ngircd-full/usr/share/doc/ngircd-full
mkdir -p $(CURDIR)/debian/ngircd-full/var/run/ircd
cat $(CURDIR)/debian/ngircd-full/usr/share/doc/ngircd-full/sample-ngircd.conf | \
sed -e "s|;ServerUID = 65534|ServerUID = irc|g" | \
sed -e "s|;ServerGID = 65534|ServerGID = irc|g" | \
sed -e "s|;PidFile = /var/run/ngircd/ngircd.pid|PidFile = /var/run/ircd/ngircd.pid|g" \
sed -e "s/;ServerUID = 65534/ServerUID = irc/g" | \
sed -e "s/;ServerGID = 65534/ServerGID = irc/g" | \
sed -e "s/;MotdFile = \/usr\/local\/etc\/ngircd.motd/MotdFile = \/etc\/ngircd\/ngircd.motd/g" | \
sed -e "s/;PidFile = \/var\/run\/ngircd\/ngircd.pid/PidFile = \/var\/run\/ircd\/ngircd.pid/g" \
>$(CURDIR)/debian/ngircd-full/etc/ngircd/ngircd.conf
touch $(CURDIR)/debian/ngircd-full/etc/ngircd/ngircd.motd
mkdir -p $(CURDIR)/debian/ngircd-full/etc/pam.d
@@ -174,13 +175,16 @@ install-ngircd-full-dbg: build-ngircd-full-dbg
# Add here commands to install the "full" package into debian/ngircd-full:
$(MAKE) install DESTDIR=$(CURDIR)/debian/ngircd-full-dbg
rm $(CURDIR)/debian/ngircd-full-dbg/usr/share/doc/ngircd-full-dbg/INSTALL*
rm $(CURDIR)/debian/ngircd-full-dbg/usr/share/doc/ngircd-full-dbg/COPYING*
rm $(CURDIR)/debian/ngircd-full-dbg/usr/share/doc/ngircd/INSTALL*
rm $(CURDIR)/debian/ngircd-full-dbg/usr/share/doc/ngircd/COPYING*
mv $(CURDIR)/debian/ngircd-full-dbg/usr/share/doc/ngircd \
$(CURDIR)/debian/ngircd-full-dbg/usr/share/doc/ngircd-full-dbg
mkdir -p $(CURDIR)/debian/ngircd-full-dbg/var/run/ircd
cat $(CURDIR)/debian/ngircd-full-dbg/usr/share/doc/ngircd-full-dbg/sample-ngircd.conf | \
sed -e "s|;ServerUID = 65534|ServerUID = irc|g" | \
sed -e "s|;ServerGID = 65534|ServerGID = irc|g" | \
sed -e "s|;PidFile = /var/run/ngircd/ngircd.pid|PidFile = /var/run/ircd/ngircd.pid|g" \
sed -e "s/;ServerUID = 65534/ServerUID = irc/g" | \
sed -e "s/;ServerGID = 65534/ServerGID = irc/g" | \
sed -e "s/;MotdFile = \/usr\/local\/etc\/ngircd.motd/MotdFile = \/etc\/ngircd\/ngircd.motd/g" | \
sed -e "s/;PidFile = \/var\/run\/ngircd\/ngircd.pid/PidFile = \/var\/run\/ircd\/ngircd.pid/g" \
>$(CURDIR)/debian/ngircd-full-dbg/etc/ngircd/ngircd.conf
touch $(CURDIR)/debian/ngircd-full-dbg/etc/ngircd/ngircd.motd
mkdir -p $(CURDIR)/debian/ngircd-full-dbg/etc/pam.d
@@ -212,7 +216,7 @@ binary-arch: build install
dh_installdocs -a
dh_installinit -a
dh_strip -a --no-package=ngircd-full-dbg
dh_compress -a -XCommands.txt
dh_compress -a
dh_fixperms -a
dh_installdeb -a
dh_shlibdeps -a

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2013 Alexander Barton (alex@barton.de) and Contributors.
* Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
*
* 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
@@ -12,21 +12,16 @@
*/
#define PACKAGE_NAME "ngIRCd"
# define PACKAGE "ngircd"
#define PACKAGE "ngircd"
#ifndef VERSION
# define VERSION "??("__DATE__")"
#define VERSION "??("__DATE__")"
#endif
#ifndef HOST_VENDOR
# define HOST_VENDOR "apple"
# define HOST_OS "darwin"
# ifdef __x86_64
# define HOST_CPU "x86_64"
# endif
#endif
#define SYSCONFDIR "/etc/ngircd"
#define DOCDIR "/usr/share/doc/ngircd"
#ifndef TARGET_VENDOR
#define TARGET_VENDOR "apple"
#define TARGET_OS "darwin"
#endif
/* -- Build options -- */
@@ -105,8 +100,6 @@
#define HAVE_INET_ATON 1
/* Define to 1 if you have the `getaddrinfo' function. */
#define HAVE_GETADDRINFO 1
/* getaddrinfo(0) */
#define HAVE_WORKING_GETADDRINFO 1
/* Define to 1 if you have the `getnameinfo' function. */
#define HAVE_GETNAMEINFO 1
/* Define to 1 if you have the `sigaction' function. */

View File

@@ -1 +1 @@
<pkg-contents spec="1.12"><f n="ngircd.dest" o="root" g="admin" p="16877" pt="../../ngircd.dest" m="false" t="file"><f n="opt" o="root" g="admin" p="16877"><f n="ngircd" o="root" g="admin" p="16877"><f n="etc" o="root" g="admin" p="16877"><f n="ngircd.motd" o="root" g="admin" p="33188"><mod>group</mod><mod>owner</mod></f><mod>group</mod><mod>owner</mod></f><f n="sbin" o="root" g="admin" p="16877"><f n="ngircd" o="root" g="admin" p="33261"><mod>group</mod><mod>owner</mod></f><mod>group</mod><mod>owner</mod></f><f n="share" o="root" g="admin" p="16877"><f n="doc" o="root" g="admin" p="16877"><f n="ngircd" o="root" g="admin" p="16877"><f n="AUTHORS" o="root" g="admin" p="33188"><mod>group</mod><mod>owner</mod></f><f n="Bopm.txt" o="root" g="admin" p="33188"><mod>group</mod><mod>owner</mod></f><f n="ChangeLog" o="root" g="admin" p="33188"><mod>group</mod><mod>owner</mod></f><f n="COPYING" o="root" g="admin" p="33188"><mod>group</mod><mod>owner</mod></f><f n="FAQ.txt" o="root" g="admin" p="33188"><mod>group</mod><mod>owner</mod></f><f n="GIT.txt" o="root" g="admin" p="33188"><mod>group</mod><mod>owner</mod></f><f n="HowToRelease.txt" o="root" g="admin" p="33188"><mod>group</mod><mod>owner</mod></f><f n="INSTALL" o="root" g="admin" p="33188"><mod>group</mod><mod>owner</mod></f><f n="NEWS" o="root" g="admin" p="33188"><mod>group</mod><mod>owner</mod></f><f n="PAM.txt" o="root" g="admin" p="33188"><mod>group</mod><mod>owner</mod></f><f n="Platforms.txt" o="root" g="admin" p="33188"><mod>group</mod><mod>owner</mod></f><f n="Protocol.txt" o="root" g="admin" p="33188"><mod>group</mod><mod>owner</mod></f><f n="README" o="root" g="admin" p="33188"><mod>group</mod><mod>owner</mod></f><f n="README-AUX.txt" o="root" g="admin" p="33188"><mod>group</mod><mod>owner</mod></f><f n="README-BeOS.txt" o="root" g="admin" p="33188"><mod>group</mod><mod>owner</mod></f><f n="README-Interix.txt" o="root" g="admin" p="33188"><mod>group</mod><mod>owner</mod></f><f n="RFC.txt" o="root" g="admin" p="33188"><mod>group</mod><mod>owner</mod></f><f n="sample-ngircd.conf" o="root" g="admin" p="33188"><mod>group</mod><mod>owner</mod></f><f n="Services.txt" o="root" g="admin" p="33188"><mod>group</mod><mod>owner</mod></f><f n="SSL.txt" o="root" g="admin" p="33188"><mod>group</mod><mod>owner</mod></f><mod>group</mod><mod>owner</mod></f><mod>group</mod><mod>owner</mod></f><f n="man" o="root" g="admin" p="16877"><f n="man5" o="root" g="admin" p="16877"><f n="ngircd.conf.5" o="root" g="admin" p="33188"><mod>group</mod><mod>owner</mod></f><mod>group</mod><mod>owner</mod></f><f n="man8" o="root" g="admin" p="16877"><f n="ngircd.8" o="root" g="admin" p="33188"><mod>group</mod><mod>owner</mod></f><mod>group</mod><mod>owner</mod></f><mod>group</mod><mod>owner</mod></f><mod>group</mod><mod>owner</mod></f><mod>group</mod><mod>owner</mod></f><mod>group</mod><mod>owner</mod></f><mod>group</mod><mod>owner</mod></f></pkg-contents>
<pkg-contents spec="1.12"><f n="ngircd.dest" o="root" g="admin" p="16877" pt="/Users/alex/Develop/ngircd/alex.git/ngircd.dest" m="false" t="file"><f n="opt" o="root" g="admin" p="16877"><f n="ngircd" o="root" g="admin" p="16877"><f n="etc" o="root" g="admin" p="16877"><f n="ngircd.motd" o="root" g="admin" p="33188"><mod>group</mod><mod>owner</mod></f><mod>group</mod><mod>owner</mod></f><f n="sbin" o="root" g="admin" p="16877"><f n="ngircd" o="root" g="admin" p="33261"><mod>group</mod><mod>owner</mod></f><mod>group</mod><mod>owner</mod></f><f n="share" o="root" g="admin" p="16877"><f n="doc" o="root" g="admin" p="16877"><f n="ngircd" o="root" g="admin" p="16877"><f n="AUTHORS" o="root" g="admin" p="33188"><mod>group</mod><mod>owner</mod></f><f n="Bopm.txt" o="root" g="admin" p="33188"><mod>group</mod><mod>owner</mod></f><f n="ChangeLog" o="root" g="admin" p="33188"><mod>group</mod><mod>owner</mod></f><f n="COPYING" o="root" g="admin" p="33188"><mod>group</mod><mod>owner</mod></f><f n="FAQ.txt" o="root" g="admin" p="33188"><mod>group</mod><mod>owner</mod></f><f n="GIT.txt" o="root" g="admin" p="33188"><mod>group</mod><mod>owner</mod></f><f n="HowToRelease.txt" o="root" g="admin" p="33188"><mod>group</mod><mod>owner</mod></f><f n="INSTALL" o="root" g="admin" p="33188"><mod>group</mod><mod>owner</mod></f><f n="NEWS" o="root" g="admin" p="33188"><mod>group</mod><mod>owner</mod></f><f n="PAM.txt" o="root" g="admin" p="33188"><mod>group</mod><mod>owner</mod></f><f n="Platforms.txt" o="root" g="admin" p="33188"><mod>group</mod><mod>owner</mod></f><f n="Protocol.txt" o="root" g="admin" p="33188"><mod>group</mod><mod>owner</mod></f><f n="README" o="root" g="admin" p="33188"><mod>group</mod><mod>owner</mod></f><f n="README-AUX.txt" o="root" g="admin" p="33188"><mod>group</mod><mod>owner</mod></f><f n="README-BeOS.txt" o="root" g="admin" p="33188"><mod>group</mod><mod>owner</mod></f><f n="README-Interix.txt" o="root" g="admin" p="33188"><mod>group</mod><mod>owner</mod></f><f n="RFC.txt" o="root" g="admin" p="33188"><mod>group</mod><mod>owner</mod></f><f n="sample-ngircd.conf" o="root" g="admin" p="33188"><mod>group</mod><mod>owner</mod></f><f n="Services.txt" o="root" g="admin" p="33188"><mod>group</mod><mod>owner</mod></f><f n="SSL.txt" o="root" g="admin" p="33188"><mod>group</mod><mod>owner</mod></f><mod>group</mod><mod>owner</mod></f><mod>group</mod><mod>owner</mod></f><f n="man" o="root" g="admin" p="16877"><f n="man5" o="root" g="admin" p="16877"><f n="ngircd.conf.5" o="root" g="admin" p="33188"><mod>group</mod><mod>owner</mod></f><mod>group</mod><mod>owner</mod></f><f n="man8" o="root" g="admin" p="16877"><f n="ngircd.8" o="root" g="admin" p="33188"><mod>group</mod><mod>owner</mod></f><mod>group</mod><mod>owner</mod></f><mod>group</mod><mod>owner</mod></f><mod>group</mod><mod>owner</mod></f><mod>group</mod><mod>owner</mod></f><mod>group</mod><mod>owner</mod></f><mod>group</mod><mod>owner</mod></f></pkg-contents>

View File

@@ -1 +1 @@
<pkgref spec="1.12" uuid="46208410-4A1B-48C6-97BD-DE284F13F864"><config><identifier>de.barton.ngircd.daemon.pkg</identifier><version>17.1</version><description></description><post-install type="none"/><requireAuthorization/><installFrom>../../ngircd.dest</installFrom><installTo mod="true">/</installTo><flags><followSymbolicLinks/></flags><packageStore type="internal"></packageStore><mod>extraFiles</mod><mod>installTo</mod><mod>installTo.isAbsoluteType</mod><mod>scripts.preinstall.path</mod><mod>identifier</mod><mod>parent</mod><mod>version</mod><mod>installTo.path</mod><mod>scripts.preupgrade.path</mod><mod>requireAuthorization</mod></config><contents><file-list>02ngircd-contents.xml</file-list><filter>/CVS$</filter><filter>/\.svn$</filter><filter>/\.cvsignore$</filter><filter>/\.cvspass$</filter><filter>/\.DS_Store$</filter></contents><extra-files/></pkgref>
<pkgref spec="1.12" uuid="46208410-4A1B-48C6-97BD-DE284F13F864"><config><identifier>de.barton.ngircd.daemon.pkg</identifier><version>17.1</version><description></description><post-install type="none"/><requireAuthorization/><installFrom>/Users/alex/Develop/ngircd/alex.git/ngircd.dest</installFrom><installTo mod="true">/</installTo><flags><followSymbolicLinks/></flags><packageStore type="internal"></packageStore><mod>extraFiles</mod><mod>installTo</mod><mod>installTo.isAbsoluteType</mod><mod>scripts.preinstall.path</mod><mod>identifier</mod><mod>parent</mod><mod>version</mod><mod>installTo.path</mod><mod>scripts.preupgrade.path</mod><mod>requireAuthorization</mod></config><contents><file-list>02ngircd-contents.xml</file-list><filter>/CVS$</filter><filter>/\.svn$</filter><filter>/\.cvsignore$</filter><filter>/\.cvspass$</filter><filter>/\.DS_Store$</filter></contents><extra-files/></pkgref>

View File

@@ -1,11 +1,11 @@
<pkmkdoc spec="1.12"><properties><title>ngIRCd</title><build>../../ngIRCd.mpkg</build><organization>de.barton.ngircd</organization><userSees ui="both"/><min-target os="2"/><domain system="true"/></properties><distribution><versions min-spec="1.000000"/><scripts></scripts></distribution><description>ngIRCd next generation Internet Relay Chat (IRC) server
daemon</description><contents><choice title="ngIRCd daemon" id="choicengircd" tooltip="ngIRCd daemon, documentation and manual pages" description="Binaries, documentation and manual pages of the ngIRCd, the next generation IRC (Internet Relay Chat) daemon. This package will be installed into /opt/ngircd." starts_selected="true" starts_enabled="true" starts_hidden="false"><pkgref id="de.barton.ngircd.daemon.pkg"/></choice><choice title="Start and stop script" id="choicelaunchscript" tooltip="LaunchDaemon start and stop script" description="Installs the ngIRCd start and stop script for the &quot;launch daemon&quot;. If this is an update/upgrade, and ngIRCd is already running, it will be automatically restarted." starts_selected="true" starts_enabled="true" starts_hidden="false"><pkgref id="de.barton.ngircd.launchscript.pkg"/></choice></contents><resources bg-scale="none" bg-align="bottomleft"><locale lang="en"><resource type="background">../ngIRCd-Logo.gif</resource><resource mime-type="text/rtf" kind="embedded" type="license"><![CDATA[{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf350
<pkmkdoc spec="1.12"><properties><title>ngIRCd</title><build>/Users/alex/Desktop/ngIRCd.mpkg</build><organization>de.barton.ngircd</organization><userSees ui="both"/><min-target os="2"/><domain system="true"/></properties><distribution><versions min-spec="1.000000"/><scripts></scripts></distribution><description>ngIRCd next generation Internet Relay Chat (IRC) server
daemon</description><contents><choice title="ngIRCd daemon" id="choicengircd" tooltip="ngIRCd daemon, documentation and manual pages" description="Binaries, documentation and manual pages of the ngIRCd, the next generation IRC (Internet Relay Chat) daemon. This package will be installed into /opt/ngircd." starts_selected="true" starts_enabled="true" starts_hidden="false"><pkgref id="de.barton.ngircd.daemon.pkg"/></choice><choice title="Start and stop script" id="choicelaunchscript" tooltip="LaunchDaemon start and stop script" description="Installs the ngIRCd start and stop script for the &quot;launch daemon&quot;. If this is an update/upgrade, and ngIRCd is already running, it will be automatically restarted." starts_selected="true" starts_enabled="true" starts_hidden="false"><pkgref id="de.barton.ngircd.launchscript.pkg"/></choice></contents><resources bg-scale="none" bg-align="bottomleft"><locale lang="en"><resource type="background">/Users/alex/Develop/ngircd/alex.git/contrib/ngIRCd-Logo.gif</resource><resource mime-type="text/rtf" kind="embedded" type="license"><![CDATA[{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf350
{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
{\colortbl;\red255\green255\blue255;}
\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\qc\pardirnatural
\f0\i\fs24 \cf0 ngIRCd -- The Next Generation IRC Daemon\
Copyright (c)2001-2014 Alexander Barton and Contributors.\
Copyright (c)2001-2013 Alexander Barton and Contributors.\
\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\ql\qnatural\pardirnatural
\i0 \cf0 \

View File

@@ -64,27 +64,12 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
FA18A63E16CEDDCE00132F66 /* configure.ng */ = {isa = PBXFileReference; lastKnownFileType = text; name = configure.ng; path = ../../configure.ng; sourceTree = "<group>"; };
FA18A63F16CEDE2300132F66 /* ngircd.service */ = {isa = PBXFileReference; lastKnownFileType = text; path = ngircd.service; sourceTree = "<group>"; };
FA18A64016CEDE2300132F66 /* ngircd.socket */ = {isa = PBXFileReference; lastKnownFileType = text; path = ngircd.socket; sourceTree = "<group>"; };
FA18A64116CEDE3500132F66 /* ngircd.pam */ = {isa = PBXFileReference; lastKnownFileType = text; path = ngircd.pam; sourceTree = "<group>"; };
FA18A64216CEDE5700132F66 /* de.barton.ngircd.plist.tmpl */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = de.barton.ngircd.plist.tmpl; sourceTree = "<group>"; };
FA18A64316CEDE8100132F66 /* Makefile.am */ = {isa = PBXFileReference; lastKnownFileType = text; path = Makefile.am; sourceTree = "<group>"; };
FA18A64416CEDFCE00132F66 /* Commands.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = Commands.txt; sourceTree = "<group>"; };
FA18A64516CEE0C700132F66 /* Makefile.ng */ = {isa = PBXFileReference; lastKnownFileType = text; name = Makefile.ng; path = ipaddr/Makefile.ng; sourceTree = "<group>"; };
FA18A64616CEE0DD00132F66 /* Makefile.ng */ = {isa = PBXFileReference; lastKnownFileType = text; path = Makefile.ng; sourceTree = "<group>"; };
FA18A64716CEE14900132F66 /* Makefile.ng */ = {isa = PBXFileReference; lastKnownFileType = text; path = Makefile.ng; sourceTree = "<group>"; };
FA18A64A16CEE18100132F66 /* Makefile.ng */ = {isa = PBXFileReference; lastKnownFileType = text; path = Makefile.ng; sourceTree = "<group>"; };
FA18A64C16CEE1AC00132F66 /* mode-test.e */ = {isa = PBXFileReference; lastKnownFileType = text; path = "mode-test.e"; sourceTree = "<group>"; };
FA18A64D16CEE1D900132F66 /* whois-test.e */ = {isa = PBXFileReference; lastKnownFileType = text; path = "whois-test.e"; sourceTree = "<group>"; };
FA18A64E16CEE24B00132F66 /* misc-test.e */ = {isa = PBXFileReference; lastKnownFileType = text; path = "misc-test.e"; sourceTree = "<group>"; };
FA18A64F16CEE27700132F66 /* Makefile.ng */ = {isa = PBXFileReference; lastKnownFileType = text; path = Makefile.ng; sourceTree = "<group>"; };
FA1A6BBC0D6857BB00AA8F71 /* misc-test.e */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = "misc-test.e"; sourceTree = "<group>"; };
FA1A6BBD0D6857D900AA8F71 /* who-test.e */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = "who-test.e"; sourceTree = "<group>"; };
FA1DBB6716C707D200D4F838 /* irc-macros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "irc-macros.h"; sourceTree = "<group>"; };
FA2D564811EA158B00D37A35 /* pam.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pam.h; sourceTree = "<group>"; };
FA2D564911EA158B00D37A35 /* pam.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pam.c; sourceTree = "<group>"; };
FA2D567A11EA1AB300D37A35 /* libpam.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libpam.dylib; path = usr/lib/libpam.dylib; sourceTree = SDKROOT; };
FA322BBA0CEF72E4001761B3 /* ngIRCd */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; name = ngIRCd; path = ngircd; sourceTree = BUILT_PRODUCTS_DIR; };
FA322BBA0CEF72E4001761B3 /* ngIRCd */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = ngIRCd; sourceTree = BUILT_PRODUCTS_DIR; };
FA322CD60CEF74B1001761B3 /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = Makefile.am; sourceTree = "<group>"; };
FA322CD90CEF74B1001761B3 /* array.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; path = array.c; sourceTree = "<group>"; };
FA322CDA0CEF74B1001761B3 /* array.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = array.h; sourceTree = "<group>"; };
@@ -127,6 +112,7 @@
FA322CFF0CEF74B1001761B3 /* lists.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = lists.h; sourceTree = "<group>"; };
FA322D000CEF74B1001761B3 /* log.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; path = log.c; sourceTree = "<group>"; };
FA322D010CEF74B1001761B3 /* log.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = log.h; sourceTree = "<group>"; };
FA322D020CEF74B1001761B3 /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = Makefile.am; sourceTree = "<group>"; };
FA322D030CEF74B1001761B3 /* match.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; path = match.c; sourceTree = "<group>"; };
FA322D040CEF74B1001761B3 /* match.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = match.h; sourceTree = "<group>"; };
FA322D050CEF74B1001761B3 /* messages.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = messages.h; sourceTree = "<group>"; };
@@ -140,6 +126,7 @@
FA322D110CEF74B1001761B3 /* ansi2knr.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; path = ansi2knr.c; sourceTree = "<group>"; };
FA322D120CEF74B1001761B3 /* exp.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = exp.h; sourceTree = "<group>"; };
FA322D130CEF74B1001761B3 /* imp.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = imp.h; sourceTree = "<group>"; };
FA322D140CEF74B1001761B3 /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = Makefile.am; sourceTree = "<group>"; };
FA322D150CEF74B1001761B3 /* portab.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = portab.h; sourceTree = "<group>"; };
FA322D160CEF74B1001761B3 /* portabtest.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; path = portabtest.c; sourceTree = "<group>"; };
FA322D170CEF74B1001761B3 /* splint.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = splint.h; sourceTree = "<group>"; };
@@ -151,6 +138,8 @@
FA322D1F0CEF74B1001761B3 /* connect-test.e */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = "connect-test.e"; sourceTree = "<group>"; };
FA322D200CEF74B1001761B3 /* functions.inc */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.pascal; path = functions.inc; sourceTree = "<group>"; };
FA322D210CEF74B1001761B3 /* getpid.sh */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.script.sh; path = getpid.sh; sourceTree = "<group>"; };
FA322D220CEF74B1001761B3 /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = Makefile.am; sourceTree = "<group>"; };
FA322D230CEF74B1001761B3 /* mode-test.e */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = "mode-test.e"; sourceTree = "<group>"; };
FA322D250CEF74B1001761B3 /* README */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
FA322D260CEF74B1001761B3 /* start-server.sh */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.script.sh; path = "start-server.sh"; sourceTree = "<group>"; };
FA322D270CEF74B1001761B3 /* stop-server.sh */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.script.sh; path = "stop-server.sh"; sourceTree = "<group>"; };
@@ -160,6 +149,9 @@
FA322D2B0CEF74B1001761B3 /* test-loop.sh */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.script.sh; path = "test-loop.sh"; sourceTree = "<group>"; };
FA322D2C0CEF74B1001761B3 /* tests.sh */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.script.sh; path = tests.sh; sourceTree = "<group>"; };
FA322D2D0CEF74B1001761B3 /* wait-tests.sh */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.script.sh; path = "wait-tests.sh"; sourceTree = "<group>"; };
FA322D300CEF74B1001761B3 /* ansi2knr.1 */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.man; path = ansi2knr.1; sourceTree = "<group>"; };
FA322D310CEF74B1001761B3 /* ansi2knr.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; path = ansi2knr.c; sourceTree = "<group>"; };
FA322D320CEF74B1001761B3 /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = Makefile.am; sourceTree = "<group>"; };
FA322D330CEF74B1001761B3 /* tool.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; path = tool.c; sourceTree = "<group>"; };
FA322D340CEF74B1001761B3 /* tool.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = tool.h; sourceTree = "<group>"; };
FA322D5A0CEF750F001761B3 /* AUTHORS */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; name = AUTHORS; path = ../../AUTHORS; sourceTree = SOURCE_ROOT; };
@@ -167,6 +159,7 @@
FA322D5C0CEF750F001761B3 /* ChangeLog */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; name = ChangeLog; path = ../../ChangeLog; sourceTree = SOURCE_ROOT; };
FA322D5E0CEF750F001761B3 /* config.guess */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.script.sh; name = config.guess; path = ../../config.guess; sourceTree = SOURCE_ROOT; };
FA322D5F0CEF750F001761B3 /* config.sub */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.script.sh; name = config.sub; path = ../../config.sub; sourceTree = SOURCE_ROOT; };
FA322D600CEF750F001761B3 /* configure.in */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; name = configure.in; path = ../../configure.in; sourceTree = SOURCE_ROOT; };
FA322D610CEF750F001761B3 /* COPYING */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; name = COPYING; path = ../../COPYING; sourceTree = SOURCE_ROOT; };
FA322D620CEF750F001761B3 /* INSTALL */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; name = INSTALL; path = ../../INSTALL; sourceTree = SOURCE_ROOT; };
FA322D630CEF750F001761B3 /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; name = Makefile.am; path = ../../Makefile.am; sourceTree = SOURCE_ROOT; };
@@ -181,8 +174,9 @@
FA322D700CEF7523001761B3 /* ngircd.init */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.script.sh; path = ngircd.init; sourceTree = "<group>"; };
FA322D710CEF7523001761B3 /* ngircd.postinst */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.script.sh; path = ngircd.postinst; sourceTree = "<group>"; };
FA322D720CEF7523001761B3 /* rules */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = rules; sourceTree = "<group>"; };
FA322D8D0CEF7523001761B3 /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; name = Makefile.am; path = MacOSX/Makefile.am; sourceTree = "<group>"; };
FA322D8D0CEF7523001761B3 /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = Makefile.am; sourceTree = "<group>"; };
FA322D8E0CEF7523001761B3 /* ngIRCd.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; path = ngIRCd.xcodeproj; sourceTree = "<group>"; };
FA322D910CEF7523001761B3 /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = Makefile.am; sourceTree = "<group>"; };
FA322D920CEF7523001761B3 /* ngindent */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = ngindent; sourceTree = "<group>"; };
FA322D940CEF7523001761B3 /* ngircd.spec */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = ngircd.spec; sourceTree = "<group>"; };
FA322D950CEF7523001761B3 /* README */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
@@ -196,13 +190,16 @@
FA322DA00CEF752C001761B3 /* RFC.txt */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = RFC.txt; sourceTree = "<group>"; };
FA322DA40CEF752C001761B3 /* Doxyfile */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = Doxyfile; sourceTree = "<group>"; };
FA322DA50CEF752C001761B3 /* footer.inc.html */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.html; path = footer.inc.html; sourceTree = "<group>"; };
FA322DA60CEF752C001761B3 /* header.inc.html */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.html; path = header.inc.html; sourceTree = "<group>"; };
FA322DA70CEF752C001761B3 /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = Makefile.am; sourceTree = "<group>"; };
FA322DA80CEF752C001761B3 /* ngircd-doc.css */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.css; path = "ngircd-doc.css"; sourceTree = "<group>"; };
FA322DA90CEF752C001761B3 /* SSL.txt */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = SSL.txt; sourceTree = "<group>"; };
FA322DAD0CEF7538001761B3 /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = Makefile.am; sourceTree = "<group>"; };
FA322DAE0CEF7538001761B3 /* ngircd.8.tmpl */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = ngircd.8.tmpl; sourceTree = "<group>"; };
FA322DAF0CEF7538001761B3 /* ngircd.conf.5.tmpl */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = ngircd.conf.5.tmpl; sourceTree = "<group>"; };
FA322DB10CEF7565001761B3 /* config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = config.h; sourceTree = "<group>"; };
FA322DC00CEF77CB001761B3 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = /usr/lib/libz.dylib; sourceTree = "<absolute>"; };
FA407F2B0DB159F400271AF1 /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; name = Makefile.am; path = ipaddr/Makefile.am; sourceTree = "<group>"; };
FA407F2C0DB159F400271AF1 /* ng_ipaddr.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = ng_ipaddr.c; path = ipaddr/ng_ipaddr.c; sourceTree = "<group>"; };
FA407F2D0DB159F400271AF1 /* ng_ipaddr.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = ng_ipaddr.h; path = ipaddr/ng_ipaddr.h; sourceTree = "<group>"; };
FA407F380DB15AC700271AF1 /* GIT.txt */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = GIT.txt; sourceTree = "<group>"; };
@@ -282,32 +279,28 @@
08FB7794FE84155DC02AAC07 /* ngIRCd */ = {
isa = PBXGroup;
children = (
FA322D630CEF750F001761B3 /* Makefile.am */,
FA322D660CEF7523001761B3 /* contrib */,
FA322D970CEF752C001761B3 /* doc */,
FA322D660CEF7523001761B3 /* contrib */,
FA322DAB0CEF7538001761B3 /* man */,
FA322CD40CEF74B0001761B3 /* src */,
FA322D5A0CEF750F001761B3 /* AUTHORS */,
FA322D5C0CEF750F001761B3 /* ChangeLog */,
FA322D610CEF750F001761B3 /* COPYING */,
FA322D620CEF750F001761B3 /* INSTALL */,
FA322D640CEF750F001761B3 /* NEWS */,
FA322D650CEF750F001761B3 /* README */,
FA322D5B0CEF750F001761B3 /* autogen.sh */,
FA322D5C0CEF750F001761B3 /* ChangeLog */,
FA322D5E0CEF750F001761B3 /* config.guess */,
FA322D5F0CEF750F001761B3 /* config.sub */,
FA18A63E16CEDDCE00132F66 /* configure.ng */,
FA322D600CEF750F001761B3 /* configure.in */,
FA322D630CEF750F001761B3 /* Makefile.am */,
1AB674ADFE9D54B511CA2CBB /* Products */,
FA6BBC651605F6D60004247A /* libiconv.dylib */,
FA2D567A11EA1AB300D37A35 /* libpam.dylib */,
FA322DC00CEF77CB001761B3 /* libz.dylib */,
);
indentWidth = 8;
name = ngIRCd;
sourceTree = "<group>";
tabWidth = 8;
usesTabs = 1;
wrapsLines = 0;
};
1AB674ADFE9D54B511CA2CBB /* Products */ = {
isa = PBXGroup;
@@ -320,12 +313,12 @@
FA322CD40CEF74B0001761B3 /* src */ = {
isa = PBXGroup;
children = (
FA322CD60CEF74B1001761B3 /* Makefile.am */,
FA407F270DB1598D00271AF1 /* ipaddr */,
FA322CD70CEF74B1001761B3 /* ngircd */,
FA407F270DB1598D00271AF1 /* ipaddr */,
FA322D0E0CEF74B1001761B3 /* portab */,
FA322D1B0CEF74B1001761B3 /* testsuite */,
FA322D2E0CEF74B1001761B3 /* tool */,
FA322CD60CEF74B1001761B3 /* Makefile.am */,
);
name = src;
path = ../../src;
@@ -334,7 +327,7 @@
FA322CD70CEF74B1001761B3 /* ngircd */ = {
isa = PBXGroup;
children = (
FA18A64616CEE0DD00132F66 /* Makefile.ng */,
FA322D020CEF74B1001761B3 /* Makefile.am */,
FA322CD90CEF74B1001761B3 /* array.c */,
FA322CDA0CEF74B1001761B3 /* array.h */,
FA322CDB0CEF74B1001761B3 /* channel.c */,
@@ -354,10 +347,10 @@
FA6BBC601605F0AC0004247A /* conn-encoding.h */,
FA322CE10CEF74B1001761B3 /* conn-func.c */,
FA322CE20CEF74B1001761B3 /* conn-func.h */,
FAA3D2790F139CDC00B2447E /* conn-ssl.c */,
FAA3D27A0F139CDC00B2447E /* conn-ssl.h */,
FA322CE30CEF74B1001761B3 /* conn-zip.c */,
FA322CE40CEF74B1001761B3 /* conn-zip.h */,
FAA3D2790F139CDC00B2447E /* conn-ssl.c */,
FAA3D27A0F139CDC00B2447E /* conn-ssl.h */,
FA322CE70CEF74B1001761B3 /* defines.h */,
FA322CE80CEF74B1001761B3 /* hash.c */,
FA322CE90CEF74B1001761B3 /* hash.h */,
@@ -375,7 +368,6 @@
FA322CEF0CEF74B1001761B3 /* irc-info.h */,
FA322CF00CEF74B1001761B3 /* irc-login.c */,
FA322CF10CEF74B1001761B3 /* irc-login.h */,
FA1DBB6716C707D200D4F838 /* irc-macros.h */,
FA4F1659164836B100DBD011 /* irc-metadata.c */,
FA4F165C164836BF00DBD011 /* irc-metadata.h */,
FA322CF20CEF74B1001761B3 /* irc-mode.c */,
@@ -420,19 +412,19 @@
FA322D0E0CEF74B1001761B3 /* portab */ = {
isa = PBXGroup;
children = (
FA18A64716CEE14900132F66 /* Makefile.ng */,
FAA3D27C0F139CF800B2447E /* strtok_r.c */,
FAA3D27D0F139CF800B2447E /* waitpid.c */,
FA322D100CEF74B1001761B3 /* ansi2knr.1 */,
FA322D110CEF74B1001761B3 /* ansi2knr.c */,
FA322D120CEF74B1001761B3 /* exp.h */,
FA322D130CEF74B1001761B3 /* imp.h */,
FA322D140CEF74B1001761B3 /* Makefile.am */,
FA322D150CEF74B1001761B3 /* portab.h */,
FA322D160CEF74B1001761B3 /* portabtest.c */,
FA322D170CEF74B1001761B3 /* splint.h */,
FA322D180CEF74B1001761B3 /* strdup.c */,
FA322D190CEF74B1001761B3 /* strlcpy.c */,
FAA3D27C0F139CF800B2447E /* strtok_r.c */,
FA322D1A0CEF74B1001761B3 /* vsnprintf.c */,
FAA3D27D0F139CF800B2447E /* waitpid.c */,
);
path = portab;
sourceTree = "<group>";
@@ -440,33 +432,32 @@
FA322D1B0CEF74B1001761B3 /* testsuite */ = {
isa = PBXGroup;
children = (
FA18A64A16CEE18100132F66 /* Makefile.ng */,
FA322D250CEF74B1001761B3 /* README */,
FA322D1D0CEF74B1001761B3 /* channel-test.e */,
FA322D1E0CEF74B1001761B3 /* check-idle.e */,
FA322D1F0CEF74B1001761B3 /* connect-test.e */,
FAA3D2700F139CB300B2447E /* invite-test.e */,
FAA3D2710F139CB300B2447E /* join-test.e */,
FAA3D2720F139CB300B2447E /* kick-test.e */,
FAA3D2730F139CB300B2447E /* message-test.e */,
FA18A64E16CEE24B00132F66 /* misc-test.e */,
FA18A64C16CEE1AC00132F66 /* mode-test.e */,
FAA3D2760F139CB300B2447E /* opless-channel-test.e */,
FAA3D2770F139CB300B2447E /* server-link-test.e */,
FA322D280CEF74B1001761B3 /* stress-A.e */,
FA322D290CEF74B1001761B3 /* stress-B.e */,
FA1A6BBD0D6857D900AA8F71 /* who-test.e */,
FA18A64D16CEE1D900132F66 /* whois-test.e */,
FA322D200CEF74B1001761B3 /* functions.inc */,
FAA3D2740F139CB300B2447E /* ngircd-test1.conf */,
FAA3D2750F139CB300B2447E /* ngircd-test2.conf */,
FAA3D2760F139CB300B2447E /* opless-channel-test.e */,
FAA3D2770F139CB300B2447E /* server-link-test.e */,
FA322D1D0CEF74B1001761B3 /* channel-test.e */,
FA322D1E0CEF74B1001761B3 /* check-idle.e */,
FA322D1F0CEF74B1001761B3 /* connect-test.e */,
FA322D200CEF74B1001761B3 /* functions.inc */,
FA322D210CEF74B1001761B3 /* getpid.sh */,
FA322D220CEF74B1001761B3 /* Makefile.am */,
FA1A6BBC0D6857BB00AA8F71 /* misc-test.e */,
FA322D230CEF74B1001761B3 /* mode-test.e */,
FA322D250CEF74B1001761B3 /* README */,
FA322D260CEF74B1001761B3 /* start-server.sh */,
FA322D270CEF74B1001761B3 /* stop-server.sh */,
FA322D280CEF74B1001761B3 /* stress-A.e */,
FA322D290CEF74B1001761B3 /* stress-B.e */,
FA322D2A0CEF74B1001761B3 /* stress-server.sh */,
FA322D2B0CEF74B1001761B3 /* test-loop.sh */,
FA322D2C0CEF74B1001761B3 /* tests.sh */,
FA322D2D0CEF74B1001761B3 /* wait-tests.sh */,
FA1A6BBD0D6857D900AA8F71 /* who-test.e */,
);
path = testsuite;
sourceTree = "<group>";
@@ -474,7 +465,9 @@
FA322D2E0CEF74B1001761B3 /* tool */ = {
isa = PBXGroup;
children = (
FA18A64F16CEE27700132F66 /* Makefile.ng */,
FA322D300CEF74B1001761B3 /* ansi2knr.1 */,
FA322D310CEF74B1001761B3 /* ansi2knr.c */,
FA322D320CEF74B1001761B3 /* Makefile.am */,
FA322D330CEF74B1001761B3 /* tool.c */,
FA322D340CEF74B1001761B3 /* tool.h */,
);
@@ -484,18 +477,16 @@
FA322D660CEF7523001761B3 /* contrib */ = {
isa = PBXGroup;
children = (
FA322D8D0CEF7523001761B3 /* Makefile.am */,
FA322D680CEF7523001761B3 /* Debian */,
FA322D730CEF7523001761B3 /* MacOSX */,
FA322D950CEF7523001761B3 /* README */,
FA322D910CEF7523001761B3 /* Makefile.am */,
FA322D920CEF7523001761B3 /* ngindent */,
FA4B08E513E7F8FB00765BA3 /* ngircd-bsd.sh */,
FA4B08E613E7F91700765BA3 /* ngIRCd-Logo.gif */,
FA4B08E713E7F91700765BA3 /* ngircd-redhat.init */,
FA18A63F16CEDE2300132F66 /* ngircd.service */,
FA18A64016CEDE2300132F66 /* ngircd.socket */,
FA322D940CEF7523001761B3 /* ngircd.spec */,
FA4B08E813E7F91C00765BA3 /* platformtest.sh */,
FA322D950CEF7523001761B3 /* README */,
FA322D960CEF7523001761B3 /* systrace.policy */,
);
name = contrib;
@@ -505,14 +496,13 @@
FA322D680CEF7523001761B3 /* Debian */ = {
isa = PBXGroup;
children = (
FA322D6E0CEF7523001761B3 /* Makefile.am */,
FA322D6A0CEF7523001761B3 /* changelog */,
FA322D6B0CEF7523001761B3 /* compat */,
FA322D6C0CEF7523001761B3 /* control */,
FA322D6D0CEF7523001761B3 /* copyright */,
FA322D6E0CEF7523001761B3 /* Makefile.am */,
FA322D6F0CEF7523001761B3 /* ngircd.default */,
FA322D700CEF7523001761B3 /* ngircd.init */,
FA18A64116CEDE3500132F66 /* ngircd.pam */,
FA322D710CEF7523001761B3 /* ngircd.postinst */,
FA322D720CEF7523001761B3 /* rules */,
);
@@ -522,17 +512,88 @@
FA322D730CEF7523001761B3 /* MacOSX */ = {
isa = PBXGroup;
children = (
FA18A64316CEDE8100132F66 /* Makefile.am */,
FAA3D2810F139D2E00B2447E /* ngIRCd.pmdoc */,
FA322DB10CEF7565001761B3 /* config.h */,
FA18A64216CEDE5700132F66 /* de.barton.ngircd.plist.tmpl */,
FA322D8E0CEF7523001761B3 /* ngIRCd.xcodeproj */,
FAA3D28A0F139D2E00B2447E /* postinstall.sh */,
FAA3D28B0F139D2E00B2447E /* preinstall.sh */,
FA322D750CEF7523001761B3 /* build */,
FA322D8D0CEF7523001761B3 /* Makefile.am */,
FA322D8E0CEF7523001761B3 /* ngIRCd.xcodeproj */,
FA322DB10CEF7565001761B3 /* config.h */,
);
path = MacOSX;
sourceTree = "<group>";
};
FA322D750CEF7523001761B3 /* build */ = {
isa = PBXGroup;
children = (
FA322D760CEF7523001761B3 /* ngIRCd.build */,
);
path = build;
sourceTree = "<group>";
};
FA322D760CEF7523001761B3 /* ngIRCd.build */ = {
isa = PBXGroup;
children = (
FA322D770CEF7523001761B3 /* Default */,
FA322D7F0CEF7523001761B3 /* ngIRCd.pbxindex */,
);
path = ngIRCd.build;
sourceTree = "<group>";
};
FA322D770CEF7523001761B3 /* Default */ = {
isa = PBXGroup;
children = (
FA322D780CEF7523001761B3 /* ngIRCd.build */,
);
path = Default;
sourceTree = "<group>";
};
FA322D780CEF7523001761B3 /* ngIRCd.build */ = {
isa = PBXGroup;
children = (
FA322D7A0CEF7523001761B3 /* Objects-normal */,
);
path = ngIRCd.build;
sourceTree = "<group>";
};
FA322D7A0CEF7523001761B3 /* Objects-normal */ = {
isa = PBXGroup;
children = (
FA322D7B0CEF7523001761B3 /* i386 */,
FA322D7D0CEF7523001761B3 /* ppc */,
);
path = "Objects-normal";
sourceTree = "<group>";
};
FA322D7B0CEF7523001761B3 /* i386 */ = {
isa = PBXGroup;
children = (
);
path = i386;
sourceTree = "<group>";
};
FA322D7D0CEF7523001761B3 /* ppc */ = {
isa = PBXGroup;
children = (
);
path = ppc;
sourceTree = "<group>";
};
FA322D7F0CEF7523001761B3 /* ngIRCd.pbxindex */ = {
isa = PBXGroup;
children = (
FA322D880CEF7523001761B3 /* strings.pbxstrings */,
);
path = ngIRCd.pbxindex;
sourceTree = "<group>";
};
FA322D880CEF7523001761B3 /* strings.pbxstrings */ = {
isa = PBXGroup;
children = (
);
path = strings.pbxstrings;
sourceTree = "<group>";
};
FA322D8F0CEF7523001761B3 /* Products */ = {
isa = PBXGroup;
children = (
@@ -544,10 +605,8 @@
isa = PBXGroup;
children = (
FA322D9B0CEF752C001761B3 /* Makefile.am */,
FA322DA20CEF752C001761B3 /* src */,
FAE22BD215270EA300F1A5AB /* Bopm.txt */,
FAD5852F15271A7800328741 /* Capabilities.txt */,
FA18A64416CEDFCE00132F66 /* Commands.txt */,
FAE22BD415270EA300F1A5AB /* Contributing.txt */,
FA322D9A0CEF752C001761B3 /* FAQ.txt */,
FA407F380DB15AC700271AF1 /* GIT.txt */,
@@ -563,6 +622,7 @@
FAA3D2800F139D1500B2447E /* Services.txt */,
FA322DA90CEF752C001761B3 /* SSL.txt */,
FA77849A133FB9FF00740057 /* sample-ngircd.conf.tmpl */,
FA322DA20CEF752C001761B3 /* src */,
);
name = doc;
path = ../../doc;
@@ -571,9 +631,11 @@
FA322DA20CEF752C001761B3 /* src */ = {
isa = PBXGroup;
children = (
FA322DA70CEF752C001761B3 /* Makefile.am */,
FA322DA40CEF752C001761B3 /* Doxyfile */,
FA322DA50CEF752C001761B3 /* footer.inc.html */,
FA322DA60CEF752C001761B3 /* header.inc.html */,
FA322DA70CEF752C001761B3 /* Makefile.am */,
FA322DA80CEF752C001761B3 /* ngircd-doc.css */,
);
path = src;
sourceTree = "<group>";
@@ -592,7 +654,7 @@
FA407F270DB1598D00271AF1 /* ipaddr */ = {
isa = PBXGroup;
children = (
FA18A64516CEE0C700132F66 /* Makefile.ng */,
FA407F2B0DB159F400271AF1 /* Makefile.am */,
FA407F2C0DB159F400271AF1 /* ng_ipaddr.c */,
FA407F2D0DB159F400271AF1 /* ng_ipaddr.h */,
);
@@ -602,12 +664,12 @@
FAA3D2810F139D2E00B2447E /* ngIRCd.pmdoc */ = {
isa = PBXGroup;
children = (
FAA3D2880F139D2E00B2447E /* Makefile.am */,
FAA3D2860F139D2E00B2447E /* index.xml */,
FAA3D2830F139D2E00B2447E /* 01ngircd.xml */,
FAA3D2820F139D2E00B2447E /* 01ngircd-contents.xml */,
FAA3D2850F139D2E00B2447E /* 02de.xml */,
FAA3D2830F139D2E00B2447E /* 01ngircd.xml */,
FAA3D2840F139D2E00B2447E /* 02de-contents.xml */,
FAA3D2850F139D2E00B2447E /* 02de.xml */,
FAA3D2860F139D2E00B2447E /* index.xml */,
FAA3D2880F139D2E00B2447E /* Makefile.am */,
);
path = ngIRCd.pmdoc;
sourceTree = "<group>";

View File

@@ -1,6 +1,6 @@
#
# ngIRCd -- The Next Generation IRC Daemon
# Copyright (c)2001-2013 Alexander Barton (alex@barton.de) and Contributors
# Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors
#
# 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
@@ -17,7 +17,6 @@ EXTRA_DIST = README \
ngIRCd-Logo.gif \
ngircd-redhat.init \
ngircd.service \
ngircd.socket \
ngircd.spec \
platformtest.sh \
systrace.policy

View File

@@ -2,21 +2,18 @@
ngIRCd - Next Generation IRC Server
http://ngircd.barton.de/
(c)2001-2013 Alexander Barton and Contributors.
(c)2001-2011 Alexander Barton and Contributors.
ngIRCd is free software and published under the
terms of the GNU General Public License.
-- Contributions --
-- Contributions --
Debian/
- Various files for building Debian GNU/Linux packages (".deb's").
- ngircd.init; ngircd.default: init script for Debian-based systems.
- ngircd.pam: example PAM configuraton.
MacOSX/
- Project files for XCode, the "project builder" of Apple Mac OS X.
- de.barton.ngircd.plist[.tmpl]: launchd(8) property list.
ngindent
- Script to indent the code of ngIRCd in the "standard way".
@@ -27,12 +24,6 @@ ngircd-bsd.sh
ngircd-redhat.init
- Start/stop script for RedHat-based distributions (like CentOS).
ngircd.service
- systemd(8) service unit configuration file.
ngircd.socket
- systemd(8) socket unit configuration file for "socket activation".
ngircd.spec
- RPM "spec" file.

View File

@@ -3,8 +3,8 @@ Description=Next Generation IRC Daemon
After=network.target
[Service]
Type=forking
ExecStart=/usr/sbin/ngircd
# don't daemonize to simplify stuff
ExecStart=/usr/sbin/ngircd -n
ExecReload=/bin/kill -HUP $MAINPID
[Install]

View File

@@ -1,11 +0,0 @@
[Unit]
Description=Next Generation IRC Daemon (Socket)
[Socket]
BindIPv6Only=ipv6-only
ListenStream=0.0.0.0:6667
#ListenStream=[::]:6667
IPTOS=low-delay
[Install]
WantedBy=sockets.target

View File

@@ -1,5 +1,5 @@
%define name ngircd
%define version 21.1
%define version 20.3
%define release 1
%define prefix %{_prefix}

View File

@@ -1,7 +1,7 @@
#!/bin/sh
#
# ngIRCd -- The Next Generation IRC Daemon
# Copyright (c)2001-2014 Alexander Barton (alex@barton.de) and Contributors
# Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors
#
# 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
@@ -54,18 +54,8 @@ if [ $? -ne 0 ]; then
cd ..
fi
echo "$NAME: Checking for GIT tree ..."
if [ -d .git ]; then
echo "$NAME: Checking for \"git\" command ..."
git version >/dev/null 2>&1
if [ $? -eq 0 ]; then
echo "$NAME: Running \"git clean\" ..."
[ -n "$VERBOSE" ] && git clean -dxf || git clean -dxf >/dev/null
fi
fi
echo "$NAME: Checking for \"./configure\" script ..."
if [ ! -r ./configure ]; then
if [ ! -e ./configure ]; then
echo "$NAME: Running \"./autogen.sh\" ..."
[ -n "$VERBOSE" ] && ./autogen.sh || ./autogen.sh >/dev/null
fi
@@ -109,7 +99,6 @@ if [ -r "Makefile" ]; then
CC=$(grep "^CC = " Makefile | cut -d' ' -f3)
$CC --version 2>&1 | grep -i "GCC" >/dev/null
if [ $? -eq 0 ]; then
# GCC, or compiler that mimics GCC
$CC --version 2>&1 | grep -i "Open64" >/dev/null
if [ $? -eq 0 ]; then
COMPILER="Open64"
@@ -119,24 +108,12 @@ if [ -r "Makefile" ]; then
COMPILER="gcc $COMPILER"
fi
else
# Non-GCC compiler
$CC --version 2>&1 | grep -i "clang" >/dev/null
if [ $? -eq 0 ]; then
COMPILER=$($CC --version 2>/dev/null | head -1 \
| cut -d'(' -f1 | cut -d'-' -f1 \
| sed -e 's/version //g' | sed -e 's/Apple /A-/g' \
| sed -e 's/Debian //g' | sed -e 's/LLVM /clang /g')
fi
$CC -version 2>&1 | grep -i "tcc" >/dev/null
if [ $? -eq 0 ]; then
COMPILER=$($CC -version 2>/dev/null | head -1 \
| cut -d'(' -f1 | sed -e 's/version //g')
fi
if [ "$COMPILER" = "unknown" ]; then
case "$CC" in
gcc*)
v="`$CC --version 2>/dev/null | head -1`"
[ -z "$v" ] && v="`$CC -version 2>/dev/null | head -1`"
[ -n "$v" ] && COMPILER="$v"
fi
[ -n "$v" ] && COMPILER="gcc $v"
;;
esac
fi
fi
@@ -151,14 +128,14 @@ esac
# Get IO interface information
if [ "$OS" = "linux-gnu" ]; then
COMMENT="1"
COMMENT="(1)"
else
grep "^#define HAVE_SYS_DEVPOLL_H 1" src/config.h >/dev/null 2>&1
[ $? -eq 0 ] && COMMENT="4"
[ $? -eq 0 ] && COMMENT="(4)"
grep "^#define HAVE_EPOLL_CREATE 1" src/config.h >/dev/null 2>&1
[ $? -eq 0 ] && COMMENT="5"
[ $? -eq 0 ] && COMMENT="(5)"
grep "^#define HAVE_KQUEUE 1" src/config.h >/dev/null 2>&1
[ $? -eq 0 ] && COMMENT="3"
[ $? -eq 0 ] && COMMENT="(3)"
fi
[ -n "$R_CONFIGURE" ] && C="Y" || C="N"
@@ -168,16 +145,16 @@ fi
[ -n "$COMMENT" ] && COMMENT=" $COMMENT"
echo
echo " the executable works (\"runs\") as expected --+"
echo " tests run successfully (\"make check\") --+ |"
echo " ngIRCd compiles (\"make\") --+ | |"
echo " ./configure works --+ | | |"
echo " | | | |"
echo "Platform Compiler ngIRCd Date Tester C M T R *"
echo "--------------------------- ------------ ---------- -------- -------- - - - - -"
echo " the executable works (\"runs\") as expected --+"
echo " tests run successfully (\"make check\") --+ |"
echo " ngIRCd compiles (\"make\") --+ | |"
echo " ./configure works --+ | | |"
echo " | | | |"
echo "Platform Compiler ngIRCd Date Tester C M T R See"
echo "--------------------------- ------------ ---------- -------- ------ - - - - ---"
type printf >/dev/null 2>&1
if [ $? -eq 0 ]; then
printf "%-27s %-12s %-10s %s %-8s %s %s %s %s%s" \
printf "%-27s %-12s %-10s %s %-6s %s %s %s %s%s" \
"$PLATFORM" "$COMPILER" "$VERSION" "$DATE" "$USER" \
"$C" "$M" "$T" "$R" "$COMMENT"
else

View File

@@ -1,991 +0,0 @@
ngIRCd - Next Generation IRC Server
http://ngircd.barton.de/
(c)2001-2013 Alexander Barton and Contributors.
ngIRCd is free software and published under the
terms of the GNU General Public License.
-- Commands.txt --
This file lists all commands available on ngIRCd. It is written in a format
that is human readable as well as machine parseable and therefore can be used
as "help text file" of the daemon.
In short, the daemon reads this file on startup and parses it as following
when an user issues a "HELP <cmd>" command:
1. Search the file for a line "- <cmd>",
2. Output all subsequent lines that start with a TAB (ASCII 9) character
to the client using NOTICE commands, treat lines containing a single "."
after the TAB as empty lines.
3. Break at the first line not starting with a TAB character.
This format allows to have information to each command stored in this file
which will not be sent to an IRC user requesting help which enables us to
have additional annotations stored here which further describe the origin,
implementation details, or limits of the specific command which are not
relevant to an end-user but administrators and developers.
A special "Intro" block is returned to the user when the HELP command is
used without a command name:
- Intro
This is ngIRCd, a server software for Internet Relay Chat (IRC)
networks. You can find more information about ngIRCd on its homepage:
<http://ngircd.barton.de>
.
Use "HELP COMMANDS" to get a list of all available commands and
"HELP <command-name>" to get help for a specific IRC command, for
example "HELP quit" or "HELP privmsg".
Connection Handling Commands
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- CAP
CAP LS
CAP LIST
CAP REQ <capabilities>
CAP ACK <capabilities>
CAP NAK <capabilities>
CAP CLEAR
CAP END
.
List, request, and clear "IRC Capabilities".
.
Using this command, an IRC client can request additional "IRC
capabilities" during login or later on, which influences the
communication between server and client. Normally, these commands
aren't directly used by humans, but automatically by their client
software. And please note that issuing such commands manually can
irritate the client software used, because of the "non-standard"
behavior of the server!
.
- CAP LS: list all available capabilities.
- CAP LIST: list active capabilities of this connection.
- CAP REQ: Request particular capabilities.
- CAP ACK: Acknowledge a set of capabilities to be enabled/disabled.
- CAP NAK: Reject a set of capabilities.
- CAP CLEAR: Clear all set capabilities.
- CAP END: Indicate end of capability negotiation during login,
ignored in an fully registered session.
Please note that the <capabilities> must be given in a single
parameter but whitespace separated, therefore a command could look
like this: "CAP REQ :capability1 capability2 capability3" for example.
References:
- <http://ircv3.atheme.org/specification/capability-negotiation-3.1>
- <http://ngircd.barton.de/doc/Capabilities.txt>
- doc/Capabilities.txt
- CHARCONV
CHARCONV <client-charset>
.
Set client character set encoding to <client-charset>.
.
After receiving such a command, the server translates all message
data received from the client using the set <client-charset> to the
server encoding (UTF-8), and all message data which is to be sent to
the client from the server encoding (UTF-8) to <client-charset>.
.
This enables older clients and clients using "strange" character sets
to transparently participate in channels and direct messages to
clients using UTF-8, which should be the default today.
References:
- IRC+, <http://ngircd.barton.de/doc/Protocol.txt>
- IRC+, doc/Protocol.txt
- NICK
NICK <nickname>
NICK <nickname> [<hops>]
NICK <nickname> <hops> <username> <host> <servertoken> <usermodes> <realname>
.
Set or change the <nickname> of a client (first form) and register
remote clients (second and third form; servers only).
References:
- RFC 1459, 4.1.2 "Nick message" (old client and server protocol)
- RFC 2812, 3.1.2 "Nick message" (client protocol)
- RFC 2813, 4.1.3 "Nick" (server protocol)
- PASS
PASS <password>
PASS <password> <version> <flags> [<options>]
.
Set a connection <password>. This command must be the first command
sent to the server, even before the NICK/USER or SERVER commands.
.
The first form is used by user sessions or (old) RFC 1459 servers,
the second form is used by RFC 2812 or IRC+ compliant servers and
enables the server to indicate its version and supported protocol
features.
References:
- RFC 1459, 4.1.1 "Password message" (old client and server protocol)
- RFC 2812, 3.1.1 "Password message" (client protocol)
- RFC 2813, 4.1.1 "Password message" (server protocol)
- IRC+, <http://ngircd.barton.de/doc/Protocol.txt>
- IRC+, doc/Protocol.txt
- PING
PING <token> [<target>]
.
Tests the presence of a connection to a client or server.
.
If no <target> has been given, the local server is used. User clients
can only use other servers as <target>, no user clients.
.
A PING message results in a PONG reply containing the <token>, which
can be arbitrary text.
Please note:
The RFCs state that the <token> parameter is used to specify the
origin of the PING command when forwarded in the network, but this
is not the case: the sender is specified using the prefix as usual,
and the parameter is used to identify the PONG reply in practice.
References:
- RFC 2812, 3.7.2 "Ping message"
- PONG
PONG <target> [<token>]
.
Reply to a "PING" command, indicate that the connection is alive.
.
The <token> is the arbitrary text received in the "PING" command and
can be used to identify the correct PONG sent as answer.
.
When the "PONG" command is received from a user session, the <target>
parameter is ignored; otherwise the PONG is forwarded to this client.
References:
- RFC 2812, 3.7.3 "Pong message"
- QUIT
QUIT [<quit-message>]
.
Terminate a user session.
.
When received from a user, the server acknowledges this by sending
an "ERROR" message back to the client and terminates the connection.
.
When a <quit-message> has been given, it is sent to all the channels
that the client is a member of when leaving.
References:
- RFC 2812, 3.1.7 "Quit"
- RFC 2813, 4.1.5 "Quit"
- USER
USER <username> <hostname> <unused> <realname>
.
Register (and authenticate) a new user session with a short <username>
and a human-readable <realname>.
.
The parameter <hostname> is only used when received by an other server
and ignored otherwise; and the parameter <unused> is always ignored.
But both parameters are required on each invocation by the protocol
and can be set to arbitrary characters/text when not used.
.
If <username> contains an "@" character, the full <username> is used
for authentication, but only the first part up to this character is
set as "user name" for this session.
References:
- RFC 2812, 3.1.3 "User message"
- WEBIRC
WEBIRC <password> <username> <hostname> <ip-address>
.
Allow Web-to-IRC gateway software (for example) to set the correct
user name and host name of users instead of their own.
.
It must be the very first command sent to the server, even before
USER and NICK commands!
.
The <password> must be set in the server configuration file to prevent
unauthorized clients to fake their identity; it is an arbitrary string.
References:
- IRC+, <http://ngircd.barton.de/doc/Protocol.txt>
- IRC+, doc/Protocol.txt
General Commands
~~~~~~~~~~~~~~~~
- AWAY
AWAY [<message>]
.
Provides the server with a message to automatically send in reply to a
PRIVMSG directed at the user, but not to a channel they are on.
.
If <message> is omitted, the away status is removed.
References:
- RFC 2812, 4.1 "Away"
- HELP
HELP [<command>]
.
Show help information for a specific IRC <command>. The <command> name
is case-insensitive.
.
Use the command "HELP Commands" to get a list of all available commands.
The HELP command isn't specified by any RFC but implemented by most
daemons. If no help text could be read in, ngIRCd outputs a list of all
implemented commands when receiving a plain "HELP" command as well as
on "HELP Commands".
ngIRCd replies using "NOTICE" commands like ircd 2.10/2.11; other
implementations are using numerics 704, 705, and 706.
- MODE
MODE <nickname> [{+|-}<mode>[<mode>] [{+|-}<mode>[<mode>] [...]]]
MODE <channel> [{+|-}<mode>[<mode>] [<arg> [<arg> [...]]] [{+|-}<mode>[<mode>] [<arg> [<arg> [...]]] [...]]]
.
Set and get user and channel modes.
.
When no mode parameters are given, the currently set user or channel
modes are returned. Otherwise the modes are adjusted accordingly
and the changes will be reported back to the client.
.
All user and channel "modes" are indicated by single case-sensitive
characters.
.
Please note that a user can only get and set his own modes, and not
all user "levels" are allowed to change all channel modes ...
.
The mode parameters can become quite complex, especially when dealing
with channel modes that require additional arguments:
.
{+|-}<mode(s}> -- set or unset one or more modes.
+<mode(s)> -<mode(s)> -- set some modes and unset others.
+<modes> <arg1> <arg2> -- set (at least) two modes with arguments.
.
Some examples:
.
MODE nick +i -- set user to "invisible".
MODE #chan +tn -- set "topic lock" and "no external messages".
MODE #chan -t +l 50 -- remove "topic lock", set "user limit" to 50.
MODE #chan +ov nick1 nick2 -- set "channel op" and "voice" mode
to nick1 and nick2 in channel #chan.
.
A complete list of all modes supported by ngIRCd can be found online
here: <http://ngircd.barton.de/doc/Modes.txt>.
References:
- RFC 2811, 4. "Channel Modes"
- RFC 2812, 3.1.5 "User mode message"
- RFC 2812, 3.2.3 "Channel mode message"
- <http://ngircd.barton.de/doc/Modes.txt>
- doc/Modes.txt
- NOTICE
NOTICE <target>[,<target>[,...]] <message>
.
Send a <message> to a given <target>, which can be a user or a
channel, but DON'T report any error.
.
The "NOTICE" command exactly behaves like the "PRIVMSG" command, but
doesn't report any errors it encounters (like an unknown <target>).
Please see the help text of the "PRIVMSG" command for a detailed
description of the parameters!
References:
- RFC 2812, 2.3.1 "Message format in Augmented BNF"
- RFC 2812, 3.3 "Sending messages"
- RFC 2812, 3.3.2 "Notice"
- PRIVMSG
PRIVMSG <target>[,<target>[,...]] <message>
.
Send a <message> to a given <target>, which can be a user or a
channel, and report all errors.
.
The <target> must follow one of these syntax variants:
.
- <nickname>
- <channel>
- <user>[%<host>]@<server>
- <user>%<host>
- <nickname>!<user>@<host>
.
If the <target> is a user, a private message is sent directly to this
user; if it resolves to a channel name, a public message is sent
to all the members of that channel.
.
In addition, IRC Ops can use these two forms to specify the <target>:
.
- #<hostmask>
- #<servermask>
.
The <mask> can contain the wildcard characters "*" and "?", but must
contain at least one dot (".") and no wildcard after the last one.
Then, the <message> is sent to all users matching this <mask>.
.
All warnings and errors are reported back to the initiator using
numeric status codes, which is the only difference to the "NOTICE"
command, which doesn't report back any errors or warnings at all.
.
Please note that clients often use "MSG" as an alias to PRIVMSG, and
a command "QUERY <nick> [<message>]" to initiate private chats. Both
are command extensions of the client and never sent to the server.
References:
- RFC 2812, 2.3.1 "Message format in Augmented BNF"
- RFC 2812, 3.3 "Sending messages"
- RFC 2812, 3.3.1 "Private messages"
Status and Informational Commands
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ADMIN
ADMIN [<target>]
.
Show administrative information about an IRC server in the network.
.
<target> can be a server name, the nickname of a client connected to
a specific server, or a mask matching a server name in the network.
The server of the current connection is used when <target> is omitted.
References:
- RFC 2812, 3.4.9 "Admin command"
- INFO
INFO [<target>]
.
Show the version, birth & online time of an IRC server in the network.
.
<target> can be a server name, the nickname of a client connected to
a specific server, or a mask matching a server name in the network.
The server of the current connection is used when <target> is omitted.
References:
- RFC 2812, 3.4.10 "Info command"
- ISON
ISON <nickname> [<nickname> [...]]
.
Query online status of a list of nicknames. The server replies with
a list only containing nicknames actually connected to a server in
the network. If no nicknames of the given list are online, an empty
list is returned to the client requesting the information.
Please note that "all" IRC daemons even parse separate nicknames in
a single parameter (like ":nick1 nick2"), and therefore ngIRCd
implements this behaviour, too.
References:
- RFC 2812, 4.9 "Ison message"
- LINKS
LINKS [[<target>] [<mask>]
.
List all servers currently registered in the network matching <mask>,
or all servers if <mask> has been omitted, as seen by the server
specified by <target> or the local server when <target> is omitted.
.
<target> can be a server name, the nickname of a client connected to
a specific server, or a mask matching a server name in the network.
References:
- RFC 2812, 3.4.5 "Links message"
- LUSERS
LUSERS [<mask> [<target>]]
.
Return statistics about the number of clients (users, servers,
services, ...) in the network as seen by the server <target>.
.
<target> can be a server name, the nickname of a client connected to
a specific server, or a mask matching a server name in the network.
The server of the current connection is used when <target> is omitted.
Please note that ngIRCd ignores the <mask> parameter entirely: it
is not possible to get information for a part of the network only.
References:
- RFC 2812, 3.4.2 "Lusers message"
- MOTD
MOTD [<target>]
.
Show the "Message of the Day" (MOTD) of an IRC server in the network.
.
<target> can be a server name, the nickname of a client connected to
a specific server, or a mask matching a server name in the network.
The server of the current connection is used when <target> is omitted.
References:
- RFC 2812, 3.4.1 "Motd message"
- NAMES
NAMES [<channel>[,<channel>[,...]] [<target>]]
.
Show the list of users that are members of a particular <channel>
(and that are visible for the client requesting this information) as
seen by the server <target>. More than one <channel> can be given
separated by "," (but not whitespaces!).
.
If <channel> has been omitted, all visible users are shown, grouped
by channel name, and all visible users not being members of at least
one channel are shown as members of the pseudo channel "*".
.
<target> can be a server name, the nickname of a client connected to
a specific server, or a mask matching a server name in the network.
The server of the current connection is used when <target> is omitted.
References:
- RFC 2812, 3.2.5 "Names message"
- STATS
STATS [<query> [<target>]]
.
Show statistics and other information of type <query> of a particular
IRC server in the network.
.
The following <query> types are supported (case-insensitive where
applicable):
.
- g Network-wide bans ("G-Lines").
- k Server-local bans ("K-Lines").
- L Link status (servers and user links).
- l Link status (servers and own link).
- m Command usage count.
- u Server uptime.
.
<target> can be a server name, the nickname of a client connected to
a specific server, or a mask matching a server name in the network.
The server of the current connection is used when <target> is omitted.
.
To use "STATS L" the user must be an IRC Operator.
References:
- RFC 2812, 3.4.4 "Stats message"
- TIME
TIME [<target>]
.
Show the local time of an IRC server in the network.
.
<target> can be a server name, the nickname of a client connected to
a specific server, or a mask matching a server name in the network.
The server of the current connection is used when <target> is omitted.
References
- RFC 2812, 3.4.6 "Time message"
- TRACE
TRACE [<target>]
.
Find the route to a specific server and send information about its
peers. Each server that processes this command reports back to the
sender about it: the replies from pass-through servers form a chain
which shows the route to the destination.
.
<target> can be a server name, the nickname of a client connected to
a specific server, or a mask matching a server name in the network.
The server of the current connection is used when <target> is omitted.
References:
- RFC 2812, 3.4.8 "Trace message"
- USERHOST
USERHOST <nickname> [<nickname> [...]]
.
Show flags and the hostmasks (<user>@<host>) of the <nickname>s,
separated by spaces. The following flags are used:
.
- "-" The client is "away" (the mode "+a" is set on this client).
- "+" Client seems to be available, at least it isn't marked "away".
- "*" The client is an IRC operator (the mode "+o" is set).
References:
- RFC 2812, 4.8 "Userhost message"
- VERSION
VERSION [<target>]
.
Show version information about a particular IRC server in the network.
.
<target> can be a server name, the nickname of a client connected to
a specific server, or a mask matching a server name in the network.
The server of the current connection is used when <target> is omitted.
.
Please note: in normal operation, the version number ends in a dot
(".", for example "ngIRCd-20.1."). If it ends in ".1" (for example
"ngIRCd-20.1.1", same version than before!), the server is running in
debug-mode; and if it ends in ".2", the "network sniffer" is active!
Keep your privacy in mind ...
References:
- RFC 2812, 3.4.3 "Version message"
- WHO
WHO [<mask> ["o"]]
.
Show a list of users who match the <mask>, or all visible users when
the <mask> has been omitted. (Special case: the <mask> "0" is
equivalent to "*")
.
If the flag "o" is given, the server will only return information about
IRC Operators.
References:
- RFC 2812, 3.6.1 "Who query"
- WHOIS
WHOIS [<target>] <mask>[,<mask>[,...]]
.
Query information about users matching the <mask> parameter(s) as seen
by the server <target>; up to 3 <masks> are supported.
.
<target> can be a server name, the nickname of a client connected to a
specific server, or a mask matching a server name in the network. The
server of the current connection is used when <target> is omitted.
References:
- RFC 2812, 3.6.2 "Whois query"
- WHOWAS
WHOWAS <nickname>[,<nickname>[,...]] [<count> [<target>]]
.
Query information about nicknames no longer in use in the network,
either because of nickname changes or disconnects. The history is
searched backwards, returning the most recent entry first. If there
are multiple entries, up to <count> entries will be shown (or all of
them, if no <count> has been given).
.
<target> can be a server name, the nickname of a client connected to a
specific server, or a mask matching a server name in the network. The
server of the current connection is used when <target> is omitted.
References:
- RFC 2812, 3.6.3 "Whowas"
Channel Commands
~~~~~~~~~~~~~~~~
- INVITE
INVITE <nickname> <channel>
.
Invite <nickname> to join channel <channel>.
.
<channel> does not have to exist, but if it does, only members of the
channel are allowed to invite other users. If the channel mode "+i"
is set, only channel "half-ops" (and above) may invite other clients,
and if channel mode "+V" is set, nobody can invite other users.
References:
- RFC 2812, 3.2.7 "Invite message"
- JOIN
JOIN {<channel>[,<channel>[,...]] [<key>[,<key>[,...]]] | 0}
.
Makes the client join the <channel> (comma-separated list), specifying
the channel keys ("passwords"). A <channel-key> is only needed if the
<channel> has the mode "+k" set.
.
If the channel(s) do not exist, then they will be created.
.
Using "JOIN 0" parts all channels at once.
References:
- RFC 2812, 3.2.1 "Join message" (client protocol)
- RFC 2813, 4.2.1 "Join message" (server protocol)
- KICK
KICK <channel>[,<channel>[,...]] <nickname>[,<nickname>[,...]] [<reason>]
.
Remove users(s) with <nickname>(s) from <channel>(s).
.
There must be either exactly one <channel> parameter and multiple
<nickname> parameters, or as many <channel> parameters as there are
<nickname> parameters. The <reason> is shown to the users being
kicked, and the nickname of the current user is used when <reason>
is omitted.
References:
- RFC 2812, 3.2.8 "Kick command"
- LIST
LIST [<channel>[,<channel>[,...]] [<server>]]
.
List all visible <channels> (comma-separated list).
.
If <server> is given, the command will be forwarded to <server> for
evaluation.
References:
- RFC 2812, 3.2.6 "List message"
- PART
PART <channel>[,<channel>[,...]] [<part-message>]
.
Leave <channel> (comma-separated list), optionally with sending a
<part-message> to all the other channel members.
References:
- RFC 2812, 3.2.2 "Part message"
- TOPIC
TOPIC <channel> [<topic>]
.
Change or view the topic of a channel.
.
The topic for channel <channel> is returned if there is no <topic>
given. If the <topic> parameter is present, the topic for that
channel will be changed, if this action is allowed for the user
requesting it. If the <topic> parameter is an empty string, the
topic for that channel will be removed.
References:
- RFC 2812, 3.2.4 "Topic message"
Administrative Commands
~~~~~~~~~~~~~~~~~~~~~~~
- CONNECT
CONNECT <server> [<port> [<remote-server> [<my-pwd> <peer-pwd>]]]
.
Instructs the current server, or <remote-server> if specified,
to connect to the server named <server>, which must be configured
in the server configuration file.
.
To use this command, the user must be an IRC Operator. To establish
a connection on a <remote-server>, you must have remote IRC operator
privileges.
.
If <port>, <my-pwd> and <peer-pwd> are given, these values override
the ones specified in the server configuration file.
References:
- RFC 2812, 3.4.7 "Connect message"
- DIE
DIE [<message>]
.
Instructs the server to shut down.
.
The optional (and non-standard) <message> text is sent to each client
connected to this server before all connections are closed.
.
To use this command, the user must be an IRC Operator.
References:
- RFC 2812, 4.3 "Die message"
- DISCONNECT
DISCONNECT <server>
.
Disconnect and disable a locally linked server.
.
To use this command, the user must be an IRC Operator.
References:
- This command is not specified in the IRC RFCs, it is an extension
of ngIRCd.
- GLINE
GLINE <nick!user@hostmask> [<timeout> :<reason>]
.
This command provides timed G-Lines (network-wide bans).
.
If a client matches a G-Line, it cannot connect to any server on
the IRC network for <timeout> seconds. When <timeout> is 0, it make
the G-Line permanent.
.
If no <timeout> and no <reason> is given, the G-Line is removed.
.
To use this command, the user must be an IRC Operator.
.
"STATS g" can be used to list all currently active G-Lines.
References:
- This command is not specified in the IRC RFCs, it is an extension
of ngIRCd.
- KILL
KILL <nickname> <reason>
.
Forcibly remove all users with a given <nickname> from the IRC
network and display the given <reason> to them.
.
This command is used internally between servers, too, for example
to disconnect duplicate <nickname>'s after a "net split".
.
To use this command, the user must be an IRC Operator.
References:
- RFC 2812, 3.7.1 "Kill message"
- KLINE
KLINE <nick!user@hostmask> [<timeout> :<reason>]
.
This command provides timed K-Lines (server-local bans).
.
If a client matches a K-Line, it cannot connect to this server for
<timeout> seconds. When <timeout> is 0, it makes the K-Line permanent.
.
If no <timeout> and no <reason> is given, the K-Line is removed.
.
To use this command, the user must be an IRC Operator.
.
"STATS k" can be used to list all currently active K-Lines.
References:
- This command is not specified in the IRC RFCs, it is an extension
of ngIRCd.
- OPER
OPER <name> <password>
.
Authenticates a user named <name> as an IRC operator on the current
server/network.
.
This operator <name> must be configured in the server configuration.
.
Please note that <name> is NOT related to a nickname at all!
References:
- RFC 2812, 3.1.4 "Oper message"
- REHASH
REHASH
.
Causes the server to re-read and re-process its configuration file(s).
.
While rehashing, no new connections are accepted, but all already
established connections stay connected.
.
To use this command, the user must be an IRC Operator.
References:
- RFC 2812, 4.2 "Rehash message"
- RESTART
RESTART
.
Restart the server.
.
While restarting, all connections are reset and no new connections
are accepted.
.
To use this command, the user must be an IRC Operator.
References:
- RFC 2812, 4.4 "Restart message"
- WALLOPS
WALLOPS <message>
.
Sends <message> to all users with user mode "+w".
.
To use this command, the user must be an IRC Operator.
References:
- RFC 2812, 4.7 "Operwall message"
IRC Service Commands
~~~~~~~~~~~~~~~~~~~~
- SERVICE
SERVICE <name> <reserved1> <distribution> <type> <reserved2> <info>
SERVICE <name> <servertoken> <distribution> {<type>|+<modes>} <hops> <info>
.
Register a new service in the network.
.
The first form is used by directly linked services and isn't supported
by ngIRCd at the moment. The second form announces services connected
to remote "pseudo-servers" ("services hubs").
.
The <distribution> and <type> parameters are ignored by ngIRCd.
References:
- RFC 2812, 3.1.6 "Service message"
- RFC 2813, 4.1.4 "Service message"
- SERVLIST
SERVLIST [<mask> [<type>]]
.
List all IRC services currently registered in the network.
.
The optional <mask> and <type> parameters can be used to limit the
listing to services matching the <mask> and that are of type <type>.
.
Please note that ngIRCd doesn't use any service types at the moment
and therefore all services are of type "0".
References:
- RFC 2812, 3.5.1 "Servlist message"
- SQUERY
SQUERY <target>[,<target>[,...]] <message>
.
Send a <message> to a given <target> IRC service, and report all
errors.
.
The "SQUERY" command exactly behaves like the "PRIVMSG" command, but
enforces that the <target> of the <message> is an IRC service.
Please see the help text of the "PRIVMSG" command for a detailed
description of the parameters!
.
If a user wants to interact with IRC services, he should use "SQUERY"
instead of "PRIVMSG" or "NOTICE": only "SQUERY makes sure that no
regular user, which uses the nickname of an IRC service, receives
the command in error, for example during a "net split"!
References:
- RFC 2812, 2.3.1 "Message format in Augmented BNF"
- RFC 2812, 3.3 "Sending messages"
- RFC 2812, 3.3.2 "Notice"
- SVSNICK
SVSNICK <oldnick> <newnick>
.
Forcefully change foreign user nicknames. This command is allowed
for servers only.
.
The "SVSNICK" command is forwarded to the server to which the user
with nickname <oldnick> is connected to, which in turn generates a
regular "NICK" command that then is sent to the client, so no special
support in the client software is required.
References:
- ngIRCd GIT commit e3f300d3231f
Server Protocol Commands
~~~~~~~~~~~~~~~~~~~~~~~~
- CHANINFO
CHANINFO <channel> +<modes> [[<key> <limit>] <topic>]
.
CHANINFO is used by servers to inform each other about a channel:
its modes, channel key, user limits and its topic.
.
The CHANINFO command is allowed on server-links only.
References:
- IRC+, <http://ngircd.barton.de/doc/Protocol.txt>
- IRC+, doc/Protocol.txt
- ERROR
ERROR [<message> [<> [...]]]
.
Inform a client or a server about an error condition. The first
parameter, if given, is logged by the server receiving the message,
all other parameters are silently ignored.
.
This command is silently ignored on non-server and non-service links
and shouldn't be used by regular IRC clients.
.
The ERROR message is also sent before terminating a regular client
connection.
References:
- RFC 2812, 3.7.4 "Error message"
- METADATA
METADATA <target> <key> <value>
.
The METADATA command is used on server-links to update "metadata"
information of clients, like the hostname, the info text ("real name"),
or the user name.
.
The METADATA command is allowed on server-links only.
References:
- IRC+, <http://ngircd.barton.de/doc/Protocol.txt>
- IRC+, doc/Protocol.txt
- NJOIN
NJOIN <channel> [<mode>]<nick>[,[<mode>]<nick>[,...]]
.
The NJOIN command is used on server-links to add users with <nick>
and <mode> to a <channel> while peering.
.
The NJOIN command is allowed on server-links only.
References:
- RFC 2813, 4.2.2 "Njoin message"
- SERVER
SERVER <servername> <info>
SERVER <servername> <hopcount> <info>
SERVER <servername> <hopcount> <token> <info>
.
The first form registers the local connection as a new server in the
network, the second (RFC 1459) and third (RFC 2812) form announce a
new remote server in the network.
.
The SERVER command is allowed on unregistered or server-links only.
References:
- RFC 1459, 4.1.4 "Server message"
- RFC 2813, 4.1.2 "Server message"
- SQUIT
SQUIT <server> <comment>
.
Disconnects an IRC Server from the network.
.
This command is used on server-links, but can be used by IRC Operators
to forcefully disconnect servers from the network, too.
References:
- RFC 2812, 3.1.8 "Squit"
- RFC 2813, 4.1.6 "Server quit message"
Dummy Commands
~~~~~~~~~~~~~~
- SUMMON
SUMMON <user> [<target> [<channel>]]
.
This command was intended to call people into IRC who are directly
connected to the terminal console of the IRC server -- but is
deprecated today. Therefore ngIRCd doesn't really implement this
command and always returns an error message, regardless of the
parameters given.
References:
- RFC 2812, 4.5 "Summon message"
- USERS
USERS [<target>]
.
This command was intended to list users directly logged in into the
console of the IRC server -- but is deprecated today. Therefore ngIRCd
doesn't really implement this command and always returns an error
message, regardless of the parameters given.
References:
- RFC 2812, 4.6 "Users"
- GET
GET [...]
.
Fake HTTP GET command. When received, the connection is shut down
immediately again to protect against crazy web browsers ...
References:
- ngIRCd GIT commit 33e8c2480649
- POST
POST [...]
.
Fake HTTP POST command. When received, the connection is shut down
immediately again to protect against crazy web browsers ...
References:
- ngIRCd GIT commit 33e8c2480649

View File

@@ -1,6 +1,6 @@
#
# ngIRCd -- The Next Generation IRC Daemon
# Copyright (c)2001-2013 Alexander Barton (alex@barton.de) and Contributors
# Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors
#
# 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
@@ -12,7 +12,6 @@
.tmpl:
$(AM_V_GEN)sed \
-e "s@:ETCDIR:@${sysconfdir}@" \
-e "s@:DOCDIR:@${docdir}@" \
<$< >$@
SUFFIXES = .tmpl
@@ -20,7 +19,6 @@ SUFFIXES = .tmpl
static_docs = \
Bopm.txt \
Capabilities.txt \
Commands.txt \
Contributing.txt \
FAQ.txt \
GIT.txt \
@@ -54,11 +52,11 @@ maintainer-clean-local:
all: $(generated_docs)
install-data-hook: $(static_docs) $(toplevel_docs) $(generated_docs)
$(MKDIR_P) -m 755 $(DESTDIR)$(sysconfdir)
$(mkinstalldirs) $(DESTDIR)$(sysconfdir)
@if [ ! -f $(DESTDIR)$(sysconfdir)/ngircd.conf ]; then \
make install-config; \
fi
$(MKDIR_P) -m 755 $(DESTDIR)$(docdir)
$(mkinstalldirs) $(DESTDIR)$(docdir)
for f in $(static_docs) $(toplevel_docs); do \
$(INSTALL) -m 644 -c $(srcdir)/$$f $(DESTDIR)$(docdir)/; \
done

View File

@@ -1,8 +1,9 @@
ngIRCd - Next Generation IRC Server
http://ngircd.barton.de/
(c)2001-2013 Alexander Barton and Contributors.
(c)2001-2010 Alexander Barton,
alex@barton.de, http://www.barton.de/
ngIRCd is free software and published under the
terms of the GNU General Public License.
@@ -33,13 +34,3 @@ is running as. Therefore a lot of PAM modules aren't working as expected,
because they need root privileges ("pam_unix", for example)!
Only PAM modules not(!) requiring root privileges (such as "pam_pgsql",
"pam_mysql", "pam_opendirectory" ...) can be used in conjunction with ngIRCd.
More Examples:
* Use an own "password file" for ngIRCd:
Note: you can use the htpasswd(1) utility of Apache to manage password
files used by pam_pwdfile, see "man htpasswd"!
/etc/pam.d/ngircd:
auth required pam_pwdfile.so pwdfile=/etc/ngircd/ngircd.passwd

View File

@@ -2,106 +2,87 @@
ngIRCd - Next Generation IRC Server
http://ngircd.barton.de/
(c)2001-2013 Alexander Barton and Contributors.
(c)2001-2012 Alexander Barton and Contributors.
ngIRCd is free software and published under the
terms of the GNU General Public License.
-- Platforms.txt --
This file lists the status of all platforms on which ngIRCd has been tested.
Included is the date and version of the last test and the name of the tester
or maintainer.
This file lists the status of all platforms on which the ngIRCd has been
tested. Included is the date and version of the last "official" test and
the name of the tester/maintainer.
If you successfully compiled and tested ngIRCd on a platform that isn't listed
here, please write to the mailing list so that this list can be updated. The
script "./contrib/platformtest.sh" should output a summary that is suitable
for inclusion here. Thanks for your help!
If you successfully compiled and tested ngIRCd on a platform that isn't
listed here, please contact Alexander Barton, <alex@barton.de>, so that this
list can be updated. Thanks for your help!
the executable works ("runs") as expected --+
tests run successfully ("make check") --+ |
ngIRCd compiles ("make") --+ | |
./configure works --+ | | |
| | | |
Platform Compiler ngIRCd Date Tester C M T R *
--------------------------- ------------ ---------- -------- -------- - - - - -
alpha/unknown/netbsd3.0 gcc 3.3.3 CVSHEAD 06-05-07 fw Y Y Y Y 3
armv6l/unk./linux-gnueabi gcc 4.7.2 20.2 13-03-08 goetz Y Y Y Y 5
armv6l/unk./linux-gnueabihf gcc 4.6.3 21~rc2 13-10-26 pi Y Y Y Y 5
armv7l/unk./linux-gnueabi gcc 4.4.3 19.1 12-04-29 goetz Y Y Y Y 5
hppa/unknown/openbsd3.5 gcc 2.95.3 CVSHEAD 04-05-25 alex Y Y Y Y
hppa/unknown/openbsd5.4 gcc 4.2.1 21 13-11-10 alex Y Y Y Y 3
hppa1.1/unknown/linux-gnu gcc 3.3.3 0.8.0 04-05-30 alex Y Y Y Y
hppa2.0/unknown/linux-gnu gcc 3.3.5 13~rc1 08-12-02 alex Y Y Y Y
hppa2.0w-hp-hpux11.11 gcc 4.2.3 14.1 09-07-22 goetz Y Y Y Y
i386/apple/darwin9.7.0 gcc 4.0.1 14.1 09-08-04 alex Y Y Y Y 3
i386/apple/darwin10.8.0 gcc 4.2.1 19 12-02-26 alex Y Y Y Y 3
i386/apple/darwin11.3.0 gcc 4.2.1 19 12-02-26 alex Y Y Y Y 3
i386/pc/solaris2.9 gcc 3.2.2 CVSHEAD 04-02-24 alex Y Y Y Y
i386/pc/solaris2.11 gcc 4.5.2 21~rc2 13-10-27 alex Y Y N Y 4
i386/unknown/freebsd5.2.1 gcc 3.3.3 0.8.0 04-05-30 alex Y Y Y Y
i386/unknown/freebsd6.2 gcc 3.4.6 20~rc1 12-11-13 alex Y Y Y Y 3
i386/unknown/freebsd7.3 gcc 4.2.1 20~rc1 12-11-13 alex Y Y Y Y 3
i686/pc/minix gcc 4.4.6 21~rc2 13-10-27 alex Y Y N N
i686/unknown/gnu0.3 gcc 4.4.5 19 12-02-29 alex Y Y Y Y
i686/unknown/gnu0.5 gcc 4.8.2 21 14-02-09 alex Y Y Y Y
i686/unkn./kfreebsd7.2-gnu gcc 4.3.4 15 09-12-02 alex Y Y Y Y 3
i386/unknown/netbsdelf1.5.2 egcs-1.1.2 21 13-11-25 goetz Y Y N Y
i386/unknown/netbsdelf1.6.2 gcc 2.95.3 18 11-07-10 goetz Y Y Y Y
i386/unknown/netbsdelf3.0.1 gcc 3.3.3 0.10.0-p1 06-08-30 alex Y Y Y Y 3
i386/unknown/netbsdelf4.0 gcc 4.1.2 19 12-02-29 alex Y Y Y Y 3
i386/unknown/netbsdelf5.0.2 gcc 4.1.3 19 12-02-26 alex Y Y Y Y 3
i386/unknown/openbsd3.5 gcc 2.95.3 21 13-11-17 goetz Y Y Y Y 3
i386/unknown/openbsd3.9 gcc 3.3.5 0.10.0-p1 06-08-30 alex Y Y Y Y 3
i386/unknown/openbsd4.1 gcc 3.3.5 16 10-04-11 alex Y Y Y Y 3
i386/unknown/openbsd5.3 gcc 4.2.1 21 13-11-28 goetz Y Y Y Y 3
i386/unknown/openbsd5.4 gcc 4.2.1 21 13-11-28 goetz Y Y Y Y 3
i586/pc/haiku gcc 2.95.3 19.2~138 12-10-11 user Y Y N N
i586/pc/interix3.5 gcc 3.3 19 12-02-29 alex Y Y N Y
i686/pc/cygwin gcc 4.8.2 21 14-01-02 alex Y Y N Y
i686/pc/linux-gnu gcc 2.7.2 21~38 14-01-06 goetz Y Y Y Y 1
i686/pc/linux-gnu gcc 2.95.4 0.8.0 04-05-30 alex Y Y Y Y 1
i686/pc/linux-gnu gcc 3.3.5 14.1 09-08-04 alex Y Y Y Y 1
i386/pc/linux-gnu gcc 4.1.2 13~rc1 08-12-05 alex Y Y Y Y 1
i686/pc/linux-gnu gcc 4.3.2 14.1 09-08-04 alex Y Y Y Y 1
m68k/apple/aux3.0.1 gcc 2.7.2 17 10-11-07 alex Y Y N Y
m68k/apple/aux3.0.1 Orig. A/UX 17 10-11-07 alex Y Y N Y 2
m68k/apple/aux3.1.1 gcc 2.7.2 19 12-02-26 alex Y Y N Y
m68k/apple/aux3.1.1 Orig. A/UX 19 12-02-26 alex Y Y N Y 2
m68k/hp/hp-ux9.10 Orig. HPUX 0.7.x-CVS 03-04-30 goetz Y Y Y Y
m88k/dg/dgux5.4R3.10 gcc 2.5.8 CVSHEAD 04-03-15 alex Y Y ? ?
mipsel/unknown/linux-gnu gcc 4.1.2 18 11-07-05 goetz Y Y N Y 1
mipsel/unknown/linux-gnu gcc 4.4.5 21 13-11-24 goetz Y Y Y Y 1
powerpc/apple/darwin6.8 gcc 3.1 21 14-01-03 goetz Y Y Y Y
powerpc/apple/darwin7.9.0 gcc 3.3 21 14-01-11 goetz Y Y Y Y 3
powerpc/apple/darwin8.11.0 gcc 4.0.1 18 11-07-02 goetz Y Y Y Y 3
powerpc/apple/darwin9.8.0 gcc 4.0.1 21 14-01-04 goetz Y Y Y Y 3
powerpc/unknown/linux-gnu gcc 3.3.3 0.8.0 04-05-30 alex Y Y Y Y
powerpc/unknown/openbsd3.6 gcc 2.95.3 0.10.0 06-10-08 alex Y Y N Y
sparc/sun/solaris2.6 gcc 2.95.3 0.7.x-CVS 03-04-22 alex Y Y Y Y
sparc/sun/solaris2.7 gcc 3.3 0.8.0 04-05-30 alex Y Y Y Y
sparc/unkn./netbsdelf1.6.1 gcc 2.95.3 0.8.0 04-05-30 alex Y Y Y Y
x86_64/apple/darwin10.8.0 gcc 4.2.1 21~rc2 13-10-30 alex Y Y Y Y 3
x86_64/apple/darwin12.3.0 gcc 4.2.1 20.2 13-04-01 alex Y Y Y Y 3
x86_64/apple/darwin13.0.0 A-clang 5.0 21 14-01-02 alex Y Y Y Y 3
x86_64/unknown/dragonfly3.4 gcc 4.7.2 21 13-11-12 goetz Y Y N Y 3
x86_64/unknown/freebsd8.4 gcc 4.2.1 21 14-01-02 alex Y Y Y Y 3
x86_64/unknown/freebsd9.1 gcc 4.2.1 21 14-01-02 alex Y Y Y Y 3
x86_64/unkn./freebsd8.1-gnu gcc 4.4.5 19 12-02-26 alex Y Y Y Y 3
x86_64/unknown/linux-gnu clang 3.3 21 14-01-07 alex Y Y Y Y 1
x86_64/unknown/linux-gnu gcc 4.8.2 21 13-12-29 alex Y Y Y Y 1
x86_64/unknown/linux-gnu nwcc 0.8.2 21 13-12-01 goetz Y Y Y Y 1
x86_64/unknown/linux-gnu Open64 21 13-11-30 goetz Y Y Y Y 1
x86_64/unknown/linux-gnu Sun C 5.12 21 13-11-22 goetz Y Y Y Y 1
x86_64/unknown/linux-gnu tcc 0.9.25 21 13-11-30 goetz Y Y Y Y 1
x86_64/unknown/openbsd4.7 gcc 3.3.5 20~rc1 12-02-26 alex Y Y Y Y 3
x86_64/unknown/openbsd4.8 gcc 4.2.1 21 13-12-28 alex Y Y Y Y 3
x86_64/unknown/openbsd5.1 gcc 4.2.1 21 13-12-28 alex Y Y Y Y 3
the executable works ("runs") as expected --+
tests run successfully ("make check") --+ |
ngIRCd compiles ("make") --+ | |
./configure works --+ | | |
| | | |
Platform Compiler ngIRCd Date Tester C M T R See
--------------------------- ------------ ---------- -------- ------ - - - - ---
alpha/unknown/netbsd3.0 gcc 3.3.3 CVSHEAD 06-05-07 fw Y Y Y Y (3)
armv6l/unkn./linux-gnueabi gcc 4.4.5 19.1 12-06-04 goetz Y Y Y Y (5)
armv7l/unkn./linux-gnueabi gcc 4.4.3 19.1 12-04-29 goetz Y Y Y Y (5)
hppa/unknown/openbsd3.5 gcc 2.95.3 CVSHEAD 04-05-25 alex Y Y Y Y
hppa1.1/unknown/linux-gnu gcc 3.3.3 0.8.0 04-05-30 alex Y Y Y Y
hppa2.0/unknown/linux-gnu gcc 3.3.5 13~rc1 08-12-02 alex Y Y Y Y
hppa2.0w-hp-hpux11.11 gcc 4.2.3 14.1 09-07-22 goetz Y Y Y Y
i386/apple/darwin9.7.0 gcc 4.0.1 14.1 09-08-04 alex Y Y Y Y (3)
i386/apple/darwin10.8.0 gcc 4.2.1 19 12-02-26 alex Y Y Y Y (3)
i386/apple/darwin11.3.0 gcc 4.2.1 19 12-02-26 alex Y Y Y Y (3)
i386/pc/solaris2.9 gcc 3.2.2 CVSHEAD 04-02-24 alex Y Y Y Y
i386/pc/solaris2.11 gcc 3.4.3 19 12-02-26 alex Y Y N Y (4)
i386/pc/solaris2.11 gcc 4.2.3 19.1 12-05-29 goetz Y Y Y Y (4)
i386/unknown/freebsd5.2.1 gcc 3.3.3 0.8.0 04-05-30 alex Y Y Y Y
i386/unknown/freebsd6.2 gcc 3.4.6 20~rc1 12-11-13 alex Y Y Y Y (3)
i386/unknown/freebsd7.3 gcc 4.2.1 20~rc1 12-11-13 alex Y Y Y Y (3)
i686/unknown/gnu0.3 gcc 4.4.5 19 12-02-29 alex Y Y Y Y
i686/unkn./kfreebsd7.2-gnu gcc 4.3.4 15 09-12-02 alex Y Y Y Y (3)
i386/unknown/netbsdelf1.6.2 gcc 2.95.3 18 11-07-10 goetz Y Y Y Y
i386/unknown/netbsdelf3.0.1 gcc 3.3.3 0.10.0-p1 06-08-30 alex Y Y Y Y (3)
i386/unknown/netbsdelf4.0 gcc 4.1.2 19 12-02-29 alex Y Y Y Y (3)
i386/unknown/netbsdelf5.0.2 gcc 4.1.3 19 12-02-26 alex Y Y Y Y (3)
i386/unknown/openbsd3.9 gcc 3.3.5 0.10.0-p1 06-08-30 alex Y Y Y Y (3)
i386/unknown/openbsd4.1 gcc 3.3.5 16 10-04-11 alex Y Y Y Y (3)
i586/pc/haiku gcc 2.95.3 19.2~138 12-10-11 user Y Y N N
i586/pc/interix3.5 gcc 3.3 19 12-02-29 alex Y Y N Y
i686/pc/cygwin gcc 3.3.1 0.8.0 04-05-30 alex Y Y N Y
i686/pc/linux-gnu gcc 2.7.2 19.1 12-05-30 goetz Y Y Y Y (1)
i686/pc/linux-gnu gcc 2.95.4 0.8.0 04-05-30 alex Y Y Y Y (1)
i686/pc/linux-gnu gcc 3.3.5 14.1 09-08-04 alex Y Y Y Y (1)
i386/pc/linux-gnu gcc 4.1.2 13~rc1 08-12-05 alex Y Y Y Y (1)
i686/pc/linux-gnu gcc 4.3.2 14.1 09-08-04 alex Y Y Y Y (1)
m68k/apple/aux3.0.1 gcc 2.7.2 17 10-11-07 alex Y Y N Y
m68k/apple/aux3.0.1 Orig. A/UX 17 10-11-07 alex Y Y N Y (2)
m68k/apple/aux3.1.1 gcc 2.7.2 19 12-02-26 alex Y Y N Y
m68k/apple/aux3.1.1 Orig. A/UX 19 12-02-26 alex Y Y N Y (2)
m68k/hp/hp-ux9.10 Orig. HPUX 0.7.x-CVS 03-04-30 goetz Y Y Y Y
m88k/dg/dgux5.4R3.10 gcc 2.5.8 CVSHEAD 04-03-15 alex Y Y ? ?
mipsel/unknown/linux-gnu gcc 4.1.2 18 11-07-05 goetz Y Y N Y (1)
mipsel/unknown/linux-gnu gcc 4.4.5 18 11-07-30 goetz Y Y Y Y (1)
powerpc/apple/darwin6.5 gcc 3.1 0.7.x-CVS 03-04-23 alex Y Y Y Y
powerpc/apple/darwin7.9.0 gcc 3.3 19.1 12-05-22 goetz Y Y Y Y (3)
powerpc/apple/darwin8.11.0 gcc 4.0.1 18 11-07-02 goetz Y Y Y Y (3)
powerpc/unknown/linux-gnu gcc 3.3.3 0.8.0 04-05-30 alex Y Y Y Y
powerpc/unknown/openbsd3.6 gcc 2.95.3 0.10.0 06-10-08 alex Y Y N Y
sparc/sun/solaris2.6 gcc 2.95.3 0.7.x-CVS 03-04-22 alex Y Y Y Y
sparc/sun/solaris2.7 gcc 3.3 0.8.0 04-05-30 alex Y Y Y Y
sparc/unkn./netbsdelf1.6.1 gcc 2.95.3 0.8.0 04-05-30 alex Y Y Y Y
x86_64/apple/darwin12.2.0 gcc 4.2.1 20~rc1 12-11-13 alex Y Y Y Y (3)
x86_64/unknown/freebsd8.1 gcc 4.2.1 20~rc1 12-11-13 alex Y Y Y Y (3)
x86_64/unkn./freebsd8.1-gnu gcc 4.4.5 19 12-02-26 alex Y Y Y Y (3)
x86_64/unknown/linux-gnu gcc 4.4.5 20~rc1 12-02-26 alex Y Y Y Y (1)
x86_64/unknown/openbsd4.7 gcc 3.3.5 20~rc1 12-02-26 alex Y Y Y Y (3)
x86_64/unknown/openbsd4.8 gcc 4.2.1 20~rc1 12-11-13 alex Y Y Y Y (3)
* Notes
~~~~~~~
Notes
~~~~~
(1) */*/linux-gnu (Linux platforms):
ngIRCd has been tested with various Linux distributions, such as SuSE,

View File

@@ -224,10 +224,8 @@ new server link", <serverflag> "M"), even if it doesn't support the given
The following <key> names are defined:
- "accountname": the account name of a client (can't be empty)
- "certfp": the certificate fingerprint of a client (can't be empty)
- "cloakhost": the cloaked hostname of a client
- "host": the hostname of a client (can't be empty)
- "cloakhost": the cloaked hostname of a client
- "info": info text ("real name") of a client
- "user": the user name of a client (can't be empty)

View File

@@ -14,7 +14,7 @@ acting as a "regular servers" ("pseudo servers") are supported, either
using the IRC protocol as defined in RFC 1459 or RFC 2812.
Support for Services has been tested using
- Anope 1.9.8 or later (<http://www.anope.org/>)
- Anope 1.9.8 or later (<http://www.anope.org/>; unreleased!)
- Atheme 7.0.2 or later (<http://www.atheme.net>)
- "IRC Services" 5.1.x by Andrew Church (<http://achurch.org/services/>)
@@ -41,11 +41,13 @@ Example:
ServiceMask = *Serv
Setting up Anope 1.9.x & 2.x
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Setting up Anope 1.9.x
~~~~~~~~~~~~~~~~~~~~~~
Anope 1.9.8 or later (<http://www.anope.org/>) can be used with ngIRCd using
the "ngircd" protocol module.
Anope 1.9.8 or later (<http://www.anope.org/>; unreleased as of 2012-11-10)
may be used with ngIRCd using the "ngircd" protocol module.
Until Anope 1.9.8 is released, you have to use the sources from the Anope
development GIT tree, see <http://sourceforge.net/projects/anope/develop/>!
At least the following settings have to be tweaked, in addition to all the
settings marked as required by Anope:
@@ -66,28 +68,20 @@ In conf/services.conf:
}
# Load ngIRCd protocol module
module
{
name = "ngircd"
}
module { name = "ngircd" }
networkinfo
{
# Must be set to the "MaxNickLength" setting of ngIRCd!
nicklen = 9
# When not using "strict mode", which is the default:
userlen = 20
chanlen = 50
}
In conf/nickserv.conf:
module
nickserv
{
name = "nickserv"
# not required if you are running ngIRCd with a higher nickname limit
# ("MaxNickLength") than 11 characters, but REQUIRED by default!
guestnickprefix = "G-"

View File

@@ -33,10 +33,6 @@
;AdminInfo2 = Location
;AdminEMail = admin@irc.server
# Text file which contains the ngIRCd help text. This file is required
# to display help texts when using the "HELP <cmd>" command.
;HelpFile = :DOCDIR:/Commands.txt
# Info text of the server. This will be shown by WHOIS and
# LINKS requests for example.
Info = Server Info Text
@@ -88,13 +84,6 @@
# to not yet (or no longer) connected servers.
;ConnectRetry = 60
# Number of seconds after which the whole daemon should shutdown when
# no connections are left active after handling at least one client
# (0: never, which is the default).
# This can be useful for testing or when ngIRCd is started using
# "socket activation" with systemd(8), for example.
;IdleTimeout = 0
# Maximum number of simultaneous in- and outbound connections the
# server is allowed to accept (0: unlimited):
;MaxConnections = 0
@@ -128,12 +117,6 @@
# behavior of ngIRCd. If you want to get started quickly, you most
# probably don't have to make changes here -- they are all optional.
# List of allowed channel types (channel prefixes) for newly created
# channels on the local server. By default, all supported channel
# types are allowed. Set this variable to the empty string to disallow
# creation of new channels by local clients at all.
;AllowedChannelTypes = #&+
# Are remote IRC operators allowed to control this server, e.g.
# use commands like CONNECT, SQUIT, DIE, ...?
;AllowRemoteOper = no
@@ -165,12 +148,7 @@
;ConnectIPv6 = yes
;ConnectIPv4 = yes
# Default user mode(s) to set on new local clients. Please note that
# only modes can be set that the client could set on itself, you can't
# set "a" (away) or "o" (IRC Op), for example! Default: none.
;DefaultUserModes = i
# Do DNS lookups when a client connects to the server.
# Do any DNS lookups when a client connects to the server.
;DNS = yes
# Do IDENT lookups if ngIRCd has been compiled with support for it.
@@ -178,10 +156,6 @@
# prepended to their user name.
;Ident = yes
# Directory containing configuration snippets (*.conf), that should
# be read in after parsing this configuration file.
;IncludeDir = :ETCDIR:/conf.d
# Enhance user privacy slightly (useful for IRC server on TOR or I2P)
# by censoring some information like idle time, logon time, etc.
;MorePrivacy = no
@@ -220,6 +194,9 @@
# character prepended to their respective user names!
;PAMIsOptional = no
# Allow Pre-Defined Channels only (see Section [Channels])
;PredefChannelsOnly = no
# Let ngIRCd send an "authentication PING" when a new client connects,
# and register this client only after receiving the corresponding
# "PONG" reply.
@@ -248,15 +225,6 @@
# SSL Server Key Certificate
;CertFile = :ETCDIR:/ssl/server-cert.pem
# Select cipher suites allowed for SSL/TLS connections. This defaults
# to HIGH:!aNULL:@STRENGTH (OpenSSL) or SECURE128 (GnuTLS).
# See 'man 1ssl ciphers' (OpenSSL) or 'man 3 gnutls_priority_init'
# (GnuTLS) for details.
# For OpenSSL:
;CipherList = HIGH:!aNULL:@STRENGTH
# For GnuTLS:
;CipherList = SECURE128
# Diffie-Hellman parameters
;DHFile = :ETCDIR:/ssl/dhparams.pem

View File

@@ -16,55 +16,106 @@
# Project related configuration options
#---------------------------------------------------------------------------
DOXYFILE_ENCODING = UTF-8
# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
# by quotes) that should identify the project.
PROJECT_NAME = ngIRCd
PROJECT_BRIEF = "Lightweight Internet Relay Chat server"
PROJECT_LOGO = "../../contrib/ngIRCd-Logo.gif"
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
# base path where the generated documentation will be put.
# If a relative path is entered, it will be relative to the location
# where doxygen was started. If left blank the current directory will be used.
OUTPUT_DIRECTORY = .
# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
# can be used to strip a user-defined part of the path. Stripping is
# only done if one of the specified strings matches the left-hand part of
# the path. The tag can be used to show relative paths in the file list.
# If left blank the directory from which doxygen is run is used as the
# path to strip.
STRIP_FROM_PATH = ../..
JAVADOC_AUTOBRIEF = YES
OPTIMIZE_OUTPUT_FOR_C = YES
TYPEDEF_HIDES_STRUCT = YES
# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
# will interpret the first line (until the first dot) of a JavaDoc-style
# comment as the brief description. If set to NO, the JavaDoc
# comments will behave just like the Qt-style comments (thus requiring an
# explicit @brief command for a brief description.
TAB_SIZE = 8
JAVADOC_AUTOBRIEF = YES
# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
# sources only. Doxygen will then generate output that is more tailored for C.
# For instance, some of the names that are used will be different. The list
# of all members will be omitted, etc.
OPTIMIZE_OUTPUT_FOR_C = YES
#---------------------------------------------------------------------------
# Build related configuration options
#---------------------------------------------------------------------------
# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
# documentation are documented, even if no documentation was available.
# Private class members and static file members will be hidden unless
# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
EXTRACT_ALL = YES
# If the EXTRACT_STATIC tag is set to YES all static members of a file
# will be included in the documentation.
EXTRACT_STATIC = YES
# If the sources in your project are distributed over multiple directories
# then setting the SHOW_DIRECTORIES tag to YES will show the directory
# hierarchy in the documentation. The default is NO.
SHOW_DIRECTORIES = YES
#---------------------------------------------------------------------------
# configuration options related to warning and progress messages
#---------------------------------------------------------------------------
QUIET = NO
WARNINGS = YES
WARN_IF_UNDOCUMENTED = YES
WARN_IF_DOC_ERROR = YES
WARN_NO_PARAMDOC = YES
#---------------------------------------------------------------------------
# configuration options related to the input files
#---------------------------------------------------------------------------
# The INPUT tag can be used to specify the files and/or directories that
# contain documented source files. You may enter file names like "myfile.cpp"
# or directories like "/usr/src/myproject". Separate the files or directories
# with spaces.
INPUT = ../../src
INPUT_ENCODING = UTF-8
# The RECURSIVE tag can be used to turn specify whether or not subdirectories
# should be searched for input files as well. Possible values are YES and NO.
# If left blank NO is used.
RECURSIVE = YES
#---------------------------------------------------------------------------
# configuration options related to source browsing
#---------------------------------------------------------------------------
# If the SOURCE_BROWSER tag is set to YES then a list of source files will
# be generated. Documented entities will be cross-referenced with these sources.
# Note: To get rid of all source code in the generated output, make sure also
# VERBATIM_HEADERS is set to NO.
SOURCE_BROWSER = YES
# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
# doxygen to hide any special comment blocks from generated source code
# fragments. Normal C and C++ comments will always remain visible.
STRIP_CODE_COMMENTS = NO
# If the REFERENCED_BY_RELATION tag is set to YES then for each documented
# function all documented functions referencing it will be listed.
REFERENCED_BY_RELATION = YES
# If the REFERENCES_RELATION tag is set to YES then for each documented
# function all documented entities called/used by that function will be listed.
REFERENCES_RELATION = YES
#---------------------------------------------------------------------------
@@ -72,7 +123,19 @@ REFERENCES_RELATION = YES
#---------------------------------------------------------------------------
GENERATE_HTML = YES
# The HTML_FOOTER tag can be used to specify a personal HTML footer for each
# generated HTML page. If it is left blank doxygen will generate a standard
# footer.
HTML_FOOTER = footer.inc.html
# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
# documentation will contain sections that can be hidden and shown after the
# page has loaded. For this to work a browser that supports JavaScript and
# DHTML is required (for instance Mozilla 1.0+, Firefox Netscape 6.0+,
# Internet explorer 5.0+, Konqueror, or Safari).
HTML_DYNAMIC_SECTIONS = YES
GENERATE_DOCSET = NO
@@ -88,6 +151,14 @@ GENERATE_PERLMOD = NO
# Configuration options related to the preprocessor
#---------------------------------------------------------------------------
# The PREDEFINED tag can be used to specify one or more macro names that
# are defined before the preprocessor is started (similar to the -D option of
# gcc). The argument of the tag is a list of macros of the form: name
# or name=definition (no spaces). If the definition and the = are
# omitted =1 is assumed. To prevent a macro definition from being
# undefined via #undef or recursively expanded use the := operator
# instead of the = operator.
PREDEFINED = DEBUG ZLIB PAM ZEROCONF CONN_MODULE __client_c__
# -eof-

View File

@@ -1,6 +1,6 @@
<hr class="footer">
<p style="text-align: center">
<p>
ngIRCd
<a href="http://ngircd.barton.de/">Homepage</a>,
<a href="http://ngircd.barton.de/cgi-bin/gitweb.cgi?p=ngircd.git">GIT-Repository</a>,

View File

@@ -1,7 +1,7 @@
.\"
.\" ngircd(8) manual page template
.\"
.TH ngircd 8 "Oct 2013" ngIRCd "ngIRCd Manual"
.TH ngircd 8 "Oct 2012" ngIRCd "ngIRCd Manual"
.SH NAME
ngIRCd \- the "next generation" IRC daemon
.SH SYNOPSIS
@@ -23,15 +23,13 @@ which is a little bit exaggerated:
.IR "lightweight Internet Relay Chat server"
most probably would have been a better name :-)
.PP
Currently supported platforms include AIX, A/UX, FreeBSD, HP-UX, Hurd, IRIX,
Linux, Mac OS X, Minix, NetBSD, OpenBSD, Solaris, and Windows with Cygwin.
Currently supported platforms include AIX, A/UX, FreeBSD, HP-UX, IRIX,
Linux, Mac OS X, NetBSD, OpenBSD, Solaris, and Windows with Cygwin.
.PP
As ngIRCd relies on UNIX standards and uses GNU automake and GNU autoconf
there are good chances that it also supports other UNIX-based operating
systems as well.
.PP
By default ngIRCd logs diagnostic and informational messages using the syslog
mechanism, or writes directly to the console when running in the foreground
(see below).
systems as well. By default, ngIRCd writes diagnostic and informational
messages using the syslog mechanism.
.SH OPTIONS
The default behavior of
.BR ngircd

View File

@@ -1,7 +1,7 @@
.\"
.\" ngircd.conf(5) manual page template
.\"
.TH ngircd.conf 5 "Oct 2013" ngIRCd "ngIRCd Manual"
.TH ngircd.conf 5 "Nov 2012" ngIRCd "ngIRCd Manual"
.SH NAME
ngircd.conf \- configuration file of ngIRCd
.SH SYNOPSIS
@@ -101,12 +101,6 @@ IRC network and must contain at least one dot (".") character.
Information about the server and the administrator, used by the ADMIN
command. This information is not required by the server but by RFC!
.TP
\fBHelpFile\fR (string)
Text file which contains the ngIRCd help text. This file is required
to display help texts when using the "HELP <cmd>" command.
Please note: Changes made to this file take effect when ngircd starts up
or is instructed to re-read its configuration file.
.TP
\fBInfo\fR (string)
Info text of the server. This will be shown by WHOIS and LINKS requests for
example.
@@ -133,8 +127,8 @@ if ngIRCd is using PAM!
.TP
\fBPidFile\fR (string)
This tells ngIRCd to write its current process ID to a file. Note that the
"PID file" is written AFTER chroot and switching the user ID, e.g. the directory
the file resides in must be writable by the ngIRCd user and exist in the
pidfile is written AFTER chroot and switching the user ID, e.g. the directory
the pidfile resides in must be writable by the ngIRCd user and exist in the
chroot directory (if configured, see above).
.TP
\fBPorts\fR (list of numbers)
@@ -170,12 +164,6 @@ should be safe, but it is wise to double-check :-)
The server tries every <ConnectRetry> seconds to establish a link to not yet
(or no longer) connected servers. Default: 60.
.TP
\fBIdleTimeout\fR (number)
Number of seconds after which the whole daemon should shutdown when no
connections are left active after handling at least one client (0: never). This
can be useful for testing or when ngIRCd is started using "socket activation"
with systemd(8), for example. Default: 0.
.TP
\fBMaxConnections\fR (number)
Maximum number of simultaneous in- and outbound connections the server is
allowed to accept (0: unlimited). Default: 0.
@@ -209,12 +197,6 @@ Optional features and configuration options to further tweak the behavior of
ngIRCd. If you want to get started quickly, you most probably don't have to
make changes here -- they are all optional.
.TP
\fBAllowedChannelTypes\fR (string)
List of allowed channel types (channel prefixes) for newly created channels
on the local server. By default, all supported channel types are allowed.
Set this variable to the empty string to disallow creation of new channels
by local clients at all. Default: #&+
.TP
\fBAllowRemoteOper\fR (boolean)
Are IRC operators connected to remote servers allowed to control this server,
e.g. are they allowed to use administrative commands like CONNECT, DIE,
@@ -258,12 +240,6 @@ Set this to no if you do not want ngIRCd to connect to other IRC servers using
the IPv6 protocol.
Default: yes.
.TP
\fBDefaultUserModes\fR (string)
Default user mode(s) to set on new local clients. Please note that only modes
can be set that the client could set on itself, you can't set "a" (away) or
"o" (IRC Op), for example!
Default: none.
.TP
\fBDNS\fR (boolean)
If set to false, ngIRCd will not make any DNS lookups when clients connect.
If you configure the daemon to connect to other servers, ngIRCd may still
@@ -277,11 +253,6 @@ Users identified using IDENT are registered without the "~" character
prepended to their user name.
Default: yes.
.TP
.TP
\fBIncludeDir\fR (string)
Directory containing configuration snippets (*.conf), that should be read in
after parsing the current configuration file.
Default: none.
\fBMorePrivacy\fR (boolean)
This will cause ngIRCd to censor user idle time, logon time as well as the
part/quit messages (that are sometimes used to inform everyone about which
@@ -331,6 +302,12 @@ able to distinguish between Ident'ified and PAM-authenticated users: both
don't have a "~" character prepended to their respective user names!
Default: no.
.TP
\fBPredefChannelsOnly\fR (boolean)
If enabled, no new channels can be created. Useful if you do not want to have
other channels than those defined in [Channel] sections in the configuration
file on this server.
Default: no.
.TP
\fBRequireAuthPing\fR (boolean)
Let ngIRCd send an "authentication PING" when a new client connects, and
register this client only after receiving the corresponding "PONG" reply.
@@ -366,12 +343,6 @@ when it is compiled with support for SSL using OpenSSL or GnuTLS!
\fBCertFile\fR (string)
SSL Certificate file of the private server key.
.TP
\fBCipherList\fR (string)
Select cipher suites allowed for SSL/TLS connections. This defaults to
"HIGH:!aNULL:@STRENGTH" (OpenSSL) or "SECURE128" (GnuTLS).
Please see 'man 1ssl ciphers' (OpenSSL) and 'man 3 gnutls_priority_init'
(GnuTLS) for details.
.TP
\fBDHFile\fR (string)
Name of the Diffie-Hellman Parameter file. Can be created with GnuTLS
"certtool \-\-generate-dh-params" or "openssl dhparam". If this file is not

View File

@@ -23,7 +23,7 @@
GLOBAL bool
ng_ipaddr_init(ng_ipaddr_t *addr, const char *ip_str, UINT16 port)
{
#ifdef HAVE_WORKING_GETADDRINFO
#ifdef HAVE_GETADDRINFO
int ret;
char portstr[64];
struct addrinfo *res0;

View File

@@ -47,7 +47,6 @@ typedef struct NG_IP_ADDR_DONTUSE ng_ipaddr_t;
static inline int
ng_ipaddr_af(const ng_ipaddr_t *a)
{
assert(a != NULL);
#ifdef WANT_IPV6
return a->sa.sa_family;
#else
@@ -60,7 +59,6 @@ ng_ipaddr_af(const ng_ipaddr_t *a)
static inline socklen_t
ng_ipaddr_salen(const ng_ipaddr_t *a)
{
assert(a != NULL);
#ifdef WANT_IPV6
assert(a->sa.sa_family == AF_INET || a->sa.sa_family == AF_INET6);
if (a->sa.sa_family == AF_INET6)
@@ -77,14 +75,11 @@ ng_ipaddr_getport(const ng_ipaddr_t *a)
#ifdef WANT_IPV6
int af = a->sa.sa_family;
assert(a != NULL);
assert(af == AF_INET || af == AF_INET6);
if (af == AF_INET6)
return ntohs(a->sin6.sin6_port);
#endif /* WANT_IPV6 */
assert(a != NULL);
assert(a->sin4.sin_family == AF_INET);
return ntohs(a->sin4.sin_port);
}
@@ -114,15 +109,12 @@ GLOBAL bool ng_ipaddr_tostr_r PARAMS((const ng_ipaddr_t *addr, char *dest));
static inline const char*
ng_ipaddr_tostr(const ng_ipaddr_t *addr)
{
assert(addr != NULL);
return inet_ntoa(addr->sin4.sin_addr);
}
static inline bool
ng_ipaddr_tostr_r(const ng_ipaddr_t *addr, char *d)
{
assert(addr != NULL);
assert(d != NULL);
strlcpy(d, inet_ntoa(addr->sin4.sin_addr), NG_INET_ADDRSTRLEN);
return true;
}

View File

@@ -86,7 +86,6 @@ noinst_HEADERS = \
irc-encoding.h \
irc-info.h \
irc-login.h \
irc-macros.h \
irc-metadata.h \
irc-mode.h \
irc-op.h \

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2013 Alexander Barton (alex@barton.de) and Contributors.
* Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
*
* 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
@@ -131,11 +131,11 @@ Channel_InitPredefined( void )
new_chan = Channel_Create(conf_chan->name);
if (!new_chan) {
Log(LOG_ERR, "Can't create pre-defined channel \"%s\"!",
Log(LOG_ERR, "Can't create pre-defined channel \"%s\"",
conf_chan->name);
continue;
}
Log(LOG_INFO, "Created pre-defined channel \"%s\".",
Log(LOG_INFO, "Created pre-defined channel \"%s\"",
conf_chan->name);
Channel_ModeAdd(new_chan, 'P');
@@ -223,7 +223,7 @@ Channel_Join( CLIENT *Client, const char *Name )
/* Check that the channel name is valid */
if (! Channel_IsValidName(Name)) {
IRC_WriteErrClient(Client, ERR_NOSUCHCHANNEL_MSG,
IRC_WriteStrClient(Client, ERR_NOSUCHCHANNEL_MSG,
Client_ID(Client), Name);
return false;
}
@@ -268,14 +268,14 @@ Channel_Part(CLIENT * Client, CLIENT * Origin, const char *Name, const char *Rea
/* Check that specified channel exists */
chan = Channel_Search(Name);
if (!chan) {
IRC_WriteErrClient(Client, ERR_NOSUCHCHANNEL_MSG,
IRC_WriteStrClient(Client, ERR_NOSUCHCHANNEL_MSG,
Client_ID(Client), Name);
return false;
}
/* Check that the client is in the channel */
if (!Get_Cl2Chan(chan, Client)) {
IRC_WriteErrClient(Client, ERR_NOTONCHANNEL_MSG,
IRC_WriteStrClient(Client, ERR_NOTONCHANNEL_MSG,
Client_ID(Client), Name);
return false;
}
@@ -299,6 +299,7 @@ Channel_Kick(CLIENT *Peer, CLIENT *Target, CLIENT *Origin, const char *Name,
const char *Reason )
{
CHANNEL *chan;
char *ptr, *target_modes;
bool can_kick = false;
assert(Peer != NULL);
@@ -309,9 +310,9 @@ Channel_Kick(CLIENT *Peer, CLIENT *Target, CLIENT *Origin, const char *Name,
/* Check that channel exists */
chan = Channel_Search( Name );
if (!chan) {
IRC_WriteErrClient(Origin, ERR_NOSUCHCHANNEL_MSG,
Client_ID(Origin), Name);
if( ! chan )
{
IRC_WriteStrClient( Origin, ERR_NOSUCHCHANNEL_MSG, Client_ID( Origin ), Name );
return;
}
@@ -319,15 +320,15 @@ Channel_Kick(CLIENT *Peer, CLIENT *Target, CLIENT *Origin, const char *Name,
Client_Type(Origin) != CLIENT_SERVICE) {
/* Check that user is on the specified channel */
if (!Channel_IsMemberOf(chan, Origin)) {
IRC_WriteErrClient(Origin, ERR_NOTONCHANNEL_MSG,
Client_ID(Origin), Name);
IRC_WriteStrClient( Origin, ERR_NOTONCHANNEL_MSG,
Client_ID(Origin), Name);
return;
}
}
/* Check that the client to be kicked is on the specified channel */
if (!Channel_IsMemberOf(chan, Target)) {
IRC_WriteErrClient(Origin, ERR_USERNOTINCHANNEL_MSG,
IRC_WriteStrClient(Origin, ERR_USERNOTINCHANNEL_MSG,
Client_ID(Origin), Client_ID(Target), Name );
return;
}
@@ -335,43 +336,55 @@ Channel_Kick(CLIENT *Peer, CLIENT *Target, CLIENT *Origin, const char *Name,
if(Client_Type(Peer) == CLIENT_USER) {
/* Channel mode 'Q' and user mode 'q' on target: nobody but
* IRC Operators and servers can kick the target user */
if ((Channel_HasMode(chan, 'Q')
if ((strchr(Channel_Modes(chan), 'Q')
|| Client_HasMode(Target, 'q')
|| Client_Type(Target) == CLIENT_SERVICE)
&& !Client_HasMode(Origin, 'o')) {
IRC_WriteErrClient(Origin, ERR_KICKDENY_MSG,
IRC_WriteStrClient(Origin, ERR_KICKDENY_MSG,
Client_ID(Origin), Name,
Client_ID(Target));
return;
}
/* Check if client has the rights to kick target */
/* Owner can kick everyone */
if (Channel_UserHasMode(chan, Peer, 'q'))
can_kick = true;
/* Admin can't kick owner */
else if (Channel_UserHasMode(chan, Peer, 'a') &&
!Channel_UserHasMode(chan, Target, 'q'))
can_kick = true;
/* Op can't kick owner | admin */
else if (Channel_UserHasMode(chan, Peer, 'o') &&
!Channel_UserHasMode(chan, Target, 'q') &&
!Channel_UserHasMode(chan, Target, 'a'))
can_kick = true;
/* Half Op can't kick owner | admin | op */
else if (Channel_UserHasMode(chan, Peer, 'h') &&
!Channel_UserHasMode(chan, Target, 'q') &&
!Channel_UserHasMode(chan, Target, 'a') &&
!Channel_UserHasMode(chan, Target, 'o'))
can_kick = true;
ptr = Channel_UserModes(chan, Peer);
target_modes = Channel_UserModes(chan, Target);
while(*ptr) {
/* Owner can kick everyone */
if ( *ptr == 'q') {
can_kick = true;
break;
}
/* Admin can't kick owner */
if ( *ptr == 'a' ) {
if (!strchr(target_modes, 'q')) {
can_kick = true;
break;
}
}
/* Op can't kick owner | admin */
if ( *ptr == 'o' ) {
if (!strchr(target_modes, 'q') &&
!strchr(target_modes, 'a')) {
can_kick = true;
break;
}
}
/* Half Op can't kick owner | admin | op */
if ( *ptr == 'h' ) {
if (!strchr(target_modes, 'q') &&
!strchr(target_modes, 'a') &&
!strchr(target_modes, 'o')) {
can_kick = true;
break;
}
}
ptr++;
}
if(!can_kick) {
IRC_WriteErrClient(Origin, ERR_CHANOPPRIVTOOLOW_MSG,
Client_ID(Origin), Name);
IRC_WriteStrClient(Origin, ERR_CHANOPPRIVTOOLOW_MSG,
Client_ID(Origin), Name);
return;
}
}
@@ -420,7 +433,7 @@ Channel_CountVisible (CLIENT *Client)
c = My_Channels;
while(c) {
if (Client) {
if (!Channel_HasMode(c, 's')
if (!strchr(Channel_Modes(c), 's')
|| Channel_IsMemberOf(c, Client))
count++;
} else
@@ -486,14 +499,6 @@ Channel_Modes( CHANNEL *Chan )
} /* Channel_Modes */
GLOBAL bool
Channel_HasMode( CHANNEL *Chan, char Mode )
{
assert( Chan != NULL );
return strchr( Chan->modes, Mode ) != NULL;
} /* Channel_HasMode */
GLOBAL char *
Channel_Key( CHANNEL *Chan )
{
@@ -631,7 +636,7 @@ Channel_ModeAdd( CHANNEL *Chan, char Mode )
assert( Chan != NULL );
x[0] = Mode; x[1] = '\0';
if( ! Channel_HasMode( Chan, x[0] ))
if( ! strchr( Chan->modes, x[0] ))
{
/* Channel does not have this mode yet, set it */
strlcat( Chan->modes, x, sizeof( Chan->modes ));
@@ -740,13 +745,6 @@ Channel_UserModes( CHANNEL *Chan, CLIENT *Client )
} /* Channel_UserModes */
GLOBAL bool
Channel_UserHasMode( CHANNEL *Chan, CLIENT *Client, char Mode )
{
return strchr(Channel_UserModes(Chan, Client), Mode) != NULL;
} /* Channel_UserHasMode */
GLOBAL bool
Channel_IsMemberOf( CHANNEL *Chan, CLIENT *Client )
{
@@ -875,15 +873,15 @@ Can_Send_To_Channel(CHANNEL *Chan, CLIENT *From)
if (Channel_IsMemberOf(Chan, From)) {
is_member = true;
if (Channel_UserHasMode(Chan, From, 'v'))
if (strchr(Channel_UserModes(Chan, From), 'v'))
has_voice = true;
if (Channel_UserHasMode(Chan, From, 'h'))
if (strchr(Channel_UserModes(Chan, From), 'h'))
is_halfop = true;
if (Channel_UserHasMode(Chan, From, 'o'))
if (strchr(Channel_UserModes(Chan, From), 'o'))
is_op = true;
if (Channel_UserHasMode(Chan, From, 'a'))
if (strchr(Channel_UserModes(Chan, From), 'a'))
is_chanadmin = true;
if (Channel_UserHasMode(Chan, From, 'q'))
if (strchr(Channel_UserModes(Chan, From), 'q'))
is_owner = true;
}
@@ -893,17 +891,17 @@ Can_Send_To_Channel(CHANNEL *Chan, CLIENT *From)
* If channel mode n set: non-members cannot send to channel.
* If channel mode m set: need voice.
*/
if (Channel_HasMode(Chan, 'n') && !is_member)
if (strchr(Channel_Modes(Chan), 'n') && !is_member)
return false;
if (Channel_HasMode(Chan, 'M') && !Client_HasMode(From, 'R')
if (strchr(Channel_Modes(Chan), 'M') && !Client_HasMode(From, 'R')
&& !Client_HasMode(From, 'o'))
return false;
if (has_voice || is_halfop || is_op || is_chanadmin || is_owner)
return true;
if (Channel_HasMode(Chan, 'm'))
if (strchr(Channel_Modes(Chan), 'm'))
return false;
if (Lists_Check(&Chan->list_excepts, From))
@@ -920,20 +918,19 @@ Channel_Write(CHANNEL *Chan, CLIENT *From, CLIENT *Client, const char *Command,
if (!Can_Send_To_Channel(Chan, From)) {
if (! SendErrors)
return CONNECTED; /* no error, see RFC 2812 */
if (Channel_HasMode(Chan, 'M'))
return IRC_WriteErrClient(From, ERR_NEEDREGGEDNICK_MSG,
if (strchr(Channel_Modes(Chan), 'M'))
return IRC_WriteStrClient(From, ERR_NEEDREGGEDNICK_MSG,
Client_ID(From), Channel_Name(Chan));
else
return IRC_WriteErrClient(From, ERR_CANNOTSENDTOCHAN_MSG,
return IRC_WriteStrClient(From, ERR_CANNOTSENDTOCHAN_MSG,
Client_ID(From), Channel_Name(Chan));
}
if (Client_Conn(From) > NONE)
Conn_UpdateIdle(Client_Conn(From));
IRC_WriteStrChannelPrefix(Client, Chan, From, true, "%s %s :%s",
Command, Channel_Name(Chan), Text);
return CONNECTED;
return IRC_WriteStrChannelPrefix(Client, Chan, From, true,
"%s %s :%s", Command, Channel_Name(Chan), Text);
}
@@ -1092,7 +1089,7 @@ Remove_Client( int Type, CHANNEL *Chan, CLIENT *Client, CLIENT *Origin, const ch
}
/* When channel is empty and is not pre-defined, delete */
if( ! Channel_HasMode( Chan, 'P' ))
if( ! strchr( Channel_Modes( Chan ), 'P' ))
{
if( ! Get_First_Cl2Chan( NULL, Chan )) Delete_Channel( Chan );
}
@@ -1220,7 +1217,7 @@ Channel_CheckKey(CHANNEL *Chan, CLIENT *Client, const char *Key)
assert(Client != NULL);
assert(Key != NULL);
if (!Channel_HasMode(Chan, 'k'))
if (!strchr(Chan->modes, 'k'))
return true;
if (*Key == '\0')
return false;

View File

@@ -79,6 +79,7 @@ GLOBAL unsigned long Channel_MemberCount PARAMS(( CHANNEL *Chan ));
GLOBAL int Channel_CountForUser PARAMS(( CLIENT *Client ));
GLOBAL const char *Channel_Name PARAMS(( const CHANNEL *Chan ));
GLOBAL char *Channel_Modes PARAMS(( CHANNEL *Chan ));
GLOBAL char *Channel_Topic PARAMS(( CHANNEL *Chan ));
GLOBAL char *Channel_Key PARAMS(( CHANNEL *Chan ));
GLOBAL unsigned long Channel_MaxUsers PARAMS(( CHANNEL *Chan ));
@@ -105,12 +106,9 @@ GLOBAL bool Channel_IsValidName PARAMS(( const char *Name ));
GLOBAL bool Channel_ModeAdd PARAMS(( CHANNEL *Chan, char Mode ));
GLOBAL bool Channel_ModeDel PARAMS(( CHANNEL *Chan, char Mode ));
GLOBAL bool Channel_HasMode PARAMS(( CHANNEL *Chan, char Mode ));
GLOBAL char *Channel_Modes PARAMS(( CHANNEL *Chan ));
GLOBAL bool Channel_UserModeAdd PARAMS(( CHANNEL *Chan, CLIENT *Client, char Mode ));
GLOBAL bool Channel_UserModeDel PARAMS(( CHANNEL *Chan, CLIENT *Client, char Mode ));
GLOBAL bool Channel_UserHasMode PARAMS(( CHANNEL *Chan, CLIENT *Client, char Mode ));
GLOBAL char *Channel_UserModes PARAMS(( CHANNEL *Chan, CLIENT *Client ));
GLOBAL bool Channel_IsMemberOf PARAMS(( CHANNEL *Chan, CLIENT *Client ));

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2014 Alexander Barton (alex@barton.de) and Contributors.
* Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
*
* 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
@@ -33,6 +33,8 @@
struct list_head My_Classes[CLASS_COUNT];
char Reject_Reason[COMMAND_LEN];
GLOBAL void
Class_Init(void)
{
@@ -47,31 +49,32 @@ Class_Exit(void)
for (i = 0; i < CLASS_COUNT; Lists_Free(&My_Classes[i++]));
}
GLOBAL bool
Class_GetMemberReason(const int Class, CLIENT *Client, char *reason, size_t len)
GLOBAL char *
Class_GetMemberReason(const int Class, CLIENT *Client)
{
char str[COMMAND_LEN];
char *reason;
assert(Class < CLASS_COUNT);
assert(Client != NULL);
strlcpy(str, "listed", sizeof(str));
reason = Lists_CheckReason(&My_Classes[Class], Client);
if (!reason)
return NULL;
if (!Lists_CheckReason(&My_Classes[Class], Client, str, sizeof(str)))
return false;
if (!*reason)
reason = "listed";
switch(Class) {
case CLASS_GLINE:
snprintf(reason, len, "\"%s\" (G-Line)", str);
break;
snprintf(Reject_Reason, sizeof(Reject_Reason),
"\"%s\" (G-Line)", reason);
return Reject_Reason;
case CLASS_KLINE:
snprintf(reason, len, "\"%s\" (K-Line)", str);
break;
default:
snprintf(reason, len, "%s", str);
break;
snprintf(Reject_Reason, sizeof(Reject_Reason),
"\"%s\" (K-Line)", reason);
return Reject_Reason;
}
return true;
return reason;
}
/**
@@ -85,13 +88,15 @@ Class_GetMemberReason(const int Class, CLIENT *Client, char *reason, size_t len)
GLOBAL bool
Class_HandleServerBans(CLIENT *Client)
{
char reject[COMMAND_LEN];
char *rejectptr;
assert(Client != NULL);
if (Class_GetMemberReason(CLASS_GLINE, Client, reject, sizeof(reject)) ||
Class_GetMemberReason(CLASS_KLINE, Client, reject, sizeof(reject))) {
Client_Reject(Client, reject, true);
rejectptr = Class_GetMemberReason(CLASS_GLINE, Client);
if (!rejectptr)
rejectptr = Class_GetMemberReason(CLASS_KLINE, Client);
if (rejectptr) {
Client_Reject(Client, rejectptr, true);
return DISCONNECTED;
}
@@ -100,30 +105,24 @@ Class_HandleServerBans(CLIENT *Client)
GLOBAL bool
Class_AddMask(const int Class, const char *Pattern, time_t ValidUntil,
Class_AddMask(const int Class, const char *Mask, time_t ValidUntil,
const char *Reason)
{
char mask[MASK_LEN];
assert(Class < CLASS_COUNT);
assert(Pattern != NULL);
assert(Mask != NULL);
assert(Reason != NULL);
Lists_MakeMask(Pattern, mask, sizeof(mask));
return Lists_Add(&My_Classes[Class], mask,
return Lists_Add(&My_Classes[Class], Lists_MakeMask(Mask),
ValidUntil, Reason);
}
GLOBAL void
Class_DeleteMask(const int Class, const char *Pattern)
Class_DeleteMask(const int Class, const char *Mask)
{
char mask[MASK_LEN];
assert(Class < CLASS_COUNT);
assert(Pattern != NULL);
assert(Mask != NULL);
Lists_MakeMask(Pattern, mask, sizeof(mask));
Lists_Del(&My_Classes[Class], mask);
Lists_Del(&My_Classes[Class], Lists_MakeMask(Mask));
}
GLOBAL struct list_head *

View File

@@ -25,12 +25,11 @@
GLOBAL void Class_Init PARAMS((void));
GLOBAL void Class_Exit PARAMS((void));
GLOBAL bool Class_AddMask PARAMS((const int Class, const char *Pattern,
GLOBAL bool Class_AddMask PARAMS((const int Class, const char *Mask,
const time_t ValidUntil, const char *Reason));
GLOBAL void Class_DeleteMask PARAMS((const int Class, const char *Pattern));
GLOBAL void Class_DeleteMask PARAMS((const int Class, const char *Mask));
GLOBAL bool Class_GetMemberReason PARAMS((const int Class, CLIENT *Client,
char *reason, size_t len));
GLOBAL char *Class_GetMemberReason PARAMS((const int Class, CLIENT *Client));
GLOBAL bool Class_HandleServerBans PARAMS((CLIENT *Client));
GLOBAL struct list_head *Class_GetList PARAMS((const int Class));

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2013 Alexander Barton (alex@barton.de) and Contributors.
* Copyright (c)2001-2012 Alexander Barton (alex@barton.de)
*
* 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
@@ -41,7 +41,6 @@
#include "hash.h"
#include "irc-write.h"
#include "log.h"
#include "match.h"
#include "messages.h"
#include <exp.h>
@@ -62,8 +61,6 @@ static CLIENT *New_Client_Struct PARAMS(( void ));
static void Generate_MyToken PARAMS(( CLIENT *Client ));
static void Adjust_Counters PARAMS(( CLIENT *Client ));
static void Free_Client PARAMS(( CLIENT **Client ));
static CLIENT *Init_New_Client PARAMS((CONN_ID Idx, CLIENT *Introducer,
CLIENT *TopServer, int Type, const char *ID,
const char *User, const char *Hostname, const char *Info,
@@ -89,7 +86,7 @@ Client_Init( void )
exit( 1 );
}
/* Client structure for this server */
/* Client-Struktur dieses Servers */
This_Server->next = NULL;
This_Server->type = CLIENT_SERVER;
This_Server->conn_id = NONE;
@@ -122,15 +119,14 @@ Client_Exit( void )
cnt = 0;
c = My_Clients;
while(c) {
while( c )
{
cnt++;
next = (CLIENT *)c->next;
Free_Client(&c);
free( c );
c = next;
}
if (cnt)
Log(LOG_INFO, "Freed %d client structure%s.",
cnt, cnt == 1 ? "" : "s");
if( cnt ) Log( LOG_INFO, "Freed %d client structure%s.", cnt, cnt == 1 ? "" : "s" );
} /* Client_Exit */
@@ -220,8 +216,8 @@ Init_New_Client(CONN_ID Idx, CLIENT *Introducer, CLIENT *TopServer,
if (Type == CLIENT_SERVER)
Generate_MyToken(client);
if (Client_HasMode(client, 'a'))
client->away = strndup(DEFAULT_AWAY_MSG, CLIENT_AWAY_LEN - 1);
if (strchr(client->modes, 'a'))
strlcpy(client->away, DEFAULT_AWAY_MSG, sizeof(client->away));
client->next = (POINTER *)My_Clients;
My_Clients = client;
@@ -238,14 +234,14 @@ Client_Destroy( CLIENT *Client, const char *LogMsg, const char *FwdMsg, bool Sen
/* remove a client */
CLIENT *last, *c;
char msg[COMMAND_LEN];
char msg[LINE_LEN];
const char *txt;
assert( Client != NULL );
txt = LogMsg ? LogMsg : FwdMsg;
if (!txt)
txt = "Reason unknown";
if( LogMsg ) txt = LogMsg;
else txt = FwdMsg;
if( ! txt ) txt = "Reason unknown.";
/* netsplit message */
if( Client->type == CLIENT_SERVER ) {
@@ -285,15 +281,10 @@ Client_Destroy( CLIENT *Client, const char *LogMsg, const char *FwdMsg, bool Sen
Destroy_UserOrService(c, txt, FwdMsg, SendQuit);
else if( c->type == CLIENT_SERVER )
{
if (c != This_Server) {
if (c->conn_id != NONE)
Log(LOG_NOTICE|LOG_snotice,
"Server \"%s\" unregistered (connection %d): %s.",
c->id, c->conn_id, txt);
else
Log(LOG_NOTICE|LOG_snotice,
"Server \"%s\" unregistered: %s.",
c->id, txt);
if( c != This_Server )
{
if( c->conn_id != NONE ) Log( LOG_NOTICE|LOG_snotice, "Server \"%s\" unregistered (connection %d): %s", c->id, c->conn_id, txt );
else Log( LOG_NOTICE|LOG_snotice, "Server \"%s\" unregistered: %s", c->id, txt );
}
/* inform other servers */
@@ -305,23 +296,17 @@ Client_Destroy( CLIENT *Client, const char *LogMsg, const char *FwdMsg, bool Sen
}
else
{
if (c->conn_id != NONE) {
if (c->id[0])
Log(LOG_NOTICE,
"Client \"%s\" unregistered (connection %d): %s.",
c->id, c->conn_id, txt);
else
Log(LOG_NOTICE,
"Client unregistered (connection %d): %s.",
c->conn_id, txt);
if( c->conn_id != NONE )
{
if( c->id[0] ) Log( LOG_NOTICE, "Client \"%s\" unregistered (connection %d): %s", c->id, c->conn_id, txt );
else Log( LOG_NOTICE, "Client unregistered (connection %d): %s", c->conn_id, txt );
} else {
Log(LOG_WARNING,
"Unregistered unknown client \"%s\": %s",
c->id[0] ? c->id : "(No Nick)", txt);
Log(LOG_WARNING, "Unregistered unknown client \"%s\": %s",
c->id[0] ? c->id : "(No Nick)", txt );
}
}
Free_Client(&c);
free( c );
break;
}
last = c;
@@ -363,27 +348,6 @@ Client_SetHostname( CLIENT *Client, const char *Hostname )
} /* Client_SetHostname */
/**
* Set IP address to display for a client.
*
* @param Client The client.
* @param IPAText Textual representation of the IP address or NULL to unset.
*/
GLOBAL void
Client_SetIPAText(CLIENT *Client, const char *IPAText)
{
assert(Client != NULL);
if (Client->ipa_text)
free(Client->ipa_text);
if (*IPAText)
Client->ipa_text = strndup(IPAText, CLIENT_HOST_LEN - 1);
else
Client->ipa_text = NULL;
}
GLOBAL void
Client_SetID( CLIENT *Client, const char *ID )
{
@@ -476,22 +440,6 @@ Client_SetFlags( CLIENT *Client, const char *Flags )
} /* Client_SetFlags */
GLOBAL void
Client_SetAccountName(CLIENT *Client, const char *AccountName)
{
assert(Client != NULL);
if (Client->account_name)
free(Client->account_name);
if (*AccountName)
Client->account_name = strndup(AccountName,
CLIENT_NICK_LEN - 1);
else
Client->account_name = NULL;
}
GLOBAL void
Client_SetAway( CLIENT *Client, const char *Txt )
{
@@ -500,11 +448,7 @@ Client_SetAway( CLIENT *Client, const char *Txt )
assert( Client != NULL );
assert( Txt != NULL );
if (Client->away)
free(Client->away);
Client->away = strndup(Txt, CLIENT_AWAY_LEN - 1);
strlcpy( Client->away, Txt, sizeof( Client->away ));
LogDebug("%s \"%s\" is away: %s", Client_TypeText(Client),
Client_Mask(Client), Txt);
} /* Client_SetAway */
@@ -545,11 +489,19 @@ Client_SetIntroducer( CLIENT *Client, CLIENT *Introducer )
} /* Client_SetIntroducer */
GLOBAL void
Client_SetOperByMe( CLIENT *Client, bool OperByMe )
{
assert( Client != NULL );
Client->oper_by_me = OperByMe;
} /* Client_SetOperByMe */
GLOBAL bool
Client_ModeAdd( CLIENT *Client, char Mode )
{
/* Set Mode.
* If Client already had Mode, return false.
* If Client already alread had Mode, return false.
* If the Mode was newly set, return true.
*/
@@ -558,7 +510,7 @@ Client_ModeAdd( CLIENT *Client, char Mode )
assert( Client != NULL );
x[0] = Mode; x[1] = '\0';
if (!Client_HasMode(Client, x[0])) {
if (!strchr( Client->modes, x[0])) {
strlcat( Client->modes, x, sizeof( Client->modes ));
return true;
}
@@ -593,14 +545,13 @@ Client_ModeDel( CLIENT *Client, char Mode )
} /* Client_ModeDel */
/**
* Search CLIENT structure of a given nick name.
*
* @return Pointer to CLIENT structure or NULL if not found.
*/
GLOBAL CLIENT *
Client_Search( const char *Nick )
{
/* return Client-Structure that has the corresponding Nick.
* If none is found, return NULL.
*/
char search_id[CLIENT_ID_LEN], *ptr;
CLIENT *c = NULL;
UINT32 search_hash;
@@ -621,39 +572,7 @@ Client_Search( const char *Nick )
c = (CLIENT *)c->next;
}
return NULL;
}
/**
* Search first CLIENT structure matching a given mask of a server.
*
* The order of servers is arbitrary, but this function makes sure that the
* local server is always returned if the mask matches it.
*
* @return Pointer to CLIENT structure or NULL if no server could be found.
*/
GLOBAL CLIENT *
Client_SearchServer(const char *Mask)
{
CLIENT *c;
assert(Mask != NULL);
/* First check if mask matches the local server */
if (MatchCaseInsensitive(Mask, Client_ID(Client_ThisServer())))
return Client_ThisServer();
c = My_Clients;
while (c) {
if (Client_Type(c) == CLIENT_SERVER) {
/* This is a server: check if Mask matches */
if (MatchCaseInsensitive(Mask, c->id))
return c;
}
c = (CLIENT *)c->next;
}
return NULL;
}
} /* Client_Search */
/**
@@ -780,6 +699,8 @@ Client_HostnameCloaked(CLIENT *Client)
* Get (potentially cloaked) hostname of a client to display it to other users.
*
* If the client has not enabled cloaking, the real hostname is used.
* Please note that this function uses a global static buffer, so you can't
* nest invocations without overwriting earlier results!
*
* @param Client Pointer to client structure
* @return Pointer to client hostname
@@ -794,28 +715,13 @@ Client_HostnameDisplayed(CLIENT *Client)
return Client_Hostname(Client);
/* Use an already saved cloaked hostname, if there is one */
if (Client->cloaked)
if (Client->cloaked[0])
return Client->cloaked;
Client_UpdateCloakedHostname(Client, NULL, NULL);
return Client->cloaked;
}
GLOBAL const char *
Client_IPAText(CLIENT *Client)
{
assert(Client != NULL);
/* Not a local client? */
if (Client_Conn(Client) <= NONE)
return "0.0.0.0";
if (!Client->ipa_text)
return Conn_GetIPAInfo(Client_Conn(Client));
else
return Client->ipa_text;
}
/**
* Update (and generate, if necessary) the cloaked hostname of a client.
*
@@ -830,32 +736,25 @@ GLOBAL void
Client_UpdateCloakedHostname(CLIENT *Client, CLIENT *Origin,
const char *Hostname)
{
char Cloak_Buffer[CLIENT_HOST_LEN];
static char Cloak_Buffer[CLIENT_HOST_LEN];
assert(Client != NULL);
if (!Origin)
Origin = Client_ThisServer();
if (!Client->cloaked) {
Client->cloaked = malloc(CLIENT_HOST_LEN);
if (!Client->cloaked)
return;
}
if (!Hostname) {
/* Generate new cloaked hostname */
if (*Conf_CloakHostModeX) {
strlcpy(Cloak_Buffer, Client->host,
sizeof(Cloak_Buffer));
strlcpy(Cloak_Buffer, Client->host, CLIENT_HOST_LEN);
strlcat(Cloak_Buffer, Conf_CloakHostSalt,
sizeof(Cloak_Buffer));
snprintf(Client->cloaked, CLIENT_HOST_LEN,
CLIENT_HOST_LEN);
snprintf(Client->cloaked, sizeof(Client->cloaked),
Conf_CloakHostModeX, Hash(Cloak_Buffer));
} else
strlcpy(Client->cloaked, Client_ID(Client->introducer),
CLIENT_HOST_LEN);
sizeof(Client->cloaked));
} else
strlcpy(Client->cloaked, Hostname, CLIENT_HOST_LEN);
strlcpy(Client->cloaked, Hostname, sizeof(Client->cloaked));
LogDebug("Cloaked hostname of \"%s\" updated to \"%s\"",
Client_ID(Client), Client->cloaked);
@@ -881,6 +780,14 @@ Client_Flags( CLIENT *Client )
} /* Client_Flags */
GLOBAL bool
Client_OperByMe( CLIENT *Client )
{
assert( Client != NULL );
return Client->oper_by_me;
} /* Client_OperByMe */
GLOBAL int
Client_Hops( CLIENT *Client )
{
@@ -998,14 +905,6 @@ Client_HasMode( CLIENT *Client, char Mode )
} /* Client_HasMode */
GLOBAL bool
Client_HasFlag( CLIENT *Client, char Flag )
{
assert( Client != NULL );
return strchr( Client->flags, Flag ) != NULL;
} /* Client_HasFlag */
GLOBAL char *
Client_Away( CLIENT *Client )
{
@@ -1014,14 +913,6 @@ Client_Away( CLIENT *Client )
} /* Client_Away */
GLOBAL char *
Client_AccountName(CLIENT *Client)
{
assert(Client != NULL);
return Client->account_name;
}
/**
* Make sure that a given nickname is valid.
*
@@ -1040,11 +931,11 @@ Client_CheckNick(CLIENT *Client, char *Nick)
if (!Client_IsValidNick(Nick)) {
if (strlen(Nick ) >= Conf_MaxNickLength)
IRC_WriteErrClient(Client, ERR_NICKNAMETOOLONG_MSG,
IRC_WriteStrClient(Client, ERR_NICKNAMETOOLONG_MSG,
Client_ID(Client), Nick,
Conf_MaxNickLength - 1);
else
IRC_WriteErrClient(Client, ERR_ERRONEUSNICKNAME_MSG,
IRC_WriteStrClient(Client, ERR_ERRONEUSNICKNAME_MSG,
Client_ID(Client), Nick);
return false;
}
@@ -1053,7 +944,7 @@ Client_CheckNick(CLIENT *Client, char *Nick)
&& Client_Type(Client) != CLIENT_SERVICE) {
/* Make sure that this isn't a restricted/forbidden nickname */
if (Conf_NickIsBlocked(Nick)) {
IRC_WriteErrClient(Client, ERR_FORBIDDENNICKNAME_MSG,
IRC_WriteStrClient(Client, ERR_FORBIDDENNICKNAME_MSG,
Client_ID(Client), Nick);
return false;
}
@@ -1061,7 +952,7 @@ Client_CheckNick(CLIENT *Client, char *Nick)
/* Nickname already registered? */
if (Client_Search(Nick)) {
IRC_WriteErrClient(Client, ERR_NICKNAMEINUSE_MSG,
IRC_WriteStrClient(Client, ERR_NICKNAMEINUSE_MSG,
Client_ID(Client), Nick);
return false;
}
@@ -1082,8 +973,7 @@ Client_CheckID( CLIENT *Client, char *ID )
/* ID too long? */
if (strlen(ID) > CLIENT_ID_LEN) {
IRC_WriteErrClient(Client, ERR_ERRONEUSNICKNAME_MSG,
Client_ID(Client), ID);
IRC_WriteStrClient(Client, ERR_ERRONEUSNICKNAME_MSG, Client_ID(Client), ID);
return false;
}
@@ -1181,8 +1071,7 @@ Client_OperCount( void )
c = My_Clients;
while( c )
{
if (c && c->type == CLIENT_USER && Client_HasMode(c, 'o' ))
cnt++;
if( c && ( c->type == CLIENT_USER ) && ( strchr( c->modes, 'o' ))) cnt++;
c = (CLIENT *)c->next;
}
return cnt;
@@ -1389,14 +1278,11 @@ MyCount( CLIENT_TYPE Type )
} /* MyCount */
/**
* Allocate and initialize new CLIENT strcuture.
*
* @return Pointer to CLIENT structure or NULL on error.
*/
static CLIENT *
New_Client_Struct( void )
{
/* Neue CLIENT-Struktur pre-initialisieren */
CLIENT *c;
c = (CLIENT *)malloc( sizeof( CLIENT ));
@@ -1410,34 +1296,14 @@ New_Client_Struct( void )
c->type = CLIENT_UNKNOWN;
c->conn_id = NONE;
c->oper_by_me = false;
c->hops = -1;
c->token = -1;
c->mytoken = -1;
return c;
}
} /* New_Client */
/**
* Free a CLIENT structure and its member variables.
*/
static void
Free_Client(CLIENT **Client)
{
assert(Client != NULL);
assert(*Client != NULL);
if ((*Client)->account_name)
free((*Client)->account_name);
if ((*Client)->away)
free((*Client)->away);
if ((*Client)->cloaked)
free((*Client)->cloaked);
if ((*Client)->ipa_text)
free((*Client)->ipa_text);
free(*Client);
*Client = NULL;
}
static void
Generate_MyToken( CLIENT *Client )
@@ -1451,7 +1317,7 @@ Generate_MyToken( CLIENT *Client )
{
if( c->mytoken == token )
{
/* The token is already in use */
/* Das Token wurde bereits vergeben */
token++;
c = My_Clients;
continue;
@@ -1558,7 +1424,7 @@ Destroy_UserOrService(CLIENT *Client, const char *Txt, const char *FwdMsg, bool
if(Client->conn_id != NONE) {
/* Local (directly connected) client */
Log(LOG_NOTICE,
"%s \"%s\" unregistered (connection %d): %s.",
"%s \"%s\" unregistered (connection %d): %s",
Client_TypeText(Client), Client_Mask(Client),
Client->conn_id, Txt);
Log_ServerNotice('c', "Client exiting: %s (%s@%s) [%s]",
@@ -1576,7 +1442,7 @@ Destroy_UserOrService(CLIENT *Client, const char *Txt, const char *FwdMsg, bool
}
} else {
/* Remote client */
LogDebug("%s \"%s\" unregistered: %s.",
LogDebug("%s \"%s\" unregistered: %s",
Client_TypeText(Client), Client_Mask(Client), Txt);
if(SendQuit) {
@@ -1602,6 +1468,9 @@ Destroy_UserOrService(CLIENT *Client, const char *Txt, const char *FwdMsg, bool
/**
* Introduce a new user or service client to a remote server.
*
* This function differentiates between RFC1459 and RFC2813 server links and
* generates the appropriate commands to register the new user or service.
*
* @param To The remote server to inform.
* @param Prefix Prefix for the generated commands.
* @param data CLIENT structure of the new client.
@@ -1610,100 +1479,43 @@ static void
cb_introduceClient(CLIENT *To, CLIENT *Prefix, void *data)
{
CLIENT *c = (CLIENT *)data;
(void)Client_Announce(To, Prefix, c);
} /* cb_introduceClient */
/**
* Announce an user or service to a server.
*
* This function differentiates between RFC1459 and RFC2813 server links and
* generates the appropriate commands to register the user or service.
*
* @param Client Server
* @param Prefix Prefix for the generated commands
* @param User User to announce
*/
GLOBAL bool
Client_Announce(CLIENT * Client, CLIENT * Prefix, CLIENT * User)
{
CONN_ID conn;
char *modes, *user, *host;
modes = Client_Modes(User);
user = Client_User(User) ? Client_User(User) : "-";
host = Client_Hostname(User) ? Client_Hostname(User) : "-";
modes = Client_Modes(c);
user = Client_User(c) ? Client_User(c) : "-";
host = Client_Hostname(c) ? Client_Hostname(c) : "-";
conn = Client_Conn(Client);
conn = Client_Conn(To);
if (Conn_Options(conn) & CONN_RFC1459) {
/* RFC 1459 mode: separate NICK and USER commands */
if (! Conn_WriteStr(conn, "NICK %s :%d",
Client_ID(User), Client_Hops(User) + 1))
return DISCONNECTED;
if (! Conn_WriteStr(conn, ":%s USER %s %s %s :%s",
Client_ID(User), user, host,
Client_ID(Client_Introducer(User)),
Client_Info(User)))
return DISCONNECTED;
if (modes[0]) {
if (! Conn_WriteStr(conn, ":%s MODE %s +%s",
Client_ID(User), Client_ID(User),
modes))
return DISCONNECTED;
}
Conn_WriteStr(conn, "NICK %s :%d", Client_ID(c),
Client_Hops(c) + 1);
Conn_WriteStr(conn, ":%s USER %s %s %s :%s",
Client_ID(c), user, host,
Client_ID(Client_Introducer(c)), Client_Info(c));
if (modes[0])
Conn_WriteStr(conn, ":%s MODE %s +%s",
Client_ID(c), Client_ID(c), modes);
} else {
/* RFC 2813 mode: one combined NICK or SERVICE command */
if (Client_Type(User) == CLIENT_SERVICE
&& Client_HasFlag(Client, 'S')) {
if (!IRC_WriteStrClientPrefix(Client, Prefix,
"SERVICE %s %d * +%s %d :%s",
Client_Mask(User),
Client_MyToken(Client_Introducer(User)),
modes, Client_Hops(User) + 1,
Client_Info(User)))
return DISCONNECTED;
} else {
if (!IRC_WriteStrClientPrefix(Client, Prefix,
"NICK %s %d %s %s %d +%s :%s",
Client_ID(User), Client_Hops(User) + 1,
user, host,
Client_MyToken(Client_Introducer(User)),
modes, Client_Info(User)))
return DISCONNECTED;
}
if (Client_Type(c) == CLIENT_SERVICE
&& strchr(Client_Flags(To), 'S'))
IRC_WriteStrClientPrefix(To, Prefix,
"SERVICE %s %d * +%s %d :%s",
Client_Mask(c),
Client_MyToken(Client_Introducer(c)),
Client_Modes(c), Client_Hops(c) + 1,
Client_Info(c));
else
IRC_WriteStrClientPrefix(To, Prefix,
"NICK %s %d %s %s %d +%s :%s",
Client_ID(c), Client_Hops(c) + 1,
user, host,
Client_MyToken(Client_Introducer(c)),
modes, Client_Info(c));
}
if (Client_HasFlag(Client, 'M')) {
/* Synchronize metadata */
if (Client_HostnameCloaked(User)) {
if (!IRC_WriteStrClientPrefix(Client, Prefix,
"METADATA %s cloakhost :%s",
Client_ID(User),
Client_HostnameCloaked(User)))
return DISCONNECTED;
}
if (Client_AccountName(User)) {
if (!IRC_WriteStrClientPrefix(Client, Prefix,
"METADATA %s accountname :%s",
Client_ID(User),
Client_AccountName(User)))
return DISCONNECTED;
}
if (Conn_GetCertFp(Client_Conn(User))) {
if (!IRC_WriteStrClientPrefix(Client, Prefix,
"METADATA %s certfp :%s",
Client_ID(User),
Conn_GetCertFp(Client_Conn(User))))
return DISCONNECTED;
}
}
return CONNECTED;
} /* Client_Announce */
} /* cb_introduceClient */
#ifdef DEBUG

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2013 Alexander Barton (alex@barton.de) and Contributors.
* Copyright (c)2001-2012 Alexander Barton (alex@barton.de)
*
* 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
@@ -17,20 +17,19 @@
* Client management (header)
*/
#define CLIENT_UNKNOWN 0x0001 /* connection of unknown type */
#define CLIENT_GOTPASS 0x0002 /* client did send PASS */
#define CLIENT_GOTNICK 0x0004 /* client did send NICK */
#define CLIENT_GOTUSER 0x0008 /* client did send USER */
#define CLIENT_USER 0x0010 /* client is an IRC user */
#define CLIENT_SERVER 0x0020 /* client is a server */
#define CLIENT_SERVICE 0x0040 /* client is a service */
#define CLIENT_UNKNOWNSERVER 0x0080 /* unregistered server connection */
#define CLIENT_GOTPASS_2813 0x0100 /* client did send PASS, RFC 2813 style */
#define CLIENT_UNKNOWN 1 /* connection of unknown type */
#define CLIENT_GOTPASS 2 /* client did send PASS */
#define CLIENT_GOTNICK 4 /* client did send NICK */
#define CLIENT_GOTUSER 8 /* client did send USER */
#define CLIENT_USER 16 /* client is an IRC user */
#define CLIENT_SERVER 32 /* client is a server */
#define CLIENT_SERVICE 64 /* client is a service */
#define CLIENT_UNKNOWNSERVER 128 /* unregistered server connection */
#define CLIENT_GOTPASS_2813 256 /* client did send PASS, RFC 2813 style */
#ifndef STRICT_RFC
# define CLIENT_WAITAUTHPING 0x0200 /* waiting for AUTH PONG from client */
# define CLIENT_WAITAUTHPING 512 /* waiting for AUTH PONG from client */
#endif
#define CLIENT_WAITCAPEND 0x0400 /* waiting for "CAP END" command */
#define CLIENT_ANY 0xFFFF
#define CLIENT_WAITCAPEND 1024 /* waiting for "CAP END" command */
#define CLIENT_TYPE int
@@ -49,8 +48,7 @@ typedef struct _CLIENT
struct _CLIENT *introducer; /* ID of the servers which the client is connected to */
struct _CLIENT *topserver; /* toplevel servers (only valid if client is a server) */
char host[CLIENT_HOST_LEN]; /* hostname of the client */
char *cloaked; /* cloaked hostname of the client */
char *ipa_text; /* textual representaton of IP address */
char cloaked[CLIENT_HOST_LEN]; /* cloaked hostname of the client */
char user[CLIENT_USER_LEN]; /* user name ("login") */
#if defined(PAM) && defined(IDENTAUTH)
char orig_user[CLIENT_USER_LEN];/* user name supplied by USER command */
@@ -58,9 +56,9 @@ typedef struct _CLIENT
char info[CLIENT_INFO_LEN]; /* long user name (user) / info text (server) */
char modes[CLIENT_MODE_LEN]; /* client modes */
int hops, token, mytoken; /* "hops" and "Token" (see SERVER command) */
char *away; /* AWAY text (valid if mode 'a' is set) */
bool oper_by_me; /* client is local IRC operator on this server? */
char away[CLIENT_AWAY_LEN]; /* AWAY text (valid if mode 'a' is set) */
char flags[CLIENT_FLAGS_LEN]; /* flags of the client */
char *account_name; /* login account (for services) */
int capabilities; /* enabled IRC capabilities */
} CLIENT;
@@ -95,10 +93,7 @@ GLOBAL CLIENT *Client_ThisServer PARAMS(( void ));
GLOBAL CLIENT *Client_GetFromToken PARAMS(( CLIENT *Client, int Token ));
GLOBAL bool Client_Announce PARAMS(( CLIENT *Client, CLIENT *Prefix, CLIENT *User ));
GLOBAL CLIENT *Client_Search PARAMS(( const char *ID ));
GLOBAL CLIENT *Client_SearchServer PARAMS(( const char *ID ));
GLOBAL CLIENT *Client_First PARAMS(( void ));
GLOBAL CLIENT *Client_Next PARAMS(( CLIENT *c ));
@@ -115,24 +110,21 @@ GLOBAL char *Client_OrigUser PARAMS(( CLIENT *Client ));
GLOBAL char *Client_Hostname PARAMS(( CLIENT *Client ));
GLOBAL char *Client_HostnameCloaked PARAMS((CLIENT *Client));
GLOBAL char *Client_HostnameDisplayed PARAMS(( CLIENT *Client ));
GLOBAL const char *Client_IPAText PARAMS(( CLIENT *Client ));
GLOBAL char *Client_Modes PARAMS(( CLIENT *Client ));
GLOBAL char *Client_Flags PARAMS(( CLIENT *Client ));
GLOBAL CLIENT *Client_Introducer PARAMS(( CLIENT *Client ));
GLOBAL bool Client_OperByMe PARAMS(( CLIENT *Client ));
GLOBAL int Client_Hops PARAMS(( CLIENT *Client ));
GLOBAL int Client_Token PARAMS(( CLIENT *Client ));
GLOBAL int Client_MyToken PARAMS(( CLIENT *Client ));
GLOBAL CLIENT *Client_TopServer PARAMS(( CLIENT *Client ));
GLOBAL CLIENT *Client_NextHop PARAMS(( CLIENT *Client ));
GLOBAL char *Client_Away PARAMS(( CLIENT *Client ));
GLOBAL char *Client_AccountName PARAMS((CLIENT *Client));
GLOBAL time_t Client_StartTime PARAMS(( CLIENT *Client ));
GLOBAL bool Client_HasMode PARAMS(( CLIENT *Client, char Mode ));
GLOBAL bool Client_HasFlag PARAMS(( CLIENT *Client, char Flag ));
GLOBAL void Client_SetHostname PARAMS(( CLIENT *Client, const char *Hostname ));
GLOBAL void Client_SetIPAText PARAMS(( CLIENT *Client, const char *IPAText ));
GLOBAL void Client_SetID PARAMS(( CLIENT *Client, const char *Nick ));
GLOBAL void Client_SetUser PARAMS(( CLIENT *Client, const char *User, bool Idented ));
GLOBAL void Client_SetOrigUser PARAMS(( CLIENT *Client, const char *User ));
@@ -140,11 +132,11 @@ GLOBAL void Client_SetInfo PARAMS(( CLIENT *Client, const char *Info ));
GLOBAL void Client_SetType PARAMS(( CLIENT *Client, int Type ));
GLOBAL void Client_SetHops PARAMS(( CLIENT *Client, int Hops ));
GLOBAL void Client_SetToken PARAMS(( CLIENT *Client, int Token ));
GLOBAL void Client_SetOperByMe PARAMS(( CLIENT *Client, bool OperByMe ));
GLOBAL void Client_SetModes PARAMS(( CLIENT *Client, const char *Modes ));
GLOBAL void Client_SetFlags PARAMS(( CLIENT *Client, const char *Flags ));
GLOBAL void Client_SetIntroducer PARAMS(( CLIENT *Client, CLIENT *Introducer ));
GLOBAL void Client_SetAway PARAMS(( CLIENT *Client, const char *Txt ));
GLOBAL void Client_SetAccountName PARAMS((CLIENT *Client, const char *AccountName));
GLOBAL bool Client_ModeAdd PARAMS(( CLIENT *Client, char Mode ));
GLOBAL bool Client_ModeDel PARAMS(( CLIENT *Client, char Mode ));

View File

@@ -37,12 +37,11 @@ struct ConnSSL_State {
void *cookie; /* pointer to server configuration structure
(for outgoing connections), or NULL. */
#endif
char *fingerprint;
};
#endif
GLOBAL bool ConnSSL_InitLibrary PARAMS((void));
bool ConnSSL_InitLibrary(void);
#endif /* conf_ssl_h */

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2013 Alexander Barton (alex@barton.de) and Contributors.
* Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
*
* 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
@@ -75,7 +75,6 @@ struct SSLOptions {
char *DHFile; /**< File containing DH parameters */
array ListenPorts; /**< Array of listening SSL ports */
array KeyFilePassword; /**< Key file password */
char *CipherList; /**< Set SSL cipher list to use */
};
#endif
@@ -112,9 +111,6 @@ GLOBAL char Conf_ServerAdminMail[CLIENT_INFO_LEN];
/** Message of the day (MOTD) of this server */
GLOBAL array Conf_Motd;
/** Help text of this server */
GLOBAL array Conf_Helptext;
/** Array of ports this server should listen on */
GLOBAL array Conf_ListenPorts;
@@ -149,8 +145,8 @@ GLOBAL CONF_SERVER Conf_Server[MAX_SERVERS];
/** Array of pre-defined channels */
GLOBAL array Conf_Channels;
/** String containing all locally allowed channel prefixes for new channels */
GLOBAL char Conf_AllowedChannelTypes[8];
/** Flag indicating if only pre-defined channels are allowed (true) or not */
GLOBAL bool Conf_PredefChannelsOnly;
/** Flag indicating if IRC operators are allowed to always use MODE (true) */
GLOBAL bool Conf_OperCanMode;
@@ -203,9 +199,6 @@ GLOBAL bool Conf_PAMIsOptional;
/** Disable all CTCP commands except for /me ? */
GLOBAL bool Conf_ScrubCTCP;
/** Default user modes for new local clients */
GLOBAL char Conf_DefaultUserModes[CLIENT_MODE_LEN];
/*
* try to connect to remote systems using the ipv6 protocol,
* if they have an ipv6 address? (default yes)
@@ -215,9 +208,6 @@ GLOBAL bool Conf_ConnectIPv6;
/** Try to connect to remote systems using the IPv4 protocol (true) */
GLOBAL bool Conf_ConnectIPv4;
/** Idle timout (seconds), after which the daemon should exit */
GLOBAL int Conf_IdleTimeout;
/** Maximum number of simultaneous connections to this server */
GLOBAL int Conf_MaxConnections;

View File

@@ -123,9 +123,9 @@ Convert_Message(iconv_t Handle, char *Message)
out_left = sizeof(Encoding_Buffer) - 1;
if (iconv(Handle, &Message, &in_left, &out, &out_left) == (size_t)(-1)) {
/* An error occurred! */
/* An error occured! */
LogDebug("Error converting message encoding!");
strlcpy(out, Message, sizeof(Encoding_Buffer));
strlcpy(Encoding_Buffer, Message, sizeof(Encoding_Buffer));
iconv(Handle, NULL, NULL, NULL, NULL);
} else
*out = '\0';

View File

@@ -137,6 +137,8 @@ Conn_Flag( CONN_ID Idx )
GLOBAL void
Conn_SetFlag( CONN_ID Idx, int Flag )
{
/* Connection markieren */
assert( Idx > NONE );
My_Connections[Idx].flag = Flag;
} /* Conn_SetFlag */
@@ -145,6 +147,9 @@ Conn_SetFlag( CONN_ID Idx, int Flag )
GLOBAL CONN_ID
Conn_First( void )
{
/* Connection-Struktur der ersten Verbindung liefern;
* Ist keine Verbindung vorhanden, wird NONE geliefert. */
CONN_ID i;
for( i = 0; i < Pool_Size; i++ )
@@ -158,6 +163,9 @@ Conn_First( void )
GLOBAL CONN_ID
Conn_Next( CONN_ID Idx )
{
/* Naechste Verbindungs-Struktur liefern; existiert keine
* weitere, so wird NONE geliefert. */
CONN_ID i = NONE;
assert( Idx > NONE );

View File

@@ -54,16 +54,11 @@ static bool ConnSSL_LoadServerKey_openssl PARAMS(( SSL_CTX *c ));
#define DH_BITS 2048
#define DH_BITS_MIN 1024
#define MAX_HASH_SIZE 64 /* from gnutls-int.h */
static gnutls_certificate_credentials_t x509_cred;
static gnutls_dh_params_t dh_params;
static gnutls_priority_t priorities_cache;
static bool ConnSSL_LoadServerKey_gnutls PARAMS(( void ));
#endif
#define SHA256_STRING_LEN (32 * 2 + 1)
static bool ConnSSL_Init_SSL PARAMS(( CONNECTION *c ));
static int ConnectAccept PARAMS(( CONNECTION *c, bool connect ));
static int ConnSSL_HandleError PARAMS(( CONNECTION *c, const int code, const char *fname ));
@@ -114,26 +109,17 @@ out:
#ifdef HAVE_LIBSSL
/**
* Log OpenSSL error message.
*
* @param msg The error message.
* @param info Additional information text or NULL.
*/
static void
LogOpenSSLError(const char *error, const char *info)
LogOpenSSLError( const char *msg, const char *msg2 )
{
unsigned long err = ERR_get_error();
char * errmsg = err
? ERR_error_string(err, NULL)
: "Unable to determine error";
char * errmsg = err ? ERR_error_string(err, NULL) : "Unable to determine error";
assert(error != NULL);
if (info)
Log(LOG_ERR, "%s: %s (%s)", error, info, errmsg);
if (!msg) msg = "SSL Error";
if (msg2)
Log( LOG_ERR, "%s: %s: %s", msg, msg2, errmsg);
else
Log(LOG_ERR, "%s: %s", error, errmsg);
Log( LOG_ERR, "%s: %s", msg, errmsg);
}
@@ -152,20 +138,13 @@ pem_passwd_cb(char *buf, int size, int rwflag, void *password)
LogDebug("pem_passwd_cb buf size %d, array size %d", size, passlen);
assert(passlen >= 0);
if (passlen <= 0) {
Log(LOG_ERR, "PEM password required but not set [in pem_passwd_cb()]!");
Log(LOG_ERR, "pem_passwd_cb: password required, but not set");
return 0;
}
size = passlen > size ? size : passlen;
memcpy(buf, (char *)(array_start(pass)), size);
return size;
}
static int
Verify_openssl(UNUSED int preverify_ok, UNUSED X509_STORE_CTX *x509_ctx)
{
return 1;
}
#endif
@@ -187,7 +166,7 @@ Load_DH_params(void)
}
dh_params = PEM_read_DHparams(fp, NULL, NULL, NULL);
if (!dh_params) {
Log(LOG_ERR, "%s: Failed to read SSL DH parameters!",
Log(LOG_ERR, "%s: PEM_read_DHparams failed!",
Conf_SSLOptions.DHFile);
ret = false;
}
@@ -201,8 +180,7 @@ Load_DH_params(void)
err = gnutls_dh_params_init(&tmp_dh_params);
if (err < 0) {
Log(LOG_ERR, "Failed to initialize SSL DH parameters: %s",
gnutls_strerror(err));
Log(LOG_ERR, "gnutls_dh_params_init: %s", gnutls_strerror(err));
return false;
}
if (Conf_SSLOptions.DHFile) {
@@ -215,9 +193,7 @@ Load_DH_params(void)
if (err == 0)
need_dhgenerate = false;
else
Log(LOG_ERR,
"Failed to initialize SSL DH parameters: %s",
gnutls_strerror(err));
Log(LOG_ERR, "gnutls_dh_params_init: %s", gnutls_strerror(err));
memset(dhparms.data, 0, size);
free(dhparms.data);
@@ -229,8 +205,7 @@ Load_DH_params(void)
DH_BITS);
err = gnutls_dh_params_generate2(tmp_dh_params, DH_BITS);
if (err < 0) {
Log(LOG_ERR, "Failed to generate SSL DH parameters: %s",
gnutls_strerror(err));
Log(LOG_ERR, "gnutls_dh_params_generate2: %s", gnutls_strerror(err));
return false;
}
}
@@ -248,10 +223,6 @@ void ConnSSL_Free(CONNECTION *c)
SSL_shutdown(ssl);
SSL_free(ssl);
c->ssl_state.ssl = NULL;
if (c->ssl_state.fingerprint) {
free(c->ssl_state.fingerprint);
c->ssl_state.fingerprint = NULL;
}
}
#endif
#ifdef HAVE_LIBGNUTLS
@@ -286,10 +257,8 @@ ConnSSL_InitLibrary( void )
if (!RAND_status()) {
Log(LOG_ERR, "OpenSSL PRNG not seeded: /dev/urandom missing?");
/*
* it is probably best to fail and let the user install EGD or
* a similar program if no kernel random device is available.
* According to OpenSSL RAND_egd(3): "The automatic query of
* /var/run/egd-pool et al was added in OpenSSL 0.9.7";
* it is probably best to fail and let the user install EGD or a similar program if no kernel random device is available.
* According to OpenSSL RAND_egd(3): "The automatic query of /var/run/egd-pool et al was added in OpenSSL 0.9.7";
* so it makes little sense to deal with PRNGD seeding ourselves.
*/
array_free(&Conf_SSLOptions.ListenPorts);
@@ -298,7 +267,7 @@ ConnSSL_InitLibrary( void )
newctx = SSL_CTX_new(SSLv23_method());
if (!newctx) {
LogOpenSSLError("Failed to create SSL context", NULL);
LogOpenSSLError("SSL_CTX_new()", NULL);
array_free(&Conf_SSLOptions.ListenPorts);
return false;
}
@@ -306,16 +275,8 @@ ConnSSL_InitLibrary( void )
if (!ConnSSL_LoadServerKey_openssl(newctx))
goto out;
if (SSL_CTX_set_cipher_list(newctx, Conf_SSLOptions.CipherList) == 0) {
Log(LOG_ERR, "Failed to apply OpenSSL cipher list \"%s\"!",
Conf_SSLOptions.CipherList);
goto out;
}
SSL_CTX_set_options(newctx, SSL_OP_SINGLE_DH_USE|SSL_OP_NO_SSLv2);
SSL_CTX_set_mode(newctx, SSL_MODE_ENABLE_PARTIAL_WRITE);
SSL_CTX_set_verify(newctx, SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE,
Verify_openssl);
SSL_CTX_free(ssl_ctx);
ssl_ctx = newctx;
Log(LOG_INFO, "%s initialized.", SSLeay_version(SSLEAY_VERSION));
@@ -328,37 +289,22 @@ out:
#ifdef HAVE_LIBGNUTLS
int err;
static bool initialized;
if (initialized) {
/* TODO: cannot reload gnutls keys: can't simply free x509
* context -- it may still be in use */
if (initialized) /* TODO: cannot reload gnutls keys: can't simply free x509 context -- it may still be in use */
return false;
}
err = gnutls_global_init();
if (err) {
Log(LOG_ERR, "Failed to initialize GnuTLS: %s",
gnutls_strerror(err));
goto out;
Log(LOG_ERR, "gnutls_global_init(): %s", gnutls_strerror(err));
array_free(&Conf_SSLOptions.ListenPorts);
return false;
}
if (!ConnSSL_LoadServerKey_gnutls())
goto out;
if (gnutls_priority_init(&priorities_cache, Conf_SSLOptions.CipherList,
NULL) != GNUTLS_E_SUCCESS) {
Log(LOG_ERR,
"Failed to apply GnuTLS cipher list \"%s\"!",
Conf_SSLOptions.CipherList);
goto out;
if (!ConnSSL_LoadServerKey_gnutls()) {
array_free(&Conf_SSLOptions.ListenPorts);
return false;
}
Log(LOG_INFO, "GnuTLS %s initialized.", gnutls_check_version(NULL));
Log(LOG_INFO, "gnutls %s initialized.", gnutls_check_version(NULL));
initialized = true;
return true;
out:
array_free(&Conf_SSLOptions.ListenPorts);
return false;
#endif
}
@@ -372,8 +318,7 @@ ConnSSL_LoadServerKey_gnutls(void)
err = gnutls_certificate_allocate_credentials(&x509_cred);
if (err < 0) {
Log(LOG_ERR, "Failed to allocate certificate credentials: %s",
gnutls_strerror(err));
Log(LOG_ERR, "gnutls_certificate_allocate_credentials: %s", gnutls_strerror(err));
return false;
}
@@ -385,7 +330,7 @@ ConnSSL_LoadServerKey_gnutls(void)
if (array_bytes(&Conf_SSLOptions.KeyFilePassword))
Log(LOG_WARNING,
"Ignoring SSL \"KeyFilePassword\": Not supported by GnuTLS.");
"Ignoring KeyFilePassword: Not supported by GNUTLS.");
if (!Load_DH_params())
return false;
@@ -393,11 +338,8 @@ ConnSSL_LoadServerKey_gnutls(void)
gnutls_certificate_set_dh_params(x509_cred, dh_params);
err = gnutls_certificate_set_x509_key_file(x509_cred, cert_file, Conf_SSLOptions.KeyFile, GNUTLS_X509_FMT_PEM);
if (err < 0) {
Log(LOG_ERR,
"Failed to set certificate key file (cert %s, key %s): %s",
cert_file,
Conf_SSLOptions.KeyFile ? Conf_SSLOptions.KeyFile : "(NULL)",
gnutls_strerror(err));
Log(LOG_ERR, "gnutls_certificate_set_x509_key_file (cert %s, key %s): %s",
cert_file, Conf_SSLOptions.KeyFile ? Conf_SSLOptions.KeyFile : "(NULL)", gnutls_strerror(err));
return false;
}
return true;
@@ -422,26 +364,26 @@ ConnSSL_LoadServerKey_openssl(SSL_CTX *ctx)
if (SSL_CTX_use_PrivateKey_file(ctx, Conf_SSLOptions.KeyFile, SSL_FILETYPE_PEM) != 1) {
array_free_wipe(&Conf_SSLOptions.KeyFilePassword);
LogOpenSSLError("Failed to add private key", Conf_SSLOptions.KeyFile);
LogOpenSSLError("SSL_CTX_use_PrivateKey_file", Conf_SSLOptions.KeyFile);
return false;
}
cert_key = Conf_SSLOptions.CertFile ? Conf_SSLOptions.CertFile:Conf_SSLOptions.KeyFile;
if (SSL_CTX_use_certificate_chain_file(ctx, cert_key) != 1) {
array_free_wipe(&Conf_SSLOptions.KeyFilePassword);
LogOpenSSLError("Failed to load certificate chain", cert_key);
LogOpenSSLError("SSL_CTX_use_certificate_file", cert_key);
return false;
}
array_free_wipe(&Conf_SSLOptions.KeyFilePassword);
if (!SSL_CTX_check_private_key(ctx)) {
LogOpenSSLError("Server private key does not match certificate", NULL);
LogOpenSSLError("Server Private Key does not match certificate", NULL);
return false;
}
if (Load_DH_params()) {
if (SSL_CTX_set_tmp_dh(ctx, dh_params) != 1)
LogOpenSSLError("Error setting DH parameters", Conf_SSLOptions.DHFile);
LogOpenSSLError("Error setting DH Parameters", Conf_SSLOptions.DHFile);
/* don't return false here: the non-DH modes will still work */
DH_free(dh_params);
dh_params = NULL;
@@ -455,39 +397,31 @@ static bool
ConnSSL_Init_SSL(CONNECTION *c)
{
int ret;
LogDebug("Initializing SSL ...");
assert(c != NULL);
#ifdef HAVE_LIBSSL
if (!ssl_ctx) {
Log(LOG_ERR,
"Can't initialize SSL context, OpenSSL initialization failed at startup!");
Log(LOG_ERR, "Cannot init ssl_ctx: OpenSSL initialization failed at startup");
return false;
}
assert(c->ssl_state.ssl == NULL);
assert(c->ssl_state.fingerprint == NULL);
c->ssl_state.ssl = SSL_new(ssl_ctx);
if (!c->ssl_state.ssl) {
LogOpenSSLError("Failed to create SSL structure", NULL);
LogOpenSSLError("SSL_new()", NULL);
return false;
}
Conn_OPTION_ADD(c, CONN_SSL);
ret = SSL_set_fd(c->ssl_state.ssl, c->sock);
if (ret != 1) {
LogOpenSSLError("Failed to set SSL file descriptor", NULL);
LogOpenSSLError("SSL_set_fd()", NULL);
ConnSSL_Free(c);
return false;
}
#endif
#ifdef HAVE_LIBGNUTLS
Conn_OPTION_ADD(c, CONN_SSL);
ret = gnutls_priority_set(c->ssl_state.gnutls_session, priorities_cache);
if (ret != GNUTLS_E_SUCCESS) {
Log(LOG_ERR, "Failed to set GnuTLS session priorities: %s",
gnutls_strerror(ret));
ret = gnutls_set_default_priority(c->ssl_state.gnutls_session);
if (ret < 0) {
Log(LOG_ERR, "gnutls_set_default_priority: %s", gnutls_strerror(ret));
ConnSSL_Free(c);
return false;
}
@@ -497,20 +431,16 @@ ConnSSL_Init_SSL(CONNECTION *c)
* There doesn't seem to be an alternate GNUTLS API we could use instead, see e.g.
* http://www.mail-archive.com/help-gnutls@gnu.org/msg00286.html
*/
gnutls_transport_set_ptr(c->ssl_state.gnutls_session,
(gnutls_transport_ptr_t) (long) c->sock);
gnutls_certificate_server_set_request(c->ssl_state.gnutls_session,
GNUTLS_CERT_REQUEST);
ret = gnutls_credentials_set(c->ssl_state.gnutls_session,
GNUTLS_CRD_CERTIFICATE, x509_cred);
if (ret != 0) {
Log(LOG_ERR, "Failed to set SSL credentials: %s",
gnutls_strerror(ret));
gnutls_transport_set_ptr(c->ssl_state.gnutls_session, (gnutls_transport_ptr_t) (long) c->sock);
ret = gnutls_credentials_set(c->ssl_state.gnutls_session, GNUTLS_CRD_CERTIFICATE, x509_cred);
if (ret < 0) {
Log(LOG_ERR, "gnutls_credentials_set: %s", gnutls_strerror(ret));
ConnSSL_Free(c);
return false;
}
gnutls_dh_set_prime_bits(c->ssl_state.gnutls_session, DH_BITS_MIN);
#endif
Conn_OPTION_ADD(c, CONN_SSL);
return true;
}
@@ -524,8 +454,7 @@ ConnSSL_PrepareConnect(CONNECTION *c, UNUSED CONF_SERVER *s)
err = gnutls_init(&c->ssl_state.gnutls_session, GNUTLS_CLIENT);
if (err) {
Log(LOG_ERR, "Failed to initialize new SSL session: %s",
gnutls_strerror(err));
Log(LOG_ERR, "gnutls_init: %s", gnutls_strerror(err));
return false;
}
#endif
@@ -541,23 +470,16 @@ ConnSSL_PrepareConnect(CONNECTION *c, UNUSED CONF_SERVER *s)
}
/**
* Check and handle error return codes after failed calls to SSL functions.
*
* OpenSSL:
* SSL_connect(), SSL_accept(), SSL_do_handshake(), SSL_read(), SSL_peek(), or
* SSL_write() on ssl.
*
* GnuTLS:
* gnutlsssl_read(), gnutls_write() or gnutls_handshake().
*
* @param c The connection handle.
* @prarm code The return code.
* @param fname The name of the function in which the error occurred.
* @return -1 on fatal errors, 0 if we can try again later.
/*
Check an Handle Error return code after failed calls to ssl/tls functions.
OpenSSL:
SSL_connect(), SSL_accept(), SSL_do_handshake(), SSL_read(), SSL_peek(), or SSL_write() on ssl.
GNUTLS:
gnutlsssl_read(), gnutls_write() or gnutls_handshake().
Return: -1 on fatal error, 0 if we can try again later.
*/
static int
ConnSSL_HandleError(CONNECTION * c, const int code, const char *fname)
ConnSSL_HandleError( CONNECTION *c, const int code, const char *fname )
{
#ifdef HAVE_LIBSSL
int ret = SSL_ERROR_SYSCALL;
@@ -565,7 +487,6 @@ ConnSSL_HandleError(CONNECTION * c, const int code, const char *fname)
int real_errno = errno;
ret = SSL_get_error(c->ssl_state.ssl, code);
switch (ret) {
case SSL_ERROR_WANT_READ:
io_event_del(c->sock, IO_WANTWRITE);
@@ -577,33 +498,31 @@ ConnSSL_HandleError(CONNECTION * c, const int code, const char *fname)
case SSL_ERROR_NONE:
return 0; /* try again later */
case SSL_ERROR_ZERO_RETURN:
LogDebug("SSL connection shut down normally.");
LogDebug("TLS/SSL connection shut down normally");
break;
/*
SSL_ERROR_WANT_CONNECT, SSL_ERROR_WANT_ACCEPT, SSL_ERROR_WANT_X509_LOOKUP
*/
case SSL_ERROR_SYSCALL:
/* SSL_ERROR_WANT_CONNECT, SSL_ERROR_WANT_ACCEPT,
* and SSL_ERROR_WANT_X509_LOOKUP */
sslerr = ERR_get_error();
if (sslerr) {
Log(LOG_ERR, "SSL error: %s [in %s()]!",
ERR_error_string(sslerr, NULL), fname);
Log( LOG_ERR, "%s: %s", fname, ERR_error_string(sslerr, NULL ));
} else {
switch (code) { /* EOF that violated protocol */
case 0:
Log(LOG_ERR,
"SSL error, client disconnected [in %s()]!",
fname);
Log(LOG_ERR, "%s: Client Disconnected", fname );
break;
case -1: /* low level socket I/O error, check errno */
Log(LOG_ERR, "SSL error: %s [in %s()]!",
strerror(real_errno), fname);
case -1: /* low level socket I/O error, check errno */
Log(LOG_ERR, "%s: %s", fname, strerror(real_errno));
}
}
break;
case SSL_ERROR_SSL:
LogOpenSSLError("SSL protocol error", fname);
LogOpenSSLError("TLS/SSL Protocol Error", fname);
break;
default:
Log(LOG_ERR, "Unknown SSL error %d [in %s()]!", ret, fname);
Log( LOG_ERR, "%s: Unknown error %d!", fname, ret);
}
ConnSSL_Free(c);
return -1;
@@ -623,8 +542,7 @@ ConnSSL_HandleError(CONNECTION * c, const int code, const char *fname)
default:
assert(code < 0);
if (gnutls_error_is_fatal(code)) {
Log(LOG_ERR, "SSL error: %s [%s].",
gnutls_strerror(code), fname);
Log(LOG_ERR, "%s: %s", fname, gnutls_strerror(code));
ConnSSL_Free(c);
return -1;
}
@@ -673,11 +591,11 @@ ConnSSL_Accept( CONNECTION *c )
#ifdef HAVE_LIBGNUTLS
int err = gnutls_init(&c->ssl_state.gnutls_session, GNUTLS_SERVER);
if (err) {
Log(LOG_ERR, "Failed to initialize new SSL session: %s",
gnutls_strerror(err));
Log(LOG_ERR, "gnutls_init: %s", gnutls_strerror(err));
return false;
}
#endif
LogDebug("ConnSSL_Accept: Initializing SSL data");
if (!ConnSSL_Init_SSL(c))
return -1;
}
@@ -696,80 +614,6 @@ ConnSSL_Connect( CONNECTION *c )
return ConnectAccept(c, true);
}
static int
ConnSSL_InitCertFp( CONNECTION *c )
{
const char hex[] = "0123456789abcdef";
int i;
#ifdef HAVE_LIBSSL
unsigned char digest[EVP_MAX_MD_SIZE];
unsigned int digest_size;
X509 *cert;
cert = SSL_get_peer_certificate(c->ssl_state.ssl);
if (!cert)
return 0;
if (!X509_digest(cert, EVP_sha256(), digest, &digest_size)) {
X509_free(cert);
return 0;
}
X509_free(cert);
#endif /* HAVE_LIBSSL */
#ifdef HAVE_LIBGNUTLS
gnutls_x509_crt_t cert;
unsigned int cert_list_size;
const gnutls_datum_t *cert_list;
unsigned char digest[MAX_HASH_SIZE];
size_t digest_size;
if (gnutls_certificate_type_get(c->ssl_state.gnutls_session) !=
GNUTLS_CRT_X509)
return 0;
if (gnutls_x509_crt_init(&cert) != GNUTLS_E_SUCCESS)
return 0;
cert_list_size = 0;
cert_list = gnutls_certificate_get_peers(c->ssl_state.gnutls_session,
&cert_list_size);
if (!cert_list) {
gnutls_x509_crt_deinit(cert);
return 0;
}
if (gnutls_x509_crt_import(cert, &cert_list[0],
GNUTLS_X509_FMT_DER) != GNUTLS_E_SUCCESS) {
gnutls_x509_crt_deinit(cert);
return 0;
}
digest_size = sizeof(digest);
if (gnutls_x509_crt_get_fingerprint(cert, GNUTLS_DIG_SHA256, digest,
&digest_size)) {
gnutls_x509_crt_deinit(cert);
return 0;
}
gnutls_x509_crt_deinit(cert);
#endif /* HAVE_LIBGNUTLS */
assert(c->ssl_state.fingerprint == NULL);
c->ssl_state.fingerprint = malloc(SHA256_STRING_LEN);
if (!c->ssl_state.fingerprint)
return 0;
for (i = 0; i < (int)digest_size; i++) {
c->ssl_state.fingerprint[i * 2] = hex[digest[i] / 16];
c->ssl_state.fingerprint[i * 2 + 1] = hex[digest[i] % 16];
}
c->ssl_state.fingerprint[i * 2] = '\0';
return 1;
}
/* accept/connect wrapper. if connect is true, connect to peer, otherwise wait for incoming connection */
static int
@@ -790,8 +634,6 @@ ConnectAccept( CONNECTION *c, bool connect)
if (ret)
return ConnSSL_HandleError(c, ret, "gnutls_handshake");
#endif /* _GNUTLS */
(void)ConnSSL_InitCertFp(c);
Conn_OPTION_DEL(c, (CONN_SSL_WANT_WRITE|CONN_SSL_WANT_READ|CONN_SSL_CONNECT));
ConnSSL_LogCertInfo(c);
@@ -883,19 +725,6 @@ ConnSSL_GetCipherInfo(CONNECTION *c, char *buf, size_t len)
#endif
}
char *
ConnSSL_GetCertFp(CONNECTION *c)
{
return c->ssl_state.fingerprint;
}
bool
ConnSSL_SetCertFp(CONNECTION *c, const char *fingerprint)
{
assert (c != NULL);
c->ssl_state.fingerprint = strndup(fingerprint, SHA256_STRING_LEN - 1);
return c->ssl_state.fingerprint != NULL;
}
#else
bool

View File

@@ -26,9 +26,6 @@ GLOBAL ssize_t ConnSSL_Write PARAMS(( CONNECTION *c, const void *buf, size_t cou
GLOBAL ssize_t ConnSSL_Read PARAMS(( CONNECTION *c, void *buf, size_t count));
GLOBAL bool ConnSSL_GetCipherInfo PARAMS(( CONNECTION *c, char *buf, size_t len ));
GLOBAL char *ConnSSL_GetCertFp PARAMS(( CONNECTION *c ));
GLOBAL bool ConnSSL_SetCertFp PARAMS(( CONNECTION *c, const char *fingerprint ));
#endif /* SSL_SUPPORT */
#endif /* conn_ssl_h */

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2013 Alexander Barton (alex@barton.de) and Contributors.
* Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
*
* 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
@@ -82,8 +82,6 @@
#define MAX_COMMANDS_SERVER_MIN 10
#define MAX_COMMANDS_SERVICE 10
#define SD_LISTEN_FDS_START 3
static bool Handle_Write PARAMS(( CONN_ID Idx ));
static bool Conn_Write PARAMS(( CONN_ID Idx, char *Data, size_t Len ));
@@ -121,44 +119,6 @@ static void cb_Read_Resolver_Result PARAMS((int sock, UNUSED short what));
static void cb_Connect_to_Server PARAMS((int sock, UNUSED short what));
static void cb_clientserver PARAMS((int sock, short what));
time_t idle_t = 0;
/**
* Get number of sockets available from systemd(8).
*
* ngIRCd needs to implement its own sd_listen_fds(3) function and can't
* use the one provided by systemd itself, because the sockets will be
* used in a forked child process with a new PID, and this would trigger
* an error in the standard implementation.
*
* @return Number of sockets available, -1 if sockets have already been
* initialized, or 0 when no sockets have been passed.
*/
static int
my_sd_listen_fds(void)
{
const char *e;
int count;
/* Check if LISTEN_PID exists; but we ignore the result, because
* normally ngircd forks a child before checking this, and therefore
* the PID set in the environment is always wrong ... */
e = getenv("LISTEN_PID");
if (!e || !*e)
return 0;
e = getenv("LISTEN_FDS");
if (!e || !*e)
return -1;
count = atoi(e);
#ifdef HAVE_UNSETENV
unsetenv("LISTEN_FDS");
#endif
return count;
}
/**
* IO callback for listening sockets: handle new connections. This callback
@@ -224,7 +184,7 @@ cb_connserver(int sock, UNUSED short what)
if (server < 0) {
Log(LOG_ERR, "Connection on socket %d to \"%s\" aborted!",
sock, My_Connections[idx].host);
Conn_Close(idx, "Connection aborted", NULL, false);
Conn_Close(idx, "Connection aborted!", NULL, false);
return;
}
@@ -245,7 +205,7 @@ cb_connserver(int sock, UNUSED short what)
My_Connections[idx].host, Conf_Server[server].port,
idx, strerror(err));
Conn_Close(idx, "Can't connect", NULL, false);
Conn_Close(idx, "Can't connect!", NULL, false);
if (ng_ipaddr_af(&Conf_Server[server].dst_addr[0])) {
/* more addresses to try... */
@@ -322,7 +282,7 @@ cb_connserver_login_ssl(int sock, short unused)
return;
case -1:
Log(LOG_ERR, "SSL connection on socket %d failed!", sock);
Conn_Close(idx, "Can't connect", NULL, false);
Conn_Close(idx, "Can't connect!", NULL, false);
return;
}
@@ -369,13 +329,13 @@ cb_clientserver(int sock, short what)
#ifdef SSL_SUPPORT
/**
* IO callback for new SSL-enabled client and server connections.
* IO callback for established SSL-enabled client and server connections.
*
* @param sock Socket descriptor.
* @param what IO specification (IO_WANTREAD/IO_WANTWRITE/...).
*/
static void
cb_clientserver_ssl(int sock, UNUSED short what)
cb_clientserver_ssl(int sock, short what)
{
CONN_ID idx = Socket2Index(sock);
@@ -392,11 +352,14 @@ cb_clientserver_ssl(int sock, UNUSED short what)
case 0:
return; /* EAGAIN: callback will be invoked again by IO layer */
default:
Conn_Close(idx,
"SSL accept error, closing socket", "SSL accept error",
false);
Conn_Close(idx, "SSL accept error, closing socket", "SSL accept error", false);
return;
}
if (what & IO_WANTREAD)
Read_Request(idx);
if (what & IO_WANTWRITE)
Handle_Write(idx);
io_event_setcb(sock, cb_clientserver); /* SSL handshake completed */
}
@@ -404,13 +367,14 @@ cb_clientserver_ssl(int sock, UNUSED short what)
/**
* Initialize connection module.
* Initialize connecion module.
*/
GLOBAL void
Conn_Init( void )
{
CONN_ID i;
/* Speicher fuer Verbindungs-Pool anfordern */
Pool_Size = CONNECTION_POOL;
if ((Conf_MaxConnections > 0) &&
(Pool_Size > Conf_MaxConnections))
@@ -490,7 +454,7 @@ Conn_CloseAllSockets(int ExceptOf)
* @returns Number of listening sockets created.
*/
static unsigned int
Init_Listeners(array *a, const char *listen_addr, void (*func)(int,short))
ports_initlisteners(array *a, const char *listen_addr, void (*func)(int,short))
{
unsigned int created = 0;
size_t len;
@@ -506,9 +470,8 @@ Init_Listeners(array *a, const char *listen_addr, void (*func)(int,short))
continue;
}
if (!io_event_create( fd, IO_WANTREAD, func )) {
Log(LOG_ERR,
"io_event_create(): Can't add fd %d (port %u): %s!",
fd, (unsigned int) *port, strerror(errno));
Log( LOG_ERR, "io_event_create(): Could not add listening fd %d (port %u): %s!",
fd, (unsigned int) *port, strerror(errno));
close(fd);
port++;
continue;
@@ -530,76 +493,14 @@ Conn_InitListeners( void )
{
/* Initialize ports on which the server should accept connections */
unsigned int created = 0;
char *af_str, *copy, *listen_addr;
int count, fd, i, addr_len;
ng_ipaddr_t addr;
char *copy, *listen_addr;
assert(Conf_ListenAddress);
count = my_sd_listen_fds();
if (count < 0) {
Log(LOG_INFO,
"Not re-initializing listening sockets of systemd(8) ...");
return 0;
}
if (count > 0) {
/* systemd(8) passed sockets to us, so don't try to initialize
* listening sockets on our own but use the passed ones */
LogDebug("Initializing %d systemd sockets ...", count);
for (i = 0; i < count; i++) {
fd = SD_LISTEN_FDS_START + i;
addr_len = (int)sizeof(addr);
getsockname(fd, (struct sockaddr *)&addr, (socklen_t*)&addr_len);
#ifdef WANT_IPV6
if (addr.sin4.sin_family != AF_INET && addr.sin4.sin_family != AF_INET6)
#else
if (addr.sin4.sin_family != AF_INET)
#endif
{
/* Socket is of unsupported type! For example, systemd passed in
* an IPv6 socket but ngIRCd isn't compiled with IPv6 support. */
switch (addr.sin4.sin_family)
{
case AF_UNSPEC: af_str = "AF_UNSPEC"; break;
case AF_UNIX: af_str = "AF_UNIX"; break;
case AF_INET: af_str = "AF_INET"; break;
#ifdef AF_INET6
case AF_INET6: af_str = "AF_INET6"; break;
#endif
#ifdef AF_NETLINK
case AF_NETLINK: af_str = "AF_NETLINK"; break;
#endif
default: af_str = "unknown"; break;
}
Log(LOG_CRIT,
"Socket %d is of unsupported type \"%s\" (%d), have to ignore it!",
fd, af_str, addr.sin4.sin_family);
close(fd);
continue;
}
Init_Socket(fd);
if (!io_event_create(fd, IO_WANTREAD, cb_listen)) {
Log(LOG_ERR,
"io_event_create(): Can't add fd %d: %s!",
fd, strerror(errno));
continue;
}
Log(LOG_INFO,
"Initialized socket %d from systemd(8): %s:%d.", fd,
ng_ipaddr_tostr(&addr), ng_ipaddr_getport(&addr));
created++;
}
return created;
}
/* not using systemd socket activation, initialize listening sockets: */
/* can't use Conf_ListenAddress directly, see below */
copy = strdup(Conf_ListenAddress);
if (!copy) {
Log(LOG_CRIT, "Cannot copy %s: %s", Conf_ListenAddress,
strerror(errno));
Log(LOG_CRIT, "Cannot copy %s: %s", Conf_ListenAddress, strerror(errno));
return 0;
}
listen_addr = strtok(copy, ",");
@@ -607,11 +508,9 @@ Conn_InitListeners( void )
while (listen_addr) {
ngt_TrimStr(listen_addr);
if (*listen_addr) {
created += Init_Listeners(&Conf_ListenPorts,
listen_addr, cb_listen);
created += ports_initlisteners(&Conf_ListenPorts, listen_addr, cb_listen);
#ifdef SSL_SUPPORT
created += Init_Listeners(&Conf_SSLOptions.ListenPorts,
listen_addr, cb_listen_ssl);
created += ports_initlisteners(&Conf_SSLOptions.ListenPorts, listen_addr, cb_listen_ssl);
#endif
}
@@ -638,12 +537,7 @@ Conn_ExitListeners( void )
int *fd;
size_t arraylen;
/* Get number of listening sockets to shut down. There can be none
* if ngIRCd has been "socket activated" by systemd. */
arraylen = array_length(&My_Listeners, sizeof (int));
if (arraylen < 1)
return;
Log(LOG_INFO,
"Shutting down all listening sockets (%d total) ...", arraylen);
fd = array_start(&My_Listeners);
@@ -674,7 +568,7 @@ InitSinaddrListenAddr(ng_ipaddr_t *addr, const char *listen_addrstr, UINT16 Port
ret = ng_ipaddr_init(addr, listen_addrstr, Port);
if (!ret) {
assert(listen_addrstr);
Log(LOG_CRIT, "Can't bind to [%s]:%u: can't convert ip address \"%s\"!",
Log(LOG_CRIT, "Can't bind to [%s]:%u: can't convert ip address \"%s\"",
listen_addrstr, Port, listen_addrstr);
}
return ret;
@@ -726,9 +620,8 @@ NewListener(const char *listen_addr, UINT16 Port)
af = ng_ipaddr_af(&addr);
sock = socket(af, SOCK_STREAM, 0);
if (sock < 0) {
Log(LOG_CRIT, "Can't create socket (af %d) : %s!", af,
strerror(errno));
if( sock < 0 ) {
Log(LOG_CRIT, "Can't create socket (af %d) : %s!", af, strerror(errno));
return -1;
}
@@ -738,23 +631,22 @@ NewListener(const char *listen_addr, UINT16 Port)
return -1;
if (bind(sock, (struct sockaddr *)&addr, ng_ipaddr_salen(&addr)) != 0) {
Log(LOG_CRIT, "Can't bind socket to address %s:%d - %s!",
ng_ipaddr_tostr(&addr), Port, strerror(errno));
Log(LOG_CRIT, "Can't bind socket to address %s:%d - %s",
ng_ipaddr_tostr(&addr), Port, strerror(errno));
close(sock);
return -1;
}
if (listen(sock, 10) != 0) {
Log(LOG_CRIT, "Can't listen on socket: %s!", strerror(errno));
close(sock);
if( listen( sock, 10 ) != 0 ) {
Log( LOG_CRIT, "Can't listen on socket: %s!", strerror( errno ));
close( sock );
return -1;
}
/* keep fd in list so we can close it when ngircd restarts/shuts down */
if (!array_catb(&My_Listeners, (char *)&sock, sizeof(int))) {
Log(LOG_CRIT, "Can't add socket to My_Listeners array: %s!",
strerror(errno));
close(sock);
if (!array_catb( &My_Listeners,(char*) &sock, sizeof(int) )) {
Log( LOG_CRIT, "Can't add socket to My_Listeners array: %s!", strerror( errno ));
close( sock );
return -1;
}
@@ -854,7 +746,8 @@ Conn_Handler(void)
/* Look for non-empty read buffers ... */
for (i = 0; i < Pool_Size; i++) {
if ((My_Connections[i].sock > NONE)
&& (array_bytes(&My_Connections[i].rbuf) > 0)) {
&& (array_bytes(&My_Connections[i].rbuf) > 0)
&& (My_Connections[i].delaytime <= t)) {
/* ... and try to handle the received data */
bytes_processed = Handle_Buffer(i);
/* if we processed data, and there might be
@@ -924,7 +817,7 @@ Conn_Handler(void)
* which is the granularity with witch we handle "penalty
* times" for example.
* Note: tv_sec/usec are undefined(!) after io_dispatch()
* returns, so we have to set it before each call to it! */
* returns, so we have to set it beforce each call to it! */
tv.tv_usec = 0;
tv.tv_sec = 1;
@@ -937,15 +830,6 @@ Conn_Handler(void)
PACKAGE_NAME);
exit(1);
}
/* Should ngIRCd timeout when idle? */
if (Conf_IdleTimeout > 0 && NumConnectionsAccepted > 0
&& idle_t > 0 && time(NULL) - idle_t >= Conf_IdleTimeout) {
LogDebug("Server idle timeout reached: %d second%s. Initiating shutdown ...",
Conf_IdleTimeout,
Conf_IdleTimeout == 1 ? "" : "s");
NGIRCd_SignalQuit = true;
}
}
if (NGIRCd_SignalQuit)
@@ -1009,7 +893,7 @@ va_dcl
*
* So we have a big problem here: we should send more bytes
* to the network than we are allowed to and we don't know
* the originator (any more). The "old" behavior of blaming
* the originator (any more). The "old" behaviour of blaming
* the receiver ("next hop") is a bad idea (it could be just
* an other server only routing the message!), so the only
* option left is to shorten the string and to hope that the
@@ -1183,8 +1067,8 @@ Conn_Close( CONN_ID Idx, const char *LogMsg, const char *FwdMsg, bool InformClie
/* Is this link already shutting down? */
if( Conn_OPTION_ISSET( &My_Connections[Idx], CONN_ISCLOSING )) {
/* Conn_Close() has been called recursively for this link;
* probable reason: Handle_Write() failed -- see below. */
LogDebug("Recursive request to close connection %d!", Idx );
* probabe reason: Handle_Write() failed -- see below. */
LogDebug("Recursive request to close connection: %d", Idx );
return;
}
@@ -1194,7 +1078,7 @@ Conn_Close( CONN_ID Idx, const char *LogMsg, const char *FwdMsg, bool InformClie
Conn_OPTION_ADD( &My_Connections[Idx], CONN_ISCLOSING );
port = ng_ipaddr_getport(&My_Connections[Idx].addr);
Log(LOG_INFO, "Shutting down connection %d (%s) with \"%s:%d\" ...", Idx,
Log(LOG_INFO, "Shutting down connection %d (%s) with %s:%d ...", Idx,
LogMsg ? LogMsg : FwdMsg, My_Connections[Idx].host, port);
/* Search client, if any */
@@ -1230,7 +1114,7 @@ Conn_Close( CONN_ID Idx, const char *LogMsg, const char *FwdMsg, bool InformClie
c = Conn_GetClient( Idx );
#ifdef SSL_SUPPORT
if ( Conn_OPTION_ISSET( &My_Connections[Idx], CONN_SSL )) {
LogDebug("SSL connection %d shutting down ...", Idx);
Log(LOG_INFO, "SSL connection %d shutting down ...", Idx);
ConnSSL_Free(&My_Connections[Idx]);
}
#endif
@@ -1268,7 +1152,7 @@ Conn_Close( CONN_ID Idx, const char *LogMsg, const char *FwdMsg, bool InformClie
in_p = (int)(( in_k * 100 ) / in_z_k );
out_p = (int)(( out_k * 100 ) / out_z_k );
Log(LOG_INFO,
"Connection %d with \"%s:%d\" closed (in: %.1fk/%.1fk/%d%%, out: %.1fk/%.1fk/%d%%).",
"Connection %d with %s:%d closed (in: %.1fk/%.1fk/%d%%, out: %.1fk/%.1fk/%d%%).",
Idx, My_Connections[Idx].host, port,
in_k, in_z_k, in_p, out_k, out_z_k, out_p);
}
@@ -1276,7 +1160,7 @@ Conn_Close( CONN_ID Idx, const char *LogMsg, const char *FwdMsg, bool InformClie
#endif
{
Log(LOG_INFO,
"Connection %d with \"%s:%d\" closed (in: %.1fk, out: %.1fk).",
"Connection %d with %s:%d closed (in: %.1fk, out: %.1fk).",
Idx, My_Connections[Idx].host, port,
in_k, out_k);
}
@@ -1307,8 +1191,6 @@ Conn_Close( CONN_ID Idx, const char *LogMsg, const char *FwdMsg, bool InformClie
NumConnections--;
LogDebug("Shutdown of connection %d completed, %ld connection%s left.",
Idx, NumConnections, NumConnections != 1 ? "s" : "");
idle_t = NumConnections > 0 ? 0 : time(NULL);
} /* Conn_Close */
@@ -1452,14 +1334,9 @@ Handle_Write( CONN_ID Idx )
if (errno == EAGAIN || errno == EINTR)
return true;
if (!Conn_OPTION_ISSET(&My_Connections[Idx], CONN_ISCLOSING))
Log(LOG_ERR,
"Write error on connection %d (socket %d): %s!",
Idx, My_Connections[Idx].sock, strerror(errno));
else
LogDebug("Recursive write error on connection %d (socket %d): %s!",
Idx, My_Connections[Idx].sock, strerror(errno));
Conn_Close(Idx, "Write error", NULL, false);
Log(LOG_ERR, "Write error on connection %d (socket %d): %s!",
Idx, My_Connections[Idx].sock, strerror(errno));
Conn_Close(Idx, "Write error!", NULL, false);
return false;
}
@@ -1623,7 +1500,7 @@ New_Connection(int Sock, UNUSED bool IsSSL)
Client_SetHostname(c, My_Connections[new_sock].host);
Log(LOG_INFO, "Accepted connection %d from \"%s:%d\" on socket %d.",
Log(LOG_INFO, "Accepted connection %d from %s:%d on socket %d.",
new_sock, My_Connections[new_sock].host,
ng_ipaddr_getport(&new_addr), Sock);
Account_Connection();
@@ -1689,7 +1566,6 @@ static void
Account_Connection(void)
{
NumConnections++;
idle_t = 0;
if (NumConnections > NumConnectionsMax)
NumConnectionsMax = NumConnections;
LogDebug("Total number of connections now %lu (max %lu).",
@@ -1719,7 +1595,7 @@ Socket2Index( int Sock )
/**
* Read data from the network to the read buffer. If an error occurs,
* Read data from the network to the read buffer. If an error occures,
* the socket of this connection will be shut down.
*
* @param Idx Connection index.
@@ -1757,10 +1633,13 @@ Read_Request( CONN_ID Idx )
#endif
len = read(My_Connections[Idx].sock, readbuf, sizeof(readbuf));
if (len == 0) {
LogDebug("Client \"%s:%u\" is closing connection %d ...",
My_Connections[Idx].host,
ng_ipaddr_tostr(&My_Connections[Idx].addr), Idx);
Conn_Close(Idx, NULL, "Client closed connection", false);
Log(LOG_INFO, "%s:%u (%s) is closing the connection ...",
My_Connections[Idx].host,
(unsigned int) ng_ipaddr_getport(&My_Connections[Idx].addr),
ng_ipaddr_tostr(&My_Connections[Idx].addr));
Conn_Close(Idx,
"Socket closed!", "Client closed connection",
false);
return;
}
@@ -1768,7 +1647,7 @@ Read_Request( CONN_ID Idx )
if( errno == EAGAIN ) return;
Log(LOG_ERR, "Read error on connection %d (socket %d): %s!",
Idx, My_Connections[Idx].sock, strerror(errno));
Conn_Close(Idx, "Read error", "Client closed connection",
Conn_Close(Idx, "Read error!", "Client closed connection",
false);
return;
}
@@ -1868,7 +1747,7 @@ Handle_Buffer(CONN_ID Idx)
maxcmd = (int)(Client_UserCount() / 5)
+ MAX_COMMANDS_SERVER_MIN;
/* Allow servers to handle even more commands while peering
* to speed up server login and network synchronization. */
* to speed up server login and network synchronisation. */
if (Conn_LastPing(Idx) == 0)
maxcmd *= 5;
break;
@@ -2133,7 +2012,6 @@ New_Server( int Server , ng_ipaddr_t *dest)
if (!ng_ipaddr_tostr_r(dest, ip_str)) {
Log(LOG_WARNING, "New_Server: Could not convert IP to string");
Conf_Server[Server].conn_id = NONE;
return;
}
@@ -2148,14 +2026,11 @@ New_Server( int Server , ng_ipaddr_t *dest)
if (new_sock < 0) {
Log(LOG_CRIT, "Can't create socket (af %d): %s!",
af_dest, strerror(errno));
Conf_Server[Server].conn_id = NONE;
return;
}
if (!Init_Socket(new_sock)) {
Conf_Server[Server].conn_id = NONE;
if (!Init_Socket(new_sock))
return;
}
/* is a bind address configured? */
res = ng_ipaddr_af(&Conf_Server[Server].bind_addr);
@@ -2171,7 +2046,6 @@ New_Server( int Server , ng_ipaddr_t *dest)
if(( res != 0 ) && ( errno != EINPROGRESS )) {
Log( LOG_CRIT, "Can't connect socket: %s!", strerror( errno ));
close( new_sock );
Conf_Server[Server].conn_id = NONE;
return;
}
@@ -2180,14 +2054,12 @@ New_Server( int Server , ng_ipaddr_t *dest)
"Cannot allocate memory for server connection (socket %d)",
new_sock);
close( new_sock );
Conf_Server[Server].conn_id = NONE;
return;
}
if (!io_event_create( new_sock, IO_WANTWRITE, cb_connserver)) {
Log(LOG_ALERT, "io_event_create(): could not add fd %d", strerror(errno));
close(new_sock);
Conf_Server[Server].conn_id = NONE;
return;
}
@@ -2202,7 +2074,6 @@ New_Server( int Server , ng_ipaddr_t *dest)
if (!c) {
Log( LOG_ALERT, "Can't establish connection: can't create client structure!" );
io_close(new_sock);
Conf_Server[Server].conn_id = NONE;
return;
}
@@ -2370,7 +2241,7 @@ cb_Connect_to_Server(int fd, UNUSED short events)
/**
* Read results of a resolver sub-process from the pipe and update the
* appropriate connection/client structure(s): hostname and/or IDENT user name.
* apropriate connection/client structure(s): hostname and/or IDENT user name.
*
* @param r_fd File descriptor of the pipe to the sub-process.
* @param events (ignored IO specification)
@@ -2464,9 +2335,9 @@ cb_Read_Resolver_Result( int r_fd, UNUSED short events )
*ptr ? "" : ": ",
*ptr ? "" : identptr);
}
} else if(Conf_Ident) {
} else {
Log(LOG_INFO, "IDENT lookup for connection %d: no result.", i);
if (Conf_NoticeAuth)
if (Conf_NoticeAuth && Conf_Ident)
(void)Conn_WriteStr(i,
"NOTICE AUTH :*** No ident response");
}
@@ -2483,8 +2354,7 @@ cb_Read_Resolver_Result( int r_fd, UNUSED short events )
Class_HandleServerBans(c);
}
#ifdef DEBUG
else
LogDebug("Resolver: discarding result for already registered connection %d.", i);
else Log( LOG_DEBUG, "Resolver: discarding result for already registered connection %d.", i );
#endif
} /* cb_Read_Resolver_Result */
@@ -2603,7 +2473,7 @@ Conn_SetAuthPing(CONN_ID Idx, long ID)
#ifdef SSL_SUPPORT
/**
* Get information about used SSL cipher.
* Get information about used SSL chiper.
*
* @param Idx Connection index number.
* @param buf Buffer for returned information text.
@@ -2635,45 +2505,6 @@ Conn_UsesSSL(CONN_ID Idx)
return Conn_OPTION_ISSET(&My_Connections[Idx], CONN_SSL);
}
GLOBAL char *
Conn_GetCertFp(CONN_ID Idx)
{
if (Idx < 0)
return NULL;
assert(Idx < (int) array_length(&My_ConnArray, sizeof(CONNECTION)));
return ConnSSL_GetCertFp(&My_Connections[Idx]);
}
GLOBAL bool
Conn_SetCertFp(CONN_ID Idx, const char *fingerprint)
{
if (Idx < 0)
return false;
assert(Idx < (int) array_length(&My_ConnArray, sizeof(CONNECTION)));
return ConnSSL_SetCertFp(&My_Connections[Idx], fingerprint);
}
#else
GLOBAL bool
Conn_UsesSSL(UNUSED CONN_ID Idx)
{
return false;
}
GLOBAL char *
Conn_GetCertFp(UNUSED CONN_ID Idx)
{
return NULL;
}
GLOBAL bool
Conn_SetCertFp(UNUSED CONN_ID Idx, UNUSED const char *fingerprint)
{
return true;
}
#endif

View File

@@ -139,12 +139,13 @@ GLOBAL CONN_ID Conn_GetFromProc PARAMS((int fd));
GLOBAL CLIENT* Conn_GetClient PARAMS((CONN_ID i));
GLOBAL PROC_STAT* Conn_GetProcStat PARAMS((CONN_ID i));
GLOBAL char *Conn_GetCertFp PARAMS((CONN_ID Idx));
GLOBAL bool Conn_SetCertFp PARAMS((CONN_ID Idx, const char *fingerprint));
GLOBAL bool Conn_UsesSSL PARAMS((CONN_ID Idx));
#ifdef SSL_SUPPORT
GLOBAL bool Conn_GetCipherInfo PARAMS((CONN_ID Idx, char *buf, size_t len));
GLOBAL bool Conn_UsesSSL PARAMS((CONN_ID Idx));
#else
static inline bool
Conn_UsesSSL(UNUSED CONN_ID Idx)
{ return false; }
#endif
GLOBAL const char *Conn_GetIPAInfo PARAMS((CONN_ID Idx));

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2013 Alexander Barton (alex@barton.de) and Contributors.
* Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
*
* 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
@@ -36,7 +36,7 @@
/* Generic buffer sizes */
/** Max. length of a line in the configuration file. */
#define LINE_LEN 1024
#define LINE_LEN 256
/** Max. length of a log message. */
#define MAX_LOG_MSG_LEN 256
@@ -50,6 +50,7 @@
/** Max. length of random salt */
#define RANDOM_SALT_LEN 32
/* Size of structures */
/** Max. count of configurable servers. */
@@ -73,15 +74,9 @@
/** Configuration file name. */
#define CONFIG_FILE "/ngircd.conf"
/** Directory containing optional configuration snippets. */
#define CONFIG_DIR "/ngircd.conf.d"
/** Name of the MOTD file. */
#define MOTD_FILE "/ngircd.motd"
/** Name of the help file. */
#define HELP_FILE "/Commands.txt"
/** Default chroot() directory. */
#define CHROOT_DIR ""
@@ -101,7 +96,7 @@
#define CLIENT_NICK_LEN 32
/** Max. password length (including NULL). */
#define CLIENT_PASS_LEN 65
#define CLIENT_PASS_LEN 21
/** Max. length of user name ("login"; incl. NULL), RFC 2812, section 1.2.1. */
#ifndef STRICT_RFC
@@ -116,9 +111,6 @@
/** Max. host name length (including NULL). */
#define CLIENT_HOST_LEN 64
/** Max. mask lenght (including NULL). */
#define MASK_LEN (2 * CLIENT_HOST_LEN)
/** Max. length of all client modes (including NULL). */
#define CLIENT_MODE_LEN 21
@@ -178,9 +170,6 @@
/** Supported channel modes. */
#define CHANMODES "abehiIklmMnoOPqQrRstvVz"
/** Supported channel types. */
#define CHANTYPES "#&+"
/** Away message for users connected to linked servers. */
#define DEFAULT_AWAY_MSG "Away"

View File

@@ -37,7 +37,7 @@ static UINT32 jenkins_hash PARAMS((UINT8 *k, UINT32 length, UINT32 initval));
GLOBAL UINT32
Hash( const char *String )
{
char buffer[COMMAND_LEN];
char buffer[LINE_LEN];
strlcpy(buffer, String, sizeof(buffer));
return jenkins_hash((UINT8 *)ngt_LowerStr(buffer),

View File

@@ -631,7 +631,7 @@ io_library_init_kqueue(unsigned int eventsize)
io_masterfd = kqueue();
Log(LOG_INFO,
"IO subsystem: kqueue (initial maxfd %u, masterfd %d).",
"IO subsystem: kqueue (initial maxfd %u, masterfd %d)",
eventsize, io_masterfd);
if (io_masterfd >= 0)
library_initialized = true;

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2013 Alexander Barton (alex@barton.de) and Contributors.
* Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
*
* 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
@@ -24,7 +24,6 @@
#include "conn.h"
#include "channel.h"
#include "client-cap.h"
#include "irc-macros.h"
#include "irc-write.h"
#include "log.h"
#include "login.h"
@@ -34,14 +33,192 @@
#include "exp.h"
#include "irc-cap.h"
/* Local functions */
bool Handle_CAP_LS PARAMS((CLIENT *Client, char *Arg));
bool Handle_CAP_LIST PARAMS((CLIENT *Client, char *Arg));
bool Handle_CAP_REQ PARAMS((CLIENT *Client, char *Arg));
bool Handle_CAP_ACK PARAMS((CLIENT *Client, char *Arg));
bool Handle_CAP_CLEAR PARAMS((CLIENT *Client));
bool Handle_CAP_END PARAMS((CLIENT *Client));
void Set_CAP_Negotiation PARAMS((CLIENT *Client));
int Parse_CAP PARAMS((int Capabilities, char *Args));
char *Get_CAP_String PARAMS((int Capabilities));
/**
* Handler for the IRCv3 "CAP" command.
*
* @param Client The client from which this command has been received.
* @param Req Request structure with prefix and all parameters.
* @returns CONNECTED or DISCONNECTED.
*/
GLOBAL bool
IRC_CAP(CLIENT *Client, REQUEST *Req)
{
assert(Client != NULL);
assert(Req != NULL);
/* Bad number of prameters? */
if (Req->argc < 1 || Req->argc > 2)
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
LogDebug("Got \"%s %s\" command from \"%s\" ...",
Req->command, Req->argv[0], Client_ID(Client));
if (Req->argc == 1) {
if (strcasecmp(Req->argv[0], "CLEAR") == 0)
return Handle_CAP_CLEAR(Client);
if (strcasecmp(Req->argv[0], "END") == 0)
return Handle_CAP_END(Client);
}
if (Req->argc >= 1 && Req->argc <= 2) {
if (strcasecmp(Req->argv[0], "LS") == 0)
return Handle_CAP_LS(Client, Req->argv[1]);
if (strcasecmp(Req->argv[0], "LIST") == 0)
return Handle_CAP_LIST(Client, Req->argv[1]);
}
if (Req->argc == 2) {
if (strcasecmp(Req->argv[0], "REQ") == 0)
return Handle_CAP_REQ(Client, Req->argv[1]);
if (strcasecmp(Req->argv[0], "ACK") == 0)
return Handle_CAP_ACK(Client, Req->argv[1]);
}
return IRC_WriteStrClient(Client, ERR_INVALIDCAP_MSG,
Client_ID(Client), Req->argv[0]);
}
/**
* Handler for the "CAP LS" command.
*
* @param Client The client from which this command has been received.
* @param Arg Command argument or NULL.
* @returns CONNECTED or DISCONNECTED.
*/
bool
Handle_CAP_LS(CLIENT *Client, UNUSED char *Arg)
{
assert(Client != NULL);
Set_CAP_Negotiation(Client);
return IRC_WriteStrClient(Client,
"CAP %s LS :multi-prefix",
Client_ID(Client));
}
/**
* Handler for the "CAP LIST" command.
*
* @param Client The client from which this command has been received.
* @param Arg Command argument or NULL.
* @returns CONNECTED or DISCONNECTED.
*/
bool
Handle_CAP_LIST(CLIENT *Client, UNUSED char *Arg)
{
assert(Client != NULL);
return IRC_WriteStrClient(Client, "CAP %s LIST :%s", Client_ID(Client),
Get_CAP_String(Client_Cap(Client)));
}
/**
* Handler for the "CAP REQ" command.
*
* @param Client The client from which this command has been received.
* @param Arg Command argument.
* @returns CONNECTED or DISCONNECTED.
*/
bool
Handle_CAP_REQ(CLIENT *Client, char *Arg)
{
int new_cap;
assert(Client != NULL);
assert(Arg != NULL);
Set_CAP_Negotiation(Client);
new_cap = Parse_CAP(Client_Cap(Client), Arg);
if (new_cap < 0)
return IRC_WriteStrClient(Client, "CAP %s NAK :%s",
Client_ID(Client), Arg);
Client_CapSet(Client, new_cap);
return IRC_WriteStrClient(Client, "CAP %s ACK :%s",
Client_ID(Client), Arg);
}
/**
* Handler for the "CAP ACK" command.
*
* @param Client The client from which this command has been received.
* @param Arg Command argument.
* @returns CONNECTED or DISCONNECTED.
*/
bool
Handle_CAP_ACK(UNUSED CLIENT *Client, UNUSED char *Arg)
{
assert(Client != NULL);
assert(Arg != NULL);
return CONNECTED;
}
/**
* Handler for the "CAP CLEAR" command.
*
* @param Client The client from which this command has been received.
* @returns CONNECTED or DISCONNECTED.
*/
bool
Handle_CAP_CLEAR(CLIENT *Client)
{
int cap_old;
assert(Client != NULL);
cap_old = Client_Cap(Client);
if (cap_old & CLIENT_CAP_MULTI_PREFIX)
Client_CapDel(Client, CLIENT_CAP_MULTI_PREFIX);
return IRC_WriteStrClient(Client, "CAP %s ACK :%s", Client_ID(Client),
Get_CAP_String(cap_old));
}
/**
* Handler for the "CAP END" command.
*
* @param Client The client from which this command has been received.
* @returns CONNECTED or DISCONNECTED.
*/
bool
Handle_CAP_END(CLIENT *Client)
{
assert(Client != NULL);
if (Client_Type(Client) != CLIENT_USER) {
/* User is still logging in ... */
Client_CapDel(Client, CLIENT_CAP_PENDING);
if (Client_Type(Client) == CLIENT_WAITCAPEND) {
/* Only "CAP END" was missing: log in! */
return Login_User(Client);
}
}
return CONNECTED;
}
/**
* Set CAP negotiation status and mark client as "supports capabilities".
*
* @param Client The client to handle.
*/
static void
void
Set_CAP_Negotiation(CLIENT *Client)
{
assert(Client != NULL);
@@ -57,7 +234,7 @@ Set_CAP_Negotiation(CLIENT *Client)
* @param Args The string containing space-separated capability names.
* @return Changed capability flags or 0 on error.
*/
static int
int
Parse_CAP(int Capabilities, char *Args)
{
static char tmp[COMMAND_LEN];
@@ -98,7 +275,7 @@ Parse_CAP(int Capabilities, char *Args)
* @param Capabilities Capability flags (bitmask).
* @return Pointer to textual representation.
*/
static char *
char *
Get_CAP_String(int Capabilities)
{
static char txt[COMMAND_LEN];
@@ -111,169 +288,4 @@ Get_CAP_String(int Capabilities)
return txt;
}
/**
* Handler for the IRCv3 sub-command "CAP LS".
*
* @param Client The client from which this command has been received.
* @param Arg Command argument or NULL.
* @return CONNECTED or DISCONNECTED.
*/
static bool
Handle_CAP_LS(CLIENT *Client, UNUSED char *Arg)
{
assert(Client != NULL);
Set_CAP_Negotiation(Client);
return IRC_WriteStrClient(Client,
"CAP %s LS :multi-prefix",
Client_ID(Client));
}
/**
* Handler for the IRCv3 sub-command "CAP LIST".
*
* @param Client The client from which this command has been received.
* @param Arg Command argument or NULL.
* @return CONNECTED or DISCONNECTED.
*/
static bool
Handle_CAP_LIST(CLIENT *Client, UNUSED char *Arg)
{
assert(Client != NULL);
return IRC_WriteStrClient(Client, "CAP %s LIST :%s", Client_ID(Client),
Get_CAP_String(Client_Cap(Client)));
}
/**
* Handler for the IRCv3 sub-command "CAP REQ".
*
* @param Client The client from which this command has been received.
* @param Arg Command argument.
* @return CONNECTED or DISCONNECTED.
*/
static bool
Handle_CAP_REQ(CLIENT *Client, char *Arg)
{
int new_cap;
assert(Client != NULL);
assert(Arg != NULL);
Set_CAP_Negotiation(Client);
new_cap = Parse_CAP(Client_Cap(Client), Arg);
if (new_cap < 0)
return IRC_WriteStrClient(Client, "CAP %s NAK :%s",
Client_ID(Client), Arg);
Client_CapSet(Client, new_cap);
return IRC_WriteStrClient(Client, "CAP %s ACK :%s",
Client_ID(Client), Arg);
}
/**
* Handler for the IRCv3 sub-command "CAP ACK".
*
* @param Client The client from which this command has been received.
* @param Arg Command argument.
* @return CONNECTED or DISCONNECTED.
*/
static bool
Handle_CAP_ACK(UNUSED CLIENT *Client, UNUSED char *Arg)
{
assert(Client != NULL);
assert(Arg != NULL);
return CONNECTED;
}
/**
* Handler for the IRCv3 sub-command "CAP CLEAR".
*
* @param Client The client from which this command has been received.
* @return CONNECTED or DISCONNECTED.
*/
static bool
Handle_CAP_CLEAR(CLIENT *Client)
{
int cap_old;
assert(Client != NULL);
cap_old = Client_Cap(Client);
if (cap_old & CLIENT_CAP_MULTI_PREFIX)
Client_CapDel(Client, CLIENT_CAP_MULTI_PREFIX);
return IRC_WriteStrClient(Client, "CAP %s ACK :%s", Client_ID(Client),
Get_CAP_String(cap_old));
}
/**
* Handler for the IRCv3 sub-command "CAP END".
*
* @param Client The client from which this command has been received.
* @return CONNECTED or DISCONNECTED.
*/
static bool
Handle_CAP_END(CLIENT *Client)
{
assert(Client != NULL);
if (Client_Type(Client) != CLIENT_USER) {
/* User is still logging in ... */
Client_CapDel(Client, CLIENT_CAP_PENDING);
if (Client_Type(Client) == CLIENT_WAITCAPEND) {
/* Only "CAP END" was missing: log in! */
return Login_User(Client);
}
}
return CONNECTED;
}
/* Global functions */
/**
* Handler for the IRCv3 command "CAP".
*
* @param Client The client from which this command has been received.
* @param Req Request structure with prefix and all parameters.
* @return CONNECTED or DISCONNECTED.
*/
GLOBAL bool
IRC_CAP(CLIENT *Client, REQUEST *Req)
{
assert(Client != NULL);
assert(Req != NULL);
LogDebug("Got \"%s %s\" command from \"%s\" ...",
Req->command, Req->argv[0], Client_ID(Client));
if (Req->argc == 1) {
if (strcasecmp(Req->argv[0], "CLEAR") == 0)
return Handle_CAP_CLEAR(Client);
if (strcasecmp(Req->argv[0], "END") == 0)
return Handle_CAP_END(Client);
}
if (Req->argc >= 1 && Req->argc <= 2) {
if (strcasecmp(Req->argv[0], "LS") == 0)
return Handle_CAP_LS(Client, Req->argv[1]);
if (strcasecmp(Req->argv[0], "LIST") == 0)
return Handle_CAP_LIST(Client, Req->argv[1]);
}
if (Req->argc == 2) {
if (strcasecmp(Req->argv[0], "REQ") == 0)
return Handle_CAP_REQ(Client, Req->argv[1]);
if (strcasecmp(Req->argv[0], "ACK") == 0)
return Handle_CAP_ACK(Client, Req->argv[1]);
}
return IRC_WriteErrClient(Client, ERR_INVALIDCAP_MSG,
Client_ID(Client), Req->argv[0]);
}
/* -eof- */

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2013 Alexander Barton (alex@barton.de) and Contributors.
* Copyright (c)2001-2010 Alexander Barton (alex@barton.de)
*
* 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
@@ -33,13 +33,13 @@
#include "parse.h"
#include "irc.h"
#include "irc-info.h"
#include "irc-macros.h"
#include "irc-write.h"
#include "conf.h"
#include "exp.h"
#include "irc-channel.h"
/**
* Part from all channels.
*
@@ -67,6 +67,7 @@ part_from_all_channels(CLIENT* client, CLIENT *target)
return CONNECTED;
} /* part_from_all_channels */
/**
* Check weather a local client is allowed to join an already existing
* channel or not.
@@ -82,9 +83,10 @@ join_allowed(CLIENT *Client, CHANNEL *chan, const char *channame,
const char *key)
{
bool is_invited, is_banned, is_exception;
const char *channel_modes;
/* Allow IRC operators to overwrite channel limits */
if (Client_HasMode(Client, 'o'))
if (strchr(Client_Modes(Client), 'o'))
return true;
is_banned = Lists_Check(Channel_GetListBans(chan), Client);
@@ -93,14 +95,15 @@ join_allowed(CLIENT *Client, CHANNEL *chan, const char *channame,
if (is_banned && !is_invited && !is_exception) {
/* Client is banned from channel (and not on invite list) */
IRC_WriteErrClient(Client, ERR_BANNEDFROMCHAN_MSG,
IRC_WriteStrClient(Client, ERR_BANNEDFROMCHAN_MSG,
Client_ID(Client), channame);
return false;
}
if (Channel_HasMode(chan, 'i') && !is_invited) {
channel_modes = Channel_Modes(chan);
if (strchr(channel_modes, 'i') && !is_invited) {
/* Channel is "invite-only" and client is not on invite list */
IRC_WriteErrClient(Client, ERR_INVITEONLYCHAN_MSG,
IRC_WriteStrClient(Client, ERR_INVITEONLYCHAN_MSG,
Client_ID(Client), channame);
return false;
}
@@ -108,37 +111,37 @@ join_allowed(CLIENT *Client, CHANNEL *chan, const char *channame,
if (!Channel_CheckKey(chan, Client, key ? key : "")) {
/* Channel is protected by a channel key and the client
* didn't specify the correct one */
IRC_WriteErrClient(Client, ERR_BADCHANNELKEY_MSG,
IRC_WriteStrClient(Client, ERR_BADCHANNELKEY_MSG,
Client_ID(Client), channame);
return false;
}
if (Channel_HasMode(chan, 'l') &&
if (strchr(channel_modes, 'l') &&
(Channel_MaxUsers(chan) <= Channel_MemberCount(chan))) {
/* There are more clints joined to this channel than allowed */
IRC_WriteErrClient(Client, ERR_CHANNELISFULL_MSG,
IRC_WriteStrClient(Client, ERR_CHANNELISFULL_MSG,
Client_ID(Client), channame);
return false;
}
if (Channel_HasMode(chan, 'z') && !Conn_UsesSSL(Client_Conn(Client))) {
if (strchr(channel_modes, 'z') && !Conn_UsesSSL(Client_Conn(Client))) {
/* Only "secure" clients are allowed, but clients doesn't
* use SSL encryption */
IRC_WriteErrClient(Client, ERR_SECURECHANNEL_MSG,
IRC_WriteStrClient(Client, ERR_SECURECHANNEL_MSG,
Client_ID(Client), channame);
return false;
}
if (Channel_HasMode(chan, 'O') && !Client_HasMode(Client, 'o')) {
if (strchr(channel_modes, 'O') && !Client_OperByMe(Client)) {
/* Only IRC operators are allowed! */
IRC_WriteErrClient(Client, ERR_OPONLYCHANNEL_MSG,
IRC_WriteStrClient(Client, ERR_OPONLYCHANNEL_MSG,
Client_ID(Client), channame);
return false;
}
if (Channel_HasMode(chan, 'R') && !Client_HasMode(Client, 'R')) {
if (strchr(channel_modes, 'R') && !strchr(Client_Modes(Client), 'R')) {
/* Only registered users are allowed! */
IRC_WriteErrClient(Client, ERR_REGONLYCHANNEL_MSG,
IRC_WriteStrClient(Client, ERR_REGONLYCHANNEL_MSG,
Client_ID(Client), channame);
return false;
}
@@ -146,6 +149,7 @@ join_allowed(CLIENT *Client, CHANNEL *chan, const char *channame,
return true;
} /* join_allowed */
/**
* Set user channel modes.
*
@@ -165,15 +169,16 @@ join_set_channelmodes(CHANNEL *chan, CLIENT *target, const char *flags)
/* If the channel is persistent (+P) and client is an IRC op:
* make client chanop, if not disabled in configuration. */
if (Channel_HasMode(chan, 'P') && Conf_OperChanPAutoOp
&& Client_HasMode(target, 'o'))
if (strchr(Channel_Modes(chan), 'P') && Conf_OperChanPAutoOp
&& strchr(Client_Modes(target), 'o'))
Channel_UserModeAdd(chan, target, 'o');
} /* join_set_channelmodes */
/**
* Forward JOIN command to a specific server
*
* This function differentiates between servers using RFC 2813 mode that
* This function diffentiates between servers using RFC 2813 mode that
* support the JOIN command with appended ASCII 7 character and channel
* modes, and servers using RFC 1459 protocol which require separate JOIN
* and MODE commands.
@@ -206,6 +211,7 @@ cb_join_forward(CLIENT *To, CLIENT *Prefix, void *Data)
Client_ID(Prefix));
} /* cb_join_forward */
/**
* Forward JOIN command to all servers
*
@@ -250,8 +256,9 @@ join_forward(CLIENT *Client, CLIENT *target, CHANNEL *chan,
}
} /* join_forward */
/**
* Acknowledge user JOIN request and send "channel info" numerics.
* Aknowledge user JOIN request and send "channel info" numerics.
*
* @param Client Client used to prefix the genrated commands
* @param target Forward commands/numerics to this user
@@ -292,12 +299,15 @@ join_send_topic(CLIENT *Client, CLIENT *target, CHANNEL *chan,
Channel_Name(chan));
} /* join_send_topic */
/**
* Handler for the IRC "JOIN" command.
*
* @param Client The client from which this command has been received.
* @param Req Request structure with prefix and all parameters.
* @return CONNECTED or DISCONNECTED.
* See RFC 2812, 3.2.1 "Join message"; RFC 2813, 4.2.1 "Join message".
*
* @param Client The client from which this command has been received
* @param Req Request structure with prefix and all parameters
* @returns CONNECTED or DISCONNECTED
*/
GLOBAL bool
IRC_JOIN( CLIENT *Client, REQUEST *Req )
@@ -309,7 +319,20 @@ IRC_JOIN( CLIENT *Client, REQUEST *Req )
assert (Client != NULL);
assert (Req != NULL);
_IRC_GET_SENDER_OR_RETURN_(target, Req, Client)
/* Bad number of arguments? */
if (Req->argc < 1 || Req->argc > 2)
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
/* Who is the sender? */
if (Client_Type(Client) == CLIENT_SERVER)
target = Client_Search(Req->prefix);
else
target = Client;
if (!target)
return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG,
Client_ID(Client), Req->prefix);
/* Is argument "0"? */
if (Req->argc == 1 && !strncmp("0", Req->argv[0], 2))
@@ -323,11 +346,9 @@ IRC_JOIN( CLIENT *Client, REQUEST *Req )
channame = strtok_r(channame, ",", &lastchan);
/* Make sure that "channame" is not the empty string ("JOIN :") */
if (!channame) {
IRC_SetPenalty(Client, 2);
return IRC_WriteErrClient(Client, ERR_NEEDMOREPARAMS_MSG,
if (! channame)
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
}
while (channame) {
flags = NULL;
@@ -342,6 +363,12 @@ IRC_JOIN( CLIENT *Client, REQUEST *Req )
}
chan = Channel_Search(channame);
if (!chan && Conf_PredefChannelsOnly) {
/* channel must be created, but forbidden by config */
IRC_WriteStrClient(Client, ERR_NOSUCHCHANNEL_MSG,
Client_ID(Client), channame);
goto join_next;
}
/* Local client? */
if (Client_Type(Client) == CLIENT_USER) {
@@ -349,21 +376,12 @@ IRC_JOIN( CLIENT *Client, REQUEST *Req )
/* Already existing channel: already member? */
if (Channel_IsMemberOf(chan, Client))
goto join_next;
} else {
/* Channel must be created */
if (!strchr(Conf_AllowedChannelTypes, channame[0])) {
/* ... but channel type is not allowed! */
IRC_WriteErrClient(Client,
ERR_NOSUCHCHANNEL_MSG,
Client_ID(Client), channame);
goto join_next;
}
}
/* Test if the user has reached the channel limit */
if ((Conf_MaxJoins > 0) &&
(Channel_CountForUser(Client) >= Conf_MaxJoins)) {
if (!IRC_WriteErrClient(Client,
if (!IRC_WriteStrClient(Client,
ERR_TOOMANYCHANNELS_MSG,
Client_ID(Client), channame))
return DISCONNECTED;
@@ -425,12 +443,15 @@ IRC_JOIN( CLIENT *Client, REQUEST *Req )
return CONNECTED;
} /* IRC_JOIN */
/**
* Handler for the IRC "PART" command.
*
* @param Client The client from which this command has been received.
* @param Req Request structure with prefix and all parameters.
* @return CONNECTED or DISCONNECTED.
* See RFC 2812, 3.2.2: "Part message".
*
* @param Client The client from which this command has been received
* @param Req Request structure with prefix and all parameters
* @returns CONNECTED or DISCONNECTED
*/
GLOBAL bool
IRC_PART(CLIENT * Client, REQUEST * Req)
@@ -441,17 +462,26 @@ IRC_PART(CLIENT * Client, REQUEST * Req)
assert(Client != NULL);
assert(Req != NULL);
_IRC_GET_SENDER_OR_RETURN_(target, Req, Client)
if (Req->argc < 1 || Req->argc > 2)
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
/* Get the sender */
if (Client_Type(Client) == CLIENT_SERVER)
target = Client_Search(Req->prefix);
else
target = Client;
if (!target)
return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG,
Client_ID(Client), Req->prefix);
/* Loop over all the given channel names */
chan = strtok(Req->argv[0], ",");
/* Make sure that "chan" is not the empty string ("PART :") */
if (!chan) {
IRC_SetPenalty(Client, 2);
return IRC_WriteErrClient(Client, ERR_NEEDMOREPARAMS_MSG,
if (! chan)
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
}
while (chan) {
Channel_Part(target, Client, chan,
@@ -466,12 +496,15 @@ IRC_PART(CLIENT * Client, REQUEST * Req)
return CONNECTED;
} /* IRC_PART */
/**
* Handler for the IRC "TOPIC" command.
*
* @param Client The client from which this command has been received.
* @param Req Request structure with prefix and all parameters.
* @return CONNECTED or DISCONNECTED.
* See RFC 2812, 3.2.4 "Topic message".
*
* @param Client The client from which this command has been received
* @param Req Request structure with prefix and all parameters
* @returns CONNECTED or DISCONNECTED
*/
GLOBAL bool
IRC_TOPIC( CLIENT *Client, REQUEST *Req )
@@ -484,23 +517,32 @@ IRC_TOPIC( CLIENT *Client, REQUEST *Req )
assert( Client != NULL );
assert( Req != NULL );
IRC_SetPenalty(Client, 1);
if (Req->argc < 1 || Req->argc > 2)
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
_IRC_GET_SENDER_OR_RETURN_(from, Req, Client)
if (Client_Type(Client) == CLIENT_SERVER)
from = Client_Search(Req->prefix);
else
from = Client;
if (!from)
return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG,
Client_ID(Client), Req->prefix);
chan = Channel_Search(Req->argv[0]);
if (!chan)
return IRC_WriteErrClient(from, ERR_NOSUCHCHANNEL_MSG,
return IRC_WriteStrClient(from, ERR_NOSUCHCHANNEL_MSG,
Client_ID(from), Req->argv[0]);
/* Only remote servers and channel members are allowed to change the
* channel topic, and IRC operators when the Conf_OperCanMode option
* channel topic, and IRC opreators when the Conf_OperCanMode option
* is set in the server configuration. */
if (Client_Type(Client) != CLIENT_SERVER) {
topic_power = Client_HasMode(from, 'o');
if (!Channel_IsMemberOf(chan, from)
&& !(Conf_OperCanMode && topic_power))
return IRC_WriteErrClient(from, ERR_NOTONCHANNEL_MSG,
return IRC_WriteStrClient(from, ERR_NOTONCHANNEL_MSG,
Client_ID(from), Req->argv[0]);
} else
topic_power = true;
@@ -529,14 +571,14 @@ IRC_TOPIC( CLIENT *Client, REQUEST *Req )
Channel_Name(chan));
}
if (Channel_HasMode(chan, 't')) {
if (strchr(Channel_Modes(chan), 't')) {
/* Topic Lock. Is the user a channel op or IRC operator? */
if(!topic_power &&
!Channel_UserHasMode(chan, from, 'h') &&
!Channel_UserHasMode(chan, from, 'o') &&
!Channel_UserHasMode(chan, from, 'a') &&
!Channel_UserHasMode(chan, from, 'q'))
return IRC_WriteErrClient(from, ERR_CHANOPRIVSNEEDED_MSG,
!strchr(Channel_UserModes(chan, from), 'h') &&
!strchr(Channel_UserModes(chan, from), 'o') &&
!strchr(Channel_UserModes(chan, from), 'a') &&
!strchr(Channel_UserModes(chan, from), 'q'))
return IRC_WriteStrClient(from, ERR_CHANOPRIVSNEEDED_MSG,
Client_ID(from),
Channel_Name(chan));
}
@@ -564,9 +606,15 @@ IRC_TOPIC( CLIENT *Client, REQUEST *Req )
return CONNECTED;
} /* IRC_TOPIC */
/**
* Handler for the IRC "LIST" command.
*
* See RFC 2812, 3.2.6 "List message".
*
* This implementation handles the local case as well as the forwarding of the
* LIST command to other servers in the IRC network.
*
* @param Client The client from which this command has been received.
* @param Req Request structure with prefix and all parameters.
* @return CONNECTED or DISCONNECTED.
@@ -582,20 +630,31 @@ IRC_LIST( CLIENT *Client, REQUEST *Req )
assert(Client != NULL);
assert(Req != NULL);
IRC_SetPenalty(Client, 2);
_IRC_GET_SENDER_OR_RETURN_(from, Req, Client)
/* Bad number of prameters? */
if (Req->argc > 2)
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
if (Req->argc > 0)
pattern = strtok(Req->argv[0], ",");
else
pattern = "*";
/* Get sender from prefix, if any */
if (Client_Type(Client) == CLIENT_SERVER)
from = Client_Search(Req->prefix);
else
from = Client;
if (!from)
return IRC_WriteStrClient(Client, ERR_NOSUCHSERVER_MSG,
Client_ID(Client), Req->prefix);
if (Req->argc == 2) {
/* Forward to other server? */
target = Client_Search(Req->argv[1]);
if (! target || Client_Type(target) != CLIENT_SERVER)
return IRC_WriteErrClient(from, ERR_NOSUCHSERVER_MSG,
return IRC_WriteStrClient(from, ERR_NOSUCHSERVER_MSG,
Client_ID(Client),
Req->argv[1]);
@@ -617,12 +676,9 @@ IRC_LIST( CLIENT *Client, REQUEST *Req )
/* Check search pattern */
if (MatchCaseInsensitive(pattern, Channel_Name(chan))) {
/* Gotcha! */
if (!Channel_HasMode(chan, 's')
if (!strchr(Channel_Modes(chan), 's')
|| Channel_IsMemberOf(chan, from)
|| (!Conf_MorePrivacy
&& Client_HasMode(Client, 'o')
&& Client_Conn(Client) > NONE))
{
|| (!Conf_MorePrivacy && Client_OperByMe(Client))) {
if ((Conf_MaxListSize > 0)
&& IRC_CheckListTooBig(from, count,
Conf_MaxListSize,
@@ -647,20 +703,25 @@ IRC_LIST( CLIENT *Client, REQUEST *Req )
pattern = NULL;
}
IRC_SetPenalty(from, 2);
return IRC_WriteStrClient(from, RPL_LISTEND_MSG, Client_ID(from));
} /* IRC_LIST */
/**
* Handler for the IRC+ "CHANINFO" command.
* Handler for the IRC+ command "CHANINFO".
*
* @param Client The client from which this command has been received.
* @param Req Request structure with prefix and all parameters.
* @return CONNECTED or DISCONNECTED.
* See doc/Protocol.txt, section II.3:
* "Exchange channel-modes, topics, and persistent channels".
*
* @param Client The client from which this command has been received
* @param Req Request structure with prefix and all parameters
* @returns CONNECTED or DISCONNECTED
*/
GLOBAL bool
IRC_CHANINFO( CLIENT *Client, REQUEST *Req )
{
char modes_add[COMMAND_LEN], l[16];
char modes_add[COMMAND_LEN], l[16], *ptr;
CLIENT *from;
CHANNEL *chan;
int arg_topic;
@@ -669,70 +730,73 @@ IRC_CHANINFO( CLIENT *Client, REQUEST *Req )
assert( Req != NULL );
/* Bad number of parameters? */
if (Req->argc < 2 || Req->argc == 4 || Req->argc > 5) {
IRC_SetPenalty(Client, 2);
return IRC_WriteErrClient(Client, ERR_NEEDMOREPARAMS_MSG,
if (Req->argc < 2 || Req->argc == 4 || Req->argc > 5)
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
}
/* Compatibility kludge */
if (Req->argc == 5)
arg_topic = 4;
else if(Req->argc == 3)
arg_topic = 2;
else
arg_topic = -1;
if( Req->argc == 5 ) arg_topic = 4;
else if( Req->argc == 3 ) arg_topic = 2;
else arg_topic = -1;
_IRC_GET_SENDER_OR_RETURN_(from, Req, Client)
/* Search origin */
from = Client_Search( Req->prefix );
if( ! from ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix );
/* Search or create channel */
chan = Channel_Search( Req->argv[0] );
if (!chan)
chan = Channel_Create( Req->argv[0] );
if (!chan)
return CONNECTED;
if( ! chan ) chan = Channel_Create( Req->argv[0] );
if( ! chan ) return CONNECTED;
if (Req->argv[1][0] == '+') {
if (!*Channel_Modes(chan)) {
/* OK, this channel doesn't have modes yet,
* set the received ones: */
Channel_SetModes(chan, &Req->argv[1][1]);
if( Req->argv[1][0] == '+' )
{
ptr = Channel_Modes( chan );
if( ! *ptr )
{
/* OK, this channel doesn't have modes jet, set the received ones: */
Channel_SetModes( chan, &Req->argv[1][1] );
if(Req->argc == 5) {
if(Channel_HasMode(chan, 'k'))
Channel_SetKey(chan, Req->argv[2]);
if(Channel_HasMode(chan, 'l'))
Channel_SetMaxUsers(chan, atol(Req->argv[3]));
} else {
if( Req->argc == 5 )
{
if( strchr( Channel_Modes( chan ), 'k' )) Channel_SetKey( chan, Req->argv[2] );
if( strchr( Channel_Modes( chan ), 'l' )) Channel_SetMaxUsers( chan, atol( Req->argv[3] ));
}
else
{
/* Delete modes which we never want to inherit */
Channel_ModeDel(chan, 'l');
Channel_ModeDel(chan, 'k');
Channel_ModeDel( chan, 'l' );
Channel_ModeDel( chan, 'k' );
}
strcpy(modes_add, "");
if (Channel_HasMode(chan, 'l')) {
snprintf(l, sizeof(l), " %lu",
Channel_MaxUsers(chan));
strlcat(modes_add, l, sizeof(modes_add));
}
if (Channel_HasMode(chan, 'k')) {
strlcat(modes_add, " ", sizeof(modes_add));
strlcat(modes_add, Channel_Key(chan),
sizeof(modes_add));
strcpy( modes_add, "" );
ptr = Channel_Modes( chan );
while( *ptr )
{
if( *ptr == 'l' )
{
snprintf( l, sizeof( l ), " %lu", Channel_MaxUsers( chan ));
strlcat( modes_add, l, sizeof( modes_add ));
}
if( *ptr == 'k' )
{
strlcat( modes_add, " ", sizeof( modes_add ));
strlcat( modes_add, Channel_Key( chan ), sizeof( modes_add ));
}
ptr++;
}
/* Inform members of this channel */
IRC_WriteStrChannelPrefix(Client, chan, from, false,
"MODE %s +%s%s", Req->argv[0],
Channel_Modes(chan), modes_add);
IRC_WriteStrChannelPrefix( Client, chan, from, false, "MODE %s +%s%s", Req->argv[0], Channel_Modes( chan ), modes_add );
}
}
else
Log(LOG_WARNING, "CHANINFO: invalid MODE format ignored!");
else Log( LOG_WARNING, "CHANINFO: invalid MODE format ignored!" );
if (arg_topic > 0) {
if( arg_topic > 0 )
{
/* We got a topic */
if (!*Channel_Topic(chan) && Req->argv[arg_topic][0]) {
ptr = Channel_Topic( chan );
if(( ! *ptr ) && ( Req->argv[arg_topic][0] ))
{
/* OK, there is no topic jet */
Channel_SetTopic(chan, Client, Req->argv[arg_topic]);
IRC_WriteStrChannelPrefix(Client, chan, from, false,
@@ -740,24 +804,13 @@ IRC_CHANINFO( CLIENT *Client, REQUEST *Req )
}
}
/* Forward CHANINFO to other servers */
if (Req->argc == 5)
IRC_WriteStrServersPrefixFlag(Client, from, 'C',
"CHANINFO %s %s %s %s :%s",
Req->argv[0], Req->argv[1],
Req->argv[2], Req->argv[3],
Req->argv[4]);
else if (Req->argc == 3)
IRC_WriteStrServersPrefixFlag(Client, from, 'C',
"CHANINFO %s %s :%s",
Req->argv[0], Req->argv[1],
Req->argv[2]);
else
IRC_WriteStrServersPrefixFlag(Client, from, 'C',
"CHANINFO %s %s",
Req->argv[0], Req->argv[1]);
/* Forward CHANINFO to other serevrs */
if( Req->argc == 5 ) IRC_WriteStrServersPrefixFlag( Client, from, 'C', "CHANINFO %s %s %s %s :%s", Req->argv[0], Req->argv[1], Req->argv[2], Req->argv[3], Req->argv[4] );
else if( Req->argc == 3 ) IRC_WriteStrServersPrefixFlag( Client, from, 'C', "CHANINFO %s %s :%s", Req->argv[0], Req->argv[1], Req->argv[2] );
else IRC_WriteStrServersPrefixFlag( Client, from, 'C', "CHANINFO %s %s", Req->argv[0], Req->argv[1] );
return CONNECTED;
} /* IRC_CHANINFO */
/* -eof- */

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2013 Alexander Barton (alex@barton.de) and Contributors.
* Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
*
* 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
@@ -48,11 +48,15 @@ IRC_CHARCONV(CLIENT *Client, REQUEST *Req)
assert (Client != NULL);
assert (Req != NULL);
if (Req->argc != 1)
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
strlcpy(encoding, Req->argv[0], sizeof(encoding));
ngt_UpperStr(encoding);
if (!Conn_SetEncoding(Client_Conn(Client), encoding))
return IRC_WriteErrClient(Client, ERR_IP_CHARCONV_MSG,
return IRC_WriteStrClient(Client, ERR_IP_CHARCONV_MSG,
Client_ID(Client), encoding);
return IRC_WriteStrClient(Client, RPL_IP_CHARCONV_MSG,

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2013 Alexander Barton (alex@barton.de) and Contributors.
* Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
*
* 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
@@ -33,21 +33,24 @@
#include "parse.h"
#include "irc.h"
#include "irc-info.h"
#include "irc-macros.h"
#include "irc-write.h"
#include "exp.h"
#include "irc-login.h"
static void Kill_Nick PARAMS((char *Nick, char *Reason));
static void Change_Nick PARAMS((CLIENT * Origin, CLIENT * Target, char *NewNick,
bool InformClient));
/**
* Handler for the IRC "PASS" command.
*
* @param Client The client from which this command has been received.
* @param Req Request structure with prefix and all parameters.
* @return CONNECTED or DISCONNECTED.
* See RFC 2813 section 4.1.1, and RFC 2812 section 3.1.1.
*
* @param Client The client from which this command has been received.
* @param Req Request structure with prefix and all parameters.
* @returns CONNECTED or DISCONNECTED.
*/
GLOBAL bool
IRC_PASS( CLIENT *Client, REQUEST *Req )
@@ -60,7 +63,7 @@ IRC_PASS( CLIENT *Client, REQUEST *Req )
/* Return an error if this is not a local client */
if (Client_Conn(Client) <= NONE)
return IRC_WriteErrClient(Client, ERR_UNKNOWNCOMMAND_MSG,
return IRC_WriteStrClient(Client, ERR_UNKNOWNCOMMAND_MSG,
Client_ID(Client), Req->command);
if (Client_Type(Client) == CLIENT_UNKNOWN && Req->argc == 1) {
@@ -80,12 +83,11 @@ IRC_PASS( CLIENT *Client, REQUEST *Req )
} else if (Client_Type(Client) == CLIENT_UNKNOWN ||
Client_Type(Client) == CLIENT_UNKNOWNSERVER) {
/* Unregistered connection, but wrong number of arguments: */
IRC_SetPenalty(Client, 2);
return IRC_WriteErrClient(Client, ERR_NEEDMOREPARAMS_MSG,
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
} else {
/* Registered connection, PASS command is not allowed! */
return IRC_WriteErrClient(Client, ERR_ALREADYREGISTRED_MSG,
return IRC_WriteStrClient(Client, ERR_ALREADYREGISTRED_MSG,
Client_ID(Client));
}
@@ -144,7 +146,7 @@ IRC_PASS( CLIENT *Client, REQUEST *Req )
} else
flags = "";
Log(LOG_INFO,
"Peer on connection %d announces itself as %s-%s using protocol %d.%d/IRC+ (flags: \"%s\").",
"Peer on conenction %d announces itself as %s-%s using protocol %d.%d/IRC+ (flags: \"%s\").",
Client_Conn(Client), impl, serverver,
protohigh, protolow, flags);
} else {
@@ -165,12 +167,19 @@ IRC_PASS( CLIENT *Client, REQUEST *Req )
return CONNECTED;
} /* IRC_PASS */
/**
* Handler for the IRC "NICK" command.
*
* @param Client The client from which this command has been received.
* @param Req Request structure with prefix and all parameters.
* @return CONNECTED or DISCONNECTED.
* See RFC 2812, 3.1.2 "Nick message", and RFC 2813, 4.1.3 "Nick".
*
* This function implements the IRC command "NICK" which is used to register
* with the server, to change already registered nicknames and to introduce
* new users which are connected to other servers.
*
* @param Client The client from which this command has been received.
* @param Req Request structure with prefix and all parameters.
* @returns CONNECTED or DISCONNECTED.
*/
GLOBAL bool
IRC_NICK( CLIENT *Client, REQUEST *Req )
@@ -195,22 +204,31 @@ IRC_NICK( CLIENT *Client, REQUEST *Req )
|| (Client_Type(Client) == CLIENT_SERVER && Req->argc == 1))
{
/* User registration or change of nickname */
_IRC_ARGC_EQ_OR_RETURN_(Client, Req, 1)
/* Wrong number of arguments? */
if( Req->argc != 1 )
return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID( Client ),
Req->command );
/* Search "target" client */
if (Client_Type(Client) == CLIENT_SERVER) {
target = Client_Search(Req->prefix);
if (!target)
return IRC_WriteErrClient(Client,
ERR_NOSUCHNICK_MSG,
Client_ID(Client),
Req->argv[0]);
} else {
if( Client_Type( Client ) == CLIENT_SERVER )
{
target = Client_Search( Req->prefix );
if( ! target )
return IRC_WriteStrClient( Client,
ERR_NOSUCHNICK_MSG,
Client_ID( Client ),
Req->argv[0] );
}
else
{
/* Is this a restricted client? */
if (Client_HasMode(Client, 'r'))
return IRC_WriteErrClient(Client,
ERR_RESTRICTED_MSG,
Client_ID(Client));
if( Client_HasMode( Client, 'r' ))
return IRC_WriteStrClient( Client,
ERR_RESTRICTED_MSG,
Client_ID( Client ));
target = Client;
}
@@ -219,14 +237,15 @@ IRC_NICK( CLIENT *Client, REQUEST *Req )
* do anything. This is how the original ircd behaves and some
* clients (for example Snak) expect it to be like this.
* But I doubt that this is "really the right thing" ... */
if (strcmp(Client_ID(target), Req->argv[0]) == 0)
if( strcmp( Client_ID( target ), Req->argv[0] ) == 0 )
return CONNECTED;
#endif
/* Check that the new nickname is available. Special case:
* the client only changes from/to upper to lower case. */
if (strcasecmp(Client_ID(target), Req->argv[0]) != 0) {
if (!Client_CheckNick(target, Req->argv[0]))
if( strcasecmp( Client_ID( target ), Req->argv[0] ) != 0 )
{
if( ! Client_CheckNick( target, Req->argv[0] ))
return CONNECTED;
}
@@ -242,11 +261,7 @@ IRC_NICK( CLIENT *Client, REQUEST *Req )
#ifndef STRICT_RFC
if (Conf_AuthPing) {
#ifdef HAVE_ARC4RANDOM
Conn_SetAuthPing(Client_Conn(Client), arc4random());
#else
Conn_SetAuthPing(Client_Conn(Client), rand());
#endif
IRC_WriteStrClient(Client, "PING :%ld",
Conn_GetAuthPing(Client_Conn(Client)));
LogDebug("Connection %d: sent AUTH PING %ld ...",
@@ -274,11 +289,9 @@ IRC_NICK( CLIENT *Client, REQUEST *Req )
/* Server or service introduces new client */
/* Bad number of parameters? */
if (Req->argc != 2 && Req->argc != 7) {
IRC_SetPenalty(Client, 2);
return IRC_WriteErrClient(Client, ERR_NEEDMOREPARAMS_MSG,
if (Req->argc != 2 && Req->argc != 7)
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
}
if (Req->argc >= 7) {
/* RFC 2813 compatible syntax */
@@ -306,33 +319,28 @@ IRC_NICK( CLIENT *Client, REQUEST *Req )
* the new nick is already present on this server:
* the new and the old one have to be disconnected now.
*/
Log(LOG_ERR,
"Server %s introduces already registered nick \"%s\"!",
Client_ID(Client), Req->argv[0]);
return IRC_KillClient(Client, NULL, Req->argv[0],
"Nick collision");
Log( LOG_ERR, "Server %s introduces already registered nick \"%s\"!", Client_ID( Client ), Req->argv[0] );
Kill_Nick( Req->argv[0], "Nick collision" );
return CONNECTED;
}
/* Find the Server this client is connected to */
intr_c = Client_GetFromToken(Client, token);
if (!intr_c) {
Log(LOG_ERR,
"Server %s introduces nick \"%s\" on unknown server!?",
Client_ID(Client), Req->argv[0]);
return IRC_KillClient(Client, NULL, Req->argv[0],
"Unknown server");
if( ! intr_c )
{
Log( LOG_ERR, "Server %s introduces nick \"%s\" on unknown server!?", Client_ID( Client ), Req->argv[0] );
Kill_Nick( Req->argv[0], "Unknown server" );
return CONNECTED;
}
c = Client_NewRemoteUser(intr_c, nick, hops, user, hostname,
token, modes, info, true);
if (!c) {
/* Out of memory, we need to disconnect client to keep
* network state consistent! */
Log(LOG_ALERT,
"Can't create client structure! (on connection %d)",
Client_Conn(Client));
return IRC_KillClient(Client, NULL, Req->argv[0],
"Server error");
if( ! c )
{
/* out of memory, need to disconnect client to keep network state consistent */
Log( LOG_ALERT, "Can't create client structure! (on connection %d)", Client_Conn( Client ));
Kill_Nick( Req->argv[0], "Server error" );
return CONNECTED;
}
/* RFC 2813: client is now fully registered, inform all the
@@ -348,11 +356,10 @@ IRC_NICK( CLIENT *Client, REQUEST *Req )
return CONNECTED;
}
else
return IRC_WriteErrClient(Client, ERR_ALREADYREGISTRED_MSG,
Client_ID(Client));
else return IRC_WriteStrClient( Client, ERR_ALREADYREGISTRED_MSG, Client_ID( Client ));
} /* IRC_NICK */
/**
* Handler for the IRC "SVSNICK" command.
*
@@ -368,6 +375,10 @@ IRC_SVSNICK(CLIENT *Client, REQUEST *Req)
assert(Client != NULL);
assert(Req != NULL);
if (Req->argc != 2)
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
/* Search the originator */
from = Client_Search(Req->prefix);
if (!from)
@@ -376,7 +387,7 @@ IRC_SVSNICK(CLIENT *Client, REQUEST *Req)
/* Search the target */
target = Client_Search(Req->argv[0]);
if (!target || Client_Type(target) != CLIENT_USER) {
return IRC_WriteErrClient(Client, ERR_NOSUCHNICK_MSG,
return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG,
Client_ID(Client), Req->argv[0]);
}
@@ -400,9 +411,11 @@ IRC_SVSNICK(CLIENT *Client, REQUEST *Req)
/**
* Handler for the IRC "USER" command.
*
* @param Client The client from which this command has been received.
* @param Req Request structure with prefix and all parameters.
* @return CONNECTED or DISCONNECTED.
* See RFC 2812, 3.1.3 "User message".
*
* @param Client The client from which this command has been received.
* @param Req Request structure with prefix and all parameters.
* @returns CONNECTED or DISCONNECTED.
*/
GLOBAL bool
IRC_USER(CLIENT * Client, REQUEST * Req)
@@ -420,14 +433,18 @@ IRC_USER(CLIENT * Client, REQUEST * Req)
Client_Type(Client) == CLIENT_GOTPASS)
{
/* New connection */
_IRC_ARGC_EQ_OR_RETURN_(Client, Req, 4)
if (Req->argc != 4)
return IRC_WriteStrClient(Client,
ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client),
Req->command);
/* User name: only alphanumeric characters and limited
punctuation is allowed.*/
ptr = Req->argv[0];
while (*ptr) {
if (!isalnum((int)*ptr) &&
*ptr != '+' && *ptr != '-' && *ptr != '@' &&
*ptr != '+' && *ptr != '-' &&
*ptr != '.' && *ptr != '_') {
Conn_Close(Client_Conn(Client), NULL,
"Invalid user name", true);
@@ -436,13 +453,6 @@ IRC_USER(CLIENT * Client, REQUEST * Req)
ptr++;
}
/* Save the received username for authentication, and use
* it up to the first '@' as default user name (like ircd2.11,
* bahamut, ircd-seven, ...), prefixed with '~', if needed: */
Client_SetOrigUser(Client, Req->argv[0]);
ptr = strchr(Req->argv[0], '@');
if (ptr)
*ptr = '\0';
#ifdef IDENTAUTH
ptr = Client_User(Client);
if (!ptr || !*ptr || *ptr == '~')
@@ -450,6 +460,7 @@ IRC_USER(CLIENT * Client, REQUEST * Req)
#else
Client_SetUser(Client, Req->argv[0], false);
#endif
Client_SetOrigUser(Client, Req->argv[0]);
/* "Real name" or user info text: Don't set it to the empty
* string, the original ircd can't deal with such "real names"
@@ -470,11 +481,14 @@ IRC_USER(CLIENT * Client, REQUEST * Req)
} else if (Client_Type(Client) == CLIENT_SERVER ||
Client_Type(Client) == CLIENT_SERVICE) {
/* Server/service updating an user */
_IRC_ARGC_EQ_OR_RETURN_(Client, Req, 4)
if (Req->argc != 4)
return IRC_WriteStrClient(Client,
ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client),
Req->command);
c = Client_Search(Req->prefix);
if (!c)
return IRC_WriteErrClient(Client, ERR_NOSUCHNICK_MSG,
return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG,
Client_ID(Client),
Req->prefix);
@@ -494,25 +508,29 @@ IRC_USER(CLIENT * Client, REQUEST * Req)
return CONNECTED;
} else if (Client_Type(Client) == CLIENT_USER) {
/* Already registered connection */
return IRC_WriteErrClient(Client, ERR_ALREADYREGISTRED_MSG,
return IRC_WriteStrClient(Client, ERR_ALREADYREGISTRED_MSG,
Client_ID(Client));
} else {
/* Unexpected/invalid connection state? */
return IRC_WriteErrClient(Client, ERR_NOTREGISTERED_MSG,
return IRC_WriteStrClient(Client, ERR_NOTREGISTERED_MSG,
Client_ID(Client));
}
} /* IRC_USER */
/**
* Handler for the IRC "SERVICE" command.
*
* This function implements IRC Services registration using the SERVICE command
* defined in RFC 2812 3.1.6 and RFC 2813 4.1.4.
*
* At the moment ngIRCd doesn't support directly linked services, so this
* function returns ERR_ERRONEUSNICKNAME when the SERVICE command has not been
* received from a peer server.
*
* @param Client The client from which this command has been received.
* @param Req Request structure with prefix and all parameters.
* @return CONNECTED or DISCONNECTED.
* @param Client The client from which this command has been received.
* @param Req Request structure with prefix and all parameters.
* @returns CONNECTED or DISCONNECTED..
*/
GLOBAL bool
IRC_SERVICE(CLIENT *Client, REQUEST *Req)
@@ -526,13 +544,22 @@ IRC_SERVICE(CLIENT *Client, REQUEST *Req)
if (Client_Type(Client) != CLIENT_GOTPASS &&
Client_Type(Client) != CLIENT_SERVER)
return IRC_WriteErrClient(Client, ERR_ALREADYREGISTRED_MSG,
return IRC_WriteStrClient(Client, ERR_ALREADYREGISTRED_MSG,
Client_ID(Client));
if (Req->argc != 6)
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
if (Client_Type(Client) != CLIENT_SERVER)
return IRC_WriteErrClient(Client, ERR_ERRONEUSNICKNAME_MSG,
return IRC_WriteStrClient(Client, ERR_ERRONEUSNICKNAME_MSG,
Client_ID(Client), Req->argv[0]);
/* Bad number of parameters? */
if (Req->argc != 6)
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
nick = Req->argv[0];
user = NULL; host = NULL;
token = atoi(Req->argv[1]);
@@ -542,20 +569,20 @@ IRC_SERVICE(CLIENT *Client, REQUEST *Req)
/* Validate service name ("nickname") */
c = Client_Search(nick);
if(c) {
/* Nickname collision: disconnect (KILL) both clients! */
Log(LOG_ERR,
"Server %s introduces already registered service \"%s\"!",
/* Nickname collission: disconnect (KILL) both clients! */
Log(LOG_ERR, "Server %s introduces already registered service \"%s\"!",
Client_ID(Client), nick);
return IRC_KillClient(Client, NULL, nick, "Nick collision");
Kill_Nick(nick, "Nick collision");
return CONNECTED;
}
/* Get the server to which the service is connected */
intr_c = Client_GetFromToken(Client, token);
if (! intr_c) {
Log(LOG_ERR,
"Server %s introduces service \"%s\" on unknown server!?",
Log(LOG_ERR, "Server %s introduces service \"%s\" on unknown server!?",
Client_ID(Client), nick);
return IRC_KillClient(Client, NULL, nick, "Unknown server");
Kill_Nick(nick, "Unknown server");
return CONNECTED;
}
/* Get user and host name */
@@ -584,28 +611,37 @@ IRC_SERVICE(CLIENT *Client, REQUEST *Req)
if (! c) {
/* Couldn't create client structure, so KILL the service to
* keep network status consistent ... */
Log(LOG_ALERT,
"Can't create client structure! (on connection %d)",
Log(LOG_ALERT, "Can't create client structure! (on connection %d)",
Client_Conn(Client));
return IRC_KillClient(Client, NULL, nick, "Server error");
Kill_Nick(nick, "Server error");
return CONNECTED;
}
Client_Introduce(Client, c, CLIENT_SERVICE);
return CONNECTED;
} /* IRC_SERVICE */
/**
* Handler for the IRC "WEBIRC" command.
*
* @param Client The client from which this command has been received.
* @param Req Request structure with prefix and all parameters.
* @return CONNECTED or DISCONNECTED.
* See doc/Protocol.txt, section II.4:
* "Update webchat/proxy client information".
*
* @param Client The client from which this command has been received.
* @param Req Request structure with prefix and all parameters.
* @returns CONNECTED or DISCONNECTED.
*/
GLOBAL bool
IRC_WEBIRC(CLIENT *Client, REQUEST *Req)
{
/* Exactly 4 parameters are requited */
if (Req->argc != 4)
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
if (!Conf_WebircPwd[0] || strcmp(Req->argv[0], Conf_WebircPwd) != 0)
return IRC_WriteErrClient(Client, ERR_PASSWDMISMATCH_MSG,
return IRC_WriteStrClient(Client, ERR_PASSWDMISMATCH_MSG,
Client_ID(Client));
LogDebug("Connection %d: got valid WEBIRC command: user=%s, host=%s, ip=%s",
@@ -613,31 +649,34 @@ IRC_WEBIRC(CLIENT *Client, REQUEST *Req)
Client_SetUser(Client, Req->argv[1], true);
Client_SetOrigUser(Client, Req->argv[1]);
if (Conf_DNS)
Client_SetHostname(Client, Req->argv[2]);
else
Client_SetHostname(Client, Req->argv[3]);
Client_SetIPAText(Client, Req->argv[3]);
Client_SetHostname(Client, Req->argv[2]);
return CONNECTED;
} /* IRC_WEBIRC */
/**
* Handler for the IRC "QUIT" command.
*
* @param Client The client from which this command has been received.
* @param Req Request structure with prefix and all parameters.
* @return CONNECTED or DISCONNECTED.
* See RFC 2812, 3.1.7 "Quit", and RFC 2813, 4.1.5 "Quit".
*
* @param Client The client from which this command has been received.
* @param Req Request structure with prefix and all parameters.
* @returns CONNECTED or DISCONNECTED.
*/
GLOBAL bool
IRC_QUIT( CLIENT *Client, REQUEST *Req )
{
CLIENT *target;
char quitmsg[COMMAND_LEN];
char quitmsg[LINE_LEN];
assert(Client != NULL);
assert(Req != NULL);
/* Wrong number of arguments? */
if (Req->argc > 1)
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
if (Req->argc == 1)
strlcpy(quitmsg, Req->argv[0], sizeof quitmsg);
@@ -652,11 +691,11 @@ IRC_QUIT( CLIENT *Client, REQUEST *Req )
}
if (target != Client) {
Client_Destroy(target, "Got QUIT command",
Client_Destroy(target, "Got QUIT command.",
Req->argc == 1 ? quitmsg : NULL, true);
return CONNECTED;
} else {
Conn_Close(Client_Conn(Client), "Got QUIT command",
Conn_Close(Client_Conn(Client), "Got QUIT command.",
Req->argc == 1 ? quitmsg : NULL, true);
return DISCONNECTED;
}
@@ -669,13 +708,14 @@ IRC_QUIT( CLIENT *Client, REQUEST *Req )
}
/* User, Service, or not yet registered */
Conn_Close(Client_Conn(Client), "Got QUIT command",
Conn_Close(Client_Conn(Client), "Got QUIT command.",
Req->argc == 1 ? quitmsg : NULL, true);
return DISCONNECTED;
}
} /* IRC_QUIT */
#ifndef STRICT_RFC
/**
@@ -684,9 +724,9 @@ IRC_QUIT( CLIENT *Client, REQUEST *Req )
* We handle these commands here to avoid the quite long timeout when
* some user tries to access this IRC daemon using an web browser ...
*
* @param Client The client from which this command has been received.
* @param Req Request structure with prefix and all parameters.
* @return CONNECTED or DISCONNECTED.
* @param Client The client from which this command has been received.
* @param Req Request structure with prefix and all parameters.
* @returns CONNECTED or DISCONNECTED.
*/
GLOBAL bool
IRC_QUIT_HTTP( CLIENT *Client, REQUEST *Req )
@@ -698,12 +738,15 @@ IRC_QUIT_HTTP( CLIENT *Client, REQUEST *Req )
#endif
/**
* Handler for the IRC "PING" command.
*
* @param Client The client from which this command has been received.
* @param Req Request structure with prefix and all parameters.
* @return CONNECTED or DISCONNECTED.
* See RFC 2812, 3.7.2 "Ping message".
*
* @param Client The client from which this command has been received.
* @param Req Request structure with prefix and all parameters.
* @returns CONNECTED or DISCONNECTED.
*/
GLOBAL bool
IRC_PING(CLIENT *Client, REQUEST *Req)
@@ -714,11 +757,13 @@ IRC_PING(CLIENT *Client, REQUEST *Req)
assert(Req != NULL);
if (Req->argc < 1)
return IRC_WriteErrClient(Client, ERR_NOORIGIN_MSG,
return IRC_WriteStrClient(Client, ERR_NOORIGIN_MSG,
Client_ID(Client));
#ifdef STRICT_RFC
/* Don't ignore additional arguments when in "strict" mode */
_IRC_ARGC_LE_OR_RETURN_(Client, Req, 2)
if (Req->argc > 2)
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
#endif
if (Req->argc > 1) {
@@ -726,7 +771,7 @@ IRC_PING(CLIENT *Client, REQUEST *Req)
target = Client_Search(Req->argv[1]);
if (!target || Client_Type(target) != CLIENT_SERVER)
return IRC_WriteErrClient(Client, ERR_NOSUCHSERVER_MSG,
return IRC_WriteStrClient(Client, ERR_NOSUCHSERVER_MSG,
Client_ID(Client), Req->argv[1]);
if (target != Client_ThisServer()) {
@@ -736,7 +781,7 @@ IRC_PING(CLIENT *Client, REQUEST *Req)
else
from = Client;
if (!from)
return IRC_WriteErrClient(Client,
return IRC_WriteStrClient(Client,
ERR_NOSUCHSERVER_MSG,
Client_ID(Client), Req->prefix);
@@ -754,7 +799,7 @@ IRC_PING(CLIENT *Client, REQUEST *Req)
} else
from = Client_ThisServer();
if (!from)
return IRC_WriteErrClient(Client, ERR_NOSUCHSERVER_MSG,
return IRC_WriteStrClient(Client, ERR_NOSUCHSERVER_MSG,
Client_ID(Client), Req->prefix);
Log(LOG_DEBUG, "Connection %d: got PING, sending PONG ...",
@@ -771,12 +816,15 @@ IRC_PING(CLIENT *Client, REQUEST *Req)
#endif
} /* IRC_PING */
/**
* Handler for the IRC "PONG" command.
*
* @param Client The client from which this command has been received.
* @param Req Request structure with prefix and all parameters.
* @return CONNECTED or DISCONNECTED.
* See RFC 2812, 3.7.3 "Pong message".
*
* @param Client The client from which this command has been received.
* @param Req Request structure with prefix and all parameters.
* @returns CONNECTED or DISCONNECTED.
*/
GLOBAL bool
IRC_PONG(CLIENT *Client, REQUEST *Req)
@@ -794,20 +842,26 @@ IRC_PONG(CLIENT *Client, REQUEST *Req)
/* Wrong number of arguments? */
if (Req->argc < 1) {
if (Client_Type(Client) == CLIENT_USER)
return IRC_WriteErrClient(Client, ERR_NOORIGIN_MSG,
return IRC_WriteStrClient(Client, ERR_NOORIGIN_MSG,
Client_ID(Client));
else
return CONNECTED;
}
if (Client_Type(Client) == CLIENT_USER) {
_IRC_ARGC_LE_OR_RETURN_(Client, Req, 2)
if (Req->argc > 2) {
if (Client_Type(Client) == CLIENT_USER)
return IRC_WriteStrClient(Client,
ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client),
Req->command);
else
return CONNECTED;
}
/* Forward? */
if (Req->argc == 2 && Client_Type(Client) == CLIENT_SERVER) {
target = Client_Search(Req->argv[0]);
if (!target)
return IRC_WriteErrClient(Client, ERR_NOSUCHSERVER_MSG,
return IRC_WriteStrClient(Client, ERR_NOSUCHSERVER_MSG,
Client_ID(Client), Req->argv[0]);
from = Client_Search(Req->prefix);
@@ -815,7 +869,7 @@ IRC_PONG(CLIENT *Client, REQUEST *Req)
if (target != Client_ThisServer() && target != from) {
/* Ok, we have to forward the message. */
if (!from)
return IRC_WriteErrClient(Client,
return IRC_WriteStrClient(Client,
ERR_NOSUCHSERVER_MSG,
Client_ID(Client), Req->prefix);
@@ -853,9 +907,8 @@ IRC_PONG(CLIENT *Client, REQUEST *Req)
if (Client_Type(Client) == CLIENT_SERVER && Conn_LastPing(conn) == 0) {
Log(LOG_INFO,
"Synchronization with \"%s\" done (connection %d): %ld second%s [%ld users, %ld channels].",
"Synchronization with \"%s\" done (connection %d): %ld seconds [%ld users, %ld channels]",
Client_ID(Client), conn, time(NULL) - Conn_GetSignon(conn),
time(NULL) - Conn_GetSignon(conn) == 1 ? "" : "s",
Client_UserCount(), Channel_CountVisible(NULL));
Conn_UpdatePing(conn);
} else
@@ -865,6 +918,33 @@ IRC_PONG(CLIENT *Client, REQUEST *Req)
return CONNECTED;
} /* IRC_PONG */
/**
* Kill all users with a specific nickname in the network.
*
* @param Nick Nickname.
* @param Reason Reason for the KILL.
*/
static void
Kill_Nick(char *Nick, char *Reason)
{
REQUEST r;
assert (Nick != NULL);
assert (Reason != NULL);
r.prefix = NULL;
r.argv[0] = Nick;
r.argv[1] = Reason;
r.argc = 2;
Log(LOG_ERR, "User(s) with nick \"%s\" will be disconnected: %s",
Nick, Reason);
IRC_KILL(Client_ThisServer(), &r);
} /* Kill_Nick */
/**
* Change the nickname of a client.
*
@@ -904,4 +984,5 @@ Change_Nick(CLIENT *Origin, CLIENT *Target, char *NewNick, bool InformClient)
Client_SetID(Target, NewNick);
}
/* -eof- */

View File

@@ -1,113 +0,0 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2013 Alexander Barton (alex@barton.de) and Contributors.
*
* 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.
* Please read the file COPYING, README and AUTHORS for more information.
*/
#ifndef __irc_macros_h__
#define __irc_macros_h__
/**
* @file
* Macros for functions that handle IRC commands.
*/
/**
* Make sure that number of passed parameters is equal to Count.
*
* If there are not exactly Count parameters, send an error to the client and
* return from the function.
*/
#define _IRC_ARGC_EQ_OR_RETURN_(Client, Req, Count) \
if (Req->argc != Count) { \
IRC_SetPenalty(Client, 2); \
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, \
Client_ID(Client), Req->command); \
}
/**
* Make sure that number of passed parameters is less or equal than Max.
*
* If there are more than Max parameters, send an error to the client and
* return from the function.
*/
#define _IRC_ARGC_LE_OR_RETURN_(Client, Req, Max) \
if (Req->argc > Max) { \
IRC_SetPenalty(Client, 2); \
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, \
Client_ID(Client), Req->command); \
}
/**
* Make sure that number of passed parameters is greater or equal than Min.
*
* If there aren't at least Min parameters, send an error to the client and
* return from the function.
*/
#define _IRC_ARGC_GE_OR_RETURN_(Client, Req, Min) \
if (Req->argc < Min) { \
IRC_SetPenalty(Client, 2); \
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, \
Client_ID(Client), Req->command); \
}
/**
* Make sure that number of passed parameters is in between Min and Max.
*
* If there aren't at least Min parameters or if there are more than Max
* parameters, send an error to the client and return from the function.
*/
#define _IRC_ARGC_BETWEEN_OR_RETURN_(Client, Req, Min, Max) \
if (Req->argc < Min || Req->argc > Max) { \
IRC_SetPenalty(Client, 2); \
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, \
Client_ID(Client), Req->command); \
}
/**
* Get sender of an IRC command.
*
* The sender is either stored in the prefix if the command has been
* received from a server or set to the client. If the sender is invalid,
* send an error to the client and return from the function.
*/
#define _IRC_GET_SENDER_OR_RETURN_(Sender, Req, Client) \
if (Client_Type(Client) == CLIENT_SERVER) \
Sender = Client_Search(Req->prefix); \
else \
Sender = Client; \
if (!Sender) \
return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG, \
Client_ID(Client), Req->prefix);
/**
* Get target of an IRC command and make sure that it is a server.
*
* Set the target to the local server if no target parameter is given in the
* received command, and send an error to the client and return from the
* function if the given target isn't resolvable to a server: the target
* parameter can be a server name, a nick name (then the target is set to
* the server to which this nick is connected), or a mask matching at least
* one server name in the network.
*/
#define _IRC_GET_TARGET_SERVER_OR_RETURN_(Target, Req, Argc, From) \
if (Req->argc > Argc) { \
Target = Client_Search(Req->argv[Argc]); \
if (!Target) \
Target = Client_SearchServer(Req->argv[Argc]); \
if (!Target) \
return IRC_WriteStrClient(From, ERR_NOSUCHSERVER_MSG, \
Client_ID(From), Req->argv[Argc]); \
if (Client_Type(Target) != CLIENT_SERVER) \
Target = Client_Introducer(Target); \
} else \
Target = Client_ThisServer();
#endif /* __irc_macros_h__ */
/* -eof- */

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2013 Alexander Barton (alex@barton.de) and Contributors.
* Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
*
* 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
@@ -51,22 +51,26 @@ IRC_METADATA(CLIENT *Client, REQUEST *Req)
assert(Client != NULL);
assert(Req != NULL);
if (Req->argc != 3)
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
prefix = Client_Search(Req->prefix);
if (!prefix)
return IRC_WriteErrClient(Client, ERR_NOSUCHNICK_MSG,
return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG,
Client_ID(Client), Req->prefix);
target = Client_Search(Req->argv[0]);
if (!target)
return IRC_WriteErrClient(Client, ERR_NOSUCHNICK_MSG,
return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG,
Client_ID(Client), Req->argv[0]);
LogDebug("Got \"METADATA\" command from \"%s\" for client \"%s\": \"%s=%s\".",
Client_ID(prefix), Client_ID(target),
Req->argv[1], Req->argv[2]);
/* Mark client: it has received a METADATA command */
if (!Client_HasFlag(target, 'M')) {
/* Mark client: it has receiveda a METADATA command */
if (!strchr(Client_Flags(target), 'M')) {
snprintf(new_flags, sizeof new_flags, "%sM",
Client_Flags(target));
Client_SetFlags(target, new_flags);
@@ -92,10 +96,6 @@ IRC_METADATA(CLIENT *Client, REQUEST *Req)
Client_SetInfo(target, Req->argv[2]);
else if (*Req->argv[2] && strcasecmp(Req->argv[1], "user") == 0)
Client_SetUser(target, Req->argv[2], true);
else if (strcasecmp(Req->argv[1], "accountname") == 0)
Client_SetAccountName(target, Req->argv[2]);
else if (*Req->argv[2] && strcasecmp(Req->argv[1], "certfp") == 0)
Conn_SetCertFp(Client_Conn(target), Req->argv[2]);
else
Log(LOG_WARNING,
"Ignored metadata update from \"%s\" for client \"%s\": \"%s=%s\" - unknown key!",

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2013 Alexander Barton (alex@barton.de) and Contributors.
* Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
*
* 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
@@ -25,7 +25,6 @@
#include "defines.h"
#include "conn.h"
#include "channel.h"
#include "irc-macros.h"
#include "irc-write.h"
#include "lists.h"
#include "log.h"
@@ -36,6 +35,7 @@
#include "exp.h"
#include "irc-mode.h"
static bool Client_Mode PARAMS((CLIENT *Client, REQUEST *Req, CLIENT *Origin,
CLIENT *Target));
static bool Channel_Mode PARAMS((CLIENT *Client, REQUEST *Req, CLIENT *Origin,
@@ -50,15 +50,16 @@ static bool Send_ListChange PARAMS((const bool IsAdd, const char ModeChar,
CLIENT *Prefix, CLIENT *Client,
CHANNEL *Channel, const char *Mask));
/**
* Handler for the IRC "MODE" command.
*
* This function detects whether user or channel modes should be modified
* and calls the appropriate sub-functions.
* See RFC 2812 section 3.1.5 ("user mode message") and section 3.2.3
* ("channel mode message"), and RFC 2811 section 4 ("channel modes").
*
* @param Client The client from which this command has been received.
* @param Req Request structure with prefix and all parameters.
* @return CONNECTED or DISCONNECTED.
* @param Client The client from which this command has been received.
* @param Req Request structure with prefix and all parameters.
* @returns CONNECTED or DISCONNECTED.
*/
GLOBAL bool
IRC_MODE( CLIENT *Client, REQUEST *Req )
@@ -69,7 +70,20 @@ IRC_MODE( CLIENT *Client, REQUEST *Req )
assert(Client != NULL);
assert(Req != NULL);
_IRC_GET_SENDER_OR_RETURN_(origin, Req, Client)
/* No parameters? */
if (Req->argc < 1)
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
/* Origin for answers */
if (Client_Type(Client) == CLIENT_SERVER) {
origin = Client_Search(Req->prefix);
if (!origin)
return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG,
Client_ID(Client),
Req->prefix);
} else
origin = Client;
/* Channel or user mode? */
cl = NULL; chan = NULL;
@@ -84,10 +98,11 @@ IRC_MODE( CLIENT *Client, REQUEST *Req )
return Channel_Mode(Client, Req, origin, chan);
/* No target found! */
return IRC_WriteErrClient(Client, ERR_NOSUCHNICK_MSG,
return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG,
Client_ID(Client), Req->argv[0]);
} /* IRC_MODE */
/**
* Check if the "mode limit" for a client has been reached.
*
@@ -108,14 +123,15 @@ Mode_Limit_Reached(CLIENT *Client, int Count)
return true;
}
/**
* Handle client mode requests
*
* @param Client The client from which this command has been received.
* @param Req Request structure with prefix and all parameters.
* @param Origin The originator of the MODE command (prefix).
* @param Target The target (client) of this MODE command.
* @return CONNECTED or DISCONNECTED.
* @param Client The client from which this command has been received.
* @param Req Request structure with prefix and all parameters.
* @param Origin The originator of the MODE command (prefix).
* @param Target The target (client) of this MODE command.
* @returns CONNECTED or DISCONNECTED.
*/
static bool
Client_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *Target )
@@ -130,7 +146,7 @@ Client_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *Target )
if (Client_Type(Client) == CLIENT_USER) {
/* Users are only allowed to manipulate their own modes! */
if (Target != Client)
return IRC_WriteErrClient(Client,
return IRC_WriteStrClient(Client,
ERR_USERSDONTMATCH_MSG,
Client_ID(Client));
}
@@ -152,7 +168,7 @@ Client_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *Target )
set = false;
strcpy(the_modes, "-");
} else
return IRC_WriteErrClient(Origin, ERR_UMODEUNKNOWNFLAG_MSG,
return IRC_WriteStrClient(Origin, ERR_UMODEUNKNOWNFLAG_MSG,
Client_ID(Origin));
x[1] = '\0';
@@ -211,34 +227,43 @@ Client_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *Target )
x[0] = 'a';
Client_SetAway(Origin, DEFAULT_AWAY_MSG);
} else
ok = IRC_WriteErrClient(Origin,
ok = IRC_WriteStrClient(Origin,
ERR_NOPRIVILEGES_MSG,
Client_ID(Origin));
break;
case 'B': /* Bot */
if (Client_HasMode(Client, 'r'))
ok = IRC_WriteErrClient(Origin,
ok = IRC_WriteStrClient(Origin,
ERR_RESTRICTED_MSG,
Client_ID(Origin));
else
x[0] = 'B';
break;
case 'c': /* Receive connect notices */
case 'q': /* KICK-protected user */
/* (only settable by IRC operators!) */
case 'c': /* Receive connect notices
* (only settable by IRC operators!) */
if (!set || Client_Type(Client) == CLIENT_SERVER
|| Client_HasMode(Origin, 'o'))
x[0] = *mode_ptr;
|| Client_OperByMe(Origin))
x[0] = 'c';
else
ok = IRC_WriteErrClient(Origin,
ok = IRC_WriteStrClient(Origin,
ERR_NOPRIVILEGES_MSG,
Client_ID(Origin));
break;
case 'o': /* IRC operator (only unsettable!) */
if (!set || Client_Type(Client) == CLIENT_SERVER) {
Client_SetOperByMe(Target, false);
x[0] = 'o';
} else
ok = IRC_WriteErrClient(Origin,
ok = IRC_WriteStrClient(Origin,
ERR_NOPRIVILEGES_MSG,
Client_ID(Origin));
break;
case 'q': /* KICK-protected user */
if (!set || Client_Type(Client) == CLIENT_SERVER
|| Client_OperByMe(Origin))
x[0] = 'q';
else
ok = IRC_WriteStrClient(Origin,
ERR_NOPRIVILEGES_MSG,
Client_ID(Origin));
break;
@@ -246,7 +271,7 @@ Client_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *Target )
if (set || Client_Type(Client) == CLIENT_SERVER)
x[0] = 'r';
else
ok = IRC_WriteErrClient(Origin,
ok = IRC_WriteStrClient(Origin,
ERR_RESTRICTED_MSG,
Client_ID(Origin));
break;
@@ -254,22 +279,22 @@ Client_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *Target )
if (Client_Type(Client) == CLIENT_SERVER)
x[0] = 'R';
else
ok = IRC_WriteErrClient(Origin,
ok = IRC_WriteStrClient(Origin,
ERR_NICKREGISTER_MSG,
Client_ID(Origin));
break;
case 'x': /* Cloak hostname */
if (Client_HasMode(Client, 'r'))
ok = IRC_WriteErrClient(Origin,
ok = IRC_WriteStrClient(Origin,
ERR_RESTRICTED_MSG,
Client_ID(Origin));
else if (!set || Conf_CloakHostModeX[0]
|| Client_Type(Client) == CLIENT_SERVER
|| Client_HasMode(Origin, 'o')) {
|| Client_OperByMe(Client)) {
x[0] = 'x';
send_RPL_HOSTHIDDEN_MSG = true;
} else
ok = IRC_WriteErrClient(Origin,
ok = IRC_WriteStrClient(Origin,
ERR_NOPRIVILEGES_MSG,
Client_ID(Origin));
break;
@@ -279,7 +304,7 @@ Client_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *Target )
"Unknown mode \"%c%c\" from \"%s\"!?",
set ? '+' : '-', *mode_ptr,
Client_ID(Origin));
ok = IRC_WriteErrClient(Origin,
ok = IRC_WriteStrClient(Origin,
ERR_UMODEUNKNOWNFLAG2_MSG,
Client_ID(Origin),
set ? '+' : '-',
@@ -344,7 +369,7 @@ Client_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *Target )
}
if (send_RPL_HOSTHIDDEN_MSG && Client_Conn(Target) > NONE) {
/* A new (cloaked) hostname must be announced */
/* A new (cloaked) hostname must be annoucned */
IRC_WriteStrClientPrefix(Target, Origin,
RPL_HOSTHIDDEN_MSG,
Client_ID(Target),
@@ -361,13 +386,7 @@ Client_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *Target )
return ok;
} /* Client_Mode */
/*
* Reply to a channel mode request.
*
* @param Origin The originator of the MODE command (prefix).
* @param Channel The channel of which the modes should be sent.
* @return CONNECTED or DISCONNECTED.
*/
static bool
Channel_Mode_Answer_Request(CLIENT *Origin, CHANNEL *Channel)
{
@@ -413,20 +432,15 @@ Channel_Mode_Answer_Request(CLIENT *Origin, CHANNEL *Channel)
return CONNECTED;
}
/**
* Handle channel mode and channel-user mode changes
*
* @param Client The client from which this command has been received.
* @param Req Request structure with prefix and all parameters.
* @param Origin The originator of the MODE command (prefix).
* @param Channel The target channel of this MODE command.
* @return CONNECTED or DISCONNECTED.
*/
static bool
Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
{
char the_modes[COMMAND_LEN], the_args[COMMAND_LEN], x[2],
argadd[CLIENT_PASS_LEN], *mode_ptr;
argadd[CLIENT_PASS_LEN], *mode_ptr, *o_mode_ptr;
bool connected, set, skiponce, retval, use_servermode,
is_halfop, is_op, is_admin, is_owner, is_machine, is_oper;
int mode_arg, arg_arg, mode_arg_count = 0;
@@ -437,7 +451,7 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
is_halfop = is_op = is_admin = is_owner = is_machine = is_oper = false;
if (Channel_IsModeless(Channel))
return IRC_WriteErrClient(Client, ERR_NOCHANMODES_MSG,
return IRC_WriteStrClient(Client, ERR_NOCHANMODES_MSG,
Client_ID(Client), Channel_Name(Channel));
/* Mode request: let's answer it :-) */
@@ -446,7 +460,7 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
/* Check if origin is oper and opers can use mode */
use_servermode = Conf_OperServerMode;
if(Client_HasMode(Client, 'o') && Conf_OperCanMode) {
if(Client_OperByMe(Client) && Conf_OperCanMode) {
is_oper = true;
}
@@ -458,7 +472,7 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
/* Check if client is member of channel or an oper or an server/service */
if(!Channel_IsMemberOf(Channel, Client) && !is_oper && !is_machine)
return IRC_WriteErrClient(Origin, ERR_NOTONCHANNEL_MSG,
return IRC_WriteStrClient(Origin, ERR_NOTONCHANNEL_MSG,
Client_ID(Origin),
Channel_Name(Channel));
@@ -537,14 +551,18 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
arg_arg = -1;
if(!is_machine && !is_oper) {
if (Channel_UserHasMode(Channel, Client, 'q'))
is_owner = true;
if (Channel_UserHasMode(Channel, Client, 'a'))
is_admin = true;
if (Channel_UserHasMode(Channel, Client, 'o'))
is_op = true;
if (Channel_UserHasMode(Channel, Client, 'h'))
is_halfop = true;
o_mode_ptr = Channel_UserModes(Channel, Client);
while( *o_mode_ptr ) {
if ( *o_mode_ptr == 'q')
is_owner = true;
if ( *o_mode_ptr == 'a')
is_admin = true;
if ( *o_mode_ptr == 'o')
is_op = true;
if ( *o_mode_ptr == 'h')
is_halfop = true;
o_mode_ptr++;
}
}
/* Validate modes */
@@ -558,7 +576,7 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
case 'z': /* Secure connections only */
if(!is_oper && !is_machine && !is_owner &&
!is_admin && !is_op) {
connected = IRC_WriteErrClient(Origin,
connected = IRC_WriteStrClient(Origin,
ERR_CHANOPRIVSNEEDED_MSG,
Client_ID(Origin), Channel_Name(Channel));
goto chan_exit;
@@ -574,7 +592,7 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
is_admin || is_op || is_halfop)
x[0] = *mode_ptr;
else
connected = IRC_WriteErrClient(Origin,
connected = IRC_WriteStrClient(Origin,
ERR_CHANOPRIVSNEEDED_MSG,
Client_ID(Origin), Channel_Name(Channel));
break;
@@ -586,7 +604,7 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
is_admin || is_op || is_halfop)
x[0] = *mode_ptr;
else
connected = IRC_WriteErrClient(Origin,
connected = IRC_WriteStrClient(Origin,
ERR_CHANOPRIVSNEEDED_MSG,
Client_ID(Origin),
Channel_Name(Channel));
@@ -602,7 +620,7 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
sizeof(argadd));
x[0] = *mode_ptr;
} else {
connected = IRC_WriteErrClient(Origin,
connected = IRC_WriteStrClient(Origin,
ERR_CHANOPRIVSNEEDED_MSG,
Client_ID(Origin),
Channel_Name(Channel));
@@ -613,8 +631,7 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
#ifdef STRICT_RFC
/* Only send error message in "strict" mode,
* this is how ircd2.11 and others behave ... */
IRC_SetPenalty(Origin, 2);
connected = IRC_WriteErrClient(Origin,
connected = IRC_WriteStrClient(Origin,
ERR_NEEDMOREPARAMS_MSG,
Client_ID(Origin), Req->command);
#endif
@@ -629,7 +646,7 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
is_admin || is_op || is_halfop)
x[0] = *mode_ptr;
else
connected = IRC_WriteErrClient(Origin,
connected = IRC_WriteStrClient(Origin,
ERR_CHANOPRIVSNEEDED_MSG,
Client_ID(Origin),
Channel_Name(Channel));
@@ -647,7 +664,7 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
x[0] = *mode_ptr;
}
} else {
connected = IRC_WriteErrClient(Origin,
connected = IRC_WriteStrClient(Origin,
ERR_CHANOPRIVSNEEDED_MSG,
Client_ID(Origin),
Channel_Name(Channel));
@@ -658,8 +675,7 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
#ifdef STRICT_RFC
/* Only send error message in "strict" mode,
* this is how ircd2.11 and others behave ... */
IRC_SetPenalty(Origin, 2);
connected = IRC_WriteErrClient(Origin,
connected = IRC_WriteStrClient(Origin,
ERR_NEEDMOREPARAMS_MSG,
Client_ID(Origin), Req->command);
#endif
@@ -673,14 +689,14 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
if(is_oper || is_machine)
x[0] = 'O';
else
connected = IRC_WriteErrClient(Origin,
connected = IRC_WriteStrClient(Origin,
ERR_NOPRIVILEGES_MSG,
Client_ID(Origin));
} else if(is_oper || is_machine || is_owner ||
is_admin || is_op)
x[0] = 'O';
else
connected = IRC_WriteErrClient(Origin,
connected = IRC_WriteStrClient(Origin,
ERR_CHANOPRIVSNEEDED_MSG,
Client_ID(Origin),
Channel_Name(Channel));
@@ -692,14 +708,14 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
if(is_oper || is_machine)
x[0] = 'P';
else
connected = IRC_WriteErrClient(Origin,
connected = IRC_WriteStrClient(Origin,
ERR_NOPRIVILEGES_MSG,
Client_ID(Origin));
} else if(is_oper || is_machine || is_owner ||
is_admin || is_op)
x[0] = 'P';
else
connected = IRC_WriteErrClient(Origin,
connected = IRC_WriteStrClient(Origin,
ERR_CHANOPRIVSNEEDED_MSG,
Client_ID(Origin),
Channel_Name(Channel));
@@ -708,7 +724,7 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
case 'q': /* Owner */
case 'a': /* Channel admin */
if(!is_oper && !is_machine && !is_owner && !is_admin) {
connected = IRC_WriteErrClient(Origin,
connected = IRC_WriteStrClient(Origin,
ERR_CHANOPPRIVTOOLOW_MSG,
Client_ID(Origin),
Channel_Name(Channel));
@@ -717,7 +733,7 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
case 'o': /* Channel operator */
if(!is_oper && !is_machine && !is_owner &&
!is_admin && !is_op) {
connected = IRC_WriteErrClient(Origin,
connected = IRC_WriteStrClient(Origin,
ERR_CHANOPRIVSNEEDED_MSG,
Client_ID(Origin),
Channel_Name(Channel));
@@ -726,7 +742,7 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
case 'h': /* Half Op */
if(!is_oper && !is_machine && !is_owner &&
!is_admin && !is_op) {
connected = IRC_WriteErrClient(Origin,
connected = IRC_WriteStrClient(Origin,
ERR_CHANOPRIVSNEEDED_MSG,
Client_ID(Origin),
Channel_Name(Channel));
@@ -740,12 +756,12 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
if (client)
x[0] = *mode_ptr;
else
connected = IRC_WriteErrClient(Origin,
connected = IRC_WriteStrClient(Origin,
ERR_NOSUCHNICK_MSG,
Client_ID(Origin),
Req->argv[arg_arg]);
} else {
connected = IRC_WriteErrClient(Origin,
connected = IRC_WriteStrClient(Origin,
ERR_CHANOPRIVSNEEDED_MSG,
Client_ID(Origin),
Channel_Name(Channel));
@@ -760,8 +776,7 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
* mode, because most other servers don't do
* it as well and some clients send "wired"
* MODE commands like "MODE #chan -ooo nick". */
IRC_SetPenalty(Origin, 2);
connected = IRC_WriteErrClient(Origin,
connected = IRC_WriteStrClient(Origin,
ERR_NEEDMOREPARAMS_MSG,
Client_ID(Origin), Req->command);
#endif
@@ -786,7 +801,7 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
Client, Channel,
Req->argv[arg_arg]);
} else {
connected = IRC_WriteErrClient(Origin,
connected = IRC_WriteStrClient(Origin,
ERR_CHANOPRIVSNEEDED_MSG,
Client_ID(Origin),
Channel_Name(Channel));
@@ -813,7 +828,7 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
"Unknown mode \"%c%c\" from \"%s\" on %s!?",
set ? '+' : '-', *mode_ptr,
Client_ID(Origin), Channel_Name(Channel));
connected = IRC_WriteErrClient(Origin,
connected = IRC_WriteStrClient(Origin,
ERR_UNKNOWNMODE_MSG,
Client_ID(Origin), *mode_ptr,
Channel_Name(Channel));
@@ -836,11 +851,12 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
/* Validate target client */
if (client && (!Channel_IsMemberOf(Channel, client))) {
if (!IRC_WriteErrClient(Origin, ERR_USERNOTINCHANNEL_MSG,
Client_ID(Origin),
Client_ID(client),
Channel_Name(Channel)))
if (!IRC_WriteStrClient
(Origin, ERR_USERNOTINCHANNEL_MSG,
Client_ID(Origin), Client_ID(client),
Channel_Name(Channel)))
break;
continue;
}
@@ -925,35 +941,31 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
return connected;
} /* Channel_Mode */
/**
* Handler for the IRC "AWAY" command.
*
* @param Client The client from which this command has been received.
* @param Req Request structure with prefix and all parameters.
* @return CONNECTED or DISCONNECTED.
*/
GLOBAL bool
IRC_AWAY( CLIENT *Client, REQUEST *Req )
{
assert (Client != NULL);
assert (Req != NULL);
assert( Client != NULL );
assert( Req != NULL );
if (Req->argc == 1 && Req->argv[0][0]) {
Client_SetAway(Client, Req->argv[0]);
Client_ModeAdd(Client, 'a');
IRC_WriteStrServersPrefix(Client, Client, "MODE %s :+a",
Client_ID( Client));
return IRC_WriteStrClient(Client, RPL_NOWAWAY_MSG,
Client_ID( Client));
} else {
Client_ModeDel(Client, 'a');
IRC_WriteStrServersPrefix(Client, Client, "MODE %s :-a",
Client_ID( Client));
return IRC_WriteStrClient(Client, RPL_UNAWAY_MSG,
Client_ID( Client));
if( Req->argc > 1 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
if(( Req->argc == 1 ) && (Req->argv[0][0] ))
{
Client_SetAway( Client, Req->argv[0] );
Client_ModeAdd( Client, 'a' );
IRC_WriteStrServersPrefix( Client, Client, "MODE %s :+a", Client_ID( Client ));
return IRC_WriteStrClient( Client, RPL_NOWAWAY_MSG, Client_ID( Client ));
}
else
{
Client_ModeDel( Client, 'a' );
IRC_WriteStrServersPrefix( Client, Client, "MODE %s :-a", Client_ID( Client ));
return IRC_WriteStrClient( Client, RPL_UNAWAY_MSG, Client_ID( Client ));
}
} /* IRC_AWAY */
/**
* Add entries to channel invite, ban and exception lists.
*
@@ -968,7 +980,7 @@ static bool
Add_To_List(char what, CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel,
const char *Pattern)
{
char mask[MASK_LEN];
const char *mask;
struct list_head *list = NULL;
long int current_count;
@@ -977,7 +989,7 @@ Add_To_List(char what, CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel,
assert(Pattern != NULL);
assert(what == 'I' || what == 'b' || what == 'e');
Lists_MakeMask(Pattern, mask, sizeof(mask));
mask = Lists_MakeMask(Pattern);
current_count = Lists_Count(Channel_GetListInvites(Channel))
+ Lists_Count(Channel_GetListExcepts(Channel))
+ Lists_Count(Channel_GetListBans(Channel));
@@ -998,7 +1010,7 @@ Add_To_List(char what, CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel,
return CONNECTED;
if (Client_Type(Client) == CLIENT_USER &&
current_count >= MAX_HNDL_CHANNEL_LISTS)
return IRC_WriteErrClient(Client, ERR_LISTFULL_MSG,
return IRC_WriteStrClient(Client, ERR_LISTFULL_MSG,
Client_ID(Client),
Channel_Name(Channel), mask,
MAX_HNDL_CHANNEL_LISTS);
@@ -1020,8 +1032,9 @@ Add_To_List(char what, CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel,
return Send_ListChange(true, what, Prefix, Client, Channel, mask);
}
/**
* Delete entries from channel invite, ban and exception lists.
* Delete entries from channel invite, ban and exeption lists.
*
* @param what Can be 'I' for invite, 'b' for ban, and 'e' for exception list.
* @param Prefix The originator of the command.
@@ -1034,7 +1047,7 @@ static bool
Del_From_List(char what, CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel,
const char *Pattern)
{
char mask[MASK_LEN];
const char *mask;
struct list_head *list = NULL;
assert(Client != NULL);
@@ -1042,7 +1055,7 @@ Del_From_List(char what, CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel,
assert(Pattern != NULL);
assert(what == 'I' || what == 'b' || what == 'e');
Lists_MakeMask(Pattern, mask, sizeof(mask));
mask = Lists_MakeMask(Pattern);
switch (what) {
case 'I':
@@ -1063,6 +1076,7 @@ Del_From_List(char what, CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel,
return Send_ListChange(false, what, Prefix, Client, Channel, mask);
}
/**
* Send information about changed channel invite/ban/exception lists to clients.
*
@@ -1100,4 +1114,5 @@ Send_ListChange(const bool IsAdd, const char ModeChar, CLIENT *Prefix,
return ok;
} /* Send_ListChange */
/* -eof- */

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2013 Alexander Barton (alex@barton.de) and Contributors.
* Copyright (c)2001-2005 by Alexander Barton (alex@barton.de)
*
* 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
@@ -24,7 +24,6 @@
#include "defines.h"
#include "conn.h"
#include "channel.h"
#include "irc-macros.h"
#include "irc-write.h"
#include "lists.h"
#include "log.h"
@@ -34,7 +33,6 @@
#include "exp.h"
#include "irc-op.h"
/* Local functions */
static bool
try_kick(CLIENT *peer, CLIENT* from, const char *nick, const char *channel,
@@ -43,22 +41,13 @@ try_kick(CLIENT *peer, CLIENT* from, const char *nick, const char *channel,
CLIENT *target = Client_Search(nick);
if (!target)
return IRC_WriteErrClient(from, ERR_NOSUCHNICK_MSG,
Client_ID(from), nick);
return IRC_WriteStrClient(from, ERR_NOSUCHNICK_MSG, Client_ID(from), nick);
Channel_Kick(peer, target, from, channel, reason);
return true;
}
/* Global functions */
/**
* Handler for the IRC command "KICK".
*
* @param Client The client from which this command has been received.
* @param Req Request structure with prefix and all parameters.
* @return CONNECTED or DISCONNECTED.
*/
GLOBAL bool
IRC_KICK(CLIENT *Client, REQUEST *Req)
{
@@ -71,7 +60,9 @@ IRC_KICK(CLIENT *Client, REQUEST *Req)
assert( Client != NULL );
assert( Req != NULL );
_IRC_GET_SENDER_OR_RETURN_(from, Req, Client)
if ((Req->argc < 2) || (Req->argc > 3))
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
while (*itemList) {
if (*itemList == ',') {
@@ -90,6 +81,15 @@ IRC_KICK(CLIENT *Client, REQUEST *Req)
itemList++;
}
if (Client_Type(Client) == CLIENT_SERVER)
from = Client_Search(Req->prefix);
else
from = Client;
if (!from)
return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG,
Client_ID(Client), Req->prefix);
reason = Req->argc == 3 ? Req->argv[2] : Client_ID(from);
currentNick = Req->argv[1];
currentChannel = Req->argv[0];
@@ -122,20 +122,13 @@ IRC_KICK(CLIENT *Client, REQUEST *Req)
nickCount--;
}
} else {
IRC_SetPenalty(Client, 2);
return IRC_WriteErrClient(Client, ERR_NEEDMOREPARAMS_MSG,
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
}
return true;
} /* IRC_KICK */
/**
* Handler for the IRC command "INVITE".
*
* @param Client The client from which this command has been received.
* @param Req Request structure with prefix and all parameters.
* @return CONNECTED or DISCONNECTED.
*/
GLOBAL bool
IRC_INVITE(CLIENT *Client, REQUEST *Req)
{
@@ -147,47 +140,51 @@ IRC_INVITE(CLIENT *Client, REQUEST *Req)
assert( Client != NULL );
assert( Req != NULL );
_IRC_GET_SENDER_OR_RETURN_(from, Req, Client)
if (Req->argc != 2)
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
if (Client_Type(Client) == CLIENT_SERVER)
from = Client_Search(Req->prefix);
else
from = Client;
if (!from)
return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG,
Client_ID(Client), Req->prefix);
/* Search user */
target = Client_Search(Req->argv[0]);
if (!target || (Client_Type(target) != CLIENT_USER))
return IRC_WriteErrClient(from, ERR_NOSUCHNICK_MSG,
Client_ID(Client), Req->argv[0]);
return IRC_WriteStrClient(from, ERR_NOSUCHNICK_MSG,
Client_ID(Client), Req->argv[0]);
chan = Channel_Search(Req->argv[1]);
if (chan) {
/* Channel exists. Is the user a valid member of the channel? */
if (!Channel_IsMemberOf(chan, from))
return IRC_WriteErrClient(from, ERR_NOTONCHANNEL_MSG,
Client_ID(Client),
Req->argv[1]);
return IRC_WriteStrClient(from, ERR_NOTONCHANNEL_MSG, Client_ID(Client), Req->argv[1]);
/* Is the channel "invite-disallow"? */
if (Channel_HasMode(chan, 'V'))
return IRC_WriteErrClient(from, ERR_NOINVITE_MSG,
Client_ID(from),
Channel_Name(chan));
if (strchr(Channel_Modes(chan), 'V'))
return IRC_WriteStrClient(from, ERR_NOINVITE_MSG,
Client_ID(from), Channel_Name(chan));
/* Is the channel "invite-only"? */
if (Channel_HasMode(chan, 'i')) {
if (strchr(Channel_Modes(chan), 'i')) {
/* Yes. The user must be channel owner/admin/operator/halfop! */
if (!Channel_UserHasMode(chan, from, 'q') &&
!Channel_UserHasMode(chan, from, 'a') &&
!Channel_UserHasMode(chan, from, 'o') &&
!Channel_UserHasMode(chan, from, 'h'))
return IRC_WriteErrClient(from,
ERR_CHANOPRIVSNEEDED_MSG,
Client_ID(from),
Channel_Name(chan));
if (!strchr(Channel_UserModes(chan, from), 'q') &&
!strchr(Channel_UserModes(chan, from), 'a') &&
!strchr(Channel_UserModes(chan, from), 'o') &&
!strchr(Channel_UserModes(chan, from), 'h'))
return IRC_WriteStrClient(from, ERR_CHANOPRIVSNEEDED_MSG,
Client_ID(from), Channel_Name(chan));
remember = true;
}
/* Is the target user already member of the channel? */
if (Channel_IsMemberOf(chan, target))
return IRC_WriteErrClient(from, ERR_USERONCHANNEL_MSG,
Client_ID(from),
Req->argv[0], Req->argv[1]);
return IRC_WriteStrClient(from, ERR_USERONCHANNEL_MSG,
Client_ID(from), Req->argv[0], Req->argv[1]);
/* If the target user is banned on that channel: remember invite */
if (Lists_Check(Channel_GetListBans(chan), target))
@@ -195,14 +192,13 @@ IRC_INVITE(CLIENT *Client, REQUEST *Req)
if (remember) {
/* We must remember this invite */
if (!Channel_AddInvite(chan, Client_MaskCloaked(target),
true))
if (!Channel_AddInvite(chan, Client_Mask(target), true))
return CONNECTED;
}
}
LogDebug("User \"%s\" invites \"%s\" to \"%s\" ...", Client_Mask(from),
Req->argv[0], Req->argv[1]);
LogDebug("User \"%s\" invites \"%s\" to \"%s\" ...", Client_Mask(from), Req->argv[0], Req->argv[1]);
/*
* RFC 2812 says:
@@ -222,7 +218,7 @@ IRC_INVITE(CLIENT *Client, REQUEST *Req)
Client_ID(from), Req->argv[0], colon_if_necessary, Req->argv[1]))
return DISCONNECTED;
if (Client_HasMode(target, 'a') &&
if (strchr(Client_Modes(target), 'a') &&
!IRC_WriteStrClient(from, RPL_AWAY_MSG, Client_ID(from),
Client_ID(target), Client_Away(target)))
return DISCONNECTED;
@@ -230,4 +226,5 @@ IRC_INVITE(CLIENT *Client, REQUEST *Req)
return CONNECTED;
} /* IRC_INVITE */
/* -eof- */

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2013 Alexander Barton (alex@barton.de) and Contributors.
* Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors.
*
* 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
@@ -28,14 +28,11 @@
#include "conf.h"
#include "channel.h"
#include "class.h"
#include "parse.h"
#include "irc.h"
#include "irc-macros.h"
#include "irc-write.h"
#include "lists.h"
#include "log.h"
#include "match.h"
#include "messages.h"
#include "parse.h"
#include "op.h"
#include <exp.h>
@@ -50,13 +47,16 @@ Bad_OperPass(CLIENT *Client, char *errtoken, char *errmsg)
{
Log(LOG_WARNING, "Got invalid OPER from \"%s\": \"%s\" -- %s",
Client_Mask(Client), errtoken, errmsg);
return IRC_WriteErrClient(Client, ERR_PASSWDMISMATCH_MSG,
IRC_SetPenalty(Client, 3);
return IRC_WriteStrClient(Client, ERR_PASSWDMISMATCH_MSG,
Client_ID(Client));
} /* Bad_OperPass */
/**
* Handler for the IRC "OPER" command.
*
* See RFC 2812, 3.1.4 "Oper message".
*
* @param Client The client from which this command has been received.
* @param Req Request structure with prefix and all parameters.
* @return CONNECTED or DISCONNECTED.
@@ -70,6 +70,10 @@ IRC_OPER( CLIENT *Client, REQUEST *Req )
assert( Client != NULL );
assert( Req != NULL );
if (Req->argc != 2)
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
len = array_length(&Conf_Opers, sizeof(*op));
op = array_start(&Conf_Opers);
for (i = 0; i < len && strcmp(op[i].name, Req->argv[0]); i++)
@@ -92,16 +96,20 @@ IRC_OPER( CLIENT *Client, REQUEST *Req )
Client_ID(Client));
}
Log(LOG_NOTICE|LOG_snotice,
"Got valid OPER for \"%s\" from \"%s\", user is an IRC operator now.",
Req->argv[0], Client_Mask(Client));
if (!Client_OperByMe(Client))
Log(LOG_NOTICE|LOG_snotice,
"Got valid OPER from \"%s\", user is an IRC operator now.",
Client_Mask(Client));
Client_SetOperByMe(Client, true);
return IRC_WriteStrClient(Client, RPL_YOUREOPER_MSG, Client_ID(Client));
} /* IRC_OPER */
/**
* Handler for the IRC "DIE" command.
*
* See RFC 2812, 4.3 "Die message".
*
* @param Client The client from which this command has been received.
* @param Req Request structure with prefix and all parameters.
* @return CONNECTED or DISCONNECTED.
@@ -120,6 +128,15 @@ IRC_DIE(CLIENT * Client, REQUEST * Req)
if (!Op_Check(Client, Req))
return Op_NoPrivileges(Client, Req);
/* Bad number of parameters? */
#ifdef STRICT_RFC
if (Req->argc != 0)
#else
if (Req->argc > 1)
#endif
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
/* Is a message given? */
if (Req->argc > 0) {
c = Conn_First();
@@ -142,6 +159,8 @@ IRC_DIE(CLIENT * Client, REQUEST * Req)
/**
* Handler for the IRC "REHASH" command.
*
* See RFC 2812, 4.2 "Rehash message".
*
* @param Client The client from which this command has been received.
* @param Req Request structure with prefix and all parameters.
* @return CONNECTED or DISCONNECTED.
@@ -157,6 +176,11 @@ IRC_REHASH( CLIENT *Client, REQUEST *Req )
if (!Op_Check(Client, Req))
return Op_NoPrivileges(Client, Req);
/* Bad number of parameters? */
if (Req->argc != 0)
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command );
Log(LOG_NOTICE|LOG_snotice, "Got REHASH command from \"%s\" ...",
Client_Mask(Client));
IRC_WriteStrClient(Client, RPL_REHASHING_MSG, Client_ID(Client));
@@ -169,6 +193,8 @@ IRC_REHASH( CLIENT *Client, REQUEST *Req )
/**
* Handler for the IRC "RESTART" command.
*
* See RFC 2812, 4.4 "Restart message".
*
* @param Client The client from which this command has been received.
* @param Req Request structure with prefix and all parameters.
* @return CONNECTED or DISCONNECTED.
@@ -184,6 +210,11 @@ IRC_RESTART( CLIENT *Client, REQUEST *Req )
if (!Op_Check(Client, Req))
return Op_NoPrivileges(Client, Req);
/* Bad number of parameters? */
if (Req->argc != 0)
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
Log(LOG_NOTICE|LOG_snotice, "Got RESTART command from \"%s\" ...",
Client_Mask(Client));
NGIRCd_SignalRestart = true;
@@ -194,6 +225,8 @@ IRC_RESTART( CLIENT *Client, REQUEST *Req )
/**
* Handler for the IRC "CONNECT" command.
*
* See RFC 2812, 3.4.7 "Connect message".
*
* @param Client The client from which this command has been received.
* @param Req Request structure with prefix and all parameters.
* @return CONNECTED or DISCONNECTED.
@@ -206,25 +239,21 @@ IRC_CONNECT(CLIENT * Client, REQUEST * Req)
assert(Client != NULL);
assert(Req != NULL);
/* Bad number of parameters? */
if (Req->argc != 1 && Req->argc != 2 && Req->argc != 3 &&
Req->argc != 5 && Req->argc != 6) {
IRC_SetPenalty(Client, 2);
return IRC_WriteErrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
}
/* Invalid port number? */
if ((Req->argc > 1) && atoi(Req->argv[1]) < 1) {
IRC_SetPenalty(Client, 2);
return IRC_WriteErrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
}
if (Client_Type(Client) != CLIENT_SERVER
&& !Client_HasMode(Client, 'o'))
return Op_NoPrivileges(Client, Req);
/* Bad number of parameters? */
if (Req->argc != 1 && Req->argc != 2 && Req->argc != 3 &&
Req->argc != 5 && Req->argc != 6)
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
/* Invalid port number? */
if ((Req->argc > 1) && atoi(Req->argv[1]) < 1)
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
from = Client;
target = Client_ThisServer();
@@ -233,14 +262,14 @@ IRC_CONNECT(CLIENT * Client, REQUEST * Req)
if (Client_Type(Client) == CLIENT_SERVER && Req->prefix)
from = Client_Search(Req->prefix);
if (! from)
return IRC_WriteErrClient(Client, ERR_NOSUCHNICK_MSG,
Client_ID(Client), Req->prefix);
return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG,
Client_ID(Client), Req->prefix);
target = (Req->argc == 3) ? Client_Search(Req->argv[2])
: Client_Search(Req->argv[5]);
if (! target || Client_Type(target) != CLIENT_SERVER)
return IRC_WriteErrClient(from, ERR_NOSUCHSERVER_MSG,
Client_ID(from), Req->argv[0]);
return IRC_WriteStrClient(from, ERR_NOSUCHSERVER_MSG,
Client_ID(from), Req->argv[0]);
}
if (target != Client_ThisServer()) {
@@ -263,7 +292,7 @@ IRC_CONNECT(CLIENT * Client, REQUEST * Req)
switch (Req->argc) {
case 1:
if (!Conf_EnablePassiveServer(Req->argv[0]))
return IRC_WriteErrClient(from, ERR_NOSUCHSERVER_MSG,
return IRC_WriteStrClient(from, ERR_NOSUCHSERVER_MSG,
Client_ID(from),
Req->argv[0]);
break;
@@ -272,7 +301,7 @@ IRC_CONNECT(CLIENT * Client, REQUEST * Req)
/* Connect configured server */
if (!Conf_EnableServer
(Req->argv[0], (UINT16) atoi(Req->argv[1])))
return IRC_WriteErrClient(from, ERR_NOSUCHSERVER_MSG,
return IRC_WriteStrClient(from, ERR_NOSUCHSERVER_MSG,
Client_ID(from),
Req->argv[0]);
break;
@@ -281,7 +310,7 @@ IRC_CONNECT(CLIENT * Client, REQUEST * Req)
if (!Conf_AddServer
(Req->argv[0], (UINT16) atoi(Req->argv[1]), Req->argv[2],
Req->argv[3], Req->argv[4]))
return IRC_WriteErrClient(from, ERR_NOSUCHSERVER_MSG,
return IRC_WriteStrClient(from, ERR_NOSUCHSERVER_MSG,
Client_ID(from),
Req->argv[0]);
}
@@ -317,6 +346,11 @@ IRC_DISCONNECT(CLIENT * Client, REQUEST * Req)
if (!Op_Check(Client, Req))
return Op_NoPrivileges(Client, Req);
/* Bad number of parameters? */
if (Req->argc != 1)
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
IRC_SendWallops(Client_ThisServer(), Client_ThisServer(),
"Received DISCONNECT %s from %s",
Req->argv[0], Client_ID(Client));
@@ -330,7 +364,7 @@ IRC_DISCONNECT(CLIENT * Client, REQUEST * Req)
/* Disconnect configured server */
if (!Conf_DisableServer(Req->argv[0]))
return IRC_WriteErrClient(Client, ERR_NOSUCHSERVER_MSG,
return IRC_WriteStrClient(Client, ERR_NOSUCHSERVER_MSG,
Client_ID(Client), Req->argv[0]);
/* Are we still connected or were we killed, too? */
@@ -343,6 +377,8 @@ IRC_DISCONNECT(CLIENT * Client, REQUEST * Req)
/**
* Handler for the IRC "WALLOPS" command.
*
* See RFC 2812, 4.7 "Operwall message".
*
* @param Client The client from which this command has been received.
* @param Req Request structure with prefix and all parameters.
* @return CONNECTED or DISCONNECTED.
@@ -355,10 +391,15 @@ IRC_WALLOPS( CLIENT *Client, REQUEST *Req )
assert( Client != NULL );
assert( Req != NULL );
if (Req->argc != 1)
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
switch (Client_Type(Client)) {
case CLIENT_USER:
if (!Op_Check(Client, Req))
return Op_NoPrivileges(Client, Req);
if (!Client_OperByMe(Client))
return IRC_WriteStrClient(Client, ERR_NOPRIVILEGES_MSG,
Client_ID(Client));
from = Client;
break;
case CLIENT_SERVER:
@@ -369,7 +410,7 @@ IRC_WALLOPS( CLIENT *Client, REQUEST *Req )
}
if (!from)
return IRC_WriteErrClient(Client, ERR_NOSUCHNICK_MSG,
return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG,
Client_ID(Client), Req->prefix);
IRC_SendWallops(Client, from, "%s", Req->argv[0]);
@@ -386,26 +427,22 @@ IRC_WALLOPS( CLIENT *Client, REQUEST *Req )
GLOBAL bool
IRC_xLINE(CLIENT *Client, REQUEST *Req)
{
CLIENT *from, *c, *c_next;
char reason[COMMAND_LEN], class_c;
struct list_head *list;
time_t timeout;
CLIENT *from;
int class;
char class_c;
assert(Client != NULL);
assert(Req != NULL);
/* Bad number of parameters? */
if (Req->argc != 1 && Req->argc != 3) {
IRC_SetPenalty(Client, 2);
return IRC_WriteErrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
}
from = Op_Check(Client, Req);
if (!from)
return Op_NoPrivileges(Client, Req);
/* Bad number of parameters? */
if (Req->argc != 1 && Req->argc != 3)
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
switch(Req->command[0]) {
case 'g':
case 'G':
@@ -436,11 +473,8 @@ IRC_xLINE(CLIENT *Client, REQUEST *Req)
}
} else {
/* Add new mask to list */
timeout = atol(Req->argv[1]);
if (timeout > 0)
timeout += time(NULL);
if (Class_AddMask(class, Req->argv[0],
timeout,
time(NULL) + atol(Req->argv[1]),
Req->argv[2])) {
Log(LOG_NOTICE|LOG_snotice,
"\"%s\" added \"%s\" to %c-Line list: \"%s\" (%ld seconds).",
@@ -453,20 +487,6 @@ IRC_xLINE(CLIENT *Client, REQUEST *Req)
Req->argv[0], Req->argv[1],
Req->argv[2]);
}
/* Check currently connected clients */
snprintf(reason, sizeof(reason), "%c-Line by \"%s\": \"%s\"",
class_c, Client_ID(from), Req->argv[2]);
list = Class_GetList(class);
c = Client_First();
while (c) {
c_next = Client_Next(c);
if ((class == CLASS_GLINE || Client_Conn(c) > NONE)
&& Lists_Check(list, c))
IRC_KillClient(Client, NULL,
Client_ID(c), reason);
c = c_next;
}
}
}

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2013 Alexander Barton (alex@barton.de) and Contributors.
* Copyright (c)2001-2007 Alexander Barton (alex@barton.de)
*
* 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
@@ -29,6 +29,7 @@
#include "conn-zip.h"
#include "conf.h"
#include "channel.h"
#include "irc-write.h"
#include "lists.h"
#include "log.h"
#include "messages.h"
@@ -36,24 +37,20 @@
#include "numeric.h"
#include "ngircd.h"
#include "irc-info.h"
#include "irc-macros.h"
#include "irc-write.h"
#include "op.h"
#include "exp.h"
#include "irc-server.h"
/**
* Handler for the IRC "SERVER" command.
*
* @param Client The client from which this command has been received.
* @param Req Request structure with prefix and all parameters.
* @return CONNECTED or DISCONNECTED.
* Handler for the IRC command "SERVER".
* See RFC 2813 section 4.1.2.
*/
GLOBAL bool
IRC_SERVER( CLIENT *Client, REQUEST *Req )
{
char str[100];
char str[LINE_LEN];
CLIENT *from, *c;
int i;
@@ -62,7 +59,7 @@ IRC_SERVER( CLIENT *Client, REQUEST *Req )
/* Return an error if this is not a local client */
if (Client_Conn(Client) <= NONE)
return IRC_WriteErrClient(Client, ERR_UNKNOWNCOMMAND_MSG,
return IRC_WriteStrClient(Client, ERR_UNKNOWNCOMMAND_MSG,
Client_ID(Client), Req->command);
if (Client_Type(Client) == CLIENT_GOTPASS ||
@@ -72,19 +69,17 @@ IRC_SERVER( CLIENT *Client, REQUEST *Req )
LogDebug("Connection %d: got SERVER command (new server link) ...",
Client_Conn(Client));
if (Req->argc != 2 && Req->argc != 3) {
IRC_SetPenalty(Client, 2);
return IRC_WriteErrClient(Client, ERR_NEEDMOREPARAMS_MSG,
if (Req->argc != 2 && Req->argc != 3)
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client),
Req->command);
}
/* Get configuration index of new remote server ... */
for (i = 0; i < MAX_SERVERS; i++)
if (strcasecmp(Req->argv[0], Conf_Server[i].name) == 0)
break;
/* Make sure the remote server is configured here */
/* Makre sure the remote server is configured here */
if (i >= MAX_SERVERS) {
Log(LOG_ERR,
"Connection %d: Server \"%s\" not configured here!",
@@ -154,17 +149,17 @@ IRC_SERVER( CLIENT *Client, REQUEST *Req )
Client_SetType(Client, CLIENT_UNKNOWNSERVER);
#ifdef ZLIB
if (Client_HasFlag(Client, 'Z')
if (strchr(Client_Flags(Client), 'Z')
&& !Zip_InitConn(Client_Conn(Client))) {
Conn_Close(Client_Conn(Client),
"Can't initialize compression (zlib)!",
"Can't inizialize compression (zlib)!",
NULL, false );
return DISCONNECTED;
}
#endif
#ifdef IRCPLUS
if (Client_HasFlag(Client, 'H')) {
if (strchr(Client_Flags(Client), 'H')) {
LogDebug("Peer supports IRC+ extended server handshake ...");
if (!IRC_Send_ISUPPORT(Client))
return DISCONNECTED;
@@ -185,70 +180,41 @@ IRC_SERVER( CLIENT *Client, REQUEST *Req )
{
/* New server is being introduced to the network */
if (Req->argc != 4) {
IRC_SetPenalty(Client, 2);
return IRC_WriteErrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
}
if( Req->argc != 4 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
/* check for existing server with same ID */
if (!Client_CheckID(Client, Req->argv[0]))
return DISCONNECTED;
if( ! Client_CheckID( Client, Req->argv[0] )) return DISCONNECTED;
from = Client_Search( Req->prefix );
if (! from) {
if( ! from )
{
/* Uh, Server, that introduced the new server is unknown?! */
Log(LOG_ALERT,
"Unknown ID in prefix of SERVER: \"%s\"! (on connection %d)",
Req->prefix, Client_Conn(Client));
Conn_Close(Client_Conn(Client), NULL,
"Unknown ID in prefix of SERVER", true);
Log( LOG_ALERT, "Unknown ID in prefix of SERVER: \"%s\"! (on connection %d)", Req->prefix, Client_Conn( Client ));
Conn_Close( Client_Conn( Client ), NULL, "Unknown ID in prefix of SERVER", true);
return DISCONNECTED;
}
c = Client_NewRemoteServer(Client, Req->argv[0], from,
atoi(Req->argv[1]), atoi(Req->argv[2]),
Req->argv[3], true);
c = Client_NewRemoteServer(Client, Req->argv[0], from, atoi(Req->argv[1]), atoi(Req->argv[2]), Req->argv[3], true);
if (!c) {
Log(LOG_ALERT,
"Can't create client structure for server! (on connection %d)",
Client_Conn(Client));
Conn_Close(Client_Conn(Client), NULL,
"Can't allocate client structure for remote server",
true);
Log( LOG_ALERT, "Can't create client structure for server! (on connection %d)", Client_Conn( Client ));
Conn_Close( Client_Conn( Client ), NULL, "Can't allocate client structure for remote server", true);
return DISCONNECTED;
}
if (Client_Hops(c) > 1 && Req->prefix[0])
snprintf(str, sizeof(str), "connected to %s, ",
Client_ID(from));
else
strcpy(str, "");
Log(LOG_NOTICE|LOG_snotice,
"Server \"%s\" registered (via %s, %s%d hop%s).",
Client_ID(c), Client_ID(Client), str, Client_Hops(c),
Client_Hops(c) > 1 ? "s": "" );
if(( Client_Hops( c ) > 1 ) && ( Req->prefix[0] )) snprintf( str, sizeof( str ), "connected to %s, ", Client_ID( from ));
else strcpy( str, "" );
Log( LOG_NOTICE|LOG_snotice, "Server \"%s\" registered (via %s, %s%d hop%s).", Client_ID( c ), Client_ID( Client ), str, Client_Hops( c ), Client_Hops( c ) > 1 ? "s": "" );
/* notify other servers */
IRC_WriteStrServersPrefix(Client, from, "SERVER %s %d %d :%s",
Client_ID(c), Client_Hops(c) + 1,
Client_MyToken(c), Client_Info(c));
IRC_WriteStrServersPrefix( Client, from, "SERVER %s %d %d :%s", Client_ID( c ), Client_Hops( c ) + 1, Client_MyToken( c ), Client_Info( c ));
return CONNECTED;
} else {
IRC_SetPenalty(Client, 2);
return IRC_WriteErrClient(Client, ERR_NEEDMOREPARAMS_MSG,
} else
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
}
} /* IRC_SERVER */
/*
* Handler for the IRC "NJOIN" command.
*
* @param Client The client from which this command has been received.
* @param Req Request structure with prefix and all parameters.
* @return CONNECTED or DISCONNECTED.
*/
GLOBAL bool
IRC_NJOIN( CLIENT *Client, REQUEST *Req )
{
@@ -260,6 +226,8 @@ IRC_NJOIN( CLIENT *Client, REQUEST *Req )
assert( Client != NULL );
assert( Req != NULL );
if( Req->argc != 2 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
strlcpy( nick_in, Req->argv[1], sizeof( nick_in ));
strcpy( nick_out, "" );
@@ -320,19 +288,15 @@ IRC_NJOIN( CLIENT *Client, REQUEST *Req )
}
/* forward to other servers */
if (nick_out[0] != '\0')
IRC_WriteStrServersPrefix(Client, Client_ThisServer(),
"NJOIN %s :%s", Req->argv[0], nick_out);
if( nick_out[0] != '\0' ) IRC_WriteStrServersPrefix( Client, Client_ThisServer( ), "NJOIN %s :%s", Req->argv[0], nick_out );
return CONNECTED;
} /* IRC_NJOIN */
/**
* Handler for the IRC "SQUIT" command.
*
* @param Client The client from which this command has been received.
* @param Req Request structure with prefix and all parameters.
* @return CONNECTED or DISCONNECTED.
* Handler for the IRC command "SQUIT".
* See RFC 2813 section 4.1.2 and RFC 2812 section 3.1.8.
*/
GLOBAL bool
IRC_SQUIT(CLIENT * Client, REQUEST * Req)
@@ -349,6 +313,11 @@ IRC_SQUIT(CLIENT * Client, REQUEST * Req)
&& !Client_HasMode(Client, 'o'))
return Op_NoPrivileges(Client, Req);
/* Bad number of arguments? */
if (Req->argc != 2)
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
if (Client_Type(Client) == CLIENT_SERVER && Req->prefix) {
from = Client_Search(Req->prefix);
if (Client_Type(from) != CLIENT_SERVER
@@ -357,7 +326,7 @@ IRC_SQUIT(CLIENT * Client, REQUEST * Req)
} else
from = Client;
if (!from)
return IRC_WriteErrClient(Client, ERR_NOSUCHNICK_MSG,
return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG,
Client_ID(Client), Req->prefix);
if (Client_Type(Client) == CLIENT_USER)
@@ -383,7 +352,7 @@ IRC_SQUIT(CLIENT * Client, REQUEST * Req)
if (Req->argv[1][0])
if (Client_NextHop(from) != Client || con > NONE)
snprintf(msg, sizeof(msg), "\"%s\" (SQUIT from %s)",
snprintf(msg, sizeof(msg), "%s (SQUIT from %s)",
Req->argv[1], Client_ID(from));
else
strlcpy(msg, Req->argv[1], sizeof(msg));
@@ -416,7 +385,7 @@ IRC_SQUIT(CLIENT * Client, REQUEST * Req)
logmsg[0] = '\0';
if (!strchr(msg, '('))
snprintf(logmsg, sizeof(logmsg),
"\"%s\" (SQUIT from %s)", Req->argv[1],
"%s (SQUIT from %s)", Req->argv[1],
Client_ID(from));
Client_Destroy(target, logmsg[0] ? logmsg : msg,
msg, false);

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2013 Alexander Barton (alex@barton.de) and Contributors.
* Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
*
* 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
@@ -33,58 +33,17 @@
#include "exp.h"
#include "irc-write.h"
#define SEND_TO_USER 1
#define SEND_TO_SERVER 2
static const char *Get_Prefix PARAMS((CLIENT *Target, CLIENT *Client));
static void cb_writeStrServersPrefixFlag PARAMS((CLIENT *Client,
CLIENT *Prefix, void *Buffer));
static void Send_Marked_Connections PARAMS((CLIENT *Prefix, const char *Buffer));
static bool Send_Marked_Connections PARAMS((CLIENT *Prefix, const char *Buffer));
/**
* Send an error message to a client and enforce a penalty time.
*
* @param Client The target client.
* @param Format Format string.
* @return CONNECTED or DISCONNECTED.
*/
#ifdef PROTOTYPES
GLOBAL bool
IRC_WriteErrClient( CLIENT *Client, const char *Format, ... )
#else
GLOBAL bool
IRC_WriteErrClient( Client, Format, va_alist )
CLIENT *Client;
const char *Format;
va_dcl
#endif
{
char buffer[1000];
va_list ap;
assert(Client != NULL);
assert(Format != NULL);
#ifdef PROTOTYPES
va_start(ap, Format);
#else
va_start(ap);
#endif
vsnprintf(buffer, 1000, Format, ap);
va_end(ap);
IRC_SetPenalty(Client, 2);
return IRC_WriteStrClientPrefix(Client, Client_ThisServer(),
"%s", buffer);
}
/**
* Send a message to a client.
*
* @param Client The target client.
* @param Format Format string.
* @return CONNECTED or DISCONNECTED.
*/
#ifdef PROTOTYPES
GLOBAL bool
IRC_WriteStrClient( CLIENT *Client, const char *Format, ... )
@@ -97,31 +56,27 @@ va_dcl
#endif
{
char buffer[1000];
bool ok = CONNECTED;
va_list ap;
assert(Client != NULL);
assert(Format != NULL);
assert( Client != NULL );
assert( Format != NULL );
#ifdef PROTOTYPES
va_start(ap, Format);
va_start( ap, Format );
#else
va_start(ap);
va_start( ap );
#endif
vsnprintf(buffer, 1000, Format, ap);
va_end(ap);
vsnprintf( buffer, 1000, Format, ap );
va_end( ap );
/* to the client itself */
ok = IRC_WriteStrClientPrefix( Client, Client_ThisServer( ), "%s", buffer );
return ok;
} /* IRC_WriteStrClient */
return IRC_WriteStrClientPrefix(Client, Client_ThisServer(),
"%s", buffer);
}
/**
* Send a message to a client using a specific prefix.
*
* @param Client The target client.
* @param Prefix The prefix to use.
* @param Format Format string.
* @return CONNECTED or DISCONNECTED.
*/
#ifdef PROTOTYPES
GLOBAL bool
IRC_WriteStrClientPrefix(CLIENT *Client, CLIENT *Prefix, const char *Format, ...)
@@ -153,24 +108,15 @@ va_dcl
return Conn_WriteStr(Client_Conn(Client_NextHop(Client)), ":%s %s",
Get_Prefix(Client_NextHop(Client), Prefix), buffer);
}
} /* IRC_WriteStrClientPrefix */
/**
* Send a message to all client in a channel.
*
* The message is only sent once per remote server.
*
* @param Client The sending client, excluded while forwarding the message.
* @param Channel The target channel.
* @param Remote If not set, the message is sent to local clients only.
* @param Format Format string.
*/
#ifdef PROTOTYPES
GLOBAL void
GLOBAL bool
IRC_WriteStrChannel(CLIENT *Client, CHANNEL *Chan, bool Remote,
const char *Format, ...)
#else
GLOBAL void
GLOBAL bool
IRC_WriteStrChannel(Client, Chan, Remote, Format, va_alist)
CLIENT *Client;
CHANNEL *Chan;
@@ -193,27 +139,21 @@ va_dcl
vsnprintf( buffer, 1000, Format, ap );
va_end( ap );
IRC_WriteStrChannelPrefix(Client, Chan, Client_ThisServer(),
Remote, "%s", buffer);
}
return IRC_WriteStrChannelPrefix( Client, Chan, Client_ThisServer( ), Remote, "%s", buffer );
} /* IRC_WriteStrChannel */
/**
* Send a message to all client in a channel using a specific prefix.
*
* The message is only sent once per remote server.
*
* @param Client The sending client, excluded while forwarding the message.
* @param Channel The target channel.
* @param Prefix The prefix to use.
* @param Remote If not set, the message is sent to local clients only.
* @param Format Format string.
* send message to all clients in the same channel, but only send message
* once per remote server.
*/
#ifdef PROTOTYPES
GLOBAL void
GLOBAL bool
IRC_WriteStrChannelPrefix(CLIENT *Client, CHANNEL *Chan, CLIENT *Prefix,
bool Remote, const char *Format, ...)
#else
GLOBAL void
GLOBAL bool
IRC_WriteStrChannelPrefix(Client, Chan, Prefix, Remote, Format, va_alist)
CLIENT *Client;
CHANNEL *Chan;
@@ -245,36 +185,29 @@ va_dcl
Conn_ClearFlags( );
cl2chan = Channel_FirstMember( Chan );
while(cl2chan) {
while( cl2chan )
{
c = Channel_GetClient( cl2chan );
if (!Remote) {
if (Client_Conn(c) <= NONE)
c = NULL;
else if(Client_Type(c) == CLIENT_SERVER)
c = NULL;
if( ! Remote )
{
if( Client_Conn( c ) <= NONE ) c = NULL;
else if( Client_Type( c ) == CLIENT_SERVER ) c = NULL;
}
if(c)
c = Client_NextHop(c);
if( c ) c = Client_NextHop( c );
if(c && c != Client) {
if( c && ( c != Client ))
{
/* Ok, another Client */
conn = Client_Conn(c);
if (Client_Type(c) == CLIENT_SERVER)
Conn_SetFlag(conn, SEND_TO_SERVER);
else
Conn_SetFlag(conn, SEND_TO_USER);
conn = Client_Conn( c );
if( Client_Type( c ) == CLIENT_SERVER ) Conn_SetFlag( conn, SEND_TO_SERVER );
else Conn_SetFlag( conn, SEND_TO_USER );
}
cl2chan = Channel_NextMember(Chan, cl2chan);
cl2chan = Channel_NextMember( Chan, cl2chan );
}
Send_Marked_Connections(Prefix, buffer);
}
return Send_Marked_Connections(Prefix, buffer);
} /* IRC_WriteStrChannelPrefix */
/**
* Send a message to all the servers in the network.
*
* @param Client The sending client, excluded while forwarding the message.
* @param Format Format string.
*/
#ifdef PROTOTYPES
GLOBAL void
IRC_WriteStrServers(CLIENT *ExceptOf, const char *Format, ...)
@@ -299,16 +232,10 @@ va_dcl
vsnprintf( buffer, 1000, Format, ap );
va_end( ap );
IRC_WriteStrServersPrefix(ExceptOf, Client_ThisServer(), "%s", buffer);
}
IRC_WriteStrServersPrefix( ExceptOf, Client_ThisServer( ), "%s", buffer );
} /* IRC_WriteStrServers */
/**
* Send a message to all the servers in the network using a specific prefix.
*
* @param Client The sending client, excluded while forwarding the message.
* @param Prefix The prefix to use.
* @param Format Format string.
*/
#ifdef PROTOTYPES
GLOBAL void
IRC_WriteStrServersPrefix(CLIENT *ExceptOf, CLIENT *Prefix,
@@ -337,17 +264,9 @@ va_dcl
va_end( ap );
IRC_WriteStrServersPrefixFlag( ExceptOf, Prefix, '\0', "%s", buffer );
}
} /* IRC_WriteStrServersPrefix */
/**
* Send a message to all the servers in the network using a specific prefix
* and matching a "client flag".
*
* @param Client The sending client, excluded while forwarding the message.
* @param Prefix The prefix to use.
* @param Flag Client flag that must be set on the target.
* @param Format Format string.
*/
#ifdef PROTOTYPES
GLOBAL void
IRC_WriteStrServersPrefixFlag(CLIENT *ExceptOf, CLIENT *Prefix, char Flag,
@@ -378,18 +297,9 @@ va_dcl
IRC_WriteStrServersPrefixFlag_CB(ExceptOf, Prefix, Flag,
cb_writeStrServersPrefixFlag, buffer);
}
} /* IRC_WriteStrServersPrefixFlag */
/**
* Send a message to all the servers in the network using a specific prefix
* and matching a "client flag" using a callback function.
*
* @param Client The sending client, excluded while forwarding the message.
* @param Prefix The prefix to use.
* @param Flag Client flag that must be set on the target.
* @param callback Callback function.
* @param Format Format string.
*/
GLOBAL void
IRC_WriteStrServersPrefixFlag_CB(CLIENT *ExceptOf, CLIENT *Prefix, char Flag,
void (*callback)(CLIENT *, CLIENT *, void *), void *cb_data)
@@ -401,32 +311,24 @@ IRC_WriteStrServersPrefixFlag_CB(CLIENT *ExceptOf, CLIENT *Prefix, char Flag,
if (Client_Type(c) == CLIENT_SERVER && Client_Conn(c) > NONE &&
c != Client_ThisServer() && c != ExceptOf) {
/* Found a target server, do the flags match? */
if (Flag == '\0' || Client_HasFlag(c, Flag))
if (Flag == '\0' || strchr(Client_Flags(c), Flag))
callback(c, Prefix, cb_data);
}
c = Client_Next(c);
}
}
} /* IRC_WriteStrServersPrefixFlag */
/**
* Send a message to all "related" clients.
*
* Related clients are the one that share one ore more channels with the client
* sending this message.
*
* The message is only sent once per remote server.
*
* @param Client The sending client, excluded while forwarding the message.
* @param Prefix The prefix to use.
* @param Remote If not set, the message is sent to local clients only.
* @param Format Format string.
* send message to all clients that are in the same channels as the client sending this message.
* only send message once per reote server.
*/
#ifdef PROTOTYPES
GLOBAL void
GLOBAL bool
IRC_WriteStrRelatedPrefix(CLIENT *Client, CLIENT *Prefix, bool Remote,
const char *Format, ...)
#else
GLOBAL void
GLOBAL bool
IRC_WriteStrRelatedPrefix(Client, Prefix, Remote, Format, va_alist)
CLIENT *Client;
CLIENT *Prefix;
@@ -482,16 +384,13 @@ va_dcl
chan_cl2chan = Channel_NextChannelOf( Client, chan_cl2chan );
}
Send_Marked_Connections(Prefix, buffer);
return Send_Marked_Connections(Prefix, buffer);
} /* IRC_WriteStrRelatedPrefix */
/**
* Send WALLOPS message.
*
* @param Client The sending client, excluded while forwarding the message.
* @param From The (remote) sender of the message.
* @param Format Format string.
*/
*/
#ifdef PROTOTYPES
GLOBAL void
IRC_SendWallops(CLIENT *Client, CLIENT *From, const char *Format, ...)
@@ -535,32 +434,23 @@ va_dcl
}
} /* IRC_SendWallops */
/**
* Set a "penalty time" for an IRC client.
*
* Note: penalty times are never set for server links or remote clients!
*
* @param Client The client.
* @param Seconds The additional "penalty time" to enforce.
*/
GLOBAL void
IRC_SetPenalty(CLIENT *Client, time_t Seconds)
IRC_SetPenalty( CLIENT *Client, time_t Seconds )
{
CONN_ID c;
assert(Client != NULL);
assert(Seconds > 0);
assert( Client != NULL );
assert( Seconds > 0 );
if (Client_Type(Client) == CLIENT_SERVER)
return;
if( Client_Type( Client ) == CLIENT_SERVER ) return;
c = Client_Conn(Client);
if (c <= NONE)
return;
Conn_SetPenalty(c, Seconds);
c = Client_Conn( Client );
if (c > NONE)
Conn_SetPenalty(c, Seconds);
} /* IRC_SetPenalty */
static const char *
Get_Prefix(CLIENT *Target, CLIENT *Client)
{
@@ -573,22 +463,19 @@ Get_Prefix(CLIENT *Target, CLIENT *Client)
return Client_MaskCloaked(Client);
} /* Get_Prefix */
static void
cb_writeStrServersPrefixFlag(CLIENT *Client, CLIENT *Prefix, void *Buffer)
{
IRC_WriteStrClientPrefix(Client, Prefix, "%s", Buffer);
} /* cb_writeStrServersPrefixFlag */
/**
* Send a message to all marked connections using a specific prefix.
*
* @param Prefix The prefix to use.
* @param Buffer The message to send.
*/
static void
static bool
Send_Marked_Connections(CLIENT *Prefix, const char *Buffer)
{
CONN_ID conn;
bool ok = CONNECTED;
assert(Prefix != NULL);
assert(Buffer != NULL);
@@ -596,13 +483,17 @@ Send_Marked_Connections(CLIENT *Prefix, const char *Buffer)
conn = Conn_First();
while (conn != NONE) {
if (Conn_Flag(conn) == SEND_TO_SERVER)
Conn_WriteStr(conn, ":%s %s",
Client_ID(Prefix), Buffer);
ok = Conn_WriteStr(conn, ":%s %s",
Client_ID(Prefix), Buffer);
else if (Conn_Flag(conn) == SEND_TO_USER)
Conn_WriteStr(conn, ":%s %s",
Client_MaskCloaked(Prefix), Buffer);
conn = Conn_Next(conn);
ok = Conn_WriteStr(conn, ":%s %s",
Client_MaskCloaked(Prefix), Buffer);
if (!ok)
break;
conn = Conn_Next( conn );
}
return ok;
}
/* -eof- */

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2013 Alexander Barton (alex@barton.de) and Contributors.
* Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
*
* 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
@@ -17,15 +17,13 @@
* Sending IRC commands over the network (header)
*/
GLOBAL bool IRC_WriteErrClient PARAMS((CLIENT *Client, const char *Format, ...));
GLOBAL bool IRC_WriteStrClient PARAMS((CLIENT *Client, const char *Format, ...));
GLOBAL bool IRC_WriteStrClientPrefix PARAMS((CLIENT *Client, CLIENT *Prefix,
const char *Format, ...));
GLOBAL void IRC_WriteStrChannel PARAMS((CLIENT *Client, CHANNEL *Chan,
GLOBAL bool IRC_WriteStrChannel PARAMS((CLIENT *Client, CHANNEL *Chan,
bool Remote, const char *Format, ...));
GLOBAL void IRC_WriteStrChannelPrefix PARAMS((CLIENT *Client, CHANNEL *Chan,
GLOBAL bool IRC_WriteStrChannelPrefix PARAMS((CLIENT *Client, CHANNEL *Chan,
CLIENT *Prefix, bool Remote, const char *Format, ...));
GLOBAL void IRC_WriteStrServers PARAMS((CLIENT *ExceptOf,
@@ -38,7 +36,7 @@ GLOBAL void IRC_WriteStrServersPrefixFlag_CB PARAMS((CLIENT *ExceptOf,
CLIENT *Prefix, char Flag,
void (*callback)(CLIENT *, CLIENT *, void *), void *cb_data));
GLOBAL void IRC_WriteStrRelatedPrefix PARAMS((CLIENT *Client, CLIENT *Prefix,
GLOBAL bool IRC_WriteStrRelatedPrefix PARAMS((CLIENT *Client, CLIENT *Prefix,
bool Remote, const char *Format, ...));
GLOBAL void IRC_SendWallops PARAMS((CLIENT *Client, CLIENT *From,

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2013 Alexander Barton (alex@barton.de) and Contributors.
* Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
*
* 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
@@ -27,25 +27,24 @@
#include "channel.h"
#include "conn-encoding.h"
#include "defines.h"
#include "irc-macros.h"
#include "irc-write.h"
#include "log.h"
#include "match.h"
#include "messages.h"
#include "parse.h"
#include "op.h"
#include "tool.h"
#include "exp.h"
#include "irc.h"
static char *Option_String PARAMS((CONN_ID Idx));
static bool Send_Message PARAMS((CLIENT *Client, REQUEST *Req, int ForceType,
bool SendErrors));
static bool Send_Message_Mask PARAMS((CLIENT *from, char *command,
char *targetMask, char *message,
bool SendErrors));
static bool Help PARAMS((CLIENT *Client, const char *Topic));
/**
* Check if a list limit is reached and inform client accordingly.
@@ -75,15 +74,9 @@ IRC_CheckListTooBig(CLIENT *From, const int Count, const int Limit,
return true;
}
/**
* Handler for the IRC "ERROR" command.
*
* @param Client The client from which this command has been received.
* @param Req Request structure with prefix and all parameters.
* @return CONNECTED or DISCONNECTED.
*/
GLOBAL bool
IRC_ERROR(CLIENT *Client, REQUEST *Req)
IRC_ERROR( CLIENT *Client, REQUEST *Req )
{
assert( Client != NULL );
assert( Req != NULL );
@@ -109,10 +102,11 @@ IRC_ERROR(CLIENT *Client, REQUEST *Req)
return CONNECTED;
} /* IRC_ERROR */
/**
* Handler for the IRC "KILL" command.
*
* This function implements the IRC command "KILL" which is used to selectively
* This function implements the IRC command "KILL" wich is used to selectively
* disconnect clients. It can be used by IRC operators and servers, for example
* to "solve" nick collisions after netsplits. See RFC 2812 section 3.7.1.
*
@@ -120,22 +114,28 @@ IRC_ERROR(CLIENT *Client, REQUEST *Req)
* KILL command being received over the network! Client is Client_ThisServer()
* in this case, and the prefix in Req is NULL.
*
* @param Client The client from which this command has been received or
* Client_ThisServer() when generated interanlly.
* @param Req Request structure with prefix and all parameters.
* @return CONNECTED or DISCONNECTED.
* @param Client The client from which this command has been received
* or Client_ThisServer() when generated interanlly.
* @param Req Request structure with prefix and all parameters.
* @returns CONNECTED or DISCONNECTED.
*/
GLOBAL bool
IRC_KILL(CLIENT *Client, REQUEST *Req)
IRC_KILL( CLIENT *Client, REQUEST *Req )
{
CLIENT *prefix;
char reason[COMMAND_LEN];
CLIENT *prefix, *c;
char reason[COMMAND_LEN], *msg;
CONN_ID my_conn, conn;
assert (Client != NULL);
assert (Req != NULL);
if (Client_Type(Client) != CLIENT_SERVER && !Op_Check(Client, Req))
return Op_NoPrivileges(Client, Req);
if (Client_Type(Client) != CLIENT_SERVER && !Client_OperByMe(Client))
return IRC_WriteStrClient(Client, ERR_NOPRIVILEGES_MSG,
Client_ID(Client));
if (Req->argc != 2)
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
/* Get prefix (origin); use the client if no prefix is given. */
if (Req->prefix)
@@ -144,8 +144,7 @@ IRC_KILL(CLIENT *Client, REQUEST *Req)
prefix = Client;
/* Log a warning message and use this server as origin when the
* prefix (origin) is invalid. And this is the reason why we don't
* use the _IRC_GET_SENDER_OR_RETURN_ macro above! */
* prefix (origin) is invalid. */
if (!prefix) {
Log(LOG_WARNING, "Got KILL with invalid prefix: \"%s\"!",
Req->prefix );
@@ -154,7 +153,7 @@ IRC_KILL(CLIENT *Client, REQUEST *Req)
if (Client != Client_ThisServer())
Log(LOG_NOTICE|LOG_snotice,
"Got KILL command from \"%s\" for \"%s\": \"%s\".",
"Got KILL command from \"%s\" for \"%s\": %s",
Client_Mask(prefix), Req->argv[0], Req->argv[1]);
/* Build reason string: Prefix the "reason" if the originator is a
@@ -165,28 +164,74 @@ IRC_KILL(CLIENT *Client, REQUEST *Req)
else
strlcpy(reason, Req->argv[1], sizeof(reason));
return IRC_KillClient(Client, prefix, Req->argv[0], reason);
}
/* Inform other servers */
IRC_WriteStrServersPrefix(Client, prefix, "KILL %s :%s",
Req->argv[0], reason);
/* Save ID of this connection */
my_conn = Client_Conn( Client );
/* Do we host such a client? */
c = Client_Search( Req->argv[0] );
if( c )
{
if(( Client_Type( c ) != CLIENT_USER ) &&
( Client_Type( c ) != CLIENT_GOTNICK ))
{
/* Target of this KILL is not a regular user, this is
* invalid! So we ignore this case if we received a
* regular KILL from the network and try to kill the
* client/connection anyway (but log an error!) if the
* origin is the local server. */
if( Client != Client_ThisServer( ))
{
/* Invalid KILL received from remote */
if( Client_Type( c ) == CLIENT_SERVER )
msg = ERR_CANTKILLSERVER_MSG;
else
msg = ERR_NOPRIVILEGES_MSG;
return IRC_WriteStrClient( Client, msg,
Client_ID( Client ));
}
Log( LOG_ERR, "Got KILL for invalid client type: %d, \"%s\"!",
Client_Type( c ), Req->argv[0] );
}
/* Kill the client NOW:
* - Close the local connection (if there is one),
* - Destroy the CLIENT structure for remote clients.
* Note: Conn_Close() removes the CLIENT structure as well. */
conn = Client_Conn( c );
if(conn > NONE)
Conn_Close(conn, NULL, reason, true);
else
Client_Destroy(c, NULL, reason, false);
}
else
Log( LOG_NOTICE, "Client with nick \"%s\" is unknown here.", Req->argv[0] );
/* Are we still connected or were we killed, too? */
if(( my_conn > NONE ) && ( Conn_GetClient( my_conn )))
return CONNECTED;
else
return DISCONNECTED;
} /* IRC_KILL */
/**
* Handler for the IRC "NOTICE" command.
*
* @param Client The client from which this command has been received.
* @param Req Request structure with prefix and all parameters.
* @return CONNECTED or DISCONNECTED.
*/
* Handler for the IRC command NOTICE.
*/
GLOBAL bool
IRC_NOTICE(CLIENT *Client, REQUEST *Req)
{
return Send_Message(Client, Req, CLIENT_USER, false);
} /* IRC_NOTICE */
/**
* Handler for the IRC "PRIVMSG" command.
*
* @param Client The client from which this command has been received.
* @param Req Request structure with prefix and all parameters.
* @return CONNECTED or DISCONNECTED.
* Handler for the IRC command PRIVMSG.
*/
GLOBAL bool
IRC_PRIVMSG(CLIENT *Client, REQUEST *Req)
@@ -194,12 +239,9 @@ IRC_PRIVMSG(CLIENT *Client, REQUEST *Req)
return Send_Message(Client, Req, CLIENT_USER, true);
} /* IRC_PRIVMSG */
/**
* Handler for the IRC "SQUERY" command.
*
* @param Client The client from which this command has been received.
* @param Req Request structure with prefix and all parameters.
* @return CONNECTED or DISCONNECTED.
* Handler for the IRC command SQUERY.
*/
GLOBAL bool
IRC_SQUERY(CLIENT *Client, REQUEST *Req)
@@ -207,269 +249,95 @@ IRC_SQUERY(CLIENT *Client, REQUEST *Req)
return Send_Message(Client, Req, CLIENT_SERVICE, true);
} /* IRC_SQUERY */
/*
* Handler for the IRC "TRACE" command.
*
* @param Client The client from which this command has been received.
* @param Req Request structure with prefix and all parameters.
* @return CONNECTED or DISCONNECTED.
*/
GLOBAL bool
IRC_TRACE(CLIENT *Client, REQUEST *Req)
GLOBAL bool
IRC_TRACE( CLIENT *Client, REQUEST *Req )
{
CLIENT *from, *target, *c;
CONN_ID idx, idx2;
char user[CLIENT_USER_LEN];
assert(Client != NULL);
assert(Req != NULL);
assert( Client != NULL );
assert( Req != NULL );
IRC_SetPenalty(Client, 3);
/* Bad number of arguments? */
if( Req->argc > 1 ) return IRC_WriteStrClient( Client, ERR_NORECIPIENT_MSG, Client_ID( Client ), Req->command );
_IRC_GET_SENDER_OR_RETURN_(from, Req, Client)
_IRC_GET_TARGET_SERVER_OR_RETURN_(target, Req, 0, from)
/* Search sender */
if( Client_Type( Client ) == CLIENT_SERVER ) from = Client_Search( Req->prefix );
else from = Client;
if( ! from ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix );
/* Search target */
if( Req->argc == 1 ) target = Client_Search( Req->argv[0] );
else target = Client_ThisServer( );
/* Forward command to other server? */
if (target != Client_ThisServer()) {
/* Send RPL_TRACELINK back to initiator */
idx = Client_Conn(Client);
assert(idx > NONE);
idx2 = Client_Conn(Client_NextHop(target));
assert(idx2 > NONE);
if( target != Client_ThisServer( ))
{
if(( ! target ) || ( Client_Type( target ) != CLIENT_SERVER )) return IRC_WriteStrClient( from, ERR_NOSUCHSERVER_MSG, Client_ID( from ), Req->argv[0] );
if (!IRC_WriteStrClient(from, RPL_TRACELINK_MSG,
Client_ID(from), PACKAGE_NAME,
PACKAGE_VERSION, Client_ID(target),
Client_ID(Client_NextHop(target)),
Option_String(idx2),
time(NULL) - Conn_StartTime(idx2),
Conn_SendQ(idx), Conn_SendQ(idx2)))
return DISCONNECTED;
/* Send RPL_TRACELINK back to initiator */
idx = Client_Conn( Client ); assert( idx > NONE );
idx2 = Client_Conn( Client_NextHop( target )); assert( idx2 > NONE );
if( ! IRC_WriteStrClient( from, RPL_TRACELINK_MSG, Client_ID( from ), PACKAGE_NAME, PACKAGE_VERSION, Client_ID( target ), Client_ID( Client_NextHop( target )), Option_String( idx2 ), time( NULL ) - Conn_StartTime( idx2 ), Conn_SendQ( idx ), Conn_SendQ( idx2 ))) return DISCONNECTED;
/* Forward command */
IRC_WriteStrClientPrefix(target, from, "TRACE %s", Req->argv[0]);
IRC_WriteStrClientPrefix( target, from, "TRACE %s", Req->argv[0] );
return CONNECTED;
}
/* Infos about all connected servers */
c = Client_First();
while (c) {
if (Client_Conn(c) > NONE) {
c = Client_First( );
while( c )
{
if( Client_Conn( c ) > NONE )
{
/* Local client */
if (Client_Type(c) == CLIENT_SERVER) {
if( Client_Type( c ) == CLIENT_SERVER )
{
/* Server link */
strlcpy(user, Client_User(c), sizeof(user));
if (user[0] == '~')
strlcpy(user, "unknown", sizeof(user));
if (!IRC_WriteStrClient(from,
RPL_TRACESERVER_MSG,
Client_ID(from), Client_ID(c),
user, Client_Hostname(c),
Client_Mask(Client_ThisServer()),
Option_String(Client_Conn(c))))
return DISCONNECTED;
strlcpy( user, Client_User( c ), sizeof( user ));
if( user[0] == '~' ) strlcpy( user, "unknown", sizeof( user ));
if( ! IRC_WriteStrClient( from, RPL_TRACESERVER_MSG, Client_ID( from ), Client_ID( c ), user, Client_Hostname( c ), Client_Mask( Client_ThisServer( )), Option_String( Client_Conn( c )))) return DISCONNECTED;
}
if (Client_Type(c) == CLIENT_USER
&& Client_HasMode(c, 'o')) {
if(( Client_Type( c ) == CLIENT_USER ) && ( strchr( Client_Modes( c ), 'o' )))
{
/* IRC Operator */
if (!IRC_WriteStrClient(from,
RPL_TRACEOPERATOR_MSG,
Client_ID(from), Client_ID(c)))
return DISCONNECTED;
if( ! IRC_WriteStrClient( from, RPL_TRACEOPERATOR_MSG, Client_ID( from ), Client_ID( c ))) return DISCONNECTED;
}
}
c = Client_Next( c );
}
return IRC_WriteStrClient(from, RPL_TRACEEND_MSG, Client_ID(from),
Conf_ServerName, PACKAGE_NAME,
PACKAGE_VERSION, NGIRCd_DebugLevel);
IRC_SetPenalty( Client, 3 );
return IRC_WriteStrClient( from, RPL_TRACEEND_MSG, Client_ID( from ), Conf_ServerName, PACKAGE_NAME, PACKAGE_VERSION, NGIRCd_DebugLevel );
} /* IRC_TRACE */
/**
* Handler for the IRC "HELP" command.
*
* @param Client The client from which this command has been received.
* @param Req Request structure with prefix and all parameters.
* @return CONNECTED or DISCONNECTED.
*/
GLOBAL bool
IRC_HELP(CLIENT *Client, REQUEST *Req)
IRC_HELP( CLIENT *Client, REQUEST *Req )
{
COMMAND *cmd;
assert(Client != NULL);
assert(Req != NULL);
assert( Client != NULL );
assert( Req != NULL );
IRC_SetPenalty(Client, 2);
/* Bad number of arguments? */
if( Req->argc > 0 ) return IRC_WriteStrClient( Client, ERR_NORECIPIENT_MSG, Client_ID( Client ), Req->command );
if ((Req->argc == 0 && array_bytes(&Conf_Helptext) > 0)
|| (Req->argc >= 1 && strcasecmp(Req->argv[0], "Commands") != 0)) {
/* Help text available and requested */
if (Req->argc >= 1)
return Help(Client, Req->argv[0]);
if (!Help(Client, "Intro"))
return DISCONNECTED;
return CONNECTED;
}
cmd = Parse_GetCommandStruct();
while(cmd->name) {
if (!IRC_WriteStrClient(Client, "NOTICE %s :%s",
Client_ID(Client), cmd->name))
return DISCONNECTED;
cmd = Parse_GetCommandStruct( );
while( cmd->name )
{
if( ! IRC_WriteStrClient( Client, "NOTICE %s :%s", Client_ID( Client ), cmd->name )) return DISCONNECTED;
cmd++;
}
IRC_SetPenalty( Client, 2 );
return CONNECTED;
} /* IRC_HELP */
/**
* Kill an client identified by its nick name.
*
* Please note that after killig a client, its CLIENT cond CONNECTION
* structures are invalid. So the caller must make sure on its own not to
* access data of probably killed clients after calling this function!
*
* @param Client The client from which the command leading to the KILL has
* been received, or NULL. The KILL will no be forwarded in this
* direction. Only relevant when From is set, too.
* @param From The client from which the command originated, or NULL for
the local server.
* @param Nick The nick name to kill.
* @param Reason Text to send as reason to the client and other servers.
*/
GLOBAL bool
IRC_KillClient(CLIENT *Client, CLIENT *From, const char *Nick, const char *Reason)
{
const char *msg;
CONN_ID my_conn, conn;
CLIENT *c;
/* Do we know such a client in the network? */
c = Client_Search(Nick);
if (!c) {
LogDebug("Client with nick \"%s\" is unknown, not forwaring.", Nick);
return CONNECTED;
}
/* Inform other servers */
IRC_WriteStrServersPrefix(From ? Client : NULL,
From ? From : Client_ThisServer(),
"KILL %s :%s", Nick, Reason);
if (Client_Type(c) != CLIENT_USER && Client_Type(c) != CLIENT_GOTNICK) {
/* Target of this KILL is not a regular user, this is
* invalid! So we ignore this case if we received a
* regular KILL from the network and try to kill the
* client/connection anyway (but log an error!) if the
* origin is the local server. */
if (Client != Client_ThisServer()) {
/* Invalid KILL received from remote */
if (Client_Type(c) == CLIENT_SERVER)
msg = ERR_CANTKILLSERVER_MSG;
else
msg = ERR_NOPRIVILEGES_MSG;
return IRC_WriteErrClient(Client, msg, Client_ID(Client));
}
Log(LOG_ERR,
"Got KILL for invalid client type: %d, \"%s\"!",
Client_Type(c), Nick);
}
/* Save ID of this connection */
my_conn = Client_Conn(Client);
/* Kill the client NOW:
* - Close the local connection (if there is one),
* - Destroy the CLIENT structure for remote clients.
* Note: Conn_Close() removes the CLIENT structure as well. */
conn = Client_Conn(c);
if(conn > NONE)
Conn_Close(conn, NULL, Reason, true);
else
Client_Destroy(c, NULL, Reason, false);
/* Are we still connected or were we killed, too? */
if (my_conn > NONE && Conn_GetClient(my_conn))
return CONNECTED;
else
return DISCONNECTED;
}
/**
* Send help for a given topic to the client.
*
* @param Client The client requesting help.
* @param Topoc The help topic requested.
* @return CONNECTED or DISCONNECTED.
*/
static bool
Help(CLIENT *Client, const char *Topic)
{
char *line;
size_t helptext_len, len_str, idx_start, lines = 0;
bool in_article = false;
assert(Client != NULL);
assert(Topic != NULL);
helptext_len = array_bytes(&Conf_Helptext);
line = array_start(&Conf_Helptext);
while (helptext_len > 0) {
len_str = strlen(line) + 1;
assert(helptext_len >= len_str);
helptext_len -= len_str;
if (in_article) {
/* The first character in each article text line must
* be a TAB (ASCII 9) character which will be stripped
* in the output. If it is not a TAB, the end of the
* article has been reached. */
if (line[0] != '\t') {
if (lines > 0)
return CONNECTED;
else
break;
}
/* A single '.' character indicates an empty line */
if (line[1] == '.' && line[2] == '\0')
idx_start = 2;
else
idx_start = 1;
if (!IRC_WriteStrClient(Client, "NOTICE %s :%s",
Client_ID(Client),
&line[idx_start]))
return DISCONNECTED;
lines++;
} else {
if (line[0] == '-' && line[1] == ' '
&& strcasecmp(&line[2], Topic) == 0)
in_article = true;
}
line += len_str;
}
/* Help topic not found (or empty)! */
if (!IRC_WriteStrClient(Client, "NOTICE %s :No help for \"%s\" found!",
Client_ID(Client), Topic))
return DISCONNECTED;
return CONNECTED;
}
/**
* Get pointer to a static string representing the connection "options".
*
* @param Idx Connection index.
* @return Pointer to static (global) string buffer.
*/
static char *
#ifdef ZLIB
Option_String(CONN_ID Idx)
@@ -478,26 +346,23 @@ Option_String(UNUSED CONN_ID Idx)
#endif
{
static char option_txt[8];
#ifdef ZLIB
UINT16 options;
assert(Idx != NONE);
options = Conn_Options(Idx);
#endif
strcpy(option_txt, "F"); /* No idea what this means, but the
* original ircd sends it ... */
#ifdef SSL_SUPPORT
if(options & CONN_SSL) /* SSL encrypted link */
strlcat(option_txt, "s", sizeof(option_txt));
#endif
#ifdef ZLIB
if(options & CONN_ZIP) /* zlib compression enabled */
strlcat(option_txt, "z", sizeof(option_txt));
if(options & CONN_ZIP) /* zlib compression supported. */
strcat(option_txt, "z");
#endif
LogDebug(" *** %d: %d = %s", Idx, options, option_txt);
return option_txt;
} /* Option_String */
static bool
Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors)
{
@@ -514,20 +379,19 @@ Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors)
if (Req->argc == 0) {
if (!SendErrors)
return CONNECTED;
return IRC_WriteErrClient(Client, ERR_NORECIPIENT_MSG,
return IRC_WriteStrClient(Client, ERR_NORECIPIENT_MSG,
Client_ID(Client), Req->command);
}
if (Req->argc == 1) {
if (!SendErrors)
return CONNECTED;
return IRC_WriteErrClient(Client, ERR_NOTEXTTOSEND_MSG,
return IRC_WriteStrClient(Client, ERR_NOTEXTTOSEND_MSG,
Client_ID(Client));
}
if (Req->argc > 2) {
if (!SendErrors)
return CONNECTED;
IRC_SetPenalty(Client, 2);
return IRC_WriteErrClient(Client, ERR_NEEDMOREPARAMS_MSG,
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
}
@@ -536,7 +400,7 @@ Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors)
else
from = Client;
if (!from)
return IRC_WriteErrClient(Client, ERR_NOSUCHNICK_MSG,
return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG,
Client_ID(Client), Req->prefix);
#ifdef ICONV
@@ -631,7 +495,7 @@ Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors)
#else
if (Client_Type(cl) != ForceType) {
#endif
if (SendErrors && !IRC_WriteErrClient(
if (SendErrors && !IRC_WriteStrClient(
from, ERR_NOSUCHNICK_MSG,Client_ID(from),
currentTarget))
return DISCONNECTED;
@@ -652,7 +516,7 @@ Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors)
!Client_HasMode(from, 'o') &&
!(Client_Type(from) == CLIENT_SERVER) &&
!(Client_Type(from) == CLIENT_SERVICE)) {
if (SendErrors && !IRC_WriteErrClient(from,
if (SendErrors && !IRC_WriteStrClient(from,
ERR_NONONREG_MSG,
Client_ID(from), Client_ID(cl)))
return DISCONNECTED;
@@ -668,7 +532,7 @@ Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors)
cl2chan = Channel_NextChannelOf(cl, cl2chan);
}
if (!cl2chan) {
if (SendErrors && !IRC_WriteErrClient(
if (SendErrors && !IRC_WriteStrClient(
from, ERR_NOTONSAMECHANNEL_MSG,
Client_ID(from), Client_ID(cl)))
return DISCONNECTED;
@@ -677,7 +541,7 @@ Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors)
}
if (SendErrors && (Client_Type(Client) != CLIENT_SERVER)
&& Client_HasMode(cl, 'a')) {
&& strchr(Client_Modes(cl), 'a')) {
/* Target is away */
if (!IRC_WriteStrClient(from, RPL_AWAY_MSG,
Client_ID(from),
@@ -708,7 +572,7 @@ Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors)
} else {
if (!SendErrors)
return CONNECTED;
if (!IRC_WriteErrClient(from, ERR_NOSUCHNICK_MSG,
if (!IRC_WriteStrClient(from, ERR_NOSUCHNICK_MSG,
Client_ID(from), currentTarget))
return DISCONNECTED;
}
@@ -722,6 +586,7 @@ Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors)
return CONNECTED;
} /* Send_Message */
static bool
Send_Message_Mask(CLIENT * from, char * command, char * targetMask,
char * message, bool SendErrors)
@@ -733,10 +598,10 @@ Send_Message_Mask(CLIENT * from, char * command, char * targetMask,
cl = NULL;
if (!Client_HasMode(from, 'o')) {
if (strchr(Client_Modes(from), 'o') == NULL) {
if (!SendErrors)
return true;
return IRC_WriteErrClient(from, ERR_NOPRIVILEGES_MSG,
return IRC_WriteStrClient(from, ERR_NOPRIVILEGES_MSG,
Client_ID(from));
}
@@ -751,7 +616,7 @@ Send_Message_Mask(CLIENT * from, char * command, char * targetMask,
{
if (!SendErrors)
return true;
return IRC_WriteErrClient(from, ERR_WILDTOPLEVEL, targetMask);
return IRC_WriteStrClient(from, ERR_WILDTOPLEVEL, targetMask);
}
/* #: hostmask, see RFC 2812, sec. 3.3.1 */
@@ -781,4 +646,5 @@ Send_Message_Mask(CLIENT * from, char * command, char * targetMask,
return CONNECTED;
} /* Send_Message_Mask */
/* -eof- */

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2013 Alexander Barton (alex@barton.de) and Contributors.
* Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
*
* 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
@@ -28,9 +28,6 @@ GLOBAL bool IRC_SQUERY PARAMS((CLIENT *Client, REQUEST *Req));
GLOBAL bool IRC_TRACE PARAMS((CLIENT *Client, REQUEST *Req));
GLOBAL bool IRC_HELP PARAMS((CLIENT *Client, REQUEST *Req));
GLOBAL bool IRC_KillClient PARAMS((CLIENT *Client, CLIENT *From,
const char *Nick, const char *Reason));
#endif
/* -eof- */

View File

@@ -34,6 +34,8 @@
#include "exp.h"
#include "lists.h"
#define MASK_LEN (2*CLIENT_HOST_LEN)
struct list_elem {
struct list_elem *next; /** pointer to next list element */
char mask[MASK_LEN]; /** IRC mask */
@@ -128,8 +130,7 @@ Lists_Add(struct list_head *h, const char *Mask, time_t ValidUntil,
if (e) {
e->valid_until = ValidUntil;
if (Reason) {
if (e->reason)
free(e->reason);
free(e->reason);
e->reason = strdup(Reason);
}
return true;
@@ -260,13 +261,17 @@ Lists_CheckDupeMask(const struct list_head *h, const char *Mask )
/**
* Generate a valid IRC mask from "any" string given.
*
* Attention: This mask is only valid until the next call to Lists_MakeMask(),
* because a single global buffer ist used! You have to copy the generated
* mask to some sane location yourself!
*
* @param Pattern Source string to generate an IRC mask for.
* @param mask Buffer to store the mask.
* @param len Size of the buffer.
* @return Pointer to global result buffer.
*/
GLOBAL void
Lists_MakeMask(const char *Pattern, char *mask, size_t len)
GLOBAL const char *
Lists_MakeMask(const char *Pattern)
{
static char TheMask[MASK_LEN];
char *excl, *at;
assert(Pattern != NULL);
@@ -279,22 +284,30 @@ Lists_MakeMask(const char *Pattern, char *mask, size_t len)
if (!at && !excl) {
/* Neither "!" nor "@" found: use string as nickname */
strlcpy(mask, Pattern, len - 5);
strlcat(mask, "!*@*", len);
} else if (!at && excl) {
strlcpy(TheMask, Pattern, sizeof(TheMask) - 5);
strlcat(TheMask, "!*@*", sizeof(TheMask));
return TheMask;
}
if (!at && excl) {
/* Domain part is missing */
strlcpy(mask, Pattern, len - 3);
strlcat(mask, "@*", len);
} else if (at && !excl) {
strlcpy(TheMask, Pattern, sizeof(TheMask) - 3);
strlcat(TheMask, "@*", sizeof(TheMask));
return TheMask;
}
if (at && !excl) {
/* User name is missing */
*at = '\0'; at++;
strlcpy(mask, Pattern, len - 5);
strlcat(mask, "!*@", len);
strlcat(mask, at, len);
} else {
/* All parts (nick, user and domain name) are given */
strlcpy(mask, Pattern, len);
strlcpy(TheMask, Pattern, sizeof(TheMask) - 5);
strlcat(TheMask, "!*@", sizeof(TheMask));
strlcat(TheMask, at, sizeof(TheMask));
return TheMask;
}
/* All parts (nick, user and domain name) are given */
strlcpy(TheMask, Pattern, sizeof(TheMask));
return TheMask;
} /* Lists_MakeMask */
/**
@@ -307,20 +320,18 @@ Lists_MakeMask(const char *Pattern, char *mask, size_t len)
bool
Lists_Check(struct list_head *h, CLIENT *Client)
{
return Lists_CheckReason(h, Client, NULL, 0);
return Lists_CheckReason(h, Client) != NULL;
}
/**
* Check if a client is listed in a list and store the reason.
* Check if a client is listed in a list and return the "reason".
*
* @param h List head.
* @param h List head.
* @param Client Client to check.
* @param reason Buffer to store the reason.
* @param len Size of the buffer if reason should be saved.
* @return true if client is listed, false if not.
*/
bool
Lists_CheckReason(struct list_head *h, CLIENT *Client, char *reason, size_t len)
char *
Lists_CheckReason(struct list_head *h, CLIENT *Client)
{
struct list_elem *e, *last, *next;
@@ -331,22 +342,20 @@ Lists_CheckReason(struct list_head *h, CLIENT *Client, char *reason, size_t len)
while (e) {
next = e->next;
if (Match(e->mask, Client_MaskCloaked(Client))) {
if (len && e->reason)
strlcpy(reason, e->reason, len);
if (Match(e->mask, Client_Mask(Client))) {
if (e->valid_until == 1) {
/* Entry is valid only once, delete it */
LogDebug("Deleted \"%s\" from list (used).",
e->mask);
Lists_Unlink(h, last, e);
}
return true;
return e->reason ? e->reason : "";
}
last = e;
e = next;
}
return false;
return NULL;
}
/**

View File

@@ -30,8 +30,7 @@ GLOBAL struct list_elem *Lists_GetFirst PARAMS((const struct list_head *));
GLOBAL struct list_elem *Lists_GetNext PARAMS((const struct list_elem *));
GLOBAL bool Lists_Check PARAMS((struct list_head *head, CLIENT *client));
GLOBAL bool Lists_CheckReason PARAMS((struct list_head *head, CLIENT *client,
char *reason, size_t len));
GLOBAL char *Lists_CheckReason PARAMS((struct list_head *head, CLIENT *client));
GLOBAL struct list_elem *Lists_CheckDupeMask PARAMS((const struct list_head *head,
const char *mask));
@@ -42,7 +41,7 @@ GLOBAL unsigned long Lists_Count PARAMS((struct list_head *h));
GLOBAL void Lists_Free PARAMS((struct list_head *head));
GLOBAL void Lists_MakeMask PARAMS((const char *Pattern, char *mask, size_t len));
GLOBAL const char *Lists_MakeMask PARAMS((const char *Pattern));
GLOBAL const char *Lists_GetMask PARAMS((const struct list_elem *e));
GLOBAL const char *Lists_GetReason PARAMS((const struct list_elem *e));
GLOBAL time_t Lists_GetValidity PARAMS((const struct list_elem *e));

View File

@@ -53,7 +53,7 @@ Log_Message(int Level, const char *msg)
if (!Is_Daemon) {
/* log to console */
fprintf(stdout, "[%ld:%d %4ld] %s\n", (long)getpid(), Level,
(long)(time(NULL) - NGIRCd_Start), msg);
(long)time(NULL) - NGIRCd_Start, msg);
fflush(stdout);
}
#ifdef SYSLOG
@@ -109,9 +109,8 @@ Log_ReInit(void)
GLOBAL void
Log_Exit( void )
{
Log(LOG_INFO, "%s done%s, served %lu connection%s.", PACKAGE_NAME,
NGIRCd_SignalRestart ? " (restarting)" : "", Conn_CountAccepted(),
Conn_CountAccepted() == 1 ? "" : "s");
Log(LOG_NOTICE, "%s done%s, served %lu connections.", PACKAGE_NAME,
NGIRCd_SignalRestart ? " (restarting)" : "", Conn_CountAccepted());
#ifdef SYSLOG
closelog();
#endif
@@ -160,7 +159,7 @@ va_dcl
* suitable for the mode ngIRCd is running in (daemon vs. non-daemon).
* If LOG_snotice is set, the log messages goes to all user with the mode +s
* set and the local &SERVER channel, too.
* Please note: you should use LogDebug(...) for debug messages!
* Please note: you sould use LogDebug(...) for debug messages!
* @param Level syslog level (LOG_xxx)
* @param Format Format string like printf().
* @param ... Further arguments.

View File

@@ -19,7 +19,6 @@
#include "imp.h"
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
@@ -38,7 +37,6 @@
#include "ngircd.h"
#include "pam.h"
#include "irc-info.h"
#include "irc-mode.h"
#include "irc-write.h"
#include "exp.h"
@@ -91,12 +89,13 @@ Login_User(CLIENT * Client)
#ifdef PAM
if (!Conf_PAM) {
/* Don't do any PAM authentication at all if PAM is not
* enabled, instead emulate the behavior of the daemon
* compiled without PAM support. */
if (strcmp(Conn_Password(conn), Conf_ServerPwd) == 0)
/* Don't do any PAM authentication at all, instead emulate
* the beahiour of the daemon compiled without PAM support:
* because there can't be any "server password", all
* passwords supplied are classified as "wrong". */
if(Conn_Password(conn)[0] == '\0')
return Login_User_PostAuth(Client);
Client_Reject(Client, "Bad server password", false);
Client_Reject(Client, "Non-empty password", false);
return DISCONNECTED;
}
@@ -110,27 +109,25 @@ Login_User(CLIENT * Client)
return Login_User_PostAuth(Client);
}
if (Conf_PAM) {
/* Fork child process for PAM authentication; and make sure that the
* process timeout is set higher than the login timeout! */
pid = Proc_Fork(Conn_GetProcStat(conn), pipefd,
cb_Read_Auth_Result, Conf_PongTimeout + 1);
if (pid > 0) {
LogDebug("Authenticator for connection %d created (PID %d).",
conn, pid);
return CONNECTED;
} else {
/* Sub process */
Log_Init_Subprocess("Auth");
Conn_CloseAllSockets(NONE);
result = PAM_Authenticate(Client);
if (write(pipefd[1], &result, sizeof(result)) != sizeof(result))
Log_Subprocess(LOG_ERR,
"Failed to pipe result to parent!");
Log_Exit_Subprocess("Auth");
exit(0);
}
} else return CONNECTED;
/* Fork child process for PAM authentication; and make sure that the
* process timeout is set higher than the login timeout! */
pid = Proc_Fork(Conn_GetProcStat(conn), pipefd,
cb_Read_Auth_Result, Conf_PongTimeout + 1);
if (pid > 0) {
LogDebug("Authenticator for connection %d created (PID %d).",
conn, pid);
return CONNECTED;
} else {
/* Sub process */
Log_Init_Subprocess("Auth");
Conn_CloseAllSockets(NONE);
result = PAM_Authenticate(Client);
if (write(pipefd[1], &result, sizeof(result)) != sizeof(result))
Log_Subprocess(LOG_ERR,
"Failed to pipe result to parent!");
Log_Exit_Subprocess("Auth");
exit(0);
}
#else
/* Check global server password ... */
if (strcmp(Conn_Password(conn), Conf_ServerPwd) != 0) {
@@ -154,9 +151,6 @@ Login_User(CLIENT * Client)
GLOBAL bool
Login_User_PostAuth(CLIENT *Client)
{
REQUEST Req;
char modes[CLIENT_MODE_LEN + 1];
assert(Client != NULL);
if (Class_HandleServerBans(Client) != CONNECTED)
@@ -191,17 +185,8 @@ Login_User_PostAuth(CLIENT *Client)
if (!IRC_Show_MOTD(Client))
return DISCONNECTED;
/* Set default user modes */
if (Conf_DefaultUserModes[0]) {
snprintf(modes, sizeof(modes), "+%s", Conf_DefaultUserModes);
Req.prefix = Client_ThisServer();
Req.command = "MODE";
Req.argc = 2;
Req.argv[0] = Client_ID(Client);
Req.argv[1] = modes;
IRC_MODE(Client, &Req);
} else
IRC_SetPenalty(Client, 1);
/* Suspend the client for a second ... */
IRC_SetPenalty(Client, 1);
return CONNECTED;
}
@@ -209,7 +194,7 @@ Login_User_PostAuth(CLIENT *Client)
#ifdef PAM
/**
* Read result of the authenticator sub-process from pipe
* Read result of the authenticatior sub-process from pipe
*
* @param r_fd File descriptor of the pipe.
* @param events (ignored IO specification)
@@ -217,7 +202,6 @@ Login_User_PostAuth(CLIENT *Client)
static void
cb_Read_Auth_Result(int r_fd, UNUSED short events)
{
char user[CLIENT_USER_LEN], *ptr;
CONN_ID conn;
CLIENT *client;
int result;
@@ -249,14 +233,7 @@ cb_Read_Auth_Result(int r_fd, UNUSED short events)
}
if (result == true) {
/* Authentication succeeded, now set the correct user name
* supplied by the client (without prepended '~' for exmaple),
* but cut it at the first '@' character: */
strlcpy(user, Client_OrigUser(client), sizeof(user));
ptr = strchr(user, '@');
if (ptr)
*ptr = '\0';
Client_SetUser(client, user, true);
Client_SetUser(client, Client_OrigUser(client), true);
(void)Login_User_PostAuth(client);
} else
Client_Reject(client, "Bad password", false);

View File

@@ -55,6 +55,7 @@ static int Matche_After_Star PARAMS(( const char *p, const char *t ));
GLOBAL bool
Match( const char *Pattern, const char *String )
{
/* Pattern mit String vergleichen */
if( Matche( Pattern, String ) == MATCH_VALID ) return true;
else return false;
} /* Match */

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2013 Alexander Barton (alex@barton.de) and Contributors.
* Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
*
* 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
@@ -21,7 +21,7 @@
#define RPL_YOURHOST_MSG "002 %s :Your host is %s, running version ngircd-%s (%s/%s/%s)"
#define RPL_CREATED_MSG "003 %s :This server has been started %s"
#define RPL_MYINFO_MSG "004 %s %s ngircd-%s %s %s"
#define RPL_ISUPPORT1_MSG "005 %s RFC2812 IRCD=ngIRCd CHARSET=UTF-8 CASEMAPPING=ascii PREFIX=(qaohv)~&@%%+ CHANTYPES=%s CHANMODES=beI,k,l,imMnOPQRstVz CHANLIMIT=%s:%d :are supported on this server"
#define RPL_ISUPPORT1_MSG "005 %s RFC2812 IRCD=ngIRCd CHARSET=UTF-8 CASEMAPPING=ascii PREFIX=(qaohv)~&@%%+ CHANTYPES=#&+ CHANMODES=beI,k,l,imMnOPQRstVz CHANLIMIT=#&+:%d :are supported on this server"
#define RPL_ISUPPORT2_MSG "005 %s CHANNELLEN=%d NICKLEN=%d TOPICLEN=%d AWAYLEN=%d KICKLEN=%d MODES=%d MAXLIST=beI:%d EXCEPTS=e INVEX=I PENALTY :are supported on this server"
#define RPL_TRACELINK_MSG "200 %s Link %s-%s %s %s V%s %ld %d %d"
@@ -49,7 +49,6 @@
#define RPL_NETUSERS_MSG "266 %s %lu %lu :Current global users: %lu, Max: %lu"
#define RPL_STATSCONN_MSG "250 %s :Highest connection count: %lu (%lu connections received)"
#define RPL_WHOISSSL_MSG "275 %s %s :is connected via SSL (secure link)"
#define RPL_WHOISCERTFP_MSG "276 %s %s :has client certificate fingerprint %s"
#define RPL_AWAY_MSG "301 %s %s :%s"
#define RPL_USERHOST_MSG "302 %s :"
@@ -57,7 +56,6 @@
#define RPL_UNAWAY_MSG "305 %s :You are no longer marked as being away"
#define RPL_NOWAWAY_MSG "306 %s :You have been marked as being away"
#define RPL_WHOISREGNICK_MSG "307 %s %s :is a registered nick"
#define RPL_WHOISSERVICE_MSG "310 %s %s :is an IRC service"
#define RPL_WHOISUSER_MSG "311 %s %s %s %s * :%s"
#define RPL_WHOISSERVER_MSG "312 %s %s %s :%s"
#define RPL_WHOISOPERATOR_MSG "313 %s %s :is an IRC operator"

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2014 Alexander Barton (alex@barton.de) and Contributors.
* Copyright (c)2001-2013 Alexander Barton (alex@barton.de) and Contributors.
*
* 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
@@ -264,7 +264,7 @@ main(int argc, const char *argv[])
/* Initialize the "main program": chroot environment, user and
* group ID, ... */
if (!NGIRCd_Init(NGIRCd_NoDaemon)) {
Log(LOG_ALERT, "Fatal: Initialization failed, exiting!");
Log(LOG_ALERT, "Fatal: Initialization failed");
exit(1);
}
@@ -297,10 +297,10 @@ main(int argc, const char *argv[])
PROTOVER, PROTOIRCPLUS, PACKAGE_NAME, PACKAGE_VERSION,
IRCPLUSFLAGS);
#ifdef ZLIB
strlcat(NGIRCd_ProtoID, "Z", sizeof NGIRCd_ProtoID);
strcat(NGIRCd_ProtoID, "Z");
#endif
if (Conf_OperCanMode)
strlcat(NGIRCd_ProtoID, "o", sizeof NGIRCd_ProtoID);
strcat(NGIRCd_ProtoID, "o");
#else /* IRCPLUS */
snprintf(NGIRCd_ProtoID, sizeof NGIRCd_ProtoID, "%s%s %s|%s",
PROTOVER, PROTOIRC, PACKAGE_NAME, PACKAGE_VERSION);
@@ -460,7 +460,7 @@ static void
Show_Version( void )
{
puts( NGIRCd_Version );
puts( "Copyright (c)2001-2014 Alexander Barton (<alex@barton.de>) and Contributors." );
puts( "Copyright (c)2001-2013 Alexander Barton (<alex@barton.de>) and Contributors." );
puts( "Homepage: <http://ngircd.barton.de/>\n" );
puts( "This is free software; see the source for copying conditions. There is NO" );
puts( "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." );
@@ -535,23 +535,21 @@ Pidfile_Create(pid_t pid)
len = snprintf(pidbuf, sizeof pidbuf, "%ld\n", (long)pid);
if (len < 0 || len >= (int)sizeof pidbuf) {
Log(LOG_ERR, "Error converting process ID!");
Log(LOG_ERR, "Error converting pid");
close(pidfd);
return;
}
if (write(pidfd, pidbuf, (size_t)len) != (ssize_t)len)
Log(LOG_ERR, "Can't write PID file (%s): %s!", Conf_PidFile,
strerror(errno));
Log( LOG_ERR, "Can't write PID file (%s): %s", Conf_PidFile, strerror( errno ));
if (close(pidfd) != 0)
Log(LOG_ERR, "Error closing PID file (%s): %s!", Conf_PidFile,
strerror(errno));
if( close(pidfd) != 0 )
Log( LOG_ERR, "Error closing PID file (%s): %s", Conf_PidFile, strerror( errno ));
} /* Pidfile_Create */
/**
* Redirect stdin, stdout and stderr to appropriate file handles.
* Redirect stdin, stdout and stderr to apropriate file handles.
*
* @param fd The file handle stdin, stdout and stderr should be redirected to.
*/
@@ -613,13 +611,6 @@ NGIRCd_getNobodyID(uid_t *uid, gid_t *gid )
#endif
#ifdef HAVE_ARC4RANDOM
static void
Random_Init(void)
{
}
#else
static bool
Random_Init_Kern(const char *file)
{
@@ -649,7 +640,6 @@ Random_Init(void)
return;
srand(rand() ^ (unsigned)getpid() ^ (unsigned)time(NULL));
}
#endif
/**
@@ -681,22 +671,21 @@ NGIRCd_Init(bool NGIRCd_NoDaemon)
}
/* SSL initialization */
if (!ConnSSL_InitLibrary()) {
Log(LOG_ERR, "Error during SSL initialization!");
goto out;
}
if (!ConnSSL_InitLibrary())
Log(LOG_WARNING,
"Error during SSL initialization, continuing without SSL ...");
/* Change root */
if (Conf_Chroot[0]) {
if (chdir(Conf_Chroot) != 0) {
Log(LOG_ERR, "Can't chdir() in ChrootDir (%s): %s!",
Log(LOG_ERR, "Can't chdir() in ChrootDir (%s): %s",
Conf_Chroot, strerror(errno));
goto out;
}
if (chroot(Conf_Chroot) != 0) {
Log(LOG_ERR,
"Can't change root directory to \"%s\": %s!",
"Can't change root directory to \"%s\": %s",
Conf_Chroot, strerror(errno));
goto out;
} else {
@@ -727,19 +716,12 @@ NGIRCd_Init(bool NGIRCd_NoDaemon)
if (setgid(Conf_GID) != 0) {
real_errno = errno;
grp = getgrgid(Conf_GID);
Log(LOG_ERR, "Can't change group ID to %s(%u): %s!",
Log(LOG_ERR, "Can't change group ID to %s(%u): %s",
grp ? grp->gr_name : "?", Conf_GID,
strerror(real_errno));
strerror(errno));
if (real_errno != EPERM)
goto out;
}
if (setgroups(0, NULL) != 0) {
real_errno = errno;
Log(LOG_ERR, "Can't drop supplementary group IDs: %s!",
strerror(errno));
if (real_errno != EPERM)
goto out;
}
}
#endif
@@ -748,9 +730,9 @@ NGIRCd_Init(bool NGIRCd_NoDaemon)
if (setuid(Conf_UID) != 0) {
real_errno = errno;
pwd = getpwuid(Conf_UID);
Log(LOG_ERR, "Can't change user ID to %s(%u): %s!",
Log(LOG_ERR, "Can't change user ID to %s(%u): %s",
pwd ? pwd->pw_name : "?", Conf_UID,
strerror(real_errno));
strerror(errno));
if (real_errno != EPERM)
goto out;
}
@@ -782,7 +764,7 @@ NGIRCd_Init(bool NGIRCd_NoDaemon)
setpgrp(0, getpid());
#endif
if (chdir("/") != 0)
Log(LOG_ERR, "Can't change directory to '/': %s!",
Log(LOG_ERR, "Can't change directory to '/': %s",
strerror(errno));
/* Detach stdin, stdout and stderr */
@@ -825,8 +807,8 @@ NGIRCd_Init(bool NGIRCd_NoDaemon)
"Changed working directory to \"%s\" ...",
pwd->pw_dir);
else
Log(LOG_ERR,
"Can't change working directory to \"%s\": %s!",
Log(LOG_INFO,
"Notice: Can't change working directory to \"%s\": %s",
pwd->pw_dir, strerror(errno));
} else
Log(LOG_ERR, "Can't get user informaton for UID %d!?", Conf_UID);

View File

@@ -47,12 +47,12 @@ Announce_Channel(CLIENT *Client, CHANNEL *Chan)
{
CL2CHAN *cl2chan;
CLIENT *cl;
char str[COMMAND_LEN], *ptr;
char str[LINE_LEN], *ptr;
bool njoin, xop;
/* Check features of remote server */
njoin = Conn_Options(Client_Conn(Client)) & CONN_RFC1459 ? false : true;
xop = Client_HasFlag(Client, 'X') ? true : false;
xop = strchr(Client_Flags(Client), 'X') ? true : false;
/* Get all the members of this channel */
cl2chan = Channel_FirstMember(Chan);
@@ -68,21 +68,21 @@ Announce_Channel(CLIENT *Client, CHANNEL *Chan)
strlcat(str, ",", sizeof(str));
/* Prepare user prefix (ChanOp, voiced, ...) */
if (xop && Channel_UserHasMode(Chan, cl, 'q'))
if (xop && strchr(Channel_UserModes(Chan, cl), 'q'))
strlcat(str, "~", sizeof(str));
if (xop && Channel_UserHasMode(Chan, cl, 'a'))
if (xop && strchr(Channel_UserModes(Chan, cl), 'a'))
strlcat(str, "&", sizeof(str));
if (Channel_UserHasMode(Chan, cl, 'o'))
if (strchr(Channel_UserModes(Chan, cl), 'o'))
strlcat(str, "@", sizeof(str));
if (xop && Channel_UserHasMode(Chan, cl, 'h'))
if (xop && strchr(Channel_UserModes(Chan, cl), 'h'))
strlcat(str, "%", sizeof(str));
if (Channel_UserHasMode(Chan, cl, 'v'))
if (strchr(Channel_UserModes(Chan, cl), 'v'))
strlcat(str, "+", sizeof(str));
strlcat(str, Client_ID(cl), sizeof(str));
/* Send the data if the buffer is "full" */
if (strlen(str) > (sizeof(str) - CLIENT_NICK_LEN - 8)) {
if (strlen(str) > (LINE_LEN - CLIENT_NICK_LEN - 8)) {
if (!IRC_WriteStrClient(Client, "%s", str))
return DISCONNECTED;
snprintf(str, sizeof(str), "NJOIN %s :",
@@ -150,6 +150,72 @@ Announce_Server(CLIENT * Client, CLIENT * Server)
} /* Announce_Server */
/**
* Announce existing user to a new server
* @param Client New server
* @param User Existing user in the network
*/
static bool
Announce_User(CLIENT * Client, CLIENT * User)
{
CONN_ID conn;
char *modes;
conn = Client_Conn(Client);
if (Conn_Options(conn) & CONN_RFC1459) {
/* RFC 1459 mode: separate NICK and USER commands */
if (! Conn_WriteStr(conn, "NICK %s :%d",
Client_ID(User), Client_Hops(User) + 1))
return DISCONNECTED;
if (! Conn_WriteStr(conn, ":%s USER %s %s %s :%s",
Client_ID(User), Client_User(User),
Client_Hostname(User),
Client_ID(Client_Introducer(User)),
Client_Info(User)))
return DISCONNECTED;
modes = Client_Modes(User);
if (modes[0]) {
return Conn_WriteStr(conn, ":%s MODE %s +%s",
Client_ID(User), Client_ID(User),
modes);
}
} else {
/* RFC 2813 mode: one combined NICK or SERVICE command */
if (Client_Type(User) == CLIENT_SERVICE
&& strchr(Client_Flags(Client), 'S')) {
if (!IRC_WriteStrClient(Client,
"SERVICE %s %d * +%s %d :%s",
Client_Mask(User),
Client_MyToken(Client_Introducer(User)),
Client_Modes(User), Client_Hops(User) + 1,
Client_Info(User)))
return DISCONNECTED;
} else {
if (!IRC_WriteStrClient(Client,
"NICK %s %d %s %s %d +%s :%s",
Client_ID(User), Client_Hops(User) + 1,
Client_User(User), Client_Hostname(User),
Client_MyToken(Client_Introducer(User)),
Client_Modes(User), Client_Info(User)))
return DISCONNECTED;
}
}
if (strchr(Client_Flags(Client), 'M')) {
/* Synchronize metadata */
if (Client_HostnameCloaked(User)) {
if (!IRC_WriteStrClient(Client,
"METADATA %s cloakhost :%s",
Client_ID(User),
Client_HostnameCloaked(User)))
return DISCONNECTED;
}
}
return CONNECTED;
} /* Announce_User */
#ifdef IRCPLUS
/**
@@ -232,8 +298,8 @@ Send_CHANINFO(CLIENT * Client, CHANNEL * Chan)
if (!*modes && !*topic)
return CONNECTED;
has_k = Channel_HasMode(Chan, 'k');
has_l = Channel_HasMode(Chan, 'l');
has_k = strchr(modes, 'k') != NULL;
has_l = strchr(modes, 'l') != NULL;
/* send CHANINFO */
if (!has_k && !has_l) {
@@ -306,7 +372,7 @@ IRC_Num_ENDOFMOTD(CLIENT * Client, UNUSED REQUEST * Req)
while (c) {
if (Client_Type(c) == CLIENT_USER ||
Client_Type(c) == CLIENT_SERVICE) {
if (!Client_Announce(Client, Client_ThisServer(), c))
if (!Announce_User(Client, c))
return DISCONNECTED;
}
c = Client_Next(c);
@@ -321,7 +387,7 @@ IRC_Num_ENDOFMOTD(CLIENT * Client, UNUSED REQUEST * Req)
}
#ifdef IRCPLUS
/* Send CHANINFO if the peer supports it */
if (Client_HasFlag(Client, 'C')) {
if (strchr(Client_Flags(Client), 'C')) {
if (!Send_CHANINFO(Client, chan))
return DISCONNECTED;
}
@@ -335,7 +401,7 @@ IRC_Num_ENDOFMOTD(CLIENT * Client, UNUSED REQUEST * Req)
}
#ifdef IRCPLUS
if (Client_HasFlag(Client, 'L')) {
if (strchr(Client_Flags(Client), 'L')) {
LogDebug("Synchronizing INVITE- and BAN-lists ...");
if (!Synchronize_Lists(Client))
return DISCONNECTED;

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2013 Alexander Barton (alex@barton.de) and Contributors.
* Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
*
* 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
@@ -46,12 +46,12 @@ Op_NoPrivileges(CLIENT * Client, REQUEST * Req)
if (from) {
Log(LOG_NOTICE, "No privileges: client \"%s\" (%s), command \"%s\"",
Req->prefix, Client_Mask(Client), Req->command);
return IRC_WriteErrClient(from, ERR_NOPRIVILEGES_MSG,
return IRC_WriteStrClient(from, ERR_NOPRIVILEGES_MSG,
Client_ID(from));
} else {
Log(LOG_NOTICE, "No privileges: client \"%s\", command \"%s\"",
Client_Mask(Client), Req->command);
return IRC_WriteErrClient(Client, ERR_NOPRIVILEGES_MSG,
return IRC_WriteStrClient(Client, ERR_NOPRIVILEGES_MSG,
Client_ID(Client));
}
} /* Op_NoPrivileges */
@@ -86,7 +86,7 @@ Op_Check(CLIENT * Client, REQUEST * Req)
return c;
if (!Client_HasMode(c, 'o'))
return NULL;
if (Client_Conn(c) <= NONE && !Conf_AllowRemoteOper)
if (!Client_OperByMe(c) && !Conf_AllowRemoteOper)
return NULL;
/* The client is an local IRC operator, or this server is configured

View File

@@ -15,7 +15,7 @@
/**
* @file
* PAM User Authentication
* PAM User Authentification
*/
#include "imp.h"

View File

@@ -16,7 +16,7 @@
/**
* @file
* PAM User Authentication (header)
* PAM User Authentification (header)
*/
GLOBAL bool PAM_Authenticate PARAMS((CLIENT *Client));

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2013 Alexander Barton (alex@barton.de) and Contributors.
* Copyright (c)2001-2010 Alexander Barton (alex@barton.de)
*
* 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
@@ -60,78 +60,74 @@ struct _NUMERIC {
static COMMAND My_Commands[] =
{
{ "ADMIN", IRC_ADMIN, CLIENT_USER|CLIENT_SERVER, 0, 1, 0, 0, 0 },
{ "AWAY", IRC_AWAY, CLIENT_USER, 0, 1, 0, 0, 0 },
{ "CAP", IRC_CAP, CLIENT_ANY, 1, 2, 0, 0, 0 },
{ "CONNECT", IRC_CONNECT, CLIENT_USER|CLIENT_SERVER, 0, -1, 0, 0, 0 },
#ifdef STRICT_RFC
{ "DIE", IRC_DIE, CLIENT_USER, 0, 0, 0, 0, 0 },
#else
{ "DIE", IRC_DIE, CLIENT_USER, 0, 1, 0, 0, 0 },
#endif
{ "DISCONNECT", IRC_DISCONNECT, CLIENT_USER, 1, 1, 0, 0, 0 },
{ "ERROR", IRC_ERROR, CLIENT_ANY, 0, -1, 0, 0, 0 },
{ "GLINE", IRC_xLINE, CLIENT_USER|CLIENT_SERVER, 0, -1, 0, 0, 0 },
{ "HELP", IRC_HELP, CLIENT_USER, 0, 1, 0, 0, 0 },
{ "INFO", IRC_INFO, CLIENT_USER|CLIENT_SERVER, 0, 1, 0, 0, 0 },
{ "INVITE", IRC_INVITE, CLIENT_USER|CLIENT_SERVER, 2, 2, 0, 0, 0 },
{ "ISON", IRC_ISON, CLIENT_USER, 1, -1, 0, 0, 0 },
{ "JOIN", IRC_JOIN, CLIENT_USER|CLIENT_SERVER, 1, 2, 0, 0, 0 },
{ "KICK", IRC_KICK, CLIENT_USER|CLIENT_SERVER, 2, 3, 0, 0, 0 },
{ "KILL", IRC_KILL, CLIENT_USER|CLIENT_SERVER, 2, 2, 0, 0, 0 },
{ "KLINE", IRC_xLINE, CLIENT_USER|CLIENT_SERVER, 0, -1, 0, 0, 0 },
{ "LINKS", IRC_LINKS, CLIENT_USER|CLIENT_SERVER, 0, 2, 0, 0, 0 },
{ "LIST", IRC_LIST, CLIENT_USER|CLIENT_SERVER, 0, 2, 0, 0, 0 },
{ "LUSERS", IRC_LUSERS, CLIENT_USER|CLIENT_SERVER, 0, 2, 0, 0, 0 },
{ "METADATA", IRC_METADATA, CLIENT_SERVER, 3, 3, 0, 0, 0 },
{ "MODE", IRC_MODE, CLIENT_USER|CLIENT_SERVER, 1, -1, 0, 0, 0 },
{ "MOTD", IRC_MOTD, CLIENT_USER|CLIENT_SERVER, 0, 1, 0, 0, 0 },
{ "NAMES", IRC_NAMES, CLIENT_USER|CLIENT_SERVER, 0, 2, 0, 0, 0 },
{ "NICK", IRC_NICK, CLIENT_ANY, 0, -1, 0, 0, 0 },
{ "NJOIN", IRC_NJOIN, CLIENT_SERVER, 2, 2, 0, 0, 0 },
{ "NOTICE", IRC_NOTICE, CLIENT_ANY, 0, -1, 0, 0, 0 },
{ "OPER", IRC_OPER, CLIENT_USER, 2, 2, 0, 0, 0 },
{ "PART", IRC_PART, CLIENT_USER|CLIENT_SERVER, 1, 2, 0, 0, 0 },
{ "PASS", IRC_PASS, CLIENT_ANY, 0, -1, 0, 0, 0 },
{ "PING", IRC_PING, CLIENT_USER|CLIENT_SERVER, 0, -1, 0, 0, 0 },
{ "PONG", IRC_PONG, CLIENT_ANY, 0, -1, 0, 0, 0 },
{ "PRIVMSG", IRC_PRIVMSG, CLIENT_USER|CLIENT_SERVER, 0, 2, 0, 0, 0 },
{ "QUIT", IRC_QUIT, CLIENT_ANY, 0, 1, 0, 0, 0 },
{ "REHASH", IRC_REHASH, CLIENT_USER, 0, 0, 0, 0, 0 },
{ "RESTART", IRC_RESTART, CLIENT_USER, 0, 0, 0, 0, 0 },
{ "SERVER", IRC_SERVER, CLIENT_ANY, 0, -1, 0, 0, 0 },
{ "SERVICE", IRC_SERVICE, CLIENT_ANY, 6, 6, 0, 0, 0 },
{ "SERVLIST", IRC_SERVLIST, CLIENT_USER, 0, 2, 0, 0, 0 },
{ "SQUERY", IRC_SQUERY, CLIENT_USER|CLIENT_SERVER, 0, 2, 0, 0, 0 },
{ "SQUIT", IRC_SQUIT, CLIENT_USER|CLIENT_SERVER, 2, 2, 0, 0, 0 },
{ "STATS", IRC_STATS, CLIENT_USER|CLIENT_SERVER, 0, 2, 0, 0, 0 },
{ "SVSNICK", IRC_SVSNICK, CLIENT_SERVER, 2, 2, 0, 0, 0 },
{ "SUMMON", IRC_SUMMON, CLIENT_USER|CLIENT_SERVER, 0, -1, 0, 0, 0 },
{ "TIME", IRC_TIME, CLIENT_USER|CLIENT_SERVER, 0, 1, 0, 0, 0 },
{ "TOPIC", IRC_TOPIC, CLIENT_USER|CLIENT_SERVER, 1, 2, 0, 0, 0 },
{ "TRACE", IRC_TRACE, CLIENT_USER|CLIENT_SERVER, 0, 1, 0, 0, 0 },
{ "USER", IRC_USER, CLIENT_ANY, 0, -1, 0, 0, 0 },
{ "USERHOST", IRC_USERHOST, CLIENT_USER, 1, -1, 0, 0, 0 },
{ "USERS", IRC_USERS, CLIENT_USER|CLIENT_SERVER, 0, -1, 0, 0, 0 },
{ "VERSION", IRC_VERSION, CLIENT_USER|CLIENT_SERVER, 0, 1, 0, 0, 0 },
{ "WALLOPS", IRC_WALLOPS, CLIENT_USER|CLIENT_SERVER, 1, 1, 0, 0, 0 },
{ "WEBIRC", IRC_WEBIRC, CLIENT_UNKNOWN, 4, 4, 0, 0, 0 },
{ "WHO", IRC_WHO, CLIENT_USER, 0, 2, 0, 0, 0 },
{ "WHOIS", IRC_WHOIS, CLIENT_USER|CLIENT_SERVER, 0, -1, 0, 0, 0 },
{ "WHOWAS", IRC_WHOWAS, CLIENT_USER|CLIENT_SERVER, 0, -1, 0, 0, 0 },
{ "ADMIN", IRC_ADMIN, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
{ "AWAY", IRC_AWAY, CLIENT_USER, 0, 0, 0 },
{ "CAP", IRC_CAP, 0xFFFF, 0, 0, 0 },
{ "CONNECT", IRC_CONNECT, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
{ "DIE", IRC_DIE, CLIENT_USER, 0, 0, 0 },
{ "DISCONNECT", IRC_DISCONNECT, CLIENT_USER, 0, 0, 0 },
{ "ERROR", IRC_ERROR, 0xFFFF, 0, 0, 0 },
{ "GLINE", IRC_xLINE, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
{ "HELP", IRC_HELP, CLIENT_USER, 0, 0, 0 },
{ "INFO", IRC_INFO, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
{ "INVITE", IRC_INVITE, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
{ "ISON", IRC_ISON, CLIENT_USER, 0, 0, 0 },
{ "JOIN", IRC_JOIN, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
{ "KICK", IRC_KICK, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
{ "KILL", IRC_KILL, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
{ "KLINE", IRC_xLINE, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
{ "LINKS", IRC_LINKS, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
{ "LIST", IRC_LIST, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
{ "LUSERS", IRC_LUSERS, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
{ "METADATA", IRC_METADATA, CLIENT_SERVER, 0, 0, 0 },
{ "MODE", IRC_MODE, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
{ "MOTD", IRC_MOTD, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
{ "NAMES", IRC_NAMES, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
{ "NICK", IRC_NICK, 0xFFFF, 0, 0, 0 },
{ "NJOIN", IRC_NJOIN, CLIENT_SERVER, 0, 0, 0 },
{ "NOTICE", IRC_NOTICE, 0xFFFF, 0, 0, 0 },
{ "OPER", IRC_OPER, CLIENT_USER, 0, 0, 0 },
{ "PART", IRC_PART, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
{ "PASS", IRC_PASS, 0xFFFF, 0, 0, 0 },
{ "PING", IRC_PING, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
{ "PONG", IRC_PONG, 0xFFFF, 0, 0, 0 },
{ "PRIVMSG", IRC_PRIVMSG, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
{ "QUIT", IRC_QUIT, 0xFFFF, 0, 0, 0 },
{ "REHASH", IRC_REHASH, CLIENT_USER, 0, 0, 0 },
{ "RESTART", IRC_RESTART, CLIENT_USER, 0, 0, 0 },
{ "SERVER", IRC_SERVER, 0xFFFF, 0, 0, 0 },
{ "SERVICE", IRC_SERVICE, 0xFFFF, 0, 0, 0 },
{ "SERVLIST", IRC_SERVLIST, CLIENT_USER, 0, 0, 0 },
{ "SQUERY", IRC_SQUERY, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
{ "SQUIT", IRC_SQUIT, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
{ "STATS", IRC_STATS, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
{ "SVSNICK", IRC_SVSNICK, CLIENT_SERVER, 0, 0, 0 },
{ "SUMMON", IRC_SUMMON, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
{ "TIME", IRC_TIME, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
{ "TOPIC", IRC_TOPIC, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
{ "TRACE", IRC_TRACE, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
{ "USER", IRC_USER, 0xFFFF, 0, 0, 0 },
{ "USERHOST", IRC_USERHOST, CLIENT_USER, 0, 0, 0 },
{ "USERS", IRC_USERS, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
{ "VERSION", IRC_VERSION, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
{ "WALLOPS", IRC_WALLOPS, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
{ "WEBIRC", IRC_WEBIRC, CLIENT_UNKNOWN, 0, 0, 0 },
{ "WHO", IRC_WHO, CLIENT_USER, 0, 0, 0 },
{ "WHOIS", IRC_WHOIS, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
{ "WHOWAS", IRC_WHOWAS, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
#ifdef IRCPLUS
{ "CHANINFO", IRC_CHANINFO, CLIENT_SERVER, 0, -1, 0, 0, 0 },
{ "CHANINFO", IRC_CHANINFO, CLIENT_SERVER, 0, 0, 0 },
# ifdef ICONV
{ "CHARCONV", IRC_CHARCONV, CLIENT_USER, 1, 1, 0, 0, 0 },
{ "CHARCONV", IRC_CHARCONV, CLIENT_USER, 0, 0, 0 },
# endif
#endif
#ifndef STRICT_RFC
{ "GET", IRC_QUIT_HTTP, CLIENT_UNKNOWN, 0, -1, 0, 0, 0 },
{ "POST", IRC_QUIT_HTTP, CLIENT_UNKNOWN, 0, -1, 0, 0, 0 },
{ "GET", IRC_QUIT_HTTP, CLIENT_UNKNOWN, 0, 0, 0 },
{ "POST", IRC_QUIT_HTTP, CLIENT_UNKNOWN, 0, 0, 0 },
#endif
{ NULL, NULL, 0x0, 0, 0, 0, 0, 0 } /* End-Mark */
{ NULL, NULL, 0x0, 0, 0, 0 } /* Ende-Marke */
};
static void Init_Request PARAMS(( REQUEST *Req ));
@@ -161,7 +157,7 @@ Parse_GetCommandStruct( void )
* Parse a command ("request") received from a client.
*
* This function is called after the connection layer received a valid CR+LF
* terminated line of text: we assume that this is a valid IRC command and
* terminated line of text: we asume that this is a valid IRC command and
* try to do something useful with it :-)
*
* All errors are reported to the client from which the command has been
@@ -173,7 +169,7 @@ Parse_GetCommandStruct( void )
* @param Idx Index of the connection from which the command has been received.
* @param Request NULL terminated line of text (the "command").
* @return true on success (valid command or "regular" error), false if a
* fatal error occurred and the connection has been shut down.
* fatal error occured and the connection has been shut down.
*/
GLOBAL bool
Parse_Request( CONN_ID Idx, char *Request )
@@ -275,6 +271,8 @@ Parse_Request( CONN_ID Idx, char *Request )
static void
Init_Request( REQUEST *Req )
{
/* Neue Request-Struktur initialisieren */
int i;
assert( Req != NULL );
@@ -325,38 +323,36 @@ Validate_Prefix( CONN_ID Idx, REQUEST *Req, bool *Closed )
}
/* check if client in prefix is known */
c = Client_Search(Req->prefix);
c = Client_Search( Req->prefix );
if (!c) {
if (Client_Type(client) != CLIENT_SERVER) {
Log(LOG_ERR,
"Ignoring command with invalid prefix \"%s\" from \"%s\" (connection %d, command \"%s\")!",
Req->prefix, Client_ID(client), Idx, Req->command);
if (!Conn_WriteStr(Idx,
"ERROR :Invalid prefix \"%s\"",
Req->prefix))
*Closed = true;
IRC_SetPenalty(client, 2);
} else
LogDebug("Ignoring command with invalid prefix \"%s\" from \"%s\" (connection %d, command \"%s\")!",
Req->prefix, Client_ID(client), Idx, Req->command);
Log(LOG_ERR,
"Invalid prefix \"%s\", client not known (connection %d, command \"%s\")!?",
Req->prefix, Idx, Req->command);
if (!Conn_WriteStr(Idx,
"ERROR :Invalid prefix \"%s\", client not known",
Req->prefix))
*Closed = true;
return false;
}
/* check if the client named in the prefix is expected
* to come from that direction */
if (Client_NextHop(c) != client) {
if (Client_Type(client) != CLIENT_SERVER) {
if (Client_Type(c) != CLIENT_SERVER) {
Log(LOG_ERR,
"Spoofed prefix \"%s\" from \"%s\" (connection %d, command \"%s\"), closing connection!",
Req->prefix, Client_ID(client), Idx, Req->command);
"Spoofed prefix \"%s\" from \"%s\" (connection %d, command \"%s\")!",
Req->prefix, Client_Mask(Conn_GetClient(Idx)), Idx,
Req->command);
Conn_Close(Idx, NULL, "Spoofed prefix", true);
*Closed = true;
} else {
Log(LOG_WARNING,
"Ignoring command with spoofed prefix \"%s\" from \"%s\" (connection %d, command \"%s\")!",
Req->prefix, Client_ID(client), Idx, Req->command);
Log(LOG_INFO,
"Ignoring spoofed prefix \"%s\" from \"%s\" (connection %d, command \"%s\").",
Req->prefix, Client_Mask(Conn_GetClient(Idx)), Idx,
Req->command);
}
return false;
}
return true;
@@ -371,7 +367,7 @@ Validate_Command( UNUSED CONN_ID Idx, UNUSED REQUEST *Req, bool *Closed )
*Closed = false;
return true;
} /* Validate_Command */
} /* Validate_Comman */
static bool
@@ -423,7 +419,7 @@ Handle_Numeric(CLIENT *client, REQUEST *Req)
{ 376, IRC_Num_ENDOFMOTD }
};
int i, num;
char str[COMMAND_LEN];
char str[LINE_LEN];
CLIENT *prefix, *target = NULL;
/* Determine target */
@@ -521,22 +517,15 @@ Handle_Request( CONN_ID Idx, REQUEST *Req )
if (!(client_type & cmd->type)) {
if (client_type == CLIENT_USER
&& cmd->type & CLIENT_SERVER)
return IRC_WriteErrClient(client,
return IRC_WriteStrClient(client,
ERR_NOTREGISTEREDSERVER_MSG,
Client_ID(client));
else
return IRC_WriteErrClient(client,
return IRC_WriteStrClient(client,
ERR_NOTREGISTERED_MSG,
Client_ID(client));
}
if (Req->argc < cmd->min_argc ||
(cmd->max_argc != -1 && Req->argc > cmd->max_argc)) {
IRC_SetPenalty(client, 2);
return IRC_WriteStrClient(client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(client), Req->command);
}
/* Command is allowed for this client: call it and count
* generated bytes in output */
Conn_ResetWCounter();
@@ -562,10 +551,11 @@ Handle_Request( CONN_ID Idx, REQUEST *Req )
Req->argc == 1 ? "parameter" : "parameters",
Req->prefix ? "" : " no" );
if (Client_Type(client) != CLIENT_SERVER)
result = IRC_WriteErrClient(client, ERR_UNKNOWNCOMMAND_MSG,
if (Client_Type(client) != CLIENT_SERVER) {
result = IRC_WriteStrClient(client, ERR_UNKNOWNCOMMAND_MSG,
Client_ID(client), Req->command);
Conn_SetPenalty(Idx, 1);
}
return result;
} /* Handle_Request */

View File

@@ -35,8 +35,6 @@ typedef struct _COMMAND
bool (*function) PARAMS(( CLIENT *Client, REQUEST *Request ));
/**< Function to handle this command */
CLIENT_TYPE type; /**< Valid client types (bit mask) */
int min_argc; /**< Min parameters */
int max_argc; /**< Max parameters */
long lcount, rcount; /**< Number of local and remote calls */
long bytes; /**< Number of bytes created */
} COMMAND;

View File

@@ -50,9 +50,7 @@ GLOBAL pid_t
Proc_Fork(PROC_STAT *proc, int *pipefds, void (*cbfunc)(int, short), int timeout)
{
pid_t pid;
#ifndef HAVE_ARC4RANDOM
unsigned int seed;
#endif
assert(proc != NULL);
assert(pipefds != NULL);
@@ -64,9 +62,7 @@ Proc_Fork(PROC_STAT *proc, int *pipefds, void (*cbfunc)(int, short), int timeout
return -1;
}
#ifndef HAVE_ARC4RANDOM
seed = (unsigned int)rand();
#endif
pid = fork();
switch (pid) {
case -1:
@@ -77,12 +73,7 @@ Proc_Fork(PROC_STAT *proc, int *pipefds, void (*cbfunc)(int, short), int timeout
return -1;
case 0:
/* New child process: */
#ifdef HAVE_ARC4RANDOM_STIR
arc4random_stir();
#endif
#ifndef HAVE_ARC4RANDOM
srand(seed ^ (unsigned int)time(NULL) ^ getpid());
#endif
Signals_Exit();
signal(SIGTERM, Proc_GenericSignalHandler);
signal(SIGALRM, Proc_GenericSignalHandler);

View File

@@ -242,7 +242,7 @@ ForwardLookup(const char *hostname, array *IpAddr, int af)
{
ng_ipaddr_t addr;
#ifdef HAVE_WORKING_GETADDRINFO
#ifdef HAVE_GETADDRINFO
int res;
struct addrinfo *a, *ai_results;
static struct addrinfo hints;

View File

@@ -1,6 +1,5 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2013 Alexander Barton (alex@barton.de) and Contributors.
*
* 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
@@ -41,6 +40,7 @@ static const int signals_catch[] = {
SIGINT, SIGQUIT, SIGTERM, SIGHUP, SIGCHLD, SIGUSR1, SIGUSR2
};
#ifdef DEBUG
static void
@@ -57,6 +57,7 @@ Dump_State(void)
#endif
static void
Signal_Block(int sig)
{
@@ -72,6 +73,7 @@ Signal_Block(int sig)
#endif
}
static void
Signal_Unblock(int sig)
{
@@ -88,6 +90,7 @@ Signal_Unblock(int sig)
#endif
}
/**
* Reload the server configuration file.
*/
@@ -114,21 +117,18 @@ Rehash(void)
* be changed during run-time */
if (strcmp(old_name, Conf_ServerName) != 0 ) {
strlcpy(Conf_ServerName, old_name, sizeof Conf_ServerName);
Log(LOG_ERR,
"Can't change \"ServerName\" on runtime! Ignored new name.");
Log(LOG_ERR, "Can't change \"ServerName\" on runtime! Ignored new name.");
}
if (old_nicklen != Conf_MaxNickLength) {
Conf_MaxNickLength = old_nicklen;
Log(LOG_ERR,
"Can't change \"MaxNickLength\" on runtime! Ignored new value.");
Log(LOG_ERR, "Can't change \"MaxNickLength\" on runtime! Ignored new value.");
}
/* Create new pre-defined channels */
Channel_InitPredefined( );
if (!ConnSSL_InitLibrary())
Log(LOG_WARNING,
"Re-Initializing of SSL failed, using old keys!");
Log(LOG_WARNING, "Re-Initializing SSL failed, using old keys");
/* Start listening on sockets */
Conn_InitListeners( );
@@ -139,6 +139,7 @@ Rehash(void)
Log( LOG_NOTICE|LOG_snotice, "Re-reading of configuration done." );
} /* Rehash */
/**
* Signal handler of ngIRCd.
* This function is called whenever ngIRCd catches a signal sent by the
@@ -197,6 +198,7 @@ Signal_Handler(int Signal)
Signal_Block(Signal);
} /* Signal_Handler */
/**
* Signal processing handler of ngIRCd.
* This function is called from the main conn event loop in (io_dispatch)
@@ -229,6 +231,7 @@ Signal_Handler_BH(int Signal)
Signal_Unblock(Signal);
}
static void
Signal_Callback(int fd, short UNUSED what)
{
@@ -245,19 +248,19 @@ Signal_Callback(int fd, short UNUSED what)
if (errno == EAGAIN || errno == EINTR)
return;
Log(LOG_EMERG, "Read from signal pipe: %s - Exiting!",
strerror(errno));
Log(LOG_EMERG, "read from signal pipe: %s", strerror(errno));
exit(1);
}
Log(LOG_EMERG, "EOF on signal pipe!? - Exiting!");
Log(LOG_EMERG, "EOF on signal pipe");
exit(1);
}
/**
* Initialize the signal handlers, catch
* those signals we are interested in and sets SIGPIPE to be ignored.
* @return true if initialization was successful.
* @return true if initialization was sucessful.
*/
bool
Signals_Init(void)
@@ -303,8 +306,9 @@ Signals_Init(void)
return io_event_create(signalpipe[0], IO_WANTREAD, Signal_Callback);
} /* Signals_Init */
/**
* Restores signals to their default behavior.
* Restores signals to their default behaviour.
*
* This should be called after a fork() in the new
* child prodcess, especially when we are about to call

View File

@@ -15,7 +15,7 @@ EXTRA_DIST = Makefile.ng
noinst_LIBRARIES = libngportab.a
libngportab_a_SOURCES = strdup.c strndup.c strlcpy.c strtok_r.c vsnprintf.c waitpid.c
libngportab_a_SOURCES = strdup.c strlcpy.c strtok_r.c vsnprintf.c waitpid.c
check_PROGRAMS = portabtest

View File

@@ -157,10 +157,6 @@ extern size_t strlcpy PARAMS(( char *dst, const char *src, size_t size ));
extern char * strdup PARAMS(( const char *s ));
#endif
#ifndef HAVE_STRNDUP
extern char * strndup PARAMS((const char *s, size_t maxlen));
#endif
#ifndef HAVE_STRTOK_R
extern char * strtok_r PARAMS((char *str, const char *delim, char **saveptr));
#endif

View File

@@ -24,8 +24,6 @@
#include "exp.h"
int allow_severity = 0, deny_severity = 0;
static void Panic PARAMS (( char *Reason, int Code ));

View File

@@ -1,37 +0,0 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
*/
#include "portab.h"
/**
* @file
* strndup() implementation. Public domain.
*/
#ifndef HAVE_STRNDUP
#include "imp.h"
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include "exp.h"
GLOBAL char *
strndup(const char *s, size_t maxlen)
{
char *dup;
size_t len = strlen(s);
if (len > maxlen)
len = maxlen;
len++;
dup = malloc(len);
if (dup)
strlcpy(dup, s, len);
return dup;
}
#endif

View File

@@ -109,16 +109,15 @@ void dummy_snprintf PARAMS(( void )) { }
#define LLONG long
#endif
static size_t dopr PARAMS((char *buffer, size_t maxlen, const char *format,
va_list args));
static void fmtstr PARAMS((char *buffer, size_t *currlen, size_t maxlen,
char *value, int flags, int min, int max));
static void fmtint PARAMS((char *buffer, size_t *currlen, size_t maxlen,
long value, int base, int min, int max, int flags));
static void fmtfp PARAMS((char *buffer, size_t *currlen, size_t maxlen,
LDOUBLE fvalue, int min, int max, int flags));
static void dopr_outch PARAMS((char *buffer, size_t *currlen, size_t maxlen,
char c));
static size_t dopr(char *buffer, size_t maxlen, const char *format,
va_list args);
static void fmtstr(char *buffer, size_t *currlen, size_t maxlen,
char *value, int flags, int min, int max);
static void fmtint(char *buffer, size_t *currlen, size_t maxlen,
long value, int base, int min, int max, int flags);
static void fmtfp(char *buffer, size_t *currlen, size_t maxlen,
LDOUBLE fvalue, int min, int max, int flags);
static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c);
/*
* dopr(): poor man's version of doprintf
@@ -154,8 +153,7 @@ static void dopr_outch PARAMS((char *buffer, size_t *currlen, size_t maxlen,
#define MAX(p,q) (((p) >= (q)) ? (p) : (q))
#endif
static size_t
dopr(char *buffer, size_t maxlen, const char *format, va_list args)
static size_t dopr(char *buffer, size_t maxlen, const char *format, va_list args)
{
char ch;
LLONG value;
@@ -412,9 +410,8 @@ dopr(char *buffer, size_t maxlen, const char *format, va_list args)
return currlen;
}
static void
fmtstr(char *buffer, size_t *currlen, size_t maxlen, char *value, int flags,
int min, int max)
static void fmtstr(char *buffer, size_t *currlen, size_t maxlen,
char *value, int flags, int min, int max)
{
int padlen, strln; /* amount to pad */
int cnt = 0;
@@ -451,9 +448,8 @@ fmtstr(char *buffer, size_t *currlen, size_t maxlen, char *value, int flags,
/* Have to handle DP_F_NUM (ie 0x and 0 alternates) */
static void
fmtint(char *buffer, size_t *currlen, size_t maxlen, long value, int base,
int min, int max, int flags)
static void fmtint(char *buffer, size_t *currlen, size_t maxlen,
long value, int base, int min, int max, int flags)
{
int signvalue = 0;
unsigned long uvalue;
@@ -536,8 +532,7 @@ fmtint(char *buffer, size_t *currlen, size_t maxlen, long value, int base,
}
}
static LDOUBLE
abs_val(LDOUBLE value)
static LDOUBLE abs_val(LDOUBLE value)
{
LDOUBLE result = value;
@@ -547,8 +542,7 @@ abs_val(LDOUBLE value)
return result;
}
static LDOUBLE
POW10(int exp)
static LDOUBLE POW10(int exp)
{
LDOUBLE result = 1;
@@ -560,8 +554,7 @@ POW10(int exp)
return result;
}
static LLONG
ROUND(LDOUBLE value)
static LLONG ROUND(LDOUBLE value)
{
LLONG intpart;
@@ -574,8 +567,7 @@ ROUND(LDOUBLE value)
/* a replacement for modf that doesn't need the math library. Should
be portable, but slow */
static double
my_modf(double x0, double *iptr)
static double my_modf(double x0, double *iptr)
{
int i;
long l;
@@ -609,9 +601,8 @@ my_modf(double x0, double *iptr)
}
static void
fmtfp (char *buffer, size_t *currlen, size_t maxlen, LDOUBLE fvalue,
int min, int max, int flags)
static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
LDOUBLE fvalue, int min, int max, int flags)
{
int signvalue = 0;
double ufvalue;
@@ -764,8 +755,7 @@ fmtfp (char *buffer, size_t *currlen, size_t maxlen, LDOUBLE fvalue,
}
}
static void
dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c)
static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c)
{
if (*currlen < maxlen) {
buffer[(*currlen)] = c;
@@ -774,25 +764,14 @@ dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c)
}
#if !defined(HAVE_VSNPRINTF)
int
vsnprintf (char *str, size_t count, const char *fmt, va_list args)
int vsnprintf (char *str, size_t count, const char *fmt, va_list args)
{
return dopr(str, count, fmt, args);
}
#endif
#if !defined(HAVE_SNPRINTF)
#ifdef PROTOTYPES
int
snprintf(char *str, size_t count, const char *fmt, ...)
#else
int
snprintf(str, count, fmt, va_alist)
char *str;
size_t count;
const char *fmt;
va_dcl
#endif
int snprintf(char *str,size_t count,const char *fmt,...)
{
size_t ret;
va_list ap;

View File

@@ -97,4 +97,3 @@ server-link-test.e
stress-A.e
stress-B.e
who-test.e
whois-test.e

View File

@@ -1,11 +1,10 @@
#!/bin/sh
# ngIRCd Test Suite
# $Id: getpid.sh,v 1.5 2006/08/05 00:15:28 alex Exp $
# did we get a name?
[ $# -ne 1 ] && exit 1
[ -x /bin/pidof ] && exec /bin/pidof -s $@
# detect flags for "ps" and "head"
UNAME=`uname`
if [ $UNAME = "FreeBSD" ]; then

View File

@@ -16,7 +16,6 @@
[Options]
OperCanUseMode = yes
Ident = no
IncludeDir = /var/empty
PAM = no
[Operator]

View File

@@ -16,7 +16,6 @@
[Options]
OperCanUseMode = yes
Ident = no
IncludeDir = /var/empty
PAM = no
[Operator]

View File

@@ -144,16 +144,11 @@ ngt_RandomStr(char *String, const size_t len)
assert(String != NULL);
gettimeofday(&t, NULL);
#ifndef HAVE_ARC4RANDOM
srand((unsigned)(t.tv_usec * t.tv_sec));
for (i = 0; i < len; ++i) {
String[i] = chars[rand() % (sizeof(chars) - 1)];
}
#else
for (i = 0; i < len; ++i)
String[i] = chars[arc4random() % (sizeof(chars) - 1)];
#endif
String[len] = '\0';
return String;