mirror of
https://github.com/osmarks/ngircd.git
synced 2025-09-25 05:24:04 +00:00
Compare commits
101 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
defd7e09af | ||
![]() |
29d448ed63 | ||
![]() |
bdec5ac1f3 | ||
![]() |
73fd26e9fa | ||
![]() |
79e1ec2b1e | ||
![]() |
615d09459e | ||
![]() |
1338ade650 | ||
![]() |
21140500f1 | ||
![]() |
77ceb9f8ab | ||
![]() |
b042363e88 | ||
![]() |
6b0bb665c3 | ||
![]() |
1caa3fb94b | ||
![]() |
025342fe46 | ||
![]() |
628c6c962b | ||
![]() |
1ed49de83a | ||
![]() |
bb914b93e9 | ||
![]() |
50e8a62c5c | ||
![]() |
aa32fec1b6 | ||
![]() |
cbe41ec875 | ||
![]() |
20276f7cc9 | ||
![]() |
6e8cf51bb2 | ||
![]() |
53fc0ebff6 | ||
![]() |
9b3e143a26 | ||
![]() |
f1bbc92b39 | ||
![]() |
1da3e25e65 | ||
![]() |
e1de769ab9 | ||
![]() |
9f58418765 | ||
![]() |
ef157715a0 | ||
![]() |
ecad9f32c8 | ||
![]() |
f58c8b94d9 | ||
![]() |
3a2ac66f7f | ||
![]() |
cf05bf31a7 | ||
![]() |
a4d7c6f145 | ||
![]() |
1ddc74f13e | ||
![]() |
75dabcaae5 | ||
![]() |
1b73e68e6e | ||
![]() |
03cde2efd3 | ||
![]() |
cb6faed61c | ||
![]() |
c62c2d349b | ||
![]() |
60137a7139 | ||
![]() |
513a75c919 | ||
![]() |
4f1b5400e9 | ||
![]() |
cade80dcf5 | ||
![]() |
28ca31e576 | ||
![]() |
c414d0bd3a | ||
![]() |
bc88b2cb06 | ||
![]() |
bc1ac7fbc5 | ||
![]() |
37e950a40c | ||
![]() |
55c04e691d | ||
![]() |
881b9af251 | ||
![]() |
294320ed62 | ||
![]() |
03b70229eb | ||
![]() |
9918dfc1d5 | ||
![]() |
e46cf64cc1 | ||
![]() |
113bd34878 | ||
![]() |
4a3e40bc95 | ||
![]() |
45b1a45c97 | ||
![]() |
7d6de7c352 | ||
![]() |
30b584c2e8 | ||
![]() |
eaaf0c3bd5 | ||
![]() |
9a7499af8b | ||
![]() |
bce16c2864 | ||
![]() |
926204cacd | ||
![]() |
3bf0c6f3b9 | ||
![]() |
f78b0c61e9 | ||
![]() |
fa09883c72 | ||
![]() |
affa03b277 | ||
![]() |
5b1efaee67 | ||
![]() |
d5f80b2a8d | ||
![]() |
60fc4d6335 | ||
![]() |
536538968c | ||
![]() |
4daf780f01 | ||
![]() |
ed72bf4ceb | ||
![]() |
d76910ce7b | ||
![]() |
8fd0e29d46 | ||
![]() |
bfa48f3448 | ||
![]() |
66c6458ae7 | ||
![]() |
3b37ad334b | ||
![]() |
c191ea53a9 | ||
![]() |
e1598e2670 | ||
![]() |
44acf41cc1 | ||
![]() |
933da741c6 | ||
![]() |
cf7e19193b | ||
![]() |
5f1e43416a | ||
![]() |
5debe20509 | ||
![]() |
a7eef6666b | ||
![]() |
56a8abc253 | ||
![]() |
21bb2bd658 | ||
![]() |
bddfd67550 | ||
![]() |
805bf03490 | ||
![]() |
63cbc6cd42 | ||
![]() |
b3cacf86df | ||
![]() |
0ef94edad7 | ||
![]() |
643ae1b48b | ||
![]() |
9b1c47220f | ||
![]() |
8e2c5816ee | ||
![]() |
f31c3a3aa2 | ||
![]() |
b0931f322b | ||
![]() |
5196e9bcb1 | ||
![]() |
57aa64e117 | ||
![]() |
fd7e85b798 |
2
AUTHORS
2
AUTHORS
@@ -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
|
||||
|
68
ChangeLog
68
ChangeLog
@@ -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.
|
||||
|
@@ -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
36
NEWS
@@ -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
4
README
@@ -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).
|
||||
|
37
configure.in
37
configure.in
@@ -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!]))
|
||||
|
@@ -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.
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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>
|
||||
|
@@ -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;
|
||||
|
@@ -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
|
||||
|
@@ -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).
|
||||
|
@@ -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
143
contrib/platformtest.sh
Executable 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
|
@@ -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
37
doc/README-Interix.txt
Normal 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.
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -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- */
|
||||
|
||||
|
@@ -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:
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
|
@@ -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\"!",
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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;
|
||||
|
@@ -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- */
|
||||
|
@@ -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- */
|
||||
|
@@ -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
|
||||
|
@@ -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 */
|
||||
|
||||
|
||||
|
@@ -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) */
|
||||
|
@@ -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;
|
||||
|
@@ -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 )
|
||||
{
|
||||
|
@@ -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));
|
||||
|
@@ -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 */
|
||||
|
||||
|
||||
|
@@ -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- */
|
||||
|
@@ -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- */
|
||||
|
@@ -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 )
|
||||
{
|
||||
|
@@ -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
|
||||
|
@@ -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 */
|
||||
|
@@ -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] )
|
||||
|
@@ -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)"
|
||||
|
@@ -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
82
src/ngircd/op.c
Normal 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
22
src/ngircd/op.h
Normal 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- */
|
@@ -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 },
|
||||
|
@@ -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- */
|
||||
|
@@ -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- */
|
||||
|
Reference in New Issue
Block a user