Merge branches 'CloakUserHost', 'QuitOnHTTP' and 'bug72-WHOIS-List'
* CloakUserHost: Add a note not to use a percent sign ("%") in CloakHost variable Rename ClientHost to CloakHost, and ClientUserNick to CloakUserToNick Don't use "the.net" in sample-ngircd.conf, use "example.net" ngircd.conf.5: document "ClientHost" and "ClientUserNick" Move "ClientHost" and "ClientUserNick" to end of [Global] section ClientUserNick setting ClientHost setting * QuitOnHTTP: Only "handle" HTTP commands on unregistered connections Don't use IRC_QUIT_HTTP() if STRICT_RFC is #define'd IRC_QUIT_HTTP(): enhance error message Move IRC_QUIT_HTTP() below IRC_QUIT() quit on HTTP commands: GET & POST * bug72-WHOIS-List: Add "whois-test" to testsuite and distribution archive Add support for up to 3 targets in WHOIS queries.
This commit is contained in:
commit
fa8b83e69b
|
@ -1,6 +1,6 @@
|
|||
#
|
||||
# ngIRCd -- The Next Generation IRC Daemon
|
||||
# Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
|
||||
# Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
@ -9,7 +9,7 @@
|
|||
# Please read the file COPYING, README and AUTHORS for more information.
|
||||
#
|
||||
|
||||
EXTRA_DIST = Doxyfile header.inc.html footer.inc.html ngircd-doc.css
|
||||
EXTRA_DIST = Doxyfile footer.inc.html
|
||||
|
||||
maintainer-clean-local:
|
||||
rm -f Makefile Makefile.in
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.\"
|
||||
.\" ngircd.conf(5) manual page template
|
||||
.\"
|
||||
.TH ngircd.conf 5 "Dec 2010" ngircd "ngIRCd Manual"
|
||||
.TH ngircd.conf 5 "Mar 2011" ngircd "ngIRCd Manual"
|
||||
.SH NAME
|
||||
ngircd.conf \- configuration file of ngIRCd
|
||||
.SH SYNOPSIS
|
||||
|
@ -36,6 +36,20 @@ The file format is line-based - that means, each non-empty newline-terminated
|
|||
line represents either a comment, a section name, or a parameter.
|
||||
.PP
|
||||
Section and parameter names are not case sensitive.
|
||||
.PP
|
||||
There are three types of variables:
|
||||
.I booleans,
|
||||
.I text strings,
|
||||
and
|
||||
.I numbers.
|
||||
Boolean values are
|
||||
.I true
|
||||
if they are "yes", "true", or any non-null integer. Text strings are used 1:1
|
||||
without leading and following spaces; there is not way to quote strings. And
|
||||
for numbers all decimal integer values are valid.
|
||||
.PP
|
||||
In addition, some string or numerical variables accept lists of values,
|
||||
separated by commas (",").
|
||||
.SH "SECTION OVERVIEW"
|
||||
The file can contain blocks of four types: [Global], [Operator], [Server],
|
||||
and [Channel].
|
||||
|
@ -65,49 +79,49 @@ The
|
|||
section is used to define the server main configuration, like the server
|
||||
name and the ports on which the server should be listening.
|
||||
.TP
|
||||
\fBName\fR
|
||||
\fBName\fR (string)
|
||||
Server name in the IRC network. This is an individual name of the IRC
|
||||
server, it is not related to the DNS host name. It must be unique in the
|
||||
IRC network and must contain at least one dot (".") character.
|
||||
.TP
|
||||
\fBInfo\fR
|
||||
\fBInfo\fR (string)
|
||||
Info text of the server. This will be shown by WHOIS and LINKS requests for
|
||||
example.
|
||||
.TP
|
||||
\fBPassword\fR
|
||||
\fBPassword\fR (string)
|
||||
Global password for all users needed to connect to the server. The default
|
||||
is empty, so no password is required.
|
||||
.TP
|
||||
\fBWebircPassword\fR
|
||||
\fBWebircPassword\fR (string)
|
||||
Password required for using the WEBIRC command used by some Web-to-IRC
|
||||
gateways. If not set or empty, the WEBIRC command can't be used.
|
||||
Default: not set.
|
||||
.TP
|
||||
\fBAdminInfo1\fR, \fBAdminInfo2\fR, \fBAdminEMail\fR
|
||||
\fBAdminInfo1\fR, \fBAdminInfo2\fR, \fBAdminEMail\fR (string)
|
||||
Information about the server and the administrator, used by the ADMIN
|
||||
command.
|
||||
.TP
|
||||
\fBPorts\fR
|
||||
\fBPorts\fR (list of numbers)
|
||||
Ports on which the server should listen. There may be more than one port,
|
||||
separated with commas (","). Default: 6667, unless \fBSSL_Ports\fR are also
|
||||
specified.
|
||||
.TP
|
||||
\fBSSLPorts\fR
|
||||
\fBSSLPorts\fR (list of numbers)
|
||||
Same as \fBPorts\fR , except that ngIRCd will expect incoming connections
|
||||
to be SSL/TLS encrypted. Common port numbers for SSL-encrypted IRC are 6669
|
||||
and 6697. Default: none.
|
||||
.TP
|
||||
\fBSSLKeyFile\fR
|
||||
\fBSSLKeyFile\fR (string)
|
||||
Filename of SSL Server Key to be used for SSL connections. This is required for
|
||||
SSL/TLS support.
|
||||
.TP
|
||||
\fBSSLKeyFilePassword\fR
|
||||
\fBSSLKeyFilePassword\fR (string)
|
||||
(OpenSSL only:) Password to decrypt private key.
|
||||
.TP
|
||||
\fBSSLCertFile\fR
|
||||
\fBSSLCertFile\fR (string)
|
||||
Certificate file of the private key.
|
||||
.TP
|
||||
\fBSSLDHFile\fR
|
||||
\fBSSLDHFile\fR (string)
|
||||
Name of the Diffie-Hellman Parameter file. Can be created with gnutls
|
||||
"certtool \-\-generate-dh-params" or "openssl dhparam".
|
||||
If this file is not present, it will be generated on startup when ngIRCd
|
||||
|
@ -115,28 +129,28 @@ was compiled with gnutls support (this may take some time). If ngIRCd
|
|||
was compiled with OpenSSL, then (Ephemeral)-Diffie-Hellman Key Exchanges and several
|
||||
Cipher Suites will not be available.
|
||||
.TP
|
||||
\fBListen\fR
|
||||
\fBListen\fR (list of strings)
|
||||
A comma separated list of IP address on which the server should listen.
|
||||
If unset, the defaults value is "0.0.0.0" or, if ngIRCd was compiled
|
||||
with IPv6 support, "::,0.0.0.0". So the server listens on all configured
|
||||
IP addresses and interfaces by default.
|
||||
.TP
|
||||
\fBSyslogFacility\fR
|
||||
\fBSyslogFacility\fR (string)
|
||||
Syslog "facility" to which ngIRCd should send log messages. Possible
|
||||
values are system dependant, but most probably "auth", "daemon", "user"
|
||||
and "local1" through "local7" are possible values; see syslog(3).
|
||||
Default is "local5" for historical reasons, you probably want to
|
||||
change this to "daemon", for example.
|
||||
.TP
|
||||
\fBMotdFile\fR
|
||||
\fBMotdFile\fR (string)
|
||||
Text file with the "message of the day" (MOTD). This message will be shown
|
||||
to all users connecting to the server. Changes made to this file
|
||||
take effect when ngircd is instructed to re-read its configuration file.
|
||||
.TP
|
||||
\fBMotdPhrase\fR
|
||||
\fBMotdPhrase\fR (string)
|
||||
A simple Phrase (<256 chars) if you don't want to use a MOTD file.
|
||||
.TP
|
||||
\fBServerUID\fR
|
||||
\fBServerUID\fR (string or number)
|
||||
User ID under which the server should run; you can use the name of the user
|
||||
or the numerical ID.
|
||||
.PP
|
||||
|
@ -148,7 +162,7 @@ started with root privileges! In addition, the configuration and MOTD files
|
|||
must be readable by this user, otherwise RESTART and REHASH won't work!
|
||||
.RE
|
||||
.TP
|
||||
\fBServerGID\fR
|
||||
\fBServerGID\fR (string or number)
|
||||
Group ID under which the ngIRCd should run; you can use the name of the
|
||||
group or the numerical ID.
|
||||
.PP
|
||||
|
@ -159,7 +173,7 @@ For this to work the server must have
|
|||
been started with root privileges!
|
||||
.RE
|
||||
.TP
|
||||
\fBChrootDir\fR
|
||||
\fBChrootDir\fR (string)
|
||||
A directory to chroot in when everything is initialized. It doesn't need
|
||||
to be populated if ngIRCd is compiled as a static binary. By default ngIRCd
|
||||
won't use the chroot() feature.
|
||||
|
@ -171,68 +185,68 @@ For this to work the server must have
|
|||
been started with root privileges!
|
||||
.RE
|
||||
.TP
|
||||
\fBPidFile\fR
|
||||
\fBPidFile\fR (string)
|
||||
This tells ngIRCd to write its current process ID to a file. Note that the
|
||||
pidfile is written AFTER chroot and switching the user ID, i. e. the
|
||||
directory the pidfile resides in must be writeable by the ngIRCd user and
|
||||
exist in the chroot directory (if configured, see above).
|
||||
.RE
|
||||
.TP
|
||||
\fBPingTimeout\fR
|
||||
\fBPingTimeout\fR (number)
|
||||
After <PingTimeout> seconds of inactivity the server will send a PING to
|
||||
the peer to test whether it is alive or not. Default: 120.
|
||||
.TP
|
||||
\fBPongTimeout\fR
|
||||
\fBPongTimeout\fR (number)
|
||||
If a client fails to answer a PING with a PONG within <PongTimeout>
|
||||
seconds, it will be disconnected by the server. Default: 20.
|
||||
.TP
|
||||
\fBConnectRetry\fR
|
||||
\fBConnectRetry\fR (number)
|
||||
The server tries every <ConnectRetry> seconds to establish a link to not yet
|
||||
(or no longer) connected servers. Default: 60.
|
||||
.TP
|
||||
\fBOperCanUseMode\fR
|
||||
\fBOperCanUseMode\fR (boolean)
|
||||
Should IRC Operators be allowed to use the MODE command even if they are
|
||||
not(!) channel-operators? Default: no.
|
||||
.TP
|
||||
\fBOperServerMode\fR
|
||||
\fBOperServerMode\fR (boolean)
|
||||
If \fBOperCanUseMode\fR is enabled, this may lead the compatibility problems with
|
||||
Servers that run the ircd-irc2 Software. This Option "masks" mode requests
|
||||
by non-chanops as if they were coming from the server. Default: no.
|
||||
.TP
|
||||
\fBAllowRemoteOper\fR
|
||||
\fBAllowRemoteOper\fR (boolean)
|
||||
Are IRC operators connected to remote servers allowed to control this server,
|
||||
e. g. are they allowed to use administrative commands like CONNECT, DIE,
|
||||
SQUIT, ... that affect this server? Default: no.
|
||||
.TP
|
||||
\fBPredefChannelsOnly\fR
|
||||
\fBPredefChannelsOnly\fR (boolean)
|
||||
If enabled, no new channels can be created. Useful if
|
||||
you do not want to have channels other than those defined in
|
||||
[Channel] sections in the configuration file.
|
||||
Default: no.
|
||||
.TP
|
||||
\fBConnectIPv4\fR
|
||||
\fBConnectIPv4\fR (boolean)
|
||||
Set this to no if you do not want ngIRCd to connect to other IRC servers using
|
||||
IPv4. This allows usage of ngIRCd in IPv6-only setups.
|
||||
Default: yes.
|
||||
.TP
|
||||
\fBConnectIPv6\fR
|
||||
\fBConnectIPv6\fR (boolean)
|
||||
Set this to no if you do not want ngIRCd to connect to other irc servers using IPv6.
|
||||
Default: yes.
|
||||
.TP
|
||||
\fBMaxConnections\fR
|
||||
\fBMaxConnections\fR (number)
|
||||
Maximum number of simultaneous in- and outbound connections the server is
|
||||
allowed to accept (0: unlimited). Default: 0.
|
||||
.TP
|
||||
\fBMaxConnectionsIP\fR
|
||||
\fBMaxConnectionsIP\fR (number)
|
||||
Maximum number of simultaneous connections from a single IP address that
|
||||
the server will accept (0: unlimited). This configuration options lowers
|
||||
the risk of denial of service attacks (DoS). Default: 5.
|
||||
.TP
|
||||
\fBMaxJoins\fR
|
||||
\fBMaxJoins\fR (number)
|
||||
Maximum number of channels a user can be member of (0: no limit).
|
||||
Default: 10.
|
||||
.TP
|
||||
\fBMaxNickLength\fR
|
||||
\fBMaxNickLength\fR (number)
|
||||
Maximum length of an user nick name (Default: 9, as in RFC 2812). Please
|
||||
note that all servers in an IRC network MUST use the same maximum nick name
|
||||
length!
|
||||
|
@ -256,36 +270,36 @@ sections are used to define IRC Operators. There may be more than one
|
|||
.I [Operator]
|
||||
block, one for each local operator.
|
||||
.TP
|
||||
\fBName\fR
|
||||
\fBName\fR (string)
|
||||
ID of the operator (may be different of the nick name).
|
||||
.TP
|
||||
\fBPassword\fR
|
||||
\fBPassword\fR (string)
|
||||
Password of the IRC operator.
|
||||
.TP
|
||||
\fBMask\fR
|
||||
\fBMask\fR (string)
|
||||
Mask that is to be checked before an /OPER for this account is accepted.
|
||||
Example: nick!ident@*.example.com
|
||||
.SH [FEATURES]
|
||||
An optional section that can be used to disable features at
|
||||
run-time. A feature is enabled by default if if ngircd was built with
|
||||
support for it.
|
||||
\fBDNS\fR
|
||||
.TP
|
||||
\fBDNS\fR (boolean)
|
||||
If set to false, ngIRCd will not make DNS lookups when clients connect.
|
||||
If you configure the daemon to connect to other servers, ngIRCd may still
|
||||
perform a DNS lookup if required.
|
||||
Default: yes.
|
||||
.TP
|
||||
\fBIdent\fR
|
||||
\fBIdent\fR (boolean)
|
||||
If ngIRCd is compiled with IDENT support this can be used to disable IDENT
|
||||
lookups at run time.
|
||||
Default: yes.
|
||||
.TP
|
||||
\fBPAM\fR
|
||||
\fBPAM\fR (boolean)
|
||||
If ngIRCd is compiled with PAM support this can be used to disable all calls
|
||||
to the PAM library at runtime; all users connecting without password are
|
||||
allowed to connect, all passwords given will fail.
|
||||
Default: yes.
|
||||
.TP
|
||||
.SH [SERVER]
|
||||
Other servers are configured in
|
||||
.I [Server]
|
||||
|
@ -304,40 +318,40 @@ There may be more than one
|
|||
.I [Server]
|
||||
block.
|
||||
.TP
|
||||
\fBName\fR
|
||||
\fBName\fR (string)
|
||||
IRC name of the remote server.
|
||||
.TP
|
||||
\fBHost\fR
|
||||
\fBHost\fR (string)
|
||||
Internet host name (or IP address) of the peer.
|
||||
.TP
|
||||
\fBBind\fR
|
||||
\fBBind\fR (string)
|
||||
IP address to use as source IP for the outgoing connection. Default is
|
||||
to let the operating system decide.
|
||||
.TP
|
||||
\fBPort\fR
|
||||
\fBPort\fR (number)
|
||||
Port of the remote server to which ngIRCd should connect (active).
|
||||
If no port is assigned to a configured server, the daemon only waits for
|
||||
incoming connections (passive, default).
|
||||
.TP
|
||||
\fBMyPassword\fR
|
||||
\fBMyPassword\fR (string)
|
||||
Own password for this connection. This password has to be configured as
|
||||
\fBPeerPassword\fR on the other server. Must not have ':' as first character.
|
||||
.TP
|
||||
\fBPeerPassword\fR
|
||||
\fBPeerPassword\fR (string)
|
||||
Foreign password for this connection. This password has to be configured as
|
||||
\fBMyPassword\fR on the other server.
|
||||
.TP
|
||||
\fBGroup\fR
|
||||
\fBGroup\fR (number)
|
||||
Group of this server (optional).
|
||||
.TP
|
||||
\fBPassive\fR
|
||||
\fBPassive\fR (boolean)
|
||||
Disable automatic connection even if port value is specified. Default: false.
|
||||
You can use the IRC Operator command CONNECT later on to create the link.
|
||||
.TP
|
||||
\fBSSLConnect\fR
|
||||
\fBSSLConnect\fR (boolean)
|
||||
Connect to the remote server using TLS/SSL. Default: false.
|
||||
.TP
|
||||
\fBServiceMask\fR
|
||||
\fBServiceMask\fR (string)
|
||||
Define a (case insensitive) mask matching nick names that should be treated as
|
||||
IRC services when introduced via this remote server. REGULAR SERVERS DON'T NEED
|
||||
this parameter, so leave it empty (which is the default).
|
||||
|
@ -359,19 +373,19 @@ There may be more than one
|
|||
.I [Channel]
|
||||
block.
|
||||
.TP
|
||||
\fBName\fR
|
||||
\fBName\fR (string)
|
||||
Name of the channel, including channel prefix ("#" or "&").
|
||||
.TP
|
||||
\fBTopic\fR
|
||||
\fBTopic\fR (string)
|
||||
Topic for this channel.
|
||||
.TP
|
||||
\fBModes\fR
|
||||
\fBModes\fR (string)
|
||||
Initial channel modes.
|
||||
.TP
|
||||
\fBKey\fR
|
||||
\fBKey\fR (string)
|
||||
Sets initial channel key (only relevant if channel mode "k" is set).
|
||||
.TP
|
||||
\fBKeyFile\fR
|
||||
\fBKeyFile\fR (string)
|
||||
Path and file name of a "key file" containing individual channel keys for
|
||||
different users. The file consists of plain text lines with the following
|
||||
syntax (without spaces!):
|
||||
|
@ -414,7 +428,7 @@ without problems, but moving or deleting the file will have not effect until
|
|||
the daemon re-reads its configuration!
|
||||
.RE
|
||||
.TP
|
||||
\fBMaxUsers\fR
|
||||
\fBMaxUsers\fR (number)
|
||||
Set maximum user limit for this channel (only relevant if channel mode "l"
|
||||
is set).
|
||||
.SH HINTS
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* Copyright (c)2001-2010 Alexander Barton <alex@barton.de>
|
||||
* Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -917,56 +917,20 @@ IRC_WHO( CLIENT *Client, REQUEST *Req )
|
|||
|
||||
|
||||
/**
|
||||
* Handler for the IRC "WHOIS" command.
|
||||
*
|
||||
* See RFC 2812, 3.6.2 "Whois query".
|
||||
* Generate WHOIS reply of one actual client.
|
||||
*
|
||||
* @param Client The client from which this command has been received.
|
||||
* @param Req Request structure with prefix and all parameters.
|
||||
* @return CONNECTED or DISCONNECTED.
|
||||
* @param from The client requesting the information ("originator").
|
||||
* @param c The client of which information should be returned.
|
||||
* @returns CONNECTED or DISCONNECTED.
|
||||
*/
|
||||
GLOBAL bool
|
||||
IRC_WHOIS( CLIENT *Client, REQUEST *Req )
|
||||
static bool
|
||||
IRC_WHOIS_SendReply(CLIENT *Client, CLIENT *from, CLIENT *c)
|
||||
{
|
||||
CLIENT *from, *target, *c;
|
||||
char str[LINE_LEN + 1];
|
||||
CL2CHAN *cl2chan;
|
||||
CHANNEL *chan;
|
||||
|
||||
assert( Client != NULL );
|
||||
assert( Req != NULL );
|
||||
|
||||
/* Bad number of parameters? */
|
||||
if (Req->argc < 1 || Req->argc > 2)
|
||||
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
|
||||
Client_ID(Client), Req->command);
|
||||
|
||||
/* Search client */
|
||||
c = Client_Search(Req->argv[Req->argc - 1]);
|
||||
if (!c || (Client_Type(c) != CLIENT_USER
|
||||
&& Client_Type(c) != CLIENT_SERVICE))
|
||||
return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG,
|
||||
Client_ID(Client),
|
||||
Req->argv[Req->argc - 1]);
|
||||
|
||||
/* Search sender of the WHOIS */
|
||||
if( Client_Type( Client ) == CLIENT_SERVER ) from = Client_Search( Req->prefix );
|
||||
else from = Client;
|
||||
if( ! from ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix );
|
||||
|
||||
/* Forward to other server? */
|
||||
if( Req->argc > 1 )
|
||||
{
|
||||
/* Search target server (can be specified as nick of that server!) */
|
||||
target = Client_Search( Req->argv[0] );
|
||||
if( ! target ) return IRC_WriteStrClient( from, ERR_NOSUCHSERVER_MSG, Client_ID( from ), Req->argv[0] );
|
||||
}
|
||||
else target = Client_ThisServer( );
|
||||
|
||||
assert( target != NULL );
|
||||
|
||||
if(( Client_NextHop( target ) != Client_ThisServer( )) && ( Client_Type( Client_NextHop( target )) == CLIENT_SERVER )) return IRC_WriteStrClientPrefix( target, from, "WHOIS %s :%s", Req->argv[0], Req->argv[1] );
|
||||
|
||||
/* Nick, user, hostname and client info */
|
||||
if (!IRC_WriteStrClient(from, RPL_WHOISUSER_MSG, Client_ID(from),
|
||||
Client_ID(c), Client_User(c),
|
||||
|
@ -974,18 +938,21 @@ IRC_WHOIS( CLIENT *Client, REQUEST *Req )
|
|||
return DISCONNECTED;
|
||||
|
||||
/* Server */
|
||||
if( ! IRC_WriteStrClient( from, RPL_WHOISSERVER_MSG, Client_ID( from ), Client_ID( c ), Client_ID( Client_Introducer( c )), Client_Info( Client_Introducer( c )))) return DISCONNECTED;
|
||||
if (!IRC_WriteStrClient(from, RPL_WHOISSERVER_MSG, Client_ID(from),
|
||||
Client_ID(c), Client_ID(Client_Introducer(c)),
|
||||
Client_Info(Client_Introducer(c))))
|
||||
return DISCONNECTED;
|
||||
|
||||
/* Channels */
|
||||
snprintf( str, sizeof( str ), RPL_WHOISCHANNELS_MSG, Client_ID( from ), Client_ID( c ));
|
||||
cl2chan = Channel_FirstChannelOf( c );
|
||||
while( cl2chan )
|
||||
{
|
||||
chan = Channel_GetChannel( cl2chan );
|
||||
assert( chan != NULL );
|
||||
snprintf(str, sizeof(str), RPL_WHOISCHANNELS_MSG,
|
||||
Client_ID(from), Client_ID(c));
|
||||
cl2chan = Channel_FirstChannelOf(c);
|
||||
while (cl2chan) {
|
||||
chan = Channel_GetChannel(cl2chan);
|
||||
assert(chan != NULL);
|
||||
|
||||
/* next */
|
||||
cl2chan = Channel_NextChannelOf( c, cl2chan );
|
||||
cl2chan = Channel_NextChannelOf(c, cl2chan);
|
||||
|
||||
/* Secret channel? */
|
||||
if (strchr(Channel_Modes(chan), 's')
|
||||
|
@ -998,54 +965,168 @@ IRC_WHOIS( CLIENT *Client, REQUEST *Req )
|
|||
continue;
|
||||
|
||||
/* Concatenate channel names */
|
||||
if( str[strlen( str ) - 1] != ':' ) strlcat( str, " ", sizeof( str ));
|
||||
if( strchr( Channel_UserModes( chan, c ), 'o' )) strlcat( str, "@", sizeof( str ));
|
||||
else if( strchr( Channel_UserModes( chan, c ), 'v' )) strlcat( str, "+", sizeof( str ));
|
||||
strlcat( str, Channel_Name( chan ), sizeof( str ));
|
||||
if (str[strlen(str) - 1] != ':')
|
||||
strlcat(str, " ", sizeof(str));
|
||||
|
||||
if( strlen( str ) > ( LINE_LEN - CHANNEL_NAME_LEN - 4 ))
|
||||
{
|
||||
strlcat(str, who_flags_qualifier(Channel_UserModes(chan, c)),
|
||||
sizeof(str));
|
||||
strlcat(str, Channel_Name(chan), sizeof(str));
|
||||
|
||||
if (strlen(str) > (LINE_LEN - CHANNEL_NAME_LEN - 4)) {
|
||||
/* Line becomes too long: send it! */
|
||||
if( ! IRC_WriteStrClient( Client, "%s", str )) return DISCONNECTED;
|
||||
snprintf( str, sizeof( str ), RPL_WHOISCHANNELS_MSG, Client_ID( from ), Client_ID( c ));
|
||||
if (!IRC_WriteStrClient(Client, "%s", str))
|
||||
return DISCONNECTED;
|
||||
snprintf(str, sizeof(str), RPL_WHOISCHANNELS_MSG,
|
||||
Client_ID(from), Client_ID(c));
|
||||
}
|
||||
}
|
||||
if( str[strlen( str ) - 1] != ':')
|
||||
{
|
||||
if(str[strlen(str) - 1] != ':') {
|
||||
/* There is data left to send: */
|
||||
if( ! IRC_WriteStrClient( Client, "%s", str )) return DISCONNECTED;
|
||||
}
|
||||
|
||||
/* IRC-Operator? */
|
||||
if( Client_HasMode( c, 'o' ))
|
||||
{
|
||||
if( ! IRC_WriteStrClient( from, RPL_WHOISOPERATOR_MSG, Client_ID( from ), Client_ID( c ))) return DISCONNECTED;
|
||||
}
|
||||
|
||||
/* Connected using SSL? */
|
||||
if (Conn_UsesSSL(Client_Conn(c))) {
|
||||
if (!IRC_WriteStrClient
|
||||
(from, RPL_WHOISSSL_MSG, Client_ID(from), Client_ID(c)))
|
||||
if (!IRC_WriteStrClient(Client, "%s", str))
|
||||
return DISCONNECTED;
|
||||
}
|
||||
|
||||
/* IRC-Operator? */
|
||||
if (Client_HasMode(c, 'o') &&
|
||||
!IRC_WriteStrClient(from, RPL_WHOISOPERATOR_MSG,
|
||||
Client_ID(from), Client_ID(c)))
|
||||
return DISCONNECTED;
|
||||
|
||||
/* Connected using SSL? */
|
||||
if (Conn_UsesSSL(Client_Conn(c)) &&
|
||||
!IRC_WriteStrClient(from, RPL_WHOISSSL_MSG,
|
||||
Client_ID(from), Client_ID(c)))
|
||||
return DISCONNECTED;
|
||||
|
||||
/* Idle and signon time (local clients only!) */
|
||||
if (Client_Conn(c) > NONE ) {
|
||||
if (! IRC_WriteStrClient(from, RPL_WHOISIDLE_MSG,
|
||||
Client_ID(from), Client_ID(c),
|
||||
(unsigned long)Conn_GetIdle(Client_Conn(c)),
|
||||
(unsigned long)Conn_GetSignon(Client_Conn(c))))
|
||||
return DISCONNECTED;
|
||||
}
|
||||
if (Client_Conn(c) > NONE &&
|
||||
!IRC_WriteStrClient(from, RPL_WHOISIDLE_MSG,
|
||||
Client_ID(from), Client_ID(c),
|
||||
(unsigned long)Conn_GetIdle(Client_Conn(c)),
|
||||
(unsigned long)Conn_GetSignon(Client_Conn(c))))
|
||||
return DISCONNECTED;
|
||||
|
||||
/* Away? */
|
||||
if( Client_HasMode( c, 'a' ))
|
||||
{
|
||||
if( ! IRC_WriteStrClient( from, RPL_AWAY_MSG, Client_ID( from ), Client_ID( c ), Client_Away( c ))) return DISCONNECTED;
|
||||
}
|
||||
if (Client_HasMode(c, 'a') &&
|
||||
!IRC_WriteStrClient(from, RPL_AWAY_MSG,
|
||||
Client_ID(from), Client_ID(c),
|
||||
Client_Away(c)))
|
||||
return DISCONNECTED;
|
||||
|
||||
/* End of Whois */
|
||||
return IRC_WriteStrClient( from, RPL_ENDOFWHOIS_MSG, Client_ID( from ), Client_ID( c ));
|
||||
return IRC_WriteStrClient(from, RPL_ENDOFWHOIS_MSG,
|
||||
Client_ID(from), Client_ID(c));
|
||||
} /* IRC_WHOIS_SendReply */
|
||||
|
||||
|
||||
/**
|
||||
* Handler for the IRC "WHOIS" command.
|
||||
*
|
||||
* See RFC 2812, 3.6.2 "Whois query".
|
||||
*
|
||||
* @param Client The client from which this command has been received.
|
||||
* @param Req Request structure with prefix and all parameters.
|
||||
* @return CONNECTED or DISCONNECTED.
|
||||
*/
|
||||
GLOBAL bool
|
||||
IRC_WHOIS( CLIENT *Client, REQUEST *Req )
|
||||
{
|
||||
CLIENT *from, *target, *c;
|
||||
unsigned int match_count = 0, found = 0;
|
||||
bool has_wildcards, is_remote;
|
||||
bool got_wildcard = false;
|
||||
const char *query;
|
||||
|
||||
assert( Client != NULL );
|
||||
assert( Req != NULL );
|
||||
|
||||
/* Bad number of parameters? */
|
||||
if (Req->argc < 1 || Req->argc > 2)
|
||||
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
|
||||
Client_ID(Client), Req->command);
|
||||
|
||||
/* Search sender of the WHOIS */
|
||||
if (Client_Type(Client) == CLIENT_SERVER) {
|
||||
from = Client_Search(Req->prefix);
|
||||
} else {
|
||||
IRC_SetPenalty(Client, 1);
|
||||
from = Client;
|
||||
}
|
||||
if (!from)
|
||||
return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG,
|
||||
Client_ID(Client), Req->prefix);
|
||||
|
||||
/* Get target server for this command */
|
||||
if (Req->argc > 1) {
|
||||
/* Search the target server, which can be specified as a
|
||||
* nick name on that server as well: */
|
||||
target = Client_Search(Req->argv[0]);
|
||||
if (!target)
|
||||
return IRC_WriteStrClient(from, ERR_NOSUCHSERVER_MSG,
|
||||
Client_ID(from), Req->argv[0]);
|
||||
} else
|
||||
target = Client_ThisServer();
|
||||
assert(target != NULL);
|
||||
|
||||
/* Forward to other server? */
|
||||
if (Client_NextHop(target) != Client_ThisServer() &&
|
||||
Client_Type(Client_NextHop(target)) == CLIENT_SERVER)
|
||||
return IRC_WriteStrClientPrefix(target, from,
|
||||
"WHOIS %s :%s",
|
||||
Req->argv[0], Req->argv[1]);
|
||||
|
||||
is_remote = Client_Conn(from) < 0;
|
||||
for (query = strtok(Req->argv[Req->argc - 1], ",");
|
||||
query && found < 3;
|
||||
query = strtok(NULL, ","), found++)
|
||||
{
|
||||
has_wildcards = query[strcspn(query, "*?")] != 0;
|
||||
/*
|
||||
* follows ircd 2.10 implementation:
|
||||
* - handle up to 3 targets
|
||||
* - no wildcards for remote clients
|
||||
* - only one wildcard target per local client
|
||||
*
|
||||
* also, at most ten matches are returned.
|
||||
*/
|
||||
if (!has_wildcards || is_remote) {
|
||||
c = Client_Search(query);
|
||||
if (c) {
|
||||
if (!IRC_WHOIS_SendReply(Client, from, c))
|
||||
return DISCONNECTED;
|
||||
} else {
|
||||
if (!IRC_WriteStrClient(Client,
|
||||
ERR_NOSUCHNICK_MSG,
|
||||
Client_ID(Client),
|
||||
query))
|
||||
return DISCONNECTED;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (got_wildcard) {
|
||||
/* we already handled one wildcard query */
|
||||
if (!IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG,
|
||||
Client_ID(Client), query))
|
||||
return DISCONNECTED;
|
||||
continue;
|
||||
}
|
||||
got_wildcard = true;
|
||||
IRC_SetPenalty(Client, 3);
|
||||
|
||||
for (c = Client_First(); c && match_count < 10; c = Client_Next(c)) {
|
||||
if (Client_Type(c) != CLIENT_USER)
|
||||
continue;
|
||||
if (!MatchCaseInsensitive(query, Client_ID(c)))
|
||||
continue;
|
||||
if (!IRC_WHOIS_SendReply(Client, from, c))
|
||||
return DISCONNECTED;
|
||||
match_count++;
|
||||
}
|
||||
|
||||
if (match_count == 0)
|
||||
return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG,
|
||||
Client_ID(Client), Req->argv[Req->argc - 1]);
|
||||
}
|
||||
return CONNECTED;
|
||||
} /* IRC_WHOIS */
|
||||
|
||||
|
||||
|
|
|
@ -683,6 +683,29 @@ IRC_QUIT( CLIENT *Client, REQUEST *Req )
|
|||
} /* IRC_QUIT */
|
||||
|
||||
|
||||
#ifndef STRICT_RFC
|
||||
|
||||
/**
|
||||
* Handler for HTTP command, e.g. GET and POST
|
||||
*
|
||||
* We handle these commands here to avoid the quite long timeout when
|
||||
* some user tries to access this IRC daemon using an web browser ...
|
||||
*
|
||||
* @param Client The client from which this command has been received.
|
||||
* @param Req Request structure with prefix and all parameters.
|
||||
* @returns CONNECTED or DISCONNECTED.
|
||||
*/
|
||||
GLOBAL bool
|
||||
IRC_QUIT_HTTP( CLIENT *Client, REQUEST *Req )
|
||||
{
|
||||
Req->argc = 1;
|
||||
Req->argv[0] = "Oops, HTTP request received? This is IRC!";
|
||||
return IRC_QUIT(Client, Req);
|
||||
} /* IRC_QUIT_HTTP */
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Handler for the IRC "PING" command.
|
||||
*
|
||||
|
|
|
@ -25,6 +25,7 @@ GLOBAL bool IRC_WEBIRC PARAMS((CLIENT *Client, REQUEST *Req));
|
|||
GLOBAL bool IRC_PING PARAMS((CLIENT *Client, REQUEST *Req));
|
||||
GLOBAL bool IRC_PONG PARAMS((CLIENT *Client, REQUEST *Req));
|
||||
GLOBAL bool IRC_QUIT PARAMS((CLIENT *Client, REQUEST *Req));
|
||||
GLOBAL bool IRC_QUIT_HTTP PARAMS((CLIENT *Client, REQUEST *Req));
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -108,6 +108,10 @@ static COMMAND My_Commands[] =
|
|||
{ "WHOWAS", IRC_WHOWAS, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
|
||||
#ifdef IRCPLUS
|
||||
{ "CHANINFO", IRC_CHANINFO, CLIENT_SERVER, 0, 0, 0 },
|
||||
#endif
|
||||
#ifndef STRICT_RFC
|
||||
{ "GET", IRC_QUIT_HTTP, CLIENT_UNKNOWN, 0, 0, 0 },
|
||||
{ "POST", IRC_QUIT_HTTP, CLIENT_UNKNOWN, 0, 0, 0 },
|
||||
#endif
|
||||
{ NULL, NULL, 0x0, 0, 0, 0 } /* Ende-Marke */
|
||||
};
|
||||
|
|
|
@ -11,6 +11,7 @@ mode-test
|
|||
opless-channel-test
|
||||
server-link-test
|
||||
who-test
|
||||
whois-test
|
||||
ngircd-test1.log
|
||||
ngircd-test2.log
|
||||
ngircd-test1.motd
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#
|
||||
# ngIRCd -- The Next Generation IRC Daemon
|
||||
# Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
|
||||
# Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors.
|
||||
#
|
||||
# Dieses Programm ist freie Software. Sie koennen es unter den Bedingungen
|
||||
# der GNU General Public License (GPL), wie von der Free Software Foundation
|
||||
|
@ -20,7 +20,7 @@ EXTRA_DIST = \
|
|||
test-loop.sh wait-tests.sh \
|
||||
channel-test.e connect-test.e check-idle.e invite-test.e \
|
||||
join-test.e kick-test.e message-test.e misc-test.e mode-test.e \
|
||||
opless-channel-test.e server-link-test.e who-test.e \
|
||||
opless-channel-test.e server-link-test.e who-test.e whois-test.e \
|
||||
stress-A.e stress-B.e \
|
||||
start-server1 stop-server1 ngircd-test1.conf \
|
||||
start-server2 stop-server2 ngircd-test2.conf
|
||||
|
@ -85,6 +85,10 @@ who-test: tests.sh
|
|||
rm -f who-test
|
||||
ln -s $(srcdir)/tests.sh who-test
|
||||
|
||||
whois-test: tests.sh
|
||||
rm -f whois-test
|
||||
ln -s $(srcdir)/tests.sh whois-test
|
||||
|
||||
TESTS = start-server1 \
|
||||
connect-test \
|
||||
start-server2 \
|
||||
|
@ -97,6 +101,7 @@ TESTS = start-server1 \
|
|||
mode-test \
|
||||
opless-channel-test \
|
||||
who-test \
|
||||
whois-test \
|
||||
server-link-test \
|
||||
stop-server2 \
|
||||
stress-server.sh \
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
# ngIRCd test suite
|
||||
# WHOIS test
|
||||
|
||||
spawn telnet localhost 6789
|
||||
expect {
|
||||
timeout { exit 1 }
|
||||
"Connected"
|
||||
}
|
||||
|
||||
send "nick nick\r"
|
||||
send "user user . . :Real Name\r"
|
||||
expect {
|
||||
timeout { exit 1 }
|
||||
"376"
|
||||
}
|
||||
|
||||
send "whois nick\r"
|
||||
expect {
|
||||
timeout { exit 1 }
|
||||
"311 nick nick ~user localhost \* :Real Name\r"
|
||||
}
|
||||
|
||||
send "whois *\r"
|
||||
expect {
|
||||
timeout { exit 1 }
|
||||
"311 nick nick ~user localhost \* :Real Name\r"
|
||||
}
|
||||
|
||||
send "whois n*\r"
|
||||
expect {
|
||||
timeout { exit 1 }
|
||||
"311 nick nick ~user localhost \* :Real Name\r"
|
||||
}
|
||||
|
||||
send "whois ?ick\r"
|
||||
expect {
|
||||
timeout { exit 1 }
|
||||
"311 nick nick ~user localhost \* :Real Name\r"
|
||||
}
|
||||
|
||||
send "whois ????,n?*k\r"
|
||||
expect {
|
||||
timeout { exit 1 }
|
||||
"311 nick nick ~user localhost \* :Real Name\r"
|
||||
}
|
||||
|
||||
send "quit\r"
|
||||
expect {
|
||||
timeout { exit 1 }
|
||||
"ERROR"
|
||||
}
|
||||
|
||||
# -eof-
|
Loading…
Reference in New Issue