/** * ccontrol.cc * Main ccontrol implementation class * * @author Daniel Karrels dan@karrels.com * @author Tomer Cohen MrBean@Undernet.org * * 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: ccontrol.cc,v 1.243 2010/09/12 20:28:24 hidden1 Exp $ */ #define MAJORVER "1" #define MINORVER "2pl7" #define RELDATE "05th April, 2012" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "client.h" #include "iClient.h" #include "EConfig.h" #include "events.h" #include "StringTokenizer.h" #include "misc.h" #include "Network.h" #include "ELog.h" #include "ccUser.h" #include "dbHandle.h" #include "ccontrol.h" #include "server.h" #include "Constants.h" #include "commLevels.h" #include "ccFloodData.h" #include "ccUserData.h" #include "ip.h" #include "ccontrol_generic.h" #include "gnuworld_config.h" RCSTAG( "$Id: ccontrol.cc,v 1.243 2010/09/12 20:28:24 hidden1 Exp $" ) ; namespace gnuworld { using std::ends ; using std::stringstream ; using std::string ; using std::vector ; using std::cout ; using std::endl ; using std::count ; namespace uworld { using namespace std; /** * Exported function used by moduleLoader to gain an * instance of this module. */ extern "C" { xClient* _gnuwinit(const string& args) { return new ccontrol( args ); } } bool dbConnected = false; ccontrol::ccontrol( const string& configFileName ) : xClient( configFileName ) { elog << "Initializing ccontrol version " << MAJORVER << "." << MINORVER << " please standby... " << endl; myHub = 0; ccHub = 0; // Read the config file EConfig conf( configFileName ) ; sqlHost = conf.Find("sql_host" )->second; sqlDb = conf.Find( "sql_db" )->second; sqlPort = conf.Find( "sql_port" )->second; sqlPass = conf.Require( "sql_pass" )->second; sqlUser = conf.Require( "sql_user" )->second; inBurst = true; inRefresh = false; string Query = "host=" + sqlHost + " dbname=" + sqlDb + " port=" + sqlPort; if (strcasecmp(sqlUser,"''")) { Query += (" user=" + sqlUser); } if (strcasecmp(sqlPass,"''")) { Query += (" password=" + sqlPass); } elog << Query << endl ; elog << "ccontrol::ccontrol> Attempting to connect to " << sqlHost << "; Database: " << sqlDb << endl; SQLDb = new dbHandle( sqlHost, ::atoi( sqlPort.c_str() ), sqlDb, sqlUser, sqlPass ) ; //(std::nothrow) cmDatabase( Query.c_str() ) ; assert( SQLDb != 0 ) ; //-- Make sure we connected to the SQL database; if // we didn't we exit entirely. if (SQLDb->ConnectionBad ()) { elog << "ccontrol::ccontrol> Unable to connect to SQL server." << endl << "ccontrol::ccontrol> PostgreSQL error message: " << SQLDb->ErrorMessage() << endl ; ::exit( 0 ) ; } else { elog << "ccontrol::ccontrol> Connection established to SQL " << endl ; } dbConnected = true; // operChanReason is the reason used when kicking non-opers from // oper-only channels operChanReason = conf.Find( "operchanreason" )->second ; // operChanModes are the modes to set when setting up an oper-only // channel operChanModes = conf.Find( "operchanmodes" )->second ; // Number of channels to show with list channels command maxListChannels = atoi( conf.Find( "maxlistchannels" )->second.c_str() ) ; // gLength is the length of time (in seconds) for default glines gLength = atoi( conf.Find( "glength" )->second.c_str() ) ; // CCEmail is the email ccontrol will post the last com report under CCEmail = conf.Require( "ccemail" )->second; //AbuseMail is the mail that the lastcom report will be post to AbuseMail = conf.Require( "abuse_mail" )->second; //GLInterval is the inteval in which ccontrol will check for expired glines ExpiredInterval = atoi( conf.Require( "Expired_interval" )->second.c_str() ); //Sendmail is the full path of the sendmail program Sendmail_Path = conf.Require("SendMail")->second; //SendReport flag that tells ccontrol if the user want the report to be mailed SendReport = atoi(conf.Require("mail_report")->second.c_str()); maxThreads = atoi(conf.Require("max_threads")->second.c_str()); checkClones = atoi(conf.Require("check_clones")->second.c_str()); showCGIpsInLogs = atoi(conf.Require("showCGIpsInLogs")->second.c_str()); dbConnectionTimer = atoi(conf.Require("dbinterval")->second.c_str()); AnnounceNick = conf.Require("AnnounceNick")->second; // Set up the oper channels EConfig::const_iterator ptr = conf.Find( "operchan" ) ; while( ptr != conf.end() && ptr->first == "operchan" ) { operChans.push_back( ptr->second ) ; ++ptr ; } // Read out the client's message channel msgChan = conf.Find( "msgchan" )->second ; // Make sure that the msgChan is in the list of operchans if( operChans.end() == find( operChans.begin(), operChans.end(), msgChan ) ) { // Not found, add it to the list of operChans operChans.push_back( msgChan ) ; } // Be sure to use all capital letters for the command name RegisterCommand( new HELPCommand( this, "HELP", "[topic]" "\t\tObtain general help or help for a specific command", true, commandLevel::flg_HELP, false, false, true, operLevel::OPERLEVEL, false ) ) ; RegisterCommand( new INVITECommand( this, "INVITE", "<#channel> " "\t\tRequest an invitation to a channel", false, commandLevel::flg_INVITE, false, true, false, operLevel::OPERLEVEL, false ) ) ; RegisterCommand( new JUPECommand( this, "JUPE", " " "Jupe a server for the given reason.", false, commandLevel::flg_JUPE, false, true, false, operLevel::OPERLEVEL, false ) ) ; RegisterCommand( new MODECommand( this, "MODE", " " "Change modes on the given channel", false, commandLevel::flg_MODE, false, true, false, operLevel::OPERLEVEL, false ) ) ; RegisterCommand( new SCHANGLINECommand( this, "SCHANGLINE", "[-u] <#channel> [time units (s,d,h)] " "Gline a given channel for the given reason", true, commandLevel::flg_SCHANGLINE, false, true, false, operLevel::CODERLEVEL, true ) ) ; RegisterCommand( new FORCECHANGLINECommand( this, "FORCECHANGLINE", "[-u] <#channel> [time units (s,d,h)] " "Gline a given channel for the given reason", true, commandLevel::flg_FORCECHANGLINE, false, true, false, operLevel::OPERLEVEL, true ) ) ; RegisterCommand( new GLINECommand( this, "GLINE", " [time units (s,d,h)] " "Gline a given user@host for the given reason", true, commandLevel::flg_GLINE, false, true, false, operLevel::OPERLEVEL, false ) ) ; RegisterCommand( new SCANGLINECommand( this, "SCANGLINE", " " "Search current network glines for glines matching ", false, commandLevel::flg_SCGLINE, false, true, false, operLevel::OPERLEVEL, false ) ) ; RegisterCommand( new REMGLINECommand( this, "REMGLINE", " " "Remove the gline matching ", true, commandLevel::flg_REMGLINE, false, true, false, operLevel::OPERLEVEL, false ) ) ; RegisterCommand( new TRANSLATECommand( this, "TRANSLATE", "" "Translate a numeric into user information", false, commandLevel::flg_TRANS, false, true, false, operLevel::OPERLEVEL, false ) ) ; RegisterCommand( new WHOISCommand( this, "WHOIS", "" "Obtain information on a given nickname", false, commandLevel::flg_WHOIS, false, true, false, operLevel::OPERLEVEL, false ) ) ; RegisterCommand( new KICKCommand( this, "KICK", " " "Kick a user from a channel", false, commandLevel::flg_KICK, false, true, false, operLevel::OPERLEVEL, false ) ) ; // The following commands deals with operchans, if you want operchans // just uncomment them /* RegisterCommand( new ADDOPERCHANCommand( this, "ADDOPERCHAN", "" "Add an oper channel", false, commandLevel::flg_ADDOPCHN, false, true, false, operLevel::OPERLEVEL, false ) ) ; RegisterCommand( new REMOPERCHANCommand( this, "REMOPERCHAN", "" "Remove an oper channel", false, commandLevel::flg_REMOPCHN, false, true, false, operLevel::OPERLEVEL, false ) ) ; RegisterCommand( new LISTOPERCHANSCommand( this, "LISTOPERCHANS", "List current IRCoperator only channels", false, commandLevel::flg_LOPCHN, true, false, false,operLevel::OPERLEVEL, false ) ) ; */ RegisterCommand( new CHANINFOCommand( this, "CHANINFO", "" "Obtain information about a given channel", false, commandLevel::flg_CHINFO, false, true, false, operLevel::OPERLEVEL, false ) ) ; RegisterCommand( new LOGINCommand( this, "LOGIN", " " "Authenticate with the bot", true, commandLevel::flg_LOGIN, false, false, true, operLevel::OPERLEVEL, false ) ) ; RegisterCommand( new DEAUTHCommand( this, "DEAUTH", "" "Deauthenticate with the bot", false, commandLevel::flg_DEAUTH, false, false, true, operLevel::OPERLEVEL, false ) ) ; RegisterCommand( new DEAUTHCommand( this, "LOGOUT", "" "Deauthenticate with the bot", false, commandLevel::flg_DEAUTH, false, false, true, operLevel::OPERLEVEL, false ) ) ; RegisterCommand( new ADDUSERCommand( this, "ADDUSER", " [SERVER*] " "Add a new oper", true, commandLevel::flg_ADDNOP, false, true, false, operLevel::OPERLEVEL, false ) ) ; RegisterCommand( new REMUSERCommand( this, "REMUSER", " " "Remove an oper", true, commandLevel::flg_REMOP, false, true, false, operLevel::OPERLEVEL, false ) ) ; RegisterCommand( new ADDCOMMANDCommand( this, "ADDCOMMAND", " " "Add a new command to an oper", true, commandLevel::flg_ADDCMD, false, true, false, operLevel::OPERLEVEL, false ) ) ; RegisterCommand( new REMCOMMANDCommand( this, "REMCOMMAND", " " "Remove a command from oper", true, commandLevel::flg_DELCMD, false, true, false, operLevel::OPERLEVEL, false ) ) ; RegisterCommand( new NEWPASSCommand( this, "NEWPASS", " " "Change password", true, commandLevel::flg_NEWPASS, false, false, true, operLevel::UHSLEVEL, false ) ) ; RegisterCommand( new SUSPENDCommand( this, "SUSPEND", " [-l level] " "Suspend an oper", true, commandLevel::flg_SUSPEND, false, true, false, operLevel::OPERLEVEL, false ) ) ; RegisterCommand( new UNSUSPENDCommand( this, "UNSUSPEND", " " "UnSuspend an oper", true, commandLevel::flg_UNSUSPEND, false, true, false, operLevel::OPERLEVEL, false ) ) ; RegisterCommand( new MODUSERCommand( this, "MODUSER", "