]> arthur.barton.de Git - ngircd.git/commitdiff
Merge branch 'xop' of https://github.com/kart0ffelsack/ngircd into bug92-xop
authorAlexander Barton <alex@barton.de>
Tue, 11 Sep 2012 10:30:19 +0000 (12:30 +0200)
committerAlexander Barton <alex@barton.de>
Tue, 11 Sep 2012 10:30:19 +0000 (12:30 +0200)
* 'xop' of https://github.com/kart0ffelsack/ngircd:
  Tests and documentation for xop
  Implemented xop support

Conflicts (because of merge of the 'cmode-M' branch):
src/ngircd/channel.c
src/ngircd/defines.h
src/ngircd/messages.h

35 files changed:
ChangeLog
NEWS
README
configure.in
contrib/Debian/control
contrib/MacOSX/ngIRCd.xcodeproj/project.pbxproj
contrib/Makefile.am
contrib/ngircd.service [new file with mode: 0644]
contrib/ngircd.spec
doc/Makefile.am
doc/Modes.txt
doc/sample-ngircd.conf.tmpl
man/ngircd.conf.5.tmpl
src/ngircd/channel.c
src/ngircd/client.c
src/ngircd/client.h
src/ngircd/conf.c
src/ngircd/conf.h
src/ngircd/conn-ssl.c
src/ngircd/conn.c
src/ngircd/conn.h
src/ngircd/defines.h
src/ngircd/io.c
src/ngircd/irc-cap.c
src/ngircd/irc-info.c
src/ngircd/irc-login.c
src/ngircd/irc-mode.c
src/ngircd/irc-server.c
src/ngircd/irc.c
src/ngircd/login.c
src/ngircd/match.c
src/ngircd/match.h
src/ngircd/messages.h
src/ngircd/pam.c
src/tool/tool.c

index 1745ea46b86e738c4df0aebedec4034e68ce46c3..9e8d5941ef1b7fdb592f831701aca2b5e55602e4 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -9,6 +9,15 @@
                                -- ChangeLog --
 
 
+ngIRCd
+
+  - Implemented hashed cloaked hostnames for both the "CloakHost" and
+    "CloakHostModeX" configuration options: now the admin can use the new
+    '%x' placeholder to insert a hashed version of the clients hostname,
+    and the new configuration option "CloakHostSalt" defines the salt for
+    the hash function. When "CloakHostSalt" is not set (the default), a
+    random salt will be generated after each server restart.
+
 ngIRCd Release 19.2 (2012-06-19)
 
   - doc/Capabilities.txt: document "multi-prefix" capability
diff --git a/NEWS b/NEWS
index ab0ac1955e5768ea040181f674c6b4ceae6cd57b..46c8b09f937028f4a8904cd0344e27c8f7378fb4 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -9,6 +9,15 @@
                                   -- NEWS --
 
 
+ngIRCd
+
+  - Implemented hashed cloaked hostnames for both the "CloakHost" and
+    "CloakHostModeX" configuration options: now the admin can use the new
+    '%x' placeholder to insert a hashed version of the clients hostname,
+    and the new configuration option "CloakHostSalt" defines the salt for
+    the hash function. When "CloakHostSalt" is not set (the default), a
+    random salt will be generated after each server restart.
+
 ngIRCd Release 19.2 (2012-06-19)
 
   ngIRCd 19.2~rc1 (2012-06-13)
diff --git a/README b/README
index 2e19d831deac91663730963afba874b0f52dd736..11d140d6464b7fb780fa79d9f7c3fa96b2197306 100644 (file)
--- a/README
+++ b/README
 I. Introduction
 ~~~~~~~~~~~~~~~
 
-ngIRCd is an Open Source server for the Internet Relay Chat (IRC), which
-is developed and published under the terms of the GNU General Public
-Licence, see the file COPYING for details. ngIRCd means "next generation
-IRC daemon" (which is a little bit exaggerated, "lightweight Internet Relay
-Chat server" would be better), it's written from scratch and not deduced
-from the "grandfather of IRC daemons", the daemon of the IRCNet.
+ngIRCd is a free, portable and lightweight Internet Relay Chat server for
+small or private networks, developed under the GNU General Public License
+(GPL; please see the file COPYING for details). It is simple to configure,
+can cope with dynamic IP addresses, and supports IPv6 as well as SSL. It is
+written from scratch and not based on the original IRCd.
+
+The name ngIRCd means next generation IRC daemon, which is a little bit
+exaggerated: lightweight Internet Relay Chat server most probably would be a
+better name :-)
 
 Please see the INSTALL document for installation and upgrade information!
 
index fb0877839383b7611adb7548d511938351327d79..52435fd4df7b419f98de0b0305447ee75a1b9867 100644 (file)
@@ -1,6 +1,6 @@
 #
 # ngIRCd -- The Next Generation IRC Daemon
-# Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors
+# Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -18,7 +18,7 @@ AC_INIT(ngircd, VERSION_ID)
 AC_CONFIG_SRCDIR(src/ngircd/ngircd.c)
 AC_CANONICAL_TARGET
 AM_INIT_AUTOMAKE(1.6)
-AM_CONFIG_HEADER(src/config.h)
+AC_CONFIG_HEADER(src/config.h)
 
 m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
 
index 0ac6d22a47446749ef69b78b37686d23a779ea64..d6cf418c15202f1227eb337fe6df94237ae49758 100644 (file)
@@ -18,11 +18,11 @@ Architecture: any
 Depends: ${shlibs:Depends}, ${misc:Depends}
 Provides: ircd
 Description: lightweight Internet Relay Chat server
- This package provides ngIRCd, a lightweight Internet Relay Chat
- server for small or private networks. It is simple to configure, can
- cope with dynamic IP addresses, and supports IPv6 as well as SSL. It
- is written from scratch, not based on the original IRCd and quite
portable.
+ This package provides ngIRCd, a portable and lightweight Internet Relay
+ Chat server for small or private networks, developed under the GNU
+ General Public License (GPL). It is simple to configure, can cope with
+ dynamic IP addresses, and supports IPv6 as well as SSL. It is written
from scratch and not based on the original IRCd.
  .
  This package contains the "standard distribution", including support for
  syslog logging and compressed server-links using zlib. Please have a look
@@ -35,11 +35,11 @@ Depends: ${shlibs:Depends}, ${misc:Depends}
 Provides: ircd
 Conflicts: ngircd, ngircd-dbg
 Description: lightweight Internet Relay Chat server
- This package provides ngIRCd, a lightweight Internet Relay Chat
- server for small or private networks. It is simple to configure, can
- cope with dynamic IP addresses, and supports IPv6 as well as SSL. It
- is written from scratch, not based on the original IRCd and quite
portable.
+ This package provides ngIRCd, a portable and lightweight Internet Relay
+ Chat server for small or private networks, developed under the GNU
+ General Public License (GPL). It is simple to configure, can cope with
+ dynamic IP addresses, and supports IPv6 as well as SSL. It is written
from scratch and not based on the original IRCd.
  .
  In addition to the features of the "standard package", this package
  includes support for TCP wrappers, IDENT requests, the IPv6 protocol and
@@ -51,11 +51,11 @@ Depends: ${shlibs:Depends}, ${misc:Depends}
 Provides: ircd
 Conflicts: ngircd, ngircd-full
 Description: lightweight Internet Relay Chat server
- This package provides ngIRCd, a lightweight Internet Relay Chat
- server for small or private networks. It is simple to configure, can
- cope with dynamic IP addresses, and supports IPv6 as well as SSL. It
- is written from scratch, not based on the original IRCd and quite
portable.
+ This package provides ngIRCd, a portable and lightweight Internet Relay
+ Chat server for small or private networks, developed under the GNU
+ General Public License (GPL). It is simple to configure, can cope with
+ dynamic IP addresses, and supports IPv6 as well as SSL. It is written
from scratch and not based on the original IRCd.
  .
  In addition to the features of the "standard package", this package
  includes support for TCP wrappers, IDENT requests, the IPv6 protocol and
