1
0
mirror of https://github.com/osmarks/ngircd.git synced 2025-10-14 22:27:39 +00:00

Compare commits

...

27 Commits

Author SHA1 Message Date
Alexander Barton
50e8a62c5c ngIRCd release 16~rc1 2010-03-25 15:57:11 +01:00
Alexander Barton
aa32fec1b6 Updated NEWS and ChangeLog file for ngIRCd 16-rc1 2010-03-25 14:55:31 +01:00
Alexander Barton
cbe41ec875 Don't use port 6668 as example for both "Ports" and "SSLPorts" 2010-03-16 16:16:03 +01:00
Florian Westphal
20276f7cc9 configure.in: only add -lnsl when needed
dpkg-shlibdeps: warning: dependency on libnsl.so.1 [..]
(they use none of its symbols).

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

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

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

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

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

But please note three things:

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

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

Detection of uninitialized automatic variable requires data flow analsys
that is only enabled during optimized compilation.
2009-12-27 17:21:37 +01:00
Alexander Barton
60137a7139 Added i686/unknown/kfreebsd7.2-gnu 2009-12-02 22:22:35 +01:00
Alexander Barton
513a75c919 platformtest.sh: Only show latest commit
Only show latest GIT commuit ID as version number,
even when the last commit has been a merge.
2009-11-15 18:25:36 +01:00
Alexander Barton
4f1b5400e9 Merge commit 'cade80dcf516f40e7d53124bc98526e6e5b3fb66'
* commit 'cade80dcf516f40e7d53124bc98526e6e5b3fb66':
  Added missing contrib/platformtest.sh to distribution
2009-11-07 21:51:36 +01:00
Florian Westphal
28ca31e576 Remove limit on max number of configured irc operators. 2009-11-07 17:42:54 +01:00
29 changed files with 580 additions and 272 deletions

View File

@@ -10,6 +10,32 @@
-- ChangeLog --
ngIRCd Release 16
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.

17
NEWS
View File

@@ -1,7 +1,7 @@
ngIRCd - Next Generation IRC Server
(c)2001-2009 Alexander Barton,
(c)2001-2010 Alexander Barton,
alex@barton.de, http://www.barton.de/
ngIRCd is free software and published under the
@@ -10,6 +10,21 @@
-- NEWS --
ngIRCd Release 16
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)

4
README
View File

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

View File

