From 800ebbf95d489010e3a99b4975c9b864d96cd0d2 Mon Sep 17 00:00:00 2001 From: brain Date: Sat, 24 Apr 2004 18:15:37 +0000 Subject: [PATCH] Added a bunch of xline stuff and added qline spport for /nick and svsnick git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@713 e03df62e-2008-0410-955e-edbf42e46eb7 --- include/commands.h | 5 + include/connection.h | 4 +- include/wildcard.h | 2 +- include/xline.h | 35 +++- src/InspIRCd.dev | 22 ++- src/InspIRCd.layout | 102 +++++----- src/commands.cpp | 29 +++ src/inspircd.cpp | 323 ++++++++++++++++--------------- src/users.cpp | 2 +- src/wildcard.cpp | 2 +- src/xline.cpp | 452 +++++++++++++++++++++++++++++++++++++++++++ 11 files changed, 773 insertions(+), 205 deletions(-) diff --git a/include/commands.h b/include/commands.h index a9046d4d1..53f80fd73 100644 --- a/include/commands.h +++ b/include/commands.h @@ -57,6 +57,11 @@ void handle_links(char **parameters, int pcnt, userrec *user); void handle_map(char **parameters, int pcnt, userrec *user); void handle_oper(char **parameters, int pcnt, userrec *user); void handle_nick(char **parameters, int pcnt, userrec *user); +void handle_kline(char **parameters, int pcnt, userrec *user); +void handle_gline(char **parameters, int pcnt, userrec *user); +void handle_zline(char **parameters, int pcnt, userrec *user); +void handle_qline(char **parameters, int pcnt, userrec *user); + /** Special functions for processing server to server traffic */ diff --git a/include/connection.h b/include/connection.h index 12d6dc754..bb402b5d2 100644 --- a/include/connection.h +++ b/include/connection.h @@ -171,7 +171,7 @@ class connection : public classbase /** IP of connection. Reserved for future use. */ - long ip; + char ip[32]; /** Inbuf of connection. Only used for userrec */ @@ -229,7 +229,7 @@ class connection : public classbase /** Unused, will be removed in a future alpha/beta */ - char internal_addr[1024]; + char internal_addr[MAXBUF]; /** Unused, will be removed in a future alpha/beta */ diff --git a/include/wildcard.h b/include/wildcard.h index ab6e6d71e..fc73c2d2a 100644 --- a/include/wildcard.h +++ b/include/wildcard.h @@ -3,5 +3,5 @@ void Delete(char* str,int pos); void Insert(char* substr,char* str,int pos); -bool match(char* literal, char* mask); +bool match(const char* literal, const char* mask); diff --git a/include/xline.h b/include/xline.h index 0532ad207..f66583ae6 100644 --- a/include/xline.h +++ b/include/xline.h @@ -17,6 +17,7 @@ */ class XLine : public classbase { + public: /** The time the line was added. */ @@ -40,37 +41,69 @@ class XLine : public classbase }; +/** KLine class + */ class KLine : public XLine { + public: /** Hostmask (ident@host) to match against * May contain wildcards. */ char hostmask[MAXBUF]; }; +/** GLine class + */ class GLine : public XLine { + public: /** Hostmask (ident@host) to match against * May contain wildcards. */ char hostmask[MAXBUF]; }; +/** ZLine class + */ class ZLine : public XLine { + public: /** IP Address (xx.yy.zz.aa) to match against - * May contain wildcards and may be CIDR + * May contain wildcards. */ char ipaddr[MAXBUF]; }; +/** QLine class + */ class QLine : public XLine { + public: /** Nickname to match against. * May contain wildcards. */ char nick[MAXBUF]; }; +void read_xline_defaults(); + +void add_gline(long duration, char* source, char* reason, char* hostmask); +void add_qline(long duration, char* source, char* reason, char* nickname); +void add_zline(long duration, char* source, char* reason, char* ipaddr); +void add_kline(long duration, char* source, char* reason, char* hostmask); + +bool del_gline(char* hostmask); +bool del_qline(char* nickname); +bool del_zline(char* ipaddr); +bool del_kline(char* hostmask); + +char* matches_qline(const char* nick); +char* matches_gline(const char* host); +char* matches_zline(const char* ipaddr); +char* matches_kline(const char* host); + +void expire_lines(); +void apply_lines(); + #endif diff --git a/src/InspIRCd.dev b/src/InspIRCd.dev index 5012e26ff..ae24fa043 100644 --- a/src/InspIRCd.dev +++ b/src/InspIRCd.dev @@ -1,7 +1,7 @@ [Project] FileName=InspIRCd.dev Name=InspIRCd - The Inspire Internet Relay Chat Daemon -UnitCount=45 +UnitCount=47 Type=1 Ver=1 ObjFiles= @@ -495,3 +495,23 @@ Priority=1000 OverrideBuildCmd=0 BuildCmd= +[Unit46] +FileName=..\include\xline.h +CompileCpp=1 +Folder=Headers +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit47] +FileName=xline.cpp +CompileCpp=1 +Folder=Source +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/src/InspIRCd.layout b/src/InspIRCd.layout index b5fe0474f..df55af071 100644 --- a/src/InspIRCd.layout +++ b/src/InspIRCd.layout @@ -1,29 +1,29 @@ [Editors] Focused=-1 -Order=2,4,6,3,7,25,5,24,39,42,43,-1,1 +Order=2,4,6,3,7,25,5,24,39,42,43,-1,1,46,0 [Editor_0] -Open=0 +Open=1 Top=0 -CursorCol=20 -CursorRow=57 -TopLine=26 +CursorCol=39 +CursorRow=78 +TopLine=35 LeftChar=1 [Editor_1] Open=1 Top=0 -CursorCol=44 -CursorRow=830 -TopLine=790 +CursorCol=7 +CursorRow=2372 +TopLine=2333 LeftChar=1 [Editor_2] Open=1 Top=0 -CursorCol=1 -CursorRow=428 -TopLine=377 +CursorCol=18 +CursorRow=354 +TopLine=327 LeftChar=1 [Editor_3] @@ -37,9 +37,9 @@ LeftChar=1 [Editor_4] Open=1 Top=0 -CursorCol=2 -CursorRow=183 -TopLine=163 +CursorCol=58 +CursorRow=163 +TopLine=135 LeftChar=1 [Editor_5] @@ -53,16 +53,16 @@ LeftChar=1 [Editor_6] Open=1 Top=0 -CursorCol=18 -CursorRow=34 +CursorCol=16 +CursorRow=17 TopLine=1 LeftChar=1 [Editor_7] Open=1 Top=0 -CursorCol=20 -CursorRow=15 +CursorCol=10 +CursorRow=18 TopLine=1 LeftChar=1 @@ -91,10 +91,10 @@ TopLine=76 LeftChar=1 [Editor_11] -Open=0 -Top=0 -CursorCol=1 -CursorRow=7 +Open=1 +Top=1 +CursorCol=39 +CursorRow=6 TopLine=1 LeftChar=1 @@ -109,9 +109,9 @@ LeftChar=1 [Editor_13] Open=1 Top=0 -CursorCol=37 -CursorRow=61 -TopLine=7 +CursorCol=12 +CursorRow=174 +TopLine=12 LeftChar=1 [Editor_14] @@ -164,7 +164,7 @@ LeftChar=1 [Editor_20] Open=1 -Top=1 +Top=0 CursorCol=5 CursorRow=506 TopLine=470 @@ -179,11 +179,11 @@ TopLine=12 LeftChar=1 [Editor_22] -Open=0 +Open=1 Top=0 CursorCol=15 CursorRow=121 -TopLine=83 +TopLine=119 LeftChar=1 [Editor_23] @@ -209,7 +209,7 @@ CursorRow=39 TopLine=1 LeftChar=1 [Editor_26] -Open=0 +Open=1 Top=0 CursorCol=1 CursorRow=13 @@ -293,11 +293,11 @@ CursorRow=178 TopLine=156 LeftChar=1 [Editor_38] -Open=0 +Open=1 Top=0 -CursorCol=1 -CursorRow=70 -TopLine=40 +CursorCol=39 +CursorRow=52 +TopLine=13 LeftChar=1 [Editor_39] Open=1 @@ -316,28 +316,42 @@ LeftChar=1 [Editor_41] Open=1 Top=0 -CursorCol=22 -CursorRow=13 +CursorCol=1 +CursorRow=1 TopLine=1 LeftChar=1 [Editor_42] Open=1 Top=0 -CursorCol=4 -CursorRow=1729 -TopLine=1685 +CursorCol=19 +CursorRow=36 +TopLine=10 LeftChar=1 [Editor_43] Open=1 Top=0 -CursorCol=6 -CursorRow=1259 -TopLine=1259 +CursorCol=1 +CursorRow=1367 +TopLine=1351 LeftChar=1 [Editor_44] Open=1 Top=0 -CursorCol=34 -CursorRow=93 -TopLine=40 +CursorCol=63 +CursorRow=63 +TopLine=16 +LeftChar=1 +[Editor_45] +Open=1 +Top=0 +CursorCol=27 +CursorRow=103 +TopLine=54 +LeftChar=1 +[Editor_46] +Open=1 +Top=0 +CursorCol=27 +CursorRow=322 +TopLine=306 LeftChar=1 diff --git a/src/commands.cpp b/src/commands.cpp index 28d10c3b5..043547180 100644 --- a/src/commands.cpp +++ b/src/commands.cpp @@ -1361,6 +1361,12 @@ void handle_nick(char **parameters, int pcnt, userrec *user) *parameters[0]++; } } + if (matches_qline(parameters[0])) + { + WriteOpers("*** Q-Lined nickname %s from %s!%s@%s: %s",parameters[0],user->nick,user->ident,user->host,matches_qline(parameters[0])); + WriteServ(user->fd,"432 %s %s :Invalid nickname: %s",user->nick,parameters[0],matches_qline(parameters[0])); + return; + } if ((Find(parameters[0])) && (Find(parameters[0]) != user)) { WriteServ(user->fd,"433 %s %s :Nickname is already in use.",user->nick,parameters[0]); @@ -1679,6 +1685,11 @@ void handle_n(char token,char* params,serverrec* source,serverrec* reply, char* kill_link(user,"Nickname collision"); return; } + if (matches_qline(newnick)) + { + kill_link(user,"Nickname collision"); + return; + } // broadcast this because its a services thingy char buffer[MAXBUF]; @@ -2604,3 +2615,21 @@ void handle_link_packet(char* udp_msg, char* tcp_host, serverrec *serv) } } + +void handle_kline(char **parameters, int pcnt, userrec *user) +{ +} + +void handle_gline(char **parameters, int pcnt, userrec *user) +{ +} + +void handle_zline(char **parameters, int pcnt, userrec *user) +{ +} + +void handle_qline(char **parameters, int pcnt, userrec *user) +{ +} + + diff --git a/src/inspircd.cpp b/src/inspircd.cpp index 989faf9c7..a3177e949 100644 --- a/src/inspircd.cpp +++ b/src/inspircd.cpp @@ -267,184 +267,189 @@ void log(int level,char *text, ...) void readfile(file_cache &F, const char* fname) { - FILE* file; - char linebuf[MAXBUF]; - - log(DEBUG,"readfile: loading %s",fname); - F.clear(); - file = fopen(fname,"r"); - if (file) - { - while (!feof(file)) - { - fgets(linebuf,sizeof(linebuf),file); - linebuf[strlen(linebuf)-1]='\0'; - if (!strcmp(linebuf,"")) - { - strcpy(linebuf," "); - } - if (!feof(file)) - { - F.push_back(linebuf); - } - } - fclose(file); - } - else - { - log(DEBUG,"readfile: failed to load file: %s",fname); - } - log(DEBUG,"readfile: loaded %s, %d lines",fname,F.size()); + FILE* file; + char linebuf[MAXBUF]; + + log(DEBUG,"readfile: loading %s",fname); + F.clear(); + file = fopen(fname,"r"); + if (file) + { + while (!feof(file)) + { + fgets(linebuf,sizeof(linebuf),file); + linebuf[strlen(linebuf)-1]='\0'; + if (!strcmp(linebuf,"")) + { + strcpy(linebuf," "); + } + if (!feof(file)) + { + F.push_back(linebuf); + } + } + fclose(file); + } + else + { + log(DEBUG,"readfile: failed to load file: %s",fname); + } + log(DEBUG,"readfile: loaded %s, %d lines",fname,F.size()); } void ReadConfig(void) { - char dbg[MAXBUF],pauseval[MAXBUF],Value[MAXBUF],timeout[MAXBUF],NB[MAXBUF],flood[MAXBUF]; - ConnectClass c; - - LoadConf(CONFIG_FILE,&config_f); - - ConfValue("server","name",0,ServerName,&config_f); - ConfValue("server","description",0,ServerDesc,&config_f); - ConfValue("server","network",0,Network,&config_f); - ConfValue("admin","name",0,AdminName,&config_f); - ConfValue("admin","email",0,AdminEmail,&config_f); - ConfValue("admin","nick",0,AdminNick,&config_f); - ConfValue("files","motd",0,motd,&config_f); - ConfValue("files","rules",0,rules,&config_f); - ConfValue("power","diepass",0,diepass,&config_f); - ConfValue("power","pause",0,pauseval,&config_f); - ConfValue("power","restartpass",0,restartpass,&config_f); - ConfValue("options","prefixquit",0,PrefixQuit,&config_f); - ConfValue("die","value",0,DieValue,&config_f); - ConfValue("options","loglevel",0,dbg,&config_f); - ConfValue("options","netbuffersize",0,NB,&config_f); - NetBufferSize = atoi(NB); - if ((!NetBufferSize) || (NetBufferSize > 65535) || (NetBufferSize < 1024)) - { - log(DEFAULT,"No NetBufferSize specified or size out of range, setting to default of 10240."); - NetBufferSize = 10240; - } - if (!strcmp(dbg,"debug")) - LogLevel = DEBUG; - if (!strcmp(dbg,"verbose")) - LogLevel = VERBOSE; - if (!strcmp(dbg,"default")) - LogLevel = DEFAULT; - if (!strcmp(dbg,"sparse")) - LogLevel = SPARSE; - if (!strcmp(dbg,"none")) - LogLevel = NONE; - readfile(MOTD,motd); - log(DEBUG,"Reading message of the day"); - readfile(RULES,rules); - log(DEBUG,"Reading connect classes"); - Classes.clear(); - for (int i = 0; i < ConfValueEnum("connect",&config_f); i++) - { - strcpy(Value,""); - ConfValue("connect","allow",i,Value,&config_f); - ConfValue("connect","timeout",i,timeout,&config_f); - ConfValue("connect","flood",i,flood,&config_f); - if (strcmp(Value,"")) - { - strcpy(c.host,Value); - c.type = CC_ALLOW; + char dbg[MAXBUF],pauseval[MAXBUF],Value[MAXBUF],timeout[MAXBUF],NB[MAXBUF],flood[MAXBUF]; + ConnectClass c; + + LoadConf(CONFIG_FILE,&config_f); + + ConfValue("server","name",0,ServerName,&config_f); + ConfValue("server","description",0,ServerDesc,&config_f); + ConfValue("server","network",0,Network,&config_f); + ConfValue("admin","name",0,AdminName,&config_f); + ConfValue("admin","email",0,AdminEmail,&config_f); + ConfValue("admin","nick",0,AdminNick,&config_f); + ConfValue("files","motd",0,motd,&config_f); + ConfValue("files","rules",0,rules,&config_f); + ConfValue("power","diepass",0,diepass,&config_f); + ConfValue("power","pause",0,pauseval,&config_f); + ConfValue("power","restartpass",0,restartpass,&config_f); + ConfValue("options","prefixquit",0,PrefixQuit,&config_f); + ConfValue("die","value",0,DieValue,&config_f); + ConfValue("options","loglevel",0,dbg,&config_f); + ConfValue("options","netbuffersize",0,NB,&config_f); + NetBufferSize = atoi(NB); + if ((!NetBufferSize) || (NetBufferSize > 65535) || (NetBufferSize < 1024)) + { + log(DEFAULT,"No NetBufferSize specified or size out of range, setting to default of 10240."); + NetBufferSize = 10240; + } + if (!strcmp(dbg,"debug")) + LogLevel = DEBUG; + if (!strcmp(dbg,"verbose")) + LogLevel = VERBOSE; + if (!strcmp(dbg,"default")) + LogLevel = DEFAULT; + if (!strcmp(dbg,"sparse")) + LogLevel = SPARSE; + if (!strcmp(dbg,"none")) + LogLevel = NONE; + readfile(MOTD,motd); + log(DEFAULT,"Reading message of the day..."); + readfile(RULES,rules); + log(DEFAULT,"Reading connect classes..."); + Classes.clear(); + for (int i = 0; i < ConfValueEnum("connect",&config_f); i++) + { strcpy(Value,""); - ConfValue("connect","password",i,Value,&config_f); - strcpy(c.pass,Value); - c.registration_timeout = 90; // default is 2 minutes - c.flood = atoi(flood); - if (atoi(timeout)>0) + ConfValue("connect","allow",i,Value,&config_f); + ConfValue("connect","timeout",i,timeout,&config_f); + ConfValue("connect","flood",i,flood,&config_f); + if (strcmp(Value,"")) + { + strcpy(c.host,Value); + c.type = CC_ALLOW; + strcpy(Value,""); + ConfValue("connect","password",i,Value,&config_f); + strcpy(c.pass,Value); + c.registration_timeout = 90; // default is 2 minutes + c.flood = atoi(flood); + if (atoi(timeout)>0) + { + c.registration_timeout = atoi(timeout); + } + Classes.push_back(c); + log(DEBUG,"Read connect class type ALLOW, host=%s password=%s timeout=%d flood=%d",c.host,c.pass,c.registration_timeout,c.flood); + } + else { - c.registration_timeout = atoi(timeout); + ConfValue("connect","deny",i,Value,&config_f); + strcpy(c.host,Value); + c.type = CC_DENY; + Classes.push_back(c); + log(DEBUG,"Read connect class type DENY, host=%s",c.host); } - Classes.push_back(c); - log(DEBUG,"Read connect class type ALLOW, host=%s password=%s timeout=%d flood=%d",c.host,c.pass,c.registration_timeout,c.flood); - } - else - { - ConfValue("connect","deny",i,Value,&config_f); - strcpy(c.host,Value); - c.type = CC_DENY; - Classes.push_back(c); - log(DEBUG,"Read connect class type DENY, host=%s",c.host); - } - } + } + log(DEFAULT,"Reading K lines,Q lines and Z lines from config..."); + read_xline_defaults(); + log(DEFAULT,"Applying K lines, Q lines and Z lines..."); + apply_lines(); + log(DEFAULT,"Done reading configuration file, InspIRCd is now running."); } /* write formatted text to a socket, in same format as printf */ void Write(int sock,char *text, ...) { - if (!text) - { - log(DEFAULT,"*** BUG *** Write was given an invalid parameter"); - return; - } - char textbuffer[MAXBUF]; - va_list argsPtr; - char tb[MAXBUF]; - - va_start (argsPtr, text); - vsnprintf(textbuffer, MAXBUF, text, argsPtr); - va_end(argsPtr); - sprintf(tb,"%s\r\n",textbuffer); - chop(tb); - if (sock != -1) - { - write(sock,tb,strlen(tb)); - update_stats_l(sock,strlen(tb)); /* add one line-out to stats L for this fd */ - } + if (!text) + { + log(DEFAULT,"*** BUG *** Write was given an invalid parameter"); + return; + } + char textbuffer[MAXBUF]; + va_list argsPtr; + char tb[MAXBUF]; + + va_start (argsPtr, text); + vsnprintf(textbuffer, MAXBUF, text, argsPtr); + va_end(argsPtr); + sprintf(tb,"%s\r\n",textbuffer); + chop(tb); + if (sock != -1) + { + write(sock,tb,strlen(tb)); + update_stats_l(sock,strlen(tb)); /* add one line-out to stats L for this fd */ + } } /* write a server formatted numeric response to a single socket */ void WriteServ(int sock, char* text, ...) { - if (!text) - { - log(DEFAULT,"*** BUG *** WriteServ was given an invalid parameter"); - return; - } - char textbuffer[MAXBUF],tb[MAXBUF]; - va_list argsPtr; - va_start (argsPtr, text); - - vsnprintf(textbuffer, MAXBUF, text, argsPtr); - va_end(argsPtr); - sprintf(tb,":%s %s\r\n",ServerName,textbuffer); - chop(tb); - if (sock != -1) - { - write(sock,tb,strlen(tb)); - update_stats_l(sock,strlen(tb)); /* add one line-out to stats L for this fd */ - } + if (!text) + { + log(DEFAULT,"*** BUG *** WriteServ was given an invalid parameter"); + return; + } + char textbuffer[MAXBUF],tb[MAXBUF]; + va_list argsPtr; + va_start (argsPtr, text); + + vsnprintf(textbuffer, MAXBUF, text, argsPtr); + va_end(argsPtr); + sprintf(tb,":%s %s\r\n",ServerName,textbuffer); + chop(tb); + if (sock != -1) + { + write(sock,tb,strlen(tb)); + update_stats_l(sock,strlen(tb)); /* add one line-out to stats L for this fd */ + } } /* write text from an originating user to originating user */ void WriteFrom(int sock, userrec *user,char* text, ...) { - if ((!text) || (!user)) - { - log(DEFAULT,"*** BUG *** WriteFrom was given an invalid parameter"); - return; - } - char textbuffer[MAXBUF],tb[MAXBUF]; - va_list argsPtr; - va_start (argsPtr, text); - - vsnprintf(textbuffer, MAXBUF, text, argsPtr); - va_end(argsPtr); - sprintf(tb,":%s!%s@%s %s\r\n",user->nick,user->ident,user->dhost,textbuffer); - chop(tb); - if (sock != -1) - { - write(sock,tb,strlen(tb)); - update_stats_l(sock,strlen(tb)); /* add one line-out to stats L for this fd */ - } + if ((!text) || (!user)) + { + log(DEFAULT,"*** BUG *** WriteFrom was given an invalid parameter"); + return; + } + char textbuffer[MAXBUF],tb[MAXBUF]; + va_list argsPtr; + va_start (argsPtr, text); + + vsnprintf(textbuffer, MAXBUF, text, argsPtr); + va_end(argsPtr); + sprintf(tb,":%s!%s@%s %s\r\n",user->nick,user->ident,user->dhost,textbuffer); + chop(tb); + if (sock != -1) + { + write(sock,tb,strlen(tb)); + update_stats_l(sock,strlen(tb)); /* add one line-out to stats L for this fd */ + } } /* write text to an destination user from a source user (e.g. user privmsg) */ @@ -2015,7 +2020,7 @@ void AddWhoWas(userrec* u) /* add a client connection to the sockets list */ -void AddClient(int socket, char* host, int port, bool iscached) +void AddClient(int socket, char* host, int port, bool iscached, char* ip) { int i; int blocking = 1; @@ -2054,6 +2059,7 @@ void AddClient(int socket, char* host, int port, bool iscached) clientlist[tempnick]->nping = time(NULL)+240; clientlist[tempnick]->lastping = 1; clientlist[tempnick]->port = port; + strncpy(clientlist[tempnick]->ip,ip,32); if (iscached) { @@ -2366,6 +2372,11 @@ void force_nickchange(userrec* user,const char* newnick) kill_link(user,"Nickname collision"); return; } + if (matches_qline(newnick)) + { + kill_link(user,"Nickname collision"); + return; + } if (user) { @@ -2738,6 +2749,10 @@ void SetupCommandTable(void) createcommand("MODULES",handle_modules,'o',0); createcommand("LINKS",handle_links,0,0); createcommand("MAP",handle_map,0,0); + createcommand("KLINE",handle_kline,'o',3); + createcommand("GLINE",handle_gline,'o',3); + createcommand("ZLINE",handle_zline,'o',3); + createcommand("QLINE",handle_qline,'o',3); } void process_buffer(const char* cmdbuf,userrec *user) @@ -3448,7 +3463,7 @@ int InspIRCd(void) } else { - AddClient(incomingSockfd, resolved, ports[count], iscached); + AddClient(incomingSockfd, resolved, ports[count], iscached, target); log(DEBUG,"InspIRCd: adding client on port %d fd=%d",ports[count],incomingSockfd); } goto label; diff --git a/src/users.cpp b/src/users.cpp index 48295eddd..6fb0e6a5c 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -12,7 +12,7 @@ userrec::userrec() { // the PROPER way to do it, AVOID bzero at *ALL* costs strcpy(nick,""); - ip = 0; + strcpy(ip,"127.0.0.1"); timeout = 0; strcpy(ident,""); strcpy(host,""); diff --git a/src/wildcard.cpp b/src/wildcard.cpp index 41070d145..f74de804a 100644 --- a/src/wildcard.cpp +++ b/src/wildcard.cpp @@ -75,7 +75,7 @@ if ((strstr(mask,"*")==0) && (strlen(literal) != strlen(mask))) } -bool match(char* literal, char* mask) +bool match(const char* literal, const char* mask) { char L[10240]; char M[10240]; diff --git a/src/xline.cpp b/src/xline.cpp index f653d80af..6ca005bad 100644 --- a/src/xline.cpp +++ b/src/xline.cpp @@ -35,6 +35,13 @@ #include "commands.h" #include "xline.h" +#ifdef GCC3 +#define nspace __gnu_cxx +#else +#define nspace std +#endif + + using namespace std; extern int MODCOUNT; @@ -56,8 +63,453 @@ extern char list[MAXBUF]; extern char PrefixQuit[MAXBUF]; extern char DieValue[MAXBUF]; +extern int debugging; +extern int WHOWAS_STALE; +extern int WHOWAS_MAX; +extern int DieDelay; +extern time_t startup_time; +extern int NetBufferSize; +extern time_t nb_start; + +extern std::vector fd_reap; +extern std::vector module_names; + +extern char bannerBuffer[MAXBUF]; +extern int boundPortCount; +extern int portCount; +extern int UDPportCount; +extern int ports[MAXSOCKS]; +extern int defaultRoute; + +extern std::vector auth_cookies; +extern std::stringstream config_f; + +extern serverrec* me[32]; + +extern FILE *log_file; + +namespace nspace +{ + template<> struct nspace::hash + { + size_t operator()(const struct in_addr &a) const + { + size_t q; + memcpy(&q,&a,sizeof(size_t)); + return q; + } + }; + + template<> struct nspace::hash + { + size_t operator()(const string &s) const + { + char a[MAXBUF]; + static struct hash strhash; + strcpy(a,s.c_str()); + strlower(a); + return strhash(a); + } + }; +} + + +struct StrHashComp +{ + + bool operator()(const string& s1, const string& s2) const + { + char a[MAXBUF],b[MAXBUF]; + strcpy(a,s1.c_str()); + strcpy(b,s2.c_str()); + return (strcasecmp(a,b) == 0); + } + +}; + +struct InAddr_HashComp +{ + + bool operator()(const in_addr &s1, const in_addr &s2) const + { + size_t q; + size_t p; + + memcpy(&q,&s1,sizeof(size_t)); + memcpy(&p,&s2,sizeof(size_t)); + + return (q == p); + } + +}; + + +typedef nspace::hash_map, StrHashComp> user_hash; +typedef nspace::hash_map, StrHashComp> chan_hash; +typedef nspace::hash_map, InAddr_HashComp> address_cache; +typedef std::deque command_table; + + +extern user_hash clientlist; +extern chan_hash chanlist; +extern user_hash whowas; +extern command_table cmdlist; +extern file_cache MOTD; +extern file_cache RULES; +extern address_cache IP; + + std::vector klines; std::vector glines; std::vector zlines; std::vector qlines; +// Reads the default bans from the config file. +// only a very small number of bans are defined +// this way these days, such as qlines against +// services nicks, etc. + +void read_xline_defaults() +{ + char ipmask[MAXBUF]; + char nick[MAXBUF]; + char host[MAXBUF]; + char reason[MAXBUF]; + + for (int i = 0; i < ConfValueEnum("badip",&config_f); i++) + { + ConfValue("badip","ipmask",i,ipmask,&config_f); + ConfValue("badip","reason",i,reason,&config_f); + add_zline(0,"",reason,ipmask); + log(DEBUG,"Read Z line (badip tag): ipmask=%s reason=%s",ipmask,reason); + } + + for (int i = 0; i < ConfValueEnum("badnick",&config_f); i++) + { + ConfValue("badnick","nick",i,nick,&config_f); + ConfValue("badnick","reason",i,reason,&config_f); + add_qline(0,"",reason,nick); + log(DEBUG,"Read Q line (badnick tag): nick=%s reason=%s",nick,reason); + } + + for (int i = 0; i < ConfValueEnum("badhost",&config_f); i++) + { + ConfValue("badhost","host",i,host,&config_f); + ConfValue("badhost","reason",i,reason,&config_f); + add_kline(0,"",reason,host); + log(DEBUG,"Read K line (badhost tag): host=%s reason=%s",host,reason); + } +} + +// adds a g:line + +void add_gline(long duration, char* source, char* reason, char* hostmask) +{ + GLine item; + item.duration = duration; + strncpy(item.hostmask,hostmask,MAXBUF); + strncpy(item.reason,reason,MAXBUF); + strncpy(item.source,source,MAXBUF); + item.n_matches = 0; + item.set_time = time(NULL); + glines.push_back(item); +} + +// adds a q:line + +void add_qline(long duration, char* source, char* reason, char* nickname) +{ + QLine item; + item.duration = duration; + strncpy(item.nick,nickname,MAXBUF); + strncpy(item.reason,reason,MAXBUF); + strncpy(item.source,source,MAXBUF); + item.n_matches = 0; + item.set_time = time(NULL); + qlines.push_back(item); +} + +// adds a z:line + +void add_zline(long duration, char* source, char* reason, char* ipaddr) +{ + ZLine item; + item.duration = duration; + strncpy(item.ipaddr,ipaddr,MAXBUF); + strncpy(item.reason,reason,MAXBUF); + strncpy(item.source,source,MAXBUF); + item.n_matches = 0; + item.set_time = time(NULL); + zlines.push_back(item); +} + +// adds a k:line + +void add_kline(long duration, char* source, char* reason, char* hostmask) +{ + KLine item; + item.duration = duration; + strncpy(item.hostmask,hostmask,MAXBUF); + strncpy(item.reason,reason,MAXBUF); + strncpy(item.source,source,MAXBUF); + item.n_matches = 0; + item.set_time = time(NULL); + klines.push_back(item); +} + +// deletes a g:line, returns true if the line existed and was removed + +bool del_gline(char* hostmask) +{ + for (std::vector::iterator i = glines.begin(); i != glines.end(); i++) + { + if (!strcasecmp(hostmask,i->hostmask)) + { + glines.erase(i); + return true; + } + } + return false; +} + +// deletes a q:line, returns true if the line existed and was removed + +bool del_qline(char* nickname) +{ + for (std::vector::iterator i = qlines.begin(); i != qlines.end(); i++) + { + if (!strcasecmp(nickname,i->nick)) + { + qlines.erase(i); + return true; + } + } + return false; +} + +// deletes a z:line, returns true if the line existed and was removed + +bool del_zline(char* ipaddr) +{ + for (std::vector::iterator i = zlines.begin(); i != zlines.end(); i++) + { + if (!strcasecmp(ipaddr,i->ipaddr)) + { + zlines.erase(i); + return true; + } + } + return false; +} + +// deletes a k:line, returns true if the line existed and was removed + +bool del_kline(char* hostmask) +{ + for (std::vector::iterator i = klines.begin(); i != klines.end(); i++) + { + if (!strcasecmp(hostmask,i->hostmask)) + { + klines.erase(i); + return true; + } + } + return false; +} + +// returns a pointer to the reason if a nickname matches a qline, NULL if it didnt match + +char* matches_qline(const char* nick) +{ + for (std::vector::iterator i = qlines.begin(); i != qlines.end(); i++) + { + if (match(nick,i->nick)) + { + return i->reason; + } + } + return NULL; +} + +// returns a pointer to the reason if a host matches a gline, NULL if it didnt match + +char* matches_gline(const char* host) +{ + for (std::vector::iterator i = glines.begin(); i != glines.end(); i++) + { + if (match(host,i->hostmask)) + { + return i->reason; + } + } + return NULL; +} + +// returns a pointer to the reason if an ip address matches a zline, NULL if it didnt match + +char* matches_zline(const char* ipaddr) +{ + for (std::vector::iterator i = zlines.begin(); i != zlines.end(); i++) + { + if (match(ipaddr,i->ipaddr)) + { + return i->reason; + } + } + return NULL; +} + +// returns a pointer to the reason if a host matches a kline, NULL if it didnt match + +char* matches_kline(const char* host) +{ + for (std::vector::iterator i = klines.begin(); i != klines.end(); i++) + { + if (match(host,i->hostmask)) + { + return i->reason; + } + } + return NULL; +} + +// removes lines that have expired + +void expire_lines() +{ + bool go_again = true; + time_t current = time(NULL); + + // because we mess up an iterator when we remove from the vector, we must bail from + // the loop early if we delete an item, therefore this outer while loop is required. + while (go_again) + { + go_again = false; + + for (std::vector::iterator i = klines.begin(); i != klines.end(); i++) + { + if ((current > (i->duration + i->set_time)) && (i->duration > 0)) + { + WriteOpers("Expiring timed K-Line %s (set by %s %d seconds ago)",i->hostmask,i->source,i->duration); + klines.erase(i); + go_again = true; + break; + } + } + + for (std::vector::iterator i = glines.begin(); i != glines.end(); i++) + { + if ((current > (i->duration + i->set_time)) && (i->duration > 0)) + { + WriteOpers("Expiring timed G-Line %s (set by %s %d seconds ago)",i->hostmask,i->source,i->duration); + glines.erase(i); + go_again = true; + break; + } + } + + for (std::vector::iterator i = zlines.begin(); i != zlines.end(); i++) + { + if ((current > (i->duration + i->set_time)) && (i->duration > 0)) + { + WriteOpers("Expiring timed Z-Line %s (set by %s %d seconds ago)",i->ipaddr,i->source,i->duration); + zlines.erase(i); + go_again = true; + break; + } + } + + for (std::vector::iterator i = qlines.begin(); i != qlines.end(); i++) + { + if ((current > (i->duration + i->set_time)) && (i->duration > 0)) + { + WriteOpers("Expiring timed Q-Line %s (set by %s %d seconds ago)",i->nick,i->source,i->duration); + qlines.erase(i); + go_again = true; + break; + } + } + } +} + +// applies lines, removing clients and changing nicks etc as applicable + +void apply_lines() +{ + bool go_again = true; + char reason[MAXBUF]; + char host[MAXBUF]; + + while (go_again) + { + go_again = false; + for (user_hash::const_iterator u = clientlist.begin(); u != clientlist.end(); u++) + { + if (!strcasecmp(u->second->server,ServerName)) + { + snprintf(host,MAXBUF,"%s@%s",u->second->ident,u->second->host); + char* check = matches_gline(host); + if (check) + { + WriteOpers("*** User %s matches G-Line: %s",u->second->nick,check); + snprintf(reason,MAXBUF,"G-Lined: %s",check); + kill_link(u->second,reason); + go_again = true; + break; + } + } + } + + for (user_hash::const_iterator u = clientlist.begin(); u != clientlist.end(); u++) + { + if (!strcasecmp(u->second->server,ServerName)) + { + snprintf(host,MAXBUF,"%s@%s",u->second->ident,u->second->host); + char* check = matches_kline(host); + if (check) + { + WriteOpers("*** User %s matches K-Line: %s",u->second->nick,check); + snprintf(reason,MAXBUF,"K-Lined: %s",check); + kill_link(u->second,reason); + go_again = true; + break; + } + } + } + + for (user_hash::const_iterator u = clientlist.begin(); u != clientlist.end(); u++) + { + if (!strcasecmp(u->second->server,ServerName)) + { + char* check = matches_qline(u->second->nick); + if (check) + { + snprintf(reason,MAXBUF,"Matched Q-Lined nick: %s",check); + WriteOpers("*** Q-Lined nickname %s from %s: %s",u->second->nick,u->second->host,check); + WriteServ(u->second->fd,"432 %s %s :Invalid nickname: %s",u->second->nick,u->second->nick,check); + kill_link(u->second,reason); + go_again = true; + break; + } + } + } + + for (user_hash::const_iterator u = clientlist.begin(); u != clientlist.end(); u++) + { + if (!strcasecmp(u->second->server,ServerName)) + { + char* check = matches_zline(u->second->ip); + if (check) + { + WriteOpers("*** User %s matches Z-Line: %s",u->second->nick,u->second->host,check); + WriteServ(u->second->fd,"432 %s %s :Invalid nickname: %s",u->second->nick,u->second->nick,check); + go_again = true; + break; + } + } + } + + } +} + + -- 2.39.5