index 6da1cb3e1e9cac2baa588f56c3572671b0ff96bb..ac3f6235381cea4879e4b0c09a1fee324ee93777 100644 (file)
                        isa = XCBuildConfiguration;
                        buildSettings = {
                                ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
+                               CODE_SIGN_IDENTITY = "Developer ID Application: Alexander Barton";
                                GCC_VERSION = 4.2;
                                GCC_WARN_ABOUT_RETURN_TYPE = YES;
                                GCC_WARN_UNUSED_VARIABLE = YES;
index 36ba245806f7cbd688a44d29a4a3e708df47ee62..99ab68446a4bfb15ede491f7a372492b1d4ad652 100644 (file)
 
 SUBDIRS = Anope Debian MacOSX
 
-EXTRA_DIST = README ngircd.spec systrace.policy ngindent ngircd-bsd.sh \
-       ngIRCd-Logo.gif ngircd-redhat.init platformtest.sh
+EXTRA_DIST = README \
+       ngindent \
+       ngircd-bsd.sh \
+       ngIRCd-Logo.gif \
+       ngircd-redhat.init \
+       ngircd.service \
+       ngircd.spec \
+       platformtest.sh \
+       systrace.policy
 
 maintainer-clean-local:
        rm -f Makefile Makefile.in
diff --git a/contrib/ngircd.service b/contrib/ngircd.service
new file mode 100644 (file)
index 0000000..b5bab06
--- /dev/null
@@ -0,0 +1,11 @@
+[Unit]
+Description=Next Generation IRC Daemon
+After=network.target
+
+[Service]
+# don't daemonize to simplify stuff
+ExecStart=/usr/sbin/ngircd -n
+ExecReload=/bin/kill -HUP $MAINPID
+
+[Install]
+WantedBy=multi-user.target
index 2041aa08b0e84cf57d0c69543070c4103e7e97c1..aeb10f2aa7604f54b0c1cfce6dd765d647eb2e18 100644 (file)
@@ -15,11 +15,11 @@ BuildRoot:    %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 BuildRequires:  zlib-devel, openssl-devel
 
 %description
-This package provides ngIRCd, a lightweight Internet Relay Chat
-server for small or private networks. It is simple to configure, can
-cope with dynamic IP addresses, and supports IPv6 as well as SSL. It
-is written from scratch, not based on the original IRCd and quite
-portable.
+This package provides ngIRCd, a portable and lightweight Internet Relay
+Chat server for small or private networks, developed under the GNU
+General Public License (GPL). It is simple to configure, can cope with
+dynamic IP addresses, and supports IPv6 as well as SSL. It is written
+from scratch and not based on the original IRCd.
 
 Advantages:
  - well arranged (lean) configuration file
index 92e019b832ad1bcd00b3ca0bdd4f4fe929a72472..3bf68fb4a22991bfde217b124b956d80d4f4907b 100644 (file)
@@ -52,8 +52,8 @@ all: $(generated_docs)
 
 install-data-hook: $(static_docs) $(toplevel_docs) $(generated_docs)
        $(mkinstalldirs) $(DESTDIR)$(sysconfdir)
-       if [ ! -f $(DESTDIR)$(sysconfdir)/ngircd.conf ]; then \
-         $(INSTALL) -m 600 -c sample-ngircd.conf $(DESTDIR)$(sysconfdir)/ngircd.conf; \
+       @if [ ! -f $(DESTDIR)$(sysconfdir)/ngircd.conf ]; then \
+         make install-config; \
         fi
        $(mkinstalldirs) $(DESTDIR)$(docdir)
        for f in $(static_docs) $(toplevel_docs); do \
@@ -63,10 +63,30 @@ install-data-hook: $(static_docs) $(toplevel_docs) $(generated_docs)
          $(INSTALL) -m 644 -c $$f $(DESTDIR)$(docdir)/; \
         done
 
+install-config:
+       $(INSTALL) -m 600 -c sample-ngircd.conf $(DESTDIR)$(sysconfdir)/ngircd.conf
+       @echo; \
+        echo " ** NOTE: Installed sample configuration file:"; \
+        echo " ** \"$(DESTDIR)$(sysconfdir)/ngircd.conf\""; \
+        echo
+
 uninstall-hook:
        rm -rf $(DESTDIR)$(docdir)
+       @if cmp --silent sample-ngircd.conf $(DESTDIR)$(sysconfdir)/ngircd.conf; then \
+         make uninstall-config; \
+        else \
+         echo; \
+         echo " ** NOTE: Not uninstalling changed configuration file:"; \
+         echo " ** \"$(DESTDIR)$(sysconfdir)/ngircd.conf\""; \
+         echo; \
+        fi
+
+uninstall-config:
+       rm -f $(DESTDIR)$(sysconfdir)/ngircd.conf
 
 srcdoc:
        make -C src srcdoc
 
+.PHONY: install-config uninstall-config srcdoc
+
 # -eof-
index d61bd2d02e4612f325140e369700dabe8924f959..dec80ce819756e3576ee6d70dfe39e21fe676379 100644 (file)
@@ -2,7 +2,7 @@
                      ngIRCd - Next Generation IRC Server
                            http://ngircd.barton.de/
 
-               (c)2001-2011 Alexander Barton and Contributors.
+               (c)2001-2012 Alexander Barton and Contributors.
                ngIRCd is free software and published under the
                    terms of the GNU General Public License.
 
@@ -22,6 +22,7 @@ channels he is using at the moment.
   mode since   description
 
   a    0.3.0   User is away.
+  B    20      User is flagged as a "bot".
   c    17      IRC operator wants to receive connect/disconnect NOTICEs.
   C    19      Only users that share a channel are allowed to send messages.
   i    0.0.1   User is "invisible".
@@ -49,6 +50,7 @@ users to lists (e.g. "invite list", "ban list"), others have parameters
   k    0.6.0   Channel has a "key" (a password).
   l    0.6.0   Channel has a user limit.
   m    0.3.0   Channel is moderated, only "voiced" users can send messages.
+  M    20      Only registered users (and IRC Ops) can send messages.
   n    0.3.0   Channel doesn't allow messages of users not being members.
   O    18      Only IRC operators are allowed to join this channel.
   P    0.5.0   Channel is "persistent".
index 6d9d77098641ec4459375d56eb2a5a0d405dbd92..57e65892054b9bd20c1d2cc309dd9ccaca1c1a41 100644 (file)
        # Connect to the remote server using TLS/SSL (Default: false)
        ;SSLConnect = yes
 
-       # Define a (case insensitive) mask matching nick names that should be
-       # treated as IRC services when introduced via this remote server.
+       # Define a (case insensitive) list of masks matching nick names that
+       # should be treated as IRC services when introduced via this remote
+       # server, separated by commas (",").
        # REGULAR SERVERS DON'T NEED this parameter, so leave it empty
        # (which is the default).
        # When you are connecting IRC services which mask as a IRC server
        # and which use "virtual users" to communicate with, for example
        # "NickServ" and "ChanServ", you should set this parameter to
-       # something like "*Serv".
-       ;ServiceMask = *Serv
+       # something like "*Serv" or "NickServ,ChanServ,XyzServ".
+       ;ServiceMask = *Serv,Global
 
 [Server]
        # More [Server] sections, if you like ...
index 71f0007851e738222ed7064b71921d4bb09cd097..aff11a67bf86ec6c79d0daae9cfadeff345662f2 100644 (file)
@@ -422,14 +422,16 @@ You can use the IRC Operator command CONNECT later on to create the link.
 Connect to the remote server using TLS/SSL. Default: false.
 .TP
 \fBServiceMask\fR (string)
-Define a (case insensitive) mask matching nick names that should be treated as
-IRC services when introduced via this remote server. REGULAR SERVERS DON'T NEED
-this parameter, so leave it empty (which is the default).
+Define a (case insensitive) list of masks matching nick names that should be
+treated as IRC services when introduced via this remote server, separated
+by commas (","). REGULAR SERVERS DON'T NEED this parameter, so leave it empty
+(which is the default).
 .PP
 .RS
 When you are connecting IRC services which mask as a IRC server and which use
 "virtual users" to communicate with, for example "NickServ" and "ChanServ",
-you should set this parameter to something like "*Serv".
+you should set this parameter to something like "*Serv", "*Serv,OtherNick",
+or "NickServ,ChanServ,XyzServ".
 .SH [CHANNEL]
 Pre-defined channels can be configured in
 .I [Channel]
index 90d2efab3e191f7ef1f3931bb1f2de6e90e5837d..8d001a825c013e8c77e339f5915a54eac792b6fa 100644 (file)
@@ -66,16 +66,8 @@ static void Set_KeyFile PARAMS((CHANNEL *Chan, const char *KeyFile));
 GLOBAL void
 Channel_Init( void )
 {
-       CHANNEL *sc;
-
        My_Channels = NULL;
        My_Cl2Chan = NULL;
-
-       sc = Channel_Create("&SERVER");
-       if (sc) {
-               Channel_SetModes(sc, "mnPt");
-               Channel_SetTopic(sc, Client_ThisServer(), "Server Messages");
-       }
 } /* Channel_Init */
 
 
@@ -103,11 +95,12 @@ Channel_GetListInvites(CHANNEL *c)
 }
 
 
