diff -rpbu10 irc2.11.0a8/common/match.c irc2.11.0a8-cvs+pl/common/match.c --- irc2.11.0a8/common/match.c Sat Oct 18 17:31:28 2003 +++ irc2.11.0a8-cvs+pl/common/match.c Mon May 17 00:30:25 2004 @@ -356,18 +356,18 @@ int isvalidusername(char *username) if (isalpha(*ch) || isdigit(*ch)) { an++; } else { nan++; } } /* we require at least one alphanum and no more than - one nonalphanum */ - if (nan > 1 || an == 0) + two nonalphanum */ + if (nan > 2 || an == 0) { return 0; } return 1; } diff -rpbu10 irc2.11.0a8/common/msg_def.h irc2.11.0a8-cvs+pl/common/msg_def.h --- irc2.11.0a8/common/msg_def.h Sat May 15 00:31:48 2004 +++ irc2.11.0a8-cvs+pl/common/msg_def.h Mon May 17 00:30:25 2004 @@ -74,12 +74,17 @@ #define MSG_DIE "DIE" #define MSG_HASH "HAZH" #define MSG_DNS "DNS" #define MSG_SMASK "SMASK" #define MSG_EOB "EOB" #define MSG_EOBACK "EOBACK" #define MSG_SET "SET" #define MSG_MAP "MAP" #define MSG_POST "POST" +#ifdef TKLINE +#define MSG_TKLINE "TKLINE" +#define MSG_UNTKLINE "UNTKLINE" +#endif + #define MAXPARA 15 diff -rpbu10 irc2.11.0a8/common/numeric_def.h irc2.11.0a8-cvs+pl/common/numeric_def.h --- irc2.11.0a8/common/numeric_def.h Sun Mar 7 04:02:13 2004 +++ irc2.11.0a8-cvs+pl/common/numeric_def.h Mon May 17 00:30:25 2004 @@ -196,20 +196,22 @@ #define ERR_NOPRIVILEGES 481 #define ERR_CHANOPRIVSNEEDED 482 #define ERR_CANTKILLSERVER 483 #define ERR_RESTRICTED 484 #define ERR_UNIQOPRIVSNEEDED 485 #define ERR_NOOPERHOST 491 #define ERR_NOSERVICEHOST 492 +#define ERR_STATSKLINE 499 + #define ERR_UMODEUNKNOWNFLAG 501 #define ERR_USERSDONTMATCH 502 /* * Numberic replies from server commands. * These are currently in the range 200-399. */ #define RPL_NONE 300 #define RPL_AWAY 301 #define RPL_USERHOST 302 diff -rpbu10 irc2.11.0a8/common/parse.c irc2.11.0a8-cvs+pl/common/parse.c --- irc2.11.0a8/common/parse.c Sat May 15 00:31:48 2004 +++ irc2.11.0a8-cvs+pl/common/parse.c Mon May 17 00:30:25 2004 @@ -129,20 +129,24 @@ struct Message msgtab[] = { #endif #ifdef OPER_SET { MSG_SET, m_set, MAXPARA, MSG_REGU|MSG_OP #ifdef LOCOP_SET | MSG_LOP #endif , 0, 0, 0L}, #endif /* OPER_SET */ { MSG_MAP, m_map, MAXPARA, MSG_LAG | MSG_REG, 0, 0, 0L}, { MSG_POST, m_post, MAXPARA, MSG_NOU, 0, 0, 0L}, +#ifdef TKLINE + { MSG_TKLINE, m_tkline, MAXPARA, MSG_REG, 0, 0, 0L}, + { MSG_UNTKLINE, m_untkline, MAXPARA, MSG_REG, 0, 0, 0L}, +#endif /* TKLINE */ #endif /* !CLIENT_COMPILE */ { NULL, NULL, 0, 0, 0, 0, 0L} }; /* * NOTE: parse() should not be called recursively by other functions! */ static char *para[MAXPARA+1]; #ifdef CLIENT_COMPILE @@ -778,21 +782,21 @@ int parse(aClient *cptr, char *buffer, c #endif } ircstp->is_unco++; return -1; } paramcount = mptr->parameters; i = bufend - ((s) ? s : ch); mptr->bytes += i; #ifndef CLIENT_COMPILE if ((mptr->flags & MSG_LAG) && - !(IsServer(cptr) || IsService(cptr))) + !(IsServer(cptr) || IsService(cptr) || CanFlood(cptr))) { /* Flood control partly migrated into penalty */ if (bootopt & BOOT_PROT) cptr->since += (1 + i / 100); else cptr->since = timeofday; /* Allow only 1 msg per 2 seconds * (on average) to prevent dumping. * to keep the response rate up, * bursts of up to 5 msgs are allowed * -SRB @@ -890,21 +894,22 @@ int parse(aClient *cptr, char *buffer, c ** >=0 if protocol message processing was successful. The return ** value indicates the penalty score. */ ret = (*mptr->func)(cptr, from, i, para); #ifndef CLIENT_COMPILE /* ** Add penalty score for sucessfully parsed command if issued by ** a LOCAL user client. */ - if ((ret > 0) && IsRegisteredUser(cptr) && (bootopt & BOOT_PROT)) + if ((ret > 0) && IsRegisteredUser(cptr) && (bootopt & BOOT_PROT) && + !CanFlood(cptr)) { cptr->since += ret; /* only to lurk sendto_one(cptr, ":%s NOTICE %s :*** Penalty INCR [%s] +%d", me.name, cptr->name, ch, ret); */ } #endif return (ret != FLUSH_BUFFER) ? 2 : FLUSH_BUFFER; diff -rpbu10 irc2.11.0a8/common/send.c irc2.11.0a8-cvs+pl/common/send.c --- irc2.11.0a8/common/send.c Thu Mar 18 01:54:45 2004 +++ irc2.11.0a8-cvs+pl/common/send.c Mon May 17 00:30:25 2004 @@ -1174,20 +1174,23 @@ static SChan svchans[SCH_MAX] = { { SCH_KILL, "&KILLS", NULL }, { SCH_CHAN, "&CHANNEL", NULL }, { SCH_NUM, "&NUMERICS", NULL }, { SCH_SERVER, "&SERVERS", NULL }, { SCH_HASH, "&HASH", NULL }, { SCH_LOCAL, "&LOCAL", NULL }, { SCH_SERVICE, "&SERVICES", NULL }, { SCH_DEBUG, "&DEBUG", NULL }, { SCH_AUTH, "&AUTH", NULL }, { SCH_SAVE, "&SAVE", NULL }, +#ifdef CLIENTS_CHANNEL + { SCH_OPER, "&OPER", NULL }, +#endif }; void setup_svchans(void) { int i; SChan *shptr; for (i = SCH_MAX, shptr = svchans + (i - 1); i > 0; i--, shptr--) shptr->svc_ptr = find_channel(shptr->svc_chname, NULL); diff -rpbu10 irc2.11.0a8/common/struct_def.h irc2.11.0a8-cvs+pl/common/struct_def.h --- irc2.11.0a8/common/struct_def.h Wed Apr 7 19:02:37 2004 +++ irc2.11.0a8-cvs+pl/common/struct_def.h Mon May 17 00:30:25 2004 @@ -174,22 +174,28 @@ typedef struct LineItem aExtData; #define FLAGS_LISTENINACTIVE 0x8000000 /* Listener does not listen() */ #define FLAGS_OPER 0x0001 /* operator */ #define FLAGS_LOCOP 0x0002 /* local operator -- SRB */ #define FLAGS_WALLOP 0x0004 /* send wallops to them */ #define FLAGS_INVISIBLE 0x0008 /* makes user invisible */ #define FLAGS_RESTRICT 0x0010 /* restricted user */ #define FLAGS_AWAY 0x0020 /* user is away */ #define FLAGS_EXEMPT 0x0040 /* user is exempted from k-lines */ +#define FLAGS_FLOOD 0x0080 /* user can flood */ + +#ifdef XLINE +#define FLAGS_XLINED 0x0100 /* X-lined client */ +#endif + #define SEND_UMODES (FLAGS_INVISIBLE|FLAGS_OPER|FLAGS_WALLOP|FLAGS_AWAY) -#define ALL_UMODES (SEND_UMODES|FLAGS_LOCOP|FLAGS_RESTRICT) +#define ALL_UMODES (SEND_UMODES|FLAGS_LOCOP|FLAGS_RESTRICT|FLAGS_FLOOD) /* * user flags macros. */ #define IsOper(x) ((x)->user && (x)->user->flags & FLAGS_OPER) #define IsLocOp(x) ((x)->user && (x)->user->flags & FLAGS_LOCOP) #define IsInvisible(x) ((x)->user->flags & FLAGS_INVISIBLE) #define IsRestricted(x) ((x)->user && \ (x)->user->flags & FLAGS_RESTRICT) #define IsAnOper(x) ((x)->user && \ @@ -199,36 +205,38 @@ typedef struct LineItem aExtData; #define SendWallops(x) ((x)->user->flags & FLAGS_WALLOP) #ifdef UNIXPORT #define IsUnixSocket(x) ((x)->flags & FLAGS_UNIX) #endif #define IsListener(x) ((x)->flags & FLAGS_LISTEN) #define IsListenerInactive(x) ((x)->flags & FLAGS_LISTENINACTIVE) #define IsLocal(x) (MyConnect(x) && (x)->flags & FLAGS_LOCAL) #define IsDead(x) ((x)->flags & FLAGS_DEADSOCK) #define IsBursting(x) (!((x)->flags & FLAGS_EOB)) #define IsKlineExempt(x) ((x)->user && (x)->user->flags & FLAGS_EXEMPT) +#define CanFlood(x) ((x)->user && (x)->user->flags & FLAGS_FLOOD) #define SetDead(x) ((x)->flags |= FLAGS_DEADSOCK) #define CBurst(x) ((x)->flags & FLAGS_CBURST) #define SetOper(x) ((x)->user->flags |= FLAGS_OPER) #define SetLocOp(x) ((x)->user->flags |= FLAGS_LOCOP) #define SetInvisible(x) ((x)->user->flags |= FLAGS_INVISIBLE) #define SetRestricted(x) ((x)->user->flags |= FLAGS_RESTRICT) #define SetWallops(x) ((x)->user->flags |= FLAGS_WALLOP) #ifdef UNIXPORT #define SetUnixSock(x) ((x)->flags |= FLAGS_UNIX) #endif #define SetDNS(x) ((x)->flags |= FLAGS_DOINGDNS) #define SetDoneXAuth(x) ((x)->flags |= FLAGS_XAUTHDONE) #define SetEOB(x) ((x)->flags |= FLAGS_EOB) #define SetListenerInactive(x) ((x)->flags |= FLAGS_LISTENINACTIVE) #define SetKlineExempt(x) ((x)->user->flags |= FLAGS_EXEMPT) +#define SetUserFlood(x) ((x)->user->flags |= FLAGS_FLOOD) #define DoingDNS(x) ((x)->flags & FLAGS_DOINGDNS) #define DoingAuth(x) ((x)->flags & FLAGS_AUTH) #define DoingXAuth(x) ((x)->flags & FLAGS_XAUTH) #define WaitingXAuth(x) ((x)->flags & FLAGS_WXAUTH) #define DoneXAuth(x) ((x)->flags & FLAGS_XAUTHDONE) #define NoNewLine(x) ((x)->flags & FLAGS_NONL) #define ClearOper(x) ((x)->user->flags &= ~FLAGS_OPER) #define ClearInvisible(x) ((x)->user->flags &= ~FLAGS_INVISIBLE) @@ -317,45 +325,58 @@ struct ListItem { #define CONF_CLASS 0x001000 #define CONF_SERVICE 0x002000 #define CONF_LEAF 0x004000 #define CONF_LISTEN_PORT 0x008000 #define CONF_HUB 0x010000 #define CONF_VER 0x020000 #define CONF_BOUNCE 0x040000 #define CONF_OTHERKILL 0x080000 #define CONF_DENY 0x100000 +#ifdef XLINE +#define CONF_XLINE 0x200000 +#endif + #define CONF_OPS (CONF_OPERATOR | CONF_LOCOP) #define CONF_SERVER_MASK (CONF_CONNECT_SERVER | CONF_NOCONNECT_SERVER |\ CONF_ZCONNECT_SERVER) #define CONF_CLIENT_MASK (CONF_CLIENT | CONF_SERVICE | CONF_OPS | \ CONF_SERVER_MASK) #define CFLAG_RESTRICTED 0x00001 #define CFLAG_RNODNS 0x00002 #define CFLAG_RNOIDENT 0x00004 #define CFLAG_KEXEMPT 0x00008 #define CFLAG_NORESOLVE 0x00010 #define CFLAG_FALL 0x00020 #define CFLAG_NORESOLVEMATCH 0x00040 +#define CFLAG_FLOOD 0x00080 #define IsConfRestricted(x) ((x)->flags & CFLAG_RESTRICTED) #define IsConfRNoDNS(x) ((x)->flags & CFLAG_RNODNS) #define IsConfRNoIdent(x) ((x)->flags & CFLAG_RNOIDENT) #define IsConfKlineExempt(x) ((x)->flags & CFLAG_KEXEMPT) #define IsConfNoResolve(x) ((x)->flags & CFLAG_NORESOLVE) #define IsConfNoResolveMatch(x) ((x)->flags & CFLAG_NORESOLVEMATCH) #define IsConfFallThrough(x) ((x)->flags & CFLAG_FALL) +#define IsConfFlood(x) ((x)->flags & CFLAG_FLOOD) #define PFLAG_DELAYED 0x00001 #define PFLAG_SERVERONLY 0x00002 +#ifdef XLINE +#define XFLAG_WHOLE 0x00001 +#define IsConfXlineWhole(x) ((x)->flags & XFLAG_WHOLE) +#define IsXlined(x) ((x)->user && (x)->user->flags & FLAGS_XLINED) +#define SetXlined(x) ((x)->user->flags |= FLAGS_XLINED) +#endif + #define IsConfDelayed(x) ((x)->flags & PFLAG_DELAYED) #define IsConfServeronly(x) ((x)->flags & PFLAG_SERVERONLY) #define IsIllegal(x) ((x)->status & CONF_ILLEGAL) typedef struct { u_long pi_id; u_long pi_seq; struct timeval pi_tv; aConfItem *pi_cp; @@ -872,21 +893,26 @@ typedef struct { #define SCH_KILL 3 #define SCH_CHAN 4 #define SCH_NUM 5 #define SCH_SERVER 6 #define SCH_HASH 7 #define SCH_LOCAL 8 #define SCH_SERVICE 9 #define SCH_DEBUG 10 #define SCH_AUTH 11 #define SCH_SAVE 12 +#ifdef CLIENTS_CHANNEL +#define SCH_OPER 13 +#define SCH_MAX 13 +#else #define SCH_MAX 12 +#endif /* used for async dns values */ #define ASYNC_NONE (-1) #define ASYNC_CLIENT 0 #define ASYNC_CONNECT 1 #define ASYNC_CONF 2 #define ASYNC_SERVER 3 /* Client exit codes for log file */ @@ -909,20 +935,23 @@ typedef struct { #define EXITC_LUHMAX 'l' /* local clients per user@host max limit */ #define EXITC_MBUF 'M' /* mem alloc error */ #define EXITC_PING 'P' /* ping timeout */ #define EXITC_BADPASS 'p' /* bad password */ #define EXITC_SENDQ 'Q' /* send queue exceeded */ #define EXITC_REF 'R' /* Refused */ #define EXITC_AREF 'U' /* Unauthorized by iauth */ #define EXITC_AREFQ 'u' /* Unauthorized by iauth, be quiet */ #define EXITC_VIRUS 'v' /* joined a channel used by PrettyPark virus */ #define EXITC_YLINEMAX 'Y' /* Y:line max clients limit */ +#ifdef XLINE +#define EXITC_XLINE 'X' /* Forbidden GECOS */ +#endif /* eXternal authentication slave OPTions */ #define XOPT_REQUIRED 0x01 /* require authentication be done by iauth */ #define XOPT_NOTIMEOUT 0x02 /* disallow iauth time outs */ #define XOPT_EXTWAIT 0x10 /* extend registration ping timeout */ #define XOPT_EARLYPARSE 0x20 /* allow early parsing and send USER/PASS information to iauth */ /* misc defines */ diff -rpbu10 irc2.11.0a8/common/support.c irc2.11.0a8-cvs+pl/common/support.c --- irc2.11.0a8/common/support.c Sun Feb 15 14:17:40 2004 +++ irc2.11.0a8-cvs+pl/common/support.c Mon May 17 00:30:25 2004 @@ -755,20 +755,21 @@ char *make_version(void) sscanf(PATCHLEVEL, "%2d%2d%2d%2d%2d", &ve, &re, &mi, &dv, &pl); /* version & revision */ sprintf(ver, "%d.%d", ve, (mi == 99) ? re + 1 : re); if (mi == 99) mi = -1; /* minor revision */ sprintf(ver + strlen(ver), ".%d", dv ? mi+1 : mi); if (dv) /* alpha/beta, note how visual patchlevel is raised above */ sprintf(ver + strlen(ver), "%c%d", DEVLEVEL, dv); if (pl) /* patchlevel */ sprintf(ver + strlen(ver), "p%d", pl); + strcat(ver,"-cvs+pl"); return mystrdup(ver); } #ifndef CLIENT_COMPILE /* Make RPL_ISUPPORT (005) numeric contents */ char **make_isupport(void) { char **tis; tis = (char **) MyMalloc(3 * sizeof(char *)); Only in irc2.11.0a8-cvs+pl: i386-unknown-freebsd4.9 diff -rpbu10 irc2.11.0a8/ircd/channel.c irc2.11.0a8-cvs+pl/ircd/channel.c --- irc2.11.0a8/ircd/channel.c Fri May 14 16:22:19 2004 +++ irc2.11.0a8-cvs+pl/ircd/channel.c Mon May 17 00:30:25 2004 @@ -689,20 +689,27 @@ void setup_server_channels(aClient *mp) chptr = get_channel(mp, "&SAVE", CREATE); strcpy(chptr->topic, "SERVER MESSAGES: save messages"); add_user_to_channel(chptr, mp, CHFL_CHANOP); chptr->mode.mode = smode; chptr = get_channel(mp, "&DEBUG", CREATE); strcpy(chptr->topic, "SERVER MESSAGES: debug messages [you shouldn't be here! ;)]"); add_user_to_channel(chptr, mp, CHFL_CHANOP); chptr->mode.mode = smode|MODE_SECRET; +#ifdef SCH_OPER + chptr = get_channel(mp, "&OPER", CREATE); + strcpy(chptr->topic,"SERVER MESSAGES: opers-only notices"); + add_user_to_channel(chptr, mp, CHFL_CHANOP); + chptr->mode.mode = smode|MODE_SECRET; +#endif + setup_svchans(); } /* * write the "simple" list of channel modes for channel chptr onto buffer mbuf * with the parameters in pbuf. */ void channel_modes(aClient *cptr, char *mbuf, char *pbuf, aChannel *chptr) { *mbuf++ = '+'; @@ -1725,21 +1732,21 @@ static int set_mode(aClient *cptr, aClie ** will be reset to 0 in is_chan_op() ** and even if not, reop_channel() will ** NOT give ops if ops are already on ** the channel. --B. */ if (IsServer(sptr)) { chptr->reop = timeofday + LDELAYCHASETIMELIMIT; } /* XXX: fix this in 2.11.1 */ - if (MyClient(sptr)) + if (MyClient(sptr) && !IsAnOper(sptr)) { break; } } if (ischop && (((whatt & MODE_ADD) && !add_modeid(tmp_chfl, sptr, chptr, lp->value.alist))|| ((whatt & MODE_DEL) && !del_modeid(tmp_chfl, chptr, @@ -1856,20 +1863,30 @@ static int can_join(aClient *sptr, aChan { if (match_modeid(CHFL_EXCEPTION, sptr, chptr)) { banned = NULL; } else if (lp == NULL) /* not invited */ { return (ERR_BANNEDFROMCHAN); } } + +#ifdef CLIENTS_CHANNEL + if (chptr->chname[0] == '&') + { + if (!strcmp(chptr->chname, "&OPER") && !IsAnOper(sptr)) + { + return (ERR_INVITEONLYCHAN); + } + } +#endif if ((chptr->mode.mode & MODE_INVITEONLY) && !match_modeid(CHFL_INVITE, sptr, chptr) && (lp == NULL)) return (ERR_INVITEONLYCHAN); if (*chptr->mode.key && (BadPtr(key) || mycmp(chptr->mode.key, key))) return (ERR_BADCHANNELKEY); if (chptr->mode.limit && (chptr->users >= chptr->mode.limit)) diff -rpbu10 irc2.11.0a8/ircd/chkconf.c irc2.11.0a8-cvs+pl/ircd/chkconf.c --- irc2.11.0a8/ircd/chkconf.c Fri Mar 5 23:06:10 2004 +++ irc2.11.0a8-cvs+pl/ircd/chkconf.c Mon May 17 00:30:25 2004 @@ -348,20 +348,25 @@ static aConfItem *initconf() case 's': /* CONF_OPERATOR */ aconf->status = CONF_SERVICE; break; case 'V': aconf->status = CONF_VER; break; case 'Y': case 'y': aconf->status = CONF_CLASS; break; +#ifdef XLINE + case 'X': + aconf->status = CONF_XLINE; + break; +#endif default: (void)fprintf(stderr, "%s:%d\tWARNING: unknown conf line letter (%c)\n", filelist->filename, nr - filelist->min, *tmp); break; } if (IsIllegal(aconf)) continue; for (;;) /* Fake loop, that I can use break here --msa */ diff -rpbu10 irc2.11.0a8/ircd/ircd.c irc2.11.0a8-cvs+pl/ircd/ircd.c --- irc2.11.0a8/ircd/ircd.c Sun May 16 18:37:25 2004 +++ irc2.11.0a8-cvs+pl/ircd/ircd.c Mon May 17 00:30:25 2004 @@ -59,20 +59,24 @@ volatile static int dorehash = 0, time_t nextdelayclose = 0; /* time for next delayed close */ #endif time_t nextconnect = 1; /* time for next try_connections call */ time_t nextgarbage = 1; /* time for next collect_channel_garbage call*/ time_t nextping = 1; /* same as above for check_pings() */ time_t nextdnscheck = 0; /* next time to poll dns to force timeouts */ time_t nextexpire = 1; /* next expire run on the dns cache */ time_t nextiarestart = 1; /* next time to check if iauth is alive */ time_t nextpreference = 1; /* time for next calculate_preference call */ +#ifdef TKLINE +time_t nexttkexpire = 0; +#endif + RETSIGTYPE s_die(int s) { #ifdef USE_SYSLOG (void)syslog(LOG_CRIT, "Server Killed By SIGTERM"); (void)closelog(); #endif logfiles_close(); ircd_writetune(tunefile); flush_connections(me.fd); exit(-1); @@ -1081,20 +1085,26 @@ static void io_loop(void) ** not every time through. Note, if there are no ** active C lines, this call to Tryconnections is ** made once only; it will return 0. - avalon */ if (nextconnect && timeofday >= nextconnect) nextconnect = try_connections(timeofday); #ifdef DELAY_CLOSE /* close all overdue delayed fds */ if (nextdelayclose && timeofday >= nextdelayclose) nextdelayclose = delay_close(-1); +#endif +#ifdef TKLINE + if (nexttkexpire && (timeofday >= nexttkexpire)) + { + nexttkexpire = expire_tklines(); + } #endif /* ** Every once in a while, hunt channel structures that ** can be freed. Reop channels while at it, too. */ if (timeofday >= nextgarbage) nextgarbage = collect_channel_garbage(timeofday); /* ** DNS checks. One to timeout queries, one for cache expiries. */ diff -rpbu10 irc2.11.0a8/ircd/ircd_ext.h irc2.11.0a8-cvs+pl/ircd/ircd_ext.h --- irc2.11.0a8/ircd/ircd_ext.h Sun Mar 21 01:39:49 2004 +++ irc2.11.0a8-cvs+pl/ircd/ircd_ext.h Mon May 17 00:30:25 2004 @@ -40,20 +40,23 @@ extern char *debugmode; extern char *sbrk0; extern char *tunefile; #ifdef DELAY_CLOSE extern time_t nextdelayclose; #endif extern time_t nextconnect; extern time_t nextgarbage; extern time_t nextping; extern time_t nextdnscheck; extern time_t nextexpire; +#ifdef TKLINE +extern time_t nexttkexpire; +#endif #endif /* IRCD_C */ /* External definitions for global functions. */ #ifndef IRCD_C #define EXTERN extern #else /* IRCD_C */ #define EXTERN #endif /* IRCD_C */ EXTERN RETSIGTYPE s_die (int s); diff -rpbu10 irc2.11.0a8/ircd/res.c irc2.11.0a8-cvs+pl/ircd/res.c --- irc2.11.0a8/ircd/res.c Wed Mar 24 00:44:27 2004 +++ irc2.11.0a8-cvs+pl/ircd/res.c Mon May 17 00:30:25 2004 @@ -926,31 +926,31 @@ struct hostent *get_res(char *lp) Debug((DEBUG_DNS, "Fatal DNS error %d for %d", h_errno, hptr->rcode)); rptr->resend = 0; rptr->retries = 0; } goto getres_err; } a = proc_answer(rptr, hptr, buf, buf+rc); if (a == -1) { #ifdef INET6 - sprintf(buffer, "Bad hostname returned from %s for %s", + sprintf(buffer, "DNS: Bad hostname returned from %s for %s", inetntop(AF_INET6, &sin.sin6_addr, mydummy2, MYDUMMY_SIZE), inetntop(AF_INET6, rptr->he.h_addr.s6_addr, mydummy, MYDUMMY_SIZE)); #else - sprintf(buffer, "Bad hostname returned from %s for ", + sprintf(buffer, "DNS: Bad hostname returned from %s for ", inetntoa((char *)&sin.sin_addr)); strcat(buffer, inetntoa((char *)&rptr->he.h_addr)); #endif - sendto_flag(SCH_ERROR, "%s", buffer); + sendto_flag(SCH_OPER, "%s", buffer); Debug((DEBUG_DNS, "%s", buffer)); } #ifdef DEBUG Debug((DEBUG_INFO,"get_res:Proc answer = %d",a)); #endif if (a > 0 && rptr->type == T_PTR) { struct hostent *hp2 = NULL; int type; diff -rpbu10 irc2.11.0a8/ircd/s_bsd.c irc2.11.0a8-cvs+pl/ircd/s_bsd.c --- irc2.11.0a8/ircd/s_bsd.c Sun Apr 18 06:31:50 2004 +++ irc2.11.0a8-cvs+pl/ircd/s_bsd.c Mon May 17 00:30:25 2004 @@ -1902,21 +1902,21 @@ static int read_packet(aClient *cptr, in else { /* ** Before we even think of parsing what we just read, stick ** it on the end of the receive queue and do it when its ** turn comes around. */ if (length && dbuf_put(&cptr->recvQ, readbuf, length) < 0) return exit_client(cptr, cptr, &me, "dbuf_put fail"); - if (IsPerson(cptr) && + if (IsPerson(cptr) && !CanFlood(cptr) && DBufLength(&cptr->recvQ) > CLIENT_FLOOD) { cptr->exitc = EXITC_FLOOD; return exit_client(cptr, cptr, &me, "Excess Flood"); } return client_packet(cptr); } return 1; } diff -rpbu10 irc2.11.0a8/ircd/s_conf.c irc2.11.0a8-cvs+pl/ircd/s_conf.c --- irc2.11.0a8/ircd/s_conf.c Fri May 7 21:29:12 2004 +++ irc2.11.0a8-cvs+pl/ircd/s_conf.c Mon May 17 00:30:25 2004 @@ -70,20 +70,23 @@ struct Config char *line; aConfig *next; }; void config_file(char *, char *, char *); aConfig *config_read(int, int); #endif aConfItem *conf = NULL; aConfItem *kconf = NULL; +#ifdef TKLINE +aConfItem *tkconf = NULL; +#endif char *networkname = NULL; /* Parse I-lines flags from string. * D - Restricted, if no DNS. * I - Restricted, if no ident. * R - Restricted. * E - Kline exempt. * N - Do not resolve hostnames (show as IP). * F - Fallthrough to next I:line when password not matched */ @@ -117,20 +120,24 @@ long iline_flags_parse(char *string) tmp |= CFLAG_NORESOLVE; } if (index(string,'M')) { tmp |= CFLAG_NORESOLVEMATCH; } if (index(string,'F')) { tmp |= CFLAG_FALL; } + if (index(string,'|')) + { + tmp |= CFLAG_FLOOD; + } return tmp; } /* convert iline flags to human readable string */ char *iline_flags_to_string(long flags) { static char ifsbuf[BUFSIZE]; char *s = ifsbuf; @@ -205,20 +212,52 @@ char *pline_flags_to_string(long flags) } if (s == pfsbuf) { *s++ = '-'; } *s++ = '\0'; return pfsbuf; } + +#ifdef XLINE +char *xline_flags_to_string(long flags) +{ + static char xfsbuf[BUFSIZE]; + char *s; + + s = xfsbuf; + + if (flags & XFLAG_WHOLE) + { + *s++ = 'W'; + } + if (s == xfsbuf) + { + *s++ = '-'; + } + *s++ = '\0'; + return xfsbuf; +} + +long xline_flags_parse(char *string) +{ + long tmp = 0; + if (index(string, 'W')) + { + tmp |= XFLAG_WHOLE; + } + return tmp; +} +#endif + /* * remove all conf entries from the client except those which match * the status field mask. */ void det_confs_butmask(aClient *cptr, int mask) { Reg Link *tmp, *tmp2; for (tmp = cptr->confs; tmp; tmp = tmp2) { @@ -441,20 +480,24 @@ int attach_Iline(aClient *cptr, struct h if (IsConfRestricted(aconf) || (!hp && IsConfRNoDNS(aconf)) || (!(cptr->flags & FLAGS_GOTID) && IsConfRNoIdent(aconf))) { SetRestricted(cptr); } if (IsConfKlineExempt(aconf)) { SetKlineExempt(cptr); } + if (IsConfFlood(aconf)) + { + SetUserFlood(cptr); + } /* Copy uhost (hostname) over sockhost, if conf flag permits. */ if (hp && !IsConfNoResolve(aconf)) { get_sockhost(cptr, uhost+ulen); } /* Note that attach_conf() should not return -2. */ if ((retval = attach_conf(cptr, aconf)) < -1) { find_bounce(cptr, ConfClass(aconf), -1); @@ -1392,20 +1435,25 @@ int initconf(int opt) case 's': /* CONF_OPERATOR */ aconf->status = CONF_SERVICE; break; case 'V': /* Server link version requirements */ aconf->status = CONF_VER; break; case 'Y': case 'y': aconf->status = CONF_CLASS; break; +#ifdef XLINE + case 'X': + aconf->status = CONF_XLINE; + break; +#endif default: Debug((DEBUG_ERROR, "Error in config file: %s", line)); break; } if (IsIllegal(aconf)) continue; for (;;) /* Fake loop, that I can use break here --msa */ { if ((tmp = getfield(NULL)) == NULL) @@ -1529,20 +1577,26 @@ int initconf(int opt) else /* no such conf line was found */ { if (aconf->host && aconf->status == CONF_LISTEN_PORT) { (void)add_listener(aconf); } } } +#ifdef XLINE + if (aconf->status & CONF_XLINE && tmp3) + { + aconf->flags = xline_flags_parse(tmp3); + } +#endif if (aconf->status & CONF_SERVICE) aconf->port &= SERVICE_MASK_ALL; if (aconf->status & (CONF_SERVER_MASK|CONF_SERVICE)) if (ncount > MAXCONFLINKS || ccount > MAXCONFLINKS || !aconf->host || index(aconf->host, '*') || index(aconf->host,'?') || !aconf->name) continue; if (aconf->status & (CONF_SERVER_MASK|CONF_LOCOP|CONF_OPERATOR|CONF_SERVICE)) @@ -1826,20 +1880,79 @@ int find_kill(aClient *cptr, int timedkl if (!BadPtr(tmp->passwd) && isdigit(*tmp->passwd) && !(now = check_time_interval(tmp->passwd, reply))) continue; if (now == ERR_YOUWILLBEBANNED) tmp = NULL; #endif break; } } +#ifdef TKLINE + for (tmp = tkconf; tmp; tmp = tmp->next) + { +#ifdef TIMEDKLINES + if (timedklines && (BadPtr(tmp->passwd) || !isdigit(*tmp->passwd))) + continue; +#endif + if (!(tmp->status & (CONF_KILL | CONF_OTHERKILL))) + continue; /* should never happen with kconf */ + if (!tmp->host || !tmp->name) + continue; + if (tmp->status == CONF_KILL) + check = name; + else + check = ident; + /* host & IP matching.. */ + if (!ip) /* unresolved */ + { + if (strchr(tmp->host, '/')) + { + if (match_ipmask((*tmp->host == '=') ? + tmp->host+1: tmp->host, cptr, 1)) + continue; + } + else + if (match((*tmp->host == '=') ? tmp->host+1 : + tmp->host, host)) + continue; + } + else if (*tmp->host == '=') /* numeric only */ + continue; + else /* resolved */ + if (strchr(tmp->host, '/')) + { + if (match_ipmask(tmp->host, cptr, 1)) + continue; + } + else + if (match(tmp->host, ip) && + match(tmp->host, host)) + continue; + + /* user & port matching */ + if ((!check || match(tmp->name, check) == 0) && + (!tmp->port || (tmp->port == cptr->acpt->port))) + { +#ifdef TIMEDKLINES + now = 0; + if (!BadPtr(tmp->passwd) && isdigit(*tmp->passwd) && + !(now = check_time_interval(tmp->passwd, reply))) + continue; + if (now == ERR_YOUWILLBEBANNED) + tmp = NULL; +#endif + break; + } + } +#endif + if (tmp && !BadPtr(tmp->passwd)) { *comment = tmp->passwd; } else { *comment = NULL; } #ifdef TIMEDKLINES if (*reply) @@ -2226,12 +2339,357 @@ aConfig *config_read(int fd, int depth) } else { ConfigTop = new; } ConfigCur = new; i = p + 1; } munmap(address, len); return ConfigTop; +} +#endif + +#ifdef TKLINE +/* parv[1] - kline duration in seconds + * parv[2] - user@host + * parv[3] - reason + */ +int m_tkline(aClient *cptr, aClient *sptr, int parc, char *parv[]) +{ + aConfItem *aconf, *tktmp, **tktmp_o; + aClient *acptr, *bcptr; + int out, i; + char buffer[1024]; + char *user, *host; + char *kline_reason; + time_t current_time; + int expire; + + if (!IsAnOper(sptr) && !IsService(sptr)) + { + sendto_one(sptr, replies[ERR_NOPRIVILEGES], ME, BadTo(parv[0])); + return 2; + } + + if (parc < 4) + { + sendto_one(sptr, replies[ERR_NEEDMOREPARAMS], ME, + BadTo(parv[0]), "TKLINE"); + return 2; + } + + user = parv[2]; + host = strchr(user, '@'); + /* parv[2] is not in correct format */ + if (!host) + { + if (IsService(sptr)) + { + sendto_flag(SCH_NOTICE,"Service %s tried to add bad" + " tkline %s", sptr->name, parv[2]); + } + else + { + sendto_one(sptr, + ":%s NOTICE %s :Sorry but \"%s\" needs" + " to be of the format of user@host", + ME, parv[0], parv[1]); + } + return 2; + } + + *host++ = '\0'; + + /* check for illegal characters */ + for (i = 0; i < strlen(parv[2]); i++) + { + if ((parv[2][i] == '#') || (parv[2][i] == IRCDCONF_DELIMITER)) + { + if (IsService(sptr)) + { + sendto_flag(SCH_NOTICE, "Service %s tried to " + "add tkline %s with illegal character %c", + sptr->name, parv[2], parv[2][i]); + } + else + { + sendto_one(sptr, ":%s NOTICE %s :Kline may not" + " contain %c", parv[2][i]); + } + + return 2; + } + } + + + + /* Check reason */ + kline_reason = parv[3]; + if (isdigit(*kline_reason)) + { + if (!IsService(sptr)) + { + sendto_one(sptr, + ":%s NOTICE %s :The tkline reason may not " + "start with a digit", ME, parv[0]); + } + else + { + sendto_flag(SCH_NOTICE, "Service %s tried to add " + "tkline with a reason starting with a digit", + sptr->name); + } + return 0; + } + + if (strlen(kline_reason) > TOPICLEN) + { + kline_reason[TOPICLEN] = '\0'; + } + + for (i = strlen(kline_reason) - 1; i >= 0; i--) + { + if ((kline_reason[i] == '#') || + (kline_reason[i] == IRCDCONF_DELIMITER)) + { + if (!IsService(sptr)) + { + sendto_one(sptr, + ":%s NOTICE %s :The tkline reason may not " + "contain '%c'", ME, parv[0], kline_reason[i]); + } + else + { + sendto_flag(SCH_NOTICE, "Service %s tried " + "to add tkline with an invalid reason", + sptr->name); + } + return 0; + } + /* Replace spaces with ANSI ones */ + if (kline_reason[i] == ' ') + { + kline_reason[i] = '\240'; + } + } + /* Check expiration */ + expire = atoi(parv[1]); + if (expire <= 0) + { + if (!IsService(sptr)) + { + sendto_one(sptr, + ":%s NOTICE %s :The tkline duration has to be " + "a positive integer", ME, parv[0]); + } + else + { + sendto_flag(SCH_NOTICE, "Service %s tried to add " + "tkline with invalid duration", + sptr->name); + } + return 0; + + } + aconf = make_conf(); + aconf->next = NULL; + aconf->status = CONF_KILL; + DupString(aconf->host, host); + DupString(aconf->passwd, kline_reason); + DupString(aconf->name, user); + aconf->hold = timeofday + expire; + aconf->port = 0; + Class(aconf) = find_class(0); + /* put the new tkline into sorted list - first expired go first */ + if (tkconf) + { + /* Find place */ + for (tktmp_o = &tkconf; (tktmp = *tktmp_o); + tktmp_o = &tktmp->next) + { + if (tktmp->hold <= timeofday && + (tktmp->next && (tktmp->next->hold < timeofday))) + { + continue; + } + aconf->next = tktmp; + *tktmp_o = aconf; + } + } + else + { + /* no tkline yet */ + tkconf = aconf; + } + nexttkexpire = tkconf->hold; + + sendto_flag(SCH_NOTICE, "%s added a tkline (%d) for %s@%s with " + "reason: %s", parv[0], expire, user, host, kline_reason); + if (!IsService(sptr)) + { + sendto_one(sptr, + ":%s NOTICE %s :Added tkline (%d) for %s@%s with reason: %s", + me.name, parv[0], expire, user, host, kline_reason); + } + + /* Check users against the tkline */ + for (i = highest_fd ; i>=0; i--) + { + char *ip; + + if (!(bcptr = local[i])) + continue; + if (!IsPerson(bcptr)) + { + continue; + } + if (IsKlineExempt(bcptr)) + { + continue; + } +#ifdef INET6 + ip = (char *) inetntop(AF_INET6, (char *)&bcptr->ip, mydummy, + MYDUMMY_SIZE); +#else + ip = (char *) inetntoa((char *)&bcptr->ip); +#endif + if (!strcmp(bcptr->sockhost, ip)) + { + ip = NULL; + } + if (!ip) /* unresolved */ + { + if (strchr(aconf->host, '/')) + { + if (match_ipmask((*aconf->host == '=') ? + aconf->host+1: aconf->host, + bcptr, 1)) + continue; + } + else + { + if (match((*aconf->host == '=') ? + aconf->host+1 : aconf->host, + bcptr->sockhost)) + continue; + } + } + else if (*aconf->host == '=') /* numeric only */ + continue; + else /* resolved */ + { + if (strchr(aconf->host, '/')) + { + if (match_ipmask(aconf->host, bcptr, 1)) + continue; + } + else + if (match(aconf->host, ip) && + match(aconf->host, bcptr->user->host)) + continue; + } + if (match(aconf->name, bcptr->user->username) == 0) + { + char buf[BUFSIZE+1]; + sendto_one(bcptr, replies[ERR_YOUREBANNEDCREEP], + ME, bcptr->name, + BadPtr(aconf->name) ? "*" : aconf->name, + BadPtr(aconf->host) ? "*" : aconf->host, + ": ", kline_reason); + + sendto_flag(SCH_NOTICE, + "Kill line active for %s", + get_client_name(bcptr, FALSE)); + bcptr->exitc = EXITC_KLINE; + sprintf(buf, "Kill line active: %.80s", + kline_reason); + (void)exit_client(bcptr, bcptr, &me, buf); + } + + } + + return 0; +} +/* parv[1] - user@host to remove */ +int m_untkline(aClient *cptr, aClient *sptr, int parc, char *parv[]) +{ + aConfItem *tktmp, **tktmp_o; + char *user, *host; + int found = 0; + + if (!IsAnOper(sptr) && !IsService(sptr)) + { + sendto_one(sptr, replies[ERR_NOPRIVILEGES], ME, BadTo(parv[0])); + return 2; + } + + if (parc < 2) + { + sendto_one(sptr, replies[ERR_NEEDMOREPARAMS], ME, + BadTo(parv[0]), "TKLINE"); + return 1; + } + + user = parv[1]; + host = strchr(user, '@'); + + if (host) + { + *host++ = '\0'; + } + else + { + sendto_one(sptr, replies[ERR_NEEDMOREPARAMS], ME, + BadTo(parv[0]), "UNTKLINE"); + return 1; + } + + if (tkconf) + { + for (tktmp_o = &tkconf; (tktmp = *tktmp_o); + tktmp_o = &tktmp->next) + { + if (!mycmp(tktmp->host, host) && + !mycmp(tktmp->name, user)) + { + *tktmp_o = tktmp->next; + free_conf(tktmp); + found = 1; + } + } + } + if (!IsService(sptr)) + { + sendto_one(sptr, ":%s NOTICE %s :tkline %s@%s %s", ME, + parv[0], user, host, found ? "removed" : "not found"); + } + if (found) + { + sendto_flag(SCH_NOTICE, "%s removed tkline %s@%s", parv[0], + user, host); + } + return 0; +} + + +/* Remove expired tklines */ +time_t expire_tklines() +{ + aConfItem *tktmp, **tktmp_o; + + if (tkconf) + { + for (tktmp_o = &tkconf; (tktmp = *tktmp_o); + tktmp_o = &tktmp->next) + { + if (tktmp->hold < timeofday) + { + *tktmp_o = tktmp->next; + free_conf(tktmp); + } + } + } + + return tkconf ? tkconf->hold : 0; } #endif diff -rpbu10 irc2.11.0a8/ircd/s_conf_ext.h irc2.11.0a8-cvs+pl/ircd/s_conf_ext.h --- irc2.11.0a8/ircd/s_conf_ext.h Sat Mar 20 22:14:33 2004 +++ irc2.11.0a8-cvs+pl/ircd/s_conf_ext.h Mon May 17 00:30:25 2004 @@ -18,20 +18,23 @@ */ /* This file contains external definitions for global variables and functions defined in ircd/s_conf.c. */ /* External definitions for global variables. */ #ifndef S_CONF_C extern aConfItem *conf, *kconf; +#ifdef TKLINE +extern aConfItem *tkconf; +#endif extern char *networkname; #endif /* S_CONF_C */ /* External definitions for global functions. */ #ifndef S_CONF_C #define EXTERN extern #else /* S_CONF_C */ #define EXTERN #endif /* S_CONF_C */ @@ -66,14 +69,23 @@ EXTERN int initconf (int opt); EXTERN int find_kill (aClient *cptr, int timedklines, char **comment); EXTERN int find_two_masks (char *name, char *host, int stat); EXTERN int find_conf_flags (char *name, char *key, int stat); EXTERN int find_restrict (aClient *cptr); EXTERN void find_bounce (aClient *cptr, int class, int fd); EXTERN aConfItem *find_denied (char *name, int class); EXTERN char *iline_flags_to_string(long flags); EXTERN long iline_flags_parse(char *string); EXTERN char *pline_flags_to_string(long flags); EXTERN long pline_flags_parse(char *string); +#ifdef XLINE +EXTERN char *xline_flags_to_string(long flags); +EXTERN long xline_flags_parse(char *string); +#endif # ifdef INET6 EXTERN char *ipv6_convert (char *orig); # endif +#ifdef TKLINE +EXTERN time_t expire_tklines(); +EXTERN int m_tkline(aClient *cptr, aClient *sptr, int parc, char *parv[]); +EXTERN int m_untkline(aClient *cptr, aClient *sptr, int parc, char *parv[]); +#endif #undef EXTERN diff -rpbu10 irc2.11.0a8/ircd/s_err.c irc2.11.0a8-cvs+pl/ircd/s_err.c --- irc2.11.0a8/ircd/s_err.c Wed May 12 18:39:53 2004 +++ irc2.11.0a8-cvs+pl/ircd/s_err.c Mon May 17 00:30:25 2004 @@ -416,21 +416,21 @@ char * replies[] = { /* 371 RPL_INFO */ ":%s 371 %s :%s", /* 372 RPL_MOTD */ ":%s 372 %s :- %s", /* 373 RPL_INFOSTART */ ":%s 373 %s :Server INFO", /* 374 RPL_ENDOFINFO */ ":%s 374 %s :End of INFO list.", /* 375 RPL_MOTDSTART */ ":%s 375 %s :- %s Message of the Day - ", /* 376 RPL_ENDOFMOTD */ ":%s 376 %s :End of MOTD command.", /* 377 */ (char *)NULL, /* 378 */ (char *)NULL, /* 379 */ (char *)NULL, /* 380 */ (char *)NULL, -/* 381 RPL_YOUREOPER */ ":%s 381 %s :You are now an IRC Operator", +/* 381 RPL_YOUREOPER */ ":%s 381 %s :You are a nice shark now. Fish are friends, not food.", /* 382 RPL_REHASHING */ ":%s 382 %s %s :Rehashing", /* 383 RPL_YOURESERVICE */ ":%s 383 %s :You are service %s", /* 384 RPL_MYPORTIS */ ":%s 384 %s %d :Port to local server is\r\n", /* 385 RPL_NOTOPERANYMORE */ (char *)NULL, /* 386 */ (char *)NULL, /* 387 */ (char *)NULL, /* 388 */ (char *)NULL, /* 389 */ (char *)NULL, /* 390 */ (char *)NULL, /* 391 RPL_TIME */ ":%s 391 %s %s :%s", @@ -549,16 +549,20 @@ char * replies[] = { /* 489 */ (char *)NULL, /* 490 */ (char *)NULL, /* 491 ERR_NOOPERHOST */ ":%s 491 %s :No O-lines for your host", /* 492 ERR_NOSERVICEHOST */ (char *)NULL, /* 493 */ (char *)NULL, /* 494 */ (char *)NULL, /* 495 */ (char *)NULL, /* 496 */ (char *)NULL, /* 497 */ (char *)NULL, /* 498 */ (char *)NULL, -/* 499 */ (char *)NULL, +#ifdef NOSTATSK +/* 499 ERR_STATSKLINE */ ":%s 499 %s :Please use http://www.irc.pl/kline instead.", +#else + /* 499 */ (char *)NULL, +#endif /* 500 */ (char *)NULL, /* 501 ERR_UMODEUNKNOWNFLAG */ ":%s 501 %s :Unknown MODE flag", /* 502 ERR_USERSDONTMATCH */ ":%s 502 %s :Can't change mode for other users" }; diff -rpbu10 irc2.11.0a8/ircd/s_misc.c irc2.11.0a8-cvs+pl/ircd/s_misc.c --- irc2.11.0a8/ircd/s_misc.c Mon Apr 19 02:32:34 2004 +++ irc2.11.0a8-cvs+pl/ircd/s_misc.c Mon May 17 00:30:25 2004 @@ -461,20 +461,25 @@ int exit_client(aClient *cptr, aClient * #if (defined(FNAME_USERLOG) || defined(FNAME_CONNLOG) \ || defined(USE_SERVICES)) \ || (defined(USE_SYSLOG) && (defined(SYSLOG_USERS) || defined(SYSLOG_CONN))) if (IsPerson(sptr)) { # if defined(FNAME_USERLOG) || defined(USE_SERVICES) || \ (defined(USE_SYSLOG) && defined(SYSLOG_USERS)) sendto_flog(sptr, EXITC_REG, sptr->user->username, sptr->user->host); # endif +#ifdef CLIENTS_CHANNEL + sendto_flag(SCH_OPER, "Client exiting: %s (%s@%s) [%s]", + sptr->name, sptr->user->username, sptr->user->host, + comment); +#endif } else { # if defined(FNAME_CONNLOG) || defined(USE_SERVICES) || \ (defined(USE_SYSLOG) && defined(SYSLOG_CONN)) if (sptr->exitc == '\0' || sptr->exitc == EXITC_REG) { sptr->exitc = EXITC_UNDEF; } sendto_flog(sptr, sptr->exitc, diff -rpbu10 irc2.11.0a8/ircd/s_serv.c irc2.11.0a8-cvs+pl/ircd/s_serv.c --- irc2.11.0a8/ircd/s_serv.c Sat May 15 00:58:13 2004 +++ irc2.11.0a8-cvs+pl/ircd/s_serv.c Mon May 17 00:30:25 2004 @@ -1851,20 +1851,37 @@ static int report_array[16][3] = { { CONF_OPERATOR, RPL_STATSOLINE, 'o'}, { CONF_HUB, RPL_STATSHLINE, 'H'}, { CONF_LOCOP, RPL_STATSOLINE, 'O'}, { CONF_SERVICE, RPL_STATSSLINE, 'S'}, { CONF_VER, RPL_STATSVLINE, 'V'}, { CONF_BOUNCE, RPL_STATSBLINE, 'B'}, { CONF_DENY, RPL_STATSDLINE, 'D'}, { 0, 0, 0} }; +#ifdef XLINE +static void report_x_lines(aClient *sptr, char *to) +{ + aConfItem *tmp; + + for (tmp = conf; tmp; tmp = tmp->next) + { + if (tmp->status != CONF_XLINE) + continue; + + sendto_one(sptr,":%s %d %s %s :%s ", ME, RPL_STATSDEBUG, to, + xline_flags_to_string(tmp->flags), + tmp->host); + } +} +#endif + static void report_configured_links(aClient *sptr, char *to, int mask) { static char null[] = ""; aConfItem *tmp; int *p, port; char c, *host, *pass, *name; for (tmp = (mask & (CONF_KILL|CONF_OTHERKILL)) ? kconf : conf; tmp; tmp = tmp->next) if (tmp->status & mask) @@ -1900,20 +1917,44 @@ static void report_configured_links(aCli c, host, (pass) ? "*" : null, name, port, get_conf_class(tmp), iline_flags_to_string(tmp->flags)); } else sendto_one(sptr, replies[p[1]], ME, BadTo(to), c, host, (pass) ? "*" : null, name, port, get_conf_class(tmp)); } +#ifdef TKLINE + if (mask & (CONF_KILL | CONF_OTHERKILL)) + { + char tbuf[BUFSIZE]; + for (tmp = tkconf; tmp; tmp = tmp->next) + { + for (p = &report_array[0][0]; *p; p += 3) + if (*p == tmp->status) + break; + if (!*p) + continue; + c = (char)*(p+2); + host = BadPtr(tmp->host) ? null : tmp->host; + pass = BadPtr(tmp->passwd) ? NULL : tmp->passwd; + name = BadPtr(tmp->name) ? null : tmp->name; + port = (int)tmp->port; + sprintf(tbuf, "(%d)\240%s", tmp->hold - timeofday, + pass ? pass : null); + sendto_one(sptr, replies[p[1]], ME, BadTo(to), + c, host, tbuf, + name, port, get_conf_class(tmp)); + } + } +#endif return; } static void report_ping(aClient *sptr, char *to) { aConfItem *tmp; aCPing *cp; for (tmp = conf; tmp; tmp = tmp->next) if ((cp = tmp->ping) && cp->lseq) @@ -2133,20 +2174,28 @@ int m_stats(aClient *cptr, aClient *sptr send_defines(cptr, parv[0]); break; case 'H' : case 'h' : /* H, L and D conf lines */ report_configured_links(cptr, parv[0], CONF_HUB|CONF_LEAF|CONF_DENY); break; case 'I' : case 'i' : /* I (and i) conf lines */ report_configured_links(cptr, parv[0], CONF_CLIENT); break; case 'K' : case 'k' : /* K lines */ +#ifdef NOSTATSK + if (!IsAnOper(sptr)) + { + sendto_one(sptr, replies[ERR_STATSKLINE], ME, BadTo(parv[0])); + return 2; + } + else +#endif report_configured_links(cptr, parv[0], (CONF_KILL|CONF_OTHERKILL)); break; case 'M' : case 'm' : /* commands use/stats */ for (mptr = msgtab; mptr->cmd; mptr++) if (mptr->count) sendto_one(cptr, replies[RPL_STATSCOMMANDS], ME, BadTo(parv[0]), mptr->cmd, mptr->count, mptr->bytes, mptr->rcount); @@ -2177,25 +2226,31 @@ int m_stats(aClient *cptr, aClient *sptr register time_t now; now = timeofday - me.since; sendto_one(sptr, replies[RPL_STATSUPTIME], ME, BadTo(parv[0]), now/86400, (now/3600)%24, (now/60)%60, now%60); break; } case 'V' : case 'v' : /* V conf lines */ report_configured_links(cptr, parv[0], CONF_VER); break; -#ifdef DEBUGMODE case 'X' : case 'x' : /* lists */ +#ifdef DEBUGMODE send_listinfo(cptr, parv[0]); - break; #endif +#ifdef XLINE + if (IsAnOper(sptr) && MyConnect(sptr)) + { + report_x_lines(sptr, parv[0]); + } +#endif + break; case 'Y' : case 'y' : /* Y lines */ report_classes(cptr, parv[0]); break; case 'Z': #ifdef DEBUGMODE /* memory use (OPER only) */ if (MyOper(sptr)) count_memory(cptr, parv[0], 1); else #endif diff -rpbu10 irc2.11.0a8/ircd/s_user.c irc2.11.0a8-cvs+pl/ircd/s_user.c --- irc2.11.0a8/ircd/s_user.c Wed May 12 18:33:18 2004 +++ irc2.11.0a8-cvs+pl/ircd/s_user.c Mon May 17 00:30:25 2004 @@ -34,20 +34,21 @@ static char rcsid[] = "@(#)$Id: s_user. static void save_user (aClient *, aClient *, char *); static char buf[BUFSIZE], buf2[BUFSIZE]; static int user_modes[] = { FLAGS_OPER, 'o', FLAGS_LOCOP, 'O', FLAGS_INVISIBLE, 'i', FLAGS_WALLOP, 'w', FLAGS_RESTRICT, 'r', FLAGS_AWAY, 'a', + FLAGS_FLOOD, 'F', 0, 0 }; /* ** m_functions execute protocol messages on this server: ** ** cptr is always NON-NULL, pointing to a *LOCAL* client ** structure (with an open socket connected!). This ** identifies the physical socket where the message ** originated (or which caused the m_function to be ** executed--some m_functions may call others...). @@ -596,20 +597,31 @@ int register_user(aClient *cptr, aClient sendto_flag(SCH_LOCAL, "K-lined %s@%s.", user->username, sptr->sockhost); ircstp->is_ref++; sptr->exitc = EXITC_KLINE; if (reason) sprintf(buf, "K-lined: %.80s", reason); return exit_client(cptr, sptr, &me, (reason) ? buf : "K-lined"); } +#ifdef XLINE + if (!IsKlineExempt(sptr) && IsXlined(sptr)) + { + sptr->exitc = EXITC_XLINE; + sendto_flag(SCH_OPER, "X-lined: %s (%s@%s) [%s]", + sptr->name, sptr->username, sptr->sockhost, sptr->info); + return exit_client(cptr, sptr, &me, + XLINE_EXIT_REASON); + } +#endif + sp = user->servp; } else strncpyzt(user->username, username, USERLEN+1); SetClient(sptr); if (!MyConnect(sptr)) { acptr = find_server(user->server, NULL); if (acptr && acptr->from != cptr) @@ -678,20 +690,34 @@ int register_user(aClient *cptr, aClient strcpy(sptr->user->uid, next_uid()); if (nick[0] == '0' && nick[1] == '\0') { strncpyzt(nick, sptr->user->uid, UIDLEN + 1); (void)strcpy(sptr->name, nick); (void)add_to_client_hash_table(nick, sptr); } sprintf(buf, "%s!%s@%s", nick, user->username, user->host); add_to_uid_hash_table(sptr->user->uid, sptr); sptr->exitc = EXITC_REG; + +#ifdef CLIENTS_CHANNEL + sendto_flag(SCH_OPER, "Client connecting: %s (%s@%s) [%s] %s", + nick, user->username,user->host, +#ifdef INET6 + inetntop(AF_INET6, + (char *)&sptr->ip, + mydummy, MYDUMMY_SIZE), +#else + inetntoa((char *)&sptr->ip), +#endif + sptr->info); +#endif + sendto_one(sptr, replies[RPL_WELCOME], ME, BadTo(nick), buf); /* This is a duplicate of the NOTICE but see below...*/ sendto_one(sptr, replies[RPL_YOURHOST], ME, BadTo(nick), get_client_name(&me, FALSE), version); sendto_one(sptr, replies[RPL_CREATED], ME, BadTo(nick), creation); sendto_one(sptr, replies[RPL_MYINFO], ME, BadTo(parv[0]), ME, version); isup = isupport; while (*isup) @@ -2450,20 +2476,49 @@ int m_user(aClient *cptr, aClient *sptr, strncpyzt(user->host, host, sizeof(user->host)); user->server = find_server_string(sp->snum); goto user_finish; } user->servp = me.serv; me.serv->refcnt++; #ifndef NO_DEFAULT_INVISIBLE SetInvisible(sptr); #endif +#ifdef XLINE + if (MyConnect(sptr)) + { + aConfItem *tmp; + char xbuf[BUFSIZE]; + sprintf(xbuf, "%s %s %s %s", username, host, server, realname); + + for (tmp = conf; tmp; tmp = tmp->next) + { + if (tmp->status != CONF_XLINE) + continue; + + if (IsConfXlineWhole(tmp)) + { + if (tmp->host && !match(tmp->host, xbuf)) + { + SetXlined(sptr); + } + } + else + { + if (tmp->host && !match(tmp->host, realname)) + { + SetXlined(sptr); + } + } + } + } +#endif /* parse desired user modes sent in USER */ /* old behaviour - bits */ if ((i = atoi(host))) { /* allows only umodes specified in UFLAGS - see above */ sptr->user->flags |= (UFLAGS & atoi(host)); } else { /* 0 here is intentional. User MUST specify + or -, @@ -2534,21 +2589,21 @@ user_finish: return register_user(cptr, sptr, sptr->name, username); } else strncpyzt(sptr->user->username, username, USERLEN+1); return 2; } /* Fear www proxy abusers... aliased to QUIT, muhaha --B. */ int m_post(aClient *cptr, aClient *sptr, int parc, char *parv[]) { - sendto_flag(SCH_LOCAL, "Denied http-post connection from %s.", + sendto_flag(SCH_OPER, "Denied http-post connection from %s.", cptr->sockhost); return m_quit(cptr, sptr, parc, parv); } /* ** m_quit ** parv[0] = sender prefix ** parv[1] = comment */ int m_quit(aClient *cptr, aClient *sptr, int parc, char *parv[]) @@ -3049,21 +3104,21 @@ int m_oper(aClient *cptr, aClient *sptr, istat.is_oper++; sptr->user->servp->usercnt[2]++; } logstring = ""; } else /* Wrong password */ { (void)detach_conf(sptr, aconf); sendto_one(sptr,replies[ERR_PASSWDMISMATCH], ME, BadTo(parv[0])); #ifdef FAILED_OPERLOG - sendto_flag(SCH_NOTICE, "FAILED OPER attempt by %s!%s@%s", + sendto_flag(SCH_NOTICE, "FAILED OPER attempt by %s (%s@%s)", parv[0], sptr->user->username, sptr->user->host); logstring = "FAILED "; #endif } if (logstring) { #if defined(USE_SYSLOG) && defined(SYSLOG_OPER) syslog(LOG_INFO, "%sOPER (%s) by (%s!%s@%s) [%s@%s]", logstring, @@ -3383,20 +3438,30 @@ int m_umode(aClient *cptr, aClient *sptr ":%s AWAY", parv[0]); #endif } #ifdef USE_SERVICES if (what == MODE_ADD) check_services_butone(SERVICE_WANT_AWAY, sptr->user->server, sptr, ":%s AWAY :", parv[0]); #endif default : + if (!IsAnOper(sptr) && MyConnect(sptr)) + { + if (*m == 'F') + { + sendto_one(sptr, + replies[ERR_UMODEUNKNOWNFLAG], + ME, BadTo(parv[0]), *m); + continue; + } + } for (s = user_modes; (flag = *s); s += 2) if (*m == (char)(*(s+1))) { if (what == MODE_ADD) sptr->user->flags |= flag; else sptr->user->flags &= ~flag; penalty += 1; break; } diff -rpbu10 irc2.11.0a8/support/config.h.dist irc2.11.0a8-cvs+pl/support/config.h.dist --- irc2.11.0a8/support/config.h.dist Sun May 9 21:15:54 2004 +++ irc2.11.0a8-cvs+pl/support/config.h.dist Mon May 17 00:30:25 2004 @@ -105,40 +105,40 @@ * Left undefined they increase the security of your server from wayward * operators and accidents. * OPER_SET enables SET command which can be used for fine-tuning of certain * aspects of ircd behaviour during runtime. * The 'LOCOP_' #defines are for making the respective commands available * to 'local' operators. Note that the 'OPER_' #defines affect both global * (big O) and local (little o) operators. Defining 'LOCOP_x' has no effect * if 'OPER_x' is undefined so you can't give local operators more rights * than global ones. */ -#undef OPER_KILL +#define OPER_KILL #define OPER_REHASH #undef OPER_RESTART -#define OPER_DIE +#undef OPER_DIE #define OPER_SET #undef LOCOP_REHASH #undef LOCOP_RESTART #undef LOCOP_DIE #undef LOCOP_SET /* * Maximum number of network connections your server will allow. This must * not exceed OS limit of max. number of open file descriptors available upon * ircd start. * If you have a lot of server connections, it may be worth splitting the load * over 2 or more servers. * 1 server = 1 connection, 1 user = 1 connection. * Due to various sanity checks during startup, minimum is 13. */ -#define MAXCONNECTIONS 50 +#define MAXCONNECTIONS 10000 /* MAXIMUM LINKS * * This define is useful for leaf nodes and gateways. It keeps you from * connecting to too many places. It works by keeping you from * connecting to more than "n" nodes which you have C:blah::blah:6667 * lines for. * * Note that any number of nodes can still connect to you. This only * limits the number that you actively reach out to connect to. @@ -210,21 +210,21 @@ * reading m4 output as the server's ircd.conf file. */ #undef M4_PREPROC /* * If you want to use #include or #include "file" directive in ircd.conf * without M4, define this. reads file from dir where ircd.conf is, and * "file" from dir where ircd was started from. Note that "#include" must be * at the beginning of the line. */ -#undef CONFIG_DIRECTIVE_INCLUDE +#define CONFIG_DIRECTIVE_INCLUDE /* * If you wish to have the server send 'vital' messages about server * through syslog, define USE_SYSLOG. Only system errors and events critical * to the server are logged although if this is defined with FNAME_USERLOG, * syslog() is used additionally to the above file. It is not recommended that * this option is used unless you tell the system administrator beforehand * and obtain their permission to send messages to the system log files. */ #undef USE_SYSLOG @@ -252,27 +252,27 @@ * LOG_OLDFORMAT * * Define this if you want old format of logs. (Mind, you will lose * additional information, like remote ip, port, etc.) */ #undef LOG_OLDFORMAT /* * Define this if you want to log failed /oper attempts. */ -#undef FAILED_OPERLOG +#define FAILED_OPERLOG /* * Define this if you want to use crypted passwords for operators in your * ircd.conf file. See contrib/mkpasswd/README for more details on this. */ -#undef CRYPT_OPER_PASSWORD +#define CRYPT_OPER_PASSWORD /* * If you want to store encrypted passwords in N-lines for server links, * define this. For a C/N pair in your ircd.conf file, the password * need not be the same for both, as long as hte opposite end has the * right password in the opposite line. See INSTALL doc for more details. */ #undef CRYPT_LINK_PASSWORD /* @@ -307,35 +307,35 @@ /* #undef IRC_UID 65534 */ /* #undef IRC_GID 65534 */ /* * CLIENT_FLOOD * * this controls the number of bytes the server will allow a client to * send to the server without processing before disconnecting the client for * flooding it. Values greater than 8000 make no difference to the server. */ -#define CLIENT_FLOOD 1000 +#define CLIENT_FLOOD 3000 /* Remote query flood protection. */ #define CHREPLLEN 8192 /* Default server for standard client */ #define UPHOST "irc" /* * If you wish to run services, define USE_SERVICES. * This can make the server noticeably bigger and slower. * services are not fully implemented yet, so don't use it unless you really * know what you are doing. */ -#undef USE_SERVICES +#define USE_SERVICES /* * Define the following to make the delay for nicks random. * Some people believe a bot can exactly time the delay and don't like it, * I think this is a useless concern. -krys */ #undef RANDOM_NDELAY /* * You've read the BOFH saga and you liked it, then define the following. @@ -345,21 +345,21 @@ */ #undef BETTER_NDELAY #undef BETTER_CDELAY /* * Defining this will enable the use of compressed server-server links. * In order to have it work, you must have the zlib version 1.0 or higher. * The library and the include files must have been found by configure, * if you have installed the zlib after running configure, run it again. */ -#undef ZIP_LINKS +#define ZIP_LINKS /* * Defining this will add an artificial 2 seconds delay for accepting * connections. This is the OLD behaviour of the server. * * NOTE: Undefining this leads to a significant increase in CPU usage if * you reject client which keeps connecting. */ #undef SLOW_ACCEPT @@ -401,46 +401,61 @@ * Connections rejected by check_clones() will be delayed for this many seconds * before final error is sent to them and their socket is closed. * This effectively reduces bouncing (fast reconnecting clients). * CLONE_CHECK must be defined for this to work. * * Note: it may lead to file descriptors exhaustion. ("All connections in use" * error message.) */ #define DELAY_CLOSE 15 /* Recommended value: 15 */ + +/* &OPER channel -- clients' connect/disconnect notices */ +#define CLIENTS_CHANNEL + +/* Temporary K-lines */ +#define TKLINE + +/* GECOS bans */ +#define XLINE +#define XLINE_EXIT_REASON "Too many host connections (global)" + +/* No /stats k for user, send an URL instead */ +#define NOSTATSK + + /* STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP */ /* STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP */ /* STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP */ /* You shouldn't change anything below this line, unless absolutely needed. */ #ifdef OPER_KILL /* LOCAL_KILL_ONLY * * To be used, OPER_KILL must be defined. * LOCAL_KILL_ONLY restricts KILLs to clients which are connected to the * server the Operator is connected to (ie lets them deal with local * problem users or 'ghost' clients */ -#define LOCAL_KILL_ONLY +#undef LOCAL_KILL_ONLY #endif /* Default server port, used by client. */ #define PORTNUM 6667 /* Maximum length the queue of pending connections to one port may grow to. * Note that your system limits this, too. FreeBSD, for instance, has sysctl * kern.ipc.somaxconn for that. Such must be bigger than this define prior to * ircd start. */ -#define LISTENQUEUE 128 +#define LISTENQUEUE 512 /* define DEBUGMODE to enable debugging mode.*/ #undef DEBUGMODE /* * Time interval to wait and if no messages have been received, then check for * PINGFREQUENCY and CONNECTFREQUENCY */ #define TIMESEC 60 /* Recommended value: 60 */ @@ -554,22 +569,22 @@ #define TOPIC_WHO_TIME 1 /* ** Define this to see local clients signon time */ #define WHOIS_SIGNON_TIME 1 /* ** Split detection */ -#define SPLIT_USERS 15000 -#define SPLIT_SERVERS 15 +#define SPLIT_USERS 40000 +#define SPLIT_SERVERS 20 /* ** Notice sent to connecting users if the server is in the split-mode. */ #define SPLIT_CONNECT_NOTICE "Server is currently in split-mode." /* ------------------------- END CONFIGURATION SECTION -------------------- */ #ifndef ENABLE_SUMMON # undef LEAST_IDLE #endif @@ -681,21 +696,21 @@ #define CLCHNO 50 # else #define CLCHNO 100 # endif # endif /* ** CLCHSEC defines minimum time in seconds between two consecutive ** "New highest local/global clients count" messages */ -#define CLCHSEC 300 +#define CLCHSEC 3000 #ifndef SPLIT_USERS #error SPLIT_USERS must be defined #endif #ifndef SPLIT_SERVERS #error SPLIT_SERVERS must be defined #endif /* * Undefining NO_OPER_REMOTE removes the restriction that O-lines only become