@@ -12,7 +12,7 @@
# -- Initialisation --
AC_PREREQ(2.50)
AC_INIT(ngircd, 15)
AC_INIT(ngircd, 16~rc1)
AC_CONFIG_SRCDIR(src/ngircd/ngircd.c)
AC_CANONICAL_TARGET
AM_INIT_AUTOMAKE(1.6)
@@ -105,7 +105,8 @@ AC_CHECK_HEADERS([ \
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])
# -- Datatypes --
@@ -130,9 +131,11 @@ AC_CHECK_MEMBER([struct sockaddr_in.sin_len], AC_DEFINE(HAVE_sockaddr_in_len),,
# -- 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 --

View File

@@ -1,3 +1,9 @@
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 +0100
ngircd (15-0ab1) unstable; urgency=low
* New "upstream" release: ngIRCd 15.

View File

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

View File

@@ -758,7 +758,7 @@
GCC_WARN_SHADOW = YES;
GCC_WARN_SIGN_COMPARE = YES;
GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNINITIALIZED_AUTOS = NO;
GCC_WARN_UNKNOWN_PRAGMAS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_LABEL = YES;

View File

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

View File

@@ -105,7 +105,7 @@ fi
# Get ngIRCd version information
if [ -d ".git" ]; then
VERSION=`git log --abbrev-commit --pretty=oneline HEAD~1.. \
| cut -d' ' -f1 | tr -d '.'`
| head -1 | cut -d' ' -f1 | tr -d '.'`
elif [ -r "Makefile" ]; then
eval $(grep "^VERSION = " Makefile | sed -e 's/ //g')
fi

View File

@@ -43,11 +43,13 @@ 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/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 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 14.1 09-07-28 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 14.1 09-07-28 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 14.1 09-08-04 alex Y Y Y Y (1)

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

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

View File

@@ -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

View File

@@ -69,6 +69,15 @@ 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.

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
* Copyright (c)2001-2010 Alexander Barton (alex@barton.de)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -181,39 +181,46 @@ Client_NewRemoteUser(CLIENT *Introducer, const char *Nick, int Hops, const char
*/
static CLIENT *
Init_New_Client(CONN_ID Idx, CLIENT *Introducer, CLIENT *TopServer,
int Type, const char *ID, const char *User, const char *Hostname, const char *Info, int Hops,
int Token, const char *Modes, bool Idented)
int Type, const char *ID, const char *User, const char *Hostname,
const char *Info, int Hops, int Token, const char *Modes, bool Idented)
{
CLIENT *client;
assert( Idx >= NONE );
assert( Introducer != NULL );
assert( Hostname != NULL );
assert(Idx >= NONE);
assert(Introducer != NULL);
assert(Hostname != NULL);
client = New_Client_Struct( );
if( ! client ) return NULL;
client = New_Client_Struct();
if (!client)
return NULL;
client->starttime = time(NULL);
client->conn_id = Idx;
client->introducer = Introducer;
client->topserver = TopServer;
client->type = Type;
if( ID ) Client_SetID( client, ID );
if( User ) Client_SetUser( client, User, Idented );
if( Hostname ) Client_SetHostname( client, Hostname );
if( Info ) Client_SetInfo( client, Info );
if (ID)
Client_SetID(client, ID);
if (User)
Client_SetUser(client, User, Idented);
if (Hostname)
Client_SetHostname(client, Hostname);
if (Info)
Client_SetInfo(client, Info);
client->hops = Hops;
client->token = Token;
if( Modes ) Client_SetModes( client, Modes );
if( Type == CLIENT_SERVER ) Generate_MyToken( client );
if (Modes)
Client_SetModes(client, Modes);
if (Type == CLIENT_SERVER)
Generate_MyToken(client);
if( strchr( client->modes, 'a' ))
strlcpy( client->away, DEFAULT_AWAY_MSG, sizeof( client->away ));
if (strchr(client->modes, 'a'))
strlcpy(client->away, DEFAULT_AWAY_MSG, sizeof(client->away));
client->next = (POINTER *)My_Clients;
My_Clients = client;
Adjust_Counters( client );
Adjust_Counters(client);
return client;
} /* Init_New_Client */

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2009 Alexander Barton (alex@barton.de)
* Copyright (c)2001-2010 Alexander Barton (alex@barton.de)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -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 ));
@@ -226,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 )
{
@@ -255,16 +291,17 @@ 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);
@@ -304,16 +341,7 @@ Conf_Test( void )
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;
@@ -609,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 );
@@ -667,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] ) {
@@ -710,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;
@@ -828,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 ));
@@ -1081,36 +1106,38 @@ Handle_GLOBAL( int Line, char *Var, char *Arg )
static void
Handle_OPERATOR( int Line, char *Var, char *Arg )
{
unsigned int opercount;
size_t len;
struct Conf_Oper *op;
assert( Line > 0 );
assert( Var != NULL );
assert( Arg != NULL );
assert( Conf_Oper_Count > 0 );
if ( Conf_Oper_Count == 0 )
op = array_alloc(&Conf_Opers, sizeof(*op), Conf_Oper_Count - 1);
if (!op) {
Config_Error(LOG_ERR, "Could not allocate memory for operator (%d:%s = %s)", Line, Var, Arg);
return;
}
opercount = Conf_Oper_Count - 1;
if( strcasecmp( Var, "Name" ) == 0 ) {
if (strcasecmp(Var, "Name") == 0) {
/* Name of IRC operator */
len = strlcpy( Conf_Oper[opercount].name, Arg, sizeof( Conf_Oper[opercount].name ));
if (len >= sizeof( Conf_Oper[opercount].name ))
Config_Error_TooLong( Line, Var );
len = strlcpy(op->name, Arg, sizeof(op->name));
if (len >= sizeof(op->name))
Config_Error_TooLong(Line, Var);
return;
}
if( strcasecmp( Var, "Password" ) == 0 ) {
if (strcasecmp(Var, "Password") == 0) {
/* Password of IRC operator */
len = strlcpy( Conf_Oper[opercount].pwd, Arg, sizeof( Conf_Oper[opercount].pwd ));
if (len >= sizeof( Conf_Oper[opercount].pwd ))
Config_Error_TooLong( Line, Var );
len = strlcpy(op->pwd, Arg, sizeof(op->pwd));
if (len >= sizeof(op->pwd))
Config_Error_TooLong(Line, Var);
return;
}
if( strcasecmp( Var, "Mask" ) == 0 ) {
if (Conf_Oper[opercount].mask) return; /* Hostname already configured */
Conf_Oper[opercount].mask = strdup_warn( Arg );
if (strcasecmp(Var, "Mask") == 0) {
if (op->mask)
return; /* Hostname already configured */
op->mask = strdup_warn( Arg );
return;
}
Config_Error( LOG_ERR, "%s, line %d (section \"Operator\"): Unknown variable \"%s\"!",

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
* Copyright (c)2001-2010 Alexander Barton (alex@barton.de)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -26,12 +26,11 @@
#include "conf-ssl.h"
typedef struct _Conf_Oper
{
struct Conf_Oper {
char name[CLIENT_PASS_LEN]; /* Name (ID) of IRC operator */
char pwd[CLIENT_PASS_LEN]; /* Password */
char *mask;
} CONF_OPER;
char *mask; /* allowed host mask */
};
typedef struct _Conf_Server
{
@@ -125,8 +124,7 @@ GLOBAL int Conf_PongTimeout;
GLOBAL int Conf_ConnectRetry;
/* Operators */
GLOBAL CONF_OPER Conf_Oper[MAX_OPERATORS];
GLOBAL unsigned int Conf_Oper_Count;
GLOBAL array Conf_Opers;
/* Servers */
GLOBAL CONF_SERVER Conf_Server[MAX_SERVERS];
@@ -190,6 +188,9 @@ GLOBAL bool Conf_AddServer PARAMS(( const char *Name, UINT16 Port, const char *H
GLOBAL bool Conf_IsService PARAMS((int ConfServer, const char *Nick));
/* Password required by WEBIRC command */
GLOBAL char Conf_WebircPwd[CLIENT_PASS_LEN];
#endif

View File

@@ -109,37 +109,51 @@ 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)
{
@@ -213,6 +227,10 @@ cb_connserver(int sock, UNUSED short what)
}
/**
* Login to a remote server.
* @param idx Connection index
*/
static void
server_login(CONN_ID idx)
{
@@ -229,6 +247,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)
{
@@ -258,6 +281,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)
{
@@ -270,18 +298,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)
{
@@ -295,11 +332,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);
@@ -312,6 +351,9 @@ cb_clientserver_ssl(int sock, short what)
#endif
/**
* Initialite connecion module.
*/
GLOBAL void
Conn_Init( void )
{
@@ -347,6 +389,9 @@ Conn_Init( void )
} /* Conn_Init */
/**
* Clean up connection module.
*/
GLOBAL void
Conn_Exit( void )
{
@@ -399,6 +444,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 )
{
@@ -433,13 +482,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 */
@@ -582,6 +630,7 @@ NewListener(const char *listen_addr, UINT16 Port)
return sock;
} /* NewListener */
#ifdef SSL_SUPPORT
/*
* SSL/TLS connections require extra treatment:
@@ -1163,12 +1212,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
@@ -1178,10 +1229,9 @@ 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) {
@@ -1198,49 +1248,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);
@@ -1249,22 +1306,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;
@@ -1292,7 +1351,14 @@ 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);
NumConnections++;
LogDebug("Total number of connections now %ld.", NumConnections);
return new_sock;
} /* New_Connection */
@@ -1811,12 +1877,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
@@ -1825,7 +1892,6 @@ Init_Socket( int Sock )
} /* Init_Socket */
static void
cb_Connect_to_Server(int fd, UNUSED short events)
{
@@ -1933,10 +1999,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) {
@@ -1972,24 +2042,34 @@ Simple_Message( int Sock, const char *Msg )
} /* 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)
{
@@ -2000,6 +2080,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)
{
@@ -2008,6 +2093,7 @@ Conn_UsesSSL(CONN_ID Idx)
assert(Idx < (int) array_length(&My_ConnArray, sizeof(CONNECTION)));
return Conn_OPTION_ISSET(&My_Connections[Idx], CONN_SSL);
}
#endif

View File

@@ -88,7 +88,7 @@ typedef struct _Connection
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;

View File

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

View File

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

View File

@@ -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 */

View File

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

View File

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

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
* Copyright (c)2001-2010 Alexander Barton (alex@barton.de)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -401,6 +401,7 @@ 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

View File

@@ -55,25 +55,26 @@ Bad_OperPass(CLIENT *Client, char *errtoken, char *errmsg)
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' ))
{

View File

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

View File

@@ -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"
@@ -113,6 +113,7 @@
#define ERR_ALREADYREGISTRED_MSG "462 %s :Connection already registered"
#define ERR_PASSWDMISMATCH_MSG "464 %s :Invalid password"
#define ERR_CHANNELISFULL_MSG "471 %s %s :Cannot join channel (+l)"
#define ERR_SECURECHANNEL_MSG "471 %s %s :Cannot join channel (+z)"
#define ERR_UNKNOWNMODE_MSG "472 %s: %c :is unknown mode char for %s"
#define ERR_INVITEONLYCHAN_MSG "473 %s %s :Cannot join channel (+i)"
#define ERR_BANNEDFROMCHAN_MSG "474 %s %s :Cannot join channel (+b)"

View File

@@ -1,6 +1,6 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
* Copyright (c)2001-2010 Alexander Barton (alex@barton.de)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -103,6 +103,7 @@ static COMMAND My_Commands[] =
{ "USERS", IRC_USERS, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
{ "VERSION", IRC_VERSION, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
{ "WALLOPS", IRC_WALLOPS, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
{ "WEBIRC", IRC_WEBIRC, CLIENT_UNKNOWN, 0, 0, 0 },
{ "WHO", IRC_WHO, CLIENT_USER, 0, 0, 0 },
{ "WHOIS", IRC_WHOIS, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
{ "WHOWAS", IRC_WHOWAS, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },

View File

@@ -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