+/**
+ * Generate predefined persistent channels and &SERVER
+ */
 GLOBAL void
 Channel_InitPredefined( void )
 {
-       /* Generate predefined persistent channels */
-
        CHANNEL *new_chan;
        const struct Conf_Channel *conf_chan;
        const char *c;
@@ -160,6 +153,18 @@ Channel_InitPredefined( void )
        }
        if (channel_count)
                array_free(&Conf_Channels);
+
+       /* Make sure the local &SERVER channel exists */
+       if (!Channel_Search("&SERVER")) {
+               new_chan = Channel_Create("&SERVER");
+               if (new_chan) {
+                       Channel_SetModes(new_chan, "mnPt");
+                       Channel_SetTopic(new_chan, Client_ThisServer(),
+                                        "Server Messages");
+               } else
+                       Log(LOG_ERR, "Failed to create \"&SERVER\" channel!");
+       } else
+               LogDebug("Required channel \"&SERVER\" already exists, ok.");
 } /* Channel_InitPredefined */
 
 
@@ -877,6 +882,10 @@ Can_Send_To_Channel(CHANNEL *Chan, CLIENT *From)
        if (strchr(Channel_Modes(Chan), 'n') && !is_member)
                return false;
 
+       if (strchr(Channel_Modes(Chan), 'M') && !Client_HasMode(From, 'R')
+           && !Client_HasMode(From, 'o'))
+               return false;
+
        if (has_voice || is_halfop || is_op || is_chanadmin || is_owner)
                return true;
 
index 49e273950ea6aeb955e909b1764021970b4fe982..4728c7a4672ac802d944dc599d23031f75e50d60 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * ngIRCd -- The Next Generation IRC Daemon
- * Copyright (c)2001-2010 Alexander Barton (alex@barton.de)
+ * Copyright (c)2001-2012 Alexander Barton (alex@barton.de)
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -440,18 +440,6 @@ Client_SetFlags( CLIENT *Client, const char *Flags )
 } /* Client_SetFlags */
 
 
-GLOBAL void
-Client_SetPassword( CLIENT *Client, const char *Pwd )
-{
-       /* set password sent by client */
-
-       assert( Client != NULL );
-       assert( Pwd != NULL );
-
-       strlcpy(Client->pwd, Pwd, sizeof(Client->pwd));
-} /* Client_SetPassword */
-
-
 GLOBAL void
 Client_SetAway( CLIENT *Client, const char *Txt )
 {
@@ -699,27 +687,36 @@ Client_Hostname(CLIENT *Client)
 
 /**
  * Get potentially cloaked hostname of a client.
+ *
  * If the client has not enabled cloaking, the real hostname is used.
+ * Please note that this function uses a global static buffer, so you can't
+ * nest invocations without overwriting earlier results!
+ *
  * @param Client Pointer to client structure
  * @return Pointer to client hostname
  */
 GLOBAL char *
 Client_HostnameCloaked(CLIENT *Client)
 {
+       static char Cloak_Buffer[CLIENT_HOST_LEN];
+
        assert(Client != NULL);
-       if (Client_HasMode(Client, 'x'))
-               return Client_ID(Client->introducer);
-       else
+
+       if (!Client_HasMode(Client, 'x'))
                return Client_Hostname(Client);
-} /* Client_HostnameCloaked */
 
+       /* Do simple mapping to the server ID? */
+       if (!*Conf_CloakHostModeX)
+               return Client_ID(Client->introducer);
 
-GLOBAL char *
-Client_Password( CLIENT *Client )
-{
-       assert( Client != NULL );
-       return Client->pwd;
-} /* Client_Password */
+       strlcpy(Cloak_Buffer, Client->host, CLIENT_HOST_LEN);
+       strlcat(Cloak_Buffer, Conf_CloakHostSalt, CLIENT_HOST_LEN);
+
+       snprintf(Cloak_Buffer, CLIENT_HOST_LEN, Conf_CloakHostModeX,
+                Hash(Cloak_Buffer));
+
+       return Cloak_Buffer;
+} /* Client_HostnameCloaked */
 
 
 GLOBAL char *
@@ -812,10 +809,12 @@ Client_Mask( CLIENT *Client )
 
 /**
  * Return ID of a client with cloaked hostname: "client!user@server-name"
+ *
  * This client ID is used for IRC prefixes, for example.
  * Please note that this function uses a global static buffer, so you can't
  * nest invocations without overwriting earlier results!
  * If the client has not enabled cloaking, the real hostname is used.
+ *
  * @param Client Pointer to client structure
  * @return Pointer to global buffer containing the client ID
  */
@@ -823,7 +822,6 @@ GLOBAL char *
 Client_MaskCloaked(CLIENT *Client)
 {
        static char Mask_Buffer[GETID_LEN];
-       char Cloak_Buffer[GETID_LEN];
 
        assert (Client != NULL);
 
@@ -831,16 +829,8 @@ Client_MaskCloaked(CLIENT *Client)
        if (!Client_HasMode(Client, 'x'))
                return Client_Mask(Client);
 
-       if(*Conf_CloakHostModeX) {
-               strlcpy(Cloak_Buffer, Client->host, GETID_LEN);
-               strlcat(Cloak_Buffer, Conf_CloakHostSalt, GETID_LEN);
-               snprintf(Cloak_Buffer, GETID_LEN, Conf_CloakHostModeX, Hash(Cloak_Buffer));
-       } else {
-               strncpy(Cloak_Buffer, Client_ID(Client->introducer), GETID_LEN);
-       }
-
-       snprintf(Mask_Buffer, GETID_LEN, "%s!%s@%s",
-               Client->id, Client->user, Cloak_Buffer);
+       snprintf(Mask_Buffer, GETID_LEN, "%s!%s@%s", Client->id, Client->user,
+                Client_HostnameCloaked(Client));
 
        return Mask_Buffer;
 } /* Client_MaskCloaked */
@@ -905,6 +895,16 @@ Client_CheckNick(CLIENT *Client, char *Nick)
                return false;
        }
 
