1
0
mirror of https://github.com/osmarks/ngircd.git synced 2025-09-25 05:24:04 +00:00

Compare commits

...

101 Commits

Author SHA1 Message Date
Alexander Barton
defd7e09af ngIRCd release 16 2010-05-02 15:25:35 +02:00
Florian Westphal
29d448ed63 doc/SSL: remove line continuation marker
some people got confused by the '\' line continuation marker,
thus put everything in a single line, even if the line gets overly long.
2010-05-01 20:29:18 +02:00
Alexander Barton
bdec5ac1f3 ngIRCd release 16~rc2 2010-04-25 13:13:11 +02:00
Alexander Barton
73fd26e9fa Don't reset counters on RESTART
When ngIRCd restarts, all the connection counters are preserved now,
as well as the command counters for example.

It's unclear if resetting or not resetting is the "correct" behaviour,
but it's quite clear that the behaviour should be consistent for all the
counters ngIRCd uses ...

And initializing "WCounter", the global but temporary write counter,
is not necessarry at all: it is initialized (reset) before its use in
the command parser (see parse.c).
2010-04-25 12:54:13 +02:00
Alexander Barton
79e1ec2b1e New numeric RPL_STATSCONN (250): display connection statistics
The RPL_STATSCONN numeric (250) displays information about the
highest simoultaneous connection count and the number of all
accepted connections since the daemon started up.

Used by ircd-Hybrid, Bahamut, and Unreal for example.
2010-04-23 23:30:14 +02:00
Alexander Barton
615d09459e Display total number of served connections on daemon shutdown 2010-04-23 23:29:22 +02:00
Alexander Barton
1338ade650 Enhace connection statistics counters
This patch enables ngIRCd to count the highest maximum simultaneous
connections and all the connections accepted since startup.

New functions:
- Conn_Count(): get current connections
- Conn_CountMax(): maximum simultaneous connections
- Conn_CountAccepted(): number of connections accepted
2010-04-23 23:25:34 +02:00
Alexander Barton
21140500f1 Conn_Init: code cleanup 2010-04-23 22:23:51 +02:00
Alexander Barton
77ceb9f8ab Updated doc/Platforms.txt 2010-04-23 11:04:39 +02:00
Alexander Barton
b042363e88 Only include <netinet/in_systm.h> if it exists 2010-04-23 11:04:15 +02:00
Alexander Barton
6b0bb665c3 Include netinet/{in.h, in_systm.h} when checking for netinet/ip.h
This solves warning messages of autoconf on e.g. FreeBSD 8:

configure: WARNING: netinet/ip.h: present but cannot be compiled
configure: WARNING: netinet/ip.h:   check for missing prerequisite headers?
2010-04-23 10:55:50 +02:00
Alexander Barton
1caa3fb94b Include netinet/in_systm.h alongside netinet/ip.h
This fixes the following error when compiling on e.g. FreeBSD 6.x:

In file included from conn.c:40:
/usr/include/netinet/ip.h:160: error: syntax error before "n_long"
/usr/include/netinet/ip.h:163: error: syntax error before "n_long"
2010-04-11 16:58:29 +00:00
Alexander Barton
025342fe46 Fix gcc warning "ignoring return value of ..."
This patch fixes two warnings of gcc 4.4.3 when used with eglibc 2.11.1:

ngircd.c: In function ‘NGIRCd_Init’:
ngircd.c:801: warning: ignoring return value of ‘chdir’, declared with
 attribute warn_unused_result
conn.c: In function ‘Simple_Message’:
conn.c:2041: warning: ignoring return value of ‘write’, declared with
 attribute warn_unused_result

The first by checking the return code and an appropriate error message,
the second by "better" ignoring it (which is correct there!) ...
2010-04-09 20:14:11 +02:00
Alexander Barton
628c6c962b Only compile in Get_Error() if really needed
This fixes "resolve.c:150: warning: ‘Get_Error’ defined but not used".
2010-04-09 20:06:44 +02:00
Alexander Barton
1ed49de83a Updated some more copyright notices, it's 2010 already (part 2)
Silly me forgot the most important place, the program output itself ...
2010-04-02 14:22:07 +02:00
Alexander Barton
bb914b93e9 Updated some more copyright notices, it's 2010 already :-) 2010-04-02 14:19:36 +02:00
Alexander Barton
50e8a62c5c ngIRCd release 16~rc1 2010-03-25 15:57:11 +01:00
Alexander Barton
aa32fec1b6 Updated NEWS and ChangeLog file for ngIRCd 16-rc1 2010-03-25 14:55:31 +01:00
Alexander Barton
cbe41ec875 Don't use port 6668 as example for both "Ports" and "SSLPorts" 2010-03-16 16:16:03 +01:00
Florian Westphal
20276f7cc9 configure.in: only add -lnsl when needed
dpkg-shlibdeps: warning: dependency on libnsl.so.1 [..]
(they use none of its symbols).

As shown via commit 2b14234abc
(dpkg-shlibdeps: warning: dependency on libnsl.so.1) and the
following revert of that commit, we cannot simply drop
the AC_CHECK_LIB(nsl). Although -lnsl is indeed unneeded
when glibc is used, some platforms (e.g. Solaris) need it.

Use AC_SEARCH_LIBS instead to only link when the library exports
a particular symbol.
2010-02-17 22:25:30 +01:00
Alexander Barton
6e8cf51bb2 Implement WEBIRC command
The WEBIRC command is used by some Web-to-IRC gateways to set the correct
user name and host name of users instead of their own.

Syntax: WEBIRC <password> <username> <hostname> <ip-address>

The <password> must be set using the new configuration variable "WebircPassword" in the [Global] section of ngircd.conf.

Please note that the <ip-address> is currently not used by ngIRCd (we don't store it in the CLIENT structure, only the resolved hostname).
2010-02-11 00:01:53 +01:00
Alexander Barton
53fc0ebff6 ngircd.conf.5: Document missing "Password" variable 2010-02-10 23:47:05 +01:00
Alexander Barton
9b3e143a26 Re-format Init_New_Client() function 2010-02-10 23:40:03 +01:00
Alexander Barton
f1bbc92b39 New README-Interix.txt for running ngIRCd on MS SFU and MS SUA 2010-02-05 00:24:33 +01:00
Alexander Barton
1da3e25e65 Added "i586/pc/interix3.5" (MS Services for UNIX) to Platforms.txt 2010-01-22 18:26:26 +01:00
Alexander Barton
e1de769ab9 Quote received messages of ERROR commands in log output 2010-01-19 19:20:56 +01:00
Alexander Barton
9f58418765 Implemented new "secure clients only" channel mode: +z
Only clients using a SSL encrypted connection to the server are
allowed to join such a channel.

But please note three things:

a) already joined clients are not checked when setting this mode,
b) IRC operators are always allowed to join every channel, and
c) remote clients using a server not supporting this mode are not
   checked either and therefore always allowed to join.
2010-01-17 14:20:07 +01:00
Alexander Barton
ef157715a0 Clean up and document IRC_STATS() function 2010-01-16 23:24:19 +01:00
Alexander Barton
ecad9f32c8 Clean up and document IRC_JOIN() and join_allowed() functions 2010-01-16 22:30:55 +01:00
Alexander Barton
f58c8b94d9 Show our name (IRCD=ngIRCd) in ISUPPORT (005) numeric
Inspired by Hyperion IRC daemon.
2010-01-16 14:59:07 +01:00
Alexander Barton
3a2ac66f7f Added missing modes to USERMODES #define
Now the numeric 004 correctly reports all the supported user and channel
modes (user modes "r" and "w" were missing), e. g.:

  :a.irc.net 004 a a.irc.net ngircd-15 aiorsw biIklmnoPstv
2010-01-16 14:07:27 +01:00
Alexander Barton
cf05bf31a7 Updated links to ngIRCd homepage (bug tracker, mailing list) 2010-01-01 18:58:56 +01:00
Alexander Barton
a4d7c6f145 setsockopt(): use IPPROTO_IP instead of SOL_IP to set IPTOS_LOWDELAY 2009-12-31 00:57:02 +01:00
Alexander Barton
1ddc74f13e Really test for netinet/ip.h and set HAVE_NETINET_IP_H 2009-12-31 00:38:47 +01:00
Alexander Barton
75dabcaae5 ReverseLookup(): fix documentation comment 2009-12-30 23:45:02 +01:00
Alexander Barton
1b73e68e6e Move NewConnection handling from callbacks to New_Connection() 2009-12-30 23:42:43 +01:00
Alexander Barton
03cde2efd3 Connection functions: add some more documentation comments 2009-12-30 23:35:17 +01:00
Alexander Barton
cb6faed61c Clean up conn.{c|h} a little bit 2009-12-30 23:32:47 +01:00
Alexander Barton
c62c2d349b Xcode: fix "-Wuninitialized is not supported without -O"
Fix Apple Xcode warning "cc1: warning: -Wuninitialized is not supported
without -O" when using the "Debug" build target:

Detection of uninitialized automatic variable requires data flow analsys
that is only enabled during optimized compilation.
2009-12-27 17:21:37 +01:00
Alexander Barton
60137a7139 Added i686/unknown/kfreebsd7.2-gnu 2009-12-02 22:22:35 +01:00
Alexander Barton
513a75c919 platformtest.sh: Only show latest commit
Only show latest GIT commuit ID as version number,
even when the last commit has been a merge.
2009-11-15 18:25:36 +01:00
Alexander Barton
4f1b5400e9 Merge commit 'cade80dcf516f40e7d53124bc98526e6e5b3fb66'
* commit 'cade80dcf516f40e7d53124bc98526e6e5b3fb66':
  Added missing contrib/platformtest.sh to distribution
2009-11-07 21:51:36 +01:00
Alexander Barton
cade80dcf5 Added missing contrib/platformtest.sh to distribution 2009-11-07 21:06:30 +01:00
Florian Westphal
28ca31e576 Remove limit on max number of configured irc operators. 2009-11-07 17:42:54 +01:00
Alexander Barton
c414d0bd3a ngIRCd release 15 2009-11-07 13:57:15 +01:00
Florian Westphal
bc88b2cb06 configtest: print ssl config options even when unset
Print "SSLOptionVar =" instead of omitting the option when
running --configtest with ssl enabled.
This better matches the behaviour of other options, e.g.  ChrootDir.
2009-10-17 15:35:26 +02:00
Alexander Barton
bc1ac7fbc5 ngIRCd release 15~rc1 2009-10-15 10:04:34 +02:00
Alexander Barton
37e950a40c Updated NEWS and ChangeLog files 2009-10-03 16:45:09 +02:00
Alexander Barton
55c04e691d Make sure forwarded CONNECT commands are handled correctly 2009-09-30 16:00:06 +02:00
Alexander Barton
881b9af251 Generate WALLOPS message on operator-generated SQUIT 2009-09-30 16:00:06 +02:00
Alexander Barton
294320ed62 Enable SQUIT command for IRC Operators
This patch enables IRC Operators to use the SQUIT command as specified in
RFC 2812, section 3.1.8 "Squit".

When forwarding SQUIT commands, the server connected to the target will
drop the connection (not the target server itself!).

Please note:

 - the configuration option "AllowRemoteOper" mus be enabled on the
   server disconnecting the target to allow forwarding of SQUIT commands.
 - if the remote server is configured to establish the connection, it
   will just do this; so the disconnect is not permanent in this case!
2009-09-30 16:00:06 +02:00
Alexander Barton
03b70229eb Xcode: added new op.{c|h} to project file 2009-09-30 16:00:06 +02:00
Alexander Barton
9918dfc1d5 Use functions provided by op.c "module"
Local functions Check_Oper() and No_Privileges() have been replaced by
global functions in op.c "module": Op_Check() and Op_NoPrivileges().
2009-09-30 16:00:06 +02:00
Alexander Barton
e46cf64cc1 New "module" op.c/op.h for IRC operator related functions
The new "module" op.c is used to implement functions related to IRC Ops.
At the moment, these two functions are available:

 - Op_Check() to check for a valid IRC Op, and
 - Op_NoPrivileges() to generate "permission denied" messages.
2009-09-30 16:00:06 +02:00
Alexander Barton
113bd34878 Allow forwarding of CONNECT commands.
The syntax of the CONNECT command now is:

  - CONNECT <server-id>
  - CONNECT <server-id> <port>
  - CONNECT <server-id> <port> <target>
  - CONNECT <server-id> <port> <host> <my-pwd> <peer-pwd>
  - CONNECT <server-id> <port> <host> <my-pwd> <peer-pwd> <target>

Note: the configuration option "AllowRemoteOper" mus be enabled on the
target server to allow forwarding of CONNECT commands.
2009-09-30 16:00:06 +02:00
Alexander Barton
4a3e40bc95 Check_Oper(): check origin of forwarded messages instead of server. 2009-09-30 16:00:05 +02:00
Alexander Barton
45b1a45c97 No_Privileges(): handle forwarded messages. 2009-09-30 16:00:05 +02:00
Alexander Barton
7d6de7c352 IRC_SendWallops(): support format string and variable parameter lists. 2009-09-30 16:00:05 +02:00
Alexander Barton
30b584c2e8 CONNECT, DISCONNECT: generate WALLOPS messages 2009-09-30 16:00:05 +02:00
Alexander Barton
eaaf0c3bd5 New function IRC_SendWallops().
Implement new global function IRC_SendWallops() that can be called by
other functions to generate WALLOPS messages to users with +w mode.
2009-09-30 16:00:05 +02:00
Alexander Barton
9a7499af8b Code cleanup of IRC_DISCONNECT(). 2009-09-30 16:00:05 +02:00
Alexander Barton
bce16c2864 Code cleanup of IRC_SQUIT() in preparation to deal with bug #73. 2009-09-30 16:00:05 +02:00
Alexander Barton
926204cacd New local functions Check_Oper() and No_Privileges(). 2009-09-30 16:00:05 +02:00
Alexander Barton
3bf0c6f3b9 Bad_OperPass(): code cleanup. 2009-09-30 16:00:05 +02:00
Alexander Barton
f78b0c61e9 New configuration option "AllowRemoteOper"
Added new configuration option "AllowRemoteOper" to control whether
remote IRC operators are allowed to use administrative commands that
affect this server or not

This commit introduces the configuration variable, but actually no
function is using it. That's up for the next patches to come ...
2009-09-30 16:00:04 +02:00
Florian Westphal
fa09883c72 fix assertion failure in ng_ipaddr.c
when building with debugging enabled, but without ipv6 support,
ngircd dumped core when loading a config file that specified an ipv6
listen address.

