mirror of
https://github.com/osmarks/ngircd.git
synced 2025-09-20 03:04:03 +00:00
Compare commits
255 Commits
rel-19.1
...
branch-20.
Author | SHA1 | Date | |
---|---|---|---|
![]() |
bb6e277963 | ||
![]() |
d24df64397 | ||
![]() |
c45d9dd1f0 | ||
![]() |
b3d4cf9081 | ||
![]() |
1265eb15b8 | ||
![]() |
84612fe773 | ||
![]() |
84f5839c17 | ||
![]() |
cb3b411166 | ||
![]() |
121bcacb98 | ||
![]() |
4105635566 | ||
![]() |
90fce2ed16 | ||
![]() |
21493731df | ||
![]() |
1f59821270 | ||
![]() |
3e47bc9af5 | ||
![]() |
5d92198487 | ||
![]() |
20ddffca0d | ||
![]() |
25e56a5e83 | ||
![]() |
1e5a7aac87 | ||
![]() |
b5b3dd9cfd | ||
![]() |
92fba63ad8 | ||
![]() |
25d35dd6f4 | ||
![]() |
a445abc10e | ||
![]() |
1342f78b09 | ||
![]() |
a0d57a6afd | ||
![]() |
c6ae353756 | ||
![]() |
12768e7a54 | ||
![]() |
35e2dcff88 | ||
![]() |
dc89e42ef5 | ||
![]() |
4a2d74c9ab | ||
![]() |
cd48b8128e | ||
![]() |
301d4915bc | ||
![]() |
8061056cec | ||
![]() |
44926b7f9f | ||
![]() |
d11a700589 | ||
![]() |
0a26079af2 | ||
![]() |
b6e49f3920 | ||
![]() |
4123118d5a | ||
![]() |
e29d198700 | ||
![]() |
6f531a3c99 | ||
![]() |
53917fa4b8 | ||
![]() |
646218e6f4 | ||
![]() |
4185c4a44a | ||
![]() |
45b0bb5aff | ||
![]() |
c7db2f8429 | ||
![]() |
f0b86e6c26 | ||
![]() |
7871a904d7 | ||
![]() |
40e3daf560 | ||
![]() |
44b7ff02fd | ||
![]() |
35ed57e6c1 | ||
![]() |
79731a57f3 | ||
![]() |
a7f37cebdc | ||
![]() |
47b99c69cc | ||
![]() |
757f3497bc | ||
![]() |
f2455cbe33 | ||
![]() |
e3f300d323 | ||
![]() |
497edbaf3e | ||
![]() |
48326e061a | ||
![]() |
84e9dcbab0 | ||
![]() |
30b32e84fe | ||
![]() |
fb92493376 | ||
![]() |
eb4f9eac0c | ||
![]() |
d7b5dd1bbf | ||
![]() |
b18e81b631 | ||
![]() |
8ff153d7d4 | ||
![]() |
32f63abb59 | ||
![]() |
23572af942 | ||
![]() |
8d9cfa157a | ||
![]() |
58abd0777b | ||
![]() |
3ee98d9f72 | ||
![]() |
b1a5ade88f | ||
![]() |
73229249d8 | ||
![]() |
e0da56fc7b | ||
![]() |
cdaaae0cb2 | ||
![]() |
c319fb8eaa | ||
![]() |
538e612a47 | ||
![]() |
9d97004a28 | ||
![]() |
87deb43012 | ||
![]() |
a9cbb375b7 | ||
![]() |
161adbb1aa | ||
![]() |
de2fa78d92 | ||
![]() |
8bede388af | ||
![]() |
c9d166747d | ||
![]() |
56cdc2175c | ||
![]() |
de453d71cb | ||
![]() |
23b07bdf50 | ||
![]() |
9ac94339dc | ||
![]() |
46b0eef721 | ||
![]() |
d3ae351236 | ||
![]() |
4790d78c98 | ||
![]() |
c66e20ce6e | ||
![]() |
343a90dc37 | ||
![]() |
09ab0704f4 | ||
![]() |
114644cdb0 | ||
![]() |
cf9f9e1f30 | ||
![]() |
19ce256a95 | ||
![]() |
eba53f652c | ||
![]() |
d8ee498a65 | ||
![]() |
e3a1a61868 | ||
![]() |
1a2bdd9e4c | ||
![]() |
384f965fba | ||
![]() |
005340c83f | ||
![]() |
d21afce2b6 | ||
![]() |
808c291c76 | ||
![]() |
62a07596d6 | ||
![]() |
b730b64bbe | ||
![]() |
3e22fc32f3 | ||
![]() |
e65a35e964 | ||
![]() |
78d189fbf7 | ||
![]() |
8cfb910441 | ||
![]() |
039a939cb8 | ||
![]() |
d7d5f4330b | ||
![]() |
79c1222896 | ||
![]() |
a3f3a1097b | ||
![]() |
d4df626d88 | ||
![]() |
eed8a4ee6e | ||
![]() |
b1b83831d1 | ||
![]() |
8e1beae4e7 | ||
![]() |
baed0618ed | ||
![]() |
e3e181f4b3 | ||
![]() |
1f2aa4da6f | ||
![]() |
fc39146f48 | ||
![]() |
192e304b94 | ||
![]() |
1744a8d145 | ||
![]() |
b12acddf4f | ||
![]() |
ef82ef4ddb | ||
![]() |
bb20aeb9bc | ||
![]() |
e9d0b2f039 | ||
![]() |
222ecbffbb | ||
![]() |
ce736fc15b | ||
![]() |
1413a4886f | ||
![]() |
cfec819f0d | ||
![]() |
107bfdc821 | ||
![]() |
5c160921ff | ||
![]() |
fe3bef55b7 | ||
![]() |
5300f0082c | ||
![]() |
85abfd84be | ||
![]() |
005ffeaa8c | ||
![]() |
5c8c6d3c70 | ||
![]() |
7eb3932d3a | ||
![]() |
ebf2f991b5 | ||
![]() |
a451cb22f1 | ||
![]() |
82bf4eb059 | ||
![]() |
d53d58fff2 | ||
![]() |
a072180c92 | ||
![]() |
0fd9a8505a | ||
![]() |
b2482b39e4 | ||
![]() |
74c7d7131f | ||
![]() |
4dd1c31dc7 | ||
![]() |
2e13e821f8 | ||
![]() |
2478c5816b | ||
![]() |
47ad9afcf3 | ||
![]() |
67e882d4bb | ||
![]() |
25c216cbdf | ||
![]() |
f5441d2170 | ||
![]() |
0d67be3f30 | ||
![]() |
f37600ee01 | ||
![]() |
f38a9035e5 | ||
![]() |
a12d6ff257 | ||
![]() |
2205227c3b | ||
![]() |
d2d867ea36 | ||
![]() |
b232ae2f17 | ||
![]() |
53b2acc00b | ||
![]() |
01b62202b2 | ||
![]() |
b68bb560e9 | ||
![]() |
21467c76f1 | ||
![]() |
33fae67579 | ||
![]() |
864015fa3f | ||
![]() |
1d3def0cc6 | ||
![]() |
e01e8f1cb6 | ||
![]() |
186ab51137 | ||
![]() |
74be904018 | ||
![]() |
298cd9a327 | ||
![]() |
414bfe65eb | ||
![]() |
c519ba9920 | ||
![]() |
fee8ff37b3 | ||
![]() |
fee591b759 | ||
![]() |
16f94546f5 | ||
![]() |
55859c1bef | ||
![]() |
bcefdef1ea | ||
![]() |
f79d41e927 | ||
![]() |
1680ea02da | ||
![]() |
1aaf54ac24 | ||
![]() |
a5984c702a | ||
![]() |
9a82304ae9 | ||
![]() |
a26e37b746 | ||
![]() |
c2b39fdede | ||
![]() |
8349a1c0d9 | ||
![]() |
360a254be0 | ||
![]() |
ab1fcebeff | ||
![]() |
a6dd2e33c2 | ||
![]() |
9d8974d509 | ||
![]() |
037b4b76df | ||
![]() |
be97fa8ab1 | ||
![]() |
164954a788 | ||
![]() |
c1d7f6216f | ||
![]() |
7df4c12da9 | ||
![]() |
0d5de60584 | ||
![]() |
4b0f526006 | ||
![]() |
4cf65b973c | ||
![]() |
160f728530 | ||
![]() |
922540306e | ||
![]() |
d48e440a72 | ||
![]() |
0709a0f050 | ||
![]() |
097c72aa65 | ||
![]() |
7b01bb833f | ||
![]() |
cfd0bddc30 | ||
![]() |
b53b12aa5f | ||
![]() |
d0bb185cf5 | ||
![]() |
49385a98b2 | ||
![]() |
b9e6cb3e55 | ||
![]() |
dffe5a9d60 | ||
![]() |
d7eb343ea0 | ||
![]() |
bf5610a3b9 | ||
![]() |
7bce6780ca | ||
![]() |
bf121ae95f | ||
![]() |
7b6b492bdd | ||
![]() |
aa7db2c0e9 | ||
![]() |
684e50f0a4 | ||
![]() |
4a90959cb5 | ||
![]() |
9b1cf420f1 | ||
![]() |
e7e47e77a3 | ||
![]() |
695df6532e | ||
![]() |
6680b536c4 | ||
![]() |
a21a7d8b66 | ||
![]() |
c0d059cd0e | ||
![]() |
7faa3ed7d6 | ||
![]() |
c9b152fa41 | ||
![]() |
ae27571414 | ||
![]() |
5e5377a063 | ||
![]() |
884c5bcff1 | ||
![]() |
3a2fcc32cd | ||
![]() |
a8aa8c6cbc | ||
![]() |
f01b09ce84 | ||
![]() |
2419a701d8 | ||
![]() |
110be707c3 | ||
![]() |
b2743af0ed | ||
![]() |
76565022fb | ||
![]() |
4602cb9891 | ||
![]() |
1d7e99531a | ||
![]() |
f0a9dbe3ad | ||
![]() |
245782897b | ||
![]() |
2327b17656 | ||
![]() |
359732af85 | ||
![]() |
1dea0d91a0 | ||
![]() |
d67d077a71 | ||
![]() |
69be7a85a2 | ||
![]() |
8ec17063a6 | ||
![]() |
da4c1ebe81 | ||
![]() |
bd3a7ccb15 | ||
![]() |
edfcc2f9d5 | ||
![]() |
ee362b3bd2 | ||
![]() |
67bd1bf34f | ||
![]() |
9f3af061cf | ||
![]() |
88c3d4896a | ||
![]() |
7b6ef3bc8e |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -4,11 +4,13 @@ aclocal.m4
|
||||
ansi2knr.1
|
||||
ansi2knr.c
|
||||
ansi2knr.h
|
||||
ar-lib
|
||||
autom4te.cache
|
||||
build-stamp-ngircd*
|
||||
config.log
|
||||
config.status
|
||||
configure
|
||||
configure.ac
|
||||
configure.lineno
|
||||
cscope.out
|
||||
debian
|
||||
|
2
AUTHORS
2
AUTHORS
@@ -2,7 +2,7 @@
|
||||
ngIRCd - Next Generation IRC Server
|
||||
http://ngircd.barton.de/
|
||||
|
||||
(c)2001-2012 Alexander Barton and Contributors.
|
||||
(c)2001-2013 Alexander Barton and Contributors.
|
||||
ngIRCd is free software and published under the
|
||||
terms of the GNU General Public License.
|
||||
|
||||
|
282
ChangeLog
282
ChangeLog
@@ -2,21 +2,261 @@
|
||||
ngIRCd - Next Generation IRC Server
|
||||
http://ngircd.barton.de/
|
||||
|
||||
(c)2001-2012 Alexander Barton and Contributors.
|
||||
(c)2001-2013 Alexander Barton and Contributors.
|
||||
ngIRCd is free software and published under the
|
||||
terms of the GNU General Public License.
|
||||
|
||||
-- ChangeLog --
|
||||
|
||||
|
||||
ngIRCd 20.3 (2013-08-23)
|
||||
|
||||
- Security: Fix a denial of service bug (server crash) which could happen
|
||||
when the configuration option "NoticeAuth" is enabled (which is NOT the
|
||||
default) and ngIRCd failed to send the "notice auth" messages to new
|
||||
clients connecting to the server (CVE-2013-5580).
|
||||
|
||||
ngIRCd 20.2 (2013-02-15)
|
||||
|
||||
- Security: Fix a denial of service bug in the function handling KICK
|
||||
commands that could be used by arbitrary users to to crash the daemon
|
||||
(CVE-2013-1747).
|
||||
- WHO command: Use the currently "displayed hostname" (which can be cloaked!)
|
||||
for hostname matching, not the real one. In other words: don't display all
|
||||
the cloaked users on a specific real hostname!
|
||||
- configure: The header file "netinet/in_systm.h" already is optional in
|
||||
ngIRCd, so don't require it in the configure script. Now ngIRCd can be
|
||||
built on Minix 3 again :-)
|
||||
- Return better "Connection not registered as server link" errors: Now ngIRCd
|
||||
returns a more specific error message for numeric ERR_NOTREGISTERED(451)
|
||||
when a regular user tries to use a command that isn't allowed for users but
|
||||
for servers.
|
||||
- Don't report ERR_NEEDMOREPARAMS(461) when a MDOE command with more modes
|
||||
than nicknames is handled, as well as for channel limit and key changes
|
||||
without specifying the limit or key parameters.
|
||||
This is how a lot (all?) other IRC servers behave, including ircd2.11,
|
||||
InspIRCd, and ircd-seven. And because of clients (tested with Textual and
|
||||
mIRC) sending bogus MODE commands like "MODE -ooo nick", end-users got the
|
||||
expected result as well as correct but misleading error messages ...
|
||||
- Correctly detect when SSL subsystem must be initialized and take
|
||||
outgoing connections (server links!) into account, too.
|
||||
- autogen.sh: Enforce serial test harness on GNU automake >=1.13. The
|
||||
new parallel test harness which is enabled by default starting with
|
||||
automake 1.13 isn't compatible with our test suite.
|
||||
And don't use "egrep -o", insetead use "sed", because it isn't portable
|
||||
and not available on OpenBSD, for example.
|
||||
|
||||
ngIRCd 20.1 (2013-01-02)
|
||||
|
||||
- Allow ERROR command on server and service links only, ignore them and
|
||||
add a penalty time on all other link types.
|
||||
- Enforced mode setting by IRC Operators: Only check the channel user
|
||||
modes of the initiator if he is joined to the channel and not an IRC
|
||||
operator enforcing modes (which requires the configuration option
|
||||
"OperCanUseMode" to be enabled), because trying to check channel user
|
||||
modes of a non-member results in an assertion when running with debug
|
||||
code or could crash the daemon otherwise. This closes bug #147, thanks
|
||||
to James Kirwill <james.kirwill@bk.ru> for tracking this down!
|
||||
- Fix build system to cope with spaces in path names.
|
||||
- Code cleanups, mostly to fix build warnings on Cygwin.
|
||||
|
||||
ngIRCd 20 (2012-12-17)
|
||||
|
||||
- Allow user names ("INDENT") up to 20 characters when ngIRCd has not
|
||||
been configured for "strict RFC mode". This is useful if you are using
|
||||
external (PAM) authenticaion mechanisms that require longer user names.
|
||||
Patch suggested by Brett Smith <brett@w3.org>, see
|
||||
<http://arthur.barton.de/pipermail/ngircd-ml/2012-October/000579.html>.
|
||||
|
||||
ngIRCd 20~rc2 (2012-12-02)
|
||||
- Rework cloaked hostname handling and implement the "METADATA cloakhost"
|
||||
subcommand: Now ngIRCd uses two fields internally, one to store the
|
||||
"real" hostname and one to save the "cloaked" hostname. This allows
|
||||
"foreign servers" (aka "IRC services") to alter the real and cloaked
|
||||
hostnames of clients without problems, even when the user itself issues
|
||||
additional "MODE +x" and "MODE -x" commands.
|
||||
- RPL_UMODEIS: send correct target name, even on server links.
|
||||
- Update platformtest.sh to follow autoconf changes and only generate
|
||||
the "configure" script when it is missing.
|
||||
- Fix the test suite to correctly execute test scripts even when stdout
|
||||
is redirected.
|
||||
- Fix some compiler warnings on NetBSD and OpenBSD.
|
||||
|
||||
ngIRCd 20~rc1 (2012-11-11)
|
||||
- Update doc/Services.txt: describe the upcoming version of Anope 1.9.8,
|
||||
then including a protocol module for ngIRCd. And remove our own patches
|
||||
in ./contrib/Anope because they aren't supported any more ...
|
||||
- Implement new "METADATA" command which can be used by remote servers
|
||||
and IRC services to update client metadata like the client info text
|
||||
("real name"), user name, and hostname, and use this command to
|
||||
configure an cloaked hostname (user mode "+x") on remote servers:
|
||||
This prevents "double cloaking" of hostnames and even cloaked
|
||||
hostnames are in sync on all servers supporting "METADATA" now.
|
||||
- Fix error message when trying to join non-predefined channels and the
|
||||
"PredefChannelsOnly" configuration option is set.
|
||||
- Implement new IRC "SVSNICK" command to allow remote servers (and IRC
|
||||
services) to change nicknames of already registered users. The SVSNICK
|
||||
command itself doesn't change the nickname, but it becomes forwarded
|
||||
to the server to which the user is connected to. And then this server
|
||||
initiates the real nickname changing using regular NICK commands.
|
||||
This allows to run mixed networks with old servers not supporting the
|
||||
SVSNICK command, because SVSNICK commands for nicknames on such servers
|
||||
are silently ignored and don't cause a desynchronization of the network.
|
||||
- Make server reconnect time a little bit more random, so that two
|
||||
servers trying to connect to each other asynchronously don't try this
|
||||
in exactly the same time periods and kick each other off ...
|
||||
- Don't accept connections for servers already being linked: there was a
|
||||
time frame that could result in one connection overwriting the other,
|
||||
e. g. the incoming connection overwriting the status of the outgoing
|
||||
one. And this could lead to all kind of weirdness (even crashes!) later
|
||||
on: now such incoming connections are dropped.
|
||||
- New configuration option "MaxListSize" to configure the maximum number
|
||||
of channels returned by a LIST command. The default is 100, as before.
|
||||
- Implement user mode "b", "block messages": when a user has set mode "b",
|
||||
all private messages and notices to this user are blocked if they don't
|
||||
originate from a registered user, an IRC Op, server or service. The
|
||||
originator gets an error numeric sent back in this case,
|
||||
ERR_NONONREG_MSG (486), which is used by UnrealIRCd, too. (Closes #144)
|
||||
- WHOIS: Not only show RPL_WHOISHOST_MSG to local IRC operators, but show
|
||||
it to all IRC operators in the network. And don't show it to anybody if
|
||||
the "more privacy" configuration option is enabled. (Closes #134)
|
||||
- Test suite: make expect scripts more verbose displaying dots for each
|
||||
reply of the server that it is waiting for.
|
||||
- WHOIS: Implement numeric RPL_WHOISMODES_MSG (379) and show user modes in
|
||||
the reply of the WHOIS command for the user himself or, if MorePrivacy
|
||||
isn't set, for request initiated by an IRC operator. (Closes #129)
|
||||
- Implement channel mode "V" (invite disallow): If the new channel mode
|
||||
"V" is set, the INVITE command becomes invalid and all clients get the
|
||||
new ERR_NOINVITE_MSG (518) reply. (Closes #143)
|
||||
- KICK-protect IRC services.
|
||||
- Implement channel mode "Q" and user mode "q": Both modes protect users
|
||||
from channel kicks: only IRC operators and servers can kick users having
|
||||
mode "q" or in channels with mode "Q". (Closes #141)
|
||||
- Debian: require "telnet" or "telnet-ssl" for building and enable
|
||||
CHARCONV in ngircd-full[-dbg] variants.
|
||||
- Send RPL_REHASHING (382) numeric if a REHASH command was accepted.
|
||||
- Fix spelling and variable names in some log messages.
|
||||
- Allow users to "cloak" their hostname only when the configuration
|
||||
variable "CloakHostModeX" (introduced in 19.2) is set. Otherwise, only
|
||||
IRC operators, other servers, and services are allowed to set the user
|
||||
mode "+x": this prevents regular users from changing their hostmask to
|
||||
the name of the IRC server itself, which confused quite a few people ;-)
|
||||
(Closes #133)
|
||||
- New configuration option "OperChanPAutoOp": If disabled, IRC operators
|
||||
don't become channel operators in persistent channels when joining.
|
||||
Enabled by default, which has been the behavior of ngIRCd up to this
|
||||
patch. (Closes #135)
|
||||
- Allow IRC operators to see secret (+s) channels in LIST command as long
|
||||
as the "MorePrivacy" configuration option isn't enabled in the
|
||||
configuration file. (Closes #136)
|
||||
- Enhance build system: Support new (>=1.12) and old (<=1.11) GNU automake
|
||||
versions, update checks for required and optional features, enable
|
||||
colored test output of automake (if available), rename configure.in to
|
||||
more modern configure.ac, include .mailmap and all build-system files in
|
||||
distribution archives and no longer require a GIT tree to detect the
|
||||
correct version string.
|
||||
- Update documentation: add doc/Contributing.txt and include version
|
||||
numbers in doc/Modes.txt.
|
||||
- Free all listen ports on initialization: now listen ports can be
|
||||
reconfigured on runtime using a configuration reload.
|
||||
- Initialize SSL when needed only, and disable SSL on errors.
|
||||
- Implement new (optional) IRC+ "CHARCONV" command to set a client
|
||||
character set that the server translates all messages to/from UTF-8.
|
||||
This feature requires the "libiconv" library and must be enabled using
|
||||
the new "--with-iconv" option of the ./configure script. See
|
||||
doc/Protocol.txt for details. (Closes #109)
|
||||
- Allow limited punctuation in usernames, for better PAM integration.
|
||||
- Correctly re-initialize signal handlers on RESTART commands.
|
||||
- Show a warning on startup if the configuration file is not a full path:
|
||||
ngIRCd is a long-running process and changes its working directory to
|
||||
"/" to not block mounted filesystems and the like when running as daemon
|
||||
("not in the foreground"); therefore the path to the configuration file
|
||||
must be relative to "/" (or the chroot() directory), which basically is
|
||||
"not relative", to ensure that "kill -HUP" and the "REHASH" command work
|
||||
as expected later on. (Closes #127)
|
||||
- Make the "&SERVER" channel definable in a [Channel] configuration block,
|
||||
which enables server operators to overwrite the built-in topic and
|
||||
channel modes. (Closes #131)
|
||||
- Don't limit list size of "WHO #channel" commands, because it makes no
|
||||
sense to not return all the users in that channel, so I removed the
|
||||
check. But if there are more than MAX_RPL_WHO(25) replies, the client
|
||||
requesting the list will be "penalized" one second more, then 2 in
|
||||
total. (Closes #125)
|
||||
- Make ngIRCd buildable using the kqueue() IO interface on FreeBSD 4.x.
|
||||
- Fix the "NoticeAuth" configuration option when using SSL connections and
|
||||
enhance the message to show the hostname and IDENT reply of the client.
|
||||
- Introduce numeric RPL_HOSTHIDDEN_MSG (396): This numeric is sent to the
|
||||
client each time it changes its displayed hostname using "MODE +/-x",
|
||||
and if "CloakHost" is set right after the MOTD has been sent.
|
||||
- Fix USERHOST not displaying the correctly cloaked hostname.
|
||||
- Implement user mode "B" ("Bot flag"): it is settable and unsettable by
|
||||
every (non-restricted) client. This is how Unreal and InspIRCd do
|
||||
behave, and so do we :-)
|
||||
- Dynamically allocate memory for connection passwords: This a) saves
|
||||
memory for clients not using passwords at all and b) allows for
|
||||
"arbitrarily" long passwords.
|
||||
- Implement channel mode "M": Only the server, identified users and IRC
|
||||
operators are able to talk in such a channel.
|
||||
- Block nicknames that are reserved for services and are defined using the
|
||||
configuration variable "ServiceMask" in "Server" blocks; And this
|
||||
variable now can handle more than one mask separated by commas.
|
||||
- Now "make uninstall" removes the installed "ngircd.conf" file, if it is
|
||||
still equal to our "sample-ngircd.conf" file and therefore hasn't been
|
||||
modified by the user. If it has been modified, it isn't removed and a
|
||||
notice is displayed to the user. And "make install" now displays a
|
||||
message when no ngircd.conf file exists and the "sample-ngircd.conf"
|
||||
file will be installed as a starting point.
|
||||
- Add contrib/ngircd.service, a systemd service file for ngircd.
|
||||
- Implemented XOP channel user modes: "Half Op" ("+h", prefix "%") can set
|
||||
the channel modes +imntvIbek and kick all +v and normal users; "Admin"
|
||||
("+a", prefix "&") can set channel modes +imntvIbekoRsz and kick all +o,
|
||||
+h, +v and normal users; and "Owner" ("+q", prefix "~") can set channel
|
||||
modes +imntvIbekoRsz and kick all +a, +o, +h, +v and normal users.
|
||||
- Implement hashed cloaked hostnames for both the "CloakHost" and
|
||||
"CloakHostModeX" configuration options: now the admin can use the new
|
||||
'%x' placeholder to insert a hashed version of the clients hostname,
|
||||
and the new configuration option "CloakHostSalt" defines the salt for
|
||||
the hash function. When "CloakHostSalt" is not set (the default), a
|
||||
random salt will be generated after each server restart. (Closes #133)
|
||||
|
||||
ngIRCd Release 19.2 (2012-06-19)
|
||||
|
||||
- doc/Capabilities.txt: document "multi-prefix" capability
|
||||
|
||||
ngIRCd 19.2~rc1 (2012-06-13)
|
||||
- New configuration option "CloakHostModeX" to configure the hostname
|
||||
that gets used for IRC clients which have user mode "+x" enabled.
|
||||
Up to now, the name of the IRC server itself has been used for this,
|
||||
which still is the default when "CloakHostModeX" isn't set.
|
||||
- Correctly handle asynchronously re-established server links: a race
|
||||
condition could let the daemon loose track of an already re-established
|
||||
incoming server link while preparing its own outgoing connection.
|
||||
Peers that both try to connect each other could have been affected.
|
||||
- Log a debug message when SIGUSR2 is handled in debug mode.
|
||||
- Only allow alphanumeric characters in user-supplied user names of
|
||||
USER command and IDENT replies.
|
||||
- Change wording of "TLS initialized" message to make it more consistent.
|
||||
- Don't leak file descriptors on error path when creating "PID files".
|
||||
- Add missing mode "r" to CHANMODES in 005 "ISUPPORT" numeric.
|
||||
- Update doc/Modes.txt and doc/Platforms.txt documents.
|
||||
- contrib/platformtest.sh: correctly detect Open64 C compiler and handle
|
||||
"CC=xxx MAKE=yyy ./platformtest.sh" calling convention.
|
||||
- Add instructions for setting up Atheme IRC services.
|
||||
- Implement support for IRC capability handling, the new "CAP" command,
|
||||
and capablity "multi-prefix" which allows both the NAME and WHO command
|
||||
handlers to return more than one "class prefix" to the client.
|
||||
- Update Xcode project files: reference missing documentation files.
|
||||
- Fix: Don't ignore "permission denied" errors when enabling chroot.
|
||||
- FAQ: enhance description of chroot setup.
|
||||
|
||||
ngIRCd Release 19.1 (2012-03-19)
|
||||
|
||||
- Fix gcc warning (v4.6.3), initialize "list" variable to NULL.
|
||||
- Fix typos: "recieved" -> "received", "Please not" -> "Please note",
|
||||
and fix lintian(1) warning ""hyphen-used-as-minus-sign", too.
|
||||
- Really include _all_ patchtes to build the Anope module into the
|
||||
- Really include _all_ patches to build the Anope module into the
|
||||
distribution archive ... ooops!
|
||||
- getpid.sh: Fix testcase error for Debian using sbuild(1).
|
||||
- getpid.sh: Fix test case error for Debian using sbuild(1).
|
||||
- Don't log "ngIRCd hello message" two times when starting up.
|
||||
|
||||
ngIRCd Release 19 (2012-02-29)
|
||||
@@ -28,7 +268,7 @@ ngIRCd Release 19 (2012-02-29)
|
||||
- Fix building ngIRCd with old gcc versions (e. g. 2.7.2).
|
||||
- Correctly re-open syslog logging after reading of configuration
|
||||
file: Syslog logging has been initialized before reading the
|
||||
configuraton, so ngIRCd always used the default facility and ignored
|
||||
configuration, so ngIRCd always used the default facility and ignored
|
||||
the "SyslogFacility" configuration option ...
|
||||
Thanks to Patrik Schindler for reporting this issue!
|
||||
|
||||
@@ -39,7 +279,7 @@ ngIRCd Release 19 (2012-02-29)
|
||||
- Log more information about server synchronization.
|
||||
- Update preliminary ngIRCd protocol module for Anope 1.9.6, which now
|
||||
is the only supported version.
|
||||
- New numeric RPL_WHOISHOST_MSG(378), which returns the DNS hostname
|
||||
- New numeric RPL_WHOISHOST_MSG(378), which returns the DNS host name
|
||||
(if available) and the IP address of a client in the WHOIS reply.
|
||||
Only the user itself and local IRC operators get this numeric.
|
||||
- Implement channel exception list (mode 'e'). This allows a channel
|
||||
@@ -52,7 +292,7 @@ ngIRCd Release 19 (2012-02-29)
|
||||
and receiver are on the same channel. This prevents private flooding
|
||||
by completely unknown clients.
|
||||
- New RPL_WHOISREGNICK_MSG(307) numeric in WHOIS command replies: it
|
||||
indicates if a nick name is registered (if user mode 'R' set).
|
||||
indicates if a nickname is registered (if user mode 'R' set).
|
||||
- Limit channel invite, ban, and exception lists to 50 entries and fix
|
||||
duplicate check and error messages when adding already listed entries
|
||||
or deleting no (longer) existing ones.
|
||||
@@ -85,7 +325,7 @@ ngIRCd Release 19 (2012-02-29)
|
||||
commands: this reduces the possibility of flooding channels with
|
||||
commands like "PRIVMSG/NOTICE #a,#n,#c,... :message" a little bit.
|
||||
Problem noticed by Cahata, thanks!
|
||||
- Display correct error message when "Server{UID|GID}" variabe in the
|
||||
- Display correct error message when "Server{UID|GID}" variable in the
|
||||
configuration file is invalid (not a number and no existing user).
|
||||
- Update Copyright notices for 2012 :-)
|
||||
- JOIN command: don't stop handling of channel lists when a single
|
||||
@@ -93,7 +333,7 @@ ngIRCd Release 19 (2012-02-29)
|
||||
limit reached), but report an error and continue. And don't check
|
||||
the channel limit and don't report with "too many channels" when
|
||||
trying to join a channel that the client already is a member of.
|
||||
- ISON command: reply with the correct upper-/lowercase nick names.
|
||||
- ISON command: reply with the correct upper-/lowercase nicknames.
|
||||
- New configuration option "PAMIsOptional": when set, clients not
|
||||
sending a password are still allowed to connect: they won't become
|
||||
"identified" and keep the "~" character prepended to their supplied
|
||||
@@ -127,8 +367,8 @@ ngIRCd Release 19 (2012-02-29)
|
||||
- ./configure: Fix logic and quoting of poll() detection code: only use
|
||||
poll() when poll.h exists as well.
|
||||
- Suppress 'Can't create pre-defined channel: invalid name: ""' message.
|
||||
- whois-test: handle local hostname = "localhost.localdomain" using the
|
||||
pattern "localhost*" for valid local hostnames.
|
||||
- whois-test: handle local host name = "localhost.localdomain" using the
|
||||
pattern "localhost*" for valid local host names.
|
||||
- sample-ngircd.conf: show correct default for "PAM" variable: The
|
||||
default of "PAM" is "yes" when ngIRCd has been configured to use it,
|
||||
so show the correct default value in the sample configuration file.
|
||||
@@ -140,7 +380,7 @@ ngIRCd Release 19 (2012-02-29)
|
||||
The bug has been introduced starting with ngIRCd 17 ... :-(
|
||||
(commit ID 6ebb31ab35e)
|
||||
- Added doc/Modes.txt: document modes supported by ngIRCd.
|
||||
- Implement user mode "R": indicates that the nick name of this user
|
||||
- Implement user mode "R": indicates that the nickname of this user
|
||||
is "registered". This mode isn't handled by ngIRCd itself, but must
|
||||
be set and unset by IRC services like Anope.
|
||||
- Implement channel mode "R": only registered users (having the user
|
||||
@@ -158,7 +398,7 @@ ngIRCd Release 19 (2012-02-29)
|
||||
- Handle channel user modes 'a', 'h', and 'q' from remote servers.
|
||||
These channel user modes aren't used for anything at the moment,
|
||||
but ngIRCd knows that these three modes are "channel user modes"
|
||||
and not "channel modes", that is that these modes take an "nick name"
|
||||
and not "channel modes", that is that these modes take an "nickname"
|
||||
argument. Like unknown user and channel modes, these modes are saved
|
||||
and forwarded to other servers, but ignored otherwise.
|
||||
- Correctly inform clients when other servers change their user modes.
|
||||
@@ -242,10 +482,10 @@ ngIRCd Release 18 (2011-07-10)
|
||||
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 "CloakHost": when set, this host name is used for
|
||||
every client instead of the real DNS host name (or IP address).
|
||||
- New configuration option "CloakUserToNick": when enabled, ngIRCd sets
|
||||
every clients' user name to their nick name and hides the user name
|
||||
every clients' user name to their nickname 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 ...
|
||||
@@ -348,7 +588,7 @@ ngIRCd Release 17 (2010-11-07)
|
||||
- configure script: correctly indent IPv6 yes/no summary output.
|
||||
- Don't reset My_Connections[Idx].lastping when reading data, so the
|
||||
client lag debug-output is working again.
|
||||
- Implement user mode "x": hostname cloaking (closes: #102).
|
||||
- Implement user mode "x": host name cloaking (closes: #102).
|
||||
- Make configure switch "--docdir" work (closes: #108).
|
||||
- Reformat and update FAQ.txt a little bit.
|
||||
- INSTALL: mention SSL, IPv6, and changed handling of MotdFile.
|
||||
@@ -453,7 +693,7 @@ ngIRCd Release 14.1 (2009-05-05)
|
||||
- Allow ping timeout quit messages to show the timeout value.
|
||||
- Fix error handling on compressed links.
|
||||
- Fix server list announcement.
|
||||
- Do not remove hostnames from info text.
|
||||
- Do not remove host names from info text.
|
||||
|
||||
ngIRCd Release 14 (2009-04-20)
|
||||
|
||||
@@ -549,7 +789,7 @@ ngIRCd 0.12.0 (2008-05-13)
|
||||
- RPL_WHOREPLY messages generated by IRC_WHO didn't include flags (*,@,+).
|
||||
(Dana Dahlstrom)
|
||||
- IRC_WHO now supports search patterns and will test this against user
|
||||
nickname/servername/hostname, etc. as required by RFC 2812, Section 3.6.1.
|
||||
nickname/server name/host name, etc. as required by RFC 2812, Section 3.6.1.
|
||||
(reported by Dana Dahlstrom)
|
||||
- Add test cases for "WHO" command. (Dana Dahlstrom)
|
||||
- Implement RFC 2812 handling of "0" argument to 'JOIN': must be treated
|
||||
@@ -572,12 +812,12 @@ ngIRCd 0.11.0 (2008-01-15)
|
||||
ngircd to crash [from HEAD]. (CVE-2008-0285)
|
||||
|
||||
ngIRCd 0.11.0-pre1 (2008-01-02)
|
||||
- Use dotted-decimal IP address if hostname is >= 64.
|
||||
- Use dotted-decimal IP address if host name is >= 64.
|
||||
- Add support for /STAT u (server uptime) command.
|
||||
- New [Server] configuration Option "Bind" allows to specify
|
||||
the source IP address to use when connecting to remote server.
|
||||
- New configuration option "MaxNickLength" to specify the allowed maximum
|
||||
length of user nick names. Note: must be unique in an IRC network!
|
||||
length of user nicknames. Note: must be unique in an IRC network!
|
||||
- Enhanced the IRC+ protocol to support an enhanced "server handshake" and
|
||||
enable server to recognize numeric 005 (ISUPPORT) and 376 (ENDOFMOTD).
|
||||
See doc/Protocol.txt for details.
|
||||
@@ -798,7 +1038,7 @@ ngIRCd 0.8.0 (2004-06-26)
|
||||
original ircd exactly: the unnecessary but missing ":" before the last
|
||||
parameter has been added.
|
||||
- Fixed TRACE: don't output "Serv" lines for ourself; display more info.
|
||||
- Results of the resolver (hostnames and IDENT names) are discarded after
|
||||
- Results of the resolver (host names and IDENT names) are discarded after
|
||||
the client is successfully registered with the server.
|
||||
- Better logging while establishing and shutting down connections.
|
||||
- The type of service (TOS) of all sockets is set to "interactive" now.
|
||||
|
47
INSTALL
47
INSTALL
@@ -2,7 +2,7 @@
|
||||
ngIRCd - Next Generation IRC Server
|
||||
http://ngircd.barton.de/
|
||||
|
||||
(c)2001-2012 Alexander Barton and Contributors.
|
||||
(c)2001-2013 Alexander Barton and Contributors.
|
||||
ngIRCd is free software and published under the
|
||||
terms of the GNU General Public License.
|
||||
|
||||
@@ -12,6 +12,14 @@
|
||||
I. Upgrade Information
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Differences to version 19.x
|
||||
|
||||
- Starting with ngIRCd 20, users can "cloak" their hostname only when the
|
||||
configuration variable "CloakHostModeX" (introduced in 19.2) is set.
|
||||
Otherwise, only IRC opertators, other servers, and services are allowed to
|
||||
set mode +x. This prevents regular users from changing their hostmask to
|
||||
the name of the IRC server itself, which confused quite a few people ;-)
|
||||
|
||||
Differences to version 17
|
||||
|
||||
- Support for ZeroConf/Bonjour/Rendezvous service registration has been
|
||||
@@ -93,7 +101,8 @@ automake ("configure") should be no problem.
|
||||
The normal installation procedure after getting (and expanding) the source
|
||||
files (using a distribution archive or GIT) is as following:
|
||||
|
||||
1) ./autogen.sh [only necessary when using GIT]
|
||||
0) Satisfy prerequisites
|
||||
1) ./autogen.sh [only necessary when using GIT]
|
||||
2) ./configure
|
||||
3) make
|
||||
4) make install
|
||||
@@ -114,6 +123,30 @@ possible options will be installed there. You'll find its template in the
|
||||
doc/ directory: sample-ngircd.conf.
|
||||
|
||||
|
||||
0): Satisfy prerequisites
|
||||
|
||||
When building from source, you'll need some other software to build ngIRCd:
|
||||
for example a working C compiler, make tool, GNU automake and autoconf (only
|
||||
when not using a distribution archive), and a few libraries depending on the
|
||||
features you want to compile in (like IDENT support, SSL, and PAM).
|
||||
|
||||
If you are using one of the "big" operating systems or Linux distributions,
|
||||
you can use the following commands to install all the required packages to
|
||||
build the sources including all optional features and to run the test suite:
|
||||
|
||||
* RedHat / Fedora based distributions:
|
||||
|
||||
yum install \
|
||||
autoconf automake expect gcc glibc-devel gnutls-devel \
|
||||
libident-devel make pam-devel tcp_wrappers-devel telnet zlib-devel
|
||||
|
||||
* Debian / Ubuntu based distributions:
|
||||
|
||||
apt-get install \
|
||||
autoconf automake build-essential expect libgnutls-dev \
|
||||
libident-dev libpam-dev libwrap0-dev libz-dev telnet
|
||||
|
||||
|
||||
1): "autogen.sh"
|
||||
|
||||
The first step, autogen.sh, is only necessary if the configure-script isn't
|
||||
@@ -124,10 +157,14 @@ This step is therefore only interesting for developers.
|
||||
|
||||
autogen.sh produces the Makefile.in's, which are necessary for the configure
|
||||
script itself, and some more files for make. To run autogen.sh you'll need
|
||||
GNU autoconf and GNU automake (use recent versions! autoconf 2.53 and
|
||||
automake 1.6.1 are known to work).
|
||||
GNU autoconf and GNU automake: at least autoconf 2.61 and automake 1.10 are
|
||||
requird, newer is better. But don't use automake 1.12 or newer for creating
|
||||
distribution archives: it will work but lack "de-ANSI-fucation" support in the
|
||||
generated Makefile's! Stick with automake 1.11.x for this purpose ...
|
||||
So automake 1.11.x and autoconf 2.67+ is recommended.
|
||||
|
||||
Again: "end users" do not need this step!
|
||||
Again: "end users" do not need this step and neither need GNU autoconf nor GNU
|
||||
automake at all!
|
||||
|
||||
|
||||
2): "./configure"
|
||||
|
14
Makefile.am
14
Makefile.am
@@ -1,6 +1,6 @@
|
||||
#
|
||||
# ngIRCd -- The Next Generation IRC Daemon
|
||||
# Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors
|
||||
# Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@@ -13,24 +13,26 @@ AUTOMAKE_OPTIONS = gnu
|
||||
|
||||
SUBDIRS = doc src man contrib
|
||||
|
||||
EXTRA_DIST = autogen.sh configure.ng .mailmap
|
||||
|
||||
clean-local:
|
||||
rm -f build-stamp*
|
||||
rm -rf ngircd.dest
|
||||
|
||||
maintainer-clean-local:
|
||||
rm -rf autom4te.cache
|
||||
rm -f Makefile.in Makefile aclocal.m4 configure
|
||||
rm -f mkinstalldirs missing depcomp install-sh
|
||||
rm -f Makefile.in Makefile aclocal.m4 configure configure.ac
|
||||
rm -f ar-lib mkinstalldirs missing depcomp install-sh
|
||||
rm -f config.log debian
|
||||
|
||||
testsuite:
|
||||
make -C src/testsuite check
|
||||
cd src/testsuite && make check
|
||||
|
||||
lint:
|
||||
make -C src/ngircd lint
|
||||
cd src/ngircd && make lint
|
||||
|
||||
srcdoc:
|
||||
make -C doc srcdoc
|
||||
cd doc && make srcdoc
|
||||
|
||||
have-xcodebuild:
|
||||
@xcodebuild -project contrib/MacOSX/ngIRCd.xcodeproj -list \
|
||||
|
140
NEWS
140
NEWS
@@ -2,16 +2,132 @@
|
||||
ngIRCd - Next Generation IRC Server
|
||||
http://ngircd.barton.de/
|
||||
|
||||
(c)2001-2012 Alexander Barton and Contributors.
|
||||
(c)2001-2013 Alexander Barton and Contributors.
|
||||
ngIRCd is free software and published under the
|
||||
terms of the GNU General Public License.
|
||||
|
||||
-- NEWS --
|
||||
|
||||
|
||||
ngIRCd 20.3 (2013-08-23)
|
||||
|
||||
- This release is a bugfix release only, without new features.
|
||||
- Security: Fix a denial of service bug (server crash) which could happen
|
||||
when the configuration option "NoticeAuth" is enabled (which is NOT the
|
||||
default) and ngIRCd failed to send the "notice auth" messages to new
|
||||
clients connecting to the server (CVE-2013-5580).
|
||||
|
||||
ngIRCd 20.2 (2013-02-15)
|
||||
|
||||
- This release is a bugfix release only, without new features.
|
||||
- Security: Fix a denial of service bug in the function handling KICK
|
||||
commands that could be used by arbitrary users to to crash the daemon
|
||||
(CVE-2013-1747).
|
||||
|
||||
ngIRCd 20.1 (2013-01-02)
|
||||
|
||||
- This release is a bugfix release only, without new features.
|
||||
|
||||
ngIRCd 20 (2012-12-17)
|
||||
|
||||
- Allow user names ("INDENT") up to 20 characters when ngIRCd has not
|
||||
been configured for "strict RFC mode". This is useful if you are using
|
||||
external (PAM) authenticaion mechanisms that require longer user names.
|
||||
Patch suggested by Brett Smith <brett@w3.org>, see
|
||||
<http://arthur.barton.de/pipermail/ngircd-ml/2012-October/000579.html>.
|
||||
|
||||
ngIRCd 20~rc2 (2012-12-02)
|
||||
- Rework cloaked hostname handling and implement the "METADATA cloakhost"
|
||||
subcommand: Now ngIRCd uses two fields internally, one to store the
|
||||
"real" hostname and one to save the "cloaked" hostname. This allows
|
||||
"foreign servers" (aka "IRC services") to alter the real and cloaked
|
||||
hostnames of clients without problems, even when the user itself issues
|
||||
additional "MODE +x" and "MODE -x" commands.
|
||||
|
||||
ngIRCd 20~rc1 (2012-11-11)
|
||||
- Update doc/Services.txt: describe the upcoming version of Anope 1.9.8,
|
||||
then including a protocol module for ngIRCd. And remove our own patches
|
||||
in ./contrib/Anope because they aren't supported any more ...
|
||||
- Implement new "METADATA" command which can be used by remote servers
|
||||
and IRC services to update client metadata like the client info text
|
||||
("real name"), user name, and hostname, and use this command to
|
||||
configure an cloaked hostname (user mode "+x") on remote servers:
|
||||
This prevents "double cloaking" of hostnames and even cloaked
|
||||
hostnames are in sync on all servers supporting "METADATA" now.
|
||||
- Implement new IRC "SVSNICK" command to allow remote servers (and IRC
|
||||
services) to change nicknames of already registered users. The SVSNICK
|
||||
command itself doesn't change the nickname, but it becomes forwarded
|
||||
to the server to which the user is connected to. And then this server
|
||||
initiates the real nickname changing using regular NICK commands.
|
||||
This allows to run mixed networks with old servers not supporting the
|
||||
SVSNICK command, because SVSNICK commands for nicknames on such servers
|
||||
are silently ignored and don't cause a desynchronization of the network.
|
||||
- New configuration option "MaxListSize" to configure the maximum number
|
||||
of channels returned by a LIST command. The default is 100, as before.
|
||||
- Implement user mode "b", "block messages": when a user has set mode "b",
|
||||
all private messages and notices to this user are blocked if they don't
|
||||
originate from a registered user, an IRC Op, server or service. The
|
||||
originator gets an error numeric sent back in this case,
|
||||
ERR_NONONREG_MSG (486), which is used by UnrealIRCd, too. (Closes #144)
|
||||
- Implement channel mode "V" (invite disallow): If the new channel mode
|
||||
"V" is set, the INVITE command becomes invalid and all clients get the
|
||||
new ERR_NOINVITE_MSG (518) reply. (Closes #143)
|
||||
- Implement channel mode "Q" and user mode "q": Both modes protect users
|
||||
from channel kicks: only IRC operators and servers can kick users having
|
||||
mode "q" or in channels with mode "Q". (Closes #141)
|
||||
- Allow users to "cloak" their hostname only when the configuration
|
||||
variable "CloakHostModeX" (introduced in 19.2) is set. Otherwise, only
|
||||
IRC operators, other servers, and services are allowed to set the user
|
||||
mode "+x": this prevents regular users from changing their hostmask to
|
||||
the name of the IRC server itself, which confused quite a few people ;-)
|
||||
(Closes #133)
|
||||
- New configuration option "OperChanPAutoOp": If disabled, IRC operators
|
||||
don't become channel operators in persistent channels when joining.
|
||||
Enabled by default, which has been the behavior of ngIRCd up to this
|
||||
patch. (Closes #135)
|
||||
- Allow IRC operators to see secret (+s) channels in LIST command as long
|
||||
as the "MorePrivacy" configuration option isn't enabled in the
|
||||
configuration file. (Closes #136)
|
||||
- Implement new (optional) IRC+ "CHARCONV" command to set a client
|
||||
character set that the server translates all messages to/from UTF-8.
|
||||
This feature requires the "libiconv" library and must be enabled using
|
||||
the new "--with-iconv" option of the ./configure script. See
|
||||
doc/Protocol.txt for details. (Closes #109)
|
||||
- Implement user mode "B" ("Bot flag"): it is settable and unsettable by
|
||||
every (non-restricted) client. This is how Unreal and InspIRCd do
|
||||
behave, and so do we :-)
|
||||
- Implement channel mode "M": Only the server, identified users and IRC
|
||||
operators are able to talk in such a channel.
|
||||
- Block nicknames that are reserved for services and are defined using the
|
||||
configuration variable "ServiceMask" in "Server" blocks; And this
|
||||
variable now can handle more than one mask separated by commas.
|
||||
- Implemented XOP channel user modes: "Half Op" ("+h", prefix "%") can set
|
||||
the channel modes +imntvIbek and kick all +v and normal users; "Admin"
|
||||
("+a", prefix "&") can set channel modes +imntvIbekoRsz and kick all +o,
|
||||
+h, +v and normal users; and "Owner" ("+q", prefix "~") can set channel
|
||||
modes +imntvIbekoRsz and kick all +a, +o, +h, +v and normal users.
|
||||
- Implement hashed cloaked hostnames for both the "CloakHost" and
|
||||
"CloakHostModeX" configuration options: now the admin can use the new
|
||||
'%x' placeholder to insert a hashed version of the clients hostname,
|
||||
and the new configuration option "CloakHostSalt" defines the salt for
|
||||
the hash function. When "CloakHostSalt" is not set (the default), a
|
||||
random salt will be generated after each server restart.
|
||||
|
||||
ngIRCd Release 19.2 (2012-06-19)
|
||||
|
||||
ngIRCd 19.2~rc1 (2012-06-13)
|
||||
- New configuration option "CloakHostModeX" to configure the hostname
|
||||
that gets used for IRC clients which have user mode "+x" enabled.
|
||||
Up to now, the name of the IRC server itself has been used for this,
|
||||
which still is the default when "CloakHostModeX" isn't set.
|
||||
- Add instructions for setting up Atheme IRC services.
|
||||
- Implement support for IRC capability handling, the new "CAP" command,
|
||||
and capablity "multi-prefix" which allows both the NAME and WHO command
|
||||
handlers to return more than one "class prefix" to the client.
|
||||
|
||||
ngIRCd Release 19.1 (2012-03-19)
|
||||
|
||||
- Really include _all_ patchtes to build the Anope module into the
|
||||
- Really include _all_ patches to build the Anope module into the
|
||||
distribution archive ... ooops!
|
||||
|
||||
ngIRCd Release 19 (2012-02-29)
|
||||
@@ -19,7 +135,7 @@ ngIRCd Release 19 (2012-02-29)
|
||||
ngIRCd 19~rc1 (2012-02-12)
|
||||
- Update preliminary ngIRCd protocol module for Anope 1.9.6, which now
|
||||
is the only supported version.
|
||||
- New numeric RPL_WHOISHOST_MSG(378), which returns the DNS hostname
|
||||
- New numeric RPL_WHOISHOST_MSG(378), which returns the DNS host name
|
||||
(if available) and the IP address of a client in the WHOIS reply.
|
||||
Only the user itself and local IRC operators get this numeric.
|
||||
- Implement channel exception list (mode 'e'). This allows a channel
|
||||
@@ -31,7 +147,7 @@ ngIRCd Release 19 (2012-02-29)
|
||||
and receiver are on the same channel. This prevents private flooding
|
||||
by completely unknown clients.
|
||||
- New RPL_WHOISREGNICK_MSG(307) numeric in WHOIS command replies: it
|
||||
indicates if a nick name is registered (if user mode 'R' set).
|
||||
indicates if a nickname is registered (if user mode 'R' set).
|
||||
- Limit channel invite, ban, and exception lists to 50 entries and fix
|
||||
duplicate check and error messages when adding already listed entries
|
||||
or deleting no (longer) existing ones.
|
||||
@@ -67,7 +183,7 @@ ngIRCd Release 19 (2012-02-29)
|
||||
NICK, and USER commands have been processed) and before the child
|
||||
processes for authentication are forked, so resource usage is smaller.
|
||||
- Added doc/Modes.txt: document modes supported by ngIRCd.
|
||||
- Implement user mode "R": indicates that the nick name of this user
|
||||
- Implement user mode "R": indicates that the nickname of this user
|
||||
is "registered". This mode isn't handled by ngIRCd itself, but must
|
||||
be set and unset by IRC services like Anope.
|
||||
- Implement channel mode "R": only registered users (having the user
|
||||
@@ -78,7 +194,7 @@ ngIRCd Release 19 (2012-02-29)
|
||||
- Handle channel user modes 'a', 'h', and 'q' from remote servers.
|
||||
These channel user modes aren't used for anything at the moment,
|
||||
but ngIRCd knows that these three modes are "channel user modes"
|
||||
and not "channel modes", that is that these modes take an "nick name"
|
||||
and not "channel modes", that is that these modes take an "nickname"
|
||||
argument. Like unknown user and channel modes, these modes are saved
|
||||
and forwarded to other servers, but ignored otherwise.
|
||||
|
||||
@@ -134,10 +250,10 @@ ngIRCd Release 18 (2011-07-10)
|
||||
(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 "CloakHost": when set, this host name is used for
|
||||
every client instead of the real DNS host name (or IP address).
|
||||
- New configuration option "CloakUserToNick": when enabled, ngIRCd sets
|
||||
every clients' user name to their nick name and hides the user name
|
||||
every clients' user name to their nickname 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
|
||||
@@ -187,7 +303,7 @@ ngIRCd Release 17 (2010-11-07)
|
||||
- Enable the daemon to disable and enable "debug mode" on runtime using
|
||||
signal SIGUSR1, when debug code is compiled in, not only on startup
|
||||
using the command line parameters.
|
||||
- Implement user mode "x": hostname cloaking (closes: #102).
|
||||
- Implement user mode "x": host name cloaking (closes: #102).
|
||||
- Change MOTD file handling: ngIRCd now caches the contens of the MOTD
|
||||
file, so the daemon now requires a HUP signal or REHASH command to
|
||||
re-read the MOTD file when its content changed.
|
||||
@@ -292,7 +408,7 @@ ngIRCd 0.12.0 (2008-05-13)
|
||||
- Implemented IRC commands INFO, SUMMON (dummy), and USERS (dummy) and
|
||||
enhanced test suite to check these commands. (Dana Dahlstrom)
|
||||
- IRC_WHO now supports search patterns and will test this against user
|
||||
nickname/servername/hostname, etc. as required by RFC 2812, Section 3.6.1.
|
||||
nickname/server name/host name, etc. as required by RFC 2812, Section 3.6.1.
|
||||
(reported by Dana Dahlstrom)
|
||||
- Implement RFC 2812 handling of "0" argument to 'JOIN': must be treated
|
||||
as if the user had sent PART commands for all channels the user is a
|
||||
@@ -305,7 +421,7 @@ ngIRCd 0.11.0 (2008-01-15)
|
||||
- New [Server] configuration Option "Bind" allows to specify
|
||||
the source IP address to use when connecting to remote server.
|
||||
- New configuration option "MaxNickLength" to specify the allowed maximum
|
||||
length of user nick names. Note: must be unique in an IRC network!
|
||||
length of user nicknames. Note: must be unique in an IRC network!
|
||||
- Numeric 317: implemented "signon time" (displayed in WHOIS result).
|
||||
- Added new server configuration option "Passive" for "Server" blocks to
|
||||
disable automatic outgoing connections (similar to -p option to ngircd,
|
||||
|
17
README
17
README
@@ -2,7 +2,7 @@
|
||||
ngIRCd - Next Generation IRC Server
|
||||
http://ngircd.barton.de/
|
||||
|
||||
(c)2001-2012 Alexander Barton and Contributors.
|
||||
(c)2001-2013 Alexander Barton and Contributors.
|
||||
ngIRCd is free software and published under the
|
||||
terms of the GNU General Public License.
|
||||
|
||||
@@ -12,12 +12,15 @@
|
||||
I. Introduction
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
ngIRCd is an Open Source server for the Internet Relay Chat (IRC), which
|
||||
is developed and published under the terms of the GNU General Public
|
||||
Licence, see the file COPYING for details. ngIRCd means "next generation
|
||||
IRC daemon" (which is a little bit exaggerated, "lightweight Internet Relay
|
||||
Chat server" would be better), it's written from scratch and not deduced
|
||||
from the "grandfather of IRC daemons", the daemon of the IRCNet.
|
||||
ngIRCd is a free, portable and lightweight Internet Relay Chat server for
|
||||
small or private networks, developed under the GNU General Public License
|
||||
(GPL; please see the file COPYING for details). It is simple to configure,
|
||||
can cope with dynamic IP addresses, and supports IPv6 as well as SSL. It is
|
||||
written from scratch and not based on the original IRCd.
|
||||
|
||||
The name ngIRCd means next generation IRC daemon, which is a little bit
|
||||
exaggerated: lightweight Internet Relay Chat server most probably would be a
|
||||
better name :-)
|
||||
|
||||
Please see the INSTALL document for installation and upgrade information!
|
||||
|
||||
|
78
autogen.sh
78
autogen.sh
@@ -1,7 +1,7 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# ngIRCd -- The Next Generation IRC Daemon
|
||||
# Copyright (c)2001-2008 Alexander Barton <alex@barton.de>
|
||||
# Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@@ -16,6 +16,11 @@
|
||||
# GNU autoconf. It tries to be smart in finding the correct/usable/available
|
||||
# installed versions of these tools on your system.
|
||||
#
|
||||
# In addition, it enables or disables the "de-ANSI-fication" support of GNU
|
||||
# automake, which is supported up to autoconf 1.11.x an has been removed
|
||||
# in automake 1.12 -- make sure to use a version of automake supporting it
|
||||
# when generating distribution archives!
|
||||
#
|
||||
# The following strategy is used for each of aclocal, autoheader, automake,
|
||||
# and autoconf: first, "tool" (the regular name of the tool, e. g. "autoconf"
|
||||
# or "automake") is checked. If this fails, "tool<major><minor>" (for example
|
||||
@@ -98,6 +103,12 @@ Notfound()
|
||||
exit 1
|
||||
}
|
||||
|
||||
Run()
|
||||
{
|
||||
[ "$VERBOSE" = "1" ] && echo " - running \"$@\" ..."
|
||||
$@
|
||||
}
|
||||
|
||||
# Reset locale settings to suppress warning messages of Perl
|
||||
unset LC_ALL
|
||||
unset LANG
|
||||
@@ -123,19 +134,18 @@ fi
|
||||
|
||||
# Try to detect the needed tools when no environment variable already
|
||||
# specifies one:
|
||||
echo "Searching tools ..."
|
||||
echo "Searching for required tools ..."
|
||||
[ -z "$ACLOCAL" ] && ACLOCAL=`Search aclocal 1`
|
||||
[ "$VERBOSE" = "1" ] && echo "ACLOCAL=$ACLOCAL"
|
||||
[ "$VERBOSE" = "1" ] && echo " - ACLOCAL=$ACLOCAL"
|
||||
[ -z "$AUTOHEADER" ] && AUTOHEADER=`Search autoheader 2`
|
||||
[ "$VERBOSE" = "1" ] && echo "AUTOHEADER=$AUTOHEADER"
|
||||
[ "$VERBOSE" = "1" ] && echo " - AUTOHEADER=$AUTOHEADER"
|
||||
[ -z "$AUTOMAKE" ] && AUTOMAKE=`Search automake 1`
|
||||
[ "$VERBOSE" = "1" ] && echo "AUTOMAKE=$AUTOMAKE"
|
||||
[ "$VERBOSE" = "1" ] && echo " - AUTOMAKE=$AUTOMAKE"
|
||||
[ -z "$AUTOCONF" ] && AUTOCONF=`Search autoconf 2`
|
||||
[ "$VERBOSE" = "1" ] && echo "AUTOCONF=$AUTOCONF"
|
||||
[ "$VERBOSE" = "1" ] && echo " - AUTOCONF=$AUTOCONF"
|
||||
|
||||
# Call ./configure when parameters have been passed to this script and
|
||||
# GO isn't already defined.
|
||||
[ -z "$GO" -a $# -gt 0 ] && GO=1
|
||||
[ $# -gt 0 ] && CONFIGURE_ARGS=" $@" || CONFIGURE_ARGS=""
|
||||
[ -z "$GO" -a -n "$CONFIGURE_ARGS" ] && GO=1
|
||||
|
||||
# Verify that all tools have been found
|
||||
[ -z "$ACLOCAL" ] && Notfound aclocal
|
||||
@@ -143,14 +153,51 @@ echo "Searching tools ..."
|
||||
[ -z "$AUTOMAKE" ] && Notfound automake
|
||||
[ -z "$AUTOCONF" ] && Notfound autoconf
|
||||
|
||||
AM_VERSION=`$AUTOMAKE --version | head -n 1 | sed -e 's/.* //g'`
|
||||
ifs=$IFS; IFS="."; set $AM_VERSION; IFS=$ifs
|
||||
AM_MAJOR="$1"; AM_MINOR="$2"; AM_PATCHLEVEL="$3"
|
||||
|
||||
AM_MAKEFILES="src/ipaddr/Makefile.ng src/ngircd/Makefile.ng src/testsuite/Makefile.ng src/tool/Makefile.ng"
|
||||
|
||||
if [ "$AM_MAJOR" -eq "1" -a "$AM_MINOR" -lt "12" ]; then
|
||||
# automake < 1.12 => automatic de-ANSI-fication support available
|
||||
echo "Enabling de-ANSI-fication support (automake $AM_VERSION) ..."
|
||||
sed -e "s|^__ng_PROTOTYPES__|AM_C_PROTOTYPES|g" configure.ng >configure.ac
|
||||
DEANSI_START=""
|
||||
DEANSI_END=""
|
||||
else
|
||||
# automake >= 1.12 => no de-ANSI-fication support available
|
||||
echo "Disabling de-ANSI-fication support (automake $AM_VERSION) ..."
|
||||
sed -e "s|^__ng_PROTOTYPES__|AC_C_PROTOTYPES|g" configure.ng >configure.ac
|
||||
DEANSI_START="#"
|
||||
DEANSI_END=" # disabled by ./autogen.sh script"
|
||||
fi
|
||||
# Serial test harness?
|
||||
if [ "$AM_MAJOR" -eq "1" -a "$AM_MINOR" -ge "13" ]; then
|
||||
# automake >= 1.13 => enforce "serial test harness"
|
||||
echo " - Enforcing serial test harness."
|
||||
SERIAL_TESTS="serial-tests"
|
||||
else
|
||||
# automake < 1.13 => no new test harness, nothing to do
|
||||
SERIAL_TEST=""
|
||||
fi
|
||||
|
||||
sed -e "s|^__ng_Makefile_am_template__|AUTOMAKE_OPTIONS = ${SERIAL_TESTS} ${DEANSI_START}ansi2knr${DEANSI_END}|g" \
|
||||
src/portab/Makefile.ng >src/portab/Makefile.am
|
||||
for makefile_ng in $AM_MAKEFILES; do
|
||||
makefile_am=`echo "$makefile_ng" | sed -e "s|\.ng\$|\.am|g"`
|
||||
sed -e "s|^__ng_Makefile_am_template__|AUTOMAKE_OPTIONS = ${SERIAL_TESTS} ${DEANSI_START}../portab/ansi2knr${DEANSI_END}|g" \
|
||||
$makefile_ng >$makefile_am
|
||||
done
|
||||
|
||||
export ACLOCAL AUTOHEADER AUTOMAKE AUTOCONF
|
||||
|
||||
# Generate files
|
||||
echo "Generating files ..."
|
||||
$ACLOCAL && \
|
||||
$AUTOHEADER && \
|
||||
$AUTOMAKE --add-missing && \
|
||||
$AUTOCONF --force
|
||||
echo "Generating files using GNU $AUTOCONF and $AUTOMAKE ..."
|
||||
Run $ACLOCAL && \
|
||||
Run $AUTOCONF && \
|
||||
Run $AUTOHEADER && \
|
||||
Run $AUTOMAKE --add-missing --no-force
|
||||
|
||||
if [ $? -eq 0 -a -x ./configure ]; then
|
||||
# Success: if we got some parameters we call ./configure and pass
|
||||
@@ -158,8 +205,7 @@ if [ $? -eq 0 -a -x ./configure ]; then
|
||||
NAME=`grep PACKAGE_STRING= configure | cut -d"'" -f2`
|
||||
if [ "$GO" = "1" ]; then
|
||||
[ -n "$PREFIX" ] && p=" --prefix=$PREFIX" || p=""
|
||||
[ -n "$*" ] && a=" $*" || a=""
|
||||
c="./configure${p}${a}"
|
||||
c="./configure${p}${CONFIGURE_ARGS}"
|
||||
echo "Okay, autogen.sh for $NAME done."
|
||||
echo "Calling \"$c\" ..."
|
||||
$c
|
||||
|
17
config.guess
vendored
17
config.guess
vendored
@@ -4,7 +4,7 @@
|
||||
# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
||||
# 2011, 2012 Free Software Foundation, Inc.
|
||||
|
||||
timestamp='2012-02-10'
|
||||
timestamp='2012-08-14'
|
||||
|
||||
# This file is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
@@ -200,6 +200,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
|
||||
echo "${machine}-${os}${release}"
|
||||
exit ;;
|
||||
*:Bitrig:*:*)
|
||||
UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
|
||||
echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE}
|
||||
exit ;;
|
||||
*:OpenBSD:*:*)
|
||||
UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
|
||||
echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
|
||||
@@ -801,6 +805,9 @@ EOF
|
||||
i*:CYGWIN*:*)
|
||||
echo ${UNAME_MACHINE}-pc-cygwin
|
||||
exit ;;
|
||||
*:MINGW64*:*)
|
||||
echo ${UNAME_MACHINE}-pc-mingw64
|
||||
exit ;;
|
||||
*:MINGW*:*)
|
||||
echo ${UNAME_MACHINE}-pc-mingw32
|
||||
exit ;;
|
||||
@@ -1201,6 +1208,9 @@ EOF
|
||||
BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
|
||||
echo i586-pc-haiku
|
||||
exit ;;
|
||||
x86_64:Haiku:*:*)
|
||||
echo x86_64-unknown-haiku
|
||||
exit ;;
|
||||
SX-4:SUPER-UX:*:*)
|
||||
echo sx4-nec-superux${UNAME_RELEASE}
|
||||
exit ;;
|
||||
@@ -1256,7 +1266,7 @@ EOF
|
||||
NEO-?:NONSTOP_KERNEL:*:*)
|
||||
echo neo-tandem-nsk${UNAME_RELEASE}
|
||||
exit ;;
|
||||
NSE-?:NONSTOP_KERNEL:*:*)
|
||||
NSE-*:NONSTOP_KERNEL:*:*)
|
||||
echo nse-tandem-nsk${UNAME_RELEASE}
|
||||
exit ;;
|
||||
NSR-?:NONSTOP_KERNEL:*:*)
|
||||
@@ -1330,9 +1340,6 @@ EOF
|
||||
exit ;;
|
||||
esac
|
||||
|
||||
#echo '(No uname command or uname output not recognized.)' 1>&2
|
||||
#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
|
||||
|
||||
eval $set_cc_for_build
|
||||
cat >$dummy.c <<EOF
|
||||
#ifdef _SEQUENT_
|
||||
|
23
config.sub
vendored
23
config.sub
vendored
@@ -4,7 +4,7 @@
|
||||
# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
||||
# 2011, 2012 Free Software Foundation, Inc.
|
||||
|
||||
timestamp='2012-02-10'
|
||||
timestamp='2012-08-18'
|
||||
|
||||
# This file is (in principle) common to ALL GNU software.
|
||||
# The presence of a machine in this file suggests that SOME GNU software
|
||||
@@ -123,7 +123,7 @@ esac
|
||||
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
|
||||
case $maybe_os in
|
||||
nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
|
||||
linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
|
||||
linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
|
||||
knetbsd*-gnu* | netbsd*-gnu* | \
|
||||
kopensolaris*-gnu* | \
|
||||
storm-chaos* | os2-emx* | rtmk-nova*)
|
||||
@@ -225,6 +225,12 @@ case $os in
|
||||
-isc*)
|
||||
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
|
||||
;;
|
||||
-lynx*178)
|
||||
os=-lynxos178
|
||||
;;
|
||||
-lynx*5)
|
||||
os=-lynxos5
|
||||
;;
|
||||
-lynx*)
|
||||
os=-lynxos
|
||||
;;
|
||||
@@ -785,6 +791,10 @@ case $basic_machine in
|
||||
microblaze)
|
||||
basic_machine=microblaze-xilinx
|
||||
;;
|
||||
mingw64)
|
||||
basic_machine=x86_64-pc
|
||||
os=-mingw64
|
||||
;;
|
||||
mingw32)
|
||||
basic_machine=i386-pc
|
||||
os=-mingw32
|
||||
@@ -1346,15 +1356,15 @@ case $os in
|
||||
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
|
||||
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
|
||||
| -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
|
||||
| -openbsd* | -solidbsd* \
|
||||
| -bitrig* | -openbsd* | -solidbsd* \
|
||||
| -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
|
||||
| -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
|
||||
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
|
||||
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
|
||||
| -chorusos* | -chorusrdb* | -cegcc* \
|
||||
| -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
|
||||
| -mingw32* | -linux-gnu* | -linux-android* \
|
||||
| -linux-newlib* | -linux-uclibc* \
|
||||
| -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
|
||||
| -linux-newlib* | -linux-musl* | -linux-uclibc* \
|
||||
| -uxpv* | -beos* | -mpeix* | -udk* \
|
||||
| -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
|
||||
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
|
||||
@@ -1537,6 +1547,9 @@ case $basic_machine in
|
||||
c4x-* | tic4x-*)
|
||||
os=-coff
|
||||
;;
|
||||
hexagon-*)
|
||||
os=-elf
|
||||
;;
|
||||
tic54x-*)
|
||||
os=-coff
|
||||
;;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
#
|
||||
# ngIRCd -- The Next Generation IRC Daemon
|
||||
# Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors
|
||||
# Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@@ -9,46 +9,60 @@
|
||||
# Please read the file COPYING, README and AUTHORS for more information.
|
||||
#
|
||||
|
||||
define(VERSION_ID,esyscmd(git describe|sed -e 's/rel-//g'|sed -e 's/-/~/'|tr -d \\n))
|
||||
define(VERSION_ID,esyscmd([
|
||||
V=`git describe 2>/dev/null | sed -e 's/rel-//g' | sed -e 's/-/~/'`;
|
||||
[ -z "$V" -a -r configure ] \
|
||||
&& V=`grep "PACKAGE_STRING=" configure | cut -d"'" -f2 | cut -d' ' -f2`
|
||||
( [ -n "$V" ] && echo "$V" || echo "??" ) | tr -d '\n';
|
||||
]))
|
||||
|
||||
m4_ifdef([AM_SILENT_RULES],
|
||||
[m4_define([ng_color_tests], [color-tests])],
|
||||
[m4_define([ng_color_tests], [])])
|
||||
|
||||
# -- Initialisation --
|
||||
|
||||
AC_PREREQ(2.50)
|
||||
AC_INIT(ngircd, VERSION_ID)
|
||||
AC_CONFIG_SRCDIR(src/ngircd/ngircd.c)
|
||||
AC_CANONICAL_TARGET
|
||||
AM_INIT_AUTOMAKE(1.6)
|
||||
AM_CONFIG_HEADER(src/config.h)
|
||||
AC_PREREQ([2.61])
|
||||
AC_INIT([ngIRCd], VERSION_ID,
|
||||
[ngircd-ml@ngircd.barton.de], [ngircd], [http://ngircd.barton.de/])
|
||||
|
||||
AC_CONFIG_SRCDIR([src/ngircd/ngircd.c])
|
||||
AC_CONFIG_HEADER([src/config.h])
|
||||
AC_CANONICAL_HOST
|
||||
|
||||
AM_INIT_AUTOMAKE([-Wall 1.10 ]ng_color_tests)
|
||||
|
||||
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
|
||||
|
||||
# -- Templates for config.h --
|
||||
|
||||
AH_TEMPLATE([DEBUG], [Define if debug-mode should be enabled])
|
||||
AH_TEMPLATE([HAVE_sockaddr_in_len], [Define if sockaddr_in.sin_len exists])
|
||||
AH_TEMPLATE([HAVE_socklen_t], [Define if socklen_t exists])
|
||||
AH_TEMPLATE([ICONV], [Define if libiconv can be used, e.g. for CHARCONV])
|
||||
AH_TEMPLATE([IDENTAUTH], [Define if the server should do IDENT requests])
|
||||
AH_TEMPLATE([IRCPLUS], [Define if IRC+ protocol should be used])
|
||||
AH_TEMPLATE([PAM], [Define if PAM should be used])
|
||||
AH_TEMPLATE([SNIFFER], [Define if IRC sniffer should be enabled])
|
||||
AH_TEMPLATE([STRICT_RFC], [Define if ngIRCd should behave strict RFC compliant])
|
||||
AH_TEMPLATE([SYSLOG], [Define if syslog should be used for logging])
|
||||
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([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])
|
||||
AH_TEMPLATE([ZLIB], [Define if zlib compression should be enabled])
|
||||
|
||||
AH_TEMPLATE([TARGET_OS], [Target operating system name])
|
||||
AH_TEMPLATE([TARGET_VENDOR], [Target system vendor])
|
||||
AH_TEMPLATE([TARGET_CPU], [Target CPU name])
|
||||
AH_TEMPLATE([HOST_OS], [Target operating system name])
|
||||
AH_TEMPLATE([HOST_VENDOR], [Target system vendor])
|
||||
AH_TEMPLATE([HOST_CPU], [Target CPU name])
|
||||
|
||||
# -- C Compiler --
|
||||
|
||||
AC_PROG_CC
|
||||
AC_PROG_CC_STDC
|
||||
AC_C_PROTOTYPES
|
||||
|
||||
# -- Helper programs --
|
||||
|
||||
m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
|
||||
|
||||
AC_PROG_AWK
|
||||
AC_PROG_INSTALL
|
||||
AC_PROG_LN_S
|
||||
@@ -57,9 +71,9 @@ AC_PROG_RANLIB
|
||||
|
||||
# -- Compiler Features --
|
||||
|
||||
AM_C_PROTOTYPES
|
||||
AC_C_CONST
|
||||
AC_C_INLINE
|
||||
__ng_PROTOTYPES__
|
||||
|
||||
# -- Hard coded system and compiler dependencies/features/options ... --
|
||||
|
||||
@@ -85,7 +99,7 @@ if test "$GCC" = "yes"; then
|
||||
GCC_STACK_PROTECT_CC
|
||||
fi
|
||||
|
||||
case "$target_os" in
|
||||
case "$host_os" in
|
||||
hpux*)
|
||||
# This is HP/UX, we need to define _XOPEN_SOURCE_EXTENDED
|
||||
# (tested with HP/UX 11.11)
|
||||
@@ -101,28 +115,20 @@ CFLAGS="$CFLAGS -DSYSCONFDIR='\"\$(sysconfdir)\"'"
|
||||
# -- Headers --
|
||||
|
||||
AC_HEADER_STDC
|
||||
AC_HEADER_TIME
|
||||
AC_HEADER_SYS_WAIT
|
||||
AC_HEADER_TIME
|
||||
|
||||
# Required header files
|
||||
AC_CHECK_HEADERS([ \
|
||||
ctype.h errno.h fcntl.h netdb.h netinet/in.h netinet/in_systm.h \
|
||||
stdlib.h string.h strings.h sys/socket.h sys/time.h unistd.h \
|
||||
fcntl.h netdb.h netinet/in.h stdlib.h string.h \
|
||||
strings.h sys/socket.h sys/time.h unistd.h \
|
||||
],,AC_MSG_ERROR([required C header missing!]))
|
||||
|
||||
AC_CHECK_HEADERS([ \
|
||||
arpa/inet.h ctype.h malloc.h netinet/ip.h stdbool.h stddef.h varargs.h \
|
||||
],[],[],[[
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
]]
|
||||
)
|
||||
# Optional header files
|
||||
AC_CHECK_HEADERS_ONCE([ \
|
||||
arpa/inet.h inttypes.h malloc.h netinet/in_systm.h netinet/ip.h \
|
||||
stdbool.h stddef.h stdint.h varargs.h \
|
||||
])
|
||||
|
||||
# -- Datatypes --
|
||||
|
||||
@@ -139,33 +145,50 @@ AC_TRY_COMPILE([
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
|
||||
AC_TYPE_PID_T
|
||||
AC_TYPE_SIGNAL
|
||||
AC_TYPE_SIZE_T
|
||||
AC_TYPE_SSIZE_T
|
||||
AC_TYPE_UID_T
|
||||
AC_TYPE_UINT16_T
|
||||
AC_TYPE_UINT32_T
|
||||
AC_TYPE_UINT8_T
|
||||
|
||||
AC_CHECK_MEMBER([struct sockaddr_in.sin_len], AC_DEFINE(HAVE_sockaddr_in_len),,
|
||||
[#include <arpa/inet.h>])
|
||||
|
||||
# -- Libraries --
|
||||
|
||||
# A/UX needs this.
|
||||
AC_CHECK_LIB(UTIL,memmove)
|
||||
# needed on solaris. GNU libc also has a libnsl, but we do not need it.
|
||||
AC_SEARCH_LIBS(gethostbyname,nsl)
|
||||
AC_CHECK_LIB(socket,bind)
|
||||
# memmove: A/UX libUTIL
|
||||
AC_SEARCH_LIBS([memmove], [UTIL], [], [
|
||||
AC_MSG_ERROR([unable to find the memmove() function])
|
||||
])
|
||||
# gethostbyname: Solaris libnsl
|
||||
AC_SEARCH_LIBS([gethostbyname], [bind nsl network], [], [
|
||||
AC_MSG_ERROR([unable to find the gethostbyname() function])
|
||||
])
|
||||
# bind: SVR4 libsocket
|
||||
AC_SEARCH_LIBS([bind], [socket network], [], [
|
||||
AC_MSG_ERROR([unable to find the bind() function])
|
||||
])
|
||||
|
||||
# -- Functions --
|
||||
|
||||
AC_FUNC_FORK
|
||||
AC_FUNC_STRFTIME
|
||||
|
||||
# Required functions
|
||||
AC_CHECK_FUNCS([ \
|
||||
bind gethostbyaddr gethostbyname gethostname inet_ntoa \
|
||||
setsid setsockopt socket strcasecmp waitpid],,
|
||||
alarm dup2 endpwent gethostbyaddr gethostbyname gethostname \
|
||||
gettimeofday inet_ntoa memmove memset setsid socket strcasecmp \
|
||||
strchr strcspn strerror strncasecmp strrchr strspn strstr \
|
||||
],,
|
||||
AC_MSG_ERROR([required function missing!]))
|
||||
|
||||
AC_CHECK_FUNCS([ \
|
||||
gai_strerror getaddrinfo getnameinfo inet_aton sigaction \
|
||||
sigprocmask snprintf vsnprintf strdup strlcpy strlcat strtok_r])
|
||||
# Optional functions
|
||||
AC_CHECK_FUNCS_ONCE([ \
|
||||
gai_strerror getaddrinfo getnameinfo inet_aton sigaction sigprocmask \
|
||||
snprintf vsnprintf strdup strlcpy strlcat strtok_r waitpid])
|
||||
|
||||
# -- Configuration options --
|
||||
|
||||
@@ -173,22 +196,20 @@ AC_CHECK_FUNCS([ \
|
||||
|
||||
x_syslog_on=no
|
||||
AC_ARG_WITH(syslog,
|
||||
[ --without-syslog disable syslog (autodetected by default)],
|
||||
AS_HELP_STRING([--without-syslog],
|
||||
[disable syslog (autodetected by default)]),
|
||||
[ 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_LIB(be, syslog)
|
||||
AC_CHECK_FUNCS(syslog, x_syslog_on=yes,
|
||||
AC_SEARCH_LIBS([syslog], [be], [x_syslog_on=yes], [
|
||||
AC_MSG_ERROR([Can't enable syslog!])
|
||||
)
|
||||
])
|
||||
fi
|
||||
],
|
||||
[
|
||||
AC_CHECK_LIB(be, syslog)
|
||||
AC_CHECK_FUNCS(syslog, x_syslog_on=yes)
|
||||
[ AC_SEARCH_LIBS([syslog], [be], [x_syslog_on=yes])
|
||||
]
|
||||
)
|
||||
if test "$x_syslog_on" = "yes"; then
|
||||
@@ -200,7 +221,8 @@ fi
|
||||
|
||||
x_zlib_on=no
|
||||
AC_ARG_WITH(zlib,
|
||||
[ --without-zlib disable zlib compression (autodetected by default)],
|
||||
AS_HELP_STRING([--without-zlib],
|
||||
[disable zlib compression (autodetected by default)]),
|
||||
[ if test "$withval" != "no"; then
|
||||
if test "$withval" != "yes"; then
|
||||
CFLAGS="-I$withval/include $CFLAGS"
|
||||
@@ -227,7 +249,8 @@ fi
|
||||
x_io_backend=none
|
||||
|
||||
AC_ARG_WITH(select,
|
||||
[ --without-select disable select IO support (autodetected by default)],
|
||||
AS_HELP_STRING([--without-select],
|
||||
[disable select IO support (autodetected by default)]),
|
||||
[ if test "$withval" != "no"; then
|
||||
if test "$withval" != "yes"; then
|
||||
CFLAGS="-I$withval/include $CFLAGS"
|
||||
@@ -245,7 +268,8 @@ AC_ARG_WITH(select,
|
||||
)
|
||||
|
||||
AC_ARG_WITH(poll,
|
||||
[ --without-poll disable poll support (autodetected by default)],
|
||||
AS_HELP_STRING([--without-poll],
|
||||
[disable poll support (autodetected by default)]),
|
||||
[ if test "$withval" != "no"; then
|
||||
if test "$withval" != "yes"; then
|
||||
CFLAGS="-I$withval/include $CFLAGS"
|
||||
@@ -271,7 +295,8 @@ AC_ARG_WITH(poll,
|
||||
)
|
||||
|
||||
AC_ARG_WITH(devpoll,
|
||||
[ --without-devpoll disable /dev/poll IO support (autodetected by default)],
|
||||
AS_HELP_STRING([--without-devpoll],
|
||||
[disable /dev/poll IO support (autodetected by default)]),
|
||||
[ if test "$withval" != "no"; then
|
||||
if test "$withval" != "yes"; then
|
||||
CFLAGS="-I$withval/include $CFLAGS"
|
||||
@@ -288,7 +313,8 @@ AC_ARG_WITH(devpoll,
|
||||
)
|
||||
|
||||
AC_ARG_WITH(epoll,
|
||||
[ --without-epoll disable epoll IO support (autodetected by default)],
|
||||
AS_HELP_STRING([--without-epoll],
|
||||
[disable epoll IO support (autodetected by default)]),
|
||||
[ if test "$withval" != "no"; then
|
||||
if test "$withval" != "yes"; then
|
||||
CFLAGS="-I$withval/include $CFLAGS"
|
||||
@@ -306,7 +332,8 @@ AC_ARG_WITH(epoll,
|
||||
)
|
||||
|
||||
AC_ARG_WITH(kqueue,
|
||||
[ --without-kqueue disable kqueue IO support (autodetected by default)],
|
||||
AS_HELP_STRING([--without-kqueue],
|
||||
[disable kqueue IO support (autodetected by default)]),
|
||||
[ if test "$withval" != "no"; then
|
||||
if test "$withval" != "yes"; then
|
||||
CFLAGS="-I$withval/include $CFLAGS"
|
||||
@@ -346,7 +373,8 @@ fi
|
||||
# use SSL?
|
||||
|
||||
AC_ARG_WITH(openssl,
|
||||
[ --with-openssl enable SSL support using OpenSSL],
|
||||
AS_HELP_STRING([--with-openssl],
|
||||
[enable SSL support using OpenSSL]),
|
||||
[ if test "$withval" != "no"; then
|
||||
if test "$withval" != "yes"; then
|
||||
CFLAGS="-I$withval/include $CFLAGS"
|
||||
@@ -363,7 +391,8 @@ AC_ARG_WITH(openssl,
|
||||
)
|
||||
|
||||
AC_ARG_WITH(gnutls,
|
||||
[ --with-gnutls enable SSL support using gnutls],
|
||||
AS_HELP_STRING([--with-gnutls],
|
||||
[enable SSL support using gnutls]),
|
||||
[ if test "$withval" != "no"; then
|
||||
if test "$withval" != "yes"; then
|
||||
CFLAGS="-I$withval/include $CFLAGS"
|
||||
@@ -393,7 +422,8 @@ fi
|
||||
|
||||
x_tcpwrap_on=no
|
||||
AC_ARG_WITH(tcp-wrappers,
|
||||
[ --with-tcp-wrappers enable TCP wrappers support],
|
||||
AS_HELP_STRING([--with-tcp-wrappers],
|
||||
[enable TCP wrappers support]),
|
||||
[ if test "$withval" != "no"; then
|
||||
if test "$withval" != "yes"; then
|
||||
CFLAGS="-I$withval/include $CFLAGS"
|
||||
@@ -424,7 +454,8 @@ int deny_severity = 0;
|
||||
|
||||
x_identauth_on=no
|
||||
AC_ARG_WITH(ident,
|
||||
[ --with-ident enable "IDENT" ("AUTH") protocol support],
|
||||
AS_HELP_STRING([--with-ident],
|
||||
[enable "IDENT" ("AUTH") protocol support]),
|
||||
[ if test "$withval" != "no"; then
|
||||
if test "$withval" != "yes"; then
|
||||
CFLAGS="-I$withval/include $CFLAGS"
|
||||
@@ -447,7 +478,8 @@ fi
|
||||
|
||||
x_pam_on=no
|
||||
AC_ARG_WITH(pam,
|
||||
[ --with-pam enable user authentication using PAM],
|
||||
AS_HELP_STRING([--with-pam],
|
||||
[enable user authentication using PAM]),
|
||||
[ if test "$withval" != "no"; then
|
||||
if test "$withval" != "yes"; then
|
||||
CFLAGS="-I$withval/include $CFLAGS"
|
||||
@@ -474,17 +506,42 @@ fi
|
||||
|
||||
x_ircplus_on=yes
|
||||
AC_ARG_ENABLE(ircplus,
|
||||
[ --disable-ircplus disable IRC+ protocol],
|
||||
AS_HELP_STRING([--disable-ircplus],
|
||||
[disable IRC+ protocol]),
|
||||
if test "$enableval" = "no"; then x_ircplus_on=no; fi
|
||||
)
|
||||
if test "$x_ircplus_on" = "yes"; then
|
||||
AC_DEFINE(IRCPLUS, 1)
|
||||
|
||||
# Compile in iconv support?
|
||||
# We only check for it when IRC+ is enabled, because the IRC+ command
|
||||
# CHARCONV is the only function depending on it.
|
||||
x_iconv_on=no
|
||||
AC_ARG_WITH(iconv,
|
||||
[ --with-iconv enable character conversation using libiconv],
|
||||
[ 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_LIB(iconv, iconv_open)
|
||||
AC_CHECK_FUNCS(iconv_open, x_iconv_on=yes,
|
||||
AC_MSG_ERROR([Can't enable libiconv support!])
|
||||
)
|
||||
fi
|
||||
]
|
||||
)
|
||||
if test "$x_iconv_on" = "yes"; then
|
||||
AC_DEFINE(ICONV, 1)
|
||||
fi
|
||||
fi
|
||||
|
||||
# enable support for IPv6?
|
||||
x_ipv6_on=no
|
||||
AC_ARG_ENABLE(ipv6,
|
||||
[ --enable-ipv6 enable IPv6 protocol support],
|
||||
AS_HELP_STRING([--enable-ipv6],
|
||||
[enable IPv6 protocol support]),
|
||||
if test "$enableval" = "yes"; then x_ipv6_on=yes; fi
|
||||
)
|
||||
if test "$x_ipv6_on" = "yes"; then
|
||||
@@ -500,7 +557,8 @@ fi
|
||||
|
||||
x_sniffer_on=no; x_debug_on=no
|
||||
AC_ARG_ENABLE(sniffer,
|
||||
[ --enable-sniffer enable IRC traffic sniffer (enables debug mode)],
|
||||
AS_HELP_STRING([--enable-sniffer],
|
||||
[enable IRC traffic sniffer (enables debug mode)]),
|
||||
if test "$enableval" = "yes"; then
|
||||
AC_DEFINE(SNIFFER, 1)
|
||||
x_sniffer_on=yes; x_debug_on=yes
|
||||
@@ -510,7 +568,8 @@ AC_ARG_ENABLE(sniffer,
|
||||
# enable additional debugging code?
|
||||
|
||||
AC_ARG_ENABLE(debug,
|
||||
[ --enable-debug show additional debug output],
|
||||
AS_HELP_STRING([--enable-debug],
|
||||
[show additional debug output]),
|
||||
if test "$enableval" = "yes"; then x_debug_on=yes; fi
|
||||
)
|
||||
if test "$x_debug_on" = "yes"; then
|
||||
@@ -523,7 +582,8 @@ fi
|
||||
|
||||
x_strict_rfc_on=no
|
||||
AC_ARG_ENABLE(strict-rfc,
|
||||
[ --enable-strict-rfc strict RFC conformance -- may break clients!],
|
||||
AS_HELP_STRING([--enable-strict-rfc],
|
||||
[strict RFC conformance -- may break clients!]),
|
||||
if test "$enableval" = "yes"; then
|
||||
AC_DEFINE(STRICT_RFC, 1)
|
||||
x_strict_rfc_on=yes
|
||||
@@ -532,9 +592,9 @@ AC_ARG_ENABLE(strict-rfc,
|
||||
|
||||
# -- Definitions --
|
||||
|
||||
AC_DEFINE_UNQUOTED(TARGET_CPU, "$target_cpu" )
|
||||
AC_DEFINE_UNQUOTED(TARGET_VENDOR, "$target_vendor" )
|
||||
AC_DEFINE_UNQUOTED(TARGET_OS, "$target_os" )
|
||||
AC_DEFINE_UNQUOTED(HOST_CPU, "$host_cpu" )
|
||||
AC_DEFINE_UNQUOTED(HOST_VENDOR, "$host_vendor" )
|
||||
AC_DEFINE_UNQUOTED(HOST_OS, "$host_os" )
|
||||
|
||||
# Add additional CFLAGS, eventually specified on the command line, but after
|
||||
# running this configure script. Useful for "-Werror" for example.
|
||||
@@ -542,25 +602,26 @@ test -n "$CFLAGS_END" && CFLAGS="$CFLAGS $CFLAGS_END"
|
||||
|
||||
# -- Generate files --
|
||||
|
||||
AC_OUTPUT([ \
|
||||
AC_CONFIG_FILES([ \
|
||||
Makefile \
|
||||
doc/Makefile \
|
||||
doc/src/Makefile \
|
||||
src/Makefile \
|
||||
src/portab/Makefile \
|
||||
src/ipaddr/Makefile \
|
||||
src/tool/Makefile \
|
||||
src/ngircd/Makefile \
|
||||
src/testsuite/Makefile \
|
||||
man/Makefile \
|
||||
contrib/Makefile \
|
||||
contrib/Anope/Makefile \
|
||||
contrib/Debian/Makefile \
|
||||
contrib/MacOSX/Makefile \
|
||||
contrib/MacOSX/ngIRCd.xcodeproj/Makefile \
|
||||
contrib/MacOSX/ngIRCd.pmdoc/Makefile \
|
||||
contrib/MacOSX/ngIRCd.xcodeproj/Makefile \
|
||||
contrib/Makefile \
|
||||
doc/Makefile \
|
||||
doc/src/Makefile \
|
||||
man/Makefile \
|
||||
src/ipaddr/Makefile \
|
||||
src/Makefile \
|
||||
src/ngircd/Makefile \
|
||||
src/portab/Makefile \
|
||||
src/testsuite/Makefile \
|
||||
src/tool/Makefile \
|
||||
])
|
||||
|
||||
AC_OUTPUT
|
||||
|
||||
type dpkg >/dev/null 2>&1
|
||||
if test $? -eq 0; then
|
||||
# Generate debian/ link if the dpkg command exists
|
||||
@@ -582,8 +643,7 @@ C=`eval echo ${sysconfdir}` ; C=`eval echo ${C}`
|
||||
M=`eval echo ${mandir}` ; M=`eval echo ${M}`
|
||||
D=`eval echo ${docdir}` ; D=`eval echo ${D}`
|
||||
|
||||
echo " Target: ${target}"
|
||||
test "$target" != "$host" && echo " Host: ${host}"
|
||||
echo " Host: ${host}"
|
||||
echo " Compiler: ${CC}"
|
||||
test -n "$CFLAGS" && echo " Compiler flags: ${CFLAGS}"
|
||||
test -n "$CPPFLAGS" && echo " Preprocessor flags: ${CPPFLAGS}"
|
||||
@@ -646,6 +706,18 @@ test "$x_pam_on" = "yes" \
|
||||
echo $ECHO_N " SSL support: $ECHO_C"
|
||||
echo "$x_ssl_lib"
|
||||
|
||||
echo $ECHO_N " libiconv support: $ECHO_C"
|
||||
echo "$x_iconv_on"
|
||||
|
||||
echo
|
||||
|
||||
define(_automake_regex_,[[^AUTOMAKE_OPTIONS = [a-z .\-]*/portab/ansi2knr]])
|
||||
if ! grep "_automake_regex_" src/ngircd/Makefile.am >/dev/null 2>&1; then
|
||||
echo "WARNING:"
|
||||
echo "This GNU automake generated build system does not support \"de-ANSI-fication\","
|
||||
echo "therefore don't use it to generate \"official\" distribution archives!"
|
||||
echo "(Most probably you want to use GNU automake 1.11.x for this purpose ...)"
|
||||
echo
|
||||
fi
|
||||
|
||||
# -eof-
|
@@ -1,496 +0,0 @@
|
||||
From bc5023fdba8091ab7eee29fe0deeca6843159743 Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Barton <alex@barton.de>
|
||||
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<User *>::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<Anope::string>&) { return false; }
|
||||
+
|
||||
+ /*
|
||||
+ * Received: :dev.anope.de MODE #anope +b *!*@*aol*
|
||||
+ */
|
||||
+ bool OnMode(const Anope::string &source, const std::vector<Anope::string> ¶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] = <unknown>
|
||||
+ params[2] = username
|
||||
+ params[3] = host
|
||||
+ params[4] = <unknown>
|
||||
+ params[5] = modes
|
||||
+ params[6] = info
|
||||
+ */
|
||||
+ bool OnNick(const Anope::string &source, const std::vector<Anope::string> ¶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<Anope::string> ¶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<unsigned>(params[1]) : 0, params[3], params[2]);
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ bool OnTopic(const Anope::string &source, const std::vector<Anope::string> ¶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 <channelname>\7<umode>
|
||||
+ */
|
||||
+ bool OnJoin (const Anope::string &source, const std::vector<Anope::string> ¶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 <chan> +<modes>
|
||||
+ * CHANINFO <chan> +<modes> :<topic>
|
||||
+ * CHANINFO <chan> +<modes> <key> <limit> :<topic>
|
||||
+ */
|
||||
+bool event_chaninfo(const Anope::string &source, const std::vector<Anope::string> ¶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<Anope::string> ¶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<ChannelMode *> 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<ChannelMode *>::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<Anope::string> ¶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<Anope::string> ¶ms)
|
||||
+{
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
+bool event_005(const Anope::string &source, const std::vector<Anope::string> ¶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<unsigned>(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<Anope::string> ¶ms)
|
||||
+{
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
+bool event_376(const Anope::string &source, const std::vector<Anope::string> ¶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
|
||||
|
@@ -1,60 +0,0 @@
|
||||
From 1ea1dd2095e63cef34edbebb729edc687f410a96 Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Barton <alex@barton.de>
|
||||
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::vector<Anope::string
|
||||
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)
|
||||
@@ -307,7 +307,7 @@ bool event_njoin(const Anope::string &source, const std::vector<Anope::string> &
|
||||
c = new Channel(params[0], Anope::CurTime);
|
||||
c->SetFlag(CH_SYNCING);
|
||||
}
|
||||
-
|
||||
+
|
||||
while (sep.GetToken(buf))
|
||||
{
|
||||
std::list<ChannelMode *> Status;
|
||||
@@ -415,9 +415,9 @@ bool event_376(const Anope::string &source, const std::vector<Anope::string> &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
|
||||
|
@@ -1,128 +0,0 @@
|
||||
From d8eddbeaadc7d161865b5342d59748b80266533c Mon Sep 17 00:00:00 2001
|
||||
From: DukePyrolator <DukePyrolator@anope.org>
|
||||
Date: Mon, 22 Aug 2011 14:53:37 +0200
|
||||
Subject: [PATCH 03/16] Update ngIRCd protocol module for current Anope 1.9
|
||||
GIT
|
||||
|
||||
---
|
||||
modules/protocol/ngircd.cpp | 37 ++++++++++++++++++-------------------
|
||||
1 files changed, 18 insertions(+), 19 deletions(-)
|
||||
|
||||
diff --git a/modules/protocol/ngircd.cpp b/modules/protocol/ngircd.cpp
|
||||
index e546d05..790b8f4 100644
|
||||
--- a/modules/protocol/ngircd.cpp
|
||||
+++ b/modules/protocol/ngircd.cpp
|
||||
@@ -11,6 +11,8 @@
|
||||
|
||||
#include "services.h"
|
||||
#include "modules.h"
|
||||
+#include "nickserv.h"
|
||||
+#include "oper.h"
|
||||
|
||||
IRCDVar myIrcd[] = {
|
||||
{"ngIRCd", /* ircd name */
|
||||
@@ -45,14 +47,7 @@ class ngIRCdProto : public IRCDProto
|
||||
{
|
||||
void SendAkill(User *u, const XLine *x)
|
||||
{
|
||||
- if (SGLine && u == NULL)
|
||||
- for (Anope::insensitive_map<User *>::iterator it = UserListByNick.begin(); it != UserListByNick.end();)
|
||||
- {
|
||||
- u = it->second;
|
||||
- ++it;
|
||||
- if (SGLine->Check(u) != NULL)
|
||||
- break;
|
||||
- }
|
||||
+ // TODO: ADD SOME CODE
|
||||
}
|
||||
|
||||
void SendAkillDel(const XLine*) { }
|
||||
@@ -62,13 +57,16 @@ class ngIRCdProto : public IRCDProto
|
||||
send_cmd(source ? source->nick : Config->ServerName, "WALLOPS :%s", buf.c_str());
|
||||
}
|
||||
|
||||
- void SendJoin(BotInfo *user, Channel *c, const ChannelStatus *status)
|
||||
+ void SendJoin(User *user, Channel *c, const ChannelStatus *status)
|
||||
{
|
||||
send_cmd(user->nick, "JOIN %s", c->name.c_str());
|
||||
if (status)
|
||||
+ {
|
||||
+ BotInfo *setter = findbot(user->nick);
|
||||
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);
|
||||
+ c->SetMode(setter, ModeManager::ChannelModes[i], user->nick, false);
|
||||
+ }
|
||||
}
|
||||
|
||||
void SendSVSKillInternal(const BotInfo *source, const User *user, const Anope::string &buf)
|
||||
@@ -84,7 +82,7 @@ class ngIRCdProto : public IRCDProto
|
||||
|
||||
void SendConnect()
|
||||
{
|
||||
- send_cmd("", "PASS %s 0210-IRC+ Anope|%s:CLHSo P", uplink_server->password.c_str(), Anope::VersionShort().c_str());
|
||||
+ send_cmd("", "PASS %s 0210-IRC+ Anope|%s:CLHSo P", Config->Uplinks[CurrentUplink]->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 */
|
||||
@@ -92,9 +90,11 @@ class ngIRCdProto : public IRCDProto
|
||||
}
|
||||
|
||||
// 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)
|
||||
+ void SendClientIntroduction(const User *u)
|
||||
{
|
||||
- EnforceQlinedNick(u->nick, "");
|
||||
+ Anope::string modes = "+" + u->GetModes();
|
||||
+ XLine x(u->nick, "Reserved for services");
|
||||
+ ircdproto->SendSQLine(NULL, &x);
|
||||
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());
|
||||
}
|
||||
|
||||
@@ -126,7 +126,7 @@ class ngIRCdProto : public IRCDProto
|
||||
|
||||
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());
|
||||
+ send_cmd(source->nick, "NOTICE @%s :%s", dest->name.c_str(), buf.c_str());
|
||||
}
|
||||
|
||||
/* INVITE */
|
||||
@@ -196,8 +196,8 @@ class ngIRCdIRCdMessage : public IRCdMessage
|
||||
{
|
||||
// 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);
|
||||
+ if (user && nickserv)
|
||||
+ nickserv->Validate(user);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -433,7 +433,7 @@ class ProtongIRCd : public Module
|
||||
ModeManager::AddUserMode(new UserMode(UMODE_CLOAK, 'x'));
|
||||
|
||||
/* b/e/I */
|
||||
- ModeManager::AddChannelMode(new ChannelModeBan(CMODE_BAN, 'b'));
|
||||
+ ModeManager::AddChannelMode(new ChannelModeList(CMODE_BAN, 'b'));
|
||||
ModeManager::AddChannelMode(new ChannelModeList(CMODE_INVITEOVERRIDE, 'I'));
|
||||
|
||||
/* v/h/o/a/q */
|
||||
@@ -454,13 +454,12 @@ class ProtongIRCd : public Module
|
||||
}
|
||||
|
||||
public:
|
||||
- ProtongIRCd(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator),
|
||||
+ ProtongIRCd(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL),
|
||||
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);
|
||||
|
||||
--
|
||||
1.7.8.3
|
||||
|
@@ -1,93 +0,0 @@
|
||||
From 88b2b14a76b8ee053b1f6ea64139350260590043 Mon Sep 17 00:00:00 2001
|
||||
From: DukePyrolator <DukePyrolator@anope.org>
|
||||
Date: Mon, 22 Aug 2011 14:55:07 +0200
|
||||
Subject: [PATCH 04/16] ngircd: Do PING-PONG on server burst to "sync servers"
|
||||
|
||||
Imagine we had three servers, A, B & C linked like so: A<->B<->C:
|
||||
|
||||
If Anope is linked to A and B splits from A and then reconnects B
|
||||
introduces itself, introduces C, sends EOS for C, introduces B's clients
|
||||
introduces C's clients, sends EOS for B. This causes all of C's clients
|
||||
to be introduced with their server "not syncing".
|
||||
|
||||
We now send a PING immediately when receiving a new server and then
|
||||
finish sync once we get a pong back from that server.
|
||||
---
|
||||
modules/protocol/ngircd.cpp | 28 ++++++++++++++++++++++++++--
|
||||
1 files changed, 26 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/modules/protocol/ngircd.cpp b/modules/protocol/ngircd.cpp
|
||||
index 790b8f4..89aecfd 100644
|
||||
--- a/modules/protocol/ngircd.cpp
|
||||
+++ b/modules/protocol/ngircd.cpp
|
||||
@@ -108,11 +108,13 @@ class ngIRCdProto : public IRCDProto
|
||||
|
||||
void SendModeInternal(const BotInfo *bi, const Channel *dest, const Anope::string &buf)
|
||||
{
|
||||
+Log(LOG_DEBUG) << "SendModeInternal 1";
|
||||
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)
|
||||
{
|
||||
+Log(LOG_DEBUG) << "SendModeInternal 2";
|
||||
send_cmd(bi ? bi->nick : Config->ServerName, "MODE %s %s", u->nick.c_str(), buf.c_str());
|
||||
}
|
||||
|
||||
@@ -212,6 +214,8 @@ class ngIRCdIRCdMessage : public IRCdMessage
|
||||
do_server("", params[0], 0, params[2], params[1]);
|
||||
else
|
||||
do_server(source, params[0], params[1].is_pos_number_only() ? convertTo<unsigned>(params[1]) : 0, params[3], params[2]);
|
||||
+
|
||||
+ ircdproto->SendPing(Config->ServerName, params[0]);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -253,6 +257,25 @@ class ngIRCdIRCdMessage : public IRCdMessage
|
||||
}
|
||||
};
|
||||
|
||||
+/** This is here because:
|
||||
+ *
|
||||
+ * If we had three servers, A, B & C linked like so: A<->B<->C
|
||||
+ * If Anope is linked to A and B splits from A and then reconnects
|
||||
+ * B introduces itself, introduces C, sends EOS for C, introduces Bs clients
|
||||
+ * introduces Cs clients, sends EOS for B. This causes all of Cs clients to be introduced
|
||||
+ * with their server "not syncing". We now send a PING immediately when receiving a new server
|
||||
+ * and then finish sync once we get a pong back from that server.
|
||||
+ */
|
||||
+bool event_pong(const Anope::string &source, const std::vector<Anope::string> ¶ms)
|
||||
+{
|
||||
+ Server *s = Server::Find(source);
|
||||
+ if (s && !s->IsSynced())
|
||||
+ s->Sync(false);
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+
|
||||
/*
|
||||
* CHANINFO <chan> +<modes>
|
||||
* CHANINFO <chan> +<modes> :<topic>
|
||||
@@ -416,7 +439,7 @@ bool event_376(const Anope::string &source, const std::vector<Anope::string> &pa
|
||||
class ProtongIRCd : public Module
|
||||
{
|
||||
Message message_kick, message_pass, message_njoin, message_chaninfo, message_005,
|
||||
- message_442, message_376;
|
||||
+ message_442, message_376, message_pong;
|
||||
|
||||
ngIRCdProto ircd_proto;
|
||||
ngIRCdIRCdMessage ircd_message;
|
||||
@@ -457,7 +480,8 @@ class ProtongIRCd : public Module
|
||||
ProtongIRCd(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL),
|
||||
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)
|
||||
+ message_005("005", event_005), message_442("442", event_442), message_376("376", event_376),
|
||||
+ message_pong("PONG", event_pong)
|
||||
{
|
||||
this->SetAuthor("Anope");
|
||||
|
||||
--
|
||||
1.7.8.3
|
||||
|
@@ -1,29 +0,0 @@
|
||||
From 0d83f8f9ca0de651d664eca6f467f36df0417f7d Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Barton <alex@barton.de>
|
||||
Date: Mon, 22 Aug 2011 14:59:49 +0200
|
||||
Subject: [PATCH 05/16] ngircd: always prefix modes in CHANINFO with "+"
|
||||
|
||||
---
|
||||
modules/protocol/ngircd.cpp | 6 ++----
|
||||
1 files changed, 2 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/modules/protocol/ngircd.cpp b/modules/protocol/ngircd.cpp
|
||||
index 89aecfd..3e5beb3 100644
|
||||
--- a/modules/protocol/ngircd.cpp
|
||||
+++ b/modules/protocol/ngircd.cpp
|
||||
@@ -139,10 +139,8 @@ Log(LOG_DEBUG) << "SendModeInternal 2";
|
||||
|
||||
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());
|
||||
+ Anope::string modes = c->GetModes(true, true);
|
||||
+ send_cmd(Config->ServerName, "CHANINFO %s +%s", c->name.c_str(), modes.c_str());
|
||||
}
|
||||
void SendTopic(BotInfo *bi, Channel *c)
|
||||
{
|
||||
--
|
||||
1.7.8.3
|
||||
|
@@ -1,47 +0,0 @@
|
||||
From 1914a36b83b1fc6b4678ef261a1a06eefab9a0ca Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Barton <alex@barton.de>
|
||||
Date: Fri, 26 Aug 2011 17:51:37 +0200
|
||||
Subject: [PATCH 06/16] ngircd: support user mode "R" and channel mode "R"
|
||||
|
||||
---
|
||||
modules/protocol/ngircd.cpp | 7 ++++---
|
||||
1 files changed, 4 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/modules/protocol/ngircd.cpp b/modules/protocol/ngircd.cpp
|
||||
index 3e5beb3..7f4186e 100644
|
||||
--- a/modules/protocol/ngircd.cpp
|
||||
+++ b/modules/protocol/ngircd.cpp
|
||||
@@ -449,26 +449,27 @@ class ProtongIRCd : public Module
|
||||
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_REGISTERED, '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 */
|
||||
+ /* Add modes for ban and invite lists */
|
||||
ModeManager::AddChannelMode(new ChannelModeList(CMODE_BAN, 'b'));
|
||||
ModeManager::AddChannelMode(new ChannelModeList(CMODE_INVITEOVERRIDE, 'I'));
|
||||
|
||||
- /* v/h/o/a/q */
|
||||
+ /* Add channel user modes */
|
||||
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_REGISTEREDONLY, 'R'));
|
||||
ModeManager::AddChannelMode(new ChannelMode(CMODE_SECRET, 's'));
|
||||
ModeManager::AddChannelMode(new ChannelMode(CMODE_TOPIC, 't'));
|
||||
ModeManager::AddChannelMode(new ChannelMode(CMODE_SSL, 'z'));
|
||||
--
|
||||
1.7.8.3
|
||||
|
@@ -1,96 +0,0 @@
|
||||
From 4c9300ede35310ee5642f34e5ac227bd96fc7384 Mon Sep 17 00:00:00 2001
|
||||
From: DukePyrolator <DukePyrolator@anope.org>
|
||||
Date: Sun, 4 Sep 2011 15:08:55 +0200
|
||||
Subject: [PATCH 07/16] ngircd: Fix handling of JOIN commands
|
||||
|
||||
---
|
||||
modules/protocol/ngircd.cpp | 60 +++++++++++++++++++++++++++++++++++++++---
|
||||
1 files changed, 55 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/modules/protocol/ngircd.cpp b/modules/protocol/ngircd.cpp
|
||||
index 7f4186e..3024fdd 100644
|
||||
--- a/modules/protocol/ngircd.cpp
|
||||
+++ b/modules/protocol/ngircd.cpp
|
||||
@@ -240,16 +240,58 @@ class ngIRCdIRCdMessage : public IRCdMessage
|
||||
{
|
||||
if (!params.empty())
|
||||
{
|
||||
+ Anope::string channel, mode;
|
||||
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, "");
|
||||
+ channel = params[0].substr(0, pos);
|
||||
+ mode = '+' + params[0].substr(pos+1, params[0].length()) + " " + source;
|
||||
}
|
||||
else
|
||||
- do_join(source, params[0], "");
|
||||
+ channel = params[0];
|
||||
+
|
||||
+ Channel *c = findchan(channel);
|
||||
+
|
||||
+ if (!c)
|
||||
+ {
|
||||
+ c = new Channel(channel, Anope::CurTime);
|
||||
+ c->SetFlag(CH_SYNCING);
|
||||
+ }
|
||||
+
|
||||
+ User *u = finduser(source);
|
||||
+
|
||||
+ if (!u)
|
||||
+ {
|
||||
+ Log(LOG_DEBUG) << "JOIN for nonexistant user " << source << " on " << channel;
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ EventReturn MOD_RESULT;
|
||||
+ FOREACH_RESULT(I_OnPreJoinChannel, OnPreJoinChannel(u, c));
|
||||
+
|
||||
+ /* Add the user to the channel */
|
||||
+ c->JoinUser(u);
|
||||
+
|
||||
+ /* set the usermodes to the channel */
|
||||
+ do_cmode(source, channel, mode, "");
|
||||
+
|
||||
+ /* 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))
|
||||
+ return false;
|
||||
+
|
||||
+ FOREACH_MOD(I_OnJoinChannel, OnJoinChannel(u, c));
|
||||
+
|
||||
+ if (c->HasFlag(CH_SYNCING))
|
||||
+ {
|
||||
+ c->UnsetFlag(CH_SYNCING);
|
||||
+ c->Sync();
|
||||
+ }
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -491,7 +533,15 @@ class ProtongIRCd : public Module
|
||||
pmodule_ircd_message(&this->ircd_message);
|
||||
|
||||
this->AddModes();
|
||||
+
|
||||
+ ModuleManager::Attach(I_OnUserNickChange, this);
|
||||
}
|
||||
+
|
||||
+ void OnUserNickChange(User *u, const Anope::string &)
|
||||
+ {
|
||||
+ u->RemoveModeInternal(ModeManager::FindUserModeByName(UMODE_REGISTERED));
|
||||
+ }
|
||||
+
|
||||
};
|
||||
|
||||
MODULE_INIT(ProtongIRCd)
|
||||
--
|
||||
1.7.8.3
|
||||
|
@@ -1,38 +0,0 @@
|
||||
From d363ebd841ea7e1db3c62730023759d69520e0d8 Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Barton <alex@barton.de>
|
||||
Date: Tue, 27 Sep 2011 15:08:09 +0200
|
||||
Subject: [PATCH 08/16] ngircd: Allow setting modes by clients on burst
|
||||
|
||||
This change is required by commit 43201ead9575a for the ngIRCd protocol
|
||||
module as well.
|
||||
---
|
||||
modules/protocol/ngircd.cpp | 7 +++++--
|
||||
1 files changed, 5 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/modules/protocol/ngircd.cpp b/modules/protocol/ngircd.cpp
|
||||
index 3024fdd..2774168 100644
|
||||
--- a/modules/protocol/ngircd.cpp
|
||||
+++ b/modules/protocol/ngircd.cpp
|
||||
@@ -57,14 +57,17 @@ class ngIRCdProto : public IRCDProto
|
||||
send_cmd(source ? source->nick : Config->ServerName, "WALLOPS :%s", buf.c_str());
|
||||
}
|
||||
|
||||
- void SendJoin(User *user, Channel *c, const ChannelStatus *status)
|
||||
+ void SendJoin(User *user, Channel *c, ChannelStatus *status)
|
||||
{
|
||||
send_cmd(user->nick, "JOIN %s", c->name.c_str());
|
||||
if (status)
|
||||
{
|
||||
+ ChannelStatus cs = *status;
|
||||
+ status->ClearFlags();
|
||||
+
|
||||
BotInfo *setter = findbot(user->nick);
|
||||
for (unsigned i = 0; i < ModeManager::ChannelModes.size(); ++i)
|
||||
- if (status->HasFlag(ModeManager::ChannelModes[i]->Name))
|
||||
+ if (cs.HasFlag(ModeManager::ChannelModes[i]->Name))
|
||||
c->SetMode(setter, ModeManager::ChannelModes[i], user->nick, false);
|
||||
}
|
||||
}
|
||||
--
|
||||
1.7.8.3
|
||||
|
@@ -1,143 +0,0 @@
|
||||
From e74a5303f2357f4a9915bb91038a2e326323db3c Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Barton <alex@barton.de>
|
||||
Date: Fri, 25 Nov 2011 19:16:37 +0100
|
||||
Subject: [PATCH 09/16] ngircd: Update protocol module for current Anope 1.9
|
||||
GIT
|
||||
|
||||
This changes are rquired by:
|
||||
|
||||
- b14f5ea88: Fixed accidentally clearing botmodes when joins are sent
|
||||
- cef3eb78d: Remove send_cmd and replace it with a stringstream
|
||||
- ddc3c2f38: Added options:nonicknameownership config option
|
||||
---
|
||||
modules/protocol/ngircd.cpp | 54 ++++++++++++++++++++++--------------------
|
||||
1 files changed, 28 insertions(+), 26 deletions(-)
|
||||
|
||||
diff --git a/modules/protocol/ngircd.cpp b/modules/protocol/ngircd.cpp
|
||||
index 2774168..55cb8d7 100644
|
||||
--- a/modules/protocol/ngircd.cpp
|
||||
+++ b/modules/protocol/ngircd.cpp
|
||||
@@ -54,16 +54,22 @@ class ngIRCdProto : public IRCDProto
|
||||
|
||||
void SendGlobopsInternal(const BotInfo *source, const Anope::string &buf)
|
||||
{
|
||||
- send_cmd(source ? source->nick : Config->ServerName, "WALLOPS :%s", buf.c_str());
|
||||
+ UplinkSocket::Message(source ? source->nick : Config->ServerName) << "WALLOPS :" << buf;
|
||||
}
|
||||
|
||||
- void SendJoin(User *user, Channel *c, ChannelStatus *status)
|
||||
+ void SendJoin(User *user, Channel *c, const ChannelStatus *status)
|
||||
{
|
||||
- send_cmd(user->nick, "JOIN %s", c->name.c_str());
|
||||
+ UplinkSocket::Message(user->nick) << "JOIN " << c->name;
|
||||
if (status)
|
||||
{
|
||||
+ /* First save the channel status incase uc->Status == status */
|
||||
ChannelStatus cs = *status;
|
||||
- status->ClearFlags();
|
||||
+ /* If the user is internally on the channel with flags, kill them so that
|
||||
+ * the stacker will allow this.
|
||||
+ */
|
||||
+ UserContainer *uc = c->FindUser(user);
|
||||
+ if (uc != NULL)
|
||||
+ uc->Status->ClearFlags();
|
||||
|
||||
BotInfo *setter = findbot(user->nick);
|
||||
for (unsigned i = 0; i < ModeManager::ChannelModes.size(); ++i)
|
||||
@@ -74,18 +80,18 @@ class ngIRCdProto : public IRCDProto
|
||||
|
||||
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());
|
||||
+ UplinkSocket::Message(source ? source->nick : Config->ServerName) << "KILL " << user->nick << " :" << buf;
|
||||
}
|
||||
|
||||
/* 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());
|
||||
+ UplinkSocket::Message() << "SERVER " << server->GetName() << " " << server->GetHops() << " :" << server->GetDescription();
|
||||
}
|
||||
|
||||
void SendConnect()
|
||||
{
|
||||
- send_cmd("", "PASS %s 0210-IRC+ Anope|%s:CLHSo P", Config->Uplinks[CurrentUplink]->password.c_str(), Anope::VersionShort().c_str());
|
||||
+ UplinkSocket::Message() << "PASS " << Config->Uplinks[CurrentUplink]->password << " 0210-IRC+ Anope|" << Anope::VersionShort() << ":CLHSo P";
|
||||
/* Make myself known to myself in the serverlist */
|
||||
SendServer(Me);
|
||||
/* finish the enhanced server handshake and register the connection */
|
||||
@@ -98,56 +104,52 @@ class ngIRCdProto : public IRCDProto
|
||||
Anope::string modes = "+" + u->GetModes();
|
||||
XLine x(u->nick, "Reserved for services");
|
||||
ircdproto->SendSQLine(NULL, &x);
|
||||
- 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());
|
||||
+ UplinkSocket::Message(Config->ServerName) << "NICK " << u->nick << " 1 " << u->GetIdent() << " " << u->host << " 1 " << modes << " :" << u->realname;
|
||||
}
|
||||
|
||||
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());
|
||||
+ UplinkSocket::Message(bi->nick) << "PART " << chan->name << " :" << buf;
|
||||
else
|
||||
- send_cmd(bi->nick, "PART %s", chan->name.c_str());
|
||||
+ UplinkSocket::Message(bi->nick) << "PART " << chan->name;
|
||||
}
|
||||
|
||||
void SendModeInternal(const BotInfo *bi, const Channel *dest, const Anope::string &buf)
|
||||
{
|
||||
-Log(LOG_DEBUG) << "SendModeInternal 1";
|
||||
- send_cmd(bi ? bi->nick : Config->ServerName, "MODE %s %s", dest->name.c_str(), buf.c_str());
|
||||
+ UplinkSocket::Message(bi ? bi->nick : Config->ServerName) << "MODE " << dest->name << " " << buf;
|
||||
}
|
||||
|
||||
void SendModeInternal(const BotInfo *bi, const User *u, const Anope::string &buf)
|
||||
{
|
||||
-Log(LOG_DEBUG) << "SendModeInternal 2";
|
||||
- send_cmd(bi ? bi->nick : Config->ServerName, "MODE %s %s", u->nick.c_str(), buf.c_str());
|
||||
+ UplinkSocket::Message(bi ? bi->nick : Config->ServerName) << "MODE " << u->nick << " " << buf;
|
||||
}
|
||||
|
||||
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());
|
||||
+ UplinkSocket::Message(bi->nick) << "KICK " << chan->name << " " << user->nick << " :" << buf;
|
||||
else
|
||||
- send_cmd(bi->nick, "KICK %s %s", chan->name.c_str(), user->nick.c_str());
|
||||
+ UplinkSocket::Message(bi->nick) << "KICK " << chan->name << " " << user->nick;
|
||||
}
|
||||
|
||||
- void SendNoticeChanopsInternal(const BotInfo *source, const Channel *dest, const Anope::string &buf)
|
||||
+ void SendChannel(Channel *c)
|
||||
{
|
||||
- send_cmd(source->nick, "NOTICE @%s :%s", dest->name.c_str(), buf.c_str());
|
||||
+ Anope::string modes = c->GetModes(true, true);
|
||||
+ UplinkSocket::Message(Config->ServerName) << "CHANINFO " << c->name << " +" << modes;
|
||||
}
|
||||
|
||||
- /* INVITE */
|
||||
- void SendInvite(BotInfo *source, const Anope::string &chan, const Anope::string &nick)
|
||||
+ void SendTopic(BotInfo *bi, Channel *c)
|
||||
{
|
||||
- send_cmd(source->nick, "INVITE %s %s", nick.c_str(), chan.c_str());
|
||||
+ UplinkSocket::Message(bi->nick) << "TOPIC " << c->name << " :" << c->topic;
|
||||
}
|
||||
|
||||
- void SendChannel(Channel *c)
|
||||
+ void SendLogin(User *u)
|
||||
{
|
||||
- Anope::string modes = c->GetModes(true, true);
|
||||
- send_cmd(Config->ServerName, "CHANINFO %s +%s", c->name.c_str(), modes.c_str());
|
||||
}
|
||||
- void SendTopic(BotInfo *bi, Channel *c)
|
||||
+
|
||||
+ void SendLogout(User *u)
|
||||
{
|
||||
- send_cmd(bi->nick, "TOPIC %s :%s", c->name.c_str(), c->topic.c_str());
|
||||
}
|
||||
};
|
||||
|
||||
--
|
||||
1.7.8.3
|
||||
|
@@ -1,57 +0,0 @@
|
||||
From d2c45d7c578ec684d3b471020f631847316de196 Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Barton <alex@barton.de>
|
||||
Date: Fri, 25 Nov 2011 19:17:19 +0100
|
||||
Subject: [PATCH 10/16] ngircd: Add ~ProtongIRCd()
|
||||
|
||||
---
|
||||
modules/protocol/ngircd.cpp | 13 ++++++++-----
|
||||
1 files changed, 8 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/modules/protocol/ngircd.cpp b/modules/protocol/ngircd.cpp
|
||||
index 55cb8d7..5fd62db 100644
|
||||
--- a/modules/protocol/ngircd.cpp
|
||||
+++ b/modules/protocol/ngircd.cpp
|
||||
@@ -302,8 +302,7 @@ class ngIRCdIRCdMessage : public IRCdMessage
|
||||
}
|
||||
};
|
||||
|
||||
-/** This is here because:
|
||||
- *
|
||||
+/*
|
||||
* If we had three servers, A, B & C linked like so: A<->B<->C
|
||||
* If Anope is linked to A and B splits from A and then reconnects
|
||||
* B introduces itself, introduces C, sends EOS for C, introduces Bs clients
|
||||
@@ -319,8 +318,6 @@ bool event_pong(const Anope::string &source, const std::vector<Anope::string> &p
|
||||
return true;
|
||||
}
|
||||
|
||||
-
|
||||
-
|
||||
/*
|
||||
* CHANINFO <chan> +<modes>
|
||||
* CHANINFO <chan> +<modes> :<topic>
|
||||
@@ -480,7 +477,6 @@ bool event_376(const Anope::string &source, const std::vector<Anope::string> &pa
|
||||
return true;
|
||||
}
|
||||
|
||||
-
|
||||
class ProtongIRCd : public Module
|
||||
{
|
||||
Message message_kick, message_pass, message_njoin, message_chaninfo, message_005,
|
||||
@@ -542,6 +538,13 @@ class ProtongIRCd : public Module
|
||||
ModuleManager::Attach(I_OnUserNickChange, this);
|
||||
}
|
||||
|
||||
+ ~ProtongIRCd()
|
||||
+ {
|
||||
+ pmodule_ircd_var(NULL);
|
||||
+ pmodule_ircd_proto(NULL);
|
||||
+ pmodule_ircd_message(NULL);
|
||||
+ }
|
||||
+
|
||||
void OnUserNickChange(User *u, const Anope::string &)
|
||||
{
|
||||
u->RemoveModeInternal(ModeManager::FindUserModeByName(UMODE_REGISTERED));
|
||||
--
|
||||
1.7.8.3
|
||||
|
@@ -1,29 +0,0 @@
|
||||
From 4dc5a3d3e2fbb218461d9459bff1c0a392a75881 Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Barton <alex@barton.de>
|
||||
Date: Sat, 31 Dec 2011 16:12:52 +0100
|
||||
Subject: [PATCH 11/16] ngircd: Update protocol module for current Anope 1.9
|
||||
GIT
|
||||
|
||||
This changes are rquired by:
|
||||
|
||||
- 150831c1a: Made capab management a bit simplier
|
||||
---
|
||||
modules/protocol/ngircd.cpp | 2 +-
|
||||
1 files changed, 1 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/modules/protocol/ngircd.cpp b/modules/protocol/ngircd.cpp
|
||||
index 5fd62db..9c26ec8 100644
|
||||
--- a/modules/protocol/ngircd.cpp
|
||||
+++ b/modules/protocol/ngircd.cpp
|
||||
@@ -527,7 +527,7 @@ class ProtongIRCd : public Module
|
||||
{
|
||||
this->SetAuthor("Anope");
|
||||
|
||||
- Capab.SetFlag(CAPAB_QS);
|
||||
+ Capab.insert("QS");
|
||||
|
||||
pmodule_ircd_var(myIrcd);
|
||||
pmodule_ircd_proto(&this->ircd_proto);
|
||||
--
|
||||
1.7.8.3
|
||||
|
@@ -1,25 +0,0 @@
|
||||
From 99c18cafdee28bfb17fad5f0526b3ed5d1f5f312 Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Barton <alex@barton.de>
|
||||
Date: Sat, 31 Dec 2011 16:17:50 +0100
|
||||
Subject: [PATCH 12/16] ngircd: let Anope know that channel mode "r" is
|
||||
supported
|
||||
|
||||
---
|
||||
modules/protocol/ngircd.cpp | 1 +
|
||||
1 files changed, 1 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/modules/protocol/ngircd.cpp b/modules/protocol/ngircd.cpp
|
||||
index 9c26ec8..6155667 100644
|
||||
--- a/modules/protocol/ngircd.cpp
|
||||
+++ b/modules/protocol/ngircd.cpp
|
||||
@@ -512,6 +512,7 @@ class ProtongIRCd : public Module
|
||||
ModeManager::AddChannelMode(new ChannelMode(CMODE_MODERATED, 'm'));
|
||||
ModeManager::AddChannelMode(new ChannelMode(CMODE_NOEXTERNAL, 'n'));
|
||||
ModeManager::AddChannelMode(new ChannelMode(CMODE_PERM, 'P'));
|
||||
+ ModeManager::AddChannelMode(new ChannelModeRegistered('r'));
|
||||
ModeManager::AddChannelMode(new ChannelMode(CMODE_REGISTEREDONLY, 'R'));
|
||||
ModeManager::AddChannelMode(new ChannelMode(CMODE_SECRET, 's'));
|
||||
ModeManager::AddChannelMode(new ChannelMode(CMODE_TOPIC, 't'));
|
||||
--
|
||||
1.7.8.3
|
||||
|
@@ -1,28 +0,0 @@
|
||||
From 5a19b69f0daceb5b12ec751bc919519a7f712f2d Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Barton <alex@barton.de>
|
||||
Date: Sun, 15 Jan 2012 13:36:14 +0100
|
||||
Subject: [PATCH 13/16] ngircd: Update copyright notice
|
||||
|
||||
---
|
||||
modules/protocol/ngircd.cpp | 7 ++++---
|
||||
1 files changed, 4 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/modules/protocol/ngircd.cpp b/modules/protocol/ngircd.cpp
|
||||
index 6155667..024c61d 100644
|
||||
--- a/modules/protocol/ngircd.cpp
|
||||
+++ b/modules/protocol/ngircd.cpp
|
||||
@@ -1,7 +1,8 @@
|
||||
-/* ngIRCd IRCD functions
|
||||
+/*
|
||||
+ * ngIRCd Protocol module for Anope IRC Services
|
||||
*
|
||||
- * (C) 2003-2011 Anope Team
|
||||
- * Contact us at team@anope.org
|
||||
+ * (C) 2011-2012 Alexander Barton <alex@barton.de>
|
||||
+ * (C) 2011 Anope Team <team@anope.org>
|
||||
*
|
||||
* Please read COPYING and README for further details.
|
||||
*
|
||||
--
|
||||
1.7.8.3
|
||||
|
@@ -1,35 +0,0 @@
|
||||
From acc24a7f4488f6ef0fb240a76766db4220b62d53 Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Barton <alex@barton.de>
|
||||
Date: Sun, 22 Jan 2012 19:05:28 +0100
|
||||
Subject: [PATCH 14/16] ngircd: set/unset GLINE's on AKILL commands
|
||||
|
||||
---
|
||||
modules/protocol/ngircd.cpp | 10 ++++++++--
|
||||
1 files changed, 8 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/modules/protocol/ngircd.cpp b/modules/protocol/ngircd.cpp
|
||||
index 024c61d..3bc3812 100644
|
||||
--- a/modules/protocol/ngircd.cpp
|
||||
+++ b/modules/protocol/ngircd.cpp
|
||||
@@ -48,10 +48,16 @@ class ngIRCdProto : public IRCDProto
|
||||
{
|
||||
void SendAkill(User *u, const XLine *x)
|
||||
{
|
||||
- // TODO: ADD SOME CODE
|
||||
+ // Calculate the time left before this would expire, capping it at 2 days
|
||||
+ time_t timeleft = x->Expires - Anope::CurTime;
|
||||
+ if (timeleft > 172800 || !x->Expires)
|
||||
+ timeleft = 172800;
|
||||
+ UplinkSocket::Message(Config->ServerName) << "GLINE " << x->Mask << " " << timeleft << " :" << x->Reason << " (" << x->By << ")";
|
||||
}
|
||||
|
||||
- void SendAkillDel(const XLine*) { }
|
||||
+ void SendAkillDel(const XLine *x) {
|
||||
+ UplinkSocket::Message(Config->ServerName) << "GLINE " << x->Mask;
|
||||
+ }
|
||||
|
||||
void SendGlobopsInternal(const BotInfo *source, const Anope::string &buf)
|
||||
{
|
||||
--
|
||||
1.7.8.3
|
||||
|
@@ -1,27 +0,0 @@
|
||||
From 3a61b190db79848d4519296432ebb2ab714c42b7 Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Barton <alex@barton.de>
|
||||
Date: Sun, 22 Jan 2012 19:06:34 +0100
|
||||
Subject: [PATCH 15/16] ngircd: ngIRCd supports channel mode 'e' now
|
||||
|
||||
---
|
||||
modules/protocol/ngircd.cpp | 3 ++-
|
||||
1 files changed, 2 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/modules/protocol/ngircd.cpp b/modules/protocol/ngircd.cpp
|
||||
index 3bc3812..0f87cbd 100644
|
||||
--- a/modules/protocol/ngircd.cpp
|
||||
+++ b/modules/protocol/ngircd.cpp
|
||||
@@ -504,8 +504,9 @@ class ProtongIRCd : public Module
|
||||
ModeManager::AddUserMode(new UserMode(UMODE_WALLOPS, 'w'));
|
||||
ModeManager::AddUserMode(new UserMode(UMODE_CLOAK, 'x'));
|
||||
|
||||
- /* Add modes for ban and invite lists */
|
||||
+ /* Add modes for ban, exception, and invite lists */
|
||||
ModeManager::AddChannelMode(new ChannelModeList(CMODE_BAN, 'b'));
|
||||
+ ModeManager::AddChannelMode(new ChannelModeList(CMODE_EXCEPT, 'e'));
|
||||
ModeManager::AddChannelMode(new ChannelModeList(CMODE_INVITEOVERRIDE, 'I'));
|
||||
|
||||
/* Add channel user modes */
|
||||
--
|
||||
1.7.8.3
|
||||
|
@@ -1,35 +0,0 @@
|
||||
From a7c48fcf47af757cf1b4eeaa6bcc96f4ae1f7410 Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Barton <alex@barton.de>
|
||||
Date: Sat, 4 Feb 2012 11:13:36 +0100
|
||||
Subject: [PATCH 16/16] ngircd: support SQUERY command
|
||||
|
||||
Thanks to DukePyrolator for explaining these changes to me.
|
||||
---
|
||||
modules/protocol/ngircd.cpp | 4 ++--
|
||||
1 files changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/modules/protocol/ngircd.cpp b/modules/protocol/ngircd.cpp
|
||||
index 0f87cbd..530686e 100644
|
||||
--- a/modules/protocol/ngircd.cpp
|
||||
+++ b/modules/protocol/ngircd.cpp
|
||||
@@ -487,7 +487,7 @@ bool event_376(const Anope::string &source, const std::vector<Anope::string> &pa
|
||||
class ProtongIRCd : public Module
|
||||
{
|
||||
Message message_kick, message_pass, message_njoin, message_chaninfo, message_005,
|
||||
- message_442, message_376, message_pong;
|
||||
+ message_442, message_376, message_pong, message_squery;
|
||||
|
||||
ngIRCdProto ircd_proto;
|
||||
ngIRCdIRCdMessage ircd_message;
|
||||
@@ -532,7 +532,7 @@ class ProtongIRCd : public Module
|
||||
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),
|
||||
- message_pong("PONG", event_pong)
|
||||
+ message_pong("PONG", event_pong), message_squery("SQUERY", ::OnPrivmsg)
|
||||
{
|
||||
this->SetAuthor("Anope");
|
||||
|
||||
--
|
||||
1.7.8.3
|
||||
|
@@ -1,34 +0,0 @@
|
||||
#
|
||||
# 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 \
|
||||
0003-Update-ngIRCd-protocol-module-for-current-Anope-1.9.patch \
|
||||
0004-ngircd-Do-PING-PONG-on-server-burst-to-sync-servers.patch \
|
||||
0005-ngircd-always-prefix-modes-in-CHANINFO-with.patch \
|
||||
0006-ngircd-support-user-mode-R-and-channel-mode-R.patch \
|
||||
0007-ngircd-Fix-handling-of-JOIN-commands.patch \
|
||||
0008-ngircd-Allow-setting-modes-by-clients-on-burst.patch \
|
||||
0009-ngircd-Update-protocol-module-for-current-Anope-1.9.patch \
|
||||
0010-ngircd-Add-ProtongIRCd.patch \
|
||||
0011-ngircd-Update-protocol-module-for-current-Anope-1.9.patch \
|
||||
0012-ngircd-Channel-mode-r-is-supported-now.patch \
|
||||
0013-ngircd-Update-copyright-notice.patch \
|
||||
0014-ngircd-set-unset-GLINE-s-on-AKILL-commands.patch \
|
||||
0015-ngircd-ngIRCd-supports-channel-mode-e-now.patch \
|
||||
0016-ngircd-support-SQUERY-command.patch
|
||||
|
||||
maintainer-clean-local:
|
||||
rm -f Makefile Makefile.in
|
||||
|
||||
# -eof-
|
@@ -1,35 +0,0 @@
|
||||
|
||||
ngIRCd - Next Generation IRC Server
|
||||
http://ngircd.barton.de/
|
||||
|
||||
(c)2001-2012 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.6, 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 (only tested with 1.9.6!),
|
||||
- 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.6-source.tar.gz
|
||||
$ cd anope-1.9.6-source
|
||||
$ for p in .../ngircd/contrib/Anope/*.patch ; do patch -p1 < $p ; done
|
||||
$ ./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.
|
@@ -1,3 +1,51 @@
|
||||
ngircd (20.3-0ab1) unstable; urgency=high
|
||||
|
||||
* New "upstream" release, fixing a security related bug: ngIRCd 20.3.
|
||||
|
||||
-- Alexander Barton <alex@barton.de> Fri, 23 Aug 2013 21:53:21 +0200
|
||||
|
||||
ngircd (20.2-0ab1) unstable; urgency=high
|
||||
|
||||
* New "upstream" release, fixing a security related bug: ngIRCd 20.2.
|
||||
|
||||
-- Alexander Barton <alex@barton.de> Fri, 15 Feb 2013 12:17:00 +0100
|
||||
|
||||
ngircd (20.1-0ab1) unstable; urgency=low
|
||||
|
||||
* New "upstream" release: ngIRCd 20.1.
|
||||
|
||||
-- Alexander Barton <alex@barton.de> Wed, 02 Jan 2013 22:37:26 +0100
|
||||
|
||||
ngircd (20-0ab1) unstable; urgency=low
|
||||
|
||||
* New "upstream" release: ngIRCd 20.
|
||||
|
||||
-- Alexander Barton <alex@barton.de> Mon, 17 Dec 2012 13:04:15 +0100
|
||||
|
||||
ngircd (20~rc2-0ab1) unstable; urgency=low
|
||||
|
||||
* New "upstream" release candidate 2 for ngIRCd Release 20.
|
||||
|
||||
-- Alexander Barton <alex@barton.de> Sun, 02 Dec 2012 18:51:06 +0100
|
||||
|
||||
ngircd (20~rc1-0ab1) unstable; urgency=low
|
||||
|
||||
* New "upstream" release candidate 1 for ngIRCd Release 20.
|
||||
|
||||
-- Alexander Barton <alex@barton.de> Sun, 11 Nov 2012 16:03:32 +0100
|
||||
|
||||
ngircd (19.2-0ab1) unstable; urgency=low
|
||||
|
||||
* New "upstream" release: ngIRCd 19.2.
|
||||
|
||||
-- Alexander Barton <alex@barton.de> Tue, 19 Jun 2012 11:03:12 +0200
|
||||
|
||||
ngircd (19.2~rc1-0ab1) unstable; urgency=low
|
||||
|
||||
* New "upstream" release candidate 1 for ngIRC Release 19.2.
|
||||
|
||||
-- Alexander Barton <alex@barton.de> Wed, 13 Jun 2012 10:59:34 +0200
|
||||
|
||||
ngircd (19.1-0ab1) unstable; urgency=low
|
||||
|
||||
* New "upstream" release: ngIRCd 19.1.
|
||||
|
@@ -10,7 +10,7 @@ Build-Depends: debhelper (>> 4.0.0),
|
||||
libident-dev,
|
||||
libgnutls-dev,
|
||||
libpam0g-dev,
|
||||
telnet,
|
||||
telnet | telnet-ssl,
|
||||
Standards-Version: 3.9.1
|
||||
|
||||
Package: ngircd
|
||||
@@ -18,11 +18,11 @@ Architecture: any
|
||||
Depends: ${shlibs:Depends}, ${misc:Depends}
|
||||
Provides: ircd
|
||||
Description: lightweight Internet Relay Chat server
|
||||
This package provides ngIRCd, a lightweight Internet Relay Chat
|
||||
server for small or private networks. It is simple to configure, can
|
||||
cope with dynamic IP addresses, and supports IPv6 as well as SSL. It
|
||||
is written from scratch, not based on the original IRCd and quite
|
||||
portable.
|
||||
This package provides ngIRCd, a portable and lightweight Internet Relay
|
||||
Chat server for small or private networks, developed under the GNU
|
||||
General Public License (GPL). It is simple to configure, can cope with
|
||||
dynamic IP addresses, and supports IPv6 as well as SSL. It is written
|
||||
from scratch and not based on the original IRCd.
|
||||
.
|
||||
This package contains the "standard distribution", including support for
|
||||
syslog logging and compressed server-links using zlib. Please have a look
|
||||
@@ -35,11 +35,11 @@ Depends: ${shlibs:Depends}, ${misc:Depends}
|
||||
Provides: ircd
|
||||
Conflicts: ngircd, ngircd-dbg
|
||||
Description: lightweight Internet Relay Chat server
|
||||
This package provides ngIRCd, a lightweight Internet Relay Chat
|
||||
server for small or private networks. It is simple to configure, can
|
||||
cope with dynamic IP addresses, and supports IPv6 as well as SSL. It
|
||||
is written from scratch, not based on the original IRCd and quite
|
||||
portable.
|
||||
This package provides ngIRCd, a portable and lightweight Internet Relay
|
||||
Chat server for small or private networks, developed under the GNU
|
||||
General Public License (GPL). It is simple to configure, can cope with
|
||||
dynamic IP addresses, and supports IPv6 as well as SSL. It is written
|
||||
from scratch and not based on the original IRCd.
|
||||
.
|
||||
In addition to the features of the "standard package", this package
|
||||
includes support for TCP wrappers, IDENT requests, the IPv6 protocol and
|
||||
@@ -51,11 +51,11 @@ Depends: ${shlibs:Depends}, ${misc:Depends}
|
||||
Provides: ircd
|
||||
Conflicts: ngircd, ngircd-full
|
||||
Description: lightweight Internet Relay Chat server
|
||||
This package provides ngIRCd, a lightweight Internet Relay Chat
|
||||
server for small or private networks. It is simple to configure, can
|
||||
cope with dynamic IP addresses, and supports IPv6 as well as SSL. It
|
||||
is written from scratch, not based on the original IRCd and quite
|
||||
portable.
|
||||
This package provides ngIRCd, a portable and lightweight Internet Relay
|
||||
Chat server for small or private networks, developed under the GNU
|
||||
General Public License (GPL). It is simple to configure, can cope with
|
||||
dynamic IP addresses, and supports IPv6 as well as SSL. It is written
|
||||
from scratch and not based on the original IRCd.
|
||||
.
|
||||
In addition to the features of the "standard package", this package
|
||||
includes support for TCP wrappers, IDENT requests, the IPv6 protocol and
|
||||
|
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/make -f
|
||||
#
|
||||
# ngIRCd -- The Next Generation IRC Daemon
|
||||
# Copyright (c)2001-2009 Alexander Barton <alex@barton.de>
|
||||
# Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@@ -53,7 +53,8 @@ configure-ngircd-full: configure
|
||||
--sysconfdir=/etc/ngircd \
|
||||
--mandir=\$${prefix}/share/man \
|
||||
--with-syslog --with-zlib \
|
||||
--with-gnutls --with-ident --with-tcp-wrappers --with-pam \
|
||||
--with-gnutls --with-iconv --with-ident --with-tcp-wrappers \
|
||||
--with-pam \
|
||||
--enable-ipv6
|
||||
|
||||
configure-ngircd-full-dbg: configure
|
||||
@@ -66,7 +67,8 @@ configure-ngircd-full-dbg: configure
|
||||
--mandir=\$${prefix}/share/man \
|
||||
--enable-debug --enable-sniffer \
|
||||
--with-syslog --with-zlib \
|
||||
--with-gnutls --with-ident --with-tcp-wrappers --with-pam \
|
||||
--with-gnutls --with-iconv --with-ident --with-tcp-wrappers \
|
||||
--with-pam \
|
||||
--enable-ipv6
|
||||
|
||||
build:
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors.
|
||||
* Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -11,7 +11,8 @@
|
||||
* Static configuration file for Mac OS X Xcode project
|
||||
*/
|
||||
|
||||
#define PACKAGE_NAME "ngircd"
|
||||
#define PACKAGE_NAME "ngIRCd"
|
||||
#define PACKAGE "ngircd"
|
||||
#ifndef VERSION
|
||||
#define VERSION "??("__DATE__")"
|
||||
#endif
|
||||
@@ -51,6 +52,9 @@
|
||||
/* Define if PAM should be used */
|
||||
#define PAM 1
|
||||
|
||||
/* Define if libiconv can be used, e.g. for CHARCONV */
|
||||
#define ICONV 1
|
||||
|
||||
/* -- Supported features -- */
|
||||
|
||||
/* Define if SSP C support is enabled. */
|
||||
@@ -76,6 +80,8 @@
|
||||
|
||||
/* Define to 1 if you have the `gai_strerror' function. */
|
||||
#define HAVE_GAI_STRERROR 1
|
||||
/* Define to 1 if you have the `iconv_open' function. */
|
||||
#define HAVE_ICONV_OPEN 1
|
||||
/* Define to 1 if you have the `kqueue' function. */
|
||||
#define HAVE_KQUEUE 1
|
||||
/* Define to 1 if you have the `inet_ntoa' function. */
|
||||
@@ -98,6 +104,8 @@
|
||||
#define HAVE_GETNAMEINFO 1
|
||||
/* Define to 1 if you have the `sigaction' function. */
|
||||
#define HAVE_SIGACTION 1
|
||||
/* Define to 1 if you have the `setsid' function. */
|
||||
#define HAVE_SETSID 1
|
||||
|
||||
/* Define if socklen_t exists */
|
||||
#define HAVE_socklen_t 1
|
||||
|
@@ -5,7 +5,7 @@
|
||||
\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\qc\pardirnatural
|
||||
|
||||
\f0\i\fs24 \cf0 ngIRCd -- The Next Generation IRC Daemon\
|
||||
Copyright (c)2001-2011 Alexander Barton and Contributors.\
|
||||
Copyright (c)2001-2013 Alexander Barton and Contributors.\
|
||||
\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\ql\qnatural\pardirnatural
|
||||
|
||||
\i0 \cf0 \
|
||||
|
@@ -36,11 +36,18 @@
|
||||
FA322DBE0CEF7766001761B3 /* tool.c in Sources */ = {isa = PBXBuildFile; fileRef = FA322D330CEF74B1001761B3 /* tool.c */; };
|
||||
FA322DC10CEF77CB001761B3 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = FA322DC00CEF77CB001761B3 /* libz.dylib */; };
|
||||
FA407F2E0DB159F400271AF1 /* ng_ipaddr.c in Sources */ = {isa = PBXBuildFile; fileRef = FA407F2C0DB159F400271AF1 /* ng_ipaddr.c */; };
|
||||
FA4F165A164836B100DBD011 /* irc-metadata.c in Sources */ = {isa = PBXBuildFile; fileRef = FA4F1659164836B100DBD011 /* irc-metadata.c */; };
|
||||
FA6BBC631605F0AC0004247A /* conn-encoding.c in Sources */ = {isa = PBXBuildFile; fileRef = FA6BBC5F1605F0AB0004247A /* conn-encoding.c */; };
|
||||
FA6BBC641605F0AC0004247A /* irc-encoding.c in Sources */ = {isa = PBXBuildFile; fileRef = FA6BBC611605F0AC0004247A /* irc-encoding.c */; };
|
||||
FA6BBC661605F6D60004247A /* libiconv.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = FA6BBC651605F6D60004247A /* libiconv.dylib */; };
|
||||
FA85178C0FA061EC006A1F5A /* op.c in Sources */ = {isa = PBXBuildFile; fileRef = FA85178B0FA061EC006A1F5A /* op.c */; };
|
||||
FA99428C10E82A27007F27ED /* proc.c in Sources */ = {isa = PBXBuildFile; fileRef = FA99428B10E82A27007F27ED /* proc.c */; };
|
||||
FAA3D27B0F139CDC00B2447E /* conn-ssl.c in Sources */ = {isa = PBXBuildFile; fileRef = FAA3D2790F139CDC00B2447E /* conn-ssl.c */; };
|
||||
FAA97C57124A271400D5BBA9 /* sighandlers.c in Sources */ = {isa = PBXBuildFile; fileRef = FAA97C55124A271400D5BBA9 /* sighandlers.c */; };
|
||||
FAACD5F514A6099C006ED74F /* class.c in Sources */ = {isa = PBXBuildFile; fileRef = FAACD5F314A6099C006ED74F /* class.c */; };
|
||||
FAD5853215271AAB00328741 /* client-cap.c in Sources */ = {isa = PBXBuildFile; fileRef = FAD5853015271AAB00328741 /* client-cap.c */; };
|
||||
FAD5853515271AB800328741 /* irc-cap.c in Sources */ = {isa = PBXBuildFile; fileRef = FAD5853315271AB800328741 /* irc-cap.c */; };
|
||||
FAD5853815272C2600328741 /* login.c in Sources */ = {isa = PBXBuildFile; fileRef = FAD5853615272C2500328741 /* login.c */; };
|
||||
FAE5CC2E0CF2308A007D69B6 /* numeric.c in Sources */ = {isa = PBXBuildFile; fileRef = FAE5CC2D0CF2308A007D69B6 /* numeric.c */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
@@ -200,6 +207,13 @@
|
||||
FA4B08E613E7F91700765BA3 /* ngIRCd-Logo.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = "ngIRCd-Logo.gif"; sourceTree = "<group>"; };
|
||||
FA4B08E713E7F91700765BA3 /* ngircd-redhat.init */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = "ngircd-redhat.init"; sourceTree = "<group>"; };
|
||||
FA4B08E813E7F91C00765BA3 /* platformtest.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = platformtest.sh; sourceTree = "<group>"; };
|
||||
FA4F1659164836B100DBD011 /* irc-metadata.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "irc-metadata.c"; sourceTree = "<group>"; };
|
||||
FA4F165C164836BF00DBD011 /* irc-metadata.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "irc-metadata.h"; sourceTree = "<group>"; };
|
||||
FA6BBC5F1605F0AB0004247A /* conn-encoding.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "conn-encoding.c"; sourceTree = "<group>"; };
|
||||
FA6BBC601605F0AC0004247A /* conn-encoding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "conn-encoding.h"; sourceTree = "<group>"; };
|
||||
FA6BBC611605F0AC0004247A /* irc-encoding.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "irc-encoding.c"; sourceTree = "<group>"; };
|
||||
FA6BBC621605F0AC0004247A /* irc-encoding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "irc-encoding.h"; sourceTree = "<group>"; };
|
||||
FA6BBC651605F6D60004247A /* libiconv.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libiconv.dylib; path = ../../../../../../../usr/lib/libiconv.dylib; sourceTree = "<group>"; };
|
||||
FA77849A133FB9FF00740057 /* sample-ngircd.conf.tmpl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "sample-ngircd.conf.tmpl"; sourceTree = "<group>"; };
|
||||
FA85178A0FA061EC006A1F5A /* op.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = op.h; sourceTree = "<group>"; };
|
||||
FA85178B0FA061EC006A1F5A /* op.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; path = op.c; sourceTree = "<group>"; };
|
||||
@@ -231,6 +245,19 @@
|
||||
FAA97C56124A271400D5BBA9 /* sighandlers.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = sighandlers.h; sourceTree = "<group>"; };
|
||||
FAACD5F314A6099C006ED74F /* class.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = class.c; sourceTree = "<group>"; };
|
||||
FAACD5F414A6099C006ED74F /* class.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = class.h; sourceTree = "<group>"; };
|
||||
FAD5852F15271A7800328741 /* Capabilities.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = Capabilities.txt; sourceTree = "<group>"; };
|
||||
FAD5853015271AAB00328741 /* client-cap.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "client-cap.c"; sourceTree = "<group>"; };
|
||||
FAD5853115271AAB00328741 /* client-cap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "client-cap.h"; sourceTree = "<group>"; };
|
||||
FAD5853315271AB800328741 /* irc-cap.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "irc-cap.c"; sourceTree = "<group>"; };
|
||||
FAD5853415271AB800328741 /* irc-cap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "irc-cap.h"; sourceTree = "<group>"; };
|
||||
FAD5853615272C2500328741 /* login.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = login.c; sourceTree = "<group>"; };
|
||||
FAD5853715272C2500328741 /* login.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = login.h; sourceTree = "<group>"; };
|
||||
FAE22BD215270EA300F1A5AB /* Bopm.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = Bopm.txt; sourceTree = "<group>"; };
|
||||
FAE22BD415270EA300F1A5AB /* Contributing.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = Contributing.txt; sourceTree = "<group>"; };
|
||||
FAE22BD515270EB500F1A5AB /* HowToRelease.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = HowToRelease.txt; sourceTree = "<group>"; };
|
||||
FAE22BD615270EB500F1A5AB /* Modes.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = Modes.txt; sourceTree = "<group>"; };
|
||||
FAE22BD715270EB500F1A5AB /* PAM.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = PAM.txt; sourceTree = "<group>"; };
|
||||
FAE22BD815270EC400F1A5AB /* README-Interix.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = "README-Interix.txt"; sourceTree = "<group>"; };
|
||||
FAE5CC2C0CF2308A007D69B6 /* numeric.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = numeric.h; sourceTree = "<group>"; };
|
||||
FAE5CC2D0CF2308A007D69B6 /* numeric.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = numeric.c; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
@@ -242,6 +269,7 @@
|
||||
files = (
|
||||
FA322DC10CEF77CB001761B3 /* libz.dylib in Frameworks */,
|
||||
FA2D567B11EA1AB300D37A35 /* libpam.dylib in Frameworks */,
|
||||
FA6BBC661605F6D60004247A /* libiconv.dylib in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -267,8 +295,9 @@
|
||||
FA322D600CEF750F001761B3 /* configure.in */,
|
||||
FA322D630CEF750F001761B3 /* Makefile.am */,
|
||||
1AB674ADFE9D54B511CA2CBB /* Products */,
|
||||
FA322DC00CEF77CB001761B3 /* libz.dylib */,
|
||||
FA6BBC651605F6D60004247A /* libiconv.dylib */,
|
||||
FA2D567A11EA1AB300D37A35 /* libpam.dylib */,
|
||||
FA322DC00CEF77CB001761B3 /* libz.dylib */,
|
||||
);
|
||||
name = ngIRCd;
|
||||
sourceTree = "<group>";
|
||||
@@ -298,8 +327,7 @@
|
||||
FA322CD70CEF74B1001761B3 /* ngircd */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
FAA3D2790F139CDC00B2447E /* conn-ssl.c */,
|
||||
FAA3D27A0F139CDC00B2447E /* conn-ssl.h */,
|
||||
FA322D020CEF74B1001761B3 /* Makefile.am */,
|
||||
FA322CD90CEF74B1001761B3 /* array.c */,
|
||||
FA322CDA0CEF74B1001761B3 /* array.h */,
|
||||
FA322CDB0CEF74B1001761B3 /* channel.c */,
|
||||
@@ -308,26 +336,40 @@
|
||||
FAACD5F414A6099C006ED74F /* class.h */,
|
||||
FA322CDD0CEF74B1001761B3 /* client.c */,
|
||||
FA322CDE0CEF74B1001761B3 /* client.h */,
|
||||
FAD5853015271AAB00328741 /* client-cap.c */,
|
||||
FAD5853115271AAB00328741 /* client-cap.h */,
|
||||
FA322CDF0CEF74B1001761B3 /* conf.c */,
|
||||
FA322CE00CEF74B1001761B3 /* conf.h */,
|
||||
FAA3D2780F139CDC00B2447E /* conf-ssl.h */,
|
||||
FA322CE50CEF74B1001761B3 /* conn.c */,
|
||||
FA322CE60CEF74B1001761B3 /* conn.h */,
|
||||
FA6BBC5F1605F0AB0004247A /* conn-encoding.c */,
|
||||
FA6BBC601605F0AC0004247A /* conn-encoding.h */,
|
||||
FA322CE10CEF74B1001761B3 /* conn-func.c */,
|
||||
FA322CE20CEF74B1001761B3 /* conn-func.h */,
|
||||
FA322CE30CEF74B1001761B3 /* conn-zip.c */,
|
||||
FA322CE40CEF74B1001761B3 /* conn-zip.h */,
|
||||
FA322CE50CEF74B1001761B3 /* conn.c */,
|
||||
FA322CE60CEF74B1001761B3 /* conn.h */,
|
||||
FAA3D2790F139CDC00B2447E /* conn-ssl.c */,
|
||||
FAA3D27A0F139CDC00B2447E /* conn-ssl.h */,
|
||||
FA322CE70CEF74B1001761B3 /* defines.h */,
|
||||
FA322CE80CEF74B1001761B3 /* hash.c */,
|
||||
FA322CE90CEF74B1001761B3 /* hash.h */,
|
||||
FA322CEA0CEF74B1001761B3 /* io.c */,
|
||||
FA322CEB0CEF74B1001761B3 /* io.h */,
|
||||
FA322CFC0CEF74B1001761B3 /* irc.c */,
|
||||
FA322CFD0CEF74B1001761B3 /* irc.h */,
|
||||
FAD5853315271AB800328741 /* irc-cap.c */,
|
||||
FAD5853415271AB800328741 /* irc-cap.h */,
|
||||
FA322CEC0CEF74B1001761B3 /* irc-channel.c */,
|
||||
FA322CED0CEF74B1001761B3 /* irc-channel.h */,
|
||||
FA6BBC611605F0AC0004247A /* irc-encoding.c */,
|
||||
FA6BBC621605F0AC0004247A /* irc-encoding.h */,
|
||||
FA322CEE0CEF74B1001761B3 /* irc-info.c */,
|
||||
FA322CEF0CEF74B1001761B3 /* irc-info.h */,
|
||||
FA322CF00CEF74B1001761B3 /* irc-login.c */,
|
||||
FA322CF10CEF74B1001761B3 /* irc-login.h */,
|
||||
FA4F1659164836B100DBD011 /* irc-metadata.c */,
|
||||
FA4F165C164836BF00DBD011 /* irc-metadata.h */,
|
||||
FA322CF20CEF74B1001761B3 /* irc-mode.c */,
|
||||
FA322CF30CEF74B1001761B3 /* irc-mode.h */,
|
||||
FA322CF40CEF74B1001761B3 /* irc-op.c */,
|
||||
@@ -338,13 +380,12 @@
|
||||
FA322CF90CEF74B1001761B3 /* irc-server.h */,
|
||||
FA322CFA0CEF74B1001761B3 /* irc-write.c */,
|
||||
FA322CFB0CEF74B1001761B3 /* irc-write.h */,
|
||||
FA322CFC0CEF74B1001761B3 /* irc.c */,
|
||||
FA322CFD0CEF74B1001761B3 /* irc.h */,
|
||||
FA322CFE0CEF74B1001761B3 /* lists.c */,
|
||||
FA322CFF0CEF74B1001761B3 /* lists.h */,
|
||||
FA322D000CEF74B1001761B3 /* log.c */,
|
||||
FA322D010CEF74B1001761B3 /* log.h */,
|
||||
FA322D020CEF74B1001761B3 /* Makefile.am */,
|
||||
FAD5853615272C2500328741 /* login.c */,
|
||||
FAD5853715272C2500328741 /* login.h */,
|
||||
FA322D030CEF74B1001761B3 /* match.c */,
|
||||
FA322D040CEF74B1001761B3 /* match.h */,
|
||||
FA322D050CEF74B1001761B3 /* messages.h */,
|
||||
@@ -563,18 +604,25 @@
|
||||
FA322D970CEF752C001761B3 /* doc */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
FAA3D2800F139D1500B2447E /* Services.txt */,
|
||||
FA407F380DB15AC700271AF1 /* GIT.txt */,
|
||||
FA322D9A0CEF752C001761B3 /* FAQ.txt */,
|
||||
FA322D9B0CEF752C001761B3 /* Makefile.am */,
|
||||
FAE22BD215270EA300F1A5AB /* Bopm.txt */,
|
||||
FAD5852F15271A7800328741 /* Capabilities.txt */,
|
||||
FAE22BD415270EA300F1A5AB /* Contributing.txt */,
|
||||
FA322D9A0CEF752C001761B3 /* FAQ.txt */,
|
||||
FA407F380DB15AC700271AF1 /* GIT.txt */,
|
||||
FAE22BD515270EB500F1A5AB /* HowToRelease.txt */,
|
||||
FAE22BD615270EB500F1A5AB /* Modes.txt */,
|
||||
FAE22BD715270EB500F1A5AB /* PAM.txt */,
|
||||
FA322D9C0CEF752C001761B3 /* Platforms.txt */,
|
||||
FA322D9D0CEF752C001761B3 /* Protocol.txt */,
|
||||
FA322D9E0CEF752C001761B3 /* README-AUX.txt */,
|
||||
FA322D9F0CEF752C001761B3 /* README-BeOS.txt */,
|
||||
FAE22BD815270EC400F1A5AB /* README-Interix.txt */,
|
||||
FA322DA00CEF752C001761B3 /* RFC.txt */,
|
||||
FAA3D2800F139D1500B2447E /* Services.txt */,
|
||||
FA322DA90CEF752C001761B3 /* SSL.txt */,
|
||||
FA77849A133FB9FF00740057 /* sample-ngircd.conf.tmpl */,
|
||||
FA322DA20CEF752C001761B3 /* src */,
|
||||
FA322DA90CEF752C001761B3 /* SSL.txt */,
|
||||
);
|
||||
name = doc;
|
||||
path = ../../doc;
|
||||
@@ -653,7 +701,7 @@
|
||||
08FB7793FE84155DC02AAC07 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0420;
|
||||
LastUpgradeCheck = 0430;
|
||||
};
|
||||
buildConfigurationList = 1DEB928908733DD80010E9CD /* Build configuration list for PBXProject "ngIRCd" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
@@ -718,6 +766,12 @@
|
||||
FA2D564A11EA158B00D37A35 /* pam.c in Sources */,
|
||||
FAA97C57124A271400D5BBA9 /* sighandlers.c in Sources */,
|
||||
FAACD5F514A6099C006ED74F /* class.c in Sources */,
|
||||
FAD5853215271AAB00328741 /* client-cap.c in Sources */,
|
||||
FAD5853515271AB800328741 /* irc-cap.c in Sources */,
|
||||
FAD5853815272C2600328741 /* login.c in Sources */,
|
||||
FA6BBC631605F0AC0004247A /* conn-encoding.c in Sources */,
|
||||
FA6BBC641605F0AC0004247A /* irc-encoding.c in Sources */,
|
||||
FA4F165A164836B100DBD011 /* irc-metadata.c in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -747,7 +801,7 @@
|
||||
GCC_WARN_UNUSED_PARAMETER = YES;
|
||||
GCC_WARN_UNUSED_VALUE = YES;
|
||||
INSTALL_PATH = /usr/local/bin;
|
||||
PRODUCT_NAME = ngIRCd;
|
||||
PRODUCT_NAME = ngircd;
|
||||
};
|
||||
name = Default;
|
||||
};
|
||||
@@ -755,10 +809,12 @@
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
|
||||
GCC_VERSION = 4.2;
|
||||
CODE_SIGN_IDENTITY = "";
|
||||
GCC_VERSION = "";
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
SDKROOT = macosx10.6;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.6;
|
||||
SDKROOT = "";
|
||||
};
|
||||
name = Default;
|
||||
};
|
||||
@@ -768,11 +824,12 @@
|
||||
ARCHS = "$(NATIVE_ARCH_ACTUAL)";
|
||||
GCC_DEBUGGING_SYMBOLS = full;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_VERSION = 4.2;
|
||||
GCC_VERSION = "";
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.6;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = macosx;
|
||||
SDKROOT = "";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
@@ -799,7 +856,7 @@
|
||||
GCC_WARN_UNUSED_PARAMETER = YES;
|
||||
GCC_WARN_UNUSED_VALUE = YES;
|
||||
INSTALL_PATH = /usr/local/bin;
|
||||
PRODUCT_NAME = ngIRCd;
|
||||
PRODUCT_NAME = ngircd;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
|
@@ -1,6 +1,6 @@
|
||||
#
|
||||
# ngIRCd -- The Next Generation IRC Daemon
|
||||
# Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors
|
||||
# Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@@ -9,10 +9,17 @@
|
||||
# Please read the file COPYING, README and AUTHORS for more information.
|
||||
#
|
||||
|
||||
SUBDIRS = Anope Debian MacOSX
|
||||
SUBDIRS = Debian MacOSX
|
||||
|
||||
EXTRA_DIST = README ngircd.spec systrace.policy ngindent ngircd-bsd.sh \
|
||||
ngIRCd-Logo.gif ngircd-redhat.init platformtest.sh
|
||||
EXTRA_DIST = README \
|
||||
ngindent \
|
||||
ngircd-bsd.sh \
|
||||
ngIRCd-Logo.gif \
|
||||
ngircd-redhat.init \
|
||||
ngircd.service \
|
||||
ngircd.spec \
|
||||
platformtest.sh \
|
||||
systrace.policy
|
||||
|
||||
maintainer-clean-local:
|
||||
rm -f Makefile Makefile.in
|
||||
|
@@ -9,9 +9,6 @@
|
||||
-- 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").
|
||||
|
||||
|
11
contrib/ngircd.service
Normal file
11
contrib/ngircd.service
Normal file
@@ -0,0 +1,11 @@
|
||||
[Unit]
|
||||
Description=Next Generation IRC Daemon
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
# don't daemonize to simplify stuff
|
||||
ExecStart=/usr/sbin/ngircd -n
|
||||
ExecReload=/bin/kill -HUP $MAINPID
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
@@ -1,5 +1,5 @@
|
||||
%define name ngircd
|
||||
%define version 19.1
|
||||
%define version 20.3
|
||||
%define release 1
|
||||
%define prefix %{_prefix}
|
||||
|
||||
@@ -15,11 +15,11 @@ BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
|
||||
BuildRequires: zlib-devel, openssl-devel
|
||||
|
||||
%description
|
||||
This package provides ngIRCd, a lightweight Internet Relay Chat
|
||||
server for small or private networks. It is simple to configure, can
|
||||
cope with dynamic IP addresses, and supports IPv6 as well as SSL. It
|
||||
is written from scratch, not based on the original IRCd and quite
|
||||
portable.
|
||||
This package provides ngIRCd, a portable and lightweight Internet Relay
|
||||
Chat server for small or private networks, developed under the GNU
|
||||
General Public License (GPL). It is simple to configure, can cope with
|
||||
dynamic IP addresses, and supports IPv6 as well as SSL. It is written
|
||||
from scratch and not based on the original IRCd.
|
||||
|
||||
Advantages:
|
||||
- well arranged (lean) configuration file
|
||||
|
@@ -1,7 +1,7 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# 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
|
||||
@@ -21,13 +21,16 @@ PLATFORM=
|
||||
COMPILER="unknown"
|
||||
VERSION="unknown"
|
||||
DATE=`date "+%y-%m-%d"`
|
||||
|
||||
CONFIGURE=
|
||||
MAKE=
|
||||
CHECK=
|
||||
RUN=
|
||||
COMMENT=
|
||||
|
||||
R_CONFIGURE=
|
||||
R_MAKE=
|
||||
R_CHECK=
|
||||
R_RUN=
|
||||
|
||||
[ -n "$MAKE" ] || MAKE="make"
|
||||
export MAKE CC
|
||||
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
"-v")
|
||||
@@ -51,8 +54,8 @@ if [ $? -ne 0 ]; then
|
||||
cd ..
|
||||
fi
|
||||
|
||||
echo "$NAME: Checking for \"./autogen.sh\" script ..."
|
||||
if [ -r ./autogen.sh ]; then
|
||||
echo "$NAME: Checking for \"./configure\" script ..."
|
||||
if [ ! -e ./configure ]; then
|
||||
echo "$NAME: Running \"./autogen.sh\" ..."
|
||||
[ -n "$VERBOSE" ] && ./autogen.sh || ./autogen.sh >/dev/null
|
||||
fi
|
||||
@@ -61,20 +64,20 @@ if [ -r ./configure ]; then
|
||||
echo "$NAME: Running \"./configure\" script ..."
|
||||
[ -n "$VERBOSE" ] && ./configure || ./configure >/dev/null
|
||||
if [ $? -eq 0 -a -r ./Makefile ]; then
|
||||
CONFIGURE=1
|
||||
echo "$NAME: Running \"make\" ..."
|
||||
[ -n "$VERBOSE" ] && make || make >/dev/null
|
||||
R_CONFIGURE=1
|
||||
echo "$NAME: Running \"$MAKE\" ..."
|
||||
[ -n "$VERBOSE" ] && "$MAKE" || "$MAKE" >/dev/null
|
||||
if [ $? -eq 0 -a -x src/ngircd/ngircd ]; then
|
||||
MAKE=1
|
||||
echo "$NAME: Running \"make check\" ..."
|
||||
[ -n "$VERBOSE" ] && make check || make check >/dev/null
|
||||
R_MAKE=1
|
||||
echo "$NAME: Running \"$MAKE check\" ..."
|
||||
[ -n "$VERBOSE" ] && "$MAKE" check || "$MAKE" check >/dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
CHECK=1
|
||||
RUN=$CHECK
|
||||
R_CHECK=1
|
||||
R_RUN=$R_CHECK
|
||||
else
|
||||
./src/ngircd/ngircd --help 2>/dev/null \
|
||||
| grep "^ngircd" >/dev/null
|
||||
[ $? -eq 0 ] && RUN=1
|
||||
| grep "^ngIRCd" >/dev/null
|
||||
[ $? -eq 0 ] && R_RUN=1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
@@ -82,9 +85,9 @@ fi
|
||||
|
||||
# Get target platform information
|
||||
if [ -r "src/config.h" ]; then
|
||||
CPU=`grep "TARGET_CPU" "src/config.h" | cut -d'"' -f2`
|
||||
OS=`grep "TARGET_OS" "src/config.h" | cut -d'"' -f2`
|
||||
VENDOR=`grep "TARGET_VENDOR" "src/config.h" | cut -d'"' -f2`
|
||||
CPU=`grep "HOST_CPU" "src/config.h" | cut -d'"' -f2`
|
||||
OS=`grep "HOST_OS" "src/config.h" | cut -d'"' -f2`
|
||||
VENDOR=`grep "HOST_VENDOR" "src/config.h" | cut -d'"' -f2`
|
||||
PLATFORM="$CPU/$VENDOR/$OS"
|
||||
fi
|
||||
if [ -z "$PLATFORM" ]; then
|
||||
@@ -96,9 +99,14 @@ 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 \
|
||||
| cut -d')' -f2 | cut -d' ' -f2)
|
||||
COMPILER="gcc $COMPILER"
|
||||
$CC --version 2>&1 | grep -i "Open64" >/dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
COMPILER="Open64"
|
||||
else
|
||||
COMPILER=$($CC --version | head -1 \
|
||||
| cut -d')' -f2 | cut -d' ' -f2)
|
||||
COMPILER="gcc $COMPILER"
|
||||
fi
|
||||
else
|
||||
case "$CC" in
|
||||
gcc*)
|
||||
@@ -130,10 +138,10 @@ else
|
||||
[ $? -eq 0 ] && COMMENT="(3)"
|
||||
fi
|
||||
|
||||
[ -n "$CONFIGURE" ] && C="Y" || C="N"
|
||||
[ -n "$MAKE" ] && M="Y" || M="N"
|
||||
[ -n "$CHECK" ] && T="Y" || T="N"
|
||||
[ -n "$RUN" ] && R="Y" || R="N"
|
||||
[ -n "$R_CONFIGURE" ] && C="Y" || C="N"
|
||||
[ -n "$R_MAKE" ] && M="Y" || M="N"
|
||||
[ -n "$R_CHECK" ] && T="Y" || T="N"
|
||||
[ -n "$R_RUN" ] && R="Y" || R="N"
|
||||
[ -n "$COMMENT" ] && COMMENT=" $COMMENT"
|
||||
|
||||
echo
|
||||
|
28
doc/Capabilities.txt
Normal file
28
doc/Capabilities.txt
Normal file
@@ -0,0 +1,28 @@
|
||||
|
||||
ngIRCd - Next Generation IRC Server
|
||||
http://ngircd.barton.de/
|
||||
|
||||
(c)2001-2012 Alexander Barton and Contributors.
|
||||
ngIRCd is free software and published under the
|
||||
terms of the GNU General Public License.
|
||||
|
||||
-- Capabilities.txt --
|
||||
|
||||
|
||||
This document lists and describes the "IRC capabilities" that ngIRCd supports
|
||||
and can be requested by a IRC/IRCv3 client that supports the "CAP" command.
|
||||
|
||||
ngIRCd implements the "IRC Client Capabilities Extension" as described here:
|
||||
<http://www.leeh.co.uk/draft-mitchell-irc-capabilities-02.html>
|
||||
|
||||
|
||||
I. Supported Capabilities
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* "multi-prefix"
|
||||
|
||||
When requested, the multi-prefix client capability will cause the IRC
|
||||
server to send all possible prefixes which apply to a user in NAMES and
|
||||
WHO output.
|
||||
|
||||
See <http://ircv3.atheme.org/extensions/multi-prefix-3.1>.
|
14
doc/FAQ.txt
14
doc/FAQ.txt
@@ -64,11 +64,19 @@ A: ngIRCd does not write its own log file. Instead, ngIRCd uses syslog(3).
|
||||
|
||||
Q: I cannot connect to remote peers when I use the chroot option, the
|
||||
following is logged: "Can't resolve example.com: unknown error!".
|
||||
A: see next question blow ...
|
||||
|
||||
Q: When running ngIRCd inside a chroot, no IP addresses can be translated
|
||||
in DNS names, errors like "Name or service not known" are logged.
|
||||
A: On Linux/glibc with chroot enabled you need to put some libraries inside
|
||||
the chroot as well, notably libnss_dns; maybe others. Unfortunately, even
|
||||
linking ngIRCd statically does not help this. The only known workaround
|
||||
is to either disable chroot support or to link against dietlibc instead
|
||||
of glibc. (tnx to Sebastian Siewior)
|
||||
linking ngIRCd statically does not help this. So you can either copy
|
||||
all the required files into the chroot directory:
|
||||
$ mkdir -p ./chroot/etc ./chroot/lib
|
||||
$ cp -a /etc/hosts /etc/resolv.conf /etc/nsswitch.conf ./chroot/etc/
|
||||
$ cp -a /lib/libresolv* /lib/libnss_* ./chroot/lib/
|
||||
Or you can try to link ngIRCd against an other C library (like dietlibc)
|
||||
that doesn't depend on NSS modules and/or these files.
|
||||
|
||||
Q: I have added an [Oper] section, how do i log on as IRC operator?
|
||||
A: You can use the /OPER command in your IRC client to become an IRC operator.
|
||||
|
@@ -40,7 +40,7 @@ a) Make sure the source tree is in a releasable state ;-)
|
||||
|
||||
b) Make sure you have working versions of GNU autoconf and GNU automake
|
||||
installed on the system you use for generating the release:
|
||||
as of October 2010 we are using GNU autoconf 2.61 and GNU automake 1.10.1
|
||||
as of October 2010 we are using GNU autoconf 2.67 and GNU automake 1.11.1
|
||||
which seem to work just fine.
|
||||
|
||||
c) Update the files describing the new release:
|
||||
|
@@ -1,6 +1,6 @@
|
||||
#
|
||||
# ngIRCd -- The Next Generation IRC Daemon
|
||||
# Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors
|
||||
# Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@@ -10,15 +10,29 @@
|
||||
#
|
||||
|
||||
.tmpl:
|
||||
sed \
|
||||
-e s@:ETCDIR:@${sysconfdir}@ \
|
||||
$(AM_V_GEN)sed \
|
||||
-e "s@:ETCDIR:@${sysconfdir}@" \
|
||||
<$< >$@
|
||||
|
||||
SUFFIXES = .tmpl
|
||||
|
||||
static_docs = Bopm.txt FAQ.txt GIT.txt HowToRelease.txt Modes.txt PAM.txt \
|
||||
Platforms.txt Protocol.txt README-AUX.txt README-BeOS.txt \
|
||||
README-Interix.txt RFC.txt SSL.txt Services.txt
|
||||
static_docs = \
|
||||
Bopm.txt \
|
||||
Capabilities.txt \
|
||||
Contributing.txt \
|
||||
FAQ.txt \
|
||||
GIT.txt \
|
||||
HowToRelease.txt \
|
||||
Modes.txt \
|
||||
PAM.txt \
|
||||
Platforms.txt \
|
||||
Protocol.txt \
|
||||
README-AUX.txt \
|
||||
README-BeOS.txt \
|
||||
README-Interix.txt \
|
||||
RFC.txt \
|
||||
Services.txt \
|
||||
SSL.txt
|
||||
|
||||
doc_templates = sample-ngircd.conf.tmpl
|
||||
|
||||
@@ -39,8 +53,8 @@ all: $(generated_docs)
|
||||
|
||||
install-data-hook: $(static_docs) $(toplevel_docs) $(generated_docs)
|
||||
$(mkinstalldirs) $(DESTDIR)$(sysconfdir)
|
||||
if [ ! -f $(DESTDIR)$(sysconfdir)/ngircd.conf ]; then \
|
||||
$(INSTALL) -m 600 -c sample-ngircd.conf $(DESTDIR)$(sysconfdir)/ngircd.conf; \
|
||||
@if [ ! -f $(DESTDIR)$(sysconfdir)/ngircd.conf ]; then \
|
||||
make install-config; \
|
||||
fi
|
||||
$(mkinstalldirs) $(DESTDIR)$(docdir)
|
||||
for f in $(static_docs) $(toplevel_docs); do \
|
||||
@@ -50,10 +64,30 @@ install-data-hook: $(static_docs) $(toplevel_docs) $(generated_docs)
|
||||
$(INSTALL) -m 644 -c $$f $(DESTDIR)$(docdir)/; \
|
||||
done
|
||||
|
||||
install-config:
|
||||
$(INSTALL) -m 600 -c sample-ngircd.conf $(DESTDIR)$(sysconfdir)/ngircd.conf
|
||||
@echo; \
|
||||
echo " ** NOTE: Installed sample configuration file:"; \
|
||||
echo " ** \"$(DESTDIR)$(sysconfdir)/ngircd.conf\""; \
|
||||
echo
|
||||
|
||||
uninstall-hook:
|
||||
rm -rf $(DESTDIR)$(docdir)
|
||||
@if cmp --silent sample-ngircd.conf $(DESTDIR)$(sysconfdir)/ngircd.conf; then \
|
||||
make uninstall-config; \
|
||||
else \
|
||||
echo; \
|
||||
echo " ** NOTE: Not uninstalling changed configuration file:"; \
|
||||
echo " ** \"$(DESTDIR)$(sysconfdir)/ngircd.conf\""; \
|
||||
echo; \
|
||||
fi
|
||||
|
||||
uninstall-config:
|
||||
rm -f $(DESTDIR)$(sysconfdir)/ngircd.conf
|
||||
|
||||
srcdoc:
|
||||
make -C src srcdoc
|
||||
|
||||
.PHONY: install-config uninstall-config srcdoc
|
||||
|
||||
# -eof-
|
||||
|
@@ -2,7 +2,7 @@
|
||||
ngIRCd - Next Generation IRC Server
|
||||
http://ngircd.barton.de/
|
||||
|
||||
(c)2001-2011 Alexander Barton and Contributors.
|
||||
(c)2001-2012 Alexander Barton and Contributors.
|
||||
ngIRCd is free software and published under the
|
||||
terms of the GNU General Public License.
|
||||
|
||||
@@ -22,10 +22,13 @@ channels he is using at the moment.
|
||||
mode since description
|
||||
|
||||
a 0.3.0 User is away.
|
||||
b 20 User blocks private messages and notices.
|
||||
B 20 User is flagged as a "bot".
|
||||
c 17 IRC operator wants to receive connect/disconnect NOTICEs.
|
||||
C 19 Only users that share a channel are allowed to send messages.
|
||||
i 0.0.1 User is "invisible".
|
||||
o 0.0.1 User is IRC operator.
|
||||
q 20 User is protected, can not be kicked from a channel.
|
||||
r 0.0.1 User is restricted.
|
||||
R (1) 19 User is registered (e.g. by NickServ).
|
||||
s 0.4.0 User wants to receive server notices.
|
||||
@@ -43,18 +46,22 @@ users to lists (e.g. "invite list", "ban list"), others have parameters
|
||||
mode since description
|
||||
|
||||
b 0.5.0 Add/remove a host mask to the ban list.
|
||||
e 19 Add/remove a host mask to the exception list.
|
||||
i 0.5.0 Channel is "invite only".
|
||||
I 0.5.0 Add/remove a host mask to the invite list.
|
||||
k 0.6.0 Channel has a "key" (a password).
|
||||
l 0.6.0 Channel has a user limit.
|
||||
m 0.3.0 Channel is moderated, only "voiced" users can send messages.
|
||||
M 20 Only registered users (and IRC Ops) can send messages.
|
||||
n 0.3.0 Channel doesn't allow messages of users not being members.
|
||||
O 18 Only IRC operators are allowed to join this channel.
|
||||
P 0.5.0 Channel is "persistent".
|
||||
Q 20 Nobody can be kicked from the channel.
|
||||
r (1) 19 Channel is "registered" (e.g. by ChanServ).
|
||||
R 19 Only registered users are allowed to join this channel.
|
||||
s 0.9.0 Channel is "secret".
|
||||
t 0.3.0 Only ChanOps are allowed to modify the channel topic.
|
||||
V 20 Channel doesn't allow invites.
|
||||
z 16 Only users connected via SSL are allowed to join the channel.
|
||||
|
||||
III. Channel User Modes
|
||||
@@ -65,7 +72,12 @@ channel of which he is a member.
|
||||
|
||||
mode since description
|
||||
|
||||
q 20 User is channel owner can only be set by a service, other
|
||||
owner and irc op. Can promote other users to q, a, o, h, v.
|
||||
a 20 User is channel admin and can promote other users to v, h, o
|
||||
o 0.2.0 User is channel operator and can op/kick/... other members.
|
||||
h 20 User is half op and can set channel modes imntvIbek and kick
|
||||
voiced and normal users.
|
||||
v 0.2.0 User is "voiced" and can speak even if channel is moderated.
|
||||
|
||||
|
||||
|
@@ -26,6 +26,8 @@ list can be updated. Thanks for your help!
|
||||
Platform Compiler ngIRCd Date Tester C M T R See
|
||||
--------------------------- ------------ ---------- -------- ------ - - - - ---
|
||||
alpha/unknown/netbsd3.0 gcc 3.3.3 CVSHEAD 06-05-07 fw Y Y Y Y (3)
|
||||
armv6l/unkn./linux-gnueabi gcc 4.4.5 19.1 12-06-04 goetz Y Y Y Y (5)
|
||||
armv7l/unkn./linux-gnueabi gcc 4.4.3 19.1 12-04-29 goetz Y Y Y Y (5)
|
||||
hppa/unknown/openbsd3.5 gcc 2.95.3 CVSHEAD 04-05-25 alex Y Y Y Y
|
||||
hppa1.1/unknown/linux-gnu gcc 3.3.3 0.8.0 04-05-30 alex Y Y Y Y
|
||||
hppa2.0/unknown/linux-gnu gcc 3.3.5 13~rc1 08-12-02 alex Y Y Y Y
|
||||
@@ -35,10 +37,10 @@ i386/apple/darwin10.8.0 gcc 4.2.1 19 12-02-26 alex Y Y Y Y (3)
|
||||
i386/apple/darwin11.3.0 gcc 4.2.1 19 12-02-26 alex Y Y Y Y (3)
|
||||
i386/pc/solaris2.9 gcc 3.2.2 CVSHEAD 04-02-24 alex Y Y Y Y
|
||||
i386/pc/solaris2.11 gcc 3.4.3 19 12-02-26 alex Y Y N Y (4)
|
||||
i386/pc/solaris2.11 gcc 4.2.3 18 11-08-17 goetz Y Y Y Y (4)
|
||||
i386/pc/solaris2.11 gcc 4.2.3 19.1 12-05-29 goetz Y Y Y Y (4)
|
||||
i386/unknown/freebsd5.2.1 gcc 3.3.3 0.8.0 04-05-30 alex Y Y Y Y
|
||||
i386/unknown/freebsd6.2 gcc 3.4.6 19 12-02-26 alex Y Y Y Y (3)
|
||||
i386/unknown/freebsd7.3 gcc 4.2.1 19 12-02-26 alex Y Y Y Y (3)
|
||||
i386/unknown/freebsd6.2 gcc 3.4.6 20~rc1 12-11-13 alex Y Y Y Y (3)
|
||||
i386/unknown/freebsd7.3 gcc 4.2.1 20~rc1 12-11-13 alex Y Y Y Y (3)
|
||||
i686/unknown/gnu0.3 gcc 4.4.5 19 12-02-29 alex Y Y Y Y
|
||||
i686/unkn./kfreebsd7.2-gnu gcc 4.3.4 15 09-12-02 alex Y Y Y Y (3)
|
||||
i386/unknown/netbsdelf1.6.2 gcc 2.95.3 18 11-07-10 goetz Y Y Y Y
|
||||
@@ -47,8 +49,10 @@ i386/unknown/netbsdelf4.0 gcc 4.1.2 19 12-02-29 alex Y Y Y Y (3)
|
||||
i386/unknown/netbsdelf5.0.2 gcc 4.1.3 19 12-02-26 alex Y Y Y Y (3)
|
||||
i386/unknown/openbsd3.9 gcc 3.3.5 0.10.0-p1 06-08-30 alex Y Y Y Y (3)
|
||||
i386/unknown/openbsd4.1 gcc 3.3.5 16 10-04-11 alex Y Y Y Y (3)
|
||||
i586/pc/haiku gcc 2.95.3 19.2~138 12-10-11 user Y Y N N
|
||||
i586/pc/interix3.5 gcc 3.3 19 12-02-29 alex Y Y N Y
|
||||
i686/pc/cygwin gcc 3.3.1 0.8.0 04-05-30 alex Y Y N Y
|
||||
i686/pc/linux-gnu gcc 2.7.2 19.1 12-05-30 goetz Y Y Y Y (1)
|
||||
i686/pc/linux-gnu gcc 2.95.4 0.8.0 04-05-30 alex Y Y Y Y (1)
|
||||
i686/pc/linux-gnu gcc 3.3.5 14.1 09-08-04 alex Y Y Y Y (1)
|
||||
i386/pc/linux-gnu gcc 4.1.2 13~rc1 08-12-05 alex Y Y Y Y (1)
|
||||
@@ -62,17 +66,19 @@ m88k/dg/dgux5.4R3.10 gcc 2.5.8 CVSHEAD 04-03-15 alex Y Y ? ?
|
||||
mipsel/unknown/linux-gnu gcc 4.1.2 18 11-07-05 goetz Y Y N Y (1)
|
||||
mipsel/unknown/linux-gnu gcc 4.4.5 18 11-07-30 goetz Y Y Y Y (1)
|
||||
powerpc/apple/darwin6.5 gcc 3.1 0.7.x-CVS 03-04-23 alex Y Y Y Y
|
||||
powerpc/apple/darwin7.9.0 gcc 3.3 CVSHEAD 06-05-07 fw Y Y Y Y (3)
|
||||
powerpc/apple/darwin7.9.0 gcc 3.3 19.1 12-05-22 goetz Y Y Y Y (3)
|
||||
powerpc/apple/darwin8.11.0 gcc 4.0.1 18 11-07-02 goetz Y Y Y Y (3)
|
||||
powerpc/unknown/linux-gnu gcc 3.3.3 0.8.0 04-05-30 alex Y Y Y Y
|
||||
powerpc/unknown/openbsd3.6 gcc 2.95.3 0.10.0 06-10-08 alex Y Y N Y
|
||||
sparc/sun/solaris2.6 gcc 2.95.3 0.7.x-CVS 03-04-22 alex Y Y Y Y
|
||||
sparc/sun/solaris2.7 gcc 3.3 0.8.0 04-05-30 alex Y Y Y Y
|
||||
sparc/unkn./netbsdelf1.6.1 gcc 2.95.3 0.8.0 04-05-30 alex Y Y Y Y
|
||||
x86_64/unknown/freebsd8.1 gcc 4.2.1 19 12-02-26 alex Y Y Y Y (3)
|
||||
x86_64/apple/darwin12.2.0 gcc 4.2.1 20~rc1 12-11-13 alex Y Y Y Y (3)
|
||||
x86_64/unknown/freebsd8.1 gcc 4.2.1 20~rc1 12-11-13 alex Y Y Y Y (3)
|
||||
x86_64/unkn./freebsd8.1-gnu gcc 4.4.5 19 12-02-26 alex Y Y Y Y (3)
|
||||
x86_64/unknown/linux-gnu gcc 4.4.5 19 12-02-26 alex Y Y Y Y (1)
|
||||
x86_64/unknown/openbsd4.7 gcc 3.3.5 19 12-02-26 alex Y Y Y Y (3)
|
||||
x86_64/unknown/linux-gnu gcc 4.4.5 20~rc1 12-02-26 alex Y Y Y Y (1)
|
||||
x86_64/unknown/openbsd4.7 gcc 3.3.5 20~rc1 12-02-26 alex Y Y Y Y (3)
|
||||
x86_64/unknown/openbsd4.8 gcc 4.2.1 20~rc1 12-11-13 alex Y Y Y Y (3)
|
||||
|
||||
|
||||
Notes
|
||||
|
@@ -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-2012 Alexander Barton and Contributors.
|
||||
ngIRCd is free software and published under the
|
||||
terms of the GNU General Public License.
|
||||
|
||||
@@ -82,11 +81,17 @@ The following <serverflags> are defined at the moment:
|
||||
- H: The server supports the "enhanced server handshake", see section II.2
|
||||
for a detailed description.
|
||||
|
||||
- M: Changing client "metadata" (hostname, real name, ...) using the
|
||||
METADATA command is supported.
|
||||
|
||||
- o: IRC operators are allowed to change channel- and channel-user-modes
|
||||
even if they aren't channel-operator of the affected channel.
|
||||
|
||||
- S: The server supports the SERVICE command (on this link).
|
||||
|
||||
- X: Server supports XOP channel modes (owner, admin, halfop) and supports
|
||||
these user prefixes in CHANINFO commands, for example.
|
||||
|
||||
- Z: Compressed server links are supported by the server.
|
||||
|
||||
Example for a complete <flags> string: "ngircd|0.7.5:CZ".
|
||||
@@ -134,7 +139,7 @@ protocol which allows at max 15 arguments per command).
|
||||
Please see <http://www.irc.org/tech_docs/005.html> for details.
|
||||
|
||||
The information exchanged using ISUPPORT can be used to detect configuration
|
||||
incompatibilities (different maximum nick name length, for example) and
|
||||
incompatibilities (different maximum nickname length, for example) and
|
||||
therefore to disconnect the peer prior to registering it in the network.
|
||||
|
||||
|
||||
@@ -181,3 +186,69 @@ first command sent to the server, even before USER and NICK commands!
|
||||
The <password> must be set in the server configuration file to prevent
|
||||
unauthorized clients to fake their identity; it is an arbitrary string.
|
||||
|
||||
|
||||
II.5 Client character encoding conversion
|
||||
|
||||
Command: CHARCONV
|
||||
Parameters: <client-charset>
|
||||
Used by: registered clients
|
||||
Replies: RPL_IP_CHARCONV, ERR_IP_CHARCONV
|
||||
|
||||
A client can set its character set encoding using the CHARCONV command:
|
||||
after receiving such a command, the server translates all message data
|
||||
received from the client using the set <client-charset> to the server
|
||||
encoding (UTF-8), and all message data which is to be sent to the client
|
||||
from the server encoding (UTF-8) to <client-charset>.
|
||||
|
||||
The list of supported client character sets is implementation dependent.
|
||||
|
||||
If a client sets its <client-charset> to the server encoding (UTF-8),
|
||||
it disables all conversions; the connection behaves as if no CHARCONV
|
||||
command has been sent at all in this session.
|
||||
|
||||
|
||||
II.6 Update client "metadata"
|
||||
|
||||
Command: METADATA
|
||||
Parameters: <target> <key> <value>
|
||||
Used by: servers only
|
||||
|
||||
The METADATA command is used on server-links to update "metadata" information
|
||||
of clients, like the hostname, the info text ("real name"), or the user name.
|
||||
|
||||
The server updates its client database according to the received <key> and
|
||||
<value> parameters, and passes the METADATA command on to all the other
|
||||
servers in the network that support this command (see section II.1 "Register
|
||||
new server link", <serverflag> "M"), even if it doesn't support the given
|
||||
<key> itself: unknown <key> names are ignored silently!
|
||||
|
||||
The following <key> names are defined:
|
||||
|
||||
- "host": the hostname of a client (can't be empty)
|
||||
- "cloakhost": the cloaked hostname of a client
|
||||
- "info": info text ("real name") of a client
|
||||
- "user": the user name of a client (can't be empty)
|
||||
|
||||
|
||||
III. Numerics used by IRC+ Protocol
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The IRC+ protocol uses numerics in the range 800-899 which aren't used by
|
||||
RFC 2812 and hopefully don't clash with other implementations ...
|
||||
|
||||
Numerics 800-849 are used for status and success messages, and numerics
|
||||
850-899 are failure and error messages.
|
||||
|
||||
|
||||
III.1 IRC+ status and success numerics
|
||||
|
||||
801 - RPL_IP_CHARCONV
|
||||
%1 :Client encoding set"
|
||||
|
||||
%1 client character set
|
||||
|
||||
|
||||
III.2 IRC+ failure and error numerics
|
||||
|
||||
851 - ERR_IP_CHARCONV
|
||||
:Can't initialize client encoding
|
||||
|
@@ -9,16 +9,20 @@
|
||||
-- Services.txt --
|
||||
|
||||
|
||||
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.
|
||||
ngIRCd doesn't implement a "special IRC services interface", but services
|
||||
acting as a "regular servers" ("pseudo servers") are supported, either
|
||||
using the IRC protocol as defined in RFC 1459 or RFC 2812.
|
||||
|
||||
Support for Services has been tested using "IRC Services" version 5.x by
|
||||
Andrew Church (<http://achurch.org/services/>), and a Anope 1.9 using a
|
||||
preliminary protocol module for ngIRCd (<http://www.anope.org/>).
|
||||
Support for Services has been tested using
|
||||
- Anope 1.9.8 or later (<http://www.anope.org/>; unreleased!)
|
||||
- Atheme 7.0.2 or later (<http://www.atheme.net>)
|
||||
- "IRC Services" 5.1.x by Andrew Church (<http://achurch.org/services/>)
|
||||
|
||||
This document describes setting up ngIRCd and these services.
|
||||
|
||||
Please let us know if you are successfully using other IRC service packages or
|
||||
which problems you encounter -- thanks!
|
||||
|
||||
|
||||
Setting up ngIRCd
|
||||
~~~~~~~~~~~~~~~~~
|
||||
@@ -40,13 +44,21 @@ Example:
|
||||
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!
|
||||
Anope 1.9.8 or later (<http://www.anope.org/>; unreleased as of 2012-11-10)
|
||||
may be used with ngIRCd using the "ngircd" protocol module.
|
||||
Until Anope 1.9.8 is released, you have to use the sources from the Anope
|
||||
development GIT tree, see <http://sourceforge.net/projects/anope/develop/>!
|
||||
|
||||
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:
|
||||
At least the following settings have to be tweaked, in addition to all the
|
||||
settings marked as required by Anope:
|
||||
|
||||
In conf/services.conf:
|
||||
|
||||
define
|
||||
{
|
||||
name = "services.host"
|
||||
value = "services.irc.net"
|
||||
}
|
||||
|
||||
uplink
|
||||
{
|
||||
@@ -55,12 +67,45 @@ settings marked as required:
|
||||
password = "123abc"
|
||||
}
|
||||
|
||||
serverinfo
|
||||
# Load ngIRCd protocol module
|
||||
module { name = "ngircd" }
|
||||
|
||||
networkinfo
|
||||
{
|
||||
name = "services.irc.net"
|
||||
type = "ngircd"
|
||||
# Must be set to the "MaxNickLength" setting of ngIRCd!
|
||||
nicklen = 9
|
||||
|
||||
chanlen = 50
|
||||
}
|
||||
|
||||
In conf/nickserv.conf:
|
||||
|
||||
nickserv
|
||||
{
|
||||
# not required if you are running ngIRCd with a higher nickname limit
|
||||
# ("MaxNickLength") than 11 characters, but REQUIRED by default!
|
||||
guestnickprefix = "G-"
|
||||
}
|
||||
|
||||
|
||||
Setting up Atheme 7.0.2 or later
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Atheme 7.0.2 or later (<http://www.atheme.net>) may be used with ngIRCd using
|
||||
the "ngircd" protocol module.
|
||||
|
||||
The following settings need to be in atheme.conf:
|
||||
|
||||
loadmodule "modules/protocol/ngircd";
|
||||
|
||||
uplink "server.irc.net" {
|
||||
password = "123abc";
|
||||
port = 6667;
|
||||
};
|
||||
|
||||
The documentation of Atheme can be found in the doc/ directory of the
|
||||
Atheme source distribution.
|
||||
|
||||
|
||||
Setting up IRC Services 5.1.x
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
@@ -91,7 +136,3 @@ In modules.conf:
|
||||
|
||||
The documentation of IRC Services can be found here:
|
||||
<http://www.ircservices.za.net/docs/>
|
||||
|
||||
|
||||
Please let us know if you are successfully using other IRC service packages or
|
||||
which problems you encounter, thanks!
|
||||
|
@@ -95,11 +95,15 @@
|
||||
# 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).
|
||||
# Maximum length of an user nickname (Default: 9, as in RFC 2812).
|
||||
# Please note that all servers in an IRC network MUST use the same
|
||||
# maximum nick name length!
|
||||
# maximum nickname length!
|
||||
;MaxNickLength = 9
|
||||
|
||||
# Maximum number of channels returned in response to a /list
|
||||
# command (0: unlimited):
|
||||
;MaxListSize = 100
|
||||
|
||||
# After <PingTimeout> seconds of inactivity the server will send a
|
||||
# PING to the peer to test whether it is alive or not.
|
||||
;PingTimeout = 120
|
||||
@@ -125,11 +129,19 @@
|
||||
;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
|
||||
# Use %x to add the hashed value of the original hostname.
|
||||
;CloakHost = cloaked.host
|
||||
|
||||
# Set every clients' user name to their nick name
|
||||
# Use this hostname for hostname cloaking on clients that have the
|
||||
# user mode "+x" set, instead of the name of the server.
|
||||
# Use %x to add the hashed value of the original hostname.
|
||||
;CloakHostModeX = cloaked.user
|
||||
|
||||
# The Salt for cloaked hostname hashing. When undefined a random
|
||||
# hash is generated after each server start.
|
||||
;CloakHostSalt = abcdefghijklmnopqrstuvwxyz
|
||||
|
||||
# Set every clients' user name to their nickname
|
||||
;CloakUserToNick = yes
|
||||
|
||||
# Try to connect to other IRC servers using IPv4 and IPv6, if possible.
|
||||
@@ -157,6 +169,9 @@
|
||||
# they are not(!) channel-operators?
|
||||
;OperCanUseMode = no
|
||||
|
||||
# Should IRC Operators get AutoOp (+o) in persistent (+P) channels?
|
||||
;OperChanPAutoOp = yes
|
||||
|
||||
# Mask IRC Operator mode requests as if they were coming from the
|
||||
# server? (This is a compatibility hack for ircd-irc2 servers)
|
||||
;OperServerMode = no
|
||||
@@ -226,7 +241,7 @@
|
||||
# [Operator] sections are used to define IRC Operators. There may be
|
||||
# more than one [Operator] block, one for each local operator.
|
||||
|
||||
# ID of the operator (may be different of the nick name)
|
||||
# ID of the operator (may be different of the nickname)
|
||||
;Name = TheOper
|
||||
|
||||
# Password of the IRC operator
|
||||
@@ -289,15 +304,16 @@
|
||||
# Connect to the remote server using TLS/SSL (Default: false)
|
||||
;SSLConnect = yes
|
||||
|
||||
# Define a (case insensitive) mask matching nick names that should be
|
||||
# treated as IRC services when introduced via this remote server.
|
||||
# Define a (case insensitive) list of masks matching nicknames that
|
||||
# should be treated as IRC services when introduced via this remote
|
||||
# server, separated by commas (",").
|
||||
# REGULAR SERVERS DON'T NEED this parameter, so leave it empty
|
||||
# (which is the default).
|
||||
# When you are connecting IRC services which mask as a IRC server
|
||||
# and which use "virtual users" to communicate with, for example
|
||||
# "NickServ" and "ChanServ", you should set this parameter to
|
||||
# something like "*Serv".
|
||||
;ServiceMask = *Serv
|
||||
# something like "*Serv" or "NickServ,ChanServ,XyzServ".
|
||||
;ServiceMask = *Serv,Global
|
||||
|
||||
[Server]
|
||||
# More [Server] sections, if you like ...
|
||||
|
@@ -1,15 +1,12 @@
|
||||
#
|
||||
# ngIRCd -- The Next Generation IRC Daemon
|
||||
# Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
|
||||
# Copyright (c)2001-2012 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
|
||||
# herausgegeben, weitergeben und/oder modifizieren, entweder unter Version 2
|
||||
# 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: Makefile.am,v 1.6 2006/12/25 16:13:26 alex Exp $
|
||||
# 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.
|
||||
#
|
||||
|
||||
TEMPLATE_MANS = ngircd.conf.5.tmpl ngircd.8.tmpl
|
||||
@@ -17,10 +14,10 @@ TEMPLATE_MANS = ngircd.conf.5.tmpl ngircd.8.tmpl
|
||||
SUFFIXES = .tmpl .
|
||||
|
||||
.tmpl:
|
||||
sed \
|
||||
-e s@:SBINDIR:@${sbindir}@ \
|
||||
-e s@:BINDIR:@${bindir}@ \
|
||||
-e s@:ETCDIR:@${sysconfdir}@ \
|
||||
$(AM_V_GEN)sed \
|
||||
-e "s@:SBINDIR:@${sbindir}@" \
|
||||
-e "s@:BINDIR:@${bindir}@" \
|
||||
-e "s@:ETCDIR:@${sysconfdir}@" \
|
||||
<$< >$@
|
||||
|
||||
man_MANS = ngircd.conf.5 ngircd.8
|
||||
|
@@ -1,30 +1,35 @@
|
||||
.\"
|
||||
.\" ngircd(8) manual page template
|
||||
.\"
|
||||
.TH ngircd 8 "Mar 2012" ngircd "ngIRCd Manual"
|
||||
.TH ngircd 8 "Oct 2012" ngIRCd "ngIRCd Manual"
|
||||
.SH NAME
|
||||
ngIRCd \- the next generation IRC daemon
|
||||
ngIRCd \- the "next generation" IRC daemon
|
||||
.SH SYNOPSIS
|
||||
.B ngircd [
|
||||
.B ngircd
|
||||
[
|
||||
.I Options
|
||||
.B ]
|
||||
]
|
||||
.SH DESCRIPTION
|
||||
.BR ngIRCd
|
||||
is a free open source daemon for the Internet Relay Chat (IRC),
|
||||
developed under the GNU General Public License (GPL).
|
||||
is a free, portable and lightweight Internet Relay Chat server for small
|
||||
or private networks, developed under the GNU General Public License (GPL).
|
||||
It is easy to configure, can cope with dynamic IP addresses, and supports
|
||||
IPv6, SSL-protected connections as well as PAM for authentication.
|
||||
It is written from scratch and not based on the original IRCd.
|
||||
.PP
|
||||
It's written from scratch and is not based upon the original IRCd like
|
||||
many others. It is easy to configure, supports server links (even with
|
||||
original ircd's) and runs on hosts with changing IP addresses (such as
|
||||
dial-in networks).
|
||||
The name ngIRCd means
|
||||
.IR "next generation IRC daemon",
|
||||
which is a little bit exaggerated:
|
||||
.IR "lightweight Internet Relay Chat server"
|
||||
most probably would have been a better name :-)
|
||||
.PP
|
||||
Currently supported platforms include AIX, A/UX, FreeBSD, HP-UX, IRIX,
|
||||
Linux, Mac OS X, NetBSD, OpenBSD, Solaris, and Windows with Cygwin.
|
||||
.PP
|
||||
As ngIRCd relies on UNIX standards and uses GNU automake and GNU autoconf
|
||||
there are good chances that it also supports other UNIX-based operating
|
||||
systems as well. By default, ngIRCd writes diagnostic and informational messages using
|
||||
the syslog mechanism.
|
||||
systems as well. By default, ngIRCd writes diagnostic and informational
|
||||
messages using the syslog mechanism.
|
||||
.SH OPTIONS
|
||||
The default behavior of
|
||||
.BR ngircd
|
||||
|
@@ -1,7 +1,7 @@
|
||||
.\"
|
||||
.\" ngircd.conf(5) manual page template
|
||||
.\"
|
||||
.TH ngircd.conf 5 "Mar 2012" ngircd "ngIRCd Manual"
|
||||
.TH ngircd.conf 5 "Nov 2012" ngIRCd "ngIRCd Manual"
|
||||
.SH NAME
|
||||
ngircd.conf \- configuration file of ngIRCd
|
||||
.SH SYNOPSIS
|
||||
@@ -178,10 +178,13 @@ 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
|
||||
Maximum length of an user nickname (Default: 9, as in RFC 2812). Please
|
||||
note that all servers in an IRC network MUST use the same maximum nickname
|
||||
length!
|
||||
.TP
|
||||
\fBMaxListSize\fR (number)
|
||||
Maximum number of channels returned in response to a LIST command. Default: 100.
|
||||
.TP
|
||||
\fBPingTimeout\fR (number)
|
||||
After <PingTimeout> seconds of inactivity the server will send a PING to
|
||||
the peer to test whether it is alive or not. Default: 120.
|
||||
@@ -212,16 +215,19 @@ For this to work the server must have been started with root privileges!
|
||||
.TP
|
||||
\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
|
||||
don't change. Use %x to add the hashed value of the original hostname.
|
||||
.TP
|
||||
\fBCloakHostModeX\fR (string)
|
||||
Use this hostname for hostname cloaking on clients that have the user mode
|
||||
"+x" set, instead of the name of the server. Default: empty, use the name
|
||||
of the server. Use %x to add the hashed value of the original hostname
|
||||
.TP
|
||||
\fBCloakHostSalt\fR (string)
|
||||
The Salt for cloaked hostname hashing. When undefined a random hash is
|
||||
generated after each server start.
|
||||
.TP
|
||||
\fBCloakUserToNick\fR (boolean)
|
||||
Set every clients' user name to their nick name and hide the one supplied
|
||||
Set every clients' user name to their nickname and hide the one supplied
|
||||
by the IRC client. Default: no.
|
||||
.TP
|
||||
\fBConnectIPv4\fR (boolean)
|
||||
@@ -265,6 +271,10 @@ while connecting. Default: no.
|
||||
Should IRC Operators be allowed to use the MODE command even if they are
|
||||
not(!) channel-operators? Default: no.
|
||||
.TP
|
||||
\fBOperChanPAutoOp\fR (boolean)
|
||||
Should IRC Operators get AutoOp (+o) in persistent (+P) channels?
|
||||
Default: yes.
|
||||
.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
|
||||
@@ -359,7 +369,7 @@ sections are used to define IRC Operators. There may be more than one
|
||||
block, one for each local operator.
|
||||
.TP
|
||||
\fBName\fR (string)
|
||||
ID of the operator (may be different of the nick name).
|
||||
ID of the operator (may be different of the nickname).
|
||||
.TP
|
||||
\fBPassword\fR (string)
|
||||
Password of the IRC operator.
|
||||
@@ -419,14 +429,16 @@ You can use the IRC Operator command CONNECT later on to create the link.
|
||||
Connect to the remote server using TLS/SSL. Default: false.
|
||||
.TP
|
||||
\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).
|
||||
Define a (case insensitive) list of masks matching nicknames that should be
|
||||
treated as IRC services when introduced via this remote server, separated
|
||||
by commas (","). REGULAR SERVERS DON'T NEED this parameter, so leave it empty
|
||||
(which is the default).
|
||||
.PP
|
||||
.RS
|
||||
When you are connecting IRC services which mask as a IRC server and which use
|
||||
"virtual users" to communicate with, for example "NickServ" and "ChanServ",
|
||||
you should set this parameter to something like "*Serv".
|
||||
you should set this parameter to something like "*Serv", "*Serv,OtherNick",
|
||||
or "NickServ,ChanServ,XyzServ".
|
||||
.SH [CHANNEL]
|
||||
Pre-defined channels can be configured in
|
||||
.I [Channel]
|
||||
|
1
src/ipaddr/.gitignore
vendored
Normal file
1
src/ipaddr/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
Makefile.am
|
@@ -1,14 +0,0 @@
|
||||
AUTOMAKE_OPTIONS = ansi2knr
|
||||
|
||||
INCLUDES = -I$(srcdir)/../portab
|
||||
|
||||
noinst_LIBRARIES = libngipaddr.a
|
||||
|
||||
libngipaddr_a_SOURCES = ng_ipaddr.c
|
||||
|
||||
noinst_HEADERS = ng_ipaddr.h
|
||||
|
||||
maintainer-clean-local:
|
||||
rm -f Makefile Makefile.in
|
||||
|
||||
# -eof-
|
21
src/ipaddr/Makefile.ng
Normal file
21
src/ipaddr/Makefile.ng
Normal file
@@ -0,0 +1,21 @@
|
||||
#
|
||||
# ipaddr/Makefile.am
|
||||
# (c) 2008 Florian Westphal <fw@strlen.de>, public domain.
|
||||
#
|
||||
|
||||
__ng_Makefile_am_template__
|
||||
|
||||
EXTRA_DIST = Makefile.ng
|
||||
|
||||
AM_CPPFLAGS = -I$(srcdir)/../portab
|
||||
|
||||
noinst_LIBRARIES = libngipaddr.a
|
||||
|
||||
libngipaddr_a_SOURCES = ng_ipaddr.c
|
||||
|
||||
noinst_HEADERS = ng_ipaddr.h
|
||||
|
||||
maintainer-clean-local:
|
||||
rm -f Makefile Makefile.in Makefile.am
|
||||
|
||||
# -eof-
|
@@ -49,8 +49,8 @@ ng_ipaddr_init(ng_ipaddr_t *addr, const char *ip_str, UINT16 port)
|
||||
if (ret != 0)
|
||||
return false;
|
||||
|
||||
assert(sizeof(*addr) >= res0->ai_addrlen);
|
||||
if (sizeof(*addr) >= res0->ai_addrlen)
|
||||
assert(sizeof(*addr) >= (size_t)res0->ai_addrlen);
|
||||
if (sizeof(*addr) >= (size_t)res0->ai_addrlen)
|
||||
memcpy(addr, res0->ai_addr, res0->ai_addrlen);
|
||||
else
|
||||
ret = -1;
|
||||
|
2
src/ngircd/.gitignore
vendored
2
src/ngircd/.gitignore
vendored
@@ -1,3 +1,5 @@
|
||||
Makefile.am
|
||||
check-help
|
||||
check-version
|
||||
ngircd
|
||||
ngircd.exe
|
||||
|
@@ -1,6 +1,6 @@
|
||||
#
|
||||
# ngIRCd -- The Next Generation IRC Daemon
|
||||
# Copyright (c)2001-2010 Alexander Barton (alex@barton.de)
|
||||
# Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@@ -9,36 +9,107 @@
|
||||
# Please read the file COPYING, README and AUTHORS for more information.
|
||||
#
|
||||
|
||||
AUTOMAKE_OPTIONS = ../portab/ansi2knr
|
||||
__ng_Makefile_am_template__
|
||||
|
||||
INCLUDES = -I$(srcdir)/../portab -I$(srcdir)/../tool -I$(srcdir)/../ipaddr
|
||||
EXTRA_DIST = Makefile.ng
|
||||
|
||||
AM_CPPFLAGS = -I$(srcdir)/../portab -I$(srcdir)/../tool -I$(srcdir)/../ipaddr
|
||||
|
||||
LINTARGS = -weak -warnunixlib +unixlib -booltype BOOLEAN \
|
||||
-varuse -retvalother -emptyret -unrecog
|
||||
|
||||
sbin_PROGRAMS = ngircd
|
||||
|
||||
ngircd_SOURCES = ngircd.c array.c channel.c class.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 resolve.c sighandlers.c
|
||||
ngircd_SOURCES = \
|
||||
ngircd.c \
|
||||
array.c \
|
||||
channel.c \
|
||||
class.c \
|
||||
client.c \
|
||||
client-cap.c \
|
||||
conf.c \
|
||||
conn.c \
|
||||
conn-encoding.c \
|
||||
conn-func.c \
|
||||
conn-ssl.c \
|
||||
conn-zip.c \
|
||||
hash.c \
|
||||
io.c \
|
||||
irc.c \
|
||||
irc-cap.c \
|
||||
irc-channel.c \
|
||||
irc-encoding.c \
|
||||
irc-info.c \
|
||||
irc-login.c \
|
||||
irc-metadata.c \
|
||||
irc-mode.c \
|
||||
irc-op.c \
|
||||
irc-oper.c \
|
||||
irc-server.c \
|
||||
irc-write.c \
|
||||
lists.c \
|
||||
log.c \
|
||||
login.c \
|
||||
match.c \
|
||||
numeric.c \
|
||||
op.c \
|
||||
pam.c \
|
||||
parse.c \
|
||||
proc.c \
|
||||
resolve.c \
|
||||
sighandlers.c
|
||||
|
||||
ngircd_LDFLAGS = -L../portab -L../tool -L../ipaddr
|
||||
|
||||
ngircd_LDADD = -lngportab -lngtool -lngipaddr
|
||||
|
||||
noinst_HEADERS = ngircd.h array.h channel.h class.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 resolve.h sighandlers.h defines.h messages.h
|
||||
noinst_HEADERS = \
|
||||
ngircd.h \
|
||||
array.h \
|
||||
channel.h \
|
||||
class.h \
|
||||
client.h \
|
||||
client-cap.h \
|
||||
conf.h \
|
||||
conf-ssl.h \
|
||||
conn.h \
|
||||
conn-encoding.h \
|
||||
conn-func.h \
|
||||
conn-ssl.h \
|
||||
conn-zip.h \
|
||||
defines.h \
|
||||
hash.h \
|
||||
io.h \
|
||||
irc.h \
|
||||
irc-cap.h \
|
||||
irc-channel.h \
|
||||
irc-encoding.h \
|
||||
irc-info.h \
|
||||
irc-login.h \
|
||||
irc-metadata.h \
|
||||
irc-mode.h \
|
||||
irc-op.h \
|
||||
irc-oper.h \
|
||||
irc-server.h \
|
||||
irc-write.h \
|
||||
lists.h \
|
||||
log.h \
|
||||
login.h \
|
||||
match.h \
|
||||
messages.h \
|
||||
numeric.h \
|
||||
op.h \
|
||||
pam.h \
|
||||
parse.h \
|
||||
proc.h \
|
||||
resolve.h \
|
||||
sighandlers.h
|
||||
|
||||
clean-local:
|
||||
rm -f check-version check-help lint.out
|
||||
|
||||
maintainer-clean-local:
|
||||
rm -f Makefile Makefile.in
|
||||
rm -f Makefile Makefile.in Makefile.am
|
||||
|
||||
check-version: Makefile
|
||||
echo "#!/bin/sh" > check-version
|
||||
@@ -57,7 +128,7 @@ lint:
|
||||
for f in *.c; do \
|
||||
echo "checking $$f ..."; \
|
||||
splint $$f $(LINTARGS) -I$(srcdir) -I$(srcdir)/.. \
|
||||
$(INCLUDES) $(AM_CFLAGS) >lint.out 2>&1; \
|
||||
$(AM_CPPFLAGS) $(AM_CFLAGS) >lint.out 2>&1; \
|
||||
grep "no warnings" lint.out > /dev/null 2>&1; \
|
||||
if [ $$? -ne 0 ]; then \
|
||||
waswarning=1; \
|
@@ -66,16 +66,8 @@ static void Set_KeyFile PARAMS((CHANNEL *Chan, const char *KeyFile));
|
||||
GLOBAL void
|
||||
Channel_Init( void )
|
||||
{
|
||||
CHANNEL *sc;
|
||||
|
||||
My_Channels = NULL;
|
||||
My_Cl2Chan = NULL;
|
||||
|
||||
sc = Channel_Create("&SERVER");
|
||||
if (sc) {
|
||||
Channel_SetModes(sc, "mnPt");
|
||||
Channel_SetTopic(sc, Client_ThisServer(), "Server Messages");
|
||||
}
|
||||
} /* Channel_Init */
|
||||
|
||||
|
||||
@@ -103,11 +95,12 @@ Channel_GetListInvites(CHANNEL *c)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generate predefined persistent channels and &SERVER
|
||||
*/
|
||||
GLOBAL void
|
||||
Channel_InitPredefined( void )
|
||||
{
|
||||
/* Generate predefined persistent channels */
|
||||
|
||||
CHANNEL *new_chan;
|
||||
const struct Conf_Channel *conf_chan;
|
||||
const char *c;
|
||||
@@ -160,6 +153,18 @@ Channel_InitPredefined( void )
|
||||
}
|
||||
if (channel_count)
|
||||
array_free(&Conf_Channels);
|
||||
|
||||
/* Make sure the local &SERVER channel exists */
|
||||
if (!Channel_Search("&SERVER")) {
|
||||
new_chan = Channel_Create("&SERVER");
|
||||
if (new_chan) {
|
||||
Channel_SetModes(new_chan, "mnPt");
|
||||
Channel_SetTopic(new_chan, Client_ThisServer(),
|
||||
"Server Messages");
|
||||
} else
|
||||
Log(LOG_ERR, "Failed to create \"&SERVER\" channel!");
|
||||
} else
|
||||
LogDebug("Required channel \"&SERVER\" already exists, ok.");
|
||||
} /* Channel_InitPredefined */
|
||||
|
||||
|
||||
@@ -294,6 +299,8 @@ Channel_Kick(CLIENT *Peer, CLIENT *Target, CLIENT *Origin, const char *Name,
|
||||
const char *Reason )
|
||||
{
|
||||
CHANNEL *chan;
|
||||
char *ptr, *target_modes;
|
||||
bool can_kick = false;
|
||||
|
||||
assert(Peer != NULL);
|
||||
assert(Target != NULL);
|
||||
@@ -314,14 +321,7 @@ Channel_Kick(CLIENT *Peer, CLIENT *Target, CLIENT *Origin, const char *Name,
|
||||
/* Check that user is on the specified channel */
|
||||
if (!Channel_IsMemberOf(chan, Origin)) {
|
||||
IRC_WriteStrClient( Origin, ERR_NOTONCHANNEL_MSG,
|
||||
Client_ID(Origin), Name);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Check if user has operator status */
|
||||
if (!strchr(Channel_UserModes(chan, Origin), 'o')) {
|
||||
IRC_WriteStrClient(Origin, ERR_CHANOPRIVSNEEDED_MSG,
|
||||
Client_ID(Origin), Name);
|
||||
Client_ID(Origin), Name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -333,6 +333,62 @@ Channel_Kick(CLIENT *Peer, CLIENT *Target, CLIENT *Origin, const char *Name,
|
||||
return;
|
||||
}
|
||||
|
||||
if(Client_Type(Peer) == CLIENT_USER) {
|
||||
/* Channel mode 'Q' and user mode 'q' on target: nobody but
|
||||
* IRC Operators and servers can kick the target user */
|
||||
if ((strchr(Channel_Modes(chan), 'Q')
|
||||
|| Client_HasMode(Target, 'q')
|
||||
|| Client_Type(Target) == CLIENT_SERVICE)
|
||||
&& !Client_HasMode(Origin, 'o')) {
|
||||
IRC_WriteStrClient(Origin, ERR_KICKDENY_MSG,
|
||||
Client_ID(Origin), Name,
|
||||
Client_ID(Target));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Check if client has the rights to kick target */
|
||||
ptr = Channel_UserModes(chan, Peer);
|
||||
target_modes = Channel_UserModes(chan, Target);
|
||||
while(*ptr) {
|
||||
/* Owner can kick everyone */
|
||||
if ( *ptr == 'q') {
|
||||
can_kick = true;
|
||||
break;
|
||||
}
|
||||
/* Admin can't kick owner */
|
||||
if ( *ptr == 'a' ) {
|
||||
if (!strchr(target_modes, 'q')) {
|
||||
can_kick = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Op can't kick owner | admin */
|
||||
if ( *ptr == 'o' ) {
|
||||
if (!strchr(target_modes, 'q') &&
|
||||
!strchr(target_modes, 'a')) {
|
||||
can_kick = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Half Op can't kick owner | admin | op */
|
||||
if ( *ptr == 'h' ) {
|
||||
if (!strchr(target_modes, 'q') &&
|
||||
!strchr(target_modes, 'a') &&
|
||||
!strchr(target_modes, 'o')) {
|
||||
can_kick = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ptr++;
|
||||
}
|
||||
|
||||
if(!can_kick) {
|
||||
IRC_WriteStrClient(Origin, ERR_CHANOPPRIVTOOLOW_MSG,
|
||||
Client_ID(Origin), Name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Kick Client from channel */
|
||||
Remove_Client( REMOVE_KICK, chan, Target, Origin, Reason, true);
|
||||
} /* Channel_Kick */
|
||||
@@ -807,9 +863,9 @@ Channel_SetMaxUsers(CHANNEL *Chan, unsigned long Count)
|
||||
static bool
|
||||
Can_Send_To_Channel(CHANNEL *Chan, CLIENT *From)
|
||||
{
|
||||
bool is_member, has_voice, is_op;
|
||||
bool is_member, has_voice, is_halfop, is_op, is_chanadmin, is_owner;
|
||||
|
||||
is_member = has_voice = is_op = false;
|
||||
is_member = has_voice = is_halfop = is_op = is_chanadmin = is_owner = false;
|
||||
|
||||
/* The server itself always can send messages :-) */
|
||||
if (Client_ThisServer() == From)
|
||||
@@ -819,8 +875,14 @@ Can_Send_To_Channel(CHANNEL *Chan, CLIENT *From)
|
||||
is_member = true;
|
||||
if (strchr(Channel_UserModes(Chan, From), 'v'))
|
||||
has_voice = true;
|
||||
if (strchr(Channel_UserModes(Chan, From), 'h'))
|
||||
is_halfop = true;
|
||||
if (strchr(Channel_UserModes(Chan, From), 'o'))
|
||||
is_op = true;
|
||||
if (strchr(Channel_UserModes(Chan, From), 'a'))
|
||||
is_chanadmin = true;
|
||||
if (strchr(Channel_UserModes(Chan, From), 'q'))
|
||||
is_owner = true;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -832,7 +894,11 @@ Can_Send_To_Channel(CHANNEL *Chan, CLIENT *From)
|
||||
if (strchr(Channel_Modes(Chan), 'n') && !is_member)
|
||||
return false;
|
||||
|
||||
if (is_op || has_voice)
|
||||
if (strchr(Channel_Modes(Chan), 'M') && !Client_HasMode(From, 'R')
|
||||
&& !Client_HasMode(From, 'o'))
|
||||
return false;
|
||||
|
||||
if (has_voice || is_halfop || is_op || is_chanadmin || is_owner)
|
||||
return true;
|
||||
|
||||
if (strchr(Channel_Modes(Chan), 'm'))
|
||||
@@ -852,7 +918,11 @@ Channel_Write(CHANNEL *Chan, CLIENT *From, CLIENT *Client, const char *Command,
|
||||
if (!Can_Send_To_Channel(Chan, From)) {
|
||||
if (! SendErrors)
|
||||
return CONNECTED; /* no error, see RFC 2812 */
|
||||
return IRC_WriteStrClient(From, ERR_CANNOTSENDTOCHAN_MSG,
|
||||
if (strchr(Channel_Modes(Chan), 'M'))
|
||||
return IRC_WriteStrClient(From, ERR_NEEDREGGEDNICK_MSG,
|
||||
Client_ID(From), Channel_Name(Chan));
|
||||
else
|
||||
return IRC_WriteStrClient(From, ERR_CANNOTSENDTOCHAN_MSG,
|
||||
Client_ID(From), Channel_Name(Chan));
|
||||
}
|
||||
|
||||
@@ -1187,64 +1257,6 @@ 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 )
|
||||
{
|
||||
|
73
src/ngircd/client-cap.c
Normal file
73
src/ngircd/client-cap.c
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#define __client_cap_c__
|
||||
|
||||
#include "portab.h"
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Functions to deal with IRC Capabilities
|
||||
*/
|
||||
|
||||
#include "imp.h"
|
||||
#include <assert.h>
|
||||
|
||||
#include "defines.h"
|
||||
#include "conn.h"
|
||||
#include "client.h"
|
||||
#include "log.h"
|
||||
|
||||
#include "exp.h"
|
||||
#include "client-cap.h"
|
||||
|
||||
GLOBAL int
|
||||
Client_Cap(CLIENT *Client)
|
||||
{
|
||||
assert (Client != NULL);
|
||||
|
||||
return Client->capabilities;
|
||||
}
|
||||
|
||||
GLOBAL void
|
||||
Client_CapSet(CLIENT *Client, int Cap)
|
||||
{
|
||||
assert(Client != NULL);
|
||||
assert(Cap >= 0);
|
||||
|
||||
Client->capabilities = Cap;
|
||||
LogDebug("Set new capability of \"%s\" to %d.",
|
||||
Client_ID(Client), Client->capabilities);
|
||||
}
|
||||
|
||||
GLOBAL void
|
||||
Client_CapAdd(CLIENT *Client, int Cap)
|
||||
{
|
||||
assert(Client != NULL);
|
||||
assert(Cap > 0);
|
||||
|
||||
Client->capabilities |= Cap;
|
||||
LogDebug("Add capability %d, new capability of \"%s\" is %d.",
|
||||
Cap, Client_ID(Client), Client->capabilities);
|
||||
}
|
||||
|
||||
GLOBAL void
|
||||
Client_CapDel(CLIENT *Client, int Cap)
|
||||
{
|
||||
assert(Client != NULL);
|
||||
assert(Cap > 0);
|
||||
|
||||
Client->capabilities &= ~Cap;
|
||||
LogDebug("Delete capability %d, new capability of \"%s\" is %d.",
|
||||
Cap, Client_ID(Client), Client->capabilities);
|
||||
}
|
||||
|
||||
/* -eof- */
|
31
src/ngircd/client-cap.h
Normal file
31
src/ngircd/client-cap.h
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
* Please read the file COPYING, README and AUTHORS for more information.
|
||||
*/
|
||||
|
||||
#ifndef __client_cap_h__
|
||||
#define __client_cap_h__
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Functions to deal with IRC Capabilities (header)
|
||||
*/
|
||||
|
||||
#define CLIENT_CAP_PENDING 1 /* Capability negotiation pending */
|
||||
#define CLIENT_CAP_SUPPORTED 2 /* Client supports IRC capabilities */
|
||||
|
||||
#define CLIENT_CAP_MULTI_PREFIX 4 /* multi-prefix */
|
||||
|
||||
GLOBAL int Client_Cap PARAMS((CLIENT *Client));
|
||||
|
||||
GLOBAL void Client_CapSet PARAMS((CLIENT *Client, int Cap));
|
||||
GLOBAL void Client_CapAdd PARAMS((CLIENT *Client, int Cap));
|
||||
GLOBAL void Client_CapDel PARAMS((CLIENT *Client, int Cap));
|
||||
|
||||
#endif
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* Copyright (c)2001-2010 Alexander Barton (alex@barton.de)
|
||||
* Copyright (c)2001-2012 Alexander Barton (alex@barton.de)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "ngircd.h"
|
||||
#include "channel.h"
|
||||
#include "conf.h"
|
||||
#include "conn-func.h"
|
||||
#include "hash.h"
|
||||
#include "irc-write.h"
|
||||
#include "log.h"
|
||||
@@ -69,6 +70,8 @@ static CLIENT *Init_New_Client PARAMS((CONN_ID Idx, CLIENT *Introducer,
|
||||
static void Destroy_UserOrService PARAMS((CLIENT *Client,const char *Txt, const char *FwdMsg,
|
||||
bool SendQuit));
|
||||
|
||||
static void cb_introduceClient PARAMS((CLIENT *Client, CLIENT *Prefix,
|
||||
void *i));
|
||||
|
||||
GLOBAL void
|
||||
Client_Init( void )
|
||||
@@ -328,9 +331,15 @@ Client_SetHostname( CLIENT *Client, const char *Hostname )
|
||||
assert(Hostname != NULL);
|
||||
|
||||
if (strlen(Conf_CloakHost)) {
|
||||
char cloak[GETID_LEN];
|
||||
|
||||
strlcpy(cloak, Hostname, GETID_LEN);
|
||||
strlcat(cloak, Conf_CloakHostSalt, GETID_LEN);
|
||||
snprintf(cloak, GETID_LEN, Conf_CloakHost, Hash(cloak));
|
||||
|
||||
LogDebug("Updating hostname of \"%s\": \"%s\" -> \"%s\"",
|
||||
Client_ID(Client), Client->host, Conf_CloakHost);
|
||||
strlcpy(Client->host, Conf_CloakHost, sizeof(Client->host));
|
||||
Client_ID(Client), Client->host, cloak);
|
||||
strlcpy(Client->host, cloak, sizeof(Client->host));
|
||||
} else {
|
||||
LogDebug("Updating hostname of \"%s\": \"%s\" -> \"%s\"",
|
||||
Client_ID(Client), Client->host, Hostname);
|
||||
@@ -431,18 +440,6 @@ Client_SetFlags( CLIENT *Client, const char *Flags )
|
||||
} /* Client_SetFlags */
|
||||
|
||||
|
||||
GLOBAL void
|
||||
Client_SetPassword( CLIENT *Client, const char *Pwd )
|
||||
{
|
||||
/* set password sent by client */
|
||||
|
||||
assert( Client != NULL );
|
||||
assert( Pwd != NULL );
|
||||
|
||||
strlcpy(Client->pwd, Pwd, sizeof(Client->pwd));
|
||||
} /* Client_SetPassword */
|
||||
|
||||
|
||||
GLOBAL void
|
||||
Client_SetAway( CLIENT *Client, const char *Txt )
|
||||
{
|
||||
@@ -674,7 +671,6 @@ Client_OrigUser(CLIENT *Client) {
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Return the hostname of a client.
|
||||
* @param Client Pointer to client structure
|
||||
@@ -685,33 +681,88 @@ Client_Hostname(CLIENT *Client)
|
||||
{
|
||||
assert (Client != NULL);
|
||||
return Client->host;
|
||||
} /* Client_Hostname */
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get potentially cloaked hostname of a client.
|
||||
* If the client has not enabled cloaking, the real hostname is used.
|
||||
* @param Client Pointer to client structure
|
||||
* @return Pointer to client hostname
|
||||
* Return the cloaked hostname of a client, if set.
|
||||
* @param Client Pointer to the client structure.
|
||||
* @return Pointer to the cloaked hostname or NULL if not set.
|
||||
*/
|
||||
GLOBAL char *
|
||||
Client_HostnameCloaked(CLIENT *Client)
|
||||
{
|
||||
assert(Client != NULL);
|
||||
if (Client_HasMode(Client, 'x'))
|
||||
return Client_ID(Client->introducer);
|
||||
else
|
||||
return Client_Hostname(Client);
|
||||
} /* Client_HostnameCloaked */
|
||||
|
||||
return Client->cloaked;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get (potentially cloaked) hostname of a client to display it to other users.
|
||||
*
|
||||
* If the client has not enabled cloaking, the real hostname is used.
|
||||
* Please note that this function uses a global static buffer, so you can't
|
||||
* nest invocations without overwriting earlier results!
|
||||
*
|
||||
* @param Client Pointer to client structure
|
||||
* @return Pointer to client hostname
|
||||
*/
|
||||
GLOBAL char *
|
||||
Client_Password( CLIENT *Client )
|
||||
Client_HostnameDisplayed(CLIENT *Client)
|
||||
{
|
||||
assert( Client != NULL );
|
||||
return Client->pwd;
|
||||
} /* Client_Password */
|
||||
assert(Client != NULL);
|
||||
|
||||
/* Client isn't cloaked at all, return real hostname: */
|
||||
if (!Client_HasMode(Client, 'x'))
|
||||
return Client_Hostname(Client);
|
||||
|
||||
/* Use an already saved cloaked hostname, if there is one */
|
||||
if (Client->cloaked[0])
|
||||
return Client->cloaked;
|
||||
|
||||
Client_UpdateCloakedHostname(Client, NULL, NULL);
|
||||
return Client->cloaked;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update (and generate, if necessary) the cloaked hostname of a client.
|
||||
*
|
||||
* The newly set cloaked hostname is announced in the network using METADATA
|
||||
* commands to peers that support this feature.
|
||||
*
|
||||
* @param Client The client of which the cloaked hostname should be updated.
|
||||
* @param Origin The originator of the hostname change, or NULL if this server.
|
||||
* @param Hostname The new cloaked hostname, or NULL if it should be generated.
|
||||
*/
|
||||
GLOBAL void
|
||||
Client_UpdateCloakedHostname(CLIENT *Client, CLIENT *Origin,
|
||||
const char *Hostname)
|
||||
{
|
||||
static char Cloak_Buffer[CLIENT_HOST_LEN];
|
||||
|
||||
assert(Client != NULL);
|
||||
if (!Origin)
|
||||
Origin = Client_ThisServer();
|
||||
|
||||
if (!Hostname) {
|
||||
/* Generate new cloaked hostname */
|
||||
if (*Conf_CloakHostModeX) {
|
||||
strlcpy(Cloak_Buffer, Client->host, CLIENT_HOST_LEN);
|
||||
strlcat(Cloak_Buffer, Conf_CloakHostSalt,
|
||||
CLIENT_HOST_LEN);
|
||||
snprintf(Client->cloaked, sizeof(Client->cloaked),
|
||||
Conf_CloakHostModeX, Hash(Cloak_Buffer));
|
||||
} else
|
||||
strlcpy(Client->cloaked, Client_ID(Client->introducer),
|
||||
sizeof(Client->cloaked));
|
||||
} else
|
||||
strlcpy(Client->cloaked, Hostname, sizeof(Client->cloaked));
|
||||
LogDebug("Cloaked hostname of \"%s\" updated to \"%s\"",
|
||||
Client_ID(Client), Client->cloaked);
|
||||
|
||||
/* Inform other servers in the network */
|
||||
IRC_WriteStrServersPrefixFlag(Client_NextHop(Origin), Origin, 'M',
|
||||
"METADATA %s cloakhost :%s",
|
||||
Client_ID(Client), Client->cloaked);
|
||||
}
|
||||
|
||||
GLOBAL char *
|
||||
Client_Modes( CLIENT *Client )
|
||||
@@ -803,10 +854,12 @@ Client_Mask( CLIENT *Client )
|
||||
|
||||
/**
|
||||
* Return ID of a client with cloaked hostname: "client!user@server-name"
|
||||
*
|
||||
* This client ID is used for IRC prefixes, for example.
|
||||
* Please note that this function uses a global static buffer, so you can't
|
||||
* nest invocations without overwriting earlier results!
|
||||
* If the client has not enabled cloaking, the real hostname is used.
|
||||
*
|
||||
* @param Client Pointer to client structure
|
||||
* @return Pointer to global buffer containing the client ID
|
||||
*/
|
||||
@@ -819,10 +872,11 @@ Client_MaskCloaked(CLIENT *Client)
|
||||
|
||||
/* Is the client using cloaking at all? */
|
||||
if (!Client_HasMode(Client, 'x'))
|
||||
return Client_Mask(Client);
|
||||
return Client_Mask(Client);
|
||||
|
||||
snprintf(Mask_Buffer, GETID_LEN, "%s!%s@%s", Client->id, Client->user,
|
||||
Client_HostnameDisplayed(Client));
|
||||
|
||||
snprintf(Mask_Buffer, GETID_LEN, "%s!%s@%s",
|
||||
Client->id, Client->user, Client_ID(Client->introducer));
|
||||
return Mask_Buffer;
|
||||
} /* Client_MaskCloaked */
|
||||
|
||||
@@ -866,7 +920,7 @@ Client_Away( CLIENT *Client )
|
||||
* the appropriate error messages.
|
||||
*
|
||||
* @param Client Client that wants to change the nickname.
|
||||
* @param Nick New nick name.
|
||||
* @param Nick New nickname.
|
||||
* @returns true if nickname is valid, false otherwise.
|
||||
*/
|
||||
GLOBAL bool
|
||||
@@ -886,6 +940,16 @@ Client_CheckNick(CLIENT *Client, char *Nick)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Client_Type(Client) != CLIENT_SERVER
|
||||
&& Client_Type(Client) != CLIENT_SERVICE) {
|
||||
/* Make sure that this isn't a restricted/forbidden nickname */
|
||||
if (Conf_NickIsBlocked(Nick)) {
|
||||
IRC_WriteStrClient(Client, ERR_FORBIDDENNICKNAME_MSG,
|
||||
Client_ID(Client), Nick);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* Nickname already registered? */
|
||||
if (Client_Search(Nick)) {
|
||||
IRC_WriteStrClient(Client, ERR_NICKNAMEINUSE_MSG,
|
||||
@@ -1142,6 +1206,46 @@ Client_Reject(CLIENT *Client, const char *Reason, bool InformClient)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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).
|
||||
*/
|
||||
GLOBAL void
|
||||
Client_Introduce(CLIENT *From, CLIENT *Client, int Type)
|
||||
{
|
||||
/* Set client type (user or service) */
|
||||
Client_SetType(Client, Type);
|
||||
|
||||
if (From) {
|
||||
if (Conf_NickIsService(Conf_GetServer(Client_Conn(From)),
|
||||
Client_ID(Client)))
|
||||
Client_SetType(Client, CLIENT_SERVICE);
|
||||
LogDebug("%s \"%s\" (+%s) registered (via %s, on %s, %d hop%s).",
|
||||
Client_TypeText(Client), Client_Mask(Client),
|
||||
Client_Modes(Client), Client_ID(From),
|
||||
Client_ID(Client_Introducer(Client)),
|
||||
Client_Hops(Client), Client_Hops(Client) > 1 ? "s": "");
|
||||
} else {
|
||||
Log(LOG_NOTICE, "%s \"%s\" registered (connection %d).",
|
||||
Client_TypeText(Client), Client_Mask(Client),
|
||||
Client_Conn(Client));
|
||||
Log_ServerNotice('c', "Client connecting: %s (%s@%s) [%s] - %s",
|
||||
Client_ID(Client), Client_User(Client),
|
||||
Client_Hostname(Client),
|
||||
Conn_IPA(Client_Conn(Client)),
|
||||
Client_TypeText(Client));
|
||||
}
|
||||
|
||||
/* Inform other servers */
|
||||
IRC_WriteStrServersPrefixFlag_CB(From,
|
||||
From != NULL ? From : Client_ThisServer(),
|
||||
'\0', cb_introduceClient, (void *)Client);
|
||||
} /* Client_Introduce */
|
||||
|
||||
|
||||
static unsigned long
|
||||
Count( CLIENT_TYPE Type )
|
||||
{
|
||||
@@ -1280,7 +1384,7 @@ Client_RegisterWhowas( CLIENT *Client )
|
||||
sizeof( My_Whowas[slot].id ));
|
||||
strlcpy( My_Whowas[slot].user, Client_User( Client ),
|
||||
sizeof( My_Whowas[slot].user ));
|
||||
strlcpy( My_Whowas[slot].host, Client_HostnameCloaked( Client ),
|
||||
strlcpy( My_Whowas[slot].host, Client_HostnameDisplayed( Client ),
|
||||
sizeof( My_Whowas[slot].host ));
|
||||
strlcpy( My_Whowas[slot].info, Client_Info( Client ),
|
||||
sizeof( My_Whowas[slot].info ));
|
||||
@@ -1361,6 +1465,59 @@ Destroy_UserOrService(CLIENT *Client, const char *Txt, const char *FwdMsg, bool
|
||||
} /* Destroy_UserOrService */
|
||||
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
CLIENT *c = (CLIENT *)data;
|
||||
CONN_ID conn;
|
||||
char *modes, *user, *host;
|
||||
|
||||
modes = Client_Modes(c);
|
||||
user = Client_User(c) ? Client_User(c) : "-";
|
||||
host = Client_Hostname(c) ? Client_Hostname(c) : "-";
|
||||
|
||||
conn = Client_Conn(To);
|
||||
if (Conn_Options(conn) & CONN_RFC1459) {
|
||||
/* RFC 1459 mode: separate NICK and USER commands */
|
||||
Conn_WriteStr(conn, "NICK %s :%d", Client_ID(c),
|
||||
Client_Hops(c) + 1);
|
||||
Conn_WriteStr(conn, ":%s USER %s %s %s :%s",
|
||||
Client_ID(c), user, host,
|
||||
Client_ID(Client_Introducer(c)), Client_Info(c));
|
||||
if (modes[0])
|
||||
Conn_WriteStr(conn, ":%s MODE %s +%s",
|
||||
Client_ID(c), Client_ID(c), modes);
|
||||
} else {
|
||||
/* RFC 2813 mode: one combined NICK or SERVICE command */
|
||||
if (Client_Type(c) == CLIENT_SERVICE
|
||||
&& strchr(Client_Flags(To), 'S'))
|
||||
IRC_WriteStrClientPrefix(To, Prefix,
|
||||
"SERVICE %s %d * +%s %d :%s",
|
||||
Client_Mask(c),
|
||||
Client_MyToken(Client_Introducer(c)),
|
||||
Client_Modes(c), Client_Hops(c) + 1,
|
||||
Client_Info(c));
|
||||
else
|
||||
IRC_WriteStrClientPrefix(To, Prefix,
|
||||
"NICK %s %d %s %s %d +%s :%s",
|
||||
Client_ID(c), Client_Hops(c) + 1,
|
||||
user, host,
|
||||
Client_MyToken(Client_Introducer(c)),
|
||||
modes, Client_Info(c));
|
||||
}
|
||||
} /* cb_introduceClient */
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
GLOBAL void
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
|
||||
* Copyright (c)2001-2012 Alexander Barton (alex@barton.de)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -29,12 +29,13 @@
|
||||
#ifndef STRICT_RFC
|
||||
# define CLIENT_WAITAUTHPING 512 /* waiting for AUTH PONG from client */
|
||||
#endif
|
||||
#define CLIENT_WAITCAPEND 1024 /* waiting for "CAP END" command */
|
||||
|
||||
#define CLIENT_TYPE int
|
||||
|
||||
#include "defines.h"
|
||||
|
||||
#if defined(__client_c__) | defined(S_SPLINT_S)
|
||||
#if defined(__client_c__) | defined(__client_cap_c__) | defined(S_SPLINT_S)
|
||||
|
||||
typedef struct _CLIENT
|
||||
{
|
||||
@@ -46,8 +47,8 @@ typedef struct _CLIENT
|
||||
CONN_ID conn_id; /* ID of the connection (if local) or NONE (remote) */
|
||||
struct _CLIENT *introducer; /* ID of the servers which the client is connected to */
|
||||
struct _CLIENT *topserver; /* toplevel servers (only valid if client is a server) */
|
||||
char pwd[CLIENT_PASS_LEN]; /* password received of the client */
|
||||
char host[CLIENT_HOST_LEN]; /* hostname of the client */
|
||||
char cloaked[CLIENT_HOST_LEN]; /* cloaked hostname of the client */
|
||||
char user[CLIENT_USER_LEN]; /* user name ("login") */
|
||||
#if defined(PAM) && defined(IDENTAUTH)
|
||||
char orig_user[CLIENT_USER_LEN];/* user name supplied by USER command */
|
||||
@@ -58,6 +59,7 @@ typedef struct _CLIENT
|
||||
bool oper_by_me; /* client is local IRC operator on this server? */
|
||||
char away[CLIENT_AWAY_LEN]; /* AWAY text (valid if mode 'a' is set) */
|
||||
char flags[CLIENT_FLAGS_LEN]; /* flags of the client */
|
||||
int capabilities; /* enabled IRC capabilities */
|
||||
} CLIENT;
|
||||
|
||||
#else
|
||||
@@ -70,7 +72,7 @@ typedef POINTER CLIENT;
|
||||
typedef struct _WHOWAS
|
||||
{
|
||||
time_t time; /* time stamp of entry or 0 if unused */
|
||||
char id[CLIENT_NICK_LEN]; /* client nick name */
|
||||
char id[CLIENT_NICK_LEN]; /* client nickname */
|
||||
char host[CLIENT_HOST_LEN]; /* hostname of the client */
|
||||
char user[CLIENT_USER_LEN]; /* user name ("login") */
|
||||
char info[CLIENT_INFO_LEN]; /* long user name */
|
||||
@@ -106,8 +108,8 @@ GLOBAL char *Client_User PARAMS(( CLIENT *Client ));
|
||||
GLOBAL char *Client_OrigUser PARAMS(( CLIENT *Client ));
|
||||
#endif
|
||||
GLOBAL char *Client_Hostname PARAMS(( CLIENT *Client ));
|
||||
GLOBAL char *Client_HostnameCloaked PARAMS(( CLIENT *Client ));
|
||||
GLOBAL char *Client_Password PARAMS(( CLIENT *Client ));
|
||||
GLOBAL char *Client_HostnameCloaked PARAMS((CLIENT *Client));
|
||||
GLOBAL char *Client_HostnameDisplayed PARAMS(( CLIENT *Client ));
|
||||
GLOBAL char *Client_Modes PARAMS(( CLIENT *Client ));
|
||||
GLOBAL char *Client_Flags PARAMS(( CLIENT *Client ));
|
||||
GLOBAL CLIENT *Client_Introducer PARAMS(( CLIENT *Client ));
|
||||
@@ -127,7 +129,6 @@ GLOBAL void Client_SetID PARAMS(( CLIENT *Client, const char *Nick ));
|
||||
GLOBAL void Client_SetUser PARAMS(( CLIENT *Client, const char *User, bool Idented ));
|
||||
GLOBAL void Client_SetOrigUser PARAMS(( CLIENT *Client, const char *User ));
|
||||
GLOBAL void Client_SetInfo PARAMS(( CLIENT *Client, const char *Info ));
|
||||
GLOBAL void Client_SetPassword PARAMS(( CLIENT *Client, const char *Pwd ));
|
||||
GLOBAL void Client_SetType PARAMS(( CLIENT *Client, int Type ));
|
||||
GLOBAL void Client_SetHops PARAMS(( CLIENT *Client, int Hops ));
|
||||
GLOBAL void Client_SetToken PARAMS(( CLIENT *Client, int Token ));
|
||||
@@ -165,6 +166,12 @@ GLOBAL const char *Client_TypeText PARAMS((CLIENT *Client));
|
||||
|
||||
GLOBAL void Client_Reject PARAMS((CLIENT *Client, const char *Reason,
|
||||
bool InformClient));
|
||||
GLOBAL void Client_Introduce PARAMS((CLIENT *From, CLIENT *Client, int Type));
|
||||
|
||||
GLOBAL void Client_UpdateCloakedHostname PARAMS((CLIENT *Client,
|
||||
CLIENT *Originator,
|
||||
const char *hostname));
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
GLOBAL void Client_DebugDump PARAMS((void));
|
||||
|
@@ -33,19 +33,15 @@ struct ConnSSL_State {
|
||||
SSL *ssl;
|
||||
#endif
|
||||
#ifdef HAVE_LIBGNUTLS
|
||||
gnutls_session gnutls_session;
|
||||
gnutls_session_t gnutls_session;
|
||||
void *cookie; /* pointer to server configuration structure
|
||||
(for outgoing connections), or NULL. */
|
||||
#endif
|
||||
};
|
||||
|
||||
bool
|
||||
ConnSSL_InitLibrary(void);
|
||||
#else
|
||||
static inline bool
|
||||
ConnSSL_InitLibrary(void)
|
||||
{ return true; }
|
||||
#endif /* SSL_SUPPORT */
|
||||
#endif
|
||||
|
||||
bool ConnSSL_InitLibrary(void);
|
||||
|
||||
#endif /* conf_ssl_h */
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors.
|
||||
* Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
#include "imp.h"
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#ifdef PROTOTYPES
|
||||
# include <stdarg.h>
|
||||
@@ -34,9 +35,6 @@
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef HAVE_CTYPE_H
|
||||
# include <ctype.h>
|
||||
#endif
|
||||
|
||||
#include "array.h"
|
||||
#include "ngircd.h"
|
||||
@@ -106,6 +104,30 @@ ConfSSL_Init(void)
|
||||
free(Conf_SSLOptions.DHFile);
|
||||
Conf_SSLOptions.DHFile = NULL;
|
||||
array_free_wipe(&Conf_SSLOptions.KeyFilePassword);
|
||||
|
||||
array_free(&Conf_SSLOptions.ListenPorts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the current configuration uses/requires SSL.
|
||||
*
|
||||
* @returns true if SSL is used and should be initialized.
|
||||
*/
|
||||
GLOBAL bool
|
||||
Conf_SSLInUse(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* SSL listen ports configured? */
|
||||
if (array_bytes(&Conf_SSLOptions.ListenPorts))
|
||||
return true;
|
||||
|
||||
for (i = 0; i < MAX_SERVERS; i++) {
|
||||
if (Conf_Server[i].port > 0
|
||||
&& Conf_Server[i].SSLConnect)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -346,10 +368,11 @@ Conf_Test( void )
|
||||
|
||||
puts("[LIMITS]");
|
||||
printf(" ConnectRetry = %d\n", Conf_ConnectRetry);
|
||||
printf(" MaxConnections = %ld\n", Conf_MaxConnections);
|
||||
printf(" MaxConnections = %d\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(" MaxListSize = %d\n", Conf_MaxListSize);
|
||||
printf(" PingTimeout = %d\n", Conf_PingTimeout);
|
||||
printf(" PongTimeout = %d\n", Conf_PongTimeout);
|
||||
puts("");
|
||||
@@ -358,6 +381,8 @@ Conf_Test( void )
|
||||
printf(" AllowRemoteOper = %s\n", yesno_to_str(Conf_AllowRemoteOper));
|
||||
printf(" ChrootDir = %s\n", Conf_Chroot);
|
||||
printf(" CloakHost = %s\n", Conf_CloakHost);
|
||||
printf(" CloakHostModeX = %s\n", Conf_CloakHostModeX);
|
||||
printf(" CloakHostSalt = %s\n", Conf_CloakHostSalt);
|
||||
printf(" CloakUserToNick = %s\n", yesno_to_str(Conf_CloakUserToNick));
|
||||
#ifdef WANT_IPV6
|
||||
printf(" ConnectIPv4 = %s\n", yesno_to_str(Conf_ConnectIPv6));
|
||||
@@ -370,6 +395,7 @@ Conf_Test( void )
|
||||
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(" OperChanPAutoOp = %s\n", yesno_to_str(Conf_OperChanPAutoOp));
|
||||
printf(" OperServerMode = %s\n", yesno_to_str(Conf_OperServerMode));
|
||||
#ifdef PAM
|
||||
printf(" PAM = %s\n", yesno_to_str(Conf_PAM));
|
||||
@@ -477,8 +503,12 @@ Conf_UnsetServer( CONN_ID Idx )
|
||||
* require the next attempt to be delayed. */
|
||||
Conf_Server[i].lasttry =
|
||||
t - Conf_ConnectRetry + RECONNECT_DELAY;
|
||||
} else
|
||||
Conf_Server[i].lasttry = t;
|
||||
} else {
|
||||
/* "Short" connection, enforce "ConnectRetry"
|
||||
* but randomize it a little bit: 15 seconds. */
|
||||
Conf_Server[i].lasttry =
|
||||
t + rand() / (RAND_MAX / 15);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -486,13 +516,23 @@ Conf_UnsetServer( CONN_ID Idx )
|
||||
/**
|
||||
* Set connection information for specified configured server.
|
||||
*/
|
||||
GLOBAL void
|
||||
GLOBAL bool
|
||||
Conf_SetServer( int ConfServer, CONN_ID Idx )
|
||||
{
|
||||
assert( ConfServer > NONE );
|
||||
assert( Idx > NONE );
|
||||
|
||||
if (Conf_Server[ConfServer].conn_id > NONE &&
|
||||
Conf_Server[ConfServer].conn_id != Idx) {
|
||||
Log(LOG_ERR,
|
||||
"Connection %d: Server configuration of \"%s\" already in use by connection %d!",
|
||||
Idx, Conf_Server[ConfServer].name,
|
||||
Conf_Server[ConfServer].conn_id);
|
||||
Conn_Close(Idx, NULL, "Server configuration already in use", true);
|
||||
return false;
|
||||
}
|
||||
Conf_Server[ConfServer].conn_id = Idx;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -626,14 +666,41 @@ Conf_AddServer(const char *Name, UINT16 Port, const char *Host,
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given nick name is an service.
|
||||
* Check if the given nickname is reserved for services on a particular server.
|
||||
*
|
||||
* @returns true if the given nick name belongs to an "IRC service".
|
||||
* @param ConfServer The server index to check.
|
||||
* @param Nick The nickname to check.
|
||||
* @returns true if the given nickname belongs to an "IRC service".
|
||||
*/
|
||||
GLOBAL bool
|
||||
Conf_IsService(int ConfServer, const char *Nick)
|
||||
Conf_NickIsService(int ConfServer, const char *Nick)
|
||||
{
|
||||
return MatchCaseInsensitive(Conf_Server[ConfServer].svs_mask, Nick);
|
||||
assert (ConfServer >= 0);
|
||||
assert (ConfServer < MAX_SERVERS);
|
||||
|
||||
return MatchCaseInsensitiveList(Conf_Server[ConfServer].svs_mask,
|
||||
Nick, ",");
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given nickname is blocked for "normal client" use.
|
||||
*
|
||||
* @param ConfServer The server index or NONE to check all configured servers.
|
||||
* @param Nick The nickname to check.
|
||||
* @returns true if the given nickname belongs to an "IRC service".
|
||||
*/
|
||||
GLOBAL bool
|
||||
Conf_NickIsBlocked(const char *Nick)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 0; i < MAX_SERVERS; i++) {
|
||||
if (!Conf_Server[i].name[0])
|
||||
continue;
|
||||
if (Conf_NickIsService(i, Nick))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -643,6 +710,7 @@ static void
|
||||
Set_Defaults(bool InitServers)
|
||||
{
|
||||
int i;
|
||||
char random[RANDOM_SALT_LEN + 1];
|
||||
|
||||
/* Global */
|
||||
strcpy(Conf_ServerName, "");
|
||||
@@ -653,6 +721,7 @@ Set_Defaults(bool InitServers)
|
||||
PACKAGE_NAME, PACKAGE_VERSION);
|
||||
free(Conf_ListenAddress);
|
||||
Conf_ListenAddress = NULL;
|
||||
array_free(&Conf_ListenPorts);
|
||||
array_free(&Conf_Motd);
|
||||
strlcpy(Conf_MotdFile, SYSCONFDIR, sizeof(Conf_MotdFile));
|
||||
strlcat(Conf_MotdFile, MOTD_FILE, sizeof(Conf_MotdFile));
|
||||
@@ -666,6 +735,7 @@ Set_Defaults(bool InitServers)
|
||||
Conf_MaxConnectionsIP = 5;
|
||||
Conf_MaxJoins = 10;
|
||||
Conf_MaxNickLength = CLIENT_NICK_LEN_DEFAULT;
|
||||
Conf_MaxListSize = 100;
|
||||
Conf_PingTimeout = 120;
|
||||
Conf_PongTimeout = 20;
|
||||
|
||||
@@ -676,6 +746,9 @@ Set_Defaults(bool InitServers)
|
||||
#endif
|
||||
strlcpy(Conf_Chroot, CHROOT_DIR, sizeof(Conf_Chroot));
|
||||
strcpy(Conf_CloakHost, "");
|
||||
strcpy(Conf_CloakHostModeX, "");
|
||||
strlcpy(Conf_CloakHostSalt, ngt_RandomStr(random, RANDOM_SALT_LEN),
|
||||
sizeof(Conf_CloakHostSalt));
|
||||
Conf_CloakUserToNick = false;
|
||||
Conf_ConnectIPv4 = true;
|
||||
#ifdef WANT_IPV6
|
||||
@@ -692,6 +765,7 @@ Set_Defaults(bool InitServers)
|
||||
Conf_MorePrivacy = false;
|
||||
Conf_NoticeAuth = false;
|
||||
Conf_OperCanMode = false;
|
||||
Conf_OperChanPAutoOp = true;
|
||||
Conf_OperServerMode = false;
|
||||
#ifdef PAM
|
||||
Conf_PAM = true;
|
||||
@@ -1023,7 +1097,7 @@ Check_ArgIsTrue(const char *Arg)
|
||||
*
|
||||
* @param Line Line number in configuration file.
|
||||
* @raram Arg Input string.
|
||||
* @returns New configured maximum nick name length.
|
||||
* @returns New configured maximum nickname length.
|
||||
*/
|
||||
static unsigned int
|
||||
Handle_MaxNickLength(int Line, const char *Arg)
|
||||
@@ -1140,6 +1214,7 @@ CheckLegacyGlobalOption(int Line, char *Var, char *Arg)
|
||||
|| strcasecmp(Var, "ConnectIPv4") == 0
|
||||
|| strcasecmp(Var, "ConnectIPv6") == 0
|
||||
|| strcasecmp(Var, "OperCanUseMode") == 0
|
||||
|| strcasecmp(Var, "OperChanPAutoOp") == 0
|
||||
|| strcasecmp(Var, "OperServerMode") == 0
|
||||
|| strcasecmp(Var, "PredefChannelsOnly") == 0
|
||||
|| strcasecmp(Var, "SyslogFacility") == 0
|
||||
@@ -1392,7 +1467,7 @@ Handle_LIMITS(int Line, char *Var, char *Arg)
|
||||
return;
|
||||
}
|
||||
if (strcasecmp(Var, "MaxConnections") == 0) {
|
||||
Conf_MaxConnections = atol(Arg);
|
||||
Conf_MaxConnections = atoi(Arg);
|
||||
if (!Conf_MaxConnections && strcmp(Arg, "0"))
|
||||
Config_Error_NaN(Line, Var);
|
||||
return;
|
||||
@@ -1413,6 +1488,12 @@ Handle_LIMITS(int Line, char *Var, char *Arg)
|
||||
Conf_MaxNickLength = Handle_MaxNickLength(Line, Arg);
|
||||
return;
|
||||
}
|
||||
if (strcasecmp(Var, "MaxListSize") == 0) {
|
||||
Conf_MaxListSize = atoi(Arg);
|
||||
if (!Conf_MaxListSize && strcmp(Arg, "0"))
|
||||
Config_Error_NaN(Line, Var);
|
||||
return;
|
||||
}
|
||||
if (strcasecmp(Var, "PingTimeout") == 0) {
|
||||
Conf_PingTimeout = atoi(Arg);
|
||||
if (Conf_PingTimeout < 5) {
|
||||
@@ -1469,6 +1550,18 @@ Handle_OPTIONS(int Line, char *Var, char *Arg)
|
||||
Config_Error_TooLong(Line, Var);
|
||||
return;
|
||||
}
|
||||
if (strcasecmp(Var, "CloakHostModeX") == 0) {
|
||||
len = strlcpy(Conf_CloakHostModeX, Arg, sizeof(Conf_CloakHostModeX));
|
||||
if (len >= sizeof(Conf_CloakHostModeX))
|
||||
Config_Error_TooLong(Line, Var);
|
||||
return;
|
||||
}
|
||||
if (strcasecmp(Var, "CloakHostSalt") == 0) {
|
||||
len = strlcpy(Conf_CloakHostSalt, Arg, sizeof(Conf_CloakHostSalt));
|
||||
if (len >= sizeof(Conf_CloakHostSalt))
|
||||
Config_Error_TooLong(Line, Var);
|
||||
return;
|
||||
}
|
||||
if (strcasecmp(Var, "CloakUserToNick") == 0) {
|
||||
Conf_CloakUserToNick = Check_ArgIsTrue(Arg);
|
||||
return;
|
||||
@@ -1503,6 +1596,10 @@ Handle_OPTIONS(int Line, char *Var, char *Arg)
|
||||
Conf_OperCanMode = Check_ArgIsTrue(Arg);
|
||||
return;
|
||||
}
|
||||
if (strcasecmp(Var, "OperChanPAutoOp") == 0) {
|
||||
Conf_OperChanPAutoOp = Check_ArgIsTrue(Arg);
|
||||
return;
|
||||
}
|
||||
if (strcasecmp(Var, "OperServerMode") == 0) {
|
||||
Conf_OperServerMode = Check_ArgIsTrue(Arg);
|
||||
return;
|
||||
@@ -1859,6 +1956,13 @@ Validate_Config(bool Configtest, bool Rehash)
|
||||
bool config_valid = true;
|
||||
char *ptr;
|
||||
|
||||
/* Emit a warning when the config file is not a full path name */
|
||||
if (NGIRCd_ConfFile[0] && NGIRCd_ConfFile[0] != '/') {
|
||||
Config_Error(LOG_WARNING,
|
||||
"Not specifying a full path name to \"%s\" can cause problems when rehashing the server!",
|
||||
NGIRCd_ConfFile);
|
||||
}
|
||||
|
||||
/* Validate configured server name, see RFC 2812 section 2.3.1 */
|
||||
ptr = Conf_ServerName;
|
||||
do {
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors.
|
||||
* Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -62,7 +62,7 @@ typedef struct _Conf_Server
|
||||
#ifdef SSL_SUPPORT
|
||||
bool SSLConnect; /**< Establish connection using SSL? */
|
||||
#endif
|
||||
char svs_mask[CLIENT_ID_LEN]; /**< Mask of nick names that should be
|
||||
char svs_mask[CLIENT_ID_LEN]; /**< Mask of nicknames that should be
|
||||
treated and counted as services */
|
||||
} CONF_SERVER;
|
||||
|
||||
@@ -151,6 +151,9 @@ GLOBAL bool Conf_PredefChannelsOnly;
|
||||
/** Flag indicating if IRC operators are allowed to always use MODE (true) */
|
||||
GLOBAL bool Conf_OperCanMode;
|
||||
|
||||
/** Flag indicating if IRC operators get AutoOp in persistent (+P) channels */
|
||||
GLOBAL bool Conf_OperChanPAutoOp;
|
||||
|
||||
/**
|
||||
* If true, mask channel MODE commands of IRC operators to the server.
|
||||
* Background: ircd2 will ignore channel MODE commands if an IRC operator
|
||||
@@ -166,7 +169,13 @@ GLOBAL bool Conf_AllowRemoteOper;
|
||||
/** Cloaked hostname of the clients */
|
||||
GLOBAL char Conf_CloakHost[CLIENT_ID_LEN];
|
||||
|
||||
/** Use nick name as user name? */
|
||||
/** Cloaked hostname for clients that did +x */
|
||||
GLOBAL char Conf_CloakHostModeX[CLIENT_ID_LEN];
|
||||
|
||||
/** Salt for hostname hash for cloaked hostnames */
|
||||
GLOBAL char Conf_CloakHostSalt[CLIENT_ID_LEN];
|
||||
|
||||
/** Use nickname as user name? */
|
||||
GLOBAL bool Conf_CloakUserToNick;
|
||||
|
||||
/** Enable all DNS functions? */
|
||||
@@ -200,7 +209,7 @@ GLOBAL bool Conf_ConnectIPv6;
|
||||
GLOBAL bool Conf_ConnectIPv4;
|
||||
|
||||
/** Maximum number of simultaneous connections to this server */
|
||||
GLOBAL long Conf_MaxConnections;
|
||||
GLOBAL int Conf_MaxConnections;
|
||||
|
||||
/** Maximum number of channels a user can join */
|
||||
GLOBAL int Conf_MaxJoins;
|
||||
@@ -208,9 +217,12 @@ GLOBAL int Conf_MaxJoins;
|
||||
/** Maximum number of connections per IP address */
|
||||
GLOBAL int Conf_MaxConnectionsIP;
|
||||
|
||||
/** Maximum length of a nick name */
|
||||
/** Maximum length of a nickname */
|
||||
GLOBAL unsigned int Conf_MaxNickLength;
|
||||
|
||||
/** Maximum number of channels returned to /list */
|
||||
GLOBAL int Conf_MaxListSize;
|
||||
|
||||
#ifndef STRICT_RFC
|
||||
|
||||
/** Require "AUTH PING-PONG" on login */
|
||||
@@ -230,7 +242,7 @@ GLOBAL bool Conf_Rehash PARAMS((void));
|
||||
GLOBAL int Conf_Test PARAMS((void));
|
||||
|
||||
GLOBAL void Conf_UnsetServer PARAMS(( CONN_ID Idx ));
|
||||
GLOBAL void Conf_SetServer PARAMS(( int ConfServer, CONN_ID Idx ));
|
||||
GLOBAL bool Conf_SetServer PARAMS(( int ConfServer, CONN_ID Idx ));
|
||||
GLOBAL int Conf_GetServer PARAMS(( CONN_ID Idx ));
|
||||
|
||||
GLOBAL bool Conf_EnableServer PARAMS(( const char *Name, UINT16 Port ));
|
||||
@@ -238,7 +250,12 @@ GLOBAL bool Conf_EnablePassiveServer PARAMS((const char *Name));
|
||||
GLOBAL bool Conf_DisableServer PARAMS(( const char *Name ));
|
||||
GLOBAL bool Conf_AddServer PARAMS(( const char *Name, UINT16 Port, const char *Host, const char *MyPwd, const char *PeerPwd ));
|
||||
|
||||
GLOBAL bool Conf_IsService PARAMS((int ConfServer, const char *Nick));
|
||||
GLOBAL bool Conf_NickIsService PARAMS((int ConfServer, const char *Nick));
|
||||
GLOBAL bool Conf_NickIsBlocked PARAMS((const char *Nick));
|
||||
|
||||
#ifdef SSL_SUPPORT
|
||||
GLOBAL bool Conf_SSLInUse PARAMS((void));
|
||||
#endif
|
||||
|
||||
/* Password required by WEBIRC command */
|
||||
GLOBAL char Conf_WebircPwd[CLIENT_PASS_LEN];
|
||||
|
192
src/ngircd/conn-encoding.c
Normal file
192
src/ngircd/conn-encoding.c
Normal file
@@ -0,0 +1,192 @@
|
||||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#define __conn_encoding_c__
|
||||
|
||||
#define CONN_MODULE
|
||||
|
||||
#include "portab.h"
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Functions to deal with character encodings and conversions
|
||||
*/
|
||||
|
||||
#include "imp.h"
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "defines.h"
|
||||
#include "conn.h"
|
||||
#include "log.h"
|
||||
|
||||
#include "exp.h"
|
||||
#include "conn-encoding.h"
|
||||
|
||||
#ifdef ICONV
|
||||
|
||||
char Encoding_Buffer[COMMAND_LEN];
|
||||
|
||||
char *Convert_Message PARAMS((iconv_t Handle, char *Message));
|
||||
|
||||
|
||||
/**
|
||||
* Set client character encoding on a connection.
|
||||
*
|
||||
* @param Conn Connection identifier.
|
||||
* @param ClientEnc Client encoding (for example "ASCII", "MacRoman", ...).
|
||||
* @return true on success, false otherwise.
|
||||
*/
|
||||
GLOBAL bool
|
||||
Conn_SetEncoding(CONN_ID Conn, const char *ClientEnc)
|
||||
{
|
||||
char client_enc[25], server_enc[25];
|
||||
|
||||
assert(Conn > NONE);
|
||||
assert(ClientEnc != NULL);
|
||||
|
||||
Conn_UnsetEncoding(Conn);
|
||||
|
||||
/* Is the client character set identical to server character set? */
|
||||
if (strcasecmp(ClientEnc, "UTF-8") == 0)
|
||||
return true;
|
||||
|
||||
snprintf(client_enc, sizeof(client_enc), "%s//TRANSLIT", ClientEnc);
|
||||
snprintf(server_enc, sizeof(server_enc), "%s//TRANSLIT", "UTF-8");
|
||||
|
||||
My_Connections[Conn].iconv_from = iconv_open(server_enc, client_enc);
|
||||
if (My_Connections[Conn].iconv_from == (iconv_t)(-1)) {
|
||||
Conn_UnsetEncoding(Conn);
|
||||
return false;
|
||||
}
|
||||
My_Connections[Conn].iconv_to = iconv_open(client_enc, server_enc);
|
||||
if (My_Connections[Conn].iconv_to == (iconv_t)(-1)) {
|
||||
Conn_UnsetEncoding(Conn);
|
||||
return false;
|
||||
}
|
||||
|
||||
LogDebug("Set client character set of connection \"%d\" to \"%s\".",
|
||||
Conn, client_enc);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove client character encoding conversion on a connection.
|
||||
*
|
||||
* @param Conn Connection identifier.
|
||||
*/
|
||||
GLOBAL void
|
||||
Conn_UnsetEncoding(CONN_ID Conn)
|
||||
{
|
||||
assert(Conn > NONE);
|
||||
|
||||
if (My_Connections[Conn].iconv_from != (iconv_t)(-1))
|
||||
iconv_close(My_Connections[Conn].iconv_from);
|
||||
if (My_Connections[Conn].iconv_to != (iconv_t)(-1))
|
||||
iconv_close(My_Connections[Conn].iconv_to);
|
||||
|
||||
My_Connections[Conn].iconv_from = (iconv_t)(-1);
|
||||
My_Connections[Conn].iconv_to = (iconv_t)(-1);
|
||||
|
||||
LogDebug("Unset character conversion of connection %d.", Conn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the encoding of a given message.
|
||||
*
|
||||
* This function uses a static buffer for the result of the encoding
|
||||
* conversion which is overwritten by subsequent calls to this function!
|
||||
*
|
||||
* @param Handle libiconv handle.
|
||||
* @param Message The message to convert.
|
||||
* @return Pointer to the result.
|
||||
*/
|
||||
char *
|
||||
Convert_Message(iconv_t Handle, char *Message)
|
||||
{
|
||||
size_t in_left, out_left;
|
||||
char *out = Encoding_Buffer;
|
||||
|
||||
assert (Handle != (iconv_t)(-1));
|
||||
assert (Message != NULL);
|
||||
|
||||
in_left = strlen(Message);
|
||||
out_left = sizeof(Encoding_Buffer) - 1;
|
||||
|
||||
if (iconv(Handle, &Message, &in_left, &out, &out_left) == (size_t)(-1)) {
|
||||
/* An error occured! */
|
||||
LogDebug("Error converting message encoding!");
|
||||
strlcpy(Encoding_Buffer, Message, sizeof(Encoding_Buffer));
|
||||
iconv(Handle, NULL, NULL, NULL, NULL);
|
||||
} else
|
||||
*out = '\0';
|
||||
|
||||
return Encoding_Buffer;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Convert encoding of a message received from a connection.
|
||||
*
|
||||
* Note 1: If no conversion is required, this function returns the original
|
||||
* pointer to the message.
|
||||
*
|
||||
* Note 2: This function uses Convert_Message(), so subsequent calls to this
|
||||
* function will overwrite the earlier results.
|
||||
*
|
||||
* @param Conn Connection identifier.
|
||||
* @param Message The message to convert.
|
||||
* @return Pointer to the result.
|
||||
* @see Convert_Message
|
||||
*/
|
||||
GLOBAL char *
|
||||
Conn_EncodingFrom(UNUSED CONN_ID Conn, char *Message)
|
||||
{
|
||||
assert(Conn > NONE);
|
||||
assert (Message != NULL);
|
||||
|
||||
#ifdef ICONV
|
||||
if (My_Connections[Conn].iconv_from != (iconv_t)(-1))
|
||||
return Convert_Message(My_Connections[Conn].iconv_from, Message);
|
||||
#endif
|
||||
return Message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert encoding of a message for sending on a connection.
|
||||
*
|
||||
* Note 1: If no conversion is required, this function returns the original
|
||||
* pointer to the message.
|
||||
*
|
||||
* Note 2: This function uses Convert_Message(), so subsequent calls to this
|
||||
* function will overwrite the earlier results.
|
||||
*
|
||||
* @param Conn Connection identifier.
|
||||
* @param Message The message to convert.
|
||||
* @return Pointer to the result.
|
||||
* @see Convert_Message
|
||||
*/
|
||||
GLOBAL char *
|
||||
Conn_EncodingTo(UNUSED CONN_ID Conn, char *Message)
|
||||
{
|
||||
assert(Conn > NONE);
|
||||
assert (Message != NULL);
|
||||
|
||||
#ifdef ICONV
|
||||
if (My_Connections[Conn].iconv_to != (iconv_t)(-1))
|
||||
return Convert_Message(My_Connections[Conn].iconv_to, Message);
|
||||
#endif
|
||||
return Message;
|
||||
}
|
||||
|
||||
/* -eof- */
|
30
src/ngircd/conn-encoding.h
Normal file
30
src/ngircd/conn-encoding.h
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
* Please read the file COPYING, README and AUTHORS for more information.
|
||||
*/
|
||||
|
||||
#ifndef __conn_encoding_h__
|
||||
#define __conn_encoding_h__
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Functions to deal with character encodings and conversions (header)
|
||||
*/
|
||||
|
||||
#ifdef ICONV
|
||||
|
||||
GLOBAL bool Conn_SetEncoding PARAMS((CONN_ID Idx, const char *ClientEnc));
|
||||
GLOBAL void Conn_UnsetEncoding PARAMS((CONN_ID Idx));
|
||||
|
||||
#endif /* ICONV */
|
||||
|
||||
GLOBAL char* Conn_EncodingFrom PARAMS((CONN_ID Idx, char *Message));
|
||||
GLOBAL char* Conn_EncodingTo PARAMS((CONN_ID Idx, char *Message));
|
||||
|
||||
#endif
|
@@ -117,24 +117,6 @@ Conn_SetPenalty(CONN_ID Idx, time_t Seconds)
|
||||
} /* Conn_SetPenalty */
|
||||
|
||||
|
||||
/**
|
||||
* Reset the "penalty time" for one connection.
|
||||
*
|
||||
* @param Idx Connection index.
|
||||
* @see Conn_SetPenalty
|
||||
*/
|
||||
GLOBAL void
|
||||
Conn_ResetPenalty(CONN_ID Idx)
|
||||
{
|
||||
assert(Idx > NONE);
|
||||
|
||||
My_Connections[Idx].delaytime = 0;
|
||||
#ifdef DEBUG
|
||||
Log(LOG_DEBUG, "Penalty time on connection %d has been reset.");
|
||||
#endif
|
||||
} /* Conn_ResetPenalty */
|
||||
|
||||
|
||||
GLOBAL void
|
||||
Conn_ClearFlags( void )
|
||||
{
|
||||
|
@@ -45,7 +45,6 @@ GLOBAL long Conn_RecvBytes PARAMS(( CONN_ID Idx ));
|
||||
GLOBAL const char *Conn_IPA PARAMS(( CONN_ID Idx ));
|
||||
|
||||
GLOBAL void Conn_SetPenalty PARAMS(( CONN_ID Idx, time_t Seconds ));
|
||||
GLOBAL void Conn_ResetPenalty PARAMS(( CONN_ID Idx ));
|
||||
|
||||
GLOBAL void Conn_ClearFlags PARAMS(( void ));
|
||||
GLOBAL int Conn_Flag PARAMS(( CONN_ID Idx ));
|
||||
|
@@ -156,7 +156,7 @@ Load_DH_params(void)
|
||||
bool ret = true;
|
||||
|
||||
if (!Conf_SSLOptions.DHFile) {
|
||||
Log(LOG_NOTICE, "Configuration option \"SSLDHFile\" not set!");
|
||||
Log(LOG_NOTICE, "Configuration option \"DHFile\" not set!");
|
||||
return false;
|
||||
}
|
||||
fp = fopen(Conf_SSLOptions.DHFile, "r");
|
||||
@@ -201,7 +201,7 @@ Load_DH_params(void)
|
||||
}
|
||||
if (need_dhgenerate) {
|
||||
Log(LOG_WARNING,
|
||||
"SSLDHFile not set, generating %u bit DH parameters. This may take a while ...",
|
||||
"DHFile not set, generating %u bit DH parameters. This may take a while ...",
|
||||
DH_BITS);
|
||||
err = gnutls_dh_params_generate2(tmp_dh_params, DH_BITS);
|
||||
if (err < 0) {
|
||||
@@ -241,6 +241,11 @@ void ConnSSL_Free(CONNECTION *c)
|
||||
bool
|
||||
ConnSSL_InitLibrary( void )
|
||||
{
|
||||
if (!Conf_SSLInUse()) {
|
||||
LogDebug("SSL not in use, skipping initialization.");
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBSSL
|
||||
SSL_CTX *newctx;
|
||||
|
||||
@@ -256,12 +261,14 @@ ConnSSL_InitLibrary( void )
|
||||
* According to OpenSSL RAND_egd(3): "The automatic query of /var/run/egd-pool et al was added in OpenSSL 0.9.7";
|
||||
* so it makes little sense to deal with PRNGD seeding ourselves.
|
||||
*/
|
||||
array_free(&Conf_SSLOptions.ListenPorts);
|
||||
return false;
|
||||
}
|
||||
|
||||
newctx = SSL_CTX_new(SSLv23_method());
|
||||
if (!newctx) {
|
||||
LogOpenSSLError("SSL_CTX_new()", NULL);
|
||||
array_free(&Conf_SSLOptions.ListenPorts);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -276,6 +283,7 @@ ConnSSL_InitLibrary( void )
|
||||
return true;
|
||||
out:
|
||||
SSL_CTX_free(newctx);
|
||||
array_free(&Conf_SSLOptions.ListenPorts);
|
||||
return false;
|
||||
#endif
|
||||
#ifdef HAVE_LIBGNUTLS
|
||||
@@ -287,10 +295,13 @@ out:
|
||||
err = gnutls_global_init();
|
||||
if (err) {
|
||||
Log(LOG_ERR, "gnutls_global_init(): %s", gnutls_strerror(err));
|
||||
array_free(&Conf_SSLOptions.ListenPorts);
|
||||
return false;
|
||||
}
|
||||
if (!ConnSSL_LoadServerKey_gnutls())
|
||||
if (!ConnSSL_LoadServerKey_gnutls()) {
|
||||
array_free(&Conf_SSLOptions.ListenPorts);
|
||||
return false;
|
||||
}
|
||||
Log(LOG_INFO, "gnutls %s initialized.", gnutls_check_version(NULL));
|
||||
initialized = true;
|
||||
return true;
|
||||
@@ -313,7 +324,7 @@ ConnSSL_LoadServerKey_gnutls(void)
|
||||
|
||||
cert_file = Conf_SSLOptions.CertFile ? Conf_SSLOptions.CertFile:Conf_SSLOptions.KeyFile;
|
||||
if (!cert_file) {
|
||||
Log(LOG_NOTICE, "No SSL server key configured, SSL disabled.");
|
||||
Log(LOG_ERR, "No SSL server key configured!");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -344,7 +355,7 @@ ConnSSL_LoadServerKey_openssl(SSL_CTX *ctx)
|
||||
|
||||
assert(ctx);
|
||||
if (!Conf_SSLOptions.KeyFile) {
|
||||
Log(LOG_NOTICE, "No SSL server key configured, SSL disabled.");
|
||||
Log(LOG_ERR, "No SSL server key configured!");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -549,17 +560,18 @@ ConnSSL_LogCertInfo( CONNECTION *c )
|
||||
|
||||
assert(ssl);
|
||||
|
||||
Log(LOG_INFO, "New %s connection using cipher %s on socket %d.",
|
||||
SSL_get_version(ssl), SSL_get_cipher(ssl), c->sock);
|
||||
Log(LOG_INFO, "Connection %d: initialized %s using cipher %s.",
|
||||
c->sock, SSL_get_version(ssl), SSL_get_cipher(ssl));
|
||||
#endif
|
||||
#ifdef HAVE_LIBGNUTLS
|
||||
gnutls_session_t sess = c->ssl_state.gnutls_session;
|
||||
gnutls_cipher_algorithm_t cipher = gnutls_cipher_get(sess);
|
||||
|
||||
Log(LOG_INFO, "New %s connection using cipher %s-%s on socket %d.",
|
||||
Log(LOG_INFO, "Connection %d: initialized %s using cipher %s-%s.",
|
||||
c->sock,
|
||||
gnutls_protocol_get_name(gnutls_protocol_get_version(sess)),
|
||||
gnutls_cipher_get_name(cipher),
|
||||
gnutls_mac_get_name(gnutls_mac_get(sess)), c->sock);
|
||||
gnutls_mac_get_name(gnutls_mac_get(sess)));
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -624,6 +636,8 @@ ConnectAccept( CONNECTION *c, bool connect)
|
||||
#endif /* _GNUTLS */
|
||||
Conn_OPTION_DEL(c, (CONN_SSL_WANT_WRITE|CONN_SSL_WANT_READ|CONN_SSL_CONNECT));
|
||||
ConnSSL_LogCertInfo(c);
|
||||
|
||||
Conn_StartLogin(CONNECTION2ID(c));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -711,6 +725,13 @@ ConnSSL_GetCipherInfo(CONNECTION *c, char *buf, size_t len)
|
||||
#endif
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
bool
|
||||
ConnSSL_InitLibrary(void)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif /* SSL_SUPPORT */
|
||||
/* -eof- */
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors.
|
||||
* Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -47,10 +47,6 @@
|
||||
# include <netinet/ip.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STDINT_H
|
||||
# include <stdint.h> /* e.g. for Mac OS X */
|
||||
#endif
|
||||
|
||||
#ifdef TCPWRAP
|
||||
# include <tcpd.h> /* for TCP Wrappers */
|
||||
#endif
|
||||
@@ -67,6 +63,7 @@
|
||||
#include "client.h"
|
||||
#include "class.h"
|
||||
#include "conf.h"
|
||||
#include "conn-encoding.h"
|
||||
#include "conn-ssl.h"
|
||||
#include "conn-zip.h"
|
||||
#include "conn-func.h"
|
||||
@@ -88,7 +85,7 @@
|
||||
|
||||
static bool Handle_Write PARAMS(( CONN_ID Idx ));
|
||||
static bool Conn_Write PARAMS(( CONN_ID Idx, char *Data, size_t Len ));
|
||||
static int New_Connection PARAMS(( int Sock ));
|
||||
static int New_Connection PARAMS(( int Sock, bool IsSSL ));
|
||||
static CONN_ID Socket2Index PARAMS(( int Sock ));
|
||||
static void Read_Request PARAMS(( CONN_ID Idx ));
|
||||
static unsigned int Handle_Buffer PARAMS(( CONN_ID Idx ));
|
||||
@@ -134,7 +131,7 @@ static void
|
||||
cb_listen(int sock, short irrelevant)
|
||||
{
|
||||
(void) irrelevant;
|
||||
(void) New_Connection(sock);
|
||||
(void) New_Connection(sock, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -152,7 +149,7 @@ cb_listen_ssl(int sock, short irrelevant)
|
||||
int fd;
|
||||
|
||||
(void) irrelevant;
|
||||
fd = New_Connection(sock);
|
||||
fd = New_Connection(sock, true);
|
||||
if (fd < 0)
|
||||
return;
|
||||
io_event_setcb(My_Connections[fd].sock, cb_clientserver_ssl);
|
||||
@@ -865,6 +862,9 @@ va_dcl
|
||||
#endif
|
||||
{
|
||||
char buffer[COMMAND_LEN];
|
||||
#ifdef ICONV
|
||||
char *ptr, *message;
|
||||
#endif
|
||||
size_t len;
|
||||
bool ok;
|
||||
va_list ap;
|
||||
@@ -905,6 +905,16 @@ va_dcl
|
||||
CUT_TXTSUFFIX);
|
||||
}
|
||||
|
||||
#ifdef ICONV
|
||||
ptr = strchr(buffer + 1, ':');
|
||||
if (ptr) {
|
||||
ptr++;
|
||||
message = Conn_EncodingTo(Idx, ptr);
|
||||
if (message != ptr)
|
||||
strlcpy(ptr, message, sizeof(buffer) - (ptr - buffer));
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SNIFFER
|
||||
if (NGIRCd_Sniffer)
|
||||
Log(LOG_DEBUG, " -> connection %d: '%s'.", Idx, buffer);
|
||||
@@ -918,6 +928,30 @@ va_dcl
|
||||
return ok;
|
||||
} /* Conn_WriteStr */
|
||||
|
||||
GLOBAL char*
|
||||
Conn_Password( CONN_ID Idx )
|
||||
{
|
||||
assert( Idx > NONE );
|
||||
if (My_Connections[Idx].pwd == NULL)
|
||||
return (char*)"\0";
|
||||
else
|
||||
return My_Connections[Idx].pwd;
|
||||
} /* Conn_Password */
|
||||
|
||||
GLOBAL void
|
||||
Conn_SetPassword( CONN_ID Idx, const char *Pwd )
|
||||
{
|
||||
assert( Idx > NONE );
|
||||
|
||||
if (My_Connections[Idx].pwd)
|
||||
free(My_Connections[Idx].pwd);
|
||||
|
||||
My_Connections[Idx].pwd = strdup(Pwd);
|
||||
if (My_Connections[Idx].pwd == NULL) {
|
||||
Log(LOG_EMERG, "Can't allocate memory! [Conn_SetPassword]");
|
||||
exit(1);
|
||||
}
|
||||
} /* Conn_SetPassword */
|
||||
|
||||
/**
|
||||
* Append Data to the outbound write buffer of a connection.
|
||||
@@ -1146,6 +1180,8 @@ Conn_Close( CONN_ID Idx, const char *LogMsg, const char *FwdMsg, bool InformClie
|
||||
|
||||
array_free(&My_Connections[Idx].rbuf);
|
||||
array_free(&My_Connections[Idx].wbuf);
|
||||
if (My_Connections[Idx].pwd != NULL)
|
||||
free(My_Connections[Idx].pwd);
|
||||
|
||||
/* Clean up connection structure (=free it) */
|
||||
Init_Conn_Struct( Idx );
|
||||
@@ -1336,17 +1372,18 @@ Count_Connections(ng_ipaddr_t *a)
|
||||
* Initialize new client connection on a listening socket.
|
||||
*
|
||||
* @param Sock Listening socket descriptor.
|
||||
* @param IsSSL true if this socket expects SSL-encrypted data.
|
||||
* @returns Accepted socket descriptor or -1 on error.
|
||||
*/
|
||||
static int
|
||||
New_Connection(int Sock)
|
||||
New_Connection(int Sock, UNUSED bool IsSSL)
|
||||
{
|
||||
#ifdef TCPWRAP
|
||||
struct request_info req;
|
||||
#endif
|
||||
ng_ipaddr_t new_addr;
|
||||
char ip_str[NG_INET_ADDRSTRLEN];
|
||||
int new_sock, new_sock_len, identsock;
|
||||
int new_sock, new_sock_len;
|
||||
CLIENT *c;
|
||||
long cnt;
|
||||
|
||||
@@ -1466,32 +1503,62 @@ New_Connection(int Sock)
|
||||
Log(LOG_INFO, "Accepted connection %d from %s:%d on socket %d.",
|
||||
new_sock, My_Connections[new_sock].host,
|
||||
ng_ipaddr_getport(&new_addr), Sock);
|
||||
|
||||
identsock = new_sock;
|
||||
#ifdef IDENTAUTH
|
||||
if (!Conf_Ident)
|
||||
identsock = -1;
|
||||
#endif
|
||||
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();
|
||||
|
||||
#ifdef SSL_SUPPORT
|
||||
/* Delay connection initalization until SSL handshake is finished */
|
||||
if (!IsSSL)
|
||||
#endif
|
||||
Conn_StartLogin(new_sock);
|
||||
|
||||
return new_sock;
|
||||
} /* New_Connection */
|
||||
|
||||
|
||||
/**
|
||||
* Finish connection initialization, start resolver subprocess.
|
||||
*
|
||||
* @param Idx Connection index.
|
||||
*/
|
||||
GLOBAL void
|
||||
Conn_StartLogin(CONN_ID Idx)
|
||||
{
|
||||
int ident_sock = -1;
|
||||
|
||||
assert(Idx >= 0);
|
||||
|
||||
/* Nothing to do if DNS (and resolver subprocess) is disabled */
|
||||
if (!Conf_DNS)
|
||||
return;
|
||||
|
||||
#ifdef IDENTAUTH
|
||||
/* Should we make an IDENT request? */
|
||||
if (Conf_Ident)
|
||||
ident_sock = My_Connections[Idx].sock;
|
||||
#endif
|
||||
|
||||
if (Conf_NoticeAuth) {
|
||||
/* Send "NOTICE AUTH" messages to the client */
|
||||
#ifdef IDENTAUTH
|
||||
if (Conf_Ident)
|
||||
(void)Conn_WriteStr(Idx,
|
||||
"NOTICE AUTH :*** Looking up your hostname and checking ident");
|
||||
else
|
||||
#endif
|
||||
(void)Conn_WriteStr(Idx,
|
||||
"NOTICE AUTH :*** Looking up your hostname");
|
||||
/* Send buffered data to the client, but break on errors
|
||||
* because Handle_Write() would have closed the connection
|
||||
* again in this case! */
|
||||
if (!Handle_Write(Idx))
|
||||
return;
|
||||
}
|
||||
|
||||
Resolve_Addr(&My_Connections[Idx].proc_stat, &My_Connections[Idx].addr,
|
||||
ident_sock, cb_Read_Resolver_Result);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update global connection counters.
|
||||
*/
|
||||
@@ -1839,10 +1906,10 @@ Check_Connections(void)
|
||||
if (My_Connections[i].lastping <
|
||||
time(NULL) - Conf_PongTimeout) {
|
||||
/* Timeout */
|
||||
LogDebug
|
||||
("Connection %d: Ping timeout: %d seconds.",
|
||||
i, Conf_PongTimeout);
|
||||
snprintf(msg, sizeof(msg), "Ping timeout: %d seconds", Conf_PongTimeout);
|
||||
snprintf(msg, sizeof(msg),
|
||||
"Ping timeout: %d seconds",
|
||||
Conf_PongTimeout);
|
||||
LogDebug("Connection %d: %s.", i, msg);
|
||||
Conn_Close(i, NULL, msg, true);
|
||||
}
|
||||
} else if (My_Connections[i].lastdata <
|
||||
@@ -1935,6 +2002,14 @@ New_Server( int Server , ng_ipaddr_t *dest)
|
||||
|
||||
assert( Server > NONE );
|
||||
|
||||
/* Make sure that the remote server hasn't re-linked to this server
|
||||
* asynchronously on its own */
|
||||
if (Conf_Server[Server].conn_id > NONE) {
|
||||
Log(LOG_INFO,
|
||||
"Connection to \"%s\" meanwhile re-established, aborting preparation.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ng_ipaddr_tostr_r(dest, ip_str)) {
|
||||
Log(LOG_WARNING, "New_Server: Could not convert IP to string");
|
||||
return;
|
||||
@@ -2008,7 +2083,8 @@ New_Server( int Server , ng_ipaddr_t *dest)
|
||||
Client_SetToken( c, TOKEN_OUTBOUND );
|
||||
|
||||
/* Register connection */
|
||||
Conf_Server[Server].conn_id = new_sock;
|
||||
if (!Conf_SetServer(Server, new_sock))
|
||||
return;
|
||||
My_Connections[new_sock].sock = new_sock;
|
||||
My_Connections[new_sock].addr = *dest;
|
||||
My_Connections[new_sock].client = c;
|
||||
@@ -2048,6 +2124,11 @@ Init_Conn_Struct(CONN_ID Idx)
|
||||
My_Connections[Idx].lastdata = now;
|
||||
My_Connections[Idx].lastprivmsg = now;
|
||||
Proc_InitStruct(&My_Connections[Idx].proc_stat);
|
||||
|
||||
#ifdef ICONV
|
||||
My_Connections[Idx].iconv_from = (iconv_t)(-1);
|
||||
My_Connections[Idx].iconv_to = (iconv_t)(-1);
|
||||
#endif
|
||||
} /* Init_Conn_Struct */
|
||||
|
||||
|
||||
@@ -2174,6 +2255,7 @@ cb_Read_Resolver_Result( int r_fd, UNUSED short events )
|
||||
char *identptr;
|
||||
#ifdef IDENTAUTH
|
||||
char readbuf[HOST_LEN + 2 + CLIENT_USER_LEN];
|
||||
char *ptr;
|
||||
#else
|
||||
char readbuf[HOST_LEN + 1];
|
||||
#endif
|
||||
@@ -2222,15 +2304,37 @@ cb_Read_Resolver_Result( int r_fd, UNUSED short events )
|
||||
Client_SetHostname(c, readbuf);
|
||||
if (Conf_NoticeAuth)
|
||||
(void)Conn_WriteStr(i,
|
||||
"NOTICE AUTH :*** Found your hostname");
|
||||
"NOTICE AUTH :*** Found your hostname: %s",
|
||||
My_Connections[i].host);
|
||||
#ifdef IDENTAUTH
|
||||
++identptr;
|
||||
if (*identptr) {
|
||||
Log(LOG_INFO, "IDENT lookup for connection %d: \"%s\".", i, identptr);
|
||||
Client_SetUser(c, identptr, true);
|
||||
if (Conf_NoticeAuth)
|
||||
ptr = identptr;
|
||||
while (*ptr) {
|
||||
if ((*ptr < '0' || *ptr > '9') &&
|
||||
(*ptr < 'A' || *ptr > 'Z') &&
|
||||
(*ptr < 'a' || *ptr > 'z'))
|
||||
break;
|
||||
ptr++;
|
||||
}
|
||||
if (*ptr) {
|
||||
/* Erroneous IDENT reply */
|
||||
Log(LOG_NOTICE,
|
||||
"Got invalid IDENT reply for connection %d! Ignored.",
|
||||
i);
|
||||
} else {
|
||||
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");
|
||||
"NOTICE AUTH :*** Got %sident response%s%s",
|
||||
*ptr ? "invalid " : "",
|
||||
*ptr ? "" : ": ",
|
||||
*ptr ? "" : identptr);
|
||||
}
|
||||
} else {
|
||||
Log(LOG_INFO, "IDENT lookup for connection %d: no result.", i);
|
||||
if (Conf_NoticeAuth && Conf_Ident)
|
||||
@@ -2238,6 +2342,15 @@ cb_Read_Resolver_Result( int r_fd, UNUSED short events )
|
||||
"NOTICE AUTH :*** No ident response");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (Conf_NoticeAuth) {
|
||||
/* Send buffered data to the client, but break on
|
||||
* errors because Handle_Write() would have closed
|
||||
* the connection again in this case! */
|
||||
if (!Handle_Write(i))
|
||||
return;
|
||||
}
|
||||
|
||||
Class_HandleServerBans(c);
|
||||
}
|
||||
#ifdef DEBUG
|
||||
|
@@ -42,7 +42,7 @@
|
||||
#define CONN_SSL_WANT_READ 128 /* SSL/TLS library needs to read protocol data */
|
||||
#define CONN_SSL_FLAGS_ALL (CONN_SSL_CONNECT|CONN_SSL|CONN_SSL_WANT_WRITE|CONN_SSL_WANT_READ)
|
||||
#endif
|
||||
typedef long CONN_ID;
|
||||
typedef int CONN_ID;
|
||||
|
||||
#include "client.h"
|
||||
#include "proc.h"
|
||||
@@ -54,6 +54,10 @@ typedef long CONN_ID;
|
||||
#include "tool.h"
|
||||
#include "ng_ipaddr.h"
|
||||
|
||||
#ifdef ICONV
|
||||
# include <iconv.h>
|
||||
#endif
|
||||
|
||||
#ifdef ZLIB
|
||||
#include <zlib.h>
|
||||
typedef struct _ZipData
|
||||
@@ -72,6 +76,7 @@ typedef struct _Connection
|
||||
ng_ipaddr_t addr; /* Client address */
|
||||
PROC_STAT proc_stat; /* Status of resolver process */
|
||||
char host[HOST_LEN]; /* Hostname */
|
||||
char *pwd; /* password received of the client */
|
||||
array rbuf; /* Read buffer */
|
||||
array wbuf; /* Write buffer */
|
||||
time_t signon; /* Signon ("connect") time */
|
||||
@@ -94,12 +99,18 @@ typedef struct _Connection
|
||||
#ifndef STRICT_RFC
|
||||
long auth_ping; /** PING response expected on login */
|
||||
#endif
|
||||
#ifdef ICONV
|
||||
iconv_t iconv_from; /** iconv: convert from client to server */
|
||||
iconv_t iconv_to; /** iconv: convert from server to client */
|
||||
#endif
|
||||
} CONNECTION;
|
||||
|
||||
GLOBAL CONNECTION *My_Connections;
|
||||
GLOBAL CONN_ID Pool_Size;
|
||||
GLOBAL long WCounter;
|
||||
|
||||
#define CONNECTION2ID(x) (long)(x - My_Connections)
|
||||
|
||||
#endif /* CONN_MODULE */
|
||||
|
||||
|
||||
@@ -111,10 +122,15 @@ GLOBAL void Conn_CloseAllSockets PARAMS((int ExceptOf));
|
||||
GLOBAL unsigned int Conn_InitListeners PARAMS(( void ));
|
||||
GLOBAL void Conn_ExitListeners PARAMS(( void ));
|
||||
|
||||
GLOBAL void Conn_StartLogin PARAMS((CONN_ID Idx));
|
||||
|
||||
GLOBAL void Conn_Handler PARAMS(( void ));
|
||||
|
||||
GLOBAL bool Conn_WriteStr PARAMS(( CONN_ID Idx, const char *Format, ... ));
|
||||
|
||||
GLOBAL char* Conn_Password PARAMS(( CONN_ID Idx ));
|
||||
GLOBAL void Conn_SetPassword PARAMS(( CONN_ID Idx, const char *Pwd ));
|
||||
|
||||
GLOBAL void Conn_Close PARAMS(( CONN_ID Idx, const char *LogMsg, const char *FwdMsg, bool InformClient ));
|
||||
|
||||
GLOBAL void Conn_SyncServerStruct PARAMS(( void ));
|
||||
@@ -122,6 +138,7 @@ GLOBAL void Conn_SyncServerStruct PARAMS(( void ));
|
||||
GLOBAL CONN_ID Conn_GetFromProc PARAMS((int fd));
|
||||
GLOBAL CLIENT* Conn_GetClient PARAMS((CONN_ID i));
|
||||
GLOBAL PROC_STAT* Conn_GetProcStat PARAMS((CONN_ID i));
|
||||
|
||||
#ifdef SSL_SUPPORT
|
||||
GLOBAL bool Conn_GetCipherInfo PARAMS((CONN_ID Idx, char *buf, size_t len));
|
||||
GLOBAL bool Conn_UsesSSL PARAMS((CONN_ID Idx));
|
||||
|
@@ -44,9 +44,12 @@
|
||||
/** Max. length of file name. */
|
||||
#define FNAME_LEN 256
|
||||
|
||||
/** Max. lenght of fully qualified host names (e. g. "abc.domain.tld"). */
|
||||
/** Max. length of fully qualified host names (e. g. "abc.domain.tld"). */
|
||||
#define HOST_LEN 256
|
||||
|
||||
/** Max. length of random salt */
|
||||
#define RANDOM_SALT_LEN 32
|
||||
|
||||
|
||||
/* Size of structures */
|
||||
|
||||
@@ -89,14 +92,18 @@
|
||||
/** Default nick length (including NULL), see. RFC 2812 section 1.2.1. */
|
||||
#define CLIENT_NICK_LEN_DEFAULT 10
|
||||
|
||||
/** Maximum nick name length (including NULL). */
|
||||
/** Maximum nickname length (including NULL). */
|
||||
#define CLIENT_NICK_LEN 32
|
||||
|
||||
/** Max. password length (including NULL). */
|
||||
#define CLIENT_PASS_LEN 21
|
||||
|
||||
/** Max. length of user name ("login"; incl. NULL), RFC 2812, section 1.2.1. */
|
||||
#define CLIENT_USER_LEN 10
|
||||
#ifndef STRICT_RFC
|
||||
# define CLIENT_USER_LEN 20
|
||||
#else
|
||||
# define CLIENT_USER_LEN 10
|
||||
#endif
|
||||
|
||||
/** Max. length of "real names" (including NULL). */
|
||||
#define CLIENT_NAME_LEN 32
|
||||
@@ -105,7 +112,7 @@
|
||||
#define CLIENT_HOST_LEN 64
|
||||
|
||||
/** Max. length of all client modes (including NULL). */
|
||||
#define CLIENT_MODE_LEN 16
|
||||
#define CLIENT_MODE_LEN 21
|
||||
|
||||
/** Max. length of server info texts (including NULL). */
|
||||
#define CLIENT_INFO_LEN 64
|
||||
@@ -120,7 +127,7 @@
|
||||
#define CHANNEL_NAME_LEN 51
|
||||
|
||||
/** Max. length of channel modes (including NULL). */
|
||||
#define CHANNEL_MODE_LEN 9
|
||||
#define CHANNEL_MODE_LEN 21
|
||||
|
||||
/** Max. IRC command length (including NULL), see. RFC 2812 section 3.2. */
|
||||
#define COMMAND_LEN 513
|
||||
@@ -154,14 +161,14 @@
|
||||
|
||||
#ifdef IRCPLUS
|
||||
/** Standard IRC+ flags. */
|
||||
# define IRCPLUSFLAGS "CHLS"
|
||||
# define IRCPLUSFLAGS "CHLMSX"
|
||||
#endif
|
||||
|
||||
/** Supported user modes. */
|
||||
#define USERMODES "acCiorRswx"
|
||||
#define USERMODES "abBcCioqrRswx"
|
||||
|
||||
/** Supported channel modes. */
|
||||
#define CHANMODES "beiIklmnoOPRstvz"
|
||||
#define CHANMODES "abehiIklmMnoOPqQrRstvVz"
|
||||
|
||||
/** Away message for users connected to linked servers. */
|
||||
#define DEFAULT_AWAY_MSG "Away"
|
||||
@@ -178,9 +185,6 @@
|
||||
|
||||
/* Defaults and limits for IRC commands */
|
||||
|
||||
/** Max. number of LIST replies. */
|
||||
#define MAX_RPL_LIST 100
|
||||
|
||||
/** Max. number of elemets allowed in channel invite and ban lists. */
|
||||
#define MAX_HNDL_CHANNEL_LISTS 50
|
||||
|
||||
|
@@ -86,6 +86,20 @@ static int io_masterfd;
|
||||
|
||||
static int io_dispatch_kqueue(struct timeval *tv);
|
||||
static bool io_event_change_kqueue(int, short, const int action);
|
||||
|
||||
#ifndef EV_SET
|
||||
/* Taken from /usr/include/sys/event.h of FreeBSD 8.1 and required by all
|
||||
* platforms that have kqueue but lack EV_SET() -- for example FreeBSD 4. */
|
||||
#define EV_SET(kevp, a, b, c, d, e, f) do { \
|
||||
struct kevent *__kevp__ = (kevp); \
|
||||
__kevp__->ident = (a); \
|
||||
__kevp__->filter = (b); \
|
||||
__kevp__->flags = (c); \
|
||||
__kevp__->fflags = (d); \
|
||||
__kevp__->data = (e); \
|
||||
__kevp__->udata = (f); \
|
||||
} while(0)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef IO_USE_POLL
|
||||
|
291
src/ngircd/irc-cap.c
Normal file
291
src/ngircd/irc-cap.c
Normal file
@@ -0,0 +1,291 @@
|
||||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* 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
|
||||
* Handler for IRC capability ("CAP") commands
|
||||
*/
|
||||
|
||||
#include "imp.h"
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "defines.h"
|
||||
#include "conn.h"
|
||||
#include "channel.h"
|
||||
#include "client-cap.h"
|
||||
#include "irc-write.h"
|
||||
#include "log.h"
|
||||
#include "login.h"
|
||||
#include "messages.h"
|
||||
#include "parse.h"
|
||||
|
||||
#include "exp.h"
|
||||
#include "irc-cap.h"
|
||||
|
||||
bool Handle_CAP_LS PARAMS((CLIENT *Client, char *Arg));
|
||||
bool Handle_CAP_LIST PARAMS((CLIENT *Client, char *Arg));
|
||||
bool Handle_CAP_REQ PARAMS((CLIENT *Client, char *Arg));
|
||||
bool Handle_CAP_ACK PARAMS((CLIENT *Client, char *Arg));
|
||||
bool Handle_CAP_CLEAR PARAMS((CLIENT *Client));
|
||||
bool Handle_CAP_END PARAMS((CLIENT *Client));
|
||||
|
||||
void Set_CAP_Negotiation PARAMS((CLIENT *Client));
|
||||
|
||||
int Parse_CAP PARAMS((int Capabilities, char *Args));
|
||||
char *Get_CAP_String PARAMS((int Capabilities));
|
||||
|
||||
/**
|
||||
* Handler for the IRCv3 "CAP" command.
|
||||
*
|
||||
* @param Client The client from which this command has been received.
|
||||
* @param Req Request structure with prefix and all parameters.
|
||||
* @returns CONNECTED or DISCONNECTED.
|
||||
*/
|
||||
GLOBAL bool
|
||||
IRC_CAP(CLIENT *Client, REQUEST *Req)
|
||||
{
|
||||
assert(Client != NULL);
|
||||
assert(Req != NULL);
|
||||
|
||||
/* Bad number of prameters? */
|
||||
if (Req->argc < 1 || Req->argc > 2)
|
||||
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
|
||||
Client_ID(Client), Req->command);
|
||||
|
||||
LogDebug("Got \"%s %s\" command from \"%s\" ...",
|
||||
Req->command, Req->argv[0], Client_ID(Client));
|
||||
|
||||
if (Req->argc == 1) {
|
||||
if (strcasecmp(Req->argv[0], "CLEAR") == 0)
|
||||
return Handle_CAP_CLEAR(Client);
|
||||
if (strcasecmp(Req->argv[0], "END") == 0)
|
||||
return Handle_CAP_END(Client);
|
||||
}
|
||||
if (Req->argc >= 1 && Req->argc <= 2) {
|
||||
if (strcasecmp(Req->argv[0], "LS") == 0)
|
||||
return Handle_CAP_LS(Client, Req->argv[1]);
|
||||
if (strcasecmp(Req->argv[0], "LIST") == 0)
|
||||
return Handle_CAP_LIST(Client, Req->argv[1]);
|
||||
}
|
||||
if (Req->argc == 2) {
|
||||
if (strcasecmp(Req->argv[0], "REQ") == 0)
|
||||
return Handle_CAP_REQ(Client, Req->argv[1]);
|
||||
if (strcasecmp(Req->argv[0], "ACK") == 0)
|
||||
return Handle_CAP_ACK(Client, Req->argv[1]);
|
||||
}
|
||||
|
||||
return IRC_WriteStrClient(Client, ERR_INVALIDCAP_MSG,
|
||||
Client_ID(Client), Req->argv[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler for the "CAP LS" command.
|
||||
*
|
||||
* @param Client The client from which this command has been received.
|
||||
* @param Arg Command argument or NULL.
|
||||
* @returns CONNECTED or DISCONNECTED.
|
||||
*/
|
||||
bool
|
||||
Handle_CAP_LS(CLIENT *Client, UNUSED char *Arg)
|
||||
{
|
||||
assert(Client != NULL);
|
||||
|
||||
Set_CAP_Negotiation(Client);
|
||||
|
||||
return IRC_WriteStrClient(Client,
|
||||
"CAP %s LS :multi-prefix",
|
||||
Client_ID(Client));
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler for the "CAP LIST" command.
|
||||
*
|
||||
* @param Client The client from which this command has been received.
|
||||
* @param Arg Command argument or NULL.
|
||||
* @returns CONNECTED or DISCONNECTED.
|
||||
*/
|
||||
bool
|
||||
Handle_CAP_LIST(CLIENT *Client, UNUSED char *Arg)
|
||||
{
|
||||
assert(Client != NULL);
|
||||
|
||||
return IRC_WriteStrClient(Client, "CAP %s LIST :%s", Client_ID(Client),
|
||||
Get_CAP_String(Client_Cap(Client)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler for the "CAP REQ" command.
|
||||
*
|
||||
* @param Client The client from which this command has been received.
|
||||
* @param Arg Command argument.
|
||||
* @returns CONNECTED or DISCONNECTED.
|
||||
*/
|
||||
bool
|
||||
Handle_CAP_REQ(CLIENT *Client, char *Arg)
|
||||
{
|
||||
int new_cap;
|
||||
|
||||
assert(Client != NULL);
|
||||
assert(Arg != NULL);
|
||||
|
||||
Set_CAP_Negotiation(Client);
|
||||
|
||||
new_cap = Parse_CAP(Client_Cap(Client), Arg);
|
||||
|
||||
if (new_cap < 0)
|
||||
return IRC_WriteStrClient(Client, "CAP %s NAK :%s",
|
||||
Client_ID(Client), Arg);
|
||||
|
||||
Client_CapSet(Client, new_cap);
|
||||
return IRC_WriteStrClient(Client, "CAP %s ACK :%s",
|
||||
Client_ID(Client), Arg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler for the "CAP ACK" command.
|
||||
*
|
||||
* @param Client The client from which this command has been received.
|
||||
* @param Arg Command argument.
|
||||
* @returns CONNECTED or DISCONNECTED.
|
||||
*/
|
||||
bool
|
||||
Handle_CAP_ACK(UNUSED CLIENT *Client, UNUSED char *Arg)
|
||||
{
|
||||
assert(Client != NULL);
|
||||
assert(Arg != NULL);
|
||||
|
||||
return CONNECTED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler for the "CAP CLEAR" command.
|
||||
*
|
||||
* @param Client The client from which this command has been received.
|
||||
* @returns CONNECTED or DISCONNECTED.
|
||||
*/
|
||||
bool
|
||||
Handle_CAP_CLEAR(CLIENT *Client)
|
||||
{
|
||||
int cap_old;
|
||||
|
||||
assert(Client != NULL);
|
||||
|
||||
cap_old = Client_Cap(Client);
|
||||
if (cap_old & CLIENT_CAP_MULTI_PREFIX)
|
||||
Client_CapDel(Client, CLIENT_CAP_MULTI_PREFIX);
|
||||
|
||||
return IRC_WriteStrClient(Client, "CAP %s ACK :%s", Client_ID(Client),
|
||||
Get_CAP_String(cap_old));
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler for the "CAP END" command.
|
||||
*
|
||||
* @param Client The client from which this command has been received.
|
||||
* @returns CONNECTED or DISCONNECTED.
|
||||
*/
|
||||
bool
|
||||
Handle_CAP_END(CLIENT *Client)
|
||||
{
|
||||
assert(Client != NULL);
|
||||
|
||||
if (Client_Type(Client) != CLIENT_USER) {
|
||||
/* User is still logging in ... */
|
||||
Client_CapDel(Client, CLIENT_CAP_PENDING);
|
||||
|
||||
if (Client_Type(Client) == CLIENT_WAITCAPEND) {
|
||||
/* Only "CAP END" was missing: log in! */
|
||||
return Login_User(Client);
|
||||
}
|
||||
}
|
||||
|
||||
return CONNECTED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set CAP negotiation status and mark client as "supports capabilities".
|
||||
*
|
||||
* @param Client The client to handle.
|
||||
*/
|
||||
void
|
||||
Set_CAP_Negotiation(CLIENT *Client)
|
||||
{
|
||||
assert(Client != NULL);
|
||||
|
||||
if (Client_Type(Client) != CLIENT_USER)
|
||||
Client_CapAdd(Client, CLIENT_CAP_PENDING);
|
||||
Client_CapAdd(Client, CLIENT_CAP_SUPPORTED);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse capability string and return numeric flag value.
|
||||
*
|
||||
* @param Args The string containing space-separated capability names.
|
||||
* @return Changed capability flags or 0 on error.
|
||||
*/
|
||||
int
|
||||
Parse_CAP(int Capabilities, char *Args)
|
||||
{
|
||||
static char tmp[COMMAND_LEN];
|
||||
char *ptr;
|
||||
|
||||
assert(Args != NULL);
|
||||
|
||||
strlcpy(tmp, Args, sizeof(tmp));
|
||||
|
||||
ptr = strtok(tmp, " ");
|
||||
while (ptr) {
|
||||
if (*ptr == '-') {
|
||||
/* drop capabilities */
|
||||
ptr++;
|
||||
if (strcmp(ptr, "multi-prefix") == 0)
|
||||
Capabilities &= ~CLIENT_CAP_MULTI_PREFIX;
|
||||
else
|
||||
return -1;
|
||||
} else {
|
||||
/* request capabilities */
|
||||
if (strcmp(ptr, "multi-prefix") == 0)
|
||||
Capabilities |= CLIENT_CAP_MULTI_PREFIX;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
ptr = strtok(NULL, " ");
|
||||
}
|
||||
|
||||
return Capabilities;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return textual representation of capability flags.
|
||||
*
|
||||
* Please note: this function returns a pointer to a global buffer and
|
||||
* therefore isn't thread safe!
|
||||
*
|
||||
* @param Capabilities Capability flags (bitmask).
|
||||
* @return Pointer to textual representation.
|
||||
*/
|
||||
char *
|
||||
Get_CAP_String(int Capabilities)
|
||||
{
|
||||
static char txt[COMMAND_LEN];
|
||||
|
||||
txt[0] = '\0';
|
||||
|
||||
if (Capabilities & CLIENT_CAP_MULTI_PREFIX)
|
||||
strlcat(txt, "multi-prefix ", sizeof(txt));
|
||||
|
||||
return txt;
|
||||
}
|
||||
|
||||
/* -eof- */
|
24
src/ngircd/irc-cap.h
Normal file
24
src/ngircd/irc-cap.h
Normal file
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __irc_cap_h__
|
||||
#define __irc_cap_h__
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Handler for IRC capability ("CAP") commands (header)
|
||||
*/
|
||||
|
||||
GLOBAL bool IRC_CAP PARAMS((CLIENT *Client, REQUEST *Req));
|
||||
|
||||
#endif
|
||||
|
||||
/* -eof- */
|
@@ -167,8 +167,10 @@ 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'))
|
||||
/* If the channel is persistent (+P) and client is an IRC op:
|
||||
* make client chanop, if not disabled in configuration. */
|
||||
if (strchr(Channel_Modes(chan), 'P') && Conf_OperChanPAutoOp
|
||||
&& strchr(Client_Modes(target), 'o'))
|
||||
Channel_UserModeAdd(chan, target, 'o');
|
||||
} /* join_set_channelmodes */
|
||||
|
||||
@@ -363,7 +365,7 @@ IRC_JOIN( CLIENT *Client, REQUEST *Req )
|
||||
chan = Channel_Search(channame);
|
||||
if (!chan && Conf_PredefChannelsOnly) {
|
||||
/* channel must be created, but forbidden by config */
|
||||
IRC_WriteStrClient(Client, ERR_BANNEDFROMCHAN_MSG,
|
||||
IRC_WriteStrClient(Client, ERR_NOSUCHCHANNEL_MSG,
|
||||
Client_ID(Client), channame);
|
||||
goto join_next;
|
||||
}
|
||||
@@ -510,7 +512,7 @@ IRC_TOPIC( CLIENT *Client, REQUEST *Req )
|
||||
CHANNEL *chan;
|
||||
CLIENT *from;
|
||||
char *topic;
|
||||
bool onchannel, topicok, use_servermode, r;
|
||||
bool r, topic_power;
|
||||
|
||||
assert( Client != NULL );
|
||||
assert( Req != NULL );
|
||||
@@ -533,12 +535,17 @@ IRC_TOPIC( CLIENT *Client, REQUEST *Req )
|
||||
return IRC_WriteStrClient(from, ERR_NOSUCHCHANNEL_MSG,
|
||||
Client_ID(from), Req->argv[0]);
|
||||
|
||||
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]);
|
||||
/* Only remote servers and channel members are allowed to change the
|
||||
* channel topic, and IRC opreators when the Conf_OperCanMode option
|
||||
* is set in the server configuration. */
|
||||
if (Client_Type(Client) != CLIENT_SERVER) {
|
||||
topic_power = Client_HasMode(from, 'o');
|
||||
if (!Channel_IsMemberOf(chan, from)
|
||||
&& !(Conf_OperCanMode && topic_power))
|
||||
return IRC_WriteStrClient(from, ERR_NOTONCHANNEL_MSG,
|
||||
Client_ID(from), Req->argv[0]);
|
||||
} else
|
||||
topic_power = true;
|
||||
|
||||
if (Req->argc == 1) {
|
||||
/* Request actual topic */
|
||||
@@ -565,8 +572,12 @@ IRC_TOPIC( CLIENT *Client, REQUEST *Req )
|
||||
}
|
||||
|
||||
if (strchr(Channel_Modes(chan), 't')) {
|
||||
/* Topic Lock. Is the user a channel or IRC operator? */
|
||||
if (!topicok)
|
||||
/* Topic Lock. Is the user a channel op or IRC operator? */
|
||||
if(!topic_power &&
|
||||
!strchr(Channel_UserModes(chan, from), 'h') &&
|
||||
!strchr(Channel_UserModes(chan, from), 'o') &&
|
||||
!strchr(Channel_UserModes(chan, from), 'a') &&
|
||||
!strchr(Channel_UserModes(chan, from), 'q'))
|
||||
return IRC_WriteStrClient(from, ERR_CHANOPRIVSNEEDED_MSG,
|
||||
Client_ID(from),
|
||||
Channel_Name(chan));
|
||||
@@ -578,7 +589,7 @@ IRC_TOPIC( CLIENT *Client, REQUEST *Req )
|
||||
Client_TypeText(from), Client_Mask(from), Channel_Name(chan),
|
||||
Req->argv[1][0] ? Req->argv[1] : "<none>");
|
||||
|
||||
if (use_servermode)
|
||||
if (Conf_OperServerMode)
|
||||
from = Client_ThisServer();
|
||||
|
||||
/* Update channel and forward new topic to other servers */
|
||||
@@ -666,10 +677,12 @@ IRC_LIST( CLIENT *Client, REQUEST *Req )
|
||||
if (MatchCaseInsensitive(pattern, Channel_Name(chan))) {
|
||||
/* Gotcha! */
|
||||
if (!strchr(Channel_Modes(chan), 's')
|
||||
|| Channel_IsMemberOf(chan, from)) {
|
||||
if (IRC_CheckListTooBig(from, count,
|
||||
MAX_RPL_LIST,
|
||||
"LIST"))
|
||||
|| Channel_IsMemberOf(chan, from)
|
||||
|| (!Conf_MorePrivacy && Client_OperByMe(Client))) {
|
||||
if ((Conf_MaxListSize > 0)
|
||||
&& IRC_CheckListTooBig(from, count,
|
||||
Conf_MaxListSize,
|
||||
"LIST"))
|
||||
break;
|
||||
if (!IRC_WriteStrClient(from,
|
||||
RPL_LIST_MSG, Client_ID(from),
|
||||
|
68
src/ngircd/irc-encoding.c
Normal file
68
src/ngircd/irc-encoding.c
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* 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
|
||||
* IRC encoding commands
|
||||
*/
|
||||
|
||||
#include "imp.h"
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "conn-func.h"
|
||||
#include "channel.h"
|
||||
#include "conn-encoding.h"
|
||||
#include "irc-write.h"
|
||||
#include "messages.h"
|
||||
#include "parse.h"
|
||||
#include "tool.h"
|
||||
|
||||
#include "exp.h"
|
||||
#include "irc-encoding.h"
|
||||
|
||||
#ifdef ICONV
|
||||
|
||||
/**
|
||||
* Handler for the IRC+ "CHARCONV" command.
|
||||
*
|
||||
* @param Client The client from which this command has been received.
|
||||
* @param Req Request structure with prefix and all parameters.
|
||||
* @returns CONNECTED or DISCONNECTED.
|
||||
*/
|
||||
GLOBAL bool
|
||||
IRC_CHARCONV(CLIENT *Client, REQUEST *Req)
|
||||
{
|
||||
char encoding[20];
|
||||
|
||||
assert (Client != NULL);
|
||||
assert (Req != NULL);
|
||||
|
||||
if (Req->argc != 1)
|
||||
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
|
||||
Client_ID(Client), Req->command);
|
||||
|
||||
strlcpy(encoding, Req->argv[0], sizeof(encoding));
|
||||
ngt_UpperStr(encoding);
|
||||
|
||||
if (!Conn_SetEncoding(Client_Conn(Client), encoding))
|
||||
return IRC_WriteStrClient(Client, ERR_IP_CHARCONV_MSG,
|
||||
Client_ID(Client), encoding);
|
||||
|
||||
return IRC_WriteStrClient(Client, RPL_IP_CHARCONV_MSG,
|
||||
Client_ID(Client), encoding);
|
||||
} /* IRC_CHARCONV */
|
||||
|
||||
#endif
|
||||
|
||||
/* -eof- */
|
24
src/ngircd/irc-encoding.h
Normal file
24
src/ngircd/irc-encoding.h
Normal file
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
* Please read the file COPYING, README and AUTHORS for more information.
|
||||
*/
|
||||
|
||||
#ifndef __irc_encoding_h__
|
||||
#define __irc_encoding_h__
|
||||
|
||||
/**
|
||||
* @file
|
||||
* IRC encoding commands (header)
|
||||
*/
|
||||
|
||||
GLOBAL bool IRC_CHARCONV PARAMS((CLIENT *Client, REQUEST *Req));
|
||||
|
||||
#endif
|
||||
|
||||
/* -eof- */
|
@@ -39,6 +39,7 @@
|
||||
#include "parse.h"
|
||||
#include "irc.h"
|
||||
#include "irc-write.h"
|
||||
#include "client-cap.h"
|
||||
|
||||
#include "exp.h"
|
||||
#include "irc-info.h"
|
||||
@@ -116,7 +117,7 @@ IRC_INFO(CLIENT * Client, REQUEST * Req)
|
||||
target = Client_Search(Req->argv[0]);
|
||||
else
|
||||
target = Client_ThisServer();
|
||||
|
||||
|
||||
/* Make sure that the target is a server */
|
||||
if (target && Client_Type(target) != CLIENT_SERVER)
|
||||
target = Client_Introducer(target);
|
||||
@@ -726,7 +727,7 @@ IRC_USERHOST(CLIENT *Client, REQUEST *Req)
|
||||
strlcat(rpl, "+", sizeof(rpl));
|
||||
strlcat(rpl, Client_User(c), sizeof(rpl));
|
||||
strlcat(rpl, "@", sizeof(rpl));
|
||||
strlcat(rpl, Client_HostnameCloaked(c), sizeof(rpl));
|
||||
strlcat(rpl, Client_HostnameDisplayed(c), sizeof(rpl));
|
||||
strlcat(rpl, " ", sizeof(rpl));
|
||||
}
|
||||
}
|
||||
@@ -791,7 +792,7 @@ write_whoreply(CLIENT *Client, CLIENT *c, const char *channelname, const char *f
|
||||
{
|
||||
return IRC_WriteStrClient(Client, RPL_WHOREPLY_MSG, Client_ID(Client),
|
||||
channelname, Client_User(c),
|
||||
Client_HostnameCloaked(c),
|
||||
Client_HostnameDisplayed(c),
|
||||
Client_ID(Client_Introducer(c)), Client_ID(c),
|
||||
flags, Client_Hops(c), Client_Info(c));
|
||||
}
|
||||
@@ -806,14 +807,48 @@ who_flags_status(const char *client_modes)
|
||||
}
|
||||
|
||||
|
||||
static const char *
|
||||
who_flags_qualifier(const char *chan_user_modes)
|
||||
/**
|
||||
* Return channel user mode prefix(es).
|
||||
*
|
||||
* @param Client The client requesting the mode prefixes.
|
||||
* @param chan_user_modes String with channel user modes.
|
||||
* @param str String buffer to which the prefix(es) will be appended.
|
||||
* @param len Size of "str" buffer.
|
||||
* @return Pointer to "str".
|
||||
*/
|
||||
static char *
|
||||
who_flags_qualifier(CLIENT *Client, const char *chan_user_modes,
|
||||
char *str, size_t len)
|
||||
{
|
||||
if (strchr(chan_user_modes, 'o'))
|
||||
return "@";
|
||||
assert(Client != NULL);
|
||||
|
||||
if (Client_Cap(Client) & CLIENT_CAP_MULTI_PREFIX) {
|
||||
if (strchr(chan_user_modes, 'q'))
|
||||
strlcat(str, "~", len);
|
||||
if (strchr(chan_user_modes, 'a'))
|
||||
strlcat(str, "&", len);
|
||||
if (strchr(chan_user_modes, 'o'))
|
||||
strlcat(str, "@", len);
|
||||
if (strchr(chan_user_modes, 'h'))
|
||||
strlcat(str, "%", len);
|
||||
if (strchr(chan_user_modes, 'v'))
|
||||
strlcat(str, "+", len);
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
if (strchr(chan_user_modes, 'q'))
|
||||
strlcat(str, "~", len);
|
||||
else if (strchr(chan_user_modes, 'a'))
|
||||
strlcat(str, "&", len);
|
||||
else if (strchr(chan_user_modes, 'o'))
|
||||
strlcat(str, "@", len);
|
||||
else if (strchr(chan_user_modes, 'h'))
|
||||
strlcat(str, "%", len);
|
||||
else if (strchr(chan_user_modes, 'v'))
|
||||
return "+";
|
||||
return "";
|
||||
strlcat(str, "+", len);
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
@@ -831,14 +866,15 @@ IRC_WHO_Channel(CLIENT *Client, CHANNEL *Chan, bool OnlyOps)
|
||||
bool is_visible, is_member, is_ircop;
|
||||
CL2CHAN *cl2chan;
|
||||
const char *client_modes;
|
||||
const char *chan_user_modes;
|
||||
char flags[8];
|
||||
char flags[10];
|
||||
CLIENT *c;
|
||||
int count = 0;
|
||||
|
||||
assert( Client != NULL );
|
||||
assert( Chan != NULL );
|
||||
|
||||
IRC_SetPenalty(Client, 1);
|
||||
|
||||
is_member = Channel_IsMemberOf(Chan, Client);
|
||||
|
||||
/* Secret channel? */
|
||||
@@ -857,16 +893,12 @@ IRC_WHO_Channel(CLIENT *Client, CHANNEL *Chan, bool OnlyOps)
|
||||
|
||||
is_visible = strchr(client_modes, 'i') == NULL;
|
||||
if (is_member || is_visible) {
|
||||
if (IRC_CheckListTooBig(Client, count, MAX_RPL_WHO, "WHO"))
|
||||
break;
|
||||
|
||||
strcpy(flags, who_flags_status(client_modes));
|
||||
if (is_ircop)
|
||||
strlcat(flags, "*", sizeof(flags));
|
||||
|
||||
chan_user_modes = Channel_UserModes(Chan, c);
|
||||
strlcat(flags, who_flags_qualifier(chan_user_modes),
|
||||
sizeof(flags));
|
||||
who_flags_qualifier(Client, Channel_UserModes(Chan, c),
|
||||
flags, sizeof(flags));
|
||||
|
||||
if (!write_whoreply(Client, c, Channel_Name(Chan),
|
||||
flags))
|
||||
@@ -874,6 +906,11 @@ IRC_WHO_Channel(CLIENT *Client, CHANNEL *Chan, bool OnlyOps)
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
/* If there are a lot of clients, augment penalty a bit */
|
||||
if (count > MAX_RPL_WHO)
|
||||
IRC_SetPenalty(Client, 1);
|
||||
|
||||
return IRC_WriteStrClient(Client, RPL_ENDOFWHO_MSG, Client_ID(Client),
|
||||
Channel_Name(Chan));
|
||||
}
|
||||
@@ -902,6 +939,7 @@ IRC_WHO_Mask(CLIENT *Client, char *Mask, bool OnlyOps)
|
||||
if (Mask)
|
||||
ngt_LowerStr(Mask);
|
||||
|
||||
IRC_SetPenalty(Client, 3);
|
||||
for (c = Client_First(); c != NULL; c = Client_Next(c)) {
|
||||
if (Client_Type(c) != CLIENT_USER)
|
||||
continue;
|
||||
@@ -912,7 +950,7 @@ IRC_WHO_Mask(CLIENT *Client, char *Mask, bool OnlyOps)
|
||||
if (Mask) {
|
||||
/* Match pattern against user host/server/name/nick */
|
||||
client_match = MatchCaseInsensitive(Mask,
|
||||
Client_Hostname(c));
|
||||
Client_HostnameDisplayed(c));
|
||||
if (!client_match)
|
||||
client_match = MatchCaseInsensitive(Mask,
|
||||
Client_ID(Client_Introducer(c)));
|
||||
@@ -949,7 +987,7 @@ IRC_WHO_Mask(CLIENT *Client, char *Mask, bool OnlyOps)
|
||||
if (IRC_CheckListTooBig(Client, count, MAX_RPL_WHO, "WHO"))
|
||||
break;
|
||||
|
||||
strcpy(flags, who_flags_status(Client_Modes(c)));
|
||||
strlcpy(flags, who_flags_status(Client_Modes(c)), sizeof(flags));
|
||||
if (strchr(Client_Modes(c), 'o'))
|
||||
strlcat(flags, "*", sizeof(flags));
|
||||
|
||||
@@ -1005,13 +1043,11 @@ IRC_WHO(CLIENT *Client, REQUEST *Req)
|
||||
chan = Channel_Search(Req->argv[0]);
|
||||
if (chan) {
|
||||
/* Members of a channel have been requested */
|
||||
IRC_SetPenalty(Client, 1);
|
||||
return IRC_WHO_Channel(Client, chan, only_ops);
|
||||
}
|
||||
if (strcmp(Req->argv[0], "0") != 0) {
|
||||
/* A mask has been given. But please note this RFC
|
||||
* stupidity: "0" is same as no arguments ... */
|
||||
IRC_SetPenalty(Client, 3);
|
||||
return IRC_WHO_Mask(Client, Req->argv[0], only_ops);
|
||||
}
|
||||
}
|
||||
@@ -1044,7 +1080,7 @@ IRC_WHOIS_SendReply(CLIENT *Client, CLIENT *from, CLIENT *c)
|
||||
/* Nick, user, hostname and client info */
|
||||
if (!IRC_WriteStrClient(from, RPL_WHOISUSER_MSG, Client_ID(from),
|
||||
Client_ID(c), Client_User(c),
|
||||
Client_HostnameCloaked(c), Client_Info(c)))
|
||||
Client_HostnameDisplayed(c), Client_Info(c)))
|
||||
return DISCONNECTED;
|
||||
|
||||
/* Server */
|
||||
@@ -1078,8 +1114,8 @@ IRC_WHOIS_SendReply(CLIENT *Client, CLIENT *from, CLIENT *c)
|
||||
if (str[strlen(str) - 1] != ':')
|
||||
strlcat(str, " ", sizeof(str));
|
||||
|
||||
strlcat(str, who_flags_qualifier(Channel_UserModes(chan, c)),
|
||||
sizeof(str));
|
||||
who_flags_qualifier(Client, Channel_UserModes(chan, c),
|
||||
str, sizeof(str));
|
||||
strlcat(str, Channel_Name(chan), sizeof(str));
|
||||
|
||||
if (strlen(str) > (LINE_LEN - CHANNEL_NAME_LEN - 4)) {
|
||||
@@ -1102,23 +1138,37 @@ IRC_WHOIS_SendReply(CLIENT *Client, CLIENT *from, CLIENT *c)
|
||||
Client_ID(from), Client_ID(c)))
|
||||
return DISCONNECTED;
|
||||
|
||||
/* IRC-Bot? */
|
||||
if (Client_HasMode(c, 'B') &&
|
||||
!IRC_WriteStrClient(from, RPL_WHOISBOT_MSG,
|
||||
Client_ID(from), Client_ID(c)))
|
||||
return DISCONNECTED;
|
||||
|
||||
/* Connected using SSL? */
|
||||
if (Conn_UsesSSL(Client_Conn(c)) &&
|
||||
!IRC_WriteStrClient(from, RPL_WHOISSSL_MSG, Client_ID(from),
|
||||
Client_ID(c)))
|
||||
return DISCONNECTED;
|
||||
|
||||
/* Registered nick name? */
|
||||
/* Registered nickname? */
|
||||
if (Client_HasMode(c, 'R') &&
|
||||
!IRC_WriteStrClient(from, RPL_WHOISREGNICK_MSG,
|
||||
Client_ID(from), Client_ID(c)))
|
||||
return DISCONNECTED;
|
||||
|
||||
if (Client_Conn(c) > NONE && (Client_OperByMe(from) || from == c) &&
|
||||
!IRC_WriteStrClient(from, RPL_WHOISHOST_MSG, Client_ID(from),
|
||||
Client_ID(c), Client_Hostname(c),
|
||||
Conn_GetIPAInfo(Client_Conn(c))))
|
||||
return DISCONNECTED;
|
||||
/* Local client and requester is the user itself or an IRC Op? */
|
||||
if (Client_Conn(c) > NONE &&
|
||||
(from == c || (!Conf_MorePrivacy && Client_HasMode(from, 'o')))) {
|
||||
/* Client hostname */
|
||||
if (!IRC_WriteStrClient(from, RPL_WHOISHOST_MSG,
|
||||
Client_ID(from), Client_ID(c), Client_Hostname(c),
|
||||
Conn_GetIPAInfo(Client_Conn(c))))
|
||||
return DISCONNECTED;
|
||||
/* Client modes */
|
||||
if (!IRC_WriteStrClient(from, RPL_WHOISMODES_MSG,
|
||||
Client_ID(from), Client_ID(c), Client_Modes(c)))
|
||||
return DISCONNECTED;
|
||||
}
|
||||
|
||||
/* Idle and signon time (local clients only!) */
|
||||
if (!Conf_MorePrivacy && Client_Conn(c) > NONE &&
|
||||
@@ -1178,7 +1228,7 @@ IRC_WHOIS( CLIENT *Client, REQUEST *Req )
|
||||
/* 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: */
|
||||
* nickname on that server as well: */
|
||||
target = Client_Search(Req->argv[0]);
|
||||
if (!target)
|
||||
return IRC_WriteStrClient(from, ERR_NOSUCHSERVER_MSG,
|
||||
@@ -1447,7 +1497,7 @@ IRC_Send_LUSERS(CLIENT *Client)
|
||||
Conn_CountMax(), Conn_CountAccepted()))
|
||||
return DISCONNECTED;
|
||||
#endif
|
||||
|
||||
|
||||
return CONNECTED;
|
||||
} /* IRC_Send_LUSERS */
|
||||
|
||||
@@ -1468,7 +1518,15 @@ Show_MOTD_Sendline(CLIENT *Client, const char *msg)
|
||||
static bool
|
||||
Show_MOTD_End(CLIENT *Client)
|
||||
{
|
||||
return IRC_WriteStrClient( Client, RPL_ENDOFMOTD_MSG, Client_ID( Client ));
|
||||
if (!IRC_WriteStrClient(Client, RPL_ENDOFMOTD_MSG, Client_ID(Client)))
|
||||
return DISCONNECTED;
|
||||
|
||||
if (*Conf_CloakHost)
|
||||
return IRC_WriteStrClient(Client, RPL_HOSTHIDDEN_MSG,
|
||||
Client_ID(Client),
|
||||
Client_Hostname(Client));
|
||||
|
||||
return CONNECTED;
|
||||
}
|
||||
|
||||
#ifdef SSL_SUPPORT
|
||||
@@ -1524,60 +1582,70 @@ IRC_Show_MOTD( CLIENT *Client )
|
||||
} /* IRC_Show_MOTD */
|
||||
|
||||
|
||||
/**
|
||||
* Send NAMES reply for a specific client and channel.
|
||||
*
|
||||
* @param Client The client requesting the NAMES information.
|
||||
* @param Chan The channel
|
||||
* @return CONNECTED or DISCONNECTED.
|
||||
*/
|
||||
GLOBAL bool
|
||||
IRC_Send_NAMES( CLIENT *Client, CHANNEL *Chan )
|
||||
IRC_Send_NAMES(CLIENT * Client, CHANNEL * Chan)
|
||||
{
|
||||
bool is_visible, is_member;
|
||||
char str[LINE_LEN + 1];
|
||||
CL2CHAN *cl2chan;
|
||||
CLIENT *cl;
|
||||
|
||||
assert( Client != NULL );
|
||||
assert( Chan != NULL );
|
||||
assert(Client != NULL);
|
||||
assert(Chan != NULL);
|
||||
|
||||
if( Channel_IsMemberOf( Chan, Client )) is_member = true;
|
||||
else is_member = false;
|
||||
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;
|
||||
if (!is_member && strchr(Channel_Modes(Chan), 's'))
|
||||
return CONNECTED;
|
||||
|
||||
/* Alle Mitglieder suchen */
|
||||
snprintf( str, sizeof( str ), RPL_NAMREPLY_MSG, Client_ID( Client ), "=", Channel_Name( Chan ));
|
||||
cl2chan = Channel_FirstMember( Chan );
|
||||
while( cl2chan )
|
||||
{
|
||||
cl = Channel_GetClient( cl2chan );
|
||||
snprintf(str, sizeof(str), RPL_NAMREPLY_MSG, Client_ID(Client), "=",
|
||||
Channel_Name(Chan));
|
||||
cl2chan = Channel_FirstMember(Chan);
|
||||
while (cl2chan) {
|
||||
cl = Channel_GetClient(cl2chan);
|
||||
|
||||
if( strchr( Client_Modes( cl ), 'i' )) is_visible = false;
|
||||
else is_visible = true;
|
||||
if (strchr(Client_Modes(cl), 'i'))
|
||||
is_visible = false;
|
||||
else
|
||||
is_visible = true;
|
||||
|
||||
if( is_member || is_visible )
|
||||
{
|
||||
/* Nick anhaengen */
|
||||
if( str[strlen( str ) - 1] != ':' ) strlcat( str, " ", sizeof( str ));
|
||||
if( strchr( Channel_UserModes( Chan, cl ), 'o' )) strlcat( str, "@", sizeof( str ));
|
||||
else if( strchr( Channel_UserModes( Chan, cl ), 'v' )) strlcat( str, "+", sizeof( str ));
|
||||
strlcat( str, Client_ID( cl ), sizeof( str ));
|
||||
if (is_member || is_visible) {
|
||||
if (str[strlen(str) - 1] != ':')
|
||||
strlcat(str, " ", sizeof(str));
|
||||
|
||||
if( strlen( str ) > ( LINE_LEN - CLIENT_NICK_LEN - 4 ))
|
||||
{
|
||||
/* Zeile wird zu lang: senden! */
|
||||
if( ! IRC_WriteStrClient( Client, "%s", str )) return DISCONNECTED;
|
||||
snprintf( str, sizeof( str ), RPL_NAMREPLY_MSG, Client_ID( Client ), "=", Channel_Name( Chan ));
|
||||
who_flags_qualifier(Client, Channel_UserModes(Chan, cl),
|
||||
str, sizeof(str));
|
||||
strlcat(str, Client_ID(cl), sizeof(str));
|
||||
|
||||
if (strlen(str) > (LINE_LEN - CLIENT_NICK_LEN - 4)) {
|
||||
if (!IRC_WriteStrClient(Client, "%s", str))
|
||||
return DISCONNECTED;
|
||||
snprintf(str, sizeof(str), RPL_NAMREPLY_MSG,
|
||||
Client_ID(Client), "=",
|
||||
Channel_Name(Chan));
|
||||
}
|
||||
}
|
||||
|
||||
/* naechstes Mitglied suchen */
|
||||
cl2chan = Channel_NextMember( Chan, cl2chan );
|
||||
cl2chan = Channel_NextMember(Chan, cl2chan);
|
||||
}
|
||||
if( str[strlen( str ) - 1] != ':')
|
||||
{
|
||||
/* Es sind noch Daten da, die gesendet werden muessen */
|
||||
if( ! IRC_WriteStrClient( Client, "%s", str )) return DISCONNECTED;
|
||||
if (str[strlen(str) - 1] != ':') {
|
||||
if (!IRC_WriteStrClient(Client, "%s", str))
|
||||
return DISCONNECTED;
|
||||
}
|
||||
|
||||
return CONNECTED;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors.
|
||||
* Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -18,22 +18,18 @@
|
||||
|
||||
#include "imp.h"
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "ngircd.h"
|
||||
#include "conn-func.h"
|
||||
#include "class.h"
|
||||
#include "conf.h"
|
||||
#include "channel.h"
|
||||
#include "io.h"
|
||||
#include "log.h"
|
||||
#include "login.h"
|
||||
#include "messages.h"
|
||||
#include "pam.h"
|
||||
#include "parse.h"
|
||||
#include "irc.h"
|
||||
#include "irc-info.h"
|
||||
@@ -42,18 +38,10 @@
|
||||
#include "exp.h"
|
||||
#include "irc-login.h"
|
||||
|
||||
static void Kill_Nick PARAMS((char *Nick, char *Reason));
|
||||
static void Change_Nick PARAMS((CLIENT * Origin, CLIENT * Target, char *NewNick,
|
||||
bool InformClient));
|
||||
|
||||
static bool Hello_User PARAMS(( CLIENT *Client ));
|
||||
static bool Hello_User_PostAuth PARAMS(( CLIENT *Client ));
|
||||
static void Kill_Nick PARAMS(( char *Nick, char *Reason ));
|
||||
static void Introduce_Client PARAMS((CLIENT *To, CLIENT *Client, int Type));
|
||||
|
||||
static void cb_introduceClient PARAMS((CLIENT *Client, CLIENT *Prefix,
|
||||
void *i));
|
||||
|
||||
#ifdef PAM
|
||||
static void cb_Read_Auth_Result PARAMS((int r_fd, UNUSED short events));
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Handler for the IRC "PASS" command.
|
||||
@@ -103,7 +91,7 @@ IRC_PASS( CLIENT *Client, REQUEST *Req )
|
||||
Client_ID(Client));
|
||||
}
|
||||
|
||||
Client_SetPassword(Client, Req->argv[0]);
|
||||
Conn_SetPassword(Client_Conn(Client), Req->argv[0]);
|
||||
|
||||
/* Protocol version */
|
||||
if (Req->argc >= 2 && strlen(Req->argv[1]) >= 4) {
|
||||
@@ -285,45 +273,14 @@ IRC_NICK( CLIENT *Client, REQUEST *Req )
|
||||
/* If we received a valid USER command already then
|
||||
* register the new client! */
|
||||
if( Client_Type( Client ) == CLIENT_GOTUSER )
|
||||
return Hello_User( Client );
|
||||
return Login_User( Client );
|
||||
else
|
||||
Client_SetType( Client, CLIENT_GOTNICK );
|
||||
} else {
|
||||
/* Nickname change */
|
||||
if (Client_Conn(target) > NONE) {
|
||||
/* Local client */
|
||||
Log(LOG_INFO,
|
||||
"%s \"%s\" changed nick (connection %d): \"%s\" -> \"%s\".",
|
||||
Client_TypeText(target), Client_Mask(target),
|
||||
Client_Conn(target), Client_ID(target),
|
||||
Req->argv[0]);
|
||||
Conn_UpdateIdle(Client_Conn(target));
|
||||
} else {
|
||||
/* Remote client */
|
||||
LogDebug("%s \"%s\" changed nick: \"%s\" -> \"%s\".",
|
||||
Client_TypeText(target),
|
||||
Client_Mask(target), Client_ID(target),
|
||||
Req->argv[0]);
|
||||
}
|
||||
|
||||
/* Inform all users and servers (which have to know)
|
||||
* of this nickname change */
|
||||
if( Client_Type( Client ) == CLIENT_USER )
|
||||
IRC_WriteStrClientPrefix( Client, Client,
|
||||
"NICK :%s",
|
||||
Req->argv[0] );
|
||||
IRC_WriteStrServersPrefix( Client, target,
|
||||
"NICK :%s", Req->argv[0] );
|
||||
IRC_WriteStrRelatedPrefix( target, target, false,
|
||||
"NICK :%s", Req->argv[0] );
|
||||
|
||||
/* Register old nickname for WHOWAS queries */
|
||||
Client_RegisterWhowas( target );
|
||||
|
||||
/* Save new nickname */
|
||||
Client_SetID( target, Req->argv[0] );
|
||||
|
||||
IRC_SetPenalty( target, 2 );
|
||||
Change_Nick(Client, target, Req->argv[0],
|
||||
Client_Type(Client) == CLIENT_USER ? true : false);
|
||||
IRC_SetPenalty(target, 2);
|
||||
}
|
||||
|
||||
return CONNECTED;
|
||||
@@ -395,7 +352,7 @@ IRC_NICK( CLIENT *Client, REQUEST *Req )
|
||||
Client_Mask(c));
|
||||
Client_SetType(c, CLIENT_GOTNICK);
|
||||
} else
|
||||
Introduce_Client(Client, c, CLIENT_USER);
|
||||
Client_Introduce(Client, c, CLIENT_USER);
|
||||
|
||||
return CONNECTED;
|
||||
}
|
||||
@@ -403,6 +360,54 @@ IRC_NICK( CLIENT *Client, REQUEST *Req )
|
||||
} /* IRC_NICK */
|
||||
|
||||
|
||||
/**
|
||||
* Handler for the IRC "SVSNICK" command.
|
||||
*
|
||||
* @param Client The client from which this command has been received.
|
||||
* @param Req Request structure with prefix and all parameters.
|
||||
* @return CONNECTED or DISCONNECTED.
|
||||
*/
|
||||
GLOBAL bool
|
||||
IRC_SVSNICK(CLIENT *Client, REQUEST *Req)
|
||||
{
|
||||
CLIENT *from, *target;
|
||||
|
||||
assert(Client != NULL);
|
||||
assert(Req != NULL);
|
||||
|
||||
if (Req->argc != 2)
|
||||
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
|
||||
Client_ID(Client), Req->command);
|
||||
|
||||
/* Search the originator */
|
||||
from = Client_Search(Req->prefix);
|
||||
if (!from)
|
||||
from = Client;
|
||||
|
||||
/* Search the target */
|
||||
target = Client_Search(Req->argv[0]);
|
||||
if (!target || Client_Type(target) != CLIENT_USER) {
|
||||
return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG,
|
||||
Client_ID(Client), Req->argv[0]);
|
||||
}
|
||||
|
||||
if (Client_Conn(target) <= NONE) {
|
||||
/* We have to forward the message to the server handling
|
||||
* this user; this is required to make sure all servers
|
||||
* in the network do follow the nick name change! */
|
||||
return IRC_WriteStrClientPrefix(Client_NextHop(target), from,
|
||||
"SVSNICK %s %s",
|
||||
Req->argv[0], Req->argv[1]);
|
||||
}
|
||||
|
||||
/* Make sure that the new nickname is valid */
|
||||
if (!Client_CheckNick(from, Req->argv[1]))
|
||||
return CONNECTED;
|
||||
|
||||
Change_Nick(from, target, Req->argv[1], true);
|
||||
return CONNECTED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler for the IRC "USER" command.
|
||||
*
|
||||
@@ -416,9 +421,7 @@ GLOBAL bool
|
||||
IRC_USER(CLIENT * Client, REQUEST * Req)
|
||||
{
|
||||
CLIENT *c;
|
||||
#ifdef IDENTAUTH
|
||||
char *ptr;
|
||||
#endif
|
||||
|
||||
assert(Client != NULL);
|
||||
assert(Req != NULL);
|
||||
@@ -436,7 +439,20 @@ IRC_USER(CLIENT * Client, REQUEST * Req)
|
||||
Client_ID(Client),
|
||||
Req->command);
|
||||
|
||||
/* User name */
|
||||
/* User name: only alphanumeric characters and limited
|
||||
punctuation is allowed.*/
|
||||
ptr = Req->argv[0];
|
||||
while (*ptr) {
|
||||
if (!isalnum((int)*ptr) &&
|
||||
*ptr != '+' && *ptr != '-' &&
|
||||
*ptr != '.' && *ptr != '_') {
|
||||
Conn_Close(Client_Conn(Client), NULL,
|
||||
"Invalid user name", true);
|
||||
return DISCONNECTED;
|
||||
}
|
||||
ptr++;
|
||||
}
|
||||
|
||||
#ifdef IDENTAUTH
|
||||
ptr = Client_User(Client);
|
||||
if (!ptr || !*ptr || *ptr == '~')
|
||||
@@ -457,7 +473,7 @@ IRC_USER(CLIENT * Client, REQUEST * Req)
|
||||
LogDebug("Connection %d: got valid USER command ...",
|
||||
Client_Conn(Client));
|
||||
if (Client_Type(Client) == CLIENT_GOTNICK)
|
||||
return Hello_User(Client);
|
||||
return Login_User(Client);
|
||||
else
|
||||
Client_SetType(Client, CLIENT_GOTUSER);
|
||||
return CONNECTED;
|
||||
@@ -487,7 +503,7 @@ IRC_USER(CLIENT * Client, REQUEST * Req)
|
||||
/* RFC 1459 style user registration?
|
||||
* Introduce client to network: */
|
||||
if (Client_Type(c) == CLIENT_GOTNICK)
|
||||
Introduce_Client(Client, c, CLIENT_USER);
|
||||
Client_Introduce(Client, c, CLIENT_USER);
|
||||
|
||||
return CONNECTED;
|
||||
} else if (Client_Type(Client) == CLIENT_USER) {
|
||||
@@ -550,10 +566,10 @@ IRC_SERVICE(CLIENT *Client, REQUEST *Req)
|
||||
hops = atoi(Req->argv[4]);
|
||||
info = Req->argv[5];
|
||||
|
||||
/* Validate service name ("nick name") */
|
||||
/* Validate service name ("nickname") */
|
||||
c = Client_Search(nick);
|
||||
if(c) {
|
||||
/* Nick name collission: disconnect (KILL) both clients! */
|
||||
/* Nickname collission: disconnect (KILL) both clients! */
|
||||
Log(LOG_ERR, "Server %s introduces already registered service \"%s\"!",
|
||||
Client_ID(Client), nick);
|
||||
Kill_Nick(nick, "Nick collision");
|
||||
@@ -601,7 +617,7 @@ IRC_SERVICE(CLIENT *Client, REQUEST *Req)
|
||||
return CONNECTED;
|
||||
}
|
||||
|
||||
Introduce_Client(Client, c, CLIENT_SERVICE);
|
||||
Client_Introduce(Client, c, CLIENT_SERVICE);
|
||||
return CONNECTED;
|
||||
} /* IRC_SERVICE */
|
||||
|
||||
@@ -880,7 +896,7 @@ IRC_PONG(CLIENT *Client, REQUEST *Req)
|
||||
if (auth_ping == atoi(Req->argv[0])) {
|
||||
Conn_SetAuthPing(conn, 0);
|
||||
if (Client_Type(Client) == CLIENT_WAITAUTHPING)
|
||||
Hello_User(Client);
|
||||
Login_User(Client);
|
||||
} else
|
||||
if (!IRC_WriteStrClient(Client,
|
||||
"To connect, type /QUOTE PONG %ld",
|
||||
@@ -904,199 +920,9 @@ IRC_PONG(CLIENT *Client, REQUEST *Req)
|
||||
|
||||
|
||||
/**
|
||||
* Initiate client registration.
|
||||
* Kill all users with a specific nickname in the network.
|
||||
*
|
||||
* 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;
|
||||
pid_t pid;
|
||||
#endif
|
||||
CONN_ID conn;
|
||||
|
||||
assert(Client != NULL);
|
||||
conn = Client_Conn(Client);
|
||||
|
||||
#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
|
||||
* passwords supplied are classified as "wrong". */
|
||||
if(Client_Password(Client)[0] == '\0')
|
||||
return Hello_User_PostAuth(Client);
|
||||
Client_Reject(Client, "Non-empty password", false);
|
||||
return DISCONNECTED;
|
||||
}
|
||||
|
||||
if (Conf_PAMIsOptional && strcmp(Client_Password(Client), "") == 0) {
|
||||
/* Clients are not required to send a password and to be PAM-
|
||||
* authenticated at all. If not, they won't become "identified"
|
||||
* and keep the "~" in their supplied user name.
|
||||
* Therefore it is sensible to either set Conf_PAMisOptional or
|
||||
* to enable IDENT lookups -- not both. */
|
||||
return Hello_User_PostAuth(Client);
|
||||
}
|
||||
|
||||
/* Fork child process for PAM authentication; and make sure that the
|
||||
* process timeout is set higher than the login timeout! */
|
||||
pid = Proc_Fork(Conn_GetProcStat(conn), pipefd,
|
||||
cb_Read_Auth_Result, Conf_PongTimeout + 1);
|
||||
if (pid > 0) {
|
||||
LogDebug("Authenticator for connection %d created (PID %d).",
|
||||
conn, pid);
|
||||
return CONNECTED;
|
||||
} else {
|
||||
/* Sub process */
|
||||
Log_Init_Subprocess("Auth");
|
||||
Conn_CloseAllSockets(NONE);
|
||||
result = PAM_Authenticate(Client);
|
||||
if (write(pipefd[1], &result, sizeof(result)) != sizeof(result))
|
||||
Log_Subprocess(LOG_ERR,
|
||||
"Failed to pipe result to parent!");
|
||||
Log_Exit_Subprocess("Auth");
|
||||
exit(0);
|
||||
}
|
||||
#else
|
||||
/* Check global server password ... */
|
||||
if (strcmp(Client_Password(Client), Conf_ServerPwd) != 0) {
|
||||
/* Bad password! */
|
||||
Client_Reject(Client, "Bad server password", false);
|
||||
return DISCONNECTED;
|
||||
}
|
||||
return Hello_User_PostAuth(Client);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#ifdef PAM
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
CONN_ID conn;
|
||||
CLIENT *client;
|
||||
int result;
|
||||
size_t len;
|
||||
PROC_STAT *proc;
|
||||
|
||||
LogDebug("Auth: Got callback on fd %d, events %d", r_fd, events);
|
||||
conn = Conn_GetFromProc(r_fd);
|
||||
if (conn == NONE) {
|
||||
/* Ops, none found? Probably the connection has already
|
||||
* been closed!? We'll ignore that ... */
|
||||
io_close(r_fd);
|
||||
LogDebug("Auth: Got callback for unknown connection!?");
|
||||
return;
|
||||
}
|
||||
proc = Conn_GetProcStat(conn);
|
||||
client = Conn_GetClient(conn);
|
||||
|
||||
/* Read result from pipe */
|
||||
len = Proc_Read(proc, &result, sizeof(result));
|
||||
Proc_Close(proc);
|
||||
if (len == 0)
|
||||
return;
|
||||
|
||||
if (len != sizeof(result)) {
|
||||
Log(LOG_CRIT, "Auth: Got malformed result!");
|
||||
Client_Reject(client, "Internal error", false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (result == true) {
|
||||
Client_SetUser(client, Client_OrigUser(client), true);
|
||||
(void)Hello_User_PostAuth(client);
|
||||
} else
|
||||
Client_Reject(client, "Bad password", false);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
assert(Client != NULL);
|
||||
|
||||
if (Class_HandleServerBans(Client) != CONNECTED)
|
||||
return DISCONNECTED;
|
||||
|
||||
Introduce_Client(NULL, Client, CLIENT_USER);
|
||||
|
||||
if (!IRC_WriteStrClient
|
||||
(Client, RPL_WELCOME_MSG, Client_ID(Client), Client_Mask(Client)))
|
||||
return false;
|
||||
if (!IRC_WriteStrClient
|
||||
(Client, RPL_YOURHOST_MSG, Client_ID(Client),
|
||||
Client_ID(Client_ThisServer()), PACKAGE_VERSION, TARGET_CPU,
|
||||
TARGET_VENDOR, TARGET_OS))
|
||||
return false;
|
||||
if (!IRC_WriteStrClient
|
||||
(Client, RPL_CREATED_MSG, Client_ID(Client), NGIRCd_StartStr))
|
||||
return false;
|
||||
if (!IRC_WriteStrClient
|
||||
(Client, RPL_MYINFO_MSG, Client_ID(Client),
|
||||
Client_ID(Client_ThisServer()), PACKAGE_VERSION, USERMODES,
|
||||
CHANMODES))
|
||||
return false;
|
||||
|
||||
/* Features supported by this server (005 numeric, ISUPPORT),
|
||||
* see <http://www.irc.org/tech_docs/005.html> for details. */
|
||||
if (!IRC_Send_ISUPPORT(Client))
|
||||
return DISCONNECTED;
|
||||
|
||||
if (!IRC_Send_LUSERS(Client))
|
||||
return DISCONNECTED;
|
||||
if (!IRC_Show_MOTD(Client))
|
||||
return DISCONNECTED;
|
||||
|
||||
/* Suspend the client for a second ... */
|
||||
IRC_SetPenalty(Client, 1);
|
||||
|
||||
return CONNECTED;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Kill all users with a specific nick name in the network.
|
||||
*
|
||||
* @param Nick Nick name.
|
||||
* @param Nick Nickname.
|
||||
* @param Reason Reason for the KILL.
|
||||
*/
|
||||
static void
|
||||
@@ -1120,96 +946,43 @@ Kill_Nick(char *Nick, char *Reason)
|
||||
|
||||
|
||||
/**
|
||||
* Introduce a new user or service client in the network.
|
||||
* Change the nickname of a client.
|
||||
*
|
||||
* @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).
|
||||
* @param Origin The client which caused the nickname change.
|
||||
* @param Target The client of which the nickname should be changed.
|
||||
* @param NewNick The new nickname.
|
||||
*/
|
||||
static void
|
||||
Introduce_Client(CLIENT *From, CLIENT *Client, int Type)
|
||||
Change_Nick(CLIENT *Origin, CLIENT *Target, char *NewNick, bool InformClient)
|
||||
{
|
||||
/* Set client type (user or service) */
|
||||
Client_SetType(Client, Type);
|
||||
|
||||
if (From) {
|
||||
if (Conf_IsService(Conf_GetServer(Client_Conn(From)),
|
||||
Client_ID(Client)))
|
||||
Client_SetType(Client, CLIENT_SERVICE);
|
||||
LogDebug("%s \"%s\" (+%s) registered (via %s, on %s, %d hop%s).",
|
||||
Client_TypeText(Client), Client_Mask(Client),
|
||||
Client_Modes(Client), Client_ID(From),
|
||||
Client_ID(Client_Introducer(Client)),
|
||||
Client_Hops(Client), Client_Hops(Client) > 1 ? "s": "");
|
||||
if (Client_Conn(Target) > NONE) {
|
||||
/* Local client */
|
||||
Log(LOG_INFO,
|
||||
"%s \"%s\" changed nick (connection %d): \"%s\" -> \"%s\".",
|
||||
Client_TypeText(Target), Client_Mask(Target),
|
||||
Client_Conn(Target), Client_ID(Target), NewNick);
|
||||
Conn_UpdateIdle(Client_Conn(Target));
|
||||
} else {
|
||||
Log(LOG_NOTICE, "%s \"%s\" registered (connection %d).",
|
||||
Client_TypeText(Client), Client_Mask(Client),
|
||||
Client_Conn(Client));
|
||||
Log_ServerNotice('c', "Client connecting: %s (%s@%s) [%s] - %s",
|
||||
Client_ID(Client), Client_User(Client),
|
||||
Client_Hostname(Client),
|
||||
Conn_IPA(Client_Conn(Client)),
|
||||
Client_TypeText(Client));
|
||||
/* Remote client */
|
||||
LogDebug("%s \"%s\" changed nick: \"%s\" -> \"%s\".",
|
||||
Client_TypeText(Target),
|
||||
Client_Mask(Target), Client_ID(Target), NewNick);
|
||||
}
|
||||
|
||||
/* Inform other servers */
|
||||
IRC_WriteStrServersPrefixFlag_CB(From,
|
||||
From != NULL ? From : Client_ThisServer(),
|
||||
'\0', cb_introduceClient, (void *)Client);
|
||||
} /* Introduce_Client */
|
||||
/* Inform all servers and users (which have to know) of the new name */
|
||||
if (InformClient) {
|
||||
IRC_WriteStrClientPrefix(Target, Target, "NICK :%s", NewNick);
|
||||
IRC_WriteStrServersPrefix(NULL, Target, "NICK :%s", NewNick);
|
||||
} else
|
||||
IRC_WriteStrServersPrefix(Origin, Target, "NICK :%s", NewNick);
|
||||
IRC_WriteStrRelatedPrefix(Target, Target, false, "NICK :%s", NewNick);
|
||||
|
||||
/* Register old nickname for WHOWAS queries */
|
||||
Client_RegisterWhowas(Target);
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
CLIENT *c = (CLIENT *)data;
|
||||
CONN_ID conn;
|
||||
char *modes, *user, *host;
|
||||
|
||||
modes = Client_Modes(c);
|
||||
user = Client_User(c) ? Client_User(c) : "-";
|
||||
host = Client_Hostname(c) ? Client_Hostname(c) : "-";
|
||||
|
||||
conn = Client_Conn(To);
|
||||
if (Conn_Options(conn) & CONN_RFC1459) {
|
||||
/* RFC 1459 mode: separate NICK and USER commands */
|
||||
Conn_WriteStr(conn, "NICK %s :%d", Client_ID(c),
|
||||
Client_Hops(c) + 1);
|
||||
Conn_WriteStr(conn, ":%s USER %s %s %s :%s",
|
||||
Client_ID(c), user, host,
|
||||
Client_ID(Client_Introducer(c)), Client_Info(c));
|
||||
if (modes[0])
|
||||
Conn_WriteStr(conn, ":%s MODE %s +%s",
|
||||
Client_ID(c), Client_ID(c), modes);
|
||||
} else {
|
||||
/* RFC 2813 mode: one combined NICK or SERVICE command */
|
||||
if (Client_Type(c) == CLIENT_SERVICE
|
||||
&& strchr(Client_Flags(To), 'S'))
|
||||
IRC_WriteStrClientPrefix(To, Prefix,
|
||||
"SERVICE %s %d * +%s %d :%s",
|
||||
Client_Mask(c),
|
||||
Client_MyToken(Client_Introducer(c)),
|
||||
Client_Modes(c), Client_Hops(c) + 1,
|
||||
Client_Info(c));
|
||||
else
|
||||
IRC_WriteStrClientPrefix(To, Prefix,
|
||||
"NICK %s %d %s %s %d +%s :%s",
|
||||
Client_ID(c), Client_Hops(c) + 1,
|
||||
user, host,
|
||||
Client_MyToken(Client_Introducer(c)),
|
||||
modes, Client_Info(c));
|
||||
}
|
||||
} /* cb_introduceClient */
|
||||
/* Save new nickname */
|
||||
Client_SetID(Target, NewNick);
|
||||
}
|
||||
|
||||
|
||||
/* -eof- */
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* Copyright (c)2001-2010 Alexander Barton (alex@barton.de)
|
||||
* Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -26,6 +26,7 @@ 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));
|
||||
GLOBAL bool IRC_SVSNICK PARAMS(( CLIENT *Client, REQUEST *Req ));
|
||||
|
||||
#endif
|
||||
|
||||
|
109
src/ngircd/irc-metadata.c
Normal file
109
src/ngircd/irc-metadata.c
Normal file
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#define __irc_metadata_c__
|
||||
|
||||
#include "portab.h"
|
||||
|
||||
/**
|
||||
* @file
|
||||
* IRC metadata commands
|
||||
*/
|
||||
|
||||
#include "imp.h"
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "conn-func.h"
|
||||
#include "channel.h"
|
||||
#include "conn-encoding.h"
|
||||
#include "irc-write.h"
|
||||
#include "log.h"
|
||||
#include "messages.h"
|
||||
#include "parse.h"
|
||||
#include "tool.h"
|
||||
|
||||
#include "exp.h"
|
||||
#include "irc-metadata.h"
|
||||
|
||||
/**
|
||||
* Handler for the IRC+ "METADATA" command.
|
||||
*
|
||||
* @param Client The client from which this command has been received.
|
||||
* @param Req Request structure with prefix and all parameters.
|
||||
* @returns CONNECTED or DISCONNECTED.
|
||||
*/
|
||||
GLOBAL bool
|
||||
IRC_METADATA(CLIENT *Client, REQUEST *Req)
|
||||
{
|
||||
CLIENT *prefix, *target;
|
||||
char new_flags[COMMAND_LEN];
|
||||
|
||||
assert(Client != NULL);
|
||||
assert(Req != NULL);
|
||||
|
||||
if (Req->argc != 3)
|
||||
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
|
||||
Client_ID(Client), Req->command);
|
||||
|
||||
prefix = Client_Search(Req->prefix);
|
||||
if (!prefix)
|
||||
return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG,
|
||||
Client_ID(Client), Req->prefix);
|
||||
|
||||
target = Client_Search(Req->argv[0]);
|
||||
if (!target)
|
||||
return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG,
|
||||
Client_ID(Client), Req->argv[0]);
|
||||
|
||||
LogDebug("Got \"METADATA\" command from \"%s\" for client \"%s\": \"%s=%s\".",
|
||||
Client_ID(prefix), Client_ID(target),
|
||||
Req->argv[1], Req->argv[2]);
|
||||
|
||||
/* Mark client: it has receiveda a METADATA command */
|
||||
if (!strchr(Client_Flags(target), 'M')) {
|
||||
snprintf(new_flags, sizeof new_flags, "%sM",
|
||||
Client_Flags(target));
|
||||
Client_SetFlags(target, new_flags);
|
||||
}
|
||||
|
||||
if (strcasecmp(Req->argv[1], "cloakhost") == 0) {
|
||||
Client_UpdateCloakedHostname(target, prefix, Req->argv[2]);
|
||||
if (Client_Conn(target) > NONE && Client_HasMode(target, 'x'))
|
||||
IRC_WriteStrClientPrefix(target, prefix,
|
||||
RPL_HOSTHIDDEN_MSG, Client_ID(target),
|
||||
Client_HostnameDisplayed(target));
|
||||
/* The Client_UpdateCloakedHostname() function already
|
||||
* forwarded the METADATA command, don't do it twice: */
|
||||
return CONNECTED;
|
||||
}
|
||||
else if (*Req->argv[2] && strcasecmp(Req->argv[1], "host") == 0) {
|
||||
Client_SetHostname(target, Req->argv[2]);
|
||||
if (Client_Conn(target) > NONE && !Client_HasMode(target, 'x'))
|
||||
IRC_WriteStrClientPrefix(target, prefix,
|
||||
RPL_HOSTHIDDEN_MSG, Client_ID(target),
|
||||
Client_HostnameDisplayed(target));
|
||||
} else if (strcasecmp(Req->argv[1], "info") == 0)
|
||||
Client_SetInfo(target, Req->argv[2]);
|
||||
else if (*Req->argv[2] && strcasecmp(Req->argv[1], "user") == 0)
|
||||
Client_SetUser(target, Req->argv[2], true);
|
||||
else
|
||||
Log(LOG_WARNING,
|
||||
"Ignored metadata update from \"%s\" for client \"%s\": \"%s=%s\" - unknown key!",
|
||||
Client_ID(Client), Client_ID(target),
|
||||
Req->argv[1], Req->argv[2]);
|
||||
|
||||
/* Forward the METADATA command to peers that support it: */
|
||||
IRC_WriteStrServersPrefixFlag(Client, prefix, 'M', "METADATA %s %s :%s",
|
||||
Client_ID(target), Req->argv[1], Req->argv[2]);
|
||||
return CONNECTED;
|
||||
}
|
24
src/ngircd/irc-metadata.h
Normal file
24
src/ngircd/irc-metadata.h
Normal file
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
* Please read the file COPYING, README and AUTHORS for more information.
|
||||
*/
|
||||
|
||||
#ifndef __irc_metadata_h__
|
||||
#define __irc_metadata_h__
|
||||
|
||||
/**
|
||||
* @file
|
||||
* IRC metadata commands (header)
|
||||
*/
|
||||
|
||||
GLOBAL bool IRC_METADATA PARAMS((CLIENT *Client, REQUEST *Req));
|
||||
|
||||
#endif
|
||||
|
||||
/* -eof- */
|
@@ -138,6 +138,7 @@ Client_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *Target )
|
||||
{
|
||||
char the_modes[COMMAND_LEN], x[2], *mode_ptr;
|
||||
bool ok, set;
|
||||
bool send_RPL_HOSTHIDDEN_MSG = false;
|
||||
int mode_arg;
|
||||
size_t len;
|
||||
|
||||
@@ -153,7 +154,7 @@ Client_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *Target )
|
||||
/* Mode request: let's answer it :-) */
|
||||
if (Req->argc == 1)
|
||||
return IRC_WriteStrClient(Origin, RPL_UMODEIS_MSG,
|
||||
Client_ID(Origin),
|
||||
Client_ID(Target),
|
||||
Client_Modes(Target));
|
||||
|
||||
mode_arg = 1;
|
||||
@@ -214,6 +215,7 @@ Client_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *Target )
|
||||
/* Validate modes */
|
||||
x[0] = '\0';
|
||||
switch (*mode_ptr) {
|
||||
case 'b': /* Block private msgs */
|
||||
case 'C': /* Only messages from clients sharing a channel */
|
||||
case 'i': /* Invisible */
|
||||
case 's': /* Server messages */
|
||||
@@ -229,6 +231,14 @@ Client_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *Target )
|
||||
ERR_NOPRIVILEGES_MSG,
|
||||
Client_ID(Origin));
|
||||
break;
|
||||
case 'B': /* Bot */
|
||||
if (Client_HasMode(Client, 'r'))
|
||||
ok = IRC_WriteStrClient(Origin,
|
||||
ERR_RESTRICTED_MSG,
|
||||
Client_ID(Origin));
|
||||
else
|
||||
x[0] = 'B';
|
||||
break;
|
||||
case 'c': /* Receive connect notices
|
||||
* (only settable by IRC operators!) */
|
||||
if (!set || Client_Type(Client) == CLIENT_SERVER
|
||||
@@ -248,6 +258,15 @@ Client_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *Target )
|
||||
ERR_NOPRIVILEGES_MSG,
|
||||
Client_ID(Origin));
|
||||
break;
|
||||
case 'q': /* KICK-protected user */
|
||||
if (!set || Client_Type(Client) == CLIENT_SERVER
|
||||
|| Client_OperByMe(Origin))
|
||||
x[0] = 'q';
|
||||
else
|
||||
ok = IRC_WriteStrClient(Origin,
|
||||
ERR_NOPRIVILEGES_MSG,
|
||||
Client_ID(Origin));
|
||||
break;
|
||||
case 'r': /* Restricted (only settable) */
|
||||
if (set || Client_Type(Client) == CLIENT_SERVER)
|
||||
x[0] = 'r';
|
||||
@@ -256,13 +275,28 @@ Client_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *Target )
|
||||
ERR_RESTRICTED_MSG,
|
||||
Client_ID(Origin));
|
||||
break;
|
||||
case 'R': /* Registered (not [un]settable by clients) */
|
||||
if (Client_Type(Client) == CLIENT_SERVER)
|
||||
x[0] = 'R';
|
||||
else
|
||||
ok = IRC_WriteStrClient(Origin,
|
||||
ERR_NICKREGISTER_MSG,
|
||||
Client_ID(Origin));
|
||||
break;
|
||||
case 'x': /* Cloak hostname */
|
||||
if (Client_HasMode(Client, 'r'))
|
||||
ok = IRC_WriteStrClient(Origin,
|
||||
ERR_RESTRICTED_MSG,
|
||||
Client_ID(Origin));
|
||||
else
|
||||
else if (!set || Conf_CloakHostModeX[0]
|
||||
|| Client_Type(Client) == CLIENT_SERVER
|
||||
|| Client_OperByMe(Client)) {
|
||||
x[0] = 'x';
|
||||
send_RPL_HOSTHIDDEN_MSG = true;
|
||||
} else
|
||||
ok = IRC_WriteStrClient(Origin,
|
||||
ERR_NOPRIVILEGES_MSG,
|
||||
Client_ID(Origin));
|
||||
break;
|
||||
default:
|
||||
if (Client_Type(Client) != CLIENT_SERVER) {
|
||||
@@ -333,6 +367,16 @@ Client_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *Target )
|
||||
Client_ID(Target),
|
||||
the_modes);
|
||||
}
|
||||
|
||||
if (send_RPL_HOSTHIDDEN_MSG && Client_Conn(Target) > NONE) {
|
||||
/* A new (cloaked) hostname must be annoucned */
|
||||
IRC_WriteStrClientPrefix(Target, Origin,
|
||||
RPL_HOSTHIDDEN_MSG,
|
||||
Client_ID(Target),
|
||||
Client_HostnameDisplayed(Target));
|
||||
|
||||
}
|
||||
|
||||
LogDebug("%s \"%s\": Mode change, now \"%s\".",
|
||||
Client_TypeText(Target), Client_Mask(Target),
|
||||
Client_Modes(Target));
|
||||
@@ -396,13 +440,16 @@ static bool
|
||||
Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
|
||||
{
|
||||
char the_modes[COMMAND_LEN], the_args[COMMAND_LEN], x[2],
|
||||
argadd[CLIENT_PASS_LEN], *mode_ptr;
|
||||
bool connected, set, skiponce, retval, onchannel, modeok, use_servermode;
|
||||
argadd[CLIENT_PASS_LEN], *mode_ptr, *o_mode_ptr;
|
||||
bool connected, set, skiponce, retval, use_servermode,
|
||||
is_halfop, is_op, is_admin, is_owner, is_machine, is_oper;
|
||||
int mode_arg, arg_arg, mode_arg_count = 0;
|
||||
CLIENT *client;
|
||||
long l;
|
||||
size_t len;
|
||||
|
||||
is_halfop = is_op = is_admin = is_owner = is_machine = is_oper = false;
|
||||
|
||||
if (Channel_IsModeless(Channel))
|
||||
return IRC_WriteStrClient(Client, ERR_NOCHANMODES_MSG,
|
||||
Client_ID(Client), Channel_Name(Channel));
|
||||
@@ -411,10 +458,20 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
|
||||
if (Req->argc <= 1)
|
||||
return Channel_Mode_Answer_Request(Origin, Channel);
|
||||
|
||||
Channel_CheckAdminRights(Channel, Client, Origin,
|
||||
&onchannel, &modeok, &use_servermode);
|
||||
/* Check if origin is oper and opers can use mode */
|
||||
use_servermode = Conf_OperServerMode;
|
||||
if(Client_OperByMe(Client) && Conf_OperCanMode) {
|
||||
is_oper = true;
|
||||
}
|
||||
|
||||
if (!onchannel && !modeok)
|
||||
/* Check if client is a server/service */
|
||||
if(Client_Type(Client) == CLIENT_SERVER ||
|
||||
Client_Type(Client) == CLIENT_SERVICE) {
|
||||
is_machine = true;
|
||||
}
|
||||
|
||||
/* Check if client is member of channel or an oper or an server/service */
|
||||
if(!Channel_IsMemberOf(Channel, Client) && !is_oper && !is_machine)
|
||||
return IRC_WriteStrClient(Origin, ERR_NOTONCHANNEL_MSG,
|
||||
Client_ID(Origin),
|
||||
Channel_Name(Channel));
|
||||
@@ -493,20 +550,46 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
|
||||
if (arg_arg >= Req->argc)
|
||||
arg_arg = -1;
|
||||
|
||||
if(!is_machine && !is_oper) {
|
||||
o_mode_ptr = Channel_UserModes(Channel, Client);
|
||||
while( *o_mode_ptr ) {
|
||||
if ( *o_mode_ptr == 'q')
|
||||
is_owner = true;
|
||||
if ( *o_mode_ptr == 'a')
|
||||
is_admin = true;
|
||||
if ( *o_mode_ptr == 'o')
|
||||
is_op = true;
|
||||
if ( *o_mode_ptr == 'h')
|
||||
is_halfop = true;
|
||||
o_mode_ptr++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Validate modes */
|
||||
x[0] = '\0';
|
||||
argadd[0] = '\0';
|
||||
client = NULL;
|
||||
switch (*mode_ptr) {
|
||||
/* --- Channel modes --- */
|
||||
case 'i': /* Invite only */
|
||||
case 'm': /* Moderated */
|
||||
case 'n': /* Only members can write */
|
||||
case 'R': /* Registered users only */
|
||||
case 's': /* Secret channel */
|
||||
case 't': /* Topic locked */
|
||||
case 'z': /* Secure connections only */
|
||||
if (modeok)
|
||||
if(!is_oper && !is_machine && !is_owner &&
|
||||
!is_admin && !is_op) {
|
||||
connected = IRC_WriteStrClient(Origin,
|
||||
ERR_CHANOPRIVSNEEDED_MSG,
|
||||
Client_ID(Origin), Channel_Name(Channel));
|
||||
goto chan_exit;
|
||||
}
|
||||
case 'i': /* Invite only */
|
||||
case 'V': /* Invite disallow */
|
||||
case 'M': /* Only identified nicks can write */
|
||||
case 'm': /* Moderated */
|
||||
case 'n': /* Only members can write */
|
||||
case 'Q': /* No kicks */
|
||||
case 't': /* Topic locked */
|
||||
if(is_oper || is_machine || is_owner ||
|
||||
is_admin || is_op || is_halfop)
|
||||
x[0] = *mode_ptr;
|
||||
else
|
||||
connected = IRC_WriteStrClient(Origin,
|
||||
@@ -517,7 +600,8 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
|
||||
if (Mode_Limit_Reached(Client, mode_arg_count++))
|
||||
goto chan_exit;
|
||||
if (!set) {
|
||||
if (modeok)
|
||||
if (is_oper || is_machine || is_owner ||
|
||||
is_admin || is_op || is_halfop)
|
||||
x[0] = *mode_ptr;
|
||||
else
|
||||
connected = IRC_WriteStrClient(Origin,
|
||||
@@ -527,7 +611,8 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
|
||||
break;
|
||||
}
|
||||
if (arg_arg > mode_arg) {
|
||||
if (modeok) {
|
||||
if (is_oper || is_machine || is_owner ||
|
||||
is_admin || is_op || is_halfop) {
|
||||
Channel_ModeDel(Channel, 'k');
|
||||
Channel_SetKey(Channel,
|
||||
Req->argv[arg_arg]);
|
||||
@@ -543,9 +628,13 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
|
||||
Req->argv[arg_arg][0] = '\0';
|
||||
arg_arg++;
|
||||
} else {
|
||||
#ifdef STRICT_RFC
|
||||
/* Only send error message in "strict" mode,
|
||||
* this is how ircd2.11 and others behave ... */
|
||||
connected = IRC_WriteStrClient(Origin,
|
||||
ERR_NEEDMOREPARAMS_MSG,
|
||||
Client_ID(Origin), Req->command);
|
||||
#endif
|
||||
goto chan_exit;
|
||||
}
|
||||
break;
|
||||
@@ -553,7 +642,8 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
|
||||
if (Mode_Limit_Reached(Client, mode_arg_count++))
|
||||
goto chan_exit;
|
||||
if (!set) {
|
||||
if (modeok)
|
||||
if (is_oper || is_machine || is_owner ||
|
||||
is_admin || is_op || is_halfop)
|
||||
x[0] = *mode_ptr;
|
||||
else
|
||||
connected = IRC_WriteStrClient(Origin,
|
||||
@@ -563,7 +653,8 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
|
||||
break;
|
||||
}
|
||||
if (arg_arg > mode_arg) {
|
||||
if (modeok) {
|
||||
if (is_oper || is_machine || is_owner ||
|
||||
is_admin || is_op || is_halfop) {
|
||||
l = atol(Req->argv[arg_arg]);
|
||||
if (l > 0 && l < 0xFFFF) {
|
||||
Channel_ModeDel(Channel, 'l');
|
||||
@@ -581,68 +672,93 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
|
||||
Req->argv[arg_arg][0] = '\0';
|
||||
arg_arg++;
|
||||
} else {
|
||||
#ifdef STRICT_RFC
|
||||
/* Only send error message in "strict" mode,
|
||||
* this is how ircd2.11 and others behave ... */
|
||||
connected = IRC_WriteStrClient(Origin,
|
||||
ERR_NEEDMOREPARAMS_MSG,
|
||||
Client_ID(Origin), Req->command);
|
||||
#endif
|
||||
goto chan_exit;
|
||||
}
|
||||
break;
|
||||
case 'O': /* IRC operators only */
|
||||
if (modeok) {
|
||||
if (set) {
|
||||
/* Only IRC operators are allowed to
|
||||
* set the 'O' channel mode! */
|
||||
if (set && !(Client_OperByMe(Client)
|
||||
|| Client_Type(Client) == CLIENT_SERVER))
|
||||
if(is_oper || is_machine)
|
||||
x[0] = 'O';
|
||||
else
|
||||
connected = IRC_WriteStrClient(Origin,
|
||||
ERR_NOPRIVILEGES_MSG,
|
||||
Client_ID(Origin));
|
||||
else
|
||||
x[0] = 'O';
|
||||
} else
|
||||
} else if(is_oper || is_machine || is_owner ||
|
||||
is_admin || is_op)
|
||||
x[0] = 'O';
|
||||
else
|
||||
connected = IRC_WriteStrClient(Origin,
|
||||
ERR_CHANOPRIVSNEEDED_MSG,
|
||||
Client_ID(Origin),
|
||||
Channel_Name(Channel));
|
||||
break;
|
||||
ERR_CHANOPRIVSNEEDED_MSG,
|
||||
Client_ID(Origin),
|
||||
Channel_Name(Channel));
|
||||
break;
|
||||
case 'P': /* Persistent channel */
|
||||
if (modeok) {
|
||||
if (set) {
|
||||
/* Only IRC operators are allowed to
|
||||
* set the 'P' channel mode! */
|
||||
if (set && !(Client_OperByMe(Client)
|
||||
|| Client_Type(Client) == CLIENT_SERVER))
|
||||
if(is_oper || is_machine)
|
||||
x[0] = 'P';
|
||||
else
|
||||
connected = IRC_WriteStrClient(Origin,
|
||||
ERR_NOPRIVILEGES_MSG,
|
||||
Client_ID(Origin));
|
||||
else
|
||||
x[0] = 'P';
|
||||
} else
|
||||
} else if(is_oper || is_machine || is_owner ||
|
||||
is_admin || is_op)
|
||||
x[0] = 'P';
|
||||
else
|
||||
connected = IRC_WriteStrClient(Origin,
|
||||
ERR_CHANOPRIVSNEEDED_MSG,
|
||||
Client_ID(Origin),
|
||||
Channel_Name(Channel));
|
||||
break;
|
||||
/* --- Channel user modes --- */
|
||||
case 'a':
|
||||
case 'h':
|
||||
case 'q':
|
||||
if (Client_Type(Client) != CLIENT_SERVER) {
|
||||
case 'q': /* Owner */
|
||||
case 'a': /* Channel admin */
|
||||
if(!is_oper && !is_machine && !is_owner && !is_admin) {
|
||||
connected = IRC_WriteStrClient(Origin,
|
||||
ERR_CHANOPPRIVTOOLOW_MSG,
|
||||
Client_ID(Origin),
|
||||
Channel_Name(Channel));
|
||||
goto chan_exit;
|
||||
}
|
||||
case 'o': /* Channel operator */
|
||||
if(!is_oper && !is_machine && !is_owner &&
|
||||
!is_admin && !is_op) {
|
||||
connected = IRC_WriteStrClient(Origin,
|
||||
ERR_CHANOPRIVSNEEDED_MSG,
|
||||
Client_ID(Origin),
|
||||
Channel_Name(Channel));
|
||||
goto chan_exit;
|
||||
}
|
||||
case 'h': /* Half Op */
|
||||
if(!is_oper && !is_machine && !is_owner &&
|
||||
!is_admin && !is_op) {
|
||||
connected = IRC_WriteStrClient(Origin,
|
||||
ERR_CHANOPRIVSNEEDED_MSG,
|
||||
Client_ID(Origin),
|
||||
Channel_Name(Channel));
|
||||
goto chan_exit;
|
||||
}
|
||||
case 'o': /* Channel operator */
|
||||
case 'v': /* Voice */
|
||||
if (arg_arg > mode_arg) {
|
||||
if (modeok) {
|
||||
if (is_oper || is_machine || is_owner ||
|
||||
is_admin || is_op || is_halfop) {
|
||||
client = Client_Search(Req->argv[arg_arg]);
|
||||
if (client)
|
||||
x[0] = *mode_ptr;
|
||||
else
|
||||
connected = IRC_WriteStrClient(Client,
|
||||
connected = IRC_WriteStrClient(Origin,
|
||||
ERR_NOSUCHNICK_MSG,
|
||||
Client_ID(Client),
|
||||
Client_ID(Origin),
|
||||
Req->argv[arg_arg]);
|
||||
} else {
|
||||
connected = IRC_WriteStrClient(Origin,
|
||||
@@ -653,9 +769,17 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
|
||||
Req->argv[arg_arg][0] = '\0';
|
||||
arg_arg++;
|
||||
} else {
|
||||
#ifdef STRICT_RFC
|
||||
/* Report an error to the client, when a user
|
||||
* mode should be changed but no nickname is
|
||||
* given. But don't do it when not in "strict"
|
||||
* mode, because most other servers don't do
|
||||
* it as well and some clients send "wired"
|
||||
* MODE commands like "MODE #chan -ooo nick". */
|
||||
connected = IRC_WriteStrClient(Origin,
|
||||
ERR_NEEDMOREPARAMS_MSG,
|
||||
Client_ID(Origin), Req->command);
|
||||
#endif
|
||||
goto chan_exit;
|
||||
}
|
||||
break;
|
||||
@@ -667,7 +791,8 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
|
||||
goto chan_exit;
|
||||
if (arg_arg > mode_arg) {
|
||||
/* modify list */
|
||||
if (modeok) {
|
||||
if (is_oper || is_machine || is_owner ||
|
||||
is_admin || is_op || is_halfop) {
|
||||
connected = set
|
||||
? Add_To_List(*mode_ptr, Origin,
|
||||
Client, Channel,
|
||||
|
@@ -164,10 +164,18 @@ IRC_INVITE(CLIENT *Client, REQUEST *Req)
|
||||
if (!Channel_IsMemberOf(chan, from))
|
||||
return IRC_WriteStrClient(from, ERR_NOTONCHANNEL_MSG, Client_ID(Client), Req->argv[1]);
|
||||
|
||||
/* Is the channel "invite-disallow"? */
|
||||
if (strchr(Channel_Modes(chan), 'V'))
|
||||
return IRC_WriteStrClient(from, ERR_NOINVITE_MSG,
|
||||
Client_ID(from), Channel_Name(chan));
|
||||
|
||||
/* Is the channel "invite-only"? */
|
||||
if (strchr(Channel_Modes(chan), 'i')) {
|
||||
/* Yes. The user must be channel operator! */
|
||||
if (!strchr(Channel_UserModes(chan, from), 'o'))
|
||||
/* Yes. The user must be channel owner/admin/operator/halfop! */
|
||||
if (!strchr(Channel_UserModes(chan, from), 'q') &&
|
||||
!strchr(Channel_UserModes(chan, from), 'a') &&
|
||||
!strchr(Channel_UserModes(chan, from), 'o') &&
|
||||
!strchr(Channel_UserModes(chan, from), 'h'))
|
||||
return IRC_WriteStrClient(from, ERR_CHANOPRIVSNEEDED_MSG,
|
||||
Client_ID(from), Channel_Name(chan));
|
||||
remember = true;
|
||||
|
@@ -183,6 +183,8 @@ IRC_REHASH( CLIENT *Client, REQUEST *Req )
|
||||
|
||||
Log(LOG_NOTICE|LOG_snotice, "Got REHASH command from \"%s\" ...",
|
||||
Client_Mask(Client));
|
||||
IRC_WriteStrClient(Client, RPL_REHASHING_MSG, Client_ID(Client));
|
||||
|
||||
raise(SIGHUP);
|
||||
|
||||
return CONNECTED;
|
||||
|
@@ -53,8 +53,7 @@ IRC_SERVER( CLIENT *Client, REQUEST *Req )
|
||||
char str[LINE_LEN];
|
||||
CLIENT *from, *c;
|
||||
int i;
|
||||
CONN_ID con;
|
||||
|
||||
|
||||
assert( Client != NULL );
|
||||
assert( Req != NULL );
|
||||
|
||||
@@ -70,26 +69,44 @@ IRC_SERVER( CLIENT *Client, REQUEST *Req )
|
||||
LogDebug("Connection %d: got SERVER command (new server link) ...",
|
||||
Client_Conn(Client));
|
||||
|
||||
if(( Req->argc != 2 ) && ( Req->argc != 3 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
|
||||
if (Req->argc != 2 && Req->argc != 3)
|
||||
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
|
||||
Client_ID(Client),
|
||||
Req->command);
|
||||
|
||||
/* Ist this server configured on out side? */
|
||||
for( i = 0; i < MAX_SERVERS; i++ ) if( strcasecmp( Req->argv[0], Conf_Server[i].name ) == 0 ) break;
|
||||
if( i >= MAX_SERVERS )
|
||||
{
|
||||
Log( LOG_ERR, "Connection %d: Server \"%s\" not configured here!", Client_Conn( Client ), Req->argv[0] );
|
||||
Conn_Close( Client_Conn( Client ), NULL, "Server not configured here", true);
|
||||
/* Get configuration index of new remote server ... */
|
||||
for (i = 0; i < MAX_SERVERS; i++)
|
||||
if (strcasecmp(Req->argv[0], Conf_Server[i].name) == 0)
|
||||
break;
|
||||
|
||||
/* Makre sure the remote server is configured here */
|
||||
if (i >= MAX_SERVERS) {
|
||||
Log(LOG_ERR,
|
||||
"Connection %d: Server \"%s\" not configured here!",
|
||||
Client_Conn(Client), Req->argv[0]);
|
||||
Conn_Close(Client_Conn(Client), NULL,
|
||||
"Server not configured here", true);
|
||||
return DISCONNECTED;
|
||||
}
|
||||
if( strcmp( Client_Password( Client ), Conf_Server[i].pwd_in ) != 0 )
|
||||
{
|
||||
/* wrong password */
|
||||
Log( LOG_ERR, "Connection %d: Got bad password from server \"%s\"!", Client_Conn( Client ), Req->argv[0] );
|
||||
Conn_Close( Client_Conn( Client ), NULL, "Bad password", true);
|
||||
|
||||
/* Check server password */
|
||||
if (strcmp(Conn_Password(Client_Conn(Client)),
|
||||
Conf_Server[i].pwd_in) != 0) {
|
||||
Log(LOG_ERR,
|
||||
"Connection %d: Got bad password from server \"%s\"!",
|
||||
Client_Conn(Client), Req->argv[0]);
|
||||
Conn_Close(Client_Conn(Client), NULL,
|
||||
"Bad password", true);
|
||||
return DISCONNECTED;
|
||||
}
|
||||
|
||||
|
||||
/* Is there a registered server with this ID? */
|
||||
if( ! Client_CheckID( Client, Req->argv[0] )) return DISCONNECTED;
|
||||
if (!Client_CheckID(Client, Req->argv[0]))
|
||||
return DISCONNECTED;
|
||||
|
||||
/* Mark this connection as belonging to an configured server */
|
||||
if (!Conf_SetServer(i, Client_Conn(Client)))
|
||||
return DISCONNECTED;
|
||||
|
||||
Client_SetID( Client, Req->argv[0] );
|
||||
Client_SetHops( Client, 1 );
|
||||
@@ -97,7 +114,6 @@ IRC_SERVER( CLIENT *Client, REQUEST *Req )
|
||||
|
||||
/* Is this server registering on our side, or are we connecting to
|
||||
* a remote server? */
|
||||
con = Client_Conn(Client);
|
||||
if (Client_Token(Client) != TOKEN_OUTBOUND) {
|
||||
/* Incoming connection, send user/pass */
|
||||
if (!IRC_WriteStrClient(Client, "PASS %s %s",
|
||||
@@ -106,7 +122,8 @@ IRC_SERVER( CLIENT *Client, REQUEST *Req )
|
||||
|| !IRC_WriteStrClient(Client, "SERVER %s 1 :%s",
|
||||
Conf_ServerName,
|
||||
Conf_ServerInfo)) {
|
||||
Conn_Close(con, "Unexpected server behavior!",
|
||||
Conn_Close(Client_Conn(Client),
|
||||
"Unexpected server behavior!",
|
||||
NULL, false);
|
||||
return DISCONNECTED;
|
||||
}
|
||||
@@ -118,25 +135,25 @@ IRC_SERVER( CLIENT *Client, REQUEST *Req )
|
||||
Client_SetToken(Client, atoi(Req->argv[1]));
|
||||
}
|
||||
|
||||
/* Mark this connection as belonging to an configured server */
|
||||
Conf_SetServer(i, con);
|
||||
|
||||
/* Check protocol level */
|
||||
if (Client_Type(Client) == CLIENT_GOTPASS) {
|
||||
/* We got a "simple" PASS command, so the peer is
|
||||
* using the protocol as defined in RFC 1459. */
|
||||
if (! (Conn_Options(con) & CONN_RFC1459))
|
||||
if (! (Conn_Options(Client_Conn(Client)) & CONN_RFC1459))
|
||||
Log(LOG_INFO,
|
||||
"Switching connection %d (\"%s\") to RFC 1459 compatibility mode.",
|
||||
con, Client_ID(Client));
|
||||
Conn_SetOption(con, CONN_RFC1459);
|
||||
Client_Conn(Client), Client_ID(Client));
|
||||
Conn_SetOption(Client_Conn(Client), CONN_RFC1459);
|
||||
}
|
||||
|
||||
Client_SetType(Client, CLIENT_UNKNOWNSERVER);
|
||||
|
||||
#ifdef ZLIB
|
||||
if (strchr(Client_Flags(Client), 'Z') && !Zip_InitConn(con)) {
|
||||
Conn_Close( con, "Can't inizialize compression (zlib)!", NULL, false );
|
||||
if (strchr(Client_Flags(Client), 'Z')
|
||||
&& !Zip_InitConn(Client_Conn(Client))) {
|
||||
Conn_Close(Client_Conn(Client),
|
||||
"Can't inizialize compression (zlib)!",
|
||||
NULL, false );
|
||||
return DISCONNECTED;
|
||||
}
|
||||
#endif
|
||||
@@ -202,10 +219,10 @@ GLOBAL bool
|
||||
IRC_NJOIN( CLIENT *Client, REQUEST *Req )
|
||||
{
|
||||
char nick_in[COMMAND_LEN], nick_out[COMMAND_LEN], *channame, *ptr, modes[8];
|
||||
bool is_op, is_voiced;
|
||||
bool is_owner, is_chanadmin, is_op, is_halfop, is_voiced;
|
||||
CHANNEL *chan;
|
||||
CLIENT *c;
|
||||
|
||||
|
||||
assert( Client != NULL );
|
||||
assert( Req != NULL );
|
||||
|
||||
@@ -218,12 +235,16 @@ IRC_NJOIN( CLIENT *Client, REQUEST *Req )
|
||||
ptr = strtok( nick_in, "," );
|
||||
while( ptr )
|
||||
{
|
||||
is_op = is_voiced = false;
|
||||
|
||||
is_owner = is_chanadmin = is_op = is_halfop = is_voiced = false;
|
||||
|
||||
/* cut off prefixes */
|
||||
while(( *ptr == '@' ) || ( *ptr == '+' ))
|
||||
while(( *ptr == '~') || ( *ptr == '&' ) || ( *ptr == '@' ) ||
|
||||
( *ptr == '%') || ( *ptr == '+' ))
|
||||
{
|
||||
if( *ptr == '~' ) is_owner = true;
|
||||
if( *ptr == '&' ) is_chanadmin = true;
|
||||
if( *ptr == '@' ) is_op = true;
|
||||
if( *ptr == 'h' ) is_halfop = true;
|
||||
if( *ptr == '+' ) is_voiced = true;
|
||||
ptr++;
|
||||
}
|
||||
@@ -234,8 +255,11 @@ IRC_NJOIN( CLIENT *Client, REQUEST *Req )
|
||||
Channel_Join( c, channame );
|
||||
chan = Channel_Search( channame );
|
||||
assert( chan != NULL );
|
||||
|
||||
|
||||
if( is_owner ) Channel_UserModeAdd( chan, c, 'q' );
|
||||
if( is_chanadmin ) Channel_UserModeAdd( chan, c, 'a' );
|
||||
if( is_op ) Channel_UserModeAdd( chan, c, 'o' );
|
||||
if( is_halfop ) Channel_UserModeAdd( chan, c, 'h' );
|
||||
if( is_voiced ) Channel_UserModeAdd( chan, c, 'v' );
|
||||
|
||||
/* announce to channel... */
|
||||
@@ -250,12 +274,15 @@ IRC_NJOIN( CLIENT *Client, REQUEST *Req )
|
||||
}
|
||||
|
||||
if( nick_out[0] != '\0' ) strlcat( nick_out, ",", sizeof( nick_out ));
|
||||
if( is_owner ) strlcat( nick_out, "~", sizeof( nick_out ));
|
||||
if( is_chanadmin ) strlcat( nick_out, "&", sizeof( nick_out ));
|
||||
if( is_op ) strlcat( nick_out, "@", sizeof( nick_out ));
|
||||
if( is_halfop ) strlcat( nick_out, "%", sizeof( nick_out ));
|
||||
if( is_voiced ) strlcat( nick_out, "+", sizeof( nick_out ));
|
||||
strlcat( nick_out, ptr, sizeof( nick_out ));
|
||||
}
|
||||
else Log( LOG_ERR, "Got NJOIN for unknown nick \"%s\" for channel \"%s\"!", ptr, channame );
|
||||
|
||||
|
||||
/* search for next Nick */
|
||||
ptr = strtok( NULL, "," );
|
||||
}
|
||||
|
@@ -25,6 +25,7 @@
|
||||
#include "conn-func.h"
|
||||
#include "conf.h"
|
||||
#include "channel.h"
|
||||
#include "conn-encoding.h"
|
||||
#include "defines.h"
|
||||
#include "irc-write.h"
|
||||
#include "log.h"
|
||||
@@ -80,6 +81,17 @@ IRC_ERROR( CLIENT *Client, REQUEST *Req )
|
||||
assert( Client != NULL );
|
||||
assert( Req != NULL );
|
||||
|
||||
if (Client_Type(Client) != CLIENT_GOTPASS
|
||||
&& Client_Type(Client) != CLIENT_GOTPASS_2813
|
||||
&& Client_Type(Client) != CLIENT_UNKNOWNSERVER
|
||||
&& Client_Type(Client) != CLIENT_SERVER
|
||||
&& Client_Type(Client) != CLIENT_SERVICE) {
|
||||
LogDebug("Ignored ERROR command from \"%s\" ...",
|
||||
Client_Mask(Client));
|
||||
IRC_SetPenalty(Client, 2);
|
||||
return CONNECTED;
|
||||
}
|
||||
|
||||
if (Req->argc < 1)
|
||||
Log(LOG_NOTICE, "Got ERROR from \"%s\"!",
|
||||
Client_Mask(Client));
|
||||
@@ -327,12 +339,18 @@ IRC_HELP( CLIENT *Client, REQUEST *Req )
|
||||
|
||||
|
||||
static char *
|
||||
Option_String( CONN_ID Idx )
|
||||
#ifdef ZLIB
|
||||
Option_String(CONN_ID Idx)
|
||||
#else
|
||||
Option_String(UNUSED CONN_ID Idx)
|
||||
#endif
|
||||
{
|
||||
static char option_txt[8];
|
||||
#ifdef ZLIB
|
||||
UINT16 options;
|
||||
|
||||
options = Conn_Options(Idx);
|
||||
#endif
|
||||
|
||||
strcpy(option_txt, "F"); /* No idea what this means, but the
|
||||
* original ircd sends it ... */
|
||||
@@ -353,6 +371,7 @@ Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors)
|
||||
CHANNEL *chan;
|
||||
char *currentTarget = Req->argv[0];
|
||||
char *lastCurrentTarget = NULL;
|
||||
char *message = NULL;
|
||||
|
||||
assert(Client != NULL);
|
||||
assert(Req != NULL);
|
||||
@@ -384,6 +403,13 @@ Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors)
|
||||
return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG,
|
||||
Client_ID(Client), Req->prefix);
|
||||
|
||||
#ifdef ICONV
|
||||
if (Client_Conn(Client) > NONE)
|
||||
message = Conn_EncodingFrom(Client_Conn(Client), Req->argv[1]);
|
||||
else
|
||||
#endif
|
||||
message = Req->argv[1];
|
||||
|
||||
/* handle msgtarget = msgto *("," msgto) */
|
||||
currentTarget = strtok_r(currentTarget, ",", &lastCurrentTarget);
|
||||
ngt_UpperStr(Req->command);
|
||||
@@ -442,7 +468,7 @@ Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors)
|
||||
if (nick != NULL && host != NULL) {
|
||||
if (strcasecmp(nick, Client_ID(cl)) == 0 &&
|
||||
strcasecmp(user, Client_User(cl)) == 0 &&
|
||||
strcasecmp(host, Client_HostnameCloaked(cl)) == 0)
|
||||
strcasecmp(host, Client_HostnameDisplayed(cl)) == 0)
|
||||
break;
|
||||
else
|
||||
continue;
|
||||
@@ -450,7 +476,7 @@ Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors)
|
||||
if (strcasecmp(user, Client_User(cl)) != 0)
|
||||
continue;
|
||||
if (host != NULL && strcasecmp(host,
|
||||
Client_HostnameCloaked(cl)) != 0)
|
||||
Client_HostnameDisplayed(cl)) != 0)
|
||||
continue;
|
||||
if (server != NULL && strcasecmp(server,
|
||||
Client_ID(Client_Introducer(cl))) != 0)
|
||||
@@ -485,6 +511,17 @@ Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors)
|
||||
Req->command = "PRIVMSG";
|
||||
}
|
||||
#endif
|
||||
if (Client_HasMode(cl, 'b') &&
|
||||
!Client_HasMode(from, 'R') &&
|
||||
!Client_HasMode(from, 'o') &&
|
||||
!(Client_Type(from) == CLIENT_SERVER) &&
|
||||
!(Client_Type(from) == CLIENT_SERVICE)) {
|
||||
if (SendErrors && !IRC_WriteStrClient(from,
|
||||
ERR_NONONREG_MSG,
|
||||
Client_ID(from), Client_ID(cl)))
|
||||
return DISCONNECTED;
|
||||
goto send_next_target;
|
||||
}
|
||||
|
||||
if (Client_HasMode(cl, 'C')) {
|
||||
cl2chan = Channel_FirstChannelOf(cl);
|
||||
@@ -517,12 +554,12 @@ Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors)
|
||||
}
|
||||
if (!IRC_WriteStrClientPrefix(cl, from, "%s %s :%s",
|
||||
Req->command, Client_ID(cl),
|
||||
Req->argv[1]))
|
||||
message))
|
||||
return DISCONNECTED;
|
||||
} else if (ForceType != CLIENT_SERVICE
|
||||
&& (chan = Channel_Search(currentTarget))) {
|
||||
if (!Channel_Write(chan, from, Client, Req->command,
|
||||
SendErrors, Req->argv[1]))
|
||||
SendErrors, message))
|
||||
return DISCONNECTED;
|
||||
} else if (ForceType != CLIENT_SERVICE
|
||||
/* $#: server/target mask, RFC 2812, sec. 3.3.1 */
|
||||
@@ -530,7 +567,7 @@ Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors)
|
||||
&& strchr(currentTarget, '.')) {
|
||||
/* targetmask */
|
||||
if (!Send_Message_Mask(from, Req->command, currentTarget,
|
||||
Req->argv[1], SendErrors))
|
||||
message, SendErrors))
|
||||
return DISCONNECTED;
|
||||
} else {
|
||||
if (!SendErrors)
|
||||
|
@@ -147,10 +147,8 @@ Lists_Add(struct list_head *h, const char *Mask, time_t ValidUntil,
|
||||
|
||||
strlcpy(newelem->mask, Mask, sizeof(newelem->mask));
|
||||
if (Reason) {
|
||||
newelem->reason = malloc(strlen(Reason) + 1);
|
||||
if (newelem->reason)
|
||||
strlcpy(newelem->reason, Reason, strlen(Reason) + 1);
|
||||
else
|
||||
newelem->reason = strdup(Reason);
|
||||
if (!newelem->reason)
|
||||
Log(LOG_EMERG,
|
||||
"Can't allocate memory for new list reason text!");
|
||||
}
|
||||
@@ -285,7 +283,7 @@ Lists_MakeMask(const char *Pattern)
|
||||
excl = NULL;
|
||||
|
||||
if (!at && !excl) {
|
||||
/* Neither "!" nor "@" found: use string as nick name */
|
||||
/* Neither "!" nor "@" found: use string as nickname */
|
||||
strlcpy(TheMask, Pattern, sizeof(TheMask) - 5);
|
||||
strlcat(TheMask, "!*@*", sizeof(TheMask));
|
||||
return TheMask;
|
||||
|
@@ -80,9 +80,9 @@ Log_Init(bool Daemon_Mode)
|
||||
#define LOG_CONS 0
|
||||
#endif
|
||||
#ifdef LOG_DAEMON
|
||||
openlog(PACKAGE_NAME, LOG_CONS|LOG_PID, LOG_DAEMON);
|
||||
openlog(PACKAGE, LOG_CONS|LOG_PID, LOG_DAEMON);
|
||||
#else
|
||||
openlog(PACKAGE_NAME, LOG_CONS|LOG_PID, 0);
|
||||
openlog(PACKAGE, LOG_CONS|LOG_PID, 0);
|
||||
#endif
|
||||
#endif
|
||||
} /* Log_Init */
|
||||
@@ -99,7 +99,7 @@ Log_ReInit(void)
|
||||
#define LOG_CONS 0
|
||||
#endif
|
||||
closelog();
|
||||
openlog(PACKAGE_NAME, LOG_CONS|LOG_PID, Conf_SyslogFacility);
|
||||
openlog(PACKAGE, LOG_CONS|LOG_PID, Conf_SyslogFacility);
|
||||
#endif
|
||||
Log(LOG_NOTICE, "%s started.", NGIRCd_Version);
|
||||
Log(LOG_INFO, "Using configuration file \"%s\" ...", NGIRCd_ConfFile);
|
||||
@@ -218,7 +218,7 @@ GLOBAL void
|
||||
Log_Init_Subprocess(char UNUSED *Name)
|
||||
{
|
||||
#ifdef SYSLOG
|
||||
openlog(PACKAGE_NAME, LOG_CONS|LOG_PID, Conf_SyslogFacility);
|
||||
openlog(PACKAGE, LOG_CONS|LOG_PID, Conf_SyslogFacility);
|
||||
#endif
|
||||
#ifdef DEBUG
|
||||
Log_Subprocess(LOG_DEBUG, "%s sub-process starting, PID %ld.",
|
||||
|
244
src/ngircd/login.c
Normal file
244
src/ngircd/login.c
Normal file
@@ -0,0 +1,244 @@
|
||||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* 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
|
||||
* Functions to deal with client logins
|
||||
*/
|
||||
|
||||
#include "imp.h"
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "defines.h"
|
||||
#include "conn.h"
|
||||
#include "class.h"
|
||||
#include "client.h"
|
||||
#include "client-cap.h"
|
||||
#include "channel.h"
|
||||
#include "conf.h"
|
||||
#include "io.h"
|
||||
#include "parse.h"
|
||||
#include "log.h"
|
||||
#include "messages.h"
|
||||
#include "ngircd.h"
|
||||
#include "pam.h"
|
||||
#include "irc-info.h"
|
||||
#include "irc-write.h"
|
||||
|
||||
#include "exp.h"
|
||||
#include "login.h"
|
||||
|
||||
#ifdef PAM
|
||||
static void cb_Read_Auth_Result PARAMS((int r_fd, UNUSED short events));
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Initiate client login.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
GLOBAL bool
|
||||
Login_User(CLIENT * Client)
|
||||
{
|
||||
#ifdef PAM
|
||||
int pipefd[2], result;
|
||||
pid_t pid;
|
||||
#endif
|
||||
CONN_ID conn;
|
||||
|
||||
assert(Client != NULL);
|
||||
conn = Client_Conn(Client);
|
||||
|
||||
#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
|
||||
|
||||
/* Still waiting for "CAP END" command? */
|
||||
if (Client_Cap(Client) & CLIENT_CAP_PENDING) {
|
||||
Client_SetType(Client, CLIENT_WAITCAPEND);
|
||||
LogDebug("Connection %d: Waiting for CAP END ...", conn);
|
||||
return CONNECTED;
|
||||
}
|
||||
|
||||
#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
|
||||
* passwords supplied are classified as "wrong". */
|
||||
if(Conn_Password(conn)[0] == '\0')
|
||||
return Login_User_PostAuth(Client);
|
||||
Client_Reject(Client, "Non-empty password", false);
|
||||
return DISCONNECTED;
|
||||
}
|
||||
|
||||
if (Conf_PAMIsOptional &&
|
||||
strcmp(Conn_Password(conn), "") == 0) {
|
||||
/* Clients are not required to send a password and to be PAM-
|
||||
* authenticated at all. If not, they won't become "identified"
|
||||
* and keep the "~" in their supplied user name.
|
||||
* Therefore it is sensible to either set Conf_PAMisOptional or
|
||||
* to enable IDENT lookups -- not both. */
|
||||
return Login_User_PostAuth(Client);
|
||||
}
|
||||
|
||||
/* Fork child process for PAM authentication; and make sure that the
|
||||
* process timeout is set higher than the login timeout! */
|
||||
pid = Proc_Fork(Conn_GetProcStat(conn), pipefd,
|
||||
cb_Read_Auth_Result, Conf_PongTimeout + 1);
|
||||
if (pid > 0) {
|
||||
LogDebug("Authenticator for connection %d created (PID %d).",
|
||||
conn, pid);
|
||||
return CONNECTED;
|
||||
} else {
|
||||
/* Sub process */
|
||||
Log_Init_Subprocess("Auth");
|
||||
Conn_CloseAllSockets(NONE);
|
||||
result = PAM_Authenticate(Client);
|
||||
if (write(pipefd[1], &result, sizeof(result)) != sizeof(result))
|
||||
Log_Subprocess(LOG_ERR,
|
||||
"Failed to pipe result to parent!");
|
||||
Log_Exit_Subprocess("Auth");
|
||||
exit(0);
|
||||
}
|
||||
#else
|
||||
/* Check global server password ... */
|
||||
if (strcmp(Conn_Password(conn), Conf_ServerPwd) != 0) {
|
||||
/* Bad password! */
|
||||
Client_Reject(Client, "Bad server password", false);
|
||||
return DISCONNECTED;
|
||||
}
|
||||
return Login_User_PostAuth(Client);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* @return CONNECTED or DISCONNECTED.
|
||||
*/
|
||||
GLOBAL bool
|
||||
Login_User_PostAuth(CLIENT *Client)
|
||||
{
|
||||
assert(Client != NULL);
|
||||
|
||||
if (Class_HandleServerBans(Client) != CONNECTED)
|
||||
return DISCONNECTED;
|
||||
|
||||
Client_Introduce(NULL, Client, CLIENT_USER);
|
||||
|
||||
if (!IRC_WriteStrClient
|
||||
(Client, RPL_WELCOME_MSG, Client_ID(Client), Client_Mask(Client)))
|
||||
return false;
|
||||
if (!IRC_WriteStrClient
|
||||
(Client, RPL_YOURHOST_MSG, Client_ID(Client),
|
||||
Client_ID(Client_ThisServer()), PACKAGE_VERSION, HOST_CPU,
|
||||
HOST_VENDOR, HOST_OS))
|
||||
return false;
|
||||
if (!IRC_WriteStrClient
|
||||
(Client, RPL_CREATED_MSG, Client_ID(Client), NGIRCd_StartStr))
|
||||
return false;
|
||||
if (!IRC_WriteStrClient
|
||||
(Client, RPL_MYINFO_MSG, Client_ID(Client),
|
||||
Client_ID(Client_ThisServer()), PACKAGE_VERSION, USERMODES,
|
||||
CHANMODES))
|
||||
return false;
|
||||
|
||||
/* Features supported by this server (005 numeric, ISUPPORT),
|
||||
* see <http://www.irc.org/tech_docs/005.html> for details. */
|
||||
if (!IRC_Send_ISUPPORT(Client))
|
||||
return DISCONNECTED;
|
||||
|
||||
if (!IRC_Send_LUSERS(Client))
|
||||
return DISCONNECTED;
|
||||
if (!IRC_Show_MOTD(Client))
|
||||
return DISCONNECTED;
|
||||
|
||||
/* Suspend the client for a second ... */
|
||||
IRC_SetPenalty(Client, 1);
|
||||
|
||||
return CONNECTED;
|
||||
}
|
||||
|
||||
#ifdef PAM
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
CONN_ID conn;
|
||||
CLIENT *client;
|
||||
int result;
|
||||
size_t len;
|
||||
PROC_STAT *proc;
|
||||
|
||||
LogDebug("Auth: Got callback on fd %d, events %d", r_fd, events);
|
||||
conn = Conn_GetFromProc(r_fd);
|
||||
if (conn == NONE) {
|
||||
/* Ops, none found? Probably the connection has already
|
||||
* been closed!? We'll ignore that ... */
|
||||
io_close(r_fd);
|
||||
LogDebug("Auth: Got callback for unknown connection!?");
|
||||
return;
|
||||
}
|
||||
proc = Conn_GetProcStat(conn);
|
||||
client = Conn_GetClient(conn);
|
||||
|
||||
/* Read result from pipe */
|
||||
len = Proc_Read(proc, &result, sizeof(result));
|
||||
Proc_Close(proc);
|
||||
if (len == 0)
|
||||
return;
|
||||
|
||||
if (len != sizeof(result)) {
|
||||
Log(LOG_CRIT, "Auth: Got malformed result!");
|
||||
Client_Reject(client, "Internal error", false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (result == true) {
|
||||
Client_SetUser(client, Client_OrigUser(client), true);
|
||||
(void)Login_User_PostAuth(client);
|
||||
} else
|
||||
Client_Reject(client, "Bad password", false);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* -eof- */
|
25
src/ngircd/login.h
Normal file
25
src/ngircd/login.h
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
* Please read the file COPYING, README and AUTHORS for more information.
|
||||
*/
|
||||
|
||||
#ifndef __login_h__
|
||||
#define __login_h__
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Functions to deal with client logins (header)
|
||||
*/
|
||||
|
||||
GLOBAL bool Login_User PARAMS((CLIENT * Client));
|
||||
GLOBAL bool Login_User_PostAuth PARAMS((CLIENT *Client));
|
||||
|
||||
#endif
|
||||
|
||||
/* -eof- */
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
|
||||
* Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -48,9 +48,9 @@ static int Matche_After_Star PARAMS(( const char *p, const char *t ));
|
||||
/**
|
||||
* Match string with pattern.
|
||||
*
|
||||
* @param Pattern Pattern to match with
|
||||
* @param String Input string
|
||||
* @return true if pattern matches
|
||||
* @param Pattern Pattern to match with
|
||||
* @param String Input string
|
||||
* @return true if pattern matches
|
||||
*/
|
||||
GLOBAL bool
|
||||
Match( const char *Pattern, const char *String )
|
||||
@@ -64,17 +64,46 @@ Match( const char *Pattern, const char *String )
|
||||
/**
|
||||
* 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
|
||||
* @param Pattern Pattern to match with
|
||||
* @param String Input string, at most COMMAND_LEN-1 characters long
|
||||
* @return true if pattern matches
|
||||
*/
|
||||
GLOBAL bool
|
||||
MatchCaseInsensitive(const char *pattern, const char *searchme)
|
||||
MatchCaseInsensitive(const char *Pattern, const char *String)
|
||||
{
|
||||
char haystack[COMMAND_LEN];
|
||||
|
||||
strlcpy(haystack, searchme, sizeof(haystack));
|
||||
return Match(pattern, ngt_LowerStr(haystack));
|
||||
strlcpy(haystack, String, sizeof(haystack));
|
||||
return Match(Pattern, ngt_LowerStr(haystack));
|
||||
} /* MatchCaseInsensitive */
|
||||
|
||||
|
||||
/**
|
||||
* Match string with pattern case-insensitive.
|
||||
*
|
||||
* @param pattern Pattern to match with
|
||||
* @param String Input string, at most COMMAND_LEN-1 characters long
|
||||
* @param Separator Character separating the individual patterns in the list
|
||||
* @return true if pattern matches
|
||||
*/
|
||||
GLOBAL bool
|
||||
MatchCaseInsensitiveList(const char *Pattern, const char *String,
|
||||
const char *Separator)
|
||||
{
|
||||
char tmp_pattern[COMMAND_LEN], haystack[COMMAND_LEN], *ptr;
|
||||
|
||||
strlcpy(tmp_pattern, Pattern, sizeof(tmp_pattern));
|
||||
strlcpy(haystack, String, sizeof(haystack));
|
||||
ngt_LowerStr(haystack);
|
||||
|
||||
ptr = strtok(tmp_pattern, Separator);
|
||||
while (ptr) {
|
||||
ngt_TrimStr(ptr);
|
||||
if (Match(ptr, haystack))
|
||||
return true;
|
||||
ptr = strtok(NULL, Separator);
|
||||
}
|
||||
return false;
|
||||
} /* MatchCaseInsensitive */
|
||||
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
|
||||
* Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -17,8 +17,14 @@
|
||||
* Wildcard pattern matching (header)
|
||||
*/
|
||||
|
||||
GLOBAL bool Match PARAMS(( const char *Pattern, const char *String ));
|
||||
GLOBAL bool MatchCaseInsensitive PARAMS(( const char *Pattern, const char *searchme ));
|
||||
GLOBAL bool Match PARAMS((const char *Pattern, const char *String));
|
||||
|
||||
GLOBAL bool MatchCaseInsensitive PARAMS((const char *Pattern,
|
||||
const char *String));
|
||||
|
||||
GLOBAL bool MatchCaseInsensitiveList PARAMS((const char *Pattern,
|
||||
const char *String,
|
||||
const char *Separator));
|
||||
|
||||
#endif
|
||||
|
||||
|
@@ -21,7 +21,7 @@
|
||||
#define RPL_YOURHOST_MSG "002 %s :Your host is %s, running version ngircd-%s (%s/%s/%s)"
|
||||
#define RPL_CREATED_MSG "003 %s :This server has been started %s"
|
||||
#define RPL_MYINFO_MSG "004 %s %s ngircd-%s %s %s"
|
||||
#define RPL_ISUPPORT1_MSG "005 %s RFC2812 IRCD=ngIRCd CASEMAPPING=ascii PREFIX=(ov)@+ CHANTYPES=#&+ CHANMODES=beI,k,l,imnOPRstz CHANLIMIT=#&+:%d :are supported on this server"
|
||||
#define RPL_ISUPPORT1_MSG "005 %s RFC2812 IRCD=ngIRCd CHARSET=UTF-8 CASEMAPPING=ascii PREFIX=(qaohv)~&@%%+ CHANTYPES=#&+ CHANMODES=beI,k,l,imMnOPQRstVz CHANLIMIT=#&+:%d :are supported on this server"
|
||||
#define RPL_ISUPPORT2_MSG "005 %s CHANNELLEN=%d NICKLEN=%d TOPICLEN=%d AWAYLEN=%d KICKLEN=%d MODES=%d MAXLIST=beI:%d EXCEPTS=e INVEX=I PENALTY :are supported on this server"
|
||||
|
||||
#define RPL_TRACELINK_MSG "200 %s Link %s-%s %s %s V%s %ld %d %d"
|
||||
@@ -34,7 +34,6 @@
|
||||
#define RPL_UMODEIS_MSG "221 %s +%s"
|
||||
#define RPL_SERVLIST_MSG "234 %s %s %s %s %d %d :%s"
|
||||
#define RPL_SERVLISTEND_MSG "235 %s %s %s :End of service listing"
|
||||
|
||||
#define RPL_STATSUPTIME "242 %s :Server Up %u days %u:%02u:%02u"
|
||||
#define RPL_LUSERCLIENT_MSG "251 %s :There are %ld users and %ld services on %ld servers"
|
||||
#define RPL_LUSEROP_MSG "252 %s %lu :operator(s) online"
|
||||
@@ -72,6 +71,7 @@
|
||||
#define RPL_NOTOPIC_MSG "331 %s %s :No topic is set"
|
||||
#define RPL_TOPIC_MSG "332 %s %s :%s"
|
||||
#define RPL_TOPICSETBY_MSG "333 %s %s %s %u"
|
||||
#define RPL_WHOISBOT_MSG "335 %s %s :is a IRC Bot"
|
||||
#define RPL_INVITING_MSG "341 %s %s %s%s"
|
||||
#define RPL_INVITELIST_MSG "346 %s %s %s"
|
||||
#define RPL_ENDOFINVITELIST_MSG "347 %s %s :End of channel invite list"
|
||||
@@ -92,9 +92,12 @@
|
||||
#define RPL_MOTDSTART_MSG "375 %s :- %s message of the day"
|
||||
#define RPL_ENDOFMOTD_MSG "376 %s :End of MOTD command"
|
||||
#define RPL_WHOISHOST_MSG "378 %s %s :is connecting from *@%s %s"
|
||||
#define RPL_WHOISMODES_MSG "379 %s %s :is using modes +%s"
|
||||
#define RPL_YOUREOPER_MSG "381 %s :You are now an IRC Operator"
|
||||
#define RPL_REHASHING_MSG "382 %s :Rehashing"
|
||||
#define RPL_YOURESERVICE_MSG "383 %s :You are service %s"
|
||||
#define RPL_TIME_MSG "391 %s %s :%s"
|
||||
#define RPL_HOSTHIDDEN_MSG "396 %s %s :is your displayed hostname now"
|
||||
|
||||
#define ERR_NOSUCHNICK_MSG "401 %s %s :No such nick or channel name"
|
||||
#define ERR_NOSUCHSERVER_MSG "402 %s %s :No such server"
|
||||
@@ -103,6 +106,7 @@
|
||||
#define ERR_TOOMANYCHANNELS_MSG "405 %s %s :You have joined too many channels"
|
||||
#define ERR_WASNOSUCHNICK_MSG "406 %s %s :There was no such nickname"
|
||||
#define ERR_NOORIGIN_MSG "409 %s :No origin specified"
|
||||
#define ERR_INVALIDCAP_MSG "410 %s %s :Invalid CAP subcommand"
|
||||
#define ERR_NORECIPIENT_MSG "411 %s :No recipient given (%s)"
|
||||
#define ERR_NOTEXTTOSEND_MSG "412 %s :No text to send"
|
||||
#define ERR_WILDTOPLEVEL "414 %s :Wildcard in toplevel domain"
|
||||
@@ -111,6 +115,7 @@
|
||||
#define ERR_NONICKNAMEGIVEN_MSG "431 %s :No nickname given"
|
||||
#define ERR_ERRONEUSNICKNAME_MSG "432 %s %s :Erroneous nickname"
|
||||
#define ERR_NICKNAMETOOLONG_MSG "432 %s %s :Nickname too long, max. %u characters"
|
||||
#define ERR_FORBIDDENNICKNAME_MSG "432 %s %s :Nickname is forbidden/blocked"
|
||||
#define ERR_NICKNAMEINUSE_MSG "433 %s %s :Nickname already in use"
|
||||
#define ERR_USERNOTINCHANNEL_MSG "441 %s %s %s :They aren't on that channel"
|
||||
#define ERR_NOTONCHANNEL_MSG "442 %s %s :You are not on that channel"
|
||||
@@ -122,31 +127,45 @@
|
||||
#define ERR_NEEDMOREPARAMS_MSG "461 %s %s :Syntax error"
|
||||
#define ERR_ALREADYREGISTRED_MSG "462 %s :Connection already registered"
|
||||
#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_REGONLYCHANNEL_MSG "471 %s %s :Cannot join channel (+R)"
|
||||
#define ERR_CHANNELISFULL_MSG "471 %s %s :Cannot join channel (+l) -- Channel is full, try later"
|
||||
#define ERR_SECURECHANNEL_MSG "471 %s %s :Cannot join channel (+z) -- SSL connections only"
|
||||
#define ERR_OPONLYCHANNEL_MSG "471 %s %s :Cannot join channel (+O) -- IRC opers only"
|
||||
#define ERR_REGONLYCHANNEL_MSG "471 %s %s :Cannot join channel (+R) -- Registered users only"
|
||||
#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)"
|
||||
#define ERR_BADCHANNELKEY_MSG "475 %s %s :Cannot join channel (+k)"
|
||||
#define ERR_INVITEONLYCHAN_MSG "473 %s %s :Cannot join channel (+i) -- Invited users only"
|
||||
#define ERR_BANNEDFROMCHAN_MSG "474 %s %s :Cannot join channel (+b) -- You are banned"
|
||||
#define ERR_BADCHANNELKEY_MSG "475 %s %s :Cannot join channel (+k) -- Wrong channel key"
|
||||
#define ERR_NOCHANMODES_MSG "477 %s %s :Channel doesn't support modes"
|
||||
#define ERR_NEEDREGGEDNICK_MSG "477 %s %s :Cannot send to channel (+M) -- You need to be identified to a registered account to message this channel"
|
||||
#define ERR_LISTFULL_MSG "478 %s %s %s: Channel list is full (%d)"
|
||||
#define ERR_NOPRIVILEGES_MSG "481 %s :Permission denied"
|
||||
#define ERR_CHANOPRIVSNEEDED_MSG "482 %s %s :You are not channel operator"
|
||||
#define ERR_CHANOPPRIVTOOLOW_MSG "482 %s %s :Your privileges are too low"
|
||||
#define ERR_KICKDENY_MSG "482 %s %s :Cannot kick, %s is protected"
|
||||
#define ERR_CANTKILLSERVER_MSG "483 %s :You can't kill a server!"
|
||||
#define ERR_RESTRICTED_MSG "484 %s :Your connection is restricted"
|
||||
#define ERR_NICKREGISTER_MSG "484 %s :Cannot modify user mode (+R) -- Use IRC services"
|
||||
#define ERR_NONONREG_MSG "486 %s :Cannot send to user (+b) -- You must identify to a registered nick to private message %s"
|
||||
#define ERR_NOOPERHOST_MSG "491 %s :Not configured for your host"
|
||||
#define ERR_NOTONSAMECHANNEL_MSG "493 %s :You must share a common channel with %s"
|
||||
|
||||
#define ERR_UMODEUNKNOWNFLAG_MSG "501 %s :Unknown mode"
|
||||
#define ERR_UMODEUNKNOWNFLAG2_MSG "501 %s :Unknown mode \"%c%c\""
|
||||
#define ERR_USERSDONTMATCH_MSG "502 %s :Can't set/get mode for other users"
|
||||
#define ERR_NOINVITE_MSG "518 %s :Cannot invite to %s (+V)"
|
||||
|
||||
#ifdef ZLIB
|
||||
#define RPL_STATSLINKINFOZIP_MSG "211 %s %s %d %ld %ld/%ld %ld %ld/%ld :%ld"
|
||||
# define RPL_STATSLINKINFOZIP_MSG "211 %s %s %d %ld %ld/%ld %ld %ld/%ld :%ld"
|
||||
#endif
|
||||
|
||||
#ifdef IRCPLUS
|
||||
|
||||
# define RPL_IP_CHARCONV_MSG "801 %s %s :Client encoding set"
|
||||
|
||||
# define ERR_IP_CHARCONV_MSG "851 %s :Can't initialize client encoding"
|
||||
|
||||
#endif /* IRCPLUS */
|
||||
|
||||
#endif
|
||||
|
||||
/* -eof- */
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
|
||||
* Copyright (c)2001-2013 Alexander Barton (alex@barton.de) and Contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -330,6 +330,7 @@ main(int argc, const char *argv[])
|
||||
Channel_Exit();
|
||||
Class_Exit();
|
||||
Log_Exit();
|
||||
Signals_Exit();
|
||||
}
|
||||
Pidfile_Delete();
|
||||
|
||||
@@ -346,70 +347,106 @@ main(int argc, const char *argv[])
|
||||
* line switch.
|
||||
*/
|
||||
static void
|
||||
Fill_Version( void )
|
||||
Fill_Version(void)
|
||||
{
|
||||
NGIRCd_VersionAddition[0] = '\0';
|
||||
|
||||
#ifdef SYSLOG
|
||||
strlcpy( NGIRCd_VersionAddition, "SYSLOG", sizeof NGIRCd_VersionAddition );
|
||||
#endif
|
||||
#ifdef ZLIB
|
||||
if( NGIRCd_VersionAddition[0] )
|
||||
strlcat( NGIRCd_VersionAddition, "+", sizeof NGIRCd_VersionAddition );
|
||||
strlcat( NGIRCd_VersionAddition, "ZLIB", sizeof NGIRCd_VersionAddition );
|
||||
#endif
|
||||
#ifdef SSL_SUPPORT
|
||||
if ( NGIRCd_VersionAddition[0] ) strlcat( NGIRCd_VersionAddition, "+", sizeof NGIRCd_VersionAddition );
|
||||
strlcat( NGIRCd_VersionAddition, "SSL", sizeof NGIRCd_VersionAddition );
|
||||
#endif
|
||||
#ifdef TCPWRAP
|
||||
if( NGIRCd_VersionAddition[0] )
|
||||
strlcat( NGIRCd_VersionAddition, "+", sizeof NGIRCd_VersionAddition );
|
||||
strlcat( NGIRCd_VersionAddition, "TCPWRAP", sizeof NGIRCd_VersionAddition );
|
||||
#endif
|
||||
#ifdef IDENTAUTH
|
||||
if( NGIRCd_VersionAddition[0] )
|
||||
strlcat( NGIRCd_VersionAddition, "+", sizeof NGIRCd_VersionAddition );
|
||||
strlcat( NGIRCd_VersionAddition, "IDENT", sizeof NGIRCd_VersionAddition );
|
||||
#endif
|
||||
#ifdef PAM
|
||||
#ifdef ICONV
|
||||
if (NGIRCd_VersionAddition[0])
|
||||
strlcat(NGIRCd_VersionAddition, "+", sizeof NGIRCd_VersionAddition);
|
||||
strlcat(NGIRCd_VersionAddition, "PAM", sizeof NGIRCd_VersionAddition);
|
||||
strlcat(NGIRCd_VersionAddition, "+",
|
||||
sizeof NGIRCd_VersionAddition);
|
||||
strlcat(NGIRCd_VersionAddition, "CHARCONV",
|
||||
sizeof NGIRCd_VersionAddition);
|
||||
#endif
|
||||
#ifdef DEBUG
|
||||
if( NGIRCd_VersionAddition[0] )
|
||||
strlcat( NGIRCd_VersionAddition, "+", sizeof NGIRCd_VersionAddition );
|
||||
strlcat( NGIRCd_VersionAddition, "DEBUG", sizeof NGIRCd_VersionAddition );
|
||||
if (NGIRCd_VersionAddition[0])
|
||||
strlcat(NGIRCd_VersionAddition, "+",
|
||||
sizeof NGIRCd_VersionAddition);
|
||||
strlcat(NGIRCd_VersionAddition, "DEBUG",
|
||||
sizeof NGIRCd_VersionAddition);
|
||||
#endif
|
||||
#ifdef SNIFFER
|
||||
if( NGIRCd_VersionAddition[0] )
|
||||
strlcat( NGIRCd_VersionAddition, "+", sizeof NGIRCd_VersionAddition );
|
||||
strlcat( NGIRCd_VersionAddition, "SNIFFER", sizeof NGIRCd_VersionAddition );
|
||||
#endif
|
||||
#ifdef STRICT_RFC
|
||||
if( NGIRCd_VersionAddition[0] )
|
||||
strlcat( NGIRCd_VersionAddition, "+", sizeof NGIRCd_VersionAddition );
|
||||
strlcat( NGIRCd_VersionAddition, "RFC", sizeof NGIRCd_VersionAddition );
|
||||
#endif
|
||||
#ifdef IRCPLUS
|
||||
if( NGIRCd_VersionAddition[0] )
|
||||
strlcat( NGIRCd_VersionAddition, "+", sizeof NGIRCd_VersionAddition );
|
||||
strlcat( NGIRCd_VersionAddition, "IRCPLUS", sizeof NGIRCd_VersionAddition );
|
||||
#ifdef IDENTAUTH
|
||||
if (NGIRCd_VersionAddition[0])
|
||||
strlcat(NGIRCd_VersionAddition, "+",
|
||||
sizeof NGIRCd_VersionAddition);
|
||||
strlcat(NGIRCd_VersionAddition, "IDENT",
|
||||
sizeof NGIRCd_VersionAddition);
|
||||
#endif
|
||||
#ifdef WANT_IPV6
|
||||
if (NGIRCd_VersionAddition[0])
|
||||
strlcat(NGIRCd_VersionAddition, "+", sizeof(NGIRCd_VersionAddition));
|
||||
strlcat(NGIRCd_VersionAddition, "IPv6", sizeof(NGIRCd_VersionAddition));
|
||||
strlcat(NGIRCd_VersionAddition, "+",
|
||||
sizeof(NGIRCd_VersionAddition));
|
||||
strlcat(NGIRCd_VersionAddition, "IPv6",
|
||||
sizeof(NGIRCd_VersionAddition));
|
||||
#endif
|
||||
if( NGIRCd_VersionAddition[0] )
|
||||
strlcat( NGIRCd_VersionAddition, "-", sizeof( NGIRCd_VersionAddition ));
|
||||
#ifdef IRCPLUS
|
||||
if (NGIRCd_VersionAddition[0])
|
||||
strlcat(NGIRCd_VersionAddition, "+",
|
||||
sizeof NGIRCd_VersionAddition);
|
||||
strlcat(NGIRCd_VersionAddition, "IRCPLUS",
|
||||
sizeof NGIRCd_VersionAddition);
|
||||
#endif
|
||||
#ifdef PAM
|
||||
if (NGIRCd_VersionAddition[0])
|
||||
strlcat(NGIRCd_VersionAddition, "+",
|
||||
sizeof NGIRCd_VersionAddition);
|
||||
strlcat(NGIRCd_VersionAddition, "PAM",
|
||||
sizeof NGIRCd_VersionAddition);
|
||||
#endif
|
||||
#ifdef STRICT_RFC
|
||||
if (NGIRCd_VersionAddition[0])
|
||||
strlcat(NGIRCd_VersionAddition, "+",
|
||||
sizeof NGIRCd_VersionAddition);
|
||||
strlcat(NGIRCd_VersionAddition, "RFC",
|
||||
sizeof NGIRCd_VersionAddition);
|
||||
#endif
|
||||
#ifdef SNIFFER
|
||||
if (NGIRCd_VersionAddition[0])
|
||||
strlcat(NGIRCd_VersionAddition, "+",
|
||||
sizeof NGIRCd_VersionAddition);
|
||||
strlcat(NGIRCd_VersionAddition, "SNIFFER",
|
||||
sizeof NGIRCd_VersionAddition);
|
||||
#endif
|
||||
#ifdef SSL_SUPPORT
|
||||
if (NGIRCd_VersionAddition[0])
|
||||
strlcat(NGIRCd_VersionAddition, "+",
|
||||
sizeof NGIRCd_VersionAddition);
|
||||
strlcat(NGIRCd_VersionAddition, "SSL",
|
||||
sizeof NGIRCd_VersionAddition);
|
||||
#endif
|
||||
#ifdef SYSLOG
|
||||
if (NGIRCd_VersionAddition[0])
|
||||
strlcat(NGIRCd_VersionAddition, "+",
|
||||
sizeof NGIRCd_VersionAddition);
|
||||
strlcat(NGIRCd_VersionAddition, "SYSLOG",
|
||||
sizeof NGIRCd_VersionAddition);
|
||||
#endif
|
||||
#ifdef TCPWRAP
|
||||
if (NGIRCd_VersionAddition[0])
|
||||
strlcat(NGIRCd_VersionAddition, "+",
|
||||
sizeof NGIRCd_VersionAddition);
|
||||
strlcat(NGIRCd_VersionAddition, "TCPWRAP",
|
||||
sizeof NGIRCd_VersionAddition);
|
||||
#endif
|
||||
#ifdef ZLIB
|
||||
if (NGIRCd_VersionAddition[0])
|
||||
strlcat(NGIRCd_VersionAddition, "+",
|
||||
sizeof NGIRCd_VersionAddition);
|
||||
strlcat(NGIRCd_VersionAddition, "ZLIB",
|
||||
sizeof NGIRCd_VersionAddition);
|
||||
#endif
|
||||
if (NGIRCd_VersionAddition[0])
|
||||
strlcat(NGIRCd_VersionAddition, "-",
|
||||
sizeof(NGIRCd_VersionAddition));
|
||||
|
||||
strlcat( NGIRCd_VersionAddition, TARGET_CPU, sizeof( NGIRCd_VersionAddition ));
|
||||
strlcat( NGIRCd_VersionAddition, "/", sizeof( NGIRCd_VersionAddition ));
|
||||
strlcat( NGIRCd_VersionAddition, TARGET_VENDOR, sizeof( NGIRCd_VersionAddition ));
|
||||
strlcat( NGIRCd_VersionAddition, "/", sizeof( NGIRCd_VersionAddition ));
|
||||
strlcat( NGIRCd_VersionAddition, TARGET_OS, sizeof( NGIRCd_VersionAddition ));
|
||||
strlcat(NGIRCd_VersionAddition, HOST_CPU,
|
||||
sizeof(NGIRCd_VersionAddition));
|
||||
strlcat(NGIRCd_VersionAddition, "/", sizeof(NGIRCd_VersionAddition));
|
||||
strlcat(NGIRCd_VersionAddition, HOST_VENDOR,
|
||||
sizeof(NGIRCd_VersionAddition));
|
||||
strlcat(NGIRCd_VersionAddition, "/", sizeof(NGIRCd_VersionAddition));
|
||||
strlcat(NGIRCd_VersionAddition, HOST_OS,
|
||||
sizeof(NGIRCd_VersionAddition));
|
||||
|
||||
snprintf(NGIRCd_Version, sizeof NGIRCd_Version, "%s %s-%s",
|
||||
PACKAGE_NAME, PACKAGE_VERSION, NGIRCd_VersionAddition);
|
||||
@@ -423,7 +460,7 @@ static void
|
||||
Show_Version( void )
|
||||
{
|
||||
puts( NGIRCd_Version );
|
||||
puts( "Copyright (c)2001-2012 Alexander Barton (<alex@barton.de>) and Contributors." );
|
||||
puts( "Copyright (c)2001-2013 Alexander Barton (<alex@barton.de>) and Contributors." );
|
||||
puts( "Homepage: <http://ngircd.barton.de/>\n" );
|
||||
puts( "This is free software; see the source for copying conditions. There is NO" );
|
||||
puts( "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." );
|
||||
@@ -498,7 +535,8 @@ Pidfile_Create(pid_t pid)
|
||||
|
||||
len = snprintf(pidbuf, sizeof pidbuf, "%ld\n", (long)pid);
|
||||
if (len < 0 || len >= (int)sizeof pidbuf) {
|
||||
Log( LOG_ERR, "Error converting pid");
|
||||
Log(LOG_ERR, "Error converting pid");
|
||||
close(pidfd);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -529,6 +567,8 @@ Setup_FDStreams(int fd)
|
||||
} /* Setup_FDStreams */
|
||||
|
||||
|
||||
#if !defined(SINGLE_USER_OS)
|
||||
|
||||
/**
|
||||
* Get user and group ID of unprivileged "nobody" user.
|
||||
*
|
||||
@@ -568,6 +608,8 @@ NGIRCd_getNobodyID(uid_t *uid, gid_t *gid )
|
||||
return true;
|
||||
} /* NGIRCd_getNobodyID */
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
static bool
|
||||
Random_Init_Kern(const char *file)
|
||||
@@ -631,7 +673,7 @@ NGIRCd_Init(bool NGIRCd_NoDaemon)
|
||||
/* SSL initialization */
|
||||
if (!ConnSSL_InitLibrary())
|
||||
Log(LOG_WARNING,
|
||||
"Warning: Error during SSL initialization, continuing ...");
|
||||
"Error during SSL initialization, continuing without SSL ...");
|
||||
|
||||
/* Change root */
|
||||
if (Conf_Chroot[0]) {
|
||||
@@ -642,12 +684,10 @@ NGIRCd_Init(bool NGIRCd_NoDaemon)
|
||||
}
|
||||
|
||||
if (chroot(Conf_Chroot) != 0) {
|
||||
if (errno != EPERM) {
|
||||
Log(LOG_ERR,
|
||||
"Can't change root directory to \"%s\": %s",
|
||||
Conf_Chroot, strerror(errno));
|
||||
goto out;
|
||||
}
|
||||
Log(LOG_ERR,
|
||||
"Can't change root directory to \"%s\": %s",
|
||||
Conf_Chroot, strerror(errno));
|
||||
goto out;
|
||||
} else {
|
||||
chrooted = true;
|
||||
Log(LOG_INFO,
|
||||
@@ -656,6 +696,7 @@ NGIRCd_Init(bool NGIRCd_NoDaemon)
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(SINGLE_USER_OS)
|
||||
/* Check user ID */
|
||||
if (Conf_UID == 0) {
|
||||
pwd = getpwuid(0);
|
||||
@@ -682,6 +723,7 @@ NGIRCd_Init(bool NGIRCd_NoDaemon)
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Change user ID */
|
||||
if (getuid() != Conf_UID) {
|
||||
@@ -716,7 +758,7 @@ NGIRCd_Init(bool NGIRCd_NoDaemon)
|
||||
}
|
||||
|
||||
/* New child process */
|
||||
#ifndef NeXT
|
||||
#ifdef HAVE_SETSID
|
||||
(void)setsid();
|
||||
#else
|
||||
setpgrp(0, getpid());
|
||||
|
@@ -48,12 +48,11 @@ Announce_Channel(CLIENT *Client, CHANNEL *Chan)
|
||||
CL2CHAN *cl2chan;
|
||||
CLIENT *cl;
|
||||
char str[LINE_LEN], *ptr;
|
||||
bool njoin;
|
||||
bool njoin, xop;
|
||||
|
||||
if (Conn_Options(Client_Conn(Client)) & CONN_RFC1459)
|
||||
njoin = false;
|
||||
else
|
||||
njoin = true;
|
||||
/* Check features of remote server */
|
||||
njoin = Conn_Options(Client_Conn(Client)) & CONN_RFC1459 ? false : true;
|
||||
xop = strchr(Client_Flags(Client), 'X') ? true : false;
|
||||
|
||||
/* Get all the members of this channel */
|
||||
cl2chan = Channel_FirstMember(Chan);
|
||||
@@ -63,14 +62,23 @@ Announce_Channel(CLIENT *Client, CHANNEL *Chan)
|
||||
assert(cl != NULL);
|
||||
|
||||
if (njoin) {
|
||||
/* RFC 2813: send NJOIN with nick names and modes
|
||||
/* RFC 2813: send NJOIN with nicknames and modes
|
||||
* (if user is channel operator or has voice) */
|
||||
if (str[strlen(str) - 1] != ':')
|
||||
strlcat(str, ",", sizeof(str));
|
||||
if (strchr(Channel_UserModes(Chan, cl), 'v'))
|
||||
strlcat(str, "+", sizeof(str));
|
||||
|
||||
/* Prepare user prefix (ChanOp, voiced, ...) */
|
||||
if (xop && strchr(Channel_UserModes(Chan, cl), 'q'))
|
||||
strlcat(str, "~", sizeof(str));
|
||||
if (xop && strchr(Channel_UserModes(Chan, cl), 'a'))
|
||||
strlcat(str, "&", sizeof(str));
|
||||
if (strchr(Channel_UserModes(Chan, cl), 'o'))
|
||||
strlcat(str, "@", sizeof(str));
|
||||
if (xop && strchr(Channel_UserModes(Chan, cl), 'h'))
|
||||
strlcat(str, "%", sizeof(str));
|
||||
if (strchr(Channel_UserModes(Chan, cl), 'v'))
|
||||
strlcat(str, "+", sizeof(str));
|
||||
|
||||
strlcat(str, Client_ID(cl), sizeof(str));
|
||||
|
||||
/* Send the data if the buffer is "full" */
|
||||
@@ -171,24 +179,40 @@ Announce_User(CLIENT * Client, CLIENT * User)
|
||||
Client_ID(User), Client_ID(User),
|
||||
modes);
|
||||
}
|
||||
return CONNECTED;
|
||||
} else {
|
||||
/* RFC 2813 mode: one combined NICK or SERVICE command */
|
||||
if (Client_Type(User) == CLIENT_SERVICE
|
||||
&& strchr(Client_Flags(Client), 'S'))
|
||||
return IRC_WriteStrClient(Client,
|
||||
"SERVICE %s %d * +%s %d :%s", Client_Mask(User),
|
||||
Client_MyToken(Client_Introducer(User)),
|
||||
Client_Modes(User), Client_Hops(User) + 1,
|
||||
Client_Info(User));
|
||||
else
|
||||
return IRC_WriteStrClient(Client,
|
||||
"NICK %s %d %s %s %d +%s :%s",
|
||||
Client_ID(User), Client_Hops(User) + 1,
|
||||
Client_User(User), Client_Hostname(User),
|
||||
Client_MyToken(Client_Introducer(User)),
|
||||
Client_Modes(User), Client_Info(User));
|
||||
&& strchr(Client_Flags(Client), 'S')) {
|
||||
if (!IRC_WriteStrClient(Client,
|
||||
"SERVICE %s %d * +%s %d :%s",
|
||||
Client_Mask(User),
|
||||
Client_MyToken(Client_Introducer(User)),
|
||||
Client_Modes(User), Client_Hops(User) + 1,
|
||||
Client_Info(User)))
|
||||
return DISCONNECTED;
|
||||
} else {
|
||||
if (!IRC_WriteStrClient(Client,
|
||||
"NICK %s %d %s %s %d +%s :%s",
|
||||
Client_ID(User), Client_Hops(User) + 1,
|
||||
Client_User(User), Client_Hostname(User),
|
||||
Client_MyToken(Client_Introducer(User)),
|
||||
Client_Modes(User), Client_Info(User)))
|
||||
return DISCONNECTED;
|
||||
}
|
||||
}
|
||||
|
||||
if (strchr(Client_Flags(Client), 'M')) {
|
||||
/* Synchronize metadata */
|
||||
if (Client_HostnameCloaked(User)) {
|
||||
if (!IRC_WriteStrClient(Client,
|
||||
"METADATA %s cloakhost :%s",
|
||||
Client_ID(User),
|
||||
Client_HostnameCloaked(User)))
|
||||
return DISCONNECTED;
|
||||
}
|
||||
}
|
||||
|
||||
return CONNECTED;
|
||||
} /* Announce_User */
|
||||
|
||||
|
||||
@@ -413,12 +437,12 @@ IRC_Num_ISUPPORT(CLIENT * Client, REQUEST * Req)
|
||||
if ((unsigned int)atol(value) == Conf_MaxNickLength - 1)
|
||||
continue;
|
||||
|
||||
/* Nick name length settings are different! */
|
||||
/* Nickname length settings are different! */
|
||||
Log(LOG_ERR,
|
||||
"Peer uses incompatible nick name length (%d/%d)! Disconnecting ...",
|
||||
"Peer uses incompatible nickname length (%d/%d)! Disconnecting ...",
|
||||
Conf_MaxNickLength - 1, atoi(value));
|
||||
Conn_Close(Client_Conn(Client),
|
||||
"Incompatible nick name length",
|
||||
"Incompatible nickname length",
|
||||
NULL, false);
|
||||
return DISCONNECTED;
|
||||
}
|
||||
|
@@ -102,8 +102,8 @@ PAM_Authenticate(CLIENT *Client) {
|
||||
/* Set supplied client password */
|
||||
if (password)
|
||||
free(password);
|
||||
password = strdup(Client_Password(Client));
|
||||
conv.appdata_ptr = Client_Password(Client);
|
||||
password = strdup(Conn_Password(Client_Conn(Client)));
|
||||
conv.appdata_ptr = Conn_Password(Client_Conn(Client));
|
||||
|
||||
/* Initialize PAM */
|
||||
retval = pam_start("ngircd", Client_OrigUser(Client), &conv, &pam);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user