+       if (Client_Type(Client) != CLIENT_SERVER
+           && Client_Type(Client) != CLIENT_SERVICE) {
+               /* Make sure that this isn't a restricted/forbidden nick name */
+               if (Conf_NickIsBlocked(Nick)) {
+                       IRC_WriteStrClient(Client, ERR_FORBIDDENNICKNAME_MSG,
+                                          Client_ID(Client), Nick);
+                       return false;
+               }
+       }
+
        /* Nickname already registered? */
        if (Client_Search(Nick)) {
                IRC_WriteStrClient(Client, ERR_NICKNAMEINUSE_MSG,
@@ -1175,7 +1175,7 @@ Client_Introduce(CLIENT *From, CLIENT *Client, int Type)
        Client_SetType(Client, Type);
 
        if (From) {
-               if (Conf_IsService(Conf_GetServer(Client_Conn(From)),
+               if (Conf_NickIsService(Conf_GetServer(Client_Conn(From)),
                                   Client_ID(Client)))
                        Client_SetType(Client, CLIENT_SERVICE);
                LogDebug("%s \"%s\" (+%s) registered (via %s, on %s, %d hop%s).",
index 4dbcc7a072232eacfe7cf45020cd2136fb774eb2..16b2a61ab8564808ad6c58066898602e30431cab 100644 (file)
@@ -47,7 +47,6 @@ typedef struct _CLIENT
        CONN_ID conn_id;                /* ID of the connection (if local) or NONE (remote) */
        struct _CLIENT *introducer;     /* ID of the servers which the client is connected to */
        struct _CLIENT *topserver;      /* toplevel servers (only valid if client is a server) */
-       char pwd[CLIENT_PASS_LEN];      /* password received of the client */
        char host[CLIENT_HOST_LEN];     /* hostname of the client */
        char user[CLIENT_USER_LEN];     /* user name ("login") */
 #if defined(PAM) && defined(IDENTAUTH)
@@ -109,7 +108,6 @@ GLOBAL char *Client_OrigUser PARAMS(( CLIENT *Client ));
 #endif
 GLOBAL char *Client_Hostname PARAMS(( CLIENT *Client ));
 GLOBAL char *Client_HostnameCloaked PARAMS(( CLIENT *Client ));
-GLOBAL char *Client_Password PARAMS(( CLIENT *Client ));
 GLOBAL char *Client_Modes PARAMS(( CLIENT *Client ));
 GLOBAL char *Client_Flags PARAMS(( CLIENT *Client ));
 GLOBAL CLIENT *Client_Introducer PARAMS(( CLIENT *Client ));
@@ -129,7 +127,6 @@ GLOBAL void Client_SetID PARAMS(( CLIENT *Client, const char *Nick ));
 GLOBAL void Client_SetUser PARAMS(( CLIENT *Client, const char *User, bool Idented ));
 GLOBAL void Client_SetOrigUser PARAMS(( CLIENT *Client, const char *User ));
 GLOBAL void Client_SetInfo PARAMS(( CLIENT *Client, const char *Info ));
-GLOBAL void Client_SetPassword PARAMS(( CLIENT *Client, const char *Pwd ));
 GLOBAL void Client_SetType PARAMS(( CLIENT *Client, int Type ));
 GLOBAL void Client_SetHops PARAMS(( CLIENT *Client, int Hops ));
 GLOBAL void Client_SetToken PARAMS(( CLIENT *Client, int Token ));
index b09113730ef185dff831ca6a0392c4a8d757ddcf..627e6d3fbf22557d695478ffe2a507b5fafe2a4d 100644 (file)
@@ -346,7 +346,7 @@ Conf_Test( void )
 
        puts("[LIMITS]");
        printf("  ConnectRetry = %d\n", Conf_ConnectRetry);
-       printf("  MaxConnections = %ld\n", Conf_MaxConnections);
+       printf("  MaxConnections = %d\n", Conf_MaxConnections);
        printf("  MaxConnectionsIP = %d\n", Conf_MaxConnectionsIP);
        printf("  MaxJoins = %d\n", Conf_MaxJoins > 0 ? Conf_MaxJoins : -1);
        printf("  MaxNickLength = %u\n", Conf_MaxNickLength - 1);
@@ -636,14 +636,41 @@ Conf_AddServer(const char *Name, UINT16 Port, const char *Host,
 }
 
 /**
- * Check if the given nick name is an service.
+ * Check if the given nick name is reserved for services on a particular server.
  *
+ * @param ConfServer The server index to check.
+ * @param Nick The nick name to check.
  * @returns true if the given nick name belongs to an "IRC service".
  */
 GLOBAL bool
-Conf_IsService(int ConfServer, const char *Nick)
+Conf_NickIsService(int ConfServer, const char *Nick)
 {
-       return MatchCaseInsensitive(Conf_Server[ConfServer].svs_mask, Nick);
+       assert (ConfServer >= 0);
+       assert (ConfServer < MAX_SERVERS);
+
+       return MatchCaseInsensitiveList(Conf_Server[ConfServer].svs_mask,
+                                       Nick, ",");
+}
+
+/**
+ * Check if the given nick name is blocked for "normal client" use.
+ *
+ * @param ConfServer The server index or NONE to check all configured servers.
+ * @param Nick The nick name to check.
+ * @returns true if the given nick name belongs to an "IRC service".
+ */
+GLOBAL bool
+Conf_NickIsBlocked(const char *Nick)
+{
+       int i;
+
+       for(i = 0; i < MAX_SERVERS; i++) {
+               if (!Conf_Server[i].name[0])
+                       continue;
+               if (Conf_NickIsService(i, Nick))
+                       return true;
+       }
+       return false;
 }
 
 /**
@@ -653,7 +680,7 @@ static void
 Set_Defaults(bool InitServers)
 {
        int i;
-       char random[RANDOM_SALT_LEN];
+       char random[RANDOM_SALT_LEN + 1];
 
        /* Global */
        strcpy(Conf_ServerName, "");
@@ -1405,7 +1432,7 @@ Handle_LIMITS(int Line, char *Var, char *Arg)
                return;
        }
        if (strcasecmp(Var, "MaxConnections") == 0) {
-               Conf_MaxConnections = atol(Arg);
+               Conf_MaxConnections = atoi(Arg);
                if (!Conf_MaxConnections && strcmp(Arg, "0"))
                        Config_Error_NaN(Line, Var);
                return;
@@ -1884,6 +1911,13 @@ Validate_Config(bool Configtest, bool Rehash)
        bool config_valid = true;
        char *ptr;
 
+       /* Emit a warning when the config file is not a full path name */
+       if (NGIRCd_ConfFile[0] && NGIRCd_ConfFile[0] != '/') {
+               Config_Error(LOG_WARNING,
+                       "Not specifying a full path name to \"%s\" can cause problems when rehashing the server!",
+                       NGIRCd_ConfFile);
+       }
+
        /* Validate configured server name, see RFC 2812 section 2.3.1 */
        ptr = Conf_ServerName;
        do {
index 4e7e3796478d8f200b11661c4ade71488dcfbad3..7a4e38aa05b56a626a4aed84055a0e7d28fc081a 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * ngIRCd -- The Next Generation IRC Daemon
- * Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors.
+ * Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -206,7 +206,7 @@ GLOBAL bool Conf_ConnectIPv6;
 GLOBAL bool Conf_ConnectIPv4;
 
 /** Maximum number of simultaneous connections to this server */
-GLOBAL long Conf_MaxConnections;
+GLOBAL int Conf_MaxConnections;
 
 /** Maximum number of channels a user can join */
 GLOBAL int Conf_MaxJoins;
@@ -244,7 +244,8 @@ GLOBAL bool Conf_EnablePassiveServer PARAMS((const char *Name));
 GLOBAL bool Conf_DisableServer PARAMS(( const char *Name ));
 GLOBAL bool Conf_AddServer PARAMS(( const char *Name, UINT16 Port, const char *Host, const char *MyPwd, const char *PeerPwd ));
 
-GLOBAL bool Conf_IsService PARAMS((int ConfServer, const char *Nick));
+GLOBAL bool Conf_NickIsService PARAMS((int ConfServer, const char *Nick));
+GLOBAL bool Conf_NickIsBlocked PARAMS((const char *Nick));
 
 /* Password required by WEBIRC command */
 GLOBAL char Conf_WebircPwd[CLIENT_PASS_LEN];
index 5d44b30f07708e46d0221c4ba227f20f1bc7d853..8f7b70afccb0e310793013e0f53ee5f38522a614 100644 (file)
@@ -625,6 +625,8 @@ ConnectAccept( CONNECTION *c, bool connect)
 #endif /* _GNUTLS */
        Conn_OPTION_DEL(c, (CONN_SSL_WANT_WRITE|CONN_SSL_WANT_READ|CONN_SSL_CONNECT));
        ConnSSL_LogCertInfo(c);
+
+       Conn_StartLogin(CONNECTION2ID(c));
        return 1;
 }
 
index 06236fd43e2ab1269e91e1065efa11786da0ed40..81a0f4507eed0fb79d470bf323452bd1a328dd58 100644 (file)
@@ -88,7 +88,7 @@
 
 static bool Handle_Write PARAMS(( CONN_ID Idx ));
 static bool Conn_Write PARAMS(( CONN_ID Idx, char *Data, size_t Len ));
-static int New_Connection PARAMS(( int Sock ));
+static int New_Connection PARAMS(( int Sock, bool IsSSL ));
 static CONN_ID Socket2Index PARAMS(( int Sock ));
 static void Read_Request PARAMS(( CONN_ID Idx ));
 static unsigned int Handle_Buffer PARAMS(( CONN_ID Idx ));
@@ -134,7 +134,7 @@ static void
 cb_listen(int sock, short irrelevant)
 {
        (void) irrelevant;
-       (void) New_Connection(sock);
+       (void) New_Connection(sock, false);
 }
 
 
@@ -152,7 +152,7 @@ cb_listen_ssl(int sock, short irrelevant)
        int fd;
 
        (void) irrelevant;
-       fd = New_Connection(sock);
+       fd = New_Connection(sock, true);
        if (fd < 0)
                return;
        io_event_setcb(My_Connections[fd].sock, cb_clientserver_ssl);
@@ -918,6 +918,30 @@ va_dcl
        return ok;
 } /* Conn_WriteStr */
 
+GLOBAL char*
+Conn_Password( CONN_ID Idx )
+{
+       assert( Idx > NONE );
+       if (My_Connections[Idx].pwd == NULL)
+               return (char*)"\0";
+       else
+               return My_Connections[Idx].pwd;
+} /* Conn_Password */
+
+GLOBAL void
+Conn_SetPassword( CONN_ID Idx, const char *Pwd )
+{
+       assert( Idx > NONE );
+
+       if (My_Connections[Idx].pwd)
+               free(My_Connections[Idx].pwd);
+
+       My_Connections[Idx].pwd = strdup(Pwd);
+       if (My_Connections[Idx].pwd == NULL) {
+               Log(LOG_EMERG, "Can't allocate memory! [Conn_SetPassword]");
+               exit(1);
+       }
+} /* Conn_SetPassword */
 
 /**
  * Append Data to the outbound write buffer of a connection.
@@ -1146,6 +1170,8 @@ Conn_Close( CONN_ID Idx, const char *LogMsg, const char *FwdMsg, bool InformClie
 
        array_free(&My_Connections[Idx].rbuf);
        array_free(&My_Connections[Idx].wbuf);
+       if (My_Connections[Idx].pwd != NULL)
+               free(My_Connections[Idx].pwd);
 
        /* Clean up connection structure (=free it) */
        Init_Conn_Struct( Idx );
@@ -1336,17 +1362,18 @@ Count_Connections(ng_ipaddr_t *a)
  * Initialize new client connection on a listening socket.
  *
  * @param Sock Listening socket descriptor.
+ * @param IsSSL        true if this socket expects SSL-encrypted data.
  * @returns    Accepted socket descriptor or -1 on error.
  */
 static int
-New_Connection(int Sock)
+New_Connection(int Sock, bool IsSSL)
 {
 #ifdef TCPWRAP
        struct request_info req;
 #endif
        ng_ipaddr_t new_addr;
        char ip_str[NG_INET_ADDRSTRLEN];
-       int new_sock, new_sock_len, identsock;
+       int new_sock, new_sock_len;
        CLIENT *c;
        long cnt;
 
@@ -1466,30 +1493,56 @@ New_Connection(int Sock)
        Log(LOG_INFO, "Accepted connection %d from %s:%d on socket %d.",
            new_sock, My_Connections[new_sock].host,
            ng_ipaddr_getport(&new_addr), Sock);
+       Account_Connection();
+
+#ifdef SSL_SUPPORT
+       /* Delay connection initalization until SSL handshake is finished */
+       if (!IsSSL)
+#endif
+               Conn_StartLogin(new_sock);
+
+       return new_sock;
+} /* New_Connection */
+
+
+/**
+ * Finish connection initialization, start resolver subprocess.
+ *
+ * @param Idx Connection index.
+ */
+GLOBAL void
+Conn_StartLogin(CONN_ID Idx)
+{
+       int ident_sock = -1;
+
+       assert(Idx >= 0);
+
+       /* Nothing to do if DNS (and resolver subprocess) is disabled */
+       if (!Conf_DNS)
+               return;
 
-       identsock = new_sock;
 #ifdef IDENTAUTH
-       if (!Conf_Ident)
-               identsock = -1;
+       /* Should we make an IDENT request? */
+       if (Conf_Ident)
+               ident_sock = My_Connections[Idx].sock;
 #endif
-       if (Conf_DNS) {
-               if (Conf_NoticeAuth) {
+
+       if (Conf_NoticeAuth) {
+               /* Send "NOTICE AUTH" messages to the client */
 #ifdef IDENTAUTH
-                       if (Conf_Ident)
-                               (void)Conn_WriteStr(new_sock,
-                                       "NOTICE AUTH :*** Looking up your hostname and checking ident");
-                       else
+               if (Conf_Ident)
+                       (void)Conn_WriteStr(Idx,
+                               "NOTICE AUTH :*** Looking up your hostname and checking ident");
+               else
 #endif
-                               (void)Conn_WriteStr(new_sock,
-                                       "NOTICE AUTH :*** Looking up your hostname");
-               }
-               Resolve_Addr(&My_Connections[new_sock].proc_stat, &new_addr,
-                            identsock, cb_Read_Resolver_Result);
+                       (void)Conn_WriteStr(Idx,
+                               "NOTICE AUTH :*** Looking up your hostname");
+               (void)Handle_Write(Idx);
        }
 
-       Account_Connection();
-       return new_sock;
-} /* New_Connection */
+       Resolve_Addr(&My_Connections[Idx].proc_stat, &My_Connections[Idx].addr,
+                    ident_sock, cb_Read_Resolver_Result);
+}
 
 
 /**
@@ -1839,10 +1892,10 @@ Check_Connections(void)
                                if (My_Connections[i].lastping <
                                    time(NULL) - Conf_PongTimeout) {
                                        /* Timeout */
-                                       LogDebug
-                                           ("Connection %d: Ping timeout: %d seconds.",
-                                            i, Conf_PongTimeout);
-                                       snprintf(msg, sizeof(msg), "Ping timeout: %d seconds", Conf_PongTimeout);
+                                       snprintf(msg, sizeof(msg),
+                                                "Ping timeout: %d seconds",
+                                                Conf_PongTimeout);
+                                       LogDebug("Connection %d: %s.", i, msg);
                                        Conn_Close(i, NULL, msg, true);
                                }
                        } else if (My_Connections[i].lastdata <
@@ -2231,7 +2284,8 @@ cb_Read_Resolver_Result( int r_fd, UNUSED short events )
                Client_SetHostname(c, readbuf);
                if (Conf_NoticeAuth)
                        (void)Conn_WriteStr(i,
-                                       "NOTICE AUTH :*** Found your hostname");
+                                       "NOTICE AUTH :*** Found your hostname: %s",
+                                       My_Connections[i].host);
 #ifdef IDENTAUTH
                ++identptr;
                if (*identptr) {
@@ -2256,8 +2310,10 @@ cb_Read_Resolver_Result( int r_fd, UNUSED short events )
                        }
                        if (Conf_NoticeAuth) {
                                (void)Conn_WriteStr(i,
-                                       "NOTICE AUTH :*** Got %sident response",
-                                       *ptr ? "invalid " : "");
+                                       "NOTICE AUTH :*** Got %sident response%s%s",
+                                       *ptr ? "invalid " : "",
+                                       *ptr ? "" : ": ",
+                                       *ptr ? "" : identptr);
                        }
                } else {
                        Log(LOG_INFO, "IDENT lookup for connection %d: no result.", i);
@@ -2266,6 +2322,10 @@ cb_Read_Resolver_Result( int r_fd, UNUSED short events )
                                        "NOTICE AUTH :*** No ident response");
                }
 #endif
