.gitignore | 6 +- AUTHORS | 5 +- ChangeLog | 117 ++- INSTALL | 74 +- Makefile.am | 28 +- NEWS | 79 ++- README | 5 +- configure.in | 85 +-- contrib/Anope/0001-Revert-Removed-ngircd.patch | 496 ++++++++ contrib/Anope/0002-ngircd-whitespace-fixes.patch | 60 + contrib/Anope/Makefile.am | 20 + contrib/Anope/README | 36 + contrib/Debian/changelog | 18 + contrib/MacOSX/config.h | 10 - contrib/MacOSX/ngIRCd.pmdoc/01ngircd-contents.xml | 2 +- contrib/MacOSX/ngIRCd.pmdoc/01ngircd.xml | 2 +- contrib/MacOSX/ngIRCd.pmdoc/02de-contents.xml | 2 +- contrib/MacOSX/ngIRCd.pmdoc/02de.xml | 2 +- contrib/MacOSX/ngIRCd.pmdoc/index.xml | 92 ++- contrib/MacOSX/ngIRCd.xcodeproj/project.pbxproj | 14 +- contrib/Makefile.am | 6 +- contrib/README | 8 +- contrib/ngIRCd-Logo.gif | Bin 0 -> 1975 bytes contrib/ngircd.spec | 2 +- contrib/platformtest.sh | 4 +- doc/Contributing.txt | 54 + doc/GIT.txt | 13 +- doc/Makefile.am | 2 +- doc/Platforms.txt | 36 +- doc/Protocol.txt | 24 +- doc/SSL.txt | 6 +- doc/Services.txt | 39 +- doc/Zeroconf.txt | 40 - doc/sample-ngircd.conf.tmpl | 215 ++-- doc/src/Doxyfile | 61 +- doc/src/Makefile.am | 4 +- doc/src/header.inc.html | 10 - doc/src/ngircd-doc.css | 77 -- man/ngircd.8.tmpl | 31 +- man/ngircd.conf.5.tmpl | 420 ++++--- src/ipaddr/ng_ipaddr.c | 7 +- src/ipaddr/ng_ipaddr.h | 7 +- src/ngircd/Makefile.am | 4 +- src/ngircd/array.c | 51 +- src/ngircd/array.h | 7 +- src/ngircd/channel.c | 84 ++- src/ngircd/channel.h | 13 +- src/ngircd/client.c | 49 +- src/ngircd/client.h | 12 +- src/ngircd/conf-ssl.h | 6 +- src/ngircd/conf.c | 1319 ++++++++++++++------- src/ngircd/conf.h | 177 ++-- src/ngircd/conn-func.c | 8 +- src/ngircd/conn-func.h | 7 +- src/ngircd/conn-ssl.c | 15 +- src/ngircd/conn-ssl.h | 6 +- src/ngircd/conn-zip.c | 13 +- src/ngircd/conn-zip.h | 11 +- src/ngircd/conn.c | 436 +++++--- src/ngircd/conn.h | 16 +- src/ngircd/defines.h | 16 +- src/ngircd/hash.c | 103 +- src/ngircd/hash.h | 12 +- src/ngircd/io.c | 7 +- src/ngircd/io.h | 9 +- src/ngircd/irc-channel.c | 206 +++- src/ngircd/irc-channel.h | 11 +- src/ngircd/irc-info.c | 254 +++-- src/ngircd/irc-info.h | 11 +- src/ngircd/irc-login.c | 256 ++++- src/ngircd/irc-login.h | 10 +- src/ngircd/irc-mode.c | 59 +- src/ngircd/irc-mode.h | 11 +- src/ngircd/irc-op.c | 8 +- src/ngircd/irc-op.h | 11 +- src/ngircd/irc-oper.c | 8 +- src/ngircd/irc-oper.h | 11 +- src/ngircd/irc-server.c | 15 +- src/ngircd/irc-server.h | 11 +- src/ngircd/irc-write.c | 8 +- src/ngircd/irc-write.h | 7 +- src/ngircd/irc.c | 8 +- src/ngircd/irc.h | 7 +- src/ngircd/lists.c | 10 +- src/ngircd/lists.h | 11 +- src/ngircd/log.c | 8 +- src/ngircd/log.h | 11 +- src/ngircd/match.c | 41 +- src/ngircd/match.h | 11 +- src/ngircd/messages.h | 10 +- src/ngircd/ngircd.c | 119 ++- src/ngircd/ngircd.h | 52 +- src/ngircd/numeric.c | 7 +- src/ngircd/numeric.h | 9 +- src/ngircd/op.c | 12 +- src/ngircd/op.h | 7 +- src/ngircd/pam.c | 7 +- src/ngircd/pam.h | 7 +- src/ngircd/parse.c | 98 ++- src/ngircd/parse.h | 34 +- src/ngircd/proc.c | 10 +- src/ngircd/proc.h | 16 +- src/ngircd/rendezvous.c | 372 ------ src/ngircd/rendezvous.h | 39 - src/ngircd/resolve.c | 40 +- src/ngircd/resolve.h | 7 +- src/ngircd/sighandlers.h | 7 + src/portab/exp.h | 9 +- src/portab/imp.h | 9 +- src/portab/portab.h | 7 +- src/portab/portabtest.c | 8 +- src/portab/splint.h | 18 +- src/portab/strdup.c | 13 +- src/portab/strlcpy.c | 13 +- src/portab/strtok_r.c | 13 +- src/portab/vsnprintf.c | 13 +- src/portab/waitpid.c | 12 +- src/testsuite/.gitignore | 1 + src/testsuite/Makefile.am | 9 +- src/testsuite/ngircd-test1.conf | 14 +- src/testsuite/ngircd-test2.conf | 10 +- src/testsuite/whois-test.e | 53 + src/tool/tool.c | 8 +- src/tool/tool.h | 10 +- 124 files changed, 4334 insertions(+), 2343 deletions(-) diff --git a/.gitignore b/.gitignore index 6a7ccc8..1990041 100644 --- a/.gitignore +++ b/.gitignore @@ -5,15 +5,17 @@ ansi2knr.1 ansi2knr.c ansi2knr.h autom4te.cache +build-stamp-ngircd* config.log config.status configure configure.lineno +cscope.out +debian depcomp install-sh missing +ngircd.dest .deps *.a *.o -debian -build-stamp-ngircd* diff --git a/AUTHORS b/AUTHORS index e0e1d07..03a19dd 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,9 +1,8 @@ ngIRCd - Next Generation IRC Server + http://ngircd.barton.de/ - (c)2001-2009 Alexander Barton, - alex@barton.de, http://www.barton.de/ - + (c)2001-2011 Alexander Barton and Contributors. ngIRCd is free software and published under the terms of the GNU General Public License. diff --git a/ChangeLog b/ChangeLog index 93206ef..ec4fc19 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,15 +1,124 @@ ngIRCd - Next Generation IRC Server + http://ngircd.barton.de/ - (c)2001-2010 Alexander Barton, - alex@barton.de, http://www.barton.de/ - + (c)2001-2011 Alexander Barton and Contributors. ngIRCd is free software and published under the terms of the GNU General Public License. -- ChangeLog -- +ngIRCd Release 18 (2011-07-10) + + - Update timestamp of ngircd(8) manual page. + - Add preliminary ngIRCd protocol module for Anope 1.9 to contrib/Anope/. + - Don't register WHOWAS information when "MorePrivacy" option is in effect. + + ngIRCd 18~rc2 (2011-06-29) + - Update documentation, fix some wording, and use a spellchecker :-) + - ngircd.conf.5: strip "SSL" prefix from variables in [SSL] section. + - ngircd.8: document debugging options. + - GnuTLS: use 1024 bits as minimum size of the DH prime. This enables + ngIRCd to accept incoming connections from other servers and clients + that "only" use at least 1024 bits again, like ngIRCd 17 did (and no + longer requires 2048 bits for incoming connections). + + ngIRCd 18~rc1 (2011-06-27) + - PAM warning message: make clear which "Password" config option is ignored. + - New configuration option "MorePrivacy" to "censor" some user information. + When enabled, signon time and idle time is left out. Part and quit + messages are made to look the same. WHOWAS requests are silently dropped. + All of this is useful if one wish to conceal users that access the ngircd + servers from TOR or I2P. + - New configuration option "ScrubCTCP" to scrub incoming CTCP commands. If + activated, the server silently drops incoming CTCP requests from both + other servers and from users. The server that scrubs CTCP will not forward + the CTCP requests to other servers in the network either, which can spell + trouble if not every oper knows about the CTCP-scrubbing. Scrubbing CTCP + commands also means that it is not possible to send files between users. + There is one exception to the CTCP scrubbing performed: ACTION ("/me + commands") requests are not scrubbed. + - Display configuration errors more prominent on "--configtest". + - Restructure ngIRCd configuration file: introduce new [Limits], [Options], + and [SSL] sections. The intention of this restructuring is to make the + [Global] section much cleaner, so that it only contains variables that + most installations must adjust to the local requirements. All the optional + variables are moved to [Limits], for configurable limits and timers of + ngIRCd, and [Options], for optional features. All SSL-related variables + are moved to [SSL] and the "SSL"-prefix is stripped. The old variables in + the [Global] section are deprecated now, but are still recognized. + => Don't forget to check your configuration, use "ngircd --configtest"! + - New documentation "how to contribute": doc/Contributing.txt. + - Slightly fix error handling when connecting to remote servers. + - GnuTLS: bump DH-bitsize to 2048: this solves the problem that some clients + refuse to connect to severs that only offer 1024. For interoperability it + would be best to just use 4096 bits, but that takes minutes, even on + current hardware ... + - contrib/platformtest.sh: fix gcc version detection. + - Avoid needlessly scary 'buffer overflow' messages: When the write buffer + space grows too large, ngIRCd has to disconnect the client to avoid + wasting too much memory, which is logged with a scary 'write buffer + overflow' message. Change this to a more descriptive wording. + - Require server prefixes for most commands on RFC2812 links. RFC1459 links + (often used by services, for example) are not affected. + - Mac OS X: update installer functionality, texts, and add our logo :-) + - New configuration option "RequireAuthPing": PING-PONG on login. When + enabled, this configuration option lets ngIRCd send a PING with an numeric + "token" to clients logging in; and it will not become registered in the + network until the client responds with the correct PONG. + - New configuration option "NoticeAuth": send NOTICE AUTH on connect. When + active, ngircd will send "NOTICE AUTH" messages on client connect time + like e.g. snircd (QuakeNet) does. + - Generate WALLOPS message on SQUIT from IRC operators; so SQUIT now behaves + like CONNECT and DISCONNECT commands, when called by an IRC operator. + - Allow servers to send more commands in the first 10 seconds ("burst"). This + helps to speed up server login and network synchronization. + - Add support for up to 3 targets in WHOIS queries, also allow up to one + wildcard query from local hosts. Follows ircd 2.10 implementation rather + than RFC 2812. At most 10 entries are returned per wildcard expansion. + - ngircd.conf(5) manual page: describe types of configuration variables + (booleans, text strings, integer numbers) and add type information to each + variable description. + - Don't use "the.net" in sample-ngircd.conf, use "example.net". + - Terminate incoming connections on HTTP commands "GET" and "POST". + - New configuration option "CloakHost": when set, this hostname is used for + every client instead of the real DNS hostname (or IP address). + - New configuration option "CloakUserToNick": when enabled, ngIRCd sets + every clients' user name to their nick name and hides the user name + supplied by the IRC client. + - doc/Protocol.txt: Update description of the CHANINFO and WEBIRC commands. + - Doxygen'ify (document) much more source files; code cleanup ... + - Make write buffers bigger, but flush early. Before this change, a client + got disconnected if the buffer flushing at 4k failed, now regular clients + can store up to 32k and servers up 64k even if flushing is not possible at + the moment. This enhances reliability on slow links. + - Don't access possibly free'd CLIENT structure. Ooops. + - Allow "Port = 0" in [Server] blocks. Port number 0 marks remote servers + that try to connect to this daemon, but where this daemon never tries to + establish a connection on its own: only incoming connections are allowed. + - Configuration: fix 'Value of "..." is not a number!' for negative values. + - Enable WHOIS command to return information about services. + - Implement channel mode 'O': "IRC operators only". This channel mode is + used on DALnet (bahamut), for example. + - Remove support for ZeroConf/Bonjour/Rendezvous service registration + including the "[No]ZeroConf" configuration option. + - TOPIC command: test for channel admin rights correctly: this enables other + servers, services and IRC operators to change channel topics, even when + the client is not joined to this channel. + - Deprecate NoXX-Options in ngircd.conf and move new variants into our new + [Options] section: 'NoDNS=no' => 'DNS=yes', 'NoIdent=no' => 'Ident=yes', + 'NoPAM=no' => 'PAM=yes', and 'NoZeroConf=no' => 'ZeroConf=yes' (and + vice-versa). The defaults are adjusted accordingly and the old variables + in [Global] are still accepted, so there is no functional change. + - Fix confusing "adding to invite list" debug messages: adding entries to + ban list produced 'invite list' debug output ... + - Don't throttle services and servers being registered. + - Xcode: correctly sort files :-) + - Don't assert() when searching a client for an invalid server token (this is + only relevant when a trusted server on a server-server link sends invalid + commands). + ngIRCd Release 17.1 (2010-12-19) - --configtest: remember if MOTD is configured by file or phrase @@ -17,7 +126,7 @@ ngIRCd Release 17.1 (2010-12-19) - Reset ID of outgoing server link on DNS error correctly - Don't log critical (or worse) messages to stderr - Manual page ngircd(8): add SIGNALS section - - Manual pages: update and simplyfy AUTHORS section + - Manual pages: update and simplify AUTHORS section - Remove "error file" when compiled with debug code enabled - README: Updated list of implemented commands - add doc/README-Interix.txt and doc/Bopm.txt to distribution tarball diff --git a/INSTALL b/INSTALL index f7e51a1..99fe33d 100644 --- a/INSTALL +++ b/INSTALL @@ -1,9 +1,8 @@ ngIRCd - Next Generation IRC Server + http://ngircd.barton.de/ - (c)2001-2010 Alexander Barton, - alex@barton.de, http://www.barton.de/ - + (c)2001-2011 Alexander Barton and Contributors. ngIRCd is free software and published under the terms of the GNU General Public License. @@ -13,6 +12,43 @@ I. Upgrade Information ~~~~~~~~~~~~~~~~~~~~~~ +Differences to version 17 + +- Support for ZeroConf/Bonjour/Rendezvous service registration has been + removed. The configuration option "NoZeroconf" is no longer available. + +- The structure of ngircd.conf has been cleaned up and three new configuration + sections have been introduced: [Limits], [Options], and [SSL]. + Lots of configuration variables stored in the [Global] section are now + deprecated there and should be stored in one of these new sections (but + still work in [Global]): + "AllowRemoteOper" -> [Options] + "ChrootDir" -> [Options] + "ConnectIPv4" -> [Options] + "ConnectIPv6" -> [Options] + "ConnectRetry" -> [Limits] + "MaxConnections" -> [Limits] + "MaxConnectionsIP" -> [Limits] + "MaxJoins" -> [Limits] + "MaxNickLength" -> [Limits] + "NoDNS" -> [Options], and renamed to "DNS" + "NoIdent" -> [Options], and renamed to "Ident" + "NoPAM" -> [Options], and renamed to "PAM" + "OperCanUseMode" -> [Options] + "OperServerMode" -> [Options] + "PingTimeout" -> [Limits] + "PongTimeout" -> [Limits] + "PredefChannelsOnly" -> [Options] + "SSLCertFile" -> [SSL], and renamed to "CertFile" + "SSLDHFile" -> [SSL], and renamed to "DHFile" + "SSLKeyFile" -> [SSL], and renamed to "KeyFile" + "SSLKeyFilePassword" -> [SSL], and renamed to "KeyFilePassword" + "SSLPorts" -> [SSL], and renamed to "Ports" + "SyslogFacility" -> [Options] + "WebircPassword" -> [Options] + You should adjust your ngircd.conf and run "ngircd --configtest" to make + sure that your settings are correct and up to date! + Differences to version 16 - Changes to the "MotdFile" specified in ngircd.conf now require a ngircd @@ -69,7 +105,8 @@ location, /usr/local/sbin/. The next step is to configure and afterwards starting the daemon. Please have a look at the ngircd(8) and ngircd.conf(5) manual pages for details -and all possible options. +and all possible options -- and don't forget to run "ngircd --configtest" +to validate your configuration file! If no previous version of the configuration file exists (the standard name is /usr/local/etc/ngircd.conf), a sample configuration file containing all @@ -97,7 +134,7 @@ Again: "end users" do not need this step! The configure-script is used to detect local system dependencies. -In the perfect case, configure should recognise all needed libraries, header +In the perfect case, configure should recognize all needed libraries, header files and so on. If this shouldn't work, "./configure --help" shows all possible options. @@ -124,11 +161,12 @@ the local system. Normally, root privileges are necessary to complete this step. If there is already an older configuration file present, it won't be overwritten. -This files will be installed by default: +These files and folders will be installed by default: - /usr/local/sbin/ngircd: executable server - /usr/local/etc/ngircd.conf: sample configuration (if not already present) - /usr/local/share/doc/ngircd/: documentation +- /usr/local/share/man/: manual pages III. Additional features @@ -174,13 +212,6 @@ standard locations. Include support for IDENT ("AUTH") lookups. The "ident" library is required for this option. -* ZeroConf Support: - --with-zeroconf[=] - - Compile ngIRCd with support for ZeroConf multicast DNS service registration. - Either the Apple ZeroConf implementation (e. g. Mac OS X) or the Howl - library is required. Which one is available is autodetected. - * TCP-Wrappers: --with-tcp-wrappers[=] @@ -229,19 +260,20 @@ V. Sample configuration file ngircd.conf In the sample configuration file, there are comments beginning with "#" OR ";" -- this is only for the better understanding of the file. -The file is separated in four blocks: [Global], [Operator], [Server], and -[Channel]. +The file is separated in five blocks: [Global], [Features], [Operator], +[Server], and [Channel]. In the [Global] section, there is the main configuration like the server -name and the ports, on which the server should be listening. IRC operators -of this server are defined in [Operator] blocks. [Server] is the section -where server links are configured. And [Channel] blocks are used to -configure pre-defined ("persistent") IRC channels. +name and the ports, on which the server should be listening. Options in +the [Features] section enable or disable functionality in the daemon. +IRC operators of this server are defined in [Operator] blocks, remote +servers are configured in [Server] sections, and [Channel] blocks are +used to configure pre-defined ("persistent") IRC channels. The meaning of the variables in the configuration file is explained in the "doc/sample-ngircd.conf", which is used as sample configuration file in /usr/local/etc after running "make install" (if you don't already have one) -and in the "ngircd.conf" manual page. +and in the ngircd.conf(5) manual page. VI. Command line options @@ -266,3 +298,5 @@ These parameters could be passed to the ngIRCd: Use "--help" to see a short help text describing all available parameters the server understands, with "--version" the ngIRCd shows its version number. In both cases the server exits after the output. + +Please see the ngircd(8) manual page for complete details! diff --git a/Makefile.am b/Makefile.am index e1d8d60..58f202c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,6 +1,6 @@ # # ngIRCd -- The Next Generation IRC Daemon -# Copyright (c)2001-2010 Alexander Barton (alex@barton.de) +# 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 @@ -37,6 +37,10 @@ have-xcodebuild: >/dev/null 2>&1 \ || ( echo; echo "Error: \"xcodebuild\" not found!"; echo; exit 1 ) +have-packagemaker: + @packagemaker >/dev/null 2>&1; [ $$? -le 1 ] \ + || ( echo; echo "Error: \"packagemaker\" not found!"; echo; exit 2) + xcode: have-xcodebuild rel=`git describe|sed -e 's/rel-//g'|sed -e 's/-/~/'`; \ def="GCC_PREPROCESSOR_DEFINITIONS=\"VERSION=\\\"$$rel\\\"\""; \ @@ -55,10 +59,15 @@ deb: [ -f debian/rules ] || ln -s contrib/Debian debian dpkg-buildpackage -rfakeroot -i -osxpkg: have-xcodebuild - @packagemaker >/dev/null 2>&1; [ $$? -le 1 ] \ - || ( echo; echo "Error: \"packagemaker\" not found!"; echo; exit 2) - make clean +osxpkg: have-packagemaker osxpkg-dest + cd contrib/MacOSX && packagemaker \ + --doc ngIRCd.pmdoc \ + --out ../../$(distdir).mpkg + rm -f $(distdir).mpkg.zip + zip -ro9 $(distdir).mpkg.zip $(distdir).mpkg + rm -rf ngircd.dest $(distdir).mpkg + +osxpkg-dest: have-xcodebuild clean ./configure --prefix=/opt/ngircd make xcode make -C contrib/MacOSX de.barton.ngircd.plist @@ -71,11 +80,8 @@ osxpkg: have-xcodebuild 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 - cd contrib/MacOSX && packagemaker \ - --doc ngIRCd.pmdoc \ - --out ../../$(distdir).mpkg - rm -f $(distdir).mpkg.zip - zip -ro9 $(distdir).mpkg.zip $(distdir).mpkg - rm -rf ngircd.dest $(distdir).mpkg + +.PHONY: deb have-packagemaker have-xcodebuild lint osxpkg osxpkg-dest rpm \ + srcdoc testsuite xcode xcode-clean # -eof- diff --git a/NEWS b/NEWS index 9524e8b..3602a4d 100644 --- a/NEWS +++ b/NEWS @@ -1,14 +1,87 @@ ngIRCd - Next Generation IRC Server + http://ngircd.barton.de/ - (c)2001-2010 Alexander Barton, - alex@barton.de, http://www.barton.de/ - + (c)2001-2011 Alexander Barton and Contributors. ngIRCd is free software and published under the terms of the GNU General Public License. -- NEWS -- +ngIRCd Release 18 (2011-07-10) + + - Add preliminary ngIRCd protocol module for Anope 1.9 to contrib/Anope/. + + ngIRCd 18~rc2 (2011-06-29) + - GnuTLS: use 1024 bits as minimum size of the DH prime. This enables + ngIRCd to accept incoming connections from other servers and clients + that "only" use at least 1024 bits again, like ngIRCd 17 did (and no + longer requires 2048 bits for incoming connections). + + ngIRCd 18~rc1 (2011-06-27) + - New configuration option "MorePrivacy" to "censor" some user information. + When enabled, signon time and idle time is left out. Part and quit + messages are made to look the same. WHOWAS requests are silently dropped. + All of this is useful if one wish to conceal users that access the ngircd + servers from TOR or I2P. + - New configuration option "ScrubCTCP" to scrub incoming CTCP commands. If + activated, the server silently drops incoming CTCP requests from both + other servers and from users. The server that scrubs CTCP will not forward + the CTCP requests to other servers in the network either, which can spell + trouble if not every oper knows about the CTCP-scrubbing. Scrubbing CTCP + commands also means that it is not possible to send files between users. + There is one exception to the CTCP scrubbing performed: ACTION ("/me + commands") requests are not scrubbed. + - Restructure ngIRCd configuration file: introduce new [Limits], [Options], + and [SSL] sections. The intention of this restructuring is to make the + [Global] section much cleaner, so that it only contains variables that + most installations must adjust to the local requirements. All the optional + variables are moved to [Limits], for configurable limits and timers of + ngIRCd, and [Options], for optional features. All SSL-related variables + are moved to [SSL] and the "SSL"-prefix is stripped. The old variables in + the [Global] section are deprecated now, but are still recognized. + => Don't forget to check your configuration, use "ngircd --configtest"! + - New documentation "how to contribute": doc/Contributing.txt. + - Avoid needlessly scary 'buffer overflow' messages: When the write buffer + space grows too large, ngIRCd has to disconnect the client to avoid + wasting too much memory, which is logged with a scary 'write buffer + overflow' message. Change this to a more descriptive wording. + - New configuration option "RequireAuthPing": PING-PONG on login. When + enabled, this configuration option lets ngIRCd send a PING with an numeric + "token" to clients logging in; and it will not become registered in the + network until the client responds with the correct PONG. + - New configuration option "NoticeAuth": send NOTICE AUTH on connect. When + active, ngircd will send "NOTICE AUTH" messages on client connect time + like e.g. snircd (QuakeNet) does. + - Add support for up to 3 targets in WHOIS queries, also allow up to one + wildcard query from local hosts. Follows ircd 2.10 implementation rather + than RFC 2812. At most 10 entries are returned per wildcard expansion. + - ngircd.conf(5) manual page: describe types of configuration variables + (booleans, text strings, integer numbers) and add type information to each + variable description. + - Terminate incoming connections on HTTP commands "GET" and "POST". + - New configuration option "CloakHost": when set, this hostname is used for + every client instead of the real DNS hostname (or IP address). + - New configuration option "CloakUserToNick": when enabled, ngIRCd sets + every clients' user name to their nick name and hides the user name + supplied by the IRC client. + - Make write buffers bigger, but flush early. Before this change, a client + got disconnected if the buffer flushing at 4k failed, now regular clients + can store up to 32k and servers up 64k even if flushing is not possible at + the moment. This enhances reliability on slow links. + - Allow "Port = 0" in [Server] blocks. Port number 0 marks remote servers + that try to connect to this daemon, but where this daemon never tries to + establish a connection on its own: only incoming connections are allowed. + - Enable WHOIS command to return information about services. + - Implement channel mode 'O': "IRC operators only". This channel mode is + used on DALnet (bahamut), for example. + - Remove support for ZeroConf/Bonjour/Rendezvous service registration + including the "[No]ZeroConf" configuration option. + - Deprecate NoXX-Options in ngircd.conf and move new variants into our new + [Options] section: 'NoDNS=no' => 'DNS=yes', 'NoIdent=no' => 'Ident=yes', + 'NoPAM=no' => 'PAM=yes', and 'NoZeroConf=no' => 'ZeroConf=yes' (and + vice-versa). The defaults are adjusted accordingly and the old variables + in [Global] are still accepted, so there is no functional change. ngIRCd Release 17.1 (2010-12-19) diff --git a/README b/README index 1feedfe..3c39cad 100644 --- a/README +++ b/README @@ -1,9 +1,8 @@ ngIRCd - Next Generation IRC Server + http://ngircd.barton.de/ - (c)2001-2007 Alexander Barton, - alex@barton.de, http://www.barton.de/ - + (c)2001-2011 Alexander Barton and Contributors. ngIRCd is free software and published under the terms of the GNU General Public License. diff --git a/configure.in b/configure.in index 1d66a22..e48e9e3 100644 --- a/configure.in +++ b/configure.in @@ -1,6 +1,6 @@ # # ngIRCd -- The Next Generation IRC Daemon -# Copyright (c)2001-2010 Alexander Barton +# 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 @@ -33,7 +33,6 @@ AH_TEMPLATE([ZLIB], [Define if zlib compression should be enabled]) AH_TEMPLATE([TCPWRAP], [Define if TCP wrappers should be used]) AH_TEMPLATE([IRCPLUS], [Define if IRC+ protocol should be used]) AH_TEMPLATE([WANT_IPV6], [Define if IPV6 protocol should be enabled]) -AH_TEMPLATE([ZEROCONF], [Define if support for Zeroconf should be included]) AH_TEMPLATE([IDENTAUTH], [Define if the server should do IDENT requests]) AH_TEMPLATE([PAM], [Define if PAM should be used]) AH_TEMPLATE([HAVE_sockaddr_in_len], [Define if sockaddr_in.sin_len exists]) @@ -163,7 +162,7 @@ AC_CHECK_FUNCS([ \ bind gethostbyaddr gethostbyname gethostname inet_ntoa \ setsid setsockopt socket strcasecmp waitpid],,AC_MSG_ERROR([required function missing!])) -AC_CHECK_FUNCS(getaddrinfo getnameinfo inet_aton isdigit sigaction sigprocmask snprintf \ +AC_CHECK_FUNCS(getaddrinfo getnameinfo inet_aton sigaction sigprocmask snprintf \ vsnprintf strdup strlcpy strlcat strtok_r) # -- Configuration options -- @@ -411,56 +410,6 @@ int deny_severity = 0; ] ) -# include support for "zeroconf"? - -x_zeroconf_on=no -AC_ARG_WITH(zeroconf, - [ --with-zeroconf enable support for "Zeroconf"], - [ if test "$withval" != "no"; then - if test "$withval" != "yes"; then - CFLAGS="-I$withval/include $CFLAGS" - CPPFLAGS="-I$withval/include $CPPFLAGS" - LDFLAGS="-L$withval/lib $LDFLAGS" - fi - AC_CHECK_FUNCS(DNSServiceRegistrationCreate, x_zeroconf_on=osx, - [ - AC_CHECK_LIB(pthread, pthread_mutexattr_init) - AC_CHECK_LIB(howl, sw_discovery_init) - AC_CHECK_FUNCS(sw_discovery_init, \ - x_zeroconf_on=howl, \ - AC_MSG_ERROR([Can't enable Zeroconf!])) - ]) - fi - ] -) -if test "$x_zeroconf_on" = "osx"; then - AC_CHECK_HEADERS([DNSServiceDiscovery/DNSServiceDiscovery.h \ - mach/port.h],,AC_MSG_ERROR([required C header missing!])) - AC_DEFINE(ZEROCONF, 1) -fi -if test "$x_zeroconf_on" = "howl"; then - for dir in /usr/local/include /usr/local/include/howl* \ - /usr/include /usr/include/howl* \ - /usr/local/include/avahi* /usr/include/avahi*; do - test -d "$dir" || continue - AC_MSG_CHECKING([for Howl headers in $dir]) - if test -f "$dir/rendezvous/rendezvous.h"; then - if test "$dir" != "/usr/local/include" -a \ - "$dir" != "/usr/include"; then - CFLAGS="-I$dir $CFLAGS" - CPPFLAGS="-I$dir $CPPFLAGS" - fi - AC_MSG_RESULT(yes) - break - else - AC_MSG_RESULT(no) - fi - done - AC_CHECK_HEADERS([rendezvous/rendezvous.h],, \ - AC_MSG_ERROR([required C header missing!])) - AC_DEFINE(ZEROCONF, 1) -fi - # do IDENT requests using libident? x_identauth_on=no @@ -595,6 +544,7 @@ AC_OUTPUT([ \ src/testsuite/Makefile \ man/Makefile \ contrib/Makefile \ + contrib/Anope/Makefile \ contrib/Debian/Makefile \ contrib/MacOSX/Makefile \ contrib/MacOSX/ngIRCd.xcodeproj/Makefile \ @@ -663,42 +613,29 @@ test "$x_strict_rfc_on" = "yes" \ && echo "yes" \ || echo "no" -echo $ECHO_N " Zeroconf support: $ECHO_C" -case "$x_zeroconf_on" in - osx) - echo $ECHO_N "Apple $ECHO_C" - ;; - howl) - echo $ECHO_N "Howl $ECHO_C" - ;; - *) - echo $ECHO_N "no $ECHO_C" - ;; -esac +echo $ECHO_N " IDENT support: $ECHO_C" +test "$x_identauth_on" = "yes" \ + && echo $ECHO_N "yes $ECHO_C" \ + || echo $ECHO_N "no $ECHO_C" echo $ECHO_N " IRC+ protocol: $ECHO_C" test "$x_ircplus_on" = "yes" \ && echo "yes" \ || echo "no" -echo $ECHO_N " IDENT support: $ECHO_C" -test "$x_identauth_on" = "yes" \ +echo $ECHO_N " IPv6 protocol: $ECHO_C" +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 $ECHO_N " IPv6 protocol: $ECHO_C" -test "$x_ipv6_on" = "yes" \ +echo $ECHO_N " PAM support: $ECHO_C" +test "$x_pam_on" = "yes" \ && echo $ECHO_N "yes $ECHO_C" \ || echo $ECHO_N "no $ECHO_C" echo $ECHO_N " SSL support: $ECHO_C" echo "$x_ssl_lib" -echo $ECHO_N " PAM support: $ECHO_C" -test "$x_pam_on" = "yes" \ - && echo "yes" \ - || echo "no" - echo # -eof- diff --git a/contrib/Anope/0001-Revert-Removed-ngircd.patch b/contrib/Anope/0001-Revert-Removed-ngircd.patch new file mode 100644 index 0000000..efed0ad --- /dev/null +++ b/contrib/Anope/0001-Revert-Removed-ngircd.patch @@ -0,0 +1,496 @@ +From bc5023fdba8091ab7eee29fe0deeca6843159743 Mon Sep 17 00:00:00 2001 +From: Alexander Barton +Date: Mon, 16 May 2011 18:23:01 +0200 +Subject: [PATCH 1/2] Revert "Removed ngircd as we've decided not to support it at this time" + +This reverts commit 605b5d57171d2f0fac56ee2ee3e1b1bbdadeb24f and re-enables +the ngIRCd protocol module for Anope. +--- + modules/protocol/ngircd.cpp | 475 +++++++++++++++++++++++++++++++++++++++++++ + 1 files changed, 475 insertions(+), 0 deletions(-) + create mode 100644 modules/protocol/ngircd.cpp + +diff --git a/modules/protocol/ngircd.cpp b/modules/protocol/ngircd.cpp +new file mode 100644 +index 0000000..6e1f21f +--- /dev/null ++++ b/modules/protocol/ngircd.cpp +@@ -0,0 +1,475 @@ ++/* ngIRCd IRCD functions ++ * ++ * (C) 2003-2011 Anope Team ++ * Contact us at team@anope.org ++ * ++ * Please read COPYING and README for further details. ++ * ++ * Based on the original code of Epona by Lara. ++ * Based on the original code of Services by Andy Church. ++ */ ++ ++#include "services.h" ++#include "modules.h" ++ ++IRCDVar myIrcd[] = { ++ {"ngIRCd", /* ircd name */ ++ "+oi", /* Modes used by pseudoclients */ ++ 0, /* SVSNICK */ ++ 0, /* Vhost */ ++ 0, /* Supports SNlines */ ++ 0, /* Supports SQlines */ ++ 0, /* Supports SZlines */ ++ 0, /* Join 2 Message */ ++ 0, /* Chan SQlines */ ++ 1, /* Quit on Kill */ ++ 0, /* vidents */ ++ 0, /* svshold */ ++ 0, /* time stamp on mode */ ++ 0, /* UMODE */ ++ 0, /* O:LINE */ ++ 0, /* No Knock requires +i */ ++ 0, /* Can remove User Channel Modes with SVSMODE */ ++ 0, /* Sglines are not enforced until user reconnects */ ++ 0, /* ts6 */ ++ "$", /* TLD Prefix for Global */ ++ 20, /* Max number of modes we can send per line */ ++ 0, /* IRCd sends a SSL users certificate fingerprint */ ++ } ++ , ++ {NULL} ++}; ++ ++/* PASS */ ++class ngIRCdProto : public IRCDProto ++{ ++ void SendAkill(User *u, const XLine *x) ++ { ++ if (SGLine && u == NULL) ++ for (Anope::insensitive_map::iterator it = UserListByNick.begin(); it != UserListByNick.end();) ++ { ++ u = it->second; ++ ++it; ++ if (SGLine->Check(u) != NULL) ++ break; ++ } ++ } ++ ++ void SendAkillDel(const XLine*) { } ++ ++ void SendGlobopsInternal(const BotInfo *source, const Anope::string &buf) ++ { ++ send_cmd(source ? source->nick : Config->ServerName, "WALLOPS :%s", buf.c_str()); ++ } ++ ++ void SendJoin(BotInfo *user, Channel *c, const ChannelStatus *status) ++ { ++ send_cmd(user->nick, "JOIN %s", c->name.c_str()); ++ if (status) ++ for (unsigned i = 0; i < ModeManager::ChannelModes.size(); ++i) ++ if (status->HasFlag(ModeManager::ChannelModes[i]->Name)) ++ c->SetMode(user, ModeManager::ChannelModes[i], user->nick, false); ++ } ++ ++ void SendSVSKillInternal(const BotInfo *source, const User *user, const Anope::string &buf) ++ { ++ send_cmd(source ? source->nick : Config->ServerName, "KILL %s :%s", user->nick.c_str(), buf.c_str()); ++ } ++ ++ /* SERVER name hop descript */ ++ void SendServer(const Server *server) ++ { ++ send_cmd("", "SERVER %s %d :%s", server->GetName().c_str(), server->GetHops(), server->GetDescription().c_str()); ++ } ++ ++ void SendConnect() ++ { ++ send_cmd("", "PASS %s 0210-IRC+ Anope|%s:CLHSo P", uplink_server->password.c_str(), Anope::VersionShort().c_str()); ++ /* Make myself known to myself in the serverlist */ ++ SendServer(Me); ++ /* finish the enhanced server handshake and register the connection */ ++ this->SendNumeric(Config->ServerName, 376, "*", ":End of MOTD command"); ++ } ++ ++ // Received: :dev.anope.de NICK DukeP 1 ~DukePyro p57ABF9C9.dip.t-dialin.net 1 +i :DukePyrolator ++ void SendClientIntroduction(const User *u, const Anope::string &modes) ++ { ++ EnforceQlinedNick(u->nick, ""); ++ send_cmd(Config->ServerName, "NICK %s 1 %s %s 1 %s :%s", u->nick.c_str(), u->GetIdent().c_str(), u->host.c_str(), modes.c_str(), u->realname.c_str()); ++ } ++ ++ void SendPartInternal(const BotInfo *bi, const Channel *chan, const Anope::string &buf) ++ { ++ if (!buf.empty()) ++ send_cmd(bi->nick, "PART %s :%s", chan->name.c_str(), buf.c_str()); ++ else ++ send_cmd(bi->nick, "PART %s", chan->name.c_str()); ++ } ++ ++ void SendModeInternal(const BotInfo *bi, const Channel *dest, const Anope::string &buf) ++ { ++ send_cmd(bi ? bi->nick : Config->ServerName, "MODE %s %s", dest->name.c_str(), buf.c_str()); ++ } ++ ++ void SendModeInternal(const BotInfo *bi, const User *u, const Anope::string &buf) ++ { ++ send_cmd(bi ? bi->nick : Config->ServerName, "MODE %s %s", u->nick.c_str(), buf.c_str()); ++ } ++ ++ void SendKickInternal(const BotInfo *bi, const Channel *chan, const User *user, const Anope::string &buf) ++ { ++ if (!buf.empty()) ++ send_cmd(bi->nick, "KICK %s %s :%s", chan->name.c_str(), user->nick.c_str(), buf.c_str()); ++ else ++ send_cmd(bi->nick, "KICK %s %s", chan->name.c_str(), user->nick.c_str()); ++ } ++ ++ void SendNoticeChanopsInternal(const BotInfo *source, const Channel *dest, const Anope::string &buf) ++ { ++ send_cmd(source ? source->nick : Config->s_ChanServ, "NOTICE @%s :%s", dest->name.c_str(), buf.c_str()); ++ } ++ ++ /* INVITE */ ++ void SendInvite(BotInfo *source, const Anope::string &chan, const Anope::string &nick) ++ { ++ send_cmd(source->nick, "INVITE %s %s", nick.c_str(), chan.c_str()); ++ } ++ ++ void SendChannel(Channel *c) ++ { ++ Anope::string mlock_modes = get_mlock_modes(c->ci, true); ++ if (mlock_modes.empty()) ++ mlock_modes = "+"; ++ send_cmd(Config->ServerName, "CHANINFO %s %s", c->name.c_str(), mlock_modes.c_str()); ++ } ++ void SendTopic(BotInfo *bi, Channel *c) ++ { ++ send_cmd(bi->nick, "TOPIC %s :%s", c->name.c_str(), c->topic.c_str()); ++ } ++}; ++ ++class ngIRCdIRCdMessage : public IRCdMessage ++{ ++ public: ++ bool OnSJoin(const Anope::string&, const std::vector&) { return false; } ++ ++ /* ++ * Received: :dev.anope.de MODE #anope +b *!*@*aol* ++ */ ++ bool OnMode(const Anope::string &source, const std::vector ¶ms) ++ { ++ if (params.size() < 2) ++ return true; ++ ++ Anope::string modes = params[1]; ++ for (unsigned i = 2; i < params.size(); ++i) ++ modes += " " + params[i]; ++ ++ if (params[0][0] == '#' || params[0][0] == '&') ++ do_cmode(source, params[0], modes, ""); ++ else ++ do_umode(params[0], params[1]); ++ ++ return true; ++ } ++ ++ /* ++ Received: :DukeP_ NICK :test2 ++ Received: :dev.anope.de NICK DukeP_ 1 ~DukePyro ip-2-201-236-154.web.vodafone.de 1 + :DukePyrolator ++ source = nickname on nickchange, servername on newuser ++ params[0] = nick ++ params[1] = ++ params[2] = username ++ params[3] = host ++ params[4] = ++ params[5] = modes ++ params[6] = info ++ */ ++ bool OnNick(const Anope::string &source, const std::vector ¶ms) ++ { ++ if (params.size() == 1) ++ { ++ // we have a nickchange ++ do_nick(source, params[0], "", "", "", "", Anope::CurTime, "", "", "", ""); ++ } ++ else if (params.size() == 7) ++ { ++ // a new user is connecting to the network ++ User *user = do_nick("", params[0], params[2], params[3], source, params[6], Anope::CurTime, "", "", "", params[5]); ++ if (user) ++ validate_user(user); ++ } ++ else ++ { ++ Log() << "Received NICK with invalid number of parameters. source = " << source << "param[0] = " << params[0] << "params.size() = " << params.size(); ++ } ++ return true; ++ } ++ ++ bool OnServer(const Anope::string &source, const std::vector ¶ms) ++ { ++ if (params.size() == 3) ++ do_server("", params[0], 0, params[2], params[1]); ++ else ++ do_server(source, params[0], params[1].is_pos_number_only() ? convertTo(params[1]) : 0, params[3], params[2]); ++ return true; ++ } ++ ++ bool OnTopic(const Anope::string &source, const std::vector ¶ms) ++ { ++ Channel *c = findchan(params[0]); ++ if (!c) ++ { ++ Log() << "TOPIC for nonexistant channel " << params[0]; ++ return true; ++ } ++ ++ c->ChangeTopicInternal(source, params[1]); ++ return true; ++ } ++ ++ /* ++ * <@po||ux> DukeP: RFC 2813, 4.2.1: the JOIN command on server-server links ++ * separates the modes ("o") with ASCII 7, not space. And you can't see ASCII 7. ++ * ++ * if a user joins a new channel, the ircd sends \7 ++ */ ++ bool OnJoin (const Anope::string &source, const std::vector ¶ms) ++ { ++ if (!params.empty()) ++ { ++ size_t pos = params[0].find('\7'); ++ if (pos != Anope::string::npos) ++ { ++ Anope::string channel = params[0].substr(0, pos); ++ Anope::string mode = '+' + params[0].substr(pos, params[0].length()) + " " + source; ++ do_join(source, channel, ""); ++ do_cmode(source, channel, mode, ""); ++ } ++ else ++ do_join(source, params[0], ""); ++ } ++ return true; ++ } ++}; ++ ++/* ++ * CHANINFO + ++ * CHANINFO + : ++ * CHANINFO + : ++ */ ++bool event_chaninfo(const Anope::string &source, const std::vector ¶ms) ++{ ++ ++ Channel *c = findchan(params[0]); ++ if (!c) ++ c = new Channel(params[0]); ++ ++ Anope::string modes = params[1]; ++ ++ if (params.size() == 3) ++ { ++ c->ChangeTopicInternal(source, params[2], Anope::CurTime); ++ } ++ else if (params.size() == 5) ++ { ++ for (size_t i = 0, end = params[1].length(); i < end; ++i) ++ { ++ switch(params[1][i]) ++ { ++ case 'k': ++ modes += " " + params[2]; ++ continue; ++ case 'l': ++ modes += " " + params[3]; ++ continue; ++ } ++ } ++ c->ChangeTopicInternal(source, params[4], Anope::CurTime); ++ } ++ ++ c->SetModesInternal(NULL, modes); ++ ++ return true; ++} ++ ++/* ++ * Received: :dev.anope.de NJOIN #test :DukeP2,@DukeP ++ */ ++bool event_njoin(const Anope::string &source, const std::vector ¶ms) ++{ ++ Channel *c = findchan(params[0]); ++ commasepstream sep(params[1]); ++ Anope::string buf; ++ ++ if (!c) ++ { ++ c = new Channel(params[0], Anope::CurTime); ++ c->SetFlag(CH_SYNCING); ++ } ++ ++ while (sep.GetToken(buf)) ++ { ++ std::list Status; ++ char ch; ++ ++ /* Get prefixes from the nick */ ++ while ((ch = ModeManager::GetStatusChar(buf[0]))) ++ { ++ buf.erase(buf.begin()); ++ ChannelMode *cm = ModeManager::FindChannelModeByChar(ch); ++ if (!cm) ++ { ++ Log() << "Received unknown mode prefix " << ch << " in NJOIN string."; ++ continue; ++ } ++ Status.push_back(cm); ++ } ++ User *u = finduser(buf); ++ if (!u) ++ { ++ Log(LOG_DEBUG) << "NJOIN for nonexistant user " << buf << " on " << c->name; ++ continue; ++ } ++ ++ EventReturn MOD_RESULT; ++ FOREACH_RESULT(I_OnPreJoinChannel, OnPreJoinChannel(u, c)); ++ ++ /* Add the user to the Channel */ ++ c->JoinUser(u); ++ ++ /* Update their status internally on the channel ++ * This will enforce secureops etc on the user ++ */ ++ for (std::list::iterator it = Status.begin(), it_end = Status.end(); it != it_end; ++it) ++ c->SetModeInternal(*it, buf); ++ /* Now set whatever modes this user is allowed to have on the channel */ ++ chan_set_correct_modes(u, c, 1); ++ ++ /* Check to see if modules want the user to join, if they do ++ * check to see if they are allowed to join (CheckKick will kick/ban them) ++ * Don't trigger OnJoinChannel event then as the user will be destroyed ++ */ ++ if (MOD_RESULT != EVENT_STOP && c->ci && c->ci->CheckKick(u)) ++ continue; ++ ++ FOREACH_MOD(I_OnJoinChannel, OnJoinChannel(u, c)); ++ } /* while */ ++ ++ if (c->HasFlag(CH_SYNCING)) ++ { ++ c->UnsetFlag(CH_SYNCING); ++ c->Sync(); ++ } ++ ++ return true; ++} ++ ++bool event_kick(const Anope::string &source, const std::vector ¶ms) ++{ ++ if (params.size() > 2) ++ do_kick(source, params[0], params[1], params[2]); ++ return true; ++} ++ ++bool event_pass(const Anope::string &source, const std::vector ¶ms) ++{ ++ return true; ++} ++ ++bool event_005(const Anope::string &source, const std::vector ¶ms) ++{ ++ size_t pos; ++ Anope::string name, data; ++ for (unsigned i = 0, end = params.size(); i < end; ++i) ++ { ++ pos = params[i].find('='); ++ if (pos != Anope::string::npos) ++ { ++ name = params[i].substr(0, pos); ++ data = params[i].substr(pos+1, params[i].length()); ++ if (name == "NICKLEN") ++ { ++ unsigned newlen = convertTo(data); ++ if (Config->NickLen != newlen) ++ { ++ Log() << "Config->NickLen changed from " << Config->NickLen << " to " << newlen; ++ Config->NickLen = newlen; ++ } ++ } ++ } ++ } ++ return true; ++} ++ ++bool event_442(const Anope::string &source, const std::vector ¶ms) ++{ ++ return true; ++} ++ ++bool event_376(const Anope::string &source, const std::vector ¶ms) ++{ ++ return true; ++} ++ ++ ++class ProtongIRCd : public Module ++{ ++ Message message_kick, message_pass, message_njoin, message_chaninfo, message_005, ++ message_442, message_376; ++ ++ ngIRCdProto ircd_proto; ++ ngIRCdIRCdMessage ircd_message; ++ ++ void AddModes() ++ { ++ /* Add user modes */ ++ ModeManager::AddUserMode(new UserMode(UMODE_ADMIN, 'a')); ++ ModeManager::AddUserMode(new UserMode(UMODE_INVIS, 'i')); ++ ModeManager::AddUserMode(new UserMode(UMODE_OPER, 'o')); ++ ModeManager::AddUserMode(new UserMode(UMODE_RESTRICTED, 'r')); ++ ModeManager::AddUserMode(new UserMode(UMODE_SNOMASK, 's')); ++ ModeManager::AddUserMode(new UserMode(UMODE_WALLOPS, 'w')); ++ ModeManager::AddUserMode(new UserMode(UMODE_CLOAK, 'x')); ++ ++ /* b/e/I */ ++ ModeManager::AddChannelMode(new ChannelModeBan(CMODE_BAN, 'b')); ++ ModeManager::AddChannelMode(new ChannelModeList(CMODE_INVITEOVERRIDE, 'I')); ++ ++ /* v/h/o/a/q */ ++ ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_VOICE, 'v', '+')); ++ ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OP, 'o', '@')); ++ ++ /* Add channel modes */ ++ // channel modes: biIklmnoPstvz ++ ModeManager::AddChannelMode(new ChannelMode(CMODE_INVITE, 'i')); ++ ModeManager::AddChannelMode(new ChannelModeKey('k')); ++ ModeManager::AddChannelMode(new ChannelModeParam(CMODE_LIMIT, 'l')); ++ ModeManager::AddChannelMode(new ChannelMode(CMODE_MODERATED, 'm')); ++ ModeManager::AddChannelMode(new ChannelMode(CMODE_NOEXTERNAL, 'n')); ++ ModeManager::AddChannelMode(new ChannelMode(CMODE_PERM, 'P')); ++ ModeManager::AddChannelMode(new ChannelMode(CMODE_SECRET, 's')); ++ ModeManager::AddChannelMode(new ChannelMode(CMODE_TOPIC, 't')); ++ ModeManager::AddChannelMode(new ChannelMode(CMODE_SSL, 'z')); ++ } ++ ++ public: ++ ProtongIRCd(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator), ++ message_kick("KICK", event_kick), message_pass("PASS", event_pass), ++ message_njoin("NJOIN", event_njoin), message_chaninfo("CHANINFO", event_chaninfo), ++ message_005("005", event_005), message_442("442", event_442), message_376("376", event_376) ++ { ++ this->SetAuthor("Anope"); ++ this->SetType(PROTOCOL); ++ ++ Capab.SetFlag(CAPAB_QS); ++ ++ pmodule_ircd_var(myIrcd); ++ pmodule_ircd_proto(&this->ircd_proto); ++ pmodule_ircd_message(&this->ircd_message); ++ ++ this->AddModes(); ++ } ++}; ++ ++MODULE_INIT(ProtongIRCd) +-- +1.7.2.5 + diff --git a/contrib/Anope/0002-ngircd-whitespace-fixes.patch b/contrib/Anope/0002-ngircd-whitespace-fixes.patch new file mode 100644 index 0000000..60356a8 --- /dev/null +++ b/contrib/Anope/0002-ngircd-whitespace-fixes.patch @@ -0,0 +1,60 @@ +From 1ea1dd2095e63cef34edbebb729edc687f410a96 Mon Sep 17 00:00:00 2001 +From: Alexander Barton +Date: Mon, 16 May 2011 18:26:56 +0200 +Subject: [PATCH 2/2] ngircd: whitespace fixes + +--- + modules/protocol/ngircd.cpp | 12 ++++++------ + 1 files changed, 6 insertions(+), 6 deletions(-) + +diff --git a/modules/protocol/ngircd.cpp b/modules/protocol/ngircd.cpp +index 6e1f21f..e546d05 100644 +--- a/modules/protocol/ngircd.cpp ++++ b/modules/protocol/ngircd.cpp +@@ -266,11 +266,11 @@ bool event_chaninfo(const Anope::string &source, const std::vectorChangeTopicInternal(source, params[2], Anope::CurTime); +- } ++ } + else if (params.size() == 5) + { + for (size_t i = 0, end = params[1].length(); i < end; ++i) +@@ -307,7 +307,7 @@ bool event_njoin(const Anope::string &source, const std::vector & + c = new Channel(params[0], Anope::CurTime); + c->SetFlag(CH_SYNCING); + } +- ++ + while (sep.GetToken(buf)) + { + std::list Status; +@@ -415,9 +415,9 @@ bool event_376(const Anope::string &source, const std::vector &pa + + class ProtongIRCd : public Module + { +- Message message_kick, message_pass, message_njoin, message_chaninfo, message_005, ++ Message message_kick, message_pass, message_njoin, message_chaninfo, message_005, + message_442, message_376; +- ++ + ngIRCdProto ircd_proto; + ngIRCdIRCdMessage ircd_message; + +@@ -461,7 +461,7 @@ class ProtongIRCd : public Module + { + this->SetAuthor("Anope"); + this->SetType(PROTOCOL); +- ++ + Capab.SetFlag(CAPAB_QS); + + pmodule_ircd_var(myIrcd); +-- +1.7.2.5 + diff --git a/contrib/Anope/Makefile.am b/contrib/Anope/Makefile.am new file mode 100644 index 0000000..7670384 --- /dev/null +++ b/contrib/Anope/Makefile.am @@ -0,0 +1,20 @@ +# +# ngIRCd -- The Next Generation IRC Daemon +# 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 +# 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. +# + +EXTRA_DIST = \ + README \ + 0001-Revert-Removed-ngircd.patch \ + 0002-ngircd-whitespace-fixes.patch + +maintainer-clean-local: + rm -f Makefile Makefile.in + +# -eof- diff --git a/contrib/Anope/README b/contrib/Anope/README new file mode 100644 index 0000000..ea47b06 --- /dev/null +++ b/contrib/Anope/README @@ -0,0 +1,36 @@ + + ngIRCd - Next Generation IRC Server + http://ngircd.barton.de/ + + (c)2001-2011 Alexander Barton and Contributors. + ngIRCd is free software and published under the + terms of the GNU General Public License. + + -- contrib/Anope/README -- + + +This directory contains two preliminary patches that (re-) add a ngIRCd +protocol module to the Anope 1.9 development branch. It has been tested +with Anope 1.9.4, there is no guarantee that it will work with other +versions as Anope 1.9.x is under heavy development ... + +To build this Anope protocol module, you have to + + - Download the Anope 1.9.x sources (tested with 1.9.4), + - Patch in the ngIRCd protocol module, + - Build and install Anope as usual, + - Configure Anope as usual, use "ngircd" as protocol module. + +So the command sequence can be something like this: + + $ tar xzf anope-1.9.4-source.tar.gz + $ cd anope-1.9.4-source + $ patch -p1 < .../ngircd/contrib/Anope/0001-Revert-Removed-ngircd.patch + $ patch -p1 < .../ngircd/contrib/Anope/0002-ngircd-whitespace-fixes.patch + $ ./Config + $ cd build + $ make + $ make install + +Please have a look at the file doc/Services.txt for more information about +how to set up ngIRCd and Anope. diff --git a/contrib/Debian/changelog b/contrib/Debian/changelog index 06e9194..cf55e05 100644 --- a/contrib/Debian/changelog +++ b/contrib/Debian/changelog @@ -1,3 +1,21 @@ +ngircd (18-0ab1) unstable; urgency=low + + * New "upstream" release: ngIRCd 18. + + -- Alexander Barton Sun, 10 Jul 2011 20:03:20 +0200 + +ngircd (18~rc2-0ab1) unstable; urgency=low + + * New "upstream" release candidate 2 for ngIRCd Release 18. + + -- Alexander Barton Wed, 29 Jun 2011 10:20:51 +0200 + +ngircd (18~rc1-0ab1) unstable; urgency=low + + * New "upstream" release candidate 1 for ngIRCd Release 18. + + -- Alexander Barton Mon, 27 Jun 2011 22:58:36 +0200 + ngircd (17.1-0ab1) unstable; urgency=low * New "upstream" release: ngIRCd 17.1. diff --git a/contrib/MacOSX/config.h b/contrib/MacOSX/config.h index ba5e7e6..af0a34c 100644 --- a/contrib/MacOSX/config.h +++ b/contrib/MacOSX/config.h @@ -42,9 +42,6 @@ /* Define if TCP wrappers should be used */ /*#define TCPWRAP 1*/ -/* Define if support for Zeroconf should be included */ -/*#define ZEROCONF 1*/ - /* Define if zlib compression should be enabled */ #define ZLIB 1 @@ -103,13 +100,6 @@ /* Define if socklen_t exists */ #define HAVE_socklen_t 1 -#ifdef ZEROCONF -/* Define to 1 if you have the header file. */ -#define HAVE_DNSSERVICEDISCOVERY_DNSSERVICEDISCOVERY_H 1 -/* Define to 1 if you have the `DNSServiceRegistrationCreate' function. */ -#define HAVE_DNSSERVICEREGISTRATIONCREATE 1 -#endif - #ifdef PAM /* Define to 1 if you have the `pam_authenticate' function. */ #define HAVE_PAM_AUTHENTICATE 1 diff --git a/contrib/MacOSX/ngIRCd.pmdoc/01ngircd-contents.xml b/contrib/MacOSX/ngIRCd.pmdoc/01ngircd-contents.xml index bc1e5a7..45bd954 100644 --- a/contrib/MacOSX/ngIRCd.pmdoc/01ngircd-contents.xml +++ b/contrib/MacOSX/ngIRCd.pmdoc/01ngircd-contents.xml @@ -1 +1 @@ - \ No newline at end of file +groupownergroupownergroupownergroupownergroupownergroupownergroupownergroupownergroupownergroupownergroupownergroupownergroupownergroupownergroupownergroupownergroupownergroupownergroupownergroupownergroupownergroupownergroupownergroupownergroupownergroupownergroupownergroupownergroupownergroupownergroupownergroupownergroupownergroupownergroupowner \ No newline at end of file diff --git a/contrib/MacOSX/ngIRCd.pmdoc/01ngircd.xml b/contrib/MacOSX/ngIRCd.pmdoc/01ngircd.xml index 66dbd1f..99b3299 100644 --- a/contrib/MacOSX/ngIRCd.pmdoc/01ngircd.xml +++ b/contrib/MacOSX/ngIRCd.pmdoc/01ngircd.xml @@ -1 +1 @@ -de.barton.ngircd.daemon.pkg1../../ngircd.dest/parentscripts.postinstall.pathscripts.postinstall.isRelativeTypescripts.preupgrade.pathinstallFrom.isRelativeTypeversionscripts.preinstall.isRelativeTypeidentifierinstallTopreinstall.shpreinstall.sh \ No newline at end of file +de.barton.ngircd.daemon.pkg17.1/Users/alex/Develop/ngircd/alex.git/ngircd.dest/extraFilesinstallToinstallTo.isAbsoluteTypescripts.preinstall.pathidentifierparentversioninstallTo.pathscripts.preupgrade.pathrequireAuthorization02ngircd-contents.xml/CVS$/\.svn$/\.cvsignore$/\.cvspass$/\.DS_Store$ \ No newline at end of file diff --git a/contrib/MacOSX/ngIRCd.pmdoc/02de-contents.xml b/contrib/MacOSX/ngIRCd.pmdoc/02de-contents.xml index bc1e5a7..1c854e6 100644 --- a/contrib/MacOSX/ngIRCd.pmdoc/02de-contents.xml +++ b/contrib/MacOSX/ngIRCd.pmdoc/02de-contents.xml @@ -1 +1 @@ - \ No newline at end of file +groupowner \ No newline at end of file diff --git a/contrib/MacOSX/ngIRCd.pmdoc/02de.xml b/contrib/MacOSX/ngIRCd.pmdoc/02de.xml index 59b5202..600e53f 100644 --- a/contrib/MacOSX/ngIRCd.pmdoc/02de.xml +++ b/contrib/MacOSX/ngIRCd.pmdoc/02de.xml @@ -1 +1 @@ -de.barton.ngircd.launchscript.pkg1de.barton.ngircd.plist/Library/LaunchDaemonsparentscripts.postinstall.pathscripts.postupgrade.pathinstallFrom.isRelativeTypeinstallTo.pathinstallToidentifierpostinstall.shpostinstall.sh \ No newline at end of file +de.barton.ngircd.launchscript.pkg17.1de.barton.ngircd.plist/Library/LaunchDaemonsscripts.preinstall.pathinstallToscripts.postinstall.pathscripts.postinstall.isRelativeTypeinstallFrom.isRelativeTypeinstallTo.isAbsoluteTypeversionparentscripts.preupgrade.pathidentifierscripts.postupgrade.pathrequireAuthorizationextraFilesscripts.postupgrade.isRelativeTypeinstallTo.pathpreinstall.shpostinstall.shpreinstall.shpostinstall.sh01de-contents.xml/CVS$/\.svn$/\.cvsignore$/\.cvspass$/\.DS_Store$ \ No newline at end of file diff --git a/contrib/MacOSX/ngIRCd.pmdoc/index.xml b/contrib/MacOSX/ngIRCd.pmdoc/index.xml index 5d6b8e3..6eccddb 100644 --- a/contrib/MacOSX/ngIRCd.pmdoc/index.xml +++ b/contrib/MacOSX/ngIRCd.pmdoc/index.xml @@ -1,10 +1,11 @@ -ngIRCd/Users/alex/Desktop/ngIRCd.mpkgde.barton.ngircdngIRCd – next generation IRC (Internet Relay Chat) server daemon//Library/LaunchDaemonsngIRCd/Users/alex/Desktop/ngIRCd.mpkgde.barton.ngircdngIRCd – next generation Internet Relay Chat (IRC) server + daemon/Users/alex/Develop/ngircd/alex.git/contrib/ngIRCd-Logo.gif01ngircd.xml02de.xmlproperties.customizeOptionproperties.titledescriptionproperties.anywhereDomainproperties.systemDomain +\f1\fs26 \cf0 sudo launchctl unload -w \\\ + /Library/LaunchDaemons/de.barton.ngircd.plist\ +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural\pardirnatural + +\f0 \cf0 \ +But don\'92t forget to +\b adjust the configuration! +\b0 By default, it is stored in the following file:\ +\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural\pardirnatural + +\fs18 \cf0 \ +\pard\tx220\tx720\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\li720\fi-720\ql\qnatural\pardirnatural + +\f1\fs26 \cf0 /opt/ngircd/etc/ngircd.conf}]]>02de.xml01ngircd.xmlextraFilesproperties.titleproperties.customizeOptiondescriptionproperties.anywhereDomainproperties.systemDomain diff --git a/contrib/MacOSX/ngIRCd.xcodeproj/project.pbxproj b/contrib/MacOSX/ngIRCd.xcodeproj/project.pbxproj index 98437c1..2f9124e 100644 --- a/contrib/MacOSX/ngIRCd.xcodeproj/project.pbxproj +++ b/contrib/MacOSX/ngIRCd.xcodeproj/project.pbxproj @@ -32,7 +32,6 @@ FA322D490CEF74B1001761B3 /* match.c in Sources */ = {isa = PBXBuildFile; fileRef = FA322D030CEF74B1001761B3 /* match.c */; }; FA322D4A0CEF74B1001761B3 /* ngircd.c in Sources */ = {isa = PBXBuildFile; fileRef = FA322D060CEF74B1001761B3 /* ngircd.c */; }; FA322D4B0CEF74B1001761B3 /* parse.c in Sources */ = {isa = PBXBuildFile; fileRef = FA322D080CEF74B1001761B3 /* parse.c */; }; - FA322D4C0CEF74B1001761B3 /* rendezvous.c in Sources */ = {isa = PBXBuildFile; fileRef = FA322D0A0CEF74B1001761B3 /* rendezvous.c */; }; FA322D4D0CEF74B1001761B3 /* resolve.c in Sources */ = {isa = PBXBuildFile; fileRef = FA322D0C0CEF74B1001761B3 /* resolve.c */; }; FA322DBE0CEF7766001761B3 /* tool.c in Sources */ = {isa = PBXBuildFile; fileRef = FA322D330CEF74B1001761B3 /* tool.c */; }; FA322DC10CEF77CB001761B3 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = FA322DC00CEF77CB001761B3 /* libz.dylib */; }; @@ -113,8 +112,6 @@ FA322D070CEF74B1001761B3 /* ngircd.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = ngircd.h; sourceTree = ""; }; FA322D080CEF74B1001761B3 /* parse.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; path = parse.c; sourceTree = ""; }; FA322D090CEF74B1001761B3 /* parse.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = parse.h; sourceTree = ""; }; - FA322D0A0CEF74B1001761B3 /* rendezvous.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; path = rendezvous.c; sourceTree = ""; }; - FA322D0B0CEF74B1001761B3 /* rendezvous.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = rendezvous.h; sourceTree = ""; }; FA322D0C0CEF74B1001761B3 /* resolve.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; path = resolve.c; sourceTree = ""; }; FA322D0D0CEF74B1001761B3 /* resolve.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = resolve.h; sourceTree = ""; }; FA322D100CEF74B1001761B3 /* ansi2knr.1 */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.man; path = ansi2knr.1; sourceTree = ""; }; @@ -184,14 +181,12 @@ FA322D9E0CEF752C001761B3 /* README-AUX.txt */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = "README-AUX.txt"; sourceTree = ""; }; FA322D9F0CEF752C001761B3 /* README-BeOS.txt */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = "README-BeOS.txt"; sourceTree = ""; }; FA322DA00CEF752C001761B3 /* RFC.txt */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = RFC.txt; sourceTree = ""; }; - FA322DA10CEF752C001761B3 /* sample-ngircd.conf */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = "sample-ngircd.conf"; sourceTree = ""; }; FA322DA40CEF752C001761B3 /* Doxyfile */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = Doxyfile; sourceTree = ""; }; FA322DA50CEF752C001761B3 /* footer.inc.html */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.html; path = footer.inc.html; sourceTree = ""; }; FA322DA60CEF752C001761B3 /* header.inc.html */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.html; path = header.inc.html; sourceTree = ""; }; FA322DA70CEF752C001761B3 /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = Makefile.am; sourceTree = ""; }; FA322DA80CEF752C001761B3 /* ngircd-doc.css */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.css; path = "ngircd-doc.css"; sourceTree = ""; }; FA322DA90CEF752C001761B3 /* SSL.txt */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = SSL.txt; sourceTree = ""; }; - FA322DAA0CEF752C001761B3 /* Zeroconf.txt */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = Zeroconf.txt; sourceTree = ""; }; FA322DAD0CEF7538001761B3 /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = Makefile.am; sourceTree = ""; }; FA322DAE0CEF7538001761B3 /* ngircd.8.tmpl */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = ngircd.8.tmpl; sourceTree = ""; }; FA322DAF0CEF7538001761B3 /* ngircd.conf.5.tmpl */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = ngircd.conf.5.tmpl; sourceTree = ""; }; @@ -201,6 +196,7 @@ FA407F2C0DB159F400271AF1 /* ng_ipaddr.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = ng_ipaddr.c; path = ipaddr/ng_ipaddr.c; sourceTree = ""; }; FA407F2D0DB159F400271AF1 /* ng_ipaddr.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = ng_ipaddr.h; path = ipaddr/ng_ipaddr.h; sourceTree = ""; }; FA407F380DB15AC700271AF1 /* GIT.txt */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = GIT.txt; sourceTree = ""; }; + FA77849A133FB9FF00740057 /* sample-ngircd.conf.tmpl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "sample-ngircd.conf.tmpl"; sourceTree = ""; }; FA85178A0FA061EC006A1F5A /* op.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = op.h; sourceTree = ""; }; FA85178B0FA061EC006A1F5A /* op.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; path = op.c; sourceTree = ""; }; FA99428A10E82A27007F27ED /* proc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = proc.h; sourceTree = ""; }; @@ -348,14 +344,12 @@ FA322D070CEF74B1001761B3 /* ngircd.h */, FAE5CC2D0CF2308A007D69B6 /* numeric.c */, FAE5CC2C0CF2308A007D69B6 /* numeric.h */, - FA85178A0FA061EC006A1F5A /* op.h */, FA85178B0FA061EC006A1F5A /* op.c */, + FA85178A0FA061EC006A1F5A /* op.h */, FA322D080CEF74B1001761B3 /* parse.c */, FA322D090CEF74B1001761B3 /* parse.h */, FA99428B10E82A27007F27ED /* proc.c */, FA99428A10E82A27007F27ED /* proc.h */, - FA322D0A0CEF74B1001761B3 /* rendezvous.c */, - FA322D0B0CEF74B1001761B3 /* rendezvous.h */, FA322D0C0CEF74B1001761B3 /* resolve.c */, FA322D0D0CEF74B1001761B3 /* resolve.h */, FAA97C55124A271400D5BBA9 /* sighandlers.c */, @@ -567,10 +561,9 @@ FA322D9E0CEF752C001761B3 /* README-AUX.txt */, FA322D9F0CEF752C001761B3 /* README-BeOS.txt */, FA322DA00CEF752C001761B3 /* RFC.txt */, - FA322DA10CEF752C001761B3 /* sample-ngircd.conf */, + FA77849A133FB9FF00740057 /* sample-ngircd.conf.tmpl */, FA322DA20CEF752C001761B3 /* src */, FA322DA90CEF752C001761B3 /* SSL.txt */, - FA322DAA0CEF752C001761B3 /* Zeroconf.txt */, ); name = doc; path = ../../doc; @@ -701,7 +694,6 @@ FA322D490CEF74B1001761B3 /* match.c in Sources */, FA322D4A0CEF74B1001761B3 /* ngircd.c in Sources */, FA322D4B0CEF74B1001761B3 /* parse.c in Sources */, - FA322D4C0CEF74B1001761B3 /* rendezvous.c in Sources */, FA322D4D0CEF74B1001761B3 /* resolve.c in Sources */, FA322DBE0CEF7766001761B3 /* tool.c in Sources */, FAE5CC2E0CF2308A007D69B6 /* numeric.c in Sources */, diff --git a/contrib/Makefile.am b/contrib/Makefile.am index 10cbf78..36ba245 100644 --- a/contrib/Makefile.am +++ b/contrib/Makefile.am @@ -1,6 +1,6 @@ # # ngIRCd -- The Next Generation IRC Daemon -# Copyright (c)2001-2009 Alexander Barton (alex@barton.de) +# 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 @@ -9,10 +9,10 @@ # Please read the file COPYING, README and AUTHORS for more information. # -SUBDIRS = Debian MacOSX +SUBDIRS = Anope Debian MacOSX EXTRA_DIST = README ngircd.spec systrace.policy ngindent ngircd-bsd.sh \ - ngircd-redhat.init platformtest.sh + ngIRCd-Logo.gif ngircd-redhat.init platformtest.sh maintainer-clean-local: rm -f Makefile Makefile.in diff --git a/contrib/README b/contrib/README index 6593fdd..6097bae 100644 --- a/contrib/README +++ b/contrib/README @@ -1,15 +1,17 @@ ngIRCd - Next Generation IRC Server + http://ngircd.barton.de/ - (c)2001-2009 Alexander Barton, - alex@barton.de, http://www.barton.de/ - + (c)2001-2011 Alexander Barton and Contributors. ngIRCd is free software and published under the terms of the GNU General Public License. -- Contributions -- +Anope/ + - A preliminary patch that adds a ngIRCd protocol module to Anope 1.9. + Debian/ - Various files for building Debian GNU/Linux packages (".deb's"). diff --git a/contrib/ngIRCd-Logo.gif b/contrib/ngIRCd-Logo.gif new file mode 100644 index 0000000..9fc6d14 Binary files /dev/null and b/contrib/ngIRCd-Logo.gif differ diff --git a/contrib/ngircd.spec b/contrib/ngircd.spec index da0c2f7..ff6cdbd 100644 --- a/contrib/ngircd.spec +++ b/contrib/ngircd.spec @@ -1,5 +1,5 @@ %define name ngircd -%define version 17.1 +%define version 18 %define release 1 %define prefix %{_prefix} diff --git a/contrib/platformtest.sh b/contrib/platformtest.sh index 85d3a1d..6449a67 100755 --- a/contrib/platformtest.sh +++ b/contrib/platformtest.sh @@ -96,8 +96,8 @@ if [ -r "Makefile" ]; then CC=$(grep "^CC = " Makefile | cut -d' ' -f3) $CC --version 2>&1 | grep -i "GCC" >/dev/null if [ $? -eq 0 ]; then - COMPILER=$($CC --version | head -1 | awk "{ print \$3 }" \ - | cut -d'-' -f1) + COMPILER=$($CC --version | head -1 \ + | cut -d')' -f2 | cut -d' ' -f2) COMPILER="gcc $COMPILER" else case "$CC" in diff --git a/doc/Contributing.txt b/doc/Contributing.txt new file mode 100644 index 0000000..089afd4 --- /dev/null +++ b/doc/Contributing.txt @@ -0,0 +1,54 @@ + + ngIRCd - Next Generation IRC Server + http://ngircd.barton.de/ + + (c)2001-2011 Alexander Barton and Contributors. + ngIRCd is free software and published under the + terms of the GNU General Public License. + + -- Contributing.txt -- + + +If you want to contribute to ngIRCd, please read the following paragraphs to +get an idea of how to do it the best :-) + + - Use GIT + + The source code of ngIRCd is maintained using GIT, see doc/GIT.txt. So if + remotely possible, use GIT for your work, too. It makes your and our lifes + much easier ;-) + + - Don't forget to include documentation + + When adding features and new configuration options, don't forget to not + only code the features but to describe them in doc/sample-ngircd.conf, + man/ngircd.8.tmp and/or man/ngircd.conf.5.tmpl as well! + + - Be present on IRC + + If you intend to code some new features or do some code cleanups or better + documentation, please be present on and + discuss your plans early! So other developers have an idea on what others + are working on, can offer help, and can synchronize their own work. + + - Check and validate your work! + + Use "make check" to validate your work, and use "make distcheck" to + validate the resulting archives, especially when adding/removing files! + + - Send patches in "unified diff" format + + Please send patches in "unified" format, that is, use "diff -u". + Or even better: use GIT ("git diff"), see above. + + - Send patches to the mailing list + + If you have some code to present, send the patch(es) and/or pointers to + your GIT repository to the official ngIRCd mailing list for review, not + only to #ngircd: so it becomes archived and more people have a chance to + review your patch. + + Sure it is a good idea to post some notes to #ngircd, too! :-) + + And this is open source, your work must not be 100% finished and perfect, + work in progress is interesting, too: "release early, release often"! diff --git a/doc/GIT.txt b/doc/GIT.txt index c42696d..4375184 100644 --- a/doc/GIT.txt +++ b/doc/GIT.txt @@ -1,10 +1,18 @@ + ngIRCd - Next Generation IRC Server + http://ngircd.barton.de/ + + (c)2001-2011 Alexander Barton and Contributors. + ngIRCd is free software and published under the + terms of the GNU General Public License. -- GIT.txt -- + The source code of ngIRCd is maintained using git, the stupid content tracker. + I. Getting the source code ~~~~~~~~~~~~~~~~~~~~~~~~~~ To access the source tree anonymously, run: @@ -20,7 +28,8 @@ git commands will be executed from within this directory in the future. Please note: When checking out a fresh copy of ngIRCd using git, the configure script doesn't exist; you have to run the autogen.sh shell script (which is included in the source tree) to generate it. This requires you to -have GNU automake and GNU autoconf installed on your system. +have GNU automake and GNU autoconf installed on your system. Please see the +file INSTALL for details! To update the git tree: @@ -28,6 +37,7 @@ To update the git tree: This retrieves all changes and merges them into the current branch. + II. Contributing ~~~~~~~~~~~~~~~~ @@ -42,4 +52,3 @@ III. Write Access ~~~~~~~~~~~~~~~~~ If you want to contribute a couple of patches and write access to the git repository would be handy, please contact Alex Barton, . - diff --git a/doc/Makefile.am b/doc/Makefile.am index 6a8578f..92e5f8f 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -19,7 +19,7 @@ SUFFIXES = .tmpl static_docs = Bopm.txt FAQ.txt GIT.txt HowToRelease.txt PAM.txt Platforms.txt \ Protocol.txt README-AUX.txt README-BeOS.txt README-Interix.txt RFC.txt \ - SSL.txt Services.txt Zeroconf.txt + SSL.txt Services.txt doc_templates = sample-ngircd.conf.tmpl diff --git a/doc/Platforms.txt b/doc/Platforms.txt index c811c19..87cbfaf 100644 --- a/doc/Platforms.txt +++ b/doc/Platforms.txt @@ -1,9 +1,8 @@ ngIRCd - Next Generation IRC Server + http://ngircd.barton.de/ - (c)2001-2010 Alexander Barton - alex@barton.de, http://www.barton.de/ - + (c)2001-2011 Alexander Barton and Contributors. ngIRCd is free software and published under the terms of the GNU General Public License. @@ -32,21 +31,22 @@ 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.4.0 gcc 4.2.1 17 10-11-07 alex Y Y Y Y (3) +i386/apple/darwin10.7.0 gcc 4.2.1 18 11-07-05 alex Y Y Y Y (3) +i386/apple/darwin11.0.0 gcc 4.2.1 18 11-07-02 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 17 10-11-07 alex Y Y N Y (4) +i386/pc/solaris2.11 gcc 3.4.3 18 11-07-10 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 17 10-11-07 alex Y Y Y Y (3) -i386/unknown/freebsd7.3 gcc 4.2.1 17 10-11-07 alex Y Y Y Y (3) -i686/unknown/gnu0.3 gcc 4.4.5 17 10-11-07 alex Y Y Y Y +i386/unknown/freebsd6.2 gcc 3.4.6 18 11-07-10 alex Y Y Y Y (3) +i386/unknown/freebsd7.3 gcc 4.2.1 18 11-07-1ß alex Y Y Y Y (3) +i686/unknown/gnu0.3 gcc 4.4.5 18 11-07-10 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.1 gcc 2.95.3 CVSHEAD 04-02-24 alex Y Y Y 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 17 10-11-07 alex Y Y Y Y (3) -i386/unknown/netbsdelf5.0.2 gcc 4.1.3 17 10-11-07 alex Y Y Y Y (3) +i386/unknown/netbsdelf4.0 gcc 4.1.2 18 11-07-10 alex Y Y Y Y (3) +i386/unknown/netbsdelf5.0.2 gcc 4.1.3 18 11-07-10 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/interix3.5 gcc 3.3 15 10-01-22 alex Y Y N Y +i586/pc/interix3.5 gcc 3.3 18 11-07-10 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.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) @@ -54,20 +54,22 @@ 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 Orig. A/UX 0.7.x-CVS 03-04-22 alex Y Y Y Y (2) +m68k/apple/aux3.1.1 gcc 2.7.2 18 11-07-02 alex Y Y N Y +m68k/apple/aux3.1.1 Orig. A/UX 18 11-07-02 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) 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 CVSHEAD 06-05-07 fw Y Y Y Y (3) -powerpc/apple/darwin8.1.0 gcc 4.0 0.9.x-CVS 05-06-27 alex Y Y Y Y +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/unknown/freebsd8.1 gcc 4.2.1 17 10-11-07 alex Y Y Y Y (3) -x86_64/unknown/linux-gnu gcc 4.3.2 17 10-11-07 alex Y Y Y Y (1) -x86_64/unknown/openbsd4.7 gcc 3.3.5 17 10-11-07 alex Y Y Y Y (3) +x86_64/unknown/freebsd8.1 gcc 4.2.1 18 11-07-10 alex Y Y Y Y (3) +x86_64/unknown/linux-gnu gcc 4.4.5 18 11-07-02 alex Y Y Y Y (1) +x86_64/unknown/openbsd4.7 gcc 3.3.5 18 11-07-10 alex Y Y Y Y (3) Notes diff --git a/doc/Protocol.txt b/doc/Protocol.txt index 354b814..5093eea 100644 --- a/doc/Protocol.txt +++ b/doc/Protocol.txt @@ -141,11 +141,17 @@ therefore to disconnect the peer prior to registering it in the network. II.3 Exchange channel-modes, topics, and persistent channels Command: CHANINFO - Parameters: + [] + Parameters: + [[ ] ] Used by: servers only CHANINFO is used by servers to inform each other about a channel: its -modes, channel key, user limits and its topic. is optional. +modes, channel key, user limits and its topic. The parameter combination + and is optional, as well as the parameter, so that +there are three possible forms of this command: + + CHANINFO + + CHANINFO + + CHANINFO + If the channel already exists on the server receiving the CHANINFO command, it only adopts the (or the ) if there are no modes (or topic) @@ -161,3 +167,17 @@ and therefore can't be omitted. The parameter must be ignored when a channel has no user limit (the parameter doesn't list the "l" channel mode). In this case should be "0". + +II.4 Update webchat/proxy client information + + Command: WEBIRC + Parameters: + Used by: unregistered clients only + +The WEBIRC command is used by some Web-to-IRC gateways 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 must be set in the server configuration file to prevent +unauthorized clients to fake their identity; it is an arbitrary string. + diff --git a/doc/SSL.txt b/doc/SSL.txt index 394894a..28ea2cd 100644 --- a/doc/SSL.txt +++ b/doc/SSL.txt @@ -34,7 +34,7 @@ possible to handle unencrypted and encrypted connections on the same port! This is a limitation of the IRC protocol ... You have to set (at least) the following configuration variables in the -[GLOBAL] section of ngircd.conf(5): SSLPorts, SSLKeyFile, and SSLCertFile. +[SSL] section of ngircd.conf(5): Ports, KeyFile, and CertFile. Now IRC clients are able to connect using SSL on the configured port(s). (Using port 6697 for encrypted connections is common.) @@ -51,7 +51,7 @@ OpenSSL: Creating a self-signed certificate and key: $ openssl req -newkey rsa:2048 -x509 -keyout server-key.pem -out server-cert.pem -days 1461 Create DH parameters (optional): - $ openssl dhparam -2 -out dhparams.pem 2048 + $ openssl dhparam -2 -out dhparams.pem 4096 GnuTLS: @@ -59,7 +59,7 @@ Creating a self-signed certificate and key: $ certtool --generate-privkey --bits 2048 --outfile server-key.pem $ certtool --generate-self-signed --load-privkey server-key.pem --outfile server-cert.pem Create DH parameters (optional): - $ certtool --generate-dh-params --bits 2048 --outfile dhparams.pem + $ certtool --generate-dh-params --bits 4096 --outfile dhparams.pem Alternate approach using stunnel(1) diff --git a/doc/Services.txt b/doc/Services.txt index 67053b1..c2059b2 100644 --- a/doc/Services.txt +++ b/doc/Services.txt @@ -1,9 +1,8 @@ ngIRCd - Next Generation IRC Server + http://ngircd.barton.de/ - (c)2001-2008 Alexander Barton, - alex@barton.de, http://www.barton.de/ - + (c)2001-2011 Alexander Barton and Contributors. ngIRCd is free software and published under the terms of the GNU General Public License. @@ -14,9 +13,11 @@ At the moment, ngIRCd doesn't implement a "special IRC services interface". But services acting as a "regular server" are supported, either using the IRC protocol defined in RFC 1459 or RFC 2812. -Services have been tested using "IRC Services" version 5.x by Andrew Church, -homepage: . This document describes setting up -ngIRCd and these services. +Support for Services has been tested using "IRC Services" version 5.x by +Andrew Church (), and a Anope 1.9 using a +preliminary protocol module for ngIRCd (). + +This document describes setting up ngIRCd and these services. Setting up ngIRCd @@ -36,6 +37,31 @@ Example: ServiceMask = *Serv +Setting up Anope 1.9.x +~~~~~~~~~~~~~~~~~~~~~~ + +Anope 1.9.4 (and above) can be used with ngIRCd using a preliminary "ngircd" +protocol module contained in our contrib/Anope/ directory. Please see the +file contrib/Anope/README for installation instructions! + +After patching and installing Anope, at least the following configuration +variables have to be adjusted in data/services.conf, in addition to all the +settings marked as required: + + uplink + { + host = "server.irc.net" + port = 6667 + password = "123abc" + } + + serverinfo + { + name = "services.irc.net" + type = "ngircd" + } + + Setting up IRC Services 5.1.x ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -66,5 +92,6 @@ In modules.conf: The documentation of IRC Services can be found here: + Please let us know if you are successfully using other IRC service packages or which problems you encounter, thanks! diff --git a/doc/Zeroconf.txt b/doc/Zeroconf.txt deleted file mode 100644 index 1208922..0000000 --- a/doc/Zeroconf.txt +++ /dev/null @@ -1,40 +0,0 @@ - - ngIRCd - Next Generation IRC Server - - (c)2001-2006 Alexander Barton - alex@barton.de, http://www.barton.de/ - - ngIRCd is free software and published under the - terms of the GNU General Public License. - - -- Zeroconf.txt -- - - -ngIRCd supports one aspect of Zeroconf Networking[1]: Multicast DNS (mDNS[2]) -with DNS Service Discovery (DNS-SD[3]). - -To use this features you can use one of two APIs: - - a) Apple "Bonjour" API as used by Mac OS X, - b) the Howl[4] Zeroconf library or the Howl compatibility layer - of the newer Avahi[5] library. - -When calling the configure script using the "--with-zeroconf" switch the -available API will be autodetected and the required additional libraries will -be linked to the ngircd binary as required. - -ngIRCd then registers a DNS-SD service for each port it is listening on using -the service type "_ircu._tcp.". - - -Links: - - [1] http://www.zeroconf.org/ - [2] http://www.multicastdns.org/ - [3] http://www.dns-sd.org/ - [4] http://www.porchdogsoft.com/products/howl/ - [5] http://avahi.org/ - - --- -$Id: Zeroconf.txt,v 1.2 2006/08/03 14:37:29 alex Exp $ diff --git a/doc/sample-ngircd.conf.tmpl b/doc/sample-ngircd.conf.tmpl index 12b688d..fb5d826 100644 --- a/doc/sample-ngircd.conf.tmpl +++ b/doc/sample-ngircd.conf.tmpl @@ -12,30 +12,20 @@ # Use "ngircd --configtest" (see manual page ngircd(8)) to validate that the # server interprets the configuration file as expected! # -# Please see ngircd.conf(5) for a complete list of configuration options. +# Please see ngircd.conf(5) for a complete list of configuration options +# and their descriptions. # [Global] # The [Global] section of this file is used to define the main # configuration of the server, like the server name and the ports # on which the server should be listening. + # These settings depend on your personal preferences, so you should + # make sure that they correspond to your installation and setup! # Server name in the IRC network, must contain at least one dot # (".") and be unique in the IRC network. Required! - Name = irc.the.net - - # Info text of the server. This will be shown by WHOIS and - # LINKS requests for example. - Info = Server Info Text - - # Global password for all users needed to connect to the server. - # (Default: not set) - ;Password = abc - - # Password required for using the WEBIRC command used by some - # Web-to-IRC gateways. If not set/empty, the WEBIRC command can't - # be used. (Default: not set) - ;WebircPassword = xyz + Name = irc.example.net # Information about the server and the administrator, used by the # ADMIN command. Not required by server but by RFC! @@ -43,38 +33,16 @@ ;AdminInfo2 = Location ;AdminEMail = admin@irc.server - # Ports on which the server should listen. There may be more than - # one port, separated with ",". (Default: 6667) - ;Ports = 6667, 6668, 6669 - - # Additional Listen Ports that expect SSL/TLS encrypted connections - ;SSLPorts = 6697, 9999 - - # SSL Server Key - ;SSLKeyFile = :ETCDIR:/ssl/server-key.pem - - # password to decrypt SSLKeyFile (OpenSSL only) - ;SSLKeyFilePassword = secret - - # SSL Server Key Certificate - ;SSLCertFile = :ETCDIR:/ssl/server-cert.pem - - # Diffie-Hellman parameters - ;SSLDHFile = :ETCDIR:/ssl/dhparams.pem + # Info text of the server. This will be shown by WHOIS and + # LINKS requests for example. + Info = Server Info Text - # comma separated list of IP addresses on which the server should + # Comma separated list of IP addresses on which the server should # listen. Default values are: # "0.0.0.0" or (if compiled with IPv6 support) "::,0.0.0.0" # so the server listens on all IP addresses of the system by default. ;Listen = 127.0.0.1,192.168.0.1 - # Syslog "facility" to which ngIRCd should send log messages. - # Possible values are system dependant, but most probably auth, daemon, - # user and local1 through local7 are possible values; see syslog(3). - # Default is "local5" for historical reasons, you probably want to - # change this to "daemon", for example. - SyslogFacility = local1 - # Text file with the "message of the day" (MOTD). This message will # be shown to all users connecting to the server: ;MotdFile = :ETCDIR:/ngircd.motd @@ -82,6 +50,25 @@ # A simple Phrase (<256 chars) if you don't want to use a motd file. ;MotdPhrase = "Hello world!" + # Global password for all users needed to connect to the server. + # (Default: not set) + ;Password = abc + + # This tells ngIRCd to write its current process ID to a file. + # Note that 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. + ;PidFile = /var/run/ngircd/ngircd.pid + + # Ports on which the server should listen. There may be more than + # one port, separated with ",". (Default: 6667) + ;Ports = 6667, 6668, 6669 + + # Group ID under which the ngIRCd should run; you can use the name + # of the group or the numerical ID. ATTENTION: For this to work the + # server must have been started with root privileges! + ;ServerGID = 65534 + # User ID under which the server should run; you can use the name # of the user or the numerical ID. ATTENTION: For this to work the # server must have been started with root privileges! In addition, @@ -89,23 +76,29 @@ # otherwise RESTART and REHASH won't work! ;ServerUID = 65534 - # Group ID under which the ngircd should run; you can use the name - # of the group or the numerical ID. ATTENTION: For this to work the - # server must have been started with root privileges! - ;ServerGID = 65534 +[Limits] + # Define some limits and timeouts for this ngIRCd instance. Default + # values should be safe, but it is wise to double-check :-) - # A directory to chroot in when everything is initialized. It - # doesn't need to be populated if ngIRCd is compiled as a static - # binary. By default ngIRCd won't use the chroot() feature. - # ATTENTION: For this to work the server must have been started - # with root privileges! - ;ChrootDir = /var/empty + # The server tries every seconds to establish a link + # to not yet (or no longer) connected servers. + ;ConnectRetry = 60 - # This tells ngircd to write its current process id to a file. - # Note that the pidfile is written AFTER chroot and switching uid, - # i. e. the Directory the pidfile resides in must be writeable by - # the ngircd user and exist in the chroot directory. - ;PidFile = /var/run/ngircd/ngircd.pid + # Maximum number of simultaneous in- and outbound connections the + # server is allowed to accept (0: unlimited): + ;MaxConnections = 0 + + # Maximum number of simultaneous connections from a single IP address + # the server will accept (0: unlimited): + ;MaxConnectionsIP = 5 + + # Maximum number of channels a user can be member of (0: no limit): + ;MaxJoins = 10 + + # Maximum length of an user nick name (Default: 9, as in RFC 2812). + # Please note that all servers in an IRC network MUST use the same + # maximum nick name length! + ;MaxNickLength = 9 # After seconds of inactivity the server will send a # PING to the peer to test whether it is alive or not. @@ -115,9 +108,48 @@ # seconds, it will be disconnected by the server. ;PongTimeout = 20 - # The server tries every seconds to establish a link - # to not yet (or no longer) connected servers. - ;ConnectRetry = 60 +[Options] + # 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. + + # Are remote IRC operators allowed to control this server, e.g. + # use commands like CONNECT, SQUIT, DIE, ...? + ;AllowRemoteOper = no + + # A directory to chroot in when everything is initialized. It + # doesn't need to be populated if ngIRCd is compiled as a static + # binary. By default ngIRCd won't use the chroot() feature. + # ATTENTION: For this to work the server must have been started + # with root privileges! + ;ChrootDir = /var/empty + + # Set this hostname for every client instead of the real one. + # Please note: don't use the percentage sign ("%"), it is reserved for + # future extensions! + ;CloakHost = irc.example.net + + # Set every clients' user name to their nick name + ;CloakUserToNick = yes + + # Try to connect to other IRC servers using IPv4 and IPv6, if possible. + ;ConnectIPv6 = yes + ;ConnectIPv4 = yes + + # 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. + ;Ident = yes + + # Enhance user privacy slightly (useful for IRC server on TOR or I2P) + # by censoring some information like idle time, logon time, etc. + ;MorePrivacy = no + + # Normally ngIRCd doesn't send any messages to a client until it is + # registered. Enable this option to let the daemon send "NOTICE AUTH" + # messages to clients while connecting. + ;NoticeAuth = no # Should IRC Operators be allowed to use the MODE command even if # they are not(!) channel-operators? @@ -127,46 +159,51 @@ # server? (This is a compatibility hack for ircd-irc2 servers) ;OperServerMode = no - # Are remote IRC operators allowed to control this server, e. g. - # use commands like CONNECT, SQUIT, DIE, ...? - ;AllowRemoteOper = no + # Use PAM if ngIRCd has been compiled with support for it. + ;PAM = no # Allow Pre-Defined Channels only (see Section [Channels]) ;PredefChannelsOnly = no - # Don't do any DNS lookups when a client connects to the server. - ;NoDNS = no + # Let ngIRCd send an "authentication PING" when a new client connects, + # and register this client only after receiving the corresponding + # "PONG" reply. + ;RequireAuthPing = no - # Don't do any IDENT lookups, even if ngIRCd has been compiled - # with support for it. - ;NoIdent = no + # Silently drop all incoming CTCP requests. + ;ScrubCTCP = no - # Don't use PAM, even if ngIRCd has been compiled with support for it. - ;NoPAM = no + # Syslog "facility" to which ngIRCd should send log messages. + # Possible values are system dependent, but most probably auth, daemon, + # user and local1 through local7 are possible values; see syslog(3). + # Default is "local5" for historical reasons, you probably want to + # change this to "daemon", for example. + ;SyslogFacility = local1 - # Don't use ZeroConf service registration, even if ngIRCd has been - # compiled with support for it (e.g. Howl, Avahi, Mac OS X). - ;NoZeroConf = no + # Password required for using the WEBIRC command used by some + # Web-to-IRC gateways. If not set/empty, the WEBIRC command can't + # be used. (Default: not set) + ;WebircPassword = xyz - # try to connect to other irc servers using ipv4 and ipv6, if possible - ;ConnectIPv6 = yes - ;ConnectIPv4 = yes +;[SSL] + # SSL-related configuration options. Please note that this section + # is only available when ngIRCd is compiled with support for SSL! + # So don't forget to remove the ";" above if this is the case ... - # Maximum number of simultaneous in- and outbound connections the - # server is allowed to accept (0: unlimited): - ;MaxConnections = 0 + # SSL Server Key Certificate + ;CertFile = :ETCDIR:/ssl/server-cert.pem - # Maximum number of simultaneous connections from a single IP address - # the server will accept (0: unlimited): - ;MaxConnectionsIP = 5 + # Diffie-Hellman parameters + ;DHFile = :ETCDIR:/ssl/dhparams.pem - # Maximum number of channels a user can be member of (0: no limit): - ;MaxJoins = 10 + # SSL Server Key + ;KeyFile = :ETCDIR:/ssl/server-key.pem - # Maximum length of an user nick name (Default: 9, as in RFC 2812). - # Please note that all servers in an IRC network MUST use the same - # maximum nick name length! - ;MaxNickLength = 9 + # password to decrypt SSLKeyFile (OpenSSL only) + ;KeyFilePassword = secret + + # Additional Listen Ports that expect SSL/TLS encrypted connections + ;Ports = 6697, 9999 [Operator] # [Operator] sections are used to define IRC Operators. There may be @@ -200,11 +237,11 @@ # IRC name of the remote server, must match the "Name" variable in # the [Global] section of the other server (when using ngIRCd). - ;Name = irc2.the.net + ;Name = irc2.example.net # Internet host name or IP address of the peer (only required when # this server should establish the connection). - ;Host = connect-to-host.the.net + ;Host = connect-to-host.example.net # IP address to use as _source_ address for the connection. if # unspecified, ngircd will let the operating system pick an address. diff --git a/doc/src/Doxyfile b/doc/src/Doxyfile index 776607b..8afec5e 100644 --- a/doc/src/Doxyfile +++ b/doc/src/Doxyfile @@ -1,6 +1,6 @@ # # ngIRCd -- The Next Generation IRC Daemon -# Copyright (c)2001-2005 Alexander Barton (alex@barton.de) +# 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 @@ -8,11 +8,9 @@ # (at your option) any later version. # Please read the file COPYING, README and AUTHORS for more information. # -# $Id: Doxyfile,v 1.2 2005/07/23 00:48:38 alex Exp $ -# - # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for ngIRCd. +# #--------------------------------------------------------------------------- # Project related configuration options @@ -47,13 +45,6 @@ STRIP_FROM_PATH = ../.. JAVADOC_AUTOBRIEF = YES -# If the DETAILS_AT_TOP tag is set to YES then Doxygen -# will output the detailed description near the top, like JavaDoc. -# If set to NO, the detailed description appears after the member -# documentation. - -DETAILS_AT_TOP = NO - # 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 @@ -72,21 +63,16 @@ OPTIMIZE_OUTPUT_FOR_C = YES EXTRACT_ALL = YES -# If the EXTRACT_PRIVATE tag is set to YES all private members of a class -# will be included in the documentation. - -EXTRACT_PRIVATE = 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 EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) -# defined locally in source files will be included in the documentation. -# If set to NO only classes defined in header files are included. +# 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. -EXTRACT_LOCAL_CLASSES = YES +SHOW_DIRECTORIES = YES #--------------------------------------------------------------------------- # configuration options related to the input files @@ -116,18 +102,43 @@ RECURSIVE = YES 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 + #--------------------------------------------------------------------------- # Output formats #--------------------------------------------------------------------------- GENERATE_HTML = YES -HTML_OUTPUT = html -HTML_FILE_EXTENSION = .html -HTML_HEADER = header.inc.html +# 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 -HTML_STYLESHEET = ngircd-doc.css +# 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 GENERATE_HTMLHELP = NO GENERATE_LATEX = NO GENERATE_RTF = NO @@ -148,6 +159,6 @@ GENERATE_PERLMOD = NO # undefined via #undef or recursively expanded use the := operator # instead of the = operator. -PREDEFINED = CONN_MODULE __client_c__ +PREDEFINED = DEBUG ZLIB PAM ZEROCONF CONN_MODULE __client_c__ # -eof- diff --git a/doc/src/Makefile.am b/doc/src/Makefile.am index 0eaa80d..0d27b7e 100644 --- a/doc/src/Makefile.am +++ b/doc/src/Makefile.am @@ -1,6 +1,6 @@ # # ngIRCd -- The Next Generation IRC Daemon -# Copyright (c)2001-2008 Alexander Barton (alex@barton.de) +# 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 @@ -9,7 +9,7 @@ # Please read the file COPYING, README and AUTHORS for more information. # -EXTRA_DIST = Doxyfile header.inc.html footer.inc.html ngircd-doc.css +EXTRA_DIST = Doxyfile footer.inc.html maintainer-clean-local: rm -f Makefile Makefile.in diff --git a/doc/src/header.inc.html b/doc/src/header.inc.html deleted file mode 100644 index 592c016..0000000 --- a/doc/src/header.inc.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - ngIRCd Source Documentation - - - - diff --git a/doc/src/ngircd-doc.css b/doc/src/ngircd-doc.css deleted file mode 100644 index a2453aa..0000000 --- a/doc/src/ngircd-doc.css +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Cascading Style Sheet for the ngIRCd source documentation - * - * $Id: ngircd-doc.css,v 1.2 2005/07/22 21:23:22 alex Exp $ - */ - -BODY { - background-color: white; - color: black; - margin: 30px; - font-family: Geneva, sans-serif; - font-size: 12px; -} - -A:visited { color: purple; background: transparent; } -A:link { color: navy; background: transparent; } -A:active { color: red; background: transparent; } -A:hover { background: #ffa; } - -H1, H2, H3 { - font-family: Verdana, sans-serif; - background-color: white; - color: #005555; -} -H1 { margin-bottom: 10px; } -H2 { - margin-top: 20px; - margin-bottom: 10px; -} - -P, LI, TD, TH, DT { - font-family: Geneva, sans-serif; - font-size: 12px; - line-height: 1.2 -} - -DD { margin-bottom: 1em; } - -UL { list-style-type: square; } - -HR { margin: 2em 0px; } - -BODY>TABLE { padding: 1em 0px; } - -TD.mdRow { - border: 1px dotted silver; - background-color: #fff9dd; -} - -TD.md { font-weight: bold; } - -TD.memItemLeft { padding-top: 4px; } -TD.memItemRight { padding-top: 4px; } -TD.mdescRight { font-style: italic; } - -DIV.qindex { - background-color: #eee; - border: 1px dotted silver; - padding: 3px; - margin-bottom: 2px; -} - -DIV.nav { - margin: 1em 0px; -} - -HR.footer { margin-top: 50px; } - -.comment { - color: gray; - font-style: italic; -} -.preprocessor { color: #f90; } -.keyword, .keywordflow, .keywordtype { color: red; } -.stringliteral { color: green; } - -/* -eof- */ diff --git a/man/ngircd.8.tmpl b/man/ngircd.8.tmpl index 4a01d71..cc2498d 100644 --- a/man/ngircd.8.tmpl +++ b/man/ngircd.8.tmpl @@ -1,7 +1,7 @@ .\" .\" ngircd(8) manual page template .\" -.TH ngircd 8 "Dec 2010" ngircd "ngIRCd Manual" +.TH ngircd 8 "Jul 2011" ngircd "ngIRCd Manual" .SH NAME ngIRCd \- the next generation IRC daemon .SH SYNOPSIS @@ -26,7 +26,7 @@ there are good chances that it also supports other UNIX-based operating systems as well. By default, ngIRCd writes diagnostic and informational messages using the syslog mechanism. .SH OPTIONS -The default behaviour of +The default behavior of .BR ngircd is to read its standard configuration file (see below), to detach from the controlling terminal and to wait for clients. @@ -68,7 +68,7 @@ Default "message of the day" (MOTD). The daemon understands the following signals: .TP \fBTERM\fR -Shut down all conections and terminate the daemon. +Shut down all connections and terminate the daemon. .TP \fBHUP\fR Shut down all listening sockets, re-read the configuration file and @@ -76,6 +76,31 @@ re-initialize the daemon. .SH HINTS It's wise to use "ngircd \-\-configtest" to validate the configuration file after changing it. +.SH DEBUGGING +When ngIRCd is compiled with debug code, that is, its source code has +been ./configure'd with "--enable-debug" and/or "--enable-sniffer" (witch +enables debug mode automatically as well), you can use two more command +line options and two more signals to debug problems with the daemon itself +or IRC clients: +.PP +\fBOptions:\fR +.TP +\fB\-d\fR, \fB\-\-debug\fR +Enable debug mode and log extra messages. +.TP +\fB\-s\fR, \fB\-\-sniffer\fR +Enable IRC protocol sniffer, which logs all sent and received IRC commands to +the console/syslog. This option requires that ngIRCd has been ./configure'd +with "--enable-sniffer" and enables debug mode automatically, too. +.PP +\fBSignals:\fR +.TP +\fBUSR1\fR +Toggle debug mode on and off during runtime. +.TP +\fBUSR2\fR +Dump internal server state to the console/syslog when debug mode is on (use +command line option \-\-debug or signal USR1). .SH AUTHORS Alexander Barton, .br diff --git a/man/ngircd.conf.5.tmpl b/man/ngircd.conf.5.tmpl index 8fa7623..38ac40b 100644 --- a/man/ngircd.conf.5.tmpl +++ b/man/ngircd.conf.5.tmpl @@ -1,7 +1,7 @@ .\" .\" ngircd.conf(5) manual page template .\" -.TH ngircd.conf 5 "Dec 2010" ngircd "ngIRCd Manual" +.TH ngircd.conf 5 "Jun 2011" ngircd "ngIRCd Manual" .SH NAME ngircd.conf \- configuration file of ngIRCd .SH SYNOPSIS @@ -10,11 +10,12 @@ ngircd.conf \- configuration file of ngIRCd .BR ngircd.conf is the configuration file of the .BR ngircd (8) -Internet Relay Chat (IRC) daemon which you should adept to your local +Internet Relay Chat (IRC) daemon, which must be customized to the local preferences and needs. .PP Most variables can be modified while the ngIRCd daemon is already running: -It will reload its configuration when a HUP signal is received. +It will reload its configuration file when a HUP signal or REHASH command +is received. .SH "FILE FORMAT" The file consists of sections and parameters. A section begins with the name of the section in square brackets and continues until the next section @@ -36,237 +37,318 @@ The file format is line-based - that means, each non-empty newline-terminated line represents either a comment, a section name, or a parameter. .PP Section and parameter names are not case sensitive. +.PP +There are three types of variables: +.I booleans, +.I text strings, +and +.I numbers. +Boolean values are +.I true +if they are "yes", "true", or any non-null integer. Text strings are used 1:1 +without leading and following spaces; there is no way to quote strings. And +for numbers all decimal integer values are valid. +.PP +In addition, some string or numerical variables accept lists of values, +separated by commas (","). .SH "SECTION OVERVIEW" -The file can contain blocks of four types: [Global], [Operator], [Server], -and [Channel]. +The file can contain blocks of seven types: [Global], [Limits], [Options], +[SSL], [Operator], [Server], and [Channel]. .PP The main configuration of the server is stored in the .I [Global] -section, like the server name, administrative information and the -ports on which the server should be listening. IRC operators of this -server are defined in +section, like the server name, administrative information and the ports on +which the server should be listening. The variables in this section have to be +adjusted to the local requirements most of the time, whereas all the variables +in the other sections can be left on there defaults very often. +.PP +Options in the +.I [Limits] +block are used to tweak different limits and timeouts of the daemon, like the +maximum number of clients allowed to connect to this server. Variables in the +.I [Options] +section can be used to enable or disable specific features of ngIRCd, like +support for IDENT, PAM, IPv6, and protocol and cloaking features. The +.I [SSL] +block contains all SSL-related configuration variables. These three sections +are all optional. +.PP +IRC operators of this server are defined in .I [Operator] -blocks. +blocks. Links to remote servers are configured in .I [Server] -is the section where server links are configured. And +sections. And .I [Channel] blocks are used to configure pre-defined ("persistent") IRC channels. .PP -There can be more than one [Operator], [Server] and [Channel] sections -per configuration file, but only one [Global] section. +There can be more than one [Operator], [Server] and [Channel] section per +configuration file (one for each operator, server, and channel), but only +exactly one [Global], one [Limits], one [Options], and one [SSL] section. .SH [GLOBAL] The .I [Global] -section is used to define the server main configuration, like the server -name and the ports on which the server should be listening. +section of this file is used to define the main configuration of the server, +like the server name and the ports on which the server should be listening. +These settings depend on your personal preferences, so you should make sure +that they correspond to your installation and setup! .TP -\fBName\fR +\fBName\fR (string; required) Server name in the IRC network. This is an individual name of the IRC server, it is not related to the DNS host name. It must be unique in the IRC network and must contain at least one dot (".") character. .TP -\fBInfo\fR -Info text of the server. This will be shown by WHOIS and LINKS requests for -example. -.TP -\fBPassword\fR -Global password for all users needed to connect to the server. The default -is empty, so no password is required. -.TP -\fBWebircPassword\fR -Password required for using the WEBIRC command used by some Web-to-IRC -gateways. If not set or empty, the WEBIRC command can't be used. -Default: not set. -.TP -\fBAdminInfo1\fR, \fBAdminInfo2\fR, \fBAdminEMail\fR +\fBAdminInfo1\fR, \fBAdminInfo2\fR, \fBAdminEMail\fR (string) Information about the server and the administrator, used by the ADMIN -command. -.TP -\fBPorts\fR -Ports on which the server should listen. There may be more than one port, -separated with commas (","). Default: 6667, unless \fBSSL_Ports\fR are also -specified. +command. This information is not required by the server but by RFC! .TP -\fBSSLPorts\fR -Same as \fBPorts\fR , except that ngIRCd will expect incoming connections -to be SSL/TLS encrypted. Common port numbers for SSL-encrypted IRC are 6669 -and 6697. Default: none. -.TP -\fBSSLKeyFile\fR -Filename of SSL Server Key to be used for SSL connections. This is required for -SSL/TLS support. -.TP -\fBSSLKeyFilePassword\fR -(OpenSSL only:) Password to decrypt private key. -.TP -\fBSSLCertFile\fR -Certificate file of the private key. -.TP -\fBSSLDHFile\fR -Name of the Diffie-Hellman Parameter file. Can be created with gnutls -"certtool \-\-generate-dh-params" or "openssl dhparam". -If this file is not present, it will be generated on startup when ngIRCd -was compiled with gnutls support (this may take some time). If ngIRCd -was compiled with OpenSSL, then (Ephemeral)-Diffie-Hellman Key Exchanges and several -Cipher Suites will not be available. +\fBInfo\fR (string) +Info text of the server. This will be shown by WHOIS and LINKS requests for +example. .TP -\fBListen\fR +\fBListen\fR (list of strings) A comma separated list of IP address on which the server should listen. If unset, the defaults value is "0.0.0.0" or, if ngIRCd was compiled with IPv6 support, "::,0.0.0.0". So the server listens on all configured IP addresses and interfaces by default. .TP -\fBSyslogFacility\fR -Syslog "facility" to which ngIRCd should send log messages. Possible -values are system dependant, but most probably "auth", "daemon", "user" -and "local1" through "local7" are possible values; see syslog(3). -Default is "local5" for historical reasons, you probably want to -change this to "daemon", for example. -.TP -\fBMotdFile\fR -Text file with the "message of the day" (MOTD). This message will be shown -to all users connecting to the server. Changes made to this file -take effect when ngircd is instructed to re-read its configuration file. +\fBMotdFile\fR (string) +Text file with the "message of the day" (MOTD). This message will be shown to +all users connecting to the server. Please note: Changes made to this file +take effect when ngircd starts up or is instructed to re-read its +configuration file. .TP -\fBMotdPhrase\fR +\fBMotdPhrase\fR (string) A simple Phrase (<256 chars) if you don't want to use a MOTD file. .TP -\fBServerUID\fR -User ID under which the server should run; you can use the name of the user -or the numerical ID. -.PP -.RS -.B Attention: -.br -For this to work the server must have been -started with root privileges! In addition, the configuration and MOTD files -must be readable by this user, otherwise RESTART and REHASH won't work! -.RE +\fBPassword\fR (string) +Global password for all users needed to connect to the server. The default is +empty, so no password is required. Please note: This feature is not available +if ngIRCd is using PAM! .TP -\fBServerGID\fR +\fBPidFile\fR (string) +This tells ngIRCd to write its current process ID to a file. Note that 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) +Ports on which the server should listen. There may be more than one port, +separated with commas (","). Default: 6667, unless \fBSSL_Ports\fR are also +specified. +.TP +\fBServerGID\fR (string or number) Group ID under which the ngIRCd should run; you can use the name of the group or the numerical ID. .PP .RS .B Attention: .br -For this to work the server must have -been started with root privileges! +For this to work the server must have been started with root privileges! .RE .TP -\fBChrootDir\fR -A directory to chroot in when everything is initialized. It doesn't need -to be populated if ngIRCd is compiled as a static binary. By default ngIRCd -won't use the chroot() feature. +\fBServerUID\fR (string or number) +User ID under which the server should run; you can use the name of the user +or the numerical ID. .PP .RS .B Attention: .br -For this to work the server must have -been started with root privileges! +For this to work the server must have been started with root privileges! In +addition, the configuration and MOTD files must be readable by this user, +otherwise RESTART and REHASH won't work! .RE +.SH [LIMITS] +Define some limits and timeouts for this ngIRCd instance. Default values +should be safe, but it is wise to double-check :-) .TP -\fBPidFile\fR -This tells ngIRCd to write its current process ID to a file. Note that the -pidfile is written AFTER chroot and switching the user ID, i. e. the -directory the pidfile resides in must be writeable by the ngIRCd user and -exist in the chroot directory (if configured, see above). -.RE +\fBConnectRetry\fR (number) +The server tries every seconds to establish a link to not yet +(or no longer) connected servers. Default: 60. +.TP +\fBMaxConnections\fR (number) +Maximum number of simultaneous in- and outbound connections the server is +allowed to accept (0: unlimited). Default: 0. +.TP +\fBMaxConnectionsIP\fR (number) +Maximum number of simultaneous connections from a single IP address that +the server will accept (0: unlimited). This configuration options lowers +the risk of denial of service attacks (DoS). Default: 5. +.TP +\fBMaxJoins\fR (number) +Maximum number of channels a user can be member of (0: no limit). +Default: 10. +.TP +\fBMaxNickLength\fR (number) +Maximum length of an user nick name (Default: 9, as in RFC 2812). Please +note that all servers in an IRC network MUST use the same maximum nick name +length! .TP -\fBPingTimeout\fR +\fBPingTimeout\fR (number) After seconds of inactivity the server will send a PING to the peer to test whether it is alive or not. Default: 120. .TP -\fBPongTimeout\fR +\fBPongTimeout\fR (number) If a client fails to answer a PING with a PONG within seconds, it will be disconnected by the server. Default: 20. +.SH [OPTIONS] +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 -\fBConnectRetry\fR -The server tries every seconds to establish a link to not yet -(or no longer) connected servers. Default: 60. +\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, +SQUIT, ... that affect this server? Default: no. .TP -\fBOperCanUseMode\fR -Should IRC Operators be allowed to use the MODE command even if they are -not(!) channel-operators? Default: no. +\fBChrootDir\fR (string) +A directory to chroot in when everything is initialized. It doesn't need +to be populated if ngIRCd is compiled as a static binary. By default ngIRCd +won't use the chroot() feature. +.PP +.RS +.B Attention: +.br +For this to work the server must have been started with root privileges! +.RE .TP -\fBOperServerMode\fR -If \fBOperCanUseMode\fR is enabled, this may lead the compatibility problems with -Servers that run the ircd-irc2 Software. This Option "masks" mode requests -by non-chanops as if they were coming from the server. Default: no. +\fBCloakHost\fR (string) +Set this hostname for every client instead of the real one. Default: empty, +don't change. +.PP +.RS +.B Please note: +.br +Don't use the percentage sign ("%"), it is reserved for future extensions! +.RE .TP -\fBAllowRemoteOper\fR -Are IRC operators connected to remote servers allowed to control this server, -e. g. are they allowed to use administrative commands like CONNECT, DIE, -SQUIT, ... that affect this server? Default: no. +\fBCloakUserToNick\fR (boolean) +Set every clients' user name to their nick name and hide the one supplied +by the IRC client. Default: no. .TP -\fBPredefChannelsOnly\fR -If enabled, no new channels can be created. Useful if -you do not want to have channels other than those defined in -[Channel] sections in the configuration file. -Default: no. +\fBConnectIPv4\fR (boolean) +Set this to no if you do not want ngIRCd to connect to other IRC servers using +the IPv4 protocol. This allows the usage of ngIRCd in IPv6-only setups. +Default: yes. .TP -\fBNoDNS\fR -If set to true, ngIRCd will not make DNS lookups when clients connect. +\fBConnectIPv6\fR (boolean) +Set this to no if you do not want ngIRCd to connect to other IRC servers using +the IPv6 protocol. +Default: yes. +.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 perform a DNS lookup if required. -Default: no. +Default: yes. .TP -\fBNoIdent\fR +\fBIdent\fR (boolean) If ngIRCd is compiled with IDENT support this can be used to disable IDENT lookups at run time. +Default: yes. +.TP +\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 +client software is being used). WHOWAS requests are also silently ignored. +This option is most useful when ngIRCd is being used together with +anonymizing software such as TOR or I2P and one does not wish to make it +too easy to collect statistics on the users. Default: no. .TP -\fBNoPAM\fR +\fBNoticeAuth\fR (boolean) +Normally ngIRCd doesn't send any messages to a client until it is registered. +Enable this option to let the daemon send "NOTICE AUTH" messages to clients +while connecting. Default: no. +.TP +\fBOperCanUseMode\fR (boolean) +Should IRC Operators be allowed to use the MODE command even if they are +not(!) channel-operators? Default: no. +.TP +\fBOperServerMode\fR (boolean) +If \fBOperCanUseMode\fR is enabled, this may lead the compatibility problems +with Servers that run the ircd-irc2 Software. This Option "masks" mode +requests by non-chanops as if they were coming from the server. Default: no; +only enable it if you have ircd-irc2 servers in your IRC network. +.TP +\fBPAM\fR (boolean) If ngIRCd is compiled with PAM support this can be used to disable all calls to the PAM library at runtime; all users connecting without password are allowed to connect, all passwords given will fail. -Default: no. -.TP -\fBNoZeroConf\fR -If ngIRCd is compiled to register its services using ZeroConf (e.g. using -Howl, Avahi or on Mac OS X) this parameter can be used to disable service -registration at runtime. -Default: no. -.TP -\fBConnectIPv4\fR -Set this to no if you do not want ngIRCd to connect to other IRC servers using -IPv4. This allows usage of ngIRCd in IPv6-only setups. Default: yes. .TP -\fBConnectIPv6\fR -Set this to no if you do not want ngIRCd to connect to other irc servers using IPv6. -Default: yes. +\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 -\fBMaxConnections\fR -Maximum number of simultaneous in- and outbound connections the server is -allowed to accept (0: unlimited). Default: 0. +\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. +Default: no. .TP -\fBMaxConnectionsIP\fR -Maximum number of simultaneous connections from a single IP address that -the server will accept (0: unlimited). This configuration options lowers -the risk of denial of service attacks (DoS). Default: 5. +\fBScrubCTCP\fR (boolean) +If set to true, ngIRCd will silently drop all CTCP requests sent to it from +both clients and servers. It will also not forward CTCP requests to any +other servers. CTCP requests can be used to query user clients about which +software they are using and which versions said software is. CTCP can also be +used to reveal clients IP numbers. ACTION CTCP requests are not blocked, +this means that /me commands will not be dropped, but please note that +blocking CTCP will disable file sharing between users! +Default: no. .TP -\fBMaxJoins\fR -Maximum number of channels a user can be member of (0: no limit). -Default: 10. +\fBSyslogFacility\fR (string) +Syslog "facility" to which ngIRCd should send log messages. Possible +values are system dependent, but most probably "auth", "daemon", "user" +and "local1" through "local7" are possible values; see syslog(3). +Default is "local5" for historical reasons, you probably want to +change this to "daemon", for example. .TP -\fBMaxNickLength\fR -Maximum length of an user nick name (Default: 9, as in RFC 2812). Please -note that all servers in an IRC network MUST use the same maximum nick name -length! +\fBWebircPassword\fR (string) +Password required for using the WEBIRC command used by some Web-to-IRC +gateways. If not set or empty, the WEBIRC command can't be used. +Default: not set. +.SH [SSL] +All SSL-related configuration variables are located in the +.I [SSL] +section. Please note that this whole section is only recognized by ngIRCd +when it is compiled with support for SSL using OpenSSL or GnuTLS! +.TP +\fBCertFile\fR (string) +SSL Certificate file of the private server key. +.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 +present, it will be generated on startup when ngIRCd was compiled with GnuTLS +support (this may take some time). If ngIRCd was compiled with OpenSSL, then +(Ephemeral)-Diffie-Hellman Key Exchanges and several Cipher Suites will not be +available. +.TP +\fBKeyFile\fR (string) +Filename of SSL Server Key to be used for SSL connections. This is required +for SSL/TLS support. +.TP +\fBKeyFilePassword\fR (string) +OpenSSL only: Password to decrypt the private key file. +.TP +\fBPorts\fR (list of numbers) +Same as \fBPorts\fR , except that ngIRCd will expect incoming connections +to be SSL/TLS encrypted. Common port numbers for SSL-encrypted IRC are 6669 +and 6697. Default: none. .SH [OPERATOR] .I [Operator] sections are used to define IRC Operators. There may be more than one .I [Operator] block, one for each local operator. .TP -\fBName\fR +\fBName\fR (string) ID of the operator (may be different of the nick name). .TP -\fBPassword\fR +\fBPassword\fR (string) Password of the IRC operator. .TP -\fBMask\fR +\fBMask\fR (string) Mask that is to be checked before an /OPER for this account is accepted. Example: nick!ident@*.example.com .SH [SERVER] @@ -287,40 +369,40 @@ There may be more than one .I [Server] block. .TP -\fBName\fR +\fBName\fR (string) IRC name of the remote server. .TP -\fBHost\fR +\fBHost\fR (string) Internet host name (or IP address) of the peer. .TP -\fBBind\fR +\fBBind\fR (string) IP address to use as source IP for the outgoing connection. Default is to let the operating system decide. .TP -\fBPort\fR +\fBPort\fR (number) Port of the remote server to which ngIRCd should connect (active). If no port is assigned to a configured server, the daemon only waits for incoming connections (passive, default). .TP -\fBMyPassword\fR +\fBMyPassword\fR (string) Own password for this connection. This password has to be configured as \fBPeerPassword\fR on the other server. Must not have ':' as first character. .TP -\fBPeerPassword\fR +\fBPeerPassword\fR (string) Foreign password for this connection. This password has to be configured as \fBMyPassword\fR on the other server. .TP -\fBGroup\fR +\fBGroup\fR (number) Group of this server (optional). .TP -\fBPassive\fR +\fBPassive\fR (boolean) Disable automatic connection even if port value is specified. Default: false. You can use the IRC Operator command CONNECT later on to create the link. .TP -\fBSSLConnect\fR +\fBSSLConnect\fR (boolean) Connect to the remote server using TLS/SSL. Default: false. .TP -\fBServiceMask\fR +\fBServiceMask\fR (string) Define a (case insensitive) mask matching nick names that should be treated as IRC services when introduced via this remote server. REGULAR SERVERS DON'T NEED this parameter, so leave it empty (which is the default). @@ -342,19 +424,19 @@ There may be more than one .I [Channel] block. .TP -\fBName\fR +\fBName\fR (string) Name of the channel, including channel prefix ("#" or "&"). .TP -\fBTopic\fR +\fBTopic\fR (string) Topic for this channel. .TP -\fBModes\fR +\fBModes\fR (string) Initial channel modes. .TP -\fBKey\fR +\fBKey\fR (string) Sets initial channel key (only relevant if channel mode "k" is set). .TP -\fBKeyFile\fR +\fBKeyFile\fR (string) Path and file name of a "key file" containing individual channel keys for different users. The file consists of plain text lines with the following syntax (without spaces!): @@ -397,7 +479,7 @@ without problems, but moving or deleting the file will have not effect until the daemon re-reads its configuration! .RE .TP -\fBMaxUsers\fR +\fBMaxUsers\fR (number) Set maximum user limit for this channel (only relevant if channel mode "l" is set). .SH HINTS diff --git a/src/ipaddr/ng_ipaddr.c b/src/ipaddr/ng_ipaddr.c index af524d0..a47a40d 100644 --- a/src/ipaddr/ng_ipaddr.c +++ b/src/ipaddr/ng_ipaddr.c @@ -1,11 +1,14 @@ /* - * Functions for AF_ agnostic ipv4/ipv6 handling. - * * (c) 2008 Florian Westphal , public domain. */ #include "portab.h" +/** + * @file + * Functions for AF_ agnostic ipv4/ipv6 handling. + */ + #include #include #include diff --git a/src/ipaddr/ng_ipaddr.h b/src/ipaddr/ng_ipaddr.h index 54a9703..1f209ef 100644 --- a/src/ipaddr/ng_ipaddr.h +++ b/src/ipaddr/ng_ipaddr.h @@ -1,6 +1,4 @@ /* - * Functions for AF_ agnostic ipv4/ipv6 handling. - * * (c) 2008 Florian Westphal , public domain. */ @@ -8,6 +6,11 @@ #define NG_IPADDR_HDR #include "portab.h" +/** + * @file + * Functions for AF_ agnostic ipv4/ipv6 handling (header). + */ + #include #include #include diff --git a/src/ngircd/Makefile.am b/src/ngircd/Makefile.am index 2e8b2e5..c617665 100644 --- a/src/ngircd/Makefile.am +++ b/src/ngircd/Makefile.am @@ -21,7 +21,7 @@ sbin_PROGRAMS = ngircd ngircd_SOURCES = ngircd.c array.c channel.c client.c conf.c conn.c conn-func.c \ conn-ssl.c conn-zip.c hash.c io.c irc.c irc-channel.c irc-info.c irc-login.c \ irc-mode.c irc-op.c irc-oper.c irc-server.c irc-write.c lists.c log.c \ - match.c op.c numeric.c pam.c parse.c proc.c rendezvous.c resolve.c sighandlers.c + match.c op.c numeric.c pam.c parse.c proc.c resolve.c sighandlers.c ngircd_LDFLAGS = -L../portab -L../tool -L../ipaddr @@ -31,7 +31,7 @@ noinst_HEADERS = ngircd.h array.h channel.h client.h conf.h conf-ssl.h conn.h \ conn-func.h conn-ssl.h conn-zip.h hash.h io.h irc.h irc-channel.h \ irc-info.h irc-login.h irc-mode.h irc-op.h irc-oper.h irc-server.h \ irc-write.h lists.h log.h match.h numeric.h op.h pam.h parse.h proc.h \ - rendezvous.h resolve.h sighandlers.h defines.h messages.h + resolve.h sighandlers.h defines.h messages.h clean-local: rm -f check-version check-help lint.out diff --git a/src/ngircd/array.c b/src/ngircd/array.c index 1e56b71..ad4f8da 100644 --- a/src/ngircd/array.c +++ b/src/ngircd/array.c @@ -5,17 +5,18 @@ * (at your option) any later version. * Please read the file COPYING, README and AUTHORS for more information. * - * functions to dynamically allocate arrays. + * libarray - dynamically allocate arrays. * Copyright (c) 2005 Florian Westphal (westphal@foo.fh-furtwangen.de) - * */ -#include "array.h" +/** + * @file + * Functions to dynamically allocate arrays. + */ -static char UNUSED id[] = "$Id: array.c,v 1.15 2007/11/18 15:05:35 alex Exp $"; +#include "array.h" #include - #include #include @@ -24,13 +25,7 @@ static char UNUSED id[] = "$Id: array.c,v 1.15 2007/11/18 15:05:35 alex Exp $"; /* Enable more Debug messages in alloc / append / memmove code. */ /* #define DEBUG_ARRAY */ - - -#define array_UNUSABLE(x) ( !(x)->mem || (0 == (x)->allocated) ) - -#define ALIGN_32U(x) (((x)+(unsigned)31 ) & ~((unsigned)31)) -#define ALIGN_1024U(x) (((x)+(unsigned)1023) & ~((unsigned)1023)) -#define ALIGN_4096U(x) (((x)+(unsigned)4095) & ~((unsigned)4095)) +#define array_UNUSABLE(x) ( !(x)->mem ) static bool @@ -61,7 +56,6 @@ void * array_alloc(array * a, size_t size, size_t pos) { size_t alloc, pos_plus1 = pos + 1; - size_t aligned = 0; char *tmp; assert(size > 0); @@ -70,43 +64,22 @@ array_alloc(array * a, size_t size, size_t pos) return NULL; if (a->allocated < alloc) { - if (alloc < 128) { - aligned = ALIGN_32U(alloc); - } else { - if (alloc < 4096) { - aligned = ALIGN_1024U(alloc); - } else { - aligned = ALIGN_4096U(alloc); - } - } -#ifdef DEBUG_ARRAY - Log(LOG_DEBUG, "array_alloc(): rounded %u to %u bytes.", alloc, aligned); -#endif - - assert(aligned >= alloc); - - if (aligned < alloc) /* rounding overflow */ - return NULL; - - alloc = aligned; #ifdef DEBUG_ARRAY Log(LOG_DEBUG, "array_alloc(): changing size from %u to %u bytes.", - a->allocated, aligned); + a->allocated, alloc); #endif - tmp = realloc(a->mem, alloc); if (!tmp) return NULL; a->mem = tmp; a->allocated = alloc; - - assert(a->allocated > a->used); - memset(a->mem + a->used, 0, a->allocated - a->used); - a->used = alloc; } + + assert(a->allocated >= a->used); + return a->mem + (pos * size); } @@ -121,6 +94,7 @@ array_length(const array * const a, size_t membersize) if (array_UNUSABLE(a)) return 0; + assert(a->allocated); return membersize ? a->used / membersize : 0; } @@ -132,6 +106,7 @@ array_copy(array * dest, const array * const src) if (array_UNUSABLE(src)) return false; + assert(src->allocated); return array_copyb(dest, src->mem, src->used); } diff --git a/src/ngircd/array.h b/src/ngircd/array.h index b4aad9f..f461162 100644 --- a/src/ngircd/array.h +++ b/src/ngircd/array.h @@ -7,13 +7,16 @@ * * libarray - dynamically allocate arrays. * Copyright (c) 2005 Florian Westphal (westphal@foo.fh-furtwangen.de) - * - * $Id: array.h,v 1.4 2005/08/30 13:36:32 fw Exp $ */ #ifndef array_h_included #define array_h_included +/** + * @file + * Functions to dynamically allocate arrays (header). + */ + #include "portab.h" typedef struct { diff --git a/src/ngircd/channel.c b/src/ngircd/channel.c index edbbc38..a36131c 100644 --- a/src/ngircd/channel.c +++ b/src/ngircd/channel.c @@ -1,22 +1,23 @@ /* * ngIRCd -- The Next Generation IRC Daemon - * Copyright (c)2001-2009 Alexander Barton (alex@barton.de) + * 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 * 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. - * - * Channel management */ - #define __channel_c__ - #include "portab.h" +/** + * @file + * Channel management + */ + #include "imp.h" #include #include @@ -262,6 +263,9 @@ Channel_Part(CLIENT * Client, CLIENT * Origin, const char *Name, const char *Rea return false; } + if (Conf_MorePrivacy) + Reason = ""; + /* Part client from channel */ if (!Remove_Client(REMOVE_PART, chan, Client, Origin, Reason, true)) return false; @@ -330,6 +334,9 @@ Channel_Quit( CLIENT *Client, const char *Reason ) assert( Client != NULL ); assert( Reason != NULL ); + if (Conf_MorePrivacy) + Reason = ""; + IRC_WriteStrRelatedPrefix( Client, Client, false, "QUIT :%s", Reason ); c = My_Channels; @@ -960,6 +967,9 @@ Remove_Client( int Type, CHANNEL *Chan, CLIENT *Client, CLIENT *Origin, const ch Client_Mask( Client ), c->name, Client_ID(Origin), Reason); break; default: /* PART */ + if (Conf_MorePrivacy) + Reason = ""; + if (InformServer) IRC_WriteStrServersPrefix(Origin, Client, "PART %s :%s", c->name, Reason); @@ -989,6 +999,7 @@ GLOBAL bool Channel_AddBan(CHANNEL *c, const char *mask ) { struct list_head *h = Channel_GetListBans(c); + LogDebug("Adding \"%s\" to \"%s\" %s list", mask, Channel_Name(c), "ban"); return Lists_Add(h, mask, false); } @@ -997,6 +1008,7 @@ GLOBAL bool Channel_AddInvite(CHANNEL *c, const char *mask, bool onlyonce) { struct list_head *h = Channel_GetListInvites(c); + LogDebug("Adding \"%s\" to \"%s\" %s list", mask, Channel_Name(c), "invite"); return Lists_Add(h, mask, onlyonce); } @@ -1079,10 +1091,10 @@ Channel_CheckKey(CHANNEL *Chan, CLIENT *Client, const char *Key) if (!strchr(Chan->modes, 'k')) return true; - if (strcmp(Chan->key, Key) == 0) - return true; if (*Key == '\0') return false; + if (strcmp(Chan->key, Key) == 0) + return true; file_name = array_start(&Chan->keyfile); if (!file_name) @@ -1117,6 +1129,64 @@ Channel_CheckKey(CHANNEL *Chan, CLIENT *Client, const char *Key) } /* Channel_CheckKey */ +/** + * Check wether a client is allowed to administer a channel or not. + * + * @param Chan The channel to test. + * @param Client The client from which the command has been received. + * @param Origin The originator of the command (or NULL). + * @param OnChannel Set to true if the originator is member of the channel. + * @param AdminOk Set to true if the client is allowed to do + * administrative tasks on this channel. + * @param UseServerMode Set to true if ngIRCd should emulate "server mode", + * that is send commands as if originating from a server + * and not the originator of the command. + */ +GLOBAL void +Channel_CheckAdminRights(CHANNEL *Chan, CLIENT *Client, CLIENT *Origin, + bool *OnChannel, bool *AdminOk, bool *UseServerMode) +{ + assert (Chan != NULL); + assert (Client != NULL); + assert (OnChannel != NULL); + assert (AdminOk != NULL); + assert (UseServerMode != NULL); + + /* Use the client as origin, if no origin has been given (no prefix?) */ + if (!Origin) + Origin = Client; + + *OnChannel = false; + *AdminOk = false; + *UseServerMode = false; + + if (Client_Type(Client) != CLIENT_USER + && Client_Type(Client) != CLIENT_SERVER + && Client_Type(Client) != CLIENT_SERVICE) + return; + + /* Allow channel administration if the client is a server or service */ + if (Client_Type(Client) != CLIENT_USER) { + *AdminOk = true; + return; + } + + *OnChannel = Channel_IsMemberOf(Chan, Origin); + + if (*OnChannel && strchr(Channel_UserModes(Chan, Origin), 'o')) { + /* User is a channel operator */ + *AdminOk = true; + } else if (Conf_OperCanMode) { + /* IRC operators are allowed to administer channels as well */ + if (Client_OperByMe(Origin)) { + *AdminOk = true; + if (Conf_OperServerMode) + *UseServerMode = true; + } + } +} /* Channel_CheckAdminRights */ + + static CL2CHAN * Get_First_Cl2Chan( CLIENT *Client, CHANNEL *Chan ) { diff --git a/src/ngircd/channel.h b/src/ngircd/channel.h index 030f910..f44e194 100644 --- a/src/ngircd/channel.h +++ b/src/ngircd/channel.h @@ -1,20 +1,21 @@ /* * ngIRCd -- The Next Generation IRC Daemon - * Copyright (c)2001-2008 by Alexander Barton (alex@barton.de) + * 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 * 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. - * - * Channel management (header) */ - #ifndef __channel_h__ #define __channel_h__ +/** + * @file + * Channel management (header) + */ #if defined(__channel_c__) | defined(S_SPLINT_S) @@ -133,6 +134,10 @@ GLOBAL void Channel_LogServer PARAMS((const char *msg)); GLOBAL bool Channel_CheckKey PARAMS((CHANNEL *Chan, CLIENT *Client, const char *Key)); +GLOBAL void Channel_CheckAdminRights PARAMS((CHANNEL *Chan, CLIENT *Client, + CLIENT *Origin, bool *OnChannel, + bool *AdminOk, bool *UseServerMode)); + #define Channel_IsLocal(c) (Channel_Name(c)[0] == '&') #define Channel_IsModeless(c) (Channel_Name(c)[0] == '+') diff --git a/src/ngircd/client.c b/src/ngircd/client.c index 739c5ea..83c80f8 100644 --- a/src/ngircd/client.c +++ b/src/ngircd/client.c @@ -7,16 +7,17 @@ * 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. - * - * Client management. */ - #define __client_c__ - #include "portab.h" +/** + * @file + * Client management. + */ + #include "imp.h" #include #include @@ -43,10 +44,8 @@ #include - #define GETID_LEN (CLIENT_NICK_LEN-1) + 1 + (CLIENT_USER_LEN-1) + 1 + (CLIENT_HOST_LEN-1) + 1 - static CLIENT *This_Server, *My_Clients; static WHOWAS My_Whowas[MAX_WHOWAS]; @@ -93,7 +92,7 @@ Client_Init( void ) This_Server->hops = 0; gethostname( This_Server->host, CLIENT_HOST_LEN ); - if (!Conf_NoDNS) { + if (Conf_DNS) { h = gethostbyname( This_Server->host ); if (h) strlcpy(This_Server->host, h->h_name, sizeof(This_Server->host)); } @@ -320,7 +319,11 @@ Client_SetHostname( CLIENT *Client, const char *Hostname ) assert( Client != NULL ); assert( Hostname != NULL ); - strlcpy( Client->host, Hostname, sizeof( Client->host )); + if (strlen(Conf_CloakHost)) { + strlcpy( Client->host, Conf_CloakHost, sizeof( Client->host )); + } else { + strlcpy( Client->host, Hostname, sizeof( Client->host )); + } } /* Client_SetHostname */ @@ -332,6 +335,11 @@ Client_SetID( CLIENT *Client, const char *ID ) strlcpy( Client->id, ID, sizeof( Client->id )); + if (Conf_CloakUserToNick) { + strlcpy( Client->user, ID, sizeof( Client->user )); + strlcpy( Client->info, ID, sizeof( Client->info )); + } + /* Hash */ Client->hash = Hash( Client->id ); } /* Client_SetID */ @@ -345,7 +353,9 @@ Client_SetUser( CLIENT *Client, const char *User, bool Idented ) assert( Client != NULL ); assert( User != NULL ); - if (Idented) { + if (Conf_CloakUserToNick) { + strlcpy(Client->user, Client->id, sizeof(Client->user)); + } else if (Idented) { strlcpy(Client->user, User, sizeof(Client->user)); } else { Client->user[0] = '~'; @@ -382,7 +392,10 @@ Client_SetInfo( CLIENT *Client, const char *Info ) assert( Client != NULL ); assert( Info != NULL ); - strlcpy(Client->info, Info, sizeof(Client->info)); + if (Conf_CloakUserToNick) + strlcpy(Client->info, Client->id, sizeof(Client->info)); + else + strlcpy(Client->info, Info, sizeof(Client->info)); } /* Client_SetInfo */ @@ -553,17 +566,19 @@ Client_Search( const char *Nick ) } /* Client_Search */ +/** + * Get client structure ("introducer") identfied by a server token. + * @return CLIENT structure or NULL if none could be found. + */ GLOBAL CLIENT * Client_GetFromToken( CLIENT *Client, int Token ) { - /* Client-Struktur, die den entsprechenden Introducer (=Client) - * und das gegebene Token hat, liefern. Wird keine gefunden, - * so wird NULL geliefert. */ - CLIENT *c; assert( Client != NULL ); - assert( Token > 0 ); + + if (!Token) + return NULL; c = My_Clients; while (c) { @@ -1177,6 +1192,10 @@ Client_RegisterWhowas( CLIENT *Client ) assert( Client != NULL ); + /* Don't register WHOWAS information when "MorePrivacy" is enabled. */ + if (Conf_MorePrivacy) + return; + now = time(NULL); /* Don't register clients that were connected less than 30 seconds. */ if( now - Client->starttime < 30 ) diff --git a/src/ngircd/client.h b/src/ngircd/client.h index 42036c4..fecf5d9 100644 --- a/src/ngircd/client.h +++ b/src/ngircd/client.h @@ -7,13 +7,16 @@ * 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. - * - * Client management (header) */ #ifndef __client_h__ #define __client_h__ +/** + * @file + * Client management (header) + */ + #define CLIENT_UNKNOWN 1 /* connection of unknown type */ #define CLIENT_GOTPASS 2 /* client did send PASS */ #define CLIENT_GOTNICK 4 /* client did send NICK */ @@ -23,6 +26,9 @@ #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 512 /* waiting for AUTH PONG from client */ +#endif #define CLIENT_TYPE int @@ -161,8 +167,6 @@ GLOBAL const char *Client_TypeText PARAMS((CLIENT *Client)); GLOBAL void Client_DebugDump PARAMS((void)); #endif - #endif - /* -eof- */ diff --git a/src/ngircd/conf-ssl.h b/src/ngircd/conf-ssl.h index cdb9968..3fab579 100644 --- a/src/ngircd/conf-ssl.h +++ b/src/ngircd/conf-ssl.h @@ -1,11 +1,15 @@ /* * ngIRCd -- The Next Generation IRC Daemon - * SSL defines. */ #ifndef conf_ssl_h #define conf_ssl_h +/** + * @file + * SSL related definitions + */ + #ifdef HAVE_LIBSSL #define SSL_SUPPORT #include diff --git a/src/ngircd/conf.c b/src/ngircd/conf.c index 4a255b2..4991918 100644 --- a/src/ngircd/conf.c +++ b/src/ngircd/conf.c @@ -1,19 +1,21 @@ /* * ngIRCd -- The Next Generation IRC Daemon - * Copyright (c)2001-2010 Alexander Barton (alex@barton.de) + * 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 * 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. - * - * Configuration management (reading, parsing & validation) */ - #include "portab.h" +/** + * @file + * Configuration management (reading, parsing & validation) + */ + #include "imp.h" #include #include @@ -62,6 +64,8 @@ static bool Read_Config PARAMS(( bool ngircd_starting )); static bool Validate_Config PARAMS(( bool TestOnly, bool Rehash )); static void Handle_GLOBAL PARAMS(( int Line, char *Var, char *Arg )); +static void Handle_LIMITS PARAMS(( int Line, char *Var, char *Arg )); +static void Handle_OPTIONS PARAMS(( int Line, char *Var, char *Arg )); static void Handle_OPERATOR PARAMS(( int Line, char *Var, char *Arg )); static void Handle_SERVER PARAMS(( int Line, char *Var, char *Arg )); static void Handle_CHANNEL PARAMS(( int Line, char *Var, char *Arg )); @@ -69,19 +73,29 @@ static void Handle_CHANNEL PARAMS(( int Line, char *Var, char *Arg )); static void Config_Error PARAMS(( const int Level, const char *Format, ... )); static void Config_Error_NaN PARAMS(( const int LINE, const char *Value )); +static void Config_Error_Section PARAMS(( const int Line, const char *Item, + const char *Section )); static void Config_Error_TooLong PARAMS(( const int LINE, const char *Value )); static void Init_Server_Struct PARAMS(( CONF_SERVER *Server )); + #ifdef WANT_IPV6 #define DEFAULT_LISTEN_ADDRSTR "::,0.0.0.0" #else #define DEFAULT_LISTEN_ADDRSTR "0.0.0.0" #endif + #ifdef SSL_SUPPORT + +static void Handle_SSL PARAMS(( int Line, char *Var, char *Ark )); + struct SSLOptions Conf_SSLOptions; +/** + * Initialize SSL configuration. + */ static void ConfSSL_Init(void) { @@ -96,59 +110,51 @@ ConfSSL_Init(void) array_free_wipe(&Conf_SSLOptions.KeyFilePassword); } -static bool -ssl_print_configvar(const char *name, const char *file) +/** + * Make sure that a configured file is readable. + * + * Currently, this function is only used for SSL-related options ... + * + * @param Var Configuration variable + * @param Filename Configured filename + */ +static void +CheckFileReadable(const char *Var, const char *Filename) { FILE *fp; - if (!file) { - printf(" %s =\n", name); - return true; - } + if (!Filename) + return; - fp = fopen(file, "r"); + fp = fopen(Filename, "r"); if (fp) fclose(fp); else - fprintf(stderr, "ERROR: %s \"%s\": %s\n", - name, file, strerror(errno)); - - printf(" %s = %s\n", name, file); - return fp != NULL; + Config_Error(LOG_ERR, "Can't read \"%s\" (\"%s\"): %s", + Filename, Var, strerror(errno)); } -static bool -ConfSSL_Puts(void) -{ - bool ret; - - ret = ssl_print_configvar("SSLKeyFile", Conf_SSLOptions.KeyFile); - - if (!ssl_print_configvar("SSLCertFile", Conf_SSLOptions.CertFile)) - ret = false; - - if (!ssl_print_configvar("SSLDHFile", Conf_SSLOptions.DHFile)) - ret = false; - - if (array_bytes(&Conf_SSLOptions.KeyFilePassword)) - puts(" SSLKeyFilePassword = "); - - array_free_wipe(&Conf_SSLOptions.KeyFilePassword); - - return ret; -} #endif + +/** + * Duplicate string and warn on errors. + * + * @returns Pointer to string on success, NULL otherwise. + */ static char * strdup_warn(const char *str) { char *ptr = strdup(str); if (!ptr) - Config_Error(LOG_ERR, "Could not allocate mem for string: %s", str); + Config_Error(LOG_ERR, + "Could not allocate memory for string: %s", str); return ptr; } - +/** + * Output a comma separated list of ports (integer values). + */ static void ports_puts(array *a) { @@ -166,7 +172,9 @@ ports_puts(array *a) putc('\n', stdout); } - +/** + * Parse a comma separated string into an array of port numbers (integers). + */ static void ports_parse(array *a, int Line, char *Arg) { @@ -176,8 +184,6 @@ ports_parse(array *a, int Line, char *Arg) array_trunc(a); - /* Ports on that the server should listen. More port numbers - * must be separated by "," */ ptr = strtok( Arg, "," ); while (ptr) { ngt_TrimStr(ptr); @@ -196,15 +202,21 @@ ports_parse(array *a, int Line, char *Arg) } } - +/** + * Initialize configuration module. + */ GLOBAL void Conf_Init( void ) { Read_Config( true ); Validate_Config(false, false); -} /* Config_Init */ - +} +/** + * "Rehash" (reload) server configuration. + * + * @returns true if configuration has been re-read, false on errors. + */ GLOBAL bool Conf_Rehash( void ) { @@ -215,9 +227,11 @@ Conf_Rehash( void ) /* Update CLIENT structure of local server */ Client_SetInfo(Client_ThisServer(), Conf_ServerInfo); return true; -} /* Config_Rehash */ - +} +/** + * Output a boolean value as "yes/no" string. + */ static const char* yesno_to_str(int boolean_value) { @@ -226,13 +240,15 @@ yesno_to_str(int boolean_value) return "no"; } - +/** + * Free all IRC operator configuration structures. + */ static void opers_free(void) { struct Conf_Oper *op; size_t len; - + len = array_length(&Conf_Opers, sizeof(*op)); op = array_start(&Conf_Opers); while (len--) { @@ -242,12 +258,15 @@ opers_free(void) array_free(&Conf_Opers); } +/** + * Output all IRC operator configuration structures. + */ static void opers_puts(void) { struct Conf_Oper *op; size_t len; - + len = array_length(&Conf_Opers, sizeof(*op)); op = array_start(&Conf_Opers); while (len--) { @@ -261,12 +280,18 @@ opers_puts(void) } } - +/** + * Read configuration, validate and output it. + * + * This function waits for a keypress of the user when stdin/stdout are valid + * tty's ("you can read our nice message and we can read in your keypress"). + * + * @return 0 on succes, 1 on failure(s); therefore the result code can + * directly be used by exit() when running "ngircd --configtest". + */ GLOBAL int Conf_Test( void ) { - /* Read configuration, validate and output it. */ - struct passwd *pwd; struct group *grp; unsigned int i; @@ -281,25 +306,20 @@ Conf_Test( void ) config_valid = Validate_Config(true, false); - /* If stdin and stdout ("you can read our nice message and we can - * read in your keypress") are valid tty's, wait for a key: */ - if( isatty( fileno( stdin )) && isatty( fileno( stdout ))) { - puts( "OK, press enter to see a dump of your service configuration ..." ); - getchar( ); - } else { - puts( "Ok, dump of your server configuration follows:\n" ); - } + /* Valid tty? */ + if(isatty(fileno(stdin)) && isatty(fileno(stdout))) { + puts("OK, press enter to see a dump of your server configuration ..."); + getchar(); + } else + puts("Ok, dump of your server configuration follows:\n"); - puts( "[GLOBAL]" ); + puts("[GLOBAL]"); printf(" Name = %s\n", Conf_ServerName); - printf(" Info = %s\n", Conf_ServerInfo); -#ifndef PAM - printf(" Password = %s\n", Conf_ServerPwd); -#endif - printf(" WebircPassword = %s\n", Conf_WebircPwd); printf(" AdminInfo1 = %s\n", Conf_ServerAdmin1); printf(" AdminInfo2 = %s\n", Conf_ServerAdmin2); printf(" AdminEMail = %s\n", Conf_ServerAdminMail); + printf(" Info = %s\n", Conf_ServerInfo); + printf(" Listen = %s\n", Conf_ListenAddress); if (Using_MotdFile) { printf(" MotdFile = %s\n", Conf_MotdFile); printf(" MotdPhrase =\n"); @@ -308,52 +328,83 @@ Conf_Test( void ) printf(" MotdPhrase = %s\n", array_bytes(&Conf_Motd) ? (const char*) array_start(&Conf_Motd) : ""); } - printf(" ChrootDir = %s\n", Conf_Chroot); +#ifndef PAM + printf(" Password = %s\n", Conf_ServerPwd); +#endif printf(" PidFile = %s\n", Conf_PidFile); - printf(" Listen = %s\n", Conf_ListenAddress); - fputs(" Ports = ", stdout); + printf(" Ports = "); ports_puts(&Conf_ListenPorts); -#ifdef SSL_SUPPORT - fputs(" SSLPorts = ", stdout); - ports_puts(&Conf_SSLOptions.ListenPorts); - if (!ConfSSL_Puts()) - config_valid = false; -#endif - - pwd = getpwuid(Conf_UID); - if (pwd) - printf(" ServerUID = %s\n", pwd->pw_name); - else - printf(" ServerUID = %ld\n", (long)Conf_UID); grp = getgrgid(Conf_GID); if (grp) printf(" ServerGID = %s\n", grp->gr_name); else printf(" ServerGID = %ld\n", (long)Conf_GID); -#ifdef SYSLOG - printf(" SyslogFacility = %s\n", - ngt_SyslogFacilityName(Conf_SyslogFacility)); -#endif + pwd = getpwuid(Conf_UID); + if (pwd) + printf(" ServerUID = %s\n", pwd->pw_name); + else + printf(" ServerUID = %ld\n", (long)Conf_UID); + puts(""); + + puts("[LIMITS]"); + printf(" ConnectRetry = %d\n", Conf_ConnectRetry); + printf(" MaxConnections = %ld\n", Conf_MaxConnections); + printf(" MaxConnectionsIP = %d\n", Conf_MaxConnectionsIP); + printf(" MaxJoins = %d\n", Conf_MaxJoins > 0 ? Conf_MaxJoins : -1); + printf(" MaxNickLength = %u\n", Conf_MaxNickLength - 1); printf(" PingTimeout = %d\n", Conf_PingTimeout); printf(" PongTimeout = %d\n", Conf_PongTimeout); - printf(" ConnectRetry = %d\n", Conf_ConnectRetry); - printf(" OperCanUseMode = %s\n", yesno_to_str(Conf_OperCanMode)); - printf(" OperServerMode = %s\n", yesno_to_str(Conf_OperServerMode)); - printf(" AllowRemoteOper = %s\n", yesno_to_str(Conf_AllowRemoteOper)); - printf(" PredefChannelsOnly = %s\n", yesno_to_str(Conf_PredefChannelsOnly)); - printf(" NoDNS = %s\n", yesno_to_str(Conf_NoDNS)); - printf(" NoIdent = %s\n", yesno_to_str(Conf_NoIdent)); - printf(" NoPAM = %s\n", yesno_to_str(Conf_NoPAM)); - printf(" NoZeroConf = %s\n", yesno_to_str(Conf_NoZeroConf)); + puts(""); + puts("[OPTIONS]"); + printf(" AllowRemoteOper = %s\n", yesno_to_str(Conf_AllowRemoteOper)); + printf(" ChrootDir = %s\n", Conf_Chroot); + printf(" CloakHost = %s\n", Conf_CloakHost); + printf(" CloakUserToNick = %s\n", yesno_to_str(Conf_CloakUserToNick)); #ifdef WANT_IPV6 printf(" ConnectIPv4 = %s\n", yesno_to_str(Conf_ConnectIPv6)); printf(" ConnectIPv6 = %s\n", yesno_to_str(Conf_ConnectIPv4)); #endif - printf(" MaxConnections = %ld\n", Conf_MaxConnections); - printf(" MaxConnectionsIP = %d\n", Conf_MaxConnectionsIP); - printf(" MaxJoins = %d\n", Conf_MaxJoins > 0 ? Conf_MaxJoins : -1); - printf(" MaxNickLength = %u\n\n", Conf_MaxNickLength - 1); + printf(" DNS = %s\n", yesno_to_str(Conf_DNS)); +#ifdef IDENT + printf(" Ident = %s\n", yesno_to_str(Conf_Ident)); +#endif + printf(" MorePrivacy = %s\n", yesno_to_str(Conf_MorePrivacy)); + printf(" NoticeAuth = %s\n", yesno_to_str(Conf_NoticeAuth)); + printf(" OperCanUseMode = %s\n", yesno_to_str(Conf_OperCanMode)); + printf(" OperServerMode = %s\n", yesno_to_str(Conf_OperServerMode)); +#ifdef PAM + printf(" PAM = %s\n", yesno_to_str(Conf_PAM)); +#endif + printf(" PredefChannelsOnly = %s\n", yesno_to_str(Conf_PredefChannelsOnly)); +#ifndef STRICT_RFC + printf(" RequireAuthPing = %s\n", yesno_to_str(Conf_AuthPing)); +#endif + printf(" ScrubCTCP = %s\n", yesno_to_str(Conf_ScrubCTCP)); +#ifdef SYSLOG + printf(" SyslogFacility = %s\n", + ngt_SyslogFacilityName(Conf_SyslogFacility)); +#endif + printf(" WebircPassword = %s\n", Conf_WebircPwd); + puts(""); + +#ifdef SSL_SUPPORT + puts("[SSL]"); + printf(" CertFile = %s\n", Conf_SSLOptions.CertFile + ? Conf_SSLOptions.CertFile : ""); + printf(" DHFile = %s\n", Conf_SSLOptions.DHFile + ? Conf_SSLOptions.DHFile : ""); + printf(" KeyFile = %s\n", Conf_SSLOptions.KeyFile + ? Conf_SSLOptions.KeyFile : ""); + if (array_bytes(&Conf_SSLOptions.KeyFilePassword)) + puts(" KeyFilePassword = "); + else + puts(" KeyFilePassword = "); + array_free_wipe(&Conf_SSLOptions.KeyFilePassword); + printf(" Ports = "); + ports_puts(&Conf_SSLOptions.ListenPorts); + puts(""); +#endif opers_puts(); @@ -393,17 +444,19 @@ Conf_Test( void ) } return (config_valid ? 0 : 1); -} /* Conf_Test */ - +} +/** + * Remove connection information from configured server. + * + * If the server is set as "once", delete it from our configuration; + * otherwise set the time for the next connection attempt. + * + * Non-server connections will be silently ignored. + */ GLOBAL void Conf_UnsetServer( CONN_ID Idx ) { - /* Set next time for next connection attempt, if this is a server - * link that is (still) configured here. If the server is set as - * "once", delete it from our configuration. - * Non-Server-Connections will be silently ignored. */ - int i; time_t t; @@ -429,26 +482,26 @@ Conf_UnsetServer( CONN_ID Idx ) Conf_Server[i].lasttry = t; } } -} /* Conf_UnsetServer */ - +} +/** + * Set connection information for specified configured server. + */ GLOBAL void Conf_SetServer( int ConfServer, CONN_ID Idx ) { - /* Set connection for specified configured server */ - assert( ConfServer > NONE ); assert( Idx > NONE ); Conf_Server[ConfServer].conn_id = Idx; -} /* Conf_SetServer */ - +} +/** + * Get index of server in configuration structure. + */ GLOBAL int Conf_GetServer( CONN_ID Idx ) { - /* Get index of server in configuration structure */ - int i = 0; assert( Idx > NONE ); @@ -457,18 +510,20 @@ Conf_GetServer( CONN_ID Idx ) if( Conf_Server[i].conn_id == Idx ) return i; } return NONE; -} /* Conf_GetServer */ - +} +/** + * Enable a server by name and adjust its port number. + * + * @returns true if a server has been enabled and now has a valid port + * number and host name for outgoing connections. + */ GLOBAL bool Conf_EnableServer( const char *Name, UINT16 Port ) { - /* Enable specified server and adjust port */ - int i; assert( Name != NULL ); - for( i = 0; i < MAX_SERVERS; i++ ) { if( strcasecmp( Conf_Server[i].name, Name ) == 0 ) { /* Gotcha! Set port and enable server: */ @@ -478,53 +533,74 @@ Conf_EnableServer( const char *Name, UINT16 Port ) } } return false; -} /* Conf_EnableServer */ - +} +/** + * Enable a server by name. + * + * The server is only usable as outgoing server, if it has set a valid port + * number for outgoing connections! + * If not, you have to use Conf_EnableServer() function to make it available. + * + * @returns true if a server has been enabled; false otherwise. + */ GLOBAL bool Conf_EnablePassiveServer(const char *Name) { - /* Enable specified server */ int i; assert( Name != NULL ); for (i = 0; i < MAX_SERVERS; i++) { - if ((strcasecmp( Conf_Server[i].name, Name ) == 0) && (Conf_Server[i].port > 0)) { + if ((strcasecmp( Conf_Server[i].name, Name ) == 0) + && (Conf_Server[i].port > 0)) { /* BINGO! Enable server */ Conf_Server[i].flags &= ~CONF_SFLAG_DISABLED; return true; } } return false; -} /* Conf_EnablePassiveServer */ - +} +/** + * Disable a server by name. + * An already established connection will be disconnected. + * + * @returns true if a server was found and has been disabled. + */ GLOBAL bool Conf_DisableServer( const char *Name ) { - /* Enable specified server and adjust port */ - int i; assert( Name != NULL ); - for( i = 0; i < MAX_SERVERS; i++ ) { if( strcasecmp( Conf_Server[i].name, Name ) == 0 ) { /* Gotcha! Disable and disconnect server: */ Conf_Server[i].flags |= CONF_SFLAG_DISABLED; - if( Conf_Server[i].conn_id > NONE ) Conn_Close( Conf_Server[i].conn_id, NULL, "Server link terminated on operator request", true); + if( Conf_Server[i].conn_id > NONE ) + Conn_Close(Conf_Server[i].conn_id, NULL, + "Server link terminated on operator request", + true); return true; } } return false; -} /* Conf_DisableServer */ - +} +/** + * Add a new remote server to our configuration. + * + * @param Name Name of the new server. + * @param Port Port number to connect to or 0 for incoming connections. + * @param Host Host name to connect to. + * @param MyPwd Password that will be sent to the peer. + * @param PeerPwd Password that must be received from the peer. + * @returns true if the new server has been added; false otherwise. + */ GLOBAL bool -Conf_AddServer( const char *Name, UINT16 Port, const char *Host, const char *MyPwd, const char *PeerPwd ) +Conf_AddServer(const char *Name, UINT16 Port, const char *Host, + const char *MyPwd, const char *PeerPwd) { - /* Add new server to configuration */ - int i; assert( Name != NULL ); @@ -548,18 +624,18 @@ Conf_AddServer( const char *Name, UINT16 Port, const char *Host, const char *MyP Conf_Server[i].flags = CONF_SFLAG_ONCE; return true; -} /* Conf_AddServer */ - +} /** - * Check if the given nick name is an service + * Check if the given nick name is an service. + * + * @returns true if the given nick name belongs to an "IRC service". */ GLOBAL bool Conf_IsService(int ConfServer, const char *Nick) { return MatchCaseInsensitive(Conf_Server[ConfServer].svs_mask, Nick); -} /* Conf_IsService */ - +} /** * Initialize configuration settings with their default values. @@ -569,50 +645,63 @@ Set_Defaults(bool InitServers) { int i; + /* Global */ strcpy(Conf_ServerName, ""); - snprintf(Conf_ServerInfo, sizeof Conf_ServerInfo, "%s %s", - PACKAGE_NAME, PACKAGE_VERSION); - strcpy(Conf_ServerPwd, ""); - strcpy(Conf_ServerAdmin1, ""); strcpy(Conf_ServerAdmin2, ""); strcpy(Conf_ServerAdminMail, ""); - + snprintf(Conf_ServerInfo, sizeof Conf_ServerInfo, "%s %s", + PACKAGE_NAME, PACKAGE_VERSION); + free(Conf_ListenAddress); + Conf_ListenAddress = NULL; + array_free(&Conf_Motd); strlcpy(Conf_MotdFile, SYSCONFDIR, sizeof(Conf_MotdFile)); strlcat(Conf_MotdFile, MOTD_FILE, sizeof(Conf_MotdFile)); - - Conf_UID = Conf_GID = 0; - strlcpy(Conf_Chroot, CHROOT_DIR, sizeof(Conf_Chroot)); + strcpy(Conf_ServerPwd, ""); strlcpy(Conf_PidFile, PID_FILE, sizeof(Conf_PidFile)); + Conf_UID = Conf_GID = 0; - free(Conf_ListenAddress); - Conf_ListenAddress = NULL; - - Conf_PingTimeout = 120; - Conf_PongTimeout = 20; + /* Limits */ Conf_ConnectRetry = 60; - Conf_NoDNS = false; - Conf_NoIdent = false; - Conf_NoPAM = false; - Conf_NoZeroConf = false; - - Conf_Oper_Count = 0; - Conf_Channel_Count = 0; - - Conf_OperCanMode = false; - Conf_OperServerMode = false; - Conf_AllowRemoteOper = false; - Conf_PredefChannelsOnly = false; - - Conf_ConnectIPv4 = true; - Conf_ConnectIPv6 = true; - Conf_MaxConnections = 0; Conf_MaxConnectionsIP = 5; Conf_MaxJoins = 10; Conf_MaxNickLength = CLIENT_NICK_LEN_DEFAULT; + Conf_PingTimeout = 120; + Conf_PongTimeout = 20; + /* Options */ + Conf_AllowRemoteOper = false; +#ifndef STRICT_RFC + Conf_AuthPing = false; +#endif + strlcpy(Conf_Chroot, CHROOT_DIR, sizeof(Conf_Chroot)); + strcpy(Conf_CloakHost, ""); + Conf_CloakUserToNick = false; + Conf_ConnectIPv4 = true; +#ifdef WANT_IPV6 + Conf_ConnectIPv6 = true; +#else + Conf_ConnectIPv6 = false; +#endif + Conf_DNS = true; +#ifdef IDENTAUTH + Conf_Ident = true; +#else + Conf_Ident = false; +#endif + Conf_MorePrivacy = false; + Conf_NoticeAuth = false; + Conf_OperCanMode = false; + Conf_OperServerMode = false; +#ifdef PAM + Conf_PAM = true; +#else + Conf_PAM = false; +#endif + Conf_PredefChannelsOnly = false; #ifdef SYSLOG + Conf_ScrubCTCP = false; #ifdef LOG_LOCAL5 Conf_SyslogFacility = LOG_LOCAL5; #else @@ -620,14 +709,22 @@ Set_Defaults(bool InitServers) #endif #endif + /* Initialize IRC operators and channels */ + Conf_Oper_Count = 0; + Conf_Channel_Count = 0; + /* Initialize server configuration structures */ if (InitServers) { for (i = 0; i < MAX_SERVERS; Init_Server_Struct(&Conf_Server[i++])); } -} /* Set_Defaults */ - +} +/** + * Get number of configured listening ports. + * + * @returns The number of ports (IPv4+IPv6) on which the server should listen. + */ static bool no_listenports(void) { @@ -638,6 +735,11 @@ no_listenports(void) return cnt == 0; } +/** + * Read MOTD ("message of the day") file. + * + * @param filename Name of the file to read. + */ static void Read_Motd(const char *filename) { @@ -649,7 +751,7 @@ Read_Motd(const char *filename) fp = fopen(filename, "r"); if (!fp) { - Log(LOG_WARNING, "Can't read MOTD file \"%s\": %s", + Config_Error(LOG_WARNING, "Can't read MOTD file \"%s\": %s", filename, strerror(errno)); return; } @@ -669,11 +771,19 @@ Read_Motd(const char *filename) fclose(fp); } +/** + * Read ngIRCd configuration file. + * + * Please note that this function uses exit(1) on fatal errors and therefore + * can result in ngIRCd terminating! + * + * @param ngircd_starting Flag indicating if ngIRCd is starting or not. + * @returns true when the configuration file has been read + * successfully; false otherwise. + */ static bool Read_Config( bool ngircd_starting ) { - /* Read configuration file. */ - char section[LINE_LEN], str[LINE_LEN], *var, *arg, *ptr; const UINT16 defaultport = 6667; int line, i, n; @@ -747,7 +857,10 @@ Read_Config( bool ngircd_starting ) /* Is this the beginning of a new section? */ if(( str[0] == '[' ) && ( str[strlen( str ) - 1] == ']' )) { strlcpy( section, str, sizeof( section )); - if( strcasecmp( section, "[GLOBAL]" ) == 0 ) + if (strcasecmp(section, "[GLOBAL]") == 0 || + strcasecmp(section, "[LIMITS]") == 0 || + strcasecmp(section, "[OPTIONS]") == 0 || + strcasecmp(section, "[SSL]") == 0) continue; if( strcasecmp( section, "[SERVER]" ) == 0 ) { @@ -783,7 +896,9 @@ Read_Config( bool ngircd_starting ) continue; } - Config_Error( LOG_ERR, "%s, line %d: Unknown section \"%s\"!", NGIRCd_ConfFile, line, section ); + Config_Error(LOG_ERR, + "%s, line %d: Unknown section \"%s\"!", + NGIRCd_ConfFile, line, section); section[0] = 0x1; } if( section[0] == 0x1 ) continue; @@ -798,11 +913,26 @@ Read_Config( bool ngircd_starting ) var = str; ngt_TrimStr( var ); arg = ptr + 1; ngt_TrimStr( arg ); - if( strcasecmp( section, "[GLOBAL]" ) == 0 ) Handle_GLOBAL( line, var, arg ); - else if( strcasecmp( section, "[OPERATOR]" ) == 0 ) Handle_OPERATOR( line, var, arg ); - else if( strcasecmp( section, "[SERVER]" ) == 0 ) Handle_SERVER( line, var, arg ); - else if( strcasecmp( section, "[CHANNEL]" ) == 0 ) Handle_CHANNEL( line, var, arg ); - else Config_Error( LOG_ERR, "%s, line %d: Variable \"%s\" outside section!", NGIRCd_ConfFile, line, var ); + if(strcasecmp(section, "[GLOBAL]") == 0) + Handle_GLOBAL(line, var, arg); + else if(strcasecmp(section, "[LIMITS]") == 0) + Handle_LIMITS(line, var, arg); + else if(strcasecmp(section, "[OPTIONS]") == 0) + Handle_OPTIONS(line, var, arg); +#ifdef SSL_SUPPORT + else if(strcasecmp(section, "[SSL]") == 0) + Handle_SSL(line, var, arg); +#endif + else if(strcasecmp(section, "[OPERATOR]") == 0) + Handle_OPERATOR(line, var, arg); + else if(strcasecmp(section, "[SERVER]") == 0) + Handle_SERVER(line, var, arg); + else if(strcasecmp(section, "[CHANNEL]") == 0) + Handle_CHANNEL(line, var, arg); + else + Config_Error(LOG_ERR, + "%s, line %d: Variable \"%s\" outside section!", + NGIRCd_ConfFile, line, var); } /* Close configuration file */ @@ -836,10 +966,23 @@ Read_Config( bool ngircd_starting ) /* No MOTD phrase configured? (re)try motd file. */ if (array_bytes(&Conf_Motd) == 0) Read_Motd(Conf_MotdFile); - return true; -} /* Read_Config */ +#ifdef SSL_SUPPORT + /* Make sure that all SSL-related files are readable */ + CheckFileReadable("CertFile", Conf_SSLOptions.CertFile); + CheckFileReadable("DHFile", Conf_SSLOptions.DHFile); + CheckFileReadable("KeyFile", Conf_SSLOptions.KeyFile); +#endif + + return true; +} +/** + * Check whether an string argument is true or false. + * + * @param Arg Input string. + * @returns true if string has been parsed as "yes"/"true"/"on". + */ static bool Check_ArgIsTrue( const char *Arg ) { @@ -848,9 +991,15 @@ Check_ArgIsTrue( const char *Arg ) if( atoi( Arg ) != 0 ) return true; return false; -} /* Check_ArgIsTrue */ - +} +/** + * Handle setting of "MaxNickLength". + * + * @param Line Line number in configuration file. + * @raram Arg Input string. + * @returns New configured maximum nick name length. + */ static unsigned int Handle_MaxNickLength(int Line, const char *Arg) { @@ -870,312 +1019,484 @@ Handle_MaxNickLength(int Line, const char *Arg) return 2; } return new; -} /* Handle_MaxNickLength */ +} + +/** + * Output a warning messages if IDENT is configured but not compiled in. + */ +static void +WarnIdent(int UNUSED Line) +{ +#ifndef IDENTAUTH + if (Conf_Ident) { + /* user has enabled ident lookups explicitly, but ... */ + Config_Error(LOG_WARNING, + "%s: line %d: \"Ident = yes\", but ngircd was built without IDENT support!", + NGIRCd_ConfFile, Line); + } +#endif +} + +/** + * Output a warning messages if IPv6 is configured but not compiled in. + */ +static void +WarnIPv6(int UNUSED Line) +{ +#ifndef WANT_IPV6 + if (Conf_ConnectIPv6) { + /* user has enabled IPv6 explicitly, but ... */ + Config_Error(LOG_WARNING, + "%s: line %d: \"ConnectIPv6 = yes\", but ngircd was built without IPv6 support!", + NGIRCd_ConfFile, Line); + } +#endif +} + +/** + * Output a warning messages if PAM is configured but not compiled in. + */ +static void +WarnPAM(int UNUSED Line) +{ +#ifndef PAM + if (Conf_PAM) { + Config_Error(LOG_WARNING, + "%s: line %d: \"PAM = yes\", but ngircd was built without PAM support!", + NGIRCd_ConfFile, Line); + } +#endif +} + +/** + * Handle legacy "NoXXX" options in [GLOBAL] section. + * + * TODO: This function and support for "NoXXX" could be removed starting + * with ngIRCd release 19 (one release after marking it "deprecated"). + * + * @param Var Variable name. + * @param Arg Argument string. + * @returns true if a NoXXX option has been processed; false otherwise. + */ +static bool +CheckLegacyNoOption(const char *Var, const char *Arg) +{ + if(strcasecmp(Var, "NoDNS") == 0) { + Conf_DNS = !Check_ArgIsTrue( Arg ); + return true; + } + if (strcasecmp(Var, "NoIdent") == 0) { + Conf_Ident = !Check_ArgIsTrue(Arg); + return true; + } + if(strcasecmp(Var, "NoPAM") == 0) { + Conf_PAM = !Check_ArgIsTrue(Arg); + return true; + } + return false; +} + +/** + * Handle deprecated legacy options in [GLOBAL] section. + * + * TODO: This function and support for these options in the [Global] section + * could be removed starting with ngIRCd release 19 (one release after + * marking it "deprecated"). + * + * @param Var Variable name. + * @param Arg Argument string. + * @returns true if a legacy option has been processed; false otherwise. + */ +static const char* +CheckLegacyGlobalOption(int Line, char *Var, char *Arg) +{ + if (strcasecmp(Var, "AllowRemoteOper") == 0 + || strcasecmp(Var, "ChrootDir") == 0 + || strcasecmp(Var, "ConnectIPv4") == 0 + || strcasecmp(Var, "ConnectIPv6") == 0 + || strcasecmp(Var, "OperCanUseMode") == 0 + || strcasecmp(Var, "OperServerMode") == 0 + || strcasecmp(Var, "PredefChannelsOnly") == 0 + || strcasecmp(Var, "SyslogFacility") == 0 + || strcasecmp(Var, "WebircPassword") == 0) { + Handle_OPTIONS(Line, Var, Arg); + return "[Options]"; + } + if (strcasecmp(Var, "ConnectRetry") == 0 + || strcasecmp(Var, "MaxConnections") == 0 + || strcasecmp(Var, "MaxConnectionsIP") == 0 + || strcasecmp(Var, "MaxJoins") == 0 + || strcasecmp(Var, "MaxNickLength") == 0 + || strcasecmp(Var, "PingTimeout") == 0 + || strcasecmp(Var, "PongTimeout") == 0) { + Handle_LIMITS(Line, Var, Arg); + return "[Limits]"; + } +#ifdef SSL_SUPPORT + if (strcasecmp(Var, "SSLCertFile") == 0 + || strcasecmp(Var, "SSLDHFile") == 0 + || strcasecmp(Var, "SSLKeyFile") == 0 + || strcasecmp(Var, "SSLKeyFilePassword") == 0 + || strcasecmp(Var, "SSLPorts") == 0) { + Handle_SSL(Line, Var + 3, Arg); + return "[SSL]"; + } +#endif + return NULL; +} + +/** + * Strip "no" prefix of a string. + * + * TODO: This function and support for "NoXXX" should be removed starting + * with ngIRCd release 19! (One release after marking it "deprecated"). + * + * @param str Pointer to input string starting with "no". + * @returns New pointer to string without "no" prefix. + */ +static const char * +NoNo(const char *str) +{ + assert(strncasecmp("no", str, 2) == 0 && str[2]); + return str + 2; +} +/** + * Invert "boolean" string. + * + * TODO: This function and support for "NoXXX" should be removed starting + * with ngIRCd release 19! (One release after marking it "deprecated"). + * + * @param arg "Boolean" input string. + * @returns Pointer to inverted "boolean string". + */ +static const char * +InvertArg(const char *arg) +{ + return yesno_to_str(!Check_ArgIsTrue(arg)); +} +/** + * Handle variable in [Global] configuration section. + * + * @param Line Line numer in configuration file. + * @param Var Variable name. + * @param Arg Variable argument. + */ static void Handle_GLOBAL( int Line, char *Var, char *Arg ) { struct passwd *pwd; struct group *grp; size_t len; - - assert( Line > 0 ); - assert( Var != NULL ); - assert( Arg != NULL ); - - if( strcasecmp( Var, "Name" ) == 0 ) { - /* Server name */ - len = strlcpy( Conf_ServerName, Arg, sizeof( Conf_ServerName )); - if (len >= sizeof( Conf_ServerName )) - Config_Error_TooLong( Line, Var ); - return; - } - if( strcasecmp( Var, "Info" ) == 0 ) { - /* Info text of server */ - len = strlcpy( Conf_ServerInfo, Arg, sizeof( Conf_ServerInfo )); - if (len >= sizeof( Conf_ServerInfo )) - Config_Error_TooLong ( Line, Var ); - return; - } - if( strcasecmp( Var, "Password" ) == 0 ) { - /* Global server password */ - len = strlcpy( Conf_ServerPwd, Arg, sizeof( Conf_ServerPwd )); - if (len >= sizeof( Conf_ServerPwd )) - Config_Error_TooLong( Line, Var ); + const char *section; + + assert(Line > 0); + assert(Var != NULL); + assert(Arg != NULL); + + if (strcasecmp(Var, "Name") == 0) { + len = strlcpy(Conf_ServerName, Arg, sizeof(Conf_ServerName)); + if (len >= sizeof(Conf_ServerName)) + Config_Error_TooLong(Line, Var); return; } - if (strcasecmp(Var, "WebircPassword") == 0) { - /* Password required for WEBIRC command */ - len = strlcpy(Conf_WebircPwd, Arg, sizeof(Conf_WebircPwd)); - if (len >= sizeof(Conf_WebircPwd)) + if (strcasecmp(Var, "AdminInfo1") == 0) { + len = strlcpy(Conf_ServerAdmin1, Arg, sizeof(Conf_ServerAdmin1)); + if (len >= sizeof(Conf_ServerAdmin1)) Config_Error_TooLong(Line, Var); return; } - if( strcasecmp( Var, "AdminInfo1" ) == 0 ) { - /* Administrative info #1 */ - len = strlcpy( Conf_ServerAdmin1, Arg, sizeof( Conf_ServerAdmin1 )); - if (len >= sizeof( Conf_ServerAdmin1 )) - Config_Error_TooLong ( Line, Var ); + if (strcasecmp(Var, "AdminInfo2") == 0) { + len = strlcpy(Conf_ServerAdmin2, Arg, sizeof(Conf_ServerAdmin2)); + if (len >= sizeof(Conf_ServerAdmin2)) + Config_Error_TooLong(Line, Var); return; } - if( strcasecmp( Var, "AdminInfo2" ) == 0 ) { - /* Administrative info #2 */ - len = strlcpy( Conf_ServerAdmin2, Arg, sizeof( Conf_ServerAdmin2 )); - if (len >= sizeof( Conf_ServerAdmin2 )) - Config_Error_TooLong ( Line, Var ); + if (strcasecmp(Var, "AdminEMail") == 0) { + len = strlcpy(Conf_ServerAdminMail, Arg, + sizeof(Conf_ServerAdminMail)); + if (len >= sizeof(Conf_ServerAdminMail)) + Config_Error_TooLong(Line, Var); return; } - if( strcasecmp( Var, "AdminEMail" ) == 0 ) { - /* Administrative email contact */ - len = strlcpy( Conf_ServerAdminMail, Arg, sizeof( Conf_ServerAdminMail )); - if (len >= sizeof( Conf_ServerAdminMail )) - Config_Error_TooLong( Line, Var ); + if (strcasecmp(Var, "Info") == 0) { + len = strlcpy(Conf_ServerInfo, Arg, sizeof(Conf_ServerInfo)); + if (len >= sizeof(Conf_ServerInfo)) + Config_Error_TooLong(Line, Var); return; } - - if( strcasecmp( Var, "Ports" ) == 0 ) { - ports_parse(&Conf_ListenPorts, Line, Arg); + if (strcasecmp(Var, "Listen") == 0) { + if (Conf_ListenAddress) { + Config_Error(LOG_ERR, + "Multiple Listen= options, ignoring: %s", + Arg); + return; + } + Conf_ListenAddress = strdup_warn(Arg); + /* If allocation fails, we're in trouble: we cannot ignore the + * error -- otherwise ngircd would listen on all interfaces. */ + if (!Conf_ListenAddress) { + Config_Error(LOG_ALERT, + "%s exiting due to fatal errors!", + PACKAGE_NAME); + exit(1); + } return; } - if( strcasecmp( Var, "MotdFile" ) == 0 ) { - len = strlcpy( Conf_MotdFile, Arg, sizeof( Conf_MotdFile )); - if (len >= sizeof( Conf_MotdFile )) - Config_Error_TooLong( Line, Var ); - Read_Motd(Arg); + if (strcasecmp(Var, "MotdFile") == 0) { + len = strlcpy(Conf_MotdFile, Arg, sizeof(Conf_MotdFile)); + if (len >= sizeof(Conf_MotdFile)) + Config_Error_TooLong(Line, Var); return; } - if( strcasecmp( Var, "MotdPhrase" ) == 0 ) { - /* "Message of the day" phrase (instead of file) */ + if (strcasecmp(Var, "MotdPhrase") == 0) { len = strlen(Arg); if (len == 0) return; if (len >= LINE_LEN) { - Config_Error_TooLong( Line, Var ); + Config_Error_TooLong(Line, Var); return; } if (!array_copyb(&Conf_Motd, Arg, len + 1)) - Config_Error(LOG_WARNING, "%s, line %d: Could not append MotdPhrase: %s", - NGIRCd_ConfFile, Line, strerror(errno)); + Config_Error(LOG_WARNING, + "%s, line %d: Could not append MotdPhrase: %s", + NGIRCd_ConfFile, Line, strerror(errno)); Using_MotdFile = false; return; } - if( strcasecmp( Var, "ChrootDir" ) == 0 ) { - /* directory for chroot() */ - len = strlcpy( Conf_Chroot, Arg, sizeof( Conf_Chroot )); - if (len >= sizeof( Conf_Chroot )) - Config_Error_TooLong( Line, Var ); + if(strcasecmp(Var, "Password") == 0) { + len = strlcpy(Conf_ServerPwd, Arg, sizeof(Conf_ServerPwd)); + if (len >= sizeof(Conf_ServerPwd)) + Config_Error_TooLong(Line, Var); return; } - if ( strcasecmp( Var, "PidFile" ) == 0 ) { - /* name of pidfile */ - len = strlcpy( Conf_PidFile, Arg, sizeof( Conf_PidFile )); - if (len >= sizeof( Conf_PidFile )) - Config_Error_TooLong( Line, Var ); + if (strcasecmp(Var, "PidFile") == 0) { + len = strlcpy(Conf_PidFile, Arg, sizeof(Conf_PidFile)); + if (len >= sizeof(Conf_PidFile)) + Config_Error_TooLong(Line, Var); return; } - if( strcasecmp( Var, "ServerUID" ) == 0 ) { - /* UID the daemon should switch to */ - pwd = getpwnam( Arg ); - if( pwd ) Conf_UID = pwd->pw_uid; + if (strcasecmp(Var, "Ports") == 0) { + ports_parse(&Conf_ListenPorts, Line, Arg); + return; + } + if (strcasecmp(Var, "ServerGID") == 0) { + grp = getgrnam(Arg); + if (grp) + Conf_GID = grp->gr_gid; else { -#ifdef HAVE_ISDIGIT - if( ! isdigit( (int)*Arg )) Config_Error_NaN( Line, Var ); - else -#endif - Conf_UID = (unsigned int)atoi( Arg ); + Conf_GID = (unsigned int)atoi(Arg); + if (!Conf_GID && strcmp(Arg, "0")) + Config_Error_NaN(Line, Var); } return; } - if( strcasecmp( Var, "ServerGID" ) == 0 ) { - /* GID the daemon should use */ - grp = getgrnam( Arg ); - if( grp ) Conf_GID = grp->gr_gid; + if (strcasecmp(Var, "ServerUID") == 0) { + pwd = getpwnam(Arg); + if (pwd) + Conf_UID = pwd->pw_uid; else { -#ifdef HAVE_ISDIGIT - if( ! isdigit( (int)*Arg )) Config_Error_NaN( Line, Var ); - else -#endif - Conf_GID = (unsigned int)atoi( Arg ); + Conf_UID = (unsigned int)atoi(Arg); + if (!Conf_UID && strcmp(Arg, "0")) + Config_Error_NaN(Line, Var); } return; } - if( strcasecmp( Var, "PingTimeout" ) == 0 ) { - /* PING timeout */ - Conf_PingTimeout = atoi( Arg ); - if( Conf_PingTimeout < 5 ) { - Config_Error( LOG_WARNING, "%s, line %d: Value of \"PingTimeout\" too low!", - NGIRCd_ConfFile, Line ); - Conf_PingTimeout = 5; - } + + if (CheckLegacyNoOption(Var, Arg)) { + /* TODO: This function and support for "NoXXX" could be + * be removed starting with ngIRCd release 19 (one release + * after marking it "deprecated"). */ + Config_Error(LOG_WARNING, + "%s, line %d (section \"Global\"): \"No\"-Prefix is deprecated, use \"%s = %s\" in [Options] section!", + NGIRCd_ConfFile, Line, NoNo(Var), InvertArg(Arg)); + if (strcasecmp(Var, "NoIdent") == 0) + WarnIdent(Line); + else if (strcasecmp(Var, "NoPam") == 0) + WarnPAM(Line); return; } - if( strcasecmp( Var, "PongTimeout" ) == 0 ) { - /* PONG timeout */ - Conf_PongTimeout = atoi( Arg ); - if( Conf_PongTimeout < 5 ) { - Config_Error( LOG_WARNING, "%s, line %d: Value of \"PongTimeout\" too low!", - NGIRCd_ConfFile, Line ); - Conf_PongTimeout = 5; + if ((section = CheckLegacyGlobalOption(Line, Var, Arg))) { + /** TODO: This function and support for these options in the + * [Global] section could be removed starting with ngIRCd + * release 19 (one release after marking it "deprecated"). */ + if (strncasecmp(Var, "SSL", 3) == 0) { + Config_Error(LOG_WARNING, + "%s, line %d (section \"Global\"): \"%s\" is deprecated here, move it to %s and rename to \"%s\"!", + NGIRCd_ConfFile, Line, Var, section, + Var + 3); + } else { + Config_Error(LOG_WARNING, + "%s, line %d (section \"Global\"): \"%s\" is deprecated here, move it to %s!", + NGIRCd_ConfFile, Line, Var, section); } return; } - if( strcasecmp( Var, "ConnectRetry" ) == 0 ) { - /* Seconds between connection attempts to other servers */ - Conf_ConnectRetry = atoi( Arg ); - if( Conf_ConnectRetry < 5 ) { - Config_Error( LOG_WARNING, "%s, line %d: Value of \"ConnectRetry\" too low!", - NGIRCd_ConfFile, Line ); + + Config_Error_Section(Line, Var, "Global"); +} + +/** + * Handle variable in [Limits] configuration section. + * + * @param Line Line numer in configuration file. + * @param Var Variable name. + * @param Arg Variable argument. + */ +static void +Handle_LIMITS(int Line, char *Var, char *Arg) +{ + assert(Line > 0); + assert(Var != NULL); + assert(Arg != NULL); + + if (strcasecmp(Var, "ConnectRetry") == 0) { + Conf_ConnectRetry = atoi(Arg); + if (Conf_ConnectRetry < 5) { + Config_Error(LOG_WARNING, + "%s, line %d: Value of \"ConnectRetry\" too low!", + NGIRCd_ConfFile, Line); Conf_ConnectRetry = 5; } return; } - if( strcasecmp( Var, "PredefChannelsOnly" ) == 0 ) { - /* Should we only allow pre-defined-channels? (i.e. users cannot create their own channels) */ - Conf_PredefChannelsOnly = Check_ArgIsTrue( Arg ); + if (strcasecmp(Var, "MaxConnections") == 0) { + Conf_MaxConnections = atol(Arg); + if (!Conf_MaxConnections && strcmp(Arg, "0")) + Config_Error_NaN(Line, Var); return; } - if( strcasecmp( Var, "NoDNS" ) == 0 ) { - /* don't do reverse dns lookups when clients connect? */ - Conf_NoDNS = Check_ArgIsTrue( Arg ); + if (strcasecmp(Var, "MaxConnectionsIP") == 0) { + Conf_MaxConnectionsIP = atoi(Arg); + if (!Conf_MaxConnectionsIP && strcmp(Arg, "0")) + Config_Error_NaN(Line, Var); return; } - if (strcasecmp(Var, "NoIdent") == 0) { - /* don't do IDENT lookups when clients connect? */ - Conf_NoIdent = Check_ArgIsTrue(Arg); -#ifndef IDENTAUTH - if (!Conf_NoIdent) { - /* user has enabled ident lookups explicitly, but ... */ + if (strcasecmp(Var, "MaxJoins") == 0) { + Conf_MaxJoins = atoi(Arg); + if (!Conf_MaxJoins && strcmp(Arg, "0")) + Config_Error_NaN(Line, Var); + return; + } + if (strcasecmp(Var, "MaxNickLength") == 0) { + Conf_MaxNickLength = Handle_MaxNickLength(Line, Arg); + return; + } + if (strcasecmp(Var, "PingTimeout") == 0) { + Conf_PingTimeout = atoi(Arg); + if (Conf_PingTimeout < 5) { Config_Error(LOG_WARNING, - "%s: line %d: NoIdent=False, but ngircd was built without IDENT support", - NGIRCd_ConfFile, Line); + "%s, line %d: Value of \"PingTimeout\" too low!", + NGIRCd_ConfFile, Line); + Conf_PingTimeout = 5; } -#endif return; } - if(strcasecmp(Var, "NoPAM") == 0) { - /* don't use PAM library to authenticate users */ - Conf_NoPAM = Check_ArgIsTrue(Arg); + if (strcasecmp(Var, "PongTimeout") == 0) { + Conf_PongTimeout = atoi(Arg); + if (Conf_PongTimeout < 5) { + Config_Error(LOG_WARNING, + "%s, line %d: Value of \"PongTimeout\" too low!", + NGIRCd_ConfFile, Line); + Conf_PongTimeout = 5; + } return; } - if(strcasecmp(Var, "NoZeroConf") == 0) { - /* don't register services using ZeroConf */ - Conf_NoZeroConf = Check_ArgIsTrue(Arg); + + Config_Error_Section(Line, Var, "Limits"); +} + +/** + * Handle variable in [Options] configuration section. + * + * @param Line Line numer in configuration file. + * @param Var Variable name. + * @param Arg Variable argument. + */ +static void +Handle_OPTIONS(int Line, char *Var, char *Arg) +{ + size_t len; + + assert(Line > 0); + assert(Var != NULL); + assert(Arg != NULL); + + if (strcasecmp(Var, "AllowRemoteOper") == 0) { + Conf_AllowRemoteOper = Check_ArgIsTrue(Arg); return; } -#ifdef WANT_IPV6 - /* the default setting for all the WANT_IPV6 special options is 'true' */ - if( strcasecmp( Var, "ConnectIPv6" ) == 0 ) { - /* connect to other hosts using ipv6, if they have an AAAA record? */ - Conf_ConnectIPv6 = Check_ArgIsTrue( Arg ); + if (strcasecmp(Var, "ChrootDir") == 0) { + len = strlcpy(Conf_Chroot, Arg, sizeof(Conf_Chroot)); + if (len >= sizeof(Conf_Chroot)) + Config_Error_TooLong(Line, Var); return; } - if( strcasecmp( Var, "ConnectIPv4" ) == 0 ) { - /* connect to other hosts using ipv4. - * again, this can be used for ipv6-only setups */ - Conf_ConnectIPv4 = Check_ArgIsTrue( Arg ); + if (strcasecmp(Var, "CloakHost") == 0) { + len = strlcpy(Conf_CloakHost, Arg, sizeof(Conf_CloakHost)); + if (len >= sizeof(Conf_CloakHost)) + Config_Error_TooLong(Line, Var); return; } -#endif - if( strcasecmp( Var, "OperCanUseMode" ) == 0 ) { - /* Are IRC operators allowed to use MODE in channels they aren't Op in? */ - Conf_OperCanMode = Check_ArgIsTrue( Arg ); + if (strcasecmp(Var, "CloakUserToNick") == 0) { + Conf_CloakUserToNick = Check_ArgIsTrue(Arg); return; } - if( strcasecmp( Var, "OperServerMode" ) == 0 ) { - /* Mask IRC operator as if coming from the server? (ircd-irc2 compat hack) */ - Conf_OperServerMode = Check_ArgIsTrue( Arg ); + if (strcasecmp(Var, "ConnectIPv6") == 0) { + Conf_ConnectIPv6 = Check_ArgIsTrue(Arg); + WarnIPv6(Line); return; } - if(strcasecmp(Var, "AllowRemoteOper") == 0) { - /* Are remote IRC operators allowed to control this server? */ - Conf_AllowRemoteOper = Check_ArgIsTrue(Arg); + if (strcasecmp(Var, "ConnectIPv4") == 0) { + Conf_ConnectIPv4 = Check_ArgIsTrue(Arg); return; } - if( strcasecmp( Var, "MaxConnections" ) == 0 ) { - /* Maximum number of connections. 0 -> "no limit". */ -#ifdef HAVE_ISDIGIT - if( ! isdigit( (int)*Arg )) Config_Error_NaN( Line, Var); - else -#endif - Conf_MaxConnections = atol( Arg ); + if (strcasecmp(Var, "DNS") == 0) { + Conf_DNS = Check_ArgIsTrue(Arg); return; } - if( strcasecmp( Var, "MaxConnectionsIP" ) == 0 ) { - /* Maximum number of simultaneous connections from one IP. 0 -> "no limit" */ -#ifdef HAVE_ISDIGIT - if( ! isdigit( (int)*Arg )) Config_Error_NaN( Line, Var ); - else -#endif - Conf_MaxConnectionsIP = atoi( Arg ); + if (strcasecmp(Var, "Ident") == 0) { + Conf_Ident = Check_ArgIsTrue(Arg); + WarnIdent(Line); return; } - if( strcasecmp( Var, "MaxJoins" ) == 0 ) { - /* Maximum number of channels a user can join. 0 -> "no limit". */ -#ifdef HAVE_ISDIGIT - if( ! isdigit( (int)*Arg )) Config_Error_NaN( Line, Var ); - else -#endif - Conf_MaxJoins = atoi( Arg ); + if (strcasecmp(Var, "MorePrivacy") == 0) { + Conf_MorePrivacy = Check_ArgIsTrue(Arg); return; } - if( strcasecmp( Var, "MaxNickLength" ) == 0 ) { - /* Maximum length of a nick name; must be same on all servers - * within the IRC network! */ - Conf_MaxNickLength = Handle_MaxNickLength(Line, Arg); + if (strcasecmp(Var, "NoticeAuth") == 0) { + Conf_NoticeAuth = Check_ArgIsTrue(Arg); return; } - - if( strcasecmp( Var, "Listen" ) == 0 ) { - /* IP-Address to bind sockets */ - if (Conf_ListenAddress) { - Config_Error(LOG_ERR, "Multiple Listen= options, ignoring: %s", Arg); - return; - } - Conf_ListenAddress = strdup_warn(Arg); - /* - * if allocation fails, we're in trouble: - * we cannot ignore the error -- otherwise ngircd - * would listen on all interfaces. - */ - if (!Conf_ListenAddress) { - Config_Error(LOG_ALERT, "%s exiting due to fatal errors!", PACKAGE_NAME); - exit(1); - } + if (strcasecmp(Var, "OperCanUseMode") == 0) { + Conf_OperCanMode = Check_ArgIsTrue(Arg); return; } - -#ifdef SSL_SUPPORT - if( strcasecmp( Var, "SSLPorts" ) == 0 ) { - ports_parse(&Conf_SSLOptions.ListenPorts, Line, Arg); + if (strcasecmp(Var, "OperServerMode") == 0) { + Conf_OperServerMode = Check_ArgIsTrue(Arg); return; } - - if( strcasecmp( Var, "SSLKeyFile" ) == 0 ) { - assert(Conf_SSLOptions.KeyFile == NULL ); - Conf_SSLOptions.KeyFile = strdup_warn(Arg); + if (strcasecmp(Var, "PAM") == 0) { + Conf_PAM = Check_ArgIsTrue(Arg); + WarnPAM(Line); return; } - if( strcasecmp( Var, "SSLCertFile" ) == 0 ) { - assert(Conf_SSLOptions.CertFile == NULL ); - Conf_SSLOptions.CertFile = strdup_warn(Arg); + if (strcasecmp(Var, "PredefChannelsOnly") == 0) { + Conf_PredefChannelsOnly = Check_ArgIsTrue(Arg); return; } - - if( strcasecmp( Var, "SSLKeyFilePassword" ) == 0 ) { - assert(array_bytes(&Conf_SSLOptions.KeyFilePassword) == 0); - if (!array_copys(&Conf_SSLOptions.KeyFilePassword, Arg)) - Config_Error( LOG_ERR, "%s, line %d (section \"Global\"): Could not copy %s: %s!", - NGIRCd_ConfFile, Line, Var, strerror(errno)); +#ifndef STRICT_RFC + if (strcasecmp(Var, "RequireAuthPing") == 0) { + Conf_AuthPing = Check_ArgIsTrue(Arg); return; } - if( strcasecmp( Var, "SSLDHFile" ) == 0 ) { - assert(Conf_SSLOptions.DHFile == NULL); - Conf_SSLOptions.DHFile = strdup_warn( Arg ); - return; - } #endif + if (strcasecmp(Var, "ScrubCTCP") == 0) { + Conf_ScrubCTCP = Check_ArgIsTrue(Arg); + return; + } #ifdef SYSLOG if (strcasecmp(Var, "SyslogFacility") == 0) { Conf_SyslogFacility = ngt_SyslogFacilityID(Arg, @@ -1183,11 +1504,73 @@ Handle_GLOBAL( int Line, char *Var, char *Arg ) return; } #endif - Config_Error(LOG_ERR, "%s, line %d (section \"Global\"): Unknown variable \"%s\"!", - NGIRCd_ConfFile, Line, Var); -} /* Handle_GLOBAL */ + if (strcasecmp(Var, "WebircPassword") == 0) { + len = strlcpy(Conf_WebircPwd, Arg, sizeof(Conf_WebircPwd)); + if (len >= sizeof(Conf_WebircPwd)) + Config_Error_TooLong(Line, Var); + return; + } + Config_Error_Section(Line, Var, "Options"); +} + +#ifdef SSL_SUPPORT +/** + * Handle variable in [SSL] configuration section. + * + * @param Line Line numer in configuration file. + * @param Var Variable name. + * @param Arg Variable argument. + */ +static void +Handle_SSL(int Line, char *Var, char *Arg) +{ + assert(Line > 0); + assert(Var != NULL); + assert(Arg != NULL); + + if (strcasecmp(Var, "CertFile") == 0) { + assert(Conf_SSLOptions.CertFile == NULL); + Conf_SSLOptions.CertFile = strdup_warn(Arg); + return; + } + if (strcasecmp(Var, "DHFile") == 0) { + assert(Conf_SSLOptions.DHFile == NULL); + Conf_SSLOptions.DHFile = strdup_warn(Arg); + return; + } + if (strcasecmp(Var, "KeyFile") == 0) { + assert(Conf_SSLOptions.KeyFile == NULL); + Conf_SSLOptions.KeyFile = strdup_warn(Arg); + return; + } + if (strcasecmp(Var, "KeyFilePassword") == 0) { + assert(array_bytes(&Conf_SSLOptions.KeyFilePassword) == 0); + if (!array_copys(&Conf_SSLOptions.KeyFilePassword, Arg)) + Config_Error(LOG_ERR, + "%s, line %d (section \"SSL\"): Could not copy %s: %s!", + NGIRCd_ConfFile, Line, Var, + strerror(errno)); + return; + } + if (strcasecmp(Var, "Ports") == 0) { + ports_parse(&Conf_SSLOptions.ListenPorts, Line, Arg); + return; + } + + Config_Error_Section(Line, Var, "SSL"); +} + +#endif + +/** + * Handle variable in [Operator] configuration section. + * + * @param Line Line numer in configuration file. + * @param Var Variable name. + * @param Arg Variable argument. + */ static void Handle_OPERATOR( int Line, char *Var, char *Arg ) { @@ -1225,17 +1608,23 @@ Handle_OPERATOR( int Line, char *Var, char *Arg ) op->mask = strdup_warn( Arg ); return; } - Config_Error( LOG_ERR, "%s, line %d (section \"Operator\"): Unknown variable \"%s\"!", - NGIRCd_ConfFile, Line, Var ); -} /* Handle_OPERATOR */ + Config_Error_Section(Line, Var, "Operator"); +} +/** + * Handle variable in [Server] configuration section. + * + * @param Line Line numer in configuration file. + * @param Var Variable name. + * @param Arg Variable argument. + */ static void Handle_SERVER( int Line, char *Var, char *Arg ) { long port; size_t len; - + assert( Line > 0 ); assert( Var != NULL ); assert( Arg != NULL ); @@ -1287,11 +1676,12 @@ Handle_SERVER( int Line, char *Var, char *Arg ) if( strcasecmp( Var, "Port" ) == 0 ) { /* Port to which this server should connect */ port = atol( Arg ); - if( port > 0 && port < 0xFFFF ) + if (port >= 0 && port < 0xFFFF) New_Server.port = (UINT16)port; else - Config_Error( LOG_ERR, "%s, line %d (section \"Server\"): Illegal port number %ld!", - NGIRCd_ConfFile, Line, port ); + Config_Error(LOG_ERR, + "%s, line %d (section \"Server\"): Illegal port number %ld!", + NGIRCd_ConfFile, Line, port ); return; } #ifdef SSL_SUPPORT @@ -1302,12 +1692,9 @@ Handle_SERVER( int Line, char *Var, char *Arg ) #endif if( strcasecmp( Var, "Group" ) == 0 ) { /* Server group */ -#ifdef HAVE_ISDIGIT - if( ! isdigit( (int)*Arg )) - Config_Error_NaN( Line, Var ); - else -#endif New_Server.group = atoi( Arg ); + if (!New_Server.group && strcmp(Arg, "0")) + Config_Error_NaN(Line, Var); return; } if( strcasecmp( Var, "Passive" ) == 0 ) { @@ -1323,11 +1710,19 @@ Handle_SERVER( int Line, char *Var, char *Arg ) return; } - Config_Error( LOG_ERR, "%s, line %d (section \"Server\"): Unknown variable \"%s\"!", - NGIRCd_ConfFile, Line, Var ); -} /* Handle_SERVER */ - + Config_Error_Section(Line, Var, "Server"); +} +/** + * Copy channel name into channel structure. + * + * If the channel name is not valid because of a missing prefix ('#', '&'), + * a default prefix of '#' will be added. + * + * @param new_chan New already allocated channel structure. + * @param name Name of the new channel. + * @returns true on success, false otherwise. + */ static bool Handle_Channelname(struct Conf_Channel *new_chan, const char *name) { @@ -1346,7 +1741,13 @@ Handle_Channelname(struct Conf_Channel *new_chan, const char *name) return size > strlcpy(dest, name, size); } - +/** + * Handle variable in [Channel] configuration section. + * + * @param Line Line numer in configuration file. + * @param Var Variable name. + * @param Arg Variable argument. + */ static void Handle_CHANNEL(int Line, char *Var, char *Arg) { @@ -1395,7 +1796,7 @@ Handle_CHANNEL(int Line, char *Var, char *Arg) if( strcasecmp( Var, "MaxUsers" ) == 0 ) { /* maximum user limit, mode l */ chan->maxusers = (unsigned long) atol(Arg); - if (chan->maxusers == 0) + if (!chan->maxusers && strcmp(Arg, "0")) Config_Error_NaN(Line, Var); return; } @@ -1407,11 +1808,19 @@ Handle_CHANNEL(int Line, char *Var, char *Arg) return; } - Config_Error( LOG_ERR, "%s, line %d (section \"Channel\"): Unknown variable \"%s\"!", - NGIRCd_ConfFile, Line, Var ); -} /* Handle_CHANNEL */ - + Config_Error_Section(Line, Var, "Channel"); +} +/** + * Validate server configuration. + * + * Please note that this function uses exit(1) on fatal errors and therefore + * can result in ngIRCd terminating! + * + * @param Configtest true if the daemon has been called with "--configtest". + * @param Rehash true if re-reading configuration on runtime. + * @returns true if configuration is valid. + */ static bool Validate_Config(bool Configtest, bool Rehash) { @@ -1491,7 +1900,7 @@ Validate_Config(bool Configtest, bool Rehash) #ifdef PAM if (Conf_ServerPwd[0]) Config_Error(LOG_ERR, - "This server uses PAM, \"Password\" will be ignored!"); + "This server uses PAM, \"Password\" in [Global] section will be ignored!"); #endif #ifdef DEBUG @@ -1509,16 +1918,40 @@ Validate_Config(bool Configtest, bool Rehash) #endif return config_valid; -} /* Validate_Config */ - +} +/** + * Output "line too long" warning. + * + * @param Line Line number in configuration file. + * @param Item Affected variable name. + */ static void Config_Error_TooLong ( const int Line, const char *Item ) { Config_Error( LOG_WARNING, "%s, line %d: Value of \"%s\" too long!", NGIRCd_ConfFile, Line, Item ); } +/** + * Output "unknown variable" warning. + * + * @param Line Line number in configuration file. + * @param Item Affected variable name. + * @param Section Section name. + */ +static void +Config_Error_Section(const int Line, const char *Item, const char *Section) +{ + Config_Error(LOG_ERR, "%s, line %d (section \"%s\"): Unknown variable \"%s\"!", + NGIRCd_ConfFile, Line, Section, Item); +} +/** + * Output "not a number" warning. + * + * @param Line Line number in configuration file. + * @param Item Affected variable name. + */ static void Config_Error_NaN( const int Line, const char *Item ) { @@ -1526,7 +1959,16 @@ Config_Error_NaN( const int Line, const char *Item ) NGIRCd_ConfFile, Line, Item ); } - +/** + * Output configuration error to console and/or logfile. + * + * On runtime, the normal log functions of the daemon are used. But when + * testing the configuration ("--configtest"), all messages go directly + * to the console. + * + * @param Level Severity level of the message. + * @param Format Format string; see printf() function. + */ #ifdef PROTOTYPES static void Config_Error( const int Level, const char *Format, ... ) #else @@ -1536,8 +1978,6 @@ const char *Format; va_dcl #endif { - /* Error! Write to console and/or logfile. */ - char msg[MAX_LOG_MSG_LEN]; va_list ap; @@ -1550,17 +1990,21 @@ va_dcl #endif vsnprintf( msg, MAX_LOG_MSG_LEN, Format, ap ); va_end( ap ); - - /* During "normal operations" the log functions of the daemon should - * be used, but during testing of the configuration file, all messages - * should go directly to the console: */ - if (Use_Log) Log( Level, "%s", msg ); - else puts( msg ); -} /* Config_Error */ + if (!Use_Log) { + if (Level <= LOG_WARNING) + printf(" - %s\n", msg); + else + puts(msg); + } else + Log(Level, "%s", msg); +} #ifdef DEBUG +/** + * Dump internal state of the "configuration module". + */ GLOBAL void Conf_DebugDump(void) { @@ -1577,16 +2021,18 @@ Conf_DebugDump(void) Conf_Server[i].group, Conf_Server[i].flags, Conf_Server[i].conn_id); } -} /* Conf_DebugDump */ +} #endif - +/** + * Initialize server configuration structur to default values. + * + * @param Server Pointer to server structure to initialize. + */ static void Init_Server_Struct( CONF_SERVER *Server ) { - /* Initialize server configuration structur to default values */ - assert( Server != NULL ); memset( Server, 0, sizeof (CONF_SERVER) ); @@ -1599,7 +2045,6 @@ Init_Server_Struct( CONF_SERVER *Server ) Proc_InitStruct(&Server->res_stat); Server->conn_id = NONE; memset(&Server->bind_addr, 0, sizeof(&Server->bind_addr)); -} /* Init_Server_Struct */ - +} /* -eof- */ diff --git a/src/ngircd/conf.h b/src/ngircd/conf.h index 47a499a..afc0afa 100644 --- a/src/ngircd/conf.h +++ b/src/ngircd/conf.h @@ -1,20 +1,22 @@ /* * ngIRCd -- The Next Generation IRC Daemon - * Copyright (c)2001-2010 Alexander Barton (alex@barton.de) + * 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 * 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. - * - * Configuration management (header) */ - #ifndef __conf_h__ #define __conf_h__ +/** + * @file + * Configuration management (header) + */ + #include #include "defines.h" @@ -25,54 +27,66 @@ #include "proc.h" #include "conf-ssl.h" - +/** + * Configured IRC operator. + * Please note the the name of the IRC operaor and his nick have nothing to + * do with each other! The IRC operator is only identified by the name and + * password configured in this structure. + */ struct Conf_Oper { - char name[CLIENT_PASS_LEN]; /* Name (ID) of IRC operator */ - char pwd[CLIENT_PASS_LEN]; /* Password */ - char *mask; /* allowed host mask */ + char name[CLIENT_PASS_LEN]; /**< Name (ID) */ + char pwd[CLIENT_PASS_LEN]; /**< Password */ + char *mask; /**< Allowed host mask */ }; +/** + * Configured server. + * Peers to which this daemon should establish an outgoing server link must + * have set a port number; all other servers are allowed to connect to this one. + */ typedef struct _Conf_Server { - char host[HOST_LEN]; /* Hostname */ - char name[CLIENT_ID_LEN]; /* IRC-Client-ID */ - char pwd_in[CLIENT_PASS_LEN]; /* Password which must be received */ - char pwd_out[CLIENT_PASS_LEN]; /* Password to send to peer */ - UINT16 port; /* Server port */ - int group; /* Group of server */ - time_t lasttry; /* Last connect attempt */ - PROC_STAT res_stat; /* Status of the resolver */ - int flags; /* Flags */ - CONN_ID conn_id; /* ID of server connection or NONE */ - ng_ipaddr_t bind_addr; /* source address to use for outgoing - connections */ - ng_ipaddr_t dst_addr[2]; /* list of addresses to connect to */ + char host[HOST_LEN]; /**< Hostname */ + char name[CLIENT_ID_LEN]; /**< IRC client ID */ + char pwd_in[CLIENT_PASS_LEN]; /**< Password which must be received */ + char pwd_out[CLIENT_PASS_LEN]; /**< Password to send to the peer */ + UINT16 port; /**< Server port to connect to */ + int group; /**< Group ID of this server */ + time_t lasttry; /**< Time of last connection attempt */ + PROC_STAT res_stat; /**< Status of the resolver */ + int flags; /**< Server flags */ + CONN_ID conn_id; /**< ID of server connection or NONE */ + ng_ipaddr_t bind_addr; /**< Source address to use for outgoing + connections */ + ng_ipaddr_t dst_addr[2]; /**< List of addresses to connect to */ #ifdef SSL_SUPPORT - bool SSLConnect; /* connect() using SSL? */ + bool SSLConnect; /**< Establish connection using SSL? */ #endif - char svs_mask[CLIENT_ID_LEN]; /* Mask of nick names that are - services */ + char svs_mask[CLIENT_ID_LEN]; /**< Mask of nick names that should be + treated and counted as services */ } CONF_SERVER; #ifdef SSL_SUPPORT +/** Configuration options required for SSL support */ struct SSLOptions { - char *KeyFile; - char *CertFile; - char *DHFile; - array ListenPorts; - array KeyFilePassword; + char *KeyFile; /**< SSL key file */ + char *CertFile; /**< SSL certificate file */ + char *DHFile; /**< File containing DH parameters */ + array ListenPorts; /**< Array of listening SSL ports */ + array KeyFilePassword; /**< Key file password */ }; #endif +/** Pre-defined channels */ struct Conf_Channel { - char name[CHANNEL_NAME_LEN]; /* Name of the channel */ - char modes[CHANNEL_MODE_LEN]; /* Initial channel modes */ - char key[CLIENT_PASS_LEN]; /* Channel key ("password", mode "k" ) */ - char topic[COMMAND_LEN]; /* Initial topic */ - char keyfile[512]; /* Path and name of channel key file */ - unsigned long maxusers; /* maximum usercount for this channel, mode "l" */ + char name[CHANNEL_NAME_LEN]; /**< Name of the channel */ + char modes[CHANNEL_MODE_LEN]; /**< Initial channel modes */ + char key[CLIENT_PASS_LEN]; /**< Channel key ("password", mode "k" ) */ + char topic[COMMAND_LEN]; /**< Initial topic */ + char keyfile[512]; /**< Path and name of channel key file */ + unsigned long maxusers; /**< User limit for this channel, mode "l" */ }; @@ -80,80 +94,98 @@ struct Conf_Channel { #define CONF_SFLAG_DISABLED 2 /* This server configuration entry is disabled */ -/* Name ("Nick") of the servers */ +/** Name (ID, "nick") of this server */ GLOBAL char Conf_ServerName[CLIENT_ID_LEN]; -/* Server info text */ +/** Server info text */ GLOBAL char Conf_ServerInfo[CLIENT_INFO_LEN]; -/* Global server passwort */ +/** Global server passwort */ GLOBAL char Conf_ServerPwd[CLIENT_PASS_LEN]; -/* Administrative information */ +/** Administrative information */ GLOBAL char Conf_ServerAdmin1[CLIENT_INFO_LEN]; GLOBAL char Conf_ServerAdmin2[CLIENT_INFO_LEN]; GLOBAL char Conf_ServerAdminMail[CLIENT_INFO_LEN]; -/* Message of the Day */ +/** Message of the day (MOTD) of this server */ GLOBAL array Conf_Motd; -/* Ports the server should listen on */ +/** Array of ports this server should listen on */ GLOBAL array Conf_ListenPorts; -/* Address to which the socket should be bound or empty (=all) */ +/** Address to which sockets should be bound to or empty (=all) */ GLOBAL char *Conf_ListenAddress; -/* User and group ID the server should run with */ +/** User and group ID this daemon should run with */ GLOBAL uid_t Conf_UID; GLOBAL gid_t Conf_GID; -/* A directory to chroot() in */ +/** The directory to chroot() into */ GLOBAL char Conf_Chroot[FNAME_LEN]; -/* File with PID of daemon */ +/** Full path and name of a file to which the PID of daemon should be written */ GLOBAL char Conf_PidFile[FNAME_LEN]; -/* Timeouts for PING and PONG */ +/** Timeout (in seconds) for PING commands */ GLOBAL int Conf_PingTimeout; + +/** Timeout (in seconds) for PONG replies */ GLOBAL int Conf_PongTimeout; -/* Seconds between connect attempts to other servers */ +/** Seconds between connection attempts to other servers */ GLOBAL int Conf_ConnectRetry; -/* Operators */ +/** Array of configured IRC operators */ GLOBAL array Conf_Opers; -/* Servers */ +/** Array of configured IRC servers */ GLOBAL CONF_SERVER Conf_Server[MAX_SERVERS]; -/* Pre-defined channels */ +/** Array of pre-defined channels */ GLOBAL array Conf_Channels; -/* Pre-defined channels only */ +/** Flag indicating if only pre-defined channels are allowed (true) or not */ GLOBAL bool Conf_PredefChannelsOnly; -/* Are IRC operators allowed to always use MODE? */ +/** Flag indicating if IRC operators are allowed to always use MODE (true) */ GLOBAL bool Conf_OperCanMode; -/* If an IRC op gives chanop privileges without being a chanop, - * ircd2 will ignore the command. This enables a workaround: - * It masks the command as coming from the server */ +/** + * If true, mask channel MODE commands of IRC operators to the server. + * Background: ircd2 will ignore channel MODE commands if an IRC operator + * gives chanel operator privileges to someone without being a channel operator + * himself. This enables a workaround: it masks the MODE command as coming + * from the IRC server and not the IRC operator. + */ GLOBAL bool Conf_OperServerMode; -/* Are remote IRC operators allowed to manage this server? */ +/** Flag indicating if remote IRC operators are allowed to manage this server */ GLOBAL bool Conf_AllowRemoteOper; -/* Disable all DNS functions? */ -GLOBAL bool Conf_NoDNS; +/** Cloaked hostname of the clients */ +GLOBAL char Conf_CloakHost[CLIENT_ID_LEN]; + +/** Use nick name as user name? */ +GLOBAL bool Conf_CloakUserToNick; + +/** Enable all DNS functions? */ +GLOBAL bool Conf_DNS; + +/** Enable IDENT lookups, even when compiled with support for it */ +GLOBAL bool Conf_Ident; + +/** Enable "more privacy" mode and "censor" some user-related information */ +GLOBAL bool Conf_MorePrivacy; -/* Disable IDENT lookups, even when compiled with support for it */ -GLOBAL bool Conf_NoIdent; +/** Enable NOTICE AUTH messages on connect */ +GLOBAL bool Conf_NoticeAuth; -/* Disable all usage of PAM, even when compiled with support for it */ -GLOBAL bool Conf_NoPAM; +/** Enable all usage of PAM, even when compiled with support for it */ +GLOBAL bool Conf_PAM; -/* Disable service registration using "ZeroConf" */ -GLOBAL bool Conf_NoZeroConf; +/** Disable all CTCP commands except for /me ? */ +GLOBAL bool Conf_ScrubCTCP; /* * try to connect to remote systems using the ipv6 protocol, @@ -161,21 +193,28 @@ GLOBAL bool Conf_NoZeroConf; */ GLOBAL bool Conf_ConnectIPv6; -/* same as above, but for ipv4 hosts, default: yes */ +/** Try to connect to remote systems using the IPv4 protocol (true) */ GLOBAL bool Conf_ConnectIPv4; -/* Maximum number of connections to this server */ +/** Maximum number of simultaneous connections to this server */ GLOBAL long Conf_MaxConnections; -/* Maximum number of channels a user can join */ +/** Maximum number of channels a user can join */ GLOBAL int Conf_MaxJoins; -/* Maximum number of connections per IP address */ +/** Maximum number of connections per IP address */ GLOBAL int Conf_MaxConnectionsIP; -/* Maximum length of a nick name */ +/** Maximum length of a nick name */ GLOBAL unsigned int Conf_MaxNickLength; +#ifndef STRICT_RFC + +/** Require "AUTH PING-PONG" on login */ +GLOBAL bool Conf_AuthPing; + +#endif + #ifdef SYSLOG /* Syslog "facility" */ diff --git a/src/ngircd/conn-func.c b/src/ngircd/conn-func.c index 15bc7cc..8b0b6f7 100644 --- a/src/ngircd/conn-func.c +++ b/src/ngircd/conn-func.c @@ -7,15 +7,17 @@ * 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. - * - * Connection management: Global functions */ - #define CONN_MODULE #include "portab.h" +/** + * @file + * Connection management: Global functions + */ + #include "imp.h" #include #include diff --git a/src/ngircd/conn-func.h b/src/ngircd/conn-func.h index d504592..729860e 100644 --- a/src/ngircd/conn-func.h +++ b/src/ngircd/conn-func.h @@ -7,14 +7,15 @@ * 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. - * - * Connection management: Global functions (header) */ - #ifndef __conn_func_h__ #define __conn_func_h__ +/** + * @file + * Connection management: Global functions (header) + */ /* Include the header conn.h if this header is _not_ included by any module * containing connection handling functions. So other modules must only diff --git a/src/ngircd/conn-ssl.c b/src/ngircd/conn-ssl.c index 6a0404f..ffb1b10 100644 --- a/src/ngircd/conn-ssl.c +++ b/src/ngircd/conn-ssl.c @@ -1,11 +1,15 @@ /* * ngIRCd -- The Next Generation IRC Daemon - * - * SSL wrapper functions. * Copyright (c) 2005-2008 Florian Westphal */ #include "portab.h" + +/** + * @file + * SSL wrapper functions + */ + #include "imp.h" #include "conf-ssl.h" @@ -47,10 +51,11 @@ static bool ConnSSL_LoadServerKey_openssl PARAMS(( SSL_CTX *c )); #include #include -#define DH_BITS 1024 +#define DH_BITS 2048 +#define DH_BITS_MIN 1024 + static gnutls_certificate_credentials_t x509_cred; static gnutls_dh_params_t dh_params; - static bool ConnSSL_LoadServerKey_gnutls PARAMS(( void )); #endif @@ -422,7 +427,7 @@ ConnSSL_Init_SSL(CONNECTION *c) ConnSSL_Free(c); return false; } - gnutls_dh_set_prime_bits(c->ssl_state.gnutls_session, DH_BITS); + gnutls_dh_set_prime_bits(c->ssl_state.gnutls_session, DH_BITS_MIN); #endif Conn_OPTION_ADD(c, CONN_SSL); return true; diff --git a/src/ngircd/conn-ssl.h b/src/ngircd/conn-ssl.h index 4cb1bde..aea0846 100644 --- a/src/ngircd/conn-ssl.h +++ b/src/ngircd/conn-ssl.h @@ -1,11 +1,15 @@ /* * ngIRCd -- The Next Generation IRC Daemon - * SSL wrapper functions. (header) */ #ifndef conn_ssl_h #define conn_ssl_h +/** + * @file + * SSL wrapper functions (header) + */ + #include "conf-ssl.h" #include "conn.h" #include "conf.h" diff --git a/src/ngircd/conn-zip.c b/src/ngircd/conn-zip.c index 24577ed..0a3c17c 100644 --- a/src/ngircd/conn-zip.c +++ b/src/ngircd/conn-zip.c @@ -7,12 +7,15 @@ * 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. - * - * Connection compression using ZLIB */ #include "portab.h" +/** + * @file + * Connection compression using ZLIB + */ + #define CONN_MODULE #ifdef ZLIB @@ -105,8 +108,8 @@ Zip_Buffer( CONN_ID Idx, const char *Data, size_t Len ) * otherwise the zip wbuf would grow too large */ buflen = array_bytes(&My_Connections[Idx].zip.wbuf); if (buflen + Len >= WRITEBUFFER_SLINK_LEN) { - Log(LOG_ALERT, "Zip Write Buffer overflow: %lu bytes\n", buflen + Len); - Conn_Close(Idx, "Zip Write buffer overflow", NULL, false); + Log(LOG_ALERT, "Zip Write buffer space exhausted: %lu bytes", buflen + Len); + Conn_Close(Idx, "Zip Write buffer space exhausted", NULL, false); return false; } return array_catb(&My_Connections[Idx].zip.wbuf, Data, Len); @@ -155,7 +158,7 @@ Zip_Flush( CONN_ID Idx ) if (out->avail_out <= 0) { /* Not all data was compressed, because data became * bigger while compressing it. */ - Log (LOG_ALERT, "Compression error: buffer overvlow!?"); + Log(LOG_ALERT, "Compression error: buffer overflow!?"); Conn_Close(Idx, "Compression error!", NULL, false); return false; } diff --git a/src/ngircd/conn-zip.h b/src/ngircd/conn-zip.h index 08abb50..573f45b 100644 --- a/src/ngircd/conn-zip.h +++ b/src/ngircd/conn-zip.h @@ -7,18 +7,17 @@ * 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. - * - * $Id: conn-zip.h,v 1.4 2006/05/10 21:24:01 alex Exp $ - * - * Connection compression using ZLIB (header) */ - #ifdef ZLIB #ifndef __conn_zip_h__ #define __conn_zip_h__ +/** + * @file + * Connection compression using ZLIB (header) + */ GLOBAL bool Zip_InitConn PARAMS(( CONN_ID Idx )); @@ -29,10 +28,8 @@ GLOBAL bool Unzip_Buffer PARAMS(( CONN_ID Idx )); GLOBAL long Zip_SendBytes PARAMS(( CONN_ID Idx )); GLOBAL long Zip_RecvBytes PARAMS(( CONN_ID Idx )); - #endif /* __conn_zip_h__ */ #endif /* ZLIB */ - /* -eof- */ diff --git a/src/ngircd/conn.c b/src/ngircd/conn.c index 9daca85..3350e20 100644 --- a/src/ngircd/conn.c +++ b/src/ngircd/conn.c @@ -7,17 +7,19 @@ * 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. - * - * Connection management */ - #define CONN_MODULE #include "portab.h" #include "conf-ssl.h" #include "io.h" +/** + * @file + * Connection management + */ + #include "imp.h" #include #ifdef PROTOTYPES @@ -71,10 +73,6 @@ #include "resolve.h" #include "tool.h" -#ifdef ZEROCONF -# include "rendezvous.h" -#endif - #include "exp.h" @@ -82,6 +80,7 @@ #define MAX_COMMANDS 3 #define MAX_COMMANDS_SERVER 10 +#define MAX_COMMANDS_SERVICE MAX_COMMANDS_SERVER static bool Handle_Write PARAMS(( CONN_ID Idx )); @@ -124,8 +123,9 @@ static void cb_clientserver PARAMS((int sock, short what)); /** * IO callback for listening sockets: handle new connections. This callback * gets called when a new non-SSL connection should be accepted. - * @param sock Socket descriptor - * @param irrelevant (ignored IO specification) + * + * @param sock Socket descriptor. + * @param irrelevant (ignored IO specification) */ static void cb_listen(int sock, short irrelevant) @@ -139,8 +139,9 @@ cb_listen(int sock, short irrelevant) /** * IO callback for listening SSL sockets: handle new connections. This callback * gets called when a new SSL-enabled connection should be accepted. - * @param sock Socket descriptor - * @param irrelevant (ignored IO specification) + * + * @param sock Socket descriptor. + * @param irrelevant (ignored IO specification) */ static void cb_listen_ssl(int sock, short irrelevant) @@ -158,8 +159,9 @@ cb_listen_ssl(int sock, short irrelevant) /** * IO callback for new outgoing non-SSL server connections. - * @param sock Socket descriptor - * @param what IO specification (IO_WANTREAD/IO_WANTWRITE/...) + * + * @param sock Socket descriptor. + * @param what IO specification (IO_WANTREAD/IO_WANTWRITE/...). */ static void cb_connserver(int sock, UNUSED short what) @@ -236,13 +238,16 @@ cb_connserver(int sock, UNUSED short what) /** * Login to a remote server. - * @param idx Connection index + * + * @param idx Connection index. */ static void server_login(CONN_ID idx) { - Log( LOG_INFO, "Connection %d with \"%s:%d\" established. Now logging in ...", idx, - My_Connections[idx].host, Conf_Server[Conf_GetServer( idx )].port ); + Log(LOG_INFO, + "Connection %d (socket %d) with \"%s:%d\" established. Now logging in ...", + idx, My_Connections[idx].sock, My_Connections[idx].host, + Conf_Server[Conf_GetServer(idx)].port); io_event_setcb( My_Connections[idx].sock, cb_clientserver); io_event_add( My_Connections[idx].sock, IO_WANTREAD|IO_WANTWRITE); @@ -256,8 +261,9 @@ server_login(CONN_ID idx) #ifdef SSL_SUPPORT /** * IO callback for new outgoing SSL-enabled server connections. - * @param sock Socket descriptor - * @param what IO specification (IO_WANTREAD/IO_WANTWRITE/...) + * + * @param sock Socket descriptor. + * @param unused (ignored IO specification) */ static void cb_connserver_login_ssl(int sock, short unused) @@ -290,8 +296,9 @@ cb_connserver_login_ssl(int sock, short unused) /** * IO callback for established non-SSL client and server connections. - * @param sock Socket descriptor - * @param what IO specification (IO_WANTREAD/IO_WANTWRITE/...) + * + * @param sock Socket descriptor. + * @param what IO specification (IO_WANTREAD/IO_WANTWRITE/...). */ static void cb_clientserver(int sock, short what) @@ -323,8 +330,9 @@ cb_clientserver(int sock, short what) #ifdef SSL_SUPPORT /** * IO callback for established SSL-enabled client and server connections. - * @param sock Socket descriptor - * @param what IO specification (IO_WANTREAD/IO_WANTWRITE/...) + * + * @param sock Socket descriptor. + * @param what IO specification (IO_WANTREAD/IO_WANTWRITE/...). */ static void cb_clientserver_ssl(int sock, short what) @@ -436,6 +444,14 @@ Conn_CloseAllSockets(void) } +/** + * Initialize listening ports. + * + * @param a Array containing the ports the daemon should listen on. + * @param listen_addr Address the socket should listen on (can be "0.0.0.0"). + * @param func IO callback function to register. + * @returns Number of listening sockets created. + */ static unsigned int ports_initlisteners(array *a, const char *listen_addr, void (*func)(int,short)) { @@ -468,7 +484,8 @@ ports_initlisteners(array *a, const char *listen_addr, void (*func)(int,short)) /** * Initialize all listening sockets. - * @return Number of created listening sockets + * + * @returns Number of created listening sockets */ GLOBAL unsigned int Conn_InitListeners( void ) @@ -509,15 +526,15 @@ Conn_InitListeners( void ) } /* Conn_InitListeners */ +/** + * Shut down all listening sockets. + */ GLOBAL void Conn_ExitListeners( void ) { /* Close down all listening sockets */ int *fd; size_t arraylen; -#ifdef ZEROCONF - Rendezvous_UnregisterListeners( ); -#endif arraylen = array_length(&My_Listeners, sizeof (int)); Log(LOG_INFO, @@ -534,6 +551,14 @@ Conn_ExitListeners( void ) } /* Conn_ExitListeners */ +/** + * Bind a socket to a specific (source) address. + * + * @param addr Address structure. + * @param listen_addrstr Source address as string. + * @param Port Port number. + * @returns true on success, false otherwise. + */ static bool InitSinaddrListenAddr(ng_ipaddr_t *addr, const char *listen_addrstr, UINT16 Port) { @@ -549,6 +574,14 @@ InitSinaddrListenAddr(ng_ipaddr_t *addr, const char *listen_addrstr, UINT16 Port } +/** + * Set a socket to "IPv6 only". If the given socket doesn't belong to the + * AF_INET6 family, or the operating system doesn't support this functionality, + * this function retruns silently. + * + * @param af Address family of the socket. + * @param sock Socket handle. + */ static void set_v6_only(int af, int sock) { @@ -567,16 +600,20 @@ set_v6_only(int af, int sock) } -/* return new listening port file descriptor or -1 on failure */ +/** + * Initialize new listening port. + * + * @param listen_addr Local address to bind the socet to (can be 0.0.0.0). + * @param Port Port number on which the new socket should be listening. + * @returns file descriptor of the socket or -1 on failure. + */ static int NewListener(const char *listen_addr, UINT16 Port) { /* Create new listening socket on specified port */ ng_ipaddr_t addr; int sock, af; -#ifdef ZEROCONF - char name[CLIENT_ID_LEN], *info; -#endif + if (!InitSinaddrListenAddr(&addr, listen_addr, Port)) return -1; @@ -612,44 +649,17 @@ NewListener(const char *listen_addr, UINT16 Port) return -1; } - Log(LOG_INFO, "Now listening on [%s]:%d (socket %d).", ng_ipaddr_tostr(&addr), Port, sock); - -#ifdef ZEROCONF - /* Get best server description text */ - if( ! Conf_ServerInfo[0] ) info = Conf_ServerName; - else - { - /* Use server info string */ - info = NULL; - if( Conf_ServerInfo[0] == '[' ) - { - /* Cut off leading hostname part in "[]" */ - info = strchr( Conf_ServerInfo, ']' ); - if( info ) - { - info++; - while( *info == ' ' ) info++; - } - } - if( ! info ) info = Conf_ServerInfo; - } - - /* Add port number to description if non-standard */ - if (Port != 6667) - snprintf(name, sizeof name, "%s (port %u)", info, - (unsigned int)Port); - else - strlcpy(name, info, sizeof name); - - /* Register service */ - Rendezvous_Register( name, MDNS_TYPE, Port ); -#endif + Log(LOG_INFO, "Now listening on [%s]:%d (socket %d).", + ng_ipaddr_tostr(&addr), Port, sock); return sock; } /* NewListener */ #ifdef SSL_SUPPORT -/* + +/** + * Check if SSL library needs to read SSL-protocol related data. + * * SSL/TLS connections require extra treatment: * When either CONN_SSL_WANT_WRITE or CONN_SSL_WANT_READ is set, we * need to take care of that first, before checking read/write buffers. @@ -660,6 +670,9 @@ NewListener(const char *listen_addr, UINT16 Port) * If this function returns true, such a condition is met and we have * to reverse the condition (check for read even if we've data to write, * do not check for read but writeability even if write-buffer is empty). + * + * @param c Connection to check. + * @returns true if SSL-library has to read protocol data. */ static bool SSL_WantRead(const CONNECTION *c) @@ -670,6 +683,15 @@ SSL_WantRead(const CONNECTION *c) } return false; } + +/** + * Check if SSL library needs to write SSL-protocol related data. + * + * Please see description of SSL_WantRead() for full description! + * + * @param c Connection to check. + * @returns true if SSL-library has to write protocol data. + */ static bool SSL_WantWrite(const CONNECTION *c) { @@ -679,18 +701,23 @@ SSL_WantWrite(const CONNECTION *c) } return false; } + #else + static inline bool SSL_WantRead(UNUSED const CONNECTION *c) { return false; } + static inline bool SSL_WantWrite(UNUSED const CONNECTION *c) { return false; } + #endif /** * "Main Loop": Loop until shutdown or restart is signalled. + * * This function loops until a shutdown or restart of ngIRCd is signalled and * calls io_dispatch() to check for readable and writable sockets every second. * It checks for status changes on pending connections (e. g. when a hostname @@ -708,10 +735,6 @@ Conn_Handler(void) while (!NGIRCd_SignalQuit && !NGIRCd_SignalRestart) { t = time(NULL); -#ifdef ZEROCONF - Rendezvous_Handler(); -#endif - /* Check configured servers and established links */ Check_Servers(); Check_Connections(); @@ -814,12 +837,14 @@ Conn_Handler(void) /** * Write a text string into the socket of a connection. + * * This function automatically appends CR+LF to the string and validates that * the result is a valid IRC message (oversized messages are shortened, for * example). Then it calls the Conn_Write() function to do the actual sending. - * @param Idx Index fo the connection. - * @param Format Format string, see printf(). - * @return true on success, false otherwise. + * + * @param Idx Index fo the connection. + * @param Format Format string, see printf(). + * @returns true on success, false otherwise. */ #ifdef PROTOTYPES GLOBAL bool @@ -889,16 +914,17 @@ va_dcl /** * Append Data to the outbound write buffer of a connection. - * @param Idx Index of the connection. - * @param Data pointer to the data. - * @param Len length of Data. - * @return true on success, false otherwise. + * + * @param Idx Index of the connection. + * @param Data pointer to the data. + * @param Len length of Data. + * @returns true on success, false otherwise. */ static bool Conn_Write( CONN_ID Idx, char *Data, size_t Len ) { CLIENT *c; - size_t writebuf_limit = WRITEBUFFER_LEN; + size_t writebuf_limit = WRITEBUFFER_MAX_LEN; assert( Idx > NONE ); assert( Data != NULL ); assert( Len > 0 ); @@ -934,7 +960,7 @@ Conn_Write( CONN_ID Idx, char *Data, size_t Len ) /* Uncompressed link: * Check if outbound buffer has enough space for the data. */ if (array_bytes(&My_Connections[Idx].wbuf) + Len >= - writebuf_limit) { + WRITEBUFFER_FLUSH_LEN) { /* Buffer is full, flush it. Handle_Write deals with * low-level errors, if any. */ if (!Handle_Write(Idx)) @@ -946,10 +972,10 @@ Conn_Write( CONN_ID Idx, char *Data, size_t Len ) if (array_bytes(&My_Connections[Idx].wbuf) + Len >= writebuf_limit) { Log(LOG_NOTICE, - "Write buffer overflow (connection %d, size %lu byte)!", - Idx, + "Write buffer space exhausted (connection %d, limit is %lu bytes, %lu bytes new, %lu bytes pending)", + Idx, writebuf_limit, Len, (unsigned long)array_bytes(&My_Connections[Idx].wbuf)); - Conn_Close(Idx, "Write buffer overflow!", NULL, false); + Conn_Close(Idx, "Write buffer space exhausted", NULL, false); return false; } @@ -967,6 +993,17 @@ Conn_Write( CONN_ID Idx, char *Data, size_t Len ) } /* Conn_Write */ +/** + * Shut down a connection. + * + * @param Idx Connection index. + * @param LogMsg Message to write to the log or NULL. If no LogMsg + * is given, the FwdMsg is logged. + * @param FwdMsg Message to forward to remote servers. + * @param InformClient If true, inform the client on the connection which is + * to be shut down of the reason (FwdMsg) and send + * connection statistics before disconnecting it. + */ GLOBAL void Conn_Close( CONN_ID Idx, const char *LogMsg, const char *FwdMsg, bool InformClient ) { @@ -1020,7 +1057,7 @@ Conn_Close( CONN_ID Idx, const char *LogMsg, const char *FwdMsg, bool InformClie if (FwdMsg) Conn_WriteStr(Idx, "ERROR :%s", FwdMsg); else - Conn_WriteStr(Idx, "ERROR :Closing connection."); + Conn_WriteStr(Idx, "ERROR :Closing connection"); } /* Try to write out the write buffer. Note: Handle_Write() eventually @@ -1111,6 +1148,11 @@ Conn_Close( CONN_ID Idx, const char *LogMsg, const char *FwdMsg, bool InformClie } /* Conn_Close */ +/** + * Get current number of connections. + * + * @returns Number of current connections. + */ GLOBAL long Conn_Count(void) { @@ -1118,6 +1160,11 @@ Conn_Count(void) } /* Conn_Count */ +/** + * Get number of maximum simultaneous connections. + * + * @returns Number of maximum simultaneous connections. + */ GLOBAL long Conn_CountMax(void) { @@ -1125,6 +1172,11 @@ Conn_CountMax(void) } /* Conn_CountMax */ +/** + * Get number of connections accepted since the daemon startet. + * + * @returns Number of connections accepted. + */ GLOBAL long Conn_CountAccepted(void) { @@ -1166,6 +1218,9 @@ Conn_SyncServerStruct(void) /** * Send out data of write buffer; connect new sockets. + * + * @param Idx Connection index. + * @returns true on success, false otherwise. */ static bool Handle_Write( CONN_ID Idx ) @@ -1230,6 +1285,11 @@ Handle_Write( CONN_ID Idx ) } /* Handle_Write */ +/** + * Count established connections to a specific IP address. + * + * @returns Number of established connections. + */ static int Count_Connections(ng_ipaddr_t *a) { @@ -1248,8 +1308,9 @@ Count_Connections(ng_ipaddr_t *a) /** * Initialize new client connection on a listening socket. - * @param Sock Listening socket descriptor - * @return Accepted socket descriptor or -1 on error + * + * @param Sock Listening socket descriptor. + * @returns Accepted socket descriptor or -1 on error. */ static int New_Connection(int Sock) @@ -1316,7 +1377,7 @@ New_Connection(int Sock) "Refused connection from %s: too may connections (%ld) from this IP address!", ip_str, cnt); Simple_Message(new_sock, - "ERROR :Connection refused, too many connections from your IP address!"); + "ERROR :Connection refused, too many connections from your IP address"); close(new_sock); return -1; } @@ -1380,18 +1441,32 @@ New_Connection(int Sock) identsock = new_sock; #ifdef IDENTAUTH - if (Conf_NoIdent) + if (!Conf_Ident) identsock = -1; #endif - if (!Conf_NoDNS) + if (Conf_DNS) { + if (Conf_NoticeAuth) { +#ifdef IDENTAUTH + if (Conf_Ident) + (void)Conn_WriteStr(new_sock, + "NOTICE AUTH :*** Looking up your hostname and checking ident"); + else +#endif + (void)Conn_WriteStr(new_sock, + "NOTICE AUTH :*** Looking up your hostname"); + } Resolve_Addr(&My_Connections[new_sock].proc_stat, &new_addr, identsock, cb_Read_Resolver_Result); + } Account_Connection(); return new_sock; } /* New_Connection */ +/** + * Update global connection counters. + */ static void Account_Connection(void) { @@ -1403,6 +1478,12 @@ Account_Connection(void) } /* Account_Connection */ +/** + * Translate socket handle into connection index. + * + * @param Sock Socket handle. + * @returns Connecion index or NONE, if no connection could be found. + */ static CONN_ID Socket2Index( int Sock ) { @@ -1421,6 +1502,8 @@ Socket2Index( int Sock ) /** * 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. */ static void Read_Request( CONN_ID Idx ) @@ -1442,9 +1525,9 @@ Read_Request( CONN_ID Idx ) { /* Read buffer is full */ Log(LOG_ERR, - "Receive buffer overflow (connection %d): %d bytes!", + "Receive buffer space exhausted (connection %d): %d bytes", Idx, array_bytes(&My_Connections[Idx].rbuf)); - Conn_Close( Idx, "Receive buffer overflow!", NULL, false ); + Conn_Close(Idx, "Receive buffer space exhausted", NULL, false); return; } @@ -1480,7 +1563,7 @@ Read_Request( CONN_ID Idx ) Log(LOG_ERR, "Could not append recieved data to zip input buffer (connn %d): %d bytes!", Idx, len); - Conn_Close(Idx, "Receive buffer overflow!", NULL, + Conn_Close(Idx, "Receive buffer space exhausted", NULL, false); return; } @@ -1489,22 +1572,27 @@ Read_Request( CONN_ID Idx ) { if (!array_catb( &My_Connections[Idx].rbuf, readbuf, len)) { Log( LOG_ERR, "Could not append recieved data to input buffer (connn %d): %d bytes!", Idx, len ); - Conn_Close( Idx, "Receive buffer overflow!", NULL, false ); + Conn_Close(Idx, "Receive buffer space exhausted", NULL, false ); } } /* Update connection statistics */ My_Connections[Idx].bytes_in += len; + My_Connections[Idx].bps += Handle_Buffer(Idx); + + /* Make sure that there is still a valid client registered */ + c = Conn_GetClient(Idx); + if (!c) + return; /* Update timestamp of last data received if this connection is * registered as a user, server or service connection. Don't update * otherwise, so users have at least Conf_PongTimeout seconds time to * register with the IRC server -- see Check_Connections(). * Update "lastping", too, if time shifted backwards ... */ - c = Conn_GetClient(Idx); - if (c && (Client_Type(c) == CLIENT_USER - || Client_Type(c) == CLIENT_SERVER - || Client_Type(c) == CLIENT_SERVICE)) { + if (Client_Type(c) == CLIENT_USER + || Client_Type(c) == CLIENT_SERVER + || Client_Type(c) == CLIENT_SERVICE) { t = time(NULL); if (My_Connections[Idx].lastdata != t) My_Connections[Idx].bps = 0; @@ -1515,8 +1603,9 @@ Read_Request( CONN_ID Idx ) } /* Look at the data in the (read-) buffer of this connection */ - My_Connections[Idx].bps += Handle_Buffer(Idx); if (Client_Type(c) != CLIENT_SERVER + && Client_Type(c) != CLIENT_UNKNOWNSERVER + && Client_Type(c) != CLIENT_SERVICE && My_Connections[Idx].bps >= maxbps) { LogDebug("Throttling connection %d: BPS exceeded! (%u >= %u)", Idx, My_Connections[Idx].bps, maxbps); @@ -1527,11 +1616,13 @@ Read_Request( CONN_ID Idx ) /** * Handle all data in the connection read-buffer. + * * Data is processed until no complete command is left in the read buffer, - * or MAX_COMMANDS[_SERVER] commands were processed. + * or MAX_COMMANDS[_SERVER|_SERVICE] commands were processed. * When a fatal error occurs, the connection is shut down. - * @param Idx Index of the connection. - * @return number of bytes processed. + * + * @param Idx Index of the connection. + * @returns Number of bytes processed. */ static unsigned int Handle_Buffer(CONN_ID Idx) @@ -1549,14 +1640,25 @@ Handle_Buffer(CONN_ID Idx) CLIENT *c; c = Conn_GetClient(Idx); - assert( c != NULL); + starttime = time(NULL); + + assert(c != NULL); /* Servers do get special command limits, so they can process * all the messages that are required while peering. */ - if (Client_Type(c) == CLIENT_SERVER) - maxcmd = MAX_COMMANDS_SERVER; + switch (Client_Type(c)) { + case CLIENT_SERVER: + /* Allow servers to send more commands in the first 10 secods + * to speed up server login and network synchronisation. */ + if (starttime - Client_StartTime(c) < 10) + maxcmd = MAX_COMMANDS_SERVER * 5; + else + maxcmd = MAX_COMMANDS_SERVER; + break; + case CLIENT_SERVICE: + maxcmd = MAX_COMMANDS_SERVICE; break; + } - starttime = time(NULL); for (i=0; i < maxcmd; i++) { /* Check penalty */ if (My_Connections[Idx].delaytime > starttime) @@ -1786,6 +1888,12 @@ Check_Servers(void) } /* Check_Servers */ +/** + * Establish a new outgoing server connection. + * + * @param Server Configuration index of the server. + * @param dest Destination IP address to connect to. + */ static void New_Server( int Server , ng_ipaddr_t *dest) { @@ -1801,14 +1909,17 @@ New_Server( int Server , ng_ipaddr_t *dest) return; } - Log(LOG_INFO, "Establishing connection for \"%s\" to \"%s\" (%s) port %d ... ", - Conf_Server[Server].name, Conf_Server[Server].host, ip_str, - Conf_Server[Server].port); - af_dest = ng_ipaddr_af(dest); new_sock = socket(af_dest, SOCK_STREAM, 0); + + Log(LOG_INFO, + "Establishing connection for \"%s\" to \"%s:%d\" (%s), socket %d ...", + Conf_Server[Server].name, Conf_Server[Server].host, + Conf_Server[Server].port, ip_str, new_sock); + if (new_sock < 0) { - Log( LOG_CRIT, "Can't create socket (af %d) : %s!", af_dest, strerror( errno )); + Log(LOG_CRIT, "Can't create socket (af %d): %s!", + af_dest, strerror(errno)); return; } @@ -1840,6 +1951,12 @@ New_Server( int Server , ng_ipaddr_t *dest) 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); + return; + } + My_Connections = array_start(&My_ConnArray); assert(My_Connections[new_sock].sock <= 0); @@ -1850,7 +1967,7 @@ New_Server( int Server , ng_ipaddr_t *dest) c = Client_NewLocal(new_sock, ip_str, CLIENT_UNKNOWNSERVER, false); if (!c) { Log( LOG_ALERT, "Can't establish connection: can't create client structure!" ); - close( new_sock ); + io_close(new_sock); return; } @@ -1867,13 +1984,6 @@ New_Server( int Server , ng_ipaddr_t *dest) strlcpy( My_Connections[new_sock].host, Conf_Server[Server].host, sizeof(My_Connections[new_sock].host )); - /* Register new socket */ - if (!io_event_create( new_sock, IO_WANTWRITE, cb_connserver)) { - Log( LOG_ALERT, "io_event_create(): could not add fd %d", strerror(errno)); - Conn_Close( new_sock, "io_event_create() failed", NULL, false ); - Init_Conn_Struct( new_sock ); - Conf_Server[Server].conn_id = NONE; - } #ifdef SSL_SUPPORT if (Conf_Server[Server].SSLConnect && !ConnSSL_PrepareConnect( &My_Connections[new_sock], &Conf_Server[Server] )) @@ -1893,6 +2003,8 @@ New_Server( int Server , ng_ipaddr_t *dest) /** * Initialize connection structure. + * + * @param Idx Connection index. */ static void Init_Conn_Struct(CONN_ID Idx) @@ -1908,11 +2020,18 @@ Init_Conn_Struct(CONN_ID Idx) } /* Init_Conn_Struct */ +/** + * Initialize options of a new socket. + * + * For example, we try to set socket options SO_REUSEADDR and IPTOS_LOWDELAY. + * The socket is automatically closed if a fatal error is encountered. + * + * @param Sock Socket handle. + * @returns false if socket was closed due to fatal error. + */ static bool Init_Socket( int Sock ) { - /* Initialize socket (set options) */ - int value; if (!io_setnonblock(Sock)) { @@ -1945,6 +2064,13 @@ Init_Socket( int Sock ) } /* Init_Socket */ +/** + * Read results of a resolver sub-process and try to initiate a new server + * connection. + * + * @param fd File descriptor of the pipe to the sub-process. + * @param events (ignored IO specification) + */ static void cb_Connect_to_Server(int fd, UNUSED short events) { @@ -1999,13 +2125,16 @@ cb_Connect_to_Server(int fd, UNUSED short events) } /* cb_Read_Forward_Lookup */ +/** + * Read results of a resolver sub-process from the pipe and update the + * 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) + */ static void cb_Read_Resolver_Result( int r_fd, UNUSED short events ) { - /* Read result of resolver sub-process from pipe and update the - * apropriate connection/client structure(s): hostname and/or - * IDENT user name.*/ - CLIENT *c; CONN_ID i; size_t len; @@ -2057,13 +2186,22 @@ cb_Read_Resolver_Result( int r_fd, UNUSED short events ) strlcpy(My_Connections[i].host, readbuf, sizeof(My_Connections[i].host)); Client_SetHostname(c, readbuf); + if (Conf_NoticeAuth) + (void)Conn_WriteStr(i, + "NOTICE AUTH :*** Found your hostname"); #ifdef IDENTAUTH ++identptr; if (*identptr) { Log(LOG_INFO, "IDENT lookup for connection %d: \"%s\".", i, identptr); Client_SetUser(c, identptr, true); + if (Conf_NoticeAuth) + (void)Conn_WriteStr(i, + "NOTICE AUTH :*** Got ident response"); } else { Log(LOG_INFO, "IDENT lookup for connection %d: no result.", i); + if (Conf_NoticeAuth && Conf_Ident) + (void)Conn_WriteStr(i, + "NOTICE AUTH :*** No ident response"); } #endif } @@ -2075,9 +2213,14 @@ cb_Read_Resolver_Result( int r_fd, UNUSED short events ) /** * Write a "simple" (error) message to a socket. + * * The message is sent without using the connection write buffers, without * compression/encryption, and even without any error reporting. It is - * designed for error messages of e.g. New_Connection(). */ + * designed for error messages of e.g. New_Connection(). + * + * @param Sock Socket handle. + * @param Msg Message string to send. + */ static void Simple_Message(int Sock, const char *Msg) { @@ -2106,8 +2249,9 @@ Simple_Message(int Sock, const char *Msg) * Get CLIENT structure that belongs to a local connection identified by its * index number. Each connection belongs to a client by definition, so it is * not required that the caller checks for NULL return values. - * @param Idx Connection index number - * @return Pointer to CLIENT structure + * + * @param Idx Connection index number. + * @returns Pointer to CLIENT structure. */ GLOBAL CLIENT * Conn_GetClient( CONN_ID Idx ) @@ -2122,8 +2266,9 @@ Conn_GetClient( CONN_ID Idx ) /** * Get PROC_STAT sub-process structure of a connection. - * @param Idx Connection index number - * @return PROC_STAT structure + * + * @param Idx Connection index number. + * @returns PROC_STAT structure. */ GLOBAL PROC_STAT * Conn_GetProcStat(CONN_ID Idx) @@ -2139,8 +2284,9 @@ Conn_GetProcStat(CONN_ID Idx) /** * Get CONN_ID from file descriptor associated to a subprocess structure. - * @param fd File descriptor - * @return CONN_ID or NONE (-1) + * + * @param fd File descriptor. + * @returns CONN_ID or NONE (-1). */ GLOBAL CONN_ID Conn_GetFromProc(int fd) @@ -2157,14 +2303,34 @@ Conn_GetFromProc(int fd) } /* Conn_GetFromProc */ +#ifndef STRICT_RFC + +GLOBAL long +Conn_GetAuthPing(CONN_ID Idx) +{ + assert (Idx != NONE); + return My_Connections[Idx].auth_ping; +} /* Conn_GetAuthPing */ + +GLOBAL void +Conn_SetAuthPing(CONN_ID Idx, long ID) +{ + assert (Idx != NONE); + My_Connections[Idx].auth_ping = ID; +} /* Conn_SetAuthPing */ + +#endif + + #ifdef SSL_SUPPORT /** * Get information about used SSL chiper. - * @param Idx Connection index number - * @param buf Buffer for returned information text - * @param len Size of return buffer "buf" - * @return true on success, false otherwise + * + * @param Idx Connection index number. + * @param buf Buffer for returned information text. + * @param len Size of return buffer "buf". + * @returns true on success, false otherwise. */ GLOBAL bool Conn_GetCipherInfo(CONN_ID Idx, char *buf, size_t len) @@ -2178,8 +2344,9 @@ Conn_GetCipherInfo(CONN_ID Idx, char *buf, size_t len) /** * Check if a connection is SSL-enabled or not. - * @param Idx Connection index number - * @return true if connection is SSL-enabled, false otherwise. + * + * @param Idx Connection index number. + * @return true if connection is SSL-enabled, false otherwise. */ GLOBAL bool Conn_UsesSSL(CONN_ID Idx) @@ -2195,6 +2362,9 @@ Conn_UsesSSL(CONN_ID Idx) #ifdef DEBUG +/** + * Dump internal state of the "connection module". + */ GLOBAL void Conn_DebugDump(void) { diff --git a/src/ngircd/conn.h b/src/ngircd/conn.h index 280c61b..c813729 100644 --- a/src/ngircd/conn.h +++ b/src/ngircd/conn.h @@ -7,14 +7,15 @@ * 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. - * - * Connection management (header) */ - #ifndef __conn_h__ #define __conn_h__ +/** + * @file + * Connection management (header) + */ #include /* for time_t, see below */ @@ -90,6 +91,9 @@ typedef struct _Connection #ifdef SSL_SUPPORT struct ConnSSL_State ssl_state; /* SSL/GNUTLS state information */ #endif +#ifndef STRICT_RFC + long auth_ping; /** PING response expected on login */ +#endif } CONNECTION; GLOBAL CONNECTION *My_Connections; @@ -131,11 +135,15 @@ GLOBAL long Conn_Count PARAMS((void)); GLOBAL long Conn_CountMax PARAMS((void)); GLOBAL long Conn_CountAccepted PARAMS((void)); +#ifndef STRICT_RFC +GLOBAL long Conn_GetAuthPing PARAMS((CONN_ID Idx)); +GLOBAL void Conn_SetAuthPing PARAMS((CONN_ID Idx, long ID)); +#endif + #ifdef DEBUG GLOBAL void Conn_DebugDump PARAMS((void)); #endif #endif - /* -eof- */ diff --git a/src/ngircd/defines.h b/src/ngircd/defines.h index 01b6037..688f2d3 100644 --- a/src/ngircd/defines.h +++ b/src/ngircd/defines.h @@ -9,7 +9,6 @@ * Please read the file COPYING, README and AUTHORS for more information. */ - #ifndef __defines_h__ #define __defines_h__ @@ -59,9 +58,12 @@ #define READBUFFER_LEN 2048 /* Size of the read buffer of a connection in bytes. */ -#define WRITEBUFFER_LEN 4096 /* Size of the write buffer of a +#define WRITEBUFFER_FLUSH_LEN 4096 /* Size of a write buffer that triggers + buffer flushing if more space is + needed for storing data. */ +#define WRITEBUFFER_MAX_LEN 32768 /* Maximum size of the write buffer of a connection in bytes. */ -#define WRITEBUFFER_SLINK_LEN 51200 /* Size of the write buffer of a +#define WRITEBUFFER_SLINK_LEN 65536 /* Maximum size of the write buffer of a server link connection in bytes. */ #define PROTOVER "0210" /* Implemented IRC protocol version, @@ -81,7 +83,7 @@ in seconds. */ #define USERMODES "aciorswx" /* Supported user modes. */ -#define CHANMODES "biIklmnoPstvz" /* Supported channel modes. */ +#define CHANMODES "biIklmnoOPstvz" /* Supported channel modes. */ #define CONNECTED true /* Internal status codes. */ #define DISCONNECTED false @@ -108,12 +110,6 @@ #define CUT_TXTSUFFIX "[CUT]" /* Suffix for oversized messages that have been shortened and cut off. */ -#ifdef ZEROCONF -#define MDNS_TYPE "_ircu._tcp." /* Service type to register with mDNS */ #endif - -#endif - - /* -eof- */ diff --git a/src/ngircd/hash.c b/src/ngircd/hash.c index 1b2f4e6..c75b57d 100644 --- a/src/ngircd/hash.c +++ b/src/ngircd/hash.c @@ -1,20 +1,20 @@ /* * ngIRCd -- The Next Generation IRC Daemon - * Copyright (c)2001-2009 Alexander Barton (alex@barton.de) + * 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 * 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. - * - * Hash calculation */ - #include "portab.h" -static char UNUSED id[] = "$Id: hash.c,v 1.13 2006/10/06 21:23:47 fw Exp $"; +/** + * @file + * Hash calculation + */ #include "imp.h" #include @@ -26,15 +26,17 @@ static char UNUSED id[] = "$Id: hash.c,v 1.13 2006/10/06 21:23:47 fw Exp $"; #include "exp.h" #include "hash.h" +static UINT32 jenkins_hash PARAMS((UINT8 *k, UINT32 length, UINT32 initval)); -static UINT32 jenkins_hash PARAMS(( register UINT8 *k, register UINT32 length, register UINT32 initval )); - - +/** + * Calculate hash value for a given string. + * + * @param String Input string + * @return 32 bit hash value + */ GLOBAL UINT32 Hash( const char *String ) { - /* Hash-Wert ueber String berechnen */ - char buffer[LINE_LEN]; strlcpy(buffer, String, sizeof(buffer)); @@ -42,70 +44,75 @@ Hash( const char *String ) (UINT32)strlen(buffer), 42); } /* Hash */ - /* - * Die hier verwendete Hash-Funktion stammt aus lookup2.c von Bob Jenkins - * (URL: ). Aus dem Header: + * This hash function originates from lookup3.c of Bob Jenkins + * (URL: ): * -------------------------------------------------------------------- - * lookup2.c, by Bob Jenkins, December 1996, Public Domain. - * hash(), hash2(), hash3, and mix() are externally useful functions. - * Routines to test the hash are included if SELF_TEST is defined. - * You can use this free for any purpose. It has no warranty. + * lookup3.c, by Bob Jenkins, May 2006, Public Domain. + * These are functions for producing 32-bit hashes for hash table lookup. + * hashword(), hashlittle(), hashlittle2(), hashbig(), mix(), and final() + * are externally useful functions. Routines to test the hash are included + * if SELF_TEST is defined. You can use this free for any purpose. It's in + * the public domain. It has no warranty. * -------------------------------------------------------------------- - * nicht alle seiner Funktionen werden hier genutzt. + * Not all of his functions are used here. */ - #define hashsize(n) ((UINT32)1<<(n)) #define hashmask(n) (hashsize(n)-1) +#define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k)))) #define mix(a,b,c) \ { \ - a -= b; a -= c; a ^= (c>>13); \ - b -= c; b -= a; b ^= (a<<8); \ - c -= a; c -= b; c ^= (b>>13); \ - a -= b; a -= c; a ^= (c>>12); \ - b -= c; b -= a; b ^= (a<<16); \ - c -= a; c -= b; c ^= (b>>5); \ - a -= b; a -= c; a ^= (c>>3); \ - b -= c; b -= a; b ^= (a<<10); \ - c -= a; c -= b; c ^= (b>>15); \ + a -= c; a ^= rot(c, 4); c += b; \ + b -= a; b ^= rot(a, 6); a += c; \ + c -= b; c ^= rot(b, 8); b += a; \ + a -= c; a ^= rot(c,16); c += b; \ + b -= a; b ^= rot(a,19); a += c; \ + c -= b; c ^= rot(b, 4); b += a; \ } /* mix */ +#define final(a,b,c) \ +{ \ + c ^= b; c -= rot(b,14); \ + a ^= c; a -= rot(c,11); \ + b ^= a; b -= rot(a,25); \ + c ^= b; c -= rot(b,16); \ + a ^= c; a -= rot(c,4); \ + b ^= a; b -= rot(a,14); \ + c ^= b; c -= rot(b,24); \ +} static UINT32 -jenkins_hash( register UINT8 *k, register UINT32 length, register UINT32 initval ) +jenkins_hash(UINT8 *k, UINT32 length, UINT32 initval) { /* k: the key * length: length of the key * initval: the previous hash, or an arbitrary value */ - - register UINT32 a,b,c,len; + UINT32 a,b,c; /* Set up the internal state */ - len = length; - a = b = 0x9e3779b9; /* the golden ratio; an arbitrary value */ - c = initval; /* the previous hash value */ + a = b = c = 0xdeadbeef + length + initval; /* handle most of the key */ - while (len >= 12) - { + while (length > 12) { a += (k[0] +((UINT32)k[1]<<8) +((UINT32)k[2]<<16) +((UINT32)k[3]<<24)); b += (k[4] +((UINT32)k[5]<<8) +((UINT32)k[6]<<16) +((UINT32)k[7]<<24)); c += (k[8] +((UINT32)k[9]<<8) +((UINT32)k[10]<<16)+((UINT32)k[11]<<24)); mix(a,b,c); - k += 12; len -= 12; + length -= 12; + k += 12; } - /* handle the last 11 bytes */ - c += length; - switch( (int)len ) /* all the case statements fall through */ + /*-------------------------------- last block: affect all 32 bits of (c) */ + switch(length) /* all the case statements fall through */ + { - case 11: c+=((UINT32)k[10]<<24); - case 10: c+=((UINT32)k[9]<<16); - case 9 : c+=((UINT32)k[8]<<8); - /* the first byte of c is reserved for the length */ + case 12: c+=((UINT32)k[11])<<24; + case 11: c+=((UINT32)k[10]<<16); + case 10: c+=((UINT32)k[9]<<8); + case 9 : c+=k[8]; case 8 : b+=((UINT32)k[7]<<24); case 7 : b+=((UINT32)k[6]<<16); case 6 : b+=((UINT32)k[5]<<8); @@ -114,13 +121,11 @@ jenkins_hash( register UINT8 *k, register UINT32 length, register UINT32 initval case 3 : a+=((UINT32)k[2]<<16); case 2 : a+=((UINT32)k[1]<<8); case 1 : a+=k[0]; - /* case 0: nothing left to add */ + break; + case 0 : return c; } - mix(a,b,c); - - /* report the result */ + final(a,b,c); return c; } /* jenkins_hash */ - /* -eof- */ diff --git a/src/ngircd/hash.h b/src/ngircd/hash.h index 577d1f5..b28ff4d 100644 --- a/src/ngircd/hash.h +++ b/src/ngircd/hash.h @@ -7,20 +7,18 @@ * 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. - * - * $Id: hash.h,v 1.6 2006/10/06 21:23:47 fw Exp $ - * - * Hash calculation (header) */ - #ifndef __hash_h__ #define __hash_h__ -GLOBAL UINT32 Hash PARAMS((const char *String )); +/** + * @file + * Hash calculation (header) + */ +GLOBAL UINT32 Hash PARAMS((const char *String )); #endif - /* -eof- */ diff --git a/src/ngircd/io.c b/src/ngircd/io.c index d13a5e2..7e78e49 100644 --- a/src/ngircd/io.c +++ b/src/ngircd/io.c @@ -5,14 +5,15 @@ * (at your option) any later version. * Please read the file COPYING, README and AUTHORS for more information. * - * I/O abstraction interface. * Copyright (c) 2005 Florian Westphal (westphal@foo.fh-furtwangen.de) - * */ #include "portab.h" -static char UNUSED id[] = "$Id: io.c,v 1.31 2008/04/03 20:56:44 fw Exp $"; +/** + * @file + * I/O abstraction interface. + */ #include #include diff --git a/src/ngircd/io.h b/src/ngircd/io.h index 2f4c964..556d752 100644 --- a/src/ngircd/io.h +++ b/src/ngircd/io.h @@ -4,15 +4,16 @@ * 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. - * - * I/O abstraction interface header - * - * $Id: io.h,v 1.4 2006/12/25 22:53:52 alex Exp $ */ #ifndef io_H_included #define io_H_included +/** + * @file + * I/O abstraction interface (header) + */ + #include "portab.h" #include diff --git a/src/ngircd/irc-channel.c b/src/ngircd/irc-channel.c index 3bf02c6..66b3eeb 100644 --- a/src/ngircd/irc-channel.c +++ b/src/ngircd/irc-channel.c @@ -7,13 +7,15 @@ * 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. - * - * IRC channel commands */ - #include "portab.h" +/** + * @file + * IRC channel commands + */ + #include "imp.h" #include #include @@ -37,13 +39,18 @@ #include "irc-channel.h" -/* +/** + * Part from all channels. + * * RFC 2812, (3.2.1 Join message Command): - * Note that this message - * accepts a special argument ("0"), which is a special request to leave all - * channels the user is currently a member of. The server will process this - * message as if the user had sent a PART command (See Section 3.2.2) for - * each channel he is a member of. + * Note that this message accepts a special argument ("0"), which is a + * special request to leave all channels the user is currently a member of. + * The server will process this message as if the user had sent a PART + * command (See Section 3.2.2) for each channel he is a member of. + * + * @param client Client that initiated the part request + * @param target Client that should part all joined channels + * @returns CONNECTED or DISCONNECTED */ static bool part_from_all_channels(CLIENT* client, CLIENT *target) @@ -57,17 +64,18 @@ part_from_all_channels(CLIENT* client, CLIENT *target) Channel_Part(target, client, Channel_Name(chan), Client_ID(target)); } return CONNECTED; -} +} /* part_from_all_channels */ /** * Check weather a local client is allowed to join an already existing * channel or not. - * @param Client Client that sent the JOIN command - * @param chan Channel to check - * @param channame Name of the channel - * @param key Provided channel key (or NULL if none has been provided) - * @return true if client is allowed to join channel, false otherwise + * + * @param Client Client that sent the JOIN command + * @param chan Channel to check + * @param channame Name of the channel + * @param key Provided channel key (or NULL) + * @returns true if client is allowed to join, false otherwise */ static bool join_allowed(CLIENT *Client, CHANNEL *chan, const char *channame, @@ -122,10 +130,24 @@ join_allowed(CLIENT *Client, CHANNEL *chan, const char *channame, return false; } + if (strchr(channel_modes, 'O') && !Client_OperByMe(Client)) { + /* Only IRC operators are allowed! */ + IRC_WriteStrClient(Client, ERR_OPONLYCHANNEL_MSG, + Client_ID(Client), channame); + return false; + } + return true; -} +} /* join_allowed */ +/** + * Set user channel modes. + * + * @param chan Channel + * @param target User to set modes for + * @param flags Channel modes to add + */ static void join_set_channelmodes(CHANNEL *chan, CLIENT *target, const char *flags) { @@ -139,9 +161,22 @@ join_set_channelmodes(CHANNEL *chan, CLIENT *target, const char *flags) /* If channel persistent and client is ircop: make client chanop */ if (strchr(Channel_Modes(chan), 'P') && strchr(Client_Modes(target), 'o')) Channel_UserModeAdd(chan, target, 'o'); -} +} /* join_set_channelmodes */ +/** + * Forward JOIN command to a specific server + * + * 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. + * + * @param To Forward JOIN (and MODE) command to this peer server + * @param Prefix Client used to prefix the genrated commands + * @param Data Parameters of JOIN command to forward, probably + * containing channel modes separated by ASCII 7. + */ static void cb_join_forward(CLIENT *To, CLIENT *Prefix, void *Data) { @@ -166,12 +201,25 @@ cb_join_forward(CLIENT *To, CLIENT *Prefix, void *Data) } /* cb_join_forward */ +/** + * Forward JOIN command to all servers + * + * This function calls cb_join_forward(), which differentiates between + * protocol implementations (e.g. RFC 2812, RFC 1459). + * + * @param Client Client used to prefix the genrated commands + * @param target Forward JOIN (and MODE) command to this peer server + * @param chan Channel structure + * @param channame Channel name + */ static void join_forward(CLIENT *Client, CLIENT *target, CHANNEL *chan, const char *channame) { char modes[CHANNEL_MODE_LEN], str[COMMAND_LEN]; + /* RFC 2813, 4.2.1: channel modes are separated from the channel + * name with ASCII 7, if any, and not spaces: */ strlcpy(&modes[1], Channel_UserModes(chan, target), sizeof(modes) - 1); if (modes[1]) modes[0] = 0x7; @@ -198,6 +246,14 @@ join_forward(CLIENT *Client, CLIENT *target, CHANNEL *chan, } /* join_forward */ +/** + * 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 + * @param chan Channel structure + * @param channame Channel name + */ static bool join_send_topic(CLIENT *Client, CLIENT *target, CHANNEL *chan, const char *channame) @@ -228,10 +284,20 @@ join_send_topic(CLIENT *Client, CLIENT *target, CHANNEL *chan, /* send list of channel members to client */ if (!IRC_Send_NAMES(Client, chan)) return false; - return IRC_WriteStrClient(Client, RPL_ENDOFNAMES_MSG, Client_ID(Client), Channel_Name(chan)); -} + return IRC_WriteStrClient(Client, RPL_ENDOFNAMES_MSG, Client_ID(Client), + Channel_Name(chan)); +} /* join_send_topic */ +/** + * Handler for the IRC "JOIN" command. + * + * 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 ) { @@ -356,6 +422,12 @@ IRC_JOIN( CLIENT *Client, REQUEST *Req ) /** * Handler for the IRC "PART" command. + * + * 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) @@ -401,55 +473,81 @@ IRC_PART(CLIENT * Client, REQUEST * Req) } /* IRC_PART */ +/** + * Handler for the IRC "TOPIC" command. + * + * 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 ) { CHANNEL *chan; CLIENT *from; char *topic; - bool r; + bool onchannel, topicok, use_servermode, r; assert( Client != NULL ); assert( Req != NULL ); - if ((Req->argc < 1) || (Req->argc > 2)) - return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, Client_ID(Client), Req->command); + if (Req->argc < 1 || 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 ); + if (Client_Type(Client) == CLIENT_SERVER) + from = Client_Search(Req->prefix); + else + from = Client; - /* Welcher Channel? */ - chan = Channel_Search( Req->argv[0] ); - if( ! chan ) return IRC_WriteStrClient( from, ERR_NOSUCHCHANNEL_MSG, Client_ID( from ), Req->argv[0] ); + if (!from) + return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG, + Client_ID(Client), Req->prefix); - /* Ist der User Mitglied in dem Channel? */ - if( ! Channel_IsMemberOf( chan, from )) return IRC_WriteStrClient( from, ERR_NOTONCHANNEL_MSG, Client_ID( from ), Req->argv[0] ); + chan = Channel_Search(Req->argv[0]); + if (!chan) + return IRC_WriteStrClient(from, ERR_NOSUCHCHANNEL_MSG, + Client_ID(from), Req->argv[0]); - if( Req->argc == 1 ) - { + Channel_CheckAdminRights(chan, Client, from, + &onchannel, &topicok, &use_servermode); + + if (!onchannel && !topicok) + return IRC_WriteStrClient(from, ERR_NOTONCHANNEL_MSG, + Client_ID(from), Req->argv[0]); + + if (Req->argc == 1) { /* Request actual topic */ topic = Channel_Topic(chan); if (*topic) { r = IRC_WriteStrClient(from, RPL_TOPIC_MSG, - Client_ID(Client), Channel_Name(chan), topic); + Client_ID(Client), + Channel_Name(chan), topic); #ifndef STRICT_RFC + if (!r) + return r; r = IRC_WriteStrClient(from, RPL_TOPICSETBY_MSG, - Client_ID(Client), Channel_Name(chan), - Channel_TopicWho(chan), - Channel_TopicTime(chan)); + Client_ID(Client), + Channel_Name(chan), + Channel_TopicWho(chan), + Channel_TopicTime(chan)); #endif return r; } else - return IRC_WriteStrClient(from, RPL_NOTOPIC_MSG, - Client_ID(from), Channel_Name(chan)); + return IRC_WriteStrClient(from, RPL_NOTOPIC_MSG, + Client_ID(from), + Channel_Name(chan)); } - if( strchr( Channel_Modes( chan ), 't' )) - { - /* Topic Lock. Ist der User ein Channel Operator? */ - if( ! strchr( Channel_UserModes( chan, from ), 'o' )) return IRC_WriteStrClient( from, ERR_CHANOPRIVSNEEDED_MSG, Client_ID( from ), Channel_Name( chan )); + if (strchr(Channel_Modes(chan), 't')) { + /* Topic Lock. Is the user a channel or IRC operator? */ + if (!topicok) + return IRC_WriteStrClient(from, ERR_CHANOPRIVSNEEDED_MSG, + Client_ID(from), + Channel_Name(chan)); } /* Set new topic */ @@ -458,6 +556,9 @@ IRC_TOPIC( CLIENT *Client, REQUEST *Req ) Client_TypeText(from), Client_Mask(from), Channel_Name(chan), Req->argv[1][0] ? Req->argv[1] : ""); + if (use_servermode) + from = Client_ThisServer(); + /* Update channel and forward new topic to other servers */ if (!Channel_IsLocal(chan)) IRC_WriteStrServersPrefix(Client, from, "TOPIC %s :%s", @@ -475,8 +576,15 @@ IRC_TOPIC( CLIENT *Client, REQUEST *Req ) /** * 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 + * @returns CONNECTED or DISCONNECTED */ GLOBAL bool IRC_LIST( CLIENT *Client, REQUEST *Req ) @@ -560,6 +668,16 @@ IRC_LIST( CLIENT *Client, REQUEST *Req ) } /* IRC_LIST */ +/** + * Handler for the IRC+ command "CHANINFO". + * + * 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 ) { @@ -572,7 +690,9 @@ IRC_CHANINFO( CLIENT *Client, REQUEST *Req ) assert( Req != NULL ); /* Bad number of parameters? */ - if(( Req->argc < 2 ) || ( Req->argc == 4 ) || ( Req->argc > 5 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command ); + 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; diff --git a/src/ngircd/irc-channel.h b/src/ngircd/irc-channel.h index d8bddbf..685ec0c 100644 --- a/src/ngircd/irc-channel.h +++ b/src/ngircd/irc-channel.h @@ -7,16 +7,15 @@ * 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. - * - * $Id: irc-channel.h,v 1.7 2005/03/19 18:43:48 fw Exp $ - * - * IRC channel commands (header) */ - #ifndef __irc_channel_h__ #define __irc_channel_h__ +/** + * @file + * IRC channel commands (header) + */ GLOBAL bool IRC_JOIN PARAMS((CLIENT *Client, REQUEST *Req )); GLOBAL bool IRC_PART PARAMS((CLIENT *Client, REQUEST *Req )); @@ -26,8 +25,6 @@ GLOBAL bool IRC_LIST PARAMS((CLIENT *Client, REQUEST *Req )); GLOBAL bool IRC_CHANINFO PARAMS((CLIENT *Client, REQUEST *Req )); - #endif - /* -eof- */ diff --git a/src/ngircd/irc-info.c b/src/ngircd/irc-info.c index 638a8e9..301da53 100644 --- a/src/ngircd/irc-info.c +++ b/src/ngircd/irc-info.c @@ -1,19 +1,21 @@ /* * ngIRCd -- The Next Generation IRC Daemon - * Copyright (c)2001-2010 Alexander Barton + * 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 * 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. - * - * IRC info commands */ - #include "portab.h" +/** + * @file + * IRC info commands + */ + #include "imp.h" #include #include @@ -914,42 +916,21 @@ IRC_WHO( CLIENT *Client, REQUEST *Req ) } /* IRC_WHO */ -GLOBAL bool -IRC_WHOIS( CLIENT *Client, REQUEST *Req ) +/** + * Generate WHOIS reply of one actual client. + * + * @param Client The client from which this command has been received. + * @param from The client requesting the information ("originator"). + * @param c The client of which information should be returned. + * @returns CONNECTED or DISCONNECTED. + */ +static bool +IRC_WHOIS_SendReply(CLIENT *Client, CLIENT *from, CLIENT *c) { - CLIENT *from, *target, *c; char str[LINE_LEN + 1]; CL2CHAN *cl2chan; CHANNEL *chan; - assert( Client != NULL ); - assert( Req != NULL ); - - /* Bad number of parameters? */ - if(( Req->argc < 1 ) || ( Req->argc > 2 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command ); - - /* Search client */ - c = Client_Search( Req->argv[Req->argc - 1] ); - if(( ! c ) || ( Client_Type( c ) != CLIENT_USER )) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->argv[Req->argc - 1] ); - - /* Search sender of the WHOIS */ - 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 ); - - /* Forward to other server? */ - if( Req->argc > 1 ) - { - /* Search target server (can be specified as nick of that server!) */ - target = Client_Search( Req->argv[0] ); - if( ! target ) return IRC_WriteStrClient( from, ERR_NOSUCHSERVER_MSG, Client_ID( from ), Req->argv[0] ); - } - else target = Client_ThisServer( ); - - assert( target != NULL ); - - if(( Client_NextHop( target ) != Client_ThisServer( )) && ( Client_Type( Client_NextHop( target )) == CLIENT_SERVER )) return IRC_WriteStrClientPrefix( target, from, "WHOIS %s :%s", Req->argv[0], Req->argv[1] ); - /* Nick, user, hostname and client info */ if (!IRC_WriteStrClient(from, RPL_WHOISUSER_MSG, Client_ID(from), Client_ID(c), Client_User(c), @@ -957,18 +938,21 @@ IRC_WHOIS( CLIENT *Client, REQUEST *Req ) return DISCONNECTED; /* Server */ - if( ! IRC_WriteStrClient( from, RPL_WHOISSERVER_MSG, Client_ID( from ), Client_ID( c ), Client_ID( Client_Introducer( c )), Client_Info( Client_Introducer( c )))) return DISCONNECTED; + if (!IRC_WriteStrClient(from, RPL_WHOISSERVER_MSG, Client_ID(from), + Client_ID(c), Client_ID(Client_Introducer(c)), + Client_Info(Client_Introducer(c)))) + return DISCONNECTED; /* Channels */ - snprintf( str, sizeof( str ), RPL_WHOISCHANNELS_MSG, Client_ID( from ), Client_ID( c )); - cl2chan = Channel_FirstChannelOf( c ); - while( cl2chan ) - { - chan = Channel_GetChannel( cl2chan ); - assert( chan != NULL ); + snprintf(str, sizeof(str), RPL_WHOISCHANNELS_MSG, + Client_ID(from), Client_ID(c)); + cl2chan = Channel_FirstChannelOf(c); + while (cl2chan) { + chan = Channel_GetChannel(cl2chan); + assert(chan != NULL); /* next */ - cl2chan = Channel_NextChannelOf( c, cl2chan ); + cl2chan = Channel_NextChannelOf(c, cl2chan); /* Secret channel? */ if (strchr(Channel_Modes(chan), 's') @@ -981,54 +965,168 @@ IRC_WHOIS( CLIENT *Client, REQUEST *Req ) continue; /* Concatenate channel names */ - if( str[strlen( str ) - 1] != ':' ) strlcat( str, " ", sizeof( str )); - if( strchr( Channel_UserModes( chan, c ), 'o' )) strlcat( str, "@", sizeof( str )); - else if( strchr( Channel_UserModes( chan, c ), 'v' )) strlcat( str, "+", sizeof( str )); - strlcat( str, Channel_Name( chan ), sizeof( str )); + if (str[strlen(str) - 1] != ':') + strlcat(str, " ", sizeof(str)); - if( strlen( str ) > ( LINE_LEN - CHANNEL_NAME_LEN - 4 )) - { + strlcat(str, who_flags_qualifier(Channel_UserModes(chan, c)), + sizeof(str)); + strlcat(str, Channel_Name(chan), sizeof(str)); + + if (strlen(str) > (LINE_LEN - CHANNEL_NAME_LEN - 4)) { /* Line becomes too long: send it! */ - if( ! IRC_WriteStrClient( Client, "%s", str )) return DISCONNECTED; - snprintf( str, sizeof( str ), RPL_WHOISCHANNELS_MSG, Client_ID( from ), Client_ID( c )); + if (!IRC_WriteStrClient(Client, "%s", str)) + return DISCONNECTED; + snprintf(str, sizeof(str), RPL_WHOISCHANNELS_MSG, + Client_ID(from), Client_ID(c)); } } - if( str[strlen( str ) - 1] != ':') - { + if(str[strlen(str) - 1] != ':') { /* There is data left to send: */ - if( ! IRC_WriteStrClient( Client, "%s", str )) return DISCONNECTED; + if (!IRC_WriteStrClient(Client, "%s", str)) + return DISCONNECTED; } /* IRC-Operator? */ - if( Client_HasMode( c, 'o' )) - { - if( ! IRC_WriteStrClient( from, RPL_WHOISOPERATOR_MSG, Client_ID( from ), Client_ID( c ))) return DISCONNECTED; - } + if (Client_HasMode(c, 'o') && + !IRC_WriteStrClient(from, RPL_WHOISOPERATOR_MSG, + Client_ID(from), Client_ID(c))) + return DISCONNECTED; /* Connected using SSL? */ - if (Conn_UsesSSL(Client_Conn(c))) { - if (!IRC_WriteStrClient - (from, RPL_WHOISSSL_MSG, Client_ID(from), Client_ID(c))) + if (Conn_UsesSSL(Client_Conn(c)) && + !IRC_WriteStrClient(from, RPL_WHOISSSL_MSG, + Client_ID(from), Client_ID(c))) return DISCONNECTED; - } /* Idle and signon time (local clients only!) */ - if (Client_Conn(c) > NONE ) { - if (! IRC_WriteStrClient(from, RPL_WHOISIDLE_MSG, - Client_ID(from), Client_ID(c), - (unsigned long)Conn_GetIdle(Client_Conn(c)), - (unsigned long)Conn_GetSignon(Client_Conn(c)))) - return DISCONNECTED; - } + if (!Conf_MorePrivacy && Client_Conn(c) > NONE && + !IRC_WriteStrClient(from, RPL_WHOISIDLE_MSG, + Client_ID(from), Client_ID(c), + (unsigned long)Conn_GetIdle(Client_Conn(c)), + (unsigned long)Conn_GetSignon(Client_Conn(c)))) + return DISCONNECTED; /* Away? */ - if( Client_HasMode( c, 'a' )) - { - if( ! IRC_WriteStrClient( from, RPL_AWAY_MSG, Client_ID( from ), Client_ID( c ), Client_Away( c ))) return DISCONNECTED; + if (Client_HasMode(c, 'a') && + !IRC_WriteStrClient(from, RPL_AWAY_MSG, + Client_ID(from), Client_ID(c), + Client_Away(c))) + return DISCONNECTED; + + return IRC_WriteStrClient(from, RPL_ENDOFWHOIS_MSG, + Client_ID(from), Client_ID(c)); +} /* IRC_WHOIS_SendReply */ + + +/** + * Handler for the IRC "WHOIS" command. + * + * See RFC 2812, 3.6.2 "Whois query". + * + * @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_WHOIS( CLIENT *Client, REQUEST *Req ) +{ + CLIENT *from, *target, *c; + unsigned int match_count = 0, found = 0; + bool has_wildcards, is_remote; + bool got_wildcard = false; + const char *query; + + assert( Client != NULL ); + assert( Req != NULL ); + + /* Bad number of parameters? */ + if (Req->argc < 1 || Req->argc > 2) + return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, + Client_ID(Client), Req->command); + + /* Search sender of the WHOIS */ + if (Client_Type(Client) == CLIENT_SERVER) { + from = Client_Search(Req->prefix); + } else { + IRC_SetPenalty(Client, 1); + from = Client; } + if (!from) + return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG, + Client_ID(Client), Req->prefix); + + /* Get target server for this command */ + if (Req->argc > 1) { + /* Search the target server, which can be specified as a + * nick name on that server as well: */ + target = Client_Search(Req->argv[0]); + if (!target) + return IRC_WriteStrClient(from, ERR_NOSUCHSERVER_MSG, + Client_ID(from), Req->argv[0]); + } else + target = Client_ThisServer(); + assert(target != NULL); + + /* Forward to other server? */ + if (Client_NextHop(target) != Client_ThisServer() && + Client_Type(Client_NextHop(target)) == CLIENT_SERVER) + return IRC_WriteStrClientPrefix(target, from, + "WHOIS %s :%s", + Req->argv[0], Req->argv[1]); + + is_remote = Client_Conn(from) < 0; + for (query = strtok(Req->argv[Req->argc - 1], ","); + query && found < 3; + query = strtok(NULL, ","), found++) + { + has_wildcards = query[strcspn(query, "*?")] != 0; + /* + * follows ircd 2.10 implementation: + * - handle up to 3 targets + * - no wildcards for remote clients + * - only one wildcard target per local client + * + * also, at most ten matches are returned. + */ + if (!has_wildcards || is_remote) { + c = Client_Search(query); + if (c) { + if (!IRC_WHOIS_SendReply(Client, from, c)) + return DISCONNECTED; + } else { + if (!IRC_WriteStrClient(Client, + ERR_NOSUCHNICK_MSG, + Client_ID(Client), + query)) + return DISCONNECTED; + } + continue; + } + if (got_wildcard) { + /* we already handled one wildcard query */ + if (!IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG, + Client_ID(Client), query)) + return DISCONNECTED; + continue; + } + got_wildcard = true; + IRC_SetPenalty(Client, 3); + + for (c = Client_First(); c && match_count < 10; c = Client_Next(c)) { + if (Client_Type(c) != CLIENT_USER) + continue; + if (!MatchCaseInsensitive(query, Client_ID(c))) + continue; + if (!IRC_WHOIS_SendReply(Client, from, c)) + return DISCONNECTED; + match_count++; + } - /* End of Whois */ - return IRC_WriteStrClient( from, RPL_ENDOFWHOIS_MSG, Client_ID( from ), Client_ID( c )); + if (match_count == 0) + return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG, + Client_ID(Client), Req->argv[Req->argc - 1]); + } + return CONNECTED; } /* IRC_WHOIS */ @@ -1065,6 +1163,10 @@ IRC_WHOWAS( CLIENT *Client, REQUEST *Req ) assert( Client != NULL ); assert( Req != NULL ); + /* Do not reveal any info on disconnected users? */ + if (Conf_MorePrivacy) + return CONNECTED; + /* Wrong number of parameters? */ if (Req->argc > 3) return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, @@ -1291,6 +1393,10 @@ IRC_Send_NAMES( CLIENT *Client, CHANNEL *Chan ) if( Channel_IsMemberOf( Chan, Client )) is_member = true; else is_member = false; + /* Do not print info on channel memberships to anyone that is not member? */ + if (Conf_MorePrivacy && !is_member) + return CONNECTED; + /* Secret channel? */ if( ! is_member && strchr( Channel_Modes( Chan ), 's' )) return CONNECTED; diff --git a/src/ngircd/irc-info.h b/src/ngircd/irc-info.h index fbebacc..6b6124b 100644 --- a/src/ngircd/irc-info.h +++ b/src/ngircd/irc-info.h @@ -7,16 +7,15 @@ * 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. - * - * $Id: irc-info.h,v 1.6 2008/02/17 13:26:42 alex Exp $ - * - * IRC info commands (header) */ - #ifndef __irc_info_h__ #define __irc_info_h__ +/** + * @file + * IRC info commands (header) + */ GLOBAL bool IRC_ADMIN PARAMS(( CLIENT *Client, REQUEST *Req )); GLOBAL bool IRC_INFO PARAMS(( CLIENT *Client, REQUEST *Req )); @@ -41,8 +40,6 @@ GLOBAL bool IRC_Send_NAMES PARAMS(( CLIENT *Client, CHANNEL *Chan )); GLOBAL bool IRC_Show_MOTD PARAMS(( CLIENT *Client )); GLOBAL bool IRC_Send_ISUPPORT PARAMS(( CLIENT *Client )); - #endif - /* -eof- */ diff --git a/src/ngircd/irc-login.c b/src/ngircd/irc-login.c index 03fea99..067703a 100644 --- a/src/ngircd/irc-login.c +++ b/src/ngircd/irc-login.c @@ -7,13 +7,15 @@ * 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. - * - * Login and logout */ - #include "portab.h" +/** + * @file + * Login and logout + */ + #include "imp.h" #include #include @@ -54,8 +56,13 @@ static void cb_Read_Auth_Result PARAMS((int r_fd, UNUSED short events)); #endif /** - * Handler for the IRC command "PASS". + * Handler for the IRC "PASS" command. + * * 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 ) @@ -143,16 +150,17 @@ IRC_PASS( CLIENT *Client, REQUEST *Req ) if (type && strcmp(type, PROTOIRCPLUS) == 0) { /* The peer seems to be a server which supports the * IRC+ protocol (see doc/Protocol.txt). */ - serverver = ptr + 1; - flags = strchr(serverver, ':'); + serverver = ptr ? ptr + 1 : "?"; + flags = strchr(ptr ? serverver : impl, ':'); if (flags) { *flags = '\0'; flags++; } else flags = ""; Log(LOG_INFO, - "Peer announces itself as %s-%s using protocol %d.%d/IRC+ (flags: \"%s\").", - impl, serverver, protohigh, protolow, flags); + "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 { /* The peer seems to be a server supporting the * "original" IRC protocol (RFC 2813). */ @@ -161,8 +169,9 @@ IRC_PASS( CLIENT *Client, REQUEST *Req ) else flags = ""; Log(LOG_INFO, - "Peer announces itself as \"%s\" using protocol %d.%d (flags: \"%s\").", - impl, protohigh, protolow, flags); + "Peer on connection %d announces itself as \"%s\" using protocol %d.%d (flags: \"%s\").", + Client_Conn(Client), impl, + protohigh, protolow, flags); } Client_SetFlags(Client, flags); } @@ -172,10 +181,17 @@ IRC_PASS( CLIENT *Client, REQUEST *Req ) /** - * IRC "NICK" command. + * Handler for the IRC "NICK" command. + * + * 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 ) @@ -255,6 +271,17 @@ IRC_NICK( CLIENT *Client, REQUEST *Req ) /* Register new nickname of this client */ Client_SetID( target, Req->argv[0] ); +#ifndef STRICT_RFC + if (Conf_AuthPing) { + Conn_SetAuthPing(Client_Conn(Client), rand()); + IRC_WriteStrClient(Client, "PING :%ld", + Conn_GetAuthPing(Client_Conn(Client))); + LogDebug("Connection %d: sent AUTH PING %ld ...", + Client_Conn(Client), + Conn_GetAuthPing(Client_Conn(Client))); + } +#endif + /* If we received a valid USER command already then * register the new client! */ if( Client_Type( Client ) == CLIENT_GOTUSER ) @@ -377,7 +404,13 @@ IRC_NICK( CLIENT *Client, REQUEST *Req ) /** - * Handler for the IRC command "USER". + * Handler for the IRC "USER" command. + * + * 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) @@ -470,12 +503,18 @@ IRC_USER(CLIENT * Client, REQUEST * Req) /** - * Handler for the IRC command "SERVICE". + * 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. + * @returns CONNECTED or DISCONNECTED.. */ GLOBAL bool IRC_SERVICE(CLIENT *Client, REQUEST *Req) @@ -568,8 +607,14 @@ IRC_SERVICE(CLIENT *Client, REQUEST *Req) /** - * Handler for the IRC command "WEBIRC". - * Syntax: WEBIRC + * Handler for the IRC "WEBIRC" command. + * + * 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) @@ -593,6 +638,15 @@ IRC_WEBIRC(CLIENT *Client, REQUEST *Req) } /* IRC_WEBIRC */ +/** + * Handler for the IRC "QUIT" command. + * + * 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 ) { @@ -640,6 +694,38 @@ IRC_QUIT( CLIENT *Client, REQUEST *Req ) } /* IRC_QUIT */ +#ifndef STRICT_RFC + +/** + * Handler for HTTP command, e.g. GET and POST + * + * 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. + * @returns CONNECTED or DISCONNECTED. + */ +GLOBAL bool +IRC_QUIT_HTTP( CLIENT *Client, REQUEST *Req ) +{ + Req->argc = 1; + Req->argv[0] = "Oops, HTTP request received? This is IRC!"; + return IRC_QUIT(Client, Req); +} /* IRC_QUIT_HTTP */ + +#endif + + +/** + * Handler for the IRC "PING" command. + * + * 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) { @@ -709,22 +795,45 @@ IRC_PING(CLIENT *Client, REQUEST *Req) } /* IRC_PING */ +/** + * Handler for the IRC "PONG" command. + * + * 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) { CLIENT *target, *from; + CONN_ID conn; +#ifndef STRICT_RFC + long auth_ping; +#endif char *s; assert(Client != NULL); assert(Req != NULL); /* Wrong number of arguments? */ - if (Req->argc < 1) - return IRC_WriteStrClient(Client, ERR_NOORIGIN_MSG, - Client_ID(Client)); - if (Req->argc > 2) - return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, - Client_ID(Client), Req->command); + if (Req->argc < 1) { + if (Client_Type(Client) == CLIENT_USER) + return IRC_WriteStrClient(Client, ERR_NOORIGIN_MSG, + Client_ID(Client)); + else + return CONNECTED; + } + 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) { @@ -753,32 +862,76 @@ IRC_PONG(CLIENT *Client, REQUEST *Req) /* The connection timestamp has already been updated when the data has * been read from so socket, so we don't need to update it here. */ + + conn = Client_Conn(Client); + +#ifndef STRICT_RFC + /* Check authentication PING-PONG ... */ + auth_ping = Conn_GetAuthPing(conn); + if (auth_ping) { + LogDebug("AUTH PONG: waiting for token \"%ld\", got \"%s\" ...", + auth_ping, Req->argv[0]); + if (auth_ping == atoi(Req->argv[0])) { + Conn_SetAuthPing(conn, 0); + if (Client_Type(Client) == CLIENT_WAITAUTHPING) + Hello_User(Client); + } else + if (!IRC_WriteStrClient(Client, + "To connect, type /QUOTE PONG %ld", + auth_ping)) + return DISCONNECTED; + } +#endif + #ifdef DEBUG - if (Client_Conn(Client) > NONE) + if (conn > NONE) Log(LOG_DEBUG, - "Connection %d: received PONG. Lag: %ld seconds.", - Client_Conn(Client), + "Connection %d: received PONG. Lag: %ld seconds.", conn, time(NULL) - Conn_LastPing(Client_Conn(Client))); else Log(LOG_DEBUG, - "Connection %d: received PONG.", Client_Conn(Client)); + "Connection %d: received PONG.", conn); #endif return CONNECTED; } /* IRC_PONG */ +/** + * Initiate client registration. + * + * This function is called after the daemon received the required NICK and + * USER commands of a new client. If the daemon is compiled with support for + * PAM, the authentication sub-processs is forked; otherwise the global server + * password is checked. + * + * @param Client The client logging in. + * @returns CONNECTED or DISCONNECTED. + */ static bool Hello_User(CLIENT * Client) { #ifdef PAM int pipefd[2], result; - CONN_ID conn; pid_t pid; +#endif + CONN_ID conn; assert(Client != NULL); conn = Client_Conn(Client); - if (Conf_NoPAM) { +#ifndef STRICT_RFC + if (Conf_AuthPing) { + /* Did we receive the "auth PONG" already? */ + if (Conn_GetAuthPing(conn)) { + Client_SetType(Client, CLIENT_WAITAUTHPING); + LogDebug("Connection %d: Waiting for AUTH PONG ...", conn); + return CONNECTED; + } + } +#endif + +#ifdef PAM + if (!Conf_PAM) { /* 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 @@ -801,13 +954,13 @@ Hello_User(CLIENT * Client) /* Sub process */ Log_Init_Subprocess("Auth"); result = PAM_Authenticate(Client); - write(pipefd[1], &result, sizeof(result)); + 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 - assert(Client != NULL); - /* Check global server password ... */ if (strcmp(Client_Password(Client), Conf_ServerPwd) != 0) { /* Bad password! */ @@ -823,6 +976,9 @@ Hello_User(CLIENT * Client) /** * Read result of the authenticatior sub-process from pipe + * + * @param r_fd File descriptor of the pipe. + * @param events (ignored IO specification) */ static void cb_Read_Auth_Result(int r_fd, UNUSED short events) @@ -866,6 +1022,14 @@ cb_Read_Auth_Result(int r_fd, UNUSED short events) #endif +/** + * Reject a client because of wrong password. + * + * This function is called either when the global server password or a password + * checked using PAM has been wrong. + * + * @param Client The client to reject. + */ static void Reject_Client(CLIENT *Client) { @@ -877,6 +1041,15 @@ Reject_Client(CLIENT *Client) } +/** + * Finish client registration. + * + * Introduce the new client to the network and send all "hello messages" + * to it after authentication has been succeeded. + * + * @param Client The client logging in. + * @returns CONNECTED or DISCONNECTED. + */ static bool Hello_User_PostAuth(CLIENT *Client) { @@ -916,6 +1089,12 @@ Hello_User_PostAuth(CLIENT *Client) } +/** + * Kill all users with a specific nick name in the network. + * + * @param Nick Nick name. + * @param Reason Reason for the KILL. + */ static void Kill_Nick( char *Nick, char *Reason ) { @@ -934,6 +1113,13 @@ Kill_Nick( char *Nick, char *Reason ) } /* Kill_Nick */ +/** + * Introduce a new user or service client in the network. + * + * @param From Remote server introducing the client or NULL (local). + * @param Client New client. + * @param Type Type of the client (CLIENT_USER or CLIENT_SERVICE). + */ static void Introduce_Client(CLIENT *From, CLIENT *Client, int Type) { @@ -967,6 +1153,16 @@ Introduce_Client(CLIENT *From, CLIENT *Client, int Type) } /* Introduce_Client */ +/** + * 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. + */ static void cb_introduceClient(CLIENT *To, CLIENT *Prefix, void *data) { diff --git a/src/ngircd/irc-login.h b/src/ngircd/irc-login.h index 1504e0b..f3138f6 100644 --- a/src/ngircd/irc-login.h +++ b/src/ngircd/irc-login.h @@ -7,14 +7,16 @@ * 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. - * - * Login and logout (header) */ - #ifndef __irc_login_h__ #define __irc_login_h__ +/** + * @file + * Login and logout (header) + */ + GLOBAL bool IRC_PASS PARAMS((CLIENT *Client, REQUEST *Req)); GLOBAL bool IRC_NICK PARAMS((CLIENT *Client, REQUEST *Req)); GLOBAL bool IRC_USER PARAMS((CLIENT *Client, REQUEST *Req)); @@ -23,8 +25,8 @@ GLOBAL bool IRC_WEBIRC PARAMS((CLIENT *Client, REQUEST *Req)); GLOBAL bool IRC_PING PARAMS((CLIENT *Client, REQUEST *Req)); GLOBAL bool IRC_PONG PARAMS((CLIENT *Client, REQUEST *Req)); GLOBAL bool IRC_QUIT PARAMS((CLIENT *Client, REQUEST *Req)); +GLOBAL bool IRC_QUIT_HTTP PARAMS((CLIENT *Client, REQUEST *Req)); #endif - /* -eof- */ diff --git a/src/ngircd/irc-mode.c b/src/ngircd/irc-mode.c index a4c1d89..50b0db0 100644 --- a/src/ngircd/irc-mode.c +++ b/src/ngircd/irc-mode.c @@ -1,19 +1,21 @@ /* * ngIRCd -- The Next Generation IRC Daemon - * Copyright (c)2001-2010 Alexander Barton (alex@barton.de) + * 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 * 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. - * - * IRC commands for mode changes (MODE, AWAY, ...) */ - #include "portab.h" +/** + * @file + * IRC commands for mode changes (like MODE, AWAY, etc.) + */ + #include "imp.h" #include #include @@ -202,7 +204,7 @@ Client_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *Target ) case 'x': /* Cloak hostname */ if (Client_HasMode(Client, 'r')) - IRC_WriteStrClient(Origin, + ok = IRC_WriteStrClient(Origin, ERR_RESTRICTED_MSG, Client_ID(Origin)); else @@ -316,8 +318,7 @@ 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; - bool connected, set, skiponce, retval, onchannel; - bool modeok = true, use_servermode = false; + bool connected, set, skiponce, retval, onchannel, modeok, use_servermode; int mode_arg, arg_arg; CLIENT *client; long l; @@ -331,28 +332,13 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel) if (Req->argc <= 1) return Channel_Mode_Answer_Request(Origin, Channel); - /* Is the user allowed to change modes? */ - if (Client_Type(Client) == CLIENT_USER) { - /* Is the originating user on that channel? */ - onchannel = Channel_IsMemberOf(Channel, Origin); - modeok = false; - /* channel operator? */ - if (onchannel && - strchr(Channel_UserModes(Channel, Origin), 'o')) { - modeok = true; - } else if (Conf_OperCanMode) { - /* IRC-Operators can use MODE as well */ - if (Client_OperByMe(Origin)) { - modeok = true; - if (Conf_OperServerMode) - use_servermode = true; /* Change Origin to Server */ - } - } + Channel_CheckAdminRights(Channel, Client, Origin, + &onchannel, &modeok, &use_servermode); - if (!onchannel && !modeok) - return IRC_WriteStrClient(Origin, ERR_NOTONCHANNEL_MSG, - Client_ID(Origin), Channel_Name(Channel)); - } + if (!onchannel && !modeok) + return IRC_WriteStrClient(Origin, ERR_NOTONCHANNEL_MSG, + Client_ID(Origin), + Channel_Name(Channel)); mode_arg = 1; mode_ptr = Req->argv[mode_arg]; @@ -515,6 +501,23 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel) goto chan_exit; } break; + case 'O': /* IRC operators only */ + if (modeok) { + /* Only IRC operators are allowed to + * set the 'O' channel mode! */ + if (set && !(Client_OperByMe(Client) + || Client_Type(Client) == CLIENT_SERVER)) + connected = IRC_WriteStrClient(Origin, + ERR_NOPRIVILEGES_MSG, + Client_ID(Origin)); + else + x[0] = 'O'; + } else + connected = IRC_WriteStrClient(Origin, + ERR_CHANOPRIVSNEEDED_MSG, + Client_ID(Origin), + Channel_Name(Channel)); + break; case 'P': /* Persistent channel */ if (modeok) { /* Only IRC operators are allowed to diff --git a/src/ngircd/irc-mode.h b/src/ngircd/irc-mode.h index dd5d9dd..4447afb 100644 --- a/src/ngircd/irc-mode.h +++ b/src/ngircd/irc-mode.h @@ -7,22 +7,19 @@ * 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. - * - * $Id: irc-mode.h,v 1.6 2005/03/19 18:43:48 fw Exp $ - * - * IRC commands for mode changes (header) */ - #ifndef __irc_mode_h__ #define __irc_mode_h__ +/** + * @file + * IRC commands for mode changes (header) + */ GLOBAL bool IRC_MODE PARAMS((CLIENT *Client, REQUEST *Req )); GLOBAL bool IRC_AWAY PARAMS((CLIENT *Client, REQUEST *Req )); - #endif - /* -eof- */ diff --git a/src/ngircd/irc-op.c b/src/ngircd/irc-op.c index e4d6f3b..5e36b02 100644 --- a/src/ngircd/irc-op.c +++ b/src/ngircd/irc-op.c @@ -7,13 +7,15 @@ * 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. - * - * Channel operator commands */ - #include "portab.h" +/** + * @file + * Channel operator commands + */ + #include "imp.h" #include #include diff --git a/src/ngircd/irc-op.h b/src/ngircd/irc-op.h index 0c8a0f2..f7ee450 100644 --- a/src/ngircd/irc-op.h +++ b/src/ngircd/irc-op.h @@ -7,22 +7,19 @@ * 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. - * - * $Id: irc-op.h,v 1.4 2005/03/19 18:43:48 fw Exp $ - * - * Channel operator commands (header) */ - #ifndef __irc_op_h__ #define __irc_op_h__ +/** + * @file + * Channel operator commands (header) + */ GLOBAL bool IRC_KICK PARAMS(( CLIENT *Client, REQUEST *Req )); GLOBAL bool IRC_INVITE PARAMS(( CLIENT *Client, REQUEST *Req )); - #endif - /* -eof- */ diff --git a/src/ngircd/irc-oper.c b/src/ngircd/irc-oper.c index 048c4f8..e8b8d26 100644 --- a/src/ngircd/irc-oper.c +++ b/src/ngircd/irc-oper.c @@ -7,13 +7,15 @@ * 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. - * - * IRC operator commands */ - #include "portab.h" +/** + * @file + * IRC operator commands + */ + #include "imp.h" #include #include diff --git a/src/ngircd/irc-oper.h b/src/ngircd/irc-oper.h index 8b867c4..7d67a0b 100644 --- a/src/ngircd/irc-oper.h +++ b/src/ngircd/irc-oper.h @@ -7,16 +7,15 @@ * 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. - * - * $Id: irc-oper.h,v 1.12 2007/08/02 10:14:26 fw Exp $ - * - * IRC operator commands (header) */ - #ifndef __irc_oper_h__ #define __irc_oper_h__ +/** + * @file + * IRC operator commands (header) + */ GLOBAL bool IRC_OPER PARAMS((CLIENT *Client, REQUEST *Req )); GLOBAL bool IRC_DIE PARAMS((CLIENT *Client, REQUEST *Req )); @@ -26,8 +25,6 @@ GLOBAL bool IRC_CONNECT PARAMS((CLIENT *Client, REQUEST *Req )); GLOBAL bool IRC_DISCONNECT PARAMS((CLIENT *Client, REQUEST *Req )); GLOBAL bool IRC_WALLOPS PARAMS(( CLIENT *Client, REQUEST *Req )); - #endif - /* -eof- */ diff --git a/src/ngircd/irc-server.c b/src/ngircd/irc-server.c index e7ff726..cca295a 100644 --- a/src/ngircd/irc-server.c +++ b/src/ngircd/irc-server.c @@ -7,13 +7,15 @@ * 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. - * - * IRC commands for server links */ - #include "portab.h" +/** + * @file + * IRC commands for server links + */ + #include "imp.h" #include #include @@ -275,6 +277,7 @@ IRC_SQUIT(CLIENT * Client, REQUEST * Req) char msg[COMMAND_LEN], logmsg[COMMAND_LEN]; CLIENT *from, *target; CONN_ID con; + int loglevel; assert(Client != NULL); assert(Req != NULL); @@ -299,7 +302,11 @@ IRC_SQUIT(CLIENT * Client, REQUEST * Req) return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG, Client_ID(Client), Req->prefix); - Log(LOG_DEBUG, "Got SQUIT from %s for \"%s\": \"%s\" ...", + if (Client_Type(Client) == CLIENT_USER) + loglevel = LOG_NOTICE | LOG_snotice; + else + loglevel = LOG_DEBUG; + Log(loglevel, "Got SQUIT from %s for \"%s\": \"%s\" ...", Client_ID(from), Req->argv[0], Req->argv[1]); target = Client_Search(Req->argv[0]); diff --git a/src/ngircd/irc-server.h b/src/ngircd/irc-server.h index 9940d79..39968d0 100644 --- a/src/ngircd/irc-server.h +++ b/src/ngircd/irc-server.h @@ -7,16 +7,15 @@ * 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. - * - * $Id: irc-server.h,v 1.6 2007/11/21 12:16:36 alex Exp $ - * - * IRC commands for server links (header) */ - #ifndef __irc_server_h__ #define __irc_server_h__ +/** + * @file + * IRC commands for server links (header) + */ GLOBAL bool IRC_SERVER PARAMS((CLIENT *Client, REQUEST *Req )); GLOBAL bool IRC_NJOIN PARAMS((CLIENT *Client, REQUEST *Req )); @@ -24,8 +23,6 @@ GLOBAL bool IRC_SQUIT PARAMS((CLIENT *Client, REQUEST *Req )); GLOBAL bool IRC_ENDOFMOTD_Server PARAMS((CLIENT *Client)); - #endif - /* -eof- */ diff --git a/src/ngircd/irc-write.c b/src/ngircd/irc-write.c index 07aadf4..16aac9a 100644 --- a/src/ngircd/irc-write.c +++ b/src/ngircd/irc-write.c @@ -7,13 +7,15 @@ * 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. - * - * Sending IRC commands over the network */ - #include "portab.h" +/** + * @file + * Sending IRC commands over the network + */ + #include "imp.h" #include #ifdef PROTOTYPES diff --git a/src/ngircd/irc-write.h b/src/ngircd/irc-write.h index f054314..dc8dec2 100644 --- a/src/ngircd/irc-write.h +++ b/src/ngircd/irc-write.h @@ -7,13 +7,16 @@ * 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. - * - * Sending IRC commands over the network (header) */ #ifndef __irc_write_h__ #define __irc_write_h__ +/** + * @file + * Sending IRC commands over the network (header) + */ + GLOBAL bool IRC_WriteStrClient PARAMS((CLIENT *Client, const char *Format, ...)); GLOBAL bool IRC_WriteStrClientPrefix PARAMS((CLIENT *Client, CLIENT *Prefix, const char *Format, ...)); diff --git a/src/ngircd/irc.c b/src/ngircd/irc.c index 75af321..8dd9bf7 100644 --- a/src/ngircd/irc.c +++ b/src/ngircd/irc.c @@ -7,14 +7,14 @@ * 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. - * - * IRC commands */ - #include "portab.h" -static char UNUSED id[] = "$Id: irc.c,v 1.132 2008/01/15 22:28:14 fw Exp $"; +/** + * @file + * IRC commands + */ #include "imp.h" #include diff --git a/src/ngircd/irc.h b/src/ngircd/irc.h index 358d91a..cdeb745 100644 --- a/src/ngircd/irc.h +++ b/src/ngircd/irc.h @@ -7,13 +7,16 @@ * 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. - * - * IRC commands (header) */ #ifndef __irc_h__ #define __irc_h__ +/** + * @file + * IRC commands (header) + */ + GLOBAL bool IRC_ERROR PARAMS((CLIENT *Client, REQUEST *Req)); GLOBAL bool IRC_KILL PARAMS((CLIENT *Client, REQUEST *Req)); GLOBAL bool IRC_NOTICE PARAMS((CLIENT *Client, REQUEST *Req)); diff --git a/src/ngircd/lists.c b/src/ngircd/lists.c index 363c62d..b30326d 100644 --- a/src/ngircd/lists.c +++ b/src/ngircd/lists.c @@ -7,13 +7,15 @@ * 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. - * - * Management of IRC lists: ban, invite, ... */ - #include "portab.h" +/** + * @file + * Management of IRC lists: ban, invite, etc. + */ + #include "imp.h" #include @@ -85,7 +87,6 @@ Lists_Add(struct list_head *header, const char *Mask, bool OnlyOnce ) newelem->next = e; header->first = newelem; - LogDebug("Added \"%s\" to invite list", Mask); return true; } @@ -209,7 +210,6 @@ Lists_MakeMask(const char *Pattern) } /* Lists_MakeMask */ - bool Lists_Check( struct list_head *header, CLIENT *Client) { diff --git a/src/ngircd/lists.h b/src/ngircd/lists.h index 6458e78..28f5478 100644 --- a/src/ngircd/lists.h +++ b/src/ngircd/lists.h @@ -7,13 +7,16 @@ * 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. - * - * Management of IRC lists: ban, invite, ... (header) */ - #ifndef __lists_h__ #define __lists_h__ + +/** + * @file + * Management of IRC lists (header) + */ + #include "portab.h" #include "client.h" @@ -23,7 +26,6 @@ struct list_head { struct list_elem *first; }; - GLOBAL struct list_elem *Lists_GetFirst PARAMS((const struct list_head *)); GLOBAL struct list_elem *Lists_GetNext PARAMS((const struct list_elem *)); @@ -41,4 +43,5 @@ GLOBAL const char *Lists_MakeMask PARAMS((const char *Pattern)); GLOBAL const char *Lists_GetMask PARAMS(( const struct list_elem *e )); #endif + /* -eof- */ diff --git a/src/ngircd/log.c b/src/ngircd/log.c index 0bc53ed..d79de26 100644 --- a/src/ngircd/log.c +++ b/src/ngircd/log.c @@ -7,13 +7,15 @@ * 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. - * - * Logging functions */ - #include "portab.h" +/** + * @file + * Logging functions + */ + #include "imp.h" #include #include diff --git a/src/ngircd/log.h b/src/ngircd/log.h index 9fdb8a2..5222b5d 100644 --- a/src/ngircd/log.h +++ b/src/ngircd/log.h @@ -7,14 +7,15 @@ * 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. - * - * Logging functions (header) */ - #ifndef __log_h__ #define __log_h__ +/** + * @file + * Logging functions (header) + */ #ifdef SYSLOG # include @@ -29,10 +30,8 @@ # define LOG_DEBUG 7 #endif - #define LOG_snotice 1024 - GLOBAL void Log_Init PARAMS(( bool Daemon_Mode )); GLOBAL void Log_Exit PARAMS(( void )); @@ -55,8 +54,6 @@ GLOBAL void Log_Subprocess PARAMS((const int Level, const char *Format, ...)); GLOBAL void Log_InitErrorfile PARAMS(( void )); #endif - #endif - /* -eof- */ diff --git a/src/ngircd/match.c b/src/ngircd/match.c index 5e97e71..79699ea 100644 --- a/src/ngircd/match.c +++ b/src/ngircd/match.c @@ -7,14 +7,14 @@ * 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. - * - * Wildcard pattern matching */ - #include "portab.h" -static char UNUSED id[] = "$Id: match.c,v 1.5 2006/10/06 21:23:47 fw Exp $"; +/** + * @file + * Wildcard pattern matching + */ #include "imp.h" #include @@ -27,10 +27,9 @@ static char UNUSED id[] = "$Id: match.c,v 1.5 2006/10/06 21:23:47 fw Exp $"; /* - * Die Pattern-Matching-Funkionen [Matche(), Matche_After_Star()] basieren - * auf Versionen von J. Kercheval. Die Version 1.1 wurde am 12.03.1991 als - * "public domain" freigegeben: - * + * The pattern matching functions [Matche(), Matche_After_Star()] are based + * on code of J. Kercheval. Version 1.1 has been released on 1991-03-12 as + * "public domain": */ @@ -38,14 +37,21 @@ static int Matche PARAMS(( const char *p, const char *t )); static int Matche_After_Star PARAMS(( const char *p, const char *t )); -#define MATCH_PATTERN 6 /* bad pattern */ -#define MATCH_LITERAL 5 /* match failure on literal match */ -#define MATCH_RANGE 4 /* match failure on [..] construct */ -#define MATCH_ABORT 3 /* premature end of text string */ -#define MATCH_END 2 /* premature end of pattern string */ -#define MATCH_VALID 1 /* valid match */ +#define MATCH_PATTERN 6 /**< bad pattern */ +#define MATCH_LITERAL 5 /**< match failure on literal match */ +#define MATCH_RANGE 4 /**< match failure on [..] construct */ +#define MATCH_ABORT 3 /**< premature end of text string */ +#define MATCH_END 2 /**< premature end of pattern string */ +#define MATCH_VALID 1 /**< valid match */ +/** + * Match string with pattern. + * + * @param Pattern Pattern to match with + * @param String Input string + * @return true if pattern matches + */ GLOBAL bool Match( const char *Pattern, const char *String ) { @@ -55,6 +61,13 @@ Match( const char *Pattern, const char *String ) } /* Match */ +/** + * Match string with pattern case-insensitive. + * + * @param pattern Pattern to match with + * @param searchme Input string, at most COMMAND_LEN-1 characters long + * @return true if pattern matches + */ GLOBAL bool MatchCaseInsensitive(const char *pattern, const char *searchme) { diff --git a/src/ngircd/match.h b/src/ngircd/match.h index 0e8df74..2efe3f5 100644 --- a/src/ngircd/match.h +++ b/src/ngircd/match.h @@ -7,22 +7,19 @@ * 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. - * - * $Id: match.h,v 1.4 2006/10/06 21:23:47 fw Exp $ - * - * Wildcard pattern matching (header) */ - #ifndef __match_h__ #define __match_h__ +/** + * @file + * Wildcard pattern matching (header) + */ GLOBAL bool Match PARAMS(( const char *Pattern, const char *String )); GLOBAL bool MatchCaseInsensitive PARAMS(( const char *Pattern, const char *searchme )); - #endif - /* -eof- */ diff --git a/src/ngircd/messages.h b/src/ngircd/messages.h index 900d2ff..93bef3d 100644 --- a/src/ngircd/messages.h +++ b/src/ngircd/messages.h @@ -7,14 +7,15 @@ * 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. - * - * IRC numerics (Header) */ - #ifndef __messages_h__ #define __messages_h__ +/** + * @file + * IRC numerics (Header) + */ #define RPL_WELCOME_MSG "001 %s :Welcome to the Internet Relay Network %s" #define RPL_YOURHOST_MSG "002 %s :Your host is %s, running version ngircd-%s (%s/%s/%s)" @@ -117,6 +118,7 @@ #define ERR_PASSWDMISMATCH_MSG "464 %s :Invalid password" #define ERR_CHANNELISFULL_MSG "471 %s %s :Cannot join channel (+l)" #define ERR_SECURECHANNEL_MSG "471 %s %s :Cannot join channel (+z)" +#define ERR_OPONLYCHANNEL_MSG "471 %s %s :Cannot join channel (+O)" #define ERR_UNKNOWNMODE_MSG "472 %s: %c :is unknown mode char for %s" #define ERR_INVITEONLYCHAN_MSG "473 %s %s :Cannot join channel (+i)" #define ERR_BANNEDFROMCHAN_MSG "474 %s %s :Cannot join channel (+b)" @@ -136,8 +138,6 @@ #define RPL_STATSLINKINFOZIP_MSG "211 %s %s %d %ld %ld/%ld %ld %ld/%ld :%ld" #endif - #endif - /* -eof- */ diff --git a/src/ngircd/ngircd.c b/src/ngircd/ngircd.c index 6dfd206..500d128 100644 --- a/src/ngircd/ngircd.c +++ b/src/ngircd/ngircd.c @@ -1,6 +1,6 @@ /* * ngIRCd -- The Next Generation IRC Daemon - * Copyright (c)2001-2010 Alexander Barton (alex@barton.de). + * 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 @@ -9,7 +9,6 @@ * Please read the file COPYING, README and AUTHORS for more information. */ - #include "portab.h" /** @@ -49,10 +48,6 @@ #include "io.h" #include "irc.h" -#ifdef ZEROCONF -#include "rendezvous.h" -#endif - #include "exp.h" #include "ngircd.h" @@ -65,6 +60,8 @@ static void Pidfile_Delete PARAMS(( void )); static void Fill_Version PARAMS(( void )); +static void Random_Init PARAMS(( void )); + static void Setup_FDStreams PARAMS(( int fd )); static bool NGIRCd_Init PARAMS(( bool )); @@ -72,11 +69,13 @@ static bool NGIRCd_Init PARAMS(( bool )); /** * The main() function of ngIRCd. + * * Here all starts: this function is called by the operating system loader, * it is the first portion of code executed of ngIRCd. - * @param argc The number of arguments passed to ngIRCd on the command line. - * @param argv An array containing all the arguments passed to ngIRCd. - * @return Global exit code of ngIRCd, zero on success. + * + * @param argc The number of arguments passed to ngIRCd on the command line. + * @param argv An array containing all the arguments passed to ngIRCd. + * @return Global exit code of ngIRCd, zero on success. */ GLOBAL int main( int argc, const char *argv[] ) @@ -237,7 +236,7 @@ main( int argc, const char *argv[] ) } } - /* Debug-Level (for IRCs "VERSION" command) */ + /* Debug level for "VERSION" command */ NGIRCd_DebugLevel[0] = '\0'; #ifdef DEBUG if( NGIRCd_Debug ) strcpy( NGIRCd_DebugLevel, "1" ); @@ -265,6 +264,8 @@ main( int argc, const char *argv[] ) NGIRCd_SignalRestart = false; NGIRCd_SignalQuit = false; + Random_Init(); + /* Initialize modules, part I */ Log_Init( ! NGIRCd_NoDaemon ); Conf_Init( ); @@ -280,9 +281,6 @@ main( int argc, const char *argv[] ) * called with already dropped privileges ... */ Channel_Init( ); Client_Init( ); -#ifdef ZEROCONF - Rendezvous_Init( ); -#endif Conn_Init( ); if (!io_library_init(CONNECTION_POOL)) { @@ -295,11 +293,9 @@ main( int argc, const char *argv[] ) exit(1); } - /* - * create protocol and server identification. - * The syntax used by ngIRCd in PASS commands and the extended flags - * are described in doc/Protocol.txt - */ + /* Create protocol and server identification. The syntax + * used by ngIRCd in PASS commands and the known "extended + * flags" are described in doc/Protocol.txt. */ #ifdef IRCPLUS snprintf( NGIRCd_ProtoID, sizeof NGIRCd_ProtoID, "%s%s %s|%s:%s", PROTOVER, PROTOIRCPLUS, PACKAGE_NAME, PACKAGE_VERSION, IRCPLUSFLAGS ); #ifdef ZLIB @@ -324,15 +320,11 @@ main( int argc, const char *argv[] ) Pidfile_Delete( ); exit( 1 ); } - - /* Hauptschleife */ + + /* Main Run Loop */ Conn_Handler( ); - /* Alles abmelden */ Conn_Exit( ); -#ifdef ZEROCONF - Rendezvous_Exit( ); -#endif Client_Exit( ); Channel_Exit( ); Log_Exit( ); @@ -344,10 +336,12 @@ main( int argc, const char *argv[] ) /** - * Generate ngIRCd "version string". - * This string is generated once and then stored in NGIRCd_Version for - * further usage, for example by the IRC command VERSION and the --version - * command line switch. + * Generate ngIRCd "version strings". + * + * The ngIRCd version information is generated once and then stored in the + * NGIRCd_Version and NGIRCd_VersionAddition string variables for further + * usage, for example by the IRC command "VERSION" and the --version command + * line switch. */ static void Fill_Version( void ) @@ -371,11 +365,6 @@ Fill_Version( void ) strlcat( NGIRCd_VersionAddition, "+", sizeof NGIRCd_VersionAddition ); strlcat( NGIRCd_VersionAddition, "TCPWRAP", sizeof NGIRCd_VersionAddition ); #endif -#ifdef ZEROCONF - if( NGIRCd_VersionAddition[0] ) - strlcat( NGIRCd_VersionAddition, "+", sizeof NGIRCd_VersionAddition ); - strlcat( NGIRCd_VersionAddition, "ZEROCONF", sizeof NGIRCd_VersionAddition ); -#endif #ifdef IDENTAUTH if( NGIRCd_VersionAddition[0] ) strlcat( NGIRCd_VersionAddition, "+", sizeof NGIRCd_VersionAddition ); @@ -422,7 +411,7 @@ Fill_Version( void ) snprintf(NGIRCd_Version, sizeof NGIRCd_Version, "%s %s-%s", PACKAGE_NAME, PACKAGE_VERSION, NGIRCd_VersionAddition); - } /* Fill_Version */ +} /* Fill_Version */ /** @@ -432,7 +421,7 @@ static void Show_Version( void ) { puts( NGIRCd_Version ); - puts( "Copyright (c)2001-2010 Alexander Barton () and Contributors." ); + puts( "Copyright (c)2001-2011 Alexander Barton () and Contributors." ); puts( "Homepage: \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." ); @@ -482,7 +471,8 @@ Pidfile_Delete( void ) /** * Create the file containing the process ID of ngIRCd ("PID file"). - * @param pid The process ID to be stored in this file. + * + * @param pid The process ID to be stored in this file. */ static void Pidfile_Create(pid_t pid) @@ -520,6 +510,8 @@ Pidfile_Create(pid_t pid) /** * Redirect stdin, stdout and stderr to apropriate file handles. + * + * @param fd The file handle stdin, stdout and stderr should be redirected to. */ static void Setup_FDStreams(int fd) @@ -535,6 +527,13 @@ Setup_FDStreams(int fd) } /* Setup_FDStreams */ +/** + * Get user and group ID of unprivileged "nobody" user. + * + * @param uid User ID + * @param gid Group ID + * @return true on success. + */ static bool NGIRCd_getNobodyID(uid_t *uid, gid_t *gid ) { @@ -559,14 +558,52 @@ NGIRCd_getNobodyID(uid_t *uid, gid_t *gid ) if ( !pwd->pw_uid || !pwd->pw_gid) return false; - *uid = pwd->pw_uid; + *uid = pwd->pw_uid; *gid = pwd->pw_gid; endpwent(); - return true; + return true; +} /* NGIRCd_getNobodyID */ + + +static bool +Random_Init_Kern(const char *file) +{ + unsigned int seed; + bool ret = false; + int fd = open(file, O_RDONLY); + if (fd >= 0) { + if (read(fd, &seed, sizeof(seed)) == sizeof(seed)) + ret = true; + close(fd); + srand(seed); + } + return ret; +} + +/** + * Initialize libc rand(3) number generator + */ +static void +Random_Init(void) +{ + if (Random_Init_Kern("/dev/urandom")) + return; + if (Random_Init_Kern("/dev/random")) + return; + if (Random_Init_Kern("/dev/arandom")) + return; + srand(rand() ^ getpid() ^ time(NULL)); } +/** + * Initialize ngIRCd daemon. + * + * @param NGIRCd_NoDaemon Set to true if ngIRCd should run in the + * foreground and not as a daemon. + * @return true on success. + */ static bool NGIRCd_Init( bool NGIRCd_NoDaemon ) { @@ -669,10 +706,8 @@ NGIRCd_Init( bool NGIRCd_NoDaemon ) /* Detach stdin, stdout and stderr */ Setup_FDStreams(fd); - if (fd > 2) { + if (fd > 2) close(fd); - fd = -1; - } } pid = getpid(); @@ -717,7 +752,7 @@ NGIRCd_Init( bool NGIRCd_NoDaemon ) if (fd > 2) close(fd); return false; -} +} /* NGIRCd_Init */ /* -eof- */ diff --git a/src/ngircd/ngircd.h b/src/ngircd/ngircd.h index bd699e5..2efb8a9 100644 --- a/src/ngircd/ngircd.h +++ b/src/ngircd/ngircd.h @@ -1,55 +1,75 @@ /* * ngIRCd -- The Next Generation IRC Daemon - * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de) + * 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 * 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. - * - * $Id: ngircd.h,v 1.22 2005/06/24 19:20:56 fw Exp $ - * - * Prototypes of the "main module". */ - #ifndef __ngircd_h__ #define __ngircd_h__ +/** + * @file + * Global variables of ngIRCd. + */ + #include #include "defines.h" #define C_ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0])) +/** UNIX timestamp of ngIRCd start */ +GLOBAL time_t NGIRCd_Start; -GLOBAL time_t NGIRCd_Start; /* Startzeitpunkt des Daemon */ +/** ngIRCd start time as string, used for RPL_CREATED_MSG (003) */ GLOBAL char NGIRCd_StartStr[64]; + +/** ngIRCd version number containing release number and compile-time options */ GLOBAL char NGIRCd_Version[126]; + +/** String specifying the compile-time options and target platform */ GLOBAL char NGIRCd_VersionAddition[126]; #ifdef DEBUG -GLOBAL bool NGIRCd_Debug; /* Debug-Modus aktivieren */ +/** Flag indicating if debug mode is active (true) or not (false) */ +GLOBAL bool NGIRCd_Debug; #endif #ifdef SNIFFER -GLOBAL bool NGIRCd_Sniffer; /* Sniffer aktivieren */ +/** Flag indication if sniffer is active (true) or not (false) */ +GLOBAL bool NGIRCd_Sniffer; #endif -GLOBAL bool NGIRCd_Passive; /* nicht zu anderen Servern connecten */ +/** + * Flag indicating if NO outgoing connections should be established (true) + * or not (false, the default) + */ +GLOBAL bool NGIRCd_Passive; -GLOBAL bool NGIRCd_SignalQuit; /* true: quit server*/ -GLOBAL bool NGIRCd_SignalRestart; /* true: restart server */ +/** Flag indicating that ngIRCd has been requested to quit (true) */ +GLOBAL bool NGIRCd_SignalQuit; -GLOBAL char NGIRCd_DebugLevel[2]; /* Debug-Level fuer IRC_VERSION() */ +/** Flag indicating that ngIRCd has been requested to restart (true) */ +GLOBAL bool NGIRCd_SignalRestart; -GLOBAL char NGIRCd_ConfFile[FNAME_LEN]; /* Konfigurationsdatei */ +/** + * Debug level for "VERSION" command, see description of numeric RPL_VERSION + * (351) in RFC 2812. ngIRCd sets debuglevel to 1 when the debug mode is + * active, and to 2 if the sniffer is running. + */ +GLOBAL char NGIRCd_DebugLevel[2]; -GLOBAL char NGIRCd_ProtoID[COMMAND_LEN];/* Protokoll- und Server-Identifikation */ +/** Full path and file name of current configuration file */ +GLOBAL char NGIRCd_ConfFile[FNAME_LEN]; +/** Protocol and server identification string; see doc/Protocol.txt */ +GLOBAL char NGIRCd_ProtoID[COMMAND_LEN]; #endif - /* -eof- */ diff --git a/src/ngircd/numeric.c b/src/ngircd/numeric.c index 0dcfe75..ba6c025 100644 --- a/src/ngircd/numeric.c +++ b/src/ngircd/numeric.c @@ -7,12 +7,15 @@ * 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. - * - * Handlers for IRC numerics sent to the server */ #include "portab.h" +/** + * @file + * Handlers for IRC numerics sent to the server + */ + #include "imp.h" #include #include diff --git a/src/ngircd/numeric.h b/src/ngircd/numeric.h index eca11ba..d9efa4b 100644 --- a/src/ngircd/numeric.h +++ b/src/ngircd/numeric.h @@ -7,15 +7,16 @@ * 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. - * - * $Id: numeric.h,v 1.1 2007/11/21 12:20:32 alex Exp $ - * - * Handlers for IRC numerics sent to the server (header) */ #ifndef __numeric_h__ #define __numeric_h__ +/** + * @file + * Handlers for IRC numerics sent to the server (header) + */ + GLOBAL bool IRC_Num_ENDOFMOTD PARAMS((CLIENT *Client, UNUSED REQUEST *Req)); GLOBAL bool IRC_Num_ISUPPORT PARAMS((CLIENT *Client, REQUEST *Req)); diff --git a/src/ngircd/op.c b/src/ngircd/op.c index c70be6e..7c0737f 100644 --- a/src/ngircd/op.c +++ b/src/ngircd/op.c @@ -7,13 +7,15 @@ * 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. - * - * IRC operator functions */ - #include "portab.h" +/** + * @file + * IRC operator functions + */ + #include "imp.h" #include #include @@ -29,6 +31,7 @@ #include #include "op.h" + /** * Return and log a "no privileges" message. */ @@ -79,3 +82,6 @@ Op_Check(CLIENT * Client, REQUEST * Req) * to trust remote operators. */ return true; } /* Op_Check */ + + +/* -eof- */ diff --git a/src/ngircd/op.h b/src/ngircd/op.h index 544be25..a1a84a3 100644 --- a/src/ngircd/op.h +++ b/src/ngircd/op.h @@ -7,13 +7,16 @@ * 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. - * - * Operator management (header) */ #ifndef __oper_h__ #define __oper_h__ +/** + * @file + * IRC operator functions (header) + */ + GLOBAL bool Op_NoPrivileges PARAMS((CLIENT * Client, REQUEST * Req)); GLOBAL bool Op_Check PARAMS((CLIENT * Client, REQUEST * Req)); diff --git a/src/ngircd/pam.c b/src/ngircd/pam.c index 0d4f27f..b28e866 100644 --- a/src/ngircd/pam.c +++ b/src/ngircd/pam.c @@ -7,14 +7,17 @@ * 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. - * - * PAM User Authentification */ #include "portab.h" #ifdef PAM +/** + * @file + * PAM User Authentification + */ + #include "imp.h" #include diff --git a/src/ngircd/pam.h b/src/ngircd/pam.h index 74b838d..ba31d50 100644 --- a/src/ngircd/pam.h +++ b/src/ngircd/pam.h @@ -7,8 +7,6 @@ * 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. - * - * PAM User Authentification (header) */ #ifdef PAM @@ -16,6 +14,11 @@ #ifndef __pam_h__ #define __pam_h__ +/** + * @file + * PAM User Authentification (header) + */ + GLOBAL bool PAM_Authenticate PARAMS((CLIENT *Client)); #endif /* __pam_h__ */ diff --git a/src/ngircd/parse.c b/src/ngircd/parse.c index 479b300..72e3430 100644 --- a/src/ngircd/parse.c +++ b/src/ngircd/parse.c @@ -47,6 +47,7 @@ #include "numeric.h" #include "exp.h" +#include "conf.h" struct _NUMERIC { int numeric; @@ -82,7 +83,7 @@ static COMMAND My_Commands[] = { "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, 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 }, @@ -109,6 +110,10 @@ static COMMAND My_Commands[] = #ifdef IRCPLUS { "CHANINFO", IRC_CHANINFO, CLIENT_SERVER, 0, 0, 0 }, #endif +#ifndef STRICT_RFC + { "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 } /* Ende-Marke */ }; @@ -120,6 +125,8 @@ static bool Validate_Args PARAMS(( CONN_ID Idx, REQUEST *Req, bool *Closed )); static bool Handle_Request PARAMS(( CONN_ID Idx, REQUEST *Req )); +static bool ScrubCTCP PARAMS((char *Request)); + /** * Return the pointer to the global "IRC command structure". * This structure, an array of type "COMMAND" describes all the IRC commands @@ -170,15 +177,17 @@ Parse_Request( CONN_ID Idx, char *Request ) /* remove leading & trailing whitespace */ ngt_TrimStr( Request ); - if( Request[0] == ':' ) - { + if (Conf_ScrubCTCP && ScrubCTCP(Request)) + return true; + + if (Request[0] == ':') { /* Prefix */ req.prefix = Request + 1; ptr = strchr( Request, ' ' ); if( ! ptr ) { LogDebug("Connection %d: Parse error: prefix without command!?", Idx); - return Conn_WriteStr( Idx, "ERROR :Prefix without command!?" ); + return Conn_WriteStr(Idx, "ERROR :Prefix without command"); } *ptr = '\0'; #ifndef STRICT_RFC @@ -272,14 +281,29 @@ Validate_Prefix( CONN_ID Idx, REQUEST *Req, bool *Closed ) *Closed = false; - if( ! Req->prefix ) return true; - client = Conn_GetClient( Idx ); assert( client != NULL ); - /* only validate if this connection is already registered */ - if(( Client_Type( client ) != CLIENT_USER ) && ( Client_Type( client ) != CLIENT_SERVER ) && ( Client_Type( client ) != CLIENT_SERVICE )) + if (!Req->prefix && Client_Type(client) == CLIENT_SERVER + && !(Conn_Options(Idx) & CONN_RFC1459) + && strcasecmp(Req->command, "ERROR") != 0 + && strcasecmp(Req->command, "PING") != 0) { + Log(LOG_ERR, + "Received command without prefix (connection %d, command \"%s\")!?", + Idx, Req->command); + if (!Conn_WriteStr(Idx, "ERROR :Prefix missing")) + *Closed = true; + return false; + } + + if (!Req->prefix) + return true; + + /* only validate if this connection is already registered */ + if (Client_Type(client) != CLIENT_USER + && Client_Type(client) != CLIENT_SERVER + && Client_Type(client) != CLIENT_SERVICE) { /* not registered, ignore prefix */ Req->prefix = NULL; return true; @@ -287,19 +311,25 @@ Validate_Prefix( CONN_ID Idx, REQUEST *Req, bool *Closed ) /* check if client in prefix is known */ c = Client_Search( Req->prefix ); - if( ! c ) - { - 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; + if (!c) { + 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 ) - { - Log( LOG_ERR, "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); + if (Client_NextHop(c) != client) { + Log(LOG_ERR, + "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; return false; } @@ -434,7 +464,6 @@ Handle_Numeric(CLIENT *client, REQUEST *Req) return IRC_WriteStrClientPrefix(target, prefix, "%s", str); } - static bool Handle_Request( CONN_ID Idx, REQUEST *Req ) { @@ -500,4 +529,39 @@ Handle_Request( CONN_ID Idx, REQUEST *Req ) } /* Handle_Request */ +/** + * Check if incoming messages contains CTCP commands and should be dropped. + * + * @param Request NULL terminated incoming command. + * @returns true, when the message should be dropped. + */ +static bool +ScrubCTCP(char *Request) +{ + static const char me_cmd[] = "ACTION "; + static const char ctcp_char = 0x1; + bool dropCommand = false; + char *ptr = Request; + char *ptrEnd = strchr(Request, '\0'); + + if (Request[0] == ':' && ptrEnd > ptr) + ptr++; + + while (ptr != ptrEnd && *ptr != ':') + ptr++; + + if ((ptrEnd - ptr) > 1) { + ptr++; + if (*ptr == ctcp_char) { + dropCommand = true; + ptr++; + /* allow /me commands */ + if ((size_t)(ptrEnd - ptr) >= strlen(me_cmd) + && !strncmp(ptr, me_cmd, strlen(me_cmd))) + dropCommand = false; + } + } + return dropCommand; +} + /* -eof- */ diff --git a/src/ngircd/parse.h b/src/ngircd/parse.h index 205dbb8..0c6f8a6 100644 --- a/src/ngircd/parse.h +++ b/src/ngircd/parse.h @@ -7,42 +7,42 @@ * 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. - * - * $Id: parse.h,v 1.13 2008/01/13 16:12:49 fw Exp $ - * - * IRC command parser and validator (header) */ - #ifndef __parse_h__ #define __parse_h__ +/** + * @file + * IRC command parser and validator (header) + */ + #include "portab.h" -typedef struct _REQUEST /* vgl. RFC 2812, 2.3 */ +/** A single IRC request ("command"). See RFC 2812 section 2.3 for details. */ +typedef struct _REQUEST { - char *prefix; /* Prefix */ - char *command; /* IRC-Befehl */ - char *argv[15]; /* Parameter (max. 15: 0..14) */ - int argc; /* Anzahl vorhandener Parameter */ + char *prefix; /**< Prefix */ + char *command; /**< IRC command */ + char *argv[15]; /**< Parameters, at most 15 (0..14) */ + int argc; /**< Number of given paramaters */ } REQUEST; - +/** IRC command handling structure */ typedef struct _COMMAND { - const char *name; /* command name */ + const char *name; /**< Command name */ bool (*function) PARAMS(( CLIENT *Client, REQUEST *Request )); - CLIENT_TYPE type; /* valid client types (bit mask) */ - long lcount, rcount; /* number of local and remote calls */ - long bytes; /* number of bytes created */ + /**< Function to handle this command */ + CLIENT_TYPE type; /**< Valid client types (bit mask) */ + long lcount, rcount; /**< Number of local and remote calls */ + long bytes; /**< Number of bytes created */ } COMMAND; - GLOBAL bool Parse_Request PARAMS((CONN_ID Idx, char *Request )); GLOBAL COMMAND *Parse_GetCommandStruct PARAMS(( void )); #endif - /* -eof- */ diff --git a/src/ngircd/proc.c b/src/ngircd/proc.c index 614aef4..54b3919 100644 --- a/src/ngircd/proc.c +++ b/src/ngircd/proc.c @@ -7,12 +7,15 @@ * 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. - * - * Process management */ #include "portab.h" +/** + * @file + * Process management + */ + #include "imp.h" #include #include @@ -47,6 +50,7 @@ GLOBAL pid_t Proc_Fork(PROC_STAT *proc, int *pipefds, void (*cbfunc)(int, short), int timeout) { pid_t pid; + unsigned int seed; assert(proc != NULL); assert(pipefds != NULL); @@ -58,6 +62,7 @@ Proc_Fork(PROC_STAT *proc, int *pipefds, void (*cbfunc)(int, short), int timeout return -1; } + seed = (unsigned int)rand(); pid = fork(); switch (pid) { case -1: @@ -68,6 +73,7 @@ Proc_Fork(PROC_STAT *proc, int *pipefds, void (*cbfunc)(int, short), int timeout return -1; case 0: /* New child process: */ + srand(seed ^ (unsigned int)time(NULL) ^ getpid()); Signals_Exit(); signal(SIGTERM, Proc_GenericSignalHandler); signal(SIGALRM, Proc_GenericSignalHandler); diff --git a/src/ngircd/proc.h b/src/ngircd/proc.h index 57612f1..84b61f2 100644 --- a/src/ngircd/proc.h +++ b/src/ngircd/proc.h @@ -7,20 +7,26 @@ * 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. - * - * Process management (header) */ #ifndef __proc_h__ #define __proc_h__ -/* This struct must not be accessed directly! */ +/** + * @file + * Process management (header) + */ + +/** Process status. This struct must not be accessed directly! */ typedef struct _Proc_Stat { - pid_t pid; /* PID of the child process or 0 if none */ - int pipe_fd; /* Pipe file descriptor or -1 if none */ + pid_t pid; /**< PID of the child process or 0 if none */ + int pipe_fd; /**< Pipe file descriptor or -1 if none */ } PROC_STAT; +/** Return true if sub-process is still running */ #define Proc_InProgress(x) ((x)->pid != 0) + +/** Return file descriptor of pipe to sub-process (or -1 if none open) */ #define Proc_GetPipeFd(x) ((x)->pipe_fd) GLOBAL void Proc_InitStruct PARAMS((PROC_STAT *proc)); diff --git a/src/ngircd/rendezvous.c b/src/ngircd/rendezvous.c deleted file mode 100644 index c0c22eb..0000000 --- a/src/ngircd/rendezvous.c +++ /dev/null @@ -1,372 +0,0 @@ -/* - * ngIRCd -- The Next Generation IRC Daemon - * Copyright (c)2001-2010 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 - * 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. - * - * Rendezvous service registration. - * - * Supported APIs are: - * - Apple Mac OS X - * - Howl - */ - - -#include "portab.h" - -#ifdef ZEROCONF - - -#include "imp.h" -#include - -#include -#include - -#ifdef HAVE_MACH_PORT_H -#include "mach/port.h" -#include "mach/message.h" -#endif - -#ifdef HAVE_DNSSERVICEDISCOVERY_DNSSERVICEDISCOVERY_H -#include -#endif - -#ifdef HAVE_RENDEZVOUS_RENDEZVOUS_H -#include -#endif - -#include "defines.h" -#include "conn.h" -#include "conf.h" -#include "log.h" - -#include "exp.h" -#include "rendezvous.h" - - -#if defined(HAVE_DNSSERVICEREGISTRATIONCREATE) -# define APPLE -#elif defined(HAVE_SW_DISCOVERY_INIT) -# define HOWL -#else -# error "Can't detect Rendezvous API!?" -#endif - - -#define MAX_RENDEZVOUS 1000 - -typedef struct _service -{ - char Desc[CLIENT_ID_LEN]; -#ifdef APPLE - dns_service_discovery_ref Discovery_Ref; - mach_port_t Mach_Port; -#endif -#ifdef HOWL - sw_discovery_oid Id; -#endif -} SERVICE; - -static SERVICE My_Rendezvous[MAX_RENDEZVOUS]; - - -static void Unregister( int Idx ); - - -/* -- Apple API -- */ - -#ifdef APPLE - -#define MAX_MACH_MSG_SIZE 512 - -static void Registration_Reply_Handler( DNSServiceRegistrationReplyErrorType ErrCode, void *Context ); - -#endif /* Apple */ - - -/* -- Howl API -- */ - -#ifdef HOWL - -static sw_discovery My_Discovery_Session = NULL; -static sw_salt My_Salt; - -static sw_result HOWL_API Registration_Reply_Handler( sw_discovery Session, sw_discovery_publish_status Status, sw_discovery_oid Id, sw_opaque Extra ); - -#endif /* Howl */ - - -GLOBAL void Rendezvous_Init( void ) -{ - /* Initialize structures */ - - int i; - -#ifdef HOWL - if( sw_discovery_init( &My_Discovery_Session ) != SW_OKAY ) - { - Log( LOG_EMERG, "Can't initialize Rendezvous (Howl): sw_discovery_init() failed!" ); - Log( LOG_ALERT, "%s exiting due to fatal errors!", PACKAGE_NAME ); - exit( 1 ); - } - - if( sw_discovery_salt( My_Discovery_Session, &My_Salt ) != SW_OKAY ) - { - Log( LOG_EMERG, "Can't initialize Rendezvous (Howl): sw_discovery_salt() failed!" ); - Log( LOG_ALERT, "%s exiting due to fatal errors!", PACKAGE_NAME ); - exit( 1 ); - } -#endif - - for( i = 0; i < MAX_RENDEZVOUS; i++ ) My_Rendezvous[i].Desc[0] = '\0'; -} /* Rendezvous_Init */ - - -GLOBAL void Rendezvous_Exit( void ) -{ - /* Clean up & exit module */ - - int i; - - for( i = 0; i < MAX_RENDEZVOUS; i++ ) - { - if( My_Rendezvous[i].Desc[0] ) Unregister( i ); - } - -#ifdef HOWL - sw_discovery_fina( My_Discovery_Session ); -#endif -} /* Rendezvous_Exit */ - - -/** - * Register ZeroConf service - */ -GLOBAL bool Rendezvous_Register( char *Name, char *Type, UINT16 Port ) -{ - int i; - - if (Conf_NoZeroConf) - return true; - - /* Search free port structure */ - for( i = 0; i < MAX_RENDEZVOUS; i++ ) if( ! My_Rendezvous[i].Desc[0] ) break; - if( i >= MAX_RENDEZVOUS ) - { - Log( LOG_ERR, "Can't register \"%s\" with Rendezvous: limit (%d) reached!", Name, MAX_RENDEZVOUS ); - return false; - } - strlcpy( My_Rendezvous[i].Desc, Name, sizeof( My_Rendezvous[i].Desc )); - -#ifdef APPLE - /* Register new service */ - My_Rendezvous[i].Discovery_Ref = DNSServiceRegistrationCreate( Name, Type, "", htonl( Port ), "", Registration_Reply_Handler, &My_Rendezvous[i] ); - if( ! My_Rendezvous[i].Discovery_Ref ) - { - Log( LOG_ERR, "Can't register \"%s\" with Rendezvous: can't register service!", My_Rendezvous[i].Desc ); - My_Rendezvous[i].Desc[0] = '\0'; - return false; - } - - /* Get and save the corresponding Mach Port */ - My_Rendezvous[i].Mach_Port = DNSServiceDiscoveryMachPort( My_Rendezvous[i].Discovery_Ref ); - if( ! My_Rendezvous[i].Mach_Port ) - { - Log( LOG_ERR, "Can't register \"%s\" with Rendezvous: got no Mach Port!", My_Rendezvous[i].Desc ); - /* Here we actually leek a descriptor :-( */ - My_Rendezvous[i].Discovery_Ref = 0; - My_Rendezvous[i].Desc[0] = '\0'; - return false; - } -#endif /* Apple */ - -#ifdef HOWL - if( sw_discovery_publish( My_Discovery_Session, 0, Name, Type, NULL, NULL, Port, NULL, 0, Registration_Reply_Handler, &My_Rendezvous[i], &My_Rendezvous[i].Id ) != SW_OKAY ) - { - Log( LOG_ERR, "Can't register \"%s\" with Rendezvous: can't register service!", My_Rendezvous[i].Desc ); - My_Rendezvous[i].Desc[0] = '\0'; - return false; - } -#endif /* Howl */ - - Log( LOG_DEBUG, "Rendezvous: Registering \"%s\" ...", My_Rendezvous[i].Desc ); - return true; -} /* Rendezvous_Register */ - - -GLOBAL bool Rendezvous_Unregister( char *Name ) -{ - /* Unregister service from rendezvous */ - - int i; - bool ok; - - ok = false; - for( i = 0; i < MAX_RENDEZVOUS; i++ ) - { - if( strcmp( Name, My_Rendezvous[i].Desc ) == 0 ) - { - Unregister( i ); - ok = true; - } - } - - return ok; -} /* Rendezvous_Unregister */ - - -GLOBAL void Rendezvous_UnregisterListeners( void ) -{ - /* Unregister all our listening sockets from Rendezvous */ - - int i; - - for( i = 0; i < MAX_RENDEZVOUS; i++ ) - { - if( My_Rendezvous[i].Desc[0] ) Unregister( i ); - } -} /* Rendezvous_UnregisterListeners */ - - -GLOBAL void Rendezvous_Handler( void ) -{ - /* Handle all Rendezvous stuff; this function must be called - * periodically from the run loop of the main program */ - -#ifdef APPLE - int i; - char buffer[MAX_MACH_MSG_SIZE]; - mach_msg_return_t result; - mach_msg_header_t *msg; - - for( i = 0; i < MAX_RENDEZVOUS; i++ ) - { - if( ! My_Rendezvous[i].Discovery_Ref ) continue; - - /* Read message from Mach Port */ - msg = (mach_msg_header_t *)buffer; - result = mach_msg( msg, MACH_RCV_MSG|MACH_RCV_TIMEOUT, 0, MAX_MACH_MSG_SIZE, My_Rendezvous[i].Mach_Port, 1, 0 ); - - /* Handle message */ - if( result == MACH_MSG_SUCCESS ) DNSServiceDiscovery_handleReply( msg ); -#ifdef DEBUG - else if( result != MACH_RCV_TIMED_OUT ) Log( LOG_DEBUG, "mach_msg(): %ld", (long)result ); -#endif /* Debug */ - } -#endif /* Apple */ - -#ifdef HOWL - sw_ulong msecs = 10; - sw_salt_step( My_Salt, &msecs ); -#endif -} /* Rendezvous_Handler */ - - -static void Unregister( int Idx ) -{ - /* Unregister service */ - -#ifdef APPLE - DNSServiceDiscoveryDeallocate( My_Rendezvous[Idx].Discovery_Ref ); -#endif /* Apple */ - -#ifdef HOWL - if( sw_discovery_cancel( My_Discovery_Session, My_Rendezvous[Idx].Id ) != SW_OKAY ) - { - Log( LOG_ERR, "Rendezvous: Failed to unregister \"%s\"!", My_Rendezvous[Idx].Desc ); - return; - } -#endif /* Howl */ - - Log( LOG_INFO, "Unregistered \"%s\" from Rendezvous.", My_Rendezvous[Idx].Desc ); - My_Rendezvous[Idx].Desc[0] = '\0'; -} /* Unregister */ - - -/* -- Apple API -- */ - -#ifdef APPLE - - -static void Registration_Reply_Handler( DNSServiceRegistrationReplyErrorType ErrCode, void *Context ) -{ - SERVICE *s = (SERVICE *)Context; - char txt[50]; - - if( ErrCode == kDNSServiceDiscoveryNoError ) - { - /* Success! */ - Log( LOG_INFO, "Successfully registered \"%s\" with Rendezvous.", s->Desc ); - return; - } - - switch( ErrCode ) - { - case kDNSServiceDiscoveryAlreadyRegistered: - strcpy( txt, "name already registered!" ); - break; - case kDNSServiceDiscoveryNameConflict: - strcpy( txt, "name conflict!" ); - break; - default: - snprintf(txt, sizeof txt, "error code %ld!", - (long)ErrCode); - } - - Log( LOG_INFO, "Can't register \"%s\" with Rendezvous: %s", s->Desc, txt ); - s->Desc[0] = '\0'; -} /* Registration_Reply_Handler */ - - -#endif /* Apple */ - - -/* -- Howl API -- */ - -#ifdef HOWL - - -static sw_result HOWL_API Registration_Reply_Handler( sw_discovery Session, sw_discovery_publish_status Status, UNUSED sw_discovery_oid Id, sw_opaque Extra ) -{ - SERVICE *s = (SERVICE *)Extra; - char txt[50]; - - assert( Session == My_Discovery_Session ); - assert( Extra != NULL ); - - if( Status == SW_DISCOVERY_PUBLISH_STARTED || Status == SW_DISCOVERY_PUBLISH_STOPPED ) - { - /* Success! */ - Log( LOG_INFO, "Successfully registered \"%s\" with Rendezvous.", s->Desc ); - return SW_OKAY; - } - - switch( Status ) - { - case SW_DISCOVERY_PUBLISH_NAME_COLLISION: - strcpy( txt, "name conflict!" ); - break; - default: - snprintf(txt, sizeof txt, "error code %ld!", - (long)Status); - } - - Log( LOG_INFO, "Can't register \"%s\" with Rendezvous: %s", s->Desc, txt ); - s->Desc[0] = '\0'; - - return SW_OKAY; -} /* Registration_Reply_Handler */ - - -#endif /* Howl */ - - -#endif /* ZEROCONF */ - - -/* -eof- */ diff --git a/src/ngircd/rendezvous.h b/src/ngircd/rendezvous.h deleted file mode 100644 index 3e65f8e..0000000 --- a/src/ngircd/rendezvous.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * ngIRCd -- The Next Generation IRC Daemon - * Copyright (c)2001-2003 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 - * 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. - * - * $Id: rendezvous.h,v 1.4 2006/05/10 21:24:01 alex Exp $ - * - * "Rendezvous" functions (Header) - */ - - -#ifdef ZEROCONF - -#ifndef __rdezvous_h__ -#define __rdezvous_h__ - - -GLOBAL void Rendezvous_Init( void ); -GLOBAL void Rendezvous_Exit( void ); - -GLOBAL bool Rendezvous_Register( char *Name, char *Type, UINT16 Port ); - -GLOBAL bool Rendezvous_Unregister( char *Name ); -GLOBAL void Rendezvous_UnregisterListeners( void ); - -GLOBAL void Rendezvous_Handler( void ); - - -#endif /* __rdezvous_h__ */ - -#endif /* ZEROCONF */ - - -/* -eof- */ diff --git a/src/ngircd/resolve.c b/src/ngircd/resolve.c index 5839c19..9b17af9 100644 --- a/src/ngircd/resolve.c +++ b/src/ngircd/resolve.c @@ -7,15 +7,17 @@ * 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. - * - * Asynchronous resolver */ - #define RESOLVER_TIMEOUT (Conf_PongTimeout*3)/4 #include "portab.h" +/** + * @file + * Asynchronous resolver + */ + #include "imp.h" #include #include @@ -234,7 +236,7 @@ ReverseLookup(const ng_ipaddr_t *IpAddr, char *resbuf, size_t reslen) * @return true if lookup successful, false if domain name not found */ static bool -ForwardLookup(const char *hostname, array *IpAddr) +ForwardLookup(const char *hostname, array *IpAddr, int af) { ng_ipaddr_t addr; @@ -243,23 +245,13 @@ ForwardLookup(const char *hostname, array *IpAddr) struct addrinfo *a, *ai_results; static struct addrinfo hints; -#ifndef WANT_IPV6 - hints.ai_family = AF_INET; -#endif #ifdef AI_ADDRCONFIG /* glibc has this, but not e.g. netbsd 4.0 */ hints.ai_flags = AI_ADDRCONFIG; #endif hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; + hints.ai_family = af; -#ifdef WANT_IPV6 - assert(Conf_ConnectIPv6 || Conf_ConnectIPv4); - - if (!Conf_ConnectIPv6) - hints.ai_family = AF_INET; - if (!Conf_ConnectIPv4) - hints.ai_family = AF_INET6; -#endif memset(&addr, 0, sizeof(addr)); res = getaddrinfo(hostname, NULL, &hints, &ai_results); @@ -388,7 +380,7 @@ Do_ResolveAddr(const ng_ipaddr_t *Addr, int identsock, int w_fd) if (!ReverseLookup(Addr, hostname, sizeof(hostname))) goto dns_done; - if (ForwardLookup(hostname, &resolved_addr)) { + if (ForwardLookup(hostname, &resolved_addr, ng_ipaddr_af(Addr))) { if (!Addr_in_list(&resolved_addr, Addr)) { Log_Forgery_WrongIP(tmp_ip_str, hostname); strlcpy(hostname, tmp_ip_str, sizeof(hostname)); @@ -425,6 +417,7 @@ Do_ResolveName( const char *Host, int w_fd ) /* Resolver sub-process: resolve name and write result into pipe * to parent. */ array IpAddrs; + int af; #ifdef DEBUG ng_ipaddr_t *addr; size_t len; @@ -432,8 +425,19 @@ Do_ResolveName( const char *Host, int w_fd ) Log_Subprocess(LOG_DEBUG, "Now resolving \"%s\" ...", Host); array_init(&IpAddrs); - /* Resolve hostname */ - if (!ForwardLookup(Host, &IpAddrs)) { + +#ifdef WANT_IPV6 + af = AF_UNSPEC; + assert(Conf_ConnectIPv6 || Conf_ConnectIPv4); + + if (!Conf_ConnectIPv6) + af = AF_INET; + if (!Conf_ConnectIPv4) + af = AF_INET6; +#else + af = AF_INET; +#endif + if (!ForwardLookup(Host, &IpAddrs, af)) { close(w_fd); return; } diff --git a/src/ngircd/resolve.h b/src/ngircd/resolve.h index 044ceec..c0b734b 100644 --- a/src/ngircd/resolve.h +++ b/src/ngircd/resolve.h @@ -7,13 +7,16 @@ * 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. - * - * Asynchronous resolver (header) */ #ifndef __resolve_h__ #define __resolve_h__ +/** + * @file + * Asynchronous resolver (header) + */ + GLOBAL bool Resolve_Addr PARAMS((PROC_STAT * s, const ng_ipaddr_t * Addr, int identsock, void (*cbfunc) (int, short))); GLOBAL bool Resolve_Name PARAMS((PROC_STAT * s, const char *Host, diff --git a/src/ngircd/sighandlers.h b/src/ngircd/sighandlers.h index 98f91e8..68491d9 100644 --- a/src/ngircd/sighandlers.h +++ b/src/ngircd/sighandlers.h @@ -11,9 +11,16 @@ #ifndef signals_included_ #define signals_included_ +/** + * @file + * Signal Handlers (header). + */ + #include "portab.h" bool Signals_Init PARAMS((void)); void Signals_Exit PARAMS((void)); #endif + +/* -eof- */ diff --git a/src/portab/exp.h b/src/portab/exp.h index 0cb2d20..d678b99 100644 --- a/src/portab/exp.h +++ b/src/portab/exp.h @@ -8,15 +8,14 @@ * der Lizenz oder (wenn Sie es wuenschen) jeder spaeteren Version. * Naehere Informationen entnehmen Sie bitter der Datei COPYING. Eine Liste * der an ngIRCd beteiligten Autoren finden Sie in der Datei AUTHORS. - * - * $Id: exp.h,v 1.1 2002/03/12 14:36:44 alex Exp $ - * - * exp.h: "Export Header" */ +/** + * @file + * "Export Header" which makes sure, that global functions are not "extern". + */ #undef GLOBAL #define GLOBAL - /* -eof- */ diff --git a/src/portab/imp.h b/src/portab/imp.h index cc51d89..68b5aee 100644 --- a/src/portab/imp.h +++ b/src/portab/imp.h @@ -8,15 +8,14 @@ * der Lizenz oder (wenn Sie es wuenschen) jeder spaeteren Version. * Naehere Informationen entnehmen Sie bitter der Datei COPYING. Eine Liste * der an ngIRCd beteiligten Autoren finden Sie in der Datei AUTHORS. - * - * $Id: imp.h,v 1.1 2002/03/12 14:36:44 alex Exp $ - * - * imp.h: "Import Header" */ +/** + * @file + * "Import Header" which makes sure that global functions are defined "extern". + */ #undef GLOBAL #define GLOBAL extern - /* -eof- */ diff --git a/src/portab/portab.h b/src/portab/portab.h index d2f769f..a75aa34 100644 --- a/src/portab/portab.h +++ b/src/portab/portab.h @@ -7,14 +7,15 @@ * 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. - * - * Portability functions and declarations (header for libngbportab). */ - #ifndef __PORTAB__ #define __PORTAB__ +/** + * @file + * Portability functions and declarations (header) + */ #include "config.h" diff --git a/src/portab/portabtest.c b/src/portab/portabtest.c index 0a2098e..09afbfd 100644 --- a/src/portab/portabtest.c +++ b/src/portab/portabtest.c @@ -7,14 +7,14 @@ * 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. - * - * test program for portab.h and friends ;-) */ - #include "portab.h" -static char UNUSED id[] = "$Id: portabtest.c,v 1.13 2005/07/31 20:13:11 alex Exp $"; +/** + * @file + * Test program for portab.h and friends ;-) + */ #include "imp.h" #include diff --git a/src/portab/splint.h b/src/portab/splint.h index 2f606a0..be33e47 100644 --- a/src/portab/splint.h +++ b/src/portab/splint.h @@ -8,19 +8,19 @@ * der Lizenz oder (wenn Sie es wuenschen) jeder spaeteren Version. * Naehere Informationen entnehmen Sie bitter der Datei COPYING. Eine Liste * der an ngIRCd beteiligten Autoren finden Sie in der Datei AUTHORS. - * - * $Id: splint.h,v 1.1 2002/03/25 19:13:19 alex Exp $ - * - * splint.h: spezieller Header fuer SPLint Code-Check - * - * Dieser Header wird von portab.h nur dann includiert, wenn ein Code-Check - * mit SPLint laeufr (d.h. S_SPLINT_S definiert ist). */ - #ifndef __splint__ #define __splint__ +/** + * @file + * Header file which is included for SPLint code checks + * + * This header is only included by portab.h if a SPLint code check is + * running (when S_SPLINT_S is defined). It makes some definitions to + * prevent SPLint from issuing false warnings. + */ #define SYSCONFDIR "/" #define LOCALSTATEDIR "/" @@ -36,8 +36,6 @@ #define WNOHANG 0 - #endif - /* -eof- */ diff --git a/src/portab/strdup.c b/src/portab/strdup.c index e735157..7c0ee8f 100644 --- a/src/portab/strdup.c +++ b/src/portab/strdup.c @@ -1,13 +1,16 @@ /* * ngIRCd -- The Next Generation IRC Daemon - * - * strdup() implementation. Public domain. - * - * $Id: strdup.c,v 1.1 2005/04/16 09:20:53 fw Exp $ */ #include "portab.h" +/** + * @file + * strdup() implementation. Public domain. + */ + +#ifndef HAVE_STRDUP + #include "imp.h" #include #include @@ -15,8 +18,6 @@ #include "exp.h" -#ifndef HAVE_STRDUP - GLOBAL char * strdup( const char *s ) { diff --git a/src/portab/strlcpy.c b/src/portab/strlcpy.c index ee93d1d..ae2018b 100644 --- a/src/portab/strlcpy.c +++ b/src/portab/strlcpy.c @@ -7,8 +7,14 @@ * 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. - * + */ + +#include "portab.h" + +/** + * @file * strlcpy() and strlcat() replacement functions. + * * See for details. * * Code partially borrowed from compat.c of rsync, written by Andrew @@ -16,11 +22,6 @@ * */ - -#include "portab.h" - -static char UNUSED id[] = "$Id: strlcpy.c,v 1.5 2005/03/19 18:43:50 fw Exp $"; - #include "imp.h" #include #include diff --git a/src/portab/strtok_r.c b/src/portab/strtok_r.c index 852c8f7..4d00772 100644 --- a/src/portab/strtok_r.c +++ b/src/portab/strtok_r.c @@ -1,8 +1,18 @@ +/* + * ngIRCd -- The Next Generation IRC Daemon + */ + #include "portab.h" -#include + +/** + * @file + * Implementation of strtok_r() + */ #ifndef HAVE_STRTOK_R +#include + char * strtok_r(char *str, const char *delim, char **saveptr) { @@ -24,4 +34,3 @@ strtok_r(char *str, const char *delim, char **saveptr) } #endif - diff --git a/src/portab/vsnprintf.c b/src/portab/vsnprintf.c index 3f9707b..c97a53e 100644 --- a/src/portab/vsnprintf.c +++ b/src/portab/vsnprintf.c @@ -7,19 +7,14 @@ * 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. - * - * snprintf() and vsnprintf() replacement functions */ - #include "portab.h" -static char UNUSED id[] = "$Id: vsnprintf.c,v 1.5 2003/04/21 10:53:38 alex Exp $"; - -#include "imp.h" - -#include "exp.h" - +/** + * @file + * snprintf() and vsnprintf() replacement functions + */ /* * snprintf.c: Copyright Patrick Powell 1995 diff --git a/src/portab/waitpid.c b/src/portab/waitpid.c index 0c16960..5846bd8 100644 --- a/src/portab/waitpid.c +++ b/src/portab/waitpid.c @@ -1,12 +1,16 @@ /* * ngIRCd -- The Next Generation IRC Daemon - * + */ + +#include "portab.h" + +/** + * @file * waitpid() implementation. Public domain. * Written by Steven D. Blackford for the NeXT system. - * */ -#include "portab.h" +#ifndef HAVE_WAITPID #include "imp.h" #include @@ -15,8 +19,6 @@ #include "exp.h" -#ifndef HAVE_WAITPID - GLOBAL int waitpid(pid, stat_loc, options) int pid, *stat_loc, options; diff --git a/src/testsuite/.gitignore b/src/testsuite/.gitignore index fd628e3..5884a48 100644 --- a/src/testsuite/.gitignore +++ b/src/testsuite/.gitignore @@ -11,6 +11,7 @@ mode-test opless-channel-test server-link-test who-test +whois-test ngircd-test1.log ngircd-test2.log ngircd-test1.motd diff --git a/src/testsuite/Makefile.am b/src/testsuite/Makefile.am index f72453f..9dc76a7 100644 --- a/src/testsuite/Makefile.am +++ b/src/testsuite/Makefile.am @@ -1,6 +1,6 @@ # # ngIRCd -- The Next Generation IRC Daemon -# Copyright (c)2001-2008 Alexander Barton (alex@barton.de) +# Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors. # # Dieses Programm ist freie Software. Sie koennen es unter den Bedingungen # der GNU General Public License (GPL), wie von der Free Software Foundation @@ -20,7 +20,7 @@ EXTRA_DIST = \ test-loop.sh wait-tests.sh \ channel-test.e connect-test.e check-idle.e invite-test.e \ join-test.e kick-test.e message-test.e misc-test.e mode-test.e \ - opless-channel-test.e server-link-test.e who-test.e \ + opless-channel-test.e server-link-test.e who-test.e whois-test.e \ stress-A.e stress-B.e \ start-server1 stop-server1 ngircd-test1.conf \ start-server2 stop-server2 ngircd-test2.conf @@ -85,6 +85,10 @@ who-test: tests.sh rm -f who-test ln -s $(srcdir)/tests.sh who-test +whois-test: tests.sh + rm -f whois-test + ln -s $(srcdir)/tests.sh whois-test + TESTS = start-server1 \ connect-test \ start-server2 \ @@ -97,6 +101,7 @@ TESTS = start-server1 \ mode-test \ opless-channel-test \ who-test \ + whois-test \ server-link-test \ stop-server2 \ stress-server.sh \ diff --git a/src/testsuite/ngircd-test1.conf b/src/testsuite/ngircd-test1.conf index 25ec842..f65f706 100644 --- a/src/testsuite/ngircd-test1.conf +++ b/src/testsuite/ngircd-test1.conf @@ -1,5 +1,5 @@ # ngIRCd test suite -# configuration file for test server #2 +# configuration file for test server #1 [Global] Name = ngircd.test.server @@ -7,11 +7,15 @@ Ports = 6789 MotdFile = ngircd-test1.motd AdminEMail = admin@irc.server + +[Limits] MaxConnectionsIP = 0 - OperCanUseMode = yes MaxJoins = 4 - NoIdent = yes - NoPAM = yes + +[Options] + OperCanUseMode = yes + Ident = no + PAM = no [Operator] Name = TestOp @@ -23,7 +27,6 @@ PeerPassword = pwd2 [Channel] -# This name should be accepted as '#InviteChannel' by ngircd. Name = InviteChannel Modes = i @@ -50,4 +53,5 @@ [Channel] Name = +ModelessChannel Topic = A modeless Channel + # -eof- diff --git a/src/testsuite/ngircd-test2.conf b/src/testsuite/ngircd-test2.conf index 0805b4e..5d2e28f 100644 --- a/src/testsuite/ngircd-test2.conf +++ b/src/testsuite/ngircd-test2.conf @@ -7,11 +7,15 @@ Ports = 6790 MotdFile = ngircd-test2.motd AdminEMail = admin@irc.server2 + +[Limits] MaxConnectionsIP = 0 - OperCanUseMode = yes MaxJoins = 4 - NoIdent = yes - NoPAM = yes + +[Options] + OperCanUseMode = yes + Ident = no + PAM = no [Operator] Name = TestOp diff --git a/src/testsuite/whois-test.e b/src/testsuite/whois-test.e new file mode 100644 index 0000000..7024d5f --- /dev/null +++ b/src/testsuite/whois-test.e @@ -0,0 +1,53 @@ +# ngIRCd test suite +# WHOIS test + +spawn telnet localhost 6789 +expect { + timeout { exit 1 } + "Connected" +} + +send "nick nick\r" +send "user user . . :Real Name\r" +expect { + timeout { exit 1 } + "376" +} + +send "whois nick\r" +expect { + timeout { exit 1 } + "311 nick nick ~user localhost \* :Real Name\r" +} + +send "whois *\r" +expect { + timeout { exit 1 } + "311 nick nick ~user localhost \* :Real Name\r" +} + +send "whois n*\r" +expect { + timeout { exit 1 } + "311 nick nick ~user localhost \* :Real Name\r" +} + +send "whois ?ick\r" +expect { + timeout { exit 1 } + "311 nick nick ~user localhost \* :Real Name\r" +} + +send "whois ????,n?*k\r" +expect { + timeout { exit 1 } + "311 nick nick ~user localhost \* :Real Name\r" +} + +send "quit\r" +expect { + timeout { exit 1 } + "ERROR" +} + +# -eof- diff --git a/src/tool/tool.c b/src/tool/tool.c index dbdb49a..ef3fb5d 100644 --- a/src/tool/tool.c +++ b/src/tool/tool.c @@ -7,13 +7,15 @@ * 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. - * - * Tool functions */ - #include "portab.h" +/** + * @file + * Tool functions + */ + #include "imp.h" #include #include diff --git a/src/tool/tool.h b/src/tool/tool.h index 4513a23..60a6537 100644 --- a/src/tool/tool.h +++ b/src/tool/tool.h @@ -7,13 +7,16 @@ * 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. - * - * Tool functions (Header) */ - #ifndef __tool_h__ #define __tool_h__ + +/** + * @file + * Tool functions (Header) + */ + #include "portab.h" #ifdef HAVE_ARPA_INET_H @@ -36,5 +39,4 @@ GLOBAL int ngt_SyslogFacilityID PARAMS((char *Name, int DefaultFacility)); #endif - /* -eof- */