2016-08-28 20:53:52 +00:00
< ? php
/*
* Copyright ( C ) 2014 < singh @ devilcode . org >
* Modified and Relicensed by < f0o @ devilcode . org > under the expressed
* permission by the Copyright - Holder < singh @ devilcode . 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 3 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 , see < http :// www . gnu . org / licenses />.
* */
namespace LibreNMS ;
2017-04-06 21:02:37 +00:00
use LibreNMS\Exceptions\DatabaseConnectException ;
2016-08-28 22:32:55 +00:00
class IRCBot
{
2016-08-28 20:53:52 +00:00
private $last_activity = '' ;
private $data = '' ;
private $authd = array ();
private $debug = false ;
private $server = '' ;
private $port = '' ;
private $ssl = false ;
private $pass = '' ;
private $nick = 'LibreNMS' ;
private $chan = array ();
private $commands = array (
'auth' ,
'quit' ,
'listdevices' ,
'device' ,
'port' ,
'down' ,
'version' ,
'status' ,
'log' ,
'help' ,
'reload' ,
'join' ,
);
private $external = array ();
private $tick = 62500 ;
2016-08-28 22:32:55 +00:00
public function __construct ()
{
2016-08-28 20:53:52 +00:00
global $config , $database_link ;
$this -> log ( 'Setting up IRC-Bot..' );
if ( is_resource ( $database_link )) {
$this -> sql = $database_link ;
}
$this -> config = $config ;
$this -> debug = $this -> config [ 'irc_debug' ];
$this -> config [ 'irc_authtime' ] = $this -> config [ 'irc_authtime' ] ? $this -> config [ 'irc_authtime' ] : 3 ;
$this -> max_retry = $this -> config [ 'irc_maxretry' ];
$this -> server = $this -> config [ 'irc_host' ];
if ( $this -> config [ 'irc_port' ][ 0 ] == '+' ) {
$this -> ssl = true ;
$this -> port = substr ( $this -> config [ 'irc_port' ], 1 );
2016-08-28 22:32:55 +00:00
} else {
2016-08-28 20:53:52 +00:00
$this -> port = $this -> config [ 'irc_port' ];
}
if ( $this -> config [ 'irc_nick' ]) {
$this -> nick = $this -> config [ 'irc_nick' ];
}
if ( $this -> config [ 'irc_chan' ]) {
if ( is_array ( $this -> config [ 'irc_chan' ])) {
$this -> chan = $this -> config [ 'irc_chan' ];
2016-08-28 22:32:55 +00:00
} elseif ( strstr ( $this -> config [ 'irc_chan' ], ',' )) {
2016-08-28 20:53:52 +00:00
$this -> chan = explode ( ',' , $this -> config [ 'irc_chan' ]);
2016-08-28 22:32:55 +00:00
} else {
2016-08-28 20:53:52 +00:00
$this -> chan = array ( $this -> config [ 'irc_chan' ]);
}
}
if ( $this -> config [ 'irc_alert_chan' ]) {
if ( strstr ( $this -> config [ 'irc_alert_chan' ], ',' )) {
$this -> config [ 'irc_alert_chan' ] = explode ( ',' , $this -> config [ 'irc_alert_chan' ]);
2016-08-28 22:32:55 +00:00
} else {
2016-08-28 20:53:52 +00:00
$this -> config [ 'irc_alert_chan' ] = array ( $this -> config [ 'irc_alert_chan' ]);
}
}
if ( $this -> config [ 'irc_pass' ]) {
$this -> pass = $this -> config [ 'irc_pass' ];
}
2016-08-28 22:32:55 +00:00
$this -> loadExternal ();
2016-08-28 20:53:52 +00:00
$this -> log ( 'Starting IRC-Bot..' );
$this -> init ();
} //end __construct()
2016-08-28 22:32:55 +00:00
private function loadExternal ()
{
2016-08-28 20:53:52 +00:00
if ( ! $this -> config [ 'irc_external' ]) {
return true ;
}
$this -> log ( 'Caching external commands...' );
if ( ! is_array ( $this -> config [ 'irc_external' ])) {
$this -> config [ 'irc_external' ] = explode ( ',' , $this -> config [ 'irc_external' ]);
}
foreach ( $this -> config [ 'irc_external' ] as $ext ) {
if (( $this -> external [ $ext ] = file_get_contents ( 'includes/ircbot/' . $ext . '.inc.php' )) == '' ) {
unset ( $this -> external [ $ext ]);
}
}
return $this -> log ( 'Cached ' . sizeof ( $this -> external ) . ' commands.' );
} //end load_external()
2016-08-28 22:32:55 +00:00
private function init ()
{
2016-08-28 20:53:52 +00:00
if ( $this -> config [ 'irc_alert' ]) {
2016-08-28 22:32:55 +00:00
$this -> connectAlert ();
2016-08-28 20:53:52 +00:00
}
$this -> last_activity = time ();
$this -> j = 2 ;
$this -> connect ();
$this -> log ( 'Connected' );
if ( $this -> pass ) {
fwrite ( $this -> socket [ 'irc' ], 'PASS ' . $this -> pass . " \n \r " );
}
$this -> doAuth ();
while ( true ) {
foreach ( $this -> socket as $n => $socket ) {
if ( ! is_resource ( $socket ) || feof ( $socket )) {
$this -> log ( " Socket ' $n ' closed. Restarting. " );
break 2 ;
}
}
$this -> getData ();
if ( $this -> config [ 'irc_alert' ]) {
$this -> alertData ();
}
if ( $this -> config [ 'irc_conn_timeout' ]) {
$inactive_seconds = time () - $this -> last_activity ;
$max_inactive = $this -> config [ 'irc_conn_timeout' ];
if ( $inactive_seconds > $max_inactive ) {
$this -> log ( " No data from server since " . $max_inactive . " seconds. Restarting. " );
break ;
}
}
usleep ( $this -> tick );
}
return $this -> init ();
} //end init()
2016-08-28 22:32:55 +00:00
private function connectAlert ()
{
2016-08-28 20:53:52 +00:00
$f = $this -> config [ 'install_dir' ] . '/.ircbot.alert' ;
if (( file_exists ( $f ) && filetype ( $f ) != 'fifo' && ! unlink ( $f ) ) || ( ! file_exists ( $f ) && ! shell_exec ( " mkfifo $f && echo 1 " ) )) {
$this -> log ( 'Error - Cannot create Alert-File' );
return false ;
}
if (( $this -> socket [ 'alert' ] = fopen ( $f , 'r+' ))) {
$this -> log ( 'Opened Alert-File' );
stream_set_blocking ( $this -> socket [ 'alert' ], false );
return true ;
}
$this -> log ( 'Error - Cannot open Alert-File' );
return false ;
} //end connect_alert()
2016-08-28 22:32:55 +00:00
private function read ( $buff )
{
2016-08-28 20:53:52 +00:00
$r = fread ( $this -> socket [ $buff ], 64 );
$this -> buff [ $buff ] .= $r ;
$r = strlen ( $r );
if ( strstr ( $this -> buff [ $buff ], " \n " )) {
$tmp = explode ( " \n " , $this -> buff [ $buff ], 2 );
$this -> buff [ $buff ] = substr ( $this -> buff [ $buff ], ( strlen ( $tmp [ 0 ]) + 1 ));
if ( $this -> debug ) {
$this -> log ( " Returning buffer ' $buff ': ' " . trim ( $tmp [ 0 ]) . " ' " );
}
return $tmp [ 0 ];
}
if ( $this -> debug && $r > 0 ) {
$this -> log ( " Expanding buffer ' $buff ' = ' " . trim ( $this -> buff [ $buff ]) . " ' " );
}
return false ;
} //end read()
2016-08-28 22:32:55 +00:00
private function alertData ()
{
2016-08-28 20:53:52 +00:00
if (( $alert = $this -> read ( 'alert' )) !== false ) {
$alert = json_decode ( $alert , true );
if ( ! is_array ( $alert )) {
return false ;
}
2016-08-28 22:32:55 +00:00
switch ( $alert [ 'state' ]) :
case 3 :
$severity_extended = '+' ;
break ;
case 4 :
$severity_extended = '-' ;
break ;
default :
$severity_extended = '' ;
2016-08-28 20:53:52 +00:00
endswitch ;
2017-06-02 19:07:09 +00:00
$severity = str_replace ( array ( 'warning' , 'critical' ), array ( _color ( 'Warning' , 'orange' ), _color ( 'Critical' , 'red' )), $alert [ 'severity' ]) . $severity_extended . ' ' ;
2016-08-28 20:53:52 +00:00
if ( $alert [ 'state' ] == 0 and $this -> config [ 'irc_alert_utf8' ]) {
2017-05-31 14:05:06 +00:00
$severity = str_replace ( array ( 'Warning' , 'Critical' ), array ( '̶W̶a̶r̶n̶i̶n̶g' , '̶C̶r̶i̶t̶i̶c̶a̶l' ), $severity );
2016-08-28 20:53:52 +00:00
}
if ( $this -> config [ 'irc_alert_chan' ]) {
foreach ( $this -> config [ 'irc_alert_chan' ] as $chan ) {
2016-08-28 22:32:55 +00:00
$this -> ircRaw ( 'PRIVMSG ' . $chan . ' :' . $severity . trim ( $alert [ 'title' ]) . ' - Rule: ' . trim ( $alert [ 'name' ] ? $alert [ 'name' ] : $alert [ 'rule' ]) . ( sizeof ( $alert [ 'faults' ]) > 0 ? ' - Faults:' : '' ));
2016-08-28 20:53:52 +00:00
foreach ( $alert [ 'faults' ] as $k => $v ) {
2016-08-28 22:32:55 +00:00
$this -> ircRaw ( 'PRIVMSG ' . $chan . ' :#' . $k . ' ' . $v [ 'string' ]);
2016-08-28 20:53:52 +00:00
}
}
2016-08-28 22:32:55 +00:00
} else {
2016-08-28 20:53:52 +00:00
foreach ( $this -> authd as $nick => $data ) {
if ( $data [ 'expire' ] >= time ()) {
2016-08-28 22:32:55 +00:00
$this -> ircRaw ( 'PRIVMSG ' . $nick . ' :' . $severity . trim ( $alert [ 'title' ]) . ' - Rule: ' . trim ( $alert [ 'name' ] ? $alert [ 'name' ] : $alert [ 'rule' ]) . ( sizeof ( $alert [ 'faults' ]) > 0 ? ' - Faults' . ( sizeof ( $alert [ 'faults' ]) > 3 ? ' (showing first 3 out of ' . sizeof ( $alert [ 'faults' ]) . ' )' : '' ) . ':' : '' ));
2016-08-28 20:53:52 +00:00
foreach ( $alert [ 'faults' ] as $k => $v ) {
2016-08-28 22:32:55 +00:00
$this -> ircRaw ( 'PRIVMSG ' . $nick . ' :#' . $k . ' ' . $v [ 'string' ]);
2016-08-28 20:53:52 +00:00
if ( $k >= 3 ) {
break ;
}
}
}
}
}
} //end if
} //end alertData()
2016-08-28 22:32:55 +00:00
private function getData ()
{
2016-08-28 20:53:52 +00:00
if (( $data = $this -> read ( 'irc' )) !== false ) {
$this -> last_activity = time ();
$this -> data = $data ;
$ex = explode ( ' ' , $this -> data );
if ( $ex [ 0 ] == 'PING' ) {
2016-08-28 22:32:55 +00:00
return $this -> ircRaw ( 'PONG ' . $ex [ 1 ]);
2016-08-28 20:53:52 +00:00
}
if ( $ex [ 1 ] == 376 || $ex [ 1 ] == 422 || ( $ex [ 1 ] == 'MODE' && $ex [ 2 ] == $this -> nick )) {
if ( $this -> j == 2 ) {
$this -> joinChan ();
$this -> j = 0 ;
}
}
$this -> command = str_replace ( array ( chr ( 10 ), chr ( 13 )), '' , $ex [ 3 ]);
if ( strstr ( $this -> command , ':.' )) {
$this -> handleCommand ();
}
}
} //end getData()
2016-08-28 22:32:55 +00:00
private function joinChan ( $chan = false )
{
2016-08-28 20:53:52 +00:00
if ( $chan ) {
$this -> chan [] = $chan ;
}
foreach ( $this -> chan as $chan ) {
2016-08-28 22:32:55 +00:00
$this -> ircRaw ( 'JOIN ' . $chan );
2016-08-28 20:53:52 +00:00
}
return true ;
} //end joinChan()
2016-08-28 22:32:55 +00:00
private function handleCommand ()
{
2016-08-28 20:53:52 +00:00
$this -> command = str_replace ( ':.' , '' , $this -> command );
$tmp = explode ( ':.' . $this -> command . ' ' , $this -> data );
2016-08-28 22:32:55 +00:00
$this -> user = $this -> getAuthdUser ();
2017-06-02 20:27:29 +00:00
if ( ! $this -> isAuthd () && ( isset ( $this -> config [ 'irc_auth' ]))) {
$this -> hostAuth ();
}
2016-08-28 20:53:52 +00:00
if ( $this -> isAuthd () || trim ( $this -> command ) == 'auth' ) {
$this -> proceedCommand ( str_replace ( " \n " , '' , trim ( $this -> command )), trim ( $tmp [ 1 ]));
}
$this -> authd [ $this -> getUser ( $this -> data )] = $this -> user ;
return false ;
} //end handleCommand()
2016-08-28 22:32:55 +00:00
private function proceedCommand ( $command , $params )
{
2016-08-28 20:53:52 +00:00
$command = strtolower ( $command );
if ( in_array ( $command , $this -> commands )) {
$this -> chkdb ();
$this -> log ( $command . " ( ' " . $params . " ' ) " );
return $this -> { '_' . $command }( $params );
2016-08-28 22:32:55 +00:00
} elseif ( $this -> external [ $command ]) {
2016-08-28 20:53:52 +00:00
$this -> chkdb ();
$this -> log ( $command . " ( ' " . $params . " ' ) [Ext] " );
return eval ( $this -> external [ $command ]);
}
return false ;
} //end proceedCommand()
2016-08-28 22:32:55 +00:00
private function respond ( $msg )
{
2016-08-28 20:53:52 +00:00
$chan = $this -> getChan ( $this -> data );
return $this -> sendMessage ( $msg , strstr ( $chan , '#' ) ? $chan : $this -> getUser ( $this -> data ));
} //end respond()
2016-08-28 22:32:55 +00:00
private function getChan ( $param )
{
2016-08-28 20:53:52 +00:00
$data = explode ( 'PRIVMSG ' , $this -> data , 3 );
$data = explode ( ' ' , $data [ 1 ], 2 );
return $data [ 0 ];
} //end getChan()
2016-08-28 22:32:55 +00:00
private function getUser ( $param )
{
2016-08-28 20:53:52 +00:00
$arrData = explode ( '!' , $param , 2 );
return str_replace ( ':' , '' , $arrData [ 0 ]);
} //end getUser()
2017-06-02 20:27:29 +00:00
private function getUserHost ( $param )
{
$arrData = explode ( ' ' , $param , 2 );
return str_replace ( ':' , '' , $arrData [ 0 ]);
} //end getUserHost()
2016-08-28 20:53:52 +00:00
2017-04-06 21:02:37 +00:00
private function connect ( $try = 0 )
2016-08-28 22:32:55 +00:00
{
2016-08-28 20:53:52 +00:00
if ( $try > $this -> max_retry ) {
$this -> log ( 'Failed too many connection attempts, aborting' );
return die ();
}
2016-09-03 13:54:37 +00:00
$this -> log ( 'Trying to connect (' . ( $try + 1 ) . ') to ' . $this -> server . ':' . $this -> port . ( $this -> ssl ? ' (SSL)' : '' ));
2016-08-28 20:53:52 +00:00
if ( $this -> socket [ 'irc' ]) {
fclose ( $this -> socket [ 'irc' ]);
}
if ( $this -> ssl ) {
$server = 'ssl://' . $this -> server ;
2016-08-28 22:32:55 +00:00
} else {
2016-08-28 20:53:52 +00:00
$server = $this -> server ;
}
if ( $this -> ssl && $this -> config [ 'irc_disable_ssl_check' ]) {
$ssl_context_params = array ( 'ssl' => array ( 'allow_self_signed' => true , 'verify_peer' => false , 'verify_peer_name' => false ));
$ssl_context = stream_context_create ( $ssl_context_params );
$this -> socket [ 'irc' ] = stream_socket_client ( $server . ':' . $this -> port , $errno , $errstr , 30 , STREAM_CLIENT_CONNECT , $ssl_context );
2016-08-28 22:32:55 +00:00
} else {
2016-08-28 20:53:52 +00:00
$this -> socket [ 'irc' ] = fsockopen ( $server , $this -> port );
}
if ( ! is_resource ( $this -> socket [ 'irc' ])) {
2016-09-03 13:54:37 +00:00
if ( $try < 5 ) {
sleep ( 5 );
} elseif ( $try < 10 ) {
sleep ( 60 );
} else {
sleep ( 300 );
}
2016-08-28 20:53:52 +00:00
return $this -> connect ( $try + 1 );
2016-08-28 22:32:55 +00:00
} else {
2016-08-28 20:53:52 +00:00
stream_set_blocking ( $this -> socket [ 'irc' ], false );
return true ;
}
} //end connect()
2016-08-28 22:32:55 +00:00
private function doAuth ()
{
if ( $this -> ircRaw ( 'USER ' . $this -> nick . ' 0 ' . $this -> nick . ' :' . $this -> nick ) && $this -> ircRaw ( 'NICK ' . $this -> nick )) {
2016-08-28 20:53:52 +00:00
return true ;
}
return false ;
} //end doAuth()
2016-08-28 22:32:55 +00:00
private function sendMessage ( $message , $chan )
{
2016-08-28 20:53:52 +00:00
if ( $this -> debug ) {
$this -> log ( " Sending 'PRIVMSG " . trim ( $chan ) . ' :' . trim ( $message ) . " ' " );
}
2016-08-28 22:32:55 +00:00
return $this -> ircRaw ( 'PRIVMSG ' . trim ( $chan ) . ' :' . trim ( $message ));
2016-08-28 20:53:52 +00:00
} //end sendMessage()
2016-08-28 22:32:55 +00:00
private function log ( $msg )
{
2016-08-28 20:53:52 +00:00
echo '[' . date ( 'r' ) . '] ' . trim ( $msg ) . " \n " ;
return true ;
} //end log()
2016-08-28 22:32:55 +00:00
private function chkdb ()
{
2016-08-28 20:53:52 +00:00
if ( ! is_resource ( $this -> sql )) {
2017-04-06 21:02:37 +00:00
try {
$this -> sql = dbConnect (
$this -> config [ 'db_host' ],
$this -> config [ 'db_user' ],
$this -> config [ 'db_pass' ],
$this -> config [ 'db_name' ],
$this -> config [ 'db_port' ],
$this -> config [ 'db_socket' ]
);
} catch ( DatabaseConnectException $e ) {
$this -> log ( 'Cannot connect to MySQL: ' . $e -> getMessage ());
2016-08-28 20:53:52 +00:00
return die ();
}
}
2017-04-06 21:02:37 +00:00
return true ;
2016-08-28 20:53:52 +00:00
} //end chkdb()
2016-08-28 22:32:55 +00:00
private function isAuthd ()
{
2016-08-28 20:53:52 +00:00
if ( $this -> user [ 'expire' ] >= time ()) {
$this -> user [ 'expire' ] = ( time () + ( $this -> config [ 'irc_authtime' ] * 3600 ));
return true ;
2016-08-28 22:32:55 +00:00
} else {
2016-08-28 20:53:52 +00:00
return false ;
}
} //end isAuthd()
2016-08-28 22:32:55 +00:00
private function getAuthdUser ()
{
2016-08-28 20:53:52 +00:00
return $this -> authd [ $this -> getUser ( $this -> data )];
2017-06-02 20:27:29 +00:00
} //end getAuthUser()
private function hostAuth ()
{
foreach ( $this -> config [ 'irc_auth' ] as $nms_user => $hosts ) {
foreach ( $hosts as $host ) {
$host = preg_replace ( " / \ */ " , " .* " , $host );
if ( preg_match ( " / $host / " , $this -> getUserHost ( $this -> data ))) {
$user_id = get_userid ( mres ( $nms_user ));
$user = get_user ( $user_id );
$this -> user [ 'name' ] = $user [ 'username' ];
$this -> user [ 'id' ] = $user_id ;
$this -> user [ 'level' ] = get_userlevel ( $user [ 'username' ]);
$this -> user [ 'expire' ] = ( time () + ( $this -> config [ 'irc_authtime' ] * 3600 ));
if ( $this -> user [ 'level' ] < 5 ) {
foreach ( dbFetchRows ( 'SELECT device_id FROM devices_perms WHERE user_id = ?' , array ( $this -> user [ 'id' ])) as $tmp ) {
$this -> user [ 'devices' ][] = $tmp [ 'device_id' ];
}
foreach ( dbFetchRows ( 'SELECT port_id FROM ports_perms WHERE user_id = ?' , array ( $this -> user [ 'id' ])) as $tmp ) {
$this -> user [ 'ports' ][] = $tmp [ 'port_id' ];
}
}
if ( $this -> debug ) {
$this -> log ( " HostAuth on irc for ' " . $user [ 'username' ] . " ', ID: ' " . $user_id . " ', Host: ' " . $host );
}
return true ;
}
}
}
return false ;
} //end hostAuth
2016-08-28 20:53:52 +00:00
2016-08-28 22:32:55 +00:00
private function ircRaw ( $params )
{
2016-08-28 20:53:52 +00:00
return fputs ( $this -> socket [ 'irc' ], $params . " \r \n " );
} //end irc_raw()
2016-08-28 22:32:55 +00:00
private function _auth ( $params )
{
2016-08-28 20:53:52 +00:00
$params = explode ( ' ' , $params , 2 );
if ( strlen ( $params [ 0 ]) == 64 ) {
if ( $this -> tokens [ $this -> getUser ( $this -> data )] == $params [ 0 ]) {
$this -> user [ 'expire' ] = ( time () + ( $this -> config [ 'irc_authtime' ] * 3600 ));
2016-09-12 16:24:22 +00:00
$tmp_user = get_user ( $this -> user [ 'id' ]);
$tmp = get_userlevel ( $tmp_user [ 'username' ]);
2016-10-20 17:53:49 +00:00
$this -> user [ 'level' ] = $tmp ;
2016-08-28 20:53:52 +00:00
if ( $this -> user [ 'level' ] < 5 ) {
foreach ( dbFetchRows ( 'SELECT device_id FROM devices_perms WHERE user_id = ?' , array ( $this -> user [ 'id' ])) as $tmp ) {
$this -> user [ 'devices' ][] = $tmp [ 'device_id' ];
}
foreach ( dbFetchRows ( 'SELECT port_id FROM ports_perms WHERE user_id = ?' , array ( $this -> user [ 'id' ])) as $tmp ) {
$this -> user [ 'ports' ][] = $tmp [ 'port_id' ];
}
}
return $this -> respond ( 'Authenticated.' );
2016-08-28 22:32:55 +00:00
} else {
2016-08-28 20:53:52 +00:00
return $this -> respond ( 'Nope.' );
}
2016-08-28 22:32:55 +00:00
} else {
2016-09-12 16:24:22 +00:00
$user_id = get_userid ( mres ( $params [ 0 ]));
$user = get_user ( $user_id );
2016-08-28 20:53:52 +00:00
if ( $user [ 'email' ] && $user [ 'username' ] == $params [ 0 ]) {
$token = hash ( 'gost' , openssl_random_pseudo_bytes ( 1024 ));
$this -> tokens [ $this -> getUser ( $this -> data )] = $token ;
$this -> user [ 'name' ] = $params [ 0 ];
$this -> user [ 'id' ] = $user [ 'user_id' ];
if ( $this -> debug ) {
$this -> log ( " Auth for ' " . $params [ 0 ] . " ', ID: ' " . $user [ 'user_id' ] . " ', Token: ' " . $token . " ', Mail: ' " . $user [ 'email' ] . " ' " );
}
if ( send_mail ( $user [ 'email' ], 'LibreNMS IRC-Bot Authtoken' , " Your Authtoken for the IRC-Bot: \r \n \r \n " . $token . " \r \n \r \n " ) === true ) {
return $this -> respond ( 'Token sent!' );
2016-08-28 22:32:55 +00:00
} else {
2016-08-28 20:53:52 +00:00
return $this -> respond ( 'Sorry, seems like mail doesnt like us.' );
}
2016-08-28 22:32:55 +00:00
} else {
2016-08-28 20:53:52 +00:00
return $this -> respond ( 'Who are you again?' );
}
} //end if
return false ;
} //end _auth()
2016-08-28 22:32:55 +00:00
private function _reload ()
{
2016-08-28 20:53:52 +00:00
if ( $this -> user [ 'level' ] == 10 ) {
global $config ;
$config = array ();
include 'includes/defaults.inc.php' ;
include 'config.php' ;
include 'includes/definitions.inc.php' ;
$this -> respond ( 'Reloading configuration & defaults' );
if ( $config != $this -> config ) {
return $this -> __construct ();
}
2016-08-28 22:32:55 +00:00
} else {
2016-08-28 20:53:52 +00:00
return $this -> respond ( 'Permission denied.' );
}
} //end _reload()
2016-08-28 22:32:55 +00:00
private function _join ( $params )
{
2016-08-28 20:53:52 +00:00
if ( $this -> user [ 'level' ] == 10 ) {
return $this -> joinChan ( $params );
2016-08-28 22:32:55 +00:00
} else {
2016-08-28 20:53:52 +00:00
return $this -> respond ( 'Permission denied.' );
}
} //end _join()
2016-08-28 22:32:55 +00:00
private function _quit ( $params )
{
2016-08-28 20:53:52 +00:00
if ( $this -> user [ 'level' ] == 10 ) {
return die ();
2016-08-28 22:32:55 +00:00
} else {
2016-08-28 20:53:52 +00:00
return $this -> respond ( 'Permission denied.' );
}
} //end _quit()
2016-08-28 22:32:55 +00:00
private function _help ( $params )
{
2016-08-28 20:53:52 +00:00
foreach ( $this -> commands as $cmd ) {
$msg .= ', ' . $cmd ;
}
$msg = substr ( $msg , 2 );
return $this -> respond ( " Available commands: $msg " );
} //end _help()
2016-08-28 22:32:55 +00:00
private function _version ( $params )
{
2016-09-07 06:33:24 +00:00
$versions = version_info ( false );
$schema_version = $versions [ 'db_schema' ];
$version = substr ( $versions [ 'local_sha' ], 0 , 7 );
$msg = $this -> config [ 'project_name_version' ] . ', Version: ' . $version . ', DB schema: #' . $schema_version . ', PHP: ' . PHP_VERSION ;
return $this -> respond ( $msg );
2016-08-28 20:53:52 +00:00
} //end _version()
2016-08-28 22:32:55 +00:00
private function _log ( $params )
{
2016-08-28 20:53:52 +00:00
$num = 1 ;
if ( $params > 1 ) {
$num = $params ;
}
if ( $this -> user [ 'level' ] < 5 ) {
$tmp = dbFetchRows ( 'SELECT `event_id`,`host`,`datetime`,`message`,`type` FROM `eventlog` WHERE `host` IN (' . implode ( ',' , $this -> user [ 'devices' ]) . ') ORDER BY `event_id` DESC LIMIT ' . mres ( $num ));
2016-08-28 22:32:55 +00:00
} else {
2016-08-28 20:53:52 +00:00
$tmp = dbFetchRows ( 'SELECT `event_id`,`host`,`datetime`,`message`,`type` FROM `eventlog` ORDER BY `event_id` DESC LIMIT ' . mres ( $num ));
}
foreach ( $tmp as $device ) {
$hostid = dbFetchRow ( 'SELECT `hostname` FROM `devices` WHERE `device_id` = ' . $device [ 'host' ]);
$this -> respond ( $device [ 'event_id' ] . ' ' . $hostid [ 'hostname' ] . ' ' . $device [ 'datetime' ] . ' ' . $device [ 'message' ] . ' ' . $device [ 'type' ]);
}
if ( ! $hostid ) {
$this -> respond ( 'Nothing to see, maybe a bug?' );
}
return true ;
} //end _log()
2016-08-28 22:32:55 +00:00
private function _down ( $params )
{
2016-08-28 20:53:52 +00:00
if ( $this -> user [ 'level' ] < 5 ) {
$tmp = dbFetchRows ( 'SELECT `hostname` FROM `devices` WHERE status=0 AND `device_id` IN (' . implode ( ',' , $this -> user [ 'devices' ]) . ')' );
2016-08-28 22:32:55 +00:00
} else {
2016-08-28 20:53:52 +00:00
$tmp = dbFetchRows ( 'SELECT `hostname` FROM `devices` WHERE status=0' );
}
foreach ( $tmp as $db ) {
if ( $db [ 'hostname' ]) {
$msg .= ', ' . $db [ 'hostname' ];
}
}
$msg = substr ( $msg , 2 );
$msg = $msg ? $msg : 'Nothing to show :)' ;
return $this -> respond ( $msg );
} //end _down()
2016-08-28 22:32:55 +00:00
private function _device ( $params )
{
2016-08-28 20:53:52 +00:00
$params = explode ( ' ' , $params );
$hostname = $params [ 0 ];
$device = dbFetchRow ( 'SELECT * FROM `devices` WHERE `hostname` = ?' , array ( $hostname ));
if ( ! $device ) {
return $this -> respond ( 'Error: Bad or Missing hostname, use .listdevices to show all devices.' );
}
if ( $this -> user [ 'level' ] < 5 && ! in_array ( $device [ 'device_id' ], $this -> user [ 'devices' ])) {
return $this -> respond ( 'Error: Permission denied.' );
}
$status = $device [ 'status' ] ? 'Up ' . formatUptime ( $device [ 'uptime' ]) : 'Down' ;
$status .= $device [ 'ignore' ] ? '*Ignored*' : '' ;
$status .= $device [ 'disabled' ] ? '*Disabled*' : '' ;
return $this -> respond ( $device [ 'os' ] . ' ' . $device [ 'version' ] . ' ' . $device [ 'features' ] . ' ' . $status );
} //end _device()
2016-08-28 22:32:55 +00:00
private function _port ( $params )
{
2016-08-28 20:53:52 +00:00
$params = explode ( ' ' , $params );
$hostname = $params [ 0 ];
$ifname = $params [ 1 ];
if ( ! $hostname || ! $ifname ) {
return $this -> respond ( 'Error: Missing hostname or ifname.' );
}
$device = dbFetchRow ( 'SELECT * FROM `devices` WHERE `hostname` = ?' , array ( $hostname ));
$port = dbFetchRow ( 'SELECT * FROM `ports` WHERE (`ifName` = ? OR `ifDescr` = ?) AND device_id = ?' , array ( $ifname , $ifname , $device [ 'device_id' ]));
if ( $this -> user [ 'level' ] < 5 && ! in_array ( $port [ 'port_id' ], $this -> user [ 'ports' ]) && ! in_array ( $device [ 'device_id' ], $this -> user [ 'devices' ])) {
return $this -> respond ( 'Error: Permission denied.' );
}
$bps_in = formatRates ( $port [ 'ifInOctets_rate' ] * 8 );
$bps_out = formatRates ( $port [ 'ifOutOctets_rate' ] * 8 );
$pps_in = format_bi ( $port [ 'ifInUcastPkts_rate' ]);
$pps_out = format_bi ( $port [ 'ifOutUcastPkts_rate' ]);
return $this -> respond ( $port [ 'ifAdminStatus' ] . '/' . $port [ 'ifOperStatus' ] . ' ' . $bps_in . ' > bps > ' . $bps_out . ' | ' . $pps_in . 'pps > PPS > ' . $pps_out . 'pps' );
} //end _port()
2016-08-28 22:32:55 +00:00
private function _listdevices ( $params )
{
2016-08-28 20:53:52 +00:00
if ( $this -> user [ 'level' ] < 5 ) {
$tmp = dbFetchRows ( 'SELECT `hostname` FROM `devices` WHERE `device_id` IN (' . implode ( ',' , $this -> user [ 'devices' ]) . ')' );
2016-08-28 22:32:55 +00:00
} else {
2016-08-28 20:53:52 +00:00
$tmp = dbFetchRows ( 'SELECT `hostname` FROM `devices`' );
}
foreach ( $tmp as $device ) {
$msg .= ', ' . $device [ 'hostname' ];
}
$msg = substr ( $msg , 2 );
$msg = $msg ? $msg : 'Nothing to show..?' ;
return $this -> respond ( $msg );
} //end _listdevices()
2016-08-28 22:32:55 +00:00
private function _status ( $params )
{
2016-08-28 20:53:52 +00:00
$params = explode ( ' ' , $params );
$statustype = $params [ 0 ];
if ( $this -> user [ 'level' ] < 5 ) {
$d_w = ' WHERE device_id IN (' . implode ( ',' , $this -> user [ 'devices' ]) . ')' ;
$d_a = ' AND device_id IN (' . implode ( ',' , $this -> user [ 'devices' ]) . ')' ;
$p_w = ' WHERE port_id IN (' . implode ( ',' , $this -> user [ 'ports' ]) . ') OR device_id IN (' . implode ( ',' , $this -> user [ 'devices' ]) . ')' ;
$p_a = ' AND (I.port_id IN (' . implode ( ',' , $this -> user [ 'ports' ]) . ') OR I.device_id IN (' . implode ( ',' , $this -> user [ 'devices' ]) . '))' ;
}
switch ( $statustype ) {
2016-08-28 22:32:55 +00:00
case 'devices' :
case 'device' :
case 'dev' :
$devcount = array_pop ( dbFetchRow ( 'SELECT count(*) FROM devices' . $d_w ));
$devup = array_pop ( dbFetchRow ( " SELECT count(*) FROM devices WHERE status = '1' AND `ignore` = '0' " . $d_a ));
$devdown = array_pop ( dbFetchRow ( " SELECT count(*) FROM devices WHERE status = '0' AND `ignore` = '0' " . $d_a ));
$devign = array_pop ( dbFetchRow ( " SELECT count(*) FROM devices WHERE `ignore` = '1' " . $d_a ));
$devdis = array_pop ( dbFetchRow ( " SELECT count(*) FROM devices WHERE `disabled` = '1' " . $d_a ));
2017-06-02 19:07:09 +00:00
if ( $devup > 0 ) {
$devup = $this -> _color ( $devup , 'green' );
}
if ( $devdown > 0 ) {
$devdown = $this -> _color ( $devdown , 'red' );
$devcount = $this -> _color ( $devcount , 'orange' , null , 'bold' );
} else {
$devcount = $this -> _color ( $devcount , 'green' , null , 'bold' );
}
2016-08-28 22:32:55 +00:00
$msg = 'Devices: ' . $devcount . ' (' . $devup . ' up, ' . $devdown . ' down, ' . $devign . ' ignored, ' . $devdis . ' disabled' . ')' ;
break ;
case 'ports' :
case 'port' :
case 'prt' :
$prtcount = array_pop ( dbFetchRow ( 'SELECT count(*) FROM ports' . $p_w ));
$prtup = array_pop ( dbFetchRow ( " SELECT count(*) FROM ports AS I, devices AS D WHERE I.ifOperStatus = 'up' AND I.ignore = '0' AND I.device_id = D.device_id AND D.ignore = '0' " . $p_a ));
$prtdown = array_pop ( dbFetchRow ( " SELECT count(*) FROM ports AS I, devices AS D WHERE I.ifOperStatus = 'down' AND I.ifAdminStatus = 'up' AND I.ignore = '0' AND D.device_id = I.device_id AND D.ignore = '0' " . $p_a ));
$prtsht = array_pop ( dbFetchRow ( " SELECT count(*) FROM ports AS I, devices AS D WHERE I.ifAdminStatus = 'down' AND I.ignore = '0' AND D.device_id = I.device_id AND D.ignore = '0' " . $p_a ));
$prtign = array_pop ( dbFetchRow ( " SELECT count(*) FROM ports AS I, devices AS D WHERE D.device_id = I.device_id AND (I.ignore = '1' OR D.ignore = '1') " . $p_a ));
$prterr = array_pop ( dbFetchRow ( " SELECT count(*) FROM ports AS I, devices AS D WHERE D.device_id = I.device_id AND (I.ignore = '0' OR D.ignore = '0') AND (I.ifInErrors_delta > '0' OR I.ifOutErrors_delta > '0') " . $p_a ));
2017-06-02 19:07:09 +00:00
if ( $prtup > 0 ) {
$prtup = $this -> _color ( $prtup , 'green' );
}
if ( $prtdown > 0 ) {
$prtdown = $this -> _color ( $prtdown , 'red' );
$prtcount = $this -> _color ( $prtcount , 'orange' , null , 'bold' );
} else {
$prtcount = $this -> _color ( $prtcount , 'green' , null , 'bold' );
}
2016-08-28 22:32:55 +00:00
$msg = 'Ports: ' . $prtcount . ' (' . $prtup . ' up, ' . $prtdown . ' down, ' . $prtign . ' ignored, ' . $prtsht . ' shutdown' . ')' ;
break ;
case 'services' :
case 'service' :
case 'srv' :
$srvcount = array_pop ( dbFetchRow ( 'SELECT count(service_id) FROM services' . $d_w ));
$srvup = array_pop ( dbFetchRow ( " SELECT count(service_id) FROM services WHERE service_status = '1' AND service_ignore ='0' " . $d_a ));
$srvdown = array_pop ( dbFetchRow ( " SELECT count(service_id) FROM services WHERE service_status = '0' AND service_ignore = '0' " . $d_a ));
$srvign = array_pop ( dbFetchRow ( " SELECT count(service_id) FROM services WHERE service_ignore = '1' " . $d_a ));
$srvdis = array_pop ( dbFetchRow ( " SELECT count(service_id) FROM services WHERE service_disabled = '1' " . $d_a ));
2017-06-02 19:07:09 +00:00
if ( $srvup > 0 ) {
$srvup = $this -> _color ( $srvup , 'green' );
}
if ( $srvdown > 0 ) {
$srvdown = $this -> _color ( $srvdown , 'red' );
$srvcount = $this -> _color ( $srvcount , 'orange' , null , 'bold' );
} else {
$srvcount = $this -> _color ( $srvcount , 'green' , null , 'bold' );
}
2016-08-28 22:32:55 +00:00
$msg = 'Services: ' . $srvcount . ' (' . $srvup . ' up, ' . $srvdown . ' down, ' . $srvign . ' ignored, ' . $srvdis . ' disabled' . ')' ;
break ;
default :
$msg = 'Error: STATUS requires one of the following: <devices|device|dev>|<ports|port|prt>|<services|service|src>' ;
break ;
2016-08-28 20:53:52 +00:00
} //end switch
return $this -> respond ( $msg );
} //end _status()
2017-06-02 19:07:09 +00:00
private function _color ( $text , $fg_color , $bg_color = null , $other = null )
{
$colors = array (
'white' => " 00 " ,
'black' => " 01 " ,
'blue' => " 02 " ,
'green' => " 03 " ,
'red' => " 04 " ,
'brown' => " 05 " ,
'purple' => " 06 " ,
'orange' => " 07 " ,
'yellow' => " 08 " ,
'lightgreen' => " 09 " ,
'cyan' => " 10 " ,
'lightcyan' => " 11 " ,
'lightblue' => " 12 " ,
'pink' => " 13 " ,
'grey' => " 14 " ,
'lightgrey' => " 15 " ,
);
$ret = chr ( 3 );
if ( in_array ( $fg_color , $colors )) {
$ret .= $colors [ $fg_color ];
if ( in_array ( $bg_color , $colors )) {
$ret .= " , " . $colors [ $fg_color ];
}
}
switch ( $other ) {
case 'bold' :
$ret .= chr ( 2 );
break ;
case 'underline' :
$ret .= chr ( 31 );
break ;
case 'italics' :
case 'reverse' :
$ret .= chr ( 22 );
break ;
}
$ret .= $text ;
$ret .= chr ( 15 );
return $ret ;
} // end _color
2016-08-28 20:53:52 +00:00
} //end class