+
+               if (Conf_NoticeAuth)
+                       (void)Handle_Write(i);
+
                Class_HandleServerBans(c);
        }
 #ifdef DEBUG
index 4752ec1ede359ee4764066d0b80b578599ff6b74..e42a2ae6a7ac1c1466ade3a8124650a489e61715 100644 (file)
@@ -42,7 +42,7 @@
 #define CONN_SSL_WANT_READ     128     /* SSL/TLS library needs to read protocol data */
 #define CONN_SSL_FLAGS_ALL     (CONN_SSL_CONNECT|CONN_SSL|CONN_SSL_WANT_WRITE|CONN_SSL_WANT_READ)
 #endif
-typedef long CONN_ID;
+typedef int CONN_ID;
 
 #include "client.h"
 #include "proc.h"
@@ -72,6 +72,7 @@ typedef struct _Connection
        ng_ipaddr_t addr;               /* Client address */
        PROC_STAT proc_stat;            /* Status of resolver process */
        char host[HOST_LEN];            /* Hostname */
+       char *pwd;                      /* password received of the client */
        array rbuf;                     /* Read buffer */
        array wbuf;                     /* Write buffer */
        time_t signon;                  /* Signon ("connect") time */
@@ -100,6 +101,8 @@ GLOBAL CONNECTION *My_Connections;
 GLOBAL CONN_ID Pool_Size;
 GLOBAL long WCounter;
 
+#define CONNECTION2ID(x) (long)(x - My_Connections)
+
 #endif /* CONN_MODULE */
 
 
@@ -111,10 +114,15 @@ GLOBAL void Conn_CloseAllSockets PARAMS((int ExceptOf));
 GLOBAL unsigned int Conn_InitListeners PARAMS(( void ));
 GLOBAL void Conn_ExitListeners PARAMS(( void ));
 
+GLOBAL void Conn_StartLogin PARAMS((CONN_ID Idx));
+
 GLOBAL void Conn_Handler PARAMS(( void ));
 
 GLOBAL bool Conn_WriteStr PARAMS(( CONN_ID Idx, const char *Format, ... ));
 
+GLOBAL char* Conn_Password PARAMS(( CONN_ID Idx ));
+GLOBAL void Conn_SetPassword PARAMS(( CONN_ID Idx, const char *Pwd ));
+
 GLOBAL void Conn_Close PARAMS(( CONN_ID Idx, const char *LogMsg, const char *FwdMsg, bool InformClient ));
 
 GLOBAL void Conn_SyncServerStruct PARAMS(( void ));