ngircd: ng_ipaddr.c:45: ng_ipaddr_init: Assertion `sizeof(*addr) >=
res0->ai_addrlen' failed.
2009-09-26 11:12:47 +02:00
Florian Westphal
affa03b277 configtest: complain when ssl keys are not readable 2009-09-20 23:22:28 +02:00
Alexander Barton
5b1efaee67 Check for sockaddr_in.sin_len and initialize it
Test for sockaddr_in.sin_len and initialize it to the correct value
which some systems (notably Mac OS X) require.

Note: this code path is only relevant when not using getaddrinfo().
2009-09-14 01:23:19 +02:00
Alexander Barton
d5f80b2a8d Always use get{addr|name}info() when available
Both getaddrinfo() and getnameinfo() are now used always when available, and
not only when compiling ngIRCd with support for IPv6.

This not only enables ngIRCd to handle multiple addresses per hostname when
compiled without support for IPv6, but fixes binding ngIRCd to IP addresses
on Mac OS X (and probably other BSD-based systems) as well: these systems
require that sockaddr_in is zeroed out and sockaddr_in.sin_len is set to
sizeof(sockaddr_in) like that:

  src/ipaddr/ng_ipaddr.c, line 54:

        assert(ip_str);
      + memset(addr, 0, sizeof *addr);
      + addr->sin4.sin_len = sizeof(addr->sin4);
        addr->sin4.sin_family = AF_INET;

But this would break all the systems not using sockaddr_in.sin_len, for
example Linux -- so we assume that all these systems provide getaddrinfo()
and use that for now.
2009-09-14 01:07:39 +02:00
Alexander Barton
60fc4d6335 Xcode: add "debug" configuration to project 2009-09-14 00:23:44 +02:00
Alexander Barton
536538968c Fix cb_connserver() to handle aborted outgoing connections
A configured server could have been removed while a connection apptempt
is still in progress. So the cb_connserver() callback has to test if the
server configuration record is still valid.
2009-09-12 00:17:42 +02:00
Florian Westphal
4daf780f01 conn.c: fix more sizeof(..dst_addr) misuse
the wrong sizeof() usage fixed in
d76910ce7b
(conn.c: fix resolver server address backlog) was a bit more
widespread, fix all others, too.
2009-09-11 23:31:46 +02:00
Florian Westphal
ed72bf4ceb resolve.c: fix valgrind 'uninitialized memory' warning
fix the following warning generated by valgrind if ipv6 is enabled:

Syscall param write(buf) points to uninitialised byte(s)
   at 0x4000982: (within /lib/ld-2.9.so)
   by 0x80681A8: Resolve_Name (resolve.c:477)
   by 0x805439F: Conn_Handler (conn.c:1658)
   by 0x804AA7C: main (ngircd.c:331)

The warning is because ng_ipaddr_t can be a union, and only the
necessary parts are initialised.  The callers know what part
of the union is valid, so this is not a bug.
2009-09-11 23:09:11 +02:00
Florian Westphal
d76910ce7b conn.c: fix resolver server address backlog
if more than one ip address is returned for a single host
name, ngircd is supposed to try other addresses in case
connect() to the first address returned fails for some
reason.

Alexander Barton noticed that this did not work at all,
as the additional results were not stored.
2009-09-11 22:55:32 +02:00
Alexander Barton
8fd0e29d46 Fix "implicit conversion shortens 64-bit value" warning
This patch fixes the following gcc warning in our sources:
"implicit conversion shortens 64-bit value into a 32-bit value"
2009-09-11 22:52:12 +02:00
Alexander Barton
bfa48f3448 Xcode: use gcc 4.0 for Mac OS X 10.4 compatibility 2009-09-11 20:19:51 +02:00
Alexander Barton
66c6458ae7 Channel_Mode(): fix return code of function
Fix error handling of Channel_Mode() to return the correct connection
status ("connected"/"disconnected") insted of always returning success.
2009-09-11 00:48:07 +02:00
Alexander Barton
3b37ad334b IRC_SERVER(): code cleanup, remove unneeded variable 2009-09-11 00:41:12 +02:00
Alexander Barton
c191ea53a9 IRC_PASS(): remove unnecessary variable initialization 2009-09-10 11:50:43 +02:00
Alexander Barton
e1598e2670 Conn_Close(): remove unused variable "txt" 2009-09-10 11:49:39 +02:00
Alexander Barton
44acf41cc1 Mac OS X: fix test for packagemaker(1) tool in Makefile 2009-09-10 11:48:14 +02:00
Alexander Barton
933da741c6 Fix --with-{openssl|gnutls} to accept path names
This patch fixes --with-openssl and --with-gnutls and enables both to
accept path names, so that you can use "./configure --with-XXX=/path".
All the other --with-XXX parameters support this already.
2009-09-02 14:28:09 +02:00
Florian Westphal
cf7e19193b do not add default listening port if ssl ports were specified
Cosmo Kastemaa reported that its impossible to create an ssl-only setup,
as ngircd binds to port 6667 by default, even if setting "Ports =".

Only add the default port if _both_ "Ports" and "SSLPorts" are
unspecified.

Fixes bugzilla #98.
2009-08-31 22:08:35 +02:00
Alexander Barton
5f1e43416a Fix LSB header of Debian init script 2009-08-29 23:57:39 +02:00
Alexander Barton
5debe20509 Use AM_SILENT_RULES([yes]), if available
Starting with GNU automake 1.11 "AM_SILENT_RULES([yes])" is available to
make the build process less verbose ("Linux 2.6 style") which helps to
spot warning and error messages.

So we use it if it is available.
2009-08-16 16:08:21 +02:00
Alexander Barton
a7eef6666b Update NEWS and ChangeLog for next release 2009-08-12 14:48:33 +02:00
Alexander Barton
56a8abc253 Updated doc/Platforms.txt 2009-08-04 22:53:38 +02:00
Alexander Barton
21bb2bd658 New script contrib/platformtest.sh
This script analyzes the build process of ngIRCd and generates output
suitable for inclusion in doc/Platforms.txt.
2009-08-04 22:30:59 +02:00
Florian Westphal
bddfd67550 doc/Platforms.txt: ngircd builds on hppa2.0w-hp-hpux11.11 target
Goetz Hoffart reports successful compile on HPUX/HPPA (on ngircd mailing list):

             Target: hppa2.0w-hp-hpux11.11
           Compiler: gcc
     Compiler flags: -g -O2 -pipe -W -Wall -Wpointer-arith -Wstrict-prototypes -fstack-protector -D_XOPEN_SOURCE_EXTENDED
-DSYSCONFDIR='"$(sysconfdir)"'
          Libraries: -lz -lnsl

     Syslog support: yes     Enable debug code: no
   zlib compression: yes           IRC sniffer: no
   Use TCP Wrappers: no        Strict RFC mode: no
   Zeroconf support: no          IRC+ protocol: yes
      IDENT support: no            I/O backend: "poll()"
      IPv6 protocol: no            SSL support: no
2009-07-22 22:06:36 +02:00
Alexander Barton
805bf03490 Client_CheckID(): fix connection information
This patch fixes the following silly log messages:
'ID "XXX" already registered (on connection -1)!'

If the ID is already registered on a local connection, the local
connection ID is printed; and if the ID is connected via a remote
server, "via network" is displayed.
2009-07-17 16:16:04 +02:00
Alexander Barton
63cbc6cd42 Fix return code of Conf_EnableServer()
Conf_EnableServer() only reports success if all required variables,
including host name and port, are set for the specific server.
2009-07-17 14:55:30 +02:00
Florian Westphal
b3cacf86df AUTHORS: update my email address 2009-06-08 12:25:35 +02:00
Florian Westphal
0ef94edad7 add section and rfc number to comment about QUIT error 2009-06-05 01:39:33 +02:00
Florian Westphal
643ae1b48b enforce upper limit on maximum number of handled commands
reported on #ngircd: pasting lots of lines into a channel can kill off
many people on the channel if the read buffer is drained quickly enough
and the client-side TCP can't keep up with the incoming data.

This implements a throttling scheme:
- an irc client may send up to 3 commands per second before a one second
pause is enforced.
- an irc client may send up to 256 bytes per second before a one second
pause is enforced.

After discussion with Alexander Barton, server <-> server links are
treated specially: There is no artificial limit on the number of bytes
sent per second, and up to 10 commands are processed per second before
a pause is enforced.

It may be neccessary to make those limits tuneable to accomondate larger
networks, but for now they are compile time values.
2009-05-25 22:25:18 +02:00
Florian Westphal
9b1c47220f conn.c: fix NumConnections imbalance
New_Server() can call Conn_Close() in its error paths,
but that function decrements the number of current active
connections. Thus we need to increment it earlier.
2009-05-17 21:32:53 +02:00
Florian Westphal
8e2c5816ee SSL/TLS: fix error handling when ssl ctx init for outgoing server link fails 2009-05-17 21:27:27 +02:00
Florian Westphal
f31c3a3aa2 SSL/TLS: fix error path in gnutls ssl ctx allocation 2009-05-17 21:18:04 +02:00
Florian Westphal
b0931f322b manpage: move SSLConnect option to the right section 2009-05-17 01:22:18 +02:00
Florian Westphal
5196e9bcb1 SSL/TLS: remove redundant asserts/ifdefs 2009-05-16 20:48:43 +02:00
Florian Westphal
57aa64e117 SSL/TLS: proper indentation, remove erroneous comment 2009-05-14 00:00:55 +02:00
Alexander Barton
fd7e85b798 Update copyright notice, it's 2009 already! 2009-05-05 17:08:48 +02:00
50 changed files with 1669 additions and 654 deletions

View File

@@ -19,7 +19,7 @@ directly, if possible!
Main Authors
~~~~~~~~~~~~
Alexander Barton, <alex@barton.de> (alex)
Florian Westphal, <westphal@foo.fh-furtwangen.de> (fw)
Florian Westphal, <fw@strlen.de>
Contributors

View File

@@ -1,7 +1,7 @@
ngIRCd - Next Generation IRC Server
(c)2001-2009 Alexander Barton,
(c)2001-2010 Alexander Barton,
alex@barton.de, http://www.barton.de/
ngIRCd is free software and published under the
@@ -10,6 +10,72 @@
-- ChangeLog --
ngIRCd Release 16 (2010-05-02)
- doc/SSL: remove line continuation marker
ngIRCd 16~rc2 (2010-04-25)
- Updated some more copyright notices, it's 2010 already :-)
- Only compile in Get_Error() if really needed
- Fix gcc warning "ignoring return value of ..."
- Include netinet/in_systm.h alongside netinet/ip.h
- Include netinet/{in.h, in_systm.h} when checking for netinet/ip.h
- Only include <netinet/in_systm.h> if it exists
- Updated doc/Platforms.txt
- Enhace connection statistics counters: display total number of served
connections on daemon shutdown and when a new client connects using
the new numeric RPL_STATSCONN (250).
ngIRCd 16~rc1 (2010-03-25)
- Various fixes to the build system and code cleanups.
- contrib/platformtest.sh: Only show latest commit.
- Updatet doc/Platforms.txt, added new README-Interix.txt documenting
how to tun ngIRCd on Microsoft Services for UNIX (MS SFU, MS SUA).
- Updated links to the ngIRCd homepage (bug tracker, mailing list).
- Added missing modes to USERMODES #define
- Show our name (IRCD=ngIRCd) in ISUPPORT (005) numeric
- Quote received messages of ERROR commands in log output.
- ngircd.conf manual page: document missing "Password" variable.
- Implement WEBIRC command used by some Web-IRC frontends. The password
required to secure this command must be configured using the new
"WebircPassword" variable in the ngircd.conf file.
- Don't use port 6668 as example for both "Ports" and "SSLPorts".
- Remove limit on max number of configured irc operators.
- Only link "nsl" library when really needed.
- A new channel mode "secure connections only" (+z) has been implemented:
Only clients using a SSL encrypted connection to the server are allowed
to join such a channel.
But please note three things: a) already joined clients are not checked
when setting this mode, b) IRC operators are always allowed to join
every channel, and c) remote clients using a server not supporting this
mode are not checked either and therefore always allowed to join.
ngIRCd Release 15 (2009-11-07)
- "ngircd --configtest": print SSL configuration options even when unset.
ngIRCd 15~rc1 (2009-10-15)
- Do not add default listening port (6667) if SSL ports were specified, so
ngIRCd can be configured to only accept SSL-encrypted connections now.
- Enable IRC operators to use the IRC command SQUIT (insted of the already
implemented but non-standard DISCONNECT command).
- New configuration option "AllowRemoteOper" (disabled by default) that
enables remote IRC operators to use the IRC commands SQUIT and CONNECT
on the local server.
- Mac OS X: fix test for packagemaker(1) tool in Makefile and use gcc 4.0
for Mac OS X 10.4 compatibility in the Xcode project file.
- Fix --with-{openssl|gnutls} to accept path names.
- Fix LSB header of Debian init script.
- Updated doc/Platforms.txt and include new script contrib/platformtest.sh
to ease generating platform reports.
- Fix connection information for already registered connections.
- Enforce upper limit on maximum number of handled commands. This implements
a throttling scheme: an IRC client can send up to 3 commands or 256 bytes
per second before a one second pause is enforced.
- Fix connection counter.
- Fix a few error handling glitches for SSL/TLS connections.
- Minor fixes to manual pages and documentation.
ngIRCd Release 14.1 (2009-05-05)
- Security: fix remotely triggerable crash in SSL/TLS code.

View File

@@ -56,7 +56,7 @@ deb:
dpkg-buildpackage -rfakeroot -i
osxpkg: have-xcodebuild
@packagemaker >/dev/null 2>&1; [ $$? -ge 1 ] \
@packagemaker >/dev/null 2>&1; [ $$? -le 1 ] \
|| ( echo; echo "Error: \"packagemaker\" not found!"; echo; exit 2)
make clean
./configure --prefix=/opt/ngircd

36
NEWS
View File

@@ -1,7 +1,7 @@
ngIRCd - Next Generation IRC Server
(c)2001-2009 Alexander Barton,
(c)2001-2010 Alexander Barton,
alex@barton.de, http://www.barton.de/
ngIRCd is free software and published under the
@@ -10,6 +10,40 @@
-- NEWS --
ngIRCd Release 16 (2010-05-02)
ngIRCd 16~rc2 (2010-04-25)
- Enhace connection statistics counters: display total number of served
connections on daemon shutdown and when a new client connects using
the new numeric RPL_STATSCONN (250).
ngIRCd 16~rc1 (2010-03-25)
- Implement WEBIRC command used by some Web-IRC frontends. The password
required to secure this command must be configured using the new
"WebircPassword" variable in the ngircd.conf file.
- Remove limit on max number of configured irc operators.
- A new channel mode "secure connections only" (+z) has been implemented:
Only clients using a SSL encrypted connection to the server are allowed
to join such a channel.
But please note three things: a) already joined clients are not checked
when setting this mode, b) IRC operators are always allowed to join
every channel, and c) remote clients using a server not supporting this
mode are not checked either and therefore always allowed to join.
ngIRCd Release 15 (2009-11-07)
ngIRCd 15~rc1 (2009-10-15)
- Do not add default listening port (6667) if SSL ports were specified, so
ngIRCd can be configured to only accept SSL-encrypted connections now.
- Enable IRC operators to use the IRC command SQUIT (insted of the already
implemented but non-standard DISCONNECT command).
- New configuration option "AllowRemoteOper" (disabled by default) that
enables remote IRC operators to use the IRC commands SQUIT and CONNECT
on the local server.
- Enforce upper limit on maximum number of handled commands. This implements
a throttling scheme: an IRC client can send up to 3 commands or 256 bytes
per second before a one second pause is enforced.
ngIRCd Release 14.1 (2009-05-05)
- Security: fix remotely triggerable crash in SSL/TLS code.

4
README
View File

@@ -78,10 +78,10 @@ VI. Bugs
If you find bugs in the ngIRCd (which might be there :-), please report
them at the following URL:
<http://ngircd.barton.de/#bugs>
<http://ngircd.barton.de/bugtracker.php>
There you can read about known bugs and limitations, too.
If you have critics, patches or something else, please feel free to post a
mail to the ngIRCd mailing list: <ngircd-ml@arthur.ath.cx> (please see
<http://ngircd.barton.de/#ml> for details).
<http://ngircd.barton.de/support.php#ml> for details).

View File

@@ -1,6 +1,6 @@
#
# ngIRCd -- The Next Generation IRC Daemon
# Copyright (c)2001-2008 Alexander Barton <alex@barton.de>
# Copyright (c)2001-2009 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
@@ -12,12 +12,14 @@
# -- Initialisation --
AC_PREREQ(2.50)
AC_INIT(ngircd, 14.1)
AC_INIT(ngircd, 16)
AC_CONFIG_SRCDIR(src/ngircd/ngircd.c)
AC_CANONICAL_TARGET
AM_INIT_AUTOMAKE(1.6)
AM_CONFIG_HEADER(src/config.h)
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
# -- Templates for config.h --
AH_TEMPLATE([DEBUG], [Define if debug-mode should be enabled])
@@ -31,6 +33,7 @@ AH_TEMPLATE([IRCPLUS], [Define if IRC+ protocol should be used])
AH_TEMPLATE([WANT_IPV6], [Define if IPV6 protocol should be enabled])
AH_TEMPLATE([ZEROCONF], [Define if support for Zeroconf should be included])
AH_TEMPLATE([IDENTAUTH], [Define if the server should do IDENT requests])
AH_TEMPLATE([HAVE_sockaddr_in_len], [Define if sockaddr_in.sin_len exists])
AH_TEMPLATE([TARGET_OS], [Target operating system name])
AH_TEMPLATE([TARGET_VENDOR], [Target system vendor])
@@ -71,7 +74,6 @@ AC_DEFUN([GCC_STACK_PROTECT_CC],[
fi
])
if test "$GCC" = "yes"; then
# We are using the GNU C compiler. Good!
CFLAGS="$CFLAGS -pipe -W -Wall -Wpointer-arith -Wstrict-prototypes"
@@ -99,11 +101,19 @@ AC_HEADER_TIME
AC_HEADER_SYS_WAIT
AC_CHECK_HEADERS([ \
ctype.h errno.h fcntl.h netdb.h netinet/in.h stdlib.h string.h \
strings.h sys/socket.h sys/time.h unistd.h \
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 \
],,AC_MSG_ERROR([required C header missing!]))
AC_CHECK_HEADERS([arpa/inet.h ctype.h malloc.h stdbool.h stddef.h varargs.h])
AC_CHECK_HEADERS([ \
arpa/inet.h ctype.h malloc.h netinet/ip.h stdbool.h stddef.h varargs.h \
],[],[],[[
#include <netinet/in.h>
#ifdef HAVE_NETINET_IN_SYSTM_H
#include <netinet/in_systm.h>
#endif
]]
)
# -- Datatypes --
@@ -123,12 +133,16 @@ AC_TRY_COMPILE([
AC_TYPE_SIGNAL
AC_TYPE_SIZE_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)
AC_CHECK_LIB(nsl,gethostent)
# -- Functions --
@@ -139,7 +153,8 @@ AC_CHECK_FUNCS([ \
bind gethostbyaddr gethostbyname gethostname inet_ntoa \
setsid setsockopt socket strcasecmp waitpid],,AC_MSG_ERROR([required function missing!]))
AC_CHECK_FUNCS(inet_aton isdigit sigaction snprintf vsnprintf strdup strlcpy strlcat strtok_r)
AC_CHECK_FUNCS(getaddrinfo getnameinfo inet_aton isdigit sigaction snprintf \
vsnprintf strdup strlcpy strlcat strtok_r)
# -- Configuration options --
@@ -313,7 +328,7 @@ fi
AC_ARG_WITH(openssl,
[ --with-openssl enable SSL support using OpenSSL],
[ if test "$withval" = "yes"; then
[ if test "$withval" != "no"; then
if test "$withval" != "yes"; then
CFLAGS="-I$withval/include $CFLAGS"
CPPFLAGS="-I$withval/include $CPPFLAGS"
@@ -330,7 +345,7 @@ AC_ARG_WITH(openssl,
AC_ARG_WITH(gnutls,
[ --with-gnutls enable SSL support using gnutls],
[ if test "$withval" = "yes"; then
[ if test "$withval" != "no"; then
if test "$withval" != "yes"; then
CFLAGS="-I$withval/include $CFLAGS"
CPPFLAGS="-I$withval/include $CPPFLAGS"
@@ -477,6 +492,8 @@ AC_ARG_ENABLE(ipv6,
if test "$enableval" = "yes"; then x_ipv6_on=yes; fi
)
if test "$x_ipv6_on" = "yes"; then
# getaddrinfo() and getnameinfo() are optional when not compiling
# with IPv6 support, but are required for IPv6 to work!
AC_CHECK_FUNCS([ \
getaddrinfo getnameinfo \
],,AC_MSG_ERROR([required function missing for IPv6 support!]))

View File

@@ -1,3 +1,33 @@
ngircd (16-0ab1) unstable; urgency=low
* New "upstream" release: ngIRCd 16.
-- Alexander Barton <alex@barton.de> Sun, 02 May 2010 13:32:41 +0200
ngircd (16~rc2-0ab1) unstable; urgency=low
* New "upstream" release candidate 2 for ngIRCd Release 16.
-- Alexander Barton <alex@barton.de> Sun, 25 Apr 2010 13:12:42 +0200
ngircd (16~rc1-0ab1) unstable; urgency=low
* New "upstream" release candidate 1 for ngIRCd Release 16.
-- Alexander Barton <alex@barton.de> Thu, 25 Mar 2010 15:56:03 +0200
ngircd (15-0ab1) unstable; urgency=low
* New "upstream" release: ngIRCd 15.
-- Alexander Barton <alex@barton.de> Thu, 7 Nov 2009 12:07:08 +0200
ngircd (15~rc1-0ab1) unstable; urgency=low
* New "upstream" release candidate 1 for ngIRCd Release 15.
-- Alexander Barton <alex@barton.de> Thu, 15 Oct 2009 10:01:08 +0200
ngircd (14.1-0ab1) unstable; urgency=high
* New "upstream" release ngIRCd 14.1, fixing a security-related bug.

View File

@@ -5,8 +5,8 @@
#
### BEGIN INIT INFO
# Provides: ngircd ircd
# Required-Start: $network $local_fs
# Provides: ngircd
# Required-Start: $network $remote_fs
# Required-Stop:
# Should-Start: $syslog $named
# Should-Stop: $syslog

View File

@@ -71,6 +71,8 @@
#define HAVE_STDBOOL_H 1
/* Define to 1 if you have the <arpa/inet.h> header file. */
#define HAVE_ARPA_INET_H 1
/* Define to 1 if you have the <netinet/ip.h> header file. */
#define HAVE_NETINET_IP_H 1
/* Define to 1 if you have the `kqueue' function. */
#define HAVE_KQUEUE 1

View File

@@ -4,7 +4,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-2009 Alexander Barton and Contributors.\
Copyright (c)2001-2010 Alexander Barton and Contributors.\
\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\ql\qnatural\pardirnatural
\i0 \cf0 \
@@ -187,4 +187,4 @@ To disable automatic starting of ngIRCd, use this command:\
\ls2\ilvl0
\f1\fs24 \cf0 sudo launchctl unload -w \\\
/Library/LaunchDaemons/de.barton.ngircd.plist\
}]]></resource></locale></resources><flags/><item type="file">01ngircd.xml</item><item type="file">02de.xml</item><mod>properties.customizeOption</mod><mod>properties.title</mod><mod>description</mod><mod>properties.anywhereDomain</mod><mod>properties.systemDomain</mod></pkmkdoc>
}]]></resource></locale></resources><flags/><item type="file">01ngircd.xml</item><item type="file">02de.xml</item><mod>properties.customizeOption</mod><mod>properties.title</mod><mod>description</mod><mod>properties.anywhereDomain</mod><mod>properties.systemDomain</mod></pkmkdoc>

View File

