From: Alexander Barton Date: Sat, 13 Aug 2011 19:04:01 +0000 (+0200) Subject: Merge branch 'ServerMode' X-Git-Tag: rel-19-rc1~137 X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=ngircd-alex.git;a=commitdiff_plain;h=7795b07c53f29bfdcfb2e4ebb5a9d18e283773c0;hp=989c9fa531d83c9b1a302b222a4bcfeef767c2b6 Merge branch 'ServerMode' * ServerMode: Handle channel user modes 'a', 'h', and 'q' from remote servers Handle unknown channel modes on server links Handle unknown user modes on server links IRC_MODE(), Client_Mode(): code cleanup [2/2] Enlarge client user mode buffer, reduce client flags buffer Infom clients when other servers change their user modes IRC_MODE(), Client_Mode(): code cleanup [1/2] --- diff --git a/contrib/MacOSX/config.h b/contrib/MacOSX/config.h index af0a34c2..86b460b1 100644 --- a/contrib/MacOSX/config.h +++ b/contrib/MacOSX/config.h @@ -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 @@ -103,10 +103,15 @@ #ifdef PAM /* Define to 1 if you have the `pam_authenticate' function. */ #define HAVE_PAM_AUTHENTICATE 1 +#if (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1060) /* Define to 1 if you have the header file. */ #define HAVE_PAM_PAM_APPL_H 1 /* Mac OS X <10.6 doesn't have pam_fail_delay() */ #define NO_PAM_FAIL_DELAY 1 +#else +/* Define to 1 if you have the header file. */ +#define HAVE_SECURITY_PAM_APPL_H 1 +#endif #endif /* -eof- */ diff --git a/contrib/MacOSX/ngIRCd.xcodeproj/.gitignore b/contrib/MacOSX/ngIRCd.xcodeproj/.gitignore index d82a5e47..d6d065a7 100644 --- a/contrib/MacOSX/ngIRCd.xcodeproj/.gitignore +++ b/contrib/MacOSX/ngIRCd.xcodeproj/.gitignore @@ -1,2 +1,4 @@ +project.xcworkspace +xcuserdata *.mode1v3 *.pbxuser diff --git a/contrib/MacOSX/ngIRCd.xcodeproj/project.pbxproj b/contrib/MacOSX/ngIRCd.xcodeproj/project.pbxproj index 2f9124e4..42ddbf26 100644 --- a/contrib/MacOSX/ngIRCd.xcodeproj/project.pbxproj +++ b/contrib/MacOSX/ngIRCd.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 44; + objectVersion = 46; objects = { /* Begin PBXBuildFile section */ @@ -170,7 +170,6 @@ FA322D8E0CEF7523001761B3 /* ngIRCd.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; path = ngIRCd.xcodeproj; sourceTree = ""; }; FA322D910CEF7523001761B3 /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = Makefile.am; sourceTree = ""; }; FA322D920CEF7523001761B3 /* ngindent */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = ngindent; sourceTree = ""; }; - FA322D930CEF7523001761B3 /* ngircd.sh */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.script.sh; path = ngircd.sh; sourceTree = ""; }; FA322D940CEF7523001761B3 /* ngircd.spec */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = ngircd.spec; sourceTree = ""; }; FA322D950CEF7523001761B3 /* README */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = README; sourceTree = ""; }; FA322D960CEF7523001761B3 /* systrace.policy */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = systrace.policy; sourceTree = ""; }; @@ -196,6 +195,10 @@ FA407F2C0DB159F400271AF1 /* ng_ipaddr.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = ng_ipaddr.c; path = ipaddr/ng_ipaddr.c; sourceTree = ""; }; FA407F2D0DB159F400271AF1 /* ng_ipaddr.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = ng_ipaddr.h; path = ipaddr/ng_ipaddr.h; sourceTree = ""; }; FA407F380DB15AC700271AF1 /* GIT.txt */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = GIT.txt; sourceTree = ""; }; + FA4B08E513E7F8FB00765BA3 /* ngircd-bsd.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = "ngircd-bsd.sh"; sourceTree = ""; }; + FA4B08E613E7F91700765BA3 /* ngIRCd-Logo.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = "ngIRCd-Logo.gif"; sourceTree = ""; }; + FA4B08E713E7F91700765BA3 /* ngircd-redhat.init */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = "ngircd-redhat.init"; sourceTree = ""; }; + FA4B08E813E7F91C00765BA3 /* platformtest.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = platformtest.sh; sourceTree = ""; }; FA77849A133FB9FF00740057 /* sample-ngircd.conf.tmpl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "sample-ngircd.conf.tmpl"; sourceTree = ""; }; FA85178A0FA061EC006A1F5A /* op.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = op.h; sourceTree = ""; }; FA85178B0FA061EC006A1F5A /* op.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; path = op.c; sourceTree = ""; }; @@ -432,8 +435,11 @@ FA322D730CEF7523001761B3 /* MacOSX */, FA322D910CEF7523001761B3 /* Makefile.am */, FA322D920CEF7523001761B3 /* ngindent */, - FA322D930CEF7523001761B3 /* ngircd.sh */, + FA4B08E513E7F8FB00765BA3 /* ngircd-bsd.sh */, + FA4B08E613E7F91700765BA3 /* ngIRCd-Logo.gif */, + FA4B08E713E7F91700765BA3 /* ngircd-redhat.init */, FA322D940CEF7523001761B3 /* ngircd.spec */, + FA4B08E813E7F91C00765BA3 /* platformtest.sh */, FA322D950CEF7523001761B3 /* README */, FA322D960CEF7523001761B3 /* systrace.policy */, ); @@ -641,8 +647,11 @@ /* Begin PBXProject section */ 08FB7793FE84155DC02AAC07 /* Project object */ = { isa = PBXProject; + attributes = { + LastUpgradeCheck = 0410; + }; buildConfigurationList = 1DEB928908733DD80010E9CD /* Build configuration list for PBXProject "ngIRCd" */; - compatibilityVersion = "Xcode 3.0"; + compatibilityVersion = "Xcode 3.2"; developmentRegion = English; hasScannedForEncodings = 1; knownRegions = ( @@ -738,13 +747,11 @@ 1DEB928B08733DD80010E9CD /* Default */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; - ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; - GCC_VERSION = 4.0; + ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; + GCC_VERSION = 4.2; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; - PREBINDING = NO; - SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.5.sdk"; + SDKROOT = macosx10.6; }; name = Default; }; @@ -754,11 +761,10 @@ ARCHS = "$(NATIVE_ARCH_ACTUAL)"; GCC_DEBUGGING_SYMBOLS = full; GCC_OPTIMIZATION_LEVEL = 0; - GCC_VERSION = 4.0; + GCC_VERSION = 4.2; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; ONLY_ACTIVE_ARCH = YES; - PREBINDING = NO; SDKROOT = ""; }; name = Debug; diff --git a/contrib/ngindent b/contrib/ngindent index 73537a6d..2ce1a26a 100755 --- a/contrib/ngindent +++ b/contrib/ngindent @@ -4,6 +4,7 @@ INDENTARGS="-kr -i8 -ts8 -l80 -c3 -cd41 -ss -ncs -psl" # check if indent(1) is available type indent >/dev/null 2>&1 && INDENT="indent" +type gindent >/dev/null 2>&1 && INDENT="gindent" type gnuindent >/dev/null 2>&1 && INDENT="gnuindent" if [ -z "$INDENT" ]; then diff --git a/doc/Platforms.txt b/doc/Platforms.txt index 460719f9..0346ac68 100644 --- a/doc/Platforms.txt +++ b/doc/Platforms.txt @@ -59,6 +59,7 @@ m68k/apple/aux3.1.1 Orig. A/UX 18 11-07-02 alex Y Y N Y (2) m68k/hp/hp-ux9.10 Orig. HPUX 0.7.x-CVS 03-04-30 goetz Y Y Y Y m88k/dg/dgux5.4R3.10 gcc 2.5.8 CVSHEAD 04-03-15 alex Y Y ? ? mipsel/unknown/linux-gnu gcc 4.1.2 18 11-07-05 goetz Y Y N Y (1) +mipsel/unknown/linux-gnu gcc 4.4.5 18 11-07-30 goetz Y Y Y Y (1) powerpc/apple/darwin6.5 gcc 3.1 0.7.x-CVS 03-04-23 alex Y Y Y Y powerpc/apple/darwin7.9.0 gcc 3.3 CVSHEAD 06-05-07 fw Y Y Y Y (3) powerpc/apple/darwin8.11.0 gcc 4.0.1 18 11-07-02 goetz Y Y Y Y (3) diff --git a/src/ngircd/irc-login.c b/src/ngircd/irc-login.c index 067703a8..edaefd61 100644 --- a/src/ngircd/irc-login.c +++ b/src/ngircd/irc-login.c @@ -653,32 +653,37 @@ IRC_QUIT( CLIENT *Client, REQUEST *Req ) CLIENT *target; char quitmsg[LINE_LEN]; - assert( Client != NULL ); - assert( Req != NULL ); + assert(Client != NULL); + assert(Req != NULL); /* Wrong number of arguments? */ - if( Req->argc > 1 ) - return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command ); + if (Req->argc > 1) + return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, + Client_ID(Client), Req->command); if (Req->argc == 1) strlcpy(quitmsg, Req->argv[0], sizeof quitmsg); - if ( Client_Type( Client ) == CLIENT_SERVER ) - { + if (Client_Type(Client) == CLIENT_SERVER) { /* Server */ - target = Client_Search( Req->prefix ); - if( ! target ) - { - Log( LOG_WARNING, "Got QUIT from %s for unknown client!?", Client_ID( Client )); + target = Client_Search(Req->prefix); + if (!target) { + Log(LOG_WARNING, + "Got QUIT from %s for unknown client!?", + Client_ID(Client)); return CONNECTED; } - Client_Destroy( target, "Got QUIT command.", Req->argc == 1 ? quitmsg : NULL, true); - - return CONNECTED; - } - else - { + if (target != Client) { + Client_Destroy(target, "Got QUIT command.", + Req->argc == 1 ? quitmsg : NULL, true); + return CONNECTED; + } else { + Conn_Close(Client_Conn(Client), "Got QUIT command.", + Req->argc == 1 ? quitmsg : NULL, true); + return DISCONNECTED; + } + } else { if (Req->argc == 1 && quitmsg[0] != '\"') { /* " " to avoid confusion */ strlcpy(quitmsg, "\"", sizeof quitmsg); @@ -687,7 +692,8 @@ IRC_QUIT( CLIENT *Client, REQUEST *Req ) } /* User, Service, or not yet registered */ - Conn_Close( Client_Conn( Client ), "Got QUIT command.", Req->argc == 1 ? quitmsg : NULL, true); + Conn_Close(Client_Conn(Client), "Got QUIT command.", + Req->argc == 1 ? quitmsg : NULL, true); return DISCONNECTED; } @@ -1096,20 +1102,22 @@ Hello_User_PostAuth(CLIENT *Client) * @param Reason Reason for the KILL. */ static void -Kill_Nick( char *Nick, char *Reason ) +Kill_Nick(char *Nick, char *Reason) { REQUEST r; - assert( Nick != NULL ); - assert( Reason != NULL ); + assert (Nick != NULL); + assert (Reason != NULL); - r.prefix = (char *)Client_ThisServer( ); + r.prefix = NULL; r.argv[0] = Nick; r.argv[1] = Reason; r.argc = 2; - Log( LOG_ERR, "User(s) with nick \"%s\" will be disconnected: %s", Nick, Reason ); - IRC_KILL( Client_ThisServer( ), &r ); + Log(LOG_ERR, "User(s) with nick \"%s\" will be disconnected: %s", + Nick, Reason); + + IRC_KILL(Client_ThisServer(), &r); } /* Kill_Nick */ diff --git a/src/ngircd/irc.c b/src/ngircd/irc.c index 8dd9bf74..69dd61a7 100644 --- a/src/ngircd/irc.c +++ b/src/ngircd/irc.c @@ -63,13 +63,21 @@ IRC_ERROR( CLIENT *Client, REQUEST *Req ) /** - * Kill client on request. + * Handler for the IRC "KILL" command. + * * This function implements the IRC command "KILL" wich is used to selectively * disconnect clients. It can be used by IRC operators and servers, for example - * to "solve" nick collisions after netsplits. + * to "solve" nick collisions after netsplits. See RFC 2812 section 3.7.1. + * * Please note that this function is also called internally, without a real * KILL command being received over the network! Client is Client_ThisServer() - * in this case. */ + * in this case, and the prefix in Req is NULL. + * + * @param Client The client from which this command has been received + * or Client_ThisServer() when generated interanlly. + * @param Req Request structure with prefix and all parameters. + * @returns CONNECTED or DISCONNECTED. + */ GLOBAL bool IRC_KILL( CLIENT *Client, REQUEST *Req ) { @@ -77,55 +85,47 @@ IRC_KILL( CLIENT *Client, REQUEST *Req ) char reason[COMMAND_LEN], *msg; CONN_ID my_conn, conn; - assert( Client != NULL ); - assert( Req != NULL ); + assert (Client != NULL); + assert (Req != NULL); - if(( Client_Type( Client ) != CLIENT_SERVER ) && - ( ! Client_OperByMe( Client ))) - { - /* The originator of the KILL is neither an IRC operator of - * this server nor a server. */ - return IRC_WriteStrClient( Client, ERR_NOPRIVILEGES_MSG, - Client_ID( Client )); - } + if (Client_Type(Client) != CLIENT_SERVER && !Client_OperByMe(Client)) + return IRC_WriteStrClient(Client, ERR_NOPRIVILEGES_MSG, + Client_ID(Client)); - if( Req->argc != 2 ) - { - /* This command requires exactly 2 parameters! */ - return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, - Client_ID( Client ), Req->command ); - } + if (Req->argc != 2) + return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, + Client_ID(Client), Req->command); - if( Req->prefix ) prefix = Client_Search( Req->prefix ); - else prefix = Client; - if( ! prefix ) - { - Log( LOG_WARNING, "Got KILL with invalid prefix: \"%s\"!", - Req->prefix ); - prefix = Client_ThisServer( ); + /* Get prefix (origin); use the client if no prefix is given. */ + if (Req->prefix) + prefix = Client_Search(Req->prefix); + else + prefix = Client; + + /* Log a warning message and use this server as origin when the + * prefix (origin) is invalid. */ + if (!prefix) { + Log(LOG_WARNING, "Got KILL with invalid prefix: \"%s\"!", + Req->prefix ); + prefix = Client_ThisServer(); } - if( Client != Client_ThisServer( )) - { - /* This is a "real" KILL received from the network. */ - Log( LOG_NOTICE|LOG_snotice, "Got KILL command from \"%s\" for \"%s\": %s", - Client_Mask( prefix ), Req->argv[0], Req->argv[1] ); - } + if (Client != Client_ThisServer()) + Log(LOG_NOTICE|LOG_snotice, + "Got KILL command from \"%s\" for \"%s\": %s", + Client_Mask(prefix), Req->argv[0], Req->argv[1]); - /* Build reason string */ - if( Client_Type( Client ) == CLIENT_USER ) - { - /* Prefix the "reason" if the originator is a regular user, - * so users can't spoof KILLs of servers. */ - snprintf( reason, sizeof( reason ), "KILLed by %s: %s", - Client_ID( Client ), Req->argv[1] ); - } + /* Build reason string: Prefix the "reason" if the originator is a + * regular user, so users can't spoof KILLs of servers. */ + if (Client_Type(Client) == CLIENT_USER) + snprintf(reason, sizeof(reason), "KILLed by %s: %s", + Client_ID(Client), Req->argv[1]); else - strlcpy( reason, Req->argv[1], sizeof( reason )); + strlcpy(reason, Req->argv[1], sizeof(reason)); /* Inform other servers */ - IRC_WriteStrServersPrefix( Client, prefix, "KILL %s :%s", - Req->argv[0], reason ); + IRC_WriteStrServersPrefix(Client, prefix, "KILL %s :%s", + Req->argv[0], reason); /* Save ID of this connection */ my_conn = Client_Conn( Client ); diff --git a/src/ngircd/ngircd.c b/src/ngircd/ngircd.c index 500d1288..2135ec4d 100644 --- a/src/ngircd/ngircd.c +++ b/src/ngircd/ngircd.c @@ -593,7 +593,7 @@ Random_Init(void) return; if (Random_Init_Kern("/dev/arandom")) return; - srand(rand() ^ getpid() ^ time(NULL)); + srand(rand() ^ (unsigned)getpid() ^ (unsigned)time(NULL)); } diff --git a/src/ngircd/parse.c b/src/ngircd/parse.c index 72e34309..be3c864d 100644 --- a/src/ngircd/parse.c +++ b/src/ngircd/parse.c @@ -325,13 +325,21 @@ Validate_Prefix( CONN_ID Idx, REQUEST *Req, bool *Closed ) /* check if the client named in the prefix is expected * to come from that direction */ if (Client_NextHop(c) != client) { - Log(LOG_ERR, - "Spoofed prefix \"%s\" from \"%s\" (connection %d, command \"%s\")!", - Req->prefix, Client_Mask(Conn_GetClient(Idx)), Idx, - Req->command); - Conn_Close(Idx, NULL, "Spoofed prefix", true); - *Closed = true; + if (Client_Type(c) != CLIENT_SERVER) { + Log(LOG_ERR, + "Spoofed prefix \"%s\" from \"%s\" (connection %d, command \"%s\")!", + Req->prefix, Client_Mask(Conn_GetClient(Idx)), Idx, + Req->command); + Conn_Close(Idx, NULL, "Spoofed prefix", true); + *Closed = true; + } else { + Log(LOG_INFO, + "Ignoring spoofed prefix \"%s\" from \"%s\" (connection %d, command \"%s\").", + Req->prefix, Client_Mask(Conn_GetClient(Idx)), Idx, + Req->command); + } return false; + } return true;