@@ -122,6 +130,7 @@ GLOBAL void Conn_SyncServerStruct PARAMS(( void ));
 GLOBAL CONN_ID Conn_GetFromProc PARAMS((int fd));
 GLOBAL CLIENT* Conn_GetClient PARAMS((CONN_ID i));
 GLOBAL PROC_STAT* Conn_GetProcStat PARAMS((CONN_ID i));
+
 #ifdef SSL_SUPPORT
 GLOBAL bool Conn_GetCipherInfo PARAMS((CONN_ID Idx, char *buf, size_t len));
 GLOBAL bool Conn_UsesSSL PARAMS((CONN_ID Idx));
index d0dc9ce18862f742617caed8c69579007303ec8a..ba7adf17adb204840418b7482b75fef975844138 100644 (file)
 #endif
 
 /** Supported user modes. */
-#define USERMODES "acCiorRswx"
+#define USERMODES "aBcCiorRswx"
 
 /** Supported channel modes. */
-#define CHANMODES "abehiIklmnoOPqrRstvz"
+#define CHANMODES "abehiIklmMnoOPqrRstvz"
 
 /** Away message for users connected to linked servers. */
 #define DEFAULT_AWAY_MSG "Away"
index 9ffdfd6b8320e4ab12439e3273e92d99ceceb8a1..cce6ef536557e7376bf93a1a8df9f912218ae0e4 100644 (file)
@@ -86,6 +86,20 @@ static int io_masterfd;
 
 static int io_dispatch_kqueue(struct timeval *tv);
 static bool io_event_change_kqueue(int, short, const int action);
+
+#ifndef EV_SET
+/* Taken from /usr/include/sys/event.h of FreeBSD 8.1 and required by all
+ * platforms that have kqueue but lack EV_SET() -- for example FreeBSD 4. */
+#define EV_SET(kevp, a, b, c, d, e, f) do {    \
+       struct kevent *__kevp__ = (kevp);       \
+       __kevp__->ident = (a);                  \
+       __kevp__->filter = (b);                 \
+       __kevp__->flags = (c);                  \
+       __kevp__->fflags = (d);                 \
+       __kevp__->data = (e);                   \
+       __kevp__->udata = (f);                  \
+} while(0)
+#endif
 #endif
 
 #ifdef IO_USE_POLL
index 2ea4c9af135f6a9309be449924946bd6ca6ae879..af34c38c18403370f16f223eac257e429bc6fb3d 100644 (file)
@@ -275,8 +275,8 @@ Parse_CAP(int Capabilities, char *Args)
  * @param Capabilities Capability flags (bitmask).
  * @return Pointer to textual representation.
  */
-char
-*Get_CAP_String(int Capabilities)
+char *
+Get_CAP_String(int Capabilities)
 {
        static char txt[COMMAND_LEN];
 
index 879da3daadeed7782bd8af15ae616a0eaaf345b9..7a122ef790a0c5ec0148c3224b83956a8de00020 100644 (file)
@@ -864,6 +864,8 @@ IRC_WHO_Channel(CLIENT *Client, CHANNEL *Chan, bool OnlyOps)
        assert( Client != NULL );
        assert( Chan != NULL );
 
+       IRC_SetPenalty(Client, 1);
+
        is_member = Channel_IsMemberOf(Chan, Client);
 
        /* Secret channel? */
@@ -882,9 +884,6 @@ IRC_WHO_Channel(CLIENT *Client, CHANNEL *Chan, bool OnlyOps)
 
                is_visible = strchr(client_modes, 'i') == NULL;
                if (is_member || is_visible) {
-                       if (IRC_CheckListTooBig(Client, count, MAX_RPL_WHO, "WHO"))
-                               break;
-
                        strcpy(flags, who_flags_status(client_modes));
                        if (is_ircop)
                                strlcat(flags, "*", sizeof(flags));
@@ -898,6 +897,11 @@ IRC_WHO_Channel(CLIENT *Client, CHANNEL *Chan, bool OnlyOps)
                        count++;
                }
        }
+
+       /* If there are a lot of clients, augment penalty a bit */
+       if (count > MAX_RPL_WHO)
+               IRC_SetPenalty(Client, 1);
+
        return IRC_WriteStrClient(Client, RPL_ENDOFWHO_MSG, Client_ID(Client),
                                  Channel_Name(Chan));
 }
@@ -926,6 +930,7 @@ IRC_WHO_Mask(CLIENT *Client, char *Mask, bool OnlyOps)
        if (Mask)
                ngt_LowerStr(Mask);
 
+       IRC_SetPenalty(Client, 3);
        for (c = Client_First(); c != NULL; c = Client_Next(c)) {
                if (Client_Type(c) != CLIENT_USER)
                        continue;
@@ -1029,13 +1034,11 @@ IRC_WHO(CLIENT *Client, REQUEST *Req)
                chan = Channel_Search(Req->argv[0]);
                if (chan) {
                        /* Members of a channel have been requested */
-                       IRC_SetPenalty(Client, 1);
                        return IRC_WHO_Channel(Client, chan, only_ops);
                }
                if (strcmp(Req->argv[0], "0") != 0) {
                        /* A mask has been given. But please note this RFC
                         * stupidity: "0" is same as no arguments ... */
-                       IRC_SetPenalty(Client, 3);
                        return IRC_WHO_Mask(Client, Req->argv[0], only_ops);
                }
        }
@@ -1125,6 +1128,12 @@ IRC_WHOIS_SendReply(CLIENT *Client, CLIENT *from, CLIENT *c)
                                Client_ID(from), Client_ID(c)))
                return DISCONNECTED;
 
+       /* IRC-Bot? */
+       if (Client_HasMode(c, 'B') &&
+           !IRC_WriteStrClient(from, RPL_WHOISBOT_MSG,
+                               Client_ID(from), Client_ID(c)))
+               return DISCONNECTED;
+
        /* Connected using SSL? */
        if (Conn_UsesSSL(Client_Conn(c)) &&
            !IRC_WriteStrClient(from, RPL_WHOISSSL_MSG, Client_ID(from),
@@ -1491,7 +1500,15 @@ Show_MOTD_Sendline(CLIENT *Client, const char *msg)
 static bool
 Show_MOTD_End(CLIENT *Client)
 {
-       return IRC_WriteStrClient( Client, RPL_ENDOFMOTD_MSG, Client_ID( Client ));
+       if (!IRC_WriteStrClient(Client, RPL_ENDOFMOTD_MSG, Client_ID(Client)))
+               return DISCONNECTED;
+
+       if (*Conf_CloakHost)
+               return IRC_WriteStrClient(Client, RPL_HOSTHIDDEN_MSG,
+                                         Client_ID(Client),
+                                         Client_Hostname(Client));
+
+       return CONNECTED;
 }
 
 #ifdef SSL_SUPPORT
index 3fb1b902412118e2cad5b58bcae8af0dacec6379..9e1abdd59e8b0349b535b9b1299989f994a3827c 100644 (file)
@@ -87,7 +87,7 @@ IRC_PASS( CLIENT *Client, REQUEST *Req )
                                          Client_ID(Client));
        }
 
-       Client_SetPassword(Client, Req->argv[0]);
+       Conn_SetPassword(Client_Conn(Client), Req->argv[0]);
 
        /* Protocol version */
        if (Req->argc >= 2 && strlen(Req->argv[1]) >= 4) {
index 3679531d6963909502bf1895c2ea3dc6a0801052..f39463433ce5261b0d3736174845f92aadb21e76 100644 (file)
@@ -138,6 +138,7 @@ Client_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *Target )
 {
        char the_modes[COMMAND_LEN], x[2], *mode_ptr;
        bool ok, set;
+       bool send_RPL_HOSTHIDDEN_MSG = false;
        int mode_arg;
        size_t len;
 
@@ -229,6 +230,14 @@ Client_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *Target )
                                                        ERR_NOPRIVILEGES_MSG,
                                                        Client_ID(Origin));
                        break;
+               case 'B': /* Bot */
+                       if (Client_HasMode(Client, 'r'))
+                               ok = IRC_WriteStrClient(Origin,
+                                                       ERR_RESTRICTED_MSG,
+                                                       Client_ID(Origin));
+                       else
+                               x[0] = 'B';
+                       break;
                case 'c': /* Receive connect notices
                           * (only settable by IRC operators!) */
                        if (!set || Client_Type(Client) == CLIENT_SERVER
@@ -256,6 +265,14 @@ Client_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *Target )
                                                        ERR_RESTRICTED_MSG,
                                                        Client_ID(Origin));
                        break;
