276 lines
6.6 KiB
C++
276 lines
6.6 KiB
C++
/**
|
|
* SGLINECommand.cc
|
|
* Glines a specific mask
|
|
*
|
|
* 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 the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
|
* USA.
|
|
*
|
|
* $Id: SGLINECommand.cc,v 1.15 2009/05/16 07:47:23 danielaustin Exp $
|
|
*/
|
|
|
|
#include <string>
|
|
#include <iomanip>
|
|
|
|
#include <cstdlib>
|
|
|
|
#include "ccontrol.h"
|
|
#include "CControlCommands.h"
|
|
#include "StringTokenizer.h"
|
|
#include "Network.h"
|
|
#include "misc.h"
|
|
#include "Gline.h"
|
|
#include "ip.h"
|
|
#include "ELog.h"
|
|
#include "Constants.h"
|
|
#include "gnuworld_config.h"
|
|
|
|
RCSTAG( "$Id: SGLINECommand.cc,v 1.15 2009/05/16 07:47:23 danielaustin Exp $" ) ;
|
|
|
|
namespace gnuworld
|
|
{
|
|
|
|
using std::string ;
|
|
|
|
// Input: sgline *@blah.net reason
|
|
// Input: sgline 3600 *@blah.net reason
|
|
//
|
|
// Output: C GL * +*@lamer.net 3600 :Banned (*@lamer) ...
|
|
//
|
|
namespace uworld
|
|
{
|
|
|
|
bool SGLINECommand::Exec( iClient* theClient, const string& Message )
|
|
{
|
|
|
|
StringTokenizer st( Message ) ;
|
|
|
|
if(st.size() < 3)
|
|
{
|
|
Usage( theClient ) ;
|
|
return true ;
|
|
}
|
|
StringTokenizer::size_type pos = 1 ;
|
|
bool RealName = (!strcasecmp(st[pos],"-rn"));
|
|
if(RealName && (st.size() < 4))
|
|
{
|
|
Usage(theClient);
|
|
return true;
|
|
}
|
|
|
|
string RealHost;
|
|
|
|
|
|
ccUser* tmpUser = bot->IsAuth(theClient);
|
|
bot->MsgChanLog("SGLINE %s\n",st.assemble(1).c_str());
|
|
|
|
if(!RealName &&(string::npos != st[pos].find_first_of('#')))
|
|
{
|
|
bot->Notice(theClient,"I don't think glining that host is such a good idea");
|
|
return true;
|
|
}
|
|
time_t gLength = bot->getDefaultGlineLength() ;
|
|
|
|
// (pos) is the index of the next token, the user@host mask.
|
|
|
|
if(!RealName)
|
|
{
|
|
string::size_type atPos = st[ pos ].find_first_of( '@' ) ;
|
|
if( string::npos == atPos )
|
|
{
|
|
// User has only specified hostname, not a user name
|
|
bot->Notice( theClient, "GLINE: Please specify gline mask in the "
|
|
"format of user@host" ) ;
|
|
return true ;
|
|
}
|
|
|
|
string userName = st[ pos ].substr( 0, pos ) ;
|
|
string hostName = st[ pos ].substr( pos + 1 ) ;
|
|
}
|
|
else //RealName Gline
|
|
{
|
|
++pos;
|
|
bool hostOk = false;
|
|
bool hasSlash = false;
|
|
if(st[pos].substr(0,2) != "$R")
|
|
{
|
|
RealHost = "$R" + st[pos];
|
|
}
|
|
else
|
|
{
|
|
RealHost = st[pos];
|
|
}
|
|
//Do alittle sanity check
|
|
for(string::size_type p =2; p< st[pos].size();++p)
|
|
{
|
|
if(RealHost[p] != '$' && RealHost[p] != '*' && RealHost[p] != '?')
|
|
hostOk = true;
|
|
if (RealHost[p] == '/')
|
|
hasSlash = true;
|
|
}
|
|
if(!hostOk)
|
|
{
|
|
bot->Notice(theClient,"You must specify at least one character other "
|
|
"than *?$ as the realname!");
|
|
return true;
|
|
}
|
|
if(hasSlash)
|
|
{
|
|
bot->Notice(theClient, "You can't use a '/' in a realname gline, consider switching it to a '?'");
|
|
return true;
|
|
}
|
|
}
|
|
|
|
string Length;
|
|
Length.assign(st[pos+1]);
|
|
unsigned int Units = 1; //Defualt for seconds
|
|
unsigned int ResStart = 2;
|
|
bool Ok = true;
|
|
if(!strcasecmp(Length.substr(Length.length()-1).c_str(),"d"))
|
|
{
|
|
Units = 24*3600;
|
|
Length.resize(Length.length()-1);
|
|
}
|
|
else if(!strcasecmp(Length.substr(Length.length()-1).c_str(),"h"))
|
|
{
|
|
Units = 3600;
|
|
Length.resize(Length.length()-1);
|
|
}
|
|
else if(!strcasecmp(Length.substr(Length.length()-1).c_str(),"m"))
|
|
{
|
|
Units = 60;
|
|
Length.resize(Length.length()-1);
|
|
}
|
|
else if(!strcasecmp(Length.substr(Length.length()-1).c_str(),"s"))
|
|
{
|
|
Units = 1;
|
|
Length.resize(Length.length()-1);
|
|
}
|
|
gLength = atoi(Length.c_str()) * Units;
|
|
|
|
if(gLength == 0)
|
|
{
|
|
gLength = bot->getDefaultGlineLength() ;
|
|
ResStart = 1;
|
|
}
|
|
if(!tmpUser)
|
|
{ // We shouldnt have got here in the first place, but check it anyway
|
|
return false;
|
|
}
|
|
|
|
unsigned int Users;
|
|
string nickUserHost = bot->removeSqlChars(theClient->getRealNickUserHost()) ;
|
|
StringTokenizer ReasonTokenizer ( st.assemble( pos + ResStart ), '|');
|
|
string Reason = ReasonTokenizer[0];
|
|
|
|
if(!RealName)
|
|
{
|
|
int gCheck = bot->checkSGline(st[pos],gLength,Users);
|
|
|
|
if(gCheck & gline::NEG_TIME)
|
|
{
|
|
bot->Notice(theClient,"A negative gline duration is not valid.");
|
|
Ok = false;
|
|
}
|
|
|
|
if(gCheck & gline::HUH_NO_HOST)
|
|
{
|
|
bot->Notice(theClient,"I don't think glining that host is such a good idea, do you?");
|
|
Ok = false;
|
|
}
|
|
if(gCheck & gline::BAD_CIDRMASK)
|
|
{
|
|
bot->Notice(theClient,"The IP listed is not on a bit boundary for the CIDR mask specified.");
|
|
Ok = false;
|
|
}
|
|
if(gCheck & gline::BAD_CIDRLEN)
|
|
{
|
|
bot->Notice(theClient,"Bad CIDR length - try something more specific.");
|
|
Ok = false;
|
|
}
|
|
if(gCheck & gline::BAD_CIDROVERRIDE)
|
|
{
|
|
bot->Notice(theClient,"For CIDR sglines, you must enter all 4 parts of the IP.");
|
|
Ok = false;
|
|
}
|
|
if(gCheck & gline::BAD_HOST)
|
|
{
|
|
bot->Notice(theClient,"illegal host");
|
|
Ok = false;
|
|
}
|
|
if(!Ok)
|
|
{
|
|
bot->Notice(theClient,"Please fix all of the above, and try again");
|
|
return false;
|
|
|
|
}
|
|
|
|
char Us[100];
|
|
Us[0] = '\0';
|
|
sprintf(Us,"%d",Users);
|
|
Reason = string("[") + Us + string("] ") + Reason;
|
|
} //RealName Gline
|
|
else
|
|
{
|
|
Users = Network->matchRealName(RealHost.substr(2,RealHost.size()-2)).size();
|
|
char Us[100];
|
|
Us[0] = '\0';
|
|
sprintf(Us,"%d",Users);
|
|
Reason = string("[") + Us + string ("] ") + Reason;
|
|
}
|
|
if(Reason.size() > gline::MAX_REASON_LENGTH)
|
|
{
|
|
bot->Notice(theClient,"Gline reason can't be more than %d characters",
|
|
gline::MAX_REASON_LENGTH);
|
|
return false;
|
|
}
|
|
/*server->setGline( nickUserHost,
|
|
st[ pos ],
|
|
string("[") + Us + "] " + Reason,
|
|
//st.assemble( pos + ResStart ) + "[" + Us + "]",
|
|
gLength , bot) ;*/
|
|
ccGline *TmpGline = bot->findGline(st[pos]);
|
|
bool Up = false;
|
|
|
|
if(TmpGline)
|
|
Up = true;
|
|
else TmpGline = new ccGline(bot->SQLDb);
|
|
if(!RealName)
|
|
TmpGline->setHost(bot->removeSqlChars(st [ pos ]));
|
|
else
|
|
TmpGline->setHost(RealHost);
|
|
TmpGline->setExpires(::time(0) + gLength);
|
|
TmpGline->setAddedBy(nickUserHost);
|
|
TmpGline->setReason(Reason);
|
|
TmpGline->setAddedOn(::time(0));
|
|
TmpGline->setLastUpdated(::time(0));
|
|
bot->addGlineToUplink(TmpGline);
|
|
if(Up)
|
|
{
|
|
TmpGline->Update();
|
|
}
|
|
else
|
|
{
|
|
TmpGline->Insert();
|
|
//We need to update the Id
|
|
TmpGline->loadData(TmpGline->getHost());
|
|
bot->addGline(TmpGline);
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
}
|
|
}
|