@@ -35,6 +35,7 @@
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 */; };
FA85178C0FA061EC006A1F5A /* op.c in Sources */ = {isa = PBXBuildFile; fileRef = FA85178B0FA061EC006A1F5A /* op.c */; };
FAA3D27B0F139CDC00B2447E /* conn-ssl.c in Sources */ = {isa = PBXBuildFile; fileRef = FAA3D2790F139CDC00B2447E /* conn-ssl.c */; };
FAE5CC2E0CF2308A007D69B6 /* numeric.c in Sources */ = {isa = PBXBuildFile; fileRef = FAE5CC2D0CF2308A007D69B6 /* numeric.c */; };
/* End PBXBuildFile section */
@@ -193,6 +194,8 @@
FA407F2C0DB159F400271AF1 /* ng_ipaddr.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = ng_ipaddr.c; path = ipaddr/ng_ipaddr.c; sourceTree = "<group>"; };
FA407F2D0DB159F400271AF1 /* ng_ipaddr.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = ng_ipaddr.h; path = ipaddr/ng_ipaddr.h; sourceTree = "<group>"; };
FA407F380DB15AC700271AF1 /* GIT.txt */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = GIT.txt; sourceTree = "<group>"; };
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>"; };
FAA3D2700F139CB300B2447E /* invite-test.e */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = "invite-test.e"; sourceTree = "<group>"; };
FAA3D2710F139CB300B2447E /* join-test.e */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = "join-test.e"; sourceTree = "<group>"; };
FAA3D2720F139CB300B2447E /* kick-test.e */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = "kick-test.e"; sourceTree = "<group>"; };
@@ -332,6 +335,8 @@
FA322D070CEF74B1001761B3 /* ngircd.h */,
FAE5CC2D0CF2308A007D69B6 /* numeric.c */,
FAE5CC2C0CF2308A007D69B6 /* numeric.h */,
FA85178A0FA061EC006A1F5A /* op.h */,
FA85178B0FA061EC006A1F5A /* op.c */,
FA322D080CEF74B1001761B3 /* parse.c */,
FA322D090CEF74B1001761B3 /* parse.h */,
FA322D0A0CEF74B1001761B3 /* rendezvous.c */,
@@ -676,6 +681,7 @@
FAE5CC2E0CF2308A007D69B6 /* numeric.c in Sources */,
FA407F2E0DB159F400271AF1 /* ng_ipaddr.c in Sources */,
FAA3D27B0F139CDC00B2447E /* conn-ssl.c in Sources */,
FA85178C0FA061EC006A1F5A /* op.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -712,10 +718,9 @@
1DEB928B08733DD80010E9CD /* Default */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = (
ppc,
i386,
);
ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)";
ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc";
GCC_VERSION = 4.0;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
PREBINDING = NO;
@@ -723,6 +728,48 @@
};
name = Default;
};
FAB0570C105D917F006AF9E2 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)";
ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc";
GCC_DEBUGGING_SYMBOLS = full;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_VERSION = 4.0;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
PREBINDING = NO;
SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.4u.sdk";
};
name = Debug;
};
FAB0570D105D917F006AF9E2 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
GCC_WARN_CHECK_SWITCH_STATEMENTS = YES;
GCC_WARN_FOUR_CHARACTER_CONSTANTS = YES;
GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
GCC_WARN_MISSING_PARENTHESES = YES;
GCC_WARN_PEDANTIC = YES;
GCC_WARN_SHADOW = YES;
GCC_WARN_SIGN_COMPARE = YES;
GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = YES;
GCC_WARN_UNINITIALIZED_AUTOS = NO;
GCC_WARN_UNKNOWN_PRAGMAS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_LABEL = YES;
GCC_WARN_UNUSED_PARAMETER = YES;
GCC_WARN_UNUSED_VALUE = YES;
INSTALL_PATH = /usr/local/bin;
PRODUCT_NAME = ngIRCd;
SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.4u.sdk";
};
name = Debug;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
@@ -730,6 +777,7 @@
isa = XCConfigurationList;
buildConfigurations = (
1DEB928708733DD80010E9CD /* Default */,
FAB0570D105D917F006AF9E2 /* Debug */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Default;
@@ -738,6 +786,7 @@
isa = XCConfigurationList;
buildConfigurations = (
1DEB928B08733DD80010E9CD /* Default */,
FAB0570C105D917F006AF9E2 /* Debug */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Default;

View File

@@ -12,7 +12,7 @@
SUBDIRS = Debian MacOSX
EXTRA_DIST = README ngircd.spec systrace.policy ngindent ngircd-bsd.sh \
ngircd-redhat.init
ngircd-redhat.init platformtest.sh
maintainer-clean-local:
rm -f Makefile Makefile.in

View File

@@ -28,5 +28,8 @@ ngircd-redhat.init
ngircd.spec
- RPM "spec" file.
platformtest.sh
- Build ngIRCd and output a "result line" suitable for doc/Platforms.txt.
systrace.policy
- Systrace policy file for OpenBSD (and probably NetBSD).

View File

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

143
contrib/platformtest.sh Executable file
View File

@@ -0,0 +1,143 @@
#!/bin/sh
#
# ngIRCd -- The Next Generation IRC Daemon
# Copyright (c)2001-2009 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.
#
# This script analyzes the build process of ngIRCd and generates output
# suitable for inclusion in doc/Platforms.txt -- please send reports
# to the ngIRCd mailing list: <ngircd-ml@ngircd.barton.de>.
NAME=`basename "$0"`
VERBOSE=
PLATFORM=
COMPILER="unknown"
VERSION="unknown"
DATE=`date "+%y-%m-%d"`
CONFIGURE=
MAKE=
CHECK=
RUN=
COMMENT=
while [ $# -gt 0 ]; do
case "$1" in
"-v")
VERBOSE=1
;;
*)
echo "Usage: $NAME [-v]"
exit 2
esac
shift
done
echo "$NAME: Checking ngIRCd base source directory ..."
grep "ngIRCd" ./ChangeLog >/dev/null 2>&1
if [ $? -ne 0 ]; then
grep "ngIRCd" ../ChangeLog >/dev/null 2>&1
if [ $? -ne 0 ]; then
echo "$NAME: ngIRCd base source directory not found!?"
exit 1
fi
cd ..
fi
echo "$NAME: Checking for ./configure script ..."
if [ ! -e ./configure ]; then
echo "$NAME: Not found. Running ./autogen.sh ..."
[ -n "$VERBOSE" ] && ./autogen.sh || ./autogen.sh >/dev/null
fi
if [ -e ./configure ]; then
echo "$NAME: Running \"./configure\" script ..."
[ -n "$VERBOSE" ] && ./configure || ./configure >/dev/null
if [ $? -eq 0 -a -e ./Makefile ]; then
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
if [ $? -eq 0 ]; then
CHECK=1
RUN=$CHECK
else
./src/ngircd/ngircd --help 2>/dev/null \
| grep "^ngircd" >/dev/null
[ $? -eq 0 ] && RUN=1
fi
fi
fi
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`
PLATFORM="$CPU/$VENDOR/$OS"
fi
if [ -z "$PLATFORM" ]; then
PLATFORM="`uname 2>/dev/null` `uname -r 2>/dev/null`, `uname -m 2>/dev/null`"
fi
# Get compiler information
if [ -r "Makefile" ]; then
eval $(grep "^CC = " Makefile | sed -e 's/ //g')
$CC --version 2>&1 | grep -i "GCC" >/dev/null
if [ $? -eq 0 ]; then
COMPILER=$($CC --version | head -n 1 | awk "{ print \$3 }" \
| cut -d'-' -f1)
COMPILER="gcc $COMPILER"
fi
fi
# Get ngIRCd version information
if [ -d ".git" ]; then
VERSION=`git log --abbrev-commit --pretty=oneline HEAD~1.. \
| head -1 | cut -d' ' -f1 | tr -d '.'`
elif [ -r "Makefile" ]; then
eval $(grep "^VERSION = " Makefile | sed -e 's/ //g')
fi
[ -n "$VERSION" ] || VERSION="unknown"
# Get IO interface information
if [ "$OS" = "linux-gnu" ]; then
COMMENT="(1)"
else
grep "^#define HAVE_SYS_DEVPOLL_H 1" src/config.h >/dev/null 2>&1
[ $? -eq 0 ] && COMMENT="(4)"
grep "^#define HAVE_EPOLL_CREATE 1" src/config.h >/dev/null 2>&1
[ $? -eq 0 ] && COMMENT="(5)"
grep "^#define HAVE_KQUEUE 1" src/config.h >/dev/null 2>&1
[ $? -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 "$COMMENT" ] && COMMENT=" $COMMENT"
echo
echo " the executable works (\"runs\") as expected --+"
echo " tests run successfully (\"make check\") --+ |"
echo " ngIRCd compiles (\"make\") --+ | |"
echo " ./configure works --+ | | |"
echo " | | | |"
echo "Platform Compiler ngIRCd Date Tester C M T R See"
echo "--------------------------- ------------ ---------- -------- ------ - - - - ---"
printf "%-27s %-12s %-10s %s %-6s %s %s %s %s%s" \
"$PLATFORM" "$COMPILER" "$VERSION" "$DATE" "$USER" \
"$C" "$M" "$T" "$R" "$COMMENT"
echo; echo

View File

@@ -1,7 +1,7 @@
ngIRCd - Next Generation IRC Server
(c)2001-2008 Alexander Barton
(c)2001-2010 Alexander Barton
alex@barton.de, http://www.barton.de/
ngIRCd is free software and published under the
@@ -30,26 +30,32 @@ alpha/unknown/netbsd3.0 gcc 3.3.3 CVSHEAD 06-05-07 fw Y Y Y Y (3)
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
i386/apple/darwin9.5.1 gcc 4.0.1 13~rc1 08-12-02 alex Y Y Y Y (3)
hppa2.0w-hp-hpux11.11 gcc 4.2.3 14.1 09-07-22 goetz Y Y Y Y
i386/apple/darwin9.7.0 gcc 4.0.1 14.1 09-08-04 alex Y Y Y Y (3)
i386/apple/darwin10.3.0 gcc 4.2.1 16 10-04-23 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 13~rc1 08-12-03 alex Y Y Y Y (4)
i386/pc/solaris2.11 gcc 3.4.3 14.1 09-08-03 alex 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.0 gcc 3.4.4 0.10.0-p1 06-08-04 alex Y Y Y Y (3)
i386/unknown/freebsd6.1 gcc 3.4.4 CVSHEAD 06-05-07 fw Y Y Y Y (3)
i386/unknown/freebsd6.2 gcc 3.4.6 13~rc1 08-12-04 alex Y Y Y Y (3)
i386/unknown/freebsd7.0 gcc 4.2.1 13~rc1 08-12-04 alex Y Y Y Y (3)
i386/unknown/freebsd6.2 gcc 3.4.6 16 10-04-11 alex Y Y Y Y (3)
i386/unknown/freebsd7.0 gcc 4.2.1 14.1 09-07-28 alex Y Y Y Y (3)
i386/unknown/freebsd7.2 gcc 4.2.1 14.1 09-08-03 alex Y Y Y Y (3)
i386/unknown/freebsd7.3 gcc 4.2.1 16 10-04-11 alex Y Y Y Y (3)
i386/unknown/gnu0.3 gcc 3.3.3 0.8.0 04-05-30 alex Y Y n Y
i686/unknown/gnu0.3 gcc 4.3.1 13~rc1 08-12-05 alex Y Y Y Y
i686/unknown/gnu0.3 gcc 4.3.1 14.1 09-07-28 alex Y Y Y Y
i686/unkn./kfreebsd7.2-gnu gcc 4.3.4 15 09-12-02 alex Y Y Y Y (3)
i386/unknown/netbsdelf1.6.1 gcc 2.95.3 CVSHEAD 04-02-24 alex Y Y Y Y
i386/unknown/netbsdelf3.0.1 gcc 3.3.3 0.10.0-p1 06-08-30 alex Y Y Y Y (3)
i386/unknown/netbsdelf4.0 gcc 4.1.2 13~rc1 08-12-05 alex Y Y Y Y (3)
i386/unknown/netbsdelf4.0 gcc 4.1.2 16 10-04-11 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 13~rc1 08-12-05 alex Y Y Y Y (3)
i386/unknown/openbsd4.1 gcc 3.3.5 16 10-04-11 alex Y Y Y Y (3)
i586/pc/interix3.5 gcc 3.3 15 10-01-22 alex Y Y N Y
i686/pc/cygwin gcc 3.3.1 0.8.0 04-05-30 alex Y Y n Y
i686/pc/linux-gnu gcc 2.95.4 0.8.0 04-05-30 alex Y Y Y Y (1)
i686/pc/linux-gnu gcc 3.3.5 13~rc1 08-12-05 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)
i386/pc/linux-gnu gcc 4.3.2 13~rc1 08-12-05 alex Y Y Y Y (1)
i686/pc/linux-gnu gcc 4.3.2 14.1 09-08-04 alex Y Y Y Y (1)
m68k/apple/aux3.1.1 Orig. A/UX 0.7.x-CVS 03-04-22 alex Y Y Y Y (2)
m68k/hp/hp-ux9.10 Orig. HPUX 0.7.x-CVS 03-04-30 goetz Y Y Y Y
m88k/dg/dgux5.4R3.10 gcc 2.5.8 CVSHEAD 04-03-15 alex Y Y ? ?
@@ -62,19 +68,20 @@ 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/linux-gnu 4.3.2 13~rc1 08-12-05 alex Y Y Y Y (5)
x86_64/unknown/freebsd8.0 gcc 4.2.1 16 10-04-23 alex Y Y Y Y (3)
x86_64/unknown/linux-gnu gcc 4.3.2 16 10-04-23 alex Y Y Y Y (1)
Notes
~~~~~
(1) i686/pc/linux-gnu:
(1) i686/pc/linux-gnu & x86_64/unknown/linux-gnu:
ngIRCd has been tested with various Linux distributions, such as SuSE,
RedHat, Debian, and Gentoo using Kernels 2.2.x, 2.4.x and 2.6.x with
various versions of the GNU C compiler (starting with 2.95.x and up to
version 4.3.x). The eldest glibc used was glibc-2.0.7. ngIRCd compiled
and run on all these systems without problems.
Actual Linux kernels (2.6.x) and glic's support the epoll() IO interface.
Actual Linux kernels (2.6.x) and glibc's support the epoll() IO interface.
(2) This compiler is an pre-ANSI C compiler, therefore the source code is
automatically converted using the included ansi2knr tool while building.

37
doc/README-Interix.txt Normal file
View File

@@ -0,0 +1,37 @@
ngIRCd - Next Generation IRC Server
(c)2001-2010 Alexander Barton,
alex@barton.de, http://www.barton.de/
ngIRCd is free software and published under the
terms of the GNU General Public License.
-- README-Interix.txt --
ngIRCd release 15 has successfully been tested on Microsoft Windows XP
Professional using the Services for UNIX (SFU) version 3.5 and Microsoft
Windows 7 with the bundled Subsystem for UNIX Applications (SUA).
SFU are supported on Windows 2000, Windows 2000 Server, Windows XP, and
Windows Server 2003. SUA is supported on Windows Server 2003 R2, Windows
Server 2008 & 2008 R2, Windows Vista, and Windows 7 -- so ngIRCd should be
able to run on all of these platforms.
But please note that the poll() API function is not fully implemented by
SFU/SUA and therefore can't be used by ngIRCd -- which normally would be
the default. Please see <http://www.suacommunity.com/faqs.aspx> section
4.25 for details:
"If you do try to use the poll() API your program will block on the
API call forever. You must direct your program to build using the
select() API."
So when running the ./configure script, you HAVE TO DISABLE poll() support:
./configure --without-poll
ngIRCd then defaults to using the select() API function which works fine.

View File

@@ -49,8 +49,7 @@ Creating a self-signed certificate
OpenSSL:
Creating a self-signed certificate and key:
$ openssl req -newkey rsa:2048 -x509 -keyout server-key.pem \
-out server-cert.pem -days 1461
$ openssl req -newkey rsa:2048 -x509 -keyout server-key.pem -out server-cert.pem -days 1461
Create DH parameters (optional):
$ openssl dhparam -2 -out dhparams.pem 2048
@@ -58,8 +57,7 @@ GnuTLS:
Creating a self-signed certificate and key:
$ certtool --generate-privkey --bits 2048 --outfile server-key.pem
$ certtool --generate-self-signed --load-privkey server-key.pem \
--outfile server-cert.pem
$ certtool --generate-self-signed --load-privkey server-key.pem --outfile server-cert.pem
Create DH parameters (optional):
$ certtool --generate-dh-params --bits 2048 --outfile dhparams.pem

View File

@@ -28,9 +28,15 @@
# LINKS requests for example.
Info = Server Info Text
# Global password for all users needed to connect to the server
# Global password for all users needed to connect to the server.
# (Default: not set)
;Password = abc
# Password required for using the WEBIRC command used by some
# Web-to-IRC gateways. If not set/empty, the WEBIRC command can't
# be used. (Default: not set)
;WebircPassword = xyz
# Information about the server and the administrator, used by the
# ADMIN command. Not required by server but by RFC!
;AdminInfo1 = Description
@@ -42,7 +48,7 @@
;Ports = 6667, 6668, 6669
# Additional Listen Ports that expect SSL/TLS encrypted connections
;SSLPorts = 9999,6668
;SSLPorts = 6697, 9999
# SSL Server Key
;SSLKeyFile = /usr/local/etc/ngircd/ssl/server-key.pem
@@ -115,6 +121,10 @@
# server? (This is a compatibility hack for ircd-irc2 servers)
;OperServerMode = no
# Are remote IRC operators allowed to control this server, e. g.
# use commands like CONNECT, SQUIT, DIE, ...?
;AllowRemoteOper = no
# Allow Pre-Defined Channels only (see Section [Channels])
;PredefChannelsOnly = no

View File

@@ -69,13 +69,23 @@ IRC network and must contain at least one dot (".") character.
Info text of the server. This will be shown by WHOIS and LINKS requests for
example.
.TP
\fBPassword\fR
Global password for all users needed to connect to the server. The default
is empty, so no password is required.
.TP
\fBWebircPassword\fR
Password required for using the WEBIRC command used by some Web-to-IRC
gateways. If not set or empty, the WEBIRC command can't be used.
Default: not set.
.TP
\fBAdminInfo1\fR, \fBAdminInfo2\fR, \fBAdminEMail\fR
Information about the server and the administrator, used by the ADMIN
command.
.TP
\fBPorts\fR
Ports on which the server should listen. There may be more than one port,
separated with commas (","). Default: 6667.
separated with commas (","). Default: 6667, unless \fBSSL_Ports\fR are also
specified.
.TP
\fBSSLPorts\fR
Same as \fBPorts\fR , except that ngIRCd will expect incoming connections
@@ -178,6 +188,11 @@ If \fBOperCanUseMode\fR is enabled, this may lead the compatibility problems wit
Servers that run the ircd-irc2 Software. This Option "masks" mode requests
by non-chanops as if they were coming from the server. Default: no.
.TP
\fBAllowRemoteOper\fR
Are IRC operators connected to remote servers allowed to control this server,
e. g. are they allowed to use administrative commands like CONNECT, DIE,
SQUIT, ... that affect this server? Default: no.
.TP
\fBPredefChannelsOnly\fR
If enabled, no new channels can be created. Useful if
you do not want to have channels other than those defined in
@@ -221,9 +236,6 @@ Default: 10.
Maximum length of an user nick name (Default: 9, as in RFC 2812). Please
note that all servers in an IRC network MUST use the same maximum nick name
length!
.TP
\fBSSLConnect\fR
Connect to the remote server using TLS/SSL. Default: false.
.SH [OPERATOR]
.I [Operator]
sections are used to define IRC Operators. There may be more than one
@@ -287,6 +299,9 @@ Group of this server (optional).
Disable automatic connection even if port value is specified. Default: false.
You can use the IRC Operator command CONNECT later on to create the link.
.TP
\fBSSLConnect\fR
Connect to the remote server using TLS/SSL. Default: false.
.TP
\fBServiceMask\fR
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

View File

@@ -30,6 +30,9 @@ ng_ipaddr_init(ng_ipaddr_t *addr, const char *ip_str, UINT16 port)
memset(&hints, 0, sizeof(hints));
hints.ai_flags = AI_NUMERICHOST;
#ifndef WANT_IPV6 /* do not convert ipv6 addresses */
hints.ai_family = AF_INET;
#endif
/* some getaddrinfo implementations require that ai_socktype is set. */
hints.ai_socktype = SOCK_STREAM;
@@ -38,7 +41,6 @@ ng_ipaddr_init(ng_ipaddr_t *addr, const char *ip_str, UINT16 port)
snprintf(portstr, sizeof(portstr), "%u", (unsigned int) port);
ret = getaddrinfo(ip_str, portstr, &hints, &res0);
assert(ret == 0);
if (ret != 0)
return false;
@@ -51,6 +53,10 @@ ng_ipaddr_init(ng_ipaddr_t *addr, const char *ip_str, UINT16 port)
return ret == 0;
#else /* HAVE_GETADDRINFO */
assert(ip_str);
memset(addr, 0, sizeof *addr);
#ifdef HAVE_sockaddr_in_len
addr->sin4.sin_len = sizeof(addr->sin4);
#endif
addr->sin4.sin_family = AF_INET;
# ifdef HAVE_INET_ATON
if (inet_aton(ip_str, &addr->sin4.sin_addr) == 0)
@@ -151,7 +157,8 @@ ng_ipaddr_tostr_r(const ng_ipaddr_t *addr, char *str)
if (*str == ':') {
char tmp[NG_INET_ADDRSTRLEN] = "0";
ret = getnameinfo(sa, ng_ipaddr_salen(addr),
tmp+1, sizeof(tmp) -1, NULL, 0, NI_NUMERICHOST);
tmp + 1, (socklen_t)sizeof(tmp) - 1,
NULL, 0, NI_NUMERICHOST);
if (ret == 0)
strlcpy(str, tmp, NG_INET_ADDRSTRLEN);
}

View File

@@ -58,10 +58,10 @@ ng_ipaddr_salen(const ng_ipaddr_t *a)
#ifdef WANT_IPV6
assert(a->sa.sa_family == AF_INET || a->sa.sa_family == AF_INET6);
if (a->sa.sa_family == AF_INET6)
return sizeof(a->sin6);
return (socklen_t)sizeof(a->sin6);
#endif
assert(a->sin4.sin_family == AF_INET);
return sizeof(a->sin4);
return (socklen_t)sizeof(a->sin4);
}
@@ -115,4 +115,3 @@ ng_ipaddr_tostr_r(const ng_ipaddr_t *addr, char *d)
#endif
/* -eof- */

View File

@@ -23,7 +23,7 @@ sbin_PROGRAMS = ngircd
ngircd_SOURCES = ngircd.c array.c channel.c client.c conf.c conn.c conn-func.c \
conn-ssl.c conn-zip.c hash.c io.c irc.c irc-channel.c irc-info.c irc-login.c \
irc-mode.c irc-op.c irc-oper.c irc-server.c irc-write.c lists.c log.c \
match.c numeric.c parse.c rendezvous.c resolve.c
match.c op.c numeric.c parse.c rendezvous.c resolve.c
ngircd_LDFLAGS = -L../portab -L../tool -L../ipaddr
@@ -32,7 +32,7 @@ ngircd_LDADD = -lngportab -lngtool -lngipaddr
noinst_HEADERS = ngircd.h array.h channel.h client.h conf.h conf-ssl.h conn.h \
conn-func.h conn-ssl.h conn-zip.h hash.h io.h irc.h irc-channel.h \
irc-info.h irc-login.h irc-mode.h irc-op.h irc-oper.h irc-server.h \
irc-write.h lists.h log.h match.h numeric.h parse.h rendezvous.h \
irc-write.h lists.h log.h match.h numeric.h op.h parse.h rendezvous.h \
resolve.h defines.h messages.h
clean-local:

View File

@@ -1085,7 +1085,7 @@ Channel_CheckKey(CHANNEL *Chan, CLIENT *Client, const char *Key)
return false;
}
while (fgets(line, sizeof(line), fd) != NULL) {
while (fgets(line, (int)sizeof(line), fd) != NULL) {
ngt_TrimStr(line);
if (! (nick = strchr(line, ':')))
continue;

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
* Copyright (c)2001-2010 Alexander Barton (alex@barton.de)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -181,39 +181,46 @@ Client_NewRemoteUser(CLIENT *Introducer, const char *Nick, int Hops, const char
*/
static CLIENT *
Init_New_Client(CONN_ID Idx, CLIENT *Introducer, CLIENT *TopServer,
int Type, const char *ID, const char *User, const char *Hostname, const char *Info, int Hops,
int Token, const char *Modes, bool Idented)
int Type, const char *ID, const char *User, const char *Hostname,
const char *Info, int Hops, int Token, const char *Modes, bool Idented)
{
CLIENT *client;
assert( Idx >= NONE );
assert( Introducer != NULL );
assert( Hostname != NULL );
assert(Idx >= NONE);
assert(Introducer != NULL);
assert(Hostname != NULL);
client = New_Client_Struct( );
if( ! client ) return NULL;
client = New_Client_Struct();
if (!client)
return NULL;
client->starttime = time(NULL);
client->conn_id = Idx;
client->introducer = Introducer;
client->topserver = TopServer;
client->type = Type;
if( ID ) Client_SetID( client, ID );
if( User ) Client_SetUser( client, User, Idented );
if( Hostname ) Client_SetHostname( client, Hostname );
if( Info ) Client_SetInfo( client, Info );
if (ID)
Client_SetID(client, ID);
if (User)
Client_SetUser(client, User, Idented);
if (Hostname)
Client_SetHostname(client, Hostname);
if (Info)
Client_SetInfo(client, Info);
client->hops = Hops;
client->token = Token;
if( Modes ) Client_SetModes( client, Modes );
if( Type == CLIENT_SERVER ) Generate_MyToken( client );
if (Modes)
Client_SetModes(client, Modes);
if (Type == CLIENT_SERVER)
Generate_MyToken(client);
if( strchr( client->modes, 'a' ))
strlcpy( client->away, DEFAULT_AWAY_MSG, sizeof( client->away ));
if (strchr(client->modes, 'a'))
strlcpy(client->away, DEFAULT_AWAY_MSG, sizeof(client->away));
client->next = (POINTER *)My_Clients;
My_Clients = client;
Adjust_Counters( client );
Adjust_Counters(client);
return client;
} /* Init_New_Client */
@@ -758,18 +765,18 @@ Client_CheckID( CLIENT *Client, char *ID )
assert( Client->conn_id > NONE );
assert( ID != NULL );
/* Nick too long? */
/* ID too long? */
if (strlen(ID) > CLIENT_ID_LEN) {
IRC_WriteStrClient(Client, ERR_ERRONEUSNICKNAME_MSG, Client_ID(Client), ID);
return false;
}
/* does ID already exist? */
/* ID already in use? */
c = My_Clients;
while (c) {
if (strcasecmp(c->id, ID) == 0) {
snprintf(str, sizeof(str), "ID \"%s\" already registered", ID);
if (Client->conn_id != c->conn_id)
if (c->conn_id != NONE)
Log(LOG_ERR, "%s (on connection %d)!", str, c->conn_id);
else
Log(LOG_ERR, "%s (via network)!", str);

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
* Copyright (c)2001-2010 Alexander Barton (alex@barton.de)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -55,6 +55,7 @@ static bool Use_Log = true;
static CONF_SERVER New_Server;
static int New_Server_Idx;
static size_t Conf_Oper_Count;
static size_t Conf_Channel_Count;
static void Set_Defaults PARAMS(( bool InitServers ));
static bool Read_Config PARAMS(( bool ngircd_starting ));
@@ -95,19 +96,46 @@ ConfSSL_Init(void)
array_free_wipe(&Conf_SSLOptions.KeyFilePassword);
}
static bool
ssl_print_configvar(const char *name, const char *file)
{
FILE *fp;
static void
if (!file) {
printf(" %s =\n", name);
return true;
}
fp = fopen(file, "r");
if (fp)
fclose(fp);
else
fprintf(stderr, "ERROR: %s \"%s\": %s\n",
name, file, strerror(errno));
printf(" %s = %s\n", name, file);
return fp != NULL;
}
static bool
ConfSSL_Puts(void)
{
if (Conf_SSLOptions.KeyFile)
printf( " SSLKeyFile = %s\n", Conf_SSLOptions.KeyFile);
if (Conf_SSLOptions.CertFile)
printf( " SSLCertFile = %s\n", Conf_SSLOptions.CertFile);
if (Conf_SSLOptions.DHFile)
printf( " SSLDHFile = %s\n", Conf_SSLOptions.DHFile);
bool ret;
ret = ssl_print_configvar("SSLKeyFile", Conf_SSLOptions.KeyFile);
if (!ssl_print_configvar("SSLCertFile", Conf_SSLOptions.CertFile))
ret = false;
if (!ssl_print_configvar("SSLDHFile", Conf_SSLOptions.DHFile))
ret = false;
if (array_bytes(&Conf_SSLOptions.KeyFilePassword))
puts(" SSLKeyFilePassword = <secret>" );
puts(" SSLKeyFilePassword = <secret>");
array_free_wipe(&Conf_SSLOptions.KeyFilePassword);
return ret;
}
#endif
@@ -152,8 +180,8 @@ ports_parse(array *a, int Line, char *Arg)
* must be separated by "," */
ptr = strtok( Arg, "," );
while (ptr) {
ngt_TrimStr( ptr );
port = atol( ptr );
ngt_TrimStr(ptr);
port = atoi(ptr);
if (port > 0 && port < 0xFFFF) {
port16 = (UINT16) port;
if (!array_catb(a, (char*)&port16, sizeof port16))
@@ -199,6 +227,41 @@ yesno_to_str(int boolean_value)
}
static void
opers_free(void)
{
struct Conf_Oper *op;
size_t len;
len = array_length(&Conf_Opers, sizeof(*op));
op = array_start(&Conf_Opers);
while (len--) {
free(op->mask);
op++;
}
array_free(&Conf_Opers);
}
static void
opers_puts(void)
{
struct Conf_Oper *op;
size_t len;
len = array_length(&Conf_Opers, sizeof(*op));
op = array_start(&Conf_Opers);
while (len--) {
assert(op->name[0]);
puts("[OPERATOR]");
printf(" Name = %s\n", op->name);
printf(" Password = %s\n", op->pwd);
printf(" Mask = %s\n\n", op->mask ? op->mask : "");
op++;
}
}
GLOBAL int
Conf_Test( void )
{
@@ -228,60 +291,57 @@ Conf_Test( void )
}
puts( "[GLOBAL]" );
printf( " Name = %s\n", Conf_ServerName );
printf( " Info = %s\n", Conf_ServerInfo );
printf( " Password = %s\n", Conf_ServerPwd );
printf( " AdminInfo1 = %s\n", Conf_ServerAdmin1 );
printf( " AdminInfo2 = %s\n", Conf_ServerAdmin2 );
printf( " AdminEMail = %s\n", Conf_ServerAdminMail );
printf( " MotdFile = %s\n", Conf_MotdFile );
printf( " MotdPhrase = %s\n", Conf_MotdPhrase );
printf( " ChrootDir = %s\n", Conf_Chroot );
printf( " PidFile = %s\n", Conf_PidFile);
printf(" Name = %s\n", Conf_ServerName);
printf(" Info = %s\n", Conf_ServerInfo);
printf(" Password = %s\n", Conf_ServerPwd);
printf(" WebircPassword = %s\n", Conf_WebircPwd);
printf(" AdminInfo1 = %s\n", Conf_ServerAdmin1);
printf(" AdminInfo2 = %s\n", Conf_ServerAdmin2);
printf(" AdminEMail = %s\n", Conf_ServerAdminMail);
printf(" MotdFile = %s\n", Conf_MotdFile);
printf(" MotdPhrase = %s\n", Conf_MotdPhrase);
printf(" ChrootDir = %s\n", Conf_Chroot);
printf(" PidFile = %s\n", Conf_PidFile);
printf(" Listen = %s\n", Conf_ListenAddress);
fputs(" Ports = ", stdout);
ports_puts(&Conf_ListenPorts);
#ifdef SSL_SUPPORT
fputs(" SSLPorts = ", stdout);
ports_puts(&Conf_SSLOptions.ListenPorts);
ConfSSL_Puts();
if (!ConfSSL_Puts())
config_valid = false;
#endif
pwd = getpwuid( Conf_UID );
if( pwd ) printf( " ServerUID = %s\n", pwd->pw_name );
else printf( " ServerUID = %ld\n", (long)Conf_UID );
grp = getgrgid( Conf_GID );
if( grp ) printf( " ServerGID = %s\n", grp->gr_name );
else printf( " ServerGID = %ld\n", (long)Conf_GID );
printf( " PingTimeout = %d\n", Conf_PingTimeout );
printf( " PongTimeout = %d\n", Conf_PongTimeout );
printf( " ConnectRetry = %d\n", Conf_ConnectRetry );
printf( " OperCanUseMode = %s\n", yesno_to_str(Conf_OperCanMode));
printf( " OperServerMode = %s\n", yesno_to_str(Conf_OperServerMode));
printf( " PredefChannelsOnly = %s\n", yesno_to_str(Conf_PredefChannelsOnly));
printf( " NoDNS = %s\n", yesno_to_str(Conf_NoDNS));
printf( " NoIdent = %s\n", yesno_to_str(Conf_NoIdent));
pwd = getpwuid(Conf_UID);
if (pwd)
printf(" ServerUID = %s\n", pwd->pw_name);
else
printf(" ServerUID = %ld\n", (long)Conf_UID);
grp = getgrgid(Conf_GID);
if (grp)
printf(" ServerGID = %s\n", grp->gr_name);
else
printf(" ServerGID = %ld\n", (long)Conf_GID);
printf(" PingTimeout = %d\n", Conf_PingTimeout);
printf(" PongTimeout = %d\n", Conf_PongTimeout);
printf(" ConnectRetry = %d\n", Conf_ConnectRetry);
printf(" OperCanUseMode = %s\n", yesno_to_str(Conf_OperCanMode));
printf(" OperServerMode = %s\n", yesno_to_str(Conf_OperServerMode));
printf(" AllowRemoteOper = %s\n", yesno_to_str(Conf_AllowRemoteOper));
printf(" PredefChannelsOnly = %s\n", yesno_to_str(Conf_PredefChannelsOnly));
printf(" NoDNS = %s\n", yesno_to_str(Conf_NoDNS));
printf(" NoIdent = %s\n", yesno_to_str(Conf_NoIdent));
#ifdef WANT_IPV6
printf(" ConnectIPv4 = %s\n", yesno_to_str(Conf_ConnectIPv6));
printf(" ConnectIPv6 = %s\n", yesno_to_str(Conf_ConnectIPv4));
#endif
printf( " MaxConnections = %ld\n", Conf_MaxConnections);
printf( " MaxConnectionsIP = %d\n", Conf_MaxConnectionsIP);
printf( " MaxJoins = %d\n", Conf_MaxJoins>0 ? Conf_MaxJoins : -1);
printf( " MaxNickLength = %u\n\n", Conf_MaxNickLength - 1);
printf(" MaxConnections = %ld\n", Conf_MaxConnections);
printf(" MaxConnectionsIP = %d\n", Conf_MaxConnectionsIP);
printf(" MaxJoins = %d\n", Conf_MaxJoins > 0 ? Conf_MaxJoins : -1);
printf(" MaxNickLength = %u\n\n", Conf_MaxNickLength - 1);
for( i = 0; i < Conf_Oper_Count; i++ ) {
if( ! Conf_Oper[i].name[0] ) continue;
/* Valid "Operator" section */
puts( "[OPERATOR]" );
printf( " Name = %s\n", Conf_Oper[i].name );
printf( " Password = %s\n", Conf_Oper[i].pwd );
if ( Conf_Oper[i].mask ) printf( " Mask = %s\n", Conf_Oper[i].mask );
puts( "" );
}
opers_puts();
for( i = 0; i < MAX_SERVERS; i++ ) {
if( ! Conf_Server[i].name[0] ) continue;
@@ -400,7 +460,7 @@ Conf_EnableServer( const char *Name, UINT16 Port )
/* Gotcha! Set port and enable server: */
Conf_Server[i].port = Port;
Conf_Server[i].flags &= ~CONF_SFLAG_DISABLED;
return true;
return (Conf_Server[i].port && Conf_Server[i].host[0]);
}
}
return false;
@@ -487,47 +547,47 @@ Conf_IsService(int ConfServer, const char *Nick)
} /* Conf_IsService */
/**
* Initialize configuration settings with their default values.
*/
static void
Set_Defaults( bool InitServers )
Set_Defaults(bool InitServers)
{
/* Initialize configuration variables with default values. */
int i;
strcpy( Conf_ServerName, "" );
snprintf( Conf_ServerInfo, sizeof Conf_ServerInfo, "%s %s", PACKAGE_NAME, PACKAGE_VERSION );
strcpy( Conf_ServerPwd, "" );
strcpy(Conf_ServerName, "");
snprintf(Conf_ServerInfo, sizeof Conf_ServerInfo, "%s %s",
PACKAGE_NAME, PACKAGE_VERSION);
strcpy(Conf_ServerPwd, "");
strcpy( Conf_ServerAdmin1, "" );
strcpy( Conf_ServerAdmin2, "" );
strcpy( Conf_ServerAdminMail, "" );
strcpy(Conf_ServerAdmin1, "");
strcpy(Conf_ServerAdmin2, "");
strcpy(Conf_ServerAdminMail, "");
strlcpy( Conf_MotdFile, SYSCONFDIR, sizeof( Conf_MotdFile ));
strlcat( Conf_MotdFile, MOTD_FILE, sizeof( Conf_MotdFile ));
strlcpy(Conf_MotdFile, SYSCONFDIR, sizeof(Conf_MotdFile));
strlcat(Conf_MotdFile, MOTD_FILE, sizeof(Conf_MotdFile));
strlcpy(Conf_MotdPhrase, MOTD_PHRASE, sizeof(Conf_MotdPhrase));
strlcpy( Conf_MotdPhrase, MOTD_PHRASE, sizeof( Conf_MotdPhrase ));
strlcpy( Conf_Chroot, CHROOT_DIR, sizeof( Conf_Chroot ));
strlcpy( Conf_PidFile, PID_FILE, sizeof( Conf_PidFile ));
Conf_UID = Conf_GID = 0;
strlcpy(Conf_Chroot, CHROOT_DIR, sizeof(Conf_Chroot));
strlcpy(Conf_PidFile, PID_FILE, sizeof(Conf_PidFile));
free(Conf_ListenAddress);
Conf_ListenAddress = NULL;
Conf_UID = Conf_GID = 0;
Conf_PingTimeout = 120;
Conf_PongTimeout = 20;
Conf_ConnectRetry = 60;
Conf_NoDNS = false;
Conf_NoIdent = false;
Conf_Oper_Count = 0;
Conf_Channel_Count = 0;
Conf_OperCanMode = false;
Conf_NoDNS = false;
Conf_NoIdent = false;
Conf_PredefChannelsOnly = false;
Conf_OperServerMode = false;
Conf_AllowRemoteOper = false;
Conf_PredefChannelsOnly = false;
Conf_ConnectIPv4 = true;
Conf_ConnectIPv6 = true;
@@ -538,10 +598,23 @@ Set_Defaults( bool InitServers )
Conf_MaxNickLength = CLIENT_NICK_LEN_DEFAULT;
/* Initialize server configuration structures */
if( InitServers ) for( i = 0; i < MAX_SERVERS; Init_Server_Struct( &Conf_Server[i++] ));
if (InitServers) {
for (i = 0; i < MAX_SERVERS;
Init_Server_Struct(&Conf_Server[i++]));
}
} /* Set_Defaults */
static bool
no_listenports(void)
{
size_t cnt = array_bytes(&Conf_ListenPorts);
#ifdef SSL_SUPPORT
cnt += array_bytes(&Conf_SSLOptions.ListenPorts);
#endif
return cnt == 0;
}
static bool
Read_Config( bool ngircd_starting )
{
@@ -564,6 +637,7 @@ Read_Config( bool ngircd_starting )
exit( 1 );
}
opers_free();
Set_Defaults( ngircd_starting );
Config_Error( LOG_INFO, "Reading configuration from \"%s\" ...", NGIRCd_ConfFile );
@@ -622,21 +696,6 @@ Read_Config( bool ngircd_starting )
if( strcasecmp( section, "[GLOBAL]" ) == 0 )
continue;
if( strcasecmp( section, "[OPERATOR]" ) == 0 ) {
if( Conf_Oper_Count + 1 > MAX_OPERATORS )
Config_Error( LOG_ERR, "Too many operators configured.");
else {
/* Initialize new operator structure */
Conf_Oper[Conf_Oper_Count].name[0] = '\0';
Conf_Oper[Conf_Oper_Count].pwd[0] = '\0';
if (Conf_Oper[Conf_Oper_Count].mask) {
free(Conf_Oper[Conf_Oper_Count].mask );
Conf_Oper[Conf_Oper_Count].mask = NULL;
}
Conf_Oper_Count++;
}
continue;
}
if( strcasecmp( section, "[SERVER]" ) == 0 ) {
/* Check if there is already a server to add */
if( New_Server.name[0] ) {
@@ -665,6 +724,10 @@ Read_Config( bool ngircd_starting )
Conf_Channel_Count++;
continue;
}
if (strcasecmp(section, "[OPERATOR]") == 0) {
Conf_Oper_Count++;
continue;
}
Config_Error( LOG_ERR, "%s, line %d: Unknown section \"%s\"!", NGIRCd_ConfFile, line, section );
section[0] = 0x1;
@@ -698,12 +761,14 @@ Read_Config( bool ngircd_starting )
Conf_Server[New_Server_Idx] = New_Server;
}
if (0 == array_length(&Conf_ListenPorts, sizeof(UINT16))) {
if (!array_copyb(&Conf_ListenPorts, (char*) &defaultport, sizeof defaultport)) {
Config_Error( LOG_ALERT, "Could not add default listening Port %u: %s",
(unsigned int) defaultport, strerror(errno));
exit( 1 );
}
/* not a single listening port? Add default. */
if (no_listenports() &&
!array_copyb(&Conf_ListenPorts, (char*) &defaultport, sizeof defaultport))
{
Config_Error(LOG_ALERT, "Could not add default listening Port %u: %s",
(unsigned int) defaultport, strerror(errno));
exit(1);
}
if (!Conf_ListenAddress)
@@ -781,6 +846,13 @@ Handle_GLOBAL( int Line, char *Var, char *Arg )
Config_Error_TooLong( Line, Var );
return;
}
if (strcasecmp(Var, "WebircPassword") == 0) {
/* Password required for WEBIRC command */
len = strlcpy(Conf_WebircPwd, Arg, sizeof(Conf_WebircPwd));
if (len >= sizeof(Conf_WebircPwd))
Config_Error_TooLong(Line, Var);
return;
}
if( strcasecmp( Var, "AdminInfo1" ) == 0 ) {
/* Administrative info #1 */
len = strlcpy( Conf_ServerAdmin1, Arg, sizeof( Conf_ServerAdmin1 ));
@@ -938,6 +1010,11 @@ Handle_GLOBAL( int Line, char *Var, char *Arg )
Conf_OperServerMode = Check_ArgIsTrue( Arg );
return;
}
if(strcasecmp(Var, "AllowRemoteOper") == 0) {
/* Are remote IRC operators allowed to control this server? */
Conf_AllowRemoteOper = Check_ArgIsTrue(Arg);
return;
}
if( strcasecmp( Var, "MaxConnections" ) == 0 ) {
/* Maximum number of connections. 0 -> "no limit". */
#ifdef HAVE_ISDIGIT
@@ -1029,36 +1106,38 @@ Handle_GLOBAL( int Line, char *Var, char *Arg )
static void
Handle_OPERATOR( int Line, char *Var, char *Arg )
{
unsigned int opercount;
size_t len;
struct Conf_Oper *op;
assert( Line > 0 );
assert( Var != NULL );
assert( Arg != NULL );
assert( Conf_Oper_Count > 0 );
if ( Conf_Oper_Count == 0 )
op = array_alloc(&Conf_Opers, sizeof(*op), Conf_Oper_Count - 1);
if (!op) {
Config_Error(LOG_ERR, "Could not allocate memory for operator (%d:%s = %s)", Line, Var, Arg);
return;
}
opercount = Conf_Oper_Count - 1;
if( strcasecmp( Var, "Name" ) == 0 ) {
if (strcasecmp(Var, "Name") == 0) {
/* Name of IRC operator */
len = strlcpy( Conf_Oper[opercount].name, Arg, sizeof( Conf_Oper[opercount].name ));
if (len >= sizeof( Conf_Oper[opercount].name ))
Config_Error_TooLong( Line, Var );
len = strlcpy(op->name, Arg, sizeof(op->name));
if (len >= sizeof(op->name))
Config_Error_TooLong(Line, Var);
return;
}
if( strcasecmp( Var, "Password" ) == 0 ) {
if (strcasecmp(Var, "Password") == 0) {
/* Password of IRC operator */
len = strlcpy( Conf_Oper[opercount].pwd, Arg, sizeof( Conf_Oper[opercount].pwd ));
if (len >= sizeof( Conf_Oper[opercount].pwd ))
Config_Error_TooLong( Line, Var );
len = strlcpy(op->pwd, Arg, sizeof(op->pwd));
if (len >= sizeof(op->pwd))
Config_Error_TooLong(Line, Var);
return;
}
if( strcasecmp( Var, "Mask" ) == 0 ) {
if (Conf_Oper[opercount].mask) return; /* Hostname already configured */
Conf_Oper[opercount].mask = strdup_warn( Arg );
if (strcasecmp(Var, "Mask") == 0) {
if (op->mask)
return; /* Hostname already configured */
op->mask = strdup_warn( Arg );
return;
}
Config_Error( LOG_ERR, "%s, line %d (section \"Operator\"): Unknown variable \"%s\"!",

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
* Copyright (c)2001-2010 Alexander Barton (alex@barton.de)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -26,12 +26,11 @@
#include "conf-ssl.h"
typedef struct _Conf_Oper
{
struct Conf_Oper {
char name[CLIENT_PASS_LEN]; /* Name (ID) of IRC operator */
char pwd[CLIENT_PASS_LEN]; /* Password */
char *mask;
} CONF_OPER;
char *mask; /* allowed host mask */
};
typedef struct _Conf_Server
{
@@ -125,8 +124,7 @@ GLOBAL int Conf_PongTimeout;
GLOBAL int Conf_ConnectRetry;
/* Operators */
GLOBAL CONF_OPER Conf_Oper[MAX_OPERATORS];
GLOBAL unsigned int Conf_Oper_Count;
GLOBAL array Conf_Opers;
/* Servers */
GLOBAL CONF_SERVER Conf_Server[MAX_SERVERS];
@@ -140,6 +138,14 @@ GLOBAL bool Conf_PredefChannelsOnly;
/* Are IRC operators allowed to always use MODE? */
GLOBAL bool Conf_OperCanMode;
/* If an IRC op gives chanop privileges without being a chanop,
* ircd2 will ignore the command. This enables a workaround:
* It masks the command as coming from the server */
GLOBAL bool Conf_OperServerMode;
/* Are remote IRC operators allowed to manage this server? */
GLOBAL bool Conf_AllowRemoteOper;
/* Disable all DNS functions? */
GLOBAL bool Conf_NoDNS;
@@ -155,11 +161,6 @@ GLOBAL bool Conf_ConnectIPv6;
/* same as above, but for ipv4 hosts, default: yes */
GLOBAL bool Conf_ConnectIPv4;
/* If an IRC op gives chanop privileges without being a chanop,
* ircd2 will ignore the command. This enables a workaround:
* It masks the command as coming from the server */
GLOBAL bool Conf_OperServerMode;
/* Maximum number of connections to this server */
GLOBAL long Conf_MaxConnections;
@@ -187,6 +188,9 @@ GLOBAL bool Conf_AddServer PARAMS(( const char *Name, UINT16 Port, const char *H
GLOBAL bool Conf_IsService PARAMS((int ConfServer, const char *Nick));
/* Password required by WEBIRC command */
GLOBAL char Conf_WebircPwd[CLIENT_PASS_LEN];
#endif

View File

@@ -383,7 +383,6 @@ ConnSSL_Init_SSL(CONNECTION *c)
int ret;
assert(c != NULL);
#ifdef HAVE_LIBSSL
assert(ssl_ctx);
if (!ssl_ctx) /* NULL when library initialization failed */
return false;
@@ -407,6 +406,7 @@ ConnSSL_Init_SSL(CONNECTION *c)
if (ret < 0) {
Log(LOG_ERR, "gnutls_set_default_priority: %s", gnutls_strerror(ret));
ConnSSL_Free(c);
return false;
}
/*
* The intermediate (long) cast is here to avoid a warning like:
@@ -419,6 +419,7 @@ ConnSSL_Init_SSL(CONNECTION *c)
if (ret < 0) {
Log(LOG_ERR, "gnutls_credentials_set: %s", gnutls_strerror(ret));
ConnSSL_Free(c);
return false;
}
gnutls_dh_set_prime_bits(c->ssl_state.gnutls_session, DH_BITS);
#endif
@@ -433,10 +434,7 @@ ConnSSL_PrepareConnect(CONNECTION *c, UNUSED CONF_SERVER *s)
bool ret;
#ifdef HAVE_LIBGNUTLS
int err;
#endif
assert(c != NULL);
assert(s != NULL);
#ifdef HAVE_LIBGNUTLS
err = gnutls_init(&c->ssl_state.gnutls_session, GNUTLS_CLIENT);
if (err) {
Log(LOG_ERR, "gnutls_init: %s", gnutls_strerror(err));
@@ -471,8 +469,6 @@ ConnSSL_HandleError( CONNECTION *c, const int code, const char *fname )
unsigned long sslerr;
int real_errno = errno;
assert( fname );
ret = SSL_get_error(c->ssl_state.ssl, code);
switch (ret) {
case SSL_ERROR_WANT_READ:
@@ -518,15 +514,14 @@ ConnSSL_HandleError( CONNECTION *c, const int code, const char *fname )
switch (code) {
case GNUTLS_E_AGAIN:
case GNUTLS_E_INTERRUPTED:
if (gnutls_record_get_direction(c->ssl_state.gnutls_session)) { /* need write */
io_event_del(c->sock, IO_WANTREAD);
Conn_OPTION_ADD(c, CONN_SSL_WANT_WRITE); /* fall through */
if (gnutls_record_get_direction(c->ssl_state.gnutls_session)) {
Conn_OPTION_ADD(c, CONN_SSL_WANT_WRITE);
io_event_del(c->sock, IO_WANTREAD);
} else {
Conn_OPTION_ADD(c, CONN_SSL_WANT_READ);
io_event_del(c->sock, IO_WANTWRITE);
}
break;
} else { /* need read */
io_event_del(c->sock, IO_WANTWRITE);
Conn_OPTION_ADD(c, CONN_SSL_WANT_READ);
break;
}
default:
assert(code < 0);
if (gnutls_error_is_fatal(code)) {
@@ -546,8 +541,7 @@ ConnSSL_LogCertInfo( CONNECTION *c )
#ifdef HAVE_LIBSSL
SSL *ssl = c->ssl_state.ssl;
assert( c );
assert( ssl );
assert(ssl);
Log(LOG_INFO, "New %s connection using cipher %s on socket %d.",
SSL_get_version(ssl), SSL_get_cipher(ssl), c->sock);
@@ -575,11 +569,8 @@ int
ConnSSL_Accept( CONNECTION *c )
{
assert(c != NULL);
#ifdef HAVE_LIBSSL
if (!c->ssl_state.ssl) {
#endif
#ifdef HAVE_LIBGNUTLS
if (!Conn_OPTION_ISSET(c, CONN_SSL)) {
#ifdef HAVE_LIBGNUTLS
int err = gnutls_init(&c->ssl_state.gnutls_session, GNUTLS_SERVER);
if (err) {
Log(LOG_ERR, "gnutls_init: %s", gnutls_strerror(err));
@@ -601,9 +592,7 @@ ConnSSL_Connect( CONNECTION *c )
#ifdef HAVE_LIBSSL
assert(c->ssl_state.ssl);
#endif
#ifdef HAVE_LIBGNUTLS
assert(Conn_OPTION_ISSET(c, CONN_SSL));
#endif
return ConnectAccept(c, true);
}
@@ -623,7 +612,6 @@ ConnectAccept( CONNECTION *c, bool connect)
#endif
#ifdef HAVE_LIBGNUTLS
(void) connect;
assert(Conn_OPTION_ISSET(c, CONN_SSL));
ret = gnutls_handshake(c->ssl_state.gnutls_session);
if (ret)
return ConnSSL_HandleError(c, ret, "gnutls_handshake");
@@ -648,7 +636,8 @@ ConnSSL_Write(CONNECTION *c, const void *buf, size_t count)
#ifdef HAVE_LIBGNUTLS
bw = gnutls_write(c->ssl_state.gnutls_session, buf, count);
#endif
if ( bw > 0 ) return bw;
if (bw > 0)
return bw;
if (ConnSSL_HandleError( c, bw, "ConnSSL_Write") == 0)
errno = EAGAIN; /* try again */
return -1;
@@ -685,11 +674,8 @@ ConnSSL_GetCipherInfo(CONNECTION *c, char *buf, size_t len)
{
#ifdef HAVE_LIBSSL
char *nl;
SSL *ssl = c->ssl_state.ssl;
SSL *ssl;
assert(c != NULL);
assert(len >= 128);
ssl = c->ssl_state.ssl;
if (!ssl)
return false;
*buf = 0;
@@ -700,8 +686,6 @@ ConnSSL_GetCipherInfo(CONNECTION *c, char *buf, size_t len)
return true;
#endif
#ifdef HAVE_LIBGNUTLS
assert(c != NULL);
assert(len >= 128);
if (Conn_OPTION_ISSET(c, CONN_SSL)) {
const char *name_cipher, *name_mac, *name_proto, *name_keyexchange;
unsigned keysize;

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2007 Alexander Barton (alex@barton.de)
* Copyright (c)2001-2010 Alexander Barton <alex@barton.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -37,6 +37,9 @@
#include <netinet/in.h>
#ifdef HAVE_NETINET_IP_H
# ifdef HAVE_NETINET_IN_SYSTM_H
# include <netinet/in_systm.h>
# endif
# include <netinet/ip.h>
#endif
@@ -75,13 +78,16 @@
#define SERVER_WAIT (NONE - 1)
#define MAX_COMMANDS 3
#define MAX_COMMANDS_SERVER 10
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 CONN_ID Socket2Index PARAMS(( int Sock ));
static void Read_Request PARAMS(( CONN_ID Idx ));
static void Handle_Buffer PARAMS(( CONN_ID Idx ));
static unsigned int Handle_Buffer PARAMS(( CONN_ID Idx ));
static void Check_Connections PARAMS(( void ));
static void Check_Servers PARAMS(( void ));
static void Init_Conn_Struct PARAMS(( CONN_ID Idx ));
@@ -89,10 +95,12 @@ static bool Init_Socket PARAMS(( int Sock ));
static void New_Server PARAMS(( int Server, ng_ipaddr_t *dest ));
static void Simple_Message PARAMS(( int Sock, const char *Msg ));
static int NewListener PARAMS(( const char *listen_addr, UINT16 Port ));
static void Account_Connection PARAMS((void));
static array My_Listeners;
static array My_ConnArray;
static size_t NumConnections;
static size_t NumConnections, NumConnectionsMax, NumConnectionsAccepted;
#ifdef TCPWRAP
int allow_severity = LOG_INFO;
@@ -106,55 +114,81 @@ extern struct SSLOptions Conf_SSLOptions;
static void cb_connserver_login_ssl PARAMS((int sock, short what));
static void cb_clientserver_ssl PARAMS((int sock, short what));
#endif
static void cb_Read_Resolver_Result PARAMS(( int sock, UNUSED short what));
static void cb_Connect_to_Server PARAMS(( int sock, UNUSED short what));
static void cb_Read_Resolver_Result PARAMS((int sock, UNUSED short what));
static void cb_Connect_to_Server PARAMS((int sock, UNUSED short what));
static void cb_clientserver PARAMS((int sock, short what));
/**
* IO callback for listening sockets: handle new connections. This callback
* gets called when a new non-SSL connection should be accepted.
* @param sock Socket descriptor
* @param irrelevant (ignored IO specification)
*/
static void
cb_listen(int sock, short irrelevant)
{
(void) irrelevant;
if (New_Connection( sock ) >= 0)
NumConnections++;
LogDebug("Total number of connections now %ld.", NumConnections);
(void) New_Connection(sock);
}
#ifdef SSL_SUPPORT
/**
* IO callback for listening SSL sockets: handle new connections. This callback
* gets called when a new SSL-enabled connection should be accepted.
* @param sock Socket descriptor
* @param irrelevant (ignored IO specification)
*/
static void
cb_listen_ssl(int sock, short irrelevant)
{
int fd;
(void) irrelevant;
fd = New_Connection(sock);
if (fd < 0)
return;
NumConnections++;
LogDebug("Total number of connections now %ld.", NumConnections);
io_event_setcb(My_Connections[fd].sock, cb_clientserver_ssl);
}
#endif
/**
* IO callback for new outgoing non-SSL server connections.
* @param sock Socket descriptor
* @param what IO specification (IO_WANTREAD/IO_WANTWRITE/...)
*/
static void
cb_connserver(int sock, UNUSED short what)
{
int res, err;
int res, err, server;
socklen_t sock_len;
CONN_ID idx = Socket2Index( sock );
if (idx <= NONE) {
LogDebug("cb_connserver wants to write on unknown socket?!");
io_close(sock);
return;
}
assert( what & IO_WANTWRITE);
assert(what & IO_WANTWRITE);
/* Make sure that the server is still configured; it could have been
* removed in the meantime! */
server = Conf_GetServer(idx);
if (server < 0) {
Log(LOG_ERR, "Connection on socket %d to \"%s\" aborted!",
sock, My_Connections[idx].host);
Conn_Close(idx, "Connection aborted!", NULL, false);
return;
}
/* connect() finished, get result. */
sock_len = sizeof( err );
res = getsockopt( My_Connections[idx].sock, SOL_SOCKET, SO_ERROR, &err, &sock_len );
assert( sock_len == sizeof( err ));
sock_len = (socklen_t)sizeof(err);
res = getsockopt(My_Connections[idx].sock, SOL_SOCKET, SO_ERROR,
&err, &sock_len );
assert(sock_len == sizeof(err));
/* Error while connecting? */
if ((res != 0) || (err != 0)) {
@@ -164,32 +198,28 @@ cb_connserver(int sock, UNUSED short what)
else
Log(LOG_CRIT,
"Can't connect socket to \"%s:%d\" (connection %d): %s!",
My_Connections[idx].host,
Conf_Server[Conf_GetServer(idx)].port,
My_Connections[idx].host, Conf_Server[server].port,
idx, strerror(err));
res = Conf_GetServer(idx);
assert(res >= 0);
Conn_Close(idx, "Can't connect!", NULL, false);
if (res < 0)
return;
if (ng_ipaddr_af(&Conf_Server[res].dst_addr[0])) {
if (ng_ipaddr_af(&Conf_Server[server].dst_addr[0])) {
/* more addresses to try... */
New_Server(res, &Conf_Server[res].dst_addr[0]);
/* connection to dst_addr[0] in progress, remove this address... */
Conf_Server[res].dst_addr[0] = Conf_Server[res].dst_addr[1];
memset(&Conf_Server[res].dst_addr[1], 0, sizeof(&Conf_Server[res].dst_addr[1]));
New_Server(res, &Conf_Server[server].dst_addr[0]);
/* connection to dst_addr[0] is now in progress, so
* remove this address... */
Conf_Server[server].dst_addr[0] =
Conf_Server[server].dst_addr[1];
memset(&Conf_Server[server].dst_addr[1], 0,
sizeof(Conf_Server[server].dst_addr[1]));
}
return;
}
res = Conf_GetServer(idx);
assert(res >= 0);
if (res >= 0) /* connect succeeded, remove all additional addresses */
memset(&Conf_Server[res].dst_addr, 0, sizeof(&Conf_Server[res].dst_addr));
/* connect() succeeded, remove all additional addresses */
memset(&Conf_Server[server].dst_addr, 0,
sizeof(Conf_Server[server].dst_addr));
Conn_OPTION_DEL( &My_Connections[idx], CONN_ISCONNECTING );
#ifdef SSL_SUPPORT
if ( Conn_OPTION_ISSET( &My_Connections[idx], CONN_SSL_CONNECT )) {
@@ -202,6 +232,10 @@ cb_connserver(int sock, UNUSED short what)
}
/**
* Login to a remote server.
* @param idx Connection index
*/
static void
server_login(CONN_ID idx)
{
@@ -218,6 +252,11 @@ server_login(CONN_ID idx)
#ifdef SSL_SUPPORT
/**
* IO callback for new outgoing SSL-enabled server connections.
* @param sock Socket descriptor
* @param what IO specification (IO_WANTREAD/IO_WANTWRITE/...)
*/
static void
cb_connserver_login_ssl(int sock, short unused)
{
@@ -247,6 +286,11 @@ cb_connserver_login_ssl(int sock, short unused)
#endif
/**
* IO callback for established non-SSL client and server connections.
* @param sock Socket descriptor
* @param what IO specification (IO_WANTREAD/IO_WANTWRITE/...)
*/
static void
cb_clientserver(int sock, short what)
{
@@ -259,18 +303,27 @@ cb_clientserver(int sock, short what)
return;
}
#ifdef SSL_SUPPORT
if (what & IO_WANTREAD || (Conn_OPTION_ISSET(&My_Connections[idx], CONN_SSL_WANT_WRITE)))
Read_Request( idx ); /* if TLS layer needs to write additional data, call Read_Request instead so SSL/TLS can continue */
if (what & IO_WANTREAD
|| (Conn_OPTION_ISSET(&My_Connections[idx], CONN_SSL_WANT_WRITE))) {
/* if TLS layer needs to write additional data, call
* Read_Request() instead so that SSL/TLS can continue */
Read_Request(idx);
}
#else
if (what & IO_WANTREAD)
Read_Request( idx );
Read_Request(idx);
#endif
if (what & IO_WANTWRITE)
Handle_Write( idx );
Handle_Write(idx);
}
#ifdef SSL_SUPPORT
/**
* IO callback for established SSL-enabled client and server connections.
* @param sock Socket descriptor
* @param what IO specification (IO_WANTREAD/IO_WANTWRITE/...)
*/
static void
cb_clientserver_ssl(int sock, short what)
{
@@ -284,11 +337,13 @@ cb_clientserver_ssl(int sock, short what)
}
switch (ConnSSL_Accept(&My_Connections[idx])) {
case 1: break; /* OK */
case 0: return; /* EAGAIN: this callback will be invoked again by the io layer */
default:
Conn_Close( idx, "Socket closed!", "SSL accept error", false );
return;
case 1:
break; /* OK */
case 0:
return; /* EAGAIN: callback will be invoked again by IO layer */
default:
Conn_Close(idx, "Socket closed!", "SSL accept error", false);
return;
}
if (what & IO_WANTREAD)
Read_Request(idx);
@@ -301,6 +356,9 @@ cb_clientserver_ssl(int sock, short what)
#endif
/**
* Initialite connecion module.
*/
GLOBAL void
Conn_Init( void )
{
@@ -313,8 +371,8 @@ Conn_Init( void )
Pool_Size = Conf_MaxConnections;
if (!array_alloc(&My_ConnArray, sizeof(CONNECTION), (size_t)Pool_Size)) {
Log( LOG_EMERG, "Can't allocate memory! [Conn_Init]" );
exit( 1 );
Log(LOG_EMERG, "Can't allocate memory! [Conn_Init]");
exit(1);
}
/* FIXME: My_Connetions/Pool_Size is needed by other parts of the
@@ -322,20 +380,21 @@ Conn_Init( void )
My_Connections = (CONNECTION*) array_start(&My_ConnArray);
LogDebug("Allocated connection pool for %d items (%ld bytes).",
array_length(&My_ConnArray, sizeof( CONNECTION )), array_bytes(&My_ConnArray));
array_length(&My_ConnArray, sizeof(CONNECTION)),
array_bytes(&My_ConnArray));
assert( array_length(&My_ConnArray, sizeof( CONNECTION )) >= (size_t) Pool_Size);
assert(array_length(&My_ConnArray, sizeof(CONNECTION)) >= (size_t)Pool_Size);
array_free( &My_Listeners );
/* Connection-Struktur initialisieren */
for( i = 0; i < Pool_Size; i++ ) Init_Conn_Struct( i );
/* Global write counter */
WCounter = 0;
for (i = 0; i < Pool_Size; i++)
Init_Conn_Struct(i);
} /* Conn_Init */
/**
* Clean up connection module.
*/
GLOBAL void
Conn_Exit( void )
{
@@ -388,6 +447,10 @@ ports_initlisteners(array *a, const char *listen_addr, void (*func)(int,short))
}
/**
* Initialize all listening sockets.
* @return Number of created listening sockets
*/
GLOBAL unsigned int
Conn_InitListeners( void )
{
@@ -422,13 +485,12 @@ Conn_InitListeners( void )
listen_addr = strtok(NULL, ",");
}
/*
* can't free() Conf_ListenAddress here. On /REHASH, if the config file
/* Can't free() Conf_ListenAddress here: on REHASH, if the config file
* cannot be re-loaded, we'd end up with a NULL Conf_ListenAddress.
* Instead, free() takes place in conf.c, before the config file
* is being parsed.
*/
* is being parsed. */
free(copy);
return created;
} /* Conn_InitListeners */
@@ -482,7 +544,7 @@ set_v6_only(int af, int sock)
if (af != AF_INET6)
return;
if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)))
if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &on, (socklen_t)sizeof(on)))
Log(LOG_ERR, "Could not set IPV6_V6ONLY: %s", strerror(errno));
#else
(void)af;
@@ -571,6 +633,7 @@ NewListener(const char *listen_addr, UINT16 Port)
return sock;
} /* NewListener */
#ifdef SSL_SUPPORT
/*
* SSL/TLS connections require extra treatment:
@@ -622,7 +685,7 @@ GLOBAL void
Conn_Handler(void)
{
int i;
unsigned int wdatalen;
unsigned int wdatalen, bytes_processed;
struct timeval tv;
time_t t;
@@ -645,9 +708,19 @@ Conn_Handler(void)
for (i = 0; i < Pool_Size; i++) {
if ((My_Connections[i].sock > NONE)
&& (array_bytes(&My_Connections[i].rbuf) > 0)
&& (My_Connections[i].delaytime < t)) {
&& (My_Connections[i].delaytime <= t)) {
/* ... and try to handle the received data */
Handle_Buffer(i);
bytes_processed = Handle_Buffer(i);
/* if we processed data, and there might be
* more commands in the input buffer, do not
* try to read any more data now */
if (bytes_processed &&
array_bytes(&My_Connections[i].rbuf) > 2) {
LogDebug
("Throttling connection %d: command limit reached!",
i);
Conn_SetPenalty(i, 1);
}
}
}
@@ -887,7 +960,6 @@ Conn_Close( CONN_ID Idx, const char *LogMsg, const char *FwdMsg, bool InformClie
* sub-processes are closed down. */
CLIENT *c;
const char *txt;
double in_k, out_k;
UINT16 port;
#ifdef ZLIB
@@ -910,13 +982,6 @@ Conn_Close( CONN_ID Idx, const char *LogMsg, const char *FwdMsg, bool InformClie
/* Mark link as "closing" */
Conn_OPTION_ADD( &My_Connections[Idx], CONN_ISCLOSING );
if (LogMsg)
txt = LogMsg;
else
txt = FwdMsg;
if (! txt)
txt = "Reason unknown";
port = ng_ipaddr_getport(&My_Connections[Idx].addr);
Log(LOG_INFO, "Shutting down connection %d (%s) with %s:%d ...", Idx,
LogMsg ? LogMsg : FwdMsg, My_Connections[Idx].host, port);
@@ -937,7 +1002,7 @@ Conn_Close( CONN_ID Idx, const char *LogMsg, const char *FwdMsg, bool InformClie
(double)My_Connections[Idx].bytes_out / 1024);
}
#endif
/* Send ERROR to client (see RFC!) */
/* Send ERROR to client (see RFC 2812, section 3.1.7) */
if (FwdMsg)
Conn_WriteStr(Idx, "ERROR :%s", FwdMsg);
else
@@ -1036,6 +1101,27 @@ Conn_Close( CONN_ID Idx, const char *LogMsg, const char *FwdMsg, bool InformClie
} /* Conn_Close */
GLOBAL long
Conn_Count(void)
{
return NumConnections;
} /* Conn_Count */
GLOBAL long
Conn_CountMax(void)
{
return NumConnectionsMax;
} /* Conn_CountMax */
GLOBAL long
Conn_CountAccepted(void)
{
return NumConnectionsAccepted;
} /* Conn_CountAccepted */
GLOBAL void
Conn_SyncServerStruct( void )
{
@@ -1150,12 +1236,14 @@ Count_Connections(ng_ipaddr_t *a)
} /* Count_Connections */
/**
* Initialize new client connection on a listening socket.
* @param Sock Listening socket descriptor
* @return Accepted socket descriptor or -1 on error
*/
static int
New_Connection( int Sock )
New_Connection(int Sock)
{
/* Neue Client-Verbindung von Listen-Socket annehmen und
* CLIENT-Struktur anlegen. */
#ifdef TCPWRAP
struct request_info req;
#endif
@@ -1165,16 +1253,16 @@ New_Connection( int Sock )
CLIENT *c;
long cnt;
assert( Sock > NONE );
/* Connection auf Listen-Socket annehmen */
new_sock_len = (int)sizeof(new_addr);
assert(Sock > NONE);
new_sock_len = (int)sizeof(new_addr);
new_sock = accept(Sock, (struct sockaddr *)&new_addr,
(socklen_t *)&new_sock_len);
if (new_sock < 0) {
Log(LOG_CRIT, "Can't accept connection: %s!", strerror(errno));
return -1;
}
NumConnectionsAccepted++;
if (!ng_ipaddr_tostr_r(&new_addr, ip_str)) {
Log(LOG_CRIT, "fd %d: Can't convert IP address!", new_sock);
@@ -1185,49 +1273,56 @@ New_Connection( int Sock )
#ifdef TCPWRAP
/* Validate socket using TCP Wrappers */
request_init( &req, RQ_DAEMON, PACKAGE_NAME, RQ_FILE, new_sock, RQ_CLIENT_SIN, &new_addr, NULL );
request_init(&req, RQ_DAEMON, PACKAGE_NAME, RQ_FILE, new_sock,
RQ_CLIENT_SIN, &new_addr, NULL);
fromhost(&req);
if (!hosts_access(&req)) {
Log (deny_severity, "Refused connection from %s (by TCP Wrappers)!", ip_str);
Simple_Message( new_sock, "ERROR :Connection refused" );
close( new_sock );
Log(deny_severity,
"Refused connection from %s (by TCP Wrappers)!", ip_str);
Simple_Message(new_sock, "ERROR :Connection refused");
close(new_sock);
return -1;
}
#endif
/* Socket initialisieren */
if (!Init_Socket( new_sock ))
if (!Init_Socket(new_sock))
return -1;
/* Check global connection limit */
if ((Conf_MaxConnections > 0) &&
(NumConnections >= (size_t) Conf_MaxConnections)) {
Log(LOG_ALERT, "Can't accept connection: limit (%d) reached!",
Conf_MaxConnections);
Simple_Message(new_sock, "ERROR :Connection limit reached");
close(new_sock);
return -1;
}
/* Check IP-based connection limit */
cnt = Count_Connections(&new_addr);
if ((Conf_MaxConnectionsIP > 0) && (cnt >= Conf_MaxConnectionsIP)) {
/* Access denied, too many connections from this IP address! */
Log( LOG_ERR, "Refused connection from %s: too may connections (%ld) from this IP address!", ip_str, cnt);
Simple_Message( new_sock, "ERROR :Connection refused, too many connections from your IP address!" );
close( new_sock );
Log(LOG_ERR,
"Refused connection from %s: too may connections (%ld) from this IP address!",
ip_str, cnt);
Simple_Message(new_sock,
"ERROR :Connection refused, too many connections from your IP address!");
close(new_sock);
return -1;
}
if ((Conf_MaxConnections > 0) &&
(NumConnections >= (size_t) Conf_MaxConnections))
{
Log( LOG_ALERT, "Can't accept connection: limit (%d) reached!", Conf_MaxConnections);
Simple_Message( new_sock, "ERROR :Connection limit reached" );
close( new_sock );
return -1;
}
if( new_sock >= Pool_Size ) {
if (new_sock >= Pool_Size) {
if (!array_alloc(&My_ConnArray, sizeof(CONNECTION),
(size_t)new_sock)) {
Log( LOG_EMERG, "Can't allocate memory! [New_Connection]" );
Simple_Message( new_sock, "ERROR: Internal error" );
close( new_sock );
(size_t) new_sock)) {
Log(LOG_EMERG,
"Can't allocate memory! [New_Connection]");
Simple_Message(new_sock, "ERROR: Internal error");
close(new_sock);
return -1;
}
LogDebug("Bumped connection pool to %ld items (internal: %ld items, %ld bytes)",
new_sock, array_length(&My_ConnArray, sizeof(CONNECTION)), array_bytes(&My_ConnArray));
new_sock, array_length(&My_ConnArray,
sizeof(CONNECTION)), array_bytes(&My_ConnArray));
/* Adjust pointer to new block */
My_Connections = array_start(&My_ConnArray);
@@ -1236,22 +1331,24 @@ New_Connection( int Sock )
}
/* register callback */
if (!io_event_create( new_sock, IO_WANTREAD, cb_clientserver)) {
Log(LOG_ALERT, "Can't accept connection: io_event_create failed!");
if (!io_event_create(new_sock, IO_WANTREAD, cb_clientserver)) {
Log(LOG_ALERT,
"Can't accept connection: io_event_create failed!");
Simple_Message(new_sock, "ERROR :Internal error");
close(new_sock);
return -1;
}
c = Client_NewLocal(new_sock, ip_str, CLIENT_UNKNOWN, false );
if( ! c ) {
Log(LOG_ALERT, "Can't accept connection: can't create client structure!");
c = Client_NewLocal(new_sock, ip_str, CLIENT_UNKNOWN, false);
if (!c) {
Log(LOG_ALERT,
"Can't accept connection: can't create client structure!");
Simple_Message(new_sock, "ERROR :Internal error");
io_close(new_sock);
return -1;
}
Init_Conn_Struct( new_sock );
Init_Conn_Struct(new_sock);
My_Connections[new_sock].sock = new_sock;
My_Connections[new_sock].addr = new_addr;
My_Connections[new_sock].client = c;
@@ -1279,11 +1376,28 @@ New_Connection( int Sock )
if (!Conf_NoDNS)
Resolve_Addr(&My_Connections[new_sock].res_stat, &new_addr,
identsock, cb_Read_Resolver_Result);
/* ngIRCd waits up to 4 seconds for the result of the asynchronous
* DNS and IDENT resolver subprocess using the "penalty" mechanism.
* If there are results earlier, the delay is aborted. */
Conn_SetPenalty(new_sock, 4);
Account_Connection();
return new_sock;
} /* New_Connection */
static void
Account_Connection(void)
{
NumConnections++;
if (NumConnections > NumConnectionsMax)
NumConnectionsMax = NumConnections;
LogDebug("Total number of connections now %lu (max %lu).",
NumConnections, NumConnectionsMax);
} /* Account_Connection */
static CONN_ID
Socket2Index( int Sock )
{
@@ -1307,7 +1421,9 @@ static void
Read_Request( CONN_ID Idx )
{
ssize_t len;
static const unsigned int maxbps = COMMAND_LEN / 2;
char readbuf[READBUFFER_LEN];
time_t t;
CLIENT *c;
assert( Idx > NONE );
assert( My_Connections[Idx].sock > NONE );
@@ -1384,21 +1500,34 @@ Read_Request( CONN_ID Idx )
if (c && (Client_Type(c) == CLIENT_USER
|| Client_Type(c) == CLIENT_SERVER
|| Client_Type(c) == CLIENT_SERVICE)) {
My_Connections[Idx].lastdata = time(NULL);
t = time(NULL);
if (My_Connections[Idx].lastdata != t)
My_Connections[Idx].bps = 0;
My_Connections[Idx].lastdata = t;
My_Connections[Idx].lastping = My_Connections[Idx].lastdata;
}
/* Look at the data in the (read-) buffer of this connection */
Handle_Buffer(Idx);
My_Connections[Idx].bps += Handle_Buffer(Idx);
if (Client_Type(c) != CLIENT_SERVER
&& My_Connections[Idx].bps >= maxbps) {
LogDebug("Throttling connection %d: BPS exceeded! (%u >= %u)",
Idx, My_Connections[Idx].bps, maxbps);
Conn_SetPenalty(Idx, 1);
}
} /* Read_Request */
/**
* Handle all data in the connection read-buffer.
* All data is precessed until no complete command is left. When a fatal
* error occurs, the connection is shut down.
* Data is processed until no complete command is left in the read buffer,
* or MAX_COMMANDS[_SERVER] commands were processed.
* When a fatal error occurs, the connection is shut down.
* @param Idx Index of the connection.
* @return number of bytes processed.
*/
static void
static unsigned int
Handle_Buffer(CONN_ID Idx)
{
#ifndef STRICT_RFC
@@ -1410,31 +1539,41 @@ Handle_Buffer(CONN_ID Idx)
#ifdef ZLIB
bool old_z;
#endif
unsigned int i, maxcmd = MAX_COMMANDS, len_processed = 0;
CLIENT *c;
c = Conn_GetClient(Idx);
assert( c != NULL);
/* Servers do get special command limits, so they can process
* all the messages that are required while peering. */
if (Client_Type(c) == CLIENT_SERVER)
maxcmd = MAX_COMMANDS_SERVER;
starttime = time(NULL);
for (;;) {
for (i=0; i < maxcmd; i++) {
/* Check penalty */
if (My_Connections[Idx].delaytime > starttime)
return;
return 0;
#ifdef ZLIB
/* Unpack compressed data, if compression is in use */
if (Conn_OPTION_ISSET(&My_Connections[Idx], CONN_ZIP)) {
/* When unzipping fails, Unzip_Buffer() shuts
* down the connection itself */
if (!Unzip_Buffer(Idx))
return;
return 0;
}
#endif
if (0 == array_bytes(&My_Connections[Idx].rbuf))
return;
break;
/* Make sure that the buffer is NULL terminated */
if (!array_cat0_temporary(&My_Connections[Idx].rbuf)) {
Conn_Close(Idx, NULL,
"Can't allocate memory [Handle_Buffer]",
true);
return;
return 0;
}
/* RFC 2812, section "2.3 Messages", 5th paragraph:
@@ -1470,7 +1609,7 @@ Handle_Buffer(CONN_ID Idx)
#endif
if (!ptr)
return;
break;
/* Complete (=line terminated) request found, handle it! */
*ptr = '\0';
@@ -1485,16 +1624,16 @@ Handle_Buffer(CONN_ID Idx)
Idx, array_bytes(&My_Connections[Idx].rbuf),
COMMAND_LEN - 1);
Conn_Close(Idx, NULL, "Request too long", true);
return;
return 0;
}
len_processed += (unsigned int)len;
if (len <= delta) {
/* Request is empty (only '\r\n', '\r' or '\n');
* delta is 2 ('\r\n') or 1 ('\r' or '\n'), see above */
array_moveleft(&My_Connections[Idx].rbuf, 1, len);
return;
continue;
}
#ifdef ZLIB
/* remember if stream is already compressed */
old_z = My_Connections[Idx].options & CONN_ZIP;
@@ -1503,7 +1642,7 @@ Handle_Buffer(CONN_ID Idx)
My_Connections[Idx].msg_in++;
if (!Parse_Request
(Idx, (char *)array_start(&My_Connections[Idx].rbuf)))
return;
return 0; /* error -> connection has been closed */
array_moveleft(&My_Connections[Idx].rbuf, 1, len);
LogDebug("Connection %d: %d bytes left in read buffer.",
@@ -1520,7 +1659,7 @@ Handle_Buffer(CONN_ID Idx)
Conn_Close(Idx, NULL,
"Can't allocate memory [Handle_Buffer]",
true);
return;
return 0;
}
array_trunc(&My_Connections[Idx].rbuf);
@@ -1530,6 +1669,7 @@ Handle_Buffer(CONN_ID Idx)
}
#endif
}
return len_processed;
} /* Handle_Buffer */
@@ -1696,6 +1836,8 @@ New_Server( int Server , ng_ipaddr_t *dest)
return;
}
/* Conn_Close() decrements this counter again */
Account_Connection();
Client_SetIntroducer( c, c );
Client_SetToken( c, TOKEN_OUTBOUND );
@@ -1722,9 +1864,9 @@ New_Server( int Server , ng_ipaddr_t *dest)
Conn_Close( new_sock, "Could not initialize SSL for outgoing connection", NULL, false );
Init_Conn_Struct( new_sock );
Conf_Server[Server].conn_id = NONE;
return;
}
#endif
NumConnections++;
LogDebug("Registered new connection %d on socket %d (%ld in total).",
new_sock, My_Connections[new_sock].sock, NumConnections);
Conn_OPTION_ADD( &My_Connections[new_sock], CONN_ISCONNECTING );
@@ -1770,12 +1912,13 @@ Init_Socket( int Sock )
}
/* Set type of service (TOS) */
#if defined(IP_TOS) && defined(IPTOS_LOWDELAY)
#if defined(IPPROTO_IP) && defined(IPTOS_LOWDELAY)
value = IPTOS_LOWDELAY;
LogDebug("Setting option IP_TOS on socket %d to IPTOS_LOWDELAY (%d).", Sock, value );
if( setsockopt( Sock, SOL_IP, IP_TOS, &value, (socklen_t)sizeof( value )) != 0 )
{
Log( LOG_ERR, "Can't set socket option IP_TOS: %s!", strerror( errno ));
LogDebug("Setting IP_TOS on socket %d to IPTOS_LOWDELAY.", Sock);
if (setsockopt(Sock, IPPROTO_IP, IP_TOS, &value,
(socklen_t) sizeof(value))) {
Log(LOG_ERR, "Can't set socket option IP_TOS: %s!",
strerror(errno));
/* ignore this error */
}
#endif
@@ -1784,7 +1927,6 @@ Init_Socket( int Sock )
} /* Init_Socket */
static void
cb_Connect_to_Server(int fd, UNUSED short events)
{
@@ -1793,7 +1935,8 @@ cb_Connect_to_Server(int fd, UNUSED short events)
size_t len;
ng_ipaddr_t dest_addrs[4]; /* we can handle at most 3; but we read up to
four so we can log the 'more than we can handle'
condition */
condition. First result is tried immediately, rest
is saved for later if needed. */
LogDebug("Resolver: Got forward lookup callback on fd %d, events %d", fd, events);
@@ -1818,13 +1961,13 @@ cb_Connect_to_Server(int fd, UNUSED short events)
LogDebug("Got result from resolver: %u structs (%u bytes).", len/sizeof(ng_ipaddr_t), len);
memset(&Conf_Server[i].dst_addr, 0, sizeof(&Conf_Server[i].dst_addr));
memset(&Conf_Server[i].dst_addr, 0, sizeof(Conf_Server[i].dst_addr));
if (len > sizeof(ng_ipaddr_t)) {
/* more than one address for this hostname, remember them
* in case first address is unreachable/not available */
len -= sizeof(ng_ipaddr_t);
if (len > sizeof(&Conf_Server[i].dst_addr)) {
len = sizeof(&Conf_Server[i].dst_addr);
if (len > sizeof(Conf_Server[i].dst_addr)) {
len = sizeof(Conf_Server[i].dst_addr);
Log(LOG_NOTICE,
"Notice: Resolver returned more IP Addresses for host than we can handle, additional addresses dropped.");
}
@@ -1891,10 +2034,14 @@ cb_Read_Resolver_Result( int r_fd, UNUSED short events )
c = Conn_GetClient( i );
assert( c != NULL );
/* Only update client information of unregistered clients */
if( Client_Type( c ) == CLIENT_UNKNOWN ) {
strlcpy(My_Connections[i].host, readbuf, sizeof( My_Connections[i].host));
Client_SetHostname( c, readbuf);
/* Only update client information of unregistered clients.
* Note: user commands (e. g. WEBIRC) are always read _after_ reading
* the resolver results, so we don't have to worry to override settings
* from these commands here. */
if(Client_Type(c) == CLIENT_UNKNOWN) {
strlcpy(My_Connections[i].host, readbuf,
sizeof(My_Connections[i].host));
Client_SetHostname(c, readbuf);
#ifdef IDENTAUTH
++identptr;
if (*identptr) {
@@ -1913,41 +2060,63 @@ cb_Read_Resolver_Result( int r_fd, UNUSED short events )
} /* cb_Read_Resolver_Result */
/**
* Write a "simple" (error) message to a socket.
* The message is sent without using the connection write buffers, without
* compression/encryption, and even without any error reporting. It is
* designed for error messages of e.g. New_Connection(). */
static void
Simple_Message( int Sock, const char *Msg )
Simple_Message(int Sock, const char *Msg)
{
char buf[COMMAND_LEN];
size_t len;
/* Write "simple" message to socket, without using compression
* or even the connection write buffers. Used e.g. for error
* messages by New_Connection(). */
assert( Sock > NONE );
assert( Msg != NULL );
strlcpy( buf, Msg, sizeof buf - 2);
len = strlcat( buf, "\r\n", sizeof buf);
(void)write(Sock, buf, len);
assert(Sock > NONE);
assert(Msg != NULL);
strlcpy(buf, Msg, sizeof buf - 2);
len = strlcat(buf, "\r\n", sizeof buf);
if (write(Sock, buf, len) < 0) {
/* Because this function most probably got called to log
* an error message, any write error is ignored here to
* avoid an endless loop. But casting the result of write()
* to "void" doesn't satisfy the GNU C code attribute
* "warn_unused_result" which is used by some versions of
* glibc (e.g. 2.11.1), therefore this silly error
* "handling" code here :-( */
return;
}
} /* Simple_Error */
/**
* Get CLIENT structure that belongs to a local connection identified by its
* index number. Each connection belongs to a client by definition, so it is
* not required that the caller checks for NULL return values.
* @param Idx Connection index number
* @return Pointer to CLIENT structure
*/
GLOBAL CLIENT *
Conn_GetClient( CONN_ID Idx )
{
/* return Client-Structure that belongs to the local Connection Idx.
* If none is found, return NULL.
*/
CONNECTION *c;
assert( Idx >= 0 );
assert(Idx >= 0);
c = array_get(&My_ConnArray, sizeof (CONNECTION), (size_t)Idx);
assert(c != NULL);
return c ? c->client : NULL;
}
#ifdef SSL_SUPPORT
/* we cannot access My_Connections in irc-info.c */
/**
* Get information about used SSL chiper.
* @param Idx Connection index number
* @param buf Buffer for returned information text
* @param len Size of return buffer "buf"
* @return true on success, false otherwise
*/
GLOBAL bool
Conn_GetCipherInfo(CONN_ID Idx, char *buf, size_t len)
{
@@ -1958,6 +2127,11 @@ Conn_GetCipherInfo(CONN_ID Idx, char *buf, size_t len)
}
/**
* Check if a connection is SSL-enabled or not.
* @param Idx Connection index number
* @return true if connection is SSL-enabled, false otherwise.
*/
GLOBAL bool
Conn_UsesSSL(CONN_ID Idx)
{
@@ -1966,5 +2140,8 @@ Conn_UsesSSL(CONN_ID Idx)
assert(Idx < (int) array_length(&My_ConnArray, sizeof(CONNECTION)));
return Conn_OPTION_ISSET(&My_Connections[Idx], CONN_SSL);
}
#endif
/* -eof- */

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2008 by Alexander Barton (alex@barton.de)
* Copyright (c)2001-2010 Alexander Barton <alex@barton.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -41,7 +41,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 int CONN_ID;
typedef long CONN_ID;
#include "client.h"
@@ -82,12 +82,13 @@ typedef struct _Connection
long msg_in, msg_out; /* Received and sent IRC messages */
int flag; /* Flag (see "irc-write" module) */
UINT16 options; /* Link options / connection state */
UINT16 bps; /* bytes processed within last second */
CLIENT *client; /* pointer to client structure */
#ifdef ZLIB
ZIPDATA zip; /* Compression information */
#endif /* ZLIB */
#ifdef SSL_SUPPORT
struct ConnSSL_State ssl_state; /* SSL/GNUTLS state information */
struct ConnSSL_State ssl_state; /* SSL/GNUTLS state information */
#endif
} CONNECTION;
@@ -121,4 +122,9 @@ static inline bool Conn_UsesSSL(UNUSED CONN_ID Idx) { return false; }
#endif
#endif
GLOBAL long Conn_Count PARAMS((void));
GLOBAL long Conn_CountMax PARAMS((void));
GLOBAL long Conn_CountAccepted PARAMS((void));
/* -eof- */

View File

@@ -1,14 +1,12 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2007 Alexander Barton (alex@barton.de)
* Copyright (c)2001-2010 Alexander Barton (alex@barton.de)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
* Please read the file COPYING, README and AUTHORS for more information.
*
* $Id: defines.h,v 1.62 2007/11/21 12:16:36 alex Exp $
*/
@@ -30,8 +28,6 @@
#define HOST_LEN 256 /* Max. lenght of fully qualified host
names (e. g. "abc.domain.tld") */
#define MAX_OPERATORS 16 /* Max. count of configurable IRC Ops */
#define MAX_SERVERS 16 /* Max. count of configurable servers */
#define MAX_WHOWAS 64 /* Max. number of WHOWAS items */
@@ -84,8 +80,8 @@
#define RECONNECT_DELAY 3 /* Time to delay re-connect attempts
in seconds. */
#define USERMODES "aios" /* Supported user modes. */
#define CHANMODES "biIklmnoPstv" /* Supported channel modes. */
#define USERMODES "aiorsw" /* Supported user modes. */
#define CHANMODES "biIklmnoPstvz" /* Supported channel modes. */
#define CONNECTED true /* Internal status codes. */
#define DISCONNECTED false

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
* Copyright (c)2001-2009 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,8 +37,9 @@ Hash( const char *String )
char buffer[LINE_LEN];
strlcpy( buffer, String, sizeof( buffer ));
return jenkins_hash( (UINT8 *)ngt_LowerStr( buffer ), strlen( buffer ), 42 );
strlcpy(buffer, String, sizeof(buffer));
return jenkins_hash((UINT8 *)ngt_LowerStr(buffer),
(UINT32)strlen(buffer), 42);
} /* Hash */

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
* Copyright (c)2001-2010 Alexander Barton (alex@barton.de)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -62,9 +62,18 @@ part_from_all_channels(CLIENT* client, CLIENT *target)
}
/**
* Check weather a local client is allowed to join an already existing
* channel or not.
* @param Client Client that sent the JOIN command
* @param chan Channel to check
* @param channame Name of the channel
* @param key Provided channel key (or NULL if none has been provided)
* @return true if client is allowed to join channel, false otherwise
*/
static bool
join_allowed(CLIENT *Client, CLIENT *target, CHANNEL *chan,
const char *channame, const char *key)
join_allowed(CLIENT *Client, CHANNEL *chan, const char *channame,
const char *key)
{
bool is_invited, is_banned;
const char *channel_modes;
@@ -73,32 +82,48 @@ join_allowed(CLIENT *Client, CLIENT *target, CHANNEL *chan,
if (strchr(Client_Modes(Client), 'o'))
return true;
is_banned = Lists_Check(Channel_GetListBans(chan), target);
is_invited = Lists_Check(Channel_GetListInvites(chan), target);
is_banned = Lists_Check(Channel_GetListBans(chan), Client);
is_invited = Lists_Check(Channel_GetListInvites(chan), Client);
if (is_banned && !is_invited) {
IRC_WriteStrClient(Client, ERR_BANNEDFROMCHAN_MSG, Client_ID(Client), channame);
/* Client is banned from channel (and not on invite list) */
IRC_WriteStrClient(Client, ERR_BANNEDFROMCHAN_MSG,
Client_ID(Client), channame);
return false;
}
channel_modes = Channel_Modes(chan);
if ((strchr(channel_modes, 'i')) && !is_invited) {
/* Channel is "invite-only" (and Client wasn't invited) */
IRC_WriteStrClient(Client, ERR_INVITEONLYCHAN_MSG, Client_ID(Client), channame);
if (strchr(channel_modes, 'i') && !is_invited) {
/* Channel is "invite-only" and client is not on invite list */
IRC_WriteStrClient(Client, ERR_INVITEONLYCHAN_MSG,
Client_ID(Client), channame);
return false;
}
/* Is the channel protected by a key? */
if (!Channel_CheckKey(chan, target, key ? key : "")) {
if (!Channel_CheckKey(chan, Client, key ? key : "")) {
/* Channel is protected by a channel key and the client
* didn't specify the correct one */
IRC_WriteStrClient(Client, ERR_BADCHANNELKEY_MSG,
Client_ID(Client), channame);
return false;
}
/* Are there already too many members? */
if ((strchr(channel_modes, 'l')) && (Channel_MaxUsers(chan) <= Channel_MemberCount(chan))) {
IRC_WriteStrClient(Client, ERR_CHANNELISFULL_MSG, Client_ID(Client), channame);
if (strchr(channel_modes, 'l') &&
(Channel_MaxUsers(chan) <= Channel_MemberCount(chan))) {
/* There are more clints joined to this channel than allowed */
IRC_WriteStrClient(Client, ERR_CHANNELISFULL_MSG,
Client_ID(Client), channame);
return false;
}
if (strchr(channel_modes, 'z') && !Conn_UsesSSL(Client_Conn(Client))) {
/* Only "secure" clients are allowed, but clients doesn't
* use SSL encryption */
IRC_WriteStrClient(Client, ERR_SECURECHANNEL_MSG,
Client_ID(Client), channame);
return false;
}
return true;
}
@@ -270,20 +295,23 @@ IRC_JOIN( CLIENT *Client, REQUEST *Req )
/* Local client? */
if (Client_Type(Client) == CLIENT_USER) {
/* Test if the user has reached his maximum channel count */
if ((Conf_MaxJoins > 0) && (Channel_CountForUser(Client) >= Conf_MaxJoins))
return IRC_WriteStrClient(Client, ERR_TOOMANYCHANNELS_MSG,
Client_ID(Client), channame);
if (!chan) {
/*
* New Channel: first user will be channel operator
* unless this is a modeless channel.
*/
/* Test if the user has reached the channel limit */
if ((Conf_MaxJoins > 0) &&
(Channel_CountForUser(Client) >= Conf_MaxJoins))
return IRC_WriteStrClient(Client,
ERR_TOOMANYCHANNELS_MSG,
Client_ID(Client), channame);
if (chan) {
/* Already existing channel: check if the
* client is allowed to join */
if (!join_allowed(Client, chan, channame, key))
break;
} else {
/* New channel: first user will become channel
* operator unless this is a modeless channel */
if (*channame != '+')
flags = "o";
} else
if (!join_allowed(Client, target, chan, channame, key))
break;
}
/* Local client: update idle time */
Conn_UpdateIdle(Client_Conn(Client));
@@ -293,7 +321,9 @@ IRC_JOIN( CLIENT *Client, REQUEST *Req )
* that the "one shot" entries (generated by INVITE
* commands) in this list become deleted when a user
* joins a channel this way. */
if (chan) (void)Lists_Check(Channel_GetListInvites(chan), target);
if (chan)
(void)Lists_Check(Channel_GetListInvites(chan),
target);
}
/* Join channel (and create channel if it doesn't exist) */

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
* Copyright (c)2001-2010 Alexander Barton <alex@barton.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -440,7 +440,7 @@ t_diff(time_t *t, const time_t d)
remain = diff * d;
*t -= remain;
return diff;
return (unsigned int)diff;
}
@@ -465,6 +465,10 @@ uptime_mins(time_t *now)
}
/**
* Handler for the IRC command "STATS".
* See RFC 2812 section 3.4.4.
*/
GLOBAL bool
IRC_STATS( CLIENT *Client, REQUEST *Req )
{
@@ -475,11 +479,12 @@ IRC_STATS( CLIENT *Client, REQUEST *Req )
time_t time_now;
unsigned int days, hrs, mins;
assert( Client != NULL );
assert( Req != NULL );
assert(Client != NULL);
assert(Req != NULL);
if (Req->argc > 2)
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, Client_ID(Client), Req->command);
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
/* use prefix to determine "From" */
if (Client_Type(Client) == CLIENT_SERVER)
@@ -487,18 +492,21 @@ IRC_STATS( CLIENT *Client, REQUEST *Req )
else
from = Client;
if (! from)
return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix);
if (!from)
return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG,
Client_ID(Client), Req->prefix);
if (Req->argc == 2) {
/* forward to another server? */
target = Client_Search( Req->argv[1] );
if(( ! target ) || ( Client_Type( target ) != CLIENT_SERVER ))
return IRC_WriteStrClient( from, ERR_NOSUCHSERVER_MSG, Client_ID( from ), Req->argv[1] );
target = Client_Search(Req->argv[1]);
if ((!target) || (Client_Type(target) != CLIENT_SERVER))
return IRC_WriteStrClient(from, ERR_NOSUCHSERVER_MSG,
Client_ID(from), Req->argv[1]);
if( target != Client_ThisServer()) {
if (target != Client_ThisServer()) {
/* forward to another server */
return IRC_WriteStrClientPrefix( target, from, "STATS %s %s", Req->argv[0], Req->argv[1] );
return IRC_WriteStrClientPrefix(target, from,
"STATS %s %s", Req->argv[0], Req->argv[1]);
}
}
@@ -508,57 +516,70 @@ IRC_STATS( CLIENT *Client, REQUEST *Req )
query = '*';
switch (query) {
case 'l': /* Links */
case 'L':
time_now = time(NULL);
for (con = Conn_First(); con != NONE ;con = Conn_Next(con)) {
cl = Conn_GetClient(con);
if (!cl)
continue;
if ((Client_Type(cl) == CLIENT_SERVER) || (cl == Client)) {
/* Server link or our own connection */
case 'l': /* Link status (servers and own link) */
case 'L':
time_now = time(NULL);
for (con = Conn_First(); con != NONE; con = Conn_Next(con)) {
cl = Conn_GetClient(con);
if (!cl)
continue;
if ((Client_Type(cl) == CLIENT_SERVER)
|| (cl == Client)) {
/* Server link or our own connection */
#ifdef ZLIB
if (Conn_Options(con) & CONN_ZIP) {
if (!IRC_WriteStrClient(from, RPL_STATSLINKINFOZIP_MSG,
Client_ID(from), Client_Mask(cl), Conn_SendQ(con),
Conn_SendMsg(con), Zip_SendBytes(con), Conn_SendBytes(con),
Conn_RecvMsg(con), Zip_RecvBytes(con), Conn_RecvBytes(con), (long)(time_now - Conn_StartTime(con))))
return DISCONNECTED;
continue;
}
#endif
if (!IRC_WriteStrClient(from, RPL_STATSLINKINFO_MSG, Client_ID(from),
Client_Mask(cl), Conn_SendQ(con), Conn_SendMsg(con), Conn_SendBytes(con),
Conn_RecvMsg(con), Conn_RecvBytes(con), (long)(time_now - Conn_StartTime(con))))
return DISCONNECTED;
}
}
break;
case 'm': /* IRC-Commands */
case 'M':
cmd = Parse_GetCommandStruct( );
for (; cmd->name ; cmd++) {
if (cmd->lcount == 0 && cmd->rcount == 0)
continue;
if (!IRC_WriteStrClient(from, RPL_STATSCOMMANDS_MSG, Client_ID(from),
cmd->name, cmd->lcount, cmd->bytes, cmd->rcount))
return DISCONNECTED;
}
break;
case 'u': /* server uptime */
case 'U':
time_now = time(NULL) - NGIRCd_Start;
days = uptime_days(&time_now);
hrs = uptime_hrs(&time_now);
mins = uptime_mins(&time_now);
if (!IRC_WriteStrClient(from, RPL_STATSUPTIME, Client_ID(from),
days, hrs, mins, (unsigned int) time_now))
if (Conn_Options(con) & CONN_ZIP) {
if (!IRC_WriteStrClient
(from, RPL_STATSLINKINFOZIP_MSG,
Client_ID(from), Client_Mask(cl),
Conn_SendQ(con), Conn_SendMsg(con),
Zip_SendBytes(con),
Conn_SendBytes(con),
Conn_RecvMsg(con),
Zip_RecvBytes(con),
Conn_RecvBytes(con),
(long)(time_now - Conn_StartTime(con))))
return DISCONNECTED;
break;
continue;
}
#endif
if (!IRC_WriteStrClient
(from, RPL_STATSLINKINFO_MSG,
Client_ID(from), Client_Mask(cl),
Conn_SendQ(con), Conn_SendMsg(con),
Conn_SendBytes(con), Conn_RecvMsg(con),
Conn_RecvBytes(con),
(long)(time_now - Conn_StartTime(con))))
return DISCONNECTED;
}
}
break;
case 'm': /* IRC command status (usage count) */
case 'M':
cmd = Parse_GetCommandStruct();
for (; cmd->name; cmd++) {
if (cmd->lcount == 0 && cmd->rcount == 0)
continue;
if (!IRC_WriteStrClient
(from, RPL_STATSCOMMANDS_MSG, Client_ID(from),
cmd->name, cmd->lcount, cmd->bytes, cmd->rcount))
return DISCONNECTED;
}
break;
case 'u': /* Server uptime */
case 'U':
time_now = time(NULL) - NGIRCd_Start;
days = uptime_days(&time_now);
hrs = uptime_hrs(&time_now);
mins = uptime_mins(&time_now);
if (!IRC_WriteStrClient(from, RPL_STATSUPTIME, Client_ID(from),
days, hrs, mins, (unsigned int)time_now))
return DISCONNECTED;
break;
}
IRC_SetPenalty(from, 2);
return IRC_WriteStrClient(from, RPL_ENDOFSTATS_MSG, Client_ID(from), query);
return IRC_WriteStrClient(from, RPL_ENDOFSTATS_MSG,
Client_ID(from), query);
} /* IRC_STATS */
@@ -1155,6 +1176,10 @@ IRC_Send_LUSERS( CLIENT *Client )
if(! IRC_WriteStrClient(Client, RPL_NETUSERS_MSG, Client_ID(Client),
cnt, max, cnt, max))
return DISCONNECTED;
/* Connection counters */
if (! IRC_WriteStrClient(Client, RPL_STATSCONN_MSG, Client_ID(Client),
Conn_CountMax(), Conn_CountAccepted()))
return DISCONNECTED;
#endif
return CONNECTED;

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
* Copyright (c)2001-2010 Alexander Barton (alex@barton.de)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -148,7 +148,6 @@ IRC_PASS( CLIENT *Client, REQUEST *Req )
} else {
/* The peer seems to be a server supporting the
* "original" IRC protocol (RFC 2813). */
serverver = "";
if (strchr(orig_flags, 'Z'))
flags = "Z";
else
@@ -558,6 +557,31 @@ IRC_SERVICE(CLIENT *Client, REQUEST *Req)
} /* IRC_SERVICE */
/**
* Handler for the IRC command "WEBIRC".
* Syntax: WEBIRC <password> <username> <real-hostname> <real-IP-address>
*/
GLOBAL bool
IRC_WEBIRC(CLIENT *Client, REQUEST *Req)
{
/* Exactly 4 parameters are requited */
if (Req->argc != 4)
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
if (!Conf_WebircPwd[0] || strcmp(Req->argv[0], Conf_WebircPwd) != 0)
return IRC_WriteStrClient(Client, ERR_PASSWDMISMATCH_MSG,
Client_ID(Client));
LogDebug("Connection %d: got valid WEBIRC command: user=%s, host=%s, ip=%s",
Client_Conn(Client), Req->argv[1], Req->argv[2], Req->argv[3]);
Client_SetUser(Client, Req->argv[1], true);
Client_SetHostname(Client, Req->argv[2]);
return CONNECTED;
} /* IRC_WEBIRC */
GLOBAL bool
IRC_QUIT( CLIENT *Client, REQUEST *Req )
{

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
* Copyright (c)2001-2010 Alexander Barton (alex@barton.de)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -19,6 +19,7 @@ GLOBAL bool IRC_PASS PARAMS((CLIENT *Client, REQUEST *Req));
GLOBAL bool IRC_NICK PARAMS((CLIENT *Client, REQUEST *Req));
GLOBAL bool IRC_USER PARAMS((CLIENT *Client, REQUEST *Req));
GLOBAL bool IRC_SERVICE PARAMS((CLIENT *Client, REQUEST *Req));
GLOBAL bool IRC_WEBIRC PARAMS((CLIENT *Client, REQUEST *Req));
GLOBAL bool IRC_PING PARAMS((CLIENT *Client, REQUEST *Req));
GLOBAL bool IRC_PONG PARAMS((CLIENT *Client, REQUEST *Req));
GLOBAL bool IRC_QUIT PARAMS((CLIENT *Client, REQUEST *Req));

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
* Copyright (c)2001-2010 Alexander Barton (alex@barton.de)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -284,7 +284,7 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
{
char the_modes[COMMAND_LEN], the_args[COMMAND_LEN], x[2],
argadd[CLIENT_PASS_LEN], *mode_ptr;
bool ok, set, modeok = true, skiponce, use_servermode = false, retval;
bool connected, set, modeok = true, skiponce, use_servermode = false, retval;
int mode_arg, arg_arg;
CLIENT *client;
long l;
@@ -344,7 +344,7 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
the_args[0] = '\0';
x[1] = '\0';
ok = CONNECTED;
connected = CONNECTED;
while (mode_ptr) {
if (!skiponce)
mode_ptr++;
@@ -401,10 +401,11 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
case 'n': /* Only members can write */
case 's': /* Secret channel */
case 't': /* Topic locked */
case 'z': /* Secure connections only */
if (modeok)
x[0] = *mode_ptr;
else
ok = IRC_WriteStrClient(Origin,
connected = IRC_WriteStrClient(Origin,
ERR_CHANOPRIVSNEEDED_MSG,
Client_ID(Origin), Channel_Name(Channel));
break;
@@ -413,7 +414,7 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
if (modeok)
x[0] = *mode_ptr;
else
ok = IRC_WriteStrClient(Origin,
connected = IRC_WriteStrClient(Origin,
ERR_CHANOPRIVSNEEDED_MSG,
Client_ID(Origin),
Channel_Name(Channel));
@@ -428,7 +429,7 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
sizeof(argadd));
x[0] = *mode_ptr;
} else {
ok = IRC_WriteStrClient(Origin,
connected = IRC_WriteStrClient(Origin,
ERR_CHANOPRIVSNEEDED_MSG,
Client_ID(Origin),
Channel_Name(Channel));
@@ -436,7 +437,7 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
Req->argv[arg_arg][0] = '\0';
arg_arg++;
} else {
ok = IRC_WriteStrClient(Origin,
connected = IRC_WriteStrClient(Origin,
ERR_NEEDMOREPARAMS_MSG,
Client_ID(Origin), Req->command);
goto chan_exit;
@@ -447,7 +448,7 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
if (modeok)
x[0] = *mode_ptr;
else
ok = IRC_WriteStrClient(Origin,
connected = IRC_WriteStrClient(Origin,
ERR_CHANOPRIVSNEEDED_MSG,
Client_ID(Origin),
Channel_Name(Channel));
@@ -464,7 +465,7 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
x[0] = *mode_ptr;
}
} else {
ok = IRC_WriteStrClient(Origin,
connected = IRC_WriteStrClient(Origin,
ERR_CHANOPRIVSNEEDED_MSG,
Client_ID(Origin),
Channel_Name(Channel));
@@ -472,7 +473,7 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
Req->argv[arg_arg][0] = '\0';
arg_arg++;
} else {
ok = IRC_WriteStrClient(Origin,
connected = IRC_WriteStrClient(Origin,
ERR_NEEDMOREPARAMS_MSG,
Client_ID(Origin), Req->command);
goto chan_exit;
@@ -484,13 +485,13 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
* set the 'P' channel mode! */
if (set && !(Client_OperByMe(Client)
|| Client_Type(Client) == CLIENT_SERVER))
ok = IRC_WriteStrClient(Origin,
connected = IRC_WriteStrClient(Origin,
ERR_NOPRIVILEGES_MSG,
Client_ID(Origin));
else
x[0] = 'P';
} else
ok = IRC_WriteStrClient(Origin,
connected = IRC_WriteStrClient(Origin,
ERR_CHANOPRIVSNEEDED_MSG,
Client_ID(Origin),
Channel_Name(Channel));
@@ -504,12 +505,12 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
if (client)
x[0] = *mode_ptr;
else
ok = IRC_WriteStrClient(Client,
connected = IRC_WriteStrClient(Client,
ERR_NOSUCHNICK_MSG,
Client_ID(Client),
Req->argv[arg_arg]);
} else {
ok = IRC_WriteStrClient(Origin,
connected = IRC_WriteStrClient(Origin,
ERR_CHANOPRIVSNEEDED_MSG,
Client_ID(Origin),
Channel_Name(Channel));
@@ -517,7 +518,7 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
Req->argv[arg_arg][0] = '\0';
arg_arg++;
} else {
ok = IRC_WriteStrClient(Origin,
connected = IRC_WriteStrClient(Origin,
ERR_NEEDMOREPARAMS_MSG,
Client_ID(Origin), Req->command);
goto chan_exit;
@@ -529,7 +530,7 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
if (arg_arg > mode_arg) {
/* modify list */
if (modeok) {
ok = set
connected = set
? Add_Ban_Invite(*mode_ptr, Origin,
Client, Channel,
Req->argv[arg_arg])
@@ -537,7 +538,7 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
Client, Channel,
Req->argv[arg_arg]);
} else {
ok = IRC_WriteStrClient(Origin,
connected = IRC_WriteStrClient(Origin,
ERR_CHANOPRIVSNEEDED_MSG,
Client_ID(Origin),
Channel_Name(Channel));
@@ -557,7 +558,7 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
set ? '+' : '-', *mode_ptr, Client_ID(Origin),
Channel_Name(Channel));
if (Client_Type(Client) != CLIENT_SERVER)
ok = IRC_WriteStrClient(Origin,
connected = IRC_WriteStrClient(Origin,
ERR_UMODEUNKNOWNFLAG2_MSG,
Client_ID(Origin),
set ? '+' : '-', *mode_ptr);
@@ -565,7 +566,7 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
goto chan_exit;
} /* switch() */
if (!ok)
if (!connected)
break;
/* Is there a valid mode change? */
@@ -646,7 +647,7 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
if (use_servermode)
Origin = Client_ThisServer();
/* Send reply to client and inform other servers and channel users */
ok = IRC_WriteStrClientPrefix(Client, Origin,
connected = IRC_WriteStrClientPrefix(Client, Origin,
"MODE %s %s%s", Channel_Name(Channel),
the_modes, the_args);
/* Only forward requests for non-local channels */
@@ -661,7 +662,7 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
}
IRC_SetPenalty(Client, 1);
return CONNECTED;
return connected;
} /* Channel_Mode */

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
* Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -16,6 +16,7 @@
#include "imp.h"
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -30,43 +31,50 @@
#include "match.h"
#include "messages.h"
#include "parse.h"
#include "op.h"
#include <exp.h>
#include "irc-oper.h"
/**
* Handle invalid received OPER command.
* Log OPER attempt and send error message to client.
*/
static bool
Bad_OperPass(CLIENT *Client, char *errtoken, char *errmsg)
{
Log( LOG_WARNING, "Got invalid OPER from \"%s\": \"%s\" -- %s", Client_Mask( Client ),
errtoken, errmsg);
Log(LOG_WARNING, "Got invalid OPER from \"%s\": \"%s\" -- %s",
Client_Mask(Client), errtoken, errmsg);
IRC_SetPenalty(Client, 3);
return IRC_WriteStrClient( Client, ERR_PASSWDMISMATCH_MSG, Client_ID( Client ));
}
return IRC_WriteStrClient(Client, ERR_PASSWDMISMATCH_MSG,
Client_ID(Client));
} /* Bad_OperPass */
GLOBAL bool
IRC_OPER( CLIENT *Client, REQUEST *Req )
{
unsigned int i;
struct Conf_Oper *op;
size_t len, i;
assert( Client != NULL );
assert( Req != NULL );
if( Req->argc != 2 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
for( i = 0; i < Conf_Oper_Count; i++)
{
if( Conf_Oper[i].name[0] && Conf_Oper[i].pwd[0] && ( strcmp( Conf_Oper[i].name, Req->argv[0] ) == 0 )) break;
}
if( i >= Conf_Oper_Count )
len = array_length(&Conf_Opers, sizeof(*op));
op = array_start(&Conf_Opers);
for (i = 0; i < len && strcmp(op[i].name, Req->argv[0]); i++)
;
if (i >= len)
return Bad_OperPass(Client, Req->argv[0], "not configured");
if( strcmp( Conf_Oper[i].pwd, Req->argv[1] ) != 0 )
return Bad_OperPass(Client, Conf_Oper[i].name, "Bad password");
if (strcmp(op[i].pwd, Req->argv[1]) != 0)
return Bad_OperPass(Client, op[i].name, "bad password");
if( Conf_Oper[i].mask && (! Match( Conf_Oper[i].mask, Client_Mask( Client ) )))
return Bad_OperPass(Client, Conf_Oper[i].mask, "hostmask check failed" );
if (op[i].mask && (!Match(op[i].mask, Client_Mask(Client))))
return Bad_OperPass(Client, op[i].mask, "hostmask check failed");
if( ! Client_HasMode( Client, 'o' ))
{
@@ -93,10 +101,8 @@ IRC_DIE(CLIENT * Client, REQUEST * Req)
assert(Client != NULL);
assert(Req != NULL);
/* Not a local IRC operator? */
if ((!Client_HasMode(Client, 'o')) || (!Client_OperByMe(Client)))
return IRC_WriteStrClient(Client, ERR_NOPRIVILEGES_MSG,
Client_ID(Client));
if (!Op_Check(Client, Req))
return Op_NoPrivileges(Client, Req);
/* Bad number of parameters? */
#ifdef STRICT_RFC
@@ -135,8 +141,8 @@ IRC_REHASH( CLIENT *Client, REQUEST *Req )
assert( Client != NULL );
assert( Req != NULL );
/* Not a local IRC operator? */
if(( ! Client_HasMode( Client, 'o' )) || ( ! Client_OperByMe( Client ))) return IRC_WriteStrClient( Client, ERR_NOPRIVILEGES_MSG, Client_ID( Client ));
if (!Op_Check(Client, Req))
return Op_NoPrivileges(Client, Req);
/* Bad number of parameters? */
if( Req->argc != 0 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
@@ -156,8 +162,8 @@ IRC_RESTART( CLIENT *Client, REQUEST *Req )
assert( Client != NULL );
assert( Req != NULL );
/* Not a local IRC operator? */
if(( ! Client_HasMode( Client, 'o' )) || ( ! Client_OperByMe( Client ))) return IRC_WriteStrClient( Client, ERR_NOPRIVILEGES_MSG, Client_ID( Client ));
if (!Op_Check(Client, Req))
return Op_NoPrivileges(Client, Req);
/* Bad number of parameters? */
if( Req->argc != 0 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
@@ -174,17 +180,18 @@ IRC_RESTART( CLIENT *Client, REQUEST *Req )
GLOBAL bool
IRC_CONNECT(CLIENT * Client, REQUEST * Req)
{
CLIENT *from, *target;
assert(Client != NULL);
assert(Req != NULL);
/* Not a local IRC operator? */
if ((!Client_HasMode(Client, 'o')) || (!Client_OperByMe(Client)))
return IRC_WriteStrClient(Client, ERR_NOPRIVILEGES_MSG,
Client_ID(Client));
if (Client_Type(Client) != CLIENT_SERVER
&& !Client_HasMode(Client, 'o'))
return Op_NoPrivileges(Client, Req);
/* Bad number of parameters? */
if ((Req->argc != 1) && (Req->argc != 2) && (Req->argc != 5))
if (Req->argc != 1 && Req->argc != 2 && Req->argc != 3 &&
Req->argc != 5 && Req->argc != 6)
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
@@ -193,74 +200,125 @@ IRC_CONNECT(CLIENT * Client, REQUEST * Req)
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
Log(LOG_NOTICE | LOG_snotice,
"Got CONNECT command from \"%s\" for \"%s\".", Client_Mask(Client),
Req->argv[0]);
from = Client;
target = Client_ThisServer();
if (Req->argc == 3 || Req->argc == 6) {
/* This CONNECT has a target parameter */
if (Client_Type(Client) == CLIENT_SERVER && Req->prefix)
from = Client_Search(Req->prefix);
if (! from)
return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG,
Client_ID(Client), Req->prefix);
target = (Req->argc == 3) ? Client_Search(Req->argv[2])
: Client_Search(Req->argv[5]);
if (! target || Client_Type(target) != CLIENT_SERVER)
return IRC_WriteStrClient(from, ERR_NOSUCHSERVER_MSG,
Client_ID(from), Req->argv[0]);
}
if (target != Client_ThisServer()) {
/* Forward CONNECT command ... */
if (Req->argc == 3)
IRC_WriteStrClientPrefix(target, from,
"CONNECT %s %s :%s", Req->argv[0],
Req->argv[1], Req->argv[2]);
else
IRC_WriteStrClientPrefix(target, from,
"CONNECT %s %s %s %s %s :%s", Req->argv[0],
Req->argv[1], Req->argv[2], Req->argv[3],
Req->argv[4], Req->argv[5]);
return CONNECTED;
}
if (!Op_Check(from, Req))
return Op_NoPrivileges(Client, Req);
switch (Req->argc) {
case 1:
if (!Conf_EnablePassiveServer(Req->argv[0]))
return IRC_WriteStrClient(Client, ERR_NOSUCHSERVER_MSG,
Client_ID(Client),
return IRC_WriteStrClient(from, ERR_NOSUCHSERVER_MSG,
Client_ID(from),
Req->argv[0]);
break;
break;
case 2:
case 3:
/* Connect configured server */
if (!Conf_EnableServer
(Req->argv[0], (UINT16) atoi(Req->argv[1])))
return IRC_WriteStrClient(Client, ERR_NOSUCHSERVER_MSG,
Client_ID(Client),
return IRC_WriteStrClient(from, ERR_NOSUCHSERVER_MSG,
Client_ID(from),
Req->argv[0]);
break;
break;
default:
/* Add server */
if (!Conf_AddServer
(Req->argv[0], (UINT16) atoi(Req->argv[1]), Req->argv[2],
Req->argv[3], Req->argv[4]))
return IRC_WriteStrClient(Client, ERR_NOSUCHSERVER_MSG,
Client_ID(Client),
return IRC_WriteStrClient(from, ERR_NOSUCHSERVER_MSG,
Client_ID(from),
Req->argv[0]);
}
Log(LOG_NOTICE | LOG_snotice,
"Got CONNECT command from \"%s\" for \"%s\".", Client_Mask(from),
Req->argv[0]);
IRC_SendWallops(Client_ThisServer(), Client_ThisServer(),
"Received CONNECT %s from %s",
Req->argv[0], Client_ID(from));
return CONNECTED;
} /* IRC_CONNECT */
/**
* Disconnect (and disable) configured server.
*/
GLOBAL bool
IRC_DISCONNECT(CLIENT *Client, REQUEST *Req )
IRC_DISCONNECT(CLIENT * Client, REQUEST * Req)
{
/* Disconnect and disable configured server */
CONN_ID my_conn;
assert( Client != NULL );
assert( Req != NULL );
assert(Client != NULL);
assert(Req != NULL);
/* Not a local IRC operator? */
if(( ! Client_HasMode( Client, 'o' )) || ( ! Client_OperByMe( Client ))) return IRC_WriteStrClient( Client, ERR_NOPRIVILEGES_MSG, Client_ID( Client ));
if (!Op_Check(Client, Req))
return Op_NoPrivileges(Client, Req);
/* Bad number of parameters? */
if( Req->argc != 1 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
if (Req->argc != 1)
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
Log( LOG_NOTICE|LOG_snotice, "Got DISCONNECT command from \"%s\" for0 \"%s\".", Client_Mask( Client ), Req->argv[0]);
IRC_SendWallops(Client_ThisServer(), Client_ThisServer(),
"Received DISCONNECT %s from %s",
Req->argv[0], Client_ID(Client));
Log(LOG_NOTICE | LOG_snotice,
"Got DISCONNECT command from \"%s\" for \"%s\".",
Client_Mask(Client), Req->argv[0]);
/* Save ID of this connection */
my_conn = Client_Conn( Client );
my_conn = Client_Conn(Client);
/* Connect configured server */
if( ! Conf_DisableServer( Req->argv[0] )) return IRC_WriteStrClient( Client, ERR_NOSUCHSERVER_MSG, Client_ID( Client ), Req->argv[0] );
/* Disconnect configured server */
if (!Conf_DisableServer(Req->argv[0]))
return IRC_WriteStrClient(Client, ERR_NOSUCHSERVER_MSG,
Client_ID(Client), Req->argv[0]);
/* Are we still connected or were we killed, too? */
if( Conn_GetClient( my_conn )) return CONNECTED;
else return DISCONNECTED;
} /* IRC_CONNECT */
if (Conn_GetClient(my_conn))
return CONNECTED;
else
return DISCONNECTED;
} /* IRC_DISCONNECT */
GLOBAL bool
IRC_WALLOPS( CLIENT *Client, REQUEST *Req )
{
CLIENT *to, *from;
int client_type;
CLIENT *from;
assert( Client != NULL );
assert( Req != NULL );
@@ -268,8 +326,7 @@ IRC_WALLOPS( CLIENT *Client, REQUEST *Req )
if (Req->argc != 1)
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, Client_ID(Client), Req->command);
client_type = Client_Type(Client);
switch (client_type) {
switch (Client_Type(Client)) {
case CLIENT_USER:
if (!Client_OperByMe(Client))
return IRC_WriteStrClient(Client, ERR_NOPRIVILEGES_MSG, Client_ID(Client));
@@ -285,25 +342,9 @@ IRC_WALLOPS( CLIENT *Client, REQUEST *Req )
if (!from)
return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG, Client_ID(Client), Req->prefix);
for (to=Client_First(); to != NULL; to=Client_Next(to)) {
if (Client_Conn(to) < 0) /* no local connection or WALLOPS origin */
continue;
client_type = Client_Type(to);
switch (client_type) {
case CLIENT_USER:
if (Client_HasMode(to, 'w'))
IRC_WriteStrClientPrefix(to, from, "WALLOPS :%s", Req->argv[0]);
break;
case CLIENT_SERVER:
if (to != Client)
IRC_WriteStrClientPrefix(to, from, "WALLOPS :%s", Req->argv[0]);
break;
}
}
IRC_SendWallops(Client, from, "%s", Req->argv[0]);
return CONNECTED;
}
} /* IRC_WALLOPS */
/* -eof- */

View File

@@ -37,6 +37,7 @@
#include "numeric.h"
#include "ngircd.h"
#include "irc-info.h"
#include "op.h"
#include "exp.h"
#include "irc-server.h"
@@ -51,7 +52,6 @@ IRC_SERVER( CLIENT *Client, REQUEST *Req )
{
char str[LINE_LEN];
CLIENT *from, *c;
bool ok;
int i;
CONN_ID con;
@@ -97,25 +97,25 @@ 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 )
{
con = Client_Conn(Client);
if (Client_Token(Client) != TOKEN_OUTBOUND) {
/* Incoming connection, send user/pass */
ok = true;
if( ! IRC_WriteStrClient( Client, "PASS %s %s", Conf_Server[i].pwd_out, NGIRCd_ProtoID )) ok = false;
else ok = IRC_WriteStrClient( Client, "SERVER %s 1 :%s", Conf_ServerName, Conf_ServerInfo );
if( ! ok )
{
Conn_Close( con, "Unexpected server behavior!", NULL, false );
return DISCONNECTED;
if (!IRC_WriteStrClient(Client, "PASS %s %s",
Conf_Server[i].pwd_out,
NGIRCd_ProtoID)
|| !IRC_WriteStrClient(Client, "SERVER %s 1 :%s",
Conf_ServerName,
Conf_ServerInfo)) {
Conn_Close(con, "Unexpected server behavior!",
NULL, false);
return DISCONNECTED;
}
Client_SetIntroducer( Client, Client );
Client_SetToken( Client, 1 );
}
else
{
/* outgoing connect, we already sent SERVER and PASS to the peer */
Client_SetToken( Client, atoi( Req->argv[1] ));
Client_SetIntroducer(Client, Client);
Client_SetToken(Client, 1);
} else {
/* outgoing connect, we already sent a SERVER and PASS
* command to the peer */
Client_SetToken(Client, atoi(Req->argv[1]));
}
/* Mark this connection as belonging to an configured server */
@@ -267,46 +267,99 @@ IRC_NJOIN( CLIENT *Client, REQUEST *Req )
} /* IRC_NJOIN */
/**
* Handler for the IRC command "SQUIT".
* See RFC 2813 section 4.1.2 and RFC 2812 section 3.1.8.
*/
GLOBAL bool
IRC_SQUIT( CLIENT *Client, REQUEST *Req )
IRC_SQUIT(CLIENT * Client, REQUEST * Req)
{
CLIENT *target;
char msg[LINE_LEN + 64];
char msg[COMMAND_LEN], logmsg[COMMAND_LEN];
CLIENT *from, *target;
CONN_ID con;
assert( Client != NULL );
assert( Req != NULL );
assert(Client != NULL);
assert(Req != NULL);
if( Req->argc != 2 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
if (Client_Type(Client) != CLIENT_SERVER
&& !Client_HasMode(Client, 'o'))
return Op_NoPrivileges(Client, Req);
Log( LOG_DEBUG, "Got SQUIT from %s for \"%s\": \"%s\" ...", Client_ID( Client ), Req->argv[0], Req->argv[1] );
/* Bad number of arguments? */
if (Req->argc != 2)
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
target = Client_Search( Req->argv[0] );
if( ! target )
{
Log( LOG_WARNING, "Got SQUIT from %s for unknown server \"%s\"!?", Client_ID( Client ), Req->argv[0] );
if (Client_Type(Client) == CLIENT_SERVER && Req->prefix) {
from = Client_Search(Req->prefix);
if (Client_Type(from) != CLIENT_SERVER
&& !Op_Check(Client, Req))
return Op_NoPrivileges(Client, Req);
} else
from = Client;
if (!from)
return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG,
Client_ID(Client), Req->prefix);
Log(LOG_DEBUG, "Got SQUIT from %s for \"%s\": \"%s\" ...",
Client_ID(from), Req->argv[0], Req->argv[1]);
target = Client_Search(Req->argv[0]);
if (Client_Type(Client) != CLIENT_SERVER &&
target == Client_ThisServer())
return Op_NoPrivileges(Client, Req);
if (!target) {
/* The server is (already) unknown */
Log(LOG_WARNING,
"Got SQUIT from %s for unknown server \"%s\"!?",
Client_ID(Client), Req->argv[0]);
return CONNECTED;
}
if( Req->argv[1][0] )
{
if( strlen( Req->argv[1] ) > LINE_LEN ) Req->argv[1][LINE_LEN] = '\0';
snprintf( msg, sizeof( msg ), "%s (SQUIT from %s).", Req->argv[1], Client_ID( Client ));
}
else snprintf( msg, sizeof( msg ), "Got SQUIT from %s.", Client_ID( Client ));
con = Client_Conn(target);
if( Client_Conn( target ) > NONE )
{
/* This server has the connection */
if( Req->argv[1][0] ) Conn_Close( Client_Conn( target ), msg, Req->argv[1], true);
else Conn_Close( Client_Conn( target ), msg, NULL, true);
return DISCONNECTED;
}
if (Req->argv[1][0])
if (Client_NextHop(from) != Client || con > NONE)
snprintf(msg, sizeof(msg), "%s (SQUIT from %s)",
Req->argv[1], Client_ID(from));
else
strlcpy(msg, Req->argv[1], sizeof(msg));
else
{
/* connection was on another server */
Client_Destroy( target, msg, Req->argv[1], false );
return CONNECTED;
snprintf(msg, sizeof(msg), "Got SQUIT from %s",
Client_ID(from));
if (con > NONE) {
/* We are directly connected to the target server, so we
* have to tear down the connection and to inform all the
* other remaining servers in the network */
IRC_SendWallops(Client_ThisServer(), Client_ThisServer(),
"Received SQUIT %s from %s: %s",
Req->argv[0], Client_ID(from),
Req->argv[1][0] ? Req->argv[1] : "-");
Conn_Close(con, NULL, msg, true);
if (con == Client_Conn(Client))
return DISCONNECTED;
} else {
/* This server is not directly connected, so the SQUIT must
* be forwarded ... */
if (Client_Type(from) != CLIENT_SERVER) {
/* The origin is not an IRC server, so don't evaluate
* this SQUIT but simply forward it */
IRC_WriteStrClientPrefix(Client_NextHop(target),
from, "SQUIT %s :%s", Req->argv[0], Req->argv[1]);
} else {
/* SQUIT has been generated by another server, so
* remove the target server from the network! */
logmsg[0] = '\0';
if (!strchr(msg, '('))
snprintf(logmsg, sizeof(logmsg),
"%s (SQUIT from %s)", Req->argv[1],
Client_ID(from));
Client_Destroy(target, logmsg[0] ? logmsg : msg,
msg, false);
}
}
return CONNECTED;
} /* IRC_SQUIT */
/* -eof- */

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2005 by Alexander Barton (alex@barton.de)
* Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -405,6 +405,53 @@ va_dcl
} /* IRC_WriteStrRelatedPrefix */
/**
* Send WALLOPS message.
*/
#ifdef PROTOTYPES
GLOBAL void
IRC_SendWallops(CLIENT *Client, CLIENT *From, const char *Format, ...)
#else
GLOBAL void
IRC_SendWallops(Client, From, Format, va_alist )
CLIENT *Client;
CLIENT *From;
char *Format;
va_dcl
#endif
{
va_list ap;
char msg[1000];
CLIENT *to;
#ifdef PROTOTYPES
va_start(ap, Format);
#else
va_start(ap);
#endif
vsnprintf(msg, 1000, Format, ap);
va_end(ap);
for (to=Client_First(); to != NULL; to=Client_Next(to)) {
if (Client_Conn(to) == NONE) /* no local connection */
continue;
switch (Client_Type(to)) {
case CLIENT_USER:
if (Client_HasMode(to, 'w'))
IRC_WriteStrClientPrefix(to, From,
"WALLOPS :%s", msg);
break;
case CLIENT_SERVER:
if (to != Client)
IRC_WriteStrClientPrefix(to, From,
"WALLOPS :%s", msg);
break;
}
}
} /* IRC_SendWallops */
GLOBAL void
IRC_SetPenalty( CLIENT *Client, time_t Seconds )
{

View File

@@ -35,6 +35,9 @@ GLOBAL void IRC_WriteStrServersPrefixFlag_CB PARAMS((CLIENT *ExceptOf,
GLOBAL bool IRC_WriteStrRelatedPrefix PARAMS((CLIENT *Client, CLIENT *Prefix,
bool Remote, char *Format, ...));
GLOBAL void IRC_SendWallops PARAMS((CLIENT *Client, CLIENT *From,
const char *Format, ...));
GLOBAL void IRC_SetPenalty PARAMS((CLIENT *Client, time_t Seconds));
#endif

View File

@@ -53,8 +53,12 @@ IRC_ERROR( CLIENT *Client, REQUEST *Req )
assert( Client != NULL );
assert( Req != NULL );
if( Req->argc < 1 ) Log( LOG_NOTICE, "Got ERROR from \"%s\"!", Client_Mask( Client ));
else Log( LOG_NOTICE, "Got ERROR from \"%s\": %s!", Client_Mask( Client ), Req->argv[0] );
if (Req->argc < 1)
Log(LOG_NOTICE, "Got ERROR from \"%s\"!",
Client_Mask(Client));
else
Log(LOG_NOTICE, "Got ERROR from \"%s\": \"%s\"!",
Client_Mask(Client), Req->argv[0]);
return CONNECTED;
} /* IRC_ERROR */

View File

@@ -146,8 +146,8 @@ GLOBAL void
Log_Exit( void )
{
/* Good Bye! */
if( NGIRCd_SignalRestart ) Log( LOG_NOTICE, "%s done (restarting).", PACKAGE_NAME );
else Log( LOG_NOTICE, "%s done.", PACKAGE_NAME );
Log(LOG_NOTICE, "%s done%s, served %lu connections.", PACKAGE_NAME,
NGIRCd_SignalRestart ? " (restarting)" : "", Conn_CountAccepted());
#ifdef DEBUG
if( Error_File[0] )

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2008 Alexander Barton <alex@barton.de>
* Copyright (c)2001-2010 Alexander Barton <alex@barton.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,7 +20,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 CASEMAPPING=ascii PREFIX=(ov)@+ CHANTYPES=#&+ CHANMODES=bI,k,l,imnPst CHANLIMIT=#&+:%d :are supported on this server"
#define RPL_ISUPPORT1_MSG "005 %s RFC2812 IRCD=ngIRCd CASEMAPPING=ascii PREFIX=(ov)@+ CHANTYPES=#&+ CHANMODES=bI,k,l,imnPst CHANLIMIT=#&+:%d :are supported on this server"
#define RPL_ISUPPORT2_MSG "005 %s CHANNELLEN=%d NICKLEN=%d TOPICLEN=%d AWAYLEN=%d KICKLEN=%d PENALTY :are supported on this server"
#define RPL_TRACELINK_MSG "200 %s Link %s-%s %s %s V%s %ld %d %d"
@@ -46,6 +46,7 @@
#define RPL_TRACEEND_MSG "262 %s %s %s-%s.%s :End of TRACE"
#define RPL_LOCALUSERS_MSG "265 %s %lu %lu :Current local users: %lu, Max: %lu"
#define RPL_NETUSERS_MSG "266 %s %lu %lu :Current global users: %lu, Max: %lu"
#define RPL_STATSCONN_MSG "250 %s :Highest connection count: %lu (%lu connections received)"
#define RPL_AWAY_MSG "301 %s %s :%s"
#define RPL_USERHOST_MSG "302 %s :"
@@ -113,6 +114,7 @@
#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_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)"

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2008 Alexander Barton (alex@barton.de).
* Copyright (c)2001-2010 Alexander Barton (alex@barton.de).
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -562,7 +562,7 @@ static void
Show_Version( void )
{
puts( NGIRCd_Version );
puts( "Copyright (c)2001-2008 Alexander Barton (<alex@barton.de>) and Contributors." );
puts( "Copyright (c)2001-2010 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." );
@@ -798,7 +798,9 @@ NGIRCd_Init( bool NGIRCd_NoDaemon )
#else
setpgrp(0, getpid());
#endif
chdir( "/" );
if (chdir( "/" ) != 0)
Log(LOG_ERR, "Can't change directory to '/': %s",
strerror(errno));
/* Detach stdin, stdout and stderr */
Setup_FDStreams( );

82
src/ngircd/op.c Normal file
View File

@@ -0,0 +1,82 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
* Please read the file COPYING, README and AUTHORS for more information.
*
* IRC operator functions
*/
#include "portab.h"
#include "imp.h"
#include <assert.h>
#include <string.h>
#include "conn.h"
#include "client.h"
#include "channel.h"
#include "conf.h"
#include "log.h"
#include "parse.h"
#include "messages.h"
#include "irc-write.h"
#include <exp.h>
#include "op.h"
/**
* Return and log a "no privileges" message.
*/
GLOBAL bool
Op_NoPrivileges(CLIENT * Client, REQUEST * Req)
{
CLIENT *from = NULL;
if (Req->prefix)
from = Client_Search(Req->prefix);
if (from) {
Log(LOG_NOTICE, "No privileges: client \"%s\" (%s), command \"%s\"",
Req->prefix, Client_Mask(Client), Req->command);
return IRC_WriteStrClient(from, ERR_NOPRIVILEGES_MSG,
Client_ID(from));
} else {
Log(LOG_NOTICE, "No privileges: client \"%s\", command \"%s\"",
Client_Mask(Client), Req->command);
return IRC_WriteStrClient(Client, ERR_NOPRIVILEGES_MSG,
Client_ID(Client));
}
} /* Op_NoPrivileges */
/**
* Check that the client is an IRC operator allowed to administer this server.
*/
GLOBAL bool
Op_Check(CLIENT * Client, REQUEST * Req)
{
CLIENT *c;
assert(Client != NULL);
assert(Req != NULL);
if (Client_Type(Client) == CLIENT_SERVER && Req->prefix)
c = Client_Search(Req->prefix);
else
c = Client;
if (!c)
return false;
if (!Client_HasMode(c, 'o'))
return false;
if (!Client_OperByMe(c) && !Conf_AllowRemoteOper)
return false;
/* The client is an local IRC operator, or this server is configured
* to trust remote operators. */
return true;
} /* Op_Check */

22
src/ngircd/op.h Normal file
View File

@@ -0,0 +1,22 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2009 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.
*
* Operator management (header)
*/
#ifndef __oper_h__
#define __oper_h__
GLOBAL bool Op_NoPrivileges PARAMS((CLIENT * Client, REQUEST * Req));
GLOBAL bool Op_Check PARAMS((CLIENT * Client, REQUEST * Req));
#endif
/* -eof- */

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
* Copyright (c)2001-2010 Alexander Barton (alex@barton.de)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -59,7 +59,7 @@ static COMMAND My_Commands[] =
{
{ "ADMIN", IRC_ADMIN, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
{ "AWAY", IRC_AWAY, CLIENT_USER, 0, 0, 0 },
{ "CONNECT", IRC_CONNECT, CLIENT_USER, 0, 0, 0 },
{ "CONNECT", IRC_CONNECT, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
{ "DIE", IRC_DIE, CLIENT_USER, 0, 0, 0 },
{ "DISCONNECT", IRC_DISCONNECT, CLIENT_USER, 0, 0, 0 },
{ "ERROR", IRC_ERROR, 0xFFFF, 0, 0, 0 },
@@ -92,7 +92,7 @@ static COMMAND My_Commands[] =
{ "SERVICE", IRC_SERVICE, 0xFFFF, 0, 0, 0 },
{ "SERVLIST", IRC_SERVLIST, CLIENT_USER, 0, 0, 0 },
{ "SQUERY", IRC_SQUERY, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
{ "SQUIT", IRC_SQUIT, CLIENT_SERVER, 0, 0, 0 },
{ "SQUIT", IRC_SQUIT, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
{ "STATS", IRC_STATS, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
{ "SUMMON", IRC_SUMMON, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
{ "TIME", IRC_TIME, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
@@ -103,6 +103,7 @@ static COMMAND My_Commands[] =
{ "USERS", IRC_USERS, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
{ "VERSION", IRC_VERSION, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
{ "WALLOPS", IRC_WALLOPS, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
{ "WEBIRC", IRC_WEBIRC, CLIENT_UNKNOWN, 0, 0, 0 },
{ "WHO", IRC_WHO, CLIENT_USER, 0, 0, 0 },
{ "WHOIS", IRC_WHOIS, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
{ "WHOWAS", IRC_WHOWAS, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2003 by Alexander Barton (alex@barton.de)
* Copyright (c)2001-2009 by Alexander Barton (alex@barton.de)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -144,8 +144,8 @@ Resolve_Init(RES_STAT *s)
}
#ifndef WANT_IPV6
#ifdef h_errno
#if !defined(HAVE_GETADDRINFO) || !defined(HAVE_GETNAMEINFO)
#if !defined(WANT_IPV6) && defined(h_errno)
static char *
Get_Error( int H_Error )
{
@@ -162,8 +162,8 @@ Get_Error( int H_Error )
}
return "unknown error";
}
#endif /* h_errno */
#endif /* WANT_IPV6 */
#endif
#endif
/* Do "IDENT" (aka "AUTH") lookup and append result to resolved_addr array */
@@ -203,7 +203,7 @@ Do_IdentQuery(int identsock, array *resolved_addr)
* the IP address in resbuf and returns false.
* @param IpAddr ip address to resolve
* @param resbuf result buffer to store DNS name/string representation of ip address
* @reslen size of result buffer (must be >= NGT_INET_ADDRSTRLEN)
* @param reslen size of result buffer (must be >= NGT_INET_ADDRSTRLEN)
* @return true if reverse lookup successful, false otherwise
*/
static bool
@@ -218,7 +218,7 @@ ReverseLookup(const ng_ipaddr_t *IpAddr, char *resbuf, size_t reslen)
*resbuf = 0;
res = getnameinfo((struct sockaddr *) IpAddr, ng_ipaddr_salen(IpAddr),
resbuf, reslen, NULL, 0, NI_NAMEREQD);
resbuf, (socklen_t)reslen, NULL, 0, NI_NAMEREQD);
if (res == 0)
return true;
@@ -291,6 +291,8 @@ ForwardLookup(const char *hostname, array *IpAddr)
if (!Conf_ConnectIPv4)
hints.ai_family = AF_INET6;
#endif
memset(&addr, 0, sizeof(addr));
res = getaddrinfo(hostname, NULL, &hints, &ai_results);
switch (res) {
case 0: break;
@@ -540,5 +542,6 @@ Resolve_Read( RES_STAT *s, void* readbuf, size_t buflen)
Resolve_Shutdown(s);
return (size_t)bytes_read;
}
/* -eof- */
/* -eof- */

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
* Copyright (c)2001-2009 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
@@ -107,16 +107,19 @@ ngt_TrimLastChr( char *String, const char Chr)
/* If last character in the string matches Chr, remove it.
* Empty strings are handled correctly. */
unsigned int len;
size_t len;
assert( String != NULL );
assert(String != NULL);
len = strlen( String );
if( len == 0 ) return;
len = strlen(String);
if(len == 0)
return;
len--;
if( String[len] == Chr ) String[len] = '\0';
if(String[len] == Chr)
String[len] = '\0';
} /* ngt_TrimLastChr */
/* -eof- */