+               case 'R': /* Registered (not [un]settable by clients) */
+                       if (Client_Type(Client) == CLIENT_SERVER)
+                               x[0] = 'R';
+                       else
+                               ok = IRC_WriteStrClient(Origin,
+                                                       ERR_NICKREGISTER_MSG,
+                                                       Client_ID(Origin));
+                       break;
                case 'x': /* Cloak hostname */
                        if (Client_HasMode(Client, 'r'))
                                ok = IRC_WriteStrClient(Origin,
@@ -263,6 +280,7 @@ Client_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *Target )
                                                        Client_ID(Origin));
                        else
                                x[0] = 'x';
+                               send_RPL_HOSTHIDDEN_MSG = true;
                        break;
                default:
                        if (Client_Type(Client) != CLIENT_SERVER) {
@@ -332,6 +350,10 @@ Client_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *Target )
                                                  "MODE %s :%s",
                                                  Client_ID(Target),
                                                  the_modes);
+                       if (send_RPL_HOSTHIDDEN_MSG)
+                               IRC_WriteStrClient(Client, RPL_HOSTHIDDEN_MSG,
+                                                  Client_ID(Client),
+                                                  Client_HostnameCloaked(Client));
                }
                LogDebug("%s \"%s\": Mode change, now \"%s\".",
                         Client_TypeText(Target), Client_Mask(Target),
@@ -538,6 +560,7 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
                                goto chan_exit;
                        }
                case 'i': /* Invite only */
+               case 'M': /* Only identified nicks can write */
                case 'm': /* Moderated */
                case 'n': /* Only members can write */
                case 't': /* Topic locked */
index 2ce4fadd8ef8430a45155e824ebbeec501a6717a..f9182d984ca9c2c6f1f743b419a198d89b31ada7 100644 (file)
@@ -80,7 +80,8 @@ IRC_SERVER( CLIENT *Client, REQUEST *Req )
                        Conn_Close( Client_Conn( Client ), NULL, "Server not configured here", true);
                        return DISCONNECTED;
                }
-               if( strcmp( Client_Password( Client ), Conf_Server[i].pwd_in ) != 0 )
+               if( strcmp( Conn_Password( Client_Conn( Client ) ),
+                           Conf_Server[i].pwd_in ) != 0 )
                {
                        /* wrong password */
                        Log( LOG_ERR, "Connection %d: Got bad password from server \"%s\"!", Client_Conn( Client ), Req->argv[0] );
index 9508ecc457b9037f389f4a5cd1bbf1b7cb6f17be..efc34d4b2e087f8e3742c1d44ea6a820e2073f92 100644 (file)
@@ -327,12 +327,18 @@ IRC_HELP( CLIENT *Client, REQUEST *Req )
 
 
 static char *
-Option_String( CONN_ID Idx )
+#ifdef ZLIB
+Option_String(CONN_ID Idx)
+#else
+Option_String(UNUSED CONN_ID Idx)
+#endif
 {
        static char option_txt[8];
+#ifdef ZLIB
        UINT16 options;
 
        options = Conn_Options(Idx);
+#endif
 
        strcpy(option_txt, "F");        /* No idea what this means, but the
                                         * original ircd sends it ... */
index 7f0299cb09088622b03787a7815950db772f02c7..460fcd1e4c1954e80d946d6ac1a08a0ba9e7722e 100644 (file)
@@ -93,13 +93,14 @@ Login_User(CLIENT * Client)
                 * the beahiour of the daemon compiled without PAM support:
                 * because there can't be any "server password", all
                 * passwords supplied are classified as "wrong". */
-               if(Client_Password(Client)[0] == '\0')
+               if(Conn_Password(conn)[0] == '\0')
                        return Login_User_PostAuth(Client);
                Client_Reject(Client, "Non-empty password", false);
                return DISCONNECTED;
        }
 
-       if (Conf_PAMIsOptional && strcmp(Client_Password(Client), "") == 0) {
+       if (Conf_PAMIsOptional &&
+           strcmp(Conn_Password(conn), "") == 0) {
                /* Clients are not required to send a password and to be PAM-
                 * authenticated at all. If not, they won't become "identified"
                 * and keep the "~" in their supplied user name.
@@ -129,7 +130,7 @@ Login_User(CLIENT * Client)
        }
 #else
        /* Check global server password ... */
-       if (strcmp(Client_Password(Client), Conf_ServerPwd) != 0) {
+       if (strcmp(Conn_Password(conn), Conf_ServerPwd) != 0) {
                /* Bad password! */
                Client_Reject(Client, "Bad server password", false);
                return DISCONNECTED;
index 79699ea0d8740b7cf555af732d3c22ec1dfc9861..75bf4358395d27fa21b8a9c213c307a82a2196d6 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * ngIRCd -- The Next Generation IRC Daemon
- * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
+ * Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -48,9 +48,9 @@ static int Matche_After_Star PARAMS(( const char *p, const char *t ));
 /**
  * Match string with pattern.
  *
- * @param Pattern      Pattern to match with
- * @param String       Input string
- * @return             true if pattern matches
+ * @param Pattern Pattern to match with
+ * @param String Input string
+ * @return true if pattern matches
  */
 GLOBAL bool
 Match( const char *Pattern, const char *String )
@@ -64,17 +64,46 @@ Match( const char *Pattern, const char *String )
 /**
  * Match string with pattern case-insensitive.
  *
- * @param pattern      Pattern to match with
- * @param searchme     Input string, at most COMMAND_LEN-1 characters long
- * @return             true if pattern matches
+ * @param Pattern Pattern to match with
+ * @param String Input string, at most COMMAND_LEN-1 characters long
+ * @return true if pattern matches
  */
 GLOBAL bool
-MatchCaseInsensitive(const char *pattern, const char *searchme)
+MatchCaseInsensitive(const char *Pattern, const char *String)
 {
        char haystack[COMMAND_LEN];
 
-       strlcpy(haystack, searchme, sizeof(haystack));
-       return Match(pattern, ngt_LowerStr(haystack));
+       strlcpy(haystack, String, sizeof(haystack));
+       return Match(Pattern, ngt_LowerStr(haystack));
+} /* MatchCaseInsensitive */
+
+
+/**
+ * Match string with pattern case-insensitive.
+ *
+ * @param pattern Pattern to match with
+ * @param String Input string, at most COMMAND_LEN-1 characters long
+ * @param Separator Character separating the individual patterns in the list
+ * @return true if pattern matches
+ */
+GLOBAL bool
+MatchCaseInsensitiveList(const char *Pattern, const char *String,
+                    const char *Separator)
+{
+       char tmp_pattern[COMMAND_LEN], haystack[COMMAND_LEN], *ptr;
+
+       strlcpy(tmp_pattern, Pattern, sizeof(tmp_pattern));
+       strlcpy(haystack, String, sizeof(haystack));
+       ngt_LowerStr(haystack);
+
+       ptr = strtok(tmp_pattern, Separator);
+       while (ptr) {
+               ngt_TrimStr(ptr);
+               if (Match(ptr, haystack))
+                       return true;
+               ptr = strtok(NULL, Separator);
+       }
+       return false;
 } /* MatchCaseInsensitive */
 
 
index 2efe3f5ba7ad81b08d0d237487b7112b77e22ebc..d4107fb65d357fcdab95677685fa6340378b53d5 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * ngIRCd -- The Next Generation IRC Daemon
- * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
+ * Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * Wildcard pattern matching (header)
  */
 
-GLOBAL bool Match PARAMS(( const char *Pattern, const char *String ));
-GLOBAL bool MatchCaseInsensitive PARAMS(( const char *Pattern, const char *searchme ));
+GLOBAL bool Match PARAMS((const char *Pattern, const char *String));
+
+GLOBAL bool MatchCaseInsensitive PARAMS((const char *Pattern,
+                                        const char *String));
+
+GLOBAL bool MatchCaseInsensitiveList PARAMS((const char *Pattern,
+                                            const char *String,
+                                            const char *Separator));
 
 #endif
 
index d8041bfd761e3d5dc621eca2864939118b778049..d99930faa5d079995932ba3140d207c08e20e5c9 100644 (file)
@@ -21,7 +21,7 @@
 #define RPL_YOURHOST_MSG               "002 %s :Your host is %s, running version ngircd-%s (%s/%s/%s)"
 #define RPL_CREATED_MSG                        "003 %s :This server has been started %s"
 #define RPL_MYINFO_MSG                 "004 %s %s ngircd-%s %s %s"
-#define RPL_ISUPPORT1_MSG              "005 %s RFC2812 IRCD=ngIRCd CASEMAPPING=ascii PREFIX=(qaohv)~&@%%+ CHANTYPES=#&+ CHANMODES=beI,k,l,imnOPRstz CHANLIMIT=#&+:%d :are supported on this server"
+#define RPL_ISUPPORT1_MSG              "005 %s RFC2812 IRCD=ngIRCd CASEMAPPING=ascii PREFIX=(qaohv)~&@%%+ CHANTYPES=#&+ CHANMODES=beI,k,l,imMnOPRstz CHANLIMIT=#&+:%d :are supported on this server"
 #define RPL_ISUPPORT2_MSG              "005 %s CHANNELLEN=%d NICKLEN=%d TOPICLEN=%d AWAYLEN=%d KICKLEN=%d MODES=%d MAXLIST=beI:%d EXCEPTS=e INVEX=I PENALTY :are supported on this server"
 
 #define RPL_TRACELINK_MSG              "200 %s Link %s-%s %s %s V%s %ld %d %d"
@@ -72,6 +72,7 @@
 #define RPL_NOTOPIC_MSG                        "331 %s %s :No topic is set"
 #define RPL_TOPIC_MSG                  "332 %s %s :%s"
 #define RPL_TOPICSETBY_MSG             "333 %s %s %s %u"
+#define RPL_WHOISBOT_MSG               "335 %s %s :is a IRC Bot"
 #define RPL_INVITING_MSG               "341 %s %s %s%s"
 #define RPL_INVITELIST_MSG             "346 %s %s %s"
 #define RPL_ENDOFINVITELIST_MSG                "347 %s %s :End of channel invite list"
 #define RPL_YOUREOPER_MSG              "381 %s :You are now an IRC Operator"
 #define RPL_YOURESERVICE_MSG           "383 %s :You are service %s"
 #define RPL_TIME_MSG                   "391 %s %s :%s"
+#define RPL_HOSTHIDDEN_MSG             "396 %s %s :is your displayed hostname now"
 
 #define ERR_NOSUCHNICK_MSG             "401 %s %s :No such nick or channel name"
 #define ERR_NOSUCHSERVER_MSG           "402 %s %s :No such server"
 #define ERR_NOSUCHCHANNEL_MSG          "403 %s %s :No such channel"
-#define ERR_CANNOTSENDTOCHAN_MSG       "404 %s %s :Cannot send to channel"
+#define ERR_CANNOTSENDTOCHAN_MSG       "404 %s %s :Cannot send to channel (+m) -- Moderated"
 #define ERR_TOOMANYCHANNELS_MSG                "405 %s %s :You have joined too many channels"
 #define ERR_WASNOSUCHNICK_MSG          "406 %s %s :There was no such nickname"
 #define ERR_NOORIGIN_MSG               "409 %s :No origin specified"
 #define ERR_NONICKNAMEGIVEN_MSG                "431 %s :No nickname given"
 #define ERR_ERRONEUSNICKNAME_MSG       "432 %s %s :Erroneous nickname"
 #define ERR_NICKNAMETOOLONG_MSG                "432 %s %s :Nickname too long, max. %u characters"
+#define ERR_FORBIDDENNICKNAME_MSG      "432 %s %s :Nickname is forbidden/blocked"
 #define ERR_NICKNAMEINUSE_MSG          "433 %s %s :Nickname already in use"
 #define ERR_USERNOTINCHANNEL_MSG       "441 %s %s %s :They aren't on that channel"
 #define ERR_NOTONCHANNEL_MSG           "442 %s %s :You are not on that channel"
 #define ERR_NEEDMOREPARAMS_MSG         "461 %s %s :Syntax error"
 #define ERR_ALREADYREGISTRED_MSG       "462 %s :Connection already registered"
 #define ERR_PASSWDMISMATCH_MSG         "464 %s :Invalid password"
-#define ERR_CHANNELISFULL_MSG          "471 %s %s :Cannot join channel (+l)"
-#define ERR_SECURECHANNEL_MSG          "471 %s %s :Cannot join channel (+z)"
-#define ERR_OPONLYCHANNEL_MSG          "471 %s %s :Cannot join channel (+O)"
-#define ERR_REGONLYCHANNEL_MSG         "471 %s %s :Cannot join channel (+R)"
+#define ERR_CHANNELISFULL_MSG          "471 %s %s :Cannot join channel (+l) -- Channel is too full, try later"
+#define ERR_SECURECHANNEL_MSG          "471 %s %s :Cannot join channel (+z) -- SSL connections only"
+#define ERR_OPONLYCHANNEL_MSG          "471 %s %s :Cannot join channel (+O) -- IRC opers only"
+#define ERR_REGONLYCHANNEL_MSG         "471 %s %s :Cannot join channel (+R) -- Registered users only"
 #define ERR_UNKNOWNMODE_MSG            "472 %s %c :is unknown mode char for %s"
-#define ERR_INVITEONLYCHAN_MSG         "473 %s %s :Cannot join channel (+i)"
-#define ERR_BANNEDFROMCHAN_MSG         "474 %s %s :Cannot join channel (+b)"
-#define ERR_BADCHANNELKEY_MSG          "475 %s %s :Cannot join channel (+k)"
+#define ERR_INVITEONLYCHAN_MSG         "473 %s %s :Cannot join channel (+i) -- Invited users only"
+#define ERR_BANNEDFROMCHAN_MSG         "474 %s %s :Cannot join channel (+b) -- You are banned"
+#define ERR_BADCHANNELKEY_MSG          "475 %s %s :Cannot join channel (+k) -- Wrong channel key"
 #define ERR_NOCHANMODES_MSG            "477 %s %s :Channel doesn't support modes"
 #define ERR_LISTFULL_MSG               "478 %s %s %s: Channel list is full (%d)"
 #define ERR_NOPRIVILEGES_MSG           "481 %s :Permission denied"
 #define ERR_CHANOPPRIVTOLOW_MSG                "482 %s %s :Your privileges are to low"
 #define ERR_CANTKILLSERVER_MSG         "483 %s :You can't kill a server!"
 #define ERR_RESTRICTED_MSG             "484 %s :Your connection is restricted"
+#define ERR_NICKREGISTER_MSG           "484 %s :Cannot modify user mode (+R) -- Use IRC services"
 #define ERR_NOOPERHOST_MSG             "491 %s :Not configured for your host"
 #define ERR_NOTONSAMECHANNEL_MSG       "493 %s :You must share a common channel with %s"
 
index 6382c594db0747f5872b7042cb553713d3abd4f1..88872c47c5f841d9b008da5fdc59a39281f4f2bb 100644 (file)
@@ -102,8 +102,8 @@ PAM_Authenticate(CLIENT *Client) {
        /* Set supplied client password */
        if (password)
                free(password);
-       password = strdup(Client_Password(Client));
-       conv.appdata_ptr = Client_Password(Client);
+       password = strdup(Conn_Password(Client_Conn(Client)));
+       conv.appdata_ptr = Conn_Password(Client_Conn(Client));
 
        /* Initialize PAM */
        retval = pam_start("ngircd", Client_OrigUser(Client), &conv, &pam);
index 31c6fb41fb9272f5b4abd5e6713b12d359fb5387..eb6c131e428462e81d3aad67075c721b429edd00 100644 (file)
@@ -135,24 +135,20 @@ ngt_TrimLastChr( char *String, const char Chr)
  * Fill a String with random chars
  */
 GLOBAL char *
-ngt_RandomStr( char *String, const size_t len)
+ngt_RandomStr(char *String, const size_t len)
 {
-       assert(String != NULL);
+       static const char chars[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!\"#$&'()*+,-./:;<=>?@[\\]^_`";
+       struct timeval t;
+       size_t i;
 
-       static const char chars[] = 
-               "0123456789ABCDEFGHIJKLMNO"
-               "PQRSTUVWXYZabcdefghijklmn"
-               "opqrstuvwxyz!\"#$&'()*+,-"
-               "./:;<=>?@[\\]^_`";
+       assert(String != NULL);
 
-       struct timeval t;
        gettimeofday(&t, NULL);
-       srand(t.tv_usec * t.tv_sec);
+       srand((unsigned)(t.tv_usec * t.tv_sec));
 
-       for (size_t i = 0; i < len; ++i) {
+       for (i = 0; i < len; ++i) {
                String[i] = chars[rand() % (sizeof(chars) - 1)];
        }
-
        String[len] = '\0';
 
        return String;